Skip to content

Commit 7ec0b4b

Browse files
committed
fix(agents): preserve persisted turn after truncation retry
1 parent 90749d7 commit 7ec0b4b

2 files changed

Lines changed: 49 additions & 0 deletions

File tree

src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,45 @@ describe("overflow compaction in run loop", () => {
305305
expect(result.meta.error).toBeUndefined();
306306
});
307307

308+
it("continues from transcript after pre-compaction truncation when the current inbound message was persisted", async () => {
309+
const overflowError = makeOverflowError();
310+
311+
mockedRunEmbeddedAttempt
312+
.mockImplementationOnce(async (attemptParams) => {
313+
(
314+
attemptParams as {
315+
onUserMessagePersisted?: (message: { role: "user"; content: string }) => void;
316+
}
317+
).onUserMessagePersisted?.({ role: "user", content: baseParams.prompt });
318+
return makeAttemptResult({
319+
promptError: overflowError,
320+
messagesSnapshot: [
321+
{
322+
role: "toolResult",
323+
content: [{ type: "text", text: "x".repeat(80_000) }],
324+
} as unknown as EmbeddedRunAttemptResult["messagesSnapshot"][number],
325+
],
326+
});
327+
})
328+
.mockResolvedValueOnce(makeAttemptResult({ promptError: null }));
329+
330+
mockedSessionLikelyHasOversizedToolResults.mockReturnValue(true);
331+
mockedTruncateOversizedToolResultsInSession.mockResolvedValueOnce({
332+
truncated: true,
333+
truncatedCount: 1,
334+
});
335+
336+
const result = await runEmbeddedPiAgent({
337+
...baseParams,
338+
currentMessageId: "telegram-msg-51026",
339+
});
340+
341+
expect(mockedCompactDirect).not.toHaveBeenCalled();
342+
expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(2);
343+
expectRetryContinuesFromTranscript();
344+
expect(result.meta.error).toBeUndefined();
345+
});
346+
308347
it("retries compaction when pre-compaction tool-result truncation does not help", async () => {
309348
queueOverflowAttemptWithOversizedToolOutput(mockedRunEmbeddedAttempt, makeOverflowError());
310349
mockedRunEmbeddedAttempt.mockResolvedValueOnce(makeAttemptResult({ promptError: null }));

src/agents/pi-embedded-runner/run.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,6 +1769,16 @@ export async function runEmbeddedPiAgent(
17691769
log.info(
17701770
`[context-overflow-recovery] Truncated ${truncResult.truncatedCount} tool result(s); retrying prompt`,
17711771
);
1772+
if (
1773+
params.currentMessageId !== undefined &&
1774+
params.currentMessageId === lastPersistedCurrentMessageId
1775+
) {
1776+
// The failed attempt reached Pi far enough to persist this user turn.
1777+
// Retrying the original prompt would replay it, so resume from the
1778+
// truncated transcript and suppress the next user append.
1779+
nextAttemptPromptOverride = MID_TURN_PRECHECK_CONTINUATION_PROMPT;
1780+
suppressNextUserMessagePersistence = true;
1781+
}
17721782
continue;
17731783
}
17741784
log.warn(

0 commit comments

Comments
 (0)