@agent-inspect/viewer 6.14.0 → 6.14.2
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.cjs +155 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +155 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -2
package/dist/index.cjs
CHANGED
|
@@ -2223,6 +2223,28 @@ async function resolveSuiteCaseTrace(suiteCase, options) {
|
|
|
2223
2223
|
};
|
|
2224
2224
|
}
|
|
2225
2225
|
|
|
2226
|
+
// packages/core/src/safety/sensitive-key.ts
|
|
2227
|
+
function normalizeSensitiveKey(value) {
|
|
2228
|
+
return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
|
|
2229
|
+
}
|
|
2230
|
+
new Set(
|
|
2231
|
+
[
|
|
2232
|
+
"tokens",
|
|
2233
|
+
"max_tokens",
|
|
2234
|
+
"min_tokens",
|
|
2235
|
+
"ls_max_tokens",
|
|
2236
|
+
"token_count",
|
|
2237
|
+
"token_limit",
|
|
2238
|
+
"token_budget",
|
|
2239
|
+
"input_tokens",
|
|
2240
|
+
"output_tokens",
|
|
2241
|
+
"total_tokens",
|
|
2242
|
+
"cached_tokens",
|
|
2243
|
+
"prompt_tokens",
|
|
2244
|
+
"completion_tokens"
|
|
2245
|
+
].map(normalizeSensitiveKey)
|
|
2246
|
+
);
|
|
2247
|
+
|
|
2226
2248
|
// packages/core/src/checks/logical-events.ts
|
|
2227
2249
|
function isRecord5(value) {
|
|
2228
2250
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -2418,6 +2440,23 @@ function projectLogicalEvents(events) {
|
|
|
2418
2440
|
}
|
|
2419
2441
|
}
|
|
2420
2442
|
if (!remapped) {
|
|
2443
|
+
if (originalParentId === event.eventId) {
|
|
2444
|
+
diagnostics.push({
|
|
2445
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
2446
|
+
message: `Removed self-parent edge on ${event.eventId}.`,
|
|
2447
|
+
eventIds: [event.eventId]
|
|
2448
|
+
});
|
|
2449
|
+
const { parentId: _drop, ...rest } = event;
|
|
2450
|
+
normalized.push({
|
|
2451
|
+
...rest,
|
|
2452
|
+
projection: {
|
|
2453
|
+
...event.projection,
|
|
2454
|
+
parentNormalized: true,
|
|
2455
|
+
originalParentId
|
|
2456
|
+
}
|
|
2457
|
+
});
|
|
2458
|
+
continue;
|
|
2459
|
+
}
|
|
2421
2460
|
if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
|
|
2422
2461
|
const mapping = event.attributes?.parentMapping;
|
|
2423
2462
|
const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
|
|
@@ -2433,6 +2472,23 @@ function projectLogicalEvents(events) {
|
|
|
2433
2472
|
normalized.push(event);
|
|
2434
2473
|
continue;
|
|
2435
2474
|
}
|
|
2475
|
+
if (nextParent === event.eventId) {
|
|
2476
|
+
diagnostics.push({
|
|
2477
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
2478
|
+
message: `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`,
|
|
2479
|
+
eventIds: [event.eventId]
|
|
2480
|
+
});
|
|
2481
|
+
const { parentId: _drop, ...rest } = event;
|
|
2482
|
+
normalized.push({
|
|
2483
|
+
...rest,
|
|
2484
|
+
projection: {
|
|
2485
|
+
...event.projection,
|
|
2486
|
+
parentNormalized: true,
|
|
2487
|
+
originalParentId
|
|
2488
|
+
}
|
|
2489
|
+
});
|
|
2490
|
+
continue;
|
|
2491
|
+
}
|
|
2436
2492
|
diagnostics.push({
|
|
2437
2493
|
code: "AI_LOGICAL_PARENT_REMAPPED",
|
|
2438
2494
|
message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
|
|
@@ -2826,7 +2882,7 @@ function createToolUsageRule(options) {
|
|
|
2826
2882
|
}
|
|
2827
2883
|
}
|
|
2828
2884
|
const forbidden = new Set(options.forbidden ?? []);
|
|
2829
|
-
const allowed = options.allowed ? new Set(options.allowed) : void 0;
|
|
2885
|
+
const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
|
|
2830
2886
|
for (const event of tools) {
|
|
2831
2887
|
const name = toolName(event);
|
|
2832
2888
|
if (forbidden.has(name)) {
|
|
@@ -2862,9 +2918,9 @@ function createLlmUsageRule(options) {
|
|
|
2862
2918
|
evaluate(context) {
|
|
2863
2919
|
const llms = finishedEvents(context, "LLM");
|
|
2864
2920
|
const findings = [];
|
|
2865
|
-
const allowedModels = options.allowedModels ? new Set(options.allowedModels) : void 0;
|
|
2866
|
-
const allowedProviders = options.allowedProviders ? new Set(options.allowedProviders) : void 0;
|
|
2867
|
-
const finishReasons = options.finishReasons ? new Set(options.finishReasons) : void 0;
|
|
2921
|
+
const allowedModels = options.allowedModels?.length ? new Set(options.allowedModels) : void 0;
|
|
2922
|
+
const allowedProviders = options.allowedProviders?.length ? new Set(options.allowedProviders) : void 0;
|
|
2923
|
+
const finishReasons = options.finishReasons?.length ? new Set(options.finishReasons) : void 0;
|
|
2868
2924
|
if (options.maxCalls !== void 0 && llms.length > options.maxCalls) {
|
|
2869
2925
|
findings.push(
|
|
2870
2926
|
failFinding(
|
|
@@ -3279,6 +3335,20 @@ function traceEventsToPersistedInspectEvents(events, options) {
|
|
|
3279
3335
|
function inc(map, key) {
|
|
3280
3336
|
map[key] = (map[key] ?? 0) + 1;
|
|
3281
3337
|
}
|
|
3338
|
+
function confidenceRank(confidence) {
|
|
3339
|
+
switch (confidence) {
|
|
3340
|
+
case "unknown":
|
|
3341
|
+
return 0;
|
|
3342
|
+
case "heuristic":
|
|
3343
|
+
return 1;
|
|
3344
|
+
case "correlated":
|
|
3345
|
+
return 2;
|
|
3346
|
+
case "explicit":
|
|
3347
|
+
return 3;
|
|
3348
|
+
default:
|
|
3349
|
+
return 0;
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3282
3352
|
function computeRunStatus(events) {
|
|
3283
3353
|
let runTerminal;
|
|
3284
3354
|
let sawRunEvent = false;
|
|
@@ -3299,6 +3369,84 @@ function computeRunStatus(events) {
|
|
|
3299
3369
|
}
|
|
3300
3370
|
return hasRunning ? "running" : "ok";
|
|
3301
3371
|
}
|
|
3372
|
+
function linkNodesVisibilityFirst(nodes) {
|
|
3373
|
+
let selfParentCount = 0;
|
|
3374
|
+
let unresolvedParentCount = 0;
|
|
3375
|
+
let normalizedEdgeCount = 0;
|
|
3376
|
+
let cycleCount = 0;
|
|
3377
|
+
const pending = [];
|
|
3378
|
+
for (const node of nodes.values()) {
|
|
3379
|
+
const parentId = node.event.parentId;
|
|
3380
|
+
if (!parentId) continue;
|
|
3381
|
+
if (parentId === node.event.eventId) {
|
|
3382
|
+
selfParentCount += 1;
|
|
3383
|
+
normalizedEdgeCount += 1;
|
|
3384
|
+
continue;
|
|
3385
|
+
}
|
|
3386
|
+
if (!nodes.has(parentId)) {
|
|
3387
|
+
unresolvedParentCount += 1;
|
|
3388
|
+
continue;
|
|
3389
|
+
}
|
|
3390
|
+
pending.push({
|
|
3391
|
+
childId: node.event.eventId,
|
|
3392
|
+
parentId,
|
|
3393
|
+
childTimestamp: node.event.timestamp,
|
|
3394
|
+
childConfidence: node.event.confidence
|
|
3395
|
+
});
|
|
3396
|
+
}
|
|
3397
|
+
pending.sort((a, b) => {
|
|
3398
|
+
const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
|
|
3399
|
+
if (conf !== 0) return conf;
|
|
3400
|
+
return a.childTimestamp - b.childTimestamp;
|
|
3401
|
+
});
|
|
3402
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
3403
|
+
for (const edge of pending) {
|
|
3404
|
+
parentOf.set(edge.childId, edge.parentId);
|
|
3405
|
+
let cursor = edge.parentId;
|
|
3406
|
+
const seen = /* @__PURE__ */ new Set([edge.childId]);
|
|
3407
|
+
let cyclic = false;
|
|
3408
|
+
while (cursor) {
|
|
3409
|
+
if (seen.has(cursor)) {
|
|
3410
|
+
cyclic = true;
|
|
3411
|
+
break;
|
|
3412
|
+
}
|
|
3413
|
+
seen.add(cursor);
|
|
3414
|
+
cursor = parentOf.get(cursor);
|
|
3415
|
+
}
|
|
3416
|
+
if (cyclic) {
|
|
3417
|
+
parentOf.delete(edge.childId);
|
|
3418
|
+
cycleCount += 1;
|
|
3419
|
+
normalizedEdgeCount += 1;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
for (const [childId, parentId] of parentOf) {
|
|
3423
|
+
nodes.get(parentId).children.push(nodes.get(childId));
|
|
3424
|
+
}
|
|
3425
|
+
const roots = [];
|
|
3426
|
+
for (const node of nodes.values()) {
|
|
3427
|
+
if (!parentOf.has(node.event.eventId)) {
|
|
3428
|
+
roots.push(node);
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
const assignDepth = (n, depth, stack) => {
|
|
3432
|
+
if (stack.has(n.event.eventId)) return;
|
|
3433
|
+
n.depth = depth;
|
|
3434
|
+
stack.add(n.event.eventId);
|
|
3435
|
+
for (const c of n.children) assignDepth(c, depth + 1, stack);
|
|
3436
|
+
stack.delete(n.event.eventId);
|
|
3437
|
+
};
|
|
3438
|
+
for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
|
|
3439
|
+
return {
|
|
3440
|
+
roots,
|
|
3441
|
+
summary: {
|
|
3442
|
+
rootCount: roots.length,
|
|
3443
|
+
selfParentCount,
|
|
3444
|
+
cycleCount,
|
|
3445
|
+
unresolvedParentCount,
|
|
3446
|
+
normalizedEdgeCount
|
|
3447
|
+
}
|
|
3448
|
+
};
|
|
3449
|
+
}
|
|
3302
3450
|
var TreeBuilder = class {
|
|
3303
3451
|
constructor(options) {
|
|
3304
3452
|
void options?.config;
|
|
@@ -3316,20 +3464,7 @@ var TreeBuilder = class {
|
|
|
3316
3464
|
for (const e of sorted) {
|
|
3317
3465
|
nodes.set(e.eventId, { event: e, children: [], depth: 0 });
|
|
3318
3466
|
}
|
|
3319
|
-
const roots =
|
|
3320
|
-
for (const node of nodes.values()) {
|
|
3321
|
-
const parentId = node.event.parentId;
|
|
3322
|
-
if (parentId && nodes.has(parentId)) {
|
|
3323
|
-
nodes.get(parentId).children.push(node);
|
|
3324
|
-
} else {
|
|
3325
|
-
roots.push(node);
|
|
3326
|
-
}
|
|
3327
|
-
}
|
|
3328
|
-
const assignDepth = (n, depth) => {
|
|
3329
|
-
n.depth = depth;
|
|
3330
|
-
for (const c of n.children) assignDepth(c, depth + 1);
|
|
3331
|
-
};
|
|
3332
|
-
for (const r of roots) assignDepth(r, 0);
|
|
3467
|
+
const { roots, summary } = linkNodesVisibilityFirst(nodes);
|
|
3333
3468
|
const confidenceBreakdown = {
|
|
3334
3469
|
explicit: 0,
|
|
3335
3470
|
correlated: 0,
|
|
@@ -3357,7 +3492,8 @@ var TreeBuilder = class {
|
|
|
3357
3492
|
metadata: {
|
|
3358
3493
|
totalEvents: sorted.length,
|
|
3359
3494
|
confidenceBreakdown,
|
|
3360
|
-
kinds
|
|
3495
|
+
kinds,
|
|
3496
|
+
relationshipSummary: summary
|
|
3361
3497
|
}
|
|
3362
3498
|
});
|
|
3363
3499
|
}
|