agent-inspect 6.7.3 → 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 +15 -0
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-EMYDJREA.mjs → chunk-FVEQ7JFF.mjs} +227 -201
- package/packages/cli/dist/chunk-FVEQ7JFF.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +247 -209
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +16 -5
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-IPJNFV37.mjs → src-I5NA7BLK.mjs} +3 -3
- package/packages/cli/dist/{src-IPJNFV37.mjs.map → src-I5NA7BLK.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +225 -199
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +26 -241
- package/packages/core/dist/advanced.mjs.map +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-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/exporters.cjs +136 -129
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +1 -1
- package/packages/core/dist/logs.cjs +13 -2
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.mjs +2 -2
- 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-EMYDJREA.mjs.map +0 -1
- package/packages/core/dist/chunk-3USJVBLA.mjs.map +0 -1
- package/packages/core/dist/chunk-E5F2LQCX.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) {
|