diff --git a/src/agents/utils.test.ts b/src/agents/utils.test.ts
index 161ad3a7b..b63a34827 100644
--- a/src/agents/utils.test.ts
+++ b/src/agents/utils.test.ts
@@ -180,7 +180,7 @@ describe("createBuiltinAgents with model overrides", () => {
// #then
expect(agents.sisyphus).toBeDefined()
- expect(agents.sisyphus.model).toBe("anthropic/claude-opus-4-6")
+ expect(agents.sisyphus.model).toBe("anthropic/claude-opus-4.6")
} finally {
cacheSpy.mockRestore()
fetchSpy.mockRestore()
@@ -918,7 +918,7 @@ describe("createBuiltinAgents with requiresAnyModel gating (sisyphus)", () => {
// #then
expect(agents.sisyphus).toBeDefined()
- expect(agents.sisyphus.model).toBe("anthropic/claude-opus-4-6")
+ expect(agents.sisyphus.model).toBe("anthropic/claude-opus-4.6")
} finally {
cacheSpy.mockRestore()
fetchSpy.mockRestore()
diff --git a/src/cli/__snapshots__/model-fallback.test.ts.snap b/src/cli/__snapshots__/model-fallback.test.ts.snap
index e6dee4dc8..3e1b2f50c 100644
--- a/src/cli/__snapshots__/model-fallback.test.ts.snap
+++ b/src/cli/__snapshots__/model-fallback.test.ts.snap
@@ -69,62 +69,67 @@ exports[`generateModelConfig single native provider uses Claude models when only
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": {
"atlas": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
+ "fallback_models": [
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
+ ],
"model": "anthropic/claude-haiku-4-5",
},
"metis": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"multimodal-looker": {
"model": "opencode/gpt-5-nano",
},
"oracle": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"prometheus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
"deep": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"quick": {
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
"ultrabrain": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"unspecified-high": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"unspecified-low": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"writing": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
}
@@ -135,63 +140,68 @@ exports[`generateModelConfig single native provider uses Claude models with isMa
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": {
"atlas": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
+ "fallback_models": [
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
+ ],
"model": "anthropic/claude-haiku-4-5",
},
"metis": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"multimodal-looker": {
"model": "opencode/gpt-5-nano",
},
"oracle": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"prometheus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
"deep": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"quick": {
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
"ultrabrain": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"unspecified-high": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"unspecified-low": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"writing": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
}
@@ -516,9 +526,14 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"variant": "medium",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
+ "fallback_models": [
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
+ ],
"model": "anthropic/claude-haiku-4-5",
},
"hephaestus": {
@@ -532,13 +547,13 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -565,7 +580,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -582,7 +597,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"model": "google/gemini-3.1-pro-preview",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
@@ -592,7 +607,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"variant": "medium",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
@@ -602,14 +617,14 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"variant": "medium",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
"artistry": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -622,7 +637,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"deep": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -636,7 +651,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"quick": {
"fallback_models": [
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
{
"model": "google/gemini-3-flash-preview",
@@ -651,7 +666,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -668,7 +683,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"model": "google/gemini-3-flash-preview",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"unspecified-low": {
"fallback_models": [
@@ -680,12 +695,12 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"model": "google/gemini-3-flash-preview",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -695,7 +710,7 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"writing": {
"fallback_models": [
{
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
],
"model": "google/gemini-3-flash-preview",
@@ -715,9 +730,14 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"variant": "medium",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
+ "fallback_models": [
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
+ ],
"model": "anthropic/claude-haiku-4-5",
},
"hephaestus": {
@@ -731,13 +751,13 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -764,7 +784,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -781,7 +801,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"model": "google/gemini-3.1-pro-preview",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
@@ -791,7 +811,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"variant": "medium",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
@@ -801,14 +821,14 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"variant": "medium",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
"artistry": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -821,7 +841,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"deep": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -835,7 +855,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"quick": {
"fallback_models": [
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
{
"model": "google/gemini-3-flash-preview",
@@ -850,7 +870,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -864,7 +884,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"unspecified-low": {
@@ -877,12 +897,12 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"model": "google/gemini-3-flash-preview",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -892,7 +912,7 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"writing": {
"fallback_models": [
{
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
],
"model": "google/gemini-3-flash-preview",
@@ -1865,13 +1885,16 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"variant": "medium",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
"fallback_models": [
{
"model": "opencode/minimax-m2.7",
},
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
{
"model": "opencode/claude-haiku-4-5",
},
@@ -1896,13 +1919,13 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -1933,7 +1956,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -1958,7 +1981,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "opencode/gemini-3.1-pro",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
@@ -1981,7 +2004,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "opencode/big-pickle",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
@@ -1997,14 +2020,14 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "opencode/big-pickle",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
"artistry": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -2021,7 +2044,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"deep": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -2039,7 +2062,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"quick": {
"fallback_models": [
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
{
"model": "opencode/claude-haiku-4-5",
@@ -2060,7 +2083,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -2084,7 +2107,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "opencode/gemini-3-flash",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"unspecified-low": {
"fallback_models": [
@@ -2099,7 +2122,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "opencode/gemini-3-flash",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
"fallback_models": [
@@ -2107,7 +2130,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "opencode/glm-5",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -2121,7 +2144,7 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"writing": {
"fallback_models": [
{
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
{
"model": "opencode/claude-sonnet-4-6",
@@ -2389,36 +2412,41 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + ZAI combinat
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": {
"atlas": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
+ "fallback_models": [
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
+ ],
"model": "anthropic/claude-haiku-4-5",
},
"librarian": {
"fallback_models": [
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
],
"model": "zai-coding-plan/glm-4.7",
},
"metis": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"multimodal-looker": {
"model": "zai-coding-plan/glm-4.6v",
},
"oracle": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"prometheus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
@@ -2427,42 +2455,42 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + ZAI combinat
"model": "zai-coding-plan/glm-5",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
"deep": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"quick": {
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
"ultrabrain": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"unspecified-high": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"unspecified-low": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
"model": "zai-coding-plan/glm-5",
},
"writing": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
}
@@ -2473,13 +2501,18 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": {
"atlas": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
+ "fallback_models": [
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
+ ],
"model": "anthropic/claude-haiku-4-5",
},
"metis": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
@@ -2489,7 +2522,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"multimodal-looker": {
@@ -2498,7 +2531,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"oracle": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -2511,22 +2544,22 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"model": "google/gemini-3.1-pro-preview",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
"artistry": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -2540,7 +2573,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"quick": {
@@ -2549,12 +2582,12 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"model": "google/gemini-3-flash-preview",
},
],
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
"ultrabrain": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -2567,7 +2600,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"model": "google/gemini-3-flash-preview",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"unspecified-low": {
"fallback_models": [
@@ -2575,12 +2608,12 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"model": "google/gemini-3-flash-preview",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
"fallback_models": [
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
],
@@ -2590,7 +2623,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"writing": {
"fallback_models": [
{
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
],
"model": "google/gemini-3-flash-preview",
@@ -3015,7 +3048,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"variant": "medium",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
"fallback_models": [
@@ -3025,6 +3058,9 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
{
"model": "opencode/minimax-m2.7",
},
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
{
"model": "opencode/claude-haiku-4-5",
},
@@ -3054,7 +3090,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/minimax-m2.7-highspeed",
},
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
{
"model": "opencode/claude-haiku-4-5",
@@ -3088,7 +3124,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
@@ -3102,7 +3138,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"variant": "xhigh",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3174,7 +3210,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3221,7 +3257,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/gemini-3.1-pro",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
@@ -3259,7 +3295,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/big-pickle",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
@@ -3286,7 +3322,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/big-pickle",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
@@ -3301,7 +3337,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3336,7 +3372,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"variant": "medium",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3372,7 +3408,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/gpt-5.4-mini",
},
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
{
"model": "github-copilot/claude-haiku-4.5",
@@ -3414,7 +3450,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3455,7 +3491,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/gemini-3-flash",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"unspecified-low": {
"fallback_models": [
@@ -3483,7 +3519,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/gemini-3-flash",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
"fallback_models": [
@@ -3502,7 +3538,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/glm-5",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3526,7 +3562,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "opencode/gemini-3-flash",
},
{
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
{
"model": "github-copilot/claude-sonnet-4.6",
@@ -3566,7 +3602,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"variant": "medium",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"explore": {
"fallback_models": [
@@ -3576,6 +3612,9 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
{
"model": "opencode/minimax-m2.7",
},
+ {
+ "model": "anthropic/claude-haiku-4.5",
+ },
{
"model": "opencode/claude-haiku-4-5",
},
@@ -3605,7 +3644,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/minimax-m2.7-highspeed",
},
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
{
"model": "opencode/claude-haiku-4-5",
@@ -3639,7 +3678,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"variant": "high",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"momus": {
@@ -3653,7 +3692,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"variant": "xhigh",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3725,7 +3764,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3772,7 +3811,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/gemini-3.1-pro",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus": {
@@ -3810,7 +3849,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/big-pickle",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"sisyphus-junior": {
@@ -3837,7 +3876,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/big-pickle",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
},
"categories": {
@@ -3852,7 +3891,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3887,7 +3926,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"variant": "medium",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -3923,7 +3962,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/gpt-5.4-mini",
},
{
- "model": "anthropic/claude-haiku-4-5",
+ "model": "anthropic/claude-haiku-4.5",
},
{
"model": "github-copilot/claude-haiku-4.5",
@@ -3965,7 +4004,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"variant": "high",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -4012,7 +4051,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/kimi-k2.5",
},
],
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
"unspecified-low": {
@@ -4041,7 +4080,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/gemini-3-flash",
},
],
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
"visual-engineering": {
"fallback_models": [
@@ -4060,7 +4099,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/glm-5",
},
{
- "model": "anthropic/claude-opus-4-6",
+ "model": "anthropic/claude-opus-4.6",
"variant": "max",
},
{
@@ -4084,7 +4123,7 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "opencode/gemini-3-flash",
},
{
- "model": "anthropic/claude-sonnet-4-6",
+ "model": "anthropic/claude-sonnet-4.6",
},
{
"model": "github-copilot/claude-sonnet-4.6",
diff --git a/src/cli/model-fallback.test.ts b/src/cli/model-fallback.test.ts
index 57ff2c16e..09d002bcb 100644
--- a/src/cli/model-fallback.test.ts
+++ b/src/cli/model-fallback.test.ts
@@ -1,3 +1,5 @@
+///
+
import { describe, expect, test } from "bun:test"
import { generateModelConfig } from "./model-fallback"
@@ -378,7 +380,7 @@ describe("generateModelConfig", () => {
const result = generateModelConfig(config)
// #then
- expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-6")
+ expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4.6")
})
test("Sisyphus is created when multiple fallback providers are available", () => {
@@ -395,7 +397,7 @@ describe("generateModelConfig", () => {
const result = generateModelConfig(config)
// #then
- expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-6")
+ expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4.6")
})
test("Sisyphus resolves to gpt-5.4 medium when only OpenAI is available", () => {
@@ -572,7 +574,11 @@ describe("generateModelConfig", () => {
// #then explore should not have fallback_models (only one chain entry matches)
expect(result.agents?.explore?.model).toBe("anthropic/claude-haiku-4-5")
- expect(result.agents?.explore?.fallback_models).toBeUndefined()
+ expect(result.agents?.explore?.fallback_models).toEqual([
+ {
+ model: "anthropic/claude-haiku-4.5",
+ },
+ ])
})
test("librarian includes fallback_models when opencode-go and Claude are both available", () => {
diff --git a/src/cli/provider-model-id-transform.test.ts b/src/cli/provider-model-id-transform.test.ts
index 17cb9dfb1..ddfdd6e2f 100644
--- a/src/cli/provider-model-id-transform.test.ts
+++ b/src/cli/provider-model-id-transform.test.ts
@@ -163,6 +163,44 @@ describe("transformModelForProvider", () => {
})
})
+ describe("anthropic provider", () => {
+ test("transforms claude-opus-4-6 to claude-opus-4.6", () => {
+ // #given anthropic provider and claude-opus-4-6 model
+ const provider = "anthropic"
+ const model = "claude-opus-4-6"
+
+ // #when transformModelForProvider is called
+ const result = transformModelForProvider(provider, model)
+
+ // #then should transform to claude-opus-4.6
+ expect(result).toBe("claude-opus-4.6")
+ })
+
+ test("transforms claude-sonnet-4-6 to claude-sonnet-4.6", () => {
+ // #given anthropic provider and claude-sonnet-4-6 model
+ const provider = "anthropic"
+ const model = "claude-sonnet-4-6"
+
+ // #when transformModelForProvider is called
+ const result = transformModelForProvider(provider, model)
+
+ // #then should transform to claude-sonnet-4.6
+ expect(result).toBe("claude-sonnet-4.6")
+ })
+
+ test("transforms claude-haiku-4-5 to claude-haiku-4.5", () => {
+ // #given anthropic provider and claude-haiku-4-5 model
+ const provider = "anthropic"
+ const model = "claude-haiku-4-5"
+
+ // #when transformModelForProvider is called
+ const result = transformModelForProvider(provider, model)
+
+ // #then should transform to claude-haiku-4.5
+ expect(result).toBe("claude-haiku-4.5")
+ })
+ })
+
describe("unknown provider", () => {
test("passes model through unchanged for unknown provider", () => {
// #given unknown provider and any model
diff --git a/src/features/background-agent/manager.test.ts b/src/features/background-agent/manager.test.ts
index 86c139132..7ad6fea39 100644
--- a/src/features/background-agent/manager.test.ts
+++ b/src/features/background-agent/manager.test.ts
@@ -855,13 +855,13 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () =>
{
info: {
agent: "sisyphus",
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
},
},
{
info: {
agent: "compaction",
- model: { providerID: "anthropic", modelID: "claude-sonnet-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-sonnet-4.6" },
},
},
],
@@ -890,7 +890,7 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () =>
//#then
expect(capturedBody?.agent).toBe("sisyphus")
- expect(capturedBody?.model).toEqual({ providerID: "anthropic", modelID: "claude-opus-4-6" })
+ expect(capturedBody?.model).toEqual({ providerID: "anthropic", modelID: "claude-opus-4.6" })
manager.shutdown()
})
@@ -913,7 +913,7 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () =>
}
const currentMessage: CurrentMessage = {
agent: "sisyphus",
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
}
// when
@@ -921,7 +921,7 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () =>
// then - uses currentMessage values, not task.parentModel/parentAgent
expect(promptBody.agent).toBe("sisyphus")
- expect(promptBody.model).toEqual({ providerID: "anthropic", modelID: "claude-opus-4-6" })
+ expect(promptBody.model).toEqual({ providerID: "anthropic", modelID: "claude-opus-4.6" })
})
test("should fallback to parentAgent when currentMessage.agent is undefined", async () => {
@@ -1155,7 +1155,7 @@ describe("BackgroundManager.notifyParentSession - notifications toggle", () => {
agent: "explore",
model: {
providerID: "anthropic",
- modelID: "claude-opus-4-6",
+ modelID: "claude-opus-4.6",
variant: "high",
},
},
@@ -1211,7 +1211,7 @@ describe("BackgroundManager.notifyParentSession - variant propagation", () => {
agent: "explore",
model: {
providerID: "anthropic",
- modelID: "claude-opus-4-6",
+ modelID: "claude-opus-4.6",
variant: "max",
},
},
@@ -1231,7 +1231,7 @@ describe("BackgroundManager.notifyParentSession - variant propagation", () => {
status: "completed",
startedAt: new Date(),
completedAt: new Date(),
- model: { providerID: "anthropic", modelID: "claude-opus-4-6", variant: "high" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6", variant: "high" },
}
getPendingByParent(manager).set("session-parent", new Set([task.id]))
@@ -1272,7 +1272,7 @@ describe("BackgroundManager.notifyParentSession - variant propagation", () => {
status: "completed",
startedAt: new Date(),
completedAt: new Date(),
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
}
getPendingByParent(manager).set("session-parent", new Set([task.id]))
@@ -1349,7 +1349,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
test("should release concurrency and clear key on completion", async () => {
// given
- const concurrencyKey = "anthropic/claude-opus-4-6"
+ const concurrencyKey = "anthropic/claude-opus-4.6"
const concurrencyManager = getConcurrencyManager(manager)
await concurrencyManager.acquire(concurrencyKey)
@@ -1378,7 +1378,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
test("should prevent double completion and double release", async () => {
// given
- const concurrencyKey = "anthropic/claude-opus-4-6"
+ const concurrencyKey = "anthropic/claude-opus-4.6"
const concurrencyManager = getConcurrencyManager(manager)
await concurrencyManager.acquire(concurrencyKey)
@@ -1508,7 +1508,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
test("should release task concurrencyKey when startTask throws after assigning it", async () => {
// given
- const concurrencyKey = "anthropic/claude-opus-4-6"
+ const concurrencyKey = "anthropic/claude-opus-4.6"
const concurrencyManager = getConcurrencyManager(manager)
const task = createMockTask({
@@ -1524,7 +1524,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
agent: task.agent,
parentSessionID: task.parentSessionID,
parentMessageID: task.parentMessageID,
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
}
getTaskMap(manager).set(task.id, task)
getQueuesByKey(manager).set(concurrencyKey, [{ task, input }])
@@ -1544,7 +1544,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
test("should mark task as error when startTask throws after session creation", async () => {
//#given - startTask creates session but fails before sending prompt
- const concurrencyKey = "anthropic/claude-opus-4-6"
+ const concurrencyKey = "anthropic/claude-opus-4.6"
const task = createMockTask({
id: "task-zombie-session",
@@ -1561,7 +1561,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
agent: task.agent,
parentSessionID: task.parentSessionID,
parentMessageID: task.parentMessageID,
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
}
getTaskMap(manager).set(task.id, task)
getQueuesByKey(manager).set(concurrencyKey, [{ task, input }])
@@ -1585,7 +1585,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
test("should release queue slot when queued task is already interrupt", async () => {
// given
- const concurrencyKey = "anthropic/claude-opus-4-6"
+ const concurrencyKey = "anthropic/claude-opus-4.6"
const concurrencyManager = getConcurrencyManager(manager)
const task = createMockTask({
@@ -1601,7 +1601,7 @@ describe("BackgroundManager.tryCompleteTask", () => {
agent: task.agent,
parentSessionID: task.parentSessionID,
parentMessageID: task.parentMessageID,
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
}
getTaskMap(manager).set(task.id, task)
getQueuesByKey(manager).set(concurrencyKey, [{ task, input }])
@@ -2104,7 +2104,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => {
agent: "test-agent",
parentSessionID: "parent-session",
parentMessageID: "parent-message",
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
}
const launchInputWithoutModel = {
description: "Test task without model",
@@ -2124,7 +2124,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => {
expect(taskWithModel.status).toBe("pending")
expect(taskWithoutModel.status).toBe("pending")
expect(promptBodies).toHaveLength(2)
- expect(promptBodies[0].model).toEqual({ providerID: "anthropic", modelID: "claude-opus-4-6" })
+ expect(promptBodies[0].model).toEqual({ providerID: "anthropic", modelID: "claude-opus-4.6" })
expect(promptBodies[0].agent).toBe("test-agent")
expect(promptBodies[1].agent).toBe("test-agent")
expect("model" in promptBodies[1]).toBe(false)
@@ -3250,7 +3250,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => {
description: "Task 1",
prompt: "Do something",
agent: "test-agent",
- model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6" },
parentSessionID: "parent-session",
parentMessageID: "parent-message",
}
@@ -4254,7 +4254,7 @@ describe("BackgroundManager.handleEvent - session.error", () => {
agent: "sisyphus",
status: "running",
concurrencyKey: input.concurrencyKey,
- model: { providerID: "anthropic", modelID: "claude-opus-4-6-thinking" },
+ model: { providerID: "anthropic", modelID: "claude-opus-4.6-thinking" },
fallbackChain: input.fallbackChain ?? defaultRetryFallbackChain,
attemptCount: 0,
})
@@ -4399,7 +4399,7 @@ describe("BackgroundManager.handleEvent - session.error", () => {
//#given
const manager = createBackgroundManager()
const concurrencyManager = getConcurrencyManager(manager)
- const concurrencyKey = "anthropic/claude-opus-4-6-thinking"
+ const concurrencyKey = "anthropic/claude-opus-4.6-thinking"
await concurrencyManager.acquire(concurrencyKey)
stubProcessKey(manager)
@@ -4425,7 +4425,7 @@ describe("BackgroundManager.handleEvent - session.error", () => {
name: "UnknownError",
data: {
message:
- "Bad Gateway: {\"error\":{\"message\":\"unknown provider for model claude-opus-4-6-thinking\"}}",
+ "Bad Gateway: {\"error\":{\"message\":\"unknown provider for model claude-opus-4.6-thinking\"}}",
},
},
},
@@ -4436,7 +4436,7 @@ describe("BackgroundManager.handleEvent - session.error", () => {
expect(task.attemptCount).toBe(1)
expect(task.model).toEqual({
providerID: "anthropic",
- modelID: "claude-opus-4-6",
+ modelID: "claude-opus-4.6",
variant: "max",
})
expect(task.concurrencyKey).toBeUndefined()
@@ -4474,7 +4474,7 @@ describe("BackgroundManager.handleEvent - session.error", () => {
expect(task.attemptCount).toBe(1)
expect(task.model).toEqual({
providerID: "anthropic",
- modelID: "claude-opus-4-6",
+ modelID: "claude-opus-4.6",
variant: "max",
})
@@ -4502,7 +4502,7 @@ describe("BackgroundManager.handleEvent - session.error", () => {
name: "UnknownError",
data: {
message:
- "Bad Gateway: {\"error\":{\"message\":\"unknown provider for model claude-opus-4-6-thinking\"}}",
+ "Bad Gateway: {\"error\":{\"message\":\"unknown provider for model claude-opus-4.6-thinking\"}}",
},
},
}
@@ -4519,7 +4519,7 @@ describe("BackgroundManager.handleEvent - session.error", () => {
expect(task.attemptCount).toBe(1)
expect(task.model).toEqual({
providerID: "anthropic",
- modelID: "claude-opus-4-6",
+ modelID: "claude-opus-4.6",
variant: "max",
})
diff --git a/src/shared/provider-model-id-transform.ts b/src/shared/provider-model-id-transform.ts
index 0cf8eb801..38fdf869d 100644
--- a/src/shared/provider-model-id-transform.ts
+++ b/src/shared/provider-model-id-transform.ts
@@ -14,5 +14,11 @@ export function transformModelForProvider(provider: string, model: string): stri
.replace(/gemini-3\.1-pro(?!-)/g, "gemini-3.1-pro-preview")
.replace(/gemini-3-flash(?!-)/g, "gemini-3-flash-preview")
}
+ if (provider === "anthropic") {
+ return model
+ .replace("claude-opus-4-6", "claude-opus-4.6")
+ .replace("claude-sonnet-4-6", "claude-sonnet-4.6")
+ .replace("claude-haiku-4-5", "claude-haiku-4.5")
+ }
return model
}
diff --git a/src/tools/delegate-task/model-selection.test.ts b/src/tools/delegate-task/model-selection.test.ts
index 6350646dc..cd1f8b6e7 100644
--- a/src/tools/delegate-task/model-selection.test.ts
+++ b/src/tools/delegate-task/model-selection.test.ts
@@ -1,5 +1,6 @@
-declare const require: (name: string) => any
-const { afterEach, beforeEach, describe, expect, mock, spyOn, test } = require("bun:test")
+///
+
+import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test"
import { resolveModelForDelegateTask } from "./model-selection"
import * as connectedProvidersCache from "../../shared/connected-providers-cache"
@@ -25,12 +26,12 @@ describe("resolveModelForDelegateTask", () => {
describe("#when availableModels is empty and no user model override", () => {
test("#then returns skipped sentinel to leave model unpinned", () => {
const result = resolveModelForDelegateTask({
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
],
availableModels: new Set(),
- systemDefaultModel: "anthropic/claude-sonnet-4-6",
+ systemDefaultModel: "anthropic/claude-sonnet-4.6",
})
expect(result).toEqual({ skipped: true })
@@ -41,12 +42,12 @@ describe("resolveModelForDelegateTask", () => {
test("#then returns the user model regardless of cache state", () => {
const result = resolveModelForDelegateTask({
userModel: "openai/gpt-5.4",
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
],
availableModels: new Set(),
- systemDefaultModel: "anthropic/claude-sonnet-4-6",
+ systemDefaultModel: "anthropic/claude-sonnet-4.6",
})
expect(result).toEqual({ model: "openai/gpt-5.4" })
@@ -57,7 +58,7 @@ describe("resolveModelForDelegateTask", () => {
test("#then returns skipped sentinel (skip fallback resolution without cache)", () => {
const result = resolveModelForDelegateTask({
userFallbackModels: ["openai/gpt-5.4", "google/gemini-3.1-pro"],
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
],
@@ -80,15 +81,15 @@ describe("resolveModelForDelegateTask", () => {
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["anthropic"])
const result = resolveModelForDelegateTask({
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
],
availableModels: new Set(),
- systemDefaultModel: "anthropic/claude-sonnet-4-6",
+ systemDefaultModel: "anthropic/claude-sonnet-4.6",
})
- expect(result).toEqual({ model: "anthropic/claude-sonnet-4-6" })
+ expect(result).toEqual({ model: "anthropic/claude-sonnet-4.6" })
readConnectedProvidersSpy.mockRestore()
})
@@ -96,12 +97,12 @@ describe("resolveModelForDelegateTask", () => {
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
const result = resolveModelForDelegateTask({
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["openai"], model: "gpt-5.4", variant: "high" },
],
availableModels: new Set(),
- systemDefaultModel: "anthropic/claude-sonnet-4-6",
+ systemDefaultModel: "anthropic/claude-sonnet-4.6",
})
expect(result).toEqual({
@@ -117,7 +118,7 @@ describe("resolveModelForDelegateTask", () => {
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
const result = resolveModelForDelegateTask({
- userFallbackModels: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"],
+ userFallbackModels: ["anthropic/claude-sonnet-4.6", "openai/gpt-5.4"],
availableModels: new Set(),
})
@@ -129,14 +130,14 @@ describe("resolveModelForDelegateTask", () => {
describe("#when availableModels has entries and category default matches", () => {
test("#then resolves via fuzzy match (existing behavior)", () => {
const result = resolveModelForDelegateTask({
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
],
- availableModels: new Set(["anthropic/claude-sonnet-4-6"]),
+ availableModels: new Set(["anthropic/claude-sonnet-4.6"]),
})
- expect(result).toEqual({ model: "anthropic/claude-sonnet-4-6" })
+ expect(result).toEqual({ model: "anthropic/claude-sonnet-4.6" })
})
test("#then trusts user-configured category model without fuzzy validation", () => {
@@ -200,7 +201,7 @@ describe("resolveModelForDelegateTask", () => {
expect(result).toBeDefined()
expect(result).not.toHaveProperty("skipped")
const resolved = result as { model: string; variant?: string }
- expect(resolved.model).toBe("anthropic/claude-haiku-4-5")
+ expect(resolved.model).toBe("anthropic/claude-haiku-4.5")
})
test("#then resolves first provider in entry that is connected", () => {
@@ -229,10 +230,10 @@ describe("resolveModelForDelegateTask", () => {
{ providers: ["opencode-go"], model: "minimax-m2.7" },
],
availableModels: new Set(),
- systemDefaultModel: "anthropic/claude-sonnet-4-6",
+ systemDefaultModel: "anthropic/claude-sonnet-4.6",
})
- expect(result).toEqual({ model: "anthropic/claude-sonnet-4-6" })
+ expect(result).toEqual({ model: "anthropic/claude-sonnet-4.6" })
})
})
@@ -259,7 +260,7 @@ describe("resolveModelForDelegateTask", () => {
test("#then extracts the variant and returns the base model separately", () => {
const result = resolveModelForDelegateTask({
userModel: "openai/gpt-5.4 high",
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["anthropic"], model: "claude-sonnet-4-6" },
],
@@ -274,7 +275,7 @@ describe("resolveModelForDelegateTask", () => {
test("#then extracts the variant and returns the base model separately", () => {
const result = resolveModelForDelegateTask({
userModel: "openai/gpt-5.4(max)",
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
availableModels: new Set(),
})
@@ -359,7 +360,7 @@ describe("resolveModelForDelegateTask", () => {
const readConnectedProvidersSpy = spyOn(connectedProvidersCache, "readConnectedProvidersCache").mockReturnValue(["openai"])
const result = resolveModelForDelegateTask({
- categoryDefaultModel: "anthropic/claude-sonnet-4-6",
+ categoryDefaultModel: "anthropic/claude-sonnet-4.6",
fallbackChain: [
{ providers: ["openai"], model: "gpt-5.4" },
],