From 5cf4e13588c4af05046cbfddebe1d2d97da6cf6b Mon Sep 17 00:00:00 2001 From: vprdev Date: Mon, 14 Sep 2026 14:32:56 -0700 Subject: [PATCH] fix(console): route new Console keys to inference (#49036) --- .../console/app/src/lib/inference-proxy.ts | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/packages/console/app/src/lib/inference-proxy.ts b/packages/console/app/src/lib/inference-proxy.ts index b572c361b65..1eade3ff8fe 100644 --- a/packages/console/app/src/lib/inference-proxy.ts +++ b/packages/console/app/src/lib/inference-proxy.ts @@ -1,5 +1,5 @@ import { Resource } from "@opencode-ai/console-resource" -import { and, Database, eq, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js" +import { and, Database, eq, isNotNull, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js" import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js" import { ProviderTable } from "@opencode-ai/console-core/schema/provider.sql.js" import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js" @@ -34,7 +34,6 @@ export async function proxyInference( : undefined) if (!path) return undefined - const go = url.pathname.startsWith("/zen/go/") const key = url.pathname.endsWith("/messages") ? request.headers.get("x-api-key") : path.startsWith("/google/") @@ -42,44 +41,23 @@ export async function proxyInference( : request.headers.get("authorization")?.split(" ")[1] if (!key || key === "public") return undefined - // Routing only; the destination owns authentication and revocation after cutover. - const workspace = await Database.use((tx) => - tx - .select({ - id: WorkspaceTable.id, - migratedAt: WorkspaceTable.migrated_at, - provider: ProviderTable.provider, - }) - .from(KeyTable) - .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID)) - .leftJoin( - ProviderTable, - !go && generation?.provider - ? and( - eq(ProviderTable.workspaceID, KeyTable.workspaceID), - eq(ProviderTable.provider, generation.provider), - isNull(ProviderTable.timeDeleted), - sql`length(${ProviderTable.credentials}) > 0`, - ) - : sql`false`, - ) - .where(eq(KeyTable.key, key)) - .limit(1) - .then((rows) => rows[0]), - ) - if (!workspace?.migratedAt) return undefined - const model = workspace.provider ? generation?.model : undefined - if (workspace.provider && !model) throw new Error("Legacy BYOK model mapping is unavailable") + // New Console keys are never in the legacy key table; every legacy key is `sk-`. + const legacy = !key.startsWith("oc_sk_") + const workspace = legacy ? await migratedWorkspace(key, generation?.provider) : undefined + if (legacy && !workspace) return undefined + const model = workspace?.provider ? generation?.model : undefined + if (workspace?.provider && !model) throw new Error("Legacy BYOK model mapping is unavailable") const destination = new URL(Resource.ConsoleMigration.inferenceUrl) // Imported connections must use this same workspace/provider-derived ID. - const target = model - ? `/custom/conn_${workspace.id.slice(4)}_${workspace.provider}${ - path.startsWith("/google/") - ? `/models/${encodeURIComponent(model)}${url.pathname.slice(url.pathname.lastIndexOf(":"))}` - : url.pathname.slice("/zen/v1".length) - }` - : path + const target = + model && workspace + ? `/custom/conn_${workspace.id.slice(4)}_${workspace.provider}${ + path.startsWith("/google/") + ? `/models/${encodeURIComponent(model)}${url.pathname.slice(url.pathname.lastIndexOf(":"))}` + : url.pathname.slice("/zen/v1".length) + }` + : path destination.pathname = `${destination.pathname.replace(/\/$/, "")}${target}` destination.search = url.search destination.hash = "" @@ -109,6 +87,30 @@ export async function proxyInference( return fetch(forwarded, { redirect: "manual" }) } +// Routing only; the destination owns authentication and revocation after cutover. +function migratedWorkspace(key: string, provider?: string) { + return Database.use((tx) => + tx + .select({ id: WorkspaceTable.id, provider: ProviderTable.provider }) + .from(KeyTable) + .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID)) + .leftJoin( + ProviderTable, + provider + ? and( + eq(ProviderTable.workspaceID, KeyTable.workspaceID), + eq(ProviderTable.provider, provider), + isNull(ProviderTable.timeDeleted), + sql`length(${ProviderTable.credentials}) > 0`, + ) + : sql`false`, + ) + .where(and(eq(KeyTable.key, key), isNotNull(WorkspaceTable.migrated_at))) + .limit(1) + .then((rows) => rows[0]), + ) +} + export function inferenceUnavailable() { return Response.json( { error: { type: "api_error", message: "Inference routing is unavailable. Please retry later." } },