@mlx-bun/inference 0.0.0-stage → 1.0.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 (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1475 -2
  3. package/THIRD_PARTY_NOTICES.md +3404 -0
  4. package/dist/native/libmlx_bun_ane.dylib +0 -0
  5. package/dist/native/libmlx_bun_expert_io.dylib +0 -0
  6. package/dist/native/mlx-bun-frame-extract +0 -0
  7. package/examples/fit-model.ts +25 -0
  8. package/examples/qwen3-forward.ts +42 -0
  9. package/examples/qwen3-generate.ts +28 -0
  10. package/examples/trellis-expand.ts +23 -0
  11. package/package.json +129 -4
  12. package/src/adapters/available.ts +110 -0
  13. package/src/adapters/index.ts +3 -0
  14. package/src/adapters/manager.ts +316 -0
  15. package/src/artifacts/auxiliary-files.ts +45 -0
  16. package/src/artifacts/config-dialects.ts +94 -0
  17. package/src/artifacts/config.ts +341 -0
  18. package/src/artifacts/draft-vocabulary.ts +30 -0
  19. package/src/artifacts/expert-offload-build.ts +75 -0
  20. package/src/artifacts/expert-offload.ts +89 -0
  21. package/src/artifacts/experts/index.ts +3 -0
  22. package/src/artifacts/experts/io.ts +386 -0
  23. package/src/artifacts/experts/residency.ts +1134 -0
  24. package/src/artifacts/experts/usage.ts +415 -0
  25. package/src/artifacts/fingerprint.ts +44 -0
  26. package/src/artifacts/glm52/container.ts +305 -0
  27. package/src/artifacts/glm52/expert-layout.ts +249 -0
  28. package/src/artifacts/glm52/index.ts +7 -0
  29. package/src/artifacts/glm52/kernel-layout.ts +124 -0
  30. package/src/artifacts/glm52/layout.ts +152 -0
  31. package/src/artifacts/glm52/memory.ts +500 -0
  32. package/src/artifacts/glm52/resident-weights.ts +135 -0
  33. package/src/artifacts/glm52/weights.ts +503 -0
  34. package/src/artifacts/glm52-config.ts +262 -0
  35. package/src/artifacts/identity.ts +94 -0
  36. package/src/artifacts/index.ts +15 -0
  37. package/src/artifacts/mmap.ts +90 -0
  38. package/src/artifacts/safetensors-writer.ts +249 -0
  39. package/src/artifacts/safetensors.ts +164 -0
  40. package/src/artifacts/turboquant-fold.ts +42 -0
  41. package/src/artifacts/weight-audit.ts +43 -0
  42. package/src/artifacts/weights.ts +255 -0
  43. package/src/contracts/index.ts +2 -0
  44. package/src/contracts/mlx/attention.ts +8 -0
  45. package/src/contracts/mlx/cache.ts +510 -0
  46. package/src/contracts/mlx/checkpoint.ts +10 -0
  47. package/src/contracts/mlx/draft-checkpoint.ts +14 -0
  48. package/src/contracts/mlx/draft-projection.ts +27 -0
  49. package/src/contracts/mlx/draft-target.ts +84 -0
  50. package/src/contracts/mlx/drafter.ts +176 -0
  51. package/src/contracts/mlx/forward-work.ts +23 -0
  52. package/src/contracts/mlx/glm52-weights.ts +25 -0
  53. package/src/contracts/mlx/graph.ts +309 -0
  54. package/src/contracts/mlx/head.ts +6 -0
  55. package/src/contracts/mlx/index.ts +15 -0
  56. package/src/contracts/mlx/kv-codec.ts +9 -0
  57. package/src/contracts/mlx/media.ts +113 -0
  58. package/src/contracts/mlx/positions.ts +16 -0
  59. package/src/contracts/mlx/row-table.ts +2 -0
  60. package/src/contracts/mlx/trainable.ts +103 -0
  61. package/src/contracts/mlx/whisper.ts +96 -0
  62. package/src/contracts/portable/composition.ts +106 -0
  63. package/src/contracts/portable/denoising.ts +17 -0
  64. package/src/contracts/portable/execution.ts +79 -0
  65. package/src/contracts/portable/generation.ts +103 -0
  66. package/src/contracts/portable/graph.ts +80 -0
  67. package/src/contracts/portable/index.ts +15 -0
  68. package/src/contracts/portable/memory-plan.ts +26 -0
  69. package/src/contracts/portable/object-cache.ts +8 -0
  70. package/src/contracts/portable/prefill.ts +63 -0
  71. package/src/contracts/portable/prefix-cache.ts +33 -0
  72. package/src/contracts/portable/prompt.ts +2 -0
  73. package/src/contracts/portable/resources.ts +25 -0
  74. package/src/contracts/portable/rollback.ts +7 -0
  75. package/src/contracts/portable/sampling.ts +44 -0
  76. package/src/contracts/portable/scheduling.ts +54 -0
  77. package/src/contracts/portable/token-delivery.ts +4 -0
  78. package/src/contracts/portable/tsconfig.json +14 -0
  79. package/src/embeddings/index.ts +1 -0
  80. package/src/embeddings/text.ts +85 -0
  81. package/src/execution/admission.ts +59 -0
  82. package/src/execution/batch-group.ts +1240 -0
  83. package/src/execution/batch-types.ts +225 -0
  84. package/src/execution/cancellation.ts +38 -0
  85. package/src/execution/continuation-request.ts +45 -0
  86. package/src/execution/continuation-types.ts +10 -0
  87. package/src/execution/coordinator.ts +70 -0
  88. package/src/execution/denoising-group.ts +180 -0
  89. package/src/execution/engine.ts +56 -0
  90. package/src/execution/fill-group.ts +505 -0
  91. package/src/execution/fit.ts +184 -0
  92. package/src/execution/gateway-binding.ts +178 -0
  93. package/src/execution/grammar-group.ts +224 -0
  94. package/src/execution/index.ts +18 -0
  95. package/src/execution/methods.ts +75 -0
  96. package/src/execution/mixed-iteration.ts +96 -0
  97. package/src/execution/plan.ts +65 -0
  98. package/src/execution/prefill-cohort.ts +100 -0
  99. package/src/execution/prefill-rows.ts +263 -0
  100. package/src/execution/request-policy.ts +19 -0
  101. package/src/execution/row-sampling.ts +49 -0
  102. package/src/execution/scheduler.ts +92 -0
  103. package/src/execution/session.ts +247 -0
  104. package/src/execution/speculative-group.ts +797 -0
  105. package/src/execution/tasks.ts +44 -0
  106. package/src/generation/autoregressive.ts +840 -0
  107. package/src/generation/bindings/autoregressive.ts +104 -0
  108. package/src/generation/bindings/denoising.ts +60 -0
  109. package/src/generation/bindings/prefill-policy.ts +36 -0
  110. package/src/generation/checkpoint-identity.ts +60 -0
  111. package/src/generation/denoising.ts +85 -0
  112. package/src/generation/diffusion.ts +583 -0
  113. package/src/generation/fill/echo-index.ts +188 -0
  114. package/src/generation/fill/index.ts +3 -0
  115. package/src/generation/fill/proposal.ts +69 -0
  116. package/src/generation/fill/schema-rows.ts +506 -0
  117. package/src/generation/fill/session.ts +464 -0
  118. package/src/generation/fill/tool-boundary.ts +103 -0
  119. package/src/generation/fill-append.ts +58 -0
  120. package/src/generation/generate.ts +44 -0
  121. package/src/generation/grammar-step.ts +39 -0
  122. package/src/generation/index.ts +14 -0
  123. package/src/generation/phase-dispatch.ts +115 -0
  124. package/src/generation/prefill.ts +33 -0
  125. package/src/generation/result.ts +49 -0
  126. package/src/generation/scopes.ts +157 -0
  127. package/src/generation/speculative/acceptance.ts +41 -0
  128. package/src/generation/speculative/adaptive-draft-gate.ts +166 -0
  129. package/src/generation/speculative/bindings/assistant-rows.ts +102 -0
  130. package/src/generation/speculative/bindings/autoregressive-rows.ts +124 -0
  131. package/src/generation/speculative/bindings/binding.ts +106 -0
  132. package/src/generation/speculative/bindings/deepspec-rows.ts +33 -0
  133. package/src/generation/speculative/bindings/draft-target.ts +10 -0
  134. package/src/generation/speculative/bindings/glm52-mtp-rows.ts +128 -0
  135. package/src/generation/speculative/bindings/projected-context-rows.ts +78 -0
  136. package/src/generation/speculative/bindings/projected-draft-rows.ts +95 -0
  137. package/src/generation/speculative/bindings/qwen-mtp-rows.ts +336 -0
  138. package/src/generation/speculative/bindings/two-model-rows.ts +63 -0
  139. package/src/generation/speculative/cache-identity.ts +16 -0
  140. package/src/generation/speculative/draft-kind.ts +149 -0
  141. package/src/generation/speculative/draft-policy.ts +41 -0
  142. package/src/generation/speculative/draft-registry.ts +118 -0
  143. package/src/generation/speculative/draft-vocab.ts +110 -0
  144. package/src/generation/speculative/index.ts +17 -0
  145. package/src/generation/speculative/output.ts +49 -0
  146. package/src/generation/speculative/round.ts +307 -0
  147. package/src/generation/speculative/source.ts +144 -0
  148. package/src/generation/speculative/sources/assistant-source.ts +64 -0
  149. package/src/generation/speculative/sources/deepspec-source.ts +70 -0
  150. package/src/generation/speculative/sources/dflash-source.ts +84 -0
  151. package/src/generation/speculative/sources/dflash2-source.ts +86 -0
  152. package/src/generation/speculative/sources/glm52-mtp-source.ts +66 -0
  153. package/src/generation/speculative/sources/ngram-source.ts +165 -0
  154. package/src/generation/speculative/sources/qwen-mtp-source.ts +154 -0
  155. package/src/generation/speculative/sources/two-model.ts +75 -0
  156. package/src/generation/types.ts +194 -0
  157. package/src/index.ts +20 -0
  158. package/src/input/audio/audiotoolbox.ts +112 -0
  159. package/src/input/audio/decode.ts +133 -0
  160. package/src/input/audio/features.ts +202 -0
  161. package/src/input/audio/index.ts +6 -0
  162. package/src/input/audio/transcode.ts +67 -0
  163. package/src/input/audio/whisper-mel.ts +185 -0
  164. package/src/input/audio/whisper-tokenizer.ts +238 -0
  165. package/src/input/chat-template.ts +389 -0
  166. package/src/input/index.ts +6 -0
  167. package/src/input/media-fetch.ts +439 -0
  168. package/src/input/packed-mixed.ts +43 -0
  169. package/src/input/special-tokens.ts +75 -0
  170. package/src/input/token-groups.ts +49 -0
  171. package/src/input/tokenizer.ts +336 -0
  172. package/src/input/tool-call.ts +689 -0
  173. package/src/input/vision/index.ts +3 -0
  174. package/src/input/vision/preprocess.ts +247 -0
  175. package/src/input/vision/prompt.ts +398 -0
  176. package/src/input/vision/qwen3vl-preprocess.ts +409 -0
  177. package/src/input/vision/qwen3vl-prompt.ts +237 -0
  178. package/src/input/vision/video-frames.ts +100 -0
  179. package/src/kernels/ane/fill.ts +101 -0
  180. package/src/kernels/ane/linear.ts +416 -0
  181. package/src/kernels/attention/flash.ts +694 -0
  182. package/src/kernels/attention/kvq4-decode.ts +155 -0
  183. package/src/kernels/attention/masks.ts +40 -0
  184. package/src/kernels/attention/multi-query.ts +193 -0
  185. package/src/kernels/attention/paged.ts +130 -0
  186. package/src/kernels/delta/gated.ts +306 -0
  187. package/src/kernels/delta/index.ts +3 -0
  188. package/src/kernels/delta/silu-rms-heads.ts +69 -0
  189. package/src/kernels/delta/state.ts +74 -0
  190. package/src/kernels/gated-rms-norm.ts +64 -0
  191. package/src/kernels/glm52/layout.ts +37 -0
  192. package/src/kernels/glm52/streamed-experts.ts +360 -0
  193. package/src/kernels/logits.ts +38 -0
  194. package/src/kernels/quantization/affine-row.ts +154 -0
  195. package/src/kernels/quantization/affine-rows.ts +36 -0
  196. package/src/kernels/quantization/affine-split-mma.ts +144 -0
  197. package/src/kernels/quantization/affine3-mma.ts +117 -0
  198. package/src/kernels/quantization/affine3-rows.ts +103 -0
  199. package/src/kernels/quantization/affine4-mma.ts +113 -0
  200. package/src/kernels/quantization/affine4-rows.ts +102 -0
  201. package/src/kernels/residual-rms-norm.ts +65 -0
  202. package/src/kernels/sampling/index.ts +2 -0
  203. package/src/kernels/sampling/normalized-argmax.ts +116 -0
  204. package/src/kernels/sampling/token-bitmask.ts +52 -0
  205. package/src/kernels/softcap.ts +35 -0
  206. package/src/kernels/trellis/codebook.ts +123 -0
  207. package/src/kernels/trellis/down-codebook.ts +184 -0
  208. package/src/kernels/trellis/down-factored.ts +180 -0
  209. package/src/kernels/trellis/down-k3-interleaved-factored.ts +146 -0
  210. package/src/kernels/trellis/down-mma-wide.ts +195 -0
  211. package/src/kernels/trellis/down-mma.ts +145 -0
  212. package/src/kernels/trellis/expand.ts +42 -0
  213. package/src/kernels/trellis/gate-up-codebook-mma.ts +141 -0
  214. package/src/kernels/trellis/gate-up-codebook.ts +137 -0
  215. package/src/kernels/trellis/gate-up-factored.ts +197 -0
  216. package/src/kernels/trellis/gate-up-mma-wide.ts +147 -0
  217. package/src/kernels/trellis/gate-up-mma.ts +148 -0
  218. package/src/kernels/trellis/gate-up.ts +248 -0
  219. package/src/kernels/trellis/geometry.ts +22 -0
  220. package/src/kernels/trellis/index.ts +103 -0
  221. package/src/kernels/trellis/launch.ts +12 -0
  222. package/src/kernels/trellis/mixed-gate-up-factored.ts +119 -0
  223. package/src/kernels/trellis/mixed-gate-up.ts +146 -0
  224. package/src/kernels/trellis/qualified.ts +34 -0
  225. package/src/kernels/trellis/reduce.ts +150 -0
  226. package/src/kernels/trellis/scatter.ts +407 -0
  227. package/src/kernels/trellis/splitk-prefill.ts +152 -0
  228. package/src/kernels/trellis/tiled-prefill.ts +131 -0
  229. package/src/kernels/trellis/vector-expand.ts +58 -0
  230. package/src/kernels/trellis/wide-prefill.ts +89 -0
  231. package/src/kernels/turboquant/decode.ts +82 -0
  232. package/src/kernels/turboquant/index.ts +5 -0
  233. package/src/kernels/turboquant/inverse.ts +122 -0
  234. package/src/kernels/turboquant/ops.ts +860 -0
  235. package/src/kernels/turboquant/signs.ts +130 -0
  236. package/src/kernels/turboquant/tables.ts +124 -0
  237. package/src/layers/affine-verify-linear.ts +75 -0
  238. package/src/layers/ane-prefill-split.ts +283 -0
  239. package/src/layers/compiled-normalization.ts +41 -0
  240. package/src/layers/delta-heads.ts +23 -0
  241. package/src/layers/dense-embedding.ts +29 -0
  242. package/src/layers/dense-linear.ts +32 -0
  243. package/src/layers/dequantized-linear.ts +72 -0
  244. package/src/layers/folded-attention.ts +42 -0
  245. package/src/layers/geglu.ts +130 -0
  246. package/src/layers/helpers.ts +7 -0
  247. package/src/layers/index.ts +36 -0
  248. package/src/layers/kv4-decode-attention.ts +15 -0
  249. package/src/layers/layer-norm.ts +24 -0
  250. package/src/layers/loading.ts +92 -0
  251. package/src/layers/lora.ts +150 -0
  252. package/src/layers/normalization.ts +9 -0
  253. package/src/layers/prefix-layout.ts +33 -0
  254. package/src/layers/quantized-append-attention.ts +32 -0
  255. package/src/layers/quantized-attention.ts +353 -0
  256. package/src/layers/quantized-embedding.ts +39 -0
  257. package/src/layers/quantized-linear.ts +137 -0
  258. package/src/layers/quantized-switch-linear.ts +37 -0
  259. package/src/layers/qwen-append.ts +12 -0
  260. package/src/layers/qwen-mrope.ts +238 -0
  261. package/src/layers/rope-2d.ts +110 -0
  262. package/src/layers/rope.ts +389 -0
  263. package/src/layers/swiglu.ts +23 -0
  264. package/src/layers/trellis-codebook-down.ts +52 -0
  265. package/src/layers/trellis-codebook-gate-up.ts +42 -0
  266. package/src/layers/trellis-down.ts +117 -0
  267. package/src/layers/trellis-gate-up.ts +71 -0
  268. package/src/layers/trellis-linear.ts +211 -0
  269. package/src/layers/trellis-prompt.ts +102 -0
  270. package/src/layers/trellis-reduce-gate-up.ts +73 -0
  271. package/src/layers/trellis-scatter-down.ts +98 -0
  272. package/src/models/ane-install.ts +74 -0
  273. package/src/models/audio/conformer.ts +656 -0
  274. package/src/models/cache-composition.ts +44 -0
  275. package/src/models/capabilities.ts +89 -0
  276. package/src/models/chat-template.ts +10 -0
  277. package/src/models/composition.ts +107 -0
  278. package/src/models/diffusion-gemma/experts.ts +59 -0
  279. package/src/models/diffusion-gemma/family.ts +21 -0
  280. package/src/models/diffusion-gemma/model.ts +900 -0
  281. package/src/models/diffusion-gemma/vision.ts +549 -0
  282. package/src/models/drafter-loaders.ts +49 -0
  283. package/src/models/drafters.ts +39 -0
  284. package/src/models/factory.ts +351 -0
  285. package/src/models/families.ts +70 -0
  286. package/src/models/family.ts +125 -0
  287. package/src/models/gemma4/assistant-target.ts +46 -0
  288. package/src/models/gemma4/assistant.ts +327 -0
  289. package/src/models/gemma4/blocks.ts +755 -0
  290. package/src/models/gemma4/compiled-decode.ts +452 -0
  291. package/src/models/gemma4/family.ts +39 -0
  292. package/src/models/gemma4/gemma4-12b.ts +677 -0
  293. package/src/models/gemma4/gemma4-26b.ts +544 -0
  294. package/src/models/gemma4/gemma4-e4b.ts +599 -0
  295. package/src/models/gemma4/graphs.ts +147 -0
  296. package/src/models/gemma4/media.ts +88 -0
  297. package/src/models/gemma4/model.ts +860 -0
  298. package/src/models/gemma4/serving-blocks.ts +72 -0
  299. package/src/models/gemma4/trainable.ts +186 -0
  300. package/src/models/gemma4/written-blocks.ts +232 -0
  301. package/src/models/gemma4/written-forward.ts +159 -0
  302. package/src/models/gemma4/written-input.ts +29 -0
  303. package/src/models/glm52/atlas.ts +507 -0
  304. package/src/models/glm52/coupling.ts +388 -0
  305. package/src/models/glm52/dsa.ts +601 -0
  306. package/src/models/glm52/family.ts +20 -0
  307. package/src/models/glm52/mla.ts +812 -0
  308. package/src/models/glm52/model.ts +1127 -0
  309. package/src/models/glm52/moe.ts +223 -0
  310. package/src/models/glm52/mtp.ts +60 -0
  311. package/src/models/glm52/pilot.ts +537 -0
  312. package/src/models/glm52/reference.ts +445 -0
  313. package/src/models/glm52/residency.ts +557 -0
  314. package/src/models/glm52/streamed-experts.ts +447 -0
  315. package/src/models/graph.ts +59 -0
  316. package/src/models/implementation.ts +230 -0
  317. package/src/models/index.ts +15 -0
  318. package/src/models/media-input.ts +15 -0
  319. package/src/models/memory-plan.ts +39 -0
  320. package/src/models/minicpm5/family.ts +29 -0
  321. package/src/models/minicpm5/model.ts +394 -0
  322. package/src/models/minicpm5/trainable.ts +90 -0
  323. package/src/models/profile.ts +337 -0
  324. package/src/models/qwen/blocks.ts +658 -0
  325. package/src/models/qwen/checkpoint.ts +190 -0
  326. package/src/models/qwen/families.ts +57 -0
  327. package/src/models/qwen/media-input.ts +161 -0
  328. package/src/models/qwen/mtp.ts +101 -0
  329. package/src/models/qwen/qwen3-moe.ts +355 -0
  330. package/src/models/qwen/qwen3.ts +323 -0
  331. package/src/models/qwen/qwen38-27b-trellis-m1max.ts +1532 -0
  332. package/src/models/qwen/qwen38-27b-trellis-m4pro.ts +1092 -0
  333. package/src/models/qwen/qwen3_5.ts +433 -0
  334. package/src/models/qwen/written-layers.ts +285 -0
  335. package/src/models/row-table.ts +1 -0
  336. package/src/models/runtime.ts +73 -0
  337. package/src/models/speculative/deepspec-artifact.ts +10 -0
  338. package/src/models/speculative/deepspec.ts +744 -0
  339. package/src/models/speculative/dflash.ts +553 -0
  340. package/src/models/speculative/dflash2-artifact.ts +9 -0
  341. package/src/models/speculative/dflash2-operations.ts +1 -0
  342. package/src/models/speculative/dflash2.ts +576 -0
  343. package/src/models/speculative/loader.ts +29 -0
  344. package/src/models/support.ts +79 -0
  345. package/src/models/universal/archs.ts +365 -0
  346. package/src/models/universal/blocks.ts +479 -0
  347. package/src/models/universal/dense.ts +255 -0
  348. package/src/models/universal/family.ts +17 -0
  349. package/src/models/vision/qwen3vl.ts +566 -0
  350. package/src/models/vision/siglip.ts +520 -0
  351. package/src/models/vision/unified.ts +176 -0
  352. package/src/models/whisper/family.ts +19 -0
  353. package/src/models/whisper/fast.ts +734 -0
  354. package/src/models/whisper/model.ts +430 -0
  355. package/src/runtime/compiled-trace.ts +16 -0
  356. package/src/runtime/config.ts +77 -0
  357. package/src/runtime/expert-trace.ts +71 -0
  358. package/src/runtime/graph-forward.ts +65 -0
  359. package/src/runtime/integers.ts +6 -0
  360. package/src/runtime/native.ts +16 -0
  361. package/src/runtime/resources.ts +53 -0
  362. package/src/runtime/row-operations.ts +42 -0
  363. package/src/runtime/trace.ts +161 -0
  364. package/src/sampling/curve.ts +122 -0
  365. package/src/sampling/draft.ts +55 -0
  366. package/src/sampling/extras.ts +45 -0
  367. package/src/sampling/filters.ts +134 -0
  368. package/src/sampling/grammar.ts +630 -0
  369. package/src/sampling/hlg.ts +290 -0
  370. package/src/sampling/index.ts +9 -0
  371. package/src/sampling/processors.ts +142 -0
  372. package/src/sampling/sampler.ts +120 -0
  373. package/src/sampling/step.ts +343 -0
  374. package/src/sampling/types.ts +161 -0
  375. package/src/sampling/window-filters.ts +46 -0
  376. package/src/scoring/decisions.ts +96 -0
  377. package/src/scoring/full-sequence.ts +103 -0
  378. package/src/scoring/index.ts +9 -0
  379. package/src/scoring/kl.ts +29 -0
  380. package/src/scoring/perplexity.ts +165 -0
  381. package/src/scoring/response-logps.ts +65 -0
  382. package/src/state/affine-attention.ts +180 -0
  383. package/src/state/attachment.ts +68 -0
  384. package/src/state/attention-read.ts +215 -0
  385. package/src/state/batched-kv.ts +294 -0
  386. package/src/state/batched-mask.ts +445 -0
  387. package/src/state/batched-quant.ts +389 -0
  388. package/src/state/batched-quantized-kv.ts +209 -0
  389. package/src/state/batched-rotating-quant.ts +457 -0
  390. package/src/state/batched-rotating-state.ts +149 -0
  391. package/src/state/batched-rotating.ts +430 -0
  392. package/src/state/batched-row-storage.ts +179 -0
  393. package/src/state/batched-ssm.ts +54 -0
  394. package/src/state/batched-turboquant-kv.ts +144 -0
  395. package/src/state/bf16-first-kv.ts +663 -0
  396. package/src/state/cache-service.ts +592 -0
  397. package/src/state/capabilities.ts +65 -0
  398. package/src/state/checkpoint.ts +46 -0
  399. package/src/state/continuation-persistence.ts +126 -0
  400. package/src/state/decode-step-inputs.ts +31 -0
  401. package/src/state/decoded-kv-donor.ts +12 -0
  402. package/src/state/delayed-quantized-kv.ts +141 -0
  403. package/src/state/delayed-rotating-quantized-kv.ts +178 -0
  404. package/src/state/delayed-turboquant-kv.ts +123 -0
  405. package/src/state/durability.ts +214 -0
  406. package/src/state/encoder-cache.ts +26 -0
  407. package/src/state/full-kv-row-append.ts +33 -0
  408. package/src/state/full-kv-row-donor.ts +54 -0
  409. package/src/state/full-prefill-padding.ts +56 -0
  410. package/src/state/full-prefill-row.ts +112 -0
  411. package/src/state/full-transitioning-kv-rows.ts +70 -0
  412. package/src/state/glm52-cache.ts +783 -0
  413. package/src/state/grouped-heads-kv4-cache.ts +26 -0
  414. package/src/state/index.ts +38 -0
  415. package/src/state/kv-attention-view.ts +77 -0
  416. package/src/state/kv-budget.ts +14 -0
  417. package/src/state/kv-scheme.ts +315 -0
  418. package/src/state/kv-storage.ts +57 -0
  419. package/src/state/kv-tensor-rows.ts +212 -0
  420. package/src/state/kv.ts +324 -0
  421. package/src/state/kv4-head256-cache.ts +46 -0
  422. package/src/state/latent-legos.ts +895 -0
  423. package/src/state/layout.ts +277 -0
  424. package/src/state/leases.ts +26 -0
  425. package/src/state/paged/cache.ts +689 -0
  426. package/src/state/paged/codec.ts +36 -0
  427. package/src/state/paged/rows.ts +223 -0
  428. package/src/state/persistence-types.ts +173 -0
  429. package/src/state/persistence-worker.ts +83 -0
  430. package/src/state/persistence.ts +1036 -0
  431. package/src/state/persistence.worker.d.ts +3 -0
  432. package/src/state/persistence.worker.js +264 -0
  433. package/src/state/prefix-cache.ts +685 -0
  434. package/src/state/quantized-kv.ts +369 -0
  435. package/src/state/quantized-tensor.ts +26 -0
  436. package/src/state/request-policy.ts +48 -0
  437. package/src/state/retention-policy.ts +37 -0
  438. package/src/state/rollback.ts +131 -0
  439. package/src/state/rotating-kv-donor.ts +35 -0
  440. package/src/state/rotating-kv-layout.ts +341 -0
  441. package/src/state/rotating-kv.ts +529 -0
  442. package/src/state/rotating-quantized-kv.ts +616 -0
  443. package/src/state/rotating-row-transaction.ts +35 -0
  444. package/src/state/rows.ts +104 -0
  445. package/src/state/softcap-attention.ts +118 -0
  446. package/src/state/speculative/glm52-mtp-state.ts +38 -0
  447. package/src/state/speculative/qwen-mtp-state.ts +34 -0
  448. package/src/state/speculative-rotating-kv.ts +113 -0
  449. package/src/state/ssd-cache.ts +434 -0
  450. package/src/state/ssm-prefill-padding.ts +39 -0
  451. package/src/state/ssm.ts +422 -0
  452. package/src/state/target-layout.ts +7 -0
  453. package/src/state/tiered-prefix-cache.ts +45 -0
  454. package/src/state/training-cache.ts +300 -0
  455. package/src/state/transitioning-kv-rows.ts +267 -0
  456. package/src/state/turboquant-attention.ts +97 -0
  457. package/src/state/turboquant-codec.ts +90 -0
  458. package/src/state/turboquant-kv.ts +442 -0
  459. package/src/state/views.ts +26 -0
  460. package/src/transcription/index.ts +3 -0
  461. package/src/transcription/silero-vad.ts +379 -0
  462. package/src/transcription/whisper/decode.ts +773 -0
  463. package/src/transcription/whisper/format.ts +74 -0
  464. package/src/transcription/whisper/index.ts +4 -0
  465. package/src/transcription/whisper/timing.ts +274 -0
  466. package/src/transcription/whisper/transcribe.ts +394 -0
  467. package/src/transcription/whisper/types.ts +22 -0
@@ -0,0 +1,389 @@
1
+ // Chat template rendering via @huggingface/jinja (pure JS, purpose-built
2
+ // for HF chat templates). Rendering the model's own chat_template.jinja beats a hand-port because
3
+ // it can't rot when the model updates its template.
4
+
5
+ import { Template } from "@huggingface/jinja";
6
+
7
+ export interface ToolCall {
8
+ id?: string;
9
+ type?: "function";
10
+ function: {
11
+ name: string;
12
+ /** Object form preferred; OpenAI's JSON-string form is normalized by
13
+ * the server before rendering. */
14
+ arguments: Record<string, unknown> | string;
15
+ };
16
+ }
17
+
18
+ export interface ChatMessage {
19
+ role: string;
20
+ content?: string | Array<Record<string, unknown>> | null;
21
+ tool_calls?: ToolCall[];
22
+ tool_call_id?: string;
23
+ name?: string;
24
+ reasoning?: string;
25
+ reasoning_content?: string;
26
+ }
27
+
28
+ /** OpenAI-style tool definition (function type). */
29
+ export interface ToolDefinition {
30
+ type: "function";
31
+ function: {
32
+ name: string;
33
+ description?: string;
34
+ parameters?: Record<string, unknown>;
35
+ };
36
+ }
37
+
38
+ export interface RenderOptions {
39
+ addGenerationPrompt?: boolean;
40
+ tools?: ToolDefinition[] | null;
41
+ enableThinking?: boolean;
42
+ /** Template-level reasoning depth (Qwen3.8: xhigh|medium|low — the template
43
+ * RAISES on other values, so callers must map OpenAI levels first and only
44
+ * set this for templates that read it; see ChatTemplate.readsReasoningEffort). */
45
+ reasoningEffort?: "xhigh" | "medium" | "low";
46
+ /** Keep think blocks from historical assistant turns in the rendered prompt
47
+ * (Qwen3.8 `preserve_thinking`, template default true — better prompt-cache
48
+ * reuse and agent-trace continuity). Only passed when the template reads it. */
49
+ preserveThinking?: boolean;
50
+ }
51
+
52
+ export type ChatRenderer = (
53
+ messages: ChatMessage[],
54
+ options: RenderOptions,
55
+ ) => string;
56
+
57
+ /** Reasoning markup a template's `enable_thinking` channel uses. */
58
+ export type ThinkingFormat = "think-tag" | "channel-tokens";
59
+
60
+ /** How to render chats for an artifact that ships no template source. */
61
+ export interface TemplateFallback {
62
+ readonly render: ChatRenderer;
63
+ readonly thinkingFormat: ThinkingFormat | null;
64
+ }
65
+
66
+ function glm52ContentText(content: ChatMessage["content"], label: string): string {
67
+ if (typeof content === "string") return content;
68
+ if (!Array.isArray(content))
69
+ throw new Error(`${label} must be a string or an array of text parts`);
70
+ return content.map((part, index) => {
71
+ if (
72
+ !part ||
73
+ (part.type !== "text" && part.type !== "input_text") ||
74
+ typeof part.text !== "string"
75
+ ) {
76
+ throw new Error(`${label}.${index}: GLM-5.2 supports text content only`);
77
+ }
78
+ return part.text;
79
+ }).join("");
80
+ }
81
+
82
+ /** Text/tool subset of the pinned GLM-5.2 template used by Colibri. */
83
+ export function renderGlm52Chat(
84
+ messages: ChatMessage[],
85
+ options: RenderOptions = {},
86
+ ): string {
87
+ if (!Array.isArray(messages) || messages.length === 0)
88
+ throw new Error("GLM-5.2 messages must be a non-empty array");
89
+ const {
90
+ addGenerationPrompt = true,
91
+ tools = null,
92
+ enableThinking = false,
93
+ } = options;
94
+ const prompt = ["[gMASK]<sop>"];
95
+ if (enableThinking)
96
+ prompt.push("<|system|>Reasoning Effort: Max");
97
+
98
+ const normalizedTools = normalizeToolSchemas(tools);
99
+ if (normalizedTools && normalizedTools.length > 0) {
100
+ prompt.push(
101
+ "<|system|>\n# Tools\n\nYou may call one or more functions to assist with the " +
102
+ "user query.\n\nYou are provided with function signatures within <tools></tools> " +
103
+ "XML tags:\n<tools>\n",
104
+ );
105
+ for (const tool of normalizedTools) {
106
+ const fn = { ...tool.function } as Record<string, unknown>;
107
+ delete fn.defer_loading;
108
+ delete fn.strict;
109
+ prompt.push(`${JSON.stringify(fn)}\n`);
110
+ }
111
+ prompt.push(
112
+ "</tools>\n\nFor each function call, output the function name and arguments " +
113
+ "within the following XML format:\n<tool_call>{function-name}" +
114
+ "<arg_key>{arg-key-1}</arg_key><arg_value>{arg-value-1}</arg_value>" +
115
+ "<arg_key>{arg-key-2}</arg_key><arg_value>{arg-value-2}</arg_value>...</tool_call>",
116
+ );
117
+ }
118
+
119
+ let previousWasTool = false;
120
+ for (let index = 0; index < messages.length; index++) {
121
+ const message = messages[index]!;
122
+ const role = message.role;
123
+ if (role === "system" || role === "developer") {
124
+ prompt.push(
125
+ `<|system|>${glm52ContentText(message.content, `messages.${index}.content`)}`,
126
+ );
127
+ } else if (role === "user") {
128
+ prompt.push(
129
+ `<|user|>${glm52ContentText(message.content, `messages.${index}.content`)}`,
130
+ );
131
+ } else if (role === "assistant") {
132
+ const content = message.content === null || message.content === undefined
133
+ ? ""
134
+ : glm52ContentText(message.content, `messages.${index}.content`);
135
+ prompt.push(`<|assistant|><think></think>${content.trim()}`);
136
+ for (const call of message.tool_calls ?? []) {
137
+ const raw = call.function.arguments;
138
+ let args: Record<string, unknown> = {};
139
+ if (typeof raw === "string") {
140
+ try {
141
+ const parsed = JSON.parse(raw);
142
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
143
+ args = parsed as Record<string, unknown>;
144
+ } catch {
145
+ // Match the pinned template path: malformed historical arguments
146
+ // contribute an empty call body rather than changing the prompt.
147
+ }
148
+ } else {
149
+ args = raw;
150
+ }
151
+ prompt.push(`<tool_call>${call.function.name}`);
152
+ for (const [key, value] of Object.entries(args)) {
153
+ prompt.push(
154
+ `<arg_key>${key}</arg_key><arg_value>` +
155
+ `${typeof value === "string" ? value : JSON.stringify(value)}</arg_value>`,
156
+ );
157
+ }
158
+ prompt.push("</tool_call>");
159
+ }
160
+ } else if (role === "tool") {
161
+ if (!previousWasTool) prompt.push("<|observation|>");
162
+ prompt.push(
163
+ `<tool_response>${glm52ContentText(message.content, `messages.${index}.content`)}` +
164
+ "</tool_response>",
165
+ );
166
+ } else {
167
+ throw new Error(`GLM-5.2 unsupported message role ${JSON.stringify(role)}`);
168
+ }
169
+ previousWasTool = role === "tool";
170
+ }
171
+ if (addGenerationPrompt) {
172
+ prompt.push(
173
+ enableThinking
174
+ ? "<|assistant|><think>"
175
+ : "<|assistant|><think></think>",
176
+ );
177
+ }
178
+ return prompt.join("");
179
+ }
180
+
181
+ /** JSON-schema type implied by a literal value. */
182
+ function jsonTypeOf(v: unknown): string {
183
+ if (typeof v === "number") return Number.isInteger(v) ? "integer" : "number";
184
+ if (typeof v === "boolean") return "boolean";
185
+ if (Array.isArray(v)) return "array";
186
+ if (v !== null && typeof v === "object") return "object";
187
+ return "string";
188
+ }
189
+
190
+ /** Infer a JSON-schema `type` for a node that lacks one (enum/const/anyOf/…). */
191
+ function inferSchemaType(node: Record<string, unknown>): string {
192
+ if (Array.isArray(node.enum) && node.enum.length > 0) return jsonTypeOf(node.enum[0]);
193
+ if ("const" in node) return jsonTypeOf(node.const);
194
+ if (node.properties || node.additionalProperties) return "object";
195
+ if (node.items !== undefined || node.prefixItems !== undefined) return "array";
196
+ for (const key of ["anyOf", "oneOf", "allOf"] as const) {
197
+ const subs = node[key];
198
+ if (Array.isArray(subs) && subs.length > 0) {
199
+ const types = subs
200
+ .map((s) => (s && typeof s === "object" ? (s as Record<string, unknown>).type : undefined))
201
+ .filter((t): t is string => typeof t === "string");
202
+ const first = types[0];
203
+ if (first !== undefined) return first;
204
+ }
205
+ }
206
+ return "string";
207
+ }
208
+
209
+ /**
210
+ * Recursively ensure every JSON-schema node carries a `type`.
211
+ *
212
+ * Why: HF chat templates (e.g. Gemma's tool-declaration block) do
213
+ * `value['type'] | upper`, which throws "Cannot apply filter upper to
214
+ * UndefinedValue" for schemas that describe a parameter via `anyOf`/`enum`/
215
+ * `const` without a top-level `type` (TypeBox unions/literals emit exactly
216
+ * this). We synthesize a sensible `type` so any tool renders, regardless of
217
+ * how its schema was authored. Returns a new object; never mutates input.
218
+ */
219
+ export function normalizeSchemaTypes(node: unknown): unknown {
220
+ if (Array.isArray(node)) return node.map(normalizeSchemaTypes);
221
+ if (!node || typeof node !== "object") return node;
222
+ const out: Record<string, unknown> = { ...(node as Record<string, unknown>) };
223
+ if (out.properties && typeof out.properties === "object") {
224
+ const props: Record<string, unknown> = {};
225
+ for (const [k, v] of Object.entries(out.properties as Record<string, unknown>)) props[k] = normalizeSchemaTypes(v);
226
+ out.properties = props;
227
+ }
228
+ if (out.items !== undefined) out.items = normalizeSchemaTypes(out.items);
229
+ if (out.prefixItems !== undefined) out.prefixItems = normalizeSchemaTypes(out.prefixItems);
230
+ if (out.additionalProperties && typeof out.additionalProperties === "object") {
231
+ out.additionalProperties = normalizeSchemaTypes(out.additionalProperties);
232
+ }
233
+ for (const key of ["anyOf", "oneOf", "allOf"] as const) {
234
+ if (Array.isArray(out[key])) out[key] = (out[key] as unknown[]).map(normalizeSchemaTypes);
235
+ }
236
+ if (typeof out.type !== "string") out.type = inferSchemaType(out);
237
+ return out;
238
+ }
239
+
240
+ /** Apply normalizeSchemaTypes to every tool's parameter schema. */
241
+ export function normalizeToolSchemas(tools: ToolDefinition[] | null): ToolDefinition[] | null {
242
+ if (!tools) return tools;
243
+ return tools.map((t) => ({
244
+ ...t,
245
+ function: {
246
+ ...t.function,
247
+ parameters: t.function.parameters
248
+ ? (normalizeSchemaTypes(t.function.parameters) as Record<string, unknown>)
249
+ : t.function.parameters,
250
+ },
251
+ }));
252
+ }
253
+
254
+ export class ChatTemplate {
255
+ readonly #template: Template | null;
256
+ readonly #renderer: ChatRenderer | null;
257
+ readonly #bosToken: string | null;
258
+ readonly #eosToken: string | null;
259
+ /** True when the template reads `reasoning_effort` (Qwen3.8's xhigh/medium/
260
+ * low depth control). Callers must not pass the variable otherwise — and
261
+ * must never pass unmapped OpenAI level names; this template family raises
262
+ * on values outside its supported set. */
263
+ readonly readsReasoningEffort: boolean;
264
+ /** True when the template reads `preserve_thinking` (Qwen3.8: keep think
265
+ * blocks from historical turns; template default true). */
266
+ readonly readsPreserveThinking: boolean;
267
+ /** Which reasoning format the template's `enable_thinking` channel uses, or
268
+ * null if the model has no switchable reasoning:
269
+ * - "think-tag": `<think>…</think>` text markers (Qwen3.5, MiniCPM5) — split
270
+ * from decoded text by ThinkingTagSplitter.
271
+ * - "channel-tokens": `<|channel>thought\n…<channel|>` (Gemma 4) — the markers
272
+ * are SPECIAL TOKENS stripped at decode, so reasoning is split at the token
273
+ * level in ToolAwareStream (sentinel-tokens mode), not from decoded text.
274
+ * Drives both the parser path and the reasoning capability advertised to Pi. */
275
+ readonly thinkingFormat: ThinkingFormat | null;
276
+ /** True when the model has a switchable reasoning channel we can parse. */
277
+ readonly supportsThinking: boolean;
278
+
279
+ private constructor(
280
+ source: string | null,
281
+ bosToken: string | null,
282
+ eosToken: string | null,
283
+ forceNoThinking = false,
284
+ renderer: ChatRenderer | null = null,
285
+ explicitThinkingFormat: ThinkingFormat | null = null,
286
+ ) {
287
+ if (source === null && renderer === null)
288
+ throw new Error("ChatTemplate needs a Jinja source or renderer");
289
+ this.#template = source === null ? null : new Template(source);
290
+ this.#renderer = renderer;
291
+ this.#bosToken = bosToken;
292
+ this.#eosToken = eosToken;
293
+ const gatesThinking = source?.includes("enable_thinking") ?? false;
294
+ this.readsReasoningEffort = source?.includes("reasoning_effort") ?? false;
295
+ this.readsPreserveThinking = source?.includes("preserve_thinking") ?? false;
296
+ // `forceNoThinking` suppresses the switchable channel even when the template
297
+ // carries the gemma markers. DiffusionGemma ships the shared gemma-family
298
+ // template (with the `<|channel>thought…<channel|>` reasoning channel), but
299
+ // its non-autoregressive canvas decode cannot reliably emit the `<channel|>`
300
+ // close, so an enabled channel never ends (everything is captured as
301
+ // reasoning, no answer). The OptiQ reference never enables thinking for this
302
+ // model — it always renders the template's `default(false)` pre-closed empty
303
+ // channel and decodes the whole canvas as plain text. We match that.
304
+ this.thinkingFormat = explicitThinkingFormat ?? (forceNoThinking
305
+ ? null
306
+ : gatesThinking && source!.includes("<think>")
307
+ ? "think-tag"
308
+ : gatesThinking && source!.includes("<|channel>")
309
+ ? "channel-tokens"
310
+ : null);
311
+ this.supportsThinking = this.thinkingFormat !== null;
312
+ }
313
+
314
+ /** Loads the artifact's template. `fallback` renders artifacts that ship none
315
+ * (the model layer supplies it from the profile); without one, a missing
316
+ * template is an error. */
317
+ static async load(
318
+ modelDir: string,
319
+ opts: { disableThinking?: boolean; fallback?: TemplateFallback } = {},
320
+ ): Promise<ChatTemplate> {
321
+ const config = (await Bun.file(`${modelDir}/tokenizer_config.json`).json()) as Record<string, any>;
322
+ let source: string | undefined = config.chat_template;
323
+ if (!source) {
324
+ const jinjaFile = Bun.file(`${modelDir}/chat_template.jinja`);
325
+ if (await jinjaFile.exists()) source = await jinjaFile.text();
326
+ }
327
+ if (!source) {
328
+ if (opts.fallback) {
329
+ const tokenText = (t: unknown): string | null =>
330
+ t == null ? null : typeof t === "string" ? t : (t as any).content;
331
+ return new ChatTemplate(
332
+ null,
333
+ tokenText(config.bos_token),
334
+ tokenText(config.eos_token),
335
+ false,
336
+ opts.fallback.render,
337
+ opts.fallback.thinkingFormat,
338
+ );
339
+ }
340
+ throw new Error(`${modelDir}: no chat template found`);
341
+ }
342
+ // @huggingface/jinja lacks the `min`/`max` array filters that real
343
+ // Jinja2 has. MiniCPM5's template uses `[a, b]|min` in its assistant
344
+ // tool-call history branch, so without this rewrite every multi-turn
345
+ // tool conversation fails at render time ("Unknown ArrayValue filter").
346
+ source = source
347
+ .replace(
348
+ /\[\s*([\w.]+)\s*,\s*([\w.]+)\s*\]\s*\|\s*min\b/g,
349
+ "($1 if $1 < $2 else $2)",
350
+ )
351
+ .replace(
352
+ /\[\s*([\w.]+)\s*,\s*([\w.]+)\s*\]\s*\|\s*max\b/g,
353
+ "($1 if $1 > $2 else $2)",
354
+ );
355
+ const tokenText = (t: unknown): string | null =>
356
+ t == null ? null : typeof t === "string" ? t : (t as any).content;
357
+ return new ChatTemplate(source, tokenText(config.bos_token), tokenText(config.eos_token));
358
+ }
359
+
360
+ render(messages: ChatMessage[], options: RenderOptions = {}): string {
361
+ if (this.#renderer) return this.#renderer(messages, options);
362
+ const {
363
+ addGenerationPrompt = true,
364
+ tools = null,
365
+ enableThinking,
366
+ reasoningEffort,
367
+ preserveThinking,
368
+ } = options;
369
+ return this.#template!.render({
370
+ messages,
371
+ add_generation_prompt: addGenerationPrompt,
372
+ // Guarantee every tool param schema has a `type` so templates that do
373
+ // `value['type'] | upper` (Gemma) never see UndefinedValue.
374
+ tools: normalizeToolSchemas(tools),
375
+ ...(enableThinking !== undefined ? { enable_thinking: enableThinking } : {}),
376
+ // Only set for templates that read them: reasoning_effort values are
377
+ // template-validated (Qwen3.8 raises on unknown levels), and an unread
378
+ // variable in other templates is dead context at best.
379
+ ...(reasoningEffort !== undefined && this.readsReasoningEffort
380
+ ? { reasoning_effort: reasoningEffort }
381
+ : {}),
382
+ ...(preserveThinking !== undefined && this.readsPreserveThinking
383
+ ? { preserve_thinking: preserveThinking }
384
+ : {}),
385
+ bos_token: this.#bosToken,
386
+ eos_token: this.#eosToken,
387
+ });
388
+ }
389
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./tokenizer";
2
+ export * from "./chat-template";
3
+ export * from "./token-groups";
4
+ export * from "./packed-mixed";
5
+ export * from "./tool-call";
6
+ export * from "./special-tokens";