@agent-inspect/mcp-server 6.18.0 → 6.19.0

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.
@@ -2993,6 +2993,325 @@ function pickString(record, keys) {
2993
2993
  return void 0;
2994
2994
  }
2995
2995
 
2996
+ // packages/core/src/checks/derived-failure.ts
2997
+ function isRecord7(value) {
2998
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2999
+ }
3000
+ function pickString2(record, keys) {
3001
+ if (!record) return void 0;
3002
+ for (const key of keys) {
3003
+ const value = record[key];
3004
+ if (typeof value === "string" && value.trim() !== "") return value;
3005
+ }
3006
+ return void 0;
3007
+ }
3008
+ function pickNumber(record, keys) {
3009
+ if (!record) return void 0;
3010
+ for (const key of keys) {
3011
+ const value = record[key];
3012
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
3013
+ return value;
3014
+ }
3015
+ }
3016
+ return void 0;
3017
+ }
3018
+ function eventMetadata(event) {
3019
+ const attrs = isRecord7(event.attributes) ? event.attributes : void 0;
3020
+ const nested = attrs !== void 0 && isRecord7(attrs.metadata) ? attrs.metadata : void 0;
3021
+ return {
3022
+ ...attrs ?? {},
3023
+ ...nested ?? {}
3024
+ };
3025
+ }
3026
+ function canonicalName(event) {
3027
+ if (event.kind === "TOOL") return resolveCanonicalToolName(event);
3028
+ return event.name;
3029
+ }
3030
+ function linkKeys(event) {
3031
+ const meta = eventMetadata(event);
3032
+ const keys = [];
3033
+ for (const key of ["linkedStepId", "toolCallId", "mcpToolCallId"]) {
3034
+ const value = pickString2(meta, [key]);
3035
+ if (value !== void 0) keys.push(`${key}:${value}`);
3036
+ }
3037
+ const stepId = pickString2(meta, ["stepId"]);
3038
+ if (stepId !== void 0) keys.push(`stepId:${stepId}`);
3039
+ return keys;
3040
+ }
3041
+ function buildRunContexts(logicalEvents) {
3042
+ const byRun = /* @__PURE__ */ new Map();
3043
+ for (const event of logicalEvents) {
3044
+ const existing = byRun.get(event.runId) ?? {
3045
+ runId: event.runId,
3046
+ name: event.name
3047
+ };
3048
+ const meta = eventMetadata(event);
3049
+ if (event.kind === "RUN" || existing.name === event.runId) {
3050
+ existing.name = event.name || existing.name;
3051
+ }
3052
+ if (event.kind === "RUN" && event.status !== void 0 && event.status !== "running") {
3053
+ existing.status = event.status;
3054
+ }
3055
+ existing.retryOf ??= pickString2(meta, ["retryOf"]);
3056
+ existing.attempt ??= pickNumber(meta, ["attempt", "retryAttempt", "retryCount"]);
3057
+ existing.sessionId ??= pickString2(meta, ["sessionId", "conversationId"]);
3058
+ existing.groupId ??= pickString2(meta, ["groupId"]);
3059
+ existing.parentGroupId ??= pickString2(meta, ["parentGroupId"]);
3060
+ existing.fallbackOf ??= pickString2(meta, ["fallbackOf", "fallbackFrom"]);
3061
+ byRun.set(event.runId, existing);
3062
+ }
3063
+ return byRun;
3064
+ }
3065
+ function sameCorrelationScope(a, b) {
3066
+ if (a.sessionId && b.sessionId && a.sessionId === b.sessionId) return true;
3067
+ if (a.groupId && b.groupId && a.groupId === b.groupId) return true;
3068
+ if (a.parentGroupId && b.parentGroupId && a.parentGroupId === b.parentGroupId) {
3069
+ return true;
3070
+ }
3071
+ return false;
3072
+ }
3073
+ function isSuccessful(event) {
3074
+ return event.status === "ok";
3075
+ }
3076
+ function isFailure(event) {
3077
+ return event.status === "error";
3078
+ }
3079
+ function compareEventOrder(a, b) {
3080
+ const byTime = a.timestamp.localeCompare(b.timestamp);
3081
+ if (byTime !== 0) return byTime;
3082
+ return a.eventId.localeCompare(b.eventId);
3083
+ }
3084
+ function collectCandidates(failure, logicalEvents, runs) {
3085
+ const failureRun = runs.get(failure.runId);
3086
+ const failureLinks = new Set(linkKeys(failure));
3087
+ const failureName = canonicalName(failure);
3088
+ const failureAttempt = pickNumber(eventMetadata(failure), ["attempt", "retryAttempt", "retryCount"]) ?? failureRun?.attempt;
3089
+ const candidates = [];
3090
+ for (const event of logicalEvents) {
3091
+ if (event.eventId === failure.eventId) continue;
3092
+ if (event.status === "running") continue;
3093
+ const eventRun = runs.get(event.runId);
3094
+ const eventMeta = eventMetadata(event);
3095
+ const sameRun = event.runId === failure.runId;
3096
+ if (eventRun?.retryOf === failure.runId) {
3097
+ candidates.push({
3098
+ event,
3099
+ basis: "retryOf",
3100
+ confidence: "explicit",
3101
+ viaRunId: event.runId
3102
+ });
3103
+ continue;
3104
+ }
3105
+ if (eventRun?.fallbackOf === failure.runId || pickString2(eventMeta, ["fallbackOf", "fallbackFrom"]) === failure.runId) {
3106
+ candidates.push({
3107
+ event,
3108
+ basis: "fallbackOf",
3109
+ confidence: "explicit",
3110
+ viaRunId: event.runId
3111
+ });
3112
+ continue;
3113
+ }
3114
+ if (sameRun && compareEventOrder(failure, event) >= 0) continue;
3115
+ const eventLinks = linkKeys(event);
3116
+ const sharedLink = eventLinks.find((key) => failureLinks.has(key));
3117
+ if (sharedLink !== void 0) {
3118
+ candidates.push({
3119
+ event,
3120
+ basis: sharedLink.split(":")[0] ?? "linkedId",
3121
+ confidence: "explicit"
3122
+ });
3123
+ continue;
3124
+ }
3125
+ const eventAttempt = pickNumber(eventMeta, ["attempt", "retryAttempt", "retryCount"]) ?? eventRun?.attempt;
3126
+ const sameParent = failure.parentId !== void 0 && event.parentId !== void 0 && failure.parentId === event.parentId;
3127
+ const differentParent = failure.parentId !== void 0 && event.parentId !== void 0 && failure.parentId !== event.parentId;
3128
+ const sessionScoped = failureRun !== void 0 && eventRun !== void 0 && sameCorrelationScope(failureRun, eventRun);
3129
+ if (canonicalName(event) === failureName && failureAttempt !== void 0 && eventAttempt !== void 0 && eventAttempt > failureAttempt && !differentParent && (sameParent || sessionScoped || sameRun)) {
3130
+ candidates.push({
3131
+ event,
3132
+ basis: "attempt-progression",
3133
+ confidence: "correlated",
3134
+ ...event.runId !== failure.runId ? { viaRunId: event.runId } : {}
3135
+ });
3136
+ }
3137
+ }
3138
+ const byId = /* @__PURE__ */ new Map();
3139
+ for (const candidate of candidates) {
3140
+ const prev = byId.get(candidate.event.eventId);
3141
+ if (!prev || prev.confidence !== "explicit" && candidate.confidence === "explicit") {
3142
+ byId.set(candidate.event.eventId, candidate);
3143
+ }
3144
+ }
3145
+ return [...byId.values()].sort((a, b) => compareEventOrder(a.event, b.event));
3146
+ }
3147
+ function classifyFailure(failure, candidates, runs, logicalEvents) {
3148
+ const successful = candidates.filter((c) => isSuccessful(c.event));
3149
+ const unsuccessful = candidates.filter((c) => !isSuccessful(c.event));
3150
+ const retryRunIds = Object.freeze(
3151
+ [...new Set(candidates.map((c) => c.viaRunId).filter((id) => id !== void 0))].sort(
3152
+ (a, b) => a.localeCompare(b)
3153
+ )
3154
+ );
3155
+ if (successful.length > 1) {
3156
+ const distinctRuns = new Set(successful.map((c) => c.event.runId));
3157
+ const distinctParents = new Set(
3158
+ successful.map((c) => c.event.parentId ?? "").filter((id) => id !== "")
3159
+ );
3160
+ if (distinctRuns.size > 1 || distinctParents.size > 1) {
3161
+ return {
3162
+ eventId: failure.eventId,
3163
+ runId: failure.runId,
3164
+ name: failure.name,
3165
+ kind: failure.kind,
3166
+ role: "unknown",
3167
+ confidence: "unknown",
3168
+ basis: Object.freeze(["ambiguous-recovery-candidates"]),
3169
+ recoveryEventIds: Object.freeze(
3170
+ successful.map((c) => c.event.eventId).sort((a, b) => a.localeCompare(b))
3171
+ ),
3172
+ retryRunIds
3173
+ };
3174
+ }
3175
+ }
3176
+ if (successful.length >= 1) {
3177
+ const best = successful[0];
3178
+ return {
3179
+ eventId: failure.eventId,
3180
+ runId: failure.runId,
3181
+ name: failure.name,
3182
+ kind: failure.kind,
3183
+ role: "recovered",
3184
+ confidence: best.confidence,
3185
+ basis: Object.freeze([best.basis]),
3186
+ recoveryEventIds: Object.freeze(
3187
+ successful.map((c) => c.event.eventId).sort((a, b) => a.localeCompare(b))
3188
+ ),
3189
+ retryRunIds
3190
+ };
3191
+ }
3192
+ if (candidates.length > 0) {
3193
+ const best = candidates[0];
3194
+ return {
3195
+ eventId: failure.eventId,
3196
+ runId: failure.runId,
3197
+ name: failure.name,
3198
+ kind: failure.kind,
3199
+ role: "transient",
3200
+ confidence: best.confidence,
3201
+ basis: Object.freeze([
3202
+ best.basis,
3203
+ unsuccessful.some((c) => c.event.status === void 0) ? "retry-incomplete" : "retry-without-success"
3204
+ ]),
3205
+ recoveryEventIds: Object.freeze([]),
3206
+ retryRunIds
3207
+ };
3208
+ }
3209
+ const failureMeta = eventMetadata(failure);
3210
+ const declaredSuccessor = pickString2(failureMeta, [
3211
+ "retriedBy",
3212
+ "nextRetryRunId",
3213
+ "retryRunId"
3214
+ ]);
3215
+ if (declaredSuccessor !== void 0 && !runs.has(declaredSuccessor)) {
3216
+ return {
3217
+ eventId: failure.eventId,
3218
+ runId: failure.runId,
3219
+ name: failure.name,
3220
+ kind: failure.kind,
3221
+ role: "transient",
3222
+ confidence: "explicit",
3223
+ basis: Object.freeze(["retry-declared", "retry-run-missing"]),
3224
+ recoveryEventIds: Object.freeze([]),
3225
+ retryRunIds: Object.freeze([declaredSuccessor])
3226
+ };
3227
+ }
3228
+ for (const run of runs.values()) {
3229
+ if (run.retryOf === failure.runId) {
3230
+ return {
3231
+ eventId: failure.eventId,
3232
+ runId: failure.runId,
3233
+ name: failure.name,
3234
+ kind: failure.kind,
3235
+ role: "transient",
3236
+ confidence: "explicit",
3237
+ basis: Object.freeze(["retryOf", "retry-run-missing-or-empty"]),
3238
+ recoveryEventIds: Object.freeze([]),
3239
+ retryRunIds: Object.freeze([run.runId])
3240
+ };
3241
+ }
3242
+ }
3243
+ const failureRun = runs.get(failure.runId);
3244
+ const hasSuccessorDeclared = [...runs.values()].some((run) => run.retryOf === failure.runId);
3245
+ const isFinalInChain = failureRun !== void 0 && !hasSuccessorDeclared && (failureRun.retryOf !== void 0 || failureRun.attempt !== void 0 && failureRun.attempt > 1 || pickNumber(eventMetadata(failure), ["attempt"]) !== void 0);
3246
+ if (isFinalInChain && failureRun?.status === "error" && !logicalEvents.some(
3247
+ (event) => event.runId === failure.runId && event.eventId !== failure.eventId && isSuccessful(event) && canonicalName(event) === canonicalName(failure)
3248
+ )) {
3249
+ return {
3250
+ eventId: failure.eventId,
3251
+ runId: failure.runId,
3252
+ name: failure.name,
3253
+ kind: failure.kind,
3254
+ role: "terminal",
3255
+ confidence: failureRun.retryOf !== void 0 ? "explicit" : "correlated",
3256
+ basis: Object.freeze(["final-retry-chain-member", "enclosing-run-error"]),
3257
+ recoveryEventIds: Object.freeze([]),
3258
+ retryRunIds: Object.freeze(
3259
+ failureRun.retryOf !== void 0 ? [failureRun.retryOf] : []
3260
+ )
3261
+ };
3262
+ }
3263
+ return {
3264
+ eventId: failure.eventId,
3265
+ runId: failure.runId,
3266
+ name: failure.name,
3267
+ kind: failure.kind,
3268
+ role: "unknown",
3269
+ confidence: "unknown",
3270
+ basis: Object.freeze(["no-explicit-or-correlated-recovery"]),
3271
+ recoveryEventIds: Object.freeze([]),
3272
+ retryRunIds: Object.freeze([])
3273
+ };
3274
+ }
3275
+ function deriveFailureFacts(logicalEvents) {
3276
+ const runs = buildRunContexts(logicalEvents);
3277
+ const failures = logicalEvents.filter((event) => isFailure(event)).sort(compareEventOrder);
3278
+ const failureFacts = failures.map(
3279
+ (failure) => classifyFailure(failure, collectCandidates(failure, logicalEvents, runs), runs, logicalEvents)
3280
+ );
3281
+ const byRole = /* @__PURE__ */ new Map([
3282
+ ["transient", []],
3283
+ ["recovered", []],
3284
+ ["terminal", []],
3285
+ ["unknown", []]
3286
+ ]);
3287
+ for (const fact of failureFacts) {
3288
+ byRole.get(fact.role).push(fact);
3289
+ }
3290
+ for (const [role, list] of byRole) {
3291
+ byRole.set(
3292
+ role,
3293
+ Object.freeze(
3294
+ [...list].sort((a, b) => {
3295
+ const byRun = a.runId.localeCompare(b.runId);
3296
+ if (byRun !== 0) return byRun;
3297
+ return a.eventId.localeCompare(b.eventId);
3298
+ })
3299
+ )
3300
+ );
3301
+ }
3302
+ const failureRoleCounts = {
3303
+ transient: byRole.get("transient").length,
3304
+ recovered: byRole.get("recovered").length,
3305
+ terminal: byRole.get("terminal").length,
3306
+ unknown: byRole.get("unknown").length
3307
+ };
3308
+ return {
3309
+ failureFacts: Object.freeze(failureFacts),
3310
+ failuresByRole: byRole,
3311
+ failureRoleCounts
3312
+ };
3313
+ }
3314
+
2996
3315
  // packages/core/src/checks/trace-facts.ts
2997
3316
  function summarizeSemanticParity(events) {
2998
3317
  const projection = projectLogicalEvents(events);
@@ -3003,6 +3322,7 @@ function summarizeSemanticParity(events) {
3003
3322
  const finishedToolNames = Object.freeze(
3004
3323
  finishedTools.map((event) => resolveCanonicalToolName(event)).sort((a, b) => a.localeCompare(b))
3005
3324
  );
3325
+ const derived = deriveFailureFacts(logical);
3006
3326
  return {
3007
3327
  rawEventCount: events.length,
3008
3328
  logicalEventCount: logical.length,
@@ -3013,7 +3333,8 @@ function summarizeSemanticParity(events) {
3013
3333
  parentRemapCount: projection.diagnostics.filter(
3014
3334
  (item) => item.code === "AI_LOGICAL_PARENT_REMAPPED"
3015
3335
  ).length,
3016
- diagnostics: projection.diagnostics
3336
+ diagnostics: projection.diagnostics,
3337
+ failureRoleCounts: derived.failureRoleCounts
3017
3338
  };
3018
3339
  }
3019
3340
  var TRACE_FACTS_INPUT_NOT_NORMALIZED = formatProgrammaticDiagnostic(
@@ -3076,6 +3397,8 @@ function buildTraceFacts(input) {
3076
3397
  for (const [name, list] of [...toolsByName.entries()]) {
3077
3398
  toolsByName.set(name, Object.freeze([...list]));
3078
3399
  }
3400
+ const derived = deriveFailureFacts(projection.logicalEvents);
3401
+ const summary = summarizeSemanticParity(events);
3079
3402
  return {
3080
3403
  rawEvents: Object.freeze([...events]),
3081
3404
  logicalEvents: projection.logicalEvents,
@@ -3083,7 +3406,12 @@ function buildTraceFacts(input) {
3083
3406
  toolsByName,
3084
3407
  llmEvents: Object.freeze(llmEvents),
3085
3408
  outcomeEvents: Object.freeze(outcomeEvents),
3086
- summary: summarizeSemanticParity(events)
3409
+ summary: {
3410
+ ...summary,
3411
+ failureRoleCounts: derived.failureRoleCounts
3412
+ },
3413
+ failureFacts: derived.failureFacts,
3414
+ failuresByRole: derived.failuresByRole
3087
3415
  };
3088
3416
  }
3089
3417
 
@@ -3409,7 +3737,7 @@ function failFinding(ruleId, message, evidence, expected, actual, meta) {
3409
3737
  function semanticEvents(context) {
3410
3738
  return context.logicalEvents ?? context.events;
3411
3739
  }
3412
- function isRecord7(value) {
3740
+ function isRecord8(value) {
3413
3741
  return typeof value === "object" && value !== null && !Array.isArray(value);
3414
3742
  }
3415
3743
  function normalizedKey(value) {
@@ -3440,7 +3768,7 @@ function pushValueEntries(entries, event, value, path16, key, depth = 0) {
3440
3768
  }
3441
3769
  return;
3442
3770
  }
3443
- if (!isRecord7(value)) return;
3771
+ if (!isRecord8(value)) return;
3444
3772
  for (const nestedKey of Object.keys(value).sort((a, b) => a.localeCompare(b))) {
3445
3773
  pushValueEntries(
3446
3774
  entries,
@@ -3688,7 +4016,7 @@ function createSafetyOversizedAttributeRule(options) {
3688
4016
  )
3689
4017
  );
3690
4018
  }
3691
- if (isRecord7(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
4019
+ if (isRecord8(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
3692
4020
  findings.push(
3693
4021
  failFinding(
3694
4022
  "safety.oversizedAttribute",
@@ -3806,14 +4134,14 @@ function runTraceChecks(input, options = {}) {
3806
4134
  }
3807
4135
 
3808
4136
  // packages/core/src/persisted/token-usage.ts
3809
- function isRecord8(value) {
4137
+ function isRecord9(value) {
3810
4138
  return typeof value === "object" && value !== null && !Array.isArray(value);
3811
4139
  }
3812
4140
  function nonNegativeFinite(value) {
3813
4141
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
3814
4142
  }
3815
4143
  function normalizeTokenUsage(value) {
3816
- if (!isRecord8(value)) return void 0;
4144
+ if (!isRecord9(value)) return void 0;
3817
4145
  const input = nonNegativeFinite(value.input);
3818
4146
  const output = nonNegativeFinite(value.output);
3819
4147
  const suppliedTotal = nonNegativeFinite(value.total);
@@ -4694,7 +5022,7 @@ function persistedEventsForParsedTrace(parsed) {
4694
5022
  sourceName: "agent-inspect-jsonl-reader"
4695
5023
  });
4696
5024
  }
4697
- function isRecord9(value) {
5025
+ function isRecord10(value) {
4698
5026
  return typeof value === "object" && value !== null && !Array.isArray(value);
4699
5027
  }
4700
5028
  function isNonEmptyString3(value) {
@@ -4709,13 +5037,13 @@ function readStringField(record, keys) {
4709
5037
  }
4710
5038
  function readRecordField(record, key) {
4711
5039
  const value = record[key];
4712
- return isRecord9(value) ? value : void 0;
5040
+ return isRecord10(value) ? value : void 0;
4713
5041
  }
4714
5042
  function parseJsonDocument(content) {
4715
5043
  return JSON.parse(content);
4716
5044
  }
4717
5045
  function looksLikeOpenInferenceSpan(value) {
4718
- if (!isRecord9(value)) return false;
5046
+ if (!isRecord10(value)) return false;
4719
5047
  const attributes = readRecordField(value, "attributes");
4720
5048
  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);
4721
5049
  }
@@ -4740,7 +5068,7 @@ function extractOpenInferenceDocument(root) {
4740
5068
  unsupportedFields
4741
5069
  };
4742
5070
  }
4743
- if (!isRecord9(root)) return void 0;
5071
+ if (!isRecord10(root)) return void 0;
4744
5072
  const rootFormat = root.format;
4745
5073
  const rootCompatibility = root.compatibility;
4746
5074
  const version = typeof root.version === "string" && root.version.trim() !== "" ? root.version : void 0;
@@ -4880,7 +5208,7 @@ function summarizeAttributeValue(value) {
4880
5208
  if (Array.isArray(value)) {
4881
5209
  return { type: "array", length: value.length };
4882
5210
  }
4883
- if (isRecord9(value)) {
5211
+ if (isRecord10(value)) {
4884
5212
  return { type: "object", keyCount: Object.keys(value).length };
4885
5213
  }
4886
5214
  if (value === null) {
@@ -4967,7 +5295,7 @@ function mapOpenInferenceKind(span, attributes, pathPrefix) {
4967
5295
  }
4968
5296
  }
4969
5297
  function mapOpenInferenceStatus(status) {
4970
- if (!isRecord9(status)) return void 0;
5298
+ if (!isRecord10(status)) return void 0;
4971
5299
  const rawCode = status.code;
4972
5300
  if (typeof rawCode !== "string") return void 0;
4973
5301
  switch (rawCode.toUpperCase()) {
@@ -5067,7 +5395,7 @@ function mapOpenInferenceSpan(span, index, version) {
5067
5395
  warnings.push(...kindWarnings);
5068
5396
  const status = mapOpenInferenceStatus(span.status);
5069
5397
  const tokenUsage = readOpenInferenceTokenUsage(rawAttributes);
5070
- const errorMessage = isRecord9(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
5398
+ const errorMessage = isRecord10(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
5071
5399
  const event = {
5072
5400
  schemaVersion: "0.2",
5073
5401
  eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : spanId,
@@ -5213,7 +5541,7 @@ var openInferenceJsonReader = {
5213
5541
  }
5214
5542
  };
5215
5543
  function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
5216
- if (!isRecord9(value)) {
5544
+ if (!isRecord10(value)) {
5217
5545
  unsupportedFields.push(field);
5218
5546
  warnings.push({
5219
5547
  code: "otlp_attribute_value_invalid",
@@ -5235,15 +5563,15 @@ function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
5235
5563
  if (typeof value.doubleValue === "number" && Number.isFinite(value.doubleValue)) {
5236
5564
  return value.doubleValue;
5237
5565
  }
5238
- if (isRecord9(value.arrayValue) && Array.isArray(value.arrayValue.values)) {
5566
+ if (isRecord10(value.arrayValue) && Array.isArray(value.arrayValue.values)) {
5239
5567
  return value.arrayValue.values.map(
5240
5568
  (item, index) => parseOtlpAnyValue(item, `${field}.arrayValue.values[${index}]`, warnings, unsupportedFields)
5241
5569
  );
5242
5570
  }
5243
- if (isRecord9(value.kvlistValue) && Array.isArray(value.kvlistValue.values)) {
5571
+ if (isRecord10(value.kvlistValue) && Array.isArray(value.kvlistValue.values)) {
5244
5572
  const out = {};
5245
5573
  for (const [index, item] of value.kvlistValue.values.entries()) {
5246
- if (!isRecord9(item) || typeof item.key !== "string") {
5574
+ if (!isRecord10(item) || typeof item.key !== "string") {
5247
5575
  unsupportedFields.push(`${field}.kvlistValue.values[${index}]`);
5248
5576
  continue;
5249
5577
  }
@@ -5294,7 +5622,7 @@ function parseOtlpAttributes(value, pathPrefix) {
5294
5622
  }
5295
5623
  for (const [index, item] of value.entries()) {
5296
5624
  const field = `${pathPrefix}[${index}]`;
5297
- if (!isRecord9(item) || typeof item.key !== "string") {
5625
+ if (!isRecord10(item) || typeof item.key !== "string") {
5298
5626
  unsupportedFields.push(field);
5299
5627
  warnings.push({
5300
5628
  code: "otlp_attribute_invalid",
@@ -5317,16 +5645,16 @@ function parseOtlpAttributes(value, pathPrefix) {
5317
5645
  return { attributes, warnings, unsupportedFields };
5318
5646
  }
5319
5647
  function looksLikeOtlpSpan(value) {
5320
- return isRecord9(value) && readStringField(value, ["traceId"]) !== void 0 && readStringField(value, ["spanId"]) !== void 0 && readStringField(value, ["name"]) !== void 0;
5648
+ return isRecord10(value) && readStringField(value, ["traceId"]) !== void 0 && readStringField(value, ["spanId"]) !== void 0 && readStringField(value, ["name"]) !== void 0;
5321
5649
  }
5322
5650
  function extractOtlpDocument(root) {
5323
- if (!isRecord9(root) || !Array.isArray(root.resourceSpans)) return void 0;
5651
+ if (!isRecord10(root) || !Array.isArray(root.resourceSpans)) return void 0;
5324
5652
  const spans = [];
5325
5653
  const warnings = [];
5326
5654
  const unsupportedFields = [];
5327
5655
  for (const [resourceIndex, resourceSpan] of root.resourceSpans.entries()) {
5328
5656
  const resourcePath = `resourceSpans[${resourceIndex}]`;
5329
- if (!isRecord9(resourceSpan)) {
5657
+ if (!isRecord10(resourceSpan)) {
5330
5658
  unsupportedFields.push(resourcePath);
5331
5659
  continue;
5332
5660
  }
@@ -5349,7 +5677,7 @@ function extractOtlpDocument(root) {
5349
5677
  }
5350
5678
  for (const [scopeIndex, scopeSpan] of resourceSpan.scopeSpans.entries()) {
5351
5679
  const scopePath = `${resourcePath}.scopeSpans[${scopeIndex}]`;
5352
- if (!isRecord9(scopeSpan)) {
5680
+ if (!isRecord10(scopeSpan)) {
5353
5681
  unsupportedFields.push(scopePath);
5354
5682
  continue;
5355
5683
  }
@@ -5416,7 +5744,7 @@ function extractOtlpDocument(root) {
5416
5744
  };
5417
5745
  }
5418
5746
  function mapOtlpStatus(status) {
5419
- if (!isRecord9(status)) return void 0;
5747
+ if (!isRecord10(status)) return void 0;
5420
5748
  const rawCode = status.code;
5421
5749
  if (typeof rawCode !== "string") return void 0;
5422
5750
  switch (rawCode.toUpperCase()) {
@@ -5516,7 +5844,7 @@ function mapOtlpEvents(value, pathPrefix) {
5516
5844
  const events = [];
5517
5845
  for (const [index, event] of value.entries()) {
5518
5846
  const eventPath = `${pathPrefix}[${index}]`;
5519
- if (!isRecord9(event)) {
5847
+ if (!isRecord10(event)) {
5520
5848
  unsupportedFields.push(eventPath);
5521
5849
  continue;
5522
5850
  }
@@ -5654,7 +5982,7 @@ function mapOtlpSpan(context) {
5654
5982
  warnings.push(...kindWarnings);
5655
5983
  const status = mapOtlpStatus(span.status);
5656
5984
  const tokenUsage = readOtlpTokenUsage(parsedSpanAttributes.attributes);
5657
- const errorMessage = isRecord9(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
5985
+ const errorMessage = isRecord10(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
5658
5986
  const event = {
5659
5987
  schemaVersion: "0.2",
5660
5988
  eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : spanId,
@@ -6005,7 +6333,7 @@ function openTrace(input, options = {}) {
6005
6333
  var EXPORT_PAYLOAD_VERSION = "0.1.2";
6006
6334
 
6007
6335
  // packages/core/src/exporters/redact-export.ts
6008
- function isRecord10(value) {
6336
+ function isRecord11(value) {
6009
6337
  return typeof value === "object" && value !== null && !Array.isArray(value);
6010
6338
  }
6011
6339
  function deepClone(value) {
@@ -6079,7 +6407,7 @@ function redactEventAttributes(attrs, redactor, maxMetadataValueLength, maxPrevi
6079
6407
  0
6080
6408
  );
6081
6409
  const err = bounded.error;
6082
- if (isRecord10(err) && typeof err.message === "string") {
6410
+ if (isRecord11(err) && typeof err.message === "string") {
6083
6411
  bounded.error = {
6084
6412
  ...err,
6085
6413
  message: truncateStringForProfile(
@@ -6804,7 +7132,7 @@ var STRICT_PROFILE_EXTRA_KEYS2 = [
6804
7132
  "retrieval",
6805
7133
  "query"
6806
7134
  ];
6807
- function isRecord11(value) {
7135
+ function isRecord12(value) {
6808
7136
  return typeof value === "object" && value !== null && !Array.isArray(value);
6809
7137
  }
6810
7138
  function toKey2(key) {
@@ -7184,7 +7512,7 @@ var Redactor2 = class {
7184
7512
  });
7185
7513
  return out;
7186
7514
  }
7187
- if (isRecord11(value)) {
7515
+ if (isRecord12(value)) {
7188
7516
  if (state.seen.has(value)) return state.seen.get(value);
7189
7517
  const out = {};
7190
7518
  state.seen.set(value, out);
@@ -7603,7 +7931,18 @@ async function callReadOnlyTool(context, name, args = {}) {
7603
7931
  toolNames: [...facts.toolsByName.keys()].sort((a, b) => a.localeCompare(b)),
7604
7932
  llmCount: facts.llmEvents.length,
7605
7933
  outcomeCount: facts.outcomeEvents.length,
7606
- note: "Bounded TraceFacts summary only; raw events and prompts are not included."
7934
+ failureRoleCounts: facts.summary.failureRoleCounts ?? {
7935
+ transient: 0,
7936
+ recovered: 0,
7937
+ terminal: 0,
7938
+ unknown: 0
7939
+ },
7940
+ failureFactIds: facts.failureFacts.map((fact) => ({
7941
+ eventId: fact.eventId,
7942
+ role: fact.role,
7943
+ confidence: fact.confidence
7944
+ })),
7945
+ note: "Bounded TraceFacts summary only; raw events, prompts, and error bodies are not included. Failure roles are derived classifications over recorded evidence."
7607
7946
  },
7608
7947
  context
7609
7948
  );
@@ -8053,5 +8392,5 @@ async function runReadOnlyMcpServer(options = {}) {
8053
8392
  }
8054
8393
 
8055
8394
  export { MCP_MAX_REQUEST_BYTES, MCP_PROTOCOL_VERSION, MCP_SERVER_INSTRUCTIONS, READ_ONLY_TOOLS, TRACE_DATA_UNTRUSTED_WARNING, callReadOnlyTool, createMcpServerContext, handleMcpProtocolLine, runReadOnlyMcpServer };
8056
- //# sourceMappingURL=chunk-FTUMVNQN.mjs.map
8057
- //# sourceMappingURL=chunk-FTUMVNQN.mjs.map
8395
+ //# sourceMappingURL=chunk-O66SXMBQ.mjs.map
8396
+ //# sourceMappingURL=chunk-O66SXMBQ.mjs.map