mlx-bun 0.0.13 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -578
- package/bin/mlx-bun.mjs +1 -1
- package/docs/README.md +91 -0
- package/docs/{design → archive}/hlg-sampling.md +3 -3
- package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
- package/docs/{design → archive/investigations}/colibri-glm52-port.md +1 -1
- package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
- package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
- package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
- package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
- package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
- package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
- package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
- package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
- package/docs/{planning → archive/planning}/chunk-task-roadmap.md +1 -1
- package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +4 -4
- package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +1 -1
- package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
- package/docs/archive/planning/release-notes-v0.2.0.md +49 -0
- package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
- package/docs/design/batching.md +569 -0
- package/docs/design/decode-speed-program.md +3178 -169
- package/docs/design/dreaming-nightly-pipeline.md +675 -282
- package/docs/design/generic-model-support.md +579 -334
- package/docs/design/kv-cache.md +680 -0
- package/docs/design/orpo-training.md +673 -1239
- package/docs/design/speculative-decoding.md +1627 -0
- package/docs/design/turboquant.md +2102 -0
- package/docs/design/unified-engine-frontier-plan.md +1831 -727
- package/docs/design/web-chat-redesign.md +666 -1083
- package/docs/planning/PRODUCT_ROADMAP.md +34 -1
- package/docs/planning/release-notes-v0.3.0.md +35 -0
- package/docs/planning/video-series.md +421 -0
- package/docs/reference/benchmarks.md +1162 -0
- package/docs/reference/cli.md +395 -149
- package/docs/reference/distribution.md +321 -181
- package/docs/reference/environment.md +348 -0
- package/docs/reference/glossary.md +39 -0
- package/docs/reference/library-api.md +580 -142
- package/docs/reference/memory.md +227 -64
- package/docs/reference/models.md +137 -6
- package/docs/reference/server-api.md +938 -422
- package/docs/reference/server-config.md +652 -320
- package/docs/reference/training.md +393 -254
- package/docs/reference/troubleshooting.md +166 -0
- package/package.json +10 -5
- package/src/admission-plan.ts +18 -0
- package/src/anthropic.ts +92 -3
- package/src/audio/decode.ts +2 -2
- package/src/audio/features.ts +2 -2
- package/src/backends/mlx/autoregressive.ts +108 -0
- package/src/backends/mlx/batch-group.ts +1646 -0
- package/src/backends/mlx/diffusion.ts +39 -0
- package/src/backends/mlx/draft-target.ts +47 -0
- package/src/backends/mlx/evaluation.ts +105 -0
- package/src/backends/mlx/fill-append.ts +45 -0
- package/src/backends/mlx/gateway-binding.ts +71 -0
- package/src/backends/mlx/graph.ts +38 -0
- package/src/backends/mlx/memory-client.ts +189 -0
- package/src/backends/mlx/memory-guard.ts +40 -0
- package/src/backends/mlx/methods.ts +90 -0
- package/src/backends/mlx/model-prompt.ts +164 -0
- package/src/backends/mlx/model-serving.ts +79 -0
- package/src/backends/mlx/prefill.ts +33 -0
- package/src/backends/mlx/request-policy.ts +20 -0
- package/src/backends/mlx/rollback.ts +51 -0
- package/src/backends/mlx/serial-executor.ts +273 -0
- package/src/backends/mlx/speculative.ts +114 -0
- package/src/backends/mlx/state-views.ts +26 -0
- package/src/backends/mlx/text-engine.ts +73 -0
- package/src/cli.ts +189 -61
- package/src/client.ts +66 -0
- package/src/config.ts +21 -4
- package/src/contracts/completion.ts +16 -0
- package/src/contracts/execution.ts +49 -0
- package/src/contracts/generation.ts +103 -0
- package/src/contracts/host.ts +7 -0
- package/src/contracts/jobs.ts +66 -0
- package/src/contracts/pi-provider.ts +30 -0
- package/src/contracts/pi.ts +259 -0
- package/src/contracts/resources.ts +18 -0
- package/src/contracts/scheduling.ts +27 -0
- package/src/contracts/tsconfig.json +14 -0
- package/src/diffusion/diffusion-generate.ts +218 -153
- package/src/embed.ts +1 -1
- package/src/engine/admission.ts +59 -0
- package/src/engine/cancellation.ts +38 -0
- package/src/engine/engine.ts +56 -0
- package/src/engine/execution-coordinator.ts +70 -0
- package/src/engine/execution-plan.ts +51 -0
- package/src/engine/resources.ts +42 -0
- package/src/engine/scheduler.ts +67 -0
- package/src/engine/session.ts +247 -0
- package/src/eval/README.md +44 -1
- package/src/eval/kl.ts +263 -23
- package/src/eval/reference-logits.ts +207 -0
- package/src/eval/runner.ts +10 -79
- package/src/eval/tasks/bfcl.ts +2 -1
- package/src/eval/tasks/gsm8k.ts +2 -1
- package/src/eval/tasks/hashhop.ts +2 -1
- package/src/eval/tasks/humaneval.ts +5 -4
- package/src/eval/tasks/ifeval.ts +2 -1
- package/src/eval/tasks/mmlu.ts +2 -1
- package/src/expert-io.ts +3 -1
- package/src/expert-offload.ts +3 -1
- package/src/fill/echo-index.ts +188 -0
- package/src/fill/fill-session.ts +452 -0
- package/src/fill/proposal.ts +68 -0
- package/src/fill/schema-rows.ts +506 -0
- package/src/fill/tool-boundary.ts +103 -0
- package/src/fit.ts +24 -43
- package/src/generate.ts +740 -337
- package/src/grammar.ts +14 -8
- package/src/harness-pi.ts +15 -34
- package/src/hub-rest.ts +4 -4
- package/src/index.ts +27 -0
- package/src/inference/denoising.ts +17 -0
- package/src/inference/graph.ts +33 -0
- package/src/inference/prefill.ts +39 -0
- package/src/inference/rollback.ts +7 -0
- package/src/jobs/db.ts +4 -0
- package/src/jobs/index.ts +2 -0
- package/src/jobs/job-entry.ts +15 -14
- package/src/jobs/runner.ts +98 -13
- package/src/jobs/task-client.ts +19 -0
- package/src/jobs/types.ts +2 -58
- package/src/kv-scheme.ts +199 -0
- package/src/kv-store.ts +459 -234
- package/src/lab/README.md +18 -0
- package/src/{assets → lab/curve}/curve-designer.html +2 -2
- package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
- package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +7 -5
- package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
- package/src/library.ts +40 -0
- package/src/lora.ts +18 -0
- package/src/media-fetch.ts +20 -4
- package/src/memory/article.ts +1 -1
- package/src/memory/chunk.ts +1 -1
- package/src/memory/model.ts +32 -170
- package/src/memory/prompts.ts +1 -1
- package/src/memory/rest.ts +1 -1
- package/src/memory/schedule.ts +1 -1
- package/src/memory/stages.ts +4 -1
- package/src/memory/vault.ts +3 -4
- package/src/mlx/array.ts +9 -10
- package/src/mlx/compile.ts +12 -2
- package/src/mlx/ffi.ts +66 -22
- package/src/mlx/materialize.ts +23 -0
- package/src/mlx/metal-kernel.ts +10 -11
- package/src/mlx/ops.ts +64 -19
- package/src/mlx/quantized-rows.ts +36 -0
- package/src/mlx/token-bitmask.ts +52 -0
- package/src/mlx/turboquant-kv-decode.ts +82 -0
- package/src/mlx/turboquant-kv-inverse.ts +122 -0
- package/src/mlx/turboquant-ops.ts +33 -3
- package/src/mlx/turboquant-tables.ts +2 -2
- package/src/model/batched-mask.ts +9 -3
- package/src/model/batched-quant.ts +2 -2
- package/src/model/batched-rotating-quant.ts +45 -99
- package/src/model/batched-rotating-state.ts +73 -0
- package/src/model/batched-rotating.ts +57 -106
- package/src/model/batched-row-storage.ts +127 -0
- package/src/model/compiled-decode.ts +4 -3
- package/src/model/diffusion-gemma.ts +8 -8
- package/src/model/factory.ts +87 -49
- package/src/model/fingerprint.ts +1 -1
- package/src/model/flash-attention.ts +3 -3
- package/src/model/gemma4-base.ts +187 -17
- package/src/model/gemma4.ts +6 -6
- package/src/model/generated/gemma4-12b.ts +52 -148
- package/src/model/generated/gemma4-26b.ts +34 -94
- package/src/model/generated/gemma4-e4b.ts +28 -76
- package/src/model/glm52-cache.ts +19 -9
- package/src/model/glm52-dsa.ts +13 -9
- package/src/model/glm52-memory.ts +28 -1
- package/src/model/implementation.ts +69 -0
- package/src/model/minicpm5.ts +7 -8
- package/src/model/profile.ts +443 -0
- package/src/model/qwen-append.ts +12 -0
- package/src/model/qwen-conv.ts +52 -0
- package/src/model/qwen3-delta.ts +98 -2
- package/src/model/qwen3-mrope.ts +252 -0
- package/src/model/qwen3_5-checkpoint.ts +164 -0
- package/src/model/qwen3_5.ts +336 -60
- package/src/model/support.ts +1 -1
- package/src/model/trellis-balanced-scatter.ts +51 -0
- package/src/model/trellis-linear.ts +672 -0
- package/src/model/trellis-shared-m.ts +151 -0
- package/src/model/trellis-shared-scatter.ts +144 -0
- package/src/model/trellis-splitk-prefill.ts +158 -0
- package/src/model/trellis-tiled-prefill.ts +136 -0
- package/src/model/trellis-vector-expand.ts +62 -0
- package/src/model/trellis-wide-prefill.ts +94 -0
- package/src/model/universal/dense.ts +1 -1
- package/src/model/universal/modules.ts +8 -1
- package/src/native/frame_extract.swift +140 -0
- package/src/native-pack.ts +15 -7
- package/src/pi-provider.ts +6 -64
- package/src/pi-web.ts +14 -320
- package/src/prompt-cache.ts +97 -54
- package/src/quantize/allocator.ts +1 -1
- package/src/quantize/atomic-output.ts +38 -0
- package/src/quantize/calibration.ts +2 -1
- package/src/quantize/config-writer.ts +16 -3
- package/src/quantize/index.ts +28 -1
- package/src/quantize/job.ts +11 -0
- package/src/quantize/quantizer.ts +265 -100
- package/src/quantize/rotate.ts +603 -0
- package/src/quantize/safetensors-writer.ts +79 -1
- package/src/quantize/sensitivity.ts +41 -59
- package/src/quantize/trellis.ts +586 -0
- package/src/quantize/weight-transform.ts +292 -0
- package/src/responses.ts +130 -3
- package/src/runtime-config.ts +81 -0
- package/src/sampler.ts +276 -4
- package/src/serve/admin-routes.ts +184 -0
- package/src/serve/aux-routes.ts +132 -0
- package/src/serve/batch-scheduler.ts +8 -1558
- package/src/serve/chat-request.ts +391 -0
- package/src/serve/chat-stage.ts +195 -0
- package/src/serve/checkpoint-identity.ts +64 -0
- package/src/serve/completion-executor.ts +354 -0
- package/src/serve/completion-sink.ts +157 -0
- package/src/serve/discovery-routes.ts +204 -0
- package/src/serve/generation-gateway.ts +211 -243
- package/src/serve/http.ts +159 -0
- package/src/serve/inference-request.ts +79 -0
- package/src/serve/isolate.ts +297 -105
- package/src/serve/kv-budget.ts +14 -0
- package/src/serve/lab-routes.ts +341 -0
- package/src/serve/lane-registry.ts +2 -1
- package/src/serve/model-admin-routes.ts +155 -0
- package/src/serve/model-binding.ts +43 -0
- package/src/serve/model-host.ts +512 -0
- package/src/serve/openai-wire.ts +103 -0
- package/src/serve/parent-application.ts +56 -0
- package/src/serve/pipeline.ts +33 -0
- package/src/serve/preparation.ts +33 -0
- package/src/serve/prompt-response-trace.ts +147 -0
- package/src/serve/request-plan.ts +162 -0
- package/src/serve/request-prep.ts +346 -0
- package/src/serve/response-lease.ts +24 -0
- package/src/serve/responses-client.ts +69 -0
- package/src/serve/session-completion-engine.ts +110 -0
- package/src/serve/session-search.ts +1 -1
- package/src/serve/static-routes.ts +101 -0
- package/src/serve/text-completion-stage.ts +104 -0
- package/src/serve/token-streams.ts +519 -0
- package/src/server.ts +523 -3551
- package/src/spec/assistant-source.ts +10 -44
- package/src/spec/deepspec-source.ts +6 -6
- package/src/spec/dflash-source.ts +9 -8
- package/src/spec/dspark/ab-stats.ts +3 -3
- package/src/spec/dspark/calibration.ts +2 -2
- package/src/spec/dspark/deepspec-module.ts +2 -2
- package/src/spec/dspark/generate-dflash.ts +2 -2
- package/src/spec/dspark/generate.ts +2 -2
- package/src/spec/dspark/loader.ts +1 -1
- package/src/spec/dspark/module-dflash.ts +5 -4
- package/src/spec/dspark/module.ts +3 -3
- package/src/spec/dspark/quantize-drafter.ts +1 -1
- package/src/spec/generate.ts +1 -1
- package/src/spec/glm52-mtp-source.ts +9 -1
- package/src/spec/ngram-source.ts +1 -1
- package/src/spec/prefix-state.ts +45 -0
- package/src/spec/qwen-mtp-source.ts +528 -0
- package/src/spec/serve-loop.ts +179 -213
- package/src/spec/source.ts +42 -10
- package/src/spec/two-model.ts +1 -1
- package/src/ssd-cache.ts +95 -24
- package/src/ssd-durability.ts +207 -0
- package/src/tool-call.ts +51 -14
- package/src/train/flash-cce.ts +14 -13
- package/src/train/forward.ts +38 -1
- package/src/train/loss.ts +3 -2
- package/src/train/prefix-shared.ts +5 -1
- package/src/train/segmented.ts +9 -6
- package/src/train/trainer.ts +9 -8
- package/src/vision/preprocess.ts +1 -1
- package/src/vision/prompt.ts +48 -2
- package/src/vision/qwen3vl-preprocess.ts +409 -0
- package/src/vision/qwen3vl-prompt.ts +196 -0
- package/src/vision/qwen3vl-tower.ts +555 -0
- package/src/vision/video-frames.ts +148 -0
- package/src/web/app.html +1 -1
- package/src/web/app.js +15 -6
- package/src/web/src/adapters-panel.ts +3 -3
- package/src/web/src/assistant.ts +2 -36
- package/src/web/src/chat.ts +16 -9
- package/src/web/src/composer.ts +4 -4
- package/src/web/src/hub.ts +1 -1
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +1 -1
- package/src/web/src/model-picker.ts +1 -1
- package/src/web/src/palette.ts +1 -1
- package/src/web/src/protocol.ts +3 -39
- package/src/web/src/sessions.ts +1 -1
- package/src/web/src/ui-catalog.ts +4 -18
- package/src/web-assets.ts +47 -0
- package/src/weights.ts +134 -33
- package/docs/archive/mlx-bun-lab-report.html +0 -275
- package/docs/archive/wwdc-mlx-bun.html +0 -848
- package/docs/design/adapters-end-to-end.md +0 -205
- package/docs/design/batching-perf-path.md +0 -255
- package/docs/design/batching-v2-plan.md +0 -529
- package/docs/design/bucketing-stage.md +0 -197
- package/docs/design/compat-cli-surface-design.md +0 -230
- package/docs/design/docs-reorg-plan.md +0 -165
- package/docs/design/dspark-serving-program.md +0 -371
- package/docs/design/dspark-speculative-decoding.md +0 -268
- package/docs/design/grammar-spec-batching-integration.md +0 -301
- package/docs/design/memory-inference-path.md +0 -422
- package/docs/design/memory-synthesis.md +0 -287
- package/docs/design/memory-system.md +0 -237
- package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
- package/docs/design/omlx-adoption-map.md +0 -98
- package/docs/design/orpo-dynamic-lambda.md +0 -220
- package/docs/design/orpo-future-enhancements.md +0 -340
- package/docs/design/paged-kv-cache.md +0 -214
- package/docs/design/parallel-slots.md +0 -567
- package/docs/design/parity-tier-dag.md +0 -161
- package/docs/design/repo-cleanup-plan.md +0 -189
- package/docs/design/runtime-isolation.md +0 -263
- package/docs/design/segmented-backward-training.md +0 -543
- package/docs/design/spec-decode-larger-targets.md +0 -229
- package/docs/design/ssd-kv-cold-tier.md +0 -288
- package/docs/design/structured-output.md +0 -484
- package/docs/design/tauri-desktop-app.md +0 -127
- package/docs/design/the-dreaming-master-plan.md +0 -445
- package/docs/design/turboquant-kv.md +0 -235
- package/docs/design/w4a16-compute-precision-spike.md +0 -232
- package/docs/design/web-chat-beat-matrix.md +0 -315
- package/docs/design/write-pipeline-entity.md +0 -468
- package/docs/investigations/curve-runs/bisector-route.json +0 -98
- package/docs/investigations/curve-runs/bisector-trace.json +0 -1393
- package/docs/investigations/curve-runs/curve-terrain.json +0 -1179
- package/docs/investigations/curve-runs/curve-terrain.svg +0 -42
- package/docs/investigations/hlg-ab.html +0 -34
- package/docs/investigations/hlg-explorer.html +0 -238
- package/docs/investigations/hlg-figs/cliff.svg +0 -1
- package/docs/investigations/hlg-figs/cross.svg +0 -1
- package/docs/investigations/hlg-figs/edges.svg +0 -1
- package/docs/investigations/hlg-figs/k20-grids.svg +0 -1
- package/docs/investigations/hlg-figs/k20-peaks.svg +0 -1
- package/docs/investigations/hlg-figs/lw-curve.svg +0 -1
- package/docs/investigations/hlg-figs/terrain.svg +0 -1
- package/docs/investigations/hlg-report.html +0 -262
- package/docs/investigations/hlg-runs/hlg-ab.json +0 -149
- package/docs/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
- package/docs/investigations/hlg-runs/hlg-blind.json +0 -107
- package/docs/investigations/hlg-runs/hlg-cliff.json +0 -197
- package/docs/investigations/hlg-runs/hlg-cross.json +0 -505
- package/docs/investigations/hlg-runs/hlg-edge.json +0 -388
- package/docs/investigations/hlg-runs/hlg-eval1.json +0 -25
- package/docs/investigations/hlg-runs/hlg-frontier.json +0 -86
- package/docs/investigations/hlg-runs/hlg-grid.json +0 -242
- package/docs/investigations/hlg-runs/hlg-grid2.json +0 -343
- package/docs/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
- package/docs/investigations/hlg-runs/hlg-map.json +0 -383
- package/docs/investigations/hlg-runs/run0-original.log +0 -159
- package/docs/investigations/hlg-runs/runA-recommended.log +0 -131
- package/docs/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
- package/docs/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
- package/docs/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
- package/docs/investigations/hlg-runs/runAD-ab-samples.log +0 -8
- package/docs/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
- package/docs/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
- package/docs/investigations/hlg-runs/runAG-eval-config2.log +0 -16
- package/docs/investigations/hlg-runs/runB-gain-variants.log +0 -192
- package/docs/investigations/hlg-runs/runC-pivots.log +0 -162
- package/docs/investigations/hlg-runs/runD-oetf.log +0 -132
- package/docs/investigations/hlg-runs/runE-eotf.log +0 -162
- package/docs/investigations/hlg-runs/runF-shaper-working.log +0 -86
- package/docs/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
- package/docs/investigations/hlg-runs/runH-wsweep.log +0 -176
- package/docs/investigations/hlg-runs/runI-asweep.log +0 -176
- package/docs/investigations/hlg-runs/runJ-knobmap.log +0 -49
- package/docs/investigations/hlg-runs/runK-frontier.log +0 -19
- package/docs/investigations/hlg-runs/runL-widemap.log +0 -65
- package/docs/investigations/hlg-runs/runM-frontier-emb.log +0 -15
- package/docs/investigations/hlg-runs/runN-verify.log +0 -116
- package/docs/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
- package/docs/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
- package/docs/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
- package/docs/investigations/hlg-runs/runR-blind-transcript.log +0 -79
- package/docs/investigations/hlg-runs/runS-cross-coherence.log +0 -33
- package/docs/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
- package/docs/investigations/hlg-runs/runU-cross-12b.log +0 -33
- package/docs/investigations/hlg-runs/runV-lw-e4b.log +0 -22
- package/docs/investigations/hlg-runs/runW-lw-12b.log +0 -22
- package/docs/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
- package/docs/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
- package/docs/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
- package/docs/planning/IDEAS.md +0 -69
- package/docs/reference/embedding.md +0 -197
- package/docs/reference/features-matrix.md +0 -100
- package/docs/reference/orpo-quickstart.md +0 -135
- package/src/flags.ts +0 -13
- /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
- /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
- /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
- /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
- /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
- /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
- /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
- /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
- /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
- /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
- /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
- /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
- /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
- /package/docs/{planning → archive/planning}/journal.md +0 -0
- /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
- /package/docs/{planning → archive/planning}/release-notes-v0.0.13.md +0 -0
- /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
- /package/{docs/investigations → src/serve/assets}/curve-terrain.html +0 -0
- /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
package/src/eval/tasks/bfcl.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { generateText, loadJsonl, sampleIndices, type TaskModel } from "../runner";
|
|
18
18
|
import { type ToolDefinition } from "../../chat-template";
|
|
19
|
+
import { runtimeValue } from "../../runtime-config";
|
|
19
20
|
|
|
20
21
|
// ---------------------------------------------------------------------------
|
|
21
22
|
// Data shapes (the merged jsonl: each line = {query, answer}).
|
|
@@ -465,7 +466,7 @@ export async function evaluateBfcl(
|
|
|
465
466
|
|
|
466
467
|
// Optiq-parity mode (DEFAULT): optiq's EXACT 200 BFCL-simple questions, scored
|
|
467
468
|
// through OUR pipeline. MLX_BUN_BFCL_FROZEN=0 reverts to our copy + sampling.
|
|
468
|
-
const useFrozen = opts.frozen ?? (
|
|
469
|
+
const useFrozen = opts.frozen ?? (runtimeValue("MLX_BUN_BFCL_FROZEN") !== "0");
|
|
469
470
|
let items: BfclItem[];
|
|
470
471
|
if (useFrozen) {
|
|
471
472
|
items = loadJsonl<BfclFrozenRow>("bfcl_optiq_frozen").map((r) => ({
|
package/src/eval/tasks/gsm8k.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// 3-shot CoT, greedy decode, extract the numeric answer, compare.
|
|
3
3
|
|
|
4
4
|
import { generateText, loadJsonl, sampleIndices, type TaskModel } from "../runner";
|
|
5
|
+
import { runtimeValue } from "../../runtime-config";
|
|
5
6
|
|
|
6
7
|
// 3-shot exemplars (verbatim from gsm8k.py).
|
|
7
8
|
const FEW_SHOT: { question: string; answer: string }[] = [
|
|
@@ -73,7 +74,7 @@ export async function evaluateGsm8k(
|
|
|
73
74
|
// his published GSM8K used) but through OUR OWN pipeline — our few-shot builder,
|
|
74
75
|
// our chat template, our scorer. If our number reproduces his, our runtime is
|
|
75
76
|
// faithful. MLX_BUN_GSM8K_FROZEN=0 falls back to our own sampling of the full set.
|
|
76
|
-
const useFrozen = opts.frozen ?? (
|
|
77
|
+
const useFrozen = opts.frozen ?? (runtimeValue("MLX_BUN_GSM8K_FROZEN") !== "0");
|
|
77
78
|
let rows: Gsm8kRow[];
|
|
78
79
|
if (useFrozen) {
|
|
79
80
|
rows = loadJsonl<Gsm8kRow>("gsm8k_optiq_frozen"); // optiq's exact draw; we use {question, answer}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// fused-attention kernel (opportunity A) has the most to prove.
|
|
11
11
|
|
|
12
12
|
import { generateText, loadJsonl, type TaskModel } from "../runner";
|
|
13
|
+
import { runtimeValue } from "../../runtime-config";
|
|
13
14
|
|
|
14
15
|
const INSTR =
|
|
15
16
|
"You will be given a list of hash assignments and a starting hash. " +
|
|
@@ -96,7 +97,7 @@ export async function evaluateHashhop(
|
|
|
96
97
|
// RECONSTRUCTION producing DIFFERENT problems, so it cannot reproduce optiq's
|
|
97
98
|
// number — the frozen problems are the only way to match. MLX_BUN_HASHHOP_FROZEN=0
|
|
98
99
|
// uses our generator.
|
|
99
|
-
const useFrozen = opts.frozen ?? (
|
|
100
|
+
const useFrozen = opts.frozen ?? (runtimeValue("MLX_BUN_HASHHOP_FROZEN") !== "0");
|
|
100
101
|
if (useFrozen) {
|
|
101
102
|
const rows = loadJsonl<HashhopFrozen>("hashhop_optiq_frozen");
|
|
102
103
|
const hopCorrect: Record<number, number> = {};
|
|
@@ -16,11 +16,12 @@ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
16
16
|
import { tmpdir } from "node:os";
|
|
17
17
|
import { join } from "node:path";
|
|
18
18
|
import { generateText, loadJsonl, sampleIndices, type TaskModel } from "../runner";
|
|
19
|
+
import { runtimeValue } from "../../runtime-config";
|
|
19
20
|
|
|
20
21
|
// Oracle venv python — the same interpreter the Python reference uses.
|
|
21
22
|
// Machine-specific: overridable via MLX_BUN_ORACLE_PYTHON (the committed default is
|
|
22
23
|
// the reference box; other laptops set the env, never re-commit the path).
|
|
23
|
-
const ORACLE_PYTHON =
|
|
24
|
+
const ORACLE_PYTHON = runtimeValue("MLX_BUN_ORACLE_PYTHON") ?? "/Users/joshrossi/Code/mlx-lm/.venv/bin/python";
|
|
24
25
|
|
|
25
26
|
interface HumanevalRow {
|
|
26
27
|
task_id: string;
|
|
@@ -185,7 +186,7 @@ function runProgram(program: string, timeoutSec: number, memoryMb: number): RunR
|
|
|
185
186
|
env,
|
|
186
187
|
timeout: timeoutSec * 1000, // hard wall-clock kill
|
|
187
188
|
killSignal: "SIGKILL",
|
|
188
|
-
stdio: ["ignore", "ignore",
|
|
189
|
+
stdio: ["ignore", "ignore", runtimeValue("MLX_BUN_EVAL_DEBUG") === "1" ? "pipe" : "ignore"],
|
|
189
190
|
encoding: "utf8",
|
|
190
191
|
});
|
|
191
192
|
|
|
@@ -219,7 +220,7 @@ export async function evaluateHumaneval(
|
|
|
219
220
|
// Optiq-parity mode (DEFAULT): optiq's EXACT 164-problem set (he runs the full
|
|
220
221
|
// HumanEval test split), scored through OUR pipeline. MLX_BUN_HUMANEVAL_FROZEN=0
|
|
221
222
|
// reverts to our own copy + optional sampling.
|
|
222
|
-
const useFrozen = opts.frozen ?? (
|
|
223
|
+
const useFrozen = opts.frozen ?? (runtimeValue("MLX_BUN_HUMANEVAL_FROZEN") !== "0");
|
|
223
224
|
const rows = loadJsonl<HumanevalRow>(useFrozen ? "humaneval_optiq_frozen" : "humaneval");
|
|
224
225
|
const idx = useFrozen
|
|
225
226
|
? Array.from({ length: rows.length }, (_, i) => i)
|
|
@@ -252,7 +253,7 @@ export async function evaluateHumaneval(
|
|
|
252
253
|
|
|
253
254
|
const rr = runProgram(program, timeoutSec, memoryMb);
|
|
254
255
|
if (rr.ok) nPass++;
|
|
255
|
-
else if (
|
|
256
|
+
else if (runtimeValue("MLX_BUN_EVAL_DEBUG") === "1") {
|
|
256
257
|
const err = rr.stderr ?? "";
|
|
257
258
|
const reason = rr.timedOut ? "TIMEOUT"
|
|
258
259
|
: completion.trim() === "" ? "EMPTY"
|
package/src/eval/tasks/ifeval.ts
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
// default in both implementations, so behavior is identical.
|
|
22
22
|
|
|
23
23
|
import { generateText, loadJsonl, sampleIndices, type TaskModel } from "../runner";
|
|
24
|
+
import { runtimeValue } from "../../runtime-config";
|
|
24
25
|
|
|
25
26
|
export interface IfevalInstance {
|
|
26
27
|
prompt: string;
|
|
@@ -472,7 +473,7 @@ export async function evaluateIfeval(
|
|
|
472
473
|
// Optiq-parity mode (DEFAULT): score optiq's EXACT prompt set (he runs the full
|
|
473
474
|
// IFEval split — 541 prompts) through OUR verifiers + OUR chat template.
|
|
474
475
|
// MLX_BUN_IFEVAL_FROZEN=0 reverts to our own copy + optional sampling.
|
|
475
|
-
const useFrozen = opts.frozen ?? (
|
|
476
|
+
const useFrozen = opts.frozen ?? (runtimeValue("MLX_BUN_IFEVAL_FROZEN") !== "0");
|
|
476
477
|
const rows = loadJsonl<IfevalRow>(useFrozen ? "ifeval_optiq_frozen" : "ifeval");
|
|
477
478
|
const nSamples = opts.nSamples ?? rows.length;
|
|
478
479
|
const idx = (!useFrozen && nSamples < rows.length)
|
package/src/eval/tasks/mmlu.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// table. MLX_BUN_MMLU_FROZEN=0 falls back to our own sampling of the full 14k set.
|
|
11
11
|
|
|
12
12
|
import { loadJsonl, sampleIndices, type TaskModel } from "../runner";
|
|
13
|
+
import { runtimeValue } from "../../runtime-config";
|
|
13
14
|
|
|
14
15
|
interface MmluRow {
|
|
15
16
|
question: string;
|
|
@@ -85,7 +86,7 @@ export async function evaluateMmlu(
|
|
|
85
86
|
// parity, not sampling. Set MLX_BUN_MMLU_FROZEN=0 (or frozen:false) to fall back to
|
|
86
87
|
// our own stratified sampling of the full 14k test set (a DIFFERENT subset: JS RNG
|
|
87
88
|
// ≠ numpy RandomState, so it does not match optiq's questions even at the same seed).
|
|
88
|
-
const useFrozen = opts.frozen ?? (
|
|
89
|
+
const useFrozen = opts.frozen ?? (runtimeValue("MLX_BUN_MMLU_FROZEN") !== "0");
|
|
89
90
|
|
|
90
91
|
const testRows = loadJsonl<MmluRow>(useFrozen ? "mmlu_optiq_frozen" : "mmlu_test");
|
|
91
92
|
const devRows = loadJsonl<MmluRow>(useFrozen ? "mmlu_optiq_dev" : "mmlu_dev");
|
package/src/expert-io.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { dirname, join } from "node:path";
|
|
|
4
4
|
import { nativePackDir } from "./native-pack";
|
|
5
5
|
import type { MlxArray } from "./mlx/array";
|
|
6
6
|
import type { MlxHandle } from "./mlx/ffi";
|
|
7
|
+
import { runtimeValue } from "./runtime-config";
|
|
7
8
|
|
|
8
9
|
const { cstring, i32, ptr: pointer, u32, u64 } = FFIType;
|
|
9
10
|
const EBUSY = 16;
|
|
@@ -69,7 +70,8 @@ export interface ExpertIOHintSnapshot {
|
|
|
69
70
|
|
|
70
71
|
function resolveLibrary(explicit?: string): string {
|
|
71
72
|
if (explicit) return explicit;
|
|
72
|
-
|
|
73
|
+
const configured = runtimeValue("MLX_BUN_EXPERT_IO_DYLIB");
|
|
74
|
+
if (configured) return configured;
|
|
73
75
|
const candidates = [
|
|
74
76
|
join(dirname(process.execPath), "libmlx_bun_expert_io.dylib"),
|
|
75
77
|
join(nativePackDir(), "libmlx_bun_expert_io.dylib"),
|
package/src/expert-offload.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { readFileSync } from "node:fs";
|
|
|
16
16
|
import { MmapFile } from "./mmap";
|
|
17
17
|
import { MlxArray, SAFETENSORS_TO_MLX } from "./mlx/array";
|
|
18
18
|
import type { SafetensorsDtype } from "./safetensors";
|
|
19
|
+
import { runtimeValue } from "./runtime-config";
|
|
19
20
|
|
|
20
21
|
export interface OffloadEntry {
|
|
21
22
|
name: string;
|
|
@@ -71,4 +72,5 @@ export function expertOffloadArray(name: string): MlxArray | null {
|
|
|
71
72
|
return MlxArray.fromPointer(mm.pointer(e.offset), e.shape, SAFETENSORS_TO_MLX[e.dtype]);
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
const expertOffloadPath = runtimeValue("MLX_BUN_EXPERT_OFFLOAD");
|
|
76
|
+
if (expertOffloadPath) activateExpertOffload(expertOffloadPath);
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// The echo source (K3c, Lab tier) — a growing per-request k-gram index over
|
|
2
|
+
// the session's own tokens, and the branch-point rule that decides how far a
|
|
3
|
+
// copied span may run.
|
|
4
|
+
//
|
|
5
|
+
// PORT. The index is the TS port of `GrowingMatcher` from the corpus study
|
|
6
|
+
// (reports/k3-replication/analyze.py): a sequence plus a k-gram → [start
|
|
7
|
+
// positions] map, appended incrementally so a lookup never rescans the prefix,
|
|
8
|
+
// with the bucket scan capped at the NEAREST candidates. The corpus tool ran
|
|
9
|
+
// it offline over recorded turns to measure how much of an agent's output is
|
|
10
|
+
// copy-determined; this runs the same structure online, over promptIds plus
|
|
11
|
+
// everything emitted (injected tokens included — the model cannot tell them
|
|
12
|
+
// apart, so neither does the index).
|
|
13
|
+
//
|
|
14
|
+
// THE INTERESTING PART is not the lookup, it is the STOPPING RULE. A match
|
|
15
|
+
// tells you where this exact k-gram occurred before; it does not tell you how
|
|
16
|
+
// far the future agrees with the past. So the span extends only while EVERY
|
|
17
|
+
// nearby occurrence continues the same way. The moment two occurrences
|
|
18
|
+
// disagree — the session history forks — the span stops. That is where
|
|
19
|
+
// old-query-vs-new-query divergence lives, and delimiters fall out of it for
|
|
20
|
+
// free: a closing quote is where histories fork.
|
|
21
|
+
//
|
|
22
|
+
// DOCTRINE. An echo span is a GUESS, unlike the schema rows. It ships under
|
|
23
|
+
// policy "verify" unless it is unambiguous all the way to a delimiter-class
|
|
24
|
+
// token — the engine then keeps only the prefix the model itself agrees with.
|
|
25
|
+
// Lab tier: default off, and a paired A/B decides whether it ever becomes a
|
|
26
|
+
// default (PLAN K3).
|
|
27
|
+
import type { Proposal, ProposalSource, TokenView } from "./proposal";
|
|
28
|
+
|
|
29
|
+
export interface EchoConfig {
|
|
30
|
+
/** Anchor length: the k-gram that has to match for a span to be proposed. */
|
|
31
|
+
k: number;
|
|
32
|
+
/** Longest span the source will propose (the session clamps again). */
|
|
33
|
+
maxSpan: number;
|
|
34
|
+
/** Bucket scan cap — the NEAREST occurrences win (recency is the signal;
|
|
35
|
+
* an unbounded scan is also the only quadratic risk here). */
|
|
36
|
+
maxCandidates: number;
|
|
37
|
+
/** Stop growing the index past this many tokens (memory cap). */
|
|
38
|
+
indexMax: number;
|
|
39
|
+
/** Token ids that legitimately END a copied span (a closing quote, the
|
|
40
|
+
* markup that follows an argument value). Derived from the template by the
|
|
41
|
+
* strict-row compiler; empty means "no span can be asserted". */
|
|
42
|
+
delimiters: ReadonlySet<number>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Growing k-gram index over one request's token sequence. */
|
|
46
|
+
export class EchoIndex {
|
|
47
|
+
readonly #k: number;
|
|
48
|
+
readonly #indexMax: number;
|
|
49
|
+
readonly #seq: number[] = [];
|
|
50
|
+
/** hash(k-gram) → start positions, oldest first. Hash collisions are
|
|
51
|
+
* harmless: every candidate's gram is compared id-for-id before use. */
|
|
52
|
+
readonly #buckets = new Map<number, number[]>();
|
|
53
|
+
#frozen = false;
|
|
54
|
+
|
|
55
|
+
constructor(k: number, indexMax: number) {
|
|
56
|
+
this.#k = Math.max(1, Math.floor(k));
|
|
57
|
+
this.#indexMax = Math.max(this.#k, Math.floor(indexMax));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get length(): number { return this.#seq.length; }
|
|
61
|
+
/** True once the memory cap stopped the index from growing. */
|
|
62
|
+
get frozen(): boolean { return this.#frozen; }
|
|
63
|
+
|
|
64
|
+
append(ids: readonly number[]): void {
|
|
65
|
+
for (const id of ids) {
|
|
66
|
+
if (this.#seq.length >= this.#indexMax) { this.#frozen = true; return; }
|
|
67
|
+
this.#seq.push(id);
|
|
68
|
+
const start = this.#seq.length - this.#k;
|
|
69
|
+
if (start < 0) continue;
|
|
70
|
+
const h = this.#hash(start);
|
|
71
|
+
const bucket = this.#buckets.get(h);
|
|
72
|
+
if (bucket) bucket.push(start);
|
|
73
|
+
else this.#buckets.set(h, [start]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Start positions whose k-gram equals `gram` AND which have at least one
|
|
78
|
+
* token after it, nearest (most recent) first. */
|
|
79
|
+
candidates(gram: readonly number[], cap: number): number[] {
|
|
80
|
+
if (gram.length !== this.#k) return [];
|
|
81
|
+
let h = 0x811c9dc5;
|
|
82
|
+
for (const id of gram) h = this.#mix(h, id);
|
|
83
|
+
const bucket = this.#buckets.get(h >>> 0);
|
|
84
|
+
if (!bucket) return [];
|
|
85
|
+
const out: number[] = [];
|
|
86
|
+
for (let i = bucket.length - 1; i >= 0 && out.length < cap; i--) {
|
|
87
|
+
const pos = bucket[i]!;
|
|
88
|
+
if (pos + this.#k >= this.#seq.length) continue; // no continuation yet
|
|
89
|
+
let ok = true;
|
|
90
|
+
for (let j = 0; j < this.#k; j++) {
|
|
91
|
+
if (this.#seq[pos + j] !== gram[j]) { ok = false; break; } // collision
|
|
92
|
+
}
|
|
93
|
+
if (ok) out.push(pos);
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Extend forward from the given anchors while EVERY anchor agrees.
|
|
99
|
+
* Returns the agreed continuation, whether it stopped at a fork, and how
|
|
100
|
+
* many occurrences corroborated the WHOLE span (survivors at the last
|
|
101
|
+
* accepted token) — one occurrence is a copy, several are a pattern. */
|
|
102
|
+
extend(
|
|
103
|
+
anchors: readonly number[], maxSpan: number, delimiters: ReadonlySet<number>,
|
|
104
|
+
): { ids: number[]; branchStop: boolean; agreed: number } {
|
|
105
|
+
const ids: number[] = [];
|
|
106
|
+
let agreed = 0;
|
|
107
|
+
let live = anchors.map((p) => p + this.#k);
|
|
108
|
+
while (ids.length < maxSpan) {
|
|
109
|
+
let next: number | undefined;
|
|
110
|
+
let forked = false;
|
|
111
|
+
const stillLive: number[] = [];
|
|
112
|
+
for (const p of live) {
|
|
113
|
+
const v = this.#seq[p];
|
|
114
|
+
// An occurrence that ran out of history simply drops out: a prefix
|
|
115
|
+
// that ends is not evidence of disagreement.
|
|
116
|
+
if (v === undefined) continue;
|
|
117
|
+
if (next === undefined) next = v;
|
|
118
|
+
else if (v !== next) { forked = true; break; }
|
|
119
|
+
stillLive.push(p + 1);
|
|
120
|
+
}
|
|
121
|
+
// A fork means the session's own history disagrees about what comes
|
|
122
|
+
// next. That is exactly the position the model must decide for itself.
|
|
123
|
+
if (forked) return { ids, branchStop: true, agreed };
|
|
124
|
+
if (next === undefined) break; // every occurrence exhausted
|
|
125
|
+
ids.push(next);
|
|
126
|
+
agreed = stillLive.length;
|
|
127
|
+
live = stillLive;
|
|
128
|
+
// A delimiter is a legitimate END: injecting the closing quote is the
|
|
129
|
+
// point, continuing past it is not.
|
|
130
|
+
if (delimiters.has(next)) break;
|
|
131
|
+
}
|
|
132
|
+
return { ids, branchStop: false, agreed };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
#hash(start: number): number {
|
|
136
|
+
let h = 0x811c9dc5;
|
|
137
|
+
for (let j = 0; j < this.#k; j++) h = this.#mix(h, this.#seq[start + j]!);
|
|
138
|
+
return h >>> 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#mix(h: number, id: number): number {
|
|
142
|
+
let x = h ^ id;
|
|
143
|
+
x = Math.imul(x, 0x01000193);
|
|
144
|
+
return x >>> 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** ProposalSource over the echo index. */
|
|
149
|
+
export class EchoSource implements ProposalSource {
|
|
150
|
+
readonly name = "echo";
|
|
151
|
+
readonly windowNeeded: number;
|
|
152
|
+
readonly index: EchoIndex;
|
|
153
|
+
|
|
154
|
+
constructor(private readonly config: EchoConfig, promptIds: readonly number[]) {
|
|
155
|
+
this.windowNeeded = config.k;
|
|
156
|
+
this.index = new EchoIndex(config.k, config.indexMax);
|
|
157
|
+
this.index.append(promptIds);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
observe(ids: readonly number[]): void {
|
|
161
|
+
this.index.append(ids);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
propose(view: TokenView): Proposal | null {
|
|
165
|
+
const { k, maxSpan, maxCandidates, delimiters } = this.config;
|
|
166
|
+
const gram = view.tail(k);
|
|
167
|
+
if (gram.length < k) return null;
|
|
168
|
+
const anchors = this.index.candidates(gram, maxCandidates);
|
|
169
|
+
if (anchors.length === 0) return null;
|
|
170
|
+
const { ids, branchStop, agreed } = this.index.extend(anchors, maxSpan, delimiters);
|
|
171
|
+
if (ids.length < 2) return null;
|
|
172
|
+
// POLICY. Assert only with CORROBORATION: several occurrences of this
|
|
173
|
+
// context all continued the same way, nothing forked, and the span stops
|
|
174
|
+
// at a delimiter-class token. A single occurrence is just a copy — and a
|
|
175
|
+
// copy will happily replay whatever followed it in the transcript,
|
|
176
|
+
// including another role's turn, so it has to be the model's call.
|
|
177
|
+
// Everything else rides policy "verify", where a wrong guess costs a
|
|
178
|
+
// rewound forward, never a wrong token.
|
|
179
|
+
const endsAtDelimiter = delimiters.has(ids[ids.length - 1]!);
|
|
180
|
+
const corroborated = agreed >= 2;
|
|
181
|
+
return {
|
|
182
|
+
ids,
|
|
183
|
+
policy: !branchStop && endsAtDelimiter && corroborated ? "assert" : "verify",
|
|
184
|
+
origin: "echo",
|
|
185
|
+
branchStop,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|