test(model-fallback): update snapshots and kimi model expectations for opencode-go integration

This commit is contained in:
YeonGyu-Kim
2026-03-13 10:48:05 +09:00
parent 2c8a8eb4f1
commit 38938508fa
4 changed files with 92 additions and 71 deletions

View File

@@ -31,6 +31,9 @@ exports[`generateModelConfig no providers available returns ULTIMATE_FALLBACK fo
"prometheus": { "prometheus": {
"model": "opencode/glm-4.7-free", "model": "opencode/glm-4.7-free",
}, },
"sisyphus-junior": {
"model": "opencode/glm-4.7-free",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -71,9 +74,6 @@ exports[`generateModelConfig single native provider uses Claude models when only
"explore": { "explore": {
"model": "anthropic/claude-haiku-4-5", "model": "anthropic/claude-haiku-4-5",
}, },
"librarian": {
"model": "anthropic/claude-sonnet-4-5",
},
"metis": { "metis": {
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -97,6 +97,9 @@ exports[`generateModelConfig single native provider uses Claude models when only
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"quick": { "quick": {
@@ -133,9 +136,6 @@ exports[`generateModelConfig single native provider uses Claude models with isMa
"explore": { "explore": {
"model": "anthropic/claude-haiku-4-5", "model": "anthropic/claude-haiku-4-5",
}, },
"librarian": {
"model": "anthropic/claude-sonnet-4-5",
},
"metis": { "metis": {
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -159,6 +159,9 @@ exports[`generateModelConfig single native provider uses Claude models with isMa
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"quick": { "quick": {
@@ -191,8 +194,7 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json", "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": { "agents": {
"atlas": { "atlas": {
"model": "openai/gpt-5.4", "model": "opencode/glm-4.7-free",
"variant": "medium",
}, },
"explore": { "explore": {
"model": "openai/gpt-5.4", "model": "openai/gpt-5.4",
@@ -207,8 +209,7 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
"variant": "medium", "variant": "medium",
}, },
"metis": { "metis": {
"model": "openai/gpt-5.4", "model": "opencode/glm-4.7-free",
"variant": "high",
}, },
"momus": { "momus": {
"model": "openai/gpt-5.4", "model": "openai/gpt-5.4",
@@ -230,6 +231,9 @@ exports[`generateModelConfig single native provider uses OpenAI models when only
"model": "openai/gpt-5.4", "model": "openai/gpt-5.4",
"variant": "medium", "variant": "medium",
}, },
"sisyphus-junior": {
"model": "opencode/glm-4.7-free",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -273,8 +277,7 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json", "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": { "agents": {
"atlas": { "atlas": {
"model": "openai/gpt-5.4", "model": "opencode/glm-4.7-free",
"variant": "medium",
}, },
"explore": { "explore": {
"model": "openai/gpt-5.4", "model": "openai/gpt-5.4",
@@ -289,8 +292,7 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
"variant": "medium", "variant": "medium",
}, },
"metis": { "metis": {
"model": "openai/gpt-5.4", "model": "opencode/glm-4.7-free",
"variant": "high",
}, },
"momus": { "momus": {
"model": "openai/gpt-5.4", "model": "openai/gpt-5.4",
@@ -312,6 +314,9 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa
"model": "openai/gpt-5.4", "model": "openai/gpt-5.4",
"variant": "medium", "variant": "medium",
}, },
"sisyphus-junior": {
"model": "opencode/glm-4.7-free",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -355,24 +360,20 @@ exports[`generateModelConfig single native provider uses Gemini models when only
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json", "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": { "agents": {
"atlas": { "atlas": {
"model": "google/gemini-3.1-pro-preview", "model": "opencode/glm-4.7-free",
}, },
"explore": { "explore": {
"model": "opencode/gpt-5-nano", "model": "opencode/gpt-5-nano",
}, },
"librarian": {
"model": "opencode/glm-4.7-free",
},
"metis": { "metis": {
"model": "google/gemini-3.1-pro-preview", "model": "opencode/glm-4.7-free",
"variant": "high",
}, },
"momus": { "momus": {
"model": "google/gemini-3.1-pro-preview", "model": "google/gemini-3.1-pro-preview",
"variant": "high", "variant": "high",
}, },
"multimodal-looker": { "multimodal-looker": {
"model": "google/gemini-3-flash-preview", "model": "opencode/glm-4.7-free",
}, },
"oracle": { "oracle": {
"model": "google/gemini-3.1-pro-preview", "model": "google/gemini-3.1-pro-preview",
@@ -381,6 +382,9 @@ exports[`generateModelConfig single native provider uses Gemini models when only
"prometheus": { "prometheus": {
"model": "google/gemini-3.1-pro-preview", "model": "google/gemini-3.1-pro-preview",
}, },
"sisyphus-junior": {
"model": "opencode/glm-4.7-free",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -416,24 +420,20 @@ exports[`generateModelConfig single native provider uses Gemini models with isMa
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json", "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-openagent/dev/assets/oh-my-opencode.schema.json",
"agents": { "agents": {
"atlas": { "atlas": {
"model": "google/gemini-3.1-pro-preview", "model": "opencode/glm-4.7-free",
}, },
"explore": { "explore": {
"model": "opencode/gpt-5-nano", "model": "opencode/gpt-5-nano",
}, },
"librarian": {
"model": "opencode/glm-4.7-free",
},
"metis": { "metis": {
"model": "google/gemini-3.1-pro-preview", "model": "opencode/glm-4.7-free",
"variant": "high",
}, },
"momus": { "momus": {
"model": "google/gemini-3.1-pro-preview", "model": "google/gemini-3.1-pro-preview",
"variant": "high", "variant": "high",
}, },
"multimodal-looker": { "multimodal-looker": {
"model": "google/gemini-3-flash-preview", "model": "opencode/glm-4.7-free",
}, },
"oracle": { "oracle": {
"model": "google/gemini-3.1-pro-preview", "model": "google/gemini-3.1-pro-preview",
@@ -442,6 +442,9 @@ exports[`generateModelConfig single native provider uses Gemini models with isMa
"prometheus": { "prometheus": {
"model": "google/gemini-3.1-pro-preview", "model": "google/gemini-3.1-pro-preview",
}, },
"sisyphus-junior": {
"model": "opencode/glm-4.7-free",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -486,9 +489,6 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"model": "openai/gpt-5.3-codex", "model": "openai/gpt-5.3-codex",
"variant": "medium", "variant": "medium",
}, },
"librarian": {
"model": "anthropic/claude-sonnet-4-5",
},
"metis": { "metis": {
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -513,6 +513,9 @@ exports[`generateModelConfig all native providers uses preferred models from fal
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -561,9 +564,6 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"model": "openai/gpt-5.3-codex", "model": "openai/gpt-5.3-codex",
"variant": "medium", "variant": "medium",
}, },
"librarian": {
"model": "anthropic/claude-sonnet-4-5",
},
"metis": { "metis": {
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -588,6 +588,9 @@ exports[`generateModelConfig all native providers uses preferred models with isM
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -637,9 +640,6 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models when on
"model": "opencode/gpt-5.3-codex", "model": "opencode/gpt-5.3-codex",
"variant": "medium", "variant": "medium",
}, },
"librarian": {
"model": "opencode/glm-4.7-free",
},
"metis": { "metis": {
"model": "opencode/claude-opus-4-6", "model": "opencode/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -664,6 +664,9 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models when on
"model": "opencode/claude-opus-4-6", "model": "opencode/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "opencode/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -712,9 +715,6 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models with is
"model": "opencode/gpt-5.3-codex", "model": "opencode/gpt-5.3-codex",
"variant": "medium", "variant": "medium",
}, },
"librarian": {
"model": "opencode/glm-4.7-free",
},
"metis": { "metis": {
"model": "opencode/claude-opus-4-6", "model": "opencode/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -739,6 +739,9 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models with is
"model": "opencode/claude-opus-4-6", "model": "opencode/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "opencode/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -784,9 +787,6 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models when
"explore": { "explore": {
"model": "github-copilot/gpt-5-mini", "model": "github-copilot/gpt-5-mini",
}, },
"librarian": {
"model": "github-copilot/claude-sonnet-4.5",
},
"metis": { "metis": {
"model": "github-copilot/claude-opus-4.6", "model": "github-copilot/claude-opus-4.6",
"variant": "max", "variant": "max",
@@ -796,7 +796,7 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models when
"variant": "xhigh", "variant": "xhigh",
}, },
"multimodal-looker": { "multimodal-looker": {
"model": "github-copilot/gemini-3-flash-preview", "model": "opencode/glm-4.7-free",
}, },
"oracle": { "oracle": {
"model": "github-copilot/gpt-5.4", "model": "github-copilot/gpt-5.4",
@@ -810,6 +810,9 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models when
"model": "github-copilot/claude-opus-4.6", "model": "github-copilot/claude-opus-4.6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "github-copilot/claude-sonnet-4.6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -850,9 +853,6 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models with
"explore": { "explore": {
"model": "github-copilot/gpt-5-mini", "model": "github-copilot/gpt-5-mini",
}, },
"librarian": {
"model": "github-copilot/claude-sonnet-4.5",
},
"metis": { "metis": {
"model": "github-copilot/claude-opus-4.6", "model": "github-copilot/claude-opus-4.6",
"variant": "max", "variant": "max",
@@ -862,7 +862,7 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models with
"variant": "xhigh", "variant": "xhigh",
}, },
"multimodal-looker": { "multimodal-looker": {
"model": "github-copilot/gemini-3-flash-preview", "model": "opencode/glm-4.7-free",
}, },
"oracle": { "oracle": {
"model": "github-copilot/gpt-5.4", "model": "github-copilot/gpt-5.4",
@@ -876,6 +876,9 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models with
"model": "github-copilot/claude-opus-4.6", "model": "github-copilot/claude-opus-4.6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "github-copilot/claude-sonnet-4.6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -938,6 +941,9 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian whe
"sisyphus": { "sisyphus": {
"model": "zai-coding-plan/glm-5", "model": "zai-coding-plan/glm-5",
}, },
"sisyphus-junior": {
"model": "opencode/glm-4.7-free",
},
}, },
"categories": { "categories": {
"quick": { "quick": {
@@ -993,6 +999,9 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian wit
"sisyphus": { "sisyphus": {
"model": "zai-coding-plan/glm-5", "model": "zai-coding-plan/glm-5",
}, },
"sisyphus-junior": {
"model": "opencode/glm-4.7-free",
},
}, },
"categories": { "categories": {
"quick": { "quick": {
@@ -1031,9 +1040,6 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "opencode/gpt-5.3-codex", "model": "opencode/gpt-5.3-codex",
"variant": "medium", "variant": "medium",
}, },
"librarian": {
"model": "opencode/glm-4.7-free",
},
"metis": { "metis": {
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -1058,6 +1064,9 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -1106,9 +1115,6 @@ exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot comb
"model": "openai/gpt-5.3-codex", "model": "openai/gpt-5.3-codex",
"variant": "medium", "variant": "medium",
}, },
"librarian": {
"model": "github-copilot/claude-sonnet-4.5",
},
"metis": { "metis": {
"model": "github-copilot/claude-opus-4.6", "model": "github-copilot/claude-opus-4.6",
"variant": "max", "variant": "max",
@@ -1133,6 +1139,9 @@ exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot comb
"model": "github-copilot/claude-opus-4.6", "model": "github-copilot/claude-opus-4.6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "github-copilot/claude-sonnet-4.6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -1203,6 +1212,9 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + ZAI combinat
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"quick": { "quick": {
@@ -1238,9 +1250,6 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"explore": { "explore": {
"model": "anthropic/claude-haiku-4-5", "model": "anthropic/claude-haiku-4-5",
}, },
"librarian": {
"model": "anthropic/claude-sonnet-4-5",
},
"metis": { "metis": {
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
@@ -1250,7 +1259,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"variant": "max", "variant": "max",
}, },
"multimodal-looker": { "multimodal-looker": {
"model": "google/gemini-3-flash-preview", "model": "opencode/glm-4.7-free",
}, },
"oracle": { "oracle": {
"model": "google/gemini-3.1-pro-preview", "model": "google/gemini-3.1-pro-preview",
@@ -1264,6 +1273,9 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -1335,6 +1347,9 @@ exports[`generateModelConfig mixed provider scenarios uses all fallback provider
"model": "github-copilot/claude-opus-4.6", "model": "github-copilot/claude-opus-4.6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "github-copilot/claude-sonnet-4.6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -1410,6 +1425,9 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {
@@ -1485,6 +1503,9 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is
"model": "anthropic/claude-opus-4-6", "model": "anthropic/claude-opus-4-6",
"variant": "max", "variant": "max",
}, },
"sisyphus-junior": {
"model": "anthropic/claude-sonnet-4-6",
},
}, },
"categories": { "categories": {
"artistry": { "artistry": {

View File

@@ -495,15 +495,15 @@ describe("generateModelConfig", () => {
expect(result.agents?.librarian?.model).toBe("zai-coding-plan/glm-4.7") expect(result.agents?.librarian?.model).toBe("zai-coding-plan/glm-4.7")
}) })
test("librarian falls back to generic chain result when no librarian provider matches", () => { test("librarian is omitted when no librarian provider matches", () => {
// #given only Claude is available (no ZAI) // #given only Claude is available (no opencode-go or ZAI)
const config = createConfig({ hasClaude: true }) const config = createConfig({ hasClaude: true })
// #when generateModelConfig is called // #when generateModelConfig is called
const result = generateModelConfig(config) const result = generateModelConfig(config)
// #then librarian should use generic chain result when chain providers are unavailable // #then librarian should be omitted when its dedicated providers are unavailable
expect(result.agents?.librarian?.model).toBe("anthropic/claude-sonnet-4-5") expect(result.agents?.librarian).toBeUndefined()
}) })
}) })

View File

@@ -134,8 +134,8 @@ describe("model fallback hook", () => {
//#then - chain should progress to entry[1], not repeat entry[0] //#then - chain should progress to entry[1], not repeat entry[0]
expect(secondOutput.message["model"]).toEqual({ expect(secondOutput.message["model"]).toEqual({
providerID: "kimi-for-coding", providerID: "opencode-go",
modelID: "k2p5", modelID: "kimi-k2.5",
}) })
expect(secondOutput.message["variant"]).toBeUndefined() expect(secondOutput.message["variant"]).toBeUndefined()
}) })

View File

@@ -212,8 +212,8 @@ describe("createEventHandler - model fallback", () => {
expect(abortCalls).toEqual([sessionID]) expect(abortCalls).toEqual([sessionID])
expect(promptCalls).toEqual([sessionID]) expect(promptCalls).toEqual([sessionID])
expect(output.message["model"]).toMatchObject({ expect(output.message["model"]).toMatchObject({
providerID: "kimi-for-coding", providerID: "opencode-go",
modelID: "k2p5", modelID: "kimi-k2.5",
}) })
expect(output.message["variant"]).toBeUndefined() expect(output.message["variant"]).toBeUndefined()
}) })
@@ -540,19 +540,19 @@ describe("createEventHandler - model fallback", () => {
//#then - first fallback entry applied (no-op skip: claude-opus-4-6 matches current model after normalization) //#then - first fallback entry applied (no-op skip: claude-opus-4-6 matches current model after normalization)
expect(first.message["model"]).toMatchObject({ expect(first.message["model"]).toMatchObject({
providerID: "kimi-for-coding", providerID: "opencode-go",
modelID: "k2p5", modelID: "kimi-k2.5",
}) })
expect(first.message["variant"]).toBeUndefined() expect(first.message["variant"]).toBeUndefined()
//#when - second retry cycle //#when - second retry cycle
const second = await triggerRetryCycle() const second = await triggerRetryCycle()
//#then - second fallback entry applied (chain advanced past k2p5) //#then - second fallback entry applied (chain advanced past opencode-go/kimi-k2.5)
expect(second.message["model"]).toMatchObject({ expect(second.message["model"]).toMatchObject({
modelID: "kimi-k2.5", providerID: "kimi-for-coding",
modelID: "k2p5",
}) })
expect((second.message["model"] as { providerID?: string })?.providerID).toBeTruthy()
expect(second.message["variant"]).toBeUndefined() expect(second.message["variant"]).toBeUndefined()
expect(abortCalls).toEqual([sessionID, sessionID]) expect(abortCalls).toEqual([sessionID, sessionID])
expect(promptCalls).toEqual([sessionID, sessionID]) expect(promptCalls).toEqual([sessionID, sessionID])