Files
OmniRoute/open-sse
Markus Hartung ae54c6221c fix(responses-api): tool call after reasoning collided on the same output_index (#10025)
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
2026-08-13 04:02:25 -03:00
..
2026-05-26 23:51:47 -03:00
2026-07-07 13:14:06 -03:00