bc0da0fad3
- prometheus-prompt.test.ts: close missing }) on the OpenSpec expanded commands describe block (introduced byd66b6bcbf, parse error). - agent-sort-shim/agent-config-integration/continuation-injection/ unstable-agent-babysitter/subagent-resolver/sync-executor/ resolve-caller-team-lead tests: expect 'Sisyphus - ultraworker' (lowercase) to match production aftercd39f8858, which lowercased the display name to dodge a TUI ZWSP rendering glitch. Legacy uppercase inputs that exercise the normalization path are preserved. - sync-executor.ts + resolve-caller-team-lead.ts: route legacy display name inputs through normalizeAgentForPrompt so prompt agent names and caller team lead lookups produce the canonical lowercase form.
226 lines
8.8 KiB
TypeScript
226 lines
8.8 KiB
TypeScript
import { describe, test, expect } from "bun:test"
|
|
import { migrateAgentNames } from "./migration"
|
|
import { getAgentDisplayName } from "./agent-display-names"
|
|
import { AGENT_MODEL_REQUIREMENTS } from "./model-requirements"
|
|
|
|
describe("Agent Config Integration", () => {
|
|
describe("Old format config migration", () => {
|
|
test("migrates old format agent keys to lowercase", () => {
|
|
// given - config with old format keys
|
|
const oldConfig = {
|
|
Sisyphus: { model: "anthropic/claude-opus-4-7" },
|
|
Atlas: { model: "anthropic/claude-opus-4-7" },
|
|
"Prometheus - Plan Builder": { model: "anthropic/claude-opus-4-7" },
|
|
"Metis - Plan Consultant": { model: "anthropic/claude-sonnet-4-6" },
|
|
"Momus - Plan Critic": { model: "anthropic/claude-sonnet-4-6" },
|
|
}
|
|
|
|
// when - migration is applied
|
|
const result = migrateAgentNames(oldConfig)
|
|
|
|
// then - keys are lowercase
|
|
expect(result.migrated).toHaveProperty("sisyphus")
|
|
expect(result.migrated).toHaveProperty("atlas")
|
|
expect(result.migrated).toHaveProperty("prometheus")
|
|
expect(result.migrated).toHaveProperty("metis")
|
|
expect(result.migrated).toHaveProperty("momus")
|
|
|
|
// then - old keys are removed
|
|
expect(result.migrated).not.toHaveProperty("Sisyphus")
|
|
expect(result.migrated).not.toHaveProperty("Atlas")
|
|
expect(result.migrated).not.toHaveProperty("Prometheus - Plan Builder")
|
|
expect(result.migrated).not.toHaveProperty("Metis - Plan Consultant")
|
|
expect(result.migrated).not.toHaveProperty("Momus - Plan Critic")
|
|
|
|
// then - values are preserved
|
|
expect(result.migrated.sisyphus).toEqual({ model: "anthropic/claude-opus-4-7" })
|
|
expect(result.migrated.atlas).toEqual({ model: "anthropic/claude-opus-4-7" })
|
|
expect(result.migrated.prometheus).toEqual({ model: "anthropic/claude-opus-4-7" })
|
|
|
|
// then - changed flag is true
|
|
expect(result.changed).toBe(true)
|
|
})
|
|
|
|
test("preserves already lowercase keys", () => {
|
|
// given - config with lowercase keys
|
|
const config = {
|
|
sisyphus: { model: "anthropic/claude-opus-4-7" },
|
|
oracle: { model: "openai/gpt-5.4" },
|
|
librarian: { model: "opencode/big-pickle" },
|
|
}
|
|
|
|
// when - migration is applied
|
|
const result = migrateAgentNames(config)
|
|
|
|
// then - keys remain unchanged
|
|
expect(result.migrated).toEqual(config)
|
|
|
|
// then - changed flag is false
|
|
expect(result.changed).toBe(false)
|
|
})
|
|
|
|
test("handles mixed case config", () => {
|
|
// given - config with mixed old and new format
|
|
const mixedConfig = {
|
|
Sisyphus: { model: "anthropic/claude-opus-4-7" },
|
|
oracle: { model: "openai/gpt-5.4" },
|
|
"Prometheus - Plan Builder": { model: "anthropic/claude-opus-4-7" },
|
|
librarian: { model: "opencode/big-pickle" },
|
|
}
|
|
|
|
// when - migration is applied
|
|
const result = migrateAgentNames(mixedConfig)
|
|
|
|
// then - all keys are lowercase
|
|
expect(result.migrated).toHaveProperty("sisyphus")
|
|
expect(result.migrated).toHaveProperty("oracle")
|
|
expect(result.migrated).toHaveProperty("prometheus")
|
|
expect(result.migrated).toHaveProperty("librarian")
|
|
expect(Object.keys(result.migrated).every((key) => key === key.toLowerCase())).toBe(true)
|
|
|
|
// then - changed flag is true
|
|
expect(result.changed).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe("Display name resolution", () => {
|
|
test("returns correct display names for all builtin agents", () => {
|
|
// given - lowercase config keys
|
|
const agents = ["sisyphus", "hephaestus", "prometheus", "atlas", "metis", "momus", "oracle", "librarian", "explore", "multimodal-looker"]
|
|
|
|
// when - display names are requested
|
|
const displayNames = agents.map((agent) => getAgentDisplayName(agent))
|
|
|
|
// then - display names are correct
|
|
expect(displayNames).toContain("Sisyphus - ultraworker")
|
|
expect(displayNames).toContain("Hephaestus - Deep Agent")
|
|
expect(displayNames).toContain("Prometheus - Plan Builder")
|
|
expect(displayNames).toContain("Atlas - Plan Executor")
|
|
expect(displayNames).toContain("Metis - Plan Consultant")
|
|
expect(displayNames).toContain("Momus - Plan Critic")
|
|
expect(displayNames).toContain("oracle")
|
|
expect(displayNames).toContain("librarian")
|
|
expect(displayNames).toContain("explore")
|
|
expect(displayNames).toContain("multimodal-looker")
|
|
})
|
|
|
|
test("handles lowercase keys case-insensitively", () => {
|
|
// given - various case formats of lowercase keys
|
|
const keys = ["Sisyphus", "Atlas", "SISYPHUS", "atlas", "prometheus", "PROMETHEUS"]
|
|
|
|
// when - display names are requested
|
|
const displayNames = keys.map((key) => getAgentDisplayName(key))
|
|
|
|
// then - correct display names are returned
|
|
expect(displayNames[0]).toBe("Sisyphus - ultraworker")
|
|
expect(displayNames[1]).toBe("Atlas - Plan Executor")
|
|
expect(displayNames[2]).toBe("Sisyphus - ultraworker")
|
|
expect(displayNames[3]).toBe("Atlas - Plan Executor")
|
|
expect(displayNames[4]).toBe("Prometheus - Plan Builder")
|
|
expect(displayNames[5]).toBe("Prometheus - Plan Builder")
|
|
})
|
|
|
|
test("returns original key for unknown agents", () => {
|
|
// given - unknown agent key
|
|
const unknownKey = "custom-agent"
|
|
|
|
// when - display name is requested
|
|
const displayName = getAgentDisplayName(unknownKey)
|
|
|
|
// then - original key is returned
|
|
expect(displayName).toBe(unknownKey)
|
|
})
|
|
})
|
|
|
|
describe("Model requirements integration", () => {
|
|
test("all model requirements use lowercase keys", () => {
|
|
// given - AGENT_MODEL_REQUIREMENTS object
|
|
const agentKeys = Object.keys(AGENT_MODEL_REQUIREMENTS)
|
|
|
|
// when - checking key format
|
|
const allLowercase = agentKeys.every((key) => key === key.toLowerCase())
|
|
|
|
// then - all keys are lowercase
|
|
expect(allLowercase).toBe(true)
|
|
})
|
|
|
|
test("model requirements include all builtin agents", () => {
|
|
// given - expected builtin agents
|
|
const expectedAgents = ["sisyphus", "hephaestus", "prometheus", "atlas", "metis", "momus", "oracle", "librarian", "explore", "multimodal-looker"]
|
|
|
|
// when - checking AGENT_MODEL_REQUIREMENTS
|
|
const agentKeys = Object.keys(AGENT_MODEL_REQUIREMENTS)
|
|
|
|
// then - all expected agents are present
|
|
for (const agent of expectedAgents) {
|
|
expect(agentKeys).toContain(agent)
|
|
}
|
|
})
|
|
|
|
test("no uppercase keys in model requirements", () => {
|
|
// given - AGENT_MODEL_REQUIREMENTS object
|
|
const agentKeys = Object.keys(AGENT_MODEL_REQUIREMENTS)
|
|
|
|
// when - checking for uppercase keys
|
|
const uppercaseKeys = agentKeys.filter((key) => key !== key.toLowerCase())
|
|
|
|
// then - no uppercase keys exist
|
|
expect(uppercaseKeys).toEqual([])
|
|
})
|
|
})
|
|
|
|
describe("End-to-end config flow", () => {
|
|
test("old config migrates and displays correctly", () => {
|
|
// given - old format config
|
|
const oldConfig = {
|
|
Sisyphus: { model: "anthropic/claude-opus-4-7", temperature: 0.1 },
|
|
"Prometheus - Plan Builder": { model: "anthropic/claude-opus-4-7" },
|
|
}
|
|
|
|
// when - config is migrated
|
|
const result = migrateAgentNames(oldConfig)
|
|
|
|
// then - keys are lowercase
|
|
expect(result.migrated).toHaveProperty("sisyphus")
|
|
expect(result.migrated).toHaveProperty("prometheus")
|
|
|
|
// when - display names are retrieved
|
|
const sisyphusDisplay = getAgentDisplayName("sisyphus")
|
|
const prometheusDisplay = getAgentDisplayName("prometheus")
|
|
|
|
// then - display names are correct
|
|
expect(sisyphusDisplay).toBe("Sisyphus - ultraworker")
|
|
expect(prometheusDisplay).toBe("Prometheus - Plan Builder")
|
|
|
|
// then - config values are preserved
|
|
expect(result.migrated.sisyphus).toEqual({ model: "anthropic/claude-opus-4-7", temperature: 0.1 })
|
|
expect(result.migrated.prometheus).toEqual({ model: "anthropic/claude-opus-4-7" })
|
|
})
|
|
|
|
test("new config works without migration", () => {
|
|
// given - new format config (already lowercase)
|
|
const newConfig = {
|
|
sisyphus: { model: "anthropic/claude-opus-4-7" },
|
|
atlas: { model: "anthropic/claude-opus-4-7" },
|
|
}
|
|
|
|
// when - migration is applied (should be no-op)
|
|
const result = migrateAgentNames(newConfig)
|
|
|
|
// then - config is unchanged
|
|
expect(result.migrated).toEqual(newConfig)
|
|
|
|
// then - changed flag is false
|
|
expect(result.changed).toBe(false)
|
|
|
|
// when - display names are retrieved
|
|
const sisyphusDisplay = getAgentDisplayName("sisyphus")
|
|
const atlasDisplay = getAgentDisplayName("atlas")
|
|
|
|
// then - display names are correct
|
|
expect(sisyphusDisplay).toBe("Sisyphus - ultraworker")
|
|
expect(atlasDisplay).toBe("Atlas - Plan Executor")
|
|
})
|
|
})
|
|
})
|