@vitest-evals/core 0.13.1 → 0.15.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.mjs CHANGED
@@ -16,7 +16,7 @@ var JsonValueSchema = z.lazy(
16
16
  var JsonObjectSchema = z.record(z.string(), JsonValueSchema);
17
17
 
18
18
  // src/harness/index.ts
19
- import { z as z3 } from "zod";
19
+ import { z as z5 } from "zod";
20
20
 
21
21
  // src/schema-utils.ts
22
22
  import { z as z2 } from "zod";
@@ -47,10 +47,232 @@ function isRecord(value) {
47
47
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
48
48
  }
49
49
 
50
+ // src/harness/errors.ts
51
+ import { z as z3 } from "zod";
52
+ var NormalizedErrorSchema = z3.object({
53
+ message: z3.string(),
54
+ type: z3.string().optional()
55
+ }).catchall(JsonValueSchema);
56
+
57
+ // src/harness/transcript.ts
58
+ import { z as z4 } from "zod";
59
+ var TranscriptToolCallEventSchema = z4.object({
60
+ type: z4.literal("tool_call"),
61
+ id: z4.string(),
62
+ name: z4.string(),
63
+ arguments: JsonObjectSchema.optional(),
64
+ startedAt: z4.string().optional(),
65
+ finishedAt: z4.string().optional(),
66
+ durationMs: FiniteNumberSchema.optional(),
67
+ metadata: JsonObjectSchema.optional()
68
+ }).strict();
69
+ var TranscriptMessageEventSchema = z4.object({
70
+ type: z4.literal("message"),
71
+ role: z4.enum(["system", "user", "assistant"]),
72
+ content: JsonValueSchema.optional(),
73
+ metadata: JsonObjectSchema.optional()
74
+ }).strict();
75
+ var TranscriptToolResultEventSchema = z4.object({
76
+ type: z4.literal("tool_result"),
77
+ toolCallId: z4.string(),
78
+ name: z4.string().optional(),
79
+ content: JsonValueSchema.optional(),
80
+ error: NormalizedErrorSchema.optional(),
81
+ startedAt: z4.string().optional(),
82
+ finishedAt: z4.string().optional(),
83
+ durationMs: FiniteNumberSchema.optional(),
84
+ metadata: JsonObjectSchema.optional()
85
+ }).strict();
86
+ var TranscriptEventSchema = z4.discriminatedUnion("type", [
87
+ TranscriptMessageEventSchema,
88
+ TranscriptToolCallEventSchema,
89
+ TranscriptToolResultEventSchema
90
+ ]);
91
+ function messagesToTranscriptEvents(messages) {
92
+ const events = [];
93
+ for (const [messageIndex, message] of messages.entries()) {
94
+ if (message.role === "tool") {
95
+ const partEvents2 = contentPartEvents(message);
96
+ if (partEvents2) {
97
+ events.push(...partEvents2);
98
+ continue;
99
+ }
100
+ if (!hasTopLevelToolCallId(message)) {
101
+ throw new TypeError("Tool result messages must include toolCallId.");
102
+ }
103
+ events.push(toolResultMessageEvent(message, message.toolCallId));
104
+ continue;
105
+ }
106
+ const partEvents = message.role === "assistant" ? contentPartEvents(message) : void 0;
107
+ const partEventsHaveToolCalls = partEvents?.some(
108
+ (event) => event.type === "tool_call"
109
+ );
110
+ if (partEvents) {
111
+ events.push(...partEvents);
112
+ } else if (message.content !== void 0) {
113
+ events.push({
114
+ type: "message",
115
+ role: message.role,
116
+ content: message.content,
117
+ ...message.metadata ? { metadata: message.metadata } : {}
118
+ });
119
+ }
120
+ if (message.role !== "assistant") {
121
+ continue;
122
+ }
123
+ if (partEventsHaveToolCalls) {
124
+ if ((message.toolCalls ?? []).length > 0) {
125
+ throw new TypeError(
126
+ "Assistant messages must not mix tool-call content parts with toolCalls."
127
+ );
128
+ }
129
+ continue;
130
+ }
131
+ const messageToolCalls = message.toolCalls ?? [];
132
+ for (const [toolIndex, toolCall] of messageToolCalls.entries()) {
133
+ const rawToolCall = toolCall;
134
+ if (Object.prototype.hasOwnProperty.call(rawToolCall, "result") || Object.prototype.hasOwnProperty.call(rawToolCall, "error")) {
135
+ throw new TypeError(
136
+ "Assistant tool calls must use separate tool result messages."
137
+ );
138
+ }
139
+ if (typeof toolCall.name !== "string" || toolCall.name.length === 0) {
140
+ throw new TypeError("Assistant tool calls must include name.");
141
+ }
142
+ const id = toolCall.id ?? `message-${messageIndex}:tool-call-${toolIndex}`;
143
+ events.push({
144
+ type: "tool_call",
145
+ id,
146
+ name: toolCall.name,
147
+ ...normalizeToolCallArguments(toolCall.arguments),
148
+ ...toolCall.startedAt ? { startedAt: toolCall.startedAt } : {},
149
+ ...toolCall.finishedAt ? { finishedAt: toolCall.finishedAt } : {},
150
+ ...toolCall.durationMs !== void 0 ? { durationMs: toolCall.durationMs } : {},
151
+ ...toolCall.metadata ? { metadata: toolCall.metadata } : {}
152
+ });
153
+ }
154
+ }
155
+ return events;
156
+ }
157
+ function contentPartEvents(message) {
158
+ if (!Array.isArray(message.content)) {
159
+ return void 0;
160
+ }
161
+ const events = [];
162
+ for (const part of message.content) {
163
+ if (!isJsonObject2(part) || typeof part.type !== "string") {
164
+ continue;
165
+ }
166
+ if (part.type === "text" && typeof part.text === "string") {
167
+ if (message.role === "tool") {
168
+ throw new TypeError("Text content parts require message role.");
169
+ }
170
+ events.push({
171
+ type: "message",
172
+ role: message.role,
173
+ content: part.text,
174
+ ...recordMetadata(message.metadata)
175
+ });
176
+ continue;
177
+ }
178
+ if (part.type === "tool-call") {
179
+ if (message.role !== "assistant" || typeof part.toolCallId !== "string" || typeof part.toolName !== "string") {
180
+ throw new TypeError(
181
+ "Tool-call content parts require assistant role, toolCallId, and toolName."
182
+ );
183
+ }
184
+ events.push({
185
+ type: "tool_call",
186
+ id: part.toolCallId,
187
+ name: part.toolName,
188
+ ...normalizeToolCallArguments(part.input),
189
+ ...jsonTimeFields(part),
190
+ ...jsonMetadata(part.metadata)
191
+ });
192
+ continue;
193
+ }
194
+ if (part.type === "tool-result") {
195
+ if (message.role !== "tool" || typeof part.toolCallId !== "string") {
196
+ throw new TypeError(
197
+ "Tool-result content parts require tool role and toolCallId."
198
+ );
199
+ }
200
+ if (hasTopLevelToolCallId(message)) {
201
+ throw new TypeError(
202
+ "Tool-result content parts must not include top-level toolCallId."
203
+ );
204
+ }
205
+ events.push({
206
+ type: "tool_result",
207
+ toolCallId: part.toolCallId,
208
+ ...typeof part.toolName === "string" ? { name: part.toolName } : {},
209
+ ...part.output !== void 0 ? { content: part.output } : {},
210
+ ...part.error ? { error: part.error } : {},
211
+ ...jsonTimeFields(part),
212
+ ...jsonMetadata(part.metadata)
213
+ });
214
+ continue;
215
+ }
216
+ throw new TypeError(
217
+ "Message content parts must use the harness message contract."
218
+ );
219
+ }
220
+ return events.length > 0 ? events : void 0;
221
+ }
222
+ function toolResultMessageEvent(message, toolCallId) {
223
+ return {
224
+ type: "tool_result",
225
+ toolCallId,
226
+ ...message.name ? { name: message.name } : {},
227
+ ...message.content !== void 0 ? { content: message.content } : {},
228
+ ...message.error ? { error: message.error } : {},
229
+ ...timeFields(message),
230
+ ...recordMetadata(message.metadata)
231
+ };
232
+ }
233
+ function hasTopLevelToolCallId(message) {
234
+ return typeof message.toolCallId === "string";
235
+ }
236
+ function timeFields(input) {
237
+ return {
238
+ ...input.startedAt ? { startedAt: input.startedAt } : {},
239
+ ...input.finishedAt ? { finishedAt: input.finishedAt } : {},
240
+ ...input.durationMs !== void 0 ? { durationMs: input.durationMs } : {}
241
+ };
242
+ }
243
+ function recordMetadata(metadata) {
244
+ return metadata ? { metadata } : {};
245
+ }
246
+ function jsonTimeFields(input) {
247
+ return {
248
+ ...typeof input.startedAt === "string" ? { startedAt: input.startedAt } : {},
249
+ ...typeof input.finishedAt === "string" ? { finishedAt: input.finishedAt } : {},
250
+ ...typeof input.durationMs === "number" ? { durationMs: input.durationMs } : {}
251
+ };
252
+ }
253
+ function jsonMetadata(value) {
254
+ return isJsonObject2(value) ? { metadata: value } : {};
255
+ }
256
+ function normalizeToolCallArguments(value) {
257
+ return value && typeof value === "object" && !Array.isArray(value) ? { arguments: value } : {};
258
+ }
259
+ function isJsonObject2(value) {
260
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
261
+ }
262
+ function isMessageEvent(event) {
263
+ return event.type === "message";
264
+ }
265
+ function isToolCallEvent(event) {
266
+ return event.type === "tool_call";
267
+ }
268
+ function isToolResultEvent(event) {
269
+ return event.type === "tool_result";
270
+ }
271
+
50
272
  // src/harness/index.ts
51
- var UsageSummarySchema = z3.object({
52
- provider: z3.string().optional(),
53
- model: z3.string().optional(),
273
+ var UsageSummarySchema = z5.object({
274
+ provider: z5.string().optional(),
275
+ model: z5.string().optional(),
54
276
  inputTokens: FiniteNumberSchema.optional(),
55
277
  outputTokens: FiniteNumberSchema.optional(),
56
278
  reasoningTokens: FiniteNumberSchema.optional(),
@@ -59,81 +281,105 @@ var UsageSummarySchema = z3.object({
59
281
  retries: FiniteNumberSchema.optional(),
60
282
  metadata: JsonObjectSchema.optional()
61
283
  }).strict();
62
- var TimingSummarySchema = z3.object({
284
+ var TimingSummarySchema = z5.object({
63
285
  totalMs: FiniteNumberSchema.optional(),
64
286
  metadata: JsonObjectSchema.optional()
65
287
  }).strict();
66
- var NormalizedErrorSchema = z3.object({
67
- message: z3.string(),
68
- type: z3.string().optional()
69
- }).catchall(JsonValueSchema);
70
- var ToolCallRecordSchema = z3.object({
71
- id: z3.string().optional(),
72
- name: z3.string(),
73
- arguments: JsonObjectSchema.optional(),
74
- result: JsonValueSchema.optional(),
75
- error: NormalizedErrorSchema.optional(),
76
- startedAt: z3.string().optional(),
77
- finishedAt: z3.string().optional(),
78
- durationMs: FiniteNumberSchema.optional(),
79
- metadata: JsonObjectSchema.optional()
80
- }).strict();
81
- var NormalizedMessageSchema = z3.object({
82
- role: z3.enum(["system", "user", "assistant", "tool"]),
83
- content: JsonValueSchema.optional(),
84
- toolCalls: z3.array(ToolCallRecordSchema).optional(),
85
- metadata: JsonObjectSchema.optional()
288
+ var ToolCallBaseSchema = z5.object({
289
+ name: z5.string(),
290
+ arguments: JsonObjectSchema.optional()
86
291
  }).strict();
87
- var NormalizedSessionSchema = z3.object({
88
- messages: z3.array(NormalizedMessageSchema).default([]),
89
- provider: z3.string().optional(),
90
- model: z3.string().optional(),
292
+ var ToolCallSchema = z5.discriminatedUnion("status", [
293
+ ToolCallBaseSchema.extend({
294
+ status: z5.literal("pending")
295
+ }).strict(),
296
+ ToolCallBaseSchema.extend({
297
+ status: z5.literal("ok"),
298
+ result: JsonValueSchema.optional()
299
+ }).strict(),
300
+ ToolCallBaseSchema.extend({
301
+ status: z5.literal("error"),
302
+ error: NormalizedErrorSchema
303
+ }).strict()
304
+ ]);
305
+ var NormalizedSessionSchema = z5.object({
306
+ events: z5.array(TranscriptEventSchema),
307
+ provider: z5.string().optional(),
308
+ model: z5.string().optional(),
91
309
  metadata: JsonObjectSchema.optional()
92
310
  }).strict();
93
311
  var NormalizedSpanAttributesSchema = JsonObjectSchema;
94
- var NormalizedSpanEventSchema = z3.object({
95
- name: z3.string(),
96
- timestamp: z3.string().optional(),
312
+ var NormalizedSpanEventSchema = z5.object({
313
+ name: z5.string(),
314
+ timestamp: z5.string().optional(),
97
315
  attributes: NormalizedSpanAttributesSchema.optional()
98
316
  }).strict();
99
- var NormalizedSpanSchema = z3.object({
100
- id: z3.string().optional(),
101
- traceId: z3.string().optional(),
102
- parentId: z3.string().optional(),
103
- name: z3.string(),
104
- kind: z3.enum(["run", "agent", "model", "tool", "guardrail", "handoff", "custom"]).optional(),
105
- startedAt: z3.string().optional(),
106
- finishedAt: z3.string().optional(),
317
+ var NormalizedSpanSchema = z5.object({
318
+ id: z5.string().optional(),
319
+ traceId: z5.string().optional(),
320
+ parentId: z5.string().optional(),
321
+ name: z5.string(),
322
+ kind: z5.enum(["run", "agent", "model", "tool", "guardrail", "handoff", "custom"]).optional(),
323
+ startedAt: z5.string().optional(),
324
+ finishedAt: z5.string().optional(),
107
325
  durationMs: FiniteNumberSchema.optional(),
108
- status: z3.enum(["ok", "error"]).optional(),
326
+ status: z5.enum(["ok", "error"]).optional(),
109
327
  error: NormalizedErrorSchema.optional(),
110
328
  attributes: NormalizedSpanAttributesSchema.optional(),
111
- events: z3.array(NormalizedSpanEventSchema).optional()
329
+ events: z5.array(NormalizedSpanEventSchema).optional()
112
330
  }).strict();
113
- var NormalizedTraceSchema = z3.object({
114
- id: z3.string().optional(),
115
- name: z3.string().optional(),
116
- startedAt: z3.string().optional(),
117
- finishedAt: z3.string().optional(),
331
+ var NormalizedTraceSchema = z5.object({
332
+ id: z5.string().optional(),
333
+ name: z5.string().optional(),
334
+ startedAt: z5.string().optional(),
335
+ finishedAt: z5.string().optional(),
118
336
  durationMs: FiniteNumberSchema.optional(),
119
337
  metadata: JsonObjectSchema.optional(),
120
- spans: z3.array(NormalizedSpanSchema).default([])
338
+ spans: z5.array(NormalizedSpanSchema)
121
339
  }).strict();
122
- var HarnessRunSchema = z3.object({
340
+ var HarnessRunSchema = z5.object({
123
341
  output: JsonValueSchema.optional(),
124
342
  session: NormalizedSessionSchema,
125
343
  usage: UsageSummarySchema,
126
344
  timings: TimingSummarySchema.optional(),
127
345
  artifacts: JsonObjectSchema.optional(),
128
- traces: z3.array(NormalizedTraceSchema).optional(),
129
- errors: z3.array(JsonObjectSchema).default([])
346
+ traces: z5.array(NormalizedTraceSchema).optional(),
347
+ errors: z5.array(JsonObjectSchema)
130
348
  }).strict();
131
349
 
132
350
  // src/harness/helpers.ts
133
351
  function toolCalls(source) {
134
- return sessionFrom(source).messages.flatMap(
135
- (message) => message.toolCalls ?? []
136
- );
352
+ const resultsById = /* @__PURE__ */ new Map();
353
+ for (const message of toolResultsFromSource(source)) {
354
+ if (!resultsById.has(message.toolCallId)) {
355
+ resultsById.set(message.toolCallId, message);
356
+ }
357
+ }
358
+ return toolCallsFromSource(source).map((call) => {
359
+ const result = resultsById.get(call.id);
360
+ const normalizedCall = {
361
+ name: call.name,
362
+ ...call.arguments ? { arguments: call.arguments } : {}
363
+ };
364
+ if (!result) {
365
+ return {
366
+ ...normalizedCall,
367
+ status: "pending"
368
+ };
369
+ }
370
+ if (result.error) {
371
+ return {
372
+ ...normalizedCall,
373
+ status: "error",
374
+ error: result.error
375
+ };
376
+ }
377
+ return {
378
+ ...normalizedCall,
379
+ status: "ok",
380
+ ...result.content !== void 0 ? { result: result.content } : {}
381
+ };
382
+ });
137
383
  }
138
384
  function spans(source) {
139
385
  return spansFrom(source);
@@ -150,8 +396,8 @@ function failedSpans(source) {
150
396
  );
151
397
  }
152
398
  function messagesByRole(source, role) {
153
- return sessionFrom(source).messages.filter(
154
- (message) => message.role === role
399
+ return sessionFrom(source).events.filter(
400
+ (event) => event.type === "message" && event.role === role
155
401
  );
156
402
  }
157
403
  function systemMessages(source) {
@@ -167,11 +413,17 @@ function latestAssistantMessageContent(source) {
167
413
  return [...messagesByRoleFromSource(source, "assistant")].reverse().find(hasNonEmptyMessageContent)?.content;
168
414
  }
169
415
  function toolMessages(source) {
170
- return messagesByRoleFromSource(source, "tool");
416
+ return toolResultsFromSource(source);
171
417
  }
172
418
  function sessionFrom(source) {
173
419
  return "session" in source ? source.session : source;
174
420
  }
421
+ function toolResultsFromSource(source) {
422
+ return sessionFrom(source).events.filter(isToolResultEvent);
423
+ }
424
+ function toolCallsFromSource(source) {
425
+ return sessionFrom(source).events.filter(isToolCallEvent);
426
+ }
175
427
  function tracesFrom(source) {
176
428
  if (source === void 0) {
177
429
  return [];
@@ -188,8 +440,8 @@ function isTraceList(source) {
188
440
  return Array.isArray(source);
189
441
  }
190
442
  function messagesByRoleFromSource(source, role) {
191
- return sessionFrom(source).messages.filter(
192
- (message) => message.role === role
443
+ return sessionFrom(source).events.filter(
444
+ (event) => event.type === "message" && event.role === role
193
445
  );
194
446
  }
195
447
  function hasNonEmptyMessageContent(message) {
@@ -197,71 +449,45 @@ function hasNonEmptyMessageContent(message) {
197
449
  }
198
450
 
199
451
  // src/report/metadata.ts
200
- import { z as z4 } from "zod";
201
- var HarnessMetaSchema = z4.object({
202
- name: z4.string().optional(),
452
+ import { z as z6 } from "zod";
453
+ var HarnessMetaSchema = z6.object({
454
+ name: z6.string().optional(),
203
455
  run: HarnessRunSchema.optional()
204
456
  }).strict();
205
- var EvalScoreSchema = z4.object({
206
- name: z4.string().optional(),
457
+ var EvalScoreSchema = z6.object({
458
+ name: z6.string().optional(),
207
459
  score: NullableFiniteNumberSchema,
208
460
  metadata: JsonObjectSchema.optional()
209
461
  }).strict();
210
- var EvalMetaSchema = z4.object({
211
- scores: z4.array(EvalScoreSchema).optional(),
462
+ var EvalMetaSchema = z6.object({
463
+ scores: z6.array(EvalScoreSchema).optional(),
212
464
  avgScore: NullableFiniteNumberSchema,
213
465
  output: JsonValueSchema.optional(),
214
- thresholdFailed: z4.boolean().optional(),
215
- toolCalls: z4.array(ToolCallRecordSchema).optional()
466
+ thresholdFailed: z6.boolean().optional(),
467
+ toolCalls: z6.array(ToolCallSchema).optional()
216
468
  }).strict();
217
- var EvalTaskMetaSchema = z4.object({
469
+ var EvalTaskMetaSchema = z6.object({
218
470
  eval: EvalMetaSchema.optional(),
219
471
  harness: HarnessMetaSchema.optional()
220
472
  }).strict();
221
- var LenientToolCallRecordSchema = ToolCallRecordSchema.strip();
222
- var LenientMessageSchema = NormalizedMessageSchema.extend({
223
- toolCalls: z4.array(LenientToolCallRecordSchema).optional().catch(void 0)
224
- }).strip();
225
- var LenientSessionSchema = NormalizedSessionSchema.extend({
226
- messages: z4.array(LenientMessageSchema).default([]).catch([])
227
- }).strip();
228
- var LenientSpanEventSchema = NormalizedSpanEventSchema.strip();
229
- var LenientSpanSchema = NormalizedSpanSchema.extend({
230
- events: z4.array(LenientSpanEventSchema).optional().catch(void 0)
231
- }).strip();
232
- var LenientTraceSchema = NormalizedTraceSchema.extend({
233
- spans: z4.array(LenientSpanSchema).default([]).catch([])
234
- }).strip();
235
- var LenientHarnessRunSchema = HarnessRunSchema.extend({
236
- session: LenientSessionSchema,
237
- usage: UsageSummarySchema.strip().default({}),
238
- timings: TimingSummarySchema.strip().optional(),
239
- traces: z4.array(LenientTraceSchema).optional().catch(void 0)
240
- }).strip();
241
- var LenientHarnessMetaSchema = HarnessMetaSchema.extend({
242
- run: LenientHarnessRunSchema.optional().catch(void 0)
243
- }).strip();
244
- var LenientEvalScoreSchema = EvalScoreSchema.strip();
245
- var LenientEvalMetaSchema = EvalMetaSchema.extend({
246
- scores: z4.array(LenientEvalScoreSchema).optional().catch(void 0),
247
- toolCalls: z4.array(LenientToolCallRecordSchema).optional().catch(void 0)
248
- }).strip();
249
473
  function readEvalTaskMeta(input) {
250
474
  if (!isJsonObject(input)) {
251
475
  return void 0;
252
476
  }
253
- const evalResult = LenientEvalMetaSchema.safeParse(input.eval);
254
- const harnessResult = LenientHarnessMetaSchema.safeParse(input.harness);
255
477
  const meta = {
256
- ...evalResult.success && input.eval !== void 0 ? { eval: evalResult.data } : {},
257
- ...harnessResult.success && input.harness !== void 0 ? { harness: harnessResult.data } : {}
478
+ ...input.eval !== void 0 ? { eval: input.eval } : {},
479
+ ...input.harness !== void 0 ? { harness: input.harness } : {}
258
480
  };
259
- return meta.eval || meta.harness ? meta : void 0;
481
+ if (!("eval" in meta) && !("harness" in meta)) {
482
+ return void 0;
483
+ }
484
+ const result = EvalTaskMetaSchema.safeParse(meta);
485
+ return result.success ? result.data : void 0;
260
486
  }
261
487
 
262
488
  // src/report/vitest-json.ts
263
- import { z as z5 } from "zod";
264
- var VitestJsonStatusSchema = z5.enum([
489
+ import { z as z7 } from "zod";
490
+ var VitestJsonStatusSchema = z7.enum([
265
491
  "passed",
266
492
  "failed",
267
493
  "skipped",
@@ -269,53 +495,53 @@ var VitestJsonStatusSchema = z5.enum([
269
495
  "todo",
270
496
  "disabled"
271
497
  ]);
272
- var VitestJsonLocationSchema = z5.object({
498
+ var VitestJsonLocationSchema = z7.object({
273
499
  line: FiniteNumberSchema,
274
500
  column: FiniteNumberSchema
275
501
  }).passthrough();
276
- var VitestJsonAssertionSchema = z5.object({
277
- ancestorTitles: z5.array(z5.string()).default([]),
278
- fullName: z5.string(),
502
+ var VitestJsonAssertionSchema = z7.object({
503
+ ancestorTitles: z7.array(z7.string()).default([]),
504
+ fullName: z7.string(),
279
505
  status: VitestJsonStatusSchema,
280
- title: z5.string(),
281
- meta: z5.unknown().optional(),
506
+ title: z7.string(),
507
+ meta: z7.unknown().optional(),
282
508
  duration: FiniteNumberSchema.nullable().optional(),
283
- failureMessages: z5.array(z5.string()).nullable().optional(),
509
+ failureMessages: z7.array(z7.string()).nullable().optional(),
284
510
  location: VitestJsonLocationSchema.nullable().optional(),
285
- tags: z5.array(z5.string()).optional()
511
+ tags: z7.array(z7.string()).optional()
286
512
  }).passthrough();
287
- var VitestJsonFileSchema = z5.object({
288
- message: z5.string(),
289
- name: z5.string(),
290
- status: z5.enum(["failed", "passed"]),
513
+ var VitestJsonFileSchema = z7.object({
514
+ message: z7.string(),
515
+ name: z7.string(),
516
+ status: z7.enum(["failed", "passed"]),
291
517
  startTime: OptionalFiniteNumberSchema,
292
518
  endTime: OptionalFiniteNumberSchema,
293
- assertionResults: z5.array(VitestJsonAssertionSchema).default([])
519
+ assertionResults: z7.array(VitestJsonAssertionSchema).default([])
294
520
  }).passthrough();
295
- var VitestJsonReportSchema = z5.object({
521
+ var VitestJsonReportSchema = z7.object({
296
522
  numFailedTests: FiniteNumberSchema,
297
523
  numPassedTests: FiniteNumberSchema,
298
524
  numPendingTests: FiniteNumberSchema,
299
525
  numTodoTests: FiniteNumberSchema,
300
526
  numTotalTests: FiniteNumberSchema,
301
527
  startTime: FiniteNumberSchema,
302
- success: z5.boolean(),
303
- testResults: z5.array(VitestJsonFileSchema).default([])
528
+ success: z7.boolean(),
529
+ testResults: z7.array(VitestJsonFileSchema).default([])
304
530
  }).passthrough();
305
531
  function parseVitestJsonReport(input) {
306
532
  return parseWithSchema(VitestJsonReportSchema, input, "Vitest JSON report");
307
533
  }
308
534
 
309
535
  // src/report/workspace.ts
310
- import { z as z6 } from "zod";
536
+ import { z as z8 } from "zod";
311
537
  var REPORT_WORKSPACE_SCHEMA_VERSION = 1;
312
- var ReportRunSchema = z6.object({
313
- id: z6.string(),
314
- source: z6.string().optional(),
315
- status: z6.enum(["passed", "failed"]),
538
+ var ReportRunSchema = z8.object({
539
+ id: z8.string(),
540
+ source: z8.string().optional(),
541
+ status: z8.enum(["passed", "failed"]),
316
542
  startedAt: FiniteNumberSchema.optional(),
317
543
  durationMs: FiniteNumberSchema.optional(),
318
- totals: z6.object({
544
+ totals: z8.object({
319
545
  total: FiniteNumberSchema,
320
546
  passed: FiniteNumberSchema,
321
547
  failed: FiniteNumberSchema,
@@ -325,28 +551,28 @@ var ReportRunSchema = z6.object({
325
551
  evalFailed: FiniteNumberSchema
326
552
  })
327
553
  }).strict();
328
- var ReportCaseSchema = z6.object({
329
- id: z6.string(),
330
- runId: z6.string(),
331
- source: z6.string().optional(),
332
- file: z6.string(),
333
- displayFile: z6.string(),
334
- title: z6.string(),
335
- fullName: z6.string(),
336
- ancestorTitles: z6.array(z6.string()),
337
- tags: z6.array(z6.string()).optional(),
338
- displayName: z6.string(),
554
+ var ReportCaseSchema = z8.object({
555
+ id: z8.string(),
556
+ runId: z8.string(),
557
+ source: z8.string().optional(),
558
+ file: z8.string(),
559
+ displayFile: z8.string(),
560
+ title: z8.string(),
561
+ fullName: z8.string(),
562
+ ancestorTitles: z8.array(z8.string()),
563
+ tags: z8.array(z8.string()).optional(),
564
+ displayName: z8.string(),
339
565
  status: VitestJsonStatusSchema,
340
566
  durationMs: FiniteNumberSchema.optional(),
341
567
  location: VitestJsonLocationSchema.optional(),
342
- failureMessages: z6.array(z6.string()).default([]),
568
+ failureMessages: z8.array(z8.string()).default([]),
343
569
  eval: EvalMetaSchema.optional(),
344
570
  harness: HarnessMetaSchema.optional()
345
571
  }).strict();
346
- var ReportWorkspaceSchema = z6.object({
347
- schemaVersion: z6.literal(REPORT_WORKSPACE_SCHEMA_VERSION),
348
- runs: z6.array(ReportRunSchema),
349
- cases: z6.array(ReportCaseSchema)
572
+ var ReportWorkspaceSchema = z8.object({
573
+ schemaVersion: z8.literal(REPORT_WORKSPACE_SCHEMA_VERSION),
574
+ runs: z8.array(ReportRunSchema),
575
+ cases: z8.array(ReportCaseSchema)
350
576
  }).strict();
351
577
  function parseReportWorkspace(input) {
352
578
  return parseWithSchema(ReportWorkspaceSchema, input, "report workspace");
@@ -365,6 +591,11 @@ function collectReportWorkspace(input, options = {}) {
365
591
  if (!meta) {
366
592
  continue;
367
593
  }
594
+ const evalMeta = meta.eval ?? (meta.harness ? {
595
+ avgScore: assertion.status === "passed" ? 1 : assertion.status === "failed" ? 0 : null,
596
+ scores: [],
597
+ thresholdFailed: false
598
+ } : void 0);
368
599
  runCases.push({
369
600
  id: createCaseId(runId, file.name, assertion),
370
601
  runId,
@@ -380,7 +611,7 @@ function collectReportWorkspace(input, options = {}) {
380
611
  ...typeof assertion.duration === "number" ? { durationMs: assertion.duration } : {},
381
612
  ...assertion.location ? { location: assertion.location } : {},
382
613
  failureMessages: assertion.failureMessages ?? [],
383
- ...meta.eval ? { eval: meta.eval } : {},
614
+ ...evalMeta ? { eval: evalMeta } : {},
384
615
  ...meta.harness ? { harness: meta.harness } : {}
385
616
  });
386
617
  }
@@ -479,7 +710,6 @@ export {
479
710
  JsonPrimitiveSchema,
480
711
  JsonValueSchema,
481
712
  NormalizedErrorSchema,
482
- NormalizedMessageSchema,
483
713
  NormalizedSessionSchema,
484
714
  NormalizedSpanAttributesSchema,
485
715
  NormalizedSpanEventSchema,
@@ -490,7 +720,11 @@ export {
490
720
  ReportRunSchema,
491
721
  ReportWorkspaceSchema,
492
722
  TimingSummarySchema,
493
- ToolCallRecordSchema,
723
+ ToolCallSchema,
724
+ TranscriptEventSchema,
725
+ TranscriptMessageEventSchema,
726
+ TranscriptToolCallEventSchema,
727
+ TranscriptToolResultEventSchema,
494
728
  UsageSummarySchema,
495
729
  VitestJsonAssertionSchema,
496
730
  VitestJsonFileSchema,
@@ -500,8 +734,12 @@ export {
500
734
  assistantMessages,
501
735
  collectReportWorkspace,
502
736
  failedSpans,
737
+ isMessageEvent,
738
+ isToolCallEvent,
739
+ isToolResultEvent,
503
740
  latestAssistantMessageContent,
504
741
  messagesByRole,
742
+ messagesToTranscriptEvents,
505
743
  parseReportWorkspace,
506
744
  parseVitestJsonReport,
507
745
  readEvalTaskMeta,