From 38938508fa97183d56154d43e68069eb2954ba75 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 13 Mar 2026 10:48:05 +0900 Subject: [PATCH] test(model-fallback): update snapshots and kimi model expectations for opencode-go integration --- .../__snapshots__/model-fallback.test.ts.snap | 137 ++++++++++-------- src/cli/model-fallback.test.ts | 8 +- src/hooks/model-fallback/hook.test.ts | 4 +- src/plugin/event.model-fallback.test.ts | 14 +- 4 files changed, 92 insertions(+), 71 deletions(-) diff --git a/src/cli/__snapshots__/model-fallback.test.ts.snap b/src/cli/__snapshots__/model-fallback.test.ts.snap index 255c39bb5..8602b7377 100644 --- a/src/cli/__snapshots__/model-fallback.test.ts.snap +++ b/src/cli/__snapshots__/model-fallback.test.ts.snap @@ -31,6 +31,9 @@ exports[`generateModelConfig no providers available returns ULTIMATE_FALLBACK fo "prometheus": { "model": "opencode/glm-4.7-free", }, + "sisyphus-junior": { + "model": "opencode/glm-4.7-free", + }, }, "categories": { "artistry": { @@ -71,9 +74,6 @@ exports[`generateModelConfig single native provider uses Claude models when only "explore": { "model": "anthropic/claude-haiku-4-5", }, - "librarian": { - "model": "anthropic/claude-sonnet-4-5", - }, "metis": { "model": "anthropic/claude-opus-4-6", "variant": "max", @@ -97,6 +97,9 @@ exports[`generateModelConfig single native provider uses Claude models when only "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "quick": { @@ -133,9 +136,6 @@ exports[`generateModelConfig single native provider uses Claude models with isMa "explore": { "model": "anthropic/claude-haiku-4-5", }, - "librarian": { - "model": "anthropic/claude-sonnet-4-5", - }, "metis": { "model": "anthropic/claude-opus-4-6", "variant": "max", @@ -159,6 +159,9 @@ exports[`generateModelConfig single native provider uses Claude models with isMa "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "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", "agents": { "atlas": { - "model": "openai/gpt-5.4", - "variant": "medium", + "model": "opencode/glm-4.7-free", }, "explore": { "model": "openai/gpt-5.4", @@ -207,8 +209,7 @@ exports[`generateModelConfig single native provider uses OpenAI models when only "variant": "medium", }, "metis": { - "model": "openai/gpt-5.4", - "variant": "high", + "model": "opencode/glm-4.7-free", }, "momus": { "model": "openai/gpt-5.4", @@ -230,6 +231,9 @@ exports[`generateModelConfig single native provider uses OpenAI models when only "model": "openai/gpt-5.4", "variant": "medium", }, + "sisyphus-junior": { + "model": "opencode/glm-4.7-free", + }, }, "categories": { "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", "agents": { "atlas": { - "model": "openai/gpt-5.4", - "variant": "medium", + "model": "opencode/glm-4.7-free", }, "explore": { "model": "openai/gpt-5.4", @@ -289,8 +292,7 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa "variant": "medium", }, "metis": { - "model": "openai/gpt-5.4", - "variant": "high", + "model": "opencode/glm-4.7-free", }, "momus": { "model": "openai/gpt-5.4", @@ -312,6 +314,9 @@ exports[`generateModelConfig single native provider uses OpenAI models with isMa "model": "openai/gpt-5.4", "variant": "medium", }, + "sisyphus-junior": { + "model": "opencode/glm-4.7-free", + }, }, "categories": { "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", "agents": { "atlas": { - "model": "google/gemini-3.1-pro-preview", + "model": "opencode/glm-4.7-free", }, "explore": { "model": "opencode/gpt-5-nano", }, - "librarian": { - "model": "opencode/glm-4.7-free", - }, "metis": { - "model": "google/gemini-3.1-pro-preview", - "variant": "high", + "model": "opencode/glm-4.7-free", }, "momus": { "model": "google/gemini-3.1-pro-preview", "variant": "high", }, "multimodal-looker": { - "model": "google/gemini-3-flash-preview", + "model": "opencode/glm-4.7-free", }, "oracle": { "model": "google/gemini-3.1-pro-preview", @@ -381,6 +382,9 @@ exports[`generateModelConfig single native provider uses Gemini models when only "prometheus": { "model": "google/gemini-3.1-pro-preview", }, + "sisyphus-junior": { + "model": "opencode/glm-4.7-free", + }, }, "categories": { "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", "agents": { "atlas": { - "model": "google/gemini-3.1-pro-preview", + "model": "opencode/glm-4.7-free", }, "explore": { "model": "opencode/gpt-5-nano", }, - "librarian": { - "model": "opencode/glm-4.7-free", - }, "metis": { - "model": "google/gemini-3.1-pro-preview", - "variant": "high", + "model": "opencode/glm-4.7-free", }, "momus": { "model": "google/gemini-3.1-pro-preview", "variant": "high", }, "multimodal-looker": { - "model": "google/gemini-3-flash-preview", + "model": "opencode/glm-4.7-free", }, "oracle": { "model": "google/gemini-3.1-pro-preview", @@ -442,6 +442,9 @@ exports[`generateModelConfig single native provider uses Gemini models with isMa "prometheus": { "model": "google/gemini-3.1-pro-preview", }, + "sisyphus-junior": { + "model": "opencode/glm-4.7-free", + }, }, "categories": { "artistry": { @@ -486,9 +489,6 @@ exports[`generateModelConfig all native providers uses preferred models from fal "model": "openai/gpt-5.3-codex", "variant": "medium", }, - "librarian": { - "model": "anthropic/claude-sonnet-4-5", - }, "metis": { "model": "anthropic/claude-opus-4-6", "variant": "max", @@ -513,6 +513,9 @@ exports[`generateModelConfig all native providers uses preferred models from fal "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "artistry": { @@ -561,9 +564,6 @@ exports[`generateModelConfig all native providers uses preferred models with isM "model": "openai/gpt-5.3-codex", "variant": "medium", }, - "librarian": { - "model": "anthropic/claude-sonnet-4-5", - }, "metis": { "model": "anthropic/claude-opus-4-6", "variant": "max", @@ -588,6 +588,9 @@ exports[`generateModelConfig all native providers uses preferred models with isM "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "artistry": { @@ -637,9 +640,6 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models when on "model": "opencode/gpt-5.3-codex", "variant": "medium", }, - "librarian": { - "model": "opencode/glm-4.7-free", - }, "metis": { "model": "opencode/claude-opus-4-6", "variant": "max", @@ -664,6 +664,9 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models when on "model": "opencode/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "opencode/claude-sonnet-4-6", + }, }, "categories": { "artistry": { @@ -712,9 +715,6 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models with is "model": "opencode/gpt-5.3-codex", "variant": "medium", }, - "librarian": { - "model": "opencode/glm-4.7-free", - }, "metis": { "model": "opencode/claude-opus-4-6", "variant": "max", @@ -739,6 +739,9 @@ exports[`generateModelConfig fallback providers uses OpenCode Zen models with is "model": "opencode/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "opencode/claude-sonnet-4-6", + }, }, "categories": { "artistry": { @@ -784,9 +787,6 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models when "explore": { "model": "github-copilot/gpt-5-mini", }, - "librarian": { - "model": "github-copilot/claude-sonnet-4.5", - }, "metis": { "model": "github-copilot/claude-opus-4.6", "variant": "max", @@ -796,7 +796,7 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models when "variant": "xhigh", }, "multimodal-looker": { - "model": "github-copilot/gemini-3-flash-preview", + "model": "opencode/glm-4.7-free", }, "oracle": { "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", "variant": "max", }, + "sisyphus-junior": { + "model": "github-copilot/claude-sonnet-4.6", + }, }, "categories": { "artistry": { @@ -850,9 +853,6 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models with "explore": { "model": "github-copilot/gpt-5-mini", }, - "librarian": { - "model": "github-copilot/claude-sonnet-4.5", - }, "metis": { "model": "github-copilot/claude-opus-4.6", "variant": "max", @@ -862,7 +862,7 @@ exports[`generateModelConfig fallback providers uses GitHub Copilot models with "variant": "xhigh", }, "multimodal-looker": { - "model": "github-copilot/gemini-3-flash-preview", + "model": "opencode/glm-4.7-free", }, "oracle": { "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", "variant": "max", }, + "sisyphus-junior": { + "model": "github-copilot/claude-sonnet-4.6", + }, }, "categories": { "artistry": { @@ -938,6 +941,9 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian whe "sisyphus": { "model": "zai-coding-plan/glm-5", }, + "sisyphus-junior": { + "model": "opencode/glm-4.7-free", + }, }, "categories": { "quick": { @@ -993,6 +999,9 @@ exports[`generateModelConfig fallback providers uses ZAI model for librarian wit "sisyphus": { "model": "zai-coding-plan/glm-5", }, + "sisyphus-junior": { + "model": "opencode/glm-4.7-free", + }, }, "categories": { "quick": { @@ -1031,9 +1040,6 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen "model": "opencode/gpt-5.3-codex", "variant": "medium", }, - "librarian": { - "model": "opencode/glm-4.7-free", - }, "metis": { "model": "anthropic/claude-opus-4-6", "variant": "max", @@ -1058,6 +1064,9 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + OpenCode Zen "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "artistry": { @@ -1106,9 +1115,6 @@ exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot comb "model": "openai/gpt-5.3-codex", "variant": "medium", }, - "librarian": { - "model": "github-copilot/claude-sonnet-4.5", - }, "metis": { "model": "github-copilot/claude-opus-4.6", "variant": "max", @@ -1133,6 +1139,9 @@ exports[`generateModelConfig mixed provider scenarios uses OpenAI + Copilot comb "model": "github-copilot/claude-opus-4.6", "variant": "max", }, + "sisyphus-junior": { + "model": "github-copilot/claude-sonnet-4.6", + }, }, "categories": { "artistry": { @@ -1203,6 +1212,9 @@ exports[`generateModelConfig mixed provider scenarios uses Claude + ZAI combinat "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "quick": { @@ -1238,9 +1250,6 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi "explore": { "model": "anthropic/claude-haiku-4-5", }, - "librarian": { - "model": "anthropic/claude-sonnet-4-5", - }, "metis": { "model": "anthropic/claude-opus-4-6", "variant": "max", @@ -1250,7 +1259,7 @@ exports[`generateModelConfig mixed provider scenarios uses Gemini + Claude combi "variant": "max", }, "multimodal-looker": { - "model": "google/gemini-3-flash-preview", + "model": "opencode/glm-4.7-free", }, "oracle": { "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", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "artistry": { @@ -1335,6 +1347,9 @@ exports[`generateModelConfig mixed provider scenarios uses all fallback provider "model": "github-copilot/claude-opus-4.6", "variant": "max", }, + "sisyphus-junior": { + "model": "github-copilot/claude-sonnet-4.6", + }, }, "categories": { "artistry": { @@ -1410,6 +1425,9 @@ exports[`generateModelConfig mixed provider scenarios uses all providers togethe "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "artistry": { @@ -1485,6 +1503,9 @@ exports[`generateModelConfig mixed provider scenarios uses all providers with is "model": "anthropic/claude-opus-4-6", "variant": "max", }, + "sisyphus-junior": { + "model": "anthropic/claude-sonnet-4-6", + }, }, "categories": { "artistry": { diff --git a/src/cli/model-fallback.test.ts b/src/cli/model-fallback.test.ts index 5abf4b4c0..bd3e38447 100644 --- a/src/cli/model-fallback.test.ts +++ b/src/cli/model-fallback.test.ts @@ -495,15 +495,15 @@ describe("generateModelConfig", () => { 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", () => { - // #given only Claude is available (no ZAI) + test("librarian is omitted when no librarian provider matches", () => { + // #given only Claude is available (no opencode-go or ZAI) const config = createConfig({ hasClaude: true }) // #when generateModelConfig is called const result = generateModelConfig(config) - // #then librarian should use generic chain result when chain providers are unavailable - expect(result.agents?.librarian?.model).toBe("anthropic/claude-sonnet-4-5") + // #then librarian should be omitted when its dedicated providers are unavailable + expect(result.agents?.librarian).toBeUndefined() }) }) diff --git a/src/hooks/model-fallback/hook.test.ts b/src/hooks/model-fallback/hook.test.ts index bcd720c56..04cfcf659 100644 --- a/src/hooks/model-fallback/hook.test.ts +++ b/src/hooks/model-fallback/hook.test.ts @@ -134,8 +134,8 @@ describe("model fallback hook", () => { //#then - chain should progress to entry[1], not repeat entry[0] expect(secondOutput.message["model"]).toEqual({ - providerID: "kimi-for-coding", - modelID: "k2p5", + providerID: "opencode-go", + modelID: "kimi-k2.5", }) expect(secondOutput.message["variant"]).toBeUndefined() }) diff --git a/src/plugin/event.model-fallback.test.ts b/src/plugin/event.model-fallback.test.ts index f8a92b6f1..b6a1f6966 100644 --- a/src/plugin/event.model-fallback.test.ts +++ b/src/plugin/event.model-fallback.test.ts @@ -212,8 +212,8 @@ describe("createEventHandler - model fallback", () => { expect(abortCalls).toEqual([sessionID]) expect(promptCalls).toEqual([sessionID]) expect(output.message["model"]).toMatchObject({ - providerID: "kimi-for-coding", - modelID: "k2p5", + providerID: "opencode-go", + modelID: "kimi-k2.5", }) 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) expect(first.message["model"]).toMatchObject({ - providerID: "kimi-for-coding", - modelID: "k2p5", + providerID: "opencode-go", + modelID: "kimi-k2.5", }) expect(first.message["variant"]).toBeUndefined() //#when - second retry cycle 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({ - 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(abortCalls).toEqual([sessionID, sessionID]) expect(promptCalls).toEqual([sessionID, sessionID])