mlx-bun 0.5.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (640) hide show
  1. package/README.md +1449 -109
  2. package/THIRD_PARTY_NOTICES.md +882 -0
  3. package/bin/mlx-bun.convert.mjs +4 -0
  4. package/bin/mlx-bun.fuse.mjs +4 -0
  5. package/bin/mlx-bun.generate.mjs +4 -0
  6. package/bin/mlx-bun.lora.mjs +4 -0
  7. package/bin/mlx-bun.mjs +13 -21
  8. package/bin/mlx-bun.server.mjs +4 -0
  9. package/bin/mlx-bun.upload.mjs +4 -0
  10. package/dist/web/app.js +9584 -0
  11. package/package.json +50 -53
  12. package/src/cli/ane-install.ts +76 -0
  13. package/src/cli/args.ts +179 -0
  14. package/src/cli/engine-entry.ts +68 -0
  15. package/src/cli/inference.ts +214 -0
  16. package/src/cli/job-entry.ts +97 -0
  17. package/src/cli/library-host.ts +117 -0
  18. package/src/cli/main.ts +57 -0
  19. package/src/cli/memory-engine.ts +163 -0
  20. package/src/cli/memory.ts +36 -0
  21. package/src/cli/mlx-lm-aliases.ts +309 -0
  22. package/src/cli/model-choice.ts +33 -0
  23. package/src/cli/model-selection.ts +84 -0
  24. package/src/cli/module-host.ts +11 -0
  25. package/src/cli/module-verbs.ts +50 -0
  26. package/src/cli/numerical-policy.ts +12 -0
  27. package/src/cli/perplexity.ts +89 -0
  28. package/src/cli/serve-host.ts +423 -0
  29. package/src/cli/serve-isolated.ts +217 -0
  30. package/src/cli/serve-options.ts +106 -0
  31. package/src/cli/serve-state.ts +205 -0
  32. package/src/cli/serve.ts +500 -0
  33. package/src/cli/served-model-host.ts +102 -0
  34. package/src/cli/server-entry.ts +148 -0
  35. package/src/cli/serving-unit.ts +177 -0
  36. package/src/{tui.ts → cli/terminal.ts} +13 -8
  37. package/src/cli/worker-adapters.ts +34 -0
  38. package/src/cli/worker-entry.ts +272 -0
  39. package/src/cli/worker-unit.ts +179 -0
  40. package/src/engine/adapter-operation.ts +26 -0
  41. package/src/engine/cache-services.ts +114 -0
  42. package/src/engine/completion.ts +39 -0
  43. package/src/engine/generation-gateway.ts +358 -0
  44. package/src/engine/index.ts +59 -0
  45. package/src/engine/kv-budget.ts +120 -0
  46. package/src/engine/media-preparation.ts +232 -0
  47. package/src/engine/model-binding.ts +24 -0
  48. package/src/engine/model-host.ts +513 -0
  49. package/src/engine/model-serving.ts +89 -0
  50. package/src/{serve → engine}/preparation.ts +7 -5
  51. package/src/{serve → engine}/session-completion-engine.ts +6 -6
  52. package/src/engine/telemetry.ts +109 -0
  53. package/src/hub/downloads.ts +116 -0
  54. package/src/jobs/db.ts +16 -7
  55. package/src/jobs/events.ts +29 -0
  56. package/src/jobs/executable.ts +5 -0
  57. package/src/jobs/host.ts +51 -0
  58. package/src/jobs/in-process.ts +55 -0
  59. package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
  60. package/src/jobs/runner.ts +150 -231
  61. package/src/jobs/service.ts +75 -0
  62. package/src/jobs/sse.ts +59 -23
  63. package/src/jobs/worker-memory.ts +46 -0
  64. package/src/jobs/worker-process.ts +163 -0
  65. package/src/jobs/worker-supervisor.ts +258 -0
  66. package/src/modules.ts +58 -0
  67. package/src/publishing/catalog-hub.ts +18 -0
  68. package/src/publishing/credentials.ts +31 -0
  69. package/src/publishing/upload.ts +37 -0
  70. package/src/residency/leased-adapters.ts +21 -0
  71. package/src/residency/local-records.ts +16 -0
  72. package/src/residency/model-residency.ts +405 -0
  73. package/src/residency/record-index.ts +28 -0
  74. package/src/residency/resident-estimate.ts +50 -0
  75. package/src/{anthropic.ts → server/anthropic.ts} +3 -81
  76. package/src/server/cache-routes.ts +36 -0
  77. package/src/{serve → server}/chat-request.ts +10 -10
  78. package/src/{serve → server}/chat-stage.ts +14 -14
  79. package/src/{client.ts → server/client.ts} +28 -2
  80. package/src/{serve → server}/completion-executor.ts +33 -41
  81. package/src/server/decision-body.ts +55 -0
  82. package/src/server/decision-routes.ts +134 -0
  83. package/src/server/decision-wire.ts +228 -0
  84. package/src/{serve → server}/discovery-routes.ts +25 -82
  85. package/src/{serve → server}/http.ts +25 -13
  86. package/src/{serve → server}/inference-request.ts +5 -5
  87. package/src/server/job-routes.ts +20 -0
  88. package/src/server/media-prompt.ts +63 -0
  89. package/src/server/memory-completion-client.ts +46 -0
  90. package/src/server/model-routes.ts +192 -0
  91. package/src/{serve → server}/openai-wire.ts +3 -2
  92. package/src/{serve → server}/pipeline.ts +1 -1
  93. package/src/server/prompt-builder.ts +13 -0
  94. package/src/server/prompt-contracts.ts +17 -0
  95. package/src/server/proxy-routes.ts +187 -0
  96. package/src/server/publishing-routes.ts +41 -0
  97. package/src/{serve → server}/request-plan.ts +6 -8
  98. package/src/{serve → server}/request-prep.ts +47 -50
  99. package/src/{serve → server}/responses-client.ts +30 -13
  100. package/src/{responses.ts → server/responses.ts} +12 -93
  101. package/src/server/routes.ts +205 -0
  102. package/src/server/start.ts +72 -0
  103. package/src/server/status-routes.ts +108 -0
  104. package/src/{serve → server}/text-completion-stage.ts +25 -4
  105. package/src/server/text-prompt.ts +12 -0
  106. package/src/{serve → server}/token-streams.ts +36 -38
  107. package/src/server/worker-routes.ts +311 -0
  108. package/src/storage/paths.ts +61 -0
  109. package/src/web/assets.ts +37 -0
  110. package/src/web/{src → browser}/api.ts +5 -23
  111. package/src/web/browser/chat-host.ts +17 -0
  112. package/src/web/browser/installed-panels.ts +6 -0
  113. package/src/web/browser/main.ts +55 -0
  114. package/src/web/browser/markdown.ts +279 -0
  115. package/src/web/browser/memory-panel.ts +9 -0
  116. package/src/web/browser/palette.ts +64 -0
  117. package/src/web/browser/protocol.ts +13 -0
  118. package/src/web/browser/shell.ts +467 -0
  119. package/src/web/{src → browser}/status.ts +32 -36
  120. package/src/web/build.ts +51 -0
  121. package/src/web/public/app.html +1054 -0
  122. package/src/web/{sw.js → public/sw.js} +4 -3
  123. package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
  124. package/src/web/{vendor → public/vendor}/hljs.js +2 -2
  125. package/THIRD_PARTY_LICENSES.md +0 -51
  126. package/docs/README.md +0 -107
  127. package/docs/archive/hlg-sampling.md +0 -350
  128. package/docs/archive/investigations/audio-input-plan.md +0 -356
  129. package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +0 -3617
  130. package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
  131. package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
  132. package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
  133. package/docs/archive/investigations/curve-bisector-routing.md +0 -123
  134. package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
  135. package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
  136. package/docs/archive/investigations/dspark-handoff.md +0 -224
  137. package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
  138. package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
  139. package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
  140. package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
  141. package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
  142. package/docs/archive/investigations/lab-build-journal.md +0 -157
  143. package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
  144. package/docs/archive/investigations/openjarvis-fit.md +0 -198
  145. package/docs/archive/investigations/openwiki-evaluation.md +0 -249
  146. package/docs/archive/investigations/optimization_plan.md +0 -346
  147. package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
  148. package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
  149. package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
  150. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
  151. package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
  152. package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
  153. package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
  154. package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
  155. package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
  156. package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
  157. package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
  158. package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
  159. package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
  160. package/docs/archive/planning/chat-ui-vision.md +0 -50
  161. package/docs/archive/planning/chunk-task-roadmap.md +0 -77
  162. package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
  163. package/docs/archive/planning/journal.md +0 -316
  164. package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
  165. package/docs/archive/planning/pi-integration-review.md +0 -178
  166. package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
  167. package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
  168. package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
  169. package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
  170. package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
  171. package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
  172. package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
  173. package/docs/archive/planning/release-notes-v0.4.0.md +0 -45
  174. package/docs/archive/planning/release-notes-v0.5.0.md +0 -37
  175. package/docs/archive/planning/web-ui-pass-plan.md +0 -213
  176. package/docs/archive/planning/website-readme-pass-plan.md +0 -224
  177. package/docs/design/batching.md +0 -2054
  178. package/docs/design/decode-speed-program.md +0 -2404
  179. package/docs/design/dreaming-nightly-pipeline.md +0 -684
  180. package/docs/design/generic-model-support.md +0 -821
  181. package/docs/design/kv-cache.md +0 -993
  182. package/docs/design/orpo-training.md +0 -680
  183. package/docs/design/speculative-decoding.md +0 -2129
  184. package/docs/design/turboquant.md +0 -2225
  185. package/docs/design/unified-engine-frontier-plan.md +0 -1987
  186. package/docs/design/web-chat-redesign.md +0 -695
  187. package/docs/planning/PRODUCT_ROADMAP.md +0 -593
  188. package/docs/planning/ResearchTopics.md +0 -119
  189. package/docs/planning/public-readiness-handoff.md +0 -244
  190. package/docs/planning/public-readiness.md +0 -149
  191. package/docs/planning/video-series.md +0 -421
  192. package/docs/reference/benchmarks.md +0 -3587
  193. package/docs/reference/cli.md +0 -646
  194. package/docs/reference/distribution.md +0 -380
  195. package/docs/reference/environment.md +0 -494
  196. package/docs/reference/glossary.md +0 -39
  197. package/docs/reference/library-api.md +0 -688
  198. package/docs/reference/memory.md +0 -260
  199. package/docs/reference/models.md +0 -346
  200. package/docs/reference/server-api.md +0 -1945
  201. package/docs/reference/server-config.md +0 -973
  202. package/docs/reference/training.md +0 -462
  203. package/docs/reference/troubleshooting.md +0 -158
  204. package/src/admission-plan.ts +0 -18
  205. package/src/audio/audiotoolbox.ts +0 -112
  206. package/src/audio/conformer.ts +0 -655
  207. package/src/audio/decode.ts +0 -133
  208. package/src/audio/features.ts +0 -202
  209. package/src/audio/mic-capture.ts +0 -98
  210. package/src/audio/silero-vad.ts +0 -379
  211. package/src/audio/transcode.ts +0 -67
  212. package/src/audio/whisper-decode.ts +0 -774
  213. package/src/audio/whisper-fast.ts +0 -732
  214. package/src/audio/whisper-format.ts +0 -73
  215. package/src/audio/whisper-mel.ts +0 -185
  216. package/src/audio/whisper-timing.ts +0 -274
  217. package/src/audio/whisper-tokenizer.ts +0 -239
  218. package/src/audio/whisper-transcribe.ts +0 -410
  219. package/src/backends/mlx/assistant-target.ts +0 -46
  220. package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
  221. package/src/backends/mlx/autoregressive.ts +0 -129
  222. package/src/backends/mlx/batch-group.ts +0 -1874
  223. package/src/backends/mlx/cache-attachment.ts +0 -67
  224. package/src/backends/mlx/cache-layout.ts +0 -31
  225. package/src/backends/mlx/checkpoint-state.ts +0 -53
  226. package/src/backends/mlx/continuation-persistence.ts +0 -107
  227. package/src/backends/mlx/continuation-request.ts +0 -43
  228. package/src/backends/mlx/continuation.ts +0 -77
  229. package/src/backends/mlx/diffusion.ts +0 -39
  230. package/src/backends/mlx/draft-target.ts +0 -32
  231. package/src/backends/mlx/encoder-cache.ts +0 -25
  232. package/src/backends/mlx/evaluation.ts +0 -105
  233. package/src/backends/mlx/fill-append.ts +0 -58
  234. package/src/backends/mlx/fill-group.ts +0 -497
  235. package/src/backends/mlx/full-kv-row-append.ts +0 -32
  236. package/src/backends/mlx/full-kv-row-donor.ts +0 -54
  237. package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
  238. package/src/backends/mlx/gateway-binding.ts +0 -174
  239. package/src/backends/mlx/graph.ts +0 -38
  240. package/src/backends/mlx/kv-codec.ts +0 -9
  241. package/src/backends/mlx/kv-maintenance.ts +0 -161
  242. package/src/backends/mlx/kv-tensor-rows.ts +0 -212
  243. package/src/backends/mlx/memory-client.ts +0 -189
  244. package/src/backends/mlx/methods.ts +0 -90
  245. package/src/backends/mlx/mixed-iteration.ts +0 -62
  246. package/src/backends/mlx/model-prompt.ts +0 -178
  247. package/src/backends/mlx/model-serving.ts +0 -80
  248. package/src/backends/mlx/paged-cache-codec.ts +0 -27
  249. package/src/backends/mlx/prefill-cohort.ts +0 -100
  250. package/src/backends/mlx/prefill-policy.ts +0 -26
  251. package/src/backends/mlx/prefill-rows.ts +0 -244
  252. package/src/backends/mlx/prefill.ts +0 -33
  253. package/src/backends/mlx/projected-context-rows.ts +0 -72
  254. package/src/backends/mlx/prompt-input.ts +0 -29
  255. package/src/backends/mlx/qwen-prompt-input.ts +0 -40
  256. package/src/backends/mlx/request-policy.ts +0 -20
  257. package/src/backends/mlx/request-state-policy.ts +0 -54
  258. package/src/backends/mlx/rollback.ts +0 -92
  259. package/src/backends/mlx/row-sampling.ts +0 -49
  260. package/src/backends/mlx/serial-executor.ts +0 -251
  261. package/src/backends/mlx/speculative-group.ts +0 -438
  262. package/src/backends/mlx/speculative-round.ts +0 -161
  263. package/src/backends/mlx/speculative.ts +0 -131
  264. package/src/backends/mlx/state-rows.ts +0 -104
  265. package/src/backends/mlx/state-views.ts +0 -46
  266. package/src/backends/mlx/target-layout-capability.ts +0 -35
  267. package/src/backends/mlx/text-engine.ts +0 -73
  268. package/src/backends/mlx/transitioning-kv-rows.ts +0 -173
  269. package/src/chat-template.ts +0 -382
  270. package/src/cli.ts +0 -3490
  271. package/src/config.ts +0 -399
  272. package/src/contracts/completion.ts +0 -16
  273. package/src/contracts/execution.ts +0 -70
  274. package/src/contracts/generation.ts +0 -103
  275. package/src/contracts/host.ts +0 -7
  276. package/src/contracts/object-cache.ts +0 -8
  277. package/src/contracts/pi-provider.ts +0 -30
  278. package/src/contracts/pi.ts +0 -261
  279. package/src/contracts/prefix-cache.ts +0 -33
  280. package/src/contracts/resources.ts +0 -25
  281. package/src/contracts/sampling.ts +0 -23
  282. package/src/contracts/scheduling.ts +0 -54
  283. package/src/contracts/tsconfig.json +0 -14
  284. package/src/dataset/generators.ts +0 -1087
  285. package/src/dataset/index.ts +0 -12
  286. package/src/dataset/job.ts +0 -81
  287. package/src/dataset/llm.ts +0 -71
  288. package/src/dataset/registry.ts +0 -528
  289. package/src/diffusion/diffusion-generate.ts +0 -507
  290. package/src/download.ts +0 -505
  291. package/src/embed.ts +0 -77
  292. package/src/engine/admission.ts +0 -59
  293. package/src/engine/cancellation.ts +0 -38
  294. package/src/engine/engine.ts +0 -56
  295. package/src/engine/execution-coordinator.ts +0 -70
  296. package/src/engine/execution-plan.ts +0 -64
  297. package/src/engine/execution-tasks.ts +0 -44
  298. package/src/engine/namespaced-cache.ts +0 -13
  299. package/src/engine/resources.ts +0 -53
  300. package/src/engine/scheduler.ts +0 -92
  301. package/src/engine/session.ts +0 -247
  302. package/src/eval/README.md +0 -130
  303. package/src/eval/ifeval.ts +0 -81
  304. package/src/eval/kl-prompts.ts +0 -29
  305. package/src/eval/kl.ts +0 -590
  306. package/src/eval/perplexity.ts +0 -164
  307. package/src/eval/quality-db.ts +0 -92
  308. package/src/eval/reference-logits.ts +0 -207
  309. package/src/eval/runner.ts +0 -124
  310. package/src/eval/score.ts +0 -49
  311. package/src/eval/tasks/bfcl.ts +0 -535
  312. package/src/eval/tasks/gsm8k.ts +0 -98
  313. package/src/eval/tasks/hashhop.ts +0 -139
  314. package/src/eval/tasks/humaneval.ts +0 -275
  315. package/src/eval/tasks/ifeval.ts +0 -525
  316. package/src/eval/tasks/mmlu.ts +0 -157
  317. package/src/eval/ultrafeedback.ts +0 -60
  318. package/src/evaldb.ts +0 -199
  319. package/src/expert-io.ts +0 -393
  320. package/src/expert-offload-build.ts +0 -77
  321. package/src/expert-offload.ts +0 -76
  322. package/src/expert-residency.ts +0 -1134
  323. package/src/expert-usage.ts +0 -415
  324. package/src/fill/echo-index.ts +0 -188
  325. package/src/fill/fill-session.ts +0 -463
  326. package/src/fill/proposal.ts +0 -68
  327. package/src/fill/schema-rows.ts +0 -506
  328. package/src/fill/tool-boundary.ts +0 -103
  329. package/src/fit.ts +0 -249
  330. package/src/generate.ts +0 -1352
  331. package/src/grammar.ts +0 -604
  332. package/src/harness-pi.ts +0 -184
  333. package/src/hf-push.ts +0 -628
  334. package/src/hub-rest.ts +0 -242
  335. package/src/index.ts +0 -63
  336. package/src/inference/denoising.ts +0 -17
  337. package/src/inference/draft-acceptance.ts +0 -41
  338. package/src/inference/draft-output.ts +0 -49
  339. package/src/inference/graph.ts +0 -33
  340. package/src/inference/prefill.ts +0 -45
  341. package/src/inference/rollback.ts +0 -7
  342. package/src/jobs/index.ts +0 -31
  343. package/src/jobs/job-entry.ts +0 -107
  344. package/src/jobs/task-client.ts +0 -19
  345. package/src/jobs/types.ts +0 -2
  346. package/src/kv-scheme.ts +0 -279
  347. package/src/kv-store.ts +0 -1135
  348. package/src/lab/README.md +0 -22
  349. package/src/lab/curve/curve-designer.html +0 -303
  350. package/src/lab/curve/curve-sampler.ts +0 -122
  351. package/src/lab/expert-trace/expert-trace.ts +0 -69
  352. package/src/lab/paged-kv/paged-attention.ts +0 -117
  353. package/src/lab/paged-kv/paged-kv-rows.ts +0 -111
  354. package/src/lab/paged-kv/paged-kv.ts +0 -336
  355. package/src/library.ts +0 -40
  356. package/src/lora.ts +0 -408
  357. package/src/md-modules.d.ts +0 -54
  358. package/src/media-fetch.ts +0 -442
  359. package/src/memory/article.ts +0 -558
  360. package/src/memory/chunk-validation.ts +0 -150
  361. package/src/memory/chunk.ts +0 -318
  362. package/src/memory/cluster.ts +0 -351
  363. package/src/memory/coverage.ts +0 -134
  364. package/src/memory/crosslink.ts +0 -0
  365. package/src/memory/db.ts +0 -253
  366. package/src/memory/entity.ts +0 -203
  367. package/src/memory/gate.ts +0 -187
  368. package/src/memory/history.ts +0 -152
  369. package/src/memory/ingest.ts +0 -335
  370. package/src/memory/model.ts +0 -183
  371. package/src/memory/normalize.ts +0 -671
  372. package/src/memory/parse.ts +0 -22
  373. package/src/memory/pipeline.ts +0 -275
  374. package/src/memory/prompts.ts +0 -65
  375. package/src/memory/query.ts +0 -334
  376. package/src/memory/reconcile.ts +0 -734
  377. package/src/memory/redirect.ts +0 -108
  378. package/src/memory/reindex.ts +0 -325
  379. package/src/memory/resolve.ts +0 -307
  380. package/src/memory/rest.ts +0 -245
  381. package/src/memory/route.ts +0 -272
  382. package/src/memory/schedule.ts +0 -165
  383. package/src/memory/stages.ts +0 -777
  384. package/src/memory/synthesize.ts +0 -1638
  385. package/src/memory/tools.ts +0 -749
  386. package/src/memory/vault.ts +0 -1194
  387. package/src/memory/wikify.ts +0 -1064
  388. package/src/mlx/array.ts +0 -425
  389. package/src/mlx/autograd.ts +0 -304
  390. package/src/mlx/checkpoint.ts +0 -149
  391. package/src/mlx/compile.ts +0 -168
  392. package/src/mlx/custom-vjp.ts +0 -188
  393. package/src/mlx/ffi.ts +0 -531
  394. package/src/mlx/materialize.ts +0 -23
  395. package/src/mlx/metal-kernel.ts +0 -159
  396. package/src/mlx/normalized-argmax.ts +0 -116
  397. package/src/mlx/ops.ts +0 -1108
  398. package/src/mlx/quantized-rows.ts +0 -36
  399. package/src/mlx/token-bitmask.ts +0 -52
  400. package/src/mlx/turboquant-kv-decode.ts +0 -82
  401. package/src/mlx/turboquant-kv-inverse.ts +0 -122
  402. package/src/mlx/turboquant-ops.ts +0 -861
  403. package/src/mlx/turboquant-tables.ts +0 -237
  404. package/src/mmap.ts +0 -90
  405. package/src/model/artifact-identity.ts +0 -73
  406. package/src/model/batched-kv.ts +0 -235
  407. package/src/model/batched-mask.ts +0 -279
  408. package/src/model/batched-quant.ts +0 -212
  409. package/src/model/batched-quantized-kv.ts +0 -144
  410. package/src/model/batched-rotating-quant.ts +0 -353
  411. package/src/model/batched-rotating-state.ts +0 -149
  412. package/src/model/batched-rotating.ts +0 -338
  413. package/src/model/batched-row-storage.ts +0 -179
  414. package/src/model/batched-ssm.ts +0 -52
  415. package/src/model/batched-turboquant-kv.ts +0 -94
  416. package/src/model/compiled-decode.ts +0 -712
  417. package/src/model/decoded-kv-donor.ts +0 -12
  418. package/src/model/delayed-quantized-kv.ts +0 -72
  419. package/src/model/delayed-rotating-quantized-kv.ts +0 -93
  420. package/src/model/delayed-turboquant-kv.ts +0 -57
  421. package/src/model/diffusion-gemma.ts +0 -1026
  422. package/src/model/factory.ts +0 -215
  423. package/src/model/fingerprint.ts +0 -45
  424. package/src/model/flash-attention.ts +0 -694
  425. package/src/model/full-prefill-padding.ts +0 -56
  426. package/src/model/full-prefill-row.ts +0 -105
  427. package/src/model/gemma4-base.ts +0 -2370
  428. package/src/model/gemma4.ts +0 -1395
  429. package/src/model/generated/gemma4-12b.ts +0 -429
  430. package/src/model/generated/gemma4-26b.ts +0 -448
  431. package/src/model/generated/gemma4-e4b.ts +0 -717
  432. package/src/model/generated/index.ts +0 -18
  433. package/src/model/glm52-atlas.ts +0 -511
  434. package/src/model/glm52-cache.ts +0 -792
  435. package/src/model/glm52-config.ts +0 -262
  436. package/src/model/glm52-container.ts +0 -305
  437. package/src/model/glm52-coupling.ts +0 -388
  438. package/src/model/glm52-dsa.ts +0 -606
  439. package/src/model/glm52-expert-layout.ts +0 -253
  440. package/src/model/glm52-layout.ts +0 -152
  441. package/src/model/glm52-memory.ts +0 -500
  442. package/src/model/glm52-mla.ts +0 -792
  443. package/src/model/glm52-moe.ts +0 -223
  444. package/src/model/glm52-pilot.ts +0 -537
  445. package/src/model/glm52-reference.ts +0 -445
  446. package/src/model/glm52-residency.ts +0 -557
  447. package/src/model/glm52-resident-weights.ts +0 -135
  448. package/src/model/glm52-streamed-experts.ts +0 -453
  449. package/src/model/glm52-streamed-metal.ts +0 -610
  450. package/src/model/glm52-weights.ts +0 -503
  451. package/src/model/glm52.ts +0 -1132
  452. package/src/model/implementation.ts +0 -69
  453. package/src/model/kv-attention-view.ts +0 -70
  454. package/src/model/minicpm5.ts +0 -376
  455. package/src/model/profile.ts +0 -468
  456. package/src/model/quantized-append-attention.ts +0 -31
  457. package/src/model/qwen-append.ts +0 -12
  458. package/src/model/qwen-conv.ts +0 -52
  459. package/src/model/qwen3-delta-state.ts +0 -74
  460. package/src/model/qwen3-delta.ts +0 -451
  461. package/src/model/qwen3-moe.ts +0 -404
  462. package/src/model/qwen3-mrope.ts +0 -250
  463. package/src/model/qwen3.ts +0 -277
  464. package/src/model/qwen3_5-checkpoint.ts +0 -164
  465. package/src/model/qwen3_5.ts +0 -881
  466. package/src/model/rotating-kv-donor.ts +0 -35
  467. package/src/model/rotating-kv-layout.ts +0 -262
  468. package/src/model/rotating-row-transaction.ts +0 -35
  469. package/src/model/speculative-rotating-kv.ts +0 -101
  470. package/src/model/ssm-prefill-padding.ts +0 -39
  471. package/src/model/support.ts +0 -110
  472. package/src/model/token-groups.ts +0 -66
  473. package/src/model/trellis-balanced-scatter.ts +0 -51
  474. package/src/model/trellis-linear.ts +0 -672
  475. package/src/model/trellis-shared-m.ts +0 -151
  476. package/src/model/trellis-shared-scatter.ts +0 -144
  477. package/src/model/trellis-splitk-prefill.ts +0 -158
  478. package/src/model/trellis-tiled-prefill.ts +0 -136
  479. package/src/model/trellis-vector-expand.ts +0 -62
  480. package/src/model/trellis-wide-prefill.ts +0 -94
  481. package/src/model/turboquant-codec.ts +0 -89
  482. package/src/model/universal/archs.ts +0 -332
  483. package/src/model/universal/dense.ts +0 -612
  484. package/src/model/universal/modules.ts +0 -170
  485. package/src/model/universal/rope.ts +0 -381
  486. package/src/model/whisper.ts +0 -435
  487. package/src/native/expert_io.c +0 -523
  488. package/src/native/frame_extract.swift +0 -140
  489. package/src/native/mic_capture.swift +0 -92
  490. package/src/native-pack.ts +0 -163
  491. package/src/pi-provider.ts +0 -53
  492. package/src/pi-session.ts +0 -81
  493. package/src/pi-terminal.ts +0 -274
  494. package/src/pi-web.ts +0 -1940
  495. package/src/preflight.ts +0 -158
  496. package/src/prompt-cache.ts +0 -682
  497. package/src/quantize/allocator.ts +0 -627
  498. package/src/quantize/atomic-output.ts +0 -38
  499. package/src/quantize/calibration.ts +0 -181
  500. package/src/quantize/config-writer.ts +0 -145
  501. package/src/quantize/index.ts +0 -84
  502. package/src/quantize/job.ts +0 -162
  503. package/src/quantize/quantizer.ts +0 -666
  504. package/src/quantize/rotate.ts +0 -603
  505. package/src/quantize/safetensors-writer.ts +0 -249
  506. package/src/quantize/sensitivity.ts +0 -216
  507. package/src/quantize/trellis.ts +0 -586
  508. package/src/quantize/weight-transform.ts +0 -292
  509. package/src/registry.ts +0 -602
  510. package/src/runtime-config.ts +0 -77
  511. package/src/safetensors.ts +0 -165
  512. package/src/sampler.ts +0 -1012
  513. package/src/serve/admin-routes.ts +0 -184
  514. package/src/serve/assets/curve-terrain.html +0 -105
  515. package/src/serve/assets/training-inference-map.html +0 -575
  516. package/src/serve/audio-routes.ts +0 -323
  517. package/src/serve/aux-routes.ts +0 -132
  518. package/src/serve/batch-scheduler.ts +0 -8
  519. package/src/serve/checkpoint-identity.ts +0 -64
  520. package/src/serve/generation-gateway.ts +0 -537
  521. package/src/serve/isolate.ts +0 -609
  522. package/src/serve/kv-budget.ts +0 -14
  523. package/src/serve/lab-routes.ts +0 -341
  524. package/src/serve/lane-registry.ts +0 -45
  525. package/src/serve/model-admin-routes.ts +0 -155
  526. package/src/serve/model-binding.ts +0 -49
  527. package/src/serve/model-host.ts +0 -511
  528. package/src/serve/parent-application.ts +0 -56
  529. package/src/serve/prompt-response-trace.ts +0 -161
  530. package/src/serve/response-lease.ts +0 -24
  531. package/src/serve/session-search.ts +0 -326
  532. package/src/serve/static-routes.ts +0 -101
  533. package/src/serve/transcription-server.ts +0 -64
  534. package/src/serve/transcription-service.ts +0 -502
  535. package/src/server.ts +0 -1282
  536. package/src/spec/assistant-rows.ts +0 -93
  537. package/src/spec/assistant-source.ts +0 -126
  538. package/src/spec/cache-identity.ts +0 -22
  539. package/src/spec/deepspec-rows.ts +0 -29
  540. package/src/spec/deepspec-source.ts +0 -145
  541. package/src/spec/dflash-source.ts +0 -149
  542. package/src/spec/drafter.ts +0 -304
  543. package/src/spec/dspark/ab-stats.ts +0 -136
  544. package/src/spec/dspark/calibration.ts +0 -112
  545. package/src/spec/dspark/data-dflash.ts +0 -156
  546. package/src/spec/dspark/data.ts +0 -201
  547. package/src/spec/dspark/deepspec-module.ts +0 -776
  548. package/src/spec/dspark/generate-dflash.ts +0 -245
  549. package/src/spec/dspark/generate.ts +0 -290
  550. package/src/spec/dspark/loader.ts +0 -23
  551. package/src/spec/dspark/loss.ts +0 -213
  552. package/src/spec/dspark/module-dflash.ts +0 -560
  553. package/src/spec/dspark/module.ts +0 -540
  554. package/src/spec/dspark/quantize-drafter.ts +0 -91
  555. package/src/spec/dspark/sample.ts +0 -112
  556. package/src/spec/generate.ts +0 -276
  557. package/src/spec/glm52-mtp-graph.ts +0 -29
  558. package/src/spec/glm52-mtp-rows.ts +0 -132
  559. package/src/spec/glm52-mtp-source.ts +0 -318
  560. package/src/spec/glm52-mtp-state.ts +0 -33
  561. package/src/spec/ngram-source.ts +0 -226
  562. package/src/spec/projected-draft-rows.ts +0 -73
  563. package/src/spec/qwen-mtp-module.ts +0 -171
  564. package/src/spec/qwen-mtp-rows.ts +0 -230
  565. package/src/spec/qwen-mtp-source.ts +0 -386
  566. package/src/spec/qwen-mtp-state.ts +0 -30
  567. package/src/spec/serve-loop.ts +0 -587
  568. package/src/spec/source.ts +0 -228
  569. package/src/spec/two-model-rows.ts +0 -62
  570. package/src/spec/two-model.ts +0 -113
  571. package/src/ssd-cache.ts +0 -431
  572. package/src/ssd-durability.ts +0 -209
  573. package/src/storage/host-buffer.ts +0 -24
  574. package/src/storage/kv-writer.ts +0 -83
  575. package/src/storage/kv-writer.worker.js +0 -264
  576. package/src/storage/retention-policy.ts +0 -37
  577. package/src/tiered-prompt-cache.ts +0 -45
  578. package/src/tokenizer.ts +0 -335
  579. package/src/tool-approvals.ts +0 -131
  580. package/src/tool-call.ts +0 -695
  581. package/src/train/dataset.ts +0 -484
  582. package/src/train/diffusion-lora.ts +0 -216
  583. package/src/train/export.ts +0 -32
  584. package/src/train/flash-cce.ts +0 -1234
  585. package/src/train/forward.ts +0 -266
  586. package/src/train/fuse.ts +0 -243
  587. package/src/train/index.ts +0 -46
  588. package/src/train/job.ts +0 -205
  589. package/src/train/lora-params.ts +0 -254
  590. package/src/train/loss.ts +0 -1591
  591. package/src/train/merge.ts +0 -195
  592. package/src/train/optimizer.ts +0 -183
  593. package/src/train/prefix-shared.ts +0 -490
  594. package/src/train/rank.ts +0 -137
  595. package/src/train/segmented.ts +0 -1828
  596. package/src/train/steel-qmm-header.ts +0 -1461
  597. package/src/train/trainer.ts +0 -1221
  598. package/src/train/watch.ts +0 -542
  599. package/src/vision/diffusion-vision.ts +0 -620
  600. package/src/vision/embedder.ts +0 -176
  601. package/src/vision/preprocess.ts +0 -247
  602. package/src/vision/prompt.ts +0 -409
  603. package/src/vision/qwen3vl-preprocess.ts +0 -409
  604. package/src/vision/qwen3vl-prompt.ts +0 -233
  605. package/src/vision/qwen3vl-tower.ts +0 -566
  606. package/src/vision/siglip.ts +0 -607
  607. package/src/vision/video-frames.ts +0 -148
  608. package/src/web/app.html +0 -2155
  609. package/src/web/app.js +0 -5863
  610. package/src/web/skills/memory/SKILL.md +0 -120
  611. package/src/web/skills/web-research/SKILL.md +0 -46
  612. package/src/web/skills.ts +0 -97
  613. package/src/web/src/adapters-panel.ts +0 -288
  614. package/src/web/src/assistant.ts +0 -451
  615. package/src/web/src/chat.ts +0 -1060
  616. package/src/web/src/composer.ts +0 -962
  617. package/src/web/src/dataset.ts +0 -132
  618. package/src/web/src/finetune.ts +0 -267
  619. package/src/web/src/hub.ts +0 -428
  620. package/src/web/src/main.ts +0 -98
  621. package/src/web/src/markdown.ts +0 -0
  622. package/src/web/src/memory-panel.ts +0 -572
  623. package/src/web/src/model-picker.ts +0 -159
  624. package/src/web/src/palette.ts +0 -346
  625. package/src/web/src/protocol.ts +0 -26
  626. package/src/web/src/quantize.ts +0 -167
  627. package/src/web/src/rag.ts +0 -274
  628. package/src/web/src/sessions.ts +0 -469
  629. package/src/web/src/shell.ts +0 -804
  630. package/src/web/src/ui-catalog.ts +0 -78
  631. package/src/web/src/voice.ts +0 -141
  632. package/src/web/vendor/README.md +0 -61
  633. package/src/web-assets.ts +0 -47
  634. package/src/web-tools.ts +0 -478
  635. package/src/weights.ts +0 -255
  636. /package/src/{serve → server}/completion-sink.ts +0 -0
  637. /package/src/{serve → server}/generated-token-history.ts +0 -0
  638. /package/src/web/{icon.svg → public/icon.svg} +0 -0
  639. /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
  640. /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
@@ -1,671 +0,0 @@
1
- // mlx-bun memory — deterministic NORMALIZE pass (P6-T2). No model.
2
- //
3
- // After every write, before `commitVault`, an article is run through this pass
4
- // so the invariants the read path depends on are CONSTITUTIVE, not advisory.
5
- // Ported from lucien (~/Code/lucien): `normalize-footnotes.ts` (footnote
6
- // bijection + contiguous renumber) and `normalize-wikilinks.ts` (spaced →
7
- // underscore link canonicalization), extended with the Dreaming structural
8
- // guards (infobox key sort, `## References` last / `## See also` before it,
9
- // `{{stub}}` for thin articles, `title = H1 = stem`).
10
- //
11
- // Everything here is PURE (string in, string out) and idempotent: a second pass
12
- // over a normalized article is a byte-identical no-op. Every step is non-fatal —
13
- // a step that cannot complete logs a note and the others still run, so a single
14
- // malformed region never corrupts the vault. `normalizeVault` is the on-disk
15
- // entry the pipeline calls; the per-article core is `normalizeArticle`.
16
-
17
- import { readFile, writeFile } from "node:fs/promises";
18
- import { join } from "node:path";
19
- import { isFenceLine, fenceLabel, parseInfobox, repairFences, serializeInfobox } from "./article";
20
- import { articlesDir, listArticles, resolveWikilinkToStem, vaultRoot } from "./vault";
21
-
22
- // ---- shared scanners --------------------------------------------------
23
-
24
- const HEADING_RE = /^(#{1,6})\s+(.+)$/;
25
- const DEF_LINE = /^[ \t]*\[\^(\d+)\]:/;
26
- const SERIES_RE = /^\*Part of a series on \[\[([^\]]+)\]\]\.?\*$/;
27
- /** A merged-away title's one-line pointer at its canonical article. */
28
- const REDIRECT_RE = /^\*Redirects to \[\[[^\]]+\]\]\.?\*$/m;
29
- /** The `{{stub}}` template, recognized only as a line of its own. */
30
- const STUB_LINE_RE = /^\{\{stub\}\}\s*$/;
31
- /** The `{{Main}}` summary-style pointer (`*Main article: [[Target]]*`). */
32
- export const MAIN_POINTER_RE = /^\*Main article: \[\[[^\]]+\]\]\*$/;
33
-
34
- // ---- footnote integrity (local copy of lucien wikify.ts) -------------
35
-
36
- export interface CheckResult {
37
- ok: boolean;
38
- errors: string[];
39
- }
40
-
41
- /**
42
- * Verify footnote markers and definitions are consistent:
43
- * every `[^N]` body marker has a `[^N]:` definition and vice-versa; marker
44
- * numbers are contiguous from 1; every definition carries exactly one
45
- * backticked `conv:HASH`. (Ported from lucien `wikify.ts`.)
46
- */
47
- export function checkFootnoteIntegrity(text: string): CheckResult {
48
- const errors: string[] = [];
49
-
50
- const defNums = new Set<number>();
51
- const defLineByNum = new Map<number, string>();
52
- for (const m of text.matchAll(/^\[\^(\d+)\]:(.*)$/gm)) {
53
- const n = parseInt(m[1]!, 10);
54
- defNums.add(n);
55
- defLineByNum.set(n, m[2]!);
56
- }
57
-
58
- // Body markers = every `[^N]` NOT on a `[^N]:` definition line. Only a
59
- // line-START `[^N]:` is a definition; a marker glued to a list colon
60
- // (`two types[^2]:`) is still a marker.
61
- const bodyText = text
62
- .split("\n")
63
- .filter((l) => !/^\[\^\d+\]:/.test(l))
64
- .join("\n");
65
- const markerNums = new Set<number>();
66
- for (const m of bodyText.matchAll(/\[\^(\d+)\]/g)) {
67
- markerNums.add(parseInt(m[1]!, 10));
68
- }
69
-
70
- for (const n of markerNums) {
71
- if (!defNums.has(n)) errors.push(`marker [^${n}] has no definition`);
72
- }
73
- for (const n of defNums) {
74
- if (!markerNums.has(n)) errors.push(`definition [^${n}] has no marker`);
75
- }
76
-
77
- const all = [...new Set([...markerNums, ...defNums])].sort((a, b) => a - b);
78
- for (let i = 0; i < all.length; i++) {
79
- if (all[i] !== i + 1) {
80
- errors.push(`footnote numbers not contiguous from 1 (saw ${all.join(",")})`);
81
- break;
82
- }
83
- }
84
-
85
- for (const [n, line] of defLineByNum) {
86
- const backticked = line.match(/`conv:[0-9a-z]{8}`/gi) ?? [];
87
- if (backticked.length !== 1) {
88
- errors.push(`[^${n}] definition lacks a backticked \`conv:HASH\` (found ${backticked.length})`);
89
- }
90
- }
91
-
92
- return { ok: errors.length === 0, errors };
93
- }
94
-
95
- /** True when two `[^N]:` definitions cite the same `conv:HASH` (the duplicate
96
- * the merge step collapses); ignores defs without a hash. */
97
- function hasDuplicateConvDefs(text: string): boolean {
98
- const seen = new Set<string>();
99
- for (const line of text.split("\n")) {
100
- const m = line.match(/^[ \t]*\[\^(\d+)\]:(.*)$/);
101
- if (!m) continue;
102
- const c = m[2]!.match(/conv:[0-9a-z]{8}/i);
103
- if (!c) continue;
104
- const h = c[0]!.toLowerCase();
105
- if (seen.has(h)) return true;
106
- seen.add(h);
107
- }
108
- return false;
109
- }
110
-
111
- // ---- footnote normalization (ported + merge) -------------------------
112
-
113
- export interface NormalizeFootnoteResult {
114
- article: string;
115
- changed: boolean;
116
- /** Orphan body markers (no definition) that were dropped. */
117
- droppedMarkers: number[];
118
- /** Orphan definitions (no body marker) that were dropped. */
119
- droppedDefs: { num: number; conv: string | null }[];
120
- /** Definitions merged into an earlier def citing the same `conv:HASH`. */
121
- mergedDefs: number[];
122
- /** Auditable summary of what changed, or null on a no-op. */
123
- talk: string | null;
124
- }
125
-
126
- /** Distinct body-marker numbers in order of first appearance (defs masked). */
127
- function bodyMarkerOrder(text: string): number[] {
128
- const masked = text
129
- .split("\n")
130
- .map((l) => (DEF_LINE.test(l) ? "" : l))
131
- .join("\n");
132
- const order: number[] = [];
133
- const seen = new Set<number>();
134
- for (const m of masked.matchAll(/\[\^(\d+)\]/g)) {
135
- const n = parseInt(m[1]!, 10);
136
- if (!seen.has(n)) {
137
- seen.add(n);
138
- order.push(n);
139
- }
140
- }
141
- return order;
142
- }
143
-
144
- /**
145
- * Deterministically repair footnote integrity (ported from lucien
146
- * `normalize-footnotes.ts`, extended to merge duplicate `conv:HASH` defs):
147
- * drop orphan markers and orphan defs, collapse two defs that cite the same
148
- * conversation into the earlier one, then renumber the survivors 1..k in order
149
- * of first body appearance. A bijective, duplicate-free article is returned
150
- * byte-identical (no-op), hence idempotent. Throws only if the post-condition
151
- * (`checkFootnoteIntegrity`) fails — the orchestrator catches that.
152
- */
153
- export function normalizeFootnotes(article: string): NormalizeFootnoteResult {
154
- if (checkFootnoteIntegrity(article).ok && !hasDuplicateConvDefs(article)) {
155
- return { article, changed: false, droppedMarkers: [], droppedDefs: [], mergedDefs: [], talk: null };
156
- }
157
-
158
- const defNums = new Set<number>();
159
- const defConv = new Map<number, string | null>();
160
- for (const line of article.split("\n")) {
161
- const m = line.match(/^[ \t]*\[\^(\d+)\]:(.*)$/);
162
- if (m) {
163
- const n = parseInt(m[1]!, 10);
164
- defNums.add(n);
165
- const c = m[2]!.match(/conv:[0-9a-z]{8}/i);
166
- defConv.set(n, c ? c[0]!.toLowerCase() : null);
167
- }
168
- }
169
-
170
- const bodyOrder = bodyMarkerOrder(article);
171
- const bodySet = new Set(bodyOrder);
172
-
173
- // Markers that also have a definition — the merge/renumber candidates.
174
- const candidates = bodyOrder.filter((n) => defNums.has(n));
175
- const droppedMarkers = bodyOrder.filter((n) => !defNums.has(n));
176
- const droppedDefs = [...defNums]
177
- .filter((n) => !bodySet.has(n))
178
- .sort((a, b) => a - b)
179
- .map((n) => ({ num: n, conv: defConv.get(n) ?? null }));
180
-
181
- // Merge: each conv:HASH maps to its first-appearing candidate.
182
- const canonByConv = new Map<string, number>();
183
- const canonMap = new Map<number, number>();
184
- for (const n of candidates) {
185
- const c = defConv.get(n) ?? null;
186
- if (c === null) {
187
- canonMap.set(n, n);
188
- continue;
189
- }
190
- if (!canonByConv.has(c)) canonByConv.set(c, n);
191
- canonMap.set(n, canonByConv.get(c)!);
192
- }
193
- const mergedDefs = candidates.filter((n) => canonMap.get(n) !== n);
194
-
195
- // Survivors in first-appearance order → contiguous 1..k.
196
- const survivorOrder: number[] = [];
197
- const seenSurv = new Set<number>();
198
- for (const n of candidates) {
199
- const c = canonMap.get(n)!;
200
- if (!seenSurv.has(c)) {
201
- seenSurv.add(c);
202
- survivorOrder.push(c);
203
- }
204
- }
205
- const remap = new Map<number, number>();
206
- survivorOrder.forEach((oldN, i) => remap.set(oldN, i + 1));
207
-
208
- const dropMarkerSet = new Set(droppedMarkers);
209
- const dropDefSet = new Set<number>([...droppedDefs.map((d) => d.num), ...mergedDefs]);
210
-
211
- const out = article
212
- .split("\n")
213
- .filter((line) => {
214
- const m = line.match(DEF_LINE);
215
- return !(m && dropDefSet.has(parseInt(m[1]!, 10)));
216
- })
217
- .map((line) =>
218
- line.replace(/[ \t]?\[\^(\d+)\]/g, (whole, num: string) => {
219
- const n = parseInt(num, 10);
220
- if (dropMarkerSet.has(n)) return ""; // orphan marker
221
- const canon = canonMap.get(n) ?? n;
222
- const nn = remap.get(canon);
223
- const lead = /^[ \t]/.test(whole) ? whole[0]! : "";
224
- return nn ? `${lead}[^${nn}]` : whole;
225
- }),
226
- )
227
- .join("\n");
228
-
229
- const post = checkFootnoteIntegrity(out);
230
- if (!post.ok) {
231
- throw new Error(`normalize-footnotes post-condition failed: ${post.errors.join("; ")}`);
232
- }
233
-
234
- const parts: string[] = [];
235
- if (droppedMarkers.length) {
236
- parts.push(
237
- `Dropped ${droppedMarkers.length} orphan citation marker(s) — ` +
238
- droppedMarkers.map((n) => `[^${n}]`).join(", ") +
239
- ` — marker emitted with no definition; nothing recoverable, prose left intact.`,
240
- );
241
- }
242
- if (droppedDefs.length) {
243
- parts.push(
244
- `Dropped ${droppedDefs.length} unused definition(s): ` +
245
- droppedDefs.map((d) => `[^${d.num}]${d.conv ? ` (\`${d.conv}\`)` : ""}`).join(", ") +
246
- ` — no body marker referenced them.`,
247
- );
248
- }
249
- if (mergedDefs.length) {
250
- parts.push(
251
- `Merged ${mergedDefs.length} duplicate definition(s) (${mergedDefs
252
- .map((n) => `[^${n}]`)
253
- .join(", ")}) into the earlier footnote citing the same conversation.`,
254
- );
255
- }
256
- parts.push("Renumbered surviving footnotes contiguously from 1.");
257
-
258
- return {
259
- article: out,
260
- changed: out !== article,
261
- droppedMarkers,
262
- droppedDefs,
263
- mergedDefs,
264
- talk: parts.join(" "),
265
- };
266
- }
267
-
268
- // ---- wikilink canonicalization (ported) ------------------------------
269
-
270
- export interface NormalizeWikilinkResult {
271
- content: string;
272
- /** Number of link targets rewritten to their canonical stem. */
273
- edits: number;
274
- /** Distinct unresolved (redlink) targets — flagged, not modified. */
275
- orphans: string[];
276
- }
277
-
278
- /**
279
- * Rewrite spaced/uncanonical wikilink targets to their underscore stem when the
280
- * stem is a known article (ported from lucien `normalize-wikilinks.ts`, using
281
- * `resolveWikilinkToStem` for resolution). The alias (`|alias`) and section
282
- * anchor (`#Section`) are display/match text and are preserved verbatim;
283
- * `conv:` and `Category:` links are left alone. Unresolved targets are true
284
- * redlinks — collected for flagging, never rewritten. Idempotent: an already
285
- * canonical link is untouched. Infobox entity-values are normalized by the same
286
- * pass (the replace runs over the whole article text, fence included).
287
- */
288
- export function normalizeWikilinks(content: string, stems: Set<string>): NormalizeWikilinkResult {
289
- let edits = 0;
290
- const orphans = new Set<string>();
291
-
292
- const out = content.replace(/\[\[([^\]]+?)\]\]/g, (whole, inner: string) => {
293
- const pipeIdx = inner.indexOf("|");
294
- const alias = pipeIdx === -1 ? null : inner.slice(pipeIdx + 1);
295
- const beforeAlias = pipeIdx === -1 ? inner : inner.slice(0, pipeIdx);
296
-
297
- const hashIdx = beforeAlias.indexOf("#");
298
- const section = hashIdx === -1 ? null : beforeAlias.slice(hashIdx + 1);
299
- const target = hashIdx === -1 ? beforeAlias : beforeAlias.slice(0, hashIdx);
300
-
301
- const t = target.trim();
302
- if (!t || /^conv:/i.test(t) || /^Category:/i.test(t)) return whole;
303
-
304
- const resolved = resolveWikilinkToStem(t, stems);
305
- if (resolved === null) {
306
- orphans.add(t); // true redlink — flag, leave verbatim
307
- return whole;
308
- }
309
- if (resolved === target) return whole; // already canonical
310
-
311
- let rebuilt = resolved;
312
- if (section !== null) rebuilt += `#${section}`;
313
- if (alias !== null) rebuilt += `|${alias}`;
314
- edits++;
315
- return `[[${rebuilt}]]`;
316
- });
317
-
318
- return { content: out, edits, orphans: [...orphans] };
319
- }
320
-
321
- // ---- infobox key sort -------------------------------------------------
322
-
323
- function findInfoBlock(lines: string[]): { start: number; end: number } | null {
324
- for (let i = 0; i < lines.length; i++) {
325
- if (isFenceLine(lines[i]!) && fenceLabel(lines[i]!) === "info") {
326
- for (let j = i + 1; j < lines.length; j++) {
327
- if (isFenceLine(lines[j]!)) return { start: i, end: j };
328
- }
329
- return null; // unterminated
330
- }
331
- }
332
- return null;
333
- }
334
-
335
- /** Schema keys lead (`type`, `kind`), `aliases` trails, the rest alphabetical. */
336
- function infoboxKeyRank(key: string): number {
337
- if (key === "type") return 0;
338
- if (key === "kind") return 1;
339
- if (key === "aliases") return 3;
340
- return 2;
341
- }
342
-
343
- /** Sort an article's infobox fields into a deterministic, idempotent order. */
344
- export function sortInfoboxKeys(content: string): { content: string; changed: boolean } {
345
- const box = parseInfobox(content);
346
- if (!box || box.fields.length === 0) return { content, changed: false };
347
-
348
- const sorted = box.fields
349
- .map((f, i) => ({ f, i }))
350
- .sort((a, b) => {
351
- const ra = infoboxKeyRank(a.f.key);
352
- const rb = infoboxKeyRank(b.f.key);
353
- if (ra !== rb) return ra - rb;
354
- const c = a.f.key.localeCompare(b.f.key);
355
- return c !== 0 ? c : a.i - b.i; // stable on equal keys
356
- })
357
- .map((x) => x.f);
358
-
359
- const sameOrder = sorted.every((f, i) => f === box.fields[i]);
360
- if (sameOrder) return { content, changed: false };
361
-
362
- const lines = content.split(/\r?\n/);
363
- const block = findInfoBlock(lines);
364
- if (!block) return { content, changed: false };
365
-
366
- const rendered = serializeInfobox({ ...box, fields: sorted }).split("\n");
367
- const next = [...lines.slice(0, block.start), ...rendered, ...lines.slice(block.end + 1)].join("\n");
368
- return { content: next, changed: next !== content };
369
- }
370
-
371
- // ---- structural guards ------------------------------------------------
372
-
373
- interface TopSection {
374
- kind: "body" | "see" | "notes" | "refs";
375
- lines: string[];
376
- }
377
-
378
- function splitTopSections(content: string): { head: string[]; sections: TopSection[] } {
379
- const lines = content.split(/\r?\n/);
380
- const head: string[] = [];
381
- const sections: TopSection[] = [];
382
- let cur: TopSection | null = null;
383
- let inFence = false;
384
- for (const line of lines) {
385
- if (isFenceLine(line)) {
386
- inFence = !inFence;
387
- (cur ? cur.lines : head).push(line);
388
- continue;
389
- }
390
- if (!inFence) {
391
- const h = HEADING_RE.exec(line);
392
- if (h && h[1]!.length === 2) {
393
- const title = h[2]!.trim().toLowerCase();
394
- const kind: TopSection["kind"] =
395
- title === "see also" ? "see" : title === "notes" ? "notes" : title === "references" ? "refs" : "body";
396
- cur = { kind, lines: [line] };
397
- sections.push(cur);
398
- continue;
399
- }
400
- }
401
- (cur ? cur.lines : head).push(line);
402
- }
403
- return { head, sections };
404
- }
405
-
406
- /** Merge several same-kind trailing-meta sections (the duplicate `## References` /
407
- * `## See also` blocks a fence-confused PATCH/cross-link left behind) into ONE:
408
- * keep the first heading, then the union of every block's body lines with
409
- * duplicate lines dropped (first occurrence wins) so repeated See-also bullets
410
- * collapse and split footnote defs coalesce. Idempotent on a singleton group. */
411
- function mergeMetaGroup(group: TopSection[]): TopSection {
412
- if (group.length === 1) return group[0]!;
413
- const heading = group[0]!.lines[0]!;
414
- const body: string[] = [];
415
- const seen = new Set<string>();
416
- for (const s of group) {
417
- for (const line of s.lines.slice(1)) {
418
- const key = line.trim();
419
- if (key === "") {
420
- if (body.length && body[body.length - 1] !== "") body.push("");
421
- continue;
422
- }
423
- if (seen.has(key)) continue;
424
- seen.add(key);
425
- body.push(line);
426
- }
427
- }
428
- while (body.length && body[body.length - 1] === "") body.pop();
429
- return { kind: group[0]!.kind, lines: [heading, ...body, ""] };
430
- }
431
-
432
- /** Reorder trailing meta sections so body → `See also` → `Notes` → `References`
433
- * (References always last), MERGING any duplicate same-kind meta blocks into one
434
- * along the way. Idempotent: an already-correct article (one block per kind, in
435
- * order) is returned untouched. */
436
- export function reorderSections(content: string): { content: string; changed: boolean } {
437
- const { head, sections } = splitTopSections(content);
438
- if (sections.length === 0) return { content, changed: false };
439
-
440
- // Body sections stay distinct and in document order; the trailing-meta kinds are
441
- // singletons by grammar, so collapse any duplicates into one block per kind.
442
- const ordered: TopSection[] = sections.filter((s) => s.kind === "body");
443
- for (const kind of ["see", "notes", "refs"] as const) {
444
- const group = sections.filter((s) => s.kind === kind);
445
- if (group.length) ordered.push(mergeMetaGroup(group));
446
- }
447
-
448
- const same = ordered.length === sections.length && ordered.every((s, i) => s === sections[i]);
449
- if (same) return { content, changed: false };
450
-
451
- const next = [...head, ...ordered.flatMap((s) => s.lines)].join("\n");
452
- return { content: next, changed: next !== content };
453
- }
454
-
455
- /** Enforce `title = H1 = stem` (underscores → spaces). Rewrites a divergent H1
456
- * and prepends one when absent. */
457
- export function enforceH1Title(content: string, stem: string): { content: string; changed: boolean } {
458
- const canonical = stem.replace(/_/g, " ");
459
- const lines = content.split(/\r?\n/);
460
- let inFence = false;
461
- for (let i = 0; i < lines.length; i++) {
462
- if (isFenceLine(lines[i]!)) {
463
- inFence = !inFence;
464
- continue;
465
- }
466
- if (inFence) continue;
467
- const h = HEADING_RE.exec(lines[i]!);
468
- if (h && h[1]!.length === 1) {
469
- if (h[2]!.trim() === canonical) return { content, changed: false };
470
- lines[i] = `# ${canonical}`;
471
- return { content: lines.join("\n"), changed: true };
472
- }
473
- }
474
- // No H1 found — prepend the canonical title.
475
- return { content: `# ${canonical}\n\n${content}`, changed: true };
476
- }
477
-
478
- /** Body-section count and body-prose word count, EXCLUDING the infobox and the
479
- * `## References` section (the L1 stub threshold inputs). */
480
- export function articleThinness(content: string): { bodySections: number; bodyWords: number; stub: boolean } {
481
- const lines = content.split(/\r?\n/);
482
- let inFence = false;
483
- let inRefs = false;
484
- let bodySections = 0;
485
- let bodyWords = 0;
486
- for (const line of lines) {
487
- if (isFenceLine(line)) {
488
- inFence = !inFence;
489
- continue;
490
- }
491
- if (inFence) continue;
492
- const h = HEADING_RE.exec(line);
493
- if (h) {
494
- if (h[1]!.length === 2) {
495
- const title = h[2]!.trim().toLowerCase();
496
- inRefs = title === "references";
497
- if (title !== "references" && title !== "see also" && title !== "notes") bodySections++;
498
- }
499
- continue; // headings are not prose
500
- }
501
- if (inRefs) continue;
502
- const t = line.trim();
503
- if (!t) continue;
504
- if (STUB_LINE_RE.test(t)) continue;
505
- if (/^categories:/i.test(t)) continue;
506
- if (SERIES_RE.test(t)) continue;
507
- bodyWords += t.split(/\s+/).length;
508
- }
509
- return { bodySections, bodyWords, stub: bodySections < 2 || bodyWords < 40 };
510
- }
511
-
512
- /** True when the article carries a `{{stub}}` line. */
513
- export function hasStubMarker(content: string): boolean {
514
- return content.split(/\r?\n/).some((l) => STUB_LINE_RE.test(l));
515
- }
516
-
517
- /** Mark a thin article `{{stub}}` (after the H1); remove a stale marker once the
518
- * article has outgrown the threshold. */
519
- export function stubGuard(content: string): { content: string; changed: boolean } {
520
- const thin = articleThinness(content).stub;
521
- const has = hasStubMarker(content);
522
- if (thin === has) return { content, changed: false };
523
-
524
- const lines = content.split(/\r?\n/);
525
- if (!thin && has) {
526
- const next = lines.filter((l) => !STUB_LINE_RE.test(l)).join("\n");
527
- return { content: next, changed: next !== content };
528
- }
529
- // thin && !has — insert after the H1 (or at the very top if none).
530
- let inFence = false;
531
- let h1 = -1;
532
- for (let i = 0; i < lines.length; i++) {
533
- if (isFenceLine(lines[i]!)) {
534
- inFence = !inFence;
535
- continue;
536
- }
537
- if (inFence) continue;
538
- const h = HEADING_RE.exec(lines[i]!);
539
- if (h && h[1]!.length === 1) {
540
- h1 = i;
541
- break;
542
- }
543
- }
544
- if (h1 < 0) lines.unshift("{{stub}}", "");
545
- else lines.splice(h1 + 1, 0, "", "{{stub}}");
546
- return { content: lines.join("\n"), changed: true };
547
- }
548
-
549
- // ---- orchestrator -----------------------------------------------------
550
-
551
- export interface NormalizeArticleResult {
552
- content: string;
553
- changed: boolean;
554
- /** Human-readable record of every normalization applied (non-fatal log). */
555
- notes: string[];
556
- /** Whether the normalized article is marked `{{stub}}`. */
557
- stub: boolean;
558
- /** Whether the article is a merge redirect (heavy guards are skipped). */
559
- redirect: boolean;
560
- }
561
-
562
- /**
563
- * Run the full deterministic NORMALIZE pass over one article. Every step is
564
- * non-fatal: a step that throws (a footnote post-condition it cannot satisfy,
565
- * say) is logged and skipped while the others still run, so a malformed region
566
- * never blocks the rest. Idempotent.
567
- */
568
- export function normalizeArticle(content: string, opts: { stem: string; stems: Set<string> }): NormalizeArticleResult {
569
- const notes: string[] = [];
570
- let out = content;
571
- const redirect = REDIRECT_RE.test(out);
572
-
573
- // 0. Fence repair — heal an unbalanced ``` BEFORE any fence-aware step runs.
574
- // An odd fence count leaves reorder/stub/H1 (and the read path) stuck "in code"
575
- // for the rest of the file, so trailing ## References / ## See also are never
576
- // recognized. Closing the dangling fence restores them. Non-fatal, idempotent.
577
- const fx = repairFences(out);
578
- if (fx.changed) {
579
- out = fx.content;
580
- notes.push("repaired unbalanced code fence");
581
- }
582
-
583
- // 1. Footnote bijection + renumber + merge.
584
- try {
585
- const fr = normalizeFootnotes(out);
586
- if (fr.changed) {
587
- out = fr.article;
588
- if (fr.droppedMarkers.length) notes.push(`dropped ${fr.droppedMarkers.length} orphan footnote marker(s)`);
589
- if (fr.droppedDefs.length) notes.push(`dropped ${fr.droppedDefs.length} orphan footnote def(s)`);
590
- if (fr.mergedDefs.length) notes.push(`merged ${fr.mergedDefs.length} duplicate footnote def(s)`);
591
- notes.push("renumbered footnotes contiguously");
592
- }
593
- } catch (err) {
594
- notes.push(`footnote normalization skipped: ${(err as Error).message}`);
595
- }
596
-
597
- // 2. Wikilink canonicalization (prose + infobox entity-values).
598
- const wl = normalizeWikilinks(out, opts.stems);
599
- if (wl.edits > 0) {
600
- out = wl.content;
601
- notes.push(`canonicalized ${wl.edits} wikilink(s)`);
602
- }
603
- if (wl.orphans.length) notes.push(`unresolved wikilink(s): ${wl.orphans.join(", ")}`);
604
-
605
- // 3. Infobox key sort.
606
- const ib = sortInfoboxKeys(out);
607
- if (ib.changed) {
608
- out = ib.content;
609
- notes.push("sorted infobox keys");
610
- }
611
-
612
- // 4. Structural guards.
613
- const h1 = enforceH1Title(out, opts.stem);
614
- if (h1.changed) {
615
- out = h1.content;
616
- notes.push("normalized H1 title to stem");
617
- }
618
- if (!redirect) {
619
- const ro = reorderSections(out);
620
- if (ro.changed) {
621
- out = ro.content;
622
- notes.push("reordered trailing sections (References last)");
623
- }
624
- const sg = stubGuard(out);
625
- if (sg.changed) {
626
- out = sg.content;
627
- notes.push(hasStubMarker(out) ? "marked {{stub}} (thin article)" : "removed stale {{stub}}");
628
- }
629
- }
630
-
631
- return { content: out, changed: out !== content, notes, stub: hasStubMarker(out), redirect };
632
- }
633
-
634
- // ---- on-disk entry (runs after every write, before commitVault) ------
635
-
636
- export interface VaultNormalizeSummary {
637
- /** Stems whose on-disk content changed. */
638
- normalized: string[];
639
- /** Per-stem normalization notes (only stems with at least one note). */
640
- notes: Record<string, string[]>;
641
- }
642
-
643
- /**
644
- * Normalize every article in the vault, writing back the ones that changed.
645
- * Best-effort and non-fatal per article; the caller commits afterward. The stem
646
- * set is the whole article list so wikilink resolution sees every neighbor.
647
- */
648
- export async function normalizeVault(root = vaultRoot()): Promise<VaultNormalizeSummary> {
649
- const stems = await listArticles(root);
650
- const stemSet = new Set(stems);
651
- const normalized: string[] = [];
652
- const notes: Record<string, string[]> = {};
653
-
654
- for (const stem of stems) {
655
- const path = join(articlesDir(root), `${stem}.md`);
656
- let content: string;
657
- try {
658
- content = await readFile(path, "utf8");
659
- } catch {
660
- continue;
661
- }
662
- const r = normalizeArticle(content, { stem, stems: stemSet });
663
- if (r.notes.length) notes[stem] = r.notes;
664
- if (r.changed) {
665
- await writeFile(path, r.content);
666
- normalized.push(stem);
667
- }
668
- }
669
-
670
- return { normalized, notes };
671
- }
@@ -1,22 +0,0 @@
1
- // mlx-bun memory — parse contracts for model outputs.
2
- //
3
- // The synthesis pipeline drives the model with small, structured prompts and
4
- // needs deterministic parsing of free-text completions back into typed values.
5
- // Two shapes cover the cases: a yes/no binary gate and a newline list.
6
-
7
- /** Binary gate: true iff the output starts with `y`/`Y` (everything else → false). */
8
- export function parseBinary(out: string): boolean {
9
- return /^\s*y/i.test(out);
10
- }
11
-
12
- /**
13
- * List output: split on newlines, trim each line, and drop empties as well as
14
- * any line that is exactly "NONE" (case-insensitive) — the model's sentinel for
15
- * "no items".
16
- */
17
- export function parseLines(out: string): string[] {
18
- return out
19
- .split("\n")
20
- .map((line) => line.trim())
21
- .filter((line) => line.length > 0 && line.toLowerCase() !== "none");
22
- }