index.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { ChatContext } from '@/app/chat-context';
  2. import { apiInterceptors, getUsableModels } from '@/client/api';
  3. import { MODEL_ICON_MAP } from '@/utils/constants';
  4. import { CaretDownOutlined } from '@ant-design/icons';
  5. import { useRequest } from 'ahooks';
  6. import { Select } from 'antd';
  7. import Image from 'next/image';
  8. import React, { useContext, useState } from 'react';
  9. import { useTranslation } from 'react-i18next';
  10. import styles from './styles.module.css';
  11. const DEFAULT_ICON_URL = '/models/huggingface.svg';
  12. export function renderModelIcon(model?: string, props?: { width: number; height: number }) {
  13. const { width, height } = props || {};
  14. if (!model) return null;
  15. return (
  16. <Image
  17. className='rounded-full border border-gray-200 object-contain bg-white inline-block'
  18. width={width || 24}
  19. height={height || 24}
  20. src={MODEL_ICON_MAP[model]?.icon || DEFAULT_ICON_URL}
  21. alt='llm'
  22. />
  23. );
  24. }
  25. const ModelSelector: React.FC = () => {
  26. const { t } = useTranslation();
  27. const { model, setModel } = useContext(ChatContext);
  28. const [modelList, setModelList] = useState<string[]>([]);
  29. useRequest(async () => await apiInterceptors(getUsableModels()), {
  30. onSuccess: data => {
  31. const [, res] = data;
  32. setModelList(res || []);
  33. },
  34. });
  35. if (modelList.length === 0) {
  36. return null;
  37. }
  38. return (
  39. <div className={styles['cus-selector']}>
  40. <Select
  41. value={model}
  42. placeholder={t('choose_model')}
  43. className='w-48 h-8 rounded-3xl'
  44. suffixIcon={<CaretDownOutlined className='text-sm text-[#000000]' />}
  45. onChange={val => {
  46. setModel(val);
  47. }}
  48. >
  49. {modelList.map(item => (
  50. <Select.Option key={item}>
  51. <div className='flex items-center'>
  52. {renderModelIcon(item)}
  53. <span className='ml-2'>{MODEL_ICON_MAP[item]?.label || item}</span>
  54. </div>
  55. </Select.Option>
  56. ))}
  57. </Select>
  58. </div>
  59. );
  60. };
  61. export default ModelSelector;