-
-
Notifications
You must be signed in to change notification settings - Fork 722
Description
Problem / 问题
When translating OpenAI/Codex streaming (/v1/responses) into Claude streaming (/v1/messages), the current translator reuses Codex output_index as Claude content_block.index.
If a single output_index produces multiple block types (e.g. tool_use + thinking + text), the same content_block.index gets reused for different block types. Claude streaming expects each content_block.index to uniquely identify one started block, and deltas for that index must match the started type.
This can cause Claude clients (e.g. Claude Code for VS Code) to fail with errors like:
Mismatched content block type content_block_delta thinking
Repro / 复现
A stream where output_index=0 contains both a tool call and reasoning/text, for example:
response.output_item.added(function_call, output_index=0)response.function_call_arguments.delta(output_index=0)response.output_item.done(output_index=0)response.reasoning_summary_part.added(output_index=0)response.reasoning_summary_text.delta(output_index=0)
This currently translates into Claude SSE where content_block_start for different types share the same index, and later content_block_delta events can mismatch the type for that index.
Proposed Fix / 修复思路
- Allocate sequential, unique Claude
content_block.indexvalues per logical block (per stream), rather than reusingoutput_index. - Ensure
content_block_startis emitted before anycontent_block_deltafor that block. - Close any still-open blocks (
content_block_stop) before emitting finalmessage_delta/message_stopon completion.
Patch / 补丁
A ready patch + regression test is in PR #538 (note: this repo has a required translator-path-guard check that blocks merging translator path changes via PRs):
Maintainers can cherry-pick from the fork branch used by the PR:
git fetch https://github.com/fuguiKz/CLIProxyAPI.git fix/codex-claude-sse-content-block-index
git cherry-pick a321be1 7761566Tests
PR adds internal/translator/codex/claude/codex_claude_response_test.go to ensure indexes are not reused across types and deltas always match the started block type for a given index.
(Notes: go test ./internal/translator/codex/claude passes.)