From e27a2c226c8d5e3df17bdee9e358e2cf4a5409c3 Mon Sep 17 00:00:00 2001 From: Helmut Januschka Date: Sat, 3 Jan 2026 16:28:53 +0100 Subject: [PATCH] fix(plan-mode): buffer text_delta to handle split [DONE:id] patterns The [DONE:id] pattern may be split across multiple streaming chunks. Now accumulates text in a buffer and scans for complete patterns. --- .../coding-agent/examples/hooks/plan-mode.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/coding-agent/examples/hooks/plan-mode.ts b/packages/coding-agent/examples/hooks/plan-mode.ts index ee9c2a46..c817db63 100644 --- a/packages/coding-agent/examples/hooks/plan-mode.ts +++ b/packages/coding-agent/examples/hooks/plan-mode.ts @@ -291,11 +291,18 @@ export default function planModeHook(pi: HookAPI) { } }); + // Buffer for accumulating text to handle [DONE:id] split across chunks + let textBuffer = ""; + // Watch for [DONE:id] tags in streaming text pi.on("text_delta", async (event, ctx) => { if (!executionMode || todoItems.length === 0) return; - const doneIds = findDoneTags(event.text); + // Accumulate text in buffer + textBuffer += event.text; + + // Look for complete [DONE:id] patterns + const doneIds = findDoneTags(textBuffer); if (doneIds.length === 0) return; let changed = false; @@ -307,6 +314,11 @@ export default function planModeHook(pi: HookAPI) { } } + // Clear processed patterns from buffer (keep last 20 chars for partial matches) + if (textBuffer.length > 50) { + textBuffer = textBuffer.slice(-20); + } + if (changed) { updateStatus(ctx); } @@ -360,6 +372,9 @@ IMPORTANT: After completing each step, output [DONE:id] where id is the step's I // After agent finishes in plan mode pi.on("agent_end", async (event, ctx) => { + // Clear text buffer + textBuffer = ""; + // Check for done tags in the final message too if (executionMode && todoItems.length > 0) { const messages = event.messages;