validate.js
2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* 模型路由配置断言。调用方可用于写入门禁或非阻断启动诊断。
*
* 与运行期错误的分工:运行期只应出现**环境性**失败(上游 429/超时、key 全冷却),
* 配置性失败必须在启动期一次性列清。判据是「这条不变量在启动时是否已经可判定」:
* - adapter 是否在网关注册表里 —— 启动时可判定。
* - runtime 会调的 mode 是否配了链 —— 启动时可判定(mode 列表由装配层声明,是入口不变量)。
* 校验「表里已有的行是否自洽」不够:**空表天然自洽**。零行配置一路绿灯启动、第一个请求才抛
* `no chain configured for mode 'kp'`,正是这类校验漏掉入口不变量的后果。
*/
/**
* 文本能力接入的 adapter 必须是网关注册表里的键,否则该接入在运行期必然 unknown provider。
* @param {Array<{ name:string, adapter:string }>} providerRows enabled 的 model_provider_capability 文本能力行
* @param {string[]} adapters `registeredProviders()` 结果
* @returns {void}
*/
export function validateAdapters(providerRows, adapters) {
const known = new Set(adapters)
const bad = providerRows.filter((row) => !known.has(row.adapter))
if (bad.length === 0) return
const detail = bad.map((row) => `${row.name}(adapter=${row.adapter})`).join(', ')
throw new Error(`llm-router: 文本能力接入的 adapter 未注册: ${detail};可用适配器: ${adapters.join(', ')}`)
}
/**
* runtime 实际会 `forMode(mode)` 的每个场景,必须在 `mode_model_config` 有 enabled 且链非空的行。
* requiredModes 由装配层声明(它是唯一知道 runtime 调哪些 mode 的地方),不从表里反推。
* @param {{ [mode: string]: Array<{ provider:string, model:string }> }} config normalizeConfig 产物
* @param {string[]} requiredModes runtime 会调用的场景名
* @returns {void}
*/
export function validateModes(config, requiredModes) {
const missing = requiredModes.filter((mode) => !config[mode] || config[mode].length === 0)
if (missing.length === 0) return
const configured = Object.keys(config)
throw new Error(
`llm-router: runtime 需要的场景在 mode_model_config 无可用链: ${missing.join(', ')};` +
`现有 enabled 场景: ${configured.length > 0 ? configured.join(', ') : '(空表)'}。` +
'配置说明:apps/visual-game-server/tools/model-config/README.md。',
)
}