model-selector.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /**
  2. * multi-models selector
  3. */
  4. import { ChatContext } from '@/app/chat-context';
  5. import { MODEL_ICON_MAP } from '@/utils/constants';
  6. import { Select } from 'antd';
  7. import Image from 'next/image';
  8. import { useContext } from 'react';
  9. import { useTranslation } from 'react-i18next';
  10. interface Props {
  11. onChange?: (model: string) => void;
  12. }
  13. const DEFAULT_ICON_URL = '/models/huggingface.svg';
  14. export function renderModelIcon(model?: string, props?: { width: number; height: number }) {
  15. const { width, height } = props || {};
  16. if (!model) return null;
  17. return (
  18. <Image
  19. className='rounded-full border border-gray-200 object-contain bg-white inline-block'
  20. width={width || 24}
  21. height={height || 24}
  22. src={MODEL_ICON_MAP[model]?.icon || DEFAULT_ICON_URL}
  23. key={MODEL_ICON_MAP[model]?.icon || DEFAULT_ICON_URL}
  24. alt='llm'
  25. />
  26. );
  27. }
  28. function ModelSelector({ onChange }: Props) {
  29. const { t } = useTranslation();
  30. const { modelList, model } = useContext(ChatContext);
  31. if (!modelList || modelList.length <= 0) {
  32. return null;
  33. }
  34. return (
  35. <Select
  36. value={model}
  37. placeholder={t('choose_model')}
  38. className='w-52'
  39. onChange={val => {
  40. onChange?.(val);
  41. }}
  42. >
  43. {modelList.map(item => (
  44. <Select.Option key={item}>
  45. <div className='flex items-center'>
  46. {renderModelIcon(item)}
  47. <span className='ml-2'>{MODEL_ICON_MAP[item]?.label || item}</span>
  48. </div>
  49. </Select.Option>
  50. ))}
  51. </Select>
  52. );
  53. }
  54. export default ModelSelector;