feat(athena): inject intent runtime guidance and action flows
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
/// <reference types="bun-types" />
|
||||
|
||||
import { describe, expect, it, beforeEach } from "bun:test"
|
||||
import { mkdtemp, mkdir, writeFile, readFile } from "node:fs/promises"
|
||||
import { join } from "node:path"
|
||||
@@ -232,4 +234,165 @@ describe("createCouncilFinalize", () => {
|
||||
expect(secondContent).toContain("Second response")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given intent-based runtime guidance injection", () => {
|
||||
it("#then registers critical custom context for Athena runtime guidance", async () => {
|
||||
await writeFile(
|
||||
join(tmpDir, ".sisyphus", "task-outputs", "bg_intent.md"),
|
||||
mockTaskOutput("Council: GPT-5", "Plan proposal"),
|
||||
"utf-8",
|
||||
)
|
||||
|
||||
const calls: Array<{ sessionID: string; content: string; priority?: string; source: string; id: string }> = []
|
||||
const collector = {
|
||||
register: (sessionID: string, options: { id: string; source: string; content: string; priority?: string }) => {
|
||||
calls.push({
|
||||
sessionID,
|
||||
id: options.id,
|
||||
source: options.source,
|
||||
content: options.content,
|
||||
priority: options.priority,
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
const toolDef = createCouncilFinalize(tmpDir, { contextCollector: collector })
|
||||
const result = await toolDef.execute(
|
||||
{ task_ids: ["bg_intent"], name: "intent", intent: "PLAN" },
|
||||
mockCtx,
|
||||
)
|
||||
|
||||
expect(() => JSON.parse(result)).not.toThrow()
|
||||
expect(calls).toHaveLength(1)
|
||||
expect(calls[0].sessionID).toBe(mockCtx.sessionID)
|
||||
expect(calls[0].id).toBe("athena-runtime-guidance")
|
||||
expect(calls[0].source).toBe("custom")
|
||||
expect(calls[0].priority).toBe("critical")
|
||||
expect(calls[0].content).toContain("<athena_runtime_guidance>")
|
||||
expect(calls[0].content).toContain("intent: PLAN")
|
||||
expect(calls[0].content).toContain("Execute full plan (Prometheus)")
|
||||
expect(calls[0].content).toContain("Execute selected phase (Prometheus)")
|
||||
expect(calls[0].content).toContain(".sisyphus/athena/notes/{council-session-name}")
|
||||
expect(calls[0].content).not.toContain("Hand off to Atlas to save the plan as .md")
|
||||
})
|
||||
|
||||
it("#then emits diagnose action options for hephaestus and sisyphus", async () => {
|
||||
await writeFile(
|
||||
join(tmpDir, ".sisyphus", "task-outputs", "bg_diagnose.md"),
|
||||
mockTaskOutput("Council: Claude", "Root cause found"),
|
||||
"utf-8",
|
||||
)
|
||||
|
||||
const calls: Array<{ content: string }> = []
|
||||
const collector = {
|
||||
register: (_sessionID: string, options: { content: string }) => {
|
||||
calls.push({ content: options.content })
|
||||
},
|
||||
}
|
||||
|
||||
const toolDef = createCouncilFinalize(tmpDir, { contextCollector: collector })
|
||||
const result = await toolDef.execute(
|
||||
{ task_ids: ["bg_diagnose"], name: "diagnose", intent: "DIAGNOSE" },
|
||||
mockCtx,
|
||||
)
|
||||
|
||||
expect(() => JSON.parse(result)).not.toThrow()
|
||||
expect(calls).toHaveLength(1)
|
||||
expect(calls[0].content).toContain("Implement (Hephaestus)")
|
||||
expect(calls[0].content).toContain("Implement (Sisyphus)")
|
||||
expect(calls[0].content).toContain("Implement (Sisyphus ultrawork)")
|
||||
expect(calls[0].content).toContain("switch_agent(agent=\"hephaestus\")")
|
||||
expect(calls[0].content).toContain("switch_agent(agent=\"sisyphus\")")
|
||||
expect(calls[0].content).toContain("prefix the handoff context with \"ultrawork \"")
|
||||
expect(calls[0].content).not.toContain("Fix now (Atlas)")
|
||||
expect(calls[0].content).not.toContain("Create plan (Prometheus)")
|
||||
})
|
||||
|
||||
it("#then emits audit processing mode and batching guidance", async () => {
|
||||
await writeFile(
|
||||
join(tmpDir, ".sisyphus", "task-outputs", "bg_audit.md"),
|
||||
mockTaskOutput("Council: Claude", "Audit findings"),
|
||||
"utf-8",
|
||||
)
|
||||
|
||||
const calls: Array<{ content: string }> = []
|
||||
const collector = {
|
||||
register: (_sessionID: string, options: { content: string }) => {
|
||||
calls.push({ content: options.content })
|
||||
},
|
||||
}
|
||||
|
||||
const toolDef = createCouncilFinalize(tmpDir, { contextCollector: collector })
|
||||
const result = await toolDef.execute(
|
||||
{ task_ids: ["bg_audit"], name: "audit", intent: "AUDIT" },
|
||||
mockCtx,
|
||||
)
|
||||
|
||||
expect(() => JSON.parse(result)).not.toThrow()
|
||||
expect(calls).toHaveLength(1)
|
||||
expect(calls[0].content).toContain("How would you like to process the findings?")
|
||||
expect(calls[0].content).toContain("One by one")
|
||||
expect(calls[0].content).toContain("By severity/urgency")
|
||||
expect(calls[0].content).toContain("By quorum")
|
||||
expect(calls[0].content).toContain("Default batch size: 3 findings per batch")
|
||||
expect(calls[0].content).toContain("Hard cap: 5 findings")
|
||||
expect(calls[0].content).toContain("Example Question tool call (batch of 3 findings)")
|
||||
expect(calls[0].content).toContain("Finding #10: choose how to proceed.")
|
||||
expect(calls[0].content).toContain("#10 Action")
|
||||
expect(calls[0].content).toContain("Stop review")
|
||||
expect(calls[0].content).toContain("#10:A, #11:skip")
|
||||
expect(calls[0].content).toContain("Which findings should we act on by severity?")
|
||||
expect(calls[0].content).toContain("All Critical (N)")
|
||||
expect(calls[0].content).toContain("All High (N)")
|
||||
expect(calls[0].content).toContain("All Medium (N)")
|
||||
expect(calls[0].content).toContain("All Low (N)")
|
||||
expect(calls[0].content).toContain("Which findings should we act on? You can also type specific finding numbers")
|
||||
expect(calls[0].content).toContain("All Unanimous (N)")
|
||||
expect(calls[0].content).toContain("All Majority (N)")
|
||||
expect(calls[0].content).toContain("All Minority (N)")
|
||||
expect(calls[0].content).toContain("All Solo (N)")
|
||||
expect(calls[0].content).toContain("Fix now (Atlas)")
|
||||
expect(calls[0].content).toContain("Create plan (Prometheus)")
|
||||
})
|
||||
|
||||
it("#then emits informational write-to-document path without atlas delegation", async () => {
|
||||
await writeFile(
|
||||
join(tmpDir, ".sisyphus", "task-outputs", "bg_eval.md"),
|
||||
mockTaskOutput("Council: Claude", "Option comparison"),
|
||||
"utf-8",
|
||||
)
|
||||
|
||||
const calls: Array<{ content: string }> = []
|
||||
const collector = {
|
||||
register: (_sessionID: string, options: { content: string }) => {
|
||||
calls.push({ content: options.content })
|
||||
},
|
||||
}
|
||||
|
||||
const toolDef = createCouncilFinalize(tmpDir, { contextCollector: collector })
|
||||
const result = await toolDef.execute(
|
||||
{ task_ids: ["bg_eval"], name: "eval", intent: "EVALUATE" },
|
||||
mockCtx,
|
||||
)
|
||||
|
||||
expect(() => JSON.parse(result)).not.toThrow()
|
||||
expect(calls).toHaveLength(1)
|
||||
expect(calls[0].content).toContain("What should we do with this evaluation?")
|
||||
expect(calls[0].content).toContain("Adopt option -> create plan (Prometheus)")
|
||||
expect(calls[0].content).toContain("Adopt option -> implement now")
|
||||
expect(calls[0].content).toContain(".sisyphus/athena/notes/{council-session-name}")
|
||||
expect(calls[0].content).not.toContain("Write to document (Atlas)")
|
||||
})
|
||||
|
||||
it("#then rejects invalid intent values", async () => {
|
||||
const toolDef = createCouncilFinalize(tmpDir)
|
||||
const result = await toolDef.execute(
|
||||
{ task_ids: ["bg_none"], name: "invalid-intent", intent: "NOT_A_REAL_INTENT" },
|
||||
mockCtx,
|
||||
)
|
||||
|
||||
expect(result).toContain("Invalid intent")
|
||||
expect(result).toContain("NOT_A_REAL_INTENT")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user