You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fitHistoryCompactMessages (packages/runtime/src/history-compact-input-fit.ts) bounds a compaction request by replacing old, oversized tool-result payloads with a placeholder, keeping every call/result pair intact.
When a single tool message carries more than one tool-result part — which happens whenever the model issues parallel tool calls, so the provider batches their results into one message — only the last replaced part survives. Each replacement copies from the original message.content:
constcontent=[...message.content];// line 65 — always the ORIGINAL partscontent[partIndex]=replacement;bounded[messageIndex]={ ...message, content };
so an earlier part's placeholder is overwritten and its payload stays at full size in the returned history — even though the budget accounting (estimatedChars) has already been decremented for it.
Result: the function can return a history that still far exceeds maxInputEstimatedTokens while treating it as "fit", so the downstream compaction / recap model call is sent over its intended input budget (risking a provider context-window error). With other sizes the same accounting mismatch instead throws input_too_large for input that would actually fit. Either way the helper fails at exactly the case it exists to handle.
The sibling active-tool-result-prune.ts handles the same multi-part shape correctly by accumulating replacements (nextContent = originalContent.slice(0, index) then push), so multi-result tool messages are a known, supported shape.
How to reproduce
Build first (npm run build), then run this against the compiled function on main:
returned "fit" chars: 16974 (budget 1000)
full payloads left : 1 (expected 0)
Expected: both payloads replaced, result within the requested budget.
Environment
Maka commit: origin/main920d7142d
OS and version: macOS 15 (arm64)
Surface: Runtime
Node.js: 24
Logs, screenshots, or additional context
Buggy line: packages/runtime/src/history-compact-input-fit.ts:65 copies from the original message.content on every replacement instead of carrying earlier replacements forward.
What happened
fitHistoryCompactMessages(packages/runtime/src/history-compact-input-fit.ts) bounds a compaction request by replacing old, oversizedtool-resultpayloads with a placeholder, keeping every call/result pair intact.When a single
toolmessage carries more than onetool-resultpart — which happens whenever the model issues parallel tool calls, so the provider batches their results into one message — only the last replaced part survives. Each replacement copies from the originalmessage.content:so an earlier part's placeholder is overwritten and its payload stays at full size in the returned history — even though the budget accounting (
estimatedChars) has already been decremented for it.Result: the function can return a history that still far exceeds
maxInputEstimatedTokenswhile treating it as "fit", so the downstream compaction / recap model call is sent over its intended input budget (risking a provider context-window error). With other sizes the same accounting mismatch instead throwsinput_too_largefor input that would actually fit. Either way the helper fails at exactly the case it exists to handle.The sibling
active-tool-result-prune.tshandles the same multi-part shape correctly by accumulating replacements (nextContent = originalContent.slice(0, index)then push), so multi-result tool messages are a known, supported shape.How to reproduce
Build first (
npm run build), then run this against the compiled function onmain:Observed on
main:Expected: both payloads replaced, result within the requested budget.
Environment
origin/main920d7142dLogs, screenshots, or additional context
packages/runtime/src/history-compact-input-fit.ts:65copies from the originalmessage.contenton every replacement instead of carrying earlier replacements forward.history-compact-summarizer.ts,session-recap.ts,openai-codex-history-compactor.ts.