diff --git a/.env.example b/.env.example index 13e9d634fe8..cf4a658e40b 100644 --- a/.env.example +++ b/.env.example @@ -64,7 +64,7 @@ TZ=Asia/Shanghai # 系统默认语言(BCP-47),用于 Prompt 中 {{language}} 占位符回退。 # 优先级:Accept-Language 请求头 > 此变量 > 内置默认值 (en-US)。 # WEKNORA_LANGUAGE=zh-CN -# 前端界面默认语言(BCP-47)。可选:zh-CN | en-US | ru-RU | ko-KR | ja-JP。 +# 前端界面默认语言(BCP-47)。可选:zh-CN | zh-TW | en-US | ru-RU | ko-KR | ja-JP。 # 优先级:用户已选语言(localStorage) > 此变量 > 内置默认 zh-CN。 # 仅影响首次访问/未手动切换语言的用户;改完重启 frontend 容器即生效,无需重建镜像。 # DEFAULT_LOCALE=en-US diff --git a/frontend/docker-entrypoint.sh b/frontend/docker-entrypoint.sh index 8847445e71b..f5ed751ee3a 100644 --- a/frontend/docker-entrypoint.sh +++ b/frontend/docker-entrypoint.sh @@ -3,7 +3,7 @@ # Only emit whitelisted locale tags to avoid config.js injection from env values. RUNTIME_DEFAULT_LOCALE="" case "${DEFAULT_LOCALE:-}" in - zh-CN|en-US|ru-RU|ko-KR|ja-JP) RUNTIME_DEFAULT_LOCALE="${DEFAULT_LOCALE}" ;; + zh-CN|zh-TW|en-US|ru-RU|ko-KR|ja-JP) RUNTIME_DEFAULT_LOCALE="${DEFAULT_LOCALE}" ;; esac # 生成运行时配置文件,注入环境变量到前端 diff --git a/frontend/public/config.js b/frontend/public/config.js index 3d57aa89084..0ea0850b83b 100644 --- a/frontend/public/config.js +++ b/frontend/public/config.js @@ -4,6 +4,6 @@ window.__RUNTIME_CONFIG__ = { MAX_SKILL_BUNDLE_SIZE_MB: 256, // Optional: serve embed on a dedicated origin, e.g. 'https://embed.example.com' EMBED_BASE_URL: '', - // Optional: default UI locale for first-time visitors (zh-CN | en-US | ru-RU | ko-KR | ja-JP) + // Optional: default UI locale for first-time visitors (zh-CN | zh-TW | en-US | ru-RU | ko-KR | ja-JP) DEFAULT_LOCALE: '', }; diff --git a/frontend/public/weknora-widget.js b/frontend/public/weknora-widget.js index d90b572ff42..07dfd603de6 100644 --- a/frontend/public/weknora-widget.js +++ b/frontend/public/weknora-widget.js @@ -12,7 +12,7 @@ * WeKnora.openWithQuery('How do I reset my password?') * Opens the panel (if closed) and sends the query when the iframe is ready. * WeKnora.setLocale('en-US') - * Switch embed UI language (zh-CN | en-US | ko-KR | ja-JP | ru-RU). + * Switch embed UI language (zh-CN | zh-TW | en-US | ko-KR | ja-JP | ru-RU). * * Secure mode (recommended): instead of `token`, pass `tokenEndpoint` — a URL on * your own backend that returns { token: "ems_...", expiresIn: 1800 }. Your diff --git a/frontend/src/App.vue b/frontend/src/App.vue index a1e59e678e1..8fba5a84c4c 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -20,6 +20,7 @@ import zhCNConfig from 'tdesign-vue-next/esm/locale/zh_CN' import koKRConfig from 'tdesign-vue-next/esm/locale/ko_KR' import jaJPConfig from 'tdesign-vue-next/esm/locale/ja_JP' import ruRUConfig from 'tdesign-vue-next/esm/locale/ru_RU' +import zhTWConfig from 'tdesign-vue-next/esm/locale/zh_TW' const { locale, t, tm } = useI18n() const { formatRole, roleIcon } = useRoleLabel() @@ -30,6 +31,7 @@ const settingsStore = useSettingsStore() const tdLocaleMap: Record = { 'en-US': enUSConfig, 'zh-CN': zhCNConfig, + 'zh-TW': zhTWConfig, 'ko-KR': koKRConfig, 'ja-JP': jaJPConfig, 'ru-RU': ruRUConfig, diff --git a/frontend/src/api/agent/index.ts b/frontend/src/api/agent/index.ts index 457e1316fb9..59c789f762e 100644 --- a/frontend/src/api/agent/index.ts +++ b/frontend/src/api/agent/index.ts @@ -316,7 +316,7 @@ export interface IMChannel { enabled: boolean; mode: 'webhook' | 'websocket' | 'longpoll'; output_mode: 'stream' | 'full'; - locale?: '' | 'zh-CN' | 'en-US' | 'ko-KR' | 'ja-JP' | 'ru-RU'; + locale?: '' | 'zh-CN' | 'zh-TW' | 'en-US' | 'ko-KR' | 'ja-JP' | 'ru-RU'; session_mode?: 'user' | 'thread'; knowledge_base_id?: string; credentials: Record; diff --git a/frontend/src/api/embed/index.ts b/frontend/src/api/embed/index.ts index c579e2489e6..d0f9c038e54 100644 --- a/frontend/src/api/embed/index.ts +++ b/frontend/src/api/embed/index.ts @@ -47,7 +47,7 @@ export interface EmbedChannelPublicConfig { default_locale?: string } -export type EmbedLocaleTag = 'zh-CN' | 'en-US' | 'ko-KR' | 'ja-JP' | 'ru-RU' | '' +export type EmbedLocaleTag = 'zh-CN' | 'zh-TW' | 'en-US' | 'ko-KR' | 'ja-JP' | 'ru-RU' | '' export interface EmbedChannelStats { session_count: number diff --git a/frontend/src/components/AgentEmbedChannelPanel.vue b/frontend/src/components/AgentEmbedChannelPanel.vue index 041199aff0f..9c252b0d128 100644 --- a/frontend/src/components/AgentEmbedChannelPanel.vue +++ b/frontend/src/components/AgentEmbedChannelPanel.vue @@ -538,6 +538,7 @@ const headerTitleModeOptions = computed(() => ([ const defaultLocaleOptions = computed(() => ([ { label: t('embedPublish.defaultLocaleBrowser'), value: '' }, { label: '简体中文', value: 'zh-CN' }, + { label: '繁體中文', value: 'zh-TW' }, { label: 'English', value: 'en-US' }, { label: '한국어', value: 'ko-KR' }, { label: '日本語', value: 'ja-JP' }, diff --git a/frontend/src/components/IMChannelPanel.vue b/frontend/src/components/IMChannelPanel.vue index 77e956f8fe0..1d0aa2368d4 100644 --- a/frontend/src/components/IMChannelPanel.vue +++ b/frontend/src/components/IMChannelPanel.vue @@ -684,6 +684,7 @@ const platformOptions = computed(() => ([ const localeOptions = computed(() => ([ { value: '' as IMLocale, label: t('agentEditor.im.replyLanguageDefault') }, { value: 'zh-CN' as IMLocale, label: '简体中文' }, + { value: 'zh-TW' as IMLocale, label: '繁體中文' }, { value: 'en-US' as IMLocale, label: 'English' }, { value: 'ja-JP' as IMLocale, label: '日本語' }, { value: 'ko-KR' as IMLocale, label: '한국어' }, diff --git a/frontend/src/i18n/embed.ts b/frontend/src/i18n/embed.ts index 276e4222c2c..eb18a40766e 100644 --- a/frontend/src/i18n/embed.ts +++ b/frontend/src/i18n/embed.ts @@ -587,6 +587,592 @@ const messages = { } } }, + "zh-TW": { + "embedPublish": { + "title": "網頁內嵌", + "description": "將智慧代理內嵌到您的網頁,訪客可透過頁面內聊天視窗或右下角浮窗發起對話。", + "create": "新建內嵌通路", + "empty": "暫無內嵌通路", + "unnamed": "未命名通路", + "agent": "智慧代理", + "rateLimit": "限流", + "rateLimitUnit": "次/分鐘", + "allowedOrigins": "域名白名單", + "embedCode": "內嵌程式碼", + "widgetCode": "浮窗指令碼", + "copyCode": "複製程式碼", + "rotateToken": "輪換 Token", + "delete": "刪除", + "edit": "編輯", + "createTitle": "新建內嵌通路", + "editTitle": "編輯內嵌通路", + "name": "名稱", + "namePlaceholder": "例如:官網客服", + "welcomeMessage": "歡迎語", + "welcomePlaceholder": "你好,有什麼可以幫您?", + "originsLabel": "域名白名單(每行一個,留空表示不限制)", + "originsPlaceholder": "https://shop.example.com", + "rateLimitLabel": "每分鐘請求上限", + "debug": "偵錯預覽", + "createdDebugHint": "內嵌通路已建立,可點擊「偵錯預覽」在新分頁體驗", + "primaryColor": "主題色", + "pageTitle": "頁面標題", + "pageTitlePlaceholder": "AI 客服", + "tokenHint": "載入通路金鑰失敗,請關閉後重新打開該通路。", + "created": "內嵌通路已建立", + "updated": "內嵌通路已更新", + "deleted": "已刪除", + "tokenRotated": "Token 已輪換", + "copied": "已複製內嵌程式碼", + "loadError": "載入失敗", + "missingChannel": "缺少內嵌通路或 Token", + "invalidChannel": "無效的內嵌通路", + "sessionFailed": "無法建立對話會話,請稍後重試", + "channelDisabled": "內嵌通路已停用,請在 Agent 編輯器的「網頁內嵌」中重新啟用", + "loading": "載入中...", + "tabIframe": "iframe", + "tabWidget": "浮窗", + "widgetPosition": "浮窗位置", + "widgetPreview": "浮窗預覽", + "positionBottomRight": "右下角", + "positionBottomLeft": "左下角", + "positionTopRight": "右上角", + "positionTopLeft": "左上角", + "publishToken": "發布 Token", + "publishTokenHelp": "發布 Token(em_…)是內嵌通路的長期金鑰,相當於 API Key。打開通路詳情即可查看並複製;輪換後舊 Token 立即失效。", + "sessionTokenHelp": "訪客打開聊天後,iframe 會用發布 Token 換取短期會話 Token(ems_…,約 30 分鐘),後續請求使用會話 Token,避免在 URL 中長期暴露發布 Token。", + "rotateTokenHelp": "輪換會作廢舊發布 Token,所有已部署的內嵌程式碼需同步更新,否則第三方站點將無法存取。", + "revealToken": "顯示", + "hideToken": "隱藏", + "copyToken": "複製 Token", + "tokenCopied": "Token 已複製", + "awaitingToken": "等待宿主頁面提供 Token…", + "preview": "預覽", + "previewLoading": "載入預覽中…", + "previewIframeHint": "模擬第三方網站用 iframe 內嵌的效果(與複製程式碼一致)。", + "previewWidgetHint": "模擬第三方網站載入浮窗指令碼後的效果;真實站點由宿主頁面透過 postMessage 傳遞 Token。", + "previewMockPage": "模擬宿主頁面", + "defaultChatTitle": "AI 助手", + "newChat": "新建對話", + "rotateConfirmTitle": "確認輪換 Token?", + "rotateConfirmBody": "輪換後舊 Token 立即失效,已發布的內嵌程式碼需全部更新。", + "tokenRequiredForPreview": "需要發布 Token 才能預覽。請先建立通路,或點擊「輪換 Token」獲取新 Token。" + }, + "chat": { + "title": "對話", + "newChat": "新對話", + "suggestedQuestions": "你可以這樣問我", + "suggestedQuestionsLoading": "載入中...", + "followUpQuestions": "繼續問", + "followUpQuestionsLoading": "載入推薦問題", + "refreshSuggestedQuestions": "換一批", + "inputPlaceholder": "請輸入您的訊息...", + "send": "傳送", + "thinking": "思考中...", + "regenerate": "重新生成", + "copy": "複製", + "delete": "刪除", + "reference": "引用", + "noMessages": "暫無訊息", + "waitingForAnswer": "等待回答...", + "cannotAnswer": "抱歉,我無法回答這個問題。", + "summarizingAnswer": "總結答案中...", + "loading": "載入中...", + "enterDescription": "輸入描述", + "referencedContent": "引用了 {count} 個相關資料", + "deepThinking": "深度思考完成", + "knowledgeBaseQandA": "知識庫問答", + "askKnowledgeBase": "向知識庫提問", + "sourcesCount": "{count} 個來源", + "pleaseEnterContent": "請輸入內容!", + "pleaseUploadKnowledgeBase": "請先上傳知識庫!", + "replyingPleaseWait": "正在回覆,請稍後再試!", + "createSessionFailed": "建立會話失敗", + "createSessionError": "建立會話出錯", + "unableToGetKnowledgeBaseId": "無法獲取知識庫ID", + "summaryInProgress": "正在總結答案……", + "thinkingAlt": "正在思考", + "conversationTime": { + "today": "今天 {time}", + "yesterday": "昨天 {time}", + "thisYear": "{month}月{day}日 {time}", + "otherYear": "{year}年{month}月{day}日 {time}" + }, + "preparingAnswer": "正在準備回答…", + "connectingModelAndGeneratingAnswer": "正在連結模型並生成回答…", + "modelStillResponding": "模型回應較慢,仍在等待…", + "deepThoughtCompleted": "已深度思考", + "deepThoughtAlt": "深度思考完成", + "referencesTitle": "參考了{count}個相關內容", + "referencesDocCount": "引用了{count}篇文件", + "referencesWebCount": "參考了{count}條網頁", + "referencesDocAndWebCount": "引用了{docCount}篇文件和{webCount}條網頁", + "referencesDrawerTitle": "參考來源", + "referencesDrawerTitleWeb": "網頁來源", + "referencesDrawerTitleDocs": "文件來源", + "referencesDrawerTitleTools": "工具結果", + "referencesDrawerTitleMixed": "參考來源", + "referencesDrawerWebSection": "網頁", + "referencesDrawerDocsSection": "知識庫文件", + "referencesDrawerToolsSection": "工具", + "referencesDrawerEmpty": "暫無參考來源", + "referenceChunkCount": "{count}個片段", + "fallbackHint": "未從知識庫中檢索到相關內容,以上為模型直接回答", + "requestInfoTitle": "請求資訊", + "requestInfoRequestId": "Request ID", + "requestInfoMessageId": "訊息 ID", + "requestInfoSessionId": "會話 ID", + "requestInfoUrl": "請求", + "requestInfoSentAt": "發起時間", + "requestInfoEmpty": "暫無請求資訊", + "channelWeb": "網頁", + "channelApi": "API", + "channelIm": "IM", + "chunkLabel": "片段{index}:", + "navigateToDocument": "查看文件詳情", + "referenceIconAlt": "參考內容圖示", + "chunkIdLabel": "片段ID:", + "documentIdLabel": "文件ID:", + "faqIdLabel": "FAQ ID:", + "faqContainerIdLabel": "所屬文件ID:", + "faqAnswersLabel": "答案:", + "chunkOrdinal": "片段 {index}", + "previewContent": "預覽內容", + "noPlanSteps": "未提供具體步驟", + "chunkIndexLabel": "片段 #{index}", + "chunkPositionLabel": "(位置: {position})", + "noRelatedChunks": "沒有找到相關片段", + "noSearchResults": "沒有找到搜尋結果", + "relevanceHigh": "高相關", + "relevanceMedium": "中相關", + "relevanceLow": "低相關", + "relevanceWeak": "弱相關", + "webSearchNoResults": "未找到搜尋結果", + "otherSource": "其他來源", + "webGroupIntro": "以下 {count} 條內容來自", + "graphConfigTitle": "圖譜設定", + "entityTypesLabel": "實體類型:", + "relationTypesLabel": "關係類型:", + "graphResultsHeader": "找到 {count} 條相關結果", + "graphNoResults": "未找到相關的圖譜資訊", + "unknownLink": "未知連結", + "contentLengthLabel": "長度 {value}", + "notProvided": "未提供", + "promptLabel": "提示語", + "errorMessageLabel": "錯誤資訊", + "summaryLabel": "總結", + "rawTextLabel": "原始文字", + "collapseRaw": "收起原文", + "expandRaw": "展開原文", + "noWebContent": "未獲取到網頁內容", + "lengthChars": "{value} 字", + "lengthThousands": "{value} 千字", + "lengthTenThousands": "{value} 萬字", + "sqlQueryExecuted": "執行的 SQL 查詢:", + "sqlResultsLabel": "返回結果:", + "rowsLabel": "行", + "columnsLabel": "列", + "noDatabaseRecords": "未找到比對的記錄", + "nullValuePlaceholder": "", + "documentTitleLabel": "文件標題:", + "chunkCountLabel": "片段數量:", + "chunkCountValue": "{count} 個片段", + "documentDescriptionLabel": "文件描述:", + "documentStatusLabel": "處理狀態:", + "documentSourceLabel": "來源:", + "documentFileLabel": "檔案資訊:", + "documentMetadataLabel": "元資料", + "documentInfoSummaryLabel": "文件資訊", + "documentInfoCount": "成功 {count} / 請求 {requested}", + "documentInfoErrors": "錯誤詳情", + "documentInfoEmpty": "暫無文件資訊", + "statusDescription": "狀態說明", + "statusIndexed": "文件已索引並可搜尋", + "statusSearchable": "可使用搜尋工具尋找文件內容", + "statusChunkDetailAvailable": "可使用 get_chunk_detail 查看片段詳情", + "positionLabel": "位置:", + "chunkPositionValue": "第 {index} 個片段", + "contentLengthLabelSimple": "內容長度:", + "fullContentLabel": "完整內容", + "copyContent": "複製內容", + "knowledgeBaseCount": "共 {count} 個知識庫", + "noKnowledgeBases": "沒有可用的知識庫", + "rawOutputLabel": "原始輸出", + "wikiWritePageTitle": "Wiki 頁面寫入", + "wikiReplaceTextTitle": "Wiki 文字取代", + "wikiRenamePageTitle": "Wiki 頁面重新命名", + "wikiDeletePageTitle": "Wiki 頁面刪除", + "wikiActionCreated": "已建立", + "wikiActionUpdated": "已更新", + "wikiActionRenamed": "已重新命名", + "wikiActionDeleted": "已刪除", + "wikiFieldSlug": "頁面路徑", + "wikiFieldTitle": "標題", + "wikiFieldPageType": "類型", + "wikiFieldSummary": "摘要", + "wikiFieldOldText": "原文字", + "wikiFieldNewText": "新文字", + "wikiFieldOldSlug": "原路徑", + "wikiFieldNewSlug": "新路徑", + "wikiFieldAffectedPages": "受影響頁面", + "wikiAffectedCount": "{count} 個頁面的連結已更新", + "selectKnowledgeBaseWarning": "請至少選擇一個知識庫", + "processError": "處理出錯", + "sessionExcerpt": "會話摘錄", + "noAnswerContent": "(無回答內容)", + "noMatchFound": "未找到比對的內容", + "deleteSessionFailed": "刪除失敗,請稍後再試!", + "imageTooMany": "最多上傳5張圖片", + "imageTypeSizeError": "僅支持 JPG/PNG/GIF/WEBP 格式,單張不超過 10MB", + "imageReadFailed": "讀取圖片失敗", + "imageUploadTooltip": "上傳圖片(支持貼上/拖曳)", + "attachmentUploadTooltip": "上傳附件(文件、音訊等)", + "attachmentWithCount": "已上傳 {count} 個附件", + "attachmentTooMany": "最多上傳 {max} 個附件", + "attachmentTooLarge": "檔案 {name} 超過 {max}MB 限制", + "attachmentTypeNotSupported": "不支持的檔案類型:{name}", + "attachmentUploading": "上傳中 {progress}%", + "attachmentParsing": "正在解析", + "attachmentReady": "解析完成", + "attachmentUploadFailed": "附件上傳失敗", + "attachmentParseFailed": "附件解析失敗", + "attachmentStillProcessing": "附件 {name} 仍在解析,請稍候", + "attachmentParseTimeout": "附件解析時間過長,請稍後重試", + "copySuccess": "已複製到剪貼簿", + "copyFailed": "複製失敗", + "emptyContentWarning": "當前回答為空", + "editorOpened": "已打開編輯器,請選擇知識庫後儲存" + }, + "common": { + "loading": "載入中...", + "confirm": "確認", + "cancel": "取消", + "close": "關閉", + "copy": "複製", + "copied": "已複製", + "finish": "完成" + }, + "error": { + "tokenNotFound": "未找到登入權杖,請重新登入", + "invalidImageLink": "無效的圖片連結", + "streamFailed": "流式連結失敗" + }, + "agent": { + "taskLabel": "任務:", + "think": "思考", + "copy": "複製", + "addToKnowledgeBase": "新增到知識庫", + "artifactDrawer": { + "buttonTitle": "查看本次生成的檔案", + "title": "生成的檔案", + "empty": "本次未生成可下載的檔案", + "preview": "預覽", + "previewBack": "返回清單", + "collecting": "正在儲存生成的檔案…", + "download": "下載", + "downloadFailed": "下載失敗,請稍後重試", + "inlinePreviewHint": "點擊預覽", + "inlineMissing": "檔案不可用", + "inlineDeleted": "檔案已刪除" + }, + "updatePlan": "更新計劃", + "webSearchFound": "找到 {count} 個網路搜尋結果", + "argumentsLabel": "參數", + "toolFallback": "工具", + "stepsCompleted": "已完成 {steps} 個步驟", + "stepsCompletedWithDuration": "已完成 {steps} 個步驟,耗時 {duration}", + "reasoningRounds": "思考 {rounds} 輪", + "toolCalls": "呼叫 {tools} 次工具", + "durationSuffix": "耗時 {duration}", + "stepSummarySeparator": " · " + }, + "agentStream": { + "toolApproval": { + "banner": "該 MCP 工具已標記為「需人工審核」,確認參數後再執行", + "waiting": "等待審核 · {target}", + "waitingStatus": "等待審核", + "targetWithTool": "{service} › {tool}", + "titleWithTarget": "人工審核 · {service} › {tool}", + "resolvedApproved": "已透過 · {target}", + "resolvedRejected": "已拒絕 · {target}", + "service": "服務", + "tool": "工具", + "argsLabel": "呼叫參數", + "argsModified": "已修改", + "countdown": "剩餘約 {seconds} 秒", + "countdownShort": "{seconds}s", + "approve": "透過並執行", + "reject": "拒絕", + "approvedTag": "已透過", + "rejectedTag": "已拒絕", + "invalidJson": "參數不是合法 JSON", + "submitted": "已提交", + "submitFailed": "提交失敗", + "userRejected": "使用者拒絕" + }, + "mcpOAuth": { + "banner": "該 MCP 服務需要 OAuth 授權後才能呼叫", + "waiting": "等待授權 · {target}", + "waitingStatus": "等待授權", + "targetWithTool": "{service} › {tool}", + "titleWithService": "OAuth 授權 · {service}", + "titleWithTool": "OAuth 授權 · {service} › {tool}", + "resolvedAuthorized": "已授權 · {target}", + "resolvedTimedOut": "授權超時 · {target}", + "resolvedCanceled": "已跳過 · {target}", + "desc": "點擊授權將打開新視窗完成登入,授權成功後會自動繼續本次工具呼叫。", + "authorize": "去授權", + "skip": "跳過", + "countdown": "剩餘約 {seconds} 秒", + "countdownShort": "{seconds}s", + "authorizedTag": "已授權", + "timedOutTag": "授權超時", + "canceledTag": "已取消", + "authorizedToast": "授權成功,正在繼續", + "startFailed": "發起授權失敗", + "resumeFailed": "復原執行失敗,請重試", + "skipFailed": "跳過失敗,請重試" + }, + "mcp": { + "discoverTools": "發現 MCP 工具", + "listServers": "查看 MCP 服務", + "listTools": "查看 MCP 工具", + "searchTools": "搜尋 MCP 工具", + "describeTool": "讀取工具定義", + "callTool": "呼叫 MCP 工具", + "showing": "已顯示 {count} / {total} 項", + "moreAvailable": "還有更多結果", + "empty": "沒有可顯示的項", + "parameters": "參數", + "expand": "展開說明", + "collapse": "收起", + "required": "必填", + "fullSchema": "完整參數定義", + "failed": "MCP 操作失敗", + "result": "執行結果", + "status": { + "not_loaded": "未載入", + "loading": "載入中", + "ready": "可用", + "needs_auth": "需要授權", + "error": "連結失敗", + "disabled": "已停用", + "unavailable": "不可用" + } + }, + "tools": { + "searchKnowledge": "知識庫檢索", + "grepChunks": "搜尋關鍵字", + "webSearch": "網路搜尋", + "webFetch": "網頁抓取", + "getDocumentInfo": "獲取文件資訊", + "listKnowledgeChunks": "查看知識切塊", + "getRelatedDocuments": "尋找相關文件", + "getDocumentContent": "獲取文件內容", + "todoWrite": "計劃管理", + "knowledgeGraphExtract": "知識圖譜抽取", + "thinking": "思考", + "imageAnalysis": "查看圖片內容", + "queryUnderstand": "理解問題", + "queryKnowledgeGraph": "知識圖譜查詢", + "readSkill": "讀取技能", + "executeSkillScript": "執行技能指令碼", + "listSandboxFiles": "列出沙箱檔案", + "readSandboxFile": "讀取沙箱檔案", + "writeSandboxFile": "寫入沙箱檔案", + "editSandboxFile": "編輯沙箱檔案", + "shellExec": "執行沙箱命令", + "dataAnalysis": "資料分析", + "dataSchema": "資料結構", + "databaseQuery": "資料庫查詢" + }, + "skillFiles": { + "heading": "技能檔案", + "script": "指令碼", + "instructions": "技能說明" + }, + "sandboxFiles": { + "found": "找到 {count} 個檔案", + "empty": "暫無檔案", + "truncated": "清單已截斷", + "wrote": "已寫入", + "edited": "已編輯", + "replacements": "取代 {count} 處", + "moreLines": "另有 {count} 行" + }, + "shellExec": { + "workDir": "目錄", + "exitCode": "退出碼", + "stdout": "標準輸出", + "stderr": "標準錯誤", + "emptyOutput": "無輸出", + "truncated": "輸出已截斷", + "killed": "已超時終止", + "binarySuppressed": "二進位輸出已省略,請將檔案寫入產物目錄後下載" + }, + "summary": { + "searchKb": "檢索知識庫 {count} 次", + "thinking": "思考 {count} 次", + "callTool": "呼叫 {name}", + "callTools": "呼叫工具 {names}", + "intermediateSteps": "{count} 個中間步驟", + "separator": "、", + "comma": "," + }, + "citation": { + "loading": "載入中...", + "notFound": "未找到內容", + "loadFailed": "載入失敗", + "chunkId": "片段ID", + "noKbForWiki": "無法識別關聯的知識庫,無法打開 Wiki" + }, + "toolSummary": { + "getDocument": "獲取文件:{title}", + "document": "文件", + "listChunks": "查看 {title}", + "listFaqEntry": "查看 FAQ:{question}", + "deepThinking": "深度思考" + }, + "plan": { + "inProgress": "進行中", + "pending": "待處理", + "completed": "已完成" + }, + "search": { + "noResults": "未找到比對的內容", + "candidatesBelowThreshold": "命中 {count} 條候選,相關性不足,未用於回答", + "foundResultsFromFiles": "找到 {count} 個結果,來自 {files} 個檔案", + "foundResults": "找到 {count} 個結果", + "foundMixedResults": "找到 {count} 個結果({docCount} 篇文件,{webCount} 條網頁)", + "webResults": "找到 {count} 條網頁", + "grepSummary": "找到 {chunks} 個比對片段,來自 {docs} 個文件" + }, + "grepResults": { + "chunkHits": "{count} 片段", + "keywordHits": "{count} 次", + "titleMatch": "標題比對", + "faqEntry": "FAQ 條目" + }, + "knowledgeChunksList": { + "chunkRange": "已載入 {fetched} / {total} 個切塊", + "page": "第 {page} 頁,每頁 {pageSize} 個", + "offsetRange": "第 {from}–{to} 塊", + "queryMatches": "文件內搜尋「{query}」命中 {count} 處", + "queryNoMatch": "文件內搜尋「{query}」無比對" + }, + "attachmentParsing": { + "parsedSummary": "已解析 {count} 個附件", + "parsedWithSkipped": "已解析 {parsed} 個附件,{skipped} 個未完成已跳過", + "noneReady": "沒有可用的已解析附件" + }, + "ragPipeline": { + "understanding": "正在理解問題...", + "understandDone": "已完成問題理解", + "searching": "正在檢索知識庫...", + "searchingWithQuery": "正在檢索知識庫:「{query}」", + "searchingWeb": "正在檢索網路...", + "searchingWebWithQuery": "正在檢索網路:「{query}」", + "searchingMixed": "正在檢索知識庫和網路...", + "searchingMixedWithQuery": "正在檢索知識庫和網路:「{query}」", + "searchDone": "檢索完成", + "searchDoneWithQuery": "檢索知識庫:「{query}」", + "referencedDocs": "引用 {count} 篇文件", + "referencedWebs": "引用 {count} 條網頁", + "referencedDocAndWeb": "引用 {docCount} 篇文件和 {webCount} 條網頁" + }, + "toolStatus": { + "calling": "正在呼叫 {name}...", + "searchKb": "檢索知識庫", + "searchKbFailed": "檢索知識庫失敗", + "searchMixed": "檢索知識庫和網路", + "searchMixedFailed": "檢索失敗", + "webSearch": "網路搜尋", + "webSearchFailed": "網路搜尋失敗", + "grepSearch": "搜尋關鍵字", + "grepSearchFailed": "搜尋關鍵字失敗", + "getDocInfo": "獲取文件資訊", + "getDocInfoFailed": "獲取文件資訊失敗", + "viewDocument": "查看文件", + "thinkingDone": "完成思考", + "thinkingFailed": "思考失敗", + "updateTodos": "更新任務清單", + "updateTodosFailed": "更新任務清單失敗", + "imageAnalyzing": "正在查看圖片內容...", + "imageAnalysisDone": "已查看圖片內容", + "imageAnalysisFailed": "圖片內容查看失敗", + "attachmentParsing": "正在解析附件...", + "attachmentParsingDone": "已解析附件", + "attachmentParsingFailed": "附件解析失敗", + "queryUnderstanding": "正在理解問題...", + "queryUnderstandDone": "已完成問題理解", + "called": "呼叫 {name}", + "calledFailed": "呼叫 {name} 失敗", + "shellExecRunning": "正在執行沙箱命令..." + }, + "copy": { + "emptyContent": "當前回答為空,無法複製", + "success": "已複製到剪貼簿", + "failed": "複製失敗,請手動複製" + }, + "saveToKb": { + "emptyContent": "當前回答為空,無法儲存到知識庫", + "editorOpened": "已打開編輯器,請選擇知識庫後儲存" + } + }, + "input": { + "placeholder": "直接向模型提問", + "stopGeneration": "停止生成", + "send": "傳送", + "webSearch": { + "label": "網路搜尋", + "toggleOn": "開啟網路搜尋", + "toggleOff": "關閉網路搜尋", + "agentDisabled": "當前智慧代理未啟用聯網搜尋" + }, + "imageUpload": { + "label": "上傳圖片", + "tooltip": "上傳圖片", + "agentDisabled": "當前智慧代理未啟用圖片上傳" + }, + "fileUpload": { + "label": "上傳附件", + "tooltip": "上傳文件等附件", + "tooMany": "最多上傳 5 個附件", + "tooLarge": "附件超過 20MB 限制" + }, + "messages": { + "enterContent": "請先輸入內容!", + "selectKnowledge": "請先選擇知識庫!", + "replying": "正在回覆中,請稍後再試!", + "agentSwitchedOn": "已切換到智慧推論", + "agentSwitchedOff": "已切換到快速問答", + "agentSelected": "已選擇智慧代理「{name}」", + "agentEnabled": "Agent 模式已啟用", + "agentDisabled": "Agent 模式已停用", + "agentNotReadyDetail": "Agent 未就緒,需要設定以下內容:{reasons}", + "webSearchNotConfigured": "未設定網路搜尋引擎,請先在設定中完成搜尋引擎選擇與介面設定。", + "webSearchEnabled": "網路搜尋已開啟", + "webSearchDisabled": "網路搜尋已關閉", + "sessionMissing": "會話 ID 不存在", + "messageMissing": "無法獲取訊息 ID,請重新整理頁面後重試", + "stopSuccess": "已停止生成", + "stopFailed": "停止失敗,請重試" + } + }, + "knowledgeEditor": { + "wikiBrowser": { + "viewInGraph": "在圖譜中查看", + "editingBadge": "編輯中", + "pageActions": "頁面操作", + "version": "v{ver}", + "filterSummary": "摘要", + "filterEntity": "實體", + "filterConcept": "概念", + "filterSynthesis": "綜合", + "filterComparison": "對比" + } + } + }, "ja-JP": { "embedPublish": { "title": "Webページ埋め込み", @@ -2062,7 +2648,7 @@ const ruEmbedPublish = { }, } as const -export const SUPPORTED_LOCALES = ['zh-CN', 'en-US', 'ko-KR', 'ja-JP', 'ru-RU'] as const +export const SUPPORTED_LOCALES = ['zh-CN', 'zh-TW', 'en-US', 'ko-KR', 'ja-JP', 'ru-RU'] as const export type EmbedLocale = (typeof SUPPORTED_LOCALES)[number] /** Isolated from the main app `locale` key so embed preview never hijacks admin UI language. */ @@ -2075,6 +2661,16 @@ export function normalizeEmbedLocale(raw: string): EmbedLocale { if (s.startsWith('ko')) return 'ko-KR' if (s.startsWith('ja')) return 'ja-JP' if (s.startsWith('ru')) return 'ru-RU' + // 繁中變體必須排在通用 'zh' 規則之前,否則 zh-TW / zh-HK / zh-Hant + // 會全部被 'zh' 規則吞掉、塌陷成 zh-CN。 + if ( + s.startsWith('zh-tw') || + s.startsWith('zh-hk') || + s.startsWith('zh-mo') || + s.startsWith('zh-hant') + ) { + return 'zh-TW' + } if (s.startsWith('zh')) return 'zh-CN' const exact = SUPPORTED_LOCALES.find((l) => l.toLowerCase() === s) return exact || 'zh-CN' @@ -2110,6 +2706,7 @@ const locale = resolveInitialEmbedLocale() export const EMBED_MESSAGES = { 'zh-CN': messages['zh-CN'], + 'zh-TW': messages['zh-TW'], 'en-US': messages['en-US'], 'ko-KR': deepMerge(messages['en-US'], koEmbedPublish), 'ja-JP': messages['ja-JP'], diff --git a/frontend/src/i18n/embedLocale.test.ts b/frontend/src/i18n/embedLocale.test.ts index a0a3170bd2c..cc7358b40f2 100644 --- a/frontend/src/i18n/embedLocale.test.ts +++ b/frontend/src/i18n/embedLocale.test.ts @@ -26,8 +26,8 @@ const EXPECTED_REFERENCES_DRAWER_KEYS = [ 'referencesDrawerEmpty', ] as const -test('supported embed locales include zh-CN, en-US, ko-KR, ja-JP, ru-RU', () => { - assert.deepEqual([...SUPPORTED_LOCALES].sort(), ['en-US', 'ja-JP', 'ko-KR', 'ru-RU', 'zh-CN'].sort()) +test('supported embed locales include zh-CN, zh-TW, en-US, ko-KR, ja-JP, ru-RU', () => { + assert.deepEqual([...SUPPORTED_LOCALES].sort(), ['en-US', 'ja-JP', 'ko-KR', 'ru-RU', 'zh-CN', 'zh-TW'].sort()) }) test('every supported locale defines conversationTime and referencesDrawer in chat', () => { @@ -149,6 +149,14 @@ test('normalizeEmbedLocale maps tags accurately with fallback to zh-CN', () => { assert.equal(normalizeEmbedLocale('zh-CN'), 'zh-CN') assert.equal(normalizeEmbedLocale('zh'), 'zh-CN') assert.equal(normalizeEmbedLocale('ZH-cn'), 'zh-CN') + // 繁中變體不得被通用 'zh' 規則吞掉 + assert.equal(normalizeEmbedLocale('zh-TW'), 'zh-TW') + assert.equal(normalizeEmbedLocale('zh-tw'), 'zh-TW') + assert.equal(normalizeEmbedLocale('ZH-TW'), 'zh-TW') + assert.equal(normalizeEmbedLocale('zh-Hant'), 'zh-TW') + assert.equal(normalizeEmbedLocale('zh-Hant-TW'), 'zh-TW') + assert.equal(normalizeEmbedLocale('zh-HK'), 'zh-TW') + assert.equal(normalizeEmbedLocale('zh-MO'), 'zh-TW') assert.equal(normalizeEmbedLocale('en-US'), 'en-US') assert.equal(normalizeEmbedLocale('en'), 'en-US') assert.equal(normalizeEmbedLocale('EN-gb'), 'en-US') diff --git a/frontend/src/i18n/index.ts b/frontend/src/i18n/index.ts index da377fb00e9..1bfbb866b99 100755 --- a/frontend/src/i18n/index.ts +++ b/frontend/src/i18n/index.ts @@ -4,10 +4,12 @@ import ruRU from './locales/ru-RU.ts' import enUS from './locales/en-US.ts' import koKR from './locales/ko-KR.ts' import jaJP from './locales/ja-JP.ts' +import zhTW from './locales/zh-TW.ts' import { BUILT_IN_DEFAULT, resolveDefaultLocale } from './resolveDefaultLocale.ts' const messages = { 'zh-CN': zhCN, + 'zh-TW': zhTW, 'en-US': enUS, 'ru-RU': ruRU, 'ko-KR': koKR, diff --git a/frontend/src/i18n/localeKeyAudit.test.ts b/frontend/src/i18n/localeKeyAudit.test.ts index 1be52f30252..fe3db027d37 100644 --- a/frontend/src/i18n/localeKeyAudit.test.ts +++ b/frontend/src/i18n/localeKeyAudit.test.ts @@ -205,6 +205,7 @@ test('prune rebuild restores registered audit keys from baked-in English default const emptyBundles = { 'en-US': {}, 'zh-CN': {}, + 'zh-TW': {}, 'ko-KR': {}, 'ja-JP': {}, 'ru-RU': {}, diff --git a/frontend/src/i18n/localeKeyAudit.ts b/frontend/src/i18n/localeKeyAudit.ts index c3079374d56..ad6460cd53b 100644 --- a/frontend/src/i18n/localeKeyAudit.ts +++ b/frontend/src/i18n/localeKeyAudit.ts @@ -21,10 +21,12 @@ import jaJP from './locales/ja-JP.ts' import koKR from './locales/ko-KR.ts' import ruRU from './locales/ru-RU.ts' import zhCN from './locales/zh-CN.ts' +import zhTW from './locales/zh-TW.ts' export const LOCALE_BUNDLES = { 'en-US': enUS, 'zh-CN': zhCN, + 'zh-TW': zhTW, 'ko-KR': koKR, 'ja-JP': jaJP, 'ru-RU': ruRU, @@ -527,7 +529,7 @@ export function findAllLocaleMessageCompileErrors( type LocaleTree = Record -const LOCALE_ORDER: LocaleName[] = ['en-US', 'zh-CN', 'ko-KR', 'ru-RU', 'ja-JP'] +const LOCALE_ORDER: LocaleName[] = ['en-US', 'zh-CN', 'zh-TW', 'ko-KR', 'ru-RU', 'ja-JP'] const LOCALES_DIR = join(dirname(fileURLToPath(import.meta.url)), 'locales') function getLocaleValueAtPathParts(current: unknown, parts: string[]): unknown { diff --git a/frontend/src/i18n/locales/en-US.ts b/frontend/src/i18n/locales/en-US.ts index d0c7b4b7d9e..afb798b60aa 100755 --- a/frontend/src/i18n/locales/en-US.ts +++ b/frontend/src/i18n/locales/en-US.ts @@ -5120,6 +5120,7 @@ export default { }, language: { zhCN: '简体中文', + zhTW: 'Traditional Chinese', enUS: 'English', ruRU: 'Русский', koKR: '한국어', diff --git a/frontend/src/i18n/locales/ja-JP.ts b/frontend/src/i18n/locales/ja-JP.ts index 1cbb54ecd9b..b8e3e047287 100644 --- a/frontend/src/i18n/locales/ja-JP.ts +++ b/frontend/src/i18n/locales/ja-JP.ts @@ -5120,6 +5120,7 @@ export default { }, language: { zhCN: '简体中文', + zhTW: '繁体字中国語', enUS: 'English', ruRU: 'Русский', koKR: '한국어', diff --git a/frontend/src/i18n/locales/ko-KR.ts b/frontend/src/i18n/locales/ko-KR.ts index 2af18593d91..da8fcf46fb3 100755 --- a/frontend/src/i18n/locales/ko-KR.ts +++ b/frontend/src/i18n/locales/ko-KR.ts @@ -2918,6 +2918,7 @@ export default { }, language: { zhCN: '简体中文', + zhTW: '번체 중국어', enUS: 'English', ruRU: 'Русский', koKR: '한국어', diff --git a/frontend/src/i18n/locales/ru-RU.ts b/frontend/src/i18n/locales/ru-RU.ts index 7adf0269de1..dfc07eb87a0 100755 --- a/frontend/src/i18n/locales/ru-RU.ts +++ b/frontend/src/i18n/locales/ru-RU.ts @@ -2918,6 +2918,7 @@ export default { }, language: { zhCN: '简体中文', + zhTW: 'Традиционный китайский', enUS: 'English', ruRU: 'Русский', koKR: '한국어', diff --git a/frontend/src/i18n/locales/workspaceTerminology.test.ts b/frontend/src/i18n/locales/workspaceTerminology.test.ts index a9a19df32ca..119dcf01f39 100644 --- a/frontend/src/i18n/locales/workspaceTerminology.test.ts +++ b/frontend/src/i18n/locales/workspaceTerminology.test.ts @@ -6,6 +6,7 @@ import jaJP from './ja-JP.ts' import koKR from './ko-KR.ts' import ruRU from './ru-RU.ts' import zhCN from './zh-CN.ts' +import zhTW from './zh-TW.ts' type LocaleValue = string | Record | unknown[] @@ -34,6 +35,7 @@ function withoutTechnicalTenantTokens(value: string): string { const localeChecks = [ { name: 'zh-CN', locale: zhCN, forbidden: /租户/ }, + { name: 'zh-TW', locale: zhTW, forbidden: /租戶/ }, { name: 'en-US', locale: enUS, forbidden: /\btenants?\b/i }, { name: 'ko-KR', locale: koKR, forbidden: /테넌트/ }, { name: 'ja-JP', locale: jaJP, forbidden: /テナント/ }, diff --git a/frontend/src/i18n/locales/zh-CN.ts b/frontend/src/i18n/locales/zh-CN.ts index 01245a89df6..68debaf27ae 100755 --- a/frontend/src/i18n/locales/zh-CN.ts +++ b/frontend/src/i18n/locales/zh-CN.ts @@ -2920,6 +2920,7 @@ export default { }, language: { zhCN: '简体中文', + zhTW: '繁體中文', enUS: 'English', ruRU: 'Русский', koKR: '한국어', diff --git a/frontend/src/i18n/locales/zh-TW.ts b/frontend/src/i18n/locales/zh-TW.ts new file mode 100644 index 00000000000..400cf30aaaf --- /dev/null +++ b/frontend/src/i18n/locales/zh-TW.ts @@ -0,0 +1,7799 @@ +export default { + modelCatalog: { + "title": "模型目錄", + "description": "模型目錄決定新增模型時可選的模型清單,以及脈絡視窗、是否支持思考等預設參數。在這裡修改後,所有空間立即生效。", + "howItWorks": "設定如何生效", + "layers": { + "builtin": "內建目錄:隨版本發布的預設模型清單。", + "deployment": "部署檔案:伺服器上的 models.json,可覆蓋內建目錄。", + "console": "管理員修改:在本頁所做的修改,優先於以上兩者。", + "explicit": "各空間在模型設定中填寫的參數始終優先;修改目錄不會改寫已儲存的模型。", + }, + "add": "新增模型", + "more": "更多", + "jsonEditor": "JSON 編輯", + "history": "版本歷史", + "import": "匯入 JSON", + "export": "匯出修改", + "search": "搜尋模型 ID 或名稱", + "allProviders": "全部廠商", + "allTypes": "全部類型", + "onlyModified": "只看已修改", + "summary": "{count} 個模型 · 版本 {version}", + "columns": { + "model": "模型", + "provider": "廠商", + "type": "類型", + "tokens": "脈絡 / 輸出", + "capabilities": "能力", + "source": "來源", + }, + "capability": { + "reasoning": "思考", + "image": "影像", + "audio": "音訊", + "video": "影片", + }, + "source": { + "builtin": "內建", + "deployment": "部署檔案", + "console": "管理員修改", + }, + "rule": "比對規則", + "ruleTip": "按名稱模式比對一組模型,只提供預設參數,不會出現在候選清單中。", + "hidden": "已隱藏", + "edit": "編輯", + "view": "查看", + "empty": "沒有比對的模型", + "editDescription": "{provider} · {type}", + "ruleNotice": "這是一條比對規則,為名稱符合該模式的模型提供預設參數。如需修改,請使用「更多 → JSON 編輯」。", + "fieldsSection": "預設參數", + "nameDesc": "在模型選擇清單中顯示的名稱。", + "dimension": "向量維度", + "dimensionDesc": "新增該向量模型時預填的維度,需與模型實際輸出一致。", + "inputDesc": "模型可接收的輸入類型;勾選影像後可作為視覺模型使用。", + "thinkingLevels": "思考等級", + "thinkingLevelsDesc": "對話中可選的思考強度。未勾選「關閉」表示該模型始終思考。", + "levelsNeedReasoning": "開啟「支持思考」後可設定。", + "levelsUnsupported": "該廠商介面不支持分級思考。", + "textOnly": "僅文字", + "noLevels": "無", + "sourceLink": "廠商文件", + "customHint": "這是管理員在本頁新增的模型,參數均來自這裡的設定。", + "fieldsHint": "各空間在模型設定中填寫的參數仍然優先。輸入框留空即復原預設值。", + "context": "脈絡視窗", + "contextDesc": "模型一次可處理的最大 token 數。", + "output": "最大輸出", + "outputDesc": "單次回覆最多生成的 token 數。", + "reasoning": "支持思考", + "reasoningDesc": "模型能否輸出思考過程。", + "hide": "在候選清單中隱藏", + "hideDesc": "隱藏後新增模型時不再出現,已設定的模型不受影響。", + "inputModes": "輸入模態", + "inherited": "預設:{value}", + "notSet": "未設定", + "optional": "可選", + "yes": "是", + "no": "否", + "modified": "已修改", + "layersSection": "各層取值", + "layerField": "參數", + "layerBuiltin": "內建目錄", + "layerDeployment": "部署檔案", + "layerEffective": "當前生效", + "save": "儲存並生效", + "restore": "復原預設", + "restoreConfirm": "移除對該模型的全部管理員修改,並立即生效?", + "restored": "已復原,其他實例約 5 秒內同步", + "remove": "刪除模型", + "removeConfirm": "從目錄中刪除這個由管理員新增的模型,並立即生效?", + "removed": "已刪除,其他實例約 5 秒內同步", + "published": "已生效,其他實例約 5 秒內同步", + "conflict": "目錄已被其他管理員更新,已重新整理到最新版本,請重新操作。", + "loadFailed": "模型目錄載入失敗", + "deploymentError": "部署檔案 models.json 載入失敗,當前只使用內建目錄:{error}", + "syncError": "最新版本同步失敗,頁面顯示的可能不是當前生效的設定:{error}", + "addDescription": "為廠商補充目錄中沒有的模型,新增後可在模型設定中直接選擇。", + "modelId": "模型 ID", + "modelIdPlaceholder": "與廠商 API 中的模型名一致,如 gpt-5-mini", + "displayName": "顯示名稱", + "required": "請選擇廠商並填寫模型 ID", + "exists": "該模型已在目錄中,請直接編輯", + "jsonDescription": "用 models.json 格式直接編輯全部管理員修改,適合批次調整或遷移。", + "jsonHint": "只寫需要修改的欄位,刪除欄位即復原預設。憑據、請求頭和環境變數引用請在模型設定或部署檔案中維護;圖示僅支持行內 SVG;最大 1 MiB。", + "jsonClear": "清空全部修改", + "jsonCheck": "檢查變更", + "jsonPublish": "發布 {count} 項變更", + "jsonUnchanged": "與當前生效的設定一致,無需發布。", + "changesTitle": "將要生效的變更", + "change": { + "added": "新增", + "removed": "移除", + "updated": "修改", + "provider": "廠商", + }, + "publishHint": "發布後本實例立即生效,其他實例約 5 秒內同步。", + "invalid": "請輸入包含 providers 物件的 models.json。", + "tooLarge": "檔案不能超過 1 MiB。", + "historyDescription": "保留最近 20 個版本,復原後立即生效。", + "historyVersion": "版本 {version}", + "historyCurrent": "當前", + "historyRestore": "復原", + "historyRestoreConfirm": "復原到版本 {version} 的設定,並立即對所有空間生效?", + "historyEmpty": "暫無歷史版本", + "historyModels": "修改了 {count} 個模型", + "historyNoOverrides": "無管理員修改", + }, + toolbox: { + "title": "工具箱", + "description": "管理智慧代理可用的技能、外部工具和瀏覽器連結。", + "unavailable": "當前空間暫無可用的工具。" + }, + localBrowser: { + pipOpen: "彈出懸浮窗", + pipReturn: "返回對話小窗", + pipFailed: "無法打開懸浮窗,請重試。", + + captureScreenshot: "截取網頁畫面", + navigationIncomplete: "導航未達到目標載入階段,請檢查當前頁面。", + noEntries: "沒有返回記錄。", + stopping: "正在結束任務…", + elapsedSeconds: "{seconds} 秒", + + searchInstructionsTitle: "瀏覽器搜尋指令", + searchInstructionsDescription: "設定你偏好的搜尋引擎和搜尋地址。", + searchInstructionsHint: "儲存後下次請求生效,留空使用預設指令。", + searchInstructionsReset: "復原預設", + searchInstructionsSaved: "已儲存", + + "sourceHint": "本輪使用本機瀏覽器查詢和操作網頁,可與聯網搜尋、知識庫及其他工具配合使用。", + "pressKey": "按鍵", + "hoverPage": "懸停元素", + "scrollPage": "滾動頁面", + "focusElement": "聚焦元素", + "blurElement": "移開焦點", + "selectOption": "選擇選項", + "closeTab": "關閉分頁", + "runScript": "執行網頁指令碼", + "readConsole": "查看控制台", + "readNetwork": "查看網路請求", + "resizeWindow": "調整視窗大小", + "emulateDevice": "模擬裝置", + "actionPending": "正在操作瀏覽器…", + "actionRecorded": "已記錄瀏覽器操作", + "untitledTab": "未命名分頁", + "contentTruncated": "僅顯示部分網頁內容。", + "controlScope": "僅控制本對話的瀏覽器操作", + "pauseHint": "中斷當前瀏覽器操作並保留頁面,可繼續操作;不會停止整段對話。", + "stopHint": "關閉本任務新建的分頁,歸還借用的分頁;不會關閉瀏覽器或撤銷配對。", + "openPage": "打開網頁", + "switchPage": "切換網頁", + "readPage": "查看網頁", + "listTabs": "查看分頁", + "clickPage": "點擊元素", + "fillPage": "填寫內容", + "waitPage": "等待頁面", + "openTab": "新建任務標籤", + "switchTab": "切換任務標籤", + "authorizeTab": "請求標籤授權", + "returnTab": "歸還標籤", + "needHelp": "等待你操作", + "browserAction": "瀏覽器操作", + "actionFailed": "未完成", + "actionCompleted": "操作已完成", + "commandBusy": "上一條瀏覽器操作尚未結束,請等待完成後繼續。", + "invalidArguments": "瀏覽器工具參數格式錯誤或不完整,智慧代理需要修正後再執行。", + "commandInterrupted": "瀏覽器操作已中斷,請先確認頁面狀態,再從小預覽繼續任務。", + "actionFailedHint": "瀏覽器操作未完成,請檢查當前頁面後重試。", + "previewStale": "畫面暫未更新", + "previewIdle": "已保留最後畫面", + "previewLive": "畫面同步中", + "previewLoading": "正在獲取畫面", + "borrowHint": "請切換到要借用的網頁,在 BrowserSkill 授權提示中選擇「允許」或「拒絕」。授權透過後會自動繼續;「繼續操作」只復原暫停的任務,不代替借用授權。", + "helpHint": "點擊預覽前往瀏覽器,完成上述步驟後,在瀏覽器幫助提示中確認完成。", + + "settingsTitle": "瀏覽器連結", + "settingsDescription": "透過 BrowserSkill 連結本機 Chrome 或 Edge,配對後即可在對話中操作真實網頁。", + "openSettings": "前往瀏覽器連結", + "settingsHint": "在工具箱中連結 BrowserSkill,即可在對話裡使用本機瀏覽器。", + "unavailable": "伺服器端尚未啟用本機瀏覽器,請聯絡管理員。", + + "source": "瀏覽器來源", + "sandbox": "沙箱瀏覽器", + "local": "本機瀏覽器", + "paused": "已暫停", + "connected": "已連結", + "disconnected": "未連結", + "resume": "繼續操作", + "pause": "暫停操作", + "start": "開始任務", + "stop": "結束瀏覽器任務", + "resumeShort": "繼續", + "pauseShort": "暫停", + "stopShort": "結束", + "pairHint": "打開擴展的「連結設定 → 遠程連結」,貼上配對連結並確認伺服器。連結 5 分鐘內有效,僅可使用一次。", + "copyPairing": "複製配對連結", + "copied": "已複製", + "windowHint": "任務在獨立的瀏覽器任務視窗中運行。借用已有分頁需要你的授權。", + "preview": "本機瀏覽器任務預覽", + "waiting": "等待任務頁面", + "startHint": "發起瀏覽器請求後,會建立獨立的任務視窗。", + "revoke": "撤銷裝置授權", + "revokeConfirm": "撤銷後需要重新配對,才能繼續使用本機瀏覽器。", + "failed": "操作失敗,請重試", + "productDescription": "開源的 Chrome / Edge 擴展,讓智慧代理在你的瀏覽器裡打開網頁、讀取內容並完成操作。", + "offline": "離線", + "notPaired": "未配對", + "lastSeen": "最近連結", + "readyHint": "已準備就緒。回到對話,直接描述需要瀏覽器完成的任務。", + "capabilitiesTitle": "智慧代理可以", + "sidebarStatus": "在側邊欄顯示連結狀態", + "reconnectHint": "保留授權,等待擴展自動重連。請確認瀏覽器和 BrowserSkill 擴展已開啟。", + "replaceDevice": "更換瀏覽器", + "installExtension": "安裝 BrowserSkill 擴展", + "storeInstall": "Chrome 應用商店", + "edgeStoreInstall": "Edge 載入項", + "extensionMinVersion": "需要 BrowserSkill v{version} 及以上版本,支持 Chrome 和 Edge。", + "extensionOutdated": "當前擴展版本 v{current} 過低,請升級到 v{version} 及以上。", + "manualInstall": "手動安裝(備用)", + "storeInstallHint": "在 Chrome 應用商店或 Edge 載入項中安裝 BrowserSkill,再回到這裡配對。", + "installHint": "無法存取商店或商店版本不相容時,可下載配套擴展並手動安裝。", + "downloadExtension": "下載配套擴展", + "officialExtension": "官方擴展(Chrome 應用商店)", + "installGuide": "如何安裝下載的擴展包?", + "pairGuide": "如何使用配對連結?", + "pairBrowser": "連結這台瀏覽器", + "packageUnavailable": "管理員尚未設定擴展下載包,請向管理員獲取配套版本。", + "manualCopy": "點擊下方輸入框複製連結,5 分鐘內有效,僅可配對一次。", + "pairingReady": "連結已複製。請在擴展中貼上,5 分鐘內有效,僅可配對一次。", + "copyAgain": "再次複製", + "usageTitle": "使用方式", + "usageStep1Title": "安裝擴展", + "usageStep1Text": "下載 ZIP 後解壓縮,在瀏覽器地址欄輸入 chrome://extensions(Edge 為 edge://extensions),開啟「開發者模式」,點擊「載入已解壓縮的擴展程式」,選擇解壓縮後的擴展目錄。", + "usageStep2Title": "配對這台瀏覽器", + "usageStep2Text": "複製配對連結,在擴展的「連結設定 → 遠程連結」中貼上並確認伺服器。配對一次,同一空間的各個對話共用。", + "usageStep3Title": "回到對話描述任務", + "usageStep3Text": "在對話輸入欄開啟「本機瀏覽器」,再傳送網頁任務。配對不會自動開啟此選項,任務會在獨立的任務視窗中運行。", + "usageStep4Title": "透過預覽查看和繼續", + "usageStep4Text": "對話裡會出現小預覽,點擊可定位到任務標籤。中斷或重連後任務仍會暫停,請在預覽中點繼續;借用已有分頁會先請你確認。", + "running": "運行中", + "locateWindow": "定位到瀏覽器", + "reconnectShort": "等待瀏覽器重連", +}, + resourceSort: { + title: '排序', + updatedTime: '更新時間', + updatedTimeDescription: '預設選項。', + createdTime: '建立時間', + createdTimeDescription: '查看最新或最早建立的內容', + name: '名稱', + nameDescription: '快速尋找明確知道名稱的內容', + recentlyUpdated: '最近更新', + earliestUpdated: '最早更新', + recentlyCreated: '最近建立', + earliestCreated: '最早建立', + nameAscending: 'A–Z', + nameDescending: 'Z–A', + }, + platformApiKeys: { + title: '平台 API Key', + description: '為跨空間自動化建立平台級憑據;呼叫空間介面時透過 X-Tenant-ID 指定目標空間。', + securityNotice: '平台 API Key 預設可選擇任意空間。請只授予必要能力;金鑰明文僅在建立時顯示一次。', + create: '建立平台 API Key', + createDescription: '平台 Key 不綁定空間,所有操作仍受能力範圍限制。', + loading: '正在載入…', + empty: '暫無平台 API Key', + name: '名稱', + namePlaceholder: '例如:集中運維自動化', + key: '金鑰', + capability: '能力授權', + capabilityMore: '+{count}', + viewAllCapabilities: '查看全部能力授權', + capabilityHint: '空間能力對任意 X-Tenant-ID 生效;系統能力用於平台控制面介面。', + lastUsed: '最後使用', + createdAt: '建立時間', + actions: '操作', + never: '從未使用', + systemCapabilityGroup: '平台控制面', + createdTitle: '平台 API Key 已建立', + createdDescription: '請立即複製並安全儲存。關閉後將不再顯示完整金鑰。', + copy: '複製金鑰', + copySuccess: '金鑰已複製', + deleteConfirm: '確定刪除「{name}」嗎?使用該 Key 的自動化將立即失效。', + deleteSuccess: '平台 API Key 已刪除', + deleteFailed: '刪除平台 API Key 失敗', + nameRequired: '請輸入名稱', + capabilityRequired: '請至少選擇一項能力', + loadFailed: '載入平台 API Key 失敗', + createFailed: '建立平台 API Key 失敗', + capabilityHints: { + tenantsRead: '列出、搜尋和查看所有空間。', + tenantsManage: '建立、更新、刪除空間及應用全局空間設定。', + settingsRead: '讀取平台級運行設定。', + settingsManage: '更新和重設平台級運行設定。', + runtimeRead: '查看任務佇列和任務詳情。', + runtimeManage: '重試、立即執行、取消或刪除運行時任務。', + auditRead: '讀取平台級稽核日誌。' + }, + capabilities: { + tenantsRead: '查看空間', + tenantsManage: '管理空間', + settingsRead: '查看系統設定', + settingsManage: '管理系統設定', + runtimeRead: '查看運行時', + runtimeManage: '管理運行時', + auditRead: '查看系統稽核' + } + }, + tenantInvitation: { + inboxTooltip: '查看待接受的邀請', + pendingSectionTitle: '待接受的邀請', + pendingSectionDesc: '發出後等待對方在站內確認。{days} 天未回應將自動過期。', + pendingEmpty: '暫無待接受的邀請。', + inviteSubmit: '傳送邀請', + inviteSuccess: '邀請已發出,等待對方接受。', + confirmInviteTitle: '確認傳送邀請?', + confirmInviteBody: '將向 {email} 發出加入邀請(角色:{role})。TA 在站內接受後才會成為成員。', + confirmSend: '傳送', + copyLink: '複製邀請連結', + copied: '已複製到剪貼簿', + copyFailed: '複製失敗,請手動選中文字', + errors: { + pendingExists: '已經向該使用者發出過一條待接受的邀請。', + alreadyMember: '該使用者已是當前空間的成員。', + notPending: '邀請已不在待處理狀態。', + forbidden: '只有被邀請人本人可以接受或拒絕該邀請。', + notFound: '邀請不存在或已被撤銷。', + generic: '操作失敗,請稍後重試。' + }, + myInbox: { + title: '我的邀請', + description: '其他空間發給您的加入邀請。接受後您將以對應角色加入對方空間。', + empty: '沒有待處理的邀請。', + acceptButton: '接受', + declineButton: '拒絕', + acceptSuccess: '已加入 "{tenant}"。', + declineSuccess: '已拒絕邀請。', + from: '邀請人', + tenantLabel: '空間', + expiresIn: '到期:{date}', + messageLabel: '留言' + }, + status: { + pending: '待接受', + shareLinkActive: '生效中', + accepted: '已接受', + declined: '已拒絕', + revoked: '已撤銷', + expired: '已過期' + }, + columns: { + invitee: '被邀請人', + role: '角色', + inviter: '邀請人', + expiresAt: '到期時間', + status: '狀態', + operations: '操作' + }, + revoke: { + button: '撤銷', + confirmBody: '撤銷後,{email} 將無法再接受此邀請;如需再邀請請重新發出。', + confirm: '撤銷', + success: '邀請已撤銷。' + }, + shareLink: { + button: '生成共享連結', + cellTitle: '透過連結邀請', + cellAccepted: '已加入 {count} 人', + cellEmpty: '尚無成員加入', + dialogTitle: '生成共享邀請連結', + description: '生成一條多人可用的註冊連結,發到群裡就行;誰打開都能用自己的電子信箱註冊並加入當前空間。連結 {days} 天後過期,或隨時可在清單中撤銷。', + generate: '生成連結', + resultTitle: '邀請連結已生成', + resultBody: '複製下方連結,透過任意私密通路發給被邀請人。連結也會儲存在下方清單中,隨時可以重新複製或撤銷。', + revokeConfirm: '撤銷後,所有還未註冊的人都無法再使用此連結;如需重發請生成新連結。' + } + }, + tenantMember: { + title: '成員管理', + sectionDescription: '邀請夥伴加入當前空間並分配角色。只有 Owner 可以新增或移除成員。', + learnRbacGuide: '了解 RBAC', + listTitle: '空間成員', + loading: '正在載入成員…', + retry: '重試', + empty: '尚未邀請任何成員。點擊右上角邀請夥伴加入。', + emptySearch: '沒有比對 "{q}" 的成員。', + searchPlaceholder: '按姓名或電子信箱搜尋', + audit: { + tabLabel: '稽核日誌', + description: '記錄當前空間的成員變更與存取拒絕事件,按時間倒序展示。一分鐘內的重複拒絕會自動去重。', + refresh: '重新整理', + end: '已經到底了。', + empty: '暫無稽核事件。', + forbidden: '無權查看稽核日誌。', + systemActor: '系統', + requiredRole: '需要角色:{role}', + expanded: { + actorId: '操作人 ID', + targetUserId: '目標使用者 ID', + targetType: '目標類型', + targetId: '目標 ID', + details: '原始詳情' + }, + outcome: { + success: '成功', + denied: '拒絕' + }, + action: { + 'rbac.member_added': '新增成員', + 'rbac.member_removed': '移除成員', + 'rbac.member_role_changed': '角色變更', + 'rbac.member_left': '成員退出', + 'rbac.access_denied': '存取被拒', + 'rbac.invitation_sent': '發出邀請', + 'rbac.invitation_accepted': '接受邀請', + 'rbac.invitation_declined': '拒絕邀請', + 'rbac.invitation_revoked': '撤銷邀請', + 'rbac.invitation_expired': '邀請過期' + }, + columns: { + time: '時間', + actor: '操作人', + action: '事件', + target: '目標', + path: '請求', + outcome: '結果' + } + }, + errors: { + emailRequired: '請輸入電子信箱', + emailFormat: '電子信箱格式不正確', + roleRequired: '請選擇角色', + userNotFound: '該電子信箱尚未註冊,請先邀請對方註冊帳號。', + lastOwner: '無法降級、移除或退出最後一位 Owner,請先把其他成員提升為 Owner。', + notFound: '未找到對應的成員。', + invalidRole: '角色必須是 owner / admin / contributor / viewer 之一。', + generic: '操作失敗,請稍後重試。' + }, + roleChange: { + success: '角色已更新' + }, + leave: { + confirmTitle: '確認退出當前空間?', + confirmBody: '退出後您將無法存取當前空間內的所有知識庫和智慧代理。後續可被再次邀請加入。', + confirm: '退出', + success: '已退出當前空間' + }, + remove: { + button: '移除', + confirmBody: '確定要將 {name} 從當前空間中移除嗎?該使用者會立即失去存取權限。', + confirm: '移除', + success: '已移除成員' + }, + add: { + button: '邀請成員', + dialogTitle: '邀請成員', + emailLabel: '電子信箱', + emailPlaceholder: 'invitee{\'@\'}example.com', + roleLabel: '角色' + }, + role: { + owner: '所有者', + admin: '管理員', + contributor: '編輯', + viewer: '訪客' + }, + columns: { + member: '姓名與電子信箱', + role: '角色', + joinedAt: '加入時間', + operations: '操作' + }, + permissions: { + title: '角色權限說明', + desc: '每個角色在當前空間內能做的事情。伺服器端強制執行,UI 控制項僅作展示。', + iconHint: '懸停查看角色權限說明', + manageMembers: '管理成員', + manageTenantConfig: '修改空間設定', + manageInfra: '設定模型 / 向量庫 / IM 通道', + createOwnKB: '建立並編輯自己的知識庫和智慧代理', + readAll: '查看空間內容' + } + }, + userProfile: { + title: '使用者資訊', + description: '查看您的帳戶基礎資訊(使用者 ID、使用者名、電子信箱、註冊時間),並可修改登入密碼', + changePassword: { + label: '修改密碼', + description: '使用當前密碼驗證後設定新密碼。修改成功後所有裝置上的登入狀態將失效,需要重新登入。', + currentLabel: '當前密碼', + currentPlaceholder: '請輸入當前密碼', + currentRequired: '請輸入當前密碼', + newLabel: '新密碼', + newPlaceholder: '請輸入新密碼', + confirmLabel: '確認新密碼', + confirmPlaceholder: '再次輸入新密碼', + submit: '更新密碼', + success: '密碼已更新,請使用新密碼重新登入', + failed: '修改密碼失敗,請檢查當前密碼是否正確', + policyFailed: '新密碼須為 8-32 個字符,且同時包含字母和數字', + sameAsCurrent: '新密碼不能與當前密碼相同', + oidcOnlyDescription: '您的帳號透過 OIDC 登入開通,尚未設定本地登入密碼。', + oidcOnlyNotice: '請聯絡系統管理員重設密碼,或繼續使用 OIDC 登入。自助修改密碼需要先知道當前密碼。', + }, + }, + credential: { + configured: '已設定', + unconfigured: '未設定', + configure: '設定', + update: '更換', + remove: '移除', + inputPlaceholder: '請輸入', + savedToast: '憑據已儲存', + saveFailed: '儲存憑據失敗', + removedToast: '憑據已移除', + removeFailed: '移除憑據失敗', + confirmRemovePrompt: '確認移除?此操作不可復原', + confirmRemove: '確認移除' + }, + integrations: { + cli: { + title: 'WeKnora CLI', + subtitle: '在終端中管理知識庫和文件、檢索內容併發起問答,也可透過指令碼或 MCP 接入 AI 工具。', + docs: '查看 CLI 文件', + docsHint: '安裝說明與完整命令參考', + quickstart: '快速開始', + installTitle: '安裝 CLI', + installDesc: '目前支持源碼建構,需要 Git 和 Go 1.26+。以下示例適用於 macOS / Linux,PATH 設定僅在當前終端生效;長期使用請將二進位放入 PATH 目錄。', + connectTitle: '連結當前服務', + connectDesc: '建立並啟用名為 weknora 的連結設定,然後使用電子信箱和密碼登入。如果已有同名設定,請更換名稱,並同步修改 MCP 示例中的設定名。', + verifyTitle: '驗證連結', + verifyDesc: '檢查服務與認證狀態,並列出當前帳號可存取的知識庫。', + commandsTitle: '常用命令', + commandsDesc: '將 KB_ID 取代為知識庫 ID,按需取代檔案路徑、檢索詞和問題。上傳後的文件需解析完成才能檢索。', + mcpTitle: '接入 MCP 用戶端', + mcpDesc: '完成登入後,將以下設定新增到支持 stdio 的 MCP 用戶端。若用戶端無法找到 weknora,請將 command 改為二進位的絕對路徑。', + copy: '複製', + copied: '已複製', + }, + title: '發布集成', + selectAgentPlaceholder: '請選擇智慧代理', + selectAgentHint: '請先選擇一個智慧代理', + boundAgent: '綁定智慧代理', + filterByAgent: '按智慧代理篩選', + filterByAgentWithName: '按智慧代理篩選:{name}', + filterAllAgents: '全部智慧代理', + claw: { + title: 'WeKnora Skill', + subtitle: '透過 WeKnora REST API 匯入文件並執行混合檢索(向量 + 關鍵字)。適用於上傳檔案/URL/Markdown 到知識庫、跨庫檢索與瀏覽知識內容。', + capabilitiesTitle: 'Skill 能力', + stepsTitle: '設定步驟', + openApiSettings: '打開 API 資訊', + copy: '複製', + copyEnvSuccess: '已複製環境變數示例', + copyCmdSuccess: '已複製安裝命令', + ecosystemNote: 'Skill 託管於 ClawHub({\'@\'}lyingbug/weknora),完整 API 說明與版本歷史請參見 ClawHub 頁面。', + installCta: '前往 ClawHub', + installCtaHint: '安裝 WeKnora Skill · 將在新分頁打開', + hubMeta: 'ClawHub · {\'@\'}lyingbug/weknora · MIT-0', + steps: { + verify: { + title: '驗證連結', + desc: '安裝後讓 Agent 列出知識庫或執行一次檢索,確認 API 憑證與網路可達。' + }, + install: { + title: '安裝 Skill', + desc: '在已安裝 OpenClaw CLI 的環境中執行下方命令,或前往 ClawHub 頁面按指引安裝。' + }, + env: { + title: '設定環境變數', + desc: '在終端或 ~/.zshrc、~/.bashrc 中設定 WEKNORA_BASE_URL 與 WEKNORA_API_KEY。下方示例已填入當前 API 地址,請將 API Key 取代為實際值。' + }, + api: { + title: '獲取 API 憑證', + desc: '在「設定 → API 資訊」中複製 API Key 與 API 地址。' + } + }, + capabilities: { + browse: { + title: '瀏覽知識庫', + desc: '列出知識庫與條目、查看詳情,管理已匯入的知識內容。' + }, + search: { + title: '混合檢索', + desc: '單庫 hybrid-search 與跨庫 knowledge-search,結合向量與關鍵字召回。' + }, + manual: { + title: '寫入 Markdown', + desc: '以 Markdown 形式建立或編輯知識條目,適合會議記錄與結構化筆記。' + }, + url: { + title: '匯入網頁', + desc: '透過 URL 抓取網頁內容並寫入知識庫,支持解析狀態輪詢。' + }, + upload: { + title: '上傳檔案', + desc: '將 PDF、Word、Excel 等文件上傳至知識庫,自動解析與向量化。' + } + } + }, + chrome: { + title: '知識管理助手', + subtitle: '配合 WeKnora 自建服務使用:在任意網頁側邊欄提問、剪藏內容、Markdown 速記,將瀏覽中的知識沉澱到你的知識庫。', + capabilitiesTitle: '核心能力', + stepsTitle: '設定步驟', + openApiSettings: '打開 API 資訊', + copy: '複製', + copySuccess: '已複製 API 地址', + installCta: '前往 Chrome 應用商店', + installCtaHint: '官方擴展 · 將在新分頁打開', + storeMeta: 'Chrome 應用商店 · v1.0.0', + steps: { + connect: { + title: '在外掛中完成連結', + desc: '打開外掛設定,選擇「企業/開發者」模式,填入服務 API 地址與 API Key。下方為當前服務地址。' + }, + install: { + title: '安裝 Chrome 外掛', + desc: '前往 Chrome 應用商店安裝「知識管理助手」。' + }, + port: { + title: '桌面版設定固定連接埠(推薦)', + desc: '使用 WeKnora 桌面版時,在 API 資訊中設定固定連接埠(如 37841),避免每次啟動後地址變化導致外掛斷連。' + }, + api: { + title: '獲取 API 憑證', + desc: '在「設定 → API 資訊」中複製 API Key 與 API 地址。' + } + }, + scenarios: { + research: '日常資料調研', + learning: '學習筆記整理', + tech: '技術資料收集', + work: '工作知識沉澱' + }, + capabilities: { + shortcuts: { + title: '高效快速鍵', + desc: '可自定義快速鍵快速提問、打開側邊欄等操作,提升日常效率。' + }, + notes: { + title: 'Markdown 速記', + desc: '內建 Markdown 編輯器,隨時記錄靈感與筆記,一鍵儲存到知識庫。' + }, + clip: { + title: '網頁內容一鍵採集', + desc: '儲存頁面 URL、AI 智慧剪藏正文,或手動框選區域,精準寫入指定知識庫。' + }, + qa: { + title: '知識庫智慧問答', + desc: '側邊欄對話面板,支持多知識庫切換與快速/深度/精確三種回答模式,邊瀏覽邊提問不打斷工作流程。' + } + } + }, + agentEditor: { + label: '發布通路', + desc: '將智慧代理發布到 IM 平台或網站,在集成中心統一管理' + }, + embedOverview: { + title: '網頁內嵌通路' + }, + imOverview: { + title: '已接入的 IM' + }, + api: { + title: 'API 集成', + subtitle: '透過 REST API 接入服務,並設定請求如何攜帶終端使用者身份。', + loading: '正在載入 API 集成設定...', + retry: '重試', + copy: '複製', + copySuccess: '已複製', + baseUrl: 'API 地址', + baseUrlDesc: '與 REST API 路徑串接使用。', + apiKeys: 'API Keys', + apiKeysDesc: '為不同集成建立獨立 Key,並限制操作權限與可存取知識庫範圍。', + createApiKey: '建立 API Key', + createApiKeyDialogDesc: '選擇該 API Key 可用的能力和知識庫範圍。', + noApiKeys: '暫無 API Key', + apiKeyName: '名稱', + apiKeyValue: 'API Key', + apiKeyNamePlaceholder: '例如:MCP 唯讀存取', + apiKeyNameRequired: '請輸入 API Key 名稱', + apiKeyCapabilitiesRequired: 'Scoped API Key 至少需要選擇一項能力', + apiKeyAccessMode: '授權方式', + apiKeyScopedAccess: '能力授權', + apiKeyAccessType: '存取類型', + apiKeyAccessTypeHint: '「知識庫」按下方權限級別在知識庫範圍內操作;「空間完全存取」額外開放模型、資料源等全部空間級介面。', + apiKeyCapabilities: '可用能力', + apiKeyCapabilityGroupKnowledge: '知識庫資料', + apiKeyCapabilityGroupAutomation: '智慧代理與集成', + apiKeyCapabilityGroupCollaboration: '成員與空間', + apiKeyCapabilityGroupTenant: '空間設定', + apiKeyCapabilitySelectGroup: '全選', + apiKeyCapabilityClearGroup: '清空', + capabilityTenantFull: '空間完全存取', + capabilityTenantFullHint: '允許呼叫模型、向量庫、資料源、通路等全部空間級介面;知識庫範圍不再生效。', + capabilityRetrieve: '檢索知識庫', + capabilityRetrieveHint: '允許讀取、查詢和檢索所選知識庫範圍內的資料;不建立會話,也不修改內容。', + capabilityChat: '對話能力', + capabilityChatHint: '允許該金鑰發起對話並管理自己的會話;不修改知識庫內容。', + capabilityReadAgents: '讀取智慧代理', + capabilityReadAgentsHint: '允許列出智慧代理、查看智慧代理詳情、讀取智慧代理預設和建議問題;不允許發起對話或修改智慧代理。', + capabilityIngest: '寫入知識庫內容', + capabilityIngestHint: '允許向授權範圍內的知識庫寫入內容(上傳文件、編輯切塊/FAQ/標籤/wiki);不能新建知識庫、不能新建智慧代理、不能清空知識庫,且僅限所選知識庫範圍。', + capabilityManageKbs: '管理知識庫', + capabilityManageKbsHint: '允許管理知識庫全生命週期:新建、複製、修改、刪除知識庫並調整初始化/設定資訊。針對已有知識庫的操作(複製/更新/刪除)仍受所選知識庫範圍限制;新建不受限(新知識庫歸本空間)。', + capabilityManageAgents: '管理智慧代理', + capabilityManageAgentsHint: '允許建立、修改、刪除、複製智慧代理。智慧代理設定可能含模型/MCP 等敏感綁定,預設關閉,按需開啟。', + capabilityMessageHistory: '訊息歷史', + capabilityMessageHistoryHint: '允許檢索空間聊天歷史並讀取聊天歷史統計;不授予空間設定權限。', + capabilityManageModels: '管理模型', + capabilityManageModelsHint: '允許管理模型設定、模型憑據、模型連通性測試和 WeKnoraCloud 憑據。', + capabilityManageMcpServices: '管理 MCP 服務', + capabilityManageMcpServicesHint: '允許管理 MCP 服務、憑據、工具審批策略和該主體的 OAuth 授權狀態。', + capabilityManageDatasources: '管理資料源', + capabilityManageDatasourcesHint: '允許管理資料源連接器、憑據、資源選擇和同步任務;綁定知識庫時仍受知識庫範圍限制。', + capabilityManageChannels: '管理通路', + capabilityManageChannelsHint: '允許管理智慧代理的內嵌通路、IM 通路和微信掃碼綁定流程。', + capabilityManageVectorStores: '管理檢索基礎設施', + capabilityManageVectorStoresHint: '允許管理向量庫設定,以及解析器、文件讀取器和存儲引擎連通性檢查。', + capabilityManageStorageBackends: '管理存儲後端', + capabilityManageStorageBackendsHint: '允許管理物件/檔案存儲後端實例(如 S3 相容或本地檔案存儲)的增刪改查、連通性測試及空間預設存儲設定。', + capabilityManageWebSearch: '管理聯網搜尋', + capabilityManageWebSearchHint: '允許管理聯網搜尋供應商設定、憑據和連結測試。', + capabilityRunEvaluations: '運行評測', + capabilityRunEvaluationsHint: '允許運行評測任務並讀取評測結果。', + capabilityManageMembers: '管理成員', + capabilityManageMembersHint: '允許查看和管理空間成員、角色、邀請和邀請連結;不包含 API Key 管理、空間刪除或所有權轉移。', + capabilityManageSpaces: '管理空間', + capabilityManageSpacesHint: '允許管理組織空間、加入流程、空間成員、邀請和共享空間可見性;不授予知識庫或智慧代理分享管理權限。', + capabilityManageTenantSettings: '管理空間設定', + capabilityManageTenantSettingsHint: '允許讀取和更新空間級集成設定,例如 API 終端使用者身份模式、請求頭設定、空間 KV 設定等;不包含 API Key 管理、成員管理、空間刪除或所有權轉移。', + apiKeyKnowledgeScope: '知識庫範圍', + apiKeyKnowledgeScopePlaceholder: '留空表示允許存取全部知識庫', + allKnowledgeBases: '全部知識庫', + editApiKeyScope: '編輯 API Key', + editApiKeyScopeDesc: '修改 API Key「{name}」的名稱和授權範圍。', + editApiKeyScopeHint: '留空表示允許存取本空間的全部知識庫。所有修改儲存後立即生效。', + updateApiKeyScopeSuccess: 'API Key 已更新', + updateApiKeyScopeFailed: '更新 API Key 失敗', + createdAt: '建立時間', + actions: '操作', + deleteApiKey: '刪除', + deleteApiKeyConfirm: '刪除後該 API Key 會立即失效,已部署的集成將無法繼續使用它。', + deleteApiKeySuccess: 'API Key 已刪除', + deleteApiKeyFailed: '刪除 API Key 失敗', + createApiKeyFailed: '建立 API Key 失敗', + loadApiKeysFailed: '載入 API Key 清單失敗', + apiKeyCreated: 'API Key 已建立', + principalMode: '使用者身份模式', + principalModeDesc: '設定 API 請求如何識別終端使用者。該身份會同時用於區分不同使用者的對話 Session 與 MCP 工具授權。', + principalScope: '終端使用者身份負責隔離 Session 與 MCP OAuth;API Key 自身的操作權限和知識庫範圍由上方 API Keys 管理。', + modeTenant: '僅空間', + modeDirect: '直接傳使用者 ID', + modeSigned: '簽章 Token', + directWarning: '直接傳使用者 ID 會信任呼叫方請求頭,僅適用於可信伺服器端到伺服器端呼叫。', + directWarningDetail: '任何持有 API Key 的呼叫方都可以透過修改使用者 ID 請求頭冒充其他外部使用者,從而共用或劫持其 MCP OAuth 授權。請勿用於瀏覽器或不可信用戶端;面向終端使用者請使用「簽章 Token」。', + signedRecommended: '推薦給面向使用者的應用:由你的業務後端為外部使用者籤發短期 HS256 JWT。', + signedFlowDetail: 'HMAC 金鑰僅儲存在 WeKnora 與你的可信後端,切勿放入請求或下發給瀏覽器。請求頭裡傳的是用該金鑰籤出的 JWT 字符串(每次籤發或過期後會變),不是金鑰本身。JWT 須包含 sub(外部使用者 ID)、tenant_id、aud=weknora、exp(有效期不超過 24 小時)。', + directHeader: '使用者 ID 請求頭', + requireDirectHeader: '必須攜帶使用者 ID', + requireDirectHeaderDesc: '開啟後,缺少使用者 ID 請求頭的 API Key 請求將被拒絕;關閉則按整個空間統一處理,不區分具體終端使用者。', + tokenHeader: 'Token 請求頭', + tokenHeaderDesc: '用戶端在該固定請求頭中攜帶後端籤發的 JWT。', + hmacSecret: 'HMAC 金鑰', + hmacSecretDesc: '與 WeKnora 儲存的同一份金鑰;僅用於後端籤發 JWT,不要作為請求頭髮送。', + secretConfigured: '已設定金鑰(不可回看);輸入新值可輪換', + secretSavedCopyHint: '金鑰已儲存,請立即複製到後端設定。離開本頁後將無法再次查看。', + generateSecret: '生成金鑰', + hmacSecretResetConfirmTitle: '確認重設 HMAC 金鑰?', + hmacSecretResetConfirmBody: '重設後,舊的 HMAC 金鑰會立即失效,所有使用舊金鑰籤發 JWT 的後端服務必須更換為新金鑰才可繼續透過簽章 Token 呼叫。此操作不可復原。', + hmacSecretResetConfirmOk: '確認重設', + hmacSecretResetConfirmCancel: '取消', + tokenSignExample: '後端籤發 JWT 示例(Go)', + signedRequestStep0: '# 0. 在你的後端籤發 JWT(HS256,aud=weknora,sub=使用者 ID,tenant_id={tenantId},exp 不超過 24 小時)', + signedRequestStep0Hint: '# 將 JWT 放入 {headerName} 請求頭,不要傳 HMAC 金鑰', + requestExampleCreateSession: '# 1. 建立會話', + requestExampleAgentChat: '# 2. Agent 對話(SSE;將 取代為第 1 步返回的 id)', + requestExampleJwtPlaceholder: '<後端籤發的 JWT>', + requestExample: '請求示例', + playgroundTitle: 'API Playground', + playgroundDesc: '用當前 API Key 和身份模式發起真實請求,驗證會話建立、智慧代理對話和 SSE 返回。', + playgroundOpen: '打開 Playground', + playgroundDrawerDesc: '按真實 API 集成方式偵錯 Session、Agent Chat 和 SSE 返回', + playgroundSectionRequest: '請求設定', + playgroundSectionPreview: '請求預覽', + playgroundSectionResult: '運行結果', + playgroundAgent: '測試智慧代理', + playgroundAgentPlaceholder: '選擇要測試的智慧代理', + playgroundBuiltin: '內建', + playgroundAgentsLoadFailed: '智慧代理清單載入失敗', + playgroundExternalUser: '外部使用者 ID', + playgroundExternalUserPlaceholder: 'user_123', + playgroundTenantModeHint: '僅空間模式不會傳送外部使用者身份,所有 API 會話歸屬同一個空間級主體。', + playgroundDirectModeHint: '將透過 {headerName} 請求頭髮送此使用者 ID。', + playgroundSignedModeHint: '簽章模式由 JWT 的 sub 代表外部使用者;Playground 會用這裡的使用者 ID 自動籤出短期測試 JWT。', + playgroundQuestion: '測試問題', + playgroundQuestionPlaceholder: '輸入要傳送給智慧代理的問題', + playgroundRequestPreview: '請求預覽(已遮蔽金鑰)', + playgroundRun: '運行測試', + playgroundStop: '停止', + playgroundNeedApiKey: '當前空間沒有 API Key。', + playgroundNeedAgent: '請選擇測試智慧代理。', + playgroundNeedQuestion: '請輸入測試問題。', + playgroundNeedExternalUser: '請輸入外部使用者 ID。', + playgroundMintTokenFailed: '生成短期測試 JWT 失敗。', + playgroundMissingSessionId: '建立會話成功,但回應中沒有 session id。', + playgroundNoStream: '對話介面沒有返回可讀取的 SSE 流。', + playgroundGeneratedToken: '本次生成的測試 Token', + playgroundStepSession: '步驟 1:建立 Session', + playgroundStepChat: '步驟 2:Agent Chat SSE', + playgroundFinalAnswer: '提取出的回答', + playgroundEmptyResult: '運行後將在這裡顯示 Session 回應、SSE 原始輸出和提取出的回答。', + playgroundSuccess: '測試完成({ms}ms)', + playgroundStopped: '測試已停止', + playgroundFailed: 'API Playground 測試失敗', + loadFailed: '載入 API 集成設定失敗', + saveFailed: '儲存 API 集成設定失敗', + saveSuccess: 'API 集成設定已儲存', + autoSaveNeedSecret: '簽章 Token 模式需要填寫 HMAC 金鑰後才能自動儲存。' + }, + mcpserver: { + title: 'MCP Server', + subtitle: '把當前空間發布為 MCP 服務,供 Claude Desktop、Cursor、Claude Code 等 MCP 用戶端直接連結。每個端點有獨立的權杖、知識庫範圍和工具清單。', + listTitle: '已發布的端點', + empty: '暫無 MCP 端點', + disabled: '已停用', + cardSummary: '{tools} 個工具 · {scope}', + scopeAll: '全部知識庫', + scopeCount: '{count} 個知識庫', + create: '新建端點', + editTitle: '編輯 MCP 端點', + createTitle: '新建 MCP 端點', + drawerDesc: '端點決定外部用戶端能看到哪些知識庫、能呼叫哪些工具。權杖只在建立和輪換時展示一次。', + sectionBasic: '基本資訊', + nameLabel: '名稱', + namePlaceholder: '例如:產品文件助手', + descriptionLabel: '說明', + descriptionPlaceholder: '可選,說明這個端點給誰用、用於什麼情境', + enabledLabel: '啟用端點', + sectionScope: '知識庫範圍', + kbScopeLabel: '可存取的知識庫', + kbScopePlaceholder: '留空表示空間內全部知識庫', + kbScopeHint: '所有檢索、問答和寫入工具都只在這些知識庫內生效。留空時端點可存取空間內的全部知識庫。', + sectionTools: '暴露的工具', + toolsHint: '只有勾選的工具會出現在用戶端的工具清單中,未勾選的工具即使按名字呼叫也會被拒絕。寫入類工具預設關閉。', + clearGroup: '取消全選', + selectGroup: '全選', + toolsRequired: '至少勾選一個工具', + groups: { + retrieve: '檢索與閱讀', + chat: '問答', + wiki: 'Wiki', + ingest: '寫入(謹慎開啟)', + }, + tools: { + list_knowledge_bases: '列出知識庫', + list_knowledge_basesDesc: '返回端點範圍內的知識庫及其支持的檢索方式', + search_knowledge: '語義搜尋', + search_knowledgeDesc: '按自然語言問題在知識庫中檢索相關片段並附來源', + grep_chunks: '關鍵字/正則搜尋', + grep_chunksDesc: '對原始切塊做大小寫不敏感的正則比對,適合精確詞、編號、程式碼', + list_documents: '列出文件', + list_documentsDesc: '分頁列出某個知識庫下的文件', + read_document: '閱讀文件', + read_documentDesc: '按順序讀取文件的元資訊和切塊內容', + ask: '問答', + askDesc: '運行端點設定的預設 Agent,返回帶引用的完整回答,支持多輪續聊', + wiki_search: '搜尋 Wiki', + wiki_searchDesc: '在知識庫生成的 Wiki 頁面中搜尋', + wiki_read_page: '讀取 Wiki 頁面', + wiki_read_pageDesc: '按 slug 讀取一篇 Wiki 頁面', + wiki_index: '瀏覽 Wiki 目錄', + wiki_indexDesc: '查看某個知識庫 Wiki 的目錄結構', + add_document: '新增文件', + add_documentDesc: '用 Markdown 文字或 URL 向知識庫新增文件', + update_document: '更新文件', + update_documentDesc: '取代 Markdown 文件的內容或標題', + delete_document: '刪除文件', + delete_documentDesc: '永久刪除文件及其索引資料', + }, + sectionAsk: '問答設定', + defaultAgentLabel: '預設 Agent', + defaultAgentPlaceholder: '未選擇時使用內建快速問答', + defaultAgentHint: '呼叫 ask 工具時使用的 Agent;用戶端無法自行指定 Agent。留空時使用內建快速問答。', + sectionLimits: '限流', + rateLimitLabel: '每分鐘最多呼叫次數', + rateLimitHint: '對該端點所有工具呼叫的總限制,超出後用戶端會收到限流提示。', + sectionConnect: '連結資訊', + stepConfig: '設定', + stepConnect: '連結', + snippetsLabel: '用戶端設定', + connectHintExisting: '權杖只在建立時展示(當前權杖前綴 {hint}…)。如需重新獲取,請輪換權杖。', + tokenDialogTitle: '端點已就緒,請儲存權杖', + connectDialogTitle: '連結此端點', + tokenOnce: '權杖只展示這一次,關閉後無法再次查看。請立即複製並妥善儲存。', + connectPlaceholderHint: '出於安全考慮不會再次展示權杖,下面的示例用預留位置代替,請取代為你儲存的權杖。', + tokenLabel: '權杖', + urlLabel: '端點地址', + snippet: { + httpTitle: 'Cursor / VS Code / Claude Desktop', + httpDesc: '支持 Streamable HTTP 的用戶端直接寫入 mcpServers 設定。', + claudeCodeTitle: 'Claude Code', + claudeCodeDesc: '在終端執行一條命令即可新增。', + stdioTitle: '僅支持 stdio 的用戶端', + stdioDesc: '透過 mcp-remote 橋接,需要本地安裝 Node.js。', + }, + loadFailed: '載入 MCP 端點失敗', + nameRequired: '請填寫名稱', + updated: '端點已更新', + created: '端點已建立', + saveFailed: '儲存失敗', + deleted: '端點已刪除', + deleteFailed: '刪除失敗', + rotated: '權杖已輪換,舊權杖立即失效', + rotateFailed: '輪換權杖失敗', + disabledToast: '端點已停用', + enabledToast: '端點已啟用', + menuConnect: '連結資訊', + menuDisable: '停用', + menuEnable: '啟用', + menuRotate: '輪換權杖', + copied: '已複製', + deleteConfirm: '刪除後使用該端點的用戶端會立即斷開,確定刪除?', + }, + tabs: { + im: 'IM 集成', + embed: '網頁內嵌', + api: 'API 集成', + chrome: 'Chrome 外掛', + cli: 'CLI', + claw: 'Claw Skill', + mcpserver: 'MCP Server' + } + }, + datasource: { + title: '資料源管理', + description: '設定外部資料源,自動同步內容到知識庫', + add: '新增資料源', + empty: '暫無資料源', + edit: '編輯', + delete: '刪除', + deleteConfirm: '確定刪除該資料源?同步的知識不會被刪除。', + deleteSuccess: '資料源已刪除', + deleteFailed: '刪除失敗', + syncNow: '立即同步', + syncTriggered: '同步任務已提交', + syncFailed: '同步觸發失敗', + pause: '暫停', + resume: '復原', + paused: '已暫停', + resumed: '已復原', + pauseFailed: '暫停失敗', + logs: '日誌', + syncModeLabel: '同步模式', + createTitle: '新增資料源', + editTitle: '編輯資料源', + nameLabel: '名稱', + namePlaceholder: '輸入資料源名稱', + sectionBasic: '基本資訊', + testConnection: '測試連結', + testSuccess: '連結成功', + testFailed: '連結失敗', + connected: '已連結', + connectionFailed: '連結失敗', + isRequired: '為必填項', + credentialsLabel: '憑證', + gitlab: { + baseUrl: 'GitLab 地址', + accessToken: '個人存取權杖', + projects: 'GitLab 專案', + projectsHint: '填寫專案 ID 或命名空間路徑(如 group/project),可選指定分支和目錄。', + project: '專案', projectId: '專案 ID', projectIdPlaceholder: '例如:12345 或 group/project', + ref: '分支', refPlaceholder: '留空時使用預設分支', + paths: '同步目錄', pathsPlaceholder: '每行一個目錄;留空同步整個專案', + addProject: '新增專案', projectRequired: '請至少新增一個 GitLab 專案', + }, + resourceHint: '選擇要同步的內容空間/資料夾', + untitled: '無標題', + resourceLoadFailed: '載入資源清單失敗', + noResources: '未找到可同步的知識庫空間', + noResourcesDesc: '應用需要透過群聊獲得知識庫存取權限才能拉取內容', + noResourcesDesc_notion: '應用需要獲得 Notion 頁面的存取權限才能拉取內容', + retryLoadResources: '重新載入', + guideStep1: '在飛書中建立一個群聊,在群設定「群機器人」中新增你的應用', + guideStep2: '打開知識庫「設定」→「成員設定」→ 新增成員,搜尋該群聊名稱並新增', + guideStep3: '確保群聊角色至少為「可閱讀」,然後回到這裡點重新載入', + guideStep1_notion: '在 Notion 中打開你想要同步的頁面或資料庫', + guideStep2_notion: '點擊右上角的「···」選單,選擇「Connect to」或「Add connections」', + guideStep3_notion: '搜尋並選擇你的集成應用(Integration),然後回到這裡點重新載入', + permissionDocLink: '查看飛書知識庫權限設定文件', + syncScheduleLabel: '同步頻率', + conflictLabel: '衝突策略', + syncDeletions: '同步刪除(源端刪除時同步刪除知識庫中的條目)', + createAndSync: '建立並立即同步', + createAndSyncSuccess: '資料源建立成功,同步任務已提交', + createButSyncFailed: '資料源已建立,但觸發同步失敗', + updateSuccessSyncHint: '資料源更新成功;編輯不會自動觸發同步,如需重新匯入請點擊「同步」。', + saveFailed: '儲存失敗', + syncHistory: '同步歷史', + refreshLogs: '重新整理日誌', + noLogs: '暫無同步記錄', + comingSoon: '即將支持', + docHint: '在以下地址獲取憑證:', + openDoc: '打開文件', + prereqBarText: '首次使用?點擊查看飛書應用設定指引', + prereqBarText_yuque: '首次使用?點擊查看語雀 Token 設定指引', + prereqStep1Brief_yuque: '建立語雀個人 Token', + prereqStep1Desc_yuque: '登入語雀 → 個人頭像 → 設定 → Token → 新建 Token', + prereqStep2Brief_yuque: '為 Token 勾選所需權限', + prereqStep2Desc_yuque: '至少勾選 repo:read 和 doc:read(讀取知識庫和文件內容)', + prereqStep3Brief_yuque: '(可選)企業版填寫 Base URL', + prereqStep3Desc_yuque: '公有雲使用者無需填寫;語雀企業版或私有部署請填寫企業域名', + prereqOpenConsole_yuque: '前往語雀 Token 設定', + yuqueFolderModeLabel: '目錄結構', + yuqueFolderModeToc: '按語雀目錄分層', + yuqueFolderModeNone: '平鋪在根目錄', + yuqueFolderModeHint: '按語雀的目錄層級放置文件。注意:之後在知識庫裡手動調整的目錄,會在該文件下次同步時被覆蓋回語雀的結構。', + yuqueTOCOnly: '只同步語雀目錄中可見的文件', + yuqueTOCOnlyHint: '需要先選擇「按語雀目錄分層」。已經同步進知識庫的文件不受影響──語雀中不在目錄裡的文件只是不再新增,不會被刪除。', + prereqBarText_dingtalk: '首次使用?點擊查看釘釘應用設定指引', + prereqStep1Brief_dingtalk: '建立企業內部應用', + prereqStep1Desc_dingtalk: '在釘釘開放平台建立企業內部應用,並獲取 Client ID 和 Client Secret', + prereqStep2Brief_dingtalk: '開通知識庫讀取權限', + prereqStep2Desc_dingtalk: '開通 Wiki.Workspace.Read、Wiki.Node.Read 和 Storage.File.Read', + prereqStep3Brief_dingtalk: '填寫操作人 Union ID', + prereqStep3Desc_dingtalk: '填寫有權存取目標知識庫的釘釘使用者 Union ID', + prereqOpenConsole_dingtalk: '前往釘釘開放平台設定', + prereqBarText_ima: '首次使用?點擊查看騰訊 IMA OpenAPI 授權指引', + prereqStep1Brief_ima: '開通 IMA 智慧代理接入', + prereqStep1Desc_ima: '登入 https://ima.qq.com/agent-interface 並申請 OpenAPI 接入', + prereqStep2Brief_ima: '獲取 ClientID 與 APIKey', + prereqStep2Desc_ima: '在智慧代理接入頁複製 ima-openapi-clientid 與 ima-openapi-apikey 兩個憑證', + prereqStep3Brief_ima: '授權目標知識庫', + prereqStep3Desc_ima: '在 IMA 用戶端為該憑證授權需要同步的知識庫,未授權的知識庫不會出現在清單中', + prereqOpenConsole_ima: '前往 IMA OpenAPI 控制台', + prereqStep1Brief_feishu: "建立飛書自建應用", + prereqStep1Desc_feishu: "登入飛書開放平台 → 建立企業自建應用", + prereqStep2Brief_feishu: "新增機器人能力", + prereqStep2Desc_feishu: "開放平台 → 你的應用 → 新增應用能力 → 機器人", + prereqStep3Brief_feishu: "設定應用權限", + prereqStep3Desc_feishu: "為應用開通 wiki:wiki:readonly, drive:drive:readonly, drive:export:readonly, docx:document:readonly 權限", + prereqStep1Brief_lark: "建立 Lark 自建應用", + prereqStep1Desc_lark: "登入 Lark 開放平台 → 建立企業自建應用", + prereqStep2Brief_lark: "新增機器人能力", + prereqStep2Desc_lark: "開放平台 → 你的應用 → 新增應用能力 → 機器人", + prereqStep3Brief_lark: "設定應用權限", + prereqStep3Desc_lark: "為應用開通 wiki:wiki:readonly, drive:drive:readonly, drive:export:readonly, docx:document:readonly 權限", + prereqStep1Brief_feishu_drive: "建立飛書自建應用", + prereqStep1Desc_feishu_drive: "登入飛書開放平台 → 建立企業自建應用", + prereqStep2Brief_feishu_drive: "新增機器人能力", + prereqStep2Desc_feishu_drive: "開放平台 → 你的應用 → 新增應用能力 → 機器人", + prereqStep3Brief_feishu_drive: "設定應用權限", + prereqStep3Desc_feishu_drive: "為應用開通 drive:drive:readonly, drive:export:readonly, docx:document:readonly 權限", + prereqStep1Brief_lark_drive: "建立 Lark 自建應用", + prereqStep1Desc_lark_drive: "登入 Lark 開放平台 → 建立企業自建應用", + prereqStep2Brief_lark_drive: "新增機器人能力", + prereqStep2Desc_lark_drive: "開放平台 → 你的應用 → 新增應用能力 → 機器人", + prereqStep3Brief_lark_drive: "設定應用權限", + prereqStep3Desc_lark_drive: "為應用開通 drive:drive:readonly, drive:export:readonly, docx:document:readonly 權限", + prereqBotBrief: '為應用新增「機器人」能力', + prereqBotDesc: '開放平台 → 新增應用能力 → 機器人 → 建立版本併發布', + prereqPermBrief: '開通 API 權限', + prereqOpenConsole: '前往飛書開放平台設定', + prereqMemberBrief: '透過群聊新增為知識庫成員', + prereqMemberDesc: '建立群聊 → 新增應用為群機器人 → 將群聊新增為知識庫成員', + back: '上一步', + next: '下一步', + save: '儲存', + schedule30min: '每 30 分鐘', + schedule1h: '每小時', + schedule6h: '每 6 小時', + schedule12h: '每 12 小時', + schedule24h: '每天', + neverSynced: '未同步', + justNow: '剛剛', + minutesAgo: '{n} 分鐘前', + hoursAgo: '{n} 小時前', + daysAgo: '{n} 天前', + resourceType: { + wikiSpace: '知識庫空間', + docCategory: '文件標籤', + book: '語雀知識庫' + }, + scheduleHuman: { + '30min': '每 30 分鐘', + '1h': '每小時', + '6h': '每 6 小時', + '12h': '每 12 小時', + '24h': '每天' + }, + field: { + appId: 'App ID', + appSecret: 'App Secret', + integrationToken: 'Integration Token', + apiToken: 'API Token', + confluenceEdition: 'Confluence 版本', + confluenceEditionServer: 'Server / Data Center', + confluenceEditionCloud: 'Cloud', + confluenceBaseUrl: 'Confluence 地址', + confluenceUsername: '使用者名或電子信箱', + confluencePassword: 'Server/DC 密碼', + confluenceApiToken: 'Cloud API 權杖', + clientId: 'Client ID', + clientSecret: 'Client Secret', + operatorId: '操作人 Union ID', + operatorIdHint: '用於按該使用者的權限讀取知識庫,可透過釘釘「查詢使用者詳情」介面獲取', + imaClientId: 'IMA ClientID', + imaApiKey: 'IMA APIKey', + baseUrl: 'Base URL(可選)', + baseUrlHint: '留空將使用預設公有雲地址;如果是私有部署/企業內網部署,或需要透過反向代理存取,請填寫自定義地址(例如 https://api-proxy.example.com)', + feedUrls: '訂閱源地址', + feedUrlsHint: '每行一個 RSS / Atom 訂閱源地址,支持同時填寫多個', + authHeaders: '自定義請求頭(可選)', + authHeadersHint: '用於存取私有訂閱源,每行一個,格式為「名稱: 值」,例如 Authorization: Bearer xxxx' + }, + confluence: { + cloudFolderLimitation: 'Confluence Cloud 暫不支持在此列出空間頂層資料夾等容器下的頁面;選擇整個空間仍會同步它們。' + }, + connectorDesc: { + feishu: '同步飛書知識庫中的文件、表格、檔案', + lark: '同步 Lark 知識庫中的文件、表格、檔案(飛書國際版)', + feishu_drive: "同步飛書雲盤資料夾中的文件、表格、檔案", + lark_drive: "同步 Lark 雲盤資料夾中的文件、表格、檔案(飛書國際版)", + notion: '同步 Notion 中的頁面和資料庫', + confluence: '將 Confluence 空間和頁面同步為 Markdown', + yuque: '同步語雀知識庫中的文件', + dingtalk: '同步釘釘知識庫中的線上文件', + ima: '同步騰訊 IMA 知識庫中的文件、筆記與檔案(暫不支持 AI 會話與影片解析)', + rss: '同步 RSS / Atom 訂閱源中的文章', + gitlab: '同步 GitLab 專案中的檔案' + }, + connector: { + feishu: '飛書', + lark: 'Lark(飛書國際版)', + feishu_drive: "飛書雲盤", + lark_drive: "Lark 雲盤", + notion: 'Notion', + confluence: 'Confluence', + yuque: '語雀', + dingtalk: '釘釘文件', + ima: '騰訊 IMA', + rss: 'RSS / Atom 訂閱', + gitlab: 'GitLab' + }, + logDetail: { + startTime: '開始時間', + endTime: '結束時間', + failedItems: '失敗文件', + failedItemsMore: '還有 {n} 個失敗文件未顯示', + docsFailedSummary: '{n} 個文件同步失敗' + }, + logSummary: { + total: '總次數', + success: '成功', + failed: '失敗', + items: '同步條目' + }, + logMetric: { + total: '總計', + skipped: '跳過', + failed: '失敗' + }, + logStatus: { + running: '同步中', + success: '成功', + partial: '部分成功', + failed: '失敗', + canceled: '已取消' + }, + step: { + selectType: '選擇類型', + credentials: '設定憑證', + resources: '選擇範圍', + strategy: '同步策略' + }, + conflict: { + overwrite: '覆蓋更新', + skip: '跳過已存在' + }, + status: { + active: '已連結', + paused: '已暫停', + error: '例外' + }, + syncMode: { + incremental: '增量同步', + full: '全量同步' + }, + drive: { + folderTokenLabel: "雲盤資料夾 Token", + folderTokenPlaceholder: "輸入 folder_token 或飛書雲盤資料夾連結", + folderTokenRequired: "請輸入具體資料夾的 folder_token,不支持雲空間根目錄", + rootNotSupportedHint: "根目錄不分頁且不返回捷徑,請選擇具體資料夾", + load: "載入", + shareHint: "需先將該雲盤資料夾分享給應用所在的群,應用才能存取", + placeholderTitle: "請先載入雲盤資料夾", + placeholderDesc: "在上方輸入 folder_token(或從飛書雲盤資料夾 URL 複製)並點擊「載入」", + loadForbiddenHint: "應用無權存取該資料夾。請在飛書雲盤中將該資料夾分享給應用所在的群後再試。", + loadAuthHint: "應用憑證無效或缺少雲盤權限,請檢查 App ID / App Secret 及 drive:drive:readonly 等權限。", + loadNotFoundHint: "folder_token 不存在或已刪除,請確認從飛書雲盤資料夾 URL 複製的 token 正確。", + }, + syncError: { + dingtalk_document_failed: '無法讀取釘釘文件,請檢查存取權限後重試同步。', + dingtalk_resource_failed: '釘釘資源不可用,請檢查存取權限和已選資源後重試。', + deletion_lookup_failed: '刪除前尋找文件失敗,請查看伺服器日誌', + deletion_failed: '刪除失敗,請查看伺服器日誌', + ingest_failed: '匯入失敗,請查看伺服器日誌' + }, + }, + ollama: { + unknown: '未知', + today: '今天', + yesterday: '昨天', + daysAgo: '{days} 天前' + }, + mermaid: { + diagram: '圖表', + expand: '全螢幕查看', + zoomIn: '放大', + zoomOut: '縮小', + reset: '重設', + download: '下載圖片', + close: '關閉', + downloading: '下載中...' + }, + faqManager: { + import: { + recentResult: '最近匯入結果', + totalData: '匯入資料', + success: '成功', + added: '新增', + merged: '合併更新', + partialFailed: '部分失敗', + failed: '失敗', + skipped: '跳過', + progressHint: '正在驗證並匯入 FAQ 資料...', + downloadReasons: '下載原因', + appendMode: '追加模式', + replaceMode: '取代模式', + importing: '匯入中...', + importDone: '匯入完成', + importFailed: '匯入失敗', + waiting: '等待中...', + importInProgress: '匯入正在進行中,請等待完成後再試', + noFailedRecords: '暫無失敗記錄可下載' + } + }, + agentEditor: { + builtinHint: '這是內建智慧代理,名稱和描述不可修改,但可以調整設定參數', + fileTypes: { + label: '支持的檔案類型', + desc: '限制可選擇的檔案類型,留空表示支持所有類型', + allTypes: '全部類型', + pdf: 'PDF 文件', + word: 'Word 文件 (.docx/.doc)', + textLabel: '文字', + text: '純文字檔案 (.txt)', + markdown: 'Markdown 文件', + csv: '逗號分隔值檔案', + excel: 'Excel 表格 (.xlsx/.xls)', + imageLabel: '圖片', + image: '圖片檔案 (.jpg/.jpeg/.png)' + }, + fallback: { + fixed: '固定回覆', + model: '模型生成' + }, + dataAnalysis: { + enableLabel: '啟用表格資料分析', + enableDesc: '命中 CSV/Excel 類檔案時,先呼叫大型語言模型生成 DuckDB SQL 進行統計或篩選,再據此回答。會額外增加一次模型呼叫與幾秒延遲,僅在確實需要時開啟。' + }, + faq: { + title: 'FAQ 優先策略', + enableLabel: '啟用 FAQ 優先', + enableDesc: 'FAQ 答案將優先於普通文件被引用,提高回答準確性', + thresholdLabel: '直接回答閾值', + thresholdDesc: '當問題與 FAQ 相似度超過此值時,直接使用 FAQ 答案', + boostLabel: 'FAQ 分數加權', + boostDesc: 'FAQ 結果的相關性分數乘以此係數,使其排序更靠前' + }, + chatParser: { + label: '聊天附件解析策略', + desc: '為不同檔案類型指定解析引擎,僅對當前智慧代理的聊天附件生效', + waitTimeoutLabel: '附件解析等待超時(秒)', + waitTimeoutDesc: '單輪問答等待附件解析完成的最長時間,超時後未完成的附件會被跳過。大檔案 / 掃描件可調大。0 表示使用全局預設。' + }, + audioUpload: { + label: '語音上傳', + desc: '啟用後使用者可在對話中上傳音訊檔案,系統將使用 ASR 模型自動轉錄為文字', + asrModel: 'ASR 模型', + asrModelDesc: '用於音訊轉錄的語音辨識模型,未設定時音訊檔案將以預留位置形式傳遞', + asrModelPlaceholder: '請選擇 ASR 模型' + }, + imageUpload: { + navLabel: '附件上傳', + sectionTitle: '附件上傳', + sectionDesc: '設定對話中圖片、文件、音訊等附件的上傳、解析及對應模型', + label: '圖片上傳', + desc: '啟用後使用者可在對話中上傳圖片並由 VLM 理解', + vlmModel: 'VLM 模型', + vlmModelDesc: '用於圖片分析的視覺語言模型', + vlmModelPlaceholder: '請選擇 VLM 模型', + vlmModelRequired: '啟用圖片上傳時必須選擇 VLM 模型', + imageUnderstandingLabel: '附件圖片理解 / 掃描件 OCR', + imageUnderstandingDesc: '對圖片型 PDF/PPT 等掃描件,當解析不出文字時用 VLM 進行 OCR 識別。開啟會增加解析耗時,預設關閉。', + ocrMaxPagesLabel: '掃描件 OCR 最大頁數', + ocrMaxPagesDesc: '掃描件送入 VLM 做 OCR 的最大頁數,越多覆蓋越全但越慢、越貴。0 表示使用全局預設。', + useGlobalDefault: '0 = 全局預設', + storageProvider: '圖片存儲', + storageProviderDesc: '選擇圖片檔案的存儲引擎,留空則使用系統預設', + storageProviderPlaceholder: '選擇存儲引擎', + storageDefault: '系統預設', + notConfigured: '未設定', + goStorageSettings: '去存儲設定中設定' + }, + llmCallTimeout: { + label: 'LLM 呼叫超時', + desc: '單次 LLM 呼叫的最大等待時間(秒),超過此時間後呼叫將被中止', + hint: '留空或填 0 表示使用預設值(120 秒)', + placeholder: '輸入秒數,建議範圍 60-1800' + }, + mcp: { + label: 'MCP 服務', + desc: '選擇 Agent 可以呼叫的 MCP 服務', + selectLabel: '選擇 MCP 服務', + selectDesc: '選擇要啟用的 MCP 服務', + selectPlaceholder: '選擇 MCP 服務', + authWaitTimeout: '授權等待超時(秒)', + authWaitTimeoutDesc: '對話中觸發 OAuth 授權時,等待你完成授權的最長秒數,超時後自動跳過授權提示(僅對使用 OAuth 的 MCP 服務生效)。', + authWaitTimeoutPlaceholder: '預設 600 秒', + unavailableService: '不可用服務' + }, + agentType: { + label: '智慧代理類型', + desc: '選擇一個預設會自動填充系統提示語、工具清單和推薦的知識庫範圍。', + defaultNamePattern: '我的{label}', + kbIncompatibleWarn: '已選的 {count} 個知識庫不適用於當前類型,請手動調整', + kbMismatch: { + ragQa: '未啟用 RAG 檢索', + wikiQa: '未啟用 Wiki', + hybridRagWiki: '未啟用任何檢索能力', + dataAnalysis: '需啟用 RAG(不支持 FAQ)', + quickAnswer: '快速問答模式需啟用 RAG 檢索', + generic: '不適用於當前類型' + } + }, + im: { + title: 'IM 集成', + description: '將智慧代理接入即時通訊平台,支持企業微信、飛書、Slack、Telegram、釘釘、Mattermost、微信、QQBot 和雲之家', + feishu: '飛書', + lark: 'Lark(飛書國際版)', + slack: 'Slack', + telegram: 'Telegram', + dingtalk: '釘釘', + mattermost: 'Mattermost', + wecom: '企業微信', + wechat: '微信', + qqbot: 'QQBot', + yunzhijia: '雲之家', + addChannel: '新增通路', + channelsTitle: 'IM 通路', + disabled: '已停用', + editChannel: '編輯通路', + deleteConfirm: '確定刪除該通路?刪除後無法復原。', + channelName: '通路名稱', + channelNamePlaceholder: '輸入通路名稱,方便辨識', + channelNameDefaultHint: '預設為平台名稱,可自行修改;留空儲存時也會使用平台名稱', + platform: '平台', + mode: '接入模式', + outputMode: '輸出模式', + outputStream: '流式輸出', + outputFull: '完整輸出', + callbackUrl: '回呼地址', + empty: '暫無 IM 通路', + unnamed: '未命名通路', + docLink: '查看接入文件', + wecomConsole: '企業微信管理後台', + feishuConsole: '飛書開放平台', + larkConsole: 'Lark 開放平台', + slackConsole: 'Slack API 控制台', + telegramConsole: 'Telegram BotFather', + dingtalkConsole: '釘釘開放平台', + dingtalkCardTemplateId: '卡片模板 ID(可選)', + dingtalkCardTemplateIdHint: '在 open-dev.dingtalk.com/fe/card 建立 AI 卡片模板,啟用後支持打字機效果的流式輸出', + mattermostConsole: 'Mattermost 集成說明', + qqbotConsole: 'QQ 開放平台', + qqbotAPIBaseURLHint: '可選,留空則使用預設正式環境 API 地址。', + qqbotGatewayURLHint: '可選,留空則自動獲取通用 WebSocket 接入點。', + yunzhijiaConsole: '雲之家開放平台', + yunzhijiaRobotDoc: '機器人訊息文件', + yunzhijiaImageDoc: '開發者平台(圖片功能)', + yunzhijiaModeHint: '支持 Webhook 和 WebSocket;WebSocket 模式無需設定公網回呼地址。', + yunzhijiaSendMsgUrl: '傳送訊息地址', + yunzhijiaSendMsgUrlHint: '用於機器人回覆訊息。', + yunzhijiaSecret: '簽章金鑰(可選)', + yunzhijiaSecretPlaceholder: '雲之家機器人設定中的 HmacSHA1 簽章金鑰', + yunzhijiaSecretHint: '設定後,將對傳入的回呼請求進行 HmacSHA1 簽章驗證', + yunzhijiaAppId: '應用 App ID(圖片下載)', + yunzhijiaAppIdPlaceholder: '雲之家開放平台應用 App ID', + yunzhijiaAppSecret: '應用 App Secret(圖片下載)', + yunzhijiaAppSecretPlaceholder: '雲之家開放平台應用 Secret', + yunzhijiaAppCredentialHint: '用於獲取 appAccessToken 並下載使用者傳送的圖片檔案。', + yunzhijiaTimeout: 'HTTP 超時時間(秒)', + yunzhijiaTimeoutHint: '透過傳送訊息地址回覆的超時時間,預設 10 秒', + yunzhijiaAllowedHostSuffix: '允許的主機後綴', + yunzhijiaAllowedHostSuffixHint: '限制傳送訊息地址的目標域名後綴,提升安全性(如 yunzhijia.com)', + yunzhijiaSendMsgUrlRequired: '請填寫雲之家機器人設定中的傳送訊息地址', + mattermostModeHint: 'Mattermost 僅支持 Webhook(出站 Webhook + Bot Token)。', + mattermostPostToMain: '回覆顯示在頻道主時間軸', + mattermostPostToMainHint: '開啟後 Bot 回覆作為頻道內新帖子;關閉(預設)則作為原訊息的執行緒回覆,主視窗僅顯示「N 條回覆」。', + modeHint: '推薦使用 WebSocket 方式接入,設定更簡單', + consoleTip: '前往獲取憑證資訊', + wecomWSEndpointHint: '可選,私有化部署時填寫自定義 WebSocket 地址,留空則使用預設公有雲地址。內網地址需將域名加入 SSRF_WHITELIST 環境變數', + wecomAPIBaseURLHint: '可選,私有化部署時填寫自定義 API 地址,留空則使用預設公有雲地址。內網地址需將域名加入 SSRF_WHITELIST 環境變數', + feishuAPIBaseURLHint: '可選。若伺服器能直連外網則留空;若需透過代理才能存取飛書,填寫反向代理地址(如 nginx,http://host:port)。內網地址需將域名加入 SSRF_WHITELIST 環境變數', + fileKnowledgeBase: '檔案儲存知識庫', + fileKnowledgeBasePlaceholder: '選擇知識庫(可選)', + fileKnowledgeBaseHint: '設定後,使用者傳送的檔案將自動儲存到該知識庫中', + sessionMode: '會話模式', + sessionModeUser: '按使用者(預設)', + sessionModeThread: '按話題', + sessionModeHint: '使用者模式:每個使用者獨立對話,使用 /clear 開始新對話。話題模式:每個訊息話題獨立對話,同一話題中多人可協作。', + replyLanguage: '回覆語言', + replyLanguageDefault: '跟隨系統預設語言', + replyLanguageHint: '固定該通路的智慧代理回覆語言;留空時使用部署的預設語言。', + wechatScanBind: '掃碼綁定微信', + wechatScanning: '請使用微信掃描二維碼', + wechatBindSuccess: '微信綁定成功', + wechatRebind: '重新綁定', + wechatHint: '需要 iOS 微信 8.0.70+ 版本,僅支持單聊訊息', + wechatQRExpired: '二維碼已過期,請重新獲取', + wechatBinding: '綁定中...', + sectionChannel: '通路資訊', + sectionConnection: '連結設定', + sectionCredentials: '平台憑證', + selectPlatform: '選擇平台', + selectPlatformDesc: '選擇要接入的即時通訊平台', + enabled: '啟用通路', + stepBasic: '基本資訊', + stepConnection: '連結設定', + stepKnowledge: '檔案存儲', + stepCredentials: '平台憑證', + sectionAccess: '接入與輸出', + sectionSession: '會話設定', + sectionCallback: '回呼地址', + sectionKnowledge: '檔案存儲', + sectionStatus: '運行狀態' + }, + embed: { + title: '網頁內嵌', + description: '將智慧代理內嵌到您的網頁,訪客可透過頁面內聊天視窗或右下角浮窗發起對話,知識庫範圍跟隨本智慧代理設定。' + }, + tools: { + thinking: '思考', + thinkingDesc: '動態和反思性的問題解決思考工具', + todoWrite: '制定計劃', + todoWriteDesc: '建立結構化的研究計劃', + searchKnowledge: '檢索知識庫', + searchKnowledgeDesc: '語義、關鍵字或混合檢索知識庫切塊', + readDocument: '閱讀文件', + readDocumentDesc: '讀取文件元資料與切塊內容,支持分頁和文內尋找', + listDocuments: '瀏覽文件清單', + listDocumentsDesc: '分頁列出知識庫中的文件', + grepChunks: '關鍵字搜尋', + grepChunksDesc: '快速定位包含特定關鍵字的文件和切塊', + knowledgeSearch: '語義搜尋', + knowledgeSearchDesc: '理解問題並尋找語義相關內容', + listChunks: '查看文件切塊', + listChunksDesc: '獲取文件完整切塊內容', + queryGraph: '查詢知識圖譜', + queryGraphDesc: '從知識圖譜中查詢關係', + getDocInfo: '獲取文件資訊', + getDocInfoDesc: '查看文件元資料', + dbQuery: '查詢資料庫', + dbQueryDesc: '查詢資料庫中的資訊', + dataAnalysis: '資料分析', + dataAnalysisDesc: '理解資料檔案並進行資料分析', + dataSchema: '查看資料元資訊', + dataSchemaDesc: '獲取表格檔案的元資訊', + requiresKb: '(需要設定知識庫)', + requiresRagKb: '(需要關聯啟用向量/關鍵字索引的知識庫)', + requiresWikiKb: '(需要關聯啟用 Wiki 能力的知識庫)', + wikiSearch: '搜尋 Wiki', + wikiSearchDesc: '在 Wiki 知識庫中按關鍵字/語義搜尋頁面', + wikiReadPage: '閱讀 Wiki 頁面', + wikiReadPageDesc: '讀取指定 Wiki 頁面的完整內容', + wikiReadSourceDoc: '精讀源文件', + wikiReadSourceDocDesc: '透過知識點深入閱讀 Wiki 頁面背後的原始文件', + wikiFlagIssue: '標記 Wiki 問題', + wikiFlagIssueDesc: '標記頁面中存在的事實錯誤或合併衝突問題', + wikiWritePage: '建立/覆蓋 Wiki', + wikiWritePageDesc: '建立新頁面或完全覆蓋已有 Wiki 頁面', + wikiReplaceText: '局部取代 Wiki', + wikiReplaceTextDesc: '取代 Wiki 頁面中的特定文字', + wikiRenamePage: '重新命名 Wiki', + wikiRenamePageDesc: '重新命名 Wiki 頁面並自動更新關聯連結', + wikiDeletePage: '刪除 Wiki', + wikiDeletePageDesc: '刪除 Wiki 頁面並自動清理關聯死鏈', + wikiReadIssue: '查看 Wiki 問題', + wikiReadIssueDesc: '查看特定 Wiki 頁面的巡檢問題詳情', + wikiUpdateIssue: '更新 Wiki 問題', + wikiUpdateIssueDesc: '更新 Wiki 頁面問題的處理狀態', + webSearch: '網路搜尋', + webFetch: '網頁抓取', + groupBase: '基礎', + groupRag: '知識庫檢索(RAG)', + groupWikiRead: 'Wiki 讀取', + groupWikiEdit: 'Wiki 編輯', + groupWikiIssue: 'Wiki 巡檢', + groupData: '資料分析', + writeWarning: '會修改 Wiki 內容', + dangerTag: '可寫', + statusNoKb: '當前未關聯任何知識庫', + kbMetricRag: 'RAG 知識庫', + kbMetricWiki: 'Wiki 知識庫', + statusInactive: '有 {count} 個已勾選工具在當前設定下無法生效', + effectiveLabel: '最終啟用的工具', + effectiveDesc: '根據當前設定計算,這是智慧代理儲存後實際能呼叫的工具集合', + effectiveEmpty: '當前沒有可用工具,智慧代理將退化為純模型問答' + }, + desc: { + name: '為智慧代理設定一個易於識別的名稱', + description: '簡要描述智慧代理的用途和特點', + systemPrompt: '自定義系統提示語,定義智慧代理的行為和角色', + promptInheritance: "保持模板原文時將跟隨模板更新;修改後按自定義內容儲存。智慧推論模式下,這裡定義角色和工作要求,工具權限與本輪來源選擇由系統單獨控制。", + leaveEmptyDefault: '(留空則使用系統預設)', + contextTemplate: '定義如何將檢索到的內容格式化後傳遞給模型', + model: '選擇智慧代理使用的大型語言模型', + temperature: '控制輸出的隨機性,0 最確定,1 最隨機', + maxTokens: '模型生成回覆的最大 Token 數。選「預設」時為 2048;選「自定義」後按你填的數儲存。', + maxTokensAgent: '每一輪推論的最大生成 Token(含工具呼叫 JSON)。選「預設」時,未綁沙箱為 4096,綁了沙箱(可寫/改檔案)為 24576。選「自定義」後按你填的數儲存,不再自動改。', + thinking: '啟用模型的擴展思考能力(需要模型支持)', + conversationSection: '設定多輪對話開關與問題改寫開關(改寫提示語見「提示語」)', + conversationSectionAgent: '智慧推論始終為多輪模式:按模型脈絡視窗保留歷史對話,超出時自動把較早的內容壓縮成摘要。', + multiTurn: '開啟後將保留歷史對話脈絡', + historyRounds: '保留最近幾輪對話作為脈絡', + retainRetrievalHistory: '保留此前輪次的知識庫檢索結果。關閉時每輪重新檢索', + rewrite: '多輪對話時自動改寫使用者問題,消解指代和補全省略', + memoryEnabled: '允許該智慧代理讀取並補充你的長期記憶。關閉後,與它的對話既不會讀取記憶,也不會新增記憶。空間或個人設定關閉時,這裡開啟也不會生效', + queryUnderstandModel: '用於問題理解(改寫與意圖識別)的模型,留空則復用主對話模型', + rewriteSystemPrompt: '用於問題改寫的系統提示語(留空使用預設)', + rewriteUserPrompt: '用於問題改寫的使用者提示語模板(留空使用預設)', + selectTools: '選擇 Agent 可以使用的工具', + maxIterations: '限制 Agent 單次任務的推論步數。選「不限制」時會一直跑到模型自然結束或你手動停止。', + kbScope: '選擇智慧代理可存取的知識庫範圍', + webSearch: '啟用後智慧代理可以搜尋網際網路獲取資訊', + webSearchProvider: '為此智慧代理指定搜尋引擎,留空則使用預設搜尋引擎', + webSearchMaxResults: '每次搜尋返回的最大結果數量', + webFetchEnabled: 'Rerank 後自動抓取排名靠前的網頁完整內容,提升回答品質', + webFetchTopN: 'Rerank 後最多抓取幾個網頁的完整內容', + retrievalSection: '設定知識庫檢索召回、排序與 FAQ 優先策略(ReRank 模型見「模型設定」)', + queryExpansion: '自動擴展查詢詞以提高召回率', + embeddingTopK: '向量檢索返回的最大結果數量', + keywordThreshold: '關鍵字檢索的最低相關性分數', + vectorThreshold: '向量檢索的最低相似度分數', + rerankTopK: '重排序後保留的最大結果數量', + rerankThreshold: '重排序的最低相關性分數', + fallbackStrategy: '當無法從知識庫找到相關內容時的處理方式', + fallbackResponse: '當無法回答時返回的固定文字', + fallbackPrompt: '當無法從知識庫找到答案時,引導模型生成回覆的提示語' + }, + selection: { + all: '全部', + selected: '指定', + disabled: '停用' + }, + promptNav: { + ariaLabel: '提示語目錄', + system: '系統提示語', + context: '脈絡模板', + intent: '意圖提示語', + rewriteSystem: '改寫 · 系統', + rewriteUser: '改寫 · 使用者', + fallback: '檢索兜底' + }, + intentPrompts: { + title: '意圖提示語', + sectionDesc: '為不同查詢意圖設定專屬系統提示語;未自定義時使用系統預設模板', + intentLabel: '意圖', + promptPlaceholder: '輸入自定義系統提示語...', + customized: '已自定義', + empty: '暫無可用的意圖模板' + }, + placeholders: { + available: '可用變數:', + clickToInsert: '(點擊插入)', + hint: '(點擊插入,或輸入 {\'{{\'} 喚起清單)' + }, + questionSuggestions: { + navLabel: '問題推薦', + title: '對話問題推薦', + description: '統一設定開場問題與回答後的脈絡追問;通路可關閉展示,但不能改寫智慧代理策略。', + startersTitle: '開場推薦', + followUpsTitle: '回答後推薦', + enableStarters: '展示開場問題', + enableStartersDesc: '在使用者首次提問前展示,可使用營運設定、知識庫或混合來源。', + enableFollowUps: '生成回答後推薦', + enableFollowUpsDesc: '每次完整回答結束後異步生成,不阻塞主回答。啟用後會產生額外模型呼叫。', + sourceMode: '內容來源', + count: '展示數量', + curatedItems: '營運設定問題', + curatedItemsDesc: '用於開場推薦;混合模式下優先展示。', + addItem: '新增問題', + model: '生成模型', + modelDesc: '留空時使用本輪對話模型。', + advancedSettings: '進階生成設定', + displayRules: '展示與兜底規則', + contextTurns: '脈絡輪數', + categories: '問題類型', + instruction: '附加生成要求', + instructionPlaceholder: '例如:優先推薦能幫助使用者落實執行的問題,避免寬泛問題或重複當前回答…', + suppressFallback: '兜底回答後不展示', + suppressQuestion: '回答本身以提問結尾時不展示', + knowledgeFallback: '模型生成失敗時使用知識庫候選', + allowRegenerate: '允許使用者換一批', + modeCurated: '營運設定', + modeKnowledge: '知識庫', + modeGenerated: '模型生成', + modeHybrid: '混合', + categoryClarify: '澄清', + categoryDeepen: '深入', + categoryAction: '下一步' + }, + navGroups: { + basic: '基礎', + knowledge: '知識檢索', + capability: '能力擴展', + integration: '發布集成' + } + }, + agentStream: { + saveToKb: { + emptyContent: '當前回答為空,無法儲存到知識庫', + editorOpened: '已打開編輯器,請選擇知識庫後儲存' + }, + copy: { + emptyContent: '當前回答為空,無法複製', + success: '已複製到剪貼簿', + failed: '複製失敗,請手動複製' + }, + mcp: { + discoverTools: "發現 MCP 工具", + listServers: "查看 MCP 服務", + listTools: "查看 MCP 工具", + searchTools: "搜尋 MCP 工具", + describeTool: "讀取工具定義", + callTool: "呼叫 MCP 工具", + showing: "已顯示 {count} / {total} 項", + moreAvailable: "還有更多結果", + empty: "沒有可顯示的項", + parameters: "參數", + expand: "展開說明", + collapse: "收起", + required: "必填", + fullSchema: "完整參數定義", + failed: "MCP 操作失敗", + result: "執行結果", + status: { + not_loaded: "未載入", + loading: "載入中", + ready: "可用", + needs_auth: "需要授權", + error: "連結失敗", + disabled: "已停用", + unavailable: "不可用", + }, + }, + toolStatus: { + calling: '正在呼叫 {name}...', + searchKb: '檢索知識庫', + searchKbFailed: '檢索知識庫失敗', + searchMixed: '檢索知識庫和網路', + searchMixedFailed: '檢索失敗', + webSearch: '網路搜尋', + webSearchFailed: '網路搜尋失敗', + grepSearch: '搜尋關鍵字', + grepSearchFailed: '搜尋關鍵字失敗', + getDocInfo: '獲取文件資訊', + getDocInfoFailed: '獲取文件資訊失敗', + viewDocument: '查看文件', + thinkingDone: '完成思考', + thinkingFailed: '思考失敗', + updateTodos: '更新任務清單', + updateTodosFailed: '更新任務清單失敗', + imageAnalyzing: '正在查看圖片內容...', + imageAnalysisDone: '已查看圖片內容', + imageAnalysisFailed: '圖片內容查看失敗', + attachmentParsing: '正在解析附件...', + attachmentParsingDone: '已解析附件', + attachmentParsingFailed: '附件解析失敗', + queryUnderstanding: '正在理解問題...', + queryUnderstandDone: '已完成問題理解', + called: '呼叫 {name}', + calledFailed: '呼叫 {name} 失敗', + shellExecRunning: '正在執行沙箱命令...' + }, + ragPipeline: { + searching: '正在檢索知識庫...', + searchingWithQuery: '正在檢索知識庫:「{query}」', + searchingWeb: '正在檢索網路...', + searchingWebWithQuery: '正在檢索網路:「{query}」', + searchingMixed: '正在檢索知識庫和網路...', + searchingMixedWithQuery: '正在檢索知識庫和網路:「{query}」', + searchDone: '檢索完成' + }, + attachmentParsing: { + parsedSummary: '已解析 {count} 個附件', + parsedWithSkipped: '已解析 {parsed} 個附件,{skipped} 個未完成已跳過', + noneReady: '沒有可用的已解析附件' + }, + knowledgeChunksList: { + chunkRange: '已載入 {fetched} / {total} 個切塊', + page: '第 {page} 頁,每頁 {pageSize} 個', + offsetRange: '第 {from}–{to} 塊', + queryMatches: '文件內搜尋「{query}」命中 {count} 處', + queryNoMatch: '文件內搜尋「{query}」無比對' + }, + grepResults: { + chunkHits: '{count} 片段', + keywordHits: '{count} 次', + titleMatch: '標題比對', + faqEntry: 'FAQ 條目' + }, + search: { + noResults: '未找到比對的內容', + candidatesBelowThreshold: '命中 {count} 條候選,相關性不足,未用於回答', + foundResultsFromFiles: '找到 {count} 個結果,來自 {files} 個檔案', + foundResults: '找到 {count} 個結果', + foundMixedResults: '找到 {count} 個結果({docCount} 篇文件,{webCount} 條網頁)', + webResults: '找到 {count} 條網頁', + grepSummary: '找到 {chunks} 個比對片段,來自 {docs} 個文件' + }, + plan: { + inProgress: '進行中', + pending: '待處理', + completed: '已完成' + }, + toolSummary: { + getDocument: '獲取文件:{title}', + document: '文件', + listChunks: '查看 {title}', + listFaqEntry: '查看 FAQ:{question}', + deepThinking: '深度思考' + }, + citation: { + notFound: '未找到內容', + loadFailed: '載入失敗', + noKbForWiki: '無法識別關聯的知識庫,無法打開 Wiki' + }, + tools: { + searchKnowledge: '知識庫檢索', + grepChunks: '搜尋關鍵字', + webSearch: '網路搜尋', + webFetch: '網頁抓取', + getDocumentInfo: '獲取文件資訊', + listKnowledgeChunks: '查看知識切塊', + getRelatedDocuments: '尋找相關文件', + getDocumentContent: '獲取文件內容', + wikiReadSourceDoc: '精讀源文件', + readDocument: '閱讀文件', + listDocuments: '瀏覽文件清單', + todoWrite: '計劃管理', + knowledgeGraphExtract: '知識圖譜抽取', + thinking: '思考', + attachmentParsing: '解析附件', + imageAnalysis: '查看圖片內容', + queryUnderstand: '理解問題', + queryKnowledgeGraph: '知識圖譜查詢', + readSkill: '讀取技能', + executeSkillScript: '執行技能指令碼', + listSandboxFiles: '列出沙箱檔案', + readFile: '讀取檔案', + readSandboxFile: '讀取沙箱檔案', + writeSandboxFile: '寫入沙箱檔案', + editSandboxFile: '編輯沙箱檔案', + shellExec: '執行沙箱命令', + dataAnalysis: '資料分析', + dataSchema: '資料結構', + databaseQuery: '資料庫查詢' + }, + skillFiles: { + heading: '技能檔案', + script: '指令碼', + instructions: '技能說明' + }, + sandboxFiles: { + found: '找到 {count} 個檔案', + empty: '暫無檔案', + truncated: '清單已截斷', + wrote: '已寫入', + edited: '已編輯', + replacements: '取代 {count} 處', + moreLines: '另有 {count} 行' + }, + shellExec: { + workDir: '目錄', + exitCode: '退出碼', + stdout: '標準輸出', + stderr: '標準錯誤', + emptyOutput: '無輸出', + truncated: '輸出已截斷', + killed: '已超時終止', + binarySuppressed: '二進位輸出已省略,請將檔案寫入產物目錄後下載' + }, + mcpOAuth: { + waiting: '等待授權 · {target}', + waitingStatus: '等待授權', + targetWithTool: '{service} › {tool}', + titleWithService: 'OAuth 授權 · {service}', + titleWithTool: 'OAuth 授權 · {service} › {tool}', + desc: '點擊授權將打開新視窗完成登入,授權成功後會自動繼續本次工具呼叫。', + authorize: '去授權', + skip: '跳過', + countdownShort: '{seconds}s', + authorizedTag: '已授權', + timedOutTag: '授權超時', + canceledTag: '已取消', + authorizedToast: '授權成功,正在繼續', + startFailed: '發起授權失敗', + resumeFailed: '復原執行失敗,請重試', + skipFailed: '跳過失敗,請重試' + }, + toolApproval: { + waiting: '等待審核 · {target}', + waitingStatus: '等待審核', + targetWithTool: '{service} › {tool}', + titleWithTarget: '人工審核 · {service} › {tool}', + argsLabel: '呼叫參數', + argsModified: '已修改', + countdownShort: '{seconds}s', + approve: '透過並執行', + reject: '拒絕', + approvedTag: '已透過', + rejectedTag: '已拒絕', + invalidJson: '參數不是合法 JSON', + submitted: '已提交', + submitFailed: '提交失敗', + userRejected: '使用者拒絕' + } + }, + kbSettings: { + parser: { + title: '解析引擎', + description: '為不同檔案類型選擇文件解析引擎。未設定的檔案類型將使用內建解析引擎。', + loading: '載入中...', + noEngineAvailable: '暫無可用解析引擎,或文件解析服務未設定。', + default: '預設', + goConfig: '前往設定 →', + noEngine: '無可用引擎', + fileTypePdf: 'PDF 文件', + fileTypeWord: 'Word 文件', + fileTypePpt: '簡報', + fileTypeExcel: 'Excel 表格', + xlsxFirstRowAsHeader: '將首行作為列標題,並保留在每行脈絡中', + fileTypeEbook: '電子書', + fileTypeWebArchive: '網頁歸檔', + fileTypeCsv: 'CSV 檔案', + fileTypeText: '純文字', + fileTypeJson: 'JSON 檔案', + fileTypeImage: '圖片', + fileTypeAudiovisual: '音訊', + engines: { + opendataloader: { + name: 'OpenDataLoader', + desc: 'OpenDataLoader PDF 解析引擎(版面分析,需 Java 11+ 與 opendataloader-pdf)' + }, + markitdown: { + name: 'MarkItDown', + desc: 'Microsoft MarkItDown 文件轉換工具(支持 PDF/Office/HTML 等)' + }, + weknoracloud: { + name: 'WeKnora Cloud', + desc: '使用 WeKnora Cloud 進行文件解析' + }, + paddleocr_vl_cloud: { + name: 'PaddleOCR-VL Cloud', + desc: 'PaddleOCR-VL 雲 API' + }, + paddleocr_vl: { + name: 'PaddleOCR-VL', + desc: 'PaddleOCR-VL 自部署服務' + }, + mineru_cloud: { + name: 'MinerU Cloud', + desc: 'MinerU Cloud API' + }, + mineru: { + name: 'MinerU', + desc: 'MinerU 自部署服務' + }, + simple: { + name: 'Simple', + desc: '簡單格式 & 圖片解析(無需外部服務)' + }, + anydoc: { + name: 'anydoc', + desc: '行程內 Office 文件解析(無需外部服務)' + }, + builtin: { + name: '內建', + desc: 'DocReader 內建解析引擎(docx/pdf/xlsx 等複雜格式)' + } + } + }, + storage: { + title: '存儲引擎', + selectDescription: '選擇此知識庫綁定的具體存儲實例。', + defaultTag: '預設', + instanceLabel: '存儲實例', + instanceDesc: '同一種存儲類型可以設定多個不同 Endpoint、Bucket 或憑據的實例。', + migrateHint: '知識庫中已有檔案,需透過存儲遷移流程才能更換實例。', + manageInstances: '管理存儲實例', + localStorage: '本地存儲', + loading: '載入中...' + }, + vectorStore: { + title: '向量存儲', + description: '選擇此知識庫要寫入的向量存儲。綁定不可更改 — 如需將現有 KB 遷移到其他存儲,請建立新 KB 並重新索引。', + loading: '正在載入向量存儲清單...', + engineLabel: '向量存儲', + engineDesc: '從全局向量存儲設定中選擇,或保持系統預設以使用空間的 RETRIEVE_DRIVER 引擎。', + boundLabel: '已綁定的向量存儲', + systemDefault: '系統預設', + immutableHint: '建立後不可更改。如需遷移,請建立一個綁定到目標存儲的新 KB 並重新索引。', + immutableEdit: '向量存儲綁定在建立後無法更改。', + unavailableHint: '綁定的向量存儲當前不可用,請在設定 → 向量存儲中檢查其連結設定。', + goGlobalSettings: '前往向量存儲設定' + } + }, + vectorStoreBadge: { + systemDefault: '系統預設', + sharedFromOrg: '來自其他組織的共享', + unknownStore: '未知存儲', + unavailable: '不可用' + }, + tools: { + multiKbSearch: '跨庫搜尋', + searchKnowledge: '檢索知識庫', + readDocument: '閱讀文件', + listDocuments: '瀏覽文件清單', + knowledgeSearch: '知識庫搜尋', + grepChunks: '搜尋關鍵字', + getChunkDetail: '獲取片段詳情', + listKnowledgeChunks: '查看知識切塊', + listKnowledgeBases: '列出知識庫', + getDocumentInfo: '獲取文件資訊', + queryKnowledgeGraph: '查詢知識圖譜', + think: '深度思考', + todoWrite: '制定計劃' + }, + commandPalette: { + placeholder: '搜尋知識庫、檔案、對話…', + clearRecent: '清除', + retrieval: '檢索參數', + untitledSession: '未命名對話', + hotkey: { + select: '選擇', + enter: '打開', + cmdNumber: '直接打開', + cmdEnter: '發起對話', + esc: '關閉' + }, + empty: { + noResults: '沒有找到比對結果', + askAi: '直接向 AI 提問', + adjustRetrieval: '調整檢索參數' + }, + quick: { + newChat: '新建對話', + knowledgeBases: '打開知識庫', + agents: '打開智慧代理', + organizations: '打開共享空間', + settings: '打開設定', + productTour: '新手引導' + }, + match: { + vector: '向量', + keyword: '關鍵字' + }, + group: { + chunks: '知識庫檔案', + messages: '對話訊息', + kbs: '知識庫', + agents: '智慧代理', + sessionsByTitle: '對話(按標題)', + commands: '命令', + recent: '最近搜尋', + quickActions: '快捷操作' + }, + scope: { + placeholder: '在本知識庫中搜尋…', + remove: '移除範圍篩選(Backspace)' + } + }, + preview: { + tab: '預覽', + loading: '正在載入文件預覽...', + loadFailed: '載入文件預覽失敗', + retry: '重試', + unsupported: '該檔案類型暫不支持線上預覽', + unsupportedHint: '請下載檔案後使用本地應用查看', + zoomIn: '放大', + zoomOut: '縮小', + fullscreen: '全螢幕預覽', + exitFullscreen: '退出全螢幕', + htmlRendered: '渲染預覽', + htmlSource: '查看源碼', + audioLoading: '載入音訊中…', + audioNotSupported: '您的瀏覽器不支持音訊播放', + videoNotSupported: '您的瀏覽器不支持影片播放' + }, + organization: { + title: '共享空間', + subtitle: '建立或加入共享空間,讓多個空間互相協作,共享知識庫與智慧代理', + createOrg: '建立共享空間', + joinOrg: '加入共享空間', + name: '共享空間名稱', + namePlaceholder: '請輸入共享空間名稱', + nameRequired: '請輸入共享空間名稱', + avatar: '共享空間頭像', + avatarClear: '清除', + avatarPickerHint: '選擇 Emoji 作為共享空間頭像', + description: '共享空間描述', + descriptionPlaceholder: '請輸入共享空間描述(選填)', + noDescription: '暫無描述', + memberCount: '成員數量', + owner: '建立者', + inviteCode: '邀請碼', + inviteCodePlaceholder: '請輸入邀請碼', + inviteCodeRequired: '請輸入邀請碼', + refreshInviteCode: '重新整理邀請碼', + inviteCodeRefreshed: '邀請碼已重新整理', + inviteCodeRefreshFailed: '重新整理邀請碼失敗', + leave: '退出共享空間', + leaveConfirmTitle: '退出共享空間', + leaveConfirmMessage: '確定要退出共享空間「{name}」嗎?退出後將無法存取該共享空間共享的知識庫。', + leaveSuccess: '已退出共享空間', + leaveFailed: '退出共享空間失敗', + deleteConfirmTitle: '刪除共享空間', + deleteConfirmMessage: '確定要刪除共享空間「{name}」嗎?刪除後所有成員將被移除,此操作不可復原。', + deleteSuccess: '共享空間已刪除', + deleteFailed: '刪除共享空間失敗', + createSuccess: '已建立共享空間', + createFailed: '建立共享空間失敗', + joinSuccess: '成功加入共享空間', + joinFailed: '加入共享空間失敗', + manageMembers: '成員管理', + noMembers: '暫無成員', + roleUpdated: '角色已更新', + roleUpdateFailed: '更新角色失敗', + memberRemoved: '成員已移除', + memberRemoveFailed: '移除成員失敗', + empty: '您還沒有加入任何共享空間', + emptyDesc: '建立一個共享空間或透過邀請碼加入現有共享空間', + createdByMe: '我建立的', + joinedByMe: '我加入的', + emptyCreated: '您還沒有建立任何共享空間', + emptyCreatedDesc: '點擊「建立共享空間」建立一個新的共享空間', + emptyJoined: '您還沒有加入任何共享空間', + emptyJoinedDesc: '透過邀請碼加入現有共享空間', + share: { + title: '共享到共享空間', + selectOrg: '選擇共享空間', + selectOrgPlaceholder: '請選擇要共享的共享空間', + permission: '權限', + permissionTip: '可編輯權限允許成員修改知識庫內容,唯讀權限僅允許檢索和問答', + shareSuccess: '已共享', + shareFailed: '共享失敗', + unshareSuccess: '已取消共享', + unshareFailed: '取消共享失敗', + sharedTo: '已共享到', + noShares: '尚未共享到任何共享空間', + searchPlaceholder: '搜尋共享空間…', + loading: '載入中…', + emptySearch: '未找到比對「{q}」的共享空間', + addShareDialogTitle: '共享到共享空間', + unshareAction: '取消共享', + sharedKnowledgeBase: '共享知識庫', + agentShareDesc: '將智慧代理共享到共享空間,共享空間成員可使用該智慧代理', + sharedFrom: '來自', + permissionReadonly: '唯讀', + permissionEditable: '可編輯', + columns: { + space: '共享空間', + permission: '權限', + sharedAt: '共享時間', + operations: '操作' + } + }, + addMember: { + button: '新增成員', + dialogTitle: '新增成員', + tipTenant: '共享空間的成員單位是空間:選定一個空間後,其下全部使用者都將獲得存取權限。下方搜尋結果按空間去重。', + searchTenant: '空間 ID', + searchTenantPlaceholder: '輸入完整空間 ID', + searchTenantHint: '僅按完整空間 ID 尋找,也可透過邀請連結加入組織', + selectRole: '分配角色', + confirmBtn: '新增', + success: '已新增成員', + failed: '新增失敗' + }, + upgrade: { + requestUpgrade: '申請升級', + pending: '審核中', + dialogTitle: '申請升級', + dialogDesc: '管理員審核透過後更新您的角色。', + currentRole: '當前角色', + selectRole: '申請角色', + reason: '申請理由(選填)', + reasonPlaceholder: '請簡要說明申請更高權限的原因...', + submitBtn: '提交申請', + submitSuccess: '權限升級申請已提交,等待管理員審核', + submitFailed: '提交申請失敗' + }, + editor: { + navBasic: '基本資訊', + navPermissions: '權限說明', + navJoin: '加入共享空間', + basicTitle: '基本資訊', + basicDesc: '設定共享空間的名稱和描述,便於成員識別', + nameTip: '建議使用團隊或專案名稱,便於成員識別', + descriptionTip: '描述共享空間的用途和目標,幫助成員了解共享空間', + permissionsTitle: '成員權限', + permissionsDesc: '了解共享空間中不同角色對知識庫與智慧代理的權限範圍', + permissionFeature: '權限功能', + fullAccess: '完整權限', + editAccess: '編輯權限', + viewAccess: '唯讀權限', + adminPerm1: '管理共享空間設定、成員及知識庫與智慧代理共享', + adminPerm2: '共享和管理知識庫與智慧代理', + adminPerm3: '編輯共享知識庫內容', + adminPerm4: '查看和檢索知識庫', + useSharedAgentsPerm: '使用共享智慧代理', + shareKBPerm: '共享知識庫到共享空間', + editorPerm1: '編輯共享知識庫內容', + editorPerm2: '查看和檢索知識庫', + editorPerm3: '管理共享空間設定和成員', + viewerPerm1: '查看和檢索知識庫', + viewerPerm2: '編輯知識庫內容', + viewerPerm3: '管理共享空間設定', + ownerNote: '作為共享空間建立者,您將自動成為共享空間的管理員,擁有完整權限。', + joinTitle: '加入共享空間', + joinDesc: '透過邀請碼加入現有共享空間,獲得知識庫與智慧代理存取權限', + joinIllustration: '輸入共享空間管理員提供的邀請碼即可加入', + inviteCodeTip: '邀請碼由共享空間管理員生成,請向他們索取', + howToGetCode: '如何獲取邀請碼?', + step1: '聯絡您要加入的共享空間管理員', + step2: '請求他們分享共享空間邀請碼', + step3: '將邀請碼貼上到上方輸入框' + }, + navGroups: { + basic: '基礎', + management: '成員與協作', + resources: '共享資源' + }, + settings: { + editTitle: '共享空間設定', + membersDesc: '查看和管理共享空間成員、調整成員角色。成員的最小單位是空間──加入後該空間下的所有使用者都將獲得存取權限。', + permissionsIconHint: '查看各角色權限說明', + sharedDesc: '查看共享到此共享空間的所有知識庫', + noSharedKB: '暫無共享的知識庫', + noSharedKBTip: '知識庫擁有者可以在知識庫設定中將其共享到此共享空間', + sharedAgents: '共享智慧代理', + noSharedAgents: '暫無共享的智慧代理', + sharedAgentsDesc: '已共享到本共享空間的智慧代理,成員可在對話中使用', + sharedAgentsKbHint: '智慧代理綁定的知識庫僅在成員使用該智慧代理對話時可 {\'@\'} 使用(唯讀),不會出現在「知識庫清單」中。若需成員在清單中看到或編輯知識庫,請單獨將知識庫共享到本共享空間。', + sharedAgentsKbHintShort: '智慧代理綁定知識僅對話內唯讀;需在清單看到或編輯請單獨共享知識庫', + noSharedAgentsTip: '管理員可將智慧代理從智慧代理設定中共享到本共享空間', + sharePermissionLabel: '共享空間權限', + myPermissionLabel: '生效權限', + permissionCalcFormula: '共享空間權限為共享時設定;生效權限取共享空間權限與你的共享空間角色中較低值', + permissionCalcTip: '生效權限取共享空間權限與你的共享空間角色中較低值;唯讀成員對此庫最多唯讀。', + inviteMembers: '邀請成員', + inviteMembersDesc: '透過邀請碼或連結邀請他人加入共享空間', + inviteLink: '邀請連結', + inviteLinkValidity: '邀請連結有效期', + inviteLinkValidityDesc: '新生成的邀請連結的有效期,僅影響之後重新整理生成的連結', + validity1Day: '1 天', + validity7Days: '7 天', + validity30Days: '30 天', + validityNever: '永不過期', + remainingValidity: '剩餘 {n} 天', + remainingValidityNever: '永不過期', + remainingValidityExpired: '已過期', + removeShareFromOrg: '從共享空間中移除', + removeShareConfirm: '確定將「{name}」從本共享空間中移除?移除後共享空間成員將無法再存取該知識庫。', + removeAgentShareConfirm: '確定將「{name}」從本共享空間中移除?移除後共享空間成員將無法再存取該智慧代理。', + removeShareSuccess: '已從共享空間中移除', + removeShareFailed: '移除失敗,請重試', + requireApproval: '需要審核', + requireApprovalDesc: '開啟後,新成員加入需要管理員審核', + searchable: '開放可被搜尋', + searchableDesc: '開啟後,共享空間將出現在「加入共享空間」的搜尋清單中,他人可搜尋並申請加入,無需邀請碼', + memberLimit: '成員數量上限', + memberLimitDesc: '超過上限後無法再新增新成員;設為 0 表示不限制', + memberLimitPlaceholder: '0 表示不限制', + memberLimitHint: '當前成員數:{count}', + joinRequests: '加入申請', + joinRequestsDesc: '審核待加入共享空間的申請', + noPendingRequests: '暫無待審核的申請', + pendingJoinRequestsBadge: '有待審批的加入申請', + pendingReview: '待審批', + assignRole: '分配角色', + approve: '透過', + reject: '拒絕', + approveSuccess: '已透過申請', + rejectSuccess: '已拒絕申請', + reviewFailed: '操作失敗,請重試' + }, + detail: { + removeMemberConfirm: '確定要移除成員「{name}」嗎?', + removeMember: '移除成員' + }, + role: { + admin: '管理員', + editor: '編輯', + viewer: '唯讀' + }, + sharedResources: { + kbListTitle: '共享知識庫', + agentListTitle: '共享智慧代理', + loading: '載入中…', + columns: { + name: '名稱', + sharedBy: '共享者', + sharedAt: '共享時間', + permission: '權限' + } + }, + joinRequests: { + listTitle: '待審核申請', + searchPlaceholder: '搜尋申請人…', + loading: '載入申請中…', + emptySearch: '未找到比對「{q}」的申請', + typeJoin: '加入', + typeUpgrade: '升級', + rejectConfirm: '確認拒絕該申請?', + approveTitle: '透過申請', + approveDesc: '為「{name}」分配加入後的角色', + columns: { + applicant: '申請人', + type: '類型', + requestedRole: '申請角色', + message: '申請說明', + appliedAt: '申請時間' + } + }, + members: { + listTitle: '共享空間成員', + searchPlaceholder: '搜尋成員…', + loading: '載入成員中…', + emptySearch: '未找到比對「{q}」的成員', + columns: { + member: '成員', + role: '角色', + joinedAt: '加入時間', + operations: '操作' + } + }, + invite: { + loading: '載入中...', + previewTitle: '加入共享空間', + inputDesc: '輸入邀請碼或貼上邀請連結中的邀請碼,查看共享空間資訊後加入', + previewAction: '查看', + primaryJoin: '加入', + invalidCode: '邀請碼無效或已過期', + previewFailed: '預覽失敗,請稍後重試', + knowledgeBases: '知識庫', + agents: '智慧代理', + alreadyMember: '您已經是該共享空間的成員', + submitRequest: '申請加入', + requireApprovalTip: '該共享空間需要管理員審核後才能加入', + approvalLabel: '加入方式', + needApproval: '需要審核', + noApproval: '無需審核', + defaultRoleAfterJoin: '加入後預設權限:{role}', + requestRole: '申請角色', + selectRole: '選擇角色', + messagePlaceholder: '選填:申請說明(如自我介紹或加入原因)', + applicationNote: '申請說明(選填)', + joinSuccess: '成功加入共享空間!', + joinFailed: '加入失敗,請稍後重試', + requestSubmitted: '申請已提交,請等待管理員審核', + requestFailed: '申請提交失敗,請稍後重試', + viewOrganization: '查看共享空間' + }, + join: { + title: '加入共享空間', + joining: '正在加入共享空間...', + success: '成功加入共享空間!', + failed: '加入共享空間失敗', + noCode: '未找到邀請碼', + goToOrganizations: '前往共享空間清單', + confirmTitle: '確認加入共享空間', + confirm: '確認加入', + preview: '預覽並加入', + memberCount: '{count} 個成員', + shareCount: '{count} 個共享知識庫', + agentShareCount: '{count} 個智慧代理', + alreadyMember: '您已經是該共享空間的成員', + invalidCode: '無效的邀請碼', + byInviteCode: '輸入邀請碼', + searchSpaces: '搜尋共享空間', + searchSpacesDesc: '瀏覽或搜尋已開放可被搜尋的共享空間,無需邀請碼即可加入', + searchSpacesPlaceholder: '按共享空間名稱、描述或 ID 搜尋', + spaceId: '共享空間ID', + noSearchResult: '未找到比對的共享空間', + noSearchableSpaces: '暫無開放可被搜尋的共享空間,或輸入關鍵字搜尋', + memberLimitReached: '成員已滿', + backToSearch: '返回搜尋' + }, + rbac: { + needTenantAdminTip: '此操作需要當前空間的 admin 或更高角色,請聯絡空間 Owner 調整權限。', + cannotCreate: '當前空間角色不足,無法建立共享空間', + cannotJoin: '當前空間角色不足,無法加入或申請加入共享空間', + cannotManage: '當前空間角色不足,無法管理共享空間' + } + }, + promptTemplate: { + noTemplates: '暫無模板', + selectTemplate: '選擇模板', + useTemplate: '使用模板', + resetDefault: '復原預設', + default: '預設', + withKnowledgeBase: '知識庫', + withWebSearch: '網路搜尋' + }, + mcpMetadata: { + "searchTools": "搜尋工具名稱或描述", + "retry": "重試", + "details": "詳情", + "description": "描述", + "parameters": "參數", + "required": "必填", + "fullSchema": "完整定義", + "noDescription": "沒有描述", + "noParameters": "沒有參數定義", + "enabled": "啟用工具", + "approval": "呼叫需審批", + "noTools": "沒有比對的工具", + "next": "下一頁", + "policyLoadFailed": "工具策略讀取失敗,請重試後再修改。", + "policySaveFailed": "工具設定儲存失敗", + + "tools": "Tools 清單", + "cacheHint": "尚未同步時會自動連結並儲存完整描述;之後只在重新整理時存取 MCP 服務。", + "refresh": "重新整理 Tools", + "fetch": "重新拉取", + "fetching": "正在連結並拉取 Tools…", + "toolCount": "{count} 個工具", + "stale": "連結或認證設定已改變。以下是舊目錄,重新同步後才能供模型使用。", + "notSynced": "尚未同步工具。連結並拉取後,會儲存完整描述和參數定義。", + "syncRequired": "請先連結並拉取 Tools,同步後的目錄才能給模型使用。", + "needsRefresh": "需要重新同步", + "saved": "已儲存目錄", + "syncedAt": "同步時間:", + "serverDocumentation": "伺服器端原始說明", + "noServerDocumentation": "該 MCP Server 的 initialize 未返回 instructions / serverInfo.description(均為可選欄位)。工具說明在下方各工具的 description 裡。", + "policyHint": "工具開關與審批設定即時儲存;重新整理目錄不會覆蓋這些設定。", + "failed": "工具目錄讀取失敗", + "setupProgress": "MCP 設定步驟", + "connection": "連結設定", + "toolsAndUsage": "工具與用途說明", + "previous": "上一步", + "usage": "服務用途", + "usageHint": "模型先讀取服務用途,再按需載入具體工具。以下內容由你維護,重新整理不會覆蓋。", + "summary": "用途摘要", + "summaryPlaceholder": "例如:查詢訂單狀態、物流進度和退款記錄。", + "usageInstructions": "使用說明", + "instructionsPlaceholder": "簡要說明服務用途、適用情境和關鍵使用約束。", + "generateUsage": "AI 生成", + "generateHint": "根據已同步且啟用的 Tools 生成精簡說明,填入後可編輯,儲存後生效。", + "instructionsRequired": "使用說明不能為空", + "generated": "已生成,請檢查後儲存", + "generateFailed": "生成失敗,請確認 Tools 已同步且已設定可用的對話模型後重試。", + "saveNext": "儲存並下一步" +}, + mcpServiceDialog: { + addTitle: '新增 MCP 服務', + addDesc: '連結外部 MCP 服務,智慧代理即可呼叫其中的工具。', + editTitle: '編輯 MCP 服務', + basicSection: '基本資訊', + connectionSection: '連結設定', + enableServiceDesc: '關閉後該服務不會被呼叫', + testAfterSaveHint: '儲存後可測試連結', + unitSecond: '秒', + unitTimes: '次', + name: '服務名稱', + namePlaceholder: '請輸入服務名稱', + description: '描述', + descriptionPlaceholder: '請輸入服務描述', + transportType: '傳輸類型', + serviceUrl: '服務 URL', + serviceUrlPlaceholder: 'https://example.com/mcp', + enableService: '啟用服務', + authConfig: '認證設定', + authType: '認證方式', + authTypeNone: '無 / 自定義 Header', + authTypeApiKey: 'API Key / Token', + authTypeOAuth: 'OAuth 2.0(首次連結授權)', + oauthScopes: 'Scopes(可選,空格分隔)', + oauthAuthorization: '授權狀態', + oauthAuthorized: '已授權', + oauthRefreshable: 'Token 已過期,將在下次使用時自動重新整理', + oauthUnauthorized: '未授權', + oauthAuthorize: '去授權', + oauthReauthorize: '重新授權', + oauthRevoke: '撤銷授權', + oauthAuthorizeHint: '點擊「去授權」會先自動儲存當前設定,再發起授權(每個使用者獨立授權)。', + apiKeyHeader: '請求頭名稱', + apiKeyHeaderDesc: '留空預設 X-API-Key。Bearer 方式請填 Authorization,並在下方金鑰值中寫 「Bearer 」;需要裸 token 時填 Authorization 並直接填入 token。', + credentialValue: '金鑰值 / Token', + optional: '可選', + advancedConfig: '進階設定', + timeoutSec: '超時時間(秒)', + retryCount: '重試次數', + retryDelaySec: '重試延遲(秒)', + codeImport: { + toggle: '從程式碼匯入', + hint: '貼上標準 mcpServers JSON 設定,自動填充表單', + parse: '解析並填充', + editOverwriteHint: '匯入會覆蓋當前表單內容(不影響已儲存的憑證,需點儲存生效)', + toasts: { + filled: '已填充表單,請檢查後儲存', + multipleServers: '檢測到多個服務,已匯入第一個:{name}' + }, + errors: { + empty: '請先貼上設定內容', + invalidJson: '無法解析,請檢查 JSON 格式', + noServer: '未找到 MCP 服務設定', + missingUrl: '設定缺少 url', + stdioUnsupported: '暫不支持 stdio(command/args)設定,請使用帶 url 的遠程設定' + } + }, + customHeaders: { + label: '自定義請求頭(可選)', + desc: '附加到每次 MCP 請求的 HTTP 請求頭,常用於企業閘道鑑權、鏈路追蹤等情境。', + add: '新增請求頭', + keyPlaceholder: 'Header 名稱', + valuePlaceholder: 'Header 值' + }, + toasts: { + created: 'MCP 服務已建立', + updated: 'MCP 服務已更新', + createFailed: '建立 MCP 服務失敗', + updateFailed: '更新 MCP 服務失敗', + oauthRequired: '該服務需要 OAuth 授權,已自動切換為 OAuth 2.0,請儲存後點擊「去授權」。', + authorized: '授權成功', + authorizeFailed: '發起授權失敗', + revoked: '已撤銷授權', + revokeFailed: '撤銷失敗' + }, + rules: { + nameRequired: '請輸入服務名稱', + transportRequired: '請選擇傳輸類型', + urlRequired: '請輸入服務 URL', + urlInvalid: '請輸入有效的 URL' + } + }, + ollamaSettings: { + title: 'Ollama 設定', + description: '管理本地 Ollama 服務,查看和下載模型', + toasts: { + connected: '連結成功', + connectFailed: '連結失敗,請檢查 Ollama 是否運行', + listFailed: '獲取模型清單失敗', + downloadFailed: '下載失敗,請稍後重試', + downloadStarted: '已開始下載模型 {name}', + downloadCompleted: '模型 {name} 下載完成', + progressFailed: '查詢下載進度失敗' + }, + installed: { + title: '已下載的模型', + desc: '已安裝在 Ollama 中的模型清單', + empty: '暫無已下載的模型' + }, + download: { + title: '下載新模型', + descPrefix: '輸入模型名稱下載,', + browse: '瀏覽 Ollama 模型庫', + placeholder: '如:qwen2.5:0.5b', + download: '下載', + downloading: '正在下載: {name}' + }, + address: { + label: '服務地址', + desc: '本地 Ollama 服務的 API 地址,由系統自動檢測。如需修改,請在 .env 設定檔中設定', + placeholder: 'http://localhost:11434', + failed: '連結失敗,請檢查 Ollama 是否運行或服務地址是否正確' + }, + status: { + label: 'Ollama 服務狀態', + desc: '自動檢測本地 Ollama 服務是否可用。如果服務未運行或地址設定錯誤,將顯示"不可用"狀態', + testing: '檢測中', + available: '可用', + unavailable: '不可用', + untested: '未檢測', + retest: '重新檢測' + } + }, + modelSettings: { + title: '模型設定', + description: '管理不同類型的 AI 模型,支持 Ollama 本地模型和遠程 API', + copySuffix: ' 副本', + builtinTag: '內建', + confirmDelete: '確定刪除模型「{name}」嗎?', + usage: { + title: '模型無法刪除', + description: '模型「{name}」仍被以下設定引用。請先打開對應設定並更換模型,再重新刪除。', + knowledgeBases: '知識庫({count})', + agents: '智慧代理({count})', + longTermMemory: '長期記憶', + openConfiguration: '打開設定', + truncated: '僅顯示前 {shown} 個,共 {total} 個', + bindings: { + embedding_model: 'Embedding 模型', + summary_model: '摘要模型', + image_processing_model: '圖片處理模型', + vlm_model: '視覺理解模型', + asr_model: '語音辨識模型', + wiki_synthesis_model: 'Wiki 綜合模型', + auto_tag_model: '自動標籤模型', + chat_model: '對話模型', + rerank_model: '重排序模型', + query_understand_model: '問題理解模型', + follow_up_model: '追問模型', + extract_model: '記憶提取模型', + unknown: '其他模型設定' + } + }, + debug: { + reasoningEffort: '思考強度', + reasoningEffortDesc: '按模型目錄上報的等級傳送 reasoning_effort', + title: '模型測試', + description: '使用已儲存的模型設定傳送真實請求;編輯中的修改需儲存後才會生效', + groupModel: '選擇模型', + groupInput: '測試輸入', + groupResult: '運行結果', + modelType: '模型類型', + model: '模型', + modelPlaceholder: '請選擇要測試的模型', + noModelsForType: '當前類型暫無已新增模型', + query: '輸入內容', + queryPlaceholder: '輸入要傳送給模型的內容', + embeddingInput: '待向量化文字', + embeddingPlaceholder: '輸入要生成 Embedding 的文字', + vlmPrompt: '圖片提示語', + vlmPromptPlaceholder: '例如:請詳細描述這張圖片', + documents: '候選文件', + documentsPlaceholder: '每行輸入一個候選文件', + documentsHint: '每個非空行會作為一個獨立文件傳送給 ReRank 模型', + imageFile: '圖片檔案', + audioFile: '音訊檔案', + chooseFile: '選擇檔案', + parameters: '請求參數', + systemPrompt: 'System Prompt', + systemPromptPlaceholder: '可選,輸入系統提示語', + run: '運行測試', + copyResult: '複製結果', + history: '歷史記錄', + runLabel: '第 {n} 次運行', + success: '呼叫成功', + failed: '呼叫失敗', + rawResponse: '回應內容', + requestPreview: '請求預覽', + requestFailed: '模型測試請求失敗', + metrics: { + api: '協議', + thinkingFormat: '思考格式', + requestedReasoningEffort: '請求思考強度', + dimension: '向量維度', + resultCount: '結果數量', + answerChars: '回答字符數', + reasoningChars: '推論字符數', + reasoningReturned: '返回推論內容', + textChars: '轉寫字符數', + segmentCount: '分段數量' + } + }, + builtinModels: { + title: '內建模型', + description: '內建模型對所有空間可見,敏感資訊會被隱藏,且不可編輯或刪除。', + descriptionAdmin: '內建模型對所有空間可見。系統管理員可編輯設定和憑據;刪除仍由部署設定管理。', + viewGuide: '查看內建模型管理指南' + }, + toasts: { + nameRequired: '模型名稱不能為空', + nameTooLong: '模型名稱不能超過100個字符', + displayNameTooLong: '顯示名稱不能超過100個字符', + baseUrlRequired: 'Remote API 類型必須填寫 Base URL', + baseUrlInvalid: 'Base URL 格式不正確,請輸入有效的 URL', + dimensionInvalid: 'Embedding 模型必須填寫有效的向量維度(128-4096)', + updated: '模型已更新', + added: '模型已新增', + saveFailed: '儲存模型失敗', + deleted: '模型已刪除', + deleteFailed: '刪除模型失敗', + builtinCannotEdit: '內建模型不能編輯', + builtinCannotDelete: '內建模型不能刪除', + builtinCannotCopy: '內建模型不能複製', + copied: '模型已複製', + copyFailed: '複製模型失敗' + }, + asr: { + title: 'ASR 語音模型', + desc: '設定用於語音辨識和音訊轉錄的語音轉文字模型(如 OpenAI Whisper)', + empty: '暫無 ASR 語音模型' + }, + vllm: { + title: 'VLLM 視覺模型', + desc: '設定用於視覺理解和多模態的視覺語言模型', + empty: '暫無 VLLM 視覺模型' + }, + rerank: { + title: 'ReRank 模型', + desc: '設定用於結果重排序的模型', + empty: '暫無 ReRank 模型' + }, + embedding: { + title: 'Embedding 模型', + desc: '設定用於文字向量化的內嵌模型', + empty: '暫無 Embedding 模型' + }, + chat: { + title: '對話模型', + desc: '設定用於對話的大型語言模型', + empty: '暫無對話模型' + }, + source: { + remote: 'Remote', + openaiCompatible: 'OpenAI相容', + custom: '自定義' + }, + actions: { + addModel: '新增模型', + debugModel: '模型測試' + }, + typeShort: { + chat: '對話', + embedding: 'Embedding', + rerank: 'ReRank', + vllm: '視覺', + asr: '語音' + } + }, + mcpSettings: { + addUsageInstructions: "新增使用說明", + noUsageInstructions: "尚未填寫使用說明", + title: 'MCP 服務管理', + description: '管理外部 MCP (Model Context Protocol) 服務,在 Agent 模式下呼叫外部工具和資源', + enabled: '已啟用', + disabled: '已停用', + configuredServices: '已設定的服務', + manageAndTest: '管理和測試 MCP 服務連結', + addService: '新增服務', + empty: '暫無 MCP 服務', + deleteConfirmBody: '確定要刪除 MCP 服務"{name}"嗎?此操作無法復原。', + unnamed: '未命名', + builtin: '內建', + toolCount: '{count} 個工具', + toolsNotSynced: '尚未同步工具', + toolsStale: '需重新同步', + toasts: { + loadFailed: '載入 MCP 服務清單失敗', + enabled: '已啟用 MCP 服務', + disabled: '已停用 MCP 服務', + updateStateFailed: '更新 MCP 服務狀態失敗', + testing: '正在測試 {name}...', + noResponse: '測試失敗:未收到伺服器回應', + testFailed: '測試 MCP 服務失敗', + deleted: 'MCP 服務已刪除', + deleteFailed: '刪除 MCP 服務失敗' + }, + actions: { + test: '測試連結' + } + }, + conversationSettings: { + maxTokens: { + desc: '生成回答的最大Token數量' + }, + temperature: { + desc: '控制模型輸出的隨機性,0最確定,1最隨機' + }, + systemPrompt: { + desc: '用於普通模式對話的系統級Prompt' + }, + contextTemplate: { + desc: '用於普通模式下基於檢索結果生成回答的Prompt模板' + }, + rerankModel: { + desc: '用於搜尋結果重排序的模型(可選)' + }, + chatModel: { + desc: '用於總結和摘要的大型語言模型' + }, + rewritePrompt: { + desc: '控制問題改寫的系統提示語' + }, + fallbackPrompt: { + desc: '當選擇模型兜底時使用的提示模板' + }, + fallbackResponse: { + desc: '當兜底策略為固定回覆時返回的文字' + }, + fallbackStrategy: { + desc: '檢索無結果時採用的處理方式' + }, + enableQueryExpansion: { + desc: '召回不足時呼叫大型語言模型生成擴展查詢(增加時延與成本)' + }, + enableRewrite: { + desc: '多輪對話自動改寫問題以獲得更優召回' + }, + rerankThreshold: { + desc: '重排序階段的最低得分閾值' + }, + rerankTopK: { + desc: '重排序後進入答案生成的文件數量' + }, + vectorThreshold: { + desc: '向量召回的最低相似度閾值' + }, + keywordThreshold: { + desc: '關鍵字檢索的最低得分閾值' + }, + embeddingTopK: { + desc: '向量召回階段保留的文件數量' + }, + maxRounds: { + desc: '用於多輪脈絡和問題改寫的歷史輪數' + }, + models: { + chatGroupLabel: '思考 / 對話模型' + } + }, + agentSettings: { + systemPrompt: { + desc: '設定 Agent 的系統提示語,支持預留位置模板。預留位置會在運行時自動取代為實際內容。' + }, + allowedTools: { + desc: '當前 Agent 可使用的工具清單' + }, + temperature: { + desc: '控制模型輸出的隨機性,0 最確定,1 最隨機' + }, + rerankModel: { + desc: '搜尋結果重排序,統一不同來源的相關度分數' + }, + thinkingModel: { + desc: '用於 Agent 推論和規劃的 LLM 模型' + }, + maxIterations: { + desc: '限制 Agent 單次任務的推論步數。選「不限制」時會一直跑到模型自然結束或你手動停止。' + }, + modelRecommendation: { + title: '模型推薦' + } + }, + upload: { + uploadDocument: '上傳文件', + uploadFolder: '上傳資料夾', + onlineEdit: '線上編輯', + deleteRecord: '刪除記錄' + }, + uploadTasks: { + panelLabel: '上傳任務', + titleUploading: '正在上傳 {done}/{total}', + titleParsing: '正在解析 {done}/{total}', + titleDone: '全部完成', + titleDoneWithIssues: '{ok} 個完成,{bad} 個未成功', + titleCancelled: '上傳已取消', + destination: '上傳至「{name}」', + destinationMany: '上傳至 {count} 個知識庫', + remaining: '剩餘約 {time}', + eta: { + seconds: '{n} 秒', + minutes: '{n} 分鐘', + hours: '{n} 小時' + }, + hintUploading: '上傳完成前請不要關閉或重新整理頁面', + hintParsing: '檔案已全部上傳,解析在後台繼續,可以放心離開此頁面', + legend: { + ready: '可檢索', + active: '處理中', + waiting: '等待中', + failed: '失敗', + duplicate: '已存在' + }, + filterAll: '全部', + filterIssues: '未成功', + phaseWaiting: '等待上傳', + phaseSaving: '正在儲存…', + phasePending: '排隊解析', + phaseParsing: '解析中', + phaseFinalizing: '可檢索,後台最佳化中', + phaseReady: '已完成', + phaseUploadFailed: '上傳失敗', + phaseParseFailed: '解析失敗', + phaseDuplicate: '知識庫中已有相同檔案', + phaseCancelled: '已取消', + phaseDeleted: '已刪除', + cancel: '取消', + cancelAll: '全部取消', + retry: '重試', + retryFailed: '重試 {count} 個', + open: '查看', + collapse: '收起', + expand: '展開', + close: '關閉', + closeConfirm: '關閉後將取消剩餘 {count} 個檔案的上傳', + closeConfirmOk: '取消上傳', + closeConfirmKeep: '繼續上傳' + }, + time: { + today: '今天', + yesterday: '昨天', + last7Days: '近7天', + last30Days: '近30天', + lastYear: '近1年', + earlier: '更早', + pinned: '已置頂' + }, + platform: { + subtitle: '大型語言模型驅動的企業級知識框架', + description: 'RAG 檢索、智慧代理推論、Wiki 知識庫,讓文件真正被理解和運用', + rag: 'RAG 增強生成', + agent: 'ReAct 智慧代理', + wiki: 'Wiki 知識庫', + hybridSearch: '混合檢索', + multimodalParsing: '多模態文件解析', + hybridSearchEngine: '混合檢索 + 知識圖譜', + ragQandA: 'ReAct 智慧代理問答', + independentTenant: '獨立空間', + fullApiAccess: '完整 API 存取', + knowledgeBaseManagement: '知識庫管理', + carousel: { + agenticRagTitle: 'Agentic RAG', + agenticRagDesc: 'ReAct 推論 + 工具呼叫 + 多步思考', + hybridSearchTitle: '混合檢索策略', + hybridSearchDesc: 'BM25 + 向量 + 知識圖譜', + wikiTitle: 'Wiki 知識庫', + wikiDesc: '文件蒸餾為結構化互聯知識', + smartDocRetrievalTitle: '智慧文件檢索', + smartDocRetrievalDesc: 'PDF/Word/圖片多格式解析' + } + }, + font: { + uiFont: '界面字型', + uiFontDescription: '用於選單、正文、按鈕等界面大部分文字的字型', + monoFont: '程式碼字型', + monoFontDescription: '用於程式碼塊、終端命令、API 金鑰、檔案路徑等技術內容,每個字符等寬顯示,避免 0/O、1/l 混淆', + selectFont: '選擇字型', + sansPreview: '示例 Sample 字型 Font — Aa Gg Oo 0123', + monoPreview: 'const msg = \'Hello\'; // 0O1l', + fontSize: '字型大小', + fontSizeDescription: '整體縮放界面(文字、圖示、間距等),切換後立即生效', + size: { + small: '小', + normal: '正常', + large: '大' + }, + mono: { + system: '系統預設', + menlo: 'Menlo', + monaco: 'Monaco', + consolas: 'Consolas', + cascadia: 'Cascadia Code', + 'dejavu-mono': 'DejaVu Sans Mono', + 'liberation-mono': 'Liberation Mono', + monospace: '通用等寬' + }, + sans: { + system: '系統預設', + pingfang: '蘋方 PingFang SC', + georgia: 'Georgia 襯線', + yahei: '微軟雅黑 Microsoft YaHei', + times: 'Times New Roman 襯線', + 'noto-cjk': 'Noto Sans CJK', + 'dejavu-serif': 'DejaVu Serif 襯線', + 'sans-serif': '通用無襯線' + } + }, + theme: { + theme: '主題模式', + themeDescription: '選擇界面的顯示主題,支持跟隨系統自動切換', + light: '淺色', + dark: '深色', + system: '跟隨系統', + selectTheme: '選擇主題' + }, + general: { + title: '常規設定', + allSettings: '全部設定', + personalSettings: '個人設定', + helpAndDocs: '幫助與文件', + description: '設定語言、外觀等基礎選項', + settings: '設定', + close: '關閉設定' + }, + language: { + zhCN: '簡體中文', + zhTW: '繁體中文', + enUS: 'English', + ruRU: 'Русский', + koKR: '한국어', + jaJP: '日本語', + selectLanguage: '選擇語言', + language: '語言', + languageDescription: '選擇界面顯示語言', + languageSaved: '語言設定已儲存' + }, + model: { + reasoning: { + levels: { + off: '關閉', + auto: '自動', + minimal: '極低', + low: '低', + medium: '中', + high: '高', + xhigh: '極高', + max: '最大', + }, + levelDescriptions: { + off: '關閉思考,不寫入任何思考參數', + auto: '廠商預設強度,由模型自行決定思考深度', + minimal: '最少思考,回應最快', + low: '輕度思考', + medium: '中等思考強度', + high: '深度思考,回應更慢', + xhigh: '超高強度思考(僅部分模型支持)', + max: '最大思考預算(僅部分模型支持)', + }, + }, + modelName: '模型名稱', + defaultTag: '預設', + addModelInSettings: '前往全局設定新增模型', + loadFailed: '載入模型清單失敗', + selectModelPlaceholder: '請選擇模型', + searchPlaceholder: '搜尋模型...', + builtinTag: '內建', + editor: { + maxOutputTokensLabel: '最大輸出 tokens', + maxOutputTokensPlaceholder: '留空使用目錄預設', + maxOutputTokensDesc: '單次回覆的輸出上限。留空則沿用目錄中該模型的預設值。', + catalog: { + reasoning: '推論', + vision: '視覺', + hint: '可從廠商內建目錄選擇,也可直接輸入自定義模型名。', + }, + resolved: { + title: '實際呼叫方式', + empty: '填寫廠商與模型名後,這裡會顯示這個模型將被怎樣呼叫', + failed: '解析失敗', + protocol: '請求協議', + catalog: '能力來源', + catalogedYes: '內建模型檔案', + catalogedNo: '廠商通用預設(未收錄此模型)', + endpoint: '請求地址', + thinkingFormat: '思考開關傳參', + thinkingLevels: '可選思考強度', + noThinking: '該模型不支持思考', + }, + advanced: { + toggle: '進階', + api: { + label: '協議覆蓋', + auto: '自動(按廠商 / URL 推斷)', + desc: '強制使用指定的請求協議;一般無需修改。', + }, + remoteModelName: { + label: '遠端模型名', + placeholder: '留空與模型名相同', + desc: '實際傳送給廠商的模型 ID,與上面的模型名不同時填寫。', + }, + legacyThinking: { + label: '思考參數格式(舊設定)', + catalog: '遵循目錄預設(推薦)', + none: '不寫入思考參數', + desc: '此模型仍帶有舊版 thinking_control 設定。選擇「遵循目錄預設」後由目錄決定思考參數的寫法。', + }, + compat: { + label: '協議相容覆蓋(JSON)', + placeholder: "{'{'} \"max_tokens_field\": \"max_tokens\" {'}'}", + desc: '只在介面與目錄預設值不一致時填寫,只寫需要改的欄位。留空表示不覆蓋。', + docLink: '查看欄位說明', + invalid: 'JSON 格式不正確', + mustBeObject: '必須是 JSON 物件', + }, + }, + addTitle: '新增模型', + editTitle: '編輯模型', + sectionType: '模型類型', + typeLabel: '模型類型', + sectionSource: '模型來源', + sectionProvider: '接入設定', + sectionAdvanced: '進階選項', + sourceLabel: '模型來源', + sourceLocal: 'Ollama', + sourceRemote: 'API', + baseUrlLabel: 'Base URL', + displayNameLabel: '顯示名稱(可選)', + displayNamePlaceholder: '例如:客服問答模型', + displayNameDesc: '僅用於界面展示,實際呼叫仍使用上面的模型名稱。', + baseUrlPlaceholder: '例如:https://api.openai.com/v1', + baseUrlPlaceholderVllm: '例如:http://localhost:11434/v1', + baseUrlPlaceholderAsr: '例如:https://api.openai.com/v1', + apiKeyOptional: 'API Key(可選)', + apiKeyPlaceholder: '輸入 API Key', + customHeadersLabel: '自定義請求頭(可選)', + customHeadersDesc: '呼叫遠程模型 API 時附加的 HTTP 請求頭,常用於企業閘道鑑權、鏈路追蹤等情境;Authorization、Content-Type 等保留頭會被自動忽略。', + customHeadersAdd: '新增請求頭', + customHeadersKeyPlaceholder: 'Header 名稱', + customHeadersValuePlaceholder: 'Header 值', + testing: '測試中...', + testConnection: '測試連結', + downloadLabel: '下載: {keyword}', + refreshList: '重新整理清單', + dimensionLabel: '向量維度', + dimensionPlaceholder: '例如:1536', + checkDimension: '檢測維度', + dimensionDetected: '檢測成功,向量維度:{value}', + dimensionFailed: '檢測失敗,請手動輸入維度', + remoteDimensionDetected: '檢測到向量維度:{value}', + dimensionOverrideLabel: '自定義輸出維度', + dimensionOverrideDesc: '僅在確認該模型支持 dimensions 參數時開啟;預設只使用檢測到的實際維度。', + supportsVisionLabel: '支持視覺/多模態', + supportsVisionDesc: '模型是否支持圖片等多模態輸入', + contextWindowLabel: '脈絡視窗', + contextWindowPlaceholder: '預設 {value}', + contextWindowDesc: '該模型一次請求能容納的 token 數。智慧代理壓縮對話歷史會按此上限工作。留空則使用預設 200000(200K)。請按廠商文件填寫真實值,填大會導致壓縮不觸發、上遊直接拒絕請求。', + contextWindowDefaultHint: '未設定,使用預設 {value}', + contextWindowTokens: '{count} tokens', + maxConcurrencyLabel: '後台併發上限', + maxConcurrencyPlaceholder: '0 表示使用全局預設', + maxConcurrencyDesc: '限制文件入庫/富化等後台任務對該模型的併發呼叫數(按模型全副本共享)。0 或留空表示沿用全局預設;不影響交互式對話。', + dimensionHint: '模型已選擇,點擊"檢測維度"按鈕自動獲取向量維度', + loadModelListFailed: '載入模型清單失敗', + listRefreshed: '清單已重新整理', + fillModelAndUrl: '請先填寫模型標識和 Base URL', + remoteBaseUrlRequired: 'Remote API 類型必須填寫 Base URL', + unsupportedModelType: '不支持的模型類型', + saveAndClose: '儲存並關閉', + testDraftHint: '使用當前填寫的連結設定,無需提前儲存。', + testDraftEditHint: '使用當前填寫的連結設定;API Key 使用已單獨儲存的值。', + testStale: '設定已修改,請重新測試。', + connectionSuccess: '連結成功', + connectionFailed: '連結失敗', + connectionConfigError: '連結失敗,請檢查設定', + downloadStarted: '開始下載 {name}', + downloadCompleted: '{name} 下載完成', + downloadFailed: '{name} 下載失敗', + downloadStartFailed: '啟動下載失敗', + ollamaUnavailable: 'Ollama服務不可用,無法選擇本地模型', + ollamaNotSupportRerank: 'Ollama 不支持 ReRank 模型,請使用遠程介面設定', + goToOllamaSettings: '查看設定', + providerLabel: '服務商', + providerPlaceholder: '選擇模型服務商', + providerDocs: '查看 {provider} 的模型文件', + validation: { + extraFieldRequired: '請填寫 {name}', + modelNameRequired: '請輸入模型名稱', + modelNameEmpty: '模型名稱不能為空', + modelNameMax: '模型名稱不能超過100個字符', + baseUrlRequired: '請輸入 Base URL', + baseUrlEmpty: 'Base URL 不能為空', + baseUrlInvalid: 'Base URL 格式不正確,請輸入有效的 URL' + }, + modelNamePlaceholder: { + local: '例如:llama2:latest', + remote: '例如:gpt-4, claude-3-opus', + localVllm: '例如:llava:latest', + remoteVllm: '例如:gpt-4-vision-preview', + remoteAsr: '例如:whisper-1' + }, + description: { + chat: '設定用於對話的大型語言模型', + embedding: '設定用於文字向量化的內嵌模型', + rerank: '設定用於結果重排序的模型', + vllm: '設定用於視覺理解和多模態的視覺語言模型', + asr: '設定用於語音辨識和音訊轉錄的語音轉文字模型', + default: '設定模型資訊' + } + } + }, + error: { + networkError: '網路錯誤,請檢查您的網路連結', + requestTimeout: '請求超時,檔案較大或網路較慢時請稍後重試', + invalidCredentials: '使用者名或密碼錯誤', + tokenRefreshFailed: 'Token重新整理失敗', + pleaseRelogin: '請重新登入', + fileSizeExceeded: '檔案大小不能超過 {size}M!', + unsupportedFileType: '不支持的檔案類型!', + invalidFileType: '檔案類型錯誤!', + invalidImageLink: '無效的圖片連結', + missingKbId: '缺少知識庫ID', + tokenNotFound: '未找到登入權杖,請重新登入', + streamFailed: '流式連結失敗', + initialization: { + checkFailed: '檢查失敗', + testFailed: '測試失敗' + }, + tenant: { + listFailed: '獲取空間清單失敗', + searchFailed: '搜尋空間失敗', + getApiPrincipalConfigFailed: '獲取 API 使用者身份設定失敗', + updateApiPrincipalConfigFailed: '更新 API 使用者身份設定失敗', + createApiPrincipalTestTokenFailed: '生成 API 測試 Token 失敗', + updateFailed: '更新空間資訊失敗', + deleteFailed: '刪除空間失敗' + }, + model: { + createFailed: '建立模型失敗', + getFailed: '獲取模型失敗', + updateFailed: '更新模型失敗', + deleteFailed: '刪除模型失敗' + }, + auth: { + loginFailed: '登入失敗', + registerFailed: '註冊失敗', + getUserFailed: '獲取使用者資訊失敗', + getTenantFailed: '獲取空間資訊失敗', + updatePreferencesFailed: '更新個性化設定失敗', + refreshTokenFailed: '重新整理Token失敗', + logoutFailed: '登出失敗', + validateTokenFailed: 'Token驗證失敗' + } + }, + mcp: { + testResult: { + title: '測試結果: {name}', + connectionSuccess: '連結成功', + connectionFailed: '連結失敗', + toolsTitle: '可用工具', + resourcesTitle: '可用資源', + descriptionLabel: '描述', + schemaLabel: '參數結構', + emptyDescription: '該服務未提供工具或資源', + requireApproval: '需人工審核', + requireApprovalTip: '開啟後,Agent 呼叫該工具前會暫停並等待確認,適用於可能改庫/刪檔案等高危操作', + approvalSaveFailed: '儲存審核設定失敗', + toolEnabled: '啟用工具', + toolEnabledTip: '關閉後,Agent 不會再看到或呼叫該工具', + toolEnabledSaveFailed: '儲存工具開關失敗' + } + }, + system: { + title: '系統資訊', + sectionDescription: '查看系統版本資訊和使用者帳戶設定', + loadingInfo: '正在載入資訊...', + retry: '重試', + versionLabel: '應用版本', + versionDescription: '當前應用服務(weknora-app)的版本號', + frontendVersionLabel: 'UI 版本', + frontendVersionDescription: '當前 UI 界面(weknora-ui)的建構版本號', + versionMismatch: '與應用版本不一致', + buildTimeLabel: '建構時間', + buildTimeDescription: '系統建構的時間', + goVersionLabel: 'Go 版本', + goVersionDescription: '後端使用的 Go 語言版本', + startedAtLabel: '服務啟動時間', + startedAtDescription: '當前後端行程最近一次啟動的時刻', + uptimeLabel: '運行時長', + uptimeDescription: '自本次啟動以來的連續運行時間', + uptimeDays: '{n} 天', + uptimeHours: '{n} 小時', + uptimeMinutes: '{n} 分鐘', + uptimeSeconds: '{n} 秒', + dbVersionLabel: '資料庫版本', + dbVersionDescription: '當前資料庫遷移版本號', + dbMigrationFailedTag: '遷移失敗', + dbMigrationFailedTitle: '資料庫遷移失敗', + dbMigrationFailedDesc: '啟動時資料庫遷移未成功完成,部分表或索引可能未建立,會導致 Wiki、知識圖譜等功能例外。建議先查看排查文件自助修復;如仍無法解決,請透過下方連結回饋。', + dbMigrationViewDocs: '查看排查文件', + dbMigrationReportIssue: '無法修復?提交 Issue', + keywordIndexEngineLabel: '關鍵字索引引擎', + keywordIndexEngineDescription: '當前使用的關鍵字索引引擎', + vectorStoreEngineLabel: '向量存儲引擎', + vectorStoreEngineDescription: '當前使用的向量存儲引擎', + graphDatabaseEngineLabel: '圖資料庫引擎', + graphDatabaseEngineDescription: '當前使用的圖資料庫引擎', + unknown: '未知', + globalSettings: { + title: '系統設定', + description: '平台級運行時設定,儲存後立即對所有空間生效。僅系統管理員可見可改。', + loading: '載入中...', + empty: '暫無可設定的系統設定', + saving: '儲存中', + saved: '已儲存', + saveAnnouncement: '{label} 已儲存', + badgeRequiresRestart: '需重啟', + badgeSecret: '敏感', + badgeHighRisk: '高風險', + badgeOverride: '已覆蓋', + badgeOverrideTooltip: '該值已由管理員儲存到資料庫,覆蓋了環境變數與預設值', + modifiedAt: '上次修改:{value}', + tagInputPlaceholder: 'Enter新增條目,例:example.com / *.foo.com / 10.0.0.0/8', + audit: { + tabLabel: '稽核日誌', + description: '記錄平台級操作:系統設定變更、系統管理員授予/回收、配額批次同步等。按時間倒序展示。', + refresh: '重新整理', + retry: '重試', + loading: '載入中...', + end: '已經到底了。', + empty: '暫無平台級稽核事件。', + forbidden: '無權查看平台稽核日誌。', + systemActor: '系統', + drawer: { + sectionSummary: '事件概要', + sectionIdentifiers: '關聯標識', + sectionRequest: '請求資訊', + targetChange: '變更內容', + requestMethod: '請求方法' + }, + expanded: { + actorId: '操作人 ID', + targetUserId: '目標使用者 ID', + targetType: '目標類型', + targetId: '目標 ID', + details: '原始詳情' + }, + target: { + bulkQuota: '批次同步:預設存儲配額', + bulkQuotaDiff: '應用到 {count} 個空間({gb} GB)', + promoteIdempotent: '目標已是系統管理員(冪等)', + revokeNoop: '目標本就不是系統管理員(冪等)', + requiredRole: '需要角色:{role}', + valueNull: '(空)' + }, + outcome: { + success: '成功', + denied: '拒絕' + }, + action: { + 'system.setting_changed': '系統設定變更', + 'system.admin_promoted': '授予系統管理員', + 'system.api_key_created': '建立平台 API Key', + 'system.api_key_revoked': '吊銷平台 API Key', + 'system.admin_revoked': '回收系統管理員', + 'system.user_password_reset': '重設使用者密碼', + 'system.user_created': '建立使用者', + 'system.queue_task_retried': '重新執行失敗任務', + 'system.queue_task_deleted': '清除失敗任務記錄', + 'system.queue_task_run_now': '立即執行佇列任務', + 'system.queue_task_cancelled': '終止佇列任務', + 'system.queue_archived_purged': '清除全部失敗任務' + }, + columns: { + time: '時間', + actor: '操作人', + action: '事件', + target: '目標', + path: '請求', + outcome: '結果' + }, + actorRole: { + system_admin: '系統管理員' + }, + errors: { + generic: '載入稽核日誌失敗' + } + }, + bulkApply: { + label: '應用到所有現有空間', + tooltip: '儲存的值預設只對之後新建的空間生效;點擊此按鈕將當前值同步寫入所有現有空間。', + confirmBtn: '應用', + confirmBody: '將把所有現有空間的存儲配額覆蓋為 {value} GB。如有空間被運維單獨調整過的配額,也會一併被覆蓋。是否繼續?', + success: '已將 {count} 個空間的存儲配額更新為 {gb} GB', + failed: '應用到所有空間失敗' + }, + passwordReset: { + label: '重設使用者密碼', + description: '為忘記密碼的其他使用者設定新密碼。重設成功後,該使用者當前所有登入會話都會失效,需要使用新密碼重新登入。', + action: '重設密碼', + dialogTitle: '重設其他使用者的密碼', + warning: '這是高風險操作。請核對使用者電子信箱;出於安全考慮,不能在這裡重設自己的密碼。', + emailLabel: '使用者電子信箱', + emailPlaceholder: '輸入需要重設密碼的使用者電子信箱', + newPasswordLabel: '新密碼', + newPasswordPlaceholder: '請輸入新密碼', + confirmPasswordLabel: '確認新密碼', + confirmPasswordPlaceholder: '再次輸入新密碼', + confirmBtn: '重設', + success: '密碼已重設,該使用者的現有會話已失效', + failed: '重設密碼失敗', + }, + createUser: { + label: '建立使用者', + description: '開通一個新的本地使用者帳號。如果平台的預設空間模式設定為「自動建立個人空間」,該使用者會像自助註冊的使用者一樣,同時獲得一個個人空間。', + action: '建立使用者', + dialogTitle: '建立新使用者', + warning: '這是高風險操作。請仔細核對使用者名和電子信箱──它們將作為該使用者登入的唯一憑據。', + usernameLabel: '使用者名', + usernamePlaceholder: '2-50 個字符', + emailLabel: '電子信箱', + emailPlaceholder: '請輸入有效的電子信箱地址', + autoGenerateLabel: '自動生成隨機密碼', + newPasswordLabel: '新密碼', + newPasswordPlaceholder: '8-32 個字符,包含字母和數字', + confirmPasswordLabel: '確認新密碼', + confirmPasswordPlaceholder: '再次輸入新密碼', + confirmBtn: '建立使用者', + success: '使用者已建立', + successIdempotent: '使用者已存在,未做任何更改', + missingPassword: '使用者已建立,但未返回生成的密碼。請使用重設密碼來復原存取。', + failed: '建立使用者失敗', + validation: { + usernameRequired: '請輸入使用者名', + usernameLength: '使用者名長度必須為 2-50 個字符', + emailRequired: '請輸入電子信箱', + emailInvalid: '請輸入有效的電子信箱地址', + passwordRequired: '請輸入新密碼', + passwordLength: '密碼長度必須為 8-32 個字符', + passwordLetter: '密碼必須包含字母', + passwordNumber: '密碼必須包含數字', + confirmRequired: '請再次輸入新密碼', + passwordMismatch: '兩次輸入的密碼不一致' + }, + generated: { + successTitle: '使用者已建立', + successBody: '已為該使用者生成一個隨機密碼。此密碼只會顯示一次。', + usernameLabel: '使用者名', + emailLabel: '電子信箱', + passwordLabel: '生成的密碼', + copyBtn: '複製帳號資訊', + copySuccess: '帳號資訊已複製到剪貼簿', + acknowledgeBtn: '我已儲存密碼' + } + }, + admins: { + label: '系統管理員', + description: '擁有平台級權限的使用者。在右側輸入電子信箱並Enter即可提升使用者為管理員;點擊 × 即為撤銷其權限。當前你(自己)已是管理員,不在清單中顯示,也無法被自己撤銷。', + placeholder: '輸入使用者電子信箱並Enter', + loadFailed: '載入系統管理員失敗', + saveSuccess: '已更新系統管理員', + saveFailed: '更新系統管理員失敗', + confirm: { + revoke: { + header: '撤銷系統管理員', + body: '確認撤銷 {email} 的系統管理員權限?撤銷後該使用者將無法再存取任何系統級功能。', + confirmBtn: '撤銷' + }, + promote: { + header: '提升為系統管理員', + body: '確認將 {email} 提升為系統管理員?該使用者將獲得平台級權限,可存取所有空間、修改系統設定、管理其他管理員。', + confirmBtn: '提升' + } + } + }, + reset: { + label: '重設', + tooltip: '清除當前 UI 覆蓋,復原使用環境變數或內建預設值', + confirmBtn: '重設', + confirmBody: '確定要重設「{label}」嗎?該操作會刪除資料庫中的覆蓋值,回退到環境變數或內建預設值。', + success: '已重設為預設值', + failed: '重設失敗' + }, + messages: { + loadFailed: '載入系統設定失敗', + saveSuccess: '已儲存', + saveFailed: '儲存失敗' + }, + listConfirm: { + ssrf: { + whitelist: { + remove: { + header: '移除 SSRF 白名單條目', + body: '確認從 SSRF 白名單中移除 {entry}?移除後該條目將重新受 SSRF 防護攔截。', + confirmBtn: '移除' + }, + add: { + header: '新增 SSRF 白名單條目', + body: '確認把 {entry} 加入 SSRF 白名單?該條目比對到的主機 / IP / 網段會繞過 SSRF 防護,可能讓 Agent 存取內網服務,請僅在確知用途時新增。', + confirmBtn: '新增' + } + } + } + }, + confirm: { + confirmBtn: '確認儲存', + cancelBtn: '取消', + emptyValue: '(空)', + bodyAuthRegistrationMode: '即將把「{label}」改為:{value}\n\n如果切到 self_serve,公網任何人都可以註冊帳號 — 務必確認是預期行為。', + bodySandboxDockerEnabled: '打開後,空間管理員可以把沙箱指到本機 Docker。本機 docker.sock 等同宿主機 root,只適合已掛載 daemon 或配了 TLS 遠程 tcp:// 的私有化單機。' + }, + enumLabels: { + auth: { + default_tenant_mode: { + create_personal: '自動建立個人空間', + tenantless: '不自動建立空間' + }, + registration_mode: { + self_serve: '自助註冊(任何人可註冊)', + invite_register: '僅限邀請註冊(需有效邀請連結)', + invite_only: '禁止註冊(已有帳號仍可接受邀請)' + } + } + }, + keyDescriptions: { + model: { + max_concurrency: '後台任務(文件入庫/富化)對單個模型的預設併發上限,按模型 ID 全副本共享。每次呼叫實時讀取,修改後立即生效、無需重啟。0 或負數表示關閉預設限制(各模型仍會尊重自身在模型管理裡設定的上限)。僅影響後台任務,不影響交互式對話。' + }, + asynq: { + core_concurrency: '文件解析與手工重解析的每實例保底併發,可額外借用共享彈性池;修改後需重啟。', + postprocess_concurrency: '解析完成後的輕量收尾和富化扇出專用併發;修改後需重啟。', + enrichment_concurrency: '摘要、圖片、圖譜與問題生成的每實例保底併發,可額外借用共享彈性池;修改後需重啟。', + maintenance_concurrency: '資料源同步、批處理和清理任務的每實例併發,與使用者面流水線硬隔離;修改後需重啟。', + shared_concurrency: '核心解析與內容富化共同使用的每實例彈性併發,由有積壓的一側自動借用;修改後需重啟。', + wiki_concurrency: '每個服務實例的 Wiki 專用 Worker 併發數,與上遊任務池相互隔離。最小值為 1;修改後需重啟服務行程方可生效。' + }, + tenant: { + max_owned_per_user: '每個非超管使用者透過自助建立可擁有的最大空間數。每次建立空間時實時讀取,修改後立即生效。0 表示使用內建預設值 10;負數表示完全關閉限制(不建議在公開部署使用)。', + self_service_creation_enabled: '是否允許非超管使用者主動建立空間。關閉後,普通使用者只能透過邀請加入已有空間;跨空間超管仍可建立。修改後立即生效。', + default_storage_quota_gb: '新建空間時預設分配的存儲配額(GB),包含向量、原文、文字、索引等。僅在建立時讀取,修改後只對之後新建的空間生效,不會回寫已存在的空間。0 或負數表示使用內建預設值 10GB。', + auto_create_api_key: '為新空間自動生成 full_access API Key,並在建立回應中返回明文 token。僅用於相容依賴舊行為的集成;預設關閉,建議透過 API Key 管理顯式建立。', + auto_accept_invitation: '開啟後,空間管理員透過電子信箱邀請已註冊使用者時,對方會立即成為成員,不再經過收件匣確認。關閉時保持「發出邀請 → 被邀請人確認」流程。修改後立即生效。' + }, + ssrf: { + whitelist: 'SSRF 防護白名單。可填入 example.com / *.foo.com / 10.0.0.0/8 / 2001:db8::1。修改後立即生效。SSRF_WHITELIST_EXTRA 環境變數仍由部署方維護,不在此處覆蓋。' + }, + sandbox: { + docker_enabled: '是否允許 Docker 沙箱後端。本機 docker.sock 等同宿主機 root,預設關閉。僅系統管理員可打開;打開後立即生效,無需重啟。私有化單機且已掛載 daemon socket,或設定了帶 TLS 的遠程 tcp:// 時再啟用。' + }, + auth: { + registration_mode: '註冊模式。開放註冊允許任何人建立帳號;僅限邀請註冊要求有效邀請連結;禁止註冊不允許建立帳號,但已有帳號仍可接受邀請。儲存後立即生效。', + default_tenant_mode: '公開註冊後的空間初始化策略。create_personal 會自動建立個人空間並授予 Owner;tenantless 僅建立帳戶,使用者需要接受邀請或主動建立空間。只影響之後註冊的使用者。', + complex_password_enabled: '是否啟用複雜密碼。開啟後密碼必須包含大小寫字母、數字和特殊字符。修改後立即生效,只影響新註冊使用者或新密碼修改/重設操作。特殊字符包含:{specialChars}' + } + }, + keyLabels: { + model: { + max_concurrency: '模型預設併發上限' + }, + asynq: { + core_concurrency: '核心解析保底併發數', + postprocess_concurrency: '後處理編排併發數', + enrichment_concurrency: '內容富化保底併發數', + maintenance_concurrency: '維護與同步併發數', + shared_concurrency: '共享彈性併發數', + wiki_concurrency: 'Wiki Worker 併發數' + }, + tenant: { + max_owned_per_user: '每使用者最大空間數', + self_service_creation_enabled: '允許使用者自助建立空間', + default_storage_quota_gb: '新空間預設存儲配額 (GB)', + auto_create_api_key: '建立空間時自動生成 API Key', + auto_accept_invitation: '邀請已註冊使用者時自動加入' + }, + ssrf: { + whitelist: 'SSRF 防護白名單' + }, + sandbox: { + docker_enabled: '啟用 Docker 沙箱' + }, + auth: { + registration_mode: '註冊模式', + default_tenant_mode: '註冊預設空間策略', + complex_password_enabled: '啟用複雜密碼' + } + }, + runtime: { + title: '任務佇列運行時', + description: '後台任務佇列的實時負載,以及各獨立 worker 池的每實例併發設定。支持查看任務明細和安全管理,每 5 秒自動重新整理。', + refresh: '重新整理', + autoRefresh: '自動重新整理(每 5 秒)', + loading: '載入中...', + retry: '重試', + unavailableTitle: '任務佇列不可用', + unavailable: '當前部署未啟用 Redis / asynq 佇列(Lite 模式),無佇列可展示。', + empty: '暫無佇列資料', + detailsTitle: '佇列明細', + detailsDescription: '各處理通道的實時負載與等待情況。「最終失敗」表示任務超過重試上限,已停止自動執行。', + poolsTitle: 'Worker 池', + poolsDescription: '各階段擁有保底容量,核心解析與內容富化還可借用共享彈性池。', + perInstance: '卡片主值為叢集運行中/容量', + poolConfigured: '單實例設定 {value}', + poolInstances: '{value} 個實例', + poolUtilization: '利用率 {value}%', + queueCount: '{value} 個佇列', + weightShort: '權重 {value}', + footnote: '卡片主值為叢集運行中/實時容量;單實例設定修改後需重啟。共享彈性池只消費核心解析和內容富化佇列。', + updatedAt: '更新於 {value}', + models: { + title: '模型併發佔用', + description: '觀察後台任務實際進入模型服務時的併發佔用;上方是任務調度,這裡是模型服務限流,兩者處於不同處理階段。', + scope: '佔用為叢集全局 · 等待為當前實例', + disabled: '模型後台併發治理未啟用。可在全局設定中設定模型預設併發上限。', + empty: '暫無模型呼叫資料;模型首次執行後台任務後會出現在這裡。', + backgroundOnly: '僅統計後台任務,不包含交互式對話', + status: { + queued: '限流中', + full: '已滿載' + }, + columns: { + model: '模型 ID', + active: '呼叫中', + waiting: '限流等待', + usage: '併發用量' + } + }, + tasks: { + title: '任務明細 · {queue}', + description: '查看各狀態任務及其安全管理動作。定時、重試任務按最近執行時間優先,其餘狀態按時間倒序。', + listTitle: '{state}任務', + openAria: '查看{queue}中 {count} 個{state}任務', + unavailable: '當前部署不支持查看任務明細', + empty: '這個佇列當前沒有{state}任務', + loadError: '獲取任務明細失敗', + loadMore: '載入更多', + loadedSummary: '已載入 {count} 條,繼續下滑或點擊載入', + loadedAll: '已全部載入,共 {count} 條', + loadingMore: '正在載入更多…', + attempts: '執行 {current}/{max}', + unknownTarget: '未識別到關聯物件', + knowledgeBaseLabel: '知識庫 ID', + knowledgeLabel: '文件 ID', + taskIDLabel: '業務任務 ID', + tenantLabel: '空間 ID', + sourceLabel: '來源 ID', + targetLabel: '目標 ID', + sourceKBLabel: '來源知識庫', + targetKBLabel: '目標知識庫', + dataSourceLabel: '資料源 ID', + syncLogLabel: '同步記錄 ID', + knowledgeCountLabel: '文件數量', + enqueuedAt: '入隊時間', + startedAt: '開始時間', + nextProcessAt: '下次執行', + lastFailedAt: '最後失敗', + completedAt: '完成時間', + deadline: '執行截止', + worker: '執行實例', + health: '運行健康', + orphaned: '執行實例已失聯,等待復原', + cancel: '終止任務', + cancelConfirm: '將透過業務取消流程終止該任務及同一文件的相關佇列任務。確認終止?', + runNow: '立即執行', + runNowConfirm: '該任務將立即進入待執行佇列,重試次數不會重設。確認繼續?', + deleteRecord: '清除記錄', + deleteConfirm: '僅從當前佇列移除這條失敗記錄,不會執行或完成原任務,歷史日誌仍會保留。確認清除?', + purgeArchived: '清除全部失敗任務', + purgeArchivedConfirm: '將從當前佇列免洗移除全部 {count} 條失敗記錄,僅清理佇列裡的失敗任務,不影響運行中或排隊中的任務,也不會回滾已失敗文件的業務狀態。確認清除?', + purgeArchivedSuccess: '已清除 {count} 條失敗任務', + purgeArchivedError: '清除失敗任務失敗', + stateFilter: '按任務狀態篩選', + actionError: { + cancel: '終止任務失敗', + run_now: '立即執行任務失敗', + delete: '清除失敗記錄失敗' + }, + actionSuccess: { + cancel: '任務已終止', + run_now: '任務已進入待執行佇列', + delete: '失敗記錄已清除' + }, + guides: { + active: '運行中任務可查看執行實例、開始時間和截止時間。只有具備完整業務取消語義的任務才允許終止。', + pending: '排隊任務尚未被 worker 領取。終止操作會同步更新業務狀態,而不是只刪除 Redis 記錄。', + scheduled: '定時任務可提前立即執行;支持業務取消的文件任務也可以安全終止。', + retry: '請結合最後錯誤、重試次數和下次執行時間判斷是否立即執行或終止。', + archived: '請先修復失敗原因再立即執行。清除記錄不會完成原業務任務。', + completed: '這裡只展示設定了結果保留時間的近期完成任務,不提供管理動作。' + }, + states: { + active: '運行中', + pending: '排隊中', + scheduled: '定時執行', + retry: '重試中', + archived: '最終失敗', + completed: '已完成' + }, + taskTypes: { + documentProcess: '文件解析', + manualProcess: '手工重新處理', + temporaryDocumentProcess: '聊天附件解析', + postProcess: '文件後處理', + summary: '摘要生成', + tableSummary: '表格摘要生成', + question: '問題生成', + multimodal: '圖片多模態處理', + graph: '知識圖譜抽取', + sync: '資料源同步', + faqImport: 'FAQ 匯入', + batchReparse: '批次重新解析', + batchDelete: '批次刪除', + move: '文件移動', + indexDelete: '索引刪除', + kbClone: '知識庫複製', + kbDelete: '知識庫刪除', + wikiIngest: 'Wiki 內容生成', + wikiFinalize: 'Wiki 收尾處理' + } + }, + failedNotice: { + title: '{count} 個任務待處理', + description: '點擊下方表中紅色「最終失敗」數字查看原因,修復後可手動重試。' + }, + status: { + working: '處理中', + waiting: '等待中', + idle: '空閒', + actionRequired: '需處理', + retrying: '重試中', + paused: '已暫停' + }, + columns: { + queue: '佇列', + active: '運行中', + pending: '排隊', + scheduled: '定時', + retry: '重試', + archived: '最終失敗', + completed: '已完成', + latency: '最早等待', + status: '狀態' + }, + summary: { + title: '運行概覽', + active: '運行中', + pending: '排隊中', + retry: '重試中', + archived: '最終失敗' + }, + pools: { + core: '核心解析', + postprocess: '後處理編排', + enrichment: '內容富化', + maintenance: '維護與同步', + shared: '共享彈性', + wiki: 'Wiki 池' + }, + poolDescriptions: { + core: '文件解析與手工重解析的保底容量', + postprocess: '解析完成後的收尾與富化扇出', + enrichment: '摘要、圖片、圖譜與問題生成', + maintenance: '資料源同步、批處理與刪除清理', + shared: '由核心解析與內容富化按積壓借用', + wiki: 'Wiki 內容生成與全局收尾' + }, + queueNames: { + default: '文件解析', + chat_attachment: '對話附件解析', + postprocess: '後處理編排', + summary: '摘要生成', + sync: '資料源同步', + low: '維護與批處理', + multimodal: '多模態處理', + graph: '圖譜抽取', + question: '問題生成', + wiki: 'Wiki 處理' + }, + queueDescriptions: { + default: '文件解析、手工重解析', + chat_attachment: '會話內上傳附件解析', + postprocess: '解析收尾、富化扇出', + summary: '文件摘要、表格摘要', + sync: '手動與定時同步', + low: 'FAQ 匯入、批次重解析、刪除清理', + multimodal: '圖片 OCR、視覺描述', + graph: '切塊圖譜抽取', + question: '切塊問題生成', + wiki: '內容生成、索引收尾' + }, + errors: { + generic: '獲取佇列狀態失敗' + } + }, + runtimeTable: { + setting: '設定項與用途', + value: '當前值' + }, + sections: { + other: { + tab: '其他 {count}', + title: '其他設定', + description: '當前部署中未歸入標準分組的設定項。' + }, + security: { + tab: '網路安全 {count}', + title: '網路安全', + description: '管理 SSRF 白名單,以及是否允許 Docker 沙箱(本機 docker.sock 等同宿主機 root)。' + }, + runtime: { + tab: '運行與併發 {count}', + title: '運行與併發', + description: '設定後台任務池與模型服務的併發容量。', + restartHint: 'Worker 設定需重啟生效' + }, + tenant: { + tab: '空間預設值 {count}', + title: '空間預設值', + description: '設定新空間的初始配額與相容性行為,不會自動改寫已有空間。' + }, + access: { + tab: '帳戶與存取 {count}', + title: '帳戶與存取', + description: '管理系統管理員、公開註冊與使用者建立空間的規則。' + } + }, + priorityHint: { + disclosure: '設定來源與優先級', + tier1: '在此頁面儲存過的項(帶「已覆蓋」徽章)— 始終以這裡的值為準,環境變數會被忽略。', + tier2: '未在此處儲存過的項 — 如果環境變數裡有就用環境變數,否則用程式內建預設值。', + tier3: '若想讓某項重新由環境變數控制,點擊該行的「重設」按鈕即可清除當前 UI 設定。' + } + }, + messages: { + fetchFailed: '獲取系統資訊失敗', + networkError: '網路錯誤,請稍後重試' + } + }, + tenant: { + title: '空間資訊', + currentTenant: '當前空間', + switchTenant: '切換空間', + sectionDescription: '查看空間的詳細設定資訊', + statusActive: '活躍', + statusInactive: '未活化', + statusSuspended: '已暫停', + statusUnknown: '未知', + loadingInfo: '正在載入資訊...', + retry: '重試', + unknown: '未知', + formatError: '格式錯誤', + searchPlaceholder: '搜尋空間名稱或輸入空間 ID...', + noMatch: '未找到比對的空間', + switchSuccessTitle: '已切換空間', + switchSuccessContent: '你已進入 {name}', + loadTenantsFailed: '載入空間清單失敗', + loading: '載入中...', + loadMore: '載入更多', + api: { + title: 'API 資訊', + docLabel: 'API 文件', + docDescription: '查看完整的 API 呼叫文件和示例,', + openDoc: '打開文件', + userIdLabel: '使用者 ID', + userIdDescription: '您的唯一使用者標識', + usernameLabel: '使用者名', + usernameDescription: '您的登入使用者名', + emailLabel: '電子信箱', + emailDescription: '您的註冊電子信箱地址', + createdAtLabel: '註冊時間', + createdAtDescription: '帳戶建立的時間', + desktopPortLabel: '本地 API 連接埠(桌面版)', + desktopPortDescription: '填寫固定連接埠(如 37841)後,Chrome 擴展等工具可長期使用同一 API 地址;0 表示每次啟動隨機連接埠。儲存後請重啟應用生效。', + desktopPortSave: '儲存', + desktopPortSaved: '已儲存,請重啟應用後生效', + desktopPortSaveFailed: '儲存失敗', + desktopPortInvalid: '請輸入 0–65535 之間的連接埠', + desktopBindPublicLabel: '允許區域網路存取 API', + desktopBindPublicDescription: '開啟後內嵌服務監聽 0.0.0.0,同一區域網路內其他裝置可透過下方地址呼叫 API。存在資料暴露風險,請在防火牆與路由側自行做好存取控制;修改後需重啟應用。', + desktopBindPublicSaved: '已儲存,請重啟應用後生效', + desktopBindPublicSaveFailed: '儲存失敗', + lanUrlLabel: '區域網路 API 地址', + lanUrlDescription: '在已開啟「允許區域網路存取」且應用已重啟後顯示;若 IP 不準確,請在本機網路設定中查看實際 IPv4 後取代主機部分。', + lanUrlCopyTitle: '複製區域網路 API 地址', + lanUrlUnavailable: '當前已監聽所有網卡,但未能自動識別本機 IPv4。請在本機網路設定中查看區域網路地址,並手動串接為 http://你的IP:連接埠/api/v1。' + }, + messages: { + fetchFailed: '獲取空間資訊失敗', + networkError: '網路錯誤,請稍後重試' + }, + deleteDangerZone: { + title: '刪除當前空間', + desc: '刪除整個空間及其設定。刪除後,空間成員將無法繼續存取其中的知識庫、智慧代理與 API Key。', + button: '刪除空間', + confirmTitle: '刪除當前空間?', + confirmBody: '此操作將刪除空間「{name}」,並使其中的知識庫、智慧代理、成員與 API Key 不再可用。此操作不可復原。', + confirmHint: '請輸入空間名稱「{name}」以確認刪除。', + confirm: '刪除', + nameMismatch: '空間名稱不比對', + success: '空間已刪除', + failed: '刪除空間失敗' + }, + leaveDangerZone: { + title: '退出當前空間', + desc: '終止您在本空間的成員身份。退出後將無法存取本空間的知識庫與智慧代理,之後可被再次邀請加入。', + button: '退出空間' + }, + storage: { + quotaLabel: '存儲配額', + quotaDescription: '空間的總存儲空間配額', + usedLabel: '已使用存儲', + usedDescription: '已經使用的存儲空間', + usageLabel: '存儲使用率', + usageDescription: '存儲空間的使用百分比' + }, + details: { + idLabel: '空間 ID', + idDescription: '您所屬空間的唯一標識', + nameLabel: '空間名稱', + nameDescription: '您所屬的空間名稱', + descriptionLabel: '空間描述', + descriptionDescription: '空間的詳細描述資訊', + businessLabel: '空間業務', + businessDescription: '空間所屬的業務類型', + statusLabel: '空間狀態', + statusDescription: '空間當前的運行狀態', + createdAtLabel: '空間建立時間', + createdAtDescription: '空間建立的時間', + editName: '修改名稱', + editNamePlaceholder: '請輸入新的空間名稱', + editNameConfirm: '儲存', + editNameCancel: '取消', + editNameRequired: '空間名稱不能為空', + editNameSuccess: '空間名稱已更新', + editNameFailed: '更新空間名稱失敗', + editDescription: '修改描述', + editDescriptionPlaceholder: '請輸入新的空間描述', + editDescriptionSuccess: '空間描述已更新', + editDescriptionFailed: '更新空間描述失敗', + descriptionEmptyPlaceholder: '未填寫' + }, + create: { + action: '建立新空間', + dialogTitle: '建立新空間', + dialogSubtitle: '空間擁有獨立的知識庫與成員,你將自動成為新空間的所有者。', + nameLabel: '空間名稱', + namePlaceholder: '例如:我的新專案', + nameRequired: '請輸入空間名稱', + descriptionLabel: '描述(可選)', + descriptionPlaceholder: '簡單描述一下這個空間的用途', + submit: '建立', + cancel: '取消', + success: '已建立空間', + failed: '空間建立失敗', + disabled: '當前系統只允許透過邀請加入空間,不能自行建立空間。' + }, + switcher: { + menuLabel: '切換空間', + currentBadge: '當前', + homeTooltip: '我的空間', + empty: '你目前只屬於這一個空間' + } + }, + chat: { + memoryUsedCount: '本次使用了 {count} 條記憶', + memoryForget: '刪除這條記憶', + memoryForgotten: '已刪除這條記憶', + memoryForgetFailed: '刪除失敗', + memoryHint: '這些是助手在回答時看到的長期記憶,刪除後不會再被使用。', + suggestedQuestions: '你可以這樣問我', + followUpQuestions: '繼續問', + followUpQuestionsLoading: '載入推薦問題', + refreshSuggestedQuestions: '換一批', + thinking: '思考中...', + thinkingAlt: '正在思考', + conversationTime: { + today: '今天 {time}', + yesterday: '昨天 {time}', + thisYear: '{month}月{day}日 {time}', + otherYear: '{year}年{month}月{day}日 {time}', + }, + preparingAnswer: '正在準備回答…', + connectingModelAndGeneratingAnswer: '正在連結模型並生成回答…', + modelStillResponding: '模型回應較慢,仍在等待…', + deepThoughtCompleted: '已深度思考', + deepThoughtAlt: '深度思考完成', + referencesTitle: '參考了{count}個相關內容', + referencesDocCount: '引用了{count}篇文件', + referencesWebCount: '參考了{count}條網頁', + referencesDocAndWebCount: '引用了{docCount}篇文件和{webCount}條網頁', + referencesDrawerTitle: '參考來源', + referencesDrawerTitleWeb: '網頁來源', + referencesDrawerTitleDocs: '文件來源', + referencesDrawerTitleTools: '工具結果', + referencesDrawerTitleMixed: '參考來源', + referencesDrawerWebSection: '網頁', + referencesDrawerDocsSection: '知識庫文件', + referencesDrawerToolsSection: '工具', + referencesDrawerEmpty: '暫無參考來源', + sandbox: { + panelTitle: '沙箱可視化', + tabArtifacts: '產物', + tabTerminal: '終端', + tabDesktop: '桌面', + artifactsEmpty: '本會話尚未生成可下載的檔案', + artifactScope: '產物範圍', + artifactsCurrent: '本輪', + artifactsAll: '全部', + artifactsSearch: '搜尋檔名', + artifactsNoMatches: '沒有比對的檔案', + desktopNotStarted: '桌面尚未連結。連結後會接入本會話的沙箱環境。', + desktopStart: '連結桌面', + desktopStarting: '正在連結桌面…(首次約需 3–8 秒)', + desktopUnsupported: '當前沙箱設定不支持桌面。需要在工作區沙箱設定的模板清單裡選中帶桌面的映像,且後端為 Cube 或 E2B。', + desktopBusy: '本會話已有一個桌面連結。桌面同一時刻只允許一個連結,否則會出現兩個人搶同一套鍵鼠。', + desktopStartFailed: '桌面啟動失敗,可以重試。', + desktopRebuilt: '沙箱已因技能更新重建,原桌面及未儲存的內容已丟失。重新連結會得到一個全新桌面。', + desktopNeedsProvision: '本會話當前沒有運行中的沙箱環境。建立並連結會新建一個沙箱,並按工作區設定計費。', + desktopCreateAndStart: '建立並連結', + desktopPaused: '本會話的沙箱已暫停。連結桌面會喚醒它。', + desktopDisconnected: '桌面連結已斷開', + desktopIdleDisconnected: '桌面空閒已斷開,沙箱將按工作區 TTL 自行暫停。可重新連結。', + desktopRetry: '重新連結', + notStarted: '終端尚未啟動。啟動後會連結本會話的沙箱環境;若沙箱不存在或已暫停,將為你建立或喚醒它。', + paused: '本會話的沙箱已暫停。啟動終端會喚醒它。', + start: '啟動終端', + connecting: '正在連結沙箱…', + needsProvision: '本會話當前沒有運行中的沙箱環境。建立並啟動會新建一個沙箱,並按工作區設定計費。', + createAndStart: '建立並啟動', + noSandbox: '會話尚未建立沙箱,且當前智慧代理未設定沙箱後端,無法確定在哪個後端建立。請切換到設定了沙箱的智慧代理,或傳送一條需要執行程式碼的訊息。', + unsupported: '當前沙箱後端不支持交互終端', + disconnected: '連結已斷開', + retry: '重新連結', + sessionEnded: '終端會話已結束', + idleDisconnected: '終端空閒已斷開,沙箱將按工作區 TTL 自行暫停。可重新連結。', + authRevoked: '登入狀態已失效,終端已斷開。請重新登入後再連結。', + }, + questionMinimapTitle: '問答', + questionMinimapPosition: '第 {current} 輪 · 共 {total} 輪', + questionMinimapAriaLabel: '提問目錄', + questionMinimapAttachmentPlaceholder: '(附件)', + referenceChunkCount: '{count}個片段', + fallbackHint: '未從知識庫中檢索到相關內容,以上為模型直接回答', + truncatedHint: '回答在模型單次輸出上限處被截斷,以上為截斷前已生成的內容', + rewind: { + tooltip: '回滾到這裡', + confirmBody: '將刪除此條之後的對話。從使用者訊息回滾時會刪掉該問題本身,並填回輸入框。若有可用檢查點,工作區會一併回退。此操作不可復原。', + confirmButton: '回滾', + cancelButton: '取消', + success: '已回滾', + busy: '請等本輪迴答結束後再回滾', + noCheckpoint: '無法回滾:當前有沙箱,但沒有可回退的檢查點', + sandboxReplaced: '無法回滾:沙箱已更換,無法回退到舊檢查點', + reloadFailed: '對話已回滾,但未能重新載入歷史。若較早訊息缺失,請重新整理頁面', + failed: '回滾失敗,請重試', + skipped: '對話已回滾,工作區未改動', + skipNoSandbox: '對話已回滾,工作區未改動(當前沒有沙箱)', + skipNoCheckpoint: '對話已回滾,工作區未改動(沒有可回退的檢查點)', + }, + requestInfoTitle: '請求資訊', + requestInfoRequestId: 'Request ID', + requestInfoMessageId: '訊息 ID', + requestInfoSessionId: '會話 ID', + requestInfoUrl: '請求', + requestInfoSentAt: '發起時間', + requestInfoEmpty: '暫無請求資訊', + channelWeb: '網頁', + channelApi: 'API', + channelIm: 'IM', + chunkLabel: '片段{index}:', + navigateToDocument: '查看文件詳情', + referenceSourceBack: '全部引用', + referenceSourceView: '查看原文', + referenceSourceRelocate: '重新定位', + referenceSourceLocating: '正在定位引用位置…', + referenceSourceExact: "已精確定位原文片段", + referenceSourcePartial: "已標示核驗透過的原文片段,部分引用內容尚未比對", + referenceSourceBlock: "已定位到來源區域,尚未精確比對文字", + referenceSourceAmbiguous: "原文有多處相同內容,無法唯一定位", + referenceSourceStale: "原文或內容已更新,當前引用無法精確定位", + referenceSourcePrevious: "上一處引用", + referenceSourceNext: "下一處引用", + referenceSourceFoundPage: '已定位到第 {page} 頁', + referenceSourceNotFound: '未能精確定位引用內容,已為你打開原文', + referenceSourceOpenWeb: '打開原網頁並定位', + chunkIdLabel: '片段ID:', + documentIdLabel: '文件ID:', + faqIdLabel: 'FAQ ID:', + faqContainerIdLabel: '所屬文件ID:', + faqAnswersLabel: '答案:', + chunkOrdinal: '片段 {index}', + previewContent: '預覽內容', + noPlanSteps: '未提供具體步驟', + chunkIndexLabel: '片段 #{index}', + chunkPositionLabel: '(位置: {position})', + noRelatedChunks: '沒有找到相關片段', + noSearchResults: '沒有找到搜尋結果', + relevanceHigh: '高相關', + relevanceMedium: '中相關', + relevanceLow: '低相關', + relevanceWeak: '弱相關', + webSearchNoResults: '未找到搜尋結果', + otherSource: '其他來源', + webGroupIntro: '以下 {count} 條內容來自', + graphConfigTitle: '圖譜設定', + entityTypesLabel: '實體類型:', + relationTypesLabel: '關係類型:', + graphResultsHeader: '找到 {count} 條相關結果', + graphNoResults: '未找到相關的圖譜資訊', + unknownLink: '未知連結', + contentLengthLabel: '長度 {value}', + notProvided: '未提供', + promptLabel: '提示語', + errorMessageLabel: '錯誤資訊', + summaryLabel: '總結', + rawTextLabel: '原始文字', + collapseRaw: '收起原文', + expandRaw: '展開原文', + noWebContent: '未獲取到網頁內容', + webFetchStatusSuccess: '抓取成功', + webFetchStatusFailed: '抓取失敗', + webFetchStatusSkipped: '已跳過', + webFetchErrorCode: '錯誤碼', + webFetchRetryable: '可重試', + webFetchContentRange: '字符範圍 {start}–{end},共 {total} 字符', + webFetchPartialContent: '部分頁面內容', + webFetchSummaryFailed: '摘要失敗', + lengthChars: '{value} 字', + lengthThousands: '{value} 千字', + lengthTenThousands: '{value} 萬字', + noDatabaseRecords: '未找到比對的記錄', + nullValuePlaceholder: '', + chunkCountValue: '{count} 個片段', + documentDescriptionLabel: '文件描述:', + documentSourceLabel: '來源:', + documentFileLabel: '檔案資訊:', + documentMetadataLabel: '元資料', + documentInfoEmpty: '暫無文件資訊', + positionLabel: '位置:', + chunkPositionValue: '第 {index} 個片段', + contentLengthLabelSimple: '內容長度:', + fullContentLabel: '完整內容', + copyContent: '複製內容', + knowledgeBaseCount: '共 {count} 個知識庫', + noKnowledgeBases: '沒有可用的知識庫', + enterDescription: '輸入描述', + rawOutputLabel: '原始輸出', + wikiWritePageTitle: 'Wiki 頁面寫入', + wikiReplaceTextTitle: 'Wiki 文字取代', + wikiRenamePageTitle: 'Wiki 頁面重新命名', + wikiDeletePageTitle: 'Wiki 頁面刪除', + wikiActionCreated: '已建立', + wikiActionUpdated: '已更新', + wikiActionRenamed: '已重新命名', + wikiActionDeleted: '已刪除', + wikiFieldSlug: '頁面路徑', + wikiFieldTitle: '標題', + wikiFieldPageType: '類型', + wikiFieldSummary: '摘要', + wikiFieldOldText: '原文字', + wikiFieldNewText: '新文字', + wikiFieldOldSlug: '原路徑', + wikiFieldNewSlug: '新路徑', + wikiFieldAffectedPages: '受影響頁面', + wikiAffectedCount: '{count} 個頁面的連結已更新', + processError: '處理出錯', + sessionExcerpt: '會話摘錄', + noAnswerContent: '(無回答內容)', + manualSourcesHeading: '參考來源', + noMatchFound: '未找到比對的內容', + deleteSessionFailed: '刪除失敗,請稍後再試!', + imageTooMany: '最多上傳5張圖片', + imageTypeSizeError: '僅支持 JPG/PNG/GIF/WEBP 格式,單張不超過 10MB', + imageUploadTooltip: '上傳圖片(支持貼上/拖曳)', + attachmentUploadTooltip: '上傳附件(文件、音訊等)', + attachmentWithCount: '已上傳 {count} 個附件', + attachmentTooMany: '最多上傳 {max} 個附件', + attachmentTotalTooMany: '圖片和附件合計最多 {max} 個', + attachmentTooLarge: '檔案 {name} 超過 {max}MB 限制', + attachmentTypeNotSupported: '不支持的檔案類型:{name}', + attachmentUploading: '上傳中 {progress}%', + attachmentParsing: '正在解析', + attachmentReady: '解析完成', + attachmentUploadFailed: '附件上傳失敗', + attachmentParseFailed: '附件解析失敗', + attachmentStillProcessing: '附件 {name} 仍在解析,請稍候' + }, + knowledgeEditor: { + titleCreate: '新建知識庫', + titleEdit: '知識庫設定', + advanced: { + title: '進階設定', + description: '設定問題生成等進階功能', + multimodal: { + label: '多模態功能', + description: '啟用圖片等多模態內容的理解能力', + vllmLabel: 'VLLM 視覺模型', + vllmDescription: '用於多模態理解的視覺語言模型(必選)', + vllmPlaceholder: '請選擇 VLLM 模型(必選)', + descriptionLanguageLabel: '圖片描述語言', + descriptionLanguageDescription: '留空時跟隨文件語言;不再強制使用中文', + descriptionLanguageAuto: '自動跟隨文件語言', + customInstructionsLabel: '圖片解析要求', + customInstructionsDescription: '補充需要重點識別的視覺資訊,OCR 和 Markdown 格式協議保持不變', + customInstructionsPlaceholder: '例如:重點識別裝置銘牌、型號、告警程式碼和表格中的單位…', + imageAttrsLabel: '圖片屬性觀察', + imageAttrsDescription: '開啟後,解析時對每張圖片先「觀察屬性+描述」,再按屬性決定是否對圖內文字再跑一輪 OCR;關閉則沿用基礎模式:所有圖片逐張描述並全部 OCR', + imageAttrsSchemaLabel: '可觀察的圖片屬性', + imageAttrsSchemaDescription: '模型會觀察以下屬性(由後端登錄檔定義)以驅動 OCR 策略', + imageAttrsOcrConditions: '根據觀察到的屬性條件觸發 OCR', + imageAttrsOcrConditionsDesc: '當觀察到的屬性滿足以下條件時,對圖片進行 OCR', + imageAttrsOcrOnUnobserved: '圖片屬性觀察失敗時仍執行 OCR', + imageAttrsOcrOnUnobservedDesc: '當模型未能正確觀察到圖片屬性時,預設仍執行 OCR 兜底,以免漏掉正文文字;關閉則跳過。(採用 4B 等小參數視覺模型,或自定義的圖片解析提示語與系統提示語衝突時,可能造成觀察失敗;8B 及以上模型的失敗概率很低,不建議關閉)', + imagePipelineKbNote: '預設跟隨知識庫設定,可針對本次任務調整' + }, + tableMetadataInstructions: { + label: '表格元資料生成要求', + description: '為 CSV/Excel 摘要補充業務背景和欄位語義,幫助後續檢索理解表格內容', + placeholder: '例如:這是銷售訂單表,金額單位為元,status 欄位使用公司內部狀態碼…' + }, + questionGeneration: { + label: 'AI 問題生成', + description: '解析文件時呼叫大型語言模型為每個切塊生成相關問題,提高檢索召回率。啟用後會增加文件解析耗時。', + countLabel: '生成問題數量', + countDescription: '每個文件切塊生成的問題數量(1-10)', + instructionsLabel: '問題生成要求', + instructionsDescription: '指定問題面向的人群、情境和表達方式,系統仍維護穩定輸出格式', + instructionsPlaceholder: '例如:生成客服使用者常問的自然語言問題,避免考試題式表達…' + }, + profile: { + label: '自動生成知識庫描述', + description: '文件新增、刪除或摘要更新後,從文件畫像聚合自動生成知識庫描述。聚合本身不呼叫模型,僅當聚合結果變化時才發起一次小模型呼叫。', + modelLabel: '生成模型', + modelDescription: '留空時使用知識庫摘要模型。', + modelPlaceholder: '請選擇生成模型', + instructionsLabel: '描述生成要求', + instructionsDescription: '補充面向的讀者、需要保留的術語或表達風格,系統仍維護穩定的輸出格式。', + instructionsPlaceholder: '例如:面向售後客服,用通俗說法描述產品線,保留產品型號…' + }, + autoTag: { + label: '自動關聯標籤', + description: '文件解析完成後,從當前知識庫已有標籤中選擇合適標籤自動關聯。不會建立或刪除標籤,並會增加一次模型呼叫。', + modelLabel: '分類模型', + modelDescription: '留空時使用知識庫摘要模型。', + modelPlaceholder: '請選擇分類模型', + maxTagsLabel: '單篇文件最多標籤數', + maxTagsDescription: '每篇文件最多自動關聯 1-10 個已有標籤。', + skipIfTaggedLabel: '跳過已有標籤的文件', + skipIfTaggedDescription: '開啟後,上傳時已手動設定標籤的文件不再自動打標籤,避免覆蓋人工分類意圖。' + } + }, + asr: { + title: '音訊語音辨識', + description: '設定語音辨識(ASR),啟用後可上傳音訊檔案並整段轉寫為文字(常見格式:mp3、wav、m4a、flac、ogg 等)。暫不支持影片上傳。', + label: '啟用音訊語音辨識', + desc: '啟用後可上傳音訊到知識庫,系統自動將語音轉寫為文字並參與解析與檢索', + modelLabel: 'ASR 模型', + modelDescription: '用於音訊中語音轉文字的識別模型(如 OpenAI Whisper)', + modelPlaceholder: '請選擇 ASR 模型', + languageLabel: '音訊語言提示', + languageDescription: '可選;指定主要語種可提高部分 ASR 模型的識別穩定性,留空時自動檢測', + languagePlaceholder: '例如 zh、en,留空自動檢測' + }, + multimodal: { + title: '影像處理設定', + description: '設定影像內容理解能力,啟用後支持圖片等非文字內容的解析和檢索' + }, + chunking: { + title: '切塊設定', + description: '控制上傳文件在內嵌前的切分方式。預設值適用於大多數情境,僅在檢索品質例外時調整。', + sizeLabel: '切塊大小', + sizeDescription: '每個切塊的最大字符數(100-4000)。預設 512 ≈ 中文 300 tokens / 英文 100-130 tokens。FAQ 用 200-400,敘述性長文件用 1000-2000。', + characters: '字符', + overlapLabel: '切塊重疊', + overlapDescription: '相鄰切塊之間共享的字符數(0-500)。預設 80 ≈ 切塊大小的 15%,符合當前研究推薦。FAQ/結構化資料用 0,長篇敘述用 150-200。', + separatorsLabel: '分隔符', + separatorsDescription: '切分時優先使用的字符或字符串。優先級高的分隔符先嘗試;預設順序優先段落 → 句子 → 標點。', + separatorsPlaceholder: '選擇或自定義分隔符', + parentChildLabel: '父子切塊', + parentChildDescription: '兩級切塊:小的子塊用於向量比對(精準命中),大的父塊返回給 LLM(更豐富脈絡)。建議用於長文件(>10 頁);短 FAQ 可關閉以節省存儲。', + parentChunkSizeLabel: '父塊大小', + parentChunkSizeDescription: '返回給 LLM 的脈絡塊大小(512-8192)。預設 4096 ≈ 1000 英文 tokens,適合所有現代 LLM 脈絡視窗。', + childChunkSizeLabel: '子塊大小', + childChunkSizeDescription: '用於向量比對的內嵌塊大小(64-2048)。預設 384 ≈ 80 tokens,是 sentence-transformer / BGE 類內嵌模型的最佳點。', + strategyLabel: '切塊策略', + strategyDescription: '選擇文件的切塊方式。自動模式會分析每個文件的結構並選擇最佳策略。', + strategyPlaceholder: '選擇切塊策略(不填則按長度切分)', + overlapWarning: '重疊相對於切塊大小較大──切塊之間會共享大部分內容。', + advancedLabel: '進階選項', + tokenLimitLabel: '每塊 Token 上限', + tokenLimitDescription: '每個切塊的硬性 Token 上限(0-8192)。0 = 關閉(僅按字符數)。當內嵌模型 Token 上限較小時啟用:MiniLM (256 tok) 用 200,BGE/Cohere (512 tok) 用 400。現代內嵌器(OpenAI、Voyage、Jina-v3)支持 >2000 tokens,保持 0 即可。', + languagesLabel: '語言提示', + languagesDescription: '限制啟發式模式只識別選定的語言(DE/EN/ZH)。留空 = 自動檢測。同質化語料庫可顯式設定以避免跨語言誤比對。', + languagesPlaceholder: '自動檢測', + debug: { + toggle: '測試切塊效果', + toggleHint: '無需重新上傳即可對示例文字運行切塊器', + sampleLabel: '示例文字', + samplePlaceholder: '貼上 Markdown / 純文字片段以查看當前設定的切塊結果…', + presetLabel: '載入示例:', + runButton: '運行預覽', + loading: '正在對示例運行切塊器…', + errorPrefix: '預覽失敗', + selectedTier: '選定策略', + rejected: '被拒絕的層級', + contextHeader: '脈絡標題', + fallbackWarning: '策略鏈已窮盡 — 當前設定無法智慧切塊此內容', + stats: { + chunks: '塊', + truncated: '已截斷;總數 {total}' + }, + profile: { + lines: '行', + chars: '字符', + headings: 'Markdown 標題', + pageBreaks: '分頁符', + chapterMarkers: '章節標記', + languages: '語言' + }, + samples: { + markdown: 'Markdown 文件', + faq: 'FAQ 清單', + chapter: 'PDF 章節', + plain: '純文字' + } + }, + languageOptions: { + de: '德語', + en: '英語', + zh: '中文' + }, + strategies: { + legacy: { + label: '按長度切分', + tooltip: '忽略結構,僅按字符數和分隔符遞迴切分──原始行為。當上述策略對你的內容效果不佳時使用。' + }, + heuristic: { + label: '結構感知', + tooltip: '識別分頁符、編號章節、多語言章節標記(DE/EN/ZH)、全大寫標題等結構信號進行切分。適合沒有 Markdown 標題的 PDF / 掃描件。' + }, + heading: { + label: '按標題切分', + tooltip: '在 Markdown 標題(#、##、###)邊界處切分,每塊自動帶上所在標題路徑。適合結構清晰的 Markdown 文件。' + }, + auto: { + label: '自動', + tooltip: '文件分析器根據內容結構自動在「按標題切分」「結構感知」「按長度切分」之間選擇。' + } + }, + separators: { + doubleNewline: '雙換行 (\\n\\n)', + singleNewline: '單換行 (\\n)', + periodCn: '中文句號 (。)', + exclamationCn: '感嘆號 (!)', + questionCn: '問號 (?)', + semicolonCn: '中文分號 (;)', + semicolonEn: '英文分號 (;)', + space: '空格 ( )' + } + }, + models: { + title: '模型設定', + description: '為知識庫選擇合適的 AI 模型', + llmLabel: 'LLM 大型語言模型', + llmDesc: '用於總結和摘要的大型語言模型', + llmPlaceholder: '請選擇 LLM 模型(可選)', + embeddingLabel: 'Embedding 內嵌模型', + embeddingDesc: '用於文字向量化的內嵌模型', + embeddingPlaceholder: '請選擇 Embedding 模型', + embeddingLocked: '知識庫中已有檔案,無法修改 Embedding 模型', + embeddingOptional: '(可選)', + embeddingWikiOptionalDesc: '可選。設定後用於 Wiki 目錄歸類的相似度比對,讓新頁面更好地復用已有目錄;不設定則按完整目錄樹歸類。' + }, + faqExport: { + exportButton: '匯出', + exportCSV: '匯出 CSV', + exportJSON: '匯出 JSON', + exportSuccess: '匯出成功', + exportFailed: '匯出失敗' + }, + faqImport: { + title: '批次匯入 FAQ', + modeLabel: '匯入模式', + appendMode: '追加匯入', + replaceMode: '取代現有條目', + fileLabel: '選擇檔案', + fileTip: '支持 JSON / CSV / Excel。CSV/Excel 表頭:標籤(必填)、問題(必填)、相似問題(選填-多個用##分隔)、反例問題(選填-多個用##分隔)、機器人回答(必填-多個用##分隔)、是否全部回覆(選填-預設FALSE)、是否停用(選填-預設FALSE)、是否禁止被推薦(選填-預設False 可被推薦)。也支持舊錶頭「分類」及舊格式:standard_question、answers、similar_questions、negative_questions', + clickToUpload: '點擊上傳檔案', + dragDropTip: '或拖曳檔案到此處', + importButton: '匯入 FAQ', + deleteSuccess: '選中條目已刪除', + previewCount: '共解析 {count} 條記錄', + previewMore: '還有 {count} 條未展示', + importSuccess: '已匯入', + parseFailed: '解析檔案失敗', + invalidJSON: 'JSON 檔案格式不正確', + unsupportedFormat: '暫不支持該檔案格式', + selectFile: '請先選擇需要匯入的檔案', + downloadExample: '下載示例檔案', + downloadExampleJSON: '下載 JSON 示例', + downloadExampleCSV: '下載 CSV 示例', + downloadExampleExcel: '下載 Excel 示例' + }, + faq: { + title: '問答', + subtitle: '結構化問答管理,支持標準問、相似問和反例,精準比對使用者查詢,提升問答準確率', + description: '設定 FAQ 知識庫的索引策略和問答組織方式', + indexModeLabel: '索引方式', + indexModeDescription: '僅索引問題可提升精度,索引問答可提高召回率', + questionIndexModeLabel: '問題索引方式', + questionIndexModeDescription: '合併索引:標準問和相似問合併索引;分別索引:標準問和每個相似問獨立索引,檢索更精確但需要更多存儲', + entryGuide: 'FAQ 條目由標準問、相似問、反例和多個答案組成,可在知識庫詳情中批次匯入、編輯。', + tagDesc: '為 FAQ 條目選擇標籤', + tagPlaceholder: '請選擇標籤', + standardQuestion: '標準問', + standardQuestionDesc: '設定問題的標準表述,這是使用者最常問的問題形式。', + answers: '答案', + answersDesc: '提供完整準確的答案內容,可新增多個答案以覆蓋不同情境。', + similarQuestions: '相似問', + similarQuestionsDesc: '新增與標準問意思相同但表述不同的問題,幫助系統更好地比對使用者查詢。', + negativeQuestions: '反例', + negativeQuestionsDesc: '新增不應比對此答案的問題,用於排除誤比對的情況。', + editorCreate: '新增 FAQ 條目', + editorEdit: '編輯 FAQ 條目', + answerPlaceholder: '請輸入答案內容,支持多行文字,按 Ctrl+Enter 或點擊按鈕新增', + similarPlaceholder: '輸入相似問題後點擊加號新增', + negativePlaceholder: '輸入反例後點擊加號新增', + answerRequired: '請至少填寫一個答案', + emptyTitle: '暫無 FAQ 條目', + emptyDesc: '點擊上方"新增 FAQ 條目"按鈕開始建立', + searchPlaceholder: '搜尋問題和答案...', + searchTest: '檢索測試', + createGroup: '新建', + searchTestTitle: 'FAQ 檢索測試', + queryLabel: '查詢內容', + queryPlaceholder: '請輸入要檢索的問題', + vectorThresholdDesc: '範圍 0-1,預設 0.7', + matchCountLabel: '結果數量', + matchCountDesc: '範圍 1-50,預設 10', + searchButton: '開始檢索', + searching: '檢索中...', + searchResults: '檢索結果', + noResults: '未找到比對的 FAQ 條目', + matchedQuestion: '命中問題', + matchTypeEmbedding: '向量比對', + matchTypeKeywords: '關鍵字比對', + similarityThresholdLabel: '相似度閾值', + statusEnabled: '已啟用', + statusDisabled: '已停用', + statusEnableSuccess: 'FAQ 條目已啟用', + statusDisableSuccess: 'FAQ 條目已停用', + statusUpdateFailed: '更新狀態失敗', + recommended: '推薦', + recommendedEnabled: '已開啟推薦', + recommendedDisabled: '已關閉推薦', + recommendedDisableSuccess: 'FAQ 條目已關閉推薦', + recommendedUpdateFailed: '更新推薦狀態失敗', + batchUpdateTag: '批次設定標籤', + batchUpdateTagTip: '將為 {count} 個選中的條目設定標籤', + batchEnable: '批次啟用', + batchDisable: '批次停用', + batchDelete: '批次刪除', + confirmBatchDelete: '確認刪除選中的 {count} 個 FAQ 條目?刪除後將無法復原。', + confirmDelete: '確認刪除該 FAQ 條目?刪除後將無法復原。', + batchDeleteSuccess: '已刪除 {count} 個 FAQ 條目', + modes: { + questionOnly: '僅標準問/相似問', + questionAnswer: '標準問 + 答案', + combined: '合併索引', + separate: '分別索引' + } + }, + document: { + title: '文件', + subtitle: '支持點擊或拖曳上傳,多格式文件自動解析並智慧切塊,快速建構可檢索的知識庫' + }, + messages: { + loadModelsFailed: '載入模型清單失敗', + loadDataFailed: '載入知識庫資料失敗', + notFound: '知識庫不存在', + nameRequired: '請輸入知識庫名稱', + summaryRequired: '請選擇 Summary 模型', + multimodalInvalid: '多模態設定驗證失敗', + createSuccess: '已建立知識庫', + createFailed: '建立知識庫失敗', + missingId: '缺少知識庫 ID', + buildDataFailed: '資料建構失敗', + updateSuccess: '設定已儲存', + indexModeRequired: '請選擇 FAQ 的索引方式', + storageChangeConfirm: '知識庫中已有檔案,更改存儲引擎後舊檔案可能無法正常存取。是否確認更改?' + }, + share: { + description: '將知識庫共享給空間,讓空間成員可以存取和使用', + hintTitle: '共享說明', + addShare: '共享', + unshareConfirm: '確定要取消對「{name}」的共享嗎?', + tip1: '共享後,空間成員將根據設定的權限存取此知識庫', + tip2: '可編輯權限允許成員修改知識庫內容,唯讀權限僅允許檢索和問答' + }, + buttons: { + create: '建立知識庫', + save: '儲存設定', + saveAndClose: '儲存並關閉', + }, + footer: { + instantEffect: '此頁的更改即時生效,無需儲存', + }, + postCreateHint: { + title: '建立成功', + footer: '可繼續調整設定,設定共享與資料源,完成後點擊「儲存並關閉」。', + followUpDesc: '可在左側設定資料源,或在「共享管理」中發布到空間', + }, + wikiBrowser: { + editBtn: '編輯', + historyBtn: '歷史', + historyTitle: '版本歷史 · {title}', + deletePageBtn: '刪除', + deletePageConfirm: '確定要刪除頁面「{title}」嗎?刪除後可在回收週期內由管理員復原資料庫記錄,但頁面將從 Wiki 中消失。', + deletePageSuccess: '頁面已刪除', + deletePageFailed: '刪除頁面失敗', + editTitlePlaceholder: '頁面標題', + editSummaryPlaceholder: '一句話摘要(用於索引清單)', + editContentPlaceholder: 'Markdown 正文,支持 [[頁面連結]] 語法', + editSaveSuccess: '頁面已儲存', + editSaveFailed: '儲存失敗', + editConflictHint: '儲存衝突:頁面已被他人或系統更新至 v{ver}。你可以放棄本地修改載入最新版本,或覆蓋儲存(被覆蓋的版本會保留在歷史中)。', + editConflictReload: '載入最新版本', + editConflictOverwrite: '覆蓋儲存', + editSourceUser: '手動編輯', + editSourceAgent: 'AI 修改', + editSourceRevert: '版本回滾', + editSourcePipeline: '自動生成', + newPageBtn: '新建頁面', + newPageTitle: '新建 Wiki 頁面', + newPageTitleLabel: '標題', + newPageTitlePlaceholder: '請輸入頁面標題', + newPageSlugLabel: 'Slug(頁面地址)', + newPageSlugPlaceholder: '例如 concept/my-topic', + newPageSlugHint: '由字母/數字/中劃線組成,可用 / 分層,建立後不可修改', + newPageTypeLabel: '頁面類型', + newPageContentLabel: '正文(可選)', + newPageMissingFields: '請填寫標題和 Slug', + newPageSuccess: '頁面已建立', + newPageFailed: '建立頁面失敗', + revisionCurrent: '當前版本', + revisionCurrentHint: '這是頁面的當前版本,選擇左側的歷史版本可查看差異或回滾。', + revisionSelectHint: '選擇左側的版本查看內容', + revisionEmpty: '暫無歷史版本,頁面內容變化後會自動記錄快照', + revisionDiff: '對比當前', + revisionRaw: '查看原文', + revisionDiffCaption: 'v{from} → v{to}(紅色為該版本,綠色為當前)', + revisionDiffIncremental: '版本變更', + revisionDiffCumulative: '對比當前', + revisionDiffBasisLabel: '對比方式', + revisionViewModeLabel: '查看方式', + revisionLatestChangeHint: '上一版到當前版的變更', + revisionIncrementalHint: '產生 v{ver} 的變更', + revisionInitialRange: '初始 → v{ver}', + revisionInitialCreationHint: '初始建立內容', + revisionCumulativeHint: '該版本到當前版的累計變更', + revisionDiffIncrementalCaption: 'v{from} → v{to}(相鄰版本,紅色為舊、綠色為新)', + revisionDiffCumulativeCaption: 'v{from} → v{to}(距當前的累計變更)', + revisionFirstVersionHint: '這是首個版本,沒有上一版可對比。', + revisionDiffTitle: '標題', + revisionDiffSummary: '摘要', + revisionDiffContent: '正文', + revisionDiffEmpty: '此版本與當前在標題、摘要和正文上均無差異', + revisionLoadFailed: '載入版本歷史失敗', + revisionNotRetained: '該版本的快照未保留或已被清理', + revisionNotRetainedRange: 'v{ver} · 完整內容', + revisionNotRetainedHint: '上一版 v{prev} 沒有留存快照(升級前的歷史不記錄快照,舊快照也可能被自動清理),以下從空白開始展示 v{ver} 的完整內容。', + revertBtn: '回滾到此版本', + revertConfirm: '確定回滾到 v{ver} 嗎?當前內容會先儲存為歷史版本,回滾操作可再次復原。', + revertSuccess: '已回滾到 v{ver}', + revertFailed: '回滾失敗', + viewInGraph: '在圖譜中查看', + editingBadge: '編輯中', + pageActions: '頁面操作', + tabDocuments: '文件', + tabGallery: '畫廊', + tabDocumentsTip: '上傳和管理原始文件', + tabWikiTip: '由文件自動整理生成的 Wiki 頁面', + tabGalleryTip: '瀏覽從文件中解析出的全部圖片', + viewTabs: '知識庫檢視', + gallery: { + title: '畫廊', + allImages: '全部圖片', + count: '共 {count} 張', + countFiltered: '篩選出 {count} 張', + searchPlaceholder: '搜尋圖片描述或文字', + filters: '篩選', + clearFilters: '清除篩選', + searchIn: '搜尋範圍', + searchInHint: '關鍵字只在勾選的內容中比對', + attrSection: '圖片屬性', + attrHint: '「隱藏」不顯示帶該屬性的圖片;「始終顯示」即使被其他條件隱藏也保留', + verdictDefault: '不限', + verdictOff: '隱藏', + verdictOn: '始終顯示', + keywordsPlaceholder: '多個關鍵字用逗號分隔', + noAttrs: '暫無可篩選的屬性', + sort: '排序', + sortField: '排序依據', + sortOrder: '順序', + orderAsc: '遞增', + orderDesc: '遞減', + empty: '還沒有可瀏覽的圖片', + emptyHint: '文件中的圖片在解析完成後會出現在這裡', + emptyFiltered: '沒有符合條件的圖片', + imageLoadError: '圖片載入失敗', + noCaption: '暫無描述', + noOcr: '未識別到文字', + caption: '描述', + ocr: '圖中文字(OCR)', + attributes: '屬性', + source: '來源文件', + details: '詳細資訊', + dimensions: '尺寸', + status: '狀態', + openSource: '打開來源文件', + copy: '複製', + zoomIn: '放大 (+)', + zoomOut: '縮小 (-)', + zoomReset: '適應視窗 (0)', + actualSize: '原始尺寸', + rotate: '旋轉 (R)', + download: '下載', + openOriginal: '在新分頁打開', + toggleInfo: '圖片資訊 (I)', + viewerClose: '關閉 (Esc)', + prev: '上一張 (←)', + next: '下一張 (→)', + // Display names for the builtin attributes the gallery itself + // declares. Attributes contributed by other sources fall back to the + // pipeline's own wording (see the imageAttr namespace). + attr: { + builtin_caption: '描述', + builtin_caption_description: '模型生成的圖片描述', + builtin_ocr_text: 'OCR 文字', + builtin_ocr_text_description: 'OCR 從圖片中提取的文字', + builtin_created_at: '建立時間', + builtin_created_at_description: '所屬文件片段的建立時間', + builtin_updated_at: '更新時間', + builtin_updated_at_description: '所屬文件片段的最後更新時間', + builtin_is_enabled: '啟用狀態', + builtin_is_enabled_description: '所屬文件片段是否參與檢索', + builtin_is_enabled_value_true: '已啟用', + builtin_is_enabled_value_false: '已停用', + }, + }, + tabGraph: '圖譜', + tabGraphTip: 'Wiki 頁面之間的引用關係圖(即頁面連結圖譜),與「知識庫設定 → 知識圖譜」中基於 LLM 抽取的實體-關係圖譜不是同一個概念', + searchPlaceholder: '搜尋 Wiki 頁面...', + searchNoResults: '沒有找到比對的頁面', + viewModeToggle: '切換目錄檢視', + viewTree: '樹狀檢視', + viewList: '清單檢視', + newRootFolder: '新建目錄', + newSubfolder: '新建子目錄', + folderActions: '目錄操作', + folderNamePlaceholder: '請輸入目錄名稱', + createFolderSuccess: '目錄已建立', + createFolderFailed: '建立目錄失敗', + movePageSuccess: '頁面已移動', + movePageFailed: '移動頁面失敗', + renameFolder: '重新命名目錄', + renameFolderSuccess: '目錄已重新命名', + renameFolderFailed: '重新命名目錄失敗', + deleteFolder: '刪除目錄', + deleteFolderConfirm: '確定要刪除目錄「{name}」嗎?', + deleteFolderSuccess: '目錄已刪除', + deleteFolderFailed: '刪除目錄失敗', + deleteFolderNotEmpty: '目錄非空,請先移除其中的頁面和子目錄', + moveFolderSuccess: '目錄已移動', + moveFolderFailed: '移動目錄失敗', + moveFolderIntoSelf: '不能將目錄移動到自身或其子目錄中', + moveConfirm: '移動到「{target}」?', + moveConfirmTitle: '確認移動', + rootFolderLabel: '根目錄', + filterSummary: '摘要', + filterKnowledge: '知識', + filterEntity: '實體', + filterConcept: '概念', + filterSynthesis: '綜合', + filterComparison: '對比', + legendFamiliar: '你常用的資料', + emptyTitle: '暫無 Wiki 頁面', + emptyDesc: '上傳文件並啟用 Wiki 後將自動生成知識頁面', + selectPageHint: '從左側選擇一個頁面查看內容', + version: 'v{ver}', + aliases: '別名', + linkedFrom: '被連結', + sources: '來源文件', + graphEmpty: '載入圖譜中...', + fitView: '適應螢幕', + indexTitle: '索引', + loading: '載入中…', + loadMoreShort: '載入更多', + indexOverviewTag: '分類目錄', + indexEmpty: '暫無 Wiki 頁面,請先上傳文件', + graphNoData: '暫無圖譜資料,請先上傳文件(這裡展示的是 Wiki 頁面之間的連結關係,與「知識庫設定 → 知識圖譜」中的實體-關係圖譜不同)', + showArrows: '顯示箭頭', + hideArrows: '隱藏箭頭', + expandNeighbors: '展開鄰居', + bloomNeighbors: '疊加鄰居', + growFrontier: '擴張邊緣 ({count})', + growFrontierTitle: '一鍵展開當前所有 {count} 個帶虛線環的節點', + cardEgoTitle: '當前焦點', + cardOverviewTitle: '全庫概覽', + cardOverviewPrimary: '{returned} / {total} 個節點', + cardOverviewHintTruncated: '按兩下任意節點聚焦到該節點的子圖', + cardOverviewHintFull: '已展示知識庫全部節點', + cardRelatedNodes: '{count} 個相關節點', + helpButtonTitle: '操作幫助', + helpTitle: '畫布操作', + helpClickAction: '單擊', + helpClickDesc: '打開節點詳情', + helpDblClickAction: '按兩下', + helpDblClickDesc: '以該節點為中心聚焦', + helpShiftClickAction: 'Shift + 單擊', + helpShiftClickDesc: '疊加該節點鄰居到畫布', + helpHoverPlusAction: '懸浮 → ⊕', + helpHoverPlusDesc: '同 Shift + 單擊', + helpDragAction: '拖曳節點', + helpDragDesc: '手動調整節點位置', + helpPanAction: '拖曳空白', + helpPanDesc: '平移畫布', + helpZoomAction: '滾輪', + helpZoomDesc: '縮放畫布', + neighborsProgress: '已顯示鄰居 {visible}/{total}(還有 {hidden} 個未載入)', + neighborsAllShown: '全部 {total} 個鄰居已在圖中(可點"展開鄰居"聚焦到該節點子圖)', + neighborsNone: '該節點沒有連結鄰居', + neighborsCenterUnreachable: '已顯示鄰居 {visible}/{total}(還有 {hidden} 個無法連通:可能是死鏈、被篩選或已刪除)', + neighborsOverviewHidden: '已顯示鄰居 {visible}/{total}({hidden} 個不在概覽範圍,點"展開鄰居"以此為中心查看)', + backToOverview: '返回概覽', + queueStatus: 'Wiki 佇列中 {count} 個待處理任務', + issueTitle: '此頁面存在 {count} 個待處理的知識衝突或錯誤', + issueFixBtn: 'AI 一鍵修復', + issueMixed: '資訊混雜', + issueConflict: '事實衝突', + issueOutdated: '資訊過時', + issueAttention: '需要追蹤', + issueReportedBy: '由 {reporter} 報告', + issueAiLinter: 'AI 巡檢', + issueIgnore: '忽略誤報', + globalIssuesTitle: '全庫待修復內容問題', + globalIssuesCount: '待修復內容問題: {count} 項', + globalIssuesEmpty: '暫無待處理的內容問題', + issuePagePrefix: '頁面: ', + issueGoFix: '去處理', + fixAssistantTitle: 'Wiki 智慧修復助手', + issueFixSuggestions: '內容最佳化建議 ({count})', + issueFixSingle: '修復', + fixStartError: '啟動修復助手失敗', + issueFixPromptSingle: '請修復頁面 [[{slug}]] 上的問題 (ID: {id})。', + issueFixPromptAutoStart: '請修復頁面 [[{slug}]] 上的以下問題:' + }, + indexing: { + title: '索引策略', + description: '設定文件上傳後的處理管道,可以獨立開啟或關閉每種索引方式', + searchTitle: 'RAG 檢索', + searchDesc: '對文件進行切塊、向量化和關鍵字索引,支持混合檢索', + wikiTitle: 'Wiki 知識庫', + wikiDesc: '自動生成互相關聯的 Wiki 知識頁面,建構結構化知識體系', + graphTitle: '知識圖譜', + graphDesc: '提取實體和關係,建構知識圖譜支持圖譜檢索', + atLeastOne: '至少需要開啟一種索引策略', + embeddingRequired: 'RAG 檢索需要設定 Embedding 模型', + lockedTip: '知識庫已有內容,索引策略暫不支持調整。如需變更,請先清空知識庫。', + rebuildConfirmTitle: '重建索引', + rebuildConfirmBody: '索引策略已變更,是否對已有的 {count} 篇文件重新處理?這可能需要一些時間。', + rebuildSuccess: '已提交重建任務,共 {count} 篇文件', + rebuildSkip: '稍後可在資料源中手動觸發重建' + }, + wiki: { + title: 'Wiki 設定', + synthesisModelLabel: 'Wiki 合成模型', + synthesisModelPlaceholder: '選擇用於 Wiki 生成的 LLM 模型', + synthesisModelTip: '不設定時將回退使用摘要模型', + extractionGranularityLabel: '提取粒度', + contentInstructionsLabel: 'Wiki 內容生成要求', + contentInstructionsTip: '控制摘要、頁面和首頁的表達重點;引用、合併與防幻覺規則由系統固定維護。修改後需重新解析才能影響已有內容。', + contentInstructionsPlaceholder: '例如:使用法務審閱口吻,優先展示責任主體、時間軸和風險提示…', + extractionInstructionsLabel: 'Wiki 提取重點', + extractionInstructionsTip: '說明應重點識別的領域實體和概念,不會取代系統的 JSON 與引用協議。', + extractionInstructionsPlaceholder: '例如:重點識別產品、版本、組織、負責人和關鍵技術概念…', + extractionGranularityTip: '控制每篇文件抽取的 Wiki 實體/概念數量。粒度越細,索引越聚焦;粒度越粗,索引越詳盡', + granularityFocused: '聚焦', + granularityStandard: '標準', + granularityExhaustive: '詳盡', + granularityFocusedHint: '只抽取文件的主角(如履歷 → 人物和專案)。最乾淨,但可能漏掉次要實體。', + granularityStandardHint: '抽取主角 + 被詳細描述的次要實體/概念。跳過一帶而過的通用名詞。適合大多數情境。', + granularityExhaustiveHint: '抽取所有可識別的命名實體與概念,包括一帶而過的技術棧。適合將知識庫當作術語表使用。' + }, + basic: { + title: '基本資訊', + description: '設定知識庫的名稱和描述資訊', + kbId: '知識庫 ID', + kbIdDesc: 'API 集成時可使用此 ID 指定知識庫', + typeLabel: '知識庫類型', + typeDocument: '文件', + typeFAQ: '問答', + typeDescription: 'FAQ 類型適合結構化問答資料;文件型支持檔案解析與切塊;Wiki 類型由 LLM 自動建構互鏈知識頁面。', + nameLabel: '知識庫名稱', + namePlaceholder: '請輸入知識庫名稱', + descriptionLabel: '知識庫描述', + descriptionPlaceholder: '請輸入知識庫描述(可選)', + profile: { + title: 'AI 生成描述', + hint: '由文件畫像聚合生成,不會覆蓋上方手寫描述;智慧代理會同時讀取兩者來判斷問題是否該在本知識庫中檢索。', + empty: '尚未生成。上傳文件並生成摘要後,點擊下方按鈕即可生成。', + noDocuments: '知識庫中還沒有已解析完成的文件。', + questions: '典型問題', + generate: '生成 AI 描述', + regenerate: '重新生成', + adopt: '用作知識庫描述', + generated: 'AI 描述已生成', + generateFailed: 'AI 描述生成失敗', + adopted: '已填入知識庫描述,儲存後生效', + failed: '上次生成失敗:{error}', + generatedAt: '生成於 {time} · 基於 {count} 篇文件' + } + }, + errors: { + vectorStoreBindingInvalid: '無法使用所選向量存儲。請選擇其他存儲或使用系統預設值。', + vectorStoreUnavailable: '所選向量存儲當前不可用。請在設定 → 向量存儲中檢查其連結設定。' + }, + sidebar: { + basic: '基本資訊', + models: '模型設定', + vectorStore: '向量存儲', + chunking: '切塊設定', + storage: '存儲引擎', + advanced: '進階設定', + faq: 'FAQ 設定', + graph: '知識圖譜', + multimodal: '影像處理', + asr: '音訊處理', + datasource: '資料源', + share: '共享管理', + activity: '活動記錄' + }, + navGroups: { + basic: '基礎', + processing: '索引與解析', + data: '存儲與資料', + integration: '發布集成', + management: '管理與稽核' + }, + activity: { + title: '活動記錄', + description: '查看這個知識庫的重要變更與後台任務入口,記錄預設遵循稽核日誌保留策略。', + allOutcomes: '全部結果', + allActions: '全部操作', + refresh: '重新整理', + retry: '重試', + empty: '暫無活動記錄', + emptyFiltered: '沒有比對的活動記錄', + clearFilters: '清除篩選', + loadingMore: '載入中…', + end: '沒有更早的記錄了', + loadFailed: '活動記錄載入失敗', + systemActor: '系統觸發', + actorWithAPIKey: '{actor} · API Key · {name}', + actorAPIKey: 'API Key · {name}', + knowledgeBase: '知識庫', + countItems: '共 {count} 項', + titleWithCount: '{title} 等 {count} 項', + importSummary: '成功 {success} / 失敗 {failed} / 跳過 {skipped}', + detailValues: { + user: '使用者發起', + manual: '手動觸發', + schedule: '定時調度', + system: '系統觸發', + pending: '待處理', + completed: '已完成', + partial: '部分完成', + canceled: '已取消', + failed: '失敗', + enqueue: '任務提交', + reuse_vectors: '復用向量', + reparse: '重新解析', + viewer: '唯讀', + editor: '可編輯', + admin: '管理', + append: '追加', + replace: '覆蓋' + }, + outcomes: { + accepted: '已受理', + success: '成功', + failed: '失敗', + partial: '部分完成', + canceled: '已取消', + denied: '已拒絕' + }, + actions: { + 'kb.created': '建立知識庫', + 'kb.updated': '更新知識庫', + 'kb.deleted': '刪除知識庫', + 'kb.duplicated': '複製知識庫', + 'kb.clone_started': '開始克隆', + 'kb.clone_completed': '完成克隆', + 'kb.clone_failed': '克隆失敗', + 'knowledge.created': '新增知識', + 'knowledge.updated': '更新知識', + 'knowledge.deleted': '刪除知識', + 'knowledge.batch_deleted': '批次刪除知識', + 'knowledge.reparse_started': '開始重新解析', + 'knowledge.parse_canceled': '取消解析', + 'knowledge.move_started': '開始移動知識', + 'knowledge.move_completed': '完成移動知識', + 'knowledge.move_failed': '移動知識失敗', + 'tag.created': '建立標籤', + 'tag.updated': '更新標籤', + 'tag.deleted': '刪除標籤', + 'datasource.created': '建立資料源', + 'datasource.updated': '更新資料源', + 'datasource.deleted': '刪除資料源', + 'datasource.sync_started': '開始同步資料源', + 'datasource.sync_completed': '資料源同步完成', + 'datasource.sync_failed': '資料源同步失敗', + 'datasource.paused': '暫停資料源', + 'datasource.resumed': '復原資料源', + 'kb.share_added': '新增共享', + 'kb.share_permission_changed': '修改共享權限', + 'kb.share_removed': '移除共享', + 'wiki.content_changed': '更新 Wiki 內容', + 'faq.import_started': '開始匯入 FAQ', + 'faq.import_completed': '完成匯入 FAQ', + 'faq.import_failed': '匯入 FAQ 失敗' + }, + detailFields: { + task_id: '任務 ID', + trigger: '觸發方式', + processing_status: '處理狀態', + source_kb_id: '來源知識庫 ID', + target_kb_id: '目標知識庫 ID', + sync_log_id: '同步記錄 ID', + mode: '執行模式', + attempt: '處理批次', + count: '專案數', + total: '總數', + processed: '已處理', + failed: '失敗數', + skipped: '跳過數', + failure_stage: '失敗階段' + }, + targets: { + knowledge_base: '知識庫', + knowledge: '知識', + faq_entry: 'FAQ 條目', + knowledge_tag: '標籤', + data_source: '資料源', + knowledge_base_share: '共享', + knowledge_move: '知識移動', + wiki: 'Wiki' + }, + drawer: { + sectionSummary: '摘要', + sectionIdentifiers: '標識符', + sectionTask: '任務資訊', + targetChange: '變更詳情' + }, + expanded: { + targetType: '物件類型', + targetId: '物件 ID', + actorId: '發起人 ID', + apiKeyName: 'API Key 名稱', + apiKeyId: 'API Key ID', + details: '詳情' + }, + columns: { + time: '時間', + action: '操作', + target: '物件', + actor: '發起人', + outcome: '結果' + } + } + }, + embedPublish: { + create: '新建內嵌通路', + channelsTitle: '內嵌通路', + disabled: '已停用', + empty: '暫無內嵌通路', + allowedOrigins: '域名白名單', + embedCode: '內嵌程式碼', + widgetCode: '浮窗指令碼', + copyCode: '複製程式碼', + channelKey: '通路金鑰', + channelKeyDesc: '用於第三方網站接入的長期金鑰,請妥善保管', + channelKeyHint: '載入通路金鑰失敗,請關閉後重新打開或重新整理頁面重試。', + channelKeyLoadFailed: '載入通路金鑰失敗', + channelKeyUnavailable: '金鑰不可用', + resetKeyTitle: '重設通路金鑰', + resetKeyConfirmOk: '確認重設', + resetKeyConfirmBody: '重設後,舊的通路金鑰會立即失效,所有已部署的內嵌程式碼必須更換為新金鑰才能繼續存取。此操作不可復原。', + resetKeySuccess: '通路金鑰已重設,新金鑰已顯示在輸入框中', + resetKeyFailed: '重設通路金鑰失敗', + copyChannelKeyTitle: '複製通路金鑰', + revealKey: '顯示金鑰', + hideKey: '隱藏金鑰', + createTitle: '新建內嵌通路', + name: '名稱', + nameDesc: '後台管理用,用於清單與通路識別', + namePlaceholder: '例如:官網客服', + nameDefaultHint: '預設為「智慧代理名 · 網頁內嵌」,可自行修改;留空儲存時也會使用該名稱', + defaultChannelName: '網頁內嵌', + defaultChannelNameWithAgent: '{agent} · 網頁內嵌', + welcomeMessage: '歡迎語', + welcomePlaceholder: '你好,有什麼可以幫您?', + welcomeMessageDesc: '訪客打開內嵌聊天後、尚未發言時展示;留空則不顯示', + showSuggestedQuestions: '推薦問題', + showSuggestedQuestionsDesc: '訪客未發言前展示快捷提問,內容來自智慧代理設定與關聯知識庫', + originsHint: '填寫允許內嵌的宿主網站來源(A),不是 WeKnora 地址(B)。每行一個完整 Origin,如 https://shop.example.com;至少一項,支持 *.example.com 子域通配', + originsRequired: '請至少填寫一個域名白名單', + originsInvalid: '域名格式無效:{origin}', + originsWildcardProd: '生產環境不允許使用萬用字元 *', + originsPlaceholder: 'https://shop.example.com', + rateLimitLabel: '每分鐘請求上限', + rateLimitDesc: '按訪客 IP 統計,每分鐘最多允許的內嵌介面請求次數;超出後暫時拒絕存取,預設 30。', + rateLimitDayLabel: '每日請求總上限', + rateLimitDayDesc: '整個通路每天(跨所有訪客 IP)允許的請求總數;用於限制發布 Token 被複製後被刷量的成本,預設 10000。', + publishTokenWarning: '發布 Token 會以明文出現在內嵌頁面源碼中,任何存取該網站的人都能看到,請將其視為「可公開金鑰」而非機密:切勿把含敏感資料的智慧代理做成內嵌通路;務必設定域名白名單與請求上限;Token 洩漏時可隨時「重設 Token」作廢舊值。', + primaryColor: '主題色', + pageTitle: '頁面標題', + pageTitleDesc: '訪客聊天頁標題與瀏覽器標籤;優先於名稱展示', + pageTitlePlaceholder: 'AI 客服', + headerTitleMode: '頂欄標題', + headerTitleModeChannel: '固定通路標題', + headerTitleModeSession: '跟隨會話標題', + headerTitleModeDesc: '固定通路標題:始終顯示頁面標題;跟隨會話標題:首條訊息後按對話內容自動命名,未生成前顯示頁面標題', + tokenHint: '載入通路金鑰失敗,請關閉後重新打開該通路。', + createdWithToken: '內嵌通路已建立,通路金鑰已顯示在下方', + created: '內嵌通路已建立', + updated: '內嵌通路已更新', + saveFailed: '儲存失敗', + deleted: '已刪除', + copied: '已複製內嵌程式碼', + loadError: '載入失敗', + missingChannel: '缺少內嵌通路或 Token', + invalidChannel: '無效的內嵌通路', + sessionFailed: '無法建立對話會話,請稍後重試', + channelDisabled: '內嵌通路已停用,請在 Agent 編輯器的「網頁內嵌」中重新啟用', + loading: '載入中...', + tabIframe: 'iframe', + tabWidget: '浮窗', + tabSecure: '安全模式', + widgetPosition: '浮窗位置', + widgetPreview: '浮窗預覽', + positionBottomRight: '右下角', + positionBottomLeft: '左下角', + positionTopRight: '右上角', + positionTopLeft: '左上角', + tokenCopied: '通路金鑰已複製', + awaitingToken: '等待宿主頁面提供 Token…', + preview: '預覽', + previewIframeHint: '模擬第三方網站用 iframe 內嵌的效果(與複製程式碼一致)。', + previewWidgetHint: '模擬第三方網站載入浮窗指令碼後的效果;真實站點由宿主頁面透過 postMessage 傳遞 Token。', + previewMockPage: '模擬宿主頁面', + previewLoading: '正在載入預覽…', + previewUnavailable: '預覽暫時不可用,請確認通路已啟用且 Redis 可用', + defaultChatTitle: 'AI 助手', + newChat: '新建對話', + sectionChannel: '通路資訊', + sectionSecurity: '安全與限流', + sectionCapabilities: '對話能力', + allowWebSearch: '顯示聯網搜尋開關', + allowWebSearchDesc: '開啟後,訪客輸入框會顯示聯網搜尋按鈕,可自行打開或關閉;不會預設開啟。僅當綁定的智慧代理已啟用聯網搜尋時按鈕才會出現。', + allowFileUpload: '顯示檔案上傳', + allowFileUploadDesc: '開啟後,訪客可上傳圖片與文件附件。僅當綁定的智慧代理已啟用圖片上傳時才會生效。', + webhookUrl: 'Webhook 地址', + webhookUrlPlaceholder: 'https://your-server.example.com/weknora/embed-events', + webhookUrlDesc: '可選。訪客發訊息與助手回覆完成時,WeKnora 會向該 HTTPS 地址 POST 事件(message_sent / message_received)。', + webhookSecret: 'Webhook 簽章金鑰', + webhookSecretPlaceholder: '用於 HMAC-SHA256 簽章(X-WeKnora-Signature)', + webhookSecretKeep: '留空表示不修改已儲存的金鑰', + webhookSecretDesc: '可選。設定後請求體會帶 sha256 簽章頭,便於你的伺服器端驗證來源。', + agentWebSearchDisabledHint: '當前智慧代理未啟用聯網搜尋,訪客端不會顯示聯網按鈕。請先在智慧代理設定中開啟聯網搜尋。', + agentImageUploadDisabledHint: '當前智慧代理未啟用圖片上傳,訪客端不會顯示上傳按鈕。請先在智慧代理設定中開啟圖片上傳。', + sectionAppearance: '外觀與展示', + sectionDeploy: '內嵌到網頁', + sectionWebhook: '事件回呼', + stepChannel: '通路資訊', + stepSecurity: '安全限流', + stepCapabilities: '對話能力', + stepAppearance: '外觀展示', + stepWebhook: '事件回呼', + stepDeploy: '網頁內嵌', + deployIntro: '選擇內嵌方式並複製下方程式碼到您的網頁;需要鑑權或輪換金鑰時,可在頁面底部的「通路金鑰」區域操作。', + deployStepEmbed: '複製內嵌程式碼', + deployStepEmbedDesc: '選擇內嵌方式,將程式碼貼上到第三方頁面即可。', + embedIframeDesc: '適合在頁面固定區域內嵌整頁聊天。', + embedWidgetDesc: '適合右下角浮窗,點擊圖示展開聊天面板。', + embedSecureDesc: '推薦:發布 Token 只儲存在你自己的後端,頁面只拿到短時權杖,瀏覽器永遠看不到長期金鑰。', + deployAfterSaveHint: '儲存通路後,可在此複製通路金鑰與內嵌程式碼。', + widgetTokenNote: '浮窗指令碼需包含通路金鑰;iframe 會在載入時自動完成憑證交換。', + secureTokenNote: '頁面不再包含發布 Token,而是指向你後端的取權杖介面(data-token-endpoint)。你的後端用發布 Token 換取 30 分鐘的短時權杖返回給頁面,浮窗會在到期前自動重新整理。', + secureServerLabel: '伺服器端取權杖介面示例(發布 Token 僅儲存在伺服器端)', + tabServerNode: 'Node.js', + tabServerGo: 'Go', + enabled: '啟用通路', + deleteConfirm: '確定刪除該內嵌通路?已部署的網站程式碼將失效。', + defaultLocale: '預設語言', + defaultLocaleDesc: '訪客打開聊天時使用的界面語言;留空則跟隨瀏覽器或宿主頁面透過 Widget 設定的 locale。', + defaultLocaleBrowser: '跟隨瀏覽器 / 宿主' + }, + knowledgeList: { + create: '新建知識庫', + subtitle: '管理和組織您的知識庫,支持文件型和問答型知識庫', + sharedToOrgs: '已共享給 {count} 個空間', + uninitializedBanner: '部分知識庫尚未初始化,需要先在設定中設定模型資訊才能新增知識文件', + features: { + knowledgeGraph: '知識圖譜', + multimodal: '多模態', + questionGeneration: '問題生成', + wiki: 'Wiki' + }, + detail: { + title: '共享知識庫', + sourceType: '來源方式', + sourceTypeKbShare: '知識庫直接共享到本空間', + sourceTypeAgent: '智慧代理可存取(透過共享智慧代理可見)', + sourceOrg: '來源空間', + sourceFromAgent: '智慧代理', + agentKbStrategy: '智慧代理知識庫策略', + agentKbStrategyAll: '全部知識庫', + agentKbStrategySelected: '指定知識庫', + agentKbStrategyNone: '不使用知識庫', + sharedAt: '共享時間', + myPermission: '我的權限', + goToKb: '進入知識庫' + }, + messages: { + deleted: '已刪除', + deleteFailed: '刪除失敗', + duplicateSuccess: '知識庫副本已建立(不包含知識內容)', + duplicateFailed: '建立知識庫副本失敗' + }, + sections: { + pinned: '置頂', + mine: '我建立的', + tenantOthers: '本空間 · 其他成員', + tenantReadonly: '本空間 · 僅查看', + sharedByMe: '我共享的', + sharedEditable: '共享給我 · 可編輯', + sharedReadonly: '共享給我 · 僅查看' + }, + pin: { + pin: '置頂', + unpin: '取消置頂', + pinSuccess: '已置頂', + unpinSuccess: '已取消置頂', + failed: '操作失敗' + }, + menu: { + viewDetails: '查看詳情', + duplicate: '建立副本' + }, + delete: { + confirmTitle: '刪除確認', + confirmMessage: '確認要刪除知識庫"{name}"?刪除後不可復原', + confirmButton: '刪除' + }, + empty: { + title: '暫無知識庫', + description: '點擊左側快捷操作"新建知識庫"按鈕建立第一個知識庫', + sharedTitle: '暫無共享知識庫', + sharedDescription: '您可以加入共享空間或請求他人共享知識庫給您', + favoritesTitle: '暫無收藏', + favoritesDescription: '在知識庫卡片右上角點擊星標即可收藏', + recentsTitle: '暫無最近存取', + recentsDescription: '最近打開過的知識庫會出現在這裡' + } + }, + createChat: { + title: 'Hi,我是 WeKnora,讓你的知識觸手可及', + newSessionTitle: '新會話', + openProject: '選擇專案', + clearProject: '取消綁定', + pickFailed: '無法打開所選路徑', + messages: { + createFailed: '建立會話失敗', + createError: '建立會話失敗,請稍後重試' + } + }, + input: { + addModel: '新增模型', + placeholder: '輸入問題或描述任務…', + agentMode: '智慧推論', + normalMode: '快速問答', + normalModeDesc: '基於知識庫的 RAG 問答', + agentModeDesc: '多步思考,深度分析', + agentMissingAllowedTools: '允許的工具', + agentMissingSummaryModel: '對話模型', + agentMissingRerankModel: '重排模型', + customAgentMissingSummaryModel: '對話模型', + customAgentMissingRerankModel: '重排模型', + goToAgentEditor: '前往設定 →', + agentNotReadyDetail: '智慧代理「{agentName}」未就緒,需要設定以下內容:{reasons}', + sharedAgentNotReadyDetail: '共享智慧代理「{agentName}」尚未就緒(缺少:{reasons}),請聯絡分享方管理員完成設定。', + knowledgeBase: '知識庫', + knowledgeBaseWithCount: '知識庫({count})', + notConfigured: '未設定', + sharedAgentModelLabel: '共享智慧代理設定的模型', + noModel: '暫無可用模型', + stopGeneration: '停止生成', + send: '傳送', + steerCurrent: '補充當前任務', + steerAfter: '完成後傳送', + steerAccepted: '本輪補充', + steerRetry: '重試傳送', + steerQueueSendNow: '補充當前任務', + steerQueueWaiting: '當前回答結束後傳送', + steerQueueInjecting: '等待接收補充', + webSearchDisabledByAgent: '當前智慧代理已停用網路搜尋', + kbLockedByAgent: '當前智慧代理已鎖定知識庫設定', + kbDisabledByAgent: '當前智慧代理已停用知識庫功能', + modelLockedByAgent: '當前智慧代理已鎖定模型設定', + imageUploadDisabledByAgent: '當前智慧代理未啟用圖片上傳', + goToAgentSettings: '去設定智慧代理', + messages: { + enterContent: '請先輸入內容!', + replying: '正在回覆中,請稍後再試!', + steerAttachmentPending: '附件尚未上傳完成,請稍後再追加', + steerHasAttachments: '進行中的回答無法附帶附件,請先移除附件或等當前回答結束後再傳送', + steerFailed: '追加失敗,請重試', + steerPromoteFailed: '立即傳送失敗,請重試', + steerRemoveFailed: '刪除排隊訊息失敗,請重試', + steerAlreadyInjected: '該訊息已被當前回答接收', + steerFollowUpTimeout: '下一輪迴答未能及時開始,請重新傳送', + steerNoActiveRun: '當前沒有正在進行的回答,請直接傳送訊息', + agentSwitchedOn: '已切換到智慧推論', + agentSwitchedOff: '已切換到快速問答', + agentSelected: '已選擇智慧代理「{name}」', + webSearchNotConfigured: '未設定網路搜尋引擎,請先在設定中完成搜尋引擎選擇與介面設定。', + webSearchEnabled: '網路搜尋已開啟', + webSearchDisabled: '網路搜尋已關閉', + sessionMissing: '會話 ID 不存在', + messageMissing: '無法獲取訊息 ID,請重新整理頁面後重試', + stopSuccess: '已停止生成', + stopFailed: '停止失敗,請重試' + }, + webSearch: { + toggleOn: '開啟網路搜尋', + toggleOff: '關閉網路搜尋', + notConfigured: '未設定網路搜尋引擎' + } + }, + manualEditor: { + defaultTitlePrefix: '新建文件', + noDocumentKnowledgeBases: '暫無可用的文件型知識庫,請先建立一個文件型知識庫', + actions: { + cancel: '取消', + saveDraft: '暫存草稿', + publish: '發布入庫' + }, + loading: { + content: '正在載入內容', + preparing: '正在準備編輯器' + }, + status: { + draftTag: '當前狀態:草稿', + publishedTag: '當前狀態:已發布', + lastUpdated: '最近更新:{time}', + counter: '{chars} 字 · {lines} 行' + }, + form: { + knowledgeBasePlaceholder: '請選擇知識庫', + titleLabel: '知識標題', + knowledgeBaseLabel: '目標知識庫', + titlePlaceholder: '請輸入標題', + contentPlaceholder: '支持 Markdown 語法,可使用 # 標題、清單、程式碼塊等' + }, + success: { + draftSaved: '草稿已儲存', + published: '知識已發布並開始索引' + }, + warning: { + selectKnowledgeBase: '請選擇目標知識庫', + enterTitle: '請輸入知識標題', + enterContent: '請輸入知識內容', + contentTooShort: '內容過短,建議補充更多資訊後再發布' + }, + error: { + fetchDetailFailed: '獲取知識詳情失敗', + saveFailed: '儲存失敗,請稍後重試' + }, + labels: { + currentKnowledgeBase: '當前知識庫' + }, + section: { + content: '知識內容' + }, + title: { + edit: '編輯 Markdown 知識', + create: '線上編輯 Markdown 知識' + }, + preview: { + empty: '暫無內容' + }, + shortcuts: { + title: '快速鍵', + continueList: '清單內自動續行', + indent: '縮排 / Shift+Tab 反縮排' + }, + view: { + edit: '編輯', + split: '分屏', + preview: '預覽', + splitUnavailable: '寬度不足,拖寬抽屜或全螢幕後可用分屏', + groupLabel: '編輯區檢視' + }, + toolbar: { + bold: '粗體', + italic: '斜體', + strike: '刪除線', + inlineCode: '行內程式碼', + heading1: '一級標題', + heading2: '二級標題', + heading3: '三級標題', + bulletList: '無序清單', + orderedList: '有序清單', + taskList: '任務清單', + blockquote: '引用', + codeBlock: '程式碼塊', + link: '插入連結', + image: '插入圖片', + table: '插入表格', + horizontalRule: '分割線', + headingGroup: '標題', + insertGroup: '插入' + }, + table: { + column1: '列1', + column2: '列2', + cell: '內容' + }, + placeholders: { + heading: '標題{level}', + listItem: '清單項', + taskItem: '任務項', + quote: '引用內容', + code: '程式碼內容', + linkText: '連結文字', + imageAlt: '描述', + bold: '粗體文字', + italic: '斜體文字', + strike: '刪除線', + inlineCode: 'code' + } + }, + file: { + upload: '上傳檔案' + }, + mentionDetail: { + readOnlyFromAgent: '僅在此對話中唯讀,不顯示在知識庫清單中', + faqCount: '共 {count} 條問答', + kbCount: '共 {count} 個文件', + mcpToolCount: '共 {count} 個工具', + mcpNotSynced: '尚未同步工具', + mcpStale: '需重新同步', + belongsToKb: '所屬知識庫:', + belongsToOrg: '所屬空間:', + noCompatibleKbForAgent: '當前智慧代理的工具與作用域內知識庫的能力不比對,暫無可引用的知識庫。' + }, + common: { + add: '新增', + me: '我', + confirm: '確認', + cancel: '取消', + unsavedChanges: { + title: '有未儲存的更改', + body: '關閉後當前修改將丟失,確定要關閉嗎?', + discard: '放棄更改', + keepEditing: '繼續編輯', + }, + fullscreen: '全螢幕', + exitFullscreen: '退出全螢幕', + save: '儲存', + delete: '刪除', + edit: '編輯', + copy: '複製', + copied: '已複製', + copySuccess: '已複製', + default: '預設', + create: '建立', + download: '下載', + refresh: '重新整理', + loading: '載入中...', + noData: '暫無資料', + noMoreData: '已載入全部內容', + loadMore: '載入更多', + error: '錯誤', + success: '成功', + failed: '失敗', + info: '資訊', + selectAll: '全選', + yes: '是', + no: '否', + close: '關閉', + back: '返回', + next: '下一步', + finish: '完成', + all: '全部', + clear: '清空', + website: '官方網站', + clawhubSkill: 'Claw Skill', + github: 'GitHub', + githubStarTip: '在 GitHub 打開倉庫,若覺得有用歡迎點個 Star', + on: '開啟', + off: '關閉', + confirmDelete: '確認刪除', + createSuccess: '已建立', + deleteSuccess: '已刪除', + deleteFailed: '刪除失敗', + updateSuccess: '已更新', + saveSuccess: '已儲存', + saveFailed: '儲存失敗', + operationFailed: '操作失敗', + file: '檔案', + skill: '技能', + knowledgeBase: '知識庫', + noResult: '無結果', + remove: '移除', + avatar: '頭像', + defaultUser: '使用者', + copyFailed: '複製失敗', + retry: '重試', + expand: '展開', + collapse: '收起' + }, + authStore: { + errors: { + parseUserFailed: '解析使用者資訊失敗', + parseTenantFailed: '解析空間資訊失敗', + parseKnowledgeBasesFailed: '解析知識庫清單失敗', + parseCurrentKnowledgeBaseFailed: '解析當前知識庫失敗' + } + }, + auth: { + login: '登入', + logout: '退出', + oidcLogin: '使用 OIDC 登入', + oidcLoginWithProvider: '使用 {provider} 登入', + redirectingToOIDC: '正在跳轉到身份提供商...', + orContinueWith: '或使用以下方式繼續', + oidcLoginFailed: 'OIDC 登入失敗', + username: '使用者名', + email: '電子信箱', + password: '密碼', + confirmPassword: '確認密碼', + loginSuccessTitle: '登入成功', + loginSuccessContent: '歡迎,你已進入 {name}', + loggingIn: '登入中...', + register: '註冊', + registering: '註冊中...', + createAccount: '建立帳戶', + haveAccount: '已有帳戶?', + backToLogin: '返回登入', + loginHint: '登入以繼續使用;首次使用請在下方建立帳戶。', + firstTime: '首次使用 WeKnora?', + registerSuccess: '註冊成功,請登入', + registerFailed: '註冊失敗', + subtitle: 'RAG 問答、ReAct 智慧代理與 Wiki 知識庫,大型語言模型驅動的企業級知識框架', + registerSubtitle: '建立帳戶並開始使用 WeKnora', + emailPlaceholder: '輸入電子信箱地址', + passwordPlaceholder: '輸入密碼', + confirmPasswordPlaceholder: '再次輸入密碼', + usernamePlaceholder: '輸入使用者名', + emailRequired: '請輸入電子信箱地址', + emailInvalid: '請輸入正確的電子信箱格式', + passwordRequired: '請輸入密碼', + passwordMinLength: '密碼至少8個字符', + passwordMaxLength: '密碼不能超過32個字符', + passwordMustContainLetter: '密碼必須包含字母', + passwordMustContainLowercaseLetter: '密碼必須包含小寫字母', + passwordMustContainUppercaseLetter: '密碼必須包含大寫字母', + passwordMustContainNumber: '密碼必須包含數字', + passwordMustContainSpecialChar: '密碼必須包含特殊字符:{specialChars}', + usernameRequired: '請輸入使用者名', + usernameMinLength: '使用者名至少2個字符', + usernameMaxLength: '使用者名不能超過20個字符', + usernameInvalid: '使用者名只能包含字母、數字、底線和中文字符', + confirmPasswordRequired: '請確認密碼', + passwordMismatch: '兩次輸入的密碼不一致', + loginError: '登入錯誤,請檢查電子信箱或密碼', + loginErrorRetry: '登入錯誤,請稍後重試', + registerError: '註冊錯誤,請稍後重試', + workspaceOnboarding: { + title: '選擇你的工作空間', + description: '建立一個空間即可開始使用,或接受邀請加入已有空間。', + create: '建立空間', + invitations: '查看邀請', + loadingPolicy: '正在確認可用的空間加入方式…', + policyLoadFailed: '暫時無法獲取空間權限,請檢查網路後重試。', + retry: '重新載入', + inviteOnlyTitle: '等待加入工作空間', + inviteOnlyDescription: '當前系統不開放個人建立空間。你可以查看並接受管理員發來的空間邀請。', + inviteOnlyNotice: '此帳戶只能透過邀請加入已有空間', + help: '你現在可以建立空間,也可以稍後回來接受邀請。', + inviteOnlyHelp: '還沒有邀請?請把你的註冊電子信箱提供給空間管理員,由管理員向你傳送邀請。' + } + }, + inviteRegister: { + bannerTitle: '您被邀請加入「{tenant}」', + bannerHint: '填寫下方資訊完成註冊,註冊成功後將自動加入該團隊。', + bannerHintLogin: '登入後將自動加入該團隊。', + loading: '正在驗證邀請連結…', + invalidTitle: '邀請連結無效或已撤銷', + invalidBody: '請聯絡邀請人重新傳送連結,或前往登入使用現有帳號。', + backToLogin: '返回登入', + title: '完成註冊', + subtitle: '您被邀請加入「{tenant}」', + email: '電子信箱', + emailPlaceholder: 'your{\'@\'}example.com', + emailHint: '用您自己的電子信箱註冊即可。', + emailInvalid: '請輸入有效的電子信箱地址', + username: '姓名', + usernamePlaceholder: '請輸入您的姓名', + password: '設定密碼', + passwordPlaceholder: '至少 6 位', + confirmPassword: '確認密碼', + submit: '完成註冊', + submitting: '提交中…', + success: '註冊成功,正在進入工作空間…', + joined: '已加入該團隊', + failed: '註冊失敗,請稍後重試', + usernameRequired: '請輸入姓名', + passwordTooShort: '密碼至少 6 位', + passwordMismatch: '兩次輸入的密碼不一致' + }, + initialization: { + skip: '跳過', + next: '下一步' + }, + graphSettings: { + title: '知識圖譜設定', + description: '設定實體-關係提取功能,自動從文字中抽取實體和關係建構知識圖譜(注意:這與 Wiki 知識庫中的「頁面連結圖譜」是兩回事──前者是基於 LLM 的實體-關係圖,後者是 Wiki 頁面之間的引用關係圖)', + enableLabel: '啟用實體關係提取', + enableDescription: '開啟後將自動從文字中提取實體和關係', + tagsLabel: '關係類型', + tagsDescription: '定義要提取的關係類型標籤,多個標籤用逗號分隔', + tagsPlaceholder: '輸入關係類型,如:工作於、同事、朋友等', + generateRandomTags: '生成隨機標籤', + sampleTextLabel: '示例文字', + sampleTextDescription: '用於測試實體關係提取的示例文字', + sampleTextPlaceholder: '輸入一段包含實體和關係的文字...', + customInstructionsLabel: '額外提取要求', + customInstructionsDescription: '補充領域範圍、實體篩選和屬性提取要求;系統仍負責結構化輸出協議', + customInstructionsPlaceholder: '例如:重點提取契約主體、金額、履約期限和違約責任…', + generateRandomText: '生成隨機文字', + entityListLabel: '實體清單', + entityListDescription: '從文字中提取的實體及其屬性', + nodeNamePlaceholder: '輸入實體名稱', + attributePlaceholder: '輸入屬性值', + addAttribute: '新增屬性', + manageEntitiesLabel: '管理實體', + manageEntitiesDescription: '新增或刪除實體節點', + addEntity: '新增實體', + relationListLabel: '關系清單', + relationListDescription: '定義實體之間的關係連結', + selectEntity: '選擇實體', + selectRelationType: '選擇關係類型', + manageRelationsLabel: '管理關係', + manageRelationsDescription: '新增或刪除實體間的關係', + addRelation: '新增關係', + extractActionsLabel: '提取操作', + extractActionsDescription: '執行實體關係提取或管理示例資料', + startExtraction: '開始提取', + extracting: '提取中...', + defaultExample: '預設示例', + clearExample: '清除示例', + completeModelConfig: '請先完成模型設定', + tagsGenerated: '標籤生成成功', + tagsGenerateFailed: '標籤生成失敗', + textGenerated: '文字生成成功', + textGenerateFailed: '文字生成失敗', + pleaseInputText: '請先輸入示例文字', + extractSuccess: '實體關係提取成功', + extractFailed: '實體關係提取失敗', + exampleLoaded: '示例已載入', + exampleCleared: '示例已清除', + disabledWarning: '知識圖譜資料庫未啟用,實體關係提取功能將無法使用', + howToEnable: '如何啟用知識圖譜?' + }, + retrievalSettings: { + title: '搜尋設定', + description: '設定知識庫搜尋和訊息搜尋的全局檢索參數', + embeddingTopKLabel: '向量檢索數量 (Top K)', + vectorThresholdLabel: '向量相似度閾值', + keywordThresholdLabel: '關鍵字比對閾值', + rerankTopKLabel: 'Rerank 數量 (Top K)', + rerankThresholdLabel: 'Rerank 閾值', + rerankModelLabel: 'Rerank 模型', + rerankModelDescription: '選擇用於搜尋結果重排序的模型', + rerankModelRequired: '請選擇 Rerank 模型,搜尋功能需要此模型對結果進行重排序', + toasts: { + saveSuccess: '檢索設定已儲存', + saveFailed: '儲存設定失敗: {message}' + } + }, + memorySettings: { + title: '我的記憶', + description: '這裡是助手跨會話記住的關於你的內容。你可以隨時查看、修改和刪除,刪除後不會再被使用。', + workspaceDisabled: '當前空間尚未開啟長期記憶,管理員開啟後這裡的開關才會生效。', + enableLabel: '為我啟用長期記憶', + enableDescription: '關閉後助手不再讀取或新增你的記憶,已有記憶會保留,重新開啟即可繼續使用。', + agentDisabledHint: '單個智慧代理也可以單獨關閉長期記憶。被關閉的智慧代理在對話中既不會讀取你的記憶,也不會新增記憶;換用其他智慧代理不受影響。', + usage: { + title: '記憶何時會被使用', + iconHint: '查看哪些記憶會在對話裡被使用', + intro: '僅「生效中」會進入對話。', + rows: { + alwaysOn: { + label: '每輪都會帶上', + text: '個人資料、偏好,以及明確說「記住」的內容' + }, + situational: { + label: '相關時才用', + text: '事實、在辦事項' + }, + interest: { + label: '理解常問方向', + text: '長期追蹤,不一定每輪都引用' + }, + tracking: { + label: '先觀察再記住', + text: '常問方向會先計數,達到次數後才成為長期追蹤' + }, + documents: { + label: '常用資料', + text: '反覆用來回答你的文件,檢索時會稍稍優先' + }, + pending: { + label: '確認後才生效', + text: '待確認的推斷' + }, + inactive: { + label: '不再使用', + text: '已被更新、已歸檔' + } + } + }, + listTitle: '記憶清單', + listCount: '共 {count} 條', + statusActive: '生效中', + statusSuperseded: '已被更新', + statusArchived: '已歸檔', + statusPending: '待確認', + statusTracking: '觀察中', + statusDocuments: '常用資料', + confirmGuess: '是的', + rejectGuess: '不是', + pendingHint: '這些是系統從你的提問裡推斷出來的,確認之前不會被使用。', + trackingHint: '這些是你反覆問到、但還沒達到「長期追蹤」次數的主題。記下來之前不會進入對話。', + documentsHint: '這些文件在回答裡反覆出現,檢索會稍微偏向它們。停止跟蹤後不再加權,再被引用兩次會重新出現。', + supersededHint: '這些內容已被更新的記憶替代,不會再進入對話,只作為變更記錄保留。', + archivedHint: '已歸檔的記憶不會再進入對話。超出每人上限後,較少用到的條目會被自動收起。', + pendingEmptyTitle: '沒有待確認的推斷', + pendingEmptyDescription: '當系統從你的提問裡推斷出關於你的資訊時,會先放在這裡等你確認。', + trackingEmptyTitle: '沒有正在觀察的主題', + trackingEmptyDescription: '自動提煉開啟後,系統會先統計你常問的方向,達到次數後再記為長期追蹤。', + documentsEmptyTitle: '還沒有常用資料', + documentsEmptyDescription: '同一份文件被回答引用兩次以上,就會出現在這裡。', + supersededEmptyTitle: '還沒有被更新的記憶', + supersededEmptyDescription: '同一主題被新說法覆蓋時,舊內容會留在這裡。在本頁直接編輯是原地改寫,不會產生這條記錄。', + archivedEmptyTitle: '還沒有歸檔的記憶', + archivedEmptyDescription: '生效中超過上限(預設 200 條)時,較少用到的會自動收起;帶過期時間的事項到期後也會進來。', + documentsHits: '已引用 {hits} 次', + untitledDocument: '未命名文件', + openDocument: '打開文件', + openDocumentUnavailable: '無法打開:缺少知識庫資訊', + stopTrackingDocument: '停止跟蹤', + stopTrackingDocumentConfirm: '停止用這份文件做個性化檢索?之後再被引用兩次會重新出現。', + stopTrackingDocumentSuccess: '已停止跟蹤這份資料', + stopTrackingDocumentFailed: '停止跟蹤失敗', + trackingProgress: '已問 {hits} 次,滿 {threshold} 次後記為長期追蹤', + trackingReady: '已達到次數,可以記為長期追蹤', + trackingAliases: '也問過:{aliases}', + promoteTopic: '記為追蹤', + dismissTopic: '不再跟蹤', + dismissTopicConfirm: '停止跟蹤這個主題?之後再問到也不會自動記為長期追蹤。', + promoteSuccess: '已記為長期追蹤', + promoteFailed: '記為關註失敗', + dismissSuccess: '已停止跟蹤這個主題', + dismissFailed: '停止跟蹤失敗', + confirmSuccess: '已確認', + confirmFailed: '確認失敗', + rejectSuccess: '已否決,不會再次推斷', + rejectFailed: '否決失敗', + export: '匯出', + consolidate: '整理', + consolidateConfirm: '合併意思接近的條目,舊內容會留在「已被更新」。確定整理?', + consolidateSuccess: '整理完成:合併 {merged} 組,到期歸檔 {expired} 條,過期事項降權 {demoted} 條', + consolidateNothing: '沒有發現需要整理的內容', + consolidateTooFewItems: '記憶還太少,暫時沒有整理的必要', + consolidateNoCandidates: '沒有發現意思相近的記憶,無需合併', + consolidateModelDeclined: '模型看過了,這些記憶說的不是同一件事,未做合併', + consolidateTooSoon: '剛整理過,請稍後再試', + consolidateModelUnavailable: '模型不可用,為避免誤合併,本次沒有改動任何記憶', + consolidateFailed: '整理失敗', + clear: '清空', + clearConfirm: '將永久刪除你的全部記憶、正在觀察的主題和常用資料,此操作不可復原。確定繼續嗎?', + deleteConfirm: '永久刪除這條記憶?', + add: '新增', + addPlaceholder: '用一句話寫下你希望助手記住的事', + addTitle: '新增記憶', + addKindLabel: '類型', + addContentLabel: '內容', + emptyTitle: '還沒有記憶', + emptyDescription: '在對話裡說「記住:……」,或者在上面直接新增一條。', + kinds: { + profile: '個人資料', + preference: '偏好', + fact: '事實', + task: '在辦事項', + interest: '長期追蹤' + }, + kindHints: { + profile: '之後每輪對話都會帶上', + preference: '之後每輪對話都會帶上', + fact: '只在問題相關時才會用到', + task: '只在問題相關時才會用到', + interest: '用來理解你常問的方向,不一定每輪都引用' + }, + origins: { + explicit: '你要求記住', + extracted: '自動提煉', + manual: '手動新增' + }, + toasts: { + enabled: '已為你開啟長期記憶', + disabled: '已關閉長期記憶', + added: '已新增', + updated: '已更新', + deleted: '已刪除', + cleared: '已刪除 {count} 條記憶', + saveFailed: '操作失敗:{message}' + } + }, + envVarSettings: { + title: '沙箱金鑰', + host: { + title: '環境變數', + description: '給本機技能用的個人金鑰,不是 WeKnora 的系統或部署設定。', + helpAria: '環境變數說明', + introRuntimeBody: '技能在這台電腦上運行時才會注入;對話裡也可以當場提供。儲存後不再顯示明文。', + loadFailed: '環境變數載入失敗。', + sandboxTitle: '在這台電腦上始終帶上的值', + sandboxHint: '只帶給你在這台電腦上跑的命令。多數情況用不到;需要時再加,對話裡也可以當場提供。', + nameInvalid: '這個名字不能用。保留名(例如 PATH,或以 WEKNORA_ 開頭的名字)不接受。', + deleteConfirm: '刪除 {name}?之後在這台電腦上運行的東西都不會再帶上它。', + }, + description: '給技能和沙箱用的個人金鑰,不是 WeKnora 的系統或部署設定。', + helpAria: '沙箱金鑰說明', + introPersonalTitle: '只屬於你', + introPersonalBody: '只注入到你自己的對話和執行裡,空間裡的其他人看不到,也不會改成他們的值。', + introRuntimeTitle: '用的時候才帶上', + introRuntimeBody: '技能運行或在沙箱裡執行命令時才會注入;對話裡也可以當場提供。儲存後不再顯示明文。', + loading: '載入中…', + loadFailed: '沙箱金鑰載入失敗。', + retry: '重試', + noConfigTitle: '還沒有沙箱', + noConfigDescription: '這個空間還沒有設定沙箱後端,暫時沒有可設定的金鑰。', + sandboxTitle: '某個沙箱裡始終帶上的值', + sandboxHint: '只帶給你在那個沙箱裡跑的命令。多數情況用不到;需要時再加,對話裡也可以當場提供。', + sandboxEmpty: '還沒有新增過。', + sandboxPick: '用在哪個沙箱', + skillTitle: '技能要用的金鑰', + skillHint: '技能聲明需要的值。可以預先儲存在這裡,也可以在對話裡當場提供。空間管理員還可以在技能卡上填空間共用值。', + skillEmptyTitle: '還沒有技能需要金鑰', + skillEmptyDesc: '安裝會聲明憑據的技能後,要填的項會出現在這裡。', + skillOnSandbox: '用於沙箱「{name}」', + skillNeedsCount: '{count} 項未在此儲存', + skillReady: '此頁已儲存', + requiredTag: '必填', + statusUnset: '未設定', + statusWorkspace: '正在使用空間共用值', + statusUser: '你已設定', + setValue: '設定', + replaceValue: '更換', + addRow: '新增', + namePlaceholder: 'VARIABLE_NAME', + nameRule: '只能用大寫字母、數字和底線,且以字母或底線開頭。', + nameInvalid: '這個名字不能用。沙箱保留的名字(例如 PATH,或以 WEKNORA_ 開頭的名字)不接受。', + nameDuplicate: '這裡已經有同名變數了。', + valuePlaceholder: '填入值', + storedPlaceholder: '已存值,填入新值即取代', + valueRequired: '儲存前請先填入值。', + valueTooLong: '單個值不能超過 {max} 位元組。', + tooManyValues: '這裡最多可以儲存 {max} 個變數。', + save: '儲存', + saveSuccess: '已儲存。值已存好,之後不會再顯示。', + saveFailed: '儲存失敗。', + delete: '刪除', + deleteConfirm: '刪除 {name}?之後在這個沙箱上運行的東西都不會再帶上它。', + deleteSuccess: '變數已刪除。', + clear: '清除我的值', + clearConfirm: '清除你為 {name} 設定的值?之後會重新使用空間共用值(如果有)。', + clearSuccess: '已清除你的值。', + updatedAt: '你於 {time} 設定' + }, + memoryWorkspaceSettings: { + title: '長期記憶', + description: '讓助手跨會話記住成員說過的個人資料、偏好、事實與在辦事項。', + introTitle: '預設關閉,需要你顯式開啟', + introDescription: '長期記憶會保留成員在對話中說過的內容,因此預設不開啟。開啟後每位成員的記憶彼此隔離,成員可以在「我的記憶」裡隨時查看、修改、刪除或整體關閉。生效中的個人資料與偏好會進入之後的每一輪對話;事實和在辦事項只在相關問題時召回。', + enableLabel: '在本空間啟用長期記憶', + enableDescription: '關閉後本空間的所有會話都不會讀取或寫入記憶。', + writeModeLabel: '記憶寫入方式', + writeModeDescription: '決定什麼內容會被記住。', + writeModeExplicit: '僅顯式記錄', + writeModeAuto: '自動提煉', + writeModeExplicitHint: '只記錄成員明確說「記住:……」的內容,以及在記憶頁手動新增的條目,不額外呼叫模型。', + writeModeAutoHint: '在此基礎上,會話結束後在後台呼叫一次模型,從成員自己說過的話裡提煉值得長期保留的內容。', + extractModelLabel: '提煉模型', + extractModelDescription: '留空則使用該次會話所用的模型。', + extractDelayLabel: '挖掘延遲', + extractDelayDescription: '一輪對話結束後等待多久再挖掘。等一等可以讓一次模型呼叫覆蓋使用者連著發的幾條訊息。', + extractMinIntervalLabel: '兩次挖掘的最小間隔', + extractMinIntervalDescription: '同一個人兩次挖掘之間至少間隔多久,用來控制成本。間隔內產生的訊息不會被丟棄,會順延到下一次挖掘一併處理。', + vectorRecallLabel: '按語義召回記憶', + vectorRecallDescription: '除了字面比對,再按含義比對。使用者換個說法之後,原來那條記憶仍然能被找到──而多數記憶遲早會被換說法。每輪問答多一次向量呼叫,超時會自動退回字面比對。', + embeddingModelLabel: '記憶 Embedding 模型', + embeddingModelDescription: '語義召回只使用這一個模型,與各知識庫綁定的 Embedding 無關。不選則只按字面比對。換模型後,新寫入立刻用新模型;舊記憶在補上新向量之前,語義召回找不到它們,只靠字面比對。', + conditioningLabel: '讓記憶參與檢索', + conditioningDescription: '開啟後,記憶會參與查詢改寫和文件排序,而不只是附加到回答提示裡。這是記憶在知識庫產品裡真正起作用的地方。', + interestThresholdLabel: '成為長期追蹤的次數', + interestThresholdDescription: '同一個主題被問到這麼多次後,才會作為長期關註記下來。設為 1 會把每個免洗問題都記下來,通常太吵。', + instructionsLabel: '自定義挖掘規則', + instructionsDescription: '追加到挖掘提示語裡的空間規則,用來表達產品猜不到的策略,例如「永遠不要記錄客戶姓名」。', + instructionsPlaceholder: '一行一條規則,例如:永遠不要記錄客戶姓名', + maxItemsLabel: '每人記憶上限', + maxItemsDescription: '超出後按重要度與使用時間歸檔最低的若干條,歸檔的記憶仍可在「我的記憶」裡查看。', + toasts: { + saveSuccess: '長期記憶設定已儲存', + saveFailed: '儲存失敗:{message}' + } + }, + chatHistorySettings: { + title: '訊息管理', + description: '設定聊天歷史知識庫,將對話訊息自動向量化索引,實現語義搜尋', + enableLabel: '啟用訊息索引', + enableDescription: '開啟後,新的對話訊息將自動索引到知識庫,支持向量搜尋', + embeddingModelLabel: 'Embedding 模型', + embeddingModelDescription: '選擇用於訊息向量化的 Embedding 模型', + embeddingModelLocked: '已有訊息被索引,Embedding 模型不可修改(修改需清空索引資料)', + statsTitle: '索引統計', + statsIndexedMessages: '已索引訊息', + statsNotConfigured: '訊息索引未設定', + statsNotConfiguredDesc: '啟用並選擇 Embedding 模型後,對話訊息將自動向量化索引', + toasts: { + saveSuccess: '訊息管理設定已儲存', + saveFailed: '儲存設定失敗: {message}' + } + }, + vectorStoreSettings: { + title: '向量資料庫引擎', + description: '註冊和管理用於知識庫搜尋的向量資料庫實例。', + basicSection: '基本資訊', + storesTitle: '向量資料庫', + addStore: '新增資料庫', + editStore: '編輯資料庫', + deleteConfirm: '確定要刪除此向量資料庫嗎?', + emptyDesc: '尚未設定向量資料庫。點擊"新增資料庫"開始設定。', + engineTypeLabel: '引擎類型', + nameLabel: '名稱', + namePlaceholder: '例如:my-vector-store', + connectionInfo: '連結資訊', + advancedIndexConfig: '進階設定', + envTag: 'DEFAULT', + testConnection: '測試連結', + testing: '測試中...', + immutableNotice: '建立後無法更改引擎類型、連結和索引設定。\n如需更改,請刪除後重新建立。', + insecureSkipVerifyWarning: '關閉 TLS 證書驗證會使連結面臨中間人攻擊風險。僅可用於自簽章證書的開發叢集,切勿在生產環境使用。', + toasts: { + storeCreated: '向量資料庫已建立', + storeUpdated: '向量資料庫已更新', + storeDeleted: '向量資料庫已刪除', + testSuccess: '連結測試成功', + testFailed: '連結測試失敗', + duplicateName: '同名向量資料庫已存在', + errorGeneric: '發生錯誤,請重試。' + }, + validation: { + nameRequired: '名稱為必填項', + engineTypeRequired: '引擎類型為必填項', + fieldRequired: '{field}為必填項', + indexNamePattern: '必須以字母開頭,僅允許字母、數字、底線和連字符(最多128個字符)' + } + }, + webSearchSettings: { + title: '網路搜尋設定', + description: '設定網路搜尋功能,在回答問題時可以從網際網路獲取實時資訊補充知識庫內容', + basicSection: '基本資訊', + credentialsSection: '連結設定', + optionsSection: '選項', + providersTitle: '搜尋引擎設定', + addProvider: '新增搜尋引擎', + editProvider: '編輯搜尋引擎', + deleteConfirm: '確定要刪除此搜尋引擎設定嗎?', + providerNameLabel: '名稱', + providerNamePlaceholder: '例如:生產環境 Bing 搜尋', + providerTypeLabel: '引擎類型', + providerDescLabel: '備註', + providerDescPlaceholder: '可選,如:測試環境用', + engineIdLabel: '搜尋引擎 ID', + setAsDefault: '設為預設', + testConnection: '測試連結', + testing: '測試中...', + viewDocs: '查看文件獲取金鑰', + noProvidersDesc: '新增一個網路搜尋引擎,為您的智慧代理提供實時的網際網路資訊檢索能力。', + setAsDefaultDesc: '當智慧代理沒有指定特定的搜尋引擎時,將預設使用此設定', + proxyUrlLabel: 'HTTP 代理', + proxyUrlPlaceholder: '例如 http://proxy.example.com:3128(可選,僅支持 http/https)', + proxyUrlHelp: '若環境存取搜尋 API 需代理,在此填寫;留空則使用系統環境變數 HTTP(S)_PROXY。', + apiKeyLabel: 'API 金鑰', + apiKeyOptionalLabel: 'API 金鑰(可選)', + baseUrlLabel: '實例地址', + baseUrlPlaceholder: 'https://searxng.example.com', + apiKeyPlaceholder: '請輸入 API 金鑰', + toasts: { + providerCreated: '搜尋引擎設定已建立', + providerUpdated: '搜尋引擎設定已更新', + providerDeleted: '搜尋引擎設定已刪除', + testSuccess: '連結測試成功', + testFailed: '連結測試失敗' + } + }, + settings: { + modelManagement: '模型管理', + webSearchConfig: '網路搜尋', + autoCheckUpdate: '自動下載更新', + autoCheckUpdateDesc: '開啟後自動檢查並在後台下載最新版本安裝包。', + vectorStoreEngine: '向量資料庫引擎', + parserEngine: '解析引擎', + storageEngine: '存儲引擎', + sandbox: { + title: '沙箱設定', + description: '設定智慧代理運行技能指令碼的隔離環境。每個智慧代理選擇一份設定。', + pageHintTitle: '什麼是沙箱?', + pageHint: '沙箱是智慧代理執行技能指令碼的隔離環境。一個空間可以新增多份設定(Docker、E2B、CubeSandbox),每個智慧代理選擇一份。技能安裝在「技能管理」頁,寫入所選設定的映像;未選擇沙箱時不會執行技能指令碼。', + editorDescription: '設定空間運行環境,Docker、CubeSandbox 和 E2B 使用同一套管理流程。', + stepConnection: '連結', + stepTemplate: '模板', + stepRuntime: '運行設定', + stepSkills: '技能', + stepSkillsLocked: '技能需要裝進這份設定的映像,先儲存設定再回到這一步。', + setupProgress: '沙箱設定進度', + stepDescriptions: { + connection: '先設定後端並驗證連結,透過後再從叢集載入模板。', + template: '選擇當前叢集返回且已經就緒的運行模板。', + runtime: '設定執行參數、環境變數,以及技能映像如何生效,然後儲存。', + skills: '把技能裝進這份設定的沙箱映像;設定已儲存後可隨時回來增刪。', + }, + back: '上一步', + connectAndContinue: '連結並繼續', + loading: '載入沙箱設定...', + loadFailed: '載入沙箱設定失敗', + backend: '沙箱', + backendType: '沙箱類型', + backendTypePlaceholder: '選擇沙箱類型', + scriptPolicyLabel: '允許在沙箱中執行技能指令碼', + scriptPolicyDesc: '關閉後本空間所有智慧代理只能閱讀技能內容,不再執行指令碼;已在運行的遠端沙箱需結束會話後才釋放。', + backendDescriptions: { + cube: '適合私有化或內網部署的自建 MicroVM 叢集', + e2b: 'E2B 託管服務或相容 E2B 的叢集', + docker: '在本機 Docker 上為每個會話保留一個長駐容器,指令碼和檔案都落在同一容器裡', + }, + dockerDisabledAlert: '當前部署未啟用 Docker 沙箱', + dockerDisabledHint: '本機 docker.sock 等同宿主機 root。僅私有化單機需要時,由系統管理員在「設定 → 系統設定 → 網路安全」中打開。', + dockerDisabledCard: '部署未啟用 Docker 沙箱,此設定不會再建立容器', + dockerHostRisk: '留空或 unix:// 會使用 WeKnora 所在機器的 Docker 守護行程,權限等同該機 root,只適合私有化單機。多套空間共用同一主機時請改用 Cube 或 E2B。遠程 tcp:// 必須填寫 TLS 證書目錄。', + addConfig: '新增沙箱', + viewClusterGuide: '叢集搭建指南', + configName: '設定名稱', + configNamePlaceholder: '如:生產 E2B', + configNameRequired: '請填寫設定名稱', + configDescription: '描述', + configDescriptionPlaceholder: '選填,用於區分多份同類型設定', + createTitle: '新增沙箱', + editTitle: '編輯沙箱', + sectionBasic: '基本資訊', + sectionConnection: '叢集連結', + sectionRuntimeEnvironment: '運行環境', + sectionTemplate: '運行模板', + sectionRuntime: '執行設定', + sectionNetwork: '網路策略', + sectionEnvironment: '環境變數', + networkHint: '控制該設定下所有沙箱的出網。改動只影響之後新建的沙箱,已有沙箱按原策略運行到回收。', + egressDefault: '出站預設', + egressAllowAll: '允許公網(預設)', + egressDenyAll: '預設拒絕', + egressPrecedence: '判定順序:放行 → 拒絕 → 預設值。放行優先於拒絕。', + allowOut: '放行目標', + allowOutPlaceholder: '域名 / IP / CIDR,例如 *.example.com', + allowOutHelp: '支持 IPv4、CIDR、域名和單層通配 *.example.com(通配不比對主域)。', + denyOut: '拒絕目標', + denyOutPlaceholder: '僅支持 IP / CIDR,例如 169.254.169.254/32', + denyOutHelp: '拒絕只按目的 IP 比對,因此不支持域名。', + domainAllowNeedsDenyAll: '放行目標裡有域名時,必須同時選擇「預設拒絕」或在拒絕目標中加入 0.0.0.0/0,否則白名單不生效。', + cubeL7Rules: 'HTTP 存取規則(L7)', + cubeL7RulesHelp: '每條規則必須填 host 或 sni,網路層只從這兩個欄位提取放行目標。欄位之間是 AND,method 清單內部是 OR。僅 HTTP 80 / HTTPS 443 生效。規則從上到下先比對先生效。', + e2bHostRules: 'Host 請求變換', + e2bHostRulesHelp: '按 host 注入 header。規則本身不授權出網,host 必須同時出現在放行目標裡。', + ruleUntitled: '未命名規則', + expandRule: '展開規則', + collapseRule: '收起規則', + moveRuleUp: '上移規則', + moveRuleDown: '下移規則', + ruleName: '規則名', + ruleScheme: '協議', + ruleSni: 'SNI', + ruleHost: 'Host', + ruleMethods: 'HTTP 方法', + rulePath: '路徑', + ruleAction: '動作', + ruleAllow: '放行', + ruleDeny: '拒絕', + ruleAudit: '稽核級別', + ruleInject: '注入 Header', + headerName: 'Header 名稱', + headerValue: 'Header 值', + addTarget: '新增目標', + addRule: '新增規則', + addHeader: '新增 Header', + removeRule: '刪除該規則', + noConfigs: '還沒有沙箱設定。智慧代理未選擇空間設定時不會執行技能指令碼。', + identityFieldHint: '該設定下有沙箱運行時,以下項無法修改:後端類型、API 端點、API Key、沙箱域名、Proxy 端點。', + connectionLockedBySkills: '該沙箱已安裝 Skill。連結地址、憑據和 DNS 會改變技能快照所屬環境,且 DNS 需重建模板才能生效;請新建一份沙箱。', + connectionLockedByInFlight: '該沙箱正在安裝或移除 Skill,完成前不能更換連結、憑據或 DNS。', + viewSandboxes: '運行實例', + inventoryTitle: '運行實例', + inventoryDrawerDesc: '該設定當前佔用的沙箱,以及受影響的會話與智慧代理。', + inventoryFailed: '獲取沙箱佔用失敗', + sandboxCount: '沙箱數量', + sandboxCountUnknown: '未知(無法連結該後端)', + inventoryUnverifiableHint: '無法連結該後端,因此沙箱數量未知──這不代表沒有沙箱。', + inventorySessions: '會話', + inventorySessionKind: '對話', + inventoryEmpty: '暫無佔用的會話', + inventoryAgentsTitle: '關聯智慧代理', + inventoryUntitledSession: '未命名會話', + sandboxesStillLive: '該設定仍有 {count} 個運行中或已暫停的沙箱,暫時無法修改身份欄位。', + blockedHint: '可結束或刪除這些會話(刪除會話會銷毀其沙箱),或新建一份設定並把智慧代理指過去。', + unverifiableBlocked: '無法連結該後端核實是否仍有沙箱,因此不能覆蓋現有憑據。', + unverifiableSaveHint: '請先復原該後端的連通性;若已廢棄,可新建一份設定並把智慧代理指過去。', + affectedSessions: '影響 {count} 個會話。', + affectedAgents: '以下智慧代理正在使用該設定:{names}', + confirmDelete: '確定刪除沙箱「{name}」嗎?', + confirmDeleteWithAgents: '確定刪除沙箱「{name}」嗎?{agents}它們將在下次執行技能時回報錯誤。', + deleteFailed: '刪除失敗', + deleted: '已刪除', + forceDeleteTitle: '無法核實沙箱佔用', + forceDeleteConfirm: '無法連結該後端核實是否仍有沙箱。若該後端已廢棄,可強制刪除這份設定;若只是暫時不可達,強制刪除會讓殘留沙箱無人回收。仍要強制刪除嗎?', + forceDelete: '強制刪除', + disableScripts: '停用沙箱執行', + enableScripts: '啟用沙箱執行', + disableScriptsConfirm: + '停用後,本空間內所有智慧代理將無法在沙箱中執行技能指令碼;仍可閱讀技能內容。已在運行中的遠端沙箱不會自動銷毀,需結束或刪除相關會話後才會釋放。是否繼續?', + scriptsDisabled: '已停用本空間沙箱執行', + scriptsEnabled: '已復原本空間沙箱執行', + policySaveFailed: '更新沙箱執行策略失敗', + legacyConfig: '已廢棄', + namedBackendHint: '空間設定是唯一運行時來源;智慧代理沒有選擇設定時不會執行技能指令碼。', + weknoraTemplateTitle: 'WeKnora 標準模板', + weknoraDockerImage: 'WeKnora 標準映像', + weknoraDockerImageHint: '每次會話獨佔一個長駐容器,指令碼、shell 命令與檔案都在同一個容器內,會話結束或空閒超時後回收。', + weknoraTemplateOverview: 'WeKnora 負責提供標準運行環境。連結叢集後會自動發現模板,缺少標準模板時自動建立。', + weknoraTemplateDescription: '包含 WeKnora 技能所需的 Python、Node.js、CLI 工具、工作目錄和非 root 執行使用者。', + recommendedTag: '推薦', + templateNotConfigured: '未設定模板', + cardTemplateConfigured: '模板已設定', + cardCredentialMissing: '缺少 API Key', + cardTimeout: '超時 {sec}s', + cardTtl: '沙箱存活 {sec}s', + cardVolumeMounted: '已掛載卷', + cardEnvVars: '{count} 個環境變數', + cardPrivateEndpoints: '允許存取私網', + imageNotConfigured: '未設定映像', + templateApplied: '已使用', + refreshTemplates: '重新整理模板', + templateSelectHelp: '模板由當前叢集實時返回,儲存時僅記錄模板 ID,無需手工複製。', + templateSelectPlaceholder: '先連結叢集並載入模板', + templateLoadHint: '填寫叢集連結後重新整理模板。沒有官方標準模板時,會從 Docker Hub 映像自動建構。桌面模板體積更大,需在下方單獨點「建立」。改 DNS 或映像後在對應卡片上點「重建」。', + templateLoadFailed: '模板清單載入失敗', + standardTemplateProvisioning: '已開始在叢集中建立 WeKnora 標準模板,請稍後重新整理查看狀態', + standardTemplateReplaced: '已刪除原標準模板並開始重建,請等待狀態就緒', + templateNotReady: '所選模板尚未建構完成,請重新整理並等待狀態就緒', + connectionPassed: '連結驗證透過,以下模板均從當前叢集實時載入。', + connectionPassedTitle: '叢集連結成功', + templateStepHint: '進入此步會列出叢集模板;若還沒有官方標準模板,會從 Docker Hub 映像自動建構。桌面模板(XFCE)體積較大,需單獨點「建立」。改 DNS 或映像後在對應卡片上點「重建」。選好並就緒後才能繼續。', + loadingTemplates: '正在從叢集載入模板…', + templateBuildingHint: '模板正在建構,清單會自動重新整理。', + templateUntaggedHint: '建構已完成,但沒有建構帶 default 標籤,建立沙箱時無法解析。請在 E2B 刪除該模板,重新整理後 WeKnora 會重新建構。', + templateFailedReason: '建構失敗:{reason}', + noTemplates: '當前叢集未返回可用模板。', + weknoraStandardTemplate: 'WeKnora 標準模板', + createStandardTemplate: '建立', + createStandardTemplateHint: '按當前連結設定建構,包含 DNS。之後改設定可在卡片上重建。', + weknoraDesktopTemplate: 'WeKnora 桌面模板', + createDesktopTemplate: '建立', + createDesktopTemplateHint: '從官方桌面映像建構 XFCE 圖形桌面。體積明顯大於標準模板,僅在需要圖形界面時建立。', + replaceStandardTemplate: '重建', + replaceStandardTemplateConfirm: '將用當前設定(含 DNS)重建 WeKnora 標準模板。新模板就緒前不會刪除仍可啟動的舊模板。', + desktopTemplateProvisioning: '已開始在叢集中建立 WeKnora 桌面模板,請稍後重新整理查看狀態', + desktopTemplateReplaced: '已刪除原桌面模板並開始重建,請等待狀態就緒。標準(CLI)模板不受影響。', + desktopTemplateTag: '桌面', + replaceDesktopTemplateConfirm: '將用當前設定(含 DNS)重建 WeKnora 桌面模板。新模板就緒前不會刪除仍可啟動的舊桌面模板,也不會刪除標準(CLI)模板。', + templateLockedBySkills: '該沙箱已安裝 Skill,技能環境綁在當前快照上,不能更換或重建運行模板。請新建一份沙箱,從新模板再裝 Skill。', + templateLockedByInFlight: '該沙箱正在安裝或移除 Skill,完成前不能更換或重建運行模板。', + templateUnnamed: '未命名模板', + templateFieldImage: '映像', + templateFieldVersion: '版本', + templateFieldId: 'ID', + templateFieldCreated: '建立時間', + templateFieldInstance: '規格', + templateFieldNetwork: '網路', + templateFieldInternet: '公網存取', + templateInternetOn: '已開啟', + templateInternetOff: '已關閉', + templateReadyHint: '模板「{name}」已就緒並選中。', + templateProvisioningHint: '模板仍在建構中,狀態會自動重新整理。', + templateStatuses: { + ready: '已就緒', + building: '建構中', + untagged: '缺少 default 標籤', + failed: '失敗', + unknown: '未知', + }, + allowPrivateEndpoints: '允許存取私網叢集地址', + allowPrivateEndpointsHint: '僅用於自建 Cube 等私網控制面;雲元資料等鏈路本地地址始終禁止存取。', + howToBuildTemplate: '沙箱叢集搭建與模板說明', + noEnvVars: '暫無額外環境變數。', + fieldRequired: '必填', + cubeApiKeyOptional: '可留空 ── 自建 CubeSandbox 通常無鑑權', + cubeApiKeyWhere: '自建叢集如何開啟鑑權', + cubeDnsServers: 'DNS 伺服器', + cubeDnsServersHelp: '可選。寫入 WeKnora 標準模板的 nameserver(須為 IP)。留空則使用叢集預設(常見 119.29.29.29)。私網或雲上 UDP 53 出不去時,填 Cube 宿主機 /etc/resolv.conf 裡能用的地址,並避開 10/8、172.16/12、192.168/16。已有標準模板需在模板卡片上點「重建」才會生效。', + cubeDnsServersPlaceholder: '例如 8.8.8.8,Enter新增', + e2bApiKeyHelp: '在 E2B 控制台的 API Keys 頁面建立,通常以 e2b_ 開頭。', + e2bApiKeyWhere: '前往 E2B 控制台獲取 API Key', + apiKeyPlaceholder: '貼上 API Key', + secretConfigured: '已設定金鑰(不可回看);輸入新值可輪換', + secretKeepHint: '已設定,留空表示不修改', + e2bApiUrlOptional: '可留空 ── 留空時使用 SDK 預設值', + e2bDomainOptional: '可留空 ── 留空時使用 SDK 預設值', + e2bProxyUrlOptional: '自建 E2B 相容叢集的資料面閘道地址;留空表示按 sandbox domain 直連(E2B Cloud 用法)', + backends: { + disabled: '停用', + local: '本地行程', + docker: 'Docker', + cube: 'CubeSandbox', + e2b: 'E2B', + }, + apiUrl: 'API 端點', + proxyUrl: 'Proxy 端點', + sandboxDomain: '沙箱域名', + apiKey: 'API Key', + templateId: '模板 ID', + httpTimeout: 'HTTP 超時(秒)', + httpTimeoutHelp: '呼叫沙箱管理介面的等待上限,超過即視為端點不可用。留空按 30 秒。', + sandboxTtl: '沙箱 TTL(秒)', + sandboxTtlHelp: '沙箱多久之後會暫停', + dockerImage: 'Docker 映像', + dockerHost: 'Docker 守護行程地址', + dockerHostHelp: '留空跟隨本機 docker CLI(DOCKER_HOST 或當前 docker context),不必手填 /var/run/docker.sock。遠程守護行程填 tcp://host:2376,必須同時填寫 TLS 證書目錄,私網地址還要開啟「允許存取私網地址」。', + dockerTlsCertPath: 'TLS 證書目錄', + dockerTlsCertPathHelp: 'WeKnora 所在主機上包含 ca.pem、cert.pem、key.pem 的目錄。遠程守護行程必填,證書不入庫,由部署方掛載。', + dockerIdleTtl: '空閒回收(秒)', + dockerIdleTtlHelp: 'Docker 守護行程本身沒有空閒超時。容器多久沒有執行任何命令就會被 WeKnora 回收,會話繼續時重建。留空按 1800 秒。', + dockerCpuLimit: 'CPU 核數上限', + dockerCpuLimitHelp: '單個沙箱可用的 CPU 核數,0 使用內建預設。', + dockerMemoryLimit: '記憶體上限(MB)', + dockerMemoryLimitHelp: '單個沙箱的記憶體上限(MB),0 使用內建預設。', + dockerPidsLimit: '行程數上限', + dockerPidsLimitHelp: '單個沙箱可建立的行程數上限,0 使用內建預設。', + dockerNetworkMode: '網路模式', + dockerNetworkModeHelp: '預設 bridge,技能安裝依賴需要出網。選擇 none 表示完全禁止出網。Docker 只能按網路隔離,無法按域名放行。', + dockerNetworkBridge: 'bridge(允許出網)', + dockerNetworkNone: 'none(禁止出網)', + defaultTimeout: '執行超時(秒)', + defaultTimeoutHelp: '單次技能指令碼允許運行的最長時間,超時會被強制終止。留空按 60 秒。', + terminalIdleDisconnect: '終端 / 桌面空閒斷開(秒)', + terminalIdleDisconnectHelp: '打開終端或桌面後,這段時間內沒有交互就斷開連結,沙箱隨後按 TTL 自行暫停。終端看鍵盤和輸出,桌面看鍵鼠。留空按 900 秒;最短 60 秒,最長 24 小時。', + envVars: '環境變數', + envKey: '變數名', + envValue: '變數值', + envVarsHint: '注入到該設定下所有沙箱;值加密存儲,但對沙箱內指令碼可見。\n只會在沙箱建立時注入,如果要實時注入請在「沙箱金鑰」頁面新增。', + addRow: '新增變數', + removeRow: '刪除', + save: '儲存', + saveAndContinue: '儲存並繼續', + saved: '已儲存,對新建會話生效', + saveFailed: '儲存失敗', + testConnection: '測試連結', + deepCheck: '完整驗證', + recheck: '重新驗證', + deepCheckIntro: '完整驗證會真實建立一個臨時沙箱、執行一次指令碼並檢查出網,隨後自動銷毀。', + deepCheckConfirm: '完整驗證會執行一次臨時指令碼;遠端後端還會真實建立並銷毀一個沙箱,可能消耗少量沙箱時長。是否繼續?', + checkPassed: '檢測透過', + checkFailed: '檢測未透過', + checkScopeConnection: '本次只驗證了控制面:端點可達且憑據有效。是否真的能跑起指令碼還沒有驗證。', + checkScopeFull: '端點、憑據、模板、沙箱內執行與出網均已真實驗證。', + checkScopePolicyRestricted: '出網按策略受限,未做真實出網探測;端點、憑據、模板與沙箱內執行已驗證。', + checkPendingHint: '{names} 需要「完整驗證」才能確認:會真實建立一個臨時沙箱、執行一次指令碼再銷毀。', + skipReasons: { + needs_deep_check: '需完整驗證', + control_plane_unreachable: '控制面不可達,已跳過', + sandbox_not_created: '沙箱未建立,已跳過', + sandbox_exec_failed: '沙箱內執行失敗,已跳過', + egress_restricted_by_policy: '按網路策略受限(該設定預設拒絕出網)', + }, + checks: { + client_build: '用戶端建構', + api_url_reachable: '端點可達性', + credential_valid: '憑據有效性', + template_exists: '模板存在性', + sandbox_exec: '沙箱內執行', + egress_available: '出網可用', + }, + manageSkills: '管理技能', + cardSkillsNone: '尚未安裝技能', + cardSkillsMore: '+{count}', + skillInstallerModel: '安裝模型', + skillInstallerModelHint: '安裝技能時由內建安裝智慧代理呼叫。請選擇支持工具呼叫的對話模型。', + skillInstallerModelRequired: '請先選擇安裝模型', + skillInstallerModelSaveFailed: '儲存安裝模型失敗', + skillRollout: '技能映像如何生效', + skillRolloutHint: '安裝或刪除技能會生成新映像。這裡決定已經打開的會話要不要換到新映像。', + skillRolloutNextTurn: '已有會話在下一輪提問時重建沙箱', + skillRolloutNewSession: '已有會話保持原沙箱,僅新會話使用新映像', + skillRolloutSaveFailed: '儲存生效方式失敗', + skillInstallGroup: '安裝新技能', + skillInstalledGroup: '已安裝', + skillUploadClick: '點擊上傳 zip 壓縮包', + skillUploadDrag: '或將檔案拖到此處', + skillUploadHint: '安裝會在當前映像上生成新快照,可能需要數分鐘。當前這一輪對話不會中斷;下一輪提問時才會按新映像重建沙箱,會話工作區草稿會在那時清空。', + skillUploadHintNewSession: '安裝會在當前映像上生成新快照,可能需要數分鐘。已打開的會話繼續使用原沙箱,直到該會話結束;只有新打開的會話才會帶上這次安裝的技能。', + skillSourceSection: '從來源安裝', + skillSourceSectionHint: '貼上 ClawHub、GitHub 或 SkillHub 連結,或 {\'@\'}owner/slug。壓縮包不超過 {size} MB。', + skillUploadSection: '上傳本地壓縮包', + skillUploadSectionHint: '把包含 SKILL.md 的 zip 拖到下方,或點擊選擇檔案。壓縮包不超過 {size} MB。', + skillSourcePlaceholder: 'ClawHub 用 {\'@\'}owner/slug,GitHub / SkillHub 請貼上完整連結', + skillSourceInstall: '安裝', + skillInstallOr: '或', + skillSourceFailed: '從託管平台安裝技能失敗', + skillUploadFailed: '技能上傳失敗', + skillBundleTooLarge: '技能壓縮包不能超過 {size} MB。', + skillBundleTooManyFiles: '技能目錄裡的檔案不能超過 {count} 個。', + skillBundleTooManyZipEntries: '壓縮包條目不能超過 {count} 個。', + skillUploading: '正在上傳 {percent}%', + skillUploadAccepted: '已開始安裝技能', + skillStatusInstalling: '安裝中', + skillStatusReady: '已就緒', + skillStatusFailed: '安裝失敗', + skillStatusRemoving: '刪除中', + skillStatusLabel: '狀態', + skillDisableHint: '停用後該技能對智慧代理不可見,檔案仍保留在映像中。變更將在會話下一次執行時生效。', + skillDeleteHint: '刪除會從映像中移除該技能目錄並生成新快照。當前這一輪對話不會中斷;下一輪提問時才會按新映像重建沙箱,會話工作區草稿會在那時清空。', + skillDeleteHintNewSession: '刪除會從映像中移除該技能目錄並生成新快照。已打開的會話繼續使用原沙箱,直到該會話結束;只有新打開的會話才會去掉該技能。', + skillRemoveInProgress: '正在解除安裝', + skillRemoveWaiting: '已開始從映像解除安裝,正在等待進度…', + skillRemoveDone: '已從沙箱解除安裝「{name}」。技能仍在目錄裡,可以稍後再裝回去。', + skillRemoveStage: { + accepted: '已接受解除安裝請求', + sandbox_ready: '正在打開維護沙箱', + removed: '檔案已刪除,正在生成新映像', + done: '解除安裝完成', + failed: '解除安裝失敗', + }, + imageInfoTitle: '當前映像', + imageInfoSnapshot: '快照 ID', + imageInfoGeneration: '版本', + imageInfoBuiltAt: '建構時間', + imageInfoBaseTemplate: '基礎模板', + imageInfoRuntimeTemplate: '運行模板', + imageInfoUsingBase: '尚未安裝技能,會話使用所選運行模板啟動。', + imageInfoEmpty: '使用基礎模板', + imageInfoUnset: '未設定', + skillTranscript: '查看安裝過程', + skillTranscriptLive: '安裝過程', + skillTranscriptLiveHint: '正在安裝,點擊查看過程', + skillTranscriptTitle: '安裝過程', + skillTranscriptHide: '收起安裝過程', + skillGuidance: { + placeholder: '補充安裝說明,例如需要安裝的 CLI、安裝文件或環境限制', + send: '傳送說明', + retry: '攜帶說明重新安裝', + pending: '待處理', + injected: '已注入', + unprocessed: '未處理,請重新安裝時補充', + unavailable: '當前階段暫不接收說明;安裝結束後可攜帶說明重試。', + failed: '傳送失敗,說明已保留,請重試。', + }, + skillTranscriptEmpty: '這次安裝沒有留下記錄。', + skillTranscriptWaiting: '安裝已開始,正在等待過程記錄…', + installCommandRunning: "命令執行中", + installCommandWaiting: "等待命令輸出,耗時持續更新。", + skillFiles: '查看檔案', + skillFilesTitle: '檔案', + skillFilesEmpty: '該技能還沒有可查看的檔案。', + skillFilesLoadFailed: '載入技能檔案失敗', + skillFilesFileLoadFailed: '無法讀取該檔案', + skillFilesBinary: '該檔案是二進位內容,無法線上預覽。', + skillFilesTruncated: '檔案較大,僅顯示前一部分。', + skillFilesSelectHint: '選擇左側檔案以查看內容', + skillFilesPreview: '預覽', + skillFilesSource: '源碼', + skillLoadFailed: '載入技能清單失敗', + skillToggleFailed: '更新技能狀態失敗', + skillDeleteAccepted: '已開始刪除技能', + skillRetry: '重新安裝', + skillRetryHint: '用已儲存的安裝包重試,無需重新上傳', + skillRetryAccepted: '已開始重新安裝', + skillRetryFailed: '重新安裝失敗', + skillStop: '停止安裝', + skillStopHint: '中止當前安裝,之後可以重試或解除安裝', + skillStopAccepted: '已停止', + skillStopFailed: '停止失敗', + skillEmpty: '尚未安裝技能。貼上託管平台連結,或上傳 zip。', + skillVersion: '版本', + skillVersionEmpty: '未填寫', + skillError: '錯誤', + skillEnabled: '已啟用技能', + skillDisabled: '已停用技能', + skillEnv: { + toggle: '環境變數', + toggleHide: '收起環境變數', + none: '這個技能沒有聲明環境變數。', + workspaceTitle: '空間共用值', + workspaceHint: '所有沒有填寫自己值的成員都會用這裡的值。成員可以在「設定 → 沙箱金鑰」裡填自己的值。', + required: '必填', + isSet: '已設定', + notSet: '未設定', + placeholderSet: '已存值,填入新值即取代', + placeholderUnset: '填入值', + save: '儲存', + saveSuccess: '空間共用值已儲存', + saveFailed: '空間共用值儲存失敗。', + clear: '清除', + clearConfirm: '清除 {name} 的空間共用值?聲明會保留,沒有自己值的成員之後會缺少這個值。', + clearSuccess: '已清除空間共用值。', + valueTooLong: '單個值不能超過 {max} 位元組。' + }, + }, + skills: { + title: '技能管理', + description: '技能屬於空間目錄,可以只登記,也可以裝到一份或多份沙箱。智慧代理只能啟用當前沙箱裡已就緒的技能。', + helpTooltip: '目錄裡的技能可以不裝任何沙箱。指令碼要跑起來,必須裝進智慧代理所用的那份沙箱映像。Docker、Cube、E2B 互不通用,裝到幾份就要裝幾次。', + hostTarget: '本機', + host: { + description: '技能屬於空間目錄。裝到這台電腦上之後,智慧代理才能啟用。', + helpTooltip: '目錄裡的技能可以先只登記。指令碼要跑起來,需要裝到這台電腦上。', + emptyDesc: '還沒有技能。新增後會裝到這台電腦上。', + addStepInstallDesc: '確認解析結果後選擇安裝模型。技能會裝到這台電腦上。', + installToSandbox: '安裝到本機', + installToSandboxDesc: '安裝會在這台電腦上準備依賴,裝好後智慧代理可以直接使用。', + installDrawerDesc: '把「{name}」裝到這台電腦上。', + noInstalls: '尚未安裝到本機', + installedOnName: '已安裝到本機', + manageDrawerDesc: '在這台電腦上管理啟用、變數和解除安裝。', + manageUninstall: '從本機解除安裝', + manageUninstallConfirm: '確定從這台電腦解除安裝「{name}」?', + deleteCatalogConfirm: '確定從目錄刪除「{name}」?請先從本機解除安裝。', + deleteCatalogBlocked: '請先從本機解除安裝此技能。', + upgradeDrawerDesc: '把「{name}」升級到目錄中的當前版本。升級期間繼續使用當前版本,升級失敗也不影響它。', + disableHint: '停用後該技能對智慧代理不可見,檔案仍留在這台電腦上。變更將在會話下一次執行時生效。', + removeDone: '已從本機解除安裝「{name}」。技能仍在目錄裡,可以稍後再裝回去。', + removeWaiting: '已開始解除安裝,正在等待進度…', + removeSandboxReady: '正在準備本機目錄', + removeRemoved: '檔案已刪除', + envWorkspaceHint: '所有沒有填寫自己值的成員都會用這裡的值。成員可以在「設定 → 環境變數」裡填自己的值。', + }, + goSandboxSettings: '去設定沙箱', + noConfigsDesc: '還沒有沙箱,技能需要先有一份可寫入的映像。', + addSkill: '新增技能', + addDrawerDesc: '貼上來源或上傳 zip,登記到目錄。可以選擇現在裝進哪些沙箱。', + addProgress: '新增進度', + addStepRegister: '登記', + addStepInstall: '安裝', + addStepRegisterDesc: '貼上來源或上傳 zip,先登記到空間目錄。', + addStepInstallDesc: '確認解析結果後,選擇要寫入的沙箱。也可以跳過,稍後在清單裡安裝。', + addFinish: '完成', + addRegisteredAs: '已登記為「{name}」', + addFileSelected: '已選擇 {name}', + addClearFile: '清除', + emptyDesc: '還沒有技能。新增後可以裝到一份或多份沙箱。', + emptyNoSandboxHint: '當前沒有沙箱。帶指令碼的技能登記後無法運行,可先去設定沙箱。', + installSkill: '新增技能', + installDrawerDesc: '安裝到「{name}」的映像。', + installToSandbox: '安裝到沙箱', + installToSandboxDesc: '每種沙箱後端要單獨安裝一次。Docker、Cube、E2B 的映像互不通用。', + pickSandboxes: '安裝到哪些沙箱', + pickSandboxesHint: '技能會寫入所選沙箱當前使用的映像。Docker、Cube、E2B 互不通用,勾幾份就裝幾次。現在可以不選,稍後在目錄裡再裝。', + noSandboxToInstall: '沒有可寫入的沙箱。', + noInstalls: '尚未裝到任何沙箱', + installedOn: '已安裝到', + installedOnName: '已安裝到 {name}', + installedCount: '已安裝到 {count} 個沙箱', + installPanelGroup: '已安裝', + installPanelAvailable: '未安裝', + viewInstallProgress: '查看進度', + manageOnSandbox: '管理沙箱「{name}」上的安裝', + manageDrawerDesc: '在沙箱「{name}」上管理啟用、變數和解除安裝。', + manageEnable: '啟用', + manageUninstall: '從沙箱解除安裝', + manageUninstallConfirm: '確定從該沙箱解除安裝「{name}」?', + deleteCatalog: '從目錄刪除', + deleteCatalogConfirm: '確定從目錄刪除「{name}」?請先從所有沙箱解除安裝。', + deleteCatalogBlocked: '請先從所有沙箱解除安裝此技能。', + deleteSuccess: '已從目錄刪除', + registerAccepted: '已新增到目錄', + installAccepted: '已開始安裝', + installPartial: '部分沙箱已開始安裝,{failed} 個未能開始。', + installOutdated: '與目錄版本不同', + upgrade: '升級', + upgradeCount: '升級 {count} 個', + upgradeTitle: '升級技能', + upgradeDrawerDesc: '把「{name}」在所選沙箱上的舊版本升級到目錄中的當前版本。升級期間沙箱繼續使用舊版本,升級失敗也不影響它。', + upgradeAvailable: '可升級', + upgradeFromTo: '可升級 {from} → {to}', + upgradeAccepted: '已開始升級', + noSandboxToUpgrade: '沒有需要升級的沙箱。', + upgradeRowTitle: '有新版本', + upgradeRowHint: '此沙箱上的版本與目錄不同。升級期間繼續使用當前版本,升級失敗也不影響它。', + upgradeRowHintVersions: '此沙箱是 {from},目錄是 {to}。升級期間繼續使用 {from},升級失敗也不影響它。', + upgradeRowHintFailed: '此沙箱上的安裝未成功,目錄中已是另一個版本。升級會改裝目錄版本。', + upgradeRowHintFailedVersions: '此沙箱上 {from} 的安裝未成功,目錄中是 {to}。升級會改裝 {to}。', + servedWhileUpgrading: '升級中,仍在使用 {version}', + servedWhileUpgradingPlain: '升級中,仍在使用舊版本', + servedAfterFailure: '升級失敗,仍在使用 {version}', + servedAfterFailurePlain: '升級失敗,仍在使用舊版本', + loadFailed: '載入失敗', + }, + mcpService: 'MCP服務', + versionInfo: '版本資訊', + taskQueue: '任務佇列', + tenantInfo: '空間資訊', + workspaceSettings: '空間設定', + system: '系統設定', + storage: { + title: '存儲引擎', + description: '設定文件與圖片的存儲方式。此處設定各引擎參數,知識庫中僅選擇使用哪個引擎。', + basicSection: '基本設定', + modeSection: '部署模式', + credentialsSection: '憑證', + bucketSection: 'Bucket', + useSslDesc: '透過 HTTPS 存取 MinIO', + loading: '載入中...', + retry: '重試', + defaultEngine: '預設引擎', + defaultEngineDesc: '新建知識庫時預設選用的存儲引擎', + engineLocal: 'Local(本地)', + engineCos: '騰訊雲 COS', + engineTos: '火山引擎 TOS', + engineOss: '阿里雲 OSS', + localTitle: 'Local(本地存儲)', + localDesc: '使用伺服器本地檔案系統存儲檔案,僅適合單機部署。', + available: '可用', + needsConfig: '需要設定', + configurable: '可設定', + pathPrefix: '路徑前綴(可選)', + pathPrefixPlaceholder: '如 weknora/images', + prefixPlaceholder: '如 weknora', + bucketName: 'Bucket 名稱', + bucketPlaceholder: '存儲桶名稱', + minioDesc: 'S3 相容的自託管物件存儲,適合內網和私有雲部署。', + minioDocker: 'Docker 部署', + minioRemote: '遠程 MinIO', + minioDockerDetected: '已檢測到 Docker 部署的 MinIO 環境變數,連結資訊由環境變數提供,無需手動填寫。', + minioDockerNotDetected: '未檢測到 MinIO 環境變數(MINIO_ENDPOINT 等),請確認 Docker Compose 設定正確。', + minioRemoteHint: '連結到遠程 MinIO 服務,需要手動填寫連結資訊。', + cosTitle: '騰訊雲 COS', + cosDesc: '騰訊雲物件存儲服務,適合公有雲部署,支持 CDN 加速。', + cosSecretIdPlaceholder: '騰訊雲 API 金鑰 SecretId', + cosSecretKeyPlaceholder: '騰訊雲 API 金鑰 SecretKey', + cosAppIdPlaceholder: '騰訊雲帳號 AppID', + tosTitle: '火山引擎 TOS', + tosDesc: '火山引擎物件存儲服務(TOS),適合公有雲部署。', + tosAccessKeyPlaceholder: '火山引擎 Access Key', + tosSecretKeyPlaceholder: '火山引擎 Secret Key', + s3Title: 'AWS S3', + s3Desc: 'AWS S3 及相容的物件存儲服務,適合公有雲部署。', + s3AccessKeyPlaceholder: 'AWS Access Key', + s3SecretKeyPlaceholder: 'AWS Secret Key', + s3DefaultCredentialsHint: 'Access Key 與 Secret Key 同時留空時,將使用 AWS 預設憑證鏈(IAM Role、IRSA / Web Identity、環境變數或共享設定)。', + s3EndpointPlaceholder: '可選,留空使用 AWS 區域預設端點', + ks3Title: '金山雲 KS3', + ks3Desc: '金山雲物件存儲服務(KS3),適合公有雲部署。', + ks3AccessKeyPlaceholder: '金山雲 Access Key', + ks3SecretKeyPlaceholder: '金山雲 Secret Key', + ks3EndpointPlaceholder: 'e.g. ks3-cn-beijing.ksyuncs.com', + ks3RegionPlaceholder: 'e.g. BEIJING', + engineKs3: '金山雲 KS3', + obsTitle: '華為雲 OBS', + obsDesc: '華為雲物件存儲服務(OBS),適合公有雲部署。', + obsAccessKeyPlaceholder: '華為雲 Access Key', + obsSecretKeyPlaceholder: '華為雲 Secret Key', + obsEndpointPlaceholder: 'e.g. obs.cn-north-4.myhuaweicloud.com', + obsRegionPlaceholder: 'e.g. cn-north-4', + engineObs: '華為雲 OBS', + ossTitle: '阿里雲 OSS', + ossDesc: '阿里雲物件存儲服務(OSS),適合公有雲部署。', + ossAccessKeyPlaceholder: '阿里雲 Access Key', + ossSecretKeyPlaceholder: '阿里雲 Secret Key', + console: '控制台', + docs: '文件', + testConnection: '測試連結', + loadFailed: '載入失敗', + saveSuccess: '已儲存', + saveFailed: '儲存失敗', + unknownError: '未知錯誤', + requestFailed: '請求失敗' + }, + storageBackend: { + description: '管理檔案與圖片使用的存儲實例;同一種類型可以設定多個實例。', + empty: '尚未設定存儲實例', + defaultTag: '預設', + add: '新增存儲實例', + editTitle: '編輯存儲實例', + createTitle: '新增存儲實例', + editSubtitle: '修改此存儲實例的連結設定。', + createSubtitle: '為檔案與圖片新增一個存儲實例。', + basicSection: '基本資訊', + nameLabel: '名稱', + namePlaceholder: '例如:生產 COS、歸檔 COS', + providerLabel: '存儲類型', + modeLabel: '部署模式', + modeRemote: '遠程實例', + modeEnv: '環境變數', + connectionSection: '連結設定', + optionalPlaceholder: '可選', + advancedSection: '進階選項', + pathPrefixLabel: '路徑前綴', + useSslDesc: '使用 HTTPS 存取 MinIO', + forcePathStyleDesc: '使用 Path Style', + useTempBucketDesc: '使用臨時桶', + tempBucketLabel: '臨時桶', + tempBucketPlaceholder: '可選,用於臨時檔案', + tempRegionLabel: '臨時桶 Region', + tempRegionPlaceholder: '留空時使用主 Region', + testConnection: '測試連結', + localStorage: '本地存儲', + setDefault: '設為預設', + edit: '編輯', + delete: '刪除', + testSuccess: '連結成功', + testFailed: '連結失敗', + nameRequired: '請輸入名稱', + saveSuccess: '已儲存', + saveFailed: '儲存失敗', + defaultUpdated: '預設存儲已更新', + deleteTitle: '刪除存儲實例', + deleteConfirm: '確定刪除「{name}」嗎?', + deleted: '已刪除', + deleteFailed: '刪除失敗' + }, + parser: { + title: '解析引擎', + description: '文件解析引擎狀態及設定。此處設定優先於伺服器端環境變數,留空則使用環境變數預設值。', + supportedFileTypes: '支持檔案類型', + statusSection: '狀態資訊', + configSection: '設定', + featuresLabel: '識別選項', + loading: '載入中...', + retry: '重試', + noEngineDetected: '未檢測到解析引擎,請確認 DocReader 服務正常運行。', + disconnected: '未連結', + connected: '已連結', + available: '可用', + unavailable: '不可用', + builtinDesc: 'DocReader 內建解析引擎(docx/pdf/xlsx 等複雜格式)', + currentAddr: '當前', + envVarHint: '修改請設定環境變數 DOCREADER_ADDR、DOCREADER_TRANSPORT(grpc/http),重啟服務生效。', + selfHostedEndpoint: '自建端點', + formulaRecognition: '公式識別', + tableRecognition: '表格識別', + parseMethodLabel: 'PDF 解析方式', + parseMethodAuto: '自動識別(推薦)', + parseMethodOCR: '強制 OCR', + parseMethodText: '僅提取文字', + parseMethodHint: '自動模式會為掃描件啟用 OCR,電子版 PDF 直接提取文字。', + sealRecognition: '印章識別', + chartRecognition: '圖表識別', + language: '語言', + testConnection: '測試連結', + docs: '文件', + loadFailed: '載入解析引擎清單失敗', + ensureDocreaderConnected: '請先確保 DocReader 服務已透過環境變數設定並已連結', + checkDoneStatusUpdated: '已使用當前填寫參數檢測,上方狀態已更新', + checkSuccess: '測試連結成功', + checkFailed: '檢測失敗', + saveSuccess: '已儲存', + saveFailed: '儲存失敗', + mineruEndpointPlaceholder: '如 https://your-mineru.example.com', + defaultPipeline: '預設 pipeline', + languagePlaceholder: '如 ch、en、ja(預設 ch)', + mineruCloudApiKeyPlaceholder: 'MinerU 雲服務 API Key', + vlmLabel: 'vlm(視覺語言模型)', + mineruHtmlLabel: 'MinerU-HTML(HTML 解析)', + serverUrl: '伺服器地址', + vlmServerUrlPlaceholder: '如 http://your-vllm-server:8000', + vlmServerUrlHint: '當 Backend 選擇 vlm-http-client 或 hybrid-http-client 時需要填寫', + mineruEndpointHint: '自動識別服務版本:MinerU 4.0 及以上走 V1 API,更早版本走 /file_parse。', + mineruServerApiKeyPlaceholder: '伺服器端啟動參數 --api-key 的值(未啟用鑑權可留空)', + mineruServerApiKeyHint: '僅 MinerU 4.0 及以上使用。', + mineruTierLabel: '解析檔位', + mineruTierDefault: '伺服器端預設(優先 standard)', + mineruTierFlash: 'flash(最快,品質最低)', + mineruTierBasic: 'basic(基礎模型,CPU 可運行)', + mineruTierStandard: 'standard(VLM,高品質)', + mineruTierAdvanced: 'advanced(VLM,品質最高、最慢)', + mineruTierHint: '僅 MinerU 4.0 及以上生效;可選檔位取決於伺服器端啟動時的 --tier。', + mineruLegacySection: '舊版參數(MinerU 3.x 及更早)', + mineruLegacySectionHint: 'MinerU 4.0 已移除以下請求參數,連結 4.0 及以上服務時會被忽略;VLM 地址改在 MinerU 伺服器端設定。', + paddleocrVlEndpointPlaceholder: '如 http://your-paddleocr-vl:8080', + paddleocrVlEndpointHint: '填寫 PaddleOCR-VL 完整服務(pipeline)地址,無需 /layout-parsing 後綴', + paddleocrVlCloudTokenPlaceholder: 'PaddleOCR-VL 飛槳星河社區 Token' + }, + weknoraCloud: { + title: 'WeKnora Cloud', + description: '設定 WeKnora Cloud 的 APPID 和 APPSECRET 憑證。憑證用於模型服務和文件解析引擎。', + viewDocs: '查看文件', + unconfigured: '尚未設定憑證,請填寫 APPID 和 APPSECRET', + configured: '憑證已設定,狀態正常', + expired: 'WeKnora Cloud 憑證已失效', + expiredDefault: '服務重啟後加密金鑰已變更,已儲存的憑證無法解密。請重新填寫憑證。', + reconfigure: '重新設定', + appIdLabel: 'APPID', + appIdDesc: 'WeKnora Cloud 的應用 ID', + appIdPlaceholder: '請輸入 APPID', + appSecretLabel: 'APPSECRET', + appSecretDesc: 'WeKnora Cloud 的應用金鑰', + appSecretPlaceholder: '請輸入 APPSECRET', + saveHint: '儲存後將驗證服務可達性並加密存儲憑證', + saveBtn: '儲存憑證', + usageTitle: '使用說明', + usageSteps: '1. 填寫並儲存 APPID / APPSECRET\n2. 在下方「雲模型接入」中按行新增 chat、embedding、rerank、vlm\n3. 文件解析:知識庫設定 → 解析引擎,選擇 WeKnora Cloud 引擎', + fillRequired: '請填寫 APPID 和 APPSECRET', + saveSuccess: '憑證已儲存', + saveFailed: '憑證儲存失敗', + credentialConfigured: 'WeKnoraCloud 憑證已設定', + credentialExpired: '憑證已失效,請重新設定。', + credentialUnconfigured: '尚未設定 WeKnoraCloud 憑證,請先填寫 APPID 和 APPSECRET。', + checkingStatus: '正在檢查憑證狀態...', + goToSettings: '前往設定中設定', + modelHintConfigured: 'WeKnoraCloud 憑證已設定。支持的模型可參考', + modelHintDocsLink: '介面文件', + addModelsSuccess: '已成功新增 {count} 個模型', + addModelsPartial: '已新增 {success} 個,{failed} 個失敗', + addModelsFailed: '新增模型失敗', + addModelsEmbeddingFailed: 'Embedding 模型連結測試失敗,無法獲取向量維度', + addModelsDisplayName: { + chat: 'WeKnoraCloud 對話', + embedding: 'WeKnoraCloud Embedding', + rerank: 'WeKnoraCloud ReRank', + vllm: 'WeKnoraCloud 視覺' + }, + modelsSection: { + title: '雲模型接入', + descReady: '將 WeKnora Cloud 提供的四類標準模型註冊到當前空間,用於對話、向量檢索、重排序與多模態理解。', + descPending: '請先儲存上方憑證,再在此新增雲模型。', + statusAdded: '已新增', + statusPending: '待設定憑證', + addOne: '新增', + addAllBtn: '新增全部缺失({count})', + addAllConfirm: '確認新增', + confirmAddOne: '新增 {type} 模型「{name}」?', + confirmAddAll: '免洗新增 {count} 個缺失的雲模型?', + allReady: '四類雲模型均已就緒' + } + }, + roleDenied: { + title: '權限不足', + desc: '你當前的角色無權存取此設定項。請聯絡本空間的管理員獲取所需角色。' + }, + capabilityUnavailable: '當前部署不支持此功能,已返回可用頁面。', + navGroups: { + account: '帳戶', + workspace: '空間', + modelsRuntime: '模型', + dataExtensions: '資料與擴展', + systemAdministration: '系統管理', + platform: '平台' + } + }, + agent: { + taskLabel: '任務:', + think: '思考', + copy: '複製', + addToKnowledgeBase: '新增到知識庫', + artifactDrawer: { + buttonTitle: '查看本次生成的檔案', + title: '生成的檔案', + empty: '本次未生成可下載的檔案', + preview: '預覽', + previewBack: '返回清單', + collecting: '正在儲存生成的檔案…', + delete: '刪除', + deleteTitle: '刪除這個檔案?', + deleteConfirm: '將永久刪除「{name}」,包括已儲存的檔案內容,且無法復原。', + deleted: '檔案已刪除', + deleteFailed: '刪除失敗,請稍後重試', + download: '下載', + downloadFailed: '下載失敗,請稍後重試', + inlinePreviewHint: '點擊預覽', + inlineMissing: '檔案不可用', + inlineDeleted: '檔案已刪除', + }, + updatePlan: '更新計劃', + webSearchFound: '找到 {count} 個網路搜尋結果', + toolFallback: '工具', + stepsCompleted: '已完成 {steps} 個步驟', + reasoningRounds: '思考 {rounds} 輪', + toolCalls: '呼叫 {tools} 次工具', + durationSuffix: '耗時 {duration}', + stepSummarySeparator: ' · ', + contextCompacted: '壓縮脈絡', + contextCompactedSummary: '{before} → {after} tokens', + contextCompactedDegraded: '摘要不可用,已保留原始記錄', + title: '智慧代理', + subtitle: '設定和管理您的智慧代理,自定義對話行為和能力', + createAgent: '建立智慧代理', + builtin: '內建', + disabled: '已停用', + disable: '停用', + enable: '啟用', + noDescription: '暫無描述', + selectAgent: '選擇智慧代理', + noAgents: '暫無智慧代理', + manageAgents: '管理', + builtinAgents: '內建智慧代理', + customAgents: '自定義智慧代理', + selector: { + title: '選擇智慧代理', + current: '當前', + goToSettings: '設定', + sharedLabel: '共享', + notReadyHint: '尚未就緒,還需設定:{items}', + notReadyStatus: '待設定', + configureAction: '去設定', + sharedNotReadyContact: '請聯絡分享方管理員完成設定', + capabilitiesSection: '能力', + webSearchCapability: '網路搜尋', + imageUploadCapability: '圖片上傳', + capabilityEnabled: '開啟', + capabilityDisabled: '關閉', + capabilitySupported: '支持', + capabilityUnsupported: '不支持', + capabilityUnconfigured: '未設定' + }, + editor: { + reasoningEffortUnsupported: '當前所選模型不支持思考,除「關閉」外的選項將被忽略。', + reasoningEffortAlwaysOn: '當前所選模型始終開啟思考,無法關閉,只能調整思考強度。', + createTitle: '建立智慧代理', + editTitle: '編輯智慧代理', + buttons: { + create: '建立智慧代理', + saveAndClose: '儲存並關閉', + }, + postCreateHint: { + title: '建立成功', + footer: '可繼續調整設定,設定共享與發布通路,完成後點擊「儲存並關閉」。', + integrationDesc: '前往集成中心設定 IM、網頁內嵌等發布通路', + }, + basicInfo: '基本資訊', + basicInfoDesc: '設定智慧代理的名稱、描述與運行模式', + promptsConfig: '提示語', + promptsConfigDesc: '設定系統提示語、脈絡模板、意圖/改寫/兜底提示語', + modelConfig: '模型設定', + modelConfigDesc: '設定對話模型、ReRank 等輔助模型及生成參數', + toolsConfig: '工具設定', + toolsConfigDesc: '設定 Agent 可以使用的工具', + knowledgeConfig: '知識庫', + knowledgeConfigDesc: '設定智慧代理可存取的知識庫範圍與 FAQ 策略', + webSearchConfig: '網路搜尋', + webSearchConfigDesc: '設定智慧代理的網路搜尋能力', + agentId: '智慧代理 ID', + agentIdDesc: 'API 集成時可使用此 ID 指定智慧代理', + name: '名稱', + namePlaceholder: '請輸入智慧代理名稱', + nameRequired: '請輸入智慧代理名稱', + systemPromptRequired: '請輸入系統提示語', + modelRequired: '請選擇模型', + queryMissingInRewrite: '改寫使用者提示語必須包含 {\'{{\'}query{\'}}\'} 預留位置', + queryMissingInFallback: '兜底提示語必須包含 {\'{{\'}query{\'}}\'} 預留位置', + description: '描述', + descriptionPlaceholder: '請輸入智慧代理描述', + normalDesc: '快速回應,直接回答問題', + agentDesc: '多步思考,深度分析複雜問題', + model: '模型', + modelPlaceholder: '請選擇模型', + systemPrompt: '系統提示語', + systemPromptPlaceholder: '自定義系統提示語,定義智慧代理的行為和角色(使用 {\'{{\'}web_search_status{\'}}\'} 預留位置動態控制網路搜尋行為)', + contextTemplateRequired: '請輸入脈絡模板', + temperature: '溫度', + thinking: '思考模式', + citationEnabled: '輸出來源引用', + citationEnabledDesc: '在最終回答中展示知識庫和網頁來源;關閉後仍會正常檢索和使用證據', + mode: '運行模式', + webSearch: '網路搜尋', + webSearchProvider: '搜尋引擎', + webSearchProviderPlaceholder: '使用預設搜尋引擎', + webSearchMaxResults: '最大搜尋結果數', + webFetchEnabled: '自動抓取頁面內容', + webFetchTopN: '抓取頁面數', + knowledgeBases: '關聯知識庫', + allKnowledgeBases: '全部知識庫', + selectedKnowledgeBases: '指定知識庫', + noKnowledgeBase: '不使用知識庫', + selectKnowledgeBases: '選擇知識庫', + selectKnowledgeBasesDesc: '選擇要關聯的知識庫(包括協作知識庫)', + myKnowledgeBases: '我的知識庫', + sharedKnowledgeBases: '協作知識庫', + retrieveKBOnlyWhenMentioned: '僅在 {\'@\'} 提及時檢索', + retrieveKBOnlyWhenMentionedDesc: '關閉:自動檢索已設定的知識庫,開啟:僅當使用者 {\'@\'} 提及時才檢索', + rerankModel: 'ReRank 模型', + rerankModelDesc: '用於對知識庫檢索結果進行重排序,提高回答準確性', + rerankModelPlaceholder: '請選擇 ReRank 模型', + rerankModelOptionalHint: '當前作用域內暫無 RAG 類型知識庫,可不填;後續若加入 RAG 知識庫,將自動使用空間預設重排模型,仍建議顯式設定。', + maxIterations: '最大疊代次數', + maxIterationsLimit: '限制', + maxIterationsUnlimited: '不限制', + allowedTools: '允許的工具', + multiTurn: '多輪對話', + historyTurns: '保留輪數', + retainRetrievalHistory: '保留檢索結果', + memoryEnabled: '長期記憶', + retrievalStrategy: '檢索策略', + embeddingTopK: '向量召回數量', + keywordThreshold: '關鍵字閾值', + vectorThreshold: '向量閾值', + rerankTopK: '重排數量', + rerankThreshold: '重排閾值', + conversationSettings: '多輪對話', + contextTemplate: '脈絡模板', + contextTemplatePlaceholder: '自定義脈絡模板...', + enableQueryExpansion: '查詢擴展', + enableRewrite: '問題改寫', + queryUnderstandModel: '問題理解模型', + queryUnderstandModelPlaceholder: '留空則復用主對話模型', + rewritePromptSystem: '改寫系統提示語', + rewritePromptSystemPlaceholder: '留空使用系統預設提示語', + rewritePromptUser: '改寫使用者提示語', + rewritePromptUserPlaceholder: '留空使用系統預設提示語', + maxCompletionTokens: '最大生成Token數', + maxCompletionTokensDefault: '預設', + maxCompletionTokensCustom: '自定義', + fallbackStrategy: '兜底策略', + fallbackResponse: '固定回覆內容', + fallbackResponsePlaceholder: '抱歉,我無法回答這個問題。', + fallbackPrompt: '兜底提示語', + fallbackPromptPlaceholder: '留空使用系統預設提示語', + skillsConfig: '技能', + skillsConfigDesc: '先選擇運行沙箱,再從下面清單選用技能。沒裝到該沙箱的會顯示「安裝」,裝好後才能勾選。', + hostSkillsConfigDesc: '從下面清單選用已經裝到這台電腦上的技能。沒裝的會顯示「安裝」,裝好後才能勾選。', + hostSkillsSelectionDesc: '這裡列出空間目錄中的技能。已經裝到這台電腦上的可以直接用;沒裝的請先點「安裝」。', + hostSelectSkillsDesc: '勾選要給這個智慧代理用的技能。沒裝到這台電腦上的不能勾選,請先點右側「安裝」。', + hostSkillsAllListHint: '「全部」只包含已經裝到這台電腦上的技能。沒裝的不會自動帶上,點「安裝」裝好後才會算進去。', + hostInstallToThisComputer: '安裝到這台電腦', + hostUpgradeOnThisComputer: '把這台電腦上的技能升級到目錄版本', + hostSkillDisabled: '已在本機停用', + skillsSelection: '技能清單', + skillsSelectionDesc: '這裡列出空間目錄中的技能。已裝到當前沙箱的可以直接用;沒裝的請先點「安裝」。', + skillsAll: '全部', + skillsSelected: '指定', + skillsNone: '停用', + selectSkills: '選擇技能', + selectSkillsDesc: '勾選要給這個智慧代理用的技能。沒裝到當前沙箱的不能勾選,請先點右側「安裝」。', + skillsAllListHint: '「全部」只包含已裝到此沙箱的技能。沒裝的不會自動帶上,點「安裝」裝好後才會算進去。', + skillsGroupAvailable: '可用', + skillsGroupUnavailable: '不可用', + noSkillsAvailable: '空間目錄裡還沒有技能。', + skillsNeedSandbox: '請先選擇運行沙箱。', + goSandboxSettings: '管理沙箱', + goSkillSettings: '管理技能', + installToThisSandbox: '安裝到此沙箱', + upgradeOnThisSandbox: '升級此沙箱上的技能到目錄版本', + installShort: '安裝', + viewInstallProgress: '查看進度', + skillNotInstalled: '未安裝', + skillNotReady: '尚未就緒', + skillDisabledOnSandbox: '已在沙箱中停用', + sandboxBackend: '運行沙箱', + sandboxBackendDefault: '不啟用', + sandboxBackendHint: '未選擇時不會執行技能指令碼。', + sandboxBackendMissing: '設定已刪除', + sandboxNoConfigs: '當前空間還沒有沙箱,技能指令碼不會執行。', + skillsInfoTitle: '技能與沙箱如何聯動?', + skillsInfoContent: '技能是預裝的專業知識模組,指令碼在所選沙箱中隔離執行。可用清單來自該沙箱已安裝的技能;同一會話的沙箱一旦建立,後續附件、產物與銷毀都會鎖定在建立時那份設定上,改沙箱只影響之後新建的會話。' + }, + messages: { + created: '已建立智慧代理', + updated: '智慧代理已更新', + deleted: '智慧代理已刪除', + deleteFailed: '刪除失敗', + saveFailed: '儲存失敗', + copied: '已複製智慧代理', + copyFailed: '複製失敗', + disabled: '已停用', + enabled: '已啟用' + }, + delete: { + confirmTitle: '刪除智慧代理', + confirmMessage: '確定要刪除智慧代理「{name}」嗎?此操作不可復原。', + confirmButton: '刪除' + }, + shareScope: { + title: '共享範圍說明', + desc: '空間成員以唯讀方式使用該智慧代理,將遵循您當前設定的能力與資源;您對智慧代理的修改會同步給已共享的空間。如需允許空間成員編輯知識庫內容,請將知識庫共享到空間。', + skillSecretsWarning: '該智慧代理啟用了技能:空間成員使用時,技能會在本空間的沙箱中運行,並帶上管理員為技能設定的環境變數(如 API Key),成員可以讓智慧代理讀出這些值。請在可以接受這一點時再共享。', + knowledgeBase: '知識庫', + chatModel: '對話模型', + rerankModel: '重排模型', + webSearch: '網路搜尋', + mcp: 'MCP 服務', + kbAll: '全部知識庫', + kbSelected: '指定 {count} 個知識庫', + kbNone: '不使用', + modelConfigured: '已設定', + modelNotSet: '未設定', + enabled: '開啟', + disabled: '關閉', + mcpAll: '全部服務', + mcpSelected: '指定 {count} 個服務', + mcpNone: '不使用' + }, + detail: { + title: '智慧代理詳情', + useInChat: '在對話中使用' + }, + empty: { + title: '暫無自定義智慧代理', + description: '點擊右上角按鈕建立您的第一個智慧代理', + sharedTitle: '暫無共享智慧代理', + sharedDescription: '您可以加入空間或請求他人將智慧代理共享給您', + favoritesTitle: '暫無收藏', + favoritesDescription: '在智慧代理卡片右上角點擊星標即可收藏', + recentsTitle: '暫無最近存取', + recentsDescription: '最近使用過的智慧代理會出現在這裡' + }, + sections: { + builtin: '內建', + mine: '我建立的', + tenantOthers: '本空間 · 其他成員', + tenantReadonly: '本空間 · 僅查看', + sharedByMe: '我共享的', + sharedEditable: '共享給我 · 可編輯', + sharedReadonly: '共享給我 · 僅查看' + }, + tabs: { + sharedToMe: '共享給我' + }, + features: { + webSearch: '支持網路搜尋', + knowledgeBase: '關聯知識庫', + mcp: '支持MCP服務', + multiTurn: '多輪對話' + }, + mode: { + normal: '快速問答', + agent: '智慧推論' + }, + type: { + normal: '快速問答', + agent: '智慧推論' + }, + capabilities: { + kbCount: '指定 {count} 個知識庫', + kbAll: '可存取全部知識庫', + mcpEnabled: '啟用 MCP 服務', + multiTurn: '多輪對話' + } + }, + knowledgeStages: { + title: '處理流水線', + root: '知識處理', + attempt: '第 {n} 次嘗試', + retry: '重新解析', + notRun: '未執行', + stageFailed: '{stage}階段失敗', + copyError: '複製錯誤資訊', + stat: { + duration: '耗時', + attempt: '嘗試', + tasks: '後台任務', + tasksValue: '運行中 {running} · 失敗 {failed} · 已完成 {completed}' + }, + refresh: '立即重新整理', + copy: '複製', + copyDetails: '複製詳情', + copied: '已複製到剪貼簿', + close: '關閉', + live: 'LIVE', + liveTooltip: '解析進行中,每 2 秒自動重新整理一次', + autoRefreshOn: '自動重新整理中', + fetchFailedShort: '重新整理失敗', + viewTrace: '查看 Trace', + expandBranch: '展開子項', + collapseBranch: '收起子項', + rowSelectHint: '點擊查看詳情;左側箭頭展開或收起子項', + resizeDrawer: '拖曳調整面板寬度', + justNow: '剛剛', + secondsAgo: '{n} 秒前', + minutesAgo: '{n} 分鐘前', + noActivity: '暫無解析記錄', + totalDuration: '總耗時:{d}', + errorCode: { + DOCREADER_UNAVAILABLE: "文件解析服務不可用", + DOCREADER_UNAVAILABLE_SUGGESTION: "無法連結 DocReader,或連結已中斷。請檢查解析服務是否啟動、是否反覆重啟以及網路是否正常;服務復原後再重試,無需重複上傳檔案。", + DOCREADER_TIMEOUT: "文件解析超時", + DOCREADER_TIMEOUT_SUGGESTION: "請檢查 DocReader 的健康狀態和負載;服務正常後再重試,必要時拆分大檔案。", + DOCREADER_PARSE_FAILED: "文件解析失敗", + DOCREADER_PARSE_FAILED_SUGGESTION: "請檢查檔案格式,並讓管理員查看本次解析對應的 DocReader 日誌。", + TASK_STALLED: '長時間無進展,已自動終止', + TASK_STALLED_SUGGESTION: '處理超過閾值仍沒有任何進展,且佇列中已無對應任務,已被系統標記為失敗。請點擊「重試」;如反覆出現,請檢查該階段依賴的服務(文件解析、模型、向量庫)是否正常。', + UNKNOWN_SUGGESTION: '請查看應用日誌獲取詳細資訊。' + }, + status: { + pending: '等待中', + running: '進行中', + finalizing: '最佳化中', + done: '已完成', + failed: '失敗', + skipped: '已跳過', + cancelled: '已取消' + }, + stage: { + docreader: '文件解析', + chunking: '切塊', + embedding: '向量化', + multimodal: '多模態識別', + postprocess: '後處理' + }, + detail: { + started: '開始', + finished: '結束', + duration: '耗時', + offset: '起點偏移', + timing: '時序', + identity: '身份資訊', + stageBreakdown: '階段分解', + stageOrder: '階段順序', + childCount: '子 span 數', + kind: '類型', + status: '狀態', + name: '名稱', + input: '輸入', + output: '輸出', + metadata: '元資料', + traceMetadata: 'Trace 級元資料', + metadataHint: '記錄與 Langfuse 等可觀測性系統關聯的輔助欄位(如 trace ID)。各階段的業務入參/出參在「輸入」「輸出」標籤中查看。', + metadataEmpty: '當前 span 沒有元資料。階段與子任務的入參/出參請查看「輸入」「輸出」;若已接入 Langfuse,trace 級欄位會顯示在「概覽」。', + error: '錯誤', + empty: '暫無資料', + inProgress: '進行中', + elapsed: '已用', + placeholderHint: '此階段未記錄詳細 span,僅展示推斷狀態。', + showJson: '展開 JSON', + hideJson: '收起 JSON', + includingChildren: '含子任務' + }, + tab: { + overview: '概覽', + raw: '原始 JSON' + }, + stall: { + title: '已 {minutes} 分鐘沒有進展,可能已卡住', + hint: '可以繼續等待,或停止解析後重建知識。長時間仍無進展時,系統會自動將其標記為失敗。', + hintAtStage: '當前停在「{stage}」階段。可以繼續等待,或停止解析後重建知識。長時間仍無進展時,系統會自動將其標記為失敗。', + queuedTitle: '已 {minutes} 分鐘沒有進展,任務仍在排隊', + queuedHint: '這篇文件還有任務在佇列中等待處理,通常是任務積壓導致,稍後會自動繼續,一般無需操作。' + }, + head: { + lastProgress: '最近進展', + stagesDone: '主流程階段', + stagesProgress: '當前階段', + attempt: '嘗試', + updated: '更新於' + }, + processConfig: { + title: '本次解析設定', + kbDefault: '使用知識庫預設設定', + graph: '知識圖譜' + } + }, + uploadConfirm: { + documentSummary: "文件摘要", + documentSummaryDescription: "為本次匯入的文件選擇是否自動生成摘要。", + generateSummary: "生成文件摘要", + generateSummaryHint: "預設開啟。關閉後跳過摘要生成,文件解析、索引及其他處理步驟仍按設定執行。", + + title: '上傳文件確認', + parseConfig: '解析設定', + configNav: '解析設定導航', + navParserDefault: '預設', + navParserCustomized: '已自定義', + moreOptions: '更多處理選項', + summaryParentChildShort: '父子切塊', + summaryParserForceScanned: '掃描件解析', + summaryQuestionCountValue: '{count} 個', + summaryGraphTagsValue: '{count} 個', + navChunkingSummary: '切塊 {size}', + statusOn: '已開啟', + statusOff: '未開啟', + notSet: '未設定', + summaryNoTags: '未設定', + summaryTagsCount: '{count} 個標籤', + confirm: '確認上傳並解析', + cancel: '取消', + tabTags: '文件標籤', + tagsDescription: '為本批次匯入的所有文件選擇標籤,可多選', + tagsPlaceholder: '請選擇標籤(可多選)', + tagsEmpty: '當前知識庫暫無標籤,可上傳後在標籤管理中建立', + tagsLoadFailed: '標籤載入失敗,可稍後在文件清單中設定', + noItems: '請至少新增一個檔案或 URL', + urlItemLabel: 'URL', + urlAdded: '已新增 URL', + urlDuplicate: '該 URL 已在清單中', + statusNeedsSetup: '待設定', + multimodalSetupHint: '含圖片內容,請啟用多模態並選擇模型', + asrSetupHint: '含音訊內容,請啟用語音辨識並選擇模型', + vlmModelRequired: '請設定多模態模型', + asrModelRequired: '請設定語音辨識模型', + vlmModelSelectRequired: '已啟用多模態,請選擇 VLM 模型', + asrModelSelectRequired: '已啟用語音辨識,請選擇 ASR 模型', + continueAdd: '繼續新增', + destinationLabel: '上傳位置', + destinationChange: '更改上傳位置', + destinationToRoot: '改到根目錄', + folderUploadTitle: '資料夾「{name}」', + folderUploadHint: '共 {count} 個檔案,將保留本地目錄結構', + filesAdded: '已新增 {count} 個檔案', + filesAllDuplicate: '所選檔案已在清單中', + titleManual: '線上編輯發布確認', + confirmManual: '確認發布並解析', + titleReparse: '重新解析確認', + confirmReparse: '確認並重新解析', + reparseSource: '待重新解析文件', + reparseHint: '將沿用上次解析的設定,可在此調整', + manualCharCount: '{count} 個字符', + pdfForceScanned: { + label: '按掃描件解析 PDF', + description: '適用於網頁列印、掃描件、圖片型 PDF。開啟後會逐頁 OCR,解析更完整但耗時和模型呼叫更多。' + } + }, + knowledgeBase: { + tagAddAction: '新增標籤', + documentCount: '{count} 個文件', + filters: '篩選', + clearFilters: '清除篩選', + + title: '知識庫', + fileContent: '檔案內容', + name: '名稱', + description: '描述', + settings: '設定', + sort: { + title: '排序', + updatedTime: '更新時間', + updatedTimeDescription: '按檔案最近發生變化的時間排序', + createdTime: '上傳/建立時間', + createdTimeDescription: '預設選項。查看新加入或最早積累的資料', + fileName: '檔案名稱', + fileNameDescription: '快速尋找明確知道名稱的檔案', + recentlyUpdated: '最近更新', + earliestUpdated: '最早更新', + newestCreated: '最新上傳', + earliestCreated: '最早上傳', + nameAscending: 'A–Z', + nameDescending: 'Z–A', + }, + tagUpdateSuccess: '標籤已更新', + tagEditDialogHeading: '編輯標籤', + folderTree: { + totalDocuments: '共 {count} 個文件', + countHint: '當前目錄 {direct} 個文件,含子目錄共 {total} 個', + filteredCount: '比對 {count} 個文件', + title: '目錄', + rootRow: '根目錄', + rootRowTip: '知識庫根目錄,未歸入子資料夾的文件在此', + folderCardCount: '{count} 個文件', + searchingSubtree: '(含子目錄)', + emptyFolder: '這個資料夾裡還沒有文件', + emptySearch: '沒有比對的文件', + collapse: '收起目錄', + expand: '展開目錄', + collapseFolder: '收起該資料夾', + expandFolder: '展開該資料夾', + rename: '重新命名', + renamePlaceholder: '輸入資料夾名稱', + renameSuccess: '資料夾已重新命名', + renameFailed: '資料夾重新命名失敗', + renameInvalid: '不能把資料夾移動到它自己的子目錄下', + }, + moveToFolder: { + action: '移動到目錄', + newFolder: '新建子目錄', + newFolderPlaceholder: '輸入新目錄名稱', + newFolderCreate: '建立', + newFolderAddRoot: '在根目錄下新建子目錄', + newFolderAddUnder: '在「{folder}」下新建子目錄', + newFolderHint: 'Enter建立並移動', + newFolderHintRoot: '將在根目錄下建立', + newFolderHintUnder: '將在「{folder}」下建立', + success: '已移動 {count} 個文件', + failed: '移動失敗', + duplicate: '該目錄已存在', + }, + tagFilterTitle: '按標籤篩選', + tagFilterPlaceholder: '標籤', + tagFilterMulti: '{count} 個標籤', + tagManageTitle: '管理標籤', + tagManageDescription: '新建、重新命名或刪除知識庫標籤', + tagManageLink: '管理標籤…', + tagManageListSection: '標籤清單', + tagManageDocCount: '{count} 個文件', + tagManageFaqCount: '{count} 個 FAQ', + tagPickerSelected: '已選擇', + tagPickerUnselected: '未選擇', + tagSelectedCount: '已選 {count} 個標籤', + tagPickerSearch: "搜尋或新建標籤", + tagPickerInUse: "此標籤仍被使用,請先移除文件上的關聯再刪除", + tagPickerDeleteConfirm: "確定刪除標籤「{name}」?", + untagged: '無標籤', + tagCreateAction: '新建標籤', + tagSearchPlaceholder: '輸入標簽章稱關鍵字', + tagNamePlaceholder: '請輸入標簽章稱', + tagNameRequired: '請先輸入標簽章稱', + tagCreateSuccess: '已建立標籤', + tagEditSuccess: '標籤已更新', + tagDeleteDescDoc: '確定刪除標籤"{name}"?該標籤下的所有文件將被一併刪除', + tagDeleteSuccess: '標籤已刪除', + tagEditAction: '重新命名', + tagDeleteAction: '刪除', + tagEmptyResult: '未找到比對的標籤', + tagLabel: '標籤', + tagPlaceholder: '請選擇標籤', + noTags: '暫無標籤', + videosFilteredNoVLM: '已跳過 {count} 個影片檔案(暫不支持影片上傳)', + unsupportedTypesHint: '部分文件類型({types})暫無可用解析引擎,上傳後將無法解析', + goToParserSettings: '前往設定', + importURL: '匯入網頁', + addDocument: '新增文件', + importURLTitle: '匯入網頁', + urlRequired: '請輸入URL', + invalidURL: '請輸入有效的URL', + urlImportSuccess: '已匯入 URL', + urlImportFailed: 'URL匯入失敗!', + urlExists: '該URL已存在', + urlLabel: 'URL地址', + urlPlaceholder: '請輸入網頁URL,例如:https://example.com', + urlTip: '支持匯入各類網頁內容,系統會自動提取和解析網頁中的文字內容', + typeURL: '網頁', + typeManual: '手動建立', + typeFile: '檔案', + channelLabel: '來源通路', + channelWeb: '網頁端', + channelApi: 'API', + channelBrowserExtension: '瀏覽器外掛', + channelWechat: '微信', + channelWecom: '企業微信', + channelFeishu: '飛書', + channelFeishuDrive: "飛書雲盤", + channelLarkDrive: "Lark 雲盤", + channelDingtalk: '釘釘', + channelSlack: 'Slack', + channelIm: 'IM 通路', + channelNotion: 'Notion', + channelConfluence: 'Confluence', + channelYuque: '語雀', + channelGitLab: 'GitLab', + channelIma: '騰訊 IMA', + channelUpload: '上傳', + channelManual: '手動', + channelUrl: '網頁', + channelUnknown: '未知', + urlSource: '來源網址', + webContent: '網頁內容', + documentContent: '文件內容', + importTime: '匯入時間', + createTime: '建立時間', + createdAt: '建立', + updatedAt: '更新', + clickToViewFull: '點擊卡片查看全文與分段', + characters: '字符', + segment: '片段', + chunkCount: '共 {count} 個片段', + viewChunks: '查看切塊', + viewMerged: '全文', + generatedQuestions: '輔助召回問題', + viewParentContext: '查看父塊脈絡', + parentContextLoadFailed: '載入父脈絡失敗', + confirmDeleteQuestion: '確定要刪除這個問題嗎?刪除後將同時移除對應的向量索引。', + legacyQuestionCannotDelete: '舊格式問題無法刪除,請重新生成問題', + customMetadata: '自定義元資料', + metadataCapabilityHint: '用於文件總結,並在文件被召回後作為文件級脈絡輔助回答;不會參與索引或影響召回排序', + noCustomMetadata: '暫無自定義元資料', + addMetadataField: '新增元資料欄位', + metadataKeyPlaceholder: '欄位名', + metadataValuePlaceholder: '欄位值', + metadataTypeText: '文字', + metadataTypeNumber: '數字', + metadataTypeBoolean: '布爾值', + metadataTypeNull: '空值', + metadataKeyRequired: '元資料欄位名不能為空', + metadataKeyDuplicate: '元資料欄位 {key} 重複', + metadataNumberRequired: '元資料欄位 {key} 必須是有效數字', + regenerateSummary: '重新生成摘要', + generateSummary: '生成摘要', + noDocumentSummary: '暫無文件摘要', + summaryRefreshed: '摘要已更新', + summaryRefreshQueued: '摘要重新整理已提交,完成後會自動更新', + indexFailed: '索引同步失敗', + chunkSavedIndexFailed: '內容已儲存,但索引同步失敗,請點擊重試索引', + chunkEditConflict: '切塊已被他人修改,清單已重新整理,請重試', + retryIndex: '重試索引', + indexRetrySuccess: '索引已同步', + chunkHistory: '切塊編輯歷史', + currentVersion: '當前版本', + noChunkHistory: '暫無編輯歷史', + compareRevisionWithCurrent: 'v{revision} 與當前 v{current} 的內容差異', + diffAddedInCurrent: '當前版本新增', + diffRemovedFromCurrent: '當前版本刪除', + noContentChanges: '內容沒有變化,該版本僅包含狀態變更', + revertRevision: '回滾版本', + revertRevisionConfirm: '確定回滾到 v{revision} 嗎?回滾後會生成一個新版本。', + chunkReverted: '切塊已回滾', + chunkContentRequired: '切塊內容不能為空', + disableChunk: '停用', + enableChunk: '啟用', + enabledStatus: '已啟用', + disabledStatus: '已停用', + editChunkContent: '編輯切塊內容', + addGeneratedQuestion: '新增輔助召回問題', + regenerateQuestions: '重新生成問題', + questionsRegenerated: '輔助召回問題已更新', + staleGeneratedQuestions: '問題基於編輯前內容生成,可按需重新生成', + noGeneratedQuestions: '暫無輔助召回問題', + notInitialized: '該知識庫尚未完成初始化設定,請先前往設定頁面設定模型資訊後再上傳檔案', + missingStorageEngine: '該知識庫尚未選擇存儲引擎,請先前往設定頁面設定存儲引擎後再上傳內容。', + missingStorageEngineUpload: '請先設定存儲引擎後再上傳內容', + goToStorageSettings: '前往設定', + getInfoFailed: '獲取知識庫資訊失敗,無法上傳檔案', + missingId: '缺少知識庫ID', + deleteFailed: '刪除失敗,請稍後再試!', + uploadTime: '上傳時間', + newSession: '新會話', + editDocument: '編輯文件', + rebuildDocument: '重建知識', + rebuildConfirm: '確認重建文件"{fileName}"?該操作會清理現有切塊並重新解析。', + rebuildSubmitted: '重建任務已提交', + rebuildFailed: '重建失敗,請稍後再試', + rebuildInProgress: '當前文件正在解析中,請稍後重試', + cancelParse: '停止解析', + cancelParseConfirmBody: '確認停止解析"{title}"?已寫入的切塊會保留,可稍後透過"重建"重新觸發;最佳化階段(摘要 / 問答 / 知識圖譜)的待執行任務會被立即丟棄。', + cancelParseSubmitted: '已停止解析', + cancelParseFailed: '停止失敗,請稍後再試', + draft: '草稿', + draftTip: '暫存內容,未參與檢索', + untitledDocument: '未命名文件', + deleteDocument: '刪除文件', + moveDocument: '移動到...', + moveToKnowledgeBase: '移動到知識庫', + moveNoTargets: '沒有相容的目標知識庫(需要相同類型和 Embedding 模型)', + moveModeReuseVectors: '復用向量(快速)', + moveModeReuseVectorsDesc: '直接移動切塊和向量索引,適用於分片設定相同的情況', + moveModeReparse: '重新解析', + moveModeReparseDesc: '使用目標知識庫的分片設定重新解析文件', + moveConfirm: '確認移動', + moveConfirmTitle: '確認移動設定', + moveStarted: '移動任務已提交', + moveFailed: '移動失敗', + moveCompleted: '移動完成', + moveCompletedWithErrors: '移動完成:{success} 成功,{failed} 失敗', + parsingFailed: '解析失敗', + parsingInProgress: '解析中...', + generatingSummary: '生成摘要中...', + documentSummary: '摘要', + detailSectionMeta: '基本資訊', + confirmDeleteDocument: '確認刪除文件"{fileName}",刪除後將無法復原', + confirmDelete: '刪除', + viewModeGrid: '卡片檢視', + viewModeList: '清單檢視', + viewModeToggle: '切換檢視', + columnName: '檔名', + columnTag: '標籤', + columnSize: '大小', + columnSource: '來源', + columnStatus: '狀態', + columnUpdatedAt: '更新時間', + columnActions: '操作', + selectAll: '全選', + selectedCount: '已選 {count} 項', + clearSelection: '取消選擇', + batchDelete: '批次刪除', + batchDownload: '批次下載', + batchDownloading: '正在打包下載…', + batchDownloadHint: '下載所選檔案為 ZIP,每批最多 200 項、原始檔案合計 512 MiB。全選僅包含已載入的文件;沒有原始檔案的網頁條目會自動跳過。ZIP 會保留知識庫資料夾。', + batchDownloadStarted: '已開始儲存 ZIP,解壓縮後即可按資料夾批次上傳檔案', + batchDownloadFailed: '批次下載失敗,請稍後重試', + batchDownloadSkipped: '已跳過 {count} 個沒有原始檔案的文件', + batchDownloadNoFiles: '所選文件沒有可下載的原始檔案', + batchDownloadTooLarge: '所選檔案合計超過 512 MiB,請減少選擇後分批下載', + selectLoaded: '全選已載入', + confirmBatchDeleteDocument: '確認刪除選中的 {count} 個文件?刪除後將無法復原。', + deleteSubmitted: '刪除任務已提交,正在等待完成。', + deletePending: '刪除尚未完成,請稍後重新整理查看結果。', + deleteTaskFailed: '刪除任務失敗,請查看文件錯誤詳情後重試。', + deleteStatusUnavailable: '暫時無法確認刪除結果,請稍後重新整理查看文件狀態。', + batchDeleteSuccess: '成功刪除 {count} 個文件', + batchDeleteFailed: '批次刪除失敗', + batchTag: '批次打標籤', + batchTagDialogHeading: '批次打標籤', + batchTagSubtitle: '為選中的 {count} 個文件統一設定標籤(將取代文件原有標籤)', + batchTagSuccess: '已為 {count} 個文件成功設定標籤', + batchTagFailed: '批次打標籤失敗', + confirmBatchReparseDocument: '確認重建選中的 {count} 個文件?現有內容將被清除並重新解析。', + confirmBatchReparse: '確認並重新解析', + batchReparseSuccess: '已提交 {count} 個重建任務', + batchReparseFailed: '批次重建失敗', + batchReparseSkippedInFlight: '已跳過 {count} 個正在解析中的文件', + statusCompleted: '已完成', + statusProcessing: '解析中', + statusFinalizing: '最佳化中', + statusStalled: '疑似卡住', + stalledHint: '已 {minutes} 分鐘沒有進展,可能已卡住。可打開 Trace 查看停在哪一步,或停止解析後重建知識。', + statusQueued: '排隊中', + queuedHint: '已 {minutes} 分鐘沒有進展,但仍有任務在佇列中等待處理,通常是任務積壓,稍後會自動繼續。', + statusFailed: '失敗', + statusCancelled: '已取消', + statusDraft: '草稿', + noDescription: '無描述', + emptyKnowledgeDragDrop: '知識為空,拖放上傳', + pdfDocFormat: 'pdf、doc 格式檔案,不超過10M', + textMarkdownFormat: 'text、markdown格式檔案,不超過200K', + dragFileNotText: '請拖曳檔案而不是文字或連結', + searchPlaceholder: '搜尋知識庫...', + docSearchPlaceholder: '搜尋檔案名稱...', + fileTypeFilter: '檔案類型', + allFileTypes: '全部類型', + allTags: '全部標籤', + parseStatusFilter: '解析狀態', + allParseStatuses: '全部狀態', + parseStatusPending: '等待中', + parseStatusProcessing: '處理中', + parseStatusCompleted: '已完成', + parseStatusFinalizing: '整理最佳化中', + parseStatusFailed: '失敗', + parseStatusCancelled: '已取消', + parseStatusDraft: '草稿', + sourceFilter: '來源', + allSources: '全部來源', + sourceApi: 'API', + sourceBrowserExtension: '瀏覽器擴展', + sourceUpload: '本地上傳', + sourceUrl: 'URL 匯入', + sourceManual: '手動建立', + updatedTimeFrom: '起始時間', + updatedTimeTo: '結束時間', + noMatch: '未找到比對的知識庫', + noKnowledge: '暫無可用知識庫', + loadingFailed: '載入知識庫失敗', + operationNotSupportedForType: '當前知識庫類型不支持該操作', + allFilesSkippedNoEngine: '所選檔案類型暫無可用解析引擎,已全部跳過', + filesSkippedNoEngine: '{count} 個檔案因無可用解析引擎被跳過', + deleteSuccess: '已刪除知識', + chunkLoadFailed: '切塊載入失敗', + infoCard: { + tooltip: '查看知識庫資訊', + title: '知識庫資訊', + basic: '基礎', + access: '存取', + binding: '存儲綁定', + capabilities: '能力', + stats: '統計', + type: '類型', + createdAt: '建立時間', + source: '來源', + sharedTo: '共享範圍', + enabled: '已啟用', + vectorStore: '向量存儲', + fileStorage: '檔案存儲', + documentCount: '文件數', + faqCount: '問答數', + supportedFileTypes: '可上傳格式', + chunking: '切塊', + parentShort: '父', + childShort: '子' + }, + accessInfo: { + myRole: '我的身份', + roleOwner: '建立者', + permissionOwner: '可編輯、管理設定、刪除知識庫', + permissionAdmin: '可編輯、管理共享設定', + permissionEditor: '可編輯文件與標籤', + permissionViewer: '僅查看與檢索', + fromOrg: '來自空間', + sharedAt: '共享於', + lastUpdated: '最後更新' + } + }, + resourceOrigin: { + mine: '我建立', + mineTooltip: '由當前使用者建立', + tenant: '本空間', + tenantTooltip: '本空間其他成員建立', + tenantTooltipWithCreator: '由 {creator} 建立', + space: '共享空間', + spaceTooltip: '來自共享空間「{space}」', + spaceTooltipWithTenant: '來自共享空間「{space}」· 源空間 {tenant}', + shared: '外部共享', + sharedTooltip: '透過共享空間從其他空間存取' + }, + listSpaceSidebar: { + all: '全部', + workspace: '本空間', + spaces: '共享給我', + favorites: '收藏', + recents: '最近' + }, + batchManage: { + selectAll: '全選', + cancel: '取消', + delete: '刪除對話', + deleteConfirmTitle: '刪除對話', + deleteConfirmBody: '確定要刪除選中的 {count} 條對話嗎?刪除後無法復原。', + deleteAllConfirmBody: '確定要刪除所有對話嗎?此操作無法復原。', + deleteSuccess: '已刪除', + deleteFailed: '刪除失敗,請稍後再試' + }, + contextualGuide: { + stepOf: '{current} / {total}', + skip: '跳過', + prev: '上一步', + next: '下一步', + done: '知道了', + interactHint: '請直接點擊標示區域繼續', + chat: { + steps: { + done: { + title: '開始探索吧', + desc: '試試提一個與已上傳文件相關的問題,體驗帶引用的精準回答。' + }, + send: { + title: '傳送開始對話', + desc: '傳送後將建立新會話,AI 會結合知識庫內容作答,並標註引用片段。' + }, + input: { + title: '輸入你的問題', + desc: '直接描述你想了解的內容;也可點擊上方推薦問題快速開始。' + }, + kb: { + title: '選擇知識範圍', + desc: '點擊 {\'@\'} 可指定一個或多個知識庫/檔案,僅基於選中內容回答;不選則按當前智慧代理設定檢索。' + } + } + }, + kbDetail: { + steps: { + done: { + title: '解析完成後即可使用', + desc: '文件解析入庫後,可在對話中 {\'@\'} 本知識庫提問,回答會附帶引用來源。' + }, + upload: { + title: '新增文件', + desc: '點擊此處上傳檔案、資料夾,或匯入網頁與線上編輯內容。' + }, + intro: { + title: '知識庫還是空的', + desc: '新增第一份資料後,才能基於它進行檢索與對話。支持拖曳上傳多種文件格式。' + } + } + }, + agentCreate: { + steps: { + submit: { + title: '儲存智慧代理', + desc: '確認設定後點擊標示的「確定」完成建立,即可在對話中選擇該智慧代理。' + }, + navTools: { + title: '工具與 MCP(可選)', + desc: '智慧推論模式下可勾選內建工具、MCP 服務等,擴展搜尋、計算等能力。' + }, + multimodal: { + title: '啟用附件上傳', + desc: '可分別設定圖片、音訊上傳及附件解析策略;啟用圖片上傳時需在下方選擇 VLM 模型。' + }, + navMultimodal: { + title: '附件上傳(可選)', + desc: '開啟後,對話中可上傳圖片、文件、音訊等附件;圖片理解需先在系統設定中設定 VLLM 模型。' + }, + navWebsearch: { + title: '聯網搜尋(可選)', + desc: '設定是否允許智慧代理呼叫外部搜尋引擎補充實時資訊。' + }, + knowledge: { + title: '知識庫範圍', + desc: '「全部」適合通用助手;「指定」可限定專業領域;「不關聯」則僅依賴模型自身能力或聯網搜尋。' + }, + navKnowledge: { + title: '關聯知識庫', + desc: '決定智慧代理可檢索哪些知識。預設「全部知識庫」,也可改為指定庫或暫不關聯。' + }, + model: { + title: '選擇模型', + desc: '從下拉清單選擇已設定的對話模型;沒有合適模型時請先到系統設定新增。' + }, + navModel: { + title: '綁定對話模型', + desc: '每個智慧代理必須指定一個 KnowledgeQA 模型作為推論引擎。' + }, + name: { + title: '命名與描述', + desc: '取一個易識別的名稱。智慧推論模式下系統可能已預填預設名稱,可按需修改。' + }, + agentType: { + title: '選擇智慧代理類型', + desc: '預設類型會自動填充系統提示語、推薦工具與知識庫範圍(如 Wiki 建構、資料分析等)。可按情境切換,名稱與描述會隨之更新。' + }, + mode: { + title: '選擇運行模式', + desc: '「普通模式」適合固定流程的快速問答;「智慧推論」可呼叫工具、多步思考,適合複雜任務。' + } + } + }, + agentList: { + steps: { + create: { + title: '建立你的智慧代理', + desc: '智慧代理把模型、知識庫、工具與提示語組合成可復用的對話助手。點擊下方標示的「建立智慧代理」開始設定。' + } + } + }, + kbCreate: { + steps: { + submit: { + title: '建立知識庫', + desc: '點擊「知道了」結束引導,無需現在建立知識庫。準備好後,填寫名稱、確認類型與模型,再點擊「建立」。' + }, + faq: { + title: 'FAQ 索引方式', + desc: '設定問答對的索引模式。建立後可在本頁繼續新增 FAQ 條目。' + }, + multimodalVllm: { + title: '選擇 VLM 模型', + desc: '開啟多模態後需指定 VLM(視覺語言模型)。若清單為空,請先在系統設定中新增 VLLM 類型模型。' + }, + multimodalToggle: { + title: '開啟多模態解析', + desc: '啟用後,上傳的圖片類文件將使用視覺語言模型提取內容,便於檢索與問答。' + }, + navMultimodal: { + title: '多模態 / 圖片理解(可選)', + desc: '若文件含大量圖表、掃描件或需理解圖片內容,可在此開啟多模態並選擇 VLM 模型。' + }, + storage: { + title: '存儲引擎(可選)', + desc: '原始檔案存放位置(本地或物件存儲)。預設跟隨空間設定即可。' + }, + chunking: { + title: '切塊策略(可選)', + desc: '決定文件如何切分為檢索片段。預設切塊大小已針對 RAG 最佳化,一般無需修改。' + }, + parser: { + title: '解析引擎(可選)', + desc: '控制 PDF、Office 等檔案的解析方式。預設設定適用於大多數情境,有 OCR 需求時可在此調整。' + }, + embedding: { + title: 'Embedding 模型', + desc: '將文字轉為向量以支持語義檢索。與上方索引策略中的「向量/關鍵字檢索」配合使用。' + }, + llm: { + title: '對話 / 摘要模型', + desc: '用於文件摘要、問答生成等。若清單為空,請透過下拉選單前往系統設定新增模型。' + }, + navModels: { + title: '設定模型(必填)', + desc: '知識庫必須綁定對話模型;開啟檢索時還需 Embedding 模型。點擊左側「模型設定」進入。' + }, + indexing: { + title: '選擇索引能力', + desc: '預設已開啟向量與關鍵字檢索,可按需開啟 Wiki 結構化索引或知識圖譜。至少保留一種檢索方式。' + }, + name: { + title: '填寫名稱', + desc: '取一個便於識別的名稱,例如「產品手冊」或「客服 FAQ」。描述可選填。' + }, + type: { + title: '選擇知識庫類型', + desc: '文件庫適合上傳 PDF、Word 等檔案;FAQ 庫適合問答對。建立後類型不可更改,請按需選擇。' + } + } + }, + tenantModels: { + needChatModelFirst: '請先新增對話模型(KnowledgeQA),再建立智慧代理。', + stepsAgent: { + done: { + title: '然後建立智慧代理', + desc: '儲存並關閉設定後,點擊「建立智慧代理」,嚮導會帶你設定模式、知識庫與附件上傳等選項。' + }, + addModel: { + title: '新增對話模型', + desc: '點擊「新增模型」,選擇 KnowledgeQA 類型並填寫接入資訊。' + }, + intro: { + title: '需要先設定對話模型', + desc: '建立智慧代理至少需要一種 KnowledgeQA(對話)模型。請先在系統設定中新增;Embedding 模型僅建立知識庫時需要。' + } + }, + steps: { + done: { + title: '新增完成後繼續', + desc: '模型儲存後關閉設定頁,即可點擊「新建知識庫」;建立嚮導會引導你完成類型、索引與模型綁定。' + }, + addModel: { + title: '新增模型', + desc: '點擊「新增模型」,分別設定 KnowledgeQA(對話)與 Embedding 類型。Lite 使用者可使用 Ollama 拉取本地模型。' + }, + intro: { + title: '需要先設定模型', + desc: '建立文件知識庫至少需要:一個對話模型(用於摘要與問答)和一個 Embedding 模型(用於向量檢索)。請先在系統設定中新增。' + } + } + }, + kbList: { + steps: { + create: { + title: '建立第一個知識庫', + desc: '知識庫用來存放文件與 FAQ。點擊下方標示的「新建知識庫」按鈕,我們會帶你完成表單填寫。' + } + } + } + }, + newUserGuide: { + stepOf: '{current} / {total}', + skip: '跳過引導', + prev: '上一步', + next: '下一步', + done: '完成', + reopen: '新手引導', + steps: { + done: { + title: '一切就緒', + desc: '你已經了解了核心功能,現在就開始建構你的知識助手吧!隨時可點擊選單頂部暱稱旁的幫助按鈕重新查看引導。' + }, + models: { + title: '設定你的模型', + desc: '這是關鍵一步:在模型管理中新增對話、向量等模型,知識庫與對話功能才能正常工作。點擊「新增模型」即可開始設定。' + }, + settings: { + title: '帳戶與設定入口', + desc: '點開這裡可以管理帳戶、成員與系統設定。需要再次查看本引導時,可點擊選單頂部暱稱旁的幫助按鈕重新打開。' + }, + agents: { + title: '打造專屬智慧代理', + desc: '把知識庫、提示語與工具組合成可復用的智慧代理,沉澱你的專業能力。' + }, + chat: { + title: '發起智慧對話', + desc: '基於知識庫內容向 AI 提問,獲得帶引用來源的精準回答。點擊這裡開始新對話。' + }, + knowledge: { + title: '建立你的知識庫', + desc: '知識庫是一切的起點:上傳文件、網頁或 FAQ,WeKnora 會自動解析並建立索引。點擊這裡進入知識庫。' + }, + welcome: { + title: '歡迎使用 WeKnora', + desc: '只需幾步,帶你快速了解知識庫、對話與智慧代理的核心用法。點擊「下一步」開始。' + } + } + }, + chatHeader: { + moreActions: '更多對話操作', + toggleSandboxPanel: '沙箱終端', + copySessionId: '複製會話 ID', + copyLink: '複製對話連結', + copyMarkdown: '複製為 Markdown', + openNewWindow: '在新視窗中打開', + deleteSession: '刪除對話', + renamePlaceholder: '輸入對話標題', + unpinSuccess: '已取消置頂', + temporaryWorkspace: '臨時工作區', + sessionIdCopied: '會話 ID 已複製', + linkCopied: '對話連結已複製', + copyFailed: '複製失敗,請檢查瀏覽器剪貼簿權限', + markdownCopied: '完整對話已複製為 Markdown', + markdownCopyFailed: '複製 Markdown 失敗,請稍後重試', + clearConfirmTitle: '清空對話訊息', + clearConfirmBody: '確認清空當前對話的全部訊息?對話本身會保留,此操作無法復原。', + deleteConfirmTitle: '刪除對話', + deleteConfirmBody: '確認刪除當前對話?刪除後將無法復原。', + deleteSuccess: '對話已刪除', + markdown: { + sessionId: '會話 ID', + exportedAt: '匯出時間', + user: '使用者', + assistant: '助手', + attachments: '附件', + references: '引用' + } + }, + artifactLibrary: { + title: '產物', + subtitle: '智慧代理在各個會話中生成的檔案,都會匯總在這裡', + typeFilter: '按類型篩選', + searchPlaceholder: '搜尋檔名', + categories: { + all: '全部', + document: '文件', + spreadsheet: '表格', + presentation: '簡報', + image: '圖片', + web: '網頁', + data: '資料' + }, + groups: { + today: '今天', + yesterday: '昨天', + last7Days: '最近 7 天', + last30Days: '最近 30 天', + earlier: '更早' + }, + total: '共 {count} 個檔案', + versions: '{count} 個版本', + preview: '預覽', + delete: '刪除', + deleteTitle: '刪除這個檔案?', + deleteConfirm: '將永久刪除「{name}」,包括已儲存的檔案內容,且無法復原。', + deleteConfirmVersions: '將永久刪除「{name}」的全部 {count} 個版本,包括已儲存的檔案內容,且無法復原。', + deleted: '檔案已刪除', + deleteFailed: '刪除失敗,請稍後重試', + download: '下載', + downloadFailed: '下載失敗,請稍後重試', + openSession: '打開所在會話', + untitledSession: '未命名會話', + loadMore: '載入更多', + loadFailed: '產物載入失敗', + retry: '重試', + clearFilters: '清除篩選', + empty: { + title: '還沒有產物', + description: '在對話中讓智慧代理生成報告、表格或簡報,檔案會出現在這裡' + }, + noMatches: { + title: '沒有比對的檔案', + description: '換個關鍵字或檔案類型試試' + } + }, + menu: { + sessionInProgress: '會話進行中', + knowledgeBase: '知識庫', + agents: '智慧代理', + artifacts: '產物', + organizations: '共享空間', + newChat: '新對話', + settings: '系統設定', + logout: '登出', + clearMessages: '清空訊息', + clearMessagesSuccess: '訊息已清空', + clearMessagesFailed: '清空訊息失敗,請稍後再試', + renameSession: '修改標題', + renameSessionSuccess: '標題已更新', + renameSessionFailed: '修改標題失敗,請稍後再試', + batchManage: '批次管理', + newSession: '新會話', + pin: '置頂', + unpin: '取消置頂', + pinFailed: '置頂失敗,請稍後再試', + unpinFailed: '取消置頂失敗,請稍後再試', + search: '搜尋', + collapseSidebar: '收起側邊欄', + expandSidebar: '展開側邊欄', + logoutSuccess: '已登出', + myChats: '我的對話', + apiChats: 'API 會話', + noSessions: '暫無對話' + }, + // 图片属性的展示文案,按属性名索引(后端注册表给出属性名,这里只做翻译)。 + // 注意:属性名里的点号要转义成下划线(contain.text → contain_text)——vue-i18n 按点号 + // 逐段下钻,写成字面量 'contain.text' 的键永远取不到。 + // 未翻译的属性会回落到后端注册表自带的说明,所以新增属性不会显示成空行。 + imageAttr: { + contain_text: { + label: '圖中文字量', + description: '圖片自身承載多少正文文字,決定是否值得為它單獨跑一輪 OCR。', + values: { + none: { label: '無文字', description: '完全沒有文字' }, + sparse: { label: '少量文字', description: '只有少量文字 ── 圖示、路牌、單個標籤' }, + block: { label: '成段正文', description: '成段正文 ── 截圖、表格、文件頁面' } + } + }, + contain_data_visual: { + label: '資料可視化', + description: '圖片是否以圖表、曲線、示意圖或資訊圖的方式承載資料;這類圖即使看起來文字很少,也會保留在 OCR 路徑上。', + values: { + 'true': { label: '是', description: '是 ── 圖表、曲線或示意圖' }, + 'false': { label: '否', description: '否 ── 照片、插畫、圖示或裝飾圖' } + } + } + } +} diff --git a/frontend/src/i18n/resolveDefaultLocale.ts b/frontend/src/i18n/resolveDefaultLocale.ts index c6b98f8ad7d..f7d67720bc9 100644 --- a/frontend/src/i18n/resolveDefaultLocale.ts +++ b/frontend/src/i18n/resolveDefaultLocale.ts @@ -1,4 +1,4 @@ -export const SUPPORTED_LOCALES = ['zh-CN', 'en-US', 'ru-RU', 'ko-KR', 'ja-JP'] as const +export const SUPPORTED_LOCALES = ['zh-CN', 'zh-TW', 'en-US', 'ru-RU', 'ko-KR', 'ja-JP'] as const export type SupportedLocale = (typeof SUPPORTED_LOCALES)[number] export const BUILT_IN_DEFAULT: SupportedLocale = 'zh-CN' diff --git a/frontend/src/views/auth/Login.vue b/frontend/src/views/auth/Login.vue index 6dd7d4b5a1e..12324a892a2 100755 --- a/frontend/src/views/auth/Login.vue +++ b/frontend/src/views/auth/Login.vue @@ -432,6 +432,7 @@ const inviteLookupLoading = ref(false) // Language options const languageOptions = [ { value: 'zh-CN', label: '简体中文', shortLabel: '中文', flag: '🇨🇳' }, + { value: 'zh-TW', label: '繁體中文', shortLabel: '繁中', flag: '繁' }, { value: 'en-US', label: 'English', shortLabel: 'EN', flag: '🇺🇸' }, { value: 'ru-RU', label: 'Русский', shortLabel: 'RU', flag: '🇷🇺' }, { value: 'ko-KR', label: '한국어', shortLabel: '한국어', flag: '🇰🇷' }, diff --git a/frontend/src/views/settings/GeneralSettings.vue b/frontend/src/views/settings/GeneralSettings.vue index 1e444b04837..2351c63e8ac 100755 --- a/frontend/src/views/settings/GeneralSettings.vue +++ b/frontend/src/views/settings/GeneralSettings.vue @@ -20,6 +20,7 @@ style="width: 280px;" > {{ $t('language.zhCN') }} + {{ $t('language.zhTW') }} {{ $t('language.enUS') }} {{ $t('language.ruRU') }} {{ $t('language.koKR') }} diff --git a/internal/handler/im.go b/internal/handler/im.go index ad0d1810c56..33dc036584a 100644 --- a/internal/handler/im.go +++ b/internal/handler/im.go @@ -302,7 +302,7 @@ func normalizeIMLocale(locale string) (string, error) { if normalized := types.NormalizeSupportedLocale(locale); normalized != "" { return normalized, nil } - return "", errors.New("locale must be one of: 'en-US', 'ja-JP', 'ko-KR', 'ru-RU', 'zh-CN'") + return "", errors.New("locale must be one of: 'en-US', 'ja-JP', 'ko-KR', 'ru-RU', 'zh-CN', 'zh-TW'") } // DeleteIMChannel deletes an IM channel. diff --git a/internal/handler/mcp_usage_instructions.go b/internal/handler/mcp_usage_instructions.go index 293b0c4799d..79bcc6612ff 100644 --- a/internal/handler/mcp_usage_instructions.go +++ b/internal/handler/mcp_usage_instructions.go @@ -101,7 +101,8 @@ func (h *MCPServiceHandler) GenerateMCPUsageInstructions(c *gin.Context) { return } language := map[string]string{ - "zh-CN": "Simplified Chinese", "en-US": "English", "ja-JP": "Japanese", + "zh-CN": "Simplified Chinese", "zh-TW": "Traditional Chinese", + "en-US": "English", "ja-JP": "Japanese", "ko-KR": "Korean", "ru-RU": "Russian", }[req.Language] if language == "" { diff --git a/internal/types/locale.go b/internal/types/locale.go index b3cc29e4200..82f95b90945 100644 --- a/internal/types/locale.go +++ b/internal/types/locale.go @@ -4,6 +4,7 @@ import "strings" var supportedLocales = map[string]struct{}{ "zh-CN": {}, + "zh-TW": {}, "en-US": {}, "ko-KR": {}, "ja-JP": {}, diff --git a/internal/types/locale_test.go b/internal/types/locale_test.go index 1b157e63afe..48c0ebb64c4 100644 --- a/internal/types/locale_test.go +++ b/internal/types/locale_test.go @@ -3,7 +3,7 @@ package types import "testing" func TestNormalizeSupportedLocale(t *testing.T) { - for _, locale := range []string{"zh-CN", "en-US", "ko-KR", "ja-JP", "ru-RU"} { + for _, locale := range []string{"zh-CN", "zh-TW", "en-US", "ko-KR", "ja-JP", "ru-RU"} { if got := NormalizeSupportedLocale(locale); got != locale { t.Errorf("NormalizeSupportedLocale(%q) = %q", locale, got) }