From 53643e81f069521c2b2d956f80dc83b10e34b88e Mon Sep 17 00:00:00 2001 From: 1600822305 <1600822305@qq.com> Date: Sun, 20 Apr 2025 01:46:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- asr-server/embedded.js | 27 +- asr-server/test.js | 106 ++--- check-duplicate-messages.js | 82 ++-- check_json.js | 66 +-- create_empty_agents.js | 16 +- electron-builder.yml | 2 + package.json | 9 +- packages/shared/IpcChannel.ts | 1 + scripts/artifact-build-completed.js | 48 +++ src/main/index.ts | 4 + src/main/reranker/JinaReranker.ts | 4 +- src/main/reranker/SiliconFlowReranker.ts | 4 +- src/main/reranker/VoyageReranker.ts | 4 +- src/main/services/ASRServerService.ts | 368 ++++++++-------- src/main/services/AxiosProxy.ts | 27 ++ src/main/services/CodeExecutorService.ts | 7 +- src/main/services/CopilotService.ts | 12 +- src/main/services/MCPService.ts | 260 ++++++----- src/main/services/WindowService.ts | 1 + src/main/services/mcp/oauth/callback.ts | 76 ++++ src/main/services/mcp/oauth/provider.ts | 78 ++++ src/main/services/mcp/oauth/storage.ts | 120 ++++++ src/main/services/mcp/oauth/types.ts | 61 +++ src/preload/index.d.ts | 5 +- src/preload/index.ts | 3 +- src/renderer/src/assets/images/apps/zai.png | 1 + src/renderer/src/assets/styles/index.scss | 1 + .../src/components/AssistantMemoryPopup.tsx | 4 +- .../CodeExecutorButton/ExecutionResult.tsx | 6 +- .../CodeMirrorEditor/ChineseSearchPanel.ts | 2 +- .../src/components/CodeMirrorEditor/index.tsx | 93 ++-- .../src/components/DeepClaudeProvider.tsx | 36 +- .../src/components/PDFSettingsInitializer.tsx | 16 +- .../Popups/AssistantMemoryPopup.tsx | 12 +- .../components/Popups/SelectModelPopup.tsx | 43 +- .../src/components/QuickPanel/view.tsx | 15 +- src/renderer/src/components/WebdavModals.tsx | 3 +- src/renderer/src/components/app/Navbar.tsx | 4 +- src/renderer/src/config/models.ts | 48 ++- src/renderer/src/hooks/useSettings.ts | 3 +- src/renderer/src/hooks/useSidebarIcon.ts | 2 +- src/renderer/src/hooks/useTopic.ts | 6 +- src/renderer/src/i18n/locales/en-us.json | 4 +- src/renderer/src/i18n/locales/ja-jp.json | 4 +- src/renderer/src/i18n/locales/ru-ru.json | 4 +- src/renderer/src/i18n/locales/zh-cn.json | 16 +- src/renderer/src/i18n/locales/zh-tw.json | 4 +- .../pages/agents/components/AddAgentPopup.tsx | 13 +- src/renderer/src/pages/agents/index.ts | 5 +- .../pages/home/Inputbar/AttachmentButton.tsx | 76 ++-- .../home/Inputbar/MentionModelsButton.tsx | 2 + .../src/pages/home/Markdown/Markdown.tsx | 17 +- .../src/pages/home/Messages/Message.tsx | 342 ++++++++------- .../pages/home/Messages/MessageContent.tsx | 237 ++++++----- .../home/Messages/MessageErrorBoundary.tsx | 39 +- .../pages/home/Messages/MessageMenubar.tsx | 2 +- .../src/pages/home/Messages/MessageStream.tsx | 8 +- src/renderer/src/pages/home/Navbar.tsx | 3 - .../settings/DeepClaudeSettings/index.tsx | 130 +++--- .../settings/MCPSettings/EditMcpJsonPopup.tsx | 4 + .../MCPSettings/ImportMcpServerPopup.tsx | 199 +++++++++ .../MCPSettings/McpSettingsNavbar.tsx | 12 +- .../pages/settings/MCPSettings/NpxSearch.tsx | 16 +- .../src/pages/settings/MCPSettings/index.tsx | 4 + .../MemorySettings/AssistantMemoryManager.tsx | 13 +- .../pages/settings/MemorySettings/index.tsx | 7 +- .../ModelCombinationSettings/index.tsx | 402 ++++++++---------- .../ProviderSettings/GeminiKeyManager.tsx | 80 +++- .../ProviderSettings/ProviderSetting.tsx | 68 ++- .../pages/settings/ProviderSettings/index.tsx | 9 +- .../WebSearchSettings/AddSubscribePopup.tsx | 4 +- .../WebSearchProviderSetting.tsx | 51 ++- src/renderer/src/pages/settings/styles.ts | 2 +- .../AiProvider/DeepClaudeProvider.ts | 236 +++++----- .../providers/AiProvider/GeminiProvider.ts | 40 +- .../providers/AiProvider/OpenAIProvider.ts | 16 +- .../providers/AiProvider/ProviderFactory.ts | 34 +- src/renderer/src/services/ASRService.ts | 1 + src/renderer/src/services/ApiService.ts | 2 +- .../src/services/AssistantMemoryService.ts | 58 +-- src/renderer/src/services/AssistantService.ts | 16 +- src/renderer/src/services/BackupService.ts | 6 +- .../services/MemoryDeduplicationService.ts | 28 +- src/renderer/src/services/MemoryService.ts | 19 +- .../src/services/ModelMessageService.ts | 49 +++ .../__tests__/ModelMessageService.test.ts | 124 ++++++ src/renderer/src/store/memory.ts | 14 +- src/renderer/src/store/messages.ts | 29 +- src/renderer/src/store/settings.ts | 10 +- src/renderer/src/types/index.ts | 19 +- src/renderer/src/types/model.ts | 222 ++++++++++ .../src/utils/createDeepClaudeProvider.ts | 72 ++-- src/renderer/src/utils/index.ts | 26 ++ src/renderer/src/utils/markdown.ts | 65 +++ src/renderer/src/utils/thinkingLibrary.ts | 75 ++-- .../src/windows/mini/home/HomeWindow.tsx | 2 +- yarn.lock | 41 +- 97 files changed, 3113 insertions(+), 1554 deletions(-) create mode 100644 scripts/artifact-build-completed.js create mode 100644 src/main/services/AxiosProxy.ts create mode 100644 src/main/services/mcp/oauth/callback.ts create mode 100644 src/main/services/mcp/oauth/provider.ts create mode 100644 src/main/services/mcp/oauth/storage.ts create mode 100644 src/main/services/mcp/oauth/types.ts create mode 100644 src/renderer/src/assets/images/apps/zai.png create mode 100644 src/renderer/src/pages/settings/MCPSettings/ImportMcpServerPopup.tsx create mode 100644 src/renderer/src/services/ModelMessageService.ts create mode 100644 src/renderer/src/services/__tests__/ModelMessageService.test.ts create mode 100644 src/renderer/src/types/model.ts diff --git a/asr-server/embedded.js b/asr-server/embedded.js index f1a5cdcc91..b7d0af0093 100644 --- a/asr-server/embedded.js +++ b/asr-server/embedded.js @@ -7,7 +7,7 @@ const http = require('http') const path = require('path') const fs = require('fs') -const net = require('net') +// const net = require('net') const crypto = require('crypto') // 输出环境信息 @@ -114,23 +114,24 @@ const clients = { } // 处理WebSocket连接 -server.on('upgrade', (request, socket, head) => { +server.on('upgrade', (request, socket) => { try { console.log('[WebSocket] Connection upgrade request received') // 解析WebSocket密钥 const key = request.headers['sec-websocket-key'] - const acceptKey = crypto.createHash('sha1') + const acceptKey = crypto + .createHash('sha1') .update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary') .digest('base64') // 发送WebSocket握手响应 socket.write( 'HTTP/1.1 101 Switching Protocols\r\n' + - 'Upgrade: websocket\r\n' + - 'Connection: Upgrade\r\n' + - `Sec-WebSocket-Accept: ${acceptKey}\r\n` + - '\r\n' + 'Upgrade: websocket\r\n' + + 'Connection: Upgrade\r\n' + + `Sec-WebSocket-Accept: ${acceptKey}\r\n` + + '\r\n' ) console.log('[WebSocket] Handshake successful') @@ -157,10 +158,8 @@ function handleWebSocketConnection(socket) { // 检查是否有完整的帧 const firstByte = buffer[0] const secondByte = buffer[1] - const isFinalFrame = Boolean((firstByte >>> 7) & 0x1) - const [opCode, maskFlag, payloadLength] = [ - firstByte & 0xF, (secondByte >>> 7) & 0x1, secondByte & 0x7F - ] + // const isFinalFrame = Boolean((firstByte >>> 7) & 0x1) + const [opCode, maskFlag, payloadLength] = [firstByte & 0xf, (secondByte >>> 7) & 0x1, secondByte & 0x7f] // 处理不同的负载长度 let payloadStartIndex = 2 @@ -265,7 +264,7 @@ function sendWebSocketFrame(socket, data, opCode = 0x1) { // 发送Pong响应 function sendPong(socket) { - const pongFrame = Buffer.from([0x8A, 0x00]) + const pongFrame = Buffer.from([0x8a, 0x00]) socket.write(pongFrame) } @@ -351,11 +350,11 @@ async function findAvailablePort(startPort) { port++ } - throw new Error(`Could not find an available port between ${startPort} and ${maxPort-1}`) + throw new Error(`Could not find an available port between ${startPort} and ${maxPort - 1}`) } // 尝试启动服务器 -(async () => { +;(async () => { try { // 默认端口 const defaultPort = 34515 diff --git a/asr-server/test.js b/asr-server/test.js index 85558cc946..cd7a23c77c 100644 --- a/asr-server/test.js +++ b/asr-server/test.js @@ -3,67 +3,73 @@ * 用于测试ASR服务器是否正常工作 */ -const WebSocket = require('ws'); -const http = require('http'); +const WebSocket = require('ws') +const http = require('http') // 测试HTTP服务器 -console.log('测试HTTP服务器...'); -http.get('http://localhost:34515', (res) => { - console.log(`HTTP状态码: ${res.statusCode}`); - - let data = ''; - res.on('data', (chunk) => { - data += chunk; - }); - - res.on('end', () => { - console.log('HTTP响应接收完成'); - console.log(`响应长度: ${data.length} 字节`); - console.log('HTTP测试完成'); - - // 测试WebSocket - testWebSocket(); - }); -}).on('error', (err) => { - console.error('HTTP测试失败:', err.message); -}); +console.log('测试HTTP服务器...') +http + .get('http://localhost:34515', (res) => { + console.log(`HTTP状态码: ${res.statusCode}`) + + let data = '' + res.on('data', (chunk) => { + data += chunk + }) + + res.on('end', () => { + console.log('HTTP响应接收完成') + console.log(`响应长度: ${data.length} 字节`) + console.log('HTTP测试完成') + + // 测试WebSocket + testWebSocket() + }) + }) + .on('error', (err) => { + console.error('HTTP测试失败:', err.message) + }) // 测试WebSocket function testWebSocket() { - console.log('\n测试WebSocket...'); - const ws = new WebSocket('ws://localhost:34515'); - + console.log('\n测试WebSocket...') + const ws = new WebSocket('ws://localhost:34515') + ws.on('open', () => { - console.log('WebSocket连接已打开'); - + console.log('WebSocket连接已打开') + // 发送身份识别消息 - ws.send(JSON.stringify({ - type: 'identify', - role: 'electron' - })); - + ws.send( + JSON.stringify({ + type: 'identify', + role: 'electron' + }) + ) + // 发送测试消息 setTimeout(() => { - console.log('发送测试消息...'); - ws.send(JSON.stringify({ - type: 'test', - message: '这是一条测试消息' - })); - }, 1000); - + console.log('发送测试消息...') + ws.send( + JSON.stringify({ + type: 'test', + message: '这是一条测试消息' + }) + ) + }, 1000) + // 关闭连接 setTimeout(() => { - console.log('关闭WebSocket连接...'); - ws.close(); - console.log('测试完成'); - }, 2000); - }); - + console.log('关闭WebSocket连接...') + ws.close() + console.log('测试完成') + }, 2000) + }) + ws.on('message', (data) => { - console.log(`收到WebSocket消息: ${data}`); - }); - + console.log(`收到WebSocket消息: ${data}`) + }) + ws.on('error', (error) => { - console.error('WebSocket测试失败:', error.message); - }); + console.error('WebSocket测试失败:', error.message) + }) } diff --git a/check-duplicate-messages.js b/check-duplicate-messages.js index 243cf4caed..0a7e0d586a 100644 --- a/check-duplicate-messages.js +++ b/check-duplicate-messages.js @@ -1,77 +1,77 @@ // 检查重复消息的脚本 -const { app } = require('electron'); -const path = require('path'); -const fs = require('fs'); +const { app } = require('electron') +const path = require('path') +const fs = require('fs') // 获取数据库文件路径 -const userDataPath = app.getPath('userData'); -const dbFilePath = path.join(userDataPath, 'CherryStudio.db'); +const userDataPath = app.getPath('userData') +const dbFilePath = path.join(userDataPath, 'CherryStudio.db') -console.log('数据库文件路径:', dbFilePath); +console.log('数据库文件路径:', dbFilePath) // 检查文件是否存在 if (fs.existsSync(dbFilePath)) { - console.log('数据库文件存在'); - + console.log('数据库文件存在') + // 读取数据库内容 - const dbContent = fs.readFileSync(dbFilePath, 'utf8'); - + const dbContent = fs.readFileSync(dbFilePath, 'utf8') + // 解析数据库内容 try { - const data = JSON.parse(dbContent); - + const data = JSON.parse(dbContent) + // 检查topics表中的消息 if (data.topics) { - console.log('找到topics表,共有', data.topics.length, '个主题'); - + console.log('找到topics表,共有', data.topics.length, '个主题') + // 遍历每个主题 - data.topics.forEach(topic => { - console.log(`检查主题: ${topic.id}`); - + data.topics.forEach((topic) => { + console.log(`检查主题: ${topic.id}`) + if (topic.messages && Array.isArray(topic.messages)) { - console.log(` 主题消息数量: ${topic.messages.length}`); - + console.log(` 主题消息数量: ${topic.messages.length}`) + // 检查重复消息 - const messageIds = new Set(); - const duplicates = []; - - topic.messages.forEach(message => { + const messageIds = new Set() + const duplicates = [] + + topic.messages.forEach((message) => { if (messageIds.has(message.id)) { - duplicates.push(message.id); + duplicates.push(message.id) } else { - messageIds.add(message.id); + messageIds.add(message.id) } - }); - + }) + if (duplicates.length > 0) { - console.log(` 发现${duplicates.length}条重复消息ID:`, duplicates); + console.log(` 发现${duplicates.length}条重复消息ID:`, duplicates) } else { - console.log(' 未发现重复消息ID'); + console.log(' 未发现重复消息ID') } - + // 检查重复的askId (对于助手消息) - const askIds = {}; - topic.messages.forEach(message => { + const askIds = {} + topic.messages.forEach((message) => { if (message.role === 'assistant' && message.askId) { if (!askIds[message.askId]) { - askIds[message.askId] = []; + askIds[message.askId] = [] } - askIds[message.askId].push(message.id); + askIds[message.askId].push(message.id) } - }); - + }) + // 输出每个askId对应的助手消息数量 Object.entries(askIds).forEach(([askId, messageIds]) => { if (messageIds.length > 1) { - console.log(` askId ${askId} 有 ${messageIds.length} 条助手消息`); + console.log(` askId ${askId} 有 ${messageIds.length} 条助手消息`) } - }); + }) } - }); + }) } } catch (error) { - console.error('解析数据库内容失败:', error); + console.error('解析数据库内容失败:', error) } } else { - console.log('数据库文件不存在'); + console.log('数据库文件不存在') } diff --git a/check_json.js b/check_json.js index bc0a2592c9..ff20d61be7 100644 --- a/check_json.js +++ b/check_json.js @@ -1,64 +1,64 @@ -const fs = require('fs'); -const path = require('path'); +const fs = require('fs') +const path = require('path') // 读取agents.json文件 -const filePath = path.join('resources', 'data', 'agents.json'); +const filePath = path.join('resources', 'data', 'agents.json') fs.readFile(filePath, (err, data) => { if (err) { - console.error('读取文件失败:', err); - return; + console.error('读取文件失败:', err) + return } // 输出文件的前20个字节的十六进制表示 - console.log('文件前20个字节:'); + console.log('文件前20个字节:') for (let i = 0; i < Math.min(20, data.length); i++) { - console.log(`字节 ${i}: 0x${data[i].toString(16)} (${String.fromCharCode(data[i])})`); + console.log(`字节 ${i}: 0x${data[i].toString(16)} (${String.fromCharCode(data[i])})`) } // 尝试不同的方式解析JSON - console.log('\n尝试不同的方式解析JSON:'); - + console.log('\n尝试不同的方式解析JSON:') + // 1. 直接解析 try { - const json1 = JSON.parse(data); - console.log('方法1成功: 直接解析'); + JSON.parse(data) + console.log('方法1成功: 直接解析') } catch (e) { - console.error('方法1失败:', e.message); + console.error('方法1失败:', e.message) } - + // 2. 转换为字符串后解析 try { - const json2 = JSON.parse(data.toString()); - console.log('方法2成功: 转换为字符串后解析'); + JSON.parse(data.toString()) + console.log('方法2成功: 转换为字符串后解析') } catch (e) { - console.error('方法2失败:', e.message); + console.error('方法2失败:', e.message) } - + // 3. 移除BOM后解析 try { - const str = data.toString(); - const noBomStr = str.charCodeAt(0) === 0xFEFF ? str.slice(1) : str; - const json3 = JSON.parse(noBomStr); - console.log('方法3成功: 移除BOM后解析'); + const str = data.toString() + const noBomStr = str.charCodeAt(0) === 0xfeff ? str.slice(1) : str + JSON.parse(noBomStr) + console.log('方法3成功: 移除BOM后解析') } catch (e) { - console.error('方法3失败:', e.message); + console.error('方法3失败:', e.message) } - + // 4. 移除前3个字符后解析 try { - const str = data.toString().slice(3); - const json4 = JSON.parse(str); - console.log('方法4成功: 移除前3个字符后解析'); + const str = data.toString().slice(3) + JSON.parse(str) + console.log('方法4成功: 移除前3个字符后解析') } catch (e) { - console.error('方法4失败:', e.message); + console.error('方法4失败:', e.message) } - + // 5. 移除所有非ASCII字符后解析 try { - const str = data.toString().replace(/[^\x20-\x7E]/g, ''); - const json5 = JSON.parse(str); - console.log('方法5成功: 移除所有非ASCII字符后解析'); + const str = data.toString().replace(/[^\x20-\x7E]/g, '') + JSON.parse(str) + console.log('方法5成功: 移除所有非ASCII字符后解析') } catch (e) { - console.error('方法5失败:', e.message); + console.error('方法5失败:', e.message) } -}); +}) diff --git a/create_empty_agents.js b/create_empty_agents.js index e30985ae57..1770917fcc 100644 --- a/create_empty_agents.js +++ b/create_empty_agents.js @@ -1,14 +1,14 @@ -const fs = require('fs'); -const path = require('path'); +const fs = require('fs') +const path = require('path') // 创建一个空的agents.json文件 -const emptyAgents = []; -const filePath = path.join('resources', 'data', 'agents.json'); +const emptyAgents = [] +const filePath = path.join('resources', 'data', 'agents.json') // 备份原始文件 -fs.copyFileSync(filePath, filePath + '.bak'); -console.log('已备份原始文件到 ' + filePath + '.bak'); +fs.copyFileSync(filePath, filePath + '.bak') +console.log('已备份原始文件到 ' + filePath + '.bak') // 写入新文件 -fs.writeFileSync(filePath, JSON.stringify(emptyAgents, null, 2), 'utf8'); -console.log('已创建新的agents.json文件,内容为空数组'); +fs.writeFileSync(filePath, JSON.stringify(emptyAgents, null, 2), 'utf8') +console.log('已创建新的agents.json文件,内容为空数组') diff --git a/electron-builder.yml b/electron-builder.yml index b903f5ab88..b261ceea1b 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -65,6 +65,7 @@ nsis: allowToChangeInstallationDirectory: true oneClick: false include: build/nsis-installer.nsh + buildUniversalInstaller: false portable: artifactName: ${productName}-${version}-${arch}-portable.${ext} mac: @@ -101,6 +102,7 @@ electronDownload: mirror: https://npmmirror.com/mirrors/electron/ afterPack: scripts/after-pack.js afterSign: scripts/notarize.js +artifactBuildCompleted: scripts/artifact-build-completed.js releaseInfo: releaseNotes: | 全新图标风格 diff --git a/package.json b/package.json index 78b29d06f7..3b31abfcde 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CherryStudio", - "version": "1.2.4", + "version": "1.2.5-bate", "private": true, "description": "A powerful AI assistant for producer.", "main": "./out/main/index.js", @@ -23,7 +23,7 @@ "build": "npm run typecheck && electron-vite build", "build:check": "yarn test && yarn typecheck && yarn check:i18n", "build:unpack": "dotenv npm run build && electron-builder --dir", - "build:win": "dotenv npm run build && electron-builder --win && node scripts/after-build.js", + "build:win": "dotenv npm run build && electron-builder --win", "build:win:x64": "dotenv npm run build && electron-builder --win --x64", "build:win:arm64": "dotenv npm run build && electron-builder --win --arm64", "build:mac": "dotenv electron-vite build && electron-builder --mac", @@ -119,7 +119,6 @@ "fs-extra": "^11.2.0", "got-scraping": "^4.1.1", "js-tiktoken": "^1.0.19", - "js-yaml": "^4.1.0", "jsdom": "^26.0.0", "markdown-it": "^14.1.0", "monaco-editor": "^0.52.2", @@ -154,7 +153,7 @@ "@google/genai": "^0.8.0", "@hello-pangea/dnd": "^16.6.0", "@kangfenmao/keyv-storage": "^0.1.0", - "@modelcontextprotocol/sdk": "^1.9.0", + "@modelcontextprotocol/sdk": "^1.10.1", "@notionhq/client": "^2.2.15", "@reduxjs/toolkit": "^2.2.5", "@tavily/core": "patch:@tavily/core@npm%3A0.3.1#~/.yarn/patches/@tavily-core-npm-0.3.1-fe69bf2bea.patch", @@ -163,7 +162,6 @@ "@types/d3": "^7", "@types/diff": "^7", "@types/fs-extra": "^11", - "@types/js-yaml": "^4", "@types/lodash": "^4.17.16", "@types/markdown-it": "^14", "@types/md5": "^2.3.5", @@ -223,6 +221,7 @@ "rehype-katex": "^7.0.1", "rehype-mathjax": "^7.0.0", "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", "remark-cjk-friendly": "^1.1.0", "remark-gfm": "^4.0.0", "remark-math": "^6.0.0", diff --git a/packages/shared/IpcChannel.ts b/packages/shared/IpcChannel.ts index 4355b93acf..a45a5c15be 100644 --- a/packages/shared/IpcChannel.ts +++ b/packages/shared/IpcChannel.ts @@ -139,6 +139,7 @@ export enum IpcChannel { // system System_GetDeviceType = 'system:getDeviceType', + System_GetHostname = 'system:getHostname', // events SelectionAction = 'selection-action', diff --git a/scripts/artifact-build-completed.js b/scripts/artifact-build-completed.js new file mode 100644 index 0000000000..f25a63bbc6 --- /dev/null +++ b/scripts/artifact-build-completed.js @@ -0,0 +1,48 @@ +/** + * This script is executed after each artifact is built. + * It removes spaces from filenames to ensure compatibility with various systems. + */ + +const fs = require('fs') +const path = require('path') + +/** + * Removes spaces from a filename and replaces them with hyphens + * @param {string} artifactPath - Path to the artifact file + */ +function removeSpacesFromFilename(artifactPath) { + const dir = path.dirname(artifactPath) + const filename = path.basename(artifactPath) + // Replace spaces with hyphens in the filename + const newFilename = filename.replace(/\s+/g, '-') + // If the filename has changed, rename the file + if (newFilename !== filename) { + const newPath = path.join(dir, newFilename) + console.log(`Renaming: ${filename} -> ${newFilename}`) + fs.renameSync(artifactPath, newPath) + return newPath + } + return artifactPath +} + +/** + * Main function that runs when an artifact is built + * @param {object} params - Parameters from electron-builder + */ +module.exports = async function (params) { + const { artifactPath } = params + if (!artifactPath) { + console.log('No artifact path provided') + return + } + console.log(`Processing artifact: ${artifactPath}`) + try { + const newPath = removeSpacesFromFilename(artifactPath) + // Return the new path so electron-builder knows where the artifact is + return { artifactPath: newPath } + } catch (error) { + console.error('Error processing artifact:', error) + // Return the original path if there was an error + return { artifactPath } + } +} diff --git a/src/main/index.ts b/src/main/index.ts index 59acda25d2..bf6c96559b 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -63,6 +63,10 @@ if (!app.requestSingleInstanceLock()) { ipcMain.handle(IpcChannel.System_GetDeviceType, () => { return process.platform === 'darwin' ? 'mac' : process.platform === 'win32' ? 'windows' : 'linux' }) + + ipcMain.handle(IpcChannel.System_GetHostname, () => { + return require('os').hostname() + }) }) registerProtocolClient(app) diff --git a/src/main/reranker/JinaReranker.ts b/src/main/reranker/JinaReranker.ts index 207ddcb992..88350a5e61 100644 --- a/src/main/reranker/JinaReranker.ts +++ b/src/main/reranker/JinaReranker.ts @@ -1,6 +1,6 @@ import { ExtractChunkData } from '@cherrystudio/embedjs-interfaces' +import AxiosProxy from '@main/services/AxiosProxy' import { KnowledgeBaseParams } from '@types' -import axios from 'axios' import BaseReranker from './BaseReranker' @@ -20,7 +20,7 @@ export default class JinaReranker extends BaseReranker { } try { - const { data } = await axios.post(url, requestBody, { headers: this.defaultHeaders() }) + const { data } = await AxiosProxy.axios.post(url, requestBody, { headers: this.defaultHeaders() }) const rerankResults = data.results return this.getRerankResult(searchResults, rerankResults) diff --git a/src/main/reranker/SiliconFlowReranker.ts b/src/main/reranker/SiliconFlowReranker.ts index 0a27cf7e2a..78a213561a 100644 --- a/src/main/reranker/SiliconFlowReranker.ts +++ b/src/main/reranker/SiliconFlowReranker.ts @@ -1,6 +1,6 @@ import type { ExtractChunkData } from '@cherrystudio/embedjs-interfaces' +import axiosProxy from '@main/services/AxiosProxy' import { KnowledgeBaseParams } from '@types' -import axios from 'axios' import BaseReranker from './BaseReranker' @@ -22,7 +22,7 @@ export default class SiliconFlowReranker extends BaseReranker { } try { - const { data } = await axios.post(url, requestBody, { headers: this.defaultHeaders() }) + const { data } = await axiosProxy.axios.post(url, requestBody, { headers: this.defaultHeaders() }) const rerankResults = data.results return this.getRerankResult(searchResults, rerankResults) diff --git a/src/main/reranker/VoyageReranker.ts b/src/main/reranker/VoyageReranker.ts index a2c0f5f8af..44c800b6d5 100644 --- a/src/main/reranker/VoyageReranker.ts +++ b/src/main/reranker/VoyageReranker.ts @@ -1,6 +1,6 @@ import { ExtractChunkData } from '@cherrystudio/embedjs-interfaces' +import axiosProxy from '@main/services/AxiosProxy' import { KnowledgeBaseParams } from '@types' -import axios from 'axios' import BaseReranker from './BaseReranker' @@ -22,7 +22,7 @@ export default class VoyageReranker extends BaseReranker { } try { - const { data } = await axios.post(url, requestBody, { + const { data } = await axiosProxy.axios.post(url, requestBody, { headers: { ...this.defaultHeaders() } diff --git a/src/main/services/ASRServerService.ts b/src/main/services/ASRServerService.ts index 90d28219cb..2c1f500305 100644 --- a/src/main/services/ASRServerService.ts +++ b/src/main/services/ASRServerService.ts @@ -1,12 +1,13 @@ -import http from 'node:http' -import net from 'node:net' import crypto from 'node:crypto' import fs from 'node:fs' +import http from 'node:http' +import net from 'node:net' import path from 'node:path' import { IpcChannel } from '@shared/IpcChannel' import { app, ipcMain } from 'electron' import log from 'electron-log' + import { getResourcePath } from '../utils' /** @@ -14,19 +15,19 @@ import { getResourcePath } from '../utils' */ export class ASRServerService { // HTML内容 - private INDEX_HTML_CONTENT: string = ''; + private INDEX_HTML_CONTENT: string = '' // 服务器相关属性 - private httpServer: http.Server | null = null; - private wsClients: { browser: any | null; electron: any | null } = { browser: null, electron: null }; - private serverPort: number = 34515; // 默认端口 - private isServerRunning: boolean = false; + private httpServer: http.Server | null = null + private wsClients: { browser: any | null; electron: any | null } = { browser: null, electron: null } + private serverPort: number = 34515 // 默认端口 + private isServerRunning: boolean = false /** * 构造函数 */ constructor() { - this.loadIndexHtml(); + this.loadIndexHtml() } /** @@ -35,24 +36,24 @@ export class ASRServerService { private loadIndexHtml(): void { try { // 在开发环境和生产环境中使用不同的路径 - let htmlPath = ''; + let htmlPath = '' if (app.isPackaged) { // 生产环境 - const resourcePath = getResourcePath(); - htmlPath = path.join(resourcePath, 'app', 'asr-server', 'index.html'); + const resourcePath = getResourcePath() + htmlPath = path.join(resourcePath, 'app', 'asr-server', 'index.html') } else { // 开发环境 - htmlPath = path.join(app.getAppPath(), 'asr-server', 'index.html'); + htmlPath = path.join(app.getAppPath(), 'asr-server', 'index.html') } - log.info(`加载index.html文件: ${htmlPath}`); + log.info(`加载index.html文件: ${htmlPath}`) if (fs.existsSync(htmlPath)) { - this.INDEX_HTML_CONTENT = fs.readFileSync(htmlPath, 'utf8'); - log.info(`成功加载index.html文件`); + this.INDEX_HTML_CONTENT = fs.readFileSync(htmlPath, 'utf8') + log.info(`成功加载index.html文件`) } else { - log.error(`index.html文件不存在: ${htmlPath}`); + log.error(`index.html文件不存在: ${htmlPath}`) // 使用默认的HTML内容 this.INDEX_HTML_CONTENT = ` @@ -63,10 +64,10 @@ export class ASRServerService {
Please make sure the ASR server files are properly installed.
-