From 07cf616e2b9b3143d4b02c75fe4f94e2e208db6f Mon Sep 17 00:00:00 2001 From: Kirill Turanskiy Date: Mon, 16 Feb 2026 00:20:23 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20handle=20response.function=5Fcall=5Fargu?= =?UTF-8?q?ments.done=20in=20codex=E2=86=92claude=20streaming=20translator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some Codex models (e.g. gpt-5.3-codex-spark) send function call arguments in a single "done" event without preceding "delta" events. The streaming translator only handled "delta" events, causing tool call arguments to be lost — resulting in empty tool inputs and infinite retry loops in clients like Claude Code. Emit the full arguments from the "done" event as a single input_json_delta so downstream clients receive the complete tool input. --- .../codex/claude/codex_claude_response.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/translator/codex/claude/codex_claude_response.go b/internal/translator/codex/claude/codex_claude_response.go index b39494b7..6f18e24d 100644 --- a/internal/translator/codex/claude/codex_claude_response.go +++ b/internal/translator/codex/claude/codex_claude_response.go @@ -177,6 +177,19 @@ func ConvertCodexResponseToClaude(_ context.Context, _ string, originalRequestRa output += "event: content_block_delta\n" output += fmt.Sprintf("data: %s\n\n", template) + } else if typeStr == "response.function_call_arguments.done" { + // Some models (e.g. gpt-5.3-codex-spark) send function call arguments + // in a single "done" event without preceding "delta" events. + // Emit the full arguments as a single input_json_delta so the + // downstream Claude client receives the complete tool input. + if args := rootResult.Get("arguments").String(); args != "" { + template = `{"type":"content_block_delta","index":0,"delta":{"type":"input_json_delta","partial_json":""}}` + template, _ = sjson.Set(template, "index", (*param).(*ConvertCodexResponseToClaudeParams).BlockIndex) + template, _ = sjson.Set(template, "delta.partial_json", args) + + output += "event: content_block_delta\n" + output += fmt.Sprintf("data: %s\n\n", template) + } } return []string{output}