Compare commits

..
1 Commits
Author SHA1 Message Date
opencode 014614d35b release: v1.18.31 2026-09-14 17:47:16 +00:00
3 changed files with 38 additions and 41 deletions
-1
View File
@@ -20,4 +20,3 @@ Slickstef11
usrnk1
vimtor
StarpTech
vaprdev
+37 -39
View File
@@ -1,5 +1,5 @@
import { Resource } from "@opencode-ai/console-resource"
import { and, Database, eq, isNotNull, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js"
import { and, Database, eq, 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,6 +34,7 @@ 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/")
@@ -41,23 +42,44 @@ export async function proxyInference(
: request.headers.get("authorization")?.split(" ")[1]
if (!key || key === "public") return undefined
// 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")
// 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")
const destination = new URL(Resource.ConsoleMigration.inferenceUrl)
// Imported connections must use this same workspace/provider-derived ID.
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
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
destination.pathname = `${destination.pathname.replace(/\/$/, "")}${target}`
destination.search = url.search
destination.hash = ""
@@ -87,30 +109,6 @@ 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." } },
@@ -160,7 +160,7 @@ export async function handler(
if (
authInfo &&
opts.modelList === "lite" &&
["deepseek-v4.1-flash", "deepseek-flash", "deepseek-v4-flash", "deepseek-v4-pro"].includes(modelInfo.id) &&
["deepseek-v4-flash", "deepseek-v4-pro"].includes(modelInfo.id) &&
!allowedRegions?.includes("cn")
)
throw new RegionError(