agent-inspect 6.8.0 → 6.9.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.
Files changed (29) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/docs/CLI.md +10 -3
  4. package/package.json +1 -1
  5. package/packages/cli/dist/{chunk-TO4VENHV.mjs → chunk-WQ5XMFH2.mjs} +109 -17
  6. package/packages/cli/dist/chunk-WQ5XMFH2.mjs.map +1 -0
  7. package/packages/cli/dist/index.cjs +357 -66
  8. package/packages/cli/dist/index.cjs.map +1 -1
  9. package/packages/cli/dist/index.mjs +252 -53
  10. package/packages/cli/dist/index.mjs.map +1 -1
  11. package/packages/cli/dist/{src-Z5W27YCW.mjs → src-C4EUHTER.mjs} +3 -3
  12. package/packages/cli/dist/{src-Z5W27YCW.mjs.map → src-C4EUHTER.mjs.map} +1 -1
  13. package/packages/core/dist/advanced.cjs +15 -6
  14. package/packages/core/dist/advanced.cjs.map +1 -1
  15. package/packages/core/dist/advanced.d.cts +4 -1
  16. package/packages/core/dist/advanced.d.ts +4 -1
  17. package/packages/core/dist/advanced.mjs +3 -2
  18. package/packages/core/dist/advanced.mjs.map +1 -1
  19. package/packages/core/dist/checks.cjs +105 -14
  20. package/packages/core/dist/checks.cjs.map +1 -1
  21. package/packages/core/dist/checks.d.cts +2 -2
  22. package/packages/core/dist/checks.d.ts +2 -2
  23. package/packages/core/dist/checks.mjs +1 -1
  24. package/packages/core/dist/{chunk-EQVXDGGU.mjs → chunk-QT6CQ2XA.mjs} +107 -16
  25. package/packages/core/dist/chunk-QT6CQ2XA.mjs.map +1 -0
  26. package/packages/core/dist/{index-BblJEdYZ.d.ts → index-BO7l0iAe.d.ts} +44 -1
  27. package/packages/core/dist/{index-DyKk7iR9.d.cts → index-mdFcxSOR.d.cts} +44 -1
  28. package/packages/cli/dist/chunk-TO4VENHV.mjs.map +0 -1
  29. package/packages/core/dist/chunk-EQVXDGGU.mjs.map +0 -1
@@ -273,8 +273,35 @@ var DEFAULT_RAW_CONTENT_KEYS = [
273
273
  "toolinput",
274
274
  "tool_input",
275
275
  "tooloutput",
276
- "tool_output"
276
+ "tool_output",
277
+ // Framework / agent metadata that carries user or task text
278
+ "currenttask",
279
+ "current_task",
280
+ "task",
281
+ "userinput",
282
+ "user_input",
283
+ "requesttext",
284
+ "request_text",
285
+ "conversationtext",
286
+ "conversation_text"
277
287
  ];
288
+ var DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES = ["tokenUsage", "usage"];
289
+ var SAFE_USAGE_LEAF_KEYS = /* @__PURE__ */ new Set([
290
+ "input",
291
+ "output",
292
+ "total",
293
+ "cached",
294
+ "input_tokens",
295
+ "inputtokens",
296
+ "output_tokens",
297
+ "outputtokens",
298
+ "total_tokens",
299
+ "totaltokens",
300
+ "prompt_tokens",
301
+ "prompttokens",
302
+ "completion_tokens",
303
+ "completiontokens"
304
+ ]);
278
305
  var DEFAULT_SECRET_PATTERNS = [
279
306
  { id: "bearer-token", pattern: /Bearer\s+[A-Za-z0-9._~+/-]{12,}=*/ },
280
307
  { id: "openai-key", pattern: /sk-[A-Za-z0-9_-]{16,}/ },
@@ -452,7 +479,11 @@ function normalizeFinding(rule, finding) {
452
479
  message: finding.message,
453
480
  ...finding.expected !== void 0 ? { expected: finding.expected } : {},
454
481
  ...finding.actual !== void 0 ? { actual: finding.actual } : {},
455
- evidence: [...finding.evidence ?? []]
482
+ evidence: [...finding.evidence ?? []],
483
+ ...finding.category !== void 0 ? { category: finding.category } : {},
484
+ ...finding.confidence !== void 0 ? { confidence: finding.confidence } : {},
485
+ ...finding.detector !== void 0 ? { detector: finding.detector } : {},
486
+ ...finding.action !== void 0 ? { action: finding.action } : {}
456
487
  };
457
488
  }
458
489
  function summarize(findings, diagnostics) {
@@ -510,15 +541,19 @@ function eventEvidence(event, path3) {
510
541
  function runEvidence(run) {
511
542
  return run ? [{ runId: run.runId, name: run.name, status: run.status }] : [];
512
543
  }
513
- function failFinding(ruleId, message, evidence, expected, actual) {
544
+ function failFinding(ruleId, message, evidence, expected, actual, meta) {
514
545
  return {
515
546
  ruleId,
516
- severity: "error",
517
- status: "fail",
547
+ severity: meta?.severity ?? "error",
548
+ status: meta?.status ?? "fail",
518
549
  message,
519
550
  ...expected !== void 0 ? { expected } : {},
520
551
  ...actual !== void 0 ? { actual } : {},
521
- evidence: [...evidence]
552
+ evidence: [...evidence],
553
+ ...meta?.category !== void 0 ? { category: meta.category } : {},
554
+ ...meta?.confidence !== void 0 ? { confidence: meta.confidence } : {},
555
+ ...meta?.detector !== void 0 ? { detector: meta.detector } : {},
556
+ ...meta?.action !== void 0 ? { action: meta.action } : {}
522
557
  };
523
558
  }
524
559
  function toolName(event) {
@@ -650,6 +685,19 @@ function isRawContentKey(key, forbiddenKeys) {
650
685
  const normalized = normalizedKey(key);
651
686
  return forbiddenKeys.some((forbidden) => normalized === normalizedKey(forbidden));
652
687
  }
688
+ function isSafeRawContentMetricPath(path3, key, safePathPrefixes) {
689
+ const leaf = normalizedKey(key ?? lastPathSegment(path3));
690
+ if (!SAFE_USAGE_LEAF_KEYS.has(leaf)) return false;
691
+ const parts = path3.split(".").filter(Boolean);
692
+ if (parts.length < 2) return false;
693
+ const parent = parts[parts.length - 2] ?? "";
694
+ const parentNorm = normalizedKey(parent);
695
+ return safePathPrefixes.some((prefix) => parentNorm === normalizedKey(prefix));
696
+ }
697
+ function isRawContentPath(path3, key, forbiddenKeys, safePathPrefixes) {
698
+ if (isSafeRawContentMetricPath(path3, key, safePathPrefixes)) return false;
699
+ return isRawContentKey(key ?? lastPathSegment(path3), forbiddenKeys);
700
+ }
653
701
  function parentMarkedUnresolved(event) {
654
702
  if (booleanAttr(event, [
655
703
  "parentUnresolved",
@@ -1533,7 +1581,13 @@ function createSafetyRedactionRule(options = {}) {
1533
1581
  `Sensitive-looking field at ${entry.path} is not redacted.`,
1534
1582
  [eventEvidence(event, entry.path)],
1535
1583
  "redaction marker",
1536
- { path: entry.path, valueType: valueType(entry.value) }
1584
+ { path: entry.path, valueType: valueType(entry.value) },
1585
+ {
1586
+ category: "credential",
1587
+ confidence: "high",
1588
+ detector: "safety.redaction",
1589
+ action: "redact"
1590
+ }
1537
1591
  )
1538
1592
  );
1539
1593
  }
@@ -1544,6 +1598,7 @@ function createSafetyRedactionRule(options = {}) {
1544
1598
  }
1545
1599
  function createSafetyRawContentRule(options = {}) {
1546
1600
  const forbiddenKeys = options.forbiddenKeys ?? DEFAULT_RAW_CONTENT_KEYS;
1601
+ const safePathPrefixes = options.safePathPrefixes ?? DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES;
1547
1602
  return {
1548
1603
  id: "safety.rawPrompt",
1549
1604
  category: "safety",
@@ -1553,14 +1608,20 @@ function createSafetyRawContentRule(options = {}) {
1553
1608
  for (const event of context.events) {
1554
1609
  for (const entry of eventValueEntries(event, { includeSummaries: options.includeSummaries })) {
1555
1610
  const key = entry.key ?? lastPathSegment(entry.path);
1556
- if (!isRawContentKey(key, forbiddenKeys)) continue;
1611
+ if (!isRawContentPath(entry.path, key, forbiddenKeys, safePathPrefixes)) continue;
1557
1612
  findings.push(
1558
1613
  failFinding(
1559
1614
  "safety.rawPrompt",
1560
1615
  `Raw content-like field ${entry.path} is present.`,
1561
1616
  [eventEvidence(event, entry.path)],
1562
1617
  "metadata-only trace fields",
1563
- { path: entry.path, valueType: valueType(entry.value) }
1618
+ { path: entry.path, valueType: valueType(entry.value) },
1619
+ {
1620
+ category: "raw-content",
1621
+ confidence: "high",
1622
+ detector: "safety.rawPrompt",
1623
+ action: "redact-or-omit"
1624
+ }
1564
1625
  )
1565
1626
  );
1566
1627
  }
@@ -1592,7 +1653,13 @@ function createSafetySecretPatternRule(options = {}) {
1592
1653
  `Secret-like pattern ${pattern.id} matched at ${entry.path}.`,
1593
1654
  [eventEvidence(event, entry.path)],
1594
1655
  "no secret-like strings",
1595
- { pattern: pattern.id, path: entry.path }
1656
+ { pattern: pattern.id, path: entry.path },
1657
+ {
1658
+ category: "credential",
1659
+ confidence: "high",
1660
+ detector: pattern.id,
1661
+ action: "redact"
1662
+ }
1596
1663
  )
1597
1664
  );
1598
1665
  break;
@@ -1619,7 +1686,13 @@ function createSafetyOversizedAttributeRule(options) {
1619
1686
  `String at ${entry.path} exceeds ${options.maxStringLength} characters.`,
1620
1687
  [eventEvidence(event, entry.path)],
1621
1688
  { maxStringLength: options.maxStringLength },
1622
- { path: entry.path, length: entry.value.length }
1689
+ { path: entry.path, length: entry.value.length },
1690
+ {
1691
+ category: "size",
1692
+ confidence: "high",
1693
+ detector: "safety.oversizedAttribute",
1694
+ action: "truncate-or-omit"
1695
+ }
1623
1696
  )
1624
1697
  );
1625
1698
  }
@@ -1630,7 +1703,13 @@ function createSafetyOversizedAttributeRule(options) {
1630
1703
  `Array at ${entry.path} exceeds ${options.maxArrayLength} items.`,
1631
1704
  [eventEvidence(event, entry.path)],
1632
1705
  { maxArrayLength: options.maxArrayLength },
1633
- { path: entry.path, length: entry.value.length }
1706
+ { path: entry.path, length: entry.value.length },
1707
+ {
1708
+ category: "size",
1709
+ confidence: "high",
1710
+ detector: "safety.oversizedAttribute",
1711
+ action: "truncate-or-omit"
1712
+ }
1634
1713
  )
1635
1714
  );
1636
1715
  }
@@ -1641,7 +1720,13 @@ function createSafetyOversizedAttributeRule(options) {
1641
1720
  `Object at ${entry.path} exceeds ${options.maxObjectKeys} keys.`,
1642
1721
  [eventEvidence(event, entry.path)],
1643
1722
  { maxObjectKeys: options.maxObjectKeys },
1644
- { path: entry.path, keys: Object.keys(entry.value).length }
1723
+ { path: entry.path, keys: Object.keys(entry.value).length },
1724
+ {
1725
+ category: "size",
1726
+ confidence: "high",
1727
+ detector: "safety.oversizedAttribute",
1728
+ action: "truncate-or-omit"
1729
+ }
1645
1730
  )
1646
1731
  );
1647
1732
  }
@@ -1654,7 +1739,13 @@ function createSafetyOversizedAttributeRule(options) {
1654
1739
  `Value at ${entry.path} exceeds ${options.maxSerializedBytes} serialized bytes.`,
1655
1740
  [eventEvidence(event, entry.path)],
1656
1741
  { maxSerializedBytes: options.maxSerializedBytes },
1657
- { path: entry.path, bytes }
1742
+ { path: entry.path, bytes },
1743
+ {
1744
+ category: "size",
1745
+ confidence: "high",
1746
+ detector: "safety.oversizedAttribute",
1747
+ action: "truncate-or-omit"
1748
+ }
1658
1749
  )
1659
1750
  );
1660
1751
  }