mlx-bun 0.0.13 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -578
- package/bin/mlx-bun.mjs +1 -1
- package/docs/README.md +91 -0
- package/docs/{design → archive}/hlg-sampling.md +3 -3
- package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
- package/docs/{design → archive/investigations}/colibri-glm52-port.md +1 -1
- package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
- package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
- package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
- package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
- package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
- package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
- package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
- package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
- package/docs/{planning → archive/planning}/chunk-task-roadmap.md +1 -1
- package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +4 -4
- package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +1 -1
- package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
- package/docs/archive/planning/release-notes-v0.2.0.md +49 -0
- package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
- package/docs/design/batching.md +569 -0
- package/docs/design/decode-speed-program.md +3178 -169
- package/docs/design/dreaming-nightly-pipeline.md +675 -282
- package/docs/design/generic-model-support.md +579 -334
- package/docs/design/kv-cache.md +680 -0
- package/docs/design/orpo-training.md +673 -1239
- package/docs/design/speculative-decoding.md +1627 -0
- package/docs/design/turboquant.md +2102 -0
- package/docs/design/unified-engine-frontier-plan.md +1831 -727
- package/docs/design/web-chat-redesign.md +666 -1083
- package/docs/planning/PRODUCT_ROADMAP.md +34 -1
- package/docs/planning/release-notes-v0.3.0.md +35 -0
- package/docs/planning/video-series.md +421 -0
- package/docs/reference/benchmarks.md +1162 -0
- package/docs/reference/cli.md +395 -149
- package/docs/reference/distribution.md +321 -181
- package/docs/reference/environment.md +348 -0
- package/docs/reference/glossary.md +39 -0
- package/docs/reference/library-api.md +580 -142
- package/docs/reference/memory.md +227 -64
- package/docs/reference/models.md +137 -6
- package/docs/reference/server-api.md +938 -422
- package/docs/reference/server-config.md +652 -320
- package/docs/reference/training.md +393 -254
- package/docs/reference/troubleshooting.md +166 -0
- package/package.json +10 -5
- package/src/admission-plan.ts +18 -0
- package/src/anthropic.ts +92 -3
- package/src/audio/decode.ts +2 -2
- package/src/audio/features.ts +2 -2
- package/src/backends/mlx/autoregressive.ts +108 -0
- package/src/backends/mlx/batch-group.ts +1646 -0
- package/src/backends/mlx/diffusion.ts +39 -0
- package/src/backends/mlx/draft-target.ts +47 -0
- package/src/backends/mlx/evaluation.ts +105 -0
- package/src/backends/mlx/fill-append.ts +45 -0
- package/src/backends/mlx/gateway-binding.ts +71 -0
- package/src/backends/mlx/graph.ts +38 -0
- package/src/backends/mlx/memory-client.ts +189 -0
- package/src/backends/mlx/memory-guard.ts +40 -0
- package/src/backends/mlx/methods.ts +90 -0
- package/src/backends/mlx/model-prompt.ts +164 -0
- package/src/backends/mlx/model-serving.ts +79 -0
- package/src/backends/mlx/prefill.ts +33 -0
- package/src/backends/mlx/request-policy.ts +20 -0
- package/src/backends/mlx/rollback.ts +51 -0
- package/src/backends/mlx/serial-executor.ts +273 -0
- package/src/backends/mlx/speculative.ts +114 -0
- package/src/backends/mlx/state-views.ts +26 -0
- package/src/backends/mlx/text-engine.ts +73 -0
- package/src/cli.ts +189 -61
- package/src/client.ts +66 -0
- package/src/config.ts +21 -4
- package/src/contracts/completion.ts +16 -0
- package/src/contracts/execution.ts +49 -0
- package/src/contracts/generation.ts +103 -0
- package/src/contracts/host.ts +7 -0
- package/src/contracts/jobs.ts +66 -0
- package/src/contracts/pi-provider.ts +30 -0
- package/src/contracts/pi.ts +259 -0
- package/src/contracts/resources.ts +18 -0
- package/src/contracts/scheduling.ts +27 -0
- package/src/contracts/tsconfig.json +14 -0
- package/src/diffusion/diffusion-generate.ts +218 -153
- package/src/embed.ts +1 -1
- package/src/engine/admission.ts +59 -0
- package/src/engine/cancellation.ts +38 -0
- package/src/engine/engine.ts +56 -0
- package/src/engine/execution-coordinator.ts +70 -0
- package/src/engine/execution-plan.ts +51 -0
- package/src/engine/resources.ts +42 -0
- package/src/engine/scheduler.ts +67 -0
- package/src/engine/session.ts +247 -0
- package/src/eval/README.md +44 -1
- package/src/eval/kl.ts +263 -23
- package/src/eval/reference-logits.ts +207 -0
- package/src/eval/runner.ts +10 -79
- package/src/eval/tasks/bfcl.ts +2 -1
- package/src/eval/tasks/gsm8k.ts +2 -1
- package/src/eval/tasks/hashhop.ts +2 -1
- package/src/eval/tasks/humaneval.ts +5 -4
- package/src/eval/tasks/ifeval.ts +2 -1
- package/src/eval/tasks/mmlu.ts +2 -1
- package/src/expert-io.ts +3 -1
- package/src/expert-offload.ts +3 -1
- package/src/fill/echo-index.ts +188 -0
- package/src/fill/fill-session.ts +452 -0
- package/src/fill/proposal.ts +68 -0
- package/src/fill/schema-rows.ts +506 -0
- package/src/fill/tool-boundary.ts +103 -0
- package/src/fit.ts +24 -43
- package/src/generate.ts +740 -337
- package/src/grammar.ts +14 -8
- package/src/harness-pi.ts +15 -34
- package/src/hub-rest.ts +4 -4
- package/src/index.ts +27 -0
- package/src/inference/denoising.ts +17 -0
- package/src/inference/graph.ts +33 -0
- package/src/inference/prefill.ts +39 -0
- package/src/inference/rollback.ts +7 -0
- package/src/jobs/db.ts +4 -0
- package/src/jobs/index.ts +2 -0
- package/src/jobs/job-entry.ts +15 -14
- package/src/jobs/runner.ts +98 -13
- package/src/jobs/task-client.ts +19 -0
- package/src/jobs/types.ts +2 -58
- package/src/kv-scheme.ts +199 -0
- package/src/kv-store.ts +459 -234
- package/src/lab/README.md +18 -0
- package/src/{assets → lab/curve}/curve-designer.html +2 -2
- package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
- package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +7 -5
- package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
- package/src/library.ts +40 -0
- package/src/lora.ts +18 -0
- package/src/media-fetch.ts +20 -4
- package/src/memory/article.ts +1 -1
- package/src/memory/chunk.ts +1 -1
- package/src/memory/model.ts +32 -170
- package/src/memory/prompts.ts +1 -1
- package/src/memory/rest.ts +1 -1
- package/src/memory/schedule.ts +1 -1
- package/src/memory/stages.ts +4 -1
- package/src/memory/vault.ts +3 -4
- package/src/mlx/array.ts +9 -10
- package/src/mlx/compile.ts +12 -2
- package/src/mlx/ffi.ts +66 -22
- package/src/mlx/materialize.ts +23 -0
- package/src/mlx/metal-kernel.ts +10 -11
- package/src/mlx/ops.ts +64 -19
- package/src/mlx/quantized-rows.ts +36 -0
- package/src/mlx/token-bitmask.ts +52 -0
- package/src/mlx/turboquant-kv-decode.ts +82 -0
- package/src/mlx/turboquant-kv-inverse.ts +122 -0
- package/src/mlx/turboquant-ops.ts +33 -3
- package/src/mlx/turboquant-tables.ts +2 -2
- package/src/model/batched-mask.ts +9 -3
- package/src/model/batched-quant.ts +2 -2
- package/src/model/batched-rotating-quant.ts +45 -99
- package/src/model/batched-rotating-state.ts +73 -0
- package/src/model/batched-rotating.ts +57 -106
- package/src/model/batched-row-storage.ts +127 -0
- package/src/model/compiled-decode.ts +4 -3
- package/src/model/diffusion-gemma.ts +8 -8
- package/src/model/factory.ts +87 -49
- package/src/model/fingerprint.ts +1 -1
- package/src/model/flash-attention.ts +3 -3
- package/src/model/gemma4-base.ts +187 -17
- package/src/model/gemma4.ts +6 -6
- package/src/model/generated/gemma4-12b.ts +52 -148
- package/src/model/generated/gemma4-26b.ts +34 -94
- package/src/model/generated/gemma4-e4b.ts +28 -76
- package/src/model/glm52-cache.ts +19 -9
- package/src/model/glm52-dsa.ts +13 -9
- package/src/model/glm52-memory.ts +28 -1
- package/src/model/implementation.ts +69 -0
- package/src/model/minicpm5.ts +7 -8
- package/src/model/profile.ts +443 -0
- package/src/model/qwen-append.ts +12 -0
- package/src/model/qwen-conv.ts +52 -0
- package/src/model/qwen3-delta.ts +98 -2
- package/src/model/qwen3-mrope.ts +252 -0
- package/src/model/qwen3_5-checkpoint.ts +164 -0
- package/src/model/qwen3_5.ts +336 -60
- package/src/model/support.ts +1 -1
- package/src/model/trellis-balanced-scatter.ts +51 -0
- package/src/model/trellis-linear.ts +672 -0
- package/src/model/trellis-shared-m.ts +151 -0
- package/src/model/trellis-shared-scatter.ts +144 -0
- package/src/model/trellis-splitk-prefill.ts +158 -0
- package/src/model/trellis-tiled-prefill.ts +136 -0
- package/src/model/trellis-vector-expand.ts +62 -0
- package/src/model/trellis-wide-prefill.ts +94 -0
- package/src/model/universal/dense.ts +1 -1
- package/src/model/universal/modules.ts +8 -1
- package/src/native/frame_extract.swift +140 -0
- package/src/native-pack.ts +15 -7
- package/src/pi-provider.ts +6 -64
- package/src/pi-web.ts +14 -320
- package/src/prompt-cache.ts +97 -54
- package/src/quantize/allocator.ts +1 -1
- package/src/quantize/atomic-output.ts +38 -0
- package/src/quantize/calibration.ts +2 -1
- package/src/quantize/config-writer.ts +16 -3
- package/src/quantize/index.ts +28 -1
- package/src/quantize/job.ts +11 -0
- package/src/quantize/quantizer.ts +265 -100
- package/src/quantize/rotate.ts +603 -0
- package/src/quantize/safetensors-writer.ts +79 -1
- package/src/quantize/sensitivity.ts +41 -59
- package/src/quantize/trellis.ts +586 -0
- package/src/quantize/weight-transform.ts +292 -0
- package/src/responses.ts +130 -3
- package/src/runtime-config.ts +81 -0
- package/src/sampler.ts +276 -4
- package/src/serve/admin-routes.ts +184 -0
- package/src/serve/aux-routes.ts +132 -0
- package/src/serve/batch-scheduler.ts +8 -1558
- package/src/serve/chat-request.ts +391 -0
- package/src/serve/chat-stage.ts +195 -0
- package/src/serve/checkpoint-identity.ts +64 -0
- package/src/serve/completion-executor.ts +354 -0
- package/src/serve/completion-sink.ts +157 -0
- package/src/serve/discovery-routes.ts +204 -0
- package/src/serve/generation-gateway.ts +211 -243
- package/src/serve/http.ts +159 -0
- package/src/serve/inference-request.ts +79 -0
- package/src/serve/isolate.ts +297 -105
- package/src/serve/kv-budget.ts +14 -0
- package/src/serve/lab-routes.ts +341 -0
- package/src/serve/lane-registry.ts +2 -1
- package/src/serve/model-admin-routes.ts +155 -0
- package/src/serve/model-binding.ts +43 -0
- package/src/serve/model-host.ts +512 -0
- package/src/serve/openai-wire.ts +103 -0
- package/src/serve/parent-application.ts +56 -0
- package/src/serve/pipeline.ts +33 -0
- package/src/serve/preparation.ts +33 -0
- package/src/serve/prompt-response-trace.ts +147 -0
- package/src/serve/request-plan.ts +162 -0
- package/src/serve/request-prep.ts +346 -0
- package/src/serve/response-lease.ts +24 -0
- package/src/serve/responses-client.ts +69 -0
- package/src/serve/session-completion-engine.ts +110 -0
- package/src/serve/session-search.ts +1 -1
- package/src/serve/static-routes.ts +101 -0
- package/src/serve/text-completion-stage.ts +104 -0
- package/src/serve/token-streams.ts +519 -0
- package/src/server.ts +523 -3551
- package/src/spec/assistant-source.ts +10 -44
- package/src/spec/deepspec-source.ts +6 -6
- package/src/spec/dflash-source.ts +9 -8
- package/src/spec/dspark/ab-stats.ts +3 -3
- package/src/spec/dspark/calibration.ts +2 -2
- package/src/spec/dspark/deepspec-module.ts +2 -2
- package/src/spec/dspark/generate-dflash.ts +2 -2
- package/src/spec/dspark/generate.ts +2 -2
- package/src/spec/dspark/loader.ts +1 -1
- package/src/spec/dspark/module-dflash.ts +5 -4
- package/src/spec/dspark/module.ts +3 -3
- package/src/spec/dspark/quantize-drafter.ts +1 -1
- package/src/spec/generate.ts +1 -1
- package/src/spec/glm52-mtp-source.ts +9 -1
- package/src/spec/ngram-source.ts +1 -1
- package/src/spec/prefix-state.ts +45 -0
- package/src/spec/qwen-mtp-source.ts +528 -0
- package/src/spec/serve-loop.ts +179 -213
- package/src/spec/source.ts +42 -10
- package/src/spec/two-model.ts +1 -1
- package/src/ssd-cache.ts +95 -24
- package/src/ssd-durability.ts +207 -0
- package/src/tool-call.ts +51 -14
- package/src/train/flash-cce.ts +14 -13
- package/src/train/forward.ts +38 -1
- package/src/train/loss.ts +3 -2
- package/src/train/prefix-shared.ts +5 -1
- package/src/train/segmented.ts +9 -6
- package/src/train/trainer.ts +9 -8
- package/src/vision/preprocess.ts +1 -1
- package/src/vision/prompt.ts +48 -2
- package/src/vision/qwen3vl-preprocess.ts +409 -0
- package/src/vision/qwen3vl-prompt.ts +196 -0
- package/src/vision/qwen3vl-tower.ts +555 -0
- package/src/vision/video-frames.ts +148 -0
- package/src/web/app.html +1 -1
- package/src/web/app.js +15 -6
- package/src/web/src/adapters-panel.ts +3 -3
- package/src/web/src/assistant.ts +2 -36
- package/src/web/src/chat.ts +16 -9
- package/src/web/src/composer.ts +4 -4
- package/src/web/src/hub.ts +1 -1
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +1 -1
- package/src/web/src/model-picker.ts +1 -1
- package/src/web/src/palette.ts +1 -1
- package/src/web/src/protocol.ts +3 -39
- package/src/web/src/sessions.ts +1 -1
- package/src/web/src/ui-catalog.ts +4 -18
- package/src/web-assets.ts +47 -0
- package/src/weights.ts +134 -33
- package/docs/archive/mlx-bun-lab-report.html +0 -275
- package/docs/archive/wwdc-mlx-bun.html +0 -848
- package/docs/design/adapters-end-to-end.md +0 -205
- package/docs/design/batching-perf-path.md +0 -255
- package/docs/design/batching-v2-plan.md +0 -529
- package/docs/design/bucketing-stage.md +0 -197
- package/docs/design/compat-cli-surface-design.md +0 -230
- package/docs/design/docs-reorg-plan.md +0 -165
- package/docs/design/dspark-serving-program.md +0 -371
- package/docs/design/dspark-speculative-decoding.md +0 -268
- package/docs/design/grammar-spec-batching-integration.md +0 -301
- package/docs/design/memory-inference-path.md +0 -422
- package/docs/design/memory-synthesis.md +0 -287
- package/docs/design/memory-system.md +0 -237
- package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
- package/docs/design/omlx-adoption-map.md +0 -98
- package/docs/design/orpo-dynamic-lambda.md +0 -220
- package/docs/design/orpo-future-enhancements.md +0 -340
- package/docs/design/paged-kv-cache.md +0 -214
- package/docs/design/parallel-slots.md +0 -567
- package/docs/design/parity-tier-dag.md +0 -161
- package/docs/design/repo-cleanup-plan.md +0 -189
- package/docs/design/runtime-isolation.md +0 -263
- package/docs/design/segmented-backward-training.md +0 -543
- package/docs/design/spec-decode-larger-targets.md +0 -229
- package/docs/design/ssd-kv-cold-tier.md +0 -288
- package/docs/design/structured-output.md +0 -484
- package/docs/design/tauri-desktop-app.md +0 -127
- package/docs/design/the-dreaming-master-plan.md +0 -445
- package/docs/design/turboquant-kv.md +0 -235
- package/docs/design/w4a16-compute-precision-spike.md +0 -232
- package/docs/design/web-chat-beat-matrix.md +0 -315
- package/docs/design/write-pipeline-entity.md +0 -468
- package/docs/investigations/curve-runs/bisector-route.json +0 -98
- package/docs/investigations/curve-runs/bisector-trace.json +0 -1393
- package/docs/investigations/curve-runs/curve-terrain.json +0 -1179
- package/docs/investigations/curve-runs/curve-terrain.svg +0 -42
- package/docs/investigations/hlg-ab.html +0 -34
- package/docs/investigations/hlg-explorer.html +0 -238
- package/docs/investigations/hlg-figs/cliff.svg +0 -1
- package/docs/investigations/hlg-figs/cross.svg +0 -1
- package/docs/investigations/hlg-figs/edges.svg +0 -1
- package/docs/investigations/hlg-figs/k20-grids.svg +0 -1
- package/docs/investigations/hlg-figs/k20-peaks.svg +0 -1
- package/docs/investigations/hlg-figs/lw-curve.svg +0 -1
- package/docs/investigations/hlg-figs/terrain.svg +0 -1
- package/docs/investigations/hlg-report.html +0 -262
- package/docs/investigations/hlg-runs/hlg-ab.json +0 -149
- package/docs/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
- package/docs/investigations/hlg-runs/hlg-blind.json +0 -107
- package/docs/investigations/hlg-runs/hlg-cliff.json +0 -197
- package/docs/investigations/hlg-runs/hlg-cross.json +0 -505
- package/docs/investigations/hlg-runs/hlg-edge.json +0 -388
- package/docs/investigations/hlg-runs/hlg-eval1.json +0 -25
- package/docs/investigations/hlg-runs/hlg-frontier.json +0 -86
- package/docs/investigations/hlg-runs/hlg-grid.json +0 -242
- package/docs/investigations/hlg-runs/hlg-grid2.json +0 -343
- package/docs/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
- package/docs/investigations/hlg-runs/hlg-map.json +0 -383
- package/docs/investigations/hlg-runs/run0-original.log +0 -159
- package/docs/investigations/hlg-runs/runA-recommended.log +0 -131
- package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
- package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
- package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
- package/docs/investigations/hlg-runs/runAD-ab-samples.log +0 -8
- package/docs/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
- package/docs/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
- package/docs/investigations/hlg-runs/runAG-eval-config2.log +0 -16
- package/docs/investigations/hlg-runs/runB-gain-variants.log +0 -192
- package/docs/investigations/hlg-runs/runC-pivots.log +0 -162
- package/docs/investigations/hlg-runs/runD-oetf.log +0 -132
- package/docs/investigations/hlg-runs/runE-eotf.log +0 -162
- package/docs/investigations/hlg-runs/runF-shaper-working.log +0 -86
- package/docs/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
- package/docs/investigations/hlg-runs/runH-wsweep.log +0 -176
- package/docs/investigations/hlg-runs/runI-asweep.log +0 -176
- package/docs/investigations/hlg-runs/runJ-knobmap.log +0 -49
- package/docs/investigations/hlg-runs/runK-frontier.log +0 -19
- package/docs/investigations/hlg-runs/runL-widemap.log +0 -65
- package/docs/investigations/hlg-runs/runM-frontier-emb.log +0 -15
- package/docs/investigations/hlg-runs/runN-verify.log +0 -116
- package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
- package/docs/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
- package/docs/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
- package/docs/investigations/hlg-runs/runR-blind-transcript.log +0 -79
- package/docs/investigations/hlg-runs/runS-cross-coherence.log +0 -33
- package/docs/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
- package/docs/investigations/hlg-runs/runU-cross-12b.log +0 -33
- package/docs/investigations/hlg-runs/runV-lw-e4b.log +0 -22
- package/docs/investigations/hlg-runs/runW-lw-12b.log +0 -22
- package/docs/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
- package/docs/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
- package/docs/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
- package/docs/planning/IDEAS.md +0 -69
- package/docs/reference/embedding.md +0 -197
- package/docs/reference/features-matrix.md +0 -100
- package/docs/reference/orpo-quickstart.md +0 -135
- package/src/flags.ts +0 -13
- /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
- /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
- /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
- /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
- /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
- /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
- /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
- /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
- /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
- /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
- /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
- /package/docs/{planning → archive/planning}/journal.md +0 -0
- /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.13.md +0 -0
- /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
- /package/{docs/investigations → src/serve/assets}/curve-terrain.html +0 -0
- /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
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// like qwen3.ts, with every arch delta selected by the UniversalArgs
|
|
4
4
|
// descriptor (archs.ts). Monolith path only: no compiled
|
|
5
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
|
+
// vs mlx-lm on this machine's GPU (tests/parity/universal-parity.test.ts).
|
|
7
7
|
//
|
|
8
8
|
// Porting discipline: each branch transcribes its mlx-lm source op-for-op
|
|
9
9
|
// (q/k-norm before vs after reshape, rope order, scale points, softcap,
|
|
@@ -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`);
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// AVFoundation frame-extraction sidecar probe (PLAN 14w) — the video
|
|
2
|
+
// equivalent of the audio path's afconvert doctrine: macOS-native codecs,
|
|
3
|
+
// zero vendored dependencies.
|
|
4
|
+
//
|
|
5
|
+
// frame-extract <video> <outDir> [fps=2] [maxFrames=768]
|
|
6
|
+
// → writes frame-%04d.png (RGB) + prints "N <count> W <w> H <h>"
|
|
7
|
+
// frame-extract --make-fixture <out.mov>
|
|
8
|
+
// → writes the deterministic 6-frame 320x240 gradient test clip
|
|
9
|
+
//
|
|
10
|
+
// Sampling mirrors mlx-vlm's do_sample_frames: timestamps k/fps for
|
|
11
|
+
// k = 0..min(ceil(duration*fps), maxFrames)-1, precise tolerance.
|
|
12
|
+
|
|
13
|
+
import AVFoundation
|
|
14
|
+
import Foundation
|
|
15
|
+
import ImageIO
|
|
16
|
+
import UniformTypeIdentifiers
|
|
17
|
+
|
|
18
|
+
func die(_ msg: String) -> Never {
|
|
19
|
+
FileHandle.standardError.write((msg + "\n").data(using: .utf8)!)
|
|
20
|
+
exit(1)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func makeFixture(_ path: String) {
|
|
24
|
+
let url = URL(fileURLWithPath: path)
|
|
25
|
+
try? FileManager.default.removeItem(at: url)
|
|
26
|
+
guard let writer = try? AVAssetWriter(outputURL: url, fileType: .mov) else {
|
|
27
|
+
die("AVAssetWriter init failed")
|
|
28
|
+
}
|
|
29
|
+
let W = 320, H = 240, FRAMES = 6
|
|
30
|
+
let settings: [String: Any] = [
|
|
31
|
+
AVVideoCodecKey: AVVideoCodecType.h264,
|
|
32
|
+
AVVideoWidthKey: W,
|
|
33
|
+
AVVideoHeightKey: H,
|
|
34
|
+
]
|
|
35
|
+
let input = AVAssetWriterInput(mediaType: .video, outputSettings: settings)
|
|
36
|
+
let adaptor = AVAssetWriterInputPixelBufferAdaptor(
|
|
37
|
+
assetWriterInput: input,
|
|
38
|
+
sourcePixelBufferAttributes: [
|
|
39
|
+
kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32ARGB,
|
|
40
|
+
kCVPixelBufferWidthKey as String: W,
|
|
41
|
+
kCVPixelBufferHeightKey as String: H,
|
|
42
|
+
])
|
|
43
|
+
writer.add(input)
|
|
44
|
+
writer.startWriting()
|
|
45
|
+
writer.startSession(atSourceTime: .zero)
|
|
46
|
+
for f in 0..<FRAMES {
|
|
47
|
+
while !input.isReadyForMoreMediaData { Thread.sleep(forTimeInterval: 0.01) }
|
|
48
|
+
var pb: CVPixelBuffer?
|
|
49
|
+
CVPixelBufferCreate(nil, W, H, kCVPixelFormatType_32ARGB, nil, &pb)
|
|
50
|
+
guard let pixelBuffer = pb else { die("CVPixelBufferCreate failed") }
|
|
51
|
+
CVPixelBufferLockBaseAddress(pixelBuffer, [])
|
|
52
|
+
let base = CVPixelBufferGetBaseAddress(pixelBuffer)!
|
|
53
|
+
let bpr = CVPixelBufferGetBytesPerRow(pixelBuffer)
|
|
54
|
+
let p = base.assumingMemoryBound(to: UInt8.self)
|
|
55
|
+
for y in 0..<H {
|
|
56
|
+
for x in 0..<W {
|
|
57
|
+
let o = y * bpr + x * 4
|
|
58
|
+
p[o] = 255
|
|
59
|
+
p[o + 1] = UInt8((x * 255 / W + f * 20) % 256)
|
|
60
|
+
p[o + 2] = UInt8((y * 255 / H + f * 10) % 256)
|
|
61
|
+
p[o + 3] = UInt8(((x + y) * 255 / (W + H) + f * 30) % 256)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
CVPixelBufferUnlockBaseAddress(pixelBuffer, [])
|
|
65
|
+
adaptor.append(pixelBuffer, withPresentationTime: CMTime(value: CMTimeValue(f), timescale: 2))
|
|
66
|
+
}
|
|
67
|
+
input.markAsFinished()
|
|
68
|
+
let sem = DispatchSemaphore(value: 0)
|
|
69
|
+
writer.finishWriting { sem.signal() }
|
|
70
|
+
sem.wait()
|
|
71
|
+
guard writer.status == .completed else { die("finishWriting status \(writer.status.rawValue)") }
|
|
72
|
+
print("fixture \(path)")
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let args = CommandLine.arguments
|
|
76
|
+
if args.count >= 3 && args[1] == "--make-fixture" {
|
|
77
|
+
makeFixture(args[2])
|
|
78
|
+
exit(0)
|
|
79
|
+
}
|
|
80
|
+
guard args.count >= 3 else { die("usage: frame-extract <video> <outDir> [fps] [maxFrames]") }
|
|
81
|
+
let videoPath = args[1]
|
|
82
|
+
let outDir = args[2]
|
|
83
|
+
let fps = args.count > 3 ? Double(args[3]) ?? 2.0 : 2.0
|
|
84
|
+
let maxFrames = args.count > 4 ? Int(args[4]) ?? 768 : 768
|
|
85
|
+
|
|
86
|
+
let asset = AVURLAsset(url: URL(fileURLWithPath: videoPath))
|
|
87
|
+
let sem = DispatchSemaphore(value: 0)
|
|
88
|
+
var duration = CMTime.zero
|
|
89
|
+
var loadError: Error?
|
|
90
|
+
Task {
|
|
91
|
+
do { duration = try await asset.load(.duration) } catch { loadError = error }
|
|
92
|
+
sem.signal()
|
|
93
|
+
}
|
|
94
|
+
sem.wait()
|
|
95
|
+
if let e = loadError { die("asset load failed: \(e.localizedDescription)") }
|
|
96
|
+
// Fragmented/malformed containers can load with an indefinite duration —
|
|
97
|
+
// CMTimeGetSeconds yields NaN and Int(NaN) is a Swift runtime TRAP. Fall
|
|
98
|
+
// back to the frame cap; the extraction loop below already stops at the
|
|
99
|
+
// first undecodable timestamp.
|
|
100
|
+
let seconds = CMTimeGetSeconds(duration)
|
|
101
|
+
let count = seconds.isFinite
|
|
102
|
+
? max(1, min(Int((seconds * fps).rounded(.up)), maxFrames))
|
|
103
|
+
: maxFrames
|
|
104
|
+
|
|
105
|
+
let gen = AVAssetImageGenerator(asset: asset)
|
|
106
|
+
gen.appliesPreferredTrackTransform = true
|
|
107
|
+
gen.requestedTimeToleranceBefore = .zero
|
|
108
|
+
gen.requestedTimeToleranceAfter = .zero
|
|
109
|
+
// Bound DECODED memory at the source: the language pipeline's video pixel
|
|
110
|
+
// budget always downscales frames far below 1024px anyway (max_pixels
|
|
111
|
+
// 32·32·768 across t·h·w), so capping the longest edge here loses nothing
|
|
112
|
+
// it would have kept while keeping a 4K clip from materializing ~24 MB per
|
|
113
|
+
// frame (768 frames ≈ 17.8 GiB) before preprocessing.
|
|
114
|
+
gen.maximumSize = CGSize(width: 1024, height: 1024)
|
|
115
|
+
|
|
116
|
+
try? FileManager.default.createDirectory(
|
|
117
|
+
atPath: outDir, withIntermediateDirectories: true)
|
|
118
|
+
var written = 0
|
|
119
|
+
var lastW = 0, lastH = 0
|
|
120
|
+
for k in 0..<count {
|
|
121
|
+
let t = CMTime(seconds: Double(k) / fps, preferredTimescale: 600)
|
|
122
|
+
let img: CGImage
|
|
123
|
+
do {
|
|
124
|
+
img = try gen.copyCGImage(at: t, actualTime: nil)
|
|
125
|
+
} catch {
|
|
126
|
+
// Past-end sampling on short clips: stop at the last decodable frame.
|
|
127
|
+
break
|
|
128
|
+
}
|
|
129
|
+
lastW = img.width
|
|
130
|
+
lastH = img.height
|
|
131
|
+
let out = URL(fileURLWithPath: String(format: "%@/frame-%04d.png", outDir, k))
|
|
132
|
+
guard let dest = CGImageDestinationCreateWithURL(
|
|
133
|
+
out as CFURL, UTType.png.identifier as CFString, 1, nil)
|
|
134
|
+
else { die("png destination failed") }
|
|
135
|
+
CGImageDestinationAddImage(dest, img, nil)
|
|
136
|
+
guard CGImageDestinationFinalize(dest) else { die("png write failed") }
|
|
137
|
+
written += 1
|
|
138
|
+
}
|
|
139
|
+
guard written > 0 else { die("no frames decodable from \(videoPath)") }
|
|
140
|
+
print("N \(written) W \(lastW) H \(lastH)")
|
package/src/native-pack.ts
CHANGED
|
@@ -8,25 +8,32 @@
|
|
|
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/
|
|
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";
|
|
15
15
|
import { homedir, tmpdir } from "node:os";
|
|
16
16
|
import { dirname, join } from "node:path";
|
|
17
17
|
import { downloadOne } from "./download";
|
|
18
|
+
import { runtimeValue } from "./runtime-config";
|
|
18
19
|
|
|
19
|
-
export const NATIVE_PACK_VERSION = "0.
|
|
20
|
+
export const NATIVE_PACK_VERSION = "0.4.0";
|
|
21
|
+
export const MLX_CORE_VERSION = "0.32.2";
|
|
20
22
|
export const NATIVE_PACK_FILES = [
|
|
21
23
|
"libmlxc.dylib", "libmlx.dylib", "libjaccl.dylib", "mlx.metallib",
|
|
22
|
-
"libmlx_bun_expert_io.dylib",
|
|
24
|
+
"libmlx_bun_expert_io.dylib", "mlx-bun-frame-extract",
|
|
23
25
|
] as const;
|
|
24
26
|
|
|
27
|
+
// RELEASE-TIME BAKE: scripts/build-native-pack.sh prints the sha256/size for
|
|
28
|
+
// the freshly built tarball — publish `native-v0.4.0` with both assets and
|
|
29
|
+
// paste the values here BEFORE tagging the package release (the download
|
|
30
|
+
// 404s until the GitHub release exists; dev trees resolve via homebrew/env
|
|
31
|
+
// and never hit this path).
|
|
25
32
|
const SHA256: Record<string, string> = {
|
|
26
|
-
arm64: "
|
|
33
|
+
arm64: "f2b0857658aa0826aee14b94a6b83d4c86c08f2c07d716991de6afd038f5ca5d",
|
|
27
34
|
};
|
|
28
35
|
const SIZE: Record<string, number> = {
|
|
29
|
-
arm64:
|
|
36
|
+
arm64: 41931583,
|
|
30
37
|
};
|
|
31
38
|
|
|
32
39
|
export function nativePackName(arch = process.arch): string {
|
|
@@ -37,7 +44,7 @@ export function nativePackName(arch = process.arch): string {
|
|
|
37
44
|
* the repo is private the download needs a token (GITHUB_TOKEN or
|
|
38
45
|
* `gh auth token`); once public it works anonymously. */
|
|
39
46
|
export function nativePackUrl(arch = process.arch): string {
|
|
40
|
-
return
|
|
47
|
+
return runtimeValue("MLX_BUN_NATIVE_PACK_URL") ??
|
|
41
48
|
`https://github.com/joshuarossi/mlx-bun/releases/download/native-v${NATIVE_PACK_VERSION}/${nativePackName(arch)}`;
|
|
42
49
|
}
|
|
43
50
|
|
|
@@ -48,7 +55,8 @@ export function nativePackDir(arch = process.arch): string {
|
|
|
48
55
|
/** Where the native runtime currently resolves from, or null if absent
|
|
49
56
|
* everywhere (= a fresh machine that needs the pack). */
|
|
50
57
|
export function nativeRuntimeDir(): string | null {
|
|
51
|
-
|
|
58
|
+
const explicit = runtimeValue("MLX_BUN_LIBMLXC");
|
|
59
|
+
if (explicit) return dirname(explicit);
|
|
52
60
|
const candidates = [
|
|
53
61
|
dirname(process.execPath),
|
|
54
62
|
nativePackDir(),
|
package/src/pi-provider.ts
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
export
|
|
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);
|