feat(athena): expand council intent system from 4 to 8 intents
Add DIAGNOSE, CREATE, PERSPECTIVES, FREEFORM intents to Athena's council classification system. Refine existing AUDIT (add DIAGNOSE boundary), EVALUATE (improve criteria guidance), and EXPLAIN (remove catch-all status). Fix bug where prepare_council_prompt defaulted to AUDIT when no intent was specified — this caused analytical frameworks to be injected into creative requests (e.g. poetry). Now defaults to no addendum. Derive validIntents from Object.keys(COUNCIL_INTENT_ADDENDUMS) to prevent drift between the addendums record and the validation array.
This commit is contained in:
@@ -1,4 +1,57 @@
|
||||
export const COUNCIL_INTENT_ADDENDUMS: Record<string, string> = {
|
||||
DIAGNOSE: `
|
||||
## Analysis Intent: DIAGNOSE
|
||||
|
||||
You are conducting a **diagnosis** — your goal is to trace an observed problem back to its root cause through systematic investigation.
|
||||
|
||||
**Focus:**
|
||||
- Start from the reported symptom — what is actually observed vs. what is expected?
|
||||
- Form hypotheses about potential causes, ordered by likelihood
|
||||
- For each hypothesis, gather concrete evidence that confirms or eliminates it
|
||||
- Follow the causal chain backward: symptom ← immediate cause ← deeper cause ← root cause
|
||||
- Distinguish the root cause from contributing factors and coincidental observations
|
||||
- Propose a fix that addresses the root cause, not just the symptom
|
||||
- You are NOT scanning broadly for issues — you are investigating a specific problem
|
||||
|
||||
**Required output fields:**
|
||||
- Symptom (observed vs. expected), Hypotheses investigated (with evidence for/against each)
|
||||
- Root cause (with causal chain and confidence), Contributing factors
|
||||
- Recommended fix (targeting root cause, with verification approach)
|
||||
|
||||
**Structure your response as:**
|
||||
\`\`\`
|
||||
<COUNCIL_MEMBER_RESPONSE>
|
||||
## Symptom
|
||||
[What is happening vs. what should be happening]
|
||||
|
||||
## Investigation
|
||||
### Hypothesis 1: [description]
|
||||
- **Likelihood**: high/medium/low
|
||||
- **Evidence for**: [what supports this hypothesis]
|
||||
- **Evidence against**: [what contradicts it]
|
||||
- **Verdict**: confirmed / eliminated / inconclusive
|
||||
|
||||
### Hypothesis 2: [description]
|
||||
...
|
||||
|
||||
## Root Cause
|
||||
- **What**: [the root cause, stated in one clear sentence]
|
||||
- **Causal Chain**: [symptom] ← [immediate cause] ← [root cause]
|
||||
- **Confidence**: high/medium/low
|
||||
- **Key Evidence**: [the specific evidence that pinpoints this as the root cause]
|
||||
|
||||
## Contributing Factors
|
||||
- [Conditions that aren't the root cause but make the problem worse or more frequent]
|
||||
|
||||
## Recommended Fix
|
||||
- **Target**: [what specifically to change]
|
||||
- **Verification**: [how to confirm the symptom is resolved]
|
||||
|
||||
## Summary
|
||||
[One-paragraph diagnosis with overall confidence level]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
AUDIT: `
|
||||
## Analysis Intent: AUDIT
|
||||
|
||||
@@ -10,6 +63,7 @@ You are conducting an **audit** — your goal is to find discrete issues, risks,
|
||||
- Severity determines priority: critical (blocks/breaks), high (significant risk), medium (should fix), low (nice to fix)
|
||||
- For each finding, provide the specific location (reference, section, or component where it occurs)
|
||||
- State your confidence: high (clear evidence), medium (likely but needs verification), low (suspicion, investigate further)
|
||||
- **This is a broad sweep, not a targeted trace.** If you are starting from a specific symptom and need to find its root cause, that is DIAGNOSE — not AUDIT.
|
||||
|
||||
**Required output fields per finding:**
|
||||
- Title, Severity (critical/high/medium/low), Location, Confidence (high/medium/low)
|
||||
@@ -32,47 +86,6 @@ You are conducting an **audit** — your goal is to find discrete issues, risks,
|
||||
## Summary
|
||||
[Total findings by severity. Overall risk assessment with confidence levels.]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
EVALUATE: `
|
||||
## Analysis Intent: EVALUATE
|
||||
|
||||
You are conducting an **evaluation** — your goal is to compare options against criteria and surface tradeoffs.
|
||||
|
||||
**Focus:**
|
||||
- Identify the options available (explicit or implied by the question)
|
||||
- Define evaluation criteria relevant to the context (cost, complexity, performance, maintainability, risk, etc.)
|
||||
- Assess each option against each criterion with evidence, not assumptions
|
||||
- Surface tradeoffs clearly — where one option wins, another likely loses
|
||||
- If the question implies a recommendation is needed, provide one with conditions
|
||||
|
||||
**Required output fields:**
|
||||
- Options identified, Criteria used, Per-option assessment, Tradeoff summary
|
||||
- Conditional recommendation (if decision is required), Confidence per assessment
|
||||
|
||||
**Structure your response as:**
|
||||
\`\`\`
|
||||
<COUNCIL_MEMBER_RESPONSE>
|
||||
## Options Identified
|
||||
1. [Option A] — [brief description]
|
||||
2. [Option B] — [brief description]
|
||||
|
||||
## Criteria & Assessment
|
||||
| Criterion | Option A | Option B |
|
||||
|-----------|----------|----------|
|
||||
| [e.g. Complexity] | [assessment] | [assessment] |
|
||||
|
||||
## Tradeoff Summary
|
||||
- Option A excels at [X] but sacrifices [Y]
|
||||
- Option B excels at [Y] but sacrifices [X]
|
||||
|
||||
## Recommendation
|
||||
[If applicable: "Choose A if [condition]; choose B if [condition]"]
|
||||
- **Confidence**: [level and reasoning]
|
||||
|
||||
## Risks & Unknowns
|
||||
[Uncertainties that could change the recommendation]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
PLAN: `
|
||||
@@ -118,6 +131,47 @@ You are conducting a **planning analysis** — your goal is to define current st
|
||||
## Summary
|
||||
[Overall effort assessment, key risks, confidence in feasibility]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
EVALUATE: `
|
||||
## Analysis Intent: EVALUATE
|
||||
|
||||
You are conducting an **evaluation** — your goal is to compare options against criteria and surface tradeoffs.
|
||||
|
||||
**Focus:**
|
||||
- Identify the options available (explicit or implied by the question)
|
||||
- Define evaluation criteria relevant to the specific decision context (not generic checklists — choose criteria that actually differentiate the options)
|
||||
- Assess each option against each criterion with evidence, not assumptions
|
||||
- Surface tradeoffs clearly — where one option wins, another likely loses
|
||||
- If the question implies a recommendation is needed, provide one with conditions
|
||||
|
||||
**Required output fields:**
|
||||
- Options identified, Criteria used, Per-option assessment, Tradeoff summary
|
||||
- Conditional recommendation (if decision is required), Confidence per assessment
|
||||
|
||||
**Structure your response as:**
|
||||
\`\`\`
|
||||
<COUNCIL_MEMBER_RESPONSE>
|
||||
## Options Identified
|
||||
1. [Option A] — [brief description]
|
||||
2. [Option B] — [brief description]
|
||||
|
||||
## Criteria & Assessment
|
||||
| Criterion | Option A | Option B |
|
||||
|-----------|----------|----------|
|
||||
| [e.g. Complexity] | [assessment] | [assessment] |
|
||||
|
||||
## Tradeoff Summary
|
||||
- Option A excels at [X] but sacrifices [Y]
|
||||
- Option B excels at [Y] but sacrifices [X]
|
||||
|
||||
## Recommendation
|
||||
[If applicable: "Choose A if [condition]; choose B if [condition]"]
|
||||
- **Confidence**: [level and reasoning]
|
||||
|
||||
## Risks & Unknowns
|
||||
[Uncertainties that could change the recommendation]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
EXPLAIN: `
|
||||
@@ -131,7 +185,9 @@ You are conducting an **explanatory analysis** — your goal is to build underst
|
||||
- Provide evidence and references for each mechanism (not just assertions)
|
||||
- Map relationships, data flows, or causal chains between components
|
||||
- Acknowledge unknowns, gaps in evidence, and areas of uncertainty
|
||||
- Works for any domain: architecture, external systems, abstract concepts, research topics
|
||||
|
||||
**Use this intent for:** "how does X work", "explain Y", "what is Z", "why does this exist", "describe the architecture of..." questions.
|
||||
**This is NOT a catch-all.** If the question doesn't fit this focus, it likely belongs in FREEFORM.
|
||||
|
||||
**Required output fields:**
|
||||
- Thesis statement, Key mechanisms/components (with evidence)
|
||||
@@ -163,5 +219,87 @@ You are conducting an **explanatory analysis** — your goal is to build underst
|
||||
## Summary
|
||||
[Synthesized explanation with overall confidence level]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
CREATE: `
|
||||
## Analysis Intent: CREATE
|
||||
|
||||
You are here to **produce something** — not to analyze, evaluate, or plan it.
|
||||
|
||||
**Focus:**
|
||||
- Produce the actual deliverable directly — code, prose, design, spec, whatever was asked for
|
||||
- Let the deliverable type dictate its own natural structure
|
||||
- Write at a professional level, as if this will be used directly
|
||||
- Be thorough and complete — a finished piece beats a polished fragment
|
||||
- Make creative choices decisively; note significant ones briefly at the end
|
||||
|
||||
**You are not an analyst right now. Stop analyzing. Start making.**
|
||||
|
||||
Do not produce a findings report. Do not produce a severity matrix. Do not produce an options comparison. Produce the thing that was asked for.
|
||||
|
||||
**Structure your response as:**
|
||||
\`\`\`
|
||||
<COUNCIL_MEMBER_RESPONSE>
|
||||
[Your complete deliverable. Structure it however is natural for what you're creating. There is no prescribed internal format.]
|
||||
|
||||
---
|
||||
*Choices: [Optional — only if significant decisions aren't self-evident]*
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
PERSPECTIVES: `
|
||||
## Analysis Intent: PERSPECTIVES
|
||||
|
||||
You are **surfacing genuine viewpoints and taking a stand** — your goal is to map the intellectual landscape, then declare where you land.
|
||||
|
||||
**Focus:**
|
||||
- Identify 2-4 perspectives that are genuinely held — real positions, not straw men
|
||||
- Argue each perspective at its strongest — as if you believed it
|
||||
- Identify the crux: what assumption must be true for each position to be right?
|
||||
- After presenting perspectives, declare YOUR position and defend it
|
||||
- Name what you're giving up by not choosing another perspective
|
||||
|
||||
**Neutral summaries are failure.** If you find every perspective equally valid, you have not thought hard enough. Take a position.
|
||||
|
||||
**Required output fields:**
|
||||
- 2-4 named perspectives (each: position, evidence, crux)
|
||||
- Core tensions between perspectives
|
||||
- Your declared position with reasoning and confidence
|
||||
|
||||
**Structure your response as:**
|
||||
\`\`\`
|
||||
<COUNCIL_MEMBER_RESPONSE>
|
||||
## Perspective 1: [Name/Label]
|
||||
- **Position**: [what this perspective argues — be precise]
|
||||
- **Strongest evidence**: [why a thoughtful person holds this view]
|
||||
- **What it gets right**: [genuine strengths, honestly stated]
|
||||
- **Crux**: [what assumption must be true for this to be right]
|
||||
|
||||
## Perspective 2: [Name/Label]
|
||||
...
|
||||
|
||||
## Core Tensions
|
||||
[Where these perspectives actually collide — incompatible assumptions or values]
|
||||
|
||||
## My Position
|
||||
[Which view you find most defensible. Be direct. Name the cost — what you're giving up or what remains uncertain even given your stance.]
|
||||
- **Confidence**: high/medium/low
|
||||
- **What would change my mind**: [specific conditions or evidence]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
|
||||
FREEFORM: `
|
||||
## Analysis Intent: FREEFORM
|
||||
|
||||
Respond naturally to the question below. No analytical framework is imposed.
|
||||
|
||||
Use whatever structure serves the answer best. Analyze if analysis helps. Answer directly if a direct answer is better. Be conversational if the question is conversational.
|
||||
|
||||
You MUST still wrap your response in \`<COUNCIL_MEMBER_RESPONSE>\` tags for extraction.
|
||||
|
||||
\`\`\`
|
||||
<COUNCIL_MEMBER_RESPONSE>
|
||||
[Your response — structured however is most appropriate for the question]
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
\`\`\``,
|
||||
}
|
||||
|
||||
@@ -75,16 +75,65 @@ describe("createPrepareCouncilPromptTool", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when called with intent DIAGNOSE", () => {
|
||||
it("#then produces file containing DIAGNOSE addendum", async () => {
|
||||
tmpDir = await mkdtemp(join(tmpdir(), "council-test-"))
|
||||
const toolDef = createPrepareCouncilPromptTool(tmpDir)
|
||||
const result = await toolDef.execute({ prompt: "Why is the API returning 500 errors?", intent: "DIAGNOSE" }, mockContext)
|
||||
|
||||
const filePath = extractFilePath(result)
|
||||
const content = await readFile(filePath, "utf-8")
|
||||
expect(content).toContain("## Analysis Intent: DIAGNOSE")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when called with intent CREATE", () => {
|
||||
it("#then produces file containing CREATE addendum", async () => {
|
||||
tmpDir = await mkdtemp(join(tmpdir(), "council-test-"))
|
||||
const toolDef = createPrepareCouncilPromptTool(tmpDir)
|
||||
const result = await toolDef.execute({ prompt: "Write a poem about TypeScript", intent: "CREATE" }, mockContext)
|
||||
|
||||
const filePath = extractFilePath(result)
|
||||
const content = await readFile(filePath, "utf-8")
|
||||
expect(content).toContain("## Analysis Intent: CREATE")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when called with intent PERSPECTIVES", () => {
|
||||
it("#then produces file containing PERSPECTIVES addendum", async () => {
|
||||
tmpDir = await mkdtemp(join(tmpdir(), "council-test-"))
|
||||
const toolDef = createPrepareCouncilPromptTool(tmpDir)
|
||||
const result = await toolDef.execute({ prompt: "What do you think about microservices?", intent: "PERSPECTIVES" }, mockContext)
|
||||
|
||||
const filePath = extractFilePath(result)
|
||||
const content = await readFile(filePath, "utf-8")
|
||||
expect(content).toContain("## Analysis Intent: PERSPECTIVES")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when called with intent FREEFORM", () => {
|
||||
it("#then produces file containing FREEFORM addendum", async () => {
|
||||
tmpDir = await mkdtemp(join(tmpdir(), "council-test-"))
|
||||
const toolDef = createPrepareCouncilPromptTool(tmpDir)
|
||||
const result = await toolDef.execute({ prompt: "Tell me something interesting", intent: "FREEFORM" }, mockContext)
|
||||
|
||||
const filePath = extractFilePath(result)
|
||||
const content = await readFile(filePath, "utf-8")
|
||||
expect(content).toContain("## Analysis Intent: FREEFORM")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when called without intent", () => {
|
||||
it("#then defaults to AUDIT addendum", async () => {
|
||||
it("#then produces file without any intent addendum", async () => {
|
||||
tmpDir = await mkdtemp(join(tmpdir(), "council-test-"))
|
||||
const toolDef = createPrepareCouncilPromptTool(tmpDir)
|
||||
const result = await toolDef.execute({ prompt: "Review this module" }, mockContext)
|
||||
|
||||
expect(result).toContain("intent: AUDIT")
|
||||
expect(result).toContain("intent: none")
|
||||
const filePath = extractFilePath(result)
|
||||
const content = await readFile(filePath, "utf-8")
|
||||
expect(content).toContain("## Analysis Intent: AUDIT")
|
||||
expect(content).not.toContain("## Analysis Intent:")
|
||||
expect(content).toContain("## Analysis Question")
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -45,10 +45,16 @@ The "mode" parameter controls whether council members can delegate exploration t
|
||||
- "delegation": Members can delegate to explore/librarian agents. Faster, lighter context.
|
||||
|
||||
The "intent" parameter controls the analysis framework injected into the prompt:
|
||||
- "AUDIT" (default): Find issues, risks, violations with severity ratings.
|
||||
- "EVALUATE": Compare options against criteria, surface tradeoffs.
|
||||
- "DIAGNOSE": Trace a specific problem to its root cause through systematic investigation.
|
||||
- "AUDIT": Find issues, risks, violations with severity ratings (broad sweep).
|
||||
- "PLAN": Define current state, target state, phased path.
|
||||
- "EVALUATE": Compare options against criteria, surface tradeoffs.
|
||||
- "EXPLAIN": Build understanding of mechanisms and relationships.
|
||||
- "CREATE": Produce a deliverable directly (code, prose, design, spec).
|
||||
- "PERSPECTIVES": Surface genuine viewpoints, argue each at its strongest, take a position.
|
||||
- "FREEFORM": No analytical framework imposed — respond naturally.
|
||||
|
||||
If no intent is specified, no analysis framework is injected.
|
||||
|
||||
Returns the file path to reference in subsequent task() calls.`
|
||||
|
||||
@@ -61,7 +67,7 @@ Returns the file path to reference in subsequent task() calls.`
|
||||
args: {
|
||||
prompt: tool.schema.string().describe("The full analysis prompt/question for council members"),
|
||||
mode: tool.schema.string().optional().describe('Analysis mode: "solo" (default) or "delegation"'),
|
||||
intent: tool.schema.string().optional().describe('Question intent: "AUDIT", "EVALUATE", "PLAN", "EXPLAIN"'),
|
||||
intent: tool.schema.string().optional().describe('Question intent: "DIAGNOSE", "AUDIT", "PLAN", "EVALUATE", "EXPLAIN", "CREATE", "PERSPECTIVES", "FREEFORM"'),
|
||||
},
|
||||
async execute(args: { prompt: string; mode?: string; intent?: string }) {
|
||||
if (!args.prompt?.trim()) {
|
||||
@@ -72,12 +78,12 @@ Returns the file path to reference in subsequent task() calls.`
|
||||
return `Invalid mode: "${args.mode}". Valid modes: "solo", "delegation".`
|
||||
}
|
||||
|
||||
const validIntents = ["AUDIT", "EVALUATE", "PLAN", "EXPLAIN"]
|
||||
const validIntents = Object.keys(COUNCIL_INTENT_ADDENDUMS)
|
||||
if (args.intent !== undefined && !validIntents.includes(args.intent.toUpperCase())) {
|
||||
return `Invalid intent: "${args.intent}". Valid intents: "AUDIT", "EVALUATE", "PLAN", "EXPLAIN".`
|
||||
return `Invalid intent: "${args.intent}". Valid intents: ${validIntents.map((i) => `"${i}"`).join(", ")}.`
|
||||
}
|
||||
|
||||
const resolvedIntent = args.intent?.toUpperCase() ?? "AUDIT"
|
||||
const resolvedIntent = args.intent?.toUpperCase()
|
||||
|
||||
const mode = args.mode === "delegation" ? "delegation" : "solo"
|
||||
|
||||
@@ -89,14 +95,10 @@ Returns the file path to reference in subsequent task() calls.`
|
||||
const filePath = join(tmpDir, filename)
|
||||
|
||||
const modeAddendum = mode === "delegation" ? COUNCIL_DELEGATION_ADDENDUM : COUNCIL_SOLO_ADDENDUM
|
||||
const intentAddendum = COUNCIL_INTENT_ADDENDUMS[resolvedIntent] ?? COUNCIL_INTENT_ADDENDUMS["AUDIT"]
|
||||
const content = `${modeAddendum}
|
||||
|
||||
${intentAddendum}
|
||||
|
||||
## Analysis Question
|
||||
|
||||
${args.prompt}`
|
||||
const intentAddendum = resolvedIntent ? (COUNCIL_INTENT_ADDENDUMS[resolvedIntent] ?? "") : ""
|
||||
const content = intentAddendum
|
||||
? `${modeAddendum}\n\n${intentAddendum}\n\n## Analysis Question\n\n${args.prompt}`
|
||||
: `${modeAddendum}\n\n## Analysis Question\n\n${args.prompt}`
|
||||
|
||||
await writeFile(filePath, content, "utf-8")
|
||||
|
||||
@@ -108,7 +110,7 @@ ${args.prompt}`
|
||||
|
||||
log("[prepare-council-prompt] Saved prompt", { filePath, length: args.prompt.length, mode })
|
||||
|
||||
return `Council prompt saved to: ${filePath} (mode: ${mode}, intent: ${resolvedIntent})
|
||||
return `Council prompt saved to: ${filePath} (mode: ${mode}, intent: ${resolvedIntent ?? "none"})
|
||||
|
||||
Use this path in each council member's task() call:
|
||||
- prompt: "Read ${filePath} for your instructions."
|
||||
|
||||
Reference in New Issue
Block a user