From eb2fa69f582fb14bd77d385857231c8a46b4470c Mon Sep 17 00:00:00 2001 From: "dayuan.jiang" Date: Sat, 11 Jul 2026 22:30:20 +0900 Subject: [PATCH] refactor: drop request-body token override, keep env-only config The unauthenticated /api/validate-model endpoint should not let callers raise the token budget; the env var / admin setting alone fixes #883. Also import the shared constants in the settings registry instead of duplicating them, and move the setting to the Features group alongside the other validation settings. --- app/api/validate-model/route.ts | 5 ----- lib/admin/settings-registry.ts | 27 ++++++++++++++++----------- lib/model-validation.ts | 18 ++++++------------ tests/unit/model-validation.test.ts | 17 +++++++++++++---- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/app/api/validate-model/route.ts b/app/api/validate-model/route.ts index 0cf1eda2..748ad936 100644 --- a/app/api/validate-model/route.ts +++ b/app/api/validate-model/route.ts @@ -32,9 +32,6 @@ interface ValidateRequest { awsRegion?: string // Vertex AI specific vertexApiKey?: string // Express Mode API key - // Optional test token budget override - maxTokens?: number - max_tokens?: number } export async function POST(req: Request) { @@ -52,8 +49,6 @@ export async function POST(req: Request) { vertexApiKey, } = body const validationMaxTokens = resolveModelValidationMaxTokens( - body.maxTokens, - body.max_tokens, process.env.MODEL_VALIDATION_MAX_TOKENS, ) diff --git a/lib/admin/settings-registry.ts b/lib/admin/settings-registry.ts index fad1b99d..76f09aed 100644 --- a/lib/admin/settings-registry.ts +++ b/lib/admin/settings-registry.ts @@ -10,6 +10,11 @@ // - ADMIN_PASSWORD / SETTINGS_FILE: bootstrap values, env-only to avoid lockout // - Per-provider reasoning/thinking tuning vars: env-only (see env.example) +import { + DEFAULT_MODEL_VALIDATION_MAX_TOKENS, + MAX_MODEL_VALIDATION_MAX_TOKENS, +} from "@/lib/model-validation" + export type SettingType = "string" | "secret" | "number" | "boolean" | "enum" export interface SettingDef { @@ -88,17 +93,6 @@ export const SETTINGS_REGISTRY: SettingDef[] = [ label: "Max Output Tokens", min: 1, }, - { - key: "MODEL_VALIDATION_MAX_TOKENS", - group: "generation", - type: "number", - label: "Model Validation Max Tokens", - description: - "Token budget for model test requests. Increase for reasoning models that may emit thinking tokens first.", - min: 1, - max: 64000, - default: "1000", - }, // ── Access Control ─────────────────────────────────────────────── { @@ -134,6 +128,17 @@ export const SETTINGS_REGISTRY: SettingDef[] = [ label: "Validation Timeout (ms)", min: 1000, }, + { + key: "MODEL_VALIDATION_MAX_TOKENS", + group: "features", + type: "number", + label: "Model Validation Max Tokens", + description: + "Token budget for model test requests. Increase for reasoning models that may emit thinking tokens first.", + min: 1, + max: MAX_MODEL_VALIDATION_MAX_TOKENS, + default: String(DEFAULT_MODEL_VALIDATION_MAX_TOKENS), + }, { key: "ENABLE_HISTORY_XML_REPLACE", group: "features", diff --git a/lib/model-validation.ts b/lib/model-validation.ts index 2bf98453..f8b8c4c8 100644 --- a/lib/model-validation.ts +++ b/lib/model-validation.ts @@ -7,22 +7,16 @@ export function parseModelValidationMaxTokens(value: unknown): number | null { const numeric = typeof value === "number" ? value : Number(String(value).trim()) - if ( - !Number.isFinite(numeric) || - !Number.isInteger(numeric) || - numeric < 1 - ) { + if (!Number.isInteger(numeric) || numeric < 1) { return null } return Math.min(numeric, MAX_MODEL_VALIDATION_MAX_TOKENS) } -export function resolveModelValidationMaxTokens(...sources: unknown[]): number { - for (const source of sources) { - const parsed = parseModelValidationMaxTokens(source) - if (parsed !== null) return parsed - } - - return DEFAULT_MODEL_VALIDATION_MAX_TOKENS +export function resolveModelValidationMaxTokens(value: unknown): number { + return ( + parseModelValidationMaxTokens(value) ?? + DEFAULT_MODEL_VALIDATION_MAX_TOKENS + ) } diff --git a/tests/unit/model-validation.test.ts b/tests/unit/model-validation.test.ts index 867621d6..e0c61ee5 100644 --- a/tests/unit/model-validation.test.ts +++ b/tests/unit/model-validation.test.ts @@ -8,14 +8,23 @@ import { describe("model validation token budget", () => { it("defaults to a larger reasoning-friendly budget", () => { - expect(resolveModelValidationMaxTokens()).toBe( + expect(resolveModelValidationMaxTokens(undefined)).toBe( DEFAULT_MODEL_VALIDATION_MAX_TOKENS, ) }) - it("prefers the first valid source", () => { - expect(resolveModelValidationMaxTokens(2000, 3000)).toBe(2000) - expect(resolveModelValidationMaxTokens("bad", "3000")).toBe(3000) + it("parses valid env values", () => { + expect(resolveModelValidationMaxTokens("2000")).toBe(2000) + expect(resolveModelValidationMaxTokens(" 300 ")).toBe(300) + }) + + it("falls back to the default on invalid values", () => { + expect(resolveModelValidationMaxTokens("abc")).toBe( + DEFAULT_MODEL_VALIDATION_MAX_TOKENS, + ) + expect(resolveModelValidationMaxTokens("")).toBe( + DEFAULT_MODEL_VALIDATION_MAX_TOKENS, + ) }) it("rejects invalid values", () => {