diff --git a/src/hooks/compaction-context-injector/hook.ts b/src/hooks/compaction-context-injector/hook.ts index 639f3e96..0f3a912f 100644 --- a/src/hooks/compaction-context-injector/hook.ts +++ b/src/hooks/compaction-context-injector/hook.ts @@ -1,3 +1,4 @@ +import type { BackgroundManager } from "../../features/background-agent" import { createSystemDirective, SystemDirectiveTypes, @@ -47,9 +48,25 @@ When summarizing this session, you MUST include the following sections in your s This section is CRITICAL for reviewer agents (momus, oracle) to maintain continuity. +## 8. Delegated Agent Sessions +- List ALL background agent tasks spawned during this session +- For each: agent name, category, status, description, and **session_id** +- **RESUME, DON'T RESTART.** Each listed session retains full context. After compaction, use \`session_id\` to continue existing agent sessions instead of spawning new ones. This saves tokens, preserves learned context, and prevents duplicate work. + This context is critical for maintaining continuity after compaction. ` -export function createCompactionContextInjector() { - return (): string => COMPACTION_CONTEXT_PROMPT +export function createCompactionContextInjector(backgroundManager?: BackgroundManager) { + return (sessionID?: string): string => { + let prompt = COMPACTION_CONTEXT_PROMPT + + if (backgroundManager && sessionID) { + const history = backgroundManager.taskHistory.formatForCompaction(sessionID) + if (history) { + prompt += `\n### Active/Recent Delegated Sessions\n${history}\n` + } + } + + return prompt + } } diff --git a/src/hooks/compaction-context-injector/index.test.ts b/src/hooks/compaction-context-injector/index.test.ts index 85348e09..a2813916 100644 --- a/src/hooks/compaction-context-injector/index.test.ts +++ b/src/hooks/compaction-context-injector/index.test.ts @@ -15,6 +15,7 @@ mock.module("../../shared/system-directive", () => ({ })) import { createCompactionContextInjector } from "./index" +import { TaskHistory } from "../../features/background-agent/task-history" describe("createCompactionContextInjector", () => { describe("Agent Verification State preservation", () => { @@ -69,4 +70,47 @@ describe("createCompactionContextInjector", () => { expect(prompt).toContain("Do NOT invent") expect(prompt).toContain("Quote constraints verbatim") }) + + describe("Delegated Agent Sessions", () => { + it("includes delegated sessions section in compaction prompt", async () => { + //#given + const injector = createCompactionContextInjector() + + //#when + const prompt = injector() + + //#then + expect(prompt).toContain("Delegated Agent Sessions") + expect(prompt).toContain("RESUME, DON'T RESTART") + expect(prompt).toContain("session_id") + }) + + it("injects actual task history when backgroundManager and sessionID provided", async () => { + //#given + const mockManager = { taskHistory: new TaskHistory() } as any + mockManager.taskHistory.record("ses_parent", { id: "t1", sessionID: "ses_child", agent: "explore", description: "Find patterns", status: "completed", category: "quick" }) + const injector = createCompactionContextInjector(mockManager) + + //#when + const prompt = injector("ses_parent") + + //#then + expect(prompt).toContain("Active/Recent Delegated Sessions") + expect(prompt).toContain("**explore**") + expect(prompt).toContain("[quick]") + expect(prompt).toContain("`ses_child`") + }) + + it("does not inject task history section when no entries exist", async () => { + //#given + const mockManager = { taskHistory: new TaskHistory() } as any + const injector = createCompactionContextInjector(mockManager) + + //#when + const prompt = injector("ses_empty") + + //#then + expect(prompt).not.toContain("Active/Recent Delegated Sessions") + }) + }) })