From 935cb0a880730d7fe690edd45e9f899c82ed495d Mon Sep 17 00:00:00 2001
From: pump-bear <78230759+pump-bear@users.noreply.github.com>
Date: Mon, 11 Aug 2025 13:22:43 +0200
Subject: [PATCH 1/2] Update README.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 11facd1..9d27e67 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
# Open Lovable
@@ -38,4 +38,4 @@ Open [http://localhost:3000](http://localhost:3000)
## License
-MIT
\ No newline at end of file
+MIT
From e73fa13b1fe8a6e9e654291875f3bd5cbba3b738 Mon Sep 17 00:00:00 2001
From: microgod
Date: Tue, 12 Aug 2025 04:46:12 +0100
Subject: [PATCH 2/2] Add support for Google Gemini AI
---
.env.example | 3 +++
README.md | 1 +
app/api/analyze-edit-intent/route.ts | 3 +++
app/api/generate-ai-code-stream/route.ts | 13 ++++++++++---
config/app.config.ts | 6 ++++--
package.json | 1 +
pnpm-lock.yaml | 18 ++++++++++++++++++
7 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/.env.example b/.env.example
index 73fbf52..c8b9f67 100644
--- a/.env.example
+++ b/.env.example
@@ -13,5 +13,8 @@ ANTHROPIC_API_KEY=your_anthropic_api_key_here
# Get yours at https://platform.openai.com
OPENAI_API_KEY=your_openai_api_key_here
+# Get yours at https://aistudio.google.com/app/apikey
+GEMINI_API_KEY=your_gemini_api_key_here
+
# Get yours at https://console.groq.com
GROQ_API_KEY=your_groq_api_key_here
\ No newline at end of file
diff --git a/README.md b/README.md
index 11facd1..4f09b18 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ FIRECRAWL_API_KEY=your_firecrawl_api_key # Get from https://firecrawl.dev (Web
# Optional (need at least one AI provider)
ANTHROPIC_API_KEY=your_anthropic_api_key # Get from https://console.anthropic.com
OPENAI_API_KEY=your_openai_api_key # Get from https://platform.openai.com (GPT-5)
+GEMINI_API_KEY=your_gemini_api_key # Get from https://aistudio.google.com/app/apikey
GROQ_API_KEY=your_groq_api_key # Get from https://console.groq.com (Fast inference - Kimi K2 recommended)
```
diff --git a/app/api/analyze-edit-intent/route.ts b/app/api/analyze-edit-intent/route.ts
index 2284829..7cf35bc 100644
--- a/app/api/analyze-edit-intent/route.ts
+++ b/app/api/analyze-edit-intent/route.ts
@@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { createGroq } from '@ai-sdk/groq';
import { createAnthropic } from '@ai-sdk/anthropic';
import { createOpenAI } from '@ai-sdk/openai';
+import { createGoogleGenerativeAI } from '@ai-sdk/google';
import { generateObject } from 'ai';
import { z } from 'zod';
import type { FileManifest } from '@/types/file-manifest';
@@ -102,6 +103,8 @@ export async function POST(request: NextRequest) {
} else {
aiModel = openai(model.replace('openai/', ''));
}
+ } else if (model.startsWith('google/')) {
+ aiModel = createGoogleGenerativeAI(model.replace('google/', ''));
} else {
// Default to groq if model format is unclear
aiModel = groq(model);
diff --git a/app/api/generate-ai-code-stream/route.ts b/app/api/generate-ai-code-stream/route.ts
index 002723b..eaae15d 100644
--- a/app/api/generate-ai-code-stream/route.ts
+++ b/app/api/generate-ai-code-stream/route.ts
@@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { createGroq } from '@ai-sdk/groq';
import { createAnthropic } from '@ai-sdk/anthropic';
import { createOpenAI } from '@ai-sdk/openai';
+import { createGoogleGenerativeAI } from '@ai-sdk/google';
import { streamText } from 'ai';
import type { SandboxState } from '@/types/sandbox';
import { selectFilesForEdit, getFileContents, formatFilesForAI } from '@/lib/context-selector';
@@ -19,6 +20,10 @@ const anthropic = createAnthropic({
baseURL: process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com/v1',
});
+const googleGenerativeAI = createGoogleGenerativeAI({
+ apiKey: process.env.GEMINI_API_KEY,
+});
+
const openai = createOpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
@@ -1148,11 +1153,13 @@ CRITICAL: When files are provided in the context:
// Determine which provider to use based on model
const isAnthropic = model.startsWith('anthropic/');
+ const isGoogle = model.startsWith('google/');
const isOpenAI = model.startsWith('openai/gpt-5');
- const modelProvider = isAnthropic ? anthropic : (isOpenAI ? openai : groq);
+ const modelProvider = isAnthropic ? anthropic : (isOpenAI ? openai : (isGoogle ? googleGenerativeAI : groq));
const actualModel = isAnthropic ? model.replace('anthropic/', '') :
- (model === 'openai/gpt-5') ? 'gpt-5' : model;
-
+ (model === 'openai/gpt-5') ? 'gpt-5' :
+ (isGoogle ? model.replace('google/', '') : model);
+
// Make streaming API call with appropriate provider
const streamOptions: any = {
model: modelProvider(actualModel),
diff --git a/config/app.config.ts b/config/app.config.ts
index ce468f0..500777d 100644
--- a/config/app.config.ts
+++ b/config/app.config.ts
@@ -34,14 +34,16 @@ export const appConfig = {
availableModels: [
'openai/gpt-5',
'moonshotai/kimi-k2-instruct',
- 'anthropic/claude-sonnet-4-20250514'
+ 'anthropic/claude-sonnet-4-20250514',
+ 'google/gemini-2.5-pro'
],
// Model display names
modelDisplayNames: {
'openai/gpt-5': 'GPT-5',
'moonshotai/kimi-k2-instruct': 'Kimi K2 Instruct',
- 'anthropic/claude-sonnet-4-20250514': 'Sonnet 4'
+ 'anthropic/claude-sonnet-4-20250514': 'Sonnet 4',
+ 'google/gemini-2.5-pro': 'Gemini 2.5 Pro'
},
// Temperature settings for non-reasoning models
diff --git a/package.json b/package.json
index 83a7923..fa30377 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
},
"dependencies": {
"@ai-sdk/anthropic": "^2.0.1",
+ "@ai-sdk/google": "^2.0.4",
"@ai-sdk/groq": "^2.0.0",
"@ai-sdk/openai": "^2.0.4",
"@anthropic-ai/sdk": "^0.57.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d7ec216..fe23553 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ importers:
'@ai-sdk/anthropic':
specifier: ^2.0.1
version: 2.0.1(zod@3.25.76)
+ '@ai-sdk/google':
+ specifier: ^2.0.4
+ version: 2.0.4(zod@3.25.76)
'@ai-sdk/groq':
specifier: ^2.0.0
version: 2.0.3(zod@3.25.76)
@@ -86,6 +89,9 @@ importers:
tailwindcss-animate:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@4.1.11)
+ zod:
+ specifier: ^3.25.76
+ version: 3.25.76
devDependencies:
'@eslint/eslintrc':
specifier: ^3
@@ -129,6 +135,12 @@ packages:
peerDependencies:
zod: ^3.25.76 || ^4
+ '@ai-sdk/google@2.0.4':
+ resolution: {integrity: sha512-d8CF3uzabVqxPwcuXLVv5OIq55bM5oKKNNMQacYQMEv3I9W6EYYYeaM9Buo+/yi1IdKsRIPsa9LQO/H9S9x8yQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ zod: ^3.25.76 || ^4
+
'@ai-sdk/groq@2.0.3':
resolution: {integrity: sha512-6U1iXh2P33YFSHcFdmESq7YZ3nHs50YQQZDSumwPFKs+iNKSPqrbfYQi/1lLKDhDtCrCEimYtyT+zMD7NlnCBQ==}
engines: {node: '>=18'}
@@ -2523,6 +2535,12 @@ snapshots:
'@ai-sdk/provider-utils': 3.0.1(zod@3.25.76)
zod: 3.25.76
+ '@ai-sdk/google@2.0.4(zod@3.25.76)':
+ dependencies:
+ '@ai-sdk/provider': 2.0.0
+ '@ai-sdk/provider-utils': 3.0.1(zod@3.25.76)
+ zod: 3.25.76
+
'@ai-sdk/groq@2.0.3(zod@3.25.76)':
dependencies:
'@ai-sdk/provider': 2.0.0