@agent-inspect/mcp-server 6.18.0 → 6.19.1
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/{chunk-FTUMVNQN.mjs → chunk-TVTJGGYV.mjs} +427 -48
- package/dist/chunk-TVTJGGYV.mjs.map +1 -0
- package/dist/cli.cjs +425 -46
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.cjs +425 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
- package/dist/chunk-FTUMVNQN.mjs.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -1160,9 +1160,63 @@ async function extractMetadata(filePath, _quickScan) {
|
|
|
1160
1160
|
createdAt: stats.birthtime
|
|
1161
1161
|
};
|
|
1162
1162
|
}
|
|
1163
|
+
var ROOT_STEP_DEPTH = 0;
|
|
1164
|
+
var MAX_RUN_SUMMARY_DEPTH = 1e3;
|
|
1163
1165
|
function isNonNegativeFiniteNumber(value) {
|
|
1164
1166
|
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
1165
1167
|
}
|
|
1168
|
+
function resolveParentStepId(step, steps) {
|
|
1169
|
+
const parentId = step.parentId;
|
|
1170
|
+
if (typeof parentId !== "string" || parentId.trim() === "") {
|
|
1171
|
+
return void 0;
|
|
1172
|
+
}
|
|
1173
|
+
return steps.has(parentId) ? parentId : void 0;
|
|
1174
|
+
}
|
|
1175
|
+
function computeStepDepth(stepId, steps, depthCache) {
|
|
1176
|
+
const cached = depthCache.get(stepId);
|
|
1177
|
+
if (cached !== void 0) return cached;
|
|
1178
|
+
const ancestry = [];
|
|
1179
|
+
const ancestryIndexes = /* @__PURE__ */ new Map();
|
|
1180
|
+
let currentStepId = stepId;
|
|
1181
|
+
let resolvedDepth;
|
|
1182
|
+
while (resolvedDepth === void 0) {
|
|
1183
|
+
const cachedDepth = depthCache.get(currentStepId);
|
|
1184
|
+
if (cachedDepth !== void 0) {
|
|
1185
|
+
resolvedDepth = cachedDepth;
|
|
1186
|
+
continue;
|
|
1187
|
+
}
|
|
1188
|
+
const cycleStart = ancestryIndexes.get(currentStepId);
|
|
1189
|
+
if (cycleStart !== void 0) {
|
|
1190
|
+
const cycleStepIds = ancestry.splice(cycleStart);
|
|
1191
|
+
for (const cycleStepId of cycleStepIds) {
|
|
1192
|
+
depthCache.set(cycleStepId, ROOT_STEP_DEPTH);
|
|
1193
|
+
}
|
|
1194
|
+
resolvedDepth = ROOT_STEP_DEPTH;
|
|
1195
|
+
continue;
|
|
1196
|
+
}
|
|
1197
|
+
const currentStep = steps.get(currentStepId);
|
|
1198
|
+
if (!currentStep) {
|
|
1199
|
+
resolvedDepth = ROOT_STEP_DEPTH;
|
|
1200
|
+
continue;
|
|
1201
|
+
}
|
|
1202
|
+
ancestryIndexes.set(currentStepId, ancestry.length);
|
|
1203
|
+
ancestry.push(currentStepId);
|
|
1204
|
+
const parentStepId = resolveParentStepId(currentStep, steps);
|
|
1205
|
+
if (parentStepId === void 0) {
|
|
1206
|
+
ancestry.pop();
|
|
1207
|
+
depthCache.set(currentStepId, ROOT_STEP_DEPTH);
|
|
1208
|
+
resolvedDepth = ROOT_STEP_DEPTH;
|
|
1209
|
+
continue;
|
|
1210
|
+
}
|
|
1211
|
+
currentStepId = parentStepId;
|
|
1212
|
+
}
|
|
1213
|
+
ancestry.reverse();
|
|
1214
|
+
for (const ancestorStepId of ancestry) {
|
|
1215
|
+
resolvedDepth = Math.min(MAX_RUN_SUMMARY_DEPTH, resolvedDepth + 1);
|
|
1216
|
+
depthCache.set(ancestorStepId, resolvedDepth);
|
|
1217
|
+
}
|
|
1218
|
+
return depthCache.get(stepId) ?? ROOT_STEP_DEPTH;
|
|
1219
|
+
}
|
|
1166
1220
|
function buildRunSummary(events) {
|
|
1167
1221
|
const started = events.find(
|
|
1168
1222
|
(e) => e.event === "run_started"
|
|
@@ -1216,27 +1270,13 @@ function buildRunSummary(events) {
|
|
|
1216
1270
|
let stepsWithKnownTotal = 0;
|
|
1217
1271
|
let hasCachedTokens = false;
|
|
1218
1272
|
const depthCache = /* @__PURE__ */ new Map();
|
|
1219
|
-
const computeDepth = (stepId) => {
|
|
1220
|
-
const cached = depthCache.get(stepId);
|
|
1221
|
-
if (cached !== void 0) return cached;
|
|
1222
|
-
const node = steps.get(stepId);
|
|
1223
|
-
if (!node) return 0;
|
|
1224
|
-
const parent = node.parentId;
|
|
1225
|
-
if (typeof parent !== "string" || parent.trim() === "" || !steps.has(parent)) {
|
|
1226
|
-
depthCache.set(stepId, 0);
|
|
1227
|
-
return 0;
|
|
1228
|
-
}
|
|
1229
|
-
const d = Math.min(1e3, computeDepth(parent) + 1);
|
|
1230
|
-
depthCache.set(stepId, d);
|
|
1231
|
-
return d;
|
|
1232
|
-
};
|
|
1233
1273
|
for (const [id, s] of steps.entries()) {
|
|
1234
1274
|
totalSteps += 1;
|
|
1235
1275
|
if (s.type === "llm") llmSteps += 1;
|
|
1236
1276
|
else if (s.type === "tool") toolSteps += 1;
|
|
1237
1277
|
else logicSteps += 1;
|
|
1238
1278
|
if (s.status === "error") errorSteps += 1;
|
|
1239
|
-
const depth =
|
|
1279
|
+
const depth = computeStepDepth(id, steps, depthCache);
|
|
1240
1280
|
if (depth > maxDepth) maxDepth = depth;
|
|
1241
1281
|
if (typeof s.durationMs === "number" && Number.isFinite(s.durationMs)) {
|
|
1242
1282
|
if (!longestStep || s.durationMs > longestStep.durationMs) {
|
|
@@ -3003,6 +3043,325 @@ function pickString(record, keys) {
|
|
|
3003
3043
|
return void 0;
|
|
3004
3044
|
}
|
|
3005
3045
|
|
|
3046
|
+
// packages/core/src/checks/derived-failure.ts
|
|
3047
|
+
function isRecord7(value) {
|
|
3048
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3049
|
+
}
|
|
3050
|
+
function pickString2(record, keys) {
|
|
3051
|
+
if (!record) return void 0;
|
|
3052
|
+
for (const key of keys) {
|
|
3053
|
+
const value = record[key];
|
|
3054
|
+
if (typeof value === "string" && value.trim() !== "") return value;
|
|
3055
|
+
}
|
|
3056
|
+
return void 0;
|
|
3057
|
+
}
|
|
3058
|
+
function pickNumber(record, keys) {
|
|
3059
|
+
if (!record) return void 0;
|
|
3060
|
+
for (const key of keys) {
|
|
3061
|
+
const value = record[key];
|
|
3062
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
3063
|
+
return value;
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
return void 0;
|
|
3067
|
+
}
|
|
3068
|
+
function eventMetadata(event) {
|
|
3069
|
+
const attrs = isRecord7(event.attributes) ? event.attributes : void 0;
|
|
3070
|
+
const nested = attrs !== void 0 && isRecord7(attrs.metadata) ? attrs.metadata : void 0;
|
|
3071
|
+
return {
|
|
3072
|
+
...attrs ?? {},
|
|
3073
|
+
...nested ?? {}
|
|
3074
|
+
};
|
|
3075
|
+
}
|
|
3076
|
+
function canonicalName(event) {
|
|
3077
|
+
if (event.kind === "TOOL") return resolveCanonicalToolName(event);
|
|
3078
|
+
return event.name;
|
|
3079
|
+
}
|
|
3080
|
+
function linkKeys(event) {
|
|
3081
|
+
const meta = eventMetadata(event);
|
|
3082
|
+
const keys = [];
|
|
3083
|
+
for (const key of ["linkedStepId", "toolCallId", "mcpToolCallId"]) {
|
|
3084
|
+
const value = pickString2(meta, [key]);
|
|
3085
|
+
if (value !== void 0) keys.push(`${key}:${value}`);
|
|
3086
|
+
}
|
|
3087
|
+
const stepId = pickString2(meta, ["stepId"]);
|
|
3088
|
+
if (stepId !== void 0) keys.push(`stepId:${stepId}`);
|
|
3089
|
+
return keys;
|
|
3090
|
+
}
|
|
3091
|
+
function buildRunContexts(logicalEvents) {
|
|
3092
|
+
const byRun = /* @__PURE__ */ new Map();
|
|
3093
|
+
for (const event of logicalEvents) {
|
|
3094
|
+
const existing = byRun.get(event.runId) ?? {
|
|
3095
|
+
runId: event.runId,
|
|
3096
|
+
name: event.name
|
|
3097
|
+
};
|
|
3098
|
+
const meta = eventMetadata(event);
|
|
3099
|
+
if (event.kind === "RUN" || existing.name === event.runId) {
|
|
3100
|
+
existing.name = event.name || existing.name;
|
|
3101
|
+
}
|
|
3102
|
+
if (event.kind === "RUN" && event.status !== void 0 && event.status !== "running") {
|
|
3103
|
+
existing.status = event.status;
|
|
3104
|
+
}
|
|
3105
|
+
existing.retryOf ??= pickString2(meta, ["retryOf"]);
|
|
3106
|
+
existing.attempt ??= pickNumber(meta, ["attempt", "retryAttempt", "retryCount"]);
|
|
3107
|
+
existing.sessionId ??= pickString2(meta, ["sessionId", "conversationId"]);
|
|
3108
|
+
existing.groupId ??= pickString2(meta, ["groupId"]);
|
|
3109
|
+
existing.parentGroupId ??= pickString2(meta, ["parentGroupId"]);
|
|
3110
|
+
existing.fallbackOf ??= pickString2(meta, ["fallbackOf", "fallbackFrom"]);
|
|
3111
|
+
byRun.set(event.runId, existing);
|
|
3112
|
+
}
|
|
3113
|
+
return byRun;
|
|
3114
|
+
}
|
|
3115
|
+
function sameCorrelationScope(a, b) {
|
|
3116
|
+
if (a.sessionId && b.sessionId && a.sessionId === b.sessionId) return true;
|
|
3117
|
+
if (a.groupId && b.groupId && a.groupId === b.groupId) return true;
|
|
3118
|
+
if (a.parentGroupId && b.parentGroupId && a.parentGroupId === b.parentGroupId) {
|
|
3119
|
+
return true;
|
|
3120
|
+
}
|
|
3121
|
+
return false;
|
|
3122
|
+
}
|
|
3123
|
+
function isSuccessful(event) {
|
|
3124
|
+
return event.status === "ok";
|
|
3125
|
+
}
|
|
3126
|
+
function isFailure(event) {
|
|
3127
|
+
return event.status === "error";
|
|
3128
|
+
}
|
|
3129
|
+
function compareEventOrder(a, b) {
|
|
3130
|
+
const byTime = a.timestamp.localeCompare(b.timestamp);
|
|
3131
|
+
if (byTime !== 0) return byTime;
|
|
3132
|
+
return a.eventId.localeCompare(b.eventId);
|
|
3133
|
+
}
|
|
3134
|
+
function collectCandidates(failure, logicalEvents, runs) {
|
|
3135
|
+
const failureRun = runs.get(failure.runId);
|
|
3136
|
+
const failureLinks = new Set(linkKeys(failure));
|
|
3137
|
+
const failureName = canonicalName(failure);
|
|
3138
|
+
const failureAttempt = pickNumber(eventMetadata(failure), ["attempt", "retryAttempt", "retryCount"]) ?? failureRun?.attempt;
|
|
3139
|
+
const candidates = [];
|
|
3140
|
+
for (const event of logicalEvents) {
|
|
3141
|
+
if (event.eventId === failure.eventId) continue;
|
|
3142
|
+
if (event.status === "running") continue;
|
|
3143
|
+
const eventRun = runs.get(event.runId);
|
|
3144
|
+
const eventMeta = eventMetadata(event);
|
|
3145
|
+
const sameRun = event.runId === failure.runId;
|
|
3146
|
+
if (eventRun?.retryOf === failure.runId) {
|
|
3147
|
+
candidates.push({
|
|
3148
|
+
event,
|
|
3149
|
+
basis: "retryOf",
|
|
3150
|
+
confidence: "explicit",
|
|
3151
|
+
viaRunId: event.runId
|
|
3152
|
+
});
|
|
3153
|
+
continue;
|
|
3154
|
+
}
|
|
3155
|
+
if (eventRun?.fallbackOf === failure.runId || pickString2(eventMeta, ["fallbackOf", "fallbackFrom"]) === failure.runId) {
|
|
3156
|
+
candidates.push({
|
|
3157
|
+
event,
|
|
3158
|
+
basis: "fallbackOf",
|
|
3159
|
+
confidence: "explicit",
|
|
3160
|
+
viaRunId: event.runId
|
|
3161
|
+
});
|
|
3162
|
+
continue;
|
|
3163
|
+
}
|
|
3164
|
+
if (sameRun && compareEventOrder(failure, event) >= 0) continue;
|
|
3165
|
+
const eventLinks = linkKeys(event);
|
|
3166
|
+
const sharedLink = eventLinks.find((key) => failureLinks.has(key));
|
|
3167
|
+
if (sharedLink !== void 0) {
|
|
3168
|
+
candidates.push({
|
|
3169
|
+
event,
|
|
3170
|
+
basis: sharedLink.split(":")[0] ?? "linkedId",
|
|
3171
|
+
confidence: "explicit"
|
|
3172
|
+
});
|
|
3173
|
+
continue;
|
|
3174
|
+
}
|
|
3175
|
+
const eventAttempt = pickNumber(eventMeta, ["attempt", "retryAttempt", "retryCount"]) ?? eventRun?.attempt;
|
|
3176
|
+
const sameParent = failure.parentId !== void 0 && event.parentId !== void 0 && failure.parentId === event.parentId;
|
|
3177
|
+
const differentParent = failure.parentId !== void 0 && event.parentId !== void 0 && failure.parentId !== event.parentId;
|
|
3178
|
+
const sessionScoped = failureRun !== void 0 && eventRun !== void 0 && sameCorrelationScope(failureRun, eventRun);
|
|
3179
|
+
if (canonicalName(event) === failureName && failureAttempt !== void 0 && eventAttempt !== void 0 && eventAttempt > failureAttempt && !differentParent && (sameParent || sessionScoped || sameRun)) {
|
|
3180
|
+
candidates.push({
|
|
3181
|
+
event,
|
|
3182
|
+
basis: "attempt-progression",
|
|
3183
|
+
confidence: "correlated",
|
|
3184
|
+
...event.runId !== failure.runId ? { viaRunId: event.runId } : {}
|
|
3185
|
+
});
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
const byId = /* @__PURE__ */ new Map();
|
|
3189
|
+
for (const candidate of candidates) {
|
|
3190
|
+
const prev = byId.get(candidate.event.eventId);
|
|
3191
|
+
if (!prev || prev.confidence !== "explicit" && candidate.confidence === "explicit") {
|
|
3192
|
+
byId.set(candidate.event.eventId, candidate);
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
return [...byId.values()].sort((a, b) => compareEventOrder(a.event, b.event));
|
|
3196
|
+
}
|
|
3197
|
+
function classifyFailure(failure, candidates, runs, logicalEvents) {
|
|
3198
|
+
const successful = candidates.filter((c) => isSuccessful(c.event));
|
|
3199
|
+
const unsuccessful = candidates.filter((c) => !isSuccessful(c.event));
|
|
3200
|
+
const retryRunIds = Object.freeze(
|
|
3201
|
+
[...new Set(candidates.map((c) => c.viaRunId).filter((id) => id !== void 0))].sort(
|
|
3202
|
+
(a, b) => a.localeCompare(b)
|
|
3203
|
+
)
|
|
3204
|
+
);
|
|
3205
|
+
if (successful.length > 1) {
|
|
3206
|
+
const distinctRuns = new Set(successful.map((c) => c.event.runId));
|
|
3207
|
+
const distinctParents = new Set(
|
|
3208
|
+
successful.map((c) => c.event.parentId ?? "").filter((id) => id !== "")
|
|
3209
|
+
);
|
|
3210
|
+
if (distinctRuns.size > 1 || distinctParents.size > 1) {
|
|
3211
|
+
return {
|
|
3212
|
+
eventId: failure.eventId,
|
|
3213
|
+
runId: failure.runId,
|
|
3214
|
+
name: failure.name,
|
|
3215
|
+
kind: failure.kind,
|
|
3216
|
+
role: "unknown",
|
|
3217
|
+
confidence: "unknown",
|
|
3218
|
+
basis: Object.freeze(["ambiguous-recovery-candidates"]),
|
|
3219
|
+
recoveryEventIds: Object.freeze(
|
|
3220
|
+
successful.map((c) => c.event.eventId).sort((a, b) => a.localeCompare(b))
|
|
3221
|
+
),
|
|
3222
|
+
retryRunIds
|
|
3223
|
+
};
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
if (successful.length >= 1) {
|
|
3227
|
+
const best = successful[0];
|
|
3228
|
+
return {
|
|
3229
|
+
eventId: failure.eventId,
|
|
3230
|
+
runId: failure.runId,
|
|
3231
|
+
name: failure.name,
|
|
3232
|
+
kind: failure.kind,
|
|
3233
|
+
role: "recovered",
|
|
3234
|
+
confidence: best.confidence,
|
|
3235
|
+
basis: Object.freeze([best.basis]),
|
|
3236
|
+
recoveryEventIds: Object.freeze(
|
|
3237
|
+
successful.map((c) => c.event.eventId).sort((a, b) => a.localeCompare(b))
|
|
3238
|
+
),
|
|
3239
|
+
retryRunIds
|
|
3240
|
+
};
|
|
3241
|
+
}
|
|
3242
|
+
if (candidates.length > 0) {
|
|
3243
|
+
const best = candidates[0];
|
|
3244
|
+
return {
|
|
3245
|
+
eventId: failure.eventId,
|
|
3246
|
+
runId: failure.runId,
|
|
3247
|
+
name: failure.name,
|
|
3248
|
+
kind: failure.kind,
|
|
3249
|
+
role: "transient",
|
|
3250
|
+
confidence: best.confidence,
|
|
3251
|
+
basis: Object.freeze([
|
|
3252
|
+
best.basis,
|
|
3253
|
+
unsuccessful.some((c) => c.event.status === void 0) ? "retry-incomplete" : "retry-without-success"
|
|
3254
|
+
]),
|
|
3255
|
+
recoveryEventIds: Object.freeze([]),
|
|
3256
|
+
retryRunIds
|
|
3257
|
+
};
|
|
3258
|
+
}
|
|
3259
|
+
const failureMeta = eventMetadata(failure);
|
|
3260
|
+
const declaredSuccessor = pickString2(failureMeta, [
|
|
3261
|
+
"retriedBy",
|
|
3262
|
+
"nextRetryRunId",
|
|
3263
|
+
"retryRunId"
|
|
3264
|
+
]);
|
|
3265
|
+
if (declaredSuccessor !== void 0 && !runs.has(declaredSuccessor)) {
|
|
3266
|
+
return {
|
|
3267
|
+
eventId: failure.eventId,
|
|
3268
|
+
runId: failure.runId,
|
|
3269
|
+
name: failure.name,
|
|
3270
|
+
kind: failure.kind,
|
|
3271
|
+
role: "transient",
|
|
3272
|
+
confidence: "explicit",
|
|
3273
|
+
basis: Object.freeze(["retry-declared", "retry-run-missing"]),
|
|
3274
|
+
recoveryEventIds: Object.freeze([]),
|
|
3275
|
+
retryRunIds: Object.freeze([declaredSuccessor])
|
|
3276
|
+
};
|
|
3277
|
+
}
|
|
3278
|
+
for (const run of runs.values()) {
|
|
3279
|
+
if (run.retryOf === failure.runId) {
|
|
3280
|
+
return {
|
|
3281
|
+
eventId: failure.eventId,
|
|
3282
|
+
runId: failure.runId,
|
|
3283
|
+
name: failure.name,
|
|
3284
|
+
kind: failure.kind,
|
|
3285
|
+
role: "transient",
|
|
3286
|
+
confidence: "explicit",
|
|
3287
|
+
basis: Object.freeze(["retryOf", "retry-run-missing-or-empty"]),
|
|
3288
|
+
recoveryEventIds: Object.freeze([]),
|
|
3289
|
+
retryRunIds: Object.freeze([run.runId])
|
|
3290
|
+
};
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
const failureRun = runs.get(failure.runId);
|
|
3294
|
+
const hasSuccessorDeclared = [...runs.values()].some((run) => run.retryOf === failure.runId);
|
|
3295
|
+
const isFinalInChain = failureRun !== void 0 && !hasSuccessorDeclared && (failureRun.retryOf !== void 0 || failureRun.attempt !== void 0 && failureRun.attempt > 1 || pickNumber(eventMetadata(failure), ["attempt"]) !== void 0);
|
|
3296
|
+
if (isFinalInChain && failureRun?.status === "error" && !logicalEvents.some(
|
|
3297
|
+
(event) => event.runId === failure.runId && event.eventId !== failure.eventId && isSuccessful(event) && canonicalName(event) === canonicalName(failure)
|
|
3298
|
+
)) {
|
|
3299
|
+
return {
|
|
3300
|
+
eventId: failure.eventId,
|
|
3301
|
+
runId: failure.runId,
|
|
3302
|
+
name: failure.name,
|
|
3303
|
+
kind: failure.kind,
|
|
3304
|
+
role: "terminal",
|
|
3305
|
+
confidence: failureRun.retryOf !== void 0 ? "explicit" : "correlated",
|
|
3306
|
+
basis: Object.freeze(["final-retry-chain-member", "enclosing-run-error"]),
|
|
3307
|
+
recoveryEventIds: Object.freeze([]),
|
|
3308
|
+
retryRunIds: Object.freeze(
|
|
3309
|
+
failureRun.retryOf !== void 0 ? [failureRun.retryOf] : []
|
|
3310
|
+
)
|
|
3311
|
+
};
|
|
3312
|
+
}
|
|
3313
|
+
return {
|
|
3314
|
+
eventId: failure.eventId,
|
|
3315
|
+
runId: failure.runId,
|
|
3316
|
+
name: failure.name,
|
|
3317
|
+
kind: failure.kind,
|
|
3318
|
+
role: "unknown",
|
|
3319
|
+
confidence: "unknown",
|
|
3320
|
+
basis: Object.freeze(["no-explicit-or-correlated-recovery"]),
|
|
3321
|
+
recoveryEventIds: Object.freeze([]),
|
|
3322
|
+
retryRunIds: Object.freeze([])
|
|
3323
|
+
};
|
|
3324
|
+
}
|
|
3325
|
+
function deriveFailureFacts(logicalEvents) {
|
|
3326
|
+
const runs = buildRunContexts(logicalEvents);
|
|
3327
|
+
const failures = logicalEvents.filter((event) => isFailure(event)).sort(compareEventOrder);
|
|
3328
|
+
const failureFacts = failures.map(
|
|
3329
|
+
(failure) => classifyFailure(failure, collectCandidates(failure, logicalEvents, runs), runs, logicalEvents)
|
|
3330
|
+
);
|
|
3331
|
+
const byRole = /* @__PURE__ */ new Map([
|
|
3332
|
+
["transient", []],
|
|
3333
|
+
["recovered", []],
|
|
3334
|
+
["terminal", []],
|
|
3335
|
+
["unknown", []]
|
|
3336
|
+
]);
|
|
3337
|
+
for (const fact of failureFacts) {
|
|
3338
|
+
byRole.get(fact.role).push(fact);
|
|
3339
|
+
}
|
|
3340
|
+
for (const [role, list] of byRole) {
|
|
3341
|
+
byRole.set(
|
|
3342
|
+
role,
|
|
3343
|
+
Object.freeze(
|
|
3344
|
+
[...list].sort((a, b) => {
|
|
3345
|
+
const byRun = a.runId.localeCompare(b.runId);
|
|
3346
|
+
if (byRun !== 0) return byRun;
|
|
3347
|
+
return a.eventId.localeCompare(b.eventId);
|
|
3348
|
+
})
|
|
3349
|
+
)
|
|
3350
|
+
);
|
|
3351
|
+
}
|
|
3352
|
+
const failureRoleCounts = {
|
|
3353
|
+
transient: byRole.get("transient").length,
|
|
3354
|
+
recovered: byRole.get("recovered").length,
|
|
3355
|
+
terminal: byRole.get("terminal").length,
|
|
3356
|
+
unknown: byRole.get("unknown").length
|
|
3357
|
+
};
|
|
3358
|
+
return {
|
|
3359
|
+
failureFacts: Object.freeze(failureFacts),
|
|
3360
|
+
failuresByRole: byRole,
|
|
3361
|
+
failureRoleCounts
|
|
3362
|
+
};
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3006
3365
|
// packages/core/src/checks/trace-facts.ts
|
|
3007
3366
|
function summarizeSemanticParity(events) {
|
|
3008
3367
|
const projection = projectLogicalEvents(events);
|
|
@@ -3013,6 +3372,7 @@ function summarizeSemanticParity(events) {
|
|
|
3013
3372
|
const finishedToolNames = Object.freeze(
|
|
3014
3373
|
finishedTools.map((event) => resolveCanonicalToolName(event)).sort((a, b) => a.localeCompare(b))
|
|
3015
3374
|
);
|
|
3375
|
+
const derived = deriveFailureFacts(logical);
|
|
3016
3376
|
return {
|
|
3017
3377
|
rawEventCount: events.length,
|
|
3018
3378
|
logicalEventCount: logical.length,
|
|
@@ -3023,7 +3383,8 @@ function summarizeSemanticParity(events) {
|
|
|
3023
3383
|
parentRemapCount: projection.diagnostics.filter(
|
|
3024
3384
|
(item) => item.code === "AI_LOGICAL_PARENT_REMAPPED"
|
|
3025
3385
|
).length,
|
|
3026
|
-
diagnostics: projection.diagnostics
|
|
3386
|
+
diagnostics: projection.diagnostics,
|
|
3387
|
+
failureRoleCounts: derived.failureRoleCounts
|
|
3027
3388
|
};
|
|
3028
3389
|
}
|
|
3029
3390
|
var TRACE_FACTS_INPUT_NOT_NORMALIZED = formatProgrammaticDiagnostic(
|
|
@@ -3086,6 +3447,8 @@ function buildTraceFacts(input) {
|
|
|
3086
3447
|
for (const [name, list] of [...toolsByName.entries()]) {
|
|
3087
3448
|
toolsByName.set(name, Object.freeze([...list]));
|
|
3088
3449
|
}
|
|
3450
|
+
const derived = deriveFailureFacts(projection.logicalEvents);
|
|
3451
|
+
const summary = summarizeSemanticParity(events);
|
|
3089
3452
|
return {
|
|
3090
3453
|
rawEvents: Object.freeze([...events]),
|
|
3091
3454
|
logicalEvents: projection.logicalEvents,
|
|
@@ -3093,7 +3456,12 @@ function buildTraceFacts(input) {
|
|
|
3093
3456
|
toolsByName,
|
|
3094
3457
|
llmEvents: Object.freeze(llmEvents),
|
|
3095
3458
|
outcomeEvents: Object.freeze(outcomeEvents),
|
|
3096
|
-
summary:
|
|
3459
|
+
summary: {
|
|
3460
|
+
...summary,
|
|
3461
|
+
failureRoleCounts: derived.failureRoleCounts
|
|
3462
|
+
},
|
|
3463
|
+
failureFacts: derived.failureFacts,
|
|
3464
|
+
failuresByRole: derived.failuresByRole
|
|
3097
3465
|
};
|
|
3098
3466
|
}
|
|
3099
3467
|
|
|
@@ -3419,7 +3787,7 @@ function failFinding(ruleId, message, evidence, expected, actual, meta) {
|
|
|
3419
3787
|
function semanticEvents(context) {
|
|
3420
3788
|
return context.logicalEvents ?? context.events;
|
|
3421
3789
|
}
|
|
3422
|
-
function
|
|
3790
|
+
function isRecord8(value) {
|
|
3423
3791
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3424
3792
|
}
|
|
3425
3793
|
function normalizedKey(value) {
|
|
@@ -3450,7 +3818,7 @@ function pushValueEntries(entries, event, value, path17, key, depth = 0) {
|
|
|
3450
3818
|
}
|
|
3451
3819
|
return;
|
|
3452
3820
|
}
|
|
3453
|
-
if (!
|
|
3821
|
+
if (!isRecord8(value)) return;
|
|
3454
3822
|
for (const nestedKey of Object.keys(value).sort((a, b) => a.localeCompare(b))) {
|
|
3455
3823
|
pushValueEntries(
|
|
3456
3824
|
entries,
|
|
@@ -3698,7 +4066,7 @@ function createSafetyOversizedAttributeRule(options) {
|
|
|
3698
4066
|
)
|
|
3699
4067
|
);
|
|
3700
4068
|
}
|
|
3701
|
-
if (
|
|
4069
|
+
if (isRecord8(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
|
|
3702
4070
|
findings.push(
|
|
3703
4071
|
failFinding(
|
|
3704
4072
|
"safety.oversizedAttribute",
|
|
@@ -3816,14 +4184,14 @@ function runTraceChecks(input, options = {}) {
|
|
|
3816
4184
|
}
|
|
3817
4185
|
|
|
3818
4186
|
// packages/core/src/persisted/token-usage.ts
|
|
3819
|
-
function
|
|
4187
|
+
function isRecord9(value) {
|
|
3820
4188
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3821
4189
|
}
|
|
3822
4190
|
function nonNegativeFinite(value) {
|
|
3823
4191
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
3824
4192
|
}
|
|
3825
4193
|
function normalizeTokenUsage(value) {
|
|
3826
|
-
if (!
|
|
4194
|
+
if (!isRecord9(value)) return void 0;
|
|
3827
4195
|
const input = nonNegativeFinite(value.input);
|
|
3828
4196
|
const output = nonNegativeFinite(value.output);
|
|
3829
4197
|
const suppliedTotal = nonNegativeFinite(value.total);
|
|
@@ -4704,7 +5072,7 @@ function persistedEventsForParsedTrace(parsed) {
|
|
|
4704
5072
|
sourceName: "agent-inspect-jsonl-reader"
|
|
4705
5073
|
});
|
|
4706
5074
|
}
|
|
4707
|
-
function
|
|
5075
|
+
function isRecord10(value) {
|
|
4708
5076
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4709
5077
|
}
|
|
4710
5078
|
function isNonEmptyString3(value) {
|
|
@@ -4719,13 +5087,13 @@ function readStringField(record, keys) {
|
|
|
4719
5087
|
}
|
|
4720
5088
|
function readRecordField(record, key) {
|
|
4721
5089
|
const value = record[key];
|
|
4722
|
-
return
|
|
5090
|
+
return isRecord10(value) ? value : void 0;
|
|
4723
5091
|
}
|
|
4724
5092
|
function parseJsonDocument(content) {
|
|
4725
5093
|
return JSON.parse(content);
|
|
4726
5094
|
}
|
|
4727
5095
|
function looksLikeOpenInferenceSpan(value) {
|
|
4728
|
-
if (!
|
|
5096
|
+
if (!isRecord10(value)) return false;
|
|
4729
5097
|
const attributes = readRecordField(value, "attributes");
|
|
4730
5098
|
return readStringField(value, ["trace_id", "traceId"]) !== void 0 && readStringField(value, ["span_id", "spanId"]) !== void 0 && (readStringField(value, ["name"]) !== void 0 || attributes?.["openinference.span.kind"] !== void 0);
|
|
4731
5099
|
}
|
|
@@ -4750,7 +5118,7 @@ function extractOpenInferenceDocument(root) {
|
|
|
4750
5118
|
unsupportedFields
|
|
4751
5119
|
};
|
|
4752
5120
|
}
|
|
4753
|
-
if (!
|
|
5121
|
+
if (!isRecord10(root)) return void 0;
|
|
4754
5122
|
const rootFormat = root.format;
|
|
4755
5123
|
const rootCompatibility = root.compatibility;
|
|
4756
5124
|
const version = typeof root.version === "string" && root.version.trim() !== "" ? root.version : void 0;
|
|
@@ -4890,7 +5258,7 @@ function summarizeAttributeValue(value) {
|
|
|
4890
5258
|
if (Array.isArray(value)) {
|
|
4891
5259
|
return { type: "array", length: value.length };
|
|
4892
5260
|
}
|
|
4893
|
-
if (
|
|
5261
|
+
if (isRecord10(value)) {
|
|
4894
5262
|
return { type: "object", keyCount: Object.keys(value).length };
|
|
4895
5263
|
}
|
|
4896
5264
|
if (value === null) {
|
|
@@ -4977,7 +5345,7 @@ function mapOpenInferenceKind(span, attributes, pathPrefix) {
|
|
|
4977
5345
|
}
|
|
4978
5346
|
}
|
|
4979
5347
|
function mapOpenInferenceStatus(status) {
|
|
4980
|
-
if (!
|
|
5348
|
+
if (!isRecord10(status)) return void 0;
|
|
4981
5349
|
const rawCode = status.code;
|
|
4982
5350
|
if (typeof rawCode !== "string") return void 0;
|
|
4983
5351
|
switch (rawCode.toUpperCase()) {
|
|
@@ -5077,7 +5445,7 @@ function mapOpenInferenceSpan(span, index, version) {
|
|
|
5077
5445
|
warnings.push(...kindWarnings);
|
|
5078
5446
|
const status = mapOpenInferenceStatus(span.status);
|
|
5079
5447
|
const tokenUsage = readOpenInferenceTokenUsage(rawAttributes);
|
|
5080
|
-
const errorMessage =
|
|
5448
|
+
const errorMessage = isRecord10(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
|
|
5081
5449
|
const event = {
|
|
5082
5450
|
schemaVersion: "0.2",
|
|
5083
5451
|
eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : spanId,
|
|
@@ -5223,7 +5591,7 @@ var openInferenceJsonReader = {
|
|
|
5223
5591
|
}
|
|
5224
5592
|
};
|
|
5225
5593
|
function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
|
|
5226
|
-
if (!
|
|
5594
|
+
if (!isRecord10(value)) {
|
|
5227
5595
|
unsupportedFields.push(field);
|
|
5228
5596
|
warnings.push({
|
|
5229
5597
|
code: "otlp_attribute_value_invalid",
|
|
@@ -5245,15 +5613,15 @@ function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
|
|
|
5245
5613
|
if (typeof value.doubleValue === "number" && Number.isFinite(value.doubleValue)) {
|
|
5246
5614
|
return value.doubleValue;
|
|
5247
5615
|
}
|
|
5248
|
-
if (
|
|
5616
|
+
if (isRecord10(value.arrayValue) && Array.isArray(value.arrayValue.values)) {
|
|
5249
5617
|
return value.arrayValue.values.map(
|
|
5250
5618
|
(item, index) => parseOtlpAnyValue(item, `${field}.arrayValue.values[${index}]`, warnings, unsupportedFields)
|
|
5251
5619
|
);
|
|
5252
5620
|
}
|
|
5253
|
-
if (
|
|
5621
|
+
if (isRecord10(value.kvlistValue) && Array.isArray(value.kvlistValue.values)) {
|
|
5254
5622
|
const out = {};
|
|
5255
5623
|
for (const [index, item] of value.kvlistValue.values.entries()) {
|
|
5256
|
-
if (!
|
|
5624
|
+
if (!isRecord10(item) || typeof item.key !== "string") {
|
|
5257
5625
|
unsupportedFields.push(`${field}.kvlistValue.values[${index}]`);
|
|
5258
5626
|
continue;
|
|
5259
5627
|
}
|
|
@@ -5304,7 +5672,7 @@ function parseOtlpAttributes(value, pathPrefix) {
|
|
|
5304
5672
|
}
|
|
5305
5673
|
for (const [index, item] of value.entries()) {
|
|
5306
5674
|
const field = `${pathPrefix}[${index}]`;
|
|
5307
|
-
if (!
|
|
5675
|
+
if (!isRecord10(item) || typeof item.key !== "string") {
|
|
5308
5676
|
unsupportedFields.push(field);
|
|
5309
5677
|
warnings.push({
|
|
5310
5678
|
code: "otlp_attribute_invalid",
|
|
@@ -5327,16 +5695,16 @@ function parseOtlpAttributes(value, pathPrefix) {
|
|
|
5327
5695
|
return { attributes, warnings, unsupportedFields };
|
|
5328
5696
|
}
|
|
5329
5697
|
function looksLikeOtlpSpan(value) {
|
|
5330
|
-
return
|
|
5698
|
+
return isRecord10(value) && readStringField(value, ["traceId"]) !== void 0 && readStringField(value, ["spanId"]) !== void 0 && readStringField(value, ["name"]) !== void 0;
|
|
5331
5699
|
}
|
|
5332
5700
|
function extractOtlpDocument(root) {
|
|
5333
|
-
if (!
|
|
5701
|
+
if (!isRecord10(root) || !Array.isArray(root.resourceSpans)) return void 0;
|
|
5334
5702
|
const spans = [];
|
|
5335
5703
|
const warnings = [];
|
|
5336
5704
|
const unsupportedFields = [];
|
|
5337
5705
|
for (const [resourceIndex, resourceSpan] of root.resourceSpans.entries()) {
|
|
5338
5706
|
const resourcePath = `resourceSpans[${resourceIndex}]`;
|
|
5339
|
-
if (!
|
|
5707
|
+
if (!isRecord10(resourceSpan)) {
|
|
5340
5708
|
unsupportedFields.push(resourcePath);
|
|
5341
5709
|
continue;
|
|
5342
5710
|
}
|
|
@@ -5359,7 +5727,7 @@ function extractOtlpDocument(root) {
|
|
|
5359
5727
|
}
|
|
5360
5728
|
for (const [scopeIndex, scopeSpan] of resourceSpan.scopeSpans.entries()) {
|
|
5361
5729
|
const scopePath = `${resourcePath}.scopeSpans[${scopeIndex}]`;
|
|
5362
|
-
if (!
|
|
5730
|
+
if (!isRecord10(scopeSpan)) {
|
|
5363
5731
|
unsupportedFields.push(scopePath);
|
|
5364
5732
|
continue;
|
|
5365
5733
|
}
|
|
@@ -5426,7 +5794,7 @@ function extractOtlpDocument(root) {
|
|
|
5426
5794
|
};
|
|
5427
5795
|
}
|
|
5428
5796
|
function mapOtlpStatus(status) {
|
|
5429
|
-
if (!
|
|
5797
|
+
if (!isRecord10(status)) return void 0;
|
|
5430
5798
|
const rawCode = status.code;
|
|
5431
5799
|
if (typeof rawCode !== "string") return void 0;
|
|
5432
5800
|
switch (rawCode.toUpperCase()) {
|
|
@@ -5526,7 +5894,7 @@ function mapOtlpEvents(value, pathPrefix) {
|
|
|
5526
5894
|
const events = [];
|
|
5527
5895
|
for (const [index, event] of value.entries()) {
|
|
5528
5896
|
const eventPath = `${pathPrefix}[${index}]`;
|
|
5529
|
-
if (!
|
|
5897
|
+
if (!isRecord10(event)) {
|
|
5530
5898
|
unsupportedFields.push(eventPath);
|
|
5531
5899
|
continue;
|
|
5532
5900
|
}
|
|
@@ -5664,7 +6032,7 @@ function mapOtlpSpan(context) {
|
|
|
5664
6032
|
warnings.push(...kindWarnings);
|
|
5665
6033
|
const status = mapOtlpStatus(span.status);
|
|
5666
6034
|
const tokenUsage = readOtlpTokenUsage(parsedSpanAttributes.attributes);
|
|
5667
|
-
const errorMessage =
|
|
6035
|
+
const errorMessage = isRecord10(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
|
|
5668
6036
|
const event = {
|
|
5669
6037
|
schemaVersion: "0.2",
|
|
5670
6038
|
eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : spanId,
|
|
@@ -6015,7 +6383,7 @@ function openTrace(input, options = {}) {
|
|
|
6015
6383
|
var EXPORT_PAYLOAD_VERSION = "0.1.2";
|
|
6016
6384
|
|
|
6017
6385
|
// packages/core/src/exporters/redact-export.ts
|
|
6018
|
-
function
|
|
6386
|
+
function isRecord11(value) {
|
|
6019
6387
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6020
6388
|
}
|
|
6021
6389
|
function deepClone(value) {
|
|
@@ -6089,7 +6457,7 @@ function redactEventAttributes(attrs, redactor, maxMetadataValueLength, maxPrevi
|
|
|
6089
6457
|
0
|
|
6090
6458
|
);
|
|
6091
6459
|
const err = bounded.error;
|
|
6092
|
-
if (
|
|
6460
|
+
if (isRecord11(err) && typeof err.message === "string") {
|
|
6093
6461
|
bounded.error = {
|
|
6094
6462
|
...err,
|
|
6095
6463
|
message: truncateStringForProfile(
|
|
@@ -6814,7 +7182,7 @@ var STRICT_PROFILE_EXTRA_KEYS2 = [
|
|
|
6814
7182
|
"retrieval",
|
|
6815
7183
|
"query"
|
|
6816
7184
|
];
|
|
6817
|
-
function
|
|
7185
|
+
function isRecord12(value) {
|
|
6818
7186
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6819
7187
|
}
|
|
6820
7188
|
function toKey2(key) {
|
|
@@ -7194,7 +7562,7 @@ var Redactor2 = class {
|
|
|
7194
7562
|
});
|
|
7195
7563
|
return out;
|
|
7196
7564
|
}
|
|
7197
|
-
if (
|
|
7565
|
+
if (isRecord12(value)) {
|
|
7198
7566
|
if (state.seen.has(value)) return state.seen.get(value);
|
|
7199
7567
|
const out = {};
|
|
7200
7568
|
state.seen.set(value, out);
|
|
@@ -7613,7 +7981,18 @@ async function callReadOnlyTool(context, name, args = {}) {
|
|
|
7613
7981
|
toolNames: [...facts.toolsByName.keys()].sort((a, b) => a.localeCompare(b)),
|
|
7614
7982
|
llmCount: facts.llmEvents.length,
|
|
7615
7983
|
outcomeCount: facts.outcomeEvents.length,
|
|
7616
|
-
|
|
7984
|
+
failureRoleCounts: facts.summary.failureRoleCounts ?? {
|
|
7985
|
+
transient: 0,
|
|
7986
|
+
recovered: 0,
|
|
7987
|
+
terminal: 0,
|
|
7988
|
+
unknown: 0
|
|
7989
|
+
},
|
|
7990
|
+
failureFactIds: facts.failureFacts.map((fact) => ({
|
|
7991
|
+
eventId: fact.eventId,
|
|
7992
|
+
role: fact.role,
|
|
7993
|
+
confidence: fact.confidence
|
|
7994
|
+
})),
|
|
7995
|
+
note: "Bounded TraceFacts summary only; raw events, prompts, and error bodies are not included. Failure roles are derived classifications over recorded evidence."
|
|
7617
7996
|
},
|
|
7618
7997
|
context
|
|
7619
7998
|
);
|