fix(translator): preserve Claude URL images for Codex (GPT-5.4) vision#2931
fix(translator): preserve Claude URL images for Codex (GPT-5.4) vision#2931dos1989 wants to merge 1 commit into
Conversation
|
This pull request targeted The base branch has been automatically changed to |
There was a problem hiding this comment.
Code Review
This pull request refactors the handling of Claude image sources by introducing a helper function claudeImageSourceToDataURL. This helper consolidates the logic for processing both base64-encoded and URL-referenced image sources, reducing code duplication in ConvertClaudeRequestToCodex. Additionally, new test cases were added to verify the correct conversion of both image source types. I have no feedback to provide.
luispater
left a comment
There was a problem hiding this comment.
Summary
Fixes Claude→Codex request translation dropping source.type == "url" image parts by centralizing image-source conversion and reusing it for both user message images and tool_result image content. Adds unit tests for base64 and URL sources.
Findings
Blocking
- None.
Non-blocking
- Consider renaming
claudeImageSourceToDataURLto...ImageURLsince it can return a plain URL. - Consider adding coverage for the
tool_result.content[].type == "image"path (now also uses the helper). - FYI this PR will keep failing
translator-path-guarddue to touchinginternal/translator/...unless the merge policy/check is overridden.
Test plan
- Not run locally (no branch checkout per request).
- CI
pr-test-buildis green; recommend also runninggo test ./internal/translator/codex/claude/....
This is an automated Codex review result and still requires manual verification by a human reviewer.
Summary
internal/translator/codex/claude/codex_claude_request.go) silently dropped Claude image content whosesource.type == "url"because it only readsource.data/source.base64. Claude clients that send URL-referenced images togpt-5.4ended up with text-only context — model couldn't 睇圖.claudeImageSourceToDataURLhelper that handles bothurlandbase64sources (matching the existinginternal/translator/openai/claude/openai_claude_request.gobehaviour), and routed the top-level user-image path and the nestedtool_resultimage path through it.TestConvertClaudeRequestToCodex_ImageSourcescovering base64 + URL cases.Root cause
codex_claude_request.gohandled image content at two call sites (top-level user message +tool_result.content[]) but only readsource.data/source.base64. Anthropic's API also allows{"type":"image","source":{"type":"url","url":"..."}}, which was silently skipped — no error surfaced upstream, the request simply reached Codex with text only.Verification
go build ./...go vet ./internal/translator/codex/claude/...go test ./internal/translator/codex/claude/...127.0.0.1:8318: Claude/v1/messageswithsource.type="url"image +model: gpt-5.4→ response:"The image shows the GitHub logo, a black Octocat silhouette in a circle."(before the fix, the model saw text only and described no image).Test plan
input_imagewith adata:<mime>;base64,...URLinput_imagewith the original URLgo test ./internal/translator/codex/claude/...passesgpt-5.4Out of scope (follow-ups)
Discovered during review, not addressed here to keep the fix minimal:
source.type == "file"(Anthropic file_id) still returns empty from the helper — both call sites will skip it. Requires the helper to return a structured image part (image_urlvsfile_id), not a string.tool_result.contentas a single image object (non-array) falls through to the string path. Siblingopenai_claude_request.goalready handles this shape.internal/translator/antigravity/claude/antigravity_claude_request.gohas the same URL-source gap (base64 only at lines 281/317/347) and its existing tests lock that behaviour.Happy to split these into separate PRs if the project prefers.