@jingyi0605/codingns4dsh 0.2.0-rc.3 → 0.2.1-beta.1

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 (377) hide show
  1. package/README.en.md +6 -6
  2. package/README.md +42 -29
  3. package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts +1 -1
  4. package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts.map +1 -1
  5. package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js +2 -2
  6. package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js.map +1 -1
  7. package/data/build/dist/bootstrap/index.d.ts +1 -1
  8. package/data/build/dist/bootstrap/index.d.ts.map +1 -1
  9. package/data/build/dist/client/bundle.js +3164 -181
  10. package/data/build/dist/client/bundle.js.map +1 -1
  11. package/data/build/dist/client/cli-catalog.d.ts +1 -1
  12. package/data/build/dist/client/cli-catalog.d.ts.map +1 -1
  13. package/data/build/dist/client/cli-catalog.js +3 -3
  14. package/data/build/dist/client/cli-catalog.js.map +1 -1
  15. package/data/build/dist/client/cli-slots.d.ts +4 -0
  16. package/data/build/dist/client/cli-slots.d.ts.map +1 -1
  17. package/data/build/dist/client/cli-slots.js +70 -9
  18. package/data/build/dist/client/cli-slots.js.map +1 -1
  19. package/data/build/dist/client/context-breakdown-dom.d.ts +1 -1
  20. package/data/build/dist/client/context-breakdown-dom.d.ts.map +1 -1
  21. package/data/build/dist/client/context-breakdown-dom.js +1 -1
  22. package/data/build/dist/client/context-breakdown-dom.js.map +1 -1
  23. package/data/build/dist/client/features/assistant-panel.d.ts +5 -0
  24. package/data/build/dist/client/features/assistant-panel.d.ts.map +1 -0
  25. package/data/build/dist/client/features/assistant-panel.js +127 -0
  26. package/data/build/dist/client/features/assistant-panel.js.map +1 -0
  27. package/data/build/dist/client/features/global-voice-assistant.d.ts +10 -0
  28. package/data/build/dist/client/features/global-voice-assistant.d.ts.map +1 -0
  29. package/data/build/dist/client/features/global-voice-assistant.js +330 -0
  30. package/data/build/dist/client/features/global-voice-assistant.js.map +1 -0
  31. package/data/build/dist/client/features/index.d.ts +2 -0
  32. package/data/build/dist/client/features/index.d.ts.map +1 -1
  33. package/data/build/dist/client/features/index.js +4 -0
  34. package/data/build/dist/client/features/index.js.map +1 -1
  35. package/data/build/dist/client/features/lan-access.d.ts.map +1 -1
  36. package/data/build/dist/client/features/lan-access.js +3 -1
  37. package/data/build/dist/client/features/lan-access.js.map +1 -1
  38. package/data/build/dist/client/features/types.d.ts +4 -1
  39. package/data/build/dist/client/features/types.d.ts.map +1 -1
  40. package/data/build/dist/client/features/voice-conversation-dialog.d.ts +20 -0
  41. package/data/build/dist/client/features/voice-conversation-dialog.d.ts.map +1 -0
  42. package/data/build/dist/client/features/voice-conversation-dialog.js +59 -0
  43. package/data/build/dist/client/features/voice-conversation-dialog.js.map +1 -0
  44. package/data/build/dist/client/features/voice-initialization-dialog.d.ts +10 -0
  45. package/data/build/dist/client/features/voice-initialization-dialog.d.ts.map +1 -0
  46. package/data/build/dist/client/features/voice-initialization-dialog.js +90 -0
  47. package/data/build/dist/client/features/voice-initialization-dialog.js.map +1 -0
  48. package/data/build/dist/client/features/workspace-session-enhancement-panel.d.ts.map +1 -1
  49. package/data/build/dist/client/features/workspace-session-enhancement-panel.js +57 -2
  50. package/data/build/dist/client/features/workspace-session-enhancement-panel.js.map +1 -1
  51. package/data/build/dist/client/features/workspace-session-enhancement.d.ts.map +1 -1
  52. package/data/build/dist/client/features/workspace-session-enhancement.js +27 -0
  53. package/data/build/dist/client/features/workspace-session-enhancement.js.map +1 -1
  54. package/data/build/dist/client/global-voice-runtime-registry.d.ts +27 -0
  55. package/data/build/dist/client/global-voice-runtime-registry.d.ts.map +1 -0
  56. package/data/build/dist/client/global-voice-runtime-registry.js +12 -0
  57. package/data/build/dist/client/global-voice-runtime-registry.js.map +1 -0
  58. package/data/build/dist/client/index.d.ts +1 -1
  59. package/data/build/dist/client/index.d.ts.map +1 -1
  60. package/data/build/dist/client/locale.d.ts.map +1 -1
  61. package/data/build/dist/client/locale.js +185 -1
  62. package/data/build/dist/client/locale.js.map +1 -1
  63. package/data/build/dist/client/locales/terminalAuth.d.ts.map +1 -1
  64. package/data/build/dist/client/locales/terminalAuth.js +2 -0
  65. package/data/build/dist/client/locales/terminalAuth.js.map +1 -1
  66. package/data/build/dist/client/locales/usage.d.ts.map +1 -1
  67. package/data/build/dist/client/locales/usage.js +4 -0
  68. package/data/build/dist/client/locales/usage.js.map +1 -1
  69. package/data/build/dist/client/mobile-session-interaction.d.ts +9 -0
  70. package/data/build/dist/client/mobile-session-interaction.d.ts.map +1 -1
  71. package/data/build/dist/client/mobile-session-interaction.js +63 -0
  72. package/data/build/dist/client/mobile-session-interaction.js.map +1 -1
  73. package/data/build/dist/client/model-catalog-cache.d.ts +23 -0
  74. package/data/build/dist/client/model-catalog-cache.d.ts.map +1 -1
  75. package/data/build/dist/client/model-catalog-cache.js +81 -9
  76. package/data/build/dist/client/model-catalog-cache.js.map +1 -1
  77. package/data/build/dist/client/service-tier.d.ts +11 -0
  78. package/data/build/dist/client/service-tier.d.ts.map +1 -1
  79. package/data/build/dist/client/service-tier.js +15 -0
  80. package/data/build/dist/client/service-tier.js.map +1 -1
  81. package/data/build/dist/client/sherpa-voice-adapter.d.ts +46 -0
  82. package/data/build/dist/client/sherpa-voice-adapter.d.ts.map +1 -0
  83. package/data/build/dist/client/sherpa-voice-adapter.js +252 -0
  84. package/data/build/dist/client/sherpa-voice-adapter.js.map +1 -0
  85. package/data/build/dist/client/skill-command.d.ts +10 -0
  86. package/data/build/dist/client/skill-command.d.ts.map +1 -0
  87. package/data/build/dist/client/skill-command.js +258 -0
  88. package/data/build/dist/client/skill-command.js.map +1 -0
  89. package/data/build/dist/client/skill-reference-dom.d.ts +38 -0
  90. package/data/build/dist/client/skill-reference-dom.d.ts.map +1 -0
  91. package/data/build/dist/client/skill-reference-dom.js +187 -0
  92. package/data/build/dist/client/skill-reference-dom.js.map +1 -0
  93. package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
  94. package/data/build/dist/client/subscription-slot.js +51 -3
  95. package/data/build/dist/client/subscription-slot.js.map +1 -1
  96. package/data/build/dist/client/terminal/model.d.ts +40 -2
  97. package/data/build/dist/client/terminal/model.d.ts.map +1 -1
  98. package/data/build/dist/client/terminal/model.js +151 -24
  99. package/data/build/dist/client/terminal/model.js.map +1 -1
  100. package/data/build/dist/client/terminal/styles.d.ts +8 -0
  101. package/data/build/dist/client/terminal/styles.d.ts.map +1 -1
  102. package/data/build/dist/client/terminal/styles.js +23 -2
  103. package/data/build/dist/client/terminal/styles.js.map +1 -1
  104. package/data/build/dist/client/terminal/ui.d.ts.map +1 -1
  105. package/data/build/dist/client/terminal/ui.js +161 -26
  106. package/data/build/dist/client/terminal/ui.js.map +1 -1
  107. package/data/build/dist/client/terminal/xterm-view.d.ts.map +1 -1
  108. package/data/build/dist/client/terminal/xterm-view.js +218 -42
  109. package/data/build/dist/client/terminal/xterm-view.js.map +1 -1
  110. package/data/build/dist/client/voice-capture.d.ts +32 -0
  111. package/data/build/dist/client/voice-capture.d.ts.map +1 -0
  112. package/data/build/dist/client/voice-capture.js +158 -0
  113. package/data/build/dist/client/voice-capture.js.map +1 -0
  114. package/data/build/dist/client/voice-device-manager.d.ts +24 -0
  115. package/data/build/dist/client/voice-device-manager.d.ts.map +1 -0
  116. package/data/build/dist/client/voice-device-manager.js +197 -0
  117. package/data/build/dist/client/voice-device-manager.js.map +1 -0
  118. package/data/build/dist/client/voice-output.d.ts +14 -0
  119. package/data/build/dist/client/voice-output.d.ts.map +1 -0
  120. package/data/build/dist/client/voice-output.js +32 -0
  121. package/data/build/dist/client/voice-output.js.map +1 -0
  122. package/data/build/dist/client/voice-security.d.ts +8 -0
  123. package/data/build/dist/client/voice-security.d.ts.map +1 -0
  124. package/data/build/dist/client/voice-security.js +26 -0
  125. package/data/build/dist/client/voice-security.js.map +1 -0
  126. package/data/build/dist/dsh-capabilities/client/primitives-adapter.d.ts +12 -1
  127. package/data/build/dist/dsh-capabilities/client/primitives-adapter.d.ts.map +1 -1
  128. package/data/build/dist/dsh-capabilities/client/primitives-adapter.js +32 -0
  129. package/data/build/dist/dsh-capabilities/client/primitives-adapter.js.map +1 -1
  130. package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts +15 -0
  131. package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts.map +1 -1
  132. package/data/build/dist/host/cli-adapters/acp-cli-driver.js +39 -9
  133. package/data/build/dist/host/cli-adapters/acp-cli-driver.js.map +1 -1
  134. package/data/build/dist/host/cli-adapters/antigravity-driver.d.ts +39 -2
  135. package/data/build/dist/host/cli-adapters/antigravity-driver.d.ts.map +1 -1
  136. package/data/build/dist/host/cli-adapters/antigravity-driver.js +198 -10
  137. package/data/build/dist/host/cli-adapters/antigravity-driver.js.map +1 -1
  138. package/data/build/dist/host/cli-adapters/antigravity-subscription.d.ts +121 -0
  139. package/data/build/dist/host/cli-adapters/antigravity-subscription.d.ts.map +1 -0
  140. package/data/build/dist/host/cli-adapters/antigravity-subscription.js +504 -0
  141. package/data/build/dist/host/cli-adapters/antigravity-subscription.js.map +1 -0
  142. package/data/build/dist/host/cli-adapters/claude-driver.d.ts +21 -0
  143. package/data/build/dist/host/cli-adapters/claude-driver.d.ts.map +1 -1
  144. package/data/build/dist/host/cli-adapters/claude-driver.js +173 -7
  145. package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
  146. package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts.map +1 -1
  147. package/data/build/dist/host/cli-adapters/codebuddy-driver.js +4 -0
  148. package/data/build/dist/host/cli-adapters/codebuddy-driver.js.map +1 -1
  149. package/data/build/dist/host/cli-adapters/codex-driver.d.ts +28 -2
  150. package/data/build/dist/host/cli-adapters/codex-driver.d.ts.map +1 -1
  151. package/data/build/dist/host/cli-adapters/codex-driver.js +234 -5
  152. package/data/build/dist/host/cli-adapters/codex-driver.js.map +1 -1
  153. package/data/build/dist/host/cli-adapters/command-code-driver.d.ts.map +1 -1
  154. package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
  155. package/data/build/dist/host/cli-adapters/command-code-subscription.js +7 -4
  156. package/data/build/dist/host/cli-adapters/command-code-subscription.js.map +1 -1
  157. package/data/build/dist/host/cli-adapters/cursor-driver.d.ts +9 -0
  158. package/data/build/dist/host/cli-adapters/cursor-driver.d.ts.map +1 -1
  159. package/data/build/dist/host/cli-adapters/cursor-driver.js +72 -2
  160. package/data/build/dist/host/cli-adapters/cursor-driver.js.map +1 -1
  161. package/data/build/dist/host/cli-adapters/driver.d.ts +21 -1
  162. package/data/build/dist/host/cli-adapters/driver.d.ts.map +1 -1
  163. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
  164. package/data/build/dist/host/cli-adapters/dsh-message-projector.js +15 -3
  165. package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
  166. package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
  167. package/data/build/dist/host/cli-adapters/feature.js +18 -1
  168. package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
  169. package/data/build/dist/host/cli-adapters/gemini-driver.d.ts.map +1 -1
  170. package/data/build/dist/host/cli-adapters/gemini-driver.js +4 -0
  171. package/data/build/dist/host/cli-adapters/gemini-driver.js.map +1 -1
  172. package/data/build/dist/host/cli-adapters/grok-driver.d.ts.map +1 -1
  173. package/data/build/dist/host/cli-adapters/grok-driver.js +4 -0
  174. package/data/build/dist/host/cli-adapters/grok-driver.js.map +1 -1
  175. package/data/build/dist/host/cli-adapters/json-rpc-process.d.ts.map +1 -1
  176. package/data/build/dist/host/cli-adapters/json-rpc-process.js.map +1 -1
  177. package/data/build/dist/host/cli-adapters/kimi-driver.d.ts.map +1 -1
  178. package/data/build/dist/host/cli-adapters/kimi-driver.js +6 -6
  179. package/data/build/dist/host/cli-adapters/kimi-driver.js.map +1 -1
  180. package/data/build/dist/host/cli-adapters/mcode-driver.d.ts.map +1 -1
  181. package/data/build/dist/host/cli-adapters/mcode-driver.js +2 -0
  182. package/data/build/dist/host/cli-adapters/mcode-driver.js.map +1 -1
  183. package/data/build/dist/host/cli-adapters/model-catalog.d.ts +49 -0
  184. package/data/build/dist/host/cli-adapters/model-catalog.d.ts.map +1 -1
  185. package/data/build/dist/host/cli-adapters/model-catalog.js +126 -0
  186. package/data/build/dist/host/cli-adapters/model-catalog.js.map +1 -1
  187. package/data/build/dist/host/cli-adapters/opencode-driver.d.ts +11 -0
  188. package/data/build/dist/host/cli-adapters/opencode-driver.d.ts.map +1 -1
  189. package/data/build/dist/host/cli-adapters/opencode-driver.js +92 -8
  190. package/data/build/dist/host/cli-adapters/opencode-driver.js.map +1 -1
  191. package/data/build/dist/host/cli-adapters/pi-driver.d.ts.map +1 -1
  192. package/data/build/dist/host/cli-adapters/pi-driver.js +4 -0
  193. package/data/build/dist/host/cli-adapters/pi-driver.js.map +1 -1
  194. package/data/build/dist/host/cli-adapters/process-utils.d.ts +10 -3
  195. package/data/build/dist/host/cli-adapters/process-utils.d.ts.map +1 -1
  196. package/data/build/dist/host/cli-adapters/process-utils.js.map +1 -1
  197. package/data/build/dist/host/cli-adapters/provider-subscription.d.ts +4 -1
  198. package/data/build/dist/host/cli-adapters/provider-subscription.d.ts.map +1 -1
  199. package/data/build/dist/host/cli-adapters/provider-subscription.js +8 -1
  200. package/data/build/dist/host/cli-adapters/provider-subscription.js.map +1 -1
  201. package/data/build/dist/host/cli-adapters/qoder-driver.d.ts +15 -0
  202. package/data/build/dist/host/cli-adapters/qoder-driver.d.ts.map +1 -1
  203. package/data/build/dist/host/cli-adapters/qoder-driver.js +171 -3
  204. package/data/build/dist/host/cli-adapters/qoder-driver.js.map +1 -1
  205. package/data/build/dist/host/cli-adapters/qoder-subscription.js +3 -1
  206. package/data/build/dist/host/cli-adapters/qoder-subscription.js.map +1 -1
  207. package/data/build/dist/host/cli-adapters/reasoning-content.d.ts +11 -0
  208. package/data/build/dist/host/cli-adapters/reasoning-content.d.ts.map +1 -0
  209. package/data/build/dist/host/cli-adapters/reasoning-content.js +79 -0
  210. package/data/build/dist/host/cli-adapters/reasoning-content.js.map +1 -0
  211. package/data/build/dist/host/cli-adapters/registry.d.ts +24 -1
  212. package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
  213. package/data/build/dist/host/cli-adapters/registry.js +109 -4
  214. package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
  215. package/data/build/dist/host/cli-adapters/rpc-driver-utils.d.ts +3 -2
  216. package/data/build/dist/host/cli-adapters/rpc-driver-utils.d.ts.map +1 -1
  217. package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +8 -2
  218. package/data/build/dist/host/cli-adapters/rpc-driver-utils.js.map +1 -1
  219. package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +3 -2
  220. package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts.map +1 -1
  221. package/data/build/dist/host/cli-adapters/standard-stream-driver.js +14 -2
  222. package/data/build/dist/host/cli-adapters/standard-stream-driver.js.map +1 -1
  223. package/data/build/dist/host/cli-bridge/injections.d.ts +10 -1
  224. package/data/build/dist/host/cli-bridge/injections.d.ts.map +1 -1
  225. package/data/build/dist/host/cli-bridge/injections.js +28 -8
  226. package/data/build/dist/host/cli-bridge/injections.js.map +1 -1
  227. package/data/build/dist/host/features/assistant-dispatch.d.ts +45 -0
  228. package/data/build/dist/host/features/assistant-dispatch.d.ts.map +1 -0
  229. package/data/build/dist/host/features/assistant-dispatch.js +49 -0
  230. package/data/build/dist/host/features/assistant-dispatch.js.map +1 -0
  231. package/data/build/dist/host/features/assistant-intent.d.ts +46 -0
  232. package/data/build/dist/host/features/assistant-intent.d.ts.map +1 -0
  233. package/data/build/dist/host/features/assistant-intent.js +149 -0
  234. package/data/build/dist/host/features/assistant-intent.js.map +1 -0
  235. package/data/build/dist/host/features/assistant-scope-settings.d.ts +25 -0
  236. package/data/build/dist/host/features/assistant-scope-settings.d.ts.map +1 -0
  237. package/data/build/dist/host/features/assistant-scope-settings.js +33 -0
  238. package/data/build/dist/host/features/assistant-scope-settings.js.map +1 -0
  239. package/data/build/dist/host/features/assistant-scope.d.ts +79 -0
  240. package/data/build/dist/host/features/assistant-scope.d.ts.map +1 -0
  241. package/data/build/dist/host/features/assistant-scope.js +107 -0
  242. package/data/build/dist/host/features/assistant-scope.js.map +1 -0
  243. package/data/build/dist/host/features/assistant-session-index.d.ts +44 -0
  244. package/data/build/dist/host/features/assistant-session-index.d.ts.map +1 -0
  245. package/data/build/dist/host/features/assistant-session-index.js +109 -0
  246. package/data/build/dist/host/features/assistant-session-index.js.map +1 -0
  247. package/data/build/dist/host/features/assistant-summary.d.ts +28 -0
  248. package/data/build/dist/host/features/assistant-summary.d.ts.map +1 -0
  249. package/data/build/dist/host/features/assistant-summary.js +166 -0
  250. package/data/build/dist/host/features/assistant-summary.js.map +1 -0
  251. package/data/build/dist/host/features/assistant-voice-stream.d.ts +10 -0
  252. package/data/build/dist/host/features/assistant-voice-stream.d.ts.map +1 -0
  253. package/data/build/dist/host/features/assistant-voice-stream.js +106 -0
  254. package/data/build/dist/host/features/assistant-voice-stream.js.map +1 -0
  255. package/data/build/dist/host/features/assistant-voice-turn.d.ts +27 -0
  256. package/data/build/dist/host/features/assistant-voice-turn.d.ts.map +1 -0
  257. package/data/build/dist/host/features/assistant-voice-turn.js +54 -0
  258. package/data/build/dist/host/features/assistant-voice-turn.js.map +1 -0
  259. package/data/build/dist/host/features/assistant-waiting-state.d.ts +14 -0
  260. package/data/build/dist/host/features/assistant-waiting-state.d.ts.map +1 -0
  261. package/data/build/dist/host/features/assistant-waiting-state.js +17 -0
  262. package/data/build/dist/host/features/assistant-waiting-state.js.map +1 -0
  263. package/data/build/dist/host/features/global-voice-coordinator.d.ts +55 -0
  264. package/data/build/dist/host/features/global-voice-coordinator.d.ts.map +1 -0
  265. package/data/build/dist/host/features/global-voice-coordinator.js +221 -0
  266. package/data/build/dist/host/features/global-voice-coordinator.js.map +1 -0
  267. package/data/build/dist/host/features/global-voice-rpc.d.ts +25 -0
  268. package/data/build/dist/host/features/global-voice-rpc.d.ts.map +1 -0
  269. package/data/build/dist/host/features/global-voice-rpc.js +862 -0
  270. package/data/build/dist/host/features/global-voice-rpc.js.map +1 -0
  271. package/data/build/dist/host/features/index.d.ts +10 -0
  272. package/data/build/dist/host/features/index.d.ts.map +1 -1
  273. package/data/build/dist/host/features/index.js +10 -0
  274. package/data/build/dist/host/features/index.js.map +1 -1
  275. package/data/build/dist/host/features/peer-host.d.ts +5 -0
  276. package/data/build/dist/host/features/peer-host.d.ts.map +1 -1
  277. package/data/build/dist/host/features/peer-host.js +232 -2
  278. package/data/build/dist/host/features/peer-host.js.map +1 -1
  279. package/data/build/dist/host/features/sherpa-voice-runtime.d.ts +42 -0
  280. package/data/build/dist/host/features/sherpa-voice-runtime.d.ts.map +1 -0
  281. package/data/build/dist/host/features/sherpa-voice-runtime.js +193 -0
  282. package/data/build/dist/host/features/sherpa-voice-runtime.js.map +1 -0
  283. package/data/build/dist/host/features/types.d.ts +26 -0
  284. package/data/build/dist/host/features/types.d.ts.map +1 -1
  285. package/data/build/dist/host/features/voice-agent-actions.d.ts +26 -0
  286. package/data/build/dist/host/features/voice-agent-actions.d.ts.map +1 -0
  287. package/data/build/dist/host/features/voice-agent-actions.js +128 -0
  288. package/data/build/dist/host/features/voice-agent-actions.js.map +1 -0
  289. package/data/build/dist/host/features/voice-agent-service.d.ts +117 -0
  290. package/data/build/dist/host/features/voice-agent-service.d.ts.map +1 -0
  291. package/data/build/dist/host/features/voice-agent-service.js +243 -0
  292. package/data/build/dist/host/features/voice-agent-service.js.map +1 -0
  293. package/data/build/dist/host/features/voice-model-setup.d.ts +20 -0
  294. package/data/build/dist/host/features/voice-model-setup.d.ts.map +1 -0
  295. package/data/build/dist/host/features/voice-model-setup.js +89 -0
  296. package/data/build/dist/host/features/voice-model-setup.js.map +1 -0
  297. package/data/build/dist/host/index.d.ts +2 -2
  298. package/data/build/dist/host/index.d.ts.map +1 -1
  299. package/data/build/dist/host/index.js +7 -1
  300. package/data/build/dist/host/index.js.map +1 -1
  301. package/data/build/dist/host/lan-access-dsh.js.map +1 -1
  302. package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.d.ts.map +1 -1
  303. package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js +53 -2
  304. package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js.map +1 -1
  305. package/data/build/dist/host/modules/peer-host/peer-host-remote-summary-source.js +15 -1
  306. package/data/build/dist/host/modules/peer-host/peer-host-remote-summary-source.js.map +1 -1
  307. package/data/build/dist/host/native-session-bridge.d.ts +2 -0
  308. package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
  309. package/data/build/dist/host/native-session-bridge.js +1 -0
  310. package/data/build/dist/host/native-session-bridge.js.map +1 -1
  311. package/data/build/dist/host/rpc.d.ts.map +1 -1
  312. package/data/build/dist/host/rpc.js +9 -4
  313. package/data/build/dist/host/rpc.js.map +1 -1
  314. package/data/build/dist/host/settings.d.ts.map +1 -1
  315. package/data/build/dist/host/settings.js +19 -1
  316. package/data/build/dist/host/settings.js.map +1 -1
  317. package/data/build/dist/host/terminal/backends/conpty-backend.js.map +1 -1
  318. package/data/build/dist/host/terminal/terminal-controller.d.ts.map +1 -1
  319. package/data/build/dist/host/terminal/terminal-controller.js +4 -0
  320. package/data/build/dist/host/terminal/terminal-controller.js.map +1 -1
  321. package/data/build/dist/host/terminal/terminal-service.d.ts +21 -1
  322. package/data/build/dist/host/terminal/terminal-service.d.ts.map +1 -1
  323. package/data/build/dist/host/terminal/terminal-service.js +118 -7
  324. package/data/build/dist/host/terminal/terminal-service.js.map +1 -1
  325. package/data/build/dist/index.d.ts +2 -2
  326. package/data/build/dist/index.d.ts.map +1 -1
  327. package/data/build/dist/index.js +1 -1
  328. package/data/build/dist/index.js.map +1 -1
  329. package/data/build/dist/shared/contracts/assistant.d.ts +70 -0
  330. package/data/build/dist/shared/contracts/assistant.d.ts.map +1 -0
  331. package/data/build/dist/shared/contracts/assistant.js +2 -0
  332. package/data/build/dist/shared/contracts/assistant.js.map +1 -0
  333. package/data/build/dist/shared/contracts/cli-adapter.d.ts +33 -1
  334. package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
  335. package/data/build/dist/shared/contracts/config.d.ts +30 -0
  336. package/data/build/dist/shared/contracts/config.d.ts.map +1 -1
  337. package/data/build/dist/shared/contracts/config.js +20 -0
  338. package/data/build/dist/shared/contracts/config.js.map +1 -1
  339. package/data/build/dist/shared/contracts/errors.d.ts +2 -2
  340. package/data/build/dist/shared/contracts/errors.d.ts.map +1 -1
  341. package/data/build/dist/shared/contracts/subscription.d.ts +30 -0
  342. package/data/build/dist/shared/contracts/subscription.d.ts.map +1 -1
  343. package/data/build/dist/shared/contracts/subscription.js.map +1 -1
  344. package/data/build/dist/shared/contracts/terminal.d.ts +2 -0
  345. package/data/build/dist/shared/contracts/terminal.d.ts.map +1 -1
  346. package/data/build/dist/shared/contracts/version.d.ts +12 -5
  347. package/data/build/dist/shared/contracts/version.d.ts.map +1 -1
  348. package/data/build/dist/shared/contracts/version.js +11 -4
  349. package/data/build/dist/shared/contracts/version.js.map +1 -1
  350. package/data/build/dist/shared/contracts/voice-runtime.d.ts +90 -0
  351. package/data/build/dist/shared/contracts/voice-runtime.d.ts.map +1 -0
  352. package/data/build/dist/shared/contracts/voice-runtime.js +16 -0
  353. package/data/build/dist/shared/contracts/voice-runtime.js.map +1 -0
  354. package/data/build/dist/shared/index.d.ts +8 -2
  355. package/data/build/dist/shared/index.d.ts.map +1 -1
  356. package/data/build/dist/shared/index.js +5 -1
  357. package/data/build/dist/shared/index.js.map +1 -1
  358. package/data/build/dist/shared/voice-models.d.ts +21 -0
  359. package/data/build/dist/shared/voice-models.d.ts.map +1 -0
  360. package/data/build/dist/shared/voice-models.js +27 -0
  361. package/data/build/dist/shared/voice-models.js.map +1 -0
  362. package/data/build/dist/shared/voice-stream.d.ts +42 -0
  363. package/data/build/dist/shared/voice-stream.d.ts.map +1 -0
  364. package/data/build/dist/shared/voice-stream.js +99 -0
  365. package/data/build/dist/shared/voice-stream.js.map +1 -0
  366. package/data/build/dist/shared/voice-text.d.ts +3 -0
  367. package/data/build/dist/shared/voice-text.d.ts.map +1 -0
  368. package/data/build/dist/shared/voice-text.js +14 -0
  369. package/data/build/dist/shared/voice-text.js.map +1 -0
  370. package/data/build/dist/typert.host.d.ts.map +1 -1
  371. package/data/build/dist/typert.host.js +1 -0
  372. package/data/build/dist/typert.host.js.map +1 -1
  373. package/package.json +56 -26
  374. package/profile/README.md +8 -5
  375. package/profile/package.json +5 -3
  376. package/profile/version.json +3 -3
  377. package/version.json +3 -3
@@ -0,0 +1,862 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { createAssistantScope } from './assistant-scope.js';
3
+ import { AssistantDispatcher } from './assistant-dispatch.js';
4
+ import { AssistantVoiceTurnRouter } from './assistant-voice-turn.js';
5
+ import { buildAssistantSessionIndex } from './assistant-session-index.js';
6
+ import { sanitizeSpeechText, summarizeAssistantEntries } from './assistant-summary.js';
7
+ import { GlobalVoiceCoordinator } from './global-voice-coordinator.js';
8
+ import { VoiceAgentService } from './voice-agent-service.js';
9
+ import { createAssistantVoiceActionBridge } from './voice-agent-actions.js';
10
+ import { AssistantWaitingState } from './assistant-waiting-state.js';
11
+ import { debugInfo } from '../../shared/debug.js';
12
+ import { createAssistantVoiceStreamHandler } from './assistant-voice-stream.js';
13
+ import { SherpaVoiceRuntime } from './sherpa-voice-runtime.js';
14
+ import { DEFAULT_ASSISTANT_VOICE_SETTINGS } from '../../shared/contracts/config.js';
15
+ import { installAssistantVoiceModel } from './voice-model-setup.js';
16
+ /**
17
+ * 全局智能助理 Host 边界。
18
+ *
19
+ * 这里故意不接收 sessionId:会话索引、意图和派发各自通过快照协作,语音租约
20
+ * 只属于 Host。这样刷新页面或切换当前对话不会改变助理的目标范围。
21
+ */
22
+ export function createGlobalVoiceRpcFeature() {
23
+ return {
24
+ descriptor: {
25
+ name: 'globalVoiceRpc',
26
+ version: '0.2.0',
27
+ enabledByDefault: true,
28
+ dependencies: [],
29
+ runtime: 'host',
30
+ },
31
+ start(context) {
32
+ const runtime = new SherpaVoiceRuntime({
33
+ env: buildSherpaRuntimeEnvironment(readAssistantVoiceSettings(context.services)),
34
+ });
35
+ const agent = new VoiceAgentService({
36
+ secureContext: true,
37
+ ...runtime.capabilities,
38
+ });
39
+ const updateVoiceAgentCapabilities = () => {
40
+ agent.updateCapabilities({
41
+ secureContext: true,
42
+ realtime: runtime.capabilities.realtime,
43
+ recognition: runtime.capabilities.speechToText,
44
+ audioInput: runtime.capabilities.streamingInput,
45
+ wakeWord: runtime.capabilities.wakeWord,
46
+ bargeIn: runtime.capabilities.bargeIn,
47
+ streamingAudio: runtime.capabilities.streamingOutput,
48
+ readAloud: runtime.capabilities.textToSpeech,
49
+ voices: runtime.capabilities.textToSpeech,
50
+ });
51
+ };
52
+ const disposeVoiceAgent = provideHostVoiceAgentService(context.services.dshContext, agent);
53
+ if (disposeVoiceAgent !== undefined)
54
+ context.resources.add(disposeVoiceAgent);
55
+ const dispatcher = new AssistantDispatcher((request) => dispatchPrompt(context.services, request));
56
+ const router = new AssistantVoiceTurnRouter(dispatcher);
57
+ const waitingState = new AssistantWaitingState();
58
+ let lastSnapshot = null;
59
+ let lastArchivedSessionIds = [];
60
+ let lastIndexKey = '';
61
+ let lastIndexVolatile = false;
62
+ let buildingIndex;
63
+ const buildIndex = async () => {
64
+ const managed = context.services.settings?.get().assistant?.managedWorkspaceIds ?? [];
65
+ const archived = readStringArray(readOptionalService(context.services.dshContext, 'workspaceRegistry')?.archivedSessionIds);
66
+ const key = JSON.stringify([managed, archived]);
67
+ if (lastSnapshot !== null && key === lastIndexKey && !lastIndexVolatile)
68
+ return lastSnapshot;
69
+ if (buildingIndex !== undefined)
70
+ return buildingIndex;
71
+ buildingIndex = (async () => {
72
+ const source = await readAssistantSource(context.services, managed, waitingState);
73
+ lastArchivedSessionIds = source.archivedSessionIds;
74
+ const snapshot = await buildAssistantSessionIndex({
75
+ sessions: source.sessions,
76
+ scope: createAssistantScope(managed),
77
+ archivedSessionIds: source.archivedSessionIds,
78
+ generation: (lastSnapshot?.generation ?? 0) + 1,
79
+ ...(source.readSummary === undefined ? {} : { readSummary: source.readSummary }),
80
+ ...(source.readWaiting === undefined ? {} : { readWaiting: source.readWaiting }),
81
+ });
82
+ lastSnapshot = snapshot;
83
+ lastIndexKey = JSON.stringify([managed, source.archivedSessionIds]);
84
+ lastIndexVolatile = source.volatile === true;
85
+ return snapshot;
86
+ })().finally(() => { buildingIndex = undefined; });
87
+ return buildingIndex;
88
+ };
89
+ const invalidateIndex = () => { lastSnapshot = null; lastIndexKey = ''; lastIndexVolatile = false; };
90
+ const eventDisposers = [];
91
+ for (const eventName of ['session/flush', 'session/update', 'session/title', 'session/status', 'workspace/archive', 'workspace/unarchive', 'workspace/changed']) {
92
+ const disposer = context.services.events?.on(eventName, invalidateIndex);
93
+ if (typeof disposer === 'function')
94
+ eventDisposers.push(disposer);
95
+ }
96
+ const waitingRequests = [
97
+ ['approval/request', 'approval'],
98
+ ['approval/asked', 'approval'],
99
+ ['user-questions/request', 'question'],
100
+ ['user_questions/request', 'question'],
101
+ ['user-question/request', 'question'],
102
+ ];
103
+ for (const [eventName, kind] of waitingRequests) {
104
+ const disposer = context.services.events?.on(eventName, (...args) => {
105
+ const sessionId = readWaitingSessionId(args);
106
+ if (sessionId !== null)
107
+ waitingState.request({ sessionId, kind });
108
+ invalidateIndex();
109
+ });
110
+ if (typeof disposer === 'function')
111
+ eventDisposers.push(disposer);
112
+ }
113
+ for (const eventName of ['approval/resolve', 'approval/resolved', 'user-questions/resolve', 'user-questions/resolved', 'user-question/resolve', 'user-question/answered', 'session/complete']) {
114
+ const disposer = context.services.events?.on(eventName, (...args) => {
115
+ const sessionId = readWaitingSessionId(args);
116
+ if (sessionId !== null)
117
+ waitingState.resolve(sessionId);
118
+ invalidateIndex();
119
+ });
120
+ if (typeof disposer === 'function')
121
+ eventDisposers.push(disposer);
122
+ }
123
+ const nativeSessionDisposer = context.services.nativeSessions?.subscribe({
124
+ onEvent: invalidateIndex,
125
+ onFlush: invalidateIndex,
126
+ });
127
+ if (typeof nativeSessionDisposer === 'function')
128
+ eventDisposers.push(nativeSessionDisposer);
129
+ const disposeSettingsWatch = context.services.settings?.watch?.(() => invalidateIndex());
130
+ if (typeof disposeSettingsWatch === 'function')
131
+ eventDisposers.push(disposeSettingsWatch);
132
+ context.resources.add(() => { for (const dispose of eventDisposers.splice(0))
133
+ dispose(); });
134
+ const actionBridge = createAssistantVoiceActionBridge({
135
+ voiceAgent: agent,
136
+ ownerPrefix: 'voice-runtime',
137
+ buildIndex,
138
+ createDispatchContext: (snapshot) => createDispatchContext(snapshot, lastArchivedSessionIds),
139
+ router,
140
+ });
141
+ // 语音运行时只提交 action 事件;动作本身再次读取索引并经过派发器复核。
142
+ actionBridge.register();
143
+ const coordinator = new GlobalVoiceCoordinator({ adapter: runtime });
144
+ if (context.services.registerAssistantVoiceStreamRoute !== undefined) {
145
+ context.resources.add(context.services.registerAssistantVoiceStreamRoute(createAssistantVoiceStreamHandler({ coordinator })));
146
+ }
147
+ context.resources.add(async () => {
148
+ await actionBridge.dispose();
149
+ coordinator.dispose();
150
+ });
151
+ context.resources.add(context.services.rpc.register('assistant', async (action, payload) => {
152
+ switch (action) {
153
+ case 'index':
154
+ return await buildIndex();
155
+ case 'summary': {
156
+ const snapshot = await buildIndex();
157
+ return summarizeAssistantEntries(snapshot.entries, snapshot.scope, snapshot.generation, snapshot.unreadableCount);
158
+ }
159
+ case 'turn': {
160
+ const request = readAssistantRequest(payload);
161
+ const snapshot = await buildIndex();
162
+ const result = await router.handleText(request.text, snapshot, {
163
+ requestId: request.requestId,
164
+ dispatchContext: createDispatchContext(snapshot, lastArchivedSessionIds),
165
+ });
166
+ debugInfo('codingns4dsh: assistant intent resolved', {
167
+ requestId: request.requestId,
168
+ text: sanitizeSpeechText(request.text).slice(0, 1000),
169
+ kind: result.kind,
170
+ targetSessionId: result.target?.sessionId ?? null,
171
+ targetHostId: result.target?.hostId ?? null,
172
+ mode: result.mode ?? null,
173
+ ok: result.kind !== 'clarify',
174
+ });
175
+ return result;
176
+ }
177
+ case 'voice/capabilities':
178
+ return {
179
+ ...coordinator.snapshot(),
180
+ voiceAgent: agent.capabilities(),
181
+ };
182
+ case 'voice/setup': {
183
+ const modelId = readVoiceModelId(payload);
184
+ if (coordinator.snapshot().active || runtime.running) {
185
+ throw new Error('请先停止当前实时语音,再更换语音模型');
186
+ }
187
+ const installed = await installAssistantVoiceModel(modelId);
188
+ const current = readAssistantVoiceSettings(context.services);
189
+ const next = {
190
+ ...DEFAULT_ASSISTANT_VOICE_SETTINGS,
191
+ ...current,
192
+ initialized: true,
193
+ provider: 'sherpa-onnx',
194
+ modelId,
195
+ asrEncoder: installed.paths.asrEncoder,
196
+ asrDecoder: installed.paths.asrDecoder,
197
+ asrJoiner: installed.paths.asrJoiner,
198
+ asrTokens: installed.paths.asrTokens,
199
+ // 实时对话使用浏览器输出;不让历史配置中的离线 VAD/TTS 偷偷生效。
200
+ vadModel: '',
201
+ ttsModel: '',
202
+ ttsTokens: '',
203
+ ttsLexicon: '',
204
+ };
205
+ if (context.services.settings === undefined)
206
+ throw new Error('当前 Host 不支持保存语音设置');
207
+ await context.services.settings.update({
208
+ assistant: {
209
+ ...context.services.settings.get().assistant,
210
+ voice: next,
211
+ },
212
+ });
213
+ runtime.configureEnvironment(buildSherpaRuntimeEnvironment(next));
214
+ updateVoiceAgentCapabilities();
215
+ return { modelId, downloaded: installed.downloaded };
216
+ }
217
+ case 'voice/start':
218
+ {
219
+ const ownerId = readOwner(payload);
220
+ if (isRecord(payload) && payload.mode === 'fallback') {
221
+ return {
222
+ unavailable: true,
223
+ realtimeOnly: true,
224
+ message: '已禁用 DSH speechToText 回退,必须使用 Sherpa-ONNX 实时模式',
225
+ };
226
+ }
227
+ const voiceSettings = readAssistantVoiceSettings(context.services);
228
+ const setupError = validateAssistantVoiceSettings(voiceSettings);
229
+ if (setupError !== undefined) {
230
+ return {
231
+ unavailable: true,
232
+ requiresSetup: true,
233
+ realtimeOnly: true,
234
+ message: setupError,
235
+ };
236
+ }
237
+ try {
238
+ const existing = coordinator.snapshot();
239
+ if (existing.active && existing.ownerId === ownerId && !runtime.running) {
240
+ // 清理旧的无运行时租约,确保本次启动重新拥有完整实时运行时。
241
+ await coordinator.stop(ownerId);
242
+ }
243
+ if (!coordinator.snapshot().active) {
244
+ runtime.configureEnvironment(buildSherpaRuntimeEnvironment(voiceSettings));
245
+ }
246
+ const snapshot = await coordinator.start(ownerId);
247
+ updateVoiceAgentCapabilities();
248
+ return snapshot;
249
+ }
250
+ catch (error) {
251
+ if (isVoiceRuntimeUnavailableError(error)) {
252
+ return {
253
+ unavailable: true,
254
+ realtimeOnly: true,
255
+ message: error instanceof Error ? error.message : String(error),
256
+ };
257
+ }
258
+ throw error;
259
+ }
260
+ }
261
+ case 'voice/stop':
262
+ return await coordinator.stop(readOwner(payload));
263
+ case 'voice/heartbeat':
264
+ return coordinator.heartbeat(readOwner(payload));
265
+ case 'voice/interrupt':
266
+ return await coordinator.interrupt(readOwner(payload));
267
+ case 'voice/register-client': {
268
+ const ownerId = readOwner(payload);
269
+ const capabilities = readVoiceRuntimeCapabilities(payload);
270
+ return { registered: true, ownerId, capabilities, hostCapabilities: runtime.capabilities };
271
+ }
272
+ case 'voice/unregister-client': {
273
+ const ownerId = readOwner(payload);
274
+ if (coordinator.snapshot().ownerId === ownerId && coordinator.snapshot().active)
275
+ await coordinator.stop(ownerId).catch(() => undefined);
276
+ return { registered: false };
277
+ }
278
+ case 'voice/event': {
279
+ const ownerId = readOwner(payload);
280
+ const event = readVoiceRuntimeEvent(payload);
281
+ const sequence = isRecord(payload) && typeof payload.sequence === 'number' && Number.isFinite(payload.sequence) ? payload.sequence : undefined;
282
+ return coordinator.acceptClientEvent(ownerId, event, sequence);
283
+ }
284
+ case 'voice/text': {
285
+ const ownerId = readOwner(payload);
286
+ coordinator.assertOwner(ownerId);
287
+ const request = readAssistantRequest(payload);
288
+ const result = await actionBridge.handleFinalText(request.text, request.requestId);
289
+ debugInfo('codingns4dsh: assistant voice text resolved', {
290
+ requestId: request.requestId,
291
+ text: sanitizeSpeechText(request.text).slice(0, 1000),
292
+ kind: result.kind,
293
+ targetSessionId: result.target?.sessionId ?? null,
294
+ targetHostId: result.target?.hostId ?? null,
295
+ mode: result.mode ?? null,
296
+ ok: result.kind !== 'clarify',
297
+ });
298
+ return result;
299
+ }
300
+ default:
301
+ throw new Error(`未知全局语音 RPC: assistant/${action}`);
302
+ }
303
+ }));
304
+ },
305
+ };
306
+ }
307
+ /**
308
+ * 在 Host Context 注册 CodingNS 自己的 voiceAgent 服务。
309
+ *
310
+ * 浏览器 Client 负责麦克风和扬声器;Host 侧服务持有 Sherpa 运行时、契约、
311
+ * 动作注册表和会话句柄。若宿主已经提供同名且契约完整的服务,保留宿主
312
+ * 实现,避免覆盖其他插件的生命周期所有权;没有 Context 或缺少公开反射 API 时
313
+ * 才跳过注册。已有同名但契约不完整属于装配错误,必须显式失败,不能伪装成可用。
314
+ */
315
+ export function provideHostVoiceAgentService(ctx, agent) {
316
+ if (ctx === undefined)
317
+ return undefined;
318
+ const reflect = ctx.reflect;
319
+ if (reflect === undefined || typeof reflect.get !== 'function' || typeof reflect.provide !== 'function') {
320
+ debugInfo('codingns4dsh: Host voiceAgent registration skipped because reflect API is unavailable');
321
+ return undefined;
322
+ }
323
+ const existing = reflect.get('voiceAgent', false);
324
+ if (existing !== undefined) {
325
+ if (!isVoiceAgentServiceContract(existing)) {
326
+ throw new Error('Host voiceAgent service is already registered with an incompatible contract');
327
+ }
328
+ debugInfo('codingns4dsh: Host voiceAgent already provided; keep existing service');
329
+ return undefined;
330
+ }
331
+ return reflect.provide('voiceAgent', agent);
332
+ }
333
+ function isVoiceAgentServiceContract(value) {
334
+ if (!isRecord(value))
335
+ return false;
336
+ return typeof value.capabilities === 'function'
337
+ && typeof value.startConversation === 'function'
338
+ && typeof value.registerActions === 'function';
339
+ }
340
+ function createDispatchContext(snapshot, archivedSessionIds) {
341
+ return {
342
+ scope: createAssistantScope(snapshot.scope.status === 'ready' ? snapshot.scope.managedWorkspaceIds : []),
343
+ archivedSessionIds,
344
+ indexGeneration: snapshot.generation,
345
+ entries: snapshot.entries,
346
+ };
347
+ }
348
+ function readOwner(payload) {
349
+ if (!isRecord(payload) || typeof payload.ownerId !== 'string' || payload.ownerId.trim() === '') {
350
+ throw new TypeError('全局语音 RPC 缺少 ownerId');
351
+ }
352
+ return payload.ownerId.trim();
353
+ }
354
+ function readAssistantRequest(payload) {
355
+ if (!isRecord(payload) || typeof payload.text !== 'string' || payload.text.trim() === '') {
356
+ throw new TypeError('智能助理请求缺少 text');
357
+ }
358
+ const requestId = typeof payload.requestId === 'string' && payload.requestId.trim() !== '' ? payload.requestId.trim() : `assistant-${randomUUID()}`;
359
+ return { text: payload.text.trim(), requestId };
360
+ }
361
+ async function dispatchPrompt(services, request) {
362
+ const localHostId = process.env.CODINGNS4DSH_HOST_ID?.trim() || 'local-host';
363
+ if (request.hostId !== undefined && request.hostId !== localHostId && services.assistantGateway !== undefined) {
364
+ await services.assistantGateway.dispatch({ ...request, hostId: request.hostId });
365
+ return;
366
+ }
367
+ const controller = readOptionalService(services.dshContext, 'sessionController');
368
+ if (controller !== undefined && typeof controller.prompt === 'function') {
369
+ await controller.prompt(request);
370
+ return;
371
+ }
372
+ throw new Error('DSH sessionController.prompt 不可用,无法派发任务');
373
+ }
374
+ async function readAssistantSource(services, managedWorkspaceIds = [], waitingState) {
375
+ const ctx = services.dshContext;
376
+ const query = readOptionalService(ctx, 'sessionQuery');
377
+ const primaryValue = query !== undefined && typeof query.listSessions === 'function'
378
+ ? await query.listSessions()
379
+ : [];
380
+ const primaryRecords = flattenSessionList(primaryValue);
381
+ const bridgeSessions = managedWorkspaceIds.length > 0 && services.nativeSessions !== undefined
382
+ ? await services.nativeSessions.listRemote()
383
+ : [];
384
+ const gatewayResult = services.assistantGateway === undefined || managedWorkspaceIds.length === 0
385
+ ? undefined
386
+ : await services.assistantGateway.list(managedWorkspaceIds).catch(() => undefined);
387
+ const sessions = dedupeSessionRecords([
388
+ ...primaryRecords,
389
+ ...(primaryRecords.length === 0 ? flattenSessionList(bridgeSessions) : []),
390
+ ...(gatewayResult?.sessions ?? []),
391
+ ]);
392
+ const workspaces = readWorkspaceRecords(ctx);
393
+ const workspaceById = new Map(workspaces.map((workspace) => [workspace.id, workspace]));
394
+ const archived = [...new Set([
395
+ ...readStringArray(readOptionalService(ctx, 'workspaceRegistry')?.archivedSessionIds),
396
+ ...(gatewayResult?.archivedSessionIds ?? []),
397
+ ])];
398
+ const archivedSet = new Set(archived);
399
+ const managed = new Set(managedWorkspaceIds);
400
+ const waitingBySession = readPendingWaiting(ctx);
401
+ for (const [sessionId, kind] of waitingState?.snapshot() ?? [])
402
+ waitingBySession.set(sessionId, kind);
403
+ const hostId = process.env.CODINGNS4DSH_HOST_ID?.trim() || 'local-host';
404
+ const records = sessions.flatMap((raw) => {
405
+ const value = asRecord(raw);
406
+ const header = asRecord(value?.header) ?? value;
407
+ const sessionId = readText(header, ['sessionId', 'id', 'key']);
408
+ if (sessionId === null)
409
+ return [];
410
+ // PeerHost Gateway 返回的摘要记录已经携带 workspaceId/hostId;本地
411
+ // sessionQuery 记录才需要通过 workspaceRegistry 的成员关系或 cwd 反查。
412
+ const workspaceId = readText(value, ['workspaceId']) ?? findWorkspaceId(sessionId, header, workspaces);
413
+ if (workspaceId === null || !managed.has(workspaceId) || archivedSet.has(sessionId))
414
+ return [];
415
+ const workspace = workspaceById.get(workspaceId);
416
+ const sourceWorkspaceName = readText(value, ['workspaceName', 'workspaceDisplayName']);
417
+ const sourceHostId = readText(value, ['hostId', 'sourceHostId']) ?? hostId;
418
+ const state = readText(value, ['state', 'status']) ?? '';
419
+ const live = value?.live === true;
420
+ const running = live || value?.running === true || /running|active|working/iu.test(state);
421
+ // listSessions 的 persisted/live 只是可用性包装,不足以证明会话已完成;
422
+ // 没有显式状态时保留 completed=false,由索引 status=unknown 表示未知。
423
+ const completed = value?.completed === true || /completed|complete|done/iu.test(state);
424
+ return [{
425
+ sessionId,
426
+ workspaceId,
427
+ workspaceName: sourceWorkspaceName ?? workspace?.name ?? workspaceId,
428
+ hostId: sourceHostId,
429
+ running: running && !completed,
430
+ completed,
431
+ error: value?.error === true || /error|failed/iu.test(state),
432
+ updatedAt: readTimestamp(header, ['updatedAt', 'updated', 'lastUpdatedAt']),
433
+ waiting: readWaiting(value) ?? waitingBySession.get(sessionId) ?? null,
434
+ title: readText(value, ['title', 'name', 'displayName']),
435
+ titleEvents: readStringArray(value?.titleEvents),
436
+ summary: null,
437
+ }];
438
+ });
439
+ const readSurface = query !== undefined && typeof query.readSurface === 'function' ? query.readSurface.bind(query) : undefined;
440
+ const readTitle = query !== undefined && typeof query.readTitle === 'function'
441
+ ? query.readTitle.bind(query)
442
+ : query !== undefined && typeof query.readTitleSnapshot === 'function'
443
+ ? query.readTitleSnapshot.bind(query)
444
+ : undefined;
445
+ const hydratedRecords = readTitle === undefined
446
+ ? records
447
+ : await Promise.all(records.map(async (record) => {
448
+ // Gateway 已经携带远端标题;本地 query 不能读取远端 Host 的 sessionId,
449
+ // 也不能把远端会话误当成本地会话产生一次额外 I/O。
450
+ if (record.hostId !== hostId)
451
+ return record;
452
+ const title = await readSessionTitle(readTitle, record.sessionId);
453
+ return title === null ? record : { ...record, title };
454
+ }));
455
+ // workspaceRegistry 可能只暴露归档 ID,而 sessionQuery 不再返回归档记录。
456
+ // 为了给用户明确的“已归档”诊断,这里只建立没有正文的元数据占位,不读取归档日志。
457
+ const knownSessionIds = new Set(records.map((record) => `${record.hostId}:${record.sessionId}`));
458
+ const archivedStubs = workspaces.flatMap((workspace) => workspace.archivedSessionIds.flatMap((sessionId) => {
459
+ const key = `${hostId}:${sessionId}`;
460
+ if (knownSessionIds.has(key))
461
+ return [];
462
+ return [{
463
+ sessionId,
464
+ workspaceId: workspace.id,
465
+ workspaceName: workspace.name,
466
+ hostId,
467
+ running: false,
468
+ completed: false,
469
+ updatedAt: null,
470
+ waiting: null,
471
+ title: null,
472
+ summary: null,
473
+ }];
474
+ })).concat(sessions.flatMap((raw) => {
475
+ const value = asRecord(raw);
476
+ const header = asRecord(value?.header) ?? value;
477
+ const sessionId = readText(header, ['sessionId', 'id', 'key']);
478
+ const workspaceId = readText(value, ['workspaceId']);
479
+ const sourceHostId = readText(value, ['hostId', 'sourceHostId']) ?? hostId;
480
+ if (sessionId === null || workspaceId === null || sourceHostId === hostId || !managed.has(workspaceId) || !archivedSet.has(sessionId))
481
+ return [];
482
+ const workspace = workspaceById.get(workspaceId);
483
+ return [{
484
+ sessionId,
485
+ workspaceId,
486
+ workspaceName: readText(value, ['workspaceName', 'workspaceDisplayName']) ?? workspace?.name ?? workspaceId,
487
+ hostId: sourceHostId,
488
+ running: false,
489
+ completed: false,
490
+ updatedAt: null,
491
+ waiting: null,
492
+ title: readText(value, ['title', 'name', 'displayName']),
493
+ summary: null,
494
+ }];
495
+ }));
496
+ return {
497
+ sessions: [...hydratedRecords, ...archivedStubs],
498
+ archivedSessionIds: archived,
499
+ ...(gatewayResult?.volatile === true ? { volatile: true } : {}),
500
+ ...((readSurface === undefined && gatewayResult?.readSummary === undefined) ? {} : {
501
+ readSummary: async (session) => {
502
+ if (session.hostId === hostId && readSurface !== undefined)
503
+ return readSurfaceSummary(readSurface, session.sessionId);
504
+ if (session.hostId !== hostId && gatewayResult?.readSummary !== undefined)
505
+ return gatewayResult.readSummary(session);
506
+ return session.summary ?? null;
507
+ },
508
+ }),
509
+ ...((gatewayResult?.readWaiting === undefined) ? {} : {
510
+ readWaiting: async (session) => {
511
+ if (session.hostId !== hostId)
512
+ return gatewayResult.readWaiting(session);
513
+ return session.waiting ?? null;
514
+ },
515
+ }),
516
+ };
517
+ }
518
+ async function readSessionTitle(readTitle, sessionId) {
519
+ try {
520
+ const value = await readTitle(sessionId);
521
+ if (typeof value === 'string' && value.trim() !== '')
522
+ return value.trim();
523
+ if (isRecord(value)) {
524
+ for (const key of ['title', 'value', 'text'])
525
+ if (typeof value[key] === 'string' && value[key].trim() !== '')
526
+ return value[key].trim();
527
+ const events = value.events;
528
+ if (Array.isArray(events)) {
529
+ for (let index = events.length - 1; index >= 0; index -= 1) {
530
+ const event = asRecord(events[index]);
531
+ const title = readText(event, ['title', 'value', 'text']) ?? readText(asRecord(event?.data), ['title']);
532
+ if (title !== null)
533
+ return title;
534
+ }
535
+ }
536
+ }
537
+ }
538
+ catch {
539
+ // 单个标题查询失败不阻断其余会话索引。
540
+ }
541
+ return null;
542
+ }
543
+ async function readSurfaceSummary(readSurface, sessionId) {
544
+ const value = await readSurface(sessionId);
545
+ if (typeof value === 'string')
546
+ return value.slice(0, 2000);
547
+ if (!isRecord(value))
548
+ return null;
549
+ for (const key of ['summary', 'text', 'content', 'surface'])
550
+ if (typeof value[key] === 'string')
551
+ return value[key].slice(0, 2000);
552
+ if (Array.isArray(value.events))
553
+ return summarizeSurfaceEvents(value.events);
554
+ return null;
555
+ }
556
+ /**
557
+ * readSurface 返回的是已经过滤过的模型表层事件。这里只读取最后几条语义事件,
558
+ * 不遍历原始日志,也不把工具流式 chunk 当成用户或助理正文。
559
+ */
560
+ export function summarizeSurfaceEvents(events) {
561
+ let latestUser = null;
562
+ let latestAssistant = null;
563
+ let latestTool = null;
564
+ for (const raw of events.slice(-80)) {
565
+ const event = asRecord(raw);
566
+ if (event === null)
567
+ continue;
568
+ const type = readText(event, ['type', 'kind', 'event']) ?? '';
569
+ const data = asRecord(event.data);
570
+ const text = readEventText(event) ?? (data === null ? null : readEventText(data));
571
+ if (type === 'user/message' || type === 'user.message' || type === 'message/user') {
572
+ if (text !== null)
573
+ latestUser = text;
574
+ }
575
+ else if (type === 'assistant/message' || type === 'assistant.message' || type === 'message/assistant') {
576
+ if (text !== null)
577
+ latestAssistant = text;
578
+ }
579
+ else if (type === 'tool/call' || type === 'tool.call' || type === 'tool-call' || type === 'tool/result' || type === 'tool.result' || type === 'tool-result') {
580
+ const tool = readText(event, ['name', 'tool', 'toolName']) ?? (data === null ? null : readText(data, ['name', 'tool', 'toolName']));
581
+ if (tool !== null)
582
+ latestTool = tool;
583
+ }
584
+ }
585
+ const parts = [
586
+ latestUser === null ? null : `用户:${latestUser}`,
587
+ latestAssistant === null ? null : `助理:${latestAssistant}`,
588
+ latestTool === null ? null : `工具:${latestTool}`,
589
+ ].filter((item) => item !== null);
590
+ return parts.length === 0 ? null : parts.join(';').slice(0, 2000);
591
+ }
592
+ function readEventText(value) {
593
+ for (const key of ['text', 'message', 'content', 'summary', 'transcript']) {
594
+ const candidate = value[key];
595
+ if (typeof candidate === 'string' && candidate.trim() !== '')
596
+ return candidate.trim();
597
+ if (Array.isArray(candidate)) {
598
+ const text = candidate
599
+ .map((item) => {
600
+ if (typeof item === 'string')
601
+ return item;
602
+ const record = asRecord(item);
603
+ return record === null ? '' : readText(record, ['text', 'content', 'value']) ?? '';
604
+ })
605
+ .join(' ')
606
+ .trim();
607
+ if (text !== '')
608
+ return text;
609
+ }
610
+ }
611
+ return null;
612
+ }
613
+ function readPendingWaiting(ctx) {
614
+ const service = readOptionalService(ctx, 'uiSession');
615
+ const pending = service?.pendingInteractions;
616
+ const result = new Map();
617
+ const values = pending instanceof Map
618
+ ? [...pending.values()]
619
+ : Array.isArray(pending)
620
+ ? pending
621
+ : isRecord(pending)
622
+ ? Object.values(pending)
623
+ : [];
624
+ for (const raw of values) {
625
+ const value = asRecord(raw);
626
+ if (value === null)
627
+ continue;
628
+ const sessionId = readText(value, ['sessionId', 'id']) ?? readText(asRecord(value.session), ['sessionId', 'id']);
629
+ const kind = readWaiting(value);
630
+ if (sessionId !== null && kind !== null)
631
+ result.set(sessionId, kind);
632
+ }
633
+ return result;
634
+ }
635
+ function readWaitingSessionId(args) {
636
+ const queue = [...args];
637
+ const seen = new Set();
638
+ while (queue.length > 0) {
639
+ const candidate = queue.shift();
640
+ const value = asRecord(candidate);
641
+ if (value === null)
642
+ continue;
643
+ if (seen.has(value))
644
+ continue;
645
+ seen.add(value);
646
+ const sessionId = readText(value, ['sessionId', 'session_id', 'id']) ?? readText(asRecord(value.session), ['sessionId', 'session_id', 'id']);
647
+ if (sessionId !== null)
648
+ return sessionId;
649
+ for (const key of ['data', 'request', 'interaction', 'payload', 'result', 'session']) {
650
+ if (value[key] !== undefined)
651
+ queue.push(value[key]);
652
+ }
653
+ }
654
+ return null;
655
+ }
656
+ function readWorkspaceRecords(ctx) {
657
+ const registry = readOptionalService(ctx, 'workspaceRegistry');
658
+ const list = registry !== undefined && typeof registry.list === 'function' ? registry.list() : [];
659
+ if (!Array.isArray(list))
660
+ return [];
661
+ return list.flatMap((raw) => {
662
+ const value = asRecord(raw);
663
+ const id = readText(value, ['id', 'workspaceId', 'key']);
664
+ if (id === null)
665
+ return [];
666
+ const archived = value?.archivedSessionIds;
667
+ const sessionIds = value?.sessionIds;
668
+ return [{
669
+ id,
670
+ name: readText(value, ['displayName', 'name', 'title']) ?? id,
671
+ path: readText(value, ['path', 'cwd']),
672
+ sessionIds: readStringArray(sessionIds),
673
+ archivedSessionIds: Array.isArray(archived) ? archived.filter((item) => typeof item === 'string') : [],
674
+ }];
675
+ });
676
+ }
677
+ function flattenSessionList(value) {
678
+ if (Array.isArray(value))
679
+ return value;
680
+ if (!isRecord(value))
681
+ return [];
682
+ const result = [];
683
+ for (const key of ['header', 'live', 'persisted', 'items', 'sessions']) {
684
+ const item = value[key];
685
+ if (Array.isArray(item))
686
+ result.push(...item);
687
+ else if (isRecord(item) && key === 'header')
688
+ result.push(value);
689
+ }
690
+ return result;
691
+ }
692
+ function dedupeSessionRecords(values) {
693
+ const seen = new Set();
694
+ const result = [];
695
+ for (const value of values) {
696
+ const record = asRecord(value);
697
+ const header = asRecord(record?.header) ?? record;
698
+ const id = readText(header, ['sessionId', 'id', 'key']);
699
+ if (id === null)
700
+ continue;
701
+ const hostId = readText(record, ['hostId', 'sourceHostId']) ?? readText(header, ['hostId', 'sourceHostId']) ?? 'local';
702
+ const key = `${hostId}:${id}`;
703
+ if (seen.has(key))
704
+ continue;
705
+ seen.add(key);
706
+ result.push(value);
707
+ }
708
+ return result;
709
+ }
710
+ function findWorkspaceId(sessionId, header, workspaces) {
711
+ for (const workspace of workspaces)
712
+ if (workspace.sessionIds.includes(sessionId))
713
+ return workspace.id;
714
+ const cwd = readText(header, ['cwd']);
715
+ if (cwd === null)
716
+ return null;
717
+ const candidate = workspaces.find((workspace) => workspace.path !== null && (cwd === workspace.path || cwd.startsWith(`${workspace.path}/`)));
718
+ return candidate?.id ?? null;
719
+ }
720
+ function readAssistantVoiceSettings(services) {
721
+ const configured = services.settings?.get().assistant?.voice;
722
+ return configured === undefined ? DEFAULT_ASSISTANT_VOICE_SETTINGS : {
723
+ ...DEFAULT_ASSISTANT_VOICE_SETTINGS,
724
+ ...configured,
725
+ };
726
+ }
727
+ function readVoiceModelId(payload) {
728
+ if (!isRecord(payload) || typeof payload.modelId !== 'string' || payload.modelId.trim() === '') {
729
+ throw new TypeError('实时语音初始化缺少模型选择');
730
+ }
731
+ return payload.modelId.trim();
732
+ }
733
+ function validateAssistantVoiceSettings(settings) {
734
+ if (!settings.initialized)
735
+ return '请先完成全局语音助理初始化配置';
736
+ if (settings.provider !== 'sherpa-onnx')
737
+ return '当前语音配置已停用,请选择 Sherpa-ONNX 实时模型';
738
+ const missing = [
739
+ ['asrEncoder', 'ASR encoder'],
740
+ ['asrDecoder', 'ASR decoder'],
741
+ ['asrJoiner', 'ASR joiner'],
742
+ ['asrTokens', 'ASR tokens'],
743
+ ];
744
+ const field = missing.find(([key]) => settings[key].trim() === '');
745
+ return field === undefined ? undefined : `Sherpa-ONNX 尚未配置 ${field[1]} 模型文件`;
746
+ }
747
+ function buildSherpaRuntimeEnvironment(settings) {
748
+ return {
749
+ ...process.env,
750
+ CODINGNS4DSH_VOICE_RUNTIME_PACKAGE: 'sherpa-onnx-node',
751
+ CODINGNS4DSH_VOICE_ASR_ENCODER: settings.asrEncoder,
752
+ CODINGNS4DSH_VOICE_ASR_DECODER: settings.asrDecoder,
753
+ CODINGNS4DSH_VOICE_ASR_JOINER: settings.asrJoiner,
754
+ CODINGNS4DSH_VOICE_ASR_TOKENS: settings.asrTokens,
755
+ CODINGNS4DSH_VOICE_VAD_MODEL: settings.vadModel,
756
+ CODINGNS4DSH_VOICE_TTS_MODEL: settings.ttsModel,
757
+ CODINGNS4DSH_VOICE_TTS_TOKENS: settings.ttsTokens,
758
+ CODINGNS4DSH_VOICE_TTS_LEXICON: settings.ttsLexicon,
759
+ };
760
+ }
761
+ /** Sherpa 运行时缺包或模型加载失败时,把真实原因返回给实时对话窗口。 */
762
+ function isVoiceRuntimeUnavailableError(error) {
763
+ const code = isRecord(error) && typeof error.code === 'string' ? error.code : '';
764
+ const message = error instanceof Error ? error.message : String(error);
765
+ return code === 'ERR_MODULE_NOT_FOUND' || /Sherpa-ONNX|CODINGNS4DSH_VOICE_/u.test(message);
766
+ }
767
+ function readOptionalService(ctx, name) {
768
+ if (ctx === undefined || ctx === null || typeof ctx.get !== 'function')
769
+ return undefined;
770
+ try {
771
+ const value = ctx.get(name);
772
+ return isRecord(value) ? value : undefined;
773
+ }
774
+ catch {
775
+ return undefined;
776
+ }
777
+ }
778
+ function asRecord(value) {
779
+ return typeof value === 'object' && value !== null && !Array.isArray(value) ? value : null;
780
+ }
781
+ function readText(value, keys) {
782
+ if (value === null)
783
+ return null;
784
+ for (const key of keys)
785
+ if (typeof value[key] === 'string' && value[key].trim() !== '')
786
+ return value[key].trim();
787
+ return null;
788
+ }
789
+ function readStringArray(value) {
790
+ return Array.isArray(value) ? value.filter((item) => typeof item === 'string' && item.trim() !== '') : [];
791
+ }
792
+ function readVoiceRuntimeCapabilities(payload) {
793
+ const value = isRecord(payload) && isRecord(payload.capabilities) ? payload.capabilities : {};
794
+ return {
795
+ realtime: value.realtime === true,
796
+ wakeWord: value.wakeWord === true,
797
+ streamingInput: value.streamingInput === true,
798
+ streamingOutput: value.streamingOutput === true,
799
+ bargeIn: value.bargeIn === true,
800
+ speechToText: value.speechToText === true,
801
+ textToSpeech: value.textToSpeech === true,
802
+ };
803
+ }
804
+ function unavailableVoiceCapabilities() {
805
+ return {
806
+ realtime: false,
807
+ wakeWord: false,
808
+ streamingInput: false,
809
+ streamingOutput: false,
810
+ bargeIn: false,
811
+ speechToText: false,
812
+ textToSpeech: false,
813
+ };
814
+ }
815
+ function readVoiceRuntimeEvent(payload) {
816
+ const value = isRecord(payload) && isRecord(payload.event) ? payload.event : null;
817
+ const epoch = value !== null && typeof value.epoch === 'number' && Number.isFinite(value.epoch) ? value.epoch : null;
818
+ if (value === null || epoch === null || typeof value.type !== 'string')
819
+ throw new TypeError('全局语音 RPC 的 event 无效');
820
+ const states = ['disabled', 'loading', 'standby', 'listening', 'speaking', 'interrupted', 'error'];
821
+ if (value.type === 'state' && states.includes(value.state))
822
+ return { type: 'state', state: value.state, epoch };
823
+ if (value.type === 'wake')
824
+ return { type: 'wake', epoch };
825
+ if (value.type === 'barge-in')
826
+ return { type: 'barge-in', epoch };
827
+ if (value.type === 'error' && typeof value.code === 'string' && typeof value.message === 'string') {
828
+ return { type: 'error', code: value.code, message: value.message, recoverable: value.recoverable !== false, epoch };
829
+ }
830
+ throw new TypeError('全局语音 RPC 不允许转发该 event 类型');
831
+ }
832
+ function readWaiting(value) {
833
+ if (value === null)
834
+ return null;
835
+ const candidate = value.waiting ?? value.pendingInteraction ?? value.pending;
836
+ if (candidate === 'approval' || candidate === 'question')
837
+ return candidate;
838
+ if (isRecord(candidate)) {
839
+ const kind = candidate.kind ?? candidate.type;
840
+ if (kind === 'approval' || kind === 'question')
841
+ return kind;
842
+ }
843
+ return null;
844
+ }
845
+ function readTimestamp(value, keys) {
846
+ if (value === null)
847
+ return null;
848
+ for (const key of keys) {
849
+ if (typeof value[key] === 'number' && Number.isFinite(value[key]))
850
+ return value[key];
851
+ if (typeof value[key] === 'string') {
852
+ const parsed = Date.parse(value[key]);
853
+ if (Number.isFinite(parsed))
854
+ return parsed;
855
+ }
856
+ }
857
+ return null;
858
+ }
859
+ function isRecord(value) {
860
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
861
+ }
862
+ //# sourceMappingURL=global-voice-rpc.js.map