Skip to content

Commit 5cf4e13

Browse files
authored
fix(console): route new Console keys to inference (anomalyco#49036)
1 parent 4ae1765 commit 5cf4e13

1 file changed

Lines changed: 39 additions & 37 deletions

File tree

‎packages/console/app/src/lib/inference-proxy.ts‎

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Resource } from "@opencode-ai/console-resource"
2-
import { and, Database, eq, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js"
2+
import { and, Database, eq, isNotNull, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js"
33
import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js"
44
import { ProviderTable } from "@opencode-ai/console-core/schema/provider.sql.js"
55
import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
@@ -34,52 +34,30 @@ export async function proxyInference(
3434
: undefined)
3535
if (!path) return undefined
3636

37-
const go = url.pathname.startsWith("/zen/go/")
3837
const key = url.pathname.endsWith("/messages")
3938
? request.headers.get("x-api-key")
4039
: path.startsWith("/google/")
4140
? request.headers.get("x-goog-api-key")
4241
: request.headers.get("authorization")?.split(" ")[1]
4342
if (!key || key === "public") return undefined
4443

45-
// Routing only; the destination owns authentication and revocation after cutover.
46-
const workspace = await Database.use((tx) =>
47-
tx
48-
.select({
49-
id: WorkspaceTable.id,
50-
migratedAt: WorkspaceTable.migrated_at,
51-
provider: ProviderTable.provider,
52-
})
53-
.from(KeyTable)
54-
.innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID))
55-
.leftJoin(
56-
ProviderTable,
57-
!go && generation?.provider
58-
? and(
59-
eq(ProviderTable.workspaceID, KeyTable.workspaceID),
60-
eq(ProviderTable.provider, generation.provider),
61-
isNull(ProviderTable.timeDeleted),
62-
sql`length(${ProviderTable.credentials}) > 0`,
63-
)
64-
: sql`false`,
65-
)
66-
.where(eq(KeyTable.key, key))
67-
.limit(1)
68-
.then((rows) => rows[0]),
69-
)
70-
if (!workspace?.migratedAt) return undefined
71-
const model = workspace.provider ? generation?.model : undefined
72-
if (workspace.provider && !model) throw new Error("Legacy BYOK model mapping is unavailable")
44+
// New Console keys are never in the legacy key table; every legacy key is `sk-`.
45+
const legacy = !key.startsWith("oc_sk_")
46+
const workspace = legacy ? await migratedWorkspace(key, generation?.provider) : undefined
47+
if (legacy && !workspace) return undefined
48+
const model = workspace?.provider ? generation?.model : undefined
49+
if (workspace?.provider && !model) throw new Error("Legacy BYOK model mapping is unavailable")
7350

7451
const destination = new URL(Resource.ConsoleMigration.inferenceUrl)
7552
// Imported connections must use this same workspace/provider-derived ID.
76-
const target = model
77-
? `/custom/conn_${workspace.id.slice(4)}_${workspace.provider}${
78-
path.startsWith("/google/")
79-
? `/models/${encodeURIComponent(model)}${url.pathname.slice(url.pathname.lastIndexOf(":"))}`
80-
: url.pathname.slice("/zen/v1".length)
81-
}`
82-
: path
53+
const target =
54+
model && workspace
55+
? `/custom/conn_${workspace.id.slice(4)}_${workspace.provider}${
56+
path.startsWith("/google/")
57+
? `/models/${encodeURIComponent(model)}${url.pathname.slice(url.pathname.lastIndexOf(":"))}`
58+
: url.pathname.slice("/zen/v1".length)
59+
}`
60+
: path
8361
destination.pathname = `${destination.pathname.replace(/\/$/, "")}${target}`
8462
destination.search = url.search
8563
destination.hash = ""
@@ -109,6 +87,30 @@ export async function proxyInference(
10987
return fetch(forwarded, { redirect: "manual" })
11088
}
11189

90+
// Routing only; the destination owns authentication and revocation after cutover.
91+
function migratedWorkspace(key: string, provider?: string) {
92+
return Database.use((tx) =>
93+
tx
94+
.select({ id: WorkspaceTable.id, provider: ProviderTable.provider })
95+
.from(KeyTable)
96+
.innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID))
97+
.leftJoin(
98+
ProviderTable,
99+
provider
100+
? and(
101+
eq(ProviderTable.workspaceID, KeyTable.workspaceID),
102+
eq(ProviderTable.provider, provider),
103+
isNull(ProviderTable.timeDeleted),
104+
sql`length(${ProviderTable.credentials}) > 0`,
105+
)
106+
: sql`false`,
107+
)
108+
.where(and(eq(KeyTable.key, key), isNotNull(WorkspaceTable.migrated_at)))
109+
.limit(1)
110+
.then((rows) => rows[0]),
111+
)
112+
}
113+
112114
export function inferenceUnavailable() {
113115
return Response.json(
114116
{ error: { type: "api_error", message: "Inference routing is unavailable. Please retry later." } },

0 commit comments

Comments
 (0)