import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; const resources = { en: { translation: { dashboard: 'Dashboard', chat: 'Chat', config: 'Config', whatsappBridge: 'WhatsApp', channelsGroup: 'Channels', whatsappBridgeHint: 'Show WhatsApp bridge status, QR login, and the current linked companion session.', telegramChannelHint: 'Configure Telegram token, allowed senders and group behavior for the built-in Telegram channel.', discordChannelHint: 'Configure Discord bot token and allowed senders for the Discord channel.', feishuChannelHint: 'Configure Feishu app credentials and group policy for the Feishu channel.', qqChannelHint: 'Configure QQ bot credentials for the QQ channel.', dingtalkChannelHint: 'Configure DingTalk app credentials for the DingTalk channel.', maixcamChannelHint: 'Configure host, port, and allowed senders for the MaixCam channel.', channelSectionConnection: 'Connection', channelSectionConnectionHint: 'Enable the channel and configure the credentials or bridge endpoint required to connect.', channelSectionAccess: 'Access Control', channelSectionAccessHint: 'Restrict which senders or conversations are allowed to reach this channel.', channelSectionGroupPolicy: 'Group Policy', channelSectionGroupPolicyHint: 'Control whether group chats are accepted and when mentions are required.', channelSectionNetwork: 'Network', channelSectionNetworkHint: 'Configure the host and port this channel should use to communicate.', channelFieldTelegramEnabledHint: 'Turn the built-in Telegram bot integration on or off.', channelFieldTelegramTokenHint: 'Telegram bot token from BotFather, used to receive and send messages.', channelFieldTelegramStreamingHint: 'Stream partial replies back to Telegram instead of waiting for the full response.', channelFieldTelegramAllowFromHint: 'Only these Telegram user IDs can message the bot when set.', channelFieldTelegramAllowChatsHint: 'Optional chat allowlist, for example private chats or specific groups.', channelFieldDiscordEnabledHint: 'Turn the Discord bot channel on or off.', channelFieldDiscordTokenHint: 'Discord bot token used to connect to the gateway bot account.', channelFieldDiscordAllowFromHint: 'Only these Discord user IDs can invoke the bot when set.', channelFieldFeishuEnabledHint: 'Turn the Feishu channel on or off.', channelFieldFeishuAppIDHint: 'Feishu app ID for the bot or custom app integration.', channelFieldFeishuAppSecretHint: 'Secret paired with the Feishu app ID.', channelFieldFeishuEncryptKeyHint: 'Optional event encryption key provided by Feishu.', channelFieldFeishuVerificationTokenHint: 'Verification token used to validate callback requests.', channelFieldFeishuAllowFromHint: 'Only these Feishu senders can invoke the channel when set.', channelFieldFeishuAllowChatsHint: 'Optional allowlist of Feishu chat IDs.', channelFieldQQEnabledHint: 'Turn the QQ channel on or off.', channelFieldQQAppIDHint: 'QQ bot application ID.', channelFieldQQAppSecretHint: 'QQ bot application secret.', channelFieldQQAllowFromHint: 'Only these QQ senders can invoke the channel when set.', channelFieldDingTalkEnabledHint: 'Turn the DingTalk channel on or off.', channelFieldDingTalkClientIDHint: 'DingTalk application client ID.', channelFieldDingTalkClientSecretHint: 'Secret paired with the DingTalk client ID.', channelFieldDingTalkAllowFromHint: 'Only these DingTalk senders can invoke the channel when set.', channelFieldMaixCamEnabledHint: 'Turn the MaixCam channel on or off.', channelFieldMaixCamHostHint: 'Hostname or IP address of the MaixCam device.', channelFieldMaixCamPortHint: 'Port used by the MaixCam service.', channelFieldMaixCamAllowFromHint: 'Only these device or sender IDs can invoke the channel when set.', channelFieldEnableGroupsHint: 'Allow messages coming from group chats.', channelFieldRequireMentionHint: 'When enabled, group messages must mention the bot before they are accepted.', whatsappBridgeURL: 'Bridge URL', whatsappBridgeAccount: 'Linked Account', whatsappBridgeLastEvent: 'Last Event', whatsappInbound: 'Inbound', whatsappOutbound: 'Outbound', whatsappReadReceipts: 'Read Receipts', whatsappLastRead: 'Last Read', whatsappLastInbound: 'Last Inbound', whatsappLastOutbound: 'Last Outbound', whatsappBridgeQRCode: 'QR Login', whatsappQRCodeReady: 'Scan with WhatsApp', whatsappQRCodeUnavailable: 'QR not available', whatsappQRCodeHint: 'If you are already linked, no QR is shown.\nIf the QR code does not appear, confirm the gateway is running and the WhatsApp channel is enabled.', whatsappStateAwaitingScan: 'Awaiting Scan', whatsappStateDisconnected: 'Disconnected', whatsappFieldEnabledHint: 'Master switch for receiving WhatsApp messages through the bridge.', whatsappFieldBridgeURLHint: 'Optional. Leave empty to use the gateway embedded WhatsApp bridge at /whatsapp/ws.', whatsappFieldAllowFromHint: 'One sender JID per line. Only these senders can trigger ClawGo.', whatsappFieldEnableGroupsHint: 'Allow messages from WhatsApp groups to enter the channel.', whatsappFieldRequireMentionHint: 'When enabled, group messages must mention the bot before being handled.', whatsappFieldAllowFromFootnote: 'Supports one JID per line, and also accepts comma-separated values.', whatsappLogoutTitle: 'Logout WhatsApp Session', whatsappLogoutMessage: 'Unlink the current WhatsApp companion session and request a new QR code?', unknownAgent: 'Unknown Agent', mainAgent: 'Main Agent', ekgWindowLabel: '{{window}} window', mcpServices: 'MCP', mcpServicesHint: 'Manage MCP servers and install service packages.', cronJobs: 'Cron Jobs', nodes: 'Nodes', nodeArtifacts: 'Node Artifacts', nodeArtifactsHint: 'Browse, download, and delete files or media returned from node dispatches.', nodeArtifactsEmpty: 'No node artifacts found.', nodeArtifactsPrune: 'Prune', nodeArtifactsKeepLatest: 'Keep latest N', nodeArtifactsRetention: 'Artifact Retention', nodeArtifactsRetentionHint: 'Latest auto-prune result from node artifact retention.', nodeArtifactsRetentionKeepLatest: 'Keep latest', nodeArtifactsRetentionRetainDays: 'Retain days', nodeArtifactsRetentionPruned: 'Pruned this run', nodeArtifactsRetentionRemaining: 'Remaining', nodeArtifactDetail: 'Artifact Detail', nodeArtifactPreviewUnavailable: 'Preview unavailable for this artifact.', allNodes: 'All Nodes', allKinds: 'All Kinds', size: 'Size', nodesDetailHint: 'Inspect node capabilities, mirrored remote agents, recent dispatches, and returned artifacts.', nodesFilterPlaceholder: 'Filter by node id, name, or tag', agentTree: 'Agent Tree', noAgentTree: 'No agent tree available.', logs: 'Real-time Logs', logCodes: 'Log Codes', skills: 'Skills', memory: 'Memory', taskAudit: 'Task Audit', subagentProfiles: 'Subagent Profiles', subagentsRuntime: 'Agents', nodeP2P: 'Node P2P', nodeAlerts: 'Node Alerts', nodeAlertsEmpty: 'No active node alerts.', nodeTags: 'Node Tags', nodeDispatchDetail: 'Dispatch Detail', replayDispatch: 'Replay Dispatch', replaying: 'Replaying...', resetReplayDraft: 'Reset Draft', nodeReplayRequest: 'Replay Request', nodeReplayResult: 'Replay Result', nodeReplayInvalidArgs: 'Replay args must be valid JSON.', agentTopology: 'Agent Topology', agentTopologyHint: 'Unified graph for local agents, registered nodes, and mirrored remote agent branches.', runningTasks: 'running', clearFocus: 'Clear Focus', zoomIn: 'Zoom In', zoomOut: 'Zoom Out', fitView: 'Fit View', noLiveTasks: 'No live tasks', remoteTasksUnavailable: 'Remote task details are not mirrored yet.', savePromptFile: 'Save AGENT.md', promptFileSaved: 'Prompt file saved.', promptFileReady: 'AGENT.md ready', promptFileMissing: 'AGENT.md missing', newProfile: 'New Profile', spawn: 'Spawn', dispatch: 'Dispatch', toolAllowlist: 'Tool Allowlist', memoryNamespace: 'Memory Namespace', subagentDeleteConfirmTitle: 'Delete Subagent Profile', subagentDeleteConfirmMessage: 'Delete subagent profile "{{id}}" permanently?', sidebarMain: 'Main', sidebarAgents: 'Agents', sidebarConfig: 'Configuration', sidebarKnowledge: 'Knowledge', sidebarOps: 'Operations', sidebarInsights: 'Insights', ekg: 'EKG', ekgEscalations: 'Escalations', ekgSourceStats: 'Source Stats', ekgChannelStats: 'Channel Stats', ekgTopProvidersWorkload: 'Top Providers (workload)', ekgTopProvidersAll: 'Top Providers (all)', ekgTopErrsigWorkload: 'Top Error Signatures (workload)', ekgTopErrsigAll: 'Top Error Signatures (all)', taskDetail: 'Task Detail', taskQueue: 'Task Queue', taskLogs: 'Task Logs', mediaSources: 'Media Sources', lastPauseReason: 'Last Pause Reason', lastPauseAt: 'Last Pause Time', allSources: 'All Sources', allStatus: 'All Status', export: 'Export', error: 'Error', noTaskAudit: 'No task audit records', selectTask: 'Select a task from the left list', loading: 'Loading...', gatewayStatus: 'Gateway Status', githubRepo: 'GitHub Repository', checkVersion: 'Check Latest Version', versionCheckUpToDateTitle: 'Already Up To Date', versionCheckUpToDateMessage: 'Current gateway and WebUI already match {{version}}.', versionCheckUpdateTitle: 'Update Available', versionCheckUpdateMessage: 'Latest: {{latest}}\nGateway: {{gateway}}\nWebUI: {{webui}}', versionCheckFailedTitle: 'Version Check Failed', versionCheckFailedMessage: 'Unable to check latest release: {{error}}', online: 'Online', offline: 'Offline', activeSessions: 'Active Sessions', nodeDetails: 'Node Details', nodeCapabilities: 'Node Capabilities', nodeActions: 'Node Actions', nodeModels: 'Node Models', nodeAgents: 'Node Agents', refreshAll: 'Refresh All', refresh: 'Refresh', dashboardNodeP2PDetail: '{{transport}} · {{sessions}} active · {{retries}} retries', dashboardNodeP2PTransport: 'Transport', dashboardNodeP2PIce: 'ICE Config', dashboardNodeP2PHealth: 'Health', dashboardNodeP2PSessions: 'Node P2P Sessions', dashboardNodeP2PSessionsEmpty: 'No node P2P sessions yet.', dashboardNodeP2PSessionCreated: 'Created', dashboardNodeP2PSessionRetries: 'Retries', dashboardNodeP2PSessionReady: 'Last Ready', dashboardNodeP2PSessionAttempt: 'Last Attempt', dashboardNodeP2PSessionError: 'Last Error', dashboardNodeDispatches: 'Recent Node Dispatches', dashboardNodeDispatchesHint: 'Actual dispatch path and fallback audit from recent node actions.', dashboardNodeDispatchesEmpty: 'No node dispatch records yet.', dashboardNodeDispatchTransport: 'Used Transport', dashboardNodeDispatchFallback: 'Fallback From', dashboardNodeDispatchDuration: 'Duration', dashboardNodeDispatchArtifacts: 'Artifacts', dashboardNodeDispatchArtifactPreview: 'Artifact Preview', dashboardNodeDispatchError: 'Error', configNodeP2P: 'Node P2P', configNodeP2PHint: 'Configure websocket tunnel or WebRTC transport for remote nodes.', configNodeDispatch: 'Node Dispatch Policy', configNodeDispatchHint: 'Bias node selection and bind actions or agents to tagged nodes.', configNodeDispatchPreferLocal: 'Prefer local node', configNodeDispatchPreferP2P: 'Prefer P2P transport', configNodeDispatchAllowRelay: 'Allow relay fallback', configNodeDispatchActionTags: 'Action tag rules', configNodeDispatchAgentTags: 'Agent tag rules', configNodeDispatchAllowActions: 'Node allow actions', configNodeDispatchDenyActions: 'Node deny actions', configNodeDispatchAllowAgents: 'Node allow agents', configNodeDispatchDenyAgents: 'Node deny agents', configNodeDispatchActionTagsPlaceholder: 'screen_snapshot=vision\ncamera_snap=vision,gpu', configNodeDispatchAgentTagsPlaceholder: 'coder=build\nvision=vision,gpu', configNodeDispatchAllowActionsPlaceholder: 'edge-a=camera_snap,screen_snapshot', configNodeDispatchDenyActionsPlaceholder: 'edge-b=screen_record', configNodeDispatchAllowAgentsPlaceholder: 'edge-a=main,coder', configNodeDispatchDenyAgentsPlaceholder: 'edge-b=vision', configNodeArtifacts: 'Node Artifact Retention', configNodeArtifactsHint: 'Auto-prune old node artifacts so audit and media storage stay bounded.', configNodeArtifactsKeepLatest: 'Keep latest artifacts', configNodeArtifactsRetainDays: 'Retain days (0 to disable)', configNodeArtifactsPruneOnRead: 'Apply retention on list/export', configNodeP2PStunPlaceholder: 'Comma-separated STUN URLs', configNodeP2PIceServers: 'ICE Servers', configNodeP2PIceServersEmpty: 'No structured ICE servers configured.', configNodeP2PIceUrlsPlaceholder: 'Comma-separated ICE URLs', configNodeP2PIceUsername: 'ICE Username', configNodeP2PIceCredential: 'ICE Credential', active: 'Active', paused: 'Paused', noCronJobs: 'No cron jobs found', noNodes: 'No nodes available', allActions: 'All Actions', allTransports: 'All Transports', mainChat: 'Main Chat', internalStream: 'Internal Stream', enable: 'Enable', disable: 'Disable', action: 'Action', maxRetries: 'Max Retries', retryBackoffMs: 'Retry Backoff (ms)', agentPromptContentPlaceholder: 'AGENT.md content...', ekgOverviewHint: 'Runtime health, provider pressure, and error signature distribution.', ekgActiveSources: 'active sources', ekgActiveChannels: 'active channels', ekgErrorsCount: 'errors', dashboardTopErrorSignature: 'Top error signature', dashboardWorkloadSnapshot: '24h workload pressure snapshot', dashboardRecentFailedTasks: 'recent failed tasks', subagentGroup: 'Subagent Group', allAgents: 'All Agents', agents: 'Agents', subagentDispatch: 'Subagent Dispatch', subagentDispatchHint: 'Operator-only panel. Dispatch a task directly to a subagent without going through the main chat loop.', dispatchToSubagent: 'Dispatch Task', subagentTaskPlaceholder: 'Describe the task to run on the selected subagent...', subagentLabelPlaceholder: 'Optional task label...', subagentTaskDispatched: 'Subagent task dispatched.', replyTo: 'Reply To', toAgent: 'To', selfRefresh: 'Self Refresh', internalEvent: 'Internal Event', noSubagentStream: 'No subagent internal stream yet.', subagentGroupReadonly: 'Subagent group is read-only.', startConversation: 'Start a conversation', typeMessage: 'Type a message...', configuration: 'Configuration', form: 'Form', rawJson: 'Raw JSON', reload: 'Reload', saveChanges: 'Save Changes', host: 'Host', port: 'Port', token: 'Token', providers: 'Providers', providersIntroBefore: 'Select a provider tab, then set auth to ', providersIntroMiddle: ' or ', providersIntroAfter: '. The OAuth fields, login link flow, callback paste step, and account list appear in that provider card.', providersQwenLabelTitle: 'Qwen Account Label', providersQwenLabelMessage: 'Qwen OAuth may not return an email. Enter an email or alias to identify this account.', providersQwenImportLabelMessage: 'Enter an email or alias for this imported Qwen account.', providersQwenLabelPlaceholder: 'team-qwen-1', providersQwenLabelRequired: 'Qwen account label is required.', providersStartingOAuthLogin: 'Starting OAuth login', providersCompletingOAuthLogin: 'Completing OAuth login', providersOAuthDeviceTitle: 'OAuth Device Login', providersOAuthDeviceMessage: 'Open this URL and finish authorization.', providersOAuthUserCode: 'User code', providersOAuthLoginTitle: 'OAuth Login', providersOAuthLoginMessage: 'Open this URL, finish login, then paste the final callback URL.', providersOAuthCallbackPlaceholder: 'http://localhost:1455/auth/callback?code=...&state=...', providersOAuthAddedTitle: 'OAuth Added', providersOAuthAddedMessage: 'Account: {{account}}', providersOAuthAddedWithModel: 'Account: {{account}}\nModel: {{model}}', providersOAuthAddedFallback: 'OAuth account added.', providersAuthJsonImportedTitle: 'auth.json Imported', providersAuthJsonImportedMessage: 'OAuth auth.json imported.', providersImportingAuthJson: 'Importing auth.json', providersSavingSelectedModel: 'Saving selected model', providersSelectModelTitle: 'Choose Model', providersSelectModelMessage: 'OAuth login fetched the provider models. Choose the model this provider should use.', providersSelectModelSearchPlaceholder: 'Search model id', providersSelectModelConfirm: 'Use this model', providersSelectModelEmpty: 'No models match the current search.', providersRefreshingOAuthAccount: 'Refreshing OAuth account', providersDeleteOAuthAccountTitle: 'Delete OAuth Account', providersDeletingOAuthAccount: 'Deleting OAuth account', providersClearingOAuthCooldown: 'Clearing OAuth cooldown', providersClearingAPICooldown: 'Clearing API cooldown', providersClearingHistory: 'Clearing provider history', providersRefreshRuntime: 'Refresh Runtime', providersAutoRefresh: 'auto refresh', providersRuntime1h: 'runtime 1h', providersRuntime24h: 'runtime 24h', providersRuntime7d: 'runtime 7d', providersRuntimeAll: 'runtime all', providersApiBase: 'API base', providersApiKey: 'API key', providersModels: 'models', providersModelsHelp: 'Press Enter to add a model id for this provider.', providersModelsEnterHint: 'Type model id and press Enter', providersAuthMode: 'auth mode', providersAuthModeHelp: 'Choose bearer for API key only, oauth for OAuth only, hybrid to use both.', providersRuntimePersist: 'runtime persist', providersRuntimePersistHelp: 'Persist runtime history to disk for this provider.', providersRuntimeHistoryFile: 'runtime history file', providersRuntimeHistoryMax: 'runtime history max', providersSwitchAuthBefore: 'Switch auth mode to ', providersSwitchAuthMiddle: ' or ', providersSwitchAuthAfter: ' to choose an OAuth provider and start login.', providersOAuthSetup: 'OAuth Setup', providersOAuthProvider: 'oauth provider', providersOAuthProviderHelp: 'Select the upstream OAuth service to log into.', providersSelectProvider: 'select provider', providersClientSecret: 'client secret', providersClientSecretHelp: 'Only needed by providers that require an explicit client secret.', providersNetworkProxy: 'network proxy', providersNetworkProxyHelp: 'Optional. If set, this OAuth account will use the proxy for login, refresh, model fetch, and requests.', providersNetworkProxyPlaceholder: 'http://127.0.0.1:7890', providersCredentialFiles: 'credential files', providersCredentialFilesHelp: 'Managed automatically after login; can also be edited manually.', providersCooldownSec: 'cooldown sec', providersRefreshScanSec: 'refresh scan sec', providersRefreshLeadSec: 'refresh lead sec', providersOAuthGuideBefore: 'Choose an OAuth provider, then click ', providersOAuthGuideAfter: '. The dialog will show the authorization URL and ask you to paste back the final callback URL for callback-based providers.', providersOAuthLoginButton: 'OAuth Login', providersImportAuthJson: 'Import auth.json', providersOAuthAccounts: 'OAuth Accounts', providersRefreshList: 'Refresh List', providersNoOAuthAccounts: 'No imported OAuth accounts yet.', system: 'System', pauseJob: 'Pause Job', startJob: 'Start Job', deleteJob: 'Delete Job', gatewayToken: 'Gateway Token', enterToken: 'Enter token...', addJob: 'Add Job', editJob: 'Edit Job', jobName: 'Job Name', kind: 'Kind', cronExpression: 'Cron Expression', runAt: 'Run At', message: 'Message', deliver: 'Deliver', channel: 'Channel', to: 'To (Recipient)', cancel: 'Cancel', save: 'Save', create: 'Create', update: 'Update', delete: 'Delete', add: 'Add', install: 'Install', installed: 'Installed', notInstalled: 'Not Installed', status: 'Status', source: 'Source', duration: 'Duration', provider: 'Provider', model: 'Model', time: 'Time', level: 'Level', code: 'Code', template: 'Template', id: 'ID', files: 'Files', close: 'Close', path: 'Path', before: 'Before', after: 'After', clear: 'Clear', pause: 'Pause', resume: 'Resume', live: 'Live', raw: 'Raw', pretty: 'Pretty', entries: 'entries', appName: 'ClawGo', webui: 'WebUI', node: 'Node', memoryFiles: 'Memory Files', memoryFileNamePrompt: 'Memory file name', noFileSelected: 'No file selected', noDescription: 'No description provided.', empty: '(empty)', modal: 'Modal', dialogPleaseConfirm: 'Please confirm', dialogNotice: 'Notice', dialogInputTitle: 'Input Required', dialogInputPlaceholder: 'Enter a value...', dialogOk: 'OK', requestFailed: 'Request Failed', saved: 'Saved', saving: 'Saving...', creating: 'Creating...', deleting: 'Deleting...', memoryCreateTitle: 'Create Memory File', memoryFileSaved: 'Memory file saved.', cronSaved: 'Cron job saved.', reloadHistory: 'Reload History', user: 'User', exec: 'Exec', agent: 'Agent', toolOutput: 'tool output', chatServerError: 'Error: Failed to get response from server.', waitingForLogs: 'Waiting for logs...', systemLog: 'system.log', codeCaller: 'Code/Caller', recursiveAddValuePlaceholder: 'Type new value and add', recursiveSelectOption: 'Select option', logCodesSearchPlaceholder: 'Search code/text', logCodesNoCodes: 'No codes', skillsDeleteTitle: 'Delete Skill', skillsDeleteMessage: 'Are you sure you want to delete this skill?', skillsClawhubMissingTitle: 'clawhub not detected', skillsClawhubMissingMessage: 'clawhub is not installed. Install dependencies and clawhub automatically?', skillsInstallPanelHint: 'Click "Install now" to bootstrap the skill environment. If Node.js/npm is missing, ClawGo will install it first, then install clawhub.', skillsInstallNow: 'Install now', skillsInstallingDeps: 'Installing node/npm and clawhub...', skillsInstallFailedTitle: 'Install failed', skillsInstallFailedMessage: 'Failed to install clawhub', skillsInstallDoneTitle: 'Install complete', skillsInstallDoneMessage: 'clawhub is installed. You can continue installing skills.', skillsInstallingSkill: 'Installing skill...', skillsInstallSkillDoneTitle: 'Skill installed', skillsInstallSkillDoneMessage: 'Skill "{{name}}" installed successfully.', skillsAddTitle: 'Add Skill', skillsAddMessage: 'Upload skill archive (.zip / .tar.gz / .tgz / .tar). It will be extracted into skills folder and archive will be removed.', skillsSelectArchive: 'Select archive', skillsImporting: 'Uploading and importing skill...', skillsImportFailedTitle: 'Import failed', skillsImportFailedMessage: 'Failed to import skill archive', skillsImportDoneTitle: 'Import complete', skillsImportedPrefix: 'Imported', skillsImportDoneMessage: 'Skill imported successfully.', skillsFileSaved: 'Skill file saved successfully.', skillsNamePlaceholder: 'skill name', skillsIgnoreSuspicious: 'Ignore suspicious warning (use --force)', skillsClawhubNotFound: 'clawhub not found', skillsClawhubStatus: 'clawhub', skillsAdd: 'Add Skill', skillsNoTools: 'No tools defined', skillsFileEdit: 'File Edit', configDiffPreview: 'Diff Preview', configBasicMode: 'Basic Mode', configAdvancedMode: 'Advanced Mode', configSaved: 'Config saved successfully.', configRiskyChangeConfirmTitle: 'Confirm Risky Config Change', configRiskyChangeConfirmMessage: 'These sensitive fields changed: {{fields}}. Save anyway?', configHotOnly: 'Hot-reload fields only', configSearchPlaceholder: 'Search group...', configHotFieldsFull: 'Hot-reload fields (full)', configTopLevel: 'Top Level', configProxies: 'Proxies', configNewProviderName: 'provider name, e.g. openai', configNoCustomProviders: 'No custom providers yet.', configMCPServers: 'MCP Servers', configNewMCPServerName: 'new MCP server name', configNoMCPServers: 'No MCP servers configured yet.', configMCPInstallTitle: 'Install MCP Server Package', configMCPInstallMessage: 'Install an npm package for MCP server "{{name}}"?', configMCPInstallPlaceholder: '@scope/package', configMCPInstalling: 'Installing MCP package...', configMCPInstallFailedTitle: 'MCP install failed', configMCPInstallFailedMessage: 'Failed to install MCP package', configMCPInstallDoneTitle: 'MCP package installed', configMCPInstallDoneMessage: 'Installed {{package}} and resolved binary {{bin}}.', configMCPInstallDoneFallback: 'MCP package installed.', configMCPArgsEnterHint: 'Type one argument and press Enter', configMCPCommandMissing: 'MCP command is unavailable.', configMCPInstallSuggested: 'Suggested package: {{pkg}}', configDeleteMCPServerConfirmTitle: 'Delete MCP Server', configDeleteMCPServerConfirmMessage: 'Delete MCP server "{{name}}" from current config?', configNoGroups: 'No config groups found.', configDiffPreviewCount: 'Diff Preview ({{count}} items)', saveConfigFailed: 'Failed to save config', sourceDirect: 'direct', sourceMemoryTodo: 'memory_todo', statusRunning: 'running', statusWaiting: 'waiting', idle: 'idle', statusBlocked: 'blocked', statusSuccess: 'success', statusError: 'error', statusSuppressed: 'suppressed', taskId: 'Task ID', inputPreview: 'Input Preview', blockReason: 'Block Reason', actionFailed: 'Action failed', cronDeleteConfirmTitle: 'Delete Cron Job', cronDeleteConfirmMessage: 'This will permanently delete the cron job. Continue?', cronDisableConfirmTitle: 'Pause Cron Job', cronDisableConfirmMessage: 'Pause this cron job now?', memoryDeleteConfirmTitle: 'Delete Memory File', memoryDeleteConfirmMessage: 'Delete memory file "{{path}}" permanently?', logsClearConfirmTitle: 'Clear Logs', logsClearConfirmMessage: 'Clear current log list from this page?', configDeleteProviderConfirmTitle: 'Delete Provider', configDeleteProviderConfirmMessage: 'Delete provider "{{name}}" from current config?', cronExpressionPlaceholder: '*/5 * * * *', recipientId: 'recipient id', languageZh: '中文', languageEn: 'English', themeLight: 'Day', themeDark: 'Night', expand: 'Expand', collapse: 'Collapse', configRoot: '(root)', configCommaSeparatedHint: ', a, b', configLabels: { gateway: 'Gateway', host: 'Host', port: 'Port', token: 'Token', agents: 'Agents', defaults: 'Defaults', max_tool_iterations: 'Max Tool Iterations', max_tokens: 'Max Tokens', providers: 'Providers', proxy: 'Proxy', timeout_sec: 'Timeout (Seconds)', shell: 'Shell', enabled: 'Enable', logging: 'Logging', level: 'Log Level', format: 'Log Format', storage: 'Storage', path: 'Path', database: 'Database', type: 'Type', connection: 'Connection', security: 'Security', cors: 'CORS', allowed_origins: 'Allowed Origins', rate_limit: 'Rate Limit', requests_per_minute: 'Requests Per Minute', enabled_true: 'Enabled', enabled_false: 'Disabled', openai: 'OpenAI', gemini: 'Gemini', anthropic: 'Anthropic', api_key: 'API Key', model: 'Model', temperature: 'Temperature', top_p: 'Top P', top_k: 'Top K', presence_penalty: 'Presence Penalty', frequency_penalty: 'Frequency Penalty', stream: 'Stream', user: 'User', system_instruction: 'System Instruction', max_output_tokens: 'Max Output Tokens', response_mime_type: 'Response MIME Type', thinking_config: 'Thinking Config', thinking_level: 'Thinking Level', google_search: 'Google Search', google_maps: 'Google Maps', url_context: 'URL Context', api_base: 'API Base', protocol: 'Protocol', models: 'Models', command: 'Command', responses: 'Responses', streaming: 'Streaming', web_search_enabled: 'Web Search Enabled', web_search_context_size: 'Web Search Context Size', file_search_vector_store_ids: 'File Search Vector Store IDs', file_search_max_num_results: 'File Search Max Results', include: 'Include', stream_include_usage: 'Stream Include Usage', organization: 'Organization', project: 'Project', region: 'Region', deployment_name: 'Deployment Name', version: 'Version', name: 'Name', description: 'Description', package: 'Package', system_prompt: 'System Prompt', tools: 'Tools', auth: 'Authentication', jwt: 'JWT', secret: 'Secret', issuer: 'Issuer', audience: 'Audience', expires_in: 'Expires In', refresh_token: 'Refresh Token', access_token: 'Access Token', client_id: 'Client ID', client_secret: 'Client Secret', redirect_uri: 'Redirect URI', scope: 'Scope', state: 'State', retry: 'Retry', backoff: 'Backoff', factor: 'Factor', min_delay: 'Min Delay', max_delay: 'Max Delay', jitter: 'Jitter', channels: 'Channels', cron: 'Cron', workspace: 'Workspace', proxy_fallbacks: 'Model Fallbacks', heartbeat: 'Heartbeat', every_sec: 'Interval (Seconds)', ack_max_chars: 'Ack Max Chars', prompt_template: 'Prompt Template', context_compaction: 'Context Compaction', mode: 'Mode', trigger_messages: 'Trigger Messages', keep_recent_messages: 'Keep Recent Messages', max_summary_chars: 'Max Summary Chars', max_transcript_chars: 'Max Transcript Chars', execution: 'Execution', summary_policy: 'Summary Policy', policy: 'Policy', intent_max_input_chars: 'Intent Max Input Chars', max_rounds_without_user: 'Max Rounds Without User', run_state_ttl_seconds: 'Run State TTL (Seconds)', run_state_max: 'Run State Max', tool_parallel_safe_names: 'Tool Parallel Safe Names', tool_max_parallel_calls: 'Tool Max Parallel Calls', marker: 'Summary Marker', completed_prefix: 'Completed Prefix', changes_prefix: 'Changes Prefix', outcome_prefix: 'Outcome Prefix', completed_title: 'Completed Title', changes_title: 'Changes Title', outcomes_title: 'Outcomes Title', inbound_message_id_dedupe_ttl_seconds: 'Inbound Message Dedupe TTL (Seconds)', inbound_content_dedupe_window_seconds: 'Inbound Content Dedupe Window (Seconds)', outbound_dedupe_window_seconds: 'Outbound Dedupe Window (Seconds)', telegram: 'Telegram', allow_from: 'Allowed Senders', allow_chats: 'Allowed Chats', enable_groups: 'Enable Groups', require_mention_in_groups: 'Require Mention In Groups', discord: 'Discord', maixcam: 'MaixCam', whatsapp: 'WhatsApp', qq: 'QQ', bridge_url: 'Bridge URL', feishu: 'Feishu', app_id: 'App ID', app_secret: 'App Secret', encrypt_key: 'Encrypt Key', verification_token: 'Verification Token', dingtalk: 'DingTalk', filesystem: 'Filesystem', working_dir: 'Working Directory', url: 'URL', timeout: 'Timeout', auto_install_missing: 'Auto-install Missing', sandbox: 'Sandbox', image: 'Image', web: 'Web', mcp: 'MCP', search: 'Search', max_results: 'Max Results', request_timeout_sec: 'Request Timeout (Seconds)', servers: 'Servers', transport: 'Transport', args: 'Arguments', env: 'Environment', proxies: 'Proxies', cross_session_call_id: 'Cross-session Call ID', supports_responses_compact: 'Supports Responses Compact', dispatch: 'Dispatch', prefer_local: 'Prefer Local', prefer_p2p: 'Prefer P2P', allow_relay_fallback: 'Allow Relay Fallback', action_tags: 'Action Tags', agent_tags: 'Agent Tags', min_sleep_sec: 'Min Sleep (Seconds)', max_sleep_sec: 'Max Sleep (Seconds)', retry_backoff_base_sec: 'Retry Backoff Base (Seconds)', retry_backoff_max_sec: 'Retry Backoff Max (Seconds)', max_consecutive_failure_retries: 'Max Consecutive Failure Retries', max_workers: 'Max Workers', dir: 'Directory', filename: 'Filename', max_size_mb: 'Max Size (MB)', retention_days: 'Retention Days', notify_channel: 'Notify Channel', notify_chat_id: 'Notify Chat ID', webhook_url: 'Webhook URL' } } }, zh: { translation: { dashboard: '仪表盘', chat: '对话', config: '配置', whatsappBridge: 'WhatsApp', channelsGroup: '通道', whatsappBridgeHint: '查看 WhatsApp bridge 状态、二维码登录,以及当前已关联的 companion 会话。', telegramChannelHint: '配置 Telegram 内置通道的 token、允许发送者和群组行为。', discordChannelHint: '配置 Discord 通道的 bot token 和允许发送者。', feishuChannelHint: '配置飞书通道的应用凭证和群组策略。', qqChannelHint: '配置 QQ 通道的机器人凭证。', dingtalkChannelHint: '配置钉钉通道的应用凭证。', maixcamChannelHint: '配置 MaixCam 通道的 host、port 和允许发送者。', channelSectionConnection: '接入配置', channelSectionConnectionHint: '启用通道,并配置连接所需的凭证或 bridge 地址。', channelSectionAccess: '访问控制', channelSectionAccessHint: '限制允许访问该通道的发送者或会话范围。', channelSectionGroupPolicy: '群组策略', channelSectionGroupPolicyHint: '控制是否接收群组消息,以及何时必须 @ 提及。', channelSectionNetwork: '网络配置', channelSectionNetworkHint: '配置该通道使用的 host 和 port。', channelFieldTelegramEnabledHint: '开启或关闭内置 Telegram 机器人通道。', channelFieldTelegramTokenHint: '来自 BotFather 的 Telegram bot token,用于收发消息。', channelFieldTelegramStreamingHint: '将回复分段流式返回到 Telegram,而不是等待整条结果完成。', channelFieldTelegramAllowFromHint: '设置后,仅允许这些 Telegram 用户 ID 调用该机器人。', channelFieldTelegramAllowChatsHint: '可选的会话白名单,例如私聊或指定群组。', channelFieldDiscordEnabledHint: '开启或关闭 Discord 机器人通道。', channelFieldDiscordTokenHint: '用于连接 Discord 机器人的 bot token。', channelFieldDiscordAllowFromHint: '设置后,仅允许这些 Discord 用户 ID 调用该机器人。', channelFieldFeishuEnabledHint: '开启或关闭飞书通道。', channelFieldFeishuAppIDHint: '飞书机器人或应用集成使用的 App ID。', channelFieldFeishuAppSecretHint: '与飞书 App ID 配套的密钥。', channelFieldFeishuEncryptKeyHint: '飞书事件订阅可选的加密 Key。', channelFieldFeishuVerificationTokenHint: '用于校验飞书回调请求的 verification token。', channelFieldFeishuAllowFromHint: '设置后,仅允许这些飞书发送者调用该通道。', channelFieldFeishuAllowChatsHint: '可选的飞书会话 ID 白名单。', channelFieldQQEnabledHint: '开启或关闭 QQ 通道。', channelFieldQQAppIDHint: 'QQ 机器人应用 ID。', channelFieldQQAppSecretHint: 'QQ 机器人应用密钥。', channelFieldQQAllowFromHint: '设置后,仅允许这些 QQ 发送者调用该通道。', channelFieldDingTalkEnabledHint: '开启或关闭钉钉通道。', channelFieldDingTalkClientIDHint: '钉钉应用的 Client ID。', channelFieldDingTalkClientSecretHint: '与钉钉 Client ID 配套的密钥。', channelFieldDingTalkAllowFromHint: '设置后,仅允许这些钉钉发送者调用该通道。', channelFieldMaixCamEnabledHint: '开启或关闭 MaixCam 通道。', channelFieldMaixCamHostHint: 'MaixCam 设备的主机名或 IP 地址。', channelFieldMaixCamPortHint: 'MaixCam 服务使用的端口。', channelFieldMaixCamAllowFromHint: '设置后,仅允许这些设备或发送者 ID 调用该通道。', channelFieldEnableGroupsHint: '允许接收来自群聊的消息。', channelFieldRequireMentionHint: '开启后,群聊消息必须先 @ 机器人才会被接收。', whatsappBridgeURL: 'Bridge 地址', whatsappBridgeAccount: '关联账号', whatsappBridgeLastEvent: '最近事件', whatsappInbound: '入站', whatsappOutbound: '出站', whatsappReadReceipts: '已读回执', whatsappLastRead: '最近已读', whatsappLastInbound: '最近入站', whatsappLastOutbound: '最近出站', whatsappBridgeQRCode: '二维码登录', whatsappQRCodeReady: '请用 WhatsApp 扫码', whatsappQRCodeUnavailable: '当前没有二维码', whatsappQRCodeHint: '如果已经关联成功,就不会显示二维码。\n如果二维码没有出现,请确认 gateway 已启动且 WhatsApp 通道已启用。', whatsappStateAwaitingScan: '等待扫码', whatsappStateDisconnected: '已断开', whatsappFieldEnabledHint: '总开关,控制是否通过 bridge 接收 WhatsApp 消息。', whatsappFieldBridgeURLHint: '可选。留空时自动使用当前 Gateway 内嵌的 /whatsapp/ws 地址。', whatsappFieldAllowFromHint: '每行一个发送者 JID,只有这些发送者可以触发 ClawGo。', whatsappFieldEnableGroupsHint: '允许来自 WhatsApp 群组的消息进入该通道。', whatsappFieldRequireMentionHint: '开启后,群消息必须显式 @ 提及机器人才会被处理。', whatsappFieldAllowFromFootnote: '支持每行一个 JID,也支持逗号分隔后自动拆分。', whatsappLogoutTitle: '退出 WhatsApp 会话', whatsappLogoutMessage: '是否解除当前 WhatsApp companion 会话,并重新申请新的二维码?', unknownAgent: '未知代理', mainAgent: '主代理', ekgWindowLabel: '{{window}} 窗口', mcpServices: 'MCP', mcpServicesHint: '管理 MCP 服务并安装服务包。', cronJobs: '定时任务', nodes: '节点', nodeArtifacts: '节点工件', nodeArtifactsHint: '查看、下载和删除节点调度返回的文件或媒体工件。', nodeArtifactsEmpty: '当前没有节点工件。', nodeArtifactsPrune: '清理', nodeArtifactsKeepLatest: '保留最近 N 条', nodeArtifactsRetention: '工件保留统计', nodeArtifactsRetentionHint: '显示最近一次节点工件自动清理的结果。', nodeArtifactsRetentionKeepLatest: '保留最近数量', nodeArtifactsRetentionRetainDays: '保留天数', nodeArtifactsRetentionPruned: '本次清理数量', nodeArtifactsRetentionRemaining: '剩余数量', nodeArtifactDetail: '工件详情', nodeArtifactPreviewUnavailable: '该工件暂不支持预览。', allNodes: '全部节点', allKinds: '全部类型', size: '大小', nodesDetailHint: '查看节点能力、远端镜像 agent、最近调度记录以及返回的工件。', nodesFilterPlaceholder: '按节点 ID、名称或标签筛选', agentTree: '代理树', noAgentTree: '当前没有可用的代理树。', logs: '实时日志', logCodes: '日志编号', skills: '技能管理', memory: '记忆文件', taskAudit: '任务审计', subagentProfiles: '子代理档案', subagentsRuntime: 'Agents', nodeP2P: '节点 P2P', nodeAlerts: '节点告警', nodeAlertsEmpty: '当前没有活跃节点告警。', nodeTags: '节点标签', nodeDispatchDetail: '调度详情', replayDispatch: '重放调度', replaying: '重放中...', resetReplayDraft: '重置草稿', nodeReplayRequest: '重放请求', nodeReplayResult: '重放结果', nodeReplayInvalidArgs: '重放参数必须是合法 JSON。', agentTopology: 'Agent 拓扑', agentTopologyHint: '统一展示本地 agent、注册 node 以及远端镜像 agent 分支的关系图。', runningTasks: '运行中', clearFocus: '清除聚焦', zoomIn: '放大', zoomOut: '缩小', fitView: '适应视图', noLiveTasks: '当前没有活动任务', remoteTasksUnavailable: '远端任务细节暂未镜像回来。', savePromptFile: '保存 AGENT.md', promptFileSaved: '提示词文件已保存。', promptFileReady: 'AGENT.md 已就绪', promptFileMissing: 'AGENT.md 缺失', newProfile: '新建档案', spawn: '创建', dispatch: '派发', toolAllowlist: '工具白名单', memoryNamespace: '记忆命名空间', subagentDeleteConfirmTitle: '删除子代理档案', subagentDeleteConfirmMessage: '确认永久删除子代理档案 "{{id}}"?', sidebarMain: '主入口', sidebarAgents: 'Agents', sidebarConfig: '配置', sidebarKnowledge: '知识与调试', sidebarOps: '运维', sidebarInsights: '洞察', ekg: 'EKG', ekgEscalations: '升级拦截次数', ekgSourceStats: '来源统计', ekgChannelStats: '通道统计', ekgTopProvidersWorkload: 'Top Providers(业务负载)', ekgTopProvidersAll: 'Top Providers(全量)', ekgTopErrsigWorkload: 'Top 错误签名(业务负载)', ekgTopErrsigAll: 'Top 错误签名(全量)', taskDetail: '任务详情', taskQueue: '任务队列', taskLogs: '任务日志', mediaSources: '媒体来源', lastPauseReason: '最近暂停原因', lastPauseAt: '最近暂停时间', allSources: '全部来源', allStatus: '全部状态', export: '导出', error: '错误', noTaskAudit: '暂无任务审计记录', selectTask: '请从左侧选择任务', loading: '加载中...', gatewayStatus: '网关状态', githubRepo: 'GitHub 仓库', checkVersion: '检查最新版本', versionCheckUpToDateTitle: '已经是最新版本', versionCheckUpToDateMessage: '当前 gateway 和 WebUI 已经是 {{version}}。', versionCheckUpdateTitle: '发现新版本', versionCheckUpdateMessage: '最新版本:{{latest}}\nGateway:{{gateway}}\nWebUI:{{webui}}', versionCheckFailedTitle: '版本检查失败', versionCheckFailedMessage: '无法检查最新版本:{{error}}', online: '在线', offline: '离线', activeSessions: '活跃会话', nodeDetails: '节点详情', nodeCapabilities: '节点能力', nodeActions: '节点动作', nodeModels: '节点模型', nodeAgents: '节点 Agents', refreshAll: '刷新全部', refresh: '刷新', dashboardNodeP2PDetail: '{{transport}} · {{sessions}} 个活跃会话 · {{retries}} 次重试', dashboardNodeP2PTransport: '传输方式', dashboardNodeP2PIce: 'ICE 配置', dashboardNodeP2PHealth: '健康状态', dashboardNodeP2PSessions: '节点 P2P 会话', dashboardNodeP2PSessionsEmpty: '当前还没有节点 P2P 会话。', dashboardNodeP2PSessionCreated: '创建时间', dashboardNodeP2PSessionRetries: '重试次数', dashboardNodeP2PSessionReady: '最近就绪', dashboardNodeP2PSessionAttempt: '最近尝试', dashboardNodeP2PSessionError: '最近错误', dashboardNodeDispatches: '最近节点调度', dashboardNodeDispatchesHint: '展示最近节点动作实际走过的传输路径和回退记录。', dashboardNodeDispatchesEmpty: '当前还没有节点调度记录。', dashboardNodeDispatchTransport: '实际传输', dashboardNodeDispatchFallback: '回退来源', dashboardNodeDispatchDuration: '耗时', dashboardNodeDispatchArtifacts: '工件', dashboardNodeDispatchArtifactPreview: '工件预览', dashboardNodeDispatchError: '错误', configNodeP2P: '节点 P2P', configNodeP2PHint: '为远端节点配置 websocket tunnel 或 WebRTC 传输。', configNodeDispatch: '节点调度策略', configNodeDispatchHint: '控制节点选择偏好,并把动作或 agent 绑定到带标签的节点。', configNodeDispatchPreferLocal: '优先本地节点', configNodeDispatchPreferP2P: '优先 P2P 传输', configNodeDispatchAllowRelay: '允许 relay 回退', configNodeDispatchActionTags: '动作标签规则', configNodeDispatchAgentTags: 'Agent 标签规则', configNodeDispatchAllowActions: '节点允许动作', configNodeDispatchDenyActions: '节点禁止动作', configNodeDispatchAllowAgents: '节点允许 Agents', configNodeDispatchDenyAgents: '节点禁止 Agents', configNodeDispatchActionTagsPlaceholder: 'screen_snapshot=vision\ncamera_snap=vision,gpu', configNodeDispatchAgentTagsPlaceholder: 'coder=build\nvision=vision,gpu', configNodeDispatchAllowActionsPlaceholder: 'edge-a=camera_snap,screen_snapshot', configNodeDispatchDenyActionsPlaceholder: 'edge-b=screen_record', configNodeDispatchAllowAgentsPlaceholder: 'edge-a=main,coder', configNodeDispatchDenyAgentsPlaceholder: 'edge-b=vision', configNodeArtifacts: '节点工件保留策略', configNodeArtifactsHint: '自动清理旧节点工件,避免审计和媒体存储无限增长。', configNodeArtifactsKeepLatest: '保留最近工件数', configNodeArtifactsRetainDays: '保留天数(0 表示关闭)', configNodeArtifactsPruneOnRead: '在列表/导出时执行保留策略', configNodeP2PStunPlaceholder: '逗号分隔的 STUN URL', configNodeP2PIceServers: 'ICE 服务器', configNodeP2PIceServersEmpty: '当前没有结构化 ICE 服务器配置。', configNodeP2PIceUrlsPlaceholder: '逗号分隔的 ICE URL', configNodeP2PIceUsername: 'ICE 用户名', configNodeP2PIceCredential: 'ICE 凭证', active: '活跃', paused: '已暂停', noCronJobs: '未找到定时任务', noNodes: '无可用节点', allActions: '全部动作', allTransports: '全部传输', mainChat: '主对话', internalStream: '内部流', enable: '启用', disable: '停用', action: '动作', maxRetries: '最大重试次数', retryBackoffMs: '重试退避(毫秒)', agentPromptContentPlaceholder: 'AGENT.md 内容...', ekgOverviewHint: '运行时健康、Provider 压力与错误签名分布。', ekgActiveSources: '活跃来源', ekgActiveChannels: '活跃通道', ekgErrorsCount: '错误数', dashboardTopErrorSignature: 'Top 错误签名', dashboardWorkloadSnapshot: '24 小时业务负载快照', dashboardRecentFailedTasks: '最近失败任务', subagentGroup: '子代理群组', allAgents: '全部代理', agents: '代理', subagentDispatch: '子代理派发', subagentDispatchHint: '仅用于运维/调试。可直接向子代理发任务,不经过主对话链路。', dispatchToSubagent: '发起任务', subagentTaskPlaceholder: '描述要发给当前子代理的任务...', subagentLabelPlaceholder: '可选任务标签...', subagentTaskDispatched: '子代理任务已发起。', replyTo: '回复给', toAgent: '发送给', selfRefresh: '自我刷新', internalEvent: '内部事件', noSubagentStream: '当前还没有子代理内部流。', subagentGroupReadonly: '子代理群组为只读视图。', startConversation: '开始对话', typeMessage: '输入消息...', configuration: '配置', form: '表单', rawJson: '原始 JSON', reload: '重新加载', saveChanges: '保存更改', host: '主机', port: '端口', token: '令牌', providers: '提供商', providersIntroBefore: '先选择一个 provider 标签,再把认证模式切到 ', providersIntroMiddle: ' 或 ', providersIntroAfter: '。对应 provider 卡片里会出现 OAuth 字段、登录链接流程、回调地址回填和账号列表。', providersQwenLabelTitle: 'Qwen 账号标识', providersQwenLabelMessage: 'Qwen OAuth 可能不会返回邮箱,请输入一个邮箱或别名来标识该账号。', providersQwenImportLabelMessage: '请为导入的 Qwen 账号输入邮箱或别名。', providersQwenLabelPlaceholder: 'team-qwen-1', providersQwenLabelRequired: 'Qwen 账号标识不能为空。', providersStartingOAuthLogin: '正在发起 OAuth 登录', providersCompletingOAuthLogin: '正在完成 OAuth 登录', providersOAuthDeviceTitle: 'OAuth 设备码登录', providersOAuthDeviceMessage: '打开这个链接并完成授权。', providersOAuthUserCode: '用户码', providersOAuthLoginTitle: 'OAuth 登录', providersOAuthLoginMessage: '打开这个链接完成登录,然后把最终回调 URL 粘贴回来。', providersOAuthCallbackPlaceholder: 'http://localhost:1455/auth/callback?code=...&state=...', providersOAuthAddedTitle: 'OAuth 已添加', providersOAuthAddedMessage: '账号:{{account}}', providersOAuthAddedWithModel: '账号:{{account}}\n模型:{{model}}', providersOAuthAddedFallback: 'OAuth 账号已添加。', providersAuthJsonImportedTitle: 'auth.json 已导入', providersAuthJsonImportedMessage: 'OAuth auth.json 已导入。', providersImportingAuthJson: '正在导入 auth.json', providersSavingSelectedModel: '正在保存所选模型', providersSelectModelTitle: '选择模型', providersSelectModelMessage: 'OAuth 登录已经拉取到服务商模型,请选择这个 provider 要使用的模型。', providersSelectModelSearchPlaceholder: '搜索模型 ID', providersSelectModelConfirm: '使用这个模型', providersSelectModelEmpty: '当前搜索没有匹配到模型。', providersRefreshingOAuthAccount: '正在刷新 OAuth 账号', providersDeleteOAuthAccountTitle: '删除 OAuth 账号', providersDeletingOAuthAccount: '正在删除 OAuth 账号', providersClearingOAuthCooldown: '正在清除 OAuth 冷却', providersClearingAPICooldown: '正在清除 API 冷却', providersClearingHistory: '正在清除 provider 历史', providersRefreshRuntime: '刷新运行态', providersAutoRefresh: '自动刷新', providersRuntime1h: '运行态 1h', providersRuntime24h: '运行态 24h', providersRuntime7d: '运行态 7d', providersRuntimeAll: '运行态 全部', providersApiBase: 'API 基础地址', providersApiKey: 'API 密钥', providersModels: '模型列表', providersModelsHelp: '输入模型 ID 后按回车添加到这个 provider。', providersModelsEnterHint: '输入模型 ID 后按回车', providersAuthMode: '认证模式', providersAuthModeHelp: 'bearer 表示只用 API key,oauth 表示只用 OAuth,hybrid 表示两者混用。', providersRuntimePersist: '运行态持久化', providersRuntimePersistHelp: '是否把这个 provider 的运行态历史写入磁盘。', providersRuntimeHistoryFile: '运行态历史文件', providersRuntimeHistoryMax: '运行态历史上限', providersSwitchAuthBefore: '先把认证模式切到 ', providersSwitchAuthMiddle: ' 或 ', providersSwitchAuthAfter: ',然后才能选择 OAuth 服务商并发起登录。', providersOAuthSetup: 'OAuth 配置', providersOAuthProvider: 'OAuth 服务商', providersOAuthProviderHelp: '选择要登录的上游 OAuth 服务商。', providersSelectProvider: '选择服务商', providersClientSecret: 'Client Secret', providersClientSecretHelp: '只有部分 provider 需要显式填写 client secret。', providersNetworkProxy: '网络代理', providersNetworkProxyHelp: '可选。填写后,这个 OAuth 账号的登录、刷新、拉模型和后续请求都会走这个代理。', providersNetworkProxyPlaceholder: 'http://127.0.0.1:7890', providersCredentialFiles: '凭证文件', providersCredentialFilesHelp: '登录后会自动维护,也可以手工编辑。', providersCooldownSec: '冷却秒数', providersRefreshScanSec: '刷新扫描秒数', providersRefreshLeadSec: '提前刷新秒数', providersOAuthGuideBefore: '先选择 OAuth 服务商,然后点击 ', providersOAuthGuideAfter: '。弹窗里会显示授权链接,并在 callback 型服务商场景下要求你回填最终回调 URL。', providersOAuthLoginButton: 'OAuth 登录', providersImportAuthJson: '导入 auth.json', providersOAuthAccounts: 'OAuth 账号', providersRefreshList: '刷新列表', providersNoOAuthAccounts: '当前还没有导入 OAuth 账号。', system: '系统', pauseJob: '暂停任务', startJob: '启动任务', deleteJob: '删除任务', gatewayToken: '网关令牌', enterToken: '输入令牌...', addJob: '新增任务', editJob: '编辑任务', jobName: '任务名称', kind: '类型', cronExpression: 'Cron 表达式', runAt: '执行时间', message: '消息', deliver: '投递', channel: '频道', to: '接收者', cancel: '取消', save: '保存', create: '创建', update: '更新', delete: '删除', add: '添加', install: '安装', installed: '已安装', notInstalled: '未安装', status: '状态', source: '来源', duration: '耗时', provider: '提供商', model: '模型', time: '时间', level: '级别', code: '代码', template: '模板', id: 'ID', files: '文件', close: '关闭', path: '路径', before: '变更前', after: '变更后', clear: '清空', pause: '暂停', resume: '继续', live: '实时', raw: '原始', pretty: '格式化', entries: '条', appName: 'ClawGo', webui: 'WebUI', node: '节点', memoryFiles: '记忆文件', memoryFileNamePrompt: '记忆文件名', noFileSelected: '未选择文件', noDescription: '暂无描述。', empty: '(空)', modal: '弹窗', dialogPleaseConfirm: '请确认', dialogNotice: '提示', dialogInputTitle: '请输入', dialogInputPlaceholder: '请输入内容...', dialogOk: '确定', requestFailed: '请求失败', saved: '已保存', saving: '保存中...', creating: '创建中...', deleting: '删除中...', memoryCreateTitle: '创建记忆文件', memoryFileSaved: '记忆文件已保存。', cronSaved: '定时任务已保存。', reloadHistory: '重新加载历史', user: '用户', exec: '执行', agent: '助手', toolOutput: '工具输出', chatServerError: '错误:获取服务端响应失败。', waitingForLogs: '等待日志中...', systemLog: '系统日志', codeCaller: '代码/来源', recursiveAddValuePlaceholder: '输入新值后添加', recursiveSelectOption: '下拉选择', logCodesSearchPlaceholder: '搜索代码/文本', logCodesNoCodes: '暂无代码', skillsDeleteTitle: '删除技能', skillsDeleteMessage: '确认删除这个技能吗?', skillsClawhubMissingTitle: '未检测到 clawhub', skillsClawhubMissingMessage: '检测到系统中未安装 clawhub。是否自动安装依赖环境并安装 clawhub?', skillsInstallPanelHint: '点击“立即安装”即可初始化技能环境。如果系统缺少 Node.js/npm,ClawGo 会先安装它们,再安装 clawhub。', skillsInstallNow: '立即安装', skillsInstallingDeps: '正在安装 node/npm 与 clawhub...', skillsInstallFailedTitle: '安装失败', skillsInstallFailedMessage: '安装 clawhub 失败', skillsInstallDoneTitle: '安装完成', skillsInstallDoneMessage: 'clawhub 已安装,可继续安装技能。', skillsInstallingSkill: '正在安装技能...', skillsInstallSkillDoneTitle: '技能安装完成', skillsInstallSkillDoneMessage: '技能 "{{name}}" 安装成功。', skillsAddTitle: '添加技能', skillsAddMessage: '请上传技能压缩包(.zip / .tar.gz / .tgz / .tar)。上传后将自动解压到 skills 目录,并删除上传压缩包。', skillsSelectArchive: '选择压缩包', skillsImporting: '正在上传并导入技能...', skillsImportFailedTitle: '导入失败', skillsImportFailedMessage: '技能压缩包导入失败', skillsImportDoneTitle: '导入完成', skillsImportedPrefix: '已导入', skillsImportDoneMessage: '技能导入成功。', skillsFileSaved: '技能文件保存成功。', skillsNamePlaceholder: '技能名', skillsIgnoreSuspicious: '忽略可疑告警(使用 --force)', skillsClawhubNotFound: '未找到 clawhub', skillsClawhubStatus: 'clawhub', skillsAdd: '添加技能', skillsNoTools: '未定义工具', skillsFileEdit: '文件编辑', configDiffPreview: '差异预览', configBasicMode: '基础模式', configAdvancedMode: '高级模式', configSaved: '配置已保存。', configRiskyChangeConfirmTitle: '确认高风险配置变更', configRiskyChangeConfirmMessage: '以下敏感字段已变更:{{fields}}。仍要保存吗?', configHotOnly: '仅热更新字段', configSearchPlaceholder: '搜索分类...', configHotFieldsFull: '热更新字段(完整)', configTopLevel: '顶层分类', configProxies: '代理配置', configNewProviderName: 'provider 名称,例如 openai', configNoCustomProviders: '暂无自定义 provider。', configMCPServers: 'MCP 服务', configNewMCPServerName: '新的 MCP 服务名', configNoMCPServers: '暂无 MCP 服务配置。', configMCPInstallTitle: '安装 MCP 服务包', configMCPInstallMessage: '是否为 MCP 服务 “{{name}}” 安装 npm 包?', configMCPInstallPlaceholder: '@scope/package', configMCPInstalling: '正在安装 MCP 包...', configMCPInstallFailedTitle: 'MCP 安装失败', configMCPInstallFailedMessage: '安装 MCP 包失败', configMCPInstallDoneTitle: 'MCP 包安装完成', configMCPInstallDoneMessage: '已安装 {{package}},并解析到可执行文件 {{bin}}。', configMCPInstallDoneFallback: 'MCP 包已安装。', configMCPArgsEnterHint: '输入一个参数后按回车添加', configMCPCommandMissing: 'MCP 命令不可用。', configMCPInstallSuggested: '建议安装包:{{pkg}}', configDeleteMCPServerConfirmTitle: '删除 MCP 服务', configDeleteMCPServerConfirmMessage: '确认从当前配置中删除 MCP 服务 “{{name}}”吗?', configNoGroups: '未找到配置分组。', configDiffPreviewCount: '配置差异预览({{count}}项)', saveConfigFailed: '保存配置失败', sourceDirect: 'direct', sourceMemoryTodo: 'memory_todo', statusRunning: 'running', statusWaiting: 'waiting', idle: '空闲', statusBlocked: 'blocked', statusSuccess: 'success', statusError: 'error', statusSuppressed: 'suppressed', taskId: '任务 ID', inputPreview: '输入预览', blockReason: '阻断原因', actionFailed: '操作失败', cronDeleteConfirmTitle: '删除定时任务', cronDeleteConfirmMessage: '此操作会永久删除该定时任务,是否继续?', cronDisableConfirmTitle: '暂停定时任务', cronDisableConfirmMessage: '确认暂停该定时任务吗?', memoryDeleteConfirmTitle: '删除记忆文件', memoryDeleteConfirmMessage: '确认永久删除记忆文件“{{path}}”吗?', logsClearConfirmTitle: '清空日志', logsClearConfirmMessage: '确认清空当前页面中的日志列表吗?', configDeleteProviderConfirmTitle: '删除 Provider', configDeleteProviderConfirmMessage: '确认从当前配置中删除 provider “{{name}}”吗?', cronExpressionPlaceholder: '*/5 * * * *', recipientId: '接收者 ID', languageZh: '中文', languageEn: 'English', themeLight: '白天', themeDark: '黑夜', expand: '展开', collapse: '收起', configRoot: '(根)', configCommaSeparatedHint: ',例如 a,b', configLabels: { gateway: '网关', host: '主机', port: '端口', token: '令牌', agents: '代理', defaults: '默认值', max_tool_iterations: '最大工具迭代次数', max_tokens: '最大 Token 数', providers: '提供商', proxy: '代理', timeout_sec: '超时时间 (秒)', shell: 'Shell', enabled: '启用', logging: '日志', level: '日志级别', format: '日志格式', storage: '存储', path: '路径', database: '数据库', type: '类型', connection: '连接', security: '安全', cors: '跨域资源共享 (CORS)', allowed_origins: '允许的来源', rate_limit: '速率限制', requests_per_minute: '每分钟请求数', enabled_true: '已启用', enabled_false: '已禁用', openai: 'OpenAI', gemini: 'Gemini', anthropic: 'Anthropic', api_key: 'API 密钥', model: '模型', temperature: '温度', top_p: 'Top P', top_k: 'Top K', presence_penalty: '存在惩罚', frequency_penalty: '频率惩罚', stream: '流式传输', user: '用户', system_instruction: '系统指令', max_output_tokens: '最大输出 Token', response_mime_type: '响应 MIME 类型', thinking_config: '思考配置', thinking_level: '思考级别', google_search: '谷歌搜索', google_maps: '谷歌地图', url_context: 'URL 上下文', api_base: 'API 基础地址', protocol: '协议', models: '模型列表', command: '命令', responses: 'Responses 配置', streaming: '流式输出', web_search_enabled: '启用网页搜索', web_search_context_size: '网页搜索上下文大小', file_search_vector_store_ids: '文件搜索向量库 ID 列表', file_search_max_num_results: '文件搜索最大结果数', include: '包含字段', stream_include_usage: '流式包含用量', organization: '组织', project: '项目', region: '区域', deployment_name: '部署名称', version: '版本', name: '名称', description: '描述', package: '包名', system_prompt: '系统提示词', tools: '工具', auth: '身份验证', jwt: 'JWT', secret: '密钥', issuer: '发行者', audience: '受众', expires_in: '过期时间', refresh_token: '刷新令牌', access_token: '访问令牌', client_id: '客户端 ID', client_secret: '客户端密钥', redirect_uri: '重定向 URI', scope: '范围', state: '状态', retry: '重试', backoff: '退避', factor: '因子', min_delay: '最小延迟', max_delay: '最大延迟', jitter: '抖动', channels: '通道', cron: '定时任务', workspace: '工作目录', proxy_fallbacks: '模型回退链', heartbeat: '心跳', every_sec: '间隔(秒)', ack_max_chars: '确认最大字符数', prompt_template: '提示模板', context_compaction: '上下文压缩', mode: '模式', trigger_messages: '触发消息数', keep_recent_messages: '保留最近消息数', max_summary_chars: '摘要最大字符数', max_transcript_chars: '转录最大字符数', execution: '执行控制', summary_policy: '摘要策略', policy: '策略', intent_max_input_chars: '意图输入最大字符数', max_rounds_without_user: '无用户最大轮数', run_state_ttl_seconds: '运行状态 TTL(秒)', run_state_max: '运行状态上限', tool_parallel_safe_names: '工具并行安全名单', tool_max_parallel_calls: '工具最大并行调用数', marker: '摘要标记', completed_prefix: '完成前缀', changes_prefix: '变更前缀', outcome_prefix: '结果前缀', completed_title: '完成标题', changes_title: '变更标题', outcomes_title: '结果标题', inbound_message_id_dedupe_ttl_seconds: '入站消息去重 TTL(秒)', inbound_content_dedupe_window_seconds: '入站内容去重窗口(秒)', outbound_dedupe_window_seconds: '出站去重窗口(秒)', telegram: 'Telegram', allow_from: '允许发送者', allow_chats: '允许会话', enable_groups: '启用群组', require_mention_in_groups: '群组需 @ 提及', discord: 'Discord', maixcam: 'MaixCam', whatsapp: 'WhatsApp', qq: 'QQ', bridge_url: '桥接地址', feishu: '飞书', app_id: '应用 ID', app_secret: '应用密钥', encrypt_key: '加密 Key', verification_token: '校验 Token', dingtalk: '钉钉', filesystem: '文件系统', working_dir: '工作目录', url: '地址', timeout: '超时', auto_install_missing: '自动安装缺失依赖', sandbox: '沙箱', image: '镜像', web: 'Web', mcp: 'MCP', search: '搜索', max_results: '最大结果数', request_timeout_sec: '请求超时(秒)', servers: '服务列表', transport: '传输方式', args: '参数', env: '环境变量', proxies: '代理集合', cross_session_call_id: '跨会话调用 ID', supports_responses_compact: '支持紧凑 responses', dispatch: '调度', prefer_local: '优先本地', prefer_p2p: '优先 P2P', allow_relay_fallback: '允许 Relay 回退', action_tags: '动作标签', agent_tags: 'Agent 标签', min_sleep_sec: '最小休眠(秒)', max_sleep_sec: '最大休眠(秒)', retry_backoff_base_sec: '重试退避基准(秒)', retry_backoff_max_sec: '重试退避上限(秒)', max_consecutive_failure_retries: '最大连续失败重试次数', max_workers: '最大 worker 数', dir: '目录', filename: '文件名', max_size_mb: '最大大小(MB)', retention_days: '保留天数', notify_channel: '通知通道', notify_chat_id: '通知会话 ID', webhook_url: 'Webhook 地址' } } } }; i18n .use(LanguageDetector) .use(initReactI18next) .init({ resources, fallbackLng: 'zh', interpolation: { escapeValue: false, }, }); export default i18n;