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.
- package/CHANGELOG.md +21 -0
- package/README.md +1 -1
- package/docs/EXPORTS.md +9 -0
- package/docs/PERFORMANCE.md +18 -0
- package/docs/STANDARDS.md +4 -0
- package/package.json +2 -2
- package/packages/cli/dist/{chunk-M6PC5KUT.mjs → chunk-FVEQ7JFF.mjs} +251 -209
- package/packages/cli/dist/chunk-FVEQ7JFF.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +292 -229
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +35 -15
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-27LC2BB3.mjs → src-I5NA7BLK.mjs} +3 -3
- package/packages/cli/dist/{src-27LC2BB3.mjs.map → src-I5NA7BLK.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +249 -207
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +51 -250
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +56 -4
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +1 -1
- package/packages/core/dist/{chunk-X2FLDF7M.mjs → chunk-CTA6XNDP.mjs} +3 -3
- package/packages/core/dist/{chunk-X2FLDF7M.mjs.map → chunk-CTA6XNDP.mjs.map} +1 -1
- package/packages/core/dist/{chunk-EWHN6NA4.mjs → chunk-EQVXDGGU.mjs} +58 -6
- package/packages/core/dist/chunk-EQVXDGGU.mjs.map +1 -0
- package/packages/core/dist/{chunk-3USJVBLA.mjs → chunk-KDDU2R5P.mjs} +236 -5
- package/packages/core/dist/chunk-KDDU2R5P.mjs.map +1 -0
- package/packages/core/dist/{chunk-E5F2LQCX.mjs → chunk-T5MASTIW.mjs} +15 -4
- package/packages/core/dist/chunk-T5MASTIW.mjs.map +1 -0
- package/packages/core/dist/{chunk-KNYL56KZ.mjs → chunk-UOPVGCOB.mjs} +3 -3
- package/packages/core/dist/{chunk-KNYL56KZ.mjs.map → chunk-UOPVGCOB.mjs.map} +1 -1
- package/packages/core/dist/diff.cjs +4 -0
- package/packages/core/dist/diff.cjs.map +1 -1
- package/packages/core/dist/diff.mjs +4 -0
- package/packages/core/dist/diff.mjs.map +1 -1
- package/packages/core/dist/exporters.cjs +145 -133
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.d.cts +3 -2
- package/packages/core/dist/exporters.d.ts +3 -2
- package/packages/core/dist/exporters.mjs +10 -5
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/logs.cjs +16 -4
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.mjs +5 -4
- package/packages/core/dist/logs.mjs.map +1 -1
- package/packages/core/dist/persisted.cjs +13 -2
- package/packages/core/dist/persisted.cjs.map +1 -1
- package/packages/core/dist/persisted.mjs +3 -3
- package/packages/core/dist/readers.cjs +13 -2
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +3 -3
- package/packages/cli/dist/chunk-M6PC5KUT.mjs.map +0 -1
- package/packages/core/dist/chunk-3USJVBLA.mjs.map +0 -1
- package/packages/core/dist/chunk-E5F2LQCX.mjs.map +0 -1
- package/packages/core/dist/chunk-EWHN6NA4.mjs.map +0 -1
|
@@ -3394,6 +3394,202 @@ function filterTraces(traces, options) {
|
|
|
3394
3394
|
return out;
|
|
3395
3395
|
}
|
|
3396
3396
|
|
|
3397
|
+
// packages/core/src/stats.ts
|
|
3398
|
+
function percentile(sorted, p) {
|
|
3399
|
+
if (sorted.length === 0) return void 0;
|
|
3400
|
+
const idx = Math.min(
|
|
3401
|
+
sorted.length - 1,
|
|
3402
|
+
Math.max(0, Math.ceil(p / 100 * sorted.length) - 1)
|
|
3403
|
+
);
|
|
3404
|
+
return sorted[idx];
|
|
3405
|
+
}
|
|
3406
|
+
async function readRunStartedMetadata(filePath) {
|
|
3407
|
+
try {
|
|
3408
|
+
const events = await readTraceEventsFromFile(filePath);
|
|
3409
|
+
for (const event of events) {
|
|
3410
|
+
if (event.event !== "run_started") continue;
|
|
3411
|
+
const rs = event;
|
|
3412
|
+
if (rs.metadata && typeof rs.metadata === "object") {
|
|
3413
|
+
return rs.metadata;
|
|
3414
|
+
}
|
|
3415
|
+
return void 0;
|
|
3416
|
+
}
|
|
3417
|
+
} catch {
|
|
3418
|
+
}
|
|
3419
|
+
return void 0;
|
|
3420
|
+
}
|
|
3421
|
+
function metaMatchesCorrelation(metadata, correlationId, groupId) {
|
|
3422
|
+
if (correlationId) {
|
|
3423
|
+
const v = metadata?.correlationId;
|
|
3424
|
+
if (typeof v !== "string" || v !== correlationId) return false;
|
|
3425
|
+
}
|
|
3426
|
+
if (groupId) {
|
|
3427
|
+
const v = metadata?.groupId;
|
|
3428
|
+
if (typeof v !== "string" || v !== groupId) return false;
|
|
3429
|
+
}
|
|
3430
|
+
return true;
|
|
3431
|
+
}
|
|
3432
|
+
async function buildTraceStats(metas, options) {
|
|
3433
|
+
let filtered = filterTraces(metas, { since: options.since });
|
|
3434
|
+
if (options.correlationId || options.groupId) {
|
|
3435
|
+
const next = [];
|
|
3436
|
+
for (const m of filtered) {
|
|
3437
|
+
const md = await readRunStartedMetadata(m.filePath);
|
|
3438
|
+
if (metaMatchesCorrelation(md, options.correlationId, options.groupId)) {
|
|
3439
|
+
next.push(m);
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
filtered = next;
|
|
3443
|
+
}
|
|
3444
|
+
let successCount = 0;
|
|
3445
|
+
let errorCount = 0;
|
|
3446
|
+
let runningCount = 0;
|
|
3447
|
+
let unknownCount = 0;
|
|
3448
|
+
const durations = [];
|
|
3449
|
+
let totalSteps = 0;
|
|
3450
|
+
let totalLlmSteps = 0;
|
|
3451
|
+
let totalToolSteps = 0;
|
|
3452
|
+
let totalErrorSteps = 0;
|
|
3453
|
+
const slowestRuns = [];
|
|
3454
|
+
const slowestSteps = [];
|
|
3455
|
+
for (const m of filtered) {
|
|
3456
|
+
if (m.status === "success") successCount += 1;
|
|
3457
|
+
else if (m.status === "error") errorCount += 1;
|
|
3458
|
+
else if (m.status === "running") runningCount += 1;
|
|
3459
|
+
else unknownCount += 1;
|
|
3460
|
+
if (typeof m.durationMs === "number" && Number.isFinite(m.durationMs) && m.durationMs >= 0) {
|
|
3461
|
+
durations.push(m.durationMs);
|
|
3462
|
+
slowestRuns.push({
|
|
3463
|
+
runId: m.runId,
|
|
3464
|
+
name: m.name,
|
|
3465
|
+
durationMs: m.durationMs,
|
|
3466
|
+
status: m.status
|
|
3467
|
+
});
|
|
3468
|
+
}
|
|
3469
|
+
try {
|
|
3470
|
+
const events = await readTraceEventsFromFile(m.filePath);
|
|
3471
|
+
if (events.length === 0) continue;
|
|
3472
|
+
const summary = buildRunSummary(events);
|
|
3473
|
+
totalSteps += summary.totalSteps;
|
|
3474
|
+
totalLlmSteps += summary.llmSteps;
|
|
3475
|
+
totalToolSteps += summary.toolSteps;
|
|
3476
|
+
totalErrorSteps += summary.errorSteps;
|
|
3477
|
+
const steps = collectCompletedSteps(events, m.runId);
|
|
3478
|
+
for (const s of steps) {
|
|
3479
|
+
slowestSteps.push(s);
|
|
3480
|
+
}
|
|
3481
|
+
} catch {
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
slowestRuns.sort((a, b) => (b.durationMs ?? 0) - (a.durationMs ?? 0));
|
|
3485
|
+
slowestSteps.sort((a, b) => b.durationMs - a.durationMs);
|
|
3486
|
+
const runLimit = options.slowRunLimit ?? 5;
|
|
3487
|
+
const stepLimit = options.slowStepLimit ?? 5;
|
|
3488
|
+
const sortedDur = [...durations].sort((a, b) => a - b);
|
|
3489
|
+
const totalRuns = filtered.length;
|
|
3490
|
+
const errorRate = totalRuns > 0 ? errorCount / totalRuns : 0;
|
|
3491
|
+
const sumDur = durations.reduce((a, b) => a + b, 0);
|
|
3492
|
+
return {
|
|
3493
|
+
traceDir: options.traceDir,
|
|
3494
|
+
...options.since ? { since: options.since } : {},
|
|
3495
|
+
...options.correlationId ? { correlationId: options.correlationId } : {},
|
|
3496
|
+
...options.groupId ? { groupId: options.groupId } : {},
|
|
3497
|
+
totalRuns,
|
|
3498
|
+
successCount,
|
|
3499
|
+
errorCount,
|
|
3500
|
+
runningCount,
|
|
3501
|
+
unknownCount,
|
|
3502
|
+
errorRate,
|
|
3503
|
+
duration: {
|
|
3504
|
+
...sortedDur.length > 0 ? {
|
|
3505
|
+
minMs: sortedDur[0],
|
|
3506
|
+
maxMs: sortedDur[sortedDur.length - 1],
|
|
3507
|
+
avgMs: sumDur / sortedDur.length,
|
|
3508
|
+
p50Ms: percentile(sortedDur, 50),
|
|
3509
|
+
p95Ms: percentile(sortedDur, 95)
|
|
3510
|
+
} : {}
|
|
3511
|
+
},
|
|
3512
|
+
totalSteps,
|
|
3513
|
+
avgStepsPerRun: totalRuns > 0 ? totalSteps / totalRuns : 0,
|
|
3514
|
+
totalLlmSteps,
|
|
3515
|
+
totalToolSteps,
|
|
3516
|
+
totalErrorSteps,
|
|
3517
|
+
slowestRuns: slowestRuns.slice(0, runLimit),
|
|
3518
|
+
slowestSteps: slowestSteps.slice(0, stepLimit)
|
|
3519
|
+
};
|
|
3520
|
+
}
|
|
3521
|
+
function collectCompletedSteps(events, runId) {
|
|
3522
|
+
const started = /* @__PURE__ */ new Map();
|
|
3523
|
+
const out = [];
|
|
3524
|
+
for (const e of events) {
|
|
3525
|
+
if (e.event === "step_started") {
|
|
3526
|
+
const s = e;
|
|
3527
|
+
started.set(s.stepId, { name: s.name, type: s.type });
|
|
3528
|
+
}
|
|
3529
|
+
if (e.event === "step_completed") {
|
|
3530
|
+
const c = e;
|
|
3531
|
+
if (c.status !== "success" && c.status !== "error") continue;
|
|
3532
|
+
if (typeof c.durationMs !== "number" || !Number.isFinite(c.durationMs)) {
|
|
3533
|
+
continue;
|
|
3534
|
+
}
|
|
3535
|
+
const meta = started.get(c.stepId);
|
|
3536
|
+
out.push({
|
|
3537
|
+
runId,
|
|
3538
|
+
stepName: meta?.name ?? c.stepId,
|
|
3539
|
+
stepType: meta?.type ?? "logic",
|
|
3540
|
+
durationMs: c.durationMs
|
|
3541
|
+
});
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
return out;
|
|
3545
|
+
}
|
|
3546
|
+
function formatStepLabel(stepType, stepName) {
|
|
3547
|
+
return stepName.startsWith(`${stepType}:`) ? stepName : `${stepType}:${stepName}`;
|
|
3548
|
+
}
|
|
3549
|
+
function renderTraceStats(stats) {
|
|
3550
|
+
const lines = [];
|
|
3551
|
+
lines.push("Trace stats (local)");
|
|
3552
|
+
lines.push(`Directory: ${stats.traceDir}`);
|
|
3553
|
+
if (stats.since) lines.push(`Since: ${stats.since}`);
|
|
3554
|
+
if (stats.correlationId) lines.push(`Correlation ID: ${stats.correlationId}`);
|
|
3555
|
+
if (stats.groupId) lines.push(`Group ID: ${stats.groupId}`);
|
|
3556
|
+
lines.push("");
|
|
3557
|
+
lines.push(`Runs: ${stats.totalRuns}`);
|
|
3558
|
+
lines.push(
|
|
3559
|
+
` success: ${stats.successCount} error: ${stats.errorCount} running: ${stats.runningCount} unknown: ${stats.unknownCount}`
|
|
3560
|
+
);
|
|
3561
|
+
lines.push(`Error rate: ${(stats.errorRate * 100).toFixed(1)}%`);
|
|
3562
|
+
if (stats.duration.avgMs !== void 0) {
|
|
3563
|
+
lines.push(
|
|
3564
|
+
`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)}`
|
|
3565
|
+
);
|
|
3566
|
+
}
|
|
3567
|
+
lines.push("");
|
|
3568
|
+
lines.push(`Steps: ${stats.totalSteps} (avg ${stats.avgStepsPerRun.toFixed(1)} per run)`);
|
|
3569
|
+
lines.push(
|
|
3570
|
+
` LLM: ${stats.totalLlmSteps} tool: ${stats.totalToolSteps} errors: ${stats.totalErrorSteps}`
|
|
3571
|
+
);
|
|
3572
|
+
if (stats.slowestRuns.length > 0) {
|
|
3573
|
+
lines.push("");
|
|
3574
|
+
lines.push("Slowest runs:");
|
|
3575
|
+
for (const r of stats.slowestRuns) {
|
|
3576
|
+
lines.push(
|
|
3577
|
+
` ${r.runId} | ${r.name ?? "-"} | ${formatDuration2(r.durationMs ?? 0)} | ${r.status}`
|
|
3578
|
+
);
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
if (stats.slowestSteps.length > 0) {
|
|
3582
|
+
lines.push("");
|
|
3583
|
+
lines.push("Slowest steps:");
|
|
3584
|
+
for (const s of stats.slowestSteps) {
|
|
3585
|
+
lines.push(
|
|
3586
|
+
` ${s.runId} | ${formatStepLabel(s.stepType, s.stepName)} | ${formatDuration2(s.durationMs)}`
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
return lines.join("\n");
|
|
3591
|
+
}
|
|
3592
|
+
|
|
3397
3593
|
// packages/core/src/timeline.ts
|
|
3398
3594
|
function finite(n) {
|
|
3399
3595
|
return typeof n === "number" && Number.isFinite(n);
|
|
@@ -3551,7 +3747,7 @@ function renderTimeline(timeline, options = {}) {
|
|
|
3551
3747
|
const dur = e.durationMs !== void 0 ? formatDuration2(e.durationMs) : "-";
|
|
3552
3748
|
const err = e.isError ? " error" : "";
|
|
3553
3749
|
const off = formatDuration2(e.offsetMs);
|
|
3554
|
-
let line = `${prefix}+${off} ${typeTag
|
|
3750
|
+
let line = `${prefix}+${off} ${formatStepLabel(typeTag, e.name)} (${dur})${err}`;
|
|
3555
3751
|
if (e.streaming?.chunkCount !== void 0) {
|
|
3556
3752
|
line += ` chunks=${e.streaming.chunkCount}`;
|
|
3557
3753
|
}
|
|
@@ -3703,6 +3899,12 @@ function renderRunWhat(summary, options = {}) {
|
|
|
3703
3899
|
}
|
|
3704
3900
|
|
|
3705
3901
|
// packages/core/src/explain.ts
|
|
3902
|
+
function toDisplayStatus(status) {
|
|
3903
|
+
if (status === "ok") return "success";
|
|
3904
|
+
if (status === "error") return "error";
|
|
3905
|
+
if (status === "running") return "running";
|
|
3906
|
+
return "unknown";
|
|
3907
|
+
}
|
|
3706
3908
|
function flatten(nodes, out = []) {
|
|
3707
3909
|
for (const node of nodes) {
|
|
3708
3910
|
out.push({ node, index: out.length + 1 });
|
|
@@ -3760,7 +3962,7 @@ function buildFacts(run, redactor) {
|
|
|
3760
3962
|
const facts = [
|
|
3761
3963
|
fact("run.id", "Run id", run.runId, redactor),
|
|
3762
3964
|
fact("run.name", "Run name", run.name ?? run.runId, redactor),
|
|
3763
|
-
fact("run.status", "Run status", run.status
|
|
3965
|
+
fact("run.status", "Run status", toDisplayStatus(run.status), redactor),
|
|
3764
3966
|
fact("run.totalEvents", "Total events", run.metadata.totalEvents, redactor),
|
|
3765
3967
|
fact("run.stepCount", "Top-level step count", run.children.length, redactor),
|
|
3766
3968
|
fact("run.nodeCount", "Total node count", nodes.length, redactor),
|
|
@@ -3836,7 +4038,7 @@ function buildLocalExplanation(run, options = {}) {
|
|
|
3836
4038
|
mode,
|
|
3837
4039
|
runId: String(redactValue(redactor, "runId", run.runId)),
|
|
3838
4040
|
...run.name !== void 0 ? { name: String(redactValue(redactor, "name", run.name)) } : {},
|
|
3839
|
-
...run.status !== void 0 ? { status: run.status } : {},
|
|
4041
|
+
...run.status !== void 0 ? { status: toDisplayStatus(run.status) } : {},
|
|
3840
4042
|
redactionProfile,
|
|
3841
4043
|
facts,
|
|
3842
4044
|
inferences: mode === "dry-run" ? [] : buildInferences(run, facts),
|
|
@@ -3847,199 +4049,6 @@ function buildLocalExplanation(run, options = {}) {
|
|
|
3847
4049
|
};
|
|
3848
4050
|
}
|
|
3849
4051
|
|
|
3850
|
-
// packages/core/src/stats.ts
|
|
3851
|
-
function percentile(sorted, p) {
|
|
3852
|
-
if (sorted.length === 0) return void 0;
|
|
3853
|
-
const idx = Math.min(
|
|
3854
|
-
sorted.length - 1,
|
|
3855
|
-
Math.max(0, Math.ceil(p / 100 * sorted.length) - 1)
|
|
3856
|
-
);
|
|
3857
|
-
return sorted[idx];
|
|
3858
|
-
}
|
|
3859
|
-
async function readRunStartedMetadata(filePath) {
|
|
3860
|
-
try {
|
|
3861
|
-
const events = await readTraceEventsFromFile(filePath);
|
|
3862
|
-
for (const event of events) {
|
|
3863
|
-
if (event.event !== "run_started") continue;
|
|
3864
|
-
const rs = event;
|
|
3865
|
-
if (rs.metadata && typeof rs.metadata === "object") {
|
|
3866
|
-
return rs.metadata;
|
|
3867
|
-
}
|
|
3868
|
-
return void 0;
|
|
3869
|
-
}
|
|
3870
|
-
} catch {
|
|
3871
|
-
}
|
|
3872
|
-
return void 0;
|
|
3873
|
-
}
|
|
3874
|
-
function metaMatchesCorrelation(metadata, correlationId, groupId) {
|
|
3875
|
-
if (correlationId) {
|
|
3876
|
-
const v = metadata?.correlationId;
|
|
3877
|
-
if (typeof v !== "string" || v !== correlationId) return false;
|
|
3878
|
-
}
|
|
3879
|
-
if (groupId) {
|
|
3880
|
-
const v = metadata?.groupId;
|
|
3881
|
-
if (typeof v !== "string" || v !== groupId) return false;
|
|
3882
|
-
}
|
|
3883
|
-
return true;
|
|
3884
|
-
}
|
|
3885
|
-
async function buildTraceStats(metas, options) {
|
|
3886
|
-
let filtered = filterTraces(metas, { since: options.since });
|
|
3887
|
-
if (options.correlationId || options.groupId) {
|
|
3888
|
-
const next = [];
|
|
3889
|
-
for (const m of filtered) {
|
|
3890
|
-
const md = await readRunStartedMetadata(m.filePath);
|
|
3891
|
-
if (metaMatchesCorrelation(md, options.correlationId, options.groupId)) {
|
|
3892
|
-
next.push(m);
|
|
3893
|
-
}
|
|
3894
|
-
}
|
|
3895
|
-
filtered = next;
|
|
3896
|
-
}
|
|
3897
|
-
let successCount = 0;
|
|
3898
|
-
let errorCount = 0;
|
|
3899
|
-
let runningCount = 0;
|
|
3900
|
-
let unknownCount = 0;
|
|
3901
|
-
const durations = [];
|
|
3902
|
-
let totalSteps = 0;
|
|
3903
|
-
let totalLlmSteps = 0;
|
|
3904
|
-
let totalToolSteps = 0;
|
|
3905
|
-
let totalErrorSteps = 0;
|
|
3906
|
-
const slowestRuns = [];
|
|
3907
|
-
const slowestSteps = [];
|
|
3908
|
-
for (const m of filtered) {
|
|
3909
|
-
if (m.status === "success") successCount += 1;
|
|
3910
|
-
else if (m.status === "error") errorCount += 1;
|
|
3911
|
-
else if (m.status === "running") runningCount += 1;
|
|
3912
|
-
else unknownCount += 1;
|
|
3913
|
-
if (typeof m.durationMs === "number" && Number.isFinite(m.durationMs) && m.durationMs >= 0) {
|
|
3914
|
-
durations.push(m.durationMs);
|
|
3915
|
-
slowestRuns.push({
|
|
3916
|
-
runId: m.runId,
|
|
3917
|
-
name: m.name,
|
|
3918
|
-
durationMs: m.durationMs,
|
|
3919
|
-
status: m.status
|
|
3920
|
-
});
|
|
3921
|
-
}
|
|
3922
|
-
try {
|
|
3923
|
-
const events = await readTraceEventsFromFile(m.filePath);
|
|
3924
|
-
if (events.length === 0) continue;
|
|
3925
|
-
const summary = buildRunSummary(events);
|
|
3926
|
-
totalSteps += summary.totalSteps;
|
|
3927
|
-
totalLlmSteps += summary.llmSteps;
|
|
3928
|
-
totalToolSteps += summary.toolSteps;
|
|
3929
|
-
totalErrorSteps += summary.errorSteps;
|
|
3930
|
-
const steps = collectCompletedSteps(events, m.runId);
|
|
3931
|
-
for (const s of steps) {
|
|
3932
|
-
slowestSteps.push(s);
|
|
3933
|
-
}
|
|
3934
|
-
} catch {
|
|
3935
|
-
}
|
|
3936
|
-
}
|
|
3937
|
-
slowestRuns.sort((a, b) => (b.durationMs ?? 0) - (a.durationMs ?? 0));
|
|
3938
|
-
slowestSteps.sort((a, b) => b.durationMs - a.durationMs);
|
|
3939
|
-
const runLimit = options.slowRunLimit ?? 5;
|
|
3940
|
-
const stepLimit = options.slowStepLimit ?? 5;
|
|
3941
|
-
const sortedDur = [...durations].sort((a, b) => a - b);
|
|
3942
|
-
const totalRuns = filtered.length;
|
|
3943
|
-
const errorRate = totalRuns > 0 ? errorCount / totalRuns : 0;
|
|
3944
|
-
const sumDur = durations.reduce((a, b) => a + b, 0);
|
|
3945
|
-
return {
|
|
3946
|
-
traceDir: options.traceDir,
|
|
3947
|
-
...options.since ? { since: options.since } : {},
|
|
3948
|
-
...options.correlationId ? { correlationId: options.correlationId } : {},
|
|
3949
|
-
...options.groupId ? { groupId: options.groupId } : {},
|
|
3950
|
-
totalRuns,
|
|
3951
|
-
successCount,
|
|
3952
|
-
errorCount,
|
|
3953
|
-
runningCount,
|
|
3954
|
-
unknownCount,
|
|
3955
|
-
errorRate,
|
|
3956
|
-
duration: {
|
|
3957
|
-
...sortedDur.length > 0 ? {
|
|
3958
|
-
minMs: sortedDur[0],
|
|
3959
|
-
maxMs: sortedDur[sortedDur.length - 1],
|
|
3960
|
-
avgMs: sumDur / sortedDur.length,
|
|
3961
|
-
p50Ms: percentile(sortedDur, 50),
|
|
3962
|
-
p95Ms: percentile(sortedDur, 95)
|
|
3963
|
-
} : {}
|
|
3964
|
-
},
|
|
3965
|
-
totalSteps,
|
|
3966
|
-
avgStepsPerRun: totalRuns > 0 ? totalSteps / totalRuns : 0,
|
|
3967
|
-
totalLlmSteps,
|
|
3968
|
-
totalToolSteps,
|
|
3969
|
-
totalErrorSteps,
|
|
3970
|
-
slowestRuns: slowestRuns.slice(0, runLimit),
|
|
3971
|
-
slowestSteps: slowestSteps.slice(0, stepLimit)
|
|
3972
|
-
};
|
|
3973
|
-
}
|
|
3974
|
-
function collectCompletedSteps(events, runId) {
|
|
3975
|
-
const started = /* @__PURE__ */ new Map();
|
|
3976
|
-
const out = [];
|
|
3977
|
-
for (const e of events) {
|
|
3978
|
-
if (e.event === "step_started") {
|
|
3979
|
-
const s = e;
|
|
3980
|
-
started.set(s.stepId, { name: s.name, type: s.type });
|
|
3981
|
-
}
|
|
3982
|
-
if (e.event === "step_completed") {
|
|
3983
|
-
const c = e;
|
|
3984
|
-
if (c.status !== "success" && c.status !== "error") continue;
|
|
3985
|
-
if (typeof c.durationMs !== "number" || !Number.isFinite(c.durationMs)) {
|
|
3986
|
-
continue;
|
|
3987
|
-
}
|
|
3988
|
-
const meta = started.get(c.stepId);
|
|
3989
|
-
out.push({
|
|
3990
|
-
runId,
|
|
3991
|
-
stepName: meta?.name ?? c.stepId,
|
|
3992
|
-
stepType: meta?.type ?? "logic",
|
|
3993
|
-
durationMs: c.durationMs
|
|
3994
|
-
});
|
|
3995
|
-
}
|
|
3996
|
-
}
|
|
3997
|
-
return out;
|
|
3998
|
-
}
|
|
3999
|
-
function renderTraceStats(stats) {
|
|
4000
|
-
const lines = [];
|
|
4001
|
-
lines.push("Trace stats (local)");
|
|
4002
|
-
lines.push(`Directory: ${stats.traceDir}`);
|
|
4003
|
-
if (stats.since) lines.push(`Since: ${stats.since}`);
|
|
4004
|
-
if (stats.correlationId) lines.push(`Correlation ID: ${stats.correlationId}`);
|
|
4005
|
-
if (stats.groupId) lines.push(`Group ID: ${stats.groupId}`);
|
|
4006
|
-
lines.push("");
|
|
4007
|
-
lines.push(`Runs: ${stats.totalRuns}`);
|
|
4008
|
-
lines.push(
|
|
4009
|
-
` success: ${stats.successCount} error: ${stats.errorCount} running: ${stats.runningCount} unknown: ${stats.unknownCount}`
|
|
4010
|
-
);
|
|
4011
|
-
lines.push(`Error rate: ${(stats.errorRate * 100).toFixed(1)}%`);
|
|
4012
|
-
if (stats.duration.avgMs !== void 0) {
|
|
4013
|
-
lines.push(
|
|
4014
|
-
`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)}`
|
|
4015
|
-
);
|
|
4016
|
-
}
|
|
4017
|
-
lines.push("");
|
|
4018
|
-
lines.push(`Steps: ${stats.totalSteps} (avg ${stats.avgStepsPerRun.toFixed(1)} per run)`);
|
|
4019
|
-
lines.push(
|
|
4020
|
-
` LLM: ${stats.totalLlmSteps} tool: ${stats.totalToolSteps} errors: ${stats.totalErrorSteps}`
|
|
4021
|
-
);
|
|
4022
|
-
if (stats.slowestRuns.length > 0) {
|
|
4023
|
-
lines.push("");
|
|
4024
|
-
lines.push("Slowest runs:");
|
|
4025
|
-
for (const r of stats.slowestRuns) {
|
|
4026
|
-
lines.push(
|
|
4027
|
-
` ${r.runId} | ${r.name ?? "-"} | ${formatDuration2(r.durationMs ?? 0)} | ${r.status}`
|
|
4028
|
-
);
|
|
4029
|
-
}
|
|
4030
|
-
}
|
|
4031
|
-
if (stats.slowestSteps.length > 0) {
|
|
4032
|
-
lines.push("");
|
|
4033
|
-
lines.push("Slowest steps:");
|
|
4034
|
-
for (const s of stats.slowestSteps) {
|
|
4035
|
-
lines.push(
|
|
4036
|
-
` ${s.runId} | ${s.stepType}:${s.stepName} | ${formatDuration2(s.durationMs)}`
|
|
4037
|
-
);
|
|
4038
|
-
}
|
|
4039
|
-
}
|
|
4040
|
-
return lines.join("\n");
|
|
4041
|
-
}
|
|
4042
|
-
|
|
4043
4052
|
// packages/core/src/search.ts
|
|
4044
4053
|
function parseDurationFilter(expr) {
|
|
4045
4054
|
const raw = expr.trim();
|
|
@@ -4106,6 +4115,12 @@ async function searchTraces(metas, options) {
|
|
|
4106
4115
|
...sessionLabel ? { sessionId: sessionLabel } : {}
|
|
4107
4116
|
});
|
|
4108
4117
|
}
|
|
4118
|
+
results.sort((a, b) => {
|
|
4119
|
+
const ta = a.timestamp ?? 0;
|
|
4120
|
+
const tb = b.timestamp ?? 0;
|
|
4121
|
+
if (ta !== tb) return tb - ta;
|
|
4122
|
+
return a.runId.localeCompare(b.runId);
|
|
4123
|
+
});
|
|
4109
4124
|
return results.slice(0, limit);
|
|
4110
4125
|
}
|
|
4111
4126
|
for (const m of filtered) {
|
|
@@ -4153,7 +4168,7 @@ async function searchTraces(metas, options) {
|
|
|
4153
4168
|
results.sort((a, b) => {
|
|
4154
4169
|
const ta = a.timestamp ?? 0;
|
|
4155
4170
|
const tb = b.timestamp ?? 0;
|
|
4156
|
-
if (ta !== tb) return
|
|
4171
|
+
if (ta !== tb) return tb - ta;
|
|
4157
4172
|
const runCmp = a.runId.localeCompare(b.runId);
|
|
4158
4173
|
if (runCmp !== 0) return runCmp;
|
|
4159
4174
|
return (a.stepName ?? "").localeCompare(b.stepName ?? "");
|
|
@@ -6421,13 +6436,24 @@ function inc(map, key) {
|
|
|
6421
6436
|
map[key] = (map[key] ?? 0) + 1;
|
|
6422
6437
|
}
|
|
6423
6438
|
function computeRunStatus(events) {
|
|
6439
|
+
let runTerminal;
|
|
6440
|
+
let sawRunEvent = false;
|
|
6441
|
+
for (const e of events) {
|
|
6442
|
+
if (e.kind !== "RUN") continue;
|
|
6443
|
+
sawRunEvent = true;
|
|
6444
|
+
if (e.status === "ok" || e.status === "error") {
|
|
6445
|
+
runTerminal = e.status;
|
|
6446
|
+
}
|
|
6447
|
+
}
|
|
6448
|
+
if (sawRunEvent) {
|
|
6449
|
+
return runTerminal ?? "running";
|
|
6450
|
+
}
|
|
6424
6451
|
let hasRunning = false;
|
|
6425
6452
|
for (const e of events) {
|
|
6426
6453
|
if (e.status === "error") return "error";
|
|
6427
6454
|
if (e.status === "running") hasRunning = true;
|
|
6428
6455
|
}
|
|
6429
|
-
|
|
6430
|
-
return "ok";
|
|
6456
|
+
return hasRunning ? "running" : "ok";
|
|
6431
6457
|
}
|
|
6432
6458
|
var TreeBuilder = class {
|
|
6433
6459
|
constructor(options) {
|
|
@@ -8643,7 +8669,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8643
8669
|
metric,
|
|
8644
8670
|
"Average duration (ms)",
|
|
8645
8671
|
baselineAgg?.avgDurationMs,
|
|
8646
|
-
candidateAgg?.avgDurationMs
|
|
8672
|
+
candidateAgg?.avgDurationMs,
|
|
8673
|
+
true,
|
|
8674
|
+
tolerance
|
|
8647
8675
|
);
|
|
8648
8676
|
if (item) comparisons.push(item);
|
|
8649
8677
|
break;
|
|
@@ -8653,7 +8681,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8653
8681
|
metric,
|
|
8654
8682
|
"Average LLM calls",
|
|
8655
8683
|
baselineAgg?.avgLlmCallCount,
|
|
8656
|
-
candidateAgg?.avgLlmCallCount
|
|
8684
|
+
candidateAgg?.avgLlmCallCount,
|
|
8685
|
+
true,
|
|
8686
|
+
tolerance
|
|
8657
8687
|
);
|
|
8658
8688
|
if (item) comparisons.push(item);
|
|
8659
8689
|
break;
|
|
@@ -8663,7 +8693,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8663
8693
|
metric,
|
|
8664
8694
|
"Average token usage",
|
|
8665
8695
|
baselineAgg?.avgTokenUsage,
|
|
8666
|
-
candidateAgg?.avgTokenUsage
|
|
8696
|
+
candidateAgg?.avgTokenUsage,
|
|
8697
|
+
true,
|
|
8698
|
+
tolerance
|
|
8667
8699
|
);
|
|
8668
8700
|
if (item) comparisons.push(item);
|
|
8669
8701
|
break;
|
|
@@ -8673,7 +8705,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8673
8705
|
metric,
|
|
8674
8706
|
"Average retries",
|
|
8675
8707
|
baselineAgg?.avgRetryCount,
|
|
8676
|
-
candidateAgg?.avgRetryCount
|
|
8708
|
+
candidateAgg?.avgRetryCount,
|
|
8709
|
+
true,
|
|
8710
|
+
tolerance
|
|
8677
8711
|
);
|
|
8678
8712
|
if (item) comparisons.push(item);
|
|
8679
8713
|
break;
|
|
@@ -8683,7 +8717,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8683
8717
|
metric,
|
|
8684
8718
|
"Observation failure rate",
|
|
8685
8719
|
baselineAgg?.observationFailureRate,
|
|
8686
|
-
candidateAgg?.observationFailureRate
|
|
8720
|
+
candidateAgg?.observationFailureRate,
|
|
8721
|
+
true,
|
|
8722
|
+
tolerance
|
|
8687
8723
|
);
|
|
8688
8724
|
if (item) comparisons.push(item);
|
|
8689
8725
|
break;
|
|
@@ -8719,7 +8755,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8719
8755
|
metric,
|
|
8720
8756
|
"Guardrail failures",
|
|
8721
8757
|
baselineAgg?.avgGuardrailFailures,
|
|
8722
|
-
candidateAgg?.avgGuardrailFailures
|
|
8758
|
+
candidateAgg?.avgGuardrailFailures,
|
|
8759
|
+
true,
|
|
8760
|
+
tolerance
|
|
8723
8761
|
);
|
|
8724
8762
|
if (item) comparisons.push(item);
|
|
8725
8763
|
break;
|
|
@@ -8729,7 +8767,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8729
8767
|
metric,
|
|
8730
8768
|
"Circuit violations",
|
|
8731
8769
|
baselineAgg?.avgCircuitViolations,
|
|
8732
|
-
candidateAgg?.avgCircuitViolations
|
|
8770
|
+
candidateAgg?.avgCircuitViolations,
|
|
8771
|
+
true,
|
|
8772
|
+
tolerance
|
|
8733
8773
|
);
|
|
8734
8774
|
if (item) comparisons.push(item);
|
|
8735
8775
|
break;
|
|
@@ -8739,7 +8779,9 @@ function compareCohortAggregates(groups, options) {
|
|
|
8739
8779
|
metric,
|
|
8740
8780
|
"Redaction warnings",
|
|
8741
8781
|
baselineAgg?.avgRedactionWarnings,
|
|
8742
|
-
candidateAgg?.avgRedactionWarnings
|
|
8782
|
+
candidateAgg?.avgRedactionWarnings,
|
|
8783
|
+
true,
|
|
8784
|
+
tolerance
|
|
8743
8785
|
);
|
|
8744
8786
|
if (item) comparisons.push(item);
|
|
8745
8787
|
break;
|