@simulatte/doppler 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -10
- package/package.json +30 -6
- package/src/client/doppler-api.browser.d.ts +1 -0
- package/src/client/doppler-api.browser.js +288 -0
- package/src/client/doppler-api.js +1 -1
- package/src/client/doppler-provider/types.js +1 -1
- package/src/config/execution-contract-check.d.ts +33 -0
- package/src/config/execution-contract-check.js +72 -0
- package/src/config/execution-v0-contract-check.d.ts +94 -0
- package/src/config/execution-v0-contract-check.js +251 -0
- package/src/config/execution-v0-graph-contract-check.d.ts +20 -0
- package/src/config/execution-v0-graph-contract-check.js +64 -0
- package/src/config/kernel-path-contract-check.d.ts +76 -0
- package/src/config/kernel-path-contract-check.js +479 -0
- package/src/config/kernel-path-loader.d.ts +16 -0
- package/src/config/kernel-path-loader.js +54 -0
- package/src/config/kernels/kernel-ref-digests.js +39 -27
- package/src/config/kernels/registry.json +598 -2
- package/src/config/loader.js +81 -48
- package/src/config/merge-contract-check.d.ts +16 -0
- package/src/config/merge-contract-check.js +321 -0
- package/src/config/merge-helpers.d.ts +58 -0
- package/src/config/merge-helpers.js +54 -0
- package/src/config/merge.js +21 -6
- package/src/config/presets/models/janus-text.json +2 -0
- package/src/config/presets/models/qwen3.json +9 -2
- package/src/config/presets/models/transformer.json +5 -0
- package/src/config/quantization-contract-check.d.ts +12 -0
- package/src/config/quantization-contract-check.js +91 -0
- package/src/config/required-inference-fields-contract-check.d.ts +24 -0
- package/src/config/required-inference-fields-contract-check.js +237 -0
- package/src/config/schema/browser-suite-metrics.schema.d.ts +17 -0
- package/src/config/schema/browser-suite-metrics.schema.js +46 -0
- package/src/config/schema/conversion-report.schema.d.ts +40 -0
- package/src/config/schema/conversion-report.schema.js +108 -0
- package/src/config/schema/doppler.schema.js +12 -18
- package/src/config/schema/index.d.ts +22 -0
- package/src/config/schema/index.js +18 -0
- package/src/config/schema/inference-defaults.schema.js +3 -0
- package/src/config/schema/inference.schema.d.ts +9 -0
- package/src/config/schema/kernel-path.schema.d.ts +6 -0
- package/src/config/schema/manifest.schema.d.ts +6 -0
- package/src/config/schema/manifest.schema.js +3 -0
- package/src/converter/core.d.ts +10 -0
- package/src/converter/core.js +27 -2
- package/src/converter/parsers/diffusion.js +63 -3
- package/src/converter/rope-config.js +42 -0
- package/src/gpu/device.js +58 -0
- package/src/gpu/kernels/attention.js +98 -0
- package/src/gpu/kernels/bias_add.wgsl +8 -6
- package/src/gpu/kernels/bias_add_f16.wgsl +8 -5
- package/src/gpu/kernels/conv2d.js +1 -1
- package/src/gpu/kernels/conv2d.wgsl +7 -8
- package/src/gpu/kernels/conv2d_f16.wgsl +7 -8
- package/src/gpu/kernels/depthwise_conv2d.d.ts +29 -0
- package/src/gpu/kernels/depthwise_conv2d.js +99 -0
- package/src/gpu/kernels/depthwise_conv2d.wgsl +55 -0
- package/src/gpu/kernels/depthwise_conv2d_f16.wgsl +59 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d.d.ts +27 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d.js +93 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d.wgsl +44 -0
- package/src/gpu/kernels/grouped_pointwise_conv2d_f16.wgsl +48 -0
- package/src/gpu/kernels/index.d.ts +30 -0
- package/src/gpu/kernels/index.js +25 -0
- package/src/gpu/kernels/matmul.js +25 -0
- package/src/gpu/kernels/pixel_shuffle.js +1 -1
- package/src/gpu/kernels/pixel_shuffle.wgsl +4 -5
- package/src/gpu/kernels/pixel_shuffle_f16.wgsl +4 -5
- package/src/gpu/kernels/relu.d.ts +18 -0
- package/src/gpu/kernels/relu.js +58 -0
- package/src/gpu/kernels/relu.wgsl +22 -0
- package/src/gpu/kernels/relu_f16.wgsl +24 -0
- package/src/gpu/kernels/repeat_channels.d.ts +21 -0
- package/src/gpu/kernels/repeat_channels.js +60 -0
- package/src/gpu/kernels/repeat_channels.wgsl +28 -0
- package/src/gpu/kernels/repeat_channels_f16.wgsl +30 -0
- package/src/gpu/kernels/residual.js +44 -8
- 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 +58 -6
- 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 +11 -1
- package/src/gpu/kernels/rope.wgsl +56 -40
- package/src/gpu/kernels/sana_linear_attention.d.ts +27 -0
- package/src/gpu/kernels/sana_linear_attention.js +121 -0
- package/src/gpu/kernels/sana_linear_attention_apply.wgsl +43 -0
- package/src/gpu/kernels/sana_linear_attention_apply_f16.wgsl +46 -0
- package/src/gpu/kernels/sana_linear_attention_summary.wgsl +51 -0
- package/src/gpu/kernels/sana_linear_attention_summary_f16.wgsl +53 -0
- package/src/gpu/kernels/silu.d.ts +1 -0
- package/src/gpu/kernels/silu.js +32 -14
- package/src/gpu/kernels/silu.wgsl +19 -9
- package/src/gpu/kernels/silu_f16.wgsl +19 -9
- package/src/gpu/kernels/transpose.js +15 -2
- package/src/gpu/kernels/transpose.wgsl +5 -6
- package/src/gpu/kernels/upsample2d.js +2 -1
- package/src/gpu/kernels/upsample2d.wgsl +6 -9
- package/src/gpu/kernels/upsample2d_f16.wgsl +6 -9
- package/src/gpu/kernels/utils.js +16 -1
- package/src/index-browser.d.ts +1 -1
- package/src/index-browser.js +2 -2
- package/src/index.js +1 -1
- package/src/inference/browser-harness.js +109 -23
- package/src/inference/pipelines/diffusion/init.js +14 -0
- package/src/inference/pipelines/diffusion/pipeline.js +215 -77
- package/src/inference/pipelines/diffusion/sana-transformer.d.ts +53 -0
- package/src/inference/pipelines/diffusion/sana-transformer.js +738 -0
- package/src/inference/pipelines/diffusion/scheduler.d.ts +17 -1
- package/src/inference/pipelines/diffusion/scheduler.js +91 -3
- package/src/inference/pipelines/diffusion/text-encoder-gpu.d.ts +11 -4
- package/src/inference/pipelines/diffusion/text-encoder-gpu.js +282 -0
- package/src/inference/pipelines/diffusion/text-encoder.js +18 -1
- package/src/inference/pipelines/diffusion/types.d.ts +4 -0
- package/src/inference/pipelines/diffusion/vae.js +782 -78
- package/src/inference/pipelines/text/attention/record.js +11 -2
- package/src/inference/pipelines/text/attention/run.js +11 -2
- package/src/inference/pipelines/text/chat-format.js +25 -1
- package/src/inference/pipelines/text/config.d.ts +9 -0
- package/src/inference/pipelines/text/config.js +69 -2
- package/src/inference/pipelines/text/execution-plan.js +23 -31
- package/src/inference/pipelines/text/execution-v0.js +43 -95
- package/src/inference/pipelines/text/ffn/standard.js +3 -0
- package/src/inference/pipelines/text/init.d.ts +4 -0
- package/src/inference/pipelines/text/init.js +56 -9
- package/src/inference/pipelines/text/layer.js +11 -0
- package/src/inference/pipelines/text.js +4 -0
- package/src/inference/tokenizers/bundled.js +156 -33
- package/src/rules/execution-rules-contract-check.d.ts +17 -0
- package/src/rules/execution-rules-contract-check.js +245 -0
- package/src/rules/kernels/depthwise-conv2d.rules.json +6 -0
- package/src/rules/kernels/grouped-pointwise-conv2d.rules.json +6 -0
- package/src/rules/kernels/relu.rules.json +6 -0
- package/src/rules/kernels/repeat-channels.rules.json +6 -0
- package/src/rules/kernels/sana-linear-attention.rules.json +6 -0
- package/src/rules/layer-pattern-contract-check.d.ts +17 -0
- package/src/rules/layer-pattern-contract-check.js +231 -0
- package/src/rules/rule-registry.d.ts +28 -0
- package/src/rules/rule-registry.js +38 -0
- package/src/rules/tooling/command-runtime.rules.json +18 -0
- package/src/tooling/command-api.d.ts +27 -1
- package/src/tooling/command-api.js +142 -3
- package/src/tooling/conversion-config-materializer.d.ts +24 -0
- package/src/tooling/conversion-config-materializer.js +99 -0
- package/src/tooling/lean-execution-contract-runner.d.ts +43 -0
- package/src/tooling/lean-execution-contract-runner.js +158 -0
- package/src/tooling/node-browser-command-runner.d.ts +4 -0
- package/src/tooling/node-browser-command-runner.js +58 -3
- package/src/tooling/node-command-runner.js +15 -0
- package/src/tooling/node-convert.d.ts +10 -0
- package/src/tooling/node-converter.js +59 -0
- package/src/tooling/node-webgpu.js +11 -89
- package/src/training/checkpoint-watch.d.ts +7 -0
- package/src/training/checkpoint-watch.js +106 -0
- package/src/training/checkpoint.d.ts +6 -1
- package/src/training/checkpoint.js +12 -2
- 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 +57 -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/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 +796 -0
- 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 +453 -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/runner.d.ts +52 -0
- package/src/training/runner.js +29 -4
- package/src/training/suite.d.ts +112 -0
- package/src/training/suite.js +9 -9
- package/src/training/workloads.d.ts +164 -0
- package/src/training/workloads.js +539 -0
- package/src/version.d.ts +2 -0
- package/src/version.js +2 -0
- package/tools/convert-safetensors-node.js +47 -0
- package/tools/doppler-cli.js +252 -41
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ for await (const token of model.generate('Hello, world')) {
|
|
|
22
22
|
}
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
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
|
|
25
|
+
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
26
|
|
|
27
27
|
## Why Doppler
|
|
28
28
|
|
|
@@ -36,11 +36,11 @@ Registry IDs resolve to hosted RDRR artifacts from `Clocksmith/rdrr` by default.
|
|
|
36
36
|
|
|
37
37
|
## Evidence
|
|
38
38
|
|
|
39
|
-

|
|
39
|
+

|
|
40
40
|
|
|
41
41
|
Snapshot artifacts:
|
|
42
|
-
- [g3-1b-p064-d064-t0-k1.compare.json](benchmarks/vendors/fixtures/g3-1b-p064-d064-t0-k1.compare.json)
|
|
43
|
-
- [lfm2-5-1-2b-p064-d064-t0-k1.compare.json](benchmarks/vendors/fixtures/lfm2-5-1-2b-p064-d064-t0-k1.compare.json)
|
|
42
|
+
- [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
|
+
- [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)
|
|
44
44
|
|
|
45
45
|
## Under the hood
|
|
46
46
|
|
|
@@ -67,7 +67,7 @@ const reply = await model.chatText([
|
|
|
67
67
|
]);
|
|
68
68
|
|
|
69
69
|
// LoRA hot-swap
|
|
70
|
-
await model.loadLoRA('oneshift-twoshift-redshift-blueshift');
|
|
70
|
+
await model.loadLoRA('https://example.com/adapters/oneshift-twoshift-redshift-blueshift/manifest.json');
|
|
71
71
|
|
|
72
72
|
// Convenience shorthand (caches model automatically)
|
|
73
73
|
for await (const token of doppler('Hello', { model: 'gemma3-270m' })) {
|
|
@@ -77,14 +77,30 @@ for await (const token of doppler('Hello', { model: 'gemma3-270m' })) {
|
|
|
77
77
|
|
|
78
78
|
## Documentation
|
|
79
79
|
|
|
80
|
-
- Docs index (canonical navigation): [docs/INDEX.md](docs/INDEX.md)
|
|
81
|
-
- First-run workflow: [docs/getting-started.md](docs/getting-started.md)
|
|
82
|
-
- Runtime config contract: [docs/config.md](docs/config.md)
|
|
83
|
-
- Architecture: [docs/architecture.md](docs/architecture.md)
|
|
80
|
+
- Docs index (canonical navigation): [docs/INDEX.md](https://github.com/clocksmith/doppler/blob/main/docs/INDEX.md)
|
|
81
|
+
- First-run workflow: [docs/getting-started.md](https://github.com/clocksmith/doppler/blob/main/docs/getting-started.md)
|
|
82
|
+
- Runtime config contract: [docs/config.md](https://github.com/clocksmith/doppler/blob/main/docs/config.md)
|
|
83
|
+
- Architecture: [docs/architecture.md](https://github.com/clocksmith/doppler/blob/main/docs/architecture.md)
|
|
84
|
+
- Generated model support table: [docs/model-support-matrix.md](https://github.com/clocksmith/doppler/blob/main/docs/model-support-matrix.md)
|
|
85
|
+
|
|
86
|
+
## Current model support
|
|
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).
|
|
84
99
|
|
|
85
100
|
## Environment requirements
|
|
86
101
|
|
|
87
|
-
- WebGPU
|
|
102
|
+
- WebGPU is required.
|
|
103
|
+
- Supported runtimes: WebGPU-capable browsers, or Node with a WebGPU provider.
|
|
88
104
|
- Chrome / Edge 113+ supported.
|
|
89
105
|
- Firefox support varies (typically behind a flag).
|
|
90
106
|
- Safari support is evolving.
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simulatte/doppler",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
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",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": {
|
|
9
|
-
"doppler": "
|
|
9
|
+
"doppler": "tools/doppler-cli.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"cli": "node tools/doppler-cli.js",
|
|
@@ -16,6 +16,16 @@
|
|
|
16
16
|
"bench": "node tools/doppler-cli.js bench",
|
|
17
17
|
"lean:check": "./lean/check.sh",
|
|
18
18
|
"lean:execution-contract": "node tools/lean-execution-contract.js",
|
|
19
|
+
"lean:execution-contract:sweep": "node tools/lean-execution-contract-sweep.js",
|
|
20
|
+
"lean:execution-contract:configs": "node tools/lean-execution-contract-config-sweep.js",
|
|
21
|
+
"ci:lean:execution-contract": "node tools/lean-execution-contract-sweep.js --root models",
|
|
22
|
+
"ci:lean:execution-contract:configs": "node tools/lean-execution-contract-config-sweep.js --config-root tools/configs/conversion --manifest-root models --require-manifest-match",
|
|
23
|
+
"contracts:check": "node tools/check-contract-artifacts.js",
|
|
24
|
+
"contracts:summary": "node tools/check-contract-artifacts.js --json",
|
|
25
|
+
"contracts:check:lean": "node tools/check-contract-artifacts.js --with-lean",
|
|
26
|
+
"contracts:summary:lean": "node tools/check-contract-artifacts.js --json --with-lean",
|
|
27
|
+
"ci:contracts:check": "node tools/check-contract-artifacts.js --with-lean --lean-require-manifest-match",
|
|
28
|
+
"reports:convert:summary": "node tools/summarize-conversion-reports.js",
|
|
19
29
|
"bench:chart": "node ./benchmarks/vendors/compare-chart.js",
|
|
20
30
|
"bench:chart:readme": "node ./benchmarks/vendors/compare-chart.js --preset readme-evidence",
|
|
21
31
|
"bench:architecture:chart": "node ./benchmarks/vendors/generate-architecture-overview-svg.js",
|
|
@@ -41,6 +51,8 @@
|
|
|
41
51
|
"agents:freshness:strict": "node tools/verify-agent-freshness.js --strict",
|
|
42
52
|
"conflicts:check": "node tools/check-merge-markers.js",
|
|
43
53
|
"imports:check:browser": "node tools/check-browser-import-graph.js",
|
|
54
|
+
"api:docs:sync": "node tools/sync-api-docs.js",
|
|
55
|
+
"api:docs:check": "node tools/sync-api-docs.js --check",
|
|
44
56
|
"verify:model": "node tools/doppler-cli.js verify",
|
|
45
57
|
"onboarding:check": "node tools/onboarding-tooling.js check",
|
|
46
58
|
"onboarding:check:strict": "node tools/onboarding-tooling.js check --strict",
|
|
@@ -53,8 +65,11 @@
|
|
|
53
65
|
"verify": "node tools/run-registry-verify.js",
|
|
54
66
|
"registry:sync:scripts": "node tools/sync-registry-scripts.js",
|
|
55
67
|
"registry:sync:scripts:check": "node tools/sync-registry-scripts.js --check",
|
|
68
|
+
"registry:hf:check": "node tools/check-hf-registry.js",
|
|
69
|
+
"registry:publish:hf": "node tools/publish-hf-registry-model.js",
|
|
56
70
|
"support:matrix:sync": "node tools/sync-model-support-matrix.js",
|
|
57
71
|
"support:matrix:check": "node tools/sync-model-support-matrix.js --check",
|
|
72
|
+
"ci:catalog:check": "npm run registry:sync:scripts:check && npm run support:matrix:check && npm run registry:hf:check",
|
|
58
73
|
"external:rdrr:index": "node tools/sync-external-rdrr-index.js",
|
|
59
74
|
"external:rdrr:index:check": "node tools/sync-external-rdrr-index.js --check",
|
|
60
75
|
"verify:embeddinggemma-300m": "node tools/run-registry-verify.js embeddinggemma-300m",
|
|
@@ -65,6 +80,7 @@
|
|
|
65
80
|
"verify:google-embeddinggemma-300m": "node tools/run-registry-verify.js google-embeddinggemma-300m",
|
|
66
81
|
"verify:google-embeddinggemma-300m-wq4k-ef16": "node tools/run-registry-verify.js google-embeddinggemma-300m-wq4k-ef16",
|
|
67
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",
|
|
68
84
|
"verify:qwen-3-5-0-8b": "node tools/run-registry-verify.js qwen-3-5-0-8b",
|
|
69
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",
|
|
70
86
|
"verify:qwen-3-5-2b": "node tools/run-registry-verify.js qwen-3-5-2b",
|
|
@@ -72,7 +88,10 @@
|
|
|
72
88
|
"verify:qwen-qwen3.5-0.8b": "node tools/run-registry-verify.js qwen-qwen3.5-0.8b",
|
|
73
89
|
"verify:qwen-qwen3.5-2b": "node tools/run-registry-verify.js qwen-qwen3.5-2b",
|
|
74
90
|
"verify:qwen3-0.8b": "node tools/run-registry-verify.js qwen3-0.8b",
|
|
75
|
-
"verify:qwen3-2b": "node tools/run-registry-verify.js qwen3-2b"
|
|
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"
|
|
76
95
|
},
|
|
77
96
|
"exports": {
|
|
78
97
|
".": {
|
|
@@ -102,12 +121,11 @@
|
|
|
102
121
|
"./energy": {
|
|
103
122
|
"types": "./src/energy/index.d.ts",
|
|
104
123
|
"import": "./src/energy/index.js"
|
|
105
|
-
}
|
|
106
|
-
"./*": "./src/*"
|
|
124
|
+
}
|
|
107
125
|
},
|
|
108
126
|
"repository": {
|
|
109
127
|
"type": "git",
|
|
110
|
-
"url": "https://github.com/clocksmith/doppler.git"
|
|
128
|
+
"url": "git+https://github.com/clocksmith/doppler.git"
|
|
111
129
|
},
|
|
112
130
|
"homepage": "https://github.com/clocksmith/doppler",
|
|
113
131
|
"keywords": [
|
|
@@ -124,6 +142,9 @@
|
|
|
124
142
|
"url": "https://github.com/clocksmith/doppler/issues"
|
|
125
143
|
},
|
|
126
144
|
"license": "Apache-2.0",
|
|
145
|
+
"publishConfig": {
|
|
146
|
+
"access": "public"
|
|
147
|
+
},
|
|
127
148
|
"files": [
|
|
128
149
|
"src",
|
|
129
150
|
"src/gpu/kernels/*.wgsl",
|
|
@@ -140,5 +161,8 @@
|
|
|
140
161
|
"jest": "^30.2.0",
|
|
141
162
|
"onnxruntime-web": "^1.24.1",
|
|
142
163
|
"playwright": "^1.58.2"
|
|
164
|
+
},
|
|
165
|
+
"optionalDependencies": {
|
|
166
|
+
"@simulatte/webgpu": "0.1.x"
|
|
143
167
|
}
|
|
144
168
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './doppler-api.d.ts';
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { loadLoRAFromManifest, loadLoRAFromUrl } from '../adapters/lora-loader.js';
|
|
2
|
+
import { log } from '../debug/index.js';
|
|
3
|
+
import { getManifestUrl, parseManifest } from '../formats/rdrr/index.js';
|
|
4
|
+
import { createPipeline } from '../generation/index.js';
|
|
5
|
+
import { getKernelCapabilities } from '../gpu/device.js';
|
|
6
|
+
import { formatChatMessages } from '../inference/pipelines/text/chat-format.js';
|
|
7
|
+
import { buildQuickstartModelBaseUrl, listQuickstartModels, resolveQuickstartModel } from './doppler-registry.js';
|
|
8
|
+
|
|
9
|
+
const convenienceModelCache = new Map();
|
|
10
|
+
const inFlightLoadCache = new Map();
|
|
11
|
+
|
|
12
|
+
function emitLoadProgress(callback, phase, percent, message) {
|
|
13
|
+
if (typeof callback !== 'function') return;
|
|
14
|
+
callback({ phase, percent, message });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function ensureWebGPUAvailable() {
|
|
18
|
+
if (typeof globalThis.navigator !== 'undefined' && globalThis.navigator?.gpu) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
throw new Error('WebGPU is unavailable. Run in a WebGPU-capable browser.');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createDefaultNodeLoadProgressLogger() {
|
|
25
|
+
return (event) => {
|
|
26
|
+
const message = typeof event?.message === 'string' ? event.message.trim() : '';
|
|
27
|
+
if (!message) return;
|
|
28
|
+
log.info('doppler', message);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function resolveLoadProgressHandlers(options = {}) {
|
|
33
|
+
const onProgress = typeof options?.onProgress === 'function' ? options.onProgress : null;
|
|
34
|
+
if (onProgress) {
|
|
35
|
+
return {
|
|
36
|
+
userProgress: onProgress,
|
|
37
|
+
pipelineProgress: onProgress,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
userProgress: null,
|
|
42
|
+
pipelineProgress: null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function fetchManifestFromBaseUrl(baseUrl) {
|
|
47
|
+
const response = await fetch(getManifestUrl(baseUrl));
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`Failed to fetch manifest from ${baseUrl}: ${response.status}`);
|
|
50
|
+
}
|
|
51
|
+
return parseManifest(await response.text());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function resolveModelSource(model) {
|
|
55
|
+
if (typeof model === 'string') {
|
|
56
|
+
const entry = await resolveQuickstartModel(model);
|
|
57
|
+
return {
|
|
58
|
+
modelId: entry.modelId,
|
|
59
|
+
baseUrl: buildQuickstartModelBaseUrl(entry),
|
|
60
|
+
manifest: null,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (model && typeof model === 'object' && typeof model.url === 'string' && model.url.trim().length > 0) {
|
|
64
|
+
return {
|
|
65
|
+
modelId: model.url.trim(),
|
|
66
|
+
baseUrl: model.url.trim(),
|
|
67
|
+
manifest: null,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (model && typeof model === 'object' && model.manifest && typeof model.manifest === 'object') {
|
|
71
|
+
const manifest = model.manifest;
|
|
72
|
+
const modelId = typeof manifest.modelId === 'string' && manifest.modelId.length > 0
|
|
73
|
+
? manifest.modelId
|
|
74
|
+
: 'manifest';
|
|
75
|
+
return {
|
|
76
|
+
modelId,
|
|
77
|
+
baseUrl: typeof model.baseUrl === 'string' && model.baseUrl.length > 0 ? model.baseUrl : null,
|
|
78
|
+
manifest,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
throw new Error('doppler.load expects a quickstart registry id, { url }, or { manifest, baseUrl? }.');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function countTokens(pipeline, text) {
|
|
85
|
+
if (!text || typeof text !== 'string') return 0;
|
|
86
|
+
try {
|
|
87
|
+
return pipeline?.tokenizer?.encode(text)?.length ?? 0;
|
|
88
|
+
} catch {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function resolveChatPromptForUsage(pipeline, messages) {
|
|
94
|
+
const templateType = pipeline?.manifest?.inference?.chatTemplate?.enabled === false
|
|
95
|
+
? null
|
|
96
|
+
: (pipeline?.manifest?.inference?.chatTemplate?.type ?? null);
|
|
97
|
+
try {
|
|
98
|
+
return formatChatMessages(messages, templateType);
|
|
99
|
+
} catch {
|
|
100
|
+
return messages.map((message) => String(message?.content ?? '')).join('\n');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function collectText(iterable) {
|
|
105
|
+
let output = '';
|
|
106
|
+
for await (const token of iterable) {
|
|
107
|
+
output += token;
|
|
108
|
+
}
|
|
109
|
+
return output;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function createModelHandle(pipeline, resolved) {
|
|
113
|
+
return {
|
|
114
|
+
generate(prompt, options = {}) {
|
|
115
|
+
return pipeline.generate(prompt, options);
|
|
116
|
+
},
|
|
117
|
+
async generateText(prompt, options = {}) {
|
|
118
|
+
return collectText(pipeline.generate(prompt, options));
|
|
119
|
+
},
|
|
120
|
+
chat(messages, options = {}) {
|
|
121
|
+
return pipeline.generate(messages, options);
|
|
122
|
+
},
|
|
123
|
+
async chatText(messages, options = {}) {
|
|
124
|
+
const content = await collectText(pipeline.generate(messages, options));
|
|
125
|
+
const promptText = resolveChatPromptForUsage(pipeline, messages);
|
|
126
|
+
const promptTokens = countTokens(pipeline, promptText);
|
|
127
|
+
const completionTokens = countTokens(pipeline, content);
|
|
128
|
+
return {
|
|
129
|
+
content,
|
|
130
|
+
usage: {
|
|
131
|
+
promptTokens,
|
|
132
|
+
completionTokens,
|
|
133
|
+
totalTokens: promptTokens + completionTokens,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
async loadLoRA(adapter) {
|
|
138
|
+
const lora = typeof adapter === 'string'
|
|
139
|
+
? await loadLoRAFromUrl(adapter)
|
|
140
|
+
: await loadLoRAFromManifest(adapter);
|
|
141
|
+
pipeline.setLoRAAdapter(lora);
|
|
142
|
+
},
|
|
143
|
+
async unloadLoRA() {
|
|
144
|
+
pipeline.setLoRAAdapter(null);
|
|
145
|
+
},
|
|
146
|
+
async unload() {
|
|
147
|
+
await pipeline.unload();
|
|
148
|
+
},
|
|
149
|
+
get activeLoRA() {
|
|
150
|
+
return pipeline.getActiveLoRA()?.name ?? null;
|
|
151
|
+
},
|
|
152
|
+
get loaded() {
|
|
153
|
+
return pipeline.isLoaded === true;
|
|
154
|
+
},
|
|
155
|
+
get modelId() {
|
|
156
|
+
return resolved.modelId;
|
|
157
|
+
},
|
|
158
|
+
get manifest() {
|
|
159
|
+
return pipeline.manifest;
|
|
160
|
+
},
|
|
161
|
+
get deviceInfo() {
|
|
162
|
+
return getKernelCapabilities()?.adapterInfo ?? null;
|
|
163
|
+
},
|
|
164
|
+
advanced: {
|
|
165
|
+
prefillKV(prompt, options = {}) {
|
|
166
|
+
return pipeline.prefillKVOnly(prompt, options);
|
|
167
|
+
},
|
|
168
|
+
generateWithPrefixKV(prefix, prompt, options = {}) {
|
|
169
|
+
return pipeline.generateWithPrefixKV(prefix, prompt, options);
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function load(model, options = {}) {
|
|
176
|
+
const { userProgress, pipelineProgress } = resolveLoadProgressHandlers(options);
|
|
177
|
+
|
|
178
|
+
emitLoadProgress(userProgress, 'resolve', 5, 'Resolving model');
|
|
179
|
+
const resolved = await resolveModelSource(model);
|
|
180
|
+
await ensureWebGPUAvailable();
|
|
181
|
+
|
|
182
|
+
emitLoadProgress(userProgress, 'manifest', 15, 'Fetching manifest');
|
|
183
|
+
const manifest = resolved.manifest ?? await fetchManifestFromBaseUrl(resolved.baseUrl);
|
|
184
|
+
|
|
185
|
+
emitLoadProgress(userProgress, 'load', 25, 'Loading weights');
|
|
186
|
+
const pipeline = await createPipeline(manifest, {
|
|
187
|
+
baseUrl: resolved.baseUrl ?? undefined,
|
|
188
|
+
runtimeConfig: options.runtimeConfig,
|
|
189
|
+
onProgress: pipelineProgress
|
|
190
|
+
? (progress) => emitLoadProgress(
|
|
191
|
+
pipelineProgress,
|
|
192
|
+
'load',
|
|
193
|
+
Math.max(25, Math.min(99, Math.round(progress.percent))),
|
|
194
|
+
progress.message || 'Loading weights'
|
|
195
|
+
)
|
|
196
|
+
: undefined,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
emitLoadProgress(userProgress, 'ready', 100, 'Model ready');
|
|
200
|
+
return createModelHandle(pipeline, resolved);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function getCachedModel(model, options = {}) {
|
|
204
|
+
const resolved = await resolveModelSource(model);
|
|
205
|
+
const cacheKey = resolved.modelId;
|
|
206
|
+
const cached = convenienceModelCache.get(cacheKey);
|
|
207
|
+
if (cached?.loaded) {
|
|
208
|
+
return cached;
|
|
209
|
+
}
|
|
210
|
+
if (cached && !cached.loaded) {
|
|
211
|
+
convenienceModelCache.delete(cacheKey);
|
|
212
|
+
}
|
|
213
|
+
if (!inFlightLoadCache.has(cacheKey)) {
|
|
214
|
+
inFlightLoadCache.set(cacheKey, load(model, options).then((instance) => {
|
|
215
|
+
convenienceModelCache.set(cacheKey, instance);
|
|
216
|
+
inFlightLoadCache.delete(cacheKey);
|
|
217
|
+
return instance;
|
|
218
|
+
}).catch((error) => {
|
|
219
|
+
inFlightLoadCache.delete(cacheKey);
|
|
220
|
+
throw error;
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
return inFlightLoadCache.get(cacheKey);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function* dopplerGenerate(prompt, options = {}) {
|
|
227
|
+
if (!options || typeof options !== 'object' || options.model == null) {
|
|
228
|
+
throw new Error('doppler() requires options.model.');
|
|
229
|
+
}
|
|
230
|
+
if (options.runtimeConfig !== undefined || options.runtimePreset !== undefined) {
|
|
231
|
+
throw new Error('doppler() does not accept load-affecting options. Use doppler.load(model, options) instead.');
|
|
232
|
+
}
|
|
233
|
+
const model = await getCachedModel(options.model, { onProgress: options.onProgress });
|
|
234
|
+
yield* model.generate(prompt, options);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function doppler(prompt, options) {
|
|
238
|
+
return dopplerGenerate(prompt, options);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
doppler.load = load;
|
|
242
|
+
|
|
243
|
+
doppler.text = async function text(prompt, options = {}) {
|
|
244
|
+
if (!options || typeof options !== 'object' || options.model == null) {
|
|
245
|
+
throw new Error('doppler.text() requires options.model.');
|
|
246
|
+
}
|
|
247
|
+
const model = await getCachedModel(options.model, { onProgress: options.onProgress });
|
|
248
|
+
return model.generateText(prompt, options);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
doppler.chat = function chat(messages, options = {}) {
|
|
252
|
+
if (!options || typeof options !== 'object' || options.model == null) {
|
|
253
|
+
throw new Error('doppler.chat() requires options.model.');
|
|
254
|
+
}
|
|
255
|
+
return (async function* run() {
|
|
256
|
+
const model = await getCachedModel(options.model, { onProgress: options.onProgress });
|
|
257
|
+
yield* model.chat(messages, options);
|
|
258
|
+
}());
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
doppler.chatText = async function chatText(messages, options = {}) {
|
|
262
|
+
if (!options || typeof options !== 'object' || options.model == null) {
|
|
263
|
+
throw new Error('doppler.chatText() requires options.model.');
|
|
264
|
+
}
|
|
265
|
+
const model = await getCachedModel(options.model, { onProgress: options.onProgress });
|
|
266
|
+
return model.chatText(messages, options);
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
doppler.evict = async function evict(model) {
|
|
270
|
+
const resolved = await resolveModelSource(model);
|
|
271
|
+
const cacheKey = resolved.modelId;
|
|
272
|
+
const cached = convenienceModelCache.get(cacheKey);
|
|
273
|
+
if (!cached) return false;
|
|
274
|
+
await cached.unload();
|
|
275
|
+
convenienceModelCache.delete(cacheKey);
|
|
276
|
+
return true;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
doppler.evictAll = async function evictAll() {
|
|
280
|
+
const cachedModels = Array.from(convenienceModelCache.values());
|
|
281
|
+
convenienceModelCache.clear();
|
|
282
|
+
await Promise.allSettled(cachedModels.map((model) => model.unload()));
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
doppler.listModels = async function listModels() {
|
|
286
|
+
const models = await listQuickstartModels();
|
|
287
|
+
return models.map((entry) => entry.aliases[0] || entry.modelId);
|
|
288
|
+
};
|
|
@@ -4,7 +4,6 @@ import { getManifestUrl, parseManifest } from '../formats/rdrr/index.js';
|
|
|
4
4
|
import { createPipeline } from '../generation/index.js';
|
|
5
5
|
import { getKernelCapabilities } from '../gpu/device.js';
|
|
6
6
|
import { formatChatMessages } from '../inference/pipelines/text/chat-format.js';
|
|
7
|
-
import { bootstrapNodeWebGPU } from '../tooling/node-webgpu.js';
|
|
8
7
|
import { buildQuickstartModelBaseUrl, listQuickstartModels, resolveQuickstartModel } from './doppler-registry.js';
|
|
9
8
|
|
|
10
9
|
const convenienceModelCache = new Map();
|
|
@@ -21,6 +20,7 @@ async function ensureWebGPUAvailable() {
|
|
|
21
20
|
return;
|
|
22
21
|
}
|
|
23
22
|
if (isNodeRuntime()) {
|
|
23
|
+
const { bootstrapNodeWebGPU } = await import('../tooling/node-webgpu.js');
|
|
24
24
|
const result = await bootstrapNodeWebGPU();
|
|
25
25
|
if (result.ok && globalThis.navigator?.gpu) {
|
|
26
26
|
return;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ExecutionV0ContractArtifact,
|
|
3
|
+
} from './execution-v0-contract-check.js';
|
|
4
|
+
import type {
|
|
5
|
+
ExecutionV0GraphContractArtifact,
|
|
6
|
+
} from './execution-v0-graph-contract-check.js';
|
|
7
|
+
|
|
1
8
|
export interface ExecutionContractStepFacts {
|
|
2
9
|
id: string;
|
|
3
10
|
phase: 'prefill' | 'decode' | 'both';
|
|
@@ -34,6 +41,28 @@ export interface ManifestExecutionContractValidationResult extends ExecutionCont
|
|
|
34
41
|
facts: ExecutionContractFacts;
|
|
35
42
|
}
|
|
36
43
|
|
|
44
|
+
export interface ExecutionContractArtifact {
|
|
45
|
+
schemaVersion: 1;
|
|
46
|
+
source: 'doppler';
|
|
47
|
+
ok: boolean;
|
|
48
|
+
checks: ExecutionContractCheckResult[];
|
|
49
|
+
errors: string[];
|
|
50
|
+
session: ExecutionContractSessionFacts | null;
|
|
51
|
+
steps: {
|
|
52
|
+
total: number;
|
|
53
|
+
attention: number;
|
|
54
|
+
attentionPhases: {
|
|
55
|
+
prefill: number;
|
|
56
|
+
decode: number;
|
|
57
|
+
both: number;
|
|
58
|
+
};
|
|
59
|
+
} | null;
|
|
60
|
+
executionV0?: {
|
|
61
|
+
kernelProfiles: ExecutionV0ContractArtifact | null;
|
|
62
|
+
graph: ExecutionV0GraphContractArtifact | null;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
37
66
|
export declare function sanitizeLeanModuleName(value: unknown): string;
|
|
38
67
|
|
|
39
68
|
export declare function extractExecutionContractFacts(
|
|
@@ -47,3 +76,7 @@ export declare function validateExecutionContractFacts(
|
|
|
47
76
|
export declare function validateManifestExecutionContract(
|
|
48
77
|
manifest: Record<string, unknown>
|
|
49
78
|
): ManifestExecutionContractValidationResult;
|
|
79
|
+
|
|
80
|
+
export declare function buildExecutionContractArtifact(
|
|
81
|
+
manifest: Record<string, unknown>
|
|
82
|
+
): ExecutionContractArtifact | null;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_BATCHING_DEFAULTS, DEFAULT_GENERATION_CONFIG } from './schema/inference-defaults.schema.js';
|
|
2
|
+
import { buildExecutionV0ContractArtifact } from './execution-v0-contract-check.js';
|
|
3
|
+
import { buildExecutionV0GraphContractArtifact } from './execution-v0-graph-contract-check.js';
|
|
4
|
+
import { EXECUTION_V0_SCHEMA_ID } from './schema/execution-v0.schema.js';
|
|
2
5
|
import { DEFAULT_KVCACHE_CONFIG } from './schema/kvcache.schema.js';
|
|
3
6
|
|
|
4
7
|
const KV_LAYOUTS = new Set(['contiguous', 'paged', 'tiered', 'bdpa']);
|
|
@@ -243,3 +246,72 @@ export function validateManifestExecutionContract(manifest) {
|
|
|
243
246
|
facts,
|
|
244
247
|
};
|
|
245
248
|
}
|
|
249
|
+
|
|
250
|
+
export function buildExecutionContractArtifact(manifest) {
|
|
251
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
if (manifest.modelType === 'diffusion' || manifest.modelType === 'energy') {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
if (!manifest.architecture || !manifest.inference || typeof manifest.inference !== 'object') {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
const evaluation = validateManifestExecutionContract(manifest);
|
|
262
|
+
const attentionPhaseCounts = { prefill: 0, decode: 0, both: 0 };
|
|
263
|
+
for (const step of evaluation.facts.steps) {
|
|
264
|
+
if (step.opClass !== 'attention') continue;
|
|
265
|
+
if (Object.prototype.hasOwnProperty.call(attentionPhaseCounts, step.phase)) {
|
|
266
|
+
attentionPhaseCounts[step.phase] += 1;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const executionV0 =
|
|
270
|
+
manifest?.inference?.schema === EXECUTION_V0_SCHEMA_ID
|
|
271
|
+
? {
|
|
272
|
+
kernelProfiles: buildExecutionV0ContractArtifact(manifest.inference, {
|
|
273
|
+
modelId: evaluation.facts.modelId,
|
|
274
|
+
}),
|
|
275
|
+
graph: buildExecutionV0GraphContractArtifact({
|
|
276
|
+
modelId: evaluation.facts.modelId,
|
|
277
|
+
numLayers: manifest?.architecture?.numLayers,
|
|
278
|
+
manifestInference: manifest.inference,
|
|
279
|
+
}),
|
|
280
|
+
}
|
|
281
|
+
: null;
|
|
282
|
+
const nestedChecks = [];
|
|
283
|
+
const nestedErrors = [];
|
|
284
|
+
if (executionV0?.kernelProfiles) {
|
|
285
|
+
nestedChecks.push(...executionV0.kernelProfiles.checks);
|
|
286
|
+
nestedErrors.push(...executionV0.kernelProfiles.errors);
|
|
287
|
+
}
|
|
288
|
+
if (executionV0?.graph) {
|
|
289
|
+
nestedChecks.push(...executionV0.graph.checks);
|
|
290
|
+
nestedErrors.push(...executionV0.graph.errors);
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
schemaVersion: 1,
|
|
294
|
+
source: 'doppler',
|
|
295
|
+
ok: evaluation.ok && nestedErrors.length === 0,
|
|
296
|
+
checks: [...evaluation.checks, ...nestedChecks],
|
|
297
|
+
errors: [...evaluation.errors, ...nestedErrors],
|
|
298
|
+
session: evaluation.facts.session,
|
|
299
|
+
steps: {
|
|
300
|
+
total: evaluation.facts.steps.length,
|
|
301
|
+
attention: attentionPhaseCounts.prefill + attentionPhaseCounts.decode + attentionPhaseCounts.both,
|
|
302
|
+
attentionPhases: attentionPhaseCounts,
|
|
303
|
+
},
|
|
304
|
+
...(executionV0 ? { executionV0 } : {}),
|
|
305
|
+
};
|
|
306
|
+
} catch (error) {
|
|
307
|
+
return {
|
|
308
|
+
schemaVersion: 1,
|
|
309
|
+
source: 'doppler',
|
|
310
|
+
ok: false,
|
|
311
|
+
checks: [],
|
|
312
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
313
|
+
session: null,
|
|
314
|
+
steps: null,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
}
|