@qvac/sdk 0.4.1 → 0.6.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 (334) hide show
  1. package/README.md +365 -200
  2. package/bare-imports.json +35 -0
  3. package/dist/client/api/cancel.d.ts +12 -3
  4. package/dist/client/api/cancel.js +12 -3
  5. package/dist/client/api/completion-stream.d.ts +15 -5
  6. package/dist/client/api/completion-stream.js +50 -14
  7. package/dist/client/api/embed.d.ts +17 -3
  8. package/dist/client/api/embed.js +0 -8
  9. package/dist/client/api/get-model-info.d.ts +2 -2
  10. package/dist/client/api/get-model-info.js +2 -2
  11. package/dist/client/api/index.d.ts +2 -2
  12. package/dist/client/api/index.js +2 -2
  13. package/dist/client/api/load-model.d.ts +37 -11
  14. package/dist/client/api/load-model.js +34 -117
  15. package/dist/client/api/logging-stream.d.ts +6 -3
  16. package/dist/client/api/logging-stream.js +6 -3
  17. package/dist/client/api/ocr.d.ts +31 -0
  18. package/dist/client/api/ocr.js +88 -0
  19. package/dist/client/api/rag.d.ts +215 -20
  20. package/dist/client/api/rag.js +382 -23
  21. package/dist/client/api/translate.js +10 -11
  22. package/dist/client/api/unload-model.js +6 -3
  23. package/dist/client/config-loader/config-utils.d.ts +5 -0
  24. package/dist/client/config-loader/config-utils.js +20 -0
  25. package/dist/client/config-loader/resolve-config.bare.d.ts +9 -0
  26. package/dist/client/config-loader/resolve-config.bare.js +87 -0
  27. package/dist/client/config-loader/resolve-config.expo.d.ts +11 -0
  28. package/dist/client/config-loader/resolve-config.expo.js +62 -0
  29. package/dist/client/config-loader/resolve-config.node.d.ts +9 -0
  30. package/dist/client/config-loader/resolve-config.node.js +118 -0
  31. package/dist/client/init-hooks.d.ts +18 -3
  32. package/dist/client/init-hooks.js +57 -29
  33. package/dist/client/logging-stream-registry.d.ts +1 -1
  34. package/dist/client/logging-stream-registry.js +14 -13
  35. package/dist/client/rpc/bare-client.d.ts +3 -184
  36. package/dist/client/rpc/bare-client.js +67 -8
  37. package/dist/client/rpc/expo-rpc-client.d.ts +2 -2
  38. package/dist/client/rpc/expo-rpc-client.js +70 -12
  39. package/dist/client/rpc/node-rpc-client.d.ts +1 -1
  40. package/dist/client/rpc/node-rpc-client.js +14 -7
  41. package/dist/client/rpc/rpc-client.d.ts +1 -1
  42. package/dist/client/rpc/rpc-client.js +13 -58
  43. package/dist/examples/config/blind-relay/blind-relay.config.d.ts +5 -0
  44. package/dist/examples/config/blind-relay/blind-relay.config.js +7 -0
  45. package/dist/examples/config/default/default.config.d.ts +8 -0
  46. package/dist/examples/config/default/default.config.js +6 -0
  47. package/dist/examples/config-reload.d.ts +2 -0
  48. package/dist/examples/config-reload.js +49 -0
  49. package/dist/examples/default-config-usage.d.ts +17 -0
  50. package/dist/examples/default-config-usage.js +47 -0
  51. package/dist/examples/delegated-inference/consumer.js +1 -0
  52. package/dist/examples/download-with-blind-relays.js +22 -21
  53. package/dist/examples/embed-hyperdrive.js +39 -3
  54. package/dist/examples/kv-cache-cleanup.js +1 -1
  55. package/dist/examples/kv-cache-custom-key.js +16 -1
  56. package/dist/examples/kv-cache-example.js +1 -1
  57. package/dist/examples/llamacpp-hyperdrive.js +1 -1
  58. package/dist/examples/llamacpp-sharded.js +13 -4
  59. package/dist/examples/logging-file-transport.d.ts +2 -0
  60. package/dist/examples/{llamacpp-file-logging.js → logging-file-transport.js} +3 -7
  61. package/dist/examples/logging-streaming.d.ts +2 -0
  62. package/dist/examples/logging-streaming.js +75 -0
  63. package/dist/examples/mcp-websearch.d.ts +13 -0
  64. package/dist/examples/mcp-websearch.js +176 -0
  65. package/dist/examples/ocr-fasttext.d.ts +2 -0
  66. package/dist/examples/ocr-fasttext.js +52 -0
  67. package/dist/examples/quickstart.d.ts +2 -0
  68. package/dist/examples/quickstart.js +28 -0
  69. package/dist/examples/rag/rag-hyperdb/cancellation.d.ts +2 -0
  70. package/dist/examples/rag/rag-hyperdb/cancellation.js +75 -0
  71. package/dist/examples/rag/rag-hyperdb/ingest.d.ts +2 -0
  72. package/dist/examples/rag/{rag-hyperdb.js → rag-hyperdb/ingest.js} +10 -4
  73. package/dist/examples/rag/rag-hyperdb/pipeline.d.ts +2 -0
  74. package/dist/examples/rag/rag-hyperdb/pipeline.js +74 -0
  75. package/dist/examples/rag/rag-hyperdb/workspaces.d.ts +2 -0
  76. package/dist/examples/rag/rag-hyperdb/workspaces.js +178 -0
  77. package/dist/examples/translation/translation-bergamot-batch.d.ts +2 -0
  78. package/dist/examples/translation/translation-bergamot-batch.js +49 -0
  79. package/dist/examples/translation/translation-bergamot.d.ts +2 -0
  80. package/dist/examples/translation/translation-bergamot.js +39 -0
  81. package/dist/examples/translation/translation-indic.js +1 -0
  82. package/dist/examples/translation/translation-opus.js +1 -0
  83. package/dist/examples/translation/translation-stream.js +1 -0
  84. package/dist/expo/plugins/withMobileBundle.js +29 -10
  85. package/dist/index.d.ts +5 -4
  86. package/dist/index.js +4 -2
  87. package/dist/logging/addon.d.ts +6 -0
  88. package/dist/logging/addon.js +75 -0
  89. package/dist/logging/base-logger.js +26 -16
  90. package/dist/logging/client-logger.d.ts +3 -0
  91. package/dist/logging/client-logger.js +24 -0
  92. package/dist/logging/index.d.ts +7 -1
  93. package/dist/logging/index.js +7 -1
  94. package/dist/logging/logger.d.ts +0 -2
  95. package/dist/logging/logger.js +11 -6
  96. package/dist/logging/namespaces.d.ts +12 -0
  97. package/dist/logging/namespaces.js +12 -0
  98. package/dist/logging/registry.d.ts +31 -0
  99. package/dist/logging/registry.js +48 -0
  100. package/dist/logging/server-logger.d.ts +3 -0
  101. package/dist/logging/server-logger.js +16 -0
  102. package/dist/logging/stream-logger.d.ts +1 -1
  103. package/dist/logging/stream-logger.js +6 -3
  104. package/dist/logging/transport.js +2 -2
  105. package/dist/logging/types.d.ts +2 -0
  106. package/dist/logging/utils.d.ts +2 -0
  107. package/dist/logging/utils.js +62 -0
  108. package/dist/models/hyperdrive/models.d.ts +1886 -230
  109. package/dist/models/hyperdrive/models.js +2191 -443
  110. package/dist/schemas/archive.d.ts +9 -0
  111. package/dist/schemas/archive.js +17 -0
  112. package/dist/schemas/cancel.d.ts +6 -0
  113. package/dist/schemas/cancel.js +5 -0
  114. package/dist/schemas/common.d.ts +660 -92
  115. package/dist/schemas/common.js +6 -4
  116. package/dist/schemas/delegate.d.ts +1 -0
  117. package/dist/schemas/delegate.js +1 -0
  118. package/dist/schemas/download-asset.d.ts +21 -9
  119. package/dist/schemas/embed.d.ts +3 -3
  120. package/dist/schemas/embed.js +9 -2
  121. package/dist/schemas/get-model-info.d.ts +12 -10
  122. package/dist/schemas/get-model-info.js +9 -1
  123. package/dist/schemas/index.d.ts +9 -1
  124. package/dist/schemas/index.js +12 -1
  125. package/dist/schemas/json-schema.d.ts +16 -0
  126. package/dist/schemas/json-schema.js +2 -0
  127. package/dist/schemas/llamacpp-config.d.ts +117 -12
  128. package/dist/schemas/llamacpp-config.js +46 -12
  129. package/dist/schemas/load-model.d.ts +3669 -481
  130. package/dist/schemas/load-model.js +95 -34
  131. package/dist/schemas/logging-stream.d.ts +11 -4
  132. package/dist/schemas/logging-stream.js +4 -3
  133. package/dist/schemas/mcp-adapter.d.ts +47 -0
  134. package/dist/schemas/mcp-adapter.js +1 -0
  135. package/dist/schemas/model-src-utils.d.ts +38 -14
  136. package/dist/schemas/model-src-utils.js +4 -3
  137. package/dist/schemas/model-types.d.ts +154 -0
  138. package/dist/schemas/model-types.js +140 -0
  139. package/dist/schemas/ocr.d.ts +88 -0
  140. package/dist/schemas/ocr.js +52 -0
  141. package/dist/schemas/rag.d.ts +183 -52
  142. package/dist/schemas/rag.js +148 -23
  143. package/dist/schemas/reload-config.d.ts +356 -0
  144. package/dist/schemas/reload-config.js +44 -0
  145. package/dist/schemas/runtime-context.d.ts +19 -0
  146. package/dist/schemas/runtime-context.js +7 -0
  147. package/dist/schemas/sdk-config.d.ts +717 -0
  148. package/dist/schemas/sdk-config.js +131 -0
  149. package/dist/schemas/sdk-errors-client.d.ts +5 -0
  150. package/dist/schemas/sdk-errors-client.js +25 -0
  151. package/dist/schemas/sdk-errors-server.d.ts +17 -0
  152. package/dist/schemas/sdk-errors-server.js +85 -0
  153. package/dist/schemas/shard.d.ts +21 -0
  154. package/dist/schemas/shard.js +17 -0
  155. package/dist/schemas/tools.d.ts +3 -0
  156. package/dist/schemas/translate.d.ts +68 -23
  157. package/dist/schemas/translate.js +37 -11
  158. package/dist/schemas/translation-config.d.ts +337 -13
  159. package/dist/schemas/translation-config.js +65 -9
  160. package/dist/schemas/whispercpp-config.d.ts +9 -1
  161. package/dist/schemas/whispercpp-config.js +2 -1
  162. package/dist/scripts/run-unit-tests.d.ts +2 -0
  163. package/dist/scripts/run-unit-tests.js +17 -0
  164. package/dist/server/bare/addons/llamacpp-completion/cache-logger.d.ts +6 -0
  165. package/dist/server/bare/addons/llamacpp-completion/cache-logger.js +34 -0
  166. package/dist/server/bare/addons/{llamacpp → llamacpp-completion}/create-model.d.ts +1 -5
  167. package/dist/server/bare/addons/{llamacpp → llamacpp-completion}/create-model.js +6 -20
  168. package/dist/server/bare/addons/{llamacpp → llamacpp-completion}/handlers/completion-stream.js +26 -7
  169. package/dist/server/bare/addons/llamacpp-completion/index.d.ts +4 -0
  170. package/dist/server/bare/addons/llamacpp-completion/index.js +3 -0
  171. package/dist/server/bare/addons/{llamacpp → llamacpp-completion}/kv-cache-utils.d.ts +4 -1
  172. package/dist/server/bare/addons/{llamacpp → llamacpp-completion}/kv-cache-utils.js +49 -14
  173. package/dist/server/bare/addons/llamacpp-embedding/create-model.d.ts +8 -0
  174. package/dist/server/bare/addons/llamacpp-embedding/create-model.js +38 -0
  175. package/dist/server/bare/addons/llamacpp-embedding/handlers/embed.d.ts +12 -0
  176. package/dist/server/bare/addons/{llamacpp → llamacpp-embedding}/handlers/embed.js +18 -4
  177. package/dist/server/bare/addons/llamacpp-embedding/index.d.ts +3 -0
  178. package/dist/server/bare/addons/llamacpp-embedding/index.js +2 -0
  179. package/dist/server/bare/addons/load-model.js +38 -28
  180. package/dist/server/bare/addons/{translation → nmtcpp-translation}/create-model.js +23 -8
  181. package/dist/server/bare/addons/{translation → nmtcpp-translation}/handlers/translate.js +35 -11
  182. package/dist/server/bare/addons/onnx-ocr/create-model.d.ts +10 -0
  183. package/dist/server/bare/addons/onnx-ocr/create-model.js +39 -0
  184. package/dist/server/bare/addons/onnx-ocr/handlers/ocr-stream.d.ts +10 -0
  185. package/dist/server/bare/addons/onnx-ocr/handlers/ocr-stream.js +109 -0
  186. package/dist/server/bare/addons/onnx-ocr/index.d.ts +3 -0
  187. package/dist/server/bare/addons/onnx-ocr/index.js +2 -0
  188. package/dist/server/bare/addons/unload-model.js +6 -3
  189. package/dist/server/bare/addons/{whispercpp → whispercpp-transcription}/create-model.js +2 -1
  190. package/dist/server/bare/addons/whispercpp-transcription/handlers/transcribe-stream.js +82 -0
  191. package/dist/server/bare/delegate-rpc-client.js +31 -11
  192. package/dist/server/bare/hyperswarm.js +7 -5
  193. package/dist/server/bare/rag-hyperdb/handlers/chunk.d.ts +3 -0
  194. package/dist/server/bare/rag-hyperdb/handlers/chunk.js +7 -0
  195. package/dist/server/bare/rag-hyperdb/handlers/close-workspace.d.ts +3 -0
  196. package/dist/server/bare/rag-hyperdb/handlers/close-workspace.js +9 -0
  197. package/dist/server/bare/rag-hyperdb/handlers/delete-embeddings.d.ts +1 -1
  198. package/dist/server/bare/rag-hyperdb/handlers/delete-embeddings.js +9 -10
  199. package/dist/server/bare/rag-hyperdb/handlers/delete-workspace.d.ts +3 -0
  200. package/dist/server/bare/rag-hyperdb/handlers/delete-workspace.js +14 -0
  201. package/dist/server/bare/rag-hyperdb/handlers/ingest.d.ts +9 -0
  202. package/dist/server/bare/rag-hyperdb/handlers/ingest.js +18 -0
  203. package/dist/server/bare/rag-hyperdb/handlers/list-workspaces.d.ts +3 -0
  204. package/dist/server/bare/rag-hyperdb/handlers/list-workspaces.js +4 -0
  205. package/dist/server/bare/rag-hyperdb/handlers/reindex.d.ts +9 -0
  206. package/dist/server/bare/rag-hyperdb/handlers/reindex.js +16 -0
  207. package/dist/server/bare/rag-hyperdb/handlers/save-embeddings.d.ts +7 -4
  208. package/dist/server/bare/rag-hyperdb/handlers/save-embeddings.js +13 -14
  209. package/dist/server/bare/rag-hyperdb/handlers/search.js +10 -10
  210. package/dist/server/bare/rag-hyperdb/index.d.ts +8 -1
  211. package/dist/server/bare/rag-hyperdb/index.js +8 -1
  212. package/dist/server/bare/rag-hyperdb/rag-operation-manager.d.ts +7 -0
  213. package/dist/server/bare/rag-hyperdb/rag-operation-manager.js +39 -0
  214. package/dist/server/bare/rag-hyperdb/rag-workspace-manager.d.ts +15 -0
  215. package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +135 -0
  216. package/dist/server/bare/registry/config-registry.d.ts +13 -4
  217. package/dist/server/bare/registry/config-registry.js +53 -10
  218. package/dist/server/bare/registry/logging-stream-registry.d.ts +24 -7
  219. package/dist/server/bare/registry/logging-stream-registry.js +99 -20
  220. package/dist/server/bare/registry/model-config-registry.d.ts +4 -0
  221. package/dist/server/bare/registry/model-config-registry.js +15 -0
  222. package/dist/server/bare/registry/model-config-utils.d.ts +15 -0
  223. package/dist/server/bare/registry/model-config-utils.js +121 -0
  224. package/dist/server/bare/registry/model-registry.d.ts +6 -26
  225. package/dist/server/bare/registry/model-registry.js +9 -6
  226. package/dist/server/bare/registry/runtime-context-registry.d.ts +7 -0
  227. package/dist/server/bare/registry/runtime-context-registry.js +26 -0
  228. package/dist/server/bare/utils/loader-adapter.d.ts +7 -0
  229. package/dist/server/bare/utils/loader-adapter.js +9 -0
  230. package/dist/server/error-handlers.js +4 -2
  231. package/dist/server/rpc/create-server.js +5 -3
  232. package/dist/server/rpc/handle-request.js +115 -19
  233. package/dist/server/rpc/handlers/cancelHandler.js +13 -2
  234. package/dist/server/rpc/handlers/completion-stream-delegated.js +4 -2
  235. package/dist/server/rpc/handlers/completion-stream.js +1 -1
  236. package/dist/server/rpc/handlers/delete-cache.js +4 -2
  237. package/dist/server/rpc/handlers/download-asset.js +3 -1
  238. package/dist/server/rpc/handlers/embed.js +4 -2
  239. package/dist/server/rpc/handlers/get-model-info.d.ts +1 -1
  240. package/dist/server/rpc/handlers/get-model-info.js +22 -10
  241. package/dist/server/rpc/handlers/index.d.ts +4 -2
  242. package/dist/server/rpc/handlers/index.js +2 -2
  243. package/dist/server/rpc/handlers/load-model/download-manager.d.ts +11 -11
  244. package/dist/server/rpc/handlers/load-model/download-manager.js +40 -28
  245. package/dist/server/rpc/handlers/{load-model.d.ts → load-model/handler.d.ts} +2 -2
  246. package/dist/server/rpc/handlers/load-model/handler.js +179 -0
  247. package/dist/server/rpc/handlers/load-model/http.js +361 -50
  248. package/dist/server/rpc/handlers/load-model/hyperdrive.js +26 -22
  249. package/dist/server/rpc/handlers/load-model/index.d.ts +2 -2
  250. package/dist/server/rpc/handlers/load-model/index.js +2 -2
  251. package/dist/server/rpc/handlers/load-model/resolve.js +39 -8
  252. package/dist/server/rpc/handlers/load-model-delegated.d.ts +2 -2
  253. package/dist/server/rpc/handlers/load-model-delegated.js +15 -10
  254. package/dist/server/rpc/handlers/logging-stream.js +4 -4
  255. package/dist/server/rpc/handlers/ocr-stream.d.ts +3 -0
  256. package/dist/server/rpc/handlers/ocr-stream.js +39 -0
  257. package/dist/server/rpc/handlers/provideHandler/connection.js +12 -10
  258. package/dist/server/rpc/handlers/provideHandler/handler.js +18 -16
  259. package/dist/server/rpc/handlers/provideHandler/proxy.js +8 -6
  260. package/dist/server/rpc/handlers/rag.d.ts +2 -2
  261. package/dist/server/rpc/handlers/rag.js +107 -41
  262. package/dist/server/rpc/handlers/stopProvideHandler.js +3 -1
  263. package/dist/server/rpc/handlers/text-to-speech.js +1 -1
  264. package/dist/server/rpc/handlers/transcribe-stream.js +4 -2
  265. package/dist/server/rpc/handlers/translate.js +9 -16
  266. package/dist/server/rpc/handlers/unload-model.js +4 -2
  267. package/dist/server/utils/archive.d.ts +3 -0
  268. package/dist/server/utils/archive.js +171 -0
  269. package/dist/server/utils/audio/decoder.d.ts +2 -1
  270. package/dist/server/utils/audio/decoder.js +48 -11
  271. package/dist/server/utils/cache.d.ts +5 -5
  272. package/dist/server/utils/cache.js +13 -11
  273. package/dist/server/utils/config-transform.d.ts +3 -0
  274. package/dist/server/utils/config-transform.js +23 -0
  275. package/dist/server/utils/formatting.d.ts +13 -0
  276. package/dist/server/utils/formatting.js +26 -0
  277. package/dist/server/utils/gguf-tensor-extractor.d.ts +15 -0
  278. package/dist/server/utils/gguf-tensor-extractor.js +314 -0
  279. package/dist/server/utils/index.d.ts +4 -1
  280. package/dist/server/utils/index.js +4 -1
  281. package/dist/server/utils/shard-utils.d.ts +42 -16
  282. package/dist/server/utils/shard-utils.js +95 -7
  283. package/dist/server/worker.js +49 -19
  284. package/dist/utils/errors-base.d.ts +1 -1
  285. package/dist/utils/errors-base.js +2 -2
  286. package/dist/utils/errors-client.d.ts +24 -0
  287. package/dist/utils/errors-client.js +40 -0
  288. package/dist/utils/errors-server.d.ts +42 -0
  289. package/dist/utils/errors-server.js +71 -0
  290. package/dist/utils/mcp-adapter.d.ts +12 -0
  291. package/dist/utils/mcp-adapter.js +103 -0
  292. package/dist/utils/object.d.ts +2 -0
  293. package/dist/utils/object.js +3 -0
  294. package/dist/utils/tool-helpers.d.ts +10 -2
  295. package/dist/utils/tool-helpers.js +24 -11
  296. package/package.json +74 -36
  297. package/dist/client/api/set-config.d.ts +0 -7
  298. package/dist/client/api/set-config.js +0 -20
  299. package/dist/client/config-manager.d.ts +0 -4
  300. package/dist/client/config-manager.js +0 -8
  301. package/dist/client/rpc/bare-rpc-client.d.ts +0 -4
  302. package/dist/client/rpc/bare-rpc-client.js +0 -91
  303. package/dist/examples/llamacpp-file-logging.d.ts +0 -2
  304. package/dist/examples/rag/rag-hyperdb-workspaces.d.ts +0 -2
  305. package/dist/examples/rag/rag-hyperdb-workspaces.js +0 -106
  306. package/dist/examples/rag/rag-hyperdb.d.ts +0 -2
  307. package/dist/schemas/set-config.d.ts +0 -21
  308. package/dist/schemas/set-config.js +0 -14
  309. package/dist/server/bare/addons/llamacpp/handlers/embed.d.ts +0 -4
  310. package/dist/server/bare/addons/llamacpp/index.d.ts +0 -4
  311. package/dist/server/bare/addons/llamacpp/index.js +0 -3
  312. package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +0 -63
  313. package/dist/server/bare/rag-hyperdb/rag-manager.d.ts +0 -5
  314. package/dist/server/bare/rag-hyperdb/rag-manager.js +0 -64
  315. package/dist/server/rpc/handlers/load-model.js +0 -59
  316. package/dist/server/rpc/handlers/set-config.d.ts +0 -3
  317. package/dist/server/rpc/handlers/set-config.js +0 -18
  318. package/dist/server/utils/hash.d.ts +0 -5
  319. package/dist/server/utils/hash.js +0 -11
  320. /package/dist/server/bare/addons/{llamacpp → llamacpp-completion}/handlers/completion-stream.d.ts +0 -0
  321. /package/dist/server/bare/addons/{translation → nmtcpp-translation}/create-model.d.ts +0 -0
  322. /package/dist/server/bare/addons/{translation → nmtcpp-translation}/handlers/translate.d.ts +0 -0
  323. /package/dist/server/bare/addons/{translation → nmtcpp-translation}/index.d.ts +0 -0
  324. /package/dist/server/bare/addons/{translation → nmtcpp-translation}/index.js +0 -0
  325. /package/dist/server/bare/addons/{tts → onnx-tts}/create-model.d.ts +0 -0
  326. /package/dist/server/bare/addons/{tts → onnx-tts}/create-model.js +0 -0
  327. /package/dist/server/bare/addons/{tts → onnx-tts}/handlers/text-to-speech.d.ts +0 -0
  328. /package/dist/server/bare/addons/{tts → onnx-tts}/handlers/text-to-speech.js +0 -0
  329. /package/dist/server/bare/addons/{tts → onnx-tts}/index.d.ts +0 -0
  330. /package/dist/server/bare/addons/{tts → onnx-tts}/index.js +0 -0
  331. /package/dist/server/bare/addons/{whispercpp → whispercpp-transcription}/create-model.d.ts +0 -0
  332. /package/dist/server/bare/addons/{whispercpp → whispercpp-transcription}/handlers/transcribe-stream.d.ts +0 -0
  333. /package/dist/server/bare/addons/{whispercpp → whispercpp-transcription}/index.d.ts +0 -0
  334. /package/dist/server/bare/addons/{whispercpp → whispercpp-transcription}/index.js +0 -0
@@ -1,10 +1,17 @@
1
1
  import fs, { promises as fsPromises } from "bare-fs";
2
+ import path from "bare-path";
2
3
  import { Readable } from "bare-stream";
3
4
  import fetch from "bare-fetch";
4
5
  import { AbortController } from "bare-abort-controller";
5
- import { getModelsCacheDir, generateShortHash } from "../../../utils/index.js";
6
+ import { withTimeout } from "../../../../utils/withTimeout.js";
7
+ import { getModelsCacheDir, getShardedModelCacheDir, generateShortHash, detectShardedModel, parsePatternBasedShardUrl, extractTensorsFromShards, calculatePercentage, isArchiveUrl, extractAndValidateShardedArchive, validateShardedModelCache, checkAllShardsExist, generateShardFilenames, hasValidGGUFHeader, } from "../../../utils/index.js";
8
+ import { getSDKConfig } from "../../../bare/registry/config-registry.js";
6
9
  import { getActiveDownload, registerDownload, unregisterDownload, createHttpDownloadKey, shouldClearCache, clearClearCacheFlag, } from "./download-manager.js";
7
- import { DownloadCancelledError, HTTPError, NoResponseBodyError, ResponseBodyNotReadableError, } from "../../../../utils/errors-server.js";
10
+ import { DownloadCancelledError, HTTPError, NoResponseBodyError, PartialDownloadOfflineError, ResponseBodyNotReadableError, } from "../../../../utils/errors-server.js";
11
+ import { getServerLogger } from "../../../../logging/index.js";
12
+ const logger = getServerLogger();
13
+ const DEFAULT_CONCURRENCY = 3;
14
+ const DEFAULT_HTTP_CONNECTION_TIMEOUT_MS = 10_000;
8
15
  function extractFilenameFromUrl(url) {
9
16
  // Parse URL to get the filename from the path
10
17
  const urlParts = url.split("/");
@@ -18,28 +25,44 @@ async function validateCachedFile(modelPath, url, signal) {
18
25
  await fsPromises.access(modelPath);
19
26
  const localStats = await fsPromises.stat(modelPath);
20
27
  const localSize = localStats.size;
21
- // Get expected size from HEAD request
28
+ const config = getSDKConfig();
29
+ const connectionTimeout = config.httpConnectionTimeoutMs ?? DEFAULT_HTTP_CONNECTION_TIMEOUT_MS;
22
30
  let expectedSize = 0;
23
31
  try {
24
- const response = await fetch(url, {
32
+ const response = await withTimeout(fetch(url, {
25
33
  method: "HEAD",
26
34
  ...(signal && { signal }),
27
- });
35
+ }), connectionTimeout);
28
36
  expectedSize = parseInt(response.headers.get("content-length") || "0");
29
37
  }
30
- catch (error) {
31
- console.log(`⚠️ Could not get expected file size from HEAD request, will re-download: ${String(error)}`);
38
+ catch (headError) {
39
+ logger.warn(`⚠️ HEAD request failed: ${headError instanceof Error ? headError.message : String(headError)}`);
40
+ logger.info(`📴 Falling back to GGUF header validation...`);
41
+ const hasValidHeader = await hasValidGGUFHeader(modelPath);
42
+ if (hasValidHeader) {
43
+ logger.info(`✅ Offline - GGUF header valid, using cached file: ${modelPath}`);
44
+ return modelPath;
45
+ }
46
+ if (localSize > 0) {
47
+ logger.error(`❌ Offline with partial download (${localSize} bytes). Cannot resume without network.`);
48
+ throw new PartialDownloadOfflineError(url, localSize);
49
+ }
50
+ logger.warn(`⚠️ Offline and GGUF validation failed - file may be incomplete`);
32
51
  return null;
33
52
  }
34
53
  if (localSize !== expectedSize) {
35
- console.log(`📥 Cached file size mismatch. Expected: ${expectedSize}, Found: ${localSize}. Re-downloading...`);
54
+ logger.info(`📥 Cached file size mismatch. Expected: ${expectedSize}, Found: ${localSize}. Re-downloading...`);
36
55
  return null;
37
56
  }
38
- console.log(`✅ Using cached HTTP model: ${modelPath}`);
57
+ logger.info(`✅ Using cached HTTP model: ${modelPath}`);
39
58
  return modelPath;
40
59
  }
41
- catch {
42
- // File doesn't exist
60
+ catch (error) {
61
+ // Re-throw PartialDownloadOfflineError
62
+ if (error instanceof PartialDownloadOfflineError) {
63
+ throw error;
64
+ }
65
+ // File doesn't exist or other access error
43
66
  return null;
44
67
  }
45
68
  }
@@ -47,7 +70,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
47
70
  if (signal?.aborted) {
48
71
  throw new DownloadCancelledError();
49
72
  }
50
- console.log(`📥 Downloading model from HTTP: ${url}`);
73
+ logger.info(`📥 Downloading model from HTTP: ${url}`);
51
74
  // Check if file exists for resuming
52
75
  let startOffset = 0;
53
76
  let downloadedBytes = 0;
@@ -55,10 +78,10 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
55
78
  const existingStats = await fsPromises.stat(modelPath);
56
79
  startOffset = existingStats.size;
57
80
  downloadedBytes = startOffset;
58
- console.log(`📥 Resuming download from byte ${startOffset}`);
81
+ logger.info(`📥 Resuming download from byte ${startOffset}`);
59
82
  }
60
83
  catch {
61
- console.log(`📥 Starting fresh download`);
84
+ logger.info(`📥 Starting fresh download`);
62
85
  }
63
86
  // Prepare headers for resume if needed
64
87
  const headers = {
@@ -67,17 +90,30 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
67
90
  if (startOffset > 0) {
68
91
  headers["Range"] = `bytes=${startOffset}-`;
69
92
  }
70
- // Make the fetch request
71
- const response = await fetch(url, {
72
- method: "GET",
73
- headers,
74
- ...(signal && { signal }),
75
- // bare-fetch automatically follows redirects
76
- });
93
+ const config = getSDKConfig();
94
+ const connectionTimeout = config.httpConnectionTimeoutMs ?? DEFAULT_HTTP_CONNECTION_TIMEOUT_MS;
95
+ let response;
96
+ try {
97
+ response = await withTimeout(fetch(url, {
98
+ method: "GET",
99
+ headers,
100
+ ...(signal && { signal }),
101
+ }), connectionTimeout);
102
+ }
103
+ catch (error) {
104
+ // Check if it was parent abort
105
+ if (signal?.aborted) {
106
+ throw new DownloadCancelledError();
107
+ }
108
+ // Connection timeout or network error
109
+ const errorMsg = error instanceof Error ? error.message : String(error);
110
+ logger.error(`❌ Connection failed: ${errorMsg}. URL: ${url}`);
111
+ throw new HTTPError(0, `Connection failed: ${errorMsg}`, error);
112
+ }
77
113
  if (!response.ok) {
78
114
  // Check if it's a 416 (Range Not Satisfiable) - file already complete
79
115
  if (response.status === 416 && startOffset > 0) {
80
- console.log(`✅ File already completely downloaded`);
116
+ logger.info(`✅ File already completely downloaded`);
81
117
  // Send 100% progress for already complete file
82
118
  if (progressCallback) {
83
119
  progressCallback({
@@ -92,22 +128,20 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
92
128
  }
93
129
  // Check if server doesn't support range requests
94
130
  if (response.status === 200 && startOffset > 0) {
95
- console.log(`⚠️ Server doesn't support resume, starting fresh download`);
131
+ logger.warn(`⚠️ Server doesn't support resume, starting fresh download`);
96
132
  startOffset = 0;
97
133
  downloadedBytes = 0;
98
134
  // Retry without Range header
99
- const freshResponse = await fetch(url, {
135
+ response = await fetch(url, {
100
136
  method: "GET",
101
137
  headers: {
102
- "User-Agent": "qvac-sdk/1.0",
138
+ "User-Agent": "qvac-sdk",
103
139
  },
104
140
  ...(signal && { signal }),
105
141
  });
106
- if (!freshResponse.ok) {
107
- throw new HTTPError(freshResponse.status, freshResponse.statusText);
142
+ if (!response.ok) {
143
+ throw new HTTPError(response.status, response.statusText);
108
144
  }
109
- // Use the fresh response
110
- Object.assign(response, freshResponse);
111
145
  }
112
146
  else if (response.status !== 206) {
113
147
  // 206 is Partial Content (successful resume)
@@ -131,7 +165,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
131
165
  // For fresh downloads
132
166
  totalBytes = contentLength ? parseInt(contentLength) : 0;
133
167
  }
134
- console.log(`📏 Total size: ${totalBytes} bytes (${(totalBytes / 1024 / 1024).toFixed(2)} MB)`);
168
+ logger.info(`📏 Total size: ${totalBytes} bytes (${(totalBytes / 1024 / 1024).toFixed(2)} MB)`);
135
169
  // Create write stream (append if resuming)
136
170
  const writeStreamOptions = startOffset > 0 && response.status === 206 ? { flags: "a" } : {};
137
171
  const writeStream = fs.createWriteStream(modelPath, writeStreamOptions);
@@ -154,7 +188,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
154
188
  type: "modelProgress",
155
189
  downloaded: downloadedBytes,
156
190
  total: totalBytes,
157
- percentage: totalBytes > 0 ? (downloadedBytes / totalBytes) * 100 : 0,
191
+ percentage: calculatePercentage(downloadedBytes, totalBytes),
158
192
  downloadKey,
159
193
  });
160
194
  }
@@ -174,7 +208,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
174
208
  signal.addEventListener("abort", abortHandler);
175
209
  }
176
210
  writeStream.on("finish", () => {
177
- console.log(`✅ Model downloaded successfully to ${modelPath}`);
211
+ logger.info(`✅ Model downloaded successfully to ${modelPath}`);
178
212
  if (signal) {
179
213
  signal.removeEventListener("abort", abortHandler);
180
214
  }
@@ -199,7 +233,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
199
233
  type: "modelProgress",
200
234
  downloaded: downloadedBytes,
201
235
  total: totalBytes,
202
- percentage: totalBytes > 0 ? (downloadedBytes / totalBytes) * 100 : 0,
236
+ percentage: calculatePercentage(downloadedBytes, totalBytes),
203
237
  downloadKey,
204
238
  });
205
239
  }
@@ -216,7 +250,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
216
250
  // Close the write stream
217
251
  await new Promise((resolve, reject) => {
218
252
  writeStream.end(() => {
219
- console.log(`✅ Model downloaded successfully to ${modelPath}`);
253
+ logger.info(`✅ Model downloaded successfully to ${modelPath}`);
220
254
  resolve();
221
255
  });
222
256
  writeStream.on("error", reject);
@@ -241,7 +275,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
241
275
  type: "modelProgress",
242
276
  downloaded: downloadedBytes,
243
277
  total: totalBytes,
244
- percentage: totalBytes > 0 ? (downloadedBytes / totalBytes) * 100 : 0,
278
+ percentage: calculatePercentage(downloadedBytes, totalBytes),
245
279
  downloadKey,
246
280
  });
247
281
  }
@@ -262,7 +296,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
262
296
  // Close the write stream
263
297
  await new Promise((resolve, reject) => {
264
298
  writeStream.end(() => {
265
- console.log(`✅ Model downloaded successfully to ${modelPath}`);
299
+ logger.info(`✅ Model downloaded successfully to ${modelPath}`);
266
300
  resolve();
267
301
  });
268
302
  writeStream.on("error", reject);
@@ -275,21 +309,27 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
275
309
  }
276
310
  catch (error) {
277
311
  writeStream.destroy();
278
- console.error("Error during download:", error instanceof Error ? error.message : String(error));
312
+ logger.error("Error during download:", error instanceof Error ? error.message : String(error));
279
313
  throw error instanceof Error ? error : new Error(String(error));
280
314
  }
281
315
  }
282
316
  export async function downloadModelFromHttp(url, progressCallback) {
317
+ const filename = extractFilenameFromUrl(url);
318
+ if (isArchiveUrl(url)) {
319
+ return downloadShardedModelFromArchive(url, progressCallback);
320
+ }
321
+ const shardInfo = detectShardedModel(filename);
322
+ if (shardInfo.isSharded && shardInfo.totalShards) {
323
+ return downloadShardedModelFromHttp(url, progressCallback);
324
+ }
283
325
  const downloadKey = createHttpDownloadKey(url);
284
- // Check if already downloading
285
326
  const existing = getActiveDownload(downloadKey);
286
327
  if (existing) {
287
- console.log(`📥 Reusing existing download for: ${downloadKey}`);
328
+ logger.info(`📥 Reusing existing download for: ${downloadKey}`);
288
329
  return existing.promise;
289
330
  }
290
331
  const cacheDir = getModelsCacheDir();
291
332
  const sourceHash = generateShortHash(url);
292
- const filename = extractFilenameFromUrl(url);
293
333
  const modelPath = `${cacheDir}/${sourceHash}_${filename}`;
294
334
  // Create managed download with AbortController
295
335
  const abortController = new AbortController();
@@ -309,8 +349,11 @@ export async function downloadModelFromHttp(url, progressCallback) {
309
349
  downloadKey,
310
350
  });
311
351
  }
312
- catch {
313
- // Ignore stat errors, file exists but might not be readable
352
+ catch (error) {
353
+ logger.debug("Failed to get file stats for progress callback", {
354
+ path: cachedPath,
355
+ error,
356
+ });
314
357
  }
315
358
  }
316
359
  return cachedPath;
@@ -329,28 +372,34 @@ export async function downloadModelFromHttp(url, progressCallback) {
329
372
  downloadKey,
330
373
  });
331
374
  }
332
- catch {
333
- // Ignore stat errors
375
+ catch (error) {
376
+ logger.debug("Failed to get file stats for final progress update", {
377
+ path: modelPath,
378
+ error,
379
+ });
334
380
  }
335
381
  }
336
382
  return modelPath;
337
383
  }
338
384
  catch (error) {
339
- console.error("❌ Error downloading model:", error instanceof Error ? error.message : String(error));
385
+ logger.error("❌ Error downloading model:", error instanceof Error ? error.message : String(error));
340
386
  // Check if we should delete the partial file (clearCache was requested)
341
387
  if (error instanceof Error && error.message === "Download cancelled") {
342
388
  if (shouldClearCache(downloadKey)) {
343
- console.log("🗑️ Clearing cache - deleting partial file");
389
+ logger.info("🗑️ Clearing cache - deleting partial file");
344
390
  try {
345
391
  await fsPromises.unlink(modelPath);
346
- console.log(`✅ Deleted partial file: ${modelPath}`);
392
+ logger.info(`✅ Deleted partial file: ${modelPath}`);
347
393
  }
348
- catch {
349
- // Ignore cleanup errors
394
+ catch (error) {
395
+ logger.debug("Failed to delete partial file during cleanup", {
396
+ path: modelPath,
397
+ error,
398
+ });
350
399
  }
351
400
  }
352
401
  else {
353
- console.log("📥 Download paused - partial file preserved for resume");
402
+ logger.info("📥 Download paused - partial file preserved for resume");
354
403
  }
355
404
  clearClearCacheFlag(downloadKey);
356
405
  }
@@ -376,3 +425,265 @@ export async function downloadModelFromHttp(url, progressCallback) {
376
425
  registerDownload(downloadKey, downloadEntry);
377
426
  return downloadPromise;
378
427
  }
428
+ async function downloadShardedModelFromHttp(shardUrl, progressCallback) {
429
+ const config = getSDKConfig();
430
+ const concurrency = config.httpDownloadConcurrency ?? DEFAULT_CONCURRENCY;
431
+ const { shardUrls: shardInfos, cacheKey } = parsePatternBasedShardUrl(shardUrl);
432
+ const downloadKey = `http-sharded:${cacheKey}`;
433
+ logger.info(`📥 HTTP sharded download: ${shardInfos.length} shards detected from ${shardUrl}`);
434
+ const existing = getActiveDownload(downloadKey);
435
+ if (existing) {
436
+ logger.info(`📥 Reusing existing sharded download for: ${downloadKey}`);
437
+ return existing.promise;
438
+ }
439
+ const abortController = new AbortController();
440
+ const shardDir = getShardedModelCacheDir(cacheKey);
441
+ const downloadPromise = (async () => {
442
+ try {
443
+ const shardStates = await Promise.all(shardInfos.map(async (shard, index) => {
444
+ const shardPath = path.join(shardDir, shard.filename);
445
+ let expectedSize = 0;
446
+ try {
447
+ const response = await fetch(shard.url, {
448
+ method: "HEAD",
449
+ signal: abortController.signal,
450
+ });
451
+ expectedSize = parseInt(response.headers.get("content-length") || "0");
452
+ }
453
+ catch (error) {
454
+ logger.warn("Failed to get shard size via HEAD request", {
455
+ url: shard.url,
456
+ error,
457
+ });
458
+ // expectedSize remains 0, progress percentage will be 0
459
+ }
460
+ return {
461
+ index,
462
+ shard,
463
+ shardPath,
464
+ expectedSize,
465
+ downloadedBytes: 0,
466
+ isComplete: false,
467
+ };
468
+ }));
469
+ const overallTotal = shardStates.reduce((sum, s) => sum + s.expectedSize, 0);
470
+ logger.info(`📏 Total size: ${overallTotal} bytes (${(overallTotal / 1024 / 1024).toFixed(2)} MB)`);
471
+ const cacheChecks = await Promise.all(shardStates.map(async (state) => {
472
+ const cached = await validateCachedFile(state.shardPath, state.shard.url, abortController.signal);
473
+ return { state, isCached: cached !== null };
474
+ }));
475
+ const shardsToDownload = cacheChecks
476
+ .filter((c) => !c.isCached)
477
+ .map((c) => c.state);
478
+ for (const check of cacheChecks) {
479
+ if (check.isCached) {
480
+ check.state.isComplete = true;
481
+ check.state.downloadedBytes = check.state.expectedSize;
482
+ }
483
+ }
484
+ logger.info(`📥 ${shardsToDownload.length} of ${shardInfos.length} shards need downloading`);
485
+ await downloadShardsWithConcurrency(shardsToDownload, shardStates, concurrency, abortController.signal, downloadKey, overallTotal, progressCallback);
486
+ logger.info(`✅ All ${shardInfos.length} shards downloaded successfully`);
487
+ await extractTensorsFromShards(shardDir, shardInfos[0].filename);
488
+ return path.join(shardDir, shardInfos[0].filename);
489
+ }
490
+ catch (error) {
491
+ logger.error("❌ Error during sharded download:", error instanceof Error ? error.message : String(error));
492
+ if (error instanceof Error && error.message === "Download cancelled") {
493
+ if (shouldClearCache(downloadKey)) {
494
+ logger.info("🗑️ Clearing cache - deleting partial shard files");
495
+ try {
496
+ await fsPromises.rm(shardDir, { recursive: true, force: true });
497
+ logger.info(`✅ Deleted shard directory: ${shardDir}`);
498
+ }
499
+ catch (cleanupError) {
500
+ logger.debug("Failed to delete shard directory during cleanup", {
501
+ path: shardDir,
502
+ error: cleanupError,
503
+ });
504
+ }
505
+ }
506
+ }
507
+ throw error;
508
+ }
509
+ finally {
510
+ unregisterDownload(downloadKey);
511
+ clearClearCacheFlag(downloadKey);
512
+ }
513
+ })();
514
+ registerDownload(downloadKey, {
515
+ key: downloadKey,
516
+ promise: downloadPromise,
517
+ abortController,
518
+ startTime: Date.now(),
519
+ type: "http",
520
+ url: shardUrl,
521
+ modelPath: shardDir,
522
+ });
523
+ return downloadPromise;
524
+ }
525
+ async function downloadShardedModelFromArchive(archiveUrl, progressCallback) {
526
+ const filename = extractFilenameFromUrl(archiveUrl);
527
+ const sourceHash = generateShortHash(archiveUrl);
528
+ const downloadKey = `http-archive:${sourceHash}`;
529
+ logger.info(`📦 HTTP archive download: ${filename}`);
530
+ const existing = getActiveDownload(downloadKey);
531
+ if (existing) {
532
+ logger.info(`📥 Reusing existing archive download for: ${downloadKey}`);
533
+ return existing.promise;
534
+ }
535
+ const abortController = new AbortController();
536
+ const extractDir = getShardedModelCacheDir(sourceHash);
537
+ const archivePath = path.join(extractDir, `${sourceHash}_${filename}`);
538
+ const downloadPromise = (async () => {
539
+ try {
540
+ await fsPromises.mkdir(extractDir, { recursive: true });
541
+ const files = await fsPromises.readdir(extractDir);
542
+ const shardedFile = files.find((f) => detectShardedModel(String(f)).isSharded);
543
+ if (!shardedFile) {
544
+ return downloadAndExtractArchive();
545
+ }
546
+ const shardFilename = String(shardedFile);
547
+ const allShardsExist = await checkAllShardsExist(extractDir, shardFilename);
548
+ if (!allShardsExist) {
549
+ logger.warn(`⚠️ Incomplete shards found, re-downloading archive`);
550
+ return downloadAndExtractArchive();
551
+ }
552
+ const shardFilenames = generateShardFilenames(shardFilename);
553
+ const firstShard = path.join(extractDir, shardFilenames[0]);
554
+ const isComplete = await validateShardedModelCache(extractDir, shardFilename);
555
+ if (isComplete) {
556
+ logger.info(`✅ Archive already extracted: ${extractDir}`);
557
+ if (progressCallback) {
558
+ progressCallback({
559
+ type: "modelProgress",
560
+ downloaded: 1,
561
+ total: 1,
562
+ percentage: 100,
563
+ downloadKey,
564
+ });
565
+ }
566
+ return firstShard;
567
+ }
568
+ logger.info(`📝 All shards present but tensors.txt missing, extracting tensors...`);
569
+ try {
570
+ await extractTensorsFromShards(extractDir, shardFilename);
571
+ logger.info(`✅ Tensors extracted successfully`);
572
+ if (progressCallback) {
573
+ progressCallback({
574
+ type: "modelProgress",
575
+ downloaded: 1,
576
+ total: 1,
577
+ percentage: 100,
578
+ downloadKey,
579
+ });
580
+ }
581
+ return firstShard;
582
+ }
583
+ catch (error) {
584
+ logger.warn(`Failed to extract tensors, will re-download archive`, {
585
+ error,
586
+ });
587
+ return downloadAndExtractArchive();
588
+ }
589
+ }
590
+ catch (error) {
591
+ logger.error("❌ Error downloading/extracting archive:", error);
592
+ throw error;
593
+ }
594
+ finally {
595
+ unregisterDownload(downloadKey);
596
+ }
597
+ async function downloadAndExtractArchive() {
598
+ await performHttpDownload(archiveUrl, archivePath, downloadKey, progressCallback, abortController.signal);
599
+ logger.info(`✅ Archive downloaded, extracting to: ${extractDir}`);
600
+ const firstShardPath = await extractAndValidateShardedArchive(archivePath, extractDir, abortController.signal);
601
+ try {
602
+ await fsPromises.unlink(archivePath);
603
+ logger.info(`🗑️ Cleaned up archive file: ${archivePath}`);
604
+ }
605
+ catch (cleanupError) {
606
+ logger.debug("Failed to delete archive file during cleanup", {
607
+ path: archivePath,
608
+ error: cleanupError,
609
+ });
610
+ }
611
+ return firstShardPath;
612
+ }
613
+ })();
614
+ registerDownload(downloadKey, {
615
+ key: downloadKey,
616
+ promise: downloadPromise,
617
+ abortController,
618
+ startTime: Date.now(),
619
+ type: "http",
620
+ url: archiveUrl,
621
+ modelPath: archivePath,
622
+ });
623
+ return downloadPromise;
624
+ }
625
+ async function downloadShardsWithConcurrency(shardsToDownload, allShards, concurrency, signal, downloadKey, overallTotal, progressCallback) {
626
+ const queue = [...shardsToDownload];
627
+ const inFlight = new Set();
628
+ while (queue.length > 0 || inFlight.size > 0) {
629
+ if (signal.aborted) {
630
+ throw new DownloadCancelledError();
631
+ }
632
+ while (queue.length > 0 && inFlight.size < concurrency) {
633
+ const state = queue.shift();
634
+ const downloadPromise = (async () => {
635
+ logger.info(`📥 Downloading shard ${state.index + 1}: ${state.shard.filename}`);
636
+ await performHttpDownload(state.shard.url, state.shardPath, downloadKey, (progress) => {
637
+ state.downloadedBytes = progress.downloaded;
638
+ if (progressCallback) {
639
+ const overallDownloaded = allShards.reduce((sum, s) => sum + s.downloadedBytes, 0);
640
+ progressCallback({
641
+ type: "modelProgress",
642
+ downloaded: state.downloadedBytes,
643
+ total: state.expectedSize,
644
+ percentage: calculatePercentage(state.downloadedBytes, state.expectedSize),
645
+ downloadKey,
646
+ shardInfo: {
647
+ currentShard: state.index + 1,
648
+ totalShards: allShards.length,
649
+ shardName: state.shard.filename,
650
+ overallDownloaded,
651
+ overallTotal,
652
+ overallPercentage: calculatePercentage(overallDownloaded, overallTotal),
653
+ },
654
+ });
655
+ }
656
+ }, signal);
657
+ logger.info(`✅ Shard ${state.index + 1} complete: ${state.shard.filename}`);
658
+ })().finally(() => {
659
+ inFlight.delete(downloadPromise);
660
+ });
661
+ inFlight.add(downloadPromise);
662
+ }
663
+ if (inFlight.size > 0) {
664
+ await Promise.race(inFlight);
665
+ }
666
+ }
667
+ // Mark all downloaded shards as complete
668
+ for (const state of shardsToDownload) {
669
+ state.isComplete = true;
670
+ state.downloadedBytes = state.expectedSize;
671
+ }
672
+ if (progressCallback) {
673
+ progressCallback({
674
+ type: "modelProgress",
675
+ downloaded: overallTotal,
676
+ total: overallTotal,
677
+ percentage: 100,
678
+ downloadKey,
679
+ shardInfo: {
680
+ currentShard: allShards.length,
681
+ totalShards: allShards.length,
682
+ shardName: allShards[allShards.length - 1].shard.filename,
683
+ overallDownloaded: overallTotal,
684
+ overallTotal,
685
+ overallPercentage: 100,
686
+ },
687
+ });
688
+ }
689
+ }