@jingyi0605/codingns4dsh 0.2.1-beta.11 → 0.2.1-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.en.md +7 -5
  2. package/README.md +9 -5
  3. package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts +1 -1
  4. package/data/build/dist/bootstrap/index.d.ts +1 -1
  5. package/data/build/dist/client/bundle.js +2280 -1495
  6. package/data/build/dist/client/bundle.js.map +1 -1
  7. package/data/build/dist/client/cli-slots.d.ts +3 -2
  8. package/data/build/dist/client/cli-slots.d.ts.map +1 -1
  9. package/data/build/dist/client/cli-slots.js +29 -5
  10. package/data/build/dist/client/cli-slots.js.map +1 -1
  11. package/data/build/dist/client/client.assistant-configuration-view.js +5 -5
  12. package/data/build/dist/client/client.assistant-configuration-view.js.map +1 -1
  13. package/data/build/dist/client/client.moss-voice-output.js +0 -166
  14. package/data/build/dist/client/client.moss-voice-output.js.map +1 -1
  15. package/data/build/dist/client/client.native-workspace-store.js +4 -4
  16. package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
  17. package/data/build/dist/client/client.react-dom.js +166 -0
  18. package/data/build/dist/client/client.react-dom.js.map +1 -1
  19. package/data/build/dist/client/client.session-translation.js +9 -1
  20. package/data/build/dist/client/client.session-translation.js.map +1 -1
  21. package/data/build/dist/client/client.transport.js +46 -0
  22. package/data/build/dist/client/client.transport.js.map +1 -1
  23. package/data/build/dist/client/conversation-translation-settings.d.ts +10 -0
  24. package/data/build/dist/client/conversation-translation-settings.d.ts.map +1 -0
  25. package/data/build/dist/client/conversation-translation-settings.js +52 -0
  26. package/data/build/dist/client/conversation-translation-settings.js.map +1 -0
  27. package/data/build/dist/client/desktop-assistant.js +512 -439
  28. package/data/build/dist/client/features/cli-adapters.js +1 -1
  29. package/data/build/dist/client/features/cli-adapters.js.map +1 -1
  30. package/data/build/dist/client/features/session-translation.d.ts.map +1 -1
  31. package/data/build/dist/client/features/session-translation.js +7 -1
  32. package/data/build/dist/client/features/session-translation.js.map +1 -1
  33. package/data/build/dist/client/locales/panels.d.ts.map +1 -1
  34. package/data/build/dist/client/locales/panels.js +46 -0
  35. package/data/build/dist/client/locales/panels.js.map +1 -1
  36. package/data/build/dist/client/session-translation-chat.d.ts +9 -3
  37. package/data/build/dist/client/session-translation-chat.d.ts.map +1 -1
  38. package/data/build/dist/client/session-translation-chat.js +146 -48
  39. package/data/build/dist/client/session-translation-chat.js.map +1 -1
  40. package/data/build/dist/client/session-translation-pending-dom.d.ts +1 -1
  41. package/data/build/dist/client/session-translation-pending-dom.d.ts.map +1 -1
  42. package/data/build/dist/client/session-translation-pending-dom.js +4 -4
  43. package/data/build/dist/client/session-translation-pending-dom.js.map +1 -1
  44. package/data/build/dist/client/session-translation-retry.d.ts +16 -0
  45. package/data/build/dist/client/session-translation-retry.d.ts.map +1 -0
  46. package/data/build/dist/client/session-translation-retry.js +66 -0
  47. package/data/build/dist/client/session-translation-retry.js.map +1 -0
  48. package/data/build/dist/client/session-translation-rules.d.ts +13 -0
  49. package/data/build/dist/client/session-translation-rules.d.ts.map +1 -0
  50. package/data/build/dist/client/session-translation-rules.js +58 -0
  51. package/data/build/dist/client/session-translation-rules.js.map +1 -0
  52. package/data/build/dist/client/style.css +276 -276
  53. package/data/build/dist/dsh-capabilities/client/interaction-presentation-adapter.d.ts.map +1 -1
  54. package/data/build/dist/dsh-capabilities/client/interaction-presentation-adapter.js +4 -13
  55. package/data/build/dist/dsh-capabilities/client/interaction-presentation-adapter.js.map +1 -1
  56. package/data/build/dist/dsh-capabilities/client/interaction-text-dom.js +1 -1
  57. package/data/build/dist/dsh-capabilities/client/interaction-text-dom.js.map +1 -1
  58. package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.d.ts +19 -0
  59. package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.d.ts.map +1 -0
  60. package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.js +39 -0
  61. package/data/build/dist/dsh-capabilities/client/message-presentation-adapter.js.map +1 -0
  62. package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.d.ts +2 -0
  63. package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.d.ts.map +1 -1
  64. package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.js +28 -0
  65. package/data/build/dist/dsh-capabilities/client/slot-presentation-mirror.js.map +1 -1
  66. package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.d.ts +10 -0
  67. package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.d.ts.map +1 -0
  68. package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.js +34 -0
  69. package/data/build/dist/dsh-capabilities/host/connection-peer-adapter.js.map +1 -0
  70. package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.d.ts +21 -0
  71. package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.d.ts.map +1 -0
  72. package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.js +11 -0
  73. package/data/build/dist/dsh-capabilities/host/native-dispatch-adapter.js.map +1 -0
  74. package/data/build/dist/dsh-capabilities/host/session-activation-adapter.d.ts +17 -0
  75. package/data/build/dist/dsh-capabilities/host/session-activation-adapter.d.ts.map +1 -0
  76. package/data/build/dist/dsh-capabilities/host/session-activation-adapter.js +37 -0
  77. package/data/build/dist/dsh-capabilities/host/session-activation-adapter.js.map +1 -0
  78. package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.d.ts +17 -0
  79. package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.d.ts.map +1 -0
  80. package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.js +45 -0
  81. package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.js.map +1 -0
  82. package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.d.ts +28 -0
  83. package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.d.ts.map +1 -0
  84. package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.js +31 -0
  85. package/data/build/dist/dsh-capabilities/host/session-prompt-adapter.js.map +1 -0
  86. package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
  87. package/data/build/dist/dsh-capabilities/matrix.js +12 -4
  88. package/data/build/dist/dsh-capabilities/matrix.js.map +1 -1
  89. package/data/build/dist/dsh-capabilities/routes.d.ts.map +1 -1
  90. package/data/build/dist/dsh-capabilities/routes.js +25 -5
  91. package/data/build/dist/dsh-capabilities/routes.js.map +1 -1
  92. package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
  93. package/data/build/dist/dsh-capabilities/types.d.ts.map +1 -1
  94. package/data/build/dist/dsh-capabilities/types.js.map +1 -1
  95. package/data/build/dist/host/cli-adapters/antigravity-driver.js +1 -1
  96. package/data/build/dist/host/cli-adapters/antigravity-driver.js.map +1 -1
  97. package/data/build/dist/host/cli-adapters/attachment-utils.d.ts +4 -3
  98. package/data/build/dist/host/cli-adapters/attachment-utils.d.ts.map +1 -1
  99. package/data/build/dist/host/cli-adapters/attachment-utils.js +9 -8
  100. package/data/build/dist/host/cli-adapters/attachment-utils.js.map +1 -1
  101. package/data/build/dist/host/cli-adapters/claude-driver.js +1 -1
  102. package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
  103. package/data/build/dist/host/cli-adapters/command-code-driver.js +1 -1
  104. package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
  105. package/data/build/dist/host/cli-adapters/driver.d.ts +2 -0
  106. package/data/build/dist/host/cli-adapters/driver.d.ts.map +1 -1
  107. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +2 -0
  108. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
  109. package/data/build/dist/host/cli-adapters/dsh-message-projector.js +11 -3
  110. package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
  111. package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
  112. package/data/build/dist/host/cli-adapters/feature.js +154 -68
  113. package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
  114. package/data/build/dist/host/cli-adapters/gemini-driver.js +1 -1
  115. package/data/build/dist/host/cli-adapters/gemini-driver.js.map +1 -1
  116. package/data/build/dist/host/cli-adapters/grok-driver.d.ts +1 -0
  117. package/data/build/dist/host/cli-adapters/grok-driver.d.ts.map +1 -1
  118. package/data/build/dist/host/cli-adapters/grok-driver.js +128 -40
  119. package/data/build/dist/host/cli-adapters/grok-driver.js.map +1 -1
  120. package/data/build/dist/host/cli-adapters/kimi-driver.js +2 -2
  121. package/data/build/dist/host/cli-adapters/kimi-driver.js.map +1 -1
  122. package/data/build/dist/host/cli-adapters/mcode-driver.js +1 -1
  123. package/data/build/dist/host/cli-adapters/mcode-driver.js.map +1 -1
  124. package/data/build/dist/host/cli-adapters/native-team-subagent.d.ts.map +1 -1
  125. package/data/build/dist/host/cli-adapters/native-team-subagent.js +2 -1
  126. package/data/build/dist/host/cli-adapters/native-team-subagent.js.map +1 -1
  127. package/data/build/dist/host/cli-adapters/pi-driver.js +1 -1
  128. package/data/build/dist/host/cli-adapters/pi-driver.js.map +1 -1
  129. package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
  130. package/data/build/dist/host/cli-adapters/registry.js +23 -16
  131. package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
  132. package/data/build/dist/host/cli-adapters/zcode-driver.js +1 -1
  133. package/data/build/dist/host/cli-adapters/zcode-driver.js.map +1 -1
  134. package/data/build/dist/host/features/global-voice-rpc.d.ts.map +1 -1
  135. package/data/build/dist/host/features/global-voice-rpc.js +2 -3
  136. package/data/build/dist/host/features/global-voice-rpc.js.map +1 -1
  137. package/data/build/dist/host/features/peer-host.js +6 -6
  138. package/data/build/dist/host/features/peer-host.js.map +1 -1
  139. package/data/build/dist/host/features/session-prompt-translation.d.ts +10 -0
  140. package/data/build/dist/host/features/session-prompt-translation.d.ts.map +1 -0
  141. package/data/build/dist/host/features/session-prompt-translation.js +197 -0
  142. package/data/build/dist/host/features/session-prompt-translation.js.map +1 -0
  143. package/data/build/dist/host/features/session-translation-protection.d.ts +6 -1
  144. package/data/build/dist/host/features/session-translation-protection.d.ts.map +1 -1
  145. package/data/build/dist/host/features/session-translation-protection.js +23 -5
  146. package/data/build/dist/host/features/session-translation-protection.js.map +1 -1
  147. package/data/build/dist/host/features/session-translation-recovery.d.ts +20 -0
  148. package/data/build/dist/host/features/session-translation-recovery.d.ts.map +1 -0
  149. package/data/build/dist/host/features/session-translation-recovery.js +122 -0
  150. package/data/build/dist/host/features/session-translation-recovery.js.map +1 -0
  151. package/data/build/dist/host/features/session-translation-service.d.ts +5 -2
  152. package/data/build/dist/host/features/session-translation-service.d.ts.map +1 -1
  153. package/data/build/dist/host/features/session-translation-service.js +60 -16
  154. package/data/build/dist/host/features/session-translation-service.js.map +1 -1
  155. package/data/build/dist/host/features/session-translation.d.ts.map +1 -1
  156. package/data/build/dist/host/features/session-translation.js +4 -1
  157. package/data/build/dist/host/features/session-translation.js.map +1 -1
  158. package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.d.ts +2 -2
  159. package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.d.ts.map +1 -1
  160. package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js +10 -9
  161. package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js.map +1 -1
  162. package/data/build/dist/host/modules/peer-host/peer-host-native-streams.d.ts +3 -3
  163. package/data/build/dist/host/modules/peer-host/peer-host-native-streams.d.ts.map +1 -1
  164. package/data/build/dist/host/modules/peer-host/peer-host-native-streams.js +26 -14
  165. package/data/build/dist/host/modules/peer-host/peer-host-native-streams.js.map +1 -1
  166. package/data/build/dist/host/native-session-bridge.d.ts +2 -1
  167. package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
  168. package/data/build/dist/host/native-session-bridge.js +5 -13
  169. package/data/build/dist/host/native-session-bridge.js.map +1 -1
  170. package/data/build/dist/host/rpc.d.ts.map +1 -1
  171. package/data/build/dist/host/rpc.js +14 -8
  172. package/data/build/dist/host/rpc.js.map +1 -1
  173. package/data/build/dist/host/settings.d.ts.map +1 -1
  174. package/data/build/dist/host/settings.js +5 -1
  175. package/data/build/dist/host/settings.js.map +1 -1
  176. package/data/build/dist/shared/attachment-prompts.d.ts +11 -0
  177. package/data/build/dist/shared/attachment-prompts.d.ts.map +1 -0
  178. package/data/build/dist/shared/attachment-prompts.js +17 -0
  179. package/data/build/dist/shared/attachment-prompts.js.map +1 -0
  180. package/data/build/dist/shared/contracts/cli-adapter.d.ts +8 -1
  181. package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
  182. package/data/build/dist/shared/contracts/errors.d.ts +2 -2
  183. package/data/build/dist/shared/contracts/session-translation.d.ts +13 -0
  184. package/data/build/dist/shared/contracts/session-translation.d.ts.map +1 -1
  185. package/data/build/dist/shared/contracts/session-translation.js +10 -0
  186. package/data/build/dist/shared/contracts/session-translation.js.map +1 -1
  187. package/data/build/dist/shared/contracts/version.d.ts +4 -4
  188. package/data/build/dist/shared/contracts/version.js +3 -3
  189. package/package.json +35 -34
  190. package/profile/README.md +2 -2
  191. package/profile/package.json +3 -3
  192. package/profile/version.json +3 -3
  193. package/version.json +3 -3
@@ -33,6 +33,9 @@ window.__ModuleLoader__.load({
33
33
  "zh"
34
34
  ];
35
35
  const DEFAULT_SESSION_TRANSLATION_SETTINGS = {
36
+ inputEnabled: true,
37
+ reasoningEnabled: true,
38
+ assistantEnabled: true,
36
39
  inputLanguage: "en",
37
40
  outputLanguage: "zh",
38
41
  bilingual: false,
@@ -67,13 +70,18 @@ window.__ModuleLoader__.load({
67
70
  if (value === void 0) return fallback;
68
71
  const translationModel = normalizeTranslationModel(value.translationModel);
69
72
  const translationModels = Array.isArray(value.translationModels) ? normalizeTranslationModels(value.translationModels) : void 0;
73
+ const translationRules = Array.isArray(value.translationRules) ? value.translationRules.filter((rule) => typeof rule === "string").map((rule) => rule.trim()).filter((rule) => rule !== "") : void 0;
70
74
  return {
75
+ inputEnabled: value.inputEnabled !== false,
76
+ reasoningEnabled: value.reasoningEnabled !== false,
77
+ assistantEnabled: value.assistantEnabled !== false,
71
78
  inputLanguage: isSessionTranslationLanguage(value.inputLanguage) ? value.inputLanguage : fallback.inputLanguage,
72
79
  outputLanguage: isSessionTranslationLanguage(value.outputLanguage) ? value.outputLanguage : fallback.outputLanguage,
73
80
  bilingual: value.bilingual === true,
74
81
  nativeEnabled: value.nativeEnabled === true,
75
82
  ...translationModel === void 0 ? {} : { translationModel },
76
- ...translationModels === void 0 ? {} : { translationModels }
83
+ ...translationModels === void 0 ? {} : { translationModels },
84
+ ...translationRules === void 0 ? {} : { translationRules }
77
85
  };
78
86
  }
79
87
  function normalizeTranslationModels(values) {
@@ -1 +1 @@
1
- {"version":3,"file":"client.session-translation.js","names":[],"sources":["../../../../src/shared/contracts/session-translation.ts"],"sourcesContent":["/** 会话翻译中间件支持的语言。 */\nexport type SessionTranslationLanguage = 'en' | 'fr' | 'de' | 'ja' | 'zh'\n\n/** 输出内容类别;工具调用、命令和路径不属于可翻译内容。 */\nexport type SessionTranslationOutputKind = 'reasoning' | 'assistant'\n\n/** 翻译请求使用的 DSH 原生模型;不保存密钥,只保存 provider/model 标识。 */\nexport interface SessionTranslationModel {\n readonly provider: string\n readonly model: string\n}\n\n/** 会话翻译中间件的持久化设置。 */\nexport interface SessionTranslationSettings {\n /** 用户输入送入 Agent 的目的语言。 */\n readonly inputLanguage: SessionTranslationLanguage\n /** 输出翻译语言;默认中文。 */\n readonly outputLanguage: SessionTranslationLanguage\n /** 是否在 UI 和历史回看中同时保留原文与译文。 */\n readonly bilingual: boolean\n /** 翻译模型;缺省时跟随 DSH 当前默认模型。 */\n readonly translationModel?: SessionTranslationModel\n /** Models in priority order. An empty pool follows the DSH default; absent pools use the legacy selection. */\n readonly translationModels?: readonly SessionTranslationModel[]\n /**\n * DSH 原生会话是否参与翻译;缺省关闭。\n *\n * 原生会话的回复由 DSH 自己写入 `assistant/message`,开启输出翻译后正文会变成\n * 译文、原文只留在块元数据里,因此不能默认改变既有行为。\n */\n readonly nativeEnabled?: boolean\n}\n\nexport const SESSION_TRANSLATION_ADAPTER_IDS = [\n 'command-code', 'claude-code', 'kimi', 'gemini', 'pi', 'codex', 'opencode', 'grok',\n 'mcode', 'zcode', 'codebuddy', 'workbuddy', 'cursor-cli', 'kiro-cli', 'qoder', 'qoder-cn',\n 'antigravity', 'doubao',\n] as const\n\n/** DSH 内置 Agent 的适配器标识;它没有外部驱动,但同样支持会话翻译。 */\nexport const DSH_NATIVE_SESSION_ADAPTER_ID = 'dsh' as const\n\nexport const SESSION_TRANSLATION_LANGUAGES = ['en', 'fr', 'de', 'ja', 'zh'] as const\n\nexport const DEFAULT_SESSION_TRANSLATION_SETTINGS: SessionTranslationSettings = {\n inputLanguage: 'en',\n outputLanguage: 'zh',\n bilingual: false,\n nativeEnabled: false,\n}\n\n/**\n * 外部 Agent 适配器判定。\n *\n * 只表示「会话由插件的外部 CLI 驱动接管」,因此 DSH 原生 Agent 不在其中:该判定\n * 还被用来把外部 Agent 的虚拟 Provider 排除在翻译模型目录之外,混入 `dsh` 会污染\n * 这一语义。会话是否可翻译统一使用 {@link supportsSessionTranslation}。\n */\nexport function isSessionTranslationAdapter(adapterId: string): boolean {\n return (SESSION_TRANSLATION_ADAPTER_IDS as readonly string[]).includes(adapterId)\n}\n\n/** 外部 Agent 与 DSH 原生 Agent 都支持会话翻译。 */\nexport function supportsSessionTranslation(adapterId: string): boolean {\n return adapterId === DSH_NATIVE_SESSION_ADAPTER_ID || isSessionTranslationAdapter(adapterId)\n}\n\n/** 判断任意字符串是否为受支持的翻译语言。 */\nexport function isSessionTranslationLanguage(value: unknown): value is SessionTranslationLanguage {\n return typeof value === 'string' && (SESSION_TRANSLATION_LANGUAGES as readonly string[]).includes(value)\n}\n\n/**\n * 归一化翻译设置:旧设置快照可能缺少 `nativeEnabled`,非法语言回落到默认值。\n *\n * 与 `session-translation-service.ts` 的内部归一化保持同一语义,供客户端设置页在\n * 写入前补齐字段,避免旧快照把新字段写丢。\n */\nexport function normalizeSessionTranslationSettings(value: SessionTranslationSettings | undefined): SessionTranslationSettings {\n const fallback = DEFAULT_SESSION_TRANSLATION_SETTINGS\n if (value === undefined) return fallback\n const translationModel = normalizeTranslationModel(value.translationModel)\n const translationModels = Array.isArray(value.translationModels) ? normalizeTranslationModels(value.translationModels) : undefined\n return {\n inputLanguage: isSessionTranslationLanguage(value.inputLanguage) ? value.inputLanguage : fallback.inputLanguage,\n outputLanguage: isSessionTranslationLanguage(value.outputLanguage) ? value.outputLanguage : fallback.outputLanguage,\n bilingual: value.bilingual === true,\n nativeEnabled: value.nativeEnabled === true,\n ...(translationModel === undefined ? {} : { translationModel }),\n ...(translationModels === undefined ? {} : { translationModels }),\n }\n}\n\nfunction normalizeTranslationModels(values: readonly SessionTranslationModel[]): readonly SessionTranslationModel[] {\n const models: SessionTranslationModel[] = []\n const seen = new Set<string>()\n for (const value of values) {\n const model = normalizeTranslationModel(value)\n if (model === undefined) continue\n const key = JSON.stringify([model.provider, model.model])\n if (seen.has(key)) continue\n seen.add(key)\n models.push(model)\n }\n return models\n}\n\nfunction normalizeTranslationModel(value: SessionTranslationModel | undefined): SessionTranslationModel | undefined {\n if (value === undefined || value === null || typeof value.provider !== 'string' || typeof value.model !== 'string') return undefined\n const provider = value.provider.trim()\n const model = value.model.trim()\n return provider === '' || model === '' ? undefined : { provider, model }\n}\n\nexport interface SessionTranslationFailure {\n readonly code: 'timeout' | 'cancelled' | 'rate-limit' | 'network' | 'unavailable' | 'invalid-response' | 'configuration' | 'provider'\n readonly retryable: boolean\n}\n\nexport interface SessionTranslationMetrics {\n /** Elapsed translation time, including model selection and fallback attempts. */\n readonly durationMs?: number\n /** Reported token consumption across model attempts, including cached input. */\n readonly totalTokens?: number\n}\n\n/** Preserve available metrics while accepting records saved before metrics existed. */\nexport function readSessionTranslationMetrics(value: unknown): SessionTranslationMetrics {\n const record = asRecord(value)\n const durationMs = record?.durationMs\n const totalTokens = record?.totalTokens\n return {\n ...(typeof durationMs === 'number' && Number.isFinite(durationMs) && durationMs >= 0 ? { durationMs } : {}),\n ...(typeof totalTokens === 'number' && Number.isSafeInteger(totalTokens) && totalTokens >= 0 ? { totalTokens } : {}),\n }\n}\n\nexport interface SessionTranslationRecord extends SessionTranslationMetrics {\n readonly original: string\n readonly translated: string\n readonly sourceLanguage?: SessionTranslationLanguage\n readonly targetLanguage: SessionTranslationLanguage\n /** 回复文本所在的 DSH 内容块类型,供界面将原文入口放回对应内容块。 */\n readonly outputKind?: SessionTranslationOutputKind\n readonly bilingual: boolean\n /** 源语言与目标语言一致,因此未调用翻译模型。 */\n readonly alreadyTargetLanguage?: boolean\n /** 实际执行本次翻译的 DSH 原生模型;旧历史可能没有该字段。 */\n readonly model?: SessionTranslationModel\n /** 本次尝试失败并回退原文;前端显示警告状态。 */\n readonly failed?: boolean\n /** Structured failure details; absent in older translation records. */\n readonly failure?: SessionTranslationFailure\n}\n\n/** 用户输入的原文、实际送出的译文和翻译模型,作为 DSH 历史元数据保存。 */\nexport interface SessionTranslationInputRecord extends SessionTranslationMetrics {\n readonly original: string\n /** 包含附件提示等不翻译内容的最终 Provider prompt。 */\n readonly translated: string\n readonly sourceLanguage?: SessionTranslationLanguage\n readonly targetLanguage: SessionTranslationLanguage\n /** 源语言与目标语言一致,因此未调用翻译模型。 */\n readonly alreadyTargetLanguage?: boolean\n /** 实际执行本次翻译的 DSH 原生模型;旧历史可能没有该字段。 */\n readonly model?: SessionTranslationModel\n /** 翻译失败并回退原文;前端显示警告状态。 */\n readonly failed?: boolean\n}\n\n/**\n * 从 DSH 原生用户消息的 source 元数据读取输入翻译记录。\n *\n * 该字段由 `agent/pre-step` 写入并随 `user/message` 持久化;未知或不完整的历史\n * 结构一律返回 undefined,调用方按「没有翻译」处理。\n */\nexport function readNativeTranslationRecord(source: unknown): SessionTranslationInputRecord | undefined {\n const record = asRecord(source)\n const candidate = asRecord(record?.codingnsTranslationInput)\n if (candidate === null) return undefined\n if (typeof candidate.original !== 'string' || typeof candidate.translated !== 'string') return undefined\n if (candidate.original.trim() === '' || candidate.translated.trim() === '') return undefined\n const targetLanguage = isSessionTranslationLanguage(candidate.targetLanguage) ? candidate.targetLanguage : undefined\n if (targetLanguage === undefined) return undefined\n const model = normalizeTranslationModel(asRecord(candidate.model) as SessionTranslationModel | undefined)\n const sourceLanguage = isSessionTranslationLanguage(candidate.sourceLanguage) ? candidate.sourceLanguage : undefined\n return {\n original: candidate.original,\n translated: candidate.translated,\n targetLanguage,\n ...(sourceLanguage === undefined ? {} : { sourceLanguage }),\n ...(candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {}),\n ...(candidate.failed === true ? { failed: true } : {}),\n ...(model === undefined ? {} : { model }),\n ...readSessionTranslationMetrics(candidate),\n }\n}\n\n/** 输入记录转换为详情弹层使用的通用记录;`outputKind` 缺省表示输入方向。 */\nexport function toSessionTranslationRecord(\n record: SessionTranslationInputRecord,\n options: { readonly outputKind?: SessionTranslationOutputKind; readonly bilingual?: boolean } = {},\n): SessionTranslationRecord {\n return {\n original: record.original,\n translated: record.translated,\n targetLanguage: record.targetLanguage,\n bilingual: options.bilingual === true,\n ...(options.outputKind === undefined ? {} : { outputKind: options.outputKind }),\n ...(record.sourceLanguage === undefined ? {} : { sourceLanguage: record.sourceLanguage }),\n ...(record.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {}),\n ...(record.failed === true ? { failed: true } : {}),\n ...(record.model === undefined ? {} : { model: record.model }),\n ...readSessionTranslationMetrics(record),\n }\n}\n\nfunction asRecord(value: unknown): Record<string, any> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value) ? value as Record<string, any> : null\n}\n\n/** 外部 Agent 的历史上下文使用实际发送的译文;DSH 用户消息正文保留用户原文。 */\nexport function formatSessionTranslationInput(record: SessionTranslationInputRecord): string {\n return record.translated\n}\n\n/** Return the output translation; native DSH history keeps the original and the client reads this record. */\nexport function formatSessionTranslationOutput(record: SessionTranslationRecord): string {\n return record.translated\n}\n"],"mappings":";;;;;;;EAiCA,MAAa,kCAAkC;GAC7C;GAAgB;GAAe;GAAQ;GAAU;GAAM;GAAS;GAAY;GAC5E;GAAS;GAAS;GAAa;GAAa;GAAc;GAAY;GAAS;GAC/E;GAAe;EACjB;EAKA,MAAa,gCAAgC;GAAC;GAAM;GAAM;GAAM;GAAM;EAAI;EAE1E,MAAa,uCAAmE;GAC9E,eAAe;GACf,gBAAgB;GAChB,WAAW;GACX,eAAe;EACjB;;;;;;;;EASA,SAAgB,4BAA4B,WAA4B;GACtE,OAAQ,gCAAsD,SAAS,SAAS;EAClF;;EAGA,SAAgB,2BAA2B,WAA4B;GACrE,OAAO,cAAA,SAA+C,4BAA4B,SAAS;EAC7F;;EAGA,SAAgB,6BAA6B,OAAqD;GAChG,OAAO,OAAO,UAAU,YAAa,8BAAoD,SAAS,KAAK;EACzG;;;;;;;EAQA,SAAgB,oCAAoC,OAA2E;GAC7H,MAAM,WAAW;GACjB,IAAI,UAAU,KAAA,GAAW,OAAO;GAChC,MAAM,mBAAmB,0BAA0B,MAAM,gBAAgB;GACzE,MAAM,oBAAoB,MAAM,QAAQ,MAAM,iBAAiB,IAAI,2BAA2B,MAAM,iBAAiB,IAAI,KAAA;GACzH,OAAO;IACL,eAAe,6BAA6B,MAAM,aAAa,IAAI,MAAM,gBAAgB,SAAS;IAClG,gBAAgB,6BAA6B,MAAM,cAAc,IAAI,MAAM,iBAAiB,SAAS;IACrG,WAAW,MAAM,cAAc;IAC/B,eAAe,MAAM,kBAAkB;IACvC,GAAI,qBAAqB,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB;IAC7D,GAAI,sBAAsB,KAAA,IAAY,CAAC,IAAI,EAAE,kBAAkB;GACjE;EACF;EAEA,SAAS,2BAA2B,QAAgF;GAClH,MAAM,SAAoC,CAAC;GAC3C,MAAM,uBAAO,IAAI,IAAY;GAC7B,KAAK,MAAM,SAAS,QAAQ;IAC1B,MAAM,QAAQ,0BAA0B,KAAK;IAC7C,IAAI,UAAU,KAAA,GAAW;IACzB,MAAM,MAAM,KAAK,UAAU,CAAC,MAAM,UAAU,MAAM,KAAK,CAAC;IACxD,IAAI,KAAK,IAAI,GAAG,GAAG;IACnB,KAAK,IAAI,GAAG;IACZ,OAAO,KAAK,KAAK;GACnB;GACA,OAAO;EACT;EAEA,SAAS,0BAA0B,OAAiF;GAClH,IAAI,UAAU,KAAA,KAAa,UAAU,QAAQ,OAAO,MAAM,aAAa,YAAY,OAAO,MAAM,UAAU,UAAU,OAAO,KAAA;GAC3H,MAAM,WAAW,MAAM,SAAS,KAAK;GACrC,MAAM,QAAQ,MAAM,MAAM,KAAK;GAC/B,OAAO,aAAa,MAAM,UAAU,KAAK,KAAA,IAAY;IAAE;IAAU;GAAM;EACzE;;EAeA,SAAgB,8BAA8B,OAA2C;GACvF,MAAM,SAAS,SAAS,KAAK;GAC7B,MAAM,aAAa,QAAQ;GAC3B,MAAM,cAAc,QAAQ;GAC5B,OAAO;IACL,GAAI,OAAO,eAAe,YAAY,OAAO,SAAS,UAAU,KAAK,cAAc,IAAI,EAAE,WAAW,IAAI,CAAC;IACzG,GAAI,OAAO,gBAAgB,YAAY,OAAO,cAAc,WAAW,KAAK,eAAe,IAAI,EAAE,YAAY,IAAI,CAAC;GACpH;EACF;EAkFA,SAAS,SAAS,OAA4C;GAC5D,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,IAAI,QAA+B;EAC/G"}
1
+ {"version":3,"file":"client.session-translation.js","names":[],"sources":["../../../../src/shared/contracts/session-translation.ts"],"sourcesContent":["/** 会话翻译中间件支持的语言。 */\nexport type SessionTranslationLanguage = 'en' | 'fr' | 'de' | 'ja' | 'zh'\n\n/** 输出内容类别;工具调用、命令和路径不属于可翻译内容。 */\nexport type SessionTranslationOutputKind = 'reasoning' | 'assistant'\n\n/** 翻译请求使用的 DSH 原生模型;不保存密钥,只保存 provider/model 标识。 */\nexport interface SessionTranslationModel {\n readonly provider: string\n readonly model: string\n}\n\n/** 会话翻译中间件的持久化设置。 */\nexport interface SessionTranslationSettings {\n /** Message categories are enabled unless explicitly disabled in older or current settings. */\n readonly inputEnabled?: boolean\n readonly reasoningEnabled?: boolean\n readonly assistantEnabled?: boolean\n /** 用户输入送入 Agent 的目的语言。 */\n readonly inputLanguage: SessionTranslationLanguage\n /** 输出翻译语言;默认中文。 */\n readonly outputLanguage: SessionTranslationLanguage\n /** 是否在 UI 和历史回看中同时保留原文与译文。 */\n readonly bilingual: boolean\n /** 翻译模型;缺省时跟随 DSH 当前默认模型。 */\n readonly translationModel?: SessionTranslationModel\n /** Models in priority order. An empty pool follows the DSH default; absent pools use the legacy selection. */\n readonly translationModels?: readonly SessionTranslationModel[]\n /** Custom prompt instructions that take precedence over the default translation prompts. */\n readonly translationRules?: readonly string[]\n /**\n * DSH 原生会话是否参与翻译;缺省关闭。\n *\n * 原生会话的回复由 DSH 自己写入 `assistant/message`,开启输出翻译后正文会变成\n * 译文、原文只留在块元数据里,因此不能默认改变既有行为。\n */\n readonly nativeEnabled?: boolean\n}\n\nexport const SESSION_TRANSLATION_ADAPTER_IDS = [\n 'command-code', 'claude-code', 'kimi', 'gemini', 'pi', 'codex', 'opencode', 'grok',\n 'mcode', 'zcode', 'codebuddy', 'workbuddy', 'cursor-cli', 'kiro-cli', 'qoder', 'qoder-cn',\n 'antigravity', 'doubao',\n] as const\n\n/** DSH 内置 Agent 的适配器标识;它没有外部驱动,但同样支持会话翻译。 */\nexport const DSH_NATIVE_SESSION_ADAPTER_ID = 'dsh' as const\n\nexport const SESSION_TRANSLATION_LANGUAGES = ['en', 'fr', 'de', 'ja', 'zh'] as const\n\nexport const DEFAULT_SESSION_TRANSLATION_SETTINGS: SessionTranslationSettings = {\n inputEnabled: true,\n reasoningEnabled: true,\n assistantEnabled: true,\n inputLanguage: 'en',\n outputLanguage: 'zh',\n bilingual: false,\n nativeEnabled: false,\n}\n\n/**\n * 外部 Agent 适配器判定。\n *\n * 只表示「会话由插件的外部 CLI 驱动接管」,因此 DSH 原生 Agent 不在其中:该判定\n * 还被用来把外部 Agent 的虚拟 Provider 排除在翻译模型目录之外,混入 `dsh` 会污染\n * 这一语义。会话是否可翻译统一使用 {@link supportsSessionTranslation}。\n */\nexport function isSessionTranslationAdapter(adapterId: string): boolean {\n return (SESSION_TRANSLATION_ADAPTER_IDS as readonly string[]).includes(adapterId)\n}\n\n/** 外部 Agent 与 DSH 原生 Agent 都支持会话翻译。 */\nexport function supportsSessionTranslation(adapterId: string): boolean {\n return adapterId === DSH_NATIVE_SESSION_ADAPTER_ID || isSessionTranslationAdapter(adapterId)\n}\n\n/** 判断任意字符串是否为受支持的翻译语言。 */\nexport function isSessionTranslationLanguage(value: unknown): value is SessionTranslationLanguage {\n return typeof value === 'string' && (SESSION_TRANSLATION_LANGUAGES as readonly string[]).includes(value)\n}\n\n/**\n * 归一化翻译设置:旧设置快照可能缺少 `nativeEnabled`,非法语言回落到默认值。\n *\n * 与 `session-translation-service.ts` 的内部归一化保持同一语义,供客户端设置页在\n * 写入前补齐字段,避免旧快照把新字段写丢。\n */\nexport function normalizeSessionTranslationSettings(value: SessionTranslationSettings | undefined): SessionTranslationSettings {\n const fallback = DEFAULT_SESSION_TRANSLATION_SETTINGS\n if (value === undefined) return fallback\n const translationModel = normalizeTranslationModel(value.translationModel)\n const translationModels = Array.isArray(value.translationModels) ? normalizeTranslationModels(value.translationModels) : undefined\n const translationRules = Array.isArray(value.translationRules)\n ? value.translationRules.filter((rule): rule is string => typeof rule === 'string').map((rule) => rule.trim()).filter((rule) => rule !== '')\n : undefined\n return {\n inputEnabled: value.inputEnabled !== false,\n reasoningEnabled: value.reasoningEnabled !== false,\n assistantEnabled: value.assistantEnabled !== false,\n inputLanguage: isSessionTranslationLanguage(value.inputLanguage) ? value.inputLanguage : fallback.inputLanguage,\n outputLanguage: isSessionTranslationLanguage(value.outputLanguage) ? value.outputLanguage : fallback.outputLanguage,\n bilingual: value.bilingual === true,\n nativeEnabled: value.nativeEnabled === true,\n ...(translationModel === undefined ? {} : { translationModel }),\n ...(translationModels === undefined ? {} : { translationModels }),\n ...(translationRules === undefined ? {} : { translationRules }),\n }\n}\n\nfunction normalizeTranslationModels(values: readonly SessionTranslationModel[]): readonly SessionTranslationModel[] {\n const models: SessionTranslationModel[] = []\n const seen = new Set<string>()\n for (const value of values) {\n const model = normalizeTranslationModel(value)\n if (model === undefined) continue\n const key = JSON.stringify([model.provider, model.model])\n if (seen.has(key)) continue\n seen.add(key)\n models.push(model)\n }\n return models\n}\n\nfunction normalizeTranslationModel(value: SessionTranslationModel | undefined): SessionTranslationModel | undefined {\n if (value === undefined || value === null || typeof value.provider !== 'string' || typeof value.model !== 'string') return undefined\n const provider = value.provider.trim()\n const model = value.model.trim()\n return provider === '' || model === '' ? undefined : { provider, model }\n}\n\nexport interface SessionTranslationFailure {\n readonly code: 'timeout' | 'cancelled' | 'rate-limit' | 'network' | 'unavailable' | 'invalid-response' | 'configuration' | 'provider'\n readonly retryable: boolean\n}\n\nexport interface SessionTranslationMetrics {\n /** Elapsed translation time, including model selection and fallback attempts. */\n readonly durationMs?: number\n /** Reported token consumption across model attempts, including cached input. */\n readonly totalTokens?: number\n}\n\n/** Preserve available metrics while accepting records saved before metrics existed. */\nexport function readSessionTranslationMetrics(value: unknown): SessionTranslationMetrics {\n const record = asRecord(value)\n const durationMs = record?.durationMs\n const totalTokens = record?.totalTokens\n return {\n ...(typeof durationMs === 'number' && Number.isFinite(durationMs) && durationMs >= 0 ? { durationMs } : {}),\n ...(typeof totalTokens === 'number' && Number.isSafeInteger(totalTokens) && totalTokens >= 0 ? { totalTokens } : {}),\n }\n}\n\nexport interface SessionTranslationRecord extends SessionTranslationMetrics {\n readonly original: string\n readonly translated: string\n readonly sourceLanguage?: SessionTranslationLanguage\n readonly targetLanguage: SessionTranslationLanguage\n /** 回复文本所在的 DSH 内容块类型,供界面将原文入口放回对应内容块。 */\n readonly outputKind?: SessionTranslationOutputKind\n readonly bilingual: boolean\n /** 源语言与目标语言一致,因此未调用翻译模型。 */\n readonly alreadyTargetLanguage?: boolean\n /** 实际执行本次翻译的 DSH 原生模型;旧历史可能没有该字段。 */\n readonly model?: SessionTranslationModel\n /** 本次尝试失败并回退原文;前端显示警告状态。 */\n readonly failed?: boolean\n /** Structured failure details; absent in older translation records. */\n readonly failure?: SessionTranslationFailure\n}\n\nexport type SessionTranslationRecoveryChoice = 'retry' | 'send' | 'cancel'\n\n/** A failed submission remains on the host until the user makes a choice. */\nexport interface SessionTranslationPendingInput {\n readonly id: string\n readonly sessionId: string\n readonly record: SessionTranslationRecord\n}\n\n/** 用户输入的原文、实际送出的译文和翻译模型,作为 DSH 历史元数据保存。 */\nexport interface SessionTranslationInputRecord extends SessionTranslationMetrics {\n readonly original: string\n /** 包含附件提示等不翻译内容的最终 Provider prompt。 */\n readonly translated: string\n readonly sourceLanguage?: SessionTranslationLanguage\n readonly targetLanguage: SessionTranslationLanguage\n /** 源语言与目标语言一致,因此未调用翻译模型。 */\n readonly alreadyTargetLanguage?: boolean\n /** 实际执行本次翻译的 DSH 原生模型;旧历史可能没有该字段。 */\n readonly model?: SessionTranslationModel\n /** 翻译失败并回退原文;前端显示警告状态。 */\n readonly failed?: boolean\n}\n\n/**\n * 从 DSH 原生用户消息的 source 元数据读取输入翻译记录。\n *\n * 该字段由 `agent/pre-step` 写入并随 `user/message` 持久化;未知或不完整的历史\n * 结构一律返回 undefined,调用方按「没有翻译」处理。\n */\nexport function readNativeTranslationRecord(source: unknown): SessionTranslationInputRecord | undefined {\n const record = asRecord(source)\n const candidate = asRecord(record?.codingnsTranslationInput)\n if (candidate === null) return undefined\n if (typeof candidate.original !== 'string' || typeof candidate.translated !== 'string') return undefined\n if (candidate.original.trim() === '' || candidate.translated.trim() === '') return undefined\n const targetLanguage = isSessionTranslationLanguage(candidate.targetLanguage) ? candidate.targetLanguage : undefined\n if (targetLanguage === undefined) return undefined\n const model = normalizeTranslationModel(asRecord(candidate.model) as SessionTranslationModel | undefined)\n const sourceLanguage = isSessionTranslationLanguage(candidate.sourceLanguage) ? candidate.sourceLanguage : undefined\n return {\n original: candidate.original,\n translated: candidate.translated,\n targetLanguage,\n ...(sourceLanguage === undefined ? {} : { sourceLanguage }),\n ...(candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {}),\n ...(candidate.failed === true ? { failed: true } : {}),\n ...(model === undefined ? {} : { model }),\n ...readSessionTranslationMetrics(candidate),\n }\n}\n\n/** 输入记录转换为详情弹层使用的通用记录;`outputKind` 缺省表示输入方向。 */\nexport function toSessionTranslationRecord(\n record: SessionTranslationInputRecord,\n options: { readonly outputKind?: SessionTranslationOutputKind; readonly bilingual?: boolean } = {},\n): SessionTranslationRecord {\n return {\n original: record.original,\n translated: record.translated,\n targetLanguage: record.targetLanguage,\n bilingual: options.bilingual === true,\n ...(options.outputKind === undefined ? {} : { outputKind: options.outputKind }),\n ...(record.sourceLanguage === undefined ? {} : { sourceLanguage: record.sourceLanguage }),\n ...(record.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {}),\n ...(record.failed === true ? { failed: true } : {}),\n ...(record.model === undefined ? {} : { model: record.model }),\n ...readSessionTranslationMetrics(record),\n }\n}\n\nfunction asRecord(value: unknown): Record<string, any> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value) ? value as Record<string, any> : null\n}\n\n/** 外部 Agent 的历史上下文使用实际发送的译文;DSH 用户消息正文保留用户原文。 */\nexport function formatSessionTranslationInput(record: SessionTranslationInputRecord): string {\n return record.translated\n}\n\n/** Return the output translation; native DSH history keeps the original and the client reads this record. */\nexport function formatSessionTranslationOutput(record: SessionTranslationRecord): string {\n return record.translated\n}\n"],"mappings":"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"}
@@ -1192,6 +1192,12 @@ window.__ModuleLoader__.load({
1192
1192
  "cli.adapterDisabled": "{name} disabled",
1193
1193
  "cli.translationConversation": "Translate conversation",
1194
1194
  "cli.translationConversationToggle": "Toggle conversation translation",
1195
+ "cli.translationSettings": "Conversation translation settings",
1196
+ "cli.translationSettingsClose": "Close",
1197
+ "cli.translationSettingsDescription": "Choose which messages to translate in conversations with translation enabled.",
1198
+ "cli.translationUserMessages": "Translate user messages",
1199
+ "cli.translationThinkingMessages": "Translate AI thinking messages",
1200
+ "cli.translationAssistantMessages": "Translate AI final messages",
1195
1201
  "lan.fieldListenPort": "listen port",
1196
1202
  "lan.fieldDshPort": "DSH local port",
1197
1203
  "lan.fieldMustBeNumber": "{field} must be a number",
@@ -1204,6 +1210,17 @@ window.__ModuleLoader__.load({
1204
1210
  "translation.outputTitle": "Translate the AI’s reasoning and final messages into the language specified below",
1205
1211
  "translation.outputLanguage": "Reply language",
1206
1212
  "translation.modelTitle": "Translation model pool",
1213
+ "translation.rulesTitle": "Translation rules",
1214
+ "translation.rulesHelp": "Rules apply to input, reasoning, and replies, including text already in the target language. They take priority over the default translation prompts.",
1215
+ "translation.rulesEmpty": "No custom rules. The default translation prompts apply.",
1216
+ "translation.ruleAdd": "Add rule",
1217
+ "translation.ruleEdit": "Edit rule {number}",
1218
+ "translation.ruleRemove": "Remove rule {number}",
1219
+ "translation.ruleText": "Rule instructions",
1220
+ "translation.rulePlaceholder": "For example: Keep product names in their original language.",
1221
+ "translation.ruleSave": "Save rule",
1222
+ "translation.ruleSaving": "Saving…",
1223
+ "translation.ruleCancel": "Cancel",
1207
1224
  "translation.modelFollowDefault": "Use the default DSH model",
1208
1225
  "translation.modelResetTitle": "Use the default DSH model?",
1209
1226
  "translation.modelResetHelp": "This will clear all {count} models and their priority order from the pool, then follow the default DSH model. Continue?",
@@ -1235,6 +1252,12 @@ window.__ModuleLoader__.load({
1235
1252
  "translation.statusTranslating": "Translating…",
1236
1253
  "translation.progressHelp": "Preparing and translating your message. The translation result will be available when this finishes.",
1237
1254
  "translation.statusFailed": "Translation failed; original kept",
1255
+ "translation.retry": "Retry translation",
1256
+ "translation.sendDirectly": "Send directly",
1257
+ "translation.cancelSending": "Cancel sending",
1258
+ "translation.inputFailedTitle": "Message translation failed",
1259
+ "translation.inputFailedHelp": "Your message has not been sent. Choose how to continue.",
1260
+ "translation.decisionFailed": "Could not apply your choice. Please try again.",
1238
1261
  "translation.statusNotNeeded": "Already in the target language; translation skipped",
1239
1262
  "translation.detectedLanguage": "Detected language",
1240
1263
  "translation.modelNotUsed": "Not used; translation was unnecessary",
@@ -1270,6 +1293,12 @@ window.__ModuleLoader__.load({
1270
1293
  "cli.adapterDisabled": "已停用 {name}",
1271
1294
  "cli.translationConversation": "翻译对话",
1272
1295
  "cli.translationConversationToggle": "切换对话翻译",
1296
+ "cli.translationSettings": "对话翻译设置",
1297
+ "cli.translationSettingsClose": "关闭",
1298
+ "cli.translationSettingsDescription": "选择已开启对话翻译的会话中需要翻译的消息类型。",
1299
+ "cli.translationUserMessages": "翻译用户消息",
1300
+ "cli.translationThinkingMessages": "翻译 AI 思考消息",
1301
+ "cli.translationAssistantMessages": "翻译 AI 正式消息",
1273
1302
  "lan.fieldListenPort": "监听端口",
1274
1303
  "lan.fieldDshPort": "DSH 本地端口",
1275
1304
  "lan.fieldMustBeNumber": "{field} 必须是数字",
@@ -1282,6 +1311,17 @@ window.__ModuleLoader__.load({
1282
1311
  "translation.outputTitle": "AI的思考内容和正式消息翻译为以下指定语言",
1283
1312
  "translation.outputLanguage": "回复语言",
1284
1313
  "translation.modelTitle": "翻译模型池",
1314
+ "translation.rulesTitle": "翻译规则",
1315
+ "translation.rulesHelp": "规则适用于输入、思考和回复,包括已经是目标语言的文本。规则的优先级高于默认翻译提示词。",
1316
+ "translation.rulesEmpty": "尚未添加自定义规则,使用默认翻译提示词。",
1317
+ "translation.ruleAdd": "添加规则",
1318
+ "translation.ruleEdit": "编辑规则 {number}",
1319
+ "translation.ruleRemove": "移除规则 {number}",
1320
+ "translation.ruleText": "规则内容",
1321
+ "translation.rulePlaceholder": "例如:产品名称保留原文,不进行翻译。",
1322
+ "translation.ruleSave": "保存规则",
1323
+ "translation.ruleSaving": "正在保存…",
1324
+ "translation.ruleCancel": "取消",
1285
1325
  "translation.modelFollowDefault": "跟随 DSH 默认模型",
1286
1326
  "translation.modelResetTitle": "确认跟随 DSH 默认模型?",
1287
1327
  "translation.modelResetHelp": "这将清空模型池中的全部 {count} 个模型及其优先级顺序,并改为跟随 DSH 默认模型。是否继续?",
@@ -1313,6 +1353,12 @@ window.__ModuleLoader__.load({
1313
1353
  "translation.statusTranslating": "正在翻译…",
1314
1354
  "translation.progressHelp": "正在准备并翻译消息,完成后可查看翻译结果。",
1315
1355
  "translation.statusFailed": "翻译失败,已保留原文",
1356
+ "translation.retry": "重试翻译",
1357
+ "translation.sendDirectly": "直接发送",
1358
+ "translation.cancelSending": "取消发送",
1359
+ "translation.inputFailedTitle": "消息翻译失败",
1360
+ "translation.inputFailedHelp": "消息尚未发送,请选择如何继续。",
1361
+ "translation.decisionFailed": "未能应用你的选择,请重试。",
1316
1362
  "translation.statusNotNeeded": "原文已是目标语言,无需翻译",
1317
1363
  "translation.detectedLanguage": "检测到的语言",
1318
1364
  "translation.modelNotUsed": "未调用,原文无需翻译",