|
1 | 1 | import type { RuntimeEnv } from "../../runtime.js"; |
| 2 | +import { loadModelCatalog } from "../../agents/model-catalog.js"; |
| 3 | +import { modelKey } from "../../agents/model-selection.js"; |
| 4 | +import { readConfigFileSnapshot } from "../../config/config.js"; |
2 | 5 | import { logConfigUpdated } from "../../config/logging.js"; |
3 | | -import { applyDefaultModelPrimaryUpdate, updateConfig } from "./shared.js"; |
| 6 | +import { applyDefaultModelPrimaryUpdate, resolveModelTarget, updateConfig } from "./shared.js"; |
4 | 7 |
|
5 | 8 | export async function modelsSetCommand(modelRaw: string, runtime: RuntimeEnv) { |
6 | | - const updated = await updateConfig((cfg) => { |
7 | | - return applyDefaultModelPrimaryUpdate({ cfg, modelRaw, field: "model" }); |
| 9 | + // 1. Read config and resolve the model reference |
| 10 | + const snapshot = await readConfigFileSnapshot(); |
| 11 | + if (!snapshot.valid) { |
| 12 | + const issues = snapshot.issues.map((i) => `- ${i.path}: ${i.message}`).join("\n"); |
| 13 | + throw new Error(`Invalid config at ${snapshot.path}\n${issues}`); |
| 14 | + } |
| 15 | + const cfg = snapshot.config; |
| 16 | + const resolved = resolveModelTarget({ raw: modelRaw, cfg }); |
| 17 | + const key = `${resolved.provider}/${resolved.model}`; |
| 18 | + |
| 19 | + // 2. Validate against catalog (skip when catalog is empty — initial setup) |
| 20 | + const catalog = await loadModelCatalog({ config: cfg }); |
| 21 | + if (catalog.length > 0) { |
| 22 | + const catalogKeys = new Set(catalog.map((e) => modelKey(e.provider, e.id))); |
| 23 | + if (!catalogKeys.has(key)) { |
| 24 | + throw new Error( |
| 25 | + `Unknown model: ${key}\nModel not found in catalog. Run "openclaw models list" to see available models.`, |
| 26 | + ); |
| 27 | + } |
| 28 | + } |
| 29 | + |
| 30 | + // 3. Track whether this is a new entry |
| 31 | + const isNewEntry = !cfg.agents?.defaults?.models?.[key]; |
| 32 | + |
| 33 | + // 4. Update config (using upstream's helper for the actual mutation) |
| 34 | + const updated = await updateConfig((c) => { |
| 35 | + return applyDefaultModelPrimaryUpdate({ cfg: c, modelRaw, field: "model" }); |
8 | 36 | }); |
9 | 37 |
|
| 38 | + // 5. Warn and log |
| 39 | + if (isNewEntry) { |
| 40 | + runtime.log( |
| 41 | + `Warning: "${key}" had no entry in models config. Added with empty config (no provider routing).`, |
| 42 | + ); |
| 43 | + } |
10 | 44 | logConfigUpdated(runtime); |
11 | 45 | runtime.log(`Default model: ${updated.agents?.defaults?.model?.primary ?? modelRaw}`); |
12 | 46 | } |
0 commit comments