agent-inspect 6.14.1 → 6.15.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.
- package/CHANGELOG.md +14 -2
- package/README.md +1 -1
- package/docs/API.md +19 -3
- package/docs/KNOWN-ISSUES.md +2 -1
- package/package.json +2 -2
- package/packages/cli/dist/{chunk-MEO2Z3KE.mjs → chunk-LFSBMUCD.mjs} +316 -41
- package/packages/cli/dist/chunk-LFSBMUCD.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +388 -42
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +59 -6
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-6VZNGIF6.mjs → src-5J2HPOJ3.mjs} +3 -3
- package/packages/cli/dist/{src-6VZNGIF6.mjs.map → src-5J2HPOJ3.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +268 -24
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +18 -10
- package/packages/core/dist/advanced.d.ts +18 -10
- package/packages/core/dist/advanced.mjs +7 -6
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +221 -22
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.d.cts +18 -8
- package/packages/core/dist/checks.d.ts +18 -8
- package/packages/core/dist/checks.mjs +2 -1
- package/packages/core/dist/chunk-AK5EN4U2.mjs +174 -0
- package/packages/core/dist/chunk-AK5EN4U2.mjs.map +1 -0
- package/packages/core/dist/chunk-FWK3Q3OJ.mjs +56 -0
- package/packages/core/dist/chunk-FWK3Q3OJ.mjs.map +1 -0
- package/packages/core/dist/{chunk-CTA6XNDP.mjs → chunk-HT54OLPE.mjs} +54 -7
- package/packages/core/dist/chunk-HT54OLPE.mjs.map +1 -0
- package/packages/core/dist/{chunk-BS2QCAJX.mjs → chunk-NF4ZHNTC.mjs} +169 -25
- package/packages/core/dist/chunk-NF4ZHNTC.mjs.map +1 -0
- package/packages/core/dist/{chunk-UOPVGCOB.mjs → chunk-NXQF73EC.mjs} +3 -3
- package/packages/core/dist/{chunk-UOPVGCOB.mjs.map → chunk-NXQF73EC.mjs.map} +1 -1
- package/packages/core/dist/{chunk-LFWZEO2L.mjs → chunk-SGL4JGCD.mjs} +3 -3
- package/packages/core/dist/{chunk-LFWZEO2L.mjs.map → chunk-SGL4JGCD.mjs.map} +1 -1
- package/packages/core/dist/{context-BHAgRjOe.d.cts → context-Ca5yK8Cs.d.cts} +3 -3
- package/packages/core/dist/{context-Blyjb5my.d.ts → context-D6cS4XIL.d.ts} +3 -3
- package/packages/core/dist/diff.d.cts +3 -3
- package/packages/core/dist/diff.d.ts +3 -3
- package/packages/core/dist/exporters.d.cts +3 -3
- package/packages/core/dist/exporters.d.ts +3 -3
- package/packages/core/dist/exporters.mjs +1 -1
- package/packages/core/dist/index-B259NKkH.d.cts +102 -0
- package/packages/core/dist/index-B9ZGvUVL.d.ts +102 -0
- package/packages/core/dist/{index-Bu_vOjql.d.ts → index-BsCcOKxy.d.ts} +4 -4
- package/packages/core/dist/{index-CmXMS-MF.d.cts → index-Xk9X-yjY.d.cts} +4 -4
- package/packages/core/dist/index.d.cts +6 -6
- package/packages/core/dist/index.d.ts +6 -6
- package/packages/core/dist/{inspect-event-DVg84S4v.d.cts → inspect-event-DRthdZlf.d.cts} +9 -0
- package/packages/core/dist/{inspect-event-DVg84S4v.d.ts → inspect-event-DRthdZlf.d.ts} +9 -0
- package/packages/core/dist/{log-config-BG1WmWf2.d.cts → log-config-CFlIJHTf.d.cts} +1 -1
- package/packages/core/dist/{log-config-Ck0aT_Ou.d.ts → log-config-OZRfpHED.d.ts} +1 -1
- package/packages/core/dist/logs.cjs +95 -15
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.d.cts +3 -3
- package/packages/core/dist/logs.d.ts +3 -3
- package/packages/core/dist/logs.mjs +2 -2
- package/packages/core/dist/{persisted-inspect-event-ChE7pGb7.d.ts → persisted-inspect-event-BVucFVrP.d.ts} +1 -1
- package/packages/core/dist/{persisted-inspect-event-d-mSP8kd.d.cts → persisted-inspect-event-CVZWZldL.d.cts} +1 -1
- package/packages/core/dist/persisted.cjs +95 -15
- package/packages/core/dist/persisted.cjs.map +1 -1
- package/packages/core/dist/persisted.d.cts +5 -5
- package/packages/core/dist/persisted.d.ts +5 -5
- package/packages/core/dist/persisted.mjs +3 -3
- package/packages/core/dist/readers.cjs +203 -18
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.d.cts +27 -78
- package/packages/core/dist/readers.d.ts +27 -78
- package/packages/core/dist/readers.mjs +4 -3
- package/packages/core/dist/{types-MuwXSJ4b.d.ts → types--ainI31J.d.ts} +1 -1
- package/packages/core/dist/{types-BLX3tiOW.d.cts → types-UnrNaTo2.d.cts} +1 -1
- package/packages/core/dist/writers.d.cts +2 -2
- package/packages/core/dist/writers.d.ts +2 -2
- package/packages/cli/dist/chunk-MEO2Z3KE.mjs.map +0 -1
- package/packages/core/dist/chunk-BS2QCAJX.mjs.map +0 -1
- package/packages/core/dist/chunk-CTA6XNDP.mjs.map +0 -1
- package/packages/core/dist/chunk-T5MASTIW.mjs +0 -94
- package/packages/core/dist/chunk-T5MASTIW.mjs.map +0 -1
|
@@ -6354,6 +6354,136 @@ var init_resolve2 = __esm({
|
|
|
6354
6354
|
}
|
|
6355
6355
|
});
|
|
6356
6356
|
|
|
6357
|
+
// packages/core/src/diagnostics/programmatic.ts
|
|
6358
|
+
function formatProgrammaticDiagnostic(code, detail) {
|
|
6359
|
+
const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
|
|
6360
|
+
const summary = detail?.trim() ? detail.trim() : spec.summary;
|
|
6361
|
+
return `${code}: ${summary} Remediation: ${spec.remediation}`;
|
|
6362
|
+
}
|
|
6363
|
+
var PROGRAMMATIC_DIAGNOSTIC_SPECS;
|
|
6364
|
+
var init_programmatic = __esm({
|
|
6365
|
+
"packages/core/src/diagnostics/programmatic.ts"() {
|
|
6366
|
+
PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
|
|
6367
|
+
AI_TRACE_INPUT_INVALID: {
|
|
6368
|
+
code: "AI_TRACE_INPUT_INVALID",
|
|
6369
|
+
summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
|
|
6370
|
+
remediation: "For a file path, use openTraceFile(path).",
|
|
6371
|
+
relatedCodes: ["invalid_input"]
|
|
6372
|
+
},
|
|
6373
|
+
AI_TRACE_FORMAT_UNSUPPORTED: {
|
|
6374
|
+
code: "AI_TRACE_FORMAT_UNSUPPORTED",
|
|
6375
|
+
summary: "No trace reader could detect the input format.",
|
|
6376
|
+
remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
|
|
6377
|
+
relatedCodes: ["unsupported_format"]
|
|
6378
|
+
},
|
|
6379
|
+
AI_TRACE_FORMAT_AMBIGUOUS: {
|
|
6380
|
+
code: "AI_TRACE_FORMAT_AMBIGUOUS",
|
|
6381
|
+
summary: "Multiple trace readers matched the input with equal confidence.",
|
|
6382
|
+
remediation: "Set options.format explicitly to disambiguate the reader.",
|
|
6383
|
+
relatedCodes: ["ambiguous_format"]
|
|
6384
|
+
},
|
|
6385
|
+
AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
|
|
6386
|
+
code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
|
|
6387
|
+
summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
|
|
6388
|
+
remediation: "Use openTraceFile() to normalize a JSONL trace first."
|
|
6389
|
+
},
|
|
6390
|
+
AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
|
|
6391
|
+
code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
6392
|
+
summary: "Multiple runs are available; select a run before executing checks.",
|
|
6393
|
+
remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
|
|
6394
|
+
relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
|
|
6395
|
+
},
|
|
6396
|
+
AI_TRACE_RELATIONSHIP_SELF_PARENT: {
|
|
6397
|
+
code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
6398
|
+
summary: "A parentId equals its own event/step id.",
|
|
6399
|
+
remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
|
|
6400
|
+
relatedCodes: [
|
|
6401
|
+
"AI_LANGGRAPH_SELF_PARENT_REJECTED",
|
|
6402
|
+
"AI_LOGICAL_SELF_PARENT_REMOVED"
|
|
6403
|
+
]
|
|
6404
|
+
},
|
|
6405
|
+
AI_TRACE_RELATIONSHIP_CYCLE: {
|
|
6406
|
+
code: "AI_TRACE_RELATIONSHIP_CYCLE",
|
|
6407
|
+
summary: "Trace contains a parentId cycle.",
|
|
6408
|
+
remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
|
|
6409
|
+
relatedCodes: ["structure.cycle"]
|
|
6410
|
+
}
|
|
6411
|
+
});
|
|
6412
|
+
}
|
|
6413
|
+
});
|
|
6414
|
+
|
|
6415
|
+
// packages/core/src/safety/sensitive-key.ts
|
|
6416
|
+
function normalizeSensitiveKey(value) {
|
|
6417
|
+
return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
|
|
6418
|
+
}
|
|
6419
|
+
function isTokenCredentialKey(normalized) {
|
|
6420
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
6421
|
+
if (normalized === "token") return true;
|
|
6422
|
+
if (normalized.endsWith("tokens")) return false;
|
|
6423
|
+
return normalized.endsWith("token");
|
|
6424
|
+
}
|
|
6425
|
+
function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
|
|
6426
|
+
if (!key) return false;
|
|
6427
|
+
const normalized = normalizeSensitiveKey(key);
|
|
6428
|
+
if (!normalized) return false;
|
|
6429
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
6430
|
+
for (const sensitive of sensitiveKeys) {
|
|
6431
|
+
const s = normalizeSensitiveKey(sensitive);
|
|
6432
|
+
if (!s) continue;
|
|
6433
|
+
if (s === "token") {
|
|
6434
|
+
if (isTokenCredentialKey(normalized)) return true;
|
|
6435
|
+
continue;
|
|
6436
|
+
}
|
|
6437
|
+
if (normalized === s) return true;
|
|
6438
|
+
if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
|
|
6439
|
+
}
|
|
6440
|
+
return false;
|
|
6441
|
+
}
|
|
6442
|
+
var NON_CREDENTIAL_TOKEN_CONFIG_KEYS, DEFAULT_CREDENTIAL_SENSITIVE_KEYS;
|
|
6443
|
+
var init_sensitive_key = __esm({
|
|
6444
|
+
"packages/core/src/safety/sensitive-key.ts"() {
|
|
6445
|
+
NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
|
|
6446
|
+
[
|
|
6447
|
+
"tokens",
|
|
6448
|
+
"max_tokens",
|
|
6449
|
+
"min_tokens",
|
|
6450
|
+
"ls_max_tokens",
|
|
6451
|
+
"token_count",
|
|
6452
|
+
"token_limit",
|
|
6453
|
+
"token_budget",
|
|
6454
|
+
"input_tokens",
|
|
6455
|
+
"output_tokens",
|
|
6456
|
+
"total_tokens",
|
|
6457
|
+
"cached_tokens",
|
|
6458
|
+
"prompt_tokens",
|
|
6459
|
+
"completion_tokens"
|
|
6460
|
+
].map(normalizeSensitiveKey)
|
|
6461
|
+
);
|
|
6462
|
+
DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
|
|
6463
|
+
"authorization",
|
|
6464
|
+
"cookie",
|
|
6465
|
+
"token",
|
|
6466
|
+
"access_token",
|
|
6467
|
+
"accesstoken",
|
|
6468
|
+
"auth_token",
|
|
6469
|
+
"authtoken",
|
|
6470
|
+
"refresh_token",
|
|
6471
|
+
"refreshtoken",
|
|
6472
|
+
"id_token",
|
|
6473
|
+
"idtoken",
|
|
6474
|
+
"bearer_token",
|
|
6475
|
+
"bearertoken",
|
|
6476
|
+
"api_token",
|
|
6477
|
+
"apitoken",
|
|
6478
|
+
"apikey",
|
|
6479
|
+
"api_key",
|
|
6480
|
+
"password",
|
|
6481
|
+
"secret",
|
|
6482
|
+
"email"
|
|
6483
|
+
];
|
|
6484
|
+
}
|
|
6485
|
+
});
|
|
6486
|
+
|
|
6357
6487
|
// packages/core/src/checks/logical-events.ts
|
|
6358
6488
|
function isRecord7(value) {
|
|
6359
6489
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -6549,6 +6679,26 @@ function projectLogicalEvents(events) {
|
|
|
6549
6679
|
}
|
|
6550
6680
|
}
|
|
6551
6681
|
if (!remapped) {
|
|
6682
|
+
if (originalParentId === event.eventId) {
|
|
6683
|
+
diagnostics.push({
|
|
6684
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
6685
|
+
message: formatProgrammaticDiagnostic(
|
|
6686
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
6687
|
+
`Removed self-parent edge on ${event.eventId}.`
|
|
6688
|
+
),
|
|
6689
|
+
eventIds: [event.eventId]
|
|
6690
|
+
});
|
|
6691
|
+
const { parentId: _drop, ...rest } = event;
|
|
6692
|
+
normalized.push({
|
|
6693
|
+
...rest,
|
|
6694
|
+
projection: {
|
|
6695
|
+
...event.projection,
|
|
6696
|
+
parentNormalized: true,
|
|
6697
|
+
originalParentId
|
|
6698
|
+
}
|
|
6699
|
+
});
|
|
6700
|
+
continue;
|
|
6701
|
+
}
|
|
6552
6702
|
if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
|
|
6553
6703
|
const mapping = event.attributes?.parentMapping;
|
|
6554
6704
|
const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
|
|
@@ -6564,6 +6714,26 @@ function projectLogicalEvents(events) {
|
|
|
6564
6714
|
normalized.push(event);
|
|
6565
6715
|
continue;
|
|
6566
6716
|
}
|
|
6717
|
+
if (nextParent === event.eventId) {
|
|
6718
|
+
diagnostics.push({
|
|
6719
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
6720
|
+
message: formatProgrammaticDiagnostic(
|
|
6721
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
6722
|
+
`Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`
|
|
6723
|
+
),
|
|
6724
|
+
eventIds: [event.eventId]
|
|
6725
|
+
});
|
|
6726
|
+
const { parentId: _drop, ...rest } = event;
|
|
6727
|
+
normalized.push({
|
|
6728
|
+
...rest,
|
|
6729
|
+
projection: {
|
|
6730
|
+
...event.projection,
|
|
6731
|
+
parentNormalized: true,
|
|
6732
|
+
originalParentId
|
|
6733
|
+
}
|
|
6734
|
+
});
|
|
6735
|
+
continue;
|
|
6736
|
+
}
|
|
6567
6737
|
diagnostics.push({
|
|
6568
6738
|
code: "AI_LOGICAL_PARENT_REMAPPED",
|
|
6569
6739
|
message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
|
|
@@ -6614,6 +6784,7 @@ function pickString(record, keys) {
|
|
|
6614
6784
|
}
|
|
6615
6785
|
var init_logical_events = __esm({
|
|
6616
6786
|
"packages/core/src/checks/logical-events.ts"() {
|
|
6787
|
+
init_programmatic();
|
|
6617
6788
|
}
|
|
6618
6789
|
});
|
|
6619
6790
|
|
|
@@ -6642,7 +6813,11 @@ function summarizeSemanticParity(events) {
|
|
|
6642
6813
|
}
|
|
6643
6814
|
var init_trace_facts = __esm({
|
|
6644
6815
|
"packages/core/src/checks/trace-facts.ts"() {
|
|
6816
|
+
init_programmatic();
|
|
6645
6817
|
init_logical_events();
|
|
6818
|
+
formatProgrammaticDiagnostic(
|
|
6819
|
+
"AI_TRACE_FACTS_INPUT_NOT_NORMALIZED"
|
|
6820
|
+
);
|
|
6646
6821
|
}
|
|
6647
6822
|
});
|
|
6648
6823
|
|
|
@@ -6753,7 +6928,13 @@ function resolveSelectedRun(input3, runId) {
|
|
|
6753
6928
|
if (input3.read.runs.length === 0) {
|
|
6754
6929
|
return {
|
|
6755
6930
|
diagnostics: [
|
|
6756
|
-
diagnostic3(
|
|
6931
|
+
diagnostic3(
|
|
6932
|
+
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
6933
|
+
formatProgrammaticDiagnostic(
|
|
6934
|
+
"AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
6935
|
+
"No runs are available for checks."
|
|
6936
|
+
)
|
|
6937
|
+
)
|
|
6757
6938
|
]
|
|
6758
6939
|
};
|
|
6759
6940
|
}
|
|
@@ -6761,7 +6942,7 @@ function resolveSelectedRun(input3, runId) {
|
|
|
6761
6942
|
diagnostics: [
|
|
6762
6943
|
diagnostic3(
|
|
6763
6944
|
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
6764
|
-
"
|
|
6945
|
+
formatProgrammaticDiagnostic("AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED")
|
|
6765
6946
|
)
|
|
6766
6947
|
]
|
|
6767
6948
|
};
|
|
@@ -7017,9 +7198,7 @@ function hasRedactionMarker(value, markers) {
|
|
|
7017
7198
|
return markers.some((marker) => value.includes(marker)) || /^\[HASH:[A-Za-z0-9_-]+\]$/.test(value);
|
|
7018
7199
|
}
|
|
7019
7200
|
function isSensitiveKey(key, sensitiveKeys) {
|
|
7020
|
-
|
|
7021
|
-
const normalized = normalizedKey(key);
|
|
7022
|
-
return sensitiveKeys.some((sensitive) => normalized.includes(normalizedKey(sensitive)));
|
|
7201
|
+
return isCredentialSensitiveKey(key, sensitiveKeys);
|
|
7023
7202
|
}
|
|
7024
7203
|
function isRawContentKey(key, forbiddenKeys) {
|
|
7025
7204
|
if (!key) return false;
|
|
@@ -7342,7 +7521,7 @@ function createToolUsageRule(options) {
|
|
|
7342
7521
|
}
|
|
7343
7522
|
}
|
|
7344
7523
|
const forbidden = new Set(options.forbidden ?? []);
|
|
7345
|
-
const allowed = options.allowed ? new Set(options.allowed) : void 0;
|
|
7524
|
+
const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
|
|
7346
7525
|
for (const event of tools) {
|
|
7347
7526
|
const name = toolName(event);
|
|
7348
7527
|
if (forbidden.has(name)) {
|
|
@@ -7378,9 +7557,9 @@ function createLlmUsageRule(options) {
|
|
|
7378
7557
|
evaluate(context) {
|
|
7379
7558
|
const llms = finishedEvents(context, "LLM");
|
|
7380
7559
|
const findings = [];
|
|
7381
|
-
const allowedModels = options.allowedModels ? new Set(options.allowedModels) : void 0;
|
|
7382
|
-
const allowedProviders = options.allowedProviders ? new Set(options.allowedProviders) : void 0;
|
|
7383
|
-
const finishReasons = options.finishReasons ? new Set(options.finishReasons) : void 0;
|
|
7560
|
+
const allowedModels = options.allowedModels?.length ? new Set(options.allowedModels) : void 0;
|
|
7561
|
+
const allowedProviders = options.allowedProviders?.length ? new Set(options.allowedProviders) : void 0;
|
|
7562
|
+
const finishReasons = options.finishReasons?.length ? new Set(options.finishReasons) : void 0;
|
|
7384
7563
|
if (options.maxCalls !== void 0 && llms.length > options.maxCalls) {
|
|
7385
7564
|
findings.push(
|
|
7386
7565
|
failFinding(
|
|
@@ -7492,7 +7671,7 @@ function createStructureCycleRule() {
|
|
|
7492
7671
|
findings.push(
|
|
7493
7672
|
failFinding(
|
|
7494
7673
|
"structure.cycle",
|
|
7495
|
-
"
|
|
7674
|
+
formatProgrammaticDiagnostic("AI_TRACE_RELATIONSHIP_CYCLE"),
|
|
7496
7675
|
cycle.map((item) => eventEvidence(item, "parentId")),
|
|
7497
7676
|
"acyclic parentId graph",
|
|
7498
7677
|
cycle.map((item) => item.eventId).sort()
|
|
@@ -8059,10 +8238,14 @@ function runTraceChecks(input3, options = {}) {
|
|
|
8059
8238
|
var SEVERITY_RANK, STATUS_RANK, CONFIDENCE_RANK, DEFAULT_SENSITIVE_KEYS, DEFAULT_RAW_CONTENT_KEYS, DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES, SAFE_USAGE_LEAF_KEYS, DEFAULT_SECRET_PATTERNS;
|
|
8060
8239
|
var init_checks2 = __esm({
|
|
8061
8240
|
"packages/core/src/checks/index.ts"() {
|
|
8241
|
+
init_programmatic();
|
|
8062
8242
|
init_outcomes();
|
|
8243
|
+
init_sensitive_key();
|
|
8063
8244
|
init_logical_events();
|
|
8064
8245
|
init_logical_events();
|
|
8065
8246
|
init_trace_facts();
|
|
8247
|
+
init_programmatic();
|
|
8248
|
+
init_sensitive_key();
|
|
8066
8249
|
init_contract();
|
|
8067
8250
|
SEVERITY_RANK = {
|
|
8068
8251
|
error: 0,
|
|
@@ -8080,16 +8263,7 @@ var init_checks2 = __esm({
|
|
|
8080
8263
|
correlated: 2,
|
|
8081
8264
|
explicit: 3
|
|
8082
8265
|
};
|
|
8083
|
-
DEFAULT_SENSITIVE_KEYS =
|
|
8084
|
-
"authorization",
|
|
8085
|
-
"cookie",
|
|
8086
|
-
"token",
|
|
8087
|
-
"apikey",
|
|
8088
|
-
"api_key",
|
|
8089
|
-
"password",
|
|
8090
|
-
"secret",
|
|
8091
|
-
"email"
|
|
8092
|
-
];
|
|
8266
|
+
DEFAULT_SENSITIVE_KEYS = DEFAULT_CREDENTIAL_SENSITIVE_KEYS;
|
|
8093
8267
|
DEFAULT_RAW_CONTENT_KEYS = [
|
|
8094
8268
|
"body",
|
|
8095
8269
|
"headers",
|
|
@@ -8434,6 +8608,20 @@ var init_from_trace_event = __esm({
|
|
|
8434
8608
|
function inc(map, key) {
|
|
8435
8609
|
map[key] = (map[key] ?? 0) + 1;
|
|
8436
8610
|
}
|
|
8611
|
+
function confidenceRank(confidence) {
|
|
8612
|
+
switch (confidence) {
|
|
8613
|
+
case "unknown":
|
|
8614
|
+
return 0;
|
|
8615
|
+
case "heuristic":
|
|
8616
|
+
return 1;
|
|
8617
|
+
case "correlated":
|
|
8618
|
+
return 2;
|
|
8619
|
+
case "explicit":
|
|
8620
|
+
return 3;
|
|
8621
|
+
default:
|
|
8622
|
+
return 0;
|
|
8623
|
+
}
|
|
8624
|
+
}
|
|
8437
8625
|
function computeRunStatus(events) {
|
|
8438
8626
|
let runTerminal;
|
|
8439
8627
|
let sawRunEvent = false;
|
|
@@ -8454,6 +8642,84 @@ function computeRunStatus(events) {
|
|
|
8454
8642
|
}
|
|
8455
8643
|
return hasRunning ? "running" : "ok";
|
|
8456
8644
|
}
|
|
8645
|
+
function linkNodesVisibilityFirst(nodes) {
|
|
8646
|
+
let selfParentCount = 0;
|
|
8647
|
+
let unresolvedParentCount = 0;
|
|
8648
|
+
let normalizedEdgeCount = 0;
|
|
8649
|
+
let cycleCount = 0;
|
|
8650
|
+
const pending = [];
|
|
8651
|
+
for (const node of nodes.values()) {
|
|
8652
|
+
const parentId = node.event.parentId;
|
|
8653
|
+
if (!parentId) continue;
|
|
8654
|
+
if (parentId === node.event.eventId) {
|
|
8655
|
+
selfParentCount += 1;
|
|
8656
|
+
normalizedEdgeCount += 1;
|
|
8657
|
+
continue;
|
|
8658
|
+
}
|
|
8659
|
+
if (!nodes.has(parentId)) {
|
|
8660
|
+
unresolvedParentCount += 1;
|
|
8661
|
+
continue;
|
|
8662
|
+
}
|
|
8663
|
+
pending.push({
|
|
8664
|
+
childId: node.event.eventId,
|
|
8665
|
+
parentId,
|
|
8666
|
+
childTimestamp: node.event.timestamp,
|
|
8667
|
+
childConfidence: node.event.confidence
|
|
8668
|
+
});
|
|
8669
|
+
}
|
|
8670
|
+
pending.sort((a, b) => {
|
|
8671
|
+
const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
|
|
8672
|
+
if (conf !== 0) return conf;
|
|
8673
|
+
return a.childTimestamp - b.childTimestamp;
|
|
8674
|
+
});
|
|
8675
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
8676
|
+
for (const edge of pending) {
|
|
8677
|
+
parentOf.set(edge.childId, edge.parentId);
|
|
8678
|
+
let cursor = edge.parentId;
|
|
8679
|
+
const seen = /* @__PURE__ */ new Set([edge.childId]);
|
|
8680
|
+
let cyclic = false;
|
|
8681
|
+
while (cursor) {
|
|
8682
|
+
if (seen.has(cursor)) {
|
|
8683
|
+
cyclic = true;
|
|
8684
|
+
break;
|
|
8685
|
+
}
|
|
8686
|
+
seen.add(cursor);
|
|
8687
|
+
cursor = parentOf.get(cursor);
|
|
8688
|
+
}
|
|
8689
|
+
if (cyclic) {
|
|
8690
|
+
parentOf.delete(edge.childId);
|
|
8691
|
+
cycleCount += 1;
|
|
8692
|
+
normalizedEdgeCount += 1;
|
|
8693
|
+
}
|
|
8694
|
+
}
|
|
8695
|
+
for (const [childId, parentId] of parentOf) {
|
|
8696
|
+
nodes.get(parentId).children.push(nodes.get(childId));
|
|
8697
|
+
}
|
|
8698
|
+
const roots = [];
|
|
8699
|
+
for (const node of nodes.values()) {
|
|
8700
|
+
if (!parentOf.has(node.event.eventId)) {
|
|
8701
|
+
roots.push(node);
|
|
8702
|
+
}
|
|
8703
|
+
}
|
|
8704
|
+
const assignDepth = (n, depth, stack) => {
|
|
8705
|
+
if (stack.has(n.event.eventId)) return;
|
|
8706
|
+
n.depth = depth;
|
|
8707
|
+
stack.add(n.event.eventId);
|
|
8708
|
+
for (const c of n.children) assignDepth(c, depth + 1, stack);
|
|
8709
|
+
stack.delete(n.event.eventId);
|
|
8710
|
+
};
|
|
8711
|
+
for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
|
|
8712
|
+
return {
|
|
8713
|
+
roots,
|
|
8714
|
+
summary: {
|
|
8715
|
+
rootCount: roots.length,
|
|
8716
|
+
selfParentCount,
|
|
8717
|
+
cycleCount,
|
|
8718
|
+
unresolvedParentCount,
|
|
8719
|
+
normalizedEdgeCount
|
|
8720
|
+
}
|
|
8721
|
+
};
|
|
8722
|
+
}
|
|
8457
8723
|
var TreeBuilder;
|
|
8458
8724
|
var init_tree_builder = __esm({
|
|
8459
8725
|
"packages/core/src/logs/tree-builder.ts"() {
|
|
@@ -8474,20 +8740,7 @@ var init_tree_builder = __esm({
|
|
|
8474
8740
|
for (const e of sorted) {
|
|
8475
8741
|
nodes.set(e.eventId, { event: e, children: [], depth: 0 });
|
|
8476
8742
|
}
|
|
8477
|
-
const roots =
|
|
8478
|
-
for (const node of nodes.values()) {
|
|
8479
|
-
const parentId = node.event.parentId;
|
|
8480
|
-
if (parentId && nodes.has(parentId)) {
|
|
8481
|
-
nodes.get(parentId).children.push(node);
|
|
8482
|
-
} else {
|
|
8483
|
-
roots.push(node);
|
|
8484
|
-
}
|
|
8485
|
-
}
|
|
8486
|
-
const assignDepth = (n, depth) => {
|
|
8487
|
-
n.depth = depth;
|
|
8488
|
-
for (const c of n.children) assignDepth(c, depth + 1);
|
|
8489
|
-
};
|
|
8490
|
-
for (const r of roots) assignDepth(r, 0);
|
|
8743
|
+
const { roots, summary } = linkNodesVisibilityFirst(nodes);
|
|
8491
8744
|
const confidenceBreakdown = {
|
|
8492
8745
|
explicit: 0,
|
|
8493
8746
|
correlated: 0,
|
|
@@ -8515,7 +8768,8 @@ var init_tree_builder = __esm({
|
|
|
8515
8768
|
metadata: {
|
|
8516
8769
|
totalEvents: sorted.length,
|
|
8517
8770
|
confidenceBreakdown,
|
|
8518
|
-
kinds
|
|
8771
|
+
kinds,
|
|
8772
|
+
relationshipSummary: summary
|
|
8519
8773
|
}
|
|
8520
8774
|
});
|
|
8521
8775
|
}
|
|
@@ -8683,6 +8937,35 @@ var init_tree_bridge = __esm({
|
|
|
8683
8937
|
init_to_inspect_event();
|
|
8684
8938
|
}
|
|
8685
8939
|
});
|
|
8940
|
+
function isTraceInput(input3) {
|
|
8941
|
+
if (typeof input3 !== "object" || input3 === null || Array.isArray(input3)) {
|
|
8942
|
+
return false;
|
|
8943
|
+
}
|
|
8944
|
+
const record = input3;
|
|
8945
|
+
switch (record.type) {
|
|
8946
|
+
case "file":
|
|
8947
|
+
case "directory":
|
|
8948
|
+
return typeof record.path === "string";
|
|
8949
|
+
case "string":
|
|
8950
|
+
return typeof record.content === "string";
|
|
8951
|
+
case "buffer":
|
|
8952
|
+
return Buffer.isBuffer(record.content);
|
|
8953
|
+
case "stdin":
|
|
8954
|
+
return true;
|
|
8955
|
+
default:
|
|
8956
|
+
return false;
|
|
8957
|
+
}
|
|
8958
|
+
}
|
|
8959
|
+
function assertTraceInput(input3) {
|
|
8960
|
+
if (isTraceInput(input3)) return;
|
|
8961
|
+
throw new TraceReadError("invalid_input", TRACE_INPUT_INVALID_MESSAGE, [
|
|
8962
|
+
{
|
|
8963
|
+
code: "AI_TRACE_INPUT_INVALID",
|
|
8964
|
+
message: TRACE_INPUT_INVALID_MESSAGE,
|
|
8965
|
+
severity: "error"
|
|
8966
|
+
}
|
|
8967
|
+
]);
|
|
8968
|
+
}
|
|
8686
8969
|
function normalizeCandidate(reader, candidate) {
|
|
8687
8970
|
const confidence = Number.isFinite(candidate.confidence) ? Math.max(0, Math.min(1, candidate.confidence)) : 0;
|
|
8688
8971
|
return {
|
|
@@ -9829,6 +10112,7 @@ function mapOtlpEventsToPersisted(document) {
|
|
|
9829
10112
|
};
|
|
9830
10113
|
}
|
|
9831
10114
|
async function detectTraceFormat(input3, options = {}) {
|
|
10115
|
+
assertTraceInput(input3);
|
|
9832
10116
|
const readers = options.readers ?? DEFAULT_TRACE_READERS;
|
|
9833
10117
|
if (options.format !== void 0) {
|
|
9834
10118
|
const reader = findReaderByFormat(options.format, readers);
|
|
@@ -9925,19 +10209,20 @@ async function detectTraceFormat(input3, options = {}) {
|
|
|
9925
10209
|
};
|
|
9926
10210
|
}
|
|
9927
10211
|
async function readTrace(input3, options = {}) {
|
|
10212
|
+
assertTraceInput(input3);
|
|
9928
10213
|
const readers = options.readers ?? DEFAULT_TRACE_READERS;
|
|
9929
10214
|
const detection = await detectTraceFormat(input3, options);
|
|
9930
10215
|
if (detection.status === "unsupported" || detection.format === void 0) {
|
|
9931
10216
|
throw new TraceReadError(
|
|
9932
10217
|
"unsupported_format",
|
|
9933
|
-
"
|
|
10218
|
+
formatProgrammaticDiagnostic("AI_TRACE_FORMAT_UNSUPPORTED"),
|
|
9934
10219
|
detection.warnings
|
|
9935
10220
|
);
|
|
9936
10221
|
}
|
|
9937
10222
|
if (detection.status === "ambiguous") {
|
|
9938
10223
|
throw new TraceReadError(
|
|
9939
10224
|
"ambiguous_format",
|
|
9940
|
-
"
|
|
10225
|
+
formatProgrammaticDiagnostic("AI_TRACE_FORMAT_AMBIGUOUS"),
|
|
9941
10226
|
detection.warnings
|
|
9942
10227
|
);
|
|
9943
10228
|
}
|
|
@@ -9945,7 +10230,10 @@ async function readTrace(input3, options = {}) {
|
|
|
9945
10230
|
if (!reader) {
|
|
9946
10231
|
throw new TraceReadError(
|
|
9947
10232
|
"unsupported_format",
|
|
9948
|
-
|
|
10233
|
+
formatProgrammaticDiagnostic(
|
|
10234
|
+
"AI_TRACE_FORMAT_UNSUPPORTED",
|
|
10235
|
+
`No trace reader is registered for format "${detection.format}".`
|
|
10236
|
+
),
|
|
9949
10237
|
detection.warnings
|
|
9950
10238
|
);
|
|
9951
10239
|
}
|
|
@@ -9974,12 +10262,13 @@ async function readTrace(input3, options = {}) {
|
|
|
9974
10262
|
function openTrace(input3, options = {}) {
|
|
9975
10263
|
return readTrace(input3, options);
|
|
9976
10264
|
}
|
|
9977
|
-
var DEFAULT_MAX_TRACE_INPUT_BYTES, MIN_DETECTION_CONFIDENCE, AMBIGUOUS_CONFIDENCE_DELTA, resolvedInputCache, OPENINFERENCE_READER_FORMAT, OTLP_READER_FORMAT, OPENINFERENCE_SPAN_KEYS, OPENINFERENCE_SENSITIVE_ATTRIBUTE_KEYS, OTLP_SPAN_KEYS, TraceReadError, openInferenceJsonReader, otlpJsonReader, agentInspectJsonlReader, DEFAULT_TRACE_READERS;
|
|
10265
|
+
var DEFAULT_MAX_TRACE_INPUT_BYTES, MIN_DETECTION_CONFIDENCE, AMBIGUOUS_CONFIDENCE_DELTA, resolvedInputCache, OPENINFERENCE_READER_FORMAT, OTLP_READER_FORMAT, OPENINFERENCE_SPAN_KEYS, OPENINFERENCE_SENSITIVE_ATTRIBUTE_KEYS, OTLP_SPAN_KEYS, TraceReadError, TRACE_INPUT_INVALID_MESSAGE, openInferenceJsonReader, otlpJsonReader, agentInspectJsonlReader, DEFAULT_TRACE_READERS;
|
|
9978
10266
|
var init_readers = __esm({
|
|
9979
10267
|
"packages/core/src/readers/index.ts"() {
|
|
9980
10268
|
init_read_trace();
|
|
9981
10269
|
init_from_trace_event();
|
|
9982
10270
|
init_tree_bridge();
|
|
10271
|
+
init_programmatic();
|
|
9983
10272
|
DEFAULT_MAX_TRACE_INPUT_BYTES = 10 * 1024 * 1024;
|
|
9984
10273
|
MIN_DETECTION_CONFIDENCE = 0.5;
|
|
9985
10274
|
AMBIGUOUS_CONFIDENCE_DELTA = 0.05;
|
|
@@ -10053,6 +10342,9 @@ var init_readers = __esm({
|
|
|
10053
10342
|
this.warnings = warnings;
|
|
10054
10343
|
}
|
|
10055
10344
|
};
|
|
10345
|
+
TRACE_INPUT_INVALID_MESSAGE = formatProgrammaticDiagnostic(
|
|
10346
|
+
"AI_TRACE_INPUT_INVALID"
|
|
10347
|
+
);
|
|
10056
10348
|
openInferenceJsonReader = {
|
|
10057
10349
|
format: OPENINFERENCE_READER_FORMAT,
|
|
10058
10350
|
name: "OpenInference JSON",
|
|
@@ -12193,7 +12485,7 @@ var init_src = __esm({
|
|
|
12193
12485
|
});
|
|
12194
12486
|
|
|
12195
12487
|
// package.json
|
|
12196
|
-
var version = "6.
|
|
12488
|
+
var version = "6.15.0";
|
|
12197
12489
|
|
|
12198
12490
|
// packages/cli/src/list.ts
|
|
12199
12491
|
init_advanced();
|
|
@@ -12523,6 +12815,7 @@ init_tree_bridge();
|
|
|
12523
12815
|
|
|
12524
12816
|
// packages/core/src/entries/readers.ts
|
|
12525
12817
|
init_readers();
|
|
12818
|
+
init_programmatic();
|
|
12526
12819
|
|
|
12527
12820
|
// packages/cli/src/read-run.ts
|
|
12528
12821
|
function mapReaderFormat(format) {
|
|
@@ -15540,7 +15833,7 @@ async function searchCommand(options = {}) {
|
|
|
15540
15833
|
}
|
|
15541
15834
|
console.log(`Search results (${results.length})`);
|
|
15542
15835
|
for (const r of results) {
|
|
15543
|
-
const step = r.stepName !== void 0 ? ` | ${r.stepType ?? "step"
|
|
15836
|
+
const step = r.stepName !== void 0 ? ` | ${formatStepLabel(r.stepType ?? "step", r.stepName)}` : "";
|
|
15544
15837
|
const dur = r.durationMs !== void 0 ? ` | ${r.durationMs}ms` : "";
|
|
15545
15838
|
console.log(
|
|
15546
15839
|
`${r.runId}${step} | ${r.runStatus}${dur} | ${r.matchReason}`
|
|
@@ -16083,6 +16376,53 @@ async function reportCommand(runId, options = {}) {
|
|
|
16083
16376
|
|
|
16084
16377
|
// packages/cli/src/redact.ts
|
|
16085
16378
|
init_advanced();
|
|
16379
|
+
|
|
16380
|
+
// packages/redact/src/sensitive-key.ts
|
|
16381
|
+
function normalizeSensitiveKey2(value) {
|
|
16382
|
+
return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
|
|
16383
|
+
}
|
|
16384
|
+
var NON_CREDENTIAL_TOKEN_CONFIG_KEYS2 = new Set(
|
|
16385
|
+
[
|
|
16386
|
+
"tokens",
|
|
16387
|
+
"max_tokens",
|
|
16388
|
+
"min_tokens",
|
|
16389
|
+
"ls_max_tokens",
|
|
16390
|
+
"token_count",
|
|
16391
|
+
"token_limit",
|
|
16392
|
+
"token_budget",
|
|
16393
|
+
"input_tokens",
|
|
16394
|
+
"output_tokens",
|
|
16395
|
+
"total_tokens",
|
|
16396
|
+
"cached_tokens",
|
|
16397
|
+
"prompt_tokens",
|
|
16398
|
+
"completion_tokens"
|
|
16399
|
+
].map(normalizeSensitiveKey2)
|
|
16400
|
+
);
|
|
16401
|
+
function isTokenCredentialKey2(normalized) {
|
|
16402
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
|
|
16403
|
+
if (normalized === "token") return true;
|
|
16404
|
+
if (normalized.endsWith("tokens")) return false;
|
|
16405
|
+
return normalized.endsWith("token");
|
|
16406
|
+
}
|
|
16407
|
+
function isCredentialSensitiveKey2(key, sensitiveKeys) {
|
|
16408
|
+
if (!key) return false;
|
|
16409
|
+
const normalized = normalizeSensitiveKey2(key);
|
|
16410
|
+
if (!normalized) return false;
|
|
16411
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
|
|
16412
|
+
for (const sensitive of sensitiveKeys) {
|
|
16413
|
+
const s = normalizeSensitiveKey2(sensitive);
|
|
16414
|
+
if (!s) continue;
|
|
16415
|
+
if (s === "token") {
|
|
16416
|
+
if (isTokenCredentialKey2(normalized)) return true;
|
|
16417
|
+
continue;
|
|
16418
|
+
}
|
|
16419
|
+
if (normalized === s) return true;
|
|
16420
|
+
if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
|
|
16421
|
+
}
|
|
16422
|
+
return false;
|
|
16423
|
+
}
|
|
16424
|
+
|
|
16425
|
+
// packages/redact/src/index.ts
|
|
16086
16426
|
var DEFAULT_REDACT_KEYS2 = [
|
|
16087
16427
|
"authorization",
|
|
16088
16428
|
"cookie",
|
|
@@ -16144,6 +16484,12 @@ function isRecord15(value) {
|
|
|
16144
16484
|
function toKey2(key) {
|
|
16145
16485
|
return key.toLowerCase();
|
|
16146
16486
|
}
|
|
16487
|
+
function findCompiledKeyRule(key, rules) {
|
|
16488
|
+
const exact = toKey2(key);
|
|
16489
|
+
const direct = rules.find((candidate) => candidate.key === exact);
|
|
16490
|
+
if (direct) return direct;
|
|
16491
|
+
return rules.find((candidate) => isCredentialSensitiveKey2(key, [candidate.key]));
|
|
16492
|
+
}
|
|
16147
16493
|
function stableHash2(value) {
|
|
16148
16494
|
const hash = crypto__default.default.createHash("sha256").update(value, "utf8").digest("hex");
|
|
16149
16495
|
return hash.slice(0, 8);
|
|
@@ -16465,7 +16811,7 @@ var Redactor2 = class {
|
|
|
16465
16811
|
return "[Truncated]";
|
|
16466
16812
|
}
|
|
16467
16813
|
if (key !== void 0) {
|
|
16468
|
-
const rule = this.#rules
|
|
16814
|
+
const rule = findCompiledKeyRule(key, this.#rules);
|
|
16469
16815
|
if (rule) {
|
|
16470
16816
|
this.#recordFinding(
|
|
16471
16817
|
state,
|