From 8efd8783d05dee0825699d2fae57facc3c2beee5 Mon Sep 17 00:00:00 2001 From: Shoubhit Dash Date: Thu, 25 Jun 2026 20:36:02 +0530 Subject: [PATCH] fix(schema): adapt legacy catalog responses --- packages/core/src/model.ts | 28 ++++++++++++++++++++++++ packages/core/src/provider.ts | 16 ++++++++++++++ packages/server/src/handlers/model.ts | 3 ++- packages/server/src/handlers/provider.ts | 7 ++++-- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/core/src/model.ts b/packages/core/src/model.ts index bae4408560..293954ecb2 100644 --- a/packages/core/src/model.ts +++ b/packages/core/src/model.ts @@ -78,6 +78,34 @@ export const Info = Schema.Struct({ export type MutableInfo = Omit, "api"> & { api: ProviderV2.MutableApi } +export function flatten(info: Info): Model.Info { + return Model.Info.make({ + id: info.id, + modelID: info.api.id === info.id ? undefined : info.api.id, + providerID: info.providerID, + family: info.family, + name: info.name, + package: info.api.type === "aisdk" ? `aisdk:${info.api.package}` : undefined, + settings: { + ...info.api.settings, + ...(info.api.url === undefined ? {} : { baseURL: info.api.url }), + }, + headers: info.request.headers, + body: info.request.body, + capabilities: info.capabilities, + variants: info.variants.map((variant) => ({ + id: variant.id, + headers: variant.headers, + body: variant.body, + })), + time: info.time, + cost: info.cost, + status: info.status, + enabled: info.enabled, + limit: info.limit, + }) +} + export function parse(input: string): { providerID: ProviderV2.ID; modelID: ID } { const [providerID, ...modelID] = input.split("/") return { diff --git a/packages/core/src/provider.ts b/packages/core/src/provider.ts index d1a541dd65..40f1f357d6 100644 --- a/packages/core/src/provider.ts +++ b/packages/core/src/provider.ts @@ -59,3 +59,19 @@ export type MutableApi = T extends Api : never export type MutableInfo = Omit, "api"> & { api: MutableApi } + +export function flatten(info: Info): Provider.Info { + return Provider.Info.make({ + id: info.id, + integrationID: info.integrationID, + name: info.name, + disabled: info.disabled, + package: info.api.type === "aisdk" ? `aisdk:${info.api.package}` : "", + settings: { + ...info.api.settings, + ...(info.api.url === undefined ? {} : { baseURL: info.api.url }), + }, + headers: info.request.headers, + body: info.request.body, + }) +} diff --git a/packages/server/src/handlers/model.ts b/packages/server/src/handlers/model.ts index 36639ae7b1..a2c2fd4960 100644 --- a/packages/server/src/handlers/model.ts +++ b/packages/server/src/handlers/model.ts @@ -3,6 +3,7 @@ import { Effect } from "effect" import { HttpApiBuilder } from "effect/unstable/httpapi" import { Api } from "../api" import { response } from "../location" +import { ModelV2 } from "@opencode-ai/core/model" export const ModelHandler = HttpApiBuilder.group(Api, "server.model", (handlers) => Effect.gen(function* () { @@ -10,7 +11,7 @@ export const ModelHandler = HttpApiBuilder.group(Api, "server.model", (handlers) "model.list", Effect.fn(function* () { const catalog = yield* Catalog.Service - return yield* response(catalog.model.available()) + return yield* response(catalog.model.available().pipe(Effect.map((models) => models.map(ModelV2.flatten)))) }), ) }), diff --git a/packages/server/src/handlers/provider.ts b/packages/server/src/handlers/provider.ts index c3f25ab0df..9144cde29f 100644 --- a/packages/server/src/handlers/provider.ts +++ b/packages/server/src/handlers/provider.ts @@ -3,6 +3,7 @@ import { Effect } from "effect" import { HttpApiBuilder } from "effect/unstable/httpapi" import { Api } from "../api" import { ProviderNotFoundError } from "@opencode-ai/protocol/errors" +import { ProviderV2 } from "@opencode-ai/core/provider" import { response } from "../location" export const ProviderHandler = HttpApiBuilder.group(Api, "server.provider", (handlers) => @@ -12,7 +13,9 @@ export const ProviderHandler = HttpApiBuilder.group(Api, "server.provider", (han "provider.list", Effect.fn(function* () { const catalog = yield* Catalog.Service - return yield* response(catalog.provider.available()) + return yield* response( + catalog.provider.available().pipe(Effect.map((providers) => providers.map(ProviderV2.flatten))), + ) }), ) .handle( @@ -25,7 +28,7 @@ export const ProviderHandler = HttpApiBuilder.group(Api, "server.provider", (han providerID: ctx.params.providerID, message: `Provider not found: ${ctx.params.providerID}`, }) - return yield* response(Effect.succeed(provider)) + return yield* response(Effect.succeed(ProviderV2.flatten(provider))) }), ) }),