agent-inspect 6.7.5 → 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 +12 -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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 627f5f4: Safety precision and share policy: additive finding taxonomy, path-aware raw-content and detector precision, framework metadata sensitivity, source-vs-artifact verify-safe/bundle/MCP gating, --explain, and local override docs. No schema break; no new root/core dependencies; no default network upload; defaults not weakened.
8
+
9
+ ## 6.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 69b6515: LangGraph fidelity contract for `@agent-inspect/langchain`: per-invocation lifecycle, callback reuse isolation, conservative parent reconciliation, synthetic semantic groups, tool identity fields, persist-by-intent, flush/finalize/close, and bounded diagnostics. Includes no-provider LangGraph coverage and NestJS/swarm recipes. No schema break; no new root/core dependencies; no default network upload.
14
+
3
15
  ## 6.7.5
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -131,7 +131,7 @@ Details: [Safe sharing](https://github.com/rajudandigam/agent-inspect/blob/main/
131
131
 
132
132
  ## Project status
133
133
 
134
- **Current release:** **6.7.4** (eighteen linked npm packages). Technical launch candidate; external pilot evidence pending. Persisted schema **1.0**. Node.js **≥ 20**. **v7 not scheduled.**
134
+ **Current release:** **6.9.0** (eighteen linked npm packages). Technical launch candidate; external pilot evidence pending. Persisted schema **1.0**. Node.js **≥ 20**. **v7 not scheduled.**
135
135
 
136
136
  [Roadmap](ROADMAP.md) · [Pilot kit](https://github.com/rajudandigam/agent-inspect/blob/main/docs/PRE-V7-PILOT-KIT.md) · [Changelog](CHANGELOG.md)
137
137
 
package/docs/CLI.md CHANGED
@@ -457,16 +457,19 @@ agent-inspect verify-safe <trace-path-or-run-id> [options]
457
457
  Statuses:
458
458
 
459
459
  - `SAFE`: no safety findings and no reader warnings.
460
- - `SAFE WITH WARNINGS`: no safety findings, but the reader reported warnings or unsupported fields.
461
- - `UNSAFE`: safety findings were detected.
460
+ - `SAFE WITH WARNINGS`: no blocking safety findings, but warnings (reader or findings) remain.
461
+ - `UNSAFE`: blocking safety findings were detected.
462
462
  - `UNKNOWN`: the input could not be read, normalized, or selected conservatively.
463
463
 
464
+ `verify-safe` assesses the **source** trace and a **share-redacted artifact**. The printed/exit `status` follows the **artifact** assessment when a single-file (or stdin) artifact can be derived. `scan` remains source-oriented.
465
+
464
466
  Options:
465
467
 
466
468
  - `--dir <path>`: trace directory for run-id lookup
467
469
  - `--format <agent-inspect-jsonl|openinference-json|otlp-json>`: explicit reader format override
468
470
  - `--run <run-id>`: select a run when input contains multiple runs
469
471
  - `--json`: print deterministic JSON safety result
472
+ - `--explain`: explain each finding (detector/path/category/confidence/redaction/override/bundle gate) without printing matched secret values
470
473
  - `--max-string-length <number>`: unsafe threshold for string values
471
474
  - `--max-array-length <number>`: unsafe threshold for array values
472
475
  - `--max-object-keys <number>`: unsafe threshold for object key counts
@@ -474,11 +477,15 @@ Options:
474
477
 
475
478
  The scan looks for raw prompt/output-like capture paths, unredacted sensitive-looking keys, secret-like string patterns, and oversized values. It reports evidence paths rather than raw prompt, output, request/response, header, API key, secret, or full tool payload values. Secret detection is best-effort and should not be treated as exhaustive.
476
479
 
480
+ Policy and overrides: [SAFETY-POLICY.md](SAFETY-POLICY.md).
481
+
477
482
  Examples:
478
483
 
479
484
  ```bash
480
485
  npx agent-inspect scan fixtures/traces-v0.2/manual-basic.jsonl --json
486
+ npx agent-inspect scan trace.jsonl --explain
481
487
  npx agent-inspect verify-safe minimal-success --dir fixtures/traces
488
+ npx agent-inspect verify-safe trace.jsonl --explain --json
482
489
  npx agent-inspect verify-safe trace.jsonl --max-string-length 8192 --json
483
490
  ```
484
491
 
@@ -866,7 +873,7 @@ If `@agent-inspect/index-sqlite` is not installed, these subcommands print a sho
866
873
 
867
874
  ### 6.24 `bundle`
868
875
 
869
- Create a **share-safe offline trace bundle** as a local folder (v4.3+). Bundles are derived copies: original traces are read-only and never mutated. Automatic `verify-safe` runs before write; the command fails on `UNSAFE` unless `--allow-unsafe`. See [BUNDLES.md](BUNDLES.md).
876
+ Create a **share-safe offline trace bundle** as a local folder (v4.3+). Bundles are derived copies: original traces are read-only and never mutated. Automatic safety assessment runs on the **redacted artifact** before write; the command fails when the artifact is `UNSAFE`/`UNKNOWN` unless `--allow-unsafe`. Source-only findings that redaction removes do not refuse the bundle. See [BUNDLES.md](BUNDLES.md) and [SAFETY-POLICY.md](SAFETY-POLICY.md).
870
877
 
871
878
  ```bash
872
879
  agent-inspect bundle <run-id> [options]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-inspect",
3
- "version": "6.7.5",
3
+ "version": "6.9.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Debug, regression-test, and safely share TypeScript AI-agent behavior locally — no account, no default upload, metadata-only by default",
@@ -3804,8 +3804,9 @@ function buildBundleSummaryMarkdown(parts) {
3804
3804
  ""
3805
3805
  ];
3806
3806
  for (const run of checks.runs) {
3807
+ const source = run.sourceStatus !== void 0 && run.sourceStatus !== run.status ? `; source ${run.sourceStatus}` : "";
3807
3808
  lines.push(
3808
- `- \`${run.runId}\`: ${run.status} (${run.findings} finding(s), ${run.errors} error(s), ${run.warnings} warning(s))`
3809
+ `- \`${run.runId}\`: artifact ${run.status}${source} (${run.findings} finding(s), ${run.errors} error(s), ${run.warnings} warning(s))`
3809
3810
  );
3810
3811
  }
3811
3812
  lines.push("", "## Redaction", "", `Total findings: ${redaction.totalFindings}`, "");
@@ -4180,8 +4181,35 @@ var DEFAULT_RAW_CONTENT_KEYS = [
4180
4181
  "toolinput",
4181
4182
  "tool_input",
4182
4183
  "tooloutput",
4183
- "tool_output"
4184
+ "tool_output",
4185
+ // Framework / agent metadata that carries user or task text
4186
+ "currenttask",
4187
+ "current_task",
4188
+ "task",
4189
+ "userinput",
4190
+ "user_input",
4191
+ "requesttext",
4192
+ "request_text",
4193
+ "conversationtext",
4194
+ "conversation_text"
4184
4195
  ];
4196
+ var DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES = ["tokenUsage", "usage"];
4197
+ var SAFE_USAGE_LEAF_KEYS = /* @__PURE__ */ new Set([
4198
+ "input",
4199
+ "output",
4200
+ "total",
4201
+ "cached",
4202
+ "input_tokens",
4203
+ "inputtokens",
4204
+ "output_tokens",
4205
+ "outputtokens",
4206
+ "total_tokens",
4207
+ "totaltokens",
4208
+ "prompt_tokens",
4209
+ "prompttokens",
4210
+ "completion_tokens",
4211
+ "completiontokens"
4212
+ ]);
4185
4213
  var DEFAULT_SECRET_PATTERNS = [
4186
4214
  { id: "bearer-token", pattern: /Bearer\s+[A-Za-z0-9._~+/-]{12,}=*/ },
4187
4215
  { id: "openai-key", pattern: /sk-[A-Za-z0-9_-]{16,}/ },
@@ -4359,7 +4387,11 @@ function normalizeFinding(rule, finding) {
4359
4387
  message: finding.message,
4360
4388
  ...finding.expected !== void 0 ? { expected: finding.expected } : {},
4361
4389
  ...finding.actual !== void 0 ? { actual: finding.actual } : {},
4362
- evidence: [...finding.evidence ?? []]
4390
+ evidence: [...finding.evidence ?? []],
4391
+ ...finding.category !== void 0 ? { category: finding.category } : {},
4392
+ ...finding.confidence !== void 0 ? { confidence: finding.confidence } : {},
4393
+ ...finding.detector !== void 0 ? { detector: finding.detector } : {},
4394
+ ...finding.action !== void 0 ? { action: finding.action } : {}
4363
4395
  };
4364
4396
  }
4365
4397
  function summarize(findings, diagnostics) {
@@ -4417,15 +4449,19 @@ function eventEvidence(event, path12) {
4417
4449
  function runEvidence(run) {
4418
4450
  return run ? [{ runId: run.runId, name: run.name, status: run.status }] : [];
4419
4451
  }
4420
- function failFinding(ruleId, message, evidence, expected, actual) {
4452
+ function failFinding(ruleId, message, evidence, expected, actual, meta) {
4421
4453
  return {
4422
4454
  ruleId,
4423
- severity: "error",
4424
- status: "fail",
4455
+ severity: meta?.severity ?? "error",
4456
+ status: meta?.status ?? "fail",
4425
4457
  message,
4426
4458
  ...expected !== void 0 ? { expected } : {},
4427
4459
  ...actual !== void 0 ? { actual } : {},
4428
- evidence: [...evidence]
4460
+ evidence: [...evidence],
4461
+ ...meta?.category !== void 0 ? { category: meta.category } : {},
4462
+ ...meta?.confidence !== void 0 ? { confidence: meta.confidence } : {},
4463
+ ...meta?.detector !== void 0 ? { detector: meta.detector } : {},
4464
+ ...meta?.action !== void 0 ? { action: meta.action } : {}
4429
4465
  };
4430
4466
  }
4431
4467
  function toolName(event) {
@@ -4546,6 +4582,19 @@ function isRawContentKey(key, forbiddenKeys) {
4546
4582
  const normalized = normalizedKey(key);
4547
4583
  return forbiddenKeys.some((forbidden) => normalized === normalizedKey(forbidden));
4548
4584
  }
4585
+ function isSafeRawContentMetricPath(path12, key, safePathPrefixes) {
4586
+ const leaf = normalizedKey(key ?? lastPathSegment(path12));
4587
+ if (!SAFE_USAGE_LEAF_KEYS.has(leaf)) return false;
4588
+ const parts = path12.split(".").filter(Boolean);
4589
+ if (parts.length < 2) return false;
4590
+ const parent = parts[parts.length - 2] ?? "";
4591
+ const parentNorm = normalizedKey(parent);
4592
+ return safePathPrefixes.some((prefix) => parentNorm === normalizedKey(prefix));
4593
+ }
4594
+ function isRawContentPath(path12, key, forbiddenKeys, safePathPrefixes) {
4595
+ if (isSafeRawContentMetricPath(path12, key, safePathPrefixes)) return false;
4596
+ return isRawContentKey(key ?? lastPathSegment(path12), forbiddenKeys);
4597
+ }
4549
4598
  function parentMarkedUnresolved(event) {
4550
4599
  if (booleanAttr(event, [
4551
4600
  "parentUnresolved",
@@ -5185,7 +5234,13 @@ function createSafetyRedactionRule(options = {}) {
5185
5234
  `Sensitive-looking field at ${entry.path} is not redacted.`,
5186
5235
  [eventEvidence(event, entry.path)],
5187
5236
  "redaction marker",
5188
- { path: entry.path, valueType: valueType(entry.value) }
5237
+ { path: entry.path, valueType: valueType(entry.value) },
5238
+ {
5239
+ category: "credential",
5240
+ confidence: "high",
5241
+ detector: "safety.redaction",
5242
+ action: "redact"
5243
+ }
5189
5244
  )
5190
5245
  );
5191
5246
  }
@@ -5196,6 +5251,7 @@ function createSafetyRedactionRule(options = {}) {
5196
5251
  }
5197
5252
  function createSafetyRawContentRule(options = {}) {
5198
5253
  const forbiddenKeys = options.forbiddenKeys ?? DEFAULT_RAW_CONTENT_KEYS;
5254
+ const safePathPrefixes = options.safePathPrefixes ?? DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES;
5199
5255
  return {
5200
5256
  id: "safety.rawPrompt",
5201
5257
  category: "safety",
@@ -5205,14 +5261,20 @@ function createSafetyRawContentRule(options = {}) {
5205
5261
  for (const event of context.events) {
5206
5262
  for (const entry of eventValueEntries(event, { includeSummaries: options.includeSummaries })) {
5207
5263
  const key = entry.key ?? lastPathSegment(entry.path);
5208
- if (!isRawContentKey(key, forbiddenKeys)) continue;
5264
+ if (!isRawContentPath(entry.path, key, forbiddenKeys, safePathPrefixes)) continue;
5209
5265
  findings.push(
5210
5266
  failFinding(
5211
5267
  "safety.rawPrompt",
5212
5268
  `Raw content-like field ${entry.path} is present.`,
5213
5269
  [eventEvidence(event, entry.path)],
5214
5270
  "metadata-only trace fields",
5215
- { path: entry.path, valueType: valueType(entry.value) }
5271
+ { path: entry.path, valueType: valueType(entry.value) },
5272
+ {
5273
+ category: "raw-content",
5274
+ confidence: "high",
5275
+ detector: "safety.rawPrompt",
5276
+ action: "redact-or-omit"
5277
+ }
5216
5278
  )
5217
5279
  );
5218
5280
  }
@@ -5244,7 +5306,13 @@ function createSafetySecretPatternRule(options = {}) {
5244
5306
  `Secret-like pattern ${pattern.id} matched at ${entry.path}.`,
5245
5307
  [eventEvidence(event, entry.path)],
5246
5308
  "no secret-like strings",
5247
- { pattern: pattern.id, path: entry.path }
5309
+ { pattern: pattern.id, path: entry.path },
5310
+ {
5311
+ category: "credential",
5312
+ confidence: "high",
5313
+ detector: pattern.id,
5314
+ action: "redact"
5315
+ }
5248
5316
  )
5249
5317
  );
5250
5318
  break;
@@ -5271,7 +5339,13 @@ function createSafetyOversizedAttributeRule(options) {
5271
5339
  `String at ${entry.path} exceeds ${options.maxStringLength} characters.`,
5272
5340
  [eventEvidence(event, entry.path)],
5273
5341
  { maxStringLength: options.maxStringLength },
5274
- { path: entry.path, length: entry.value.length }
5342
+ { path: entry.path, length: entry.value.length },
5343
+ {
5344
+ category: "size",
5345
+ confidence: "high",
5346
+ detector: "safety.oversizedAttribute",
5347
+ action: "truncate-or-omit"
5348
+ }
5275
5349
  )
5276
5350
  );
5277
5351
  }
@@ -5282,7 +5356,13 @@ function createSafetyOversizedAttributeRule(options) {
5282
5356
  `Array at ${entry.path} exceeds ${options.maxArrayLength} items.`,
5283
5357
  [eventEvidence(event, entry.path)],
5284
5358
  { maxArrayLength: options.maxArrayLength },
5285
- { path: entry.path, length: entry.value.length }
5359
+ { path: entry.path, length: entry.value.length },
5360
+ {
5361
+ category: "size",
5362
+ confidence: "high",
5363
+ detector: "safety.oversizedAttribute",
5364
+ action: "truncate-or-omit"
5365
+ }
5286
5366
  )
5287
5367
  );
5288
5368
  }
@@ -5293,7 +5373,13 @@ function createSafetyOversizedAttributeRule(options) {
5293
5373
  `Object at ${entry.path} exceeds ${options.maxObjectKeys} keys.`,
5294
5374
  [eventEvidence(event, entry.path)],
5295
5375
  { maxObjectKeys: options.maxObjectKeys },
5296
- { path: entry.path, keys: Object.keys(entry.value).length }
5376
+ { path: entry.path, keys: Object.keys(entry.value).length },
5377
+ {
5378
+ category: "size",
5379
+ confidence: "high",
5380
+ detector: "safety.oversizedAttribute",
5381
+ action: "truncate-or-omit"
5382
+ }
5297
5383
  )
5298
5384
  );
5299
5385
  }
@@ -5306,7 +5392,13 @@ function createSafetyOversizedAttributeRule(options) {
5306
5392
  `Value at ${entry.path} exceeds ${options.maxSerializedBytes} serialized bytes.`,
5307
5393
  [eventEvidence(event, entry.path)],
5308
5394
  { maxSerializedBytes: options.maxSerializedBytes },
5309
- { path: entry.path, bytes }
5395
+ { path: entry.path, bytes },
5396
+ {
5397
+ category: "size",
5398
+ confidence: "high",
5399
+ detector: "safety.oversizedAttribute",
5400
+ action: "truncate-or-omit"
5401
+ }
5310
5402
  )
5311
5403
  );
5312
5404
  }
@@ -9055,5 +9147,5 @@ function renderGateReport(result, options = {}) {
9055
9147
  }
9056
9148
 
9057
9149
  export { COHORT_METRIC_IDS, DEFAULT_SUITE_ARTIFACTS_DIR, Redactor, TraceDirectory, TraceReadError, TreeBuilder, aggregateBundleSafeStatus, aggregateSessionCheckResults, analyzeCohort, applyProfileMetadataCaps, assertBundlePathContained, buildActivitySummary, buildBundleMetadata, buildBundleSummaryMarkdown, buildLocalExplanation, buildPlaceholderArtifact, buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildSessionIndex, buildTraceStats, bundleFailsOnSafety, bundleRunAssetRelativePath, compactAttributes3 as compactAttributes, createBaselineRegressionRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRunDepthRule, createRunDurationRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStructureCycleRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolUsageRule, defaultBundleOutputPath, defaultSuiteConfigTemplate, enrichSessionRunRecord, escapeHtml, escapeMarkdown, extractMetadata, extractOutcomesFromTraceEvents, filterMetasBySessionScope, filterTraces, flattenTree, formatDuration2 as formatDuration, formatTimestamp, gateHasThresholds, getIndent, getTraceFilePath, isAgentInspectTrace, isPersistedInspectEvent, loadSessionRunRecords, loadSuiteConfig, loadTraceMetadataList, nanoid, normalizeBundleOutputPath, openTrace, parseCohortMetricList, parseDuration, parseDurationFilter, parseGateList, parseTraceJsonl, persistedInspectEventsToTraceEvents, renderActivitySummaryHuman, renderCohortReport, renderErrorLine, renderGateReport, renderObservedOutcomesHtml, renderObservedOutcomesMarkdown, renderRunWhat, renderStepLine, renderSuiteReport, renderTimeline, renderTraceStats, resolveBundleRunIds, resolveRedactionProfile, resolveSuiteTemplate, resolveTraceDir, runGate, runSuite, runTraceChecks, safeString, sanitizeBundleRunId, searchTraces, source_default, stableJson, summarizeObservedOutcomes, traceEventToPersistedInspectEvent, truncateName, truncateStringForProfile, validateEvent, validateSuiteConfig, zeroKinds };
9058
- //# sourceMappingURL=chunk-TO4VENHV.mjs.map
9059
- //# sourceMappingURL=chunk-TO4VENHV.mjs.map
9150
+ //# sourceMappingURL=chunk-WQ5XMFH2.mjs.map
9151
+ //# sourceMappingURL=chunk-WQ5XMFH2.mjs.map