Skip to content

Fix: Codex→chat/completions translator drops custom_tool_call (breaks Cursor ApplyPatch / any custom tool)#4079

Open
harmalh wants to merge 1 commit into
router-for-me:devfrom
harmalh:fix/codex-custom-tool-call-chat-completions
Open

Fix: Codex→chat/completions translator drops custom_tool_call (breaks Cursor ApplyPatch / any custom tool)#4079
harmalh wants to merge 1 commit into
router-for-me:devfrom
harmalh:fix/codex-custom-tool-call-chat-completions

Conversation

@harmalh

@harmalh harmalh commented Jul 1, 2026

Copy link
Copy Markdown

Summary

  • Fix the Codex → OpenAI chat/completions response translator dropping upstream custom_tool_call output items (e.g. Cursor ApplyPatch / any OpenAI type:"custom" tool).
  • Mirror the existing function_call streaming path for custom_tool_call: output_item.added/.done, custom_tool_call_input.delta/.done, and non-stream response.completed output.
  • Map Codex custom_tool_call.input into chat/completions tool_calls[].function.arguments and set finish_reason: "tool_calls" when a custom tool call is present.

Context

Reproduced on v7.2.45 and v7.2.48. Standard type:"function" tools were unaffected; only the custom_tool_call return path was broken. The request translator already forwards type:"custom" tools upstream — the model invokes them — but the response translator only handled function_call.

Root cause: hard guards in internal/translator/codex/openai/chat-completions/codex_openai_response.go that returned empty chunks for anything other than function_call.

Test plan

  • go test ./internal/translator/codex/openai/chat-completions/...
  • Added streaming test for custom_tool_call announcement, custom_tool_call_input.delta, suppressed output_item.done, and finish_reason:"tool_calls"
  • Added fallback test for custom_tool_call_input.done when no deltas were streamed
  • Added non-stream test for custom_tool_call in response.completed output
  • go build -o cli-proxy-api ./cmd/server

Made with Cursor

…nses.

Mirror existing function_call handling for custom_tool_call output items and
custom_tool_call_input stream events so clients receive tool_calls and
finish_reason tool_calls for OpenAI custom tools like Cursor ApplyPatch.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

This pull request targeted main.

The base branch has been automatically changed to dev.

@github-actions github-actions Bot changed the base branch from main to dev July 1, 2026 15:32

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for custom_tool_call alongside the existing function_call handling in the Codex-to-OpenAI response translator. It refactors the tool call processing logic into reusable helper functions (such as isCodexToolCallItemType, resolveToolCallName, and toolCallArgumentsFromCodexItem) to handle both streaming and non-streaming responses cleanly. Additionally, comprehensive unit tests have been added to verify the streaming, fallback, and non-streaming behaviors of custom tool calls. There are no review comments to address.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e1ec1e5493

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
case "function_call":
// Handle function call content
case "function_call", "custom_tool_call":

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve custom tool-call type across the chat round trip

When this branch exposes a custom_tool_call as a Chat Completions tool_calls[].type:"function", the next client turn has no way to indicate that the tool result belongs to a custom Responses call; the existing request translator still hard-codes every role:"tool" message to function_call_output in internal/translator/codex/openai/chat-completions/codex_openai_request.go:122-128. In the ApplyPatch/custom-tool flow, the model call is now surfaced to the client, but the result is sent back upstream as a function output instead of custom_tool_call_output, so the custom call cannot be continued correctly unless the call_id/type is preserved and used on the request side.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant