mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-13 18:52:18 +03:00
emitToolCallAdded/closeToolCall used the provider's raw Chat Completions tool_calls[].index directly as the Responses API output_index. That index is scoped only to the tool_calls array and legitimately restarts at 0 for the first tool call, but a reasoning item (and/or a text message) emitted earlier in the same turn may already have claimed output_index 0 (and 1). A client that tracks response items by output_index (as the Responses API spec expects) then sees the tool call's added/delta/done events land on an index it already marked complete, and silently drops the tool call -- producing an "incomplete turn" that never dispatches it. Reported live: OpenClaw on combo default -> opencode-zen/big-pickle sent a reasoning block immediately followed by a function call in the same turn (no text message in between); the function call's output_index collided with the reasoning item's. A similar collision (tool call after a *text message*) was already fixed in open-sse/translator/response/openai-responses.ts (#9822/#9843), but that file is only used by the zed-hosted executor -- the general /v1/responses path (wired via responsesHandler.ts) goes through this file, which never received the equivalent fix. Fix: compute the tool call's output_index once (offset past any reasoning/ message item already emitted this turn) and cache it in state.funcOutputIndex, so every added/delta/done event for that call -- including ones emitted later from the finish_reason handler or flush() -- shares exactly the same output_index. TDD: new regression tests in tests/unit/responses-transformer-tool-call-reasoning-collision.test.ts reproduce the exact live scenario (reasoning immediately followed by a tool call, and multiple tool calls after reasoning) -- confirmed failing against the pre-fix code, passing after. Full transformer test suite (responses-transformer*.test.ts, responses-replay-fixes.test.ts, responses-api-truncation.test.ts, responses-request-translation.test.ts) -- 24/24 passing, no regressions. ⚠️ base-red inherited: #9985