fix(responses): preserve whitespace in tool-call arguments (#244) - #245
Merged
Merged
Conversation
response.function_call_arguments.delta fragments went through the trimming firstString() helper — the same per-chunk-.trim() bug class as #192, but on a path the #192 fix deliberately left alone. Responses API argument fragments are arbitrary JSON slices that can split inside string values, so per-fragment trimming corrupted tool-call input on every GPT-family model (all route to /v1/responses) on both Go and Zen, sending the model into reasoning loops. Three-layer fix: - root cause: fragments now go through firstStringRaw() - new response.function_call_arguments.done handler emits the final authoritative arguments tagged argumentsDone: true - ToolCallAccumulator treats argumentsDone as REPLACE instead of append, healing any gateway-side delta mis-join Verified against openai-node's own accumulator (raw += event.delta) and the official done-event semantics. 5 regression tests; 489/489 pass. Docs: docs/issues/107, doc 83 annotated (superseded assumption), CHANGELOG 0.7.7, devlog, ARCHITECTURE-MAP. Version bump 0.7.7. closes #244
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #244
Problem
All whitespace is stripped from tool calls and responses on OpenAI models (both OpenCode Go and Zen) — every word concatenated (
thisiswhattheresponselookslike), and corrupted tool-call arguments send the model into reasoning loops. Text-only conversations are also affected because agent-mode output flows through tool calls.Root cause
Regression class of #192 (fixed in PR #194). That fix moved text/reasoning deltas to
firstStringRaw()but deliberately leftarguments_deltaon the trimmingfirstString()under the assumption that arguments tolerate whitespace stripping.That assumption was wrong. Responses API argument fragments are arbitrary JSON slices that can split inside string values (
"hello wo+rld"), so per-fragment.trim()destroyed boundary whitespace and corrupted tool-call input on every GPT-family model (all route to/v1/responses).Verified against official sources:
response-accumulator.tsaccumulates via rawoutput.arguments += event.delta— no trim, no falsy filteringresponse.function_call_arguments.donecarries the final authoritative arguments stringReporter diagnostics confirmed every affected request hit the
responsesendpoint (HTTP 200, silent corruption) with the repeat-request/cache-hit pattern of an agent retrying mangled tool calls.Fix (3 layers)
src/core/routing.tsfunction_call_arguments.delta→firstStringRaw()(no trim)src/core/routing.tsfunction_call_arguments.donehandler → emits final arguments taggedargumentsDone: truesrc/toolCallAccumulator.tsargumentsDonedelta REPLACES pending arguments instead of appending — heals any gateway-side delta mis-joinTests
5 new regression tests: fragment split mid-string-value, done-event mapping, done-without-args, replace semantics, append-only path unaffected. 489/489 pass,
npm run compile+ typecheck clean.Docs
docs/issues/107-20260924-issue244-tool-call-arguments-whitespace.md(new)docs/issues/83annotated — superseded assumption noted[0.7.7], devlog, ARCHITECTURE-MAPNotes for merge
Per repo policy: merge commit (
gh pr merge --merge), no squash.