Conversation
…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.
fix(antigravity): place tool_result images in functionResponse.parts and unify mimeType
…fallback fix(antigravity): keep primary model list and backfill empty auths
Summary of ChangesHello @luispater, 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 introduces significant improvements to how Antigravity models are managed and how image data is handled in tool results for Claude models. A new caching layer ensures greater resilience by providing fallback model lists during network issues. The Claude translator now intelligently processes image content within tool results, optimizing the data structure for better context management. Additionally, a new mechanism allows for efficient propagation of model lists to newly registered Antigravity authentications, and static model definitions have been updated. Highlights
🧠 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
Activity
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
Code Review
This pull request introduces several enhancements for robustness and user experience, primarily for the "antigravity" provider. Key changes include adding a caching and fallback mechanism for model discovery to improve resilience against endpoint failures, and a backfill feature to share a successfully fetched model list across all antigravity accounts. The PR also refactors how image content within Claude tool results is handled to optimize context usage and corrects the mime_type field to mimeType for consistency across translators. The changes are well-supported by new tests. My review includes one suggestion to refactor duplicated code in the Claude translator for better maintainability.
| } else if functionResponseResult.IsArray() { | ||
| frResults := functionResponseResult.Array() | ||
| if len(frResults) == 1 { | ||
| functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "response.result", frResults[0].Raw) | ||
| nonImageCount := 0 | ||
| lastNonImageRaw := "" | ||
| filteredJSON := "[]" | ||
| imagePartsJSON := "[]" | ||
| for _, fr := range frResults { | ||
| if fr.Get("type").String() == "image" && fr.Get("source.type").String() == "base64" { | ||
| inlineDataJSON := `{}` | ||
| if mimeType := fr.Get("source.media_type").String(); mimeType != "" { | ||
| inlineDataJSON, _ = sjson.Set(inlineDataJSON, "mimeType", mimeType) | ||
| } | ||
| if data := fr.Get("source.data").String(); data != "" { | ||
| inlineDataJSON, _ = sjson.Set(inlineDataJSON, "data", data) | ||
| } | ||
|
|
||
| imagePartJSON := `{}` | ||
| imagePartJSON, _ = sjson.SetRaw(imagePartJSON, "inlineData", inlineDataJSON) | ||
| imagePartsJSON, _ = sjson.SetRaw(imagePartsJSON, "-1", imagePartJSON) | ||
| continue | ||
| } | ||
|
|
||
| nonImageCount++ | ||
| lastNonImageRaw = fr.Raw | ||
| filteredJSON, _ = sjson.SetRaw(filteredJSON, "-1", fr.Raw) | ||
| } | ||
|
|
||
| if nonImageCount == 1 { | ||
| functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "response.result", lastNonImageRaw) | ||
| } else if nonImageCount > 1 { | ||
| functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "response.result", filteredJSON) | ||
| } else { | ||
| functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "response.result", functionResponseResult.Raw) | ||
| functionResponseJSON, _ = sjson.Set(functionResponseJSON, "response.result", "") | ||
| } | ||
|
|
||
| // Place image data inside functionResponse.parts as inlineData | ||
| // instead of as sibling parts in the outer content, to avoid | ||
| // base64 data bloating the text context. | ||
| if gjson.Get(imagePartsJSON, "#").Int() > 0 { | ||
| functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "parts", imagePartsJSON) | ||
| } | ||
|
|
||
| } else if functionResponseResult.IsObject() { | ||
| functionResponseJSON, _ = sjson.SetRaw(functionResponseJSON, "response.result", functionResponseResult.Raw) | ||
| 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) | ||
| } |
There was a problem hiding this comment.
There is significant code duplication in how image parts are processed within the IsArray and IsObject conditions. The logic to construct inlineDataJSON and imagePartJSON is nearly identical in both branches (lines 232-242 and 268-277). To improve maintainability and reduce redundancy, consider refactoring this shared logic. A local helper function (closure) could encapsulate this logic, making the code cleaner and easier to manage.
No description provided.