From f541a48c513ff7b8d5bf833f17d6ca571615df7d Mon Sep 17 00:00:00 2001 From: Mitch Fultz <57411549+fitchmultz@users.noreply.github.com> Date: Thu, 24 Sep 2026 07:34:20 -0600 Subject: [PATCH] fix: honor projected omissions in owner answer recovery --- index.ts | 2 ++ test/native.test.mjs | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/index.ts b/index.ts index eb5c289..1333e47 100644 --- a/index.ts +++ b/index.ts @@ -600,7 +600,9 @@ function buildAutoHandoff(entries: readonly EntryLike[], projected: readonly Pro for (const entry of current) { if (entry.type === "context_edit" && entry.targetId) edits.set(entry.targetId, entry); } + const omittedProjectedIds = new Set(projected.filter(({ messages }) => !messages.length).map(({ sourceEntry }) => sourceEntry.id)); const edited = current.flatMap((entry) => { + if (entry.id && omittedProjectedIds.has(entry.id)) return []; const edit = entry.id ? edits.get(entry.id) : undefined; if (edit?.replacement === null) return []; if (!edit?.replacement) return [entry]; diff --git a/test/native.test.mjs b/test/native.test.mjs index 18ca2f7..f23834c 100644 --- a/test/native.test.mjs +++ b/test/native.test.mjs @@ -336,13 +336,13 @@ test("interleaved async receipts retain projected provenance across complete res assert.ok(handoff.indexOf("EDITED_FIRST_RECEIPT") < handoff.indexOf("SECOND_ASYNC_RECEIPT")); }); -test("recovery excludes results dependent on an omitted async call", async (t) => { +for (const toolName of ["work", "ask_question"]) test(`recovery excludes ${toolName} results dependent on an omitted async call`, async (t) => { const h = await fixture(t, { seed(manager) { - const call = { ...fauxToolCall("work", {}), async: true, executionStarted: true }; + const call = { ...fauxToolCall(toolName, {}), async: true, executionStarted: true }; const callId = manager.appendMessage(fauxAssistantMessage(call, { stopReason: "toolUse" })); const laterId = manager.appendMessage(fauxAssistantMessage("Unrelated complete response")); manager.appendMessage({ - role: "toolResult", toolName: "work", toolCallId: call.id, + role: "toolResult", toolName, toolCallId: call.id, content: [{ type: "text", text: "PRIVATE_ASYNC_RESULT" }], isError: false, timestamp: Date.now(), }); manager.appendCompaction("Previous context", laterId, 100);