fix(claude): strip empty Read pages tool input - #2937
Conversation
Buffer Claude Code Read tool calls through the existing shim layer so empty pages placeholders are removed before streaming input_json_delta to the client. Also clean JSON-string Responses tool arguments, not only object arguments. Closes diegosouzapw#2935 Addresses diegosouzapw#2889
There was a problem hiding this comment.
Code Review
This pull request introduces a Read tool shim to filter out empty pages arguments from non-Anthropic models and refactors the argument cleaning logic in openai-responses.ts into a reusable stripEmptyOptionalToolArgs helper, supported by new unit tests. Feedback on these changes highlights a potential bug in stripEmptyOptionalToolArgs where using the logical OR operator (||) for a fallback value could inadvertently replace valid falsy JSON values (such as false or 0) with {}. It is recommended to use the nullish coalescing operator (??) instead to preserve these values.
| if (typeof value === "string") { | ||
| try { | ||
| const parsed = JSON.parse(value); | ||
| const cleaned = stripEmptyOptionalToolArgs(parsed); | ||
| return JSON.stringify(cleaned || {}); | ||
| } catch { | ||
| return value; | ||
| } | ||
| } |
There was a problem hiding this comment.
Using the logical OR operator (||) to provide a fallback value of {} will cause any valid falsy JSON values (such as false, 0, or "") to be incorrectly replaced with {}. For example, if a tool argument is a stringified boolean "false", it will be parsed as false, cleaned as false, and then false || {} will evaluate to {}, resulting in "{}" being returned instead of "false".
Using the nullish coalescing operator (??) instead ensures that only null or undefined values are coalesced to {}, preserving other valid falsy values.
| if (typeof value === "string") { | |
| try { | |
| const parsed = JSON.parse(value); | |
| const cleaned = stripEmptyOptionalToolArgs(parsed); | |
| return JSON.stringify(cleaned || {}); | |
| } catch { | |
| return value; | |
| } | |
| } | |
| if (typeof value === "string") { | |
| try { | |
| const parsed = JSON.parse(value); | |
| const cleaned = stripEmptyOptionalToolArgs(parsed); | |
| return JSON.stringify(cleaned ?? {}); | |
| } catch { | |
| return value; | |
| } | |
| } |
Keep existing object-argument cleanup behavior, but avoid parsing and stripping arbitrary JSON-string arguments for unrelated tools where empty strings or arrays may be valid payloads. Add regression coverage for non-Read and non-object Read arguments.
|
Follow-up after the bot review: addressed in later commits.
Local verification after the follow-up changes: |
|
Thank you for your contribution! This PR has been reviewed and integrated into the upcoming |
Integrated into release/v3.8.8
Integrated into release/v3.8.8
Integrated into release/v3.8.8
Summary
Readtool-call shim that removes invalid emptypagesplaceholders before streaming tool input back to Claude Code.item.arguments, not only object arguments.input_json_deltabehavior, and JSON-string Responses arguments.Closes #2935
Addresses #2889
Test Plan
npm exec -- cross-env DISABLE_SQLITE_AUTO_BACKUP=true node --max-old-space-size=4096 --import tsx --import ./open-sse/utils/setupPolyfill.ts --test --test-force-exit tests/unit/translator-tool-call-shim.test.ts tests/unit/translator-resp-openai-responses.test.tsResult: 32 passing, 0 failing.