import { createMemo, createSignal } from "solid-js" import { useLocal } from "@tui/context/local" import { useSync } from "@tui/context/sync" import { map, pipe, flatMap, entries, filter, sortBy, take } from "remeda" import { DialogSelect, type DialogSelectRef } from "@tui/ui/dialog-select" import { useDialog } from "@tui/ui/dialog" import { createDialogProviderOptions, DialogProvider } from "./dialog-provider" import { Keybind } from "@/util/keybind" export function useConnected() { const sync = useSync() return createMemo(() => sync.data.provider.some((x) => x.id !== "opencode" || Object.values(x.models).some((y) => y.cost?.input !== 0)), ) } export function DialogModel(props: { providerID?: string }) { const local = useLocal() const sync = useSync() const dialog = useDialog() const [ref, setRef] = createSignal>() const connected = useConnected() const providers = createDialogProviderOptions() const showExtra = createMemo(() => { if (!connected()) return false if (props.providerID) return false return true }) const options = createMemo(() => { const query = ref()?.filter const favorites = showExtra() ? local.model.favorite() : [] const recents = local.model.recent() const recentList = showExtra() ? recents .filter( (item) => !favorites.some((fav) => fav.providerID === item.providerID && fav.modelID === item.modelID), ) .slice(0, 5) : [] const favoriteOptions = !query ? favorites.flatMap((item) => { const provider = sync.data.provider.find((x) => x.id === item.providerID) if (!provider) return [] const model = provider.models[item.modelID] if (!model) return [] return [ { key: item, value: { providerID: provider.id, modelID: model.id, }, title: model.name ?? item.modelID, description: provider.name, category: "Favorites", disabled: provider.id === "opencode" && model.id.includes("-nano"), footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined, onSelect: () => { dialog.clear() local.model.set( { providerID: provider.id, modelID: model.id, }, { recent: true }, ) }, }, ] }) : [] const recentOptions = !query ? recentList.flatMap((item) => { const provider = sync.data.provider.find((x) => x.id === item.providerID) if (!provider) return [] const model = provider.models[item.modelID] if (!model) return [] return [ { key: item, value: { providerID: provider.id, modelID: model.id, }, title: model.name ?? item.modelID, description: provider.name, category: "Recent", disabled: provider.id === "opencode" && model.id.includes("-nano"), footer: model.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined, onSelect: () => { dialog.clear() local.model.set( { providerID: provider.id, modelID: model.id, }, { recent: true }, ) }, }, ] }) : [] return [ ...favoriteOptions, ...recentOptions, ...pipe( sync.data.provider, sortBy( (provider) => provider.id !== "opencode", (provider) => provider.name, ), flatMap((provider) => pipe( provider.models, entries(), filter(([_, info]) => info.status !== "deprecated"), filter(([_, info]) => (props.providerID ? info.providerID === props.providerID : true)), map(([model, info]) => { const value = { providerID: provider.id, modelID: model, } return { value, title: info.name ?? model, description: favorites.some( (item) => item.providerID === value.providerID && item.modelID === value.modelID, ) ? "(Favorite)" : undefined, category: connected() ? provider.name : undefined, disabled: provider.id === "opencode" && model.includes("-nano"), footer: info.cost?.input === 0 && provider.id === "opencode" ? "Free" : undefined, onSelect() { dialog.clear() local.model.set( { providerID: provider.id, modelID: model, }, { recent: true }, ) }, } }), filter((x) => { if (query) return true const value = x.value const inFavorites = favorites.some( (item) => item.providerID === value.providerID && item.modelID === value.modelID, ) if (inFavorites) return false const inRecents = recents.some( (item) => item.providerID === value.providerID && item.modelID === value.modelID, ) if (inRecents) return false return true }), sortBy( (x) => x.footer !== "Free", (x) => x.title, ), ), ), ), ...(!connected() ? pipe( providers(), map((option) => { return { ...option, category: "Popular providers", } }), take(6), ) : []), ] }) const provider = createMemo(() => props.providerID ? sync.data.provider.find((x) => x.id === props.providerID) : null, ) const title = createMemo(() => { if (provider()) return provider()!.name return "Select model" }) return ( ) }, }, { keybind: Keybind.parse("ctrl+f")[0], title: "Favorite", disabled: !connected(), onTrigger: (option) => { local.model.toggleFavorite(option.value as { providerID: string; modelID: string }) }, }, ]} ref={setRef} title={title()} current={local.model.current()} options={options()} /> ) }