import { Combobox } from "@kobalte/core/combobox" import { For, Show, createEffect, createMemo } from "solid-js" import { providers, fetchProviders } from "../stores/sessions" import { ChevronDown } from "lucide-solid" import type { Provider, Model } from "../types/session" import Kbd from "./kbd" interface ModelSelectorProps { instanceId: string sessionId: string currentModel: { providerId: string; modelId: string } onModelChange: (model: { providerId: string; modelId: string }) => Promise } interface FlatModel extends Model { providerName: string } export default function ModelSelector(props: ModelSelectorProps) { const instanceProviders = () => providers().get(props.instanceId) || [] let inputRef!: HTMLInputElement createEffect(() => { if (instanceProviders().length === 0) { fetchProviders(props.instanceId).catch(console.error) } }) const handleFocus = (e: FocusEvent) => { const input = e.target as HTMLInputElement input.select() } const allModels = createMemo(() => instanceProviders().flatMap((p) => p.models.map((m) => ({ ...m, providerName: p.name, })), ), ) const currentModelValue = createMemo(() => allModels().find((m) => m.providerId === props.currentModel.providerId && m.id === props.currentModel.modelId), ) const handleChange = async (value: FlatModel | null) => { if (!value) return if (value.providerId !== props.currentModel.providerId || value.id !== props.currentModel.modelId) { await props.onModelChange({ providerId: value.providerId, modelId: value.id }) } } return (
`${m.providerId}/${m.id}`} optionTextValue={(m) => `${m.name} ${m.providerName} ${m.providerId}/${m.id}`} optionLabel="name" placeholder="Search models..." defaultFilter="contains" triggerMode="focus" allowsEmptyCollection={false} itemComponent={(itemProps) => (
{itemProps.item.rawValue.name} {itemProps.item.rawValue.providerName} • {itemProps.item.rawValue.providerId}/ {itemProps.item.rawValue.id}
)} >
) }