@qvac/sdk 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/NOTICE +1455 -29
  2. package/README.md +2 -0
  3. package/dist/client/api/cancel.d.ts +24 -32
  4. package/dist/client/api/cancel.js +58 -31
  5. package/dist/client/api/classify.d.ts +23 -0
  6. package/dist/client/api/classify.js +43 -0
  7. package/dist/client/api/client-request-id.d.ts +17 -0
  8. package/dist/client/api/client-request-id.js +27 -0
  9. package/dist/client/api/completion-stream.d.ts +1 -1
  10. package/dist/client/api/completion-stream.js +34 -3
  11. package/dist/client/api/diffusion.d.ts +46 -0
  12. package/dist/client/api/diffusion.js +50 -1
  13. package/dist/client/api/download-asset.d.ts +12 -2
  14. package/dist/client/api/download-asset.js +21 -3
  15. package/dist/client/api/embed.d.ts +8 -4
  16. package/dist/client/api/embed.js +14 -1
  17. package/dist/client/api/get-model-info.d.ts +1 -1
  18. package/dist/client/api/index.d.ts +5 -0
  19. package/dist/client/api/index.js +5 -0
  20. package/dist/client/api/load-model.d.ts +12 -4
  21. package/dist/client/api/load-model.js +49 -2
  22. package/dist/client/api/rag.d.ts +9 -3
  23. package/dist/client/api/rag.js +23 -3
  24. package/dist/client/api/transcribe.d.ts +23 -8
  25. package/dist/client/api/transcribe.js +69 -4
  26. package/dist/client/api/unload-model.d.ts +5 -2
  27. package/dist/client/api/unload-model.js +9 -4
  28. package/dist/client/api/upscale.d.ts +45 -0
  29. package/dist/client/api/upscale.js +99 -0
  30. package/dist/client/api/video.d.ts +64 -0
  31. package/dist/client/api/video.js +147 -0
  32. package/dist/client/api/vla-helpers.d.ts +45 -0
  33. package/dist/client/api/vla-helpers.js +130 -0
  34. package/dist/client/api/vla.d.ts +65 -0
  35. package/dist/client/api/vla.js +109 -0
  36. package/dist/client/config-loader/resolve-config.node.d.ts +16 -0
  37. package/dist/client/config-loader/resolve-config.node.js +77 -23
  38. package/dist/client/plugins-factory.d.ts +8 -0
  39. package/dist/client/plugins-factory.js +10 -0
  40. package/dist/client/rpc/bare-client.js +62 -66
  41. package/dist/client/rpc/ensure-worker-ready.d.ts +9 -0
  42. package/dist/client/rpc/ensure-worker-ready.js +17 -0
  43. package/dist/client/rpc/expo-rpc-client.js +2 -1
  44. package/dist/client/rpc/node-rpc-client.js +22 -8
  45. package/dist/client/rpc/rpc-client.d.ts +2 -2
  46. package/dist/client/rpc/rpc-client.js +10 -4
  47. package/dist/client/rpc/rpc-error.d.ts +9 -0
  48. package/dist/client/rpc/rpc-error.js +105 -0
  49. package/dist/commands/bundle/bare-pack.d.ts +13 -0
  50. package/dist/commands/bundle/bare-pack.js +54 -0
  51. package/dist/commands/bundle/constants.d.ts +7 -0
  52. package/dist/commands/bundle/constants.js +23 -0
  53. package/dist/commands/bundle/entry-gen.d.ts +2 -0
  54. package/dist/commands/bundle/entry-gen.js +48 -0
  55. package/dist/commands/bundle/index.d.ts +20 -0
  56. package/dist/commands/bundle/index.js +141 -0
  57. package/dist/commands/bundle/manifest.d.ts +21 -0
  58. package/dist/commands/bundle/manifest.js +193 -0
  59. package/dist/commands/bundle/plugins.d.ts +9 -0
  60. package/dist/commands/bundle/plugins.js +51 -0
  61. package/dist/commands/index.d.ts +5 -0
  62. package/dist/commands/index.js +2 -0
  63. package/dist/commands/verify/abi.d.ts +52 -0
  64. package/dist/commands/verify/abi.js +125 -0
  65. package/dist/commands/verify/addon-source.d.ts +43 -0
  66. package/dist/commands/verify/addon-source.js +75 -0
  67. package/dist/commands/verify/bundle-source.d.ts +12 -0
  68. package/dist/commands/verify/bundle-source.js +53 -0
  69. package/dist/commands/verify/index.d.ts +59 -0
  70. package/dist/commands/verify/index.js +371 -0
  71. package/dist/commands/verify/node-modules-source.d.ts +11 -0
  72. package/dist/commands/verify/node-modules-source.js +76 -0
  73. package/dist/commands/verify/prebuilds.d.ts +15 -0
  74. package/dist/commands/verify/prebuilds.js +39 -0
  75. package/dist/examples/cancel-by-request-id.d.ts +38 -0
  76. package/dist/examples/cancel-by-request-id.js +103 -0
  77. package/dist/examples/classification/classify-image.d.ts +2 -0
  78. package/dist/examples/classification/classify-image.js +23 -0
  79. package/dist/examples/diffusion-esrgan-upscale.d.ts +2 -0
  80. package/dist/examples/diffusion-esrgan-upscale.js +78 -0
  81. package/dist/examples/diffusion-txt2vid.d.ts +2 -0
  82. package/dist/examples/diffusion-txt2vid.js +81 -0
  83. package/dist/examples/download-with-cancel.js +10 -10
  84. package/dist/examples/embed-multi-gpu.d.ts +2 -0
  85. package/dist/examples/embed-multi-gpu.js +46 -0
  86. package/dist/examples/llamacpp-multi-gpu.d.ts +2 -0
  87. package/dist/examples/llamacpp-multi-gpu.js +57 -0
  88. package/dist/examples/plugins.js +3 -7
  89. package/dist/examples/rag/rag-hyperdb/cancellation.js +20 -17
  90. package/dist/examples/tools/llamacpp-tools-gemma4.d.ts +2 -0
  91. package/dist/examples/tools/llamacpp-tools-gemma4.js +73 -0
  92. package/dist/examples/tools/llamacpp-tools-qwen35.d.ts +2 -0
  93. package/dist/examples/tools/llamacpp-tools-qwen35.js +69 -0
  94. package/dist/examples/transcription/parakeet-ctc-filesystem.js +18 -12
  95. package/dist/examples/transcription/parakeet-microphone-record.js +7 -12
  96. package/dist/examples/transcription/parakeet-microphone-stream.d.ts +2 -0
  97. package/dist/examples/transcription/parakeet-microphone-stream.js +79 -0
  98. package/dist/examples/transcription/parakeet-sortformer-streaming.d.ts +2 -0
  99. package/dist/examples/transcription/parakeet-sortformer-streaming.js +121 -0
  100. package/dist/examples/transcription/parakeet-sortformer.js +58 -55
  101. package/dist/examples/transcription/parakeet-tdt-filesystem.js +18 -15
  102. package/dist/examples/transcription/whispercpp-microphone-conversation.d.ts +2 -0
  103. package/dist/examples/transcription/whispercpp-microphone-conversation.js +107 -0
  104. package/dist/examples/tts/chatterbox.js +7 -16
  105. package/dist/examples/tts/llm-to-tts-streaming.js +3 -10
  106. package/dist/examples/tts/supertonic-multilingual.js +4 -12
  107. package/dist/examples/tts/supertonic.js +5 -12
  108. package/dist/examples/vla-smolvla.d.ts +2 -0
  109. package/dist/examples/vla-smolvla.js +75 -0
  110. package/dist/examples/voice-assistant/voice-assistant.js +3 -10
  111. package/dist/expo/plugins/find-in-ancestor-node-modules.d.ts +14 -0
  112. package/dist/expo/plugins/find-in-ancestor-node-modules.js +24 -0
  113. package/dist/expo/plugins/get-project-root.d.ts +22 -0
  114. package/dist/expo/plugins/get-project-root.js +23 -0
  115. package/dist/expo/plugins/index.d.ts +4 -0
  116. package/dist/expo/plugins/index.js +4 -0
  117. package/dist/expo/plugins/resolve-sdk-package-dir.d.ts +9 -2
  118. package/dist/expo/plugins/resolve-sdk-package-dir.js +38 -11
  119. package/dist/expo/plugins/withDeviceInfo.js +2 -1
  120. package/dist/expo/plugins/withMobileBundle.d.ts +5 -4
  121. package/dist/expo/plugins/withMobileBundle.js +42 -58
  122. package/dist/index.d.ts +6 -2
  123. package/dist/index.js +23 -2
  124. package/dist/models/registry/models.d.ts +3725 -514
  125. package/dist/models/registry/models.js +7269 -3910
  126. package/dist/models/update-models/naming.js +22 -8
  127. package/dist/pear/pre.d.ts +3 -0
  128. package/dist/pear/pre.js +9 -2
  129. package/dist/schemas/cancel.d.ts +172 -28
  130. package/dist/schemas/cancel.js +120 -19
  131. package/dist/schemas/classification.d.ts +53 -0
  132. package/dist/schemas/classification.js +33 -0
  133. package/dist/schemas/common.d.ts +860 -1379
  134. package/dist/schemas/common.js +8 -1
  135. package/dist/schemas/completion-event.d.ts +17 -0
  136. package/dist/schemas/completion-event.js +12 -1
  137. package/dist/schemas/completion-stream.d.ts +16 -1
  138. package/dist/schemas/completion-stream.js +25 -7
  139. package/dist/schemas/download-asset.d.ts +25 -9
  140. package/dist/schemas/download-asset.js +17 -6
  141. package/dist/schemas/embed.d.ts +1 -0
  142. package/dist/schemas/embed.js +5 -0
  143. package/dist/schemas/engine-addon-map.d.ts +3 -0
  144. package/dist/schemas/engine-addon-map.js +18 -5
  145. package/dist/schemas/error.d.ts +31 -0
  146. package/dist/schemas/error.js +29 -1
  147. package/dist/schemas/finetune.d.ts +2 -0
  148. package/dist/schemas/finetune.js +5 -0
  149. package/dist/schemas/get-model-info.d.ts +10 -6
  150. package/dist/schemas/get-model-info.js +2 -0
  151. package/dist/schemas/index.d.ts +3 -0
  152. package/dist/schemas/index.js +3 -0
  153. package/dist/schemas/llamacpp-config.d.ts +64 -8
  154. package/dist/schemas/llamacpp-config.js +12 -0
  155. package/dist/schemas/load-model.d.ts +4644 -8605
  156. package/dist/schemas/load-model.js +90 -7
  157. package/dist/schemas/model-src-utils.d.ts +34 -14
  158. package/dist/schemas/model-types.d.ts +54 -14
  159. package/dist/schemas/model-types.js +28 -5
  160. package/dist/schemas/ocr.d.ts +8 -3
  161. package/dist/schemas/plugin.d.ts +60 -6
  162. package/dist/schemas/plugin.js +31 -5
  163. package/dist/schemas/rag.d.ts +9 -0
  164. package/dist/schemas/rag.js +17 -9
  165. package/dist/schemas/registry.d.ts +74 -30
  166. package/dist/schemas/registry.js +5 -0
  167. package/dist/schemas/reload-config.d.ts +34 -14
  168. package/dist/schemas/sdcpp-config.d.ts +445 -16
  169. package/dist/schemas/sdcpp-config.js +387 -26
  170. package/dist/schemas/sdk-config.d.ts +2431 -2723
  171. package/dist/schemas/sdk-config.js +16 -1
  172. package/dist/schemas/sdk-errors-client.d.ts +6 -0
  173. package/dist/schemas/sdk-errors-client.js +31 -1
  174. package/dist/schemas/sdk-errors-server.d.ts +8 -1
  175. package/dist/schemas/sdk-errors-server.js +45 -5
  176. package/dist/schemas/text-to-speech.d.ts +81 -698
  177. package/dist/schemas/text-to-speech.js +46 -19
  178. package/dist/schemas/transcription-config.d.ts +40 -229
  179. package/dist/schemas/transcription-config.js +76 -15
  180. package/dist/schemas/transcription.d.ts +108 -2
  181. package/dist/schemas/transcription.js +81 -0
  182. package/dist/schemas/translate.d.ts +2 -0
  183. package/dist/schemas/translate.js +13 -2
  184. package/dist/schemas/translation-config.d.ts +90 -40
  185. package/dist/schemas/unload-model.d.ts +2 -1
  186. package/dist/schemas/unload-model.js +4 -1
  187. package/dist/schemas/vla.d.ts +87 -0
  188. package/dist/schemas/vla.js +108 -0
  189. package/dist/scripts/run-unit-tests.js +22 -3
  190. package/dist/server/bare/ops/cancel.d.ts +27 -1
  191. package/dist/server/bare/ops/cancel.js +36 -10
  192. package/dist/server/bare/ops/embed.d.ts +3 -3
  193. package/dist/server/bare/ops/embed.js +144 -28
  194. package/dist/server/bare/ops/kv-cache-utils.d.ts +0 -7
  195. package/dist/server/bare/ops/kv-cache-utils.js +8 -47
  196. package/dist/server/bare/ops/transcribe.d.ts +11 -5
  197. package/dist/server/bare/ops/transcribe.js +230 -50
  198. package/dist/server/bare/ops/translate.d.ts +1 -1
  199. package/dist/server/bare/ops/translate.js +197 -88
  200. package/dist/server/bare/plugins/ggml-classification/ops/classify.d.ts +6 -0
  201. package/dist/server/bare/plugins/ggml-classification/ops/classify.js +30 -0
  202. package/dist/server/bare/plugins/ggml-classification/plugin.d.ts +32 -0
  203. package/dist/server/bare/plugins/ggml-classification/plugin.js +55 -0
  204. package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.d.ts +3 -0
  205. package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.js +12 -0
  206. package/dist/server/bare/plugins/ggml-vla/ops/vla-run.d.ts +3 -0
  207. package/dist/server/bare/plugins/ggml-vla/ops/vla-run.js +75 -0
  208. package/dist/server/bare/plugins/ggml-vla/plugin.d.ts +54 -0
  209. package/dist/server/bare/plugins/ggml-vla/plugin.js +57 -0
  210. package/dist/server/bare/plugins/index.d.ts +3 -1
  211. package/dist/server/bare/plugins/index.js +3 -1
  212. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +12 -3
  213. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +173 -172
  214. package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.d.ts +29 -0
  215. package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.js +65 -0
  216. package/dist/server/bare/plugins/llamacpp-completion/ops/finetune.js +125 -21
  217. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.d.ts +154 -0
  218. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.js +448 -0
  219. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.d.ts +21 -73
  220. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.js +18 -101
  221. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +36 -3
  222. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +183 -85
  223. package/dist/server/bare/plugins/llamacpp-completion/transform.d.ts +10 -0
  224. package/dist/server/bare/plugins/llamacpp-completion/transform.js +34 -0
  225. package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +7 -0
  226. package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +10 -1
  227. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +42 -15
  228. package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +5 -1
  229. package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +8 -3
  230. package/dist/server/bare/plugins/onnx-ocr/plugin.js +3 -0
  231. package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +73 -244
  232. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +68 -96
  233. package/dist/server/bare/plugins/sdcpp-generation/ops/diffusion.js +8 -0
  234. package/dist/server/bare/plugins/sdcpp-generation/ops/upscale.d.ts +3 -0
  235. package/dist/server/bare/plugins/sdcpp-generation/ops/upscale.js +40 -0
  236. package/dist/server/bare/plugins/sdcpp-generation/ops/video.d.ts +3 -0
  237. package/dist/server/bare/plugins/sdcpp-generation/ops/video.js +199 -0
  238. package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +288 -15
  239. package/dist/server/bare/plugins/sdcpp-generation/plugin.js +150 -7
  240. package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.js +2 -15
  241. package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.js +2 -1
  242. package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +75 -0
  243. package/dist/server/bare/plugins/tts-ggml/plugin.js +189 -0
  244. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +47 -3
  245. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +61 -14
  246. package/dist/server/bare/rag-hyperdb/index.d.ts +1 -1
  247. package/dist/server/bare/rag-hyperdb/index.js +1 -1
  248. package/dist/server/bare/rag-hyperdb/rag-operation-manager.d.ts +26 -4
  249. package/dist/server/bare/rag-hyperdb/rag-operation-manager.js +65 -28
  250. package/dist/server/bare/registry/model-config-utils.js +7 -0
  251. package/dist/server/bare/runtime/disposable-scope.d.ts +36 -0
  252. package/dist/server/bare/runtime/disposable-scope.js +69 -0
  253. package/dist/server/bare/runtime/index.d.ts +8 -0
  254. package/dist/server/bare/runtime/index.js +3 -0
  255. package/dist/server/bare/runtime/request-context.d.ts +49 -0
  256. package/dist/server/bare/runtime/request-context.js +1 -0
  257. package/dist/server/bare/runtime/request-id.d.ts +12 -0
  258. package/dist/server/bare/runtime/request-id.js +14 -0
  259. package/dist/server/bare/runtime/request-registry-singleton.d.ts +4 -0
  260. package/dist/server/bare/runtime/request-registry-singleton.js +27 -0
  261. package/dist/server/bare/runtime/request-registry.d.ts +136 -0
  262. package/dist/server/bare/runtime/request-registry.js +297 -0
  263. package/dist/server/bare/runtime/with-request-context.d.ts +22 -0
  264. package/dist/server/bare/runtime/with-request-context.js +53 -0
  265. package/dist/server/bare/runtime-lifecycle.js +9 -9
  266. package/dist/server/bare/types/addon-responses.d.ts +12 -1
  267. package/dist/server/env.js +4 -1
  268. package/dist/server/plugins/index.d.ts +1 -1
  269. package/dist/server/plugins/index.js +1 -1
  270. package/dist/server/plugins/registry.d.ts +1 -0
  271. package/dist/server/plugins/registry.js +5 -0
  272. package/dist/server/rpc/handler-registry.js +30 -7
  273. package/dist/server/rpc/handler-selection.d.ts +9 -0
  274. package/dist/server/rpc/handler-selection.js +14 -0
  275. package/dist/server/rpc/handler-utils.js +5 -13
  276. package/dist/server/rpc/handlers/cancel-delegated.js +28 -31
  277. package/dist/server/rpc/handlers/cancelHandler.d.ts +30 -1
  278. package/dist/server/rpc/handlers/cancelHandler.js +54 -22
  279. package/dist/server/rpc/handlers/classify.d.ts +3 -0
  280. package/dist/server/rpc/handlers/classify.js +4 -0
  281. package/dist/server/rpc/handlers/delete-cache.d.ts +9 -0
  282. package/dist/server/rpc/handlers/delete-cache.js +13 -15
  283. package/dist/server/rpc/handlers/download-asset.js +133 -40
  284. package/dist/server/rpc/handlers/index.d.ts +4 -0
  285. package/dist/server/rpc/handlers/index.js +4 -0
  286. package/dist/server/rpc/handlers/load-model/download-manager.d.ts +60 -2
  287. package/dist/server/rpc/handlers/load-model/download-manager.js +141 -8
  288. package/dist/server/rpc/handlers/load-model/handler.js +216 -98
  289. package/dist/server/rpc/handlers/load-model/http.js +3 -3
  290. package/dist/server/rpc/handlers/load-model/hyperdrive.js +1 -1
  291. package/dist/server/rpc/handlers/load-model/registry.js +1 -1
  292. package/dist/server/rpc/handlers/load-model/resolve-session.d.ts +20 -1
  293. package/dist/server/rpc/handlers/load-model/resolve-session.js +6 -5
  294. package/dist/server/rpc/handlers/load-model/resolve.d.ts +3 -2
  295. package/dist/server/rpc/handlers/load-model/resolve.js +18 -6
  296. package/dist/server/rpc/handlers/load-model/types.d.ts +24 -0
  297. package/dist/server/rpc/handlers/rag.js +133 -15
  298. package/dist/server/rpc/handlers/upscale-stream.d.ts +3 -0
  299. package/dist/server/rpc/handlers/upscale-stream.js +4 -0
  300. package/dist/server/rpc/handlers/video-stream.d.ts +3 -0
  301. package/dist/server/rpc/handlers/video-stream.js +4 -0
  302. package/dist/server/rpc/profiling/operation-metrics.js +23 -0
  303. package/dist/server/utils/completion-normalizer.js +8 -0
  304. package/dist/server/utils/config-transform.js +1 -1
  305. package/dist/server/utils/tools/dialect.js +4 -0
  306. package/dist/server/utils/tools/parser.js +16 -1
  307. package/dist/server/utils/tools/parsers/gemma4native.d.ts +4 -0
  308. package/dist/server/utils/tools/parsers/gemma4native.js +60 -0
  309. package/dist/server/utils/tools/parsers/qwen35.d.ts +4 -0
  310. package/dist/server/utils/tools/parsers/qwen35.js +120 -0
  311. package/dist/server/worker.js +14 -11
  312. package/dist/utils/aggregate-events.d.ts +9 -0
  313. package/dist/utils/aggregate-events.js +18 -3
  314. package/dist/utils/decorate-promise.d.ts +34 -0
  315. package/dist/utils/decorate-promise.js +35 -0
  316. package/dist/utils/errors-client.d.ts +18 -0
  317. package/dist/utils/errors-client.js +31 -0
  318. package/dist/utils/errors-server.d.ts +115 -2
  319. package/dist/utils/errors-server.js +148 -3
  320. package/package.json +68 -77
  321. package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +0 -490
  322. package/dist/server/bare/plugins/onnx-tts/plugin.js +0 -266
  323. package/dist/server/bare/plugins/onnx-tts/wav-helper.d.ts +0 -14
  324. package/dist/server/bare/plugins/onnx-tts/wav-helper.js +0 -107
  325. /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.d.ts +0 -0
  326. /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.d.ts +0 -0
@@ -1,5 +1,6 @@
1
1
  import { type ModelProgressUpdate } from "../../../../schemas/index";
2
2
  import type { ResolveResult, DownloadHooks } from "./types";
3
- export declare function resolveModelPath(modelSrc: unknown, progressCallback?: (progress: ModelProgressUpdate) => void, seed?: boolean, hooks?: DownloadHooks): Promise<string>;
4
- export declare function resolveModelPathWithStats(modelSrc: unknown, progressCallback?: (progress: ModelProgressUpdate) => void, seed?: boolean, hooks?: DownloadHooks): Promise<ResolveResult>;
3
+ import type { AbortSignal } from "bare-abort-controller";
4
+ export declare function resolveModelPath(modelSrc: unknown, progressCallback?: (progress: ModelProgressUpdate) => void, seed?: boolean, signal?: AbortSignal, hooks?: DownloadHooks): Promise<string>;
5
+ export declare function resolveModelPathWithStats(modelSrc: unknown, progressCallback?: (progress: ModelProgressUpdate) => void, seed?: boolean, signal?: AbortSignal, hooks?: DownloadHooks): Promise<ResolveResult>;
5
6
  //# sourceMappingURL=resolve.d.ts.map
@@ -7,7 +7,7 @@ import { downloadModelFromHttp } from "./http.js";
7
7
  import { downloadModelFromHyperdrive } from "./hyperdrive.js";
8
8
  import { downloadModelFromRegistry } from "./registry.js";
9
9
  import { downloadModelFromHttpWithStats, downloadModelFromHyperdriveWithStats, downloadModelFromRegistryWithStats, } from "./download-stats.js";
10
- import { ModelLoadFailedError, ModelNotFoundError, SeedingNotSupportedError, } from "../../../../utils/errors-server.js";
10
+ import { InferenceCancelledError, ModelLoadFailedError, ModelNotFoundError, SeedingNotSupportedError, } from "../../../../utils/errors-server.js";
11
11
  import { validateAndJoinPath } from "../../../utils/path-security.js";
12
12
  import { getServerLogger } from "../../../../logging/index.js";
13
13
  import { modelInputToSrcSchema } from "../../../../schemas/index.js";
@@ -74,8 +74,20 @@ function buildResult(pathOrResult, sourceType) {
74
74
  }
75
75
  return { path: pathOrResult, sourceType };
76
76
  }
77
- async function resolveModelPathCore(modelSrc, progressCallback, seed, mode, hooks) {
77
+ async function resolveModelPathCore(modelSrc, progressCallback, seed, mode, signal, hooks) {
78
+ if (signal?.aborted) {
79
+ throw new InferenceCancelledError(hooks?.requestBinding?.requestId ?? "unknown");
80
+ }
78
81
  const srcString = modelInputToSrcSchema.parse(modelSrc);
82
+ // Empty modelSrc is reserved for plugins that ship bundled weights
83
+ // (e.g. `@qvac/classification-ggml`). The handler skips this resolver
84
+ // for them when `skipPrimaryModelPathValidation` is set, but if it
85
+ // somehow gets called we return an empty path so the plugin's
86
+ // `params.modelPath` falls through to undefined instead of being set
87
+ // to the cache directory itself.
88
+ if (srcString === "") {
89
+ return { path: "", sourceType: "filesystem" };
90
+ }
79
91
  // Parse hyperdrive URLs if present
80
92
  let hyperdriveKey;
81
93
  let actualModelSrc = srcString;
@@ -137,10 +149,10 @@ async function resolveModelPathCore(modelSrc, progressCallback, seed, mode, hook
137
149
  }
138
150
  return { path: resolvedPath, sourceType: "filesystem" };
139
151
  }
140
- export async function resolveModelPath(modelSrc, progressCallback, seed, hooks) {
141
- const result = await resolveModelPathCore(modelSrc, progressCallback, seed, "base", hooks);
152
+ export async function resolveModelPath(modelSrc, progressCallback, seed, signal, hooks) {
153
+ const result = await resolveModelPathCore(modelSrc, progressCallback, seed, "base", signal, hooks);
142
154
  return result.path;
143
155
  }
144
- export async function resolveModelPathWithStats(modelSrc, progressCallback, seed, hooks) {
145
- return resolveModelPathCore(modelSrc, progressCallback, seed, "stats", hooks);
156
+ export async function resolveModelPathWithStats(modelSrc, progressCallback, seed, signal, hooks) {
157
+ return resolveModelPathCore(modelSrc, progressCallback, seed, "stats", signal, hooks);
146
158
  }
@@ -1,4 +1,6 @@
1
1
  import type { SourceType } from "../../../../schemas/index";
2
+ import type { AbortSignal } from "bare-abort-controller";
3
+ import type { DisposableScope } from "../../../bare/runtime/disposable-scope";
2
4
  export interface DownloadStats {
3
5
  downloadTimeMs?: number;
4
6
  totalBytesDownloaded?: number;
@@ -16,12 +18,34 @@ export interface DownloadResult {
16
18
  path: string;
17
19
  stats?: DownloadStats;
18
20
  }
21
+ /**
22
+ * Internal request binding threaded through `DownloadHooks` so the
23
+ * download manager's `startOrJoinDownload` can register a per-subscriber
24
+ * cancel hook against the caller's `RequestContext`. The binding's
25
+ * fields mirror the registry context's surface area: `signal` is wired
26
+ * to a subscriber-removing listener, `scope` registers the idempotent
27
+ * cleanup, and `requestId` lets `cancelTransfer` (legacy entry point)
28
+ * route cancels through `registry.cancel(...)` rather than reaching
29
+ * into the transfer directly.
30
+ */
31
+ export interface DownloadRequestBinding {
32
+ signal: AbortSignal;
33
+ scope: DisposableScope;
34
+ requestId: string;
35
+ }
19
36
  export interface DownloadHooks {
20
37
  onDownloadKey?: (key: string) => void;
21
38
  markCacheHit?: () => void;
22
39
  markCacheMiss?: () => void;
23
40
  markSharedTransfer?: () => void;
24
41
  addChecksumValidationTimeMs?: (durationMs: number) => void;
42
+ /**
43
+ * When set, `startOrJoinDownload` attaches a per-subscriber cancel
44
+ * listener bound to this request. `registry.cancel({ requestId })`
45
+ * aborts only this subscriber; the transfer keeps running for siblings
46
+ * joined on the same `downloadKey` until the last subscriber leaves.
47
+ */
48
+ requestBinding?: DownloadRequestBinding;
25
49
  }
26
50
  export interface LoadModelProfilingMeta {
27
51
  sourceType?: string;
@@ -1,4 +1,59 @@
1
- import { chunk, ingest, reindex, saveEmbeddings, search, deleteEmbeddings, listWorkspaces, closeWorkspace, deleteWorkspace, DEFAULT_WORKSPACE, registerRagOperation, unregisterRagOperation, } from "../../bare/rag-hyperdb/index.js";
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
53
+ import { chunk, ingest, reindex, saveEmbeddings, search, deleteEmbeddings, listWorkspaces, closeWorkspace, deleteWorkspace, DEFAULT_WORKSPACE, getActiveRagRequest, setActiveRagRequest, clearActiveRagRequest, } from "../../bare/rag-hyperdb/index.js";
54
+ import { getRequestRegistry, withRequestContext, } from "../../bare/runtime/index.js";
55
+ import { generateServerRequestId } from "../../bare/runtime/request-id.js";
56
+ import { getServerLogger } from "../../../logging/index.js";
2
57
  import { profileReplyHandler, registerOperationMetrics, } from "../profiling/index.js";
3
58
  registerOperationMetrics({
4
59
  op: "rag",
@@ -20,8 +75,7 @@ registerOperationMetrics({
20
75
  return Object.keys(gauges).length > 0 ? gauges : undefined;
21
76
  },
22
77
  });
23
- function createHandlerOptions(operation, workspace, onProgress) {
24
- const signal = registerRagOperation(workspace, operation);
78
+ function createHandlerOptions(operation, workspace, signal, onProgress) {
25
79
  const options = { signal };
26
80
  if (onProgress) {
27
81
  options.onProgress = (stage, current, total) => onProgress({
@@ -42,6 +96,37 @@ function omitOnProgress(obj) {
42
96
  void withProgress;
43
97
  return rest;
44
98
  }
99
+ /**
100
+ * Begin a registry-tracked RAG context with workspace-level pre-emption.
101
+ *
102
+ * Workspace-level admission lives in the dispatcher rather than as a
103
+ * registry policy primitive (it's a dispatch concern, not a registry
104
+ * `kind` admission rule). The sequence is **cancel-prior → begin-new**:
105
+ * if another RAG operation is already running on the same workspace,
106
+ * cancel it first, then begin the new context. Reversing the order
107
+ * would cancel the just-installed context.
108
+ *
109
+ * The workspace → requestId map is updated after `begin(...)` succeeds
110
+ * and cleared on scope unwind via `scope.defer(...)`, with a
111
+ * "still mine?" guard so an older op's deferred cleanup cannot stomp
112
+ * a newer op's mapping.
113
+ */
114
+ function beginRagContext(workspace, requestId) {
115
+ const registry = getRequestRegistry();
116
+ const prev = getActiveRagRequest(workspace);
117
+ if (prev !== undefined && prev !== requestId) {
118
+ registry.cancel({ requestId: prev, reason: "rag-workspace-preempt" });
119
+ }
120
+ const ctx = registry.begin({
121
+ requestId,
122
+ kind: "rag",
123
+ });
124
+ setActiveRagRequest(workspace, requestId);
125
+ ctx.scope.defer(() => {
126
+ clearActiveRagRequest(workspace, requestId);
127
+ });
128
+ return ctx;
129
+ }
45
130
  export async function handleRag(request, onProgress) {
46
131
  return profileReplyHandler({ op: "rag", request }, async () => handleRagInternal(request, onProgress));
47
132
  }
@@ -57,10 +142,15 @@ async function handleRagInternal(request, onProgress) {
57
142
  };
58
143
  }
59
144
  case "ingest": {
60
- const workspace = request.workspace ?? DEFAULT_WORKSPACE;
61
- const handlerOptions = createHandlerOptions("ingest", workspace, onProgress);
62
- const params = omitOnProgress(request);
145
+ const env_1 = { stack: [], error: void 0, hasError: false };
63
146
  try {
147
+ const workspace = request.workspace ?? DEFAULT_WORKSPACE;
148
+ const requestId = request.requestId ?? generateServerRequestId();
149
+ const ctx = __addDisposableResource(env_1, beginRagContext(workspace, requestId), true);
150
+ const log = withRequestContext(getServerLogger(), ctx);
151
+ log.debug("ingest start");
152
+ const handlerOptions = createHandlerOptions("ingest", workspace, ctx.signal, onProgress);
153
+ const params = omitOnProgress(request);
64
154
  const result = await ingest(params, handlerOptions);
65
155
  return {
66
156
  type: "rag",
@@ -70,15 +160,26 @@ async function handleRagInternal(request, onProgress) {
70
160
  droppedIndices: result.droppedIndices,
71
161
  };
72
162
  }
163
+ catch (e_1) {
164
+ env_1.error = e_1;
165
+ env_1.hasError = true;
166
+ }
73
167
  finally {
74
- unregisterRagOperation(workspace);
168
+ const result_1 = __disposeResources(env_1);
169
+ if (result_1)
170
+ await result_1;
75
171
  }
76
172
  }
77
173
  case "saveEmbeddings": {
78
- const workspace = request.workspace ?? DEFAULT_WORKSPACE;
79
- const handlerOptions = createHandlerOptions("saveEmbeddings", workspace, onProgress);
80
- const params = omitOnProgress(request);
174
+ const env_2 = { stack: [], error: void 0, hasError: false };
81
175
  try {
176
+ const workspace = request.workspace ?? DEFAULT_WORKSPACE;
177
+ const requestId = request.requestId ?? generateServerRequestId();
178
+ const ctx = __addDisposableResource(env_2, beginRagContext(workspace, requestId), true);
179
+ const log = withRequestContext(getServerLogger(), ctx);
180
+ log.debug("saveEmbeddings start");
181
+ const handlerOptions = createHandlerOptions("saveEmbeddings", workspace, ctx.signal, onProgress);
182
+ const params = omitOnProgress(request);
82
183
  const processed = await saveEmbeddings(params, handlerOptions);
83
184
  return {
84
185
  type: "rag",
@@ -87,8 +188,14 @@ async function handleRagInternal(request, onProgress) {
87
188
  processed,
88
189
  };
89
190
  }
191
+ catch (e_2) {
192
+ env_2.error = e_2;
193
+ env_2.hasError = true;
194
+ }
90
195
  finally {
91
- unregisterRagOperation(workspace);
196
+ const result_2 = __disposeResources(env_2);
197
+ if (result_2)
198
+ await result_2;
92
199
  }
93
200
  }
94
201
  case "search": {
@@ -109,10 +216,15 @@ async function handleRagInternal(request, onProgress) {
109
216
  };
110
217
  }
111
218
  case "reindex": {
112
- const workspace = request.workspace ?? DEFAULT_WORKSPACE;
113
- const handlerOptions = createHandlerOptions("reindex", workspace, onProgress);
114
- const params = omitOnProgress(request);
219
+ const env_3 = { stack: [], error: void 0, hasError: false };
115
220
  try {
221
+ const workspace = request.workspace ?? DEFAULT_WORKSPACE;
222
+ const requestId = request.requestId ?? generateServerRequestId();
223
+ const ctx = __addDisposableResource(env_3, beginRagContext(workspace, requestId), true);
224
+ const log = withRequestContext(getServerLogger(), ctx);
225
+ log.debug("reindex start");
226
+ const handlerOptions = createHandlerOptions("reindex", workspace, ctx.signal, onProgress);
227
+ const params = omitOnProgress(request);
116
228
  const result = await reindex(params, handlerOptions);
117
229
  return {
118
230
  type: "rag",
@@ -121,8 +233,14 @@ async function handleRagInternal(request, onProgress) {
121
233
  result,
122
234
  };
123
235
  }
236
+ catch (e_3) {
237
+ env_3.error = e_3;
238
+ env_3.hasError = true;
239
+ }
124
240
  finally {
125
- unregisterRagOperation(workspace);
241
+ const result_3 = __disposeResources(env_3);
242
+ if (result_3)
243
+ await result_3;
126
244
  }
127
245
  }
128
246
  case "listWorkspaces": {
@@ -0,0 +1,3 @@
1
+ import type { UpscaleStreamRequest, UpscaleStreamResponse } from "../../../schemas/sdcpp-config";
2
+ export declare function handleUpscaleStream(request: UpscaleStreamRequest): AsyncGenerator<UpscaleStreamResponse>;
3
+ //# sourceMappingURL=upscale-stream.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { dispatchPluginStream } from "./plugin-dispatch.js";
2
+ export async function* handleUpscaleStream(request) {
3
+ yield* dispatchPluginStream(request.modelId, "upscaleStream", request);
4
+ }
@@ -0,0 +1,3 @@
1
+ import type { VideoStreamRequest, VideoStreamResponse } from "../../../schemas/sdcpp-config";
2
+ export declare function handleVideoStream(request: VideoStreamRequest): AsyncGenerator<VideoStreamResponse>;
3
+ //# sourceMappingURL=video-stream.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { dispatchPluginStream } from "./plugin-dispatch.js";
2
+ export async function* handleVideoStream(request) {
3
+ yield* dispatchPluginStream(request.modelId, "videoStream", request);
4
+ }
@@ -242,6 +242,29 @@ registerOperationMetrics({
242
242
  return Object.keys(gauges).length > 0 ? gauges : undefined;
243
243
  },
244
244
  });
245
+ registerOperationMetrics({
246
+ op: "videoStream",
247
+ kind: "handler",
248
+ getTags: (req) => (req.modelId ? { modelId: req.modelId } : {}),
249
+ fromFinalChunk: (res) => {
250
+ if (!res.stats)
251
+ return undefined;
252
+ const gauges = {};
253
+ if (res.stats.generationMs !== undefined)
254
+ gauges["generationMs"] = res.stats.generationMs;
255
+ if (res.stats.totalSteps !== undefined)
256
+ gauges["totalSteps"] = res.stats.totalSteps;
257
+ if (res.stats.totalVideos !== undefined)
258
+ gauges["totalVideos"] = res.stats.totalVideos;
259
+ if (res.stats.totalVideoFrames !== undefined)
260
+ gauges["totalVideoFrames"] = res.stats.totalVideoFrames;
261
+ if (res.stats.videoFrames !== undefined)
262
+ gauges["videoFrames"] = res.stats.videoFrames;
263
+ if (res.stats.fps !== undefined)
264
+ gauges["fps"] = res.stats.fps;
265
+ return Object.keys(gauges).length > 0 ? gauges : undefined;
266
+ },
267
+ });
245
268
  registerOperationMetrics({
246
269
  op: "pluginInvoke",
247
270
  kind: "handler",
@@ -34,6 +34,14 @@ const DIALECT_SPECS = {
34
34
  "<|return|>",
35
35
  ],
36
36
  },
37
+ qwen35: {
38
+ // Same <tool_call>…</tool_call> framing as hermes; inner content is XML.
39
+ toolFrames: [{ open: "<tool_call>", close: "</tool_call>" }],
40
+ },
41
+ gemma4: {
42
+ toolFrames: [{ open: "<|tool_call>", close: "<tool_call|>" }],
43
+ thinkingFrames: [{ open: "<|channel>thought", close: "<channel|>" }],
44
+ },
37
45
  };
38
46
  // Capture-gated reasoning marker — the generic `<think>...</think>`
39
47
  // convention used by reasoning-tuned models. When the gate is off the
@@ -14,7 +14,7 @@ export function transformConfigForReload(modelType, config) {
14
14
  case ModelType.llamacppCompletion:
15
15
  case ModelType.llamacppEmbedding:
16
16
  case ModelType.nmtcppTranslation:
17
- case ModelType.onnxTts:
17
+ case ModelType.ttsGgml:
18
18
  // Return as-is for now
19
19
  return config;
20
20
  default:
@@ -6,6 +6,10 @@
6
6
  export function detectToolDialectFromName(name, path) {
7
7
  const basename = path.toLowerCase().split(/[/\\]/).pop() ?? "";
8
8
  const tag = `${(name ?? "").toLowerCase()}|${basename}`;
9
+ if (/qwen3[._-]?[56](?![a-z0-9])/.test(tag))
10
+ return "qwen35";
11
+ if (/gemma[-_]?4(?=[^a-z0-9]|$)/.test(tag))
12
+ return "gemma4";
9
13
  if (/gpt[_-]?oss/.test(tag))
10
14
  return "harmony";
11
15
  if (/lfm[_-]?\d/.test(tag))
@@ -3,6 +3,8 @@ import { parseGemmaFormat, parseGenericFormat, parseLlamacppFormat, } from "./pa
3
3
  import { parseHermesFormat } from "./parsers/hermes.js";
4
4
  import { parsePythonicFormat } from "./parsers/pythonic.js";
5
5
  import { parseHarmonyFormat } from "./parsers/harmony.js";
6
+ import { parseQwen35Format } from "./parsers/qwen35.js";
7
+ import { parseGemma4NativeFormat } from "./parsers/gemma4native.js";
6
8
  function pickFormatParsers(dialect) {
7
9
  switch (dialect) {
8
10
  case "pythonic":
@@ -15,13 +17,26 @@ function pickFormatParsers(dialect) {
15
17
  return [parseGemmaFormat, parseLlamacppFormat];
16
18
  case "harmony":
17
19
  return [parseHarmonyFormat];
20
+ case "qwen35":
21
+ // Hermes fallback: Qwen3.5 templates sometimes emit OpenAI-style JSON
22
+ // when the native XML format fails; Hermes chain recovers those.
23
+ return [parseQwen35Format, parseHermesFormat];
24
+ case "gemma4":
25
+ // No JSON fallback: Gemma4 emits only its native channel-thought dialect
26
+ // and never falls back to JSON-envelope formats.
27
+ return [parseGemma4NativeFormat];
18
28
  default:
19
- // Harmony first: `to=functions.` is uniquely Harmony and can't
29
+ // Gemma4 first: `<|tool_call>` is uniquely distinctive and can't
20
30
  // false-match other dialects.
31
+ // Harmony next: `to=functions.` is also uniquely Harmony.
32
+ // Qwen35 before Hermes: defers to Hermes when JSON is inside <tool_call>,
33
+ // so the XML path is recovered without breaking Hermes-JSON payloads.
21
34
  // Pythonic last: its bare `[name(...)]` form can match payloads that
22
35
  // look like other dialects.
23
36
  return [
37
+ parseGemma4NativeFormat,
24
38
  parseHarmonyFormat,
39
+ parseQwen35Format,
25
40
  parseHermesFormat,
26
41
  parseGemmaFormat,
27
42
  parseLlamacppFormat,
@@ -0,0 +1,4 @@
1
+ import type { Tool } from "../../../../schemas/index";
2
+ import { type ParserResult } from "../shared";
3
+ export declare function parseGemma4NativeFormat(text: string, tools: Tool[]): ParserResult;
4
+ //# sourceMappingURL=gemma4native.d.ts.map
@@ -0,0 +1,60 @@
1
+ import { generateStableToolCallId, validateToolArguments, } from "../shared.js";
2
+ // Transliterates Gemma 4's JS-literal argument body to valid JSON so it can
3
+ // be parsed with JSON.parse. The body uses:
4
+ // - <|"|>...<|"|> instead of "..." for string values
5
+ // - bare (unquoted) object keys
6
+ // Strategy: split by <|"|> tokens so structural parts (even indices) and
7
+ // string value parts (odd indices) are processed separately, preventing
8
+ // the key-quoting regex from matching `, key:` patterns inside string values.
9
+ function gemmaArgsToJson(argsRaw) {
10
+ const parts = ("{" + argsRaw + "}").split(/<\|"\|>/);
11
+ return parts
12
+ .map((part, i) => i % 2 === 0
13
+ ? part.replace(/([{,]\s*)([A-Za-z_][\w-]*)\s*:/g, '$1"$2":')
14
+ : '"' + part.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/[\x00-\x1f]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`) + '"')
15
+ .join("");
16
+ }
17
+ // Parses Gemma 4's native tool-call dialect:
18
+ // <|tool_call>call:NAME{key:<|"|>val<|"|>,key2:bareNum,...}<tool_call|>
19
+ // Keys are bare identifiers; string values are wrapped in <|"|>...<|"|>;
20
+ // numbers/booleans are bare literals; nested objects/arrays use JS-literal
21
+ // syntax throughout. Transliterates to JSON then parses.
22
+ export function parseGemma4NativeFormat(text, tools) {
23
+ const toolCalls = [];
24
+ const errors = [];
25
+ if (!text.includes("<|tool_call>")) {
26
+ return { matched: false, toolCalls, errors };
27
+ }
28
+ const callRegex = /<\|tool_call>call:([A-Za-z_][\w-]*)\{([\s\S]*?)\}<tool_call\|>/g;
29
+ const matches = Array.from(text.matchAll(callRegex));
30
+ if (matches.length === 0)
31
+ return { matched: false, toolCalls, errors };
32
+ for (const match of matches) {
33
+ const name = match[1];
34
+ const argsRaw = match[2];
35
+ let args;
36
+ try {
37
+ args = JSON.parse(gemmaArgsToJson(argsRaw));
38
+ }
39
+ catch (err) {
40
+ errors.push({
41
+ code: "PARSE_ERROR",
42
+ message: `Failed to parse Gemma 4 tool call arguments: ${err instanceof Error ? err.message : String(err)}`,
43
+ raw: match[0],
44
+ });
45
+ continue;
46
+ }
47
+ const validation = validateToolArguments(name, args, tools);
48
+ if (!validation.isValid && validation.error) {
49
+ errors.push({ ...validation.error, raw: match[0] });
50
+ continue;
51
+ }
52
+ toolCalls.push({
53
+ id: generateStableToolCallId(name, args),
54
+ name,
55
+ arguments: args,
56
+ raw: match[0],
57
+ });
58
+ }
59
+ return { matched: true, toolCalls, errors };
60
+ }
@@ -0,0 +1,4 @@
1
+ import type { Tool } from "../../../../schemas/index";
2
+ import { type ParserResult } from "../shared";
3
+ export declare function parseQwen35Format(text: string, tools: Tool[]): ParserResult;
4
+ //# sourceMappingURL=qwen35.d.ts.map
@@ -0,0 +1,120 @@
1
+ import { generateStableToolCallId, validateToolArguments, } from "../shared.js";
2
+ // Coerce raw parameter text to the type declared in the tool's JSON schema.
3
+ // String values are raw (not JSON-quoted); arrays/objects are valid JSON.
4
+ function coerceParamValue(raw, schema) {
5
+ const trimmed = raw.trim();
6
+ if (!schema?.type)
7
+ return trimmed;
8
+ switch (schema.type) {
9
+ case "number": {
10
+ if (trimmed.length === 0)
11
+ throw new Error(`invalid numeric value: ""`);
12
+ const n = Number(trimmed);
13
+ if (Number.isNaN(n))
14
+ throw new Error(`invalid numeric value: "${trimmed}"`);
15
+ return n;
16
+ }
17
+ case "integer": {
18
+ if (trimmed.length === 0)
19
+ throw new Error(`invalid integer value: ""`);
20
+ const n = Number(trimmed);
21
+ if (Number.isNaN(n) || !Number.isInteger(n))
22
+ throw new Error(`invalid integer value: "${trimmed}"`);
23
+ return n;
24
+ }
25
+ case "boolean":
26
+ if (trimmed === "true")
27
+ return true;
28
+ if (trimmed === "false")
29
+ return false;
30
+ throw new Error(`invalid boolean value: "${trimmed}"`);
31
+ case "array":
32
+ case "object":
33
+ return JSON.parse(trimmed);
34
+ default:
35
+ return trimmed;
36
+ }
37
+ }
38
+ // Parses Qwen3.5/3.6 Pythonic-XML tool-call format:
39
+ // <tool_call>
40
+ // <function=NAME>
41
+ // <parameter=KEY>VALUE</parameter>
42
+ // </function>
43
+ // </tool_call>
44
+ // String parameter values are raw text (not JSON-quoted); arrays/objects
45
+ // are JSON. Type coercion uses the tool schema; unknown params pass through.
46
+ export function parseQwen35Format(text, tools) {
47
+ const toolCalls = [];
48
+ const errors = [];
49
+ if (!text.includes("<tool_call>")) {
50
+ return { matched: false, toolCalls, errors };
51
+ }
52
+ const outerRegex = /<tool_call>([\s\S]*?)<\/tool_call>/g;
53
+ const outerMatches = Array.from(text.matchAll(outerRegex));
54
+ if (outerMatches.length === 0)
55
+ return { matched: false, toolCalls, errors };
56
+ // If no match contains XML function syntax, check if this is JSON format
57
+ // (defer to hermes) or just malformed content (surface as PARSE_ERROR).
58
+ if (!outerMatches.some((m) => m[1].includes("<function="))) {
59
+ const looksLikeJson = outerMatches.some((m) => {
60
+ const inner = m[1].trim();
61
+ return inner.startsWith("{") || inner.startsWith("[");
62
+ });
63
+ if (looksLikeJson)
64
+ return { matched: false, toolCalls, errors };
65
+ return {
66
+ matched: true,
67
+ toolCalls,
68
+ errors: outerMatches.map((m) => ({
69
+ code: "PARSE_ERROR",
70
+ message: "Qwen3.5 tool call missing <function=NAME>...</function>",
71
+ raw: m[1].trim(),
72
+ })),
73
+ };
74
+ }
75
+ for (const outerMatch of outerMatches) {
76
+ const inner = outerMatch[1].trim();
77
+ const fnMatch = /<function=([^>\s]+)\s*>([\s\S]*?)<\/function>/i.exec(inner);
78
+ if (!fnMatch) {
79
+ errors.push({
80
+ code: "PARSE_ERROR",
81
+ message: "Qwen3.5 tool call missing <function=NAME>...</function>",
82
+ raw: inner,
83
+ });
84
+ continue;
85
+ }
86
+ const name = fnMatch[1].trim();
87
+ const paramsBlock = fnMatch[2];
88
+ const tool = tools.find((t) => t.name === name);
89
+ const schemaProperties = tool?.parameters?.properties ?? {};
90
+ const args = {};
91
+ let parseError;
92
+ try {
93
+ const paramRegex = /<parameter=([^>\s]+)\s*>([\s\S]*?)<\/parameter>/gi;
94
+ let pm;
95
+ while ((pm = paramRegex.exec(paramsBlock)) !== null) {
96
+ const paramName = pm[1].trim();
97
+ args[paramName] = coerceParamValue(pm[2], schemaProperties[paramName]);
98
+ }
99
+ }
100
+ catch (err) {
101
+ parseError = err instanceof Error ? err.message : String(err);
102
+ }
103
+ if (parseError !== undefined) {
104
+ errors.push({ code: "PARSE_ERROR", message: parseError, raw: inner });
105
+ continue;
106
+ }
107
+ const validation = validateToolArguments(name, args, tools);
108
+ if (!validation.isValid && validation.error) {
109
+ errors.push({ ...validation.error, raw: inner });
110
+ continue;
111
+ }
112
+ toolCalls.push({
113
+ id: generateStableToolCallId(name, args),
114
+ name,
115
+ arguments: args,
116
+ raw: inner,
117
+ });
118
+ }
119
+ return { matched: true, toolCalls, errors };
120
+ }