diff --git a/CHANGELOG.md b/CHANGELOG.md index c64548aa5a0..2a08c7fb2e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -118,6 +118,7 @@ Docs: https://docs.openclaw.ai - Gateway/session stores: regenerate the Swift push-test protocol models and align Windows native session-store realpath handling so protocol checks and sync session discovery stop drifting on Windows. (#44266) thanks @jalehman. - Context engine/session routing: forward optional `sessionKey` through context-engine lifecycle calls so plugins can see structured routing metadata during bootstrap, assembly, post-turn ingestion, and compaction. (#44157) thanks @jalehman. - Agents/failover: classify z.ai `network_error` stop reasons as retryable timeouts so provider connectivity failures trigger fallback instead of surfacing raw unhandled-stop-reason errors. (#43884) Thanks @hougangdev. +- Config/Anthropic startup: inline Anthropic alias normalization during config load so gateway startup no longer crashes on dated Anthropic model refs like `anthropic/claude-sonnet-4-20250514`. (#45520) Thanks @BunsDev. - Memory/session sync: add mode-aware post-compaction session reindexing with `agents.defaults.compaction.postIndexSync` plus `agents.defaults.memorySearch.sync.sessions.postCompactionForce`, so compacted session memory can refresh immediately without forcing every deployment into synchronous reindexing. (#25561) thanks @rodrigouroz. - Telegram/model picker: make inline model button selections persist the chosen session model correctly, clear overrides when selecting the configured default, and include effective fallback models in `/models` button validation. (#40105) Thanks @avirweb. - Telegram/native command sync: suppress expected `BOT_COMMANDS_TOO_MUCH` retry error noise, add a final fallback summary log, and document the difference between command-menu overflow and real Telegram network failures. diff --git a/src/agents/model-selection.test.ts b/src/agents/model-selection.test.ts index 35ac52dcf26..e2d90f355bc 100644 --- a/src/agents/model-selection.test.ts +++ b/src/agents/model-selection.test.ts @@ -121,6 +121,12 @@ describe("model-selection", () => { defaultProvider: "anthropic", expected: { provider: "anthropic", model: "claude-sonnet-4-6" }, }, + { + name: "keeps dated anthropic model ids unchanged", + variants: ["anthropic/claude-sonnet-4-20250514", "claude-sonnet-4-20250514"], + defaultProvider: "anthropic", + expected: { provider: "anthropic", model: "claude-sonnet-4-20250514" }, + }, { name: "normalizes deprecated google flash preview ids", variants: ["google/gemini-3.1-flash-preview", "gemini-3.1-flash-preview"], diff --git a/src/agents/model-selection.ts b/src/agents/model-selection.ts index 7bbd8ed8ba7..6606b0bc4b4 100644 --- a/src/agents/model-selection.ts +++ b/src/agents/model-selection.ts @@ -31,13 +31,6 @@ export type ModelAliasIndex = { byKey: Map; }; -const ANTHROPIC_MODEL_ALIASES: Record = { - "opus-4.6": "claude-opus-4-6", - "opus-4.5": "claude-opus-4-5", - "sonnet-4.6": "claude-sonnet-4-6", - "sonnet-4.5": "claude-sonnet-4-5", -}; - function normalizeAliasKey(value: string): string { return value.trim().toLowerCase(); } @@ -151,7 +144,20 @@ function normalizeAnthropicModelId(model: string): string { return trimmed; } const lower = trimmed.toLowerCase(); - return ANTHROPIC_MODEL_ALIASES[lower] ?? trimmed; + // Keep alias resolution local so bundled startup paths cannot trip a TDZ on + // a module-level alias table while config parsing is still initializing. + switch (lower) { + case "opus-4.6": + return "claude-opus-4-6"; + case "opus-4.5": + return "claude-opus-4-5"; + case "sonnet-4.6": + return "claude-sonnet-4-6"; + case "sonnet-4.5": + return "claude-sonnet-4-5"; + default: + return trimmed; + } } function normalizeProviderModelId(provider: string, model: string): string { diff --git a/src/config/config.pruning-defaults.test.ts b/src/config/config.pruning-defaults.test.ts index f2f66ce6bac..ad28175e5db 100644 --- a/src/config/config.pruning-defaults.test.ts +++ b/src/config/config.pruning-defaults.test.ts @@ -73,6 +73,33 @@ describe("config pruning defaults", () => { }); }); + it("adds cacheRetention defaults for dated Anthropic primary model refs", async () => { + await withTempHome(async (home) => { + await writeConfigForTest(home, { + auth: { + profiles: { + "anthropic:api": { provider: "anthropic", mode: "api_key" }, + }, + }, + agents: { + defaults: { + model: { primary: "anthropic/claude-sonnet-4-20250514" }, + }, + }, + }); + + const cfg = loadConfig(); + + expect(cfg.agents?.defaults?.contextPruning?.mode).toBe("cache-ttl"); + expect(cfg.agents?.defaults?.contextPruning?.ttl).toBe("1h"); + expect(cfg.agents?.defaults?.heartbeat?.every).toBe("30m"); + expect( + cfg.agents?.defaults?.models?.["anthropic/claude-sonnet-4-20250514"]?.params + ?.cacheRetention, + ).toBe("short"); + }); + }); + it("adds default cacheRetention for Anthropic Claude models on Bedrock", async () => { await withTempHome(async (home) => { await writeConfigForTest(home, {