diff --git a/src/config/defaults.ts b/src/config/defaults.ts index d68be922f..a576a0221 100644 --- a/src/config/defaults.ts +++ b/src/config/defaults.ts @@ -211,18 +211,16 @@ export function applyModelDefaults(cfg: OpenClawConfig): OpenClawConfig { } const existingAgent = nextCfg.agents?.defaults; - if (!existingAgent) return mutated ? nextCfg : cfg; - const existingModels = existingAgent.models ?? {}; - if (Object.keys(existingModels).length === 0) return mutated ? nextCfg : cfg; + const existingModels = existingAgent?.models ?? {}; const nextModels: Record = { ...existingModels, }; + // Always apply default model aliases, creating entries if they don't exist for (const [alias, target] of Object.entries(DEFAULT_MODEL_ALIASES)) { const entry = nextModels[target]; - if (!entry) continue; - if (entry.alias !== undefined) continue; + if (entry?.alias !== undefined) continue; // User already defined an alias nextModels[target] = { ...entry, alias }; mutated = true; } diff --git a/src/config/model-alias-defaults.test.ts b/src/config/model-alias-defaults.test.ts index 82bff85da..890db53a1 100644 --- a/src/config/model-alias-defaults.test.ts +++ b/src/config/model-alias-defaults.test.ts @@ -4,6 +4,34 @@ import { applyModelDefaults } from "./defaults.js"; import type { OpenClawConfig } from "./types.js"; describe("applyModelDefaults", () => { + it("adds default aliases even when no user models are configured", () => { + // Regression test: previously applyModelDefaults returned early when + // agents.defaults.models was empty, causing cron jobs using aliases + // like "sonnet" to fail with "Unknown model" errors. + const cfg = {} satisfies MoltbotConfig; + const next = applyModelDefaults(cfg); + + expect(next.agents?.defaults?.models?.["anthropic/claude-opus-4-5"]?.alias).toBe("opus"); + expect(next.agents?.defaults?.models?.["anthropic/claude-sonnet-4-5"]?.alias).toBe("sonnet"); + expect(next.agents?.defaults?.models?.["openai/gpt-5.2"]?.alias).toBe("gpt"); + expect(next.agents?.defaults?.models?.["openai/gpt-5-mini"]?.alias).toBe("gpt-mini"); + expect(next.agents?.defaults?.models?.["google/gemini-3-pro-preview"]?.alias).toBe("gemini"); + expect(next.agents?.defaults?.models?.["google/gemini-3-flash-preview"]?.alias).toBe( + "gemini-flash", + ); + }); + + it("adds default aliases when agents.defaults exists but models is empty", () => { + const cfg = { + agents: { + defaults: {}, + }, + } satisfies MoltbotConfig; + const next = applyModelDefaults(cfg); + + expect(next.agents?.defaults?.models?.["anthropic/claude-sonnet-4-5"]?.alias).toBe("sonnet"); + }); + it("adds default aliases when models are present", () => { const cfg = { agents: {