From e4dea4be45c6d9cee115812b48183a40ecb61088 Mon Sep 17 00:00:00 2001 From: eeee0717 Date: Thu, 29 May 2025 16:22:34 +0800 Subject: [PATCH 1/3] feat: add MinerU --- src/main/ocr/Doc2xOcrProvider.ts | 5 + src/main/ocr/MineruOcrProvider.ts | 333 +++++++++++++++++++++++++++++ src/main/ocr/OcrProviderFactory.ts | 3 + src/renderer/src/store/index.ts | 2 +- src/renderer/src/store/migrate.ts | 6 + src/renderer/src/store/ocr.ts | 6 + 6 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 src/main/ocr/MineruOcrProvider.ts diff --git a/src/main/ocr/Doc2xOcrProvider.ts b/src/main/ocr/Doc2xOcrProvider.ts index df6e3a9fa..c92a35180 100644 --- a/src/main/ocr/Doc2xOcrProvider.ts +++ b/src/main/ocr/Doc2xOcrProvider.ts @@ -248,6 +248,11 @@ export default class Doc2xOcrProvider extends BaseOcrProvider { const response = await axios.get(url, { responseType: 'arraybuffer' }) fs.writeFileSync(zipPath, response.data) + // 确保提取目录存在 + if (!fs.existsSync(extractPath)) { + fs.mkdirSync(extractPath, { recursive: true }) + } + // 解压文件 const zip = new AdmZip(zipPath) zip.extractAllTo(extractPath, true) diff --git a/src/main/ocr/MineruOcrProvider.ts b/src/main/ocr/MineruOcrProvider.ts new file mode 100644 index 000000000..2cb7c76b7 --- /dev/null +++ b/src/main/ocr/MineruOcrProvider.ts @@ -0,0 +1,333 @@ +import fs from 'node:fs' +import path from 'node:path' + +import { FileType, OcrProvider } from '@types' +import AdmZip from 'adm-zip' +import axios from 'axios' +import Logger from 'electron-log' + +import BaseOcrProvider from './BaseOcrProvider' + +type ApiResponse = { + code: number + data: T + msg?: string + trace_id?: string +} + +type BatchUploadResponse = { + batch_id: string + file_urls: string[] +} + +type ExtractProgress = { + extracted_pages: number + total_pages: number + start_time: string +} + +type ExtractFileResult = { + file_name: string + state: 'done' | 'waiting-file' | 'pending' | 'running' | 'converting' | 'failed' + err_msg: string + full_zip_url?: string + extract_progress?: ExtractProgress +} + +type ExtractResultResponse = { + batch_id: string + extract_result: ExtractFileResult[] +} + +export default class MineruOcrProvider extends BaseOcrProvider { + constructor(provider: OcrProvider) { + super(provider) + } + + public async parseFile(sourceId: string, file: FileType): Promise<{ processedFile: FileType }> { + try { + Logger.info(`MinerU OCR processing started: ${file.path}`) + await this.validateFile(file.path) + + // 1. 获取上传URL并上传文件 + const batchId = await this.uploadFile(file) + Logger.info(`MinerU file upload completed: batch_id=${batchId}`) + + // 2. 等待处理完成并获取结果 + const extractResult = await this.waitForCompletion(sourceId, batchId, file.origin_name) + Logger.info(`MinerU processing completed for batch: ${batchId}`) + + // 3. 下载并解压文件 + const { path: outputPath } = await this.downloadAndExtractFile(extractResult.full_zip_url!, file.path) + + // 4. 创建处理后的文件信息 + return { + processedFile: this.createProcessedFileInfo(file, outputPath) + } + } catch (error: any) { + Logger.error(`MinerU OCR processing failed for ${file.path}: ${error.message}`) + throw new Error(`OCR processing failed: ${error.message}`) + } + } + + private async validateFile(filePath: string): Promise { + const pdfBuffer = await fs.promises.readFile(filePath) + + const doc = await this.readPdf(new Uint8Array(pdfBuffer)) + + // 文件页数小于600页 + if (doc.numPages >= 600) { + throw new Error(`PDF page count (${doc.numPages}) exceeds the limit of 600 pages`) + } + // 文件大小小于200MB + if (pdfBuffer.length >= 200 * 1024 * 1024) { + const fileSizeMB = Math.round(pdfBuffer.length / (1024 * 1024)) + throw new Error(`PDF file size (${fileSizeMB}MB) exceeds the limit of 200MB`) + } + } + + private createProcessedFileInfo(file: FileType, outputPath: string): FileType { + // 查找解压后的主要文件 + let finalPath = '' + let finalName = file.origin_name.replace('.pdf', '.md') + + try { + const files = fs.readdirSync(outputPath) + + const mdFile = files.find((f) => f.endsWith('.md')) + if (mdFile) { + const originalMdPath = path.join(outputPath, mdFile) + const newMdPath = path.join(outputPath, finalName) + + // 重命名文件为原始文件名 + try { + fs.renameSync(originalMdPath, newMdPath) + finalPath = newMdPath + Logger.info(`Renamed markdown file from ${mdFile} to ${finalName}`) + } catch (renameError) { + Logger.warn(`Failed to rename file ${mdFile} to ${finalName}: ${renameError}`) + // 如果重命名失败,使用原文件 + finalPath = originalMdPath + finalName = mdFile + } + } + } catch (error) { + Logger.warn(`Failed to read output directory ${outputPath}: ${error}`) + finalPath = path.join(outputPath, `${file.id}.md`) + } + + return { + ...file, + name: finalName, + path: finalPath, + ext: path.extname(finalName), + size: fs.existsSync(finalPath) ? fs.statSync(finalPath).size : 0 + } + } + + private async downloadAndExtractFile(zipUrl: string, originalFilePath: string): Promise<{ path: string }> { + const dirPath = path.dirname(originalFilePath) + const baseName = path.basename(originalFilePath, path.extname(originalFilePath)) + const zipPath = path.join(dirPath, `${baseName}.zip`) + const extractPath = path.join(dirPath, `${baseName}`) + + Logger.info(`Downloading MinerU result to: ${zipPath}`) + + try { + // 下载ZIP文件 + const response = await axios.get(zipUrl, { responseType: 'arraybuffer' }) + fs.writeFileSync(zipPath, response.data) + Logger.info(`Downloaded ZIP file: ${zipPath}`) + + // 确保提取目录存在 + if (!fs.existsSync(extractPath)) { + fs.mkdirSync(extractPath, { recursive: true }) + } + + // 解压文件 + const zip = new AdmZip(zipPath) + zip.extractAllTo(extractPath, true) + Logger.info(`Extracted files to: ${extractPath}`) + + // 删除临时ZIP文件 + fs.unlinkSync(zipPath) + + return { path: extractPath } + } catch (error) { + Logger.error(`Failed to download and extract file: ${error instanceof Error ? error.message : String(error)}`) + throw new Error('Failed to download and extract file') + } + } + + private async uploadFile(file: FileType): Promise { + try { + // 步骤1: 获取上传URL + const { batchId, fileUrls } = await this.getBatchUploadUrls(file) + Logger.info(`Got upload URLs for batch: ${batchId}`) + + console.log('batchId:', batchId, 'fileurls:', fileUrls) + // 步骤2: 上传文件到获取的URL + await this.putFileToUrl(file.path, fileUrls[0]) + Logger.info(`File uploaded successfully: ${file.path}`) + + return batchId + } catch (error) { + Logger.error(`Failed to upload file ${file.path}: ${error instanceof Error ? error.message : String(error)}`) + throw new Error('Failed to upload file') + } + } + + private async getBatchUploadUrls(file: FileType): Promise<{ batchId: string; fileUrls: string[] }> { + const endpoint = `${this.provider.apiHost}/api/v4/file-urls/batch` + + const payload = { + language: 'auto', + enable_formula: true, + enable_table: true, + files: [ + { + name: file.origin_name, + is_ocr: true, + data_id: file.id + } + ] + } + + try { + const response = await fetch(endpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${this.provider.apiKey}` + }, + body: JSON.stringify(payload) + }) + + if (response.ok) { + const data: ApiResponse = await response.json() + if (data.code === 0 && data.data) { + const { batch_id, file_urls } = data.data + return { + batchId: batch_id, + fileUrls: file_urls + } + } else { + throw new Error(`API returned error: ${data.msg || JSON.stringify(data)}`) + } + } else { + throw new Error(`HTTP ${response.status}: ${response.statusText}`) + } + } catch (error) { + Logger.error(`Failed to get batch upload URLs: ${error instanceof Error ? error.message : String(error)}`) + throw new Error('Failed to get upload URLs') + } + } + + private async putFileToUrl(filePath: string, uploadUrl: string): Promise { + try { + const fileBuffer = await fs.promises.readFile(filePath) + + const response = await fetch(uploadUrl, { + method: 'PUT', + body: fileBuffer, + headers: { + 'Content-Length': fileBuffer.length.toString() + } + }) + + if (!response.ok) { + throw new Error(`Upload failed with status ${response.status}: ${response.statusText}`) + } + + Logger.info(`File uploaded successfully to: ${uploadUrl}`) + } catch (error) { + Logger.error( + `Failed to upload file to URL ${uploadUrl}: ${error instanceof Error ? error.message : String(error)}` + ) + throw new Error('Failed to upload file to provided URL') + } + } + + private async getExtractResults(batchId: string): Promise { + const endpoint = `${this.provider.apiHost}/api/v4/extract-results/batch/${batchId}` + + try { + const response = await fetch(endpoint, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${this.provider.apiKey}` + } + }) + + if (response.ok) { + const data: ApiResponse = await response.json() + if (data.code === 0 && data.data) { + return data.data + } else { + throw new Error(`API returned error: ${data.msg || JSON.stringify(data)}`) + } + } else { + throw new Error(`HTTP ${response.status}: ${response.statusText}`) + } + } catch (error) { + Logger.error( + `Failed to get extract results for batch ${batchId}: ${error instanceof Error ? error.message : String(error)}` + ) + throw new Error('Failed to get extract results') + } + } + + private async waitForCompletion( + sourceId: string, + batchId: string, + fileName: string, + maxRetries: number = 60, + intervalMs: number = 5000 + ): Promise { + let retries = 0 + + while (retries < maxRetries) { + try { + const result = await this.getExtractResults(batchId) + + // 查找对应文件的处理结果 + const fileResult = result.extract_result.find((item) => item.file_name === fileName) + if (!fileResult) { + throw new Error(`File ${fileName} not found in batch results`) + } + + // 检查处理状态 + if (fileResult.state === 'done' && fileResult.full_zip_url) { + Logger.info(`Processing completed for file: ${fileName}`) + return fileResult + } else if (fileResult.state === 'failed') { + throw new Error(`Processing failed for file: ${fileName}, error: ${fileResult.err_msg}`) + } else if (fileResult.state === 'running') { + // 发送进度更新 + if (fileResult.extract_progress) { + const progress = Math.round( + (fileResult.extract_progress.extracted_pages / fileResult.extract_progress.total_pages) * 100 + ) + await this.sendOcrProgress(sourceId, progress) + Logger.info(`File ${fileName} processing progress: ${progress}%`) + } else { + // 如果没有具体进度信息,发送一个通用进度 + await this.sendOcrProgress(sourceId, 50) + Logger.info(`File ${fileName} is still processing...`) + } + } + } catch (error) { + Logger.warn(`Failed to check status for batch ${batchId}, retry ${retries + 1}/${maxRetries}`) + if (retries === maxRetries - 1) { + throw error + } + } + + retries++ + await new Promise((resolve) => setTimeout(resolve, intervalMs)) + } + + throw new Error(`Processing timeout for batch: ${batchId}`) + } +} diff --git a/src/main/ocr/OcrProviderFactory.ts b/src/main/ocr/OcrProviderFactory.ts index c86af683f..98cf7ca3b 100644 --- a/src/main/ocr/OcrProviderFactory.ts +++ b/src/main/ocr/OcrProviderFactory.ts @@ -6,6 +6,7 @@ import BaseOcrProvider from './BaseOcrProvider' import DefaultOcrProvider from './DefaultOcrProvider' import Doc2xOcrProvider from './Doc2xOcrProvider' import MacSysOcrProvider from './MacSysOcrProvider' +import MineruOcrProvider from './MineruOcrProvider' import MistralOcrProvider from './MistralOcrProvider' export default class OcrProviderFactory { static create(provider: OcrProvider): BaseOcrProvider { @@ -19,6 +20,8 @@ export default class OcrProviderFactory { Logger.warn('[OCR] System OCR provider is only available on macOS') } return new MacSysOcrProvider(provider) + case 'mineru': + return new MineruOcrProvider(provider) default: return new DefaultOcrProvider(provider) } diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index 9fed3cc63..037068a88 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -52,7 +52,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 108, + version: 109, blacklist: ['runtime', 'messages', 'messageBlocks'], migrate }, diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 320a05b39..a78e84376 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -1488,6 +1488,12 @@ const migrateConfig = { model: 'mistral-ocr-latest', apiKey: '', apiHost: 'https://api.mistral.ai' + }, + { + id: 'mineru', + name: 'MinerU', + apiKey: '', + apiHost: 'https://mineru.net' } ] } diff --git a/src/renderer/src/store/ocr.ts b/src/renderer/src/store/ocr.ts index ec2c584c7..78becfd3a 100644 --- a/src/renderer/src/store/ocr.ts +++ b/src/renderer/src/store/ocr.ts @@ -21,6 +21,12 @@ const initialState: OcrState = { apiKey: '', apiHost: 'https://api.mistral.ai' }, + { + id: 'mineru', + name: 'MinerU', + apiKey: '', + apiHost: 'https://mineru.net' + }, { id: 'system', name: 'System(Mac Only)', From 8269ede05be852a8fff45690c8de359c59112fd4 Mon Sep 17 00:00:00 2001 From: eeee0717 Date: Tue, 3 Jun 2025 14:32:49 +0800 Subject: [PATCH 2/3] chore: add i18n --- src/main/ocr/MineruOcrProvider.ts | 2 +- src/renderer/src/assets/images/ocr/doc2x.png | Bin 0 -> 49106 bytes src/renderer/src/assets/images/ocr/doc2x.svg | 1 - src/renderer/src/assets/images/ocr/mineru.jpg | Bin 0 -> 16601 bytes src/renderer/src/config/ocrProviders.ts | 11 +- src/renderer/src/i18n/locales/ja-jp.json | 2 +- src/renderer/src/i18n/locales/ru-ru.json | 2 +- src/renderer/src/i18n/locales/zh-cn.json | 116 +++++++++--------- src/renderer/src/i18n/locales/zh-tw.json | 2 +- 9 files changed, 72 insertions(+), 64 deletions(-) create mode 100644 src/renderer/src/assets/images/ocr/doc2x.png delete mode 100644 src/renderer/src/assets/images/ocr/doc2x.svg create mode 100644 src/renderer/src/assets/images/ocr/mineru.jpg diff --git a/src/main/ocr/MineruOcrProvider.ts b/src/main/ocr/MineruOcrProvider.ts index 2cb7c76b7..49f8a5b0c 100644 --- a/src/main/ocr/MineruOcrProvider.ts +++ b/src/main/ocr/MineruOcrProvider.ts @@ -120,7 +120,7 @@ export default class MineruOcrProvider extends BaseOcrProvider { ...file, name: finalName, path: finalPath, - ext: path.extname(finalName), + ext: '.md', size: fs.existsSync(finalPath) ? fs.statSync(finalPath).size : 0 } } diff --git a/src/renderer/src/assets/images/ocr/doc2x.png b/src/renderer/src/assets/images/ocr/doc2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4b0d0efa369d7fd31031f5feea56e0d9152ace81 GIT binary patch literal 49106 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

4eJA}+gy*K{Mm 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 literal 0 HcmV?d00001 diff --git a/src/renderer/src/assets/images/ocr/doc2x.svg b/src/renderer/src/assets/images/ocr/doc2x.svg deleted file mode 100644 index ff3d7740c..000000000 --- a/src/renderer/src/assets/images/ocr/doc2x.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/renderer/src/assets/images/ocr/mineru.jpg b/src/renderer/src/assets/images/ocr/mineru.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c4295d1f650f39db5b569abedead67fa38de0b90 GIT binary patch literal 16601 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 CIc-@0 literal 0 HcmV?d00001 diff --git a/src/renderer/src/config/ocrProviders.ts b/src/renderer/src/config/ocrProviders.ts index e39ef5604..43ae1b484 100644 --- a/src/renderer/src/config/ocrProviders.ts +++ b/src/renderer/src/config/ocrProviders.ts @@ -1,4 +1,5 @@ -import Doc2xLogo from '@renderer/assets/images/ocr/doc2x.svg' +import Doc2xLogo from '@renderer/assets/images/ocr/doc2x.png' +import MinerULogo from '@renderer/assets/images/ocr/mineru.jpg' import MacOSLogo from '@renderer/assets/images/providers/macos.svg' import MistralLogo from '@renderer/assets/images/providers/mistral.png' @@ -10,6 +11,8 @@ export function getOcrProviderLogo(providerId: string) { return MistralLogo case 'system': return MacOSLogo + case 'mineru': + return MinerULogo default: return undefined } @@ -27,5 +30,11 @@ export const OCR_PROVIDER_CONFIG = { official: 'https://mistral.ai', apiKey: 'https://mistral.ai/api-keys' } + }, + mineru: { + websites: { + official: 'https://mineru.net/', + apiKey: 'https://mineru.net/apiManage' + } } } diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index fad627a9a..17b62d7b3 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -1936,4 +1936,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 726fd0196..56947656e 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -1936,4 +1936,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 492a64f69..00f202acc 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -824,14 +824,14 @@ "seed_desc_tip": "相同的种子和提示词可以生成相似的图片,设置 -1 每次生成都不一样", "title": "图片", "magic_prompt_option": "提示词增强", - "model": "版本", + "model": "模型", "aspect_ratio": "画幅比例", "style_type": "风格", "rendering_speed": "渲染速度", "learn_more": "了解更多", "paint_course": "教程", "prompt_placeholder_edit": "输入你的图片描述,文本绘制用 \"双引号\" 包裹", - "proxy_required": "目前需要打开代理才能查看生成图片,后续会支持国内直连", + "proxy_required": "打开代理并开启”TUN模式“查看生成图片或复制到浏览器打开,后续会支持国内直连", "image_file_required": "请先上传图片", "image_file_retry": "请重新上传图片", "image_placeholder": "暂无图片", @@ -854,7 +854,7 @@ "generate": "绘图", "edit": "编辑", "remix": "混合", - "upscale": "放大" + "upscale": "高清增强" }, "generate": { "model_tip": "模型版本:V3 为最新版本,V2 为之前版本,V2A 为快速模型、V_1 为初代模型,_TURBO 为加速版本", @@ -950,7 +950,7 @@ "zhinao": "360智脑", "zhipu": "智谱AI", "voyageai": "Voyage AI", - "qiniu": "七牛云", + "qiniu": "七牛云 AI 推理", "tokenflux": "TokenFlux" }, "restore": { @@ -1452,7 +1452,7 @@ "messages.input.send_shortcuts": "发送快捷键", "messages.input.show_estimated_tokens": "显示预估 Token 数", "messages.input.title": "输入设置", - "messages.input.enable_quick_triggers": "启用 '/' 和 '@' 触发快捷菜单", + "messages.input.enable_quick_triggers": "启用 / 和 @ 触发快捷菜单", "messages.input.enable_delete_model": "启用删除键删除输入的模型/附件", "messages.markdown_rendering_input_message": "Markdown 渲染输入消息", "messages.math_engine": "数学公式引擎", @@ -1642,7 +1642,6 @@ "zoom_out": "缩小界面", "zoom_reset": "重置缩放" }, - "theme.auto": "自动", "theme.dark": "深色", "theme.light": "浅色", "theme.title": "主题", @@ -1650,6 +1649,14 @@ "theme.window.style.title": "窗口样式", "theme.window.style.transparent": "透明窗口", "title": "设置", + "topic.position": "话题位置", + "topic.position.left": "左侧", + "topic.position.right": "右侧", + "topic.show.time": "显示话题时间", + "topic.pin_to_top": "固定话题置顶", + "tray.onclose": "关闭时最小化到托盘", + "tray.show": "显示托盘图标", + "tray.title": "托盘", "quickPhrase": { "title": "快捷短语", "add": "添加短语", @@ -1696,64 +1703,57 @@ "service_tier.default": "默认", "service_tier.flex": "灵活" }, - "topic.pin_to_top": "固定话题置顶", - "topic.position": "话题位置", - "topic.position.left": "左侧", - "topic.position.right": "右侧", - "topic.show.time": "显示话题时间", - "tray.onclose": "关闭时最小化到托盘", - "tray.show": "显示托盘图标", - "tray.title": "托盘", + "theme.auto": "自动", "tool": { - "title": "[to be translated]:Tools Settings", + "title": "工具设置", "ocr": { - "title": "[to be translated]:OCR", - "provider": "[to be translated]:OCR Provider", - "provider_placeholder": "[to be translated]:Choose an OCR provider", + "title": "OCR", + "provider": "OCR 服务商", + "provider_placeholder": "选择一个 OCR 服务商", "mac_system_ocr_options": { "mode": { - "title": "[to be translated]:Recognition Mode", - "accurate": "[to be translated]:Accurate", - "fast": "[to be translated]:Fast" + "title": "识别模式", + "accurate": "准确", + "fast": "快速" }, - "min_confidence": "[to be translated]:Minimum Confidence" + "min_confidence": "最低置信度" } }, "websearch": { - "blacklist": "[to be translated]:Blacklist", - "blacklist_description": "[to be translated]:Results from the following websites will not appear in search results", - "blacklist_tooltip": "[to be translated]:Please use the following format (separated by newlines)\nPattern matching: *://*.example.com/*\nRegular expression: /example\\.(net|org)/", - "check": "[to be translated]:Check", - "check_failed": "[to be translated]:Verification failed", - "check_success": "[to be translated]:Verification successful", - "get_api_key": "[to be translated]:Get API Key", - "no_provider_selected": "[to be translated]:Please select a search service provider before checking.", - "search_max_result": "[to be translated]:Number of search results", - "search_provider": "[to be translated]:Search service provider", - "search_provider_placeholder": "[to be translated]:Choose a search service provider.", - "search_result_default": "[to be translated]:Default", - "search_with_time": "[to be translated]:Search with dates included", + "blacklist": "黑名单", + "blacklist_description": "在搜索结果中不会出现以下网站的结果", + "blacklist_tooltip": "请使用以下格式(换行分隔)\n匹配模式: *://*.example.com/*\n正则表达式: /example\\.(net|org)/", + "check": "检测", + "check_failed": "验证失败", + "check_success": "验证成功", + "overwrite": "覆盖服务商搜索", + "overwrite_tooltip": "强制使用搜索服务商而不是大语言模型进行搜索", + "get_api_key": "点击这里获取密钥", + "no_provider_selected": "请选择搜索服务商后再检测", + "search_max_result": "搜索结果个数", + "search_provider": "搜索服务商", + "search_provider_placeholder": "选择一个搜索服务商", + "subscribe": "黑名单订阅", + "subscribe_update": "立即更新", + "subscribe_add": "添加订阅", + "subscribe_url": "订阅源地址", + "subscribe_name": "替代名字", + "subscribe_name.placeholder": "当下载的订阅源没有名称时所使用的替代名称", + "subscribe_add_success": "订阅源添加成功!", + "subscribe_delete": "删除订阅源", + "search_result_default": "默认", + "search_with_time": "搜索包含日期", "tavily": { - "api_key": "[to be translated]:Tavily API Key", - "api_key.placeholder": "[to be translated]:Enter Tavily API Key", - "description": "[to be translated]:Tavily is a search engine tailored for AI agents, delivering real-time, accurate results, intelligent query suggestions, and in-depth research capabilities.", - "title": "[to be translated]:Tavily" + "api_key": "Tavily API 密钥", + "api_key.placeholder": "请输入 Tavily API 密钥", + "description": "Tavily 是一个为 AI 代理量身定制的搜索引擎,提供实时、准确的结果、智能查询建议和深入的研究能力", + "title": "Tavily" }, - "title": "[to be translated]:Web Search", - "subscribe": "[to be translated]:Blacklist Subscription", - "subscribe_update": "[to be translated]:Update", - "subscribe_add": "[to be translated]:Add Subscription", - "subscribe_url": "[to be translated]:Subscription Url", - "subscribe_name": "[to be translated]:Alternative name", - "subscribe_name.placeholder": "[to be translated]:Alternative name used when the downloaded subscription feed has no name.", - "subscribe_add_success": "[to be translated]:Subscription feed added successfully!", - "subscribe_delete": "[to be translated]:Delete", - "overwrite": "[to be translated]:Override search service", - "overwrite_tooltip": "[to be translated]:Force use search service instead of LLM", - "apikey": "[to be translated]:API key", - "free": "[to be translated]:Free", - "content_limit": "[to be translated]:Content length limit", - "content_limit_tooltip": "[to be translated]:Limit the content length of the search results; content that exceeds the limit will be truncated." + "title": "网络搜索", + "apikey": "API 密钥", + "free": "免费", + "content_limit": "内容长度限制", + "content_limit_tooltip": "限制搜索结果的内容长度, 超过限制的内容将被截断" } } }, @@ -1784,10 +1784,10 @@ "input.placeholder": "输入文本进行翻译", "output.placeholder": "翻译", "processing": "翻译中...", - "scroll_sync.disable": "关闭滚动同步", - "scroll_sync.enable": "开启滚动同步", "title": "翻译", - "tooltip.newline": "换行" + "tooltip.newline": "换行", + "scroll_sync.disable": "禁用滚动同步", + "scroll_sync.enable": "启用滚动同步" }, "tray": { "quit": "退出", @@ -1936,4 +1936,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 9a571b88e..0f8c83b28 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -1936,4 +1936,4 @@ } } } -} +} \ No newline at end of file From 6cc0ec20a74771692f97f8193c4938221abcb465 Mon Sep 17 00:00:00 2001 From: eeee0717 Date: Tue, 3 Jun 2025 14:41:10 +0800 Subject: [PATCH 3/3] chore: add rc version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b6af06b4..bb0566872 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CherryStudio", - "version": "1.3.12", + "version": "1.5.0-rc.1", "private": true, "description": "A powerful AI assistant for producer.", "main": "./out/main/index.js",