@sema-agent/client-core 0.109.0 → 0.111.0

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 (236) hide show
  1. package/CHANGELOG.md +342 -0
  2. package/README.md +88 -32
  3. package/dist/abortableSleep.d.ts +7 -0
  4. package/dist/abortableSleep.js +37 -0
  5. package/dist/adapt/arms.js +45 -11
  6. package/dist/adapt/toolCards.d.ts +3 -1
  7. package/dist/adapt/toolCards.js +4 -2
  8. package/dist/adapter/activeRunSelfHeal.d.ts +39 -0
  9. package/dist/adapter/activeRunSelfHeal.js +171 -3
  10. package/dist/adapter/downstream/eventToSdkMessage.js +20 -15
  11. package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
  12. package/dist/adapter/downstream/terminalToSdkResult.js +11 -0
  13. package/dist/adapter/runStream.d.ts +5 -0
  14. package/dist/adapter/runStream.js +15 -3
  15. package/dist/attachmentRoute.d.ts +20 -0
  16. package/dist/attachmentRoute.js +39 -0
  17. package/dist/attachmentsWireCaps.js +1 -1
  18. package/dist/builtinOutputStyles.d.ts +12 -0
  19. package/dist/builtinOutputStyles.js +147 -0
  20. package/dist/compactionStatus.d.ts +9 -0
  21. package/dist/compactionStatus.js +29 -5
  22. package/dist/controlRouter.js +2 -1
  23. package/dist/coreValuePorts.d.ts +39 -1
  24. package/dist/coreValuePorts.js +10 -0
  25. package/dist/declared/supportFloorDeclared.js +1 -1
  26. package/dist/displayUntrusted.d.ts +1 -0
  27. package/dist/displayUntrusted.js +138 -14
  28. package/dist/engineErrorCodes.d.ts +3 -0
  29. package/dist/engineErrorCodes.js +3 -0
  30. package/dist/engineHealthFacts.d.ts +20 -0
  31. package/dist/engineHealthFacts.js +42 -1
  32. package/dist/engineHealthProbeVerdict.d.ts +23 -0
  33. package/dist/engineHealthProbeVerdict.js +115 -0
  34. package/dist/engineInlineTaskStats.d.ts +4 -3
  35. package/dist/engineInlineTaskStats.js +18 -2
  36. package/dist/engineNoticeCodes.d.ts +10 -0
  37. package/dist/engineNoticeCodes.js +36 -6
  38. package/dist/engineRepoint.d.ts +147 -0
  39. package/dist/engineRepoint.js +310 -0
  40. package/dist/engineRowRef.d.ts +3 -0
  41. package/dist/engineRowRef.js +13 -1
  42. package/dist/engineSessionMessages.d.ts +2 -1
  43. package/dist/engineSessionMessages.js +5 -0
  44. package/dist/engineSwapCrossing.d.ts +57 -0
  45. package/dist/engineSwapCrossing.js +297 -0
  46. package/dist/engineUnavailable.d.ts +44 -0
  47. package/dist/engineUnavailable.js +492 -0
  48. package/dist/errorSupplementRoles.js +2 -1
  49. package/dist/eventLeg.js +3 -3
  50. package/dist/fleet/fleetProjection.js +3 -2
  51. package/dist/generated/engineFactTables.d.ts +2 -0
  52. package/dist/generated/engineFactTables.js +12 -0
  53. package/dist/generated/sdkFactTables.d.ts +2 -1
  54. package/dist/generated/sdkFactTables.js +5 -0
  55. package/dist/generated/settingsSchemaTables.d.ts +4 -0
  56. package/dist/generated/settingsSchemaTables.js +1 -0
  57. package/dist/hitl/approvalAskers.d.ts +6 -0
  58. package/dist/hitl/approvalAskers.js +30 -0
  59. package/dist/hitl/approvalCardReasons.js +6 -3
  60. package/dist/hitl/approvalDelivery.d.ts +1 -0
  61. package/dist/hitl/approvalDelivery.js +1 -1
  62. package/dist/hitl/approvalRequestFrameReading.d.ts +7 -0
  63. package/dist/hitl/approvalRequestFrameReading.js +11 -0
  64. package/dist/hitl/approvalResolution.d.ts +9 -2
  65. package/dist/hitl/approvalResolution.js +6 -1
  66. package/dist/hitl/askGateWire.js +5 -8
  67. package/dist/hitl/automaticAnswerVerdict.js +2 -2
  68. package/dist/hitl/decisionConflict.js +6 -3
  69. package/dist/hitl/decisionRefusal.d.ts +2 -0
  70. package/dist/hitl/decisionRefusal.js +8 -8
  71. package/dist/hitl/decisionRefusalCarrier.d.ts +3 -0
  72. package/dist/hitl/decisionRefusalCarrier.js +348 -0
  73. package/dist/hitl/decisionSend.d.ts +10 -0
  74. package/dist/hitl/decisionSend.js +57 -17
  75. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  76. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  77. package/dist/hitl/elicitationRefusal.d.ts +4 -0
  78. package/dist/hitl/elicitationRefusal.js +23 -0
  79. package/dist/hitl/frameRouter.d.ts +2 -2
  80. package/dist/hitl/frameRouter.js +12 -33
  81. package/dist/hitl/gateIdentity.d.ts +5 -0
  82. package/dist/hitl/gateIdentity.js +23 -0
  83. package/dist/hitl/gateLedger.d.ts +0 -4
  84. package/dist/hitl/gateLedger.js +0 -19
  85. package/dist/hitl/hitlBridge.d.ts +7 -0
  86. package/dist/hitl/hitlBridge.js +14 -8
  87. package/dist/hitl/hitlHostSurface.d.ts +3 -1
  88. package/dist/hitl/hitlHostSurface.js +14 -4
  89. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  90. package/dist/hitl/hostWithdrawal.js +38 -0
  91. package/dist/hitl/localAllowRedemption.d.ts +67 -0
  92. package/dist/hitl/localAllowRedemption.js +256 -0
  93. package/dist/hitl/parkResolver.js +32 -13
  94. package/dist/hitl/persistedRulesWire.d.ts +16 -0
  95. package/dist/hitl/persistedRulesWire.js +72 -2
  96. package/dist/hitl/planReviewWire.d.ts +3 -0
  97. package/dist/hitl/planReviewWire.js +37 -10
  98. package/dist/hitl/policyDenyCause.d.ts +1 -1
  99. package/dist/hitl/policyDenyCause.js +1 -1
  100. package/dist/hitl/resumeRunningCard.d.ts +1 -0
  101. package/dist/hitl/resumeRunningCard.js +1 -0
  102. package/dist/hitl/screenCardCarriers.d.ts +15 -0
  103. package/dist/hitl/screenCardCarriers.js +41 -0
  104. package/dist/hitl/screenDecisionCards.d.ts +98 -0
  105. package/dist/hitl/screenDecisionCards.js +362 -0
  106. package/dist/hitl/sessionPolicyWire.js +6 -4
  107. package/dist/hitl/standingRows.d.ts +4 -1
  108. package/dist/hitl/standingRows.js +33 -1
  109. package/dist/hitl/toolApprovalWire.d.ts +64 -15
  110. package/dist/hitl/toolApprovalWire.js +470 -125
  111. package/dist/hooksWireCaps.js +31 -1
  112. package/dist/hostSettingNoticeArm.d.ts +3 -0
  113. package/dist/hostSettingNoticeArm.js +12 -0
  114. package/dist/hostTurnSettings.d.ts +13 -4
  115. package/dist/hostTurnSettings.js +150 -10
  116. package/dist/humanTurnRead.js +11 -1
  117. package/dist/i18n/messages.en.d.ts +212 -0
  118. package/dist/i18n/messages.en.js +217 -5
  119. package/dist/i18n/messages.zh.js +235 -5
  120. package/dist/i18n/translate.d.ts +3 -0
  121. package/dist/i18n/translate.js +78 -10
  122. package/dist/i18n/zh.d.ts +1 -0
  123. package/dist/i18n/zh.js +1 -0
  124. package/dist/index.d.ts +56 -16
  125. package/dist/index.js +40 -12
  126. package/dist/inheritEnvCapability.js +2 -0
  127. package/dist/inputAuthor.d.ts +16 -0
  128. package/dist/inputAuthor.js +44 -0
  129. package/dist/interactiveHalt.js +2 -1
  130. package/dist/interactiveInterrupt.js +20 -2
  131. package/dist/interruptRefusalNote.d.ts +2 -0
  132. package/dist/interruptRefusalNote.js +17 -0
  133. package/dist/liveModelCatalog.d.ts +2 -0
  134. package/dist/liveModelCatalog.js +23 -9
  135. package/dist/liveQuestionStore.d.ts +4 -1
  136. package/dist/liveQuestionStore.js +12 -3
  137. package/dist/localEngineSeatReading.d.ts +2 -2
  138. package/dist/localEngineSeatReading.js +5 -3
  139. package/dist/localEngineSpawn.d.ts +0 -7
  140. package/dist/localEngineSpawn.js +0 -92
  141. package/dist/localEngineStep.d.ts +2 -2
  142. package/dist/localEngineStep.js +2 -0
  143. package/dist/mcpEngineLeg.d.ts +3 -0
  144. package/dist/mcpEngineLeg.js +38 -1
  145. package/dist/mcpPanel.js +2 -0
  146. package/dist/mcpReconnect.d.ts +9 -1
  147. package/dist/mcpReconnect.js +124 -19
  148. package/dist/mcpWireCaps.js +1 -1
  149. package/dist/model/engineModelWords.d.ts +3 -0
  150. package/dist/model/engineModelWords.js +13 -0
  151. package/dist/model/subagentModelWord.d.ts +21 -2
  152. package/dist/model/subagentModelWord.js +100 -29
  153. package/dist/modelCapabilityProbe.js +7 -43
  154. package/dist/modsFace.d.ts +8 -1
  155. package/dist/modsFace.js +27 -0
  156. package/dist/notifications.d.ts +36 -6
  157. package/dist/notifications.js +170 -20
  158. package/dist/ownKey.d.ts +6 -5
  159. package/dist/ownKey.js +31 -7
  160. package/dist/peerFrames.d.ts +40 -2
  161. package/dist/peerFrames.js +158 -3
  162. package/dist/pendingUserRow.d.ts +4 -0
  163. package/dist/pendingUserRow.js +16 -0
  164. package/dist/permissionsDeclaration.d.ts +1 -0
  165. package/dist/permissionsDeclaration.js +11 -1
  166. package/dist/planReviewCardFacts.d.ts +3 -0
  167. package/dist/planReviewCardFacts.js +52 -2
  168. package/dist/pluginHooksWire.d.ts +10 -1
  169. package/dist/pluginHooksWire.js +96 -7
  170. package/dist/printToolResultFrame.js +4 -2
  171. package/dist/promptBlockedCopy.js +11 -6
  172. package/dist/promptSuggestionBatch.d.ts +7 -0
  173. package/dist/promptSuggestionBatch.js +9 -0
  174. package/dist/promptSuggestionsTail.d.ts +39 -0
  175. package/dist/promptSuggestionsTail.js +116 -0
  176. package/dist/replayBody.js +10 -2
  177. package/dist/request/taskRequest.d.ts +5 -0
  178. package/dist/request/taskRequest.js +142 -21
  179. package/dist/requestCoordinate.d.ts +1 -0
  180. package/dist/requestCoordinate.js +13 -0
  181. package/dist/resumeRefusalCopy.d.ts +1 -3
  182. package/dist/resumeRefusalCopy.js +2 -1
  183. package/dist/retryStatus.d.ts +2 -2
  184. package/dist/retryStatus.js +2 -0
  185. package/dist/rewindArchiveReading.js +4 -4
  186. package/dist/runCancelContext.d.ts +2 -1
  187. package/dist/runCancelContext.js +1 -0
  188. package/dist/runPermissionModeSwitch.js +2 -2
  189. package/dist/scenarioRefusal.js +11 -13
  190. package/dist/scenarioSkills.js +11 -6
  191. package/dist/seam.d.ts +27 -2
  192. package/dist/seam.js +17 -1
  193. package/dist/seatContract.d.ts +189 -12
  194. package/dist/seatContract.js +401 -9
  195. package/dist/sessionBackground.js +2 -1
  196. package/dist/sessionBackgroundHandoff.js +2 -1
  197. package/dist/sessionCostReading.d.ts +70 -0
  198. package/dist/sessionCostReading.js +150 -0
  199. package/dist/sessionEngine.d.ts +2 -0
  200. package/dist/sessionEngine.js +111 -0
  201. package/dist/sessionHooksRoster.d.ts +4 -0
  202. package/dist/sessionHooksRoster.js +158 -0
  203. package/dist/sessionMemoryStatus.d.ts +2 -1
  204. package/dist/sessionMemoryStatus.js +2 -2
  205. package/dist/sessionReadRedaction.d.ts +7 -0
  206. package/dist/sessionReadRedaction.js +26 -0
  207. package/dist/sessionSyncFileHistory.d.ts +4 -0
  208. package/dist/sessionSyncFileHistory.js +27 -0
  209. package/dist/settingsHooksSalvage.js +2 -1
  210. package/dist/sseIdleTriage.d.ts +13 -1
  211. package/dist/sseIdleTriage.js +25 -6
  212. package/dist/storeDurabilityWord.d.ts +15 -0
  213. package/dist/storeDurabilityWord.js +18 -0
  214. package/dist/storePostureCapability.d.ts +7 -3
  215. package/dist/storePostureCapability.js +69 -39
  216. package/dist/subagent/engineSubagentResume.js +2 -2
  217. package/dist/subagent/engineSubagentTail.js +8 -1
  218. package/dist/subagentContentStore.d.ts +11 -0
  219. package/dist/subagentContentStore.js +28 -2
  220. package/dist/terminalStatuses.d.ts +1 -0
  221. package/dist/terminalStatuses.js +4 -1
  222. package/dist/toolResult.d.ts +1 -0
  223. package/dist/toolResult.js +2 -0
  224. package/dist/turnFailurePresentation.js +9 -2
  225. package/dist/typePins.d.ts +11 -0
  226. package/dist/usageAnalytics.d.ts +17 -0
  227. package/dist/usageAnalytics.js +44 -2
  228. package/dist/userAttachmentEnvelope.d.ts +2 -1
  229. package/dist/userAttachmentEnvelope.js +10 -0
  230. package/dist/wireErrorTriage.js +2 -1
  231. package/dist/wireFailureShape.d.ts +6 -5
  232. package/dist/wireFailureShape.js +150 -38
  233. package/dist/wireRefusalCopy.d.ts +16 -5
  234. package/dist/wireRefusalCopy.js +119 -86
  235. package/docs/INTEGRATION-CLIENTS.md +4228 -21
  236. package/package.json +7 -3
@@ -115,8 +115,16 @@ const ZH = {
115
115
  'model.subagent.chainUnbound': '子代理模型 {word} 在这台引擎上没有绑定(它和比它低的档位都没绑模型)—— 子代理将沿用父代理的模型。',
116
116
  'model.subagent.bindingNotInCatalog': '子代理模型 {word} 绑定的模型不在这台引擎的模型目录里 —— 子代理将沿用父代理的模型。',
117
117
  'model.subagent.ambiguous': '子代理模型 {word} 同时对上了几个只差大小写的模型名 —— 请照原样拼写;子代理将沿用父代理的模型。',
118
+ 'model.subagent.call.ambiguous': '这次调用用不了子代理模型 {word}:它同时对上了几个只差大小写的模型名 —— 请照原样拼写。',
119
+ 'model.subagent.call.tiersInert': '这次调用用不了子代理模型 {word}:它是档位词,但这台引擎没有配置模型档位。',
120
+ 'model.subagent.call.chainUnbound': '这次调用用不了子代理模型 {word}:它对应档位 {tier},这台引擎上这一档没有绑定模型(比它低的档位也都没有)。',
121
+ 'model.subagent.call.bindingNotInCatalog': '这次调用用不了子代理模型 {word}:它的档位 {tier} 绑定的模型不在这台引擎的模型目录里。',
122
+ 'model.subagent.refused.notListed': '子代理模型 {word} 在这台引擎上既不是模型名,也不是档位词或模型 id —— 这个代理不随请求发出(带着它的请求引擎一律拒收);请改这个代理的模型,或设成 `inherit`。',
123
+ 'model.subagent.refused.notServed': '子代理模型 {word} 在这台引擎上背后没有模型 —— 这个代理不随请求发出(带着它的请求引擎一律拒收);请改这个代理的模型,或设成 `inherit`。',
124
+ 'model.subagent.refused.disabled': '子代理模型 {word} 在这台引擎上已停用 —— 这个代理不随请求发出(带着它的请求引擎一律拒收);请改这个代理的模型,或设成 `inherit`。',
118
125
  'model.catalogDefault.refused.named': '不点名模型的任务会被拒:引擎从它的模型配置里解析不出缺省模型(设置里的缺省是 {name}) · 设一个引擎跑得了的缺省模型,或添加 / 修好一个',
119
126
  'model.catalogDefault.refused.select': '不点名模型的任务会被拒:引擎从它的模型配置里解析不出缺省模型(设置里的缺省是挑选条件) · 改挑选条件,或添加 / 修好一个引擎跑得了的模型',
127
+ 'session.sync.pushRowBitsWriterSide': '会话已推送 · 它在目的端是只读镜像,标题与置顶由写入它的那一端持有,这一次没有在目的端更改',
120
128
  'session.devices.laneAbsent': '这个后端没有远程控制车道',
121
129
  'session.devices.laneUnreported': '这个后端没有报告远程控制车道',
122
130
  'session.devices.verbsOff': '这个后端的设备车道开着,但设备管理动作关着 —— 这里列不出也改不了设备',
@@ -130,6 +138,27 @@ const ZH = {
130
138
  'session.engine.dispatch.scopeUnproven': '确认不了你当前的登录能到达这只会话所在的引擎,什么都没发。先登录那台引擎所在的空间(或直接连上那台引擎),再试一次。',
131
139
  'session.engine.dispatch.unresolved': '这只会话所在的引擎还不知道,什么都没发。先为这只会话选一次引擎,再试一次。',
132
140
  'session.engine.dispatch.sessionAmbiguous': '这个会话同时登记在两台引擎上,先停下不发 —— 请先确认它属于哪一台。',
141
+ 'session.mcpReconnect.notRunning': '这只会话此刻在这台引擎上没有存活的任务(可能在等你回答、已经结束,或在别处运行),所以没有重连 {server};之后启动或恢复的任务会重新连接它声明的服务器。',
142
+ 'session.mcpReconnect.unsupported': '这台引擎不支持在会话进行中重连 MCP 服务器,所以没有重连 {server}。',
143
+ 'session.mcpReconnect.notFound': '引擎没有找到这个会话,所以没有重连 {server}。',
144
+ 'session.mcpReconnect.invalid': '重连 {server} 的请求不合规(会话标识或服务器名称不可用),所以没有重连。',
145
+ 'session.mcpReconnect.failed': '没能在引擎上重连 {server}:请求没有完成。',
146
+ 'session.mcpReconnect.noSession': '还没有引擎会话,所以没有在引擎上重连 {server}。',
147
+ 'session.mcpReconnect.unavailable': '这里不能在引擎上重连 {server}。',
148
+ 'session.mcpReconnect.accepted.one': 'MCP 服务器 {server} 已重连:为这次运行挂载了 {toolCount} 个工具(新增 {added} 个,移除 {removed} 个)',
149
+ 'session.mcpReconnect.accepted.other': 'MCP 服务器 {server} 已重连:为这次运行挂载了 {toolCount} 个工具(新增 {added} 个,移除 {removed} 个)',
150
+ 'session.mcpReconnect.refused.untouched': 'MCP 服务器 {server} 没有重连,它的连接和工具原样未动{why}。',
151
+ 'session.mcpReconnect.refused.noTools': 'MCP 服务器 {server} 没有重连;这次运行的工具列表里此刻没有它的工具(重连失败,或这次运行的工具设置没放行它的任何工具){why}。',
152
+ 'session.mcpReconnect.refused.listed.one': 'MCP 服务器 {server} 没有重连;这次尝试之后,引擎报告它有 {toolCount} 个工具{why}。',
153
+ 'session.mcpReconnect.refused.listed.other': 'MCP 服务器 {server} 没有重连;这次尝试之后,引擎报告它有 {toolCount} 个工具{why}。',
154
+ 'session.mcpReconnect.undeclared': '这次运行没有声明任何 MCP 服务器,所以没有可重连的对象({server} 不属于这次运行){why}。',
155
+ 'session.mcpReconnect.unsettled': 'MCP 重连在本次请求愿意等待的时间内没有落定,所以还没有结果:重连没有被取消,可能仍在进行。再次重连这台服务器前,请先确认它的状态——拨号落定之后再发一次请求,会先关闭连接、再重新拨号。',
156
+ 'session.mcpReconnect.reasonTail': ' —— {reason}',
157
+ 'session.mcpReconnect.transaction': '重连会先关闭当前连接,再重新拨号。在运行正常的服务器上,这是一次整体操作,不是刷新:重拨失败会让服务器保持断开,并把它的工具从模型那里撤走,直到之后某次重拨成功。',
158
+ 'session.mcpFailure.reauthorizeSuffix': '(需要重新授权)',
159
+ 'session.mcpFailure.serverDownSuffix': '(服务器不可用)',
160
+ 'mcp.elicitation.refused.named': 'MCP 服务器 {server} 请求通过表单填写信息,此处无法呈现表单,已拒绝该请求。',
161
+ 'mcp.elicitation.refused.unnamed': '有 MCP 服务器请求通过表单填写信息,此处无法呈现表单,已拒绝该请求。',
133
162
  'config.cloudLogin.accessDenied': '登录被拒绝了。',
134
163
  'config.cloudLogin.expiredToken': '登录码在批准之前过期了 —— 请重新开始。',
135
164
  'config.cloudLogin.invalidGrant': 'Cloud 登录已无法续期 —— 请重新登录。',
@@ -202,9 +231,9 @@ const ZH = {
202
231
  'config.mcp.transportsNone': '无',
203
232
  'config.mcp.transportInvalid': 'MCP 服务器 {name}{where} 没有启动:它的传输设置不可用 —— {path} {problem}。请修正这台服务器的这项设置(或删掉这台服务器);其他 MCP 服务器不受影响。',
204
233
  'config.mcp.transportDegraded': 'MCP 服务器 {name}{where} 已启动,但它的部分传输设置不能照原样使用、被略去了:{lost}。其余设置照常生效;请修正上面点名的设置,让它们也生效。',
205
- 'config.mcp.toolAxesInvalid': 'MCP 服务器 {name}{where} 没有启动:它的 toolAxes 设置不合法 —— {problem}。请修正这台服务器的 toolAxes(或删掉它);其他 MCP 服务器不受影响。',
234
+ 'config.mcp.toolAxesInvalid': 'MCP 服务器 {name}{where} 曾被启动去读取它的工具列表,随后被丢弃:它的 toolAxes 设置不合法 —— {problem}。请修正这台服务器的 toolAxes(或删掉它);其他 MCP 服务器不受影响。',
206
235
  'config.mcp.toolAxesFallbackProblem': '这份声明不是一组合法的按工具安全设置',
207
- 'config.mcp.toolFacesInvalid': 'MCP 服务器 {name}{where} 没有启动:它的 toolFaces 设置不合法 —— {problem}。请修正这台服务器的 toolFaces(或删掉它);其他 MCP 服务器不受影响。',
236
+ 'config.mcp.toolFacesInvalid': 'MCP 服务器 {name}{where} 曾被启动去读取它的工具列表,随后被丢弃:它的 toolFaces 设置不合法 —— {problem}。请修正这台服务器的 toolFaces(或删掉它);其他 MCP 服务器不受影响。',
208
237
  'config.mcp.toolFacesFallbackProblem': '这份声明不是一组合法的按工具展示与审批设置',
209
238
  'config.mcp.toolFacesUnreadable': '这项设置读不出来(它上面的取值器或代理陷阱抛了错)',
210
239
  'config.mcp.elicitationInvalid': 'MCP 服务器 {name}{where} 没有启动:它的 elicitation 设置必须是 true 或 false。请修正这台服务器的 elicitation(或删掉它);其他 MCP 服务器不受影响。',
@@ -214,7 +243,7 @@ const ZH = {
214
243
  'config.mcp.transportTypeUnsupported': '这种传输类别请求面承载不了(只支持 stdio 与 http)',
215
244
  'config.mcp.transportIdentityBothSetProblem': '同时设置了 principalHeader 与 assertionHeader,而这两项指的是同一个身份头 —— 只保留其中一项',
216
245
  'config.mcp.cloudElicitationInvalid': '云配置:这些 MCP 服务器条目被略过,因为它们的 elicitation 设置不是 true 或 false —— 请修正或删掉 elicitation 条目:{who}',
217
- 'config.mcp.allowToolsInvalid': 'MCP 服务器 {name}{where} 没有启动:它的 allowTools 设置不能使用 —— {problem}。请修正这台服务器的 allowTools 条目(工具名字符串的列表);其他 MCP 服务器不受影响。',
246
+ 'config.mcp.allowToolsInvalid': 'MCP 服务器 {name}{where} 曾被启动去读取它的工具列表,随后被丢弃:它的 allowTools 设置不能使用 —— {problem}。请修正这台服务器的 allowTools 条目(工具名字符串的列表);其他 MCP 服务器不受影响。',
218
247
  'config.mcp.allowToolsNotArray': '{path} 必须是字符串数组(实际是 {got})',
219
248
  'config.mcp.allowToolsElementNotString': '{path} 必须是字符串(实际是 {got})',
220
249
  'config.mcp.allowToolsHole': '{path} 缺失:列表中不允许有空缺,每个位置都必须是字符串',
@@ -252,6 +281,7 @@ const ZH = {
252
281
  'approval.settle.cause.streamDisconnected': '承载这张卡的连接断了',
253
282
  'approval.settle.cause.undeliverable': '它没能送达任何审批界面',
254
283
  'approval.resolution.engineUnavailable': '引擎暂不可用 —— 待引擎回来再答。',
284
+ 'approval.allowNote.notCarried': '这台引擎不能在「Yes」上附带备注 —— 写在这里的备注不会送达模型。',
255
285
  'approval.decide.requiresBinding': '这次决定没有带上把它绑到审批卡上那个具体动作的绑定,引擎拒绝了 · 什么都没有决定,这条审批仍在等待 · 请重新获取待决审批,按现在列出的那张卡再决定;如果列出的卡本身就没有绑定,{wayOut}',
256
286
  'approval.decide.unboundWayOut.armed': '这里决不了 —— 取消这次运行,或等这条审批过期',
257
287
  'approval.decide.unboundWayOut.none': '这里决不了 —— 取消这次运行(这条审批没有到期计时)',
@@ -261,17 +291,24 @@ const ZH = {
261
291
  'approval.rowUnresumable.askNotSurfaced': '这条待决行(任务 {taskId})这台引擎续不了,所以没有呈成可作答的卡:{sentence}',
262
292
  'approval.park.stillParked': '{gate} 这道门没能作答:{reason} —— 这一跑仍停在这条审批上。',
263
293
  'approval.park.refusedNotResumable': '{gate} 这道门没能作答:{reason} —— 这台引擎目前续不了这条审批;若这一跑仍停着,请取消它。',
294
+ 'approval.park.resume.card': '{gate} 这道门没能作答:{reason} —— 这一跑仍停在这条审批上:卡再次出现时在卡上决,或取消这一跑。',
295
+ 'approval.park.resume.speak': '{gate} 这道门没能作答:{reason} —— 这一跑仍停在这条审批上:发一句话把这张卡重新打开,再在卡上决,或取消这一跑。',
264
296
  'approval.park.argsFromModelCall': '这条待决审批的记录里没有将执行的工具入参,下面显示的是对话里模型的原始调用 —— 若它在那之后被改写过(例如被钩子),实际执行的会与所见不同。这张卡不接受编辑后批准:所见入参不是将执行的那一份',
265
297
  'approval.park.questionsFromModelCall': '这条待决审批的记录里没有可呈现的问题,下面显示的是对话里模型的原始调用 —— 若它在那之后被改写过(例如被钩子),引擎实际在问的问题会与所见不同',
266
298
  'approval.policyDeny.denyRule': '这次工具调用被权限设置里的拒绝规则拒绝了。{tail}',
267
299
  'approval.policyDeny.dontAsk': '这次工具调用被拒绝了:本会话不再询问审批,凡需要审批的调用一律拒绝。{tail}',
268
300
  'approval.policyDeny.engineFloor': '这次工具调用被引擎侧的保护规则拒绝了,权限设置无法覆盖。{tail}',
301
+ 'approval.policyDeny.hook': '这次工具调用被一只 PermissionRequest 钩子拒绝了。该操作没有执行。不要声称它已成功,也不要原样重试 —— 请向用户说明被拦下的是什么,或建议别的做法。',
269
302
  'approval.policyDeny.tail': '该操作没有执行。不要声称它已成功,也不要在本会话里重试 —— 请向用户说明这一限制,或建议别的做法。',
270
303
  'approval.decision.grantChanged': '引擎拒收了这次批准:它绑定的技能授予在卡呈出之后已经变了 · 什么都没有决定,这一请求仍在等待,但再批一次会以同样的理由被拒 · 请拒绝这一请求,让模型重新激活那个技能',
271
304
  'approval.decision.answerInvalid': '引擎拒收了这次回答本身:它与所问的问题对不上 · 什么都没有决定,这一问仍在等待 · 请改正回答后重新发送',
305
+ 'approval.editRefusal.stem': '这条请求在此处看不到工具入参,所以收不了改写后的批准',
306
+ 'approval.editRefusal.line': '这次批准没有发出:{stem}。原卡照旧在等你决断——请按原样批准或拒绝。',
307
+ 'approval.editRefusal.parkReason': '这张卡回了一个改写后的批准,但{stem}——什么都没有发出(待决记录里的入参缺失,或因为太大在那里只留下了一个标明大小的占位);请按原样批准或拒绝',
272
308
  'approval.decision.settledElsewhereContrary.deniedFirst': '这一请求已在别处被答复为拒绝,你的批准没有生效。',
273
309
  'approval.decision.settledElsewhereContrary.approvedFirst': '这一请求已在别处被答复为批准,你的拒绝没有生效。',
274
310
  'approval.decision.unconfirmedAfterRetry': '不知道你的答复有没有生效:之前那一发没有得到确认,重发时这一请求已不在等待 · 动手之前先看任务当前的状态',
311
+ 'approval.decideAck.unconfirmed': '不知道你的答复有没有生效 · 再答之前先看这一请求的当前状态',
275
312
  'notice.decide.rowUnrevivable': '引擎已经无法恢复这张审批卡,批准和拒绝都不会生效 · 这张卡只能在服务端清理 —— 请等待清理完成,或联系运维这台引擎的人',
276
313
  'approval.askPark.autoReopenBlocked.policyInteractive': '引擎的准入策略拒绝续跑这一停驻步骤(run {run}),所以 sema 不会自己把它的卡放回屏幕。请换成这台部署允许的权限模式,或联系部署的运维方,然后发一条消息把卡带回来。',
277
314
  'approval.askPark.autoReopenBlocked.policyPrint': '引擎的准入策略拒绝续跑这一停驻步骤(run {run}),所以 sema 不会自己把它的卡放回屏幕。请换成这台部署允许的权限模式,或联系部署的运维方,然后发一条消息把卡带回来;或者停掉这条 run({cancel})。',
@@ -437,6 +474,9 @@ const ZH = {
437
474
  'session.selfHeal.injected.notDelivered': '{lead}没有送达:这个会话还被较早的一轮回复占着{id},而且没有可以回答来放行的打开的卡{noView}。sema 没有重试,所以模型没有看到它。',
438
475
  'session.selfHeal.injected.redundant': '{lead}没有转交:它说的那一轮回复{id}在那次决定之后已经自己接着往下走了,它没有什么可补充的。',
439
476
  'session.selfHeal.injected.deferred': '{lead}正在等待:这个会话正被较早的一轮回复{id}占着,sema 保留了这条消息,等那一轮回复结束或暂停后再作为一条新消息发送。',
477
+ 'session.selfHeal.injected.resendWithheldLeftConfirmed': '{lead}没有送达:较早的那一轮回复{id}已经放开了这条消息要发往的那个对话,但 sema 还没来得及发送,屏幕就切到了另一个对话;sema 不会把它发进另一个对话 —— 模型没有看到它。',
478
+ 'session.selfHeal.injected.resendWithheldUnconfirmed': '{lead}没有送达:sema 无法确认屏幕上仍是这条消息要发往的那个对话,所以没有发送 —— 模型没有看到它。',
479
+ 'session.selfHeal.injected.resendWithheldLeftInferred': '{lead}没有送达:较早的那一轮回复{id}在这条消息要发往的那个对话里现在报告为已结束,但 sema 还没来得及发送,屏幕就切到了另一个对话;sema 不会把它发进另一个对话 —— 模型没有看到它。',
440
480
  'session.selfHeal.decisionInFlight': '上一个 turn 处于 parked 状态,{parkedOn},而你对那张卡的回答还在送往引擎的路上,所以 sema 没有再次显示那张卡 —— 再回答一次会发出第二个决断。它没有取消这次 run。你的消息没有发出;请稍等片刻,等引擎应用了那个决断之后再发一次。',
441
481
  'session.selfHeal.parkedOn.ask': '在等你的决断(run {taskId})',
442
482
  'session.selfHeal.parkedOn.plan': '停在一次计划审阅上(run {taskId})',
@@ -476,6 +516,17 @@ const ZH = {
476
516
  'session.selfHeal.row.attach': '{disclosure}你的消息没有发出;等那次 run 结束后,请再发一次。',
477
517
  'session.selfHeal.row.cancelled.confirmed': '你选择了取消 run {taskId}。引擎确认它不再占着这个会话,所以 sema 现在就发送你的消息。',
478
518
  'session.selfHeal.row.cancelled.reported': '你选择了取消 run {taskId}。引擎现在报告那次 run 已结束,所以 sema 现在就发送你的消息;如果那次 run 还没完全放开这个会话,你可能得再发一次。',
519
+ 'session.selfHeal.row.resendWithheldLeft.confirmed': '你的消息没有发出去:run {taskId} 已经不再占着你输入这条消息的那个对话,但 sema 还没来得及重发,屏幕就切到了另一个对话;sema 不会把消息发进另一个对话。如果还需要,请切回那个对话再发一次。',
520
+ 'session.selfHeal.row.resendWithheldLeft.reported': '你的消息没有发出去:引擎现在报告 run {taskId} 在你输入这条消息的那个对话里已结束,但 sema 还没来得及重发,屏幕就切到了另一个对话;sema 不会把消息发进另一个对话。如果还需要,请切回那个对话再发一次(如果那次 run 还没完全放开那个对话,你可能得再发一次)。',
521
+ 'session.selfHeal.row.resendWithheldUnconfirmed': '你的消息没有发出去:sema 无法确认屏幕上仍是你输入这条消息的那个对话,所以没有重发 —— 把消息发进别的对话比不发更糟。如果这仍是那个对话,请再发一次。',
522
+ 'session.selfHeal.stopLeft.untouched': 'sema 没有动 run {taskId}:sema 检查那次 run 时屏幕切到了另一个对话,而 sema 不会替一个已经不在屏幕上的对话结束 run。那次 run 可能仍占着它所属的那个对话 —— 请切回那个对话,然后{endRun}。',
523
+ 'session.selfHeal.stopLeft.waiting.certain': 'run {taskId} 正在它所属的那个对话里等你做决定,而 sema 不会结束一个在等你回答的 run。屏幕此后已切到另一个对话 —— 请切回那个对话去回答。',
524
+ 'session.selfHeal.stopLeft.waiting.uncertain': 'run {taskId} 可能正在它所属的那个对话里等你做决定 —— sema 无法确认它没有在等 —— 所以 sema 没有动它。屏幕此后已切到另一个对话 —— 请切回那个对话去回答;如果那里没有在等的决定,{endRun}。',
525
+ 'session.selfHeal.stopLeft.ended.confirmed': 'run {taskId} 已结束 —— 引擎确认它不再占着它所属的那个对话。屏幕此后已切到另一个对话 —— 请切回那个对话再发一次你的消息。',
526
+ 'session.selfHeal.stopLeft.ended.reported': 'run {taskId} 已结束 —— 引擎报告它已完成。屏幕此后已切到另一个对话 —— 请切回那个对话再发一次你的消息。',
527
+ 'session.selfHeal.stopLeft.nothingToEnd': 'run {taskId} 早已结束,没有可结束的东西。屏幕此后已切到另一个对话 —— 请切回那个对话再发一次你的消息。',
528
+ 'session.selfHeal.stopLeft.refused': 'sema 没能结束 run {taskId}:引擎拒绝了({detail}),所以什么都没有结束。屏幕此后已切到另一个对话 —— 请切回那次 run 所属的对话再试一次:{endRun}。',
529
+ 'session.selfHeal.stopLeft.notConfirmed': 'sema 无法确认 run {taskId} 已经放开它所属的那个对话,而屏幕此后已切到另一个对话。请切回那个对话去确认;要结束它,{endRun}。',
479
530
  'session.selfHeal.row.cancelTimeout.aborted': 'sema 请引擎取消 run {taskId},而你在它还在确认的时候中断了(已过 {waited})。取消是异步的,所以那次 run 可能仍在收尾,仍占着这个会话。你的消息没有发出;请稍等片刻再发一次,或者{wayOut}。',
480
531
  'session.selfHeal.row.cancelTimeout.unread': 'sema 请引擎取消 run {taskId},但在 {waited} 内读不回那次 run 的状态,所以确认不了会话是否已被释放。你的消息没有发出;请稍等片刻再发一次(如果那次 run 真的没了,它就会直接运行),或者{wayOut}。',
481
532
  'session.selfHeal.row.cancelTimeout.held': 'sema 请引擎取消 run {taskId},但 {waited} 之后那次 run 仍占着这个会话 —— 取消是异步的,它可能仍在收尾。你的消息没有发出;请稍等片刻再发一次,或者{wayOut}。',
@@ -634,6 +685,8 @@ const ZH = {
634
685
  'session.hostSettings.heldPrevious': '刚才有一份设置文件没能完整读出(可能正在保存),所以仍按上一次完整读到的权限规则执行。',
635
686
  'session.hostSettings.styleMissing': '设置里选中的输出风格「{name}」找不到或读不出,这一次请求不套用它。',
636
687
  'session.hostSettings.styleSafeMode': '安全模式已开启,设置里的输出风格不套用。',
688
+ 'session.hostSettings.styleOversize': '你的输出风格这一次请求没有套用:加上内置的产品背景说明后超过了 {limit} 个字符的上限。请缩短风格正文后再用。',
689
+ 'session.hostSettings.styleUnreadable': '输出风格的正文读不成文本,这一次请求不套用它。',
637
690
  'model.identity.lane.processEnv': '本客户端启动时的环境',
638
691
  'model.identity.lane.settingsEnv': '本客户端的设置文件',
639
692
  'model.identity.lane.modelCatalogFile': '本地模型目录文件',
@@ -675,7 +728,7 @@ const ZH = {
675
728
  'notice.durableGate.exit.other': '要使用持久审批,需要有可用的检查点存储。',
676
729
  'notice.durableGate.exitAlt.forceDurableGate': '或者请运维这套部署的人撤掉对这个账号的此项要求。',
677
730
  'notice.durableGate.exitAlt.durableApproval': '或者让这个任务在有实时审批人的地方运行。',
678
- 'notice.memory.sessionPolluted': '本会话收进了来自外部来源的内容({reason})。从现在起,它写入的记忆可能被扣下候审,而不是存入长期记忆库;每一批实际扣下了什么,会另行通知。',
731
+ 'notice.memory.sessionPolluted': '本会话里有工具能够到外部内容({reason})。从现在起,它写入的记忆可能被扣下候审,而不是存入长期记忆库;每一批实际扣下了什么,会另行通知。',
679
732
  'notice.memory.harvestQuarantined.counts': '记忆收集把本会话写入或修改的条目文件扣下了,没有加入长期记忆库 —— 扣下 {count} 个,移到一旁候审 {moved} 个,需要跟进 {escalated} 个;后两个数字可能有重叠。',
680
733
  'notice.memory.harvestQuarantined.indexOnly': '记忆收集把本会话对记忆索引的改动回滚到了原样;没有条目文件被扣下。',
681
734
  'notice.memory.harvestQuarantined.indexAlso': '记忆索引也已回滚。',
@@ -708,6 +761,29 @@ const ZH = {
708
761
  'notice.peer.inbound.resupplyExhausted': '{subject}:模型可能从未读到它 —— 上下文压缩两次把它从模型的上下文里丢掉,发送方也没有被告知。',
709
762
  'notice.peer.inbound.other': '{subject}:本版本认不出引擎报告的处置方式。',
710
763
  'notice.peer.inbound.cause': '原因:{cause}。',
764
+ 'notice.sessionBox.peer.another': '另一个会话',
765
+ 'notice.sessionBox.peer.anotherStart': '另一个会话',
766
+ 'notice.sessionBox.inbox.one': '有 1 条跨会话消息待读',
767
+ 'notice.sessionBox.inbox.many': '有 {pending} 条跨会话消息待读',
768
+ 'notice.sessionBox.inbox.urgent': '(其中 {urgent} 条紧急)',
769
+ 'notice.sessionBox.inbox.resupplied': '(补投 {resupplied} 条)',
770
+ 'notice.sessionBox.delivery.delivered': '你发给 {peer} 的消息已送达。',
771
+ 'notice.sessionBox.delivery.held': '你发给 {peer} 的消息正在等待对方会话批准。',
772
+ 'notice.sessionBox.delivery.heldByPolicy': '你发给 {peer} 的消息被对方会话自身的设置暂扣,对方没有人被请求批准它。',
773
+ 'notice.sessionBox.delivery.denied': '你发给 {peer} 的消息被对方会话拒绝了。',
774
+ 'notice.sessionBox.delivery.refused': '{peer} 不接收跨会话消息,你的消息没有送达。',
775
+ 'notice.sessionBox.delivery.expired': '你发给 {peer} 的消息在获批前已过期。',
776
+ 'notice.sessionBox.delivery.dropped': '你发给 {peer} 的消息被丢弃了({reason})。',
777
+ 'notice.sessionBox.delivery.droppedPlain': '你发给 {peer} 的消息被丢弃了。',
778
+ 'notice.sessionBox.delivery.other': '你发给 {peer} 的消息有新的投递状态。',
779
+ 'notice.sessionBox.idle.finished': '{peer} 已结束本轮。',
780
+ 'notice.sessionBox.idle.finishedDetail': '{peer} 已结束本轮:{detail}',
781
+ 'notice.sessionBox.idle.exited': '{peer} 已退出。',
782
+ 'notice.sessionBox.idle.unavailable': '{peer} 不可用。',
783
+ 'notice.sessionBox.idle.expired': '{peer} 在等待结束前没有应答。',
784
+ 'notice.sessionBox.idle.other': '{peer} 有新的状态通知。',
785
+ 'notice.resupply.truncated.one': '这条通知已精简:完整记录有 {bytes} 字节,超过通知大小上限,省略了 1 个字段。完整内容仍可在运行记录里查看。',
786
+ 'notice.resupply.truncated.other': '这条通知已精简:完整记录有 {bytes} 字节,超过通知大小上限,省略了 {count} 个字段。完整内容仍可在运行记录里查看。',
711
787
  'notice.peer.held.deliveredApproved': '{subject} 已获批准并送达。',
712
788
  'notice.peer.held.deliveredRejudged': '{subject} 经重新判断后送达,因为策略现在接受它。',
713
789
  'notice.peer.held.droppedRejudged': '{subject} 曾获批准,但策略现在拒绝它,所以被丢弃了。',
@@ -736,6 +812,7 @@ const ZH = {
736
812
  'notice.task.lateApproval': '你对"{tool}"的批准没有被采用:一次运行或回合中断在你的决定落地之前就放掉了这个请求,所以这个工具没有运行,你的答复也没有结算任何东西。这只是时序上的事实,不是错误;如果还需要那一步,请再问一次。',
737
813
  'notice.task.haltUnconsumed': '你的停止请求没有切断任何东西:它到达时这次运行已经因自身原因在收尾,所以它没有停下任何东西,以这次运行自己的结局为准。',
738
814
  'notice.steering.parkedInputBlocked': '你在这次运行暂停期间发出的一条指令,在运行恢复时被拦下了:这套部署的输入筛查把它扣住,所以它没有到达模型。如果仍然适用,请再发一次。',
815
+ 'notice.model.capabilityDowngraded.image': '这段对话里的图片没有发给 {model}:它的目录条目声明了不收图片输入,所以每张图只以一行占位说明的形式到达它。如果它其实能看图,请在该模型条目里声明(input: ["text", "image"]);否则请换一个能看图的模型。',
739
816
  'rules.refusal.sentence.one': '权限:有 1 条规则不会被执行 —— {list}',
740
817
  'rules.refusal.sentence.other': '权限:有 {count} 条规则不会被执行 —— {list}',
741
818
  'rules.refusal.item': '{rule}({reason})',
@@ -818,6 +895,10 @@ const ZH = {
818
895
  'session.steerRefusal.advice': '{happened} —— {nextStep}',
819
896
  'session.steerRefusal.hostQueue.queued': '它留在队列里,在这个 turn 结束时会原样提交',
820
897
  'session.steerRefusal.hostQueue.dropped': '它没有被保留;{nextStep}',
898
+ 'session.interruptRefusal.nothingInFlight': '这次打断没有被接受:这条 run 正在等待一个待决的决定,所以没有在飞的一轮可以切 · run 本身没有变化,仍在等待 · 要结束它,请停止整条 run;要给它留一条消息,直接发送 —— 消息会在 run 继续时送达',
899
+ 'session.interruptRefusal.notHeld': '这次打断没有被接受:这台服务器上没有这条 run 可以切的在飞一轮 —— 这条 run 可能在另一台服务器上运行,或走的是没有在飞一轮的路径 · run 本身没有变化 · 要结束它,请停止整条 run',
900
+ 'session.interruptRefusal.notRunning': '这次打断没有被接受:这条 run 已经不在运行 —— 它刚刚结束,或已不再接受打断 · 没有切掉任何东西,也没有改变任何东西 · 动手之前先看一下它当前的状态',
901
+ 'session.interruptRefusal.unrecognised': '这次打断没有被接受,原因这一版认不出来 · 不要假定这条 run 已经停了,或有哪一轮被切掉了 · 请看一下它当前的状态;如果反复出现,请反馈错误码(如果引擎给了的话)',
821
902
  'session.permissionModeSwitch.applied': '正在跑的这一轮现在用 {mode} 权限模式。',
822
903
  'session.permissionModeSwitch.folded': '正在跑的这一轮现在用 {mode} 权限模式,不是你选的那一档 —— {reason}。',
823
904
  'session.permissionModeSwitch.reason.entryFloor': '这台部署不允许比它的下限更宽松的模式',
@@ -860,6 +941,20 @@ const ZH = {
860
941
  'notice.capability.mcpProbe.notReported': '这台引擎没有报告逐服务器 MCP 状态面 —— 这说不清这个面在不在,所以这条路在这里可能并不存在(直接问它,可能得到机读的「路由不存在」答复,但超时或不带码的网关答复两头都说明不了什么);有会话面板的末腿名册时优先用它,否则就把这个原因摆出来,而不是摆一个答不了的入口',
861
942
  'notice.capability.mcpProbe.absent': '逐服务器 MCP 状态面在这个部署上报告为关 —— 这台引擎在那里不回答任何读数;本端不猜原因,而调用方自带的声明会不会被认,是另一位独立的问题、有它自己的答案',
862
943
  'notice.capability.mcpProbe.present': '逐服务器 MCP 状态面已开启 —— 这台引擎按请求去连它自己声明的 MCP 服务器,不需要 run,而对调用方自带声明的探测会答回同一种体形',
944
+ 'notice.capability.subject.storePosture': '存储姿态',
945
+ 'notice.capability.storePosture.unobserved': '存储姿态没有观测到 —— 引擎在 /v1/capabilities 上报它;本进程没有缓存可用的能力读数,所以这个部署持不持久化状态是未知的',
946
+ 'notice.capability.storePosture.notReported': '这台引擎没有报告存储姿态;这说明不了这个部署持不持久化状态',
947
+ 'notice.capability.storePosture.assembled': '存储 {backend}',
948
+ 'notice.capability.storePosture.assembledDeclared': '存储声明为 {declared},实际运行在 {backend} 上',
949
+ 'notice.capability.storePosture.durable': '{assembled} —— 持久:这台副本会持久化它的状态,重启之后仍在',
950
+ 'notice.capability.storePosture.notDurableHead': '不持久',
951
+ 'notice.capability.storePosture.memory': '{assembled} —— {head}:这台副本把状态放在内存里,重启就会丢',
952
+ 'notice.capability.storePosture.ephemeral': '{assembled} —— {head}:引擎报告这台副本有状态放在重启后留不下来的存储上',
953
+ 'notice.capability.storePosture.unknown': '{assembled} —— 持久性未知:引擎报告它判断不了这台副本的状态重启之后还在不在',
954
+ 'notice.capability.storePosture.unrecognized': '{assembled} —— 持久性未知:引擎报了一个本端还不认识的持久性词:"{word}"',
955
+ 'notice.capability.storePosture.degraded.dbUnreachable': '{line}(降级:声明的数据库在启动时打不开,所以引擎退回了,而不是拒绝启动)',
956
+ 'notice.capability.storePosture.degraded.localUnwritable': '{line}(降级:默认的本地文件存储建不起来 —— 数据目录只读或写满是一种可能的原因,本端分不出是哪一种)',
957
+ 'notice.capability.storePosture.degraded.other': '{line}(降级,原因本端还不认识:"{reason}")',
863
958
  'notice.capability.hands.noneStem': '这条 run 腿装配时没有任何内置的文件与 shell 工具',
864
959
  'notice.capability.hands.noneTail': '所以在这条腿上,模型没有引擎自己的、用来改文件或跑命令的工具(由别的条件挂载的工具,例如外部服务器,以及委派给别的腿的子 run,不在这一读数的范围内)',
865
960
  'notice.capability.hands.noneLine': '{stem} —— {why},{tail}',
@@ -954,6 +1049,8 @@ const ZH = {
954
1049
  'notice.failure.headline.parked': '事件流结束时这次 run 还没到终态 —— 这次 run 很可能是 parked 在等一个决断,而不是崩溃了。请查看它的状态并处理待决的事项;这个 turn 没有在这里完成。',
955
1050
  'notice.failure.headline.internal': '这个客户端遇到了内部错误 —— 这是客户端的 bug,不是引擎故障,这个 turn 没有完成。',
956
1051
  'notice.failure.headline.causeUnreadable': '这次失败的原因读不出(错误对象有一部分不可读)—— 不知道引擎是否收到了你的消息。重新发送之前,请先查看这次 run 的状态,或者重新接上它。',
1052
+ 'notice.streamEnded.emptyLegs.headline': '事件流连着两次打开都没收到任何内容,结束时这次 run 还没到终态 —— 这次 run 很可能是 parked 在等一个决断,而不是崩溃了。请查看它的状态并处理待决的事项;这个 turn 没有在这里完成。',
1053
+ 'notice.streamEnded.consecutiveFailures.headline': '事件流一直断在没有进展的地方,客户端已经不再重新打开它 —— 不知道这次 run 是仍在运行,还是在等一个决断。重新发送之前,请先查看它的状态,或者重新接上它;这个 turn 没有在这里完成。',
957
1054
  'notice.failure.quota.fiveHour': '你的 5 小时额度已用完',
958
1055
  'notice.failure.quota.weekly': '你的每周额度已用完',
959
1056
  'notice.failure.quota.budgetPersonal': '你的个人预算已用完',
@@ -1108,6 +1205,16 @@ const ZH = {
1108
1205
  'notice.wireRefusal.sessionIdRetired.folded': '这件停驻的工作无法继续:它的会话 id 属于这台服务端上一只已删除的会话,这个 id 下的工作现在只为那只会话原来的属主运行;什么都没有续跑,这张卡仍在等待',
1109
1206
  'notice.wireRefusal.runConcurrencyCap.head': '这个部署在飞的运行已达到它允许的数量,所以引擎没有受理这个请求 · 请求本身没有任何问题',
1110
1207
  'notice.wireRefusal.runConcurrencyCap.unknownWait': '请等在飞的运行有一条结束后再发送',
1208
+ 'notice.wireRefusal.unreadMembers': '引擎没有受理这个请求:它带着{part},这个版本的服务端读不出原样的写法,照它跑会悄悄把这一部分漏掉',
1209
+ 'notice.wireRefusal.unreadMembers.folded': '这件停驻的工作无法继续:为它保存的请求带着{part},这个版本的服务端读不出原样的写法,续跑会悄悄把这一部分漏掉;什么都没有续跑,这张卡仍在等待',
1210
+ 'notice.wireRefusal.unreadMembers.where': '位置:{where}',
1211
+ 'notice.wireRefusal.unreadMembers.remedy': '请把这一部分改成当前的写法后重新发送请求',
1212
+ 'notice.wireRefusal.unreadMembers.folded.remedy': '若这件工作仍停驻着,请先取消它,然后作为新请求重新提交,并把这一部分改成当前的写法',
1213
+ 'notice.wireRefusal.unreadMembers.part.settingsHooks': '钩子设置',
1214
+ 'notice.wireRefusal.unreadMembers.part.settingsEnv': '环境变量',
1215
+ 'notice.wireRefusal.unreadMembers.part.settingsOther': '一项设置',
1216
+ 'notice.wireRefusal.unreadMembers.part.mcpTransport': '某个 MCP 服务的连接设置',
1217
+ 'notice.wireRefusal.unreadMembers.part.a2aHeaders': '某个 A2A 对端的请求头',
1111
1218
  'notice.wireRefusal.unsupportedRule': '引擎拒绝了这个请求,所以其中任何内容都没有生效:里面有一条规则是引擎不支持的写法 —— {detail} · 请删掉或改写那条规则(要整只拦下一个工具,请只写工具名),再重新发送',
1112
1219
  'notice.wireRefusal.unsupportedRule.other': '引擎拒绝了这个请求,所以其中任何内容都没有生效:里面有 {count} 条规则是引擎不支持的写法 —— {detail} · 请删掉或改写这些规则(要整只拦下一个工具,请只写工具名),再重新发送',
1113
1220
  'notice.wireRefusal.unsupportedRule.stored': '引擎拒绝继续这件工作:为它保存的请求里有一条规则是引擎不支持的写法 —— {detail} · 它无法按保存的样子继续。请删掉或改写那条规则(要整只拦下一个工具,请只写工具名);若这件工作仍停驻着,请先取消它,然后作为新请求重新提交',
@@ -1169,15 +1276,21 @@ const ZH = {
1169
1276
  'session.subagent.delegatedPrompt.absence.forbidden': '这个子代的 prompt 显示不了:引擎不允许读取它的对话。',
1170
1277
  'session.subagent.delegatedPrompt.absence.promptAbsent': '读到了这个子代的对话,但里面没有可显示的委派 prompt。',
1171
1278
  'session.subagent.delegatedPrompt.absence.unknown': '这个子代的 prompt 这次读取不到。',
1279
+ 'rules.sessionPolicy.remove.loosenForbiddenStem': '引擎拒绝把这些条目从这个会话的规则记录里拿掉,所以记录没有变:引擎把其中至少一条算作运维方写下的、而不是会话属主自己加的,而属主只能撤自己加的条目。',
1280
+ 'rules.sessionPolicy.remove.loosenForbidden': '{stem}请让运维方来撤,或者在新会话里继续。',
1172
1281
  'rules.sessionPolicy.tighten.unknown.sessionOwnerless.noIdentity': '这个会话没有属主,为它写的规则之后永远读不回来;没有写入任何内容。',
1173
1282
  'rules.sessionPolicy.tighten.unknown.storeCorrupt.noOperator': '引擎确认不了这个会话的规则当前在哪一版,拒绝盖新版本,所以没有写入任何内容。送去的条目没有问题 —— 这台部署没有运维方可以查看规则库,要由运行它的人处理。',
1174
1283
  'rules.sessionPolicy.deployment.noOperator.readStoreCorrupt': '引擎确认不了这个会话的规则当前在哪一版,所以没有交出这份记录。这台部署没有运维方可以查看规则库,要由运行它的人处理。',
1175
- 'rules.sessionPolicy.deployment.noOperator.removeLoosenForbidden': '引擎拒绝把这些条目从这个会话的规则记录里拿掉:这台引擎上只有运维方能从里面删条目,而这台部署没有运维方,所以记录没有变。请在新会话里继续。',
1284
+ 'rules.sessionPolicy.deployment.noOperator.removeLoosenForbidden': '{stem}这台部署没有运维方来撤。请在新会话里继续。',
1176
1285
  'rules.sessionPolicy.deployment.noOperator.removeReadStoreCorrupt': '引擎确认不了这个会话的规则当前在哪一版,所以没有改动任何内容。这台部署没有运维方可以查看规则库,要由运行它的人处理。',
1177
1286
  'rules.sessionPolicy.deployment.noOperator.removeWriteStoreCorrupt': '引擎确认不了这个会话的规则当前在哪一版,拒绝盖新版本,所以没有改动任何内容。这台部署没有运维方可以查看规则库,要由运行它的人处理。',
1178
1287
  'config.hooks.plan.reason.compactionLocalFallback': '这一次压缩的摘要因引擎会话不可用而在本客户端本地生成,引擎不会替它运行这只 hook,所以由本客户端自己运行',
1179
1288
  'config.hooks.plan.reason.keyNotRead': '所连服务端不读这只 hook 上写的某个键(删掉该键,或改用会读它的服务端)',
1180
1289
  'config.hooks.plan.disableAllHooks': '托管设置关闭了全部 hooks(disableAllHooks)。',
1290
+ 'config.hooks.plan.reason.closedUntrusted': '这个工作区未受信任,所以其中不运行任何 hook',
1291
+ 'config.hooks.plan.reason.closedGovernanceUnreadable': '托管策略读不出来,所以这一回合不运行任何 hook',
1292
+ 'config.hooks.plan.reason.closedDisableAll': '托管设置关闭了全部 hooks(disableAllHooks)',
1293
+ 'config.hooks.plan.reason.noExecutor': '引擎和本客户端都不运行这个事件',
1181
1294
  'config.hooks.plan.keyNotRead.oneKey': '{layer}:{hooks} 不会运行 —— 所连服务端不读键 {coordinates}。删掉该键,或改用会读它的服务端。',
1182
1295
  'config.hooks.plan.keyNotRead.manyKeys': '{layer}:{hooks} 不会运行 —— 所连服务端不读这些键:{coordinates}。删掉这些键,或改用会读它们的服务端。',
1183
1296
  'config.hooks.plan.keyNotRead.more': '{shown} 等另 {rest} 处',
@@ -1224,8 +1337,13 @@ const ZH = {
1224
1337
  'config.mods.loader.failed': '{name} 装载失败:{reason}',
1225
1338
  'config.mods.loader.failedNoReason': '{name} 装载失败',
1226
1339
  'config.mods.refusal.by': '被 {by} 拒绝',
1340
+ 'config.mods.request.by': '由 {by} 发起',
1227
1341
  'config.mods.rewrite.resultInPlace': '由 {by} 代替工具作答',
1228
1342
  'config.mods.rewrite.inputBy': '参数在放行前被 {by} 改过',
1343
+ 'config.mods.session.unreadable': '读不出这个对话最近一次运行用了哪些 mod',
1344
+ 'config.mods.session.unarmed': '这个对话在当前引擎上运行过之后,这里会显示 mod',
1345
+ 'config.hooks.roster.unreadable': '读不出这个对话的 hooks 计划',
1346
+ 'config.hooks.roster.unarmed': '这个应用打开这个对话之后,这里会显示 hooks',
1229
1347
  'follow.notFollowed.headRun': '这块屏已不再跟着 run {taskId}{reason}{ending}{exit}',
1230
1348
  'follow.notFollowed.headTurn': '这块屏已不再跟着这一轮的 run{reason}{ending}{exit}',
1231
1349
  'follow.notFollowed.reason.exhaustedDraining': ':服务它的那台引擎实例在它最后一条事件流关闭时正在下线,而这个客户端的重新附着次数已经用完。',
@@ -1311,6 +1429,7 @@ const ZH = {
1311
1429
  'localEngine.down.spawnRefused': '本机引擎没有启动:启动前的准备没有通过。',
1312
1430
  'localEngine.down.stopFailed': '旧的本机引擎没有按时停下,所以没有更换。',
1313
1431
  'localEngine.down.crashLoop': '本机引擎反复意外停止,自动重启已暂停。',
1432
+ 'localEngine.down.exitedOnce': '本机引擎启动后已退出,Sema 不会自动重新启动它。',
1314
1433
  'localEngine.down.highWaterUnreadable': '读不出这台机器上用过的最新引擎版本记录,本机引擎不启动;请检查引擎数据目录。',
1315
1434
  'localEngine.crashLoop.retry': '本机引擎反复意外停止;约 {seconds} 秒后再试一次。',
1316
1435
  'localEngine.crashLoop.stopped': '本机引擎反复意外停止;Sema 已不再自动重试,请手动重启。',
@@ -1337,10 +1456,113 @@ const ZH = {
1337
1456
  'localEngine.restartOutcome.pendingBusy': '有别的会话在用本机引擎;没人用时就重启。',
1338
1457
  'localEngine.restartOutcome.failedPrepare': '本机引擎没有重启;当前引擎照常运行。',
1339
1458
  'localEngine.restartOutcome.failedDown': '本机引擎没能重启:{detail}',
1459
+ 'localEngine.swapGuard.newer': '本机引擎(版本 {running})是比这个 Sema({own})更新的 Sema 启动的,Sema 让它继续运行,不用更旧的引擎替换它。',
1460
+ 'localEngine.swapGuard.newer.highWater': '这台机器的本机引擎数据上次由更新的 Sema(引擎版本 {running})用过,比这个 Sema({own})新,Sema 不会在上面启动更旧的引擎。',
1461
+ 'localEngine.swapGuard.newer.cliUpdate': '要让改动生效,请运行 `sema update`。',
1462
+ 'localEngine.swapGuard.newer.appUpdate': '要让改动生效,请更新本应用。',
1463
+ 'localEngine.swapGuard.hold': '本机引擎暂不替换:仍在等待的工作换引擎后可能无法继续。',
1464
+ 'localEngine.swapGuard.unknown': 'Sema 无法判断在跑的本机引擎是否比这个 Sema 新,未经你确认不会替换它。',
1465
+ 'localEngine.swapGuard.parked.one': '有一张审批卡仍在等待回答。',
1466
+ 'localEngine.swapGuard.parked.oneSession': '有 {count} 张审批卡仍在同一个会话里等待回答。',
1467
+ 'localEngine.swapGuard.parked.manySessions': '有 {count} 张审批卡仍在 {sessions} 个会话里等待回答。',
1468
+ 'localEngine.swapGuard.parked.failed': '读不出是否还有审批卡在等待回答。',
1469
+ 'localEngine.swapGuard.parked.unsupported': '这台引擎读不到是否还有审批卡在等待回答。',
1470
+ 'localEngine.swapGuard.wayOut.interactive': '请先回答等待中的卡,或确认后立即替换引擎。',
1471
+ 'localEngine.swapGuard.wayOut.print': '本次命令继续使用当前引擎;请以交互方式打开 Sema 回答等待中的卡或替换引擎。',
1472
+ 'localEngine.swapGuard.told.one': '本机引擎已替换;之前仍在等待的那张审批卡可能无法再回答。如果它提示无法继续,请重新发送那一轮。',
1473
+ 'localEngine.swapGuard.told.other': '本机引擎已替换;之前仍在等待的 {count} 张审批卡可能无法再回答。如果某张提示无法继续,请重新发送那一轮。',
1474
+ 'localEngine.swapGuard.told.unknown': '本机引擎已替换;之前若有仍在等待的审批卡,可能无法再回答。如果某张提示无法继续,请重新发送那一轮。',
1475
+ 'engine.unavailable.line': '[sema] engine-fatal · {tag} — {head},本会话的任何内容都到不了模型:{detail}。{fix}',
1476
+ 'engine.unavailable.lineNoDetail': '[sema] engine-fatal · {tag} — {head},本会话的任何内容都到不了模型。{fix}',
1477
+ 'engine.unavailable.lineNoFix': '[sema] engine-fatal · {tag} — {head},本会话的任何内容都到不了模型:{detail}',
1478
+ 'engine.unavailable.lineBare': '[sema] engine-fatal · {tag} — {head},本会话的任何内容都到不了模型。',
1479
+ 'engine.unavailable.lineRefusedUse': '[sema] engine-fatal · {tag} — {head},本会话没有向模型发出任何内容:{detail}',
1480
+ 'engine.unavailable.lineRefusedUseNoDetail': '[sema] engine-fatal · {tag} — {head},本会话没有向模型发出任何内容。',
1481
+ 'engine.unavailable.head.notRunning': 'sema 引擎没有在运行',
1482
+ 'engine.unavailable.head.refused': 'sema 引擎拒绝启动',
1483
+ 'engine.unavailable.head.notAnswering': 'sema 引擎没有应答',
1484
+ 'engine.unavailable.head.noHealthyAnswer': 'sema 引擎一直没有给出健康应答',
1485
+ 'engine.unavailable.head.drainStuck': '上一台 sema 引擎还没停完',
1486
+ 'engine.unavailable.head.addressRefused': 'sema 没有连接 SEMA_ENGINE_URL 指定的引擎',
1487
+ 'engine.unavailable.head.versionRefused': '有一台引擎在运行,但这个 sema 拒绝使用它',
1488
+ 'engine.unavailable.head.unknown': 'sema 引擎不可用',
1489
+ 'engine.unavailable.again.session': '重新启动 sema',
1490
+ 'engine.unavailable.again.command': '重新运行这条命令',
1491
+ 'engine.unavailable.again.app': '重新打开本应用',
1492
+ 'engine.unavailable.retry.session': '重启 sema 再试',
1493
+ 'engine.unavailable.retry.command': '重新运行这条命令再试',
1494
+ 'engine.unavailable.fix.diagnose': '出路:运行 `sema doctor` 诊断,或{retry}。',
1495
+ 'engine.unavailable.fix.modelSetup': '出路:运行 `sema onboard` 把模型配置补完,然后{again}。',
1496
+ 'engine.unavailable.fix.credentialConflict': '出路:两把凭据去掉一把,留下你的端点要的那一把,然后{again}。',
1497
+ 'engine.unavailable.fix.credentialMalformed': '出路:运行 `sema cloud login` 重新登录(它会重写 sema 管理的那只文件),或运行 `sema cloud logout` 不再使用它;如果 {tokenFile} 是你自己设的,修好那只文件。然后{again}。',
1498
+ 'engine.unavailable.fix.credentialMultiTenant': '出路:把工作节点拉取令牌交给引擎({token},或在 {tokenFile} 指向的文件里写一行令牌),或去掉 REQUIRE_PRINCIPAL 改成单用户引擎,然后{again}。',
1499
+ 'engine.unavailable.fix.credential': '出路:改正引擎点名的那份登录凭据,然后{again}。',
1500
+ 'engine.unavailable.wait.respond': '等它应答',
1501
+ 'engine.unavailable.wait.healthy': '等它给出健康应答',
1502
+ 'engine.unavailable.wait.exit': '等它退出',
1503
+ 'engine.unavailable.fix.waitPid': '出路:{wait}后{again},或自己停掉它(kill {pid})后{again}。',
1504
+ 'engine.unavailable.fix.wait': '出路:{wait}后{again},或自己停掉那台引擎进程后{again}。',
1505
+ 'engine.bootRefusal.withWaysOut': '本机引擎拒绝启动:{reason} {waysOut}',
1506
+ 'engine.bootRefusal.withFix': '本机引擎拒绝启动:{reason} {fix}',
1507
+ 'engine.bootRefusal.waysOut': '出路:(1){newer} —— {separate};(2){restore};(3){repair}。',
1508
+ 'engine.bootRefusal.who.sema': '更新的 sema',
1509
+ 'engine.bootRefusal.who.semaAtLeast': '更新的 sema(它的引擎是 {version} 或更新的版本)',
1510
+ 'engine.bootRefusal.who.app': '本应用更新的版本',
1511
+ 'engine.bootRefusal.who.appAtLeast': '本应用更新的版本(它的引擎是 {version} 或更新的版本)',
1512
+ 'engine.bootRefusal.who.build': '更新的构建',
1513
+ 'engine.bootRefusal.who.buildAtLeast': '更新的构建(引擎 {version} 或更新)',
1514
+ 'engine.bootRefusal.newer.update': '{who}用过这个数据文件夹:用 `sema update` 更新这个 sema 后{again},或重新启动那个更新的 sema',
1515
+ 'engine.bootRefusal.newer.projectLocal': '{who}用过这个数据文件夹:在装它的那个项目里更新这份 sema,然后{again};或重新启动那个更新的 sema',
1516
+ 'engine.bootRefusal.newer.devTree': '{who}用过这个数据文件夹:把这份源码检出切到更新的构建,然后{again};或重新启动那个更新的 sema',
1517
+ 'engine.bootRefusal.newer.app': '{who}用过这个数据文件夹:更新本应用,或重新启动那个更新的版本',
1518
+ 'engine.bootRefusal.newer.unknown': '{who}用过这个数据文件夹:重新启动那个更新的 sema',
1519
+ 'engine.bootRefusal.newer.deployment': '{who}写过这个数据根:部署那份构建',
1520
+ 'engine.bootRefusal.separate.embedded': '要在这台电脑上继续用这个 sema,就给它单独的配置文件夹启动:`{key}=<another-folder> sema`(启动后没有你的设置和会话)',
1521
+ 'engine.bootRefusal.separate.app': '要继续用这个版本,就给它单独的配置文件夹启动(`{key}=<another-folder>`);启动后没有你的设置和会话',
1522
+ 'engine.bootRefusal.separate.deployment': '要在这台机器上运行这份较旧的构建,给它单独的数据根(LOCAL_DATA_ROOT)',
1523
+ 'engine.bootRefusal.restore': '放回 {folder} 在更新的引擎第一次打开它之前的副本,然后{again}(上面点名的文件损坏时也走这条;副本之后的改动会丢)',
1524
+ 'engine.bootRefusal.restoreDeployment': '恢复升级前做的数据根备份,然后启动这份构建(上面点名的文件损坏时也走这条)',
1525
+ 'engine.bootRefusal.folder.default': '你的 sema 配置文件夹里的 engine-data 文件夹',
1526
+ 'engine.bootRefusal.repair': '如果上面点名的文件根本读不了(EACCES 一类的 I/O 错误),修好它的访问(权限、磁盘)后{again}',
1527
+ 'engine.bootRefusal.repairDeployment': '如果上面点名的文件根本读不了(EACCES 一类的 I/O 错误),修好它的访问(权限、挂载、磁盘)后重启',
1528
+ 'session.devices.repoint.done': '已改指:这台机器的设备档和会话现在跟着新的引擎地址走。设备身份没变 —— 没有重新注册。',
1529
+ 'session.devices.repoint.unverified': '什么都没改:确认不了新地址上有这台设备。如果它就是同一台引擎,请确认你是用这台设备所属账号登录的,然后再试一次;否则请到引擎自己的地址重新注册这台机器,再到引擎的设备列表里移除旧设备。',
1530
+ 'session.devices.repoint.undetermined': '什么都没改:对新地址的一项核对没读到结果,所以不知道这台设备是否登记在那边。请再试一次;或者到引擎自己的地址重新注册这台机器,再到引擎的设备列表里移除旧设备。',
1531
+ 'session.devices.repoint.partial': '设备档已跟着新地址走,但不是每只会话都改成了。再运行一次同样的命令即可补完 —— 已改好的会话不会再动。',
1532
+ 'session.devices.repoint.storeFailed': '设备档没能确认迁过去,会话都没有动。请再运行一次同样的命令;一直失败的话,到引擎自己的地址重新注册这台机器。',
1533
+ 'session.devices.repoint.refused.addressInvalid': '什么都没改:有一个地址用不了。请给引擎完整的 https:// 地址(明文 http:// 只收本机地址)。',
1534
+ 'session.devices.repoint.refused.sameAddress': '什么都没改:新地址和旧地址是同一个引擎地址。',
1535
+ 'session.devices.repoint.refused.recordAbsent': '什么都没改:这台机器上没有旧地址对应的设备档。',
1536
+ 'session.devices.repoint.refused.recordNotActive': '什么都没改:这个地址上的设备档不是已完成的注册(还在注册中,或设备已被移除)。请到引擎自己的地址重新注册。',
1537
+ 'session.devices.repoint.refused.recordUnreadable': '什么都没改:有一份设备档读不了,所以原样没动。',
1538
+ 'session.devices.repoint.refused.targetOccupied': '什么都没改:这台机器在新地址上已经有一份不同设备的设备档。',
1539
+ 'session.devices.repoint.refused.unarmed': '什么都没改:这个应用没有接好迁移设备档和会话的能力。',
1540
+ 'session.devices.repoint.refused.rosterUnbound': '什么都没改:这个应用没有接好新地址上的设备列表,所以无法核对这次迁移。这是应用自己的接线问题,再试一次也不会好。',
1541
+ 'attachments.withheld.toolsElsewhere.row': '这个会话的工具不读写这台机器上的文件',
1542
+ 'attachments.withheld.toolsLocationUnconfirmed.row': '无法确认这个会话的工具读写的是这台机器上的文件',
1543
+ 'attachments.withheld.toolsElsewhere.model': '这个会话的工具不读写客户端所在机器上的文件,所以客户端没有附上那台机器上的副本;它可能与工具读写的文件不同,文件也可能只存在于工具运行的地方',
1544
+ 'attachments.withheld.toolsLocationUnconfirmed.model': '客户端无法确认这个会话的工具读写的是它所在机器上的文件,所以没有附上那台机器上的副本;它可能与工具读写的文件不同,文件也可能只存在于工具运行的地方',
1545
+ 'attachments.localCopy.model': '这是用户从客户端所在机器上交来的内容:它是那台机器上的副本,随附的路径也是那台机器上的路径。这个会话的工具未必读写那台机器上的文件,所以工具读写的文件可能不同,也可能不存在。',
1546
+ 'session.compaction.canceled': '压缩已取消。',
1547
+ 'localEngine.health.answer.unansweredTimeout': '没有在时限内应答',
1548
+ 'localEngine.health.answer.unansweredNetwork': '连不上',
1549
+ 'localEngine.health.answer.ok': '应答了,状态为 "ok"',
1550
+ 'localEngine.health.answer.notOkHttp': '应答了 HTTP {http}',
1551
+ 'localEngine.health.answer.notOkStatus': '应答了 HTTP {http},但状态不是 "ok"',
1340
1552
  };
1341
1553
  export const ZH_MESSAGES = Object.freeze(ZH);
1342
1554
  export const TERM_SLOTS = Object.freeze({
1343
1555
  'session.background.refusal.envOff': ['SEMA_HEADLESS_DETACH'],
1556
+ 'approval.policyDeny.hook': ['PermissionRequest'],
1557
+ 'session.mcpReconnect.unsupported': ['MCP'],
1558
+ 'session.mcpReconnect.accepted.one': ['MCP'],
1559
+ 'session.mcpReconnect.accepted.other': ['MCP'],
1560
+ 'session.mcpReconnect.refused.untouched': ['MCP'],
1561
+ 'session.mcpReconnect.refused.noTools': ['MCP'],
1562
+ 'session.mcpReconnect.refused.listed.one': ['MCP'],
1563
+ 'session.mcpReconnect.refused.listed.other': ['MCP'],
1564
+ 'session.mcpReconnect.undeclared': ['MCP'],
1565
+ 'session.mcpReconnect.unsettled': ['MCP'],
1344
1566
  'session.permissionModeSwitch.reason.disableAutoMode': ['auto'],
1345
1567
  'session.thinking.offWithUltracodeOnBody': ['Ultracode'],
1346
1568
  'config.mcp.toolAxesInvalid': ['toolAxes'],
@@ -1439,6 +1661,12 @@ export const TERM_SLOTS = Object.freeze({
1439
1661
  'session.selfHeal.row.attach': ['run'],
1440
1662
  'session.selfHeal.row.cancelled.confirmed': ['run'],
1441
1663
  'session.selfHeal.row.cancelled.reported': ['run'],
1664
+ 'session.selfHeal.row.resendWithheldLeft.confirmed': ['run'],
1665
+ 'session.selfHeal.row.resendWithheldLeft.reported': ['run'],
1666
+ 'session.selfHeal.stopLeft.untouched': ['run'],
1667
+ 'session.selfHeal.stopLeft.waiting.certain': ['run'],
1668
+ 'session.selfHeal.stopLeft.refused': ['run'],
1669
+ 'session.selfHeal.stopLeft.notConfirmed': ['run'],
1442
1670
  'session.selfHeal.row.cancelTimeout.aborted': ['run'],
1443
1671
  'session.selfHeal.row.cancelTimeout.unread': ['run'],
1444
1672
  'session.selfHeal.row.cancelTimeout.held': ['run'],
@@ -1495,6 +1723,8 @@ export const TERM_SLOTS = Object.freeze({
1495
1723
  'notice.failure.headline.connectionLost': ['run'],
1496
1724
  'notice.failure.headline.timeout': ['run'],
1497
1725
  'notice.failure.headline.parked': ['parked', 'run', 'turn'],
1726
+ 'notice.streamEnded.emptyLegs.headline': ['parked', 'run', 'turn'],
1727
+ 'notice.streamEnded.consecutiveFailures.headline': ['run', 'turn'],
1498
1728
  'notice.failure.headline.internal': ['turn'],
1499
1729
  'notice.failure.headline.causeUnreadable': ['run'],
1500
1730
  'notice.failure.settings.safety': ['turn'],
@@ -18,6 +18,9 @@ export type MissLedger = {
18
18
  };
19
19
  export declare function createMissLedger(): MissLedger;
20
20
  export declare const uiMissLedger: MissLedger;
21
+ export type MessageCatalogInstallOutcome = 'installed' | 'built_in' | 'unknown_language' | 'not_a_catalog' | 'conflict';
22
+ export declare function renderLanguageOf(lang: string | undefined): UiLanguage;
23
+ export declare function installMessageCatalog(lang: Exclude<UiLanguage, 'en'>, catalog: Readonly<Record<MessageKey, string>>): MessageCatalogInstallOutcome;
21
24
  export declare function translate(lang: UiLanguage, key: string, params?: MessageParams, ledger?: MissLedger): string;
22
25
  export declare function createTranslator(lang: UiLanguage, ledger?: MissLedger): Translator;
23
26
  export declare function msg(key: MessageKey, params?: MessageParams): MessageRef;
@@ -1,5 +1,4 @@
1
1
  import { EN_MESSAGES } from './messages.en.js';
2
- import { ZH_MESSAGES } from './messages.zh.js';
3
2
  import { isUiLanguage } from '../env/uiLanguage.js';
4
3
  export const DATA_FACE_LANGUAGE = 'en';
5
4
  export function createMissLedger() {
@@ -19,10 +18,70 @@ export function createMissLedger() {
19
18
  };
20
19
  }
21
20
  export const uiMissLedger = createMissLedger();
22
- const CATALOGS = Object.freeze({
23
- en: EN_MESSAGES,
24
- zh: ZH_MESSAGES,
25
- });
21
+ const installedCatalogs = new Map();
22
+ const announcedAbsentLanguages = new Set();
23
+ function tableOf(lang) {
24
+ return lang === 'en' ? EN_MESSAGES : installedCatalogs.get(lang)?.table;
25
+ }
26
+ export function renderLanguageOf(lang) {
27
+ return isUiLanguage(lang) && (lang === 'en' || installedCatalogs.has(lang)) ? lang : 'en';
28
+ }
29
+ function snapshotCatalog(catalog) {
30
+ try {
31
+ const table = Object.create(null);
32
+ let n = 0;
33
+ for (const key of Object.keys(catalog)) {
34
+ if (!Object.hasOwn(EN_MESSAGES, key))
35
+ continue;
36
+ const d = Object.getOwnPropertyDescriptor(catalog, key);
37
+ if (d === undefined || !Object.hasOwn(d, 'value') || typeof d.value !== 'string')
38
+ continue;
39
+ table[key] = d.value;
40
+ n++;
41
+ }
42
+ return n > 0 ? Object.freeze(table) : undefined;
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
48
+ export function installMessageCatalog(lang, catalog) {
49
+ const asked = lang;
50
+ if (!isUiLanguage(asked))
51
+ return 'unknown_language';
52
+ if (asked === 'en')
53
+ return 'built_in';
54
+ let isTable = false;
55
+ try {
56
+ isTable = catalog !== null && typeof catalog === 'object' && !Array.isArray(catalog);
57
+ }
58
+ catch {
59
+ isTable = false;
60
+ }
61
+ if (!isTable)
62
+ return 'not_a_catalog';
63
+ const held = installedCatalogs.get(asked);
64
+ if (held !== undefined)
65
+ return held.source === catalog ? 'installed' : 'conflict';
66
+ const table = snapshotCatalog(catalog);
67
+ if (table === undefined)
68
+ return 'not_a_catalog';
69
+ installedCatalogs.set(asked, Object.freeze({ source: catalog, table }));
70
+ return 'installed';
71
+ }
72
+ function announceAbsent(lang) {
73
+ if (announcedAbsentLanguages.has(lang))
74
+ return 'already_announced';
75
+ announcedAbsentLanguages.add(lang);
76
+ try {
77
+ console.error(`[client-core] message catalog "${lang}" is not installed — rendering English. ` +
78
+ `Install it once at startup: installMessageCatalog('${lang}', ${lang.toUpperCase()}_MESSAGES) with the catalog from '@sema-agent/client-core/i18n/${lang}'.`);
79
+ return 'announced';
80
+ }
81
+ catch {
82
+ return 'notice_failed';
83
+ }
84
+ }
26
85
  const UNKNOWN_LANGUAGE_ENTRY = 'lang:?';
27
86
  const PLACEHOLDER = /\{(\w+)\}/g;
28
87
  const MESSAGE_REF_MARK = Symbol.for('@sema-agent/client-core.MessageRef');
@@ -40,7 +99,10 @@ function isMintedRef(v) {
40
99
  function lookup(lang, key) {
41
100
  if (typeof key !== 'string')
42
101
  return undefined;
43
- const d = Object.getOwnPropertyDescriptor(CATALOGS[lang], key);
102
+ const table = tableOf(lang);
103
+ if (table === undefined)
104
+ return undefined;
105
+ const d = Object.getOwnPropertyDescriptor(table, key);
44
106
  return d !== undefined && Object.hasOwn(d, 'value') && typeof d.value === 'string' ? d.value : undefined;
45
107
  }
46
108
  function paramOf(params, name) {
@@ -64,10 +126,16 @@ function noteMiss(ledger, entry) {
64
126
  }
65
127
  }
66
128
  function languageOf(lang, ledger) {
67
- if (isUiLanguage(lang))
68
- return lang;
69
- noteMiss(ledger, UNKNOWN_LANGUAGE_ENTRY);
70
- return 'en';
129
+ if (!isUiLanguage(lang)) {
130
+ noteMiss(ledger, UNKNOWN_LANGUAGE_ENTRY);
131
+ return 'en';
132
+ }
133
+ const rendered = renderLanguageOf(lang);
134
+ if (rendered !== lang) {
135
+ noteMiss(ledger, `lang:${lang}`);
136
+ announceAbsent(lang);
137
+ }
138
+ return rendered;
71
139
  }
72
140
  const MAX_REF_DEPTH = 8;
73
141
  function interpolate(lang, template, key, params, ledger, depth) {
@@ -0,0 +1 @@
1
+ export { ZH_MESSAGES } from './messages.zh.js';
@@ -0,0 +1 @@
1
+ export { ZH_MESSAGES } from './messages.zh.js';