-
Notifications
You must be signed in to change notification settings - Fork 72
fix: force finish_reason='tool_calls' when tool calls were emitted#8
Open
wonsik-song wants to merge 1 commit into
Open
fix: force finish_reason='tool_calls' when tool calls were emitted #8wonsik-song wants to merge 1 commit into
wonsik-song wants to merge 1 commit into
Conversation
Codex Responses API sometimes reports finishReason as 'stop' or undefined even when the turn ends with tool calls. OpenAI-compatible clients rely on finish_reason='tool_calls' on the final chunk to drain tool_call deltas accumulated across streaming chunks — without it, accumulated tool calls are silently dropped and the assistant appears to return an empty response. Override the mapped finish_reason to 'tool_calls' whenever the stream emitted any tool_calls (or the non-stream response contains toolCalls) and the upstream finishReason didn't already map to 'tool_calls'. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
Summary
Codex Responses API sometimes reports
finishReasonas"stop"orundefinedeven when the turn ends with tool calls. OpenAI-compatible clients (e.g. any SDK that parses streamingchat.completionsand drains tool_call deltas onfinish_reason="tool_calls") silently drop accumulated tool calls when the final chunk carriesfinish_reason: null/"stop".This PR overrides the mapped
finish_reasonto"tool_calls"in both the streaming and non-streaming paths whenever any tool calls were actually emitted during the turn.Why this matters
OpenAI-compat clients accumulate tool_call argument deltas across streaming chunks (delta.tool_calls[].function.arguments chunks). They only flush the accumulated tool call into a real
ToolCallevent when the final chunk signalsfinish_reason="tool_calls"(or on[DONE], but clients that follow the OpenAI reference behavior rely on the former). If the proxy hands themfinish_reason=nullor"stop"on a turn that emitted tool_calls, the tool call is dropped and the assistant appears to return an empty response.I hit this from a Rust client that uses the official OpenAI streaming format. Turn ends with a complete
tool_callsdelta stream forcontext_get(...), proxy emitsfinish_reason: nullin the finish chunk, client never drains, agent loop exits with 0 tool calls, UI shows nothing.Changes
packages/openai-oauth/src/chat-stream.ts— in the"finish"case, if any tool calls were emitted during the stream (toolIndexes.size > 0) and the mapped finish_reason is not already"tool_calls", override it.packages/openai-oauth/src/chat-completions.ts— same defensive override in the non-streaming response builder whentoolCalls.length > 0.Test plan
/v1/chat/completionswithstream: trueand a prompt that triggers a tool call → verify the finish chunk carriesfinish_reason: "tool_calls".choices[0].finish_reasonis"tool_calls"."stop"(not overridden).🤖 Generated with Claude Code