feat(athena): split into athena (interactive) and athena-junior (subagent)
Split the Athena council orchestrator into two distinct agents: - athena: primary mode, interactive prompt with Question tool and switch_agent - athena-junior: subagent mode, non-interactive prompt with structured JSON output Key changes: - Create athena-junior-agent.ts factory (mode=subagent, denies question+call_omo_agent) - Revert athena agent.ts to primary mode (no env var switching) - Make buildAthenaRuntimeGuidance mode-aware (strips action_paths for non-interactive) - Add mode parameter to council_finalize tool - Register athena-junior in builtin-agents, tool-config, model-requirements - Replace "athena" with "athena-junior" in call_omo_agent ALLOWED_AGENTS - Update all tests for new architecture Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -6,7 +6,7 @@ export const ALLOWED_AGENTS = [
|
||||
"metis",
|
||||
"momus",
|
||||
"multimodal-looker",
|
||||
"athena",
|
||||
"athena-junior",
|
||||
] as const
|
||||
|
||||
export const CALL_OMO_AGENT_DESCRIPTION = `Spawn explore/librarian agent or custom agents. run_in_background REQUIRED (true=async with task_id, false=sync).
|
||||
|
||||
@@ -512,7 +512,7 @@ describe("createCallOmoAgent", () => {
|
||||
expect(result).toContain("background_task.maxDepth=3")
|
||||
})
|
||||
|
||||
test("should accept athena as a valid agent type", async () => {
|
||||
test("should accept athena-junior as a valid agent type", async () => {
|
||||
//#given
|
||||
const toolDef = createCallOmoAgent(mockCtx, mockBackgroundManager, [])
|
||||
const executeFunc = toolDef.execute as Function
|
||||
@@ -522,7 +522,7 @@ describe("createCallOmoAgent", () => {
|
||||
{
|
||||
description: "Test",
|
||||
prompt: "Test prompt",
|
||||
subagent_type: "athena",
|
||||
subagent_type: "athena-junior",
|
||||
run_in_background: true,
|
||||
},
|
||||
{ sessionID: "test", messageID: "msg", agent: "test", abort: new AbortController().signal }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
resolveCouncilIntent,
|
||||
COUNCIL_DEFAULTS,
|
||||
} from "../../agents/athena"
|
||||
import type { CouncilGuidanceMode } from "../../agents/athena"
|
||||
import type { CouncilFinalizeArgs, CouncilMemberResult, CouncilFinalizeResult } from "./types"
|
||||
|
||||
export function createCouncilFinalize(
|
||||
@@ -30,6 +31,10 @@ export function createCouncilFinalize(
|
||||
.describe(`Classified question intent used for runtime Athena guidance injection. Valid intents: ${getValidCouncilIntents().join(", ")}`),
|
||||
question: tool.schema.string().optional().describe("Original user question that triggered the council"),
|
||||
prompt_file: tool.schema.string().optional().describe("Path to the council prompt temp file (will be moved into the archive)"),
|
||||
mode: tool.schema
|
||||
.string()
|
||||
.optional()
|
||||
.describe('Council guidance mode: "interactive" (default) includes action paths with Question tool, "non-interactive" strips action paths for programmatic use'),
|
||||
},
|
||||
async execute(args: CouncilFinalizeArgs, toolContext) {
|
||||
const resolvedIntent = resolveCouncilIntent(args.intent)
|
||||
@@ -154,7 +159,8 @@ export function createCouncilFinalize(
|
||||
members,
|
||||
}
|
||||
|
||||
const guidance = buildAthenaRuntimeGuidance(resolvedIntent)
|
||||
const resolvedMode = (args.mode === "non-interactive" ? "non-interactive" : "interactive") as CouncilGuidanceMode
|
||||
const guidance = buildAthenaRuntimeGuidance(resolvedIntent, resolvedMode)
|
||||
return JSON.stringify(result, null, 2) + "\n\n" + guidance
|
||||
},
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ export interface CouncilFinalizeArgs {
|
||||
intent: string
|
||||
question?: string
|
||||
prompt_file?: string
|
||||
mode?: string
|
||||
}
|
||||
|
||||
export interface CouncilMemberResult {
|
||||
|
||||
Reference in New Issue
Block a user