mirror of
https://github.com/anomalyco/opencode.git
synced 2026-09-28 05:23:19 +08:00
fix(console): route new Console keys to inference (#49036)
This commit is contained in:
@@ -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." } },
|
||||
|
||||
Reference in New Issue
Block a user