fix(athena): council review fixes — delegation bug, dead code, test coverage
- Add background_output to council-member allowlist (fixes delegation deadlock) - Replace empty catch with error logging in prepare-council-prompt - Remove unnecessary type assertion in agent.ts - Remove dead hasAgentToolRestrictions function - Fix incorrect test assertions (undefined vs false semantics) - Add barrel export for athena module - Add guard function test coverage (5 tests) - Add parity test for triple-sync restrictions (9 tests)
This commit is contained in:
@@ -238,7 +238,7 @@ export function createAthenaAgent(model: string): AgentConfig {
|
||||
// question permission is set by tool-config-handler.ts based on CLI mode (allow/deny)
|
||||
const permission = {
|
||||
...restrictions.permission,
|
||||
} as AgentConfig["permission"]
|
||||
}
|
||||
|
||||
const base = {
|
||||
description:
|
||||
|
||||
@@ -52,6 +52,7 @@ export function createCouncilMemberAgent(model: string): AgentConfig {
|
||||
"lsp_diagnostics",
|
||||
"ast_grep_search",
|
||||
"call_omo_agent",
|
||||
"background_output",
|
||||
])
|
||||
|
||||
// Explicitly deny TodoWrite/TodoRead even though `*: deny` should catch them.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export { createAthenaAgent, ATHENA_PROMPT_METADATA } from "./agent"
|
||||
export { createCouncilMemberAgent, COUNCIL_MEMBER_PROMPT, COUNCIL_DELEGATION_ADDENDUM } from "./council-member-agent"
|
||||
export { applyModelThinkingConfig } from "./model-thinking-config"
|
||||
@@ -0,0 +1,85 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { applyMissingCouncilGuard } from "./athena-council-guard"
|
||||
import type { AgentConfig } from "@opencode-ai/sdk"
|
||||
|
||||
describe("applyMissingCouncilGuard", () => {
|
||||
describe("#given an athena agent config with no skipped members", () => {
|
||||
test("#when applying the guard #then replaces prompt with missing council message", () => {
|
||||
//#given
|
||||
const athenaConfig: AgentConfig = {
|
||||
model: "anthropic/claude-opus-4-6",
|
||||
prompt: "original orchestration prompt",
|
||||
temperature: 0.1,
|
||||
}
|
||||
//#when
|
||||
const result = applyMissingCouncilGuard(athenaConfig)
|
||||
//#then
|
||||
expect(result.prompt).not.toBe("original orchestration prompt")
|
||||
expect(result.prompt).toContain("No Council Members Configured")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given an athena agent config with skipped members", () => {
|
||||
test("#when applying the guard #then includes skipped member names and reasons", () => {
|
||||
//#given
|
||||
const athenaConfig: AgentConfig = {
|
||||
model: "anthropic/claude-opus-4-6",
|
||||
prompt: "original orchestration prompt",
|
||||
}
|
||||
const skippedMembers = [
|
||||
{ name: "GPT", reason: "invalid model format" },
|
||||
{ name: "Gemini", reason: "duplicate name" },
|
||||
]
|
||||
//#when
|
||||
const result = applyMissingCouncilGuard(athenaConfig, skippedMembers)
|
||||
//#then
|
||||
expect(result.prompt).toContain("GPT")
|
||||
expect(result.prompt).toContain("invalid model format")
|
||||
expect(result.prompt).toContain("Gemini")
|
||||
expect(result.prompt).toContain("duplicate name")
|
||||
expect(result.prompt).toContain("Why Council Failed")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given an athena agent config", () => {
|
||||
test("#when applying the guard #then preserves model and other agent properties", () => {
|
||||
//#given
|
||||
const athenaConfig: AgentConfig = {
|
||||
model: "anthropic/claude-opus-4-6",
|
||||
prompt: "original prompt",
|
||||
temperature: 0.1,
|
||||
}
|
||||
//#when
|
||||
const result = applyMissingCouncilGuard(athenaConfig)
|
||||
//#then
|
||||
expect(result.model).toBe("anthropic/claude-opus-4-6")
|
||||
expect(result.temperature).toBe(0.1)
|
||||
})
|
||||
|
||||
test("#when applying the guard #then prompt includes configuration instructions", () => {
|
||||
//#given
|
||||
const athenaConfig: AgentConfig = {
|
||||
model: "anthropic/claude-opus-4-6",
|
||||
prompt: "original prompt",
|
||||
}
|
||||
//#when
|
||||
const result = applyMissingCouncilGuard(athenaConfig)
|
||||
//#then
|
||||
expect(result.prompt).toContain("oh-my-opencode")
|
||||
expect(result.prompt).toContain("council")
|
||||
expect(result.prompt).toContain("members")
|
||||
})
|
||||
|
||||
test("#when applying the guard with empty skipped members array #then does not include why council failed section", () => {
|
||||
//#given
|
||||
const athenaConfig: AgentConfig = {
|
||||
model: "anthropic/claude-opus-4-6",
|
||||
prompt: "original prompt",
|
||||
}
|
||||
//#when
|
||||
const result = applyMissingCouncilGuard(athenaConfig, [])
|
||||
//#then
|
||||
expect(result.prompt).not.toContain("Why Council Failed")
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AgentConfig } from "@opencode-ai/sdk"
|
||||
import type { CouncilConfig, CouncilMemberConfig } from "../../config/schema/athena"
|
||||
import { createCouncilMemberAgent } from "../athena/council-member-agent"
|
||||
import { createCouncilMemberAgent } from "../athena"
|
||||
import { parseModelString } from "../../tools/delegate-task/model-string-parser"
|
||||
import { log } from "../../shared/logger"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user