alexchenzl пре 5 месеци
родитељ
комит
1bd2ad396c

+ 1 - 0
chrome-extension/package.json

@@ -20,6 +20,7 @@
     "@extension/storage": "workspace:*",
     "@langchain/anthropic": "^0.3.12",
     "@langchain/core": "^0.3.37",
+    "@langchain/google-genai": "0.1.10",
     "@langchain/openai": "^0.4.2",
     "puppeteer-core": "24.1.1",
     "webextension-polyfill": "^0.12.0",

+ 12 - 0
chrome-extension/src/background/agent/helper.ts

@@ -1,6 +1,7 @@
 import { type ProviderConfig, LLMProviderEnum, AgentNameEnum } from '@extension/storage';
 import { ChatOpenAI } from '@langchain/openai';
 import { ChatAnthropic } from '@langchain/anthropic';
+import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
 import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
 
 // create a chat model based on the agent name, the model name and provider
@@ -60,6 +61,17 @@ export function createChatModel(
       }
       return new ChatAnthropic(args);
     }
+    case LLMProviderEnum.Gemini: {
+      temperature = 0.5;
+      topP = 0.8;
+      const args = {
+        model: modelName,
+        apiKey: providerConfig.apiKey,
+        temperature,
+        topP,
+      };
+      return new ChatGoogleGenerativeAI(args);
+    }
     default: {
       throw new Error(`Provider ${providerName} not supported yet`);
     }

+ 6 - 3
packages/storage/lib/settings/types.ts

@@ -9,14 +9,17 @@ export enum LLMProviderEnum {
   OpenAI = 'openai',
   Anthropic = 'anthropic',
   Gemini = 'gemini',
-  Deepseek = 'deepseek',
 }
 
 export const llmProviderModelNames = {
   [LLMProviderEnum.OpenAI]: ['gpt-4o', 'gpt-4o-mini', 'o1', 'o1-mini', 'o3-mini'],
   [LLMProviderEnum.Anthropic]: ['claude-3-5-sonnet-latest', 'claude-3-5-haiku-latest'],
-  [LLMProviderEnum.Gemini]: ['gemini-2.0-flash', 'gemini-2.0-flash-thinking-exp-01-21', 'gemini-2.0-pro-exp-02-05'],
-  [LLMProviderEnum.Deepseek]: ['deepseek-v3', 'deepseek-reasoner'],
+  [LLMProviderEnum.Gemini]: [
+    'gemini-2.0-flash',
+    'gemini-2.0-flash-lite',
+    'gemini-2.0-pro-exp-02-05',
+    'gemini-2.0-flash-thinking-exp-01-21',
+  ],
 };
 
 /**

+ 40 - 0
pages/options/src/components/ModelSettings.tsx

@@ -291,6 +291,46 @@ export const ModelSettings = () => {
               />
             </div>
           </div>
+
+          <div className="border-t border-gray-200" />
+
+          {/* Gemini Section */}
+          <div className="space-y-4">
+            <div className="flex items-center justify-between">
+              <h3 className="text-lg font-medium text-gray-700">Gemini</h3>
+              <Button
+                {...getButtonProps(LLMProviderEnum.Gemini)}
+                size="sm"
+                onClick={() =>
+                  apiKeys[LLMProviderEnum.Gemini]?.apiKey && !modifiedProviders.has(LLMProviderEnum.Gemini)
+                    ? handleDelete(LLMProviderEnum.Gemini)
+                    : handleSave(LLMProviderEnum.Gemini)
+                }
+              />
+            </div>
+            <div className="space-y-3">
+              <input
+                type="password"
+                placeholder="Gemini API key"
+                value={apiKeys[LLMProviderEnum.Gemini]?.apiKey || ''}
+                onChange={e => handleApiKeyChange(LLMProviderEnum.Gemini, e.target.value)}
+                className="w-full p-2 rounded-md bg-gray-50 border border-gray-200 focus:border-blue-400 focus:ring-2 focus:ring-blue-200 outline-none"
+              />
+              <input
+                type="text"
+                placeholder="Custom Base URL (Optional)"
+                value={apiKeys[LLMProviderEnum.Gemini]?.baseUrl || ''}
+                onChange={e =>
+                  handleApiKeyChange(
+                    LLMProviderEnum.Gemini,
+                    apiKeys[LLMProviderEnum.Gemini]?.apiKey || '',
+                    e.target.value,
+                  )
+                }
+                className="w-full p-2 rounded-md bg-gray-50 border border-gray-200 focus:border-blue-400 focus:ring-2 focus:ring-blue-200 outline-none"
+              />
+            </div>
+          </div>
         </div>
       </div>
 

+ 23 - 0
pnpm-lock.yaml

@@ -117,6 +117,9 @@ importers:
       '@langchain/core':
         specifier: ^0.3.37
         version: 0.3.37(openai@4.82.0(ws@8.18.0)(zod@3.24.1))
+      '@langchain/google-genai':
+        specifier: 0.1.10
+        version: 0.1.10(@langchain/core@0.3.37(openai@4.82.0(ws@8.18.0)(zod@3.24.1)))(zod@3.24.1)
       '@langchain/openai':
         specifier: ^0.4.2
         version: 0.4.2(@langchain/core@0.3.37(openai@4.82.0(ws@8.18.0)(zod@3.24.1)))(ws@8.18.0)
@@ -680,6 +683,10 @@ packages:
     resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
+  '@google/generative-ai@0.21.0':
+    resolution: {integrity: sha512-7XhUbtnlkSEZK15kN3t+tzIMxsbKm/dSkKBFalj+20NvPKe1kBY7mR2P7vuijEn+f06z5+A8bVGKO0v39cr6Wg==}
+    engines: {node: '>=18.0.0'}
+
   '@humanwhocodes/config-array@0.11.14':
     resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
     engines: {node: '>=10.10.0'}
@@ -731,6 +738,12 @@ packages:
     resolution: {integrity: sha512-LFk9GqHxcyCFx0oXvCBP7vDZIOUHYzzNU7JR+2ofIMnfkBLzcCKzBLySQDfPtd13PrpGHkaeOeLq8H1Tqi9lSw==}
     engines: {node: '>=18'}
 
+  '@langchain/google-genai@0.1.10':
+    resolution: {integrity: sha512-+0xFWvauNDNp8Nvhy5F5g8RbB5g4WWQSIxoPI4IQIUICBBT/kS/Omf1VJI6Loc0IH93m9ZSwYxRVCRu3qx51TQ==}
+    engines: {node: '>=18'}
+    peerDependencies:
+      '@langchain/core': '>=0.3.17 <0.4.0'
+
   '@langchain/openai@0.4.2':
     resolution: {integrity: sha512-Cuj7qbVcycALTP0aqZuPpEc7As8cwiGaU21MhXRyZFs+dnWxKYxZ1Q1z4kcx6cYkq/I+CNwwmk+sP+YruU73Aw==}
     engines: {node: '>=18'}
@@ -3555,6 +3568,8 @@ snapshots:
 
   '@eslint/js@8.57.0': {}
 
+  '@google/generative-ai@0.21.0': {}
+
   '@humanwhocodes/config-array@0.11.14':
     dependencies:
       '@humanwhocodes/object-schema': 2.0.3
@@ -3630,6 +3645,14 @@ snapshots:
     transitivePeerDependencies:
       - openai
 
+  '@langchain/google-genai@0.1.10(@langchain/core@0.3.37(openai@4.82.0(ws@8.18.0)(zod@3.24.1)))(zod@3.24.1)':
+    dependencies:
+      '@google/generative-ai': 0.21.0
+      '@langchain/core': 0.3.37(openai@4.82.0(ws@8.18.0)(zod@3.24.1))
+      zod-to-json-schema: 3.24.1(zod@3.24.1)
+    transitivePeerDependencies:
+      - zod
+
   '@langchain/openai@0.4.2(@langchain/core@0.3.37(openai@4.82.0(ws@8.18.0)(zod@3.24.1)))(ws@8.18.0)':
     dependencies:
       '@langchain/core': 0.3.37(openai@4.82.0(ws@8.18.0)(zod@3.24.1))