// src/components/AvailableModels.tsx import { LlmIcon } from '@/components/svg-icon'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { useTranslate } from '@/hooks/common-hooks'; import { useSelectLlmList } from '@/hooks/llm-hooks'; import { Plus, Search } from 'lucide-react'; import { FC, useMemo, useState } from 'react'; type TagType = | 'LLM' | 'TEXT EMBEDDING' | 'TEXT RE-RANK' | 'TTS' | 'SPEECH2TEXT' | 'IMAGE2TEXT' | 'MODERATION'; const sortTags = (tags: string) => { const orderMap: Record = { LLM: 1, 'TEXT EMBEDDING': 2, 'TEXT RE-RANK': 3, TTS: 4, SPEECH2TEXT: 5, IMAGE2TEXT: 6, MODERATION: 7, }; return tags .split(',') .map((tag) => tag.trim()) .sort( (a, b) => (orderMap[a as TagType] || 999) - (orderMap[b as TagType] || 999), ); }; export const AvailableModels: FC<{ handleAddModel: (factory: string) => void; }> = ({ handleAddModel }) => { const { t } = useTranslate('setting'); const { factoryList } = useSelectLlmList(); const [searchTerm, setSearchTerm] = useState(''); const [selectedTag, setSelectedTag] = useState(null); const filteredModels = useMemo(() => { const models = factoryList.filter((model) => { const matchesSearch = model.name .toLowerCase() .includes(searchTerm.toLowerCase()); const matchesTag = selectedTag === null || model.tags.split(',').some((tag) => tag.trim() === selectedTag); return matchesSearch && matchesTag; }); return models; }, [factoryList, searchTerm, selectedTag]); const allTags = useMemo(() => { const tagsSet = new Set(); factoryList.forEach((model) => { model.tags.split(',').forEach((tag) => tagsSet.add(tag.trim())); }); return Array.from(tagsSet).sort(); }, [factoryList]); const handleTagClick = (tag: string) => { setSelectedTag(selectedTag === tag ? null : tag); }; return (
{t('availableModels')}
{/* Search Bar */}
setSearchTerm(e.target.value)} className="w-full px-4 py-2 pl-10 bg-bg-input border border-border-default rounded-lg focus:outline-none focus:ring-1 focus:ring-border-button transition-colors" />
{/* Tags Filter */}
{allTags.map((tag) => ( ))}
{/* Models List */}
{filteredModels.map((model) => (
handleAddModel(model.name)} >
{model.name}
{sortTags(model.tags).map((tag, index) => ( {tag} ))}
))}
); };