mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-17 11:07:11 +08:00
756 lines
34 KiB
TypeScript
756 lines
34 KiB
TypeScript
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 和 TXT,TXT 会转成 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 || ''
|
||
}
|