-
Notifications
You must be signed in to change notification settings - Fork 489
feat: add Gemini CLI provider integration #647
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: add Gemini CLI provider integration #647
Conversation
- Add GeminiProvider class extending CliProvider for Gemini CLI integration - Add Gemini models (Gemini 3 Pro/Flash Preview, 2.5 Pro/Flash/Flash-Lite) - Add gemini-models.ts with model definitions and types - Update ModelProvider type to include 'gemini' - Add isGeminiModel() to provider-utils.ts for model detection - Register Gemini provider in provider-factory with priority 4 - Add Gemini setup detection routes (status, auth, deauth) - Add GeminiCliStatus to setup store for UI state management - Add Gemini to PROVIDER_ICON_COMPONENTS for UI icon display - Add GEMINI_MODELS to model-display for dropdown population - Support thinking levels: off, low, medium, high Based on https://github.com/google-gemini/gemini-cli
- Add GeminiCliStatus component for CLI detection display - Add GeminiSettingsTab component for global settings - Update provider-tabs.tsx to include Gemini as 5th tab - Update providers-setup-step.tsx with Gemini provider detection - Add useGeminiCliStatus hook for querying CLI status - Add getGeminiStatus, authGemini, deauthGemini to HTTP API client - Add gemini query key for React Query - Fix GeminiModelId type to not double-prefix model IDs
…ini-provider-o0dx8
- Add 'gemini-provider' to SettingsViewId type - Add GeminiIcon and gemini-provider to navigation config - Add gemini-provider to NAV_ID_TO_PROVIDER mapping - Add gemini-provider case in settings-view switch - Export GeminiSettingsTab from providers index This fixes the missing Gemini entry in the AI Providers sidebar menu.
- Create GeminiModelConfiguration component for model selection - Add enabledGeminiModels and geminiDefaultModel state to app-store - Add setEnabledGeminiModels, setGeminiDefaultModel, toggleGeminiModel actions - Update GeminiSettingsTab to show model configuration when CLI is installed - Import GeminiModelId and getAllGeminiModelIds from types This adds the ability to configure which Gemini models are available in the feature modal, similar to other providers like Codex and OpenCode.
- Add GEMINI_MODELS to model-constants.ts for UI dropdowns - Add Gemini to ALL_MODELS array used throughout the app - Add GeminiIcon to PROFILE_ICONS mapping - Fix GEMINI_MODELS in model-display.ts to use correct model IDs - Update getModelDisplayName to handle Gemini models correctly Gemini models now appear in all model selection dropdowns including Model Defaults, Feature Defaults, and feature card settings.
- Fix model ID prefix handling: strip gemini- prefix in agent-service, add it back in buildCliArgs for CLI invocation - Fix event normalization to match actual Gemini CLI output format: - type: 'init' (not 'system') - type: 'message' with role (not 'assistant') - tool_name/tool_id/parameters/output field names - Add --sandbox false and --approval-mode yolo for faster execution - Remove thinking level selector from UI (Gemini CLI doesn't support it) - Update auth status to show errors properly
…ini-provider-o0dx8
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughAdds first-class Gemini CLI support across server, types, and UI: a new GeminiProvider with CLI streaming, setup routes for status/auth, Gemini model types and registration, UI settings/setup components and hooks, store/state changes, and tests updated to include Gemini. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as User / UI
participant API as Server API
participant CLI as Gemini CLI (local)
participant FS as File System
UI->>API: GET /api/setup/gemini-status
API->>FS: stat .automaker/.gemini-disconnected
alt marker present
FS-->>API: marker found
API-->>UI: installed: true?, auth: none
else
API->>CLI: detect installation & version (spawn/check path)
CLI-->>API: version/path or not installed
API->>CLI: check auth (env/API key/credentials file)
CLI-->>API: auth status
API-->>UI: installed/version/path/auth info
end
UI->>API: POST /api/setup/auth-gemini
API->>FS: unlink .gemini-disconnected (if exists)
FS-->>API: removed
API-->>UI: { success: true }
UI->>API: POST /api/setup/deauth-gemini
API->>FS: write .gemini-disconnected marker
FS-->>API: written
API-->>UI: { success: true }
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @stefandevo, 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 a significant new feature by integrating Google's Gemini CLI as a first-class AI provider. It enables users to leverage Gemini's advanced models directly within the application, offering a seamless experience for model selection, authentication, and execution. The changes span both the backend, with a new provider implementation, and the frontend, with extensive UI updates to ensure full configurability and status visibility for Gemini. 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. 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.
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 introduces a comprehensive integration for the Gemini CLI provider, covering backend logic, API routes, and UI components. The implementation is thorough, but there are a few critical issues to address. The npm package name for the Gemini CLI is incorrect in several places, which will prevent users from installing it correctly. There are also several instances of synchronous file system operations within asynchronous functions, which should be converted to asynchronous calls to avoid blocking the event loop. Finally, some TypeScript interfaces for Gemini stream events are inconsistent with the documented data format, which could lead to confusion and maintenance issues.
apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx
Outdated
Show resolved
Hide resolved
- Add GeminiProvider import and spy mock - Update expected provider count from 4 to 5 - Add test for GeminiProvider inclusion - Add gemini key to checkAllProviders test
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: 11
🤖 Fix all issues with AI agents
In `@apps/server/src/providers/gemini-provider.ts`:
- Around line 431-436: The user-facing install string in
getInstallInstructions() is wrong — replace the placeholder package name
`@anthropic-ai/gemini-cli` with the correct Gemini CLI package (or change the
message to clearly indicate it's pending/placeholder), e.g., update the return
value of protected getInstallInstructions() to either the accurate package name
for Gemini CLI or a “TBD/see docs” phrasing so the instruction is not
misleading.
- Around line 150-154: The npxPackage value in getSpawnConfig() is using the
wrong npm namespace; update the npxPackage field in the getSpawnConfig() method
of the Gemini provider to use the official package name "@google/gemini-cli"
instead of "@anthropic-ai/gemmini-cli" (locate the npxPackage property in
getSpawnConfig() and replace the string with "@google/gemini-cli").
In `@apps/server/src/providers/provider-factory.ts`:
- Around line 307-313: Tests expecting 4 providers must be updated to account
for the new Gemini registration: find assertions and helpers that check provider
counts (e.g., calls to getAllProviders() and checkAllProviders(), any
EXPECTED_PROVIDER_COUNT or similar constants) and change expected values from 4
to 5 (or update snapshots that assert provider list length), and add/adjust any
assertions that validate provider identities to include 'gemini' (or its alias
'google') so the tests reflect the new provider registration in
factory.registerProvider('gemini', ...).
In `@apps/ui/src/components/views/board-view/shared/model-constants.ts`:
- Around line 131-140: GEMINI_MODELS constructs ModelOption entries using
GEMINI_MODEL_MAP but sets badge to undefined for non-thinking models, causing
inconsistency with the fallback 'Speed' used elsewhere; update the badge logic
in GEMINI_MODELS (and related fields if present) to use 'Speed' as the fallback
(e.g., set badge to config.supportsThinking ? 'Thinking' : 'Speed') so that
badge, hasThinking, id, label and description remain consistent with the display
expectations.
In
`@apps/ui/src/components/views/settings-view/providers/gemini-settings-tab.tsx`:
- Around line 30-41: The mapping in the useMemo for cliStatus ignores the
server's installCommand and loginCommand fields and returns installCommands
(plural) only; update the transform in the cliStatus useMemo to read
cliStatusData.installCommand and cliStatusData.loginCommand and forward them on
the returned object (or normalize names to match SharedCliStatus), and if
SharedCliStatus lacks a loginCommand field, extend SharedCliStatus to include
loginCommand so the UI receives both install and login hints from the API.
In `@apps/ui/src/components/views/settings-view/providers/provider-tabs.tsx`:
- Line 3: The import line for provider icons (AnthropicIcon, CursorIcon,
OpenAIIcon, GeminiIcon, OpenCodeIcon) is not Prettier-formatted; run the
project's Prettier config (or your editor formatter) on
apps/ui/src/components/views/settings-view/providers/provider-tabs.tsx and
reformat the import statement so it conforms to the project's style (line
breaks/spacing as configured) and clears the pipeline formatting warning.
In `@apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx`:
- Line 34: The import statement pulling AnthropicIcon, CursorIcon, OpenAIIcon,
OpenCodeIcon, and GeminiIcon from '@/components/ui/provider-icon' is triggering
Prettier formatting errors; reformat the import (or run the project's Prettier)
so it conforms to the project's line-length rules—e.g., split the long import
across multiple lines or let Prettier rewrite it—ensuring the module name
provider-icon and the named exports AnthropicIcon, CursorIcon, OpenAIIcon,
OpenCodeIcon, and GeminiIcon remain unchanged.
- Around line 1391-1397: The fallback install command currently uses the wrong
package name; update both usages of the literal fallback string that reference
geminiCliStatus?.installCommand (the displayed command and the value passed into
copyCommand) to use 'npm install -g `@google/gemini-cli`' instead of
'@anthropic/gemini-cli' so that the UI and the copy action show/install the
official Gemini CLI package.
In `@apps/ui/src/store/app-store.ts`:
- Around line 2752-2761: Add the Gemini settings to the settings sync list by
including the keys for enabledGeminiModels and geminiDefaultModel in the
SETTINGS_FIELDS_TO_SYNC array in use-settings-sync.ts so those values set by
setEnabledGeminiModels, setGeminiDefaultModel and toggleGeminiModel persist
across sessions; also add the analogous Codex keys (e.g., enabledCodexModels and
codexDefaultModel) to the same SETTINGS_FIELDS_TO_SYNC array so Codex settings
persist alongside the existing Cursor and OpenCode provider settings.
In `@apps/ui/src/store/setup-store.ts`:
- Around line 66-79: The GeminiCliStatus interface is missing the hasEnvApiKey
field in its auth object; update the GeminiCliStatus definition so the auth
property includes hasEnvApiKey?: boolean (optional) alongside authenticated,
method, and hasApiKey to match server responses and preserve API parity for
environment-key auth state.
In `@libs/types/src/gemini-models.ts`:
- Around line 83-88: The comment for the GeminiThinkingLevel type incorrectly
states it maps to a CLI flag; update the JSDoc for GeminiThinkingLevel to
clarify that these values represent the Gemini API's thinking control
(thinkingLevel/thinkingBudget) rather than a currently supported CLI flag, or
remove the CLI flag reference entirely so the comment accurately describes
API-level usage; locate the export type GeminiThinkingLevel and edit its
preceding comment accordingly.
🧹 Nitpick comments (2)
apps/server/src/routes/setup/routes/auth-gemini.ts (1)
17-39: Consider using async fs operations for consistency.The handler is declared
asyncbut uses synchronousfs.existsSyncandfs.unlinkSync. While this works fine for quick file operations, usingfs.promiseswould be more consistent with the async handler pattern and avoid blocking the event loop:♻️ Optional refactor using async fs
import type { Request, Response } from 'express'; import { getErrorMessage, logError } from '../common.js'; -import * as fs from 'fs'; +import * as fs from 'fs/promises'; import * as path from 'path'; const DISCONNECTED_MARKER_FILE = '.gemini-disconnected'; export function createAuthGeminiHandler() { return async (_req: Request, res: Response): Promise<void> => { try { const projectRoot = process.cwd(); const automakerDir = path.join(projectRoot, '.automaker'); const markerPath = path.join(automakerDir, DISCONNECTED_MARKER_FILE); // Remove the disconnection marker if it exists - if (fs.existsSync(markerPath)) { - fs.unlinkSync(markerPath); - } + try { + await fs.unlink(markerPath); + } catch { + // File doesn't exist, nothing to remove + } res.json({ success: true, message: 'Gemini CLI connected to app', }); } catch (error) { logError(error, 'Auth Gemini failed'); res.status(500).json({ success: false, error: getErrorMessage(error), }); } }; }apps/ui/src/components/views/settings-view/cli-status/gemini-cli-status.tsx (1)
9-22: Reuse shared Gemini auth types to avoid drift.
These types are already defined in@automaker/types. Prefer importing the shared type and deriving the method union locally. As per coding guidelines, ...♻️ Suggested refactor
-import type { CliStatus } from '../shared/types'; +import type { CliStatus } from '../shared/types'; +import type { GeminiAuthStatus } from '@automaker/types'; import { GeminiIcon } from '@/components/ui/provider-icon'; -export type GeminiAuthMethod = - | 'api_key' - | 'google_login' - | 'vertex_ai' - | 'none'; - -export interface GeminiAuthStatus { - authenticated: boolean; - method: GeminiAuthMethod; - hasApiKey?: boolean; - hasEnvApiKey?: boolean; - hasCredentialsFile?: boolean; - error?: string; -} +type GeminiAuthMethod = GeminiAuthStatus['method'];
| // Register Gemini provider | ||
| registerProvider('gemini', { | ||
| factory: () => new GeminiProvider(), | ||
| aliases: ['google'], | ||
| canHandleModel: (model: string) => isGeminiModel(model), | ||
| priority: 4, // Between opencode (3) and codex (5) | ||
| }); |
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.
Update provider-count tests for the new Gemini registration.
CI reports failures because provider counts now return 5 instead of 4. Please update the test expectations for getAllProviders() and checkAllProviders() to account for Gemini.
🤖 Prompt for AI Agents
In `@apps/server/src/providers/provider-factory.ts` around lines 307 - 313, Tests
expecting 4 providers must be updated to account for the new Gemini
registration: find assertions and helpers that check provider counts (e.g.,
calls to getAllProviders() and checkAllProviders(), any EXPECTED_PROVIDER_COUNT
or similar constants) and change expected values from 4 to 5 (or update
snapshots that assert provider list length), and add/adjust any assertions that
validate provider identities to include 'gemini' (or its alias 'google') so the
tests reflect the new provider registration in
factory.registerProvider('gemini', ...).
| // Transform CLI status to the expected format | ||
| const cliStatus = useMemo((): SharedCliStatus | null => { | ||
| if (!cliStatusData) return null; | ||
| return { | ||
| success: cliStatusData.success ?? false, | ||
| status: cliStatusData.installed ? 'installed' : 'not_installed', | ||
| method: cliStatusData.auth?.method, | ||
| version: cliStatusData.version, | ||
| path: cliStatusData.path, | ||
| recommendation: cliStatusData.recommendation, | ||
| installCommands: cliStatusData.installCommands, | ||
| }; |
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.
Map install/login commands from the API payload.
The server responds with installCommand and loginCommand, but the mapping reads installCommands and never forwards loginCommand, so install/login hints can disappear in the UI. Consider normalizing here (and extending SharedCliStatus if needed).
🛠️ Suggested update
return {
success: cliStatusData.success ?? false,
status: cliStatusData.installed ? 'installed' : 'not_installed',
method: cliStatusData.auth?.method,
version: cliStatusData.version,
path: cliStatusData.path,
- recommendation: cliStatusData.recommendation,
- installCommands: cliStatusData.installCommands,
+ recommendation: cliStatusData.recommendation,
+ installCommands: cliStatusData.installCommand
+ ? [cliStatusData.installCommand]
+ : cliStatusData.installCommands,
+ loginCommand: cliStatusData.loginCommand,
};🤖 Prompt for AI Agents
In `@apps/ui/src/components/views/settings-view/providers/gemini-settings-tab.tsx`
around lines 30 - 41, The mapping in the useMemo for cliStatus ignores the
server's installCommand and loginCommand fields and returns installCommands
(plural) only; update the transform in the cliStatus useMemo to read
cliStatusData.installCommand and cliStatusData.loginCommand and forward them on
the returned object (or normalize names to match SharedCliStatus), and if
SharedCliStatus lacks a loginCommand field, extend SharedCliStatus to include
loginCommand so the UI receives both install and login hints from the API.
apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx
Outdated
Show resolved
Hide resolved
apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx
Outdated
Show resolved
Hide resolved
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: 1
🤖 Fix all issues with AI agents
In `@apps/server/src/providers/provider-factory.ts`:
- Around line 313-319: The test comment references the wrong line numbers for
the assertion about gemini-3-pro routing; update the test's assertion comment to
point to lines 160-163 (not 156-159) and/or adjust any inline note near the
assertion that mentions line numbers so it correctly documents that
getProviderForModelName() chooses Cursor over Gemini due to Cursor's higher
priority; check related symbols LEGACY_CURSOR_MODEL_MAP, isCursorModel,
getProviderForModelName, and the provider registration for 'gemini'
(registerProvider('gemini', ... priority: 4)) to ensure the comment accurately
reflects the current provider priority and legacy model mapping behavior.
♻️ Duplicate comments (2)
apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx (2)
34-40: LGTM on the import addition.The
GeminiIconimport follows the project's path alias conventions. The formatting issue was already flagged in a previous review.
1393-1410: Wrong package name in fallback install command.The fallback uses
@anthropic/gemini-clibut the official package is@google/gemini-cli. This affects both the displayed command (line 1397) and the copied command (line 1404).🐛 Proposed fix
<code className="flex-1 bg-muted px-3 py-2 rounded text-sm font-mono text-foreground overflow-x-auto"> - {geminiCliStatus?.installCommand || 'npm install -g `@anthropic/gemini-cli`'} + {geminiCliStatus?.installCommand || 'npm install -g `@google/gemini-cli`'} </code> <Button variant="ghost" size="icon" onClick={() => copyCommand( - geminiCliStatus?.installCommand || 'npm install -g `@anthropic/gemini-cli`' + geminiCliStatus?.installCommand || 'npm install -g `@google/gemini-cli`' ) } >
🧹 Nitpick comments (2)
apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx (1)
1750-1756: Consider using a distinct color for Gemini.Gemini uses
'text-blue-500'which is the same as Cursor. For visual differentiation, consider using a Gemini-associated color (e.g.,'text-purple-500'or'text-indigo-500'to align with Google's Gemini branding).♻️ Suggested change
{ id: 'gemini' as const, label: 'Gemini', icon: GeminiIcon, status: getProviderStatus(isGeminiInstalled, isGeminiAuthenticated), - color: 'text-blue-500', + color: 'text-purple-500', },apps/server/tests/unit/providers/provider-factory.test.ts (1)
221-222: Consider adding tests for Gemini-specific provider lookups.The current coverage verifies Gemini is present in the provider list, but there are no tests for:
getProviderByName('gemini')returning GeminiProvidergetProviderByName('google')returning GeminiProvider (alias support)- Gemini model routing via
getProviderForModel('gemini-2.5-flash')These would ensure the registration and alias configuration work correctly.
| // Register Gemini provider | ||
| registerProvider('gemini', { | ||
| factory: () => new GeminiProvider(), | ||
| aliases: ['google'], | ||
| canHandleModel: (model: string) => isGeminiModel(model), | ||
| priority: 4, // Between opencode (3) and codex (5) | ||
| }); |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
echo "=== Checking provider-factory.ts for Gemini and other provider priorities ==="
rg -n "priority:" --type ts apps/server/src/providers/provider-factory.ts
echo ""
echo "=== Looking for test file with gemini-3-pro routing test ==="
fd -e test.ts -e spec.ts | xargs grep -l "gemini-3-pro" 2>/dev/null | head -5Repository: AutoMaker-Org/automaker
Length of output: 559
🏁 Script executed:
#!/bin/bash
echo "=== Checking isGeminiModel and isCursorModel implementation ==="
rg -n "isGeminiModel|isCursorModel" --type ts -A 10 libs/types/src/provider-utils.ts
echo ""
echo "=== Looking for Cursor model map definitions ==="
rg -n "CursorModel|cursorModels" --type ts libs/ -A 5 | head -50Repository: AutoMaker-Org/automaker
Length of output: 4737
🏁 Script executed:
#!/bin/bash
echo "=== Checking if Cursor provider includes gemini models ==="
rg -n "gemini" --type ts libs/ apps/ | grep -i "cursor\|model" | head -20Repository: AutoMaker-Org/automaker
Length of output: 1697
🏁 Script executed:
#!/bin/bash
echo "=== Checking test file lines 156-159 ==="
sed -n '150,165p' apps/server/tests/unit/providers/provider-factory.test.ts
echo ""
echo "=== Checking if gemini-3-pro is in GEMINI_MODEL_MAP ==="
rg -n "gemini-3-pro|gemini-3-flash" --type ts libs/types/src/gemini-models.ts -B 2 -A 2
echo ""
echo "=== Checking LEGACY_CURSOR_MODEL_MAP for gemini models ==="
rg -n "LEGACY_CURSOR_MODEL_MAP|gemini-3" --type ts libs/types/src/cursor-models.ts | head -20Repository: AutoMaker-Org/automaker
Length of output: 1758
🏁 Script executed:
#!/bin/bash
echo "=== Check full GEMINI_MODEL_MAP structure ==="
cat libs/types/src/gemini-models.ts | head -50Repository: AutoMaker-Org/automaker
Length of output: 1483
🏁 Script executed:
#!/bin/bash
echo "=== Verify the actual check order and model routing logic ==="
sed -n '160,195p' libs/types/src/provider-utils.tsRepository: AutoMaker-Org/automaker
Length of output: 1163
🏁 Script executed:
#!/bin/bash
echo "=== Check ProviderFactory.getProviderForModel implementation ==="
rg -n "getProviderForModel" --type ts apps/server/src/providers/provider-factory.ts -A 20Repository: AutoMaker-Org/automaker
Length of output: 2817
🏁 Script executed:
#!/bin/bash
echo "=== Check if there's special handling that overrides getModelProvider ==="
rg -n "gemini-3-pro|LEGACY_CURSOR_MODEL_MAP" --type ts apps/server/src/providers/ -B 3 -A 3Repository: AutoMaker-Org/automaker
Length of output: 140
🏁 Script executed:
#!/bin/bash
echo "=== Check Cursor provider's canHandleModel implementation ==="
rg -n "canHandleModel" --type ts apps/server/src/providers/provider-factory.ts -B 5 -A 5 | grep -A 5 -B 5 "cursor"Repository: AutoMaker-Org/automaker
Length of output: 440
🏁 Script executed:
#!/bin/bash
echo "=== Get full provider registrations with canHandleModel details ==="
sed -n '280,330p' apps/server/src/providers/provider-factory.tsRepository: AutoMaker-Org/automaker
Length of output: 1357
Correct the line number reference for the test assertion.
The test at lines 160-163 (not 156-159) confirms that gemini-3-pro routes to CursorProvider. This is the correct behavior given the provider registration logic: getProviderForModelName() iterates through providers sorted by priority (descending), checking each canHandleModel function. Since Cursor has priority 10 and Gemini has priority 4, Cursor's canHandleModel is evaluated first. Both return true for gemini-3-pro (it's a legacy Cursor model in LEGACY_CURSOR_MODEL_MAP and starts with the gemini- prefix), but Cursor wins due to its higher priority.
The architectural concern remains valid: gemini-3-pro and gemini-3-flash are legacy Cursor model aliases, so they intentionally route to Cursor. If the Gemini CLI should handle its native models preferentially in the future, consider removing these models from LEGACY_CURSOR_MODEL_MAP or adjusting the logic in isCursorModel.
🤖 Prompt for AI Agents
In `@apps/server/src/providers/provider-factory.ts` around lines 313 - 319, The
test comment references the wrong line numbers for the assertion about
gemini-3-pro routing; update the test's assertion comment to point to lines
160-163 (not 156-159) and/or adjust any inline note near the assertion that
mentions line numbers so it correctly documents that getProviderForModelName()
chooses Cursor over Gemini due to Cursor's higher priority; check related
symbols LEGACY_CURSOR_MODEL_MAP, isCursorModel, getProviderForModelName, and the
provider registration for 'gemini' (registerProvider('gemini', ... priority: 4))
to ensure the comment accurately reflects the current provider priority and
legacy model mapping behavior.
- Fix npm package name from @anthropic-ai/gemini-cli to @google/gemini-cli - Fix comments in gemini-provider.ts to match actual CLI output format - Convert sync fs operations to async using fs/promises
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: 1
🤖 Fix all issues with AI agents
In `@apps/server/src/routes/setup/routes/deauth-gemini.ts`:
- Around line 16-42: Update the import that currently pulls getErrorMessage and
logError from a relative module to use the shared package namespace: replace the
relative import with import { getErrorMessage, logError } from
'@automaker/common' so the handler (createDeauthGeminiHandler) uses the shared
package; also apply the same change to the corresponding imports in
auth-gemini.ts and gemini-status.ts to keep consistency for getErrorMessage and
logError.
🧹 Nitpick comments (3)
apps/server/src/providers/gemini-provider.ts (3)
228-230: Consider adding runtime validation for incoming events.The type assertion
event as GeminiStreamEventon line 229 bypasses runtime type checking. If the CLI sends malformed JSON or an unexpected structure, this could lead to subtle bugs. Consider adding a validation check for thetypeproperty before processing.♻️ Suggested validation
normalizeEvent(event: unknown): ProviderMessage | null { - const geminiEvent = event as GeminiStreamEvent; + if (!event || typeof event !== 'object' || !('type' in event)) { + logger.debug('Received invalid event structure'); + return null; + } + const geminiEvent = event as GeminiStreamEvent;
536-550: Consider using async exec for version check.
execSyncon line 541 blocks the event loop. While the 5-second timeout limits exposure and this is called infrequently, consider using the asyncexecfromchild_process/promisesfor consistency with the async method signature.♻️ Suggested async version
+import { exec } from 'child_process/promises'; + async getVersion(): Promise<string | null> { this.ensureCliDetected(); if (!this.cliPath) return null; try { - const result = execSync(`"${this.cliPath}" --version`, { - encoding: 'utf8', + const { stdout } = await exec(`"${this.cliPath}" --version`, { timeout: 5000, - stdio: 'pipe', - }).trim(); - return result; + }); + return stdout.trim(); } catch { return null; } }
571-572: Redundant variable assignment.
hasEnvApiKeyis assigned the same value ashasApiKeyon line 572. If they're meant to track different things (e.g., env var vs settings file), the logic needs adjustment. Otherwise, consider removing the redundant variable.♻️ Suggested simplification
// Determine the likely auth method based on environment const hasApiKey = !!process.env.GEMINI_API_KEY; - const hasEnvApiKey = hasApiKey; const hasVertexAi = !!( process.env.GOOGLE_APPLICATION_CREDENTIALS || process.env.GOOGLE_CLOUD_PROJECT ); - logger.debug(`checkAuth: hasApiKey=${hasApiKey}, hasVertexAi=${hasVertexAi}`); + logger.debug(`checkAuth: hasApiKey=${hasApiKey}, hasVertexAi=${hasVertexAi}`);Then update return statements to use
hasApiKeyfor bothhasApiKeyandhasEnvApiKeyfields, or clarify the distinction if they should differ.
Add enabledGeminiModels, geminiDefaultModel, enabledCodexModels, and codexDefaultModel to SETTINGS_FIELDS_TO_SYNC for persistence across sessions.
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: 1
🤖 Fix all issues with AI agents
In `@apps/ui/src/hooks/use-settings-sync.ts`:
- Around line 69-72: The SETTINGS_FIELDS_TO_SYNC list now includes
enabledCodexModels, codexDefaultModel, enabledGeminiModels, and
geminiDefaultModel but refreshSettingsFromServer() never restores them; update
the useAppStore.setState(...) call inside refreshSettingsFromServer to set
enabledCodexModels and codexDefaultModel and enabledGeminiModels and
geminiDefaultModel from the sanitized values you derive (analogous to
enabledCursorModels/cursorDefaultModel and
enabledOpencodeModels/opencodeDefaultModel), ensuring the fields names match
SETTINGS_FIELDS_TO_SYNC and are assigned the corresponding
sanitizedCodex*/sanitizedGemini* variables used earlier in that function.
- Use 'Speed' badge for non-thinking Gemini models (consistency) - Fix installCommand mapping in gemini-settings-tab.tsx - Add hasEnvApiKey to GeminiCliStatus interface for API parity - Clarify GeminiThinkingLevel comment (CLI doesn't support --thinking-level)
Add sanitization and restoration logic for enabledCodexModels, codexDefaultModel, enabledGeminiModels, and geminiDefaultModel in refreshSettingsFromServer() to match the fields in SETTINGS_FIELDS_TO_SYNC.
- Add tool name mapping to normalize Gemini CLI tool names to standard names (e.g., write_todos -> TodoWrite, read_file -> Read) - Add normalizeGeminiToolInput to convert write_todos format to TodoWrite format (description -> content, handle cancelled status) - Pass --include-directories with cwd to fix workspace restriction errors when Gemini CLI has a different cached workspace from previous sessions
Summary
Changes
Provider Implementation
GeminiProviderclass extendingCliProviderwith:--output-format stream-json)init,message,tool_use,tool_result,resulteventsUI Integration
Models Supported
Test plan
Summary by CodeRabbit
New Features
UI
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.