Skip to content

fix(antigravity): place tool_result images in functionResponse.parts and unify mimeType#1682

Merged
luispater merged 1 commit intorouter-for-me:devfrom
sususu98:fix/tool-result-image-parts
Feb 25, 2026
Merged

fix(antigravity): place tool_result images in functionResponse.parts and unify mimeType#1682
luispater merged 1 commit intorouter-for-me:devfrom
sususu98:fix/tool-result-image-parts

Conversation

@sususu98
Copy link
Copy Markdown
Collaborator

@sususu98 sususu98 commented Feb 23, 2026

Summary

  • Extract base64 image data from Claude tool_result content into functionResponse.parts as inlineData, so the Gemini API can properly interpret them as images instead of opaque JSON text.
  • Unify all inlineData field naming to camelCase mimeType across Claude, OpenAI, and Gemini translators (was inconsistently using mime_type in some paths).

Problem

When a Claude tool_result contains image content (e.g., screenshots from tool calls), the image block was dumped as raw Claude-format JSON into functionResponse.response.result:

{
    "functionResponse": {
        "response": {
            "result": [
                {"type":"text","text":"..."},
                {"type":"image","source":{"type":"base64","media_type":"image/png","data":"..."}}
            ]
        }
    }
}

The Gemini API cannot interpret this Claude-format image object — it treats it as opaque text, wasting context and losing the actual image data.

Additionally, inlineData field naming was inconsistent: some code paths used snake_case mime_type instead of the correct camelCase mimeType, affecting both user-input images (Claude translator) and file attachments (OpenAI translator).

Solution

  • Claude translator (antigravity_claude_request.go): Detect type: "image" + source.type: "base64" entries within tool_result content. Convert them to Gemini inlineData format and place them in functionResponse.parts[] instead of leaving them as raw JSON in response.result. Handles both array content (mixed text + images) and single object content (image-only).
  • Claude translator: Fix mime_typemimeType for standalone image content blocks (user-input images).
  • OpenAI translator (antigravity_openai_request.go): Fix mime_typemimeType in 3 places where inlineData is constructed for data URIs and file attachments.

Tests

  • Added 7 new test cases covering: text+image, single image, multiple images+texts, image-only, non-base64 image fallthrough, missing data field, missing media_type field.
  • Added Gemini-side regression test verifying functionResponse.parts with inlineData survives fixCLIToolResponse pipeline.

…and unify mimeType

Move base64 image data from Claude tool_result into functionResponse.parts
as inlineData instead of outer sibling parts, preventing context bloat.
Unify all inlineData field naming to camelCase mimeType across Claude,
OpenAI, and Gemini translators. Add comprehensive edge case tests and
Gemini-side regression test for functionResponse.parts preservation.
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @sususu98, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refines how image data is processed within tool results, specifically for Claude models, by relocating base64 images to a dedicated inlineData structure within functionResponse.parts. This change significantly reduces unnecessary text context bloat. Additionally, it unifies the naming convention for the mimeType field across different translators, improving consistency and maintainability.

Highlights

  • Claude Tool Result Image Handling: Base64 image data from Claude tool_result content is now correctly moved into functionResponse.parts as inlineData, preventing it from bloating the text context in the outer contents[].parts[] array.
  • MimeType Field Unification: The mime_type field in inlineData structures has been standardized to mimeType across Claude, OpenAI, and Gemini translators for consistency.
  • Enhanced Test Coverage: Seven new test cases were added for the Claude translator to cover various tool_result image scenarios, including mixed content, single images, multiple images, and edge cases like missing data or media types. A regression test was also added for the Gemini translator to ensure functionResponse.parts are preserved.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • internal/translator/antigravity/claude/antigravity_claude_request.go
    • Refactored functionResponseResult.IsArray() logic to identify and extract base64 image content, moving it to functionResponse.parts and filtering it from response.result.
    • Introduced new logic for functionResponseResult.IsObject() to handle single base64 image objects, placing them in functionResponse.parts.
    • Updated mime_type to mimeType when setting inlineData for standalone image content blocks.
  • internal/translator/antigravity/claude/antigravity_claude_request_test.go
    • Modified an existing test case to assert against mimeType instead of mime_type.
    • Added new test cases for tool_result content containing text and images, ensuring images are correctly moved to functionResponse.parts.
    • Included test cases for tool_result with single image objects, multiple images and texts, and only multiple images.
    • Added tests for scenarios where tool_result images are not base64, or are missing data or media_type fields.
  • internal/translator/antigravity/gemini/antigravity_gemini_request_test.go
    • Added a new test TestFixCLIToolResponse_PreservesFunctionResponseParts to verify that fixCLIToolResponse correctly preserves the parts field within functionResponse.
  • internal/translator/antigravity/openai/chat-completions/antigravity_openai_request.go
    • Changed mime_type to mimeType in three instances where inlineData is constructed for data URIs and file attachments.
Activity
  • The pull request was created by sususu98 to address issues with Claude tool_result image handling and mimeType naming inconsistencies.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

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

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 effectively addresses the issue of base64 image data from Claude tool_result bloating the context by moving it into functionResponse.parts. The changes are well-implemented, particularly the logic to separate image and non-image content from tool results. The addition of 7 new test cases is excellent and covers various scenarios, including edge cases, which greatly improves confidence in the change.

The unification of mime_type to mimeType across the Claude, OpenAI, and Gemini translators is also a great cleanup that improves consistency.

I have one suggestion regarding code duplication in the Claude translator to improve maintainability. Overall, this is a solid contribution.

Comment on lines +267 to +284
if functionResponseResult.Get("type").String() == "image" && functionResponseResult.Get("source.type").String() == "base64" {
inlineDataJSON := `{}`
if mimeType := functionResponseResult.Get("source.media_type").String(); mimeType != "" {
inlineDataJSON, _ = sjson.Set(inlineDataJSON, "mimeType", mimeType)
}
if data := functionResponseResult.Get("source.data").String(); data != "" {
inlineDataJSON, _ = sjson.Set(inlineDataJSON, "data", data)
}

imagePartJSON := `{}`
imagePartJSON, _ = sjson.SetRaw(imagePartJSON, "inlineData", inlineDataJSON)
imagePartsJSON := "[]"
imagePartsJSON, _ = sjson.SetRaw(imagePartsJSON, "-1", imagePartJSON)
functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "parts", imagePartsJSON)
functionResponseJSON, _ = sjson.Set(functionResponseJSON, "response.result", "")
} else {
functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "response.result", functionResponseResult.Raw)
}
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.

medium

There's significant code duplication between this block (for handling IsObject) and the logic inside the IsArray loop on lines 231-243. Both sections build inlineData and imagePart JSON for base64 images.

To improve maintainability and reduce redundancy, consider extracting this logic into a helper function. For example, you could create a function that takes a gjson.Result representing an image content part and returns the corresponding imagePartJSON string.

Example of a potential helper:

func createImagePartFromContent(content gjson.Result) (string, bool) {
    if content.Get("type").String() != "image" || content.Get("source.type").String() != "base64" {
        return "", false
    }

    inlineDataJSON := `{}`
    if mimeType := content.Get("source.media_type").String(); mimeType != "" {
        inlineDataJSON, _ = sjson.Set(inlineDataJSON, "mimeType", mimeType)
    }
    if data := content.Get("source.data").String(); data != "" {
        inlineDataJSON, _ = sjson.Set(inlineDataJSON, "data", data)
    }

    imagePartJSON := `{}`
    imagePartJSON, _ = sjson.SetRaw(imagePartJSON, "inlineData", inlineDataJSON)
    
    return imagePartJSON, true
}

This would make the code cleaner and easier to manage.

@KooshaPari

This comment was marked as spam.

@KooshaPari

This comment was marked as spam.

@KooshaPari

This comment was marked as spam.

@KooshaPari

This comment was marked as spam.

1 similar comment
@KooshaPari

This comment was marked as spam.

@luispater luispater changed the base branch from main to dev February 25, 2026 15:14
@luispater luispater merged commit 816fb4c into router-for-me:dev Feb 25, 2026
1 of 2 checks passed
AoaoMH pushed a commit to AoaoMH/CLIProxyAPI-Aoao that referenced this pull request Mar 3, 2026
…mage-parts

fix(antigravity): place tool_result images in functionResponse.parts and unify mimeType
xiaojiou176 pushed a commit to xiaojiou176/CLIProxyAPI that referenced this pull request Mar 27, 2026
…mage-parts

fix(antigravity): place tool_result images in functionResponse.parts and unify mimeType
xiaojiou176 pushed a commit to xiaojiou176/CLIProxyAPI that referenced this pull request Mar 29, 2026
…mage-parts

fix(antigravity): place tool_result images in functionResponse.parts and unify mimeType
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.

3 participants