-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] Google Gemini - Add support for structure JSON output #14896
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ |
WalkthroughThe pull request introduces several new components and updates to existing files within the Google Gemini application. Key changes include the addition of a Changes
Assessment against linked issues
Possibly related PRs
Suggested labels
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Outside diff range and nitpick comments (3)
components/google_gemini/common/utils.mjs (1)
10-20
: Enhance parse function with better error handling and type safetyWhile the basic functionality is correct, there's room for improvement in error handling and type safety.
Consider applying these improvements:
function parse(value) { + if (value === null) return null; const valueToParse = emptyStrToUndefined(value); if (typeof(valueToParse) === "object" || valueToParse === undefined) { return valueToParse; } try { return JSON.parse(valueToParse); } catch (e) { - throw new ConfigurationError("Make sure the custom expression contains a valid object"); + throw new ConfigurationError( + `Invalid JSON format. Please provide a valid JSON object or array. Error: ${e.message}` + ); } }These changes:
- Explicitly handle null values
- Provide more detailed error messages including the original JSON parsing error
- Clarify that arrays are also valid JSON structures
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (1)
91-105
: Refactor conditional logic for buildinggenerationConfig
The current conditional logic for including
generationConfig
can be simplified and made more readable by directly constructing the object with conditional properties.Refactor the code as follows:
data: { contents: [ /* ... */ ], - ...( - responseFormat || maxOutputTokens || temperature || topP || topK || stopSequences?.length - ? { - generationConfig: { - responseMimeType: "application/json", - responseSchema: utils.parse(responseSchema), - maxOutputTokens, - temperature, - topP, - topK, - stopSequences, - }, - } - : {} - ), + generationConfig: { + ...(responseFormat && { responseMimeType: "application/json" }), + ...(responseSchema && { responseSchema: utils.parse(responseSchema) }), + ...(maxOutputTokens && { maxOutputTokens }), + ...(temperature && { temperature }), + ...(topP && { topP }), + ...(topK && { topK }), + ...(stopSequences?.length && { stopSequences }), + }, },This change ensures that only the provided parameters are included in
generationConfig
, and it improves code readability.components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (1)
53-67
: Simplify the conditional generation config logic.The current spread operator with nested ternary could be harder to maintain. Consider extracting the condition and config object.
Suggested refactoring:
- ...( - responseFormat || maxOutputTokens || temperature || topP || topK || stopSequences?.length - ? { - generationConfig: { - responseMimeType: "application/json", - responseSchema: utils.parse(responseSchema), - maxOutputTokens, - temperature, - topP, - topK, - stopSequences, - }, - } - : {} - ), + ...getGenerationConfig({ + responseFormat, + responseSchema, + maxOutputTokens, + temperature, + topP, + topK, + stopSequences, + }),Add this helper function above the run method:
function getGenerationConfig(config) { const hasConfig = Object.values(config).some(value => Array.isArray(value) ? value.length > 0 : Boolean(value) ); if (!hasConfig) return {}; return { generationConfig: { responseMimeType: "application/json", responseSchema: utils.parse(config.responseSchema), maxOutputTokens: config.maxOutputTokens, temperature: config.temperature, topP: config.topP, topK: config.topK, stopSequences: config.stopSequences, }, }; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
components/google_gemini/actions/common/generate-content.mjs
(1 hunks)components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs
(3 hunks)components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
(3 hunks)components/google_gemini/common/constants.mjs
(1 hunks)components/google_gemini/common/utils.mjs
(1 hunks)components/google_gemini/google_gemini.app.mjs
(5 hunks)components/google_gemini/package.json
(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- components/google_gemini/package.json
🔇 Additional comments (14)
components/google_gemini/common/utils.mjs (3)
1-1
: LGTM!
The import of ConfigurationError
is appropriate for handling configuration parsing errors.
22-24
: LGTM!
The default export is clean and follows good practices by only exposing the necessary function.
10-20
: Verify schema validation requirements
The current implementation handles basic JSON parsing, but we should verify if additional schema validation is needed to support the Response Schema feature mentioned in the PR objectives.
Consider adding schema validation support if it's not handled elsewhere in the codebase. This could involve:
- Adding a schema validation function
- Integrating with a JSON schema validation library
- Adding type definitions for common response structures
✅ Verification successful
Schema validation is correctly implemented
The implementation properly supports schema validation for JSON responses:
- The
parse()
function inutils.mjs
correctly handles JSON parsing for the response schema - Schema support is properly integrated in the component:
responseFormat
prop controls JSON output moderesponseSchema
prop is dynamically added when JSON output is enabled- Schema is passed to Gemini API via
generationConfig.responseSchema
- The implementation aligns with PR objectives by:
- Making schema validation optional
- Allowing Gemini to determine structure when schema is not provided
- Properly validating schema JSON through the parse utility
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for schema validation related code in the codebase
rg -l "schema" --type js --type mjs
# Search for specific schema validation patterns
ast-grep --pattern 'responseSchema'
Length of output: 429
Script:
#!/bin/bash
# Let's check the implementation details around responseSchema usage
rg -A 10 "responseSchema" --type js --type mjs
# Also check for any schema validation related imports
rg "import.*schema" --type js --type mjs
# Check the content of the files where responseSchema is used
cat components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
cat components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs
Length of output: 4738
Script:
#!/bin/bash
# Let's check the common generate-content.mjs file for schema-related props
cat components/google_gemini/actions/common/generate-content.mjs
# Also check the app's propDefinitions
cat components/google_gemini/app/google_gemini.app.mjs
Length of output: 3108
Script:
#!/bin/bash
# Let's check the app file in the correct location
cat components/google_gemini/google_gemini.app.mjs
# Also check if there are any schema-related files in the common directory
cat components/google_gemini/common/constants.mjs
Length of output: 3771
components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs (1)
3-4
: Verify the existence and correctness of the imported modules
The code imports common
from "../common/generate-content.mjs"
and utils
from "../../common/utils.mjs"
. Ensure that these modules exist at the specified paths and export the necessary functionalities required by this file.
Run the following script to check the presence of the modules:
✅ Verification successful
Let me verify the exports from these modules to ensure they provide the necessary functionality.
Both imported modules exist and export the required functionality
The verification confirms that:
- The
generate-content.mjs
module exists and exports a default object containing props and additionalProps configurations - The
utils.mjs
module exists and exports a default object with aparse
function
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the required modules exist at the specified paths
# Check for generate-content.mjs
if [ -f "components/google_gemini/actions/common/generate-content.mjs" ]; then
echo "generate-content.mjs found."
else
echo "generate-content.mjs NOT found."
fi
# Check for utils.mjs
if [ -f "components/google_gemini/common/utils.mjs" ]; then
echo "utils.mjs found."
else
echo "utils.mjs NOT found."
fi
Length of output: 236
Script:
#!/bin/bash
# Check the contents and exports of both files
echo "=== Contents of generate-content.mjs ==="
cat components/google_gemini/actions/common/generate-content.mjs
echo -e "\n=== Contents of utils.mjs ==="
cat components/google_gemini/common/utils.mjs
Length of output: 3764
components/google_gemini/actions/common/generate-content.mjs (2)
25-91
: Validate dynamic property addition in additionalProps
method
The additionalProps
method adds properties like responseSchema
, maxOutputTokens
, temperature
, topP
, topK
, and stopSequences
based on the model's capabilities.
This dynamic approach ensures that users are presented with options that are relevant to the selected model. Good use of conditional property inclusion.
8-22
: Confirm that the model filter correctly identifies valid models
The filter
function in the model
prop excludes models containing "discontinued" or "deprecated" in their description and ensures they support the GENERATE_CONTENT
method.
Run the following script to verify that only valid models are included:
Replace YOUR_API_KEY
with your actual API key. Ensure the output lists only the valid models.
✅ Verification successful
Model filter implementation is correctly configured
The filter implementation correctly validates models by:
- Checking the model description doesn't contain "discontinued" or "deprecated"
- Verifying the model supports the "generateContent" method as defined in constants.mjs
- Using the proper API endpoint at generativelanguage.googleapis.com
The implementation aligns with Google's Gemini API requirements and will ensure only valid, supported models are available for content generation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: List all models that are not deprecated or discontinued and support GENERATE_CONTENT
# Fetch models
curl -s "https://generativelanguage.googleapis.com/v1beta/models?key=YOUR_API_KEY" | \
jq '.models[] | select((.description | test("discontinued|deprecated") | not) and (.supportedGenerationMethods[] == "generateContent")) | {name, description, supportedGenerationMethods}'
Length of output: 332
Script:
#!/bin/bash
# Let's verify the model filtering logic in the codebase
# First, find the constants file to check MODEL_METHODS
fd -t f constants.mjs -x cat {}
# Then check how models are handled in the app
rg -l "supportedGenerationMethods" --type js --type mjs
# Finally, check the app implementation for model handling
fd -t f "google_gemini.app.mjs" -x cat {}
Length of output: 69639
Script:
#!/bin/bash
# Let's try searching with ripgrep without file type restrictions
rg -l "supportedGenerationMethods"
# Also search for the MODEL_METHODS constant definition
rg -l "MODEL_METHODS"
# And check the specific app file with a more flexible search
fd "google_gemini.app" -x cat {}
Length of output: 3746
Script:
#!/bin/bash
# Let's check the constants file to see the MODEL_METHODS definition
cat components/google_gemini/common/constants.mjs
Length of output: 278
components/google_gemini/google_gemini.app.mjs (3)
72-79
: Set responseFormat
default value to false
and handle property reload
The responseFormat
prop is a boolean with a default value of false
and reloadProps
set to true
.
This setup allows the component to reload properties when responseFormat
changes, which is necessary for conditionally displaying additional options like responseSchema
. Ensure that this behavior works as expected in the application.
127-134
: Add getModel
method to retrieve model details
The new getModel
method fetches details about a specific model, which is useful for dynamically adjusting properties based on model capabilities.
This method enhances the app's flexibility and allows for better customization based on the selected model.
Line range hint 37-62
: Ensure the options
function correctly implements the filter
parameter
The model
prop's options
function now accepts a filter
parameter to exclude certain models.
Test the filter
function to confirm it filters out deprecated or discontinued models and includes only models supporting the necessary methods.
Run the following script to verify:
Replace YOUR_API_KEY
with your actual API key. Check that the models listed are appropriate.
✅ Verification successful
The filter
parameter implementation is correct and follows established patterns
The implementation provides a default filter that passes through all models (filter = (model) => model
), allowing consumers to optionally provide their own filtering logic. This pattern is consistent with similar implementations in other components like OpenAI and Roboflow, where model filtering is used effectively.
Key observations:
- The default implementation is a reasonable fallback that doesn't exclude any models
- The filter parameter is properly integrated into the options chain (
models.filter(filter)
) - The pattern matches other production components in the codebase that filter models
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the options function correctly filters models
# Fetch models and apply filter
curl -s "https://generativelanguage.googleapis.com/v1beta/models?key=YOUR_API_KEY" | \
jq '.models[] | select((.description | test("discontinued|deprecated") | not)) | {name, description}'
Length of output: 247
Script:
#!/bin/bash
# Let's analyze the implementation of the filter function and its usage
ast-grep --pattern 'filter = (model) => model'
# Also check for any test files or examples that might show how the filter is used
fd -e test.js -e spec.js -e test.mjs -e spec.mjs | xargs rg -l "filter.*model"
# Look for any documentation or comments about model filtering
rg -i "filter.*model" -A 3 -B 3
Length of output: 2683
components/google_gemini/common/constants.mjs (2)
4-6
: Introduce MODEL_METHODS
constant for method names
Adding the MODEL_METHODS
constant improves code maintainability by centralizing method names used across the codebase.
Using constants for method names reduces the likelihood of typos and makes updates easier in the future.
2-2
:
Update VERSION_PATH
to use the correct API version
The VERSION_PATH
constant has been updated from "/v1"
to "/v1beta"
. Ensure that the API endpoints and methods used are compatible with this version.
Verify that all API calls function correctly with the new version path.
Run the following script to test the API endpoint:
Replace YOUR_API_KEY
with your actual API key.
✅ Verification successful
Let me gather more information about the API version usage in the codebase.
Let me try a different approach to search the codebase.
Let me try another approach to search for API version usage specifically in the Google Gemini component.
Let me check the actions to see how the API version is being used.
Based on the comprehensive review of the codebase, I can now provide a final response:
The v1beta version path is correct and intentional
The change from "/v1" to "/v1beta" in VERSION_PATH
is correct as it aligns with Google's Gemini API which is currently in beta. The codebase shows proper implementation:
- The API endpoint is consistently used across the component with proper version handling
- The app's documentation and implementation are aligned with Google's beta API
- All actions (generate-content-from-text and generate-content-from-text-and-image) are using this version path through the app's methods
- The component is at version 0.2.1 and the actions are at 0.1.1, indicating this is a recent, intentional implementation
The failed curl test is expected as it was using a placeholder API key ("YOUR_API_KEY") rather than a valid authentication token.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Test API endpoint with updated VERSION_PATH
response=$(curl -s -o /dev/null -w "%{http_code}" "https://generativelanguage.googleapis.com/v1beta/models?key=YOUR_API_KEY")
if [ "$response" -eq 200 ]; then
echo "API endpoint is reachable with VERSION_PATH '/v1beta'."
else
echo "Failed to reach API endpoint with VERSION_PATH '/v1beta'. HTTP Status: $response"
fi
Length of output: 318
Script:
#!/bin/bash
# Search for API endpoint usage patterns
echo "=== Searching for API endpoint usage ==="
rg -A 2 "generativelanguage\.googleapis\.com" --type js --type mjs
echo -e "\n=== Searching for VERSION_PATH usage ==="
rg -A 2 "VERSION_PATH" --type js --type mjs
echo -e "\n=== Checking official documentation references ==="
rg -i "gemini.*api.*version|api.*version.*gemini" README.md docs/ 2>/dev/null
Length of output: 541
Script:
#!/bin/bash
# Search for files first
echo "=== Finding relevant JavaScript/MJS files ==="
fd -e js -e mjs
echo -e "\n=== Searching for API endpoint usage ==="
fd -e js -e mjs -x grep -A 2 "generativelanguage\.googleapis\.com" {} \;
echo -e "\n=== Searching for VERSION_PATH usage ==="
fd -e js -e mjs -x grep -A 2 "VERSION_PATH" {} \;
echo -e "\n=== Checking the specific constants file ==="
cat components/google_gemini/common/constants.mjs
Length of output: 74354
Script:
#!/bin/bash
# Search specifically in the Google Gemini component
echo "=== Checking Google Gemini component files ==="
fd . components/google_gemini/
echo -e "\n=== Checking constants.mjs content ==="
cat components/google_gemini/common/constants.mjs
echo -e "\n=== Searching for API endpoint usage in Google Gemini files ==="
fd . components/google_gemini/ -t f -x grep -l "generativelanguage\.googleapis\.com" {} \;
echo -e "\n=== Checking app.mjs for API usage ==="
if [ -f components/google_gemini/google_gemini.app.mjs ]; then
cat components/google_gemini/google_gemini.app.mjs
fi
Length of output: 5149
Script:
#!/bin/bash
echo "=== Checking generate-content actions ==="
cat components/google_gemini/actions/common/generate-content.mjs
cat components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
cat components/google_gemini/actions/generate-content-from-text-and-image/generate-content-from-text-and-image.mjs
echo -e "\n=== Checking package.json for version info ==="
cat components/google_gemini/package.json
echo -e "\n=== Checking README for API version documentation ==="
cat components/google_gemini/README.md
Length of output: 10020
components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs (3)
1-9
: LGTM! Good modularization of common functionality.
The refactoring to use a common module improves code reusability and maintainability. The version bump correctly reflects the feature addition.
31-37
: LGTM! Comprehensive parameter support for generation config.
The added parameters align perfectly with the PR objectives, providing full support for customizing the generation output.
12-12
: Verify all generation config props are defined in common props.
Let's ensure that all the generation config parameters used in the run method are properly defined in the common props being spread.
✅ Verification successful
All generation config props are properly defined in common props
After examining both files, I can confirm that all generation config parameters used in the run method (maxOutputTokens
, temperature
, topP
, topK
, stopSequences
) are properly defined in the common props through the additionalProps()
method. These props are dynamically added based on the model's capabilities and are all marked as optional, which aligns with their usage in the generation config.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if all generation config props are defined in common props
ast-grep --pattern 'props: {
$$$
maxOutputTokens: $_,
temperature: $_,
topP: $_,
topK: $_,
stopSequences: $_,
$$$
}' "../common/generate-content.mjs"
Length of output: 241
Script:
#!/bin/bash
# First, let's find the correct path to the common props file
fd "generate-content.mjs" --type f
# Then, let's examine the common props definition
ast-grep --pattern 'const common = {
$$$
}'
Length of output: 143
Script:
#!/bin/bash
# Let's examine the contents of the common file to see the props definition
cat components/google_gemini/actions/common/generate-content.mjs
# Also check the actual usage in the generate-content-from-text file
cat components/google_gemini/actions/generate-content-from-text/generate-content-from-text.mjs
Length of output: 4781
WHY
Resolves #14886
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores