agent-inspect 6.7.2 → 6.7.4

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +1 -1
  3. package/docs/EXPORTS.md +9 -0
  4. package/docs/PERFORMANCE.md +18 -0
  5. package/docs/STANDARDS.md +4 -0
  6. package/package.json +2 -2
  7. package/packages/cli/dist/{chunk-M6PC5KUT.mjs → chunk-FVEQ7JFF.mjs} +251 -209
  8. package/packages/cli/dist/chunk-FVEQ7JFF.mjs.map +1 -0
  9. package/packages/cli/dist/index.cjs +292 -229
  10. package/packages/cli/dist/index.cjs.map +1 -1
  11. package/packages/cli/dist/index.mjs +35 -15
  12. package/packages/cli/dist/index.mjs.map +1 -1
  13. package/packages/cli/dist/{src-27LC2BB3.mjs → src-I5NA7BLK.mjs} +3 -3
  14. package/packages/cli/dist/{src-27LC2BB3.mjs.map → src-I5NA7BLK.mjs.map} +1 -1
  15. package/packages/core/dist/advanced.cjs +249 -207
  16. package/packages/core/dist/advanced.cjs.map +1 -1
  17. package/packages/core/dist/advanced.mjs +51 -250
  18. package/packages/core/dist/advanced.mjs.map +1 -1
  19. package/packages/core/dist/checks.cjs +56 -4
  20. package/packages/core/dist/checks.cjs.map +1 -1
  21. package/packages/core/dist/checks.mjs +1 -1
  22. package/packages/core/dist/{chunk-X2FLDF7M.mjs → chunk-CTA6XNDP.mjs} +3 -3
  23. package/packages/core/dist/{chunk-X2FLDF7M.mjs.map → chunk-CTA6XNDP.mjs.map} +1 -1
  24. package/packages/core/dist/{chunk-EWHN6NA4.mjs → chunk-EQVXDGGU.mjs} +58 -6
  25. package/packages/core/dist/chunk-EQVXDGGU.mjs.map +1 -0
  26. package/packages/core/dist/{chunk-3USJVBLA.mjs → chunk-KDDU2R5P.mjs} +236 -5
  27. package/packages/core/dist/chunk-KDDU2R5P.mjs.map +1 -0
  28. package/packages/core/dist/{chunk-E5F2LQCX.mjs → chunk-T5MASTIW.mjs} +15 -4
  29. package/packages/core/dist/chunk-T5MASTIW.mjs.map +1 -0
  30. package/packages/core/dist/{chunk-KNYL56KZ.mjs → chunk-UOPVGCOB.mjs} +3 -3
  31. package/packages/core/dist/{chunk-KNYL56KZ.mjs.map → chunk-UOPVGCOB.mjs.map} +1 -1
  32. package/packages/core/dist/diff.cjs +4 -0
  33. package/packages/core/dist/diff.cjs.map +1 -1
  34. package/packages/core/dist/diff.mjs +4 -0
  35. package/packages/core/dist/diff.mjs.map +1 -1
  36. package/packages/core/dist/exporters.cjs +145 -133
  37. package/packages/core/dist/exporters.cjs.map +1 -1
  38. package/packages/core/dist/exporters.d.cts +3 -2
  39. package/packages/core/dist/exporters.d.ts +3 -2
  40. package/packages/core/dist/exporters.mjs +10 -5
  41. package/packages/core/dist/exporters.mjs.map +1 -1
  42. package/packages/core/dist/logs.cjs +16 -4
  43. package/packages/core/dist/logs.cjs.map +1 -1
  44. package/packages/core/dist/logs.mjs +5 -4
  45. package/packages/core/dist/logs.mjs.map +1 -1
  46. package/packages/core/dist/persisted.cjs +13 -2
  47. package/packages/core/dist/persisted.cjs.map +1 -1
  48. package/packages/core/dist/persisted.mjs +3 -3
  49. package/packages/core/dist/readers.cjs +13 -2
  50. package/packages/core/dist/readers.cjs.map +1 -1
  51. package/packages/core/dist/readers.mjs +3 -3
  52. package/packages/cli/dist/chunk-M6PC5KUT.mjs.map +0 -1
  53. package/packages/core/dist/chunk-3USJVBLA.mjs.map +0 -1
  54. package/packages/core/dist/chunk-E5F2LQCX.mjs.map +0 -1
  55. package/packages/core/dist/chunk-EWHN6NA4.mjs.map +0 -1
@@ -2225,6 +2225,210 @@ var init_trace_filter = __esm({
2225
2225
  }
2226
2226
  });
2227
2227
 
2228
+ // packages/core/src/stats.ts
2229
+ function percentile(sorted, p) {
2230
+ if (sorted.length === 0) return void 0;
2231
+ const idx = Math.min(
2232
+ sorted.length - 1,
2233
+ Math.max(0, Math.ceil(p / 100 * sorted.length) - 1)
2234
+ );
2235
+ return sorted[idx];
2236
+ }
2237
+ async function readRunStartedMetadata(filePath) {
2238
+ try {
2239
+ const events = await readTraceEventsFromFile(filePath);
2240
+ for (const event of events) {
2241
+ if (event.event !== "run_started") continue;
2242
+ const rs = event;
2243
+ if (rs.metadata && typeof rs.metadata === "object") {
2244
+ return rs.metadata;
2245
+ }
2246
+ return void 0;
2247
+ }
2248
+ } catch {
2249
+ }
2250
+ return void 0;
2251
+ }
2252
+ function metaMatchesCorrelation(metadata, correlationId, groupId) {
2253
+ if (correlationId) {
2254
+ const v = metadata?.correlationId;
2255
+ if (typeof v !== "string" || v !== correlationId) return false;
2256
+ }
2257
+ if (groupId) {
2258
+ const v = metadata?.groupId;
2259
+ if (typeof v !== "string" || v !== groupId) return false;
2260
+ }
2261
+ return true;
2262
+ }
2263
+ async function buildTraceStats(metas, options) {
2264
+ let filtered = filterTraces(metas, { since: options.since });
2265
+ if (options.correlationId || options.groupId) {
2266
+ const next = [];
2267
+ for (const m of filtered) {
2268
+ const md = await readRunStartedMetadata(m.filePath);
2269
+ if (metaMatchesCorrelation(md, options.correlationId, options.groupId)) {
2270
+ next.push(m);
2271
+ }
2272
+ }
2273
+ filtered = next;
2274
+ }
2275
+ let successCount = 0;
2276
+ let errorCount = 0;
2277
+ let runningCount = 0;
2278
+ let unknownCount = 0;
2279
+ const durations = [];
2280
+ let totalSteps = 0;
2281
+ let totalLlmSteps = 0;
2282
+ let totalToolSteps = 0;
2283
+ let totalErrorSteps = 0;
2284
+ const slowestRuns = [];
2285
+ const slowestSteps = [];
2286
+ for (const m of filtered) {
2287
+ if (m.status === "success") successCount += 1;
2288
+ else if (m.status === "error") errorCount += 1;
2289
+ else if (m.status === "running") runningCount += 1;
2290
+ else unknownCount += 1;
2291
+ if (typeof m.durationMs === "number" && Number.isFinite(m.durationMs) && m.durationMs >= 0) {
2292
+ durations.push(m.durationMs);
2293
+ slowestRuns.push({
2294
+ runId: m.runId,
2295
+ name: m.name,
2296
+ durationMs: m.durationMs,
2297
+ status: m.status
2298
+ });
2299
+ }
2300
+ try {
2301
+ const events = await readTraceEventsFromFile(m.filePath);
2302
+ if (events.length === 0) continue;
2303
+ const summary = buildRunSummary(events);
2304
+ totalSteps += summary.totalSteps;
2305
+ totalLlmSteps += summary.llmSteps;
2306
+ totalToolSteps += summary.toolSteps;
2307
+ totalErrorSteps += summary.errorSteps;
2308
+ const steps = collectCompletedSteps(events, m.runId);
2309
+ for (const s of steps) {
2310
+ slowestSteps.push(s);
2311
+ }
2312
+ } catch {
2313
+ }
2314
+ }
2315
+ slowestRuns.sort((a, b) => (b.durationMs ?? 0) - (a.durationMs ?? 0));
2316
+ slowestSteps.sort((a, b) => b.durationMs - a.durationMs);
2317
+ const runLimit = options.slowRunLimit ?? 5;
2318
+ const stepLimit = options.slowStepLimit ?? 5;
2319
+ const sortedDur = [...durations].sort((a, b) => a - b);
2320
+ const totalRuns = filtered.length;
2321
+ const errorRate = totalRuns > 0 ? errorCount / totalRuns : 0;
2322
+ const sumDur = durations.reduce((a, b) => a + b, 0);
2323
+ return {
2324
+ traceDir: options.traceDir,
2325
+ ...options.since ? { since: options.since } : {},
2326
+ ...options.correlationId ? { correlationId: options.correlationId } : {},
2327
+ ...options.groupId ? { groupId: options.groupId } : {},
2328
+ totalRuns,
2329
+ successCount,
2330
+ errorCount,
2331
+ runningCount,
2332
+ unknownCount,
2333
+ errorRate,
2334
+ duration: {
2335
+ ...sortedDur.length > 0 ? {
2336
+ minMs: sortedDur[0],
2337
+ maxMs: sortedDur[sortedDur.length - 1],
2338
+ avgMs: sumDur / sortedDur.length,
2339
+ p50Ms: percentile(sortedDur, 50),
2340
+ p95Ms: percentile(sortedDur, 95)
2341
+ } : {}
2342
+ },
2343
+ totalSteps,
2344
+ avgStepsPerRun: totalRuns > 0 ? totalSteps / totalRuns : 0,
2345
+ totalLlmSteps,
2346
+ totalToolSteps,
2347
+ totalErrorSteps,
2348
+ slowestRuns: slowestRuns.slice(0, runLimit),
2349
+ slowestSteps: slowestSteps.slice(0, stepLimit)
2350
+ };
2351
+ }
2352
+ function collectCompletedSteps(events, runId) {
2353
+ const started = /* @__PURE__ */ new Map();
2354
+ const out = [];
2355
+ for (const e of events) {
2356
+ if (e.event === "step_started") {
2357
+ const s = e;
2358
+ started.set(s.stepId, { name: s.name, type: s.type });
2359
+ }
2360
+ if (e.event === "step_completed") {
2361
+ const c = e;
2362
+ if (c.status !== "success" && c.status !== "error") continue;
2363
+ if (typeof c.durationMs !== "number" || !Number.isFinite(c.durationMs)) {
2364
+ continue;
2365
+ }
2366
+ const meta2 = started.get(c.stepId);
2367
+ out.push({
2368
+ runId,
2369
+ stepName: meta2?.name ?? c.stepId,
2370
+ stepType: meta2?.type ?? "logic",
2371
+ durationMs: c.durationMs
2372
+ });
2373
+ }
2374
+ }
2375
+ return out;
2376
+ }
2377
+ function formatStepLabel(stepType, stepName) {
2378
+ return stepName.startsWith(`${stepType}:`) ? stepName : `${stepType}:${stepName}`;
2379
+ }
2380
+ function renderTraceStats(stats) {
2381
+ const lines = [];
2382
+ lines.push("Trace stats (local)");
2383
+ lines.push(`Directory: ${stats.traceDir}`);
2384
+ if (stats.since) lines.push(`Since: ${stats.since}`);
2385
+ if (stats.correlationId) lines.push(`Correlation ID: ${stats.correlationId}`);
2386
+ if (stats.groupId) lines.push(`Group ID: ${stats.groupId}`);
2387
+ lines.push("");
2388
+ lines.push(`Runs: ${stats.totalRuns}`);
2389
+ lines.push(
2390
+ ` success: ${stats.successCount} error: ${stats.errorCount} running: ${stats.runningCount} unknown: ${stats.unknownCount}`
2391
+ );
2392
+ lines.push(`Error rate: ${(stats.errorRate * 100).toFixed(1)}%`);
2393
+ if (stats.duration.avgMs !== void 0) {
2394
+ lines.push(
2395
+ `Duration: min ${formatDuration2(stats.duration.minMs ?? 0)} | avg ${formatDuration2(stats.duration.avgMs)} | p50 ${formatDuration2(stats.duration.p50Ms ?? 0)} | p95 ${formatDuration2(stats.duration.p95Ms ?? 0)} | max ${formatDuration2(stats.duration.maxMs ?? 0)}`
2396
+ );
2397
+ }
2398
+ lines.push("");
2399
+ lines.push(`Steps: ${stats.totalSteps} (avg ${stats.avgStepsPerRun.toFixed(1)} per run)`);
2400
+ lines.push(
2401
+ ` LLM: ${stats.totalLlmSteps} tool: ${stats.totalToolSteps} errors: ${stats.totalErrorSteps}`
2402
+ );
2403
+ if (stats.slowestRuns.length > 0) {
2404
+ lines.push("");
2405
+ lines.push("Slowest runs:");
2406
+ for (const r of stats.slowestRuns) {
2407
+ lines.push(
2408
+ ` ${r.runId} | ${r.name ?? "-"} | ${formatDuration2(r.durationMs ?? 0)} | ${r.status}`
2409
+ );
2410
+ }
2411
+ }
2412
+ if (stats.slowestSteps.length > 0) {
2413
+ lines.push("");
2414
+ lines.push("Slowest steps:");
2415
+ for (const s of stats.slowestSteps) {
2416
+ lines.push(
2417
+ ` ${s.runId} | ${formatStepLabel(s.stepType, s.stepName)} | ${formatDuration2(s.durationMs)}`
2418
+ );
2419
+ }
2420
+ }
2421
+ return lines.join("\n");
2422
+ }
2423
+ var init_stats = __esm({
2424
+ "packages/core/src/stats.ts"() {
2425
+ init_trace_metadata();
2426
+ init_trace_filter();
2427
+ init_storage();
2428
+ init_utils();
2429
+ }
2430
+ });
2431
+
2228
2432
  // packages/core/src/timeline.ts
2229
2433
  function finite(n) {
2230
2434
  return typeof n === "number" && Number.isFinite(n);
@@ -2382,7 +2586,7 @@ function renderTimeline(timeline, options = {}) {
2382
2586
  const dur = e.durationMs !== void 0 ? formatDuration2(e.durationMs) : "-";
2383
2587
  const err = e.isError ? " error" : "";
2384
2588
  const off = formatDuration2(e.offsetMs);
2385
- let line = `${prefix}+${off} ${typeTag}:${e.name} (${dur})${err}`;
2589
+ let line = `${prefix}+${off} ${formatStepLabel(typeTag, e.name)} (${dur})${err}`;
2386
2590
  if (e.streaming?.chunkCount !== void 0) {
2387
2591
  line += ` chunks=${e.streaming.chunkCount}`;
2388
2592
  }
@@ -2395,6 +2599,7 @@ function renderTimeline(timeline, options = {}) {
2395
2599
  }
2396
2600
  var init_timeline = __esm({
2397
2601
  "packages/core/src/timeline.ts"() {
2602
+ init_stats();
2398
2603
  init_utils();
2399
2604
  }
2400
2605
  });
@@ -2545,6 +2750,12 @@ var init_what = __esm({
2545
2750
  });
2546
2751
 
2547
2752
  // packages/core/src/explain.ts
2753
+ function toDisplayStatus(status) {
2754
+ if (status === "ok") return "success";
2755
+ if (status === "error") return "error";
2756
+ if (status === "running") return "running";
2757
+ return "unknown";
2758
+ }
2548
2759
  function flatten(nodes, out = []) {
2549
2760
  for (const node of nodes) {
2550
2761
  out.push({ node, index: out.length + 1 });
@@ -2602,7 +2813,7 @@ function buildFacts(run, redactor) {
2602
2813
  const facts = [
2603
2814
  fact("run.id", "Run id", run.runId, redactor),
2604
2815
  fact("run.name", "Run name", run.name ?? run.runId, redactor),
2605
- fact("run.status", "Run status", run.status ?? "unknown", redactor),
2816
+ fact("run.status", "Run status", toDisplayStatus(run.status), redactor),
2606
2817
  fact("run.totalEvents", "Total events", run.metadata.totalEvents, redactor),
2607
2818
  fact("run.stepCount", "Top-level step count", run.children.length, redactor),
2608
2819
  fact("run.nodeCount", "Total node count", nodes.length, redactor),
@@ -2678,7 +2889,7 @@ function buildLocalExplanation(run, options = {}) {
2678
2889
  mode,
2679
2890
  runId: String(redactValue(redactor, "runId", run.runId)),
2680
2891
  ...run.name !== void 0 ? { name: String(redactValue(redactor, "name", run.name)) } : {},
2681
- ...run.status !== void 0 ? { status: run.status } : {},
2892
+ ...run.status !== void 0 ? { status: toDisplayStatus(run.status) } : {},
2682
2893
  redactionProfile,
2683
2894
  facts,
2684
2895
  inferences: mode === "dry-run" ? [] : buildInferences(run, facts),
@@ -2695,207 +2906,6 @@ var init_explain = __esm({
2695
2906
  }
2696
2907
  });
2697
2908
 
2698
- // packages/core/src/stats.ts
2699
- function percentile(sorted, p) {
2700
- if (sorted.length === 0) return void 0;
2701
- const idx = Math.min(
2702
- sorted.length - 1,
2703
- Math.max(0, Math.ceil(p / 100 * sorted.length) - 1)
2704
- );
2705
- return sorted[idx];
2706
- }
2707
- async function readRunStartedMetadata(filePath) {
2708
- try {
2709
- const events = await readTraceEventsFromFile(filePath);
2710
- for (const event of events) {
2711
- if (event.event !== "run_started") continue;
2712
- const rs = event;
2713
- if (rs.metadata && typeof rs.metadata === "object") {
2714
- return rs.metadata;
2715
- }
2716
- return void 0;
2717
- }
2718
- } catch {
2719
- }
2720
- return void 0;
2721
- }
2722
- function metaMatchesCorrelation(metadata, correlationId, groupId) {
2723
- if (correlationId) {
2724
- const v = metadata?.correlationId;
2725
- if (typeof v !== "string" || v !== correlationId) return false;
2726
- }
2727
- if (groupId) {
2728
- const v = metadata?.groupId;
2729
- if (typeof v !== "string" || v !== groupId) return false;
2730
- }
2731
- return true;
2732
- }
2733
- async function buildTraceStats(metas, options) {
2734
- let filtered = filterTraces(metas, { since: options.since });
2735
- if (options.correlationId || options.groupId) {
2736
- const next = [];
2737
- for (const m of filtered) {
2738
- const md = await readRunStartedMetadata(m.filePath);
2739
- if (metaMatchesCorrelation(md, options.correlationId, options.groupId)) {
2740
- next.push(m);
2741
- }
2742
- }
2743
- filtered = next;
2744
- }
2745
- let successCount = 0;
2746
- let errorCount = 0;
2747
- let runningCount = 0;
2748
- let unknownCount = 0;
2749
- const durations = [];
2750
- let totalSteps = 0;
2751
- let totalLlmSteps = 0;
2752
- let totalToolSteps = 0;
2753
- let totalErrorSteps = 0;
2754
- const slowestRuns = [];
2755
- const slowestSteps = [];
2756
- for (const m of filtered) {
2757
- if (m.status === "success") successCount += 1;
2758
- else if (m.status === "error") errorCount += 1;
2759
- else if (m.status === "running") runningCount += 1;
2760
- else unknownCount += 1;
2761
- if (typeof m.durationMs === "number" && Number.isFinite(m.durationMs) && m.durationMs >= 0) {
2762
- durations.push(m.durationMs);
2763
- slowestRuns.push({
2764
- runId: m.runId,
2765
- name: m.name,
2766
- durationMs: m.durationMs,
2767
- status: m.status
2768
- });
2769
- }
2770
- try {
2771
- const events = await readTraceEventsFromFile(m.filePath);
2772
- if (events.length === 0) continue;
2773
- const summary = buildRunSummary(events);
2774
- totalSteps += summary.totalSteps;
2775
- totalLlmSteps += summary.llmSteps;
2776
- totalToolSteps += summary.toolSteps;
2777
- totalErrorSteps += summary.errorSteps;
2778
- const steps = collectCompletedSteps(events, m.runId);
2779
- for (const s of steps) {
2780
- slowestSteps.push(s);
2781
- }
2782
- } catch {
2783
- }
2784
- }
2785
- slowestRuns.sort((a, b) => (b.durationMs ?? 0) - (a.durationMs ?? 0));
2786
- slowestSteps.sort((a, b) => b.durationMs - a.durationMs);
2787
- const runLimit = options.slowRunLimit ?? 5;
2788
- const stepLimit = options.slowStepLimit ?? 5;
2789
- const sortedDur = [...durations].sort((a, b) => a - b);
2790
- const totalRuns = filtered.length;
2791
- const errorRate = totalRuns > 0 ? errorCount / totalRuns : 0;
2792
- const sumDur = durations.reduce((a, b) => a + b, 0);
2793
- return {
2794
- traceDir: options.traceDir,
2795
- ...options.since ? { since: options.since } : {},
2796
- ...options.correlationId ? { correlationId: options.correlationId } : {},
2797
- ...options.groupId ? { groupId: options.groupId } : {},
2798
- totalRuns,
2799
- successCount,
2800
- errorCount,
2801
- runningCount,
2802
- unknownCount,
2803
- errorRate,
2804
- duration: {
2805
- ...sortedDur.length > 0 ? {
2806
- minMs: sortedDur[0],
2807
- maxMs: sortedDur[sortedDur.length - 1],
2808
- avgMs: sumDur / sortedDur.length,
2809
- p50Ms: percentile(sortedDur, 50),
2810
- p95Ms: percentile(sortedDur, 95)
2811
- } : {}
2812
- },
2813
- totalSteps,
2814
- avgStepsPerRun: totalRuns > 0 ? totalSteps / totalRuns : 0,
2815
- totalLlmSteps,
2816
- totalToolSteps,
2817
- totalErrorSteps,
2818
- slowestRuns: slowestRuns.slice(0, runLimit),
2819
- slowestSteps: slowestSteps.slice(0, stepLimit)
2820
- };
2821
- }
2822
- function collectCompletedSteps(events, runId) {
2823
- const started = /* @__PURE__ */ new Map();
2824
- const out = [];
2825
- for (const e of events) {
2826
- if (e.event === "step_started") {
2827
- const s = e;
2828
- started.set(s.stepId, { name: s.name, type: s.type });
2829
- }
2830
- if (e.event === "step_completed") {
2831
- const c = e;
2832
- if (c.status !== "success" && c.status !== "error") continue;
2833
- if (typeof c.durationMs !== "number" || !Number.isFinite(c.durationMs)) {
2834
- continue;
2835
- }
2836
- const meta2 = started.get(c.stepId);
2837
- out.push({
2838
- runId,
2839
- stepName: meta2?.name ?? c.stepId,
2840
- stepType: meta2?.type ?? "logic",
2841
- durationMs: c.durationMs
2842
- });
2843
- }
2844
- }
2845
- return out;
2846
- }
2847
- function renderTraceStats(stats) {
2848
- const lines = [];
2849
- lines.push("Trace stats (local)");
2850
- lines.push(`Directory: ${stats.traceDir}`);
2851
- if (stats.since) lines.push(`Since: ${stats.since}`);
2852
- if (stats.correlationId) lines.push(`Correlation ID: ${stats.correlationId}`);
2853
- if (stats.groupId) lines.push(`Group ID: ${stats.groupId}`);
2854
- lines.push("");
2855
- lines.push(`Runs: ${stats.totalRuns}`);
2856
- lines.push(
2857
- ` success: ${stats.successCount} error: ${stats.errorCount} running: ${stats.runningCount} unknown: ${stats.unknownCount}`
2858
- );
2859
- lines.push(`Error rate: ${(stats.errorRate * 100).toFixed(1)}%`);
2860
- if (stats.duration.avgMs !== void 0) {
2861
- lines.push(
2862
- `Duration: min ${formatDuration2(stats.duration.minMs ?? 0)} | avg ${formatDuration2(stats.duration.avgMs)} | p50 ${formatDuration2(stats.duration.p50Ms ?? 0)} | p95 ${formatDuration2(stats.duration.p95Ms ?? 0)} | max ${formatDuration2(stats.duration.maxMs ?? 0)}`
2863
- );
2864
- }
2865
- lines.push("");
2866
- lines.push(`Steps: ${stats.totalSteps} (avg ${stats.avgStepsPerRun.toFixed(1)} per run)`);
2867
- lines.push(
2868
- ` LLM: ${stats.totalLlmSteps} tool: ${stats.totalToolSteps} errors: ${stats.totalErrorSteps}`
2869
- );
2870
- if (stats.slowestRuns.length > 0) {
2871
- lines.push("");
2872
- lines.push("Slowest runs:");
2873
- for (const r of stats.slowestRuns) {
2874
- lines.push(
2875
- ` ${r.runId} | ${r.name ?? "-"} | ${formatDuration2(r.durationMs ?? 0)} | ${r.status}`
2876
- );
2877
- }
2878
- }
2879
- if (stats.slowestSteps.length > 0) {
2880
- lines.push("");
2881
- lines.push("Slowest steps:");
2882
- for (const s of stats.slowestSteps) {
2883
- lines.push(
2884
- ` ${s.runId} | ${s.stepType}:${s.stepName} | ${formatDuration2(s.durationMs)}`
2885
- );
2886
- }
2887
- }
2888
- return lines.join("\n");
2889
- }
2890
- var init_stats = __esm({
2891
- "packages/core/src/stats.ts"() {
2892
- init_trace_metadata();
2893
- init_trace_filter();
2894
- init_storage();
2895
- init_utils();
2896
- }
2897
- });
2898
-
2899
2909
  // packages/core/src/search.ts
2900
2910
  function parseDurationFilter(expr) {
2901
2911
  const raw = expr.trim();
@@ -2962,6 +2972,12 @@ async function searchTraces(metas, options) {
2962
2972
  ...sessionLabel ? { sessionId: sessionLabel } : {}
2963
2973
  });
2964
2974
  }
2975
+ results.sort((a, b) => {
2976
+ const ta = a.timestamp ?? 0;
2977
+ const tb = b.timestamp ?? 0;
2978
+ if (ta !== tb) return tb - ta;
2979
+ return a.runId.localeCompare(b.runId);
2980
+ });
2965
2981
  return results.slice(0, limit);
2966
2982
  }
2967
2983
  for (const m of filtered) {
@@ -3009,7 +3025,7 @@ async function searchTraces(metas, options) {
3009
3025
  results.sort((a, b) => {
3010
3026
  const ta = a.timestamp ?? 0;
3011
3027
  const tb = b.timestamp ?? 0;
3012
- if (ta !== tb) return ta - tb;
3028
+ if (ta !== tb) return tb - ta;
3013
3029
  const runCmp = a.runId.localeCompare(b.runId);
3014
3030
  if (runCmp !== 0) return runCmp;
3015
3031
  return (a.stepName ?? "").localeCompare(b.stepName ?? "");
@@ -6213,13 +6229,24 @@ function inc(map, key) {
6213
6229
  map[key] = (map[key] ?? 0) + 1;
6214
6230
  }
6215
6231
  function computeRunStatus(events) {
6232
+ let runTerminal;
6233
+ let sawRunEvent = false;
6234
+ for (const e of events) {
6235
+ if (e.kind !== "RUN") continue;
6236
+ sawRunEvent = true;
6237
+ if (e.status === "ok" || e.status === "error") {
6238
+ runTerminal = e.status;
6239
+ }
6240
+ }
6241
+ if (sawRunEvent) {
6242
+ return runTerminal ?? "running";
6243
+ }
6216
6244
  let hasRunning = false;
6217
6245
  for (const e of events) {
6218
6246
  if (e.status === "error") return "error";
6219
6247
  if (e.status === "running") hasRunning = true;
6220
6248
  }
6221
- if (hasRunning) return "running";
6222
- return "ok";
6249
+ return hasRunning ? "running" : "ok";
6223
6250
  }
6224
6251
  var TreeBuilder;
6225
6252
  var init_tree_builder = __esm({
@@ -8489,7 +8516,9 @@ function compareCohortAggregates(groups, options) {
8489
8516
  metric,
8490
8517
  "Average duration (ms)",
8491
8518
  baselineAgg?.avgDurationMs,
8492
- candidateAgg?.avgDurationMs
8519
+ candidateAgg?.avgDurationMs,
8520
+ true,
8521
+ tolerance
8493
8522
  );
8494
8523
  if (item) comparisons.push(item);
8495
8524
  break;
@@ -8499,7 +8528,9 @@ function compareCohortAggregates(groups, options) {
8499
8528
  metric,
8500
8529
  "Average LLM calls",
8501
8530
  baselineAgg?.avgLlmCallCount,
8502
- candidateAgg?.avgLlmCallCount
8531
+ candidateAgg?.avgLlmCallCount,
8532
+ true,
8533
+ tolerance
8503
8534
  );
8504
8535
  if (item) comparisons.push(item);
8505
8536
  break;
@@ -8509,7 +8540,9 @@ function compareCohortAggregates(groups, options) {
8509
8540
  metric,
8510
8541
  "Average token usage",
8511
8542
  baselineAgg?.avgTokenUsage,
8512
- candidateAgg?.avgTokenUsage
8543
+ candidateAgg?.avgTokenUsage,
8544
+ true,
8545
+ tolerance
8513
8546
  );
8514
8547
  if (item) comparisons.push(item);
8515
8548
  break;
@@ -8519,7 +8552,9 @@ function compareCohortAggregates(groups, options) {
8519
8552
  metric,
8520
8553
  "Average retries",
8521
8554
  baselineAgg?.avgRetryCount,
8522
- candidateAgg?.avgRetryCount
8555
+ candidateAgg?.avgRetryCount,
8556
+ true,
8557
+ tolerance
8523
8558
  );
8524
8559
  if (item) comparisons.push(item);
8525
8560
  break;
@@ -8529,7 +8564,9 @@ function compareCohortAggregates(groups, options) {
8529
8564
  metric,
8530
8565
  "Observation failure rate",
8531
8566
  baselineAgg?.observationFailureRate,
8532
- candidateAgg?.observationFailureRate
8567
+ candidateAgg?.observationFailureRate,
8568
+ true,
8569
+ tolerance
8533
8570
  );
8534
8571
  if (item) comparisons.push(item);
8535
8572
  break;
@@ -8565,7 +8602,9 @@ function compareCohortAggregates(groups, options) {
8565
8602
  metric,
8566
8603
  "Guardrail failures",
8567
8604
  baselineAgg?.avgGuardrailFailures,
8568
- candidateAgg?.avgGuardrailFailures
8605
+ candidateAgg?.avgGuardrailFailures,
8606
+ true,
8607
+ tolerance
8569
8608
  );
8570
8609
  if (item) comparisons.push(item);
8571
8610
  break;
@@ -8575,7 +8614,9 @@ function compareCohortAggregates(groups, options) {
8575
8614
  metric,
8576
8615
  "Circuit violations",
8577
8616
  baselineAgg?.avgCircuitViolations,
8578
- candidateAgg?.avgCircuitViolations
8617
+ candidateAgg?.avgCircuitViolations,
8618
+ true,
8619
+ tolerance
8579
8620
  );
8580
8621
  if (item) comparisons.push(item);
8581
8622
  break;
@@ -8585,7 +8626,9 @@ function compareCohortAggregates(groups, options) {
8585
8626
  metric,
8586
8627
  "Redaction warnings",
8587
8628
  baselineAgg?.avgRedactionWarnings,
8588
- candidateAgg?.avgRedactionWarnings
8629
+ candidateAgg?.avgRedactionWarnings,
8630
+ true,
8631
+ tolerance
8589
8632
  );
8590
8633
  if (item) comparisons.push(item);
8591
8634
  break;
@@ -9677,7 +9720,7 @@ var require_bindings = __commonJS({
9677
9720
  "node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js"(exports$1, module) {
9678
9721
  var fs = __require("fs");
9679
9722
  var path37 = __require("path");
9680
- var fileURLToPath2 = require_file_uri_to_path();
9723
+ var fileURLToPath3 = require_file_uri_to_path();
9681
9724
  var join = path37.join;
9682
9725
  var dirname = path37.dirname;
9683
9726
  var exists2 = fs.accessSync && function(path38) {
@@ -9789,7 +9832,7 @@ var require_bindings = __commonJS({
9789
9832
  Error.stackTraceLimit = origSTL;
9790
9833
  var fileSchema = "file://";
9791
9834
  if (fileName.indexOf(fileSchema) === 0) {
9792
- fileName = fileURLToPath2(fileName);
9835
+ fileName = fileURLToPath3(fileName);
9793
9836
  }
9794
9837
  return fileName;
9795
9838
  };
@@ -10788,7 +10831,7 @@ var init_src = __esm({
10788
10831
  });
10789
10832
 
10790
10833
  // package.json
10791
- var version = "6.7.2";
10834
+ var version = "6.7.4";
10792
10835
 
10793
10836
  // packages/cli/src/list.ts
10794
10837
  init_advanced();
@@ -11749,13 +11792,14 @@ function parseTimestamp(v) {
11749
11792
  function hasToken(hay, token) {
11750
11793
  return hay.includes(token);
11751
11794
  }
11795
+ var ERROR_TOKEN_RE = /\.(error|failed)(\.|$)/;
11752
11796
  function inferKind(eventName) {
11753
11797
  if (hasToken(eventName, ".llm.")) return "LLM";
11754
11798
  if (hasToken(eventName, ".tool.")) return "TOOL";
11755
11799
  if (hasToken(eventName, ".agent.")) return "AGENT";
11756
11800
  if (hasToken(eventName, ".retriever.")) return "RETRIEVER";
11757
11801
  if (hasToken(eventName, ".result.")) return "RESULT";
11758
- if (eventName.endsWith(".error") || eventName.endsWith(".failed") || eventName.includes(".error") || eventName.includes(".failed")) {
11802
+ if (ERROR_TOKEN_RE.test(eventName)) {
11759
11803
  return "ERROR";
11760
11804
  }
11761
11805
  return "LOG";
@@ -11835,7 +11879,7 @@ var EventNormalizer = class {
11835
11879
  status = mapping.status;
11836
11880
  } else if (mapping?.kind === "ERROR") {
11837
11881
  status = "error";
11838
- } else if (eventName.includes(".failed") || eventName.includes(".error")) {
11882
+ } else if (ERROR_TOKEN_RE.test(eventName)) {
11839
11883
  status = "error";
11840
11884
  } else if (mapping?.startsRun || mapping?.startsStep) {
11841
11885
  status = "running";
@@ -13038,6 +13082,11 @@ init_helpers();
13038
13082
  function hexFrom(seed, byteLen) {
13039
13083
  return crypto__default.default.createHash("sha256").update(seed, "utf8").digest("hex").slice(0, byteLen * 2);
13040
13084
  }
13085
+ function unixNano(ms) {
13086
+ const whole = Math.trunc(ms);
13087
+ const fractionNs = Math.round((ms - whole) * 1e6);
13088
+ return BigInt(whole) * 1000000n + BigInt(fractionNs);
13089
+ }
13041
13090
  function mapInspectKindToOI(kind, warnings) {
13042
13091
  switch (kind) {
13043
13092
  case "LLM":
@@ -13087,10 +13136,10 @@ function exportOpenInference(tree, options) {
13087
13136
  const ev = n.event;
13088
13137
  const spanId = hexFrom(`${tree.runId}:${ev.eventId}`, 8);
13089
13138
  const parentSpanHex = ev.parentId ? hexFrom(`${tree.runId}:${ev.parentId}`, 8) : void 0;
13090
- const startNs = Math.round(ev.timestamp * 1e6);
13139
+ const startNs = unixNano(ev.timestamp);
13091
13140
  let endNs;
13092
13141
  if (ev.durationMs !== void 0 && Number.isFinite(ev.durationMs)) {
13093
- endNs = startNs + Math.round(ev.durationMs * 1e6);
13142
+ endNs = startNs + unixNano(ev.durationMs);
13094
13143
  }
13095
13144
  const { openInferenceKind } = mapInspectKindToOI(ev.kind, warnings);
13096
13145
  const attrs = {
@@ -13138,8 +13187,8 @@ function exportOpenInference(tree, options) {
13138
13187
  span_id: spanId,
13139
13188
  parent_span_id: parentSpanHex,
13140
13189
  name: ev.name,
13141
- start_time_unix_nano: startNs,
13142
- end_time_unix_nano: endNs,
13190
+ start_time_unix_nano: startNs.toString(),
13191
+ end_time_unix_nano: endNs?.toString(),
13143
13192
  attributes: attrs,
13144
13193
  status
13145
13194
  });
@@ -13891,6 +13940,10 @@ function manualTraceEventsToComparableRun(events) {
13891
13940
  meta2 = { ...meta2 ?? {}, agent_inspect_diff_parent_missing: true };
13892
13941
  }
13893
13942
  const outputPreview = extractOutputPreview(meta2);
13943
+ if (meta2 !== void 0 && ("outputPreview" in meta2 || "resultPreview" in meta2)) {
13944
+ delete meta2.outputPreview;
13945
+ delete meta2.resultPreview;
13946
+ }
13894
13947
  const sc = {
13895
13948
  id: acc.id,
13896
13949
  name: acc.name,
@@ -14540,6 +14593,7 @@ async function searchCommand(options = {}) {
14540
14593
  console.log(`Session not found: ${sessionId}`);
14541
14594
  console.log(`Trace directory: ${traceDir}`);
14542
14595
  }
14596
+ process.exitCode = 1;
14543
14597
  return;
14544
14598
  }
14545
14599
  metas = scoped.metas;
@@ -16875,9 +16929,20 @@ function buildRules(config, options) {
16875
16929
  ...asStringArray2(checks2.select) ?? [],
16876
16930
  ...options.rule ?? []
16877
16931
  ];
16932
+ if (select.length === 0) {
16933
+ const auto = new Set(DEFAULT_SELECT);
16934
+ for (const rule of rules) {
16935
+ if (rule.id !== "run.status") auto.add(rule.id);
16936
+ }
16937
+ return {
16938
+ rules,
16939
+ select: [...auto],
16940
+ diagnostics
16941
+ };
16942
+ }
16878
16943
  return {
16879
16944
  rules,
16880
- select: select.length > 0 ? select : DEFAULT_SELECT,
16945
+ select,
16881
16946
  diagnostics
16882
16947
  };
16883
16948
  }
@@ -18127,13 +18192,11 @@ async function studioCommand(options = {}) {
18127
18192
  await new Promise(() => {
18128
18193
  });
18129
18194
  }
18130
-
18131
- // packages/eval/src/index.ts
18132
18195
  function isTraceReadResult(value) {
18133
18196
  return value !== null && typeof value === "object" && "runs" in value && "events" in value && "format" in value;
18134
18197
  }
18135
18198
  function traceInputFrom(value) {
18136
- return { type: "file", path: value instanceof URL ? value.pathname : value };
18199
+ return { type: "file", path: value instanceof URL ? url.fileURLToPath(value) : value };
18137
18200
  }
18138
18201
  async function resolveRead(input3, options) {
18139
18202
  try {
@@ -20457,7 +20520,7 @@ jobs:
20457
20520
  async function planInit(options = {}) {
20458
20521
  const framework = normalizeFramework(options.framework);
20459
20522
  const cwd = path26__default.default.resolve(options.cwd ?? process.cwd());
20460
- const demoPath = framework === "custom" ? path26__default.default.join("examples", "agent-inspect-demo.mjs") : path26__default.default.join("examples", `agent-inspect-${framework}-demo.mjs`);
20523
+ const demoPath = framework === "custom" ? "examples/agent-inspect-demo.mjs" : `examples/agent-inspect-${framework}-demo.mjs`;
20461
20524
  const candidates = [
20462
20525
  { rel: CONFIG_FILE, content: configTemplate(framework) },
20463
20526
  { rel: GITKEEP, content: "" },