mlx-bun 0.0.13 → 0.3.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 (427) hide show
  1. package/README.md +71 -578
  2. package/bin/mlx-bun.mjs +1 -1
  3. package/docs/README.md +91 -0
  4. package/docs/{design → archive}/hlg-sampling.md +3 -3
  5. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  6. package/docs/{design → archive/investigations}/colibri-glm52-port.md +1 -1
  7. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  8. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  9. package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
  10. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  11. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  12. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
  13. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  14. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  15. package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
  16. package/docs/{planning → archive/planning}/chunk-task-roadmap.md +1 -1
  17. package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +4 -4
  18. package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +1 -1
  19. package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
  20. package/docs/archive/planning/release-notes-v0.2.0.md +49 -0
  21. package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
  22. package/docs/design/batching.md +569 -0
  23. package/docs/design/decode-speed-program.md +3178 -169
  24. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  25. package/docs/design/generic-model-support.md +579 -334
  26. package/docs/design/kv-cache.md +680 -0
  27. package/docs/design/orpo-training.md +673 -1239
  28. package/docs/design/speculative-decoding.md +1627 -0
  29. package/docs/design/turboquant.md +2102 -0
  30. package/docs/design/unified-engine-frontier-plan.md +1831 -727
  31. package/docs/design/web-chat-redesign.md +666 -1083
  32. package/docs/planning/PRODUCT_ROADMAP.md +34 -1
  33. package/docs/planning/release-notes-v0.3.0.md +35 -0
  34. package/docs/planning/video-series.md +421 -0
  35. package/docs/reference/benchmarks.md +1162 -0
  36. package/docs/reference/cli.md +395 -149
  37. package/docs/reference/distribution.md +321 -181
  38. package/docs/reference/environment.md +348 -0
  39. package/docs/reference/glossary.md +39 -0
  40. package/docs/reference/library-api.md +580 -142
  41. package/docs/reference/memory.md +227 -64
  42. package/docs/reference/models.md +137 -6
  43. package/docs/reference/server-api.md +938 -422
  44. package/docs/reference/server-config.md +652 -320
  45. package/docs/reference/training.md +393 -254
  46. package/docs/reference/troubleshooting.md +166 -0
  47. package/package.json +10 -5
  48. package/src/admission-plan.ts +18 -0
  49. package/src/anthropic.ts +92 -3
  50. package/src/audio/decode.ts +2 -2
  51. package/src/audio/features.ts +2 -2
  52. package/src/backends/mlx/autoregressive.ts +108 -0
  53. package/src/backends/mlx/batch-group.ts +1646 -0
  54. package/src/backends/mlx/diffusion.ts +39 -0
  55. package/src/backends/mlx/draft-target.ts +47 -0
  56. package/src/backends/mlx/evaluation.ts +105 -0
  57. package/src/backends/mlx/fill-append.ts +45 -0
  58. package/src/backends/mlx/gateway-binding.ts +71 -0
  59. package/src/backends/mlx/graph.ts +38 -0
  60. package/src/backends/mlx/memory-client.ts +189 -0
  61. package/src/backends/mlx/memory-guard.ts +40 -0
  62. package/src/backends/mlx/methods.ts +90 -0
  63. package/src/backends/mlx/model-prompt.ts +164 -0
  64. package/src/backends/mlx/model-serving.ts +79 -0
  65. package/src/backends/mlx/prefill.ts +33 -0
  66. package/src/backends/mlx/request-policy.ts +20 -0
  67. package/src/backends/mlx/rollback.ts +51 -0
  68. package/src/backends/mlx/serial-executor.ts +273 -0
  69. package/src/backends/mlx/speculative.ts +114 -0
  70. package/src/backends/mlx/state-views.ts +26 -0
  71. package/src/backends/mlx/text-engine.ts +73 -0
  72. package/src/cli.ts +189 -61
  73. package/src/client.ts +66 -0
  74. package/src/config.ts +21 -4
  75. package/src/contracts/completion.ts +16 -0
  76. package/src/contracts/execution.ts +49 -0
  77. package/src/contracts/generation.ts +103 -0
  78. package/src/contracts/host.ts +7 -0
  79. package/src/contracts/jobs.ts +66 -0
  80. package/src/contracts/pi-provider.ts +30 -0
  81. package/src/contracts/pi.ts +259 -0
  82. package/src/contracts/resources.ts +18 -0
  83. package/src/contracts/scheduling.ts +27 -0
  84. package/src/contracts/tsconfig.json +14 -0
  85. package/src/diffusion/diffusion-generate.ts +218 -153
  86. package/src/embed.ts +1 -1
  87. package/src/engine/admission.ts +59 -0
  88. package/src/engine/cancellation.ts +38 -0
  89. package/src/engine/engine.ts +56 -0
  90. package/src/engine/execution-coordinator.ts +70 -0
  91. package/src/engine/execution-plan.ts +51 -0
  92. package/src/engine/resources.ts +42 -0
  93. package/src/engine/scheduler.ts +67 -0
  94. package/src/engine/session.ts +247 -0
  95. package/src/eval/README.md +44 -1
  96. package/src/eval/kl.ts +263 -23
  97. package/src/eval/reference-logits.ts +207 -0
  98. package/src/eval/runner.ts +10 -79
  99. package/src/eval/tasks/bfcl.ts +2 -1
  100. package/src/eval/tasks/gsm8k.ts +2 -1
  101. package/src/eval/tasks/hashhop.ts +2 -1
  102. package/src/eval/tasks/humaneval.ts +5 -4
  103. package/src/eval/tasks/ifeval.ts +2 -1
  104. package/src/eval/tasks/mmlu.ts +2 -1
  105. package/src/expert-io.ts +3 -1
  106. package/src/expert-offload.ts +3 -1
  107. package/src/fill/echo-index.ts +188 -0
  108. package/src/fill/fill-session.ts +452 -0
  109. package/src/fill/proposal.ts +68 -0
  110. package/src/fill/schema-rows.ts +506 -0
  111. package/src/fill/tool-boundary.ts +103 -0
  112. package/src/fit.ts +24 -43
  113. package/src/generate.ts +740 -337
  114. package/src/grammar.ts +14 -8
  115. package/src/harness-pi.ts +15 -34
  116. package/src/hub-rest.ts +4 -4
  117. package/src/index.ts +27 -0
  118. package/src/inference/denoising.ts +17 -0
  119. package/src/inference/graph.ts +33 -0
  120. package/src/inference/prefill.ts +39 -0
  121. package/src/inference/rollback.ts +7 -0
  122. package/src/jobs/db.ts +4 -0
  123. package/src/jobs/index.ts +2 -0
  124. package/src/jobs/job-entry.ts +15 -14
  125. package/src/jobs/runner.ts +98 -13
  126. package/src/jobs/task-client.ts +19 -0
  127. package/src/jobs/types.ts +2 -58
  128. package/src/kv-scheme.ts +199 -0
  129. package/src/kv-store.ts +459 -234
  130. package/src/lab/README.md +18 -0
  131. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  132. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  133. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +7 -5
  134. package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
  135. package/src/library.ts +40 -0
  136. package/src/lora.ts +18 -0
  137. package/src/media-fetch.ts +20 -4
  138. package/src/memory/article.ts +1 -1
  139. package/src/memory/chunk.ts +1 -1
  140. package/src/memory/model.ts +32 -170
  141. package/src/memory/prompts.ts +1 -1
  142. package/src/memory/rest.ts +1 -1
  143. package/src/memory/schedule.ts +1 -1
  144. package/src/memory/stages.ts +4 -1
  145. package/src/memory/vault.ts +3 -4
  146. package/src/mlx/array.ts +9 -10
  147. package/src/mlx/compile.ts +12 -2
  148. package/src/mlx/ffi.ts +66 -22
  149. package/src/mlx/materialize.ts +23 -0
  150. package/src/mlx/metal-kernel.ts +10 -11
  151. package/src/mlx/ops.ts +64 -19
  152. package/src/mlx/quantized-rows.ts +36 -0
  153. package/src/mlx/token-bitmask.ts +52 -0
  154. package/src/mlx/turboquant-kv-decode.ts +82 -0
  155. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  156. package/src/mlx/turboquant-ops.ts +33 -3
  157. package/src/mlx/turboquant-tables.ts +2 -2
  158. package/src/model/batched-mask.ts +9 -3
  159. package/src/model/batched-quant.ts +2 -2
  160. package/src/model/batched-rotating-quant.ts +45 -99
  161. package/src/model/batched-rotating-state.ts +73 -0
  162. package/src/model/batched-rotating.ts +57 -106
  163. package/src/model/batched-row-storage.ts +127 -0
  164. package/src/model/compiled-decode.ts +4 -3
  165. package/src/model/diffusion-gemma.ts +8 -8
  166. package/src/model/factory.ts +87 -49
  167. package/src/model/fingerprint.ts +1 -1
  168. package/src/model/flash-attention.ts +3 -3
  169. package/src/model/gemma4-base.ts +187 -17
  170. package/src/model/gemma4.ts +6 -6
  171. package/src/model/generated/gemma4-12b.ts +52 -148
  172. package/src/model/generated/gemma4-26b.ts +34 -94
  173. package/src/model/generated/gemma4-e4b.ts +28 -76
  174. package/src/model/glm52-cache.ts +19 -9
  175. package/src/model/glm52-dsa.ts +13 -9
  176. package/src/model/glm52-memory.ts +28 -1
  177. package/src/model/implementation.ts +69 -0
  178. package/src/model/minicpm5.ts +7 -8
  179. package/src/model/profile.ts +443 -0
  180. package/src/model/qwen-append.ts +12 -0
  181. package/src/model/qwen-conv.ts +52 -0
  182. package/src/model/qwen3-delta.ts +98 -2
  183. package/src/model/qwen3-mrope.ts +252 -0
  184. package/src/model/qwen3_5-checkpoint.ts +164 -0
  185. package/src/model/qwen3_5.ts +336 -60
  186. package/src/model/support.ts +1 -1
  187. package/src/model/trellis-balanced-scatter.ts +51 -0
  188. package/src/model/trellis-linear.ts +672 -0
  189. package/src/model/trellis-shared-m.ts +151 -0
  190. package/src/model/trellis-shared-scatter.ts +144 -0
  191. package/src/model/trellis-splitk-prefill.ts +158 -0
  192. package/src/model/trellis-tiled-prefill.ts +136 -0
  193. package/src/model/trellis-vector-expand.ts +62 -0
  194. package/src/model/trellis-wide-prefill.ts +94 -0
  195. package/src/model/universal/dense.ts +1 -1
  196. package/src/model/universal/modules.ts +8 -1
  197. package/src/native/frame_extract.swift +140 -0
  198. package/src/native-pack.ts +15 -7
  199. package/src/pi-provider.ts +6 -64
  200. package/src/pi-web.ts +14 -320
  201. package/src/prompt-cache.ts +97 -54
  202. package/src/quantize/allocator.ts +1 -1
  203. package/src/quantize/atomic-output.ts +38 -0
  204. package/src/quantize/calibration.ts +2 -1
  205. package/src/quantize/config-writer.ts +16 -3
  206. package/src/quantize/index.ts +28 -1
  207. package/src/quantize/job.ts +11 -0
  208. package/src/quantize/quantizer.ts +265 -100
  209. package/src/quantize/rotate.ts +603 -0
  210. package/src/quantize/safetensors-writer.ts +79 -1
  211. package/src/quantize/sensitivity.ts +41 -59
  212. package/src/quantize/trellis.ts +586 -0
  213. package/src/quantize/weight-transform.ts +292 -0
  214. package/src/responses.ts +130 -3
  215. package/src/runtime-config.ts +81 -0
  216. package/src/sampler.ts +276 -4
  217. package/src/serve/admin-routes.ts +184 -0
  218. package/src/serve/aux-routes.ts +132 -0
  219. package/src/serve/batch-scheduler.ts +8 -1558
  220. package/src/serve/chat-request.ts +391 -0
  221. package/src/serve/chat-stage.ts +195 -0
  222. package/src/serve/checkpoint-identity.ts +64 -0
  223. package/src/serve/completion-executor.ts +354 -0
  224. package/src/serve/completion-sink.ts +157 -0
  225. package/src/serve/discovery-routes.ts +204 -0
  226. package/src/serve/generation-gateway.ts +211 -243
  227. package/src/serve/http.ts +159 -0
  228. package/src/serve/inference-request.ts +79 -0
  229. package/src/serve/isolate.ts +297 -105
  230. package/src/serve/kv-budget.ts +14 -0
  231. package/src/serve/lab-routes.ts +341 -0
  232. package/src/serve/lane-registry.ts +2 -1
  233. package/src/serve/model-admin-routes.ts +155 -0
  234. package/src/serve/model-binding.ts +43 -0
  235. package/src/serve/model-host.ts +512 -0
  236. package/src/serve/openai-wire.ts +103 -0
  237. package/src/serve/parent-application.ts +56 -0
  238. package/src/serve/pipeline.ts +33 -0
  239. package/src/serve/preparation.ts +33 -0
  240. package/src/serve/prompt-response-trace.ts +147 -0
  241. package/src/serve/request-plan.ts +162 -0
  242. package/src/serve/request-prep.ts +346 -0
  243. package/src/serve/response-lease.ts +24 -0
  244. package/src/serve/responses-client.ts +69 -0
  245. package/src/serve/session-completion-engine.ts +110 -0
  246. package/src/serve/session-search.ts +1 -1
  247. package/src/serve/static-routes.ts +101 -0
  248. package/src/serve/text-completion-stage.ts +104 -0
  249. package/src/serve/token-streams.ts +519 -0
  250. package/src/server.ts +523 -3551
  251. package/src/spec/assistant-source.ts +10 -44
  252. package/src/spec/deepspec-source.ts +6 -6
  253. package/src/spec/dflash-source.ts +9 -8
  254. package/src/spec/dspark/ab-stats.ts +3 -3
  255. package/src/spec/dspark/calibration.ts +2 -2
  256. package/src/spec/dspark/deepspec-module.ts +2 -2
  257. package/src/spec/dspark/generate-dflash.ts +2 -2
  258. package/src/spec/dspark/generate.ts +2 -2
  259. package/src/spec/dspark/loader.ts +1 -1
  260. package/src/spec/dspark/module-dflash.ts +5 -4
  261. package/src/spec/dspark/module.ts +3 -3
  262. package/src/spec/dspark/quantize-drafter.ts +1 -1
  263. package/src/spec/generate.ts +1 -1
  264. package/src/spec/glm52-mtp-source.ts +9 -1
  265. package/src/spec/ngram-source.ts +1 -1
  266. package/src/spec/prefix-state.ts +45 -0
  267. package/src/spec/qwen-mtp-source.ts +528 -0
  268. package/src/spec/serve-loop.ts +179 -213
  269. package/src/spec/source.ts +42 -10
  270. package/src/spec/two-model.ts +1 -1
  271. package/src/ssd-cache.ts +95 -24
  272. package/src/ssd-durability.ts +207 -0
  273. package/src/tool-call.ts +51 -14
  274. package/src/train/flash-cce.ts +14 -13
  275. package/src/train/forward.ts +38 -1
  276. package/src/train/loss.ts +3 -2
  277. package/src/train/prefix-shared.ts +5 -1
  278. package/src/train/segmented.ts +9 -6
  279. package/src/train/trainer.ts +9 -8
  280. package/src/vision/preprocess.ts +1 -1
  281. package/src/vision/prompt.ts +48 -2
  282. package/src/vision/qwen3vl-preprocess.ts +409 -0
  283. package/src/vision/qwen3vl-prompt.ts +196 -0
  284. package/src/vision/qwen3vl-tower.ts +555 -0
  285. package/src/vision/video-frames.ts +148 -0
  286. package/src/web/app.html +1 -1
  287. package/src/web/app.js +15 -6
  288. package/src/web/src/adapters-panel.ts +3 -3
  289. package/src/web/src/assistant.ts +2 -36
  290. package/src/web/src/chat.ts +16 -9
  291. package/src/web/src/composer.ts +4 -4
  292. package/src/web/src/hub.ts +1 -1
  293. package/src/web/src/markdown.ts +0 -0
  294. package/src/web/src/memory-panel.ts +1 -1
  295. package/src/web/src/model-picker.ts +1 -1
  296. package/src/web/src/palette.ts +1 -1
  297. package/src/web/src/protocol.ts +3 -39
  298. package/src/web/src/sessions.ts +1 -1
  299. package/src/web/src/ui-catalog.ts +4 -18
  300. package/src/web-assets.ts +47 -0
  301. package/src/weights.ts +134 -33
  302. package/docs/archive/mlx-bun-lab-report.html +0 -275
  303. package/docs/archive/wwdc-mlx-bun.html +0 -848
  304. package/docs/design/adapters-end-to-end.md +0 -205
  305. package/docs/design/batching-perf-path.md +0 -255
  306. package/docs/design/batching-v2-plan.md +0 -529
  307. package/docs/design/bucketing-stage.md +0 -197
  308. package/docs/design/compat-cli-surface-design.md +0 -230
  309. package/docs/design/docs-reorg-plan.md +0 -165
  310. package/docs/design/dspark-serving-program.md +0 -371
  311. package/docs/design/dspark-speculative-decoding.md +0 -268
  312. package/docs/design/grammar-spec-batching-integration.md +0 -301
  313. package/docs/design/memory-inference-path.md +0 -422
  314. package/docs/design/memory-synthesis.md +0 -287
  315. package/docs/design/memory-system.md +0 -237
  316. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  317. package/docs/design/omlx-adoption-map.md +0 -98
  318. package/docs/design/orpo-dynamic-lambda.md +0 -220
  319. package/docs/design/orpo-future-enhancements.md +0 -340
  320. package/docs/design/paged-kv-cache.md +0 -214
  321. package/docs/design/parallel-slots.md +0 -567
  322. package/docs/design/parity-tier-dag.md +0 -161
  323. package/docs/design/repo-cleanup-plan.md +0 -189
  324. package/docs/design/runtime-isolation.md +0 -263
  325. package/docs/design/segmented-backward-training.md +0 -543
  326. package/docs/design/spec-decode-larger-targets.md +0 -229
  327. package/docs/design/ssd-kv-cold-tier.md +0 -288
  328. package/docs/design/structured-output.md +0 -484
  329. package/docs/design/tauri-desktop-app.md +0 -127
  330. package/docs/design/the-dreaming-master-plan.md +0 -445
  331. package/docs/design/turboquant-kv.md +0 -235
  332. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  333. package/docs/design/web-chat-beat-matrix.md +0 -315
  334. package/docs/design/write-pipeline-entity.md +0 -468
  335. package/docs/investigations/curve-runs/bisector-route.json +0 -98
  336. package/docs/investigations/curve-runs/bisector-trace.json +0 -1393
  337. package/docs/investigations/curve-runs/curve-terrain.json +0 -1179
  338. package/docs/investigations/curve-runs/curve-terrain.svg +0 -42
  339. package/docs/investigations/hlg-ab.html +0 -34
  340. package/docs/investigations/hlg-explorer.html +0 -238
  341. package/docs/investigations/hlg-figs/cliff.svg +0 -1
  342. package/docs/investigations/hlg-figs/cross.svg +0 -1
  343. package/docs/investigations/hlg-figs/edges.svg +0 -1
  344. package/docs/investigations/hlg-figs/k20-grids.svg +0 -1
  345. package/docs/investigations/hlg-figs/k20-peaks.svg +0 -1
  346. package/docs/investigations/hlg-figs/lw-curve.svg +0 -1
  347. package/docs/investigations/hlg-figs/terrain.svg +0 -1
  348. package/docs/investigations/hlg-report.html +0 -262
  349. package/docs/investigations/hlg-runs/hlg-ab.json +0 -149
  350. package/docs/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  351. package/docs/investigations/hlg-runs/hlg-blind.json +0 -107
  352. package/docs/investigations/hlg-runs/hlg-cliff.json +0 -197
  353. package/docs/investigations/hlg-runs/hlg-cross.json +0 -505
  354. package/docs/investigations/hlg-runs/hlg-edge.json +0 -388
  355. package/docs/investigations/hlg-runs/hlg-eval1.json +0 -25
  356. package/docs/investigations/hlg-runs/hlg-frontier.json +0 -86
  357. package/docs/investigations/hlg-runs/hlg-grid.json +0 -242
  358. package/docs/investigations/hlg-runs/hlg-grid2.json +0 -343
  359. package/docs/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  360. package/docs/investigations/hlg-runs/hlg-map.json +0 -383
  361. package/docs/investigations/hlg-runs/run0-original.log +0 -159
  362. package/docs/investigations/hlg-runs/runA-recommended.log +0 -131
  363. package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  364. package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  365. package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  366. package/docs/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  367. package/docs/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  368. package/docs/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  369. package/docs/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  370. package/docs/investigations/hlg-runs/runB-gain-variants.log +0 -192
  371. package/docs/investigations/hlg-runs/runC-pivots.log +0 -162
  372. package/docs/investigations/hlg-runs/runD-oetf.log +0 -132
  373. package/docs/investigations/hlg-runs/runE-eotf.log +0 -162
  374. package/docs/investigations/hlg-runs/runF-shaper-working.log +0 -86
  375. package/docs/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  376. package/docs/investigations/hlg-runs/runH-wsweep.log +0 -176
  377. package/docs/investigations/hlg-runs/runI-asweep.log +0 -176
  378. package/docs/investigations/hlg-runs/runJ-knobmap.log +0 -49
  379. package/docs/investigations/hlg-runs/runK-frontier.log +0 -19
  380. package/docs/investigations/hlg-runs/runL-widemap.log +0 -65
  381. package/docs/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  382. package/docs/investigations/hlg-runs/runN-verify.log +0 -116
  383. package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  384. package/docs/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  385. package/docs/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  386. package/docs/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  387. package/docs/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  388. package/docs/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  389. package/docs/investigations/hlg-runs/runU-cross-12b.log +0 -33
  390. package/docs/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  391. package/docs/investigations/hlg-runs/runW-lw-12b.log +0 -22
  392. package/docs/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  393. package/docs/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  394. package/docs/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  395. package/docs/planning/IDEAS.md +0 -69
  396. package/docs/reference/embedding.md +0 -197
  397. package/docs/reference/features-matrix.md +0 -100
  398. package/docs/reference/orpo-quickstart.md +0 -135
  399. package/src/flags.ts +0 -13
  400. /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
  401. /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
  402. /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
  403. /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
  404. /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
  405. /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
  406. /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
  407. /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
  408. /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
  409. /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
  410. /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
  411. /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
  412. /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
  413. /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
  414. /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
  415. /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
  416. /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
  417. /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
  418. /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
  419. /package/docs/{planning → archive/planning}/journal.md +0 -0
  420. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  421. /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
  422. /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
  423. /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
  424. /package/docs/{planning → archive/planning}/release-notes-v0.0.13.md +0 -0
  425. /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
  426. /package/{docs/investigations → src/serve/assets}/curve-terrain.html +0 -0
  427. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -0,0 +1,341 @@
1
+ import type { JobStore } from "../jobs";
2
+
3
+ export interface LabRouteDeps {
4
+ ensureJobs(): Promise<JobStore>;
5
+ acquireGpu?: (signal: AbortSignal) => Promise<import("../contracts/resources").DisposableResource>;
6
+ serverPort(): number | undefined;
7
+ invalidateLibrary(): void;
8
+ }
9
+
10
+ export type LabRoute =
11
+ | "dataset-templates"
12
+ | "dataset-submit"
13
+ | "quantize-inspect"
14
+ | "model-resolve-folder"
15
+ | "quantize-submit"
16
+ | "finetune-inspect-dataset"
17
+ | "finetune-submit"
18
+ | "finetune-merge"
19
+ | "finetune-export";
20
+
21
+ export function matchLabRoute(method: string, pathname: string): LabRoute | null {
22
+ switch (`${method} ${pathname}`) {
23
+ case "GET /api/dataset/templates": return "dataset-templates";
24
+ case "POST /api/dataset/submit": return "dataset-submit";
25
+ case "POST /api/quantize/inspect": return "quantize-inspect";
26
+ case "POST /api/quantize/resolve-folder":
27
+ case "POST /api/model/resolve-folder":
28
+ return "model-resolve-folder";
29
+ case "POST /api/quantize/submit": return "quantize-submit";
30
+ case "POST /api/finetune/inspect-dataset": return "finetune-inspect-dataset";
31
+ case "POST /api/finetune/submit": return "finetune-submit";
32
+ case "POST /api/finetune/merge": return "finetune-merge";
33
+ case "POST /api/finetune/export": return "finetune-export";
34
+ default: return null;
35
+ }
36
+ }
37
+
38
+ export async function handleLabRoute(
39
+ url: URL,
40
+ request: Request,
41
+ deps: LabRouteDeps,
42
+ ): Promise<Response | null> {
43
+ switch (matchLabRoute(request.method, url.pathname)) {
44
+ case "dataset-templates": {
45
+ const { TEMPLATES } = await import("../dataset");
46
+ return Response.json({ templates: TEMPLATES });
47
+ }
48
+ case "dataset-submit": {
49
+ const body = (await request.json().catch(() => ({}))) as {
50
+ template_id?: string;
51
+ inputs?: Record<string, unknown>;
52
+ model_name?: string;
53
+ };
54
+ const { getTemplate } = await import("../dataset");
55
+ if (!body.template_id || !getTemplate(body.template_id)) {
56
+ return Response.json(
57
+ { ok: false, error: `unknown template ${body.template_id}` },
58
+ { status: 400 },
59
+ );
60
+ }
61
+ const store = await deps.ensureJobs();
62
+ const { submitInProcess } = await import("../jobs");
63
+ const { homedir } = await import("node:os");
64
+ const safe = body.template_id.replace(/[^a-z0-9_-]/gi, "");
65
+ const outDir = `${homedir()}/.cache/mlx-bun/datasets/dataset-${safe}-${Date.now()}`;
66
+ const { jobId } = submitInProcess(store, "dataset", {
67
+ template_id: body.template_id,
68
+ inputs: body.inputs ?? {},
69
+ output_dir: outDir,
70
+ api_url: `http://127.0.0.1:${deps.serverPort()}`,
71
+ model_name: body.model_name ?? "local",
72
+ }, outDir);
73
+ return Response.json({ ok: true, job_id: jobId, output_dir: outDir });
74
+ }
75
+ case "quantize-inspect": {
76
+ const body = (await request.json().catch(() => ({}))) as { model_id?: string };
77
+ const { inspectModel } = await import("../quantize");
78
+ return Response.json(await inspectModel(body.model_id ?? ""));
79
+ }
80
+ case "model-resolve-folder":
81
+ return resolveModelFolder(request);
82
+ case "quantize-submit":
83
+ return submitQuantize(request, deps);
84
+ case "finetune-inspect-dataset": {
85
+ const body = (await request.json().catch(() => ({}))) as { path?: string };
86
+ const { inspectDataset } = await import("../train");
87
+ return Response.json(await inspectDataset(body.path ?? ""));
88
+ }
89
+ case "finetune-submit": {
90
+ const body = (await request.json().catch(() => ({}))) as Record<string, unknown>;
91
+ if (!body.model_dir || !body.data_dir) {
92
+ return Response.json(
93
+ { ok: false, error: "model_dir and data_dir required" },
94
+ { status: 400 },
95
+ );
96
+ }
97
+ const store = await deps.ensureJobs();
98
+ const { submitSubprocess } = await import("../jobs");
99
+ const { homedir } = await import("node:os");
100
+ const adapterPath = (body.adapter_path as string) ||
101
+ `${homedir()}/.cache/mlx-bun/adapters/adapter-${Date.now()}`;
102
+ const { jobId } = submitSubprocess(
103
+ store,
104
+ "finetune",
105
+ { ...body, adapter_path: adapterPath },
106
+ adapterPath,
107
+ { acquire: deps.acquireGpu },
108
+ );
109
+ return Response.json({ ok: true, job_id: jobId, adapter_path: adapterPath });
110
+ }
111
+ case "finetune-merge": {
112
+ const body = (await request.json().catch(() => ({}))) as {
113
+ adapter_a?: string;
114
+ adapter_b?: string;
115
+ scales?: number[];
116
+ };
117
+ if (!body.adapter_a || !body.adapter_b) {
118
+ return Response.json(
119
+ { ok: false, error: "adapter_a and adapter_b required" },
120
+ { status: 400 },
121
+ );
122
+ }
123
+ try {
124
+ const { mergeAdapters } = await import("../train");
125
+ const { homedir } = await import("node:os");
126
+ const mergedPath = `${homedir()}/.cache/mlx-bun/adapters/merged-${Date.now()}`;
127
+ const stats = await mergeAdapters(
128
+ [body.adapter_a, body.adapter_b],
129
+ mergedPath,
130
+ body.scales,
131
+ );
132
+ return Response.json({ ok: true, merged_path: mergedPath, stats });
133
+ } catch (error) {
134
+ return Response.json({ ok: false, error: (error as Error).message }, { status: 400 });
135
+ }
136
+ }
137
+ case "finetune-export": {
138
+ const body = (await request.json().catch(() => ({}))) as {
139
+ base_model?: string;
140
+ adapter_path?: string;
141
+ method?: string;
142
+ };
143
+ if (!body.base_model || !body.adapter_path) {
144
+ return Response.json(
145
+ { ok: false, error: "base_model and adapter_path required" },
146
+ { status: 400 },
147
+ );
148
+ }
149
+ try {
150
+ const { exportAdapter } = await import("../train");
151
+ const { homedir } = await import("node:os");
152
+ const exportPath = `${homedir()}/.cache/mlx-bun/exports/export-${Date.now()}`;
153
+ const manifest = await exportAdapter(
154
+ exportPath,
155
+ body.base_model,
156
+ body.adapter_path,
157
+ body.method,
158
+ );
159
+ return Response.json({ ok: true, export_path: exportPath, manifest });
160
+ } catch (error) {
161
+ return Response.json({ ok: false, error: (error as Error).message }, { status: 400 });
162
+ }
163
+ }
164
+ default:
165
+ return null;
166
+ }
167
+ }
168
+
169
+ async function resolveModelFolder(request: Request): Promise<Response> {
170
+ const body = (await request.json().catch(() => ({}))) as {
171
+ folder_name?: string;
172
+ rel_path?: string;
173
+ };
174
+ const { statSync, readdirSync, readFileSync } = await import("node:fs");
175
+ const { join } = await import("node:path");
176
+ const { homedir } = await import("node:os");
177
+ const hubRoot = process.env.HF_HUB_CACHE ??
178
+ (process.env.HF_HOME
179
+ ? join(process.env.HF_HOME, "hub")
180
+ : join(homedir(), ".cache/huggingface/hub"));
181
+ const roots = [hubRoot, join(homedir(), ".cache/mlx-bun")];
182
+ const hasConfig = (dir: string) => {
183
+ try {
184
+ return statSync(join(dir, "config.json")).isFile();
185
+ } catch {
186
+ return false;
187
+ }
188
+ };
189
+ const folder = (body.folder_name ?? "")
190
+ .replace(/\\/g, "/")
191
+ .split("/")
192
+ .filter(Boolean)
193
+ .pop() ?? "";
194
+ const relSegments = (body.rel_path ?? "")
195
+ .replace(/\\/g, "/")
196
+ .split("/")
197
+ .filter(Boolean);
198
+ const configDir = relSegments.length >= 2 ? relSegments[relSegments.length - 2] : "";
199
+ const repoIdOf = (modelsDir: string) =>
200
+ modelsDir.slice("models--".length).replaceAll("--", "/");
201
+ const pickSnapshot = (repoDir: string): string | null => {
202
+ const snapshots = join(repoDir, "snapshots");
203
+ let head = "";
204
+ try {
205
+ head = readFileSync(join(repoDir, "refs", "main"), "utf8").trim();
206
+ } catch {}
207
+ if (head && hasConfig(join(snapshots, head))) return join(snapshots, head);
208
+ try {
209
+ for (const hash of readdirSync(snapshots)) {
210
+ if (hasConfig(join(snapshots, hash))) return join(snapshots, hash);
211
+ }
212
+ } catch {}
213
+ return null;
214
+ };
215
+
216
+ if (folder.startsWith("models--")) {
217
+ const path = pickSnapshot(join(hubRoot, folder));
218
+ if (path) return Response.json({ ok: true, path, repo_id: repoIdOf(folder) });
219
+ }
220
+
221
+ const hashDir = configDir || folder;
222
+ if (hashDir) {
223
+ try {
224
+ for (const repo of readdirSync(hubRoot)) {
225
+ if (!repo.startsWith("models--")) continue;
226
+ const candidate = join(hubRoot, repo, "snapshots", hashDir);
227
+ if (hasConfig(candidate)) {
228
+ return Response.json({ ok: true, path: candidate, repo_id: repoIdOf(repo) });
229
+ }
230
+ }
231
+ } catch {}
232
+ }
233
+
234
+ for (const root of roots) {
235
+ if (folder && hasConfig(join(root, folder))) {
236
+ return Response.json({ ok: true, path: join(root, folder) });
237
+ }
238
+ }
239
+
240
+ const { Registry } = await import("../registry");
241
+ const registry = new Registry();
242
+ try {
243
+ await registry.scan();
244
+ const all = registry.list();
245
+ const record = (folder.startsWith("models--")
246
+ ? all.find((model) => model.repoId === repoIdOf(folder))
247
+ : undefined) ??
248
+ all.find((model) => model.path.split("/").pop() === hashDir) ??
249
+ all.find((model) => model.repoId.split("/").pop() === folder);
250
+ if (record) {
251
+ return Response.json({
252
+ ok: true,
253
+ path: record.path,
254
+ repo_id: record.repoId,
255
+ model_type: record.modelType,
256
+ });
257
+ }
258
+ } finally {
259
+ registry.close();
260
+ }
261
+ return Response.json({
262
+ ok: false,
263
+ error: "Couldn't locate this folder on disk — paste the path instead.",
264
+ });
265
+ }
266
+
267
+ async function submitQuantize(request: Request, deps: LabRouteDeps): Promise<Response> {
268
+ const body = (await request.json().catch(() => ({}))) as {
269
+ model_id?: string;
270
+ bits?: number;
271
+ group_size?: number;
272
+ target_bpw?: number;
273
+ candidate_bits?: number[];
274
+ reference?: string;
275
+ calibration_mix?: string;
276
+ n_calibration?: number;
277
+ rotate_weights?: boolean;
278
+ rotation_seed?: number;
279
+ };
280
+ if (!body.model_id)
281
+ return Response.json({ ok: false, error: "model_id required" }, { status: 400 });
282
+ const store = await deps.ensureJobs();
283
+ const { submitSubprocess } = await import("../jobs");
284
+ const { homedir } = await import("node:os");
285
+ const { join } = await import("node:path");
286
+ const { mkdirSync, writeFileSync } = await import("node:fs");
287
+ const { createHash } = await import("node:crypto");
288
+ const bits = body.bits ?? 4;
289
+ const groupSize = body.group_size ?? 64;
290
+ const snapshotMatch = body.model_id.match(/(models--[^/]+)\/snapshots\//);
291
+ let org = "local";
292
+ let name: string;
293
+ if (snapshotMatch) {
294
+ const parts = snapshotMatch[1]!.split("--");
295
+ org = parts[1] ?? "local";
296
+ name = parts.slice(2).join("--");
297
+ } else if (
298
+ body.model_id.includes("/") &&
299
+ !body.model_id.startsWith("/") &&
300
+ !body.model_id.startsWith("~")
301
+ ) {
302
+ const segments = body.model_id.split("/");
303
+ org = segments[0]!;
304
+ name = segments.slice(1).join("-");
305
+ } else {
306
+ name = body.model_id.split("/").filter(Boolean).at(-1) ?? "model";
307
+ }
308
+ name = (name || "model").replace(/[^a-z0-9_.-]/gi, "");
309
+ org = (org || "local").replace(/[^a-z0-9_.-]/gi, "");
310
+ const suffix = `${body.target_bpw ? `mixed-${body.target_bpw}bpw` : `${bits}bit`}` +
311
+ `${body.rotate_weights ? `-rot${body.rotation_seed ?? 42}` : ""}`;
312
+ const quantRepo = `${name}-OptiQ-${suffix}`;
313
+ const hubRoot = process.env.HF_HUB_CACHE ??
314
+ (process.env.HF_HOME
315
+ ? join(process.env.HF_HOME, "hub")
316
+ : join(homedir(), ".cache/huggingface/hub"));
317
+ const repoDir = join(hubRoot, `models--${org}--${quantRepo}`);
318
+ const snapshotHash = createHash("sha1").update(`${org}/${quantRepo}`).digest("hex");
319
+ const outDir = join(repoDir, "snapshots", snapshotHash);
320
+ try {
321
+ mkdirSync(join(repoDir, "refs"), { recursive: true });
322
+ writeFileSync(join(repoDir, "refs", "main"), snapshotHash);
323
+ } catch {}
324
+ const { jobId } = submitSubprocess(store, "quantize", {
325
+ model_id: body.model_id,
326
+ out_dir: outDir,
327
+ bits,
328
+ group_size: groupSize,
329
+ target_bpw: body.target_bpw,
330
+ candidate_bits: body.candidate_bits,
331
+ reference: body.reference,
332
+ calibration_mix: body.calibration_mix,
333
+ n_calibration: body.n_calibration,
334
+ rotate_weights: body.rotate_weights,
335
+ rotation_seed: body.rotation_seed,
336
+ }, outDir, {
337
+ acquire: deps.acquireGpu,
338
+ onComplete: () => deps.invalidateLibrary(),
339
+ });
340
+ return Response.json({ ok: true, job_id: jobId, output_dir: outDir });
341
+ }
@@ -16,7 +16,8 @@
16
16
  // a same-process debugging/telemetry aid, not a durable store — entries for
17
17
  // long-dead requests must not leak memory over a long-running server.
18
18
 
19
- export type Lane = "serial" | "serial+spec" | "batched";
19
+ import type { Lane } from "../contracts/pi";
20
+ export type { Lane } from "../contracts/pi";
20
21
 
21
22
  const MAX_ENTRIES = 512;
22
23
  const lanes = new Map<string, Lane>();
@@ -0,0 +1,155 @@
1
+ import { modelServingBinding } from "../backends/mlx/model-serving";
2
+ import type { ServingContext } from "./model-host";
3
+ import type { GenerationGateway } from "./generation-gateway";
4
+ import { listAvailableAdapters } from "../lora";
5
+
6
+ export type ModelAdminRoute =
7
+ | { kind: "embeddings" }
8
+ | { kind: "adapters-available" }
9
+ | { kind: "adapters-list" }
10
+ | { kind: "adapters-mount" }
11
+ | { kind: "adapters-unmount"; id: string };
12
+
13
+ export function matchModelAdminRoute(method: string, pathname: string): ModelAdminRoute | null {
14
+ switch (`${method} ${pathname}`) {
15
+ case "POST /v1/embeddings": return { kind: "embeddings" };
16
+ case "GET /v1/adapters/available": return { kind: "adapters-available" };
17
+ case "GET /v1/adapters": return { kind: "adapters-list" };
18
+ case "POST /v1/adapters": return { kind: "adapters-mount" };
19
+ }
20
+ if (method === "DELETE" && pathname.startsWith("/v1/adapters/")) {
21
+ return {
22
+ kind: "adapters-unmount",
23
+ id: decodeURIComponent(pathname.slice("/v1/adapters/".length)),
24
+ };
25
+ }
26
+ return null;
27
+ }
28
+
29
+ export async function handleModelAdminRoute(
30
+ url: URL,
31
+ request: Request,
32
+ ctx: ServingContext,
33
+ gateway: Pick<GenerationGateway, "runExclusive">,
34
+ ): Promise<Response | null> {
35
+ const route = matchModelAdminRoute(request.method, url.pathname);
36
+ if (!route) return null;
37
+
38
+ switch (route.kind) {
39
+ case "embeddings": {
40
+ const binding = modelServingBinding(ctx);
41
+ const embed = binding.embed?.bind(binding);
42
+ if (!embed) {
43
+ return Response.json({
44
+ error: {
45
+ message: `served model "${ctx.modelId}" is not an embedding model; ` +
46
+ "serve an embedding model (e.g. Qwen3-Embedding) to use /v1/embeddings",
47
+ type: "invalid_request_error",
48
+ },
49
+ }, { status: 400 });
50
+ }
51
+ let body: { input?: string | string[]; instruction?: string };
52
+ try {
53
+ body = (await request.json()) as typeof body;
54
+ } catch {
55
+ return Response.json({ error: { message: "invalid JSON body" } }, { status: 400 });
56
+ }
57
+ const inputs = Array.isArray(body.input)
58
+ ? body.input
59
+ : body.input != null
60
+ ? [body.input]
61
+ : [];
62
+ if (inputs.length === 0 || !inputs.every((input) => typeof input === "string")) {
63
+ return Response.json({
64
+ error: {
65
+ message: "`input` must be a string or array of strings",
66
+ type: "invalid_request_error",
67
+ },
68
+ }, { status: 400 });
69
+ }
70
+ const instruction = typeof body.instruction === "string" ? body.instruction : undefined;
71
+ const results = await gateway.runExclusive(async () => embed(inputs, instruction), undefined, request.signal);
72
+ let totalTokens = 0;
73
+ const data = results.map((result, index) => {
74
+ totalTokens += result.tokens;
75
+ return { object: "embedding", index, embedding: Array.from(result.vector) };
76
+ });
77
+ return Response.json({
78
+ object: "list",
79
+ data,
80
+ model: ctx.modelId,
81
+ usage: { prompt_tokens: totalTokens, total_tokens: totalTokens },
82
+ });
83
+ }
84
+
85
+ case "adapters-available": {
86
+ const { homedir } = await import("node:os");
87
+ const stores = [
88
+ `${homedir()}/.cache/mlx-bun-finetunes`,
89
+ `${homedir()}/.cache/mlx-bun/adapters`,
90
+ ];
91
+ const mounted = new Set(ctx.adapters.list().map((adapter) => adapter.id));
92
+ const bareName = (value: string) => value.split("/").pop()!.toLowerCase();
93
+ const servedName = bareName(ctx.modelId);
94
+ const adapters = (await listAvailableAdapters(stores)).map((adapter) => ({
95
+ id: adapter.id,
96
+ path: adapter.path,
97
+ rank: adapter.rank,
98
+ scale: adapter.scale,
99
+ base_model: adapter.baseModel,
100
+ mounted: mounted.has(adapter.id),
101
+ compatible: adapter.baseModel == null || bareName(adapter.baseModel) === servedName,
102
+ }));
103
+ return Response.json({ adapters });
104
+ }
105
+
106
+ case "adapters-list":
107
+ return Response.json({
108
+ adapters: ctx.adapters.list().map((adapter) => ({
109
+ id: adapter.id,
110
+ path: adapter.path,
111
+ rank: adapter.rank,
112
+ scale: adapter.scale,
113
+ size_bytes: adapter.sizeBytes,
114
+ mounted_layers: adapter.mountedLayers,
115
+ ram_bytes: adapter.ramBytes,
116
+ })),
117
+ });
118
+
119
+ case "adapters-mount": {
120
+ let body: { id?: string; path?: string };
121
+ try {
122
+ body = (await request.json()) as typeof body;
123
+ } catch {
124
+ return Response.json({ error: { message: "invalid JSON body" } }, { status: 400 });
125
+ }
126
+ if (!body.id || !body.path) {
127
+ return Response.json({ error: { message: "id and path required" } }, { status: 400 });
128
+ }
129
+ try {
130
+ const info = await gateway.runExclusive(() =>
131
+ ctx.adapters.mount(body.id!, body.path!),
132
+ );
133
+ return Response.json({
134
+ id: info.id,
135
+ mounted_layers: info.mountedLayers,
136
+ rank: info.rank,
137
+ scale: info.scale,
138
+ ram_bytes: info.ramBytes,
139
+ });
140
+ } catch (error) {
141
+ return Response.json({ error: { message: (error as Error).message } }, { status: 400 });
142
+ }
143
+ }
144
+
145
+ case "adapters-unmount": {
146
+ const removed = await gateway.runExclusive(async () => ctx.adapters.unmount(route.id));
147
+ return removed > 0
148
+ ? Response.json({ id: route.id, removed_layers: removed })
149
+ : Response.json(
150
+ { error: { message: `adapter ${route.id} not mounted` } },
151
+ { status: 404 },
152
+ );
153
+ }
154
+ }
155
+ }
@@ -0,0 +1,43 @@
1
+ import type { ModelConfig } from "../config";
2
+ import type { MlxArray } from "../mlx/array";
3
+ import type { MlxGatewayBinding } from "../backends/mlx/gateway-binding";
4
+ import type { MlxSerialServices } from "../backends/mlx/serial-executor";
5
+ import type { SsdCacheStore, SsdIndexEntry } from "../ssd-cache";
6
+ import type { ChatRequestParams } from "./chat-request";
7
+ import type { SerialRun, Vision } from "./generation-gateway";
8
+ import type { RequestOwnership } from "./request-plan";
9
+ import type { RequestPrep } from "./request-prep";
10
+
11
+ export interface ServedModelInfo {
12
+ readonly config: ModelConfig;
13
+ readonly weightsBytes: number;
14
+ }
15
+
16
+ export interface BuiltPrompt {
17
+ promptIds: number[];
18
+ vision: Vision | undefined;
19
+ startInThinking: boolean;
20
+ probeStableLen: boolean;
21
+ diffusionPixels: MlxArray | null;
22
+ }
23
+
24
+ export interface ModelPromptBuilder {
25
+ (body: ChatRequestParams, tools: ChatRequestParams["tools"] | null,
26
+ ownership: RequestOwnership, prep: RequestPrep): Promise<BuiltPrompt>;
27
+ }
28
+
29
+ /** Model-owned native services. A replacement supplies this one binding;
30
+ * routes and sessions consume it without requiring a concrete model class. */
31
+ export interface ModelServingBinding {
32
+ /** Opaque identity of the backend numerics that produced persisted state. */
33
+ readonly stateCompatibility: string;
34
+ readonly gateway: MlxGatewayBinding;
35
+ createSerial(services: MlxSerialServices): SerialRun;
36
+ readonly buildPrompt: ModelPromptBuilder;
37
+ restore(store: SsdCacheStore, entry: SsdIndexEntry): ReturnType<SsdCacheStore["restore"]>;
38
+ signal(promptIds: number[], bins: number, minimum: number): Promise<{ bins: number[]; vocab: number }>;
39
+ diagnostics(): Record<string, unknown>;
40
+ readonly discovery: { readonly adapters: boolean; readonly training: boolean;
41
+ readonly dsa: unknown; readonly embeddings: boolean };
42
+ embed?(inputs: string[], instruction?: string): ReturnType<typeof import("../embed").embedMany>;
43
+ }