@simulatte/doppler 0.1.5 → 0.1.7
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 +126 -0
- package/README.md +25 -17
- package/package.json +20 -4
- 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 +26 -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 +8 -7
- 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.js +5 -36
- package/src/config/kernels/kernel-ref-digests.js +39 -39
- package/src/config/kernels/registry.js +14 -1
- package/src/config/kernels/registry.json +49 -7
- package/src/config/loader.d.ts +1 -1
- package/src/config/loader.js +43 -4
- package/src/config/merge-contract-check.js +59 -4
- package/src/config/merge-helpers.js +128 -7
- package/src/config/merge.d.ts +1 -0
- package/src/config/merge.js +28 -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/registry.json +29 -8
- package/src/config/presets/models/gemma2.json +2 -2
- package/src/config/presets/models/qwen3.json +9 -2
- package/src/config/presets/models/transformer.json +5 -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/platform/metal-apple-q4k.json +1 -1
- package/src/config/required-inference-fields-contract-check.js +6 -0
- package/src/config/runtime.js +6 -1
- 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 +6 -3
- package/src/config/schema/inference.schema.d.ts +9 -0
- package/src/config/schema/kernel-path.schema.d.ts +11 -1
- package/src/config/schema/kernel-thresholds.schema.js +12 -4
- package/src/config/schema/manifest.schema.d.ts +8 -1
- package/src/config/schema/manifest.schema.js +19 -3
- package/src/config/training-defaults.js +30 -22
- package/src/converter/conversion-plan.js +94 -9
- package/src/converter/core.d.ts +7 -0
- package/src/converter/core.js +14 -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 +43 -12
- package/src/converter/parsers/diffusion.js +0 -3
- package/src/converter/quantization-info.js +35 -15
- package/src/converter/rope-config.js +42 -0
- package/src/converter/shard-packer.d.ts +1 -1
- package/src/converter/shard-packer.js +4 -1
- package/src/debug/config.js +123 -11
- 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 +77 -26
- 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.js +39 -2
- 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 +131 -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 +113 -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/bias_add.wgsl +8 -6
- package/src/gpu/kernels/bias_add_f16.wgsl +8 -5
- 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/conv2d.wgsl +7 -8
- package/src/gpu/kernels/conv2d_f16.wgsl +7 -8
- package/src/gpu/kernels/cross_entropy_loss.js +21 -15
- package/src/gpu/kernels/depthwise_conv2d.js +37 -26
- package/src/gpu/kernels/depthwise_conv2d.wgsl +6 -9
- package/src/gpu/kernels/depthwise_conv2d_f16.wgsl +6 -9
- 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 +34 -23
- package/src/gpu/kernels/grouped_pointwise_conv2d.wgsl +6 -9
- package/src/gpu/kernels/grouped_pointwise_conv2d_f16.wgsl +6 -9
- package/src/gpu/kernels/groupnorm.js +34 -23
- 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.js +83 -39
- 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/pixel_shuffle.wgsl +4 -5
- package/src/gpu/kernels/pixel_shuffle_f16.wgsl +4 -5
- package/src/gpu/kernels/relu.js +31 -10
- package/src/gpu/kernels/relu.wgsl +2 -1
- package/src/gpu/kernels/relu_f16.wgsl +2 -1
- package/src/gpu/kernels/repeat_channels.js +25 -17
- package/src/gpu/kernels/repeat_channels.wgsl +4 -5
- package/src/gpu/kernels/repeat_channels_f16.wgsl +4 -5
- package/src/gpu/kernels/residual.js +69 -23
- package/src/gpu/kernels/residual.wgsl +6 -3
- package/src/gpu/kernels/residual_f16.wgsl +2 -1
- package/src/gpu/kernels/residual_f16_vec4.wgsl +2 -1
- package/src/gpu/kernels/residual_vec4.wgsl +2 -1
- package/src/gpu/kernels/rmsnorm.js +96 -28
- package/src/gpu/kernels/rmsnorm.wgsl +14 -6
- package/src/gpu/kernels/rmsnorm_f16.wgsl +10 -2
- package/src/gpu/kernels/rope.d.ts +2 -0
- package/src/gpu/kernels/rope.js +14 -1
- package/src/gpu/kernels/rope.wgsl +56 -40
- package/src/gpu/kernels/sample.js +27 -38
- package/src/gpu/kernels/sana_linear_attention.js +19 -12
- package/src/gpu/kernels/sana_linear_attention_apply.wgsl +4 -5
- package/src/gpu/kernels/sana_linear_attention_apply_f16.wgsl +4 -5
- package/src/gpu/kernels/sana_linear_attention_summary.wgsl +4 -0
- package/src/gpu/kernels/sana_linear_attention_summary_f16.wgsl +4 -0
- package/src/gpu/kernels/scale.js +18 -11
- package/src/gpu/kernels/shader-cache.js +4 -2
- package/src/gpu/kernels/silu.d.ts +1 -0
- package/src/gpu/kernels/silu.js +148 -82
- package/src/gpu/kernels/silu.wgsl +19 -9
- package/src/gpu/kernels/silu_f16.wgsl +19 -9
- package/src/gpu/kernels/softmax.js +44 -25
- package/src/gpu/kernels/split_qkv.js +23 -13
- package/src/gpu/kernels/transpose.js +31 -10
- package/src/gpu/kernels/transpose.wgsl +6 -5
- package/src/gpu/kernels/upsample2d.js +22 -13
- package/src/gpu/kernels/upsample2d.wgsl +6 -9
- package/src/gpu/kernels/upsample2d_f16.wgsl +6 -9
- package/src/gpu/kernels/utils.js +35 -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/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 +6 -0
- package/src/inference/browser-harness.js +130 -1950
- 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 +7 -2
- package/src/inference/pipelines/diffusion/pipeline.js +17 -7
- package/src/inference/pipelines/diffusion/sd3-transformer.js +10 -10
- package/src/inference/pipelines/diffusion/text-encoder-gpu.d.ts +5 -0
- package/src/inference/pipelines/diffusion/text-encoder-gpu.js +27 -15
- 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/projections.js +151 -101
- package/src/inference/pipelines/text/attention/record.js +73 -10
- package/src/inference/pipelines/text/attention/run.js +73 -10
- package/src/inference/pipelines/text/chat-format.js +25 -1
- package/src/inference/pipelines/text/config.d.ts +4 -0
- package/src/inference/pipelines/text/config.js +71 -5
- package/src/inference/pipelines/text/embed.js +2 -8
- package/src/inference/pipelines/text/execution-plan.js +64 -50
- 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 +78 -1002
- package/src/inference/pipelines/text/ffn/standard.js +3 -0
- package/src/inference/pipelines/text/generator-steps.d.ts +46 -0
- package/src/inference/pipelines/text/generator-steps.js +298 -207
- package/src/inference/pipelines/text/generator.js +6 -23
- package/src/inference/pipelines/text/init.d.ts +4 -0
- package/src/inference/pipelines/text/init.js +134 -29
- 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 +14 -9
- package/src/inference/pipelines/text/linear-attention.d.ts +10 -0
- package/src/inference/pipelines/text/linear-attention.js +80 -6
- package/src/inference/pipelines/text/logits/gpu.js +10 -5
- package/src/inference/pipelines/text/logits/index.js +10 -11
- 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 +279 -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/weights.js +17 -7
- package/src/inference/pipelines/text.js +17 -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 +15 -5
- 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 +176 -33
- 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 +8 -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 +81 -12
- package/src/loader/shard-resolver.js +25 -3
- package/src/loader/tensors/tensor-loader.js +209 -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/kernel-path.rules.json +24 -8
- package/src/rules/rule-registry.js +25 -1
- package/src/rules/tooling/command-runtime.rules.json +18 -0
- package/src/storage/backends/opfs-store.js +68 -24
- package/src/storage/downloader.js +364 -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 +51 -3
- 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.d.ts +27 -1
- package/src/tooling/command-api.js +26 -473
- package/src/tooling/command-envelope.js +4 -1
- package/src/tooling/command-runner-shared.js +52 -18
- package/src/tooling/lean-execution-contract.js +150 -3
- package/src/tooling/node-browser-command-runner.d.ts +4 -0
- package/src/tooling/node-browser-command-runner.js +218 -273
- package/src/tooling/node-command-runner.js +44 -3
- package/src/tooling/node-converter.js +27 -1
- package/src/tooling/node-source-runtime.d.ts +1 -1
- package/src/tooling/node-source-runtime.js +84 -3
- package/src/tooling/node-webgpu.js +30 -105
- 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 +8 -0
- package/src/training/checkpoint-watch.js +139 -0
- package/src/training/checkpoint.d.ts +6 -1
- package/src/training/checkpoint.js +46 -7
- package/src/training/clip.js +2 -1
- package/src/training/datasets/token-batch.js +20 -8
- package/src/training/distillation/artifacts.d.ts +71 -0
- package/src/training/distillation/artifacts.js +132 -0
- package/src/training/distillation/checkpoint-watch.d.ts +10 -0
- package/src/training/distillation/checkpoint-watch.js +58 -0
- package/src/training/distillation/dataset.d.ts +59 -0
- package/src/training/distillation/dataset.js +337 -0
- package/src/training/distillation/eval.d.ts +34 -0
- package/src/training/distillation/eval.js +310 -0
- package/src/training/distillation/index.d.ts +29 -0
- package/src/training/distillation/index.js +29 -0
- package/src/training/distillation/runtime.d.ts +20 -0
- package/src/training/distillation/runtime.js +121 -0
- package/src/training/distillation/scoreboard.d.ts +6 -0
- package/src/training/distillation/scoreboard.js +8 -0
- package/src/training/distillation/stage-a.d.ts +45 -0
- package/src/training/distillation/stage-a.js +338 -0
- package/src/training/distillation/stage-b.d.ts +24 -0
- package/src/training/distillation/stage-b.js +20 -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/index.d.ts +10 -0
- package/src/training/index.js +10 -0
- package/src/training/lora-pipeline.d.ts +40 -0
- package/src/training/lora-pipeline.js +793 -0
- 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-artifacts.d.ts +62 -0
- package/src/training/operator-artifacts.js +140 -0
- package/src/training/operator-command.d.ts +5 -0
- package/src/training/operator-command.js +455 -0
- package/src/training/operator-eval.d.ts +48 -0
- package/src/training/operator-eval.js +230 -0
- package/src/training/operator-scoreboard.d.ts +5 -0
- package/src/training/operator-scoreboard.js +44 -0
- package/src/training/optimizer.js +19 -7
- package/src/training/runner.d.ts +52 -0
- package/src/training/runner.js +31 -5
- package/src/training/suite.d.ts +112 -0
- package/src/training/suite.js +24 -984
- 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.d.ts +164 -0
- package/src/training/workloads.js +530 -0
- package/src/version.js +1 -1
- package/tools/convert-safetensors-node.js +22 -16
- package/tools/doppler-cli.js +179 -63
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function collectTrainingArtifactsFromSuiteResult(suiteResult) {
|
|
2
|
+
const ulArtifacts = [];
|
|
3
|
+
const distillArtifacts = [];
|
|
4
|
+
const checkpointResumeTimeline = Array.isArray(suiteResult?.metrics?.checkpointResumeTimeline)
|
|
5
|
+
? suiteResult.metrics.checkpointResumeTimeline
|
|
6
|
+
.filter((entry) => entry && typeof entry === 'object')
|
|
7
|
+
: [];
|
|
8
|
+
const addArtifact = (artifact, source = null) => {
|
|
9
|
+
if (!artifact || typeof artifact !== 'object' || typeof artifact.manifestPath !== 'string') {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const stage = String(artifact.stage || '').trim();
|
|
13
|
+
const kind = String(artifact.kind || '').trim();
|
|
14
|
+
if (kind === 'distill' || stage === 'stage_a' || stage === 'stage_b') {
|
|
15
|
+
distillArtifacts.push(artifact);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (kind === 'ul' || stage === 'stage1_joint' || stage === 'stage2_base' || source === 'ul') {
|
|
19
|
+
ulArtifacts.push(artifact);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
ulArtifacts.push(artifact);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const metricUlArtifacts = Array.isArray(suiteResult?.metrics?.ulArtifacts)
|
|
26
|
+
? suiteResult.metrics.ulArtifacts
|
|
27
|
+
: [];
|
|
28
|
+
for (const artifact of metricUlArtifacts) {
|
|
29
|
+
addArtifact(artifact, 'ul');
|
|
30
|
+
}
|
|
31
|
+
const metricDistillArtifacts = Array.isArray(suiteResult?.metrics?.distillArtifacts)
|
|
32
|
+
? suiteResult.metrics.distillArtifacts
|
|
33
|
+
: [];
|
|
34
|
+
for (const artifact of metricDistillArtifacts) {
|
|
35
|
+
addArtifact(artifact, 'distill');
|
|
36
|
+
}
|
|
37
|
+
const resultEntries = Array.isArray(suiteResult?.results) ? suiteResult.results : [];
|
|
38
|
+
for (const entry of resultEntries) {
|
|
39
|
+
addArtifact(entry?.artifact, null);
|
|
40
|
+
}
|
|
41
|
+
return { ulArtifacts, distillArtifacts, checkpointResumeTimeline };
|
|
42
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export declare function parseReportTimestamp(
|
|
2
|
+
rawTimestamp: string | number | Date | null | undefined,
|
|
3
|
+
label?: string
|
|
4
|
+
): string | null;
|
|
5
|
+
export declare function resolveReportTimestamp(
|
|
6
|
+
rawTimestamp: string | number | Date | null | undefined,
|
|
7
|
+
label: string,
|
|
8
|
+
fallbackTimestamp?: string | null
|
|
9
|
+
): string;
|
|
10
|
+
export declare function resolveRuntime(options: Record<string, unknown>): Record<string, unknown>;
|
|
11
|
+
export declare function cloneRuntimeConfig(runtimeConfig: Record<string, unknown> | null | undefined): Record<string, unknown> | null;
|
|
12
|
+
export declare function snapshotRuntimeState(): {
|
|
13
|
+
runtimeConfig: Record<string, unknown> | null;
|
|
14
|
+
activeKernelPath: unknown;
|
|
15
|
+
activeKernelPathSource: string | null;
|
|
16
|
+
activeKernelPathPolicy: unknown;
|
|
17
|
+
};
|
|
18
|
+
export declare function restoreRuntimeState(snapshot: Record<string, unknown> | null | undefined): void;
|
|
19
|
+
export declare function runWithRuntimeIsolationForSuite<T>(run: () => Promise<T>): Promise<T>;
|
|
20
|
+
export declare function sanitizeReportOutput(output: unknown): unknown;
|
|
21
|
+
export declare function loadRuntimeConfigFromRef(
|
|
22
|
+
ref: string,
|
|
23
|
+
context: Record<string, unknown>
|
|
24
|
+
): Promise<{ config: Record<string, unknown>; runtime: Record<string, unknown> }>;
|
|
25
|
+
export declare function loadRuntimeConfigFromUrl(
|
|
26
|
+
url: string,
|
|
27
|
+
options?: Record<string, unknown>
|
|
28
|
+
): Promise<{ config: Record<string, unknown>; runtime: Record<string, unknown> }>;
|
|
29
|
+
export declare function applyRuntimeConfigFromUrl(
|
|
30
|
+
url: string,
|
|
31
|
+
options?: Record<string, unknown>
|
|
32
|
+
): Promise<Record<string, unknown>>;
|
|
33
|
+
export declare function loadRuntimePreset(
|
|
34
|
+
presetId: string,
|
|
35
|
+
options?: Record<string, unknown>
|
|
36
|
+
): Promise<{ config: Record<string, unknown>; runtime: Record<string, unknown> }>;
|
|
37
|
+
export declare function applyRuntimePreset(
|
|
38
|
+
presetId: string,
|
|
39
|
+
options?: Record<string, unknown>
|
|
40
|
+
): Promise<Record<string, unknown>>;
|
|
41
|
+
export declare function normalizeRuntimeConfigChain(value: unknown): string[];
|
|
42
|
+
export declare function applyRuntimeForRun(
|
|
43
|
+
run: Record<string, unknown>,
|
|
44
|
+
options?: Record<string, unknown>
|
|
45
|
+
): Promise<void>;
|
|
46
|
+
export declare function normalizeManifest(manifest: Record<string, unknown>): {
|
|
47
|
+
defaults: Record<string, unknown>;
|
|
48
|
+
runs: Array<Record<string, unknown>>;
|
|
49
|
+
reportModelId: string;
|
|
50
|
+
report: Record<string, unknown> | null;
|
|
51
|
+
};
|
|
52
|
+
export declare function mergeRunDefaults(
|
|
53
|
+
defaults: Record<string, unknown>,
|
|
54
|
+
run: Record<string, unknown>
|
|
55
|
+
): Record<string, unknown>;
|
|
56
|
+
export declare function summarizeManifestRuns(results: Array<Record<string, unknown>>): {
|
|
57
|
+
totalRuns: number;
|
|
58
|
+
passedRuns: number;
|
|
59
|
+
failedRuns: number;
|
|
60
|
+
durationMs: number;
|
|
61
|
+
};
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { parseRuntimeOverridesFromURL } from './test-harness.js';
|
|
2
|
+
import { getRuntimeConfig, setRuntimeConfig } from '../config/runtime.js';
|
|
3
|
+
import {
|
|
4
|
+
setActiveKernelPath,
|
|
5
|
+
getActiveKernelPath,
|
|
6
|
+
getActiveKernelPathSource,
|
|
7
|
+
getActiveKernelPathPolicy,
|
|
8
|
+
} from '../config/kernel-path-loader.js';
|
|
9
|
+
import { mergeRuntimeValues } from '../config/runtime-merge.js';
|
|
10
|
+
import { buildRuntimeContractPatch } from '../tooling/command-api.js';
|
|
11
|
+
import {
|
|
12
|
+
applyOrderedRuntimeInputs,
|
|
13
|
+
resolveRuntimeFromConfig,
|
|
14
|
+
} from '../tooling/runtime-input-composition.js';
|
|
15
|
+
|
|
16
|
+
export function parseReportTimestamp(rawTimestamp, label = 'timestamp') {
|
|
17
|
+
if (rawTimestamp == null) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (rawTimestamp instanceof Date) {
|
|
22
|
+
const timestamp = rawTimestamp.getTime();
|
|
23
|
+
if (!Number.isFinite(timestamp)) {
|
|
24
|
+
throw new Error(`Invalid ${label}: not a valid Date.`);
|
|
25
|
+
}
|
|
26
|
+
return rawTimestamp.toISOString();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof rawTimestamp === 'number') {
|
|
30
|
+
if (!Number.isFinite(rawTimestamp)) {
|
|
31
|
+
throw new Error(`Invalid ${label}: must be a finite epoch timestamp.`);
|
|
32
|
+
}
|
|
33
|
+
return new Date(rawTimestamp).toISOString();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (typeof rawTimestamp === 'string') {
|
|
37
|
+
const trimmed = rawTimestamp.trim();
|
|
38
|
+
if (trimmed.length === 0) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const numericCandidate = Number(trimmed);
|
|
42
|
+
if (Number.isFinite(numericCandidate)) {
|
|
43
|
+
return new Date(numericCandidate).toISOString();
|
|
44
|
+
}
|
|
45
|
+
const parsed = new Date(trimmed);
|
|
46
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
47
|
+
throw new Error(`Invalid ${label}: expected ISO-8601 string or epoch milliseconds.`);
|
|
48
|
+
}
|
|
49
|
+
return parsed.toISOString();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
throw new Error(`Invalid ${label}: expected Date, ISO-8601 string, epoch milliseconds, or nullish.`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function resolveReportTimestamp(rawTimestamp, label, fallbackTimestamp = null) {
|
|
56
|
+
const parsed = parseReportTimestamp(rawTimestamp, label);
|
|
57
|
+
return parsed ?? (fallbackTimestamp == null ? new Date().toISOString() : String(fallbackTimestamp));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function resolveRuntime(options) {
|
|
61
|
+
if (options.runtime) return options.runtime;
|
|
62
|
+
if (options.searchParams) return parseRuntimeOverridesFromURL(options.searchParams);
|
|
63
|
+
const runtimeConfig = cloneRuntimeConfig(getRuntimeConfig());
|
|
64
|
+
const runtime = typeof globalThis.location === 'undefined'
|
|
65
|
+
? parseRuntimeOverridesFromURL(new URLSearchParams())
|
|
66
|
+
: parseRuntimeOverridesFromURL();
|
|
67
|
+
if (runtimeConfig) {
|
|
68
|
+
runtime.runtimeConfig = runtime.runtimeConfig
|
|
69
|
+
? mergeRuntimeValues(runtimeConfig, runtime.runtimeConfig)
|
|
70
|
+
: runtimeConfig;
|
|
71
|
+
}
|
|
72
|
+
return runtime;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function normalizePresetPath(value) {
|
|
76
|
+
const trimmed = String(value || '').replace(/^[./]+/, '');
|
|
77
|
+
if (!trimmed) return null;
|
|
78
|
+
return trimmed.endsWith('.json') ? trimmed : `${trimmed}.json`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function resolvePresetBaseUrl() {
|
|
82
|
+
try {
|
|
83
|
+
return new URL('../config/presets/runtime/', import.meta.url).toString().replace(/\/$/, '');
|
|
84
|
+
} catch {
|
|
85
|
+
if (typeof globalThis.location !== 'undefined' && globalThis.location?.href) {
|
|
86
|
+
return new URL('/src/config/presets/runtime/', globalThis.location.href).toString().replace(/\/$/, '');
|
|
87
|
+
}
|
|
88
|
+
return '/src/config/presets/runtime';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function cloneRuntimeConfig(runtimeConfig) {
|
|
93
|
+
if (!runtimeConfig) return null;
|
|
94
|
+
if (typeof structuredClone === 'function') {
|
|
95
|
+
return structuredClone(runtimeConfig);
|
|
96
|
+
}
|
|
97
|
+
return JSON.parse(JSON.stringify(runtimeConfig));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function snapshotRuntimeState() {
|
|
101
|
+
return {
|
|
102
|
+
runtimeConfig: cloneRuntimeConfig(getRuntimeConfig()),
|
|
103
|
+
activeKernelPath: getActiveKernelPath(),
|
|
104
|
+
activeKernelPathSource: getActiveKernelPathSource(),
|
|
105
|
+
activeKernelPathPolicy: getActiveKernelPathPolicy(),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function restoreRuntimeState(snapshot) {
|
|
110
|
+
if (!snapshot) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
setRuntimeConfig(snapshot.runtimeConfig);
|
|
114
|
+
setActiveKernelPath(
|
|
115
|
+
snapshot.activeKernelPath,
|
|
116
|
+
snapshot.activeKernelPathSource || 'none',
|
|
117
|
+
snapshot.activeKernelPathPolicy ?? null
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function runWithRuntimeIsolationForSuite(run) {
|
|
122
|
+
const snapshot = snapshotRuntimeState();
|
|
123
|
+
try {
|
|
124
|
+
return await run();
|
|
125
|
+
} finally {
|
|
126
|
+
restoreRuntimeState(snapshot);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function sanitizeReportOutput(output) {
|
|
131
|
+
if (output == null) return null;
|
|
132
|
+
if (typeof output !== 'object') return output;
|
|
133
|
+
if (ArrayBuffer.isView(output)) {
|
|
134
|
+
return {
|
|
135
|
+
type: output.constructor?.name || 'TypedArray',
|
|
136
|
+
length: Number.isFinite(output.length) ? output.length : null,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (
|
|
140
|
+
Number.isFinite(output?.width)
|
|
141
|
+
&& Number.isFinite(output?.height)
|
|
142
|
+
&& ArrayBuffer.isView(output?.pixels)
|
|
143
|
+
) {
|
|
144
|
+
const { pixels, ...rest } = output;
|
|
145
|
+
return {
|
|
146
|
+
...rest,
|
|
147
|
+
width: output.width,
|
|
148
|
+
height: output.height,
|
|
149
|
+
pixels: {
|
|
150
|
+
type: pixels.constructor?.name || 'TypedArray',
|
|
151
|
+
length: Number.isFinite(pixels.length) ? pixels.length : null,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return output;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function normalizeExtends(value) {
|
|
159
|
+
if (Array.isArray(value)) {
|
|
160
|
+
return value.map((entry) => String(entry || '').trim()).filter(Boolean);
|
|
161
|
+
}
|
|
162
|
+
if (typeof value === 'string') {
|
|
163
|
+
const trimmed = value.trim();
|
|
164
|
+
return trimmed ? [trimmed] : [];
|
|
165
|
+
}
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function normalizeExtendsPath(value) {
|
|
170
|
+
const trimmed = String(value || '').trim();
|
|
171
|
+
if (!trimmed) return null;
|
|
172
|
+
return trimmed.endsWith('.json') ? trimmed : `${trimmed}.json`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function resolveAbsoluteUrl(target, base) {
|
|
176
|
+
try {
|
|
177
|
+
if (base) {
|
|
178
|
+
return new URL(target, base).toString();
|
|
179
|
+
}
|
|
180
|
+
if (typeof globalThis.location !== 'undefined' && globalThis.location?.href) {
|
|
181
|
+
return new URL(target, globalThis.location.href).toString();
|
|
182
|
+
}
|
|
183
|
+
return new URL(target, import.meta.url).toString();
|
|
184
|
+
} catch {
|
|
185
|
+
return target;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function isAbsoluteUrl(value) {
|
|
190
|
+
return /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(value);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function joinUrl(base, path) {
|
|
194
|
+
if (!base) return path;
|
|
195
|
+
if (isAbsoluteUrl(base)) {
|
|
196
|
+
return new URL(path, base.endsWith('/') ? base : `${base}/`).toString();
|
|
197
|
+
}
|
|
198
|
+
const normalizedBase = base.replace(/\/$/, '');
|
|
199
|
+
const normalizedPath = path.replace(/^\//, '');
|
|
200
|
+
return `${normalizedBase}/${normalizedPath}`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function resolveExtendCandidates(ref, context) {
|
|
204
|
+
const normalized = normalizeExtendsPath(ref);
|
|
205
|
+
if (!normalized) return [];
|
|
206
|
+
if (isAbsoluteUrl(normalized) || normalized.startsWith('/')) {
|
|
207
|
+
return [normalized];
|
|
208
|
+
}
|
|
209
|
+
if (normalized.startsWith('./') || normalized.startsWith('../')) {
|
|
210
|
+
return [resolveAbsoluteUrl(normalized, context.sourceUrl)];
|
|
211
|
+
}
|
|
212
|
+
if (normalized.includes('/')) {
|
|
213
|
+
return [joinUrl(context.presetBaseUrl, normalized)];
|
|
214
|
+
}
|
|
215
|
+
const candidates = [];
|
|
216
|
+
if (context.presetBaseUrl) {
|
|
217
|
+
candidates.push(joinUrl(context.presetBaseUrl, normalized));
|
|
218
|
+
candidates.push(joinUrl(context.presetBaseUrl, `modes/${normalized}`));
|
|
219
|
+
}
|
|
220
|
+
if (context.sourceUrl) {
|
|
221
|
+
const sourceDir = resolveAbsoluteUrl('./', context.sourceUrl);
|
|
222
|
+
candidates.push(resolveAbsoluteUrl(normalized, sourceDir));
|
|
223
|
+
}
|
|
224
|
+
return [...new Set(candidates)];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function fetchRuntimeConfig(url, options = {}) {
|
|
228
|
+
const response = await fetch(url, { signal: options.signal });
|
|
229
|
+
if (!response.ok) {
|
|
230
|
+
const error = new Error(`Failed to load runtime config: ${response.status}`);
|
|
231
|
+
error.code = response.status === 404 ? 'runtime_config_not_found' : 'runtime_config_fetch_failed';
|
|
232
|
+
throw error;
|
|
233
|
+
}
|
|
234
|
+
return response.json();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function resolveRuntimeConfigExtends(config, context) {
|
|
238
|
+
const runtime = resolveRuntimeFromConfig(config);
|
|
239
|
+
if (!runtime) {
|
|
240
|
+
throw new Error('Runtime config is missing runtime fields');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const extendsRefs = normalizeExtends(config.extends);
|
|
244
|
+
let mergedRuntime = null;
|
|
245
|
+
let mergedConfig = null;
|
|
246
|
+
|
|
247
|
+
for (const ref of extendsRefs) {
|
|
248
|
+
const base = await loadRuntimeConfigFromRef(ref, context);
|
|
249
|
+
mergedRuntime = mergedRuntime ? mergeRuntimeValues(mergedRuntime, base.runtime) : base.runtime;
|
|
250
|
+
mergedConfig = mergedConfig ? mergeRuntimeValues(mergedConfig, base.config) : base.config;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const combinedRuntime = mergedRuntime ? mergeRuntimeValues(mergedRuntime, runtime) : runtime;
|
|
254
|
+
const combinedConfig = mergedConfig ? mergeRuntimeValues(mergedConfig, config) : { ...config };
|
|
255
|
+
const resolved = { ...combinedConfig, runtime: combinedRuntime };
|
|
256
|
+
if (resolved.extends !== undefined) {
|
|
257
|
+
delete resolved.extends;
|
|
258
|
+
}
|
|
259
|
+
return { config: resolved, runtime: combinedRuntime };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function loadRuntimeConfigChain(url, options = {}, stack = []) {
|
|
263
|
+
const presetBaseUrl = options.presetBaseUrl || options.baseUrl || resolvePresetBaseUrl();
|
|
264
|
+
const resolvedUrl = resolveAbsoluteUrl(url);
|
|
265
|
+
if (stack.includes(resolvedUrl)) {
|
|
266
|
+
throw new Error(`Runtime config extends cycle: ${[...stack, resolvedUrl].join(' -> ')}`);
|
|
267
|
+
}
|
|
268
|
+
const config = await fetchRuntimeConfig(resolvedUrl, options);
|
|
269
|
+
return resolveRuntimeConfigExtends(config, {
|
|
270
|
+
...options,
|
|
271
|
+
sourceUrl: resolvedUrl,
|
|
272
|
+
presetBaseUrl,
|
|
273
|
+
stack: [...stack, resolvedUrl],
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export async function loadRuntimeConfigFromRef(ref, context) {
|
|
278
|
+
const candidates = resolveExtendCandidates(ref, context);
|
|
279
|
+
if (!candidates.length) {
|
|
280
|
+
throw new Error(`Runtime config extends is invalid: ${ref}`);
|
|
281
|
+
}
|
|
282
|
+
let lastError = null;
|
|
283
|
+
for (const candidate of candidates) {
|
|
284
|
+
try {
|
|
285
|
+
return await loadRuntimeConfigChain(candidate, context, context.stack ?? []);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
if (error?.code === 'runtime_config_not_found') {
|
|
288
|
+
lastError = error;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
throw error;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (lastError) {
|
|
295
|
+
throw lastError;
|
|
296
|
+
}
|
|
297
|
+
throw new Error(`Runtime config extends not found: ${ref}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export async function loadRuntimeConfigFromUrl(url, options = {}) {
|
|
301
|
+
if (!url) {
|
|
302
|
+
throw new Error('runtime config url is required');
|
|
303
|
+
}
|
|
304
|
+
return loadRuntimeConfigChain(url, options);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export async function applyRuntimeConfigFromUrl(url, options = {}) {
|
|
308
|
+
const { runtime } = await loadRuntimeConfigFromUrl(url, options);
|
|
309
|
+
const mergedRuntime = mergeRuntimeValues(getRuntimeConfig(), runtime);
|
|
310
|
+
setRuntimeConfig(mergedRuntime);
|
|
311
|
+
return mergedRuntime;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export async function loadRuntimePreset(presetId, options = {}) {
|
|
315
|
+
const baseUrl = options.baseUrl || resolvePresetBaseUrl();
|
|
316
|
+
const normalized = normalizePresetPath(presetId);
|
|
317
|
+
if (!normalized) {
|
|
318
|
+
throw new Error('runtime preset id is required');
|
|
319
|
+
}
|
|
320
|
+
const url = `${baseUrl.replace(/\/$/, '')}/${normalized}`;
|
|
321
|
+
return loadRuntimeConfigFromUrl(url, { ...options, presetBaseUrl: baseUrl });
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export async function applyRuntimePreset(presetId, options = {}) {
|
|
325
|
+
const { runtime } = await loadRuntimePreset(presetId, options);
|
|
326
|
+
const mergedRuntime = mergeRuntimeValues(getRuntimeConfig(), runtime);
|
|
327
|
+
setRuntimeConfig(mergedRuntime);
|
|
328
|
+
return mergedRuntime;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export function normalizeRuntimeConfigChain(value) {
|
|
332
|
+
if (!Array.isArray(value)) {
|
|
333
|
+
return [];
|
|
334
|
+
}
|
|
335
|
+
return value
|
|
336
|
+
.map((entry) => typeof entry === 'string' ? entry.trim() : '')
|
|
337
|
+
.filter(Boolean);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export async function applyRuntimeForRun(run, options = {}) {
|
|
341
|
+
const configChain = normalizeRuntimeConfigChain(
|
|
342
|
+
run.configChain
|
|
343
|
+
?? run.runtime?.configChain
|
|
344
|
+
?? options.runtime?.configChain
|
|
345
|
+
);
|
|
346
|
+
await applyOrderedRuntimeInputs({
|
|
347
|
+
getRuntimeConfig,
|
|
348
|
+
setRuntimeConfig,
|
|
349
|
+
}, {
|
|
350
|
+
configChain,
|
|
351
|
+
runtimePreset: run.runtimePreset ?? null,
|
|
352
|
+
runtimeConfigUrl: run.runtimeConfigUrl ?? null,
|
|
353
|
+
runtimeConfig: run.runtimeConfig ?? null,
|
|
354
|
+
runtimeContractPatch: typeof run.command === 'string' && run.command.trim()
|
|
355
|
+
? () => buildRuntimeContractPatch({
|
|
356
|
+
...run,
|
|
357
|
+
configChain: undefined,
|
|
358
|
+
modelId: run.modelId ?? null,
|
|
359
|
+
})
|
|
360
|
+
: null,
|
|
361
|
+
}, {
|
|
362
|
+
loadRuntimeConfigFromRef: (ref, runtimeOptions) => loadRuntimeConfigFromRef(ref, runtimeOptions),
|
|
363
|
+
applyRuntimePreset,
|
|
364
|
+
applyRuntimeConfigFromUrl,
|
|
365
|
+
}, options);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function normalizeManifest(manifest) {
|
|
369
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
370
|
+
throw new Error('Harness manifest must be an object.');
|
|
371
|
+
}
|
|
372
|
+
const runs = Array.isArray(manifest.runs) ? manifest.runs : [];
|
|
373
|
+
if (!runs.length) {
|
|
374
|
+
throw new Error('Harness manifest must include at least one run.');
|
|
375
|
+
}
|
|
376
|
+
return {
|
|
377
|
+
defaults: manifest.defaults ?? {},
|
|
378
|
+
runs,
|
|
379
|
+
reportModelId: manifest.reportModelId ?? manifest.id ?? 'manifest',
|
|
380
|
+
report: manifest.report ?? null,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export function mergeRunDefaults(defaults, run) {
|
|
385
|
+
return {
|
|
386
|
+
...defaults,
|
|
387
|
+
...run,
|
|
388
|
+
configChain: run.configChain ?? defaults.configChain ?? null,
|
|
389
|
+
runtimePreset: run.runtimePreset ?? defaults.runtimePreset ?? null,
|
|
390
|
+
runtimeConfigUrl: run.runtimeConfigUrl ?? defaults.runtimeConfigUrl ?? null,
|
|
391
|
+
runtimeConfig: run.runtimeConfig ?? defaults.runtimeConfig ?? null,
|
|
392
|
+
suite: run.suite ?? defaults.suite ?? 'inference',
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export function summarizeManifestRuns(results) {
|
|
397
|
+
let passedRuns = 0;
|
|
398
|
+
let failedRuns = 0;
|
|
399
|
+
let durationMs = 0;
|
|
400
|
+
for (const result of results) {
|
|
401
|
+
const failures = (result.results || []).filter((entry) => !entry.passed && !entry.skipped);
|
|
402
|
+
if (failures.length > 0) {
|
|
403
|
+
failedRuns += 1;
|
|
404
|
+
} else {
|
|
405
|
+
passedRuns += 1;
|
|
406
|
+
}
|
|
407
|
+
durationMs += result.duration || 0;
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
totalRuns: results.length,
|
|
411
|
+
passedRuns,
|
|
412
|
+
failedRuns,
|
|
413
|
+
durationMs,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare function buildSuiteSummary(
|
|
2
|
+
suiteName: string,
|
|
3
|
+
results: Array<Record<string, unknown>>,
|
|
4
|
+
startTimeMs: number
|
|
5
|
+
): {
|
|
6
|
+
suite: string;
|
|
7
|
+
passed: number;
|
|
8
|
+
failed: number;
|
|
9
|
+
skipped: number;
|
|
10
|
+
duration: number;
|
|
11
|
+
results: Array<Record<string, unknown>>;
|
|
12
|
+
};
|
|
13
|
+
export declare function normalizeCacheMode(value: unknown): 'cold' | 'warm';
|
|
14
|
+
export declare function normalizeLoadMode(value: unknown, hasModelUrl: boolean): 'opfs' | 'http' | 'memory';
|
|
15
|
+
export declare function normalizeWorkloadType(value: unknown): string | null;
|
|
16
|
+
export declare function safeStatsValue(value: unknown): number;
|
|
17
|
+
export declare function calculateRatePerSecond(count: unknown, durationMs: unknown): number;
|
|
18
|
+
export declare function buildDiffusionPerformanceArtifact(options: Record<string, unknown>): Record<string, unknown>;
|
|
19
|
+
export declare function assertDiffusionPerformanceArtifact(metrics: Record<string, unknown>, contextLabel?: string): void;
|
|
20
|
+
export declare function toTimingNumber(value: unknown, fallback?: number | null): number | null;
|
|
21
|
+
export declare function safeToFixed(value: unknown, fallback?: number | null, digits?: number): number | null;
|
|
22
|
+
export declare function sampleTimingNumber(
|
|
23
|
+
stats: Record<string, unknown> | null | undefined,
|
|
24
|
+
key: string,
|
|
25
|
+
fallback?: number | null
|
|
26
|
+
): number | null;
|
|
27
|
+
export declare function buildCanonicalTiming(overrides?: Record<string, unknown>): Record<string, unknown>;
|
|
28
|
+
export declare function buildTimingDiagnostics(timing?: Record<string, unknown>, options?: Record<string, unknown>): Record<string, unknown>;
|