agent-inspect 6.17.3 → 6.17.5

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 (40) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/docs/ADAPTER-CONFORMANCE.md +24 -0
  4. package/docs/ADAPTERS.md +3 -3
  5. package/docs/API.md +13 -7
  6. package/docs/CI-ARTIFACTS.md +2 -1
  7. package/docs/CLI.md +2 -0
  8. package/docs/LIMITATIONS.md +1 -0
  9. package/docs/OPENAI-AGENTS-LOCAL.md +14 -0
  10. package/docs/SAFE-TRACE-SHARING.md +1 -0
  11. package/docs/SELF-HOSTING.md +2 -0
  12. package/docs/STANDARDS.md +15 -0
  13. package/docs/SUPPORT-LEVELS.md +23 -0
  14. package/docs/TRACE-CONTRACTS.md +90 -0
  15. package/package.json +7 -3
  16. package/packages/cli/dist/{chunk-5GGYDIZD.mjs → chunk-GOHYSE7W.mjs} +93 -19
  17. package/packages/cli/dist/chunk-GOHYSE7W.mjs.map +1 -0
  18. package/packages/cli/dist/index.cjs +505 -88
  19. package/packages/cli/dist/index.cjs.map +1 -1
  20. package/packages/cli/dist/index.mjs +417 -74
  21. package/packages/cli/dist/index.mjs.map +1 -1
  22. package/packages/cli/dist/{src-IDMCWKRH.mjs → src-OYGG7QAZ.mjs} +3 -3
  23. package/packages/cli/dist/{src-IDMCWKRH.mjs.map → src-OYGG7QAZ.mjs.map} +1 -1
  24. package/packages/core/dist/advanced.cjs +86 -17
  25. package/packages/core/dist/advanced.cjs.map +1 -1
  26. package/packages/core/dist/advanced.d.cts +1 -1
  27. package/packages/core/dist/advanced.d.ts +1 -1
  28. package/packages/core/dist/advanced.mjs +15 -5
  29. package/packages/core/dist/advanced.mjs.map +1 -1
  30. package/packages/core/dist/checks.cjs +126 -28
  31. package/packages/core/dist/checks.cjs.map +1 -1
  32. package/packages/core/dist/checks.d.cts +28 -2
  33. package/packages/core/dist/checks.d.ts +28 -2
  34. package/packages/core/dist/checks.mjs +1 -1
  35. package/packages/core/dist/{chunk-UFP54T7F.mjs → chunk-DIZPIPY2.mjs} +128 -30
  36. package/packages/core/dist/chunk-DIZPIPY2.mjs.map +1 -0
  37. package/packages/core/dist/{index-Xk9X-yjY.d.cts → index-DWu54Y28.d.cts} +107 -122
  38. package/packages/core/dist/{index-BsCcOKxy.d.ts → index-DlwbVqEs.d.ts} +107 -122
  39. package/packages/cli/dist/chunk-5GGYDIZD.mjs.map +0 -1
  40. package/packages/core/dist/chunk-UFP54T7F.mjs.map +0 -1
@@ -3230,14 +3230,15 @@ function enrichSessionSummary(summary, runs, options = {}) {
3230
3230
 
3231
3231
  // packages/core/src/sessions/checks.ts
3232
3232
  function emptySummary() {
3233
- return { passed: 0, failed: 0, warnings: 0, errors: 0 };
3233
+ return { passed: 0, failed: 0, warnings: 0, errors: 0, rulesEvaluated: 0 };
3234
3234
  }
3235
3235
  function mergeSummary(target, source) {
3236
3236
  return {
3237
3237
  passed: target.passed + source.passed,
3238
3238
  failed: target.failed + source.failed,
3239
3239
  warnings: target.warnings + source.warnings,
3240
- errors: target.errors + source.errors
3240
+ errors: target.errors + source.errors,
3241
+ rulesEvaluated: target.rulesEvaluated + source.rulesEvaluated
3241
3242
  };
3242
3243
  }
3243
3244
  function sessionDiagnostic(code, message) {
@@ -3261,6 +3262,7 @@ function aggregateSessionCheckResults(perRun, scope) {
3261
3262
  `${scope.scopeKind} not found: ${scope.scopeLabel}`
3262
3263
  )
3263
3264
  ],
3265
+ ruleExecutions: [],
3264
3266
  ...scope.sessionWarnings?.length ? { sessionWarnings: [...scope.sessionWarnings] } : {}
3265
3267
  };
3266
3268
  }
@@ -3281,17 +3283,20 @@ function aggregateSessionCheckResults(perRun, scope) {
3281
3283
  `No readable traces in ${scope.scopeKind}: ${scope.scopeLabel}`
3282
3284
  )
3283
3285
  ],
3286
+ ruleExecutions: [],
3284
3287
  ...scope.sessionWarnings?.length ? { sessionWarnings: [...scope.sessionWarnings] } : {}
3285
3288
  };
3286
3289
  }
3287
3290
  let summary = emptySummary();
3288
3291
  const findings = [];
3289
3292
  const diagnostics = [];
3293
+ const ruleExecutions = [];
3290
3294
  const runResults = [];
3291
3295
  for (const result of perRun) {
3292
3296
  summary = mergeSummary(summary, result.summary);
3293
3297
  findings.push(...result.findings);
3294
3298
  diagnostics.push(...result.diagnostics);
3299
+ ruleExecutions.push(...result.ruleExecutions ?? []);
3295
3300
  if (result.runId) {
3296
3301
  runResults.push({ runId: result.runId, status: result.status });
3297
3302
  }
@@ -3304,6 +3309,11 @@ function aggregateSessionCheckResults(perRun, scope) {
3304
3309
  if (runCmp !== 0) return runCmp;
3305
3310
  return a.ruleId.localeCompare(b.ruleId);
3306
3311
  });
3312
+ ruleExecutions.sort((a, b) => {
3313
+ const runCmp = (a.runId ?? "").localeCompare(b.runId ?? "");
3314
+ if (runCmp !== 0) return runCmp;
3315
+ return a.ruleId.localeCompare(b.ruleId);
3316
+ });
3307
3317
  const hasErrors = diagnostics.some((item) => item.severity === "error");
3308
3318
  const status = hasErrors ? "error" : summary.failed > 0 ? "fail" : "pass";
3309
3319
  return {
@@ -3317,6 +3327,7 @@ function aggregateSessionCheckResults(perRun, scope) {
3317
3327
  summary,
3318
3328
  findings,
3319
3329
  diagnostics,
3330
+ ruleExecutions,
3320
3331
  ...scope.sessionWarnings?.length ? { sessionWarnings: [...scope.sessionWarnings] } : {}
3321
3332
  };
3322
3333
  }
@@ -6237,8 +6248,11 @@ formatProgrammaticDiagnostic(
6237
6248
  );
6238
6249
 
6239
6250
  // packages/core/src/safety/sensitive-key.ts
6251
+ function keyHasExplicitSeparator(value) {
6252
+ return /[_\-.]/.test(value);
6253
+ }
6240
6254
  function normalizeSensitiveKey(value) {
6241
- return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
6255
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
6242
6256
  }
6243
6257
  var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
6244
6258
  [
@@ -6290,6 +6304,7 @@ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSIT
6290
6304
  const normalized = normalizeSensitiveKey(key);
6291
6305
  if (!normalized) return false;
6292
6306
  if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
6307
+ const allowPrefixCompound = keyHasExplicitSeparator(key);
6293
6308
  for (const sensitive of sensitiveKeys) {
6294
6309
  const s = normalizeSensitiveKey(sensitive);
6295
6310
  if (!s) continue;
@@ -6298,7 +6313,8 @@ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSIT
6298
6313
  continue;
6299
6314
  }
6300
6315
  if (normalized === s) return true;
6301
- if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
6316
+ if (normalized.endsWith(`_${s}`)) return true;
6317
+ if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
6302
6318
  }
6303
6319
  return false;
6304
6320
  }
@@ -6396,10 +6412,11 @@ function emptySummary2() {
6396
6412
  passed: 0,
6397
6413
  failed: 0,
6398
6414
  warnings: 0,
6399
- errors: 0
6415
+ errors: 0,
6416
+ rulesEvaluated: 0
6400
6417
  };
6401
6418
  }
6402
- function errorResult(input, diagnostics, selectedRun) {
6419
+ function errorResult(input, diagnostics, selectedRun, ruleExecutions = []) {
6403
6420
  return {
6404
6421
  ok: false,
6405
6422
  status: "error",
@@ -6407,10 +6424,12 @@ function errorResult(input, diagnostics, selectedRun) {
6407
6424
  ...selectedRun ? { runId: selectedRun.runId } : {},
6408
6425
  summary: {
6409
6426
  ...emptySummary2(),
6410
- errors: diagnostics.filter((item) => item.severity === "error").length
6427
+ errors: diagnostics.filter((item) => item.severity === "error").length,
6428
+ rulesEvaluated: ruleExecutions.length
6411
6429
  },
6412
6430
  findings: [],
6413
- diagnostics: [...diagnostics]
6431
+ diagnostics: [...diagnostics],
6432
+ ruleExecutions: [...ruleExecutions]
6414
6433
  };
6415
6434
  }
6416
6435
  function flattenNodes(nodes) {
@@ -6566,7 +6585,7 @@ function normalizeFinding(rule, finding) {
6566
6585
  ...finding.action !== void 0 ? { action: finding.action } : {}
6567
6586
  };
6568
6587
  }
6569
- function summarize(findings, diagnostics) {
6588
+ function summarize(findings, diagnostics, rulesEvaluated) {
6570
6589
  return {
6571
6590
  passed: findings.filter((finding) => finding.status === "pass").length,
6572
6591
  failed: findings.filter(
@@ -6575,9 +6594,21 @@ function summarize(findings, diagnostics) {
6575
6594
  warnings: findings.filter(
6576
6595
  (finding) => finding.status === "warning" || finding.severity === "warning"
6577
6596
  ).length,
6578
- errors: diagnostics.filter((item) => item.severity === "error").length
6597
+ errors: diagnostics.filter((item) => item.severity === "error").length,
6598
+ rulesEvaluated
6579
6599
  };
6580
6600
  }
6601
+ function classifyRuleExecution(findings, threw) {
6602
+ if (findings.some((finding) => finding.status === "fail" && finding.severity === "error")) {
6603
+ return "fail";
6604
+ }
6605
+ if (findings.some(
6606
+ (finding) => finding.status === "warning" || finding.severity === "warning"
6607
+ )) {
6608
+ return "warning";
6609
+ }
6610
+ return "pass";
6611
+ }
6581
6612
  function stringAttr(event, keys) {
6582
6613
  for (const key of keys) {
6583
6614
  const value = event.attributes?.[key];
@@ -6674,6 +6705,9 @@ function finishedEvents(context, kind) {
6674
6705
  (event) => (kind === void 0 || event.kind === kind) && event.status !== "running"
6675
6706
  );
6676
6707
  }
6708
+ function toolInvocationEvents(context) {
6709
+ return semanticEvents(context).filter((event) => event.kind === "TOOL");
6710
+ }
6677
6711
  function isRecord8(value) {
6678
6712
  return typeof value === "object" && value !== null && !Array.isArray(value);
6679
6713
  }
@@ -7074,7 +7108,7 @@ function createToolUsageRule(options) {
7074
7108
  category: "tool",
7075
7109
  defaultSeverity: "error",
7076
7110
  evaluate(context) {
7077
- const tools = finishedEvents(context, "TOOL");
7111
+ const tools = toolInvocationEvents(context);
7078
7112
  const names = tools.map(toolName);
7079
7113
  const nameSet = new Set(names);
7080
7114
  const findings = [];
@@ -7724,12 +7758,24 @@ function createBaselineRegressionRule(options) {
7724
7758
  }
7725
7759
  function createObservedOutcomeRule(options = {}) {
7726
7760
  const failOn = options.failOn ?? ["failed"];
7761
+ const requireAny = options.requireAny === true;
7727
7762
  return {
7728
7763
  id: "outcome.status",
7729
7764
  category: "run",
7730
7765
  defaultSeverity: "error",
7731
7766
  evaluate(context) {
7732
7767
  const outcomes = extractOutcomesFromPersistedEvents(context.events);
7768
+ if (requireAny && outcomes.length === 0) {
7769
+ return [
7770
+ failFinding(
7771
+ "outcome.status",
7772
+ "Expected at least one observed outcome.",
7773
+ runEvidence(context.selectedRun),
7774
+ { requireAny: true, expected: "at least one observed outcome" },
7775
+ { code: "outcome.missing", actual: 0 }
7776
+ )
7777
+ ];
7778
+ }
7733
7779
  const matching = outcomesMatchingStatus(outcomes, failOn);
7734
7780
  if (matching.length === 0) return [];
7735
7781
  return [
@@ -7765,6 +7811,18 @@ function runTraceChecks(input, options = {}) {
7765
7811
  if (rules.diagnostics.length > 0) {
7766
7812
  return errorResult(input, rules.diagnostics, selected.run);
7767
7813
  }
7814
+ if (rules.rules.length === 0) {
7815
+ return errorResult(
7816
+ input,
7817
+ [
7818
+ diagnostic3(
7819
+ "AI_CHECK_NO_RULES_EVALUATED",
7820
+ "No trace check rules were evaluated. Configure at least one rule, contract, or CLI check option."
7821
+ )
7822
+ ],
7823
+ selected.run
7824
+ );
7825
+ }
7768
7826
  const facts = buildFacts2(input, selected.run);
7769
7827
  const context = {
7770
7828
  ...facts,
@@ -7773,22 +7831,38 @@ function runTraceChecks(input, options = {}) {
7773
7831
  };
7774
7832
  const diagnostics = [];
7775
7833
  const findings = [];
7834
+ const ruleExecutions = [];
7776
7835
  for (const rule of rules.rules) {
7777
7836
  try {
7778
- findings.push(...rule.evaluate(context).map((finding) => normalizeFinding(rule, finding)));
7837
+ const ruleFindings = rule.evaluate(context).map((finding) => normalizeFinding(rule, finding));
7838
+ findings.push(...ruleFindings);
7839
+ ruleExecutions.push({
7840
+ ruleId: rule.id,
7841
+ category: rule.category,
7842
+ status: classifyRuleExecution(ruleFindings, false),
7843
+ findingCount: ruleFindings.length,
7844
+ ...selected.run ? { runId: selected.run.runId } : {}
7845
+ });
7779
7846
  } catch (error) {
7780
7847
  const message = error instanceof Error ? error.message : String(error);
7781
7848
  diagnostics.push(
7782
7849
  diagnostic3("AI_CHECK_INTERNAL_ERROR", `Rule ${rule.id} failed: ${message}`, rule.id)
7783
7850
  );
7851
+ ruleExecutions.push({
7852
+ ruleId: rule.id,
7853
+ category: rule.category,
7854
+ status: "error",
7855
+ findingCount: 0,
7856
+ ...selected.run ? { runId: selected.run.runId } : {}
7857
+ });
7784
7858
  }
7785
7859
  }
7786
7860
  if (diagnostics.length > 0) {
7787
- return errorResult(input, diagnostics, selected.run);
7861
+ return errorResult(input, diagnostics, selected.run, ruleExecutions);
7788
7862
  }
7789
7863
  const eventById = new Map(input.read.events.map((event) => [event.eventId, event]));
7790
7864
  const sortedFindings = findings.sort(compareFindings(eventById));
7791
- const summary = summarize(sortedFindings, diagnostics);
7865
+ const summary = summarize(sortedFindings, diagnostics, ruleExecutions.length);
7792
7866
  const status = summary.failed > 0 ? "fail" : "pass";
7793
7867
  return {
7794
7868
  ok: status === "pass",
@@ -7797,7 +7871,8 @@ function runTraceChecks(input, options = {}) {
7797
7871
  ...selected.run ? { runId: selected.run.runId } : {},
7798
7872
  summary,
7799
7873
  findings: sortedFindings,
7800
- diagnostics
7874
+ diagnostics,
7875
+ ruleExecutions
7801
7876
  };
7802
7877
  }
7803
7878
 
@@ -10161,8 +10236,7 @@ async function runSuiteCase(suiteCase, config, options) {
10161
10236
  status: "pass",
10162
10237
  format: read.format,
10163
10238
  findings: [],
10164
- diagnostics: []
10165
- };
10239
+ diagnostics: []};
10166
10240
  const observationResult = validateExpectedObservations(suiteCase, read);
10167
10241
  const diagnostics = [
10168
10242
  ...checkResult.diagnostics.map(
@@ -11341,5 +11415,5 @@ function renderGateReport(result, options = {}) {
11341
11415
  }
11342
11416
 
11343
11417
  export { COHORT_METRIC_IDS, DEFAULT_SUITE_ARTIFACTS_DIR, EVIDENCE_FORMAT_VERSION, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, Redactor, TraceDirectory, TraceReadError, TreeBuilder, aggregateBundleSafeStatus, aggregateSessionCheckResults, analyzeCohort, applyProfileMetadataCaps, assertBundlePathContained, assertEvidenceRelativePath, buildActivitySummary, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceCausalFailureViewHtml, buildEvidenceCiPackage, buildEvidenceCircuitViewHtml, buildEvidenceContractsViewHtml, buildEvidenceDiffViewHtml, buildEvidenceHtmlShell, buildEvidenceManifest, buildEvidenceOutcomesViewHtml, buildEvidenceProvenanceViewHtml, buildEvidenceSafetyViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceTreeViewHtml, buildLocalExplanation, buildPlaceholderArtifact, buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildSessionIndex, buildTraceStats, buildZipArchive, bundleFailsOnSafety, bundleRunAssetRelativePath, collectTraceSchemaVersions, compactAttributes, createBaselineRegressionRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRunDepthRule, createRunDurationRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStructureCycleRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolUsageRule, defaultBundleOutputPath, defaultSuiteConfigTemplate, diffRuns, diffTraceEvents, enrichSessionRunRecord, escapeHtml, escapeMarkdown, extractMetadata, extractOutcomesFromTraceEvents, filterMetasBySessionScope, filterTraces, flattenTree, formatDuration2 as formatDuration, formatStepLabel, formatTimestamp, gateHasThresholds, getIndent, getTraceFilePath, inferEvidenceFileRole, isAgentInspectTrace, isPersistedInspectEvent, loadSessionRunRecords, loadSuiteConfig, loadTraceMetadataList, manualTraceEventsToComparableRun, nanoid, normalizeBundleOutputPath, openTrace, parseCohortMetricList, parseDuration, parseDurationFilter, parseGateList, parseTraceJsonl, persistedInspectEventsToTraceEvents, renderActivitySummaryHuman, renderCohortReport, renderErrorLine, renderGateReport, renderObservedOutcomesHtml, renderObservedOutcomesMarkdown, renderRunDiff, renderRunWhat, renderStepLine, renderSuiteReport, renderTimeline, renderTraceStats, resolveBundleRunIds, resolveRedactionProfile, resolveSuiteTemplate, resolveTraceDir, runGate, runSuite, runTraceChecks, safeString, sanitizeBundleRunId, searchTraces, serializeEvidenceManifest, sha256Hex, stableJson, summarizeObservedOutcomes, summarizeSemanticParity, traceEventToPersistedInspectEvent, truncateName, truncateStringForProfile, validateEvent, validateSuiteConfig, verifyEvidenceDirectory, zeroKinds };
11344
- //# sourceMappingURL=chunk-5GGYDIZD.mjs.map
11345
- //# sourceMappingURL=chunk-5GGYDIZD.mjs.map
11418
+ //# sourceMappingURL=chunk-GOHYSE7W.mjs.map
11419
+ //# sourceMappingURL=chunk-GOHYSE7W.mjs.map