diff --git a/.env.example b/.env.example index ebab9e7..7c35261 100644 --- a/.env.example +++ b/.env.example @@ -92,6 +92,11 @@ OLLAMA_URL='http://127.0.0.1:11434/api/chat' OLLAMA_MODEL='' OLLAMA_SYSTEM_MESSAGE='You are a personal assistant.' +# Gemini +# 默认使用gemini-2.5-flash" +GEMINI_API_KEY = '' +GEMINI_MODEL = 'gemini-2.5-flash"' + # 白名单配置 #定义机器人的名称,这里是为了防止群聊消息太多,所以只有艾特机器人才会回复, #这里不要把@去掉,在@后面加上你启动机器人账号的微信名称 diff --git a/README.md b/README.md index 3713fb1..67f8bab 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,22 @@ wb agent --im wechat --agent pi CLAUDE_SYSTEM = '' ``` +- Gemini + + 前往[Gemini API Quickstart官网](https://ai.google.dev/gemini-api/docs/quickstart)创建API并在.env中配置即可,里面有详细教程。Gemini配置比较简单,只需要一个API就可以了。收费方式和OpenAI差不多,依旧是需要海外信用卡。 + + ```bash + # 执行下面命令,拷贝一份 .env.example 文件为 .env,如果已存在则忽略此步 + cp .env.example .env + + # 编辑.env文件并添加claude相关配置 + GEMINI_API_KEY = '你的API KEY' + GEMINI_MODEL = 'gemini-2.5-flash' + + ``` + + 关于GEMINI_MODEL处可用的Model List,参见[Models](https://ai.google.dev/gemini-api/docs/models) + - 其他 (待实践)理论上使用 openAI 格式的 api,都可以使用,在 env 文件中修改对应的 api_key、model、proxy_url 即可。 diff --git a/package.json b/package.json index 2a55ee6..bd6a3e3 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "author": "荣顶", "license": "ISC", "dependencies": { + "@google/genai": "^1.40.0", "axios": "^1.6.8", "chatgpt": "^2.5.2", "commander": "^12.0.0", diff --git a/src/Gemini/__test__.js b/src/Gemini/__test__.js new file mode 100644 index 0000000..18e5cd1 --- /dev/null +++ b/src/Gemini/__test__.js @@ -0,0 +1,10 @@ +import { getGeminiReply } from './index.js' + +// 测试 Gemini api +async function testMessage() { + let message + message = await getGeminiReply('Hello') + console.log('🌸🌸🌸 / message: ', message) +} + +testMessage() diff --git a/src/Gemini/index.js b/src/Gemini/index.js new file mode 100644 index 0000000..8014f93 --- /dev/null +++ b/src/Gemini/index.js @@ -0,0 +1,48 @@ +import { GoogleGenAI } from '@google/genai' +import dotenv from 'dotenv' +const env = dotenv.config().parsed // 环境参数 +import fs from 'fs' +import path from 'path' + +const __dirname = path.resolve() +// 判断是否有 .env 文件, 没有则报错 +const envPath = path.join(__dirname, '.env') +if (!fs.existsSync(envPath)) { + console.log('❌ 请先根据文档,创建并配置.env文件!') + process.exit(1) +} + +if (!env.GEMINI_API_KEY) { + console.log('❌ 请先根据文档,配置GEMINI_API_KEY!') + process.exit(1) +} + +// 默認使用Gemini-2.5-flash +const targetModel = env.GEMINI_MODEL ? env.GEMINI_MODEL : 'gemini-2.5-flash' + +const gemini = new GoogleGenAI({ + apiKey: env.GEMINI_API_KEY, +}) + +export async function getGeminiReply(prompt) { + if (!prompt) { + console.warn('⚠️ Warning: Received empty prompt.') + return '' + } + console.log('🚀🚀🚀 / prompt', prompt) + try { + const response = await gemini.models.generateContent({ + model: targetModel, + contents: prompt, + }) + if (!response || !response.text) { + console.warn('⚠️ Warning: Empty response from Gemini (possibly blocked by safety settings).') + return '' + } + console.log('🚀🚀🚀 / reply', response.text) + return `${response.text}` + } catch (error) { + console.error('❌ Gemini API Error:', error.message) + return '' + } +} diff --git a/src/index.js b/src/index.js index 625bbf7..5290e18 100644 --- a/src/index.js +++ b/src/index.js @@ -26,6 +26,7 @@ export const serveList = [ { name: 'tongyi', value: 'tongyi' }, { name: 'claude', value: 'claude' }, { name: 'pi', value: 'pi' }, + { name: 'Gemini', value: 'Gemini' }, ] function getMissingConfig(type) { @@ -56,6 +57,8 @@ function getMissingConfig(type) { return env.CLAUDE_API_KEY && env.CLAUDE_MODEL ? [] : ['CLAUDE_API_KEY', 'CLAUDE_MODEL'] case 'pi': return [] + case 'Gemini': + return env.GEMINI_API_KEY && env.GEMINI_MODEL ? [] : ['GEMINI_API_KEY', 'GEMINI_MODEL'] default: return ['SERVICE_TYPE'] } diff --git a/src/wechaty/serve.js b/src/wechaty/serve.js index 281ea07..96222d7 100644 --- a/src/wechaty/serve.js +++ b/src/wechaty/serve.js @@ -36,6 +36,8 @@ export function getServe(serviceType) { return lazyServe(() => import('../claude/index.js'), 'getClaudeReply') case 'pi': return lazyServe(() => import('../pi/index.js'), 'getPiReply') + case 'Gemini': + return lazyServe(() => import('../Gemini/index.js'), 'getGeminiReply') default: return lazyServe(() => import('../openai/index.js'), 'getGptReply') } diff --git a/src/wechaty/testMessage.js b/src/wechaty/testMessage.js index 498faf7..9125261 100644 --- a/src/wechaty/testMessage.js +++ b/src/wechaty/testMessage.js @@ -7,6 +7,8 @@ import { getDeepSeekFreeReply } from '../deepseek-free/index.js' import { get302AiReply } from '../302ai/index.js' import { getDifyReply } from '../dify/index.js' import { getOllamaReply } from '../ollama/index.js' +import { getGeminiReply } from '../Gemini/index.js' + const env = dotenv.config().parsed // 环境参数 // 控制启动 @@ -69,6 +71,14 @@ async function handleRequest(type) { } console.log('❌ 请先配置.env文件中的 OLLAMA_URL') break + case 'Gemini': + if (env.GEMINI_API_KEY) { + const message = await getGeminiReply('hello') + console.log('🌸🌸🌸 / reply: ', message) + return + } + console.log('❌ 请先配置.env文件中的 GEMINI_API_KEY') + break default: console.log('🚀服务类型错误') }