fix: repair tool_use/tool_result pairings after history truncation (fixes #4367)

The message processing pipeline had a synchronization bug where
limitHistoryTurns() truncated conversation history AFTER
repairToolUseResultPairing() had already fixed tool_use/tool_result
pairings. This could split assistant messages (with tool_use) from
their corresponding tool_result blocks, creating orphaned tool_result
blocks that the Anthropic API rejects.

This fix calls sanitizeToolUseResultPairing() AFTER limitHistoryTurns()
to repair any pairings broken by truncation, ensuring the transcript
remains valid before being sent to the LLM API.

Changes:
- Added import for sanitizeToolUseResultPairing from session-transcript-repair.js
- Call sanitizeToolUseResultPairing() on the limited message array
- Updated variable name from 'limited' to 'repaired' for clarity
This commit is contained in:
spiceoogway 2026-01-30 00:10:57 -05:00
parent 87267fad4f
commit 832420148c

View File

@ -52,6 +52,7 @@ import {
import { DEFAULT_BOOTSTRAP_FILENAME } from "../../workspace.js";
import { buildSystemPromptReport } from "../../system-prompt-report.js";
import { resolveDefaultModelForAgent } from "../../model-selection.js";
import { sanitizeToolUseResultPairing } from "../../session-transcript-repair.js";
import { isAbortError } from "../abort.js";
import { buildEmbeddedExtensionPaths } from "../extensions.js";
@ -535,9 +536,11 @@ export async function runEmbeddedAttempt(
validated,
getDmHistoryLimitFromSessionKey(params.sessionKey, params.config),
);
cacheTrace?.recordStage("session:limited", { messages: limited });
if (limited.length > 0) {
activeSession.agent.replaceMessages(limited);
// Fix: Repair tool_use/tool_result pairings AFTER truncation (issue #4367)
const repaired = sanitizeToolUseResultPairing(limited);
cacheTrace?.recordStage("session:limited", { messages: repaired });
if (repaired.length > 0) {
activeSession.agent.replaceMessages(repaired);
}
} catch (err) {
sessionManager.flushPendingToolResults?.();