mlx-bun 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -588
- package/docs/README.md +94 -0
- package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
- package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
- package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
- package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
- package/docs/archive/investigations/openjarvis-fit.md +198 -0
- package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
- package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
- package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
- package/docs/archive/planning/release-notes-v0.3.0.md +35 -0
- package/docs/design/batching.md +1841 -0
- package/docs/design/decode-speed-program.md +2346 -169
- package/docs/design/dreaming-nightly-pipeline.md +675 -282
- package/docs/design/generic-model-support.md +655 -334
- package/docs/design/kv-cache.md +824 -0
- package/docs/design/orpo-training.md +673 -1239
- package/docs/design/speculative-decoding.md +1990 -0
- package/docs/design/turboquant.md +2212 -0
- package/docs/design/unified-engine-frontier-plan.md +1833 -727
- package/docs/design/web-chat-redesign.md +666 -1083
- package/docs/planning/PRODUCT_ROADMAP.md +50 -1
- package/docs/planning/release-notes-v0.4.0.md +45 -0
- package/docs/planning/video-series.md +2 -2
- package/docs/reference/benchmarks.md +3613 -0
- package/docs/reference/cli.md +434 -160
- package/docs/reference/distribution.md +328 -182
- package/docs/reference/environment.md +398 -0
- package/docs/reference/glossary.md +39 -0
- package/docs/reference/library-api.md +566 -168
- package/docs/reference/memory.md +227 -64
- package/docs/reference/models.md +113 -6
- package/docs/reference/server-api.md +944 -429
- package/docs/reference/server-config.md +740 -338
- package/docs/reference/training.md +393 -254
- package/docs/reference/troubleshooting.md +158 -0
- package/package.json +9 -4
- package/src/audio/decode.ts +2 -2
- package/src/audio/features.ts +2 -2
- package/src/backends/mlx/assistant-target.ts +46 -0
- package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
- package/src/backends/mlx/autoregressive.ts +108 -0
- package/src/backends/mlx/batch-group.ts +1790 -0
- package/src/backends/mlx/cache-attachment.ts +67 -0
- package/src/backends/mlx/cache-layout.ts +31 -0
- package/src/backends/mlx/checkpoint-state.ts +53 -0
- package/src/backends/mlx/continuation-persistence.ts +106 -0
- package/src/backends/mlx/continuation-request.ts +43 -0
- package/src/backends/mlx/continuation.ts +77 -0
- package/src/backends/mlx/diffusion.ts +39 -0
- package/src/backends/mlx/draft-target.ts +32 -0
- package/src/backends/mlx/evaluation.ts +105 -0
- package/src/backends/mlx/fill-append.ts +45 -0
- package/src/backends/mlx/full-kv-row-append.ts +32 -0
- package/src/backends/mlx/full-kv-row-donor.ts +54 -0
- package/src/backends/mlx/full-transitioning-kv-rows.ts +65 -0
- package/src/backends/mlx/gateway-binding.ts +130 -0
- package/src/backends/mlx/graph.ts +38 -0
- package/src/backends/mlx/kv-codec.ts +9 -0
- package/src/backends/mlx/kv-maintenance.ts +133 -0
- package/src/backends/mlx/kv-tensor-rows.ts +212 -0
- package/src/backends/mlx/memory-client.ts +189 -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-cohort.ts +89 -0
- package/src/backends/mlx/prefill-rows.ts +200 -0
- package/src/backends/mlx/prefill.ts +33 -0
- package/src/backends/mlx/projected-context-rows.ts +72 -0
- package/src/backends/mlx/request-policy.ts +20 -0
- package/src/backends/mlx/request-state-policy.ts +41 -0
- package/src/backends/mlx/rollback.ts +89 -0
- package/src/backends/mlx/row-sampling.ts +49 -0
- package/src/backends/mlx/serial-executor.ts +242 -0
- package/src/backends/mlx/speculative-group.ts +359 -0
- package/src/backends/mlx/speculative-round.ts +161 -0
- package/src/backends/mlx/speculative.ts +114 -0
- package/src/backends/mlx/state-rows.ts +104 -0
- package/src/backends/mlx/state-views.ts +46 -0
- package/src/backends/mlx/target-layout-capability.ts +35 -0
- package/src/backends/mlx/text-engine.ts +73 -0
- package/src/backends/mlx/transitioning-kv-rows.ts +165 -0
- package/src/cli.ts +66 -58
- package/src/client.ts +66 -0
- package/src/config.ts +21 -4
- package/src/contracts/completion.ts +16 -0
- package/src/contracts/execution.ts +60 -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/prefix-cache.ts +23 -0
- package/src/contracts/resources.ts +25 -0
- package/src/contracts/sampling.ts +23 -0
- package/src/contracts/scheduling.ts +45 -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 +53 -0
- package/src/engine/resources.ts +53 -0
- package/src/engine/scheduler.ts +72 -0
- package/src/engine/session.ts +247 -0
- package/src/eval/README.md +44 -1
- package/src/eval/kl.ts +236 -3
- package/src/eval/reference-logits.ts +207 -0
- package/src/eval/runner.ts +8 -96
- 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 +30 -16
- package/src/generate.ts +709 -417
- package/src/grammar.ts +12 -7
- package/src/harness-pi.ts +14 -33
- package/src/hub-rest.ts +4 -4
- package/src/index.ts +7 -0
- package/src/inference/denoising.ts +17 -0
- package/src/inference/draft-acceptance.ts +41 -0
- package/src/inference/draft-output.ts +49 -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 +12 -12
- 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 +70 -12
- package/src/kv-store.ts +177 -63
- 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} +5 -5
- package/src/lab/paged-kv/paged-kv-rows.ts +83 -0
- package/src/{model → lab/paged-kv}/paged-kv.ts +32 -15
- package/src/library.ts +40 -0
- package/src/lora.ts +18 -0
- package/src/media-fetch.ts +1 -1
- package/src/memory/article.ts +1 -1
- package/src/memory/chunk.ts +1 -1
- package/src/memory/model.ts +30 -169
- 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 +1 -3
- package/src/mlx/array.ts +11 -11
- package/src/mlx/compile.ts +12 -2
- package/src/mlx/ffi.ts +58 -11
- package/src/mlx/materialize.ts +23 -0
- package/src/mlx/metal-kernel.ts +10 -11
- package/src/mlx/ops.ts +33 -13
- 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/artifact-identity.ts +73 -0
- package/src/model/batched-kv.ts +235 -0
- package/src/model/batched-mask.ts +20 -6
- package/src/model/batched-quant.ts +9 -3
- package/src/model/batched-quantized-kv.ts +144 -0
- package/src/model/batched-rotating-quant.ts +78 -17
- package/src/model/batched-rotating-state.ts +76 -0
- package/src/model/batched-rotating.ts +65 -23
- package/src/model/batched-row-storage.ts +52 -0
- package/src/model/batched-ssm.ts +52 -0
- package/src/model/batched-turboquant-kv.ts +93 -0
- package/src/model/compiled-decode.ts +8 -2
- package/src/model/decoded-kv-donor.ts +12 -0
- package/src/model/delayed-quantized-kv.ts +72 -0
- package/src/model/delayed-rotating-quantized-kv.ts +93 -0
- package/src/model/delayed-turboquant-kv.ts +55 -0
- package/src/model/diffusion-gemma.ts +8 -8
- package/src/model/factory.ts +76 -33
- package/src/model/fingerprint.ts +1 -1
- package/src/model/flash-attention.ts +3 -3
- package/src/model/full-prefill-padding.ts +56 -0
- package/src/model/full-prefill-row.ts +105 -0
- package/src/model/gemma4-base.ts +179 -80
- package/src/model/gemma4.ts +40 -32
- package/src/model/generated/gemma4-12b.ts +6 -3
- package/src/model/generated/gemma4-26b.ts +6 -3
- package/src/model/generated/gemma4-e4b.ts +6 -3
- package/src/model/glm52-cache.ts +80 -4
- package/src/model/glm52-dsa.ts +13 -9
- package/src/model/glm52-memory.ts +1 -1
- package/src/model/glm52-mla.ts +12 -6
- package/src/model/glm52.ts +19 -40
- package/src/model/implementation.ts +69 -0
- package/src/model/kv-attention-view.ts +67 -0
- package/src/model/minicpm5.ts +17 -15
- package/src/model/profile.ts +12 -2
- package/src/model/qwen-append.ts +12 -0
- package/src/model/qwen-conv.ts +52 -0
- package/src/model/qwen3-delta-state.ts +74 -0
- package/src/model/qwen3-delta.ts +59 -36
- package/src/model/qwen3_5-checkpoint.ts +164 -0
- package/src/model/qwen3_5.ts +202 -78
- package/src/model/rotating-kv-donor.ts +35 -0
- package/src/model/rotating-kv-layout.ts +262 -0
- package/src/model/rotating-row-transaction.ts +35 -0
- package/src/model/speculative-rotating-kv.ts +101 -0
- package/src/model/ssm-prefill-padding.ts +39 -0
- 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/turboquant-codec.ts +83 -0
- package/src/model/universal/dense.ts +15 -14
- package/src/model/universal/modules.ts +8 -1
- package/src/native-pack.ts +6 -5
- package/src/pi-provider.ts +6 -64
- package/src/pi-web.ts +8 -315
- package/src/preflight.ts +31 -15
- package/src/prompt-cache.ts +110 -69
- package/src/quantize/allocator.ts +1 -1
- package/src/quantize/config-writer.ts +10 -3
- package/src/quantize/rotate.ts +4 -4
- package/src/quantize/trellis.ts +586 -0
- package/src/responses.ts +28 -1
- package/src/runtime-config.ts +18 -4
- package/src/sampler.ts +40 -29
- package/src/serve/batch-scheduler.ts +8 -1671
- 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 +15 -7
- package/src/serve/discovery-routes.ts +12 -13
- package/src/serve/generation-gateway.ts +183 -213
- 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/lab-routes.ts +3 -0
- package/src/serve/lane-registry.ts +2 -1
- package/src/serve/model-admin-routes.ts +7 -5
- package/src/serve/model-binding.ts +43 -0
- package/src/serve/model-host.ts +511 -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/request-plan.ts +23 -18
- package/src/serve/request-prep.ts +344 -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 +5 -5
- package/src/serve/text-completion-stage.ts +104 -0
- package/src/serve/token-streams.ts +519 -0
- package/src/server.ts +335 -2711
- package/src/spec/assistant-rows.ts +92 -0
- package/src/spec/assistant-source.ts +31 -55
- package/src/spec/cache-identity.ts +22 -0
- package/src/spec/deepspec-rows.ts +29 -0
- package/src/spec/deepspec-source.ts +16 -14
- package/src/spec/dflash-source.ts +36 -12
- package/src/spec/drafter.ts +153 -142
- package/src/spec/dspark/ab-stats.ts +3 -3
- package/src/spec/dspark/calibration.ts +2 -2
- package/src/spec/dspark/deepspec-module.ts +97 -122
- 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 +129 -172
- 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-graph.ts +29 -0
- package/src/spec/glm52-mtp-rows.ts +132 -0
- package/src/spec/glm52-mtp-source.ts +54 -137
- package/src/spec/glm52-mtp-state.ts +33 -0
- package/src/spec/ngram-source.ts +93 -21
- package/src/spec/projected-draft-rows.ts +73 -0
- package/src/spec/qwen-mtp-module.ts +171 -0
- package/src/spec/qwen-mtp-rows.ts +219 -0
- package/src/spec/qwen-mtp-source.ts +147 -195
- package/src/spec/qwen-mtp-state.ts +30 -0
- package/src/spec/serve-loop.ts +201 -201
- package/src/spec/source.ts +110 -13
- package/src/spec/two-model-rows.ts +61 -0
- package/src/spec/two-model.ts +44 -102
- package/src/ssd-cache.ts +99 -19
- package/src/ssd-durability.ts +36 -20
- package/src/tool-call.ts +51 -14
- package/src/train/flash-cce.ts +2 -2
- package/src/train/forward.ts +6 -0
- package/src/train/loss.ts +1 -1
- package/src/train/prefix-shared.ts +5 -1
- package/src/train/segmented.ts +5 -3
- package/src/train/trainer.ts +6 -6
- package/src/vision/prompt.ts +1 -1
- package/src/vision/qwen3vl-tower.ts +52 -10
- package/src/web/app.html +1 -1
- package/src/web/app.js +62 -60
- package/src/web/src/adapters-panel.ts +3 -3
- package/src/web/src/assistant.ts +2 -36
- package/src/web/src/chat.ts +4 -4
- 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 +55 -9
- package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
- package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
- package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
- package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
- package/docs/archive/investigations/hlg-ab.html +0 -34
- package/docs/archive/investigations/hlg-explorer.html +0 -238
- package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
- package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
- package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
- package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
- package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
- package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
- package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
- package/docs/archive/investigations/hlg-report.html +0 -262
- package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
- package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
- package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
- package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
- package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
- package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
- package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
- package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
- package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
- package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
- package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
- package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
- package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
- package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
- package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
- package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
- package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
- package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
- package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
- package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
- package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
- package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
- package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
- package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
- package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
- package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
- package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
- package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
- package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
- package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
- package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
- package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
- package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
- package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
- package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
- package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
- package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
- package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
- package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
- package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
- package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
- package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
- package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
- package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
- package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
- package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
- 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 -318
- 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-serving-execution-seam.md +0 -81
- 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 -231
- 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 -415
- 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/turboquant-weights.md +0 -467
- 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/planning/IDEAS.md +0 -69
- package/docs/reference/embedding.md +0 -197
- package/docs/reference/features-matrix.md +0 -101
- package/docs/reference/orpo-quickstart.md +0 -135
- package/src/flags.ts +0 -11
- /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
- /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
- /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
- /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
- /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
- /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
- /package/{docs/archive/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
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { MlxArray } from "../mlx/array";
|
|
2
|
+
import * as tq from "../mlx/turboquant-ops";
|
|
3
|
+
import type { KvCodec } from "../backends/mlx/kv-codec";
|
|
4
|
+
|
|
5
|
+
/** One TurboQuant-encoded (K, V) storage tuple — the 5 arrays kv-store.ts
|
|
6
|
+
* and toQuantized/fromKVCache pass around. Not `ops.QuantizedTensor`
|
|
7
|
+
* (mlx's affine int4/int8 scheme): this is the rotation + Lloyd-Max
|
|
8
|
+
* layout (docs/design/turboquant.md), asymmetric-affine for keys,
|
|
9
|
+
* FWHT+Lloyd-Max for values. Field order is the kv-store.ts tensor-slot
|
|
10
|
+
* contract — do not reorder without updating snapshotCache/loadKvCache. */
|
|
11
|
+
export interface TurboQuantTensor {
|
|
12
|
+
kIdx: MlxArray;
|
|
13
|
+
kScales: MlxArray;
|
|
14
|
+
kZeros: MlxArray;
|
|
15
|
+
vPacked: MlxArray;
|
|
16
|
+
vScales: MlxArray;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const disposeTurboQuant = (t: TurboQuantTensor): void => {
|
|
20
|
+
t.kIdx.dispose();
|
|
21
|
+
t.kScales.dispose();
|
|
22
|
+
t.kZeros.dispose();
|
|
23
|
+
t.vPacked.dispose();
|
|
24
|
+
t.vScales.dispose();
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** Numerical representation only. Storage owns capacity, positions, row
|
|
28
|
+
* membership and persistence; this codec retains the existing kernel choices. */
|
|
29
|
+
export class TurboQuantCodec implements KvCodec<TurboQuantTensor> {
|
|
30
|
+
constructor(readonly kBits: number, readonly vBits: number, readonly fusedDecode: boolean) {}
|
|
31
|
+
|
|
32
|
+
/** Encode k/v [B,H,L,D] into a fresh TurboQuantTensor (packed at rest). */
|
|
33
|
+
encode(k: MlxArray, v: MlxArray): TurboQuantTensor {
|
|
34
|
+
const signed = this.kBits === 8;
|
|
35
|
+
const kEnc = tq.encodeKeys(k, this.kBits, signed);
|
|
36
|
+
const kIdxPacked = this.kBits < 8 ? tq.packBits(kEnc.indices, this.kBits) : kEnc.indices;
|
|
37
|
+
if (kIdxPacked !== kEnc.indices) kEnc.indices.dispose();
|
|
38
|
+
const vEnc = tq.encodeValues(v, this.vBits);
|
|
39
|
+
const vIdxPacked = this.vBits < 8 ? tq.packBits(vEnc.indices, this.vBits) : vEnc.indices;
|
|
40
|
+
if (vIdxPacked !== vEnc.indices) vEnc.indices.dispose();
|
|
41
|
+
return {
|
|
42
|
+
kIdx: kIdxPacked, kScales: kEnc.scales, kZeros: kEnc.zeros,
|
|
43
|
+
vPacked: vIdxPacked, vScales: vEnc.scales,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Decode a TurboQuantTensor's active [B,H,upTo,*] window back to
|
|
48
|
+
* bf16 [B,H,upTo,headDim] (k, v). Caller owns the returned arrays.
|
|
49
|
+
* deferV leaves V in the rotated domain (decodeValuesRotated) — the
|
|
50
|
+
* caller un-rotates its attention output instead (tq.unrotateValues). */
|
|
51
|
+
decode(t: TurboQuantTensor, upTo: number, headDim: number, deferV = false): [MlxArray, MlxArray] {
|
|
52
|
+
const cut = (a: MlxArray): MlxArray => {
|
|
53
|
+
const [B, H, , D] = a.shape as [number, number, number, number];
|
|
54
|
+
return a.slice([0, 0, 0, 0], [B, H, upTo, D]);
|
|
55
|
+
};
|
|
56
|
+
if (this.fusedDecode) {
|
|
57
|
+
const inputs = [cut(t.kIdx), cut(t.kScales), cut(t.kZeros), cut(t.vPacked), cut(t.vScales)] as const;
|
|
58
|
+
try {
|
|
59
|
+
const decoded = tq.tryDecodePackedKv(inputs, this.kBits, this.vBits, headDim, deferV);
|
|
60
|
+
if (decoded) return decoded;
|
|
61
|
+
} finally { for (const input of inputs) input.dispose(); }
|
|
62
|
+
}
|
|
63
|
+
const kIdxCut = cut(t.kIdx);
|
|
64
|
+
const kIdxUnpacked = this.kBits < 8 ? tq.unpackBits(kIdxCut, this.kBits, headDim) : kIdxCut;
|
|
65
|
+
if (kIdxUnpacked !== kIdxCut) kIdxCut.dispose();
|
|
66
|
+
const kScalesCut = cut(t.kScales);
|
|
67
|
+
const kZerosCut = cut(t.kZeros);
|
|
68
|
+
const k = tq.decodeKeys(kIdxUnpacked, kScalesCut, kZerosCut);
|
|
69
|
+
for (const a of [kIdxUnpacked, kScalesCut, kZerosCut]) a.dispose();
|
|
70
|
+
|
|
71
|
+
const vPackedCut = cut(t.vPacked);
|
|
72
|
+
const vIdxUnpacked = this.vBits < 8 ? tq.unpackBits(vPackedCut, this.vBits, headDim) : vPackedCut;
|
|
73
|
+
if (vIdxUnpacked !== vPackedCut) vPackedCut.dispose();
|
|
74
|
+
const vScalesCut = cut(t.vScales);
|
|
75
|
+
const v = deferV
|
|
76
|
+
? tq.decodeValuesRotated(vIdxUnpacked, vScalesCut, this.vBits)
|
|
77
|
+
: tq.decodeValues(vIdxUnpacked, vScalesCut, this.vBits);
|
|
78
|
+
for (const a of [vIdxUnpacked, vScalesCut]) a.dispose();
|
|
79
|
+
|
|
80
|
+
return [k, v];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { captureKvAttention } from "../kv-attention-view";
|
|
1
2
|
// UniversalDense — the Tier-0 config-driven dense llama-family module
|
|
2
3
|
// (docs/design/generic-model-support.md §3.1). One module, shaped exactly
|
|
3
4
|
// like qwen3.ts, with every arch delta selected by the UniversalArgs
|
|
4
5
|
// descriptor (archs.ts). Monolith path only: no compiled
|
|
5
|
-
// decode
|
|
6
|
-
//
|
|
6
|
+
// decode. Standard attention uses the shared plain/affine KV port; the
|
|
7
|
+
// softcap branch retains plain KV. The bar is L1 bit-exactness
|
|
8
|
+
// vs mlx-lm on this machine's GPU (tests/parity/universal-parity.test.ts).
|
|
7
9
|
//
|
|
8
10
|
// Porting discipline: each branch transcribes its mlx-lm source op-for-op
|
|
9
11
|
// (q/k-norm before vs after reshape, rope order, scale points, softcap,
|
|
@@ -154,19 +156,18 @@ class UniversalAttention {
|
|
|
154
156
|
? this.rope.applyDynamic(k, offArr)
|
|
155
157
|
: this.rope.apply(k, cache.offset));
|
|
156
158
|
|
|
157
|
-
const [keys, values] = cache.updateAndFetch(k, v);
|
|
158
|
-
k.dispose();
|
|
159
|
-
v.dispose();
|
|
160
|
-
|
|
161
159
|
let attn: MlxArray;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
160
|
+
try {
|
|
161
|
+
if (a.attnLogitSoftcap !== null) {
|
|
162
|
+
const [keys, values] = cache.updateAndFetch(k, v);
|
|
163
|
+
try { attn = this.#softcapAttention(q, keys, values, mask, B, L); }
|
|
164
|
+
finally { keys.dispose(); values.dispose(); }
|
|
165
|
+
} else {
|
|
166
|
+
const view = captureKvAttention(cache, k, v);
|
|
167
|
+
try { attn = view.attend(q, a.attnScale, mask); }
|
|
168
|
+
finally { view.dispose(); }
|
|
169
|
+
}
|
|
170
|
+
} finally { k.dispose(); v.dispose(); q.dispose(); }
|
|
170
171
|
|
|
171
172
|
const attnT = ops.transposeAxes(attn, [0, 2, 1, 3]);
|
|
172
173
|
attn.dispose();
|
|
@@ -11,6 +11,7 @@ import type { Weights } from "../../weights";
|
|
|
11
11
|
import { MlxArray } from "../../mlx/array";
|
|
12
12
|
import * as ops from "../../mlx/ops";
|
|
13
13
|
import { QuantizedEmbedding, QuantizedLinear, RMSNorm } from "../gemma4-base";
|
|
14
|
+
import { TrellisLinear } from "../trellis-linear";
|
|
14
15
|
|
|
15
16
|
/** Records every tensor a universal load consumes; `finish` diffs against
|
|
16
17
|
* the shard index so a descriptor mistake is a LOAD error (unconsumed /
|
|
@@ -66,7 +67,7 @@ export class DenseLinear {
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
/** Either linear flavor behind one call surface. */
|
|
69
|
-
export type AnyLinear = QuantizedLinear | DenseLinear;
|
|
70
|
+
export type AnyLinear = QuantizedLinear | DenseLinear | TrellisLinear;
|
|
70
71
|
|
|
71
72
|
/** Quantized when `.scales` exists (MLX-quantized checkpoints), else dense
|
|
72
73
|
* bf16/f16/f32 (Phase 1.5). Both flavors carry the optional ADDITIVE
|
|
@@ -74,6 +75,12 @@ export type AnyLinear = QuantizedLinear | DenseLinear;
|
|
|
74
75
|
export function loadLinear(
|
|
75
76
|
weights: Weights, path: string, config: ModelConfig, audit: WeightAudit,
|
|
76
77
|
): AnyLinear {
|
|
78
|
+
if (TrellisLinear.isTrellis(config, path)) {
|
|
79
|
+
const lin = TrellisLinear.load(weights, path, config);
|
|
80
|
+
audit.use(`${path}.weight`);
|
|
81
|
+
audit.use(`${path}.scales`);
|
|
82
|
+
return lin;
|
|
83
|
+
}
|
|
77
84
|
if (weights.has(`${path}.scales`)) {
|
|
78
85
|
const lin = QuantizedLinear.load(weights, path, config);
|
|
79
86
|
audit.use(`${path}.weight`);
|
package/src/native-pack.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
//
|
|
9
9
|
// Resolution order for the libs (mirrored in src/mlx/ffi.ts):
|
|
10
10
|
// MLX_BUN_LIBMLXC env > beside the executable (sidecar dist/ layout,
|
|
11
|
-
// docs/reference/
|
|
11
|
+
// docs/reference/distribution.md) > the native-pack cache dir > homebrew.
|
|
12
12
|
// Dev trees and embedders therefore never download anything.
|
|
13
13
|
|
|
14
14
|
import { existsSync, mkdirSync, renameSync, rmSync } from "node:fs";
|
|
@@ -17,22 +17,23 @@ import { dirname, join } from "node:path";
|
|
|
17
17
|
import { downloadOne } from "./download";
|
|
18
18
|
import { runtimeValue } from "./runtime-config";
|
|
19
19
|
|
|
20
|
-
export const NATIVE_PACK_VERSION = "0.
|
|
20
|
+
export const NATIVE_PACK_VERSION = "0.4.0";
|
|
21
|
+
export const MLX_CORE_VERSION = "0.32.2";
|
|
21
22
|
export const NATIVE_PACK_FILES = [
|
|
22
23
|
"libmlxc.dylib", "libmlx.dylib", "libjaccl.dylib", "mlx.metallib",
|
|
23
24
|
"libmlx_bun_expert_io.dylib", "mlx-bun-frame-extract",
|
|
24
25
|
] as const;
|
|
25
26
|
|
|
26
27
|
// RELEASE-TIME BAKE: scripts/build-native-pack.sh prints the sha256/size for
|
|
27
|
-
// the freshly built tarball — publish `native-v0.
|
|
28
|
+
// the freshly built tarball — publish `native-v0.4.0` with both assets and
|
|
28
29
|
// paste the values here BEFORE tagging the package release (the download
|
|
29
30
|
// 404s until the GitHub release exists; dev trees resolve via homebrew/env
|
|
30
31
|
// and never hit this path).
|
|
31
32
|
const SHA256: Record<string, string> = {
|
|
32
|
-
arm64: "
|
|
33
|
+
arm64: "f2b0857658aa0826aee14b94a6b83d4c86c08f2c07d716991de6afd038f5ca5d",
|
|
33
34
|
};
|
|
34
35
|
const SIZE: Record<string, number> = {
|
|
35
|
-
arm64:
|
|
36
|
+
arm64: 41931583,
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
export function nativePackName(arch = process.arch): string {
|
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);
|