Repository navigation
fix: prevent empty tool-call deltas from fragmenting OpenAI-compatible reasoning streams - #20253
Conversation
Co-authored-by: Gregor Martynus <[email protected]>
Co-authored-by: WuJunkai2004 <[email protected]>
Co-authored-by: WuJunkai2004 <[email protected]>
Bugfix reviewOutcome: approved Reproduction replayStatus: no-longer-reproduces The exact original reproduction completed successfully and the original bug signal did not appear. Fixes issueStatus: fully-addresses The implementation ignores empty tool-call arrays for reasoning lifecycle transitions while preserving handling for non-empty tool-call deltas, directly correcting the reported root cause. Side effectsRisk: low The only production behavior change is that an empty tool-call array no longer ends reasoning; actual text and non-empty tool-call deltas retain their existing transition behavior. PerformanceRisk: none The added constant-time array-length check introduces no meaningful overhead and prevents unnecessary reasoning lifecycle events. Backwards compatibilityRisk: none No persistence code or stored-data format is touched, so existing stored data requires no migration or reinterpretation. Breaking changesRisk: none No public APIs, types, exports, accepted inputs, defaults, configuration, errors, or persisted formats change; only the erroneous streamed event sequence for empty tool-call arrays is corrected. ArchitectureRisk: none The fix remains localized to the OpenAI-compatible stream adapter that owns this behavior and introduces no dependencies, cross-package source imports, shared abstractions, or boundary violations. Change scopeStatus: minimal The merge-base diff contains one production condition change, one focused regression test, and the required patch changeset. SecurityRisk: none The change does not alter URL handling, credentials, parsing, validation, authorization, or other security-sensitive behavior. TestingStatus: appropriate The regression test covers consecutive reasoning deltas carrying empty tool-call arrays, while existing tests continue to cover non-empty tool-call streaming; the exact reproduction replay also passed. VerificationReviewed the complete three-file merge-base diff and surrounding reasoning, text, tool-call, and schema logic. The OpenAI-compatible package's Node and Edge suites each passed with 262 tests, and package type-checking, build, and diff validation passed. |
|
🚀 Published in:
|
Background
OpenAI-compatible gateways that attach
tool_calls: []to reasoning deltas caused one logical reasoning span to be emitted as multiple user-visible reasoning blocks.Root Cause
The stream transform treated any non-null
tool_callsarray as active tool output. The immutable reproduction and regression test confirmed that empty arrays closed reasoning after each delta, producing two start/end cycles instead of one.Summary
Reasoning now ends for tool calls only when the streamed
tool_callsarray contains entries. Added a patch changeset and removed reproduction-only artifacts.Testing
Added a regression test verifying consecutive reasoning deltas with empty tool-call arrays remain within one reasoning lifecycle.
End-to-end Validation
pnpm -C packages/openai-compatible buildcompleted successfully.Related Issues
Fixes #20203
Closes #20251