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.
- package/README.md +1449 -109
- package/THIRD_PARTY_NOTICES.md +882 -0
- package/bin/mlx-bun.convert.mjs +4 -0
- package/bin/mlx-bun.fuse.mjs +4 -0
- package/bin/mlx-bun.generate.mjs +4 -0
- package/bin/mlx-bun.lora.mjs +4 -0
- package/bin/mlx-bun.mjs +13 -21
- package/bin/mlx-bun.server.mjs +4 -0
- package/bin/mlx-bun.upload.mjs +4 -0
- package/dist/web/app.js +9584 -0
- package/package.json +50 -53
- package/src/cli/ane-install.ts +76 -0
- package/src/cli/args.ts +179 -0
- package/src/cli/engine-entry.ts +68 -0
- package/src/cli/inference.ts +214 -0
- package/src/cli/job-entry.ts +97 -0
- package/src/cli/library-host.ts +117 -0
- package/src/cli/main.ts +57 -0
- package/src/cli/memory-engine.ts +163 -0
- package/src/cli/memory.ts +36 -0
- package/src/cli/mlx-lm-aliases.ts +309 -0
- package/src/cli/model-choice.ts +33 -0
- package/src/cli/model-selection.ts +84 -0
- package/src/cli/module-host.ts +11 -0
- package/src/cli/module-verbs.ts +50 -0
- package/src/cli/numerical-policy.ts +12 -0
- package/src/cli/perplexity.ts +89 -0
- package/src/cli/serve-host.ts +423 -0
- package/src/cli/serve-isolated.ts +217 -0
- package/src/cli/serve-options.ts +106 -0
- package/src/cli/serve-state.ts +205 -0
- package/src/cli/serve.ts +500 -0
- package/src/cli/served-model-host.ts +102 -0
- package/src/cli/server-entry.ts +148 -0
- package/src/cli/serving-unit.ts +177 -0
- package/src/{tui.ts → cli/terminal.ts} +13 -8
- package/src/cli/worker-adapters.ts +34 -0
- package/src/cli/worker-entry.ts +272 -0
- package/src/cli/worker-unit.ts +179 -0
- package/src/engine/adapter-operation.ts +26 -0
- package/src/engine/cache-services.ts +114 -0
- package/src/engine/completion.ts +39 -0
- package/src/engine/generation-gateway.ts +358 -0
- package/src/engine/index.ts +59 -0
- package/src/engine/kv-budget.ts +120 -0
- package/src/engine/media-preparation.ts +232 -0
- package/src/engine/model-binding.ts +24 -0
- package/src/engine/model-host.ts +513 -0
- package/src/engine/model-serving.ts +89 -0
- package/src/{serve → engine}/preparation.ts +7 -5
- package/src/{serve → engine}/session-completion-engine.ts +6 -6
- package/src/engine/telemetry.ts +109 -0
- package/src/hub/downloads.ts +116 -0
- package/src/jobs/db.ts +16 -7
- package/src/jobs/events.ts +29 -0
- package/src/jobs/executable.ts +5 -0
- package/src/jobs/host.ts +51 -0
- package/src/jobs/in-process.ts +55 -0
- package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
- package/src/jobs/runner.ts +150 -231
- package/src/jobs/service.ts +75 -0
- package/src/jobs/sse.ts +59 -23
- package/src/jobs/worker-memory.ts +46 -0
- package/src/jobs/worker-process.ts +163 -0
- package/src/jobs/worker-supervisor.ts +258 -0
- package/src/modules.ts +58 -0
- package/src/publishing/catalog-hub.ts +18 -0
- package/src/publishing/credentials.ts +31 -0
- package/src/publishing/upload.ts +37 -0
- package/src/residency/leased-adapters.ts +21 -0
- package/src/residency/local-records.ts +16 -0
- package/src/residency/model-residency.ts +405 -0
- package/src/residency/record-index.ts +28 -0
- package/src/residency/resident-estimate.ts +50 -0
- package/src/{anthropic.ts → server/anthropic.ts} +3 -81
- package/src/server/cache-routes.ts +36 -0
- package/src/{serve → server}/chat-request.ts +10 -10
- package/src/{serve → server}/chat-stage.ts +14 -14
- package/src/{client.ts → server/client.ts} +28 -2
- package/src/{serve → server}/completion-executor.ts +33 -41
- package/src/server/decision-body.ts +55 -0
- package/src/server/decision-routes.ts +134 -0
- package/src/server/decision-wire.ts +228 -0
- package/src/{serve → server}/discovery-routes.ts +25 -82
- package/src/{serve → server}/http.ts +25 -13
- package/src/{serve → server}/inference-request.ts +5 -5
- package/src/server/job-routes.ts +20 -0
- package/src/server/media-prompt.ts +63 -0
- package/src/server/memory-completion-client.ts +46 -0
- package/src/server/model-routes.ts +192 -0
- package/src/{serve → server}/openai-wire.ts +3 -2
- package/src/{serve → server}/pipeline.ts +1 -1
- package/src/server/prompt-builder.ts +13 -0
- package/src/server/prompt-contracts.ts +17 -0
- package/src/server/proxy-routes.ts +187 -0
- package/src/server/publishing-routes.ts +41 -0
- package/src/{serve → server}/request-plan.ts +6 -8
- package/src/{serve → server}/request-prep.ts +47 -50
- package/src/{serve → server}/responses-client.ts +30 -13
- package/src/{responses.ts → server/responses.ts} +12 -93
- package/src/server/routes.ts +205 -0
- package/src/server/start.ts +72 -0
- package/src/server/status-routes.ts +108 -0
- package/src/{serve → server}/text-completion-stage.ts +25 -4
- package/src/server/text-prompt.ts +12 -0
- package/src/{serve → server}/token-streams.ts +36 -38
- package/src/server/worker-routes.ts +311 -0
- package/src/storage/paths.ts +61 -0
- package/src/web/assets.ts +37 -0
- package/src/web/{src → browser}/api.ts +5 -23
- package/src/web/browser/chat-host.ts +17 -0
- package/src/web/browser/installed-panels.ts +6 -0
- package/src/web/browser/main.ts +55 -0
- package/src/web/browser/markdown.ts +279 -0
- package/src/web/browser/memory-panel.ts +9 -0
- package/src/web/browser/palette.ts +64 -0
- package/src/web/browser/protocol.ts +13 -0
- package/src/web/browser/shell.ts +467 -0
- package/src/web/{src → browser}/status.ts +32 -36
- package/src/web/build.ts +51 -0
- package/src/web/public/app.html +1054 -0
- package/src/web/{sw.js → public/sw.js} +4 -3
- package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
- package/src/web/{vendor → public/vendor}/hljs.js +2 -2
- package/THIRD_PARTY_LICENSES.md +0 -51
- package/docs/README.md +0 -107
- package/docs/archive/hlg-sampling.md +0 -350
- package/docs/archive/investigations/audio-input-plan.md +0 -356
- package/docs/archive/investigations/benchmark-ledger-through-v0.4.0.md +0 -3617
- package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
- package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
- package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
- package/docs/archive/investigations/curve-bisector-routing.md +0 -123
- package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
- package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
- package/docs/archive/investigations/dspark-handoff.md +0 -224
- package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
- package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
- package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
- package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
- package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
- package/docs/archive/investigations/lab-build-journal.md +0 -157
- package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
- package/docs/archive/investigations/openjarvis-fit.md +0 -198
- package/docs/archive/investigations/openwiki-evaluation.md +0 -249
- package/docs/archive/investigations/optimization_plan.md +0 -346
- package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
- package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
- package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
- package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
- package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
- package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
- package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
- package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
- package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
- package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
- package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
- package/docs/archive/planning/chat-ui-vision.md +0 -50
- package/docs/archive/planning/chunk-task-roadmap.md +0 -77
- package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
- package/docs/archive/planning/journal.md +0 -316
- package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
- package/docs/archive/planning/pi-integration-review.md +0 -178
- package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
- package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
- package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
- package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
- package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
- package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
- package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
- package/docs/archive/planning/release-notes-v0.4.0.md +0 -45
- package/docs/archive/planning/release-notes-v0.5.0.md +0 -37
- package/docs/archive/planning/web-ui-pass-plan.md +0 -213
- package/docs/archive/planning/website-readme-pass-plan.md +0 -224
- package/docs/design/batching.md +0 -2054
- package/docs/design/decode-speed-program.md +0 -2404
- package/docs/design/dreaming-nightly-pipeline.md +0 -684
- package/docs/design/generic-model-support.md +0 -821
- package/docs/design/kv-cache.md +0 -993
- package/docs/design/orpo-training.md +0 -680
- package/docs/design/speculative-decoding.md +0 -2129
- package/docs/design/turboquant.md +0 -2225
- package/docs/design/unified-engine-frontier-plan.md +0 -1987
- package/docs/design/web-chat-redesign.md +0 -695
- package/docs/planning/PRODUCT_ROADMAP.md +0 -593
- package/docs/planning/ResearchTopics.md +0 -119
- package/docs/planning/public-readiness-handoff.md +0 -244
- package/docs/planning/public-readiness.md +0 -149
- package/docs/planning/video-series.md +0 -421
- package/docs/reference/benchmarks.md +0 -3587
- package/docs/reference/cli.md +0 -646
- package/docs/reference/distribution.md +0 -380
- package/docs/reference/environment.md +0 -494
- package/docs/reference/glossary.md +0 -39
- package/docs/reference/library-api.md +0 -688
- package/docs/reference/memory.md +0 -260
- package/docs/reference/models.md +0 -346
- package/docs/reference/server-api.md +0 -1945
- package/docs/reference/server-config.md +0 -973
- package/docs/reference/training.md +0 -462
- package/docs/reference/troubleshooting.md +0 -158
- package/src/admission-plan.ts +0 -18
- package/src/audio/audiotoolbox.ts +0 -112
- package/src/audio/conformer.ts +0 -655
- package/src/audio/decode.ts +0 -133
- package/src/audio/features.ts +0 -202
- package/src/audio/mic-capture.ts +0 -98
- package/src/audio/silero-vad.ts +0 -379
- package/src/audio/transcode.ts +0 -67
- package/src/audio/whisper-decode.ts +0 -774
- package/src/audio/whisper-fast.ts +0 -732
- package/src/audio/whisper-format.ts +0 -73
- package/src/audio/whisper-mel.ts +0 -185
- package/src/audio/whisper-timing.ts +0 -274
- package/src/audio/whisper-tokenizer.ts +0 -239
- package/src/audio/whisper-transcribe.ts +0 -410
- package/src/backends/mlx/assistant-target.ts +0 -46
- package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
- package/src/backends/mlx/autoregressive.ts +0 -129
- package/src/backends/mlx/batch-group.ts +0 -1874
- package/src/backends/mlx/cache-attachment.ts +0 -67
- package/src/backends/mlx/cache-layout.ts +0 -31
- package/src/backends/mlx/checkpoint-state.ts +0 -53
- package/src/backends/mlx/continuation-persistence.ts +0 -107
- package/src/backends/mlx/continuation-request.ts +0 -43
- package/src/backends/mlx/continuation.ts +0 -77
- package/src/backends/mlx/diffusion.ts +0 -39
- package/src/backends/mlx/draft-target.ts +0 -32
- package/src/backends/mlx/encoder-cache.ts +0 -25
- package/src/backends/mlx/evaluation.ts +0 -105
- package/src/backends/mlx/fill-append.ts +0 -58
- package/src/backends/mlx/fill-group.ts +0 -497
- package/src/backends/mlx/full-kv-row-append.ts +0 -32
- package/src/backends/mlx/full-kv-row-donor.ts +0 -54
- package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
- package/src/backends/mlx/gateway-binding.ts +0 -174
- package/src/backends/mlx/graph.ts +0 -38
- package/src/backends/mlx/kv-codec.ts +0 -9
- package/src/backends/mlx/kv-maintenance.ts +0 -161
- package/src/backends/mlx/kv-tensor-rows.ts +0 -212
- package/src/backends/mlx/memory-client.ts +0 -189
- package/src/backends/mlx/methods.ts +0 -90
- package/src/backends/mlx/mixed-iteration.ts +0 -62
- package/src/backends/mlx/model-prompt.ts +0 -178
- package/src/backends/mlx/model-serving.ts +0 -80
- package/src/backends/mlx/paged-cache-codec.ts +0 -27
- package/src/backends/mlx/prefill-cohort.ts +0 -100
- package/src/backends/mlx/prefill-policy.ts +0 -26
- package/src/backends/mlx/prefill-rows.ts +0 -244
- package/src/backends/mlx/prefill.ts +0 -33
- package/src/backends/mlx/projected-context-rows.ts +0 -72
- package/src/backends/mlx/prompt-input.ts +0 -29
- package/src/backends/mlx/qwen-prompt-input.ts +0 -40
- package/src/backends/mlx/request-policy.ts +0 -20
- package/src/backends/mlx/request-state-policy.ts +0 -54
- package/src/backends/mlx/rollback.ts +0 -92
- package/src/backends/mlx/row-sampling.ts +0 -49
- package/src/backends/mlx/serial-executor.ts +0 -251
- package/src/backends/mlx/speculative-group.ts +0 -438
- package/src/backends/mlx/speculative-round.ts +0 -161
- package/src/backends/mlx/speculative.ts +0 -131
- package/src/backends/mlx/state-rows.ts +0 -104
- package/src/backends/mlx/state-views.ts +0 -46
- package/src/backends/mlx/target-layout-capability.ts +0 -35
- package/src/backends/mlx/text-engine.ts +0 -73
- package/src/backends/mlx/transitioning-kv-rows.ts +0 -173
- package/src/chat-template.ts +0 -382
- package/src/cli.ts +0 -3490
- package/src/config.ts +0 -399
- package/src/contracts/completion.ts +0 -16
- package/src/contracts/execution.ts +0 -70
- package/src/contracts/generation.ts +0 -103
- package/src/contracts/host.ts +0 -7
- package/src/contracts/object-cache.ts +0 -8
- package/src/contracts/pi-provider.ts +0 -30
- package/src/contracts/pi.ts +0 -261
- package/src/contracts/prefix-cache.ts +0 -33
- package/src/contracts/resources.ts +0 -25
- package/src/contracts/sampling.ts +0 -23
- package/src/contracts/scheduling.ts +0 -54
- package/src/contracts/tsconfig.json +0 -14
- package/src/dataset/generators.ts +0 -1087
- package/src/dataset/index.ts +0 -12
- package/src/dataset/job.ts +0 -81
- package/src/dataset/llm.ts +0 -71
- package/src/dataset/registry.ts +0 -528
- package/src/diffusion/diffusion-generate.ts +0 -507
- package/src/download.ts +0 -505
- package/src/embed.ts +0 -77
- package/src/engine/admission.ts +0 -59
- package/src/engine/cancellation.ts +0 -38
- package/src/engine/engine.ts +0 -56
- package/src/engine/execution-coordinator.ts +0 -70
- package/src/engine/execution-plan.ts +0 -64
- package/src/engine/execution-tasks.ts +0 -44
- package/src/engine/namespaced-cache.ts +0 -13
- package/src/engine/resources.ts +0 -53
- package/src/engine/scheduler.ts +0 -92
- package/src/engine/session.ts +0 -247
- package/src/eval/README.md +0 -130
- package/src/eval/ifeval.ts +0 -81
- package/src/eval/kl-prompts.ts +0 -29
- package/src/eval/kl.ts +0 -590
- package/src/eval/perplexity.ts +0 -164
- package/src/eval/quality-db.ts +0 -92
- package/src/eval/reference-logits.ts +0 -207
- package/src/eval/runner.ts +0 -124
- package/src/eval/score.ts +0 -49
- package/src/eval/tasks/bfcl.ts +0 -535
- package/src/eval/tasks/gsm8k.ts +0 -98
- package/src/eval/tasks/hashhop.ts +0 -139
- package/src/eval/tasks/humaneval.ts +0 -275
- package/src/eval/tasks/ifeval.ts +0 -525
- package/src/eval/tasks/mmlu.ts +0 -157
- package/src/eval/ultrafeedback.ts +0 -60
- package/src/evaldb.ts +0 -199
- package/src/expert-io.ts +0 -393
- package/src/expert-offload-build.ts +0 -77
- package/src/expert-offload.ts +0 -76
- package/src/expert-residency.ts +0 -1134
- package/src/expert-usage.ts +0 -415
- package/src/fill/echo-index.ts +0 -188
- package/src/fill/fill-session.ts +0 -463
- package/src/fill/proposal.ts +0 -68
- package/src/fill/schema-rows.ts +0 -506
- package/src/fill/tool-boundary.ts +0 -103
- package/src/fit.ts +0 -249
- package/src/generate.ts +0 -1352
- package/src/grammar.ts +0 -604
- package/src/harness-pi.ts +0 -184
- package/src/hf-push.ts +0 -628
- package/src/hub-rest.ts +0 -242
- package/src/index.ts +0 -63
- package/src/inference/denoising.ts +0 -17
- package/src/inference/draft-acceptance.ts +0 -41
- package/src/inference/draft-output.ts +0 -49
- package/src/inference/graph.ts +0 -33
- package/src/inference/prefill.ts +0 -45
- package/src/inference/rollback.ts +0 -7
- package/src/jobs/index.ts +0 -31
- package/src/jobs/job-entry.ts +0 -107
- package/src/jobs/task-client.ts +0 -19
- package/src/jobs/types.ts +0 -2
- package/src/kv-scheme.ts +0 -279
- package/src/kv-store.ts +0 -1135
- package/src/lab/README.md +0 -22
- package/src/lab/curve/curve-designer.html +0 -303
- package/src/lab/curve/curve-sampler.ts +0 -122
- package/src/lab/expert-trace/expert-trace.ts +0 -69
- package/src/lab/paged-kv/paged-attention.ts +0 -117
- package/src/lab/paged-kv/paged-kv-rows.ts +0 -111
- package/src/lab/paged-kv/paged-kv.ts +0 -336
- package/src/library.ts +0 -40
- package/src/lora.ts +0 -408
- package/src/md-modules.d.ts +0 -54
- package/src/media-fetch.ts +0 -442
- package/src/memory/article.ts +0 -558
- package/src/memory/chunk-validation.ts +0 -150
- package/src/memory/chunk.ts +0 -318
- package/src/memory/cluster.ts +0 -351
- package/src/memory/coverage.ts +0 -134
- package/src/memory/crosslink.ts +0 -0
- package/src/memory/db.ts +0 -253
- package/src/memory/entity.ts +0 -203
- package/src/memory/gate.ts +0 -187
- package/src/memory/history.ts +0 -152
- package/src/memory/ingest.ts +0 -335
- package/src/memory/model.ts +0 -183
- package/src/memory/normalize.ts +0 -671
- package/src/memory/parse.ts +0 -22
- package/src/memory/pipeline.ts +0 -275
- package/src/memory/prompts.ts +0 -65
- package/src/memory/query.ts +0 -334
- package/src/memory/reconcile.ts +0 -734
- package/src/memory/redirect.ts +0 -108
- package/src/memory/reindex.ts +0 -325
- package/src/memory/resolve.ts +0 -307
- package/src/memory/rest.ts +0 -245
- package/src/memory/route.ts +0 -272
- package/src/memory/schedule.ts +0 -165
- package/src/memory/stages.ts +0 -777
- package/src/memory/synthesize.ts +0 -1638
- package/src/memory/tools.ts +0 -749
- package/src/memory/vault.ts +0 -1194
- package/src/memory/wikify.ts +0 -1064
- package/src/mlx/array.ts +0 -425
- package/src/mlx/autograd.ts +0 -304
- package/src/mlx/checkpoint.ts +0 -149
- package/src/mlx/compile.ts +0 -168
- package/src/mlx/custom-vjp.ts +0 -188
- package/src/mlx/ffi.ts +0 -531
- package/src/mlx/materialize.ts +0 -23
- package/src/mlx/metal-kernel.ts +0 -159
- package/src/mlx/normalized-argmax.ts +0 -116
- package/src/mlx/ops.ts +0 -1108
- package/src/mlx/quantized-rows.ts +0 -36
- package/src/mlx/token-bitmask.ts +0 -52
- package/src/mlx/turboquant-kv-decode.ts +0 -82
- package/src/mlx/turboquant-kv-inverse.ts +0 -122
- package/src/mlx/turboquant-ops.ts +0 -861
- package/src/mlx/turboquant-tables.ts +0 -237
- package/src/mmap.ts +0 -90
- package/src/model/artifact-identity.ts +0 -73
- package/src/model/batched-kv.ts +0 -235
- package/src/model/batched-mask.ts +0 -279
- package/src/model/batched-quant.ts +0 -212
- package/src/model/batched-quantized-kv.ts +0 -144
- package/src/model/batched-rotating-quant.ts +0 -353
- package/src/model/batched-rotating-state.ts +0 -149
- package/src/model/batched-rotating.ts +0 -338
- package/src/model/batched-row-storage.ts +0 -179
- package/src/model/batched-ssm.ts +0 -52
- package/src/model/batched-turboquant-kv.ts +0 -94
- package/src/model/compiled-decode.ts +0 -712
- package/src/model/decoded-kv-donor.ts +0 -12
- package/src/model/delayed-quantized-kv.ts +0 -72
- package/src/model/delayed-rotating-quantized-kv.ts +0 -93
- package/src/model/delayed-turboquant-kv.ts +0 -57
- package/src/model/diffusion-gemma.ts +0 -1026
- package/src/model/factory.ts +0 -215
- package/src/model/fingerprint.ts +0 -45
- package/src/model/flash-attention.ts +0 -694
- package/src/model/full-prefill-padding.ts +0 -56
- package/src/model/full-prefill-row.ts +0 -105
- package/src/model/gemma4-base.ts +0 -2370
- package/src/model/gemma4.ts +0 -1395
- package/src/model/generated/gemma4-12b.ts +0 -429
- package/src/model/generated/gemma4-26b.ts +0 -448
- package/src/model/generated/gemma4-e4b.ts +0 -717
- package/src/model/generated/index.ts +0 -18
- package/src/model/glm52-atlas.ts +0 -511
- package/src/model/glm52-cache.ts +0 -792
- package/src/model/glm52-config.ts +0 -262
- package/src/model/glm52-container.ts +0 -305
- package/src/model/glm52-coupling.ts +0 -388
- package/src/model/glm52-dsa.ts +0 -606
- package/src/model/glm52-expert-layout.ts +0 -253
- package/src/model/glm52-layout.ts +0 -152
- package/src/model/glm52-memory.ts +0 -500
- package/src/model/glm52-mla.ts +0 -792
- package/src/model/glm52-moe.ts +0 -223
- package/src/model/glm52-pilot.ts +0 -537
- package/src/model/glm52-reference.ts +0 -445
- package/src/model/glm52-residency.ts +0 -557
- package/src/model/glm52-resident-weights.ts +0 -135
- package/src/model/glm52-streamed-experts.ts +0 -453
- package/src/model/glm52-streamed-metal.ts +0 -610
- package/src/model/glm52-weights.ts +0 -503
- package/src/model/glm52.ts +0 -1132
- package/src/model/implementation.ts +0 -69
- package/src/model/kv-attention-view.ts +0 -70
- package/src/model/minicpm5.ts +0 -376
- package/src/model/profile.ts +0 -468
- package/src/model/quantized-append-attention.ts +0 -31
- package/src/model/qwen-append.ts +0 -12
- package/src/model/qwen-conv.ts +0 -52
- package/src/model/qwen3-delta-state.ts +0 -74
- package/src/model/qwen3-delta.ts +0 -451
- package/src/model/qwen3-moe.ts +0 -404
- package/src/model/qwen3-mrope.ts +0 -250
- package/src/model/qwen3.ts +0 -277
- package/src/model/qwen3_5-checkpoint.ts +0 -164
- package/src/model/qwen3_5.ts +0 -881
- package/src/model/rotating-kv-donor.ts +0 -35
- package/src/model/rotating-kv-layout.ts +0 -262
- package/src/model/rotating-row-transaction.ts +0 -35
- package/src/model/speculative-rotating-kv.ts +0 -101
- package/src/model/ssm-prefill-padding.ts +0 -39
- package/src/model/support.ts +0 -110
- package/src/model/token-groups.ts +0 -66
- package/src/model/trellis-balanced-scatter.ts +0 -51
- package/src/model/trellis-linear.ts +0 -672
- package/src/model/trellis-shared-m.ts +0 -151
- package/src/model/trellis-shared-scatter.ts +0 -144
- package/src/model/trellis-splitk-prefill.ts +0 -158
- package/src/model/trellis-tiled-prefill.ts +0 -136
- package/src/model/trellis-vector-expand.ts +0 -62
- package/src/model/trellis-wide-prefill.ts +0 -94
- package/src/model/turboquant-codec.ts +0 -89
- package/src/model/universal/archs.ts +0 -332
- package/src/model/universal/dense.ts +0 -612
- package/src/model/universal/modules.ts +0 -170
- package/src/model/universal/rope.ts +0 -381
- package/src/model/whisper.ts +0 -435
- package/src/native/expert_io.c +0 -523
- package/src/native/frame_extract.swift +0 -140
- package/src/native/mic_capture.swift +0 -92
- package/src/native-pack.ts +0 -163
- package/src/pi-provider.ts +0 -53
- package/src/pi-session.ts +0 -81
- package/src/pi-terminal.ts +0 -274
- package/src/pi-web.ts +0 -1940
- package/src/preflight.ts +0 -158
- package/src/prompt-cache.ts +0 -682
- package/src/quantize/allocator.ts +0 -627
- package/src/quantize/atomic-output.ts +0 -38
- package/src/quantize/calibration.ts +0 -181
- package/src/quantize/config-writer.ts +0 -145
- package/src/quantize/index.ts +0 -84
- package/src/quantize/job.ts +0 -162
- package/src/quantize/quantizer.ts +0 -666
- package/src/quantize/rotate.ts +0 -603
- package/src/quantize/safetensors-writer.ts +0 -249
- package/src/quantize/sensitivity.ts +0 -216
- package/src/quantize/trellis.ts +0 -586
- package/src/quantize/weight-transform.ts +0 -292
- package/src/registry.ts +0 -602
- package/src/runtime-config.ts +0 -77
- package/src/safetensors.ts +0 -165
- package/src/sampler.ts +0 -1012
- package/src/serve/admin-routes.ts +0 -184
- package/src/serve/assets/curve-terrain.html +0 -105
- package/src/serve/assets/training-inference-map.html +0 -575
- package/src/serve/audio-routes.ts +0 -323
- package/src/serve/aux-routes.ts +0 -132
- package/src/serve/batch-scheduler.ts +0 -8
- package/src/serve/checkpoint-identity.ts +0 -64
- package/src/serve/generation-gateway.ts +0 -537
- package/src/serve/isolate.ts +0 -609
- package/src/serve/kv-budget.ts +0 -14
- package/src/serve/lab-routes.ts +0 -341
- package/src/serve/lane-registry.ts +0 -45
- package/src/serve/model-admin-routes.ts +0 -155
- package/src/serve/model-binding.ts +0 -49
- package/src/serve/model-host.ts +0 -511
- package/src/serve/parent-application.ts +0 -56
- package/src/serve/prompt-response-trace.ts +0 -161
- package/src/serve/response-lease.ts +0 -24
- package/src/serve/session-search.ts +0 -326
- package/src/serve/static-routes.ts +0 -101
- package/src/serve/transcription-server.ts +0 -64
- package/src/serve/transcription-service.ts +0 -502
- package/src/server.ts +0 -1282
- package/src/spec/assistant-rows.ts +0 -93
- package/src/spec/assistant-source.ts +0 -126
- package/src/spec/cache-identity.ts +0 -22
- package/src/spec/deepspec-rows.ts +0 -29
- package/src/spec/deepspec-source.ts +0 -145
- package/src/spec/dflash-source.ts +0 -149
- package/src/spec/drafter.ts +0 -304
- package/src/spec/dspark/ab-stats.ts +0 -136
- package/src/spec/dspark/calibration.ts +0 -112
- package/src/spec/dspark/data-dflash.ts +0 -156
- package/src/spec/dspark/data.ts +0 -201
- package/src/spec/dspark/deepspec-module.ts +0 -776
- package/src/spec/dspark/generate-dflash.ts +0 -245
- package/src/spec/dspark/generate.ts +0 -290
- package/src/spec/dspark/loader.ts +0 -23
- package/src/spec/dspark/loss.ts +0 -213
- package/src/spec/dspark/module-dflash.ts +0 -560
- package/src/spec/dspark/module.ts +0 -540
- package/src/spec/dspark/quantize-drafter.ts +0 -91
- package/src/spec/dspark/sample.ts +0 -112
- package/src/spec/generate.ts +0 -276
- package/src/spec/glm52-mtp-graph.ts +0 -29
- package/src/spec/glm52-mtp-rows.ts +0 -132
- package/src/spec/glm52-mtp-source.ts +0 -318
- package/src/spec/glm52-mtp-state.ts +0 -33
- package/src/spec/ngram-source.ts +0 -226
- package/src/spec/projected-draft-rows.ts +0 -73
- package/src/spec/qwen-mtp-module.ts +0 -171
- package/src/spec/qwen-mtp-rows.ts +0 -230
- package/src/spec/qwen-mtp-source.ts +0 -386
- package/src/spec/qwen-mtp-state.ts +0 -30
- package/src/spec/serve-loop.ts +0 -587
- package/src/spec/source.ts +0 -228
- package/src/spec/two-model-rows.ts +0 -62
- package/src/spec/two-model.ts +0 -113
- package/src/ssd-cache.ts +0 -431
- package/src/ssd-durability.ts +0 -209
- package/src/storage/host-buffer.ts +0 -24
- package/src/storage/kv-writer.ts +0 -83
- package/src/storage/kv-writer.worker.js +0 -264
- package/src/storage/retention-policy.ts +0 -37
- package/src/tiered-prompt-cache.ts +0 -45
- package/src/tokenizer.ts +0 -335
- package/src/tool-approvals.ts +0 -131
- package/src/tool-call.ts +0 -695
- package/src/train/dataset.ts +0 -484
- package/src/train/diffusion-lora.ts +0 -216
- package/src/train/export.ts +0 -32
- package/src/train/flash-cce.ts +0 -1234
- package/src/train/forward.ts +0 -266
- package/src/train/fuse.ts +0 -243
- package/src/train/index.ts +0 -46
- package/src/train/job.ts +0 -205
- package/src/train/lora-params.ts +0 -254
- package/src/train/loss.ts +0 -1591
- package/src/train/merge.ts +0 -195
- package/src/train/optimizer.ts +0 -183
- package/src/train/prefix-shared.ts +0 -490
- package/src/train/rank.ts +0 -137
- package/src/train/segmented.ts +0 -1828
- package/src/train/steel-qmm-header.ts +0 -1461
- package/src/train/trainer.ts +0 -1221
- package/src/train/watch.ts +0 -542
- package/src/vision/diffusion-vision.ts +0 -620
- package/src/vision/embedder.ts +0 -176
- package/src/vision/preprocess.ts +0 -247
- package/src/vision/prompt.ts +0 -409
- package/src/vision/qwen3vl-preprocess.ts +0 -409
- package/src/vision/qwen3vl-prompt.ts +0 -233
- package/src/vision/qwen3vl-tower.ts +0 -566
- package/src/vision/siglip.ts +0 -607
- package/src/vision/video-frames.ts +0 -148
- package/src/web/app.html +0 -2155
- package/src/web/app.js +0 -5863
- package/src/web/skills/memory/SKILL.md +0 -120
- package/src/web/skills/web-research/SKILL.md +0 -46
- package/src/web/skills.ts +0 -97
- package/src/web/src/adapters-panel.ts +0 -288
- package/src/web/src/assistant.ts +0 -451
- package/src/web/src/chat.ts +0 -1060
- package/src/web/src/composer.ts +0 -962
- package/src/web/src/dataset.ts +0 -132
- package/src/web/src/finetune.ts +0 -267
- package/src/web/src/hub.ts +0 -428
- package/src/web/src/main.ts +0 -98
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +0 -572
- package/src/web/src/model-picker.ts +0 -159
- package/src/web/src/palette.ts +0 -346
- package/src/web/src/protocol.ts +0 -26
- package/src/web/src/quantize.ts +0 -167
- package/src/web/src/rag.ts +0 -274
- package/src/web/src/sessions.ts +0 -469
- package/src/web/src/shell.ts +0 -804
- package/src/web/src/ui-catalog.ts +0 -78
- package/src/web/src/voice.ts +0 -141
- package/src/web/vendor/README.md +0 -61
- package/src/web-assets.ts +0 -47
- package/src/web-tools.ts +0 -478
- package/src/weights.ts +0 -255
- /package/src/{serve → server}/completion-sink.ts +0 -0
- /package/src/{serve → server}/generated-token-history.ts +0 -0
- /package/src/web/{icon.svg → public/icon.svg} +0 -0
- /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
- /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// The public `mlx-bun/server` entry: main's in-process `createServer` over a
|
|
2
|
+
// caller-loaded model context, with main's `loadContext`. The server is the app
|
|
3
|
+
// `mlx-bun serve` composes (serve.ts startApp: the persistent state, then
|
|
4
|
+
// serve-host's startContextHost), so it serves the same routes, browser app,
|
|
5
|
+
// Pi chat, jobs, and hub. Loading this module loads no native library and
|
|
6
|
+
// starts nothing; `createServer` imports the composition when it is called.
|
|
7
|
+
import type { DurabilityFlushResult } from "@mlx-bun/inference/state";
|
|
8
|
+
import { releaseContext, type ContextOwnership, type LoadedModelContext } from "../engine/model-host";
|
|
9
|
+
import type { ContextHost, ContextHostOptions } from "./serve-host";
|
|
10
|
+
import type { ServeOptions } from "./serve-options";
|
|
11
|
+
|
|
12
|
+
export { loadContext } from "../engine/model-host";
|
|
13
|
+
export type { AdapterService, ContextOwnership, DraftKind, GenSamplingDefaults, LoadContextOptions, LoadedModelContext,
|
|
14
|
+
ModelContext, ModelHostSource, ServedModelInfo } from "../engine/model-host";
|
|
15
|
+
export type { ModelBinding } from "../engine/model-binding";
|
|
16
|
+
export type { BuiltPrompt, ModelPromptBuilder, PromptNativeWork } from "../server/prompt-contracts";
|
|
17
|
+
export type { DurabilityFlushResult, DurabilitySnapshotStats } from "@mlx-bun/inference/state";
|
|
18
|
+
|
|
19
|
+
/** Serving policy, `mlx-bun serve`'s options by their programmatic names. */
|
|
20
|
+
export interface ServerOptions extends Partial<Pick<ServeOptions, "capacity" | "defaultGeneratedTokens" | "kvBudgetBytes" |
|
|
21
|
+
"memoryBudgetBytes" | "readOnly" | "cache" | "request" | "memoryPaths" | "chatPaths" | "storagePaths">>,
|
|
22
|
+
Omit<ContextHost, "ownership" | "owner"> {
|
|
23
|
+
/** The interface to bind. Omitted: Bun's default, every interface (main's
|
|
24
|
+
* library default); `mlx-bun serve` binds 127.0.0.1. */
|
|
25
|
+
hostname?: string;
|
|
26
|
+
/** The enforced context ceiling. Omitted: `MLX_BUN_RD_CONTEXT_LIMIT` when set, else none. */
|
|
27
|
+
contextLimit?: number | null;
|
|
28
|
+
/** The speech-to-text companion's checkpoint directory and residency; omitted,
|
|
29
|
+
* the first downloaded Whisper checkpoint is found on the first audio request. */
|
|
30
|
+
whisper?: Pick<NonNullable<ServeOptions["whisper"]>, "modelDir" | "modelId" | "idleUnloadSec" | "resident">;
|
|
31
|
+
/** Default "borrowed" (main's): the server never disposes the context. */
|
|
32
|
+
ownership?: ContextOwnership;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ServerShutdownResult {
|
|
36
|
+
/** The drain finished: the listener stopped and every resource the server created was released. */
|
|
37
|
+
stopped: boolean;
|
|
38
|
+
/** The deadline passed first. The drain continues; nothing was released early. */
|
|
39
|
+
timedOut: boolean;
|
|
40
|
+
/** The final cache flush's result. After a timeout, the pending counters with `durable: false`. */
|
|
41
|
+
durability: DurabilityFlushResult;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface RunningServer {
|
|
45
|
+
/** The bound TCP port. */
|
|
46
|
+
readonly port: number;
|
|
47
|
+
/** Flush prompt-cache persistence while serving (main's `flushServerCacheDurability`). */
|
|
48
|
+
flush(): Promise<DurabilityFlushResult>;
|
|
49
|
+
/** Stop admission and drain (main's `shutdownServer`); see createServer. */
|
|
50
|
+
close(options?: { timeoutMs?: number }): Promise<ServerShutdownResult>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Serve a loaded model context in this process: the full `mlx-bun serve` app
|
|
55
|
+
* (OpenAI, Anthropic, and Responses APIs, `/stats`, adapters, cache
|
|
56
|
+
* administration, the browser app, Pi web chat on `/ws/chat`, jobs, hub,
|
|
57
|
+
* memory, sessions, and publishing), over one shared continuous engine.
|
|
58
|
+
* Resolves once the listener is bound; `port` 0 binds an ephemeral port.
|
|
59
|
+
*
|
|
60
|
+
* The context comes from `loadContext` or a caller's own implementation.
|
|
61
|
+
* Without `options.binding` the built-in model classes supply the numerics; a
|
|
62
|
+
* supplied `binding` and `buildPrompt` reach the engine and routes as given,
|
|
63
|
+
* with no registry lookup, model class, or reload. Chat prompts render the
|
|
64
|
+
* context's template, and a context without one is refused, unless
|
|
65
|
+
* `buildPrompt` builds them (it then returns `probeStableLen: false`).
|
|
66
|
+
* `artifact` only describes the weights for `/fit`, `/stats`, and hub GC
|
|
67
|
+
* protection.
|
|
68
|
+
*
|
|
69
|
+
* The server applies no runtime switches and activates no expert offload; the
|
|
70
|
+
* process's runtime configuration and whatever loaded the context own those.
|
|
71
|
+
* It sets the MLX allocator limit from the context's runtime memory plan or
|
|
72
|
+
* `memoryBudgetBytes` and restores the previous limit after close. That limit
|
|
73
|
+
* is process-wide: servers running at the same time in one process share it,
|
|
74
|
+
* the last applied wins, and each close restores the value it found. Sequential
|
|
75
|
+
* servers over one context are supported. No signal handler, browser, or
|
|
76
|
+
* download is started; user stores default to HOME unless `memoryPaths`,
|
|
77
|
+
* `chatPaths`, or `storagePaths` name others.
|
|
78
|
+
*
|
|
79
|
+
* Ownership: by default the context is borrowed. Close, and any failed start
|
|
80
|
+
* (options, state, binding, caches, engine, or bind), release everything the
|
|
81
|
+
* server created and never the context, which stays usable (for another
|
|
82
|
+
* server) until the caller disposes it after close has resolved with
|
|
83
|
+
* `stopped: true`. With `ownership: "owned"` the server disposes the context
|
|
84
|
+
* exactly once, after execution drains or when startup fails, even when other
|
|
85
|
+
* cleanup fails.
|
|
86
|
+
*
|
|
87
|
+
* `close({ timeoutMs = 120_000 })` stops admission (new requests get 503),
|
|
88
|
+
* stops jobs and downloads, closes chat sessions, waits for responses in
|
|
89
|
+
* flight, then releases the engine, flushes and clears the caches, releases an
|
|
90
|
+
* owned context, and restores the allocator limit. One drain runs however often
|
|
91
|
+
* it is called; a failure rejects every call. It resolves `{ stopped: true,
|
|
92
|
+
* timedOut: false, durability }` with the final flush's result, which is
|
|
93
|
+
* `durable: false` when persistence is incomplete. If the deadline passes
|
|
94
|
+
* first it resolves `{ stopped: false, timedOut: true }` with the pending
|
|
95
|
+
* counters and `durable: false`, and the drain continues: weights are never
|
|
96
|
+
* released under running execution. Call close again (`timeoutMs: Infinity`
|
|
97
|
+
* waits without a deadline) before disposing a borrowed context.
|
|
98
|
+
*/
|
|
99
|
+
export async function createServer(context: LoadedModelContext, port = 0, options: ServerOptions = {}): Promise<RunningServer> {
|
|
100
|
+
const ownership = options.ownership ?? "borrowed";
|
|
101
|
+
// An owned context is released here if startup fails before the host takes
|
|
102
|
+
// it; the host owns its release, and every later cleanup, from its call on.
|
|
103
|
+
let transferred = false;
|
|
104
|
+
let app;
|
|
105
|
+
try {
|
|
106
|
+
const [{ startApp, profileContextLimit }, { startContextHost }, { createInProcessMemoryClient }] = await Promise.all([
|
|
107
|
+
import("./serve"), import("./serve-host"), import("./memory-engine"),
|
|
108
|
+
]);
|
|
109
|
+
const serving: ContextHostOptions = { port, hostname: options.hostname ?? null, capacity: options.capacity ?? 8,
|
|
110
|
+
contextLimit: options.contextLimit === undefined ? profileContextLimit() : options.contextLimit,
|
|
111
|
+
cache: options.cache ?? {}, request: options.request ?? {},
|
|
112
|
+
defaultGeneratedTokens: options.defaultGeneratedTokens, kvBudgetBytes: options.kvBudgetBytes,
|
|
113
|
+
memoryBudgetBytes: options.memoryBudgetBytes, whisper: options.whisper };
|
|
114
|
+
const served: ContextHost = { ownership, binding: options.binding, buildPrompt: options.buildPrompt,
|
|
115
|
+
artifact: options.artifact, defaultAdapter: options.defaultAdapter };
|
|
116
|
+
// Memory synthesis gets main's task model, as in `mlx-bun serve`; nothing
|
|
117
|
+
// loads before a run. The host's drain joins the state's close (jobs,
|
|
118
|
+
// downloads, synthesis) while the engine and model are still alive.
|
|
119
|
+
app = await startApp({ port, memoryPaths: options.memoryPaths, chatPaths: options.chatPaths, readOnly: options.readOnly ?? false,
|
|
120
|
+
memoryTaskModel: () => createInProcessMemoryClient() }, options.storagePaths ?? {}, state => {
|
|
121
|
+
transferred = true;
|
|
122
|
+
return startContextHost(state, context, serving, served, { beforeDrain: () => state.close() });
|
|
123
|
+
});
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (!transferred) {
|
|
126
|
+
try { releaseContext(context, ownership); }
|
|
127
|
+
catch (failure) { throw new AggregateError([error, failure], "startup and cleanup failed"); }
|
|
128
|
+
}
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
const { host } = app;
|
|
132
|
+
let drain: Promise<ServerShutdownResult> | undefined;
|
|
133
|
+
return {
|
|
134
|
+
port: host.port,
|
|
135
|
+
flush: () => host.flush(),
|
|
136
|
+
async close({ timeoutMs = 120_000 } = {}) {
|
|
137
|
+
const started = performance.now();
|
|
138
|
+
const work = drain ??= app.close().then(durability => ({ stopped: true, timedOut: false, durability }));
|
|
139
|
+
if (!Number.isFinite(timeoutMs)) return work;
|
|
140
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
141
|
+
const deadline = new Promise<ServerShutdownResult>(resolve => {
|
|
142
|
+
timer = setTimeout(() => resolve({ stopped: false, timedOut: true, durability: { ...host.stats(), durable: false,
|
|
143
|
+
flushedSnapshots: 0, missingSnapshots: 0, elapsedMs: performance.now() - started } }), Math.max(0, timeoutMs));
|
|
144
|
+
});
|
|
145
|
+
try { return await Promise.race([work, deadline]); } finally { clearTimeout(timer); }
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// One loaded model, served: its binding, caches, engine, and the routes bound
|
|
2
|
+
// to them. A unit is what the model host holds resident (residency/model-residency.ts);
|
|
3
|
+
// closing it drains its work, flushes its saved state durably, and releases the
|
|
4
|
+
// context by the ownership rule. Persistent services and the listener belong to
|
|
5
|
+
// the host that holds units (serve-host.ts), never to a unit.
|
|
6
|
+
import { releaseContext, requireChatTemplate, type ContextOwnership, type LoadedModelContext } from "../engine/model-host";
|
|
7
|
+
import type { ModelBinding } from "../engine/model-binding";
|
|
8
|
+
import type { KvBudget } from "../engine/kv-budget";
|
|
9
|
+
import type { UnitClosed, ResidentUnit } from "../residency/model-residency";
|
|
10
|
+
import { servingReserveBytes } from "../residency/resident-estimate";
|
|
11
|
+
import { fit } from "@mlx-bun/inference/execution/fit";
|
|
12
|
+
import type { DurabilityFlushResult, DurabilitySnapshotStats } from "@mlx-bun/inference/state";
|
|
13
|
+
import type { EventBus } from "@mlx-bun/app-core";
|
|
14
|
+
import type { DisposableResource } from "@mlx-bun/inference/contracts/portable";
|
|
15
|
+
import { createEngineTelemetry } from "../engine/telemetry";
|
|
16
|
+
import type { TranscriptionInfo } from "../server/discovery-routes";
|
|
17
|
+
import type { ModelPromptBuilder } from "../server/prompt-contracts";
|
|
18
|
+
import type { ResponseHistory } from "../server/responses";
|
|
19
|
+
import { resolveServingLimits, type ServeOptions } from "./serve-options";
|
|
20
|
+
import type { RouteGroup } from "./serve-state";
|
|
21
|
+
|
|
22
|
+
/** The serving policy one host applies to every unit: serve's options minus the loader's and the CLI process's own. */
|
|
23
|
+
export type ContextHostOptions = Pick<ServeOptions, "port" | "capacity" | "contextLimit" | "defaultGeneratedTokens" |
|
|
24
|
+
"kvBudgetBytes" | "memoryBudgetBytes" | "modelBudgetBytes" | "whisper" | "cache" | "request"> & {
|
|
25
|
+
/** The interface to bind; null binds Bun's default, every interface. */
|
|
26
|
+
hostname: string | null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** What a unit serves besides its context. Nothing here is loaded or looked up. */
|
|
30
|
+
export interface ContextHost {
|
|
31
|
+
/** Who releases the context; see ContextOwnership. */
|
|
32
|
+
ownership: ContextOwnership;
|
|
33
|
+
/** Replacement numerics for the context; default binds the built-in model classes. */
|
|
34
|
+
binding?: ModelBinding;
|
|
35
|
+
/** Replacement chat prompt construction; default renders the context's
|
|
36
|
+
* template. With one, a context without a template serves; the builder then
|
|
37
|
+
* returns `probeStableLen: false`. */
|
|
38
|
+
buildPrompt?: ModelPromptBuilder;
|
|
39
|
+
/** Descriptive artifact metadata for `/fit`, `/stats`, and hub GC protection;
|
|
40
|
+
* each field defaults to main's unknown value (path: the config's model directory). */
|
|
41
|
+
artifact?: { path?: string; sizeBytes?: number; expertsBytes?: number };
|
|
42
|
+
/** An adapter id already mounted on the context, used when a request names none. */
|
|
43
|
+
defaultAdapter?: string;
|
|
44
|
+
/** `/stats`' `server.owner`; default "embedded". */
|
|
45
|
+
owner?: string;
|
|
46
|
+
/** Milliseconds the loader took to load the model, published with its `model.load` event; absent for a context this host did not load. */
|
|
47
|
+
loadMs?: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Shared by every unit of one host. */
|
|
51
|
+
export interface UnitShared {
|
|
52
|
+
readonly responses: ResponseHistory;
|
|
53
|
+
/** The `events` bus: each unit's engine publishes its request timings and samples through it. */
|
|
54
|
+
readonly events: Pick<EventBus, "publish">;
|
|
55
|
+
readonly toolApprovalsFile?: string;
|
|
56
|
+
readonly transcription: () => Promise<TranscriptionInfo | null>;
|
|
57
|
+
/** One saved-state budget across every unit's store. */
|
|
58
|
+
readonly ssdBudget?: KvBudget;
|
|
59
|
+
/** The process allocator limit the host applied; bounds each unit's optional RAM caches. */
|
|
60
|
+
readonly allocatorLimitBytes?: number;
|
|
61
|
+
/** Each close's durability result, for the host's own final report. */
|
|
62
|
+
readonly onClosed?: (result: DurabilityFlushResult) => void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface ServingUnit extends ResidentUnit {
|
|
66
|
+
readonly context: LoadedModelContext;
|
|
67
|
+
readonly artifactPath: string;
|
|
68
|
+
/** Everything model-scoped: status, cache administration and the wire routes. */
|
|
69
|
+
readonly routes: RouteGroup;
|
|
70
|
+
/** Stop background work (idle demotion) ahead of a drain. */
|
|
71
|
+
stopBackground(): void;
|
|
72
|
+
flush(): Promise<DurabilityFlushResult>;
|
|
73
|
+
stats(): DurabilitySnapshotStats;
|
|
74
|
+
/** The engine's execution gateway, for callers that run work under its lock. */
|
|
75
|
+
readonly gateway: { acquireExecutionLease(signal?: AbortSignal): Promise<DisposableResource>; runExclusive<T>(fn: () => Promise<T>, trace?: undefined, signal?: AbortSignal): Promise<T> };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The context is released by `input.ownership` on close and on a failed
|
|
79
|
+
* start alike; everything else the unit created is released either way. A
|
|
80
|
+
* context without a chat template is refused unless `input.buildPrompt`
|
|
81
|
+
* builds its prompts. */
|
|
82
|
+
export async function createServingUnit(context: LoadedModelContext, options: ContextHostOptions, input: ContextHost,
|
|
83
|
+
shared: UnitShared): Promise<ServingUnit> {
|
|
84
|
+
let cleanup: (() => void | Promise<unknown>) | undefined = () => releaseContext(context, input.ownership);
|
|
85
|
+
try {
|
|
86
|
+
const [{ modelServingBinding, createCacheServices, createAppEngine },
|
|
87
|
+
{ createCompletionRoutes }, { GeneratedTokenHistory }, { createStatusRoutes }, { createCacheRoutes }, { createAdapterOperation }] = await Promise.all([
|
|
88
|
+
import("../engine"), import("../server/routes"), import("../server/generated-token-history"), import("../server/status-routes"),
|
|
89
|
+
import("../server/cache-routes"), import("../engine/adapter-operation"),
|
|
90
|
+
]);
|
|
91
|
+
// The default prompt path renders the context's template; a supplied builder replaces it.
|
|
92
|
+
if (!input.buildPrompt) requireChatTemplate(context);
|
|
93
|
+
const binding = await modelServingBinding(context, input.binding);
|
|
94
|
+
// The loaded model's cache service, built with its budget (`--kv-budget`, `--ssd-cache-max`).
|
|
95
|
+
const caches = await createCacheServices(context, binding, { ...options.cache,
|
|
96
|
+
...(options.kvBudgetBytes !== undefined ? { kvBudgetBytes: options.kvBudgetBytes } : {}),
|
|
97
|
+
...(shared.allocatorLimitBytes ? { allocatorLimitBytes: shared.allocatorLimitBytes } : {}),
|
|
98
|
+
...(shared.ssdBudget ? { ssdBudget: shared.ssdBudget } : {}) });
|
|
99
|
+
const cache = caches.cache;
|
|
100
|
+
// The persistence result of the final flush is the close's evidence.
|
|
101
|
+
let durability: DurabilityFlushResult | undefined;
|
|
102
|
+
const closeCaches = async () => {
|
|
103
|
+
const result = durability = await cache.close();
|
|
104
|
+
if (!result.durable) console.warn(`[server] cache flush incomplete: ${result.pendingSnapshots} snapshots, ${result.pendingSpills} spills, ${result.failedSpills} failed`);
|
|
105
|
+
};
|
|
106
|
+
cleanup = async () => { try { await closeCaches(); } finally { releaseContext(context, input.ownership); } };
|
|
107
|
+
// createAppEngine takes ownership even when its constructor rejects.
|
|
108
|
+
cleanup = undefined;
|
|
109
|
+
const engine = await createAppEngine(context, { capacity: options.capacity, binding, ownership: input.ownership,
|
|
110
|
+
gateway: { cache, adapterNamespace: caches.adapterNamespace },
|
|
111
|
+
beforeModelDispose: closeCaches,
|
|
112
|
+
});
|
|
113
|
+
cleanup = () => engine.close();
|
|
114
|
+
// The engine's events (request timings, batch and cache samples) come from one adapter around the completion engine.
|
|
115
|
+
const telemetry = createEngineTelemetry({ events: shared.events, model: context.modelId, capacity: options.capacity,
|
|
116
|
+
weightsBytes: context.model.weightsBytes, gateway: engine.gateway, cache });
|
|
117
|
+
engine.completion = telemetry.observe(engine.completion);
|
|
118
|
+
telemetry.sample();
|
|
119
|
+
const tokenHistory = new GeneratedTokenHistory(context.tokenizer);
|
|
120
|
+
for (const tokens of cache.savedPrefixes()) tokenHistory.remember(tokens);
|
|
121
|
+
cache.onPut = tokens => tokenHistory.remember(tokens);
|
|
122
|
+
const admission = context.memoryPlan ?? fit(context.model.config, context.model.weightsBytes, 1,
|
|
123
|
+
undefined, undefined, 0, options.memoryBudgetBytes, caches.resolvedKvScheme.fitOptions);
|
|
124
|
+
const limits = resolveServingLimits(options, context.memoryPlan, admission);
|
|
125
|
+
const completions = createCompletionRoutes(engine, { ...options.request, promptCache: cache,
|
|
126
|
+
...limits, tokenHistory, responseHistory: shared.responses,
|
|
127
|
+
transcription: shared.transcription,
|
|
128
|
+
...(input.buildPrompt ? { buildPrompt: input.buildPrompt } : {}),
|
|
129
|
+
...(input.defaultAdapter ? { defaultAdapter: input.defaultAdapter } : {}) });
|
|
130
|
+
const status = createStatusRoutes({ ...(input.owner ? { owner: input.owner } : {}), context, cache,
|
|
131
|
+
resolvedKvScheme: caches.resolvedKvScheme, gateway: engine.gateway,
|
|
132
|
+
diagnostics: () => binding.diagnostics(), responseStats: completions.responseStats,
|
|
133
|
+
artifact: { expertsBytes: input.artifact?.expertsBytes ?? 0, sizeBytes: input.artifact?.sizeBytes ?? null },
|
|
134
|
+
capacity: options.capacity, contextLimit: limits.contextLimit, startedAt: Date.now(),
|
|
135
|
+
ssdCacheDir: options.cache.ssdCacheDir, memoryBudgetBytes: options.memoryBudgetBytes });
|
|
136
|
+
const cacheAdmin = createCacheRoutes(cache);
|
|
137
|
+
const adapters = createAdapterOperation(context, engine.gateway);
|
|
138
|
+
const routes: RouteGroup = { handle: async request => await status.handle(request) ?? await cacheAdmin.handle(request) ?? await completions.handle(request) };
|
|
139
|
+
const artifactPath = input.artifact?.path ?? context.model.config.modelDir;
|
|
140
|
+
// Weights plus the KV and working set of a typical context, plus the RAM prefix cache it holds now.
|
|
141
|
+
const reserve = context.memoryPlan ? 0 : servingReserveBytes(context.model.config, context.model.weightsBytes,
|
|
142
|
+
{ expertsBytes: input.artifact?.expertsBytes, kvScheme: caches.resolvedKvScheme.fitOptions });
|
|
143
|
+
let closing: Promise<UnitClosed> | undefined;
|
|
144
|
+
const unit: ServingUnit = {
|
|
145
|
+
id: context.modelId, context, artifactPath, routes, gateway: engine.gateway,
|
|
146
|
+
// Saved state was found for this model: a request can resume from it.
|
|
147
|
+
resumed: (cache.report().saved?.entries ?? 0) > 0,
|
|
148
|
+
operations: ["generate", ...(binding.discovery.embeddings ? ["embed" as const] : [])],
|
|
149
|
+
bytes: () => context.memoryPlan ? context.memoryPlan.totalBytes : context.model.weightsBytes + reserve + cache.report().prefixes.bytes,
|
|
150
|
+
memory: () => {
|
|
151
|
+
const held = cache.report();
|
|
152
|
+
return { weightsBytes: context.model.weightsBytes, kvBytes: held.kv.projectedBytes, prefixCacheBytes: held.prefixes.bytes };
|
|
153
|
+
},
|
|
154
|
+
operationsFor: () => ({
|
|
155
|
+
generate: async request => await completions.handle(request) ?? Response.json({ error: { message: "Not found" } }, { status: 404 }),
|
|
156
|
+
adapters,
|
|
157
|
+
}),
|
|
158
|
+
pause: signal => engine.gateway.acquireExecutionLease(signal),
|
|
159
|
+
stopBackground: () => { telemetry.stop(); cache.stopIdleDemotion(); },
|
|
160
|
+
flush: () => cache.flush(),
|
|
161
|
+
stats: () => cache.stats(),
|
|
162
|
+
// Closes the engine (admission stops, work in flight drains), then flushes and clears the caches, then releases the context.
|
|
163
|
+
close: () => closing ??= (async () => {
|
|
164
|
+
const started = performance.now();
|
|
165
|
+
telemetry.stop();
|
|
166
|
+
await engine.close();
|
|
167
|
+
return { flushed: durability?.durable ?? true, drainMs: performance.now() - started - (durability?.elapsedMs ?? 0),
|
|
168
|
+
...(durability ? { flushMs: durability.elapsedMs } : {}) };
|
|
169
|
+
})().finally(() => { if (durability) shared.onClosed?.(durability); }),
|
|
170
|
+
};
|
|
171
|
+
return unit;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
try { await cleanup?.(); }
|
|
174
|
+
catch (failure) { throw new AggregateError([error, failure], "startup and cleanup failed"); }
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -40,6 +40,7 @@ const WORDMARK = `
|
|
|
40
40
|
██║ ╚═╝ ██║███████╗██╔╝ ██╗ ██████╔╝╚██████╔╝██║ ╚████║
|
|
41
41
|
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝`.slice(1);
|
|
42
42
|
|
|
43
|
+
/** Main's startup wordmark; one plain line when stdout is not a TTY. */
|
|
43
44
|
export function banner(version: string, tagline = "local AI · apple silicon · one binary"): void {
|
|
44
45
|
if (!tty()) {
|
|
45
46
|
console.log(`mlx-bun ${version} — ${tagline}`);
|
|
@@ -86,17 +87,21 @@ export function step(text: string): Step {
|
|
|
86
87
|
};
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
/** Rounded box with a gradient border. Lines may contain ANSI codes. */
|
|
90
|
-
export function
|
|
90
|
+
/** Rounded box with a gradient border, one output line per entry. Lines may contain ANSI codes. */
|
|
91
|
+
export function boxLines(lines: string[], { pad = 1 }: { pad?: number } = {}): string[] {
|
|
91
92
|
const visible = (s: string) => [...s.replace(/\x1b\[[0-9;]*m/g, "")].length;
|
|
92
93
|
const width = Math.max(...lines.map(visible)) + pad * 2;
|
|
93
94
|
const hue = (s: string) => (tty() ? fg(rampAt(0.15)) + s + RESET : s);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
return [
|
|
96
|
+
hue(` ╭${"─".repeat(width)}╮`),
|
|
97
|
+
...lines.map((l) => `${hue(" │")}${" ".repeat(pad)}${l}${" ".repeat(width - visible(l) - pad * 2)}${" ".repeat(pad)}${hue("│")}`),
|
|
98
|
+
hue(` ╰${"─".repeat(width)}╯`),
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Rounded box with a gradient border. Lines may contain ANSI codes. */
|
|
103
|
+
export function box(lines: string[], options: { pad?: number } = {}): void {
|
|
104
|
+
for (const line of boxLines(lines, options)) console.log(line);
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
export interface Column {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// A worker's `adapters` operation as the isolated parent reaches it: each call is one POST on the worker's private socket
|
|
2
|
+
// (`/admin/adapters`), which runs on the worker's own model under its engine lock (server/worker-routes.ts). Nothing here
|
|
3
|
+
// touches native code.
|
|
4
|
+
import type { AdapterMergeStats, AdapterOperation, MountedAdapter } from "@mlx-bun/app-core";
|
|
5
|
+
import { ModelHostFailure } from "@mlx-bun/app-services/portable";
|
|
6
|
+
import type { WorkerAdapterCall } from "../server/worker-routes";
|
|
7
|
+
|
|
8
|
+
export function workerAdapters(worker: { fetch(url: string, init?: RequestInit): Promise<Response> }): AdapterOperation {
|
|
9
|
+
async function call<T>(body: WorkerAdapterCall, signal: AbortSignal | undefined): Promise<T> {
|
|
10
|
+
let response: Response;
|
|
11
|
+
try {
|
|
12
|
+
response = await worker.fetch("http://engine/admin/adapters", { method: "POST", headers: { "content-type": "application/json" },
|
|
13
|
+
body: JSON.stringify(body), ...(signal ? { signal } : {}) });
|
|
14
|
+
} catch (error) {
|
|
15
|
+
// A worker that is down, restarting or gone under the call is the model host being unavailable, not a refusal of the adapter.
|
|
16
|
+
signal?.throwIfAborted();
|
|
17
|
+
throw new ModelHostFailure("closed", error instanceof Error ? error.message : String(error), { cause: error });
|
|
18
|
+
}
|
|
19
|
+
const text = await response.text();
|
|
20
|
+
let parsed: { error?: { message?: string } } & Record<string, unknown> = {};
|
|
21
|
+
try { parsed = JSON.parse(text) as typeof parsed; } catch { /* answered with something else */ }
|
|
22
|
+
if (!response.ok) throw new Error(parsed.error?.message ?? `the model worker answered ${response.status}`);
|
|
23
|
+
return parsed as T;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
async list(signal) { return (await call<{ adapters: MountedAdapter[] }>({ op: "list" }, signal)).adapters; },
|
|
27
|
+
async mount(id, path, signal) { return (await call<{ adapter: MountedAdapter }>({ op: "mount", id, path }, signal)).adapter; },
|
|
28
|
+
async unmount(id, signal) { return (await call<{ removed: number }>({ op: "unmount", id }, signal)).removed; },
|
|
29
|
+
async merge(request, signal) {
|
|
30
|
+
return (await call<{ stats: AdapterMergeStats }>({ op: "merge", adapters: [request.adapters[0], request.adapters[1]], output: request.output,
|
|
31
|
+
...(request.scales ? { scales: [...request.scales] } : {}) }, signal)).stats;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|