mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
Codex sends the results of custom (freeform) tools such as `apply_patch` back as `custom_tool_call_output` input items. `RequestPayload.correlatingToolCallID` only matched `function_call_output`, so these follow-up interceptions had no correlating tool call ID. They were not linked to the interception that issued the tool call, which left blank AI Gateway sessions. [Example session](https://dogfood.cdr.dev/ai-gateway/sessions/01a1184a-08a4-7d50-8e15-a12368302a2f) <img width="996" height="576" alt="image" src="https://github.com/user-attachments/assets/5bce6035-963b-4438-897b-bee36ead5a47" /> `custom_tool_call_output` is now handled the same way as `function_call_output`. The earlier `custom_tool_call` is already recorded as a tool usage with its `call_id`, and `GetAIBridgeInterceptionLineageByToolCallID` does not check the tool type, so lineage now resolves without any other change. Fixes AIGOV-707 <details> <summary>Implementation notes</summary> - **Reproduction first:** the first commit adds blocking and streaming `custom_tool_result.txtar` fixtures. Each one is a follow-up turn that replays a `custom_tool_call` and ends with its `custom_tool_call_output`. `TestResponsesOutputMatchesUpstream` now checks `CorrelatingToolCallID` on every case, and `TestCorrelatingToolCallID` gains a `custom_tool_call_output` case plus a case where the last item is the tool call itself rather than its result. On that commit, both fixture cases and the unit case fail with `nil` instead of the custom tool's call ID. The second commit makes them pass. - **Out of scope:** other client-executed result types (`computer_call_output`, `shell_call_output`, `apply_patch_call_output`, `local_shell_call_output`) are not correlated either. Codex's `apply_patch` arrives as a custom tool, so it is covered here. Those other types were left out to keep this change tied to the reported bug. </details> > Generated by Coder Agents on behalf of @dannykopping.