import { IconAvatarProps, ModelIcon, ProviderIcon } from '@bentwnghk/icons'; import { Avatar, Icon, Tooltip } from '@bentwnghk/ui'; import { Typography } from 'antd'; import { createStyles } from 'antd-style'; import { Infinity, AtomIcon, LucideEye, LucideGlobe, LucideImage, LucidePaperclip, ToyBrick, } from 'lucide-react'; import numeral from 'numeral'; import { rgba } from 'polished'; import { FC, memo } from 'react'; import { useTranslation } from 'react-i18next'; import { Center, Flexbox } from 'react-layout-kit'; import { ModelAbilities } from '@/types/aiModel'; import { AiProviderSourceType } from '@/types/aiProvider'; import { ChatModelCard } from '@/types/llm'; import { formatTokenNumber } from '@/utils/format'; const useStyles = createStyles(({ css, token, isDarkMode }) => ({ custom: css` width: 36px; height: 20px; border-radius: 4px; font-family: ${token.fontFamilyCode}; font-size: 12px; color: ${rgba(token.colorWarning, 0.75)}; background: ${token.colorWarningBg}; `, tag: css` cursor: default; display: flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 4px; `, tagBlue: css` color: ${token.geekblue}; background: ${token.geekblue1}; `, tagCyan: css` color: ${isDarkMode ? token.cyan7 : token.cyan10}; background: ${isDarkMode ? token.cyan1 : token.cyan2}; `, tagGreen: css` color: ${token.green}; background: ${token.green1}; `, tagGreenDeep: css` color: ${token.green9}; background: ${token.green3}; `, tagPurple: css` color: ${token.purple}; background: ${token.purple1}; `, token: css` width: 36px; height: 20px; border-radius: 4px; font-family: ${token.fontFamilyCode}; font-size: 11px; color: ${token.colorTextSecondary}; background: ${token.colorFillTertiary}; `, })); interface ModelInfoTagsProps extends ModelAbilities { contextWindowTokens?: number | null; directionReverse?: boolean; isCustom?: boolean; placement?: 'top' | 'right'; } export const ModelInfoTags = memo( ({ directionReverse, placement = 'right', ...model }) => { const { t } = useTranslation('components'); const { styles, cx } = useStyles(); return ( {model.files && (
)} {model.imageOutput && (
)} {model.vision && (
)} {model.functionCall && (
)} {model.reasoning && (
)} {model.search && (
)} {typeof model.contextWindowTokens === 'number' && (
{model.contextWindowTokens === 0 ? ( ) : ( formatTokenNumber(model.contextWindowTokens as number) )}
)}
); }, ); interface ModelItemRenderProps extends ChatModelCard { showInfoTag?: boolean; } export const ModelItemRender = memo(({ showInfoTag = true, ...model }) => { return ( {model.displayName || model.id} {showInfoTag && } ); }); interface ProviderItemRenderProps { logo?: string; name: string; provider: string; source?: AiProviderSourceType; } export const ProviderItemRender = memo( ({ provider, name, source, logo }) => { return ( {source === 'custom' && !!logo ? ( ) : ( )} {name} ); }, ); interface LabelRendererProps { Icon: FC; label: string; } export const LabelRenderer = memo(({ Icon, label }) => ( {label} ));