@artemiskit/core 0.5.1 → 0.5.3
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 +16 -0
- package/dist/artifacts/manifest.d.ts +4 -1
- package/dist/artifacts/manifest.d.ts.map +1 -1
- package/dist/artifacts/types.d.ts +58 -0
- package/dist/artifacts/types.d.ts.map +1 -1
- package/dist/comparison/eligibility.d.ts +26 -0
- package/dist/comparison/eligibility.d.ts.map +1 -0
- package/dist/comparison/index.d.ts +2 -0
- package/dist/comparison/index.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +590 -392
- package/dist/runner/executor.d.ts.map +1 -1
- package/dist/runner/runner.d.ts.map +1 -1
- package/dist/runner/types.d.ts +13 -1
- package/dist/runner/types.d.ts.map +1 -1
- package/dist/storage/local.d.ts.map +1 -1
- package/dist/storage/supabase.d.ts.map +1 -1
- package/dist/storage/types.d.ts +5 -1
- package/dist/storage/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/artifacts/manifest.test.ts +87 -1
- package/src/artifacts/manifest.ts +21 -29
- package/src/artifacts/types.ts +173 -0
- package/src/comparison/eligibility.test.ts +101 -0
- package/src/comparison/eligibility.ts +116 -0
- package/src/comparison/index.ts +8 -0
- package/src/index.ts +3 -0
- package/src/runner/executor.test.ts +50 -0
- package/src/runner/executor.ts +74 -2
- package/src/runner/runner.ts +20 -0
- package/src/runner/types.ts +7 -1
- package/src/scenario/schema.ts +1 -1
- package/src/storage/local.test.ts +39 -0
- package/src/storage/local.ts +9 -1
- package/src/storage/supabase.ts +9 -1
- package/src/storage/types.ts +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/runner/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/runner/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAKV,UAAU,EACX,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAQnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAwE/C;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,UAAU,CAAC,CA6ErB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAErD;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAyJzE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CASlF"}
|
package/dist/runner/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Runner types and interfaces
|
|
3
3
|
*/
|
|
4
4
|
import type { ModelClient } from '../adapters/types';
|
|
5
|
-
import type { CaseResult, ResolvedConfig, RunManifest } from '../artifacts/types';
|
|
5
|
+
import type { CaseResult, CostProvenance, ResolvedConfig, RunManifest } from '../artifacts/types';
|
|
6
6
|
import type { RedactionConfig } from '../redaction/types';
|
|
7
7
|
import type { Scenario } from '../scenario/schema';
|
|
8
8
|
import type { ToolExecutor } from '../tools';
|
|
@@ -26,6 +26,13 @@ export interface RunOptions {
|
|
|
26
26
|
timeout?: number;
|
|
27
27
|
/** Number of retries per case */
|
|
28
28
|
retries?: number;
|
|
29
|
+
/** One-based coordinate for an independently planned repetition. */
|
|
30
|
+
repetition?: {
|
|
31
|
+
index: number;
|
|
32
|
+
total: number;
|
|
33
|
+
};
|
|
34
|
+
/** Attested or operator-supplied monetary evidence; omitted means unavailable. */
|
|
35
|
+
costProvenance?: CostProvenance;
|
|
29
36
|
/** Redaction configuration (CLI overrides scenario) */
|
|
30
37
|
redaction?: RedactionConfig;
|
|
31
38
|
/** SDK-only executor for explicitly supplied real tools. */
|
|
@@ -56,6 +63,11 @@ export interface ExecutorContext {
|
|
|
56
63
|
requestedModel?: string;
|
|
57
64
|
timeout?: number;
|
|
58
65
|
retries?: number;
|
|
66
|
+
runId?: string;
|
|
67
|
+
repetition?: {
|
|
68
|
+
index: number;
|
|
69
|
+
total: number;
|
|
70
|
+
};
|
|
59
71
|
/** Redaction configuration for this execution */
|
|
60
72
|
redaction?: RedactionConfig;
|
|
61
73
|
toolExecutor?: ToolExecutor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runner/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runner/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAClG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,0BAA0B;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,kFAAkF;IAClF,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,uDAAuD;IACvD,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,4DAA4D;IAC5D,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,oCAAoC;IACpC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5E,oCAAoC;IACpC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,6BAA6B;IAC7B,QAAQ,EAAE,WAAW,CAAC;IACtB,8BAA8B;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,+BAA+B;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,iDAAiD;IACjD,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,cAAc,EAGpB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/storage/local.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,cAAc,EAGpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACZ,MAAM,SAAS,CAAC;AAyDjB,qBAAa,mBAAoB,YAAW,sBAAsB;IAChE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;gBAElB,QAAQ,SAAmB;IAKjC,IAAI,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAa5C,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAczC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAS5C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAQpD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAQlD,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA0DnD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAuBjE,eAAe;YASf,SAAS;IAWvB;;OAEG;YACW,iBAAiB;IAS/B;;OAEG;YACW,iBAAiB;IAM/B;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4B3F;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKrE;;OAEG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAMzE;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAOlD;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD;;OAEG;IACG,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW5D;;OAEG;IACG,iBAAiB,CACrB,KAAK,EAAE,MAAM,EACb,mBAAmB,SAAO,GACzB,OAAO,CAAC;QACT,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,UAAU,EAAE,gBAAgB,CAAC;QAC7B,aAAa,EAAE,OAAO,CAAC;QACvB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,GAAG,IAAI,CAAC;CAyBV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/storage/supabase.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAEL,KAAK,WAAW,EAGjB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/storage/supabase.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Storage types and interfaces
|
|
3
3
|
*/
|
|
4
4
|
import type { AnyManifest, CaseEvaluationEvidence, RedTeamManifest, RunManifest, StressManifest } from '../artifacts/types';
|
|
5
|
+
import type { ComparisonEligibility } from '../comparison';
|
|
5
6
|
/**
|
|
6
7
|
* Run listing item
|
|
7
8
|
*/
|
|
@@ -21,7 +22,10 @@ export interface RunListItem {
|
|
|
21
22
|
export interface ComparisonResult {
|
|
22
23
|
baseline: RunManifest;
|
|
23
24
|
current: RunManifest;
|
|
24
|
-
delta
|
|
25
|
+
/** Compatibility decision made before any metric delta is calculated. */
|
|
26
|
+
eligibility: ComparisonEligibility;
|
|
27
|
+
/** Absent when workloads or rubrics are incomparable. */
|
|
28
|
+
delta?: {
|
|
25
29
|
successRate: number;
|
|
26
30
|
latency: number;
|
|
27
31
|
tokens: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,WAAW,EACX,cAAc,EACf,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -55,13 +55,19 @@ describe('createRunManifest', () => {
|
|
|
55
55
|
endTime,
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
expect(manifest.version).toBe('1.
|
|
58
|
+
expect(manifest.version).toBe('1.4');
|
|
59
59
|
expect(manifest.project).toBe('test-project');
|
|
60
60
|
expect(manifest.run_id).toBeTruthy();
|
|
61
61
|
expect(manifest.run_id.length).toBe(12);
|
|
62
62
|
expect(manifest.config.scenario).toBe('test-scenario');
|
|
63
63
|
expect(manifest.config.provider).toBe('openai');
|
|
64
64
|
expect(manifest.config.model).toBe('gpt-4');
|
|
65
|
+
expect(manifest.metrics.cost).toBeUndefined();
|
|
66
|
+
expect(manifest.metrics.cost_provenance).toEqual({
|
|
67
|
+
schema_version: '1',
|
|
68
|
+
status: 'unavailable',
|
|
69
|
+
unavailable_reason: 'provider_billing_not_recorded',
|
|
70
|
+
});
|
|
65
71
|
});
|
|
66
72
|
|
|
67
73
|
test('calculates metrics correctly', () => {
|
|
@@ -340,4 +346,84 @@ describe('createRunManifest', () => {
|
|
|
340
346
|
})
|
|
341
347
|
).toThrow('malformed target evidence');
|
|
342
348
|
});
|
|
349
|
+
|
|
350
|
+
test('retains attested cost evidence but rejects malformed monetary claims', () => {
|
|
351
|
+
const manifest = createRunManifest({
|
|
352
|
+
project: 'test-project',
|
|
353
|
+
config: { scenario: 'cost', provider: 'openai' },
|
|
354
|
+
costProvenance: {
|
|
355
|
+
schema_version: '1',
|
|
356
|
+
status: 'known',
|
|
357
|
+
amount: 1.25,
|
|
358
|
+
currency: 'USD',
|
|
359
|
+
source: 'provider_billing',
|
|
360
|
+
recorded_at: '2026-09-10T00:00:00.000Z',
|
|
361
|
+
},
|
|
362
|
+
cases: mockCases,
|
|
363
|
+
startTime: new Date(),
|
|
364
|
+
endTime: new Date(),
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
expect(manifest.metrics.cost_provenance?.status).toBe('known');
|
|
368
|
+
expect(() => assertRunManifestIntegrity(manifest)).not.toThrow();
|
|
369
|
+
expect(() =>
|
|
370
|
+
assertRunManifestIntegrity({
|
|
371
|
+
...manifest,
|
|
372
|
+
metrics: {
|
|
373
|
+
...manifest.metrics,
|
|
374
|
+
cost_provenance: { schema_version: '1', status: 'known', amount: 1 },
|
|
375
|
+
},
|
|
376
|
+
})
|
|
377
|
+
).toThrow('malformed cost provenance');
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
test('validates bounded retry-chain evidence without requiring it from historical manifests', () => {
|
|
381
|
+
const manifest = createRunManifest({
|
|
382
|
+
project: 'test-project',
|
|
383
|
+
config: { scenario: 'retry', provider: 'fixture' },
|
|
384
|
+
attemptEvidence: {
|
|
385
|
+
schema_version: '1',
|
|
386
|
+
repetition: { index: 1, total: 2 },
|
|
387
|
+
retry_policy: { default_max_retries: 1, backoff: 'exponential', initial_delay_ms: 1000 },
|
|
388
|
+
timeout: { default_ms: 5000 },
|
|
389
|
+
},
|
|
390
|
+
cases: [
|
|
391
|
+
{
|
|
392
|
+
...mockCases[0],
|
|
393
|
+
attempts: 2,
|
|
394
|
+
attempt_evidence: [
|
|
395
|
+
{
|
|
396
|
+
attempt_id: 'run:case-1:1',
|
|
397
|
+
retry_chain_id: 'run:case-1',
|
|
398
|
+
repetition_index: 1,
|
|
399
|
+
attempt_number: 1,
|
|
400
|
+
status: 'error',
|
|
401
|
+
included_in_outcome: false,
|
|
402
|
+
latency_ms: 3,
|
|
403
|
+
error_code: 'target_error',
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
attempt_id: 'run:case-1:2',
|
|
407
|
+
retry_chain_id: 'run:case-1',
|
|
408
|
+
repetition_index: 1,
|
|
409
|
+
attempt_number: 2,
|
|
410
|
+
status: 'passed',
|
|
411
|
+
included_in_outcome: true,
|
|
412
|
+
latency_ms: 4,
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
},
|
|
416
|
+
],
|
|
417
|
+
startTime: new Date(),
|
|
418
|
+
endTime: new Date(),
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
expect(() => assertRunManifestIntegrity(manifest)).not.toThrow();
|
|
422
|
+
expect(() =>
|
|
423
|
+
assertRunManifestIntegrity({
|
|
424
|
+
...manifest,
|
|
425
|
+
cases: [{ ...manifest.cases[0], attempt_evidence: [] }],
|
|
426
|
+
})
|
|
427
|
+
).toThrow('malformed attempt evidence');
|
|
428
|
+
});
|
|
343
429
|
});
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { nanoid } from 'nanoid';
|
|
6
|
-
import { estimateCost, getModelPricing } from '../cost/pricing';
|
|
7
6
|
import { getEnvironmentInfo } from '../provenance/environment';
|
|
8
7
|
import { getGitInfo } from '../provenance/git';
|
|
9
8
|
import type {
|
|
10
9
|
CaseResult,
|
|
11
|
-
|
|
10
|
+
CostProvenance,
|
|
12
11
|
ExecutionProvenance,
|
|
13
12
|
ManifestRedactionInfo,
|
|
14
13
|
ResolvedConfig,
|
|
14
|
+
RunAttemptEvidence,
|
|
15
15
|
RunConfig,
|
|
16
16
|
RunManifest,
|
|
17
17
|
RunMetrics,
|
|
@@ -28,6 +28,9 @@ export function createRunManifest(options: {
|
|
|
28
28
|
resolvedConfig?: ResolvedConfig;
|
|
29
29
|
workloadIdentity?: WorkloadIdentity;
|
|
30
30
|
executionProvenance?: ExecutionProvenance;
|
|
31
|
+
attemptEvidence?: RunAttemptEvidence;
|
|
32
|
+
costProvenance?: CostProvenance;
|
|
33
|
+
runId?: string;
|
|
31
34
|
cases: CaseResult[];
|
|
32
35
|
startTime: Date;
|
|
33
36
|
endTime: Date;
|
|
@@ -41,6 +44,9 @@ export function createRunManifest(options: {
|
|
|
41
44
|
resolvedConfig,
|
|
42
45
|
workloadIdentity,
|
|
43
46
|
executionProvenance,
|
|
47
|
+
attemptEvidence,
|
|
48
|
+
costProvenance,
|
|
49
|
+
runId,
|
|
44
50
|
cases,
|
|
45
51
|
startTime,
|
|
46
52
|
endTime,
|
|
@@ -49,15 +55,13 @@ export function createRunManifest(options: {
|
|
|
49
55
|
redaction,
|
|
50
56
|
} = options;
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
const modelForCost = resolvedConfig?.model || config.model;
|
|
54
|
-
const metrics = calculateMetrics(cases, modelForCost);
|
|
58
|
+
const metrics = calculateMetrics(cases, costProvenance);
|
|
55
59
|
const git = getGitInfo();
|
|
56
60
|
const environment = getEnvironmentInfo();
|
|
57
61
|
|
|
58
62
|
return {
|
|
59
|
-
version: '1.
|
|
60
|
-
run_id: nanoid(12),
|
|
63
|
+
version: '1.4',
|
|
64
|
+
run_id: runId ?? nanoid(12),
|
|
61
65
|
project,
|
|
62
66
|
start_time: startTime.toISOString(),
|
|
63
67
|
end_time: endTime.toISOString(),
|
|
@@ -66,6 +70,7 @@ export function createRunManifest(options: {
|
|
|
66
70
|
resolved_config: resolvedConfig,
|
|
67
71
|
workload_identity: workloadIdentity,
|
|
68
72
|
execution_provenance: executionProvenance,
|
|
73
|
+
attempt_evidence: attemptEvidence,
|
|
69
74
|
metrics,
|
|
70
75
|
git,
|
|
71
76
|
provenance: {
|
|
@@ -82,7 +87,7 @@ export function createRunManifest(options: {
|
|
|
82
87
|
/**
|
|
83
88
|
* Calculate metrics from case results
|
|
84
89
|
*/
|
|
85
|
-
function calculateMetrics(cases: CaseResult[],
|
|
90
|
+
function calculateMetrics(cases: CaseResult[], costProvenance?: CostProvenance): RunMetrics {
|
|
86
91
|
const passedCases = cases.filter((c) => getCaseEvaluationStatus(c) === 'passed');
|
|
87
92
|
const validCases = cases.filter((c) => {
|
|
88
93
|
const status = getCaseEvaluationStatus(c);
|
|
@@ -98,26 +103,13 @@ function calculateMetrics(cases: CaseResult[], model?: string): RunMetrics {
|
|
|
98
103
|
const totalPromptTokens = cases.reduce((sum, c) => sum + c.tokens.prompt, 0);
|
|
99
104
|
const totalCompletionTokens = cases.reduce((sum, c) => sum + c.tokens.completion, 0);
|
|
100
105
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const costEstimate = estimateCost(totalPromptTokens, totalCompletionTokens, model);
|
|
109
|
-
const pricing = getModelPricing(model);
|
|
110
|
-
cost = {
|
|
111
|
-
total_usd: costEstimate.totalUsd,
|
|
112
|
-
prompt_cost_usd: costEstimate.promptCostUsd,
|
|
113
|
-
completion_cost_usd: costEstimate.completionCostUsd,
|
|
114
|
-
model: costEstimate.model,
|
|
115
|
-
pricing: {
|
|
116
|
-
prompt_per_1k: pricing.promptPer1K,
|
|
117
|
-
completion_per_1k: pricing.completionPer1K,
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
}
|
|
106
|
+
// Token counts are not provider billing records. Never turn a generic price
|
|
107
|
+
// table into assurance cost evidence.
|
|
108
|
+
const cost_provenance: CostProvenance = costProvenance ?? {
|
|
109
|
+
schema_version: '1',
|
|
110
|
+
status: 'unavailable',
|
|
111
|
+
unavailable_reason: 'provider_billing_not_recorded',
|
|
112
|
+
};
|
|
121
113
|
|
|
122
114
|
return {
|
|
123
115
|
success_rate: validCases.length > 0 ? passedCases.length / validCases.length : 0,
|
|
@@ -133,7 +125,7 @@ function calculateMetrics(cases: CaseResult[], model?: string): RunMetrics {
|
|
|
133
125
|
total_tokens: totalPromptTokens + totalCompletionTokens,
|
|
134
126
|
total_prompt_tokens: totalPromptTokens,
|
|
135
127
|
total_completion_tokens: totalCompletionTokens,
|
|
136
|
-
|
|
128
|
+
cost_provenance,
|
|
137
129
|
};
|
|
138
130
|
}
|
|
139
131
|
|
package/src/artifacts/types.ts
CHANGED
|
@@ -124,6 +124,39 @@ export interface CaseEvaluationEvidence {
|
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
/** A bounded record of one execution in a retry chain. */
|
|
128
|
+
export interface CaseAttemptEvidence {
|
|
129
|
+
attempt_id: string;
|
|
130
|
+
retry_chain_id: string;
|
|
131
|
+
/** One-based coordinate within a deliberately independent repetition. */
|
|
132
|
+
repetition_index: number;
|
|
133
|
+
/** One-based coordinate within this retry chain. */
|
|
134
|
+
attempt_number: number;
|
|
135
|
+
status: CaseEvaluationStatus;
|
|
136
|
+
/** Only the terminal measurement can contribute to an outcome rate. */
|
|
137
|
+
included_in_outcome: boolean;
|
|
138
|
+
latency_ms: number;
|
|
139
|
+
/** Sanitized classification, never arbitrary provider error text. */
|
|
140
|
+
error_code?: 'timeout' | 'target_error' | 'tool_error';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Declared retry and repetition context for a run. */
|
|
144
|
+
export interface RunAttemptEvidence {
|
|
145
|
+
schema_version: '1';
|
|
146
|
+
repetition: {
|
|
147
|
+
index: number;
|
|
148
|
+
total: number;
|
|
149
|
+
};
|
|
150
|
+
retry_policy: {
|
|
151
|
+
default_max_retries: number;
|
|
152
|
+
backoff: 'exponential';
|
|
153
|
+
initial_delay_ms: number;
|
|
154
|
+
};
|
|
155
|
+
timeout?: {
|
|
156
|
+
default_ms: number;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
127
160
|
/**
|
|
128
161
|
* Individual test case result
|
|
129
162
|
*/
|
|
@@ -135,6 +168,8 @@ export interface CaseResult {
|
|
|
135
168
|
status?: CaseEvaluationStatus;
|
|
136
169
|
/** Number of execution attempts represented by this terminal result. */
|
|
137
170
|
attempts?: number;
|
|
171
|
+
/** Bounded retry-chain evidence for this terminal case result. */
|
|
172
|
+
attempt_evidence?: CaseAttemptEvidence[];
|
|
138
173
|
score: number;
|
|
139
174
|
matcherType: string;
|
|
140
175
|
reason?: string;
|
|
@@ -180,6 +215,28 @@ export interface CostEstimateInfo {
|
|
|
180
215
|
};
|
|
181
216
|
}
|
|
182
217
|
|
|
218
|
+
/** Whether a monetary value is attested, supplied by an operator, or unavailable. */
|
|
219
|
+
export type CostProvenanceStatus = 'known' | 'user_supplied' | 'unavailable';
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Cost evidence suitable for assurance reporting. Generic token-price estimates
|
|
223
|
+
* are intentionally not cost evidence.
|
|
224
|
+
*/
|
|
225
|
+
export interface CostProvenance {
|
|
226
|
+
schema_version: '1';
|
|
227
|
+
status: CostProvenanceStatus;
|
|
228
|
+
/** Required for known and user-supplied amounts. */
|
|
229
|
+
amount?: number;
|
|
230
|
+
/** ISO 4217 currency required with an amount. */
|
|
231
|
+
currency?: string;
|
|
232
|
+
/** Origin of a recorded monetary value. */
|
|
233
|
+
source?: 'provider_billing' | 'operator_input';
|
|
234
|
+
/** ISO timestamp for a recorded monetary value. */
|
|
235
|
+
recorded_at?: string;
|
|
236
|
+
/** Stable reason code when no attested amount is available. */
|
|
237
|
+
unavailable_reason?: 'provider_billing_not_recorded' | 'unsupported_provider' | 'not_requested';
|
|
238
|
+
}
|
|
239
|
+
|
|
183
240
|
/**
|
|
184
241
|
* Run metrics
|
|
185
242
|
*/
|
|
@@ -202,7 +259,10 @@ export interface RunMetrics {
|
|
|
202
259
|
total_prompt_tokens: number;
|
|
203
260
|
total_completion_tokens: number;
|
|
204
261
|
/** Estimated cost information */
|
|
262
|
+
/** @deprecated Generic pricing estimates are not assurance cost evidence. */
|
|
205
263
|
cost?: CostEstimateInfo;
|
|
264
|
+
/** Explicit monetary evidence for assurance reporting. */
|
|
265
|
+
cost_provenance?: CostProvenance;
|
|
206
266
|
}
|
|
207
267
|
|
|
208
268
|
/**
|
|
@@ -333,6 +393,8 @@ export interface RunManifest {
|
|
|
333
393
|
workload_identity?: WorkloadIdentity;
|
|
334
394
|
/** Requested and observed target/evaluator configuration for this run. */
|
|
335
395
|
execution_provenance?: ExecutionProvenance;
|
|
396
|
+
/** Retry-chain and repetition context. Present in manifest v1.4+. */
|
|
397
|
+
attempt_evidence?: RunAttemptEvidence;
|
|
336
398
|
metrics: RunMetrics;
|
|
337
399
|
git: GitInfo;
|
|
338
400
|
provenance: ProvenanceInfo;
|
|
@@ -385,6 +447,12 @@ export function assertRunManifestIntegrity(manifest: unknown): asserts manifest
|
|
|
385
447
|
if (manifest.execution_provenance !== undefined) {
|
|
386
448
|
assertExecutionProvenance(manifest.execution_provenance);
|
|
387
449
|
}
|
|
450
|
+
if (manifest.attempt_evidence !== undefined) {
|
|
451
|
+
assertRunAttemptEvidence(manifest.attempt_evidence);
|
|
452
|
+
}
|
|
453
|
+
if (isRecord(manifest.metrics) && manifest.metrics.cost_provenance !== undefined) {
|
|
454
|
+
assertCostProvenance(manifest.metrics.cost_provenance);
|
|
455
|
+
}
|
|
388
456
|
|
|
389
457
|
for (const [index, caseResult] of manifest.cases.entries()) {
|
|
390
458
|
if (!isRecord(caseResult)) {
|
|
@@ -407,9 +475,114 @@ export function assertRunManifestIntegrity(manifest: unknown): asserts manifest
|
|
|
407
475
|
if (caseResult.target !== undefined) {
|
|
408
476
|
assertCaseTargetEvidence(caseResult.target);
|
|
409
477
|
}
|
|
478
|
+
if (caseResult.attempt_evidence !== undefined) {
|
|
479
|
+
assertCaseAttemptEvidence(caseResult.attempt_evidence, index);
|
|
480
|
+
}
|
|
410
481
|
}
|
|
411
482
|
}
|
|
412
483
|
|
|
484
|
+
function assertRunAttemptEvidence(evidence: unknown): void {
|
|
485
|
+
if (
|
|
486
|
+
!isRecord(evidence) ||
|
|
487
|
+
evidence.schema_version !== '1' ||
|
|
488
|
+
!isRecord(evidence.repetition) ||
|
|
489
|
+
!isPositiveSafeInteger(evidence.repetition.index) ||
|
|
490
|
+
!isPositiveSafeInteger(evidence.repetition.total) ||
|
|
491
|
+
evidence.repetition.index > evidence.repetition.total ||
|
|
492
|
+
!isRecord(evidence.retry_policy) ||
|
|
493
|
+
!isNonnegativeSafeInteger(evidence.retry_policy.default_max_retries) ||
|
|
494
|
+
evidence.retry_policy.backoff !== 'exponential' ||
|
|
495
|
+
!isNonnegativeFiniteNumber(evidence.retry_policy.initial_delay_ms) ||
|
|
496
|
+
(evidence.timeout !== undefined &&
|
|
497
|
+
(!isRecord(evidence.timeout) || !isPositiveFiniteNumber(evidence.timeout.default_ms)))
|
|
498
|
+
) {
|
|
499
|
+
throw new Error('Invalid run manifest: malformed attempt evidence');
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function assertCaseAttemptEvidence(evidence: unknown, index: number): void {
|
|
504
|
+
if (!Array.isArray(evidence) || evidence.length === 0 || evidence.length > 100) {
|
|
505
|
+
throw new Error(`Invalid run manifest: case ${index} has malformed attempt evidence`);
|
|
506
|
+
}
|
|
507
|
+
for (const attempt of evidence) {
|
|
508
|
+
if (
|
|
509
|
+
!isRecord(attempt) ||
|
|
510
|
+
!isBoundedNonemptyString(attempt.attempt_id, 200) ||
|
|
511
|
+
!isBoundedNonemptyString(attempt.retry_chain_id, 200) ||
|
|
512
|
+
!isPositiveSafeInteger(attempt.repetition_index) ||
|
|
513
|
+
!isPositiveSafeInteger(attempt.attempt_number) ||
|
|
514
|
+
!isCaseEvaluationStatus(attempt.status) ||
|
|
515
|
+
typeof attempt.included_in_outcome !== 'boolean' ||
|
|
516
|
+
!isNonnegativeFiniteNumber(attempt.latency_ms) ||
|
|
517
|
+
(attempt.error_code !== undefined &&
|
|
518
|
+
attempt.error_code !== 'timeout' &&
|
|
519
|
+
attempt.error_code !== 'target_error' &&
|
|
520
|
+
attempt.error_code !== 'tool_error')
|
|
521
|
+
) {
|
|
522
|
+
throw new Error(`Invalid run manifest: case ${index} has malformed attempt evidence`);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
function assertCostProvenance(cost: unknown): void {
|
|
528
|
+
if (!isRecord(cost) || cost.schema_version !== '1') {
|
|
529
|
+
throw new Error('Invalid run manifest: malformed cost provenance');
|
|
530
|
+
}
|
|
531
|
+
if (cost.status === 'unavailable') {
|
|
532
|
+
if (
|
|
533
|
+
cost.amount !== undefined ||
|
|
534
|
+
cost.currency !== undefined ||
|
|
535
|
+
cost.source !== undefined ||
|
|
536
|
+
cost.recorded_at !== undefined ||
|
|
537
|
+
(cost.unavailable_reason !== 'provider_billing_not_recorded' &&
|
|
538
|
+
cost.unavailable_reason !== 'unsupported_provider' &&
|
|
539
|
+
cost.unavailable_reason !== 'not_requested')
|
|
540
|
+
) {
|
|
541
|
+
throw new Error('Invalid run manifest: malformed cost provenance');
|
|
542
|
+
}
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
if (
|
|
546
|
+
(cost.status !== 'known' && cost.status !== 'user_supplied') ||
|
|
547
|
+
!isNonnegativeFiniteNumber(cost.amount) ||
|
|
548
|
+
!isBoundedNonemptyString(cost.currency, 3) ||
|
|
549
|
+
(cost.status === 'known' && cost.source !== 'provider_billing') ||
|
|
550
|
+
(cost.status === 'user_supplied' && cost.source !== 'operator_input') ||
|
|
551
|
+
!isIsoTimestamp(cost.recorded_at) ||
|
|
552
|
+
cost.unavailable_reason !== undefined
|
|
553
|
+
) {
|
|
554
|
+
throw new Error('Invalid run manifest: malformed cost provenance');
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
function isCaseEvaluationStatus(value: unknown): value is CaseEvaluationStatus {
|
|
559
|
+
return value === 'passed' || value === 'failed' || value === 'invalid' || value === 'error';
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function isBoundedNonemptyString(value: unknown, maxLength: number): value is string {
|
|
563
|
+
return typeof value === 'string' && value.length > 0 && value.length <= maxLength;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
function isNonnegativeFiniteNumber(value: unknown): value is number {
|
|
567
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function isPositiveFiniteNumber(value: unknown): value is number {
|
|
571
|
+
return isNonnegativeFiniteNumber(value) && value > 0;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
function isNonnegativeSafeInteger(value: unknown): value is number {
|
|
575
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function isPositiveSafeInteger(value: unknown): value is number {
|
|
579
|
+
return isNonnegativeSafeInteger(value) && value > 0;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
function isIsoTimestamp(value: unknown): value is string {
|
|
583
|
+
return typeof value === 'string' && Number.isFinite(Date.parse(value));
|
|
584
|
+
}
|
|
585
|
+
|
|
413
586
|
function assertCaseTargetEvidence(target: unknown): void {
|
|
414
587
|
if (
|
|
415
588
|
!isRecord(target) ||
|