Fix: prevent Invalid diff now finding less tool calls error#35379
Fix: prevent Invalid diff now finding less tool calls error#35379Octane0411 wants to merge 1 commit intoopenclaw:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1c49545385
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const codePoint = Number.parseInt(entity.slice(2, -1), 10); | ||
| return Number.isNaN(codePoint) ? entity : String.fromCodePoint(codePoint); |
There was a problem hiding this comment.
Validate codepoint range before decoding numeric HTML entities
decodeHtmlEntities decodes any numeric entity with String.fromCodePoint, but entities like � or � match this branch and throw RangeError because the value is outside Unicode’s valid range. Since xAI runs enable this decoding path (wrapStreamFnTrimToolCallNames(..., isXaiProvider(...))), a single malformed entity in tool arguments can crash stream processing instead of being treated as plain text. Add an upper/lower bound check (and/or safe fallback) before calling String.fromCodePoint.
Useful? React with 👍 / 👎.
| const missingCalls = previousToolCalls.slice(currentToolCalls.length).map((block) => cloneUnknown(block)); | ||
| if (missingCalls.length > 0) { | ||
| currentContent.push(...missingCalls); |
There was a problem hiding this comment.
Reconstruct dropped tool calls by ID instead of positional slice
The monotonic repair logic assumes only trailing tool calls are missing (previousToolCalls.slice(currentToolCalls.length)), which is incorrect when an earlier call drops while a later one remains. For example, transitioning from [callA, callB] to [callB] appends another clone of callB, yielding duplicated tool calls/IDs in the live partial message; this wrapper runs on the execution stream, so duplicated calls can lead to duplicate tool execution or mismatched tool_result pairing. Compare by call ID/content and append only genuinely missing calls.
Useful? React with 👍 / 👎.
Greptile SummaryThis PR addresses the "Invalid diff: now finding less tool calls!" streaming error by introducing The core fix is directionally sound for handling the specific issue where streaming partials regress to fewer tool calls. The implementation extracts tool blocks from both current and previous partials, identifies the difference, and appends missing blocks back to maintain monotonicity in the tool call count during streaming. Confidence Score: 4/5
Last reviewed commit: 1c49545 |
Summary
Describe the problem and fix in 2–5 bullets:
partialpayloads can temporarily regress (fewertoolCallblocks than a prior chunk), which triggers downstream stream-diff validation errors likeInvalid diff: now finding less tool calls!.src/agents/pi-embedded-runner/run/attempt.ts,wrapStreamFnTrimToolCallNamesnow tracks the previous partial snapshot and enforces monotonic tool-call count viapreserveMonotonicToolCallsInPartialMessage(...); helper cloning was added to avoid reference pitfalls during patching.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
partialsnapshot with fewer tool calls than the previous snapshot; tool-call streaming remains stable.Security Impact (required)
Repro + Verification
Environment
Steps
wrapStreamFnTrimToolCallNames.Expected
Actual
Evidence
Human Verification (required)
oxfmt) on touched files.Compatibility / Migration
AI Assisted
Codex