diff --git a/packages/console/app/src/routes/zen/go/v1/models.ts b/packages/console/app/src/routes/zen/go/v1/models.ts index 83ef74fb6148..d2d8bb08dfb6 100644 --- a/packages/console/app/src/routes/zen/go/v1/models.ts +++ b/packages/console/app/src/routes/zen/go/v1/models.ts @@ -1,12 +1,16 @@ import type { APIEvent } from "@solidjs/start/server" import { ZenData } from "@opencode-ai/console-core/model.js" -import { buildModelsResponse, buildOptionsResponse } from "../../util/modelsHandler" +import { buildModelsResponse, buildOptionsResponse, getNpm } from "../../util/modelsHandler" export async function OPTIONS(_input: APIEvent) { return buildOptionsResponse() } export async function GET(_input: APIEvent) { - const models = Object.keys(ZenData.list("lite").models) + const catalog = ZenData.list("lite") + const models = Object.entries(catalog.models).map(([id, model]) => ({ + id, + npm: getNpm(model, catalog.providers), + })) return buildModelsResponse(models) } diff --git a/packages/console/app/src/routes/zen/util/modelsHandler.ts b/packages/console/app/src/routes/zen/util/modelsHandler.ts index 102e4151b9fc..4aca209f3f16 100644 --- a/packages/console/app/src/routes/zen/util/modelsHandler.ts +++ b/packages/console/app/src/routes/zen/util/modelsHandler.ts @@ -1,3 +1,15 @@ +import type { ZenData } from "@opencode-ai/console-core/model.js" + +const npmByFormat: Record = { + anthropic: "@ai-sdk/anthropic", + google: "@ai-sdk/google", + openai: "@ai-sdk/openai", + "oa-compat": "@ai-sdk/openai-compatible", +} + +type CatalogModel = ReturnType["models"][string] +type CatalogProviders = ReturnType["providers"] + export async function buildOptionsResponse() { return new Response(null, { status: 200, @@ -9,17 +21,28 @@ export async function buildOptionsResponse() { }) } -export async function buildModelsResponse(models: string[]) { +export function getNpm(model: CatalogModel, providers: CatalogProviders) { + const format = Array.isArray(model) + ? model[0]?.formatFilter + : model.providers + .map((provider) => providers[provider.id]?.format) + .find((format): format is ZenData.Format => format !== undefined) + + return npmByFormat[format ?? "oa-compat"] +} + +export async function buildModelsResponse(models: { id: string; npm: string }[]) { return new Response( JSON.stringify({ object: "list", data: models - .filter((id) => !id.startsWith("alpha-")) - .map((id) => ({ - id, + .filter((model) => !model.id.startsWith("alpha-")) + .map((model) => ({ + id: model.id, object: "model", created: Math.floor(Date.now() / 1000), owned_by: "opencode", + npm: model.npm, })), }), { diff --git a/packages/console/app/src/routes/zen/v1/models.ts b/packages/console/app/src/routes/zen/v1/models.ts index 68c3cac69467..720e7a4a693e 100644 --- a/packages/console/app/src/routes/zen/v1/models.ts +++ b/packages/console/app/src/routes/zen/v1/models.ts @@ -4,13 +4,14 @@ import { and, Database, eq, isNull } from "@opencode-ai/console-core/drizzle/ind import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js" import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js" import { ModelTable } from "@opencode-ai/console-core/schema/model.sql.js" -import { buildOptionsResponse, buildModelsResponse } from "~/routes/zen/util/modelsHandler" +import { buildOptionsResponse, buildModelsResponse, getNpm } from "~/routes/zen/util/modelsHandler" export async function OPTIONS(_input: APIEvent) { return buildOptionsResponse() } export async function GET(input: APIEvent) { + const catalog = ZenData.list("full") const disabledModels = await (() => { const apiKey = input.request.headers.get("authorization")?.split(" ")[1] if (!apiKey) return [] as string[] @@ -28,9 +29,13 @@ export async function GET(input: APIEvent) { ) })() - const models = Object.keys(ZenData.list("full").models) - .filter((id) => !id.endsWith(":global")) - .filter((id) => !disabledModels.includes(id)) + const models = Object.entries(catalog.models) + .filter(([id]) => !id.endsWith(":global")) + .filter(([id]) => !disabledModels.includes(id)) + .map(([id, model]) => ({ + id, + npm: getNpm(model, catalog.providers), + })) return buildModelsResponse(models) }