diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx index c30b8d12a9..b210f8ed35 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx @@ -7,6 +7,27 @@ import { useDialog } from "@tui/ui/dialog" import { createDialogProviderOptions, DialogProvider } from "./dialog-provider" import { useKeybind } from "../context/keybind" import * as fuzzysort from "fuzzysort" +import type { Provider } from "@opencode-ai/sdk/v2" + +function pickLatest(models: [string, Provider["models"][string]][]) { + const picks: Record = {} + for (const item of models) { + const model = item[0] + const info = item[1] + const key = info.family ?? model + const prev = picks[key] + if (!prev) { + picks[key] = item + continue + } + if (info.release_date !== prev[1].release_date) { + if (info.release_date > prev[1].release_date) picks[key] = item + continue + } + if (model > prev[0]) picks[key] = item + } + return Object.values(picks) +} export function useConnected() { const sync = useSync() @@ -21,6 +42,7 @@ export function DialogModel(props: { providerID?: string }) { const dialog = useDialog() const keybind = useKeybind() const [query, setQuery] = createSignal("") + const [all, setAll] = createSignal(false) const connected = useConnected() const providers = createDialogProviderOptions() @@ -72,8 +94,8 @@ export function DialogModel(props: { providerID?: string }) { (provider) => provider.id !== "opencode", (provider) => provider.name, ), - flatMap((provider) => - pipe( + flatMap((provider) => { + const items = pipe( provider.models, entries(), filter(([_, info]) => info.status !== "deprecated"), @@ -104,8 +126,9 @@ export function DialogModel(props: { providerID?: string }) { (x) => x.footer !== "Free", (x) => x.title, ), - ), - ), + ) + return items + }), ) const popularProviders = !connected() @@ -154,6 +177,13 @@ export function DialogModel(props: { providerID?: string }) { local.model.toggleFavorite(option.value as { providerID: string; modelID: string }) }, }, + { + keybind: keybind.all.model_show_all_toggle?.[0], + title: all() ? "Show latest only" : "Show all models", + onTrigger: () => { + setAll((value) => !value) + }, + }, ]} onFilter={setQuery} flat={true} diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index a231a53007..6a03c15f70 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -778,6 +778,7 @@ export namespace Config { stash_delete: z.string().optional().default("ctrl+d").describe("Delete stash entry"), model_provider_list: z.string().optional().default("ctrl+a").describe("Open provider list from model dialog"), model_favorite_toggle: z.string().optional().default("ctrl+f").describe("Toggle model favorite status"), + model_show_all_toggle: z.string().optional().default("ctrl+o").describe("Toggle showing all models"), session_share: z.string().optional().default("none").describe("Share current session"), session_unshare: z.string().optional().default("none").describe("Unshare current session"), session_interrupt: z.string().optional().default("escape").describe("Interrupt current session"), diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 9543e5b579..8d8fd3a4af 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1030,6 +1030,10 @@ export type KeybindsConfig = { * Toggle model favorite status */ model_favorite_toggle?: string + /** + * Toggle showing all models + */ + model_show_all_toggle?: string /** * Share current session */