| 1 | import { useCallback } from "react"; |
| 2 | import { useI18n, type DictKey } from "./i18n"; |
| 3 | |
| 4 | // Loaded with model settings, keeping setup-only copy out of the chat startup bundle. |
| 5 | const en = { |
| 6 | "providerUI.modelHelpLabel": "About {name}", |
| 7 | "providerUI.defaultModelHelp": "Used for new conversations. Existing conversations keep their saved model; change it in the conversation when needed.", |
| 8 | "providerUI.plannerModelHelp": "Follow conversation model: use the same model for planning and execution.\n\nChoose another model to handle planning separately; execution continues with the conversation model.", |
| 9 | "providerUI.visionModelHelp": "Provides image understanding when the conversation model cannot read images directly.\n\nAuto selects an image-capable model from the same connection. Select a model to use a specific connection, or None to disable this fallback. Native image support is unchanged.", |
| 10 | "providerUI.searchModelHelp": "Automatic: prefer the conversation account, otherwise choose an available account with search enabled.\n\nAssigned model: send queries through that connection and attribute search usage to it; do not switch accounts on failure.\n\nApplies when the runtime is recreated. Running tasks keep their existing configuration.", |
| 11 | "providerUI.subagentModelHelp": "Follow parent agent model: use the parent model when the task starts.\n\nSelect a model to set the default for subagent tasks. An explicit task or skill model takes precedence; the parent model stays unchanged.", |
| 12 | "providerUI.subagentEffortHelp": "Controls the default reasoning effort for subagent tasks. Auto uses the provider default; an explicit task setting takes precedence.\n\nHigher effort may increase latency and usage. Available levels depend on the selected model.", |
| 13 | |
| 14 | "providerUI.providers": "Providers", |
| 15 | "providerUI.builtin": "Built-in providers", |
| 16 | "providerUI.custom": "Custom providers", |
| 17 | "providerUI.chooseProvider": "Choose a provider", |
| 18 | "providerUI.searchProviders": "Search providers…", |
| 19 | "providerUI.presetHint": "Endpoint, protocol and models come from the selected preset.", |
| 20 | "providerUI.manualAdd": "Add manually", |
| 21 | "providerUI.addModel": "Add model", |
| 22 | "providerUI.editModel": "Edit model", |
| 23 | "providerUI.deleteModel": "Delete model", |
| 24 | "providerUI.modelID": "Model ID", |
| 25 | "providerUI.context": "Context window", |
| 26 | "providerUI.output": "Maximum output tokens", |
| 27 | "providerUI.auto": "Auto", |
| 28 | "providerUI.inherit": "Leave empty to inherit the model default.", |
| 29 | "providerUI.outputHint": "Leave empty to inherit; -1 omits optional output limits.", |
| 30 | "providerUI.text": "Text", |
| 31 | "providerUI.supported": "Supported", |
| 32 | "providerUI.unsupported": "Not supported", |
| 33 | "providerUI.capabilityHint": "Auto uses model metadata. Override only for capabilities your endpoint supports.", |
| 34 | "providerUI.saveDraft": "Save to draft", |
| 35 | "providerUI.applyModel": "Apply to form", |
| 36 | "providerUI.emptyModels": "No models yet. Discover models or add a model ID manually.", |
| 37 | "providerUI.discoveryHint": "Only selected new models are added. Existing models are kept.", |
| 38 | "providerUI.noDiscoveredModels": "No models returned. You can still add models manually.", |
| 39 | "providerUI.alreadyAdded": "Added", |
| 40 | "providerUI.selected": "{n} new models selected", |
| 41 | "providerUI.addSelected": "Add selected models", |
| 42 | "providerUI.validation.required": "Model ID is required.", |
| 43 | "providerUI.validation.syntax": "Model ID cannot contain spaces or commas.", |
| 44 | "providerUI.validation.duplicate": "This model ID is already added.", |
| 45 | "providerUI.validation.context": "Context must be a positive integer or empty.", |
| 46 | "providerUI.validation.output": "Output limit must be a positive integer, -1, or empty.", |
| 47 | "providerUI.test": "Test model", |
| 48 | "providerUI.testing": "Testing connection…", |
| 49 | "providerUI.testSuccess": "Connection successful · just now", |
| 50 | "providerUI.keySet": "Key configured · enter to replace", |
| 51 | "providerUI.saveFailed": "Could not save. Your draft is still available.", |
| 52 | "providerUI.baseURL": "Base URL", |
| 53 | "providerUI.finalURL": "Request URL:", |
| 54 | "providerUI.exactURL": "Override request URL", |
| 55 | "providerUI.exactURLHint": "Optional. Takes precedence over Base URL and keeps custom gateway paths intact.", |
| 56 | "providerUI.draftHint": "Changes stay in this form until you save.", |
| 57 | }; |
| 58 | const zh: Record<keyof typeof en, string> = { |
| 59 | "providerUI.modelHelpLabel": "{name}说明", |
| 60 | "providerUI.defaultModelHelp": "用于新建会话。已有会话继续使用各自保存的模型,需要时可在会话中切换。", |
| 61 | "providerUI.plannerModelHelp": "跟随会话模型:使用同一个模型进行规划与执行。\n\n指定其它模型后,由它独立负责规划,执行仍使用会话模型。", |
| 62 | "providerUI.visionModelHelp": "会话模型无法直接读取图片时,由图片理解模型提供辅助。\n\n自动:从当前连接中选择支持图片的模型。也可指定模型及连接;选择“无”关闭此辅助,不影响主模型原生图片能力。", |
| 63 | "providerUI.searchModelHelp": "自动:优先使用会话账号,否则选择已开启搜索的可用账号。\n\n指定模型:通过所选连接搜索,查询和用量归属该连接;失败不会改用其它账号。\n\n运行时重建后生效,进行中的任务继续使用原配置。", |
| 64 | "providerUI.subagentModelHelp": "跟随主代理模型:使用发起任务时主代理的模型。\n\n指定模型后,作为子代理任务的默认模型;任务或技能显式指定的模型优先,不改变主代理模型。", |
| 65 | "providerUI.subagentEffortHelp": "设置子代理任务的默认推理强度。auto 使用模型服务默认值;任务单独指定时优先使用任务设置。\n\n较高强度可能增加耗时和用量,可选级别取决于所选模型。", |
| 66 | |
| 67 | "providerUI.providers": "供应商", |
| 68 | "providerUI.builtin": "内置供应商", |
| 69 | "providerUI.custom": "自定义供应商", |
| 70 | "providerUI.chooseProvider": "选择供应商", |
| 71 | "providerUI.searchProviders": "搜索供应商…", |
| 72 | "providerUI.presetHint": "地址、协议和模型将使用所选供应商的预设。", |
| 73 | "providerUI.manualAdd": "手动添加", |
| 74 | "providerUI.addModel": "添加模型", |
| 75 | "providerUI.editModel": "编辑模型", |
| 76 | "providerUI.deleteModel": "删除模型", |
| 77 | "providerUI.modelID": "模型 ID", |
| 78 | "providerUI.context": "上下文窗口", |
| 79 | "providerUI.output": "最大输出 Token", |
| 80 | "providerUI.auto": "自动", |
| 81 | "providerUI.inherit": "留空沿用模型默认值。", |
| 82 | "providerUI.outputHint": "留空沿用默认值;-1 表示不发送可选输出限制。", |
| 83 | "providerUI.text": "文本", |
| 84 | "providerUI.supported": "支持", |
| 85 | "providerUI.unsupported": "不支持", |
| 86 | "providerUI.capabilityHint": "自动使用模型元数据;仅在端点确实支持时手动覆盖能力。", |
| 87 | "providerUI.saveDraft": "保存到草稿", |
| 88 | "providerUI.applyModel": "应用到表单", |
| 89 | "providerUI.emptyModels": "尚未添加模型。可获取模型列表或手动输入模型 ID。", |
| 90 | "providerUI.discoveryHint": "仅添加选中的新模型,保留已有模型。", |
| 91 | "providerUI.noDiscoveredModels": "未返回模型,仍可手动添加。", |
| 92 | "providerUI.alreadyAdded": "已添加", |
| 93 | "providerUI.selected": "已选择 {n} 个新模型", |
| 94 | "providerUI.addSelected": "添加所选模型", |
| 95 | "providerUI.validation.required": "模型 ID 不能为空。", |
| 96 | "providerUI.validation.syntax": "模型 ID 不能包含空格或逗号。", |
| 97 | "providerUI.validation.duplicate": "此模型 ID 已存在。", |
| 98 | "providerUI.validation.context": "上下文窗口必须为正整数,或留空使用默认值。", |
| 99 | "providerUI.validation.output": "输出限制必须为正整数、-1,或留空。", |
| 100 | "providerUI.test": "测试模型", |
| 101 | "providerUI.testing": "正在测试连接…", |
| 102 | "providerUI.testSuccess": "连接成功 · 刚刚", |
| 103 | "providerUI.keySet": "密钥已设置 · 输入以替换", |
| 104 | "providerUI.saveFailed": "保存失败,草稿已保留。", |
| 105 | "providerUI.baseURL": "Base URL", |
| 106 | "providerUI.finalURL": "最终请求地址:", |
| 107 | "providerUI.exactURL": "覆盖完整请求 URL", |
| 108 | "providerUI.exactURLHint": "可选,优先于 Base URL,保留自定义网关的完整路径。", |
| 109 | "providerUI.draftHint": "更改暂存于表单,点击保存后生效。", |
| 110 | }; |
| 111 | const zhTW: Record<keyof typeof en, string> = { |
| 112 | "providerUI.modelHelpLabel": "{name}說明", |
| 113 | "providerUI.defaultModelHelp": "用於新建對話。已有對話繼續使用各自儲存的模型,需要時可在對話中切換。", |
| 114 | "providerUI.plannerModelHelp": "跟隨對話模型:使用同一個模型進行規劃與執行。\n\n指定其他模型後,由它獨立負責規劃,執行仍使用對話模型。", |
| 115 | "providerUI.visionModelHelp": "對話模型無法直接讀取圖片時,由圖片理解模型提供輔助。\n\n自動:從目前連線選擇支援圖片的模型。也可指定模型及連線;選擇「無」關閉此輔助,不影響主模型原生圖片能力。", |
| 116 | "providerUI.searchModelHelp": "自動:優先使用對話帳號,否則選擇已開啟搜尋的可用帳號。\n\n指定模型:透過所選連線搜尋,查詢和用量歸屬該連線;失敗不會改用其他帳號。\n\n執行階段重建後生效,進行中的任務繼續使用原設定。", |
| 117 | "providerUI.subagentModelHelp": "跟隨主代理模型:使用發起任務時主代理的模型。\n\n指定模型後,作為子代理任務的預設模型;任務或技能明確指定的模型優先,不改變主代理模型。", |
| 118 | "providerUI.subagentEffortHelp": "設定子代理任務的預設推理強度。auto 使用模型服務預設值;任務單獨指定時優先使用任務設定。\n\n較高強度可能增加耗時和用量,可選級別取決於所選模型。", |
| 119 | |
| 120 | "providerUI.providers": "供應商", |
| 121 | "providerUI.builtin": "內建供應商", |
| 122 | "providerUI.custom": "自訂供應商", |
| 123 | "providerUI.chooseProvider": "選擇供應商", |
| 124 | "providerUI.searchProviders": "搜尋供應商…", |
| 125 | "providerUI.presetHint": "位址、協定和模型將使用所選供應商的預設。", |
| 126 | "providerUI.manualAdd": "手動新增", |
| 127 | "providerUI.addModel": "新增模型", |
| 128 | "providerUI.editModel": "編輯模型", |
| 129 | "providerUI.deleteModel": "刪除模型", |
| 130 | "providerUI.modelID": "模型 ID", |
| 131 | "providerUI.context": "上下文視窗", |
| 132 | "providerUI.output": "最大輸出 Token", |
| 133 | "providerUI.auto": "自動", |
| 134 | "providerUI.inherit": "留空沿用模型預設值。", |
| 135 | "providerUI.outputHint": "留空沿用預設值;-1 表示不傳送可選輸出限制。", |
| 136 | "providerUI.text": "文字", |
| 137 | "providerUI.supported": "支援", |
| 138 | "providerUI.unsupported": "不支援", |
| 139 | "providerUI.capabilityHint": "自動使用模型中繼資料;僅在端點確實支援時手動覆寫能力。", |
| 140 | "providerUI.saveDraft": "儲存至草稿", |
| 141 | "providerUI.applyModel": "套用至表單", |
| 142 | "providerUI.emptyModels": "尚未新增模型。可取得模型清單或手動輸入模型 ID。", |
| 143 | "providerUI.discoveryHint": "僅新增選取的新模型,保留既有模型。", |
| 144 | "providerUI.noDiscoveredModels": "未回傳模型,仍可手動新增。", |
| 145 | "providerUI.alreadyAdded": "已新增", |
| 146 | "providerUI.selected": "已選取 {n} 個新模型", |
| 147 | "providerUI.addSelected": "新增所選模型", |
| 148 | "providerUI.validation.required": "模型 ID 不可為空。", |
| 149 | "providerUI.validation.syntax": "模型 ID 不可包含空格或逗號。", |
| 150 | "providerUI.validation.duplicate": "此模型 ID 已存在。", |
| 151 | "providerUI.validation.context": "上下文視窗必須為正整數,或留空使用預設值。", |
| 152 | "providerUI.validation.output": "輸出限制必須為正整數、-1,或留空。", |
| 153 | "providerUI.test": "測試模型", |
| 154 | "providerUI.testing": "正在測試連線…", |
| 155 | "providerUI.testSuccess": "連線成功 · 剛剛", |
| 156 | "providerUI.keySet": "金鑰已設定 · 輸入以替換", |
| 157 | "providerUI.saveFailed": "儲存失敗,草稿已保留。", |
| 158 | "providerUI.baseURL": "Base URL", |
| 159 | "providerUI.finalURL": "最終請求位址:", |
| 160 | "providerUI.exactURL": "覆寫完整請求 URL", |
| 161 | "providerUI.exactURLHint": "可選,優先於 Base URL,保留自訂閘道的完整路徑。", |
| 162 | "providerUI.draftHint": "變更暫存於表單,按下儲存後生效。", |
| 163 | }; |
| 164 | |
| 165 | export function useProviderT() { |
| 166 | const { locale, t } = useI18n(); |
| 167 | return useCallback((key: DictKey | keyof typeof en, vars?: Record<string, string | number>): string => { |
| 168 | if (!(key in en)) return t(key as DictKey, vars); |
| 169 | const dict = locale === "zh" ? zh : locale === "zh-TW" ? zhTW : en; |
| 170 | const value = dict[key as keyof typeof en]; |
| 171 | return vars ? value.replace(/\{(\w+)\}/g, (_, k) => vars[k] === undefined ? `{${k}}` : String(vars[k])) : value; |
| 172 | }, [locale, t]); |
| 173 | } |
| 174 |