agent-inspect 6.31.33 → 6.31.35

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 (42) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/docs/LIMITATIONS.md +22 -0
  4. package/docs/SAFE-TRACE-SHARING.md +1 -1
  5. package/package.json +1 -1
  6. package/packages/cli/dist/{chunk-AILSHDEF.mjs → chunk-RLFYFWIZ.mjs} +76 -22
  7. package/packages/cli/dist/chunk-RLFYFWIZ.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +136 -37
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +64 -19
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-SP36M4VB.mjs → src-S23RCPL2.mjs} +3 -3
  13. package/packages/cli/dist/{src-SP36M4VB.mjs.map → src-S23RCPL2.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +47 -7
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.mjs +9 -9
  17. package/packages/core/dist/checks.cjs +71 -18
  18. package/packages/core/dist/checks.cjs.map +1 -1
  19. package/packages/core/dist/checks.mjs +3 -3
  20. package/packages/core/dist/{chunk-6S666BF4.mjs → chunk-2SKAI5ZN.mjs} +3 -3
  21. package/packages/core/dist/{chunk-6S666BF4.mjs.map → chunk-2SKAI5ZN.mjs.map} +1 -1
  22. package/packages/core/dist/{chunk-EMDJLFRK.mjs → chunk-3OMB34E6.mjs} +74 -21
  23. package/packages/core/dist/chunk-3OMB34E6.mjs.map +1 -0
  24. package/packages/core/dist/{chunk-FBPDF7HO.mjs → chunk-6F6KLGCR.mjs} +3 -3
  25. package/packages/core/dist/{chunk-FBPDF7HO.mjs.map → chunk-6F6KLGCR.mjs.map} +1 -1
  26. package/packages/core/dist/{chunk-RB6WANSW.mjs → chunk-PU3FF5AP.mjs} +5 -4
  27. package/packages/core/dist/chunk-PU3FF5AP.mjs.map +1 -0
  28. package/packages/core/dist/{chunk-VIEJJ5JB.mjs → chunk-X5RP2E2H.mjs} +4 -4
  29. package/packages/core/dist/{chunk-VIEJJ5JB.mjs.map → chunk-X5RP2E2H.mjs.map} +1 -1
  30. package/packages/core/dist/exporters.cjs +33 -9
  31. package/packages/core/dist/exporters.cjs.map +1 -1
  32. package/packages/core/dist/exporters.mjs +33 -10
  33. package/packages/core/dist/exporters.mjs.map +1 -1
  34. package/packages/core/dist/index.cjs +3 -2
  35. package/packages/core/dist/index.cjs.map +1 -1
  36. package/packages/core/dist/index.mjs +4 -4
  37. package/packages/core/dist/writers.cjs +3 -2
  38. package/packages/core/dist/writers.cjs.map +1 -1
  39. package/packages/core/dist/writers.mjs +1 -1
  40. package/packages/cli/dist/chunk-AILSHDEF.mjs.map +0 -1
  41. package/packages/core/dist/chunk-EMDJLFRK.mjs.map +0 -1
  42. package/packages/core/dist/chunk-RB6WANSW.mjs.map +0 -1
@@ -1,15 +1,15 @@
1
- import { extractSessionWorkflowMetadata, sessionKeyForRun, defineTraceContract, runTraceChecks, createRunStatusRule, createToolUsageRule, createRunDurationRule, createRunDepthRule, createToolFailureRule, createLlmUsageRule, createObservedOutcomeRule } from './chunk-EMDJLFRK.mjs';
2
- export { extractSessionWorkflowMetadata, sessionKeyForRun } from './chunk-EMDJLFRK.mjs';
3
- export { MAX_TERMINAL_DEPTH, MAX_TERMINAL_NAME_LENGTH, TERMINAL_INDENT, TraceDirectory, createInspector, createInspectorRuntime, formatTerminalName, getCurrentContext, getCurrentCorrelationMetadata, getCurrentDepth, getCurrentRunId, getCurrentRunName, getCurrentStepId, getIndent, getParentStepId, getTraceDirFromContext, getTraceSafetyFromContext, hasActiveContext, isAgentInspectEnabled, isSilentContext, maybeInspectRun, printError, printFailedAt, printRunComplete, printRunStart, printStepComplete, printStepStart, renderErrorLine, renderRunSummary, renderStepLine, resolveTraceDir, runWithContext, runWithStepContext } from './chunk-VIEJJ5JB.mjs';
4
- import { buildRunTimeline, filterTraces, extractMetadata, buildRunSummary } from './chunk-6S666BF4.mjs';
5
- export { buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildTraceStats, extractMetadata, filterTraces, formatStepLabel, renderRunWhat, renderTimeline, renderTraceStats } from './chunk-6S666BF4.mjs';
6
- import { extractOutcomesFromTraceEvents, parseObservationFilter, summarizeObservedOutcomes, extractOutcomesFromPersistedEvents, renderObservedOutcomesHtml } from './chunk-FBPDF7HO.mjs';
7
- export { extractOutcomesFromPersistedEvents, extractOutcomesFromTraceEvents } from './chunk-FBPDF7HO.mjs';
1
+ import { extractSessionWorkflowMetadata, sessionKeyForRun, defineTraceContract, runTraceChecks, createRunStatusRule, createToolUsageRule, createRunDurationRule, createRunDepthRule, createToolFailureRule, createLlmUsageRule, createObservedOutcomeRule } from './chunk-3OMB34E6.mjs';
2
+ export { extractSessionWorkflowMetadata, sessionKeyForRun } from './chunk-3OMB34E6.mjs';
3
+ export { MAX_TERMINAL_DEPTH, MAX_TERMINAL_NAME_LENGTH, TERMINAL_INDENT, TraceDirectory, createInspector, createInspectorRuntime, formatTerminalName, getCurrentContext, getCurrentCorrelationMetadata, getCurrentDepth, getCurrentRunId, getCurrentRunName, getCurrentStepId, getIndent, getParentStepId, getTraceDirFromContext, getTraceSafetyFromContext, hasActiveContext, isAgentInspectEnabled, isSilentContext, maybeInspectRun, printError, printFailedAt, printRunComplete, printRunStart, printStepComplete, printStepStart, renderErrorLine, renderRunSummary, renderStepLine, resolveTraceDir, runWithContext, runWithStepContext } from './chunk-X5RP2E2H.mjs';
4
+ import { buildRunTimeline, filterTraces, extractMetadata, buildRunSummary } from './chunk-2SKAI5ZN.mjs';
5
+ export { buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildTraceStats, extractMetadata, filterTraces, formatStepLabel, renderRunWhat, renderTimeline, renderTraceStats } from './chunk-2SKAI5ZN.mjs';
6
+ import { extractOutcomesFromTraceEvents, parseObservationFilter, summarizeObservedOutcomes, extractOutcomesFromPersistedEvents, renderObservedOutcomesHtml } from './chunk-6F6KLGCR.mjs';
7
+ export { extractOutcomesFromPersistedEvents, extractOutcomesFromTraceEvents } from './chunk-6F6KLGCR.mjs';
8
8
  import { diffTraceEvents, renderRunDiff } from './chunk-F7STQ5JF.mjs';
9
9
  import './chunk-BT7CATSD.mjs';
10
10
  import { escapeHtml, flattenTree } from './chunk-CAWPF22J.mjs';
11
- import { resolveRedactionProfile, readTraceEventsFromFile, stringContainsHighConfidenceCredential } from './chunk-RB6WANSW.mjs';
12
- export { DEFAULT_MAX_EVENT_BYTES, DEFAULT_MAX_METADATA_VALUE_LENGTH, DEFAULT_MAX_PREVIEW_LENGTH, getRunIdFromTraceFileName, initializeTraceFile, listTraceFiles, prepareMetadataForDisk, prepareTraceEventForDisk, readTraceEvents, readTraceFile, resolveRedactionProfile, resolveTraceSafetyOptions, serializeEvent, validateEvent, writeTraceEvent } from './chunk-RB6WANSW.mjs';
11
+ import { resolveRedactionProfile, readTraceEventsFromFile, stringContainsHighConfidenceCredential } from './chunk-PU3FF5AP.mjs';
12
+ export { DEFAULT_MAX_EVENT_BYTES, DEFAULT_MAX_METADATA_VALUE_LENGTH, DEFAULT_MAX_PREVIEW_LENGTH, getRunIdFromTraceFileName, initializeTraceFile, listTraceFiles, prepareMetadataForDisk, prepareTraceEventForDisk, readTraceEvents, readTraceFile, resolveRedactionProfile, resolveTraceSafetyOptions, serializeEvent, validateEvent, writeTraceEvent } from './chunk-PU3FF5AP.mjs';
13
13
  import { Redactor } from './chunk-VLVCLAPB.mjs';
14
14
  import { openTrace } from './chunk-JJSL346L.mjs';
15
15
  import './chunk-77PUPLPG.mjs';
@@ -3982,10 +3982,11 @@ var SAFE_USAGE_LEAF_KEYS = /* @__PURE__ */ new Set([
3982
3982
  var DEFAULT_SECRET_PATTERNS = [
3983
3983
  { id: "bearer-token", pattern: /Bearer\s+[A-Za-z0-9._~+/-]{12,}=*/ },
3984
3984
  { id: "openai-key", pattern: /sk-[A-Za-z0-9_-]{16,}/ },
3985
- // Stripe + Slack: keep in sync with packages/redact + credential-value-patterns (#520).
3985
+ // Stripe + Slack: keep in sync with packages/redact + credential-value-patterns (#520/#528).
3986
+ // Non-alnum lookarounds so underscore-adjacent forms (acct_sk_live_…, …_eu) match.
3986
3987
  {
3987
3988
  id: "stripe-key",
3988
- pattern: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/
3989
+ pattern: /(?<![A-Za-z0-9])(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}(?![A-Za-z0-9])/
3989
3990
  },
3990
3991
  { id: "slack-token", pattern: /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/ },
3991
3992
  { id: "aws-access-key", pattern: /AKIA[0-9A-Z]{16}/ },
@@ -4159,11 +4160,27 @@ function eventTimestamp(finding, eventById) {
4159
4160
  const eventId = finding.evidence[0]?.eventId;
4160
4161
  return eventId ? eventById.get(eventId)?.timestamp ?? "" : "";
4161
4162
  }
4163
+ function isObservedToolPolicyFinding(finding) {
4164
+ return finding.ruleId === "tool.usage" && finding.evidence[0]?.eventId !== void 0;
4165
+ }
4166
+ function isMissingToolConsequenceFinding(finding) {
4167
+ if (finding.evidence[0]?.eventId !== void 0) return false;
4168
+ if (finding.ruleId === "tool.usage" && /did not appear/.test(finding.message)) {
4169
+ return true;
4170
+ }
4171
+ return finding.ruleId.startsWith("contract.tool.arguments") && /^No finished tool named /.test(finding.message);
4172
+ }
4162
4173
  function compareFindings(eventById) {
4163
4174
  return (a, b) => {
4164
4175
  if (SEVERITY_RANK[a.severity] !== SEVERITY_RANK[b.severity]) {
4165
4176
  return SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity];
4166
4177
  }
4178
+ const aPolicy = isObservedToolPolicyFinding(a);
4179
+ const bPolicy = isObservedToolPolicyFinding(b);
4180
+ const aMissing = isMissingToolConsequenceFinding(a);
4181
+ const bMissing = isMissingToolConsequenceFinding(b);
4182
+ if (aPolicy && bMissing) return -1;
4183
+ if (bPolicy && aMissing) return 1;
4167
4184
  const byRule = a.ruleId.localeCompare(b.ruleId);
4168
4185
  if (byRule !== 0) return byRule;
4169
4186
  if (STATUS_RANK[a.status] !== STATUS_RANK[b.status]) {
@@ -4299,20 +4316,43 @@ function failFinding(ruleId, message, evidence, expected, actual, meta) {
4299
4316
  function toolName(event) {
4300
4317
  return resolveCanonicalToolName(event);
4301
4318
  }
4319
+ var MAX_TOOL_NAME_CODEPOINT_DETAILS = 3;
4320
+ function isAsciiLetterCodePoint(codePoint) {
4321
+ return codePoint >= 65 && codePoint <= 90 || codePoint >= 97 && codePoint <= 122;
4322
+ }
4323
+ function isRiskyToolNameCodePoint(codePoint) {
4324
+ if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) return true;
4325
+ return codePoint === 1564 || codePoint === 8203 || codePoint === 8204 || codePoint === 8205 || codePoint === 8206 || codePoint === 8207 || codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8294 && codePoint <= 8297 || codePoint === 65279;
4326
+ }
4327
+ function formatCodePointDetail(codePoint, index) {
4328
+ return `U+${codePoint.toString(16).toUpperCase().padStart(4, "0")} at index ${index}`;
4329
+ }
4302
4330
  function formatToolNameForMessage(name) {
4331
+ let hasAsciiLetter = false;
4332
+ let hasNonAscii = false;
4333
+ let hasRisky = false;
4303
4334
  const details = [];
4304
4335
  for (let index = 0; index < name.length; ) {
4305
4336
  const codePoint = name.codePointAt(index);
4306
4337
  const width = codePoint > 65535 ? 2 : 1;
4338
+ if (isAsciiLetterCodePoint(codePoint)) hasAsciiLetter = true;
4339
+ const risky = isRiskyToolNameCodePoint(codePoint);
4340
+ if (risky) hasRisky = true;
4307
4341
  if (codePoint > 127) {
4308
- details.push(
4309
- `U+${codePoint.toString(16).toUpperCase().padStart(4, "0")} at index ${index}`
4310
- );
4342
+ hasNonAscii = true;
4343
+ details.push(formatCodePointDetail(codePoint, index));
4344
+ } else if (risky) {
4345
+ details.push(formatCodePointDetail(codePoint, index));
4311
4346
  }
4312
4347
  index += width;
4313
4348
  }
4314
- if (details.length === 0) return name;
4315
- return `"${name}" (contains ${details.join("; ")})`;
4349
+ if (!hasRisky && !(hasAsciiLetter && hasNonAscii) || details.length === 0) {
4350
+ return name;
4351
+ }
4352
+ const shown = details.slice(0, MAX_TOOL_NAME_CODEPOINT_DETAILS);
4353
+ const remaining = details.length - shown.length;
4354
+ const detailText = remaining > 0 ? `${shown.join("; ")}; and ${remaining} more` : shown.join("; ");
4355
+ return `"${name}" (contains ${detailText})`;
4316
4356
  }
4317
4357
  function describeRunningEvent(event) {
4318
4358
  if (event.kind === "TOOL") {
@@ -4975,7 +5015,12 @@ function createStepOrderingRule(options) {
4975
5015
  const beforeRunning = semanticEvents(context).filter(
4976
5016
  (event) => event.kind === options.before.kind && event.status === "running" && stepEndpointName(event, options.before.kind) === options.before.name
4977
5017
  );
4978
- if (beforeEvents.length === 0 && afterEvents.length > 0 && beforeRunning.length > 0) {
5018
+ const afterRunning = semanticEvents(context).filter(
5019
+ (event) => event.kind === options.after.kind && event.status === "running" && stepEndpointName(event, options.after.kind) === options.after.name
5020
+ );
5021
+ const afterStarted = afterEvents.length > 0 || afterRunning.length > 0;
5022
+ const afterEvidenceEvent = afterEvents[0] ?? afterRunning[0];
5023
+ if (beforeRunning.length > 0 && afterStarted && afterEvidenceEvent !== void 0) {
4979
5024
  const endpointExpected2 = bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after };
4980
5025
  return [
4981
5026
  failFinding(
@@ -4983,18 +5028,20 @@ function createStepOrderingRule(options) {
4983
5028
  `${subject} ${beforeLabel} started but never finished before ${afterLabel} ran.`,
4984
5029
  [
4985
5030
  ...beforeRunning.map((event) => eventEvidence3(event)),
4986
- eventEvidence3(afterEvents[0])
5031
+ eventEvidence3(afterEvidenceEvent)
4987
5032
  ],
4988
5033
  { ...endpointExpected2, mode },
4989
5034
  {
4990
5035
  code: bothTools ? "tool.order.interval-unresolved" : "step.order.interval-unresolved",
4991
5036
  unfinishedBefore: true,
4992
- beforeStatus: "running"
5037
+ beforeStatus: "running",
5038
+ ...beforeEvents.length > 0 ? { finishedBeforeMasked: true } : {},
5039
+ ...afterEvents.length === 0 ? { afterStatus: "running" } : {}
4993
5040
  }
4994
5041
  )
4995
5042
  ];
4996
5043
  }
4997
- if (beforeEvents.length === 0 || afterEvents.length === 0) {
5044
+ if (beforeEvents.length === 0 || !afterStarted) {
4998
5045
  if (!requireEndpoints) return [];
4999
5046
  const findings = [];
5000
5047
  if (beforeEvents.length === 0) {
@@ -5018,7 +5065,7 @@ function createStepOrderingRule(options) {
5018
5065
  )
5019
5066
  );
5020
5067
  }
5021
- if (afterEvents.length === 0) {
5068
+ if (!afterStarted) {
5022
5069
  const otherKinds = otherKindsForStepName(
5023
5070
  context,
5024
5071
  options.after.kind,
@@ -5041,9 +5088,15 @@ function createStepOrderingRule(options) {
5041
5088
  }
5042
5089
  return findings;
5043
5090
  }
5044
- const encounter = finishedEvents(context).filter(
5045
- (event) => event.kind === options.before.kind && stepEndpointName(event, options.before.kind) === options.before.name || event.kind === options.after.kind && stepEndpointName(event, options.after.kind) === options.after.name
5046
- );
5091
+ const afterForOrder = afterEvents.length > 0 ? afterEvents : afterRunning;
5092
+ const encounter = [
5093
+ ...finishedEvents(context).filter(
5094
+ (event) => event.kind === options.before.kind && stepEndpointName(event, options.before.kind) === options.before.name || event.kind === options.after.kind && stepEndpointName(event, options.after.kind) === options.after.name
5095
+ ),
5096
+ ...afterEvents.length === 0 ? afterRunning.filter(
5097
+ (event) => !finishedEvents(context).some((finished) => finished.eventId === event.eventId)
5098
+ ) : []
5099
+ ];
5047
5100
  let beforeIndex;
5048
5101
  let afterIndex;
5049
5102
  for (const [position, event] of encounter.entries()) {
@@ -5074,7 +5127,7 @@ function createStepOrderingRule(options) {
5074
5127
  ];
5075
5128
  }
5076
5129
  const beforeEvent = beforeEvents[0];
5077
- const afterEvent = afterEvents[0];
5130
+ const afterEvent = afterForOrder[0];
5078
5131
  const beforeEnd = eventEndMs(beforeEvent);
5079
5132
  const afterStart = eventStartMs(afterEvent);
5080
5133
  const endpointExpected = bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after };
@@ -5160,7 +5213,7 @@ function createStepOrderingRule(options) {
5160
5213
  latestBefore = { event, end };
5161
5214
  }
5162
5215
  }
5163
- for (const event of afterEvents) {
5216
+ for (const event of afterForOrder) {
5164
5217
  const start = eventStartMs(event);
5165
5218
  if (start === void 0) {
5166
5219
  missingAfterStarts += 1;
@@ -5189,7 +5242,7 @@ function createStepOrderingRule(options) {
5189
5242
  const tie = tiedEnd === tiedStart ? recordedTieOrder(
5190
5243
  context,
5191
5244
  beforeEvents.filter((event) => eventEndMs(event) === tiedEnd),
5192
- afterEvents.filter((event) => eventStartMs(event) === tiedStart)
5245
+ afterForOrder.filter((event) => eventStartMs(event) === tiedStart)
5193
5246
  ) : void 0;
5194
5247
  if (latestBefore.end > earliestAfter.start || tie !== void 0 && tie.inOrder !== true) {
5195
5248
  return [