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,467 @@
|
|
|
1
|
+
// The app's shell glue: what the page needs around the generic web shell (`@mlx-bun/web-shell`, which owns
|
|
2
|
+
// navigation, hash routing, theme, the Developer switch, the shortcut sheet, the Escape overlay sweep, panel mounting
|
|
3
|
+
// and the palette chrome). Here: the app's routes and chrome hooks, the Hugging Face token settings and the shared
|
|
4
|
+
// push-to-hub flow, the agent-tools settings (the chat panel's host side), the overlays and key bindings that reach the
|
|
5
|
+
// chat panel, the connection pill and model identity polling, and the routes-map probe. The generic helpers the
|
|
6
|
+
// per-page modules import from here are re-exported from the shell package. main.ts holds the boot order.
|
|
7
|
+
|
|
8
|
+
import { $, createShell, toast, trapFocus, type FocusTrap, type Overlay, type Palette, type RouteController, type ShellPanel } from "@mlx-bun/web-shell";
|
|
9
|
+
import { api } from "./api";
|
|
10
|
+
import type { ApiEnvelope } from "./protocol";
|
|
11
|
+
|
|
12
|
+
export { $, el, injectStyles, toast, trapFocus, type FocusTrap } from "@mlx-bun/web-shell";
|
|
13
|
+
export type Controller = RouteController;
|
|
14
|
+
|
|
15
|
+
/* ════════════════════════════════════════════════════════════════════
|
|
16
|
+
THE SHELL — the app's pages and the chrome that depends on the page
|
|
17
|
+
════════════════════════════════════════════════════════════════════ */
|
|
18
|
+
/** The chat panel element's public methods, as the app calls them (the panel is `@mlx-bun/module-chat`'s: the shell mounts
|
|
19
|
+
* it as the first page, and the app reaches it through the element, never through an import). */
|
|
20
|
+
export interface ChatPanelApi extends HTMLElement {
|
|
21
|
+
newChat(): void;
|
|
22
|
+
copyLastResponse(): void;
|
|
23
|
+
setCodingTools(enabled: boolean): void;
|
|
24
|
+
refreshAdapters(): void;
|
|
25
|
+
focusComposer(): void;
|
|
26
|
+
toggleThinking(): void;
|
|
27
|
+
recentChats(): { title: string; path: string }[];
|
|
28
|
+
openSession(path: string): boolean;
|
|
29
|
+
exportActiveChat(format?: "md" | "json"): Promise<void>;
|
|
30
|
+
toggleDrawer(): void;
|
|
31
|
+
closeDrawer(): void;
|
|
32
|
+
drawerOpen(): boolean;
|
|
33
|
+
popoverOpen(): boolean;
|
|
34
|
+
closePopover(): boolean;
|
|
35
|
+
}
|
|
36
|
+
/** The mounted chat panel, once the shell has created it (it does on the first visit, which is the home page's). */
|
|
37
|
+
export const chatPanel = (): ChatPanelApi | null => document.querySelector<ChatPanelApi>("mlx-chat-panel");
|
|
38
|
+
|
|
39
|
+
/** The chat is the product (a workspace panel the shell mounts first); the pages below are developer tools behind the nav's Developer switch. */
|
|
40
|
+
export const shell = createShell({
|
|
41
|
+
routes: [
|
|
42
|
+
{ id: "status", developer: true }, { id: "routes", developer: true },
|
|
43
|
+
],
|
|
44
|
+
home: "chat",
|
|
45
|
+
onRoute(route) {
|
|
46
|
+
// dim the ambient bloom slightly in the chat workspace so text reads cleanly
|
|
47
|
+
$("bloom").style.opacity = route === "chat" ? "0.55" : "1";
|
|
48
|
+
// The mobile drawer hamburger only makes sense on /chat (it opens the recent-chats sidebar, which only exists
|
|
49
|
+
// there): CSS hides it >=760px; this hides it off-route regardless of viewport width.
|
|
50
|
+
$("chat-hamburger").style.display = route === "chat" ? "" : "none";
|
|
51
|
+
if (route !== "chat") chatPanel()?.closeDrawer();
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
/** Page controllers by route id, populated by main.ts; pages reach each other through it. */
|
|
55
|
+
export const controllers = shell.controllers;
|
|
56
|
+
export const currentRoute = (): string => shell.currentRoute();
|
|
57
|
+
export const isDeveloperMode = (): boolean => shell.isDeveloperMode();
|
|
58
|
+
export const setDeveloperMode = (on: boolean): void => shell.setDeveloperMode(on);
|
|
59
|
+
|
|
60
|
+
/* ════════════════════════════════════════════════════════════════════
|
|
61
|
+
SHARED HELPERS
|
|
62
|
+
════════════════════════════════════════════════════════════════════ */
|
|
63
|
+
export const gb = (b: number | null | undefined): string => b == null ? "—" : (b / 2 ** 30).toFixed(2) + " GB";
|
|
64
|
+
export const mb = (b: number | null | undefined): string => b == null ? "—" : (b / 2 ** 20).toFixed(1) + " MB";
|
|
65
|
+
export const num = (n: number | null | undefined): string => n == null ? "—" : Math.round(n).toLocaleString();
|
|
66
|
+
|
|
67
|
+
/* ════════════════════════════════════════════════════════════════════
|
|
68
|
+
HUGGING FACE — shared token settings + push-to-hub flow
|
|
69
|
+
════════════════════════════════════════════════════════════════════ */
|
|
70
|
+
|
|
71
|
+
/** Reflect saved-token state on the nav gear. */
|
|
72
|
+
export async function refreshHfGear(): Promise<boolean> {
|
|
73
|
+
try {
|
|
74
|
+
const d = await api("/api/settings/hf-token");
|
|
75
|
+
const saved = !!(d && d.ok && (d as { hasToken?: boolean }).hasToken);
|
|
76
|
+
$("nav-hf").classList.toggle("saved", saved);
|
|
77
|
+
$("nav-hf").title = saved ? "Hugging Face token saved · click to replace" : "Hugging Face token settings";
|
|
78
|
+
return saved;
|
|
79
|
+
} catch { return false; }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let hfOverlayTrap: FocusTrap | null = null; // set by initHfSettings() below
|
|
83
|
+
|
|
84
|
+
function openHfSettings(): void {
|
|
85
|
+
const ov = $("hf-overlay"); ov.classList.add("open");
|
|
86
|
+
if (hfOverlayTrap) hfOverlayTrap.capture();
|
|
87
|
+
($("hf-token-input") as HTMLInputElement).value = ""; $("hf-settings-msg").innerHTML = "";
|
|
88
|
+
$("hf-state").textContent = "Checking for a saved token…";
|
|
89
|
+
api("/api/settings/hf-token").then((d) => {
|
|
90
|
+
const saved = !!(d && d.ok && (d as { hasToken?: boolean }).hasToken);
|
|
91
|
+
$("hf-state").innerHTML = saved
|
|
92
|
+
? "A write token is <strong>saved</strong>. Enter a new one below to replace it."
|
|
93
|
+
: "No token saved yet. Add a write token to push models and datasets to the Hub.";
|
|
94
|
+
}).catch(() => { $("hf-state").textContent = "Could not reach the server."; });
|
|
95
|
+
setTimeout(() => $("hf-token-input").focus(), 50);
|
|
96
|
+
}
|
|
97
|
+
function closeHfSettings(): void {
|
|
98
|
+
$("hf-overlay").classList.remove("open");
|
|
99
|
+
if (hfOverlayTrap) hfOverlayTrap.restore();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function saveHfToken(): Promise<void> {
|
|
103
|
+
const tokenInput = $("hf-token-input") as HTMLInputElement;
|
|
104
|
+
const token = tokenInput.value.trim();
|
|
105
|
+
const msg = $("hf-settings-msg");
|
|
106
|
+
if (!token) { msg.innerHTML = '<div class="flash err">Enter a token first.</div>'; return; }
|
|
107
|
+
const btn = $("hf-save") as HTMLButtonElement; btn.disabled = true;
|
|
108
|
+
const d = await api("/api/settings/hf-token", { method: "POST", body: { token } }).catch((): ApiEnvelope => ({ ok: false, error: "request failed" }));
|
|
109
|
+
btn.disabled = false;
|
|
110
|
+
if (!d.ok) { msg.innerHTML = '<div class="flash err">' + escHtml(d.error || "could not save token") + "</div>"; return; }
|
|
111
|
+
msg.innerHTML = '<div class="flash ok">Token saved to <code>~/.mlx-bun/hf.json</code>.</div>';
|
|
112
|
+
tokenInput.value = "";
|
|
113
|
+
refreshHfGear();
|
|
114
|
+
toast("Hugging Face token saved", "ok");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Local esc() copy to avoid a circular import with markdown.ts (shell.ts
|
|
118
|
+
// only needs escaping, not the full markdown surface) — identical logic to
|
|
119
|
+
// markdown.ts's esc().
|
|
120
|
+
function escHtml(s: unknown): string {
|
|
121
|
+
return String(s ?? "").replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ } as Record<string, string>)[c]!);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface PushToHubOpts {
|
|
125
|
+
kind: "quantize" | "finetune" | "dataset";
|
|
126
|
+
job_id?: string;
|
|
127
|
+
source_path?: string;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Shared push-to-hub flow, rendered inline inside a done-step card.
|
|
132
|
+
* pushToHub(panelEl, { kind, job_id?, source_path? })
|
|
133
|
+
* kind: "quantize" | "finetune" | "dataset". Posts to /api/{kind}/push.
|
|
134
|
+
* Walks: ensure token -> repo_id + private -> POST -> success/error flash.
|
|
135
|
+
*/
|
|
136
|
+
export async function pushToHub(panel: HTMLElement, opts: PushToHubOpts): Promise<void> {
|
|
137
|
+
const { kind, job_id, source_path } = opts;
|
|
138
|
+
panel.innerHTML = '<div class="pushpanel"><div class="flash"><span class="shimmer">checking Hugging Face token…</span></div></div>';
|
|
139
|
+
const wrap = panel.firstChild as HTMLElement;
|
|
140
|
+
let hasToken = false;
|
|
141
|
+
try { const s = await api("/api/settings/hf-token"); hasToken = !!(s && s.ok && (s as { hasToken?: boolean }).hasToken); } catch { /* treat as no token */ }
|
|
142
|
+
|
|
143
|
+
const renderForm = () => {
|
|
144
|
+
wrap.innerHTML =
|
|
145
|
+
(!hasToken
|
|
146
|
+
? '<div class="field"><label>Hugging Face write token</label>' +
|
|
147
|
+
'<input type="password" class="p-token" placeholder="hf_…" autocomplete="off" spellcheck="false">' +
|
|
148
|
+
'<div class="hint">A <strong>write</strong> token from huggingface.co/settings/tokens. Stored locally at <code>~/.mlx-bun/hf.json</code>.</div></div>'
|
|
149
|
+
: "") +
|
|
150
|
+
'<div class="field"><label>Repository id</label>' +
|
|
151
|
+
'<input type="text" class="p-repo" placeholder="you/my-' + escHtml(kind === "dataset" ? "dataset" : "model") + '" autocomplete="off"></div>' +
|
|
152
|
+
'<div class="field"><label class="chk"><input type="checkbox" class="p-priv">Private repository</label></div>' +
|
|
153
|
+
'<div class="p-msg"></div>' +
|
|
154
|
+
'<div class="btnrow" style="margin-top:6px"><button class="btn primary sm p-go">' +
|
|
155
|
+
(hasToken ? "Push" : "Save token & push") + "</button></div>";
|
|
156
|
+
(wrap.querySelector(".p-go") as HTMLButtonElement).onclick = go;
|
|
157
|
+
const focusEl = wrap.querySelector(hasToken ? ".p-repo" : ".p-token") as HTMLElement | null;
|
|
158
|
+
if (focusEl) focusEl.focus();
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
async function go(): Promise<void> {
|
|
162
|
+
const msg = wrap.querySelector(".p-msg") as HTMLElement;
|
|
163
|
+
const repo = ((wrap.querySelector(".p-repo") as HTMLInputElement).value || "").trim();
|
|
164
|
+
const priv = (wrap.querySelector(".p-priv") as HTMLInputElement).checked;
|
|
165
|
+
if (!repo) { msg.innerHTML = '<div class="flash err">Enter a repository id (e.g. <code>you/my-model</code>).</div>'; return; }
|
|
166
|
+
const btn = wrap.querySelector(".p-go") as HTMLButtonElement; btn.disabled = true;
|
|
167
|
+
|
|
168
|
+
if (!hasToken) {
|
|
169
|
+
const token = ((wrap.querySelector(".p-token") as HTMLInputElement).value || "").trim();
|
|
170
|
+
if (!token) { msg.innerHTML = '<div class="flash err">Enter a write token first.</div>'; btn.disabled = false; return; }
|
|
171
|
+
const sv = await api("/api/settings/hf-token", { method: "POST", body: { token } }).catch((): ApiEnvelope => ({ ok: false, error: "request failed" }));
|
|
172
|
+
if (!sv.ok) { msg.innerHTML = '<div class="flash err">' + escHtml(sv.error || "could not save token") + "</div>"; btn.disabled = false; return; }
|
|
173
|
+
hasToken = true; refreshHfGear();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
msg.innerHTML = '<div class="flash"><span class="shimmer">pushing to ' + escHtml(repo) + "…</span></div>";
|
|
177
|
+
const body: Record<string, unknown> = { repo_id: repo, private: priv };
|
|
178
|
+
if (job_id != null) body.job_id = job_id;
|
|
179
|
+
if (source_path != null) body.source_path = source_path;
|
|
180
|
+
const d = await api("/api/" + kind + "/push", { method: "POST", body }).catch((): ApiEnvelope => ({ ok: false, error: "request failed" }));
|
|
181
|
+
btn.disabled = false;
|
|
182
|
+
if (!d.ok) { msg.innerHTML = '<div class="flash err">' + escHtml(d.error || "push failed") + "</div>"; return; }
|
|
183
|
+
const url = (d as { url?: string }).url || ("https://huggingface.co/" + repo);
|
|
184
|
+
wrap.innerHTML = '<div class="flash ok">Pushed to <a href="' + escHtml(url) + '" target="_blank" rel="noopener" style="text-decoration:underline">' + escHtml(url) + "</a></div>";
|
|
185
|
+
toast("Pushed to Hugging Face", "ok");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
renderForm();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/* wire the nav gear + modal once at boot. The modal now also hosts the
|
|
192
|
+
* Agent tools section — see the block below;
|
|
193
|
+
* kept in this same init function since it's one modal, one open/close
|
|
194
|
+
* lifecycle, one focus trap. */
|
|
195
|
+
export function initHfSettings(): void {
|
|
196
|
+
$("nav-hf").onclick = openHfSettings;
|
|
197
|
+
$("hf-close").onclick = closeHfSettings;
|
|
198
|
+
$("hf-save").onclick = saveHfToken;
|
|
199
|
+
$("hf-overlay").addEventListener("click", (e) => { if (e.target === $("hf-overlay")) closeHfSettings(); });
|
|
200
|
+
$("hf-token-input").addEventListener("keydown", (e) => { if ((e as KeyboardEvent).key === "Enter") saveHfToken(); });
|
|
201
|
+
// Escape is handled globally by the shell's overlay sweep (one
|
|
202
|
+
// Escape mechanism for every popover/overlay, not a bespoke one per modal).
|
|
203
|
+
hfOverlayTrap = trapFocus($("hf-overlay"), () => $("hf-overlay").classList.contains("open"));
|
|
204
|
+
refreshHfGear();
|
|
205
|
+
initCodingToolsToggle();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* ════════════════════════════════════════════════════════════════════
|
|
209
|
+
AGENT TOOLS SETTINGS — the codingTools
|
|
210
|
+
opt-in toggle + the durable "always allow" list. State of record for
|
|
211
|
+
BOTH is server-side (the toggle's enforcement, and the tool-approvals
|
|
212
|
+
config file); this module only reflects what the server last reported
|
|
213
|
+
(coding_tools/tool_approvals ServerMessages, relayed here by chat.ts —
|
|
214
|
+
shell.ts owns no WebSocket) plus the localStorage mirror that lets the
|
|
215
|
+
checkbox restore its last-requested state before the first `ready`
|
|
216
|
+
frame arrives.
|
|
217
|
+
════════════════════════════════════════════════════════════════════ */
|
|
218
|
+
const CODING_TOOLS_KEY = "mlxbun.codingTools";
|
|
219
|
+
|
|
220
|
+
/** Last requested state (this browser). The server is the actual source of
|
|
221
|
+
* truth for enforcement — this is only UI restoration so the checkbox
|
|
222
|
+
* doesn't flash unchecked while waiting on the first `ready`/`coding_tools`
|
|
223
|
+
* frame after a reload. */
|
|
224
|
+
export function storedCodingToolsPreference(): boolean {
|
|
225
|
+
return localStorage.getItem(CODING_TOOLS_KEY) === "1";
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function setStoredCodingToolsPreference(on: boolean): void {
|
|
229
|
+
localStorage.setItem(CODING_TOOLS_KEY, on ? "1" : "0");
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Reflect the server's coding_tools frame {active, pending} into the
|
|
233
|
+
* checkbox + the honest status note. `active` is what THIS session's tool
|
|
234
|
+
* surface actually contains; `pending` is the last request, which only
|
|
235
|
+
* takes effect on the next new/opened/forked chat — the note says so
|
|
236
|
+
* explicitly rather than implying the toggle is live immediately. */
|
|
237
|
+
export function renderCodingToolsState(active: boolean, pending: boolean): void {
|
|
238
|
+
const cb = $("settings-coding-tools") as HTMLInputElement | null;
|
|
239
|
+
if (cb) cb.checked = pending;
|
|
240
|
+
const note = $("settings-coding-tools-note");
|
|
241
|
+
if (!note) return;
|
|
242
|
+
if (pending && !active) {
|
|
243
|
+
note.style.display = "";
|
|
244
|
+
note.textContent = "Will apply starting with your next new chat (this chat keeps its current tools).";
|
|
245
|
+
} else if (!pending && active) {
|
|
246
|
+
note.style.display = "";
|
|
247
|
+
note.textContent = "Turning this off won't remove tools from the CURRENT chat — start a new chat to fully disable.";
|
|
248
|
+
} else {
|
|
249
|
+
note.style.display = "none";
|
|
250
|
+
note.textContent = "";
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Reflect the durable always-allow set (tool_approvals frame) into the
|
|
255
|
+
* settings list, each row with a "forget" button. `onForget` is supplied
|
|
256
|
+
* by chat.ts (it owns the WebSocket) — this module never sends frames
|
|
257
|
+
* itself, matching pushToHub/refreshHfGear's api()-only pattern above. */
|
|
258
|
+
export function renderToolApprovals(tools: readonly string[], onForget: (tool: string) => void): void {
|
|
259
|
+
const list = $("settings-approvals-list");
|
|
260
|
+
if (!list) return;
|
|
261
|
+
if (tools.length === 0) {
|
|
262
|
+
list.innerHTML = '<div class="settings-approvals-empty">No tools are set to always-allow yet.</div>';
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
list.innerHTML = tools.map((t) =>
|
|
266
|
+
'<div class="settings-approval-row"><span class="satool">' + escHtml(t) +
|
|
267
|
+
'</span><button class="saforget" data-tool="' + escHtml(t) + '">Forget</button></div>'
|
|
268
|
+
).join("");
|
|
269
|
+
list.querySelectorAll<HTMLButtonElement>(".saforget").forEach((btn) => {
|
|
270
|
+
btn.onclick = () => onForget(btn.dataset.tool || "");
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Wire the checkbox; the actual set_coding_tools WS send is the chat panel's (`setCodingTools`), since this file owns no
|
|
275
|
+
* WebSocket. Until the panel exists, localStorage still records the preference (the panel re-sends it on every `ready`
|
|
276
|
+
* frame), so nothing is lost. */
|
|
277
|
+
function initCodingToolsToggle(): void {
|
|
278
|
+
const cb = $("settings-coding-tools") as HTMLInputElement | null;
|
|
279
|
+
if (!cb) return;
|
|
280
|
+
cb.checked = storedCodingToolsPreference();
|
|
281
|
+
cb.onchange = () => {
|
|
282
|
+
const on = cb.checked;
|
|
283
|
+
setStoredCodingToolsPreference(on);
|
|
284
|
+
chatPanel()?.setCodingTools(on);
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* ════════════════════════════════════════════════════════════════════
|
|
289
|
+
MOBILE DRAWER — the chat's recent-chats sidebar is a slide-over on narrow viewports. The sidebar, its backdrop and
|
|
290
|
+
its focus trap belong to the chat panel; this is the hamburger in the nav, which is app chrome (shown on the chat
|
|
291
|
+
route only, see the shell's onRoute).
|
|
292
|
+
════════════════════════════════════════════════════════════════════ */
|
|
293
|
+
export function initDrawer(): void {
|
|
294
|
+
$("chat-hamburger").onclick = () => chatPanel()?.toggleDrawer();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** A registered close callback for the memory overlay (memory-panel.ts's initMemoryPanel()) — avoids a circular import (shell.ts
|
|
298
|
+
* is imported BY memory-panel.ts for $/trapFocus/etc., so shell.ts can't
|
|
299
|
+
* import memory-panel.ts's closeMemPanel back). */
|
|
300
|
+
export let memPanelClose: (() => void) | null = null;
|
|
301
|
+
export function setMemPanelClose(fn: (() => void) | null): void { memPanelClose = fn; }
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
/** The overlays Escape closes, in priority order (the shell adds its shortcut sheet first): each is open when its
|
|
305
|
+
* element carries `.open` and its page registered a close callback. */
|
|
306
|
+
export function registerOverlays(palette: Palette): void {
|
|
307
|
+
const byId = (id: string, close: () => (() => void) | null): Overlay => ({
|
|
308
|
+
isOpen: () => { const e = document.getElementById(id); return !!e && e.classList.contains("open") && close() !== null; },
|
|
309
|
+
close: () => close()!(),
|
|
310
|
+
});
|
|
311
|
+
const add = (overlay: Overlay) => shell.overlays.add(overlay);
|
|
312
|
+
add({ isOpen: () => $("hf-overlay").classList.contains("open"), close: closeHfSettings });
|
|
313
|
+
// The chat panel's popovers (sampling, system prompt, adapter table) close themselves.
|
|
314
|
+
add({ isOpen: () => !!chatPanel()?.popoverOpen(), close: () => { chatPanel()?.closePopover(); } });
|
|
315
|
+
add(byId("mem-overlay", () => memPanelClose));
|
|
316
|
+
add(palette);
|
|
317
|
+
add({ isOpen: () => !!chatPanel()?.drawerOpen(), close: () => chatPanel()?.closeDrawer() });
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** The chat's keyboard bindings, consulted after the shell's own. */
|
|
321
|
+
export function appKeys(e: KeyboardEvent): boolean {
|
|
322
|
+
const mod = e.metaKey || e.ctrlKey;
|
|
323
|
+
// Cmd/Ctrl+Shift+O: new chat. (Ctrl+Shift+O is free in every major browser; Cmd+Shift+O has no macOS Safari/Chrome reservation either.)
|
|
324
|
+
if (mod && e.shiftKey && (e.key === "O" || e.key === "o")) {
|
|
325
|
+
if (currentRoute() !== "chat") return true; // no-op off the chat route
|
|
326
|
+
e.preventDefault();
|
|
327
|
+
chatPanel()?.newChat();
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
// Cmd/Ctrl+Shift+C: copy last response.
|
|
331
|
+
if (mod && e.shiftKey && (e.key === "C" || e.key === "c")) {
|
|
332
|
+
if (currentRoute() !== "chat") return true;
|
|
333
|
+
e.preventDefault();
|
|
334
|
+
chatPanel()?.copyLastResponse();
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
// Shift+Escape: focus the composer.
|
|
338
|
+
if (e.shiftKey && e.key === "Escape") {
|
|
339
|
+
if (currentRoute() !== "chat") return true;
|
|
340
|
+
e.preventDefault();
|
|
341
|
+
chatPanel()?.focusComposer();
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* ── Routes tab feature-detection ──
|
|
348
|
+
/dag reads a repo-relative doc that is absent from compiled binaries and npm installs. Probe once at boot with a
|
|
349
|
+
HEAD request; on 404 hide the Routes tab entirely (rather than leaving a dead link that iframes a raw 404) and, if
|
|
350
|
+
the user is already sitting on #/routes, swap in a graceful in-app note instead of the broken iframe. */
|
|
351
|
+
export async function initRoutesProbe(): Promise<void> {
|
|
352
|
+
let ok = true;
|
|
353
|
+
try {
|
|
354
|
+
const r = await fetch("/dag", { method: "HEAD" });
|
|
355
|
+
ok = r.ok;
|
|
356
|
+
} catch { ok = false; }
|
|
357
|
+
if (ok) return;
|
|
358
|
+
shell.markUnavailable("routes");
|
|
359
|
+
const section = $("s-routes");
|
|
360
|
+
if (section) {
|
|
361
|
+
section.innerHTML =
|
|
362
|
+
'<div class="wrap" style="max-width:640px;margin:60px auto;text-align:center;color:var(--dim)">' +
|
|
363
|
+
"<h2>Routes map unavailable</h2>" +
|
|
364
|
+
"<p>The training/inference route diagram ships alongside the repo checkout " +
|
|
365
|
+
"and isn't bundled into this build.</p></div>";
|
|
366
|
+
}
|
|
367
|
+
// If a deep link landed here directly, bounce to chat rather than sit on an orphaned nav state with no visible tab pointing at it.
|
|
368
|
+
if (currentRoute() === "routes") location.replace("#/chat");
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
/* ════════════════════════════════════════════════════════════════════
|
|
373
|
+
GLOBAL CONNECTION PILL + MODEL ID (polled lightly, always on)
|
|
374
|
+
════════════════════════════════════════════════════════════════════ */
|
|
375
|
+
export let activeModelId: string | null = null;
|
|
376
|
+
|
|
377
|
+
export function setConn(state: string, text: string): void {
|
|
378
|
+
const p = $("nav-conn");
|
|
379
|
+
p.className = "pill " + (state || "");
|
|
380
|
+
$("nav-conn-text").textContent = text;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
let defaultHelloSub: string | null = null;
|
|
384
|
+
|
|
385
|
+
export async function pollIdentity(): Promise<void> {
|
|
386
|
+
try {
|
|
387
|
+
const [models, dl] = await Promise.all([
|
|
388
|
+
fetch("/v1/models").then((r) => r.json()),
|
|
389
|
+
fetch("/downloads").then((r) => r.json()).catch(() => ({ downloads: [] })),
|
|
390
|
+
]);
|
|
391
|
+
// The server marks the current model; a server that predates residency lists the served one first.
|
|
392
|
+
const listed: { id: string; current?: boolean }[] = models.data || [];
|
|
393
|
+
const served = listed.find((m) => m.current) || listed[0];
|
|
394
|
+
const next = served ? served.id : null;
|
|
395
|
+
const switched = activeModelId !== null && next !== null && next !== activeModelId;
|
|
396
|
+
activeModelId = next;
|
|
397
|
+
$("nav-model").textContent = activeModelId || "no model";
|
|
398
|
+
// Chat reads the model's capabilities when it connects: an idle chat reconnects to pick them up.
|
|
399
|
+
if (switched) window.dispatchEvent(new CustomEvent("mlx-model-changed", { detail: next }));
|
|
400
|
+
setConn("ok", "live · localhost");
|
|
401
|
+
updateDownloadIndicator((dl && dl.downloads) || []);
|
|
402
|
+
} catch {
|
|
403
|
+
$("nav-model").textContent = "server unreachable";
|
|
404
|
+
setConn("bad", "unreachable — retrying");
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/** The nav's model label opens the Models panel (a page the shell mounts from the models module); a switch or an adapter change made
|
|
409
|
+
* there re-reads the served model's identity at once instead of at the next poll. */
|
|
410
|
+
export function initModelLink(): void {
|
|
411
|
+
$("nav-model").onclick = () => { location.hash = "#/models"; };
|
|
412
|
+
document.addEventListener("mlx-models-changed", () => { void pollIdentity(); });
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
interface DownloadInfo {
|
|
416
|
+
state: string;
|
|
417
|
+
repoId: string;
|
|
418
|
+
totalBytes?: number;
|
|
419
|
+
receivedBytes?: number;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/** Surface a background model download — the "bigger model arriving while you
|
|
423
|
+
* chat on the starter" case — as a live nav pill plus a download-aware
|
|
424
|
+
* greeting in the empty chat state. Hidden when nothing else is downloading. */
|
|
425
|
+
export function updateDownloadIndicator(downloads: DownloadInfo[]): void {
|
|
426
|
+
const sub = $("chat-hello-sub");
|
|
427
|
+
if (sub && defaultHelloSub === null) defaultHelloSub = sub.textContent;
|
|
428
|
+
const incoming = downloads.find((d) => d.state === "active" && d.repoId !== activeModelId);
|
|
429
|
+
const pill = $("nav-download");
|
|
430
|
+
if (incoming) {
|
|
431
|
+
const pct = incoming.totalBytes ? Math.floor(((incoming.receivedBytes || 0) / incoming.totalBytes) * 100) : 0;
|
|
432
|
+
const name = incoming.repoId.split("/").pop();
|
|
433
|
+
$("nav-download-text").textContent = "↓ " + name + " · " + pct + "%";
|
|
434
|
+
pill.style.display = "";
|
|
435
|
+
if (sub) sub.textContent = "You're on a small, fast starter model so you can chat right now — a more capable one (" + name + ") is downloading and takes over next launch. Ask me anything, or about mlx-bun itself.";
|
|
436
|
+
} else {
|
|
437
|
+
pill.style.display = "none";
|
|
438
|
+
if (sub && defaultHelloSub !== null) sub.textContent = defaultHelloSub;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** Presentation the embedding app supplies to the job panels that consume it. */
|
|
443
|
+
export function connectPanels(panels: readonly ShellPanel[]): ShellPanel[] {
|
|
444
|
+
return panels.map(panel => {
|
|
445
|
+
if (!["mlx-quantize-panel", "mlx-train-panel", "mlx-datasets-panel"].includes(panel.tag)) return panel;
|
|
446
|
+
return { ...panel, connection: { ...panel.connection, ui: {
|
|
447
|
+
notify: toast,
|
|
448
|
+
publish: pushToHub,
|
|
449
|
+
...(panel.tag === "mlx-datasets-panel" ? { modelId: () => activeModelId || undefined } : { catalogChanged: () => {
|
|
450
|
+
const status = controllers.status;
|
|
451
|
+
if (status?.refreshLibrary) (status.refreshLibrary as () => void)();
|
|
452
|
+
chatPanel()?.refreshAdapters();
|
|
453
|
+
} }),
|
|
454
|
+
} } };
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/** Keep the app's existing navigation order while its pages move into installed panels. */
|
|
459
|
+
export function mountPanels(panels: readonly ShellPanel[]): void {
|
|
460
|
+
shell.mountPanels(connectPanels(panels));
|
|
461
|
+
const order = ["chat", "quantize", "finetune", "dataset", "status", "routes", "benchmarks", "metrics", "models"];
|
|
462
|
+
const tabs = $("tabs");
|
|
463
|
+
[...tabs.querySelectorAll<HTMLElement>(".tab")].sort((a, b) => {
|
|
464
|
+
const position = (tab: HTMLElement) => { const index = order.indexOf(tab.dataset.tab || ""); return index < 0 ? order.length : index; };
|
|
465
|
+
return position(a) - position(b);
|
|
466
|
+
}).forEach(tab => tabs.append(tab));
|
|
467
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
// GENERATED-ADJACENT source module — part of the src/web/
|
|
2
|
-
//
|
|
1
|
+
// GENERATED-ADJACENT source module — part of the apps/mlx-bun/src/web/browser/*
|
|
2
|
+
// split. Built into apps/mlx-bun/dist/web/app.js by
|
|
3
|
+
// scripts/build-web.ts.
|
|
3
4
|
//
|
|
4
5
|
// STATUS CONTROLLER — ported dashboard (poll /stats + /v1/models + /fit +
|
|
5
6
|
// /library + /downloads). Behavior-identical port of the original
|
|
@@ -46,7 +47,7 @@ interface SkuRow {
|
|
|
46
47
|
export function createStatusController() {
|
|
47
48
|
let timer: ReturnType<typeof setInterval> | null = null, libTimer: ReturnType<typeof setInterval> | null = null, fitLoaded = false;
|
|
48
49
|
const dlRates: Record<string, { bytes: number; t: number }> = {};
|
|
49
|
-
// Library staleness (web-ui-pass-plan.md #3): /library is server-cached for
|
|
50
|
+
// Library staleness (`02d723a:docs/archive/planning/web-ui-pass-plan.md` #3): /library is server-cached for
|
|
50
51
|
// 30s, but the client used to fetch it exactly once per page load
|
|
51
52
|
// (gated on `fitLoaded`) — a quantize job finishing, a fresh download
|
|
52
53
|
// landing, or a manual drop into the HF cache never showed up without a
|
|
@@ -59,7 +60,8 @@ export function createStatusController() {
|
|
|
59
60
|
fetch("/stats").then((r) => r.json()),
|
|
60
61
|
fetch("/v1/models").then((r) => r.json()),
|
|
61
62
|
]);
|
|
62
|
-
const
|
|
63
|
+
const listed: { id: string; context_window?: number; current?: boolean }[] = models.data || [];
|
|
64
|
+
const m = listed.find((x) => x.current) || listed[0];
|
|
63
65
|
$("st-model-id").textContent = (m && m.id) || "—";
|
|
64
66
|
const a = stats.admission || {};
|
|
65
67
|
$("st-model-meta").textContent = num(m && m.context_window) + " token window · weights " + gb(a.weights_bytes);
|
|
@@ -90,25 +92,25 @@ export function createStatusController() {
|
|
|
90
92
|
.map(([k, v]) => '<div class="kv"><b>' + esc(k) + ' layers</b><span class="num">' + esc(v) + "</span></div>").join("") +
|
|
91
93
|
(att ? '<div class="kv"><b>attention</b><span class="num">' + esc(att.global) + " global · " + esc(att.sliding_window) + " sliding</span></div>" : "");
|
|
92
94
|
|
|
93
|
-
const
|
|
94
|
-
const expert =
|
|
95
|
-
const expertCard = $("st-
|
|
96
|
-
expertCard.style.display =
|
|
97
|
-
if (
|
|
95
|
+
const runtime = stats.runtime;
|
|
96
|
+
const expert = runtime && runtime.expert_runtime;
|
|
97
|
+
const expertCard = $("st-expert-card");
|
|
98
|
+
expertCard.style.display = runtime ? "" : "none";
|
|
99
|
+
if (runtime) {
|
|
98
100
|
const rate = (d: { hits?: number; misses?: number } | null | undefined): string => {
|
|
99
101
|
const total = (d?.hits || 0) + (d?.misses || 0);
|
|
100
102
|
return total ? (100 * (d?.hits || 0) / total).toFixed(1) + "%" : "—";
|
|
101
103
|
};
|
|
102
104
|
const turn = expert && expert.last_turn;
|
|
103
|
-
$("st-
|
|
104
|
-
$("st-
|
|
105
|
+
$("st-expert-main-hit").textContent = rate(turn?.main?.demand);
|
|
106
|
+
$("st-expert-main-read").textContent = turn?.main?.demand
|
|
105
107
|
? gb(turn.main.demand.readBytes) : "—";
|
|
106
|
-
$("st-
|
|
107
|
-
$("st-
|
|
108
|
+
$("st-expert-mtp-hit").textContent = rate(turn?.mtp?.demand);
|
|
109
|
+
$("st-expert-mtp-read").textContent = turn?.mtp?.demand
|
|
108
110
|
? gb(turn.mtp.demand.readBytes) : "—";
|
|
109
111
|
const main = expert?.main_residency;
|
|
110
112
|
const mtp = expert?.mtp_residency;
|
|
111
|
-
$("st-
|
|
113
|
+
$("st-expert-residency").textContent = main
|
|
112
114
|
? "resident slots main " + num(main.resident + main.pinned) +
|
|
113
115
|
" / " + num(main.resident + main.pinned + main.working) +
|
|
114
116
|
(mtp ? " · MTP " + num(mtp.resident + mtp.pinned) +
|
|
@@ -176,7 +178,7 @@ export function createStatusController() {
|
|
|
176
178
|
else if (!m.supported) status = '<span style="color:var(--dimmer)">unsupported (' + esc(m.model_type) + ")</span>";
|
|
177
179
|
else if (a && a.fits) status = '<span style="color:var(--green);font-weight:600">fits</span>';
|
|
178
180
|
else status = '<span style="color:var(--red);font-weight:600">too big</span>';
|
|
179
|
-
// web-ui-pass-plan.md #20: max_safe_context is meaningful whenever
|
|
181
|
+
// `02d723a:docs/archive/planning/web-ui-pass-plan.md` #20: max_safe_context is meaningful whenever
|
|
180
182
|
// it's > 0, even when `fits` is false at the library's default 8192
|
|
181
183
|
// probe context — e.g. a model that doesn't fit at 8192 tokens but
|
|
182
184
|
// does fit at a smaller context still gets a real number here rather
|
|
@@ -205,12 +207,10 @@ export function createStatusController() {
|
|
|
205
207
|
machine?: { ram_bytes?: number; bandwidth_gbs?: number; chip?: string };
|
|
206
208
|
sku_matrix_ctx?: number;
|
|
207
209
|
sku_matrix?: SkuRow[];
|
|
208
|
-
|
|
210
|
+
plan?: {
|
|
209
211
|
artifact_disk_bytes?: number | null;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
direct_oracle_warm_decode_tps?: number;
|
|
213
|
-
aspirational_decode_tps?: number;
|
|
212
|
+
streamed_weights?: Record<string, number>;
|
|
213
|
+
max_generation_tokens?: number | null;
|
|
214
214
|
};
|
|
215
215
|
}
|
|
216
216
|
let f: FitResponse;
|
|
@@ -221,31 +221,27 @@ export function createStatusController() {
|
|
|
221
221
|
if (f.measured_decode_tps) {
|
|
222
222
|
$("st-tps").textContent = tps(f.measured_decode_tps);
|
|
223
223
|
$("st-tps").closest(".card")!.querySelector("h3")!.textContent = "Decode · measured";
|
|
224
|
-
$("st-tps-cap").textContent =
|
|
225
|
-
|
|
226
|
-
tps(f.glm52.direct_oracle_warm_decode_tps || 0) +
|
|
227
|
-
" · aspiration " + tps(f.glm52.aspirational_decode_tps || 0)
|
|
228
|
-
: "mlx-bun benchmark on this machine · predicted " +
|
|
229
|
-
tps(f.typical_decode_tps || 0) + " at " + num(f.typical_context_tokens) + " ctx";
|
|
224
|
+
$("st-tps-cap").textContent = "mlx-bun benchmark on this machine · predicted " +
|
|
225
|
+
tps(f.typical_decode_tps || 0) + " at " + num(f.typical_context_tokens) + " ctx";
|
|
230
226
|
} else if (f.typical_decode_tps) {
|
|
231
227
|
$("st-tps").textContent = f.typical_decode_tps.toFixed(1);
|
|
232
228
|
$("st-tps-cap").textContent = "at " + num(f.typical_context_tokens) + " context · " + (r.predicted_decode_tps || 0).toFixed(1) + " tok/s at the " + num(f.context_tokens) + " max (full-KV reads)";
|
|
233
229
|
} else {
|
|
234
|
-
$("st-tps").textContent =
|
|
230
|
+
$("st-tps").textContent = r.predicted_decode_tps == null ? "—" : r.predicted_decode_tps.toFixed(1);
|
|
235
231
|
}
|
|
236
232
|
$("st-m-ram").textContent = gb(f.machine && f.machine.ram_bytes);
|
|
237
233
|
$("st-m-bw").textContent = (f.machine && f.machine.bandwidth_gbs || "—") + " GB/s";
|
|
238
234
|
$("st-m-fits").innerHTML = r.fits ? '<span style="color:var(--green);font-weight:700">FITS</span>' : '<span style="color:var(--red);font-weight:700">DOES NOT FIT</span>';
|
|
239
235
|
$("st-fit-ctx").textContent = num(f.context_tokens);
|
|
240
|
-
document.querySelectorAll<HTMLElement>("[data-
|
|
241
|
-
row.style.display = f.
|
|
236
|
+
document.querySelectorAll<HTMLElement>("[data-plan-fit]").forEach((row) => {
|
|
237
|
+
row.style.display = f.plan ? "" : "none";
|
|
242
238
|
});
|
|
243
|
-
$("st-f-weights-label").textContent = f.
|
|
244
|
-
$("st-f-transient-label").textContent = f.
|
|
245
|
-
$("st-f-artifact").textContent = f.
|
|
246
|
-
? gb(f.
|
|
247
|
-
$("st-f-
|
|
248
|
-
|
|
239
|
+
$("st-f-weights-label").textContent = f.plan ? "resident weights" : "weights";
|
|
240
|
+
$("st-f-transient-label").textContent = f.plan ? "other reserves" : "transient";
|
|
241
|
+
$("st-f-artifact").textContent = f.plan?.artifact_disk_bytes
|
|
242
|
+
? gb(f.plan.artifact_disk_bytes) : "registry unavailable";
|
|
243
|
+
$("st-f-streamed").innerHTML = Object.entries(f.plan?.streamed_weights || {})
|
|
244
|
+
.map(([label, bytes]) => '<div class="kv"><b>' + esc(label) + '</b><span class="num">' + gb(bytes) + "</span></div>").join("");
|
|
249
245
|
$("st-f-weights").textContent = gb(r.weights_bytes);
|
|
250
246
|
$("st-f-kv").textContent = gb(r.kv_bytes);
|
|
251
247
|
$("st-f-transient").textContent = gb(r.transient_bytes);
|
|
@@ -293,7 +289,7 @@ export function createStatusController() {
|
|
|
293
289
|
// Exposed so a quantize job's `done` event (this same controller's own
|
|
294
290
|
// quantize flow, see controllers.quantize below) can force an immediate
|
|
295
291
|
// refresh instead of waiting up to 15s — the server invalidates its
|
|
296
|
-
// /library cache the moment the job completes (
|
|
292
|
+
// /library cache the moment the job completes (apps/mlx-bun/src/cli/serve-state.ts onComplete),
|
|
297
293
|
// so an immediate re-fetch is guaranteed fresh, not a race.
|
|
298
294
|
refreshLibrary: loadLibrary,
|
|
299
295
|
};
|