feat(console): block reported model providers

This commit is contained in:
Frank 2026-07-20 19:28:59 +00:00
commit 40d3787d62
9 changed files with 3282 additions and 1 deletions

View file

@ -374,6 +374,8 @@ export const dict = {
"zen.api.error.userMonthlyLimitReached":
"You have reached your monthly spending limit of ${{amount}}. Manage your limits here: {{membersUrl}}",
"zen.api.error.modelDisabled": "Model is disabled",
"zen.api.error.modelAccessBlocked":
"{{models}} model access has been disabled for this workspace following a report from {{provider}}. Contact support@opencode.ai for help.",
"zen.api.error.regionNotAllowed":
"This model is hosted in China. If you would like to use this model, enable it in your settings: {{consoleGoUrl}}",
"zen.api.error.trialEnded":

View file

@ -3,6 +3,7 @@ export class CreditsError extends Error {}
export class MonthlyLimitError extends Error {}
export class UserLimitError extends Error {}
export class ModelError extends Error {}
export class ModelAccessError extends Error {}
export class RegionError extends Error {}
class LimitError extends Error {

View file

@ -21,6 +21,7 @@ import {
MonthlyLimitError,
UserLimitError,
ModelError,
ModelAccessError,
RegionError,
RateLimitError,
FreeUsageLimitError,
@ -52,6 +53,7 @@ import { createProviderBudgetTracker } from "./providerBudgetTracker"
import { accumulateUsage, HOT_WORKSPACES } from "./usageBatcher"
import { Workspace } from "@opencode-ai/console-core/workspace.js"
import { countryFromRequest } from "~/lib/request-country"
import { ModelAccess } from "@opencode-ai/console-core/model-access.js"
type ZenData = Awaited<ReturnType<typeof ZenData.list>>
type RetryOptions = {
@ -128,6 +130,7 @@ export async function handler(
: createKeyRateLimiter(modelInfo.id, modelInfo.rateLimit, zenApiKey, input.request)
await rateLimiter?.check()
const authInfo = await authenticate(modelInfo, zenApiKey)
validateModelAccess(authInfo, modelInfo)
const allowedRegions = authInfo?.region
? authInfo.region
: await (async () => {
@ -466,7 +469,7 @@ export async function handler(
} catch {}
}
if (error instanceof RegionError)
if (error instanceof RegionError || error instanceof ModelAccessError)
return new Response(
JSON.stringify({
type: "error",
@ -697,6 +700,7 @@ export async function handler(
workspace: {
id: WorkspaceTable.id,
region: WorkspaceTable.region,
blockedModelProviders: WorkspaceTable.blocked_model_providers,
},
billing: {
balance: BillingTable.balance,
@ -800,6 +804,7 @@ export async function handler(
apiKeyId: data.apiKey,
workspaceID: data.workspace.id,
region: data.workspace.region,
blockedModelProviders: data.workspace.blockedModelProviders,
billing: data.billing,
user: data.user,
black: data.black,
@ -988,6 +993,13 @@ export async function handler(
return "balance"
}
function validateModelAccess(authInfo: AuthInfo, modelInfo: ModelInfo) {
if (!authInfo) return
if (!ModelAccess.blocked(modelInfo.id, authInfo.blockedModelProviders)) return
const provider = ModelAccess.provider(modelInfo.id)!
throw new ModelAccessError(t("zen.api.error.modelAccessBlocked", ModelAccess.label(provider)))
}
function validateModelSettings(billingSource: BillingSource, authInfo: AuthInfo) {
if (billingSource === "lite") return
if (billingSource === "anonymous") return