Skip to content

Commit 6f52edb

Browse files
committed
feat(provider): add Gemini CLI provider
This commit introduces a new "Gemini CLI" provider, enabling users to leverage the authentication and free-tier access from the official Google Gemini CLI. The provider works by reading the local OAuth credentials generated by the `gemini auth` command. It handles token refreshes, project discovery, and communicates with the same backend API as the CLI tool. This allows users to use Gemini models within the extension without needing a separate API key. Key changes include: - A new `GeminiCliHandler` in the backend for authentication and API communication. - Model definitions for the available Gemini CLI models. - A new settings UI for the Gemini CLI provider. - Full test coverage for both the backend handler and the frontend UI.
1 parent e84dd0a commit 6f52edb

File tree

34 files changed

+1328
-3
lines changed

34 files changed

+1328
-3
lines changed

.prototools

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pnpm = "10.8.1"

.vscode/settings.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,14 @@
1010
},
1111
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
1212
"typescript.tsc.autoDetect": "off",
13-
"vitest.disableWorkspaceWarning": true
13+
"vitest.disableWorkspaceWarning": true,
14+
"workbench.colorCustomizations": {
15+
"sash.hoverBorder": "#f8b367",
16+
"statusBar.background": "#f69b36",
17+
"statusBar.foreground": "#15202b",
18+
"statusBarItem.hoverBackground": "#ee820b",
19+
"statusBarItem.remoteBackground": "#f69b36",
20+
"statusBarItem.remoteForeground": "#15202b"
21+
},
22+
"peacock.color": "#f69b36"
1423
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import type { ModelInfo } from "../model.js"
2+
3+
// Gemini CLI models with free tier pricing (all $0)
4+
export type GeminiCliModelId = keyof typeof geminiCliModels
5+
6+
export const geminiCliDefaultModelId: GeminiCliModelId = "gemini-2.0-flash-001"
7+
8+
export const geminiCliModels = {
9+
"gemini-2.0-flash-001": {
10+
maxTokens: 8192,
11+
contextWindow: 1_048_576,
12+
supportsImages: true,
13+
supportsPromptCache: false,
14+
inputPrice: 0,
15+
outputPrice: 0,
16+
},
17+
"gemini-2.0-flash-thinking-exp-01-21": {
18+
maxTokens: 65_536,
19+
contextWindow: 1_048_576,
20+
supportsImages: true,
21+
supportsPromptCache: false,
22+
inputPrice: 0,
23+
outputPrice: 0,
24+
},
25+
"gemini-2.0-flash-thinking-exp-1219": {
26+
maxTokens: 8192,
27+
contextWindow: 32_767,
28+
supportsImages: true,
29+
supportsPromptCache: false,
30+
inputPrice: 0,
31+
outputPrice: 0,
32+
},
33+
"gemini-2.0-flash-exp": {
34+
maxTokens: 8192,
35+
contextWindow: 1_048_576,
36+
supportsImages: true,
37+
supportsPromptCache: false,
38+
inputPrice: 0,
39+
outputPrice: 0,
40+
},
41+
"gemini-1.5-flash-002": {
42+
maxTokens: 8192,
43+
contextWindow: 1_048_576,
44+
supportsImages: true,
45+
supportsPromptCache: false,
46+
inputPrice: 0,
47+
outputPrice: 0,
48+
},
49+
"gemini-1.5-flash-exp-0827": {
50+
maxTokens: 8192,
51+
contextWindow: 1_048_576,
52+
supportsImages: true,
53+
supportsPromptCache: false,
54+
inputPrice: 0,
55+
outputPrice: 0,
56+
},
57+
"gemini-1.5-flash-8b-exp-0827": {
58+
maxTokens: 8192,
59+
contextWindow: 1_048_576,
60+
supportsImages: true,
61+
supportsPromptCache: false,
62+
inputPrice: 0,
63+
outputPrice: 0,
64+
},
65+
"gemini-1.5-pro-002": {
66+
maxTokens: 8192,
67+
contextWindow: 2_097_152,
68+
supportsImages: true,
69+
supportsPromptCache: false,
70+
inputPrice: 0,
71+
outputPrice: 0,
72+
},
73+
"gemini-1.5-pro-exp-0827": {
74+
maxTokens: 8192,
75+
contextWindow: 2_097_152,
76+
supportsImages: true,
77+
supportsPromptCache: false,
78+
inputPrice: 0,
79+
outputPrice: 0,
80+
},
81+
"gemini-exp-1206": {
82+
maxTokens: 8192,
83+
contextWindow: 2_097_152,
84+
supportsImages: true,
85+
supportsPromptCache: false,
86+
inputPrice: 0,
87+
outputPrice: 0,
88+
},
89+
"gemini-2.5-flash": {
90+
maxTokens: 64_000,
91+
contextWindow: 1_048_576,
92+
supportsImages: true,
93+
supportsPromptCache: false,
94+
inputPrice: 0,
95+
outputPrice: 0,
96+
maxThinkingTokens: 24_576,
97+
supportsReasoningBudget: true,
98+
},
99+
"gemini-2.5-pro": {
100+
maxTokens: 64_000,
101+
contextWindow: 1_048_576,
102+
supportsImages: true,
103+
supportsPromptCache: false,
104+
inputPrice: 0,
105+
outputPrice: 0,
106+
maxThinkingTokens: 32_768,
107+
supportsReasoningBudget: true,
108+
requiredReasoningBudget: true,
109+
},
110+
} as const satisfies Record<string, ModelInfo>

packages/types/src/providers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from "./chutes.js"
44
export * from "./claude-code.js"
55
export * from "./deepseek.js"
66
export * from "./gemini.js"
7+
export * from "./gemini-cli.js"
78
export * from "./glama.js"
89
export * from "./groq.js"
910
export * from "./lite-llm.js"

src/api/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
OllamaHandler,
1616
LmStudioHandler,
1717
GeminiHandler,
18+
GeminiCliHandler,
1819
OpenAiNativeHandler,
1920
DeepSeekHandler,
2021
MistralHandler,
@@ -85,6 +86,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
8586
return new LmStudioHandler(options)
8687
case "gemini":
8788
return new GeminiHandler(options)
89+
case "gemini-cli":
90+
return new GeminiCliHandler(options)
8891
case "openai-native":
8992
return new OpenAiNativeHandler(options)
9093
case "deepseek":

0 commit comments

Comments
 (0)