oh-my-opencode/src/agents/athena/council-orchestrator.ts
ismeth 4d675bac89 refactor(athena): remove dead code from phases 2, 3, 5 pipeline
Remove 9 files (913 lines) from the code-driven synthesis pipeline that
was superseded by the agent-driven approach in phases 6-8.

Phases 3/5 built: collectCouncilResults → formatForSynthesis →
buildSynthesisPrompt → formatFindingsForUser → buildDelegationPrompt.

Phases 6-8 replaced with: launch → background_output → Athena
synthesizes in conversation → switch_agent. The old pipeline was
never wired into runtime and all consumers were other dead code.

Also simplifies executeCouncil to return CouncilLaunchResult (task IDs
+ failures) instead of reading stale task status via collectCouncilResults.

Deleted: council-result-collector, synthesis-types, synthesis-prompt,
synthesis-formatter, findings-presenter, delegation-prompts (+ 4 tests).
Cleaned: CouncilMemberStatus, AgreementLevel, CouncilMemberResponse,
CouncilExecutionResult types from types.ts.
2026-02-24 22:20:54 +09:00

93 lines
2.8 KiB
TypeScript

import type { LaunchInput, BackgroundTask } from "../../features/background-agent/types"
import { createAgentToolRestrictions } from "../../shared/permission-compat"
import { buildCouncilPrompt } from "./council-prompt"
import { parseModelString } from "./model-parser"
import type { CouncilConfig, CouncilLaunchFailure, CouncilLaunchedMember, CouncilLaunchResult, CouncilMemberConfig } from "./types"
export type CouncilLaunchInput = LaunchInput
export interface CouncilLauncher {
launch(input: CouncilLaunchInput): Promise<BackgroundTask>
}
export interface CouncilExecutionInput {
question: string
council: CouncilConfig
launcher: CouncilLauncher
parentSessionID: string
parentMessageID: string
parentAgent?: string
}
/**
* Launches all council members in parallel and returns launch outcomes.
* Does NOT wait for task completion — actual results are collected by the
* agent via background_output calls after this returns.
*/
export async function executeCouncil(input: CouncilExecutionInput): Promise<CouncilLaunchResult> {
const { question, council, launcher, parentSessionID, parentMessageID, parentAgent } = input
const prompt = buildCouncilPrompt(question)
const launchResults = await Promise.allSettled(
council.members.map((member) =>
launchMember(member, prompt, launcher, parentSessionID, parentMessageID, parentAgent)
)
)
const launched: CouncilLaunchedMember[] = []
const failures: CouncilLaunchFailure[] = []
launchResults.forEach((result, index) => {
const member = council.members[index]
if (result.status === "fulfilled") {
launched.push({ member, taskId: result.value.id })
return
}
failures.push({
member,
error: `Launch failed: ${String(result.reason)}`,
})
})
return {
question,
launched,
failures,
totalMembers: council.members.length,
}
}
async function launchMember(
member: CouncilMemberConfig,
prompt: string,
launcher: CouncilLauncher,
parentSessionID: string,
parentMessageID: string,
parentAgent: string | undefined
): Promise<BackgroundTask> {
const parsedModel = parseModelString(member.model)
if (!parsedModel) {
throw new Error(`Invalid model string: "${member.model}"`)
}
const restrictions = createAgentToolRestrictions(["write", "edit", "task"])
const memberName = member.name ?? member.model
return launcher.launch({
description: `Council member: ${memberName}`,
prompt,
agent: "athena",
parentSessionID,
parentMessageID,
parentAgent,
model: {
providerID: parsedModel.providerID,
modelID: parsedModel.modelID,
...(member.variant ? { variant: member.variant } : {}),
},
...(member.temperature !== undefined ? { temperature: member.temperature } : {}),
permission: restrictions.permission,
})
}