fix(agent-variant): resolve variant based on current model, not static config (#1179)

This commit is contained in:
Moha Abdi
2026-01-28 10:26:31 +03:00
committed by GitHub
parent d11c4a1f81
commit 3e32afe646
3 changed files with 165 additions and 4 deletions

View File

@@ -40,7 +40,7 @@ import {
contextCollector,
createContextInjectorMessagesTransformHook,
} from "./features/context-injector";
import { applyAgentVariant, resolveAgentVariant } from "./shared/agent-variant";
import { applyAgentVariant, resolveAgentVariant, resolveVariantForModel } from "./shared/agent-variant";
import { createFirstMessageVariantGate } from "./shared/first-message-variant";
import {
discoverUserClaudeSkills,
@@ -384,14 +384,23 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
const message = (output as { message: { variant?: string } }).message
if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
const variant = resolveAgentVariant(pluginConfig, input.agent)
const variant = input.model && input.agent
? resolveVariantForModel(pluginConfig, input.agent, input.model)
: resolveAgentVariant(pluginConfig, input.agent)
if (variant !== undefined) {
message.variant = variant
}
firstMessageVariantGate.markApplied(input.sessionID)
} else {
if (input.model && input.agent && message.variant === undefined) {
const variant = resolveVariantForModel(pluginConfig, input.agent, input.model)
if (variant !== undefined) {
message.variant = variant
}
} else {
applyAgentVariant(pluginConfig, input.agent, message)
}
}
await keywordDetector?.["chat.message"]?.(input, output);
await claudeCodeHooks["chat.message"]?.(input, output);

View File

@@ -1,6 +1,6 @@
import { describe, expect, test } from "bun:test"
import type { OhMyOpenCodeConfig } from "../config"
import { applyAgentVariant, resolveAgentVariant } from "./agent-variant"
import { applyAgentVariant, resolveAgentVariant, resolveVariantForModel } from "./agent-variant"
describe("resolveAgentVariant", () => {
test("returns undefined when agent name missing", () => {
@@ -81,3 +81,117 @@ describe("applyAgentVariant", () => {
expect(message.variant).toBe("max")
})
})
describe("resolveVariantForModel", () => {
test("returns correct variant for anthropic provider", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "anthropic", modelID: "claude-opus-4-5" }
// #when
const variant = resolveVariantForModel(config, "sisyphus", model)
// #then
expect(variant).toBe("max")
})
test("returns correct variant for openai provider", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "openai", modelID: "gpt-5.2" }
// #when
const variant = resolveVariantForModel(config, "sisyphus", model)
// #then
expect(variant).toBe("medium")
})
test("returns undefined for provider with no variant in chain", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "google", modelID: "gemini-3-pro" }
// #when
const variant = resolveVariantForModel(config, "sisyphus", model)
// #then
expect(variant).toBeUndefined()
})
test("returns undefined for provider not in chain", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "unknown-provider", modelID: "some-model" }
// #when
const variant = resolveVariantForModel(config, "sisyphus", model)
// #then
expect(variant).toBeUndefined()
})
test("returns undefined for unknown agent", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "anthropic", modelID: "claude-opus-4-5" }
// #when
const variant = resolveVariantForModel(config, "nonexistent-agent", model)
// #then
expect(variant).toBeUndefined()
})
test("returns variant for zai-coding-plan provider without variant", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "zai-coding-plan", modelID: "glm-4.7" }
// #when
const variant = resolveVariantForModel(config, "sisyphus", model)
// #then
expect(variant).toBeUndefined()
})
test("falls back to category chain when agent has no requirement", () => {
// #given
const config = {
agents: {
"custom-agent": { category: "ultrabrain" },
},
} as OhMyOpenCodeConfig
const model = { providerID: "openai", modelID: "gpt-5.2-codex" }
// #when
const variant = resolveVariantForModel(config, "custom-agent", model)
// #then
expect(variant).toBe("xhigh")
})
test("returns correct variant for oracle agent with openai", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "openai", modelID: "gpt-5.2" }
// #when
const variant = resolveVariantForModel(config, "oracle", model)
// #then
expect(variant).toBe("high")
})
test("returns correct variant for oracle agent with anthropic", () => {
// #given
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "anthropic", modelID: "claude-opus-4-5" }
// #when
const variant = resolveVariantForModel(config, "oracle", model)
// #then
expect(variant).toBe("max")
})
})

View File

@@ -1,5 +1,6 @@
import type { OhMyOpenCodeConfig } from "../config"
import { findCaseInsensitive } from "./case-insensitive"
import { AGENT_MODEL_REQUIREMENTS, CATEGORY_MODEL_REQUIREMENTS } from "./model-requirements"
export function resolveAgentVariant(
config: OhMyOpenCodeConfig,
@@ -29,6 +30,43 @@ export function resolveAgentVariant(
return config.categories?.[categoryName]?.variant
}
export function resolveVariantForModel(
config: OhMyOpenCodeConfig,
agentName: string,
currentModel: { providerID: string; modelID: string },
): string | undefined {
const agentRequirement = AGENT_MODEL_REQUIREMENTS[agentName]
if (agentRequirement) {
return findVariantInChain(agentRequirement.fallbackChain, currentModel.providerID)
}
const agentOverrides = config.agents as
| Record<string, { category?: string }>
| undefined
const agentOverride = agentOverrides ? findCaseInsensitive(agentOverrides, agentName) : undefined
const categoryName = agentOverride?.category
if (categoryName) {
const categoryRequirement = CATEGORY_MODEL_REQUIREMENTS[categoryName]
if (categoryRequirement) {
return findVariantInChain(categoryRequirement.fallbackChain, currentModel.providerID)
}
}
return undefined
}
function findVariantInChain(
fallbackChain: { providers: string[]; model: string; variant?: string }[],
providerID: string,
): string | undefined {
for (const entry of fallbackChain) {
if (entry.providers.includes(providerID)) {
return entry.variant
}
}
return undefined
}
export function applyAgentVariant(
config: OhMyOpenCodeConfig,
agentName: string | undefined,