-
Notifications
You must be signed in to change notification settings - Fork 839
feat: Integrate Google Gemini API support #859
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
feat: Integrate Google Gemini API support #859
Conversation
Adds support for using the Google Gemini API via an API key. Key changes include: - Configuration: - Added `geminiApiKey` to `defaultConfig` in `src/config/index.mjs`. - Defined `geminiApiModelKeys` and added 'Gemini (API, Pro)' to `Models` and `ModelGroups`. - Added 'geminiApiPro' to the default `activeApiModes`. - API Client: - Created `src/services/apis/gemini-api.mjs` with logic to connect to the Gemini API using the configured API key. Includes placeholder for the exact API endpoint and payload structure. - User Interface: - Added an input field in `src/popup/sections/GeneralPart.jsx` for you to enter your Gemini API key. This field is conditionally displayed when a Gemini API model is active. - Integration: - Updated `src/background/index.mjs` to route requests to the `generateAnswersWithGeminiApi` client when a Gemini model is selected. Manual testing with a valid Gemini API key is required to fully verify the functionality.
@Copilot
Copilot
AI
left a comment
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.
Pull Request Overview
This PR introduces support for the Google Gemini API by integrating a new API client, updating configuration, and adding a user interface input for the Gemini API key.
- Added a new service module for communicating with the Gemini API.
- Updated configuration and UI components to handle the Gemini API key.
- Integrated Gemini API support in the background routing for generating answers.
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
src/services/apis/gemini-api.mjs | New API client added to connect to the Gemini API. |
src/popup/sections/GeneralPart.jsx | Added conditional input field for Gemini API key. |
src/config/index.mjs | Updated configuration with Gemini API keys and models. |
src/background/index.mjs | Routed requests to the new Gemini API client. |
Copilot
AI
May 31, 2025
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.
In React, the style prop should be provided as an object (e.g., style={{ width: '50%' }}) rather than a string literal to ensure proper rendering.
Copilot uses AI. Check for mistakes.
/review
Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.
PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
Sensitive information exposure:
The PR adds a new API key field for Gemini in the UI. While the input is properly set as type="password" to mask the key visually, there should be additional checks to ensure the API key is stored securely and not exposed in logs or network requests (beyond the authenticated API call itself). The current implementation directly includes the API key as a query parameter in line 38, which could expose it in server logs. Consider using an Authorization header instead.
Error Handling
The error handling in the Gemini API client could be improved. The code attempts to extract error messages from the response but may not handle all error scenarios correctly, especially when the response structure is different than expected.
if (!response.ok) {
const errorData = await response.json().catch(() => ({ message: response.statusText }));
console.error('Gemini API error:', errorData);
port.postMessage({ error: `Gemini API error: ${errorData.error?.message || errorData.message || 'Unknown error'}`, done: true, session });
return;
}
API Implementation
The Gemini API implementation is using placeholder structures that need verification against the actual API documentation. The payload structure and response parsing logic may need adjustments to match Google's Gemini API specifications.
// Construct the request payload // This is a placeholder structure and needs to be verified against Gemini API documentation const payload = { contents: [{ parts: [{ text: question, }], }], // generationConfig: { // Optional: configure temperature, maxOutputTokens, etc. // temperature: config.temperature, // maxOutputTokens: config.maxResponseTokenLength, // }, // safetySettings: [ // Optional: configure safety settings // { category: 'HARM_CATEGORY_HARASSMENT', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // { category: 'HARM_CATEGORY_HATE_SPEECH', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // { category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // { category: 'HARM_CATEGORY_DANGEROUS_CONTENT', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // ], }; const response = await fetch(`${GEMINI_API_ENDPOINT}?key=${apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ message: response.statusText })); console.error('Gemini API error:', errorData); port.postMessage({ error: `Gemini API error: ${errorData.error?.message || errorData.message || 'Unknown error'}`, done: true, session }); return; } const responseData = await response.json(); // Extract the answer from the responseData // This is a placeholder and needs to be verified against actual Gemini API response structure // Expected structure: responseData.candidates[0].content.parts[0].text let answer = 'No response from Gemini API.'; if (responseData.candidates && responseData.candidates[0] && responseData.candidates[0].content && responseData.candidates[0].content.parts && responseData.candidates[0].content.parts[0]) { answer = responseData.candidates[0].content.parts[0].text; } else { console.error('Unexpected Gemini API response structure:', responseData); }
Missing Conversation History
The implementation doesn't appear to handle conversation history properly. Unlike other API implementations, it doesn't seem to send previous messages in the conversation to maintain context.
const payload = { contents: [{ parts: [{ text: question, }], }], // generationConfig: { // Optional: configure temperature, maxOutputTokens, etc. // temperature: config.temperature, // maxOutputTokens: config.maxResponseTokenLength, // }, // safetySettings: [ // Optional: configure safety settings // { category: 'HARM_CATEGORY_HARASSMENT', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // { category: 'HARM_CATEGORY_HATE_SPEECH', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // { category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // { category: 'HARM_CATEGORY_DANGEROUS_CONTENT', threshold: 'BLOCK_MEDIUM_AND_ABOVE' }, // ], };
/improve
Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here. PR Code Suggestions ✨
|
5d81453
to
ffad115
Compare
Adds support for using the Google Gemini API via an API key.
Key changes include:
Configuration:
geminiApiKey
todefaultConfig
insrc/config/index.mjs
.geminiApiModelKeys
and added 'Gemini (API, Pro)' toModels
andModelGroups
.activeApiModes
.API Client:
src/services/apis/gemini-api.mjs
with logic to connect to the Gemini API using the configured API key. Includes placeholder for the exact API endpoint and payload structure.User Interface:
src/popup/sections/GeneralPart.jsx
for you to enter your Gemini API key. This field is conditionally displayed when a Gemini API model is active.Integration:
src/background/index.mjs
to route requests to thegenerateAnswersWithGeminiApi
client when a Gemini model is selected.Manual testing with a valid Gemini API key is required to fully verify the functionality.