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
@@ -0,0 +1,94 @@
1
+ // Packed Trellis prefill with MLX 0.32.2 GemvWide arithmetic.
2
+ // Ported from ml-explore/mlx v0.32.2, mlx/backend/metal/kernels/gemv.h
3
+ // (MIT). Decode weights to bf16 inside the native dot/unroll/shuffle order;
4
+ // share each decoded row across every input vector in this narrow regime.
5
+ import { MetalKernel } from "../mlx/metal-kernel";
6
+ import { type MlxArray } from "../mlx/array";
7
+ import { Dtype, deviceArchitecture } from "../mlx/ffi";
8
+ import { type TrellisGeometry } from "./trellis-linear";
9
+
10
+ /** Matches the bundled runtime's native reduction on M3 and newer GPUs. */
11
+ export function nativeTrellisWidePrefill(m: number): boolean {
12
+ return m >= 5 && m <= 15 &&
13
+ Number(/^applegpu_[a-z](\d{2})/.exec(deviceArchitecture())?.[1] ?? 0) >= 15;
14
+ }
15
+
16
+ export function wideTrellisPrefillEligible(g: TrellisGeometry, m: number, dtype: Dtype): boolean {
17
+ return dtype === Dtype.bfloat16 && nativeTrellisWidePrefill(m) &&
18
+ g.axis === 1 && g.T === 256 && g.L === 12 && [2, 3, 4].includes(g.k) &&
19
+ g.inFeatures === 5120 && g.outFeatures === 17408 && !g.blockInterleave;
20
+ }
21
+
22
+ let kernel: MetalKernel | undefined;
23
+ function wideKernel() {
24
+ return kernel ??= new MetalKernel({ name: 'mlx_bun_trellis_wide_prefill',
25
+ inputNames: ['x', 'codes', 'scales'], outputNames: ['out'], source: String.raw`
26
+ constexpr uint unroll=8, rows_per_simd=32/KL, simdgroups=KL/8;
27
+ const uint lane=thread_index_in_simdgroup, sg=simdgroup_index_in_threadgroup;
28
+ const uint kl=lane%KL, row=threadgroup_position_in_grid.y*4+sg*rows_per_simd+lane/KL;
29
+ const uint vec0=threadgroup_position_in_grid.x*SM;
30
+ constexpr uint wpb=BT*BITS/32, row_words=KC*BITS/32;
31
+ const float scale=float(scales[row]);
32
+ constexpr uint n_v4=KC/4, n_main=n_v4-n_v4%(KL*unroll);
33
+ float result[SM]={0};
34
+ for(uint base=0;base<n_main;base+=KL*unroll) {
35
+ float4 wf[unroll];
36
+ #pragma clang loop unroll(full)
37
+ for(uint i=0;i<unroll;i++) {
38
+ #pragma clang loop unroll(full)
39
+ for(uint c=0;c<4;c++) {
40
+ const uint k=(base+i*KL+kl)*4+c, block=k/BT, t=k%BT;
41
+ const device uint* bw=codes+(ulong)row*row_words+block*wpb;
42
+ const uint pos=(BT-1-t)*BITS, wi=pos>>5, off=pos&31u;
43
+ uint win=bw[wi]>>off;
44
+ if(off+L>32)win|=bw[wi+1==wpb?0:wi+1]<<(32-off);
45
+ win&=(1u<<L)-1;
46
+ const uint z=win*34038481u+76625530u;
47
+ const uint p=(z&0x00FF00FFu)+((z>>8)&0x00FF00FFu);
48
+ const int code=int((p&0xFFFFu)+(p>>16))-510;
49
+ const float reciprocal=1.0f/147.800537109375f;
50
+ const float approx=float(code)*reciprocal;
51
+ const float residual=metal::fma(-approx,147.800537109375f,float(code));
52
+ const float value=metal::fma(residual,reciprocal,approx);
53
+ wf[i][c]=float(T(value*scale));
54
+ }
55
+ }
56
+ #pragma clang loop unroll(full)
57
+ for(uint v=0;v<SM;v++) {
58
+ const uint m=min(vec0+v,uint(M-1));
59
+ float acc=0;
60
+ #pragma clang loop unroll(full)
61
+ for(uint i=0;i<unroll;i++) {
62
+ const ulong offset=(ulong)m*KC+(base+i*KL+kl)*4;
63
+ const float4 xv=float4(float(x[offset]),float(x[offset+1]),float(x[offset+2]),float(x[offset+3]));
64
+ acc+=metal::dot(wf[i],xv);
65
+ }
66
+ result[v]+=acc;
67
+ }
68
+ }
69
+ #pragma clang loop unroll(full)
70
+ for(uint v=0;v<SM;v++) {
71
+ #pragma clang loop unroll(full)
72
+ for(ushort off=KL/2;off>=1;off>>=1) result[v]+=simd_shuffle_down(result[v],off);
73
+ if(kl==0 && vec0+v<M) out[(ulong)(vec0+v)*N+row]=T(result[v]);
74
+ }
75
+ ` });
76
+ }
77
+ /** Requires the caller to prove aligned, row-contiguous x, as Qwen does
78
+ * with its RMSNorm output. Preserve native fallback when that proof is absent. */
79
+ export function wideTrellisPrefill(x: MlxArray, codes: MlxArray, scales: MlxArray, g: TrellisGeometry): MlxArray {
80
+ const [m, k] = x.shape;
81
+ if (x.ndim !== 2 || x.dtype !== Dtype.bfloat16 || !m || m < 5 || m > 15 ||
82
+ k !== 5120 || g.inFeatures !== k || g.axis !== 1 || g.T !== 256 || g.L !== 12 ||
83
+ ![2, 3, 4].includes(g.k) || g.blockInterleave || g.rows < 4 || g.rows % 4 ||
84
+ g.outFeatures !== g.rows || g.cols !== k || codes.dtype !== Dtype.uint32 ||
85
+ codes.ndim !== 2 || codes.shape[0] !== g.rows || codes.shape[1] !== k * g.k / 32 || scales.size !== g.rows)
86
+ throw new Error("unsupported wide trellis prefill geometry, dtype or layout");
87
+ const kl = m <= 5 ? 32 : 16;
88
+ return wideKernel().apply([x, codes, scales], {
89
+ outputs: [{ shape: [m, g.outFeatures], dtype: x.dtype }],
90
+ grid: [32, g.outFeatures / 4 * (kl / 8), 1], threadGroup: [32, kl / 8, 1],
91
+ templateDtypes: { T: x.dtype },
92
+ templateInts: { M: m, SM: m, KL: kl, KC: k, N: g.outFeatures, BT: g.T, L: g.L, BITS: g.k },
93
+ })[0]!;
94
+ }
@@ -0,0 +1,83 @@
1
+ import type { MlxArray } from "../mlx/array";
2
+ import * as tq from "../mlx/turboquant-ops";
3
+ import type { KvCodec } from "../backends/mlx/kv-codec";
4
+
5
+ /** One TurboQuant-encoded (K, V) storage tuple — the 5 arrays kv-store.ts
6
+ * and toQuantized/fromKVCache pass around. Not `ops.QuantizedTensor`
7
+ * (mlx's affine int4/int8 scheme): this is the rotation + Lloyd-Max
8
+ * layout (docs/design/turboquant.md), asymmetric-affine for keys,
9
+ * FWHT+Lloyd-Max for values. Field order is the kv-store.ts tensor-slot
10
+ * contract — do not reorder without updating snapshotCache/loadKvCache. */
11
+ export interface TurboQuantTensor {
12
+ kIdx: MlxArray;
13
+ kScales: MlxArray;
14
+ kZeros: MlxArray;
15
+ vPacked: MlxArray;
16
+ vScales: MlxArray;
17
+ }
18
+
19
+ export const disposeTurboQuant = (t: TurboQuantTensor): void => {
20
+ t.kIdx.dispose();
21
+ t.kScales.dispose();
22
+ t.kZeros.dispose();
23
+ t.vPacked.dispose();
24
+ t.vScales.dispose();
25
+ };
26
+
27
+ /** Numerical representation only. Storage owns capacity, positions, row
28
+ * membership and persistence; this codec retains the existing kernel choices. */
29
+ export class TurboQuantCodec implements KvCodec<TurboQuantTensor> {
30
+ constructor(readonly kBits: number, readonly vBits: number, readonly fusedDecode: boolean) {}
31
+
32
+ /** Encode k/v [B,H,L,D] into a fresh TurboQuantTensor (packed at rest). */
33
+ encode(k: MlxArray, v: MlxArray): TurboQuantTensor {
34
+ const signed = this.kBits === 8;
35
+ const kEnc = tq.encodeKeys(k, this.kBits, signed);
36
+ const kIdxPacked = this.kBits < 8 ? tq.packBits(kEnc.indices, this.kBits) : kEnc.indices;
37
+ if (kIdxPacked !== kEnc.indices) kEnc.indices.dispose();
38
+ const vEnc = tq.encodeValues(v, this.vBits);
39
+ const vIdxPacked = this.vBits < 8 ? tq.packBits(vEnc.indices, this.vBits) : vEnc.indices;
40
+ if (vIdxPacked !== vEnc.indices) vEnc.indices.dispose();
41
+ return {
42
+ kIdx: kIdxPacked, kScales: kEnc.scales, kZeros: kEnc.zeros,
43
+ vPacked: vIdxPacked, vScales: vEnc.scales,
44
+ };
45
+ }
46
+
47
+ /** Decode a TurboQuantTensor's active [B,H,upTo,*] window back to
48
+ * bf16 [B,H,upTo,headDim] (k, v). Caller owns the returned arrays.
49
+ * deferV leaves V in the rotated domain (decodeValuesRotated) — the
50
+ * caller un-rotates its attention output instead (tq.unrotateValues). */
51
+ decode(t: TurboQuantTensor, upTo: number, headDim: number, deferV = false): [MlxArray, MlxArray] {
52
+ const cut = (a: MlxArray): MlxArray => {
53
+ const [B, H, , D] = a.shape as [number, number, number, number];
54
+ return a.slice([0, 0, 0, 0], [B, H, upTo, D]);
55
+ };
56
+ if (this.fusedDecode) {
57
+ const inputs = [cut(t.kIdx), cut(t.kScales), cut(t.kZeros), cut(t.vPacked), cut(t.vScales)] as const;
58
+ try {
59
+ const decoded = tq.tryDecodePackedKv(inputs, this.kBits, this.vBits, headDim, deferV);
60
+ if (decoded) return decoded;
61
+ } finally { for (const input of inputs) input.dispose(); }
62
+ }
63
+ const kIdxCut = cut(t.kIdx);
64
+ const kIdxUnpacked = this.kBits < 8 ? tq.unpackBits(kIdxCut, this.kBits, headDim) : kIdxCut;
65
+ if (kIdxUnpacked !== kIdxCut) kIdxCut.dispose();
66
+ const kScalesCut = cut(t.kScales);
67
+ const kZerosCut = cut(t.kZeros);
68
+ const k = tq.decodeKeys(kIdxUnpacked, kScalesCut, kZerosCut);
69
+ for (const a of [kIdxUnpacked, kScalesCut, kZerosCut]) a.dispose();
70
+
71
+ const vPackedCut = cut(t.vPacked);
72
+ const vIdxUnpacked = this.vBits < 8 ? tq.unpackBits(vPackedCut, this.vBits, headDim) : vPackedCut;
73
+ if (vIdxUnpacked !== vPackedCut) vPackedCut.dispose();
74
+ const vScalesCut = cut(t.vScales);
75
+ const v = deferV
76
+ ? tq.decodeValuesRotated(vIdxUnpacked, vScalesCut, this.vBits)
77
+ : tq.decodeValues(vIdxUnpacked, vScalesCut, this.vBits);
78
+ for (const a of [vIdxUnpacked, vScalesCut]) a.dispose();
79
+
80
+ return [k, v];
81
+ }
82
+
83
+ }
@@ -1,9 +1,11 @@
1
+ import { captureKvAttention } from "../kv-attention-view";
1
2
  // UniversalDense — the Tier-0 config-driven dense llama-family module
2
3
  // (docs/design/generic-model-support.md §3.1). One module, shaped exactly
3
4
  // like qwen3.ts, with every arch delta selected by the UniversalArgs
4
5
  // descriptor (archs.ts). Monolith path only: no compiled
5
- // decode, no kv-quant — slow, never broken. The bar is L1 bit-exactness
6
- // vs mlx-lm on this machine's GPU (tests/universal-parity.test.ts).
6
+ // decode. Standard attention uses the shared plain/affine KV port; the
7
+ // softcap branch retains plain KV. The bar is L1 bit-exactness
8
+ // vs mlx-lm on this machine's GPU (tests/parity/universal-parity.test.ts).
7
9
  //
8
10
  // Porting discipline: each branch transcribes its mlx-lm source op-for-op
9
11
  // (q/k-norm before vs after reshape, rope order, scale points, softcap,
@@ -154,19 +156,18 @@ class UniversalAttention {
154
156
  ? this.rope.applyDynamic(k, offArr)
155
157
  : this.rope.apply(k, cache.offset));
156
158
 
157
- const [keys, values] = cache.updateAndFetch(k, v);
158
- k.dispose();
159
- v.dispose();
160
-
161
159
  let attn: MlxArray;
162
- if (a.attnLogitSoftcap !== null) {
163
- attn = this.#softcapAttention(q, keys, values, mask, B, L);
164
- } else {
165
- attn = ops.sdpa(q, keys, values, a.attnScale, mask.mode, mask.arr);
166
- }
167
- keys.dispose();
168
- values.dispose();
169
- q.dispose();
160
+ try {
161
+ if (a.attnLogitSoftcap !== null) {
162
+ const [keys, values] = cache.updateAndFetch(k, v);
163
+ try { attn = this.#softcapAttention(q, keys, values, mask, B, L); }
164
+ finally { keys.dispose(); values.dispose(); }
165
+ } else {
166
+ const view = captureKvAttention(cache, k, v);
167
+ try { attn = view.attend(q, a.attnScale, mask); }
168
+ finally { view.dispose(); }
169
+ }
170
+ } finally { k.dispose(); v.dispose(); q.dispose(); }
170
171
 
171
172
  const attnT = ops.transposeAxes(attn, [0, 2, 1, 3]);
172
173
  attn.dispose();
@@ -11,6 +11,7 @@ import type { Weights } from "../../weights";
11
11
  import { MlxArray } from "../../mlx/array";
12
12
  import * as ops from "../../mlx/ops";
13
13
  import { QuantizedEmbedding, QuantizedLinear, RMSNorm } from "../gemma4-base";
14
+ import { TrellisLinear } from "../trellis-linear";
14
15
 
15
16
  /** Records every tensor a universal load consumes; `finish` diffs against
16
17
  * the shard index so a descriptor mistake is a LOAD error (unconsumed /
@@ -66,7 +67,7 @@ export class DenseLinear {
66
67
  }
67
68
 
68
69
  /** Either linear flavor behind one call surface. */
69
- export type AnyLinear = QuantizedLinear | DenseLinear;
70
+ export type AnyLinear = QuantizedLinear | DenseLinear | TrellisLinear;
70
71
 
71
72
  /** Quantized when `.scales` exists (MLX-quantized checkpoints), else dense
72
73
  * bf16/f16/f32 (Phase 1.5). Both flavors carry the optional ADDITIVE
@@ -74,6 +75,12 @@ export type AnyLinear = QuantizedLinear | DenseLinear;
74
75
  export function loadLinear(
75
76
  weights: Weights, path: string, config: ModelConfig, audit: WeightAudit,
76
77
  ): AnyLinear {
78
+ if (TrellisLinear.isTrellis(config, path)) {
79
+ const lin = TrellisLinear.load(weights, path, config);
80
+ audit.use(`${path}.weight`);
81
+ audit.use(`${path}.scales`);
82
+ return lin;
83
+ }
77
84
  if (weights.has(`${path}.scales`)) {
78
85
  const lin = QuantizedLinear.load(weights, path, config);
79
86
  audit.use(`${path}.weight`);
@@ -8,7 +8,7 @@
8
8
  //
9
9
  // Resolution order for the libs (mirrored in src/mlx/ffi.ts):
10
10
  // MLX_BUN_LIBMLXC env > beside the executable (sidecar dist/ layout,
11
- // docs/reference/embedding.md) > the native-pack cache dir > homebrew.
11
+ // docs/reference/distribution.md) > the native-pack cache dir > homebrew.
12
12
  // Dev trees and embedders therefore never download anything.
13
13
 
14
14
  import { existsSync, mkdirSync, renameSync, rmSync } from "node:fs";
@@ -17,22 +17,23 @@ import { dirname, join } from "node:path";
17
17
  import { downloadOne } from "./download";
18
18
  import { runtimeValue } from "./runtime-config";
19
19
 
20
- export const NATIVE_PACK_VERSION = "0.3.0";
20
+ export const NATIVE_PACK_VERSION = "0.4.0";
21
+ export const MLX_CORE_VERSION = "0.32.2";
21
22
  export const NATIVE_PACK_FILES = [
22
23
  "libmlxc.dylib", "libmlx.dylib", "libjaccl.dylib", "mlx.metallib",
23
24
  "libmlx_bun_expert_io.dylib", "mlx-bun-frame-extract",
24
25
  ] as const;
25
26
 
26
27
  // RELEASE-TIME BAKE: scripts/build-native-pack.sh prints the sha256/size for
27
- // the freshly built tarball — publish `native-v0.3.0` with both assets and
28
+ // the freshly built tarball — publish `native-v0.4.0` with both assets and
28
29
  // paste the values here BEFORE tagging the package release (the download
29
30
  // 404s until the GitHub release exists; dev trees resolve via homebrew/env
30
31
  // and never hit this path).
31
32
  const SHA256: Record<string, string> = {
32
- arm64: "b485fed858971ea6f072f349a0234c0e2d5030d3ef2ddfa942c8975eca2d3b2e",
33
+ arm64: "f2b0857658aa0826aee14b94a6b83d4c86c08f2c07d716991de6afd038f5ca5d",
33
34
  };
34
35
  const SIZE: Record<string, number> = {
35
- arm64: 52299265,
36
+ arm64: 41931583,
36
37
  };
37
38
 
38
39
  export function nativePackName(arch = process.arch): string {
@@ -17,37 +17,11 @@ import { AuthStorage, ModelRegistry } from "@earendil-works/pi-coding-agent";
17
17
  * derive it from the registry's `find()` return type. */
18
18
  export type PiModel = NonNullable<ReturnType<ModelRegistry["find"]>>;
19
19
 
20
- // Provider/model constants — kept aligned with src/harness-pi.ts so every
21
- // path (web embed, terminal embed, external pi) registers the same provider.
22
- export const PI_PROVIDER_ID = "mlx-bun";
23
- export const PI_LOCAL_MODEL_ID = "local";
24
- export const PI_API_KEY = "sk-mlx-bun-local";
25
- export const PI_API = "openai-completions" as const;
26
-
27
- export const DEFAULT_CONTEXT_WINDOW = 32_768;
28
- export const DEFAULT_MAX_TOKENS = 8_192;
29
-
30
- export interface PiProviderOptions {
31
- /** Advertised context window. Default: DEFAULT_CONTEXT_WINDOW. */
32
- contextWindow?: number;
33
- /** Advertised max output tokens. Default: DEFAULT_MAX_TOKENS. */
34
- maxTokens?: number;
35
- /** Human-readable model label (e.g. the real repo id). Default: "mlx-bun (local)". */
36
- name?: string;
37
- /** The loaded model has a switchable reasoning channel (server's
38
- * `ctx.template.supportsThinking` — true for any model whose chat template
39
- * gates on enable_thinking: Qwen3.5, MiniCPM5, …). When true Pi engages
40
- * reasoning and sends the on/off switch the server maps to enable_thinking.
41
- * Default false. */
42
- reasoning?: boolean;
43
- /** The loaded model can accept images (server's `ctx.vision != null`).
44
- * This MUST match the real model: pi-ai serializes user content as OpenAI
45
- * multimodal content-parts (`[{type:"text",…}]`) for image-capable models
46
- * and as a plain string otherwise. A text-only chat template renders nothing
47
- * for a parts array, so declaring a non-vision model as image-capable makes
48
- * the user's turn vanish ("I don't see any message"). Default false. */
49
- vision?: boolean;
50
- }
20
+ import { PI_PROVIDER_ID, PI_API_KEY, PI_API, PI_LOCAL_MODEL_ID, piModelDefinition,
21
+ type PiModelOptions } from "./contracts/pi-provider";
22
+ export { PI_PROVIDER_ID, PI_API_KEY, PI_API, PI_LOCAL_MODEL_ID,
23
+ DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_TOKENS } from "./contracts/pi-provider";
24
+ export interface PiProviderOptions extends PiModelOptions {}
51
25
 
52
26
  export interface PiProviderWiring {
53
27
  authStorage: AuthStorage;
@@ -70,39 +44,7 @@ export function buildPiProvider(baseUrl: string, opts: PiProviderOptions = {}):
70
44
  baseUrl,
71
45
  apiKey: PI_API_KEY,
72
46
  api: PI_API,
73
- models: [
74
- {
75
- id: PI_LOCAL_MODEL_ID,
76
- name: opts.name ?? "mlx-bun (local)",
77
- api: PI_API,
78
- reasoning: opts.reasoning ?? false,
79
- // Compat flags that make pi emit the wire format our local server's
80
- // chat templates expect (docs/custom-provider.md "Model Definition
81
- // Reference"):
82
- // - supportsDeveloperRole:false → pi sends the system prompt as the
83
- // `system` role, not `developer` (our templates only know
84
- // system/user/assistant/tool).
85
- // - thinkingFormat:"qwen-chat-template" (reasoning models only) → pi
86
- // sends chat_template_kwargs.enable_thinking, the boolean our
87
- // Qwen3.5/MiniCPM5 templates gate on. pi computes the boolean from
88
- // the selected thinking level (off → false), so no thinkingLevelMap.
89
- compat: {
90
- supportsDeveloperRole: false,
91
- ...(opts.reasoning ? { thinkingFormat: "qwen-chat-template" as const } : {}),
92
- },
93
- // input MUST match the loaded model. pi-ai serializes user content as a
94
- // plain string for text-only models and as OpenAI content-parts
95
- // (`[{type:"text",…}]`) once a model declares image input — and a
96
- // text-only chat template renders NOTHING for a parts array, dropping
97
- // the user's turn ("I don't see any message"). So declare image input
98
- // only for an actual vision model; the web `ready` frame's `vision`
99
- // flag is the same signal that drives the UI's image affordance.
100
- input: opts.vision ? ["text", "image"] : ["text"],
101
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
102
- contextWindow: opts.contextWindow ?? DEFAULT_CONTEXT_WINDOW,
103
- maxTokens: opts.maxTokens ?? DEFAULT_MAX_TOKENS,
104
- },
105
- ],
47
+ models: [piModelDefinition(opts)],
106
48
  });
107
49
 
108
50
  const model = modelRegistry.find(PI_PROVIDER_ID, PI_LOCAL_MODEL_ID);