diff --git a/dev-app-update.yml b/dev-app-update.yml index 12788dcfd..6c9cb28c9 100644 --- a/dev-app-update.yml +++ b/dev-app-update.yml @@ -1,8 +1,8 @@ # provider: generic # url: http://127.0.0.1:8080 # updaterCacheDirName: cherry-studio-updater -# provider: github -# repo: cherry-studio -# owner: kangfenmao -provider: generic -url: https://cherrystudio.ocool.online +provider: github +repo: cherry-studio +owner: kangfenmao +# provider: generic +# url: https://cherrystudio.ocool.online diff --git a/package.json b/package.json index e76601eb2..bd308d83f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "CherryStudio", - "version": "1.1.8", + "version": "1.1.9", "private": true, "description": "A powerful AI assistant for producer.", "main": "./out/main/index.js", @@ -50,12 +50,8 @@ "prepare": "husky" }, "dependencies": { - "@agentic/exa": "^7.3.3", - "@agentic/searxng": "^7.3.3", - "@agentic/tavily": "^7.3.3", "@electron-toolkit/utils": "^3.0.0", "@electron/notarize": "^2.5.0", - "@emotion/is-prop-valid": "^1.3.1", "@google/generative-ai": "^0.21.0", "@llm-tools/embedjs": "patch:@llm-tools/embedjs@npm%3A0.1.28#~/.yarn/patches/@llm-tools-embedjs-npm-0.1.28-8e4393fa2d.patch", "@llm-tools/embedjs-libsql": "^0.1.28", @@ -68,12 +64,7 @@ "@llm-tools/embedjs-loader-xml": "^0.1.28", "@llm-tools/embedjs-openai": "^0.1.28", "@modelcontextprotocol/sdk": "patch:@modelcontextprotocol/sdk@npm%3A1.6.1#~/.yarn/patches/@modelcontextprotocol-sdk-npm-1.6.1-b46313efe7.patch", - "@notionhq/client": "^2.2.15", - "@tryfabric/martian": "^1.2.4", - "@types/pdf-parse": "^1.1.4", - "@types/react-infinite-scroll-component": "^5.0.0", "adm-zip": "^0.5.16", - "apache-arrow": "^18.1.0", "docx": "^9.0.2", "electron-log": "^5.1.5", "electron-store": "^8.2.0", @@ -83,30 +74,34 @@ "fetch-socks": "^1.3.2", "fs-extra": "^11.2.0", "markdown-it": "^14.1.0", - "npx-scope-finder": "^1.2.0", "officeparser": "^4.1.1", - "p-queue": "^8.1.0", "pdf-parse": "^1.1.1", "proxy-agent": "^6.5.0", "tar": "^7.4.3", - "tokenx": "^0.4.1", "undici": "^7.4.0", "webdav": "^5.8.0", "zipread": "^1.3.3" }, "devDependencies": { + "@agentic/exa": "^7.3.3", + "@agentic/searxng": "^7.3.3", + "@agentic/tavily": "^7.3.3", "@anthropic-ai/sdk": "^0.38.0", "@electron-toolkit/eslint-config-prettier": "^3.0.0", "@electron-toolkit/eslint-config-ts": "^3.0.0", "@electron-toolkit/preload": "^3.0.0", "@electron-toolkit/tsconfig": "^1.0.1", + "@emotion/is-prop-valid": "^1.3.1", "@eslint-react/eslint-plugin": "^1.36.1", "@eslint/js": "^9.22.0", + "@google/genai": "^0.4.0", "@hello-pangea/dnd": "^16.6.0", "@kangfenmao/keyv-storage": "^0.1.0", "@llm-tools/embedjs-loader-image": "^0.1.28", + "@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", + "@tryfabric/martian": "^1.2.4", "@types/adm-zip": "^0", "@types/fs-extra": "^11", "@types/lodash": "^4.17.5", @@ -118,6 +113,7 @@ "@types/react-dom": "^18.2.18", "@types/react-infinite-scroll-component": "^5.0.0", "@types/tinycolor2": "^1", + "@types/pdf-parse": "^1.1.4", "@vitejs/plugin-react": "^4.2.1", "antd": "^5.22.5", "applescript": "^1.0.0", @@ -145,7 +141,9 @@ "lint-staged": "^15.5.0", "lodash": "^4.17.21", "mime": "^4.0.4", + "npx-scope-finder": "^1.2.0", "openai": "patch:openai@npm%3A4.77.3#~/.yarn/patches/openai-npm-4.77.3-59c6d42e7a.patch", + "p-queue": "^8.1.0", "prettier": "^3.5.3", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -170,6 +168,7 @@ "string-width": "^7.2.0", "styled-components": "^6.1.11", "tinycolor2": "^1.6.0", + "tokenx": "^0.4.1", "typescript": "^5.6.2", "uuid": "^10.0.0", "vite": "^5.0.12" diff --git a/scripts/update-i18n.ts b/scripts/update-i18n.ts new file mode 100644 index 000000000..2140f4cef --- /dev/null +++ b/scripts/update-i18n.ts @@ -0,0 +1,130 @@ +/** + * OCOOL_API_KEY=sk-abcxxxxxxxxxxxxxxxxxxxxxxx123 ts-node scripts/update-i18n.ts + */ + +// OCOOL API KEY +const OCOOL_API_KEY = process.env.OCOOL_API_KEY + +const INDEX = [ + // 语言的名称 代码 用来翻译的模型 + { name: 'France', code: 'fr-fr', model: 'qwen2.5-32b-instruct' }, + { name: 'Spanish', code: 'es-es', model: 'qwen2.5-32b-instruct' }, + { name: 'Portuguese', code: 'pt-pt', model: 'qwen2.5-72b-instruct' }, + { name: 'Greek', code: 'el-gr', model: 'qwen-turbo' } +] + +const fs = require('fs') +import OpenAI from 'openai' + +const zh = JSON.parse(fs.readFileSync('src/renderer/src/i18n/locales/zh-cn.json', 'utf8')) as object + +const openai = new OpenAI({ + apiKey: OCOOL_API_KEY, + baseURL: 'https://one.ocoolai.com/v1' +}) + +// 递归遍历翻译 +async function translate(zh: object, obj: object, target: string, model: string, updateFile) { + const texts: { [key: string]: string } = {} + for (const e in zh) { + if (typeof zh[e] == 'object') { + // 遍历下一层 + if (!obj[e] || typeof obj[e] != 'object') obj[e] = {} + await translate(zh[e], obj[e], target, model, updateFile) + } else { + // 加入到本层待翻译列表 + if (!obj[e] || typeof obj[e] != 'string') { + texts[e] = zh[e] + } + } + } + if (Object.keys(texts).length > 0) { + const completion = await openai.chat.completions.create({ + model: model, + response_format: { type: 'json_object' }, + messages: [ + { + role: 'user', + content: ` +You are a robot specifically designed for translation tasks. As a model that has been extensively fine-tuned on Russian language corpora, you are proficient in using the Russian language. +Now, please output the translation based on the input content. The input will include both Chinese and English key values, and you should output the corresponding key values in the Russian language. +When translating, ensure that no key value is omitted, and maintain the accuracy and fluency of the translation. Pay attention to the capitalization rules in the output to match the source text, and especially pay attention to whether to capitalize the first letter of each word except for prepositions. For strings containing \`{{value}}\`, ensure that the format is not disrupted. +Output in JSON. +###################################################### +INPUT +###################################################### +${JSON.stringify({ + confirm: '确定要备份数据吗?', + select_model: '选择模型', + title: '文件', + deeply_thought: '已深度思考(用时 {{secounds}} 秒)' +})} +###################################################### +MAKE SURE TO OUTPUT IN Russian. DO NOT OUTPUT IN UNSPECIFIED LANGUAGE. +###################################################### + ` + }, + { + role: 'assistant', + content: JSON.stringify({ + confirm: 'Подтвердите резервное копирование данных?', + select_model: 'Выберите Модель', + title: 'Файл', + deeply_thought: 'Глубоко продумано (заняло {{seconds}} секунд)' + }) + }, + { + role: 'user', + content: ` +You are a robot specifically designed for translation tasks. As a model that has been extensively fine-tuned on ${target} language corpora, you are proficient in using the ${target} language. +Now, please output the translation based on the input content. The input will include both Chinese and English key values, and you should output the corresponding key values in the ${target} language. +When translating, ensure that no key value is omitted, and maintain the accuracy and fluency of the translation. Pay attention to the capitalization rules in the output to match the source text, and especially pay attention to whether to capitalize the first letter of each word except for prepositions. For strings containing \`{{value}}\`, ensure that the format is not disrupted. +Output in JSON. +###################################################### +INPUT +###################################################### +${JSON.stringify(texts)} +###################################################### +MAKE SURE TO OUTPUT IN ${target}. DO NOT OUTPUT IN UNSPECIFIED LANGUAGE. +###################################################### + ` + } + ] + }) + // 添加翻译后的键值,并打印错译漏译内容 + try { + const result = JSON.parse(completion.choices[0].message.content!) + for (const e in texts) { + if (result[e] && typeof result[e] === 'string') { + obj[e] = result[e] + } else { + console.log('[warning]', `missing value "${e}" in ${target} translation`) + } + } + } catch (e) { + console.log('[error]', e) + for (const e in texts) { + console.log('[warning]', `missing value "${e}" in ${target} translation`) + } + } + } + // 删除多余的键值 + for (const e in obj) { + if (!zh[e]) { + delete obj[e] + } + } + // 更新文件 + updateFile() +} + +;(async () => { + for (const { name, code, model } of INDEX) { + const obj = fs.existsSync(`src/renderer/src/i18n/translate/${code}.json`) + ? JSON.parse(fs.readFileSync(`src/renderer/src/i18n/translate/${code}.json`, 'utf8')) + : {} + await translate(zh, obj, name, model, () => { + fs.writeFileSync(`src/renderer/src/i18n/translate/${code}.json`, JSON.stringify(obj, null, 2), 'utf8') + }) + } +})() diff --git a/src/main/index.ts b/src/main/index.ts index 907ef2b64..970dbaf59 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -4,6 +4,7 @@ import { app, ipcMain } from 'electron' import installExtension, { REDUX_DEVTOOLS } from 'electron-devtools-installer' import { registerIpc } from './ipc' +import { configManager } from './services/ConfigManager' import { registerShortcuts } from './services/ShortcutService' import { TrayService } from './services/TrayService' import { windowService } from './services/WindowService' @@ -21,6 +22,12 @@ if (!app.requestSingleInstanceLock()) { // Set app user model id for windows electronApp.setAppUserModelId(import.meta.env.VITE_MAIN_BUNDLE_ID || 'com.kangfenmao.CherryStudio') + // Mac: Hide dock icon before window creation when launch to tray is set + const isLaunchToTray = configManager.getLaunchToTray() + if (isLaunchToTray) { + app.dock?.hide() + } + const mainWindow = windowService.createMainWindow() new TrayService() diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 91842c56a..224f91d3a 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -1,5 +1,6 @@ import fs from 'node:fs' +import { isMac, isWin } from '@main/constant' import { getBinaryPath, isBinaryExists, runInstallScript } from '@main/utils/process' import { MCPServer, Shortcut, ThemeMode } from '@types' import { BrowserWindow, ipcMain, session, shell } from 'electron' @@ -68,11 +69,30 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { configManager.setLanguage(language) }) + // launch on boot + ipcMain.handle('app:set-launch-on-boot', (_, openAtLogin: boolean) => { + // Set login item settings for windows and mac + // linux is not supported because it requires more file operations + if (isWin || isMac) { + app.setLoginItemSettings({ openAtLogin }) + } + }) + + // launch to tray + ipcMain.handle('app:set-launch-to-tray', (_, isActive: boolean) => { + configManager.setLaunchToTray(isActive) + }) + // tray ipcMain.handle('app:set-tray', (_, isActive: boolean) => { configManager.setTray(isActive) }) + // to tray on close + ipcMain.handle('app:set-tray-on-close', (_, isActive: boolean) => { + configManager.setTrayOnClose(isActive) + }) + ipcMain.handle('app:restart-tray', () => TrayService.getInstance().restartTray()) ipcMain.handle('config:set', (_, key: string, value: any) => { diff --git a/src/main/reranker/DefaultReranker.ts b/src/main/reranker/DefaultReranker.ts index 0bb074560..aac0c65e8 100644 --- a/src/main/reranker/DefaultReranker.ts +++ b/src/main/reranker/DefaultReranker.ts @@ -7,6 +7,7 @@ export default class DefaultReranker extends BaseReranker { constructor(base: KnowledgeBaseParams) { super(base) } + async rerank(): Promise { throw new Error('Method not implemented.') } diff --git a/src/main/reranker/JinaReranker.ts b/src/main/reranker/JinaReranker.ts index dbee063cc..3dfede195 100644 --- a/src/main/reranker/JinaReranker.ts +++ b/src/main/reranker/JinaReranker.ts @@ -10,9 +10,15 @@ export default class JinaReranker extends BaseReranker { } public rerank = async (query: string, searchResults: ExtractChunkData[]): Promise => { - const baseURL = this.base?.rerankBaseURL?.endsWith('/') + let baseURL = this.base?.rerankBaseURL?.endsWith('/') ? this.base.rerankBaseURL.slice(0, -1) : this.base.rerankBaseURL + + // 必须携带/v1,否则会404 + if (baseURL && !baseURL.endsWith('/v1')) { + baseURL = `${baseURL}/v1` + } + const url = `${baseURL}/rerank` const requestBody = { @@ -40,9 +46,9 @@ export default class JinaReranker extends BaseReranker { }) .filter((doc): doc is ExtractChunkData => doc !== undefined) .sort((a, b) => b.score - a.score) - } catch (error) { - console.error('Jina Reranker API 错误:', error) - throw error + } catch (error: any) { + console.error('Jina Reranker API 错误:', error.status) + throw new Error(`${error} - BaseUrl: ${baseURL}`) } } } diff --git a/src/main/reranker/SiliconFlowReranker.ts b/src/main/reranker/SiliconFlowReranker.ts index ee82362e2..1e47cca9c 100644 --- a/src/main/reranker/SiliconFlowReranker.ts +++ b/src/main/reranker/SiliconFlowReranker.ts @@ -10,9 +10,15 @@ export default class SiliconFlowReranker extends BaseReranker { } public rerank = async (query: string, searchResults: ExtractChunkData[]): Promise => { - const baseURL = this.base?.rerankBaseURL?.endsWith('/') + let baseURL = this.base?.rerankBaseURL?.endsWith('/') ? this.base.rerankBaseURL.slice(0, -1) : this.base.rerankBaseURL + + // 必须携带/v1,否则会404 + if (baseURL && !baseURL.endsWith('/v1')) { + baseURL = `${baseURL}/v1` + } + const url = `${baseURL}/rerank` const requestBody = { @@ -42,9 +48,9 @@ export default class SiliconFlowReranker extends BaseReranker { }) .filter((doc): doc is ExtractChunkData => doc !== undefined) .sort((a, b) => b.score - a.score) - } catch (error) { - console.error('SiliconFlow Reranker API 错误:', error) - throw error + } catch (error: any) { + console.error('SiliconFlow Reranker API 错误:', error.status) + throw new Error(`${error} - BaseUrl: ${baseURL}`) } } } diff --git a/src/main/services/ConfigManager.ts b/src/main/services/ConfigManager.ts index 719d089e9..da20bc414 100644 --- a/src/main/services/ConfigManager.ts +++ b/src/main/services/ConfigManager.ts @@ -30,6 +30,14 @@ export class ConfigManager { this.store.set('theme', theme) } + getLaunchToTray(): boolean { + return !!this.store.get('launchToTray', false) + } + + setLaunchToTray(value: boolean) { + this.store.set('launchToTray', value) + } + getTray(): boolean { return !!this.store.get('tray', true) } @@ -39,6 +47,14 @@ export class ConfigManager { this.notifySubscribers('tray', value) } + getTrayOnClose(): boolean { + return !!this.store.get('trayOnClose', true) + } + + setTrayOnClose(value: boolean) { + this.store.set('trayOnClose', value) + } + getZoomFactor(): number { return this.store.get('zoomFactor', 1) as number } diff --git a/src/main/services/ProxyManager.ts b/src/main/services/ProxyManager.ts index 573d0a9f3..24c741b5c 100644 --- a/src/main/services/ProxyManager.ts +++ b/src/main/services/ProxyManager.ts @@ -73,7 +73,6 @@ export class ProxyManager { await this.setSessionsProxy({ mode: 'system' }) const proxyString = await session.defaultSession.resolveProxy('https://dummy.com') const [protocol, address] = proxyString.split(';')[0].split(' ') - console.log('protocol', protocol) const url = protocol === 'PROXY' ? `http://${address}` : null if (url && url !== this.config.url) { this.config.url = url.toLowerCase() diff --git a/src/main/services/ShortcutService.ts b/src/main/services/ShortcutService.ts index 0738a6b92..949c07f8f 100644 --- a/src/main/services/ShortcutService.ts +++ b/src/main/services/ShortcutService.ts @@ -115,7 +115,20 @@ const convertShortcutRecordedByKeyboardEventKeyValueToElectronGlobalShortcutForm } export function registerShortcuts(window: BrowserWindow) { - const register = () => { + window.once('ready-to-show', () => { + if (configManager.getLaunchToTray()) { + registerOnlyUniversalShortcuts() + } + }) + + //only for clearer code + const registerOnlyUniversalShortcuts = () => { + register(true) + } + + //onlyUniversalShortcuts is used to register shortcuts that are not window specific, like show_app & mini_window + //onlyUniversalShortcuts is needed when we launch to tray + const register = (onlyUniversalShortcuts: boolean = false) => { if (window.isDestroyed()) return const shortcuts = configManager.getShortcuts() @@ -132,6 +145,11 @@ export function registerShortcuts(window: BrowserWindow) { return } + // only register universal shortcuts when needed + if (onlyUniversalShortcuts && !['show_app', 'mini_window'].includes(shortcut.key)) { + return + } + const handler = getShortcutHandler(shortcut) if (!handler) { return diff --git a/src/main/services/WindowService.ts b/src/main/services/WindowService.ts index 14bdef4e1..928bb8d37 100644 --- a/src/main/services/WindowService.ts +++ b/src/main/services/WindowService.ts @@ -1,5 +1,5 @@ import { is } from '@electron-toolkit/utils' -import { isDev, isLinux, isWin } from '@main/constant' +import { isDev, isLinux, isMac, isWin } from '@main/constant' import { getFilesDir } from '@main/utils/file' import { app, BrowserWindow, ipcMain, Menu, MenuItem, shell } from 'electron' import Logger from 'electron-log' @@ -39,8 +39,6 @@ export class WindowService { }) const theme = configManager.getTheme() - const isMac = process.platform === 'darwin' - const isLinux = process.platform === 'linux' this.mainWindow = new BrowserWindow({ x: mainWindowState.x, @@ -146,7 +144,12 @@ export class WindowService { private setupWindowEvents(mainWindow: BrowserWindow) { mainWindow.once('ready-to-show', () => { mainWindow.webContents.setZoomFactor(configManager.getZoomFactor()) - mainWindow.show() + + // show window only when laucn to tray not set + const isLaunchToTray = configManager.getLaunchToTray() + if (!isLaunchToTray) { + mainWindow.show() + } }) // 处理全屏相关事件 @@ -255,12 +258,20 @@ export class WindowService { return app.quit() } - // 没有开启托盘,且是Windows或Linux系统,直接退出 - const notInTray = !configManager.getTray() - if ((isWin || isLinux) && notInTray) { - return app.quit() + // 托盘及关闭行为设置 + const isShowTray = configManager.getTray() + const isTrayOnClose = configManager.getTrayOnClose() + + // 没有开启托盘,或者开启了托盘,但设置了直接关闭,应执行直接退出 + if (!isShowTray || (isShowTray && !isTrayOnClose)) { + // 如果是Windows或Linux,直接退出 + // mac按照系统默认行为,不退出 + if (isWin || isLinux) { + return app.quit() + } } + //上述逻辑以下,是“开启托盘+设置关闭时最小化到托盘”的情况 // 如果是Windows或Linux,且处于全屏状态,则退出应用 if (this.wasFullScreen) { if (isWin || isLinux) { @@ -271,8 +282,13 @@ export class WindowService { return } } + event.preventDefault() mainWindow.hide() + + if (isMac && isTrayOnClose) { + app.dock?.hide() //for mac to hide to tray + } }) mainWindow.on('closed', () => { @@ -301,6 +317,9 @@ export class WindowService { this.mainWindow = this.createMainWindow() this.mainWindow.focus() } + + //for mac users, when window is shown, should show dock icon (dock may be set to hide when launch) + app.dock?.show() } public showMiniWindow() { @@ -310,9 +329,6 @@ export class WindowService { return } - if (this.mainWindow && !this.mainWindow.isDestroyed()) { - this.mainWindow.hide() - } if (this.selectionMenuWindow && !this.selectionMenuWindow.isDestroyed()) { this.selectionMenuWindow.hide() } @@ -327,8 +343,6 @@ export class WindowService { return } - const isMac = process.platform === 'darwin' - this.miniWindow = new BrowserWindow({ width: 500, height: 520, @@ -403,7 +417,6 @@ export class WindowService { } const theme = configManager.getTheme() - const isMac = process.platform === 'darwin' this.selectionMenuWindow = new BrowserWindow({ width: 280, diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index ba14b8210..febaf299e 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -23,7 +23,10 @@ declare global { openWebsite: (url: string) => void setProxy: (proxy: string | undefined) => void setLanguage: (theme: LanguageVarious) => void + setLaunchOnBoot: (isActive: boolean) => void + setLaunchToTray: (isActive: boolean) => void setTray: (isActive: boolean) => void + setTrayOnClose: (isActive: boolean) => void restartTray: () => void setTheme: (theme: 'light' | 'dark') => void minApp: (options: { url: string; windowOptions?: Electron.BrowserWindowConstructorOptions }) => void diff --git a/src/preload/index.ts b/src/preload/index.ts index 5072f4a45..3eeb24980 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -11,7 +11,10 @@ const api = { checkForUpdate: () => ipcRenderer.invoke('app:check-for-update'), showUpdateDialog: () => ipcRenderer.invoke('app:show-update-dialog'), setLanguage: (lang: string) => ipcRenderer.invoke('app:set-language', lang), + setLaunchOnBoot: (isActive: boolean) => ipcRenderer.invoke('app:set-launch-on-boot', isActive), + setLaunchToTray: (isActive: boolean) => ipcRenderer.invoke('app:set-launch-to-tray', isActive), setTray: (isActive: boolean) => ipcRenderer.invoke('app:set-tray', isActive), + setTrayOnClose: (isActive: boolean) => ipcRenderer.invoke('app:set-tray-on-close', isActive), restartTray: () => ipcRenderer.invoke('app:restart-tray'), setTheme: (theme: 'light' | 'dark') => ipcRenderer.invoke('app:set-theme', theme), openWebsite: (url: string) => ipcRenderer.invoke('open:website', url), diff --git a/src/renderer/src/components/Icons/ReasoningIcon.tsx b/src/renderer/src/components/Icons/ReasoningIcon.tsx index 300b45ec2..4f98f5735 100644 --- a/src/renderer/src/components/Icons/ReasoningIcon.tsx +++ b/src/renderer/src/components/Icons/ReasoningIcon.tsx @@ -8,7 +8,7 @@ const ReasoningIcon: FC - + diff --git a/src/renderer/src/components/Icons/VisionIcon.tsx b/src/renderer/src/components/Icons/VisionIcon.tsx index 219043368..e95608d9c 100644 --- a/src/renderer/src/components/Icons/VisionIcon.tsx +++ b/src/renderer/src/components/Icons/VisionIcon.tsx @@ -9,7 +9,7 @@ const VisionIcon: FC, return ( - + diff --git a/src/renderer/src/components/Icons/WebSearchIcon.tsx b/src/renderer/src/components/Icons/WebSearchIcon.tsx index 507135e00..6dc99000a 100644 --- a/src/renderer/src/components/Icons/WebSearchIcon.tsx +++ b/src/renderer/src/components/Icons/WebSearchIcon.tsx @@ -9,7 +9,7 @@ const WebSearchIcon: FC - + diff --git a/src/renderer/src/components/ModelTags.tsx b/src/renderer/src/components/ModelTags.tsx index 0bc3038b3..4c683bff5 100644 --- a/src/renderer/src/components/ModelTags.tsx +++ b/src/renderer/src/components/ModelTags.tsx @@ -2,6 +2,7 @@ import { isEmbeddingModel, isFunctionCallingModel, isReasoningModel, + isRerankModel, isVisionModel, isWebSearchModel } from '@renderer/config/models' @@ -32,8 +33,9 @@ const ModelTags: FC = ({ model, showFree = true, showReasoning = {isWebSearchModel(model) && } {showReasoning && isReasoningModel(model) && } {showToolsCalling && isFunctionCallingModel(model) && } - {isEmbeddingModel(model) && {t('models.embedding')}} - {showFree && isFreeModel(model) && {t('models.free')}} + {isEmbeddingModel(model) && {t('models.type.embedding')}} + {showFree && isFreeModel(model) && {t('models.type.free')}} + {isRerankModel(model) && {t('models.type.rerank')}} ) } diff --git a/src/renderer/src/components/ObsidianExportDialog.tsx b/src/renderer/src/components/ObsidianExportDialog.tsx new file mode 100644 index 000000000..ec37b8a71 --- /dev/null +++ b/src/renderer/src/components/ObsidianExportDialog.tsx @@ -0,0 +1,120 @@ +import i18n from '@renderer/i18n' +import { exportMarkdownToObsidian } from '@renderer/utils/export' +import { Form, Input, Modal, Select } from 'antd' +import React, { useState } from 'react' + +const { Option } = Select + +interface ObsidianExportDialogProps { + title: string + markdown: string + open: boolean // 使用 open 属性替代 visible + onClose: (success: boolean) => void + obsidianTags: string | null + processingMethod: string | '3' //默认新增(存在就覆盖) +} + +const ObsidianExportDialog: React.FC = ({ + title, + markdown, + obsidianTags, + processingMethod, + open, + onClose +}) => { + const [state, setState] = useState({ + title: title, + tags: obsidianTags || '', + createdAt: new Date().toISOString().split('T')[0], + source: 'Cherry Studio', + processingMethod: processingMethod + }) + + const handleOk = async () => { + //构建content 并复制到粘贴板 + let content = '' + if (state.processingMethod !== '3') { + content = `\n---\n${markdown}` + } else { + content = `--- + \ntitle: ${state.title} + \ncreated: ${state.createdAt} + \nsource: ${state.source} + \ntags: ${state.tags} + \n---\n${markdown}` + } + if (content === '') { + window.message.error(i18n.t('chat.topics.export.obsidian_export_failed')) + } + await navigator.clipboard.writeText(content) + markdown = '' + exportMarkdownToObsidian(state) + onClose(true) + } + + const handleCancel = () => { + onClose(false) + } + + const handleChange = (key: string, value: any) => { + setState((prevState) => ({ ...prevState, [key]: value })) + } + + return ( + +
+ + handleChange('title', e.target.value)} + placeholder={i18n.t('chat.topics.export.obsidian_title_placeholder')} + /> + + + handleChange('tags', e.target.value)} + placeholder={i18n.t('chat.topics.export.obsidian_tags_placeholder')} + /> + + + handleChange('createdAt', e.target.value)} + placeholder={i18n.t('chat.topics.export.obsidian_created_placeholder')} + /> + + + handleChange('source', e.target.value)} + placeholder={i18n.t('chat.topics.export.obsidian_source_placeholder')} + /> + + + + +
+
+ ) +} + +export default ObsidianExportDialog diff --git a/src/renderer/src/components/ObsidianFolderSelector.tsx b/src/renderer/src/components/ObsidianFolderSelector.tsx deleted file mode 100644 index cb6f61708..000000000 --- a/src/renderer/src/components/ObsidianFolderSelector.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import { FileOutlined, FolderOutlined } from '@ant-design/icons' -import { Spin, Switch, Tree } from 'antd' -import { FC, useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' -import styled from 'styled-components' - -interface Props { - defaultPath: string - obsidianUrl: string - obsidianApiKey: string - onPathChange: (path: string, isMdFile: boolean) => void -} - -interface TreeNode { - title: string - key: string - isLeaf: boolean - isMdFile?: boolean - children?: TreeNode[] -} - -const ObsidianFolderSelector: FC = ({ defaultPath, obsidianUrl, obsidianApiKey, onPathChange }) => { - const { t } = useTranslation() - const [treeData, setTreeData] = useState([]) - const [loading, setLoading] = useState(false) - const [expandedKeys, setExpandedKeys] = useState(['/']) - const [showMdFiles, setShowMdFiles] = useState(false) - // 当前选中的节点信息 - const [currentSelection, setCurrentSelection] = useState({ - path: defaultPath, - isMdFile: false - }) - // 使用key强制Tree组件重新渲染 - const [treeKey, setTreeKey] = useState(0) - - // 只初始化根节点,不立即加载内容 - useEffect(() => { - initializeRootNode() - }, [showMdFiles]) - - // 初始化根节点,但不自动加载子节点 - const initializeRootNode = () => { - const rootNode: TreeNode = { - title: '/', - key: '/', - isLeaf: false - } - - setTreeData([rootNode]) - } - - // 异步加载子节点 - const loadData = async (node: any) => { - if (node.isLeaf) return // 如果是叶子节点(md文件),不加载子节点 - - setLoading(true) - try { - // 确保路径末尾有斜杠 - const path = node.key === '/' ? '' : node.key - const requestPath = path.endsWith('/') ? path : `${path}/` - - const response = await fetch(`${obsidianUrl}vault${requestPath}`, { - headers: { - Authorization: `Bearer ${obsidianApiKey}` - } - }) - const data = await response.json() - - if (!response.ok || (!data?.files && data?.errorCode !== 40400)) { - throw new Error('获取文件夹失败') - } - - const childNodes: TreeNode[] = (data.files || []) - .filter((file: string) => file.endsWith('/') || (showMdFiles && file.endsWith('.md'))) // 根据开关状态决定是否显示md文件 - .map((file: string) => { - // 修复路径问题,避免重复的斜杠 - const normalizedFile = file.replace('/', '') - const isMdFile = file.endsWith('.md') - const childPath = requestPath.endsWith('/') - ? `${requestPath}${normalizedFile}${isMdFile ? '' : '/'}` - : `${requestPath}/${normalizedFile}${isMdFile ? '' : '/'}` - - return { - title: normalizedFile, - key: childPath, - isLeaf: isMdFile, - isMdFile - } - }) - - // 更新节点的子节点 - setTreeData((origin) => { - const loop = (data: TreeNode[], key: string, children: TreeNode[]): TreeNode[] => { - return data.map((item) => { - if (item.key === key) { - return { - ...item, - children - } - } - if (item.children) { - return { - ...item, - children: loop(item.children, key, children) - } - } - return item - }) - } - return loop(origin, node.key, childNodes) - }) - } catch (error) { - window.message.error(t('chat.topics.export.obsidian_fetch_failed')) - } finally { - setLoading(false) - } - } - - // 处理开关切换 - const handleSwitchChange = (checked: boolean) => { - setShowMdFiles(checked) - // 重置选择 - setCurrentSelection({ - path: defaultPath, - isMdFile: false - }) - onPathChange(defaultPath, false) - - // 重置Tree状态并强制重新渲染 - setTreeData([]) - setExpandedKeys(['/']) - - // 递增key值以强制Tree组件完全重新渲染 - setTreeKey((prev) => prev + 1) - - // 延迟初始化根节点,让状态完全清除 - setTimeout(() => { - initializeRootNode() - }, 50) - } - - // 自定义图标,为md文件和文件夹显示不同的图标 - const renderIcon = (props: any) => { - const { data } = props - if (data.isMdFile) { - return - } - return - } - - return ( - - - {t('chat.topics.export.obsidian_show_md_files')} - - - - - setExpandedKeys(keys as string[])} - treeData={treeData} - loadData={loadData} - onSelect={(selectedKeys, info) => { - if (selectedKeys.length > 0) { - const path = selectedKeys[0] as string - const isMdFile = !!(info.node as any).isMdFile - - setCurrentSelection({ - path, - isMdFile - }) - - onPathChange?.(path, isMdFile) - } - }} - showLine - showIcon - icon={renderIcon} - /> - - -
- {currentSelection.path !== defaultPath && ( - - {t('chat.topics.export.obsidian_selected_path')}: {currentSelection.path} - - )} -
-
- ) -} - -const Container = styled.div` - display: flex; - flex-direction: column; - height: 400px; -` - -const TreeContainer = styled.div` - flex: 1; - overflow-y: auto; - border: 1px solid var(--color-border); - border-radius: 4px; - padding: 10px; - margin-bottom: 10px; - height: 320px; -` - -const SwitchContainer = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 10px; - padding: 0 10px; -` - -const SelectedPath = styled.div` - font-size: 12px; - color: var(--color-text-2); - margin-top: 5px; - padding: 0 10px; - word-break: break-all; -` - -export default ObsidianFolderSelector diff --git a/src/renderer/src/components/Popups/ObsidianExportPopup.tsx b/src/renderer/src/components/Popups/ObsidianExportPopup.tsx index b258e9cdb..5f229d74a 100644 --- a/src/renderer/src/components/Popups/ObsidianExportPopup.tsx +++ b/src/renderer/src/components/Popups/ObsidianExportPopup.tsx @@ -1,68 +1,52 @@ -import ObsidianFolderSelector from '@renderer/components/ObsidianFolderSelector' +import ObsidianExportDialog from '@renderer/components/ObsidianExportDialog' import i18n from '@renderer/i18n' import store from '@renderer/store' -import { exportMarkdownToObsidian } from '@renderer/utils/export' +import { createRoot } from 'react-dom/client' interface ObsidianExportOptions { title: string markdown: string + processingMethod: string | '3' // 默认新增(存在就覆盖) } -// 用于显示 Obsidian 导出对话框 +/** + * 配置Obsidian 笔记属性弹窗 + * @param options.title 标题 + * @param options.markdown markdown内容 + * @param options.processingMethod 处理方式 + * @returns + */ const showObsidianExportDialog = async (options: ObsidianExportOptions): Promise => { - const { title, markdown } = options - const obsidianUrl = store.getState().settings.obsidianUrl - const obsidianApiKey = store.getState().settings.obsidianApiKey + const obsidianValut = store.getState().settings.obsidianValut + const obsidianFolder = store.getState().settings.obsidianFolder - if (!obsidianUrl || !obsidianApiKey) { + if (!obsidianValut || !obsidianFolder) { window.message.error(i18n.t('chat.topics.export.obsidian_not_configured')) return false } - try { - // 创建一个状态变量来存储选择的路径 - let selectedPath = '/' - let selectedIsMdFile = false + return new Promise((resolve) => { + const div = document.createElement('div') + document.body.appendChild(div) + const root = createRoot(div) - // 显示文件夹选择对话框 - return new Promise((resolve) => { - window.modal.confirm({ - title: i18n.t('chat.topics.export.obsidian_select_folder'), - content: ( - { - selectedPath = path - selectedIsMdFile = isMdFile - }} - /> - ), - width: 600, - icon: null, - closable: true, - maskClosable: true, - centered: true, - okButtonProps: { type: 'primary' }, - okText: i18n.t('chat.topics.export.obsidian_select_folder.btn'), - onOk: () => { - // 如果选择的是md文件,则使用选择的文件名而不是传入的标题 - const fileName = selectedIsMdFile ? selectedPath.split('/').pop()?.replace('.md', '') : title - - exportMarkdownToObsidian(fileName as string, markdown, selectedPath, selectedIsMdFile) - resolve(true) - }, - onCancel: () => { - resolve(false) - } - }) - }) - } catch (error) { - window.message.error(i18n.t('chat.topics.export.obsidian_fetch_failed')) - console.error(error) - return false - } + const handleClose = (success: boolean) => { + root.unmount() + document.body.removeChild(div) + resolve(success) + } + const obsidianTags = store.getState().settings.obsidianTages + root.render( + + ) + }) } const ObsidianExportPopup = { diff --git a/src/renderer/src/components/Popups/SelectModelPopup.tsx b/src/renderer/src/components/Popups/SelectModelPopup.tsx index 06e7e0454..fe5bf0526 100644 --- a/src/renderer/src/components/Popups/SelectModelPopup.tsx +++ b/src/renderer/src/components/Popups/SelectModelPopup.tsx @@ -1,6 +1,6 @@ import { PushpinOutlined, SearchOutlined } from '@ant-design/icons' import { TopView } from '@renderer/components/TopView' -import { getModelLogo, isEmbeddingModel } from '@renderer/config/models' +import { getModelLogo, isEmbeddingModel, isRerankModel } from '@renderer/config/models' import db from '@renderer/databases' import { useProviders } from '@renderer/hooks/useProvider' import { getModelUniqId } from '@renderer/services/ModelService' @@ -76,7 +76,7 @@ const PopupContainer: React.FC = ({ model, resolve }) => { // 根据输入的文本筛选模型 const getFilteredModels = useCallback( (provider) => { - let models = provider.models.filter((m) => !isEmbeddingModel(m)) + let models = provider.models.filter((m) => !isEmbeddingModel(m) && !isRerankModel(m)) if (searchText.trim()) { const keywords = searchText.toLowerCase().split(/\s+/).filter(Boolean) diff --git a/src/renderer/src/config/models.ts b/src/renderer/src/config/models.ts index 2b35d9943..597fbcbf6 100644 --- a/src/renderer/src/config/models.ts +++ b/src/renderer/src/config/models.ts @@ -172,7 +172,7 @@ export const TEXT_TO_IMAGE_REGEX = /flux|diffusion|stabilityai|sd-|dall|cogview| // Reasoning models export const REASONING_REGEX = - /^(o\d+(?:-[\w-]+)?|.*\b(?:reasoner|thinking)\b.*|.*-[rR]\d+.*|.*\bqwq(?:-[\w-]+)?\b.*)$/i + /^(o\d+(?:-[\w-]+)?|.*\b(?:reasoner|thinking)\b.*|.*-[rR]\d+.*|.*\bqwq(?:-[\w-]+)?\b.*|.*\bhunyuan-t1(?:-[\w-]+)?\b.*)$/i // Embedding models export const EMBEDDING_REGEX = /(?:^text-|embed|bge-|e5-|LLM2Vec|retrieval|uae-|gte-|jina-clip|jina-embeddings)/i @@ -1102,6 +1102,12 @@ export const SYSTEM_MODELS: Record = { name: 'GLM 4V', group: 'GLM-4v' }, + { + id: 'glm-4v-flash', + provider: 'zhipu', + name: 'GLM-4V-Flash', + group: 'GLM-4v' + }, { id: 'glm-4v-plus', provider: 'zhipu', @@ -1872,6 +1878,8 @@ export const TEXT_TO_IMAGES_MODELS_SUPPORT_IMAGE_ENHANCEMENT = [ 'stabilityai/stable-diffusion-xl-base-1.0' ] +export const GENERATE_IMAGE_MODELS = ['gemini-2.0-flash-exp-image-generation', 'gemini-2.0-flash-exp'] + export function isTextToImageModel(model: Model): boolean { return TEXT_TO_IMAGE_REGEX.test(model.id) } @@ -1889,14 +1897,15 @@ export function isEmbeddingModel(model: Model): boolean { return EMBEDDING_REGEX.test(model.name) } + if (isRerankModel(model)) { + return false + } + return EMBEDDING_REGEX.test(model.id) || model.type?.includes('embedding') || false } export function isRerankModel(model: Model): boolean { - if (!model) { - return false - } - return RERANKING_REGEX.test(model.id) || false + return model ? RERANKING_REGEX.test(model.id) || false : false } export function isVisionModel(model: Model): boolean { @@ -2002,6 +2011,28 @@ export function isWebSearchModel(model: Model): boolean { return false } +export function isGenerateImageModel(model: Model): boolean { + if (!model) { + return false + } + + const provider = getProviderByModel(model) + + if (!provider) { + return false + } + + const isEmbedding = isEmbeddingModel(model) + + if (isEmbedding) { + return false + } + if (GENERATE_IMAGE_MODELS.includes(model.id)) { + return true + } + return false +} + export function getOpenAIWebSearchParams(assistant: Assistant, model: Model): Record { if (isWebSearchModel(model)) { if (assistant.enableWebSearch) { diff --git a/src/renderer/src/config/providers.ts b/src/renderer/src/config/providers.ts index e371df0d2..7e01f5f86 100644 --- a/src/renderer/src/config/providers.ts +++ b/src/renderer/src/config/providers.ts @@ -93,6 +93,8 @@ export function getProviderLogo(providerId: string) { return PROVIDER_LOGO_MAP[providerId as keyof typeof PROVIDER_LOGO_MAP] } +export const SUPPORTED_REANK_PROVIDERS = ['silicon', 'jina'] + export const PROVIDER_CONFIG = { openai: { api: { diff --git a/src/renderer/src/context/AntdProvider.tsx b/src/renderer/src/context/AntdProvider.tsx index ea5357b92..3e230931b 100644 --- a/src/renderer/src/context/AntdProvider.tsx +++ b/src/renderer/src/context/AntdProvider.tsx @@ -1,8 +1,12 @@ import { useSettings } from '@renderer/hooks/useSettings' import { LanguageVarious } from '@renderer/types' import { ConfigProvider, theme } from 'antd' +import elGR from 'antd/locale/el_GR' import enUS from 'antd/locale/en_US' +import esES from 'antd/locale/es_ES' +import frFR from 'antd/locale/fr_FR' import jaJP from 'antd/locale/ja_JP' +import ptPT from 'antd/locale/pt_PT' import ruRU from 'antd/locale/ru_RU' import zhCN from 'antd/locale/zh_CN' import zhTW from 'antd/locale/zh_TW' @@ -53,7 +57,14 @@ function getAntdLocale(language: LanguageVarious) { return ruRU case 'ja-JP': return jaJP - + case 'el-GR': + return elGR + case 'es-ES': + return esES + case 'fr-FR': + return frFR + case 'pt-PT': + return ptPT default: return zhCN } diff --git a/src/renderer/src/hooks/useSettings.ts b/src/renderer/src/hooks/useSettings.ts index abe673c26..0a05a162f 100644 --- a/src/renderer/src/hooks/useSettings.ts +++ b/src/renderer/src/hooks/useSettings.ts @@ -1,6 +1,8 @@ import store, { useAppDispatch, useAppSelector } from '@renderer/store' import { SendMessageShortcut, + setLaunchOnBoot, + setLaunchToTray, setSendMessageShortcut as _setSendMessageShortcut, setShowAssistantIcon, setSidebarIcons, @@ -8,7 +10,8 @@ import { setTheme, SettingsState, setTopicPosition, - setTray, + setTray as _setTray, + setTrayOnClose, setWindowStyle } from '@renderer/store/settings' import { SidebarIcon, ThemeMode, TranslateLanguageVarious } from '@renderer/types' @@ -22,10 +25,30 @@ export function useSettings() { setSendMessageShortcut(shortcut: SendMessageShortcut) { dispatch(_setSendMessageShortcut(shortcut)) }, - setTray(isActive: boolean) { - dispatch(setTray(isActive)) - window.api.setTray(isActive) + + setLaunch(isLaunchOnBoot: boolean | undefined, isLaunchToTray: boolean | undefined = undefined) { + if (isLaunchOnBoot !== undefined) { + dispatch(setLaunchOnBoot(isLaunchOnBoot)) + window.api.setLaunchOnBoot(isLaunchOnBoot) + } + + if (isLaunchToTray !== undefined) { + dispatch(setLaunchToTray(isLaunchToTray)) + window.api.setLaunchToTray(isLaunchToTray) + } }, + + setTray(isShowTray: boolean | undefined, isTrayOnClose: boolean | undefined = undefined) { + if (isShowTray !== undefined) { + dispatch(_setTray(isShowTray)) + window.api.setTray(isShowTray) + } + if (isTrayOnClose !== undefined) { + dispatch(setTrayOnClose(isTrayOnClose)) + window.api.setTrayOnClose(isTrayOnClose) + } + }, + setTheme(theme: ThemeMode) { dispatch(setTheme(theme)) }, diff --git a/src/renderer/src/i18n/index.ts b/src/renderer/src/i18n/index.ts index ac38e1dc7..ff4dda951 100644 --- a/src/renderer/src/i18n/index.ts +++ b/src/renderer/src/i18n/index.ts @@ -1,18 +1,28 @@ import i18n from 'i18next' import { initReactI18next } from 'react-i18next' +// Original translation import enUS from './locales/en-us.json' import jaJP from './locales/ja-jp.json' import ruRU from './locales/ru-ru.json' import zhCN from './locales/zh-cn.json' import zhTW from './locales/zh-tw.json' +// Machine translation +import elGR from './translate/el-gr.json' +import esES from './translate/es-es.json' +import frFR from './translate/fr-fr.json' +import ptPT from './translate/pt-pt.json' const resources = { + 'el-GR': elGR, 'en-US': enUS, - 'zh-CN': zhCN, - 'zh-TW': zhTW, + 'es-ES': esES, + 'fr-FR': frFR, 'ja-JP': jaJP, - 'ru-RU': ruRU + 'pt-PT': ptPT, + 'ru-RU': ruRU, + 'zh-CN': zhCN, + 'zh-TW': zhTW } export const getLanguage = () => { diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 8c68ccdbe..e35c2a3e5 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -105,6 +105,8 @@ "input.estimated_tokens.tip": "Estimated tokens", "input.expand": "Expand", "input.file_not_supported": "Model does not support this file type", + "input.generate_image": "Generate image", + "input.generate_image_not_supported": "The model does not support generating images.", "input.knowledge_base": "Knowledge Base", "input.new.context": "Clear Context {{Command}}", "input.new_topic": "New Topic {{Command}}", @@ -126,6 +128,12 @@ "message.quote": "Quote", "message.regenerate.model": "Switch Model", "message.useful": "Helpful", + "navigation": { + "first": "Already at the first message", + "last": "Already at the last message", + "next": "Next Message", + "prev": "Previous Message" + }, "resend": "Resend", "save": "Save", "settings.code_collapsible": "Code block collapsible", @@ -157,37 +165,42 @@ "topics.edit.placeholder": "Enter new name", "topics.edit.title": "Edit Name", "topics.export.image": "Export as image", + "topics.export.joplin": "Export to Joplin", "topics.export.md": "Export as markdown", "topics.export.notion": "Export to Notion", + "topics.export.obsidian": "Export to Obsidian", + "topics.export.obsidian_atributes": "Configure Note Attributes", + "topics.export.obsidian_btn": "Confirm", + "topics.export.obsidian_created": "Creation Time", + "topics.export.obsidian_created_placeholder": "Please select the creation time", + "topics.export.obsidian_export_failed": "Export failed", + "topics.export.obsidian_export_success": "Export success", + "topics.export.obsidian_not_configured": "Obsidian not configured", + "topics.export.obsidian_operate": "Operation Method", + "topics.export.obsidian_operate_append": "Append", + "topics.export.obsidian_operate_new_or_overwrite": "Create New (Overwrite if it exists)", + "topics.export.obsidian_operate_placeholder": "Please select the operation method", + "topics.export.obsidian_operate_prepend": "Prepend", + "topics.export.obsidian_source": "Source", + "topics.export.obsidian_source_placeholder": "Please enter the source", + "topics.export.obsidian_tags": "Tags", + "topics.export.obsidian_tags_placeholder": "Please enter tags, separate multiple tags with commas", + "topics.export.obsidian_title": "Title", + "topics.export.obsidian_title_placeholder": "Please enter the title", + "topics.export.obsidian_title_required": "The title cannot be empty", "topics.export.title": "Export", "topics.export.word": "Export as Word", "topics.export.yuque": "Export to Yuque", - "topics.export.obsidian": "Export to Obsidian", - "topics.export.obsidian_not_configured": "Obsidian not configured", - "topics.export.obsidian_fetch_failed": "Failed to fetch Obsidian folder structure", - "topics.export.obsidian_select_folder": "Select Obsidian folder", - "topics.export.obsidian_select_folder.btn": "Confirm", - "topics.export.obsidian_export_success": "Export success", - "topics.export.obsidian_export_failed": "Export failed", - "topics.export.obsidian_show_md_files": "Show MD Files", - "topics.export.obsidian_selected_path": "Selected Path", - "topics.export.joplin": "Export to Joplin", "topics.list": "Topic List", "topics.move_to": "Move to", + "topics.new": "New Topic", "topics.pinned": "Pinned Topics", "topics.prompt": "Topic Prompts", "topics.prompt.edit.title": "Edit Topic Prompts", "topics.prompt.tips": "Topic Prompts: Additional supplementary prompts provided for the current topic", "topics.title": "Topics", "topics.unpinned": "Unpinned Topics", - "topics.new": "New Topic", - "translate": "Translate", - "navigation": { - "prev": "Previous Message", - "next": "Next Message", - "first": "Already at the first message", - "last": "Already at the last message" - } + "translate": "Translate" }, "code_block": { "collapse": "Collapse", @@ -197,6 +210,7 @@ }, "common": { "add": "Add", + "advanced_settings": "Advanced Settings", "and": "and", "assistant": "Assistant", "avatar": "Avatar", @@ -205,6 +219,8 @@ "chat": "Chat", "clear": "Clear", "close": "Close", + "confirm": "Confirm", + "copied": "Copied", "copy": "Copy", "cut": "Cut", "default": "Default", @@ -214,6 +230,7 @@ "download": "Download", "duplicate": "Duplicate", "edit": "Edit", + "expand": "Expand", "footnote": "Reference content", "footnotes": "References", "fullscreen": "Entered fullscreen mode. Press F11 to exit", @@ -221,6 +238,7 @@ "language": "Language", "model": "Model", "models": "Models", + "more": "More", "name": "Name", "paste": "Paste", "prompt": "Prompt", @@ -233,12 +251,7 @@ "select": "Select", "topics": "Topics", "warning": "Warning", - "you": "You", - "copied": "Copied", - "confirm": "Confirm", - "more": "More", - "advanced_settings": "Advanced Settings", - "expand": "Expand" + "you": "You" }, "docs": { "title": "Docs" @@ -296,6 +309,12 @@ "title": "Files", "type": "Type" }, + "gpustack": { + "keep_alive_time.description": "The time in minutes to keep the connection alive, default is 5 minutes.", + "keep_alive_time.placeholder": "Minutes", + "keep_alive_time.title": "Keep Alive Time", + "title": "GPUStack" + }, "history": { "continue_chat": "Continue Chatting", "locate.message": "Locate the message", @@ -365,13 +384,13 @@ "threshold_too_large_or_small": "Threshold cannot be greater than 1 or less than 0", "threshold_tooltip": "Used to evaluate the relevance between the user's question and the content in the knowledge base (0-1)", "title": "Knowledge Base", + "topN": "Number of results returned", + "topN__too_large_or_small": "The number of results returned cannot be greater than 100 or less than 1.", + "topN_placeholder": "Not set", + "topN_tooltip": "The number of matching results returned; the larger the value, the more matching results, but also the more tokens consumed.", "url_added": "URL added", "url_placeholder": "Enter URL, multiple URLs separated by Enter", - "urls": "URLs", - "topN": "Number of results returned", - "topN_placeholder": "Not set", - "topN__too_large_or_small": "The number of results returned cannot be greater than 100 or less than 1.", - "topN_tooltip": "The number of matching results returned; the larger the value, the more matching results, but also the more tokens consumed." + "urls": "URLs" }, "languages": { "arabic": "Arabic", @@ -409,22 +428,22 @@ "title": "Mermaid Diagram" }, "message": { - "attachments": { - "pasted_text": "Pasted Text", - "pasted_image": "Pasted Image" - }, "api.check.model.title": "Select the model to use for detection", "api.connection.failed": "Connection failed", "api.connection.success": "Connection successful", "assistant.added.content": "Assistant added successfully", + "attachments": { + "pasted_image": "Pasted Image", + "pasted_text": "Pasted Text" + }, "backup.failed": "Backup failed", "backup.start.success": "Backup started", "backup.success": "Backup successful", "chat.completion.paused": "Chat completion paused", "citations": "References", "copied": "Copied!", - "copy.success": "Copied!", "copy.failed": "Copy failed", + "copy.success": "Copied!", "error.chunk_overlap_too_large": "Chunk overlap cannot be greater than chunk size", "error.dimension_too_large": "Content size is too large", "error.enter.api.host": "Please enter your API host first", @@ -437,18 +456,20 @@ "error.invalid.enter.model": "Please select a model", "error.invalid.proxy.url": "Invalid proxy URL", "error.invalid.webdav": "Invalid WebDAV settings", + "error.joplin.export": "Failed to export to Joplin. Please keep Joplin running and check connection status or configuration", + "error.joplin.no_config": "Joplin Authorization Token or URL is not configured", "error.markdown.export.preconf": "Failed to export the Markdown file to the preconfigured path", "error.markdown.export.specified": "Failed to export the Markdown file", "error.notion.export": "Failed to export to Notion. Please check connection status and configuration according to documentation", "error.notion.no_api_key": "Notion ApiKey or Notion DatabaseID is not configured", "error.yuque.export": "Failed to export to Yuque. Please check connection status and configuration according to documentation", "error.yuque.no_config": "Yuque Token or Yuque Url is not configured", - "error.joplin.no_config": "Joplin Authorization Token or URL is not configured", - "error.joplin.export": "Failed to export to Joplin. Please keep Joplin running and check connection status or configuration", "group.delete.content": "Deleting a group message will delete the user's question and all assistant's answers", "group.delete.title": "Delete Group Message", "ignore.knowledge.base": "Web search mode is enabled, ignore knowledge base", "info.notion.block_reach_limit": "Dialogue too long, exporting to Notion in pages", + "loading.notion.exporting_progress": "Exporting to Notion ({{current}}/{{total}})...", + "loading.notion.preparing": "Preparing to export to Notion...", "mention.title": "Switch model answer", "message.code_style": "Code style", "message.delete.content": "Are you sure you want to delete this message?", @@ -463,8 +484,6 @@ "message.style": "Message style", "message.style.bubble": "Bubble", "message.style.plain": "Plain", - "loading.notion.preparing": "Preparing to export to Notion...", - "loading.notion.exporting_progress": "Exporting to Notion ({{current}}/{{total}})...", "regenerate.confirm": "Regenerating will replace current message", "reset.confirm.content": "Are you sure you want to clear all data?", "reset.double.confirm.content": "All data will be lost, do you want to continue?", @@ -473,22 +492,22 @@ "restore.success": "Restored successfully", "save.success.title": "Saved successfully", "searching": "Searching the internet...", + "success.joplin.export": "Successfully exported to Joplin", "success.markdown.export.preconf": "Successfully exported the Markdown file to the preconfigured path", "success.markdown.export.specified": "Successfully exported the Markdown file", "success.notion.export": "Successfully exported to Notion", "success.yuque.export": "Successfully exported to Yuque", - "success.joplin.export": "Successfully exported to Joplin", "switch.disabled": "Please wait for the current reply to complete", + "tools": { + "completed": "Completed", + "invoking": "Invoking" + }, "topic.added": "New topic added", "upgrade.success.button": "Restart", "upgrade.success.content": "Please restart the application to complete the upgrade", "upgrade.success.title": "Upgrade successfully", "warn.notion.exporting": "Exporting to Notion, please do not request export repeatedly!", - "warning.rate.limit": "Too many requests. Please wait {{seconds}} seconds before trying again.", - "tools": { - "invoking": "Invoking", - "completed": "Completed" - } + "warning.rate.limit": "Too many requests. Please wait {{seconds}} seconds before trying again." }, "minapp": { "sidebar.add.title": "Add to sidebar", @@ -527,7 +546,7 @@ "embedding": "Embedding", "embedding_model": "Embedding Model", "embedding_model_tooltip": "Add in Settings->Model Provider->Manage", - "free": "Free", + "function_calling": "Function Calling", "no_matches": "No models available", "parameter_name": "Parameter Name", "parameter_type": { @@ -537,22 +556,22 @@ "string": "Text" }, "pinned": "Pinned", - "reasoning": "Reasoning", + "rerank_model": "Reordering Model", + "rerank_model_support_provider": "Currently, the reordering model only supports some providers ({{provider}})", + "rerank_model_tooltip": "Click the Manage button in Settings -> Model Services to add.", "search": "Search models...", "stream_output": "Stream output", - "function_calling": "Function Calling", "type": { "embedding": "Embedding", + "free": "Free", + "function_calling": "Tool", "reasoning": "Reasoning", + "rerank": "Reordering", "select": "Select Model Types", "text": "Text", "vision": "Vision", - "function_calling": "Function Calling" - }, - "vision": "Vision", - "websearch": "WebSearch", - "rerank_model": "Reordering Model", - "rerank_model_tooltip": "Click the Manage button in Settings -> Model Services to add." + "websearch": "WebSearch" + } }, "navbar": { "expand": "Expand Dialog", @@ -598,12 +617,6 @@ }, "title": "PlantUML Diagram" }, - "gpustack": { - "keep_alive_time.description": "The time in minutes to keep the connection alive, default is 5 minutes.", - "keep_alive_time.placeholder": "Minutes", - "keep_alive_time.title": "Keep Alive Time", - "title": "GPUStack" - }, "prompts": { "explanation": "Explain this concept to me", "summarize": "Summarize this text", @@ -611,10 +624,12 @@ }, "provider": { "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", "anthropic": "Anthropic", "azure-openai": "Azure OpenAI", "baichuan": "Baichuan", "baidu-cloud": "Baidu Cloud", + "copilot": "GitHub Copilot", "dashscope": "Alibaba Cloud", "deepseek": "DeepSeek", "dmxapi": "DMXAPI", @@ -623,6 +638,7 @@ "gemini": "Gemini", "gitee-ai": "Gitee AI", "github": "GitHub Models", + "gpustack": "GPUStack", "graphrag-kylin-mountain": "GraphRAG", "grok": "Grok", "groq": "Groq", @@ -651,10 +667,7 @@ "xirang": "State Cloud Xirang", "yi": "Yi", "zhinao": "360AI", - "zhipu": "ZHIPU AI", - "copilot": "GitHub Copilot", - "gpustack": "GPUStack", - "alayanew": "Alaya NeW" + "zhipu": "ZHIPU AI" }, "restore": { "confirm": "Are you sure you want to restore data?", @@ -716,15 +729,30 @@ "data.title": "Data Directory", "hour_interval_one": "{{count}} hour", "hour_interval_other": "{{count}} hours", - "minute_interval_one": "{{count}} minute", - "minute_interval_other": "{{count}} minutes", - "markdown_export.title": "Markdown Export", + "joplin": { + "check": { + "button": "Check", + "empty_token": "Please enter Joplin Authorization Token", + "empty_url": "Please enter Joplin Clipper Service URL", + "fail": "Joplin connection verification failed", + "success": "Joplin connection verification successful" + }, + "help": "In Joplin options, enable the web clipper (no browser extension needed), confirm the port, and copy the auth token here.", + "title": "Joplin Configuration", + "token": "Joplin Authorization Token", + "token_placeholder": "Joplin Authorization Token", + "url": "Joplin Web Clipper Service URL", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "When enabled, $$ will be forcibly used to mark LaTeX formulas when exporting to Markdown. Note: This option also affects all export methods through Markdown, such as Notion, Yuque, etc.", + "markdown_export.force_dollar_math.title": "Force $$ for LaTeX formulas", + "markdown_export.help": "If provided, exports will be automatically saved to this path; otherwise, a save dialog will appear.", "markdown_export.path": "Default Export Path", "markdown_export.path_placeholder": "Export Path", "markdown_export.select": "Select", - "markdown_export.help": "If provided, exports will be automatically saved to this path; otherwise, a save dialog will appear.", - "markdown_export.force_dollar_math.title": "Force $$ for LaTeX formulas", - "markdown_export.force_dollar_math.help": "When enabled, $$ will be forcibly used to mark LaTeX formulas when exporting to Markdown. Note: This option also affects all export methods through Markdown, such as Notion, Yuque, etc.", + "markdown_export.title": "Markdown Export", + "minute_interval_one": "{{count}} minute", + "minute_interval_other": "{{count}} minutes", "notion.api_key": "Notion API Key", "notion.api_key_placeholder": "Enter Notion API Key", "notion.auto_split": "Auto split when exporting", @@ -746,11 +774,22 @@ "notion.split_size_help": "Recommended: 90 for Free plan, 24990 for Plus plan, default is 90", "notion.split_size_placeholder": "Enter block limit per page (default 90)", "notion.title": "Notion Configuration", + "obsidian": { + "folder": "Folder", + "folder_placeholder": "Please enter the folder name", + "tags": "Global Tags", + "tags_placeholder": "Please enter the tag name, separate multiple tags with commas", + "title": "Obsidian Configuration", + "vault": "Vault", + "vault_placeholder": "Please enter the vault name" + }, "title": "Data Settings", "webdav": { "autoSync": "Auto Backup", "autoSync.off": "Off", "backup.button": "Backup to WebDAV", + "backup.modal.filename.placeholder": "Please enter backup filename", + "backup.modal.title": "Backup to WebDAV", "host": "WebDAV Host", "host.placeholder": "http://localhost:8080", "hour_interval_one": "{{count}} hour", @@ -762,14 +801,12 @@ "password": "WebDAV Password", "path": "WebDAV Path", "path.placeholder": "/backup", - "backup.modal.title": "Backup to WebDAV", - "backup.modal.filename.placeholder": "Please enter backup filename", - "restore.modal.title": "Restore from WebDAV", - "restore.modal.select.placeholder": "Please select a backup file to restore", - "restore.confirm.title": "Confirm Restore", - "restore.confirm.content": "Restoring from WebDAV will overwrite current data. Do you want to continue?", "restore.button": "Restore from WebDAV", + "restore.confirm.content": "Restoring from WebDAV will overwrite current data. Do you want to continue?", + "restore.confirm.title": "Confirm Restore", "restore.content": "Restore from WebDAV will overwrite the current data, continue?", + "restore.modal.select.placeholder": "Please select a backup file to restore", + "restore.modal.title": "Restore from WebDAV", "restore.title": "Restore from WebDAV", "syncError": "Backup Error", "syncStatus": "Backup Status", @@ -790,36 +827,6 @@ "title": "Yuque Configuration", "token": "Yuque Token", "token_placeholder": "Please enter the Yuque Token" - }, - "obsidian": { - "check": { - "button": "Check", - "empty_url": "Please enter the Obsidian REST API URL first", - "empty_api_key": "Please enter the Obsidian API Key first", - "fail": "Obsidian connection verification failed", - "success": "Obsidian connection verification successful" - }, - "help": "Install the Obsidian plugin Local REST API first, then get the Obsidian API Key", - "url": "Obsidian Knowledge Base URL", - "url_placeholder": "http://127.0.0.1:27123/", - "title": "Obsidian Configuration", - "api_key": "Obsidian API Key", - "api_key_placeholder": "Please enter the Obsidian API Key" - }, - "joplin": { - "check": { - "button": "Check", - "empty_url": "Please enter Joplin Clipper Service URL", - "empty_token": "Please enter Joplin Authorization Token", - "fail": "Joplin connection verification failed", - "success": "Joplin connection verification successful" - }, - "title": "Joplin Configuration", - "help": "In Joplin options, enable the web clipper (no browser extension needed), confirm the port, and copy the auth token here.", - "url": "Joplin Web Clipper Service URL", - "url_placeholder": "http://127.0.0.1:41184/", - "token": "Joplin Authorization Token", - "token_placeholder": "Joplin Authorization Token" } }, "display.assistant.title": "Assistant Settings", @@ -865,12 +872,15 @@ "input.target_language.english": "English", "input.target_language.japanese": "Japanese", "input.target_language.russian": "Russian", + "launch.onboot": "Start Automatically on Boot", + "launch.title": "Launch", + "launch.totray": "Minimize to Tray on Launch", "mcp": { "actions": "Actions", "active": "Active", + "addError": "Failed to add server", "addServer": "Add Server", "addSuccess": "Server added successfully", - "addError": "Failed to add server", "args": "Arguments", "argsTooltip": "Each argument on a new line", "baseUrlTooltip": "Remote server base URL", @@ -879,57 +889,53 @@ "config_description": "Configure Model Context Protocol servers", "confirmDelete": "Delete Server", "confirmDeleteMessage": "Are you sure you want to delete the server?", - "deleteSuccess": "Server deleted successfully", "deleteError": "Failed to delete server", + "deleteSuccess": "Server deleted successfully", + "dependenciesInstall": "Install Dependencies", + "dependenciesInstalling": "Installing dependencies...", "description": "Description", "duplicateName": "A server with this name already exists", + "editJson": "Edit JSON", "editServer": "Edit Server", "env": "Environment Variables", "envTooltip": "Format: KEY=value, one per line", "findMore": "Find More MCP Servers", + "install": "Install", + "installError": "Failed to install dependencies", + "installSuccess": "Dependencies installed successfully", + "jsonFormatError": "JSON formatting error", + "jsonModeHint": "Edit the JSON representation of the MCP server configuration. Please ensure the format is correct before saving.", + "jsonSaveError": "Failed to save JSON configuration.", + "jsonSaveSuccess": "JSON configuration has been saved.", + "missingDependencies": "is Missing, please install it to continue.", "name": "Name", "nameRequired": "Please enter a server name", "noServers": "No servers configured", + "npx_list": { + "actions": "Actions", + "desc": "Search and add npm packages as MCP servers", + "description": "Description", + "no_packages": "No packages found", + "npm": "NPM", + "package_name": "Package Name", + "scope_placeholder": "Enter npm scope (e.g. @your-org)", + "scope_required": "Please enter npm scope", + "search": "Search", + "search_error": "Search error", + "title": "NPX Package List", + "usage": "Usage", + "version": "Version" + }, "serverPlural": "servers", "serverSingular": "server", "title": "MCP Servers", - "type": "Type", - "updateSuccess": "Server updated successfully", - "updateError": "Failed to update server", - "url": "URL", "toggleError": "Toggle failed", - "dependenciesInstalling": "Installing dependencies...", - "dependenciesInstall": "Install Dependencies", - "installSuccess": "Dependencies installed successfully", - "installError": "Failed to install dependencies", - "missingDependencies": "is Missing, please install it to continue.", - "install": "Install", - "npx_list": { - "title": "NPX Package List", - "desc": "Search and add npm packages as MCP servers", - "scope_placeholder": "Enter npm scope (e.g. @your-org)", - "search": "Search", - "package_name": "Package Name", - "description": "Description", - "usage": "Usage", - "npm": "NPM", - "version": "Version", - "actions": "Actions", - "scope_required": "Please enter npm scope", - "no_packages": "No packages found", - "search_error": "Search error" - }, - "editJson": "Edit JSON", - "jsonModeHint": "Edit the JSON representation of the MCP server configuration. Please ensure the format is correct before saving.", - "jsonFormatError": "JSON formatting error", - "jsonSaveSuccess": "JSON configuration has been saved.", - "jsonSaveError": "Failed to save JSON configuration." + "type": "Type", + "updateError": "Failed to update server", + "updateSuccess": "Server updated successfully", + "url": "URL" }, "messages.divider": "Show divider between messages", - "messages.navigation": "Message Navigation", - "messages.navigation.none": "None", - "messages.navigation.buttons": "Navigation Buttons", - "messages.navigation.anchor": "Message Anchor", "messages.grid_columns": "Message grid display columns", "messages.grid_popover_trigger": "Grid detail trigger", "messages.grid_popover_trigger.click": "Click to display", @@ -943,6 +949,10 @@ "messages.math_engine": "Math engine", "messages.metrics": "{{time_first_token_millsec}}ms to first token | {{token_speed}} tok/sec", "messages.model.title": "Model Settings", + "messages.navigation": "Message Navigation", + "messages.navigation.anchor": "Message Anchor", + "messages.navigation.buttons": "Navigation Buttons", + "messages.navigation.none": "None", "messages.title": "Message Settings", "messages.use_serif_font": "Use serif font", "model": "Default Model", @@ -1005,43 +1015,43 @@ "check": "Check", "check_all_keys": "Check All Keys", "check_multiple_keys": "Check Multiple API Keys", + "copilot": { + "auth_failed": "Github Copilot authentication failed.", + "auth_success": "GitHub Copilot authentication successful.", + "auth_success_title": "Certification successful.", + "code_failed": "Failed to obtain Device Code, please try again.", + "code_generated_desc": "Please copy the device code into the browser link below.", + "code_generated_title": "Obtain Device Code", + "confirm_login": "Excessive use may lead to your Github account being banned, please use it cautiously!!!!", + "confirm_title": "Risk Warning", + "connect": "Connect to Github", + "custom_headers": "Custom request header", + "description": "Your GitHub account needs to subscribe to Copilot.", + "expand": "Expand", + "headers_description": "Custom request headers (JSON format)", + "invalid_json": "JSON format error", + "login": "Log in to Github", + "logout": "Exit GitHub", + "logout_failed": "Exit failed, please try again.", + "logout_success": "Successfully logged out.", + "model_setting": "Model settings", + "open_verification_first": "Please click the link above to access the verification page.", + "rate_limit": "Rate limiting", + "tooltip": "You need to log in to Github before using Github Copilot" + }, "delete.content": "Are you sure you want to delete this provider?", "delete.title": "Delete Provider", "docs_check": "Check", "docs_more_details": "for more details", "get_api_key": "Get API Key", + "is_not_support_array_content": "Enable compatible mode", "no_models": "Please add models first before checking the API connection", "not_checked": "Not Checked", "remove_duplicate_keys": "Remove Duplicate Keys", "remove_invalid_keys": "Remove Invalid Keys", "search": "Search Providers...", "search_placeholder": "Search model id or name", - "title": "Model Provider", - "is_not_support_array_content": "Enable compatible mode", - "copilot": { - "tooltip": "You need to log in to Github before using Github Copilot", - "description": "Your GitHub account needs to subscribe to Copilot.", - "login": "Log in to Github", - "connect": "Connect to Github", - "logout": "Exit GitHub", - "auth_success_title": "Certification successful.", - "code_generated_title": "Obtain Device Code", - "code_generated_desc": "Please copy the device code into the browser link below.", - "code_failed": "Failed to obtain Device Code, please try again.", - "auth_success": "GitHub Copilot authentication successful.", - "auth_failed": "Github Copilot authentication failed.", - "logout_success": "Successfully logged out.", - "logout_failed": "Exit failed, please try again.", - "confirm_title": "Risk Warning", - "confirm_login": "Excessive use may lead to your Github account being banned, please use it cautiously!!!!", - "rate_limit": "Rate limiting", - "custom_headers": "Custom request header", - "headers_description": "Custom request headers (JSON format)", - "expand": "Expand", - "model_setting": "Model settings", - "invalid_json": "JSON format error", - "open_verification_first": "Please click the link above to access the verification page." - } + "title": "Model Provider" }, "proxy": { "mode": { @@ -1056,9 +1066,9 @@ "quickAssistant": { "click_tray_to_show": "Click the tray icon to start", "enable_quick_assistant": "Enable Quick Assistant", + "read_clipboard_at_startup": "Read clipboard at startup", "title": "Quick Assistant", - "use_shortcut_to_show": "Right-click the tray icon or use shortcuts to start", - "read_clipboard_at_startup": "Read clipboard at startup" + "use_shortcut_to_show": "Right-click the tray icon or use shortcuts to start" }, "shortcuts": { "action": "Action", @@ -1095,14 +1105,18 @@ "topic.position.left": "Left", "topic.position.right": "Right", "topic.show.time": "Show topic time", - "tray.title": "Enable System Tray Icon", + "tray.onclose": "Minimize to Tray on Close", + "tray.show": "Show Tray Icon", + "tray.title": "Tray", "websearch": { "blacklist": "Blacklist", "blacklist_description": "Results from the following websites will not appear in search results", "blacklist_tooltip": "Please use the following format (separated by line breaks)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", "check": "Check", - "check_success": "Verification successful", "check_failed": "Verification failed", + "check_success": "Verification successful", + "enhance_mode": "Search enhance mode", + "enhance_mode_tooltip": "Use the default model to extract search keywords from the problem and search", "get_api_key": "Get API Key", "no_provider_selected": "Please select a search service provider before checking.", "search_max_result": "Number of search results", @@ -1110,8 +1124,6 @@ "search_provider_placeholder": "Choose a search service provider.", "search_result_default": "Default", "search_with_time": "Search with dates included", - "enhance_mode": "Search enhance mode", - "enhance_mode_tooltip": "Use the default model to extract search keywords from the problem and search", "tavily": { "api_key": "Tavily API Key", "api_key.placeholder": "Enter Tavily API Key", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 68066152d..3d6bab82e 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -105,6 +105,8 @@ "input.estimated_tokens.tip": "推定トークン数", "input.expand": "展開", "input.file_not_supported": "モデルはこのファイルタイプをサポートしません", + "input.generate_image": "画像を生成する", + "input.generate_image_not_supported": "モデルは画像の生成をサポートしていません。", "input.knowledge_base": "ナレッジベース", "input.new.context": "コンテキストをクリア {{Command}}", "input.new_topic": "新しいトピック {{Command}}", @@ -126,6 +128,12 @@ "message.quote": "引用", "message.regenerate.model": "モデルを切り替え", "message.useful": "役立つ", + "navigation": { + "first": "最初のメッセージです", + "last": "最後のメッセージです", + "next": "次のメッセージ", + "prev": "前のメッセージ" + }, "resend": "再送信", "save": "保存", "settings.code_collapsible": "コードブロック折り畳み", @@ -157,37 +165,42 @@ "topics.edit.placeholder": "新しい名前を入力", "topics.edit.title": "名前を編集", "topics.export.image": "画像としてエクスポート", + "topics.export.joplin": "Joplin にエクスポート", "topics.export.md": "Markdownとしてエクスポート", "topics.export.notion": "Notion にエクスポート", + "topics.export.obsidian": "Obsidian にエクスポート", + "topics.export.obsidian_atributes": "ノートの属性を設定", + "topics.export.obsidian_btn": "確定", + "topics.export.obsidian_created": "作成日時", + "topics.export.obsidian_created_placeholder": "作成日時を選択してください", + "topics.export.obsidian_export_failed": "エクスポート失敗", + "topics.export.obsidian_export_success": "エクスポート成功", + "topics.export.obsidian_not_configured": "Obsidian 未設定", + "topics.export.obsidian_operate": "処理方法", + "topics.export.obsidian_operate_append": "追加", + "topics.export.obsidian_operate_new_or_overwrite": "新規作成(既に存在する場合は上書き)", + "topics.export.obsidian_operate_placeholder": "処理方法を選択してください", + "topics.export.obsidian_operate_prepend": "先頭に追加", + "topics.export.obsidian_source": "ソース", + "topics.export.obsidian_source_placeholder": "ソースを入力してください", + "topics.export.obsidian_tags": "タグ", + "topics.export.obsidian_tags_placeholder": "タグを入力してください。複数のタグは英語のコンマで区切ってください", + "topics.export.obsidian_title": "タイトル", + "topics.export.obsidian_title_placeholder": "タイトルを入力してください", + "topics.export.obsidian_title_required": "タイトルは空白にできません", "topics.export.title": "エクスポート", "topics.export.word": "Wordとしてエクスポート", "topics.export.yuque": "語雀にエクスポート", - "topics.export.obsidian": "Obsidian にエクスポート", - "topics.export.obsidian_not_configured": "Obsidian 未設定", - "topics.export.obsidian_fetch_failed": "Obsidian ファイルフォルダ構造取得失敗", - "topics.export.obsidian_select_folder": "Obsidian ファイルフォルダ選択", - "topics.export.obsidian_select_folder.btn": "確定", - "topics.export.obsidian_export_success": "エクスポート成功", - "topics.export.obsidian_export_failed": "エクスポート失敗", - "topics.export.obsidian_show_md_files": "mdファイルを表示", - "topics.export.obsidian_selected_path": "選択済みパス", - "topics.export.joplin": "Joplin にエクスポート", "topics.list": "トピックリスト", "topics.move_to": "移動先", + "topics.new": "新しいトピック", "topics.pinned": "トピックを固定", "topics.prompt": "トピック提示語", "topics.prompt.edit.title": "トピック提示語を編集する", "topics.prompt.tips": "トピック提示語:現在のトピックに対して追加の補足提示語を提供", "topics.title": "トピック", "topics.unpinned": "固定解除", - "topics.new": "新しいトピック", - "translate": "翻訳", - "navigation": { - "prev": "前のメッセージ", - "next": "次のメッセージ", - "first": "最初のメッセージです", - "last": "最後のメッセージです" - } + "translate": "翻訳" }, "code_block": { "collapse": "折りたたむ", @@ -197,6 +210,7 @@ }, "common": { "add": "追加", + "advanced_settings": "詳細設定", "and": "と", "assistant": "アシスタント", "avatar": "アバター", @@ -205,6 +219,8 @@ "chat": "チャット", "clear": "クリア", "close": "閉じる", + "confirm": "確認", + "copied": "コピーされました", "copy": "コピー", "cut": "切り取り", "default": "デフォルト", @@ -214,6 +230,7 @@ "download": "ダウンロード", "duplicate": "複製", "edit": "編集", + "expand": "展開", "footnote": "引用内容", "footnotes": "脚注", "fullscreen": "全画面モードに入りました。F11キーで終了します", @@ -221,6 +238,7 @@ "language": "言語", "model": "モデル", "models": "モデル", + "more": "もっと", "name": "名前", "paste": "貼り付け", "prompt": "プロンプト", @@ -233,12 +251,7 @@ "select": "選択", "topics": "トピック", "warning": "警告", - "you": "あなた", - "copied": "コピーされました", - "confirm": "確認", - "more": "もっと", - "advanced_settings": "詳細設定", - "expand": "展開" + "you": "あなた" }, "docs": { "title": "ドキュメント" @@ -296,6 +309,12 @@ "title": "ファイル", "type": "タイプ" }, + "gpustack": { + "keep_alive_time.description": "モデルがメモリに保持される時間(デフォルト:5分)", + "keep_alive_time.placeholder": "分", + "keep_alive_time.title": "保持時間", + "title": "GPUStack" + }, "history": { "continue_chat": "チャットを続ける", "locate.message": "メッセージを探す", @@ -365,13 +384,13 @@ "threshold_too_large_or_small": "しきい値は0より大きく1より小さい必要があります", "threshold_tooltip": "ユーザーの質問と知識ベースの内容の関連性を評価するためのしきい値(0-1)", "title": "ナレッジベース", + "topN": "返却される結果の数", + "topN__too_large_or_small": "結果の数は100より大きくてはならず、1より小さくてはなりません。", + "topN_placeholder": "未設定", + "topN_tooltip": "返されるマッチ結果の数は、数値が大きいほどマッチ結果が多くなりますが、消費されるトークンも増えます。", "url_added": "URLが追加されました", "url_placeholder": "URLを入力, 複数のURLはEnterで区切る", - "urls": "URL", - "topN": "返却される結果の数", - "topN_placeholder": "未設定", - "topN__too_large_or_small": "結果の数は100より大きくてはならず、1より小さくてはなりません。", - "topN_tooltip": "返されるマッチ結果の数は、数値が大きいほどマッチ結果が多くなりますが、消費されるトークンも増えます。" + "urls": "URL" }, "languages": { "arabic": "アラビア語", @@ -409,22 +428,22 @@ "title": "Mermaid図" }, "message": { - "attachments": { - "pasted_text": "クリップボードファイル", - "pasted_image": "クリップボード画像" - }, "api.check.model.title": "検出に使用するモデルを選択してください", "api.connection.failed": "接続に失敗しました", "api.connection.success": "接続に成功しました", "assistant.added.content": "アシスタントが追加されました", + "attachments": { + "pasted_image": "クリップボード画像", + "pasted_text": "クリップボードファイル" + }, "backup.failed": "バックアップに失敗しました", "backup.start.success": "バックアップを開始しました", "backup.success": "バックアップに成功しました", "chat.completion.paused": "チャットの完了が一時停止されました", "citations": "参考文献", "copied": "コピーしました!", - "copy.success": "コピーしました!", "copy.failed": "コピーに失敗しました", + "copy.success": "コピーしました!", "error.chunk_overlap_too_large": "チャンクの重なりは、チャンクサイズを超えることはできません", "error.dimension_too_large": "内容のサイズが大きすぎます", "error.enter.api.host": "APIホストを入力してください", @@ -437,20 +456,20 @@ "error.invalid.enter.model": "モデルを選択してください", "error.invalid.proxy.url": "無効なプロキシURL", "error.invalid.webdav": "無効なWebDAV設定", + "error.joplin.export": "Joplin へのエクスポートに失敗しました。Joplin が実行中であることを確認してください", + "error.joplin.no_config": "Joplin 認証トークン または URL が設定されていません", "error.markdown.export.preconf": "Markdown ファイルを事前設定されたパスにエクスポートできませんでした", "error.markdown.export.specified": "Markdown ファイルのエクスポートに失敗しました", "error.notion.export": "Notionへのエクスポートに失敗しました。接続状態と設定を確認してください", "error.notion.no_api_key": "Notion ApiKey または Notion DatabaseID が設定されていません", "error.yuque.export": "語雀へのエクスポートに失敗しました。接続状態と設定を確認してください", "error.yuque.no_config": "語雀Token または 知識ベースID が設定されていません", - "error.joplin.no_config": "Joplin 認証トークン または URL が設定されていません", - "error.joplin.export": "Joplin へのエクスポートに失敗しました。Joplin が実行中であることを確認してください", "group.delete.content": "分組メッセージを削除するとユーザーの質問と助け手の回答がすべて削除されます", "group.delete.title": "分組メッセージを削除", - "loading.notion.preparing": "Notionへのエクスポートを準備中...", - "loading.notion.exporting_progress": "Notionにエクスポート中 ({{current}}/{{total}})...", "ignore.knowledge.base": "インターネットモードが有効になっています。ナレッジベースを無視します", "info.notion.block_reach_limit": "会話が長すぎます。Notionにページごとにエクスポートしています", + "loading.notion.exporting_progress": "Notionにエクスポート中 ({{current}}/{{total}})...", + "loading.notion.preparing": "Notionへのエクスポートを準備中...", "mention.title": "モデルを切り替える", "message.code_style": "コードスタイル", "message.delete.content": "このメッセージを削除してもよろしいですか?", @@ -473,22 +492,22 @@ "restore.success": "復元に成功しました", "save.success.title": "保存に成功しました", "searching": "インターネットで検索中...", + "success.joplin.export": "Joplin へのエクスポートに成功しました", "success.markdown.export.preconf": "Markdown ファイルを事前設定されたパスに正常にエクスポートしました", "success.markdown.export.specified": "Markdown ファイルを正常にエクスポートしました", "success.notion.export": "Notionへのエクスポートに成功しました", "success.yuque.export": "語雀へのエクスポートに成功しました", - "success.joplin.export": "Joplin へのエクスポートに成功しました", "switch.disabled": "現在の応答が完了するまで切り替えを無効にします", + "tools": { + "completed": "完了", + "invoking": "呼び出し中" + }, "topic.added": "新しいトピックが追加されました", "upgrade.success.button": "再起動", "upgrade.success.content": "アップグレードを完了するためにアプリケーションを再起動してください", "upgrade.success.title": "アップグレードに成功しました", "warn.notion.exporting": "Notionにエクスポート中です。重複してエクスポートしないでください! ", - "warning.rate.limit": "送信が頻繁すぎます。{{seconds}} 秒待ってから再試行してください。", - "tools": { - "invoking": "呼び出し中", - "completed": "完了" - } + "warning.rate.limit": "送信が頻繁すぎます。{{seconds}} 秒待ってから再試行してください。" }, "minapp": { "sidebar.add.title": "サイドバーに追加", @@ -527,7 +546,7 @@ "embedding": "埋め込み", "embedding_model": "埋め込み模型", "embedding_model_tooltip": "設定->モデルサービス->管理で追加", - "free": "無料", + "function_calling": "関数呼び出し", "no_matches": "利用可能なモデルがありません", "parameter_name": "パラメータ名", "parameter_type": { @@ -537,22 +556,22 @@ "string": "テキスト" }, "pinned": "固定済み", - "reasoning": "推論", + "rerank_model": "再順序付けモデル", + "rerank_model_support_provider": "現在の再順序付けモデルは、{{provider}} のみサポートしています", + "rerank_model_tooltip": "設定->モデルサービスに移動し、管理ボタンをクリックして追加します。", "search": "モデルを検索...", "stream_output": "ストリーム出力", - "function_calling": "関数呼び出し", "type": { "embedding": "埋め込み", + "free": "無料", + "function_calling": "ツール", "reasoning": "推論", + "rerank": "再順序付け", "select": "モデルタイプを選択", "text": "テキスト", "vision": "画像", - "function_calling": "関数呼び出し" - }, - "vision": "画像", - "websearch": "ウェブ検索", - "rerank_model": "再順序付けモデル", - "rerank_model_tooltip": "設定->モデルサービスに移動し、管理ボタンをクリックして追加します。" + "websearch": "ウェブ検索" + } }, "navbar": { "expand": "ダイアログを展開", @@ -598,12 +617,6 @@ }, "title": "PlantUML 図表" }, - "gpustack": { - "keep_alive_time.description": "モデルがメモリに保持される時間(デフォルト:5分)", - "keep_alive_time.placeholder": "分", - "keep_alive_time.title": "保持時間", - "title": "GPUStack" - }, "prompts": { "explanation": "この概念を説明してください", "summarize": "このテキストを要約してください", @@ -611,10 +624,12 @@ }, "provider": { "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", "anthropic": "Anthropic", "azure-openai": "Azure OpenAI", "baichuan": "百川", "baidu-cloud": "Baidu Cloud", + "copilot": "GitHub Copilot", "dashscope": "Alibaba Cloud", "deepseek": "DeepSeek", "dmxapi": "DMXAPI", @@ -623,6 +638,7 @@ "gemini": "Gemini", "gitee-ai": "Gitee AI", "github": "GitHub Models", + "gpustack": "GPUStack", "graphrag-kylin-mountain": "GraphRAG", "grok": "Grok", "groq": "Groq", @@ -651,10 +667,7 @@ "xirang": "天翼クラウド 息壤", "yi": "零一万物", "zhinao": "360智脳", - "zhipu": "智譜AI", - "copilot": "GitHub Copilot", - "gpustack": "GPUStack", - "alayanew": "Alaya NeW" + "zhipu": "智譜AI" }, "restore": { "confirm": "データを復元しますか?", @@ -716,15 +729,30 @@ "data.title": "データディレクトリ", "hour_interval_one": "{{count}} 時間", "hour_interval_other": "{{count}} 時間", - "minute_interval_one": "{{count}} 分", - "minute_interval_other": "{{count}} 分", - "markdown_export.title": "Markdown エクスポート", + "joplin": { + "check": { + "button": "確認", + "empty_token": "Joplin 認証トークン を先に入力してください", + "empty_url": "Joplin 剪輯服務 URL を先に入力してください", + "fail": "Joplin 接続確認に失敗しました", + "success": "Joplin 接続確認に成功しました" + }, + "help": "Joplin オプションで、剪輯サービスを有効にしてください。ポート番号を確認し、認証トークンをコピーしてください", + "title": "Joplin 設定", + "token": "Joplin 認証トークン", + "token_placeholder": "Joplin 認証トークンを入力してください", + "url": "Joplin 剪輯服務 URL", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "有効にすると、Markdownにエクスポートする際にLaTeX数式を$$で強制的にマークします。注意:この設定はNotion、Yuqueなど、Markdownを通じたすべてのエクスポート方法にも影響します。", + "markdown_export.force_dollar_math.title": "LaTeX数式に$$を強制使用", + "markdown_export.help": "入力された場合、エクスポート時に自動的にこのパスに保存されます。未入力の場合、保存ダイアログが表示されます。", "markdown_export.path": "デフォルトのエクスポートパス", "markdown_export.path_placeholder": "エクスポートパス", "markdown_export.select": "選択", - "markdown_export.help": "入力された場合、エクスポート時に自動的にこのパスに保存されます。未入力の場合、保存ダイアログが表示されます。", - "markdown_export.force_dollar_math.title": "LaTeX数式に$$を強制使用", - "markdown_export.force_dollar_math.help": "有効にすると、Markdownにエクスポートする際にLaTeX数式を$$で強制的にマークします。注意:この設定はNotion、Yuqueなど、Markdownを通じたすべてのエクスポート方法にも影響します。", + "markdown_export.title": "Markdown エクスポート", + "minute_interval_one": "{{count}} 分", + "minute_interval_other": "{{count}} 分", "notion.api_key": "Notion APIキー", "notion.api_key_placeholder": "Notion APIキーを入力してください", "notion.auto_split": "ダイアログをエクスポートすると自動ページ分割", @@ -746,11 +774,22 @@ "notion.split_size_help": "Notion無料版ユーザーは90、有料版ユーザーは24990、デフォルトは90", "notion.split_size_placeholder": "ページごとのブロック数制限を入力してください(デフォルト90)", "notion.title": "Notion 設定", + "obsidian": { + "folder": "フォルダー", + "folder_placeholder": "フォルダーの名前を入力してください", + "tags": "グローバルタグ", + "tags_placeholder": "タグの名前を入力してください。複数のタグは英語のコンマで区切ってください", + "title": "Obsidian の設定", + "vault": "ヴォールト(保管庫)", + "vault_placeholder": "保管庫の名前を入力してください" + }, "title": "データ設定", "webdav": { "autoSync": "自動バックアップ", "autoSync.off": "オフ", "backup.button": "WebDAVにバックアップ", + "backup.modal.filename.placeholder": "バックアップファイル名を入力してください", + "backup.modal.title": "WebDAV にバックアップ", "host": "WebDAVホスト", "host.placeholder": "http://localhost:8080", "hour_interval_one": "{{count}} 時間", @@ -763,18 +802,16 @@ "path": "WebDAVパス", "path.placeholder": "/backup", "restore.button": "WebDAVから復元", + "restore.confirm.content": "WebDAV から復元すると現在のデータが上書きされます。続行しますか?", + "restore.confirm.title": "復元を確認", "restore.content": "WebDAVから復元すると現在のデータが上書きされます。続行しますか?", + "restore.modal.select.placeholder": "復元するバックアップファイルを選択してください", + "restore.modal.title": "WebDAV から復元", "restore.title": "WebDAVから復元", "syncError": "バックアップエラー", "syncStatus": "バックアップ状態", "title": "WebDAV", - "user": "WebDAVユーザー", - "backup.modal.title": "WebDAV にバックアップ", - "backup.modal.filename.placeholder": "バックアップファイル名を入力してください", - "restore.modal.title": "WebDAV から復元", - "restore.modal.select.placeholder": "復元するバックアップファイルを選択してください", - "restore.confirm.title": "復元を確認", - "restore.confirm.content": "WebDAV から復元すると現在のデータが上書きされます。続行しますか?" + "user": "WebDAVユーザー" }, "yuque": { "check": { @@ -790,36 +827,6 @@ "title": "Yuque設定", "token": "Yuqueトークン", "token_placeholder": "Yuqueトークンを入力してください" - }, - "obsidian": { - "check": { - "button": "確認", - "empty_url": "Obsidian REST API URL を先に入力してください", - "empty_api_key": "Obsidian API Key を先に入力してください", - "fail": "Obsidian 接続確認に失敗しました", - "success": "Obsidian 接続確認に成功しました" - }, - "help": "Obsidian プラグイン Local REST API を先にインストールしてください。その後、Obsidian API Key を取得してください", - "url": "Obsidian 知識ベース URL", - "url_placeholder": "http://127.0.0.1:27123/", - "title": "Obsidian 設定", - "api_key": "Obsidian API Key", - "api_key_placeholder": "Obsidian API Key を入力してください" - }, - "joplin": { - "check": { - "button": "確認", - "empty_url": "Joplin 剪輯服務 URL を先に入力してください", - "empty_token": "Joplin 認証トークン を先に入力してください", - "fail": "Joplin 接続確認に失敗しました", - "success": "Joplin 接続確認に成功しました" - }, - "title": "Joplin 設定", - "help": "Joplin オプションで、剪輯サービスを有効にしてください。ポート番号を確認し、認証トークンをコピーしてください", - "url": "Joplin 剪輯服務 URL", - "url_placeholder": "http://127.0.0.1:41184/", - "token": "Joplin 認証トークン", - "token_placeholder": "Joplin 認証トークンを入力してください" } }, "display.assistant.title": "アシスタント設定", @@ -865,12 +872,15 @@ "input.target_language.english": "英語", "input.target_language.japanese": "日本語", "input.target_language.russian": "ロシア語", + "launch.onboot": "起動時に自動で開始", + "launch.title": "起動", + "launch.totray": "起動時にトレイに最小化", "mcp": { "actions": "操作", "active": "有効", + "addError": "サーバーの追加に失敗しました", "addServer": "サーバーを追加", "addSuccess": "サーバーが正常に追加されました", - "addError": "サーバーの追加に失敗しました", "args": "引数", "argsTooltip": "1行に1つの引数を入力してください", "baseUrlTooltip": "リモートURLアドレス", @@ -881,55 +891,51 @@ "confirmDeleteMessage": "本当にこのサーバーを削除しますか?", "deleteError": "サーバーの削除に失敗しました", "deleteSuccess": "サーバーが正常に削除されました", + "dependenciesInstall": "依存関係をインストール", + "dependenciesInstalling": "依存関係をインストール中...", "description": "説明", "duplicateName": "同じ名前のサーバーが既に存在します", + "editJson": "JSONを編集", "editServer": "サーバーを編集", "env": "環境変数", "envTooltip": "形式: KEY=value, 1行に1つ", "findMore": "MCP サーバーを見つける", + "install": "インストール", + "installError": "依存関係のインストールに失敗しました", + "installSuccess": "依存関係のインストールに成功しました", + "jsonFormatError": "JSONフォーマットエラー", + "jsonModeHint": "MCPサーバー設定のJSON表現を編集します。保存する前に、フォーマットが正しいことを確認してください。", + "jsonSaveError": "JSON設定の保存に失敗しました", + "jsonSaveSuccess": "JSON設定が保存されました。", + "missingDependencies": "が不足しています。続行するにはインストールしてください。", "name": "名前", "nameRequired": "サーバー名を入力してください", "noServers": "サーバーが設定されていません", + "npx_list": { + "actions": "アクション", + "desc": "npm パッケージを検索して MCP サーバーとして追加", + "description": "説明", + "no_packages": "パッケージが見つかりません", + "npm": "NPM", + "package_name": "パッケージ名", + "scope_placeholder": "npm スコープを入力 (例: @your-org)", + "scope_required": "npm スコープを入力してください", + "search": "検索", + "search_error": "パッケージの検索に失敗しました", + "title": "NPX パッケージリスト", + "usage": "使用法", + "version": "バージョン" + }, "serverPlural": "サーバー", "serverSingular": "サーバー", "title": "MCP サーバー", - "type": "タイプ", - "updateSuccess": "サーバーが正常に更新されました", - "updateError": "サーバーの更新に失敗しました", - "url": "URL", "toggleError": "切り替えに失敗しました", - "dependenciesInstalling": "依存関係をインストール中...", - "dependenciesInstall": "依存関係をインストール", - "installSuccess": "依存関係のインストールに成功しました", - "installError": "依存関係のインストールに失敗しました", - "missingDependencies": "が不足しています。続行するにはインストールしてください。", - "install": "インストール", - "npx_list": { - "title": "NPX パッケージリスト", - "desc": "npm パッケージを検索して MCP サーバーとして追加", - "scope_placeholder": "npm スコープを入力 (例: @your-org)", - "search": "検索", - "package_name": "パッケージ名", - "description": "説明", - "usage": "使用法", - "npm": "NPM", - "version": "バージョン", - "actions": "アクション", - "scope_required": "npm スコープを入力してください", - "no_packages": "パッケージが見つかりません", - "search_error": "パッケージの検索に失敗しました" - }, - "editJson": "JSONを編集", - "jsonModeHint": "MCPサーバー設定のJSON表現を編集します。保存する前に、フォーマットが正しいことを確認してください。", - "jsonFormatError": "JSONフォーマットエラー", - "jsonSaveSuccess": "JSON設定が保存されました。", - "jsonSaveError": "JSON設定の保存に失敗しました" + "type": "タイプ", + "updateError": "サーバーの更新に失敗しました", + "updateSuccess": "サーバーが正常に更新されました", + "url": "URL" }, "messages.divider": "メッセージ間に区切り線を表示", - "messages.navigation": "メッセージナビゲーション", - "messages.navigation.none": "表示しない", - "messages.navigation.buttons": "上下ボタン", - "messages.navigation.anchor": "会話アンカー", "messages.grid_columns": "メッセージグリッドの表示列数", "messages.grid_popover_trigger": "グリッド詳細トリガー", "messages.grid_popover_trigger.click": "クリックで表示", @@ -943,6 +949,10 @@ "messages.math_engine": "数式エンジン", "messages.metrics": "最初のトークンまでの時間 {{time_first_token_millsec}}ms | トークン速度 {{token_speed}} tok/sec", "messages.model.title": "モデル設定", + "messages.navigation": "メッセージナビゲーション", + "messages.navigation.anchor": "会話アンカー", + "messages.navigation.buttons": "上下ボタン", + "messages.navigation.none": "表示しない", "messages.title": "メッセージ設定", "messages.use_serif_font": "セリフフォントを使用", "model": "デフォルトモデル", @@ -1005,43 +1015,43 @@ "check": "チェック", "check_all_keys": "すべてのキーをチェック", "check_multiple_keys": "複数のAPIキーをチェック", + "copilot": { + "auth_failed": "Github Copilotの認証に失敗しました。", + "auth_success": "Github Copilotの認証が成功しました", + "auth_success_title": "認証成功", + "code_failed": "デバイスコードの取得に失敗しました。再試行してください。", + "code_generated_desc": "デバイスコードを下記のブラウザリンクにコピーしてください。", + "code_generated_title": "デバイスコードを取得する", + "confirm_login": "過度使用すると、あなたのGithubアカウントが停止される可能性があるため、慎重に使用してください!!!!", + "confirm_title": "リスク警告", + "connect": "GitHubに接続する", + "custom_headers": "カスタムリクエストヘッダー", + "description": "あなたのGithubアカウントはCopilotを購読する必要があります。", + "expand": "展開", + "headers_description": "カスタムリクエストヘッダー(JSONフォーマット)", + "invalid_json": "JSONフォーマットエラー", + "login": "GitHubにログインする", + "logout": "GitHubから退出する", + "logout_failed": "ログアウトに失敗しました。もう一度お試しください。", + "logout_success": "正常にログアウトしました。", + "model_setting": "モデル設定", + "open_verification_first": "上のリンクをクリックして、確認ページにアクセスしてください。", + "rate_limit": "レート制限", + "tooltip": "Github Copilot を使用するには、まず Github にログインする必要があります。" + }, "delete.content": "このプロバイダーを削除してもよろしいですか?", "delete.title": "プロバイダーを削除", "docs_check": "チェック", "docs_more_details": "詳細を確認", "get_api_key": "APIキーを取得", + "is_not_support_array_content": "互換モードを有効にする", "no_models": "API接続をチェックする前に、モデルを追加してください", "not_checked": "未チェック", "remove_duplicate_keys": "重複キーを削除", "remove_invalid_keys": "無効なキーを削除", "search": "プロバイダーを検索...", "search_placeholder": "モデルIDまたは名前を検索", - "title": "モデルプロバイダー", - "is_not_support_array_content": "互換モードを有効にする", - "copilot": { - "tooltip": "Github Copilot を使用するには、まず Github にログインする必要があります。", - "description": "あなたのGithubアカウントはCopilotを購読する必要があります。", - "login": "GitHubにログインする", - "connect": "GitHubに接続する", - "logout": "GitHubから退出する", - "auth_success_title": "認証成功", - "code_generated_title": "デバイスコードを取得する", - "code_generated_desc": "デバイスコードを下記のブラウザリンクにコピーしてください。", - "code_failed": "デバイスコードの取得に失敗しました。再試行してください。", - "auth_success": "Github Copilotの認証が成功しました", - "auth_failed": "Github Copilotの認証に失敗しました。", - "logout_success": "正常にログアウトしました。", - "logout_failed": "ログアウトに失敗しました。もう一度お試しください。", - "confirm_title": "リスク警告", - "confirm_login": "過度使用すると、あなたのGithubアカウントが停止される可能性があるため、慎重に使用してください!!!!", - "rate_limit": "レート制限", - "custom_headers": "カスタムリクエストヘッダー", - "headers_description": "カスタムリクエストヘッダー(JSONフォーマット)", - "expand": "展開", - "model_setting": "モデル設定", - "invalid_json": "JSONフォーマットエラー", - "open_verification_first": "上のリンクをクリックして、確認ページにアクセスしてください。" - } + "title": "モデルプロバイダー" }, "proxy": { "mode": { @@ -1056,9 +1066,9 @@ "quickAssistant": { "click_tray_to_show": "トレイアイコンをクリックして起動", "enable_quick_assistant": "クイックアシスタントを有効にする", + "read_clipboard_at_startup": "起動時にクリップボードを読み取る", "title": "クイックアシスタント", - "use_shortcut_to_show": "トレイアイコンを右クリックするか、ショートカットキーで起動できます", - "read_clipboard_at_startup": "起動時にクリップボードを読み取る" + "use_shortcut_to_show": "トレイアイコンを右クリックするか、ショートカットキーで起動できます" }, "shortcuts": { "action": "操作", @@ -1095,14 +1105,18 @@ "topic.position.left": "左", "topic.position.right": "右", "topic.show.time": "トピックの時間を表示", - "tray.title": "システムトレイアイコンを有効にする", + "tray.onclose": "閉じるときにトレイに最小化", + "tray.show": "トレイアイコンを表示", + "tray.title": "トレイ", "websearch": { "blacklist": "ブラックリスト", "blacklist_description": "以下のウェブサイトの結果は検索結果に表示されません", "blacklist_tooltip": "以下の形式を使用してください(改行区切り)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", "check": "チェック", - "check_success": "検証に成功しました", "check_failed": "検証に失敗しました", + "check_success": "検証に成功しました", + "enhance_mode": "検索強化モード", + "enhance_mode_tooltip": "デフォルトモデルを使用して問題から検索キーワードを抽出し、検索を実行します", "get_api_key": "APIキーを取得", "no_provider_selected": "検索サービスプロバイダーを選択してから再確認してください。", "search_max_result": "検索結果の数", @@ -1110,8 +1124,6 @@ "search_provider_placeholder": "検索サービスプロバイダーを選択する", "search_result_default": "デフォルト", "search_with_time": "日付を含む検索", - "enhance_mode": "検索強化モード", - "enhance_mode_tooltip": "デフォルトモデルを使用して問題から検索キーワードを抽出し、検索を実行します", "tavily": { "api_key": "Tavily API キー", "api_key.placeholder": "Tavily API キーを入力してください", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index b1b32680e..d3c854c4e 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -105,6 +105,8 @@ "input.estimated_tokens.tip": "Затраты токенов", "input.expand": "Развернуть", "input.file_not_supported": "Модель не поддерживает этот тип файла", + "input.generate_image": "Сгенерировать изображение", + "input.generate_image_not_supported": "Модель не поддерживает генерацию изображений.", "input.knowledge_base": "База знаний", "input.new.context": "Очистить контекст {{Command}}", "input.new_topic": "Новый топик {{Command}}", @@ -126,6 +128,12 @@ "message.quote": "Цитата", "message.regenerate.model": "Переключить модель", "message.useful": "Полезно", + "navigation": { + "first": "Уже первое сообщение", + "last": "Уже последнее сообщение", + "next": "Следующее сообщение", + "prev": "Предыдущее сообщение" + }, "resend": "Переотправить", "save": "Сохранить", "settings.code_collapsible": "Блок кода свернут", @@ -157,37 +165,42 @@ "topics.edit.placeholder": "Введите новый заголовок", "topics.edit.title": "Редактировать заголовок", "topics.export.image": "Экспорт как изображение", + "topics.export.joplin": "Экспорт в Joplin", "topics.export.md": "Экспорт как markdown", "topics.export.notion": "Экспорт в Notion", + "topics.export.obsidian": "Экспорт в Obsidian", + "topics.export.obsidian_atributes": "Настроить атрибуты заметки", + "topics.export.obsidian_btn": "Подтвердить", + "topics.export.obsidian_created": "Дата создания", + "topics.export.obsidian_created_placeholder": "Пожалуйста, выберите дату создания", + "topics.export.obsidian_export_failed": "Экспорт не удалось", + "topics.export.obsidian_export_success": "Экспорт успешно завершен", + "topics.export.obsidian_not_configured": "Obsidian не настроен", + "topics.export.obsidian_operate": "Метод обработки", + "topics.export.obsidian_operate_append": "Добавить в конец", + "topics.export.obsidian_operate_new_or_overwrite": "Создать новый (перезаписать, если уже существует)", + "topics.export.obsidian_operate_placeholder": "Пожалуйста, выберите метод обработки", + "topics.export.obsidian_operate_prepend": "Добавить в начало", + "topics.export.obsidian_source": "Источник", + "topics.export.obsidian_source_placeholder": "Пожалуйста, введите источник", + "topics.export.obsidian_tags": "Тэги", + "topics.export.obsidian_tags_placeholder": "Пожалуйста, введите имена тегов. Разделяйте несколько тегов запятыми на английском языке", + "topics.export.obsidian_title": "Заголовок", + "topics.export.obsidian_title_placeholder": "Пожалуйста, введите заголовок", + "topics.export.obsidian_title_required": "Заголовок не может быть пустым", "topics.export.title": "Экспорт", "topics.export.word": "Экспорт как Word", "topics.export.yuque": "Экспорт в Yuque", - "topics.export.obsidian": "Экспорт в Obsidian", - "topics.export.obsidian_not_configured": "Obsidian не настроен", - "topics.export.obsidian_fetch_failed": "Не удалось получить структуру файлов Obsidian", - "topics.export.obsidian_select_folder": "Выберите папку Obsidian", - "topics.export.obsidian_select_folder.btn": "Определить", - "topics.export.obsidian_export_success": "Экспорт успешно завершен", - "topics.export.obsidian_export_failed": "Экспорт не удалось", - "topics.export.obsidian_show_md_files": "Показать файлы MD", - "topics.export.obsidian_selected_path": "Выбранный путь", - "topics.export.joplin": "Экспорт в Joplin", "topics.list": "Список топиков", "topics.move_to": "Переместить в", + "topics.new": "Новый топик", "topics.pinned": "Закрепленные темы", "topics.prompt": "Тематические подсказки", "topics.prompt.edit.title": "Редактировать подсказки темы", "topics.prompt.tips": "Тематические подсказки: Дополнительные подсказки, предоставленные для текущей темы", "topics.title": "Топики", "topics.unpinned": "Открепленные темы", - "topics.new": "Новый топик", - "translate": "Перевести", - "navigation": { - "prev": "Предыдущее сообщение", - "next": "Следующее сообщение", - "first": "Уже первое сообщение", - "last": "Уже последнее сообщение" - } + "translate": "Перевести" }, "code_block": { "collapse": "Свернуть", @@ -197,6 +210,7 @@ }, "common": { "add": "Добавить", + "advanced_settings": "Дополнительные настройки", "and": "и", "assistant": "Ассистент", "avatar": "Аватар", @@ -205,6 +219,8 @@ "chat": "Чат", "clear": "Очистить", "close": "Закрыть", + "confirm": "Подтверждение", + "copied": "Скопировано", "copy": "Копировать", "cut": "Вырезать", "default": "По умолчанию", @@ -214,6 +230,7 @@ "download": "Скачать", "duplicate": "Дублировать", "edit": "Редактировать", + "expand": "Развернуть", "footnote": "Цитируемый контент", "footnotes": "Сноски", "fullscreen": "Вы вошли в полноэкранный режим. Нажмите F11 для выхода", @@ -221,6 +238,7 @@ "language": "Язык", "model": "Модель", "models": "Модели", + "more": "Ещё", "name": "Имя", "paste": "Вставить", "prompt": "Промпт", @@ -233,12 +251,7 @@ "select": "Выбрать", "topics": "Топики", "warning": "Предупреждение", - "you": "Вы", - "confirm": "Подтверждение", - "copied": "Скопировано", - "more": "Ещё", - "advanced_settings": "Дополнительные настройки", - "expand": "Развернуть" + "you": "Вы" }, "docs": { "title": "Документация" @@ -296,6 +309,12 @@ "title": "Файлы", "type": "Тип" }, + "gpustack": { + "keep_alive_time.description": "Время в минутах, в течение которого модель остается активной, по умолчанию 5 минут.", + "keep_alive_time.placeholder": "Минуты", + "keep_alive_time.title": "Время жизни модели", + "title": "GPUStack" + }, "history": { "continue_chat": "Продолжить чат", "locate.message": "Найти сообщение", @@ -365,13 +384,13 @@ "threshold_too_large_or_small": "Порог не может быть больше 1 или меньше 0", "threshold_tooltip": "Используется для оценки соответствия между пользовательским вопросом и содержимым в базе знаний (0-1)", "title": "База знаний", + "topN": "Количество возвращаемых результатов", + "topN__too_large_or_small": "Количество возвращаемых результатов не может быть больше 100 или меньше 1.", + "topN_placeholder": "Не установлено", + "topN_tooltip": "Количество возвращаемых совпадений; чем больше значение, тем больше совпадений, но и потребление токенов тоже возрастает.", "url_added": "URL добавлен", "url_placeholder": "Введите URL, несколько URL через Enter", - "urls": "URL-адреса", - "topN": "Количество возвращаемых результатов", - "topN_placeholder": "Не установлено", - "topN__too_large_or_small": "Количество возвращаемых результатов не может быть больше 100 или меньше 1.", - "topN_tooltip": "Количество возвращаемых совпадений; чем больше значение, тем больше совпадений, но и потребление токенов тоже возрастает." + "urls": "URL-адреса" }, "languages": { "arabic": "Арабский", @@ -408,29 +427,23 @@ }, "title": "Диаграмма Mermaid" }, - "gpustack": { - "keep_alive_time.description": "Время в минутах, в течение которого модель остается активной, по умолчанию 5 минут.", - "keep_alive_time.placeholder": "Минуты", - "keep_alive_time.title": "Время жизни модели", - "title": "GPUStack" - }, "message": { - "attachments": { - "pasted_text": "Вырезанный текст", - "pasted_image": "Вырезанное изображение" - }, "api.check.model.title": "Выберите модель для проверки", "api.connection.failed": "Соединение не удалось", "api.connection.success": "Соединение успешно", "assistant.added.content": "Ассистент успешно добавлен", + "attachments": { + "pasted_image": "Вырезанное изображение", + "pasted_text": "Вырезанный текст" + }, "backup.failed": "Создание резервной копии не удалось", "backup.start.success": "Создание резервной копии начато", "backup.success": "Резервная копия успешно создана", "chat.completion.paused": "Завершение чата приостановлено", "citations": "Источники", "copied": "Скопировано!", - "copy.success": "Скопировано!", "copy.failed": "Не удалось скопировать", + "copy.success": "Скопировано!", "error.chunk_overlap_too_large": "Перекрытие фрагментов не может быть больше размера фрагмента.", "error.dimension_too_large": "Размер содержимого слишком велик", "error.enter.api.host": "Пожалуйста, введите ваш API хост", @@ -443,20 +456,20 @@ "error.invalid.enter.model": "Пожалуйста, выберите модель", "error.invalid.proxy.url": "Неверный URL прокси", "error.invalid.webdav": "Неверные настройки WebDAV", + "error.joplin.export": "Не удалось экспортировать в Joplin, пожалуйста, убедитесь, что Joplin запущен и проверьте состояние подключения или настройки", + "error.joplin.no_config": "Joplin Authorization Token или URL не настроен", "error.markdown.export.preconf": "Не удалось экспортировать файл Markdown в предуказанный путь", "error.markdown.export.specified": "Не удалось экспортировать файл Markdown", "error.notion.export": "Ошибка экспорта в Notion, пожалуйста, проверьте состояние подключения и настройки в документации", "error.notion.no_api_key": "Notion ApiKey или Notion DatabaseID не настроен", "error.yuque.export": "Ошибка экспорта в Yuque, пожалуйста, проверьте состояние подключения и настройки в документации", "error.yuque.no_config": "Yuque Token или Yuque Url не настроен", - "error.joplin.no_config": "Joplin Authorization Token или URL не настроен", - "error.joplin.export": "Не удалось экспортировать в Joplin, пожалуйста, убедитесь, что Joplin запущен и проверьте состояние подключения или настройки", "group.delete.content": "Удаление группы сообщений удалит пользовательский вопрос и все ответы помощника", "group.delete.title": "Удалить группу сообщений", "ignore.knowledge.base": "Режим сети включен, игнорировать базу знаний", "info.notion.block_reach_limit": "Диалог слишком длинный, экспортируется в Notion по страницам", - "loading.notion.preparing": "Подготовка к экспорту в Notion...", "loading.notion.exporting_progress": "Экспорт в Notion ({{current}}/{{total}})...", + "loading.notion.preparing": "Подготовка к экспорту в Notion...", "mention.title": "Переключить модель ответа", "message.code_style": "Стиль кода", "message.delete.content": "Вы уверены, что хотите удалить это сообщение?", @@ -479,22 +492,22 @@ "restore.success": "Успешно восстановлено", "save.success.title": "Успешно сохранено", "searching": "Поиск в Интернете...", + "success.joplin.export": "Успешный экспорт в Joplin", "success.markdown.export.preconf": "Файл Markdown успешно экспортирован в предуказанный путь", "success.markdown.export.specified": "Файл Markdown успешно экспортирован", "success.notion.export": "Успешный экспорт в Notion", "success.yuque.export": "Успешный экспорт в Yuque", - "success.joplin.export": "Успешный экспорт в Joplin", "switch.disabled": "Пожалуйста, дождитесь завершения текущего ответа", + "tools": { + "completed": "Завершено", + "invoking": "Вызов" + }, "topic.added": "Новый топик добавлен", "upgrade.success.button": "Перезапустить", "upgrade.success.content": "Пожалуйста, перезапустите приложение для завершения обновления", "upgrade.success.title": "Обновление успешно", "warn.notion.exporting": "Экспортируется в Notion, пожалуйста, не отправляйте повторные запросы!", - "warning.rate.limit": "Отправка слишком частая, пожалуйста, подождите {{seconds}} секунд, прежде чем попробовать снова.", - "tools": { - "invoking": "Вызов", - "completed": "Завершено" - } + "warning.rate.limit": "Отправка слишком частая, пожалуйста, подождите {{seconds}} секунд, прежде чем попробовать снова." }, "minapp": { "sidebar.add.title": "Добавить в боковую панель", @@ -533,7 +546,7 @@ "embedding": "Встраиваемые", "embedding_model": "Встраиваемые модели", "embedding_model_tooltip": "Добавьте в настройки->модель сервиса->управление", - "free": "Бесплатные", + "function_calling": "Вызов функции", "no_matches": "Нет доступных моделей", "parameter_name": "Имя параметра", "parameter_type": { @@ -543,22 +556,22 @@ "string": "Текст" }, "pinned": "Закреплено", - "reasoning": "Рассуждение", + "rerank_model": "Модель переупорядочивания", + "rerank_model_support_provider": "Текущая модель переупорядочивания поддерживается только некоторыми поставщиками ({{provider}})", + "rerank_model_tooltip": "В настройках -> Служба модели нажмите кнопку \"Управление\", чтобы добавить.", "search": "Поиск моделей...", "stream_output": "Потоковый вывод", - "function_calling": "Вызов функции", "type": { "embedding": "Встраиваемые", + "free": "Бесплатные", + "function_calling": "Инструкция", "reasoning": "Рассуждение", + "rerank": "Переупорядочить", "select": "Выберите тип модели", "text": "Текст", - "vision": "Изображение", - "function_calling": "Вызов функции" - }, - "vision": "Визуальные", - "websearch": "Веб-поисковые", - "rerank_model": "Модель переупорядочивания", - "rerank_model_tooltip": "В настройках -> Служба модели нажмите кнопку \"Управление\", чтобы добавить." + "vision": "Визуальные", + "websearch": "Веб-поисковые" + } }, "navbar": { "expand": "Развернуть диалоговое окно", @@ -611,10 +624,12 @@ }, "provider": { "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", "anthropic": "Anthropic", "azure-openai": "Azure OpenAI", "baichuan": "Baichuan", "baidu-cloud": "Baidu Cloud", + "copilot": "GitHub Copilot", "dashscope": "Alibaba Cloud", "deepseek": "DeepSeek", "dmxapi": "DMXAPI", @@ -623,6 +638,7 @@ "gemini": "Gemini", "gitee-ai": "Gitee AI", "github": "GitHub Models", + "gpustack": "GPUStack", "graphrag-kylin-mountain": "GraphRAG", "grok": "Grok", "groq": "Groq", @@ -651,10 +667,7 @@ "xirang": "State Cloud Xirang", "yi": "Yi", "zhinao": "360AI", - "zhipu": "ZHIPU AI", - "copilot": "GitHub Copilot", - "gpustack": "GPUStack", - "alayanew": "Alaya NeW" + "zhipu": "ZHIPU AI" }, "restore": { "confirm": "Вы уверены, что хотите восстановить данные?", @@ -716,15 +729,30 @@ "data.title": "Каталог данных", "hour_interval_one": "{{count}} час", "hour_interval_other": "{{count}} часов", - "minute_interval_one": "{{count}} минута", - "minute_interval_other": "{{count}} минут", - "markdown_export.title": "Экспорт в Markdown", + "joplin": { + "check": { + "button": "Проверить", + "empty_token": "Сначала введите токен Joplin", + "empty_url": "Сначала введите URL Joplin", + "fail": "Не удалось проверить подключение к Joplin", + "success": "Подключение к Joplin успешно проверено" + }, + "help": "Включите Joplin опцию, проверьте порт и скопируйте токен", + "title": "Настройка Joplin", + "token": "Токен Joplin", + "token_placeholder": "Введите токен Joplin", + "url": "URL Joplin", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "Если включено, при экспорте в Markdown для обозначения формул LaTeX будет принудительно использоваться $$. Примечание: Эта опция также влияет на все методы экспорта через Markdown, такие как Notion, Yuque и т.д.", + "markdown_export.force_dollar_math.title": "Принудительно использовать $$ для формул LaTeX", + "markdown_export.help": "Если указано, файлы будут автоматически сохраняться в этот путь; в противном случае появится диалоговое окно сохранения.", "markdown_export.path": "Путь экспорта по умолчанию", "markdown_export.path_placeholder": "Путь экспорта", "markdown_export.select": "Выбрать", - "markdown_export.help": "Если указано, файлы будут автоматически сохраняться в этот путь; в противном случае появится диалоговое окно сохранения.", - "markdown_export.force_dollar_math.title": "Принудительно использовать $$ для формул LaTeX", - "markdown_export.force_dollar_math.help": "Если включено, при экспорте в Markdown для обозначения формул LaTeX будет принудительно использоваться $$. Примечание: Эта опция также влияет на все методы экспорта через Markdown, такие как Notion, Yuque и т.д.", + "markdown_export.title": "Экспорт в Markdown", + "minute_interval_one": "{{count}} минута", + "minute_interval_other": "{{count}} минут", "notion.api_key": "Ключ API Notion", "notion.api_key_placeholder": "Введите ключ API Notion", "notion.auto_split": "Автоматическое разбиение на страницы при экспорте диалога", @@ -746,11 +774,22 @@ "notion.split_size_help": "Рекомендуется 90 для пользователей бесплатной версии Notion, 24990 для пользователей премиум-версии, значение по умолчанию — 90", "notion.split_size_placeholder": "Введите ограничение количества блоков на странице (по умолчанию 90)", "notion.title": "Настройки Notion", + "obsidian": { + "folder": "Папка", + "folder_placeholder": "Пожалуйста, введите имя папки", + "tags": "Глобальные Теги", + "tags_placeholder": "Пожалуйста, введите имена тегов. Разделяйте несколько тегов запятыми на английском языке. В Obsidian нельзя использовать только цифры.", + "title": "Конфигурация Obsidian", + "vault": "Хранилище", + "vault_placeholder": "Пожалуйста, введите имя хранилища" + }, "title": "Настройки данных", "webdav": { "autoSync": "Автоматическое резервное копирование", "autoSync.off": "Выключено", "backup.button": "Резервное копирование на WebDAV", + "backup.modal.filename.placeholder": "Введите имя файла резервной копии", + "backup.modal.title": "Резервное копирование на WebDAV", "host": "Хост WebDAV", "host.placeholder": "http://localhost:8080", "hour_interval_one": "{{count}} час", @@ -763,18 +802,16 @@ "path": "Путь WebDAV", "path.placeholder": "/backup", "restore.button": "Восстановление с WebDAV", + "restore.confirm.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?", + "restore.confirm.title": "Подтверждение восстановления", "restore.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?", + "restore.modal.select.placeholder": "Выберите файл резервной копии для восстановления", + "restore.modal.title": "Восстановление с WebDAV", "restore.title": "Восстановление с WebDAV", "syncError": "Ошибка резервного копирования", "syncStatus": "Статус резервного копирования", "title": "WebDAV", - "user": "Пользователь WebDAV", - "backup.modal.title": "Резервное копирование на WebDAV", - "backup.modal.filename.placeholder": "Введите имя файла резервной копии", - "restore.modal.title": "Восстановление с WebDAV", - "restore.modal.select.placeholder": "Выберите файл резервной копии для восстановления", - "restore.confirm.title": "Подтверждение восстановления", - "restore.confirm.content": "Восстановление с WebDAV перезапишет текущие данные, продолжить?" + "user": "Пользователь WebDAV" }, "yuque": { "check": { @@ -790,36 +827,6 @@ "title": "Настройка Yuque", "token": "Токен Yuque", "token_placeholder": "Введите токен Yuque" - }, - "obsidian": { - "check": { - "button": "Проверить", - "empty_url": "Сначала введите URL REST API Obsidian", - "empty_api_key": "Сначала введите API Key Obsidian", - "fail": "Не удалось проверить подключение к Obsidian", - "success": "Подключение к Obsidian успешно проверено" - }, - "help": "Сначала установите плагин Local REST API Obsidian, затем получите API Key Obsidian", - "url": "URL базы знаний Obsidian", - "url_placeholder": "http://127.0.0.1:27123/", - "title": "Настройка Obsidian", - "api_key": "API Key Obsidian", - "api_key_placeholder": "Введите API Key Obsidian" - }, - "joplin": { - "check": { - "button": "Проверить", - "empty_url": "Сначала введите URL Joplin", - "empty_token": "Сначала введите токен Joplin", - "fail": "Не удалось проверить подключение к Joplin", - "success": "Подключение к Joplin успешно проверено" - }, - "title": "Настройка Joplin", - "help": "Включите Joplin опцию, проверьте порт и скопируйте токен", - "url": "URL Joplin", - "url_placeholder": "http://127.0.0.1:41184/", - "token": "Токен Joplin", - "token_placeholder": "Введите токен Joplin" } }, "display.assistant.title": "Настройки ассистентов", @@ -865,12 +872,15 @@ "input.target_language.english": "Английский", "input.target_language.japanese": "Японский", "input.target_language.russian": "Русский", + "launch.onboot": "Автозапуск при включении", + "launch.title": "Запуск", + "launch.totray": "Свернуть в трей при запуске", "mcp": { "actions": "Действия", "active": "Активен", + "addError": "Ошибка добавления сервера", "addServer": "Добавить сервер", "addSuccess": "Сервер успешно добавлен", - "addError": "Ошибка добавления сервера", "args": "Аргументы", "argsTooltip": "Каждый аргумент с новой строки", "baseUrlTooltip": "Адрес удаленного URL", @@ -881,55 +891,51 @@ "confirmDeleteMessage": "Вы уверены, что хотите удалить этот сервер?", "deleteError": "Не удалось удалить сервер", "deleteSuccess": "Сервер успешно удален", + "dependenciesInstall": "Установить зависимости", + "dependenciesInstalling": "Установка зависимостей...", "description": "Описание", "duplicateName": "Сервер с таким именем уже существует", + "editJson": "Редактировать JSON", "editServer": "Редактировать сервер", "env": "Переменные окружения", "envTooltip": "Формат: KEY=value, по одной на строку", "findMore": "Найти больше MCP серверов", + "install": "Установить", + "installError": "Не удалось установить зависимости", + "installSuccess": "Зависимости успешно установлены", + "jsonFormatError": "Ошибка форматирования JSON", + "jsonModeHint": "Редактируйте JSON-форматирование конфигурации сервера MCP. Перед сохранением убедитесь, что формат правильный.", + "jsonSaveError": "Не удалось сохранить конфигурацию JSON", + "jsonSaveSuccess": "JSON конфигурация сохранена", + "missingDependencies": "отсутствует, пожалуйста, установите для продолжения.", "name": "Имя", "nameRequired": "Пожалуйста, введите имя сервера", "noServers": "Серверы не настроены", + "npx_list": { + "actions": "Действия", + "desc": "Поиск и добавление npm пакетов в качестве MCP серверов", + "description": "Описание", + "no_packages": "Ничего не найдено", + "npm": "NPM", + "package_name": "Имя пакета", + "scope_placeholder": "Введите область npm (например, @your-org)", + "scope_required": "Пожалуйста, введите область npm", + "search": "Поиск", + "search_error": "Ошибка поиска", + "title": "Список пакетов NPX", + "usage": "Использование", + "version": "Версия" + }, "serverPlural": "серверы", "serverSingular": "сервер", "title": "Серверы MCP", - "type": "Тип", - "updateSuccess": "Сервер успешно обновлен", - "updateError": "Ошибка обновления сервера", - "url": "URL", "toggleError": "Переключение не удалось", - "dependenciesInstalling": "Установка зависимостей...", - "dependenciesInstall": "Установить зависимости", - "installSuccess": "Зависимости успешно установлены", - "installError": "Не удалось установить зависимости", - "missingDependencies": "отсутствует, пожалуйста, установите для продолжения.", - "install": "Установить", - "npx_list": { - "title": "Список пакетов NPX", - "desc": "Поиск и добавление npm пакетов в качестве MCP серверов", - "scope_placeholder": "Введите область npm (например, @your-org)", - "search": "Поиск", - "package_name": "Имя пакета", - "description": "Описание", - "usage": "Использование", - "npm": "NPM", - "version": "Версия", - "actions": "Действия", - "scope_required": "Пожалуйста, введите область npm", - "no_packages": "Ничего не найдено", - "search_error": "Ошибка поиска" - }, - "editJson": "Редактировать JSON", - "jsonModeHint": "Редактируйте JSON-форматирование конфигурации сервера MCP. Перед сохранением убедитесь, что формат правильный.", - "jsonFormatError": "Ошибка форматирования JSON", - "jsonSaveSuccess": "JSON конфигурация сохранена", - "jsonSaveError": "Не удалось сохранить конфигурацию JSON" + "type": "Тип", + "updateError": "Ошибка обновления сервера", + "updateSuccess": "Сервер успешно обновлен", + "url": "URL" }, "messages.divider": "Показывать разделитель между сообщениями", - "messages.navigation": "Навигация сообщений", - "messages.navigation.none": "Не показывать", - "messages.navigation.buttons": "Кнопки пагинации", - "messages.navigation.anchor": "Диалог анкор", "messages.grid_columns": "Количество столбцов сетки сообщений", "messages.grid_popover_trigger": "Триггер для отображения подробной информации в сетке", "messages.grid_popover_trigger.click": "Нажатие для отображения", @@ -943,6 +949,10 @@ "messages.math_engine": "Математический движок", "messages.metrics": "{{time_first_token_millsec}}ms до первого токена | {{token_speed}} tok/sec", "messages.model.title": "Настройки модели", + "messages.navigation": "Навигация сообщений", + "messages.navigation.anchor": "Диалог анкор", + "messages.navigation.buttons": "Кнопки пагинации", + "messages.navigation.none": "Не показывать", "messages.title": "Настройки сообщений", "messages.use_serif_font": "Использовать serif шрифт", "model": "Модель по умолчанию", @@ -1005,43 +1015,43 @@ "check": "Проверить", "check_all_keys": "Проверить все ключи", "check_multiple_keys": "Проверить несколько ключей API", + "copilot": { + "auth_failed": "Github Copilot认证失败", + "auth_success": "Github Copilot认证成功", + "auth_success_title": "Аутентификация успешна", + "code_failed": "Получение кода устройства не удалось, пожалуйста, попробуйте еще раз.", + "code_generated_desc": "Пожалуйста, скопируйте код устройства в приведенную ниже ссылку браузера.", + "code_generated_title": "Получить код устройства", + "confirm_login": "Чрезмерное использование может привести к блокировке вашего Github, будьте осторожны!!!!", + "confirm_title": "Предупреждение о рисках", + "connect": "Подключить Github", + "custom_headers": "Пользовательские заголовки запроса", + "description": "Ваша учетная запись Github должна подписаться на Copilot.", + "expand": "развернуть", + "headers_description": "Пользовательские заголовки запроса (формат json)", + "invalid_json": "Ошибка формата JSON", + "login": "Войти в Github", + "logout": "Выйти из Github", + "logout_failed": "Не удалось выйти, пожалуйста, повторите попытку.", + "logout_success": "Успешно вышел", + "model_setting": "Настройки модели", + "open_verification_first": "Пожалуйста, сначала щелкните по ссылке выше, чтобы перейти на страницу проверки.", + "rate_limit": "Ограничение скорости", + "tooltip": "Для использования Github Copilot необходимо сначала войти в Github." + }, "delete.content": "Вы уверены, что хотите удалить этот провайдер?", "delete.title": "Удалить провайдер", "docs_check": "Проверить", "docs_more_details": "для получения дополнительной информации", "get_api_key": "Получить ключ API", + "is_not_support_array_content": "Включить совместимый режим", "no_models": "Пожалуйста, добавьте модели перед проверкой соединения с API", "not_checked": "Не проверено", "remove_duplicate_keys": "Удалить дубликаты ключей", "remove_invalid_keys": "Удалить недействительные ключи", "search": "Поиск поставщиков...", "search_placeholder": "Поиск по ID или имени модели", - "title": "Провайдеры моделей", - "is_not_support_array_content": "Включить совместимый режим", - "copilot": { - "tooltip": "Для использования Github Copilot необходимо сначала войти в Github.", - "description": "Ваша учетная запись Github должна подписаться на Copilot.", - "login": "Войти в Github", - "connect": "Подключить Github", - "logout": "Выйти из Github", - "auth_success_title": "Аутентификация успешна", - "code_generated_title": "Получить код устройства", - "code_generated_desc": "Пожалуйста, скопируйте код устройства в приведенную ниже ссылку браузера.", - "code_failed": "Получение кода устройства не удалось, пожалуйста, попробуйте еще раз.", - "auth_success": "Github Copilot认证成功", - "auth_failed": "Github Copilot认证失败", - "logout_success": "Успешно вышел", - "logout_failed": "Не удалось выйти, пожалуйста, повторите попытку.", - "confirm_title": "Предупреждение о рисках", - "confirm_login": "Чрезмерное использование может привести к блокировке вашего Github, будьте осторожны!!!!", - "rate_limit": "Ограничение скорости", - "custom_headers": "Пользовательские заголовки запроса", - "headers_description": "Пользовательские заголовки запроса (формат json)", - "expand": "развернуть", - "model_setting": "Настройки модели", - "invalid_json": "Ошибка формата JSON", - "open_verification_first": "Пожалуйста, сначала щелкните по ссылке выше, чтобы перейти на страницу проверки." - } + "title": "Провайдеры моделей" }, "proxy": { "mode": { @@ -1056,9 +1066,9 @@ "quickAssistant": { "click_tray_to_show": "Нажмите на иконку трея для запуска", "enable_quick_assistant": "Включить быстрый помощник", + "read_clipboard_at_startup": "Чтение буфера обмена при запуске", "title": "Быстрый помощник", - "use_shortcut_to_show": "Нажмите на иконку трея или используйте горячие клавиши для запуска", - "read_clipboard_at_startup": "Чтение буфера обмена при запуске" + "use_shortcut_to_show": "Нажмите на иконку трея или используйте горячие клавиши для запуска" }, "shortcuts": { "action": "Действие", @@ -1095,14 +1105,18 @@ "topic.position.left": "Слева", "topic.position.right": "Справа", "topic.show.time": "Показывать время топика", - "tray.title": "Включить значок системного трея", + "tray.onclose": "Свернуть в трей при закрытии", + "tray.show": "Показать значок в трее", + "tray.title": "Трей", "websearch": { "blacklist": "Черный список", "blacklist_description": "Результаты из следующих веб-сайтов не будут отображаться в результатах поиска", "blacklist_tooltip": "Пожалуйста, используйте следующий формат (разделенный переносами строк)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", "check": "проверка", - "check_success": "Проверка успешна", "check_failed": "Проверка не прошла", + "check_success": "Проверка успешна", + "enhance_mode": "Режим улучшения поиска", + "enhance_mode_tooltip": "Используйте модель по умолчанию для извлечения ключевых слов из проблемы и поиска", "get_api_key": "Получить ключ API", "no_provider_selected": "Пожалуйста, выберите поставщика поисковых услуг, затем проверьте.", "search_max_result": "Количество результатов поиска", @@ -1110,8 +1124,6 @@ "search_provider_placeholder": "Выберите поставщика поисковых услуг", "search_result_default": "По умолчанию", "search_with_time": "Поиск, содержащий дату", - "enhance_mode": "Режим улучшения поиска", - "enhance_mode_tooltip": "Используйте модель по умолчанию для извлечения ключевых слов из проблемы и поиска", "tavily": { "api_key": "Ключ API Tavily", "api_key.placeholder": "Введите ключ API Tavily", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 7de957c78..81b455447 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -105,6 +105,8 @@ "input.estimated_tokens.tip": "预估 token 数", "input.expand": "展开", "input.file_not_supported": "模型不支持此文件类型", + "input.generate_image": "生成图片", + "input.generate_image_not_supported": "模型不支持生成图片", "input.knowledge_base": "知识库", "input.new.context": "清除上下文 {{Command}}", "input.new_topic": "新话题 {{Command}}", @@ -126,6 +128,12 @@ "message.quote": "引用", "message.regenerate.model": "切换模型", "message.useful": "有用", + "navigation": { + "first": "已经是第一条消息", + "last": "已经是最后一条消息", + "next": "下一条消息", + "prev": "上一条消息" + }, "resend": "重新发送", "save": "保存", "settings.code_collapsible": "代码块可折叠", @@ -157,37 +165,42 @@ "topics.edit.placeholder": "输入新名称", "topics.edit.title": "编辑话题名", "topics.export.image": "导出为图片", + "topics.export.joplin": "导出到 Joplin", "topics.export.md": "导出为 Markdown", "topics.export.notion": "导出到 Notion", + "topics.export.obsidian": "导出到 Obsidian", + "topics.export.obsidian_atributes": "配置笔记属性", + "topics.export.obsidian_btn": "确定", + "topics.export.obsidian_created": "创建时间", + "topics.export.obsidian_created_placeholder": "请选择创建时间", + "topics.export.obsidian_export_failed": "导出失败", + "topics.export.obsidian_export_success": "导出成功", + "topics.export.obsidian_not_configured": "Obsidian 未配置", + "topics.export.obsidian_operate": "处理方式", + "topics.export.obsidian_operate_append": "追加", + "topics.export.obsidian_operate_new_or_overwrite": "新建(如果存在就覆盖)", + "topics.export.obsidian_operate_placeholder": "请选择处理方式", + "topics.export.obsidian_operate_prepend": "前置", + "topics.export.obsidian_source": "来源", + "topics.export.obsidian_source_placeholder": "请输入来源", + "topics.export.obsidian_tags": "标签", + "topics.export.obsidian_tags_placeholder": "请输入标签,多个标签用英文逗号分隔", + "topics.export.obsidian_title": "标题", + "topics.export.obsidian_title_placeholder": "请输入标题", + "topics.export.obsidian_title_required": "标题不能为空", "topics.export.title": "导出", "topics.export.word": "导出为 Word", "topics.export.yuque": "导出到语雀", - "topics.export.obsidian": "导出到 Obsidian", - "topics.export.obsidian_not_configured": "Obsidian 未配置", - "topics.export.obsidian_fetch_failed": "获取 Obsidian 文件夹结构失败", - "topics.export.obsidian_select_folder": "选择 Obsidian 文件夹", - "topics.export.obsidian_select_folder.btn": "确定", - "topics.export.obsidian_export_success": "导出成功", - "topics.export.obsidian_export_failed": "导出失败", - "topics.export.obsidian_show_md_files": "显示md文件", - "topics.export.obsidian_selected_path": "已选择路径", - "topics.export.joplin": "导出到 Joplin", "topics.list": "话题列表", "topics.move_to": "移动到", + "topics.new": "开始新对话", "topics.pinned": "固定话题", "topics.prompt": "话题提示词", "topics.prompt.edit.title": "编辑话题提示词", "topics.prompt.tips": "话题提示词: 针对当前话题提供额外的补充提示词", "topics.title": "话题", "topics.unpinned": "取消固定", - "topics.new": "开始新对话", - "translate": "翻译", - "navigation": { - "prev": "上一条消息", - "next": "下一条消息", - "first": "已经是第一条消息", - "last": "已经是最后一条消息" - } + "translate": "翻译" }, "code_block": { "collapse": "收起", @@ -197,6 +210,7 @@ }, "common": { "add": "添加", + "advanced_settings": "高级设置", "and": "和", "assistant": "智能体", "avatar": "头像", @@ -206,8 +220,8 @@ "clear": "清除", "close": "关闭", "confirm": "确认", - "copy": "复制", "copied": "已复制", + "copy": "复制", "cut": "剪切", "default": "默认", "delete": "删除", @@ -216,6 +230,7 @@ "download": "下载", "duplicate": "复制", "edit": "编辑", + "expand": "展开", "footnote": "引用内容", "footnotes": "引用内容", "fullscreen": "已进入全屏模式,按 F11 退出", @@ -223,6 +238,7 @@ "language": "语言", "model": "模型", "models": "模型", + "more": "更多", "name": "名称", "paste": "粘贴", "prompt": "提示词", @@ -235,10 +251,7 @@ "select": "选择", "topics": "话题", "warning": "警告", - "you": "用户", - "more": "更多", - "advanced_settings": "高级设置", - "expand": "展开" + "you": "用户" }, "docs": { "title": "帮助文档" @@ -296,6 +309,12 @@ "title": "文件", "type": "类型" }, + "gpustack": { + "keep_alive_time.description": "模型在内存中保持的时间(默认:5分钟)", + "keep_alive_time.placeholder": "分钟", + "keep_alive_time.title": "保持活跃时间", + "title": "GPUStack" + }, "history": { "continue_chat": "继续聊天", "locate.message": "定位到消息", @@ -363,11 +382,11 @@ "threshold_placeholder": "未设置", "threshold_too_large_or_small": "阈值不能大于1或小于0", "threshold_tooltip": "用于衡量用户问题与知识库内容之间的相关性(0-1)", - "topN": "返回结果数量", - "topN_placeholder": "未设置", - "topN__too_large_or_small": "返回结果数量不能大于100或小于1", - "topN_tooltip": "返回的匹配结果数量,数值越大,匹配结果越多,但消耗的 Token 也越多", "title": "知识库", + "topN": "返回结果数量", + "topN__too_large_or_small": "返回结果数量不能大于100或小于1", + "topN_placeholder": "未设置", + "topN_tooltip": "返回的匹配结果数量,数值越大,匹配结果越多,但消耗的 Token 也越多", "url_added": "网址已添加", "url_placeholder": "请输入网址, 多个网址用回车分隔", "urls": "网址", @@ -419,22 +438,22 @@ "title": "Mermaid 图表" }, "message": { - "attachments": { - "pasted_text": "剪切板文件", - "pasted_image": "剪切板图片" - }, "api.check.model.title": "请选择要检测的模型", "api.connection.failed": "连接失败", "api.connection.success": "连接成功", "assistant.added.content": "智能体添加成功", + "attachments": { + "pasted_image": "剪切板图片", + "pasted_text": "剪切板文件" + }, "backup.failed": "备份失败", "backup.start.success": "开始备份", "backup.success": "备份成功", "chat.completion.paused": "会话已停止", "citations": "引用内容", "copied": "已复制", - "copy.success": "复制成功", "copy.failed": "复制失败", + "copy.success": "复制成功", "error.chunk_overlap_too_large": "分段重叠不能大于分段大小", "error.dimension_too_large": "内容尺寸过大", "error.enter.api.host": "请输入您的 API 地址", @@ -447,20 +466,20 @@ "error.invalid.enter.model": "请选择一个模型", "error.invalid.proxy.url": "无效的代理地址", "error.invalid.webdav": "无效的 WebDAV 设置", + "error.joplin.export": "导出 Joplin 失败,请保持 Joplin 已运行并检查连接状态或检查配置", + "error.joplin.no_config": "未配置 Joplin 授权令牌 或 URL", "error.markdown.export.preconf": "导出Markdown文件到预先设定的路径失败", "error.markdown.export.specified": "导出Markdown文件失败", "error.notion.export": "导出 Notion 错误,请检查连接状态并对照文档检查配置", "error.notion.no_api_key": "未配置 Notion API Key 或 Notion Database ID", "error.yuque.export": "导出语雀错误,请检查连接状态并对照文档检查配置", "error.yuque.no_config": "未配置语雀 Token 或 知识库 URL", - "error.joplin.no_config": "未配置 Joplin 授权令牌 或 URL", - "error.joplin.export": "导出 Joplin 失败,请保持 Joplin 已运行并检查连接状态或检查配置", "group.delete.content": "删除分组消息会删除用户提问和所有助手的回答", "group.delete.title": "删除分组消息", "ignore.knowledge.base": "联网模式开启,忽略知识库", "info.notion.block_reach_limit": "对话过长,正在分页导出到Notion", - "loading.notion.preparing": "正在准备导出到Notion...", "loading.notion.exporting_progress": "正在导出到Notion ({{current}}/{{total}})...", + "loading.notion.preparing": "正在准备导出到Notion...", "mention.title": "切换模型回答", "message.code_style": "代码风格", "message.delete.content": "确定要删除此消息吗?", @@ -483,22 +502,22 @@ "restore.success": "恢复成功", "save.success.title": "保存成功", "searching": "正在联网搜索...", + "success.joplin.export": "成功导出到 Joplin", "success.markdown.export.preconf": "成功导出 Markdown 文件到预先设定的路径", "success.markdown.export.specified": "成功导出 Markdown 文件", "success.notion.export": "成功导出到 Notion", "success.yuque.export": "成功导出到语雀", - "success.joplin.export": "成功导出到 Joplin", "switch.disabled": "请等待当前回复完成后操作", + "tools": { + "completed": "已完成", + "invoking": "调用中" + }, "topic.added": "话题添加成功", "upgrade.success.button": "重启", "upgrade.success.content": "重启用以完成升级", "upgrade.success.title": "升级成功", "warn.notion.exporting": "正在导出到 Notion, 请勿重复请求导出!", - "warning.rate.limit": "发送过于频繁,请等待 {{seconds}} 秒后再尝试", - "tools": { - "invoking": "调用中", - "completed": "已完成" - } + "warning.rate.limit": "发送过于频繁,请等待 {{seconds}} 秒后再尝试" }, "minapp": { "sidebar.add.title": "添加到侧边栏", @@ -537,9 +556,7 @@ "embedding": "嵌入", "embedding_model": "嵌入模型", "embedding_model_tooltip": "在设置->模型服务中点击管理按钮添加", - "rerank_model": "重排序模型", - "rerank_model_tooltip": "在设置->模型服务中点击管理按钮添加", - "free": "免费", + "function_calling": "函数调用", "no_matches": "无可用模型", "parameter_name": "参数名称", "parameter_type": { @@ -549,20 +566,22 @@ "string": "文本" }, "pinned": "已固定", - "reasoning": "推理", + "rerank_model": "重排模型", + "rerank_model_support_provider": "目前重排序模型仅支持部分服务商 ({{provider}})", + "rerank_model_tooltip": "在设置->模型服务中点击管理按钮添加", "search": "搜索模型...", "stream_output": "流式输出", - "function_calling": "函数调用", "type": { "embedding": "嵌入", + "free": "免费", + "function_calling": "工具", "reasoning": "推理", + "rerank": "重排", "select": "选择模型类型", "text": "文本", - "vision": "图像", - "function_calling": "函数调用" - }, - "vision": "视觉", - "websearch": "联网" + "vision": "视觉", + "websearch": "联网" + } }, "navbar": { "expand": "伸缩对话框", @@ -615,10 +634,12 @@ }, "provider": { "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", "anthropic": "Anthropic", "azure-openai": "Azure OpenAI", "baichuan": "百川", "baidu-cloud": "百度云千帆", + "copilot": "GitHub Copilot", "dashscope": "阿里云百炼", "deepseek": "深度求索", "dmxapi": "DMXAPI", @@ -627,6 +648,7 @@ "gemini": "Gemini", "gitee-ai": "Gitee AI", "github": "GitHub Models", + "gpustack": "GPUStack", "graphrag-kylin-mountain": "GraphRAG", "grok": "Grok", "groq": "Groq", @@ -655,10 +677,7 @@ "xirang": "天翼云息壤", "yi": "零一万物", "zhinao": "360智脑", - "zhipu": "智谱AI", - "copilot": "GitHub Copilot", - "gpustack": "GPUStack", - "alayanew": "Alaya NeW" + "zhipu": "智谱AI" }, "restore": { "confirm": "确定要恢复数据吗?", @@ -674,12 +693,6 @@ }, "title": "数据恢复" }, - "gpustack": { - "keep_alive_time.description": "模型在内存中保持的时间(默认:5分钟)", - "keep_alive_time.placeholder": "分钟", - "keep_alive_time.title": "保持活跃时间", - "title": "GPUStack" - }, "settings": { "about": "关于我们", "about.checkingUpdate": "正在检查更新...", @@ -726,15 +739,30 @@ "data.title": "数据目录", "hour_interval_one": "{{count}} 小时", "hour_interval_other": "{{count}} 小时", - "minute_interval_one": "{{count}} 分钟", - "minute_interval_other": "{{count}} 分钟", - "markdown_export.title": "Markdown 导出", + "joplin": { + "check": { + "button": "检查", + "empty_token": "请先输入 Joplin 授权令牌", + "empty_url": "请先输入 Joplin 剪裁服务监听 URL", + "fail": "Joplin 连接验证失败", + "success": "Joplin 连接验证成功" + }, + "help": "在 Joplin 选项中,启用网页剪裁服务(无需安装浏览器插件),确认端口号,并复制授权令牌", + "title": "Joplin 配置", + "token": "Joplin 授权令牌", + "token_placeholder": "请输入 Joplin 授权令牌", + "url": "Joplin 剪裁服务监听 URL", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "开启后,导出Markdown时会将强制使用$$来标记LaTeX公式。注意:该项也会影响所有通过Markdown导出的方式,如Notion、语雀等。", + "markdown_export.force_dollar_math.title": "强制使用$$来标记LaTeX公式", + "markdown_export.help": "若填入,则每次导出时将自动保存到该路径;否则,将弹出保存对话框", "markdown_export.path": "默认导出路径", "markdown_export.path_placeholder": "导出路径", "markdown_export.select": "选择", - "markdown_export.help": "若填入,则每次导出时将自动保存到该路径;否则,将弹出保存对话框", - "markdown_export.force_dollar_math.title": "强制使用$$来标记LaTeX公式", - "markdown_export.force_dollar_math.help": "开启后,导出Markdown时会将强制使用$$来标记LaTeX公式。注意:该项也会影响所有通过Markdown导出的方式,如Notion、语雀等。", + "markdown_export.title": "Markdown 导出", + "minute_interval_one": "{{count}} 分钟", + "minute_interval_other": "{{count}} 分钟", "notion.api_key": "Notion 密钥", "notion.api_key_placeholder": "请输入Notion 密钥", "notion.auto_split": "导出对话时自动分页", @@ -756,11 +784,22 @@ "notion.split_size_help": "Notion免费版用户建议设置为90,高级版用户建议设置为24990,默认值为90", "notion.split_size_placeholder": "请输入每页块数限制(默认90)", "notion.title": "Notion 配置", + "obsidian": { + "folder": "文件夹", + "folder_placeholder": "请输入文件夹名称", + "tags": "全局标签", + "tags_placeholder": "请输入标签名称, 多个标签用英文逗号分隔", + "title": "Obsidian 配置", + "vault": "保管库", + "vault_placeholder": "请输入保管库名称" + }, "title": "数据设置", "webdav": { "autoSync": "自动备份", "autoSync.off": "关闭", "backup.button": "备份到 WebDAV", + "backup.modal.filename.placeholder": "请输入备份文件名", + "backup.modal.title": "备份到 WebDAV", "host": "WebDAV 地址", "host.placeholder": "http://localhost:8080", "hour_interval_one": "{{count}} 小时", @@ -772,14 +811,12 @@ "password": "WebDAV 密码", "path": "WebDAV 路径", "path.placeholder": "/backup", - "backup.modal.title": "备份到 WebDAV", - "backup.modal.filename.placeholder": "请输入备份文件名", - "restore.modal.title": "从 WebDAV 恢复", - "restore.modal.select.placeholder": "请选择要恢复的备份文件", - "restore.confirm.title": "确认恢复", - "restore.confirm.content": "从 WebDAV 恢复将会覆盖当前数据,是否继续?", "restore.button": "从 WebDAV 恢复", + "restore.confirm.content": "从 WebDAV 恢复将会覆盖当前数据,是否继续?", + "restore.confirm.title": "确认恢复", "restore.content": "从 WebDAV 恢复将覆盖当前数据,是否继续?", + "restore.modal.select.placeholder": "请选择要恢复的备份文件", + "restore.modal.title": "从 WebDAV 恢复", "restore.title": "从 WebDAV 恢复", "syncError": "备份错误", "syncStatus": "备份状态", @@ -800,36 +837,6 @@ "title": "语雀配置", "token": "语雀 Token", "token_placeholder": "请输入语雀Token" - }, - "obsidian": { - "check": { - "button": "检查", - "empty_url": "请先输入 Obsidian REST API URL", - "empty_api_key": "请先输入 Obsidian API Key", - "fail": "Obsidian 连接验证失败", - "success": "Obsidian 连接验证成功" - }, - "help": "先安装 Obsidian 插件 Local REST API,然后获取 Obsidian API Key", - "url": "Obsidian 知识库 URL", - "url_placeholder": "http://127.0.0.1:27123/", - "title": "Obsidian 配置", - "api_key": "Obsidian API Key", - "api_key_placeholder": "请输入 Obsidian API Key" - }, - "joplin": { - "check": { - "button": "检查", - "empty_url": "请先输入 Joplin 剪裁服务监听 URL", - "empty_token": "请先输入 Joplin 授权令牌", - "fail": "Joplin 连接验证失败", - "success": "Joplin 连接验证成功" - }, - "title": "Joplin 配置", - "help": "在 Joplin 选项中,启用网页剪裁服务(无需安装浏览器插件),确认端口号,并复制授权令牌", - "url": "Joplin 剪裁服务监听 URL", - "url_placeholder": "http://127.0.0.1:41184/", - "token": "Joplin 授权令牌", - "token_placeholder": "请输入 Joplin 授权令牌" } }, "display.assistant.title": "助手设置", @@ -875,6 +882,9 @@ "input.target_language.english": "英文", "input.target_language.japanese": "日文", "input.target_language.russian": "俄文", + "launch.onboot": "开机自动启动", + "launch.title": "启动", + "launch.totray": "启动时最小化到托盘", "knowledge": { "title": "知识库", "ocr": { @@ -885,9 +895,9 @@ "mcp": { "actions": "操作", "active": "启用", + "addError": "添加服务器失败", "addServer": "添加服务器", "addSuccess": "服务器添加成功", - "addError": "添加服务器失败", "args": "参数", "argsTooltip": "每个参数占一行", "baseUrlTooltip": "远程 URL 地址", @@ -898,55 +908,51 @@ "confirmDeleteMessage": "您确定要删除该服务器吗?", "deleteError": "删除服务器失败", "deleteSuccess": "服务器删除成功", + "dependenciesInstall": "安装依赖项", + "dependenciesInstalling": "正在安装依赖项...", "description": "描述", "duplicateName": "已存在同名服务器", + "editJson": "编辑JSON", "editServer": "编辑服务器", "env": "环境变量", "envTooltip": "格式:KEY=value,每行一个", "findMore": "更多 MCP 服务器", + "install": "安装", + "installError": "安装依赖项失败", + "installSuccess": "依赖项安装成功", + "jsonFormatError": "JSON格式化错误", + "jsonModeHint": "编辑MCP服务器配置的JSON表示。保存前请确保格式正确。", + "jsonSaveError": "保存JSON配置失败", + "jsonSaveSuccess": "JSON配置已保存", + "missingDependencies": "缺失,请安装它以继续", "name": "名称", "nameRequired": "请输入服务器名称", "noServers": "未配置服务器", + "npx_list": { + "actions": "操作", + "desc": "搜索并添加 npm 包作为 MCP 服务", + "description": "描述", + "no_packages": "未找到包", + "npm": "NPM", + "package_name": "包名称", + "scope_placeholder": "输入 npm 作用域 (例如 @your-org)", + "scope_required": "请输入 npm 作用域", + "search": "搜索", + "search_error": "搜索失败", + "title": "NPX 包列表", + "usage": "用法", + "version": "版本" + }, "serverPlural": "服务器", "serverSingular": "服务器", "title": "MCP 服务器", - "type": "类型", - "updateSuccess": "服务器更新成功", - "updateError": "更新服务器失败", - "url": "URL", "toggleError": "切换失败", - "dependenciesInstalling": "正在安装依赖项...", - "dependenciesInstall": "安装依赖项", - "installSuccess": "依赖项安装成功", - "installError": "安装依赖项失败", - "missingDependencies": "缺失,请安装它以继续", - "install": "安装", - "npx_list": { - "title": "NPX 包列表", - "desc": "搜索并添加 npm 包作为 MCP 服务", - "scope_placeholder": "输入 npm 作用域 (例如 @your-org)", - "search": "搜索", - "package_name": "包名称", - "description": "描述", - "usage": "用法", - "npm": "NPM", - "version": "版本", - "actions": "操作", - "scope_required": "请输入 npm 作用域", - "no_packages": "未找到包", - "search_error": "搜索失败" - }, - "editJson": "编辑JSON", - "jsonModeHint": "编辑MCP服务器配置的JSON表示。保存前请确保格式正确。", - "jsonFormatError": "JSON格式化错误", - "jsonSaveSuccess": "JSON配置已保存", - "jsonSaveError": "保存JSON配置失败" + "type": "类型", + "updateError": "更新服务器失败", + "updateSuccess": "服务器更新成功", + "url": "URL" }, "messages.divider": "消息分割线", - "messages.navigation": "对话导航按钮", - "messages.navigation.none": "不显示", - "messages.navigation.buttons": "上下按钮", - "messages.navigation.anchor": "对话锚点", "messages.grid_columns": "消息网格展示列数", "messages.grid_popover_trigger": "网格详情触发", "messages.grid_popover_trigger.click": "点击显示", @@ -960,6 +966,10 @@ "messages.math_engine": "数学公式引擎", "messages.metrics": "首字时延 {{time_first_token_millsec}}ms | 每秒 {{token_speed}} tokens", "messages.model.title": "模型设置", + "messages.navigation": "对话导航按钮", + "messages.navigation.anchor": "对话锚点", + "messages.navigation.buttons": "上下按钮", + "messages.navigation.none": "不显示", "messages.title": "消息设置", "messages.use_serif_font": "使用衬线字体", "model": "默认模型", @@ -1022,43 +1032,43 @@ "check": "检查", "check_all_keys": "检查所有密钥", "check_multiple_keys": "检查多个 API 密钥", + "copilot": { + "auth_failed": "Github Copilot 认证失败", + "auth_success": "Github Copilot 认证成功", + "auth_success_title": "认证成功", + "code_failed": "获取 Device Code 失败,请重试", + "code_generated_desc": "请将 Device Code 复制到下面的浏览器链接中", + "code_generated_title": "获取 Device Code", + "confirm_login": "过度使用可能会导致您的 Github 账号遭到封号,请谨慎使用!!!!", + "confirm_title": "风险警告", + "connect": "连接 Github", + "custom_headers": "自定义请求头", + "description": "您的 Github 账号需要订阅 Copilot", + "expand": "展开", + "headers_description": "自定义请求头(json格式)", + "invalid_json": "JSON 格式错误", + "login": "登录 Github", + "logout": "退出 Github", + "logout_failed": "退出失败,请重试", + "logout_success": "已成功退出", + "model_setting": "模型设置", + "open_verification_first": "请先点击上方链接访问验证页面", + "rate_limit": "速率限制", + "tooltip": "使用 Github Copilot 需要先登录 Github" + }, "delete.content": "确定要删除此模型提供商吗?", "delete.title": "删除提供商", "docs_check": "查看", "docs_more_details": "获取更多详情", "get_api_key": "点击这里获取密钥", + "is_not_support_array_content": "开启兼容模式", "no_models": "请先添加模型再检查 API 连接", "not_checked": "未检查", "remove_duplicate_keys": "移除重复密钥", "remove_invalid_keys": "删除无效密钥", "search": "搜索模型平台...", "search_placeholder": "搜索模型 ID 或名称", - "title": "模型服务", - "is_not_support_array_content": "开启兼容模式", - "copilot": { - "tooltip": "使用 Github Copilot 需要先登录 Github", - "description": "您的 Github 账号需要订阅 Copilot", - "login": "登录 Github", - "connect": "连接 Github", - "logout": "退出 Github", - "auth_success_title": "认证成功", - "code_generated_title": "获取 Device Code", - "code_generated_desc": "请将 Device Code 复制到下面的浏览器链接中", - "code_failed": "获取 Device Code 失败,请重试", - "auth_success": "Github Copilot 认证成功", - "auth_failed": "Github Copilot 认证失败", - "logout_success": "已成功退出", - "logout_failed": "退出失败,请重试", - "confirm_title": "风险警告", - "confirm_login": "过度使用可能会导致您的 Github 账号遭到封号,请谨慎使用!!!!", - "rate_limit": "速率限制", - "custom_headers": "自定义请求头", - "headers_description": "自定义请求头(json格式)", - "expand": "展开", - "model_setting": "模型设置", - "invalid_json": "JSON 格式错误", - "open_verification_first": "请先点击上方链接访问验证页面" - } + "title": "模型服务" }, "proxy": { "mode": { @@ -1073,9 +1083,9 @@ "quickAssistant": { "click_tray_to_show": "点击托盘图标启动", "enable_quick_assistant": "启用快捷助手", + "read_clipboard_at_startup": "启动时读取剪贴板", "title": "快捷助手", - "use_shortcut_to_show": "右键点击托盘图标或使用快捷键启动", - "read_clipboard_at_startup": "启动时读取剪贴板" + "use_shortcut_to_show": "右键点击托盘图标或使用快捷键启动" }, "shortcuts": { "action": "操作", @@ -1112,14 +1122,18 @@ "topic.position.left": "左侧", "topic.position.right": "右侧", "topic.show.time": "显示话题时间", - "tray.title": "启用系统托盘图标", + "tray.onclose": "关闭时最小化到托盘", + "tray.show": "显示托盘图标", + "tray.title": "托盘", "websearch": { "blacklist": "黑名单", "blacklist_description": "在搜索结果中不会出现以下网站的结果", "blacklist_tooltip": "请使用以下格式(换行分隔)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", "check": "检查", - "check_success": "验证成功", "check_failed": "验证失败", + "check_success": "验证成功", + "enhance_mode": "搜索增强模式", + "enhance_mode_tooltip": "使用默认模型提取关键词后搜索", "get_api_key": "点击这里获取密钥", "no_provider_selected": "请选择搜索服务商后再检查", "search_max_result": "搜索结果个数", @@ -1127,8 +1141,6 @@ "search_provider_placeholder": "选择一个搜索服务商", "search_result_default": "默认", "search_with_time": "搜索包含日期", - "enhance_mode": "搜索增强模式", - "enhance_mode_tooltip": "使用默认模型提取关键词后搜索", "tavily": { "api_key": "Tavily API 密钥", "api_key.placeholder": "请输入 Tavily API 密钥", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 12d92d300..3c13cc698 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -105,6 +105,8 @@ "input.estimated_tokens.tip": "預估 Token 數", "input.expand": "展開", "input.file_not_supported": "模型不支援此檔案類型", + "input.generate_image": "生成圖片", + "input.generate_image_not_supported": "模型不支援生成圖片", "input.knowledge_base": "知識庫", "input.new.context": "清除上下文 {{Command}}", "input.new_topic": "新話題 {{Command}}", @@ -126,6 +128,12 @@ "message.quote": "引用", "message.regenerate.model": "切換模型", "message.useful": "有用", + "navigation": { + "first": "已經是第一條訊息", + "last": "已經是最後一條訊息", + "next": "下一條訊息", + "prev": "上一條訊息" + }, "resend": "重新傳送", "save": "儲存", "settings.code_collapsible": "程式碼區塊可折疊", @@ -157,37 +165,42 @@ "topics.edit.placeholder": "輸入新名稱", "topics.edit.title": "編輯名稱", "topics.export.image": "匯出為圖片", + "topics.export.joplin": "匯出到 Joplin", "topics.export.md": "匯出為 Markdown", "topics.export.notion": "匯出到 Notion", + "topics.export.obsidian": "匯出到 Obsidian", + "topics.export.obsidian_atributes": "配置筆記屬性", + "topics.export.obsidian_btn": "確定", + "topics.export.obsidian_created": "建立時間", + "topics.export.obsidian_created_placeholder": "請選擇建立時間", + "topics.export.obsidian_export_failed": "匯出失敗", + "topics.export.obsidian_export_success": "匯出成功", + "topics.export.obsidian_not_configured": "Obsidian 未配置", + "topics.export.obsidian_operate": "處理方式", + "topics.export.obsidian_operate_append": "追加", + "topics.export.obsidian_operate_new_or_overwrite": "新建(如果存在就覆蓋)", + "topics.export.obsidian_operate_placeholder": "請選擇處理方式", + "topics.export.obsidian_operate_prepend": "前置", + "topics.export.obsidian_source": "來源", + "topics.export.obsidian_source_placeholder": "請輸入來源", + "topics.export.obsidian_tags": "標籤", + "topics.export.obsidian_tags_placeholder": "請輸入標籤名稱,多個標籤用英文逗號分隔", + "topics.export.obsidian_title": "標題", + "topics.export.obsidian_title_placeholder": "請輸入標題", + "topics.export.obsidian_title_required": "標題不能為空", "topics.export.title": "匯出", "topics.export.word": "匯出為 Word", "topics.export.yuque": "匯出到語雀", - "topics.export.obsidian": "匯出到 Obsidian", - "topics.export.obsidian_not_configured": "Obsidian 未配置", - "topics.export.obsidian_fetch_failed": "獲取 Obsidian 文件夾結構失敗", - "topics.export.obsidian_select_folder": "選擇 Obsidian 文件夾", - "topics.export.obsidian_select_folder.btn": "確定", - "topics.export.obsidian_export_success": "匯出成功", - "topics.export.obsidian_export_failed": "匯出失敗", - "topics.export.obsidian_show_md_files": "顯示md文件", - "topics.export.obsidian_selected_path": "已選擇路徑", - "topics.export.joplin": "匯出到 Joplin", "topics.list": "話題列表", "topics.move_to": "移動到", + "topics.new": "開始新對話", "topics.pinned": "固定話題", "topics.prompt": "話題提示詞", "topics.prompt.edit.title": "編輯話題提示詞", "topics.prompt.tips": "話題提示詞:針對目前話題提供額外的補充提示詞", "topics.title": "話題", "topics.unpinned": "取消固定", - "topics.new": "開始新對話", - "translate": "翻譯", - "navigation": { - "prev": "上一條訊息", - "next": "下一條訊息", - "first": "已經是第一條訊息", - "last": "已經是最後一條訊息" - } + "translate": "翻譯" }, "code_block": { "collapse": "折疊", @@ -197,6 +210,7 @@ }, "common": { "add": "新增", + "advanced_settings": "進階設定", "and": "與", "assistant": "智慧代理人", "avatar": "頭像", @@ -205,6 +219,8 @@ "chat": "聊天", "clear": "清除", "close": "關閉", + "confirm": "確認", + "copied": "已複製", "copy": "複製", "cut": "剪下", "default": "預設", @@ -214,6 +230,7 @@ "download": "下載", "duplicate": "複製", "edit": "編輯", + "expand": "展開", "footnote": "引用內容", "footnotes": "引用", "fullscreen": "已進入全螢幕模式,按 F11 結束", @@ -221,6 +238,7 @@ "language": "語言", "model": "模型", "models": "模型", + "more": "更多", "name": "名稱", "paste": "貼上", "prompt": "提示詞", @@ -233,12 +251,7 @@ "select": "選擇", "topics": "話題", "warning": "警告", - "you": "您", - "copied": "已複製", - "confirm": "確認", - "more": "更多", - "advanced_settings": "進階設定", - "expand": "展開" + "you": "您" }, "docs": { "title": "說明文件" @@ -296,6 +309,12 @@ "title": "檔案", "type": "類型" }, + "gpustack": { + "keep_alive_time.description": "模型在記憶體中保持的時間(預設為 5 分鐘)。", + "keep_alive_time.placeholder": "分鐘", + "keep_alive_time.title": "保持活躍時間", + "title": "GPUStack" + }, "history": { "continue_chat": "繼續聊天", "locate.message": "定位到訊息", @@ -365,13 +384,13 @@ "threshold_too_large_or_small": "閾值不能大於 1 或小於 0", "threshold_tooltip": "用於衡量使用者問題與知識庫內容之間的相關性(0-1)", "title": "知識庫", + "topN": "返回結果數量", + "topN__too_large_or_small": "返回結果數量不能大於100或小於1", + "topN_placeholder": "未設定", + "topN_tooltip": "返回的匹配結果數量,數值越大,匹配結果越多,但消耗的 Token 也越多", "url_added": "網址已新增", "url_placeholder": "請輸入網址,多個網址用換行符號分隔", - "urls": "網址", - "topN": "返回結果數量", - "topN_placeholder": "未設定", - "topN__too_large_or_small": "返回結果數量不能大於100或小於1", - "topN_tooltip": "返回的匹配結果數量,數值越大,匹配結果越多,但消耗的 Token 也越多" + "urls": "網址" }, "languages": { "arabic": "阿拉伯文", @@ -409,22 +428,22 @@ "title": "Mermaid 圖表" }, "message": { - "attachments": { - "pasted_text": "剪切板文件", - "pasted_image": "剪切板圖片" - }, "api.check.model.title": "請選擇要偵測的模型", "api.connection.failed": "連接失敗", "api.connection.success": "連接成功", "assistant.added.content": "智慧代理人新增成功", + "attachments": { + "pasted_image": "剪切板圖片", + "pasted_text": "剪切板文件" + }, "backup.failed": "備份失敗", "backup.start.success": "開始備份", "backup.success": "備份成功", "chat.completion.paused": "聊天完成已暫停", "citations": "參考文獻", "copied": "已複製!", - "copy.success": "已複製!", "copy.failed": "複製失敗", + "copy.success": "已複製!", "error.chunk_overlap_too_large": "分段重疊不能大於分段大小", "error.dimension_too_large": "內容尺寸過大", "error.enter.api.host": "請先輸入您的 API 主機地址", @@ -437,20 +456,20 @@ "error.invalid.enter.model": "請選擇一個模型", "error.invalid.proxy.url": "無效的代理伺服器 URL", "error.invalid.webdav": "無效的 WebDAV 設定", + "error.joplin.export": "匯出 Joplin 失敗,請保持 Joplin 已運行並檢查連接狀態或檢查設定", + "error.joplin.no_config": "未設定 Joplin 授權Token 或 URL", "error.markdown.export.preconf": "導出 Markdown 文件到預先設定的路徑失敗", "error.markdown.export.specified": "導出 Markdown 文件失敗", "error.notion.export": "匯出 Notion 錯誤,請檢查連接狀態並對照文件檢查設定", "error.notion.no_api_key": "未設定 Notion API Key 或 Notion Database ID", "error.yuque.export": "匯出語雀錯誤,請檢查連接狀態並對照文件檢查設定", "error.yuque.no_config": "未設定語雀 Token 或知識庫 Url", - "error.joplin.no_config": "未設定 Joplin 授權Token 或 URL", - "error.joplin.export": "匯出 Joplin 失敗,請保持 Joplin 已運行並檢查連接狀態或檢查設定", "group.delete.content": "刪除分組訊息會刪除使用者提問和所有助手的回答", "group.delete.title": "刪除分組訊息", "ignore.knowledge.base": "網路模式開啟,忽略知識庫", "info.notion.block_reach_limit": "對話過長,自動分頁匯出到 Notion", - "loading.notion.preparing": "正在準備匯出到 Notion...", "loading.notion.exporting_progress": "正在匯出到 Notion ({{current}}/{{total}})...", + "loading.notion.preparing": "正在準備匯出到 Notion...", "mention.title": "切換模型回答", "message.code_style": "程式碼風格", "message.delete.content": "確定要刪除此訊息嗎?", @@ -473,22 +492,22 @@ "restore.success": "恢復成功", "save.success.title": "儲存成功", "searching": "正在網路上搜尋...", + "success.joplin.export": "成功匯出到 Joplin", "success.markdown.export.preconf": "成功導出 Markdown 文件到預先設定的路徑", "success.markdown.export.specified": "成功導出 Markdown 文件", "success.notion.export": "成功匯出到 Notion", "success.yuque.export": "成功匯出到語雀", - "success.joplin.export": "成功匯出到 Joplin", "switch.disabled": "請等待當前回覆完成", + "tools": { + "completed": "已完成", + "invoking": "調用中" + }, "topic.added": "新話題已新增", "upgrade.success.button": "重新啟動", "upgrade.success.content": "請重新啟動程式以完成升級", "upgrade.success.title": "升級成功", "warn.notion.exporting": "正在匯出到 Notion,請勿重複請求匯出!", - "warning.rate.limit": "發送過於頻繁,請在 {{seconds}} 秒後再嘗試", - "tools": { - "invoking": "調用中", - "completed": "已完成" - } + "warning.rate.limit": "發送過於頻繁,請在 {{seconds}} 秒後再嘗試" }, "minapp": { "sidebar.add.title": "新增到側邊欄", @@ -527,7 +546,7 @@ "embedding": "嵌入", "embedding_model": "嵌入模型", "embedding_model_tooltip": "在設定->模型服務中點選管理按鈕新增", - "free": "免費", + "function_calling": "函數調用", "no_matches": "無可用模型", "parameter_name": "參數名稱", "parameter_type": { @@ -537,22 +556,22 @@ "string": "文字" }, "pinned": "已固定", - "reasoning": "推理", + "rerank_model": "重排模型", + "rerank_model_support_provider": "目前重排序模型僅支持部分服務商 ({{provider}})", + "rerank_model_tooltip": "在設定->模型服務中點擊管理按鈕添加", "search": "搜尋模型...", "stream_output": "串流輸出", - "function_calling": "函數調用", "type": { "embedding": "嵌入", + "free": "免費", + "function_calling": "工具", "reasoning": "推理", + "rerank": "重排", "select": "選擇模型類型", "text": "文字", - "vision": "影像", - "function_calling": "函數調用" - }, - "vision": "視覺", - "websearch": "網路搜尋", - "rerank_model": "重排序模型", - "rerank_model_tooltip": "在設定->模型服務中點擊管理按鈕添加" + "vision": "視覺", + "websearch": "網路搜尋" + } }, "navbar": { "expand": "伸縮對話框", @@ -605,10 +624,12 @@ }, "provider": { "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", "anthropic": "Anthropic", "azure-openai": "Azure OpenAI", "baichuan": "百川", "baidu-cloud": "百度雲千帆", + "copilot": "GitHub Copilot", "dashscope": "阿里雲百鍊", "deepseek": "深度求索", "dmxapi": "DMXAPI", @@ -617,6 +638,7 @@ "gemini": "Gemini", "gitee-ai": "Gitee AI", "github": "GitHub Models", + "gpustack": "GPUStack", "graphrag-kylin-mountain": "GraphRAG", "grok": "Grok", "groq": "Groq", @@ -645,10 +667,7 @@ "xirang": "天翼雲息壤", "yi": "零一萬物", "zhinao": "360 智腦", - "zhipu": "智譜 AI", - "copilot": "GitHub Copilot", - "gpustack": "GPUStack", - "alayanew": "Alaya NeW" + "zhipu": "智譜 AI" }, "restore": { "confirm": "確定要復原資料嗎?", @@ -664,12 +683,6 @@ }, "title": "資料復原" }, - "gpustack": { - "keep_alive_time.description": "模型在記憶體中保持的時間(預設為 5 分鐘)。", - "keep_alive_time.placeholder": "分鐘", - "keep_alive_time.title": "保持活躍時間", - "title": "GPUStack" - }, "settings": { "about": "關於與回饋", "about.checkingUpdate": "正在檢查更新...", @@ -716,15 +729,30 @@ "data.title": "資料目錄", "hour_interval_one": "{{count}} 小時", "hour_interval_other": "{{count}} 小時", - "minute_interval_one": "{{count}} 分鐘", - "minute_interval_other": "{{count}} 分鐘", - "markdown_export.title": "Markdown 匯出", + "joplin": { + "check": { + "button": "檢查", + "empty_token": "請先輸入 Joplin 授權Token", + "empty_url": "請先輸入 Joplin 剪輯服務 URL", + "fail": "Joplin 連接驗證失敗", + "success": "Joplin 連接驗證成功" + }, + "help": "在 Joplin 選項中,啟用剪輯服務(無需安裝瀏覽器外掛),確認埠編號,並複製授權Token", + "title": "Joplin 設定", + "token": "Joplin 授權Token", + "token_placeholder": "請輸入 Joplin 授權Token", + "url": "Joplin 剪輯服務 URL", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "開啟後,匯出Markdown時會強制使用$$來標記LaTeX公式。注意:該項也會影響所有透過Markdown匯出的方式,如Notion、語雀等。", + "markdown_export.force_dollar_math.title": "LaTeX公式強制使用$$", + "markdown_export.help": "若填入,每次匯出時將自動儲存至該路徑;否則,將彈出儲存對話框。", "markdown_export.path": "預設匯出路徑", "markdown_export.path_placeholder": "匯出路徑", "markdown_export.select": "選擇", - "markdown_export.help": "若填入,每次匯出時將自動儲存至該路徑;否則,將彈出儲存對話框。", - "markdown_export.force_dollar_math.title": "LaTeX公式強制使用$$", - "markdown_export.force_dollar_math.help": "開啟後,匯出Markdown時會強制使用$$來標記LaTeX公式。注意:該項也會影響所有透過Markdown匯出的方式,如Notion、語雀等。", + "markdown_export.title": "Markdown 匯出", + "minute_interval_one": "{{count}} 分鐘", + "minute_interval_other": "{{count}} 分鐘", "notion.api_key": "Notion 金鑰", "notion.api_key_placeholder": "請輸入 Notion 金鑰", "notion.auto_split": "匯出對話時自動分頁", @@ -746,11 +774,22 @@ "notion.split_size_help": "Notion 免費版使用者建議設定為 90,進階版使用者建議設定為 24990,預設值為 90", "notion.split_size_placeholder": "請輸入每頁塊數限制 (預設 90)", "notion.title": "Notion 設定", + "obsidian": { + "folder": "資料夾", + "folder_placeholder": "請輸入資料夾名稱", + "tags": "全域標籤", + "tags_placeholder": "請輸入標籤名稱,多個標籤用英文逗號分隔。Obsidian 不可用純數字。", + "title": "Obsidian 設定", + "vault": "保險庫", + "vault_placeholder": "請輸入保險庫名稱" + }, "title": "資料設定", "webdav": { "autoSync": "自動備份", "autoSync.off": "關閉", "backup.button": "備份到 WebDAV", + "backup.modal.filename.placeholder": "請輸入備份文件名", + "backup.modal.title": "備份到 WebDAV", "host": "WebDAV 主機位址", "host.placeholder": "http://localhost:8080", "hour_interval_one": "{{count}} 小時", @@ -763,18 +802,16 @@ "path": "WebDAV 路徑", "path.placeholder": "/backup", "restore.button": "從 WebDAV 恢復", + "restore.confirm.content": "從 WebDAV 恢復將覆蓋目前資料,是否繼續?", + "restore.confirm.title": "復元確認", "restore.content": "從 WebDAV 恢復將覆蓋目前資料,是否繼續?", + "restore.modal.select.placeholder": "請選擇要恢復的備份文件", + "restore.modal.title": "從 WebDAV 恢復", "restore.title": "從 WebDAV 恢復", "syncError": "備份錯誤", "syncStatus": "備份狀態", "title": "WebDAV", - "user": "WebDAV 使用者名稱", - "backup.modal.title": "備份到 WebDAV", - "backup.modal.filename.placeholder": "請輸入備份文件名", - "restore.modal.title": "從 WebDAV 恢復", - "restore.modal.select.placeholder": "請選擇要恢復的備份文件", - "restore.confirm.title": "復元確認", - "restore.confirm.content": "從 WebDAV 恢復將覆蓋目前資料,是否繼續?" + "user": "WebDAV 使用者名稱" }, "yuque": { "check": { @@ -790,36 +827,6 @@ "title": "語雀設定", "token": "語雀 Token", "token_placeholder": "請輸入語雀 Token" - }, - "obsidian": { - "check": { - "button": "檢查", - "empty_url": "請先輸入 Obsidian REST API URL", - "empty_api_key": "請先輸入 Obsidian API Key", - "fail": "Obsidian 連接驗證失敗", - "success": "Obsidian 連接驗證成功" - }, - "help": "先安裝 Obsidian 插件 Local REST API,然後獲取 Obsidian API Key", - "url": "Obsidian 知識庫 URL", - "url_placeholder": "http://127.0.0.1:27123/", - "title": "Obsidian 設定", - "api_key": "Obsidian API Key", - "api_key_placeholder": "請輸入 Obsidian API Key" - }, - "joplin": { - "check": { - "button": "檢查", - "empty_url": "請先輸入 Joplin 剪輯服務 URL", - "empty_token": "請先輸入 Joplin 授權Token", - "fail": "Joplin 連接驗證失敗", - "success": "Joplin 連接驗證成功" - }, - "title": "Joplin 設定", - "help": "在 Joplin 選項中,啟用剪輯服務(無需安裝瀏覽器外掛),確認埠編號,並複製授權Token", - "url": "Joplin 剪輯服務 URL", - "url_placeholder": "http://127.0.0.1:41184/", - "token": "Joplin 授權Token", - "token_placeholder": "請輸入 Joplin 授權Token" } }, "display.assistant.title": "助手設定", @@ -865,12 +872,15 @@ "input.target_language.english": "英文", "input.target_language.japanese": "日文", "input.target_language.russian": "俄文", + "launch.onboot": "開機自動啟動", + "launch.title": "啟動", + "launch.totray": "啟動時最小化到系统匣", "mcp": { "actions": "操作", "active": "啟用", + "addError": "添加伺服器失敗", "addServer": "新增伺服器", "addSuccess": "伺服器新增成功", - "addError": "添加伺服器失敗", "args": "參數", "argsTooltip": "每個參數佔一行", "baseUrlTooltip": "遠端 URL 地址", @@ -881,55 +891,51 @@ "confirmDeleteMessage": "您確定要刪除該伺服器嗎?", "deleteError": "刪除伺服器失敗", "deleteSuccess": "伺服器刪除成功", + "dependenciesInstall": "安裝相依套件", + "dependenciesInstalling": "正在安裝相依套件...", "description": "描述", "duplicateName": "已存在相同名稱的伺服器", + "editJson": "編輯JSON", "editServer": "編輯伺服器", "env": "環境變數", "envTooltip": "格式:KEY=value,每行一個", "findMore": "更多 MCP 伺服器", + "install": "安裝", + "installError": "安裝相依套件失敗", + "installSuccess": "相依套件安裝成功", + "jsonFormatError": "JSON格式錯誤", + "jsonModeHint": "編輯MCP伺服器配置的JSON表示。保存前請確保格式正確。", + "jsonSaveError": "保存JSON配置失敗", + "jsonSaveSuccess": "JSON配置已儲存", + "missingDependencies": "缺失,請安裝它以繼續", "name": "名稱", "nameRequired": "請輸入伺服器名稱", "noServers": "未設定伺服器", + "npx_list": { + "actions": "操作", + "desc": "搜索並添加 npm 包作為 MCP 服務", + "description": "描述", + "no_packages": "未找到包", + "npm": "NPM", + "package_name": "包名稱", + "scope_placeholder": "輸入 npm 作用域 (例如 @your-org)", + "scope_required": "請輸入 npm 作用域", + "search": "搜索", + "search_error": "搜索失敗", + "title": "NPX 包列表", + "usage": "用法", + "version": "版本" + }, "serverPlural": "伺服器", "serverSingular": "伺服器", "title": "MCP 伺服器", - "type": "類型", - "updateSuccess": "伺服器更新成功", - "updateError": "更新伺服器失敗", - "url": "URL", "toggleError": "切換失敗", - "dependenciesInstalling": "正在安裝相依套件...", - "dependenciesInstall": "安裝相依套件", - "installSuccess": "相依套件安裝成功", - "installError": "安裝相依套件失敗", - "missingDependencies": "缺失,請安裝它以繼續", - "install": "安裝", - "npx_list": { - "title": "NPX 包列表", - "desc": "搜索並添加 npm 包作為 MCP 服務", - "scope_placeholder": "輸入 npm 作用域 (例如 @your-org)", - "search": "搜索", - "package_name": "包名稱", - "description": "描述", - "usage": "用法", - "npm": "NPM", - "version": "版本", - "actions": "操作", - "scope_required": "請輸入 npm 作用域", - "no_packages": "未找到包", - "search_error": "搜索失敗" - }, - "editJson": "編輯JSON", - "jsonModeHint": "編輯MCP伺服器配置的JSON表示。保存前請確保格式正確。", - "jsonFormatError": "JSON格式錯誤", - "jsonSaveSuccess": "JSON配置已儲存", - "jsonSaveError": "保存JSON配置失敗" + "type": "類型", + "updateError": "更新伺服器失敗", + "updateSuccess": "伺服器更新成功", + "url": "URL" }, "messages.divider": "訊息間顯示分隔線", - "messages.navigation": "訊息導航", - "messages.navigation.none": "不顯示", - "messages.navigation.buttons": "上下按鈕", - "messages.navigation.anchor": "對話錨點", "messages.grid_columns": "訊息網格展示列數", "messages.grid_popover_trigger": "網格詳細資訊觸發", "messages.grid_popover_trigger.click": "點選顯示", @@ -943,6 +949,10 @@ "messages.math_engine": "Markdown 渲染輸入訊息", "messages.metrics": "首字延遲 {{time_first_token_millsec}}ms | 每秒 {{token_speed}} tokens", "messages.model.title": "模型設定", + "messages.navigation": "訊息導航", + "messages.navigation.anchor": "對話錨點", + "messages.navigation.buttons": "上下按鈕", + "messages.navigation.none": "不顯示", "messages.title": "訊息設定", "messages.use_serif_font": "使用襯線字型", "model": "預設模型", @@ -1005,43 +1015,43 @@ "check": "檢查", "check_all_keys": "檢查所有金鑰", "check_multiple_keys": "檢查多個 API 金鑰", + "copilot": { + "auth_failed": "Github Copilot認證失敗", + "auth_success": "Github Copilot 認證成功", + "auth_success_title": "認證成功", + "code_failed": "獲取 Device Code失敗,請重試", + "code_generated_desc": "請將設備代碼複製到下面的瀏覽器連結中", + "code_generated_title": "獲取設備代碼", + "confirm_login": "過度使用可能會導致您的 Github 帳號遭到封號,請謹慎使用!!!!", + "confirm_title": "風險警告", + "connect": "連接 Github", + "custom_headers": "自訂請求標頭", + "description": "您的 Github 帳號需要訂閱 Copilot", + "expand": "展開", + "headers_description": "自訂請求標頭(json格式)", + "invalid_json": "JSON 格式錯誤", + "login": "登入 Github", + "logout": "退出 Github", + "logout_failed": "退出失敗,請重試", + "logout_success": "已成功登出", + "model_setting": "模型設定", + "open_verification_first": "請先點擊上方連結訪問驗證頁面", + "rate_limit": "速率限制", + "tooltip": "使用 Github Copilot 需要先登入 Github" + }, "delete.content": "確定要刪除此提供者嗎?", "delete.title": "刪除提供者", "docs_check": "檢查", "docs_more_details": "檢視更多細節", "get_api_key": "點選這裡取得金鑰", + "is_not_support_array_content": "開啟相容模式", "no_models": "請先新增模型再檢查 API 連接", "not_checked": "未檢查", "remove_duplicate_keys": "移除重複金鑰", "remove_invalid_keys": "刪除無效金鑰", "search": "搜尋模型平臺...", "search_placeholder": "搜尋模型 ID 或名稱", - "title": "模型提供者", - "is_not_support_array_content": "開啟相容模式", - "copilot": { - "tooltip": "使用 Github Copilot 需要先登入 Github", - "description": "您的 Github 帳號需要訂閱 Copilot", - "login": "登入 Github", - "connect": "連接 Github", - "logout": "退出 Github", - "auth_success_title": "認證成功", - "code_generated_title": "獲取設備代碼", - "code_generated_desc": "請將設備代碼複製到下面的瀏覽器連結中", - "code_failed": "獲取 Device Code失敗,請重試", - "auth_success": "Github Copilot 認證成功", - "auth_failed": "Github Copilot認證失敗", - "logout_success": "已成功登出", - "logout_failed": "退出失敗,請重試", - "confirm_title": "風險警告", - "confirm_login": "過度使用可能會導致您的 Github 帳號遭到封號,請謹慎使用!!!!", - "rate_limit": "速率限制", - "custom_headers": "自訂請求標頭", - "headers_description": "自訂請求標頭(json格式)", - "expand": "展開", - "model_setting": "模型設定", - "invalid_json": "JSON 格式錯誤", - "open_verification_first": "請先點擊上方連結訪問驗證頁面" - } + "title": "模型提供者" }, "proxy": { "mode": { @@ -1056,9 +1066,9 @@ "quickAssistant": { "click_tray_to_show": "點選工具列圖示啟動", "enable_quick_assistant": "啟用快捷助手", + "read_clipboard_at_startup": "啟動時讀取剪貼簿", "title": "快捷助手", - "use_shortcut_to_show": "右鍵點選工具列圖示或使用快捷鍵啟動", - "read_clipboard_at_startup": "啟動時讀取剪貼簿" + "use_shortcut_to_show": "右鍵點選工具列圖示或使用快捷鍵啟動" }, "shortcuts": { "action": "操作", @@ -1095,14 +1105,18 @@ "topic.position.left": "左側", "topic.position.right": "右側", "topic.show.time": "顯示話題時間", - "tray.title": "啟用系統工具列圖示", + "tray.onclose": "關閉時最小化到系统匣", + "tray.show": "顯示系统匣圖示", + "tray.title": "系统匣", "websearch": { "blacklist": "黑名單", "blacklist_description": "以下網站不會出現在搜尋結果中", "blacklist_tooltip": "請使用以下格式 (換行符號分隔)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", "check": "檢查", - "check_success": "驗證成功", "check_failed": "驗證失敗", + "check_success": "驗證成功", + "enhance_mode": "搜索增強模式", + "enhance_mode_tooltip": "使用預設模型提取關鍵詞後搜索", "get_api_key": "點選這裡取得金鑰", "no_provider_selected": "請選擇搜尋服務商後再檢查", "search_max_result": "搜尋結果個數", @@ -1110,8 +1124,6 @@ "search_provider_placeholder": "選擇一個搜尋服務商", "search_result_default": "預設", "search_with_time": "搜尋包含日期", - "enhance_mode": "搜索增強模式", - "enhance_mode_tooltip": "使用預設模型提取關鍵詞後搜索", "tavily": { "api_key": "Tavily API 金鑰", "api_key.placeholder": "請輸入 Tavily API 金鑰", @@ -1158,4 +1170,4 @@ "visualization": "視覺化" } } -} +} \ No newline at end of file diff --git a/src/renderer/src/i18n/translate/README.md b/src/renderer/src/i18n/translate/README.md new file mode 100644 index 000000000..abdaacb01 --- /dev/null +++ b/src/renderer/src/i18n/translate/README.md @@ -0,0 +1,2 @@ +本目录文件使用机器翻译,请勿编辑 +This directory file is machine translated, please do not edit diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json new file mode 100644 index 000000000..8741b470b --- /dev/null +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -0,0 +1,1173 @@ +{ + "translation": { + "agents": { + "add.button": "Προσθήκη στο Βοηθό", + "add.knowledge_base": "Βάση γνώσεων", + "add.knowledge_base.placeholder": "Επιλέξτε βάση γνώσεων", + "add.name": "Όνομα", + "add.name.placeholder": "Εισαγάγετε όνομα", + "add.prompt": "Φράση προκαλέσεως", + "add.prompt.placeholder": "Εισαγάγετε φράση προκαλέσεως", + "add.title": "Δημιουργία νέου ειδικού", + "delete.popup.content": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτόν τον ειδικό;", + "edit.message.add.title": "Προσθήκη", + "edit.message.assistant.placeholder": "Εισαγάγετε μήνυμα βοηθού", + "edit.message.assistant.title": "Βοηθός", + "edit.message.empty.content": "Το περιεχόμενο του συνομιλητή δεν μπορεί να είναι κενό.", + "edit.message.group.title": "Ομάδα μηνυμάτων", + "edit.message.title": "Προεπιλογές μηνυμάτων", + "edit.message.user.placeholder": "Εισαγάγετε μήνυμα χρήστη", + "edit.message.user.title": "Χρήστης", + "edit.model.select.title": "Επιλογή μοντέλου", + "edit.settings.hide_preset_messages": "Απόκρυψη προεπιλογών μηνυμάτων", + "edit.title": "Επεξεργασία ειδικού", + "manage.title": "Διαχείριση ειδικών", + "my_agents": "Οι ειδικοί μου", + "search.no_results": "Δεν βρέθηκαν σχετικοί ειδικοί", + "sorting.title": "Ταξινόμηση", + "tag.agent": "Ειδικός", + "tag.default": "Προεπιλογή", + "tag.new": "Νέος", + "tag.system": "Σύστημα", + "title": "Ειδικοί" + }, + "assistants": { + "abbr": "Βοηθός", + "clear.content": "Η διαγραφή του θέματος θα διαγράψει όλα τα θέματα και τα αρχεία του βοηθού. Είστε σίγουροι πως θέλετε να συνεχίσετε;", + "clear.title": "Διαγραφή θέματος", + "copy.title": "Αντιγραφή βοηθού", + "delete.content": "Η διαγραφή του βοηθού θα διαγράψει όλα τα θέματα και τα αρχεία που είναι συνδεδεμένα με αυτόν. Είστε σίγουροι πως θέλετε να συνεχίσετε;", + "delete.title": "Διαγραφή βοηθού", + "edit.title": "Επεξεργασία βοηθού", + "save.success": "Η αποθήκευση ολοκληρώθηκε επιτυχώς", + "save.title": "Αποθήκευση στον νοητή", + "search": "Αναζήτηση βοηθού", + "settings.default_model": "Προεπιλεγμένο μοντέλο", + "settings.knowledge_base": "Ρυθμίσεις βάσης γνώσεων", + "settings.model": "Ρυθμίσεις μοντέλου", + "settings.preset_messages": "Προεπιλεγμένα μηνύματα", + "settings.prompt": "Ρυθμίσεις προκαλύμματος", + "settings.reasoning_effort": "Μήκος λογισμικού αλυσίδας", + "settings.reasoning_effort.high": "Μεγάλο", + "settings.reasoning_effort.low": "Μικρό", + "settings.reasoning_effort.medium": "Μεσαίο", + "settings.reasoning_effort.off": "Απενεργοποίηση", + "settings.reasoning_effort.tip": "Υποστηρίζεται μόνο για μοντέλα πληροφορικής OpenAI o-series και Anthropic", + "title": "Βοηθός" + }, + "auth": { + "error": "Αποτυχία στην αυτόματη πήγαινη των κλειδιών, παρακαλείστε να το κάνετε χειροκίνητα", + "get_key": "Πήγαινη", + "get_key_success": "Η αυτόματη πήγαινη των κλειδιών ήταν επιτυχής", + "login": "Είσοδος", + "oauth_button": "Είσοδος με {{provider}}" + }, + "backup": { + "confirm": "Είστε σίγουροι ότι θέλετε να αντιγράψετε τα δεδομένα;", + "confirm.button": "Επιλογή μοντέλου αντιγράφου προσωρινής αποθήκευσης", + "content": "Αντιγράφετε όλα τα δεδομένα, συμπεριλαμβανομένων των εγγραφών συζήτησης, των ρυθμίσεων, της βάσης γνώσεων και όλων των δεδομένων. Παρακαλούμε σημειώστε ότι η διαδικασία αντιγράφου μπορεί να χρειαστεί λίγο χρόνο. Ευχαριστούμε για την υπομονή.", + "progress": { + "completed": "Η αντιγραφή ασφαλείας ολοκληρώθηκε", + "compressing": "Συμπίεση αρχείων...", + "copying_files": "Αντιγραφή αρχείων... {{progress}}%", + "preparing": "Ετοιμασία αντιγράφου ασφαλείας...", + "title": "Πρόοδος αντιγράφου ασφαλείας", + "writing_data": "Εγγραφή δεδομένων..." + }, + "title": "Αντιγραφή Δεδομένων" + }, + "button": { + "add": "προσθέστε", + "added": "προστέθηκε", + "collapse": "συμπεριλάβετε", + "manage": "χειριστείτε", + "select_model": "επιλογή μοντέλου", + "show.all": "δείξτε όλα", + "update_available": "Υπάρχει διαθέσιμη ενημέρωση" + }, + "chat": { + "add.assistant.title": "Προσθήκη βοηθού", + "artifacts.button.download": "Λήψη", + "artifacts.button.openExternal": "Άνοιγμα στο εξωτερικό περιηγητή", + "artifacts.button.preview": "Προεπισκόπηση", + "artifacts.preview.openExternal.error.content": "Σφάλμα κατά την άνοιγμα στο εξωτερικό περιηγητή", + "assistant.search.placeholder": "Αναζήτηση", + "deeply_thought": "Έχει βαθιά σκεφτεί (χρήση {{secounds}} δευτερόλεπτα)", + "default.description": "Γεια σου, είμαι ο προεπαγγελματικός βοηθός. Μπορείς να ξεκινήσεις να μου μιλάς αμέσως.", + "default.name": "Προεπαγγελματικός βοηθός", + "default.topic.name": "Προεπαγγελματικός θέμα", + "input.auto_resize": "Αυτόματη μείωση ύψους", + "input.clear": "Καθαρισμός μηνυμάτων {{Command}}", + "input.clear.content": "Είσαι σίγουρος ότι θέλεις να διαγράψεις όλα τα μηνύματα της τρέχουσας συζήτησης;", + "input.clear.title": "Καθαρισμός μηνυμάτων", + "input.collapse": "Συμπιέζω", + "input.context_count.tip": "Πλήθος ενδιάμεσων/Μέγιστο πλήθος ενδιάμεσων", + "input.estimated_tokens.tip": "Εκτιμώμενος αριθμός tokens", + "input.expand": "Επεκτάση", + "input.file_not_supported": "Το μοντέλο δεν υποστηρίζει αυτό το είδος αρχείων", + "input.knowledge_base": "Βάση γνώσεων", + "input.new.context": "Καθαρισμός ενδιάμεσων {{Command}}", + "input.new_topic": "Νέο θέμα {{Command}}", + "input.pause": "Παύση", + "input.placeholder": "Εισάγετε μήνυμα εδώ...", + "input.send": "Αποστολή", + "input.settings": "Ρυθμίσεις", + "input.topics": "Θέματα", + "input.translate": "Μετάφραση στο {{target_language}}", + "input.upload": "Φόρτωση εικόνας ή έγγραφου", + "input.upload.document": "Φόρτωση έγγραφου (το μοντέλο δεν υποστηρίζει εικόνες)", + "input.web_search": "Ενεργοποίηση διαδικτυακής αναζήτησης", + "input.web_search.button.ok": "Πήγαινε στις ρυθμίσεις", + "input.web_search.enable": "Ενεργοποίηση διαδικτυακής αναζήτησης", + "input.web_search.enable_content": "Πρέπει να ελέγξετε τη σύνδεση με το διαδίκτυο στις ρυθμίσεις πρώτα", + "message.new.branch": "Διακοπή", + "message.new.branch.created": "Νέα διακοπή δημιουργήθηκε", + "message.new.context": "Καθαρισμός ενδιάμεσων", + "message.quote": "Αναφορά", + "message.regenerate.model": "Εναλλαγή μοντέλου", + "message.useful": "Χρήσιμο", + "navigation": { + "first": "Ήδη το πρώτο μήνυμα", + "last": "Ήδη το τελευταίο μήνυμα", + "next": "Επόμενο μήνυμα", + "prev": "Προηγούμενο μήνυμα" + }, + "resend": "Ξαναστείλε", + "save": "Αποθήκευση", + "settings.code_collapsible": "Οι κώδικες μπορούν να συμπιεζόνται", + "settings.code_wrappable": "Οι κώδικες μπορούν να γράφονται σε διαφορετική γραμμή", + "settings.context_count": "Πλήθος ενδιάμεσων", + "settings.context_count.tip": "Πλήθος των μηνυμάτων που θα παραμείνουν στα ενδιάμεσα, όσο μεγαλύτερο είναι το αριθμός, τόσο μεγαλύτερο είναι το μήκος του ενδιάμεσου και τόσο περισσότερα tokens χρησιμοποιούνται. Συνομιλία συνήθως συνιστάται μεταξύ 5-10", + "settings.max": "Όχι ορισμένο", + "settings.max_tokens": "Ενεργοποίηση περιορισμού μήκους μηνύματος", + "settings.max_tokens.confirm": "Ενεργοποίηση περιορισμού μήκους μηνύματος", + "settings.max_tokens.confirm_content": "Μετά την ενεργοποίηση του περιορισμού μήκους μηνύματος, ο μέγιστος αριθμός των tokens που χρησιμοποιούνται κάθε φορά, θα επηρεάζει το μήκος της απάντησης. Πρέπει να το ρυθμίζετε βάσει των περιορισμών του πλαισίου του μοντέλου, διαφορετικά θα σφάλλεται.", + "settings.max_tokens.tip": "Ο μέγιστος αριθμός των tokens που χρησιμοποιούνται κάθε φορά, θα επηρεάζει το μήκος της απάντησης. Πρέπει να το ρυθμίζετε βάσει των περιορισμών του πλαισίου του μοντέλου, διαφορετικά θα σφάλλεται.", + "settings.reset": "Επαναφορά", + "settings.set_as_default": "Εφαρμογή στον προεπαγγελματικό βοηθό", + "settings.show_line_numbers": "Εμφάνιση αριθμού γραμμών στον κώδικα", + "settings.temperature": "Θερμοκρασία μοντέλου", + "settings.temperature.tip": "Ο αντικειμενικός βαθμός τυχαιότητας του μοντέλου στην παραγωγή κειμένου. Ο μεγαλύτερος αριθμός σημαίνει περισσότερη ποικιλία, δημιουργικότητα και τυχαιότητα στις απαντήσεις· η έδρα μετά την επιλογή 0 επιστρέφει απαντήσεις βάσει των γεγονότων. Για καθημερινές συζητήσεις προτείνεται η επιλογή 0.7.", + "settings.thought_auto_collapse": "Αυτόματη συμπίεση σκέψεων", + "settings.thought_auto_collapse.tip": "Μετά τη λήξη της σκέψης, η σκέψη αυτόματα συμπιεζεται", + "settings.top_p": "Top-P", + "settings.top_p.tip": "Η προεπιλογή είναι 1, όσο μικρότερος είναι ο αριθμός, τόσο μικρότερη είναι η ποικιλία του περιεχομένου που παράγεται από το AI και τόσο εύκολοτερο είναι να κατανοείται· όσο μεγαλύτερος είναι, τόσο μεγαλύτερη είναι η ποικιλία των λέξεων που μπορεί να χρησιμοποιήσει το AI.", + "suggestions.title": "Προτεινόμενες ερωτήσεις", + "thinking": "Σκέψη", + "topics.auto_rename": "Δημιουργία θέματος", + "topics.clear.title": "Καθαρισμός μηνυμάτων", + "topics.copy.image": "Αντιγραφή ως εικόνα", + "topics.copy.md": "Αντιγραφή ως Markdown", + "topics.copy.title": "Αντιγραφή", + "topics.delete.shortcut": "Πατήστε {{key}} για να διαγράψετε αμέσως", + "topics.edit.placeholder": "Εισαγάγετε το νέο όνομα", + "topics.edit.title": "Επεξεργασία ονόματος θέματος", + "topics.export.image": "Εξαγωγή ως εικόνα", + "topics.export.joplin": "Εξαγωγή στο Joplin", + "topics.export.md": "Εξαγωγή ως Markdown", + "topics.export.notion": "Εξαγωγή στο Notion", + "topics.export.obsidian": "Εξαγωγή στο Obsidian", + "topics.export.obsidian_atributes": "Ρυθμίσεις σημείου σημείωσης", + "topics.export.obsidian_btn": "ΟΚ", + "topics.export.obsidian_created": "Ημερομηνία δημιουργίας", + "topics.export.obsidian_created_placeholder": "Επιλέξτε την ημερομηνία δημιουργίας", + "topics.export.obsidian_export_failed": "Η εξαγωγή απέτυχε", + "topics.export.obsidian_export_success": "Η εξαγωγή ήταν επιτυχής", + "topics.export.obsidian_not_configured": "Το Obsidian δεν είναι συντονισμένο", + "topics.export.obsidian_operate": "Επεξεργασία μεθόδου", + "topics.export.obsidian_operate_append": "Επισυναγωγή", + "topics.export.obsidian_operate_new_or_overwrite": "Νέο (επιστροφή σε επιστροφή)", + "topics.export.obsidian_operate_placeholder": "Επιλέξτε την μεθόδο επεξεργασίας", + "topics.export.obsidian_operate_prepend": "Προσθήκη", + "topics.export.obsidian_source": "Πηγή", + "topics.export.obsidian_source_placeholder": "Εισάγετε την πηγή", + "topics.export.obsidian_tags": "Ετικέτες", + "topics.export.obsidian_tags_placeholder": "Εισάγετε τις ετικέτες, χωρισμένες με κόμματα στα Αγγλικά, τα ετικέτα μπορεί να μην είναι μόνο αριθμοί", + "topics.export.obsidian_title": "Τίτλος", + "topics.export.obsidian_title_placeholder": "Εισάγετε τον τίτλο", + "topics.export.obsidian_title_required": "Ο τίτλος δεν μπορεί να είναι κενός", + "topics.export.title": "Εξαγωγή", + "topics.export.word": "Εξαγωγή ως Word", + "topics.export.yuque": "Εξαγωγή στο Yuque", + "topics.list": "Λίστα θεμάτων", + "topics.move_to": "Μετακίνηση στο", + "topics.new": "Ξεκινήστε νέα συζήτηση", + "topics.pinned": "Σταθερά θέματα", + "topics.prompt": "Προσδοκώμενα όρια", + "topics.prompt.edit.title": "Επεξεργασία προσδοκώμενων όριων", + "topics.prompt.tips": "Προσδοκώμενα όρια: προσθέτει επιπλέον επιστημονικές προσθήκες για το παρόν θέμα", + "topics.title": "Θέματα", + "topics.unpinned": "Αποστέλλω", + "translate": "Μετάφραση", + "input.generate_image": "Δημιουργία εικόνας", + "input.generate_image_not_supported": "Το μοντέλο δεν υποστηρίζει τη δημιουργία εικόνων" + }, + "code_block": { + "collapse": "συμπεριληφθείς", + "disable_wrap": "ακύρωση αλλαγής γραμμής", + "enable_wrap": "άλλαγη γραμμής", + "expand": "επιλογή" + }, + "common": { + "add": "Προσθέστε", + "advanced_settings": "Προχωρημένες ρυθμίσεις", + "and": "και", + "assistant": "Εξυπνιασμένη Ενότητα", + "avatar": "Εικονίδιο", + "back": "Πίσω", + "cancel": "Άκυρο", + "chat": "Συζήτηση", + "clear": "Καθαρισμός", + "close": "Κλείσιμο", + "confirm": "Επιβεβαίωση", + "copied": "Αντιγράφηκε", + "copy": "Αντιγραφή", + "cut": "Κοπή", + "default": "Προεπιλογή", + "delete": "Διαγραφή", + "description": "Περιγραφή", + "docs": "Έγγραφα", + "download": "Λήψη", + "duplicate": "Αντιγραφή", + "edit": "Επεξεργασία", + "expand": "Επεκτάση", + "footnote": "Παραπομπή", + "footnotes": "Παραπομπές", + "fullscreen": "Εισήχθη σε πλήρη οθόνη, πατήστε F11 για να έξω", + "knowledge_base": "Βάση Γνώσεων", + "language": "Γλώσσα", + "model": "Μοντέλο", + "models": "Μοντέλα", + "more": "Περισσότερα", + "name": "Όνομα", + "paste": "Επικόλληση", + "prompt": "Ενδεικτικός ρήματος", + "provider": "Παρέχων", + "regenerate": "Ξαναπαραγωγή", + "rename": "Μετονομασία", + "reset": "Επαναφορά", + "save": "Αποθήκευση", + "search": "Αναζήτηση", + "select": "Επιλογή", + "topics": "Θέματα", + "warning": "Προσοχή", + "you": "Εσείς" + }, + "docs": { + "title": "Βοήθεια" + }, + "error": { + "backup.file_format": "Λάθος μορφή αρχείου που επιστρέφεται", + "chat.response": "Σφάλμα. Εάν δεν έχετε ρυθμίσει το κλειδί API, πηγαίνετε στο ρυθμισμένα > παρέχοντας το πρόσωπο του μοντέλου", + "http": { + "400": "Σφάλμα ζητήματος, παρακαλώ ελέγξτε αν τα παράμετρα του ζητήματος είναι σωστά. Εάν έχετε αλλάξει τις ρυθμίσεις του μοντέλου, επαναφέρετε τις προεπιλεγμένες ρυθμίσεις.", + "401": "Αποτυχία επιβεβαίωσης ταυτότητας, παρακαλώ ελέγξτε αν η κλειδί API είναι σωστή", + "403": "Απαγορεύεται η πρόσβαση, παρακαλώ μεταφράστε το συγκεκριμένο σφάλμα για να δείτε την αιτία ή επικοινωνήστε με τον παροχεύτη για να μάθετε την αιτία της απαγόρευσης", + "404": "Το μοντέλο δεν υπάρχει ή η διαδρομή παραγγελίας είναι λάθος", + "429": "Υπερβολική συχνότητα ζητημάτων, παρακαλώ δοκιμάστε ξανά", + "500": "Εσωτερικό σφάλμα διαχειριστή, παρακαλώ δοκιμάστε ξανά", + "502": "Σφάλμα φάρων, παρακαλώ δοκιμάστε ξανά", + "503": "Η υπηρεσία δεν είναι διαθέσιμη, παρακαλώ δοκιμάστε ξανά", + "504": "Υπερχρονισμός φάρων, παρακαλώ δοκιμάστε ξανά" + }, + "model.exists": "Το μοντέλο υπάρχει ήδη", + "no_api_key": "Δεν έχετε ρυθμίσει το κλειδί API", + "provider_disabled": "Ο παρεχόμενος παροχός του μοντέλου δεν είναι ενεργοποιημένος", + "render": { + "description": "Απέτυχε η ώθηση της εξίσωσης, παρακαλώ ελέγξτε το σωστό μορφάτι της", + "title": "Σφάλμα Παρασκήνιου" + }, + "user_message_not_found": "Αδυναμία εύρεσης της αρχικής μηνύματος χρήστη" + }, + "export": { + "assistant": "βοηθός", + "attached_files": "συνημμένα αρχεία", + "conversation_details": "λεπτομέρειες συζήτησης", + "conversation_history": "Ιστορικό Συζητήσεων", + "created": "Ημερομηνία Δημιουργίας", + "last_updated": "Τελευταία ενημέρωση", + "messages": "Αριθμός Μηνυμάτων", + "user": "Χρήστης" + }, + "files": { + "actions": "Ενέργειες", + "all": "Όλα τα αρχεία", + "count": "Αριθμός αρχείων", + "created_at": "Ημερομηνία δημιουργίας", + "delete": "Διαγραφή", + "delete.content": "Η διαγραφή του αρχείου θα διαγράψει την αναφορά του σε όλα τα μηνύματα. Είστε σίγουροι ότι θέλετε να διαγράψετε αυτό το αρχείο;", + "delete.paintings.warning": "Το σχεδίο περιλαμβάνει αυτή την εικόνα και δεν είναι παρόλως δυνατή η διαγραφή.", + "delete.title": "Διαγραφή αρχείου", + "document": "Έγγραφο", + "edit": "Επεξεργασία", + "file": "Αρχείο", + "image": "Εικόνα", + "name": "Όνομα αρχείου", + "open": "Άνοιγμα", + "size": "Μέγεθος", + "text": "Κείμενο", + "title": "Αρχεία", + "type": "Τύπος" + }, + "gpustack": { + "keep_alive_time.description": "Χρόνος που ο μοντέλος παραμένει στη μνήμη (προεπιλογή: 5 λεπτά)", + "keep_alive_time.placeholder": "λεπτά", + "keep_alive_time.title": "Χρόνος διατήρησης ενεργοποίησης", + "title": "GPUStack" + }, + "history": { + "continue_chat": "Συνεχίστε το συνομιλημένο", + "locate.message": "Εφαρμογή στο μήνυμα", + "search.messages": "Αναζήτηση όλων των μηνυμάτων", + "search.placeholder": "Αναζήτηση θεμάτων ή μηνυμάτων...", + "search.topics.empty": "Δεν βρέθηκαν σχετικά θέματα, πατήστε Enter για να αναζητήσετε όλα τα μηνύματα", + "title": "Αναζήτηση θεμάτων" + }, + "knowledge": { + "add": { + "title": "Προσθήκη βιβλιοθήκης γνώσεων" + }, + "add_directory": "Προσθήκη καταλόγου", + "add_file": "Προσθήκη αρχείου", + "add_note": "Προσθήκη σημειώματος", + "add_sitemap": "Χάρτης τόπων", + "add_url": "Προσθήκη διευθύνσεως", + "cancel_index": "Άκυρη ευρετήριοποίηση", + "chunk_overlap": "Μέγεθος επιφάνειας", + "chunk_overlap_placeholder": "Προεπιλογή (δεν συνιστάται να το αλλάξετε)", + "chunk_overlap_tooltip": "Το ποσοστό επιφάνειας επιφάνειας μεταξύ γειτνιώντων κειμένων μπλοκ, για να εξασφαλίσετε ότι τα κείμενα μπλοκ μετά τη διακοσμηση εξακολουθούν να έχουν σχέση σε προσδιορισμό, βελτιώνοντας την συνολική αποτελεσματικότητα επεξεργασίας με μοντέλα μεγάλου κειμένου", + "chunk_size": "Μέγεθος μερισμού", + "chunk_size_change_warning": "Η αλλαγή του μεγέθους μερισμού και της επιφάνειας επιφάνειας εφαρμόζεται μόνο για νέα προσθέτομεν αρχεία", + "chunk_size_placeholder": "Προεπιλογή (δεν συνιστάται να το αλλάξετε)", + "chunk_size_too_large": "Το μέγεθος μερισμού δεν μπορεί να ξεπεράσει το όριο πλάτους επιρροής του μοντέλου ({{max_context}})", + "chunk_size_tooltip": "Διαχωρισμός των έγγραφων σε μεριδισμούς, με το μέγεθος κάθε μεριδισμού να μην ξεπεράζει το όριο πλάτους επιρροής του μοντέλου", + "clear_selection": "Καθαρισμός επιλογής", + "delete": "Διαγραφή", + "delete_confirm": "Είστε σίγουρος ότι θέλετε να διαγράψετε αυτή τη βάση γνώσεων;", + "directories": "Κατάλογοι", + "directory_placeholder": "Εισάγετε το δρομολόγιο του καταλόγου", + "document_count": "Ποσότητα κειμένων που ζητούνται", + "document_count_default": "Προεπιλογή", + "document_count_help": "Όσο μεγαλύτερη είναι η ποσότητα των κειμένων που ζητούνται, τόσο περισσότερες πληροφορίες παρέχονται, αλλά και οι καταναλωτικοί Token επειδή περισσότερα", + "drag_file": "Βάλτε το αρχείο εδώ", + "edit_remark": "Μεταβολή σημειώματος", + "edit_remark_placeholder": "Εισάγετε το σημείωμα", + "empty": "Λεηλασία βάσης γνώσεων", + "file_hint": "Υποστηρίζεται το {{file_types}} μορφάττων", + "index_all": "Ευρετήριοποίηση όλων", + "index_cancelled": "Η ευρετήριοποίηση διακόπηκε", + "index_started": "Η ευρετήριοποίηση ξεκίνησε", + "invalid_url": "Μη έγκυρη διευθύνση", + "model_info": "Πληροφορίες μοντέλου", + "no_bases": "Λεηλασία βάσης γνώσεων", + "no_match": "Δεν βρέθηκαν στοιχεία γνώσεων", + "no_provider": "Η παροχή υπηρεσιών μοντέλου βάσης γνώσεων χαθηκε, αυτή η βάση γνώσεων δεν θα υποστηρίζεται πλέον, παρακαλείστε να δημιουργήσετε ξανά μια βάση γνώσεων", + "not_set": "Δεν έχει ρυθμιστεί", + "not_support": "Το μοντέλο βάσης γνώσεων έχει ενημερωθεί, αυτή η βάση γνώσεων δεν θα υποστηρίζεται πλέον, παρακαλείστε να δημιουργήσετε ξανά μια βάση γνώσεων", + "notes": "Σημειώματα", + "notes_placeholder": "Εισάγετε πρόσθετες πληροφορίες ή πληροφορίες προσδιορισμού για αυτή τη βάση γνώσεων...", + "rename": "Μετονομασία", + "search": "Αναζήτηση βάσης γνώσεων", + "search_placeholder": "Εισάγετε την αναζήτηση", + "settings": "Ρυθμίσεις βάσης γνώσεων", + "sitemap_placeholder": "Εισάγετε τη διεύθυνση URL του χάρτη τόπων", + "sitemaps": "Στοιχεία του δικτύου", + "source": "Πηγή", + "status": "Κατάσταση", + "status_completed": "Ολοκληρώθηκε", + "status_failed": "Αποτυχία", + "status_new": "Προστέθηκε", + "status_pending": "Εκκρεμής", + "status_processing": "Επεξεργασία", + "threshold": "Περιθώριο συνάφειας", + "threshold_placeholder": "Δεν έχει ρυθμιστεί", + "threshold_too_large_or_small": "Το περιθώριο δεν μπορεί να είναι μεγαλύτερο από 1 ή μικρότερο από 0", + "threshold_tooltip": "Χρησιμοποιείται για τη μετρηση της σχέσης συνάφειας μεταξύ της ερώτησης του χρήστη και των περιεχομένων της βάσης γνώσεων (0-1)", + "title": "Βάση γνώσεων", + "topN": "Ποσότητα αποτελεσμάτων που επιστρέφονται", + "topN__too_large_or_small": "Η ποσότητα των αποτελεσμάτων που επιστρέφονται δεν μπορεί να είναι μεγαλύτερη από 100 ή μικρότερη από 1", + "topN_placeholder": "Δεν έχει ρυθμιστεί", + "topN_tooltip": "Η ποσότητα των επιστρεφόμενων αποτελεσμάτων που συνάφονται, όσο μεγαλύτερη είναι η τιμή, τόσο περισσότερα αποτελέσματα συνδέονται, αλλά και οι καταναλωτικοί Token επειδή περισσότερα", + "url_added": "Η διεύθυνση προστέθηκε", + "url_placeholder": "Εισάγετε τη διεύθυνση, χωρίστε πολλαπλές διευθύνσεις με επιστροφή", + "urls": "Διευθύνσεις" + }, + "languages": { + "arabic": "Αραβικά", + "chinese": "Σίναρα Κινέζικά", + "chinese-traditional": "Παραδοσιακά Κινέζικά", + "english": "Αγγλικά", + "french": "Γαλλικά", + "german": "Γερμανικά", + "italian": "Ιταλικά", + "japanese": "Ιαπωνικά", + "korean": "Κορεάτικά", + "portuguese": "Πορτογαλικά", + "russian": "Ρωσικά", + "spanish": "Ισπανικά" + }, + "lmstudio": { + "keep_alive_time.description": "Χρόνος που ο μοντέλος διατηρείται στη μνήμη μετά από το συνομιλητή (προεπιλογή: 5 λεπτά)", + "keep_alive_time.placeholder": "λεπτά", + "keep_alive_time.title": "Χρόνος διατήρησης ενεργοποίησης", + "title": "LM Studio" + }, + "mermaid": { + "download": { + "png": "Λήψη PNG", + "svg": "Λήψη SVG" + }, + "resize": { + "zoom-in": "Μεγάλυνση", + "zoom-out": "Σμικρύνση" + }, + "tabs": { + "preview": "Προεπισκόπηση", + "source": "Κώδικας πηγής" + }, + "title": "Χαρτί Mermaid" + }, + "message": { + "api.check.model.title": "Επιλέξτε το μοντέλο που θα ελέγξετε", + "api.connection.failed": "Η σύνδεση απέτυχε", + "api.connection.success": "Η σύνδεση ήταν επιτυχής", + "assistant.added.content": "Ο ενεργοποιημένος αστρόναυτης προστέθηκε επιτυχώς", + "attachments": { + "pasted_image": "Εικόνα στο πινάκιδα", + "pasted_text": "Κείμενο στο πινάκιδα" + }, + "backup.failed": "Η αντιγραφή ασφαλείας απέτυχε", + "backup.start.success": "Η αρχή της αντιγραφής ασφαλείας ήταν επιτυχής", + "backup.success": "Η αντιγραφή ασφαλείας ήταν επιτυχής", + "chat.completion.paused": "Η συζήτηση διακόπηκε", + "citations": "Περιεχόμενα αναφοράς", + "copied": "Αντιγράφηκε", + "copy.failed": "Η αντιγραφή απέτυχε", + "copy.success": "Η αντιγραφή ήταν επιτυχής", + "error.chunk_overlap_too_large": "Η επικάλυψη μεριδίων δεν μπορεί να είναι μεγαλύτερη από το μέγεθος του μεριδίου", + "error.dimension_too_large": "Το μέγεθος του περιεχομένου είναι πολύ μεγάλο", + "error.enter.api.host": "Παρακαλώ εισάγετε τη διεύθυνση API σας", + "error.enter.api.key": "Παρακαλώ εισάγετε το κλειδί API σας", + "error.enter.model": "Παρακαλώ επιλέξτε ένα μοντέλο", + "error.enter.name": "Παρακαλώ εισάγετε ένα όνομα για τη βάση γνώσεων", + "error.get_embedding_dimensions": "Απέτυχε η πρόσληψη διαστάσεων ενσωμάτωσης", + "error.invalid.api.host": "Μη έγκυρη διεύθυνση API", + "error.invalid.api.key": "Μη έγκυρο κλειδί API", + "error.invalid.enter.model": "Παρακαλώ επιλέξτε ένα μοντέλο", + "error.invalid.proxy.url": "Μη έγκυρη διεύθυνση προξενικού", + "error.invalid.webdav": "Μη έγκυρη ρύθμιση WebDAV", + "error.joplin.export": "Η εξαγωγή του Joplin απέτυχε, παρακαλείστε να ελέγξετε τη σύνδεση και τη διαμόρφωση κατά τη διατύπωση του χειρισμού", + "error.joplin.no_config": "Δεν έχετε διαθέσιμο το Token εξουσιοδότησης του Joplin ή το URL του Joplin", + "error.markdown.export.preconf": "Η εξαγωγή αρχείου Markdown στο προϋπολογισμένο μοντέλο απέτυχε", + "error.markdown.export.specified": "Η εξαγωγή αρχείου Markdown απέτυχε", + "error.notion.export": "Σφάλμα στην εξαγωγή του Notion, παρακαλείστε να ελέγξετε τη σύνδεση και τη διαμόρφωση κατά τη διατύπωση του χειρισμού", + "error.notion.no_api_key": "Δεν έχετε διαθέσιμο το API Key του Notion ή το ID της βάσης του Notion", + "error.yuque.export": "Σφάλμα στην εξαγωγή της Yuque, παρακαλείστε να ελέγξετε τη σύνδεση και τη διαμόρφωση κατά τη διατύπωση του χειρισμού", + "error.yuque.no_config": "Δεν έχετε διαθέσιμο το Token της Yuque ή το URL της βάσης της Yuque", + "group.delete.content": "Η διαγραφή της ομάδας θα διαγράψει τις ερωτήσεις των χρηστών και όλες τις απαντήσεις του αστρόναυτη", + "group.delete.title": "Διαγραφή ομάδας", + "ignore.knowledge.base": "Λειτουργία σύνδεσης ενεργοποιημένη, αγνοείται η βάση γνώσεων", + "info.notion.block_reach_limit": "Η συζήτηση είναι πολύ μεγάλη, εξάγεται σε περιοχές στο Notion", + "loading.notion.exporting_progress": "Εξάγεται στο Notion ({{current}}/{{total}})...", + "loading.notion.preparing": "Ετοιμάζεται η εξαγωγή στο Notion...", + "mention.title": "Εναλλαγή απάντησης αστρόναυτη", + "message.code_style": "Στυλ κώδικα", + "message.delete.content": "Θέλετε να διαγράψετε αυτό το μήνυμα;", + "message.delete.title": "Διαγραφή μηνύματος", + "message.multi_model_style": "Στυλ πολλαπλών απαντήσεων μοντέλου", + "message.multi_model_style.fold": "Κατάσταση ενσωμάτωσης", + "message.multi_model_style.fold.compress": "Εναλλαγή στη συμπιεσμένη διάταξη", + "message.multi_model_style.fold.expand": "Εναλλαγή στην επεκτατική διάταξη", + "message.multi_model_style.grid": "Διάταξη κάρτας", + "message.multi_model_style.horizontal": "Διάταξη επίπεδης", + "message.multi_model_style.vertical": "Διάταξη κάθετης", + "message.style": "Στυλ μηνύματος", + "message.style.bubble": "Αερογεύματα", + "message.style.plain": "Απλός", + "regenerate.confirm": "Η επαναδημιουργία θα αφαιρέσει το τρέχον μήνυμα", + "reset.confirm.content": "Θέλετε να επαναφέρετε όλα τα δεδομένα;", + "reset.double.confirm.content": "Όλα τα δεδομένα σας θα χαθούν, εάν δεν έχετε κάνει αντιγραφή, δεν θα μπορείτε να ανακτήσετε τα δεδομένα, είστε σίγουροι ότι θέλετε να συνεχίσετε;", + "reset.double.confirm.title": "Η απώλεια δεδομένων!!!", + "restore.failed": "Η αποκατάσταση απέτυχε", + "restore.success": "Η αποκατάσταση ήταν επιτυχής", + "save.success.title": "Η αποθήκευση ήταν επιτυχής", + "searching": "Ενεργοποιείται αναζήτηση στο διαδίκτυο...", + "success.joplin.export": "Η εξαγωγή στο Joplin ήταν επιτυχής", + "success.markdown.export.preconf": "Η εξαγωγή αρχείου Markdown στο προϋπολογισμένο μοντέλο ήταν επιτυχής", + "success.markdown.export.specified": "Η εξαγωγή αρχείου Markdown ήταν επιτυχής", + "success.notion.export": "Η εξαγωγή στο Notion ήταν επιτυχής", + "success.yuque.export": "Η εξαγωγή στη Yuque ήταν επιτυχής", + "switch.disabled": "Παρακαλείστε να περιμένετε τη λήξη της τρέχουσας απάντησης", + "tools": { + "completed": "Ολοκληρώθηκε", + "invoking": "κλήση σε εξέλιξη" + }, + "topic.added": "Η θεματική προστέθηκε επιτυχώς", + "upgrade.success.button": "Επανεκκίνηση", + "upgrade.success.content": "Επανεκκίνηση για να ολοκληρώσετε την ενημέρωση", + "upgrade.success.title": "Η ενημέρωση ήταν επιτυχής", + "warn.notion.exporting": "Εξαγωγή στο Notion, μην επαναλάβετε την διαδικασία εξαγωγής!", + "warning.rate.limit": "Υπερβολική συχνότητα στείλατε παρακαλώ περιμένετε {{seconds}} δευτερόλεπτα και προσπαθήστε ξανά" + }, + "minapp": { + "sidebar.add.title": "Προσθήκη στην πλευρή", + "sidebar.remove.title": "Αφαίρεση από την πλευρή", + "title": "Μικρόπρογραμμα" + }, + "miniwindow": { + "clipboard": { + "empty": "Το πινάκιδα κόπων είναι άδειο" + }, + "feature": { + "chat": "Απάντηση σ' αυτή την ερώτηση", + "explanation": "Εξήγηση", + "summary": "Σύνοψη", + "translate": "Μετάφραση κειμένου" + }, + "footer": { + "copy_last_message": "Παράκαμε το τελευταίο μήνυμα", + "esc": "πατήστε ESC για {{action}}", + "esc_back": "Επιστροφή", + "esc_close": "Κλείσιμο παραθύρου" + }, + "input": { + "placeholder": { + "empty": "Ρώτα τον {{model}} για βοήθεια...", + "title": "Τι θέλεις να κάνεις με το κείμενο που είναι παρακάτω" + } + } + }, + "models": { + "add_parameter": "Προσθήκη παραμέτρων", + "all": "Όλα", + "custom_parameters": "Προσαρμοσμένοι παράμετροι", + "dimensions": "{{dimensions}} διαστάσεις", + "edit": "Επεξεργασία μοντέλου", + "embedding": "Ενσωμάτωση", + "embedding_model": "Μοντέλο ενσωμάτωσης", + "embedding_model_tooltip": "Κάντε κλικ στο κουμπί Διαχείριση στο παράθυρο Ρυθμίσεις -> Υπηρεσία Μοντέλων", + "function_calling": "Ξεχωριστική Κλήση Συναρτήσεων", + "no_matches": "Δεν υπάρχουν διαθέσιμα μοντέλα", + "parameter_name": "Όνομα παραμέτρου", + "parameter_type": { + "boolean": "Πιθανότητα", + "json": "JSON", + "number": "Αριθμός", + "string": "Συμβολοσειρά" + }, + "pinned": "Κατακερματισμένο", + "rerank_model": "Μοντέλο αναδιάταξης", + "rerank_model_support_provider": "Σημειώστε ότι το μοντέλο αναδιάταξης υποστηρίζεται από μερικούς παρόχους ({{provider}})", + "rerank_model_tooltip": "Κάντε κλικ στο κουμπί Διαχείριση στο παράθυρο Ρυθμίσεις -> Υπηρεσία Μοντέλων", + "search": "Αναζήτηση μοντέλου...", + "stream_output": "Διαρκής Εξόδος", + "type": { + "embedding": "ενσωμάτωση", + "function_calling": "κλήση συνάρτησης", + "reasoning": "λογική", + "select": "Επιλέξτε τύπο μοντέλου", + "text": "κείμενο", + "vision": "εικόνα", + "free": "δωρεάν", + "rerank": "Τακτοποιώ", + "websearch": "δικτύωση" + } + }, + "navbar": { + "expand": "Επισκευή διαλόγου", + "hide_sidebar": "Απόκρυψη πλάγιας μπάρας", + "show_sidebar": "Εμφάνιση πλάγιας μπάρας" + }, + "ollama": { + "keep_alive_time.description": "Χρόνος που ο μοντέλος διατηρείται στη μνήμη μετά τη συζήτηση (προεπιλογή: 5 λεπτά)", + "keep_alive_time.placeholder": "λεπτά", + "keep_alive_time.title": "Χρόνος διατήρησης ενεργοποίησης", + "title": "Ollama" + }, + "paintings": { + "button.delete.image": "Διαγραφή εικόνας", + "button.delete.image.confirm": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτή την εικόνα;", + "button.new.image": "Νέα εικόνα", + "guidance_scale": "Κλίμακα προσαρμογής", + "guidance_scale_tip": "Χωρίς κλάσικο προσαρμογής. Ελέγχει την προσαρμογή του μοντέλου στην αναζήτηση παρόμοιων εικόνων για το σχόλιο.", + "image.size": "Μέγεθος εικόνας", + "inference_steps": "Βήματα επεξεργασίας", + "inference_steps_tip": "Το πλήθος των βημάτων επεξεργασίας που πρέπει να εκτελεστούν. Περισσότερα βήματα = χαμηλότερη ποιότητα και μεγαλύτερος χρόνος εκτέλεσης", + "negative_prompt": "Αντίστροφη προσδοκία", + "negative_prompt_tip": "Περιγράψτε τα πράγματα που δεν θέλετε να εμφανίζονται στην εικόνα", + "number_images": "Ποσότητα δημιουργιών", + "number_images_tip": "Ποσότητα εικόνων που θα δημιουργηθούν μια φορά (1-4)", + "prompt_enhancement": "Βελτιστοποίηση σχόλιου", + "prompt_enhancement_tip": "Όταν ενεργοποιηθεί, η προσδοκία προσαρμόζεται για να γίνει περισσότερο λεπτομερής και συμβατή με το μοντέλο", + "prompt_placeholder": "Περιγράψτε την εικόνα που θέλετε να δημιουργήσετε, για παράδειγμα: ένα ηρωϊκό λιμάνι, το δείπνο του θεού, με απέναντι την ορεινή περιοχή", + "regenerate.confirm": "Αυτό θα επιβάλει τις δημιουργίες που έχετε κάνει, θέλετε να συνεχίσετε;", + "seed": "Τυχαίος παράγοντας", + "seed_tip": "Η χρήση του ίδιου παραγόντα και του σχολίου μπορεί να δημιουργήσει παρόμοιες εικόνες", + "title": "Εικόνα" + }, + "plantuml": { + "download": { + "failed": "Η κατέβαση απέτυχε, παρακαλούμε ελέγξτε το δίκτυο", + "png": "Κατέβασμα PNG", + "svg": "Κατέβασμα SVG" + }, + "tabs": { + "preview": "προεπισκόπηση", + "source": "πηγαίος κώδικας" + }, + "title": "Σχέδιο PlantUML" + }, + "prompts": { + "explanation": "Με βοηθήστε να εξηγήσετε αυτό το όρισμα", + "summarize": "Με βοηθήστε να συνοψίσετε αυτό το κείμενο", + "title": "Είστε ένας ειδικευμένος βοηθός συζητήσεων, πρέπει να συνοψίζετε τη συζήτηση του χρήστη σε έναν τίτλο με μεχρι 10 λέξεις, η γλώσσα του τίτλου να είναι ίδια με την πρώτη γλώσσα του χρήστη, δεν χρησιμοποιείστε πόσοι ή άλλα ειδικά σύμβολα" + }, + "provider": { + "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", + "anthropic": "Anthropic", + "azure-openai": "Azure OpenAI", + "baichuan": "Παράκειμαι", + "baidu-cloud": "Baidu Cloud Qianfan", + "copilot": "GitHub Copilot", + "dashscope": "AliCloud Bailian", + "deepseek": "Βαθιά Αναζήτηση", + "dmxapi": "DMXAPI", + "doubao": "Huoshan Engine", + "fireworks": "Fireworks", + "gemini": "Gemini", + "gitee-ai": "Gitee AI", + "github": "GitHub Models", + "gpustack": "GPUStack", + "graphrag-kylin-mountain": "GraphRAG", + "grok": "Grok", + "groq": "Groq", + "hunyuan": "Tencent Hunyuan", + "hyperbolic": "Υπερβολικός", + "infini": "Χωρίς Ερώτημα Xin Qiong", + "jina": "Jina", + "lmstudio": "LM Studio", + "minimax": "MiniMax", + "mistral": "Mistral", + "modelscope": "ModelScope Magpie", + "moonshot": "Σκοτεινή Κορωνίδα της Σελήνης", + "nvidia": "NVIDIA", + "o3": "O3", + "ocoolai": "ocoolAI", + "ollama": "Ollama", + "openai": "OpenAI", + "openrouter": "OpenRouter", + "perplexity": "Perplexity", + "ppio": "PPIO Piao Yun", + "qwenlm": "QwenLM", + "silicon": "Σιδηρική Παρουσία", + "stepfun": "Βήμα Ουράς", + "tencent-cloud-ti": "Tencent Cloud TI", + "together": "Together", + "xirang": "China Telecom Xiran", + "yi": "Zero One Wanyiwu", + "zhinao": "360 Intelligent Brain", + "zhipu": "Zhipu AI" + }, + "restore": { + "confirm": "Είστε σίγουροι ότι θέλετε να επαναφέρετε τα δεδομένα;", + "confirm.button": "Επιλογή αρχείου εφαρμογής", + "content": "Η επαναφορά θα χρησιμοποιήσει τα αντίγραφα ασφαλείας για να επικαλύψει όλα τα σημερινά δεδομένα εφαρμογής. Παρακαλούμε σημειώστε ότι η διαδικασία μπορεί να χρειαστεί λίγο καιρό, ευχαριστούμε για την υπομονή.", + "progress": { + "completed": "Η αποκατάσταση ολοκληρώθηκε", + "copying_files": "Αντιγραφή αρχείων... {{progress}}%", + "extracting": "Εξtraction της αντιγραφής...", + "preparing": "Ήταν προετοιμασία για την αποκατάσταση...", + "reading_data": "Ανάγνωση δεδομένων...", + "title": "Πρόοδος αποκατάστασης" + }, + "title": "Επαναφορά Δεδομένων" + }, + "settings": { + "about": "Περί μας", + "about.checkingUpdate": "Ελέγχω ενημερώσεις...", + "about.checkUpdate": "Έλεγχος ενημερώσεων", + "about.checkUpdate.available": "Άμεση ενημέρωση", + "about.contact.button": "Ταχυδρομείο", + "about.contact.title": "Επικοινωνία μέσω ταχυδρομείου", + "about.description": "Ένα AI ασιστάντα που έχει σχεδιαστεί για δημιουργούς", + "about.downloading": "Λήψη ενημερώσεων...", + "about.feedback.button": "Σχόλια και Παρατηρήσεις", + "about.feedback.title": "Αποστολή σχολίων", + "about.license.button": "Προβολή", + "about.license.title": "Licenses", + "about.releases.button": "Προβολή", + "about.releases.title": "Ημερολόγιο Ενημερώσεων", + "about.social.title": "Κοινωνικά Λογαριασμοί", + "about.title": "Περί μας", + "about.updateAvailable": "Νέα έκδοση {{version}} εντοπίστηκε", + "about.updateError": "Σφάλμα κατά την ενημέρωση", + "about.updateNotAvailable": "Το λογισμικό σας είναι ήδη στην πιο πρόσφατη έκδοση", + "about.website.button": "Προβολή", + "about.website.title": "Ιστοσελίδα", + "advanced.auto_switch_to_topics": "Αυτόματη μετάβαση σε θέματα", + "advanced.title": "Ρυθμίσεις Ανώτερου Νiveau", + "assistant": "Πρόεδρος Υπηρεσίας", + "assistant.model_params": "Παράμετροι Μοντέλου", + "assistant.show.icon": "Εμφάνιση εικονιδίου μοντέλου", + "assistant.title": "Πρόεδρος Υπηρεσίας", + "data": { + "app_data": "Δεδομένα εφαρμογής", + "app_knowledge": "Αρχεία βάσης γνώσεων", + "app_knowledge.button.delete": "Διαγραφή αρχείου", + "app_knowledge.remove_all": "Διαγραφή αρχείων βάσης γνώσεων", + "app_knowledge.remove_all_confirm": "Η διαγραφή των αρχείων της βάσης γνώσεων μπορεί να μειώσει τη χρήση χώρου αποθήκευσης, αλλά δεν θα διαγράψει τα διανυσματωτικά δεδομένα της βάσης γνώσεων. Μετά τη διαγραφή, δεν θα μπορείτε να ανοίξετε τα αρχεία πηγή. Θέλετε να διαγράψετε;", + "app_knowledge.remove_all_success": "Τα αρχεία διαγράφηκαν με επιτυχία", + "app_logs": "Φάκελοι εφαρμογής", + "clear_cache": { + "button": "Καθαρισμός Μνήμης", + "confirm": "Η διαγραφή της μνήμης θα διαγράψει τα στοιχεία καθαρισμού της εφαρμογής, συμπεριλαμβανομένων των στοιχείων πρόσθετων εφαρμογών. Αυτή η ενέργεια δεν είναι αναστρέψιμη. Θέλετε να συνεχίσετε;", + "error": "Αποτυχία καθαρισμού της μνήμης", + "success": "Η μνήμη καθαρίστηκε με επιτυχία", + "title": "Καθαρισμός Μνήμης" + }, + "data.title": "Φάκελος δεδομένων", + "hour_interval_one": "{{count}} ώρα", + "hour_interval_other": "{{count}} ώρες", + "joplin": { + "check": { + "button": "Έλεγχος", + "empty_token": "Παρακαλούμε εισάγετε τον κωδικό προσβασιμότητας του Joplin", + "empty_url": "Παρακαλούμε εισάγετε την URL που είναι συνδεδεμένη με την υπηρεσία κοπής του Joplin", + "fail": "Η επαλήθευση σύνδεσης του Joplin απέτυχε", + "success": "Η επαλήθευση σύνδεσης του Joplin ήταν επιτυχής" + }, + "help": "Σ τις επιλογές του Joplin, ενεργοποιήστε την υπηρεσία περικοπής ιστότοπων (χωρίς εγκατάσταση πρόσθετων στο περιηγητή), επιβεβαιώστε τον θύραρι και αντιγράψτε τον κωδικό πρόσβασης.", + "title": "Ρύθμιση Joplin", + "token": "Κωδικός πρόσβασης Joplin", + "token_placeholder": "Εισαγάγετε τον κωδικό πρόσβασης Joplin", + "url": "URL υπηρεσίας περικοπής Joplin", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "Κάνοντας το ενεργό, κατά την εξαγωγή Markdown, θα χρησιμοποιείται αναγκαστικά το $$ για να σημειώσετε την εξίσωση LaTeX. Νομίζετε: Αυτή η επιλογή θα επηρεάσει και όλες τις μεθόδους εξαγωγής μέσω Markdown, όπως το Notion, Yuyu κλπ.", + "markdown_export.force_dollar_math.title": "Ανάγκη χρήσης $$ για να σημειώσετε την εξίσωση LaTeX", + "markdown_export.help": "Εάν συμπληρώσετε, κάθε φορά που θα εξαγάγετε θα αποθηκεύεται αυτόματα σε αυτή τη διαδρομή· διαφορετικά, θα εμφανιστεί μια διαβεβαίωση αποθήκευσης.", + "markdown_export.path": "Προεπιλογή διαδρομής εξαγωγής", + "markdown_export.path_placeholder": "Διαδρομή εξαγωγής", + "markdown_export.select": "Επιλογή", + "markdown_export.title": "Εξαγωγή Markdown", + "minute_interval_one": "{{count}} λεπτά", + "minute_interval_other": "{{count}} λεπτά", + "notion.api_key": "Κλειδί Notion", + "notion.api_key_placeholder": "Εισαγάγετε το κλειδί Notion", + "notion.auto_split": "Αυτόματη εκχώρηση σε σελίδες κατά την εξαγωγή συζητήσεων", + "notion.auto_split_tip": "Όταν η συζήτηση που θα εξαγάγετε είναι πολύ μεγάλη, θα εκχωρείται αυτόματα σε περισσότερες σελίδες στο Notion", + "notion.check": { + "button": "Έλεγχος", + "empty_api_key": "Δεν έχει ρυθμιστεί η κλειδιά API", + "empty_database_id": "Δεν έχει ρυθμιστεί ο ID της βάσης δεδομένων", + "error": "Σφάλμα σύνδεσης, παρακαλείστε ελέγξτε το δίκτυο και αν το API key και το Database ID είναι σωστά", + "fail": "Η σύνδεση απέτυχε, παρακαλείστε ελέγξτε το δίκτυο και αν το API key και το Database ID είναι σωστά", + "success": "Η σύνδεση ήταν επιτυχής" + }, + "notion.database_id": "ID Βάσης Δεδομένων Notion", + "notion.database_id_placeholder": "Εισαγάγετε το ID Βάσης Δεδομένων Notion", + "notion.help": "Έγχρωστη διαδρομή του Notion", + "notion.page_name_key": "Όνομα πεδίου τίτλου σελίδας", + "notion.page_name_key_placeholder": "Εισαγάγετε το όνομα του πεδίου τίτλου σελίδας, προεπιλογή: Name", + "notion.split_size": "Μέγεθος αυτόματης διαχωριστικής σελίδας", + "notion.split_size_help": "Οι χρήστες της δωρεάν έκδοσης του Notion προτείνεται να ορίσουν 90, οι υψηλότερες έκδοσεις προτείνονται να ορίσουν 24990, το προεπιλεγμένο είναι 90", + "notion.split_size_placeholder": "Εισαγάγετε τον περιορισμό μπλοκ κάθε σελίδας (προεπιλογή: 90)", + "notion.title": "Ρυθμίσεις του Notion", + "obsidian": { + "folder": "Φάκελος", + "folder_placeholder": "Παρακαλώ εισάγετε όνομα φακέλου", + "tags": "Παγκόσμιοι ετικέτες", + "tags_placeholder": "Παρακαλώ εισάγετε ονόματα ετικετών, χωριστά με κόμματα, οι ετικέτες στο Obsidian δεν μπορούν να είναι μόνο αριθμοί", + "title": "Ρύθμιση του Obsidian", + "vault": "Αποθήκη", + "vault_placeholder": "Παρακαλώ εισάγετε όνομα αποθήκης" + }, + "title": "Ρυθμίσεις δεδομένων", + "webdav": { + "autoSync": "Αυτόματη αντιγραφή ασφαλείας", + "autoSync.off": "Επιστροφή στο κλειδωμένο κατάσταμμα", + "backup.button": "Αντιγραφή ασφαλείας στο WebDAV", + "backup.modal.filename.placeholder": "Εισαγάγετε το όνομα του αρχείου αντιγράφου ασφαλείας", + "backup.modal.title": "Αντιγραφή ασφαλείας στο WebDAV", + "host": "Διεύθυνση WebDAV", + "host.placeholder": "http://localhost:8080", + "hour_interval_one": "{{count}} ώρα", + "hour_interval_other": "{{count}} ώρες", + "lastSync": "Η τελευταία αντιγραφή ασφαλείας", + "minute_interval_one": "{{count}} λεπτό", + "minute_interval_other": "{{count}} λεπτά", + "noSync": "Εκκρεμεί η επόμενη αντιγραφή ασφαλείας", + "password": "Κωδικός πρόσβασης WebDAV", + "path": "Διαδρομή WebDAV", + "path.placeholder": "/backup", + "restore.button": "Αποκατάσταση από το WebDAV", + "restore.confirm.content": "Η αποκατάσταση από το WebDAV θα επιβάλλει τα σημερινά δεδομένα. Θέλετε να συνεχίσετε;", + "restore.confirm.title": "Υποβεβαίωση αποκατάστασης", + "restore.content": "Η αποκατάσταση από το WebDAV θα επιβάλλει τα σημερινά δεδομένα. Θέλετε να συνεχίσετε;", + "restore.modal.select.placeholder": "Επιλέξτε το αρχείο αντιγράφου ασφαλείας για αποκατάσταση", + "restore.modal.title": "Αποκατάσταση από το WebDAV", + "restore.title": "Αποκατάσταση από το WebDAV", + "syncError": "Σφάλμα στην αντιγραφή ασφαλείας", + "syncStatus": "Κατάσταση αντιγραφής ασφαλείας", + "title": "WebDAV", + "user": "Όνομα χρήστη WebDAV" + }, + "yuque": { + "check": { + "button": "Έλεγχος", + "empty_repo_url": "Παρακαλώ εισάγετε το URL του βιβλιοθηκέυματος πρώτα", + "empty_token": "Παρακαλώ εισάγετε τον κλειδί του Yuluxian πρώτα", + "fail": "Απέτυχε η επαλήθευση σύνδεσης με το Yuluxian", + "success": "Η επαλήθευση σύνδεσης με το Yuluxian ήταν επιτυχής" + }, + "help": "Λήψη Token του Yusi", + "repo_url": "Διεύθυνση URL του βιβλιοθικίου", + "repo_url_placeholder": "https://www.yuque.com/username/xxx", + "title": "Ρύθμιση Yusi", + "token": "Token του Yusi", + "token_placeholder": "Παρακαλούμε εισάγετε το Token του Yusi" + } + }, + "display.assistant.title": "Ρυθμίσεις Υπηρεσίας", + "display.custom.css": "Προσαρμοστική CSS", + "display.custom.css.cherrycss": "Λήψη από cherrycss.com", + "display.custom.css.placeholder": "/* Γράψτε εδώ την προσαρμοστική CSS */", + "display.minApp.disabled": "Αποκρυμμένα μικροπρογράμματα", + "display.minApp.empty": "Βάλτε εδώ τα μικροπρογράμματα που θέλετε να κρύψετε από την αριστερά", + "display.minApp.title": "Ρυθμίσεις εμφάνισης μικροπρογραμμάτων", + "display.minApp.visible": "Εμφανιζόμενα μικροπρογράμματα", + "display.sidebar.chat.hiddenMessage": "Η υπηρεσία είναι βασική λειτουργία και δεν υποστηρίζεται η κρυμμένη εμφάνιση", + "display.sidebar.disabled": "Αποκρυμμένα εικονίδια", + "display.sidebar.empty": "Βάλτε εδώ τις λειτουργίες που θέλετε να κρύψετε από την αριστερά", + "display.sidebar.files.icon": "Εμφάνιση εικονιδίου αρχείων", + "display.sidebar.knowledge.icon": "Εμφάνιση εικονιδίου γνώσης", + "display.sidebar.minapp.icon": "Εμφάνιση εικονιδίου μικροπρογραμμάτων", + "display.sidebar.painting.icon": "Εμφάνιση εικονιδίου ζωγραφικής", + "display.sidebar.title": "Ρυθμίσεις πλευρικού μενού", + "display.sidebar.translate.icon": "Εμφάνιση εικονιδίου μετάφρασης", + "display.sidebar.visible": "Εμφανιζόμενα εικονίδια", + "display.title": "Ρυθμίσεις εμφάνισης", + "display.topic.title": "Ρυθμίσεις Θεμάτων", + "font_size.title": "Μέγεθος γραμμάτων των μηνυμάτων", + "general": "Γενικές ρυθμίσεις", + "general.avatar.reset": "Επαναφορά εικονιδίου", + "general.backup.button": "Αντιγραφή ασφαλείας", + "general.backup.title": "Αντιγραφή ασφαλείας και αποκατάσταση δεδομένων", + "general.display.title": "Ρυθμίσεις εμφάνισης", + "general.emoji_picker": "Επιλογή σμιλιών", + "general.image_upload": "Φόρτωση εικόνων", + "general.manually_check_update.title": "Απενεργοποίηση ελέγχου ενημερώσεων", + "general.reset.button": "Επαναφορά", + "general.reset.title": "Επαναφορά δεδομένων", + "general.restore.button": "Αποκατάσταση", + "general.title": "Γενικές ρυθμίσεις", + "general.user_name": "Όνομα χρήστη", + "general.user_name.placeholder": "Εισαγάγετε όνομα χρήστη", + "general.view_webdav_settings": "Προβολή ρυθμίσεων WebDAV", + "input.auto_translate_with_space": "Μετάφραση με τρεις γρήγορες πιστώσεις", + "input.target_language": "Γλώσσα προορισμού", + "input.target_language.chinese": "Σινογραμματικό", + "input.target_language.chinese-traditional": "Επιτυχημένο Σινογραμματικό", + "input.target_language.english": "Αγγλικά", + "input.target_language.japanese": "Ιαπωνικά", + "input.target_language.russian": "Ρωσικά", + "launch.onboot": "Αυτόματη εκκίνηση κατά την εκκίνηση του συστήματος", + "launch.title": "Εκκίνηση", + "launch.totray": "Εισαγωγή στην συνδρομή κατά την εκκίνηση", + "mcp": { + "actions": "Ενέργειες", + "active": "Ενεργοποίηση", + "addError": "Αποτυχία προσθήκης διακομιστή", + "addServer": "Προσθήκη διακομιστή", + "addSuccess": "Ο διακομιστής προστέθηκε επιτυχώς", + "args": "Παράμετροι", + "argsTooltip": "Κάθε παράμετρος σε μια γραμμή", + "baseUrlTooltip": "Σύνδεσμος Απομακρυσμένης διεύθυνσης URL", + "command": "Εντολή", + "commandRequired": "Παρακαλώ εισάγετε την εντολή", + "config_description": "Ρυθμίζει το πλαίσιο συντονισμού πρωτοκόλλων διακομιστή", + "confirmDelete": "Διαγραφή διακομιστή", + "confirmDeleteMessage": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτόν τον διακομιστή;", + "deleteError": "Αποτυχία διαγραφής διακομιστή", + "deleteSuccess": "Ο διακομιστής διαγράφηκε επιτυχώς", + "dependenciesInstall": "Εγκατάσταση εξαρτήσεων", + "dependenciesInstalling": "Βράζουν οι εξαρτήσεις...", + "description": "Περιγραφή", + "duplicateName": "Υπάρχει ήδη ένας διακομιστής με αυτό το όνομα", + "editJson": "Επεξεργασία JSON", + "editServer": "Επεξεργασία διακομιστή", + "env": "Περιβαλλοντικές μεταβλητές", + "envTooltip": "Μορφή: KEY=value, κάθε μια σε μια γραμμή", + "findMore": "Περισσότεροι διακομιστές MCP", + "install": "Εγκατάσταση", + "installError": "Αποτυχία εγκατάστασης εξαρτήσεων", + "installSuccess": "Η εγκατάσταση των εξαρτήσεων ολοκληρώθηκε επιτυχώς", + "jsonFormatError": "Σφάλμα στη μορφοποίηση JSON", + "jsonModeHint": "Επεξεργασία της εκφώνησης JSON του διακομιστή MCP. Παρακαλώ εξασφαλίστε ότι το μορφοποίηση είναι σωστό πριν από την αποθήκευση.", + "jsonSaveError": "Αποτυχία αποθήκευσης της διαμορφωτικής ρύθμισης JSON", + "jsonSaveSuccess": "Η διαμορφωτική ρύθμιση JSON αποθηκεύτηκε επιτυχώς", + "missingDependencies": "Απο缺失, παρακαλώ εγκαταστήστε το για να συνεχίσετε", + "name": "Όνομα", + "nameRequired": "Παρακαλώ εισάγετε το όνομα του διακομιστή", + "noServers": "Δεν έχουν ρυθμιστεί διακομιστές", + "npx_list": { + "actions": "Ενέργειες", + "desc": "Αναζητήστε και προσθέστε πακέτα npm ως υπηρεσίες MCP", + "description": "Περιγραφή", + "no_packages": "Δεν βρέθηκαν πακέτα", + "npm": "NPM", + "package_name": "Όνομα πακέτου", + "scope_placeholder": "Εισαγάγετε το σκοπό του npm (π.χ. @your-org)", + "scope_required": "Παρακαλώ εισαγάγετε το σκοπό του npm", + "search": "Αναζήτηση", + "search_error": "Η αναζήτηση απέτυχε", + "title": "Λίστα πακέτων NPX", + "usage": "Χρήση", + "version": "Έκδοση" + }, + "serverPlural": "Διακομιστές", + "serverSingular": "Διακομιστής", + "title": "Διακομιστές MCP", + "toggleError": "Αποτυχία εναλλαγής", + "type": "Τύπος", + "updateError": "Αποτυχία ενημέρωσης διακομιστή", + "updateSuccess": "Ο διακομιστής ενημερώθηκε επιτυχώς", + "url": "URL" + }, + "messages.divider": "Διαχωριστική γραμμή μηνυμάτων", + "messages.grid_columns": "Αριθμός στήλων γριλ μηνυμάτων", + "messages.grid_popover_trigger": "Καταγραφή στοιχείων στο grid", + "messages.grid_popover_trigger.click": "Εμφάνιση κλικ", + "messages.grid_popover_trigger.hover": "Εμφάνιση επιστροφής", + "messages.input.paste_long_text_as_file": "Επικόλληση μεγάλου κειμένου ως αρχείο", + "messages.input.paste_long_text_threshold": "Όριο μεγάλου κειμένου", + "messages.input.send_shortcuts": "Συντάγματα αποστολής", + "messages.input.show_estimated_tokens": "Εμφάνιση εκτιμώμενου αριθμού token", + "messages.input.title": "Ρυθμίσεις εισαγωγής", + "messages.markdown_rendering_input_message": "Markdown Rendering Input Message", + "messages.math_engine": "Μηχανική μαθηματικών εξισώσεων", + "messages.metrics": "Χρόνος πρώτου χαρακτήρα {{time_first_token_millsec}}ms | {{token_speed}} tokens ανά δευτερόλεπτο", + "messages.model.title": "Ρυθμίσεις μοντέλου", + "messages.navigation": "Κουμπιά πλοήγησης συζητήσεων", + "messages.navigation.anchor": "Ancre συζητήσεων", + "messages.navigation.buttons": "Πάνω και κάτω κουμπιά", + "messages.navigation.none": "Χωρίς εμφάνιση", + "messages.title": "Ρυθμίσεις μηνυμάτων", + "messages.use_serif_font": "Χρήση μορφής Serif", + "model": "Πρόεδρος Υπηρεσίας", + "models.add.add_model": "Προσθήκη μοντέλου", + "models.add.group_name": "Όνομα ομάδας", + "models.add.group_name.placeholder": "Για παράδειγμα ChatGPT", + "models.add.group_name.tooltip": "Για παράδειγμα ChatGPT", + "models.add.model_id": "ID μοντέλου", + "models.add.model_id.placeholder": "Απαραίτητο για παράδειγμα gpt-3.5-turbo", + "models.add.model_id.tooltip": "Για παράδειγμα gpt-3.5-turbo", + "models.add.model_name": "Όνομα μοντέλου", + "models.add.model_name.placeholder": "Για παράδειγμα GPT-3.5", + "models.check.all": "Όλα", + "models.check.all_models_passed": "Όλα τα μοντέλα περάσαν ενεργειακά", + "models.check.button_caption": "Ελεγχος υγείας", + "models.check.disabled": "Απενεργοποίηση", + "models.check.enable_concurrent": "Επιτρέπει τη συγχρονη ελεγχος", + "models.check.enabled": "Ενεργοποίηση", + "models.check.failed": "Αποτυχία", + "models.check.keys_status_count": "Επιτυχημένοι: {{count_passed}} κλειδιά, αποτυχημένοι: {{count_failed}} κλειδιά", + "models.check.model_status_summary": "{{provider}}: {{count_passed}} μοντέλα ελέγχθηκαν επιτυχώς (από τα οποία {{count_partial}} μοντέλα δεν είναι προσβάσιμα με ορισμένα κλειδιά), {{count_failed}} μοντέλα είναι εντελώς απρόσβαστα.", + "models.check.no_api_keys": "Δεν βρέθηκαν API κλειδιά. Παρακαλούμε πρώτα προσθέστε κλειδιά API.", + "models.check.passed": "Επιτυχία", + "models.check.select_api_key": "Επιλέξτε το API key που θέλετε να χρησιμοποιήσετε:", + "models.check.single": "Μόνο", + "models.check.start": "Έναρξη", + "models.check.title": "Ελεγχος υγείας μοντέλου", + "models.check.use_all_keys": "Χρήση όλων των κλειδιών", + "models.default_assistant_model": "Πρόεδρος Υπηρεσίας προεπιλεγμένου μοντέλου", + "models.default_assistant_model_description": "Το μοντέλο που χρησιμοποιείται όταν δημιουργείτε νέο υπάλληλο. Αν το υπάλληλο δεν έχει επιλεγμένο ένα μοντέλο, τότε θα χρησιμοποιεί αυτό το μοντέλο.", + "models.empty": "Δεν υπάρχουν μοντέλα", + "models.enable_topic_naming": "Αυτόματη αναδόμηση θεμάτων", + "models.manage.add_whole_group": "Προσθήκη ολόκληρης ομάδας", + "models.manage.remove_whole_group": "Αφαίρεση ολόκληρης ομάδας", + "models.topic_naming_model": "Μοντέλο αναδόμησης θεμάτων", + "models.topic_naming_model_description": "Το μοντέλο που χρησιμοποιείται όταν αυτόματα ονομάζεται ένα νέο θέμα", + "models.topic_naming_model_setting_title": "Ρυθμίσεις Μοντέλου Αναδόμησης Θεμάτων", + "models.topic_naming_prompt": "Προσδιορισμός προκαθορισμένου θέματος", + "models.translate_model": "Μοντέλο μετάφρασης", + "models.translate_model_description": "Το μοντέλο που χρησιμοποιείται για τη μετάφραση", + "models.translate_model_prompt_message": "Εισάγετε την προσδιορισμένη προειδοποίηση μετάφρασης", + "models.translate_model_prompt_title": "Προσδιορισμός προκαθορισμένου θέματος μετάφρασης", + "moresetting": "Περισσότερες ρυθμίσεις", + "moresetting.check.confirm": "Επιβεβαίωση επιλογής", + "moresetting.check.warn": "Παρακαλούμε επιλέξτε με προσοχή αυτή την επιλογή, μια λάθος επιλογή μπορεί να εμποδίσει την σωστή λειτουργία του μοντέλου!!", + "moresetting.warn": "Χρησιμοποιείται κίνδυνος", + "provider": { + "add.name": "Όνομα παρόχου", + "add.name.placeholder": "π.χ. OpenAI", + "add.title": "Προσθήκη παρόχου", + "add.type": "Τύπος παρόχου", + "api.url.preview": "Προεπισκόπηση: {{url}}", + "api.url.reset": "Επαναφορά", + "api.url.tip": "/τέλος αγνόηση v1 έκδοσης, #τέλος ενδεχόμενη χρήση της εισαγωγής διευθύνσεως", + "api_host": "Διεύθυνση API", + "api_key": "Κλειδί API", + "api_key.tip": "Χωριστά με κόμμα περισσότερα κλειδιά API", + "api_version": "Έκδοση API", + "charge": "Κατέβασμα", + "check": "Έλεγχος", + "check_all_keys": "Έλεγχος όλων των κλειδιών", + "check_multiple_keys": "Έλεγχος πολλαπλών κλειδιών API", + "copilot": { + "auth_failed": "Η επιβεβαίωση του Github Copilot απέτυχε", + "auth_success": "Η επιβεβαίωση του Github Copilot ήταν επιτυχής", + "auth_success_title": "Η επιβεβαίωση ήταν επιτυχής", + "code_failed": "Η λήψη του Device Code απέτυχε, παρακαλώ δοκιμάστε ξανά", + "code_generated_desc": "Παρακαλώ αντιγράψτε το Device Code στον παρακάτω σύνδεσμο περιηγητή", + "code_generated_title": "Λήψη Device Code", + "confirm_login": "Η υπερβολική χρήση μπορεί να οδηγήσει στην απενεργοποίηση του λογαριασμού σας στο Github, παρακαλώ χρησιμοποιήστε το με προσοχή!!!!", + "confirm_title": "Ειδοποίηση κινδύνου", + "connect": "Σύνδεση με το Github", + "custom_headers": "Προσαρμοσμένες κεφαλίδες αιτήματος", + "description": "Ο λογαριασμός σας στο Github χρειάζεται να εγγραφεί για να χρησιμοποιήσει το Copilot", + "expand": "Επεκτάση", + "headers_description": "Προσαρμοσμένες κεφαλίδες αιτήματος (σε JSON μορφή)", + "invalid_json": "Λάθος σύνταξη JSON", + "login": "Σύνδεση με το Github", + "logout": "Αποσύνδεση από το Github", + "logout_failed": "Η αποσύνδεση απέτυχε, παρακαλώ δοκιμάστε ξανά", + "logout_success": "Έγινε επιτυχής η αποσύνδεση", + "model_setting": "Ρυθμίσεις μοντέλου", + "open_verification_first": "Παρακαλώ κάντε κλικ στον παραπάνω σύνδεσμο για να επισκεφτείτε τη σελίδα επιβεβαίωσης", + "rate_limit": "Όριο ρυθμού", + "tooltip": "Για τη χρήση του Github Copilot πρέπει να συνδεθείτε στο Github" + }, + "delete.content": "Είστε σίγουροι ότι θέλετε να διαγράψετε αυτόν τον παροχό;", + "delete.title": "Διαγραφή παρόχου", + "docs_check": "Άνοιγμα", + "docs_more_details": "Λάβετε περισσότερες λεπτομέρειες", + "get_api_key": "Κάντε κλικ εδώ για να πάρετε κλειδί", + "is_not_support_array_content": "Ενεργοποίηση συμβατικού μοντέλου", + "no_models": "Πρέπει να προσθέσετε πρώτα πρόσωπο το πρόσωπο της μονάδας πριν ελέγξετε τη σύνδεση API", + "not_checked": "Δεν ελέγχεται", + "remove_duplicate_keys": "Αφαίρεση Επαναλαμβανόμενων Κλειδιών", + "remove_invalid_keys": "Διαγραφή Ακυρωμένων Κλειδιών", + "search": "Αναζήτηση πλατφόρμας μονάδων...", + "search_placeholder": "Αναζήτηση ID ή ονόματος μονάδας", + "title": "Υπηρεσία μονάδων" + }, + "proxy": { + "mode": { + "custom": "προσαρμοσμένη προξενική", + "none": "χωρίς πρόξενο", + "system": "συστηματική προξενική", + "title": "κλίμακα προξενικής" + }, + "title": "Ρυθμίσεις προξενείου" + }, + "proxy.title": "Διευθύνσεις προξενιακού", + "quickAssistant": { + "click_tray_to_show": "Επιλέξτε την εικόνα στο πίνακα για να ενεργοποιήσετε", + "enable_quick_assistant": "Ενεργοποίηση γρήγορου βοηθού", + "read_clipboard_at_startup": "Αναγνωρίζει το πρόχειρο κατά την εκκίνηση", + "title": "Γρήγορος βοηθός", + "use_shortcut_to_show": "Κάντε δεξικό κλικ στην εικόνα του πίνακα ή χρησιμοποιήστε την συντομεύση για να ενεργοποιήσετε" + }, + "shortcuts": { + "action": "Ενέργεια", + "clear_shortcut": "Καθαρισμός συντομού πλήκτρου", + "clear_topic": "Άδειασμα μηνυμάτων", + "copy_last_message": "Αντιγραφή του τελευταίου μηνύματος", + "key": "Πλήκτρο", + "mini_window": "Συντομεύστε επιχειρηματικά", + "new_topic": "Νέο θέμα", + "press_shortcut": "Πάτησε το συντομού πλήκτρου", + "reset_defaults": "Επαναφορά στα προεπιλεγμένα συντομού πλήκτρα", + "reset_defaults_confirm": "Θέλετε να επαναφέρετε όλα τα συντομού πλήκτρα στις προεπιλεγμένες τιμές;", + "reset_to_default": "Επαναφορά στις προεπιλεγμένες", + "search_message": "Αναζήτηση μηνυμάτων", + "show_app": "Εμφάνιση εφαρμογής", + "show_settings": "Άνοιγμα των ρυθμίσεων", + "title": "Συντομοί δρομολόγια", + "toggle_new_context": "Άδειασμα σενάριων", + "toggle_show_assistants": "Εναλλαγή εμφάνισης βοηθών", + "toggle_show_topics": "Εναλλαγή εμφάνισης θεμάτων", + "zoom_in": "Μεγέθυνση εμφάνισης", + "zoom_out": "Σμικρύνση εμφάνισης", + "zoom_reset": "Επαναφορά εμφάνισης" + }, + "theme.auto": "Αυτόματο", + "theme.dark": "Σκοτεινό", + "theme.light": "Φωτεινό", + "theme.title": "Θέμα", + "theme.window.style.opaque": "Μη διαφανή παράθυρα", + "theme.window.style.title": "Στυλ παραθύρων", + "theme.window.style.transparent": "Διαφανή παράθυρα", + "title": "Ρυθμίσεις", + "topic.position": "Θέση θεμάτων", + "topic.position.left": "Αριστερά", + "topic.position.right": "Δεξιά", + "topic.show.time": "Εμφάνιση ώρας θέματος", + "tray.onclose": "Μειωμένο στη συνδρομή κατά την κλεισιά", + "tray.show": "Εμφάνιση εικονιδίου συνδρομής", + "tray.title": "Συνδρομή", + "websearch": { + "blacklist": "Μαύρη Λίστα", + "blacklist_description": "Τα αποτελέσματα των παρακάτω ιστοσελίδων δεν θα εμφανιστούν στα αποτελέσματα αναζήτησης", + "blacklist_tooltip": "Παρακαλούμε χρησιμοποιήστε το ακόλουθο μορφάτο (*):\\nexample.com\\nhttps://www.example.com\\nhttps://example.com\\n*://*.example.com", + "check": "Έλεγχος", + "check_failed": "Αποτυχία του έλεγχου", + "check_success": "Έλεγχος επιτυχής", + "enhance_mode": "Ρύθμιση βελτιστοποίησης αναζήτησης", + "enhance_mode_tooltip": "Αναζητήστε με βάση τις λέξεις-κλειδιά που αντικαταστάθηκαν από το πρότυπο μοντέλο", + "get_api_key": "Κάντε κλικ εδώ για να λάβετε το κλειδί", + "no_provider_selected": "Παρακαλούμε επιλέξτε παρόχο αναζήτησης πριν να ελέγξετε", + "search_max_result": "Αριθμός αποτελεσμάτων αναζήτησης", + "search_provider": "Παρόχος αναζήτησης", + "search_provider_placeholder": "Επιλέξτε έναν παρόχο αναζήτησης", + "search_result_default": "Πρόσφατες αναζητήσεις", + "search_with_time": "Αναζήτηση με ημερομηνία", + "tavily": { + "api_key": "Κλειδί API Tavily", + "api_key.placeholder": "Παρακαλούμε εισάγετε το Κλειδί API Tavily", + "description": "Το Tavily είναι ένα αναζητητής που διαμορφώνεται για AI-agents, παρέχοντας συνεχεία ακριβείς αποτελέσματα, νοηματικές προτάσεις αναζήτησης και βαθειά ικανότητες μελέτης", + "title": "Tavily" + }, + "title": "Διαδικτυακή αναζήτηση" + } + }, + "translate": { + "any.language": " οποιαδήποτε γλώσσα", + "button.translate": "Μετάφραση", + "close": "Κλείσιμο", + "confirm": { + "content": "Μετάφραση θα επικαλύψει το αρχικό κείμενο, συνεχίζει;", + "title": "Επιβεβαίωση μετάφρασης" + }, + "error.failed": "Η μετάφραση απέτυχε", + "error.not_configured": "Το μοντέλο μετάφρασης δεν είναι ρυθμισμένο", + "history": { + "clear": "Καθαρισμός ιστορικού", + "clear_description": "Η διαγραφή του ιστορικού θα διαγράψει όλα τα απομνημονεύματα μετάφρασης. Θέλετε να συνεχίσετε;", + "delete": "Διαγραφή", + "empty": "δεν υπάρχουν απομνημονεύματα μετάφρασης", + "title": "Ιστορικό μετάφρασης" + }, + "input.placeholder": "Εισαγάγετε κείμενο για μετάφραση", + "output.placeholder": "Μετάφραση", + "processing": "Μεταφράζεται...", + "scroll_sync.disable": "Απενεργοποίηση συγχρονισμού οριζόντιου μετακινήσεων", + "scroll_sync.enable": "Ενεργοποίηση συγχρονισμού οριζόντιου μετακινήσεων", + "title": "Μετάφραση", + "tooltip.newline": "Αλλαγή γραμμής" + }, + "tray": { + "quit": "Έξοδος", + "show_mini_window": "Σύντομη βοήθεια", + "show_window": "Εμφάνιση παραθύρου" + }, + "words": { + "knowledgeGraph": "γνώσεις Γράφου", + "quit": "Έξοδος", + "show_window": "Εμφάνιση Παραθύρου", + "visualization": "προβολή" + } + } +} diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json new file mode 100644 index 000000000..3d7eb4f38 --- /dev/null +++ b/src/renderer/src/i18n/translate/es-es.json @@ -0,0 +1,1173 @@ +{ + "translation": { + "agents": { + "add.button": "Agregar al asistente", + "add.knowledge_base": "Base de conocimiento", + "add.knowledge_base.placeholder": "Seleccionar base de conocimiento", + "add.name": "Nombre", + "add.name.placeholder": "Ingrese el nombre", + "add.prompt": "Palabra clave", + "add.prompt.placeholder": "Ingrese la palabra clave", + "add.title": "Crear agente inteligente", + "delete.popup.content": "¿Está seguro de que desea eliminar este agente inteligente?", + "edit.message.add.title": "Agregar", + "edit.message.assistant.placeholder": "Ingrese el mensaje del asistente", + "edit.message.assistant.title": "Asistente", + "edit.message.empty.content": "El contenido de la sesión de chat no puede estar vacío", + "edit.message.group.title": "Grupo de mensajes", + "edit.message.title": "Mensaje predeterminado", + "edit.message.user.placeholder": "Ingrese el mensaje del usuario", + "edit.message.user.title": "Usuario", + "edit.model.select.title": "Seleccionar modelo", + "edit.settings.hide_preset_messages": "Ocultar mensajes predeterminados", + "edit.title": "Editar agente inteligente", + "manage.title": "Administrar agentes inteligentes", + "my_agents": "Mis agentes inteligentes", + "search.no_results": "No se encontraron agentes relacionados", + "sorting.title": "Ordenar", + "tag.agent": "Agente", + "tag.default": "Predeterminado", + "tag.new": "Nuevo", + "tag.system": "Sistema", + "title": "Agente" + }, + "assistants": { + "abbr": "Asistente", + "clear.content": "Vaciar el tema eliminará todos los temas y archivos del asistente. ¿Está seguro de que desea continuar?", + "clear.title": "Vaciar Tema", + "copy.title": "Copiar Asistente", + "delete.content": "Eliminar el asistente borrará todos los temas y archivos asociados. ¿Está seguro de que desea continuar?", + "delete.title": "Eliminar Asistente", + "edit.title": "Editar Asistente", + "save.success": "Guardado exitosamente", + "save.title": "Guardar en Agente Inteligente", + "search": "Buscar Asistente", + "settings.default_model": "Modelo Predeterminado", + "settings.knowledge_base": "Configuración de Base de Conocimientos", + "settings.model": "Configuración de Modelo", + "settings.preset_messages": "Mensajes Preestablecidos", + "settings.prompt": "Configuración de Palabras Clave", + "settings.reasoning_effort": "Longitud de Cadena de Razonamiento", + "settings.reasoning_effort.high": "Largo", + "settings.reasoning_effort.low": "Corto", + "settings.reasoning_effort.medium": "Medio", + "settings.reasoning_effort.off": "Apagado", + "settings.reasoning_effort.tip": "Solo compatible con modelos de razonamiento OpenAI o-series y Anthropic", + "title": "Asistente" + }, + "auth": { + "error": "Falló la obtención automática de la clave, por favor obténla manualmente", + "get_key": "Obtener", + "get_key_success": "Obtención automática de la clave exitosa", + "login": "Iniciar sesión", + "oauth_button": "Iniciar sesión con {{provider}}" + }, + "backup": { + "confirm": "¿Está seguro de que desea realizar una copia de seguridad de los datos?", + "confirm.button": "Seleccionar ubicación de copia de seguridad", + "content": "Realizar una copia de seguridad de todos los datos, incluyendo registros de chat, configuraciones, bases de conocimiento y todos los demás datos. Tenga en cuenta que el proceso de copia de seguridad puede llevar algún tiempo, gracias por su paciencia.", + "progress": { + "completed": "Copia de seguridad completada", + "compressing": "Comprimiendo archivos...", + "copying_files": "Copiando archivos... {{progress}}%", + "preparing": "Preparando copia de seguridad...", + "title": "Progreso de la copia de seguridad", + "writing_data": "Escribiendo datos..." + }, + "title": "Copia de Seguridad de Datos" + }, + "button": { + "add": "Agregar", + "added": "Agregado", + "collapse": "Colapsar", + "manage": "Administrar", + "select_model": "Seleccionar Modelo", + "show.all": "Mostrar Todo", + "update_available": "Hay Actualizaciones Disponibles" + }, + "chat": { + "add.assistant.title": "Agregar asistente", + "artifacts.button.download": "Descargar", + "artifacts.button.openExternal": "Abrir en navegador externo", + "artifacts.button.preview": "Vista previa", + "artifacts.preview.openExternal.error.content": "Error al abrir en navegador externo", + "assistant.search.placeholder": "Buscar", + "deeply_thought": "Profundamente pensado (tomó {{secounds}} segundos)", + "default.description": "Hola, soy el asistente predeterminado. Puedes comenzar a conversar conmigo de inmediato.", + "default.name": "Asistente predeterminado", + "default.topic.name": "Tema predeterminado", + "input.auto_resize": "Ajuste automático de altura", + "input.clear": "Limpiar mensajes {{Command}}", + "input.clear.content": "¿Estás seguro de que quieres eliminar todos los mensajes de la sesión actual?", + "input.clear.title": "Limpiar mensajes", + "input.collapse": "Colapsar", + "input.context_count.tip": "Número de contextos / Número máximo de contextos", + "input.estimated_tokens.tip": "Número estimado de tokens", + "input.expand": "Expandir", + "input.file_not_supported": "El modelo no admite este tipo de archivo", + "input.knowledge_base": "Base de conocimientos", + "input.new.context": "Limpiar contexto {{Command}}", + "input.new_topic": "Nuevo tema {{Command}}", + "input.pause": "Pausar", + "input.placeholder": "Escribe aquí tu mensaje...", + "input.send": "Enviar", + "input.settings": "Configuración", + "input.topics": "Temas", + "input.translate": "Traducir a {{target_language}}", + "input.upload": "Subir imagen o documento", + "input.upload.document": "Subir documento (el modelo no admite imágenes)", + "input.web_search": "Habilitar búsqueda web", + "input.web_search.button.ok": "Ir a configuración", + "input.web_search.enable": "Habilitar búsqueda web", + "input.web_search.enable_content": "Primero verifica la conectividad de la búsqueda web en la configuración", + "message.new.branch": "Rama nueva", + "message.new.branch.created": "Nueva rama creada", + "message.new.context": "Limpiar contexto", + "message.quote": "Citar", + "message.regenerate.model": "Cambiar modelo", + "message.useful": "Útil", + "navigation": { + "first": "Ya es el primer mensaje", + "last": "Ya es el último mensaje", + "next": "Siguiente mensaje", + "prev": "Mensaje anterior" + }, + "resend": "Reenviar", + "save": "Guardar", + "settings.code_collapsible": "Bloques de código plegables", + "settings.code_wrappable": "Bloques de código reemplazables", + "settings.context_count": "Número de contextos", + "settings.context_count.tip": "Número de mensajes que se deben mantener en el contexto. Cuanto mayor sea el valor, más largo será el contexto y más tokens se consumirán. Para una conversación normal, se sugiere un valor entre 5-10", + "settings.max": "Sin límite", + "settings.max_tokens": "Habilitar límite de longitud del mensaje", + "settings.max_tokens.confirm": "Habilitar límite de longitud del mensaje", + "settings.max_tokens.confirm_content": "Al habilitar el límite de longitud del mensaje, se establece el número máximo de tokens por interacción, lo que afectará la longitud del resultado devuelto. Debe ajustarse según las limitaciones del contexto del modelo, de lo contrario se producirá un error", + "settings.max_tokens.tip": "Número máximo de tokens por interacción, lo que afectará la longitud del resultado devuelto. Debe ajustarse según las limitaciones del contexto del modelo, de lo contrario se producirá un error", + "settings.reset": "Restablecer", + "settings.set_as_default": "Aplicar a asistente predeterminado", + "settings.show_line_numbers": "Mostrar números de línea", + "settings.temperature": "Temperatura del modelo", + "settings.temperature.tip": "Aleatoriedad en la generación de texto del modelo. Cuanto mayor sea el valor, más diversidad, creatividad y aleatoriedad tendrá la respuesta; si se establece en 0, responde basándose en hechos. Para una conversación diaria, se recomienda un valor de 0.7", + "settings.thought_auto_collapse": "Plegado automático del contenido de pensamiento", + "settings.thought_auto_collapse.tip": "El contenido de pensamiento se pliega automáticamente después de finalizar el pensamiento", + "settings.top_p": "Top-P", + "settings.top_p.tip": "Valor predeterminado es 1, cuanto menor sea el valor, el contenido generado por la IA será menos variado pero más fácil de entender; cuanto mayor sea el valor, el vocabulario y la variedad de la respuesta de la IA serán mayores", + "suggestions.title": "Preguntas sugeridas", + "thinking": "Pensando", + "topics.auto_rename": "Generar nombre de tema", + "topics.clear.title": "Limpiar mensajes", + "topics.copy.image": "Copiar como imagen", + "topics.copy.md": "Copiar como Markdown", + "topics.copy.title": "Copiar", + "topics.delete.shortcut": "Mantén presionada {{key}} para eliminar directamente", + "topics.edit.placeholder": "Introduce nuevo nombre", + "topics.edit.title": "Editar nombre del tema", + "topics.export.image": "Exportar como imagen", + "topics.export.joplin": "Exportar a Joplin", + "topics.export.md": "Exportar como Markdown", + "topics.export.notion": "Exportar a Notion", + "topics.export.obsidian": "Exportar a Obsidian", + "topics.export.obsidian_atributes": "Configurar atributos de nota", + "topics.export.obsidian_btn": "Aceptar", + "topics.export.obsidian_created": "Fecha de creación", + "topics.export.obsidian_created_placeholder": "Selecciona la fecha de creación", + "topics.export.obsidian_export_failed": "Exportación fallida", + "topics.export.obsidian_export_success": "Exportación exitosa", + "topics.export.obsidian_not_configured": "Obsidian no configurado", + "topics.export.obsidian_operate": "Modo de operación", + "topics.export.obsidian_operate_append": "Agregar", + "topics.export.obsidian_operate_new_or_overwrite": "Crear nuevo (si existe, sobrescribir)", + "topics.export.obsidian_operate_placeholder": "Selecciona el modo de operación", + "topics.export.obsidian_operate_prepend": "Preponer", + "topics.export.obsidian_source": "Fuente", + "topics.export.obsidian_source_placeholder": "Introduce la fuente", + "topics.export.obsidian_tags": "Etiquetas", + "topics.export.obsidian_tags_placeholder": "Introduce etiquetas, múltiples etiquetas separadas por comas, Obsidian no admite números puros", + "topics.export.obsidian_title": "Título", + "topics.export.obsidian_title_placeholder": "Introduce el título", + "topics.export.obsidian_title_required": "El título no puede estar vacío", + "topics.export.title": "Exportar", + "topics.export.word": "Exportar como Word", + "topics.export.yuque": "Exportar a Yuque", + "topics.list": "Lista de temas", + "topics.move_to": "Mover a", + "topics.new": "Iniciar nueva conversación", + "topics.pinned": "Fijar tema", + "topics.prompt": "Palabras clave del tema", + "topics.prompt.edit.title": "Editar palabras clave del tema", + "topics.prompt.tips": "Palabras clave del tema: proporcionar indicaciones adicionales para el tema actual", + "topics.title": "Tema", + "topics.unpinned": "Quitar fijación", + "translate": "Traducir", + "input.generate_image": "Generar imagen", + "input.generate_image_not_supported": "El modelo no soporta la generación de imágenes" + }, + "code_block": { + "collapse": "Replegar", + "disable_wrap": "Deshabilitar salto de línea", + "enable_wrap": "Habilitar salto de línea", + "expand": "Expandir" + }, + "common": { + "add": "Agregar", + "advanced_settings": "Configuración avanzada", + "and": "y", + "assistant": "Agente inteligente", + "avatar": "Avatar", + "back": "Atrás", + "cancel": "Cancelar", + "chat": "Chat", + "clear": "Limpiar", + "close": "Cerrar", + "confirm": "Confirmar", + "copied": "Copiado", + "copy": "Copiar", + "cut": "Cortar", + "default": "Predeterminado", + "delete": "Eliminar", + "description": "Descripción", + "docs": "Documentos", + "download": "Descargar", + "duplicate": "Duplicar", + "edit": "Editar", + "expand": "Expandir", + "footnote": "Nota al pie", + "footnotes": "Notas al pie", + "fullscreen": "En modo pantalla completa, presione F11 para salir", + "knowledge_base": "Base de conocimiento", + "language": "Idioma", + "model": "Modelo", + "models": "Modelos", + "more": "Más", + "name": "Nombre", + "paste": "Pegar", + "prompt": "Prompt", + "provider": "Proveedor", + "regenerate": "Regenerar", + "rename": "Renombrar", + "reset": "Restablecer", + "save": "Guardar", + "search": "Buscar", + "select": "Seleccionar", + "topics": "Temas", + "warning": "Advertencia", + "you": "Usuario" + }, + "docs": { + "title": "Documentación de Ayuda" + }, + "error": { + "backup.file_format": "Formato de archivo de copia de seguridad incorrecto", + "chat.response": "Ha ocurrido un error, si no ha configurado la clave API, vaya a Configuración > Proveedor de modelos para configurar la clave", + "http": { + "400": "Error en la solicitud, revise si los parámetros de la solicitud son correctos. Si modificó la configuración del modelo, restablezca a la configuración predeterminada", + "401": "Fallo en la autenticación, revise si la clave API es correcta", + "403": "Acceso prohibido, traduzca el mensaje de error específico para ver la causa o póngase en contacto con el proveedor de servicios para preguntar sobre la razón de la prohibición", + "404": "El modelo no existe o la ruta de la solicitud está incorrecta", + "429": "La tasa de solicitudes excede el límite, inténtelo de nuevo más tarde", + "500": "Error del servidor, inténtelo de nuevo más tarde", + "502": "Error de puerta de enlace, inténtelo de nuevo más tarde", + "503": "Servicio no disponible, inténtelo de nuevo más tarde", + "504": "Tiempo de espera de la puerta de enlace, inténtelo de nuevo más tarde" + }, + "model.exists": "El modelo ya existe", + "no_api_key": "La clave API no está configurada", + "provider_disabled": "El proveedor de modelos no está habilitado", + "render": { + "title": "Error de renderizado", + "description": "Error al renderizar la fórmula, por favor, compruebe si el formato de la fórmula es correcto" + }, + "user_message_not_found": "No se pudo encontrar el mensaje original del usuario" + }, + "export": { + "assistant": "Asistente", + "attached_files": "Archivos adjuntos", + "conversation_details": "Detalles de la conversación", + "conversation_history": "Historial de la conversación", + "created": "Fecha de creación", + "last_updated": "Última actualización", + "messages": "Mensajes", + "user": "Usuario" + }, + "files": { + "actions": "Acciones", + "all": "Todos los archivos", + "count": "Número de archivos", + "created_at": "Fecha de creación", + "delete": "Eliminar", + "delete.content": "Eliminar el archivo eliminará todas las referencias del archivo en todos los mensajes. ¿Estás seguro de que quieres eliminar este archivo?", + "delete.paintings.warning": "La imagen está incluida en un dibujo, por lo que temporalmente no se puede eliminar", + "delete.title": "Eliminar archivo", + "document": "Documento", + "edit": "Editar", + "file": "Archivo", + "image": "Imagen", + "name": "Nombre del archivo", + "open": "Abrir", + "size": "Tamaño", + "text": "Texto", + "title": "Archivo", + "type": "Tipo" + }, + "gpustack": { + "keep_alive_time.description": "Tiempo que el modelo permanece en memoria (por defecto: 5 minutos)", + "keep_alive_time.placeholder": "minutos", + "keep_alive_time.title": "Tiempo de Actividad", + "title": "GPUStack" + }, + "history": { + "continue_chat": "Continuar chat", + "locate.message": "Localizar mensaje", + "search.messages": "Buscar todos los mensajes", + "search.placeholder": "Buscar tema o mensaje...", + "search.topics.empty": "No se encontraron temas relacionados, presione Enter para buscar todos los mensajes", + "title": "Búsqueda de temas" + }, + "knowledge": { + "add": { + "title": "Agregar base de conocimientos" + }, + "add_directory": "Agregar directorio", + "add_file": "Agregar archivo", + "add_note": "Agregar nota", + "add_sitemap": "Mapa del sitio", + "add_url": "Agregar URL", + "cancel_index": "Cancelar índice", + "chunk_overlap": "Superposición de fragmentos", + "chunk_overlap_placeholder": "Valor predeterminado (no recomendado para modificar)", + "chunk_overlap_tooltip": "La cantidad de contenido repetido entre bloques de texto adyacentes, asegurando que los fragmentos de texto divididos aún mantengan un contexto, mejorando el rendimiento general del modelo en textos largos", + "chunk_size": "Tamaño de fragmento", + "chunk_size_change_warning": "Las modificaciones del tamaño de fragmento y la superposición solo se aplican al nuevo contenido agregado", + "chunk_size_placeholder": "Valor predeterminado (no recomendado para modificar)", + "chunk_size_too_large": "El tamaño de fragmento no puede exceder el límite de contexto del modelo ({{max_context}})", + "chunk_size_tooltip": "Divide el documento en fragmentos de este tamaño, no debe exceder el límite de contexto del modelo", + "clear_selection": "Limpiar selección", + "delete": "Eliminar", + "delete_confirm": "¿Está seguro de querer eliminar esta base de conocimientos?", + "directories": "Directorios", + "directory_placeholder": "Ingrese la ruta del directorio", + "document_count": "Número de fragmentos de documentos solicitados", + "document_count_default": "Predeterminado", + "document_count_help": "Más fragmentos de documentos solicitados significa más información adjunta, pero también consume más tokens", + "drag_file": "Arrastre archivos aquí", + "edit_remark": "Editar observación", + "edit_remark_placeholder": "Ingrese el contenido de la observación", + "empty": "Sin bases de conocimientos", + "file_hint": "Formatos soportados: {{file_types}}", + "index_all": "Indexar todo", + "index_cancelled": "Índice cancelado", + "index_started": "Índice iniciado", + "invalid_url": "URL inválida", + "model_info": "Información del modelo", + "no_bases": "Sin bases de conocimientos", + "no_match": "No se encontraron coincidencias en la base de conocimientos", + "no_provider": "El proveedor del modelo de la base de conocimientos está perdido, esta base de conocimientos ya no es compatible, por favor cree una nueva base de conocimientos", + "not_set": "No configurado", + "not_support": "El motor de base de datos de la base de conocimientos ha sido actualizado, esta base de conocimientos ya no es compatible, por favor cree una nueva base de conocimientos", + "notes": "Notas", + "notes_placeholder": "Ingrese información adicional o contexto para esta base de conocimientos...", + "rename": "Renombrar", + "search": "Buscar en la base de conocimientos", + "search_placeholder": "Ingrese el contenido de la consulta", + "settings": "Configuración de la base de conocimientos", + "sitemap_placeholder": "Ingrese la URL del mapa del sitio", + "sitemaps": "Sitios web", + "source": "Fuente", + "status": "Estado", + "status_completed": "Completado", + "status_failed": "Fallido", + "status_new": "Nuevo", + "status_pending": "Pendiente", + "status_processing": "Procesando", + "threshold": "Umbral de coincidencia", + "threshold_placeholder": "No configurado", + "threshold_too_large_or_small": "El umbral no puede ser mayor que 1 o menor que 0", + "threshold_tooltip": "Se usa para medir la relevancia entre la pregunta del usuario y el contenido de la base de conocimientos (0-1)", + "title": "Base de conocimientos", + "topN": "Número de resultados devueltos", + "topN__too_large_or_small": "El número de resultados devueltos no puede ser mayor que 100 o menor que 1", + "topN_placeholder": "No configurado", + "topN_tooltip": "Número de resultados coincidentes devueltos, un valor más alto significa más resultados coincidentes, pero también consume más tokens", + "url_added": "URL agregada", + "url_placeholder": "Ingrese la URL, múltiples URLs separadas por enter", + "urls": "URLs" + }, + "languages": { + "arabic": "Árabe", + "chinese": "Chino simplificado", + "chinese-traditional": "Chino tradicional", + "english": "Inglés", + "french": "Francés", + "german": "Alemán", + "italian": "Italiano", + "japanese": "Japonés", + "korean": "Coreano", + "portuguese": "Portugués", + "russian": "Ruso", + "spanish": "Español" + }, + "lmstudio": { + "keep_alive_time.description": "Tiempo que el modelo permanece en memoria después de la conversación (predeterminado: 5 minutos)", + "keep_alive_time.placeholder": "minutos", + "keep_alive_time.title": "Tiempo de Actividad", + "title": "LM Studio" + }, + "mermaid": { + "download": { + "png": "Descargar PNG", + "svg": "Descargar SVG" + }, + "resize": { + "zoom-in": "Acercar", + "zoom-out": "Alejar" + }, + "tabs": { + "preview": "Vista previa", + "source": "Código fuente" + }, + "title": "Gráfico Mermaid" + }, + "message": { + "api.check.model.title": "Seleccione el modelo a verificar", + "api.connection.failed": "Conexión fallida", + "api.connection.success": "Conexión exitosa", + "assistant.added.content": "Asistente agregado con éxito", + "attachments": { + "pasted_image": "Imagen del portapapeles", + "pasted_text": "Archivo del portapapeles" + }, + "backup.failed": "Backup fallido", + "backup.start.success": "Inicio de backup", + "backup.success": "Backup exitoso", + "chat.completion.paused": "Chat pausado", + "citations": "Citas", + "copied": "Copiado", + "copy.failed": "Copia fallida", + "copy.success": "Copia exitosa", + "error.chunk_overlap_too_large": "El solapamiento del fragmento no puede ser mayor que el tamaño del fragmento", + "error.dimension_too_large": "La dimensión del contenido es demasiado grande", + "error.enter.api.host": "Ingrese su dirección API", + "error.enter.api.key": "Ingrese su clave API", + "error.enter.model": "Seleccione un modelo", + "error.enter.name": "Ingrese el nombre de la base de conocimiento", + "error.get_embedding_dimensions": "Fallo al obtener las dimensiones de incrustación", + "error.invalid.api.host": "Dirección API inválida", + "error.invalid.api.key": "Clave API inválida", + "error.invalid.enter.model": "Seleccione un modelo", + "error.invalid.proxy.url": "URL de proxy inválida", + "error.invalid.webdav": "Configuración de WebDAV inválida", + "error.joplin.export": "Error de exportación de Joplin, asegúrese de que Joplin esté en ejecución y verifique el estado de conexión o la configuración", + "error.joplin.no_config": "No se ha configurado el token de autorización de Joplin o la URL", + "error.markdown.export.preconf": "Error al exportar archivo Markdown a ruta predefinida", + "error.markdown.export.specified": "Error al exportar archivo Markdown", + "error.notion.export": "Error de exportación de Notion, verifique el estado de conexión y la configuración según la documentación", + "error.notion.no_api_key": "No se ha configurado la clave API de Notion o la ID de la base de datos de Notion", + "error.yuque.export": "Error de exportación de Yuque, verifique el estado de conexión y la configuración según la documentación", + "error.yuque.no_config": "No se ha configurado el token de Yuque o la URL de la base de conocimiento", + "group.delete.content": "Eliminar el mensaje del grupo eliminará la pregunta del usuario y todas las respuestas del asistente", + "group.delete.title": "Eliminar mensaje del grupo", + "ignore.knowledge.base": "Modo en línea activado, ignorando la base de conocimiento", + "info.notion.block_reach_limit": "La conversación es demasiado larga, se está exportando por páginas a Notion", + "loading.notion.exporting_progress": "Exportando a Notion ({{current}}/{{total}})...", + "loading.notion.preparing": "Preparando para exportar a Notion...", + "mention.title": "Cambiar modelo de respuesta", + "message.code_style": "Estilo de código", + "message.delete.content": "¿Está seguro de querer eliminar este mensaje?", + "message.delete.title": "Eliminar mensaje", + "message.multi_model_style": "Estilo de respuesta multi-modelo", + "message.multi_model_style.fold": "Modo de etiquetas", + "message.multi_model_style.fold.compress": "Cambiar a disposición compacta", + "message.multi_model_style.fold.expand": "Cambiar a disposición expandida", + "message.multi_model_style.grid": "Diseño de tarjetas", + "message.multi_model_style.horizontal": "Disposición horizontal", + "message.multi_model_style.vertical": "Pila vertical", + "message.style": "Estilo de mensaje", + "message.style.bubble": "Burbuja", + "message.style.plain": "Simple", + "regenerate.confirm": "Regenerar sobrescribirá el mensaje actual", + "reset.confirm.content": "¿Está seguro de querer restablecer todos los datos?", + "reset.double.confirm.content": "Todos sus datos se perderán, si no tiene una copia de seguridad, no podrán ser recuperados, ¿desea continuar?", + "reset.double.confirm.title": "¡¡Pérdida de datos!!", + "restore.failed": "Restauración fallida", + "restore.success": "Restauración exitosa", + "save.success.title": "Guardado exitoso", + "searching": "Buscando en línea...", + "success.joplin.export": "Exportado con éxito a Joplin", + "success.markdown.export.preconf": "Archivo Markdown exportado con éxito a la ruta predefinida", + "success.markdown.export.specified": "Archivo Markdown exportado con éxito", + "success.notion.export": "Exportado con éxito a Notion", + "success.yuque.export": "Exportado con éxito a Yuque", + "switch.disabled": "Espere a que se complete la respuesta actual antes de realizar la operación", + "tools": { + "completed": "Completado", + "invoking": "En llamada" + }, + "topic.added": "Tema agregado con éxito", + "upgrade.success.button": "Reiniciar", + "upgrade.success.content": "Reinicie para completar la actualización", + "upgrade.success.title": "Actualización exitosa", + "warn.notion.exporting": "Se está exportando a Notion, ¡no solicite nuevamente la exportación!", + "warning.rate.limit": "Envío demasiado frecuente, espere {{seconds}} segundos antes de intentarlo de nuevo" + }, + "minapp": { + "sidebar.add.title": "Agregar al panel lateral", + "sidebar.remove.title": "Quitar del panel lateral", + "title": "Mini programa" + }, + "miniwindow": { + "clipboard": { + "empty": "El portapapeles está vacío" + }, + "feature": { + "chat": "Responder a esta pregunta", + "explanation": "Explicación", + "summary": "Resumen del contenido", + "translate": "Traducción de texto" + }, + "footer": { + "copy_last_message": "Presione C para copiar", + "esc": "Presione ESC {{action}}", + "esc_back": "Volver", + "esc_close": "Cerrar ventana" + }, + "input": { + "placeholder": { + "empty": "Pregunta a {{model}} para obtener ayuda...", + "title": "¿Qué deseas hacer con el texto de abajo?" + } + } + }, + "models": { + "add_parameter": "Agregar parámetro", + "all": "Todo", + "custom_parameters": "Parámetros personalizados", + "dimensions": "{{dimensions}} dimensiones", + "edit": "Editar modelo", + "embedding": "Inmersión", + "embedding_model": "Modelo de inmersión", + "embedding_model_tooltip": "Haga clic en el botón Administrar en Configuración->Servicio de modelos para agregar", + "function_calling": "Llamada a función", + "no_matches": "No hay modelos disponibles", + "parameter_name": "Nombre del parámetro", + "parameter_type": { + "boolean": "Valor booleano", + "json": "JSON", + "number": "Número", + "string": "Texto" + }, + "pinned": "Fijado", + "rerank_model": "Modelo de reordenamiento", + "rerank_model_support_provider": "Actualmente, el modelo de reordenamiento solo es compatible con algunos proveedores ({{provider}})", + "rerank_model_tooltip": "Haga clic en el botón Administrar en Configuración->Servicio de modelos para agregar", + "search": "Buscar modelo...", + "stream_output": "Salida en flujo", + "type": { + "embedding": "Incrustación", + "function_calling": "Llamada a función", + "reasoning": "Razonamiento", + "select": "Seleccionar tipo de modelo", + "text": "Texto", + "vision": "Imagen", + "free": "Gratis", + "rerank": "Reclasificar", + "websearch": "Búsqueda en línea" + } + }, + "navbar": { + "expand": "Expandir cuadro de diálogo", + "hide_sidebar": "Ocultar barra lateral", + "show_sidebar": "Mostrar barra lateral" + }, + "ollama": { + "keep_alive_time.description": "Tiempo que el modelo permanece en memoria después de la conversación (por defecto: 5 minutos)", + "keep_alive_time.placeholder": "minutos", + "keep_alive_time.title": "Tiempo de Actividad", + "title": "Ollama" + }, + "paintings": { + "button.delete.image": "Eliminar imagen", + "button.delete.image.confirm": "¿Está seguro de que desea eliminar esta imagen?", + "button.new.image": "Nueva imagen", + "guidance_scale": "Escala de guía", + "guidance_scale_tip": "Sin clasificador de guía. Controla la medida en que el modelo sigue la sugerencia al buscar imágenes relacionadas", + "image.size": "Tamaño de la imagen", + "inference_steps": "Paso de inferencia", + "inference_steps_tip": "Número de pasos de inferencia a realizar. Cuantos más pasos, mejor la calidad pero más tiempo tarda", + "negative_prompt": "Prompt negativo", + "negative_prompt_tip": "Describe lo que no quieres que aparezca en la imagen", + "number_images": "Cantidad de imágenes generadas", + "number_images_tip": "Número de imágenes generadas por vez (1-4)", + "prompt_enhancement": "Mejora del prompt", + "prompt_enhancement_tip": "Al activar esto, se reescribirá la sugerencia para una versión más detallada y adecuada para el modelo", + "prompt_placeholder": "Describe la imagen que deseas crear, por ejemplo: un lago tranquilo, el sol poniente, con montañas lejanas", + "regenerate.confirm": "Esto sobrescribirá las imágenes generadas, ¿desea continuar?", + "seed": "Semilla aleatoria", + "seed_tip": "La misma semilla y la misma sugerencia generarán imágenes similares", + "title": "Imagen" + }, + "plantuml": { + "download": { + "failed": "Descarga fallida, por favor verifica la conexión a internet", + "png": "Descargar PNG", + "svg": "Descargar SVG" + }, + "tabs": { + "preview": "Vista previa", + "source": "Código fuente" + }, + "title": "Diagrama PlantUML" + }, + "prompts": { + "explanation": "Ayúdame a explicar este concepto", + "summarize": "Ayúdame a resumir este párrafo", + "title": "Eres un asistente hábil en conversación, debes resumir la conversación del usuario en un título de 10 palabras o menos. El idioma del título debe coincidir con el idioma principal del usuario, no uses signos de puntuación ni otros símbolos especiales" + }, + "provider": { + "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", + "anthropic": "Antropológico", + "azure-openai": "Azure OpenAI", + "baichuan": "BaiChuan", + "baidu-cloud": "Baidu Nube Qiánfān", + "copilot": "GitHub Copiloto", + "dashscope": "Álibaba Nube BaiLiàn", + "deepseek": "Profundo Buscar", + "dmxapi": "DMXAPI", + "doubao": "Volcán Motor", + "fireworks": "Fuegos Artificiales", + "gemini": "Géminis", + "gitee-ai": "Gitee IA", + "github": "GitHub Modelos", + "gpustack": "GPUStack", + "graphrag-kylin-mountain": "GraphRAG", + "grok": "Grok", + "groq": "Groq", + "hunyuan": "Tencent Hùnyuán", + "hyperbolic": "Hiperbólico", + "infini": "Infini", + "jina": "Jina", + "lmstudio": "Estudio LM", + "minimax": "Minimax", + "mistral": "Mistral", + "modelscope": "ModelScope Módulo", + "moonshot": "Lanzamiento Lunar", + "nvidia": "Nvidia", + "o3": "O3", + "ocoolai": "ocoolAI", + "ollama": "Ollama", + "openai": "OpenAI", + "openrouter": "OpenRouter", + "perplexity": "Perplejidad", + "ppio": "PPIO Cloud Piao", + "qwenlm": "QwenLM", + "silicon": "Silicio Fluido", + "stepfun": "Función Salto", + "tencent-cloud-ti": "Tencent Nube TI", + "together": "Juntos", + "xirang": "Telecom Nube XiRang", + "yi": "Cero Uno Todo", + "zhinao": "360 Inteligente", + "zhipu": "ZhiPu IA" + }, + "restore": { + "confirm": "¿Está seguro de que desea restaurar los datos?", + "confirm.button": "Seleccionar archivo de respaldo", + "content": "La operación de restauración sobrescribirá todos los datos actuales de la aplicación con los datos de respaldo. Tenga en cuenta que el proceso de restauración puede llevar algún tiempo, gracias por su paciencia.", + "progress": { + "completed": "Restauración completada", + "copying_files": "Copiando archivos... {{progress}}%", + "extracting": "Descomprimiendo la copia de seguridad...", + "preparing": "Preparando la restauración...", + "reading_data": "Leyendo datos...", + "title": "Progreso de Restauración" + }, + "title": "Restauración de Datos" + }, + "settings": { + "about": "Acerca de nosotros", + "about.checkingUpdate": "Verificando actualizaciones...", + "about.checkUpdate": "Comprobar actualizaciones", + "about.checkUpdate.available": "Actualizar ahora", + "about.contact.button": "Correo electrónico", + "about.contact.title": "Contacto por correo electrónico", + "about.description": "Una asistente de IA creada para los creadores", + "about.downloading": "Descargando actualización...", + "about.feedback.button": "Enviar feedback", + "about.feedback.title": "Enviar comentarios", + "about.license.button": "Ver", + "about.license.title": "Licencia", + "about.releases.button": "Ver", + "about.releases.title": "Registro de cambios", + "about.social.title": "Cuentas sociales", + "about.title": "Acerca de nosotros", + "about.updateAvailable": "Versión nueva disponible {{version}}", + "about.updateError": "Error de actualización", + "about.updateNotAvailable": "Tu software ya está actualizado", + "about.website.button": "Ver", + "about.website.title": "Sitio web oficial", + "advanced.auto_switch_to_topics": "Cambiar automáticamente a temas", + "advanced.title": "Configuración avanzada", + "assistant": "Asistente predeterminado", + "assistant.model_params": "Parámetros del modelo", + "assistant.show.icon": "Mostrar icono del modelo", + "assistant.title": "Asistente predeterminado", + "data": { + "app_data": "Datos de la aplicación", + "app_knowledge": "Archivo de base de conocimientos", + "app_knowledge.button.delete": "Eliminar archivo", + "app_knowledge.remove_all": "Eliminar archivos de la base de conocimientos", + "app_knowledge.remove_all_confirm": "Eliminar los archivos de la base de conocimientos reducirá el uso del espacio de almacenamiento, pero no eliminará los datos vectorizados de la base de conocimientos. Después de la eliminación, no se podrán abrir los archivos originales. ¿Desea eliminarlos?", + "app_knowledge.remove_all_success": "Archivos eliminados con éxito", + "app_logs": "Registros de la aplicación", + "clear_cache": { + "button": "Limpiar caché", + "confirm": "Limpiar caché eliminará los datos de la caché de la aplicación, incluyendo los datos de las aplicaciones mini. Esta acción no se puede deshacer, ¿desea continuar?", + "error": "Error al limpiar la caché", + "success": "Caché limpia con éxito", + "title": "Limpiar caché" + }, + "data.title": "Directorio de datos", + "hour_interval_one": "{{count}} hora", + "hour_interval_other": "{{count}} horas", + "joplin": { + "check": { + "button": "Revisar", + "empty_token": "Por favor, ingrese primero el token de autorización de Joplin", + "empty_url": "Por favor, ingrese primero la URL de escucha del servicio de recorte de Joplin", + "fail": "La validación de la conexión de Joplin falló", + "success": "La validación de la conexión de Joplin fue exitosa" + }, + "help": "En las opciones de Joplin, habilita el servicio de recorte de páginas web (sin necesidad de instalar una extensión del navegador), confirma el número de puerto y copia el token de autorización", + "title": "Configuración de Joplin", + "token": "Token de autorización de Joplin", + "token_placeholder": "Introduce el token de autorización de Joplin", + "url": "URL a la que escucha el servicio de recorte de Joplin", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "Al activarlo, al exportar a Markdown se usarán $$ para marcar las fórmulas LaTeX. Nota: Esto también afectará a todas las formas de exportación a través de Markdown, como Notion, Yuque, etc.", + "markdown_export.force_dollar_math.title": "Forzar el uso de $$ para marcar fórmulas LaTeX", + "markdown_export.help": "Si se especifica, se guardará automáticamente en esta ruta cada vez que se exporte; de lo contrario, se mostrará un cuadro de diálogo para guardar", + "markdown_export.path": "Ruta de exportación predeterminada", + "markdown_export.path_placeholder": "Ruta de exportación", + "markdown_export.select": "Seleccionar", + "markdown_export.title": "Exportar Markdown", + "minute_interval_one": "{{count}} minuto", + "minute_interval_other": "{{count}} minutos", + "notion.api_key": "Clave de API de Notion", + "notion.api_key_placeholder": "Introduzca la clave de API de Notion", + "notion.auto_split": "Dividir automáticamente las conversaciones al exportar", + "notion.auto_split_tip": "Cuando se exportan temas largos, se dividirán automáticamente en páginas en Notion", + "notion.check": { + "button": "Verificar", + "empty_api_key": "API key no configurada", + "empty_database_id": "Database ID no configurado", + "error": "Conexión anormal, por favor verifica la red y si el API key y Database ID son correctos", + "fail": "Conexión fallida, por favor verifica la red y si el API key y Database ID son correctos", + "success": "Conexión exitosa" + }, + "notion.database_id": "ID de la base de datos de Notion", + "notion.database_id_placeholder": "Introduzca el ID de la base de datos de Notion", + "notion.help": "Documentación de configuración de Notion", + "notion.page_name_key": "Campo del nombre de la página", + "notion.page_name_key_placeholder": "Introduzca el campo del nombre de la página, por defecto es Nombre", + "notion.split_size": "Tamaño de la división automática", + "notion.split_size_help": "Para usuarios gratuitos de Notion, se recomienda establecerlo en 90, y para usuarios avanzados, en 24990. El valor predeterminado es 90", + "notion.split_size_placeholder": "Introduzca el límite de bloques por página (predeterminado 90)", + "notion.title": "Configuración de Notion", + "obsidian": { + "folder": "Carpeta", + "folder_placeholder": "Introduce el nombre de la carpeta", + "tags": "Etiquetas globales", + "tags_placeholder": "Introduce el nombre de la etiqueta, múltiples etiquetas separadas por comas, Obsidian no admite números puros", + "title": "Configuración de Obsidian", + "vault": "Custodia", + "vault_placeholder": "Introduce el nombre de la custodia" + }, + "title": "Configuración de datos", + "webdav": { + "autoSync": "Sincronización automática", + "autoSync.off": "Desactivar", + "backup.button": "Hacer copia de seguridad en WebDAV", + "backup.modal.filename.placeholder": "Ingrese el nombre del archivo de copia de seguridad", + "backup.modal.title": "Hacer copia de seguridad en WebDAV", + "host": "Dirección WebDAV", + "host.placeholder": "http://localhost:8080", + "hour_interval_one": "{{count}} hora", + "hour_interval_other": "{{count}} horas", + "lastSync": "Última copia de seguridad", + "minute_interval_one": "{{count}} minuto", + "minute_interval_other": "{{count}} minutos", + "noSync": "Esperando la próxima copia de seguridad", + "password": "Contraseña WebDAV", + "path": "Ruta WebDAV", + "path.placeholder": "/backup", + "restore.button": "Restaurar desde WebDAV", + "restore.confirm.content": "La restauración desde WebDAV sobrescribirá los datos actuales, ¿desea continuar?", + "restore.confirm.title": "Confirmar restauración", + "restore.content": "La restauración desde WebDAV sobrescribirá los datos actuales, ¿desea continuar?", + "restore.modal.select.placeholder": "Seleccione el archivo de copia de seguridad a restaurar", + "restore.modal.title": "Restaurar desde WebDAV", + "restore.title": "Restaurar desde WebDAV", + "syncError": "Error de copia de seguridad", + "syncStatus": "Estado de copia de seguridad", + "title": "WebDAV", + "user": "Nombre de usuario WebDAV" + }, + "yuque": { + "check": { + "button": "Verificar", + "empty_repo_url": "Por favor, ingrese primero la URL del repositorio de conocimientos", + "empty_token": "Por favor, ingrese primero el Token de YuQue", + "fail": "La validación de la conexión de YuQue falló", + "success": "La validación de la conexión de YuQue fue exitosa" + }, + "help": "Obtener el Token de Yuque", + "repo_url": "URL del repositorio de conocimiento", + "repo_url_placeholder": "https://www.yuque.com/username/xxx", + "title": "Configuración de Yuque", + "token": "Token de Yuque", + "token_placeholder": "Ingrese el Token de Yuque" + } + }, + "display.assistant.title": "Configuración del asistente", + "display.custom.css": "CSS personalizado", + "display.custom.css.cherrycss": "Obtener desde cherrycss.com", + "display.custom.css.placeholder": "/* Escribe tu CSS personalizado aquí */", + "display.minApp.disabled": "Miniprogramas ocultos", + "display.minApp.empty": "Arrastra los miniprogramas que quieres ocultar desde la izquierda aquí", + "display.minApp.title": "Configuración de visualización de miniprogramas", + "display.minApp.visible": "Miniprogramas visibles", + "display.sidebar.chat.hiddenMessage": "El asistente es una función básica y no se puede ocultar", + "display.sidebar.disabled": "Iconos ocultos", + "display.sidebar.empty": "Arrastra las funciones que deseas ocultar desde la izquierda aquí", + "display.sidebar.files.icon": "Mostrar icono de archivos", + "display.sidebar.knowledge.icon": "Mostrar icono de conocimiento", + "display.sidebar.minapp.icon": "Mostrar icono de miniprogramas", + "display.sidebar.painting.icon": "Mostrar icono de pintura", + "display.sidebar.title": "Configuración de barra lateral", + "display.sidebar.translate.icon": "Mostrar icono de traducción", + "display.sidebar.visible": "Iconos visibles", + "display.title": "Configuración de visualización", + "display.topic.title": "Configuración de tema", + "font_size.title": "Tamaño de fuente de mensajes", + "general": "Configuración general", + "general.avatar.reset": "Restablecer avatar", + "general.backup.button": "Hacer copia de seguridad", + "general.backup.title": "Copia de seguridad y restauración de datos", + "general.display.title": "Configuración de visualización", + "general.emoji_picker": "Selector de emojis", + "general.image_upload": "Carga de imágenes", + "general.manually_check_update.title": "Desactivar verificación de actualizaciones", + "general.reset.button": "Restablecer", + "general.reset.title": "Restablecer datos", + "general.restore.button": "Restaurar", + "general.title": "Configuración general", + "general.user_name": "Nombre de usuario", + "general.user_name.placeholder": "Ingresa un nombre de usuario", + "general.view_webdav_settings": "Ver configuración WebDAV", + "input.auto_translate_with_space": "Traducir con tres espacios rápidos", + "input.target_language": "Idioma objetivo", + "input.target_language.chinese": "Chino simplificado", + "input.target_language.chinese-traditional": "Chino tradicional", + "input.target_language.english": "Inglés", + "input.target_language.japanese": "Japonés", + "input.target_language.russian": "Ruso", + "launch.onboot": "Iniciar automáticamente al encender", + "launch.title": "Inicio", + "launch.totray": "Minimizar a la bandeja al iniciar", + "mcp": { + "actions": "Acciones", + "active": "Activar", + "addError": "Fallo al agregar servidor", + "addServer": "Agregar servidor", + "addSuccess": "Servidor agregado exitosamente", + "args": "Argumentos", + "argsTooltip": "Cada argumento en una línea", + "baseUrlTooltip": "Dirección URL remota", + "command": "Comando", + "commandRequired": "Por favor ingrese el comando", + "config_description": "Configurar modelo de contexto del protocolo del servidor", + "confirmDelete": "Eliminar servidor", + "confirmDeleteMessage": "¿Está seguro de que desea eliminar este servidor?", + "deleteError": "Fallo al eliminar servidor", + "deleteSuccess": "Servidor eliminado exitosamente", + "dependenciesInstall": "Instalar dependencias", + "dependenciesInstalling": "Instalando dependencias...", + "description": "Descripción", + "duplicateName": "Ya existe un servidor con el mismo nombre", + "editJson": "Editar JSON", + "editServer": "Editar servidor", + "env": "Variables de entorno", + "envTooltip": "Formato: CLAVE=valor, una por línea", + "findMore": "Más servidores MCP", + "install": "Instalar", + "installError": "Fallo al instalar dependencias", + "installSuccess": "Dependencias instaladas exitosamente", + "jsonFormatError": "Error de formato JSON", + "jsonModeHint": "Edite la representación JSON de la configuración del servidor MCP. Asegúrese de que el formato sea correcto antes de guardar.", + "jsonSaveError": "Fallo al guardar la configuración JSON", + "jsonSaveSuccess": "Configuración JSON guardada exitosamente", + "missingDependencies": "Faltan, instalelas para continuar", + "name": "Nombre", + "nameRequired": "Por favor ingrese el nombre del servidor", + "noServers": "No se han configurado servidores", + "npx_list": { + "actions": "Acciones", + "desc": "Buscar y agregar paquetes npm como servicios MCP", + "description": "Descripción", + "no_packages": "No se encontraron paquetes", + "npm": "NPM", + "package_name": "Nombre del paquete", + "scope_placeholder": "Ingrese el ámbito npm (por ejemplo @your-org)", + "scope_required": "Por favor ingrese el ámbito npm", + "search": "Buscar", + "search_error": "Error de búsqueda", + "title": "Lista de paquetes NPX", + "usage": "Uso", + "version": "Versión" + }, + "serverPlural": "Servidores", + "serverSingular": "Servidor", + "title": "Servidores MCP", + "toggleError": "Fallo al cambiar", + "type": "Tipo", + "updateError": "Fallo al actualizar servidor", + "updateSuccess": "Servidor actualizado exitosamente", + "url": "URL" + }, + "messages.divider": "Separador de mensajes", + "messages.grid_columns": "Número de columnas en la cuadrícula de mensajes", + "messages.grid_popover_trigger": "Desencadenante de detalles de cuadrícula", + "messages.grid_popover_trigger.click": "Mostrar al hacer clic", + "messages.grid_popover_trigger.hover": "Mostrar al pasar el ratón", + "messages.input.paste_long_text_as_file": "Pegar texto largo como archivo", + "messages.input.paste_long_text_threshold": "Límite de longitud de texto largo", + "messages.input.send_shortcuts": "Atajos de teclado para enviar", + "messages.input.show_estimated_tokens": "Mostrar número estimado de tokens", + "messages.input.title": "Configuración de entrada", + "messages.markdown_rendering_input_message": "Renderizar mensajes de entrada en Markdown", + "messages.math_engine": "Motor de fórmulas matemáticas", + "messages.metrics": "Retraso inicial {{time_first_token_millsec}}ms | {{token_speed}} tokens por segundo", + "messages.model.title": "Configuración del modelo", + "messages.navigation": "Botón de navegación de conversación", + "messages.navigation.anchor": "Ancla de conversación", + "messages.navigation.buttons": "Botones arriba y abajo", + "messages.navigation.none": "No mostrar", + "messages.title": "Configuración de mensajes", + "messages.use_serif_font": "Usar fuente serif", + "model": "Modelo predeterminado", + "models.add.add_model": "Agregar modelo", + "models.add.group_name": "Nombre del grupo", + "models.add.group_name.placeholder": "Por ejemplo, ChatGPT", + "models.add.group_name.tooltip": "Por ejemplo, ChatGPT", + "models.add.model_id": "ID del modelo", + "models.add.model_id.placeholder": "Obligatorio, por ejemplo, gpt-3.5-turbo", + "models.add.model_id.tooltip": "Por ejemplo, gpt-3.5-turbo", + "models.add.model_name": "Nombre del modelo", + "models.add.model_name.placeholder": "Por ejemplo, GPT-3.5", + "models.check.all": "Todos", + "models.check.all_models_passed": "Todos los modelos pasaron la verificación", + "models.check.button_caption": "Verificación de salud", + "models.check.disabled": "Deshabilitado", + "models.check.enable_concurrent": "Verificación concurrente", + "models.check.enabled": "Habilitado", + "models.check.failed": "Fallido", + "models.check.keys_status_count": "Pasados: {{count_passed}} claves, fallidos: {{count_failed}} claves", + "models.check.model_status_summary": "{{provider}}: {{count_passed}} modelos completaron la verificación de salud ({{count_partial}} modelos no accesibles con algunas claves), {{count_failed}} modelos completamente inaccesibles.", + "models.check.no_api_keys": "No se encontraron claves API, agrega una clave API primero.", + "models.check.passed": "Pasado", + "models.check.select_api_key": "Seleccionar clave API a usar:", + "models.check.single": "Individual", + "models.check.start": "Iniciar", + "models.check.title": "Verificación de salud del modelo", + "models.check.use_all_keys": "Usar todas las claves", + "models.default_assistant_model": "Modelo predeterminado del asistente", + "models.default_assistant_model_description": "Modelo utilizado al crear nuevos asistentes, si el asistente no tiene un modelo asignado, se utiliza este modelo", + "models.empty": "Sin modelos", + "models.enable_topic_naming": "Renombrar temas automáticamente", + "models.manage.add_whole_group": "Agregar todo el grupo", + "models.manage.remove_whole_group": "Eliminar todo el grupo", + "models.topic_naming_model": "Modelo de nombramiento de temas", + "models.topic_naming_model_description": "Modelo utilizado para nombrar temas automáticamente", + "models.topic_naming_model_setting_title": "Configuración del modelo de nombramiento de temas", + "models.topic_naming_prompt": "Sugerencias para nombramiento de temas", + "models.translate_model": "Modelo de traducción", + "models.translate_model_description": "Modelo utilizado para el servicio de traducción", + "models.translate_model_prompt_message": "Ingrese las sugerencias del modelo de traducción", + "models.translate_model_prompt_title": "Sugerencias del modelo de traducción", + "moresetting": "Configuración adicional", + "moresetting.check.confirm": "Confirmar selección", + "moresetting.check.warn": "Ten cuidado al seleccionar esta opción, ¡una elección incorrecta puede causar que los modelos no funcionen correctamente!!!", + "moresetting.warn": "Advertencia de riesgo", + "provider": { + "add.name": "Nombre del proveedor", + "add.name.placeholder": "Por ejemplo, OpenAI", + "add.title": "Agregar proveedor", + "add.type": "Tipo de proveedor", + "api.url.preview": "Vista previa: {{url}}", + "api.url.reset": "Restablecer", + "api.url.tip": "Ignorar v1 al final con /, forzar uso de dirección de entrada con # al final", + "api_host": "Dirección API", + "api_key": "Clave API", + "api_key.tip": "Separar múltiples claves con comas", + "api_version": "Versión API", + "charge": "Recargar", + "check": "Verificar", + "check_all_keys": "Verificar todas las claves", + "check_multiple_keys": "Verificar múltiples claves API", + "copilot": { + "auth_failed": "Autenticación de Github Copilot fallida", + "auth_success": "Autenticación de Github Copilot exitosa", + "auth_success_title": "Autenticación exitosa", + "code_failed": "Error al obtener Código del Dispositivo, por favor inténtelo de nuevo", + "code_generated_desc": "Por favor, copie el Código del Dispositivo en el siguiente enlace del navegador", + "code_generated_title": "Obtener Código del Dispositivo", + "confirm_login": "El uso excesivo puede llevar al bloqueo de su cuenta de Github, use con precaución!!!!", + "confirm_title": "Advertencia de Riesgo", + "connect": "Conectar con Github", + "custom_headers": "Encabezados personalizados", + "description": "Su cuenta de Github necesita suscribirse a Copilot", + "expand": "Expandir", + "headers_description": "Encabezados personalizados (formato json)", + "invalid_json": "Formato JSON incorrecto", + "login": "Iniciar sesión en Github", + "logout": "Cerrar sesión en Github", + "logout_failed": "Error al cerrar sesión, por favor inténtelo de nuevo", + "logout_success": "Ha cerrado sesión exitosamente", + "model_setting": "Configuración del modelo", + "open_verification_first": "Por favor, haga clic en el enlace superior para acceder a la página de verificación", + "rate_limit": "Límite de tasa", + "tooltip": "Para usar Github Copilot, primero debe iniciar sesión en Github" + }, + "delete.content": "¿Está seguro de que desea eliminar este proveedor de modelos?", + "delete.title": "Eliminar proveedor", + "docs_check": "Ver", + "docs_more_details": "Obtener más detalles", + "get_api_key": "Haga clic aquí para obtener la clave", + "is_not_support_array_content": "Activar modo compatible", + "no_models": "Agregue un modelo primero antes de verificar la conexión API", + "not_checked": "No verificado", + "remove_duplicate_keys": "Eliminar claves duplicadas", + "remove_invalid_keys": "Eliminar claves inválidas", + "search": "Buscar plataforma de modelos...", + "search_placeholder": "Buscar ID o nombre del modelo", + "title": "Servicio de modelos" + }, + "proxy": { + "mode": { + "custom": "Proxy personalizado", + "none": "No usar proxy", + "system": "Proxy del sistema", + "title": "Modo de proxy" + }, + "title": "Configuración de Proxy" + }, + "proxy.title": "Dirección proxy", + "quickAssistant": { + "click_tray_to_show": "Haz clic en el icono de la bandeja para iniciar", + "enable_quick_assistant": "Habilitar Asistente Rápido", + "read_clipboard_at_startup": "Leer portapapeles al iniciar", + "title": "Asistente Rápido", + "use_shortcut_to_show": "Haz clic derecho en el icono de la bandeja o usa un atajo de teclado para iniciar" + }, + "shortcuts": { + "action": "Acción", + "clear_shortcut": "Borrar atajo", + "clear_topic": "Vaciar mensaje", + "copy_last_message": "Copiar el último mensaje", + "key": "Tecla", + "mini_window": "Asistente rápido", + "new_topic": "Nuevo tema", + "press_shortcut": "Presionar atajo", + "reset_defaults": "Restablecer atajos predeterminados", + "reset_defaults_confirm": "¿Está seguro de querer restablecer todos los atajos?", + "reset_to_default": "Restablecer a predeterminado", + "search_message": "Buscar mensaje", + "show_app": "Mostrar aplicación", + "show_settings": "Abrir configuración", + "title": "Atajos", + "toggle_new_context": "Limpiar contexto", + "toggle_show_assistants": "Alternar visibilidad de asistentes", + "toggle_show_topics": "Alternar visibilidad de temas", + "zoom_in": "Ampliar interfaz", + "zoom_out": "Reducir interfaz", + "zoom_reset": "Restablecer zoom" + }, + "theme.auto": "Automático", + "theme.dark": "Oscuro", + "theme.light": "Claro", + "theme.title": "Tema", + "theme.window.style.opaque": "Ventana opaca", + "theme.window.style.title": "Estilo de ventana", + "theme.window.style.transparent": "Ventana transparente", + "title": "Configuración", + "topic.position": "Posición del tema", + "topic.position.left": "Izquierda", + "topic.position.right": "Derecha", + "topic.show.time": "Mostrar tiempo del tema", + "tray.onclose": "Minimizar a la bandeja al cerrar", + "tray.show": "Mostrar bandera del sistema", + "tray.title": "Bandera", + "websearch": { + "blacklist": "Lista negra", + "blacklist_description": "No aparecerán los resultados de los siguientes sitios web en los resultados de búsqueda", + "blacklist_tooltip": "Por favor, use el siguiente formato (separado por saltos de línea)\">\">example.com\">https://www.example.com\">https://example.com\">*://*.example.com", + "check": "Comprobar", + "check_failed": "Verificación fallida", + "check_success": "Verificación exitosa", + "enhance_mode": "Modo de búsqueda mejorada", + "enhance_mode_tooltip": "Utilice el modelo predeterminado para extraer palabras clave y luego busque", + "get_api_key": "Haz clic aquí para obtener la clave", + "no_provider_selected": "Por favor, seleccione un proveedor de búsqueda antes de comprobar", + "search_max_result": "Número de resultados de búsqueda", + "search_provider": "Proveedor de búsqueda", + "search_provider_placeholder": "Seleccione un proveedor de búsqueda", + "search_result_default": "Predeterminado", + "search_with_time": "Búsqueda con fecha", + "tavily": { + "api_key": "Clave de API de Tavily", + "api_key.placeholder": "Introduce la clave de API de Tavily", + "description": "Tavily es un motor de búsqueda diseñado específicamente para agentes de IA, proporcionando resultados en tiempo real, precisos, sugerencias de consulta inteligentes y capacidades de investigación profundas", + "title": "Tavily" + }, + "title": "Búsqueda en la web" + } + }, + "translate": { + "any.language": "cualquier idioma", + "button.translate": "Traducir", + "close": "Cerrar", + "confirm": { + "content": "La traducción reemplazará el texto original, ¿desea continuar?", + "title": "Confirmación de traducción" + }, + "error.failed": "Fallo en la traducción", + "error.not_configured": "El modelo de traducción no está configurado", + "history": { + "clear": "Borrar historial", + "clear_description": "Borrar el historial eliminará todos los registros de traducciones, ¿desea continuar?", + "delete": "Eliminar", + "empty": "Sin historial de traducciones por el momento", + "title": "Historial de traducciones" + }, + "input.placeholder": "Ingrese el texto para traducir", + "output.placeholder": "Traducción", + "processing": "Traduciendo...", + "scroll_sync.disable": "Deshabilitar sincronización de desplazamiento", + "scroll_sync.enable": "Habilitar sincronización de desplazamiento", + "title": "Traducción", + "tooltip.newline": "Salto de línea" + }, + "tray": { + "quit": "Salir", + "show_mini_window": "Asistente rápido", + "show_window": "Mostrar ventana" + }, + "words": { + "knowledgeGraph": "Grafo de Conocimiento", + "quit": "Salir", + "show_window": "Mostrar Ventana", + "visualization": "Visualización" + } + } +} diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json new file mode 100644 index 000000000..6b4791c83 --- /dev/null +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -0,0 +1,1173 @@ +{ + "translation": { + "agents": { + "add.button": "Ajouter à l'assistant", + "add.knowledge_base": "Base de connaissances", + "add.knowledge_base.placeholder": "Sélectionner une base de connaissances", + "add.name": "Nom", + "add.name.placeholder": "Entrer le nom", + "add.prompt": "Mot-clé", + "add.prompt.placeholder": "Entrer le mot-clé", + "add.title": "Créer un agent intelligent", + "delete.popup.content": "Êtes-vous sûr de vouloir supprimer cet agent intelligent ?", + "edit.message.add.title": "Ajouter", + "edit.message.assistant.placeholder": "Entrer le message de l'assistant", + "edit.message.assistant.title": "Assistant", + "edit.message.empty.content": "Le contenu de la session ne peut pas être vide", + "edit.message.group.title": "Groupe de messages", + "edit.message.title": "Messages prédéfinis", + "edit.message.user.placeholder": "Entrer le message de l'utilisateur", + "edit.message.user.title": "Utilisateur", + "edit.model.select.title": "Sélectionner un modèle", + "edit.settings.hide_preset_messages": "Masquer les messages prédéfinis", + "edit.title": "Modifier l'agent intelligent", + "manage.title": "Gérer les agents intelligents", + "my_agents": "Mes agents intelligents", + "search.no_results": "Aucun agent intelligent correspondant trouvé", + "sorting.title": "Trier", + "tag.agent": "Agent intelligent", + "tag.default": "Par défaut", + "tag.new": "Nouveau", + "tag.system": "Système", + "title": "Agent intelligent" + }, + "assistants": { + "abbr": "Aide", + "clear.content": "Supprimer le sujet supprimera tous les sujets et fichiers de l'aide. Êtes-vous sûr de vouloir continuer ?", + "clear.title": "Supprimer les sujets", + "copy.title": "Copier l'Aide", + "delete.content": "La suppression de l'aide supprimera tous les sujets et fichiers sous l'aide. Êtes-vous sûr de vouloir la supprimer ?", + "delete.title": "Supprimer l'Aide", + "edit.title": "Modifier l'Aide", + "save.success": "Sauvegarde réussie", + "save.title": "Enregistrer dans l'agent", + "search": "Rechercher des assistants...", + "settings.default_model": "Modèle par défaut", + "settings.knowledge_base": "Paramètres de la base de connaissances", + "settings.model": "Paramètres du modèle", + "settings.preset_messages": "Messages prédéfinis", + "settings.prompt": "Paramètres de l'invite", + "settings.reasoning_effort": "Longueur de la chaîne de raisonnement", + "settings.reasoning_effort.high": "Long", + "settings.reasoning_effort.low": "Court", + "settings.reasoning_effort.medium": "Moyen", + "settings.reasoning_effort.off": "Off", + "settings.reasoning_effort.tip": "Prise en charge uniquement des modèles de raisonnement OpenAI o-series et Anthropic", + "title": "Aides" + }, + "auth": { + "error": "Échec de l'obtention automatique de la clé, veuillez la récupérer manuellement", + "get_key": "Obtenir", + "get_key_success": "Obtention automatique de la clé réussie", + "login": "Se connecter", + "oauth_button": "Se connecter avec {{provider}}" + }, + "backup": { + "confirm": "Êtes-vous sûr de vouloir effectuer une sauvegarde des données ?", + "confirm.button": "Sélectionner l'emplacement de sauvegarde", + "content": "Sauvegarder toutes les données, y compris l'historique des conversations, les paramètres et la base de connaissances. Veuillez noter que le processus de sauvegarde peut prendre un certain temps, merci de votre patience.", + "progress": { + "completed": "Sauvegarde terminée", + "compressing": "Compression des fichiers...", + "copying_files": "Copie des fichiers... {{progress}}%", + "preparing": "Préparation de la sauvegarde...", + "title": "Progrès de la sauvegarde", + "writing_data": "Écriture des données..." + }, + "title": "Sauvegarde des données" + }, + "button": { + "add": "Ajouter", + "added": "Ajouté", + "collapse": "Réduire", + "manage": "Gérer", + "select_model": "Sélectionner le Modèle", + "show.all": "Afficher tout", + "update_available": "Mise à jour disponible" + }, + "chat": { + "add.assistant.title": "Ajouter un assistant", + "artifacts.button.download": "Télécharger", + "artifacts.button.openExternal": "Ouvrir dans un navigateur externe", + "artifacts.button.preview": "Aperçu", + "artifacts.preview.openExternal.error.content": "Erreur lors de l'ouverture dans un navigateur externe", + "assistant.search.placeholder": "Rechercher", + "deeply_thought": "Profondément réfléchi ({{secounds}} secondes)", + "default.description": "Bonjour, je suis l'assistant par défaut. Vous pouvez commencer à discuter avec moi tout de suite.", + "default.name": "Assistant par défaut", + "default.topic.name": "Sujet par défaut", + "input.auto_resize": "Ajustement automatique de la hauteur", + "input.clear": "Effacer le message {{Command}}", + "input.clear.content": "Êtes-vous sûr de vouloir effacer tous les messages de la conversation actuelle ?", + "input.clear.title": "Effacer le message", + "input.collapse": "Récupérer", + "input.context_count.tip": "Nombre de contextes / Nombre maximal de contextes", + "input.estimated_tokens.tip": "Estimation du nombre de tokens", + "input.expand": "Développer", + "input.file_not_supported": "Le modèle ne prend pas en charge ce type de fichier", + "input.knowledge_base": "Base de connaissances", + "input.new.context": "Effacer le contexte {{Command}}", + "input.new_topic": "Nouveau sujet {{Command}}", + "input.pause": "Pause", + "input.placeholder": "Entrez votre message ici...", + "input.send": "Envoyer", + "input.settings": "Paramètres", + "input.topics": "Sujets", + "input.translate": "Traduire en {{target_language}}", + "input.upload": "Télécharger une image ou un document", + "input.upload.document": "Télécharger un document (le modèle ne prend pas en charge les images)", + "input.web_search": "Activer la recherche web", + "input.web_search.button.ok": "Aller aux paramètres", + "input.web_search.enable": "Activer la recherche web", + "input.web_search.enable_content": "Vous devez vérifier la connectivité de la recherche web dans les paramètres", + "message.new.branch": "Branche", + "message.new.branch.created": "Nouvelle branche créée", + "message.new.context": "Effacer le contexte", + "message.quote": "Citer", + "message.regenerate.model": "Changer de modèle", + "message.useful": "Utile", + "navigation": { + "first": "Déjà premier message", + "last": "Déjà dernier message", + "next": "Prochain message", + "prev": "Précédent message" + }, + "resend": "Réenvoyer", + "save": "Enregistrer", + "settings.code_collapsible": "Blocs de code pliables", + "settings.code_wrappable": "Blocs de code avec retours à la ligne", + "settings.context_count": "Nombre de contextes", + "settings.context_count.tip": "Nombre de messages à conserver dans le contexte. Plus la valeur est élevée, plus le contexte est long et plus les tokens consommés sont nombreux. Pour une conversation normale, il est recommandé de choisir entre 5 et 10", + "settings.max": "Illimité", + "settings.max_tokens": "Activer la limitation de la longueur du message", + "settings.max_tokens.confirm": "Activer la limitation de la longueur du message", + "settings.max_tokens.confirm_content": "Après activation de la limitation de la longueur du message, le nombre maximal de tokens utilisé pour une interaction unique affectera la longueur du résultat renvoyé. Il faut le configurer en fonction des limitations du contexte du modèle, sinon cela génèrera une erreur", + "settings.max_tokens.tip": "Nombre maximal de tokens utilisé pour une interaction unique. Cela affectera la longueur du résultat renvoyé. Il faut le configurer en fonction des limitations du contexte du modèle, sinon cela génèrera une erreur", + "settings.reset": "Réinitialiser", + "settings.set_as_default": "Appliquer à l'assistant par défaut", + "settings.show_line_numbers": "Afficher les numéros de ligne", + "settings.temperature": "Température du modèle", + "settings.temperature.tip": "Degré de génération aléatoire du texte par le modèle. Plus la valeur est élevée, plus la réponse est diverse, créative et aléatoire ; fixez-la à 0 pour obtenir une réponse factuelle. Pour une conversation quotidienne, il est recommandé de la fixer à 0.7", + "settings.thought_auto_collapse": "Pliage automatique du contenu de la pensée", + "settings.thought_auto_collapse.tip": "Le contenu de la pensée se replie automatiquement après la fin de la pensée", + "settings.top_p": "Top-P", + "settings.top_p.tip": "Valeur par défaut : 1. Plus la valeur est faible, plus le contenu généré par l'IA est monotone mais facile à comprendre ; plus la valeur est élevée, plus le vocabulaire et la diversité de la réponse de l'IA sont grands", + "suggestions.title": "Questions suggérées", + "thinking": "En réflexion", + "topics.auto_rename": "Générer un nom de sujet", + "topics.clear.title": "Effacer le message", + "topics.copy.image": "Copier sous forme d'image", + "topics.copy.md": "Copier sous forme de Markdown", + "topics.copy.title": "Copier", + "topics.delete.shortcut": "Maintenez {{key}} pour supprimer directement", + "topics.edit.placeholder": "Entrez un nouveau nom", + "topics.edit.title": "Modifier le nom du sujet", + "topics.export.image": "Exporter sous forme d'image", + "topics.export.joplin": "Exporter vers Joplin", + "topics.export.md": "Exporter sous forme de Markdown", + "topics.export.notion": "Exporter vers Notion", + "topics.export.obsidian": "Exporter vers Obsidian", + "topics.export.obsidian_atributes": "Configurer les attributs de la note", + "topics.export.obsidian_btn": "Confirmer", + "topics.export.obsidian_created": "Date de création", + "topics.export.obsidian_created_placeholder": "Choisissez la date de création", + "topics.export.obsidian_export_failed": "Échec de l'exportation", + "topics.export.obsidian_export_success": "Exportation réussie", + "topics.export.obsidian_not_configured": "Obsidian non configuré", + "topics.export.obsidian_operate": "Mode de traitement", + "topics.export.obsidian_operate_append": "Ajouter", + "topics.export.obsidian_operate_new_or_overwrite": "Créer (écraser si existant)", + "topics.export.obsidian_operate_placeholder": "Choisissez un mode de traitement", + "topics.export.obsidian_operate_prepend": "Préfixer", + "topics.export.obsidian_source": "Source", + "topics.export.obsidian_source_placeholder": "Entrez une source", + "topics.export.obsidian_tags": "Étiquettes", + "topics.export.obsidian_tags_placeholder": "Entrez des étiquettes, séparées par des virgules en anglais, Obsidian ne peut pas utiliser des nombres purs", + "topics.export.obsidian_title": "Titre", + "topics.export.obsidian_title_placeholder": "Entrez un titre", + "topics.export.obsidian_title_required": "Le titre ne peut pas être vide", + "topics.export.title": "Exporter", + "topics.export.word": "Exporter sous forme de Word", + "topics.export.yuque": "Exporter vers Yuque", + "topics.list": "Liste des sujets", + "topics.move_to": "Déplacer vers", + "topics.new": "Commencer une nouvelle conversation", + "topics.pinned": "Fixer le sujet", + "topics.prompt": "Indicateurs de sujet", + "topics.prompt.edit.title": "Modifier les indicateurs de sujet", + "topics.prompt.tips": "Indicateurs de sujet : fournir des indications supplémentaires pour le sujet actuel", + "topics.title": "Sujet", + "topics.unpinned": "Annuler le fixage", + "translate": "Traduire", + "input.generate_image": "Générer une image", + "input.generate_image_not_supported": "Le modèle ne supporte pas la génération d'images" + }, + "code_block": { + "collapse": "Réduire", + "disable_wrap": "Désactiver le retour à la ligne", + "enable_wrap": "Activer le retour à la ligne", + "expand": "Développer" + }, + "common": { + "add": "Ajouter", + "advanced_settings": "Paramètres avancés", + "and": "et", + "assistant": "Intelligence artificielle", + "avatar": "Avatar", + "back": "Retour", + "cancel": "Annuler", + "chat": "Chat", + "clear": "Effacer", + "close": "Fermer", + "confirm": "Confirmer", + "copied": "Copié", + "copy": "Copier", + "cut": "Couper", + "default": "Défaut", + "delete": "Supprimer", + "description": "Description", + "docs": "Documents", + "download": "Télécharger", + "duplicate": "Dupliquer", + "edit": "Éditer", + "expand": "Développer", + "footnote": "Note de bas de page", + "footnotes": "Notes de bas de page", + "fullscreen": "Mode plein écran, appuyez sur F11 pour quitter", + "knowledge_base": "Base de connaissances", + "language": "Langue", + "model": "Modèle", + "models": "Modèles", + "more": "Plus", + "name": "Nom", + "paste": "Coller", + "prompt": "Prompt", + "provider": "Fournisseur", + "regenerate": "Regénérer", + "rename": "Renommer", + "reset": "Réinitialiser", + "save": "Enregistrer", + "search": "Rechercher", + "select": "Sélectionner", + "topics": "Sujets", + "warning": "Avertissement", + "you": "Vous" + }, + "docs": { + "title": "Documentation d'aide" + }, + "error": { + "backup.file_format": "Le format du fichier de sauvegarde est incorrect", + "chat.response": "Une erreur s'est produite, si l'API n'est pas configurée, veuillez aller dans Paramètres > Fournisseurs de modèles pour configurer la clé", + "http": { + "400": "Erreur de requête, veuillez vérifier si les paramètres de la requête sont corrects. Si vous avez modifié les paramètres du modèle, réinitialisez-les aux paramètres par défaut.", + "401": "Échec de l'authentification, veuillez vérifier que votre clé API est correcte.", + "403": "Accès interdit, veuillez traduire le message d'erreur spécifique pour connaître la raison ou contacter le fournisseur de services pour demander la raison de l'interdiction.", + "404": "Le modèle n'existe pas ou la requête de chemin est incorrecte.", + "429": "Le taux de requêtes dépasse la limite, veuillez réessayer plus tard.", + "500": "Erreur serveur, veuillez réessayer plus tard.", + "502": "Erreur de passerelle, veuillez réessayer plus tard.", + "503": "Service indisponible, veuillez réessayer plus tard.", + "504": "Délai d'expiration de la passerelle, veuillez réessayer plus tard." + }, + "model.exists": "Le modèle existe déjà", + "no_api_key": "La clé API n'est pas configurée", + "provider_disabled": "Le fournisseur de modèles n'est pas activé", + "render": { + "description": "La formule n'a pas été rendue avec succès, veuillez vérifier si le format de la formule est correct", + "title": "Erreur de rendu" + }, + "user_message_not_found": "Impossible de trouver le message d'utilisateur original" + }, + "export": { + "assistant": "Assistant", + "attached_files": "Pièces jointes", + "conversation_details": "Détails de la conversation", + "conversation_history": "Historique de la conversation", + "created": "Date de création", + "last_updated": "Dernière mise à jour", + "messages": "Messages", + "user": "Utilisateur" + }, + "files": { + "actions": "Actions", + "all": "Tous les fichiers", + "count": "Nombre de fichiers", + "created_at": "Date de création", + "delete": "Supprimer", + "delete.content": "La suppression du fichier supprimera toutes les références au fichier dans tous les messages. Êtes-vous sûr de vouloir supprimer ce fichier ?", + "delete.paintings.warning": "Cette image est incluse dans un dessin, elle ne peut pas être supprimée pour l'instant", + "delete.title": "Supprimer le fichier", + "document": "Document", + "edit": "Éditer", + "file": "Fichier", + "image": "Image", + "name": "Nom du fichier", + "open": "Ouvrir", + "size": "Taille", + "text": "Texte", + "title": "Fichier", + "type": "Type" + }, + "gpustack": { + "keep_alive_time.description": "Le modèle reste en mémoire pendant ce temps (par défaut : 5 minutes)", + "keep_alive_time.placeholder": "minutes", + "keep_alive_time.title": "Temps de maintien actif", + "title": "GPUStack" + }, + "history": { + "continue_chat": "Continuer la conversation", + "locate.message": "Localiser le message", + "search.messages": "Rechercher tous les messages", + "search.placeholder": "Rechercher un sujet ou un message...", + "search.topics.empty": "Aucun sujet correspondant trouvé, appuyez sur Entrée pour rechercher tous les messages", + "title": "Recherche de sujets" + }, + "knowledge": { + "add": { + "title": "Ajouter une base de connaissances" + }, + "add_directory": "Ajouter un répertoire", + "add_file": "Ajouter un fichier", + "add_note": "Ajouter une note", + "add_sitemap": "Plan du site", + "add_url": "Ajouter une URL", + "cancel_index": "Annuler l'indexation", + "chunk_overlap": "Chevauchement de blocs", + "chunk_overlap_placeholder": "Valeur par défaut (ne pas modifier)", + "chunk_overlap_tooltip": "Quantité de contenu redondant entre les blocs de texte adjacents pour maintenir la continuité contextuelle et améliorer le traitement des longs textes par le modèle", + "chunk_size": "Taille de bloc", + "chunk_size_change_warning": "Les modifications de taille de bloc et de chevauchement ne s'appliquent qu'aux nouveaux contenus ajoutés", + "chunk_size_placeholder": "Valeur par défaut (ne pas modifier)", + "chunk_size_too_large": "La taille de bloc ne peut pas dépasser la limite de contexte du modèle ({{max_context}})", + "chunk_size_tooltip": "Taille des segments de document, ne doit pas dépasser la limite de contexte du modèle", + "clear_selection": "Effacer la sélection", + "delete": "Supprimer", + "delete_confirm": "Êtes-vous sûr de vouloir supprimer cette base de connaissances ?", + "directories": "Répertoires", + "directory_placeholder": "Entrez le chemin du répertoire", + "document_count": "Nombre de fragments de documents demandés", + "document_count_default": "Par défaut", + "document_count_help": "Plus vous demandez de fragments de documents, plus d'informations sont fournies, mais plus de jetons sont consommés", + "drag_file": "Glissez-déposez un fichier ici", + "edit_remark": "Modifier la remarque", + "edit_remark_placeholder": "Entrez le contenu de la remarque", + "empty": "Aucune base de connaissances pour le moment", + "file_hint": "Format supporté : {{file_types}}", + "index_all": "Indexer tout", + "index_cancelled": "L'indexation a été annulée", + "index_started": "L'indexation a commencé", + "invalid_url": "URL invalide", + "model_info": "Informations sur le modèle", + "no_bases": "Aucune base de connaissances pour le moment", + "no_match": "Aucun contenu de la base de connaissances correspondant", + "no_provider": "Le fournisseur de modèle de la base de connaissances est perdu, cette base de connaissances ne sera plus supportée, veuillez en créer une nouvelle", + "not_set": "Non défini", + "not_support": "Le moteur de base de données de la base de connaissances a été mis à jour, cette base de connaissances ne sera plus supportée, veuillez en créer une nouvelle", + "notes": "Notes", + "notes_placeholder": "Entrez des informations supplémentaires ou un contexte pour cette base de connaissances...", + "rename": "Renommer", + "search": "Rechercher dans la base de connaissances", + "search_placeholder": "Entrez votre requête", + "settings": "Paramètres de la base de connaissances", + "sitemap_placeholder": "Entrez l'URL du plan du site", + "sitemaps": "Sites web", + "source": "Source", + "status": "Statut", + "status_completed": "Terminé", + "status_failed": "Échec", + "status_new": "Ajouté", + "status_pending": "En attente", + "status_processing": "En cours de traitement", + "threshold": "Seuil de similarité", + "threshold_placeholder": "Non défini", + "threshold_too_large_or_small": "Le seuil ne peut pas être supérieur à 1 ou inférieur à 0", + "threshold_tooltip": "Utilisé pour mesurer la pertinence entre la question de l'utilisateur et le contenu de la base de connaissances (0-1)", + "title": "Base de connaissances", + "topN": "Nombre de résultats retournés", + "topN__too_large_or_small": "Le nombre de résultats retournés ne peut pas être supérieur à 100 ou inférieur à 1", + "topN_placeholder": "Non défini", + "topN_tooltip": "Nombre de résultats de correspondance retournés, plus le chiffre est élevé, plus il y a de résultats de correspondance, mais plus de jetons sont consommés", + "url_added": "URL ajoutée", + "url_placeholder": "Entrez l'URL, plusieurs URLs séparées par des sauts de ligne", + "urls": "URLs" + }, + "languages": { + "arabic": "Arabe", + "chinese": "Chinois simplifié", + "chinese-traditional": "Chinois traditionnel", + "english": "Anglais", + "french": "Français", + "german": "Allemand", + "italian": "Italien", + "japanese": "Japonais", + "korean": "Coréen", + "portuguese": "Portugais", + "russian": "Russe", + "spanish": "Espagnol" + }, + "lmstudio": { + "keep_alive_time.description": "Temps pendant lequel le modèle reste en mémoire après la conversation (par défaut : 5 minutes)", + "keep_alive_time.placeholder": "minutes", + "keep_alive_time.title": "Maintenir le temps d'activité", + "title": "LM Studio" + }, + "mermaid": { + "download": { + "png": "Télécharger PNG", + "svg": "Télécharger SVG" + }, + "resize": { + "zoom-in": "Approfondir", + "zoom-out": "Éloigner" + }, + "tabs": { + "preview": "Aperçu", + "source": "Code source" + }, + "title": "Diagramme Mermaid" + }, + "message": { + "api.check.model.title": "Veuillez sélectionner le modèle à tester", + "api.connection.failed": "La connexion a échoué", + "api.connection.success": "La connexion a réussi", + "assistant.added.content": "L'assistant a été ajouté avec succès", + "attachments": { + "pasted_image": "Image Presse-papiers", + "pasted_text": "Fichier Presse-papiers" + }, + "backup.failed": "La sauvegarde a échoué", + "backup.start.success": "La sauvegarde a commencé", + "backup.success": "La sauvegarde a réussi", + "chat.completion.paused": "La conversation est en pause", + "citations": "Citations", + "copied": "Copié", + "copy.failed": "La copie a échoué", + "copy.success": "Copie réussie", + "error.chunk_overlap_too_large": "Le chevauchement de segment ne peut pas dépasser la taille du segment", + "error.dimension_too_large": "Les dimensions du contenu sont trop grandes", + "error.enter.api.host": "Veuillez entrer votre adresse API", + "error.enter.api.key": "Veuillez entrer votre clé API", + "error.enter.model": "Veuillez sélectionner un modèle", + "error.enter.name": "Veuillez entrer le nom de la base de connaissances", + "error.get_embedding_dimensions": "Impossible d'obtenir les dimensions d'encodage", + "error.invalid.api.host": "Adresse API invalide", + "error.invalid.api.key": "Clé API invalide", + "error.invalid.enter.model": "Veuillez sélectionner un modèle", + "error.invalid.proxy.url": "URL proxy invalide", + "error.invalid.webdav": "Configuration WebDAV invalide", + "error.joplin.export": "Échec de l'exportation vers Joplin, veuillez vous assurer que Joplin est en cours d'exécution et vérifier l'état de la connexion ou la configuration", + "error.joplin.no_config": "Aucun jeton d'autorisation Joplin ou URL configuré", + "error.markdown.export.preconf": "Échec de l'exportation vers un fichier Markdown dans le chemin prédéfini", + "error.markdown.export.specified": "Échec de l'exportation vers un fichier Markdown", + "error.notion.export": "Erreur lors de l'exportation vers Notion, veuillez vérifier l'état de la connexion et la configuration dans la documentation", + "error.notion.no_api_key": "Aucune clé API Notion ou ID de base de données Notion configurée", + "error.yuque.export": "Erreur lors de l'exportation vers Yuque, veuillez vérifier l'état de la connexion et la configuration dans la documentation", + "error.yuque.no_config": "Aucun jeton Yuque ou URL de base de connaissances configuré", + "group.delete.content": "La suppression du groupe de messages supprimera les questions des utilisateurs et toutes les réponses des assistants", + "group.delete.title": "Supprimer le groupe de messages", + "ignore.knowledge.base": "Mode en ligne activé, la base de connaissances est ignorée", + "info.notion.block_reach_limit": "La conversation est trop longue, exportation par pages vers Notion", + "loading.notion.exporting_progress": "Exportation vers Notion en cours ({{current}}/{{total}})...", + "loading.notion.preparing": "Préparation pour l'exportation vers Notion...", + "mention.title": "Changer le modèle de réponse", + "message.code_style": "Style de code", + "message.delete.content": "Êtes-vous sûr de vouloir supprimer ce message?", + "message.delete.title": "Supprimer le message", + "message.multi_model_style": "Style de réponse multi-modèle", + "message.multi_model_style.fold": "Mode étiquette", + "message.multi_model_style.fold.compress": "Basculer vers une disposition compacte", + "message.multi_model_style.fold.expand": "Basculer vers une disposition détaillée", + "message.multi_model_style.grid": "Disposition en carte", + "message.multi_model_style.horizontal": "Disposition horizontale", + "message.multi_model_style.vertical": "Disposition verticale", + "message.style": "Style du message", + "message.style.bubble": "Bulles", + "message.style.plain": "Simplifié", + "regenerate.confirm": "La régénération va remplacer le message actuel", + "reset.confirm.content": "Êtes-vous sûr de vouloir réinitialiser toutes les données?", + "reset.double.confirm.content": "Toutes vos données seront perdues, si aucune sauvegarde n'a été effectuée, elles ne pourront pas être récupérées. Êtes-vous sûr de vouloir continuer?", + "reset.double.confirm.title": "Perte de données!!!", + "restore.failed": "La restauration a échoué", + "restore.success": "La restauration a réussi", + "save.success.title": "Enregistrement réussi", + "searching": "Recherche en ligne en cours...", + "success.joplin.export": "Exportation réussie vers Joplin", + "success.markdown.export.preconf": "Exportation réussie vers un fichier Markdown dans le chemin prédéfini", + "success.markdown.export.specified": "Exportation réussie vers un fichier Markdown", + "success.notion.export": "Exportation réussie vers Notion", + "success.yuque.export": "Exportation réussie vers Yuque", + "switch.disabled": "Veuillez attendre la fin de la réponse actuelle avant de procéder", + "tools": { + "completed": "Terminé", + "invoking": "En cours d'exécution" + }, + "topic.added": "Thème ajouté avec succès", + "upgrade.success.button": "Redémarrer", + "upgrade.success.content": "Redémarrez pour finaliser la mise à jour", + "upgrade.success.title": "Mise à jour réussie", + "warn.notion.exporting": "Exportation en cours vers Notion, veuillez ne pas faire plusieurs demandes d'exportation!", + "warning.rate.limit": "Vous envoyez trop souvent, veuillez attendre {{seconds}} secondes avant de réessayer" + }, + "minapp": { + "sidebar.add.title": "Ajouter à la barre latérale", + "sidebar.remove.title": "Supprimer de la barre latérale", + "title": "Mini-programme" + }, + "miniwindow": { + "clipboard": { + "empty": "Presse-papiers vide" + }, + "feature": { + "chat": "Répondre à cette question", + "explanation": "Explication", + "summary": "Résumé du contenu", + "translate": "Traduction de texte" + }, + "footer": { + "copy_last_message": "Appuyez sur C pour copier", + "esc": "Appuyez sur ESC {{action}}", + "esc_back": "Revenir en arrière", + "esc_close": "Fermer la fenêtre" + }, + "input": { + "placeholder": { + "empty": "Demander à {{model}} pour obtenir de l'aide...", + "title": "Que souhaitez-vous faire avec le texte ci-dessous" + } + } + }, + "models": { + "add_parameter": "Ajouter un paramètre", + "all": "Tout", + "custom_parameters": "Paramètres personnalisés", + "dimensions": "{{dimensions}} dimensions", + "edit": "Éditer le modèle", + "embedding": "Incrustation", + "embedding_model": "Modèle d'incrustation", + "embedding_model_tooltip": "Cliquez sur le bouton Gérer dans Paramètres -> Services de modèles pour ajouter", + "function_calling": "Appel de fonction", + "no_matches": "Aucun modèle disponible", + "parameter_name": "Nom du paramètre", + "parameter_type": { + "boolean": "Valeur booléenne", + "json": "JSON", + "number": "Chiffre", + "string": "Texte" + }, + "pinned": "Épinglé", + "rerank_model": "Modèle de réordonnancement", + "rerank_model_support_provider": "Le modèle de réordonnancement ne prend actuellement en charge que certains fournisseurs ({{provider}})", + "rerank_model_tooltip": "Cliquez sur le bouton Gérer dans Paramètres -> Services de modèles pour ajouter", + "search": "Rechercher un modèle...", + "stream_output": "Sortie en flux", + "type": { + "embedding": "Incorporation", + "function_calling": "Appel de fonction", + "reasoning": "Raisonnement", + "select": "Sélectionnez le type de modèle", + "text": "Texte", + "vision": "Image", + "free": "Gratuit", + "rerank": "Reclasser", + "websearch": "Recherche web" + } + }, + "navbar": { + "expand": "Agrandir la boîte de dialogue", + "hide_sidebar": "Cacher la barre latérale", + "show_sidebar": "Afficher la barre latérale" + }, + "ollama": { + "keep_alive_time.description": "Le temps pendant lequel le modèle reste en mémoire après la conversation (par défaut : 5 minutes)", + "keep_alive_time.placeholder": "minutes", + "keep_alive_time.title": "Temps de maintien actif", + "title": "Ollama" + }, + "paintings": { + "button.delete.image": "Supprimer l'image", + "button.delete.image.confirm": "Êtes-vous sûr de vouloir supprimer cette image?", + "button.new.image": "Nouvelle image", + "guidance_scale": "Échelle de guidance", + "guidance_scale_tip": "Aucune guidance du classificateur. Contrôle le niveau d'obéissance du modèle aux mots-clés lors de la recherche d'images pertinentes", + "image.size": "Taille de l'image", + "inference_steps": "Étapes d'inférence", + "inference_steps_tip": "Nombre d'étapes d'inférence à effectuer. Plus il y a d'étapes, meilleure est la qualité mais plus c'est long", + "negative_prompt": "Prompt négatif", + "negative_prompt_tip": "Décrivez ce que vous ne voulez pas voir dans l'image", + "number_images": "Nombre d'images générées", + "number_images_tip": "Le nombre d'images générées en une seule fois (1-4)", + "prompt_enhancement": "Amélioration des prompts", + "prompt_enhancement_tip": "Activez pour réécrire le prompt en une version détaillée et adaptée au modèle", + "prompt_placeholder": "Décrivez l'image que vous souhaitez créer, par exemple : un lac paisible, le soleil couchant, avec des montagnes à l'horizon", + "regenerate.confirm": "Cela va remplacer les images générées, voulez-vous continuer?", + "seed": "Graine aléatoire", + "seed_tip": "La même graine et le même prompt peuvent générer des images similaires", + "title": "Image" + }, + "plantuml": { + "download": { + "failed": "Échec du téléchargement, veuillez vérifier votre connexion Internet", + "png": "Télécharger PNG", + "svg": "Télécharger SVG" + }, + "tabs": { + "preview": "Aperçu", + "source": "Code source" + }, + "title": "Diagramme PlantUML" + }, + "prompts": { + "explanation": "Aidez-moi à expliquer ce concept", + "summarize": "Aidez-moi à résumer ce passage", + "title": "Vous êtes un assistant conversant. Résumez la conversation de l'utilisateur en un titre de 10 mots ou moins. La langue du titre doit correspondre à la langue principale de l'utilisateur, sans utiliser de ponctuation ni de symboles spéciaux" + }, + "provider": { + "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", + "anthropic": "Anthropic", + "azure-openai": "Azure OpenAI", + "baichuan": "BaiChuan", + "baidu-cloud": "Baidu Cloud Qianfan", + "copilot": "GitHub Copilote", + "dashscope": "AliCloud BaiLian", + "deepseek": "DeepSeek", + "dmxapi": "DMXAPI", + "doubao": "Huoshan Engine", + "fireworks": "Fireworks", + "gemini": "Gemini", + "gitee-ai": "Gitee IA", + "github": "GitHub Modèles", + "gpustack": "GPUStack", + "graphrag-kylin-mountain": "GraphRAG", + "grok": "Grok", + "groq": "Groq", + "hunyuan": "Tencent HunYuan", + "hyperbolic": "Hyperbolique", + "infini": "Sans Frontières Céleste", + "jina": "Jina", + "lmstudio": "Studio LM", + "minimax": "MiniMax", + "mistral": "Mistral", + "modelscope": "ModelScope MoDa", + "moonshot": "Face Sombre de la Lune", + "nvidia": "NVIDIA", + "o3": "O3", + "ocoolai": "ocoolIA", + "ollama": "Ollama", + "openai": "OpenAI", + "openrouter": "OpenRouter", + "perplexity": "Perplexité", + "ppio": "PPIO Cloud Piou", + "qwenlm": "QwenLM", + "silicon": "Silicium Fluide", + "stepfun": "Échelon Étoile", + "tencent-cloud-ti": "Tencent Cloud TI", + "together": "Ensemble", + "xirang": "CTyun XiRang", + "yi": "ZéroUnInfini", + "zhinao": "360 ZhiNao", + "zhipu": "ZhiPu IA" + }, + "restore": { + "confirm": "Êtes-vous sûr de vouloir restaurer les données ?", + "confirm.button": "Sélectionnez le fichier de sauvegarde", + "content": "L'opération de restauration va utiliser les données de sauvegarde pour remplacer toutes les données d'applications actuelles. Veuillez noter que le processus de restauration peut prendre un certain temps. Merci de votre patience.", + "progress": { + "completed": "Restauration terminée", + "copying_files": "Copie des fichiers... {{progress}}%", + "extracting": "Décompression de la sauvegarde...", + "preparing": "Préparation de la restauration...", + "reading_data": "Lecture des données...", + "title": "Progression de la restauration" + }, + "title": "Restauration des données" + }, + "settings": { + "about": "À propos de nous", + "about.checkingUpdate": "Vérification des mises à jour en cours...", + "about.checkUpdate": "Vérifier les mises à jour", + "about.checkUpdate.available": "Mettre à jour maintenant", + "about.contact.button": "Courriel", + "about.contact.title": "Contactez-nous par courriel", + "about.description": "Un assistant IA conçu pour les créateurs", + "about.downloading": "Téléchargement de la mise à jour en cours...", + "about.feedback.button": "Faire un retour", + "about.feedback.title": "Retour d'information", + "about.license.button": "Afficher", + "about.license.title": "Licence", + "about.releases.button": "Afficher", + "about.releases.title": "Journal des mises à jour", + "about.social.title": "Comptes sociaux", + "about.title": "À propos de nous", + "about.updateAvailable": "Nouvelle version disponible {{version}}", + "about.updateError": "Erreur lors de la mise à jour", + "about.updateNotAvailable": "Votre logiciel est déjà à jour", + "about.website.button": "Visiter le site web", + "about.website.title": "Site web officiel", + "advanced.auto_switch_to_topics": "Basculer automatiquement vers les sujets", + "advanced.title": "Paramètres avancés", + "assistant": "Assistant par défaut", + "assistant.model_params": "Paramètres du modèle", + "assistant.show.icon": "Afficher l'icône du modèle", + "assistant.title": "Assistant par défaut", + "data": { + "app_data": "Données de l'application", + "app_knowledge": "Fichier de base de connaissances", + "app_knowledge.button.delete": "Supprimer le fichier", + "app_knowledge.remove_all": "Supprimer les fichiers de la base de connaissances", + "app_knowledge.remove_all_confirm": "La suppression des fichiers de la base de connaissances libérera de l'espace de stockage, mais ne supprimera pas les données vectorisées de la base de connaissances. Après la suppression, vous ne pourrez plus ouvrir les fichiers sources. Souhaitez-vous continuer ?", + "app_knowledge.remove_all_success": "Fichiers supprimés avec succès", + "app_logs": "Journaux de l'application", + "clear_cache": { + "button": "Effacer le cache", + "confirm": "L'effacement du cache supprimera les données du cache de l'application, y compris les données des mini-programmes. Cette action ne peut pas être annulée, voulez-vous continuer ?", + "error": "Échec de l'effacement du cache", + "success": "Le cache a été effacé avec succès", + "title": "Effacer le cache" + }, + "data.title": "Répertoire des données", + "hour_interval_one": "{{count}} heure", + "hour_interval_other": "{{count}} heures", + "joplin": { + "check": { + "button": "Vérifier", + "empty_token": "Veuillez d'abord entrer le jeton d'autorisation Joplin", + "empty_url": "Veuillez d'abord entrer l'URL de surveillance du service de découpage Joplin", + "fail": "La validation de la connexion Joplin a échoué", + "success": "La validation de la connexion Joplin a réussi" + }, + "help": "Dans les options de Joplin, activez le service de découpage de pages web (pas besoin d'installer une extension de navigateur), confirmez le numéro de port et copiez le jeton d'autorisation", + "title": "Configuration de Joplin", + "token": "Jeton d'autorisation de Joplin", + "token_placeholder": "Veuillez entrer le jeton d'autorisation de Joplin", + "url": "URL surveillée par le service de découpage de Joplin", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "Lorsque cette option est activée, l'exportation en Markdown utilisera $$ pour marquer les formules LaTeX. Note : Cette option affecte également toutes les méthodes d'exportation en Markdown, comme Notion, YuQue, etc.", + "markdown_export.force_dollar_math.title": "Forcer l'utilisation de $$ pour marquer les formules LaTeX", + "markdown_export.help": "Si rempli, les exports seront automatiquement sauvegardés à ce chemin ; sinon, une boîte de dialogue de sauvegarde s'affichera.", + "markdown_export.path": "Chemin d'exportation par défaut", + "markdown_export.path_placeholder": "Chemin d'exportation", + "markdown_export.select": "Sélectionner", + "markdown_export.title": "Exporter en Markdown", + "minute_interval_one": "{{count}} minute", + "minute_interval_other": "{{count}} minutes", + "notion.api_key": "Clé API Notion", + "notion.api_key_placeholder": "Veuillez entrer votre clé API Notion", + "notion.auto_split": "Division automatique lors de l'exportation des conversations", + "notion.auto_split_tip": "Divise automatiquement les sujets longs en plusieurs pages lors de l'exportation vers Notion", + "notion.check": { + "button": "Vérifier", + "empty_api_key": "Clé API non configurée", + "empty_database_id": "ID de la base de données non configuré", + "error": "Anomalie de connexion, veuillez vérifier votre réseau et si la clé API et l'ID de la base de données sont corrects", + "fail": "Échec de la connexion, veuillez vérifier votre réseau et si la clé API et l'ID de la base de données sont corrects", + "success": "Connexion réussie" + }, + "notion.database_id": "ID de la base de données Notion", + "notion.database_id_placeholder": "Veuillez entrer l'ID de la base de données Notion", + "notion.help": "Documentation de configuration Notion", + "notion.page_name_key": "Nom du champ du titre de la page", + "notion.page_name_key_placeholder": "Veuillez entrer le nom du champ du titre de la page, par défaut Name", + "notion.split_size": "Taille de la division automatique", + "notion.split_size_help": "Les utilisateurs gratuits de Notion sont invités à définir cette valeur à 90, tandis que les utilisateurs premium sont invités à définir cette valeur à 24990. La valeur par défaut est de 90.", + "notion.split_size_placeholder": "Veuillez entrer la limite de blocs par page (par défaut 90)", + "notion.title": "Configuration Notion", + "obsidian": { + "folder": "Dossier", + "folder_placeholder": "Veuillez entrer le nom du dossier", + "tags": "Étiquettes globales", + "tags_placeholder": "Veuillez entrer le nom de l'étiquette, plusieurs étiquettes sont séparées par une virgule anglaise, Obsidian ne peut pas utiliser uniquement des chiffres", + "title": "Configuration d'Obsidian", + "vault": "Coffre-fort", + "vault_placeholder": "Veuillez entrer le nom du coffre-fort" + }, + "title": "Paramètres des données", + "webdav": { + "autoSync": "Synchronisation automatique", + "autoSync.off": "Désactiver", + "backup.button": "Sauvegarder sur WebDAV", + "backup.modal.filename.placeholder": "Entrez le nom du fichier de sauvegarde", + "backup.modal.title": "Sauvegarder sur WebDAV", + "host": "Adresse WebDAV", + "host.placeholder": "http://localhost:8080", + "hour_interval_one": "{{count}} heure", + "hour_interval_other": "{{count}} heures", + "lastSync": "Dernière sauvegarde", + "minute_interval_one": "{{count}} minute", + "minute_interval_other": "{{count}} minutes", + "noSync": "Attendre la prochaine sauvegarde", + "password": "Mot de passe WebDAV", + "path": "Chemin WebDAV", + "path.placeholder": "/backup", + "restore.button": "Restaurer depuis WebDAV", + "restore.confirm.content": "La restauration depuis WebDAV écrasera les données actuelles, voulez-vous continuer ?", + "restore.confirm.title": "Confirmer la restauration", + "restore.content": "La restauration depuis WebDAV écrasera les données actuelles, voulez-vous continuer ?", + "restore.modal.select.placeholder": "Sélectionnez le fichier de sauvegarde à restaurer", + "restore.modal.title": "Restaurer depuis WebDAV", + "restore.title": "Restaurer depuis WebDAV", + "syncError": "Erreur de sauvegarde", + "syncStatus": "Statut de la sauvegarde", + "title": "WebDAV", + "user": "Nom d'utilisateur WebDAV" + }, + "yuque": { + "check": { + "button": "Vérifier", + "empty_repo_url": "Veuillez d'abord saisir l'URL de la base de connaissances", + "empty_token": "Veuillez d'abord saisir le Token Yuyuè", + "fail": "La validation de la connexion Yuyuè a échoué", + "success": "La validation de la connexion Yuyuè a réussi" + }, + "help": "Obtenir le Token Yuque", + "repo_url": "URL de la base de connaissances", + "repo_url_placeholder": "https://www.yuque.com/nom_utilisateur/xxx", + "title": "Configuration Yuque", + "token": "Token Yuque", + "token_placeholder": "Veuillez entrer le Token Yuque" + } + }, + "display.assistant.title": "Paramètres de l'assistant", + "display.custom.css": "CSS personnalisé", + "display.custom.css.cherrycss": "Obtenir depuis cherrycss.com", + "display.custom.css.placeholder": "/* Écrire votre CSS personnalisé ici */", + "display.minApp.disabled": "Applications minimisées masquées", + "display.minApp.empty": "Glissez les applications minimisées à masquer ici", + "display.minApp.title": "Paramètres d'affichage des applications minimisées", + "display.minApp.visible": "Applications minimisées affichées", + "display.sidebar.chat.hiddenMessage": "L'assistant est une fonction de base et ne peut pas être masquée", + "display.sidebar.disabled": "Icônes masquées", + "display.sidebar.empty": "Glissez les fonctions à masquer ici", + "display.sidebar.files.icon": "Afficher l'icône des fichiers", + "display.sidebar.knowledge.icon": "Afficher l'icône des connaissances", + "display.sidebar.minapp.icon": "Afficher l'icône des applications minimisées", + "display.sidebar.painting.icon": "Afficher l'icône de peinture", + "display.sidebar.title": "Paramètres de la barre latérale", + "display.sidebar.translate.icon": "Afficher l'icône de traduction", + "display.sidebar.visible": "Icônes affichées", + "display.title": "Paramètres d'affichage", + "display.topic.title": "Paramètres de sujet", + "font_size.title": "Taille de police des messages", + "general": "Paramètres généraux", + "general.avatar.reset": "Réinitialiser l'avatar", + "general.backup.button": "Sauvegarder", + "general.backup.title": "Sauvegarde et restauration des données", + "general.display.title": "Paramètres d'affichage", + "general.emoji_picker": "Sélectionneur d'émoticônes", + "general.image_upload": "Téléchargement d'images", + "general.manually_check_update.title": "Désactiver la vérification des mises à jour", + "general.reset.button": "Réinitialiser", + "general.reset.title": "Réinitialiser les données", + "general.restore.button": "Restaurer", + "general.title": "Paramètres généraux", + "general.user_name": "Nom d'utilisateur", + "general.user_name.placeholder": "Entrez votre nom d'utilisateur", + "general.view_webdav_settings": "Voir les paramètres WebDAV", + "input.auto_translate_with_space": "Traduire en frappant rapidement 3 fois l'espace", + "input.target_language": "Langue cible", + "input.target_language.chinese": "Chinois simplifié", + "input.target_language.chinese-traditional": "Chinois traditionnel", + "input.target_language.english": "Anglais", + "input.target_language.japanese": "Japonais", + "input.target_language.russian": "Russe", + "launch.onboot": "Démarrer automatiquement au démarrage", + "launch.title": "Démarrage", + "launch.totray": "Minimiser dans la barre d'état système au démarrage", + "mcp": { + "actions": "Actions", + "active": "Activer", + "addError": "Échec de l'ajout du serveur", + "addServer": "Ajouter un serveur", + "addSuccess": "Serveur ajouté avec succès", + "args": "Arguments", + "argsTooltip": "Chaque argument sur une ligne", + "baseUrlTooltip": "Adresse URL distante", + "command": "Commande", + "commandRequired": "Veuillez entrer une commande", + "config_description": "Configurer le modèle du protocole de contexte du serveur", + "confirmDelete": "Supprimer le serveur", + "confirmDeleteMessage": "Êtes-vous sûr de vouloir supprimer ce serveur ?", + "deleteError": "Échec de la suppression du serveur", + "deleteSuccess": "Serveur supprimé avec succès", + "dependenciesInstall": "Installer les dépendances", + "dependenciesInstalling": "Installation des dépendances en cours...", + "description": "Description", + "duplicateName": "Un serveur portant le même nom existe déjà", + "editJson": "Modifier le JSON", + "editServer": "Modifier le serveur", + "env": "Variables d'environnement", + "envTooltip": "Format : CLÉ=valeur, une par ligne", + "findMore": "Plus de serveurs MCP", + "install": "Installer", + "installError": "Échec de l'installation des dépendances", + "installSuccess": "Dépendances installées avec succès", + "jsonFormatError": "Erreur de format JSON", + "jsonModeHint": "Modifier la représentation JSON de la configuration des serveurs MCP. Assurez-vous que le format est correct avant de sauvegarder.", + "jsonSaveError": "Échec de la sauvegarde de la configuration JSON", + "jsonSaveSuccess": "Configuration JSON sauvegardée", + "missingDependencies": "Manquantes, veuillez les installer pour continuer", + "name": "Nom", + "nameRequired": "Veuillez entrer le nom du serveur", + "noServers": "Aucun serveur configuré", + "npx_list": { + "actions": "Actions", + "desc": "Rechercher et ajouter un package npm en tant que service MCP", + "description": "Description", + "no_packages": "Aucun package trouvé", + "npm": "NPM", + "package_name": "Nom du package", + "scope_placeholder": "Entrez le scope npm (par exemple @votre-org)", + "scope_required": "Veuillez entrer le scope npm", + "search": "Rechercher", + "search_error": "La recherche a échoué", + "title": "Liste des packages NPX", + "usage": "Utilisation", + "version": "Version" + }, + "serverPlural": "Serveurs", + "serverSingular": "Serveur", + "title": "Serveurs MCP", + "toggleError": "Échec du basculement", + "type": "Type", + "updateError": "Échec de la mise à jour du serveur", + "updateSuccess": "Serveur mis à jour avec succès", + "url": "URL" + }, + "messages.divider": "Séparateur de messages", + "messages.grid_columns": "Nombre de colonnes de la grille de messages", + "messages.grid_popover_trigger": "Déclencheur de popover de la grille", + "messages.grid_popover_trigger.click": "Afficher au clic", + "messages.grid_popover_trigger.hover": "Afficher au survol", + "messages.input.paste_long_text_as_file": "Coller le texte long sous forme de fichier", + "messages.input.paste_long_text_threshold": "Seuil de longueur de texte", + "messages.input.send_shortcuts": "Raccourcis d'envoi", + "messages.input.show_estimated_tokens": "Afficher le nombre estimatif de tokens", + "messages.input.title": "Paramètres d'entrée", + "messages.markdown_rendering_input_message": "Rendu Markdown des messages d'entrée", + "messages.math_engine": "Moteur de formules mathématiques", + "messages.metrics": "Latence initiale {{time_first_token_millsec}}ms | Vitesse de tokenisation {{token_speed}} tokens/s", + "messages.model.title": "Paramètres du modèle", + "messages.navigation": "Bouton de navigation des conversations", + "messages.navigation.anchor": "Ancre de conversation", + "messages.navigation.buttons": "Boutons haut/bas", + "messages.navigation.none": "Ne pas afficher", + "messages.title": "Paramètres des messages", + "messages.use_serif_font": "Utiliser une police serif", + "model": "Modèle par défaut", + "models.add.add_model": "Ajouter un modèle", + "models.add.group_name": "Nom du groupe", + "models.add.group_name.placeholder": "Par exemple, ChatGPT", + "models.add.group_name.tooltip": "Par exemple, ChatGPT", + "models.add.model_id": "ID du modèle", + "models.add.model_id.placeholder": "Obligatoire, par exemple gpt-3.5-turbo", + "models.add.model_id.tooltip": "Par exemple, gpt-3.5-turbo", + "models.add.model_name": "Nom du modèle", + "models.add.model_name.placeholder": "Par exemple, GPT-3.5", + "models.check.all": "Tous", + "models.check.all_models_passed": "Tous les modèles ont passé les tests", + "models.check.button_caption": "Test de santé", + "models.check.disabled": "Désactivé", + "models.check.enable_concurrent": "Activer les tests simultanés", + "models.check.enabled": "Activé", + "models.check.failed": "Échec", + "models.check.keys_status_count": "Passé : {{count_passed}} clés, échoué : {{count_failed}} clés", + "models.check.model_status_summary": "{{provider}} : {{count_passed}} modèles ont passé le test de santé ({{count_partial}} modèles ne sont pas accessibles avec certains clés), {{count_failed}} modèles ne sont pas accessibles.", + "models.check.no_api_keys": "Aucune clé API trouvée, veuillez en ajouter une première.", + "models.check.passed": "Passé", + "models.check.select_api_key": "Sélectionner la clé API à utiliser :", + "models.check.single": "Unique", + "models.check.start": "Commencer", + "models.check.title": "Test de santé des modèles", + "models.check.use_all_keys": "Utiliser toutes les clés", + "models.default_assistant_model": "Modèle d'assistant par défaut", + "models.default_assistant_model_description": "Modèle utilisé pour créer de nouveaux assistants, si aucun modèle n'est défini pour l'assistant, ce modèle sera utilisé", + "models.empty": "Aucun modèle", + "models.enable_topic_naming": "Renommage automatique des sujets", + "models.manage.add_whole_group": "Ajouter tout le groupe", + "models.manage.remove_whole_group": "Supprimer tout le groupe", + "models.topic_naming_model": "Modèle de renommage des sujets", + "models.topic_naming_model_description": "Modèle utilisé pour le renommage automatique des nouveaux sujets", + "models.topic_naming_model_setting_title": "Paramètres du modèle de renommage des sujets", + "models.topic_naming_prompt": "Mot-clé de renommage des sujets", + "models.translate_model": "Modèle de traduction", + "models.translate_model_description": "Modèle utilisé pour le service de traduction", + "models.translate_model_prompt_message": "Entrez le mot-clé du modèle de traduction", + "models.translate_model_prompt_title": "Mot-clé du modèle de traduction", + "moresetting": "Paramètres supplémentaires", + "moresetting.check.confirm": "Confirmer la sélection", + "moresetting.check.warn": "Veuillez faire preuve de prudence en cochant cette option, une sélection incorrecte peut rendre le modèle inutilisable !!!", + "moresetting.warn": "Avertissement de risque", + "provider": { + "add.name": "Nom du fournisseur", + "add.name.placeholder": "Par exemple OpenAI", + "add.title": "Ajouter un fournisseur", + "add.type": "Type de fournisseur", + "api.url.preview": "Aperçu : {{url}}", + "api.url.reset": "Réinitialiser", + "api.url.tip": "Ignorer la version v1 si terminé par /, forcer l'utilisation de l'adresse d'entrée si terminé par #", + "api_host": "Adresse API", + "api_key": "Clé API", + "api_key.tip": "Séparer les clés multiples par des virgules", + "api_version": "Version API", + "charge": "Recharger", + "check": "Vérifier", + "check_all_keys": "Vérifier toutes les clés", + "check_multiple_keys": "Vérifier plusieurs clés API", + "copilot": { + "auth_failed": "Échec de l'authentification Github Copilot", + "auth_success": "Authentification Github Copilot réussie", + "auth_success_title": "Authentification réussie", + "code_failed": "Échec de l'obtention du code Device, veuillez réessayer", + "code_generated_desc": "Veuillez copier le code Device dans le lien du navigateur ci-dessous", + "code_generated_title": "Obtenir le code Device", + "confirm_login": "L'utilisation excessive peut entraîner la suspension de votre compte Github, utilisez avec prudence!!!!", + "confirm_title": "Avertissement de risque", + "connect": "Connectez-vous à Github", + "custom_headers": "Entêtes de requête personnalisées", + "description": "Votre compte Github doit souscrire à Copilot", + "expand": "Développer", + "headers_description": "Entêtes de requête personnalisées (format json)", + "invalid_json": "Format JSON incorrect", + "login": "Se connecter à Github", + "logout": "Déconnexion de Github", + "logout_failed": "Échec de la déconnexion, veuillez réessayer", + "logout_success": "Déconnexion réussie", + "model_setting": "Paramètres du modèle", + "open_verification_first": "Cliquez d'abord sur le lien ci-dessus pour accéder à la page de vérification", + "rate_limit": "Limite de taux", + "tooltip": "Pour utiliser Github Copilot, vous devez vous connecter à Github" + }, + "delete.content": "Êtes-vous sûr de vouloir supprimer ce fournisseur de modèles ?", + "delete.title": "Supprimer le fournisseur", + "docs_check": "Voir", + "docs_more_details": "Obtenir plus de détails", + "get_api_key": "Cliquez ici pour obtenir une clé", + "is_not_support_array_content": "Activer le mode compatible", + "no_models": "Veuillez ajouter un modèle avant de vérifier la connexion API", + "not_checked": "Non vérifié", + "remove_duplicate_keys": "Supprimer les clés en double", + "remove_invalid_keys": "Supprimer les clés invalides", + "search": "Rechercher une plateforme de modèles...", + "search_placeholder": "Rechercher un ID ou un nom de modèle", + "title": "Services de modèles" + }, + "proxy": { + "mode": { + "custom": "Proxy personnalisé", + "none": "Ne pas utiliser de proxy", + "system": "Proxy système", + "title": "Mode de proxy" + }, + "title": "Paramètres du proxy" + }, + "proxy.title": "Adresse proxy", + "quickAssistant": { + "click_tray_to_show": "Cliquez sur l'icône dans la barre d'état système pour démarrer", + "enable_quick_assistant": "Activer l'assistant rapide", + "read_clipboard_at_startup": "Lire le presse-papiers au démarrage", + "title": "Assistant Rapide", + "use_shortcut_to_show": "Cliquez avec le bouton droit sur l'icône dans la barre d'état système ou utilisez un raccourci clavier pour démarrer" + }, + "shortcuts": { + "action": "Action", + "clear_shortcut": "Effacer raccourci clavier", + "clear_topic": "Vider les messages", + "copy_last_message": "Copier le dernier message", + "key": "Touche", + "mini_window": "Assistant rapide", + "new_topic": "Nouveau sujet", + "press_shortcut": "Appuyer sur raccourci clavier", + "reset_defaults": "Réinitialiser raccourcis par défaut", + "reset_defaults_confirm": "Êtes-vous sûr de vouloir réinitialiser tous les raccourcis clavier ?", + "reset_to_default": "Réinitialiser aux valeurs par défaut", + "search_message": "Rechercher un message", + "show_app": "Afficher l'application", + "show_settings": "Ouvrir les paramètres", + "title": "Raccourcis", + "toggle_new_context": "Effacer le contexte", + "toggle_show_assistants": "Basculer l'affichage des assistants", + "toggle_show_topics": "Basculer l'affichage des sujets", + "zoom_in": "Agrandir l'interface", + "zoom_out": "Réduire l'interface", + "zoom_reset": "Réinitialiser le zoom" + }, + "theme.auto": "Automatique", + "theme.dark": "Sombre", + "theme.light": "Clair", + "theme.title": "Thème", + "theme.window.style.opaque": "Fenêtre opaque", + "theme.window.style.title": "Style de fenêtre", + "theme.window.style.transparent": "Fenêtre transparente", + "title": "Paramètres", + "topic.position": "Position du sujet", + "topic.position.left": "Gauche", + "topic.position.right": "Droite", + "topic.show.time": "Afficher l'heure du sujet", + "tray.onclose": "Minimiser dans la barre d'état système lors de la fermeture", + "tray.show": "Afficher l'icône dans la barre d'état système", + "tray.title": "Barre d'état système", + "websearch": { + "blacklist": "Liste noire", + "blacklist_description": "Les résultats des sites web suivants ne s'afficheront pas dans les résultats de recherche", + "blacklist_tooltip": "Veuillez utiliser le format suivant (séparé par des retours à la ligne)\"network.comnhttps://www.example.comnhttps://example.comn*://*.example.com", + "check": "Vérifier", + "check_failed": "Échec de la vérification", + "check_success": "Vérification réussie", + "enhance_mode": "Mode de recherche amélioré", + "enhance_mode_tooltip": "Utilisez le modèle par défaut pour extraire les mots-clés avant de rechercher", + "get_api_key": "Cliquez ici pour obtenir la clé", + "no_provider_selected": "Veuillez sélectionner un fournisseur de recherche avant de vérifier", + "search_max_result": "Nombre de résultats de recherche", + "search_provider": "Fournisseur de recherche", + "search_provider_placeholder": "Sélectionnez un fournisseur de recherche", + "search_result_default": "Par défaut", + "search_with_time": "Recherche avec date", + "tavily": { + "api_key": "Clé API Tavily", + "api_key.placeholder": "Veuillez entrer la clé API Tavily", + "description": "Tavily est un moteur de recherche conçu spécifiquement pour les agents IA, offrant des résultats en temps réel, précis, des suggestions de requêtes intelligentes et des capacités de recherche approfondie", + "title": "Tavily" + }, + "title": "Recherche sur Internet" + } + }, + "translate": { + "any.language": "langue arbitraire", + "button.translate": "traduire", + "close": "fermer", + "confirm": { + "content": "La traduction remplacera le texte original, voulez-vous continuer ?", + "title": "Confirmation de traduction" + }, + "error.failed": "échec de la traduction", + "error.not_configured": "le modèle de traduction n'est pas configuré", + "history": { + "clear": "Effacer l'historique", + "clear_description": "L'effacement de l'historique supprimera toutes les entrées d'historique de traduction, voulez-vous continuer ?", + "delete": "Supprimer", + "empty": "Aucun historique de traduction pour le moment", + "title": "Historique des traductions" + }, + "input.placeholder": "entrez le texte à traduire", + "output.placeholder": "traduction", + "processing": "en cours de traduction...", + "scroll_sync.disable": "désactiver la synchronisation du défilement", + "scroll_sync.enable": "activer la synchronisation du défilement", + "title": "traduction", + "tooltip.newline": "saut de ligne" + }, + "tray": { + "quit": "Quitter", + "show_mini_window": "Assistant Rapide", + "show_window": "Afficher la fenêtre" + }, + "words": { + "knowledgeGraph": "Graphe de connaissances", + "quit": "Quitter", + "show_window": "Afficher la fenêtre", + "visualization": "Visualisation" + } + } +} diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json new file mode 100644 index 000000000..6d520a88e --- /dev/null +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -0,0 +1,1173 @@ +{ + "translation": { + "agents": { + "add.button": "Adicionar ao Assistente", + "add.knowledge_base": "Base de Conhecimento", + "add.knowledge_base.placeholder": "Selecione a Base de Conhecimento", + "add.name": "Nome", + "add.name.placeholder": "Digite o Nome", + "add.prompt": "Prompt", + "add.prompt.placeholder": "Digite o Prompt", + "add.title": "Criar Agente Inteligente", + "delete.popup.content": "Tem certeza de que deseja excluir este agente inteligente?", + "edit.message.add.title": "Adicionar", + "edit.message.assistant.placeholder": "Digite a Mensagem do Assistente", + "edit.message.assistant.title": "Assistente", + "edit.message.empty.content": "O conteúdo da sessão não pode estar vazio", + "edit.message.group.title": "Grupo de Mensagens", + "edit.message.title": "Mensagens Padrão", + "edit.message.user.placeholder": "Digite a Mensagem do Usuário", + "edit.message.user.title": "Usuário", + "edit.model.select.title": "Selecionar Modelo", + "edit.settings.hide_preset_messages": "Ocultar Mensagens Padrão", + "edit.title": "Editar Agente Inteligente", + "manage.title": "Gerenciar Agentes Inteligentes", + "my_agents": "Meus Agentes Inteligentes", + "search.no_results": "Nenhum agente inteligente encontrado", + "sorting.title": "Ordenação", + "tag.agent": "Agente", + "tag.default": "Padrão", + "tag.new": "Novo", + "tag.system": "Sistema", + "title": "Agente" + }, + "assistants": { + "abbr": "Assistente", + "clear.content": "Limpar o tópico removerá todos os tópicos e arquivos do assistente. Tem certeza de que deseja continuar?", + "clear.title": "Limpar Tópico", + "copy.title": "Copiar Assistente", + "delete.content": "Excluir o assistente removerá todos os tópicos e arquivos sob esse assistente. Tem certeza de que deseja continuar?", + "delete.title": "Excluir Assistente", + "edit.title": "Editar Assistente", + "save.success": "Salvo com Sucesso", + "save.title": "Salvar para Agente Inteligente", + "search": "Pesquisar Assistente", + "settings.default_model": "Modelo Padrão", + "settings.knowledge_base": "Configurações da Base de Conhecimento", + "settings.model": "Configurações do Modelo", + "settings.preset_messages": "Mensagens Pré-definidas", + "settings.prompt": "Configurações de Prompt", + "settings.reasoning_effort": "Comprimento da Cadeia de Raciocínio", + "settings.reasoning_effort.high": "Longo", + "settings.reasoning_effort.low": "Curto", + "settings.reasoning_effort.medium": "Médio", + "settings.reasoning_effort.off": "Desligado", + "settings.reasoning_effort.tip": "Apenas suporta modelos de raciocínio OpenAI o-series e Anthropic", + "title": "Assistente" + }, + "auth": { + "error": "Falha ao obter a chave automaticamente, por favor obtenha manualmente", + "get_key": "Obter", + "get_key_success": "Obtenção automática da chave bem-sucedida", + "login": "Entrar", + "oauth_button": "Entrar com {{provider}}" + }, + "backup": { + "confirm": "Tem certeza de que deseja fazer backup dos dados?", + "confirm.button": "Escolher local de backup", + "content": "Fazer backup de todos os dados, incluindo registros de chat, configurações, base de conhecimento e todos os outros dados. Por favor, note que o processo de backup pode levar algum tempo. Agradecemos sua paciência.", + "progress": { + "completed": "Backup concluído", + "compressing": "Comprimindo arquivo...", + "copying_files": "Copiando arquivos... {{progress}}%", + "preparing": "Preparando backup...", + "title": "Progresso do Backup", + "writing_data": "Escrevendo dados..." + }, + "title": "Backup de Dados" + }, + "button": { + "add": "Adicionar", + "added": "Adicionado", + "collapse": "Recolher", + "manage": "Gerenciar", + "select_model": "Selecionar Modelo", + "show.all": "Mostrar tudo", + "update_available": "Atualização disponível" + }, + "chat": { + "add.assistant.title": "Adicionar assistente", + "artifacts.button.download": "Baixar", + "artifacts.button.openExternal": "Abrir em navegador externo", + "artifacts.button.preview": "Visualizar", + "artifacts.preview.openExternal.error.content": "Erro ao abrir em navegador externo", + "assistant.search.placeholder": "Pesquisar", + "deeply_thought": "Profundamente pensado (demorou {{secounds}} segundos)", + "default.description": "Olá, eu sou o assistente padrão. Você pode começar a conversar comigo agora.", + "default.name": "Assistente Padrão", + "default.topic.name": "Tópico Padrão", + "input.auto_resize": "Ajuste automático de altura", + "input.clear": "Limpar mensagens {{Command}}", + "input.clear.content": "Tem certeza de que deseja limpar todas as mensagens da sessão atual?", + "input.clear.title": "Limpar mensagens", + "input.collapse": "Colapsar", + "input.context_count.tip": "Número de contexto / Número máximo de contexto", + "input.estimated_tokens.tip": "Número estimado de tokens", + "input.expand": "Expandir", + "input.file_not_supported": "O modelo não suporta este tipo de arquivo", + "input.knowledge_base": "Base de conhecimento", + "input.new.context": "Limpar contexto {{Command}}", + "input.new_topic": "Novo tópico {{Command}}", + "input.pause": "Pausar", + "input.placeholder": "Digite sua mensagem aqui...", + "input.send": "Enviar", + "input.settings": "Configurações", + "input.topics": "Tópicos", + "input.translate": "Traduzir para {{target_language}}", + "input.upload": "Carregar imagem ou documento", + "input.upload.document": "Carregar documento (o modelo não suporta imagens)", + "input.web_search": "Ativar pesquisa na web", + "input.web_search.button.ok": "Ir para configurações", + "input.web_search.enable": "Ativar pesquisa na web", + "input.web_search.enable_content": "É necessário verificar a conectividade da pesquisa na web nas configurações primeiro", + "message.new.branch": "Ramificação", + "message.new.branch.created": "Nova ramificação criada", + "message.new.context": "Limpar contexto", + "message.quote": "Citar", + "message.regenerate.model": "Trocar modelo", + "message.useful": "Útil", + "navigation": { + "first": "Esta é a primeira mensagem", + "last": "Esta é a última mensagem", + "next": "Próxima mensagem", + "prev": "Mensagem anterior" + }, + "resend": "Reenviar", + "save": "Salvar", + "settings.code_collapsible": "Bloco de código colapsável", + "settings.code_wrappable": "Bloco de código com quebra de linha", + "settings.context_count": "Número de contexto", + "settings.context_count.tip": "Número de mensagens a serem mantidas no contexto. Quanto maior o número, mais longo será o contexto e mais tokens serão consumidos. Para conversas normais, é recomendado um valor entre 5-10", + "settings.max": "Sem limite", + "settings.max_tokens": "Ativar limite de comprimento da mensagem", + "settings.max_tokens.confirm": "Ativar limite de comprimento da mensagem", + "settings.max_tokens.confirm_content": "Ao ativar o limite de comprimento da mensagem, o número máximo de tokens usados em uma única interação afetará o comprimento do resultado retornado. É necessário definir de acordo com o limite de contexto do modelo, caso contrário, ocorrerá um erro", + "settings.max_tokens.tip": "Número máximo de tokens usados em uma única interação, afetando o comprimento do resultado retornado. É necessário definir de acordo com o limite de contexto do modelo, caso contrário, ocorrerá um erro", + "settings.reset": "Redefinir", + "settings.set_as_default": "Aplicar ao assistente padrão", + "settings.show_line_numbers": "Exibir números de linha no código", + "settings.temperature": "Temperatura do modelo", + "settings.temperature.tip": "Aleatoriedade na geração de texto pelo modelo. Quanto maior o valor, mais variadas, criativas e aleatórias são as respostas; se definido como 0, o modelo responderá com base nos fatos. Para conversas diárias, é recomendado um valor de 0,7", + "settings.thought_auto_collapse": "Conteúdo de pensamento colapsado automaticamente", + "settings.thought_auto_collapse.tip": "O conteúdo de pensamento será colapsado automaticamente após a conclusão do pensamento", + "settings.top_p": "Top-P", + "settings.top_p.tip": "Valor padrão é 1, quanto menor o valor, mais monótono será o conteúdo gerado pela IA, mas também mais fácil de entender; quanto maior o valor, maior será o vocabulário usado pela IA e mais diversificado será o conteúdo", + "suggestions.title": "Perguntas sugeridas", + "thinking": "Pensando", + "topics.auto_rename": "Gerar nome de tópico", + "topics.clear.title": "Limpar mensagens", + "topics.copy.image": "Copiar como imagem", + "topics.copy.md": "Copiar como Markdown", + "topics.copy.title": "Copiar", + "topics.delete.shortcut": "Pressione {{key}} para deletar diretamente", + "topics.edit.placeholder": "Digite novo nome", + "topics.edit.title": "Editar nome do tópico", + "topics.export.image": "Exportar como imagem", + "topics.export.joplin": "Exportar para Joplin", + "topics.export.md": "Exportar como Markdown", + "topics.export.notion": "Exportar para Notion", + "topics.export.obsidian": "Exportar para Obsidian", + "topics.export.obsidian_atributes": "Configurar atributos da nota", + "topics.export.obsidian_btn": "Confirmar", + "topics.export.obsidian_created": "Data de criação", + "topics.export.obsidian_created_placeholder": "Selecione a data de criação", + "topics.export.obsidian_export_failed": "Exportação falhou", + "topics.export.obsidian_export_success": "Exportação bem-sucedida", + "topics.export.obsidian_not_configured": "Obsidian não configurado", + "topics.export.obsidian_operate": "Operação", + "topics.export.obsidian_operate_append": "Anexar", + "topics.export.obsidian_operate_new_or_overwrite": "Criar novo (substituir se existir)", + "topics.export.obsidian_operate_placeholder": "Selecione a operação", + "topics.export.obsidian_operate_prepend": "Prepend", + "topics.export.obsidian_source": "Fonte", + "topics.export.obsidian_source_placeholder": "Digite a fonte", + "topics.export.obsidian_tags": "Etiquetas", + "topics.export.obsidian_tags_placeholder": "Digite as etiquetas, use vírgulas para separar múltiplas etiquetas, Obsidian não aceita números puros", + "topics.export.obsidian_title": "Título", + "topics.export.obsidian_title_placeholder": "Digite o título", + "topics.export.obsidian_title_required": "O título não pode estar vazio", + "topics.export.title": "Exportar", + "topics.export.word": "Exportar como Word", + "topics.export.yuque": "Exportar para Yuque", + "topics.list": "Lista de tópicos", + "topics.move_to": "Mover para", + "topics.new": "Começar nova conversa", + "topics.pinned": "Fixar tópico", + "topics.prompt": "Prompt do tópico", + "topics.prompt.edit.title": "Editar prompt do tópico", + "topics.prompt.tips": "Prompt do tópico: fornecer prompts adicionais para o tópico atual", + "topics.title": "Tópicos", + "topics.unpinned": "Desfixar", + "translate": "Traduzir", + "input.generate_image": "Gerar imagem", + "input.generate_image_not_supported": "Modelo não suporta geração de imagem" + }, + "code_block": { + "collapse": "Recolher", + "disable_wrap": "Desativar quebra de linha", + "enable_wrap": "Ativar quebra de linha", + "expand": "Expandir" + }, + "common": { + "add": "Adicionar", + "advanced_settings": "Configurações Avançadas", + "and": "e", + "assistant": "Agente Inteligente", + "avatar": "Avatar", + "back": "Voltar", + "cancel": "Cancelar", + "chat": "Bate-papo", + "clear": "Limpar", + "close": "Fechar", + "confirm": "Confirmar", + "copied": "Copiado", + "copy": "Copiar", + "cut": "Cortar", + "default": "Padrão", + "delete": "Excluir", + "description": "Descrição", + "docs": "Documentos", + "download": "Baixar", + "duplicate": "Duplicar", + "edit": "Editar", + "expand": "Expandir", + "footnote": "Nota de rodapé", + "footnotes": "Notas de rodapé", + "fullscreen": "Entrou no modo de tela cheia, pressione F11 para sair", + "knowledge_base": "Base de Conhecimento", + "language": "Língua", + "model": "Modelo", + "models": "Modelos", + "more": "Mais", + "name": "Nome", + "paste": "Colar", + "prompt": "Prompt", + "provider": "Fornecedor", + "regenerate": "Regenerar", + "rename": "Renomear", + "reset": "Redefinir", + "save": "Salvar", + "search": "Pesquisar", + "select": "Selecionar", + "topics": "Tópicos", + "warning": "Aviso", + "you": "Você" + }, + "docs": { + "title": "Documentação de Ajuda" + }, + "error": { + "backup.file_format": "Formato do arquivo de backup está incorreto", + "chat.response": "Ocorreu um erro, se a chave da API não foi configurada, por favor vá para Configurações > Provedores de Modelo para configurar a chave", + "http": { + "400": "Erro na solicitação, por favor verifique se os parâmetros da solicitação estão corretos. Se você alterou as configurações do modelo, redefina para as configurações padrão", + "401": "Falha na autenticação, por favor verifique se a chave da API está correta", + "403": "Acesso negado, por favor traduza a mensagem de erro específica para verificar o motivo, ou entre em contato com o fornecedor de serviços para perguntar sobre o motivo da proibição", + "404": "O modelo não existe ou a rota da solicitação está incorreta", + "429": "Taxa de solicitação excedeu o limite, por favor tente novamente mais tarde", + "500": "Erro do servidor, por favor tente novamente mais tarde", + "502": "Erro de gateway, por favor tente novamente mais tarde", + "503": "Serviço indisponível, por favor tente novamente mais tarde", + "504": "Tempo de espera do gateway excedido, por favor tente novamente mais tarde" + }, + "model.exists": "O modelo já existe", + "no_api_key": "A chave da API não foi configurada", + "provider_disabled": "O provedor de modelos está desativado", + "render": { + "description": "Falha ao renderizar a fórmula, por favor verifique se o formato da fórmula está correto", + "title": "Erro de Renderização" + }, + "user_message_not_found": "Não foi possível encontrar a mensagem original do usuário" + }, + "export": { + "assistant": "Assistente", + "attached_files": "Anexos", + "conversation_details": "Detalhes da Conversa", + "conversation_history": "Histórico da Conversa", + "created": "Criado em", + "last_updated": "Última Atualização", + "messages": "Mensagens", + "user": "Usuário" + }, + "files": { + "actions": "Ações", + "all": "Todos os Arquivos", + "count": "Número de Arquivos", + "created_at": "Data de Criação", + "delete": "Excluir", + "delete.content": "Excluir o arquivo removerá todas as referências ao arquivo em todas as mensagens. Tem certeza de que deseja excluir este arquivo?", + "delete.paintings.warning": "Esta imagem está incluída em um desenho e não pode ser excluída temporariamente", + "delete.title": "Excluir Arquivo", + "document": "Documento", + "edit": "Editar", + "file": "Arquivo", + "image": "Imagem", + "name": "Nome do Arquivo", + "open": "Abrir", + "size": "Tamanho", + "text": "Texto", + "title": "Arquivo", + "type": "Tipo" + }, + "gpustack": { + "keep_alive_time.description": "O tempo que o modelo permanece na memória (padrão: 5 minutos)", + "keep_alive_time.placeholder": "minutos", + "keep_alive_time.title": "Manter tempo ativo", + "title": "GPUStack" + }, + "history": { + "continue_chat": "Continuar conversando", + "locate.message": "Localizar mensagem", + "search.messages": "Procurar todas as mensagens", + "search.placeholder": "Procurar tópico ou mensagem...", + "search.topics.empty": "Nenhum tópico relacionado encontrado, clique em Enter para procurar todas as mensagens", + "title": "Procurar Tópicos" + }, + "knowledge": { + "add": { + "title": "Adicionar Base de Conhecimento" + }, + "add_directory": "Adicionar diretório", + "add_file": "Adicionar arquivo", + "add_note": "Adicionar nota", + "add_sitemap": "Adicionar mapa do site", + "add_url": "Adicionar URL", + "cancel_index": "Cancelar índice", + "chunk_overlap": "Sobreposição de bloco", + "chunk_overlap_placeholder": "Valor padrão (não recomendado alterar)", + "chunk_overlap_tooltip": "Quantidade de conteúdo repetido entre blocos de texto adjacentes, garantindo que os blocos de texto divididos ainda tenham conexões de contexto, melhorando o desempenho geral do modelo em textos longos", + "chunk_size": "Tamanho do bloco", + "chunk_size_change_warning": "A alteração do tamanho do bloco e da sobreposição de bloco é válida apenas para novos conteúdos adicionados", + "chunk_size_placeholder": "Valor padrão (não recomendado alterar)", + "chunk_size_too_large": "O tamanho do bloco não pode exceder o limite de contexto do modelo ({{max_context}})", + "chunk_size_tooltip": "Dividir o documento em blocos, o tamanho de cada bloco, que não pode exceder o limite de contexto do modelo", + "clear_selection": "Limpar seleção", + "delete": "Excluir", + "delete_confirm": "Tem certeza de que deseja excluir este repositório de conhecimento?", + "directories": "Diretórios", + "directory_placeholder": "Digite o caminho do diretório", + "document_count": "Número de fragmentos de documentos solicitados", + "document_count_default": "Padrão", + "document_count_help": "Quanto mais fragmentos de documentos solicitados, mais informações são incluídas, mas mais tokens são consumidos", + "drag_file": "Arraste o arquivo aqui", + "edit_remark": "Editar observação", + "edit_remark_placeholder": "Digite o conteúdo da observação", + "empty": "Sem repositório de conhecimento", + "file_hint": "Formatos suportados: {{file_types}}", + "index_all": "Índice total", + "index_cancelled": "Índice cancelado", + "index_started": "Índice iniciado", + "invalid_url": "URL inválida", + "model_info": "Informações do modelo", + "no_bases": "Sem repositório de conhecimento", + "no_match": "Não houve correspondência com o conteúdo do repositório de conhecimento", + "no_provider": "O provedor do modelo do repositório de conhecimento foi perdido, este repositório de conhecimento não será mais suportado, por favor, crie um novo repositório de conhecimento", + "not_set": "Não definido", + "not_support": "O motor de banco de dados do repositório de conhecimento foi atualizado, este repositório de conhecimento não será mais suportado, por favor, crie um novo repositório de conhecimento", + "notes": "Notas", + "notes_placeholder": "Digite informações adicionais ou contexto para este repositório de conhecimento...", + "rename": "Renomear", + "search": "Pesquisar repositório de conhecimento", + "search_placeholder": "Digite o conteúdo da consulta", + "settings": "Configurações do repositório de conhecimento", + "sitemap_placeholder": "Digite a URL do mapa do site", + "sitemaps": "Sites", + "source": "Fonte", + "status": "Status", + "status_completed": "Concluído", + "status_failed": "Falhou", + "status_new": "Adicionado", + "status_pending": "Pendente", + "status_processing": "Processando", + "threshold": "Limite de correspondência", + "threshold_placeholder": "Não definido", + "threshold_too_large_or_small": "O limite não pode ser maior que 1 ou menor que 0", + "threshold_tooltip": "Usado para medir a relevância entre a pergunta do usuário e o conteúdo do repositório de conhecimento (0-1)", + "title": "Repositório de conhecimento", + "topN": "Número de resultados retornados", + "topN__too_large_or_small": "O número de resultados retornados não pode ser maior que 100 ou menor que 1", + "topN_placeholder": "Não definido", + "topN_tooltip": "Número de resultados correspondentes retornados, quanto maior o valor, mais resultados correspondentes, mas mais tokens são consumidos", + "url_added": "URL adicionada", + "url_placeholder": "Digite a URL, várias URLs separadas por enter", + "urls": "URLs" + }, + "languages": { + "arabic": "Árabe", + "chinese": "Chinês Simplificado", + "chinese-traditional": "Chinês Tradicional", + "english": "Inglês", + "french": "Francês", + "german": "Alemão", + "italian": "Italiano", + "japanese": "Japonês", + "korean": "Coreano", + "portuguese": "Português", + "russian": "Russo", + "spanish": "Espanhol" + }, + "lmstudio": { + "keep_alive_time.description": "Tempo que o modelo permanece na memória após a conversa (padrão: 5 minutos)", + "keep_alive_time.placeholder": "minutos", + "keep_alive_time.title": "Manter tempo ativo", + "title": "LM Studio" + }, + "mermaid": { + "download": { + "png": "Baixar PNG", + "svg": "Baixar SVG" + }, + "resize": { + "zoom-in": "Aproximar", + "zoom-out": "Afastar" + }, + "tabs": { + "preview": "Pré-visualização", + "source": "Código-fonte" + }, + "title": "Gráfico Mermaid" + }, + "message": { + "api.check.model.title": "Selecione o modelo a ser verificado", + "api.connection.failed": "Conexão falhou", + "api.connection.success": "Conexão bem-sucedida", + "assistant.added.content": "Assistente adicionado com sucesso", + "attachments": { + "pasted_image": "Imagem da área de transferência", + "pasted_text": "Arquivo da área de transferência" + }, + "backup.failed": "Backup falhou", + "backup.start.success": "Início do backup", + "backup.success": "Backup bem-sucedido", + "chat.completion.paused": "Conversa pausada", + "citations": "Citações", + "copied": "Copiado", + "copy.failed": "Cópia falhou", + "copy.success": "Cópia bem-sucedida", + "error.chunk_overlap_too_large": "A sobreposição de fragmentos não pode ser maior que o tamanho do fragmento", + "error.dimension_too_large": "Dimensão do conteúdo muito grande", + "error.enter.api.host": "Insira seu endereço API", + "error.enter.api.key": "Insira sua chave API", + "error.enter.model": "Selecione um modelo", + "error.enter.name": "Insira o nome da base de conhecimento", + "error.get_embedding_dimensions": "Falha ao obter dimensões de incorporação", + "error.invalid.api.host": "Endereço API inválido", + "error.invalid.api.key": "Chave API inválida", + "error.invalid.enter.model": "Selecione um modelo", + "error.invalid.proxy.url": "URL do proxy inválido", + "error.invalid.webdav": "Configuração WebDAV inválida", + "error.joplin.export": "Falha ao exportar Joplin, mantenha o Joplin em execução e verifique o status da conexão ou a configuração", + "error.joplin.no_config": "Token de autorização Joplin ou URL não configurados", + "error.markdown.export.preconf": "Falha ao exportar arquivo Markdown para caminho pré-configurado", + "error.markdown.export.specified": "Falha ao exportar arquivo Markdown", + "error.notion.export": "Erro ao exportar Notion, verifique o status da conexão e a configuração de acordo com a documentação", + "error.notion.no_api_key": "API Key ou Notion Database ID não configurados", + "error.yuque.export": "Erro ao exportar Yuque, verifique o status da conexão e a configuração de acordo com a documentação", + "error.yuque.no_config": "Token Yuque ou URL da base de conhecimento não configurados", + "group.delete.content": "Excluir mensagens de grupo removerá as perguntas dos usuários e todas as respostas do assistente", + "group.delete.title": "Excluir mensagens de grupo", + "ignore.knowledge.base": "Modo online ativado, ignorando base de conhecimento", + "info.notion.block_reach_limit": "Conversa muito longa, exportando em páginas para Notion", + "loading.notion.exporting_progress": "Exportando para Notion ({{current}}/{{total}})...", + "loading.notion.preparing": "Preparando exportação para Notion...", + "mention.title": "Alternar modelo de resposta", + "message.code_style": "Estilo de código", + "message.delete.content": "Tem certeza de que deseja excluir esta mensagem?", + "message.delete.title": "Excluir mensagem", + "message.multi_model_style": "Estilo de resposta multi-modelo", + "message.multi_model_style.fold": "Modo de etiqueta", + "message.multi_model_style.fold.compress": "Alternar para disposição compacta", + "message.multi_model_style.fold.expand": "Alternar para disposição expandida", + "message.multi_model_style.grid": "Layout de cartão", + "message.multi_model_style.horizontal": "Arranjo horizontal", + "message.multi_model_style.vertical": "Pilha vertical", + "message.style": "Estilo da mensagem", + "message.style.bubble": "Bolha", + "message.style.plain": "Simples", + "regenerate.confirm": "A regeneração substituirá a mensagem atual", + "reset.confirm.content": "Tem certeza de que deseja resetar todos os dados?", + "reset.double.confirm.content": "Todos os seus dados serão perdidos, se não houver backup, eles não poderão ser recuperados, tem certeza de que deseja continuar?", + "reset.double.confirm.title": "Perda de dados!!!", + "restore.failed": "Restauração falhou", + "restore.success": "Restauração bem-sucedida", + "save.success.title": "Salvo com sucesso", + "searching": "Pesquisando na internet...", + "success.joplin.export": "Exportado com sucesso para Joplin", + "success.markdown.export.preconf": "Arquivo Markdown exportado com sucesso para caminho pré-configurado", + "success.markdown.export.specified": "Arquivo Markdown exportado com sucesso", + "success.notion.export": "Exportado com sucesso para Notion", + "success.yuque.export": "Exportado com sucesso para Yuque", + "switch.disabled": "Aguarde a conclusão da resposta atual antes de operar", + "tools": { + "completed": "Completo", + "invoking": "Em execução" + }, + "topic.added": "Tópico adicionado com sucesso", + "upgrade.success.button": "Reiniciar", + "upgrade.success.content": "Reinicie para concluir a atualização", + "upgrade.success.title": "Atualização bem-sucedida", + "warn.notion.exporting": "Exportando para Notion, não solicite novamente a exportação!", + "warning.rate.limit": "Envio muito frequente, aguarde {{seconds}} segundos antes de tentar novamente" + }, + "minapp": { + "sidebar.add.title": "Adicionar à barra lateral", + "sidebar.remove.title": "Remover da barra lateral", + "title": "Pequeno aplicativo" + }, + "miniwindow": { + "clipboard": { + "empty": "A área de transferência está vazia" + }, + "feature": { + "chat": "Responder a esta pergunta", + "explanation": "Explicação", + "summary": "Resumo do conteúdo", + "translate": "Tradução de texto" + }, + "footer": { + "copy_last_message": "Pressione C para copiar", + "esc": "Pressione ESC {{action}}", + "esc_back": "Voltar", + "esc_close": "Fechar janela" + }, + "input": { + "placeholder": { + "empty": "Pergunte a {{model}} para obter ajuda...", + "title": "O que você quer fazer com o texto abaixo" + } + } + }, + "models": { + "add_parameter": "Adicionar parâmetro", + "all": "Todos", + "custom_parameters": "Parâmetros personalizados", + "dimensions": "{{dimensions}} dimensões", + "edit": "Editar modelo", + "embedding": "Inscrição", + "embedding_model": "Modelo de inscrição", + "embedding_model_tooltip": "Clique no botão Gerenciar em Configurações -> Serviço de modelos para adicionar", + "function_calling": "Chamada de função", + "no_matches": "Nenhum modelo disponível", + "parameter_name": "Nome do parâmetro", + "parameter_type": { + "boolean": "Valor booleano", + "json": "JSON", + "number": "Número", + "string": "Texto" + }, + "pinned": "Fixado", + "rerank_model": "Modelo de reclassificação", + "rerank_model_support_provider": "O modelo de reclassificação atualmente suporta apenas alguns provedores ({{provider}})", + "rerank_model_tooltip": "Clique no botão Gerenciar em Configurações -> Serviço de modelos para adicionar", + "search": "Procurar modelo...", + "stream_output": "Saída em fluxo", + "type": { + "embedding": "inserção", + "function_calling": "chamada de função", + "reasoning": "raciocínio", + "select": "selecione o tipo de modelo", + "text": "texto", + "vision": "imagem", + "free": "Grátis", + "rerank": "Reclassificar", + "websearch": "Procurar na web" + } + }, + "navbar": { + "expand": "Expandir caixa de diálogo", + "hide_sidebar": "Ocultar barra lateral", + "show_sidebar": "Mostrar barra lateral" + }, + "ollama": { + "keep_alive_time.description": "Tempo que o modelo permanece na memória após a conversa (padrão: 5 minutos)", + "keep_alive_time.placeholder": "minutos", + "keep_alive_time.title": "Manter tempo ativo", + "title": "Ollama" + }, + "paintings": { + "button.delete.image": "Excluir Imagem", + "button.delete.image.confirm": "Deseja realmente excluir esta imagem?", + "button.new.image": "Nova Imagem", + "guidance_scale": "Escala de Direção", + "guidance_scale_tip": "Sem direção do classificador. Controle o grau ao qual o modelo segue a palavra-chave ao procurar imagens relacionadas", + "image.size": "Tamanho da Imagem", + "inference_steps": "Passos de Inferência", + "inference_steps_tip": "Número de passos de inferência a serem executados. Quanto mais passos, melhor a qualidade, mas mais demorado", + "negative_prompt": "Prompt Negativo", + "negative_prompt_tip": "Descreva o que você não quer na imagem", + "number_images": "Quantidade de Imagens", + "number_images_tip": "Quantidade de imagens a serem geradas por vez (1-4)", + "prompt_enhancement": "Aumento do Prompt", + "prompt_enhancement_tip": "Ao ativar, o prompt será reescrito para uma versão detalhada e adequada ao modelo", + "prompt_placeholder": "Descreva a imagem que deseja criar, por exemplo: um lago tranquilo, com o pôr do sol, montanhas distantes", + "regenerate.confirm": "Isso substituirá as imagens já geradas, deseja continuar?", + "seed": "Semente Aleatória", + "seed_tip": "A mesma semente e palavra-chave podem gerar imagens semelhantes", + "title": "Imagem" + }, + "plantuml": { + "download": { + "failed": "Download falhou, por favor verifique a sua conexão com a internet", + "png": "Download PNG", + "svg": "Download SVG" + }, + "tabs": { + "preview": "Pré-visualização", + "source": "Código-fonte" + }, + "title": "Diagrama PlantUML" + }, + "prompts": { + "explanation": "Ajude-me a explicar este conceito", + "summarize": "Ajude-me a resumir este parágrafo", + "title": "Você é um assistente hábil em conversação, precisa resumir o diálogo do usuário em um título de até 10 caracteres, o idioma do título deve ser o mesmo que a principal língua do usuário, não use pontuação ou outros símbolos especiais" + }, + "provider": { + "aihubmix": "AiHubMix", + "alayanew": "Alaya NeW", + "anthropic": "Antropológico", + "azure-openai": "Azure OpenAI", + "baichuan": "BaiChuan", + "baidu-cloud": "Nuvem Baidu", + "copilot": "GitHub Copiloto", + "dashscope": "Área de Atuação AliCloud", + "deepseek": "Busca Profunda", + "dmxapi": "DMXAPI", + "doubao": "Volcano Engine", + "fireworks": "Fogos de Artifício", + "gemini": "Gêmeos", + "gitee-ai": "Gitee IA", + "github": "GitHub Models", + "gpustack": "GPUStack", + "graphrag-kylin-mountain": "GraphRAG", + "grok": "Compreender", + "groq": "Groq", + "hunyuan": "Tencent Hún Yuán", + "hyperbolic": "Hiperbólico", + "infini": "Infinito", + "jina": "Jina", + "lmstudio": "Estúdio LM", + "minimax": "Minimax", + "mistral": "Mistral", + "modelscope": "ModelScope MôDá", + "moonshot": "Disparo Lunar", + "nvidia": "NVIDIA", + "o3": "O3", + "ocoolai": "ocoolAI", + "ollama": "Ollama", + "openai": "OpenAI", + "openrouter": "OpenRouter", + "perplexity": "Perplexidade", + "ppio": "PPIO Nuvem Piao", + "qwenlm": "QwenLM", + "silicon": "Silício em Fluxo", + "stepfun": "Função de Passo Estelar", + "tencent-cloud-ti": "Nuvem TI da Tencent", + "together": "Juntos", + "xirang": "XiRang do Nuvem Telecom", + "yi": "ZeroUmTudo", + "zhinao": "360 Inteligência Artificial", + "zhipu": "ZhiPu IA" + }, + "restore": { + "confirm": "Tem certeza de que deseja restaurar os dados?", + "confirm.button": "Selecione o arquivo de backup", + "content": "A operação de restauração usará os dados de backup para substituir todos os dados atuais do aplicativo. Por favor, note que o processo de restauração pode levar algum tempo. Agradecemos sua paciência.", + "progress": { + "completed": "Restauração concluída", + "copying_files": "Copiando arquivos... {{progress}}%", + "extracting": "Descompactando backup...", + "preparing": "Preparando restauração...", + "reading_data": "Lendo dados...", + "title": "Progresso da Restauração" + }, + "title": "Restauração de Dados" + }, + "settings": { + "about": "Sobre Nós", + "about.checkingUpdate": "Verificando atualizações...", + "about.checkUpdate": "Verificar atualizações", + "about.checkUpdate.available": "Atualizar agora", + "about.contact.button": "E-mail", + "about.contact.title": "Contato por e-mail", + "about.description": "Um assistente de IA criado para criadores", + "about.downloading": "Baixando atualizações...", + "about.feedback.button": "Feedback", + "about.feedback.title": "Enviar feedback", + "about.license.button": "Ver", + "about.license.title": "Licença", + "about.releases.button": "Ver", + "about.releases.title": "Registro de alterações", + "about.social.title": "Contas sociais", + "about.title": "Sobre nós", + "about.updateAvailable": "Nova versão disponível {{version}}", + "about.updateError": "Erro ao atualizar", + "about.updateNotAvailable": "Seu software já está atualizado", + "about.website.button": "Ver", + "about.website.title": "Site oficial", + "advanced.auto_switch_to_topics": "Alternar automaticamente para tópicos", + "advanced.title": "Configurações avançadas", + "assistant": "Assistente padrão", + "assistant.model_params": "Parâmetros do modelo", + "assistant.show.icon": "Mostrar ícone do modelo", + "assistant.title": "Assistente padrão", + "data": { + "app_data": "Dados do aplicativo", + "app_knowledge": "Arquivo de base de conhecimento", + "app_knowledge.button.delete": "Excluir arquivo", + "app_knowledge.remove_all": "Excluir arquivos da base de conhecimento", + "app_knowledge.remove_all_confirm": "A exclusão dos arquivos da base de conhecimento reduzirá o uso do espaço de armazenamento, mas não excluirá os dados vetoriais da base de conhecimento. Após a exclusão, os arquivos originais não poderão ser abertos. Deseja excluir?", + "app_knowledge.remove_all_success": "Arquivo excluído com sucesso", + "app_logs": "Logs do aplicativo", + "clear_cache": { + "button": "Limpar cache", + "confirm": "Limpar cache removerá os dados armazenados em cache do aplicativo, incluindo dados de aplicativos minúsculos. Esta ação não pode ser desfeita, deseja continuar?", + "error": "Falha ao limpar cache", + "success": "Cache limpo com sucesso", + "title": "Limpar cache" + }, + "data.title": "Diretório de dados", + "hour_interval_one": "{{count}} hora", + "hour_interval_other": "{{count}} horas", + "joplin": { + "check": { + "button": "Verificar", + "empty_token": "Por favor, insira primeiro o token de autorização do Joplin", + "empty_url": "Por favor, insira primeiro a URL de monitoramento do serviço de recorte do Joplin", + "fail": "A validação da conexão com o Joplin falhou", + "success": "A validação da conexão com o Joplin foi bem-sucedida" + }, + "help": "Na opção Joplin, ative o serviço de recorte da web (sem necessidade de instalar um plug-in do navegador), confirme a porta e copie o token de autorização", + "title": "Configuração do Joplin", + "token": "Token de autorização do Joplin", + "token_placeholder": "Insira o token de autorização do Joplin", + "url": "URL para o qual o serviço de recorte do Joplin está escutando", + "url_placeholder": "http://127.0.0.1:41184/" + }, + "markdown_export.force_dollar_math.help": "Ao ativar, a exportação para Markdown forçará o uso de $$ para marcar fórmulas LaTeX. Nota: isso também afetará todas as formas de exportação via Markdown, como Notion, Yuque, etc.", + "markdown_export.force_dollar_math.title": "Forçar o uso de $$ para marcar fórmulas LaTeX", + "markdown_export.help": "Se preenchido, será salvo automaticamente nesse caminho em cada exportação; caso contrário, uma caixa de diálogo de salvamento será exibida", + "markdown_export.path": "Caminho padrão de exportação", + "markdown_export.path_placeholder": "Caminho de exportação", + "markdown_export.select": "Selecionar", + "markdown_export.title": "Exportação Markdown", + "minute_interval_one": "{{count}} minuto", + "minute_interval_other": "{{count}} minutos", + "notion.api_key": "Chave de API do Notion", + "notion.api_key_placeholder": "Insira a chave de API do Notion", + "notion.auto_split": "Dividir automaticamente ao exportar conversas", + "notion.auto_split_tip": "Divide automaticamente tópicos longos ao exportar para o Notion", + "notion.check": { + "button": "Verificar", + "empty_api_key": "API key não configurada", + "empty_database_id": "Database ID não configurado", + "error": "Conexão anormal, por favor verifique a rede e se a API key e Database ID estão corretos", + "fail": "Falha na conexão, por favor verifique a rede e se a API key e Database ID estão corretos", + "success": "Conexão bem-sucedida" + }, + "notion.database_id": "ID do banco de dados do Notion", + "notion.database_id_placeholder": "Insira o ID do banco de dados do Notion", + "notion.help": "Documentação de configuração do Notion", + "notion.page_name_key": "Campo do título da página", + "notion.page_name_key_placeholder": "Insira o campo do título da página, por padrão é Nome", + "notion.split_size": "Tamanho de divisão automática", + "notion.split_size_help": "Para usuários gratuitos do Notion, recomendamos 90; para usuários premium, recomendamos 24990; o valor padrão é 90", + "notion.split_size_placeholder": "Insira o limite de blocos por página (padrão 90)", + "notion.title": "Configurações do Notion", + "obsidian": { + "folder": "Pasta", + "folder_placeholder": "Insira o nome da pasta", + "tags": "Tags Globais", + "tags_placeholder": "Insira o nome da tag, use vírgulas para separar múltiplas tags, o Obsidian não permite números puros", + "title": "Configuração do Obsidian", + "vault": "Cofre", + "vault_placeholder": "Insira o nome do cofre" + }, + "title": "Configurações de dados", + "webdav": { + "autoSync": "Backup automático", + "autoSync.off": "Desligar", + "backup.button": "Fazer backup para WebDAV", + "backup.modal.filename.placeholder": "Digite o nome do arquivo de backup", + "backup.modal.title": "Fazer backup para WebDAV", + "host": "Endereço WebDAV", + "host.placeholder": "http://localhost:8080", + "hour_interval_one": "{{count}} hora", + "hour_interval_other": "{{count}} horas", + "lastSync": "Último backup", + "minute_interval_one": "{{count}} minuto", + "minute_interval_other": "{{count}} minutos", + "noSync": "Aguardando próximo backup", + "password": "Senha WebDAV", + "path": "Caminho WebDAV", + "path.placeholder": "/backup", + "restore.button": "Restaurar de WebDAV", + "restore.confirm.content": "A restauração de WebDAV substituirá os dados atuais. Deseja continuar?", + "restore.confirm.title": "Confirmar restauração", + "restore.content": "A restauração de WebDAV substituirá os dados atuais. Deseja continuar?", + "restore.modal.select.placeholder": "Selecione o arquivo de backup para restaurar", + "restore.modal.title": "Restaurar de WebDAV", + "restore.title": "Restaurar de WebDAV", + "syncError": "Erro de backup", + "syncStatus": "Status de backup", + "title": "WebDAV", + "user": "Nome de usuário WebDAV" + }, + "yuque": { + "check": { + "button": "Verificar", + "empty_repo_url": "Por favor, insira primeiro a URL do repositório de conhecimento", + "empty_token": "Por favor, insira primeiro o Token do YuQue", + "fail": "Validação da conexão com o YuQue falhou", + "success": "Validação da conexão com o YuQue foi bem-sucedida" + }, + "help": "Obter Token do Yuque", + "repo_url": "URL da Base de Conhecimento", + "repo_url_placeholder": "https://www.yuque.com/username/xxx", + "title": "Configuração do Yuque", + "token": "Token do Yuque", + "token_placeholder": "Insira o Token do Yuque" + } + }, + "display.assistant.title": "Configurações do assistente", + "display.custom.css": "CSS personalizado", + "display.custom.css.cherrycss": "Obter do cherrycss.com", + "display.custom.css.placeholder": "/* Escreva seu CSS personalizado aqui */", + "display.minApp.disabled": "Aplicativos ocultos", + "display.minApp.empty": "Arraste os aplicativos que deseja ocultar da esquerda para cá", + "display.minApp.title": "Configurações de exibição de aplicativos", + "display.minApp.visible": "Aplicativos visíveis", + "display.sidebar.chat.hiddenMessage": "O assistente é uma funcionalidade básica e não pode ser ocultada", + "display.sidebar.disabled": "Ícones ocultos", + "display.sidebar.empty": "Arraste as funcionalidades que deseja ocultar da esquerda para cá", + "display.sidebar.files.icon": "Mostrar ícone de arquivo", + "display.sidebar.knowledge.icon": "Mostrar ícone de conhecimento", + "display.sidebar.minapp.icon": "Mostrar ícone de aplicativo", + "display.sidebar.painting.icon": "Mostrar ícone de pintura", + "display.sidebar.title": "Configurações de barra lateral", + "display.sidebar.translate.icon": "Mostrar ícone de tradução", + "display.sidebar.visible": "Ícones visíveis", + "display.title": "Configurações de exibição", + "display.topic.title": "Configurações de tópico", + "font_size.title": "Tamanho da fonte da mensagem", + "general": "Configurações gerais", + "general.avatar.reset": "Redefinir avatar", + "general.backup.button": "Backup", + "general.backup.title": "Backup e restauração de dados", + "general.display.title": "Configurações de exibição", + "general.emoji_picker": "Seletor de emojis", + "general.image_upload": "Carregar imagem", + "general.manually_check_update.title": "Desativar verificação de atualização", + "general.reset.button": "Redefinir", + "general.reset.title": "Redefinir dados", + "general.restore.button": "Restaurar", + "general.title": "Configurações gerais", + "general.user_name": "Nome de usuário", + "general.user_name.placeholder": "Digite o nome de usuário", + "general.view_webdav_settings": "Ver configurações WebDAV", + "input.auto_translate_with_space": "Traduzir com três espaços rápidos", + "input.target_language": "Língua alvo", + "input.target_language.chinese": "Chinês simplificado", + "input.target_language.chinese-traditional": "Chinês tradicional", + "input.target_language.english": "Inglês", + "input.target_language.japanese": "Japonês", + "input.target_language.russian": "Russo", + "launch.onboot": "Iniciar automaticamente ao ligar", + "launch.title": "Inicialização", + "launch.totray": "Minimizar para bandeja ao iniciar", + "mcp": { + "actions": "Ações", + "active": "Ativar", + "addError": "Falha ao adicionar servidor", + "addServer": "Adicionar Servidor", + "addSuccess": "Servidor adicionado com sucesso", + "args": "Argumentos", + "argsTooltip": "Cada argumento em uma linha", + "baseUrlTooltip": "Endereço de URL remoto", + "command": "Comando", + "commandRequired": "Digite o comando", + "config_description": "Configurar modelo de protocolo de contexto do servidor", + "confirmDelete": "Excluir servidor", + "confirmDeleteMessage": "Tem certeza de que deseja excluir este servidor?", + "deleteError": "Falha ao excluir servidor", + "deleteSuccess": "Servidor excluído com sucesso", + "dependenciesInstall": "Instalar dependências", + "dependenciesInstalling": "Instalando dependências...", + "description": "Descrição", + "duplicateName": "Já existe um servidor com o mesmo nome", + "editJson": "Editar JSON", + "editServer": "Editar servidor", + "env": "Variáveis de ambiente", + "envTooltip": "Formato: CHAVE=valor, uma por linha", + "findMore": "Mais servidores MCP", + "install": "Instalar", + "installError": "Falha ao instalar dependências", + "installSuccess": "Dependências instaladas com sucesso", + "jsonFormatError": "Erro de formatação JSON", + "jsonModeHint": "Edite a representação JSON da configuração do servidor MCP. Certifique-se de que o formato está correto antes de salvar.", + "jsonSaveError": "Falha ao salvar configuração JSON", + "jsonSaveSuccess": "Configuração JSON salva com sucesso", + "missingDependencies": "Ausente, instale para continuar", + "name": "Nome", + "nameRequired": "Digite o nome do servidor", + "noServers": "Nenhum servidor configurado", + "npx_list": { + "actions": "Ações", + "desc": "Pesquise e adicione pacotes npm como serviço MCP", + "description": "Descrição", + "no_packages": "Nenhum pacote encontrado", + "npm": "NPM", + "package_name": "Nome do Pacote", + "scope_placeholder": "Insira o escopo npm (por exemplo, @sua-organizacao)", + "scope_required": "Insira o escopo npm", + "search": "Pesquisar", + "search_error": "Falha na pesquisa", + "title": "Lista de Pacotes NPX", + "usage": "Uso", + "version": "Versão" + }, + "serverPlural": "Servidores", + "serverSingular": "Servidor", + "title": "Servidores MCP", + "toggleError": "Falha ao alternar", + "type": "Tipo", + "updateError": "Falha ao atualizar servidor", + "updateSuccess": "Servidor atualizado com sucesso", + "url": "URL" + }, + "messages.divider": "Divisor de mensagens", + "messages.grid_columns": "Número de colunas da grade de mensagens", + "messages.grid_popover_trigger": "Disparador de detalhes da grade", + "messages.grid_popover_trigger.click": "Clique para mostrar", + "messages.grid_popover_trigger.hover": "Passe o mouse para mostrar", + "messages.input.paste_long_text_as_file": "Colar texto longo como arquivo", + "messages.input.paste_long_text_threshold": "Limite de texto longo", + "messages.input.send_shortcuts": "Atalhos de envio", + "messages.input.show_estimated_tokens": "Mostrar número estimado de tokens", + "messages.input.title": "Configurações de entrada", + "messages.markdown_rendering_input_message": "Renderização de markdown na entrada de mensagens", + "messages.math_engine": "Motor de fórmulas matemáticas", + "messages.metrics": "Atraso inicial {{time_first_token_millsec}}ms | Taxa de token por segundo {{token_speed}} tokens", + "messages.model.title": "Configurações de modelo", + "messages.navigation": "Botão de navegação de conversa", + "messages.navigation.anchor": "Ancoragem de conversa", + "messages.navigation.buttons": "Botões de cima e de baixo", + "messages.navigation.none": "Não mostrar", + "messages.title": "Configurações de mensagem", + "messages.use_serif_font": "Usar fonte serif", + "model": "Modelo padrão", + "models.add.add_model": "Adicionar modelo", + "models.add.group_name": "Nome do grupo", + "models.add.group_name.placeholder": "Exemplo: ChatGPT", + "models.add.group_name.tooltip": "Exemplo: ChatGPT", + "models.add.model_id": "ID do modelo", + "models.add.model_id.placeholder": "Obrigatório Exemplo: gpt-3.5-turbo", + "models.add.model_id.tooltip": "Exemplo: gpt-3.5-turbo", + "models.add.model_name": "Nome do modelo", + "models.add.model_name.placeholder": "Exemplo: GPT-3.5", + "models.check.all": "Todos", + "models.check.all_models_passed": "Todos os modelos passaram na verificação", + "models.check.button_caption": "Verificação de saúde", + "models.check.disabled": "Desabilitado", + "models.check.enable_concurrent": "Verificação concorrente", + "models.check.enabled": "Habilitado", + "models.check.failed": "Falhou", + "models.check.keys_status_count": "Passou: {{count_passed}} chaves, falhou: {{count_failed}} chaves", + "models.check.model_status_summary": "{{provider}}: {{count_passed}} modelos completaram a verificação de saúde (entre eles, {{count_partial}} modelos não podem ser acessados com algumas chaves), {{count_failed}} modelos não podem ser acessados completamente.", + "models.check.no_api_keys": "Nenhuma chave API encontrada, adicione uma chave API primeiro.", + "models.check.passed": "Passou", + "models.check.select_api_key": "Selecione a chave API a ser usada:", + "models.check.single": "Individual", + "models.check.start": "Começar", + "models.check.title": "Verificação de saúde do modelo", + "models.check.use_all_keys": "Use chaves", + "models.default_assistant_model": "Modelo de assistente padrão", + "models.default_assistant_model_description": "Modelo usado ao criar um novo assistente, se o assistente não tiver um modelo definido, este será usado", + "models.empty": "Sem modelos", + "models.enable_topic_naming": "Renomeação automática de tópicos", + "models.manage.add_whole_group": "Adicionar todo o grupo", + "models.manage.remove_whole_group": "Remover todo o grupo", + "models.topic_naming_model": "Modelo de nomenclatura de tópicos", + "models.topic_naming_model_description": "Modelo usado para nomear tópicos automaticamente", + "models.topic_naming_model_setting_title": "Configurações do modelo de nomenclatura de tópicos", + "models.topic_naming_prompt": "Prompt de nomenclatura de tópicos", + "models.translate_model": "Modelo de tradução", + "models.translate_model_description": "Modelo usado para serviços de tradução", + "models.translate_model_prompt_message": "Digite o prompt do modelo de tradução", + "models.translate_model_prompt_title": "Prompt do modelo de tradução", + "moresetting": "Configurações adicionais", + "moresetting.check.confirm": "Confirmar seleção", + "moresetting.check.warn": "Por favor, selecione com cuidado esta opção, uma seleção incorreta pode impedir o uso normal dos modelos!!!", + "moresetting.warn": "Aviso de risco", + "provider": { + "add.name": "Nome do Fornecedor", + "add.name.placeholder": "Exemplo OpenAI", + "add.title": "Adicionar Fornecedor", + "add.type": "Tipo de Fornecedor", + "api.url.preview": "Pré-visualização: {{url}}", + "api.url.reset": "Redefinir", + "api.url.tip": "Ignorar v1 na versão finalizada com /, usar endereço de entrada forçado se terminar com #", + "api_host": "Endereço API", + "api_key": "Chave API", + "api_key.tip": "Use vírgula para separar várias chaves", + "api_version": "Versão da API", + "charge": "Recarregar", + "check": "Verificar", + "check_all_keys": "Verificar todas as chaves", + "check_multiple_keys": "Verificar várias chaves API", + "copilot": { + "auth_failed": "Falha na autenticação do Github Copilot", + "auth_success": "Autenticação do Github Copilot bem-sucedida", + "auth_success_title": "Autenticação bem-sucedida", + "code_failed": "Falha ao obter Código do Dispositivo, tente novamente", + "code_generated_desc": "Por favor, copie o Código do Dispositivo para o link do navegador abaixo", + "code_generated_title": "Obter Código do Dispositivo", + "confirm_login": "O uso excessivo pode resultar no bloqueio da sua conta do Github, use com cuidado!!!!", + "confirm_title": "Aviso de Risco", + "connect": "Conectar ao Github", + "custom_headers": "Cabeçalhos Personalizados", + "description": "Sua conta do Github precisa assinar o Copilot", + "expand": "Expandir", + "headers_description": "Cabeçalhos personalizados (formato json)", + "invalid_json": "Formato JSON inválido", + "login": "Fazer login no Github", + "logout": "Sair do Github", + "logout_failed": "Falha ao sair, tente novamente", + "logout_success": "Saiu com sucesso", + "model_setting": "Configuração do Modelo", + "open_verification_first": "Por favor, clique no link acima para acessar a página de verificação", + "rate_limit": "Limite de Taxa", + "tooltip": "Para usar o Github Copilot, você precisa fazer login no Github" + }, + "delete.content": "Tem certeza de que deseja excluir este fornecedor de modelo?", + "delete.title": "Excluir Fornecedor", + "docs_check": "Verificar", + "docs_more_details": "Obter mais detalhes", + "get_api_key": "Clique aqui para obter a chave", + "is_not_support_array_content": "Ativar modo compatível", + "no_models": "Por favor, adicione um modelo antes de verificar a conexão da API", + "not_checked": "Não verificado", + "remove_duplicate_keys": "Remover chaves duplicadas", + "remove_invalid_keys": "Remover chaves inválidas", + "search": "Procurar plataforma de modelos...", + "search_placeholder": "Procurar ID ou nome do modelo", + "title": "Serviços de Modelos" + }, + "proxy": { + "mode": { + "custom": "Proxy Personalizado", + "none": "Não Usar Proxy", + "system": "Proxy do Sistema", + "title": "Modo de Proxy" + }, + "title": "Configurações de Proxy" + }, + "proxy.title": "Endereço de proxy", + "quickAssistant": { + "click_tray_to_show": "Clique no ícone da bandeja para iniciar", + "enable_quick_assistant": "Ativar assistente rápido", + "read_clipboard_at_startup": "Ler área de transferência ao iniciar", + "title": "Assistente Rápido", + "use_shortcut_to_show": "Clique com o botão direito no ícone da bandeja ou use atalhos para iniciar" + }, + "shortcuts": { + "action": "Ação", + "clear_shortcut": "Limpar atalho", + "clear_topic": "Limpar mensagem", + "copy_last_message": "Copiar a última mensagem", + "key": "Tecla", + "mini_window": "Atalho de assistente", + "new_topic": "Novo tópico", + "press_shortcut": "Pressionar atalho", + "reset_defaults": "Redefinir atalhos padrão", + "reset_defaults_confirm": "Tem certeza de que deseja redefinir todos os atalhos?", + "reset_to_default": "Redefinir para padrão", + "search_message": "Pesquisar mensagem", + "show_app": "Exibir aplicativo", + "show_settings": "Abrir configurações", + "title": "Atalhos", + "toggle_new_context": "Limpar contexto", + "toggle_show_assistants": "Alternar exibição de assistentes", + "toggle_show_topics": "Alternar exibição de tópicos", + "zoom_in": "Ampliar interface", + "zoom_out": "Diminuir interface", + "zoom_reset": "Redefinir zoom" + }, + "theme.auto": "Automático", + "theme.dark": "Escuro", + "theme.light": "Claro", + "theme.title": "Tema", + "theme.window.style.opaque": "Janela opaca", + "theme.window.style.title": "Estilo de janela", + "theme.window.style.transparent": "Janela transparente", + "title": "Configurações", + "topic.position": "Posição do tópico", + "topic.position.left": "Esquerda", + "topic.position.right": "Direita", + "topic.show.time": "Mostrar tempo do tópico", + "tray.onclose": "Minimizar para bandeja ao fechar", + "tray.show": "Mostrar ícone de bandeja", + "tray.title": "Tray", + "websearch": { + "blacklist": "Lista Negra", + "blacklist_description": "Os seguintes sites não aparecerão nos resultados da pesquisa", + "blacklist_tooltip": "Por favor, use o seguinte formato (separado por quebras de linha)\\nexample.com \\\\:nhttps://www.example.com \\\\:nhttps://example.com \\\\:n*://*.example.com", + "check": "Verificar", + "check_failed": "Verificação falhou", + "check_success": "Verificação bem-sucedida", + "enhance_mode": "Modo de pesquisa avançada", + "enhance_mode_tooltip": "Use o modelo padrão para extrair palavras-chave e depois pesquise", + "get_api_key": "Clique aqui para obter a chave", + "no_provider_selected": "Selecione um provedor de pesquisa antes de verificar", + "search_max_result": "Número de resultados da pesquisa", + "search_provider": "Provedor de pesquisa", + "search_provider_placeholder": "Selecione um provedor de pesquisa", + "search_result_default": "Padrão", + "search_with_time": "Pesquisar com data", + "tavily": { + "api_key": "Chave de API do Tavily", + "api_key.placeholder": "Insira a chave de API do Tavily", + "description": "O Tavily é um mecanismo de busca projetado especificamente para agentes de IA, oferecendo resultados em tempo real, precisos, sugestões inteligentes de consulta e capacidades de pesquisa aprofundada", + "title": "Tavily" + }, + "title": "Pesquisa na Web" + } + }, + "translate": { + "any.language": "qualquer idioma", + "button.translate": "Traduzir", + "close": "Fechar", + "confirm": { + "content": "A tradução substituirá o texto original, deseja continuar?", + "title": "Confirmação de Tradução" + }, + "error.failed": "Tradução falhou", + "error.not_configured": "Modelo de tradução não configurado", + "history": { + "clear": "Limpar Histórico", + "clear_description": "Limpar histórico irá deletar todos os registros de tradução. Deseja continuar?", + "delete": "Excluir", + "empty": "Nenhum histórico de tradução disponível", + "title": "Histórico de Tradução" + }, + "input.placeholder": "Digite o texto para traduzir", + "output.placeholder": "Tradução", + "processing": "Traduzindo...", + "scroll_sync.disable": "Desativar sincronização de rolagem", + "scroll_sync.enable": "Ativar sincronização de rolagem", + "title": "Tradução", + "tooltip.newline": "Quebra de linha" + }, + "tray": { + "quit": "Sair", + "show_mini_window": "Atalho de Assistente", + "show_window": "Exibir Janela" + }, + "words": { + "knowledgeGraph": "Gráfico de Conhecimento", + "quit": "Sair", + "show_window": "Exibir Janela", + "visualization": "Visualização" + } + } +} diff --git a/src/renderer/src/pages/agents/agentGroupTranslations.ts b/src/renderer/src/pages/agents/agentGroupTranslations.ts index b5330a3f4..201afc876 100644 --- a/src/renderer/src/pages/agents/agentGroupTranslations.ts +++ b/src/renderer/src/pages/agents/agentGroupTranslations.ts @@ -1,250 +1,390 @@ export type GroupTranslations = { [key: string]: { + 'el-GR': string 'en-US': string + 'es-ES': string + 'fr-FR': string 'zh-CN': string 'zh-TW': string 'ru-RU': string 'ja-JP': string + 'pt-PT': string } } export const groupTranslations: GroupTranslations = { 我的: { + 'el-GR': 'Τα δικά μου', 'en-US': 'My Agents', + 'es-ES': 'Mis agentes', + 'fr-FR': 'Mes agents', 'zh-CN': '我的', 'zh-TW': '我的', 'ru-RU': 'Мои агенты', - 'ja-JP': '私のエージェント' + 'ja-JP': '私のエージェント', + 'pt-PT': 'Meus Agentes' }, 职业: { + 'el-GR': 'Επαγγελμα', 'en-US': 'Career', + 'es-ES': 'Profesional', + 'fr-FR': 'Professionnel', 'zh-CN': '职业', 'zh-TW': '職業', 'ru-RU': 'Карьера', - 'ja-JP': 'キャリア' + 'ja-JP': 'キャリア', + 'pt-PT': 'Profissional' }, 商业: { + 'el-GR': 'Εμπορικός', 'en-US': 'Business', + 'es-ES': 'Negocio', + 'fr-FR': 'Commercial', 'zh-CN': '商业', 'zh-TW': '商業', 'ru-RU': 'Бизнес', - 'ja-JP': 'ビジネス' + 'ja-JP': 'ビジネス', + 'pt-PT': 'Negócio' }, 工具: { + 'el-GR': 'Εργαλεία', 'en-US': 'Tools', + 'es-ES': 'Herramientas', + 'fr-FR': 'Outils', 'zh-CN': '工具', 'zh-TW': '工具', 'ru-RU': 'Инструменты', - 'ja-JP': 'ツール' + 'ja-JP': 'ツール', + 'pt-PT': 'Ferramentas' }, 语言: { + 'el-GR': 'Γλώσσα', 'en-US': 'Language', + 'es-ES': 'Idioma', + 'fr-FR': 'Langue', 'zh-CN': '语言', 'zh-TW': '語言', 'ru-RU': 'Язык', - 'ja-JP': '言語' + 'ja-JP': '言語', + 'pt-PT': 'Idioma' }, 办公: { + 'el-GR': 'Γραφείο', 'en-US': 'Office', + 'es-ES': 'Oficina', + 'fr-FR': 'Bureau', 'zh-CN': '办公', 'zh-TW': '辦公', 'ru-RU': 'Офис', - 'ja-JP': 'オフィス' + 'ja-JP': 'オフィス', + 'pt-PT': 'Escritório' }, 通用: { + 'el-GR': 'Γενικά', 'en-US': 'General', + 'es-ES': 'General', + 'fr-FR': 'Général', 'zh-CN': '通用', 'zh-TW': '通用', 'ru-RU': 'Общее', - 'ja-JP': '一般' + 'ja-JP': '一般', + 'pt-PT': 'Geral' }, 写作: { + 'el-GR': 'Γράφημα', 'en-US': 'Writing', + 'es-ES': 'Escritura', + 'fr-FR': 'Écriture', 'zh-CN': '写作', 'zh-TW': '寫作', 'ru-RU': 'Письмо', - 'ja-JP': '書き込み' + 'ja-JP': '書き込み', + 'pt-PT': 'Escrita' }, 精选: { + 'el-GR': 'Επιλεγμένο', 'en-US': 'Featured', + 'es-ES': 'Destacado', + 'fr-FR': 'Sélection', 'zh-CN': '精选', 'zh-TW': '精選', 'ru-RU': 'Избранное', - 'ja-JP': '特集' + 'ja-JP': '特集', + 'pt-PT': 'Destaque' }, 编程: { + 'el-GR': 'Προγραμματισμός', 'en-US': 'Programming', + 'es-ES': 'Programación', + 'fr-FR': 'Programmation', 'zh-CN': '编程', 'zh-TW': '編程', 'ru-RU': 'Программирование', - 'ja-JP': 'プログラミング' + 'ja-JP': 'プログラミング', + 'pt-PT': 'Programação' }, 情感: { + 'el-GR': 'Αίσθημα', 'en-US': 'Emotion', + 'es-ES': 'Emoción', + 'fr-FR': 'Émotion', 'zh-CN': '情感', 'zh-TW': '情感', 'ru-RU': 'Эмоции', - 'ja-JP': '感情' + 'ja-JP': '感情', + 'pt-PT': 'Emoção' }, 教育: { + 'el-GR': 'Εκπαίδευση', 'en-US': 'Education', + 'es-ES': 'Educación', + 'fr-FR': 'Éducation', 'zh-CN': '教育', 'zh-TW': '教育', 'ru-RU': 'Образование', - 'ja-JP': '教育' + 'ja-JP': '教育', + 'pt-PT': 'Educação' }, 创意: { + 'el-GR': 'Κreativiteit', 'en-US': 'Creative', + 'es-ES': 'Creativo', + 'fr-FR': 'Créatif', 'zh-CN': '创意', 'zh-TW': '創意', 'ru-RU': 'Креатив', - 'ja-JP': 'クリエイティブ' + 'ja-JP': 'クリエイティブ', + 'pt-PT': 'Criativo' }, 学术: { + 'el-GR': 'Ακαδημικός', 'en-US': 'Academic', + 'es-ES': 'Académico', + 'fr-FR': 'Académique', 'zh-CN': '学术', 'zh-TW': '學術', 'ru-RU': 'Академический', - 'ja-JP': 'アカデミック' + 'ja-JP': 'アカデミック', + 'pt-PT': 'Académico' }, 设计: { + 'el-GR': 'Δημιουργικό', 'en-US': 'Design', + 'es-ES': 'Diseño', + 'fr-FR': 'Design', 'zh-CN': '设计', 'zh-TW': '設計', 'ru-RU': 'Дизайн', - 'ja-JP': 'デザイン' + 'ja-JP': 'デザイン', + 'pt-PT': 'Design' }, 艺术: { + 'el-GR': 'Τέχνη', 'en-US': 'Art', + 'es-ES': 'Arte', + 'fr-FR': 'Art', 'zh-CN': '艺术', 'zh-TW': '藝術', 'ru-RU': 'Искусство', - 'ja-JP': 'アート' + 'ja-JP': 'アート', + 'pt-PT': 'Arte' }, 娱乐: { + 'el-GR': 'Αναψυχή', 'en-US': 'Entertainment', + 'es-ES': 'Entretenimiento', + 'fr-FR': 'Divertissement', 'zh-CN': '娱乐', 'zh-TW': '娛樂', 'ru-RU': 'Развлечения', - 'ja-JP': 'エンターテイメント' + 'ja-JP': 'エンターテイメント', + 'pt-PT': 'Entretenimento' }, 生活: { + 'el-GR': 'Ζωή', 'en-US': 'Life', + 'es-ES': 'Vida', + 'fr-FR': 'Vie', 'zh-CN': '生活', 'zh-TW': '生活', 'ru-RU': 'Жизнь', - 'ja-JP': '生活' + 'ja-JP': '生活', + 'pt-PT': 'Vida' }, 医疗: { + 'el-GR': 'Υγεία', 'en-US': 'Medical', + 'es-ES': 'Médico', + 'fr-FR': 'Médical', 'zh-CN': '医疗', 'zh-TW': '醫療', 'ru-RU': 'Медицина', - 'ja-JP': '医療' + 'ja-JP': '医療', + 'pt-PT': 'Saúde' }, 游戏: { + 'el-GR': 'Παιχνίδια', 'en-US': 'Games', + 'es-ES': 'Juegos', + 'fr-FR': 'Jeux', 'zh-CN': '游戏', 'zh-TW': '遊戲', 'ru-RU': 'Игры', - 'ja-JP': 'ゲーム' + 'ja-JP': 'ゲーム', + 'pt-PT': 'Jogos' }, 翻译: { + 'el-GR': 'Γραφήματα', 'en-US': 'Translation', + 'es-ES': 'Traducción', + 'fr-FR': 'Traduction', 'zh-CN': '翻译', 'zh-TW': '翻譯', 'ru-RU': 'Перевод', - 'ja-JP': '翻訳' + 'ja-JP': '翻訳', + 'pt-PT': 'Tradução' }, 音乐: { + 'el-GR': 'Μουσική', 'en-US': 'Music', + 'es-ES': 'Música', + 'fr-FR': 'Musique', 'zh-CN': '音乐', 'zh-TW': '音樂', 'ru-RU': 'Музыка', - 'ja-JP': '音楽' + 'ja-JP': '音楽', + 'pt-PT': 'Música' }, 点评: { + 'el-GR': 'Αξιολόγηση', 'en-US': 'Review', + 'es-ES': 'Revisión', + 'fr-FR': 'Avis', 'zh-CN': '点评', 'zh-TW': '點評', 'ru-RU': 'Обзор', - 'ja-JP': 'レビュー' + 'ja-JP': 'レビュー', + 'pt-PT': 'Revisão' }, 文案: { + 'el-GR': 'Γραφήματα', 'en-US': 'Copywriting', + 'es-ES': 'Redacción', + 'fr-FR': 'Rédaction', 'zh-CN': '文案', 'zh-TW': '文案', 'ru-RU': 'Копирайтинг', - 'ja-JP': 'コピーライティング' + 'ja-JP': 'コピーライティング', + 'pt-PT': 'Escrita' }, 百科: { + 'el-GR': 'Εγκυκλοπαίδεια', 'en-US': 'Encyclopedia', + 'es-ES': 'Enciclopedia', + 'fr-FR': 'Encyclopédie', 'zh-CN': '百科', 'zh-TW': '百科', 'ru-RU': 'Энциклопедия', - 'ja-JP': '百科事典' + 'ja-JP': '百科事典', + 'pt-PT': 'Enciclopédia' }, 健康: { + 'el-GR': 'Υγεία', 'en-US': 'Health', + 'es-ES': 'Salud', + 'fr-FR': 'Santé', 'zh-CN': '健康', 'zh-TW': '健康', 'ru-RU': 'Здоровье', - 'ja-JP': '健康' + 'ja-JP': '健康', + 'pt-PT': 'Saúde' }, 营销: { + 'el-GR': 'Μάρκετινγκ', 'en-US': 'Marketing', + 'es-ES': 'Marketing', + 'fr-FR': 'Marketing', 'zh-CN': '营销', 'zh-TW': '營銷', 'ru-RU': 'Маркетинг', - 'ja-JP': 'マーケティング' + 'ja-JP': 'マーケティング', + 'pt-PT': 'Marketing' }, 科学: { + 'el-GR': 'Επιστήμη', 'en-US': 'Science', + 'es-ES': 'Ciencia', + 'fr-FR': 'Science', 'zh-CN': '科学', 'zh-TW': '科學', 'ru-RU': 'Наука', - 'ja-JP': '科学' + 'ja-JP': '科学', + 'pt-PT': 'Ciência' }, 分析: { + 'el-GR': 'Ανάλυση', 'en-US': 'Analysis', + 'es-ES': 'Análisis', + 'fr-FR': 'Analyse', 'zh-CN': '分析', 'zh-TW': '分析', 'ru-RU': 'Анализ', - 'ja-JP': '分析' + 'ja-JP': '分析', + 'pt-PT': 'Análise' }, 法律: { + 'el-GR': 'Νόμος', 'en-US': 'Legal', + 'es-ES': 'Legal', + 'fr-FR': 'Légal', 'zh-CN': '法律', 'zh-TW': '法律', 'ru-RU': 'Право', - 'ja-JP': '法律' + 'ja-JP': '法律', + 'pt-PT': 'Legal' }, 咨询: { + 'el-GR': 'Συμβουλή', 'en-US': 'Consulting', + 'es-ES': 'Consultoría', + 'fr-FR': 'Consultation', 'zh-CN': '咨询', 'zh-TW': '諮詢', 'ru-RU': 'Консалтинг', - 'ja-JP': 'コンサルティング' + 'ja-JP': 'コンサルティング', + 'pt-PT': 'Consultoria' }, 金融: { + 'el-GR': 'Φορολογία', 'en-US': 'Finance', + 'es-ES': 'Finanzas', + 'fr-FR': 'Finance', 'zh-CN': '金融', 'zh-TW': '金融', 'ru-RU': 'Финансы', - 'ja-JP': '金融' + 'ja-JP': '金融', + 'pt-PT': 'Finanças' }, 旅游: { + 'el-GR': 'Τουρισμός', 'en-US': 'Travel', + 'es-ES': 'Viajes', + 'fr-FR': 'Voyages', 'zh-CN': '旅游', 'zh-TW': '旅遊', 'ru-RU': 'Путешествия', - 'ja-JP': '旅行' + 'ja-JP': '旅行', + 'pt-PT': 'Viagens' }, 管理: { + 'el-GR': 'Διοίκηση', 'en-US': 'Management', + 'es-ES': 'Gestión', + 'fr-FR': 'Gestion', 'zh-CN': '管理', 'zh-TW': '管理', 'ru-RU': 'Управление', - 'ja-JP': '管理' + 'ja-JP': '管理', + 'pt-PT': 'Gestão' } } diff --git a/src/renderer/src/pages/home/Inputbar/GenerateImageButton.tsx b/src/renderer/src/pages/home/Inputbar/GenerateImageButton.tsx new file mode 100644 index 000000000..41b6ccc50 --- /dev/null +++ b/src/renderer/src/pages/home/Inputbar/GenerateImageButton.tsx @@ -0,0 +1,36 @@ +import { PictureOutlined } from '@ant-design/icons' +import { isGenerateImageModel } from '@renderer/config/models' +import { Assistant, Model } from '@renderer/types' +import { Tooltip } from 'antd' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' + +interface Props { + assistant: Assistant + model: Model + ToolbarButton: any + onEnableGenerateImage: () => void +} + +const GenerateImageButton: FC = ({ model, ToolbarButton, assistant, onEnableGenerateImage }) => { + const { t } = useTranslation() + + if (!isGenerateImageModel(model)) { + return null + } + + return ( + + + + + + ) +} + +export default GenerateImageButton diff --git a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx index dce62038a..1dadb0545 100644 --- a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx +++ b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx @@ -10,7 +10,7 @@ import { QuestionCircleOutlined } from '@ant-design/icons' import TranslateButton from '@renderer/components/TranslateButton' -import { isFunctionCallingModel, isVisionModel, isWebSearchModel } from '@renderer/config/models' +import { isFunctionCallingModel, isGenerateImageModel, isVisionModel, isWebSearchModel } from '@renderer/config/models' import db from '@renderer/databases' import { useAssistant } from '@renderer/hooks/useAssistant' import { useMessageOperations } from '@renderer/hooks/useMessageOperations' @@ -44,6 +44,7 @@ import styled from 'styled-components' import NarrowLayout from '../Messages/NarrowLayout' import AttachmentButton from './AttachmentButton' import AttachmentPreview from './AttachmentPreview' +import GenerateImageButton from './GenerateImageButton' import KnowledgeBaseButton from './KnowledgeBaseButton' import MCPToolsButton from './MCPToolsButton' import MentionModelsButton from './MentionModelsButton' @@ -626,7 +627,6 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = } const onEnableWebSearch = () => { - console.log(assistant) if (!isWebSearchModel(model)) { if (!WebSearchService.isWebSearchEnabled()) { window.modal.confirm({ @@ -645,10 +645,17 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = updateAssistant({ ...assistant, enableWebSearch: !assistant.enableWebSearch }) } + const onEnableGenerateImage = () => { + updateAssistant({ ...assistant, enableGenerateImage: !assistant.enableGenerateImage }) + } + useEffect(() => { if (!isWebSearchModel(model) && !WebSearchService.isWebSearchEnabled() && assistant.enableWebSearch) { updateAssistant({ ...assistant, enableWebSearch: false }) } + if (!isGenerateImageModel(model) && assistant.enableGenerateImage) { + updateAssistant({ ...assistant, enableGenerateImage: false }) + } }, [assistant, model, updateAssistant]) const resetHeight = () => { @@ -738,6 +745,12 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) = ToolbarButton={ToolbarButton} /> )} + onMentionModel(model, mentionFromKeyboard)} diff --git a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx index 2b314014e..be3c64faa 100644 --- a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx +++ b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx @@ -135,7 +135,7 @@ const MessageAnchorLine: FC = ({ messages }) => { messageElement.scrollIntoView({ behavior: 'smooth', block: 'start' }) }, - [messages, setSelectedMessage] + [setSelectedMessage] ) if (messages.length === 0) return null diff --git a/src/renderer/src/pages/home/Messages/MessageContent.tsx b/src/renderer/src/pages/home/Messages/MessageContent.tsx index 6d5f7b69f..eea785032 100644 --- a/src/renderer/src/pages/home/Messages/MessageContent.tsx +++ b/src/renderer/src/pages/home/Messages/MessageContent.tsx @@ -16,6 +16,7 @@ import styled from 'styled-components' import Markdown from '../Markdown/Markdown' import MessageAttachments from './MessageAttachments' import MessageError from './MessageError' +import MessageImage from './MessageImage' import MessageSearchResults from './MessageSearchResults' import MessageThought from './MessageThought' import MessageTools from './MessageTools' @@ -150,6 +151,7 @@ const MessageContent: React.FC = ({ message: _message, model }) => { + {message.metadata?.generateImage && } {message.translatedContent && ( diff --git a/src/renderer/src/pages/home/Messages/MessageImage.tsx b/src/renderer/src/pages/home/Messages/MessageImage.tsx new file mode 100644 index 000000000..0f24eded3 --- /dev/null +++ b/src/renderer/src/pages/home/Messages/MessageImage.tsx @@ -0,0 +1,29 @@ +import { Message } from '@renderer/types' +import { Image as AntdImage } from 'antd' +import { FC } from 'react' +import styled from 'styled-components' + +interface Props { + message: Message +} + +const MessageImage: FC = ({ message }) => { + return ( + + {message.metadata?.generateImage!.images.map((image, index) => ( + + ))} + + ) +} +const Container = styled.div` + display: flex; + flex-direction: row; + gap: 10px; + margin-top: 8px; +` +const Image = styled(AntdImage)` + border-radius: 10px; +` + +export default MessageImage diff --git a/src/renderer/src/pages/home/Messages/MessageMenubar.tsx b/src/renderer/src/pages/home/Messages/MessageMenubar.tsx index 0eb5fa19e..903e1fe80 100644 --- a/src/renderer/src/pages/home/Messages/MessageMenubar.tsx +++ b/src/renderer/src/pages/home/Messages/MessageMenubar.tsx @@ -15,8 +15,8 @@ import { UploadOutlined } from '@ant-design/icons' import ObsidianExportPopup from '@renderer/components/Popups/ObsidianExportPopup' import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup' import TextEditPopup from '@renderer/components/Popups/TextEditPopup' -import { TranslateLanguageOptions } from '@renderer/config/translate' import { isReasoningModel } from '@renderer/config/models' +import { TranslateLanguageOptions } from '@renderer/config/translate' import { useMessageOperations } from '@renderer/hooks/useMessageOperations' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import { getMessageTitle, resetAssistantMessage } from '@renderer/services/MessagesService' @@ -24,7 +24,6 @@ import { translateText } from '@renderer/services/TranslateService' import { Message, Model } from '@renderer/types' import { Assistant, Topic } from '@renderer/types' import { captureScrollableDivAsBlob, captureScrollableDivAsDataURL, removeTrailingDoubleSpaces } from '@renderer/utils' -import { withMessageThought } from '@renderer/utils/formats' import { exportMarkdownToJoplin, exportMarkdownToNotion, @@ -32,12 +31,13 @@ import { exportMessageAsMarkdown, messageToMarkdown } from '@renderer/utils/export' +import { withMessageThought } from '@renderer/utils/formats' import { Button, Dropdown, Popconfirm, Tooltip } from 'antd' import dayjs from 'dayjs' +import { clone } from 'lodash' import { FC, memo, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' -import { clone } from 'lodash' interface Props { message: Message @@ -242,8 +242,8 @@ const MessageMenubar: FC = (props) => { key: 'obsidian', onClick: async () => { const markdown = messageToMarkdown(message) - const title = getMessageTitle(message) - await ObsidianExportPopup.show({ title, markdown }) + const title = topic.name?.replace(/\//g, '_') || 'Untitled' + await ObsidianExportPopup.show({ title, markdown, processingMethod: '1' }) } }, { @@ -258,7 +258,7 @@ const MessageMenubar: FC = (props) => { ] } ], - [message, messageContainerRef, onEdit, onNewBranch, t] + [message, messageContainerRef, onEdit, onNewBranch, t, topic.name] ) const onRegenerate = async (e: React.MouseEvent | undefined) => { diff --git a/src/renderer/src/pages/home/Messages/Messages.tsx b/src/renderer/src/pages/home/Messages/Messages.tsx index 47ffa60d7..ffd0f26f6 100644 --- a/src/renderer/src/pages/home/Messages/Messages.tsx +++ b/src/renderer/src/pages/home/Messages/Messages.tsx @@ -26,8 +26,8 @@ import BeatLoader from 'react-spinners/BeatLoader' import styled from 'styled-components' import ChatNavigation from './ChatNavigation' -import MessageGroup from './MessageGroup' import MessageAnchorLine from './MessageAnchorLine' +import MessageGroup from './MessageGroup' import NarrowLayout from './NarrowLayout' import NewTopicButton from './NewTopicButton' import Prompt from './Prompt' @@ -139,7 +139,13 @@ const Messages: React.FC = ({ assistant, topic, setActiveTopic }) EventEmitter.on(EVENT_NAMES.NEW_BRANCH, async (index: number) => { const newTopic = getDefaultTopic(assistant.id) newTopic.name = topic.name - const branchMessages = take(messages, messages.length - index) + const currentMessages = messagesRef.current + + // 复制消息并且更新 topicId + const branchMessages = take(currentMessages, currentMessages.length - index).map((msg) => ({ + ...msg, + topicId: newTopic.id + })) // 将分支的消息放入数据库 await db.topics.add({ id: newTopic.id, messages: branchMessages }) diff --git a/src/renderer/src/pages/home/Tabs/SettingsTab.tsx b/src/renderer/src/pages/home/Tabs/SettingsTab.tsx index 68d5fc998..e796c4e91 100644 --- a/src/renderer/src/pages/home/Tabs/SettingsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/SettingsTab.tsx @@ -24,6 +24,7 @@ import { setFontSize, setMathEngine, setMessageFont, + setMessageNavigation, setMessageStyle, setMultiModelMessageStyle, setPasteLongTextAsFile, @@ -31,7 +32,6 @@ import { setRenderInputMessageAsMarkdown, setShowInputEstimatedTokens, setShowMessageDivider, - setMessageNavigation, setThoughtAutoCollapse } from '@renderer/store/settings' import { Assistant, AssistantSettings, CodeStyleVarious, ThemeMode, TranslateLanguageVarious } from '@renderer/types' diff --git a/src/renderer/src/pages/home/Tabs/TopicsTab.tsx b/src/renderer/src/pages/home/Tabs/TopicsTab.tsx index 79d8776c1..7d6f46294 100644 --- a/src/renderer/src/pages/home/Tabs/TopicsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/TopicsTab.tsx @@ -262,7 +262,7 @@ const Topics: FC = ({ assistant: _assistant, activeTopic, setActiveTopic key: 'obsidian', onClick: async () => { const markdown = await topicToMarkdown(topic) - await ObsidianExportPopup.show({ title: topic.name, markdown }) + await ObsidianExportPopup.show({ title: topic.name, markdown, processingMethod: '3' }) } }, { diff --git a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx index 2dab9434e..e7cbe9cf9 100644 --- a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx +++ b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx @@ -28,6 +28,7 @@ import styled from 'styled-components' import KnowledgeSearchPopup from './components/KnowledgeSearchPopup' import KnowledgeSettings from './components/KnowledgeSettings' import StatusIcon from './components/StatusIcon' +import KnowledgeSettingsPopup from './components/KnowledgeSettingsPopup' const { Dragger } = Upload const { Title } = Typography @@ -62,6 +63,7 @@ const KnowledgeContent: FC = ({ selectedBase }) => { } = useKnowledge(selectedBase.id || '') const providerName = getProviderName(base?.model.provider || '') + const rerankModelProviderName = getProviderName(base?.rerankModel?.provider || '') const disabled = !base?.version || !providerName if (!base) { @@ -458,13 +460,34 @@ const KnowledgeContent: FC = ({ selectedBase }) => { - - - {base.model.name} - {t('models.dimensions', { dimensions: base.dimensions || 0 })} - {providerName && {providerName}} - diff --git a/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx b/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx index 68fbd104a..8e70107c8 100644 --- a/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx +++ b/src/renderer/src/pages/settings/DataSettings/WebDavSettings.tsx @@ -12,13 +12,13 @@ import { setWebdavSyncInterval as _setWebdavSyncInterval, setWebdavUser as _setWebdavUser } from '@renderer/store/settings' +import { formatFileSize } from '@renderer/utils' import { Button, Input, Modal, Select, Spin, Tooltip } from 'antd' import dayjs from 'dayjs' import { FC, useState } from 'react' import { useTranslation } from 'react-i18next' import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..' -import { formatFileSize } from '@renderer/utils' interface BackupFile { fileName: string diff --git a/src/renderer/src/pages/settings/GeneralSettings.tsx b/src/renderer/src/pages/settings/GeneralSettings.tsx index e73e33824..65ef1102e 100644 --- a/src/renderer/src/pages/settings/GeneralSettings.tsx +++ b/src/renderer/src/pages/settings/GeneralSettings.tsx @@ -13,13 +13,47 @@ import { useTranslation } from 'react-i18next' import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '.' const GeneralSettings: FC = () => { - const { language, proxyUrl: storeProxyUrl, theme, setTray, tray, proxyMode: storeProxyMode } = useSettings() + const { + language, + proxyUrl: storeProxyUrl, + theme, + setLaunch, + setTray, + launchOnBoot, + launchToTray, + trayOnClose, + tray, + proxyMode: storeProxyMode + } = useSettings() const [proxyUrl, setProxyUrl] = useState(storeProxyUrl) const { theme: themeMode } = useTheme() - const updateTray = (value: boolean) => { - setTray(value) - window.api.setTray(value) + const updateTray = (isShowTray: boolean) => { + setTray(isShowTray) + //only set tray on close/launch to tray when tray is enabled + if (!isShowTray) { + updateTrayOnClose(false) + updateLaunchToTray(false) + } + } + + const updateTrayOnClose = (isTrayOnClose: boolean) => { + setTray(undefined, isTrayOnClose) + //in case tray is not enabled, enable it + if (isTrayOnClose && !tray) { + updateTray(true) + } + } + + const updateLaunchOnBoot = (isLaunchOnBoot: boolean) => { + setLaunch(isLaunchOnBoot) + } + + const updateLaunchToTray = (isLaunchToTray: boolean) => { + setLaunch(undefined, isLaunchToTray) + if (isLaunchToTray && !tray) { + updateTray(true) + } } const dispatch = useAppDispatch() @@ -52,8 +86,10 @@ const GeneralSettings: FC = () => { dispatch(setProxyMode(mode)) if (mode === 'system') { window.api.setProxy('system') + dispatch(_setProxyUrl(undefined)) } else if (mode === 'none') { window.api.setProxy(undefined) + dispatch(_setProxyUrl(undefined)) } } @@ -62,7 +98,11 @@ const GeneralSettings: FC = () => { { value: 'zh-TW', label: '中文(繁体)', flag: '🇭🇰' }, { value: 'en-US', label: 'English', flag: '🇺🇸' }, { value: 'ja-JP', label: '日本語', flag: '🇯🇵' }, - { value: 'ru-RU', label: 'Русский', flag: '🇷🇺' } + { value: 'ru-RU', label: 'Русский', flag: '🇷🇺' }, + { value: 'el-GR', label: 'Ελληνικά', flag: '🇬🇷' }, + { value: 'es-ES', label: 'Español', flag: '🇪🇸' }, + { value: 'fr-FR', label: 'Français', flag: '🇫🇷' }, + { value: 'pt-PT', label: 'Português', flag: '🇵🇹' } ] return ( @@ -111,11 +151,32 @@ const GeneralSettings: FC = () => { )} + + + {t('settings.launch.title')} - {t('settings.tray.title')} + {t('settings.launch.onboot')} + updateLaunchOnBoot(checked)} /> + + + + {t('settings.launch.totray')} + updateLaunchToTray(checked)} /> + + + + {t('settings.tray.title')} + + + {t('settings.tray.show')} updateTray(checked)} /> + + + {t('settings.tray.onclose')} + updateTrayOnClose(checked)} disabled={!tray} /> + ) diff --git a/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx b/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx index c751ebc8c..4eb8895b9 100644 --- a/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx @@ -1,9 +1,9 @@ import { SearchOutlined } from '@ant-design/icons' import { useTheme } from '@renderer/context/ThemeProvider' -import { MCPServer } from '@renderer/types' +import type { MCPServer } from '@renderer/types' import { Button, Input, Space, Spin, Table, Typography } from 'antd' import { npxFinder } from 'npx-scope-finder' -import { FC, useState } from 'react' +import { type FC, useState } from 'react' import { useTranslation } from 'react-i18next' import { SettingDivider, SettingGroup, SettingTitle } from '..' @@ -21,7 +21,7 @@ interface SearchResult { const NpxSearch: FC = () => { const { theme } = useTheme() const { t } = useTranslation() - const { Paragraph, Text } = Typography + const { Paragraph, Text, Link } = Typography // Add new state variables for npm scope search const [npmScope, setNpmScope] = useState('@modelcontextprotocol') @@ -59,8 +59,12 @@ const NpxSearch: FC = () => { if (formattedResults.length === 0) { window.message.info(t('settings.mcp.npx_list.no_packages')) } - } catch (error: any) { - window.message.error(`${t('settings.mcp.npx_list.search_error')}: ${error.message}`) + } catch (error: unknown) { + if (error instanceof Error) { + window.message.error(`${t('settings.mcp.npx_list.search_error')}: ${error.message}`) + } else { + window.message.error(t('settings.mcp.npx_list.search_error')) + } } finally { setSearchLoading(false) } @@ -92,7 +96,7 @@ const NpxSearch: FC = () => { ) : searchResults.length > 0 ? ( - + { { title: t('settings.mcp.npx_list.description'), key: 'description', + ellipsis: true, render: (_, record: SearchResult) => ( - - {record.description} - + + {record.description} + {t('settings.mcp.npx_list.usage')}: {record.usage} - - {record.npmLink} - + + + {record.npmLink} + + ) }, @@ -125,7 +132,7 @@ const NpxSearch: FC = () => { { title: t('settings.mcp.npx_list.actions'), key: 'actions', - width: '100px', + width: '120px', render: (_, record: SearchResult) => ( + ProviderSettingsPopup.show({ provider })} + /> )} = ({ provider: _provider }) => { )} {provider.id === 'copilot' && } - - {t('common.models')} + - {!isEmpty(models) && ( + {t('common.models')} + {!isEmpty(models) && } + + {!isEmpty(models) && ( + - )} - - + /> + + )} + - + ) } diff --git a/src/renderer/src/providers/GeminiProvider.ts b/src/renderer/src/providers/GeminiProvider.ts index 653877e35..a21385fb7 100644 --- a/src/renderer/src/providers/GeminiProvider.ts +++ b/src/renderer/src/providers/GeminiProvider.ts @@ -1,3 +1,10 @@ +import { + ContentListUnion, + createPartFromBase64, + FinishReason, + GenerateContentResponse, + GoogleGenAI +} from '@google/genai' import { Content, FileDataPart, @@ -35,16 +42,19 @@ import axios from 'axios' import { isEmpty, takeRight } from 'lodash' import OpenAI from 'openai' -import { CompletionsParams } from '.' +import { ChunkCallbackData, CompletionsParams } from '.' import BaseProvider from './BaseProvider' export default class GeminiProvider extends BaseProvider { private sdk: GoogleGenerativeAI private requestOptions: RequestOptions + private imageSdk: GoogleGenAI constructor(provider: Provider) { super(provider) this.sdk = new GoogleGenerativeAI(this.apiKey) + /// this sdk is experimental + this.imageSdk = new GoogleGenAI({ apiKey: this.apiKey }) this.requestOptions = { baseUrl: this.getBaseURL() } @@ -105,6 +115,25 @@ export default class GeminiProvider extends BaseProvider { const role = message.role === 'user' ? 'user' : 'model' const parts: Part[] = [{ text: await this.getMessageContent(message) }] + // Add any generated images from previous responses + if (message.metadata?.generateImage?.images && message.metadata.generateImage.images.length > 0) { + for (const imageUrl of message.metadata.generateImage.images) { + if (imageUrl && imageUrl.startsWith('data:')) { + // Extract base64 data and mime type from the data URL + const matches = imageUrl.match(/^data:(.+);base64,(.*)$/) + if (matches && matches.length === 3) { + const mimeType = matches[1] + const base64Data = matches[2] + parts.push({ + inlineData: { + data: base64Data, + mimeType: mimeType + } + } as InlineDataPart) + } + } + } + } for (const file of message.files || []) { if (file.type === FileTypes.IMAGE) { @@ -179,180 +208,184 @@ export default class GeminiProvider extends BaseProvider { * @param onFilterMessages - The onFilterMessages callback */ public async completions({ messages, assistant, mcpTools, onChunk, onFilterMessages }: CompletionsParams) { - const defaultModel = getDefaultModel() - const model = assistant.model || defaultModel - const { contextCount, maxTokens, streamOutput } = getAssistantSettings(assistant) + if (assistant.enableGenerateImage) { + await this.generateImageExp({ messages, assistant, onFilterMessages, onChunk }) + } else { + const defaultModel = getDefaultModel() + const model = assistant.model || defaultModel + const { contextCount, maxTokens, streamOutput } = getAssistantSettings(assistant) - const userMessages = filterUserRoleStartMessages( - filterEmptyMessages(filterContextMessages(takeRight(messages, contextCount + 2))) - ) - onFilterMessages(userMessages) + const userMessages = filterUserRoleStartMessages( + filterEmptyMessages(filterContextMessages(takeRight(messages, contextCount + 2))) + ) + onFilterMessages(userMessages) - const userLastMessage = userMessages.pop() + const userLastMessage = userMessages.pop() - const history: Content[] = [] + const history: Content[] = [] - for (const message of userMessages) { - history.push(await this.getMessageContents(message)) - } - - const tools = mcpToolsToGeminiTools(mcpTools) - const toolResponses: MCPToolResponse[] = [] - - if (assistant.enableWebSearch && isWebSearchModel(model)) { - tools.push({ - // @ts-ignore googleSearch is not a valid tool for Gemini - googleSearch: {} - }) - } - - const geminiModel = this.sdk.getGenerativeModel( - { - model: model.id, - ...(isGemmaModel(model) ? {} : { systemInstruction: assistant.prompt }), - safetySettings: this.getSafetySettings(model.id), - tools: tools, - generationConfig: { - maxOutputTokens: maxTokens, - temperature: assistant?.settings?.temperature, - topP: assistant?.settings?.topP, - ...this.getCustomParameters(assistant) - } - }, - this.requestOptions - ) - - const chat = geminiModel.startChat({ history }) - const messageContents = await this.getMessageContents(userLastMessage!) - - if (isGemmaModel(model) && assistant.prompt) { - const isFirstMessage = history.length === 0 - if (isFirstMessage) { - const systemMessage = { - role: 'user', - parts: [ - { - text: - 'user\n' + - assistant.prompt + - '\n' + - 'user\n' + - messageContents.parts[0].text + - '' - } - ] - } - messageContents.parts = systemMessage.parts + for (const message of userMessages) { + history.push(await this.getMessageContents(message)) } - } - const start_time_millsec = new Date().getTime() - const { abortController, cleanup } = this.createAbortController(userLastMessage?.id) - const { signal } = abortController + const tools = mcpToolsToGeminiTools(mcpTools) + const toolResponses: MCPToolResponse[] = [] - if (!streamOutput) { - const { response } = await chat.sendMessage(messageContents.parts, { signal }) - const time_completion_millsec = new Date().getTime() - start_time_millsec - onChunk({ - text: response.candidates?.[0].content.parts[0].text, - usage: { - prompt_tokens: response.usageMetadata?.promptTokenCount || 0, - completion_tokens: response.usageMetadata?.candidatesTokenCount || 0, - total_tokens: response.usageMetadata?.totalTokenCount || 0 - }, - metrics: { - completion_tokens: response.usageMetadata?.candidatesTokenCount, - time_completion_millsec, - time_first_token_millsec: 0 - }, - search: response.candidates?.[0]?.groundingMetadata - }) - return - } - - const userMessagesStream = await chat.sendMessageStream(messageContents.parts, { signal }) - let time_first_token_millsec = 0 - - const processStream = async (stream: GenerateContentStreamResult, idx: number) => { - for await (const chunk of stream.stream) { - if (window.keyv.get(EVENT_NAMES.CHAT_COMPLETION_PAUSED)) break - - if (time_first_token_millsec == 0) { - time_first_token_millsec = new Date().getTime() - start_time_millsec - } - - const time_completion_millsec = new Date().getTime() - start_time_millsec - - const functionCalls = chunk.functionCalls() - - if (functionCalls) { - const fcallParts: FunctionCallPart[] = [] - const fcRespParts: FunctionResponsePart[] = [] - for (const call of functionCalls) { - console.log('Function call:', call) - fcallParts.push({ functionCall: call } as FunctionCallPart) - const mcpTool = geminiFunctionCallToMcpTool(mcpTools, call) - if (mcpTool) { - upsertMCPToolResponse( - toolResponses, - { - tool: mcpTool, - status: 'invoking', - id: `${call.name}-${idx}` - }, - onChunk - ) - const toolCallResponse = await callMCPTool(mcpTool) - fcRespParts.push({ - functionResponse: { - name: mcpTool.id, - response: toolCallResponse - } - }) - upsertMCPToolResponse( - toolResponses, - { - tool: mcpTool, - status: 'done', - response: toolCallResponse, - id: `${call.name}-${idx}` - }, - onChunk - ) - } - } - - if (fcRespParts) { - history.push(messageContents) - history.push({ - role: 'model', - parts: fcallParts - }) - const newChat = geminiModel.startChat({ history }) - const newStream = await newChat.sendMessageStream(fcRespParts, { signal }) - await processStream(newStream, idx + 1) - } - } - - onChunk({ - text: chunk.text(), - usage: { - prompt_tokens: chunk.usageMetadata?.promptTokenCount || 0, - completion_tokens: chunk.usageMetadata?.candidatesTokenCount || 0, - total_tokens: chunk.usageMetadata?.totalTokenCount || 0 - }, - metrics: { - completion_tokens: chunk.usageMetadata?.candidatesTokenCount, - time_completion_millsec, - time_first_token_millsec - }, - search: chunk.candidates?.[0]?.groundingMetadata, - mcpToolResponse: toolResponses + if (assistant.enableWebSearch && isWebSearchModel(model)) { + tools.push({ + // @ts-ignore googleSearch is not a valid tool for Gemini + googleSearch: {} }) } - } - await processStream(userMessagesStream, 0).finally(cleanup) + const geminiModel = this.sdk.getGenerativeModel( + { + model: model.id, + ...(isGemmaModel(model) ? {} : { systemInstruction: assistant.prompt }), + safetySettings: this.getSafetySettings(model.id), + tools: tools, + generationConfig: { + maxOutputTokens: maxTokens, + temperature: assistant?.settings?.temperature, + topP: assistant?.settings?.topP, + ...this.getCustomParameters(assistant) + } + }, + this.requestOptions + ) + + const chat = geminiModel.startChat({ history }) + const messageContents = await this.getMessageContents(userLastMessage!) + + if (isGemmaModel(model) && assistant.prompt) { + const isFirstMessage = history.length === 0 + if (isFirstMessage) { + const systemMessage = { + role: 'user', + parts: [ + { + text: + 'user\n' + + assistant.prompt + + '\n' + + 'user\n' + + messageContents.parts[0].text + + '' + } + ] + } + messageContents.parts = systemMessage.parts + } + } + + const start_time_millsec = new Date().getTime() + const { abortController, cleanup } = this.createAbortController(userLastMessage?.id) + const { signal } = abortController + + if (!streamOutput) { + const { response } = await chat.sendMessage(messageContents.parts, { signal }) + const time_completion_millsec = new Date().getTime() - start_time_millsec + onChunk({ + text: response.candidates?.[0].content.parts[0].text, + usage: { + prompt_tokens: response.usageMetadata?.promptTokenCount || 0, + completion_tokens: response.usageMetadata?.candidatesTokenCount || 0, + total_tokens: response.usageMetadata?.totalTokenCount || 0 + }, + metrics: { + completion_tokens: response.usageMetadata?.candidatesTokenCount, + time_completion_millsec, + time_first_token_millsec: 0 + }, + search: response.candidates?.[0]?.groundingMetadata + }) + return + } + + const userMessagesStream = await chat.sendMessageStream(messageContents.parts, { signal }) + let time_first_token_millsec = 0 + + const processStream = async (stream: GenerateContentStreamResult, idx: number) => { + for await (const chunk of stream.stream) { + if (window.keyv.get(EVENT_NAMES.CHAT_COMPLETION_PAUSED)) break + + if (time_first_token_millsec == 0) { + time_first_token_millsec = new Date().getTime() - start_time_millsec + } + + const time_completion_millsec = new Date().getTime() - start_time_millsec + + const functionCalls = chunk.functionCalls() + + if (functionCalls) { + const fcallParts: FunctionCallPart[] = [] + const fcRespParts: FunctionResponsePart[] = [] + for (const call of functionCalls) { + console.log('Function call:', call) + fcallParts.push({ functionCall: call } as FunctionCallPart) + const mcpTool = geminiFunctionCallToMcpTool(mcpTools, call) + if (mcpTool) { + upsertMCPToolResponse( + toolResponses, + { + tool: mcpTool, + status: 'invoking', + id: `${call.name}-${idx}` + }, + onChunk + ) + const toolCallResponse = await callMCPTool(mcpTool) + fcRespParts.push({ + functionResponse: { + name: mcpTool.id, + response: toolCallResponse + } + }) + upsertMCPToolResponse( + toolResponses, + { + tool: mcpTool, + status: 'done', + response: toolCallResponse, + id: `${call.name}-${idx}` + }, + onChunk + ) + } + } + + if (fcRespParts) { + history.push(messageContents) + history.push({ + role: 'model', + parts: fcallParts + }) + const newChat = geminiModel.startChat({ history }) + const newStream = await newChat.sendMessageStream(fcRespParts, { signal }) + await processStream(newStream, idx + 1) + } + } + + onChunk({ + text: chunk.text(), + usage: { + prompt_tokens: chunk.usageMetadata?.promptTokenCount || 0, + completion_tokens: chunk.usageMetadata?.candidatesTokenCount || 0, + total_tokens: chunk.usageMetadata?.totalTokenCount || 0 + }, + metrics: { + completion_tokens: chunk.usageMetadata?.candidatesTokenCount, + time_completion_millsec, + time_first_token_millsec + }, + search: chunk.candidates?.[0]?.groundingMetadata, + mcpToolResponse: toolResponses + }) + } + } + + await processStream(userMessagesStream, 0).finally(cleanup) + } } /** @@ -536,6 +569,150 @@ export default class GeminiProvider extends BaseProvider { return [] } + /** + * 生成图像 + * @param messages - 消息列表 + * @param assistant - 助手配置 + * @param onChunk - 处理生成块的回调 + * @param onFilterMessages - 过滤消息的回调 + * @returns Promise + */ + private async generateImageExp({ messages, assistant, onChunk, onFilterMessages }: CompletionsParams): Promise { + const defaultModel = getDefaultModel() + const model = assistant.model || defaultModel + const { contextCount } = getAssistantSettings(assistant) + + const userMessages = filterUserRoleStartMessages(filterContextMessages(takeRight(messages, contextCount + 2))) + onFilterMessages(userMessages) + + const userLastMessage = userMessages.pop() + if (!userLastMessage) { + throw new Error('No user message found') + } + + const history: Content[] = [] + + for (const message of userMessages) { + history.push(await this.getMessageContents(message)) + } + + const userLastMessageContent = await this.getMessageContents(userLastMessage) + const allContents = [...history, userLastMessageContent] + + let contents: ContentListUnion = allContents.length > 0 ? (allContents as ContentListUnion) : [] + + contents = await this.addImageFileToContents(userLastMessage, contents) + + const response = await this.callGeminiGenerateContent(model.id, contents) + + console.log('response', response) + + const { isValid, message } = this.isValidGeminiResponse(response) + if (!isValid) { + throw new Error(`Gemini API error: ${message}`) + } + + this.processGeminiImageResponse(response, onChunk) + } + + /** + * 添加图片文件到内容列表 + * @param message - 用户消息 + * @param contents - 内容列表 + * @returns 更新后的内容列表 + */ + private async addImageFileToContents(message: Message, contents: ContentListUnion): Promise { + if (message.files && message.files.length > 0) { + const file = message.files[0] + const fileContent = await window.api.file.base64Image(file.id + file.ext) + + if (fileContent && fileContent.base64) { + const contentsArray = Array.isArray(contents) ? contents : [contents] + return [...contentsArray, createPartFromBase64(fileContent.base64, fileContent.mime)] + } + } + return contents + } + + /** + * 调用Gemini API生成内容 + * @param modelId - 模型ID + * @param contents - 内容列表 + * @returns 生成结果 + */ + private async callGeminiGenerateContent( + modelId: string, + contents: ContentListUnion + ): Promise { + try { + return await this.imageSdk.models.generateContent({ + model: modelId, + contents: contents, + config: { + responseModalities: ['Text', 'Image'], + responseMimeType: 'text/plain' + } + }) + } catch (error) { + console.error('Gemini API error:', error) + throw error + } + } + + /** + * 检查Gemini响应是否有效 + * @param response - Gemini响应 + * @returns 是否有效 + */ + private isValidGeminiResponse(response: GenerateContentResponse): { isValid: boolean; message: string } { + return { + isValid: response?.candidates?.[0]?.finishReason === FinishReason.STOP ? true : false, + message: response?.candidates?.[0]?.finishReason || '' + } + } + + /** + * 处理Gemini图像响应 + * @param response - Gemini响应 + * @param onChunk - 处理生成块的回调 + */ + private processGeminiImageResponse(response: any, onChunk: (chunk: ChunkCallbackData) => void): void { + const parts = response.candidates[0].content.parts + + // 提取图像数据 + const images = parts + .filter((part: Part) => part.inlineData) + .map((part: Part) => { + if (!part.inlineData) { + return null + } + const dataPrefix = `data:${part.inlineData.mimeType || 'image/png'};base64,` + return part.inlineData.data.startsWith('data:') ? part.inlineData.data : dataPrefix + part.inlineData.data + }) + + // 提取文本数据 + const text = parts + .filter((part: Part) => part.text !== undefined) + .map((part: Part) => part.text) + .join('') + + // 返回结果 + onChunk({ + text, + generateImage: { + images + }, + usage: { + prompt_tokens: response.usageMetadata?.promptTokenCount || 0, + completion_tokens: response.usageMetadata?.candidatesTokenCount || 0, + total_tokens: response.usageMetadata?.totalTokenCount || 0 + }, + metrics: { + completion_tokens: response.usageMetadata?.candidatesTokenCount + } + }) + } + /** * Check if the model is valid * @param model - The model diff --git a/src/renderer/src/providers/OpenAIProvider.ts b/src/renderer/src/providers/OpenAIProvider.ts index 8764f4991..b776aec5b 100644 --- a/src/renderer/src/providers/OpenAIProvider.ts +++ b/src/renderer/src/providers/OpenAIProvider.ts @@ -474,7 +474,7 @@ export default class OpenAIProvider extends BaseProvider { const finishReason = chunk.choices[0]?.finish_reason - if (delta?.tool_calls) { + if (delta?.tool_calls?.length) { const chunkToolCalls = delta.tool_calls for (const t of chunkToolCalls) { const { index, id, function: fn, type } = t diff --git a/src/renderer/src/providers/index.d.ts b/src/renderer/src/providers/index.d.ts index 40b9f6803..f21880b4e 100644 --- a/src/renderer/src/providers/index.d.ts +++ b/src/renderer/src/providers/index.d.ts @@ -9,6 +9,7 @@ interface ChunkCallbackData { search?: GroundingMetadata citations?: string[] mcpToolResponse?: MCPToolResponse[] + generateImage?: GenerateImageResponse } interface CompletionsParams { diff --git a/src/renderer/src/services/ApiService.ts b/src/renderer/src/services/ApiService.ts index a8e2e3c2e..492909126 100644 --- a/src/renderer/src/services/ApiService.ts +++ b/src/renderer/src/services/ApiService.ts @@ -111,7 +111,7 @@ export async function fetchChatCompletion({ messages: filterUsefulMessages(messages), assistant, onFilterMessages: (messages) => (_messages = messages), - onChunk: ({ text, reasoning_content, usage, metrics, search, citations, mcpToolResponse }) => { + onChunk: ({ text, reasoning_content, usage, metrics, search, citations, mcpToolResponse, generateImage }) => { message.content = message.content + text || '' message.usage = usage message.metrics = metrics @@ -127,6 +127,12 @@ export async function fetchChatCompletion({ if (mcpToolResponse) { message.metadata = { ...message.metadata, mcpTools: cloneDeep(mcpToolResponse) } } + if (generateImage) { + message.metadata = { + ...message.metadata, + generateImage: generateImage + } + } // Handle citations from Perplexity API if (isFirstChunk && citations) { @@ -162,6 +168,7 @@ export async function fetchChatCompletion({ } } } + console.log('message', message) } catch (error: any) { if (isAbortError(error)) { message.status = 'paused' diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 6693d4044..4eb1bbed5 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -800,6 +800,9 @@ const migrateConfig = { }, '83': (state: RootState) => { state.settings.messageNavigation = 'buttons' + state.settings.launchOnBoot = false + state.settings.launchToTray = false + state.settings.trayOnClose = true return state } } diff --git a/src/renderer/src/store/settings.ts b/src/renderer/src/store/settings.ts index b532c8e67..c6106b382 100644 --- a/src/renderer/src/store/settings.ts +++ b/src/renderer/src/store/settings.ts @@ -28,6 +28,9 @@ export interface SettingsState { showMessageDivider: boolean messageFont: 'system' | 'serif' showInputEstimatedTokens: boolean + launchOnBoot: boolean + launchToTray: boolean + trayOnClose: boolean tray: boolean theme: ThemeMode windowStyle: 'transparent' | 'opaque' @@ -83,8 +86,10 @@ export interface SettingsState { yuqueToken: string | null yuqueUrl: string | null yuqueRepoId: string | null - obsidianApiKey: string | null - obsidianUrl: string | null + //obsidian settings obsidianVault, obisidanFolder + obsidianValut: string | null + obsidianFolder: string | null + obsidianTages: string | null joplinToken: string | null joplinUrl: string | null } @@ -103,6 +108,9 @@ const initialState: SettingsState = { showMessageDivider: true, messageFont: 'system', showInputEstimatedTokens: false, + launchOnBoot: false, + launchToTray: false, + trayOnClose: true, tray: true, theme: ThemeMode.auto, windowStyle: 'transparent', @@ -155,8 +163,9 @@ const initialState: SettingsState = { yuqueToken: '', yuqueUrl: '', yuqueRepoId: '', - obsidianApiKey: '', - obsidianUrl: '', + obsidianValut: '', + obsidianFolder: '', + obsidianTages: '', joplinToken: '', joplinUrl: '' } @@ -205,9 +214,18 @@ const settingsSlice = createSlice({ setShowInputEstimatedTokens: (state, action: PayloadAction) => { state.showInputEstimatedTokens = action.payload }, + setLaunchOnBoot: (state, action: PayloadAction) => { + state.launchOnBoot = action.payload + }, + setLaunchToTray: (state, action: PayloadAction) => { + state.launchToTray = action.payload + }, setTray: (state, action: PayloadAction) => { state.tray = action.payload }, + setTrayOnClose: (state, action: PayloadAction) => { + state.trayOnClose = action.payload + }, setTheme: (state, action: PayloadAction) => { state.theme = action.payload }, @@ -354,11 +372,14 @@ const settingsSlice = createSlice({ setYuqueUrl: (state, action: PayloadAction) => { state.yuqueUrl = action.payload }, - setObsidianApiKey: (state, action: PayloadAction) => { - state.obsidianApiKey = action.payload + setObsidianValut: (state, action: PayloadAction) => { + state.obsidianValut = action.payload }, - setObsidianUrl: (state, action: PayloadAction) => { - state.obsidianUrl = action.payload + setObsidianFolder: (state, action: PayloadAction) => { + state.obsidianFolder = action.payload + }, + setObsidianTages: (state, action: PayloadAction) => { + state.obsidianTages = action.payload }, setJoplinToken: (state, action: PayloadAction) => { state.joplinToken = action.payload @@ -386,6 +407,9 @@ export const { setShowMessageDivider, setMessageFont, setShowInputEstimatedTokens, + setLaunchOnBoot, + setLaunchToTray, + setTrayOnClose, setTray, setTheme, setFontSize, @@ -434,8 +458,9 @@ export const { setYuqueToken, setYuqueRepoId, setYuqueUrl, - setObsidianApiKey, - setObsidianUrl, + setObsidianValut, + setObsidianFolder, + setObsidianTages, setJoplinToken, setJoplinUrl, setMessageNavigation diff --git a/src/renderer/src/types/index.ts b/src/renderer/src/types/index.ts index fcdabc2d2..0177ad965 100644 --- a/src/renderer/src/types/index.ts +++ b/src/renderer/src/types/index.ts @@ -16,6 +16,7 @@ export type Assistant = { settings?: Partial messages?: AssistantMessage[] enableWebSearch?: boolean + enableGenerateImage?: boolean } export type AssistantMessage = { @@ -77,6 +78,8 @@ export type Message = { webSearch?: WebSearchResponse // MCP Tools mcpTools?: MCPToolResponse[] + // Generate Image + generateImage?: GenerateImageResponse } // 多模型消息样式 multiModelMessageStyle?: 'horizontal' | 'vertical' | 'fold' | 'grid' @@ -196,9 +199,18 @@ export enum ThemeMode { auto = 'auto' } -export type LanguageVarious = 'zh-CN' | 'zh-TW' | 'en-US' | 'ru-RU' | 'ja-JP' +export type LanguageVarious = 'zh-CN' | 'zh-TW' | 'el-GR' | 'en-US' | 'es-ES' | 'fr-FR' | 'ja-JP' | 'pt-PT' | 'ru-RU' -export type TranslateLanguageVarious = 'chinese' | 'chinese-traditional' | 'english' | 'japanese' | 'russian' +export type TranslateLanguageVarious = + | 'chinese' + | 'chinese-traditional' + | 'greek' + | 'english' + | 'spanish' + | 'french' + | 'japanese' + | 'portuguese' + | 'russian' export type CodeStyleVarious = BuiltinTheme | 'auto' @@ -306,6 +318,10 @@ export type GenerateImageParams = { promptEnhancement?: boolean } +export type GenerateImageResponse = { + images: string[] +} + export interface TranslateHistory { id: string sourceText: string diff --git a/src/renderer/src/utils/export.ts b/src/renderer/src/utils/export.ts index b483e0e27..f8d74d040 100644 --- a/src/renderer/src/utils/export.ts +++ b/src/renderer/src/utils/export.ts @@ -320,58 +320,46 @@ export const exportMarkdownToYuque = async (title: string, content: string) => { /** * 导出Markdown到Obsidian + * @param attributes 文档属性 + * @param attributes.title 标题 + * @param attributes.created 创建时间 + * @param attributes.source 来源 + * @param attributes.tags 标签 + * @param attributes.processingMethod 处理方式 */ -export const exportMarkdownToObsidian = async ( - fileName: string, - markdown: string, - selectedPath: string, - isMdFile: boolean = false -) => { +export const exportMarkdownToObsidian = async (attributes: any) => { try { - const obsidianUrl = store.getState().settings.obsidianUrl - const obsidianApiKey = store.getState().settings.obsidianApiKey + const obsidianValut = store.getState().settings.obsidianValut + const obsidianFolder = store.getState().settings.obsidianFolder - if (!obsidianUrl || !obsidianApiKey) { + if (!obsidianValut || !obsidianFolder) { window.message.error(i18n.t('chat.topics.export.obsidian_not_configured')) return } + let path = '' - // 如果是md文件,直接将内容追加到该文件 - if (isMdFile) { - const response = await fetch(`${obsidianUrl}vault${selectedPath}`, { - method: 'POST', - headers: { - 'Content-Type': 'text/markdown', - Authorization: `Bearer ${obsidianApiKey}` - }, - body: `\n\n${markdown}` // 添加两个换行后追加内容 - }) - - if (!response.ok) { - window.message.error(i18n.t('chat.topics.export.obsidian_export_failed')) - return - } - } else { - // 创建新文件 - const sanitizedFileName = removeSpecialCharactersForFileName(fileName) - const path = selectedPath === '/' ? '' : selectedPath - const fullPath = path.endsWith('/') ? `${path}${sanitizedFileName}.md` : `${path}/${sanitizedFileName}.md` - - const response = await fetch(`${obsidianUrl}vault${fullPath}`, { - method: 'PUT', - headers: { - 'Content-Type': 'text/markdown', - Authorization: `Bearer ${obsidianApiKey}` - }, - body: markdown - }) - - if (!response.ok) { - window.message.error(i18n.t('chat.topics.export.obsidian_export_failed')) - return - } + if (!attributes.title) { + window.message.error(i18n.t('chat.topics.export.obsidian_title_required')) + return } + //构建保存路径添加以 / 结尾 + if (!obsidianFolder.endsWith('/')) { + path = obsidianFolder + '/' + } + //构建文件名 + const fileName = transformObsidianFileName(attributes.title) + + let obsidianUrl = `obsidian://new?file=${encodeURIComponent(path + fileName)}&vault=${encodeURIComponent(obsidianValut)}&clipboard` + + if (attributes.processingMethod === '3') { + obsidianUrl += '&overwrite=true' + } else if (attributes.processingMethod === '2') { + obsidianUrl += '&prepend=true' + } else if (attributes.processingMethod === '1') { + obsidianUrl += '&append=true' + } + window.open(obsidianUrl) window.message.success(i18n.t('chat.topics.export.obsidian_export_success')) } catch (error) { console.error('导出到Obsidian失败:', error) @@ -379,6 +367,51 @@ export const exportMarkdownToObsidian = async ( } } +/** + * 生成Obsidian文件名,源自 Obsidian Web Clipper 官方实现,修改了一些细节 + * @param fileName + * @returns + */ + +function transformObsidianFileName(fileName: string): string { + const platform = window.navigator.userAgent + const isWindows = /win/i.test(platform) + const isMac = /mac/i.test(platform) + + // 删除Obsidian 全平台无效字符 + let sanitized = fileName.replace(/[#|\\^\\[\]]/g, '') + + if (isWindows) { + // Windows 的清理 + sanitized = sanitized + .replace(/[<>:"\\/\\|?*]/g, '') // 移除无效字符 + .replace(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i, '_$1$2') // 避免保留名称 + .replace(/[\s.]+$/, '') // 移除结尾的空格和句点 + } else if (isMac) { + // Mac 的清理 + sanitized = sanitized + .replace(/[/:\u0020-\u007E]/g, '') // 移除无效字符 + .replace(/^\./, '_') // 避免以句点开头 + } else { + // Linux 或其他系统 + sanitized = sanitized + .replace(/[<>:"\\/\\|?*]/g, '') // 移除无效字符 + .replace(/^\./, '_') // 避免以句点开头 + } + + // 所有平台的通用操作 + sanitized = sanitized + .replace(/^\.+/, '') // 移除开头的句点 + .trim() // 移除前后空格 + .slice(0, 245) // 截断为 245 个字符,留出空间以追加 ' 1.md' + + // 确保文件名不为空 + if (sanitized.length === 0) { + sanitized = 'Untitled' + } + + return sanitized +} export const exportMarkdownToJoplin = async (title: string, content: string) => { const { joplinUrl, joplinToken } = store.getState().settings diff --git a/yarn.lock b/yarn.lock index d524b2e34..5fa4c561e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1021,6 +1021,16 @@ __metadata: languageName: node linkType: hard +"@google/genai@npm:^0.4.0": + version: 0.4.0 + resolution: "@google/genai@npm:0.4.0" + dependencies: + google-auth-library: "npm:^9.14.2" + ws: "npm:^8.18.0" + checksum: 10c0/4feb837b373cdbe60a5388b880b2384b116ffa369ae17ec2562c4e9da0f90e315d5e30c413ee3a620b6d147c55e1e9165f0e143aba6d945f1dfbe61fa584fefc + languageName: node + linkType: hard + "@google/generative-ai@npm:^0.21.0": version: 0.21.0 resolution: "@google/generative-ai@npm:0.21.0" @@ -2638,15 +2648,6 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:^0.5.11": - version: 0.5.15 - resolution: "@swc/helpers@npm:0.5.15" - dependencies: - tslib: "npm:^2.8.0" - checksum: 10c0/33002f74f6f885f04c132960835fdfc474186983ea567606db62e86acd0680ca82f34647e8e610f4e1e422d1c16fce729dde22cd3b797ab1fd9061a825dabca4 - languageName: node - linkType: hard - "@szmarczak/http-timer@npm:^4.0.5": version: 4.0.6 resolution: "@szmarczak/http-timer@npm:4.0.6" @@ -2797,20 +2798,6 @@ __metadata: languageName: node linkType: hard -"@types/command-line-args@npm:^5.2.3": - version: 5.2.3 - resolution: "@types/command-line-args@npm:5.2.3" - checksum: 10c0/3a9bc58fd26e546391f6369dd28c03d59349dc4ac39eada1a5c39cc3578e02e4aac222615170e0db79b198ffba2af84fdbdda46e08c6edc4da42bc17ea85200f - languageName: node - linkType: hard - -"@types/command-line-usage@npm:^5.0.4": - version: 5.0.4 - resolution: "@types/command-line-usage@npm:5.0.4" - checksum: 10c0/67840ebf4bcfee200c07d978669ad596fe2adc350fd5c19d44ec2248623575d96ec917f513d1d59453f8f57e879133861a4cc41c20045c07f6c959f1fcaac7ad - languageName: node - linkType: hard - "@types/debug@npm:^4.0.0, @types/debug@npm:^4.1.6": version: 4.1.12 resolution: "@types/debug@npm:4.1.12" @@ -3018,7 +3005,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.13.0, @types/node@npm:^20.9.0": +"@types/node@npm:^20.9.0": version: 20.17.24 resolution: "@types/node@npm:20.17.24" dependencies: @@ -3343,6 +3330,7 @@ __metadata: "@emotion/is-prop-valid": "npm:^1.3.1" "@eslint-react/eslint-plugin": "npm:^1.36.1" "@eslint/js": "npm:^9.22.0" + "@google/genai": "npm:^0.4.0" "@google/generative-ai": "npm:^0.21.0" "@hello-pangea/dnd": "npm:^16.6.0" "@kangfenmao/keyv-storage": "npm:^0.1.0" @@ -3377,7 +3365,6 @@ __metadata: "@vitejs/plugin-react": "npm:^4.2.1" adm-zip: "npm:^0.5.16" antd: "npm:^5.22.5" - apache-arrow: "npm:^18.1.0" applescript: "npm:^1.0.0" axios: "npm:^1.7.3" babel-plugin-styled-components: "npm:^2.1.4" @@ -3732,25 +3719,6 @@ __metadata: languageName: node linkType: hard -"apache-arrow@npm:^18.1.0": - version: 18.1.0 - resolution: "apache-arrow@npm:18.1.0" - dependencies: - "@swc/helpers": "npm:^0.5.11" - "@types/command-line-args": "npm:^5.2.3" - "@types/command-line-usage": "npm:^5.0.4" - "@types/node": "npm:^20.13.0" - command-line-args: "npm:^5.2.1" - command-line-usage: "npm:^7.0.1" - flatbuffers: "npm:^24.3.25" - json-bignum: "npm:^0.0.3" - tslib: "npm:^2.6.2" - bin: - arrow2csv: bin/arrow2csv.js - checksum: 10c0/2bb43c19e8e29b5cba8eb5a3a76f7e4e93ecb25658e49de2c3997be12a461a72e2a4ddd2f90e6806e9725bb28e391ffedc9e6e0ab1f613eb70cfb5438d2c4d21 - languageName: node - linkType: hard - "app-builder-bin@npm:4.0.0": version: 4.0.0 resolution: "app-builder-bin@npm:4.0.0" @@ -3865,20 +3833,6 @@ __metadata: languageName: node linkType: hard -"array-back@npm:^3.0.1, array-back@npm:^3.1.0": - version: 3.1.0 - resolution: "array-back@npm:3.1.0" - checksum: 10c0/bb1fe86aa8b39c21e73c68c7abf8b05ed939b8951a3b17527217f6a2a84e00e4cfa4fdec823081689c5e216709bf1f214a4f5feeee6726eaff83897fa1a7b8ee - languageName: node - linkType: hard - -"array-back@npm:^6.2.2": - version: 6.2.2 - resolution: "array-back@npm:6.2.2" - checksum: 10c0/c98a6e43b669400f58e2fba478336d5d02aac970566ffae3af0cb9b5585ec3811a1e010c76e34fb809a9762e6822a43a9c9a1b99f2a35f43b11a9e198e782818 - languageName: node - linkType: hard - "array-union@npm:^2.1.0": version: 2.1.0 resolution: "array-union@npm:2.1.0" @@ -4021,7 +3975,7 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": +"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf @@ -4044,6 +3998,13 @@ __metadata: languageName: node linkType: hard +"bignumber.js@npm:^9.0.0": + version: 9.1.2 + resolution: "bignumber.js@npm:9.1.2" + checksum: 10c0/e17786545433f3110b868725c449fa9625366a6e675cd70eb39b60938d6adbd0158cb4b3ad4f306ce817165d37e63f4aa3098ba4110db1d9a3b9f66abfbaf10d + languageName: node + linkType: hard + "bindings@npm:^1.5.0": version: 1.5.0 resolution: "bindings@npm:1.5.0" @@ -4210,6 +4171,13 @@ __metadata: languageName: node linkType: hard +"buffer-equal-constant-time@npm:1.0.1": + version: 1.0.1 + resolution: "buffer-equal-constant-time@npm:1.0.1" + checksum: 10c0/fb2294e64d23c573d0dd1f1e7a466c3e978fe94a4e0f8183937912ca374619773bef8e2aceb854129d2efecbbc515bbd0cc78d2734a3e3031edb0888531bbc8e + languageName: node + linkType: hard + "buffer-equal@npm:0.0.1": version: 0.0.1 resolution: "buffer-equal@npm:0.0.1" @@ -4505,15 +4473,6 @@ __metadata: languageName: node linkType: hard -"chalk-template@npm:^0.4.0": - version: 0.4.0 - resolution: "chalk-template@npm:0.4.0" - dependencies: - chalk: "npm:^4.1.2" - checksum: 10c0/6a4cb4252966475f0bd3ee1cd8780146e1ba69f445e59c565cab891ac18708c8143515d23e2b0fb7e192574fb7608d429ea5b28f3b7b9507770ad6fccd3467e3 - languageName: node - linkType: hard - "chalk@npm:2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -4787,30 +4746,6 @@ __metadata: languageName: node linkType: hard -"command-line-args@npm:^5.2.1": - version: 5.2.1 - resolution: "command-line-args@npm:5.2.1" - dependencies: - array-back: "npm:^3.1.0" - find-replace: "npm:^3.0.0" - lodash.camelcase: "npm:^4.3.0" - typical: "npm:^4.0.0" - checksum: 10c0/a4f6a23a1e420441bd1e44dee24efd12d2e49af7efe6e21eb32fca4e843ca3d5501ddebad86a4e9d99aa626dd6dcb64c04a43695388be54e3a803dbc326cc89f - languageName: node - linkType: hard - -"command-line-usage@npm:^7.0.1": - version: 7.0.3 - resolution: "command-line-usage@npm:7.0.3" - dependencies: - array-back: "npm:^6.2.2" - chalk-template: "npm:^0.4.0" - table-layout: "npm:^4.1.0" - typical: "npm:^7.1.1" - checksum: 10c0/444a3e3c6fcbdcb5802de0fd2864ea5aef83eeeb3a825fd24846b996503d4b4140e75aeb2939b3430a06407f3acc02b76b3e08dafb3a3092d22fdcced0ecb0b0 - languageName: node - linkType: hard - "commander@npm:9.2.0": version: 9.2.0 resolution: "commander@npm:9.2.0" @@ -5657,6 +5592,15 @@ __metadata: languageName: node linkType: hard +"ecdsa-sig-formatter@npm:1.0.11, ecdsa-sig-formatter@npm:^1.0.11": + version: 1.0.11 + resolution: "ecdsa-sig-formatter@npm:1.0.11" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: 10c0/ebfbf19d4b8be938f4dd4a83b8788385da353d63307ede301a9252f9f7f88672e76f2191618fd8edfc2f24679236064176fab0b78131b161ee73daa37125408c + languageName: node + linkType: hard + "ee-first@npm:1.1.1": version: 1.1.1 resolution: "ee-first@npm:1.1.1" @@ -6672,7 +6616,7 @@ __metadata: languageName: node linkType: hard -"extend@npm:^3.0.0, extend@npm:~3.0.2": +"extend@npm:^3.0.0, extend@npm:^3.0.2, extend@npm:~3.0.2": version: 3.0.2 resolution: "extend@npm:3.0.2" checksum: 10c0/73bf6e27406e80aa3e85b0d1c4fd987261e628064e170ca781125c0b635a3dabad5e05adbf07595ea0cf1e6c5396cacb214af933da7cbaf24fe75ff14818e8f9 @@ -6937,15 +6881,6 @@ __metadata: languageName: node linkType: hard -"find-replace@npm:^3.0.0": - version: 3.0.0 - resolution: "find-replace@npm:3.0.0" - dependencies: - array-back: "npm:^3.0.1" - checksum: 10c0/fcd1bf7960388c8193c2861bcdc760c18ac14edb4bde062a961915d9a25727b2e8aabf0229e90cc09c753fd557e5a3e5ae61e49cadbe727be89a9e8e49ce7668 - languageName: node - linkType: hard - "find-up@npm:^1.0.0": version: 1.1.2 resolution: "find-up@npm:1.1.2" @@ -6985,13 +6920,6 @@ __metadata: languageName: node linkType: hard -"flatbuffers@npm:^24.3.25": - version: 24.12.23 - resolution: "flatbuffers@npm:24.12.23" - checksum: 10c0/f6c7e4440c724ee337dac54db1d6ae428e84b2bf6618c542d095956e77b521bdd8a0e4d87dc93b15ae6ed4d07a8b269b5c99fd766e5acbe67546ef81034b1e05 - languageName: node - linkType: hard - "flatted@npm:^3.2.9": version: 3.3.3 resolution: "flatted@npm:3.3.3" @@ -7258,6 +7186,30 @@ __metadata: languageName: node linkType: hard +"gaxios@npm:^6.0.0, gaxios@npm:^6.1.1": + version: 6.7.1 + resolution: "gaxios@npm:6.7.1" + dependencies: + extend: "npm:^3.0.2" + https-proxy-agent: "npm:^7.0.1" + is-stream: "npm:^2.0.0" + node-fetch: "npm:^2.6.9" + uuid: "npm:^9.0.1" + checksum: 10c0/53e92088470661c5bc493a1de29d05aff58b1f0009ec5e7903f730f892c3642a93e264e61904383741ccbab1ce6e519f12a985bba91e13527678b32ee6d7d3fd + languageName: node + linkType: hard + +"gcp-metadata@npm:^6.1.0": + version: 6.1.1 + resolution: "gcp-metadata@npm:6.1.1" + dependencies: + gaxios: "npm:^6.1.1" + google-logging-utils: "npm:^0.0.2" + json-bigint: "npm:^1.0.0" + checksum: 10c0/71f6ad4800aa622c246ceec3955014c0c78cdcfe025971f9558b9379f4019f5e65772763428ee8c3244fa81b8631977316eaa71a823493f82e5c44d7259ffac8 + languageName: node + linkType: hard + "gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" @@ -7501,6 +7453,27 @@ __metadata: languageName: node linkType: hard +"google-auth-library@npm:^9.14.2": + version: 9.15.1 + resolution: "google-auth-library@npm:9.15.1" + dependencies: + base64-js: "npm:^1.3.0" + ecdsa-sig-formatter: "npm:^1.0.11" + gaxios: "npm:^6.1.1" + gcp-metadata: "npm:^6.1.0" + gtoken: "npm:^7.0.0" + jws: "npm:^4.0.0" + checksum: 10c0/6eef36d9a9cb7decd11e920ee892579261c6390104b3b24d3e0f3889096673189fe2ed0ee43fd563710e2560de98e63ad5aa4967b91e7f4e69074a422d5f7b65 + languageName: node + linkType: hard + +"google-logging-utils@npm:^0.0.2": + version: 0.0.2 + resolution: "google-logging-utils@npm:0.0.2" + checksum: 10c0/9a4bbd470dd101c77405e450fffca8592d1d7114f245a121288d04a957aca08c9dea2dd1a871effe71e41540d1bb0494731a0b0f6fea4358e77f06645e4268c1 + languageName: node + linkType: hard + "gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" @@ -7560,6 +7533,16 @@ __metadata: languageName: node linkType: hard +"gtoken@npm:^7.0.0": + version: 7.1.0 + resolution: "gtoken@npm:7.1.0" + dependencies: + gaxios: "npm:^6.0.0" + jws: "npm:^4.0.0" + checksum: 10c0/0a3dcacb1a3c4578abe1ee01c7d0bf20bffe8ded3ee73fc58885d53c00f6eb43b4e1372ff179f0da3ed5cfebd5b7c6ab8ae2776f1787e90d943691b4fe57c716 + languageName: node + linkType: hard + "har-schema@npm:^2.0.0": version: 2.0.0 resolution: "har-schema@npm:2.0.0" @@ -8495,6 +8478,13 @@ __metadata: languageName: node linkType: hard +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5 + languageName: node + linkType: hard + "is-stream@npm:^3.0.0": version: 3.0.0 resolution: "is-stream@npm:3.0.0" @@ -8671,10 +8661,12 @@ __metadata: languageName: node linkType: hard -"json-bignum@npm:^0.0.3": - version: 0.0.3 - resolution: "json-bignum@npm:0.0.3" - checksum: 10c0/f9f9312d57a68f72676802fa087da4ed60241d73b6cc0e3fb9f587ca0de7364efb62612a14414ccfbedc0b77ce3c320adca21834a5673c99eb3375aef9f561db +"json-bigint@npm:^1.0.0": + version: 1.0.0 + resolution: "json-bigint@npm:1.0.0" + dependencies: + bignumber.js: "npm:^9.0.0" + checksum: 10c0/e3f34e43be3284b573ea150a3890c92f06d54d8ded72894556357946aeed9877fd795f62f37fe16509af189fd314ab1104d0fd0f163746ad231b9f378f5b33f4 languageName: node linkType: hard @@ -8822,6 +8814,27 @@ __metadata: languageName: node linkType: hard +"jwa@npm:^2.0.0": + version: 2.0.0 + resolution: "jwa@npm:2.0.0" + dependencies: + buffer-equal-constant-time: "npm:1.0.1" + ecdsa-sig-formatter: "npm:1.0.11" + safe-buffer: "npm:^5.0.1" + checksum: 10c0/6baab823b93c038ba1d2a9e531984dcadbc04e9eb98d171f4901b7a40d2be15961a359335de1671d78cb6d987f07cbe5d350d8143255977a889160c4d90fcc3c + languageName: node + linkType: hard + +"jws@npm:^4.0.0": + version: 4.0.0 + resolution: "jws@npm:4.0.0" + dependencies: + jwa: "npm:^2.0.0" + safe-buffer: "npm:^5.0.1" + checksum: 10c0/f1ca77ea5451e8dc5ee219cb7053b8a4f1254a79cb22417a2e1043c1eb8a569ae118c68f24d72a589e8a3dd1824697f47d6bd4fb4bebb93a3bdf53545e721661 + languageName: node + linkType: hard + "katex@npm:^0.12.0": version: 0.12.0 resolution: "katex@npm:0.12.0" @@ -9160,13 +9173,6 @@ __metadata: languageName: node linkType: hard -"lodash.camelcase@npm:^4.3.0": - version: 4.3.0 - resolution: "lodash.camelcase@npm:4.3.0" - checksum: 10c0/fcba15d21a458076dd309fce6b1b4bf611d84a0ec252cb92447c948c533ac250b95d2e00955801ebc367e5af5ed288b996d75d37d2035260a937008e14eaf432 - languageName: node - linkType: hard - "lodash.escaperegexp@npm:^4.1.2": version: 4.1.2 resolution: "lodash.escaperegexp@npm:4.1.2" @@ -10812,7 +10818,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.7": +"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.7, node-fetch@npm:^2.6.9": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -14455,16 +14461,6 @@ __metadata: languageName: node linkType: hard -"table-layout@npm:^4.1.0": - version: 4.1.1 - resolution: "table-layout@npm:4.1.1" - dependencies: - array-back: "npm:^6.2.2" - wordwrapjs: "npm:^5.1.0" - checksum: 10c0/26d8e54a55ddb4de447c8f02a8d7fcbb66a9580375e406a3bc7717ab223a413f6dfbded6710f288b3dfd277991813a0bd5a17419a0dc6db54d9a36d883d868dc - languageName: node - linkType: hard - "tar-fs@npm:^2.0.0": version: 2.1.2 resolution: "tar-fs@npm:2.1.2" @@ -14773,7 +14769,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0": +"tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.6.2": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 @@ -14878,20 +14874,6 @@ __metadata: languageName: node linkType: hard -"typical@npm:^4.0.0": - version: 4.0.0 - resolution: "typical@npm:4.0.0" - checksum: 10c0/f300b198fb9fe743859b75ec761d53c382723dc178bbce4957d9cb754f2878a44ce17dc0b6a5156c52be1065449271f63754ba594dac225b80ce3aa39f9241ed - languageName: node - linkType: hard - -"typical@npm:^7.1.1": - version: 7.3.0 - resolution: "typical@npm:7.3.0" - checksum: 10c0/bee697a88e1dd0447bc1cf7f6e875eaa2b0fb2cccb338b7b261e315f7df84a66402864bfc326d6b3117c50475afd1d49eda03d846a6299ad25f211035bfab3b1 - languageName: node - linkType: hard - "uc.micro@npm:^2.0.0, uc.micro@npm:^2.1.0": version: 2.1.0 resolution: "uc.micro@npm:2.1.0" @@ -15268,6 +15250,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^9.0.1": + version: 9.0.1 + resolution: "uuid@npm:9.0.1" + bin: + uuid: dist/bin/uuid + checksum: 10c0/1607dd32ac7fc22f2d8f77051e6a64845c9bce5cd3dd8aa0070c074ec73e666a1f63c7b4e0f4bf2bc8b9d59dc85a15e17807446d9d2b17c8485fbc2147b27f9b + languageName: node + linkType: hard + "uzip@npm:0.20201231.0": version: 0.20201231.0 resolution: "uzip@npm:0.20201231.0" @@ -15539,13 +15530,6 @@ __metadata: languageName: node linkType: hard -"wordwrapjs@npm:^5.1.0": - version: 5.1.0 - resolution: "wordwrapjs@npm:5.1.0" - checksum: 10c0/e147162f139eb8c05257729fde586f5422a2d242aa8f027b5fa5adead1b571b455d0690a15c73aeaa31c93ba96864caa06d84ebdb2c32a0890602ab86a7568d1 - languageName: node - linkType: hard - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" @@ -15596,7 +15580,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.13.0": +"ws@npm:^8.13.0, ws@npm:^8.18.0": version: 8.18.1 resolution: "ws@npm:8.18.1" peerDependencies: