@agent-inspect/mcp-server 6.14.1 → 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.
@@ -2568,6 +2568,73 @@ function diffRuns(left, right, options) {
2568
2568
  return table;
2569
2569
  })();
2570
2570
 
2571
+ // packages/core/src/safety/sensitive-key.ts
2572
+ function normalizeSensitiveKey(value) {
2573
+ return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
2574
+ }
2575
+ var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
2576
+ [
2577
+ "tokens",
2578
+ "max_tokens",
2579
+ "min_tokens",
2580
+ "ls_max_tokens",
2581
+ "token_count",
2582
+ "token_limit",
2583
+ "token_budget",
2584
+ "input_tokens",
2585
+ "output_tokens",
2586
+ "total_tokens",
2587
+ "cached_tokens",
2588
+ "prompt_tokens",
2589
+ "completion_tokens"
2590
+ ].map(normalizeSensitiveKey)
2591
+ );
2592
+ var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
2593
+ "authorization",
2594
+ "cookie",
2595
+ "token",
2596
+ "access_token",
2597
+ "accesstoken",
2598
+ "auth_token",
2599
+ "authtoken",
2600
+ "refresh_token",
2601
+ "refreshtoken",
2602
+ "id_token",
2603
+ "idtoken",
2604
+ "bearer_token",
2605
+ "bearertoken",
2606
+ "api_token",
2607
+ "apitoken",
2608
+ "apikey",
2609
+ "api_key",
2610
+ "password",
2611
+ "secret",
2612
+ "email"
2613
+ ];
2614
+ function isTokenCredentialKey(normalized) {
2615
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
2616
+ if (normalized === "token") return true;
2617
+ if (normalized.endsWith("tokens")) return false;
2618
+ return normalized.endsWith("token");
2619
+ }
2620
+ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
2621
+ if (!key) return false;
2622
+ const normalized = normalizeSensitiveKey(key);
2623
+ if (!normalized) return false;
2624
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
2625
+ for (const sensitive of sensitiveKeys) {
2626
+ const s = normalizeSensitiveKey(sensitive);
2627
+ if (!s) continue;
2628
+ if (s === "token") {
2629
+ if (isTokenCredentialKey(normalized)) return true;
2630
+ continue;
2631
+ }
2632
+ if (normalized === s) return true;
2633
+ if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
2634
+ }
2635
+ return false;
2636
+ }
2637
+
2571
2638
  // packages/core/src/checks/logical-events.ts
2572
2639
  function isRecord6(value) {
2573
2640
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -2763,6 +2830,23 @@ function projectLogicalEvents(events) {
2763
2830
  }
2764
2831
  }
2765
2832
  if (!remapped) {
2833
+ if (originalParentId === event.eventId) {
2834
+ diagnostics.push({
2835
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2836
+ message: `Removed self-parent edge on ${event.eventId}.`,
2837
+ eventIds: [event.eventId]
2838
+ });
2839
+ const { parentId: _drop, ...rest } = event;
2840
+ normalized.push({
2841
+ ...rest,
2842
+ projection: {
2843
+ ...event.projection,
2844
+ parentNormalized: true,
2845
+ originalParentId
2846
+ }
2847
+ });
2848
+ continue;
2849
+ }
2766
2850
  if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
2767
2851
  const mapping = event.attributes?.parentMapping;
2768
2852
  const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
@@ -2778,6 +2862,23 @@ function projectLogicalEvents(events) {
2778
2862
  normalized.push(event);
2779
2863
  continue;
2780
2864
  }
2865
+ if (nextParent === event.eventId) {
2866
+ diagnostics.push({
2867
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
2868
+ message: `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`,
2869
+ eventIds: [event.eventId]
2870
+ });
2871
+ const { parentId: _drop, ...rest } = event;
2872
+ normalized.push({
2873
+ ...rest,
2874
+ projection: {
2875
+ ...event.projection,
2876
+ parentNormalized: true,
2877
+ originalParentId
2878
+ }
2879
+ });
2880
+ continue;
2881
+ }
2781
2882
  diagnostics.push({
2782
2883
  code: "AI_LOGICAL_PARENT_REMAPPED",
2783
2884
  message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
@@ -2894,16 +2995,7 @@ var STATUS_RANK = {
2894
2995
  warning: 1,
2895
2996
  pass: 2
2896
2997
  };
2897
- var DEFAULT_SENSITIVE_KEYS = [
2898
- "authorization",
2899
- "cookie",
2900
- "token",
2901
- "apikey",
2902
- "api_key",
2903
- "password",
2904
- "secret",
2905
- "email"
2906
- ];
2998
+ var DEFAULT_SENSITIVE_KEYS = DEFAULT_CREDENTIAL_SENSITIVE_KEYS;
2907
2999
  var DEFAULT_RAW_CONTENT_KEYS = [
2908
3000
  "body",
2909
3001
  "headers",
@@ -3258,9 +3350,7 @@ function hasRedactionMarker(value, markers) {
3258
3350
  return markers.some((marker) => value.includes(marker)) || /^\[HASH:[A-Za-z0-9_-]+\]$/.test(value);
3259
3351
  }
3260
3352
  function isSensitiveKey(key, sensitiveKeys) {
3261
- if (!key) return false;
3262
- const normalized = normalizedKey(key);
3263
- return sensitiveKeys.some((sensitive) => normalized.includes(normalizedKey(sensitive)));
3353
+ return isCredentialSensitiveKey(key, sensitiveKeys);
3264
3354
  }
3265
3355
  function isRawContentKey(key, forbiddenKeys) {
3266
3356
  if (!key) return false;
@@ -3830,6 +3920,20 @@ function traceEventsToPersistedInspectEvents(events, options) {
3830
3920
  function inc(map, key) {
3831
3921
  map[key] = (map[key] ?? 0) + 1;
3832
3922
  }
3923
+ function confidenceRank(confidence) {
3924
+ switch (confidence) {
3925
+ case "unknown":
3926
+ return 0;
3927
+ case "heuristic":
3928
+ return 1;
3929
+ case "correlated":
3930
+ return 2;
3931
+ case "explicit":
3932
+ return 3;
3933
+ default:
3934
+ return 0;
3935
+ }
3936
+ }
3833
3937
  function computeRunStatus(events) {
3834
3938
  let runTerminal;
3835
3939
  let sawRunEvent = false;
@@ -3850,6 +3954,84 @@ function computeRunStatus(events) {
3850
3954
  }
3851
3955
  return hasRunning ? "running" : "ok";
3852
3956
  }
3957
+ function linkNodesVisibilityFirst(nodes) {
3958
+ let selfParentCount = 0;
3959
+ let unresolvedParentCount = 0;
3960
+ let normalizedEdgeCount = 0;
3961
+ let cycleCount = 0;
3962
+ const pending = [];
3963
+ for (const node of nodes.values()) {
3964
+ const parentId = node.event.parentId;
3965
+ if (!parentId) continue;
3966
+ if (parentId === node.event.eventId) {
3967
+ selfParentCount += 1;
3968
+ normalizedEdgeCount += 1;
3969
+ continue;
3970
+ }
3971
+ if (!nodes.has(parentId)) {
3972
+ unresolvedParentCount += 1;
3973
+ continue;
3974
+ }
3975
+ pending.push({
3976
+ childId: node.event.eventId,
3977
+ parentId,
3978
+ childTimestamp: node.event.timestamp,
3979
+ childConfidence: node.event.confidence
3980
+ });
3981
+ }
3982
+ pending.sort((a, b) => {
3983
+ const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
3984
+ if (conf !== 0) return conf;
3985
+ return a.childTimestamp - b.childTimestamp;
3986
+ });
3987
+ const parentOf = /* @__PURE__ */ new Map();
3988
+ for (const edge of pending) {
3989
+ parentOf.set(edge.childId, edge.parentId);
3990
+ let cursor = edge.parentId;
3991
+ const seen = /* @__PURE__ */ new Set([edge.childId]);
3992
+ let cyclic = false;
3993
+ while (cursor) {
3994
+ if (seen.has(cursor)) {
3995
+ cyclic = true;
3996
+ break;
3997
+ }
3998
+ seen.add(cursor);
3999
+ cursor = parentOf.get(cursor);
4000
+ }
4001
+ if (cyclic) {
4002
+ parentOf.delete(edge.childId);
4003
+ cycleCount += 1;
4004
+ normalizedEdgeCount += 1;
4005
+ }
4006
+ }
4007
+ for (const [childId, parentId] of parentOf) {
4008
+ nodes.get(parentId).children.push(nodes.get(childId));
4009
+ }
4010
+ const roots = [];
4011
+ for (const node of nodes.values()) {
4012
+ if (!parentOf.has(node.event.eventId)) {
4013
+ roots.push(node);
4014
+ }
4015
+ }
4016
+ const assignDepth = (n, depth, stack) => {
4017
+ if (stack.has(n.event.eventId)) return;
4018
+ n.depth = depth;
4019
+ stack.add(n.event.eventId);
4020
+ for (const c of n.children) assignDepth(c, depth + 1, stack);
4021
+ stack.delete(n.event.eventId);
4022
+ };
4023
+ for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
4024
+ return {
4025
+ roots,
4026
+ summary: {
4027
+ rootCount: roots.length,
4028
+ selfParentCount,
4029
+ cycleCount,
4030
+ unresolvedParentCount,
4031
+ normalizedEdgeCount
4032
+ }
4033
+ };
4034
+ }
3853
4035
  var TreeBuilder = class {
3854
4036
  constructor(options) {
3855
4037
  void options?.config;
@@ -3867,20 +4049,7 @@ var TreeBuilder = class {
3867
4049
  for (const e of sorted) {
3868
4050
  nodes.set(e.eventId, { event: e, children: [], depth: 0 });
3869
4051
  }
3870
- const roots = [];
3871
- for (const node of nodes.values()) {
3872
- const parentId = node.event.parentId;
3873
- if (parentId && nodes.has(parentId)) {
3874
- nodes.get(parentId).children.push(node);
3875
- } else {
3876
- roots.push(node);
3877
- }
3878
- }
3879
- const assignDepth = (n, depth) => {
3880
- n.depth = depth;
3881
- for (const c of n.children) assignDepth(c, depth + 1);
3882
- };
3883
- for (const r of roots) assignDepth(r, 0);
4052
+ const { roots, summary } = linkNodesVisibilityFirst(nodes);
3884
4053
  const confidenceBreakdown = {
3885
4054
  explicit: 0,
3886
4055
  correlated: 0,
@@ -3908,7 +4077,8 @@ var TreeBuilder = class {
3908
4077
  metadata: {
3909
4078
  totalEvents: sorted.length,
3910
4079
  confidenceBreakdown,
3911
- kinds
4080
+ kinds,
4081
+ relationshipSummary: summary
3912
4082
  }
3913
4083
  });
3914
4084
  }
@@ -6322,6 +6492,53 @@ function exportRunTree(tree, options) {
6322
6492
  }
6323
6493
  }
6324
6494
  }
6495
+
6496
+ // packages/redact/src/sensitive-key.ts
6497
+ function normalizeSensitiveKey2(value) {
6498
+ return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
6499
+ }
6500
+ var NON_CREDENTIAL_TOKEN_CONFIG_KEYS2 = new Set(
6501
+ [
6502
+ "tokens",
6503
+ "max_tokens",
6504
+ "min_tokens",
6505
+ "ls_max_tokens",
6506
+ "token_count",
6507
+ "token_limit",
6508
+ "token_budget",
6509
+ "input_tokens",
6510
+ "output_tokens",
6511
+ "total_tokens",
6512
+ "cached_tokens",
6513
+ "prompt_tokens",
6514
+ "completion_tokens"
6515
+ ].map(normalizeSensitiveKey2)
6516
+ );
6517
+ function isTokenCredentialKey2(normalized) {
6518
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
6519
+ if (normalized === "token") return true;
6520
+ if (normalized.endsWith("tokens")) return false;
6521
+ return normalized.endsWith("token");
6522
+ }
6523
+ function isCredentialSensitiveKey2(key, sensitiveKeys) {
6524
+ if (!key) return false;
6525
+ const normalized = normalizeSensitiveKey2(key);
6526
+ if (!normalized) return false;
6527
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
6528
+ for (const sensitive of sensitiveKeys) {
6529
+ const s = normalizeSensitiveKey2(sensitive);
6530
+ if (!s) continue;
6531
+ if (s === "token") {
6532
+ if (isTokenCredentialKey2(normalized)) return true;
6533
+ continue;
6534
+ }
6535
+ if (normalized === s) return true;
6536
+ if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
6537
+ }
6538
+ return false;
6539
+ }
6540
+
6541
+ // packages/redact/src/index.ts
6325
6542
  var DEFAULT_REDACT_KEYS2 = [
6326
6543
  "authorization",
6327
6544
  "cookie",
@@ -6383,6 +6600,12 @@ function isRecord11(value) {
6383
6600
  function toKey2(key) {
6384
6601
  return key.toLowerCase();
6385
6602
  }
6603
+ function findCompiledKeyRule(key, rules) {
6604
+ const exact = toKey2(key);
6605
+ const direct = rules.find((candidate) => candidate.key === exact);
6606
+ if (direct) return direct;
6607
+ return rules.find((candidate) => isCredentialSensitiveKey2(key, [candidate.key]));
6608
+ }
6386
6609
  function stableHash2(value) {
6387
6610
  const hash = crypto.createHash("sha256").update(value, "utf8").digest("hex");
6388
6611
  return hash.slice(0, 8);
@@ -6704,7 +6927,7 @@ var Redactor2 = class {
6704
6927
  return "[Truncated]";
6705
6928
  }
6706
6929
  if (key !== void 0) {
6707
- const rule = this.#rules.find((candidate) => candidate.key === toKey2(key));
6930
+ const rule = findCompiledKeyRule(key, this.#rules);
6708
6931
  if (rule) {
6709
6932
  this.#recordFinding(
6710
6933
  state,
@@ -7586,5 +7809,5 @@ async function runReadOnlyMcpServer(options = {}) {
7586
7809
  }
7587
7810
 
7588
7811
  export { MCP_MAX_REQUEST_BYTES, MCP_PROTOCOL_VERSION, READ_ONLY_TOOLS, callReadOnlyTool, createMcpServerContext, handleMcpProtocolLine, runReadOnlyMcpServer };
7589
- //# sourceMappingURL=chunk-C6EBJS57.mjs.map
7590
- //# sourceMappingURL=chunk-C6EBJS57.mjs.map
7812
+ //# sourceMappingURL=chunk-7AL325ZU.mjs.map
7813
+ //# sourceMappingURL=chunk-7AL325ZU.mjs.map