Files
chatgpt-on-wechat/desktop/src/renderer/src/i18n.ts
2026-06-29 19:52:46 +08:00

756 lines
34 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const translations: Record<string, Record<string, string>> = {
zh: {
console: '控制台',
nav_chat: '对话',
nav_manage: '管理',
nav_monitor: '监控',
menu_chat: '对话',
menu_config: '配置',
menu_skills: '技能',
menu_memory: '记忆',
menu_channels: '通道',
menu_tasks: '定时',
menu_logs: '日志',
menu_models: '模型',
menu_knowledge: '知识',
menu_settings: '设置',
// knowledge
knowledge_title: '知识库',
knowledge_desc: '浏览和探索你的知识库',
knowledge_tab_docs: '文档',
knowledge_tab_graph: '图谱',
knowledge_search: '搜索文档...',
knowledge_stats: '{pages} 篇 · {size}',
knowledge_select_hint: '从左侧选择一个文档查看',
knowledge_empty: '知识库还是空的',
knowledge_empty_guide: '在对话中发送文档、链接或主题给 Agent它会自动整理到你的知识库中',
knowledge_go_chat: '开始对话',
knowledge_loading: '加载知识库中...',
knowledge_graph_empty: '暂无关联图谱',
knowledge_disabled: '知识库未启用',
knowledge_doc_load_error: '文档加载失败',
// knowledge management
knowledge_new: '新建',
knowledge_new_category: '新建分类',
knowledge_new_document: '新建文档',
knowledge_import_documents: '导入文档',
knowledge_working: '处理中...',
knowledge_importing: '正在导入...',
knowledge_request_failed: '请求失败,请稍后重试',
knowledge_import_failed: '导入失败',
knowledge_category_created: '分类已创建',
knowledge_document_created: '文档已创建',
knowledge_dialog_confirm: '确定',
knowledge_dialog_cancel: '取消',
knowledge_field_required: '此项不能为空',
knowledge_category_label: '分类路径',
knowledge_category_hint: '支持嵌套路径,例如 research/ai',
knowledge_category_subtitle: '分类会创建为 knowledge/ 下的目录',
knowledge_need_category: '请先创建分类',
knowledge_destination: '目标分类',
knowledge_doc_choose_category: '先选择分类,然后输入文件名',
knowledge_doc_save_to: '保存到 {category}',
knowledge_doc_filename: '文件名',
knowledge_doc_filename_required: '文件名不能为空',
knowledge_doc_must_md: '新建文档仅支持 .md 文件名',
knowledge_doc_content: 'Markdown 内容',
knowledge_doc_content_required: '内容不能为空',
knowledge_doc_content_too_large: '内容不能超过 10MB',
knowledge_doc_insert_template: '插入模板',
knowledge_import_selected: '已选择 {count} 个文件',
knowledge_import_hint: '支持 Markdown 和 TXTTXT 会转成 Markdown 文档',
knowledge_import_need_category: '请先创建一个分类',
knowledge_import_choose_files: '请选择 .md 或 .txt 文件',
knowledge_import_too_many: '一次最多导入 {max} 个文件',
knowledge_import_file_too_large: '{name} 超过 10MB',
knowledge_import_total_too_large: '单次导入总大小不能超过 200MB',
knowledge_import_result: '导入 {imported} 个,跳过 {skipped} 个,失败 {failed} 个',
knowledge_drop_hint: '拖放 .md / .txt 文件到此导入',
nav_expand: '展开侧栏',
nav_collapse: '收起侧栏',
session_history: '历史会话',
update_available: '发现新版本',
update_download: '下载更新',
update_downloading: '正在下载',
update_restart: '重启以更新',
update_later: '稍后',
update_latest: '已是最新版本',
// onboarding
onboarding_welcome_title: '欢迎使用 CowAgent',
onboarding_welcome_desc: '你的私人超级 AI 助手。几步设置,即可开始对话。',
onboarding_lang_label: '界面语言',
onboarding_model_title: '配置对话模型',
onboarding_model_desc: '选择模型厂商并填入 API Key即可开始使用。',
onboarding_provider: '模型厂商',
onboarding_select_provider: '选择厂商',
onboarding_apikey: 'API Key',
onboarding_apikey_placeholder: '输入 API 密钥',
onboarding_key_guide: '没有秘钥?前往创建',
onboarding_apibase: 'API 地址(可选)',
onboarding_model: '模型',
onboarding_select_model: '选择模型',
onboarding_done_title: '一切就绪',
onboarding_done_desc: '配置完成,开始你的第一次对话吧。',
onboarding_next: '下一步',
onboarding_back: '上一步',
onboarding_skip: '跳过',
onboarding_finish: '开始对话',
onboarding_step: '第 {n} / {total} 步',
onboarding_saving: '保存中...',
onboarding_save_failed: '保存失败,请检查后重试',
sessions_title: '会话',
session_new: '新对话',
session_rename: '重命名',
session_delete: '删除',
session_empty: '暂无会话',
session_today: '今天',
session_yesterday: '昨天',
session_earlier: '更早',
msg_copy: '复制',
msg_copied: '已复制',
msg_regenerate: '重新生成',
msg_edit: '编辑',
msg_delete: '删除',
msg_cancelled: '已中止',
msg_self_learned: '自主学习',
msg_stop: '停止',
chat_clear_context: '清除上下文',
chat_load_earlier: '加载更早的消息',
chat_send: '发送',
chat_attach: '添加附件',
slash_hint: '输入 / 查看命令',
chat_welcome: '有什么可以帮你的?',
chat_empty_hint: '发送一条消息开始对话',
welcome_subtitle: '我可以帮你解答问题、管理你的电脑、创建并执行技能,\n还能通过长期记忆不断成长。',
example_sys_title: '系统管理',
example_sys_text: '查看工作空间里有哪些文件',
example_task_title: '定时任务',
example_task_text: '1分钟后提醒我检查服务器',
example_code_title: '编程助手',
example_code_text: '搜索AI资讯并生成可视化网页报告',
example_knowledge_title: '知识库',
example_knowledge_text: '查看知识库当前文档情况',
example_skill_title: '技能系统',
example_skill_text: '查看所有支持的工具和技能',
example_web_title: '指令中心',
example_web_text: '查看全部命令',
input_placeholder: '输入消息...',
config_title: '配置管理',
config_desc: '管理模型和 Agent 配置',
config_model: '模型配置',
config_agent: 'Agent 配置',
config_provider: '模型厂商',
config_model_name: '模型',
config_custom_model_hint: '输入自定义模型名称',
config_save: '保存',
config_saved: '已保存',
config_save_error: '保存失败',
config_custom_option: '自定义',
config_max_tokens: '最大上下文 Token',
config_max_turns: '最大记忆轮次',
config_max_steps: '最大执行步数',
config_max_tokens_hint: '对话中 Agent 能输入的最大 Token 长度,超过后会智能压缩处理',
config_max_turns_hint: '一问一答为一轮,超过后会智能压缩处理',
config_max_steps_hint: '单次对话中 Agent 最多调用工具的次数',
config_thinking: '深度思考',
config_thinking_hint: '是否启用深度思考模式',
config_evolution: '自主进化',
config_evolution_hint: '会话空闲后自动复盘,沉淀记忆、优化技能、处理未完成事项',
config_security: '安全设置',
config_password: '访问密码',
config_password_hint: '留空则不启用密码保护',
config_password_placeholder: '留空表示不设密码',
config_password_saved: '密码已更新,请重新登录',
config_password_cleared: '密码已清除',
config_language: '语言',
config_language_hint: '界面与回复语言',
config_credentials_link: 'API Key 与接口地址请在「模型配置」中设置',
config_goto_models: '前往配置',
config_provider_unconfigured: '未配置',
config_provider_unconfigured_hint: '该厂商尚未配置 API Key请先前往配置',
config_cancel: '取消',
// settings tabs
settings_tab_basic: '基础配置',
settings_tab_models: '模型配置',
// models tab
models_vendors: '厂商凭据',
models_vendors_sub: '一处配置,多个模型能力共享',
models_configured: '已配置',
models_no_vendor: '尚未配置任何厂商',
models_add_vendor: '添加厂商',
models_custom_vendor: '自定义',
models_add_custom: '添加自定义厂商',
models_add_custom_hint: '接口需遵循 OpenAI API 协议',
models_edit_custom: '编辑自定义厂商',
models_custom_name: '名称',
models_custom_base_hint: '接口需遵循 OpenAI API 协议',
models_clear: '清除凭据',
models_delete: '删除',
models_clear_confirm: '确认清除该厂商的 API Key 与 Base URL 吗?相关能力将不再可用。',
models_delete_confirm: '确定删除该自定义厂商吗?此操作无法撤销。',
models_provider: '厂商',
models_model: '模型',
models_voice: '音色',
models_select_provider: '待选择',
models_select_model: '请选择模型',
models_select_voice: '请选择音色',
models_no_options: '暂无可选项',
models_auto: '自动',
models_asr_auto: '自动(跟随主模型)',
models_disabled: '不启用',
models_fallback: '兜底',
models_cap_chat: '主模型',
models_cap_chat_sub: '用于基础对话和 Agent 推理',
models_cap_vision: '图像理解',
models_cap_vision_sub: '识别图片内容,用于图像识别工具',
models_cap_image: '图像生成',
models_cap_image_sub: '生成图片,用于图像生成技能',
models_cap_asr: '语音识别',
models_cap_asr_sub: '语音转文字',
models_cap_tts: '语音合成',
models_cap_tts_sub: '文字转语音',
models_cap_embedding: '向量',
models_cap_embedding_sub: '用于记忆与知识的向量化检索',
models_cap_search: '联网搜索',
models_cap_search_sub: '实时网页检索能力,用于搜索工具',
models_tts_reply_mode: '语音回复模式',
models_tts_reply_mode_hint: '决定何时以语音回复用户',
models_tts_mode_off: '关闭',
models_tts_mode_if_voice: '仅当用户发语音时',
models_tts_mode_always: '始终语音回复',
models_embedding_dim: '维度',
models_embedding_rebuild_hint: '切换向量模型后,已有索引将失效,需要重建',
models_search_strategy: '策略',
models_search_auto: '自动',
models_search_fixed: '指定',
models_search_provider: '搜索厂商',
models_search_bocha_key: '配置博查 API Key',
models_search_bocha_hint: '前往博查开放平台创建 API Key',
skills_title: '技能管理',
skills_desc: '查看、启用或禁用 Agent 工具和技能',
skills_hub_btn: '探索技能广场',
tools_section_title: '内置工具',
skills_section_title: '技能',
tools_loading: '加载工具中...',
skills_loading: '加载技能中...',
skills_loading_desc: '技能将在加载后显示',
skill_enabled: '已启用',
skill_disabled: '已禁用',
tools_empty: '暂无内置工具',
skills_empty: '暂无技能',
memory_title: '记忆管理',
memory_desc: '查看 Agent 记忆文件和内容',
memory_tab_files: '记忆文件',
memory_tab_dreams: '自主进化',
memory_loading: '加载记忆文件中...',
memory_loading_desc: '记忆文件将在加载后显示',
memory_col_name: '文件名',
memory_col_type: '类型',
memory_col_size: '大小',
memory_col_updated: '更新时间',
memory_back: '返回列表',
memory_empty_files: '暂无记忆文件',
memory_empty_evolution: '暂无进化记录',
memory_type_global: '全局',
memory_type_daily: '每日',
memory_type_evolution: '进化',
memory_type_dream: '梦境',
memory_doc_load_error: '内容加载失败',
memory_prev: '上一页',
memory_next: '下一页',
channels_title: '通道管理',
channels_desc: '查看和管理消息通道',
channels_add: '接入通道',
channels_select_label: '选择要接入的通道',
channels_select_placeholder: '请选择通道...',
channels_add_close: '关闭',
channels_connected: '已连接',
channels_disconnected: '未连接',
channels_connect: '连接',
channels_disconnect: '断开',
channels_save: '保存',
channels_loading: '加载通道中...',
channels_connected_section: '已连接',
channels_available_section: '可添加',
channels_empty_connected: '暂无已连接的通道',
channels_qr_hint: '该通道通过扫码登录,请前往 Web 控制台完成扫码连接',
channels_save_ok: '已保存',
channels_save_error: '保存失败',
channels_connect_error: '连接失败',
channels_scan_login: '扫码登录',
channels_scan_register: '扫码注册',
weixin_scan_title: '微信扫码登录',
weixin_scan_desc: '使用微信扫描下方二维码登录',
weixin_scan_loading: '正在获取二维码...',
weixin_scan_waiting: '等待扫码',
weixin_scan_scanned: '已扫描,请在手机上确认',
weixin_scan_success: '登录成功',
weixin_scan_expired: '二维码已过期,正在刷新...',
weixin_scan_fail: '获取二维码失败',
weixin_qr_tip: '请使用登录的微信扫码',
feishu_scan_title: '飞书扫码注册',
feishu_scan_desc: '扫码后将自动创建并连接飞书机器人',
feishu_scan_loading: '正在生成二维码...',
feishu_scan_waiting: '请使用飞书扫码授权',
feishu_scan_tip: '扫码后在飞书中确认授权',
feishu_scan_open_link: '打开授权链接',
feishu_scan_success: '注册成功',
feishu_scan_expired: '二维码已过期',
feishu_scan_denied: '授权被拒绝',
feishu_scan_fail: '注册失败',
feishu_scan_retry: '重试',
tasks_title: '定时任务',
tasks_desc: '查看和管理定时任务',
tasks_active: '运行中',
tasks_paused: '已暂停',
tasks_empty: '暂无定时任务',
tasks_empty_guide: '在对话中告诉 Agent「每天 9 点提醒我…」即可创建定时任务',
tasks_go_chat: '去对话创建',
tasks_next_run: '下次执行',
tasks_loading: '加载定时任务中...',
task_edit_title: '编辑任务',
task_name: '名称',
task_enabled: '启用',
task_schedule_type: '调度类型',
task_type_cron: 'Cron 表达式',
task_type_interval: '固定间隔',
task_type_once: '单次执行',
task_cron_expr: 'Cron 表达式',
task_cron_hint: '如 0 9 * * * 表示每天 9 点',
task_interval_seconds: '间隔(秒)',
task_once_time: '执行时间',
task_action_type: '动作类型',
task_action_send: '发送消息',
task_action_agent: 'Agent 任务',
task_message_content: '消息内容',
task_task_description: '任务描述',
task_channel: '通道',
task_receiver: '接收者',
task_channel_locked: '通道与接收者创建后不可修改',
task_save: '保存',
task_cancel: '取消',
task_delete: '删除',
task_delete_confirm: '确定删除该任务吗?此操作不可撤销。',
task_save_error: '保存失败',
logs_title: '日志',
logs_desc: '实时日志输出 (run.log)',
logs_live: '实时',
logs_connecting: '日志流将在连接后显示...',
status_starting: '正在启动 CowAgent...',
status_starting_desc: '正在初始化客户端,请稍候',
status_error: '初始化失败',
status_error_desc: '客户端初始化失败,请重试',
status_retry: '重试',
// slash command descriptions
slash_menu_title: '命令',
slash_new: '新建对话',
slash_clear: '清除对话上下文',
slash_help: '显示命令帮助',
slash_status: '查看运行状态',
slash_context: '查看对话上下文',
slash_skill_list: '查看已安装技能',
slash_skill_search: '搜索技能',
slash_skill_install: '安装技能 (名称或 GitHub URL)',
slash_memory_dream: '手动触发记忆蒸馏 (可指定天数, 默认3)',
slash_knowledge: '查看知识库统计',
slash_knowledge_list: '查看知识库文件树',
slash_config: '查看当前配置',
slash_cancel: '中止当前正在运行的 Agent 任务',
slash_logs: '查看最近日志',
slash_version: '查看版本',
},
en: {
console: 'Console',
nav_chat: 'Chat',
nav_manage: 'Management',
nav_monitor: 'Monitor',
menu_chat: 'Chat',
menu_config: 'Config',
menu_skills: 'Skills',
menu_memory: 'Memory',
menu_channels: 'Channels',
menu_tasks: 'Tasks',
menu_logs: 'Logs',
menu_models: 'Models',
menu_knowledge: 'Knowledge',
// knowledge
knowledge_title: 'Knowledge Base',
knowledge_desc: 'Browse and explore your knowledge base',
knowledge_tab_docs: 'Documents',
knowledge_tab_graph: 'Graph',
knowledge_search: 'Search documents...',
knowledge_stats: '{pages} pages · {size}',
knowledge_select_hint: 'Select a document to view',
knowledge_empty: 'Your knowledge base is empty',
knowledge_empty_guide: 'Send documents, links or topics to the agent in chat — it will organize them into your knowledge base',
knowledge_go_chat: 'Start chatting',
knowledge_loading: 'Loading knowledge base...',
knowledge_graph_empty: 'No graph available',
knowledge_disabled: 'Knowledge base is disabled',
knowledge_doc_load_error: 'Failed to load document',
// knowledge management
knowledge_new: 'New',
knowledge_new_category: 'New category',
knowledge_new_document: 'New document',
knowledge_import_documents: 'Import documents',
knowledge_working: 'Working...',
knowledge_importing: 'Importing...',
knowledge_request_failed: 'Request failed, please try again',
knowledge_import_failed: 'Import failed',
knowledge_category_created: 'Category created',
knowledge_document_created: 'Document created',
knowledge_dialog_confirm: 'Confirm',
knowledge_dialog_cancel: 'Cancel',
knowledge_field_required: 'This field is required',
knowledge_category_label: 'Category path',
knowledge_category_hint: 'Nested paths are supported, e.g. research/ai',
knowledge_category_subtitle: 'Creates a directory under knowledge/',
knowledge_need_category: 'Create a category first',
knowledge_destination: 'Destination category',
knowledge_doc_choose_category: 'Choose a category, then enter a filename',
knowledge_doc_save_to: 'Save to {category}',
knowledge_doc_filename: 'Filename',
knowledge_doc_filename_required: 'Filename is required',
knowledge_doc_must_md: 'New documents must be .md files',
knowledge_doc_content: 'Markdown content',
knowledge_doc_content_required: 'Content is required',
knowledge_doc_content_too_large: 'Content cannot exceed 10MB',
knowledge_doc_insert_template: 'Insert template',
knowledge_import_selected: '{count} file(s) selected',
knowledge_import_hint: 'Markdown and TXT are supported. TXT is converted to Markdown.',
knowledge_import_need_category: 'Create a category first',
knowledge_import_choose_files: 'Choose .md or .txt files',
knowledge_import_too_many: 'Import at most {max} files at a time',
knowledge_import_file_too_large: '{name} exceeds 10MB',
knowledge_import_total_too_large: 'Total import size cannot exceed 200MB',
knowledge_import_result: '{imported} imported · {skipped} skipped · {failed} failed',
knowledge_drop_hint: 'Drop .md / .txt files here to import',
menu_settings: 'Settings',
nav_expand: 'Expand sidebar',
nav_collapse: 'Collapse sidebar',
session_history: 'Chat history',
update_available: 'New version available',
update_download: 'Download update',
update_downloading: 'Downloading',
update_restart: 'Restart to update',
update_later: 'Later',
update_latest: 'You are up to date',
// onboarding
onboarding_welcome_title: 'Welcome to CowAgent',
onboarding_welcome_desc: 'Your personal super AI assistant. A few quick steps and you are ready to chat.',
onboarding_lang_label: 'Language',
onboarding_model_title: 'Set up your chat model',
onboarding_model_desc: 'Pick a provider and paste its API key to get started.',
onboarding_provider: 'Provider',
onboarding_select_provider: 'Select a provider',
onboarding_apikey: 'API Key',
onboarding_apikey_placeholder: 'Enter your API key',
onboarding_key_guide: 'No key yet? Create one',
onboarding_apibase: 'API base (optional)',
onboarding_model: 'Model',
onboarding_select_model: 'Select a model',
onboarding_done_title: 'All set',
onboarding_done_desc: 'Setup complete. Start your first conversation.',
onboarding_next: 'Next',
onboarding_back: 'Back',
onboarding_skip: 'Skip',
onboarding_finish: 'Start chatting',
onboarding_step: 'Step {n} of {total}',
onboarding_saving: 'Saving...',
onboarding_save_failed: 'Save failed, please check and retry',
sessions_title: 'Chats',
session_new: 'New chat',
session_rename: 'Rename',
session_delete: 'Delete',
session_empty: 'No conversations yet',
session_today: 'Today',
session_yesterday: 'Yesterday',
session_earlier: 'Earlier',
msg_copy: 'Copy',
msg_copied: 'Copied',
msg_regenerate: 'Regenerate',
msg_edit: 'Edit',
msg_delete: 'Delete',
msg_cancelled: 'Cancelled',
msg_self_learned: 'Self-learned',
msg_stop: 'Stop',
chat_clear_context: 'Clear context',
chat_load_earlier: 'Load earlier messages',
chat_send: 'Send',
chat_attach: 'Attach file',
slash_hint: 'Type / for commands',
chat_welcome: 'How can I help you?',
chat_empty_hint: 'Send a message to start the conversation',
welcome_subtitle: 'I can help you answer questions, manage your computer, create and execute skills,\nand keep growing through long-term memory.',
example_sys_title: 'System',
example_sys_text: 'Show me the files in the workspace',
example_task_title: 'Scheduled Task',
example_task_text: 'Remind me to check the server in 1 minute',
example_code_title: 'Coding',
example_code_text: 'Search AI news and build a visual web report',
example_knowledge_title: 'Knowledge Base',
example_knowledge_text: 'Show the current documents in the knowledge base',
example_skill_title: 'Skills',
example_skill_text: 'Show all supported tools and skills',
example_web_title: 'Commands',
example_web_text: 'Show all commands',
input_placeholder: 'Type a message...',
config_title: 'Configuration',
config_desc: 'Manage model and agent settings',
config_model: 'Model Configuration',
config_agent: 'Agent Configuration',
config_provider: 'Provider',
config_model_name: 'Model',
config_custom_model_hint: 'Enter custom model name',
config_save: 'Save',
config_saved: 'Saved',
config_save_error: 'Save failed',
config_custom_option: 'Custom',
config_max_tokens_hint: 'Max token length the Agent can take in; longer context is compressed automatically',
config_max_turns_hint: 'One question and answer is a turn; older turns are compressed automatically',
config_max_steps_hint: 'Max tool calls the Agent can make in one turn',
config_thinking: 'Deep Thinking',
config_thinking_hint: 'Whether to enable deep thinking mode',
config_evolution: 'Self-Evolution',
config_evolution_hint: 'Review automatically when idle: consolidate memory, refine skills, finish pending tasks',
config_security: 'Security',
config_password: 'Access Password',
config_password_hint: 'Leave empty to disable password protection',
config_password_placeholder: 'Leave empty for no password',
config_password_saved: 'Password updated, please log in again',
config_password_cleared: 'Password cleared',
config_language: 'Language',
config_language_hint: 'Interface and reply language',
config_credentials_link: 'Set API key and endpoint in "Models"',
config_goto_models: 'Configure',
config_provider_unconfigured: 'Not configured',
config_provider_unconfigured_hint: 'This provider has no API key yet — configure it first',
config_cancel: 'Cancel',
// settings tabs
settings_tab_basic: 'Basic',
settings_tab_models: 'Models',
// models tab
models_vendors: 'Provider Credentials',
models_vendors_sub: 'Configured once, shared by multiple model capabilities',
models_configured: 'configured',
models_no_vendor: 'No provider configured yet',
models_add_vendor: 'Add Provider',
models_custom_vendor: 'Custom',
models_add_custom: 'Add custom provider',
models_add_custom_hint: 'Endpoint must follow the OpenAI API protocol',
models_edit_custom: 'Edit custom provider',
models_custom_name: 'Name',
models_custom_base_hint: 'Endpoint must follow the OpenAI API protocol',
models_clear: 'Clear credentials',
models_delete: 'Delete',
models_clear_confirm: 'Clear the API key and base URL for this provider? Related capabilities will stop working.',
models_delete_confirm: 'Delete this custom provider? This cannot be undone.',
models_provider: 'Provider',
models_model: 'Model',
models_voice: 'Voice',
models_select_provider: 'Select',
models_select_model: 'Select a model',
models_select_voice: 'Select a voice',
models_no_options: 'No options',
models_auto: 'Auto',
models_asr_auto: 'Auto (follow main model)',
models_disabled: 'Disabled',
models_fallback: 'Fallback',
models_cap_chat: 'Main Model',
models_cap_chat_sub: 'Used for basic chat and agent reasoning',
models_cap_vision: 'Image Understanding',
models_cap_vision_sub: 'Recognizes image content, used by image recognition tools',
models_cap_image: 'Image Generation',
models_cap_image_sub: 'Generates images, used by image generation skills',
models_cap_asr: 'Speech Recognition',
models_cap_asr_sub: 'Voice to text',
models_cap_tts: 'Speech Synthesis',
models_cap_tts_sub: 'Text to voice',
models_cap_embedding: 'Embedding',
models_cap_embedding_sub: 'Used for vectorized retrieval of memory and knowledge',
models_cap_search: 'Web Search',
models_cap_search_sub: 'Real-time web retrieval, used by search tools',
models_tts_reply_mode: 'Voice Reply Mode',
models_tts_reply_mode_hint: 'When to reply with voice',
models_tts_mode_off: 'Off',
models_tts_mode_if_voice: 'Only when user sends voice',
models_tts_mode_always: 'Always reply with voice',
models_embedding_dim: 'Dimension',
models_embedding_rebuild_hint: 'Existing index becomes invalid and must be rebuilt after changing the model',
models_search_strategy: 'Strategy',
models_search_auto: 'Auto',
models_search_fixed: 'Pinned',
models_search_provider: 'Search provider',
models_search_bocha_key: 'Configure Bocha API Key',
models_search_bocha_hint: 'Create a key at the Bocha open platform',
config_max_tokens: 'Max Context Tokens',
config_max_turns: 'Max Memory Turns',
config_max_steps: 'Max Steps',
skills_title: 'Skills',
skills_desc: 'View, enable, or disable agent tools and skills',
skills_hub_btn: 'Skill Hub',
tools_section_title: 'Built-in Tools',
skills_section_title: 'Skills',
tools_loading: 'Loading tools...',
skills_loading: 'Loading skills...',
skills_loading_desc: 'Skills will be displayed here after loading',
skill_enabled: 'Enabled',
skill_disabled: 'Disabled',
tools_empty: 'No built-in tools',
skills_empty: 'No skills found',
memory_title: 'Memory',
memory_desc: 'View agent memory files and contents',
memory_tab_files: 'Memory Files',
memory_tab_dreams: 'Self-Evolution',
memory_loading: 'Loading memory files...',
memory_loading_desc: 'Memory files will be displayed here',
memory_col_name: 'Filename',
memory_col_type: 'Type',
memory_col_size: 'Size',
memory_col_updated: 'Updated',
memory_back: 'Back to list',
memory_empty_files: 'No memory files',
memory_empty_evolution: 'No evolution records yet',
memory_type_global: 'Global',
memory_type_daily: 'Daily',
memory_type_evolution: 'Evolution',
memory_type_dream: 'Dream',
memory_doc_load_error: 'Failed to load content',
memory_prev: 'Prev',
memory_next: 'Next',
channels_title: 'Channels',
channels_desc: 'View and manage messaging channels',
channels_add: 'Add channel',
channels_select_label: 'Select a channel to add',
channels_select_placeholder: 'Select a channel...',
channels_add_close: 'Close',
channels_connected: 'Connected',
channels_disconnected: 'Disconnected',
channels_connect: 'Connect',
channels_disconnect: 'Disconnect',
channels_save: 'Save',
channels_loading: 'Loading channels...',
channels_connected_section: 'Connected',
channels_available_section: 'Available',
channels_empty_connected: 'No connected channels yet',
channels_qr_hint: 'This channel uses QR login — please connect it from the Web console',
channels_save_ok: 'Saved',
channels_save_error: 'Failed to save',
channels_connect_error: 'Failed to connect',
channels_scan_login: 'QR login',
channels_scan_register: 'QR register',
weixin_scan_title: 'WeChat QR Login',
weixin_scan_desc: 'Scan the QR code below with WeChat to log in',
weixin_scan_loading: 'Fetching QR code...',
weixin_scan_waiting: 'Waiting for scan',
weixin_scan_scanned: 'Scanned, please confirm on your phone',
weixin_scan_success: 'Logged in',
weixin_scan_expired: 'QR code expired, refreshing...',
weixin_scan_fail: 'Failed to fetch QR code',
weixin_qr_tip: 'Scan with the WeChat account to log in',
feishu_scan_title: 'Feishu QR Register',
feishu_scan_desc: 'Scanning will create and connect a Feishu bot automatically',
feishu_scan_loading: 'Generating QR code...',
feishu_scan_waiting: 'Scan with Feishu to authorize',
feishu_scan_tip: 'Confirm the authorization in Feishu after scanning',
feishu_scan_open_link: 'Open authorization link',
feishu_scan_success: 'Registered',
feishu_scan_expired: 'QR code expired',
feishu_scan_denied: 'Authorization denied',
feishu_scan_fail: 'Registration failed',
feishu_scan_retry: 'Retry',
tasks_title: 'Scheduled Tasks',
tasks_desc: 'View and manage scheduled tasks',
tasks_active: 'Active',
tasks_paused: 'Paused',
tasks_empty: 'No scheduled tasks',
tasks_empty_guide: 'Tell the agent "remind me every day at 9am…" in chat to create a scheduled task',
tasks_go_chat: 'Create in chat',
tasks_next_run: 'Next run',
tasks_loading: 'Loading scheduled tasks...',
task_edit_title: 'Edit Task',
task_name: 'Name',
task_enabled: 'Enabled',
task_schedule_type: 'Schedule type',
task_type_cron: 'Cron',
task_type_interval: 'Interval',
task_type_once: 'Once',
task_cron_expr: 'Cron expression',
task_cron_hint: 'e.g. 0 9 * * * runs daily at 9am',
task_interval_seconds: 'Interval (seconds)',
task_once_time: 'Run at',
task_action_type: 'Action type',
task_action_send: 'Send message',
task_action_agent: 'Agent task',
task_message_content: 'Message content',
task_task_description: 'Task description',
task_channel: 'Channel',
task_receiver: 'Receiver',
task_channel_locked: 'Channel and receiver cannot be changed after creation',
task_save: 'Save',
task_cancel: 'Cancel',
task_delete: 'Delete',
task_delete_confirm: 'Delete this task? This cannot be undone.',
task_save_error: 'Failed to save',
logs_title: 'Logs',
logs_desc: 'Real-time log output (run.log)',
logs_live: 'Live',
logs_connecting: 'Log streaming will connect shortly...',
status_starting: 'Starting CowAgent...',
status_starting_desc: 'Initializing the client, please wait',
status_error: 'Initialization Failed',
status_error_desc: 'Failed to initialize the client, please retry',
status_retry: 'Retry',
// slash command descriptions
slash_menu_title: 'Commands',
slash_new: 'New chat',
slash_clear: 'Clear conversation context',
slash_help: 'Show command help',
slash_status: 'Show running status',
slash_context: 'Show conversation context',
slash_skill_list: 'List installed skills',
slash_skill_search: 'Search skills',
slash_skill_install: 'Install a skill (name or GitHub URL)',
slash_memory_dream: 'Trigger memory distillation (optional days, default 3)',
slash_knowledge: 'Show knowledge base stats',
slash_knowledge_list: 'Show knowledge base file tree',
slash_config: 'Show current config',
slash_cancel: 'Abort the running agent task',
slash_logs: 'Show recent logs',
slash_version: 'Show version',
},
}
export type Lang = 'zh' | 'en'
// First-run default: follow the OS language so zh-* systems start in Chinese
// and everyone else in English. Once the user picks a language it's persisted
// in cow_lang and always wins. Falls back to 'en' when the locale is unknown.
function detectDefaultLang(): Lang {
const locale = (window.electronAPI?.systemLocale || navigator.language || '').toLowerCase()
return locale.startsWith('zh') ? 'zh' : 'en'
}
const savedLang = localStorage.getItem('cow_lang') as Lang | null
let currentLang: Lang = savedLang === 'zh' || savedLang === 'en' ? savedLang : detectDefaultLang()
export function t(key: string): string {
return translations[currentLang]?.[key] || translations['en']?.[key] || key
}
export function getLang(): Lang {
return currentLang
}
export function setLang(lang: Lang) {
currentLang = lang
localStorage.setItem('cow_lang', lang)
}
/** Resolve a possibly-localized label ({zh,en} or plain string) for the current language. */
export function localizedLabel(label: string | { zh: string; en: string } | undefined): string {
if (!label) return ''
if (typeof label === 'string') return label
return label[currentLang] || label.en || label.zh || ''
}