@attest-ai/vitest 1.0.0-rc.1 → 1.0.0-rc.2

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.
@@ -1,8 +1,17 @@
1
1
  import type { TestContext } from "vitest";
2
2
  import { type ExpectChain, AgentResult, AttestClient } from "@attest-ai/core";
3
+ import { type TestBudget } from "./test-state.js";
3
4
  export interface InspectOptions {
4
5
  /** Throw when the cumulative session cost exceeds this USD amount. */
5
6
  budget?: number;
7
+ /**
8
+ * Limits for this test's attest model calls. Each evaluation sends what is
9
+ * left: judge calls not yet used in the test, and `maxCostUsd` minus the
10
+ * test's attest cost and agent spend so far (trace `metadata.cost_usd`). A
11
+ * call that does not fit is not sent and its assertion is not_evaluated with
12
+ * reason "budget_exhausted". Inside trials(), defaults to the trials budget.
13
+ */
14
+ testBudget?: TestBudget;
6
15
  /**
7
16
  * The running test's context (`it("…", async (context) => …)`). Used to
8
17
  * attach results to the right test for AttestReporter and to skip it;
@@ -21,7 +30,8 @@ export interface EvaluateOptions extends InspectOptions {
21
30
  * Fail or skip the running Vitest test according to the batch outcome:
22
31
  * any hard_fail throws with rendered diagnostics; otherwise any
23
32
  * not_evaluated skips with "not evaluated: <reasons>" (throws when strict);
24
- * soft failures pass.
33
+ * soft failures pass. Inside a trial of trials() (N > 1) it does nothing and
34
+ * returns `result`: trials() enforces the aggregate outcome after the last trial.
25
35
  */
26
36
  export declare function enforceOutcome(result: AgentResult, strict: boolean, context?: TestContext): AgentResult;
27
37
  export declare class AttestEngineFixture {
@@ -48,8 +58,11 @@ export declare class AttestEngineFixture {
48
58
  evaluate(chain: ExpectChain, options?: EvaluateOptions): Promise<AgentResult>;
49
59
  }
50
60
  export declare function useAttest(): AttestEngineFixture;
51
- /** Evaluate and enforce: hard_fail throws, not_evaluated skips (strict: throws). */
61
+ /**
62
+ * Evaluate and enforce: hard_fail throws, not_evaluated skips (strict: throws).
63
+ * Inside a trial of trials() (N > 1) it does not enforce, like inspect().
64
+ */
52
65
  export declare function evaluate(chain: ExpectChain, options?: EvaluateOptions): Promise<AgentResult>;
53
- /** Evaluate without enforcing; use for trial loops and custom checks. */
66
+ /** Evaluate without enforcing; use for custom checks. For repeated runs use trials(). */
54
67
  export declare function inspect(chain: ExpectChain, options?: InspectOptions): Promise<AgentResult>;
55
68
  //# sourceMappingURL=fixtures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EACL,KAAK,WAAW,EAChB,WAAW,EACX,YAAY,EAQb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA8CD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,WAAW,CAUb;AAmBD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAA;KAAE;IAWvF;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,IAAI,MAAM,IAAI,YAAY,CAKzB;YAEa,aAAa;IAM3B,wEAAwE;IAClE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IA4CjF,kEAAkE;IAC5D,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;CAIpF;AAOD,wBAAgB,SAAS,IAAI,mBAAmB,CAO/C;AAED,oFAAoF;AACpF,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,yEAAyE;AACzE,wBAAsB,OAAO,CAC3B,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,WAAW,CAAC,CAEtB"}
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EACL,KAAK,WAAW,EAChB,WAAW,EAEX,YAAY,EASb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAYL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,WAAW,CAab;AAmBD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAA;KAAE;IAWvF;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,IAAI,MAAM,IAAI,YAAY,CAKzB;YAEa,aAAa;IAM3B,wEAAwE;IAClE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IA4EjF,kEAAkE;IAC5D,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;CAIpF;AAOD,wBAAgB,SAAS,IAAI,mBAAmB,CAO/C;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,yFAAyF;AACzF,wBAAsB,OAAO,CAC3B,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,WAAW,CAAC,CAEtB"}
package/dist/fixtures.js CHANGED
@@ -1,58 +1,23 @@
1
1
  import * as vitest from "vitest";
2
- import { AgentResult, AttestClient, EngineManager, isSimulationMode, renderDiagnostics, requireSimulationCapability, OUTCOME_FAIL, OUTCOME_SKIP, STATUS_SOFT_FAIL, } from "@attest-ai/core";
3
- /**
4
- * The running test: `TestRunner.getCurrentTest()` on Vitest 4.1+, `vitest/suite`
5
- * before that (loaded only there, because Vitest 4.1 warns when it is imported).
6
- */
7
- async function runningTest() {
8
- const runner = vitest.TestRunner;
9
- if (runner !== undefined)
10
- return runner.getCurrentTest();
11
- const suite = await import("vitest/suite");
12
- return suite.getCurrentTest();
13
- }
14
- /**
15
- * Attach the results to the running test's meta so AttestReporter, in the main
16
- * process, can write them with the test's file and line. Results from an earlier
17
- * attempt of a retried test are dropped, so the report matches the outcome Vitest
18
- * reports. Outside a test (e.g. in a beforeAll hook) there is no test to attach to.
19
- */
20
- async function recordOnTest(result, context) {
21
- const test = context?.task ?? (await runningTest());
22
- if (test === undefined)
23
- return;
24
- if (context === undefined && test.concurrent === true) {
25
- throw new Error("Attest results from a test.concurrent test — pass the test context: " +
26
- "inspect(chain, { context }) or evaluate(chain, { context })");
27
- }
28
- const attempt = test.result?.retryCount ?? 0;
29
- let meta = test.meta.attest;
30
- if (meta === undefined || meta.attempt !== attempt) {
31
- meta = { attempt, results: [], totalCost: 0, totalDurationMs: 0 };
32
- test.meta.attest = meta;
33
- }
34
- meta.results.push(...result.assertionResults);
35
- meta.totalCost += result.totalCost;
36
- meta.totalDurationMs += result.totalDurationMs;
37
- }
38
- function strictFromEnv() {
39
- const v = (process.env["ATTEST_STRICT"] ?? "").trim().toLowerCase();
40
- return v === "1" || v === "true" || v === "yes";
41
- }
2
+ import { AgentResult, STATUS_SOFT_FAIL, AttestClient, EngineManager, isSimulationMode, renderDiagnostics, requireSimulationCapability, OUTCOME_FAIL, OUTCOME_SKIP, zeroUsage, } from "@attest-ai/core";
3
+ import { assignAssertionIds, attemptState, inTrial, recordAgentSpend, recordOnTest, recordUnattachedUsage, remainingBudget, resolveTest, strictFromEnv, trialScope, validateBudget, } from "./test-state.js";
42
4
  /**
43
5
  * Fail or skip the running Vitest test according to the batch outcome:
44
6
  * any hard_fail throws with rendered diagnostics; otherwise any
45
7
  * not_evaluated skips with "not evaluated: <reasons>" (throws when strict);
46
- * soft failures pass.
8
+ * soft failures pass. Inside a trial of trials() (N > 1) it does nothing and
9
+ * returns `result`: trials() enforces the aggregate outcome after the last trial.
47
10
  */
48
11
  export function enforceOutcome(result, strict, context) {
12
+ if (inTrial())
13
+ return result;
49
14
  const outcome = result.outcome({ strict });
50
15
  if (outcome === OUTCOME_FAIL) {
51
16
  const header = result.hardFailures.length === 0 ? `strict: ${result.skipReason()}\n` : "";
52
17
  throw new Error(header + renderDiagnostics(result).replace(/^\n/, ""));
53
18
  }
54
19
  if (outcome === OUTCOME_SKIP) {
55
- (context ?? currentTestContext(result)).skip(result.skipReason());
20
+ (context ?? trialScope.getStore()?.test.context ?? currentTestContext(result)).skip(result.skipReason());
56
21
  }
57
22
  return result;
58
23
  }
@@ -131,14 +96,44 @@ export class AttestEngineFixture {
131
96
  /** Evaluate collected assertions without enforcing the test outcome. */
132
97
  async inspect(chain, options) {
133
98
  await this.ensureStarted();
134
- const result = await this.client.evaluateBatch(chain.trace, chain.assertions);
99
+ // Inside a test, assertion IDs are deterministic (the test's report test_id
100
+ // and the assertion's ordinal in the test, restarting each trial) so trials
101
+ // and baselines match rows by ID. Outside a test they stay random.
102
+ const test = await resolveTest(options?.context);
103
+ const scope = trialScope.getStore();
104
+ const trial = scope !== undefined && scope.test === test ? scope.trial : undefined;
105
+ const budget = options?.testBudget !== undefined
106
+ ? validateBudget(options.testBudget)
107
+ : scope !== undefined && scope.test === test
108
+ ? scope.budget
109
+ : undefined;
110
+ let assertions = chain.assertions;
111
+ let batchBudget;
112
+ if (test !== undefined) {
113
+ assertions = assignAssertionIds(test, assertions);
114
+ recordAgentSpend(test, chain.trace);
115
+ if (budget !== undefined) {
116
+ const state = attemptState(test);
117
+ batchBudget = remainingBudget(budget, state.usage, state.agentSpendUsd);
118
+ }
119
+ }
120
+ else if (budget !== undefined) {
121
+ // Outside a test the budget covers this one evaluation.
122
+ batchBudget = remainingBudget(budget, zeroUsage(), chain.trace.metadata?.cost_usd ?? 0);
123
+ }
124
+ const result = await this.client.evaluateBatch(chain.trace, assertions, batchBudget === undefined ? undefined : { budget: batchBudget });
135
125
  globalThis.__attest_session_cost__ =
136
126
  (globalThis.__attest_session_cost__ ?? 0) + (result.total_cost ?? 0);
137
127
  const softFailCount = (result.results ?? []).filter((r) => r.status === STATUS_SOFT_FAIL).length;
138
128
  globalThis.__attest_session_soft_failures__ =
139
129
  (globalThis.__attest_session_soft_failures__ ?? 0) + softFailCount;
140
- const agentResult = new AgentResult(chain.trace, result.results ?? [], result.total_cost ?? 0, result.total_duration_ms ?? 0);
141
- await recordOnTest(agentResult, options?.context);
130
+ const agentResult = new AgentResult(chain.trace, result.results ?? [], result.total_cost ?? 0, result.total_duration_ms ?? 0, result.usage);
131
+ if (test !== undefined)
132
+ recordOnTest(test, agentResult, trial);
133
+ else
134
+ recordUnattachedUsage(agentResult.usage);
135
+ if (scope !== undefined && scope.test === test)
136
+ scope.results.push(agentResult);
142
137
  // Track non-passing AgentResults so AttestCostReporter can render the
143
138
  // diagnostic block at the end of the run. Bound size because long
144
139
  // suites with many failures should not balloon RAM.
@@ -173,11 +168,14 @@ export function useAttest() {
173
168
  workerFixture ??= new AttestEngineFixture();
174
169
  return workerFixture;
175
170
  }
176
- /** Evaluate and enforce: hard_fail throws, not_evaluated skips (strict: throws). */
171
+ /**
172
+ * Evaluate and enforce: hard_fail throws, not_evaluated skips (strict: throws).
173
+ * Inside a trial of trials() (N > 1) it does not enforce, like inspect().
174
+ */
177
175
  export async function evaluate(chain, options) {
178
176
  return useAttest().evaluate(chain, options);
179
177
  }
180
- /** Evaluate without enforcing; use for trial loops and custom checks. */
178
+ /** Evaluate without enforcing; use for custom checks. For repeated runs use trials(). */
181
179
  export async function inspect(chain, options) {
182
180
  return useAttest().inspect(chain, options);
183
181
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,9 +2,12 @@ export { attestGlobalSetup } from "./plugin.js";
2
2
  export type { AttestGlobalSetupOptions } from "./plugin.js";
3
3
  export { AttestEngineFixture, useAttest, evaluate, inspect, enforceOutcome } from "./fixtures.js";
4
4
  export type { EvaluateOptions, InspectOptions } from "./fixtures.js";
5
+ export { trials, MIN_PASS_RATE_ENV } from "./trials.js";
6
+ export type { TrialsOptions } from "./trials.js";
7
+ export type { TestBudget } from "./test-state.js";
5
8
  export { AttestCostReporter, AttestReporter } from "./reporter.js";
6
9
  export type { AttestReporterOptions } from "./reporter.js";
7
- export { buildReport, REPORT_VERSION } from "./report.js";
8
- export type { AttestTaskMeta, TestOutcome, TestRecord } from "./report.js";
10
+ export { buildReport, REPORT_VERSION, sessionUsage, summaryLines } from "./report.js";
11
+ export type { AttestTaskMeta, RecordedResult, TestOutcome, TestRecord, TrialsMeta } from "./report.js";
9
12
  export { filterByTier } from "./tier-filter.js";
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClG,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClG,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtF,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACvG,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { attestGlobalSetup } from "./plugin.js";
2
2
  export { AttestEngineFixture, useAttest, evaluate, inspect, enforceOutcome } from "./fixtures.js";
3
+ export { trials, MIN_PASS_RATE_ENV } from "./trials.js";
3
4
  export { AttestCostReporter, AttestReporter } from "./reporter.js";
4
- export { buildReport, REPORT_VERSION } from "./report.js";
5
+ export { buildReport, REPORT_VERSION, sessionUsage, summaryLines } from "./report.js";
5
6
  export { filterByTier } from "./tier-filter.js";
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAElG,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAElG,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/plugin.d.ts CHANGED
@@ -2,6 +2,12 @@ import { EngineManager, AttestClient, type AgentResult } from "@attest-ai/core";
2
2
  export interface AttestGlobalSetupOptions {
3
3
  enginePath?: string;
4
4
  logLevel?: string;
5
+ /**
6
+ * Minimum passed / evaluated trials for every trials() test of the run (0..1,
7
+ * default 1.0); trials(body, { minPassRate }) overrides it per test. Reaches
8
+ * the workers as the ATTEST_MIN_PASS_RATE environment variable.
9
+ */
10
+ minPassRate?: number;
5
11
  }
6
12
  declare global {
7
13
  var __attest_engine__: EngineManager | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAKzB,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC;IAEjD,IAAI,iBAAiB,EAAE,YAAY,GAAG,SAAS,CAAC;IAEhD,IAAI,uBAAuB,EAAE,MAAM,CAAC;IAEpC,IAAI,gCAAgC,EAAE,MAAM,CAAC;IAE7C,IAAI,2BAA2B,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;CAC5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,wBAAwB;;;EA8CnE"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAMzB,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC;IAEjD,IAAI,iBAAiB,EAAE,YAAY,GAAG,SAAS,CAAC;IAEhD,IAAI,uBAAuB,EAAE,MAAM,CAAC;IAEpC,IAAI,gCAAgC,EAAE,MAAM,CAAC;IAE7C,IAAI,2BAA2B,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;CAC5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,wBAAwB;;;EAmDnE"}
package/dist/plugin.js CHANGED
@@ -1,9 +1,15 @@
1
1
  import { EngineManager, AttestClient, isSimulationMode, requireSimulationCapability, } from "@attest-ai/core";
2
+ import { MIN_PASS_RATE_ENV, validateMinPassRate } from "./trials.js";
2
3
  let engineManager;
3
4
  let attestClient;
4
5
  export function attestGlobalSetup(options) {
6
+ const minPassRate = options?.minPassRate === undefined
7
+ ? undefined
8
+ : validateMinPassRate(options.minPassRate, `minPassRate=${options.minPassRate}`);
5
9
  return {
6
10
  async setup() {
11
+ if (minPassRate !== undefined)
12
+ process.env[MIN_PASS_RATE_ENV] = String(minPassRate);
7
13
  globalThis.__attest_session_cost__ = 0;
8
14
  globalThis.__attest_session_soft_failures__ = 0;
9
15
  globalThis.__attest_session_failures__ = [];
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,2BAA2B,GAE5B,MAAM,iBAAiB,CAAC;AAEzB,IAAI,aAAwC,CAAC;AAC7C,IAAI,YAAsC,CAAC;AAoB3C,MAAM,UAAU,iBAAiB,CAAC,OAAkC;IAClE,OAAO;QACL,KAAK,CAAC,KAAK;YACT,UAAU,CAAC,uBAAuB,GAAG,CAAC,CAAC;YACvC,UAAU,CAAC,gCAAgC,GAAG,CAAC,CAAC;YAChD,UAAU,CAAC,2BAA2B,GAAG,EAAE,CAAC;YAE5C,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,iEAAiE;gBACjE,iDAAiD;gBACjD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC;YACzC,CAAC;YAED,aAAa,GAAG,IAAI,aAAa,CAAC;gBAChC,UAAU,EAAE,OAAO,EAAE,UAAU;gBAC/B,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,MAAM;aACtC,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;YACzC,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,2BAA2B,CAAC,IAAI,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;oBAC3B,aAAa,GAAG,SAAS,CAAC;oBAC1B,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;YACD,YAAY,GAAG,IAAI,YAAY,CAAC,aAAa,CAAC,CAAC;YAE/C,UAAU,CAAC,iBAAiB,GAAG,aAAa,CAAC;YAC7C,UAAU,CAAC,iBAAiB,GAAG,YAAY,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,QAAQ;YACZ,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;gBAC3B,aAAa,GAAG,SAAS,CAAC;gBAC1B,YAAY,GAAG,SAAS,CAAC;YAC3B,CAAC;YAED,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,2BAA2B,GAAG,SAAS,CAAC;QACrD,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,2BAA2B,GAE5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAErE,IAAI,aAAwC,CAAC;AAC7C,IAAI,YAAsC,CAAC;AA0B3C,MAAM,UAAU,iBAAiB,CAAC,OAAkC;IAClE,MAAM,WAAW,GACf,OAAO,EAAE,WAAW,KAAK,SAAS;QAChC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,WAAW,EAAE,eAAe,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACrF,OAAO;QACL,KAAK,CAAC,KAAK;YACT,IAAI,WAAW,KAAK,SAAS;gBAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;YACpF,UAAU,CAAC,uBAAuB,GAAG,CAAC,CAAC;YACvC,UAAU,CAAC,gCAAgC,GAAG,CAAC,CAAC;YAChD,UAAU,CAAC,2BAA2B,GAAG,EAAE,CAAC;YAE5C,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,iEAAiE;gBACjE,iDAAiD;gBACjD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC;YACzC,CAAC;YAED,aAAa,GAAG,IAAI,aAAa,CAAC;gBAChC,UAAU,EAAE,OAAO,EAAE,UAAU;gBAC/B,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,MAAM;aACtC,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC;YACzC,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,2BAA2B,CAAC,IAAI,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;oBAC3B,aAAa,GAAG,SAAS,CAAC;oBAC1B,MAAM,GAAG,CAAC;gBACZ,CAAC;YACH,CAAC;YACD,YAAY,GAAG,IAAI,YAAY,CAAC,aAAa,CAAC,CAAC;YAE/C,UAAU,CAAC,iBAAiB,GAAG,aAAa,CAAC;YAC7C,UAAU,CAAC,iBAAiB,GAAG,YAAY,CAAC;QAC9C,CAAC;QAED,KAAK,CAAC,QAAQ;YACZ,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;gBAC3B,aAAa,GAAG,SAAS,CAAC;gBAC1B,YAAY,GAAG,SAAS,CAAC;YAC3B,CAAC;YAED,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACzC,UAAU,CAAC,2BAA2B,GAAG,SAAS,CAAC;QACrD,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/report.d.ts CHANGED
@@ -6,16 +6,35 @@
6
6
  * outcome. `attest policy evaluate` gates on `results`; the pr-annotate action
7
7
  * places inline comments with `file` and `line`.
8
8
  */
9
- import { type AssertionResult } from "@attest-ai/core";
9
+ import { type AssertionResult, type Usage } from "@attest-ai/core";
10
10
  export declare const REPORT_VERSION = 2;
11
11
  export type TestOutcome = "passed" | "failed" | "skipped";
12
+ /** An assertion result as recorded for the report; `trial` is set under trials() with N > 1. */
13
+ export type RecordedResult = AssertionResult & {
14
+ readonly trial?: number;
15
+ };
16
+ /** How a trials() call with N > 1 went. */
17
+ export interface TrialsMeta {
18
+ /** N. */
19
+ requested: number;
20
+ /** Trials actually run; fewer than N when the test's cost budget was spent. */
21
+ run: number;
22
+ passed: number;
23
+ /** Trials that passed, failed or raised (not counting not-evaluated ones). */
24
+ evaluated: number;
25
+ notEvaluated: number;
26
+ stoppedByBudget: boolean;
27
+ }
12
28
  /** Attest results a test recorded, carried from the worker in task meta. */
13
29
  export interface AttestTaskMeta {
14
30
  /** `retryCount` of the attempt that produced `results`. */
15
31
  attempt: number;
16
- results: AssertionResult[];
32
+ results: RecordedResult[];
17
33
  totalCost: number;
18
34
  totalDurationMs: number;
35
+ /** Attest model usage of every attempt of the test, including retried ones. */
36
+ usage: Usage;
37
+ trials?: TrialsMeta;
19
38
  }
20
39
  declare module "vitest" {
21
40
  interface TaskMeta {
@@ -33,5 +52,18 @@ export interface TestRecord {
33
52
  durationMs: number;
34
53
  attest: AttestTaskMeta | undefined;
35
54
  }
36
- export declare function buildReport(tests: readonly TestRecord[], simulated: boolean): Record<string, unknown>;
55
+ /**
56
+ * `unattached` is the usage of evaluations that belong to no test (beforeAll,
57
+ * scripts); it counts in `summary.usage`.
58
+ */
59
+ export declare function buildReport(tests: readonly TestRecord[], simulated: boolean, unattached?: Usage): Record<string, unknown>;
60
+ /** Attest usage summed over every test of the run plus the evaluations that belong to no test. */
61
+ export declare function sessionUsage(tests: readonly TestRecord[], unattached?: Usage): Usage;
62
+ /**
63
+ * Lines for the end of the run: one per trials test
64
+ * ("<test_id>: <passed>/<evaluated> trials passed (<n> not evaluated)", plus a
65
+ * note when the test budget stopped it early), then the "attest usage: …" line
66
+ * when the session made or refused a model call.
67
+ */
68
+ export declare function summaryLines(tests: readonly TestRecord[], unattached?: Usage): string[];
37
69
  //# sourceMappingURL=report.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,QAAQ;QAChB,MAAM,CAAC,EAAE,cAAc,CAAC;KACzB;CACF;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8CrG"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAQL,KAAK,eAAe,EACpB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,gGAAgG;AAChG,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,SAAS;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,QAAQ;QAChB,MAAM,CAAC,EAAE,cAAc,CAAC;KACzB;CACF;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,SAAS,EAAE,OAAO,EAClB,UAAU,GAAE,KAAmB,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgDzB;AAED,kGAAkG;AAClG,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,UAAU,GAAE,KAAmB,GAAG,KAAK,CAEjG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,UAAU,GAAE,KAAmB,GAAG,MAAM,EAAE,CAiBpG"}
package/dist/report.js CHANGED
@@ -6,9 +6,13 @@
6
6
  * outcome. `attest policy evaluate` gates on `results`; the pr-annotate action
7
7
  * places inline comments with `file` and `line`.
8
8
  */
9
- import { STATUS_HARD_FAIL, STATUS_NOT_EVALUATED, STATUS_PASS, STATUS_SOFT_FAIL, } from "@attest-ai/core";
9
+ import { STATUS_HARD_FAIL, STATUS_NOT_EVALUATED, STATUS_PASS, STATUS_SOFT_FAIL, sumUsage, usageSummaryLine, zeroUsage, } from "@attest-ai/core";
10
10
  export const REPORT_VERSION = 2;
11
- export function buildReport(tests, simulated) {
11
+ /**
12
+ * `unattached` is the usage of evaluations that belong to no test (beforeAll,
13
+ * scripts); it counts in `summary.usage`.
14
+ */
15
+ export function buildReport(tests, simulated, unattached = zeroUsage()) {
12
16
  const rows = [];
13
17
  const testRows = [];
14
18
  let totalCost = 0;
@@ -16,13 +20,13 @@ export function buildReport(tests, simulated) {
16
20
  for (const test of tests) {
17
21
  if (test.line < 1)
18
22
  throw new Error(`${test.testId}: line must be >= 1, got ${test.line}`);
19
- const assertionIds = [];
23
+ const assertionIds = new Set();
20
24
  const reasons = [];
21
25
  totalCost += test.attest?.totalCost ?? 0;
22
26
  totalDurationMs += test.attest?.totalDurationMs ?? 0;
23
27
  for (const result of test.attest?.results ?? []) {
24
28
  rows.push({ ...result, test_id: test.testId, file: test.file, line: test.line });
25
- assertionIds.push(result.assertion_id);
29
+ assertionIds.add(result.assertion_id);
26
30
  if (result.status === STATUS_NOT_EVALUATED && !reasons.includes(String(result.reason))) {
27
31
  reasons.push(String(result.reason));
28
32
  }
@@ -34,8 +38,9 @@ export function buildReport(tests, simulated) {
34
38
  line: test.line,
35
39
  outcome: test.outcome,
36
40
  ...(reasons.length > 0 ? { not_evaluated_reasons: reasons } : {}),
37
- assertion_ids: assertionIds,
41
+ assertion_ids: [...assertionIds],
38
42
  duration_ms: Math.round(test.durationMs),
43
+ ...(test.attest?.trials !== undefined ? { trials: test.attest.trials.run } : {}),
39
44
  });
40
45
  }
41
46
  const count = (status) => rows.filter((r) => r["status"] === status).length;
@@ -49,6 +54,7 @@ export function buildReport(tests, simulated) {
49
54
  soft_fail: count(STATUS_SOFT_FAIL),
50
55
  hard_fail: count(STATUS_HARD_FAIL),
51
56
  not_evaluated: count(STATUS_NOT_EVALUATED),
57
+ usage: sessionUsage(tests, unattached),
52
58
  },
53
59
  results: rows,
54
60
  tests: testRows,
@@ -56,4 +62,30 @@ export function buildReport(tests, simulated) {
56
62
  total_duration_ms: totalDurationMs,
57
63
  };
58
64
  }
65
+ /** Attest usage summed over every test of the run plus the evaluations that belong to no test. */
66
+ export function sessionUsage(tests, unattached = zeroUsage()) {
67
+ return sumUsage([unattached, ...tests.flatMap((t) => (t.attest === undefined ? [] : [t.attest.usage]))]);
68
+ }
69
+ /**
70
+ * Lines for the end of the run: one per trials test
71
+ * ("<test_id>: <passed>/<evaluated> trials passed (<n> not evaluated)", plus a
72
+ * note when the test budget stopped it early), then the "attest usage: …" line
73
+ * when the session made or refused a model call.
74
+ */
75
+ export function summaryLines(tests, unattached = zeroUsage()) {
76
+ const lines = [];
77
+ for (const test of tests) {
78
+ const trials = test.attest?.trials;
79
+ if (trials === undefined)
80
+ continue;
81
+ lines.push(`${test.testId}: ${trials.passed}/${trials.evaluated} trials passed (${trials.notEvaluated} not evaluated)`);
82
+ if (trials.stoppedByBudget) {
83
+ lines.push(`${test.testId}: stopped after ${trials.run} of ${trials.requested} trials: test budget spent`);
84
+ }
85
+ }
86
+ const usage = usageSummaryLine(sessionUsage(tests, unattached));
87
+ if (usage !== undefined)
88
+ lines.push(usage);
89
+ return lines;
90
+ }
59
91
  //# sourceMappingURL=report.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
@@ -31,12 +31,21 @@ export interface AttestReporterOptions {
31
31
  * `--attest-report=<path>`:
32
32
  * `vitest run --reporter=default --reporter=@attest-ai/vitest/reporter --outputFile.attest=<path>`. Turns on `includeTaskLocation` so each test carries its
33
33
  * line. Requires Vitest 3+.
34
+ *
35
+ * At the end of the run it prints, with or without an output file, one line per
36
+ * `trials()` test ("<test_id>: <passed>/<evaluated> trials passed (<n> not evaluated)")
37
+ * and the "attest usage: …" line when the run made or refused an attest model call.
34
38
  */
35
39
  export declare class AttestReporter implements Reporter {
36
40
  private outputFile;
37
41
  private root;
42
+ private vitest;
43
+ private usageDir;
38
44
  constructor(options?: AttestReporterOptions);
39
45
  onInit(vitest: Vitest): void;
46
+ onTestRunStart(): void;
47
+ /** Sum and remove the usage files workers wrote for evaluations outside any test. */
48
+ private takeUnattachedUsage;
40
49
  onTestRunEnd(testModules: ReadonlyArray<TestModule>): void;
41
50
  }
42
51
  /** `vitest run --reporter=@attest-ai/vitest/reporter` loads the default export. */
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGhE,UAAU,eAAe;IACvB,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;CAwC/E;AAED,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,IAAI,CAAiB;gBAEjB,OAAO,GAAE,qBAA0B;IAI/C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAS5B,YAAY,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,IAAI;CA+B3D;AAED,mFAAmF;AACnF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIhE,UAAU,eAAe;IACvB,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI;CAwC/E;AAED,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAqB;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAe5B,cAAc,IAAI,IAAI;IAItB,qFAAqF;IACrF,OAAO,CAAC,mBAAmB;IAS3B,YAAY,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,IAAI;CAmC3D;AAED,mFAAmF;AACnF,eAAe,cAAc,CAAC"}
package/dist/reporter.js CHANGED
@@ -1,7 +1,9 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
2
- import { dirname, relative, resolve, sep } from "node:path";
3
- import { isSimulationMode, renderDiagnostics, renderSummary } from "@attest-ai/core";
4
- import { buildReport } from "./report.js";
1
+ import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { dirname, join, relative, resolve, sep } from "node:path";
4
+ import { isSimulationMode, parseUsage, renderDiagnostics, renderSummary, sumUsage, } from "@attest-ai/core";
5
+ import { buildReport, summaryLines } from "./report.js";
6
+ import { ROOT_ENV, USAGE_DIR_ENV } from "./test-state.js";
5
7
  /**
6
8
  * Vitest reporter that prints the cost report and a hierarchical
7
9
  * diagnostic block for every failed Attest evaluation in the run.
@@ -44,31 +46,56 @@ export class AttestCostReporter {
44
46
  * `--attest-report=<path>`:
45
47
  * `vitest run --reporter=default --reporter=@attest-ai/vitest/reporter --outputFile.attest=<path>`. Turns on `includeTaskLocation` so each test carries its
46
48
  * line. Requires Vitest 3+.
49
+ *
50
+ * At the end of the run it prints, with or without an output file, one line per
51
+ * `trials()` test ("<test_id>: <passed>/<evaluated> trials passed (<n> not evaluated)")
52
+ * and the "attest usage: …" line when the run made or refused an attest model call.
47
53
  */
48
54
  export class AttestReporter {
49
55
  outputFile;
50
56
  root = process.cwd();
57
+ vitest;
58
+ usageDir;
51
59
  constructor(options = {}) {
52
60
  this.outputFile = options.outputFile;
53
61
  }
54
62
  onInit(vitest) {
63
+ this.vitest = vitest;
55
64
  this.root = vitest.config.root;
56
65
  const configured = vitest.config.outputFile;
57
66
  if (this.outputFile === undefined && typeof configured === "object") {
58
67
  this.outputFile = configured["attest"];
59
68
  }
60
69
  vitest.config.includeTaskLocation = true;
70
+ // Workers inherit these: test ids hash paths relative to this root, and
71
+ // evaluations outside any test drop their usage in usageDir.
72
+ this.usageDir = mkdtempSync(join(tmpdir(), "attest-usage-"));
73
+ process.env[ROOT_ENV] = this.root;
74
+ process.env[USAGE_DIR_ENV] = this.usageDir;
75
+ }
76
+ onTestRunStart() {
77
+ if (this.usageDir !== undefined)
78
+ mkdirSync(this.usageDir, { recursive: true });
79
+ }
80
+ /** Sum and remove the usage files workers wrote for evaluations outside any test. */
81
+ takeUnattachedUsage() {
82
+ const dir = this.usageDir;
83
+ if (dir === undefined)
84
+ return sumUsage([]);
85
+ const files = readdirSync(dir).filter((f) => f.endsWith(".json"));
86
+ const usage = sumUsage(files.map((f) => parseUsage(JSON.parse(readFileSync(join(dir, f), "utf8")))));
87
+ rmSync(dir, { recursive: true, force: true });
88
+ return usage;
61
89
  }
62
90
  onTestRunEnd(testModules) {
63
91
  const outputFile = this.outputFile;
64
- if (outputFile === undefined)
65
- return;
66
92
  const tests = [];
67
93
  for (const testModule of testModules) {
68
94
  const file = relative(this.root, testModule.moduleId).split(sep).join("/");
69
95
  for (const testCase of testModule.children.allTests()) {
70
96
  const location = testCase.location;
71
- if (location === undefined) {
97
+ // The location matters only for the report file; summary lines need none.
98
+ if (location === undefined && outputFile !== undefined) {
72
99
  throw new Error(`AttestReporter: no source location for "${testCase.fullName}". Vitest records ` +
73
100
  "locations only when test.includeTaskLocation is true and the test file path matches " +
74
101
  "the root; set test.root to the real path (no symlinks) if it is set.");
@@ -78,16 +105,22 @@ export class AttestReporter {
78
105
  testId: `${file} > ${testCase.fullName}`,
79
106
  name: testCase.name,
80
107
  file,
81
- line: location.line,
108
+ line: location?.line ?? 0,
82
109
  outcome: state === "passed" || state === "failed" ? state : "skipped",
83
110
  durationMs: testCase.diagnostic()?.duration ?? 0,
84
111
  attest: testCase.meta().attest,
85
112
  });
86
113
  }
87
114
  }
115
+ const unattached = this.takeUnattachedUsage();
116
+ const lines = summaryLines(tests, unattached);
117
+ if (lines.length > 0)
118
+ this.vitest?.logger.log(lines.join("\n"));
119
+ if (outputFile === undefined)
120
+ return;
88
121
  const path = resolve(this.root, outputFile);
89
122
  mkdirSync(dirname(path), { recursive: true });
90
- writeFileSync(path, `${JSON.stringify(buildReport(tests, isSimulationMode()), null, 2)}\n`);
123
+ writeFileSync(path, `${JSON.stringify(buildReport(tests, isSimulationMode(), unattached), null, 2)}\n`);
91
124
  }
92
125
  }
93
126
  /** `vitest run --reporter=@attest-ai/vitest/reporter` loads the default export. */
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Per-test state shared by evaluate/inspect and trials: deterministic assertion
3
+ * IDs, the per-test budget remainder, and the results recorded on task meta.
4
+ */
5
+ import { AsyncLocalStorage } from "node:async_hooks";
6
+ import type { TestContext } from "vitest";
7
+ import { type AgentResult, type Assertion, type BatchBudget, type Trace, type Usage } from "@attest-ai/core";
8
+ import type { AttestTaskMeta } from "./report.js";
9
+ export type RunningTest = NonNullable<TestContext["task"]>;
10
+ /** Limits for the attest model calls of one test (all its evaluations and trials). */
11
+ export interface TestBudget {
12
+ /** Judge-provider requests the test may make. */
13
+ maxJudgeCalls?: number;
14
+ /** USD the test may spend: attest judge/embedding cost plus agent spend (trace `metadata.cost_usd`). */
15
+ maxCostUsd?: number;
16
+ }
17
+ /** The trials() call a body runs in; `trial` is undefined for a single run (N = 1). */
18
+ export interface TrialScope {
19
+ test: RunningTest;
20
+ trial: number | undefined;
21
+ budget: TestBudget | undefined;
22
+ /** Evaluations of the current trial. */
23
+ results: AgentResult[];
24
+ }
25
+ export declare const trialScope: AsyncLocalStorage<TrialScope>;
26
+ /** True while the code runs inside trial i of a trials() call with N > 1. */
27
+ export declare function inTrial(): boolean;
28
+ interface AttemptState {
29
+ attempt: number;
30
+ /** Assertions given an ID in this test (this trial, under trials()). */
31
+ ordinal: number;
32
+ /** Attest usage of this attempt so far. */
33
+ usage: Usage;
34
+ /** Sum of `metadata.cost_usd` of the traces evaluated in this attempt. */
35
+ agentSpendUsd: number;
36
+ traceIds: Set<string>;
37
+ }
38
+ /** State of the running attempt of `test`; a retried test starts afresh. */
39
+ export declare function attemptState(test: RunningTest): AttemptState;
40
+ /**
41
+ * The running test: `TestRunner.getCurrentTest()` on Vitest 4.1+, `vitest/suite`
42
+ * before that (loaded only there, because Vitest 4.1 warns when it is imported).
43
+ */
44
+ export declare function runningTest(): Promise<RunningTest | undefined>;
45
+ /**
46
+ * The test an evaluation belongs to: the passed context, else the enclosing
47
+ * trials() call, else Vitest's running test. Under test.concurrent the running
48
+ * test may be another test, so outside trials() the caller must pass `context`.
49
+ */
50
+ export declare function resolveTest(context: TestContext | undefined): Promise<RunningTest | undefined>;
51
+ /**
52
+ * Set by AttestReporter in the main process before workers start: the Vitest
53
+ * root its report paths are relative to, and the directory where workers drop
54
+ * the usage of evaluations that belong to no test.
55
+ */
56
+ export declare const ROOT_ENV = "ATTEST_VITEST_ROOT";
57
+ export declare const USAGE_DIR_ENV = "ATTEST_VITEST_USAGE_DIR";
58
+ /**
59
+ * The report's test_id of `test`: "<file> > <suites> > <name>", the same string
60
+ * AttestReporter writes. The file is relative to the Vitest root AttestReporter
61
+ * publishes (in a multi-project setup, not the project root); without
62
+ * AttestReporter it is the file task's name, relative to the project root.
63
+ */
64
+ export declare function testIdOf(test: RunningTest): string;
65
+ /**
66
+ * Hand the usage of an evaluation that belongs to no test (beforeAll, a script)
67
+ * to AttestReporter: one file per evaluation in its usage directory, so the
68
+ * session usage counts it once. Without AttestReporter there is no report to add it to.
69
+ */
70
+ export declare function recordUnattachedUsage(usage: Usage): void;
71
+ /** `assert_` + the first 12 hex chars of sha256("<test_id>#<ordinal>"). */
72
+ export declare function deterministicAssertionId(testId: string, ordinal: number): string;
73
+ /** Give each assertion the next deterministic ID of the test. */
74
+ export declare function assignAssertionIds(test: RunningTest, assertions: readonly Assertion[]): Assertion[];
75
+ /** Reject a budget with unknown keys or negative/non-numeric limits. */
76
+ export declare function validateBudget(budget: TestBudget): TestBudget;
77
+ /**
78
+ * What is left of the test budget for the next evaluate_batch: judge calls not
79
+ * yet used, and USD not yet spent by attest or the agent, each floored at 0.
80
+ * Undefined when the budget sets no limit.
81
+ */
82
+ export declare function remainingBudget(budget: TestBudget, usage: Usage, agentSpendUsd: number): BatchBudget | undefined;
83
+ /** True when attest cost plus agent spend has reached the test's cost limit. */
84
+ export declare function costBudgetSpent(budget: TestBudget | undefined, state: AttemptState): boolean;
85
+ /** Count the agent's own spend of a trace once per attempt. */
86
+ export declare function recordAgentSpend(test: RunningTest, trace: Trace): void;
87
+ /**
88
+ * The meta of the running attempt. Results from an earlier attempt of a retried
89
+ * test are dropped, so the report matches the outcome Vitest reports; their
90
+ * usage is kept, because those model calls were made.
91
+ */
92
+ export declare function attemptMeta(test: RunningTest): AttestTaskMeta;
93
+ /**
94
+ * Attach the results to the test's meta so AttestReporter, in the main process,
95
+ * can write them with the test's file and line; rows of trial i carry `trial`.
96
+ */
97
+ export declare function recordOnTest(test: RunningTest, result: AgentResult, trial: number | undefined): void;
98
+ export declare function strictFromEnv(): boolean;
99
+ export {};
100
+ //# sourceMappingURL=test-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-state.d.ts","sourceRoot":"","sources":["../src/test-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Per-test state shared by evaluate/inspect and trials: deterministic assertion
3
+ * IDs, the per-test budget remainder, and the results recorded on task meta.
4
+ */
5
+ import { AsyncLocalStorage } from "node:async_hooks";
6
+ import { createHash, randomUUID } from "node:crypto";
7
+ import { mkdirSync, writeFileSync } from "node:fs";
8
+ import { join, relative, sep } from "node:path";
9
+ import * as vitest from "vitest";
10
+ import { addUsage, zeroUsage, } from "@attest-ai/core";
11
+ export const trialScope = new AsyncLocalStorage();
12
+ /** True while the code runs inside trial i of a trials() call with N > 1. */
13
+ export function inTrial() {
14
+ return trialScope.getStore()?.trial !== undefined;
15
+ }
16
+ const attempts = new WeakMap();
17
+ function attemptOf(test) {
18
+ return test.result?.retryCount ?? 0;
19
+ }
20
+ /** State of the running attempt of `test`; a retried test starts afresh. */
21
+ export function attemptState(test) {
22
+ const attempt = attemptOf(test);
23
+ let state = attempts.get(test);
24
+ if (state === undefined || state.attempt !== attempt) {
25
+ state = { attempt, ordinal: 0, usage: zeroUsage(), agentSpendUsd: 0, traceIds: new Set() };
26
+ attempts.set(test, state);
27
+ }
28
+ return state;
29
+ }
30
+ /**
31
+ * The running test: `TestRunner.getCurrentTest()` on Vitest 4.1+, `vitest/suite`
32
+ * before that (loaded only there, because Vitest 4.1 warns when it is imported).
33
+ */
34
+ export async function runningTest() {
35
+ const runner = vitest.TestRunner;
36
+ if (runner !== undefined)
37
+ return runner.getCurrentTest();
38
+ const suite = await import("vitest/suite");
39
+ return suite.getCurrentTest();
40
+ }
41
+ /**
42
+ * The test an evaluation belongs to: the passed context, else the enclosing
43
+ * trials() call, else Vitest's running test. Under test.concurrent the running
44
+ * test may be another test, so outside trials() the caller must pass `context`.
45
+ */
46
+ export async function resolveTest(context) {
47
+ if (context !== undefined)
48
+ return context.task;
49
+ const scope = trialScope.getStore();
50
+ if (scope !== undefined)
51
+ return scope.test;
52
+ const test = await runningTest();
53
+ if (test !== undefined && test.concurrent === true) {
54
+ throw new Error("Attest results from a test.concurrent test — pass the test context: " +
55
+ "inspect(chain, { context }), evaluate(chain, { context }) or trials(body, { context })");
56
+ }
57
+ return test;
58
+ }
59
+ /**
60
+ * Set by AttestReporter in the main process before workers start: the Vitest
61
+ * root its report paths are relative to, and the directory where workers drop
62
+ * the usage of evaluations that belong to no test.
63
+ */
64
+ export const ROOT_ENV = "ATTEST_VITEST_ROOT";
65
+ export const USAGE_DIR_ENV = "ATTEST_VITEST_USAGE_DIR";
66
+ /**
67
+ * The report's test_id of `test`: "<file> > <suites> > <name>", the same string
68
+ * AttestReporter writes. The file is relative to the Vitest root AttestReporter
69
+ * publishes (in a multi-project setup, not the project root); without
70
+ * AttestReporter it is the file task's name, relative to the project root.
71
+ */
72
+ export function testIdOf(test) {
73
+ const names = [test.name];
74
+ for (let suite = test.suite; suite !== undefined && suite !== test.file; suite = suite.suite) {
75
+ names.unshift(suite.name);
76
+ }
77
+ const root = process.env[ROOT_ENV];
78
+ const file = root === undefined || test.file.filepath === undefined
79
+ ? test.file.name
80
+ : relative(root, test.file.filepath).split(sep).join("/");
81
+ return `${file} > ${names.join(" > ")}`;
82
+ }
83
+ /**
84
+ * Hand the usage of an evaluation that belongs to no test (beforeAll, a script)
85
+ * to AttestReporter: one file per evaluation in its usage directory, so the
86
+ * session usage counts it once. Without AttestReporter there is no report to add it to.
87
+ */
88
+ export function recordUnattachedUsage(usage) {
89
+ const dir = process.env[USAGE_DIR_ENV];
90
+ if (dir === undefined)
91
+ return;
92
+ if (Object.values(usage).every((v) => v === 0))
93
+ return;
94
+ mkdirSync(dir, { recursive: true });
95
+ writeFileSync(join(dir, `${randomUUID()}.json`), JSON.stringify(usage));
96
+ }
97
+ /** `assert_` + the first 12 hex chars of sha256("<test_id>#<ordinal>"). */
98
+ export function deterministicAssertionId(testId, ordinal) {
99
+ return `assert_${createHash("sha256").update(`${testId}#${ordinal}`).digest("hex").slice(0, 12)}`;
100
+ }
101
+ /** Give each assertion the next deterministic ID of the test. */
102
+ export function assignAssertionIds(test, assertions) {
103
+ const state = attemptState(test);
104
+ const testId = testIdOf(test);
105
+ return assertions.map((a) => ({ ...a, assertion_id: deterministicAssertionId(testId, state.ordinal++) }));
106
+ }
107
+ /** Reject a budget with unknown keys or negative/non-numeric limits. */
108
+ export function validateBudget(budget) {
109
+ for (const key of Object.keys(budget)) {
110
+ if (key !== "maxJudgeCalls" && key !== "maxCostUsd") {
111
+ throw new Error(`Attest budget: unknown option "${key}" (expected maxJudgeCalls, maxCostUsd)`);
112
+ }
113
+ }
114
+ const { maxJudgeCalls, maxCostUsd } = budget;
115
+ if (maxJudgeCalls !== undefined && !(Number.isInteger(maxJudgeCalls) && maxJudgeCalls >= 0)) {
116
+ throw new Error(`Attest budget: maxJudgeCalls must be an integer >= 0, got ${String(maxJudgeCalls)}`);
117
+ }
118
+ if (maxCostUsd !== undefined && !(Number.isFinite(maxCostUsd) && maxCostUsd >= 0)) {
119
+ throw new Error(`Attest budget: maxCostUsd must be a number >= 0, got ${String(maxCostUsd)}`);
120
+ }
121
+ return budget;
122
+ }
123
+ /**
124
+ * What is left of the test budget for the next evaluate_batch: judge calls not
125
+ * yet used, and USD not yet spent by attest or the agent, each floored at 0.
126
+ * Undefined when the budget sets no limit.
127
+ */
128
+ export function remainingBudget(budget, usage, agentSpendUsd) {
129
+ const wire = {};
130
+ if (budget.maxJudgeCalls !== undefined) {
131
+ wire.max_judge_calls = Math.max(0, budget.maxJudgeCalls - usage.judge_calls);
132
+ }
133
+ if (budget.maxCostUsd !== undefined) {
134
+ wire.max_cost_usd = Math.max(0, budget.maxCostUsd - (usage.cost_usd + agentSpendUsd));
135
+ }
136
+ return Object.keys(wire).length === 0 ? undefined : wire;
137
+ }
138
+ /** True when attest cost plus agent spend has reached the test's cost limit. */
139
+ export function costBudgetSpent(budget, state) {
140
+ return (budget?.maxCostUsd !== undefined && state.usage.cost_usd + state.agentSpendUsd >= budget.maxCostUsd);
141
+ }
142
+ /** Count the agent's own spend of a trace once per attempt. */
143
+ export function recordAgentSpend(test, trace) {
144
+ const state = attemptState(test);
145
+ if (state.traceIds.has(trace.trace_id))
146
+ return;
147
+ state.traceIds.add(trace.trace_id);
148
+ state.agentSpendUsd += trace.metadata?.cost_usd ?? 0;
149
+ }
150
+ /**
151
+ * The meta of the running attempt. Results from an earlier attempt of a retried
152
+ * test are dropped, so the report matches the outcome Vitest reports; their
153
+ * usage is kept, because those model calls were made.
154
+ */
155
+ export function attemptMeta(test) {
156
+ const attempt = attemptOf(test);
157
+ let meta = test.meta.attest;
158
+ if (meta === undefined || meta.attempt !== attempt) {
159
+ meta = {
160
+ attempt,
161
+ results: [],
162
+ totalCost: 0,
163
+ totalDurationMs: 0,
164
+ usage: meta?.usage ?? zeroUsage(),
165
+ };
166
+ test.meta.attest = meta;
167
+ }
168
+ return meta;
169
+ }
170
+ /**
171
+ * Attach the results to the test's meta so AttestReporter, in the main process,
172
+ * can write them with the test's file and line; rows of trial i carry `trial`.
173
+ */
174
+ export function recordOnTest(test, result, trial) {
175
+ const state = attemptState(test);
176
+ state.usage = addUsage(state.usage, result.usage);
177
+ const meta = attemptMeta(test);
178
+ meta.results.push(...result.assertionResults.map((r) => (trial === undefined ? r : { ...r, trial })));
179
+ meta.totalCost += result.totalCost;
180
+ meta.totalDurationMs += result.totalDurationMs;
181
+ meta.usage = addUsage(meta.usage, result.usage);
182
+ }
183
+ export function strictFromEnv() {
184
+ const v = (process.env["ATTEST_STRICT"] ?? "").trim().toLowerCase();
185
+ return v === "1" || v === "true" || v === "yes";
186
+ }
187
+ //# sourceMappingURL=test-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-state.js","sourceRoot":"","sources":["../src/test-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Fixed-N trials: the Vitest counterpart of pytest's `--attest-trials=N`.
3
+ */
4
+ import type { TestContext } from "vitest";
5
+ import { type TestBudget } from "./test-state.js";
6
+ /** How attestGlobalSetup({ minPassRate }) reaches the workers that run trials(). */
7
+ export declare const MIN_PASS_RATE_ENV = "ATTEST_MIN_PASS_RATE";
8
+ export interface TrialsOptions {
9
+ /** Number of trials N; defaults to the ATTEST_TRIALS environment variable, else 1. */
10
+ n?: number;
11
+ /**
12
+ * The running test's context (`it("…", async (context) => …)`); required under
13
+ * `test.concurrent` and on Vitest before 4.1.
14
+ */
15
+ context?: TestContext;
16
+ /**
17
+ * Limits for the test's attest model calls across all trials; see
18
+ * InspectOptions.testBudget. Before each trial after the first, the trials stop
19
+ * when attest cost plus agent spend has reached `maxCostUsd`.
20
+ */
21
+ budget?: TestBudget;
22
+ /**
23
+ * Fail the test when passed / evaluated trials is below this rate (0..1).
24
+ * Overrides the run's value: attestGlobalSetup({ minPassRate }) or the
25
+ * ATTEST_MIN_PASS_RATE environment variable, else 1.0 (any failing trial fails).
26
+ */
27
+ minPassRate?: number;
28
+ }
29
+ /** A pass rate in [0, 1]; anything else is an error naming where it came from. */
30
+ export declare function validateMinPassRate(rate: number, source: string): number;
31
+ /**
32
+ * Run `body` N times inside the current test (N = `options.n`, else the
33
+ * ATTEST_TRIALS environment variable, else 1) and enforce only the aggregate.
34
+ *
35
+ * With N = 1 the body runs once as a plain test body: evaluate() enforces as
36
+ * usual. With N > 1, during trial i (1-based): evaluate() does not enforce
37
+ * (it behaves as inspect()), enforceOutcome() returns its argument, every
38
+ * result row is reported with `trial = i`, and assertion IDs restart so each
39
+ * assertion keeps its ID across trials. A trial that throws counts as failed:
40
+ * its rows are replaced by one hard_fail row (failure_class broken_code) per
41
+ * assertion ID the test evaluated; when no trial evaluated anything, the first
42
+ * error is rethrown. A trial whose own outcome is skip counts as not evaluated,
43
+ * also under ATTEST_STRICT. After the last trial the test is skipped when no trial was
44
+ * evaluated (failed under ATTEST_STRICT), fails when passed / evaluated
45
+ * trials is below the minimum pass rate (default 1.0: any failing trial
46
+ * fails; not-evaluated trials are left out of the rate), and passes otherwise. AttestReporter prints "<test_id>: <passed>/<evaluated>
47
+ * trials passed (<n> not evaluated)".
48
+ *
49
+ * This is a pass/fail gate on N runs, not a statistical verdict: whether the
50
+ * pass rate regressed (pass / regressed / inconclusive) comes from
51
+ * `attest policy evaluate --baseline <tag>` with a `regression` rule over the
52
+ * report's per-trial rows.
53
+ */
54
+ export declare function trials(body: (trial: number) => Promise<void> | void, options?: TrialsOptions): Promise<void>;
55
+ //# sourceMappingURL=trials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trials.d.ts","sourceRoot":"","sources":["../src/trials.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAS1C,OAAO,EASL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAEzB,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,sFAAsF;IACtF,CAAC,CAAC,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAoBD,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKxE;AA0ED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,EAC7C,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAqEf"}
package/dist/trials.js ADDED
@@ -0,0 +1,184 @@
1
+ import { AgentResult, FailureClass, STATUS_HARD_FAIL, STATUS_NOT_EVALUATED, renderDiagnostics, } from "@attest-ai/core";
2
+ import { attemptMeta, attemptState, costBudgetSpent, runningTest, strictFromEnv, trialScope, validateBudget, } from "./test-state.js";
3
+ /** How attestGlobalSetup({ minPassRate }) reaches the workers that run trials(). */
4
+ export const MIN_PASS_RATE_ENV = "ATTEST_MIN_PASS_RATE";
5
+ function trialCount(n) {
6
+ const raw = n ?? Number(process.env["ATTEST_TRIALS"] ?? 1);
7
+ if (!Number.isInteger(raw) || raw < 1) {
8
+ const source = n === undefined ? `ATTEST_TRIALS=${process.env["ATTEST_TRIALS"]}` : `n=${n}`;
9
+ throw new Error(`trials(): N must be an integer >= 1, got ${source}`);
10
+ }
11
+ return raw;
12
+ }
13
+ /** A pass rate in [0, 1]; anything else is an error naming where it came from. */
14
+ export function validateMinPassRate(rate, source) {
15
+ if (!Number.isFinite(rate) || rate < 0 || rate > 1) {
16
+ throw new Error(`minPassRate must be a number between 0 and 1, got ${source}`);
17
+ }
18
+ return rate;
19
+ }
20
+ /** The run's minimum pass rate: ATTEST_MIN_PASS_RATE (set by attestGlobalSetup), else 1.0. */
21
+ function runMinPassRate() {
22
+ const raw = process.env[MIN_PASS_RATE_ENV];
23
+ if (raw === undefined)
24
+ return 1;
25
+ return validateMinPassRate(raw.trim() === "" ? Number.NaN : Number(raw), `${MIN_PASS_RATE_ENV}=${raw}`);
26
+ }
27
+ function describeError(error) {
28
+ return error instanceof Error ? `${error.name}: ${error.message}` : `${typeof error}: ${String(error)}`;
29
+ }
30
+ /** A trial's own outcome: raised or any hard_fail fails; else not_evaluated (or nothing evaluated) skips. */
31
+ function trialOutcome(trial) {
32
+ if (trial.error !== undefined)
33
+ return "fail";
34
+ const rows = trial.results.flatMap((r) => r.assertionResults);
35
+ if (rows.some((r) => r.status === STATUS_HARD_FAIL))
36
+ return "fail";
37
+ if (rows.length === 0)
38
+ return "skip";
39
+ if (rows.some((r) => r.status === STATUS_NOT_EVALUATED))
40
+ return "skip";
41
+ return "pass";
42
+ }
43
+ /**
44
+ * Replace the rows of each trial that threw with exactly one hard_fail row per
45
+ * assertion ID of the test, so pass rates count the trial as failed once per ID.
46
+ * When the trial had evaluated the ID before throwing, the explanation keeps
47
+ * the engine's status.
48
+ */
49
+ function thrownTrialRows(test, trials) {
50
+ const meta = attemptMeta(test);
51
+ const ids = [...new Set(trials.flatMap((t) => t.results.flatMap((r) => r.assertionResults)).map((r) => r.assertion_id))];
52
+ for (const trial of trials) {
53
+ if (trial.error === undefined)
54
+ continue;
55
+ const before = new Map(trial.results.flatMap((r) => r.assertionResults.map((row) => [row.assertion_id, row.status])));
56
+ meta.results = meta.results.filter((row) => row.trial !== trial.index);
57
+ const raised = `trial ${trial.index} raised ${describeError(trial.error.value)}`;
58
+ for (const id of ids) {
59
+ const status = before.get(id);
60
+ const row = {
61
+ assertion_id: id,
62
+ status: STATUS_HARD_FAIL,
63
+ score: 0,
64
+ explanation: status === undefined ? raised : `${raised} (engine status before the error: ${status})`,
65
+ failure_class: FailureClass.BrokenCode,
66
+ trial: trial.index,
67
+ };
68
+ meta.results.push(row);
69
+ }
70
+ }
71
+ }
72
+ function failureMessage(summary, trials, minPassRate) {
73
+ const rate = summary.passed / summary.evaluated;
74
+ const parts = [
75
+ `${summary.passed}/${summary.evaluated} trials passed (pass rate ${rate.toFixed(2)}) ` +
76
+ `below min pass rate ${minPassRate.toFixed(2)}`,
77
+ ];
78
+ for (const trial of trials) {
79
+ if (trialOutcome(trial) !== "fail")
80
+ continue;
81
+ if (trial.error !== undefined) {
82
+ parts.push(`trial ${trial.index} raised ${describeError(trial.error.value)}`);
83
+ continue;
84
+ }
85
+ for (const result of trial.results) {
86
+ if (result.hardFailures.length === 0)
87
+ continue;
88
+ parts.push(`trial ${trial.index}:${renderDiagnostics(result)}`);
89
+ }
90
+ }
91
+ return parts.join("\n");
92
+ }
93
+ /**
94
+ * Run `body` N times inside the current test (N = `options.n`, else the
95
+ * ATTEST_TRIALS environment variable, else 1) and enforce only the aggregate.
96
+ *
97
+ * With N = 1 the body runs once as a plain test body: evaluate() enforces as
98
+ * usual. With N > 1, during trial i (1-based): evaluate() does not enforce
99
+ * (it behaves as inspect()), enforceOutcome() returns its argument, every
100
+ * result row is reported with `trial = i`, and assertion IDs restart so each
101
+ * assertion keeps its ID across trials. A trial that throws counts as failed:
102
+ * its rows are replaced by one hard_fail row (failure_class broken_code) per
103
+ * assertion ID the test evaluated; when no trial evaluated anything, the first
104
+ * error is rethrown. A trial whose own outcome is skip counts as not evaluated,
105
+ * also under ATTEST_STRICT. After the last trial the test is skipped when no trial was
106
+ * evaluated (failed under ATTEST_STRICT), fails when passed / evaluated
107
+ * trials is below the minimum pass rate (default 1.0: any failing trial
108
+ * fails; not-evaluated trials are left out of the rate), and passes otherwise. AttestReporter prints "<test_id>: <passed>/<evaluated>
109
+ * trials passed (<n> not evaluated)".
110
+ *
111
+ * This is a pass/fail gate on N runs, not a statistical verdict: whether the
112
+ * pass rate regressed (pass / regressed / inconclusive) comes from
113
+ * `attest policy evaluate --baseline <tag>` with a `regression` rule over the
114
+ * report's per-trial rows.
115
+ */
116
+ export async function trials(body, options) {
117
+ const n = trialCount(options?.n);
118
+ const minPassRate = options?.minPassRate === undefined
119
+ ? runMinPassRate()
120
+ : validateMinPassRate(options.minPassRate, `minPassRate=${options.minPassRate}`);
121
+ const budget = options?.budget === undefined ? undefined : validateBudget(options.budget);
122
+ const test = options?.context?.task ?? (await runningTest());
123
+ if (test === undefined)
124
+ throw new Error("trials() must be called inside a test");
125
+ if (options?.context === undefined && test.concurrent === true) {
126
+ throw new Error("trials() in a test.concurrent test — pass the test context: trials(body, { context })");
127
+ }
128
+ if (n === 1) {
129
+ await trialScope.run({ test, trial: undefined, budget, results: [] }, () => body(1));
130
+ return;
131
+ }
132
+ const state = attemptState(test);
133
+ const records = [];
134
+ let stoppedByBudget = false;
135
+ for (let index = 1; index <= n; index++) {
136
+ if (index > 1 && costBudgetSpent(budget, state)) {
137
+ stoppedByBudget = true;
138
+ break;
139
+ }
140
+ state.ordinal = 0;
141
+ const record = { index, results: [], error: undefined };
142
+ records.push(record);
143
+ try {
144
+ await trialScope.run({ test, trial: index, budget, results: record.results }, () => body(index));
145
+ }
146
+ catch (error) {
147
+ record.error = { value: error };
148
+ }
149
+ }
150
+ const evaluatedAny = records.some((r) => r.results.some((res) => res.assertionResults.length > 0));
151
+ const firstError = records.find((r) => r.error !== undefined)?.error;
152
+ if (!evaluatedAny && firstError !== undefined)
153
+ throw firstError.value;
154
+ thrownTrialRows(test, records);
155
+ const strict = strictFromEnv();
156
+ const outcomes = records.map((r) => trialOutcome(r));
157
+ const passed = outcomes.filter((o) => o === "pass").length;
158
+ const failed = outcomes.filter((o) => o === "fail").length;
159
+ const summary = {
160
+ requested: n,
161
+ run: records.length,
162
+ passed,
163
+ evaluated: passed + failed,
164
+ notEvaluated: outcomes.length - passed - failed,
165
+ stoppedByBudget,
166
+ };
167
+ attemptMeta(test).trials = summary;
168
+ if (summary.evaluated === 0) {
169
+ const all = records.flatMap((r) => r.results);
170
+ const rows = all.flatMap((r) => r.assertionResults);
171
+ const first = all[0];
172
+ const reason = first === undefined || rows.length === 0
173
+ ? `not evaluated: no assertions in ${records.length} trials`
174
+ : new AgentResult(first.trace, rows).skipReason();
175
+ if (strict)
176
+ throw new Error(`strict: ${reason}`);
177
+ (options?.context ?? test.context).skip(reason);
178
+ return;
179
+ }
180
+ if (passed / summary.evaluated < minPassRate) {
181
+ throw new Error(failureMessage(summary, records, minPassRate));
182
+ }
183
+ }
184
+ //# sourceMappingURL=trials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trials.js","sourceRoot":"","sources":["../src/trials.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@attest-ai/vitest",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "Attest vitest integration — global setup, fixtures, cost reporter, tier filtering",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -50,7 +50,7 @@
50
50
  "ajv": "^8.20.0",
51
51
  "typescript": "^5.9.3",
52
52
  "vitest": "^4.1.10",
53
- "@attest-ai/core": "1.0.0-rc.1"
53
+ "@attest-ai/core": "1.0.0-rc.2"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "tsc",