diff --git a/.openchrome/hints/hints-2026-03-09.jsonl b/.openchrome/hints/hints-2026-03-09.jsonl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.openchrome/timeline/timeline-2026-03-09.jsonl b/.openchrome/timeline/timeline-2026-03-09.jsonl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/agents/anti-duplication.test.ts b/src/agents/anti-duplication.test.ts new file mode 100644 index 0000000000..49137329af --- /dev/null +++ b/src/agents/anti-duplication.test.ts @@ -0,0 +1,92 @@ +/// + +import { describe, it, expect } from "bun:test" +import { buildAntiDuplicationSection } from "./dynamic-agent-prompt-builder" + +describe("buildAntiDuplicationSection", () => { + it("#given no arguments #when building anti-duplication section #then returns comprehensive rule section", () => { + //#given: no special configuration needed + + //#when: building the anti-duplication section + const result = buildAntiDuplicationSection() + + //#then: should contain the anti-duplication rule with all key concepts + expect(result).toContain("Anti-Duplication Rule") + expect(result).toContain("CRITICAL") + expect(result).toContain("DO NOT perform the same search yourself") + }) + + it("#given no arguments #when building #then explicitly forbids manual re-search after delegation", () => { + //#given: no special configuration + + //#when: building the section + const result = buildAntiDuplicationSection() + + //#then: should explicitly list forbidden behaviors + expect(result).toContain("FORBIDDEN") + expect(result).toContain("manually grep/search for the same information") + expect(result).toContain("Re-doing the research") + }) + + it("#given no arguments #when building #then allows non-overlapping work", () => { + //#given: no special configuration + + //#when: building the section + const result = buildAntiDuplicationSection() + + //#then: should explicitly allow non-overlapping work + expect(result).toContain("ALLOWED") + expect(result).toContain("non-overlapping work") + expect(result).toContain("work that doesn't depend on the delegated research") + }) + + it("#given no arguments #when building #then includes wait-for-results instructions", () => { + //#given: no special configuration + + //#when: building the section + const result = buildAntiDuplicationSection() + + //#then: should include instructions for waiting properly + expect(result).toContain("Wait for Results Properly") + expect(result).toContain("End your response") + expect(result).toContain("Wait for the completion notification") + expect(result).toContain("background_output") + }) + + it("#given no arguments #when building #then explains why this matters", () => { + //#given: no special configuration + + //#when: building the section + const result = buildAntiDuplicationSection() + + //#then: should explain the purpose + expect(result).toContain("Why This Matters") + expect(result).toContain("Wasted tokens") + expect(result).toContain("Confusion") + expect(result).toContain("Efficiency") + }) + + it("#given no arguments #when building #then provides code examples", () => { + //#given: no special configuration + + //#when: building the section + const result = buildAntiDuplicationSection() + + //#then: should include examples + expect(result).toContain("Example") + expect(result).toContain("WRONG") + expect(result).toContain("CORRECT") + expect(result).toContain("task(subagent_type=") + }) + + it("#given no arguments #when building #then uses proper markdown formatting", () => { + //#given: no special configuration + + //#when: building the section + const result = buildAntiDuplicationSection() + + //#then: should be wrapped in Anti_Duplication tag + expect(result).toContain("") + expect(result).toContain("") + }) +}) diff --git a/src/agents/atlas/atlas-prompt.test.ts b/src/agents/atlas/atlas-prompt.test.ts new file mode 100644 index 0000000000..759f3ac8da --- /dev/null +++ b/src/agents/atlas/atlas-prompt.test.ts @@ -0,0 +1,118 @@ +import { describe, test, expect } from "bun:test" +import { ATLAS_SYSTEM_PROMPT } from "./default" +import { ATLAS_GPT_SYSTEM_PROMPT } from "./gpt" +import { ATLAS_GEMINI_SYSTEM_PROMPT } from "./gemini" + +describe("Atlas prompts auto-continue policy", () => { + test("default variant should forbid asking user for continuation confirmation", () => { + // given + const prompt = ATLAS_SYSTEM_PROMPT + + // when + const lowerPrompt = prompt.toLowerCase() + + // then + expect(lowerPrompt).toContain("auto-continue policy") + expect(lowerPrompt).toContain("never ask the user") + expect(lowerPrompt).toContain("should i continue") + expect(lowerPrompt).toContain("proceed to next task") + expect(lowerPrompt).toContain("approval-style") + expect(lowerPrompt).toContain("auto-continue immediately") + }) + + test("gpt variant should forbid asking user for continuation confirmation", () => { + // given + const prompt = ATLAS_GPT_SYSTEM_PROMPT + + // when + const lowerPrompt = prompt.toLowerCase() + + // then + expect(lowerPrompt).toContain("auto-continue policy") + expect(lowerPrompt).toContain("never ask the user") + expect(lowerPrompt).toContain("should i continue") + expect(lowerPrompt).toContain("proceed to next task") + expect(lowerPrompt).toContain("approval-style") + expect(lowerPrompt).toContain("auto-continue immediately") + }) + + test("gemini variant should forbid asking user for continuation confirmation", () => { + // given + const prompt = ATLAS_GEMINI_SYSTEM_PROMPT + + // when + const lowerPrompt = prompt.toLowerCase() + + // then + expect(lowerPrompt).toContain("auto-continue policy") + expect(lowerPrompt).toContain("never ask the user") + expect(lowerPrompt).toContain("should i continue") + expect(lowerPrompt).toContain("proceed to next task") + expect(lowerPrompt).toContain("approval-style") + expect(lowerPrompt).toContain("auto-continue immediately") + }) + + test("all variants should require immediate continuation after verification passes", () => { + // given + const prompts = [ATLAS_SYSTEM_PROMPT, ATLAS_GPT_SYSTEM_PROMPT, ATLAS_GEMINI_SYSTEM_PROMPT] + + // when / then + for (const prompt of prompts) { + const lowerPrompt = prompt.toLowerCase() + expect(lowerPrompt).toMatch(/auto-continue immediately after verification/) + expect(lowerPrompt).toMatch(/immediately delegate next task/) + } + }) + + test("all variants should define when user interaction is actually needed", () => { + // given + const prompts = [ATLAS_SYSTEM_PROMPT, ATLAS_GPT_SYSTEM_PROMPT, ATLAS_GEMINI_SYSTEM_PROMPT] + + // when / then + for (const prompt of prompts) { + const lowerPrompt = prompt.toLowerCase() + expect(lowerPrompt).toMatch(/only pause.*truly blocked/) + expect(lowerPrompt).toMatch(/plan needs clarification|blocked by external/) + } + }) +}) + +describe("Atlas prompts plan path consistency", () => { + test("default variant should use .sisyphus/plans/{plan-name}.md path", () => { + // given + const prompt = ATLAS_SYSTEM_PROMPT + + // when / then + expect(prompt).toContain(".sisyphus/plans/{plan-name}.md") + expect(prompt).not.toContain(".sisyphus/tasks/{plan-name}.yaml") + expect(prompt).not.toContain(".sisyphus/tasks/") + }) + + test("gpt variant should use .sisyphus/plans/{plan-name}.md path", () => { + // given + const prompt = ATLAS_GPT_SYSTEM_PROMPT + + // when / then + expect(prompt).toContain(".sisyphus/plans/{plan-name}.md") + expect(prompt).not.toContain(".sisyphus/tasks/") + }) + + test("gemini variant should use .sisyphus/plans/{plan-name}.md path", () => { + // given + const prompt = ATLAS_GEMINI_SYSTEM_PROMPT + + // when / then + expect(prompt).toContain(".sisyphus/plans/{plan-name}.md") + expect(prompt).not.toContain(".sisyphus/tasks/") + }) + + test("all variants should read plan file after verification", () => { + // given + const prompts = [ATLAS_SYSTEM_PROMPT, ATLAS_GPT_SYSTEM_PROMPT, ATLAS_GEMINI_SYSTEM_PROMPT] + + // when / then + for (const prompt of prompts) { + expect(prompt).toMatch(/read[\s\S]*?\.sisyphus\/plans\//) + } + }) +}) diff --git a/src/agents/atlas/default.ts b/src/agents/atlas/default.ts index 405529a404..3910375f0e 100644 --- a/src/agents/atlas/default.ts +++ b/src/agents/atlas/default.ts @@ -99,6 +99,29 @@ Every \`task()\` prompt MUST include ALL 6 sections: **If your prompt is under 30 lines, it's TOO SHORT.** + +## AUTO-CONTINUE POLICY (STRICT) + +**CRITICAL: NEVER ask the user "should I continue", "proceed to next task", or any approval-style questions between plan steps.** + +**You MUST auto-continue immediately after verification passes:** +- After any delegation completes and passes verification → Immediately delegate next task +- Do NOT wait for user input, do NOT ask "should I continue" +- Only pause or ask if you are truly blocked by missing information, an external dependency, or a critical failure + +**The only time you ask the user:** +- Plan needs clarification or modification before execution +- Blocked by an external dependency beyond your control +- Critical failure prevents any further progress + +**Auto-continue examples:** +- Task A done → Verify → Pass → Immediately start Task B +- Task fails → Retry 3x → Still fails → Document → Move to next independent task +- NEVER: "Should I continue to the next task?" + +**This is NOT optional. This is core to your role as orchestrator.** + + ## Step 0: Register Tracking @@ -214,7 +237,7 @@ After EVERY delegation, complete ALL of these steps — no shortcuts: After verification, READ the plan file directly — every time, no exceptions: \`\`\` -Read(".sisyphus/tasks/{plan-name}.yaml") +Read(".sisyphus/plans/{plan-name}.md") \`\`\` Count remaining \`- [ ]\` tasks. This is your ground truth for what comes next. diff --git a/src/agents/atlas/gemini.ts b/src/agents/atlas/gemini.ts index 0337d2d021..d249c34ca5 100644 --- a/src/agents/atlas/gemini.ts +++ b/src/agents/atlas/gemini.ts @@ -116,6 +116,29 @@ Every \`task()\` prompt MUST include ALL 6 sections: **Minimum 30 lines per delegation prompt. Under 30 lines = the subagent WILL fail.** + +## AUTO-CONTINUE POLICY (STRICT) + +**CRITICAL: NEVER ask the user "should I continue", "proceed to next task", or any approval-style questions between plan steps.** + +**You MUST auto-continue immediately after verification passes:** +- After any delegation completes and passes verification → Immediately delegate next task +- Do NOT wait for user input, do NOT ask "should I continue" +- Only pause or ask if you are truly blocked by missing information, an external dependency, or a critical failure + +**The only time you ask the user:** +- Plan needs clarification or modification before execution +- Blocked by an external dependency beyond your control +- Critical failure prevents any further progress + +**Auto-continue examples:** +- Task A done → Verify → Pass → Immediately start Task B +- Task fails → Retry 3x → Still fails → Document → Move to next independent task +- NEVER: "Should I continue to the next task?" + +**This is NOT optional. This is core to your role as orchestrator.** + + ## Step 0: Register Tracking diff --git a/src/agents/atlas/gpt.ts b/src/agents/atlas/gpt.ts index 90d922d252..9d868c526e 100644 --- a/src/agents/atlas/gpt.ts +++ b/src/agents/atlas/gpt.ts @@ -48,9 +48,10 @@ Complete ALL tasks in a work plan via \`task()\` until fully done. -- If a task is ambiguous or underspecified: +- During initial plan analysis, if a task is ambiguous or underspecified: - Ask 1-3 precise clarifying questions, OR - State your interpretation explicitly and proceed with the simplest approach. +- Once execution has started, do NOT stop to ask for continuation or approval between steps. - Never fabricate task details, file paths, or requirements. - Prefer language like "Based on the plan..." instead of absolute claims. - When unsure about parallelization, default to sequential execution. @@ -134,6 +135,29 @@ Every \`task()\` prompt MUST include ALL 6 sections: **Minimum 30 lines per delegation prompt.** + +## AUTO-CONTINUE POLICY (STRICT) + +**CRITICAL: NEVER ask the user "should I continue", "proceed to next task", or any approval-style questions between plan steps.** + +**You MUST auto-continue immediately after verification passes:** +- After any delegation completes and passes verification → Immediately delegate next task +- Do NOT wait for user input, do NOT ask "should I continue" +- Only pause or ask if you are truly blocked by missing information, an external dependency, or a critical failure + +**The only time you ask the user:** +- Plan needs clarification or modification before execution +- Blocked by an external dependency beyond your control +- Critical failure prevents any further progress + +**Auto-continue examples:** +- Task A done → Verify → Pass → Immediately start Task B +- Task fails → Retry 3x → Still fails → Document → Move to next independent task +- NEVER: "Should I continue to the next task?" + +**This is NOT optional. This is core to your role as orchestrator.** + + ## Step 0: Register Tracking diff --git a/src/agents/delegation-trust-prompt.test.ts b/src/agents/delegation-trust-prompt.test.ts new file mode 100644 index 0000000000..8d91f7a529 --- /dev/null +++ b/src/agents/delegation-trust-prompt.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, test } from "bun:test" +import { createSisyphusAgent } from "./sisyphus" +import { createHephaestusAgent } from "./hephaestus" +import { buildSisyphusJuniorPrompt } from "./sisyphus-junior/agent" +import { + buildAntiDuplicationSection, + buildExploreSection, + type AvailableAgent, +} from "./dynamic-agent-prompt-builder" + +const exploreAgent = { + name: "explore", + description: "Contextual grep specialist", + metadata: { + category: "advisor", + cost: "FREE", + promptAlias: "Explore", + triggers: [], + useWhen: ["Multiple search angles needed"], + avoidWhen: ["Single keyword search is enough"], + }, +} satisfies AvailableAgent + +describe("delegation trust prompt rules", () => { + test("buildAntiDuplicationSection explains overlap is forbidden", () => { + // given + const section = buildAntiDuplicationSection() + + // when / then + expect(section).toContain("DO NOT perform the same search yourself") + expect(section).toContain("non-overlapping work") + expect(section).toContain("End your response") + }) + + test("buildExploreSection includes delegation trust rule", () => { + // given + const agents = [exploreAgent] + + // when + const section = buildExploreSection(agents) + + // then + expect(section).toContain("Delegation Trust Rule") + expect(section).toContain("do **not** manually perform that same search yourself") + }) + + test("Sisyphus prompt forbids duplicate delegated exploration", () => { + // given + const agent = createSisyphusAgent("anthropic/claude-sonnet-4-6", [exploreAgent]) + + // when + const prompt = agent.prompt + + // then + expect(prompt).toContain("Continue only with non-overlapping work") + expect(prompt).toContain("DO NOT perform the same search yourself") + }) + + test("Hephaestus prompt forbids duplicate delegated exploration", () => { + // given + const agent = createHephaestusAgent("openai/gpt-5.2", [exploreAgent]) + + // when + const prompt = agent.prompt + + // then + expect(prompt).toContain("Continue only with non-overlapping work after launching background agents") + expect(prompt).toContain("DO NOT perform the same search yourself") + }) + + test("Sisyphus-Junior GPT prompt forbids duplicate delegated exploration", () => { + // given + const prompt = buildSisyphusJuniorPrompt("openai/gpt-5.2", false) + + // when / then + expect(prompt).toContain("continue only with non-overlapping work while they search") + expect(prompt).toContain("DO NOT perform the same search yourself") + }) + + test("Sisyphus-Junior Gemini prompt forbids duplicate delegated exploration", () => { + // given + const prompt = buildSisyphusJuniorPrompt("google/gemini-3.1-pro", false) + + // when / then + expect(prompt).toContain("continue only with non-overlapping work while they search") + expect(prompt).toContain("DO NOT perform the same search yourself") + }) +}) diff --git a/src/agents/dynamic-agent-prompt-builder.ts b/src/agents/dynamic-agent-prompt-builder.ts index f6e8cbc656..436f2679ae 100644 --- a/src/agents/dynamic-agent-prompt-builder.ts +++ b/src/agents/dynamic-agent-prompt-builder.ts @@ -118,6 +118,8 @@ export function buildExploreSection(agents: AvailableAgent[]): string { Use it as a **peer tool**, not a fallback. Fire liberally. +**Delegation Trust Rule:** Once you fire an explore agent for a search, do **not** manually perform that same search yourself. Use direct tools only for non-overlapping work or when you intentionally skipped delegation. + **Use Direct Tools when:** ${avoidWhen.map((w) => `- ${w}`).join("\n")} @@ -308,6 +310,7 @@ export function buildAntiPatternsSection(): string { "- **Search**: Firing agents for single-line typos or obvious syntax errors", "- **Debugging**: Shotgun debugging, random changes", "- **Background Tasks**: Polling `background_output` on running tasks — end response and wait for notification", + "- **Delegation Duplication**: Delegating exploration to explore/librarian and then manually doing the same search yourself", "- **Oracle**: Delivering answer without collecting Oracle results", ] @@ -409,3 +412,52 @@ export function buildUltraworkSection( return lines.join("\n") } + +// Anti-duplication section for agent prompts +export function buildAntiDuplicationSection(): string { + return ` +## Anti-Duplication Rule (CRITICAL) + +Once you delegate exploration to explore/librarian agents, **DO NOT perform the same search yourself**. + +### What this means: + +**FORBIDDEN:** +- After firing explore/librarian, manually grep/search for the same information +- Re-doing the research the agents were just tasked with +- "Just quickly checking" the same files the background agents are checking + +**ALLOWED:** +- Continue with **non-overlapping work** — work that doesn't depend on the delegated research +- Work on unrelated parts of the codebase +- Preparation work (e.g., setting up files, configs) that can proceed independently + +### Wait for Results Properly: + +When you need the delegated results but they're not ready: + +1. **End your response** — do NOT continue with work that depends on those results +2. **Wait for the completion notification** — the system will trigger your next turn +3. **Then** collect results via \`background_output(task_id="...")\` +4. **Do NOT** impatiently re-search the same topics while waiting + +### Why This Matters: + +- **Wasted tokens**: Duplicate exploration wastes your context budget +- **Confusion**: You might contradict the agent's findings +- **Efficiency**: The whole point of delegation is parallel throughput + +### Example: + +\`\`\`typescript +// WRONG: After delegating, re-doing the search +task(subagent_type="explore", run_in_background=true, ...) +// Then immediately grep for the same thing yourself — FORBIDDEN + +// CORRECT: Continue non-overlapping work +task(subagent_type="explore", run_in_background=true, ...) +// Work on a different, unrelated file while they search +// End your response and wait for the notification +\`\`\` +` +} diff --git a/src/agents/hephaestus.ts b/src/agents/hephaestus.ts index 8a510ecda2..af13f8fdb5 100644 --- a/src/agents/hephaestus.ts +++ b/src/agents/hephaestus.ts @@ -16,6 +16,7 @@ import { buildOracleSection, buildHardBlocksSection, buildAntiPatternsSection, + buildAntiDuplicationSection, categorizeTools, } from "./dynamic-agent-prompt-builder"; @@ -290,11 +291,13 @@ Prompt structure for each agent: - Fire 2-5 explore agents in parallel for any non-trivial codebase question - Parallelize independent file reads — don't read files one at a time - NEVER use \`run_in_background=false\` for explore/librarian -- Continue your work immediately after launching background agents +- Continue only with non-overlapping work after launching background agents - Collect results with \`background_output(task_id="...")\` when needed - BEFORE final answer, cancel DISPOSABLE tasks individually: \`background_cancel(taskId="bg_explore_xxx")\`, \`background_cancel(taskId="bg_librarian_xxx")\` - **NEVER use \`background_cancel(all=true)\`** — it kills tasks whose results you haven't collected yet +${buildAntiDuplicationSection()} + ### Search Stop Conditions STOP searching when: diff --git a/src/agents/sisyphus-junior/gemini.ts b/src/agents/sisyphus-junior/gemini.ts index e6c727b53e..b4b10980b2 100644 --- a/src/agents/sisyphus-junior/gemini.ts +++ b/src/agents/sisyphus-junior/gemini.ts @@ -9,6 +9,7 @@ */ import { resolvePromptAppend } from "../builtin-agents/resolve-file-uri" +import { buildAntiDuplicationSection } from "../dynamic-agent-prompt-builder" export function buildGeminiSisyphusJuniorPrompt( useTaskSystem: boolean, @@ -58,7 +59,7 @@ Before responding, ask yourself: What tools do I need to call? What am I assumin - Run verification (lint, tests, build) WITHOUT asking - Make decisions. Course-correct only on CONCRETE failure - Note assumptions in final message, not as questions mid-work -- Need context? Fire explore/librarian via call_omo_agent IMMEDIATELY — keep working while they search +- Need context? Fire explore/librarian via call_omo_agent IMMEDIATELY — continue only with non-overlapping work while they search ## Scope Discipline @@ -77,13 +78,15 @@ Before responding, ask yourself: What tools do I need to call? What am I assumin - Parallelize independent tool calls: multiple file reads, grep searches, agent fires — all at once -- Explore/Librarian via call_omo_agent = background research. Fire them and keep working +- Explore/Librarian via call_omo_agent = background research. Fire them and continue only with non-overlapping work - After any file edit: restate what changed, where, and what validation follows - Prefer tools over guessing whenever you need specific data (files, configs, patterns) - ALWAYS use tools over internal knowledge for file contents, project state, and verification - **DO NOT SKIP tool calls because you think you already know the answer. You DON'T.** +${buildAntiDuplicationSection()} + ${taskDiscipline} ## Progress Updates diff --git a/src/agents/sisyphus-junior/gpt.ts b/src/agents/sisyphus-junior/gpt.ts index e04734aea1..8626c5f52f 100644 --- a/src/agents/sisyphus-junior/gpt.ts +++ b/src/agents/sisyphus-junior/gpt.ts @@ -7,6 +7,7 @@ */ import { resolvePromptAppend } from "../builtin-agents/resolve-file-uri" +import { buildAntiDuplicationSection } from "../dynamic-agent-prompt-builder" export function buildGptSisyphusJuniorPrompt( useTaskSystem: boolean, @@ -40,7 +41,7 @@ When blocked: try a different approach → decompose the problem → challenge a - Run verification (lint, tests, build) WITHOUT asking - Make decisions. Course-correct only on CONCRETE failure - Note assumptions in final message, not as questions mid-work -- Need context? Fire explore/librarian via call_omo_agent IMMEDIATELY — keep working while they search +- Need context? Fire explore/librarian via call_omo_agent IMMEDIATELY — continue only with non-overlapping work while they search ## Scope Discipline @@ -58,12 +59,14 @@ When blocked: try a different approach → decompose the problem → challenge a - Parallelize independent tool calls: multiple file reads, grep searches, agent fires — all at once -- Explore/Librarian via call_omo_agent = background research. Fire them and keep working +- Explore/Librarian via call_omo_agent = background research. Fire them and continue only with non-overlapping work - After any file edit: restate what changed, where, and what validation follows - Prefer tools over guessing whenever you need specific data (files, configs, patterns) - ALWAYS use tools over internal knowledge for file contents, project state, and verification +${buildAntiDuplicationSection()} + ${taskDiscipline} ## Progress Updates diff --git a/src/agents/sisyphus.ts b/src/agents/sisyphus.ts index 042cec1a1a..1db759aa6b 100644 --- a/src/agents/sisyphus.ts +++ b/src/agents/sisyphus.ts @@ -35,6 +35,7 @@ import { buildAntiPatternsSection, buildDeepParallelSection, buildNonClaudePlannerSection, + buildAntiDuplicationSection, categorizeTools, } from "./dynamic-agent-prompt-builder"; @@ -333,7 +334,7 @@ task(subagent_type="explore", run_in_background=true, load_skills=[], descriptio // Reference Grep (external) task(subagent_type="librarian", run_in_background=true, load_skills=[], description="Find JWT security docs", prompt="I'm implementing JWT auth and need current security best practices to choose token storage (httpOnly cookies vs localStorage) and set expiration policy. Find: OWASP auth guidelines, recommended token lifetimes, refresh token rotation strategies, common JWT vulnerabilities. Skip 'what is JWT' tutorials — production security guidance only.") task(subagent_type="librarian", run_in_background=true, load_skills=[], description="Find Express auth patterns", prompt="I'm building Express auth middleware and need production-quality patterns to structure my middleware chain. Find how established Express apps (1000+ stars) handle: middleware ordering, token refresh, role-based access control, auth error propagation. Skip basic tutorials — I need battle-tested patterns with proper error handling.") -// Continue working immediately. System notifies on completion — collect with background_output then. +// Continue only with non-overlapping work. System notifies on completion — collect with background_output then. // WRONG: Sequential or blocking result = task(..., run_in_background=false) // Never wait synchronously for explore/librarian @@ -341,11 +342,13 @@ result = task(..., run_in_background=false) // Never wait synchronously for exp ### Background Result Collection: 1. Launch parallel agents \u2192 receive task_ids -2. Continue immediate work +2. Continue only with non-overlapping work 3. System sends \`\` on each task completion — then call \`background_output(task_id="...")\` 4. Need results not yet ready? **End your response.** The notification will trigger your next turn. 5. Cleanup: Cancel disposable tasks individually via \`background_cancel(taskId="...")\` +${buildAntiDuplicationSection()} + ### Search Stop Conditions STOP searching when: diff --git a/src/tools/background-task/create-background-output.ts b/src/tools/background-task/create-background-output.ts index e12cfa9aaf..a3e4931ed0 100644 --- a/src/tools/background-task/create-background-output.ts +++ b/src/tools/background-task/create-background-output.ts @@ -87,7 +87,6 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: const shouldBlock = args.block === true const timeoutMs = Math.min(args.timeout ?? 60000, 600000) - const fullSession = args.full_session ?? true let resolvedTask = task @@ -123,6 +122,10 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: } const isActive = isTaskActiveStatus(resolvedTask.status) + const fullSessionProvided = args.full_session !== undefined + const fullSession = fullSessionProvided + ? (args.full_session ?? true) + : !isActive const includeThinking = isActive || (args.include_thinking ?? false) const includeToolResults = isActive || (args.include_tool_results ?? false)