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 } from "remeda" import { DialogSelect, type DialogSelectRef } from "@tui/ui/dialog-select" import { useDialog } from "@tui/ui/dialog" import { Keybind } from "@/util/keybind" import * as fuzzysort from "fuzzysort" export function useConnected() { const sync = useSync() return createMemo(() => sync.data.provider.length > 0) } export function DialogModel() { const local = useLocal() const sync = useSync() const dialog = useDialog() const [ref, setRef] = createSignal>() const [query, setQuery] = createSignal("") const options = createMemo(() => { const q = query() const favorites = local.model.favorite() const recents = local.model.recent() const recentList = recents.filter( (item) => !favorites.some((fav) => fav.providerID === item.providerID && fav.modelID === item.modelID), ) const favoriteOptions = 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, category: "Favorites", onSelect: () => { dialog.clear() local.model.set( { providerID: provider.id, modelID: model.id, }, { recent: true }, ) }, }, ] }) const recentOptions = 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, category: "Recent", onSelect: () => { dialog.clear() local.model.set( { providerID: provider.id, modelID: model.id, }, { recent: true }, ) }, }, ] }) const providerOptions = pipe( sync.data.provider, flatMap((provider) => pipe( provider.models, entries(), filter(([_, info]) => info.status !== "deprecated"), 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, onSelect() { dialog.clear() local.model.set( { providerID: provider.id, modelID: model, }, { recent: true }, ) }, } }), filter((x) => { const value = x.value const inFavorites = favorites.some( (item) => item.providerID === value.providerID && item.modelID === value.modelID, ) if (inFavorites) return false const inRecents = recentList.some( (item) => item.providerID === value.providerID && item.modelID === value.modelID, ) if (inRecents) return false return true }), sortBy((x) => x.title), ), ), ) if (q) { const filteredFavorites = fuzzysort.go(q, favoriteOptions, { keys: ["title"] }).map((x) => x.obj) const filteredRecents = fuzzysort .go(q, recentOptions, { keys: ["title"] }) .map((x) => x.obj) .slice(0, 5) const filteredProviders = fuzzysort.go(q, providerOptions, { keys: ["title"] }).map((x) => x.obj) return [...filteredFavorites, ...filteredRecents, ...filteredProviders] } return [...favoriteOptions, ...recentOptions, ...providerOptions] }) return ( { local.model.toggleFavorite(option.value as { providerID: string; modelID: string }) }, }, ]} ref={setRef} onFilter={setQuery} skipFilter={true} title="Select model" current={local.model.current()} options={options()} /> ) }