From c1e4b1c9bf248e61a358659d5eac217ba2d83993 Mon Sep 17 00:00:00 2001 From: chaochaoweb3 <49186707+chaochaoweb3@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:48:04 +0800 Subject: [PATCH 1/3] fix: make model validation token budget configurable --- app/api/validate-model/route.ts | 13 +++++++++-- env.example | 5 +++++ lib/admin/settings-registry.ts | 11 +++++++++ lib/i18n/dictionaries/en.json | 4 ++++ lib/i18n/dictionaries/ja.json | 4 ++++ lib/i18n/dictionaries/zh-Hant.json | 4 ++++ lib/i18n/dictionaries/zh.json | 4 ++++ lib/model-validation.ts | 28 +++++++++++++++++++++++ tests/unit/model-validation.test.ts | 35 +++++++++++++++++++++++++++++ 9 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 lib/model-validation.ts create mode 100644 tests/unit/model-validation.test.ts diff --git a/app/api/validate-model/route.ts b/app/api/validate-model/route.ts index 6f3b5b90..0cf1eda2 100644 --- a/app/api/validate-model/route.ts +++ b/app/api/validate-model/route.ts @@ -15,6 +15,7 @@ import { isAihubmixStandardBaseURL, normalizeMiniMaxBaseURL, } from "@/lib/ai-providers" +import { resolveModelValidationMaxTokens } from "@/lib/model-validation" import { allowPrivateUrls, isPrivateUrl } from "@/lib/ssrf-protection" import { PROVIDER_INFO, type ProviderName } from "@/lib/types/model-config" @@ -31,6 +32,9 @@ 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) { @@ -47,6 +51,11 @@ export async function POST(req: Request) { // Note: Express Mode only needs vertexApiKey vertexApiKey, } = body + const validationMaxTokens = resolveModelValidationMaxTokens( + body.maxTokens, + body.max_tokens, + process.env.MODEL_VALIDATION_MAX_TOKENS, + ) if (!provider || !modelId) { return NextResponse.json( @@ -299,7 +308,7 @@ export async function POST(req: Request) { messages: [ { role: "user", content: "Say 'OK'" }, ], - max_tokens: 20, + max_tokens: validationMaxTokens, stream: true, enable_thinking: false, }), @@ -413,7 +422,7 @@ export async function POST(req: Request) { await generateText({ model, prompt: "Say 'OK'", - maxOutputTokens: 20, + maxOutputTokens: validationMaxTokens, }) const responseTime = Date.now() - startTime diff --git a/env.example b/env.example index fbf1d499..088f81fb 100644 --- a/env.example +++ b/env.example @@ -121,6 +121,11 @@ AI_MODEL=global.anthropic.claude-sonnet-4-5-20250929-v1:0 # Leave unset for models that don't support temperature (e.g., GPT-5.1 reasoning models) # TEMPERATURE=0 +# Model Validation (Optional) +# Token budget used when testing model availability. Increase for reasoning +# models that may emit thinking tokens before final content. +# MODEL_VALIDATION_MAX_TOKENS=1000 + # Access Control (Optional) # ACCESS_CODE_LIST=your-secret-code,another-code diff --git a/lib/admin/settings-registry.ts b/lib/admin/settings-registry.ts index 6419b3c5..fad1b99d 100644 --- a/lib/admin/settings-registry.ts +++ b/lib/admin/settings-registry.ts @@ -88,6 +88,17 @@ 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 ─────────────────────────────────────────────── { diff --git a/lib/i18n/dictionaries/en.json b/lib/i18n/dictionaries/en.json index 0de5b7b3..5a6abcd9 100644 --- a/lib/i18n/dictionaries/en.json +++ b/lib/i18n/dictionaries/en.json @@ -494,6 +494,10 @@ "MAX_OUTPUT_TOKENS": { "label": "Max Output Tokens" }, + "MODEL_VALIDATION_MAX_TOKENS": { + "label": "Model Validation Max Tokens", + "description": "Token budget for model test requests. Increase for reasoning models that may emit thinking tokens first." + }, "ACCESS_CODE_LIST": { "label": "Access Codes", "description": "Comma-separated list. Users must enter one to chat. Empty = open access." diff --git a/lib/i18n/dictionaries/ja.json b/lib/i18n/dictionaries/ja.json index 262d7c6a..b5b63135 100644 --- a/lib/i18n/dictionaries/ja.json +++ b/lib/i18n/dictionaries/ja.json @@ -494,6 +494,10 @@ "MAX_OUTPUT_TOKENS": { "label": "最大出力トークン数" }, + "MODEL_VALIDATION_MAX_TOKENS": { + "label": "モデル検証の最大トークン数", + "description": "モデルテストリクエストのトークン予算。推論モデルが先に思考トークンを出す場合は増やしてください。" + }, "ACCESS_CODE_LIST": { "label": "アクセスコード", "description": "カンマ区切りのリスト。チャットにはいずれかの入力が必要です。空 = オープンアクセス。" diff --git a/lib/i18n/dictionaries/zh-Hant.json b/lib/i18n/dictionaries/zh-Hant.json index 586dcc44..27715e97 100644 --- a/lib/i18n/dictionaries/zh-Hant.json +++ b/lib/i18n/dictionaries/zh-Hant.json @@ -494,6 +494,10 @@ "MAX_OUTPUT_TOKENS": { "label": "最大輸出 token 數" }, + "MODEL_VALIDATION_MAX_TOKENS": { + "label": "模型驗證最大 token 數", + "description": "模型測試請求的 token 預算。推理模型可能先輸出思考 token,可適當調大。" + }, "ACCESS_CODE_LIST": { "label": "存取碼", "description": "以逗號分隔的清單。使用者需輸入其中之一才能聊天。留空 = 開放存取。" diff --git a/lib/i18n/dictionaries/zh.json b/lib/i18n/dictionaries/zh.json index 38c64049..e617fb99 100644 --- a/lib/i18n/dictionaries/zh.json +++ b/lib/i18n/dictionaries/zh.json @@ -494,6 +494,10 @@ "MAX_OUTPUT_TOKENS": { "label": "最大输出 token 数" }, + "MODEL_VALIDATION_MAX_TOKENS": { + "label": "模型验证最大 token 数", + "description": "模型测试请求的 token 预算。推理模型可能先输出思考 token,可适当调大。" + }, "ACCESS_CODE_LIST": { "label": "访问码", "description": "以逗号分隔的列表。用户需输入其中之一才能聊天。留空 = 开放访问。" diff --git a/lib/model-validation.ts b/lib/model-validation.ts new file mode 100644 index 00000000..2bf98453 --- /dev/null +++ b/lib/model-validation.ts @@ -0,0 +1,28 @@ +export const DEFAULT_MODEL_VALIDATION_MAX_TOKENS = 1000 +export const MAX_MODEL_VALIDATION_MAX_TOKENS = 64000 + +export function parseModelValidationMaxTokens(value: unknown): number | null { + if (value === undefined || value === null || value === "") return null + + const numeric = + typeof value === "number" ? value : Number(String(value).trim()) + + if ( + !Number.isFinite(numeric) || + !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 +} diff --git a/tests/unit/model-validation.test.ts b/tests/unit/model-validation.test.ts new file mode 100644 index 00000000..867621d6 --- /dev/null +++ b/tests/unit/model-validation.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from "vitest" +import { + DEFAULT_MODEL_VALIDATION_MAX_TOKENS, + MAX_MODEL_VALIDATION_MAX_TOKENS, + parseModelValidationMaxTokens, + resolveModelValidationMaxTokens, +} from "@/lib/model-validation" + +describe("model validation token budget", () => { + it("defaults to a larger reasoning-friendly budget", () => { + expect(resolveModelValidationMaxTokens()).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("rejects invalid values", () => { + expect(parseModelValidationMaxTokens(0)).toBeNull() + expect(parseModelValidationMaxTokens(-1)).toBeNull() + expect(parseModelValidationMaxTokens(1.5)).toBeNull() + expect(parseModelValidationMaxTokens("abc")).toBeNull() + }) + + it("caps very large values", () => { + expect( + resolveModelValidationMaxTokens( + MAX_MODEL_VALIDATION_MAX_TOKENS + 1, + ), + ).toBe(MAX_MODEL_VALIDATION_MAX_TOKENS) + }) +}) From eb2fa69f582fb14bd77d385857231c8a46b4470c Mon Sep 17 00:00:00 2001 From: "dayuan.jiang" Date: Sat, 11 Jul 2026 22:30:20 +0900 Subject: [PATCH 2/3] 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", () => { From 42ab388118bfe1a00e9576edfe20343ac0539501 Mon Sep 17 00:00:00 2001 From: chaochaoweb3 <49186707+chaochaoweb3@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:08:10 +0800 Subject: [PATCH 3/3] refactor: hardcode model validation token budget --- app/api/validate-model/route.ts | 9 ++---- env.example | 5 ---- lib/admin/settings-registry.ts | 16 ----------- lib/i18n/dictionaries/en.json | 4 --- lib/i18n/dictionaries/ja.json | 4 --- lib/i18n/dictionaries/zh-Hant.json | 4 --- lib/i18n/dictionaries/zh.json | 4 --- lib/model-validation.ts | 22 --------------- tests/unit/model-validation.test.ts | 44 ----------------------------- 9 files changed, 2 insertions(+), 110 deletions(-) delete mode 100644 lib/model-validation.ts delete mode 100644 tests/unit/model-validation.test.ts diff --git a/app/api/validate-model/route.ts b/app/api/validate-model/route.ts index 748ad936..872a2392 100644 --- a/app/api/validate-model/route.ts +++ b/app/api/validate-model/route.ts @@ -15,7 +15,6 @@ import { isAihubmixStandardBaseURL, normalizeMiniMaxBaseURL, } from "@/lib/ai-providers" -import { resolveModelValidationMaxTokens } from "@/lib/model-validation" import { allowPrivateUrls, isPrivateUrl } from "@/lib/ssrf-protection" import { PROVIDER_INFO, type ProviderName } from "@/lib/types/model-config" @@ -48,10 +47,6 @@ export async function POST(req: Request) { // Note: Express Mode only needs vertexApiKey vertexApiKey, } = body - const validationMaxTokens = resolveModelValidationMaxTokens( - process.env.MODEL_VALIDATION_MAX_TOKENS, - ) - if (!provider || !modelId) { return NextResponse.json( { valid: false, error: "Provider and model ID are required" }, @@ -303,7 +298,7 @@ export async function POST(req: Request) { messages: [ { role: "user", content: "Say 'OK'" }, ], - max_tokens: validationMaxTokens, + max_tokens: 1000, stream: true, enable_thinking: false, }), @@ -417,7 +412,7 @@ export async function POST(req: Request) { await generateText({ model, prompt: "Say 'OK'", - maxOutputTokens: validationMaxTokens, + maxOutputTokens: 1000, }) const responseTime = Date.now() - startTime diff --git a/env.example b/env.example index 088f81fb..fbf1d499 100644 --- a/env.example +++ b/env.example @@ -121,11 +121,6 @@ AI_MODEL=global.anthropic.claude-sonnet-4-5-20250929-v1:0 # Leave unset for models that don't support temperature (e.g., GPT-5.1 reasoning models) # TEMPERATURE=0 -# Model Validation (Optional) -# Token budget used when testing model availability. Increase for reasoning -# models that may emit thinking tokens before final content. -# MODEL_VALIDATION_MAX_TOKENS=1000 - # Access Control (Optional) # ACCESS_CODE_LIST=your-secret-code,another-code diff --git a/lib/admin/settings-registry.ts b/lib/admin/settings-registry.ts index 76f09aed..6419b3c5 100644 --- a/lib/admin/settings-registry.ts +++ b/lib/admin/settings-registry.ts @@ -10,11 +10,6 @@ // - 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 { @@ -128,17 +123,6 @@ 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/i18n/dictionaries/en.json b/lib/i18n/dictionaries/en.json index 5a6abcd9..0de5b7b3 100644 --- a/lib/i18n/dictionaries/en.json +++ b/lib/i18n/dictionaries/en.json @@ -494,10 +494,6 @@ "MAX_OUTPUT_TOKENS": { "label": "Max Output Tokens" }, - "MODEL_VALIDATION_MAX_TOKENS": { - "label": "Model Validation Max Tokens", - "description": "Token budget for model test requests. Increase for reasoning models that may emit thinking tokens first." - }, "ACCESS_CODE_LIST": { "label": "Access Codes", "description": "Comma-separated list. Users must enter one to chat. Empty = open access." diff --git a/lib/i18n/dictionaries/ja.json b/lib/i18n/dictionaries/ja.json index b5b63135..262d7c6a 100644 --- a/lib/i18n/dictionaries/ja.json +++ b/lib/i18n/dictionaries/ja.json @@ -494,10 +494,6 @@ "MAX_OUTPUT_TOKENS": { "label": "最大出力トークン数" }, - "MODEL_VALIDATION_MAX_TOKENS": { - "label": "モデル検証の最大トークン数", - "description": "モデルテストリクエストのトークン予算。推論モデルが先に思考トークンを出す場合は増やしてください。" - }, "ACCESS_CODE_LIST": { "label": "アクセスコード", "description": "カンマ区切りのリスト。チャットにはいずれかの入力が必要です。空 = オープンアクセス。" diff --git a/lib/i18n/dictionaries/zh-Hant.json b/lib/i18n/dictionaries/zh-Hant.json index 27715e97..586dcc44 100644 --- a/lib/i18n/dictionaries/zh-Hant.json +++ b/lib/i18n/dictionaries/zh-Hant.json @@ -494,10 +494,6 @@ "MAX_OUTPUT_TOKENS": { "label": "最大輸出 token 數" }, - "MODEL_VALIDATION_MAX_TOKENS": { - "label": "模型驗證最大 token 數", - "description": "模型測試請求的 token 預算。推理模型可能先輸出思考 token,可適當調大。" - }, "ACCESS_CODE_LIST": { "label": "存取碼", "description": "以逗號分隔的清單。使用者需輸入其中之一才能聊天。留空 = 開放存取。" diff --git a/lib/i18n/dictionaries/zh.json b/lib/i18n/dictionaries/zh.json index e617fb99..38c64049 100644 --- a/lib/i18n/dictionaries/zh.json +++ b/lib/i18n/dictionaries/zh.json @@ -494,10 +494,6 @@ "MAX_OUTPUT_TOKENS": { "label": "最大输出 token 数" }, - "MODEL_VALIDATION_MAX_TOKENS": { - "label": "模型验证最大 token 数", - "description": "模型测试请求的 token 预算。推理模型可能先输出思考 token,可适当调大。" - }, "ACCESS_CODE_LIST": { "label": "访问码", "description": "以逗号分隔的列表。用户需输入其中之一才能聊天。留空 = 开放访问。" diff --git a/lib/model-validation.ts b/lib/model-validation.ts deleted file mode 100644 index f8b8c4c8..00000000 --- a/lib/model-validation.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const DEFAULT_MODEL_VALIDATION_MAX_TOKENS = 1000 -export const MAX_MODEL_VALIDATION_MAX_TOKENS = 64000 - -export function parseModelValidationMaxTokens(value: unknown): number | null { - if (value === undefined || value === null || value === "") return null - - const numeric = - typeof value === "number" ? value : Number(String(value).trim()) - - if (!Number.isInteger(numeric) || numeric < 1) { - return null - } - - return Math.min(numeric, MAX_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 deleted file mode 100644 index e0c61ee5..00000000 --- a/tests/unit/model-validation.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { describe, expect, it } from "vitest" -import { - DEFAULT_MODEL_VALIDATION_MAX_TOKENS, - MAX_MODEL_VALIDATION_MAX_TOKENS, - parseModelValidationMaxTokens, - resolveModelValidationMaxTokens, -} from "@/lib/model-validation" - -describe("model validation token budget", () => { - it("defaults to a larger reasoning-friendly budget", () => { - expect(resolveModelValidationMaxTokens(undefined)).toBe( - DEFAULT_MODEL_VALIDATION_MAX_TOKENS, - ) - }) - - 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", () => { - expect(parseModelValidationMaxTokens(0)).toBeNull() - expect(parseModelValidationMaxTokens(-1)).toBeNull() - expect(parseModelValidationMaxTokens(1.5)).toBeNull() - expect(parseModelValidationMaxTokens("abc")).toBeNull() - }) - - it("caps very large values", () => { - expect( - resolveModelValidationMaxTokens( - MAX_MODEL_VALIDATION_MAX_TOKENS + 1, - ), - ).toBe(MAX_MODEL_VALIDATION_MAX_TOKENS) - }) -})