diff --git a/src/shared/agent-variant.test.ts b/src/shared/agent-variant.test.ts index 16c46e9134..401f4831b9 100644 --- a/src/shared/agent-variant.test.ts +++ b/src/shared/agent-variant.test.ts @@ -211,4 +211,40 @@ describe("resolveVariantForModel", () => { // then expect(variant).toBe("max") }) + + test("returns thinking variant for github-copilot provider with claude-opus-4-5", () => { + // #given - github-copilot doesn't support "max" variant, only "standard" and "thinking" + const config = {} as OhMyOpenCodeConfig + const model = { providerID: "github-copilot", modelID: "claude-opus-4-5" } + + // #when + const variant = resolveVariantForModel(config, "sisyphus", model) + + // #then - should return "thinking" instead of "max" + expect(variant).toBe("thinking") + }) + + test("returns thinking variant for github-copilot claude in oracle agent", () => { + // #given - oracle agent with github-copilot provider + const config = {} as OhMyOpenCodeConfig + const model = { providerID: "github-copilot", modelID: "claude-opus-4-5" } + + // #when + const variant = resolveVariantForModel(config, "oracle", model) + + // #then - copilot claude gets "thinking" variant + expect(variant).toBe("thinking") + }) + + test("returns high variant for github-copilot gemini-3-pro in oracle agent", () => { + // #given - oracle agent with github-copilot provider and gemini model + const config = {} as OhMyOpenCodeConfig + const model = { providerID: "github-copilot", modelID: "gemini-3-pro" } + + // #when + const variant = resolveVariantForModel(config, "oracle", model) + + // #then - copilot gemini gets "high" variant (not "max") + expect(variant).toBe("high") + }) }) diff --git a/src/shared/model-requirements.test.ts b/src/shared/model-requirements.test.ts index 05d1d5568c..d3d4a21d8e 100644 --- a/src/shared/model-requirements.test.ts +++ b/src/shared/model-requirements.test.ts @@ -28,18 +28,25 @@ describe("AGENT_MODEL_REQUIREMENTS", () => { const sisyphus = AGENT_MODEL_REQUIREMENTS["sisyphus"] // #when - accessing Sisyphus requirement - // #then - fallbackChain exists with claude-opus-4-5 as first entry, glm-4.7-free as last + // #then - fallbackChain exists with claude-opus-4-5 (anthropic) as first entry, glm-4.7-free as last expect(sisyphus).toBeDefined() expect(sisyphus.fallbackChain).toBeArray() - expect(sisyphus.fallbackChain).toHaveLength(5) + expect(sisyphus.fallbackChain).toHaveLength(6) expect(sisyphus.requiresAnyModel).toBe(true) + // First entry: anthropic/opencode gets "max" variant const primary = sisyphus.fallbackChain[0] expect(primary.providers[0]).toBe("anthropic") expect(primary.model).toBe("claude-opus-4-5") expect(primary.variant).toBe("max") - const last = sisyphus.fallbackChain[4] + // Second entry: github-copilot gets "thinking" variant (copilot doesn't support "max") + const copilotEntry = sisyphus.fallbackChain[1] + expect(copilotEntry.providers[0]).toBe("github-copilot") + expect(copilotEntry.model).toBe("claude-opus-4-5") + expect(copilotEntry.variant).toBe("thinking") + + const last = sisyphus.fallbackChain[5] expect(last.providers[0]).toBe("opencode") expect(last.model).toBe("glm-4.7-free") }) diff --git a/src/shared/model-requirements.ts b/src/shared/model-requirements.ts index 8b5eabc116..966200d997 100644 --- a/src/shared/model-requirements.ts +++ b/src/shared/model-requirements.ts @@ -14,7 +14,8 @@ export type ModelRequirement = { export const AGENT_MODEL_REQUIREMENTS: Record = { sisyphus: { fallbackChain: [ - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, { providers: ["kimi-for-coding"], model: "k2p5" }, { providers: ["opencode"], model: "kimi-k2.5-free" }, { providers: ["zai-coding-plan"], model: "glm-4.7" }, @@ -31,8 +32,10 @@ export const AGENT_MODEL_REQUIREMENTS: Record = { oracle: { fallbackChain: [ { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }, - { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }, - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["google", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["github-copilot"], model: "gemini-3-pro", variant: "high" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, ], }, librarian: { @@ -62,7 +65,8 @@ export const AGENT_MODEL_REQUIREMENTS: Record = { }, prometheus: { fallbackChain: [ - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, { providers: ["kimi-for-coding"], model: "k2p5" }, { providers: ["opencode"], model: "kimi-k2.5-free" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }, @@ -71,18 +75,22 @@ export const AGENT_MODEL_REQUIREMENTS: Record = { }, metis: { fallbackChain: [ - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, { providers: ["kimi-for-coding"], model: "k2p5" }, { providers: ["opencode"], model: "kimi-k2.5-free" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }, - { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["google", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["github-copilot"], model: "gemini-3-pro", variant: "high" }, ], }, momus: { fallbackChain: [ { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "medium" }, - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, - { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, + { providers: ["google", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["github-copilot"], model: "gemini-3-pro", variant: "high" }, ], }, atlas: { @@ -100,29 +108,36 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record = { "visual-engineering": { fallbackChain: [ { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }, - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, { providers: ["zai-coding-plan"], model: "glm-4.7" }, ], }, ultrabrain: { fallbackChain: [ { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "xhigh" }, - { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }, - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["google", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["github-copilot"], model: "gemini-3-pro", variant: "high" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, ], }, deep: { fallbackChain: [ { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2-codex", variant: "medium" }, - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, - { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, + { providers: ["google", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["github-copilot"], model: "gemini-3-pro", variant: "high" }, ], requiresModel: "gpt-5.2-codex", }, artistry: { fallbackChain: [ - { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }, - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["google", "opencode"], model: "gemini-3-pro", variant: "max" }, + { providers: ["github-copilot"], model: "gemini-3-pro", variant: "high" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2" }, ], requiresModel: "gemini-3-pro", @@ -143,7 +158,8 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record = { }, "unspecified-high": { fallbackChain: [ - { providers: ["anthropic", "github-copilot", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["anthropic", "opencode"], model: "claude-opus-4-5", variant: "max" }, + { providers: ["github-copilot"], model: "claude-opus-4-5", variant: "thinking" }, { providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.2", variant: "high" }, { providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro" }, ],