@qvac/sdk 0.9.2 → 0.10.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 (343) hide show
  1. package/NOTICE +42 -95
  2. package/dist/client/api/cancel.d.ts +1 -1
  3. package/dist/client/api/cancel.js +1 -1
  4. package/dist/client/api/completion-stream.d.ts +51 -12
  5. package/dist/client/api/completion-stream.js +129 -56
  6. package/dist/client/api/delete-cache.d.ts +1 -0
  7. package/dist/client/api/delete-cache.js +1 -0
  8. package/dist/client/api/diffusion.d.ts +17 -2
  9. package/dist/client/api/diffusion.js +21 -4
  10. package/dist/client/api/embed.d.ts +4 -0
  11. package/dist/client/api/finetune.d.ts +21 -0
  12. package/dist/client/api/get-loaded-model-info.d.ts +25 -0
  13. package/dist/client/api/get-loaded-model-info.js +36 -0
  14. package/dist/client/api/get-model-info.d.ts +9 -1
  15. package/dist/client/api/get-model-info.js +8 -0
  16. package/dist/client/api/heartbeat.d.ts +2 -2
  17. package/dist/client/api/heartbeat.js +2 -2
  18. package/dist/client/api/index.d.ts +3 -1
  19. package/dist/client/api/index.js +3 -1
  20. package/dist/client/api/invoke-plugin.d.ts +16 -0
  21. package/dist/client/api/invoke-plugin.js +16 -0
  22. package/dist/client/api/load-model.d.ts +36 -3
  23. package/dist/client/api/load-model.js +31 -10
  24. package/dist/client/api/provide.d.ts +11 -5
  25. package/dist/client/api/provide.js +11 -6
  26. package/dist/client/api/rag.d.ts +9 -0
  27. package/dist/client/api/rag.js +9 -0
  28. package/dist/client/api/registry.d.ts +26 -0
  29. package/dist/client/api/registry.js +26 -0
  30. package/dist/client/api/resume.d.ts +20 -4
  31. package/dist/client/api/resume.js +20 -4
  32. package/dist/client/api/state.d.ts +23 -0
  33. package/dist/client/api/state.js +29 -0
  34. package/dist/client/api/stop-provider.d.ts +11 -5
  35. package/dist/client/api/stop-provider.js +11 -5
  36. package/dist/client/api/suspend.d.ts +21 -3
  37. package/dist/client/api/suspend.js +21 -3
  38. package/dist/client/api/text-to-speech.d.ts +64 -6
  39. package/dist/client/api/text-to-speech.js +423 -47
  40. package/dist/client/api/transcribe.d.ts +29 -4
  41. package/dist/client/api/transcribe.js +86 -28
  42. package/dist/client/api/translate.d.ts +1 -0
  43. package/dist/client/api/translate.js +1 -0
  44. package/dist/client/rpc/bare-client.js +22 -1
  45. package/dist/client/rpc/expo-rpc-client.d.ts +1 -1
  46. package/dist/client/rpc/expo-rpc-client.js +96 -4
  47. package/dist/client/rpc/node-rpc-client.js +36 -0
  48. package/dist/examples/audio/mic-input.d.ts +9 -0
  49. package/dist/examples/audio/mic-input.js +111 -0
  50. package/dist/examples/completion-events.d.ts +18 -0
  51. package/dist/examples/completion-events.js +79 -0
  52. package/dist/examples/delegated-inference/composite.js +12 -18
  53. package/dist/examples/delegated-inference/consumer-profiled.js +4 -11
  54. package/dist/examples/delegated-inference/consumer.js +8 -13
  55. package/dist/examples/delegated-inference/provider.js +11 -16
  56. package/dist/examples/diffusion-flux2-klein-img2img.d.ts +2 -0
  57. package/dist/examples/diffusion-flux2-klein-img2img.js +60 -0
  58. package/dist/examples/diffusion-flux2-klein.js +1 -0
  59. package/dist/examples/diffusion-img2img.d.ts +2 -0
  60. package/dist/examples/diffusion-img2img.js +49 -0
  61. package/dist/examples/diffusion-txt2img.js +2 -1
  62. package/dist/examples/kv-cache-example.js +11 -12
  63. package/dist/examples/llamacpp-cache.d.ts +2 -0
  64. package/dist/examples/llamacpp-cache.js +107 -0
  65. package/dist/examples/llamacpp-dynamic-tools.d.ts +2 -0
  66. package/dist/examples/llamacpp-dynamic-tools.js +144 -0
  67. package/dist/examples/llamacpp-structured-output.d.ts +2 -0
  68. package/dist/examples/llamacpp-structured-output.js +106 -0
  69. package/dist/examples/plugins.js +4 -4
  70. package/dist/examples/suspend-resume.js +21 -4
  71. package/dist/examples/{llamacpp-native-tools.js → tools/llamacpp-native-tools.js} +6 -55
  72. package/dist/examples/tools/llamacpp-tools-harmony-multiturn.d.ts +2 -0
  73. package/dist/examples/tools/llamacpp-tools-harmony-multiturn.js +81 -0
  74. package/dist/examples/tools/llamacpp-tools-pythonic.d.ts +2 -0
  75. package/dist/examples/tools/llamacpp-tools-pythonic.js +50 -0
  76. package/dist/examples/tools/shared.d.ts +21 -0
  77. package/dist/examples/tools/shared.js +42 -0
  78. package/dist/examples/transcription/parakeet-microphone-record.js +6 -33
  79. package/dist/examples/transcription/whispercpp-filesystem-streaming.js +7 -5
  80. package/dist/examples/transcription/whispercpp-filesystem.js +12 -3
  81. package/dist/examples/transcription/whispercpp-microphone-record.js +6 -29
  82. package/dist/examples/translation/translation-stream.js +5 -5
  83. package/dist/examples/tts/llm-to-tts-streaming.d.ts +16 -0
  84. package/dist/examples/tts/llm-to-tts-streaming.js +143 -0
  85. package/dist/examples/tts/supertonic-multilingual.js +3 -3
  86. package/dist/examples/tts/supertonic.js +3 -3
  87. package/dist/examples/tts/utils.d.ts +11 -1
  88. package/dist/examples/tts/utils.js +70 -17
  89. package/dist/examples/voice-assistant/voice-assistant.d.ts +2 -0
  90. package/dist/examples/voice-assistant/voice-assistant.js +207 -0
  91. package/dist/expo/plugins/withMobileBundle.js +1 -1
  92. package/dist/index.d.ts +2 -2
  93. package/dist/index.js +2 -2
  94. package/dist/logging/logger.d.ts +11 -0
  95. package/dist/logging/logger.js +11 -0
  96. package/dist/logging/types.d.ts +18 -0
  97. package/dist/models/registry/models.d.ts +6973 -7457
  98. package/dist/models/registry/models.js +6889 -6855
  99. package/dist/models/update-models/codegen.js +84 -23
  100. package/dist/models/update-models/companions.d.ts +18 -0
  101. package/dist/models/update-models/companions.js +175 -0
  102. package/dist/models/update-models/naming.js +0 -25
  103. package/dist/models/update-models/registry.d.ts +1 -0
  104. package/dist/models/update-models/registry.js +23 -3
  105. package/dist/models/update-models/types.d.ts +37 -9
  106. package/dist/profiling/index.d.ts +49 -0
  107. package/dist/profiling/index.js +49 -0
  108. package/dist/schemas/cancel.d.ts +6 -2
  109. package/dist/schemas/cancel.js +14 -7
  110. package/dist/schemas/common.d.ts +354 -271
  111. package/dist/schemas/common.js +26 -5
  112. package/dist/schemas/completion-event.d.ts +225 -0
  113. package/dist/schemas/completion-event.js +79 -0
  114. package/dist/schemas/completion-stream.d.ts +126 -31
  115. package/dist/schemas/completion-stream.js +138 -36
  116. package/dist/schemas/delegate.d.ts +0 -2
  117. package/dist/schemas/delegate.js +25 -6
  118. package/dist/schemas/download-asset.d.ts +5 -5
  119. package/dist/schemas/embed.js +21 -9
  120. package/dist/schemas/engine-addon-map.d.ts +11 -1
  121. package/dist/schemas/engine-addon-map.js +2 -2
  122. package/dist/schemas/get-loaded-model-info.d.ts +52 -0
  123. package/dist/schemas/get-loaded-model-info.js +44 -0
  124. package/dist/schemas/get-model-info.d.ts +2 -2
  125. package/dist/schemas/get-model-info.js +103 -32
  126. package/dist/schemas/heartbeat.d.ts +0 -1
  127. package/dist/schemas/index.d.ts +4 -1
  128. package/dist/schemas/index.js +4 -1
  129. package/dist/schemas/llamacpp-config.d.ts +14 -4
  130. package/dist/schemas/llamacpp-config.js +5 -0
  131. package/dist/schemas/load-model.d.ts +3233 -1260
  132. package/dist/schemas/load-model.js +23 -16
  133. package/dist/schemas/model-src-utils.d.ts +7 -6
  134. package/dist/schemas/model-src-utils.js +27 -1
  135. package/dist/schemas/model-types.d.ts +4 -4
  136. package/dist/schemas/ocr.d.ts +1 -1
  137. package/dist/schemas/plugin.d.ts +27 -3
  138. package/dist/schemas/plugin.js +27 -2
  139. package/dist/schemas/profiling.js +11 -3
  140. package/dist/schemas/provide.d.ts +1 -3
  141. package/dist/schemas/provide.js +0 -3
  142. package/dist/schemas/rag.d.ts +4 -4
  143. package/dist/schemas/registry.d.ts +10 -10
  144. package/dist/schemas/registry.js +36 -14
  145. package/dist/schemas/reload-config.d.ts +73 -7
  146. package/dist/schemas/sdcpp-config.d.ts +16 -8
  147. package/dist/schemas/sdcpp-config.js +118 -25
  148. package/dist/schemas/sdk-config.d.ts +116 -90
  149. package/dist/schemas/sdk-config.js +16 -0
  150. package/dist/schemas/sdk-errors-client.d.ts +3 -0
  151. package/dist/schemas/sdk-errors-client.js +16 -1
  152. package/dist/schemas/sdk-errors-server.d.ts +3 -0
  153. package/dist/schemas/sdk-errors-server.js +23 -0
  154. package/dist/schemas/state.d.ts +23 -0
  155. package/dist/schemas/state.js +14 -0
  156. package/dist/schemas/stop-provide.d.ts +0 -5
  157. package/dist/schemas/stop-provide.js +2 -6
  158. package/dist/schemas/text-to-speech.d.ts +93 -27
  159. package/dist/schemas/text-to-speech.js +27 -0
  160. package/dist/schemas/tools.d.ts +16 -0
  161. package/dist/schemas/tools.js +15 -0
  162. package/dist/schemas/transcription-config.d.ts +8 -8
  163. package/dist/schemas/transcription.d.ts +33 -0
  164. package/dist/schemas/transcription.js +9 -0
  165. package/dist/schemas/translate.js +59 -19
  166. package/dist/schemas/translation-config.d.ts +157 -133
  167. package/dist/schemas/translation-config.js +34 -11
  168. package/dist/server/bare/delegate-rpc-client.d.ts +1 -1
  169. package/dist/server/bare/delegate-rpc-client.js +131 -122
  170. package/dist/server/bare/hyperswarm.d.ts +2 -2
  171. package/dist/server/bare/hyperswarm.js +12 -7
  172. package/dist/server/bare/ops/cancel.js +7 -0
  173. package/dist/server/bare/ops/kv-cache-utils.d.ts +7 -10
  174. package/dist/server/bare/ops/kv-cache-utils.js +31 -40
  175. package/dist/server/bare/ops/load-model.js +0 -1
  176. package/dist/server/bare/ops/transcribe.d.ts +11 -4
  177. package/dist/server/bare/ops/transcribe.js +25 -4
  178. package/dist/server/bare/ops/translate.js +42 -4
  179. package/dist/server/bare/ops/unload-model.js +21 -19
  180. package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.js +1 -2
  181. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +13 -8
  182. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +257 -85
  183. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.d.ts +101 -0
  184. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.js +135 -0
  185. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +80 -22
  186. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +57 -32
  187. package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +10 -16
  188. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +69 -44
  189. package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +54 -116
  190. package/dist/server/bare/plugins/nmtcpp-translation/resolve-vocab.d.ts +32 -0
  191. package/dist/server/bare/plugins/nmtcpp-translation/resolve-vocab.js +117 -0
  192. package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +1 -1
  193. package/dist/server/bare/plugins/onnx-ocr/plugin.js +1 -2
  194. package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech-stream.d.ts +7 -0
  195. package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech-stream.js +116 -0
  196. package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech.d.ts +2 -3
  197. package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech.js +71 -9
  198. package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +41 -13
  199. package/dist/server/bare/plugins/onnx-tts/plugin.js +48 -3
  200. package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +15 -7
  201. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +5 -6
  202. package/dist/server/bare/plugins/sdcpp-generation/ops/diffusion.js +6 -0
  203. package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +8 -5
  204. package/dist/server/bare/plugins/sdcpp-generation/plugin.js +13 -13
  205. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +17 -1
  206. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +40 -17
  207. package/dist/server/bare/registry/config-registry.js +14 -3
  208. package/dist/server/bare/registry/model-registry.d.ts +8 -10
  209. package/dist/server/bare/registry/model-registry.js +17 -12
  210. package/dist/server/bare/registry/registry-client.js +79 -19
  211. package/dist/server/bare/runtime-lifecycle.d.ts +2 -1
  212. package/dist/server/bare/runtime-lifecycle.js +13 -2
  213. package/dist/server/bare/types/addon-responses.d.ts +8 -3
  214. package/dist/server/bare/utils/transcribe-metadata.d.ts +21 -0
  215. package/dist/server/bare/utils/transcribe-metadata.js +28 -0
  216. package/dist/server/bare/utils/tts-stats.d.ts +22 -0
  217. package/dist/server/bare/utils/tts-stats.js +10 -0
  218. package/dist/server/rpc/create-server.d.ts +4 -1
  219. package/dist/server/rpc/create-server.js +5 -1
  220. package/dist/server/rpc/delegate-transport.js +36 -29
  221. package/dist/server/rpc/handle-request.js +28 -3
  222. package/dist/server/rpc/handler-registry.js +7 -1
  223. package/dist/server/rpc/handler-utils.d.ts +5 -0
  224. package/dist/server/rpc/handler-utils.js +22 -0
  225. package/dist/server/rpc/handlers/cancel-delegated.js +3 -5
  226. package/dist/server/rpc/handlers/cancelHandler.js +4 -5
  227. package/dist/server/rpc/handlers/completion-stream-delegated.js +14 -5
  228. package/dist/server/rpc/handlers/delete-cache.js +8 -3
  229. package/dist/server/rpc/handlers/download-asset.js +3 -24
  230. package/dist/server/rpc/handlers/get-loaded-model-info.d.ts +3 -0
  231. package/dist/server/rpc/handlers/get-loaded-model-info.js +39 -0
  232. package/dist/server/rpc/handlers/get-model-info.js +93 -84
  233. package/dist/server/rpc/handlers/heartbeat-delegated.js +2 -2
  234. package/dist/server/rpc/handlers/index.d.ts +6 -0
  235. package/dist/server/rpc/handlers/index.js +6 -0
  236. package/dist/server/rpc/handlers/load-model/download-manager.d.ts +35 -9
  237. package/dist/server/rpc/handlers/load-model/download-manager.js +142 -38
  238. package/dist/server/rpc/handlers/load-model/download-stats.d.ts +5 -4
  239. package/dist/server/rpc/handlers/load-model/download-stats.js +49 -8
  240. package/dist/server/rpc/handlers/load-model/handler.js +31 -50
  241. package/dist/server/rpc/handlers/load-model/http.d.ts +2 -2
  242. package/dist/server/rpc/handlers/load-model/http.js +97 -142
  243. package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +2 -2
  244. package/dist/server/rpc/handlers/load-model/hyperdrive.js +55 -74
  245. package/dist/server/rpc/handlers/load-model/index.d.ts +0 -1
  246. package/dist/server/rpc/handlers/load-model/index.js +0 -1
  247. package/dist/server/rpc/handlers/load-model/registry-client-options.d.ts +27 -0
  248. package/dist/server/rpc/handlers/load-model/registry-client-options.js +19 -0
  249. package/dist/server/rpc/handlers/load-model/registry-companion-set.d.ts +22 -0
  250. package/dist/server/rpc/handlers/load-model/registry-companion-set.js +208 -0
  251. package/dist/server/rpc/handlers/load-model/registry-download-utils.d.ts +24 -0
  252. package/dist/server/rpc/handlers/load-model/registry-download-utils.js +114 -0
  253. package/dist/server/rpc/handlers/load-model/registry.d.ts +2 -20
  254. package/dist/server/rpc/handlers/load-model/registry.js +109 -381
  255. package/dist/server/rpc/handlers/load-model/resolve-session.d.ts +15 -0
  256. package/dist/server/rpc/handlers/load-model/resolve-session.js +61 -0
  257. package/dist/server/rpc/handlers/load-model/resolve.d.ts +3 -3
  258. package/dist/server/rpc/handlers/load-model/resolve.js +14 -23
  259. package/dist/server/rpc/handlers/load-model/types.d.ts +11 -4
  260. package/dist/server/rpc/handlers/load-model/types.js +28 -1
  261. package/dist/server/rpc/handlers/load-model-delegated.js +2 -4
  262. package/dist/server/rpc/handlers/plugin-dispatch.js +9 -5
  263. package/dist/server/rpc/handlers/plugin-invoke.js +1 -1
  264. package/dist/server/rpc/handlers/provideHandler/connection.js +13 -2
  265. package/dist/server/rpc/handlers/provideHandler/handler.js +42 -29
  266. package/dist/server/rpc/handlers/state.d.ts +3 -0
  267. package/dist/server/rpc/handlers/state.js +7 -0
  268. package/dist/server/rpc/handlers/stopProvideHandler.d.ts +2 -2
  269. package/dist/server/rpc/handlers/stopProvideHandler.js +12 -7
  270. package/dist/server/rpc/handlers/text-to-speech-stream.d.ts +3 -0
  271. package/dist/server/rpc/handlers/text-to-speech-stream.js +4 -0
  272. package/dist/server/rpc/handlers/unload-model-delegated.js +3 -3
  273. package/dist/server/rpc/profiling/operation-metrics.js +20 -0
  274. package/dist/server/rpc/rpc-utils.js +1 -1
  275. package/dist/server/rpc/transport-selector.d.ts +3 -0
  276. package/dist/server/rpc/transport-selector.js +18 -0
  277. package/dist/server/utils/cache/auto-history.d.ts +4 -0
  278. package/dist/server/utils/cache/auto-history.js +22 -0
  279. package/dist/server/utils/{cache.d.ts → cache/paths.d.ts} +22 -5
  280. package/dist/server/utils/{cache.js → cache/paths.js} +36 -20
  281. package/dist/server/utils/cache/types.d.ts +8 -0
  282. package/dist/server/utils/cache/types.js +1 -0
  283. package/dist/server/utils/checksum.d.ts +2 -2
  284. package/dist/server/utils/checksum.js +1 -1
  285. package/dist/server/utils/clear-storage.d.ts +5 -0
  286. package/dist/server/utils/clear-storage.js +17 -0
  287. package/dist/server/utils/completion-normalizer.d.ts +17 -0
  288. package/dist/server/utils/completion-normalizer.js +413 -0
  289. package/dist/server/utils/expand-gguf-shards.d.ts +3 -0
  290. package/dist/server/utils/expand-gguf-shards.js +22 -0
  291. package/dist/server/utils/formatting.js +1 -1
  292. package/dist/server/utils/index.d.ts +4 -2
  293. package/dist/server/utils/index.js +4 -2
  294. package/dist/server/utils/qvac-paths.d.ts +2 -0
  295. package/dist/server/utils/qvac-paths.js +5 -0
  296. package/dist/server/utils/response-format.d.ts +3 -0
  297. package/dist/server/utils/response-format.js +20 -0
  298. package/dist/server/utils/tool-integration.d.ts +15 -4
  299. package/dist/server/utils/tool-integration.js +21 -41
  300. package/dist/server/utils/tools/dialect.d.ts +8 -0
  301. package/dist/server/utils/tools/dialect.js +14 -0
  302. package/dist/server/utils/tools/index.d.ts +3 -0
  303. package/dist/server/utils/tools/index.js +2 -0
  304. package/dist/server/utils/tools/parser.d.ts +6 -0
  305. package/dist/server/utils/tools/parser.js +46 -0
  306. package/dist/server/utils/tools/parsers/harmony.d.ts +4 -0
  307. package/dist/server/utils/tools/parsers/harmony.js +59 -0
  308. package/dist/server/utils/tools/parsers/hermes.d.ts +4 -0
  309. package/dist/server/utils/tools/parsers/hermes.js +100 -0
  310. package/dist/server/utils/tools/parsers/json.d.ts +6 -0
  311. package/dist/server/utils/tools/parsers/json.js +115 -0
  312. package/dist/server/utils/tools/parsers/pythonic.d.ts +4 -0
  313. package/dist/server/utils/tools/parsers/pythonic.js +267 -0
  314. package/dist/server/utils/tools/shared.d.ts +18 -0
  315. package/dist/server/utils/tools/shared.js +54 -0
  316. package/dist/server/utils/worker-lock.d.ts +3 -0
  317. package/dist/server/utils/worker-lock.js +67 -0
  318. package/dist/server/worker-core.d.ts +16 -1
  319. package/dist/server/worker-core.js +114 -14
  320. package/dist/utils/aggregate-events.d.ts +16 -0
  321. package/dist/utils/aggregate-events.js +52 -0
  322. package/dist/utils/cache-normalize.d.ts +10 -0
  323. package/dist/utils/cache-normalize.js +23 -0
  324. package/dist/utils/encoding.d.ts +8 -0
  325. package/dist/utils/encoding.js +13 -0
  326. package/dist/utils/errors-client.d.ts +12 -0
  327. package/dist/utils/errors-client.js +20 -0
  328. package/dist/utils/errors-server.d.ts +14 -0
  329. package/dist/utils/errors-server.js +31 -0
  330. package/dist/utils/load-model-validation.d.ts +7 -0
  331. package/dist/utils/load-model-validation.js +18 -0
  332. package/expo/plugins/patches/android-link.mjs +1 -1
  333. package/expo/plugins/patches/ios-link.mjs +1 -1
  334. package/package.json +14 -18
  335. package/dist/examples/translation/translation-opus.d.ts +0 -2
  336. package/dist/examples/translation/translation-opus.js +0 -33
  337. package/dist/server/bare/utils/loader-adapter.d.ts +0 -7
  338. package/dist/server/bare/utils/loader-adapter.js +0 -9
  339. package/dist/server/utils/model-path.d.ts +0 -5
  340. package/dist/server/utils/model-path.js +0 -7
  341. package/dist/server/utils/tool-parser.d.ts +0 -7
  342. package/dist/server/utils/tool-parser.js +0 -248
  343. /package/dist/examples/{llamacpp-native-tools.d.ts → tools/llamacpp-native-tools.d.ts} +0 -0
@@ -2,17 +2,23 @@ import {} from "../../schemas/index.js";
2
2
  import { send } from "../rpc/rpc-client.js";
3
3
  import { InvalidResponseError, ProviderStopFailedError, } from "../../utils/errors-client.js";
4
4
  /**
5
- * Stops a running provider service and leaves the specified topic.
5
+ * Stops the running provider service.
6
+ *
7
+ * After this call returns, incoming peer connections are dropped at the RPC
8
+ * layer and remote `loadModel`/`completion`/etc. requests will no longer be
9
+ * served. The keyPair stays bound on the DHT (a `swarm.listen()` cannot be
10
+ * undone without tearing down the shared swarm), so peers may still open a
11
+ * raw socket — but those sockets are immediately destroyed and no RPC server
12
+ * is mounted on them.
13
+ *
14
+ * Idempotent: calling more than once with no provider running is a no-op.
6
15
  *
7
- * @param options - Options object with required topic
8
- * @param options.topic - Topic hex string to leave
9
16
  * @returns A promise that resolves to the stop provide response containing success status
10
17
  * @throws {QvacErrorBase} When the response type is not "stopProvide" or the request fails
11
18
  */
12
- export async function stopQVACProvider(params) {
19
+ export async function stopQVACProvider() {
13
20
  const request = {
14
21
  type: "stopProvide",
15
- topic: params.topic,
16
22
  };
17
23
  const response = await send(request);
18
24
  if (response.type !== "stopProvide") {
@@ -1,13 +1,31 @@
1
1
  /**
2
- * Suspends all active Hyperswarm and Corestore resources
2
+ * Suspends the SDK runtime: pauses all registered Hyperswarm and Corestore
3
+ * resources and engages the lifecycle gate so non-lifecycle operations are
4
+ * blocked until `resume()` is called.
3
5
  *
4
- * Idempotent — calling while already suspended is a no-op.
6
+ * Safe to call from any lifecycle state — `suspend()` is never blocked by the
7
+ * lifecycle gate (along with `resume()` and `state()`). Idempotent.
5
8
  *
6
- * @throws {RPCError} When one or more resources fail to suspend (partial failure).
9
+ * After `suspend()` resolves, runtime state is `"suspended"` and any non-
10
+ * lifecycle SDK operation throws `LifecycleOperationBlockedError` until
11
+ * `resume()` is called.
12
+ *
13
+ * In-flight operations started before suspend:
14
+ * - P2P / Hyperdrive downloads: stall cleanly, continue after `resume()`
15
+ * - HTTP downloads: bypass suspend entirely (bytes keep flowing)
16
+ * - Local native inference: runs to completion regardless
17
+ * - Delegated reply RPCs: stall, then auto-recover after `resume()`
18
+ * (subject to delegate `timeout`)
19
+ * - Delegated stream RPCs: severed, consumer iterator hangs silently;
20
+ * re-issue after `resume()` works normally.
21
+ *
22
+ * @throws {RPCError} When one or more resources fail to suspend. The runtime
23
+ * still commits to `"suspended"` so callers can recover with `resume()`.
7
24
  *
8
25
  * @example
9
26
  * // Background handler
10
27
  * await suspend();
28
+ * console.log(await state()); // "suspended"
11
29
  */
12
30
  export declare function suspend(): Promise<void>;
13
31
  //# sourceMappingURL=suspend.d.ts.map
@@ -1,15 +1,33 @@
1
1
  import { send } from "../rpc/rpc-client.js";
2
2
  import { InvalidResponseError } from "../../utils/errors-client.js";
3
3
  /**
4
- * Suspends all active Hyperswarm and Corestore resources
4
+ * Suspends the SDK runtime: pauses all registered Hyperswarm and Corestore
5
+ * resources and engages the lifecycle gate so non-lifecycle operations are
6
+ * blocked until `resume()` is called.
5
7
  *
6
- * Idempotent — calling while already suspended is a no-op.
8
+ * Safe to call from any lifecycle state — `suspend()` is never blocked by the
9
+ * lifecycle gate (along with `resume()` and `state()`). Idempotent.
7
10
  *
8
- * @throws {RPCError} When one or more resources fail to suspend (partial failure).
11
+ * After `suspend()` resolves, runtime state is `"suspended"` and any non-
12
+ * lifecycle SDK operation throws `LifecycleOperationBlockedError` until
13
+ * `resume()` is called.
14
+ *
15
+ * In-flight operations started before suspend:
16
+ * - P2P / Hyperdrive downloads: stall cleanly, continue after `resume()`
17
+ * - HTTP downloads: bypass suspend entirely (bytes keep flowing)
18
+ * - Local native inference: runs to completion regardless
19
+ * - Delegated reply RPCs: stall, then auto-recover after `resume()`
20
+ * (subject to delegate `timeout`)
21
+ * - Delegated stream RPCs: severed, consumer iterator hangs silently;
22
+ * re-issue after `resume()` works normally.
23
+ *
24
+ * @throws {RPCError} When one or more resources fail to suspend. The runtime
25
+ * still commits to `"suspended"` so callers can recover with `resume()`.
9
26
  *
10
27
  * @example
11
28
  * // Background handler
12
29
  * await suspend();
30
+ * console.log(await state()); // "suspended"
13
31
  */
14
32
  export async function suspend() {
15
33
  const response = await send({ type: "suspend" });
@@ -1,7 +1,65 @@
1
- import { type TtsClientParams, type RPCOptions } from "../../schemas/index";
2
- export declare function textToSpeech(params: TtsClientParams, options?: RPCOptions): {
3
- bufferStream: AsyncGenerator<number>;
4
- buffer: Promise<number[]>;
5
- done: Promise<boolean>;
6
- };
1
+ import { type TtsClientParamsInput, type RPCOptions, type TtsResponse, type TextToSpeechStreamClientParams, type TextToSpeechStreamSession, type TextToSpeechStreamResult } from "../../schemas/index";
2
+ /**
3
+ * Fan-out queue that lets multiple consumers iterate the same TTS response
4
+ * stream independently. Items are retained only until every active subscriber
5
+ * has consumed them, then trimmed from the queue.
6
+ *
7
+ * The source is injected as an `AsyncIterable<TtsResponse>` so this class can
8
+ * be unit-tested directly against the real implementation (without mocking
9
+ * the RPC layer). Production callsites adapt `streamRpc(...)` via
10
+ * `ttsResponseSource()` below.
11
+ *
12
+ * Exported for test use; not part of the public SDK surface.
13
+ */
14
+ export declare class TtsMulticast {
15
+ private readonly queue;
16
+ private readonly waiters;
17
+ private readonly subscriberIndexes;
18
+ private ended;
19
+ private fatal;
20
+ private readonly resolvePumpDone;
21
+ private readonly rejectPumpDone;
22
+ readonly done: Promise<boolean>;
23
+ constructor(source: AsyncIterable<TtsResponse>);
24
+ subscribe(): AsyncGenerator<TtsResponse>;
25
+ private notify;
26
+ private trimConsumed;
27
+ private unsubscribe;
28
+ private pump;
29
+ private drain;
30
+ }
31
+ /**
32
+ * Converts text to speech audio using a loaded TTS model.
33
+ *
34
+ * Three modes selected by `params.stream` and `params.sentenceStream`:
35
+ *
36
+ * - `stream: false` (default) — collect all PCM samples and resolve once via
37
+ * `result.buffer` (`Promise<number[]>`). `bufferStream` is empty.
38
+ * - `stream: true` — yield PCM samples through `result.bufferStream`
39
+ * (`AsyncGenerator<number>`) as they arrive. `buffer` resolves to an empty
40
+ * array.
41
+ * - `stream: true, sentenceStream: true` — also exposes `result.chunkUpdates`
42
+ * (`AsyncGenerator<TtsSentenceChunkUpdate>`) so callers can mux per-sentence
43
+ * metadata with the audio. Multiple consumers can iterate the response
44
+ * independently via the underlying `TtsMulticast`.
45
+ *
46
+ * `result.done` resolves to `true` when synthesis completes cleanly, `false`
47
+ * if the consumer breaks out before the terminal frame, or rejects on a
48
+ * pipeline error. Awaiting `done` is safe even when no stream is iterated.
49
+ *
50
+ * @param params - TTS request parameters (see `TtsClientParamsInput`).
51
+ * @param options - Optional RPC options (timeout, profiling, force new connection).
52
+ * @returns A `TextToSpeechStreamResult` with `bufferStream`, `buffer`, `done`,
53
+ * and (when `sentenceStream: true`) `chunkUpdates`.
54
+ * @throws {TextToSpeechStreamFailedError} When `sentenceStream: true` is paired
55
+ * with `stream: false`, or when the underlying RPC stream errors.
56
+ */
57
+ export declare function textToSpeech(params: TtsClientParamsInput, options?: RPCOptions): TextToSpeechStreamResult;
58
+ /**
59
+ * Duplex session: write UTF-8 text fragments (e.g. LLM token deltas) via `write`. Each string or
60
+ * Buffer should be a complete UTF-8 fragment. The worker forwards them to ONNX TTS `runStreaming`
61
+ * (optional sentence accumulation via request fields). Iterate the session for `TextToSpeechStreamResponse`
62
+ * lines (PCM in `buffer`, optional `chunkIndex` / `sentenceChunk`) until `done`.
63
+ */
64
+ export declare function textToSpeechStream(params: TextToSpeechStreamClientParams, options?: RPCOptions): Promise<TextToSpeechStreamSession>;
7
65
  //# sourceMappingURL=text-to-speech.d.ts.map
@@ -1,58 +1,434 @@
1
- import { ttsResponseSchema, } from "../../schemas/index.js";
2
- import { stream as streamRpc } from "../rpc/rpc-client.js";
3
- export function textToSpeech(params, options) {
4
- const request = {
1
+ import { textToSpeechStreamResponseSchema, ttsClientParamsSchema, } from "../../schemas/index.js";
2
+ import { stream as streamRpc, duplex } from "../rpc/rpc-client.js";
3
+ import { getClientLogger } from "../../logging/index.js";
4
+ import { TextToSpeechStreamFailedError } from "../../utils/errors-client.js";
5
+ const logger = getClientLogger();
6
+ /**
7
+ * Fan-out queue that lets multiple consumers iterate the same TTS response
8
+ * stream independently. Items are retained only until every active subscriber
9
+ * has consumed them, then trimmed from the queue.
10
+ *
11
+ * The source is injected as an `AsyncIterable<TtsResponse>` so this class can
12
+ * be unit-tested directly against the real implementation (without mocking
13
+ * the RPC layer). Production callsites adapt `streamRpc(...)` via
14
+ * `ttsResponseSource()` below.
15
+ *
16
+ * Exported for test use; not part of the public SDK surface.
17
+ */
18
+ export class TtsMulticast {
19
+ queue = [];
20
+ waiters = [];
21
+ subscriberIndexes = [];
22
+ ended = false;
23
+ fatal;
24
+ resolvePumpDone;
25
+ rejectPumpDone;
26
+ done;
27
+ constructor(source) {
28
+ let resolve;
29
+ let reject;
30
+ this.done = new Promise((r, rj) => {
31
+ resolve = r;
32
+ reject = rj;
33
+ });
34
+ // Silence unhandled-rejection warnings when the caller never awaits
35
+ // `done` (e.g. only iterates the buffer stream). Re-awaits still get the
36
+ // rejection because the underlying promise state is unchanged.
37
+ this.done.catch(() => { });
38
+ this.resolvePumpDone = resolve;
39
+ this.rejectPumpDone = reject;
40
+ void this.pump(source);
41
+ }
42
+ subscribe() {
43
+ const subIdx = this.subscriberIndexes.length;
44
+ this.subscriberIndexes.push(0);
45
+ return this.drain(subIdx);
46
+ }
47
+ notify() {
48
+ for (const fn of this.waiters.splice(0))
49
+ fn();
50
+ }
51
+ trimConsumed() {
52
+ if (this.subscriberIndexes.length === 0)
53
+ return;
54
+ // `Number.POSITIVE_INFINITY` marks an unsubscribed slot; ignore those when
55
+ // computing how far every live subscriber has advanced.
56
+ const minIndex = Math.min(...this.subscriberIndexes);
57
+ if (!Number.isFinite(minIndex))
58
+ return;
59
+ if (minIndex > 0) {
60
+ this.queue.splice(0, minIndex);
61
+ for (let j = 0; j < this.subscriberIndexes.length; j++) {
62
+ const v = this.subscriberIndexes[j] ?? 0;
63
+ if (Number.isFinite(v))
64
+ this.subscriberIndexes[j] = v - minIndex;
65
+ }
66
+ }
67
+ }
68
+ unsubscribe(subIdx) {
69
+ // Park the slot at +Infinity instead of splicing so every other
70
+ // subscriber's `subIdx` stays valid. `trimConsumed` filters these out.
71
+ this.subscriberIndexes[subIdx] = Number.POSITIVE_INFINITY;
72
+ this.trimConsumed();
73
+ }
74
+ async pump(source) {
75
+ try {
76
+ for await (const response of source) {
77
+ // The server owns this response schema; per-frame Zod .parse() adds
78
+ // non-trivial CPU overhead for large sentences with many PCM frames.
79
+ // Rely on the discriminated union narrowing at the RPC boundary and
80
+ // skip re-validation here.
81
+ this.queue.push(response);
82
+ this.notify();
83
+ if (response.done)
84
+ break;
85
+ }
86
+ }
87
+ catch (e) {
88
+ this.fatal = e instanceof Error ? e : new Error(String(e));
89
+ }
90
+ finally {
91
+ this.ended = true;
92
+ this.notify();
93
+ if (this.fatal) {
94
+ // Reject rather than resolving false so callers awaiting `done`
95
+ // with no iteration — and callers iterating drain() — both see the
96
+ // real error instead of a silent sentinel.
97
+ this.rejectPumpDone(this.fatal);
98
+ }
99
+ else {
100
+ this.resolvePumpDone(true);
101
+ }
102
+ }
103
+ }
104
+ async *drain(subIdx) {
105
+ // If the consumer breaks out of a `for await` (or calls `.return()` /
106
+ // throws), this generator's finally block runs; release the slot so it
107
+ // no longer pins `trimConsumed`'s min-index and the queue can be GC'd.
108
+ try {
109
+ while (true) {
110
+ while ((this.subscriberIndexes[subIdx] ?? 0) < this.queue.length) {
111
+ const currentIdx = this.subscriberIndexes[subIdx] ?? 0;
112
+ const item = this.queue[currentIdx];
113
+ this.subscriberIndexes[subIdx] = currentIdx + 1;
114
+ this.trimConsumed();
115
+ yield item;
116
+ }
117
+ if (this.fatal)
118
+ throw this.fatal;
119
+ if (this.ended)
120
+ return;
121
+ await new Promise((resolve) => {
122
+ this.waiters.push(resolve);
123
+ });
124
+ }
125
+ }
126
+ finally {
127
+ this.unsubscribe(subIdx);
128
+ }
129
+ }
130
+ }
131
+ function buildTtsRequest(params) {
132
+ return {
5
133
  type: "textToSpeech",
6
134
  modelId: params.modelId,
7
135
  inputType: params.inputType,
8
136
  text: params.text,
9
137
  stream: params.stream,
138
+ sentenceStream: params.sentenceStream,
139
+ ...(params.sentenceStreamLocale !== undefined && {
140
+ sentenceStreamLocale: params.sentenceStreamLocale,
141
+ }),
142
+ ...(params.sentenceStreamMaxChunkScalars !== undefined && {
143
+ sentenceStreamMaxChunkScalars: params.sentenceStreamMaxChunkScalars,
144
+ }),
145
+ };
146
+ }
147
+ function buildTextToSpeechStreamRequest(params) {
148
+ return {
149
+ type: "textToSpeechStream",
150
+ modelId: params.modelId,
151
+ inputType: params.inputType ?? "text",
152
+ ...(params.accumulateSentences !== undefined && {
153
+ accumulateSentences: params.accumulateSentences,
154
+ }),
155
+ ...(params.sentenceDelimiterPreset !== undefined && {
156
+ sentenceDelimiterPreset: params.sentenceDelimiterPreset,
157
+ }),
158
+ ...(params.maxBufferScalars !== undefined && {
159
+ maxBufferScalars: params.maxBufferScalars,
160
+ }),
161
+ ...(params.flushAfterMs !== undefined && {
162
+ flushAfterMs: params.flushAfterMs,
163
+ }),
164
+ };
165
+ }
166
+ /**
167
+ * Converts text to speech audio using a loaded TTS model.
168
+ *
169
+ * Three modes selected by `params.stream` and `params.sentenceStream`:
170
+ *
171
+ * - `stream: false` (default) — collect all PCM samples and resolve once via
172
+ * `result.buffer` (`Promise<number[]>`). `bufferStream` is empty.
173
+ * - `stream: true` — yield PCM samples through `result.bufferStream`
174
+ * (`AsyncGenerator<number>`) as they arrive. `buffer` resolves to an empty
175
+ * array.
176
+ * - `stream: true, sentenceStream: true` — also exposes `result.chunkUpdates`
177
+ * (`AsyncGenerator<TtsSentenceChunkUpdate>`) so callers can mux per-sentence
178
+ * metadata with the audio. Multiple consumers can iterate the response
179
+ * independently via the underlying `TtsMulticast`.
180
+ *
181
+ * `result.done` resolves to `true` when synthesis completes cleanly, `false`
182
+ * if the consumer breaks out before the terminal frame, or rejects on a
183
+ * pipeline error. Awaiting `done` is safe even when no stream is iterated.
184
+ *
185
+ * @param params - TTS request parameters (see `TtsClientParamsInput`).
186
+ * @param options - Optional RPC options (timeout, profiling, force new connection).
187
+ * @returns A `TextToSpeechStreamResult` with `bufferStream`, `buffer`, `done`,
188
+ * and (when `sentenceStream: true`) `chunkUpdates`.
189
+ * @throws {TextToSpeechStreamFailedError} When `sentenceStream: true` is paired
190
+ * with `stream: false`, or when the underlying RPC stream errors.
191
+ */
192
+ export function textToSpeech(params, options) {
193
+ const parsed = ttsClientParamsSchema.parse(params);
194
+ if (parsed.sentenceStream && !parsed.stream) {
195
+ throw new TextToSpeechStreamFailedError("textToSpeech: `sentenceStream: true` requires `stream: true`");
196
+ }
197
+ const request = buildTtsRequest(parsed);
198
+ if (parsed.stream && parsed.sentenceStream) {
199
+ return sentenceStreamTts(request, options);
200
+ }
201
+ if (parsed.stream) {
202
+ return plainStreamTts(request, options);
203
+ }
204
+ return collectTts(request, options);
205
+ }
206
+ // Adapts the raw RPC stream into the filtered `TtsResponse` source the
207
+ // multicast expects. Kept here (not inlined) so the multicast can be
208
+ // constructed in tests with a hand-rolled source instead.
209
+ async function* ttsResponseSource(request, options) {
210
+ for await (const response of streamRpc(request, options)) {
211
+ if (response.type !== "textToSpeech")
212
+ continue;
213
+ yield response;
214
+ }
215
+ }
216
+ function sentenceStreamTts(request, options) {
217
+ const multicast = new TtsMulticast(ttsResponseSource(request, options));
218
+ // Subscribe eagerly, synchronously — before pump() can push its first
219
+ // item — so both subscribers see the full queue from index 0. If we
220
+ // deferred subscribing until the generators were iterated, the first
221
+ // consumer could trim the queue before the second ever registered,
222
+ // silently dropping earlier frames.
223
+ const bufferSubscription = multicast.subscribe();
224
+ const chunkSubscription = multicast.subscribe();
225
+ return {
226
+ bufferStream: sentenceBufferStream(bufferSubscription),
227
+ chunkUpdates: sentenceChunkUpdates(chunkSubscription),
228
+ buffer: Promise.resolve([]),
229
+ done: multicast.done,
230
+ };
231
+ }
232
+ async function* sentenceBufferStream(source) {
233
+ for await (const m of source) {
234
+ if (m.buffer.length > 0) {
235
+ yield* m.buffer;
236
+ }
237
+ if (m.done)
238
+ break;
239
+ }
240
+ }
241
+ async function* sentenceChunkUpdates(source) {
242
+ for await (const m of source) {
243
+ const hasAudio = m.buffer.length > 0;
244
+ const hasMeta = m.chunkIndex !== undefined ||
245
+ (typeof m.sentenceChunk === "string" && m.sentenceChunk.length > 0);
246
+ if (hasAudio || hasMeta) {
247
+ yield {
248
+ buffer: hasAudio ? [...m.buffer] : [],
249
+ ...(m.chunkIndex !== undefined ? { chunkIndex: m.chunkIndex } : {}),
250
+ ...(typeof m.sentenceChunk === "string" && m.sentenceChunk.length > 0
251
+ ? { sentenceChunk: m.sentenceChunk }
252
+ : {}),
253
+ };
254
+ }
255
+ if (m.done)
256
+ break;
257
+ }
258
+ }
259
+ function plainStreamTts(request, options) {
260
+ let resolveDone;
261
+ let rejectDone;
262
+ const done = new Promise((resolve, reject) => {
263
+ resolveDone = resolve;
264
+ rejectDone = reject;
265
+ });
266
+ done.catch(() => { });
267
+ return {
268
+ bufferStream: plainTtsBufferStream(request, options, resolveDone, rejectDone),
269
+ buffer: Promise.resolve([]),
270
+ done,
10
271
  };
11
- let doneResolver = () => { };
12
- const donePromise = new Promise((resolve) => {
13
- doneResolver = resolve;
272
+ }
273
+ async function* plainTtsBufferStream(request, options, resolveDone, rejectDone) {
274
+ let settled = false;
275
+ try {
276
+ for await (const response of streamRpc(request, options)) {
277
+ if (response.type !== "textToSpeech")
278
+ continue;
279
+ // See TtsMulticast.pump — skip per-frame Zod validation; the server is
280
+ // the source of truth for this wire shape.
281
+ if (response.buffer.length > 0) {
282
+ yield* response.buffer;
283
+ }
284
+ if (response.done) {
285
+ settled = true;
286
+ resolveDone(true);
287
+ }
288
+ }
289
+ }
290
+ catch (e) {
291
+ if (!settled) {
292
+ settled = true;
293
+ rejectDone(e);
294
+ }
295
+ throw e;
296
+ }
297
+ finally {
298
+ // Consumer broke out of the for-await before `done` arrived; resolve
299
+ // with `false` so `await result.done` never hangs.
300
+ if (!settled)
301
+ resolveDone(false);
302
+ }
303
+ }
304
+ function collectTts(request, options) {
305
+ let resolveDone;
306
+ let rejectDone;
307
+ const done = new Promise((resolve, reject) => {
308
+ resolveDone = resolve;
309
+ rejectDone = reject;
14
310
  });
15
- if (params.stream) {
16
- const bufferStream = (async function* () {
17
- for await (const response of streamRpc(request, options)) {
18
- if (response.type === "textToSpeech") {
19
- const streamResponse = ttsResponseSchema.parse(response);
20
- if (streamResponse.buffer.length > 0) {
21
- yield* streamResponse.buffer;
22
- }
23
- if (streamResponse.done) {
24
- doneResolver(true);
25
- }
26
- }
311
+ done.catch(() => { });
312
+ return {
313
+ bufferStream: emptyBufferStream(),
314
+ buffer: collectTtsBuffer(request, options, resolveDone, rejectDone),
315
+ done,
316
+ };
317
+ }
318
+ async function* emptyBufferStream() {
319
+ // Non-streaming mode exposes no incremental buffer stream.
320
+ }
321
+ async function collectTtsBuffer(request, options, resolveDone, rejectDone) {
322
+ let buffer = [];
323
+ try {
324
+ for await (const response of streamRpc(request, options)) {
325
+ if (response.type !== "textToSpeech")
326
+ continue;
327
+ buffer = buffer.concat(response.buffer);
328
+ if (response.done) {
329
+ resolveDone(true);
27
330
  }
28
- })();
29
- return {
30
- bufferStream,
31
- buffer: Promise.resolve([]),
32
- done: donePromise,
33
- };
34
- }
35
- else {
36
- const bufferStream = (async function* () {
37
- //Empty generator for non-streaming mode
38
- })();
39
- const bufferPromise = (async () => {
40
- let buffer = [];
41
- for await (const response of streamRpc(request, options)) {
42
- if (response.type === "textToSpeech") {
43
- const streamResponse = ttsResponseSchema.parse(response);
44
- buffer = buffer.concat(streamResponse.buffer);
45
- if (streamResponse.done) {
46
- doneResolver(true);
47
- }
48
- }
331
+ }
332
+ return buffer;
333
+ }
334
+ catch (e) {
335
+ rejectDone(e);
336
+ throw e;
337
+ }
338
+ }
339
+ /**
340
+ * Duplex session: write UTF-8 text fragments (e.g. LLM token deltas) via `write`. Each string or
341
+ * Buffer should be a complete UTF-8 fragment. The worker forwards them to ONNX TTS `runStreaming`
342
+ * (optional sentence accumulation via request fields). Iterate the session for `TextToSpeechStreamResponse`
343
+ * lines (PCM in `buffer`, optional `chunkIndex` / `sentenceChunk`) until `done`.
344
+ */
345
+ export async function textToSpeechStream(params, options) {
346
+ const request = buildTextToSpeechStreamRequest(params);
347
+ const { requestStream, responseStream } = await duplex(request, options);
348
+ const responses = parseTextToSpeechStreamLines(responseStream);
349
+ let consumed = false;
350
+ // `closed` flips on `end()` or `destroy()`. Without this guard a late
351
+ // `write()` would propagate a raw Bare/Node "write after end" stream error
352
+ // to the caller. Throwing a typed SDK error keeps the duplex session
353
+ // surface predictable.
354
+ let closed = false;
355
+ return {
356
+ write(textFragment) {
357
+ if (closed) {
358
+ throw new TextToSpeechStreamFailedError("TextToSpeechStreamSession.write() called after end()/destroy()");
359
+ }
360
+ const buf = typeof textFragment === "string"
361
+ ? Buffer.from(textFragment, "utf8")
362
+ : textFragment;
363
+ requestStream.write(buf);
364
+ },
365
+ end() {
366
+ if (closed)
367
+ return;
368
+ closed = true;
369
+ requestStream.end();
370
+ },
371
+ destroy() {
372
+ closed = true;
373
+ requestStream.destroy();
374
+ responseStream.destroy();
375
+ },
376
+ [Symbol.asyncIterator]() {
377
+ if (consumed) {
378
+ // Return an iterator whose first .next() rejects asynchronously so
379
+ // `for await` surfaces the error in the normal async-iteration
380
+ // control flow instead of a synchronous throw from the iterator
381
+ // protocol (which callers commonly forget to wrap in try/catch).
382
+ return {
383
+ next() {
384
+ return Promise.reject(new TextToSpeechStreamFailedError("TextToSpeechStreamSession can only be iterated once"));
385
+ },
386
+ };
49
387
  }
50
- return buffer;
51
- })();
52
- return {
53
- bufferStream,
54
- buffer: bufferPromise,
55
- done: donePromise,
56
- };
388
+ consumed = true;
389
+ return responses;
390
+ },
391
+ };
392
+ }
393
+ async function* parseTextToSpeechStreamLines(responseStream) {
394
+ let buf = "";
395
+ for await (const chunk of responseStream) {
396
+ buf += chunk.toString();
397
+ const lines = buf.split("\n");
398
+ buf = lines.pop() || "";
399
+ for (const line of lines) {
400
+ const yielded = processTextToSpeechStreamLine(line);
401
+ if (yielded === undefined)
402
+ continue;
403
+ yield yielded;
404
+ // Close the stream after the terminal frame so consumers don't
405
+ // depend on the server closing the socket to stop iteration.
406
+ if (yielded.done)
407
+ return;
408
+ }
409
+ }
410
+ if (buf.trim()) {
411
+ const yielded = processTextToSpeechStreamLine(buf);
412
+ if (yielded !== undefined) {
413
+ yield yielded;
414
+ }
415
+ }
416
+ }
417
+ function processTextToSpeechStreamLine(line) {
418
+ if (!line.trim()) {
419
+ return undefined;
420
+ }
421
+ let parsed;
422
+ try {
423
+ parsed = JSON.parse(line);
424
+ }
425
+ catch {
426
+ logger.warn("textToSpeechStream: malformed JSON from server:", line);
427
+ return undefined;
428
+ }
429
+ const obj = parsed;
430
+ if (obj["type"] === "error") {
431
+ throw new TextToSpeechStreamFailedError(obj["message"] ?? "Unknown server error");
57
432
  }
433
+ return textToSpeechStreamResponseSchema.parse(parsed);
58
434
  }