import * as React from 'react' import {__, _x} from '@wordpress/i18n' import cx from 'classnames' import { useMemo, } from '@wordpress/element' import { ToggleControl, __experimentalVStack as VStack, } from '@wordpress/components' import { useQuery, } from '@tanstack/react-query' import Fuse from 'fuse.js' import { Search, SearchResult, } from '@ska/components' import { usePluginPreference, } from '@ska/plugin' import { fetchModels, } from '../../api' import type { OpenRouterModel, } from '../../types' import './style.scss' export interface ModelPickerProps { value?: string onChange: (nextValue: string) => void showFilters?: boolean /** `@tanstack/react-query` query client provider. */ QueryClientProvider: React.FC } const NO_MODELS: OpenRouterModel[] = [] const ModelPicker: React.FC> = ({ value, onChange, showFilters = false, }) => { const [filters = {}, setFilters] = usePluginPreference('aiModelFilters') const { free = true, } = filters const { isLoading, isFetched, data = NO_MODELS, } = useQuery({ queryKey: ['models'], queryFn: ({signal}) => fetchModels({signal}), retry: 3, gcTime: 1000 * 60 * 30, }) const fuse = useMemo(() => { const models = data.filter(model => { const { architecture, } = model const { input_modalities = [], output_modalities = [], } = architecture || {} return input_modalities.includes('text') && output_modalities.includes('text') }) return new Fuse(models, { keys: ['id', 'name', 'description'], }) }, [data]) const getResults = (searchTerm: string) => { return fuse .search(searchTerm) .map(r => r.item) .filter(model => { return free ? !Object.values(model.pricing).some(price => price !== '0') : true }) .map(model => { const { id, name, canonical_slug, } = model return { id, title: name, content: canonical_slug, } as SearchResult }) } const onSelect = async (result: SearchResult) => { const {id = ''} = result onChange(id.toString()) } return ( {showFilters && <> setFilters({...filters, free: !free})} __nextHasNoMarginBottom /> } null} onSelect={onSelect} actionInputProps={{ label: __('Search for a model', 'ska-blocks'), placeholder: value || __('Search models…', 'ska-blocks'), actionLabel: __('Search', 'ska-blocks'), loading: isLoading, }} /> ) } export {ModelPicker} const ModelPickerComponent: React.FC = ({QueryClientProvider, ...props}) => { return ( ) } export default ModelPickerComponent