import assert from "node:assert/strict"; import * as fs from "node:fs"; import * as os from "node:os"; import * as path from "node:path"; import { afterEach, describe, it } from "node:test"; import { writeSteerRequestToDir } from "../../src/runs/background/control-channel.ts"; import { SUBAGENT_CHILD_AGENT_ENV, SUBAGENT_CHILD_INDEX_ENV, SUBAGENT_FANOUT_CHILD_ENV, SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV, SUBAGENT_ORCHESTRATOR_TARGET_ENV, SUBAGENT_RUN_ID_ENV, SUBAGENT_STEER_INBOX_ENV, SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV, } from "../../src/runs/shared/pi-args.ts"; import { STRUCTURED_OUTPUT_CAPTURE_ENV, STRUCTURED_OUTPUT_SCHEMA_ENV } from "../../src/runs/shared/structured-output.ts"; import { TOOL_BUDGET_ENV } from "../../src/runs/shared/tool-budget.ts"; import registerSubagentPromptRuntime, { CHILD_FANOUT_BOUNDARY_INSTRUCTIONS, CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS, SUBAGENT_INTERCOM_SESSION_NAME_ENV, rewriteSubagentPrompt, stripInheritedSkills, stripParentOnlySubagentMessages, stripProjectContext, stripSubagentOrchestrationSkill, } from "../../src/runs/shared/subagent-prompt-runtime.ts"; const envSnapshot = { SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT: process.env.SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT, SELESAI_SUBAGENT_INHERIT_SKILLS: process.env.SELESAI_SUBAGENT_INHERIT_SKILLS, SELESAI_SUBAGENT_INTERCOM_SESSION_NAME: process.env.SELESAI_SUBAGENT_INTERCOM_SESSION_NAME, SELESAI_SUBAGENT_FANOUT_CHILD: process.env.SELESAI_SUBAGENT_FANOUT_CHILD, SELESAI_SUBAGENT_STEER_INBOX: process.env.SELESAI_SUBAGENT_STEER_INBOX, SELESAI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE: process.env.SELESAI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE, SELESAI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA: process.env.SELESAI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA, SELESAI_SUBAGENT_TOOL_BUDGET: process.env.SELESAI_SUBAGENT_TOOL_BUDGET, SELESAI_SUBAGENT_ORCHESTRATOR_TARGET: process.env.SELESAI_SUBAGENT_ORCHESTRATOR_TARGET, SELESAI_SUBAGENT_ORCHESTRATOR_SESSION_ID: process.env.SELESAI_SUBAGENT_ORCHESTRATOR_SESSION_ID, SELESAI_SUBAGENT_SUPERVISOR_CHANNEL_DIR: process.env.SELESAI_SUBAGENT_SUPERVISOR_CHANNEL_DIR, SELESAI_SUBAGENT_RUN_ID: process.env.SELESAI_SUBAGENT_RUN_ID, SELESAI_SUBAGENT_CHILD_AGENT: process.env.SELESAI_SUBAGENT_CHILD_AGENT, SELESAI_SUBAGENT_CHILD_INDEX: process.env.SELESAI_SUBAGENT_CHILD_INDEX, }; const SKILLS_SECTION = "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n safe-bash\n desc\n /tmp/SKILL.md\n \n \n pi-subagents\n delegate to subagents\n /tmp/pi-subagents/SKILL.md\n \n"; const BASE_PROMPT = [ "You are a subagent.", "\n\n# Project Context\n\nProject-specific instructions and guidelines:\n\n## /repo/AGENTS.md\n\nProject rules\n\n", SKILLS_SECTION, "\nCurrent date: 2026-04-16", "\nCurrent working directory: /repo", ].join(""); const PROMPT_WITH_EXPLICIT_SKILL = [ "You are a subagent.\n\n\nKeep this section\n", "\n\n# Project Context\n\nProject-specific instructions and guidelines:\n\n## /repo/AGENTS.md\n\nProject rules\n\n", SKILLS_SECTION, "\nCurrent date: 2026-04-16", ].join(""); const CONFIGURED_SKILLS_SECTION = "\n\nThe following configured skills are available to this subagent.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n configured-skill\n explicit agent skill\n /tmp/configured-skill/SKILL.md\n \n"; afterEach(() => { if (envSnapshot.SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT === undefined) delete process.env.SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT; else process.env.SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT = envSnapshot.SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT; if (envSnapshot.SELESAI_SUBAGENT_INHERIT_SKILLS === undefined) delete process.env.SELESAI_SUBAGENT_INHERIT_SKILLS; else process.env.SELESAI_SUBAGENT_INHERIT_SKILLS = envSnapshot.SELESAI_SUBAGENT_INHERIT_SKILLS; if (envSnapshot.SELESAI_SUBAGENT_INTERCOM_SESSION_NAME === undefined) delete process.env.SELESAI_SUBAGENT_INTERCOM_SESSION_NAME; else process.env.SELESAI_SUBAGENT_INTERCOM_SESSION_NAME = envSnapshot.SELESAI_SUBAGENT_INTERCOM_SESSION_NAME; if (envSnapshot.SELESAI_SUBAGENT_FANOUT_CHILD === undefined) delete process.env.SELESAI_SUBAGENT_FANOUT_CHILD; else process.env.SELESAI_SUBAGENT_FANOUT_CHILD = envSnapshot.SELESAI_SUBAGENT_FANOUT_CHILD; if (envSnapshot.SELESAI_SUBAGENT_STEER_INBOX === undefined) delete process.env[SUBAGENT_STEER_INBOX_ENV]; else process.env[SUBAGENT_STEER_INBOX_ENV] = envSnapshot.SELESAI_SUBAGENT_STEER_INBOX; if (envSnapshot.SELESAI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE === undefined) delete process.env[STRUCTURED_OUTPUT_CAPTURE_ENV]; else process.env[STRUCTURED_OUTPUT_CAPTURE_ENV] = envSnapshot.SELESAI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE; if (envSnapshot.SELESAI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA === undefined) delete process.env[STRUCTURED_OUTPUT_SCHEMA_ENV]; else process.env[STRUCTURED_OUTPUT_SCHEMA_ENV] = envSnapshot.SELESAI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA; if (envSnapshot.SELESAI_SUBAGENT_TOOL_BUDGET === undefined) delete process.env[TOOL_BUDGET_ENV]; else process.env[TOOL_BUDGET_ENV] = envSnapshot.SELESAI_SUBAGENT_TOOL_BUDGET; if (envSnapshot.SELESAI_SUBAGENT_ORCHESTRATOR_TARGET === undefined) delete process.env[SUBAGENT_ORCHESTRATOR_TARGET_ENV]; else process.env[SUBAGENT_ORCHESTRATOR_TARGET_ENV] = envSnapshot.SELESAI_SUBAGENT_ORCHESTRATOR_TARGET; if (envSnapshot.SELESAI_SUBAGENT_ORCHESTRATOR_SESSION_ID === undefined) delete process.env[SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV]; else process.env[SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV] = envSnapshot.SELESAI_SUBAGENT_ORCHESTRATOR_SESSION_ID; if (envSnapshot.SELESAI_SUBAGENT_SUPERVISOR_CHANNEL_DIR === undefined) delete process.env[SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV]; else process.env[SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV] = envSnapshot.SELESAI_SUBAGENT_SUPERVISOR_CHANNEL_DIR; if (envSnapshot.SELESAI_SUBAGENT_RUN_ID === undefined) delete process.env[SUBAGENT_RUN_ID_ENV]; else process.env[SUBAGENT_RUN_ID_ENV] = envSnapshot.SELESAI_SUBAGENT_RUN_ID; if (envSnapshot.SELESAI_SUBAGENT_CHILD_AGENT === undefined) delete process.env[SUBAGENT_CHILD_AGENT_ENV]; else process.env[SUBAGENT_CHILD_AGENT_ENV] = envSnapshot.SELESAI_SUBAGENT_CHILD_AGENT; if (envSnapshot.SELESAI_SUBAGENT_CHILD_INDEX === undefined) delete process.env[SUBAGENT_CHILD_INDEX_ENV]; else process.env[SUBAGENT_CHILD_INDEX_ENV] = envSnapshot.SELESAI_SUBAGENT_CHILD_INDEX; }); function setSupervisorEnv(): void { process.env[SUBAGENT_ORCHESTRATOR_TARGET_ENV] = "subagent-chat-parent"; process.env[SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV] = "session-parent"; process.env[SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV] = path.join(os.tmpdir(), "subagent-supervisor-runtime-test"); process.env[SUBAGENT_RUN_ID_ENV] = "run-123"; process.env[SUBAGENT_CHILD_AGENT_ENV] = "worker"; process.env[SUBAGENT_CHILD_INDEX_ENV] = "0"; } describe("subagent prompt runtime", () => { it("nudges after the tool budget soft limit and blocks configured tools after hard", () => { const handlers = new Map unknown>(); const sent: string[] = []; process.env[TOOL_BUDGET_ENV] = JSON.stringify({ soft: 2, hard: 2, block: ["read"] }); registerSubagentPromptRuntime({ on(event: string, handler: (payload: { toolName?: string }) => unknown) { handlers.set(event, handler); }, sendUserMessage(content: string) { sent.push(content); }, } as { on(event: string, handler: (payload: { toolName?: string }) => unknown): void; sendUserMessage(content: string): void }); const toolCall = handlers.get("tool_call"); assert.ok(toolCall, "tool_call handler should be registered"); assert.equal(toolCall({ toolName: "grep" }), undefined); assert.equal(toolCall({ toolName: "grep" }), undefined); assert.equal(sent.length, 1); assert.match(sent[0] ?? "", /soft limit reached/); assert.deepEqual(toolCall({ toolName: "read" }), { block: true, reason: "Tool budget hard limit reached after 3 tool calls (hard 2). The 'read' tool is blocked so you can finalize from the context you already have.", }); assert.equal(toolCall({ toolName: "write" }), undefined); }); it("delivers steering inbox requests as mid-run user messages", () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), "subagent-steering-runtime-")); try { const inbox = path.join(dir, "steer"); process.env[SUBAGENT_STEER_INBOX_ENV] = inbox; const handlers = new Map unknown>(); const sent: Array<{ content: string; options: { deliverAs: string } }> = []; registerSubagentPromptRuntime({ on(event: string, handler: (payload?: unknown) => unknown) { handlers.set(event, handler); }, sendUserMessage(content: string, options: { deliverAs: string }) { sent.push({ content, options }); }, } as { on(event: string, handler: (payload?: unknown) => unknown): void; sendUserMessage(content: string, options: { deliverAs: string }): void }); writeSteerRequestToDir(inbox, { type: "steer", id: "steer-1", ts: 1, message: "Focus on tests." }); handlers.get("message_start")?.({}); handlers.get("session_shutdown")?.({}); assert.equal(sent.length, 1); assert.equal(sent[0]?.options.deliverAs, "steer"); assert.match(sent[0]?.content ?? "", /Mid-run steering/); assert.match(sent[0]?.content ?? "", /Focus on tests\./); assert.deepEqual(fs.readdirSync(inbox).filter((entry) => entry.endsWith(".json")), []); } finally { fs.rmSync(dir, { recursive: true, force: true }); } }); it("registered structured_output tool accepts valid schema output and writes the capture file", async () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), "subagent-structured-runtime-")); try { const schemaPath = path.join(dir, "schema.json"); const outputPath = path.join(dir, "output.json"); fs.writeFileSync(schemaPath, JSON.stringify({ type: "object", required: ["ok"], properties: { ok: { type: "boolean" } } }), "utf-8"); process.env[STRUCTURED_OUTPUT_SCHEMA_ENV] = schemaPath; process.env[STRUCTURED_OUTPUT_CAPTURE_ENV] = outputPath; let execute: ((_id: string, params: { value: unknown }) => Promise<{ terminate?: boolean }>) | undefined; registerSubagentPromptRuntime({ registerTool(tool: { name: string; execute: (_id: string, params: { value: unknown }) => Promise<{ terminate?: boolean }> }) { if (tool.name === "structured_output") execute = tool.execute; }, on() {}, } as { registerTool(tool: { name: string; execute: (_id: string, params: { value: unknown }) => Promise<{ terminate?: boolean }> }): void; on(): void }); assert.ok(execute, "structured_output tool should be registered"); const result = await execute("tool-1", { value: { ok: true } }); assert.equal(result.terminate, true); assert.deepEqual(JSON.parse(fs.readFileSync(outputPath, "utf-8")), { ok: true }); } finally { fs.rmSync(dir, { recursive: true, force: true }); } }); it("strips only the project context block", () => { const rewritten = stripProjectContext(BASE_PROMPT); assert.ok(!rewritten.includes("# Project Context")); assert.ok(rewritten.includes("The following skills provide specialized instructions for specific tasks.")); assert.ok(rewritten.includes("Current date: 2026-04-16")); }); it("strips only the inherited skills block", () => { const rewritten = stripInheritedSkills(BASE_PROMPT); assert.ok(rewritten.includes("# Project Context")); assert.ok(!rewritten.includes("")); assert.ok(rewritten.includes("Current date: 2026-04-16")); }); it("can strip both inherited sections together", () => { const rewritten = rewriteSubagentPrompt(BASE_PROMPT, { inheritProjectContext: false, inheritSkills: false, }); assert.ok(!rewritten.includes("# Project Context")); assert.ok(!rewritten.includes("")); assert.ok(rewritten.includes("Current working directory: /repo")); }); it("injects a child-only boundary that forbids proposing or running subagents", () => { const rewritten = rewriteSubagentPrompt(BASE_PROMPT, { inheritProjectContext: true, inheritSkills: true, }); assert.ok(rewritten.startsWith(CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS)); assert.ok(rewritten.includes("Do not propose or run subagents.")); assert.ok(rewritten.includes("If you need to edit files, use the available editing tools.")); assert.ok(!rewritten.includes("call the actual edit/write tools")); assert.ok(rewritten.includes("Do not print tool-call syntax, patches, or pseudo-tool calls as text.")); assert.equal(rewriteSubagentPrompt(rewritten, { inheritProjectContext: true, inheritSkills: true }).indexOf(CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS), 0); assert.equal(rewriteSubagentPrompt(rewritten, { inheritProjectContext: true, inheritSkills: true }).lastIndexOf(CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS), 0); }); it("replaces inherited child boundaries with the fanout boundary when authorized", () => { const strictPrompt = `${CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS}\n\n${BASE_PROMPT}`; const rewritten = rewriteSubagentPrompt(strictPrompt, { inheritProjectContext: true, inheritSkills: true, fanoutChild: true, }); assert.ok(rewritten.startsWith(CHILD_FANOUT_BOUNDARY_INSTRUCTIONS)); assert.ok(rewritten.includes("You may use the `subagent` tool only for the fanout work explicitly requested in this task.")); assert.ok(rewritten.includes("If you need to edit files, use the available editing tools.")); assert.ok(!rewritten.includes("call the actual edit/write tools")); assert.ok(!rewritten.includes("Do not propose or run subagents.")); assert.equal(rewritten.lastIndexOf(CHILD_FANOUT_BOUNDARY_INSTRUCTIONS), 0); }); it("replaces inherited fanout boundaries with the strict boundary when fanout is not authorized", () => { const fanoutPrompt = `${CHILD_FANOUT_BOUNDARY_INSTRUCTIONS}\n\n${BASE_PROMPT}`; const rewritten = rewriteSubagentPrompt(fanoutPrompt, { inheritProjectContext: true, inheritSkills: true, }); assert.ok(rewritten.startsWith(CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS)); assert.ok(!rewritten.includes("explicit fanout responsibility")); assert.equal(rewritten.lastIndexOf(CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS), 0); }); it("keeps explicitly injected skill content when inherited skills are stripped", () => { const rewritten = rewriteSubagentPrompt(PROMPT_WITH_EXPLICIT_SKILL, { inheritProjectContext: false, inheritSkills: false, }); assert.ok(rewritten.includes("")); assert.ok(!rewritten.includes("")); assert.ok(!rewritten.includes("# Project Context")); }); it("keeps configured lazy skill references when inherited skills are stripped", () => { const prompt = [ "You are a subagent.", CONFIGURED_SKILLS_SECTION, "\n\n# Project Context\n\nProject-specific instructions and guidelines:\n\n## /repo/AGENTS.md\n\nProject rules\n\n", SKILLS_SECTION, "\nCurrent date: 2026-04-16", ].join(""); const rewritten = rewriteSubagentPrompt(prompt, { inheritProjectContext: false, inheritSkills: false, }); assert.ok(rewritten.includes("configured-skill")); assert.ok(rewritten.includes("/tmp/configured-skill/SKILL.md")); assert.ok(!rewritten.includes("safe-bash")); assert.ok(!rewritten.includes("# Project Context")); }); it("strips the subagent orchestration skill even when inherited skills remain", () => { const rewritten = rewriteSubagentPrompt(BASE_PROMPT, { inheritProjectContext: true, inheritSkills: true, }); assert.ok(rewritten.includes("safe-bash")); assert.ok(!rewritten.includes("pi-subagents")); assert.ok(!rewritten.includes("delegate to subagents")); }); it("strips explicit pi-subagents skill injection from child prompts", () => { const prompt = "Before\n\n\nDo not keep this.\n\n\n\nKeep this.\n\nAfter"; const rewritten = stripSubagentOrchestrationSkill(prompt); assert.ok(!rewritten.includes("Do not keep this")); assert.ok(rewritten.includes("")); }); it("strips parent-only subagent custom messages from forked child context", () => { const user = { role: "user", content: "Task" }; const instruction = { role: "custom", customType: "subagent-orchestration-instructions", content: "Subagent orchestration is enabled." }; const slashResult = { role: "custom", customType: "subagent-slash-result", content: "## Orchestration" }; const slashTextResult = { role: "custom", customType: "subagent-slash-text-result", content: "Subagent profiles" }; const notify = { role: "custom", customType: "subagent-notify", content: "Background task completed" }; const control = { role: "custom", customType: "subagent_control_notice", content: "needs attention" }; const otherCustom = { role: "custom", customType: "other", content: "keep" }; assert.deepEqual(stripParentOnlySubagentMessages([user, instruction, slashResult, slashTextResult, notify, control, otherCustom]), [user, otherCustom]); }); it("strips prior parent subagent tool calls and results from forked child context", () => { const user = { role: "user", content: "Task" }; const subagentResult = { role: "toolResult", toolName: "subagent", content: "subagent results" }; const readResult = { role: "toolResult", toolName: "read", content: "file contents" }; const mixedAssistant = { role: "assistant", content: [ { type: "text", text: "I will inspect the repo." }, { type: "toolCall", name: "subagent", input: { agent: "worker" } }, { type: "toolCall", name: "read", input: { path: "README.md" } }, ], }; const pureSubagentCall = { role: "assistant", content: [{ type: "toolCall", name: "subagent", input: { agent: "reviewer" } }], }; assert.deepEqual( stripParentOnlySubagentMessages([user, subagentResult, readResult, mixedAssistant, pureSubagentCall]), [ user, readResult, { role: "assistant", content: [ { type: "text", text: "I will inspect the repo." }, { type: "toolCall", name: "read", input: { path: "README.md" } }, ], }, ], ); }); it("preserves live nested subagent calls and results in fanout child context", () => { const user = { role: "user", content: "Task" }; const subagentResult = { role: "toolResult", toolName: "subagent", content: "OK" }; const subagentCall = { role: "assistant", content: [{ type: "toolCall", name: "subagent", input: { agent: "delegate" } }] }; const instruction = { role: "custom", customType: "subagent-orchestration-instructions", content: "Subagent orchestration is enabled." }; process.env[SUBAGENT_FANOUT_CHILD_ENV] = "1"; assert.deepEqual(stripParentOnlySubagentMessages([user, subagentCall, subagentResult, instruction]), [user, subagentCall, subagentResult]); }); it("defers native supervisor registration until runtime events and respects installed pi-intercom tools", async () => { setSupervisorEnv(); const handlers = new Map unknown>(); const registered: string[] = []; registerSubagentPromptRuntime({ on(event: string, handler: (payload?: unknown) => unknown) { handlers.set(event, handler); }, getAllTools: () => [{ name: "intercom" }, { name: "contact_supervisor" }], registerTool(tool: { name: string }) { registered.push(tool.name); }, } as { on(event: string, handler: (payload?: unknown) => unknown): void; getAllTools(): Array<{ name: string }>; registerTool(tool: { name: string }): void }); assert.deepEqual(registered, []); handlers.get("session_start")?.({}); await handlers.get("before_agent_start")?.({ systemPrompt: BASE_PROMPT }); assert.deepEqual(registered, []); }); it("keeps installed pi-intercom while filling only a missing child contact_supervisor tool", async () => { setSupervisorEnv(); const handlers = new Map unknown>(); const registered: string[] = []; registerSubagentPromptRuntime({ on(event: string, handler: (payload?: unknown) => unknown) { handlers.set(event, handler); }, getAllTools: () => [{ name: "intercom" }, ...registered.map((name) => ({ name }))], registerTool(tool: { name: string }) { registered.push(tool.name); }, } as { on(event: string, handler: (payload?: unknown) => unknown): void; getAllTools(): Array<{ name: string }>; registerTool(tool: { name: string }): void }); handlers.get("session_start")?.({}); await handlers.get("before_agent_start")?.({ systemPrompt: BASE_PROMPT }); assert.deepEqual(registered, ["contact_supervisor"]); }); it("registers native supervisor tools at runtime when pi-intercom is absent", async () => { setSupervisorEnv(); const handlers = new Map unknown>(); const registered: string[] = []; registerSubagentPromptRuntime({ on(event: string, handler: (payload?: unknown) => unknown) { handlers.set(event, handler); }, getAllTools: () => registered.map((name) => ({ name })), registerTool(tool: { name: string }) { registered.push(tool.name); }, } as { on(event: string, handler: (payload?: unknown) => unknown): void; getAllTools(): Array<{ name: string }>; registerTool(tool: { name: string }): void }); handlers.get("session_start")?.({}); assert.deepEqual(registered, ["contact_supervisor"]); await handlers.get("before_agent_start")?.({ systemPrompt: BASE_PROMPT }); assert.deepEqual(registered, ["contact_supervisor", "intercom"]); }); it("sets the child intercom session name from env during agent startup", async () => { let sessionName: string | undefined; let beforeAgentStart: ((event: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>) | undefined; process.env[SUBAGENT_INTERCOM_SESSION_NAME_ENV] = "subagent-worker-78f659a3"; registerSubagentPromptRuntime({ on(event: string, handler: (payload: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>) { if (event === "before_agent_start") beforeAgentStart = handler; }, setSessionName(name: string) { sessionName = name; }, } as { on(event: string, handler: (payload: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>): void; setSessionName(name: string): void }); await beforeAgentStart?.({ systemPrompt: BASE_PROMPT }); assert.equal(sessionName, "subagent-worker-78f659a3"); }); it("rewrites the final child-visible prompt through before_agent_start", async () => { let beforeAgentStart: ((event: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>) | undefined; registerSubagentPromptRuntime({ on(event: string, handler: (payload: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>) { if (event === "before_agent_start") beforeAgentStart = handler; }, } as { on(event: string, handler: (payload: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>): void }); assert.ok(beforeAgentStart, "expected before_agent_start handler"); process.env.SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT = "0"; process.env.SELESAI_SUBAGENT_INHERIT_SKILLS = "0"; const rewritten = await beforeAgentStart?.({ systemPrompt: BASE_PROMPT }); assert.ok(rewritten); assert.ok(!rewritten.systemPrompt.includes("# Project Context")); assert.ok(!rewritten.systemPrompt.includes("")); assert.ok(rewritten.systemPrompt.includes("Current date: 2026-04-16")); }); it("uses the fanout boundary through before_agent_start when fanout env is set", async () => { let beforeAgentStart: ((event: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>) | undefined; registerSubagentPromptRuntime({ on(event: string, handler: (payload: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>) { if (event === "before_agent_start") beforeAgentStart = handler; }, } as { on(event: string, handler: (payload: { systemPrompt: string }) => Promise<{ systemPrompt: string } | undefined>): void }); process.env.SELESAI_SUBAGENT_INHERIT_PROJECT_CONTEXT = "1"; process.env.SELESAI_SUBAGENT_INHERIT_SKILLS = "1"; process.env[SUBAGENT_FANOUT_CHILD_ENV] = "1"; const rewritten = await beforeAgentStart?.({ systemPrompt: BASE_PROMPT }); assert.ok(rewritten); assert.ok(rewritten.systemPrompt.startsWith(CHILD_FANOUT_BOUNDARY_INSTRUCTIONS)); }); it("filters parent-only artifacts from polluted fork context while preserving ordinary history", () => { let contextHandler: ((event: { messages: unknown[] }) => { messages: unknown[] } | undefined) | undefined; registerSubagentPromptRuntime({ on(event: string, handler: (payload: { messages: unknown[] }) => { messages: unknown[] } | undefined) { if (event === "context") contextHandler = handler; }, } as { on(event: string, handler: (payload: { messages: unknown[] }) => { messages: unknown[] } | undefined): void }); const priorParentTurn = { role: "user", content: "Earlier we said planner → worker → reviewers → worker." }; const currentTask = { role: "user", content: "Now implement only the assigned fix." }; const instruction = { role: "custom", customType: "subagent-orchestration-instructions", content: "Subagent orchestration is enabled." }; const slashResult = { role: "custom", customType: "subagent-slash-result", content: "## Orchestration" }; const subagentResult = { role: "toolResult", toolName: "subagent", content: "subagent results" }; const subagentCall = { role: "assistant", content: [{ type: "toolCall", name: "subagent", input: { agent: "worker" } }] }; const otherCustom = { role: "custom", customType: "other", content: "keep" }; assert.deepEqual(contextHandler?.({ messages: [priorParentTurn, instruction, slashResult, subagentCall, subagentResult, otherCustom, currentTask] }), { messages: [priorParentTurn, otherCustom, currentTask], }); }); it("does not rewrite child context when no parent-only artifacts are present", () => { let contextHandler: ((event: { messages: unknown[] }) => { messages: unknown[] } | undefined) | undefined; registerSubagentPromptRuntime({ on(event: string, handler: (payload: { messages: unknown[] }) => { messages: unknown[] } | undefined) { if (event === "context") contextHandler = handler; }, } as { on(event: string, handler: (payload: { messages: unknown[] }) => { messages: unknown[] } | undefined): void }); const messages = [ { role: "user", content: "Task" }, { role: "toolResult", toolName: "read", content: "file" }, { role: "assistant", content: [{ type: "toolCall", name: "read", input: { path: "README.md" } }] }, ]; assert.equal(contextHandler?.({ messages }), undefined); }); });