Whisk native Gemini support - #2
Conversation
This change implements the `Execute`, `ExecuteStream`, and `CountTokens` methods in the `WhiskExecutor` to support native Gemini `generateContent` requests. The executor now handles: - Image generation (Text to Image) using `IMAGEN_3_5`. - Image editing (Text + Image to Image) using `GEM_PIX`. - Image description (Text + Image to Text) using Whisk's captioning model. Key changes: - Implemented `Execute` to parse Gemini JSON payloads and route to appropriate Whisk methods. - Added heuristic logic to distinguish between "edit" and "describe" tasks. - Added aspect ratio mapping from Gemini to Whisk formats. - Formatted Whisk responses back into Gemini-compliant JSON. - Added unit tests for parsing and formatting logic. - Fixed a potential panic in captioning logic. Co-authored-by: jooni22 <20043534+jooni22@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Summary of ChangesHello @jooni22, 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 native Gemini API compatibility to the Whisk executor. It allows the system to interpret and respond to Gemini-formatted requests for various image-related functionalities, such as generating new images, refining existing ones, or providing descriptions. The core changes involve parsing the Gemini Highlights
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
The pull request introduces native Gemini API support for the Whisk executor, enabling image generation, editing, and description tasks. The changes include parsing logic for Gemini requests, mapping aspect ratios, and formatting responses back into the Gemini format. Unit tests have been added for the new parsing and formatting functions, and the ExecuteStream and CountTokens methods have been updated for Gemini compatibility. Overall, the implementation provides a solid foundation for Gemini integration. However, there are a couple of areas where the model selection for image generation could be more flexible and error handling for JSON manipulation could be improved for robustness.
| // Generation | ||
| whiskReq := WhiskImageRequest{ | ||
| Prompt: prompt, | ||
| Model: WhiskModelImagen35, // Use 3.5 for generations |
There was a problem hiding this comment.
The GenerateImage call hardcodes WhiskModelImagen35 for image generations. This means that if the incoming Gemini request specifies a different model in req.Model for image generation, it will be ignored. This limits the flexibility of the Gemini API integration and might lead to unexpected behavior if users expect their specified model to be used.
Consider using req.Model here, possibly with a fallback to WhiskModelImagen35 if req.Model is empty or not a valid Whisk image generation model.
| Model: WhiskModelImagen35, // Use 3.5 for generations | |
| Model: req.Model, // Use req.Model for generations, fallback if needed |
| res, _ = sjson.Set(res, "candidates.0.content.parts.0.text", text) | ||
| res, _ = sjson.Set(res, "model", model) |
There was a problem hiding this comment.
Errors returned by sjson.Set are currently ignored. While the initial JSON template is controlled, it's good practice to handle potential errors, especially when constructing responses that external systems will consume. If sjson.Set encounters an issue (e.g., an invalid path or value), it could lead to malformed JSON being returned without any indication of a problem.
Consider checking the err return value and handling it appropriately, perhaps by logging the error or returning an cliproxyexecutor.Response{} with an error.
| res, _ = sjson.Set(res, "candidates.0.content.parts.0.text", text) | |
| res, _ = sjson.Set(res, "model", model) | |
| res, err = sjson.Set(res, "candidates.0.content.parts.0.text", text) | |
| if err != nil { | |
| // Handle error, e.g., log it or return an error response | |
| } | |
| res, err = sjson.Set(res, "model", model) | |
| if err != nil { | |
| // Handle error | |
| } |
|
|
||
| func formatGeminiImageResponse(result *WhiskImageResponse, model string) cliproxyexecutor.Response { | ||
| res := `{"candidates":[{"content":{"parts":[],"role":"model"},"finishReason":"STOP","index":0}],"usageMetadata":{"promptTokenCount":0,"candidatesTokenCount":0,"totalTokenCount":0}}` | ||
| res, _ = sjson.Set(res, "model", model) |
There was a problem hiding this comment.
Similar to formatGeminiTextResponse, errors from sjson.Set are ignored here. It's important to ensure that the JSON response is always well-formed. If setting the model fails silently, it could lead to downstream issues.
Consider adding error handling for the sjson.Set call.
| res, _ = sjson.Set(res, "model", model) | |
| res, err = sjson.Set(res, "model", model) | |
| if err != nil { | |
| // Handle error | |
| } |
| inlineDataJSON, _ := json.Marshal(inlineData) | ||
| res, _ = sjson.SetRaw(res, path, string(inlineDataJSON)) |
There was a problem hiding this comment.
Errors from json.Marshal and sjson.SetRaw are ignored. While inlineData is a simple map, json.Marshal can return an error if the data is unmarshallable. More critically, sjson.SetRaw can fail if the path is invalid or the raw JSON string is malformed. Silently ignoring these errors can result in an incomplete or malformed response being sent.
It's recommended to check and handle these errors to ensure the robustness of the response formatting.
inlineDataJSON, err := json.Marshal(inlineData)
if err != nil {
// Handle error
continue // Skip this image if its data cannot be marshaled
}
res, err = sjson.SetRaw(res, path, string(inlineDataJSON))
if err != nil {
// Handle error
}| textPath := fmt.Sprintf("candidates.0.content.parts.%d.text", len(result.Data)+i) | ||
| res, _ = sjson.Set(res, textPath, "Revised prompt: "+img.Prompt) |
There was a problem hiding this comment.
Errors from sjson.Set are ignored when adding the revised prompt. This could lead to a situation where the prompt is not added to the response, but the function indicates success. Robust error handling would ensure that any issues during JSON manipulation are caught and addressed.
Consider adding error handling for this sjson.Set call.
textPath := fmt.Sprintf("candidates.0.content.parts.%d.text", len(result.Data)+i)
res, err = sjson.Set(res, textPath, "Revised prompt: "+img.Prompt)
if err != nil {
// Handle error
}
Implemented native Gemini API support for the Whisk executor, allowing image generation, editing, and description tasks via the standard Gemini
generateContentendpoint. Added parsing, mapping, and formatting logic along with unit tests.PR created automatically by Jules for task 6405815222955259202 started by @jooni22