@vitest-evals/core 0.13.0 → 0.14.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.js CHANGED
@@ -29,7 +29,6 @@ __export(index_exports, {
29
29
  JsonPrimitiveSchema: () => JsonPrimitiveSchema,
30
30
  JsonValueSchema: () => JsonValueSchema,
31
31
  NormalizedErrorSchema: () => NormalizedErrorSchema,
32
- NormalizedMessageSchema: () => NormalizedMessageSchema,
33
32
  NormalizedSessionSchema: () => NormalizedSessionSchema,
34
33
  NormalizedSpanAttributesSchema: () => NormalizedSpanAttributesSchema,
35
34
  NormalizedSpanEventSchema: () => NormalizedSpanEventSchema,
@@ -40,7 +39,11 @@ __export(index_exports, {
40
39
  ReportRunSchema: () => ReportRunSchema,
41
40
  ReportWorkspaceSchema: () => ReportWorkspaceSchema,
42
41
  TimingSummarySchema: () => TimingSummarySchema,
43
- ToolCallRecordSchema: () => ToolCallRecordSchema,
42
+ ToolCallSchema: () => ToolCallSchema,
43
+ TranscriptEventSchema: () => TranscriptEventSchema,
44
+ TranscriptMessageEventSchema: () => TranscriptMessageEventSchema,
45
+ TranscriptToolCallEventSchema: () => TranscriptToolCallEventSchema,
46
+ TranscriptToolResultEventSchema: () => TranscriptToolResultEventSchema,
44
47
  UsageSummarySchema: () => UsageSummarySchema,
45
48
  VitestJsonAssertionSchema: () => VitestJsonAssertionSchema,
46
49
  VitestJsonFileSchema: () => VitestJsonFileSchema,
@@ -50,8 +53,12 @@ __export(index_exports, {
50
53
  assistantMessages: () => assistantMessages,
51
54
  collectReportWorkspace: () => collectReportWorkspace,
52
55
  failedSpans: () => failedSpans,
56
+ isMessageEvent: () => isMessageEvent,
57
+ isToolCallEvent: () => isToolCallEvent,
58
+ isToolResultEvent: () => isToolResultEvent,
53
59
  latestAssistantMessageContent: () => latestAssistantMessageContent,
54
60
  messagesByRole: () => messagesByRole,
61
+ messagesToTranscriptEvents: () => messagesToTranscriptEvents,
55
62
  parseReportWorkspace: () => parseReportWorkspace,
56
63
  parseVitestJsonReport: () => parseVitestJsonReport,
57
64
  readEvalTaskMeta: () => readEvalTaskMeta,
@@ -83,7 +90,7 @@ var JsonValueSchema = import_zod.z.lazy(
83
90
  var JsonObjectSchema = import_zod.z.record(import_zod.z.string(), JsonValueSchema);
84
91
 
85
92
  // src/harness/index.ts
86
- var import_zod3 = require("zod");
93
+ var import_zod5 = require("zod");
87
94
 
88
95
  // src/schema-utils.ts
89
96
  var import_zod2 = require("zod");
@@ -114,10 +121,232 @@ function isRecord(value) {
114
121
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
115
122
  }
116
123
 
124
+ // src/harness/errors.ts
125
+ var import_zod3 = require("zod");
126
+ var NormalizedErrorSchema = import_zod3.z.object({
127
+ message: import_zod3.z.string(),
128
+ type: import_zod3.z.string().optional()
129
+ }).catchall(JsonValueSchema);
130
+
131
+ // src/harness/transcript.ts
132
+ var import_zod4 = require("zod");
133
+ var TranscriptToolCallEventSchema = import_zod4.z.object({
134
+ type: import_zod4.z.literal("tool_call"),
135
+ id: import_zod4.z.string(),
136
+ name: import_zod4.z.string(),
137
+ arguments: JsonObjectSchema.optional(),
138
+ startedAt: import_zod4.z.string().optional(),
139
+ finishedAt: import_zod4.z.string().optional(),
140
+ durationMs: FiniteNumberSchema.optional(),
141
+ metadata: JsonObjectSchema.optional()
142
+ }).strict();
143
+ var TranscriptMessageEventSchema = import_zod4.z.object({
144
+ type: import_zod4.z.literal("message"),
145
+ role: import_zod4.z.enum(["system", "user", "assistant"]),
146
+ content: JsonValueSchema.optional(),
147
+ metadata: JsonObjectSchema.optional()
148
+ }).strict();
149
+ var TranscriptToolResultEventSchema = import_zod4.z.object({
150
+ type: import_zod4.z.literal("tool_result"),
151
+ toolCallId: import_zod4.z.string(),
152
+ name: import_zod4.z.string().optional(),
153
+ content: JsonValueSchema.optional(),
154
+ error: NormalizedErrorSchema.optional(),
155
+ startedAt: import_zod4.z.string().optional(),
156
+ finishedAt: import_zod4.z.string().optional(),
157
+ durationMs: FiniteNumberSchema.optional(),
158
+ metadata: JsonObjectSchema.optional()
159
+ }).strict();
160
+ var TranscriptEventSchema = import_zod4.z.discriminatedUnion("type", [
161
+ TranscriptMessageEventSchema,
162
+ TranscriptToolCallEventSchema,
163
+ TranscriptToolResultEventSchema
164
+ ]);
165
+ function messagesToTranscriptEvents(messages) {
166
+ const events = [];
167
+ for (const [messageIndex, message] of messages.entries()) {
168
+ if (message.role === "tool") {
169
+ const partEvents2 = contentPartEvents(message);
170
+ if (partEvents2) {
171
+ events.push(...partEvents2);
172
+ continue;
173
+ }
174
+ if (!hasTopLevelToolCallId(message)) {
175
+ throw new TypeError("Tool result messages must include toolCallId.");
176
+ }
177
+ events.push(toolResultMessageEvent(message, message.toolCallId));
178
+ continue;
179
+ }
180
+ const partEvents = message.role === "assistant" ? contentPartEvents(message) : void 0;
181
+ const partEventsHaveToolCalls = partEvents?.some(
182
+ (event) => event.type === "tool_call"
183
+ );
184
+ if (partEvents) {
185
+ events.push(...partEvents);
186
+ } else if (message.content !== void 0) {
187
+ events.push({
188
+ type: "message",
189
+ role: message.role,
190
+ content: message.content,
191
+ ...message.metadata ? { metadata: message.metadata } : {}
192
+ });
193
+ }
194
+ if (message.role !== "assistant") {
195
+ continue;
196
+ }
197
+ if (partEventsHaveToolCalls) {
198
+ if ((message.toolCalls ?? []).length > 0) {
199
+ throw new TypeError(
200
+ "Assistant messages must not mix tool-call content parts with toolCalls."
201
+ );
202
+ }
203
+ continue;
204
+ }
205
+ const messageToolCalls = message.toolCalls ?? [];
206
+ for (const [toolIndex, toolCall] of messageToolCalls.entries()) {
207
+ const rawToolCall = toolCall;
208
+ if (Object.prototype.hasOwnProperty.call(rawToolCall, "result") || Object.prototype.hasOwnProperty.call(rawToolCall, "error")) {
209
+ throw new TypeError(
210
+ "Assistant tool calls must use separate tool result messages."
211
+ );
212
+ }
213
+ if (typeof toolCall.name !== "string" || toolCall.name.length === 0) {
214
+ throw new TypeError("Assistant tool calls must include name.");
215
+ }
216
+ const id = toolCall.id ?? `message-${messageIndex}:tool-call-${toolIndex}`;
217
+ events.push({
218
+ type: "tool_call",
219
+ id,
220
+ name: toolCall.name,
221
+ ...normalizeToolCallArguments(toolCall.arguments),
222
+ ...toolCall.startedAt ? { startedAt: toolCall.startedAt } : {},
223
+ ...toolCall.finishedAt ? { finishedAt: toolCall.finishedAt } : {},
224
+ ...toolCall.durationMs !== void 0 ? { durationMs: toolCall.durationMs } : {},
225
+ ...toolCall.metadata ? { metadata: toolCall.metadata } : {}
226
+ });
227
+ }
228
+ }
229
+ return events;
230
+ }
231
+ function contentPartEvents(message) {
232
+ if (!Array.isArray(message.content)) {
233
+ return void 0;
234
+ }
235
+ const events = [];
236
+ for (const part of message.content) {
237
+ if (!isJsonObject2(part) || typeof part.type !== "string") {
238
+ continue;
239
+ }
240
+ if (part.type === "text" && typeof part.text === "string") {
241
+ if (message.role === "tool") {
242
+ throw new TypeError("Text content parts require message role.");
243
+ }
244
+ events.push({
245
+ type: "message",
246
+ role: message.role,
247
+ content: part.text,
248
+ ...recordMetadata(message.metadata)
249
+ });
250
+ continue;
251
+ }
252
+ if (part.type === "tool-call") {
253
+ if (message.role !== "assistant" || typeof part.toolCallId !== "string" || typeof part.toolName !== "string") {
254
+ throw new TypeError(
255
+ "Tool-call content parts require assistant role, toolCallId, and toolName."
256
+ );
257
+ }
258
+ events.push({
259
+ type: "tool_call",
260
+ id: part.toolCallId,
261
+ name: part.toolName,
262
+ ...normalizeToolCallArguments(part.input),
263
+ ...jsonTimeFields(part),
264
+ ...jsonMetadata(part.metadata)
265
+ });
266
+ continue;
267
+ }
268
+ if (part.type === "tool-result") {
269
+ if (message.role !== "tool" || typeof part.toolCallId !== "string") {
270
+ throw new TypeError(
271
+ "Tool-result content parts require tool role and toolCallId."
272
+ );
273
+ }
274
+ if (hasTopLevelToolCallId(message)) {
275
+ throw new TypeError(
276
+ "Tool-result content parts must not include top-level toolCallId."
277
+ );
278
+ }
279
+ events.push({
280
+ type: "tool_result",
281
+ toolCallId: part.toolCallId,
282
+ ...typeof part.toolName === "string" ? { name: part.toolName } : {},
283
+ ...part.output !== void 0 ? { content: part.output } : {},
284
+ ...part.error ? { error: part.error } : {},
285
+ ...jsonTimeFields(part),
286
+ ...jsonMetadata(part.metadata)
287
+ });
288
+ continue;
289
+ }
290
+ throw new TypeError(
291
+ "Message content parts must use the harness message contract."
292
+ );
293
+ }
294
+ return events.length > 0 ? events : void 0;
295
+ }
296
+ function toolResultMessageEvent(message, toolCallId) {
297
+ return {
298
+ type: "tool_result",
299
+ toolCallId,
300
+ ...message.name ? { name: message.name } : {},
301
+ ...message.content !== void 0 ? { content: message.content } : {},
302
+ ...message.error ? { error: message.error } : {},
303
+ ...timeFields(message),
304
+ ...recordMetadata(message.metadata)
305
+ };
306
+ }
307
+ function hasTopLevelToolCallId(message) {
308
+ return typeof message.toolCallId === "string";
309
+ }
310
+ function timeFields(input) {
311
+ return {
312
+ ...input.startedAt ? { startedAt: input.startedAt } : {},
313
+ ...input.finishedAt ? { finishedAt: input.finishedAt } : {},
314
+ ...input.durationMs !== void 0 ? { durationMs: input.durationMs } : {}
315
+ };
316
+ }
317
+ function recordMetadata(metadata) {
318
+ return metadata ? { metadata } : {};
319
+ }
320
+ function jsonTimeFields(input) {
321
+ return {
322
+ ...typeof input.startedAt === "string" ? { startedAt: input.startedAt } : {},
323
+ ...typeof input.finishedAt === "string" ? { finishedAt: input.finishedAt } : {},
324
+ ...typeof input.durationMs === "number" ? { durationMs: input.durationMs } : {}
325
+ };
326
+ }
327
+ function jsonMetadata(value) {
328
+ return isJsonObject2(value) ? { metadata: value } : {};
329
+ }
330
+ function normalizeToolCallArguments(value) {
331
+ return value && typeof value === "object" && !Array.isArray(value) ? { arguments: value } : {};
332
+ }
333
+ function isJsonObject2(value) {
334
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
335
+ }
336
+ function isMessageEvent(event) {
337
+ return event.type === "message";
338
+ }
339
+ function isToolCallEvent(event) {
340
+ return event.type === "tool_call";
341
+ }
342
+ function isToolResultEvent(event) {
343
+ return event.type === "tool_result";
344
+ }
345
+
117
346
  // src/harness/index.ts
118
- var UsageSummarySchema = import_zod3.z.object({
119
- provider: import_zod3.z.string().optional(),
120
- model: import_zod3.z.string().optional(),
347
+ var UsageSummarySchema = import_zod5.z.object({
348
+ provider: import_zod5.z.string().optional(),
349
+ model: import_zod5.z.string().optional(),
121
350
  inputTokens: FiniteNumberSchema.optional(),
122
351
  outputTokens: FiniteNumberSchema.optional(),
123
352
  reasoningTokens: FiniteNumberSchema.optional(),
@@ -126,182 +355,213 @@ var UsageSummarySchema = import_zod3.z.object({
126
355
  retries: FiniteNumberSchema.optional(),
127
356
  metadata: JsonObjectSchema.optional()
128
357
  }).strict();
129
- var TimingSummarySchema = import_zod3.z.object({
358
+ var TimingSummarySchema = import_zod5.z.object({
130
359
  totalMs: FiniteNumberSchema.optional(),
131
360
  metadata: JsonObjectSchema.optional()
132
361
  }).strict();
133
- var NormalizedErrorSchema = import_zod3.z.object({
134
- message: import_zod3.z.string(),
135
- type: import_zod3.z.string().optional()
136
- }).catchall(JsonValueSchema);
137
- var ToolCallRecordSchema = import_zod3.z.object({
138
- id: import_zod3.z.string().optional(),
139
- name: import_zod3.z.string(),
140
- arguments: JsonObjectSchema.optional(),
141
- result: JsonValueSchema.optional(),
142
- error: NormalizedErrorSchema.optional(),
143
- startedAt: import_zod3.z.string().optional(),
144
- finishedAt: import_zod3.z.string().optional(),
145
- durationMs: FiniteNumberSchema.optional(),
146
- metadata: JsonObjectSchema.optional()
147
- }).strict();
148
- var NormalizedMessageSchema = import_zod3.z.object({
149
- role: import_zod3.z.enum(["system", "user", "assistant", "tool"]),
150
- content: JsonValueSchema.optional(),
151
- toolCalls: import_zod3.z.array(ToolCallRecordSchema).optional(),
152
- metadata: JsonObjectSchema.optional()
362
+ var ToolCallBaseSchema = import_zod5.z.object({
363
+ name: import_zod5.z.string(),
364
+ arguments: JsonObjectSchema.optional()
153
365
  }).strict();
154
- var NormalizedSessionSchema = import_zod3.z.object({
155
- messages: import_zod3.z.array(NormalizedMessageSchema).default([]),
156
- provider: import_zod3.z.string().optional(),
157
- model: import_zod3.z.string().optional(),
366
+ var ToolCallSchema = import_zod5.z.discriminatedUnion("status", [
367
+ ToolCallBaseSchema.extend({
368
+ status: import_zod5.z.literal("pending")
369
+ }).strict(),
370
+ ToolCallBaseSchema.extend({
371
+ status: import_zod5.z.literal("ok"),
372
+ result: JsonValueSchema.optional()
373
+ }).strict(),
374
+ ToolCallBaseSchema.extend({
375
+ status: import_zod5.z.literal("error"),
376
+ error: NormalizedErrorSchema
377
+ }).strict()
378
+ ]);
379
+ var NormalizedSessionSchema = import_zod5.z.object({
380
+ events: import_zod5.z.array(TranscriptEventSchema),
381
+ provider: import_zod5.z.string().optional(),
382
+ model: import_zod5.z.string().optional(),
158
383
  metadata: JsonObjectSchema.optional()
159
384
  }).strict();
160
385
  var NormalizedSpanAttributesSchema = JsonObjectSchema;
161
- var NormalizedSpanEventSchema = import_zod3.z.object({
162
- name: import_zod3.z.string(),
163
- timestamp: import_zod3.z.string().optional(),
386
+ var NormalizedSpanEventSchema = import_zod5.z.object({
387
+ name: import_zod5.z.string(),
388
+ timestamp: import_zod5.z.string().optional(),
164
389
  attributes: NormalizedSpanAttributesSchema.optional()
165
390
  }).strict();
166
- var NormalizedSpanSchema = import_zod3.z.object({
167
- id: import_zod3.z.string().optional(),
168
- traceId: import_zod3.z.string().optional(),
169
- parentId: import_zod3.z.string().optional(),
170
- name: import_zod3.z.string(),
171
- kind: import_zod3.z.enum(["run", "agent", "model", "tool", "guardrail", "handoff", "custom"]).optional(),
172
- startedAt: import_zod3.z.string().optional(),
173
- finishedAt: import_zod3.z.string().optional(),
391
+ var NormalizedSpanSchema = import_zod5.z.object({
392
+ id: import_zod5.z.string().optional(),
393
+ traceId: import_zod5.z.string().optional(),
394
+ parentId: import_zod5.z.string().optional(),
395
+ name: import_zod5.z.string(),
396
+ kind: import_zod5.z.enum(["run", "agent", "model", "tool", "guardrail", "handoff", "custom"]).optional(),
397
+ startedAt: import_zod5.z.string().optional(),
398
+ finishedAt: import_zod5.z.string().optional(),
174
399
  durationMs: FiniteNumberSchema.optional(),
175
- status: import_zod3.z.enum(["ok", "error"]).optional(),
400
+ status: import_zod5.z.enum(["ok", "error"]).optional(),
176
401
  error: NormalizedErrorSchema.optional(),
177
402
  attributes: NormalizedSpanAttributesSchema.optional(),
178
- events: import_zod3.z.array(NormalizedSpanEventSchema).optional()
403
+ events: import_zod5.z.array(NormalizedSpanEventSchema).optional()
179
404
  }).strict();
180
- var NormalizedTraceSchema = import_zod3.z.object({
181
- id: import_zod3.z.string().optional(),
182
- name: import_zod3.z.string().optional(),
183
- startedAt: import_zod3.z.string().optional(),
184
- finishedAt: import_zod3.z.string().optional(),
405
+ var NormalizedTraceSchema = import_zod5.z.object({
406
+ id: import_zod5.z.string().optional(),
407
+ name: import_zod5.z.string().optional(),
408
+ startedAt: import_zod5.z.string().optional(),
409
+ finishedAt: import_zod5.z.string().optional(),
185
410
  durationMs: FiniteNumberSchema.optional(),
186
411
  metadata: JsonObjectSchema.optional(),
187
- spans: import_zod3.z.array(NormalizedSpanSchema).default([])
412
+ spans: import_zod5.z.array(NormalizedSpanSchema)
188
413
  }).strict();
189
- var HarnessRunSchema = import_zod3.z.object({
414
+ var HarnessRunSchema = import_zod5.z.object({
190
415
  output: JsonValueSchema.optional(),
191
416
  session: NormalizedSessionSchema,
192
417
  usage: UsageSummarySchema,
193
418
  timings: TimingSummarySchema.optional(),
194
419
  artifacts: JsonObjectSchema.optional(),
195
- traces: import_zod3.z.array(NormalizedTraceSchema).optional(),
196
- errors: import_zod3.z.array(JsonObjectSchema).default([])
420
+ traces: import_zod5.z.array(NormalizedTraceSchema).optional(),
421
+ errors: import_zod5.z.array(JsonObjectSchema)
197
422
  }).strict();
198
423
 
199
424
  // src/harness/helpers.ts
200
- function toolCalls(session) {
201
- return session.messages.flatMap((message) => message.toolCalls ?? []);
425
+ function toolCalls(source) {
426
+ const resultsById = /* @__PURE__ */ new Map();
427
+ for (const message of toolResultsFromSource(source)) {
428
+ if (!resultsById.has(message.toolCallId)) {
429
+ resultsById.set(message.toolCallId, message);
430
+ }
431
+ }
432
+ return toolCallsFromSource(source).map((call) => {
433
+ const result = resultsById.get(call.id);
434
+ const normalizedCall = {
435
+ name: call.name,
436
+ ...call.arguments ? { arguments: call.arguments } : {}
437
+ };
438
+ if (!result) {
439
+ return {
440
+ ...normalizedCall,
441
+ status: "pending"
442
+ };
443
+ }
444
+ if (result.error) {
445
+ return {
446
+ ...normalizedCall,
447
+ status: "error",
448
+ error: result.error
449
+ };
450
+ }
451
+ return {
452
+ ...normalizedCall,
453
+ status: "ok",
454
+ ...result.content !== void 0 ? { result: result.content } : {}
455
+ };
456
+ });
202
457
  }
203
- function spans(run) {
204
- return (run.traces ?? []).flatMap((trace) => trace.spans);
458
+ function spans(source) {
459
+ return spansFrom(source);
205
460
  }
206
- function traceSpans(run) {
207
- return spans(run);
461
+ function traceSpans(source) {
462
+ return spansFrom(source);
208
463
  }
209
- function spansByKind(run, kind) {
210
- return spans(run).filter((span) => span.kind === kind);
464
+ function spansByKind(source, kind) {
465
+ return spansFrom(source).filter((span) => span.kind === kind);
211
466
  }
212
- function failedSpans(run) {
213
- return spans(run).filter(
467
+ function failedSpans(source) {
468
+ return spansFrom(source).filter(
214
469
  (span) => span.status === "error" || span.error !== void 0
215
470
  );
216
471
  }
217
- function messagesByRole(session, role) {
218
- return session.messages.filter((message) => message.role === role);
472
+ function messagesByRole(source, role) {
473
+ return sessionFrom(source).events.filter(
474
+ (event) => event.type === "message" && event.role === role
475
+ );
476
+ }
477
+ function systemMessages(source) {
478
+ return messagesByRoleFromSource(source, "system");
479
+ }
480
+ function userMessages(source) {
481
+ return messagesByRoleFromSource(source, "user");
482
+ }
483
+ function assistantMessages(source) {
484
+ return messagesByRoleFromSource(source, "assistant");
219
485
  }
220
- function systemMessages(session) {
221
- return messagesByRole(session, "system");
486
+ function latestAssistantMessageContent(source) {
487
+ return [...messagesByRoleFromSource(source, "assistant")].reverse().find(hasNonEmptyMessageContent)?.content;
222
488
  }
223
- function userMessages(session) {
224
- return messagesByRole(session, "user");
489
+ function toolMessages(source) {
490
+ return toolResultsFromSource(source);
225
491
  }
226
- function assistantMessages(session) {
227
- return messagesByRole(session, "assistant");
492
+ function sessionFrom(source) {
493
+ return "session" in source ? source.session : source;
228
494
  }
229
- function latestAssistantMessageContent(session) {
230
- return [...assistantMessages(session)].reverse().find(hasNonEmptyMessageContent)?.content;
495
+ function toolResultsFromSource(source) {
496
+ return sessionFrom(source).events.filter(isToolResultEvent);
231
497
  }
232
- function toolMessages(session) {
233
- return messagesByRole(session, "tool");
498
+ function toolCallsFromSource(source) {
499
+ return sessionFrom(source).events.filter(isToolCallEvent);
500
+ }
501
+ function tracesFrom(source) {
502
+ if (source === void 0) {
503
+ return [];
504
+ }
505
+ if (isTraceList(source)) {
506
+ return source;
507
+ }
508
+ return source.traces ?? [];
509
+ }
510
+ function spansFrom(source) {
511
+ return tracesFrom(source).flatMap((trace) => trace.spans);
512
+ }
513
+ function isTraceList(source) {
514
+ return Array.isArray(source);
515
+ }
516
+ function messagesByRoleFromSource(source, role) {
517
+ return sessionFrom(source).events.filter(
518
+ (event) => event.type === "message" && event.role === role
519
+ );
234
520
  }
235
521
  function hasNonEmptyMessageContent(message) {
236
522
  return message.content !== void 0 && (typeof message.content !== "string" || message.content.trim().length > 0);
237
523
  }
238
524
 
239
525
  // src/report/metadata.ts
240
- var import_zod4 = require("zod");
241
- var HarnessMetaSchema = import_zod4.z.object({
242
- name: import_zod4.z.string().optional(),
526
+ var import_zod6 = require("zod");
527
+ var HarnessMetaSchema = import_zod6.z.object({
528
+ name: import_zod6.z.string().optional(),
243
529
  run: HarnessRunSchema.optional()
244
530
  }).strict();
245
- var EvalScoreSchema = import_zod4.z.object({
246
- name: import_zod4.z.string().optional(),
531
+ var EvalScoreSchema = import_zod6.z.object({
532
+ name: import_zod6.z.string().optional(),
247
533
  score: NullableFiniteNumberSchema,
248
534
  metadata: JsonObjectSchema.optional()
249
535
  }).strict();
250
- var EvalMetaSchema = import_zod4.z.object({
251
- scores: import_zod4.z.array(EvalScoreSchema).optional(),
536
+ var EvalMetaSchema = import_zod6.z.object({
537
+ scores: import_zod6.z.array(EvalScoreSchema).optional(),
252
538
  avgScore: NullableFiniteNumberSchema,
253
539
  output: JsonValueSchema.optional(),
254
- thresholdFailed: import_zod4.z.boolean().optional(),
255
- toolCalls: import_zod4.z.array(ToolCallRecordSchema).optional()
540
+ thresholdFailed: import_zod6.z.boolean().optional(),
541
+ toolCalls: import_zod6.z.array(ToolCallSchema).optional()
256
542
  }).strict();
257
- var EvalTaskMetaSchema = import_zod4.z.object({
543
+ var EvalTaskMetaSchema = import_zod6.z.object({
258
544
  eval: EvalMetaSchema.optional(),
259
545
  harness: HarnessMetaSchema.optional()
260
546
  }).strict();
261
- var LenientToolCallRecordSchema = ToolCallRecordSchema.strip();
262
- var LenientMessageSchema = NormalizedMessageSchema.extend({
263
- toolCalls: import_zod4.z.array(LenientToolCallRecordSchema).optional().catch(void 0)
264
- }).strip();
265
- var LenientSessionSchema = NormalizedSessionSchema.extend({
266
- messages: import_zod4.z.array(LenientMessageSchema).default([]).catch([])
267
- }).strip();
268
- var LenientSpanEventSchema = NormalizedSpanEventSchema.strip();
269
- var LenientSpanSchema = NormalizedSpanSchema.extend({
270
- events: import_zod4.z.array(LenientSpanEventSchema).optional().catch(void 0)
271
- }).strip();
272
- var LenientTraceSchema = NormalizedTraceSchema.extend({
273
- spans: import_zod4.z.array(LenientSpanSchema).default([]).catch([])
274
- }).strip();
275
- var LenientHarnessRunSchema = HarnessRunSchema.extend({
276
- session: LenientSessionSchema,
277
- usage: UsageSummarySchema.strip().default({}),
278
- timings: TimingSummarySchema.strip().optional(),
279
- traces: import_zod4.z.array(LenientTraceSchema).optional().catch(void 0)
280
- }).strip();
281
- var LenientHarnessMetaSchema = HarnessMetaSchema.extend({
282
- run: LenientHarnessRunSchema.optional().catch(void 0)
283
- }).strip();
284
- var LenientEvalScoreSchema = EvalScoreSchema.strip();
285
- var LenientEvalMetaSchema = EvalMetaSchema.extend({
286
- scores: import_zod4.z.array(LenientEvalScoreSchema).optional().catch(void 0),
287
- toolCalls: import_zod4.z.array(LenientToolCallRecordSchema).optional().catch(void 0)
288
- }).strip();
289
547
  function readEvalTaskMeta(input) {
290
548
  if (!isJsonObject(input)) {
291
549
  return void 0;
292
550
  }
293
- const evalResult = LenientEvalMetaSchema.safeParse(input.eval);
294
- const harnessResult = LenientHarnessMetaSchema.safeParse(input.harness);
295
551
  const meta = {
296
- ...evalResult.success && input.eval !== void 0 ? { eval: evalResult.data } : {},
297
- ...harnessResult.success && input.harness !== void 0 ? { harness: harnessResult.data } : {}
552
+ ...input.eval !== void 0 ? { eval: input.eval } : {},
553
+ ...input.harness !== void 0 ? { harness: input.harness } : {}
298
554
  };
299
- return meta.eval || meta.harness ? meta : void 0;
555
+ if (!("eval" in meta) && !("harness" in meta)) {
556
+ return void 0;
557
+ }
558
+ const result = EvalTaskMetaSchema.safeParse(meta);
559
+ return result.success ? result.data : void 0;
300
560
  }
301
561
 
302
562
  // src/report/vitest-json.ts
303
- var import_zod5 = require("zod");
304
- var VitestJsonStatusSchema = import_zod5.z.enum([
563
+ var import_zod7 = require("zod");
564
+ var VitestJsonStatusSchema = import_zod7.z.enum([
305
565
  "passed",
306
566
  "failed",
307
567
  "skipped",
@@ -309,53 +569,53 @@ var VitestJsonStatusSchema = import_zod5.z.enum([
309
569
  "todo",
310
570
  "disabled"
311
571
  ]);
312
- var VitestJsonLocationSchema = import_zod5.z.object({
572
+ var VitestJsonLocationSchema = import_zod7.z.object({
313
573
  line: FiniteNumberSchema,
314
574
  column: FiniteNumberSchema
315
575
  }).passthrough();
316
- var VitestJsonAssertionSchema = import_zod5.z.object({
317
- ancestorTitles: import_zod5.z.array(import_zod5.z.string()).default([]),
318
- fullName: import_zod5.z.string(),
576
+ var VitestJsonAssertionSchema = import_zod7.z.object({
577
+ ancestorTitles: import_zod7.z.array(import_zod7.z.string()).default([]),
578
+ fullName: import_zod7.z.string(),
319
579
  status: VitestJsonStatusSchema,
320
- title: import_zod5.z.string(),
321
- meta: import_zod5.z.unknown().optional(),
580
+ title: import_zod7.z.string(),
581
+ meta: import_zod7.z.unknown().optional(),
322
582
  duration: FiniteNumberSchema.nullable().optional(),
323
- failureMessages: import_zod5.z.array(import_zod5.z.string()).nullable().optional(),
583
+ failureMessages: import_zod7.z.array(import_zod7.z.string()).nullable().optional(),
324
584
  location: VitestJsonLocationSchema.nullable().optional(),
325
- tags: import_zod5.z.array(import_zod5.z.string()).optional()
585
+ tags: import_zod7.z.array(import_zod7.z.string()).optional()
326
586
  }).passthrough();
327
- var VitestJsonFileSchema = import_zod5.z.object({
328
- message: import_zod5.z.string(),
329
- name: import_zod5.z.string(),
330
- status: import_zod5.z.enum(["failed", "passed"]),
587
+ var VitestJsonFileSchema = import_zod7.z.object({
588
+ message: import_zod7.z.string(),
589
+ name: import_zod7.z.string(),
590
+ status: import_zod7.z.enum(["failed", "passed"]),
331
591
  startTime: OptionalFiniteNumberSchema,
332
592
  endTime: OptionalFiniteNumberSchema,
333
- assertionResults: import_zod5.z.array(VitestJsonAssertionSchema).default([])
593
+ assertionResults: import_zod7.z.array(VitestJsonAssertionSchema).default([])
334
594
  }).passthrough();
335
- var VitestJsonReportSchema = import_zod5.z.object({
595
+ var VitestJsonReportSchema = import_zod7.z.object({
336
596
  numFailedTests: FiniteNumberSchema,
337
597
  numPassedTests: FiniteNumberSchema,
338
598
  numPendingTests: FiniteNumberSchema,
339
599
  numTodoTests: FiniteNumberSchema,
340
600
  numTotalTests: FiniteNumberSchema,
341
601
  startTime: FiniteNumberSchema,
342
- success: import_zod5.z.boolean(),
343
- testResults: import_zod5.z.array(VitestJsonFileSchema).default([])
602
+ success: import_zod7.z.boolean(),
603
+ testResults: import_zod7.z.array(VitestJsonFileSchema).default([])
344
604
  }).passthrough();
345
605
  function parseVitestJsonReport(input) {
346
606
  return parseWithSchema(VitestJsonReportSchema, input, "Vitest JSON report");
347
607
  }
348
608
 
349
609
  // src/report/workspace.ts
350
- var import_zod6 = require("zod");
610
+ var import_zod8 = require("zod");
351
611
  var REPORT_WORKSPACE_SCHEMA_VERSION = 1;
352
- var ReportRunSchema = import_zod6.z.object({
353
- id: import_zod6.z.string(),
354
- source: import_zod6.z.string().optional(),
355
- status: import_zod6.z.enum(["passed", "failed"]),
612
+ var ReportRunSchema = import_zod8.z.object({
613
+ id: import_zod8.z.string(),
614
+ source: import_zod8.z.string().optional(),
615
+ status: import_zod8.z.enum(["passed", "failed"]),
356
616
  startedAt: FiniteNumberSchema.optional(),
357
617
  durationMs: FiniteNumberSchema.optional(),
358
- totals: import_zod6.z.object({
618
+ totals: import_zod8.z.object({
359
619
  total: FiniteNumberSchema,
360
620
  passed: FiniteNumberSchema,
361
621
  failed: FiniteNumberSchema,
@@ -365,28 +625,28 @@ var ReportRunSchema = import_zod6.z.object({
365
625
  evalFailed: FiniteNumberSchema
366
626
  })
367
627
  }).strict();
368
- var ReportCaseSchema = import_zod6.z.object({
369
- id: import_zod6.z.string(),
370
- runId: import_zod6.z.string(),
371
- source: import_zod6.z.string().optional(),
372
- file: import_zod6.z.string(),
373
- displayFile: import_zod6.z.string(),
374
- title: import_zod6.z.string(),
375
- fullName: import_zod6.z.string(),
376
- ancestorTitles: import_zod6.z.array(import_zod6.z.string()),
377
- tags: import_zod6.z.array(import_zod6.z.string()).optional(),
378
- displayName: import_zod6.z.string(),
628
+ var ReportCaseSchema = import_zod8.z.object({
629
+ id: import_zod8.z.string(),
630
+ runId: import_zod8.z.string(),
631
+ source: import_zod8.z.string().optional(),
632
+ file: import_zod8.z.string(),
633
+ displayFile: import_zod8.z.string(),
634
+ title: import_zod8.z.string(),
635
+ fullName: import_zod8.z.string(),
636
+ ancestorTitles: import_zod8.z.array(import_zod8.z.string()),
637
+ tags: import_zod8.z.array(import_zod8.z.string()).optional(),
638
+ displayName: import_zod8.z.string(),
379
639
  status: VitestJsonStatusSchema,
380
640
  durationMs: FiniteNumberSchema.optional(),
381
641
  location: VitestJsonLocationSchema.optional(),
382
- failureMessages: import_zod6.z.array(import_zod6.z.string()).default([]),
642
+ failureMessages: import_zod8.z.array(import_zod8.z.string()).default([]),
383
643
  eval: EvalMetaSchema.optional(),
384
644
  harness: HarnessMetaSchema.optional()
385
645
  }).strict();
386
- var ReportWorkspaceSchema = import_zod6.z.object({
387
- schemaVersion: import_zod6.z.literal(REPORT_WORKSPACE_SCHEMA_VERSION),
388
- runs: import_zod6.z.array(ReportRunSchema),
389
- cases: import_zod6.z.array(ReportCaseSchema)
646
+ var ReportWorkspaceSchema = import_zod8.z.object({
647
+ schemaVersion: import_zod8.z.literal(REPORT_WORKSPACE_SCHEMA_VERSION),
648
+ runs: import_zod8.z.array(ReportRunSchema),
649
+ cases: import_zod8.z.array(ReportCaseSchema)
390
650
  }).strict();
391
651
  function parseReportWorkspace(input) {
392
652
  return parseWithSchema(ReportWorkspaceSchema, input, "report workspace");
@@ -520,7 +780,6 @@ function normalizeReportPath(path, workspace) {
520
780
  JsonPrimitiveSchema,
521
781
  JsonValueSchema,
522
782
  NormalizedErrorSchema,
523
- NormalizedMessageSchema,
524
783
  NormalizedSessionSchema,
525
784
  NormalizedSpanAttributesSchema,
526
785
  NormalizedSpanEventSchema,
@@ -531,7 +790,11 @@ function normalizeReportPath(path, workspace) {
531
790
  ReportRunSchema,
532
791
  ReportWorkspaceSchema,
533
792
  TimingSummarySchema,
534
- ToolCallRecordSchema,
793
+ ToolCallSchema,
794
+ TranscriptEventSchema,
795
+ TranscriptMessageEventSchema,
796
+ TranscriptToolCallEventSchema,
797
+ TranscriptToolResultEventSchema,
535
798
  UsageSummarySchema,
536
799
  VitestJsonAssertionSchema,
537
800
  VitestJsonFileSchema,
@@ -541,8 +804,12 @@ function normalizeReportPath(path, workspace) {
541
804
  assistantMessages,
542
805
  collectReportWorkspace,
543
806
  failedSpans,
807
+ isMessageEvent,
808
+ isToolCallEvent,
809
+ isToolResultEvent,
544
810
  latestAssistantMessageContent,
545
811
  messagesByRole,
812
+ messagesToTranscriptEvents,
546
813
  parseReportWorkspace,
547
814
  parseVitestJsonReport,
548
815
  readEvalTaskMeta,