feat(athena): add session handoff with Question tool for Atlas/Prometheus routing

After Athena synthesizes council findings, presents user with Question tool
TUI to choose: Atlas (fix now), Prometheus (create plan), or no action.
On selection, session_handoff tool stores intent + calls updateSessionAgent(),
then agent-handoff hook fires on session.idle to switch the main session's
active agent via promptAsync with synthesis context.
This commit is contained in:
ismeth
2026-02-13 12:57:16 +01:00
committed by YeonGyu-Kim
parent 84c91cb8d7
commit 7db0f110ee
16 changed files with 281 additions and 12 deletions
+37
View File
@@ -0,0 +1,37 @@
import { tool, type ToolDefinition } from "@opencode-ai/plugin"
import { setPendingHandoff } from "../../features/agent-handoff"
import { updateSessionAgent } from "../../features/claude-code-session-state"
import type { SessionHandoffArgs } from "./types"
const DESCRIPTION =
"Switch the active session agent. After calling this tool, the session will transition to the specified agent " +
"with the provided context as its starting prompt. Use this to hand off work to another agent " +
"(e.g., Atlas for fixes, Prometheus for planning). The handoff executes when the current agent's turn completes."
const ALLOWED_AGENTS = new Set(["atlas", "prometheus", "sisyphus", "hephaestus"])
export function createSessionHandoffTool(): ToolDefinition {
return tool({
description: DESCRIPTION,
args: {
agent: tool.schema
.string()
.describe("Target agent name to hand off to (e.g., 'atlas', 'prometheus')"),
context: tool.schema
.string()
.describe("Context message for the target agent — include confirmed findings, the original question, and what action to take"),
},
async execute(args: SessionHandoffArgs, toolContext) {
const agentName = args.agent.toLowerCase()
if (!ALLOWED_AGENTS.has(agentName)) {
return `Invalid handoff target: "${args.agent}". Allowed agents: ${[...ALLOWED_AGENTS].join(", ")}`
}
updateSessionAgent(toolContext.sessionID, agentName)
setPendingHandoff(toolContext.sessionID, agentName, args.context)
return `Handoff queued. Session will switch to ${agentName} when your turn completes.`
},
})
}