diff --git a/package.json b/package.json index a5adbb8e7..345a9546f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ ], "scripts": { "build": "tsdown", - "dev": "bun run --watch ./src/main.ts", + "dev": "bun run --watch ./src/main.ts start", "knip": "knip-bun", "lint": "eslint --cache", "lint:all": "eslint --cache .", diff --git a/src/lib/utils.ts b/src/lib/utils.ts index cc80be667..d3b4b4371 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,6 +1,6 @@ import consola from "consola" -import { getModels } from "~/services/copilot/get-models" +import { getModels, type Model } from "~/services/copilot/get-models" import { getVSCodeVersion } from "~/services/get-vscode-version" import { state } from "./state" @@ -18,6 +18,21 @@ export async function cacheModels(): Promise { state.models = models } +/** + * Returns models filtered by model_picker_enabled and deduplicated by id. + */ +export function getAvailableModels(): Model[] { + if (!state.models) return [] + + const seen = new Set() + return state.models.data.filter((model) => { + if (!model.model_picker_enabled) return false + if (seen.has(model.id)) return false + seen.add(model.id) + return true + }) +} + export const cacheVSCodeVersion = async () => { const response = await getVSCodeVersion() state.vsCodeVersion = response diff --git a/src/routes/models/route.ts b/src/routes/models/route.ts index 5254e2af7..3450da2d5 100644 --- a/src/routes/models/route.ts +++ b/src/routes/models/route.ts @@ -1,8 +1,8 @@ import { Hono } from "hono" import { forwardError } from "~/lib/error" +import { cacheModels, getAvailableModels } from "~/lib/utils" import { state } from "~/lib/state" -import { cacheModels } from "~/lib/utils" export const modelRoutes = new Hono() @@ -13,7 +13,7 @@ modelRoutes.get("/", async (c) => { await cacheModels() } - const models = state.models?.data.map((model) => ({ + const models = getAvailableModels().map((model) => ({ id: model.id, object: "model", type: "model", diff --git a/src/start.ts b/src/start.ts index 14abbbdff..f2068dab8 100644 --- a/src/start.ts +++ b/src/start.ts @@ -11,7 +11,11 @@ import { initProxyFromEnv } from "./lib/proxy" import { generateEnvScript } from "./lib/shell" import { state } from "./lib/state" import { setupCopilotToken, setupGitHubToken } from "./lib/token" -import { cacheModels, cacheVSCodeVersion } from "./lib/utils" +import { + cacheModels, + cacheVSCodeVersion, + getAvailableModels, +} from "./lib/utils" import { server } from "./server" interface RunServerOptions { @@ -60,20 +64,22 @@ export async function runServer(options: RunServerOptions): Promise { await setupCopilotToken() await cacheModels() + const availableModels = getAvailableModels() + consola.info( - `Available models: \n${state.models?.data.map((model) => `- ${model.id}`).join("\n")}`, + `Available models: \n${availableModels.map((model) => `- ${model.id}`).join("\n")}`, ) const serverUrl = `http://localhost:${options.port}` if (options.claudeCode) { - invariant(state.models, "Models should be loaded by now") + invariant(availableModels.length > 0, "Models should be loaded by now") const selectedModel = await consola.prompt( "Select a model to use with Claude Code", { type: "select", - options: state.models.data.map((model) => model.id), + options: availableModels.map((model) => model.id), }, ) @@ -81,7 +87,7 @@ export async function runServer(options: RunServerOptions): Promise { "Select a small model to use with Claude Code", { type: "select", - options: state.models.data.map((model) => model.id), + options: availableModels.map((model) => model.id), }, )