@leostera/evalkit 0.9.0 → 0.11.0

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/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as Schema from "effect/Schema";
2
+ import { AssistantBlock, AssistantBlock as AssistantBlock$1, EntryRecord, EntryRecord as EntryRecord$1, MessageRecord, MessageRecord as MessageRecord$1, ModelContext, ModelContext as ModelContext$1, ModelRef, ModelRef as ModelRef$1, Origin, StopReason, ToolCallBlock, ToolCallBlock as ToolCallBlock$1, Transcript, Transcript as Transcript$1, TranscriptHeader, TreeRecord, TreeRecord as TreeRecord$1, Usage, UserBlock, UserBlock as UserBlock$1, UserContent, UserContent as UserContent$1 } from "@leostera/atxf";
2
3
  //#region ../core/src/identity.d.ts
3
4
  export declare const ResourceKindSchema: Schema.Literal<["run", "artifact"]>;
4
5
  export type ResourceKind = typeof ResourceKindSchema.Type;
@@ -109,70 +110,462 @@ export declare function relativeDatasetPath(value: string, label: string): strin
109
110
  export declare function defineDataset<TLoaded extends DatasetContent>(definition: StaticDatasetDefinition | ComputedDatasetDefinition<TLoaded>): Dataset;
110
111
  export declare function isDataset(value: unknown): value is Dataset;
111
112
  //#endregion
112
- //#region ../core/src/aut-events.d.ts
113
+ //#region ../core/src/usage.d.ts
113
114
  /**
114
- * Events as adapters emit them. Payloads accept any JSON-convertible value and
115
- * timestamps are optional; EvalKit converts them once into `AutEvent`s.
115
+ * Token usage as an adapter reports it: ATXF's buckets, each optional.
116
+ * The buckets are disjoint: `input` excludes cached tokens, which are
117
+ * `cacheRead` (read from a prompt cache) and `cacheWrite` (written to one);
118
+ * `output` includes `reasoning`. Convert your provider's conventions: one
119
+ * that counts cached tokens inside its prompt tokens reports
120
+ * `input: promptTokens - cachedTokens, cacheRead: cachedTokens`.
116
121
  */
117
- export type AutEventInput = {
118
- kind: 'started';
119
- timestamp?: string;
120
- } | {
121
- kind: 'message';
122
- role: 'system' | 'user' | 'assistant' | 'tool';
123
- content: unknown;
124
- timestamp?: string;
125
- } | {
126
- kind: 'tool-call';
127
- id: string;
128
- name: string;
129
- arguments?: unknown;
130
- timestamp?: string;
131
- } | {
132
- kind: 'tool-result';
133
- id: string;
134
- name?: string;
135
- result?: unknown;
136
- timestamp?: string;
137
- } | {
138
- kind: 'turn-started';
139
- turn: number;
140
- timestamp?: string;
141
- } | {
142
- kind: 'turn-completed';
143
- turn: number;
144
- timestamp?: string;
145
- latencyMs?: number;
146
- usage?: Usage;
147
- } | {
148
- kind: 'completed';
149
- output?: unknown;
150
- timestamp?: string;
151
- } | {
152
- kind: 'error';
153
- error: RecordedError;
154
- timestamp?: string;
122
+ type UsageInput = {
123
+ input?: number;
124
+ output?: number;
125
+ cacheRead?: number;
126
+ cacheWrite?: number;
127
+ reasoning?: number;
128
+ /** The provider's total; used only when no bucket is reported. */
129
+ total?: number;
130
+ };
131
+ //#endregion
132
+ //#region ../core/src/agent-transcript.d.ts
133
+ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
134
+ /** An ATXF tree record to append: `id`, `time` and `parentId` are filled in when absent. */
135
+ export type RecordInput = DistributiveOmit<TreeRecord$1, 'id' | 'time' | 'parentId' | 'hash'> & {
136
+ id?: string;
137
+ time?: string;
138
+ parentId?: string | null;
139
+ };
140
+ /** An assistant message: what the model said and the tools it called. */
141
+ export type AssistantInput = {
142
+ /** Text, or ATXF blocks: `text`, `reasoning`, `tool_call` and `image`. */
143
+ content: string | AssistantBlock$1[];
144
+ /** `provider/id` (`openai/gpt-5`), or an ATXF model reference. */
145
+ model?: string | ModelRef$1;
146
+ /** This response's usage, in ATXF's buckets. */
147
+ usage?: UsageInput;
148
+ stop?: StopReason;
149
+ error?: {
150
+ message: string;
151
+ code?: string;
152
+ };
153
+ };
154
+ /**
155
+ * Where an adapter records what its agent did, as an ATXF transcript
156
+ * (https://atxf.leostera.dev). Each method appends one record and returns
157
+ * its ID. EvalKit writes each scripted user message itself, unless the
158
+ * adapter writes it (or imports a transcript holding it) first.
159
+ */
160
+ export type TranscriptWriter = {
161
+ /** A message the agent received. */
162
+ user(content: string | UserBlock$1[], options?: {
163
+ origin?: Origin;
164
+ }): string;
165
+ assistant(message: AssistantInput): string;
166
+ /**
167
+ * A tool call's result. A string is the result's text; any other
168
+ * JSON-convertible value is kept as is in `details.result` and shown as
169
+ * JSON.
170
+ */
171
+ toolResult(callId: string, result: unknown, options?: {
172
+ name?: string;
173
+ isError?: boolean;
174
+ }): string;
175
+ /** Any other ATXF tree record, such as `reasoning` settings, a compaction or a sub-agent link. */
176
+ append(record: RecordInput): string;
177
+ /**
178
+ * Appends an ATXF transcript's records that were not imported before (by
179
+ * ID), keeping their IDs and native records: for agents whose sessions
180
+ * ATXF converts (`pi.toAtxf(await readFile(sessionFile, 'utf8'))`, from `@leostera/atxf/pi`). Import the whole session
181
+ * after each turn; a user message matching the one EvalKit is about to
182
+ * write stands for it.
183
+ */
184
+ import(transcript: Transcript$1): void;
185
+ /**
186
+ * Marks a turn's start or end, as the agent saw it: `turn('start')`
187
+ * returns a turn ID to pass to `turn('end', { turnId, outcome })`.
188
+ */
189
+ turn(phase: 'start' | 'end', options?: {
190
+ turnId?: string;
191
+ outcome?: 'succeeded' | 'failed' | 'interrupted';
192
+ error?: {
193
+ message: string;
194
+ code?: string;
195
+ };
196
+ }): string;
197
+ /**
198
+ * Keeps a sub-agent's ATXF transcript with the run, in
199
+ * `transcripts/<id>.atxf.jsonl`, linked from this one by an `agent_link`
200
+ * record with its `transcriptId` (append one, or import a session that
201
+ * has it). Its steps and tokens count toward the run's limits. Pass the
202
+ * whole transcript again as it grows; it replaces the one kept.
203
+ */
204
+ subagent(transcript: Transcript$1): void;
155
205
  };
156
206
  export type TurnToolCall = {
157
207
  name: string;
158
208
  arguments?: unknown;
159
- /** When given, a `tool-result` event is recorded after the call. */
209
+ /** When given, the call's result is recorded after it. */
160
210
  result?: unknown;
161
211
  id?: string;
162
212
  };
163
- /** What `send()` may return instead of (or as well as) emitting events. A string is the reply. */
213
+ /** What `send()` may return instead of writing to the transcript. A string is the reply. */
164
214
  export type TurnResult = string | {
215
+ /** Text, or a JSON value (recorded as its JSON text). */
165
216
  reply?: unknown;
166
217
  toolCalls?: readonly TurnToolCall[];
167
- usage?: Usage;
218
+ usage?: UsageInput;
219
+ /** The model that answered. */
220
+ model?: string | ModelRef$1;
221
+ };
222
+ //#endregion
223
+ //#region ../core/src/isolation.d.ts
224
+ /**
225
+ * Where a run's processes run, and the shell adapters and scorers use to
226
+ * run them (RFD0009). Types and constructors only: the runner implements
227
+ * them.
228
+ */
229
+ /** Commands run on the host, in the run's workspace. The default. */
230
+ export type NoIsolation = {
231
+ kind: 'none';
232
+ };
233
+ /**
234
+ * What a run's container can reach: nothing, only the project's fixtures,
235
+ * or whatever the container runtime allows by default.
236
+ */
237
+ export type ContainerNetwork = 'none' | 'fixtures' | 'full';
238
+ /** A host path mounted read-only into every run's container. */
239
+ export type ContainerMount = {
240
+ host: string;
241
+ path: string;
242
+ };
243
+ /** One container per run, from `image`, with the candidate workspace at `/workspace`. */
244
+ export type ContainerIsolation = {
245
+ kind: 'container';
246
+ /** An image reference (`node:22`), or a Dockerfile path relative to the project (`./evals/Dockerfile`). */
247
+ image: string;
248
+ network: ContainerNetwork;
249
+ /** The `docker`-compatible command to run: `docker` (the default) or `podman`. */
250
+ runtime: string;
251
+ /** Names of host environment variables passed into the container; nothing else is. */
252
+ env: readonly string[];
253
+ mounts: readonly ContainerMount[];
254
+ };
255
+ /** macOS only: each run's processes run under a generated `sandbox-exec` profile. */
256
+ export type SandboxExecIsolation = {
257
+ kind: 'sandbox-exec';
258
+ /** Host paths the run may read and write besides its workspace, such as a cache (`~/.npm`). */
259
+ allow: readonly string[];
260
+ /** Host paths the run may only read, such as a toolchain or an agent CLI's install. */
261
+ read: readonly string[];
262
+ /** More host paths the run may not touch, such as a fixture's state; `allow` and `read` still win inside them. */
263
+ deny: readonly string[];
264
+ /**
265
+ * Names of host environment variables the run gets, besides `PATH`,
266
+ * `HOME`, `TMPDIR`, `USER`, `LANG` and `TERM`; undefined passes the whole
267
+ * environment. A command's own `env` is added on top.
268
+ */
269
+ env?: readonly string[];
270
+ };
271
+ export type SandboxExecOptions = {
272
+ allow?: readonly string[];
273
+ read?: readonly string[];
274
+ deny?: readonly string[];
275
+ env?: readonly string[];
276
+ };
277
+ export type Isolation = NoIsolation | ContainerIsolation | SandboxExecIsolation;
278
+ export type ContainerOptions = {
279
+ image: string;
280
+ /** Default `'none'`. */
281
+ network?: ContainerNetwork;
282
+ runtime?: string;
283
+ env?: readonly string[];
284
+ /** `{ host, path }`, or `'host:path'`. */
285
+ mounts?: readonly (ContainerMount | string)[];
286
+ };
287
+ /** No isolation: commands run on the host in the run's workspace. */
288
+ export declare function none(): NoIsolation;
289
+ /**
290
+ * Container isolation through the `docker` CLI, or a compatible one such as
291
+ * podman's: a container per run, the candidate workspace mounted at
292
+ * `/workspace`, the evaluator workspace never mounted, and its own process
293
+ * table, so a `pkill` reaches only that run.
294
+ */
295
+ export declare function container(options: ContainerOptions): ContainerIsolation;
296
+ /**
297
+ * macOS `sandbox-exec` isolation, for projects that cannot use containers:
298
+ * the run cannot read or write the project, the home directory or other
299
+ * runs' workspaces, except its own workspace and `allow`, and can signal
300
+ * only processes it started.
301
+ */
302
+ export declare function sandboxExec(options?: SandboxExecOptions): SandboxExecIsolation;
303
+ /**
304
+ * A service runs reach, such as a fake store or API, started on the host
305
+ * before the first run that needs it and stopped after the invocation's
306
+ * last.
307
+ */
308
+ export type Fixture = {
309
+ /** The command that starts it, run with `sh -c` in the project root. */
310
+ start: string;
311
+ /** A URL polled until it answers, or a command that must exit 0. */
312
+ ready?: string;
313
+ /** A command run before the fixture is stopped. */
314
+ stop?: string;
315
+ /** The port it listens on; taken from `ready` when that is a URL with one. */
316
+ port?: number;
317
+ };
318
+ /** A fixture as one run reaches it. */
319
+ export type FixtureAddress = {
320
+ /** Where the run reaches it: `http://localhost:8787`, or `http://fixtures.<name>:8787` from a container. */
321
+ url: string;
322
+ };
323
+ /** A process's exit: a signal shows as 128 plus its number, a timeout as 124. */
324
+ export type ShellExit = {
325
+ exitCode: number;
326
+ /** The signal that stopped it, if one did. */
327
+ signal?: string;
328
+ /** True when `timeoutMs` passed and the process was stopped. */
329
+ timedOut?: true;
330
+ };
331
+ export type ShellResult = ShellExit & {
332
+ stdout: string;
333
+ stderr: string;
334
+ };
335
+ export type ShellOptions = {
336
+ /** Relative to the workspace. */
337
+ cwd?: string;
338
+ /** Added to the environment the process gets. */
339
+ env?: Readonly<Record<string, string>>;
340
+ /** Stops the process when aborted. Default: the run's signal. */
341
+ signal?: AbortSignal;
342
+ /** Stops the process after this many milliseconds. */
343
+ timeoutMs?: number;
344
+ /** Written to the process's standard input, which is then closed. */
345
+ input?: string;
346
+ };
347
+ /** A process started with `spawn`. Its output is always read, so it never blocks on a full pipe. */
348
+ export type ShellProcess = {
349
+ /** Its process ID where it runs (inside the container, for container isolation). */
350
+ readonly pid: number | undefined;
351
+ /** Its standard output so far: the last megabyte. */
352
+ stdout(): string;
353
+ stderr(): string;
354
+ /** Calls `listener` with each chunk of output as it arrives; returns a function that stops. */
355
+ onOutput(listener: (chunk: string, stream: 'stdout' | 'stderr') => void): () => void;
356
+ /** Resolves when it exits. */
357
+ wait(): Promise<ShellExit>;
358
+ /** Signals it and the processes it started. Default `SIGTERM`. */
359
+ kill(signal?: string): Promise<void>;
168
360
  };
169
- /** Converts an adapter event into a recorded `AutEvent`. */
170
- export declare function normalizeAutEvent(input: AutEventInput, now: () => Date): AutEvent;
171
361
  /**
172
- * The events a returned turn result stands for: each tool call (and its
173
- * result), then the reply, then the usage as a `turn-completed` event.
362
+ * The run's shell: commands, long-lived processes and files, wherever the
363
+ * run's isolation puts them. One per run, shared by the adapter and the
364
+ * run's scorers; processes it started are stopped when the run ends. A
365
+ * string command runs with `sh -c`; an array runs as it is.
174
366
  */
175
- export declare function turnResultEvents(result: TurnResult, turn: number, now: () => Date): AutEvent[];
367
+ export type Shell = {
368
+ readonly isolation: Isolation['kind'];
369
+ /** The workspace as commands see it: its host path, or `/workspace` in a container. */
370
+ readonly root: string;
371
+ /**
372
+ * The run's private directory, outside the workspace, as commands see it
373
+ * (`/evalkit-home` in a container): for an agent CLI's config and session
374
+ * files. It is never snapshotted, and is removed with the run.
375
+ */
376
+ readonly home: string;
377
+ exec(command: string | readonly string[], options?: ShellOptions): Promise<ShellResult>;
378
+ spawn(command: string | readonly string[], options?: Omit<ShellOptions, 'timeoutMs'>): ShellProcess;
379
+ /** Relative to the workspace, or absolute inside `root` or `home`. */
380
+ readFile(path: string): Promise<string>;
381
+ writeFile(path: string, content: string | Uint8Array): Promise<void>;
382
+ /** A directory's entries, relative to the workspace; directories end with `/`. */
383
+ list(path?: string): Promise<string[]>;
384
+ };
385
+ //#endregion
386
+ //#region ../core/src/limits.d.ts
387
+ /** What a run may use before EvalKit stops it. */
388
+ type Limits = {
389
+ /** Assistant messages, one per model call, sub-agents included. */
390
+ steps?: number;
391
+ /** The `tokens` metric: uncached input, cache writes and output. Cache reads do not count. */
392
+ tokens?: number;
393
+ /** Milliseconds from the session's start to the end of its last turn; scoring is not counted. */
394
+ time?: number;
395
+ };
396
+ type LimitKind = keyof Limits;
397
+ declare const LIMIT_KINDS: readonly LimitKind[];
398
+ /** Limits as written in config and scenarios: `time` may be a duration such as `'20m'`. */
399
+ type LimitsInput = {
400
+ steps?: number;
401
+ tokens?: number;
402
+ /** Milliseconds, or `'90s'`, `'20m'`, `'1h'`. */
403
+ time?: number | string;
404
+ };
405
+ /** Which limit a run hit, its value, and how much was used. */
406
+ type LimitReached = {
407
+ limit: LimitKind;
408
+ value: number;
409
+ used: number;
410
+ };
411
+ /** `'20m'` → 1_200_000. A number is milliseconds. */
412
+ declare function parseDuration(value: number | string, owner: string): number;
413
+ /** Checks and normalizes limits; `owner` names where they were written. */
414
+ declare function parseLimits(input: LimitsInput | undefined, owner: string): Limits;
415
+ /** Later layers win, kind by kind: config, then scenario, then matrix cell, then the command line. */
416
+ declare function resolveLimits(...layers: readonly Limits[]): Limits;
417
+ /** A matrix's `limits` axes are parameters named `limits.<kind>`. */
418
+ declare const LIMIT_PARAMETER_PREFIX = "limits.";
419
+ /** The limits a matrix cell's `limits.<kind>` parameters set. */
420
+ declare function limitsFromParameters(parameters: Readonly<Record<string, unknown>> | undefined): Limits;
421
+ /** `steps=80` or `time=1h`, from `--limit`. */
422
+ declare function parseLimitFlag(flag: string): Limits;
423
+ /** `40 steps`, `2,000,000 tokens`, `20m`. */
424
+ declare function formatLimit(kind: LimitKind, value: number): string;
425
+ //#endregion
426
+ //#region ../core/src/transcript.d.ts
427
+ /** The ATXF version EvalKit writes. */
428
+ declare const ATXF_VERSION = "0.1";
429
+ declare function isTreeRecord(record: EntryRecord$1): record is TreeRecord$1;
430
+ type AssistantMessage = MessageRecord$1 & {
431
+ role: 'assistant';
432
+ };
433
+ type ToolMessage = MessageRecord$1 & {
434
+ role: 'tool';
435
+ };
436
+ /**
437
+ * The records from the transcript's root to its active leaf, in order: what
438
+ * the session is now, without abandoned branches (ATXF §4).
439
+ */
440
+ declare function activePath(transcript: Transcript$1): TreeRecord$1[];
441
+ /** Messages on the active path, optionally of one role. */
442
+ declare function transcriptMessages(transcript: Transcript$1, role?: MessageRecord$1['role']): MessageRecord$1[];
443
+ /** A tool call and, when the transcript has it, its result. */
444
+ type PairedToolCall = {
445
+ /** The assistant message holding the call. */
446
+ message: AssistantMessage;
447
+ call: ToolCallBlock$1;
448
+ result?: ToolMessage;
449
+ };
450
+ /** A tool call as scorers see it: its name, arguments and what it returned. */
451
+ type ToolCall = {
452
+ id: string;
453
+ name: string;
454
+ /** Its arguments; `{}` when the agent recorded raw `input` instead. */
455
+ arguments: Record<string, unknown>;
456
+ /** Raw input for tools that take text rather than JSON arguments. */
457
+ input?: string;
458
+ /** What the tool returned (JSON the adapter recorded, else the result's text); undefined before a result. */
459
+ result?: unknown;
460
+ /** The tool reported an error. */
461
+ isError: boolean;
462
+ /** The assistant message holding the call. */
463
+ messageId: string;
464
+ /** The tool result message, when there is one. */
465
+ resultId?: string;
466
+ };
467
+ /** Every tool call on the active path, in order, with its result. */
468
+ declare function transcriptToolCalls(transcript: Transcript$1, name?: string): ToolCall[];
469
+ /** Tool calls among `records`, each paired with the first result for it. */
470
+ declare function callsIn(records: readonly TreeRecord$1[]): PairedToolCall[];
471
+ /** The text of a message's content: text blocks joined, other blocks left out. */
472
+ declare function contentText(content: UserContent$1 | AssistantBlock$1[]): string;
473
+ /** The text of the last assistant message on the active path, or `''`. */
474
+ declare function transcriptReply(transcript: Transcript$1): string;
475
+ /**
476
+ * A tool result's value: the JSON an adapter returned (kept in
477
+ * `details.result`), else the result's text.
478
+ */
479
+ declare function toolResultValue(result: ToolMessage): unknown;
480
+ /** `provider/id`, or `id` when the provider is unknown. */
481
+ declare function modelName(model: ModelRef$1 | undefined): string | undefined;
482
+ /** `openai/gpt-5` → `{ provider: 'openai', id: 'gpt-5' }`; without a provider, `unknown`. */
483
+ declare function parseModel(model: string | ModelRef$1): ModelRef$1;
484
+ /** The transcript, empty: what scorers see before the agent recorded anything. */
485
+ declare function emptyTranscript(header: Transcript$1['header']): Transcript$1;
486
+ //#endregion
487
+ //#region ../core/src/judge.d.ts
488
+ /**
489
+ * How a judge must answer, and how EvalKit turns the answer into a score.
490
+ *
491
+ * - `verdict` (the default): a value from 0 to 1 and a reason, as JSON.
492
+ * - `choices`: one of a fixed set of answers, such as A/B/C, each worth a value.
493
+ * - `criteria`: a value from 0 to 1 per criterion; the score is their weighted mean.
494
+ */
495
+ type JudgeAnswer = {
496
+ kind: 'verdict';
497
+ } | {
498
+ kind: 'choices';
499
+ choices: JudgeChoice[];
500
+ } | {
501
+ kind: 'criteria';
502
+ criteria: JudgeCriterion[];
503
+ };
504
+ /** One answer a `choices` judge can give. Keys are matched case-insensitively. */
505
+ type JudgeChoice = {
506
+ key: string;
507
+ label: string;
508
+ value: number;
509
+ };
510
+ /** One thing a `criteria` judge scores. */
511
+ type JudgeCriterion = {
512
+ name: string;
513
+ weight: number;
514
+ description?: string;
515
+ };
516
+ /**
517
+ * A judge that answers with one of these choices, in this order:
518
+ * `choices({ A: ['Accurate and helpful', 1], B: ['Partly right', 0.5], C: ['Wrong', 0] })`.
519
+ */
520
+ export declare function choices(options: Record<string, readonly [label: string, value: number]>): JudgeAnswer;
521
+ /**
522
+ * Criteria by name: a number is the weight; `{ weight, description }` also
523
+ * says what the criterion checks. Weights default to 1.
524
+ */
525
+ type CriteriaOptions = Record<string, number | {
526
+ weight?: number;
527
+ description?: string;
528
+ }>;
529
+ /**
530
+ * A judge that scores each criterion from 0 to 1; the score is the weighted
531
+ * mean. A number is the weight; `{ weight, description }` also says what the
532
+ * criterion means. Weights default to 1.
533
+ */
534
+ export declare function criteria(options: CriteriaOptions): JudgeAnswer;
535
+ /**
536
+ * One criterion's result, as a scorer returns it and as results record it:
537
+ * a value with what it saw, or `reached: false` when the check never got to
538
+ * run, because something before it failed (say, the app would not start).
539
+ * A criterion not reached counts as 0; the score's `explanation` says why,
540
+ * once, instead of every criterion repeating it.
541
+ */
542
+ type CriterionResult = ReachedCriterion | UnreachedCriterion;
543
+ type ReachedCriterion = {
544
+ name: string;
545
+ /** From 0 to 1. */
546
+ value: number;
547
+ /** Default 1, or the declared weight. */
548
+ weight?: number;
549
+ /** Why this value. */
550
+ explanation?: string;
551
+ /** What the check observed, as plain data. */
552
+ evidence?: JsonValue;
553
+ };
554
+ type UnreachedCriterion = {
555
+ name: string;
556
+ reached: false;
557
+ weight?: number;
558
+ explanation?: string;
559
+ };
560
+ /** A criterion as a scorer returns it: its evidence may be any plain value. */
561
+ type CriterionInput = (Omit<ReachedCriterion, 'evidence'> & {
562
+ evidence?: unknown;
563
+ }) | UnreachedCriterion;
564
+ /**
565
+ * The pass mark in words: `only 1`, `≥ 0.5`, or for choices the ones that
566
+ * pass, such as `A or B`.
567
+ */
568
+ export declare function passMark(passAt: number | undefined, answer?: JudgeAnswer): string;
176
569
  //#endregion
177
570
  //#region ../core/src/catalog.d.ts
178
571
  /**
@@ -184,6 +577,8 @@ export declare function turnResultEvents(result: TurnResult, turn: number, now:
184
577
  export type CatalogOptions = {
185
578
  /** Project root; definition sites are reported relative to it, never absolute. */
186
579
  root?: string;
580
+ /** The project's default judge agent (`judge` in evalkit.config.ts). */
581
+ judge?: AutAdapter;
187
582
  };
188
583
  export type EvalCatalogAgent = {
189
584
  name?: string;
@@ -235,10 +630,20 @@ export type EvalCatalogDataset = {
235
630
  export type EvalCatalogScorer = {
236
631
  name: string;
237
632
  kind: ScoringRule['kind'];
633
+ /** What it checks, in the author's words. */
634
+ description?: string;
238
635
  passAt?: number;
239
636
  supportsPartial?: boolean;
240
637
  /** Judges only. */
241
638
  rubric?: string;
639
+ /** Judges only: the agent that judges (its own, or the project's default). */
640
+ agent?: EvalCatalogAgent;
641
+ /** Judges only: the names of the inputs it sees. */
642
+ inputs?: string[];
643
+ /** Judges only: how it answers. */
644
+ answer?: JudgeAnswer;
645
+ /** Judges only: the prompt it receives, with `{input}` placeholders. */
646
+ prompt?: string;
242
647
  definedAt?: string;
243
648
  };
244
649
  export type EvalCatalogStep =
@@ -271,9 +676,10 @@ export type EvalCatalogEntry = {
271
676
  /** Runs started each time the scenario runs (`repeat`). */
272
677
  repeat: number;
273
678
  policy: {
274
- timeoutMs?: number;
275
679
  failfast?: boolean;
276
680
  };
681
+ /** The scenario's own limits; the project's, a cell's and `--limit` may add to them. */
682
+ limits?: Limits;
277
683
  transcript: EvalCatalogStep[];
278
684
  scorers: EvalCatalogScorer[];
279
685
  metadata?: JsonValue;
@@ -312,13 +718,22 @@ type EvalMatrixDefinition = {
312
718
  cases?: readonly JsonObject[];
313
719
  /** Partial patterns over declared dimensions; matching cells are never run. */
314
720
  exclude?: readonly JsonObject[];
721
+ /**
722
+ * Limits to compare, as axes: `{ steps: [40, 80] }`. Each becomes the axis
723
+ * `limits.steps`, so cells show it and `-a limits.steps=80` selects it.
724
+ */
725
+ limits?: Readonly<{
726
+ steps?: readonly number[];
727
+ tokens?: readonly number[];
728
+ time?: readonly (number | string)[];
729
+ }>;
315
730
  };
316
731
  type EvalMatrix = EvalMatrixDefinition & {
317
732
  kind: 'matrix';
318
733
  count(selection?: MatrixSelection): number;
319
734
  cells(selection?: MatrixSelection): IterableIterator<EvalMatrixCell>;
320
735
  };
321
- export declare function defineEvalMatrix<const T extends EvalMatrixDefinition>(definition: T): EvalMatrix & T;
736
+ export declare function defineEvalMatrix<const T extends EvalMatrixDefinition>(input: T): EvalMatrix & T;
322
737
  //#endregion
323
738
  //#region ../core/src/config.d.ts
324
739
  type EvalkitConfig = {
@@ -342,6 +757,24 @@ type EvalkitConfig = {
342
757
  repeat?: number;
343
758
  maxCells?: number;
344
759
  };
760
+ /**
761
+ * What each run may use before EvalKit stops it: `{ steps: 40, tokens:
762
+ * 2_000_000, time: '20m' }`. A scenario's `limits`, a matrix cell's and
763
+ * `--limit` override these, kind by kind.
764
+ */
765
+ limits?: LimitsInput;
766
+ /**
767
+ * Where each run's processes run: `none()` (the default, on the host),
768
+ * `container({ image, network })` or `sandboxExec({ allow })`. Adapters
769
+ * and scorers run commands through `context.shell`, which puts them there.
770
+ */
771
+ isolation?: Isolation;
772
+ /**
773
+ * Services runs reach, by name: started on the host before the first run
774
+ * that needs them and stopped after the invocation's last. Each run finds
775
+ * them in `context.fixtures`.
776
+ */
777
+ fixtures?: Readonly<Record<string, Fixture>>;
345
778
  reportDir?: string;
346
779
  /** The candidate files saved with each run's results. */
347
780
  artifacts?: {
@@ -355,11 +788,21 @@ type EvalkitConfig = {
355
788
  /** Limits for files adapters `attach()`. */
356
789
  attachments?: AttachmentLimits;
357
790
  };
358
- /** Where each run's real workspace lives during a run. Default `_evalkit-sandbox`. */
791
+ /**
792
+ * Where each run's real workspace lives. Default: outside the project, in
793
+ * `<tmp>/evalkit/<project>-<hash>`, so agents cannot read the project or
794
+ * other runs by looking around. Inside the project, `run` warns.
795
+ */
359
796
  sandboxDir?: string;
360
797
  /** Which run workspaces to keep in `sandboxDir` afterwards. Default `'failed'`: only runs that did not pass. */
361
798
  keepSandboxes?: KeepSandboxes;
362
799
  share?: ShareConfig;
800
+ /**
801
+ * The agent for every judge that names none: `judge(name, { rubric })`.
802
+ * Made with `defineAgent()`; it gets each run's parameters, so a matrix
803
+ * axis can choose its model.
804
+ */
805
+ judge?: AutAdapter;
363
806
  };
364
807
  type KeepSandboxes = 'failed' | 'all' | 'none';
365
808
  type AttachmentLimits = {
@@ -386,32 +829,6 @@ type ShareConfig = {
386
829
  /** Pure, typed project configuration. Loading/discovery belongs to the CLI. */
387
830
  export declare function defineConfig<const T extends EvalkitConfig>(configuration: T): T;
388
831
  //#endregion
389
- //#region ../core/src/usage.d.ts
390
- /**
391
- * Token usage an agent reports for one turn. EvalKit never measures or infers
392
- * it; adapters copy it from their provider.
393
- */
394
- type Usage = {
395
- /**
396
- * Every input token the model read this turn: the prompt, history and tool
397
- * results, **including** tokens read from or written to a prompt cache.
398
- * (Some providers report cached tokens separately; add them in.)
399
- */
400
- inputTokens?: number;
401
- /** Every token the model produced, including reasoning tokens. */
402
- outputTokens?: number;
403
- /** Of `inputTokens`, how many were read from a prompt cache. Informational. */
404
- cachedInputTokens?: number;
405
- /** The provider's own total; used only when input and output are not reported. */
406
- totalTokens?: number;
407
- };
408
- /**
409
- * The tokens a turn counts toward the `tokens` metric: `inputTokens +
410
- * outputTokens` (cached input included), or `totalTokens` when neither is
411
- * reported. Undefined when the turn reported no usage.
412
- */
413
- export declare function turnTokens(usage: Usage | undefined): number | undefined;
414
- //#endregion
415
832
  //#region ../core/src/json.d.ts
416
833
  /** A value that cannot be stored in a report, with the path of the offending part. */
417
834
  export declare class NotJsonError extends Error {
@@ -448,9 +865,9 @@ export declare function definitionSite(value: unknown): DefinitionSite | undefin
448
865
  //#endregion
449
866
  //#region ../core/src/schema.d.ts
450
867
  /** Runtime schemas for serialized EvalKit report and API boundaries. */
451
- export declare const RunStatusSchema: Schema.Literal<["running", "passed", "failed", "errored", "cancelled"]>;
868
+ export declare const RunStatusSchema: Schema.Literal<["running", "passed", "failed", "errored", "cancelled", "limited"]>;
452
869
  /** The report schema version this EvalKit writes and reads. */
453
- export declare const REPORT_SCHEMA_VERSION = 6;
870
+ export declare const REPORT_SCHEMA_VERSION = 7;
454
871
  export declare const RecordedErrorSchema: Schema.Struct<{
455
872
  name: typeof Schema.String;
456
873
  message: typeof Schema.String;
@@ -488,8 +905,25 @@ export declare const RunDatasetSchema: Schema.Struct<{
488
905
  source: Schema.Literal<["static", "computed"]>;
489
906
  digest: typeof Schema.String;
490
907
  }>;
908
+ export declare const LimitsSchema: Schema.Struct<{
909
+ steps: Schema.optional<typeof Schema.Number>;
910
+ tokens: Schema.optional<typeof Schema.Number>;
911
+ time: Schema.optional<typeof Schema.Number>;
912
+ }>;
913
+ export declare const LimitReachedSchema: Schema.Struct<{
914
+ limit: Schema.Literal<["steps", "tokens", "time"]>;
915
+ value: typeof Schema.Number;
916
+ used: typeof Schema.Number;
917
+ }>;
918
+ export declare const RunIsolationSchema: Schema.Union<[Schema.Struct<{
919
+ kind: Schema.Literal<["container"]>;
920
+ image: typeof Schema.String;
921
+ network: Schema.Literal<["none", "fixtures", "full"]>;
922
+ }>, Schema.Struct<{
923
+ kind: Schema.Literal<["sandbox-exec"]>;
924
+ }>]>;
491
925
  export declare const RunMetadataSchema: Schema.Struct<{
492
- schemaVersion: Schema.Literal<[6]>;
926
+ schemaVersion: Schema.Literal<[7]>;
493
927
  runUri: Schema.filter<typeof Schema.String>;
494
928
  evalId: typeof Schema.String;
495
929
  suiteId: Schema.optional<typeof Schema.String>;
@@ -536,10 +970,22 @@ export declare const RunMetadataSchema: Schema.Struct<{
536
970
  source: Schema.Literal<["static", "computed"]>;
537
971
  digest: typeof Schema.String;
538
972
  }>>>>;
973
+ limits: Schema.optional<Schema.Struct<{
974
+ steps: Schema.optional<typeof Schema.Number>;
975
+ tokens: Schema.optional<typeof Schema.Number>;
976
+ time: Schema.optional<typeof Schema.Number>;
977
+ }>>;
978
+ isolation: Schema.optional<Schema.Union<[Schema.Struct<{
979
+ kind: Schema.Literal<["container"]>;
980
+ image: typeof Schema.String;
981
+ network: Schema.Literal<["none", "fixtures", "full"]>;
982
+ }>, Schema.Struct<{
983
+ kind: Schema.Literal<["sandbox-exec"]>;
984
+ }>]>>;
539
985
  }>;
540
986
  /** On-disk manifests include a lifecycle status. */
541
987
  export declare const RunManifestSchema: Schema.Struct<{
542
- schemaVersion: Schema.Literal<[6]>;
988
+ schemaVersion: Schema.Literal<[7]>;
543
989
  runUri: Schema.filter<typeof Schema.String>;
544
990
  evalId: typeof Schema.String;
545
991
  suiteId: Schema.optional<typeof Schema.String>;
@@ -585,14 +1031,42 @@ export declare const RunManifestSchema: Schema.Struct<{
585
1031
  source: Schema.Literal<["static", "computed"]>;
586
1032
  digest: typeof Schema.String;
587
1033
  }>>>>;
588
- status: Schema.optional<Schema.Literal<["running", "passed", "failed", "errored", "cancelled"]>>;
1034
+ limits: Schema.optional<Schema.Struct<{
1035
+ steps: Schema.optional<typeof Schema.Number>;
1036
+ tokens: Schema.optional<typeof Schema.Number>;
1037
+ time: Schema.optional<typeof Schema.Number>;
1038
+ }>>;
1039
+ isolation: Schema.optional<Schema.Union<[Schema.Struct<{
1040
+ kind: Schema.Literal<["container"]>;
1041
+ image: typeof Schema.String;
1042
+ network: Schema.Literal<["none", "fixtures", "full"]>;
1043
+ }>, Schema.Struct<{
1044
+ kind: Schema.Literal<["sandbox-exec"]>;
1045
+ }>]>>;
1046
+ status: Schema.optional<Schema.Literal<["running", "passed", "failed", "errored", "cancelled", "limited"]>>;
589
1047
  }>;
1048
+ /** ATXF usage: disjoint buckets, `input` without cached tokens. */
590
1049
  export declare const UsageSchema: Schema.Struct<{
591
- inputTokens: Schema.optional<typeof Schema.Number>;
592
- outputTokens: Schema.optional<typeof Schema.Number>;
593
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
594
- totalTokens: Schema.optional<typeof Schema.Number>;
1050
+ input: typeof Schema.Number;
1051
+ output: typeof Schema.Number;
1052
+ cacheRead: Schema.optional<typeof Schema.Number>;
1053
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1054
+ reasoning: Schema.optional<typeof Schema.Number>;
1055
+ total: Schema.optional<typeof Schema.Number>;
1056
+ cost: Schema.optional<Schema.Struct<{
1057
+ currency: Schema.optional<typeof Schema.String>;
1058
+ input: Schema.optional<typeof Schema.Number>;
1059
+ output: Schema.optional<typeof Schema.Number>;
1060
+ cacheRead: Schema.optional<typeof Schema.Number>;
1061
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1062
+ total: typeof Schema.Number;
1063
+ }>>;
595
1064
  }>;
1065
+ /**
1066
+ * An ATXF transcript in JSON (`{ header, records }`). Its records are checked
1067
+ * by the ATXF validator where they are written, not here.
1068
+ */
1069
+ export declare const TranscriptSchema: Schema.declare<Transcript, Transcript, readonly [], never>;
596
1070
  export declare const JudgeRunInfoSchema: Schema.Struct<{
597
1071
  agent: Schema.optional<Schema.Struct<{
598
1072
  id: typeof Schema.String;
@@ -600,15 +1074,45 @@ export declare const JudgeRunInfoSchema: Schema.Struct<{
600
1074
  name: Schema.optional<typeof Schema.String>;
601
1075
  version: Schema.optional<typeof Schema.String>;
602
1076
  }>>;
1077
+ model: Schema.optional<typeof Schema.String>;
603
1078
  usage: Schema.optional<Schema.Struct<{
604
- inputTokens: Schema.optional<typeof Schema.Number>;
605
- outputTokens: Schema.optional<typeof Schema.Number>;
606
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
607
- totalTokens: Schema.optional<typeof Schema.Number>;
1079
+ input: typeof Schema.Number;
1080
+ output: typeof Schema.Number;
1081
+ cacheRead: Schema.optional<typeof Schema.Number>;
1082
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1083
+ reasoning: Schema.optional<typeof Schema.Number>;
1084
+ total: Schema.optional<typeof Schema.Number>;
1085
+ cost: Schema.optional<Schema.Struct<{
1086
+ currency: Schema.optional<typeof Schema.String>;
1087
+ input: Schema.optional<typeof Schema.Number>;
1088
+ output: Schema.optional<typeof Schema.Number>;
1089
+ cacheRead: Schema.optional<typeof Schema.Number>;
1090
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1091
+ total: typeof Schema.Number;
1092
+ }>>;
608
1093
  }>>;
609
- events: Schema.optional<Schema.mutable<Schema.Array$<Schema.Schema<JsonValue, JsonValue, never>>>>;
1094
+ prompt: Schema.optional<typeof Schema.String>;
1095
+ reply: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1096
+ attempts: Schema.optional<typeof Schema.Number>;
1097
+ /** The judge's own session, an ATXF transcript (checked when written). */
1098
+ transcript: Schema.optional<Schema.declare<Transcript, Transcript, readonly [], never>>;
610
1099
  }>;
611
1100
  export declare const ScoreResultSchema: Schema.Struct<{
1101
+ passAt: Schema.optional<typeof Schema.Number>;
1102
+ choice: Schema.optional<typeof Schema.String>;
1103
+ criteria: Schema.optional<Schema.mutable<Schema.Array$<Schema.Union<[Schema.Struct<{
1104
+ name: typeof Schema.String;
1105
+ value: typeof Schema.Number;
1106
+ weight: Schema.optional<typeof Schema.Number>;
1107
+ explanation: Schema.optional<typeof Schema.String>;
1108
+ evidence: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1109
+ }>, Schema.Struct<{
1110
+ name: typeof Schema.String;
1111
+ reached: Schema.Literal<[false]>;
1112
+ weight: Schema.optional<typeof Schema.Number>;
1113
+ explanation: Schema.optional<typeof Schema.String>;
1114
+ }>]>>>>;
1115
+ attachments: Schema.optional<Schema.mutable<Schema.Array$<typeof Schema.String>>>;
612
1116
  name: typeof Schema.String;
613
1117
  kind: Schema.Literal<["predicate", "judge"]>;
614
1118
  value: Schema.optional<typeof Schema.Number>;
@@ -622,13 +1126,28 @@ export declare const ScoreResultSchema: Schema.Struct<{
622
1126
  name: Schema.optional<typeof Schema.String>;
623
1127
  version: Schema.optional<typeof Schema.String>;
624
1128
  }>>;
1129
+ model: Schema.optional<typeof Schema.String>;
625
1130
  usage: Schema.optional<Schema.Struct<{
626
- inputTokens: Schema.optional<typeof Schema.Number>;
627
- outputTokens: Schema.optional<typeof Schema.Number>;
628
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
629
- totalTokens: Schema.optional<typeof Schema.Number>;
1131
+ input: typeof Schema.Number;
1132
+ output: typeof Schema.Number;
1133
+ cacheRead: Schema.optional<typeof Schema.Number>;
1134
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1135
+ reasoning: Schema.optional<typeof Schema.Number>;
1136
+ total: Schema.optional<typeof Schema.Number>;
1137
+ cost: Schema.optional<Schema.Struct<{
1138
+ currency: Schema.optional<typeof Schema.String>;
1139
+ input: Schema.optional<typeof Schema.Number>;
1140
+ output: Schema.optional<typeof Schema.Number>;
1141
+ cacheRead: Schema.optional<typeof Schema.Number>;
1142
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1143
+ total: typeof Schema.Number;
1144
+ }>>;
630
1145
  }>>;
631
- events: Schema.optional<Schema.mutable<Schema.Array$<Schema.Schema<JsonValue, JsonValue, never>>>>;
1146
+ prompt: Schema.optional<typeof Schema.String>;
1147
+ reply: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1148
+ attempts: Schema.optional<typeof Schema.Number>;
1149
+ /** The judge's own session, an ATXF transcript (checked when written). */
1150
+ transcript: Schema.optional<Schema.declare<Transcript, Transcript, readonly [], never>>;
632
1151
  }>>;
633
1152
  durationMs: typeof Schema.Number;
634
1153
  error: Schema.optional<Schema.Struct<{
@@ -639,6 +1158,21 @@ export declare const ScoreResultSchema: Schema.Struct<{
639
1158
  skipped: Schema.optional<Schema.Literal<[true]>>;
640
1159
  }>;
641
1160
  export declare const CheckpointResultSchema: Schema.Struct<{
1161
+ passAt: Schema.optional<typeof Schema.Number>;
1162
+ choice: Schema.optional<typeof Schema.String>;
1163
+ criteria: Schema.optional<Schema.mutable<Schema.Array$<Schema.Union<[Schema.Struct<{
1164
+ name: typeof Schema.String;
1165
+ value: typeof Schema.Number;
1166
+ weight: Schema.optional<typeof Schema.Number>;
1167
+ explanation: Schema.optional<typeof Schema.String>;
1168
+ evidence: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1169
+ }>, Schema.Struct<{
1170
+ name: typeof Schema.String;
1171
+ reached: Schema.Literal<[false]>;
1172
+ weight: Schema.optional<typeof Schema.Number>;
1173
+ explanation: Schema.optional<typeof Schema.String>;
1174
+ }>]>>>>;
1175
+ attachments: Schema.optional<Schema.mutable<Schema.Array$<typeof Schema.String>>>;
642
1176
  step: typeof Schema.Number;
643
1177
  kind: Schema.Literal<["predicate", "judge", "expect-tool-call"]>;
644
1178
  name: typeof Schema.String;
@@ -654,13 +1188,28 @@ export declare const CheckpointResultSchema: Schema.Struct<{
654
1188
  name: Schema.optional<typeof Schema.String>;
655
1189
  version: Schema.optional<typeof Schema.String>;
656
1190
  }>>;
1191
+ model: Schema.optional<typeof Schema.String>;
657
1192
  usage: Schema.optional<Schema.Struct<{
658
- inputTokens: Schema.optional<typeof Schema.Number>;
659
- outputTokens: Schema.optional<typeof Schema.Number>;
660
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
661
- totalTokens: Schema.optional<typeof Schema.Number>;
1193
+ input: typeof Schema.Number;
1194
+ output: typeof Schema.Number;
1195
+ cacheRead: Schema.optional<typeof Schema.Number>;
1196
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1197
+ reasoning: Schema.optional<typeof Schema.Number>;
1198
+ total: Schema.optional<typeof Schema.Number>;
1199
+ cost: Schema.optional<Schema.Struct<{
1200
+ currency: Schema.optional<typeof Schema.String>;
1201
+ input: Schema.optional<typeof Schema.Number>;
1202
+ output: Schema.optional<typeof Schema.Number>;
1203
+ cacheRead: Schema.optional<typeof Schema.Number>;
1204
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1205
+ total: typeof Schema.Number;
1206
+ }>>;
662
1207
  }>>;
663
- events: Schema.optional<Schema.mutable<Schema.Array$<Schema.Schema<JsonValue, JsonValue, never>>>>;
1208
+ prompt: Schema.optional<typeof Schema.String>;
1209
+ reply: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1210
+ attempts: Schema.optional<typeof Schema.Number>;
1211
+ /** The judge's own session, an ATXF transcript (checked when written). */
1212
+ transcript: Schema.optional<Schema.declare<Transcript, Transcript, readonly [], never>>;
664
1213
  }>>;
665
1214
  durationMs: Schema.optional<typeof Schema.Number>;
666
1215
  error: Schema.optional<Schema.Struct<{
@@ -669,7 +1218,7 @@ export declare const CheckpointResultSchema: Schema.Struct<{
669
1218
  stack: Schema.optional<typeof Schema.String>;
670
1219
  }>>;
671
1220
  matchedToolCall: Schema.optional<Schema.Struct<{
672
- eventIndex: typeof Schema.Number;
1221
+ messageId: typeof Schema.String;
673
1222
  id: typeof Schema.String;
674
1223
  }>>;
675
1224
  }>;
@@ -687,6 +1236,21 @@ export declare const MetricResultSchema: Schema.Struct<{
687
1236
  }>;
688
1237
  export declare const RunScoringSchema: Schema.Struct<{
689
1238
  results: Schema.mutable<Schema.Array$<Schema.Struct<{
1239
+ passAt: Schema.optional<typeof Schema.Number>;
1240
+ choice: Schema.optional<typeof Schema.String>;
1241
+ criteria: Schema.optional<Schema.mutable<Schema.Array$<Schema.Union<[Schema.Struct<{
1242
+ name: typeof Schema.String;
1243
+ value: typeof Schema.Number;
1244
+ weight: Schema.optional<typeof Schema.Number>;
1245
+ explanation: Schema.optional<typeof Schema.String>;
1246
+ evidence: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1247
+ }>, Schema.Struct<{
1248
+ name: typeof Schema.String;
1249
+ reached: Schema.Literal<[false]>;
1250
+ weight: Schema.optional<typeof Schema.Number>;
1251
+ explanation: Schema.optional<typeof Schema.String>;
1252
+ }>]>>>>;
1253
+ attachments: Schema.optional<Schema.mutable<Schema.Array$<typeof Schema.String>>>;
690
1254
  name: typeof Schema.String;
691
1255
  kind: Schema.Literal<["predicate", "judge"]>;
692
1256
  value: Schema.optional<typeof Schema.Number>;
@@ -700,13 +1264,28 @@ export declare const RunScoringSchema: Schema.Struct<{
700
1264
  name: Schema.optional<typeof Schema.String>;
701
1265
  version: Schema.optional<typeof Schema.String>;
702
1266
  }>>;
1267
+ model: Schema.optional<typeof Schema.String>;
703
1268
  usage: Schema.optional<Schema.Struct<{
704
- inputTokens: Schema.optional<typeof Schema.Number>;
705
- outputTokens: Schema.optional<typeof Schema.Number>;
706
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
707
- totalTokens: Schema.optional<typeof Schema.Number>;
1269
+ input: typeof Schema.Number;
1270
+ output: typeof Schema.Number;
1271
+ cacheRead: Schema.optional<typeof Schema.Number>;
1272
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1273
+ reasoning: Schema.optional<typeof Schema.Number>;
1274
+ total: Schema.optional<typeof Schema.Number>;
1275
+ cost: Schema.optional<Schema.Struct<{
1276
+ currency: Schema.optional<typeof Schema.String>;
1277
+ input: Schema.optional<typeof Schema.Number>;
1278
+ output: Schema.optional<typeof Schema.Number>;
1279
+ cacheRead: Schema.optional<typeof Schema.Number>;
1280
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1281
+ total: typeof Schema.Number;
1282
+ }>>;
708
1283
  }>>;
709
- events: Schema.optional<Schema.mutable<Schema.Array$<Schema.Schema<JsonValue, JsonValue, never>>>>;
1284
+ prompt: Schema.optional<typeof Schema.String>;
1285
+ reply: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1286
+ attempts: Schema.optional<typeof Schema.Number>;
1287
+ /** The judge's own session, an ATXF transcript (checked when written). */
1288
+ transcript: Schema.optional<Schema.declare<Transcript, Transcript, readonly [], never>>;
710
1289
  }>>;
711
1290
  durationMs: typeof Schema.Number;
712
1291
  error: Schema.optional<Schema.Struct<{
@@ -729,6 +1308,21 @@ export declare const RunScoringSchema: Schema.Struct<{
729
1308
  }>>;
730
1309
  }>>>>;
731
1310
  checkpoints: Schema.optional<Schema.mutable<Schema.Array$<Schema.Struct<{
1311
+ passAt: Schema.optional<typeof Schema.Number>;
1312
+ choice: Schema.optional<typeof Schema.String>;
1313
+ criteria: Schema.optional<Schema.mutable<Schema.Array$<Schema.Union<[Schema.Struct<{
1314
+ name: typeof Schema.String;
1315
+ value: typeof Schema.Number;
1316
+ weight: Schema.optional<typeof Schema.Number>;
1317
+ explanation: Schema.optional<typeof Schema.String>;
1318
+ evidence: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1319
+ }>, Schema.Struct<{
1320
+ name: typeof Schema.String;
1321
+ reached: Schema.Literal<[false]>;
1322
+ weight: Schema.optional<typeof Schema.Number>;
1323
+ explanation: Schema.optional<typeof Schema.String>;
1324
+ }>]>>>>;
1325
+ attachments: Schema.optional<Schema.mutable<Schema.Array$<typeof Schema.String>>>;
732
1326
  step: typeof Schema.Number;
733
1327
  kind: Schema.Literal<["predicate", "judge", "expect-tool-call"]>;
734
1328
  name: typeof Schema.String;
@@ -744,13 +1338,28 @@ export declare const RunScoringSchema: Schema.Struct<{
744
1338
  name: Schema.optional<typeof Schema.String>;
745
1339
  version: Schema.optional<typeof Schema.String>;
746
1340
  }>>;
1341
+ model: Schema.optional<typeof Schema.String>;
747
1342
  usage: Schema.optional<Schema.Struct<{
748
- inputTokens: Schema.optional<typeof Schema.Number>;
749
- outputTokens: Schema.optional<typeof Schema.Number>;
750
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
751
- totalTokens: Schema.optional<typeof Schema.Number>;
1343
+ input: typeof Schema.Number;
1344
+ output: typeof Schema.Number;
1345
+ cacheRead: Schema.optional<typeof Schema.Number>;
1346
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1347
+ reasoning: Schema.optional<typeof Schema.Number>;
1348
+ total: Schema.optional<typeof Schema.Number>;
1349
+ cost: Schema.optional<Schema.Struct<{
1350
+ currency: Schema.optional<typeof Schema.String>;
1351
+ input: Schema.optional<typeof Schema.Number>;
1352
+ output: Schema.optional<typeof Schema.Number>;
1353
+ cacheRead: Schema.optional<typeof Schema.Number>;
1354
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1355
+ total: typeof Schema.Number;
1356
+ }>>;
752
1357
  }>>;
753
- events: Schema.optional<Schema.mutable<Schema.Array$<Schema.Schema<JsonValue, JsonValue, never>>>>;
1358
+ prompt: Schema.optional<typeof Schema.String>;
1359
+ reply: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1360
+ attempts: Schema.optional<typeof Schema.Number>;
1361
+ /** The judge's own session, an ATXF transcript (checked when written). */
1362
+ transcript: Schema.optional<Schema.declare<Transcript, Transcript, readonly [], never>>;
754
1363
  }>>;
755
1364
  durationMs: Schema.optional<typeof Schema.Number>;
756
1365
  error: Schema.optional<Schema.Struct<{
@@ -759,7 +1368,7 @@ export declare const RunScoringSchema: Schema.Struct<{
759
1368
  stack: Schema.optional<typeof Schema.String>;
760
1369
  }>>;
761
1370
  matchedToolCall: Schema.optional<Schema.Struct<{
762
- eventIndex: typeof Schema.Number;
1371
+ messageId: typeof Schema.String;
763
1372
  id: typeof Schema.String;
764
1373
  }>>;
765
1374
  }>>>>;
@@ -778,11 +1387,26 @@ export declare const AttachmentEntrySchema: Schema.Struct<{
778
1387
  truncatedFrom: Schema.optional<typeof Schema.Number>;
779
1388
  }>;
780
1389
  export declare const RunSummarySchema: Schema.Struct<{
781
- status: Schema.Literal<["running", "passed", "failed", "errored", "cancelled"]>;
1390
+ status: Schema.Literal<["running", "passed", "failed", "errored", "cancelled", "limited"]>;
782
1391
  endedAt: typeof Schema.String;
783
1392
  durationMs: Schema.optional<typeof Schema.Number>;
784
1393
  scoring: Schema.optional<Schema.Struct<{
785
1394
  results: Schema.mutable<Schema.Array$<Schema.Struct<{
1395
+ passAt: Schema.optional<typeof Schema.Number>;
1396
+ choice: Schema.optional<typeof Schema.String>;
1397
+ criteria: Schema.optional<Schema.mutable<Schema.Array$<Schema.Union<[Schema.Struct<{
1398
+ name: typeof Schema.String;
1399
+ value: typeof Schema.Number;
1400
+ weight: Schema.optional<typeof Schema.Number>;
1401
+ explanation: Schema.optional<typeof Schema.String>;
1402
+ evidence: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1403
+ }>, Schema.Struct<{
1404
+ name: typeof Schema.String;
1405
+ reached: Schema.Literal<[false]>;
1406
+ weight: Schema.optional<typeof Schema.Number>;
1407
+ explanation: Schema.optional<typeof Schema.String>;
1408
+ }>]>>>>;
1409
+ attachments: Schema.optional<Schema.mutable<Schema.Array$<typeof Schema.String>>>;
786
1410
  name: typeof Schema.String;
787
1411
  kind: Schema.Literal<["predicate", "judge"]>;
788
1412
  value: Schema.optional<typeof Schema.Number>;
@@ -796,13 +1420,28 @@ export declare const RunSummarySchema: Schema.Struct<{
796
1420
  name: Schema.optional<typeof Schema.String>;
797
1421
  version: Schema.optional<typeof Schema.String>;
798
1422
  }>>;
1423
+ model: Schema.optional<typeof Schema.String>;
799
1424
  usage: Schema.optional<Schema.Struct<{
800
- inputTokens: Schema.optional<typeof Schema.Number>;
801
- outputTokens: Schema.optional<typeof Schema.Number>;
802
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
803
- totalTokens: Schema.optional<typeof Schema.Number>;
1425
+ input: typeof Schema.Number;
1426
+ output: typeof Schema.Number;
1427
+ cacheRead: Schema.optional<typeof Schema.Number>;
1428
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1429
+ reasoning: Schema.optional<typeof Schema.Number>;
1430
+ total: Schema.optional<typeof Schema.Number>;
1431
+ cost: Schema.optional<Schema.Struct<{
1432
+ currency: Schema.optional<typeof Schema.String>;
1433
+ input: Schema.optional<typeof Schema.Number>;
1434
+ output: Schema.optional<typeof Schema.Number>;
1435
+ cacheRead: Schema.optional<typeof Schema.Number>;
1436
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1437
+ total: typeof Schema.Number;
1438
+ }>>;
804
1439
  }>>;
805
- events: Schema.optional<Schema.mutable<Schema.Array$<Schema.Schema<JsonValue, JsonValue, never>>>>;
1440
+ prompt: Schema.optional<typeof Schema.String>;
1441
+ reply: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1442
+ attempts: Schema.optional<typeof Schema.Number>;
1443
+ /** The judge's own session, an ATXF transcript (checked when written). */
1444
+ transcript: Schema.optional<Schema.declare<Transcript, Transcript, readonly [], never>>;
806
1445
  }>>;
807
1446
  durationMs: typeof Schema.Number;
808
1447
  error: Schema.optional<Schema.Struct<{
@@ -825,6 +1464,21 @@ export declare const RunSummarySchema: Schema.Struct<{
825
1464
  }>>;
826
1465
  }>>>>;
827
1466
  checkpoints: Schema.optional<Schema.mutable<Schema.Array$<Schema.Struct<{
1467
+ passAt: Schema.optional<typeof Schema.Number>;
1468
+ choice: Schema.optional<typeof Schema.String>;
1469
+ criteria: Schema.optional<Schema.mutable<Schema.Array$<Schema.Union<[Schema.Struct<{
1470
+ name: typeof Schema.String;
1471
+ value: typeof Schema.Number;
1472
+ weight: Schema.optional<typeof Schema.Number>;
1473
+ explanation: Schema.optional<typeof Schema.String>;
1474
+ evidence: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1475
+ }>, Schema.Struct<{
1476
+ name: typeof Schema.String;
1477
+ reached: Schema.Literal<[false]>;
1478
+ weight: Schema.optional<typeof Schema.Number>;
1479
+ explanation: Schema.optional<typeof Schema.String>;
1480
+ }>]>>>>;
1481
+ attachments: Schema.optional<Schema.mutable<Schema.Array$<typeof Schema.String>>>;
828
1482
  step: typeof Schema.Number;
829
1483
  kind: Schema.Literal<["predicate", "judge", "expect-tool-call"]>;
830
1484
  name: typeof Schema.String;
@@ -840,13 +1494,28 @@ export declare const RunSummarySchema: Schema.Struct<{
840
1494
  name: Schema.optional<typeof Schema.String>;
841
1495
  version: Schema.optional<typeof Schema.String>;
842
1496
  }>>;
1497
+ model: Schema.optional<typeof Schema.String>;
843
1498
  usage: Schema.optional<Schema.Struct<{
844
- inputTokens: Schema.optional<typeof Schema.Number>;
845
- outputTokens: Schema.optional<typeof Schema.Number>;
846
- cachedInputTokens: Schema.optional<typeof Schema.Number>;
847
- totalTokens: Schema.optional<typeof Schema.Number>;
1499
+ input: typeof Schema.Number;
1500
+ output: typeof Schema.Number;
1501
+ cacheRead: Schema.optional<typeof Schema.Number>;
1502
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1503
+ reasoning: Schema.optional<typeof Schema.Number>;
1504
+ total: Schema.optional<typeof Schema.Number>;
1505
+ cost: Schema.optional<Schema.Struct<{
1506
+ currency: Schema.optional<typeof Schema.String>;
1507
+ input: Schema.optional<typeof Schema.Number>;
1508
+ output: Schema.optional<typeof Schema.Number>;
1509
+ cacheRead: Schema.optional<typeof Schema.Number>;
1510
+ cacheWrite: Schema.optional<typeof Schema.Number>;
1511
+ total: typeof Schema.Number;
1512
+ }>>;
848
1513
  }>>;
849
- events: Schema.optional<Schema.mutable<Schema.Array$<Schema.Schema<JsonValue, JsonValue, never>>>>;
1514
+ prompt: Schema.optional<typeof Schema.String>;
1515
+ reply: Schema.optional<Schema.Schema<JsonValue, JsonValue, never>>;
1516
+ attempts: Schema.optional<typeof Schema.Number>;
1517
+ /** The judge's own session, an ATXF transcript (checked when written). */
1518
+ transcript: Schema.optional<Schema.declare<Transcript, Transcript, readonly [], never>>;
850
1519
  }>>;
851
1520
  durationMs: Schema.optional<typeof Schema.Number>;
852
1521
  error: Schema.optional<Schema.Struct<{
@@ -855,7 +1524,7 @@ export declare const RunSummarySchema: Schema.Struct<{
855
1524
  stack: Schema.optional<typeof Schema.String>;
856
1525
  }>>;
857
1526
  matchedToolCall: Schema.optional<Schema.Struct<{
858
- eventIndex: typeof Schema.Number;
1527
+ messageId: typeof Schema.String;
859
1528
  id: typeof Schema.String;
860
1529
  }>>;
861
1530
  }>>>>;
@@ -878,17 +1547,18 @@ export declare const RunSummarySchema: Schema.Struct<{
878
1547
  message: typeof Schema.String;
879
1548
  stack: Schema.optional<typeof Schema.String>;
880
1549
  }>>;
1550
+ limit: Schema.optional<Schema.Struct<{
1551
+ limit: Schema.Literal<["steps", "tokens", "time"]>;
1552
+ value: typeof Schema.Number;
1553
+ used: typeof Schema.Number;
1554
+ }>>;
881
1555
  }>;
882
- export declare const TrajectoryEventSchema: Schema.Schema<TrajectoryEvent>;
1556
+ export declare const RunEventSchema: Schema.Schema<RunEvent>;
883
1557
  export declare const ApiErrorSchema: Schema.Struct<{
884
1558
  error: typeof Schema.String;
885
1559
  message: typeof Schema.String;
886
1560
  }>;
887
1561
  //#endregion
888
- //#region ../core/src/trajectory.d.ts
889
- /** Decode one private report's JSONL trajectory; reject malformed/non-event lines with their line number. */
890
- export declare function parseTrajectoryJsonl(contents: string): TrajectoryEvent[];
891
- //#endregion
892
1562
  //#region ../core/src/index.d.ts
893
1563
  export type JsonPrimitive = boolean | number | string | null;
894
1564
  export type JsonValue = JsonPrimitive | JsonValue[] | {
@@ -919,45 +1589,6 @@ export type RecordedError = {
919
1589
  message: string;
920
1590
  stack?: string;
921
1591
  };
922
- export type AutEvent = {
923
- kind: 'started';
924
- timestamp: string;
925
- } | {
926
- kind: 'message';
927
- role: 'system' | 'user' | 'assistant' | 'tool';
928
- content: JsonValue;
929
- timestamp: string;
930
- } | {
931
- kind: 'tool-call';
932
- id: string;
933
- name: string;
934
- arguments: JsonValue;
935
- timestamp: string;
936
- } | {
937
- kind: 'tool-result';
938
- id: string;
939
- name?: string;
940
- result: JsonValue;
941
- timestamp: string;
942
- } | {
943
- kind: 'turn-started';
944
- turn: number;
945
- timestamp: string;
946
- } | {
947
- kind: 'turn-completed';
948
- turn: number;
949
- timestamp: string;
950
- latencyMs?: number;
951
- usage?: Usage;
952
- } | {
953
- kind: 'completed';
954
- output?: JsonValue;
955
- timestamp: string;
956
- } | {
957
- kind: 'error';
958
- error: RecordedError;
959
- timestamp: string;
960
- };
961
1592
  export type RunnerEvent = {
962
1593
  kind: 'run-started';
963
1594
  timestamp: string;
@@ -1006,7 +1637,10 @@ export type RunnerEvent = {
1006
1637
  scorer: string;
1007
1638
  error: RecordedError;
1008
1639
  timestamp: string;
1009
- } | {
1640
+ } | ({
1641
+ kind: 'limit-reached';
1642
+ timestamp: string;
1643
+ } & LimitReached) | {
1010
1644
  kind: 'run-completed';
1011
1645
  timestamp: string;
1012
1646
  } | {
@@ -1014,11 +1648,25 @@ export type RunnerEvent = {
1014
1648
  error: RecordedError;
1015
1649
  timestamp: string;
1016
1650
  };
1017
- export type TrajectoryEvent = (AutEvent & {
1018
- source: 'aut';
1019
- }) | (RunnerEvent & {
1020
- source: 'runner';
1021
- });
1651
+ /**
1652
+ * One of EvalKit's own events in `run-events.jsonl`. `at` is the ID of the
1653
+ * transcript record it happened after (null before the first), which places
1654
+ * it in the agent's transcript.
1655
+ */
1656
+ /**
1657
+ * What the dashboard shows of one run's session: the agent's transcript
1658
+ * (null before its first line is written) and EvalKit's events, placed in
1659
+ * it by `at`.
1660
+ */
1661
+ export type RunTranscriptView = {
1662
+ transcript: Transcript | null;
1663
+ /** Sub-agent transcripts the run kept, by transcript ID. */
1664
+ subagents: Record<string, Transcript>;
1665
+ runEvents: RunEvent[];
1666
+ };
1667
+ export type RunEvent = RunnerEvent & {
1668
+ at: string | null;
1669
+ };
1022
1670
  export type WorkspaceView = {
1023
1671
  /** Absolute path to this run-scoped workspace. Do not persist it in reports. */
1024
1672
  root: string;
@@ -1036,6 +1684,20 @@ export type AutContext = {
1036
1684
  runtime?: AgentRuntimeName;
1037
1685
  /** Values of the scenario's candidate datasets, by dataset ID. */
1038
1686
  data: JsonObject;
1687
+ /**
1688
+ * Aborts when the run hits a limit or is cancelled. Pass it to model calls
1689
+ * and tool processes so they stop with the run.
1690
+ */
1691
+ signal: AbortSignal;
1692
+ /** The limits in force for this run; see `limits` in the config. */
1693
+ limits: Limits;
1694
+ /**
1695
+ * The run's shell: run the agent and its tools through it, so they run
1696
+ * where the project's `isolation` puts them. Scorers get the same one.
1697
+ */
1698
+ shell: Shell;
1699
+ /** The project's fixtures, as this run reaches them, by name. */
1700
+ fixtures: Readonly<Record<string, FixtureAddress>>;
1039
1701
  /** Contains only resources visible to the AUT/model. */
1040
1702
  workspace: CandidateWorkspace;
1041
1703
  /** Private evaluator capability for trusted AUT adapters; never expose this to the model. */
@@ -1048,8 +1710,11 @@ export type AutAdapter<TMessage = string> = {
1048
1710
  start(options: {
1049
1711
  context: AutContext;
1050
1712
  runtime?: AgentRuntime;
1051
- /** Optional: stream events as they happen. Returning a turn result from `send` is enough for most agents. */
1052
- onEvent: (event: AutEventInput) => void | Promise<void>;
1713
+ /**
1714
+ * Where to record what the agent does, as ATXF. Optional: returning a
1715
+ * turn result from `send` is enough for most agents.
1716
+ */
1717
+ transcript: TranscriptWriter;
1053
1718
  /**
1054
1719
  * Saves a file with the run's results, such as the agent's raw log,
1055
1720
  * whether or not its sandbox is kept. `name` is a relative path of
@@ -1098,19 +1763,15 @@ export type AgentStep = {
1098
1763
  kind: 'agent';
1099
1764
  expectation: JsonObject;
1100
1765
  };
1766
+ /** One user step and what the agent did in answer to it. */
1101
1767
  export type TurnView = {
1102
1768
  userStepIndex: number;
1103
- events: readonly (AutEvent & {
1104
- source: 'aut';
1105
- })[];
1106
- assistantMessages: readonly (Extract<AutEvent, {
1107
- kind: 'message';
1108
- }> & {
1109
- role: 'assistant';
1110
- source: 'aut';
1111
- })[];
1769
+ /** The transcript records of this turn, on the active path, in order. */
1770
+ records: readonly TreeRecord[];
1771
+ assistantMessages: readonly AssistantMessage[];
1112
1772
  toolCalls: readonly {
1113
- eventIndex: number;
1773
+ /** The assistant message holding the call. */
1774
+ messageId: string;
1114
1775
  id: string;
1115
1776
  name: string;
1116
1777
  arguments: JsonValue;
@@ -1136,11 +1797,25 @@ export declare function expectToolCall(expected: ExpectToolCallStep['expected'])
1136
1797
  */
1137
1798
  export declare function user(message: UserStep['message']): UserStep;
1138
1799
  export declare function agent(expectation: JsonObject): AgentStep;
1800
+ /**
1801
+ * What a judge saw and said. The built-in `judge()` records all of it; a
1802
+ * predicate that calls a model itself can report `model`, `prompt` and
1803
+ * `reply` so the dashboard shows them the same way.
1804
+ */
1139
1805
  export type JudgeRunInfo = {
1140
1806
  agent?: AutIdentity;
1807
+ /** The model the judge reported using, as `provider/id`. */
1808
+ model?: string;
1809
+ /** Tokens the judge used: never counted in the agent's `tokens`. */
1141
1810
  usage?: Usage;
1142
- /** Judge-agent observations; never attributed to the AUT trajectory. */
1143
- events?: JsonValue[];
1811
+ /** The exact prompt the judge received. */
1812
+ prompt?: string;
1813
+ /** Its reply, as text or JSON. */
1814
+ reply?: JsonValue;
1815
+ /** 2 when its first reply was not in the format asked for and it was asked again. */
1816
+ attempts?: number;
1817
+ /** The judge's own session, as ATXF; never part of the agent's transcript. */
1818
+ transcript?: Transcript;
1144
1819
  };
1145
1820
  /** A scorer's "does not apply" result; see `skip()`. */
1146
1821
  export type SkippedScore = {
@@ -1148,7 +1823,8 @@ export type SkippedScore = {
1148
1823
  reason: string;
1149
1824
  };
1150
1825
  export type ScoreValue<Evidence = unknown> = number | SkippedScore | {
1151
- value: number;
1826
+ /** From 0 to 1. Without it, the weighted mean of `criteria`. */
1827
+ value?: number;
1152
1828
  passed?: boolean;
1153
1829
  explanation?: string;
1154
1830
  /**
@@ -1156,7 +1832,12 @@ export type ScoreValue<Evidence = unknown> = number | SkippedScore | {
1156
1832
  * evidence reaches later scorers through `checkpoint(rule)`.
1157
1833
  */
1158
1834
  evidence?: Evidence;
1159
- /** Judge-agent evidence, never inferred from AUT usage. */
1835
+ /**
1836
+ * Per-criterion results, each shown on its own; see `CriterionResult`.
1837
+ * Return `{ name, reached: false }` for a check that never ran.
1838
+ */
1839
+ criteria?: CriterionInput[];
1840
+ /** What a model-backed scorer saw and said; never counted as AUT usage. */
1160
1841
  judge?: JudgeRunInfo;
1161
1842
  };
1162
1843
  /**
@@ -1169,8 +1850,15 @@ export type ScoreResult = {
1169
1850
  kind: 'predicate' | 'judge';
1170
1851
  value?: number;
1171
1852
  passed?: boolean;
1853
+ /** The pass mark the value was held to (1 unless the rule set `passAt`). */
1854
+ passAt?: number;
1172
1855
  explanation?: string;
1173
1856
  evidence?: JsonValue;
1857
+ /** A `choices` judge's answer, such as `B`. */
1858
+ choice?: string;
1859
+ criteria?: CriterionResult[];
1860
+ /** Files its scorer saved with `attach()`, by name. */
1861
+ attachments?: string[];
1174
1862
  judge?: JudgeRunInfo;
1175
1863
  durationMs: number;
1176
1864
  error?: RecordedError;
@@ -1183,14 +1871,21 @@ export type ArtifactView = {
1183
1871
  };
1184
1872
  export type ScoringContext = {
1185
1873
  context: AutContext;
1186
- trajectory: {
1187
- events: readonly TrajectoryEvent[];
1188
- };
1874
+ /**
1875
+ * What the agent did, as an ATXF transcript: all of it for final scorers,
1876
+ * up to this step for checkpoints. `messages(ctx)`, `toolCalls(ctx)` and
1877
+ * `lastReply(ctx)` read it.
1878
+ */
1879
+ transcript: Transcript;
1880
+ /** Sub-agent transcripts the agent kept, by transcript ID. */
1881
+ subagents: Readonly<Record<string, Transcript>>;
1882
+ /** EvalKit's events so far: steps, checkpoints and scorers. */
1883
+ runEvents: readonly RunEvent[];
1189
1884
  artifacts: ArtifactView;
1190
1885
  /** Most recent completed turn; absent if no user message has been sent. */
1191
1886
  turn?: TurnView;
1192
- /** Content of the last assistant message of `turn`. */
1193
- output?: JsonValue;
1887
+ /** The text of the last assistant message of `turn`. */
1888
+ output?: string;
1194
1889
  /** Values of all the scenario's datasets (candidate and evaluator), by dataset ID. */
1195
1890
  data: JsonObject;
1196
1891
  /**
@@ -1225,21 +1920,60 @@ export type CheckpointOutcome<Evidence> = Omit<CheckpointResult, 'evidence'> & {
1225
1920
  export type PredicateScorer<Evidence = unknown> = {
1226
1921
  kind: 'predicate';
1227
1922
  name: string;
1923
+ /** What it checks, in a sentence, shown wherever the scorer is. */
1924
+ description?: string;
1228
1925
  supportsPartial?: boolean;
1229
1926
  /** A numeric result passes when it is at least this value. Default: only 1 passes. */
1230
1927
  passAt?: number;
1928
+ /**
1929
+ * The checks it reports, declared up front so they show before a run.
1930
+ * A declared criterion it leaves out is recorded as not reached; one it
1931
+ * did not declare is an error.
1932
+ */
1933
+ criteria?: JudgeCriterion[];
1231
1934
  run(context: ScoringContext): boolean | ScoreValue<Evidence> | Promise<boolean | ScoreValue<Evidence>>;
1232
1935
  };
1936
+ /** What a judge sees: one named input, read from the run. */
1937
+ export type JudgeInput = (scoring: ScoringContext) => JsonValue | undefined | Promise<JsonValue | undefined>;
1938
+ /**
1939
+ * A rubric-graded scorer. EvalKit builds the prompt from the rubric, the
1940
+ * inputs and the answer format, runs the judge agent, checks its answer
1941
+ * (asking once more if it is not in the format asked for), and records
1942
+ * what it saw and said.
1943
+ */
1233
1944
  export type JudgeRule = {
1234
1945
  kind: 'judge';
1235
1946
  name: string;
1236
1947
  rubric: string;
1948
+ /** What it checks, in a sentence, shown wherever the judge is. */
1949
+ description?: string;
1950
+ /**
1951
+ * The agent that judges, made with `defineAgent()`. Default: `judge` in
1952
+ * evalkit.config.ts. It gets the run's parameters, so a matrix axis can
1953
+ * choose its model.
1954
+ */
1955
+ agent?: AutAdapter;
1956
+ /**
1957
+ * What the judge sees, by name. Default: `conversation` (this turn at a
1958
+ * checkpoint, the whole run in final scoring) and `reply` (the last reply).
1959
+ */
1960
+ inputs?: Readonly<Record<string, JudgeInput>>;
1961
+ /** How it answers. Default `verdict`: a value from 0 to 1 and a reason. */
1962
+ answer: JudgeAnswer;
1963
+ /** A value passes when it is at least this. Default: only 1 passes. */
1964
+ passAt?: number;
1237
1965
  /** Run even when the scenario stopped early or execution failed. */
1238
1966
  supportsPartial?: boolean;
1239
1967
  };
1240
1968
  export type ScoringRule = PredicateScorer | JudgeRule;
1241
1969
  /** A scorer in code. Its `evidence` type carries through to `checkpoint(rule)`. */
1242
- export declare function predicate<Evidence = unknown>(name: string, run: PredicateScorer<Evidence>['run'], options?: Pick<PredicateScorer, 'supportsPartial' | 'passAt'>): PredicateScorer<Evidence>;
1970
+ export declare function predicate<Evidence = unknown>(name: string, run: PredicateScorer<Evidence>['run'], options?: Pick<PredicateScorer, 'supportsPartial' | 'passAt' | 'description'> & {
1971
+ /** The checks it reports by name: `{ 'cannot push': 'the share token gets 403' }` or `{ name: { weight, description } }`. */
1972
+ criteria?: Record<string, string | number | {
1973
+ weight?: number;
1974
+ description?: string;
1975
+ }>;
1976
+ }): PredicateScorer<Evidence>;
1243
1977
  /**
1244
1978
  * A number measured for every run, such as tokens, retries or web searches.
1245
1979
  * Metrics never decide pass or fail; they are averaged per run and shown on
@@ -1267,9 +2001,10 @@ export type MetricResult = {
1267
2001
  builtIn?: true;
1268
2002
  error?: RecordedError;
1269
2003
  };
1270
- export declare function judge(name: string, options: Pick<JudgeRule, 'rubric' | 'supportsPartial'>): JudgeRule;
2004
+ export declare function judge(name: string, options: Omit<JudgeRule, 'kind' | 'name' | 'answer'> & {
2005
+ answer?: JudgeAnswer;
2006
+ }): JudgeRule;
1271
2007
  export type EvalPolicy = {
1272
- timeoutMs?: number;
1273
2008
  /** Stop later transcript steps after a failed checkpoint assertion. Default false. */
1274
2009
  failfast?: boolean;
1275
2010
  };
@@ -1277,8 +2012,6 @@ export type EvalDefinition<TAgent extends AutAdapter = AutAdapter> = {
1277
2012
  id: string;
1278
2013
  name?: string;
1279
2014
  agent: TAgent;
1280
- /** Separate judge agent; its model and tools are never inherited from the AUT. */
1281
- judge?: AutAdapter;
1282
2015
  /** Data and files the scenario uses; each run gets its own copy. */
1283
2016
  datasets?: readonly Dataset[];
1284
2017
  transcript: TranscriptStep[];
@@ -1291,6 +2024,11 @@ export type EvalDefinition<TAgent extends AutAdapter = AutAdapter> = {
1291
2024
  * under identical conditions, to see how often it passes. Default 1.
1292
2025
  */
1293
2026
  repeat?: number;
2027
+ /**
2028
+ * What each run may use before EvalKit stops it: `{ steps: 40, time: '20m' }`.
2029
+ * Over the project's `limits`; a matrix cell's and `--limit` come after.
2030
+ */
2031
+ limits?: LimitsInput;
1294
2032
  /** Any JSON-convertible object; converted when the eval is defined. */
1295
2033
  metadata?: Record<string, unknown>;
1296
2034
  workspace?: EvalWorkspace;
@@ -1308,6 +2046,10 @@ export type EvalWorkspace = {
1308
2046
  ignore?: readonly string[];
1309
2047
  };
1310
2048
  export declare function defineEval<const T extends EvalDefinition>(definition: T): T;
2049
+ /** A judge never grades with the agent it is judging. */
2050
+ export declare function assertJudgesIndependent(definition: Pick<EvalDefinition, 'agent' | 'transcript' | 'scoring'> & {
2051
+ id: string;
2052
+ }, defaultJudge?: AutAdapter): void;
1311
2053
  export type EvalSuite<TEvals extends readonly EvalDefinition[] = readonly EvalDefinition[]> = {
1312
2054
  id: string;
1313
2055
  name?: string;
@@ -1347,9 +2089,11 @@ export type EvalSuiteMetadata = {
1347
2089
  export declare function registerEvals<const TRegistrations extends readonly EvalRegistration[]>(registrations: TRegistrations): EvalRegistry;
1348
2090
  /**
1349
2091
  * How a run ended: `passed` or `failed` by its scores, `errored` when it could
1350
- * not finish (the agent, a dataset or EvalKit failed), `cancelled` by Ctrl+C.
2092
+ * not finish (the agent, a dataset or EvalKit failed), `cancelled` by Ctrl+C,
2093
+ * `limited` when it hit one of its limits (graded by scorers that support
2094
+ * partial work, and never a pass).
1351
2095
  */
1352
- export type RunStatus = 'running' | 'passed' | 'failed' | 'errored' | 'cancelled';
2096
+ export type RunStatus = 'running' | 'passed' | 'failed' | 'errored' | 'cancelled' | 'limited';
1353
2097
  /** Runs launched together as repeats of one configuration (`repeat`). */
1354
2098
  export type Batch = {
1355
2099
  id: string;
@@ -1391,7 +2135,7 @@ export type RunProcess = {
1391
2135
  hostname: string;
1392
2136
  };
1393
2137
  export type RunMetadata = {
1394
- schemaVersion: 6;
2138
+ schemaVersion: 7;
1395
2139
  runId: string;
1396
2140
  runUri: ResourceUri<'run'>;
1397
2141
  evalId: string;
@@ -1412,6 +2156,18 @@ export type RunMetadata = {
1412
2156
  workspaceIgnore?: string[];
1413
2157
  /** The datasets this run used, with content digests. */
1414
2158
  datasets?: RunDataset[];
2159
+ /** The limits in force. */
2160
+ limits?: Limits;
2161
+ /** Where its processes ran; absent for runs on the host. */
2162
+ isolation?: RunIsolation;
2163
+ };
2164
+ /** A run's isolation as its manifest records it: no host paths, no environment. */
2165
+ export type RunIsolation = {
2166
+ kind: 'container';
2167
+ image: string;
2168
+ network: ContainerNetwork;
2169
+ } | {
2170
+ kind: 'sandbox-exec';
1415
2171
  };
1416
2172
  export type RunDataset = {
1417
2173
  id: string;
@@ -1427,13 +2183,19 @@ export type CheckpointResult = {
1427
2183
  status: 'passed' | 'failed' | 'error' | 'skipped';
1428
2184
  value?: number;
1429
2185
  passed?: boolean;
2186
+ passAt?: number;
1430
2187
  explanation?: string;
1431
2188
  evidence?: JsonValue;
2189
+ choice?: string;
2190
+ criteria?: CriterionResult[];
2191
+ /** Files its scorer saved with `attach()`, by name. */
2192
+ attachments?: string[];
1432
2193
  judge?: JudgeRunInfo;
1433
2194
  durationMs?: number;
1434
2195
  error?: RecordedError;
2196
+ /** The tool call it matched: the assistant message holding it, and the call's ID. */
1435
2197
  matchedToolCall?: {
1436
- eventIndex: number;
2198
+ messageId: string;
1437
2199
  id: string;
1438
2200
  };
1439
2201
  };
@@ -1441,13 +2203,17 @@ export type CheckpointResult = {
1441
2203
  * Metrics EvalKit records for every run; scenario metrics may not reuse
1442
2204
  * these names.
1443
2205
  *
1444
- * - `agent time` (ms): from the run's first event to its last one before
1445
- * final scoring.
1446
- * - `tokens`: the sum of `turnTokens(usage)` over the turns that reported
1447
- * usage, cached input included. Absent when no turn reported any.
1448
- * - `tool calls`: the agent's `tool-call` events.
2206
+ * - `agent time` (ms): from the session's start to the end of its last turn.
2207
+ * - `tokens`: uncached input, cache writes and output, summed over the
2208
+ * transcript (`uncachedTokens`). Absent when nothing reported usage.
2209
+ * - `cached tokens`: input tokens read from a prompt cache.
2210
+ * - `output tokens`: output, reasoning included.
2211
+ * - `cache hit rate`: the share of input tokens read from a cache, 0 to 1.
2212
+ * - `steps`: assistant messages, one per model call.
2213
+ * - `tool calls`: tool calls in the transcript.
2214
+ * - `judge tokens`: `tokens` over the judges' transcripts, never the agent's.
1449
2215
  */
1450
- export declare const BUILT_IN_METRICS: readonly ['agent time', 'tokens', 'tool calls'];
2216
+ export declare const BUILT_IN_METRICS: readonly ['agent time', 'tokens', 'cached tokens', 'output tokens', 'cache hit rate', 'steps', 'tool calls', 'judge tokens'];
1451
2217
  export type BuiltInMetricName = (typeof BUILT_IN_METRICS)[number];
1452
2218
  /** A built-in metric's name (suggested by editors), or a scenario's own. */
1453
2219
  export type MetricName = BuiltInMetricName | (string & {});
@@ -1481,10 +2247,17 @@ export type RunSummary = {
1481
2247
  artifacts?: ArtifactEntry[];
1482
2248
  attachments?: AttachmentEntry[];
1483
2249
  error?: RecordedError;
2250
+ /** The limit a `limited` run hit. */
2251
+ limit?: LimitReached;
1484
2252
  };
1485
2253
  export type RunWriter = {
1486
2254
  readonly location: string;
1487
- appendEvent(event: TrajectoryEvent): Promise<void>;
2255
+ /** Appends one of EvalKit's events to `run-events.jsonl`. */
2256
+ appendEvent(event: RunEvent): Promise<void>;
2257
+ /** Appends an ATXF record (the header first) to `transcript.atxf.jsonl`. */
2258
+ appendTranscript(line: Transcript['header'] | Transcript['records'][number]): Promise<void>;
2259
+ /** Writes a sub-agent's whole transcript (JSONL), replacing the one kept. */
2260
+ writeSubagent(id: string, text: string): Promise<void>;
1488
2261
  writeScores(scoring: RunScoring): Promise<void>;
1489
2262
  /** Writes a file below this run's artifact root. */
1490
2263
  writeArtifact(path: string, data: Uint8Array): Promise<void>;
@@ -1506,17 +2279,165 @@ export type RunResult = {
1506
2279
  durationMs?: number;
1507
2280
  scoring?: RunScoring;
1508
2281
  error?: RecordedError;
2282
+ /** The limit a `limited` run hit. */
2283
+ limit?: LimitReached;
1509
2284
  };
1510
2285
  export declare function recordError(error: unknown): RecordedError;
2286
+ /** Messages on the active path of what the agent did, optionally of one role. */
2287
+ export declare function messages(scoring: Pick<ScoringContext, 'transcript'>, role?: MessageRecord['role']): Message[];
2288
+ /** A message as scorers see it: who said it and its text, with the ATXF record for the rest. */
2289
+ export type Message = {
2290
+ id: string;
2291
+ role: MessageRecord['role'];
2292
+ /** Its text blocks, joined; tool calls and images are left out. */
2293
+ text: string;
2294
+ time: string;
2295
+ record: MessageRecord;
2296
+ };
2297
+ /** The agent's tool calls, in order, each with its result when recorded; optionally of one tool. */
2298
+ export declare function toolCalls(scoring: Pick<ScoringContext, 'transcript'>, name?: string): ToolCall[];
2299
+ /** The text of the agent's last reply, or `''`. */
2300
+ export declare function lastReply(scoring: Pick<ScoringContext, 'transcript'>): string;
2301
+ /** Everything the agent's transcript reported using; undefined when nothing reported usage. */
2302
+ export declare function usage(scoring: Pick<ScoringContext, 'transcript'>): Usage | undefined;
2303
+ /**
2304
+ * What the model saw at the end of the agent's transcript, rebuilt by ATXF
2305
+ * (compactions and context edits applied): its instructions, tools and
2306
+ * messages.
2307
+ */
2308
+ export declare function modelContext(scoring: Pick<ScoringContext, 'transcript'>): ModelContext$1;
1511
2309
  //#endregion
1512
- //#region ../agents/src/index.d.ts
1513
- type PiAutOptions = {
2310
+ //#region ../agents/src/harness.d.ts
2311
+ /** Options every coding-agent harness takes. */
2312
+ type HarnessOptions = {
2313
+ /** The CLI to run; defaults to the harness's own name (`pi`, `codex`, …). */
1514
2314
  command?: string;
1515
- /** Additional non-secret Pi arguments, such as an explicit model selection. */
1516
- args?: string[];
2315
+ /**
2316
+ * The model, in the CLI's own syntax (`--model`), or a function of the
2317
+ * run's parameters for a matrix: `({ model }) => String(model)`.
2318
+ */
2319
+ model?: string | ((parameters: JsonObject) => string | undefined);
2320
+ /** More arguments for every turn, after EvalKit's own. */
2321
+ args?: readonly string[];
2322
+ /** Environment variables for the CLI, such as an API key or proxy settings. */
2323
+ env?: Readonly<Record<string, string>>;
2324
+ /**
2325
+ * Which config the CLI reads. `'private'` (the default) points it at a
2326
+ * new, empty config directory in the run's private home, so the person's
2327
+ * extensions, skills, instructions and logins never reach the agent and
2328
+ * every run starts the same; give it what it needs with `configFiles`
2329
+ * and `env`. `'user'` uses the person's own config, which isolation
2330
+ * usually hides: allow it with `sandboxExec({ read })`.
2331
+ */
2332
+ config?: 'private' | 'user';
2333
+ /**
2334
+ * Files to write into the private config directory before the first
2335
+ * turn, by path relative to it (`'auth.json'`), such as a provider's
2336
+ * settings. The agent can read them, so prefer credentials it cannot
2337
+ * use elsewhere, or a proxy that adds them.
2338
+ */
2339
+ configFiles?: Readonly<Record<string, string | Uint8Array>>;
2340
+ };
2341
+ /** One turn's command line. */
2342
+ type HarnessTurn = {
2343
+ /** The CLI, as configured. */
2344
+ command: string;
2345
+ /** The model for this run, if one was chosen. */
2346
+ model: string | undefined;
2347
+ /** The private config directory, or undefined with `config: 'user'`. */
2348
+ configDir: string | undefined;
2349
+ /** The run's directory for this harness's own files, as commands see it. */
2350
+ stateDir: string;
2351
+ /** The session to continue, or undefined on the first turn when the CLI picks it. */
2352
+ session: string | undefined;
2353
+ first: boolean;
2354
+ };
2355
+ /** What a harness needs to say about its CLI. */
2356
+ type HarnessSpec = {
2357
+ id: string;
2358
+ name: string;
2359
+ command: string;
2360
+ /** Environment variables that point the CLI at a private config directory. */
2361
+ configEnv(configDir: string): Record<string, string>;
2362
+ /** A session ID to start with, for CLIs that take one. */
2363
+ newSession?(): string;
2364
+ /** The command for one turn, starting with `turn.command`; the message goes on stdin. */
2365
+ argv(turn: HarnessTurn): string[];
2366
+ /** The session ID the CLI printed, for CLIs that pick their own. */
2367
+ sessionFromOutput?(stdout: string): string | undefined;
2368
+ /**
2369
+ * A shell command that copies the session's native record to `target`;
2370
+ * it runs where the CLI ran, with the same environment.
2371
+ */
2372
+ saveSession(options: HarnessTurn & {
2373
+ session: string;
2374
+ target: string;
2375
+ }): string[];
2376
+ /** The native record as an ATXF transcript. */
2377
+ toAtxf(text: string): Transcript$1;
2378
+ };
2379
+ /**
2380
+ * An adapter that runs a coding-agent CLI through `context.shell`, one
2381
+ * non-interactive invocation per user message, continuing one session.
2382
+ * After each turn it imports the CLI's own session record through ATXF,
2383
+ * so the run's transcript has every message, tool call and token count.
2384
+ */
2385
+ export declare function harnessAgent(spec: HarnessSpec, options: HarnessOptions): AutAdapter;
2386
+ //#endregion
2387
+ //#region ../agents/src/pi.d.ts
2388
+ type PiOptions = HarnessOptions & {
2389
+ /** False runs Pi without tools (`--no-tools`), such as for a judge. */
2390
+ tools?: boolean;
2391
+ /** Skill files or directories to load (`--skill`), as paths commands see. */
2392
+ skills?: readonly string[];
2393
+ /** Text appended to Pi's system prompt (`--append-system-prompt`). */
2394
+ appendSystemPrompt?: string;
2395
+ };
2396
+ /**
2397
+ * Pi (https://pi.dev) as the agent under test: `pi --print` with its own
2398
+ * tools, system prompt and context handling, one session per run. Its
2399
+ * session file becomes the run's transcript.
2400
+ */
2401
+ export declare function piAgent(options?: PiOptions): AutAdapter;
2402
+ //#endregion
2403
+ //#region ../agents/src/codex.d.ts
2404
+ type CodexOptions = HarnessOptions;
2405
+ /**
2406
+ * Codex as the agent under test: `codex exec` with approvals and its own
2407
+ * sandbox off (EvalKit's isolation is the sandbox; Codex's cannot nest in
2408
+ * `sandboxExec()`), one session per run. Its rollout file becomes the
2409
+ * run's transcript.
2410
+ */
2411
+ export declare function codexAgent(options?: CodexOptions): AutAdapter;
2412
+ //#endregion
2413
+ //#region ../agents/src/opencode.d.ts
2414
+ type OpencodeOptions = HarnessOptions & {
2415
+ /** The opencode agent to run (`--agent`), such as `build`. */
2416
+ agent?: string;
2417
+ };
2418
+ /**
2419
+ * opencode as the agent under test: `opencode run --standalone`, with a
2420
+ * private server per command and permissions auto-approved, one session
2421
+ * per run. Its session export becomes the run's transcript.
2422
+ *
2423
+ * With `config: 'private'`, opencode's config, data and state directories
2424
+ * (`XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`) are in the config
2425
+ * directory: put `config/opencode/opencode.json` and
2426
+ * `data/opencode/auth.json` in `configFiles`.
2427
+ */
2428
+ export declare function opencodeAgent(options?: OpencodeOptions): AutAdapter;
2429
+ //#endregion
2430
+ //#region ../agents/src/claude-code.d.ts
2431
+ type ClaudeCodeOptions = HarnessOptions & {
2432
+ /** Text appended to Claude Code's system prompt (`--append-system-prompt`). */
2433
+ appendSystemPrompt?: string;
1517
2434
  };
1518
- /** A local, one-prompt-per-turn AUT backed by Pi's non-interactive print mode. */
1519
- export declare function piAgent(options?: PiAutOptions): AutAdapter;
2435
+ /**
2436
+ * Claude Code as the agent under test: `claude -p` with every tool allowed
2437
+ * (EvalKit's isolation is the sandbox), one session per run. Its session
2438
+ * file becomes the run's transcript.
2439
+ */
2440
+ export declare function claudeCodeAgent(options?: ClaudeCodeOptions): AutAdapter;
1520
2441
  //#endregion
1521
- export type { AttachmentLimits, DefinitionSite, EvalMatrix, EvalMatrixCell, EvalkitConfig, KeepSandboxes, MatrixSelection, ShareConfig, ShareHeaders, Usage };
2442
+ export type { ATXF_VERSION, AssistantBlock, AssistantMessage, AttachmentLimits, ClaudeCodeOptions, CodexOptions, CriteriaOptions, CriterionInput, CriterionResult, DefinitionSite, EntryRecord, EvalMatrix, EvalMatrixCell, EvalkitConfig, HarnessOptions, HarnessSpec, HarnessTurn, JudgeAnswer, JudgeChoice, JudgeCriterion, KeepSandboxes, LIMIT_KINDS, LIMIT_PARAMETER_PREFIX, LimitKind, LimitReached, Limits, LimitsInput, MatrixSelection, MessageRecord, ModelContext, ModelRef, OpencodeOptions, PairedToolCall, PiOptions, ReachedCriterion, ShareConfig, ShareHeaders, ToolCall, ToolCallBlock, ToolMessage, Transcript, TranscriptHeader, TreeRecord, UnreachedCriterion, Usage, UsageInput, UserBlock, UserContent, activePath, callsIn, contentText, emptyTranscript, formatLimit, isTreeRecord, limitsFromParameters, modelName, parseDuration, parseLimitFlag, parseLimits, parseModel, resolveLimits, toolResultValue, transcriptMessages, transcriptReply, transcriptToolCalls };
1522
2443
  //# sourceMappingURL=index.d.mts.map