mlx-bun 0.2.0 → 0.4.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 (433) hide show
  1. package/README.md +71 -588
  2. package/docs/README.md +94 -0
  3. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  4. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  5. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  6. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  7. package/docs/archive/investigations/openjarvis-fit.md +198 -0
  8. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  9. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  10. package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
  11. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  12. package/docs/archive/planning/release-notes-v0.3.0.md +35 -0
  13. package/docs/design/batching.md +1841 -0
  14. package/docs/design/decode-speed-program.md +2346 -169
  15. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  16. package/docs/design/generic-model-support.md +655 -334
  17. package/docs/design/kv-cache.md +824 -0
  18. package/docs/design/orpo-training.md +673 -1239
  19. package/docs/design/speculative-decoding.md +1990 -0
  20. package/docs/design/turboquant.md +2212 -0
  21. package/docs/design/unified-engine-frontier-plan.md +1833 -727
  22. package/docs/design/web-chat-redesign.md +666 -1083
  23. package/docs/planning/PRODUCT_ROADMAP.md +50 -1
  24. package/docs/planning/release-notes-v0.4.0.md +45 -0
  25. package/docs/planning/video-series.md +2 -2
  26. package/docs/reference/benchmarks.md +3613 -0
  27. package/docs/reference/cli.md +434 -160
  28. package/docs/reference/distribution.md +328 -182
  29. package/docs/reference/environment.md +398 -0
  30. package/docs/reference/glossary.md +39 -0
  31. package/docs/reference/library-api.md +566 -168
  32. package/docs/reference/memory.md +227 -64
  33. package/docs/reference/models.md +113 -6
  34. package/docs/reference/server-api.md +944 -429
  35. package/docs/reference/server-config.md +740 -338
  36. package/docs/reference/training.md +393 -254
  37. package/docs/reference/troubleshooting.md +158 -0
  38. package/package.json +9 -4
  39. package/src/audio/decode.ts +2 -2
  40. package/src/audio/features.ts +2 -2
  41. package/src/backends/mlx/assistant-target.ts +46 -0
  42. package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
  43. package/src/backends/mlx/autoregressive.ts +108 -0
  44. package/src/backends/mlx/batch-group.ts +1790 -0
  45. package/src/backends/mlx/cache-attachment.ts +67 -0
  46. package/src/backends/mlx/cache-layout.ts +31 -0
  47. package/src/backends/mlx/checkpoint-state.ts +53 -0
  48. package/src/backends/mlx/continuation-persistence.ts +106 -0
  49. package/src/backends/mlx/continuation-request.ts +43 -0
  50. package/src/backends/mlx/continuation.ts +77 -0
  51. package/src/backends/mlx/diffusion.ts +39 -0
  52. package/src/backends/mlx/draft-target.ts +32 -0
  53. package/src/backends/mlx/evaluation.ts +105 -0
  54. package/src/backends/mlx/fill-append.ts +45 -0
  55. package/src/backends/mlx/full-kv-row-append.ts +32 -0
  56. package/src/backends/mlx/full-kv-row-donor.ts +54 -0
  57. package/src/backends/mlx/full-transitioning-kv-rows.ts +65 -0
  58. package/src/backends/mlx/gateway-binding.ts +130 -0
  59. package/src/backends/mlx/graph.ts +38 -0
  60. package/src/backends/mlx/kv-codec.ts +9 -0
  61. package/src/backends/mlx/kv-maintenance.ts +133 -0
  62. package/src/backends/mlx/kv-tensor-rows.ts +212 -0
  63. package/src/backends/mlx/memory-client.ts +189 -0
  64. package/src/backends/mlx/methods.ts +90 -0
  65. package/src/backends/mlx/model-prompt.ts +164 -0
  66. package/src/backends/mlx/model-serving.ts +79 -0
  67. package/src/backends/mlx/prefill-cohort.ts +89 -0
  68. package/src/backends/mlx/prefill-rows.ts +200 -0
  69. package/src/backends/mlx/prefill.ts +33 -0
  70. package/src/backends/mlx/projected-context-rows.ts +72 -0
  71. package/src/backends/mlx/request-policy.ts +20 -0
  72. package/src/backends/mlx/request-state-policy.ts +41 -0
  73. package/src/backends/mlx/rollback.ts +89 -0
  74. package/src/backends/mlx/row-sampling.ts +49 -0
  75. package/src/backends/mlx/serial-executor.ts +242 -0
  76. package/src/backends/mlx/speculative-group.ts +359 -0
  77. package/src/backends/mlx/speculative-round.ts +161 -0
  78. package/src/backends/mlx/speculative.ts +114 -0
  79. package/src/backends/mlx/state-rows.ts +104 -0
  80. package/src/backends/mlx/state-views.ts +46 -0
  81. package/src/backends/mlx/target-layout-capability.ts +35 -0
  82. package/src/backends/mlx/text-engine.ts +73 -0
  83. package/src/backends/mlx/transitioning-kv-rows.ts +165 -0
  84. package/src/cli.ts +66 -58
  85. package/src/client.ts +66 -0
  86. package/src/config.ts +21 -4
  87. package/src/contracts/completion.ts +16 -0
  88. package/src/contracts/execution.ts +60 -0
  89. package/src/contracts/generation.ts +103 -0
  90. package/src/contracts/host.ts +7 -0
  91. package/src/contracts/jobs.ts +66 -0
  92. package/src/contracts/pi-provider.ts +30 -0
  93. package/src/contracts/pi.ts +259 -0
  94. package/src/contracts/prefix-cache.ts +23 -0
  95. package/src/contracts/resources.ts +25 -0
  96. package/src/contracts/sampling.ts +23 -0
  97. package/src/contracts/scheduling.ts +45 -0
  98. package/src/contracts/tsconfig.json +14 -0
  99. package/src/diffusion/diffusion-generate.ts +218 -153
  100. package/src/embed.ts +1 -1
  101. package/src/engine/admission.ts +59 -0
  102. package/src/engine/cancellation.ts +38 -0
  103. package/src/engine/engine.ts +56 -0
  104. package/src/engine/execution-coordinator.ts +70 -0
  105. package/src/engine/execution-plan.ts +53 -0
  106. package/src/engine/resources.ts +53 -0
  107. package/src/engine/scheduler.ts +72 -0
  108. package/src/engine/session.ts +247 -0
  109. package/src/eval/README.md +44 -1
  110. package/src/eval/kl.ts +236 -3
  111. package/src/eval/reference-logits.ts +207 -0
  112. package/src/eval/runner.ts +8 -96
  113. package/src/fill/echo-index.ts +188 -0
  114. package/src/fill/fill-session.ts +452 -0
  115. package/src/fill/proposal.ts +68 -0
  116. package/src/fill/schema-rows.ts +506 -0
  117. package/src/fill/tool-boundary.ts +103 -0
  118. package/src/fit.ts +30 -16
  119. package/src/generate.ts +709 -417
  120. package/src/grammar.ts +12 -7
  121. package/src/harness-pi.ts +14 -33
  122. package/src/hub-rest.ts +4 -4
  123. package/src/index.ts +7 -0
  124. package/src/inference/denoising.ts +17 -0
  125. package/src/inference/draft-acceptance.ts +41 -0
  126. package/src/inference/draft-output.ts +49 -0
  127. package/src/inference/graph.ts +33 -0
  128. package/src/inference/prefill.ts +39 -0
  129. package/src/inference/rollback.ts +7 -0
  130. package/src/jobs/db.ts +4 -0
  131. package/src/jobs/index.ts +2 -0
  132. package/src/jobs/job-entry.ts +12 -12
  133. package/src/jobs/runner.ts +98 -13
  134. package/src/jobs/task-client.ts +19 -0
  135. package/src/jobs/types.ts +2 -58
  136. package/src/kv-scheme.ts +70 -12
  137. package/src/kv-store.ts +177 -63
  138. package/src/lab/README.md +18 -0
  139. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  140. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  141. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +5 -5
  142. package/src/lab/paged-kv/paged-kv-rows.ts +83 -0
  143. package/src/{model → lab/paged-kv}/paged-kv.ts +32 -15
  144. package/src/library.ts +40 -0
  145. package/src/lora.ts +18 -0
  146. package/src/media-fetch.ts +1 -1
  147. package/src/memory/article.ts +1 -1
  148. package/src/memory/chunk.ts +1 -1
  149. package/src/memory/model.ts +30 -169
  150. package/src/memory/prompts.ts +1 -1
  151. package/src/memory/rest.ts +1 -1
  152. package/src/memory/schedule.ts +1 -1
  153. package/src/memory/stages.ts +4 -1
  154. package/src/memory/vault.ts +1 -3
  155. package/src/mlx/array.ts +11 -11
  156. package/src/mlx/compile.ts +12 -2
  157. package/src/mlx/ffi.ts +58 -11
  158. package/src/mlx/materialize.ts +23 -0
  159. package/src/mlx/metal-kernel.ts +10 -11
  160. package/src/mlx/ops.ts +33 -13
  161. package/src/mlx/quantized-rows.ts +36 -0
  162. package/src/mlx/token-bitmask.ts +52 -0
  163. package/src/mlx/turboquant-kv-decode.ts +82 -0
  164. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  165. package/src/mlx/turboquant-ops.ts +33 -3
  166. package/src/mlx/turboquant-tables.ts +2 -2
  167. package/src/model/artifact-identity.ts +73 -0
  168. package/src/model/batched-kv.ts +235 -0
  169. package/src/model/batched-mask.ts +20 -6
  170. package/src/model/batched-quant.ts +9 -3
  171. package/src/model/batched-quantized-kv.ts +144 -0
  172. package/src/model/batched-rotating-quant.ts +78 -17
  173. package/src/model/batched-rotating-state.ts +76 -0
  174. package/src/model/batched-rotating.ts +65 -23
  175. package/src/model/batched-row-storage.ts +52 -0
  176. package/src/model/batched-ssm.ts +52 -0
  177. package/src/model/batched-turboquant-kv.ts +93 -0
  178. package/src/model/compiled-decode.ts +8 -2
  179. package/src/model/decoded-kv-donor.ts +12 -0
  180. package/src/model/delayed-quantized-kv.ts +72 -0
  181. package/src/model/delayed-rotating-quantized-kv.ts +93 -0
  182. package/src/model/delayed-turboquant-kv.ts +55 -0
  183. package/src/model/diffusion-gemma.ts +8 -8
  184. package/src/model/factory.ts +76 -33
  185. package/src/model/fingerprint.ts +1 -1
  186. package/src/model/flash-attention.ts +3 -3
  187. package/src/model/full-prefill-padding.ts +56 -0
  188. package/src/model/full-prefill-row.ts +105 -0
  189. package/src/model/gemma4-base.ts +179 -80
  190. package/src/model/gemma4.ts +40 -32
  191. package/src/model/generated/gemma4-12b.ts +6 -3
  192. package/src/model/generated/gemma4-26b.ts +6 -3
  193. package/src/model/generated/gemma4-e4b.ts +6 -3
  194. package/src/model/glm52-cache.ts +80 -4
  195. package/src/model/glm52-dsa.ts +13 -9
  196. package/src/model/glm52-memory.ts +1 -1
  197. package/src/model/glm52-mla.ts +12 -6
  198. package/src/model/glm52.ts +19 -40
  199. package/src/model/implementation.ts +69 -0
  200. package/src/model/kv-attention-view.ts +67 -0
  201. package/src/model/minicpm5.ts +17 -15
  202. package/src/model/profile.ts +12 -2
  203. package/src/model/qwen-append.ts +12 -0
  204. package/src/model/qwen-conv.ts +52 -0
  205. package/src/model/qwen3-delta-state.ts +74 -0
  206. package/src/model/qwen3-delta.ts +59 -36
  207. package/src/model/qwen3_5-checkpoint.ts +164 -0
  208. package/src/model/qwen3_5.ts +202 -78
  209. package/src/model/rotating-kv-donor.ts +35 -0
  210. package/src/model/rotating-kv-layout.ts +262 -0
  211. package/src/model/rotating-row-transaction.ts +35 -0
  212. package/src/model/speculative-rotating-kv.ts +101 -0
  213. package/src/model/ssm-prefill-padding.ts +39 -0
  214. package/src/model/support.ts +1 -1
  215. package/src/model/trellis-balanced-scatter.ts +51 -0
  216. package/src/model/trellis-linear.ts +672 -0
  217. package/src/model/trellis-shared-m.ts +151 -0
  218. package/src/model/trellis-shared-scatter.ts +144 -0
  219. package/src/model/trellis-splitk-prefill.ts +158 -0
  220. package/src/model/trellis-tiled-prefill.ts +136 -0
  221. package/src/model/trellis-vector-expand.ts +62 -0
  222. package/src/model/trellis-wide-prefill.ts +94 -0
  223. package/src/model/turboquant-codec.ts +83 -0
  224. package/src/model/universal/dense.ts +15 -14
  225. package/src/model/universal/modules.ts +8 -1
  226. package/src/native-pack.ts +6 -5
  227. package/src/pi-provider.ts +6 -64
  228. package/src/pi-web.ts +8 -315
  229. package/src/preflight.ts +31 -15
  230. package/src/prompt-cache.ts +110 -69
  231. package/src/quantize/allocator.ts +1 -1
  232. package/src/quantize/config-writer.ts +10 -3
  233. package/src/quantize/rotate.ts +4 -4
  234. package/src/quantize/trellis.ts +586 -0
  235. package/src/responses.ts +28 -1
  236. package/src/runtime-config.ts +18 -4
  237. package/src/sampler.ts +40 -29
  238. package/src/serve/batch-scheduler.ts +8 -1671
  239. package/src/serve/chat-request.ts +391 -0
  240. package/src/serve/chat-stage.ts +195 -0
  241. package/src/serve/checkpoint-identity.ts +64 -0
  242. package/src/serve/completion-executor.ts +15 -7
  243. package/src/serve/discovery-routes.ts +12 -13
  244. package/src/serve/generation-gateway.ts +183 -213
  245. package/src/serve/http.ts +159 -0
  246. package/src/serve/inference-request.ts +79 -0
  247. package/src/serve/isolate.ts +297 -105
  248. package/src/serve/lab-routes.ts +3 -0
  249. package/src/serve/lane-registry.ts +2 -1
  250. package/src/serve/model-admin-routes.ts +7 -5
  251. package/src/serve/model-binding.ts +43 -0
  252. package/src/serve/model-host.ts +511 -0
  253. package/src/serve/openai-wire.ts +103 -0
  254. package/src/serve/parent-application.ts +56 -0
  255. package/src/serve/pipeline.ts +33 -0
  256. package/src/serve/preparation.ts +33 -0
  257. package/src/serve/request-plan.ts +23 -18
  258. package/src/serve/request-prep.ts +344 -0
  259. package/src/serve/response-lease.ts +24 -0
  260. package/src/serve/responses-client.ts +69 -0
  261. package/src/serve/session-completion-engine.ts +110 -0
  262. package/src/serve/session-search.ts +1 -1
  263. package/src/serve/static-routes.ts +5 -5
  264. package/src/serve/text-completion-stage.ts +104 -0
  265. package/src/serve/token-streams.ts +519 -0
  266. package/src/server.ts +335 -2711
  267. package/src/spec/assistant-rows.ts +92 -0
  268. package/src/spec/assistant-source.ts +31 -55
  269. package/src/spec/cache-identity.ts +22 -0
  270. package/src/spec/deepspec-rows.ts +29 -0
  271. package/src/spec/deepspec-source.ts +16 -14
  272. package/src/spec/dflash-source.ts +36 -12
  273. package/src/spec/drafter.ts +153 -142
  274. package/src/spec/dspark/ab-stats.ts +3 -3
  275. package/src/spec/dspark/calibration.ts +2 -2
  276. package/src/spec/dspark/deepspec-module.ts +97 -122
  277. package/src/spec/dspark/generate-dflash.ts +2 -2
  278. package/src/spec/dspark/generate.ts +2 -2
  279. package/src/spec/dspark/loader.ts +1 -1
  280. package/src/spec/dspark/module-dflash.ts +129 -172
  281. package/src/spec/dspark/module.ts +3 -3
  282. package/src/spec/dspark/quantize-drafter.ts +1 -1
  283. package/src/spec/generate.ts +1 -1
  284. package/src/spec/glm52-mtp-graph.ts +29 -0
  285. package/src/spec/glm52-mtp-rows.ts +132 -0
  286. package/src/spec/glm52-mtp-source.ts +54 -137
  287. package/src/spec/glm52-mtp-state.ts +33 -0
  288. package/src/spec/ngram-source.ts +93 -21
  289. package/src/spec/projected-draft-rows.ts +73 -0
  290. package/src/spec/qwen-mtp-module.ts +171 -0
  291. package/src/spec/qwen-mtp-rows.ts +219 -0
  292. package/src/spec/qwen-mtp-source.ts +147 -195
  293. package/src/spec/qwen-mtp-state.ts +30 -0
  294. package/src/spec/serve-loop.ts +201 -201
  295. package/src/spec/source.ts +110 -13
  296. package/src/spec/two-model-rows.ts +61 -0
  297. package/src/spec/two-model.ts +44 -102
  298. package/src/ssd-cache.ts +99 -19
  299. package/src/ssd-durability.ts +36 -20
  300. package/src/tool-call.ts +51 -14
  301. package/src/train/flash-cce.ts +2 -2
  302. package/src/train/forward.ts +6 -0
  303. package/src/train/loss.ts +1 -1
  304. package/src/train/prefix-shared.ts +5 -1
  305. package/src/train/segmented.ts +5 -3
  306. package/src/train/trainer.ts +6 -6
  307. package/src/vision/prompt.ts +1 -1
  308. package/src/vision/qwen3vl-tower.ts +52 -10
  309. package/src/web/app.html +1 -1
  310. package/src/web/app.js +62 -60
  311. package/src/web/src/adapters-panel.ts +3 -3
  312. package/src/web/src/assistant.ts +2 -36
  313. package/src/web/src/chat.ts +4 -4
  314. package/src/web/src/composer.ts +4 -4
  315. package/src/web/src/hub.ts +1 -1
  316. package/src/web/src/markdown.ts +0 -0
  317. package/src/web/src/memory-panel.ts +1 -1
  318. package/src/web/src/model-picker.ts +1 -1
  319. package/src/web/src/palette.ts +1 -1
  320. package/src/web/src/protocol.ts +3 -39
  321. package/src/web/src/sessions.ts +1 -1
  322. package/src/web/src/ui-catalog.ts +4 -18
  323. package/src/web-assets.ts +47 -0
  324. package/src/weights.ts +55 -9
  325. package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
  326. package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
  327. package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
  328. package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
  329. package/docs/archive/investigations/hlg-ab.html +0 -34
  330. package/docs/archive/investigations/hlg-explorer.html +0 -238
  331. package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
  332. package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
  333. package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
  334. package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
  335. package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
  336. package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
  337. package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
  338. package/docs/archive/investigations/hlg-report.html +0 -262
  339. package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
  340. package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  341. package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
  342. package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
  343. package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
  344. package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
  345. package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
  346. package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
  347. package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
  348. package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
  349. package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  350. package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
  351. package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
  352. package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
  353. package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  354. package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  355. package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  356. package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  357. package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  358. package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  359. package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  360. package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
  361. package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
  362. package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
  363. package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
  364. package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
  365. package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  366. package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
  367. package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
  368. package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
  369. package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
  370. package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
  371. package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  372. package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
  373. package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  374. package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  375. package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  376. package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  377. package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  378. package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  379. package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
  380. package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  381. package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
  382. package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  383. package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  384. package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  385. package/docs/archive/mlx-bun-lab-report.html +0 -275
  386. package/docs/archive/wwdc-mlx-bun.html +0 -848
  387. package/docs/design/adapters-end-to-end.md +0 -205
  388. package/docs/design/batching-perf-path.md +0 -255
  389. package/docs/design/batching-v2-plan.md +0 -529
  390. package/docs/design/bucketing-stage.md +0 -197
  391. package/docs/design/compat-cli-surface-design.md +0 -230
  392. package/docs/design/docs-reorg-plan.md +0 -165
  393. package/docs/design/dspark-serving-program.md +0 -371
  394. package/docs/design/dspark-speculative-decoding.md +0 -318
  395. package/docs/design/grammar-spec-batching-integration.md +0 -301
  396. package/docs/design/memory-inference-path.md +0 -422
  397. package/docs/design/memory-synthesis.md +0 -287
  398. package/docs/design/memory-system.md +0 -237
  399. package/docs/design/mlx-lm-serving-execution-seam.md +0 -81
  400. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  401. package/docs/design/omlx-adoption-map.md +0 -98
  402. package/docs/design/orpo-dynamic-lambda.md +0 -220
  403. package/docs/design/orpo-future-enhancements.md +0 -340
  404. package/docs/design/paged-kv-cache.md +0 -214
  405. package/docs/design/parallel-slots.md +0 -567
  406. package/docs/design/parity-tier-dag.md +0 -161
  407. package/docs/design/repo-cleanup-plan.md +0 -231
  408. package/docs/design/runtime-isolation.md +0 -263
  409. package/docs/design/segmented-backward-training.md +0 -543
  410. package/docs/design/spec-decode-larger-targets.md +0 -229
  411. package/docs/design/ssd-kv-cold-tier.md +0 -415
  412. package/docs/design/structured-output.md +0 -484
  413. package/docs/design/tauri-desktop-app.md +0 -127
  414. package/docs/design/the-dreaming-master-plan.md +0 -445
  415. package/docs/design/turboquant-kv.md +0 -235
  416. package/docs/design/turboquant-weights.md +0 -467
  417. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  418. package/docs/design/web-chat-beat-matrix.md +0 -315
  419. package/docs/design/write-pipeline-entity.md +0 -468
  420. package/docs/planning/IDEAS.md +0 -69
  421. package/docs/reference/embedding.md +0 -197
  422. package/docs/reference/features-matrix.md +0 -101
  423. package/docs/reference/orpo-quickstart.md +0 -135
  424. package/src/flags.ts +0 -11
  425. /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
  426. /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
  427. /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
  428. /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
  429. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  430. /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
  431. /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
  432. /package/{docs/archive/investigations → src/serve/assets}/curve-terrain.html +0 -0
  433. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
package/src/grammar.ts CHANGED
@@ -33,6 +33,7 @@ import xgrammar, {
33
33
  import { readFileSync } from "node:fs";
34
34
  import { MlxArray } from "./mlx/array";
35
35
  import * as ops from "./mlx/ops";
36
+ import { applyTokenBitmask } from "./mlx/token-bitmask";
36
37
  import { runtimeValue } from "./runtime-config";
37
38
  import type { LoadedTokenizer } from "./tokenizer";
38
39
 
@@ -52,7 +53,7 @@ export interface GrammarRequest {
52
53
  guided_grammar?: string;
53
54
  /** vLLM/oMLX: regex. Compiled via `root ::= <regex>` EBNF embedding, so
54
55
  * only the regex∩EBNF subset works (the F5 gap — real regex→EBNF or
55
- * structural-tag RegexFormat is the tracked fix, structured-output.md). */
56
+ * structural-tag RegexFormat is the tracked fix, docs/reference/server-api.md). */
56
57
  guidedRegex?: string;
57
58
  guided_regex?: string;
58
59
  /** vLLM/oMLX: restrict output to one of these strings (enum). */
@@ -80,7 +81,7 @@ export interface CompiledGrammarResult {
80
81
  /** Module-level serializer for ALL xgrammar WASM calls. The WASM instance is
81
82
  * single-threaded; CONCURRENT async calls corrupt emscripten's binding
82
83
  * layer (BindingError: Expected null or instance of VectorInt, got an
83
- * instance of VectorInt — reproduced in tests/grammar.test.ts B1 test, which
84
+ * instance of VectorInt — reproduced in tests/parity/grammar.test.ts B1 test, which
84
85
  * fires 4 overlapping compiles + fills). Under `--batch N` the scheduler
85
86
  * fires N accept()s (each kicks an async fill) then awaits ready() on all;
86
87
  * and the server compiles grammar for concurrent requests. Without
@@ -119,7 +120,7 @@ let cachedTokenizerInfo: {
119
120
  * - decoder is Sequence w/ ByteFallback → byte_fallback (Gemma/SP)
120
121
  * - otherwise → raw
121
122
  * prependSpace is true for byte_level (ByteLevel pretokenizers add a leading
122
- * space). Validated in scripts/experiments/xgrammar-spike.ts across Gemma
123
+ * space). Validated in xgrammar-spike.ts (deleted 2026-08-23; git history) across Gemma
123
124
  * (byte_fallback, 256k), Llama-3 / Qwen2.5 (byte_level, 128k/151k). */
124
125
  function loadVocab(tokenizerJsonPath: string): {
125
126
  vocab: string[];
@@ -207,6 +208,7 @@ export class GrammarController {
207
208
  private pending: Promise<void> | null;
208
209
  private terminated = false;
209
210
  private disposed = false;
211
+ private readonly metalMask = runtimeValue("MLX_BUN_TOKEN_MASK") === "metal";
210
212
  /** Tokens emitted via jumpForward() this generation — telemetry/test hook. */
211
213
  jumpedTokens = 0;
212
214
 
@@ -238,6 +240,7 @@ export class GrammarController {
238
240
  * Sync — the mask is already materialized. Returns a NEW array (caller
239
241
  * disposes the input). Mirrors oMLX's apply_token_bitmask_mlx. */
240
242
  applyMask(logits: MlxArray): MlxArray {
243
+ if (this.metalMask) return applyTokenBitmask(logits, this.readyMask);
241
244
  // Build a -inf/0 additive float mask on device from the int32 bitmask.
242
245
  // Each int32 bit b (little-endian within the word) gates token
243
246
  // word*32 + b. Set = valid (xgrammar convention). Adding -inf → -inf,
@@ -255,7 +258,9 @@ export class GrammarController {
255
258
  const valid = (w >>> bit) & 1;
256
259
  maskArr[id] = valid ? 0 : -Infinity;
257
260
  }
258
- const mask = MlxArray.fromFloat32(maskArr, [1, V]).astype(logits.dtype);
261
+ const raw = MlxArray.fromFloat32(maskArr, [1, V]);
262
+ const mask = raw.astype(logits.dtype);
263
+ raw.dispose();
259
264
  const out = ops.add(logits, mask);
260
265
  mask.dispose();
261
266
  return out;
@@ -285,7 +290,7 @@ export class GrammarController {
285
290
  * time: a controller disposed while its fill is still queued (an exception
286
291
  * between accept/jumpForward and ready()) must not call into the deleted
287
292
  * WASM matcher — that BindingError poisons the module-wide wasmChain for
288
- * every later grammar request (found by tests/grammar-jump.test.ts). */
293
+ * every later grammar request (found by tests/parity/grammar-jump.test.ts). */
289
294
  private fireFill(): Promise<void> {
290
295
  return wasmQueue(() =>
291
296
  this.disposed
@@ -458,7 +463,7 @@ export async function compileGrammarRequest(
458
463
  if (!degradeHint) degradeHint = resolved.degradeDescription ?? "grammar compile failed";
459
464
  // The compiler is the cached per-TokenizerInfo instance (F4) — a failed
460
465
  // compile must NOT dispose it; the WASM abort is catchable and the
461
- // compiler state survives (verified in tests/grammar.test.ts).
466
+ // compiler state survives (verified in tests/parity/grammar.test.ts).
462
467
  // Return the hint (NOT bare null): it drives the degrade path's
463
468
  // system-prompt injection + Warning header. Dropping it here served
464
469
  // unconstrained output with no Warning at all (found 2026-07-07 sweep).
@@ -539,7 +544,7 @@ function resolveGrammarRequest(req: GrammarRequest):
539
544
  kind: "json_schema",
540
545
  schema,
541
546
  strict: js?.strict,
542
- // Whitespace-stall escape hatch (structured-output.md known gaps):
547
+ // Whitespace-stall escape hatch (docs/reference/server-api.md known gaps):
543
548
  // any_whitespace=false compiles the schema with xgrammar's compact
544
549
  // separators — no whitespace choice points, so a whitespace-
545
550
  // degenerate base model can't greedily tab-loop to max_tokens.
package/src/harness-pi.ts CHANGED
@@ -13,7 +13,9 @@ import { homedir } from "node:os";
13
13
  import { dirname, join } from "node:path";
14
14
 
15
15
  export const PI_EXTENSION_FILENAME = "mlx-bun-provider.ts";
16
- export const PI_PROVIDER_ID = "mlx-bun";
16
+ import { PI_PROVIDER_ID, PI_LOCAL_MODEL_ID, PI_API_KEY, PI_API, piModelDefinition,
17
+ DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_TOKENS } from "./contracts/pi-provider";
18
+ export { PI_PROVIDER_ID, PI_LOCAL_MODEL_ID } from "./contracts/pi-provider";
17
19
  /** Stable pi-facing model id. The server runs exactly one model at a time
18
20
  * (memory: the 26B alone is 18 GB) and which one varies run-to-run, so
19
21
  * advertising the real, changing repo id makes pi's persisted default go
@@ -21,7 +23,7 @@ export const PI_PROVIDER_ID = "mlx-bun";
21
23
  * model is loaded; the real model is carried in the `name` field, and the
22
24
  * server still reports the true id in /v1/models and responses. Gives a
23
25
  * clean `mlx-bun/local` handle instead of `mlx-bun/mlx-community/…`. */
24
- export const PI_LOCAL_MODEL_ID = "local";
26
+
25
27
  // 127.0.0.1 (the server's actual default bind), not "localhost": the generated
26
28
  // extension runs under the USER'S pi (node/jiti, not Bun), so don't depend on
27
29
  // how that runtime's resolver maps localhost.
@@ -89,8 +91,8 @@ export async function fetchServerModels(baseUrl: string, timeoutMs = 3000): Prom
89
91
  if (!served) return [];
90
92
  return [{
91
93
  id: served.id,
92
- contextWindow: served.context_window ?? 32768,
93
- maxTokens: 8192,
94
+ contextWindow: served.context_window ?? DEFAULT_CONTEXT_WINDOW,
95
+ maxTokens: DEFAULT_MAX_TOKENS,
94
96
  reasoning: !!served.reasoning,
95
97
  vision: !!served.vision,
96
98
  }];
@@ -120,6 +122,7 @@ export function renderPiExtension(baseUrl: string, fallbackModels: ServerModel[]
120
122
  // is the fallback when the server isn't running.
121
123
  const BASE_URL = ${JSON.stringify(baseUrl)};
122
124
  const FALLBACK_MODELS = ${fallback};
125
+ const modelEntry = ${piModelDefinition.toString()};
123
126
 
124
127
  export default async function (pi: any) {
125
128
  let models = FALLBACK_MODELS;
@@ -131,27 +134,19 @@ export default async function (pi: any) {
131
134
  // The SERVED model is the row with the capability extras (first);
132
135
  // the rest are servable-but-not-served registry entries.
133
136
  const served = data.find((m: any) => m.context_window !== undefined) ?? data[0];
134
- models = [{
135
- id: ${JSON.stringify(PI_LOCAL_MODEL_ID)},
137
+ models = [modelEntry({
136
138
  name: \`\${served.id} (mlx-bun local)\`,
137
- reasoning: !!served.reasoning,
138
- compat: {
139
- supportsDeveloperRole: false,
140
- ...(served.reasoning ? { thinkingFormat: "qwen-chat-template" } : {}),
141
- },
142
- input: served.vision ? ["text", "image"] : ["text"],
143
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
144
- contextWindow: served.context_window ?? 32768,
145
- maxTokens: 8192,
146
- }];
139
+ reasoning: !!served.reasoning, vision: !!served.vision,
140
+ contextWindow: served.context_window,
141
+ })];
147
142
  }
148
143
  }
149
144
  } catch {}
150
145
  if (models.length === 0) return; // nothing to register
151
146
  pi.registerProvider(${JSON.stringify(PI_PROVIDER_ID)}, {
152
147
  baseUrl: BASE_URL,
153
- apiKey: "sk-mlx-bun-local",
154
- api: "openai-completions",
148
+ apiKey: ${JSON.stringify(PI_API_KEY)},
149
+ api: ${JSON.stringify(PI_API)},
155
150
  models,
156
151
  });
157
152
  }
@@ -159,21 +154,7 @@ export default async function (pi: any) {
159
154
  }
160
155
 
161
156
  function modelEntry(m: ServerModel) {
162
- return {
163
- id: PI_LOCAL_MODEL_ID,
164
- name: `${m.id} (mlx-bun local)`,
165
- reasoning: !!m.reasoning,
166
- // Kept aligned with buildPiProvider (src/pi-provider.ts): the system
167
- // prompt must arrive as `system`, not `developer`.
168
- compat: {
169
- supportsDeveloperRole: false,
170
- ...(m.reasoning ? { thinkingFormat: "qwen-chat-template" } : {}),
171
- },
172
- input: m.vision ? ["text", "image"] : ["text"],
173
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
174
- contextWindow: m.contextWindow,
175
- maxTokens: m.maxTokens,
176
- };
157
+ return piModelDefinition({ ...m, name: `${m.id} (mlx-bun local)` });
177
158
  }
178
159
 
179
160
  export interface InstallResult {
package/src/hub-rest.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // Axis 3 "Hub" row). Same posture as src/memory/rest.ts: pure (request|url)
4
4
  // => Response handlers with no `ctx` dependency, dispatched from
5
5
  // src/server.ts by path+method, so they're unit-testable without booting a
6
- // model context (see tests/hub-rest.test.ts).
6
+ // model context (see tests/serve/hub-rest.test.ts).
7
7
  //
8
8
  // Three sources, same as optiq Lab's Hub, plus the hardware-fit column optiq
9
9
  // lacks:
@@ -19,7 +19,7 @@
19
19
  // - POST /api/hub/serve — model-swap investigation (see the doc header
20
20
  // above the handler): today this ALWAYS returns
21
21
  // { ok:false, restart_required:true, command } — see
22
- // docs/design/runtime-isolation.md for why no in-process swap seam is
22
+ // docs/reference/server-config.md for why no in-process swap seam is
23
23
  // reachable from the web chat's serving path today.
24
24
 
25
25
  import { loadModelConfig } from "./config";
@@ -43,7 +43,7 @@ function jsonErr(error: string, status = 400): Response {
43
43
  * fixed 8k context (the same "typical" context /fit and /library use, so
44
44
  * the three surfaces never disagree). `reg`/`hubDir` are injectable so
45
45
  * tests can point at a synthetic hub dir instead of the real
46
- * ~/.cache/huggingface/hub (matching tests/registry-fit.test.ts's pattern);
46
+ * ~/.cache/huggingface/hub (matching tests/unit/registry-fit.test.ts's pattern);
47
47
  * the live server route omits both and gets the real registry. */
48
48
  export async function handleHubLocal(
49
49
  opts: { reg?: Registry; hubDir?: string } = {},
@@ -210,7 +210,7 @@ export async function handleHubDownload(request: Request): Promise<Response> {
210
210
 
211
211
  // ---- POST /api/hub/serve --------------------------------------------------
212
212
 
213
- /** Model-swap investigation (docs/design/runtime-isolation.md): the web
213
+ /** Model-swap investigation (docs/reference/server-config.md): the web
214
214
  * chat's `/ws/chat` is explicitly NOT proxied even under `--isolate`
215
215
  * (src/serve/isolate.ts serves it a 501 with a pointer back to the direct,
216
216
  * non-isolated server) and `--isolate` itself is opt-in, not the default —
package/src/index.ts CHANGED
@@ -16,9 +16,15 @@ export {
16
16
  createModel,
17
17
  openGlm52RuntimeModel,
18
18
  openModel,
19
+ type ModelOpenOptions,
19
20
  type Glm52RuntimeOpenOptions,
20
21
  type RuntimeModel,
21
22
  } from "./model/factory";
23
+ export { ModelImplementationRegistry, type ModelImplementation, type ModelImplementationProvider } from "./model/implementation";
24
+ export type { ModelServingBinding, ModelPromptBuilder, BuiltPrompt, ServedModelInfo } from "./serve/model-binding";
25
+ export type { ServingContext, ModelHostSource, AdapterService } from "./serve/model-host";
26
+ export type { MlxGatewayBinding, MlxBatchGroup } from "./backends/mlx/gateway-binding";
27
+ export type { MlxSerialServices, MlxSerialBinding } from "./backends/mlx/serial-executor";
22
28
  export { Qwen3Model } from "./model/qwen3";
23
29
  export { configFingerprint } from "./model/fingerprint";
24
30
  export {
@@ -49,6 +55,7 @@ export { downloadModel } from "./download";
49
55
  export { Registry } from "./registry";
50
56
  export {
51
57
  createServer,
58
+ shutdownServer,
52
59
  loadContext,
53
60
  type LoadContextOptions,
54
61
  type ServerContext,
@@ -0,0 +1,17 @@
1
+ import type { GraphDescriptor } from "./graph";
2
+
3
+ /** Denoising has canvas state and feedback, independent of AR token caches.
4
+ * Returned tensors/state are owned by the run. Inputs remain borrowed. A
5
+ * fused method may bypass this graph and implement InferenceMethod directly. */
6
+ export interface DenoisingGraph<Tensor, State> {
7
+ readonly descriptor: GraphDescriptor;
8
+ readonly vocabSize: number;
9
+ readonly canvasLength: number;
10
+ readonly embedScale: number;
11
+ prefill(promptIds: number[], vision?: Tensor): State;
12
+ extendPrefill(tokens: Tensor, state: State): void;
13
+ decoderLogits(canvas: Tensor, state: State, feedback: Tensor | null): Tensor;
14
+ dequantEmbedWeight(): Tensor;
15
+ softEmbeddings(logits: Tensor, weight: Tensor): Tensor;
16
+ closeState(state: State): void;
17
+ }
@@ -0,0 +1,41 @@
1
+ /** One request's exact-token speculative acceptance walk. The backend owns
2
+ * logits and sampling; this state owns only the accepted prefix and stop facts.
3
+ * A group advances each live walk independently, regardless of batch size. */
4
+ export class DraftAcceptance {
5
+ position = 0;
6
+ accepted = 0;
7
+ correction: number | null = null;
8
+ readonly emitted: number[] = [];
9
+ sawEos = false;
10
+ grammarDone = false;
11
+ done = false;
12
+
13
+ constructor(
14
+ readonly drafts: readonly number[],
15
+ readonly remaining: number,
16
+ readonly eosTokenIds: readonly number[],
17
+ ) {}
18
+
19
+ /** Supply one target sample after its sampler has updated request history
20
+ * and grammar. Once done, this request needs no further target samples. */
21
+ accept(token: number, grammarDone = false): void {
22
+ const matches = this.position < this.drafts.length && token === this.drafts[this.position];
23
+ this.position++;
24
+ if (matches) {
25
+ this.accepted++;
26
+ if (this.eosTokenIds.includes(token)) {
27
+ this.sawEos = this.done = true;
28
+ return;
29
+ }
30
+ this.emitted.push(token);
31
+ this.grammarDone = grammarDone;
32
+ this.done = grammarDone || this.emitted.length >= this.remaining;
33
+ return;
34
+ }
35
+ this.correction = token;
36
+ this.sawEos = this.eosTokenIds.includes(token);
37
+ if (!this.sawEos) this.emitted.push(token);
38
+ this.grammarDone = grammarDone;
39
+ this.done = true;
40
+ }
41
+ }
@@ -0,0 +1,49 @@
1
+ import type { Cancellation, CancelReason, GenerationOutput, TokenLogprobs } from "../contracts/generation";
2
+ import type { DraftAcceptance } from "./draft-acceptance";
3
+
4
+ export interface DraftOutputRow {
5
+ readonly acceptance: DraftAcceptance;
6
+ readonly logprobs?: readonly (TokenLogprobs | undefined)[];
7
+ readonly output: Pick<GenerationOutput, "commit">;
8
+ readonly cancellation?: Cancellation;
9
+ }
10
+
11
+ /** Counts apply to this round. Accepted counts describe processed proposed
12
+ * inputs, excluding an unprocessed correction/bonus and any unpublished EOS.
13
+ * Failed/cancelled requests must be discarded, never checkpointed. */
14
+ export type DraftOutputResult = { readonly generated: number; readonly accepted: number } & (
15
+ | { readonly kind: "continue"; readonly pending: number }
16
+ | { readonly kind: "stop" | "length" }
17
+ | { readonly kind: "cancelled"; readonly reason: CancelReason }
18
+ | { readonly kind: "failed"; readonly error: unknown }
19
+ );
20
+
21
+ /** Deliver verified content through the output interface before resolving
22
+ * retained state. A stopped or failed consumer affects only its own request.
23
+ * Token-sized publications preserve callbacks that stop inside a draft burst. */
24
+ export async function deliverDraftOutputs(rows: readonly DraftOutputRow[]): Promise<DraftOutputResult[]> {
25
+ const results: DraftOutputResult[] = [];
26
+ for (const row of rows) results.push(await deliver(row));
27
+ return results;
28
+ }
29
+
30
+ async function deliver(row: DraftOutputRow): Promise<DraftOutputResult> {
31
+ const { acceptance } = row;
32
+ let generated = 0;
33
+ const retained = () => ({ generated, accepted: Math.min(generated, acceptance.accepted) });
34
+ try {
35
+ for (const token of acceptance.emitted) {
36
+ const reason = row.cancellation?.reason;
37
+ if (reason) return { kind: "cancelled", reason, generated, accepted: 0 };
38
+ const metadata = row.logprobs?.[generated];
39
+ const more = await row.output.commit([token], metadata ? [metadata] : undefined);
40
+ generated++;
41
+ if (more === false) return { kind: "stop", ...retained() };
42
+ }
43
+ const reason = row.cancellation?.reason;
44
+ if (reason) return { kind: "cancelled", reason, generated, accepted: 0 };
45
+ if (acceptance.sawEos || acceptance.grammarDone) return { kind: "stop", ...retained() };
46
+ if (generated >= acceptance.remaining) return { kind: "length", ...retained() };
47
+ return { kind: "continue", pending: acceptance.correction!, ...retained() };
48
+ } catch (error) { return { kind: "failed", error, generated, accepted: 0 }; }
49
+ }
@@ -0,0 +1,33 @@
1
+ /** Describes an implementation's ABI, not a claim of oracle parity or speed. */
2
+ export interface GraphDescriptor {
3
+ readonly id: string;
4
+ readonly backend: string;
5
+ readonly graphAbi: string;
6
+ readonly stateAbi: string;
7
+ readonly artifact: string;
8
+ }
9
+
10
+ export type LogitSelection =
11
+ | { readonly type: "all" }
12
+ | { readonly type: "last" }
13
+ | { readonly type: "range"; readonly start: number; readonly end: number };
14
+
15
+ /** Backend-bound graph. Tensor/State/Inputs stay concrete within the binding.
16
+ * Inputs and hidden are borrowed until the returned lazy work completes;
17
+ * returned hidden/logits are owned by the caller. The graph appends to state.
18
+ * Hidden is [batch, positions, hidden-width]; logits are [batch, selected
19
+ * positions, vocabulary]. Selection precedes the vocabulary projection.
20
+ * Dtypes and evaluation/fence semantics belong to the declared backend ABI.
21
+ * Per-run masks, positions, media, taps, and adapters belong in Inputs or in
22
+ * a bound graph context; they are not mutable session fields. */
23
+ export interface AutoregressiveGraph<Tensor, State, Inputs> {
24
+ readonly descriptor: GraphDescriptor;
25
+ forwardHidden(inputs: Inputs, state: State): Tensor | Promise<Tensor>;
26
+ projectLogits(hidden: Tensor, selection: LogitSelection): Tensor;
27
+ }
28
+
29
+ /** A fused InferenceMethod can bypass this graph interface entirely. It need
30
+ * only satisfy the method's output, cancellation, and ownership contracts. */
31
+ export interface GraphFactory<Artifact, Binding, Graph> {
32
+ open(artifact: Artifact, binding: Binding): Promise<{ graph: Graph; close(): Promise<void> }>;
33
+ }
@@ -0,0 +1,39 @@
1
+ export interface PrefillPosition {
2
+ readonly length: number;
3
+ readonly position: number;
4
+ readonly chunkSize: number;
5
+ readonly tailSplit: boolean;
6
+ readonly snapshotAt?: number | null;
7
+ }
8
+
9
+ export interface PrefillStep {
10
+ readonly start: number;
11
+ readonly end: number;
12
+ readonly kind: "drain" | "final";
13
+ readonly snapshot: boolean;
14
+ /** Batch admission may finish a short last drain and token zero in one tick.
15
+ * Serial execution still yields between every drain and the next forward. */
16
+ readonly batchYield: boolean;
17
+ }
18
+
19
+ /** Shared serial/solo-batch prefill program. No tensors, runtime policy reads,
20
+ * or sampling. Advance position only after executing the returned step. */
21
+ export function nextPrefillStep(input: PrefillPosition): PrefillStep {
22
+ const { length, position, chunkSize, tailSplit, snapshotAt } = input;
23
+ if (!Number.isSafeInteger(length) || !Number.isSafeInteger(position) ||
24
+ !Number.isSafeInteger(chunkSize) || chunkSize < 1 || position < 0 || position >= length)
25
+ throw new Error("invalid prefill position or chunk size");
26
+ if (snapshotAt != null && (!Number.isSafeInteger(snapshotAt) || snapshotAt < 0 || snapshotAt > length))
27
+ throw new Error("invalid prefill snapshot boundary");
28
+ if (snapshotAt != null && snapshotAt > position && snapshotAt < length) {
29
+ const end = Math.min(position + chunkSize, snapshotAt);
30
+ return { start: position, end, kind: "drain", snapshot: end === snapshotAt, batchYield: true };
31
+ }
32
+ const remaining = length - position;
33
+ if (remaining > (tailSplit ? 1 : chunkSize)) {
34
+ const end = position + (tailSplit ? Math.min(chunkSize, remaining - 1) : chunkSize);
35
+ return { start: position, end, kind: "drain", snapshot: false,
36
+ batchYield: !tailSplit || remaining - 1 > chunkSize };
37
+ }
38
+ return { start: position, end: length, kind: "final", snapshot: false, batchYield: false };
39
+ }
@@ -0,0 +1,7 @@
1
+ /** A complete transaction over every participating target state layer.
2
+ * A failed begin/resolve invalidates the run; its state must be discarded. */
3
+ export interface SpeculativeTransaction<Acceptance = number> {
4
+ canBegin(drafts: number): boolean;
5
+ begin(drafts: number): void;
6
+ resolve(accepted: Acceptance): void;
7
+ }
package/src/jobs/db.ts CHANGED
@@ -55,6 +55,10 @@ export class JobStore {
55
55
  this.dbPath = dbPath;
56
56
  this.logsDir = logsDir;
57
57
  this.db = new Database(dbPath);
58
+ // Parent submissions and child progress updates share this WAL database.
59
+ // Wait for a short writer transaction instead of failing a valid job with
60
+ // SQLITE_BUSY while the other process commits its terminal event.
61
+ this.db.exec("PRAGMA busy_timeout = 5000");
58
62
  this.db.exec("PRAGMA journal_mode = WAL");
59
63
  this.db.exec(SCHEMA);
60
64
  this.migrate();
package/src/jobs/index.ts CHANGED
@@ -8,6 +8,8 @@ export {
8
8
  getRunner,
9
9
  submitInProcess,
10
10
  submitSubprocess,
11
+ closeSubprocessJobs,
12
+ closeInProcessJobs,
11
13
  makeEmit,
12
14
  isGpuBusy,
13
15
  currentGpuJob,
@@ -7,6 +7,7 @@
7
7
  // the runner, runs it with a log-appending emit, sets terminal status, and
8
8
  // exits 0 (done) / 1 (failed).
9
9
 
10
+ import { createJobTaskClient } from "./task-client";
10
11
  import { JobStore } from "./db";
11
12
  import { getRunner, makeEmit } from "./runner";
12
13
  import type { JobRunner } from "./types";
@@ -16,9 +17,9 @@ import { runtimeValue } from "../runtime-config";
16
17
  * kinds are built by parallel efforts; importing the module is expected to
17
18
  * call `registerRunner(kind, ...)` at top level. Missing module ⇒ the job
18
19
  * fails cleanly (see resolveRunner). */
19
- const KIND_MODULES: Record<string, string> = {
20
- quantize: "../quantize/job.ts",
21
- finetune: "../train/job.ts",
20
+ const KIND_MODULES: Record<string, () => Promise<unknown>> = {
21
+ quantize: () => import("../quantize/job"),
22
+ finetune: () => import("../train/job"),
22
23
  };
23
24
 
24
25
  /** Resolve a runner for `kind`. Test kinds (noop/crash) are pre-registered in
@@ -28,19 +29,19 @@ async function resolveRunner(kind: string): Promise<JobRunner> {
28
29
  const existing = getRunner(kind);
29
30
  if (existing) return existing;
30
31
 
31
- const modPath = KIND_MODULES[kind];
32
- if (modPath) {
32
+ const load = KIND_MODULES[kind];
33
+ if (load) {
33
34
  try {
34
- await import(modPath);
35
+ await load();
35
36
  } catch (e) {
36
37
  throw new Error(
37
- `kind "${kind}": failed to load runner module ${modPath} ` +
38
+ `kind "${kind}": failed to load runner module ${kind} ` +
38
39
  `(${e instanceof Error ? e.message : String(e)})`,
39
40
  );
40
41
  }
41
42
  const loaded = getRunner(kind);
42
43
  if (loaded) return loaded;
43
- throw new Error(`kind "${kind}": module ${modPath} did not register a runner`);
44
+ throw new Error(`kind "${kind}": module ${kind} did not register a runner`);
44
45
  }
45
46
  throw new Error(`no runner registered for kind "${kind}"`);
46
47
  }
@@ -49,8 +50,7 @@ function nowIso(): string {
49
50
  return new Date().toISOString().replace("T", " ").slice(0, 19);
50
51
  }
51
52
 
52
- async function main(): Promise<void> {
53
- const jobId = process.argv[2];
53
+ export async function runJobEntry(jobId = process.argv[2]): Promise<void> {
54
54
  if (!jobId) {
55
55
  console.error("usage: bun job-entry.ts <jobId>");
56
56
  process.exit(2);
@@ -87,7 +87,7 @@ async function main(): Promise<void> {
87
87
 
88
88
  try {
89
89
  const runner = await resolveRunner(row.kind);
90
- const result = await runner(emit, config);
90
+ const result = await createJobTaskClient(runner).run(config, emit);
91
91
  const out = result?.outputPath;
92
92
  if (out) store.setOutputPath(jobId, out);
93
93
  store.setProgress(jobId, 1);
@@ -104,4 +104,4 @@ async function main(): Promise<void> {
104
104
  }
105
105
  }
106
106
 
107
- main();
107
+ if (import.meta.main) void runJobEntry();