@simulatte/doppler 0.1.6 → 0.1.8
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/CHANGELOG.md +145 -0
- package/README.md +16 -23
- package/package.json +30 -32
- package/src/adapters/adapter-registry.js +12 -1
- package/src/adapters/lora-loader.js +23 -6
- package/src/bridge/extension-client.d.ts +5 -0
- package/src/bridge/extension-client.js +40 -0
- package/src/bridge/index.d.ts +2 -1
- package/src/bridge/index.js +6 -4
- package/src/browser/browser-converter.js +31 -1
- package/src/browser/file-picker.js +6 -0
- package/src/browser/safetensors-parser-browser.js +84 -1
- package/src/browser/shard-io-browser.js +2 -2
- package/src/browser/tensor-source-download.js +8 -2
- package/src/browser/tensor-source-http.d.ts +1 -0
- package/src/browser/tensor-source-http.js +5 -1
- package/src/client/doppler-api.browser.js +20 -4
- package/src/client/doppler-api.js +19 -3
- package/src/client/doppler-provider/generation.js +12 -0
- package/src/client/doppler-provider/model-manager.d.ts +10 -0
- package/src/client/doppler-provider/model-manager.js +91 -19
- package/src/client/doppler-provider/source-runtime.d.ts +2 -1
- package/src/client/doppler-provider/source-runtime.js +132 -13
- package/src/client/doppler-registry.json +5 -20
- package/src/config/backward-registry-loader.js +17 -2
- package/src/config/execution-v0-contract-check.js +113 -15
- package/src/config/kernel-path-contract-check.js +57 -29
- package/src/config/kernel-path-loader.d.ts +5 -0
- package/src/config/kernel-path-loader.js +18 -36
- package/src/config/kernels/kernel-ref-digests.js +1 -1
- package/src/config/kernels/registry.js +14 -1
- package/src/config/kernels/registry.json +81 -5
- package/src/config/loader.d.ts +1 -1
- package/src/config/loader.js +15 -2
- package/src/config/merge-contract-check.js +66 -4
- package/src/config/merge-helpers.js +128 -7
- package/src/config/merge.d.ts +1 -0
- package/src/config/merge.js +10 -0
- package/src/config/param-validator.js +47 -2
- package/src/config/presets/kernel-paths/{gemma2-q4k-dequant-f32a.json → gemma2-q4k-dequant-f32a-nosubgroups.json} +3 -3
- package/src/config/presets/kernel-paths/gemma3-f16-fused-f32a-online-streamingprefill.json +223 -0
- package/src/config/presets/kernel-paths/{gemma3-q4k-dequant-f32a.json → gemma3-q4k-dequant-f32a-nosubgroups.json} +3 -3
- package/src/config/presets/kernel-paths/gemma3-q4k-dequant-f32w-f32a-online.json +56 -0
- package/src/config/presets/kernel-paths/lfm2-q4k-dequant-f32a-nosubgroups.json +61 -0
- package/src/config/presets/kernel-paths/registry.json +43 -8
- package/src/config/presets/models/gemma2.json +3 -2
- package/src/config/presets/models/gemma3.json +2 -0
- package/src/config/presets/models/qwen3.json +4 -3
- package/src/config/presets/models/qwen3_5.json +16 -0
- package/src/config/presets/runtime/experiments/bench/gemma3-bench-q4k.json +1 -1
- package/src/config/presets/runtime/experiments/debug/gemma3-debug-q4k.json +1 -1
- package/src/config/presets/runtime/experiments/verify/gemma3-verify.json +1 -1
- package/src/config/presets/runtime/kernels/dequant-f16-q4k.json +6 -13
- package/src/config/presets/runtime/kernels/dequant-f32-q4k.json +6 -13
- package/src/config/presets/runtime/kernels/embeddinggemma-q4k-dequant-f32a.json +37 -0
- package/src/config/presets/runtime/kernels/fused-q4k.json +6 -13
- package/src/config/presets/runtime/kernels/gemma2-q4k-dequant-f16a.json +33 -0
- package/src/config/presets/runtime/kernels/gemma2-q4k-dequant-f32a-nosubgroups.json +33 -0
- package/src/config/presets/runtime/kernels/gemma2-q4k-fused-f32a.json +33 -0
- package/src/config/presets/runtime/kernels/safe-q4k.json +6 -13
- package/src/config/presets/runtime/model/qwen3-5-layer-probe.json +52 -0
- package/src/config/presets/runtime/model/qwen3-5-linear-attn-debug.json +90 -0
- package/src/config/presets/runtime/platform/metal-apple-q4k.json +1 -1
- package/src/config/runtime.js +6 -1
- package/src/config/schema/conversion.schema.d.ts +1 -0
- package/src/config/schema/debug.schema.d.ts +5 -0
- package/src/config/schema/doppler.schema.js +16 -21
- package/src/config/schema/inference-defaults.schema.js +3 -3
- package/src/config/schema/kernel-path.schema.d.ts +5 -1
- package/src/config/schema/kernel-thresholds.schema.js +12 -4
- package/src/config/schema/manifest.schema.d.ts +3 -2
- package/src/config/schema/manifest.schema.js +17 -4
- package/src/config/schema/storage.schema.js +1 -1
- package/src/config/training-defaults.js +30 -22
- package/src/converter/conversion-plan.js +104 -11
- package/src/converter/core.d.ts +7 -0
- package/src/converter/core.js +16 -9
- package/src/converter/execution-v0-manifest.js +4 -1
- package/src/converter/index.d.ts +1 -0
- package/src/converter/index.js +1 -0
- package/src/converter/manifest-inference.js +50 -29
- package/src/converter/parsers/diffusion.js +0 -3
- package/src/converter/parsers/transformer.js +4 -0
- package/src/converter/quantization-info.js +40 -16
- package/src/converter/quantizer.js +19 -12
- package/src/converter/rope-config.js +8 -6
- package/src/converter/shard-packer.d.ts +1 -1
- package/src/converter/shard-packer.js +4 -1
- package/src/converter/tokenizer-utils.d.ts +1 -0
- package/src/converter/tokenizer-utils.js +4 -1
- package/src/debug/config.js +123 -11
- package/src/debug/reference/hf_qwen35_linear_attn_debug.py +268 -0
- package/src/debug/signals.js +7 -1
- package/src/debug/tensor.d.ts +2 -0
- package/src/debug/tensor.js +13 -2
- package/src/distribution/p2p-control-plane.js +52 -12
- package/src/distribution/p2p-observability.js +43 -7
- package/src/distribution/p2p-webrtc-browser.js +20 -0
- package/src/distribution/shard-delivery.js +83 -27
- package/src/formats/gguf/types.js +33 -16
- package/src/formats/rdrr/groups.d.ts +12 -4
- package/src/formats/rdrr/groups.js +3 -6
- package/src/formats/rdrr/parsing.d.ts +4 -0
- package/src/formats/rdrr/parsing.js +53 -3
- package/src/formats/rdrr/types.d.ts +2 -1
- package/src/gpu/command-recorder.js +86 -61
- package/src/gpu/device.d.ts +1 -0
- package/src/gpu/device.js +73 -19
- package/src/gpu/kernel-tuner/benchmarks.js +326 -316
- package/src/gpu/kernel-tuner/cache.js +71 -4
- package/src/gpu/kernel-tuner/tuner.js +22 -4
- package/src/gpu/kernels/attention.js +15 -34
- package/src/gpu/kernels/backward/adam.js +62 -58
- package/src/gpu/kernels/backward/attention_backward.js +257 -169
- package/src/gpu/kernels/backward/conv2d_backward.js +14 -1
- package/src/gpu/kernels/cast.js +191 -149
- package/src/gpu/kernels/check-stop.js +33 -44
- package/src/gpu/kernels/conv2d.js +27 -17
- package/src/gpu/kernels/cross_entropy_loss.js +21 -15
- package/src/gpu/kernels/depthwise_conv2d.js +36 -26
- package/src/gpu/kernels/dequant.js +178 -126
- package/src/gpu/kernels/energy.d.ts +3 -21
- package/src/gpu/kernels/energy.js +111 -88
- package/src/gpu/kernels/feature-check.js +1 -1
- package/src/gpu/kernels/fused_ffn.js +84 -65
- package/src/gpu/kernels/fused_matmul_residual.js +56 -33
- package/src/gpu/kernels/fused_matmul_rmsnorm.js +62 -45
- package/src/gpu/kernels/gather.js +33 -15
- package/src/gpu/kernels/gelu.js +19 -11
- package/src/gpu/kernels/grouped_pointwise_conv2d.js +33 -23
- package/src/gpu/kernels/groupnorm.js +34 -23
- package/src/gpu/kernels/index.d.ts +8 -0
- package/src/gpu/kernels/index.js +6 -0
- package/src/gpu/kernels/kv-quantize.js +5 -2
- package/src/gpu/kernels/layernorm.js +35 -19
- package/src/gpu/kernels/logit-merge.js +5 -3
- package/src/gpu/kernels/matmul-selection.js +47 -4
- package/src/gpu/kernels/matmul.d.ts +2 -0
- package/src/gpu/kernels/matmul.js +59 -40
- package/src/gpu/kernels/modulate.js +23 -15
- package/src/gpu/kernels/moe.js +221 -175
- package/src/gpu/kernels/pixel_shuffle.js +22 -14
- package/src/gpu/kernels/relu.js +18 -10
- package/src/gpu/kernels/repeat_channels.js +25 -17
- package/src/gpu/kernels/residual.js +37 -27
- package/src/gpu/kernels/rmsnorm.js +66 -43
- package/src/gpu/kernels/rope.js +3 -0
- package/src/gpu/kernels/sample.js +27 -38
- package/src/gpu/kernels/sana_linear_attention.js +18 -10
- package/src/gpu/kernels/scale.js +18 -11
- package/src/gpu/kernels/shader-cache.js +4 -2
- package/src/gpu/kernels/silu.js +120 -72
- package/src/gpu/kernels/softmax.js +44 -25
- package/src/gpu/kernels/split_qg.d.ts +50 -0
- package/src/gpu/kernels/split_qg.js +46 -0
- package/src/gpu/kernels/split_qg.wgsl +58 -0
- package/src/gpu/kernels/split_qg_f16.wgsl +62 -0
- package/src/gpu/kernels/split_qkv.js +23 -13
- package/src/gpu/kernels/transpose.js +18 -10
- package/src/gpu/kernels/transpose.wgsl +5 -3
- package/src/gpu/kernels/upsample2d.js +21 -13
- package/src/gpu/kernels/utils.js +20 -13
- package/src/gpu/partitioned-buffer-pool.js +10 -2
- package/src/gpu/perf-guards.js +2 -9
- package/src/gpu/profiler.js +27 -22
- package/src/gpu/readback-utils.d.ts +16 -0
- package/src/gpu/readback-utils.js +41 -0
- package/src/gpu/submit-tracker.js +13 -0
- package/src/gpu/uniform-cache.d.ts +1 -0
- package/src/gpu/uniform-cache.js +30 -9
- package/src/gpu/weight-buffer.d.ts +1 -1
- package/src/gpu/weight-buffer.js +1 -1
- package/src/hotswap/intent-bundle.js +6 -0
- package/src/hotswap/manifest.d.ts +10 -1
- package/src/hotswap/manifest.js +12 -2
- package/src/hotswap/runtime.js +30 -8
- package/src/index-browser.d.ts +44 -0
- package/src/index-browser.js +14 -0
- package/src/inference/browser-harness-contract-helpers.d.ts +5 -0
- package/src/inference/browser-harness-contract-helpers.js +28 -0
- package/src/inference/browser-harness-diffusion-energy-suites.d.ts +2 -0
- package/src/inference/browser-harness-diffusion-energy-suites.js +269 -0
- package/src/inference/browser-harness-model-helpers.d.ts +16 -0
- package/src/inference/browser-harness-model-helpers.js +217 -0
- package/src/inference/browser-harness-report-helpers.d.ts +7 -0
- package/src/inference/browser-harness-report-helpers.js +42 -0
- package/src/inference/browser-harness-runtime-helpers.d.ts +61 -0
- package/src/inference/browser-harness-runtime-helpers.js +415 -0
- package/src/inference/browser-harness-suite-helpers.d.ts +28 -0
- package/src/inference/browser-harness-suite-helpers.js +268 -0
- package/src/inference/browser-harness-text-helpers.d.ts +27 -0
- package/src/inference/browser-harness-text-helpers.js +788 -0
- package/src/inference/browser-harness.d.ts +8 -0
- package/src/inference/browser-harness.js +149 -1996
- package/src/inference/kv-cache/base.js +140 -94
- package/src/inference/kv-cache/tiered.js +5 -3
- package/src/inference/moe-router.js +88 -56
- package/src/inference/multi-model-network.js +5 -3
- package/src/inference/network-evolution.d.ts +11 -2
- package/src/inference/network-evolution.js +20 -21
- package/src/inference/pipelines/context.d.ts +3 -0
- package/src/inference/pipelines/context.js +142 -2
- package/src/inference/pipelines/diffusion/helpers.js +10 -2
- package/src/inference/pipelines/diffusion/pipeline.js +2 -1
- package/src/inference/pipelines/diffusion/sd3-transformer.js +10 -10
- package/src/inference/pipelines/diffusion/text-encoder-gpu.js +8 -2
- package/src/inference/pipelines/diffusion/vae.js +3 -7
- package/src/inference/pipelines/energy/pipeline.js +27 -21
- package/src/inference/pipelines/energy/quintel.d.ts +5 -0
- package/src/inference/pipelines/energy/quintel.js +11 -0
- package/src/inference/pipelines/energy-head/row-head-pipeline.js +17 -13
- package/src/inference/pipelines/structured/json-head-pipeline.js +26 -11
- package/src/inference/pipelines/text/attention/output-projection.d.ts +12 -0
- package/src/inference/pipelines/text/attention/output-projection.js +8 -0
- package/src/inference/pipelines/text/attention/projections.d.ts +10 -1
- package/src/inference/pipelines/text/attention/projections.js +192 -112
- package/src/inference/pipelines/text/attention/record.js +77 -14
- package/src/inference/pipelines/text/attention/run.js +112 -14
- package/src/inference/pipelines/text/config.js +17 -4
- package/src/inference/pipelines/text/embed.js +2 -8
- package/src/inference/pipelines/text/execution-plan.js +46 -23
- package/src/inference/pipelines/text/execution-v0-contract-helpers.d.ts +59 -0
- package/src/inference/pipelines/text/execution-v0-contract-helpers.js +937 -0
- package/src/inference/pipelines/text/execution-v0-runtime-builders.d.ts +15 -0
- package/src/inference/pipelines/text/execution-v0-runtime-builders.js +279 -0
- package/src/inference/pipelines/text/execution-v0.js +62 -1013
- package/src/inference/pipelines/text/generator-runtime.js +5 -0
- package/src/inference/pipelines/text/generator-steps.d.ts +52 -0
- package/src/inference/pipelines/text/generator-steps.js +340 -221
- package/src/inference/pipelines/text/generator.js +56 -40
- package/src/inference/pipelines/text/init.d.ts +13 -0
- package/src/inference/pipelines/text/init.js +94 -25
- package/src/inference/pipelines/text/kernel-path-auto-select.js +2 -0
- package/src/inference/pipelines/text/kernel-trace.d.ts +2 -0
- package/src/inference/pipelines/text/kernel-trace.js +6 -0
- package/src/inference/pipelines/text/layer.js +4 -9
- package/src/inference/pipelines/text/linear-attention.d.ts +15 -0
- package/src/inference/pipelines/text/linear-attention.js +113 -9
- package/src/inference/pipelines/text/logits/gpu.js +12 -7
- package/src/inference/pipelines/text/logits/index.d.ts +6 -1
- package/src/inference/pipelines/text/logits/index.js +13 -12
- package/src/inference/pipelines/text/logits/utils.d.ts +7 -0
- package/src/inference/pipelines/text/logits/utils.js +9 -0
- package/src/inference/pipelines/text/lora-apply.js +50 -32
- package/src/inference/pipelines/text/model-load.js +282 -104
- package/src/inference/pipelines/text/moe-cache.js +5 -4
- package/src/inference/pipelines/text/moe-cpu-gptoss.js +74 -69
- package/src/inference/pipelines/text/moe-cpu.js +42 -38
- package/src/inference/pipelines/text/moe-gpu.js +110 -86
- package/src/inference/pipelines/text/ops.js +90 -90
- package/src/inference/pipelines/text/probes.js +9 -9
- package/src/inference/pipelines/text/sampling.js +52 -6
- package/src/inference/pipelines/text/weights.js +17 -7
- package/src/inference/pipelines/text.js +13 -1
- package/src/inference/speculative.d.ts +2 -2
- package/src/inference/speculative.js +4 -18
- package/src/inference/test-harness.d.ts +1 -1
- package/src/inference/test-harness.js +17 -7
- package/src/inference/tokenizer.d.ts +0 -5
- package/src/inference/tokenizer.js +4 -23
- package/src/inference/tokenizers/bpe.js +9 -0
- package/src/inference/tokenizers/bundled.js +20 -0
- package/src/inference/tokenizers/sentencepiece.js +12 -0
- package/src/loader/doppler-loader.js +38 -22
- package/src/loader/dtype-utils.js +3 -44
- package/src/loader/embedding-loader.js +7 -3
- package/src/loader/experts/expert-cache.js +13 -6
- package/src/loader/experts/expert-loader.js +10 -6
- package/src/loader/final-weights-loader.js +10 -4
- package/src/loader/layer-loader.js +2 -1
- package/src/loader/loader-state.js +2 -2
- package/src/loader/memory-monitor.js +8 -0
- package/src/loader/multi-model-loader.d.ts +14 -0
- package/src/loader/multi-model-loader.js +70 -24
- package/src/loader/shard-cache.js +84 -14
- package/src/loader/shard-resolver.js +25 -3
- package/src/loader/tensors/tensor-loader.js +214 -144
- package/src/loader/tensors/tensor-reader.js +76 -19
- package/src/loader/weight-downcast.js +1 -1
- package/src/memory/buffer-pool.d.ts +9 -1
- package/src/memory/buffer-pool.js +109 -44
- package/src/memory/unified-detect.js +1 -1
- package/src/rules/inference/dtype.rules.json +5 -0
- package/src/rules/inference/kernel-path.rules.json +24 -8
- package/src/rules/kernels/split-qg.rules.json +6 -0
- package/src/rules/rule-registry.js +27 -1
- package/src/storage/backends/opfs-store.js +68 -24
- package/src/storage/downloader.js +365 -83
- package/src/storage/index.d.ts +3 -0
- package/src/storage/index.js +3 -0
- package/src/storage/preflight.d.ts +2 -2
- package/src/storage/preflight.js +24 -2
- package/src/storage/quickstart-downloader.js +11 -5
- package/src/storage/registry.js +10 -4
- package/src/storage/reports.js +1 -1
- package/src/storage/shard-manager.d.ts +15 -1
- package/src/storage/shard-manager.js +55 -6
- package/src/storage/source-artifact-store.d.ts +52 -0
- package/src/storage/source-artifact-store.js +234 -0
- package/src/tooling/command-api-constants.d.ts +9 -0
- package/src/tooling/command-api-constants.js +9 -0
- package/src/tooling/command-api-family-normalizers.d.ts +9 -0
- package/src/tooling/command-api-family-normalizers.js +343 -0
- package/src/tooling/command-api-helpers.d.ts +25 -0
- package/src/tooling/command-api-helpers.js +262 -0
- package/src/tooling/command-api.js +16 -602
- package/src/tooling/command-envelope.js +4 -1
- package/src/tooling/command-runner-shared.js +52 -18
- package/src/tooling/conversion-config-materializer.js +3 -5
- package/src/tooling/lean-execution-contract.js +150 -3
- package/src/tooling/node-browser-command-runner.js +161 -271
- package/src/tooling/node-command-runner.js +29 -3
- package/src/tooling/node-converter.js +30 -1
- package/src/tooling/node-source-runtime.d.ts +1 -1
- package/src/tooling/node-source-runtime.js +120 -3
- package/src/tooling/node-webgpu.js +24 -21
- package/src/tooling/opfs-cache.js +21 -4
- package/src/tooling/runtime-input-composition.d.ts +38 -0
- package/src/tooling/runtime-input-composition.js +86 -0
- package/src/tooling/source-runtime-bundle.d.ts +40 -5
- package/src/tooling/source-runtime-bundle.js +261 -34
- package/src/tooling/source-runtime-materializer.d.ts +6 -0
- package/src/tooling/source-runtime-materializer.js +93 -0
- package/src/training/attention-backward.js +32 -17
- package/src/training/autograd.js +80 -52
- package/src/training/checkpoint-watch.d.ts +2 -1
- package/src/training/checkpoint-watch.js +39 -6
- package/src/training/checkpoint.js +40 -11
- package/src/training/clip.js +2 -1
- package/src/training/datasets/token-batch.js +20 -8
- package/src/training/distillation/checkpoint-watch.js +1 -0
- package/src/training/distillation/student-fixture.d.ts +22 -0
- package/src/training/distillation/student-fixture.js +846 -0
- package/src/training/distillation/suite-data.d.ts +45 -0
- package/src/training/distillation/suite-data.js +189 -0
- package/src/training/lora-pipeline.js +4 -7
- package/src/training/lora.js +26 -12
- package/src/training/loss.js +5 -6
- package/src/training/objectives/cross_entropy.js +2 -5
- package/src/training/objectives/distill_kd.js +4 -8
- package/src/training/objectives/distill_triplet.js +4 -8
- package/src/training/objectives/ul_stage2_base.js +4 -8
- package/src/training/operator-command.js +2 -0
- package/src/training/optimizer.js +19 -7
- package/src/training/runner.js +2 -1
- package/src/training/suite.js +18 -978
- package/src/training/tensor-factory.d.ts +9 -0
- package/src/training/tensor-factory.js +13 -0
- package/src/training/trainer.js +3 -5
- package/src/training/ul_dataset.js +3 -5
- package/src/training/workloads.js +70 -79
- package/src/types/model.d.ts +5 -0
- package/src/version.js +1 -1
- package/tools/convert-safetensors-node.js +22 -16
- package/tools/doppler-cli.js +50 -26
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@simulatte/doppler` are documented in this file.
|
|
4
|
+
|
|
5
|
+
This changelog is package-facing and release-oriented. Entries before `0.1.7`
|
|
6
|
+
were retrofitted from package version history, release commits, and release
|
|
7
|
+
docs so the `0.1.x` line has one conventional npm-visible history surface.
|
|
8
|
+
|
|
9
|
+
## [0.1.8] - 2026-03-13
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Simplified demo to show only verified Q4K models (Gemma 3 270M, Gemma 3 1B).
|
|
14
|
+
Hidden Translate, Diffusion, and Embedding tabs until models are ready.
|
|
15
|
+
- Trimmed hosted HF registry and quickstart registry to the two verified models.
|
|
16
|
+
- Aligned catalog, HF registry, and quickstart registry to the canonical
|
|
17
|
+
external support registry as single source of truth for HF revisions.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Fixed Qwen 3.5 conversion configs using wrong model preset (`qwen3` instead
|
|
22
|
+
of `qwen3_5`), which caused support matrix check failures.
|
|
23
|
+
- Fixed catalog lifecycle metadata inconsistencies: corrected `local`, `hf`,
|
|
24
|
+
`curated`, and `demo` fields to match actual artifact availability.
|
|
25
|
+
- Removed failing and unverified models from demo visibility (TranslateGemma 4B,
|
|
26
|
+
EmbeddingGemma 300M with broken HF manifest, Qwen 3.5 0.8B/2B, F16 variant).
|
|
27
|
+
|
|
28
|
+
## [0.1.7] - 2026-03-10
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Added a conventional npm-facing changelog and included it in the published
|
|
33
|
+
package file list.
|
|
34
|
+
- Added stronger release-claim, quickstart-registry, local-model-integrity,
|
|
35
|
+
and browser diagnostics regression coverage.
|
|
36
|
+
- Added browser OPFS registry smoke workflows for text and embedding model
|
|
37
|
+
validation.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Tightened release-facing model claims around the verified quickstart/catalog
|
|
42
|
+
set and regenerated the support and release matrices from current metadata.
|
|
43
|
+
- Synced the public quickstart registry from canonical catalog metadata instead
|
|
44
|
+
of maintaining it by hand.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- Fixed a tensor-loader buffer ownership bug that corrupted returned weight
|
|
49
|
+
buffers and broke Gemma 3 1B generation.
|
|
50
|
+
- Fixed quickstart Hugging Face revision drift for registry-backed model IDs.
|
|
51
|
+
- Fixed multiple CI contract drifts across onboarding, release metadata,
|
|
52
|
+
support matrices, and generated benchmark fixtures.
|
|
53
|
+
|
|
54
|
+
## [0.1.6] - 2026-03-07
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- Added stricter config and contract tests around runtime overrides, kernel-path
|
|
59
|
+
semantics, and release-support metadata.
|
|
60
|
+
- Added distillation helper extraction coverage for training suite refactors.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- Continued the execution-v0 and training orchestration refactor work so public
|
|
65
|
+
entrypoints read more like facades and less like inline policy code.
|
|
66
|
+
- Refreshed package exports, repository metadata, and release-facing support
|
|
67
|
+
surfaces for the npm package.
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- Preserved explicit `null` semantics for `runtime.inference.kernelPath` through
|
|
72
|
+
schema, runtime config, and harness paths.
|
|
73
|
+
- Fixed CI drift around onboarding, registry verification aliases, release
|
|
74
|
+
matrix metadata, and kernel-path preset naming.
|
|
75
|
+
|
|
76
|
+
## [0.1.5] - 2026-03-06
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- Added diffusion kernel and contract work, plus additional Lean execution
|
|
81
|
+
contract sweep tooling.
|
|
82
|
+
- Added public API reference inventory and stronger registry workflow tooling.
|
|
83
|
+
|
|
84
|
+
### Changed
|
|
85
|
+
|
|
86
|
+
- Expanded documentation around public APIs, registry workflow, hosted model
|
|
87
|
+
visibility, and release metadata.
|
|
88
|
+
- Tightened package exports and release checks for the public package surface.
|
|
89
|
+
|
|
90
|
+
### Fixed
|
|
91
|
+
|
|
92
|
+
- Fixed hosted TranslateGemma visibility and registry metadata alignment across
|
|
93
|
+
docs, demos, and package surfaces.
|
|
94
|
+
- Removed incorrect self-dependency metadata from the published package.
|
|
95
|
+
|
|
96
|
+
## [0.1.4] - 2026-03-05
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
|
|
100
|
+
- Added Lean execution contract scripts and related package commands.
|
|
101
|
+
- Added translation prompt validation and quickstart/demo polish.
|
|
102
|
+
|
|
103
|
+
### Fixed
|
|
104
|
+
|
|
105
|
+
- Fixed external resolution issues in conversion publication paths.
|
|
106
|
+
- Fixed quickstart-facing package and demo issues ahead of publication.
|
|
107
|
+
|
|
108
|
+
## [0.1.3] - 2026-03-05
|
|
109
|
+
|
|
110
|
+
### Changed
|
|
111
|
+
|
|
112
|
+
- Intermediate package metadata and dependency layout refresh during early npm
|
|
113
|
+
packaging work.
|
|
114
|
+
|
|
115
|
+
## [0.1.2] - 2026-03-05
|
|
116
|
+
|
|
117
|
+
### Changed
|
|
118
|
+
|
|
119
|
+
- Aligned build scripts, tests, docs, and package conventions with the active
|
|
120
|
+
workspace and release process.
|
|
121
|
+
- Refined README messaging and compatibility notes before npm publication.
|
|
122
|
+
|
|
123
|
+
## [0.1.1] - 2026-03-05
|
|
124
|
+
|
|
125
|
+
### Added
|
|
126
|
+
|
|
127
|
+
- Added benchmark vendor comparison docs, runtime patch documentation, and
|
|
128
|
+
refreshed evidence/chart surfaces for the package release.
|
|
129
|
+
|
|
130
|
+
### Changed
|
|
131
|
+
|
|
132
|
+
- Moved vendor benchmark dependencies to development dependencies and kept the
|
|
133
|
+
runtime package dependency surface leaner.
|
|
134
|
+
- Refreshed package metadata, exports, and README/API positioning for the first
|
|
135
|
+
public npm publishing cycle.
|
|
136
|
+
|
|
137
|
+
## [0.1.0] - 2025-12-23
|
|
138
|
+
|
|
139
|
+
### Added
|
|
140
|
+
|
|
141
|
+
- Initial npm package release for Doppler.
|
|
142
|
+
- Browser and Node command surfaces, CLI entrypoint, loader/storage pipeline,
|
|
143
|
+
RDRR manifest handling, config schemas/presets, WebGPU kernel registry, text
|
|
144
|
+
inference pipeline, conversion tooling, benchmark tooling, tests, and demo
|
|
145
|
+
infrastructure.
|
package/README.md
CHANGED
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Inference and training on raw WebGPU. Pure JS + WGSL.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Install
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install @simulatte/doppler
|
|
11
|
-
```
|
|
5
|
+

|
|
12
6
|
|
|
13
7
|
## Quick start
|
|
14
8
|
|
|
@@ -17,13 +11,25 @@ import { doppler } from '@simulatte/doppler';
|
|
|
17
11
|
|
|
18
12
|
const model = await doppler.load('gemma3-270m');
|
|
19
13
|
|
|
20
|
-
for await (const token of model.generate('
|
|
14
|
+
for await (const token of model.generate('Describe WebGPU briefly')) {
|
|
21
15
|
process.stdout.write(token);
|
|
22
16
|
}
|
|
23
17
|
```
|
|
24
18
|
|
|
19
|
+
Browser-first WebGPU inference and training with explicit manifest-driven
|
|
20
|
+
runtime behavior. Built for local models, streamed generation, adapter
|
|
21
|
+
hot-swap, and direct JS → WGSL → WebGPU execution.
|
|
22
|
+
|
|
25
23
|
Registry IDs resolve to hosted RDRR artifacts from `Clocksmith/rdrr` by default. Tokens stream from a native `AsyncGenerator`. See [more examples](#more-examples) below or the canonical [Root API guide](https://github.com/clocksmith/doppler/blob/main/docs/api/root.md).
|
|
26
24
|
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @simulatte/doppler
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**[Live Demo](https://d4da.com)** · **[npm](https://www.npmjs.com/package/@simulatte/doppler)** · **[docs](https://github.com/clocksmith/doppler/blob/main/docs/INDEX.md)** · **[Project site](https://simulatte.world)**
|
|
32
|
+
|
|
27
33
|
## Why Doppler
|
|
28
34
|
|
|
29
35
|
**JS → WGSL → WebGPU.** Direct JavaScript orchestration into native WebGPU kernels, avoiding ONNX runtimes, WASM blobs, and bridge layers.
|
|
@@ -36,8 +42,6 @@ Registry IDs resolve to hosted RDRR artifacts from `Clocksmith/rdrr` by default.
|
|
|
36
42
|
|
|
37
43
|
## Evidence
|
|
38
44
|
|
|
39
|
-

|
|
40
|
-
|
|
41
45
|
Snapshot artifacts:
|
|
42
46
|
- [g3-1b-p064-d064-t0-k1.compare.json](https://github.com/clocksmith/doppler/blob/main/benchmarks/vendors/fixtures/g3-1b-p064-d064-t0-k1.compare.json)
|
|
43
47
|
- [lfm2-5-1-2b-p064-d064-t0-k1.compare.json](https://github.com/clocksmith/doppler/blob/main/benchmarks/vendors/fixtures/lfm2-5-1-2b-p064-d064-t0-k1.compare.json)
|
|
@@ -83,19 +87,8 @@ for await (const token of doppler('Hello', { model: 'gemma3-270m' })) {
|
|
|
83
87
|
- Architecture: [docs/architecture.md](https://github.com/clocksmith/doppler/blob/main/docs/architecture.md)
|
|
84
88
|
- Generated model support table: [docs/model-support-matrix.md](https://github.com/clocksmith/doppler/blob/main/docs/model-support-matrix.md)
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
Verified right now:
|
|
89
|
-
- `gemma-3-270m-it-wq4k-ef16-hf16`
|
|
90
|
-
- `gemma-3-1b-it-wq4k-ef16-hf16`
|
|
91
|
-
- `google-embeddinggemma-300m-wq4k-ef16`
|
|
92
|
-
- `translategemma-4b-it-wq4k-ef16-hf16`
|
|
93
|
-
|
|
94
|
-
Known failing right now:
|
|
95
|
-
- `qwen-3-5-0-8b-wq4k-ef16-hf16-f16`
|
|
96
|
-
- `qwen-3-5-2b-wq4k-ef16-hf16-f16`
|
|
97
|
-
|
|
98
|
-
For the generated status table, including `loads but unverified` and `everything else`, see [docs/model-support-matrix.md](https://github.com/clocksmith/doppler/blob/main/docs/model-support-matrix.md).
|
|
90
|
+
Current model support is generated from the catalog and conversion registry.
|
|
91
|
+
See [docs/model-support-matrix.md](https://github.com/clocksmith/doppler/blob/main/docs/model-support-matrix.md) for the canonical verified, failing, and unverified status table.
|
|
99
92
|
|
|
100
93
|
## Environment requirements
|
|
101
94
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simulatte/doppler",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Browser-native WebGPU inference engine for local intent and inference loops",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -29,22 +29,22 @@
|
|
|
29
29
|
"bench:chart": "node ./benchmarks/vendors/compare-chart.js",
|
|
30
30
|
"bench:chart:readme": "node ./benchmarks/vendors/compare-chart.js --preset readme-evidence",
|
|
31
31
|
"bench:architecture:chart": "node ./benchmarks/vendors/generate-architecture-overview-svg.js",
|
|
32
|
-
"ci:diffusion:contract": "node tools/ci-diffusion-contract-gates.
|
|
33
|
-
"ci:diffusion:contract:list": "node tools/ci-diffusion-contract-gates.
|
|
34
|
-
"ci:training:contract": "node tools/ci-training-contract-gates.
|
|
35
|
-
"ci:training:contract:list": "node tools/ci-training-contract-gates.
|
|
36
|
-
"training:contract:delta": "node tools/emit-training-contract-delta.
|
|
37
|
-
"training:workloads:verify": "node tools/verify-training-workload-packs.
|
|
38
|
-
"training:report-ids:publish": "node tools/publish-training-report-ids.
|
|
39
|
-
"distill:studio:mvp": "node tools/distill-studio-mvp.
|
|
40
|
-
"distill:quality-gate": "node tools/distill-studio-quality-gate.
|
|
41
|
-
"p2p:observability": "node tools/p2p-delivery-observability.
|
|
42
|
-
"p2p:drill": "node tools/p2p-resilience-drill.
|
|
32
|
+
"ci:diffusion:contract": "node tools/ci-diffusion-contract-gates.js",
|
|
33
|
+
"ci:diffusion:contract:list": "node tools/ci-diffusion-contract-gates.js --list",
|
|
34
|
+
"ci:training:contract": "node tools/ci-training-contract-gates.js",
|
|
35
|
+
"ci:training:contract:list": "node tools/ci-training-contract-gates.js --list",
|
|
36
|
+
"training:contract:delta": "node tools/emit-training-contract-delta.js",
|
|
37
|
+
"training:workloads:verify": "node tools/verify-training-workload-packs.js --registry tools/configs/training-workloads/registry.json",
|
|
38
|
+
"training:report-ids:publish": "node tools/publish-training-report-ids.js --registry tools/configs/training-workloads/registry.json",
|
|
39
|
+
"distill:studio:mvp": "node tools/distill-studio-mvp.js",
|
|
40
|
+
"distill:quality-gate": "node tools/distill-studio-quality-gate.js",
|
|
41
|
+
"p2p:observability": "node tools/p2p-delivery-observability.js",
|
|
42
|
+
"p2p:drill": "node tools/p2p-resilience-drill.js",
|
|
43
43
|
"test": "npm run test:unit",
|
|
44
|
-
"test:unit": "node tools/run-node-tests.
|
|
45
|
-
"test:gpu": "node tools/run-node-tests.
|
|
46
|
-
"test:coverage": "node tools/run-node-coverage.
|
|
47
|
-
"test:coverage:report": "node tools/run-node-coverage.
|
|
44
|
+
"test:unit": "node tools/run-node-tests.js --suite unit",
|
|
45
|
+
"test:gpu": "node tools/run-node-tests.js --suite gpu",
|
|
46
|
+
"test:coverage": "node tools/run-node-coverage.js",
|
|
47
|
+
"test:coverage:report": "node tools/run-node-coverage.js --no-threshold",
|
|
48
48
|
"test:gpu:browser": "node tools/doppler-cli.js verify --config '{\"request\":{\"suite\":\"kernels\"},\"run\":{\"surface\":\"browser\",\"browser\":{\"opfsCache\":false,\"headless\":true,\"channel\":\"chromium\",\"browserArgs\":[\"--use-angle=swiftshader\",\"--disable-vulkan-surface\"],\"console\":true}}}'",
|
|
49
49
|
"agents:verify": "node tools/verify-agent-parity.js",
|
|
50
50
|
"agents:freshness": "node tools/verify-agent-freshness.js",
|
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
"api:docs:sync": "node tools/sync-api-docs.js",
|
|
55
55
|
"api:docs:check": "node tools/sync-api-docs.js --check",
|
|
56
56
|
"verify:model": "node tools/doppler-cli.js verify",
|
|
57
|
+
"quickstart:sync": "node tools/sync-quickstart-registry.js",
|
|
58
|
+
"quickstart:check": "node tools/sync-quickstart-registry.js --check",
|
|
57
59
|
"onboarding:check": "node tools/onboarding-tooling.js check",
|
|
58
60
|
"onboarding:check:strict": "node tools/onboarding-tooling.js check --strict",
|
|
59
61
|
"onboarding:scaffold": "node tools/onboarding-tooling.js scaffold",
|
|
@@ -72,26 +74,20 @@
|
|
|
72
74
|
"ci:catalog:check": "npm run registry:sync:scripts:check && npm run support:matrix:check && npm run registry:hf:check",
|
|
73
75
|
"external:rdrr:index": "node tools/sync-external-rdrr-index.js",
|
|
74
76
|
"external:rdrr:index:check": "node tools/sync-external-rdrr-index.js --check",
|
|
75
|
-
"
|
|
77
|
+
"external:support:sync": "node tools/sync-external-support-registry.js",
|
|
78
|
+
"external:support:check": "node tools/sync-external-support-registry.js --check",
|
|
79
|
+
"catalog:sync:external": "node tools/sync-catalog-from-external-support.js",
|
|
80
|
+
"catalog:sync:external:check": "node tools/sync-catalog-from-external-support.js --check",
|
|
81
|
+
"verify:gemma-3-1b-it-q4k-ehf16-af32": "node tools/run-registry-verify.js gemma-3-1b-it-q4k-ehf16-af32",
|
|
82
|
+
"verify:gemma-3-1b-it-wq4k-ef16-hf16": "node tools/run-registry-verify.js gemma-3-1b-it-wq4k-ef16-hf16",
|
|
83
|
+
"verify:gemma-3-270m-it-q4k-ehf16-af32": "node tools/run-registry-verify.js gemma-3-270m-it-q4k-ehf16-af32",
|
|
76
84
|
"verify:gemma-3-270m-it-wq4k-ef16": "node tools/run-registry-verify.js gemma-3-270m-it-wq4k-ef16",
|
|
77
85
|
"verify:gemma-3-270m-it-wq4k-ef16-hf16": "node tools/run-registry-verify.js gemma-3-270m-it-wq4k-ef16-hf16",
|
|
78
86
|
"verify:gemma-3-270m-it-wq4k-ef16-hf16-f32": "node tools/run-registry-verify.js gemma-3-270m-it-wq4k-ef16-hf16-f32",
|
|
87
|
+
"verify:gemma3-1b": "node tools/run-registry-verify.js gemma3-1b",
|
|
79
88
|
"verify:gemma3-270m": "node tools/run-registry-verify.js gemma3-270m",
|
|
80
|
-
"verify:google-
|
|
81
|
-
"verify:google-
|
|
82
|
-
"verify:google-gemma-3-270m-it": "node tools/run-registry-verify.js google-gemma-3-270m-it",
|
|
83
|
-
"verify:google-translategemma-4b-it": "node tools/run-registry-verify.js google-translategemma-4b-it",
|
|
84
|
-
"verify:qwen-3-5-0-8b": "node tools/run-registry-verify.js qwen-3-5-0-8b",
|
|
85
|
-
"verify:qwen-3-5-0-8b-wq4k-ef16-hf16-f16": "node tools/run-registry-verify.js qwen-3-5-0-8b-wq4k-ef16-hf16-f16",
|
|
86
|
-
"verify:qwen-3-5-2b": "node tools/run-registry-verify.js qwen-3-5-2b",
|
|
87
|
-
"verify:qwen-3-5-2b-wq4k-ef16-hf16-f16": "node tools/run-registry-verify.js qwen-3-5-2b-wq4k-ef16-hf16-f16",
|
|
88
|
-
"verify:qwen-qwen3.5-0.8b": "node tools/run-registry-verify.js qwen-qwen3.5-0.8b",
|
|
89
|
-
"verify:qwen-qwen3.5-2b": "node tools/run-registry-verify.js qwen-qwen3.5-2b",
|
|
90
|
-
"verify:qwen3-0.8b": "node tools/run-registry-verify.js qwen3-0.8b",
|
|
91
|
-
"verify:qwen3-2b": "node tools/run-registry-verify.js qwen3-2b",
|
|
92
|
-
"verify:translategemma": "node tools/run-registry-verify.js translategemma",
|
|
93
|
-
"verify:translategemma-4b": "node tools/run-registry-verify.js translategemma-4b",
|
|
94
|
-
"verify:translategemma-4b-it-wq4k-ef16-hf16": "node tools/run-registry-verify.js translategemma-4b-it-wq4k-ef16-hf16"
|
|
89
|
+
"verify:google-gemma-3-1b-it": "node tools/run-registry-verify.js google-gemma-3-1b-it",
|
|
90
|
+
"verify:google-gemma-3-270m-it": "node tools/run-registry-verify.js google-gemma-3-270m-it"
|
|
95
91
|
},
|
|
96
92
|
"exports": {
|
|
97
93
|
".": {
|
|
@@ -104,6 +100,7 @@
|
|
|
104
100
|
},
|
|
105
101
|
"./tooling": {
|
|
106
102
|
"types": "./src/tooling-exports.d.ts",
|
|
103
|
+
"browser": "./src/tooling-exports.browser.js",
|
|
107
104
|
"import": "./src/tooling-exports.js"
|
|
108
105
|
},
|
|
109
106
|
"./internal": {
|
|
@@ -149,6 +146,7 @@
|
|
|
149
146
|
"src",
|
|
150
147
|
"src/gpu/kernels/*.wgsl",
|
|
151
148
|
"README.md",
|
|
149
|
+
"CHANGELOG.md",
|
|
152
150
|
"LICENSE",
|
|
153
151
|
"NOTICE",
|
|
154
152
|
"BRANDING.md",
|
|
@@ -9,6 +9,12 @@ import { DEFAULT_ADAPTER_REGISTRY_CONFIG } from '../config/schema/index.js';
|
|
|
9
9
|
|
|
10
10
|
const { dbName: DB_NAME, dbVersion: DB_VERSION, storeName: STORE_NAME } = DEFAULT_ADAPTER_REGISTRY_CONFIG;
|
|
11
11
|
|
|
12
|
+
function isNodeRuntime() {
|
|
13
|
+
return typeof process !== 'undefined'
|
|
14
|
+
&& !!process.versions?.node
|
|
15
|
+
&& typeof window === 'undefined';
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
|
|
13
19
|
class IndexedDBStorage {
|
|
14
20
|
#db = null;
|
|
@@ -163,8 +169,13 @@ export class AdapterRegistry {
|
|
|
163
169
|
this.#storage = storage;
|
|
164
170
|
} else if (typeof indexedDB !== 'undefined') {
|
|
165
171
|
this.#storage = new IndexedDBStorage();
|
|
166
|
-
} else {
|
|
172
|
+
} else if (isNodeRuntime()) {
|
|
167
173
|
this.#storage = new MemoryStorage();
|
|
174
|
+
} else {
|
|
175
|
+
throw new Error(
|
|
176
|
+
'AdapterRegistry requires IndexedDB in browser environments. ' +
|
|
177
|
+
'Pass explicit storage or use createMemoryRegistry() for tests.'
|
|
178
|
+
);
|
|
168
179
|
}
|
|
169
180
|
}
|
|
170
181
|
|
|
@@ -82,6 +82,20 @@ async function computeSHA256(data) {
|
|
|
82
82
|
return Array.from(hashArray).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
function assertCompleteAdapterLayers(adapter) {
|
|
86
|
+
for (const [layerIndex, layer] of adapter.layers.entries()) {
|
|
87
|
+
for (const [moduleName, weights] of Object.entries(layer)) {
|
|
88
|
+
const hasA = weights?.a instanceof Float32Array && weights.a.length > 0;
|
|
89
|
+
const hasB = weights?.b instanceof Float32Array && weights.b.length > 0;
|
|
90
|
+
if (!hasA || !hasB) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`LoRA adapter layer ${layerIndex} module ${moduleName} is incomplete; both lora_a and lora_b tensors are required.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
85
99
|
// ============================================================================
|
|
86
100
|
// Core Loading Functions
|
|
87
101
|
// ============================================================================
|
|
@@ -156,14 +170,14 @@ export async function loadLoRAWeights(path, options = {}) {
|
|
|
156
170
|
if (manifest.checksum && !options.skipVerify) {
|
|
157
171
|
const algorithm = manifest.checksumAlgorithm;
|
|
158
172
|
if (algorithm !== 'sha256') {
|
|
159
|
-
|
|
173
|
+
throw new Error(`Unsupported LoRA checksum algorithm: ${algorithm}`);
|
|
160
174
|
} else if (manifest.weightsPath) {
|
|
161
175
|
// Compute checksum of the weights file
|
|
162
176
|
const weightsData = await fetchWithBase(manifest.weightsPath);
|
|
163
177
|
const computedHash = await computeSHA256(weightsData);
|
|
164
178
|
checksumValid = computedHash.toLowerCase() === manifest.checksum.toLowerCase();
|
|
165
179
|
if (!checksumValid) {
|
|
166
|
-
|
|
180
|
+
throw new Error(`LoRA checksum mismatch: expected ${manifest.checksum}, got ${computedHash}`);
|
|
167
181
|
}
|
|
168
182
|
} else if (manifest.tensors && manifest.tensors.length > 0) {
|
|
169
183
|
// For inline tensors, compute checksum over concatenated tensor data
|
|
@@ -187,7 +201,7 @@ export async function loadLoRAWeights(path, options = {}) {
|
|
|
187
201
|
const computedHash = await computeSHA256(combined.buffer);
|
|
188
202
|
checksumValid = computedHash.toLowerCase() === manifest.checksum.toLowerCase();
|
|
189
203
|
if (!checksumValid) {
|
|
190
|
-
|
|
204
|
+
throw new Error(`LoRA checksum mismatch: expected ${manifest.checksum}, got ${computedHash}`);
|
|
191
205
|
}
|
|
192
206
|
}
|
|
193
207
|
}
|
|
@@ -223,8 +237,7 @@ export async function loadLoRAFromManifest(manifest, options = {}) {
|
|
|
223
237
|
for (const tensor of tensors) {
|
|
224
238
|
const parsed = parseTensorName(tensor.name);
|
|
225
239
|
if (!parsed) {
|
|
226
|
-
|
|
227
|
-
continue;
|
|
240
|
+
throw new Error(`Unrecognized LoRA tensor name: ${tensor.name}`);
|
|
228
241
|
}
|
|
229
242
|
|
|
230
243
|
const data = await toFloat32Array(tensor, options);
|
|
@@ -257,6 +270,7 @@ export async function loadLoRAFromManifest(manifest, options = {}) {
|
|
|
257
270
|
}
|
|
258
271
|
}
|
|
259
272
|
|
|
273
|
+
assertCompleteAdapterLayers(adapter);
|
|
260
274
|
return adapter;
|
|
261
275
|
}
|
|
262
276
|
|
|
@@ -312,7 +326,9 @@ export async function loadLoRAFromSafetensors(data, manifest) {
|
|
|
312
326
|
if (tensorName === '__metadata__') continue;
|
|
313
327
|
|
|
314
328
|
const parsed = parseTensorName(tensorName);
|
|
315
|
-
if (!parsed)
|
|
329
|
+
if (!parsed) {
|
|
330
|
+
throw new Error(`Unrecognized LoRA safetensors tensor name: ${tensorName}`);
|
|
331
|
+
}
|
|
316
332
|
|
|
317
333
|
const [start, end] = tensorInfo.data_offsets;
|
|
318
334
|
const tensorData = new Uint8Array(data, dataOffset + start, end - start);
|
|
@@ -359,6 +375,7 @@ export async function loadLoRAFromSafetensors(data, manifest) {
|
|
|
359
375
|
adapter.layers.set(parsed.layer, layer);
|
|
360
376
|
}
|
|
361
377
|
|
|
378
|
+
assertCompleteAdapterLayers(adapter);
|
|
362
379
|
return adapter;
|
|
363
380
|
}
|
|
364
381
|
|
|
@@ -64,6 +64,16 @@ export class ExtensionBridgeClient {
|
|
|
64
64
|
throw new Error('Chrome extension API not available');
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
if (this.#status === BridgeStatus.CONNECTING) {
|
|
68
|
+
throw new Error('Bridge client connection already in progress');
|
|
69
|
+
}
|
|
70
|
+
if (this.#status === BridgeStatus.CONNECTED) {
|
|
71
|
+
if ((extensionId ?? null) !== this.#extensionId) {
|
|
72
|
+
throw new Error('Bridge client already connected to a different extension target');
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
67
77
|
this.#extensionId = extensionId;
|
|
68
78
|
this.#status = BridgeStatus.CONNECTING;
|
|
69
79
|
this.#notifyStatusChange();
|
|
@@ -209,6 +219,11 @@ export class ExtensionBridgeClient {
|
|
|
209
219
|
|
|
210
220
|
|
|
211
221
|
#handleMessage(message) {
|
|
222
|
+
if (message?.type === 'error') {
|
|
223
|
+
this.#handleExplicitError(message);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
212
227
|
if (message.type !== 'binary' || !message.data) {
|
|
213
228
|
log.warn('ExtensionBridge', `Unexpected message type: ${message.type}`);
|
|
214
229
|
return;
|
|
@@ -308,6 +323,27 @@ export class ExtensionBridgeClient {
|
|
|
308
323
|
}
|
|
309
324
|
}
|
|
310
325
|
|
|
326
|
+
#handleExplicitError(message) {
|
|
327
|
+
const text = typeof message?.message === 'string' && message.message.length > 0
|
|
328
|
+
? message.message
|
|
329
|
+
: 'Native bridge error';
|
|
330
|
+
const error = new Error(text);
|
|
331
|
+
|
|
332
|
+
this.#port = null;
|
|
333
|
+
this.#status = BridgeStatus.ERROR;
|
|
334
|
+
this.#notifyStatusChange();
|
|
335
|
+
|
|
336
|
+
for (const [, pending] of this.#pendingRequests) {
|
|
337
|
+
clearTimeout(pending.timeout);
|
|
338
|
+
pending.reject(error);
|
|
339
|
+
}
|
|
340
|
+
this.#pendingRequests.clear();
|
|
341
|
+
|
|
342
|
+
if (this.onError) {
|
|
343
|
+
this.onError(error);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
311
347
|
|
|
312
348
|
#handleDisconnect() {
|
|
313
349
|
const error = chrome.runtime?.lastError;
|
|
@@ -340,6 +376,10 @@ export class ExtensionBridgeClient {
|
|
|
340
376
|
return this.#status;
|
|
341
377
|
}
|
|
342
378
|
|
|
379
|
+
getExtensionId() {
|
|
380
|
+
return this.#extensionId;
|
|
381
|
+
}
|
|
382
|
+
|
|
343
383
|
|
|
344
384
|
isConnected() {
|
|
345
385
|
return this.#status === BridgeStatus.CONNECTED;
|
package/src/bridge/index.d.ts
CHANGED
package/src/bridge/index.js
CHANGED
|
@@ -27,24 +27,26 @@ export {
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
export async function createBridgeClient(extensionId = null) {
|
|
30
|
-
const {
|
|
30
|
+
const { getBridgeClient, isBridgeAvailable } = await import('./extension-client.js');
|
|
31
31
|
|
|
32
32
|
if (!isBridgeAvailable()) {
|
|
33
33
|
throw new Error('Native bridge not available - Chrome extension API required');
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const client =
|
|
36
|
+
const client = getBridgeClient();
|
|
37
37
|
await client.connect(extensionId);
|
|
38
38
|
return client;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
export async function readFileNative(path, offset = 0, length = 0) {
|
|
42
|
+
export async function readFileNative(path, offset = 0, length = 0, extensionId = null) {
|
|
43
43
|
const { getBridgeClient } = await import('./extension-client.js');
|
|
44
44
|
const client = getBridgeClient();
|
|
45
45
|
|
|
46
46
|
if (!client.isConnected()) {
|
|
47
|
-
await client.connect();
|
|
47
|
+
await client.connect(extensionId);
|
|
48
|
+
} else if ((extensionId ?? null) !== (client.getExtensionId?.() ?? null)) {
|
|
49
|
+
throw new Error('Bridge client already connected to a different extension target');
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
return client.read(path, offset, length);
|
|
@@ -160,6 +160,18 @@ function normalizePath(path) {
|
|
|
160
160
|
return String(path || '').replace(/\\/g, '/');
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
function attachRelativePath(file, relativePath) {
|
|
164
|
+
if (!file || !relativePath) return;
|
|
165
|
+
try {
|
|
166
|
+
Object.defineProperty(file, 'relativePath', {
|
|
167
|
+
value: relativePath,
|
|
168
|
+
configurable: true,
|
|
169
|
+
});
|
|
170
|
+
} catch {
|
|
171
|
+
// Ignore if File is non-extensible in this environment.
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
163
175
|
function getBaseName(path) {
|
|
164
176
|
const normalized = normalizePath(path);
|
|
165
177
|
if (!normalized) return '';
|
|
@@ -396,6 +408,7 @@ export async function convertModel(files, options = {}) {
|
|
|
396
408
|
// Parse based on format
|
|
397
409
|
let modelInfo;
|
|
398
410
|
let config = null;
|
|
411
|
+
let generationConfig = null;
|
|
399
412
|
let tokenizerJson = null;
|
|
400
413
|
let tokenizerConfig = null;
|
|
401
414
|
let tokenizerModel = null;
|
|
@@ -443,6 +456,10 @@ export async function convertModel(files, options = {}) {
|
|
|
443
456
|
tokenizerConfig = await parseTokenizerConfigJson(auxiliary.tokenizerConfig);
|
|
444
457
|
modelInfo.tokenizerConfig = tokenizerConfig;
|
|
445
458
|
}
|
|
459
|
+
if (auxiliary.generationConfig) {
|
|
460
|
+
generationConfig = await parseConfigJson(auxiliary.generationConfig);
|
|
461
|
+
modelInfo.generationConfig = generationConfig;
|
|
462
|
+
}
|
|
446
463
|
if (auxiliary.tokenizerModel) {
|
|
447
464
|
const source = normalizeTensorSource(auxiliary.tokenizerModel);
|
|
448
465
|
tokenizerModel = await source.readRange(0, source.size);
|
|
@@ -924,8 +941,16 @@ export async function pickModelFiles() {
|
|
|
924
941
|
|
|
925
942
|
async function collectFilesFromDirectory(
|
|
926
943
|
dirHandle,
|
|
927
|
-
files = []
|
|
944
|
+
files = [],
|
|
945
|
+
basePath = '',
|
|
946
|
+
depth = 0
|
|
928
947
|
) {
|
|
948
|
+
if (depth > 4) {
|
|
949
|
+
throw new Error(
|
|
950
|
+
`Model directory exceeds supported depth (4) near "${basePath || dirHandle?.name || '.'}". ` +
|
|
951
|
+
'Choose a shallower directory root or flatten the model files.'
|
|
952
|
+
);
|
|
953
|
+
}
|
|
929
954
|
const entries = dirHandle.values();
|
|
930
955
|
for await (const entry of entries) {
|
|
931
956
|
if (entry.kind === 'file') {
|
|
@@ -937,8 +962,13 @@ async function collectFilesFromDirectory(
|
|
|
937
962
|
file.name.endsWith('.json') ||
|
|
938
963
|
file.name === 'tokenizer.model'
|
|
939
964
|
) {
|
|
965
|
+
const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name;
|
|
966
|
+
attachRelativePath(file, relativePath);
|
|
940
967
|
files.push(file);
|
|
941
968
|
}
|
|
969
|
+
} else if (entry.kind === 'directory') {
|
|
970
|
+
const nextBasePath = basePath ? `${basePath}/${entry.name}` : entry.name;
|
|
971
|
+
await collectFilesFromDirectory(entry, files, nextBasePath, depth + 1);
|
|
942
972
|
}
|
|
943
973
|
}
|
|
944
974
|
return files;
|
|
@@ -140,6 +140,12 @@ async function collectModelFilesFromDirectory(
|
|
|
140
140
|
const nextBasePath = basePath ? `${basePath}/${entry.name}` : entry.name;
|
|
141
141
|
const subFiles = await collectModelFilesFromDirectory(subDirHandle, nextBasePath, maxDepth - 1);
|
|
142
142
|
files.push(...subFiles);
|
|
143
|
+
} else if (entry.kind === 'directory') {
|
|
144
|
+
const nextBasePath = basePath ? `${basePath}/${entry.name}` : entry.name;
|
|
145
|
+
throw new Error(
|
|
146
|
+
`Model directory exceeds supported depth (${MODEL_DIRECTORY_MAX_DEPTH}) near "${nextBasePath}". ` +
|
|
147
|
+
'Choose a shallower directory root or flatten the model files.'
|
|
148
|
+
);
|
|
143
149
|
}
|
|
144
150
|
}
|
|
145
151
|
|