From f8447cadb61b5638378ce7fe02dbb4e00b741bef Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Mon, 2 Jun 2025 19:37:54 +0800 Subject: [PATCH] support google gemini --- renderer/public/iconfont.css | 10 ++++++--- renderer/public/iconfont.woff2 | Bin 6772 -> 6984 bytes .../main-panel/chat/core/task-loop.ts | 20 ++++++++++++----- renderer/src/hook/mcp.ts | 1 + renderer/src/hook/setting.ts | 4 +++- renderer/src/i18n/ar.json | 3 ++- renderer/src/i18n/de.json | 3 ++- renderer/src/i18n/en.json | 3 ++- renderer/src/i18n/fr.json | 3 ++- renderer/src/i18n/ja.json | 3 ++- renderer/src/i18n/ko.json | 3 ++- renderer/src/i18n/ru.json | 3 ++- renderer/src/i18n/zh-cn.json | 3 ++- renderer/src/i18n/zh-tw.json | 3 ++- renderer/src/views/setting/general.vue | 14 ++++++++++++ service/src/hook/axios-fetch.ts | 21 +++++++++++++----- service/src/llm/llm.service.ts | 10 ++++----- service/src/mcp/client.service.ts | 3 --- service/src/mcp/connect.controller.ts | 3 --- service/src/setting/setting.service.ts | 6 ++++- 20 files changed, 83 insertions(+), 36 deletions(-) diff --git a/renderer/public/iconfont.css b/renderer/public/iconfont.css index 2f32010..1db10e8 100644 --- a/renderer/public/iconfont.css +++ b/renderer/public/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 4870215 */ - src: url('iconfont.woff2?t=1747820198035') format('woff2'), - url('iconfont.woff?t=1747820198035') format('woff'), - url('iconfont.ttf?t=1747820198035') format('truetype'); + src: url('iconfont.woff2?t=1748859145515') format('woff2'), + url('iconfont.woff?t=1748859145515') format('woff'), + url('iconfont.ttf?t=1748859145515') format('truetype'); } .iconfont { @@ -13,6 +13,10 @@ -moz-osx-font-smoothing: grayscale; } +.icon-proxy:before { + content: "\e723"; +} + .icon-parallel:before { content: "\e61d"; } diff --git a/renderer/public/iconfont.woff2 b/renderer/public/iconfont.woff2 index 6e2c510eaa3f7f3c57205d34c4d2b62f2bfda365..bd733c2237ae43d8556ce1fdb1abace20abb027e 100644 GIT binary patch literal 6984 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 ahw4q-gPLrMrjg%Fym&QBCKzR=yE_1S-HDw5 literal 6772 zcmV-)8jIz3Pew8T0RR9102*`v3jhEB05H@502(C#0RR9100000000000000000000 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 WLJn<*O<`IZe<5qe$Y@N2R{#KapC3N} diff --git a/renderer/src/components/main-panel/chat/core/task-loop.ts b/renderer/src/components/main-panel/chat/core/task-loop.ts index 0a18245..93106bd 100644 --- a/renderer/src/components/main-panel/chat/core/task-loop.ts +++ b/renderer/src/components/main-panel/chat/core/task-loop.ts @@ -9,9 +9,10 @@ import { ElMessage } from "element-plus"; import { handleToolCalls, type ToolCallResult } from "./handle-tool-calls"; import { getPlatform } from "@/api/platform"; import { getSystemPrompt } from "../chat-box/options/system-prompt"; +import { mcpSetting } from "@/hook/mcp"; export type ChatCompletionChunk = OpenAI.Chat.Completions.ChatCompletionChunk; -export type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams & { id?: string }; +export type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams & { id?: string, proxyServer?: string }; export interface TaskLoopOptions { maxEpochs?: number; maxJsonParseRetry?: number; @@ -79,13 +80,18 @@ export class TaskLoop { const toolCall = chunk.choices[0]?.delta?.tool_calls?.[0]; if (toolCall) { - const currentCall = this.streamingToolCalls.value[toolCall.index]; + if (toolCall.index === undefined || toolCall.index === null) { + console.warn('tool_call.index is undefined or null'); + } + + const index = toolCall.index || 0; + const currentCall = this.streamingToolCalls.value[index]; if (currentCall === undefined) { // 新的工具调用开始 - this.streamingToolCalls.value[toolCall.index] = { + this.streamingToolCalls.value[index] = { id: toolCall.id, - index: toolCall.index, + index, type: 'function', function: { name: toolCall.function?.name || '', @@ -124,6 +130,8 @@ export class TaskLoop { // data.code 一定为 200,否则不会走这个 route const { chunk } = data.msg as { chunk: ChatCompletionChunk }; + console.log(chunk); + // 处理增量的 content 和 tool_calls this.handleChunkDeltaContent(chunk); this.handleChunkDeltaToolCalls(chunk); @@ -181,6 +189,7 @@ export class TaskLoop { const temperature = tabStorage.settings.temperature; const tools = getToolSchema(tabStorage.settings.enableTools); const parallelToolCalls = tabStorage.settings.parallelToolCalls; + const proxyServer = mcpSetting.proxyServer || ''; const userMessages = []; @@ -211,6 +220,7 @@ export class TaskLoop { tools, parallelToolCalls, messages: userMessages, + proxyServer } as ChatCompletionCreateParamsBase; return chatData; @@ -396,7 +406,7 @@ export class TaskLoop { tabStorage.messages.push({ role: 'tool', index: toolCall.index || 0, - tool_call_id: toolCall.id || toolCall.function.name, + tool_call_id: toolCall.id || '', content: toolCallResult.content, extraInfo: { created: Date.now(), diff --git a/renderer/src/hook/mcp.ts b/renderer/src/hook/mcp.ts index 37c4174..baf3337 100644 --- a/renderer/src/hook/mcp.ts +++ b/renderer/src/hook/mcp.ts @@ -33,4 +33,5 @@ export function normaliseJavascriptType(type: string) { export const mcpSetting = reactive({ timeout: 60, + proxyServer: '', }); \ No newline at end of file diff --git a/renderer/src/hook/setting.ts b/renderer/src/hook/setting.ts index c5c4699..72b94d4 100644 --- a/renderer/src/hook/setting.ts +++ b/renderer/src/hook/setting.ts @@ -20,6 +20,7 @@ export async function loadSetting() { llmManager.currentModelIndex = persistConfig.MODEL_INDEX || 0; I18n.global.locale.value = persistConfig.LANG || 'zh'; mcpSetting.timeout = persistConfig.MCP_TIMEOUT_SEC || 60; + mcpSetting.proxyServer = persistConfig.PROXY_SERVER || ''; persistConfig.LLM_INFO.forEach((element: any) => { llms.push(element); @@ -51,7 +52,8 @@ export function saveSetting(saveHandler?: () => void) { MODEL_INDEX: llmManager.currentModelIndex, LLM_INFO: JSON.parse(JSON.stringify(llms)), LANG: I18n.global.locale.value, - MCP_TIMEOUT_SEC: mcpSetting.timeout + MCP_TIMEOUT_SEC: mcpSetting.timeout, + PROXY_SERVER: mcpSetting.proxyServer }; bridge.addCommandListener('setting/save', data => { diff --git a/renderer/src/i18n/ar.json b/renderer/src/i18n/ar.json index 97ce616..8cac488 100644 --- a/renderer/src/i18n/ar.json +++ b/renderer/src/i18n/ar.json @@ -156,5 +156,6 @@ "error": "خطأ", "feedback": "تعليقات", "waiting-mcp-server": "في انتظار استجابة خادم MCP", - "parallel-tool-calls": "السماح للنموذج باستدعاء أدوات متعددة في رد واحد" + "parallel-tool-calls": "السماح للنموذج باستدعاء أدوات متعددة في رد واحد", + "proxy-server": "خادم وكيل" } \ No newline at end of file diff --git a/renderer/src/i18n/de.json b/renderer/src/i18n/de.json index be8f275..cf241e3 100644 --- a/renderer/src/i18n/de.json +++ b/renderer/src/i18n/de.json @@ -156,5 +156,6 @@ "error": "Fehler", "feedback": "Feedback", "waiting-mcp-server": "Warten auf Antwort vom MCP-Server", - "parallel-tool-calls": "Erlauben Sie dem Modell, mehrere Tools in einer einzigen Antwort aufzurufen" + "parallel-tool-calls": "Erlauben Sie dem Modell, mehrere Tools in einer einzigen Antwort aufzurufen", + "proxy-server": "Proxy-Server" } \ No newline at end of file diff --git a/renderer/src/i18n/en.json b/renderer/src/i18n/en.json index a1e41e5..047b0ef 100644 --- a/renderer/src/i18n/en.json +++ b/renderer/src/i18n/en.json @@ -156,5 +156,6 @@ "error": "Error", "feedback": "Feedback", "waiting-mcp-server": "Waiting for MCP server response", - "parallel-tool-calls": "Allow the model to call multiple tools in a single reply" + "parallel-tool-calls": "Allow the model to call multiple tools in a single reply", + "proxy-server": "Proxy server" } \ No newline at end of file diff --git a/renderer/src/i18n/fr.json b/renderer/src/i18n/fr.json index b553741..8798712 100644 --- a/renderer/src/i18n/fr.json +++ b/renderer/src/i18n/fr.json @@ -156,5 +156,6 @@ "error": "Erreur", "feedback": "Retour", "waiting-mcp-server": "En attente de la réponse du serveur MCP", - "parallel-tool-calls": "Permettre au modèle d'appeler plusieurs outils en une seule réponse" + "parallel-tool-calls": "Permettre au modèle d'appeler plusieurs outils en une seule réponse", + "proxy-server": "Serveur proxy" } \ No newline at end of file diff --git a/renderer/src/i18n/ja.json b/renderer/src/i18n/ja.json index 3a755e9..a487fc1 100644 --- a/renderer/src/i18n/ja.json +++ b/renderer/src/i18n/ja.json @@ -156,5 +156,6 @@ "error": "エラー", "feedback": "フィードバック", "waiting-mcp-server": "MCPサーバーの応答を待機中", - "parallel-tool-calls": "モデルが単一の返信で複数のツールを呼び出すことを許可する" + "parallel-tool-calls": "モデルが単一の返信で複数のツールを呼び出すことを許可する", + "proxy-server": "プロキシサーバー" } \ No newline at end of file diff --git a/renderer/src/i18n/ko.json b/renderer/src/i18n/ko.json index bb5ac07..97337de 100644 --- a/renderer/src/i18n/ko.json +++ b/renderer/src/i18n/ko.json @@ -156,5 +156,6 @@ "error": "오류", "feedback": "피드백", "waiting-mcp-server": "MCP 서버 응답 대기 중", - "parallel-tool-calls": "모델이 단일 응답에서 여러 도구를 호출할 수 있도록 허용" + "parallel-tool-calls": "모델이 단일 응답에서 여러 도구를 호출할 수 있도록 허용", + "proxy-server": "프록시 서버" } \ No newline at end of file diff --git a/renderer/src/i18n/ru.json b/renderer/src/i18n/ru.json index a757bb7..03a1cd9 100644 --- a/renderer/src/i18n/ru.json +++ b/renderer/src/i18n/ru.json @@ -156,5 +156,6 @@ "error": "Ошибка", "feedback": "Обратная связь", "waiting-mcp-server": "Ожидание ответа от сервера MCP", - "parallel-tool-calls": "Разрешить модели вызывать несколько инструментов в одном ответе" + "parallel-tool-calls": "Разрешить модели вызывать несколько инструментов в одном ответе", + "proxy-server": "Прокси-сервер" } \ No newline at end of file diff --git a/renderer/src/i18n/zh-cn.json b/renderer/src/i18n/zh-cn.json index d145509..5f17c41 100644 --- a/renderer/src/i18n/zh-cn.json +++ b/renderer/src/i18n/zh-cn.json @@ -156,5 +156,6 @@ "error": "错误", "feedback": "反馈", "waiting-mcp-server": "等待 MCP 服务器响应", - "parallel-tool-calls": "允许模型在单轮回复中调用多个工具" + "parallel-tool-calls": "允许模型在单轮回复中调用多个工具", + "proxy-server": "代理服务器" } \ No newline at end of file diff --git a/renderer/src/i18n/zh-tw.json b/renderer/src/i18n/zh-tw.json index 4f0ffd8..d3bf8d1 100644 --- a/renderer/src/i18n/zh-tw.json +++ b/renderer/src/i18n/zh-tw.json @@ -156,5 +156,6 @@ "error": "錯誤", "feedback": "反饋", "waiting-mcp-server": "等待MCP伺服器響應", - "parallel-tool-calls": "允許模型在單輪回覆中調用多個工具" + "parallel-tool-calls": "允許模型在單輪回覆中調用多個工具", + "proxy-server": "代理伺服器" } \ No newline at end of file diff --git a/renderer/src/views/setting/general.vue b/renderer/src/views/setting/general.vue index 28c0d2a..6c9c692 100644 --- a/renderer/src/views/setting/general.vue +++ b/renderer/src/views/setting/general.vue @@ -27,6 +27,20 @@ @change="safeSaveSetting" /> + +
+ + + {{ t('proxy-server') }} + +
+ +
+
diff --git a/service/src/hook/axios-fetch.ts b/service/src/hook/axios-fetch.ts index d7ecb66..b410cb5 100644 --- a/service/src/hook/axios-fetch.ts +++ b/service/src/hook/axios-fetch.ts @@ -1,4 +1,5 @@ -import axios, { AxiosResponse } from "axios"; +import axios, { AxiosProxyConfig } from "axios"; +import { HttpsProxyAgent } from 'https-proxy-agent'; interface FetchOptions { method?: string; @@ -16,7 +17,7 @@ interface FetchResponse { redirected: boolean; type: string; body: any; - + json(): Promise; text(): Promise; arrayBuffer(): Promise; @@ -24,7 +25,7 @@ interface FetchResponse { } interface ReadableStreamDefaultReader { - read(): Promise<{done: boolean, value?: any}>; + read(): Promise<{ done: boolean, value?: any }>; cancel(): Promise; releaseLock(): void; get closed(): boolean; @@ -185,8 +186,18 @@ function adaptResponse(axiosResponse: FetchOptions): FetchResponse { /** * @description 主函数 - 用 axios 实现 fetch */ -export async function axiosFetch(url: any, options: any): Promise { - const axiosConfig = adaptRequestOptions(url, options); +export async function axiosFetch(input: any, init: any, requestOption: { proxyServer?: string } = {}): Promise { + const axiosConfig = adaptRequestOptions(input, init); + + const { + proxyServer = '' + } = requestOption; + + if (proxyServer) { + const proxyAgent = new HttpsProxyAgent(proxyServer); + axiosConfig.httpsAgent = proxyAgent; + axiosConfig.httpAgent = proxyAgent; + } try { const response = await axios(axiosConfig) as FetchOptions; diff --git a/service/src/llm/llm.service.ts b/service/src/llm/llm.service.ts index b9dbcaa..5168293 100644 --- a/service/src/llm/llm.service.ts +++ b/service/src/llm/llm.service.ts @@ -20,7 +20,8 @@ export async function streamingChatCompletion( messages, temperature, tools = [], - parallelToolCalls = true + parallelToolCalls = true, + proxyServer = '' } = data; const client = new OpenAI({ @@ -28,7 +29,7 @@ export async function streamingChatCompletion( apiKey, fetch: async (input: string | URL | Request, init?: RequestInit) => { - console.log('openai fetch begin'); + console.log('openai fetch begin, proxyServer:', proxyServer); if (model.startsWith('gemini')) { // 该死的 google @@ -38,11 +39,8 @@ export async function streamingChatCompletion( 'Authorization': `Bearer ${apiKey}` } } - - console.log('input:', input); - console.log('init:', init); - return await axiosFetch(input, init); + return await axiosFetch(input, init, { proxyServer }); } else { return await fetch(input, init); } diff --git a/service/src/mcp/client.service.ts b/service/src/mcp/client.service.ts index d56edcc..0fd6661 100644 --- a/service/src/mcp/client.service.ts +++ b/service/src/mcp/client.service.ts @@ -135,10 +135,7 @@ export class McpClient { // 调用工具 public async callTool(options: { name: string; arguments: Record, callToolOption?: any }) { const { callToolOption, ...methodArgs } = options; - console.log('methodArgs', methodArgs); - console.log('callToolOption', callToolOption); const res = await this.client.callTool(methodArgs, undefined, callToolOption); - console.log('callTool res', res); return res; } diff --git a/service/src/mcp/connect.controller.ts b/service/src/mcp/connect.controller.ts index 96df6c4..3b2906b 100644 --- a/service/src/mcp/connect.controller.ts +++ b/service/src/mcp/connect.controller.ts @@ -15,9 +15,6 @@ export class ConnectController { async lookupEnvVar(data: RequestData, webview: PostMessageble) { const { keys } = data; const values = keys.map((key: string) => { - // TODO: 在 Windows 上测试 - console.log(key); - console.log(process.env); if (process.platform === 'win32') { switch (key) { diff --git a/service/src/setting/setting.service.ts b/service/src/setting/setting.service.ts index 1cc0f16..ed5e553 100644 --- a/service/src/setting/setting.service.ts +++ b/service/src/setting/setting.service.ts @@ -52,7 +52,11 @@ export function loadSetting(): IConfig { try { const configData = fs.readFileSync(configPath, 'utf-8'); - return JSON.parse(configData) as IConfig; + const config = JSON.parse(configData) as IConfig; + if (!config.LLM_INFO || (Array.isArray(config.LLM_INFO) && config.LLM_INFO.length === 0)) { + config.LLM_INFO = llms; + } + return config; } catch (error) { console.error('Error loading config file, creating new one:', error); return createConfig();