Skip to content

Commit ce611ac

Browse files
committed
Added Gemini Ai
1 parent 9539669 commit ce611ac

File tree

9 files changed

+334
-0
lines changed

9 files changed

+334
-0
lines changed

packages/api/ai/config.mts

+11
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ export async function getModel(): Promise<LanguageModel> {
3030
const anthropic = createAnthropic({ apiKey: config.anthropicKey });
3131
return anthropic(model);
3232

33+
case 'Gemini':
34+
if (!config.geminiKey) {
35+
throw new Error('Gemini API key is not set');
36+
}
37+
const gemini = createOpenAI({
38+
compatibility: 'compatible',
39+
baseURL: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=',
40+
apiKey: config.geminiKey,
41+
});
42+
return gemini(model);
43+
3344
case 'Xai':
3445
if (!config.xaiKey) {
3546
throw new Error('Xai API key is not set');

packages/api/db/schema.mts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const configs = sqliteTable('config', {
99
openaiKey: text('openai_api_key'),
1010
anthropicKey: text('anthropic_api_key'),
1111
xaiKey: text('xai_api_key'),
12+
geminiKey: text('gemini_api_key'),
1213
// TODO: This is deprecated in favor of SRCBOOK_DISABLE_ANALYTICS env variable. Remove this.
1314
enabledAnalytics: integer('enabled_analytics', { mode: 'boolean' }).notNull().default(true),
1415
// Stable ID for posthog
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE `config` ADD `gemini_api_key` text;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
{
2+
"version": "6",
3+
"dialect": "sqlite",
4+
"id": "c148b92f-4dbc-4a31-887d-dfaebd4db615",
5+
"prevId": "0acbefdc-659a-48ad-a4c1-a44ebca56c08",
6+
"tables": {
7+
"apps": {
8+
"name": "apps",
9+
"columns": {
10+
"id": {
11+
"name": "id",
12+
"type": "integer",
13+
"primaryKey": true,
14+
"notNull": true,
15+
"autoincrement": false
16+
},
17+
"name": {
18+
"name": "name",
19+
"type": "text",
20+
"primaryKey": false,
21+
"notNull": true,
22+
"autoincrement": false
23+
},
24+
"external_id": {
25+
"name": "external_id",
26+
"type": "text",
27+
"primaryKey": false,
28+
"notNull": true,
29+
"autoincrement": false
30+
},
31+
"history": {
32+
"name": "history",
33+
"type": "text",
34+
"primaryKey": false,
35+
"notNull": true,
36+
"autoincrement": false,
37+
"default": "'[]'"
38+
},
39+
"history_version": {
40+
"name": "history_version",
41+
"type": "integer",
42+
"primaryKey": false,
43+
"notNull": true,
44+
"autoincrement": false,
45+
"default": 1
46+
},
47+
"created_at": {
48+
"name": "created_at",
49+
"type": "integer",
50+
"primaryKey": false,
51+
"notNull": true,
52+
"autoincrement": false,
53+
"default": "(unixepoch())"
54+
},
55+
"updated_at": {
56+
"name": "updated_at",
57+
"type": "integer",
58+
"primaryKey": false,
59+
"notNull": true,
60+
"autoincrement": false,
61+
"default": "(unixepoch())"
62+
}
63+
},
64+
"indexes": {
65+
"apps_external_id_unique": {
66+
"name": "apps_external_id_unique",
67+
"columns": [
68+
"external_id"
69+
],
70+
"isUnique": true
71+
}
72+
},
73+
"foreignKeys": {},
74+
"compositePrimaryKeys": {},
75+
"uniqueConstraints": {}
76+
},
77+
"config": {
78+
"name": "config",
79+
"columns": {
80+
"base_dir": {
81+
"name": "base_dir",
82+
"type": "text",
83+
"primaryKey": false,
84+
"notNull": true,
85+
"autoincrement": false
86+
},
87+
"default_language": {
88+
"name": "default_language",
89+
"type": "text",
90+
"primaryKey": false,
91+
"notNull": true,
92+
"autoincrement": false,
93+
"default": "'typescript'"
94+
},
95+
"openai_api_key": {
96+
"name": "openai_api_key",
97+
"type": "text",
98+
"primaryKey": false,
99+
"notNull": false,
100+
"autoincrement": false
101+
},
102+
"anthropic_api_key": {
103+
"name": "anthropic_api_key",
104+
"type": "text",
105+
"primaryKey": false,
106+
"notNull": false,
107+
"autoincrement": false
108+
},
109+
"xai_api_key": {
110+
"name": "xai_api_key",
111+
"type": "text",
112+
"primaryKey": false,
113+
"notNull": false,
114+
"autoincrement": false
115+
},
116+
"gemini_api_key": {
117+
"name": "gemini_api_key",
118+
"type": "text",
119+
"primaryKey": false,
120+
"notNull": false,
121+
"autoincrement": false
122+
},
123+
"enabled_analytics": {
124+
"name": "enabled_analytics",
125+
"type": "integer",
126+
"primaryKey": false,
127+
"notNull": true,
128+
"autoincrement": false,
129+
"default": true
130+
},
131+
"srcbook_installation_id": {
132+
"name": "srcbook_installation_id",
133+
"type": "text",
134+
"primaryKey": false,
135+
"notNull": true,
136+
"autoincrement": false,
137+
"default": "'gid1al6p9ibob8tb6qmmuokg94'"
138+
},
139+
"ai_provider": {
140+
"name": "ai_provider",
141+
"type": "text",
142+
"primaryKey": false,
143+
"notNull": true,
144+
"autoincrement": false,
145+
"default": "'openai'"
146+
},
147+
"ai_model": {
148+
"name": "ai_model",
149+
"type": "text",
150+
"primaryKey": false,
151+
"notNull": false,
152+
"autoincrement": false,
153+
"default": "'gpt-4o'"
154+
},
155+
"ai_base_url": {
156+
"name": "ai_base_url",
157+
"type": "text",
158+
"primaryKey": false,
159+
"notNull": false,
160+
"autoincrement": false
161+
},
162+
"subscription_email": {
163+
"name": "subscription_email",
164+
"type": "text",
165+
"primaryKey": false,
166+
"notNull": false,
167+
"autoincrement": false
168+
}
169+
},
170+
"indexes": {},
171+
"foreignKeys": {},
172+
"compositePrimaryKeys": {},
173+
"uniqueConstraints": {}
174+
},
175+
"secrets": {
176+
"name": "secrets",
177+
"columns": {
178+
"id": {
179+
"name": "id",
180+
"type": "integer",
181+
"primaryKey": true,
182+
"notNull": true,
183+
"autoincrement": false
184+
},
185+
"name": {
186+
"name": "name",
187+
"type": "text",
188+
"primaryKey": false,
189+
"notNull": true,
190+
"autoincrement": false
191+
},
192+
"value": {
193+
"name": "value",
194+
"type": "text",
195+
"primaryKey": false,
196+
"notNull": true,
197+
"autoincrement": false
198+
}
199+
},
200+
"indexes": {
201+
"secrets_name_unique": {
202+
"name": "secrets_name_unique",
203+
"columns": [
204+
"name"
205+
],
206+
"isUnique": true
207+
}
208+
},
209+
"foreignKeys": {},
210+
"compositePrimaryKeys": {},
211+
"uniqueConstraints": {}
212+
},
213+
"secrets_to_sessions": {
214+
"name": "secrets_to_sessions",
215+
"columns": {
216+
"id": {
217+
"name": "id",
218+
"type": "integer",
219+
"primaryKey": true,
220+
"notNull": true,
221+
"autoincrement": false
222+
},
223+
"session_id": {
224+
"name": "session_id",
225+
"type": "text",
226+
"primaryKey": false,
227+
"notNull": true,
228+
"autoincrement": false
229+
},
230+
"secret_id": {
231+
"name": "secret_id",
232+
"type": "integer",
233+
"primaryKey": false,
234+
"notNull": true,
235+
"autoincrement": false
236+
}
237+
},
238+
"indexes": {
239+
"secrets_to_sessions_session_id_secret_id_unique": {
240+
"name": "secrets_to_sessions_session_id_secret_id_unique",
241+
"columns": [
242+
"session_id",
243+
"secret_id"
244+
],
245+
"isUnique": true
246+
}
247+
},
248+
"foreignKeys": {
249+
"secrets_to_sessions_secret_id_secrets_id_fk": {
250+
"name": "secrets_to_sessions_secret_id_secrets_id_fk",
251+
"tableFrom": "secrets_to_sessions",
252+
"tableTo": "secrets",
253+
"columnsFrom": [
254+
"secret_id"
255+
],
256+
"columnsTo": [
257+
"id"
258+
],
259+
"onDelete": "no action",
260+
"onUpdate": "no action"
261+
}
262+
},
263+
"compositePrimaryKeys": {},
264+
"uniqueConstraints": {}
265+
}
266+
},
267+
"enums": {},
268+
"_meta": {
269+
"schemas": {},
270+
"tables": {},
271+
"columns": {}
272+
},
273+
"internal": {
274+
"indexes": {}
275+
}
276+
}

packages/api/drizzle/meta/_journal.json

+7
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@
9999
"when": 1731347691803,
100100
"tag": "0013_add_x_ai",
101101
"breakpoints": true
102+
},
103+
{
104+
"idx": 14,
105+
"version": "6",
106+
"when": 1732197490638,
107+
"tag": "0014_Gemini_Integration",
108+
"breakpoints": true
102109
}
103110
]
104111
}

packages/shared/src/ai.mts

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const AiProvider = {
22
OpenAI: 'openai',
33
Anthropic: 'anthropic',
44
XAI: 'Xai',
5+
Gemini: 'Gemini',
56
Custom: 'custom',
67
} as const;
78

@@ -12,6 +13,7 @@ export const defaultModels: Record<AiProviderType, string> = {
1213
[AiProvider.Anthropic]: 'claude-3-5-sonnet-latest',
1314
[AiProvider.Custom]: 'mistral-nemo',
1415
[AiProvider.XAI]: 'grok-beta',
16+
[AiProvider.Gemini]: 'google-developer-ai',
1517
} as const;
1618

1719
export function isValidProvider(provider: string): provider is AiProviderType {

packages/web/src/components/use-settings.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export function SettingsProvider({ config, children }: ProviderPropsType) {
3535
(config.openaiKey && config.aiProvider === 'openai') ||
3636
(config.anthropicKey && config.aiProvider === 'anthropic') ||
3737
(config.xaiKey && config.aiProvider === 'Xai') ||
38+
(config.geminiKey && config.aiProvider === 'Gemini') ||
3839
(config.aiProvider === 'custom' && !!config.aiBaseUrl) ||
3940
false;
4041

0 commit comments

Comments
 (0)