oh-my-opencode/src/shared/agent-variant.test.ts
YeonGyu-Kim 64825158a7
feat(agents): add Hephaestus - autonomous deep worker agent (#1287)
* refactor(keyword-detector): split constants into domain-specific modules

* feat(shared): add requiresAnyModel and isAnyFallbackModelAvailable

* feat(config): add hephaestus to agent schemas

* feat(agents): add Hephaestus autonomous deep worker

* feat(cli): update model-fallback for hephaestus support

* feat(plugin): add hephaestus to config handler with ordering

* test(delegate-task): update tests for hephaestus agent

* docs: update AGENTS.md files for hephaestus

* docs: add hephaestus to READMEs

* chore: regenerate config schema

* fix(delegate-task): bypass requiresModel check when user provides explicit config

* docs(hephaestus): add 4-part context structure for explore/librarian prompts

* docs: fix review comments from cubic (non-breaking changes)

- Move Hephaestus from Primary Agents to Subagents (uses own fallback chain)
- Fix Hephaestus fallback chain documentation (claude-opus-4-5 → gemini-3-pro)
- Add settings.local.json to claude-code-hooks config sources
- Fix delegate_task parameters in ultrawork prompt (agent→subagent_type, background→run_in_background, add load_skills)
- Update line counts in AGENTS.md (index.ts: 788, manager.ts: 1440)

* docs: fix additional documentation inconsistencies from oracle review

- Fix delegate_task parameters in Background Agents example (docs/features.md)
- Fix Hephaestus fallback chain in root AGENTS.md to match model-requirements.ts

* docs: clarify Hephaestus has no fallback (requires gpt-5.2-codex only)

Hephaestus uses requiresModel constraint - it only activates when gpt-5.2-codex
is available. The fallback chain in code is unreachable, so documentation
should not mention fallbacks.

* fix(hephaestus): remove unreachable fallback chain entries

Hephaestus has requiresModel: gpt-5.2-codex which means the agent only
activates when that specific model is available. The fallback entries
(claude-opus-4-5, gemini-3-pro) were unreachable and misleading.

---------

Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com>
2026-02-01 19:26:57 +09:00

198 lines
5.1 KiB
TypeScript

import { describe, expect, test } from "bun:test"
import type { OhMyOpenCodeConfig } from "../config"
import { applyAgentVariant, resolveAgentVariant, resolveVariantForModel } from "./agent-variant"
describe("resolveAgentVariant", () => {
test("returns undefined when agent name missing", () => {
// given
const config = {} as OhMyOpenCodeConfig
// when
const variant = resolveAgentVariant(config)
// then
expect(variant).toBeUndefined()
})
test("returns agent override variant", () => {
// given
const config = {
agents: {
sisyphus: { variant: "low" },
},
} as OhMyOpenCodeConfig
// when
const variant = resolveAgentVariant(config, "sisyphus")
// then
expect(variant).toBe("low")
})
test("returns category variant when agent uses category", () => {
// given
const config = {
agents: {
sisyphus: { category: "ultrabrain" },
},
categories: {
ultrabrain: { model: "openai/gpt-5.2", variant: "xhigh" },
},
} as OhMyOpenCodeConfig
// when
const variant = resolveAgentVariant(config, "sisyphus")
// then
expect(variant).toBe("xhigh")
})
})
describe("applyAgentVariant", () => {
test("sets variant when message is undefined", () => {
// given
const config = {
agents: {
sisyphus: { variant: "low" },
},
} as OhMyOpenCodeConfig
const message: { variant?: string } = {}
// when
applyAgentVariant(config, "sisyphus", message)
// then
expect(message.variant).toBe("low")
})
test("does not override existing variant", () => {
// given
const config = {
agents: {
sisyphus: { variant: "low" },
},
} as OhMyOpenCodeConfig
const message = { variant: "max" }
// when
applyAgentVariant(config, "sisyphus", message)
// then
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 (hephaestus agent)", () => {
// #given hephaestus has openai/gpt-5.2-codex with variant "medium" in its chain
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "openai", modelID: "gpt-5.2-codex" }
// #when
const variant = resolveVariantForModel(config, "hephaestus", model)
// then
expect(variant).toBe("medium")
})
test("returns undefined for provider not in sisyphus chain", () => {
// #given openai is not in sisyphus fallback chain anymore
const config = {} as OhMyOpenCodeConfig
const model = { providerID: "openai", modelID: "gpt-5.2" }
// 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")
})
})