@simulatte/doppler 0.1.4 → 0.1.5

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.
Files changed (103) hide show
  1. package/README.md +4 -3
  2. package/package.json +25 -4
  3. package/src/client/doppler-api.browser.d.ts +1 -0
  4. package/src/client/doppler-api.browser.js +288 -0
  5. package/src/client/doppler-api.js +1 -1
  6. package/src/client/doppler-provider/types.js +1 -1
  7. package/src/config/execution-contract-check.d.ts +33 -0
  8. package/src/config/execution-contract-check.js +72 -0
  9. package/src/config/execution-v0-contract-check.d.ts +94 -0
  10. package/src/config/execution-v0-contract-check.js +251 -0
  11. package/src/config/execution-v0-graph-contract-check.d.ts +20 -0
  12. package/src/config/execution-v0-graph-contract-check.js +64 -0
  13. package/src/config/kernel-path-contract-check.d.ts +76 -0
  14. package/src/config/kernel-path-contract-check.js +479 -0
  15. package/src/config/kernel-path-loader.d.ts +16 -0
  16. package/src/config/kernel-path-loader.js +54 -0
  17. package/src/config/kernels/kernel-ref-digests.js +12 -0
  18. package/src/config/kernels/registry.json +556 -0
  19. package/src/config/loader.js +50 -46
  20. package/src/config/merge-contract-check.d.ts +16 -0
  21. package/src/config/merge-contract-check.js +321 -0
  22. package/src/config/merge-helpers.d.ts +58 -0
  23. package/src/config/merge-helpers.js +54 -0
  24. package/src/config/merge.js +3 -6
  25. package/src/config/presets/models/janus-text.json +2 -0
  26. package/src/config/quantization-contract-check.d.ts +12 -0
  27. package/src/config/quantization-contract-check.js +91 -0
  28. package/src/config/required-inference-fields-contract-check.d.ts +24 -0
  29. package/src/config/required-inference-fields-contract-check.js +231 -0
  30. package/src/config/schema/browser-suite-metrics.schema.d.ts +17 -0
  31. package/src/config/schema/browser-suite-metrics.schema.js +46 -0
  32. package/src/config/schema/conversion-report.schema.d.ts +40 -0
  33. package/src/config/schema/conversion-report.schema.js +108 -0
  34. package/src/config/schema/doppler.schema.js +12 -18
  35. package/src/config/schema/index.d.ts +22 -0
  36. package/src/config/schema/index.js +18 -0
  37. package/src/converter/core.d.ts +10 -0
  38. package/src/converter/core.js +27 -2
  39. package/src/converter/parsers/diffusion.js +63 -3
  40. package/src/gpu/kernels/depthwise_conv2d.d.ts +29 -0
  41. package/src/gpu/kernels/depthwise_conv2d.js +98 -0
  42. package/src/gpu/kernels/depthwise_conv2d.wgsl +58 -0
  43. package/src/gpu/kernels/depthwise_conv2d_f16.wgsl +62 -0
  44. package/src/gpu/kernels/grouped_pointwise_conv2d.d.ts +27 -0
  45. package/src/gpu/kernels/grouped_pointwise_conv2d.js +92 -0
  46. package/src/gpu/kernels/grouped_pointwise_conv2d.wgsl +47 -0
  47. package/src/gpu/kernels/grouped_pointwise_conv2d_f16.wgsl +51 -0
  48. package/src/gpu/kernels/index.d.ts +30 -0
  49. package/src/gpu/kernels/index.js +25 -0
  50. package/src/gpu/kernels/relu.d.ts +18 -0
  51. package/src/gpu/kernels/relu.js +45 -0
  52. package/src/gpu/kernels/relu.wgsl +21 -0
  53. package/src/gpu/kernels/relu_f16.wgsl +23 -0
  54. package/src/gpu/kernels/repeat_channels.d.ts +21 -0
  55. package/src/gpu/kernels/repeat_channels.js +60 -0
  56. package/src/gpu/kernels/repeat_channels.wgsl +29 -0
  57. package/src/gpu/kernels/repeat_channels_f16.wgsl +31 -0
  58. package/src/gpu/kernels/sana_linear_attention.d.ts +27 -0
  59. package/src/gpu/kernels/sana_linear_attention.js +122 -0
  60. package/src/gpu/kernels/sana_linear_attention_apply.wgsl +44 -0
  61. package/src/gpu/kernels/sana_linear_attention_apply_f16.wgsl +47 -0
  62. package/src/gpu/kernels/sana_linear_attention_summary.wgsl +47 -0
  63. package/src/gpu/kernels/sana_linear_attention_summary_f16.wgsl +49 -0
  64. package/src/index-browser.d.ts +1 -1
  65. package/src/index-browser.js +2 -2
  66. package/src/index.js +1 -1
  67. package/src/inference/browser-harness.js +62 -22
  68. package/src/inference/pipelines/diffusion/init.js +14 -0
  69. package/src/inference/pipelines/diffusion/pipeline.js +206 -77
  70. package/src/inference/pipelines/diffusion/sana-transformer.d.ts +53 -0
  71. package/src/inference/pipelines/diffusion/sana-transformer.js +738 -0
  72. package/src/inference/pipelines/diffusion/scheduler.d.ts +17 -1
  73. package/src/inference/pipelines/diffusion/scheduler.js +91 -3
  74. package/src/inference/pipelines/diffusion/text-encoder-gpu.d.ts +6 -4
  75. package/src/inference/pipelines/diffusion/text-encoder-gpu.js +270 -0
  76. package/src/inference/pipelines/diffusion/text-encoder.js +18 -1
  77. package/src/inference/pipelines/diffusion/types.d.ts +4 -0
  78. package/src/inference/pipelines/diffusion/vae.js +782 -78
  79. package/src/inference/pipelines/text/config.d.ts +5 -0
  80. package/src/inference/pipelines/text/config.js +1 -1
  81. package/src/inference/pipelines/text/execution-v0.js +14 -93
  82. package/src/rules/execution-rules-contract-check.d.ts +17 -0
  83. package/src/rules/execution-rules-contract-check.js +245 -0
  84. package/src/rules/kernels/depthwise-conv2d.rules.json +6 -0
  85. package/src/rules/kernels/grouped-pointwise-conv2d.rules.json +6 -0
  86. package/src/rules/kernels/relu.rules.json +6 -0
  87. package/src/rules/kernels/repeat-channels.rules.json +6 -0
  88. package/src/rules/kernels/sana-linear-attention.rules.json +6 -0
  89. package/src/rules/layer-pattern-contract-check.d.ts +17 -0
  90. package/src/rules/layer-pattern-contract-check.js +231 -0
  91. package/src/rules/rule-registry.d.ts +28 -0
  92. package/src/rules/rule-registry.js +38 -0
  93. package/src/tooling/conversion-config-materializer.d.ts +24 -0
  94. package/src/tooling/conversion-config-materializer.js +99 -0
  95. package/src/tooling/lean-execution-contract-runner.d.ts +43 -0
  96. package/src/tooling/lean-execution-contract-runner.js +158 -0
  97. package/src/tooling/node-convert.d.ts +10 -0
  98. package/src/tooling/node-converter.js +59 -0
  99. package/src/tooling/node-webgpu.js +9 -9
  100. package/src/version.d.ts +2 -0
  101. package/src/version.js +2 -0
  102. package/tools/convert-safetensors-node.js +47 -0
  103. package/tools/doppler-cli.js +115 -1
@@ -210,6 +210,11 @@ export interface ManifestWithInference {
210
210
  */
211
211
  export function hasManifestInference(manifest: Manifest): manifest is Manifest & { inference: ManifestInferenceSchema };
212
212
 
213
+ export function validateRequiredInferenceFields(
214
+ inf: ManifestInferenceSchema,
215
+ modelId: string
216
+ ): void;
217
+
213
218
  /**
214
219
  * Convert MergedConfig to ParsedModelConfig.
215
220
  */
@@ -129,7 +129,7 @@ export function hasManifestInference(manifest) {
129
129
  }
130
130
 
131
131
 
132
- function validateRequiredInferenceFields(inf, modelId) {
132
+ export function validateRequiredInferenceFields(inf, modelId) {
133
133
 
134
134
  const errors = [];
135
135
 
@@ -1,4 +1,12 @@
1
1
  import { mergeRuntimeValues } from '../../../config/runtime-merge.js';
2
+ import {
3
+ buildExecutionV0KernelProfileKey,
4
+ indexExecutionV0KernelProfiles,
5
+ normalizeExecutionV0Dtype,
6
+ resolveExecutionV0KernelProfile,
7
+ resolveExecutionV0KVIO,
8
+ resolveExecutionV0Precision,
9
+ } from '../../../config/execution-v0-contract-check.js';
2
10
  import {
3
11
  EXECUTION_V0_SCHEMA_ID,
4
12
  DEFAULT_EXECUTION_V0_POLICIES,
@@ -59,13 +67,9 @@ function cloneJson(value) {
59
67
  return JSON.parse(JSON.stringify(value));
60
68
  }
61
69
 
62
- function normalizeDtype(value, label) {
63
- const normalized = String(value ?? '').trim().toLowerCase();
64
- if (normalized !== 'f16' && normalized !== 'f32') {
65
- throw new Error(`[ExecutionV0] ${label} must be "f16" or "f32"; got "${value}"`);
66
- }
67
- return normalized;
68
- }
70
+ const normalizeDtype = normalizeExecutionV0Dtype;
71
+ const resolvePrecision = resolveExecutionV0Precision;
72
+ const resolveKVIO = resolveExecutionV0KVIO;
69
73
 
70
74
  function normalizePhase(value, label) {
71
75
  const normalized = String(value ?? '').trim().toLowerCase();
@@ -117,10 +121,7 @@ function stepHasLayer(step, layerIdx) {
117
121
  return step.layers.includes(layerIdx);
118
122
  }
119
123
 
120
- function buildKernelProfileKey(kernelRef) {
121
- if (!kernelRef) return null;
122
- return `${kernelRef.id}|${kernelRef.version}|${kernelRef.digest}`;
123
- }
124
+ const buildKernelProfileKey = buildExecutionV0KernelProfileKey;
124
125
 
125
126
  function normalizeSlot(value, label) {
126
127
  if (typeof value !== 'string' || value.trim().length === 0) {
@@ -212,90 +213,10 @@ function hasDefinedPath(root, pathSegments) {
212
213
  return current !== undefined;
213
214
  }
214
215
 
215
- function indexKernelProfiles(sessionDefaults) {
216
- const byKey = new Map();
217
- const profiles = sessionDefaults?.compute?.kernelProfiles ?? [];
218
- for (const profile of profiles) {
219
- assertKernelRef(profile.kernelRef, 'sessionDefaults.compute.kernelProfiles[].kernelRef');
220
- byKey.set(buildKernelProfileKey(profile.kernelRef), profile);
221
- }
222
- return byKey;
223
- }
216
+ const indexKernelProfiles = indexExecutionV0KernelProfiles;
224
217
 
225
218
  function resolveProfile(profileIndex, step) {
226
- const key = buildKernelProfileKey(step.kernelRef);
227
- if (!key) return null;
228
- return profileIndex.get(key) ?? null;
229
- }
230
-
231
- function resolvePrecision(step, profile, sessionDefaults) {
232
- const defaults = sessionDefaults.compute.defaults;
233
- const precision = {
234
- inputDtype: step.precision?.inputDtype
235
- ?? profile?.precision?.inputDtype
236
- ?? null,
237
- mathDtype: step.precision?.mathDtype
238
- ?? profile?.precision?.mathDtype
239
- ?? defaults.mathDtype,
240
- accumDtype: step.precision?.accumDtype
241
- ?? profile?.precision?.accumDtype
242
- ?? defaults.accumDtype,
243
- outputDtype: step.precision?.outputDtype
244
- ?? profile?.precision?.outputDtype
245
- ?? defaults.outputDtype,
246
- };
247
- const sources = {
248
- inputDtype: step.precision?.inputDtype != null
249
- ? 'manifest'
250
- : profile?.precision?.inputDtype != null
251
- ? 'kernelProfile'
252
- : 'derived',
253
- mathDtype: step.precision?.mathDtype != null
254
- ? 'manifest'
255
- : profile?.precision?.mathDtype != null
256
- ? 'kernelProfile'
257
- : 'sessionDefault',
258
- accumDtype: step.precision?.accumDtype != null
259
- ? 'manifest'
260
- : profile?.precision?.accumDtype != null
261
- ? 'kernelProfile'
262
- : 'sessionDefault',
263
- outputDtype: step.precision?.outputDtype != null
264
- ? 'manifest'
265
- : profile?.precision?.outputDtype != null
266
- ? 'kernelProfile'
267
- : 'sessionDefault',
268
- };
269
- return { precision, sources };
270
- }
271
-
272
- function resolveKVIO(step, profile, sessionDefaults) {
273
- if (step.kvIO) {
274
- return {
275
- value: {
276
- readDtype: normalizeDtype(step.kvIO.readDtype, `${step.id}.kvIO.readDtype`),
277
- writeDtype: normalizeDtype(step.kvIO.writeDtype, `${step.id}.kvIO.writeDtype`),
278
- },
279
- source: 'manifest',
280
- };
281
- }
282
- if (profile?.kvIO) {
283
- return {
284
- value: {
285
- readDtype: normalizeDtype(profile.kvIO.readDtype, `${step.id}.profile.kvIO.readDtype`),
286
- writeDtype: normalizeDtype(profile.kvIO.writeDtype, `${step.id}.profile.kvIO.writeDtype`),
287
- },
288
- source: 'kernelProfile',
289
- };
290
- }
291
- const kvDtype = normalizeDtype(
292
- sessionDefaults?.kvcache?.kvDtype ?? sessionDefaults.compute.defaults.activationDtype,
293
- `${step.id}.sessionDefaults.kvcache.kvDtype`
294
- );
295
- return {
296
- value: { readDtype: kvDtype, writeDtype: kvDtype },
297
- source: 'sessionDefault',
298
- };
219
+ return resolveExecutionV0KernelProfile(profileIndex, step);
299
220
  }
300
221
 
301
222
  function validateStepShape(step, index) {
@@ -0,0 +1,17 @@
1
+ export interface InferenceExecutionRulesContractArtifact {
2
+ schemaVersion: 1;
3
+ source: 'doppler';
4
+ ok: boolean;
5
+ checks: Array<{ id: string; ok: boolean }>;
6
+ errors: string[];
7
+ stats: {
8
+ decodeRecorderRules: number;
9
+ batchDecodeRules: number;
10
+ decodeRecorderContexts: number;
11
+ batchDecodeContexts: number;
12
+ };
13
+ }
14
+
15
+ export declare function buildInferenceExecutionRulesContractArtifact(
16
+ ruleGroup: Record<string, unknown> | null | undefined
17
+ ): InferenceExecutionRulesContractArtifact;
@@ -0,0 +1,245 @@
1
+ import { selectByRules } from '../gpu/kernels/rule-matcher.js';
2
+
3
+ function isPlainObject(value) {
4
+ return value != null && typeof value === 'object' && !Array.isArray(value);
5
+ }
6
+
7
+ function matchesExactObject(actual, expected) {
8
+ if (!isPlainObject(actual) || !isPlainObject(expected)) {
9
+ return false;
10
+ }
11
+ const actualKeys = Object.keys(actual).sort();
12
+ const expectedKeys = Object.keys(expected).sort();
13
+ if (actualKeys.length !== expectedKeys.length) {
14
+ return false;
15
+ }
16
+ for (let i = 0; i < actualKeys.length; i += 1) {
17
+ if (actualKeys[i] !== expectedKeys[i]) {
18
+ return false;
19
+ }
20
+ }
21
+ for (const key of expectedKeys) {
22
+ const expectedValue = expected[key];
23
+ const actualValue = actual[key];
24
+ if (isPlainObject(expectedValue)) {
25
+ if (!matchesExactObject(actualValue, expectedValue)) {
26
+ return false;
27
+ }
28
+ continue;
29
+ }
30
+ if (Array.isArray(expectedValue)) {
31
+ if (!Array.isArray(actualValue) || actualValue.length !== expectedValue.length) {
32
+ return false;
33
+ }
34
+ for (let i = 0; i < expectedValue.length; i += 1) {
35
+ if (actualValue[i] !== expectedValue[i]) {
36
+ return false;
37
+ }
38
+ }
39
+ continue;
40
+ }
41
+ if (actualValue !== expectedValue) {
42
+ return false;
43
+ }
44
+ }
45
+ return true;
46
+ }
47
+
48
+ function decodeRecorderSemantic(context) {
49
+ return context.hasDevice === true
50
+ && context.debug !== true
51
+ && context.disableCommandBatching !== true
52
+ && context.kvLayout !== 'bdpa_paged';
53
+ }
54
+
55
+ function batchDecodeSemantic(context) {
56
+ return context.batchSize > 1
57
+ && context.useGPU === true
58
+ && context.gpuSamplingAvailable === true
59
+ && context.disableMultiTokenDecode !== true
60
+ && context.disableCommandBatching !== true
61
+ && context.isBdpaPagedLayout !== true
62
+ && context.finitenessFallbackWindowOpen !== true;
63
+ }
64
+
65
+ function enumerateDecodeRecorderContexts() {
66
+ const values = [true, false];
67
+ const kvLayouts = ['bdpa_paged', 'paged', null];
68
+ const contexts = [];
69
+ for (const hasDevice of values) {
70
+ for (const debug of values) {
71
+ for (const disableCommandBatching of values) {
72
+ for (const kvLayout of kvLayouts) {
73
+ contexts.push({
74
+ hasDevice,
75
+ debug,
76
+ disableCommandBatching,
77
+ kvLayout,
78
+ });
79
+ }
80
+ }
81
+ }
82
+ }
83
+ return contexts;
84
+ }
85
+
86
+ function enumerateBatchDecodeContexts() {
87
+ const values = [true, false];
88
+ const batchSizes = [1, 2];
89
+ const contexts = [];
90
+ for (const batchSize of batchSizes) {
91
+ for (const useGPU of values) {
92
+ for (const gpuSamplingAvailable of values) {
93
+ for (const disableMultiTokenDecode of values) {
94
+ for (const disableCommandBatching of values) {
95
+ for (const isBdpaPagedLayout of values) {
96
+ for (const finitenessFallbackWindowOpen of values) {
97
+ contexts.push({
98
+ batchSize,
99
+ useGPU,
100
+ gpuSamplingAvailable,
101
+ disableMultiTokenDecode,
102
+ disableCommandBatching,
103
+ isBdpaPagedLayout,
104
+ finitenessFallbackWindowOpen,
105
+ });
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ return contexts;
114
+ }
115
+
116
+ function checkRuleShape(rules, expectedFirstMatch, label) {
117
+ if (!Array.isArray(rules)) {
118
+ return {
119
+ ok: false,
120
+ errors: [`[ExecutionRulesContract] ${label} must be an array.`],
121
+ };
122
+ }
123
+ if (rules.length !== 2) {
124
+ return {
125
+ ok: false,
126
+ errors: [`[ExecutionRulesContract] ${label} must contain exactly 2 rules; got ${rules.length}.`],
127
+ };
128
+ }
129
+ const [firstRule, secondRule] = rules;
130
+ const errors = [];
131
+ if (!matchesExactObject(firstRule?.match, expectedFirstMatch) || firstRule?.value !== true) {
132
+ errors.push(`[ExecutionRulesContract] ${label} first rule drifted from the expected enabling predicate.`);
133
+ }
134
+ if (!matchesExactObject(secondRule?.match, {}) || secondRule?.value !== false) {
135
+ errors.push(`[ExecutionRulesContract] ${label} fallback rule must be { match: {}, value: false }.`);
136
+ }
137
+ return {
138
+ ok: errors.length === 0,
139
+ errors,
140
+ };
141
+ }
142
+
143
+ function checkRuleSemantics(rules, contexts, expectedValue, label) {
144
+ const errors = [];
145
+ for (const context of contexts) {
146
+ const actual = selectByRules(rules, context);
147
+ const expected = expectedValue(context);
148
+ if (actual !== expected) {
149
+ errors.push(
150
+ `[ExecutionRulesContract] ${label} mismatched context ${JSON.stringify(context)}: ` +
151
+ `expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}.`
152
+ );
153
+ break;
154
+ }
155
+ }
156
+ return {
157
+ ok: errors.length === 0,
158
+ errors,
159
+ sampledContexts: contexts.length,
160
+ };
161
+ }
162
+
163
+ export function buildInferenceExecutionRulesContractArtifact(ruleGroup) {
164
+ const errors = [];
165
+ const checks = [];
166
+ const decodeRules = ruleGroup?.decodeRecorderEnabled;
167
+ const batchRules = ruleGroup?.batchDecodeEnabled;
168
+
169
+ const decodeShape = checkRuleShape(
170
+ decodeRules,
171
+ {
172
+ hasDevice: true,
173
+ debug: false,
174
+ disableCommandBatching: false,
175
+ kvLayout: { neq: 'bdpa_paged' },
176
+ },
177
+ 'decodeRecorderEnabled'
178
+ );
179
+ errors.push(...decodeShape.errors);
180
+ checks.push({
181
+ id: 'inference.execution.decodeRecorderEnabled.shape',
182
+ ok: decodeShape.ok,
183
+ });
184
+
185
+ const decodeSemantics = Array.isArray(decodeRules)
186
+ ? checkRuleSemantics(
187
+ decodeRules,
188
+ enumerateDecodeRecorderContexts(),
189
+ decodeRecorderSemantic,
190
+ 'decodeRecorderEnabled'
191
+ )
192
+ : { ok: false, errors: ['[ExecutionRulesContract] decodeRecorderEnabled is unavailable for semantic check.'], sampledContexts: 0 };
193
+ errors.push(...decodeSemantics.errors);
194
+ checks.push({
195
+ id: 'inference.execution.decodeRecorderEnabled.semantics',
196
+ ok: decodeSemantics.ok,
197
+ });
198
+
199
+ const batchShape = checkRuleShape(
200
+ batchRules,
201
+ {
202
+ batchSize: { gt: 1 },
203
+ useGPU: true,
204
+ gpuSamplingAvailable: true,
205
+ disableMultiTokenDecode: false,
206
+ disableCommandBatching: false,
207
+ isBdpaPagedLayout: false,
208
+ finitenessFallbackWindowOpen: false,
209
+ },
210
+ 'batchDecodeEnabled'
211
+ );
212
+ errors.push(...batchShape.errors);
213
+ checks.push({
214
+ id: 'inference.execution.batchDecodeEnabled.shape',
215
+ ok: batchShape.ok,
216
+ });
217
+
218
+ const batchSemantics = Array.isArray(batchRules)
219
+ ? checkRuleSemantics(
220
+ batchRules,
221
+ enumerateBatchDecodeContexts(),
222
+ batchDecodeSemantic,
223
+ 'batchDecodeEnabled'
224
+ )
225
+ : { ok: false, errors: ['[ExecutionRulesContract] batchDecodeEnabled is unavailable for semantic check.'], sampledContexts: 0 };
226
+ errors.push(...batchSemantics.errors);
227
+ checks.push({
228
+ id: 'inference.execution.batchDecodeEnabled.semantics',
229
+ ok: batchSemantics.ok,
230
+ });
231
+
232
+ return {
233
+ schemaVersion: 1,
234
+ source: 'doppler',
235
+ ok: errors.length === 0,
236
+ checks,
237
+ errors,
238
+ stats: {
239
+ decodeRecorderRules: Array.isArray(decodeRules) ? decodeRules.length : 0,
240
+ batchDecodeRules: Array.isArray(batchRules) ? batchRules.length : 0,
241
+ decodeRecorderContexts: decodeSemantics.sampledContexts,
242
+ batchDecodeContexts: batchSemantics.sampledContexts,
243
+ },
244
+ };
245
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "variant": [
3
+ { "match": { "isF16": true }, "value": "default_f16" },
4
+ { "match": {}, "value": "default" }
5
+ ]
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "variant": [
3
+ { "match": { "isF16": true }, "value": "default_f16" },
4
+ { "match": {}, "value": "default" }
5
+ ]
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "variant": [
3
+ { "match": { "dtype": "f16" }, "value": "default_f16" },
4
+ { "match": {}, "value": "default" }
5
+ ]
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "variant": [
3
+ { "match": { "dtype": "f16" }, "value": "default_f16" },
4
+ { "match": {}, "value": "default" }
5
+ ]
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "variant": [
3
+ { "match": { "isF16": true }, "value": "default_f16" },
4
+ { "match": {}, "value": "default" }
5
+ ]
6
+ }
@@ -0,0 +1,17 @@
1
+ export interface LayerPatternContractArtifact {
2
+ schemaVersion: 1;
3
+ source: 'doppler';
4
+ ok: boolean;
5
+ checks: Array<{ id: string; ok: boolean }>;
6
+ errors: string[];
7
+ stats: {
8
+ patternKindRules: number;
9
+ layerTypeRules: number;
10
+ patternKindContexts: number;
11
+ layerTypeContexts: number;
12
+ };
13
+ }
14
+
15
+ export declare function buildLayerPatternContractArtifact(
16
+ ruleGroup: Record<string, unknown> | null | undefined
17
+ ): LayerPatternContractArtifact;