@agent-inspect/mcp-server 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/dist/{chunk-C6EBJS57.mjs → chunk-JASWIBAT.mjs} +400 -37
- package/dist/chunk-JASWIBAT.mjs.map +1 -0
- package/dist/cli.cjs +398 -35
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.cjs +398 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
- package/dist/chunk-C6EBJS57.mjs.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -2578,6 +2578,126 @@ function diffRuns(left, right, options) {
|
|
|
2578
2578
|
return table;
|
|
2579
2579
|
})();
|
|
2580
2580
|
|
|
2581
|
+
// packages/core/src/diagnostics/programmatic.ts
|
|
2582
|
+
var PROGRAMMATIC_DIAGNOSTIC_SPECS = Object.freeze({
|
|
2583
|
+
AI_TRACE_INPUT_INVALID: {
|
|
2584
|
+
code: "AI_TRACE_INPUT_INVALID",
|
|
2585
|
+
summary: 'Expected { type: "file", path }, { type: "directory", path }, { type: "string", content }, { type: "buffer", content }, or { type: "stdin" }.',
|
|
2586
|
+
remediation: "For a file path, use openTraceFile(path).",
|
|
2587
|
+
relatedCodes: ["invalid_input"]
|
|
2588
|
+
},
|
|
2589
|
+
AI_TRACE_FORMAT_UNSUPPORTED: {
|
|
2590
|
+
code: "AI_TRACE_FORMAT_UNSUPPORTED",
|
|
2591
|
+
summary: "No trace reader could detect the input format.",
|
|
2592
|
+
remediation: "Pass an AgentInspect JSONL file via openTraceFile, or set options.format to a registered reader.",
|
|
2593
|
+
relatedCodes: ["unsupported_format"]
|
|
2594
|
+
},
|
|
2595
|
+
AI_TRACE_FORMAT_AMBIGUOUS: {
|
|
2596
|
+
code: "AI_TRACE_FORMAT_AMBIGUOUS",
|
|
2597
|
+
summary: "Multiple trace readers matched the input with equal confidence.",
|
|
2598
|
+
remediation: "Set options.format explicitly to disambiguate the reader.",
|
|
2599
|
+
relatedCodes: ["ambiguous_format"]
|
|
2600
|
+
},
|
|
2601
|
+
AI_TRACE_FACTS_INPUT_NOT_NORMALIZED: {
|
|
2602
|
+
code: "AI_TRACE_FACTS_INPUT_NOT_NORMALIZED",
|
|
2603
|
+
summary: "TraceFacts requires TraceReadResult or PersistedInspectEvent[].",
|
|
2604
|
+
remediation: "Use openTraceFile() to normalize a JSONL trace first."
|
|
2605
|
+
},
|
|
2606
|
+
AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED: {
|
|
2607
|
+
code: "AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
2608
|
+
summary: "Multiple runs are available; select a run before executing checks.",
|
|
2609
|
+
remediation: "Pass options.runId or TraceCheckInput.selectedRun.",
|
|
2610
|
+
relatedCodes: ["AI_CHECK_RUN_SELECTION_REQUIRED"]
|
|
2611
|
+
},
|
|
2612
|
+
AI_TRACE_RELATIONSHIP_SELF_PARENT: {
|
|
2613
|
+
code: "AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
2614
|
+
summary: "A parentId equals its own event/step id.",
|
|
2615
|
+
remediation: "Reject at capture (AI_LANGGRAPH_SELF_PARENT_REJECTED) or drop via logical projection; do not invent replacement parents.",
|
|
2616
|
+
relatedCodes: [
|
|
2617
|
+
"AI_LANGGRAPH_SELF_PARENT_REJECTED",
|
|
2618
|
+
"AI_LOGICAL_SELF_PARENT_REMOVED"
|
|
2619
|
+
]
|
|
2620
|
+
},
|
|
2621
|
+
AI_TRACE_RELATIONSHIP_CYCLE: {
|
|
2622
|
+
code: "AI_TRACE_RELATIONSHIP_CYCLE",
|
|
2623
|
+
summary: "Trace contains a parentId cycle.",
|
|
2624
|
+
remediation: "Use visibility-first tree linking for legacy fixtures; prefer acyclic capture for new adapter output.",
|
|
2625
|
+
relatedCodes: ["structure.cycle"]
|
|
2626
|
+
}
|
|
2627
|
+
});
|
|
2628
|
+
function formatProgrammaticDiagnostic(code, detail) {
|
|
2629
|
+
const spec = PROGRAMMATIC_DIAGNOSTIC_SPECS[code];
|
|
2630
|
+
const summary = detail?.trim() ? detail.trim() : spec.summary;
|
|
2631
|
+
return `${code}: ${summary} Remediation: ${spec.remediation}`;
|
|
2632
|
+
}
|
|
2633
|
+
|
|
2634
|
+
// packages/core/src/safety/sensitive-key.ts
|
|
2635
|
+
function normalizeSensitiveKey(value) {
|
|
2636
|
+
return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
|
|
2637
|
+
}
|
|
2638
|
+
var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
|
|
2639
|
+
[
|
|
2640
|
+
"tokens",
|
|
2641
|
+
"max_tokens",
|
|
2642
|
+
"min_tokens",
|
|
2643
|
+
"ls_max_tokens",
|
|
2644
|
+
"token_count",
|
|
2645
|
+
"token_limit",
|
|
2646
|
+
"token_budget",
|
|
2647
|
+
"input_tokens",
|
|
2648
|
+
"output_tokens",
|
|
2649
|
+
"total_tokens",
|
|
2650
|
+
"cached_tokens",
|
|
2651
|
+
"prompt_tokens",
|
|
2652
|
+
"completion_tokens"
|
|
2653
|
+
].map(normalizeSensitiveKey)
|
|
2654
|
+
);
|
|
2655
|
+
var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
|
|
2656
|
+
"authorization",
|
|
2657
|
+
"cookie",
|
|
2658
|
+
"token",
|
|
2659
|
+
"access_token",
|
|
2660
|
+
"accesstoken",
|
|
2661
|
+
"auth_token",
|
|
2662
|
+
"authtoken",
|
|
2663
|
+
"refresh_token",
|
|
2664
|
+
"refreshtoken",
|
|
2665
|
+
"id_token",
|
|
2666
|
+
"idtoken",
|
|
2667
|
+
"bearer_token",
|
|
2668
|
+
"bearertoken",
|
|
2669
|
+
"api_token",
|
|
2670
|
+
"apitoken",
|
|
2671
|
+
"apikey",
|
|
2672
|
+
"api_key",
|
|
2673
|
+
"password",
|
|
2674
|
+
"secret",
|
|
2675
|
+
"email"
|
|
2676
|
+
];
|
|
2677
|
+
function isTokenCredentialKey(normalized) {
|
|
2678
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
2679
|
+
if (normalized === "token") return true;
|
|
2680
|
+
if (normalized.endsWith("tokens")) return false;
|
|
2681
|
+
return normalized.endsWith("token");
|
|
2682
|
+
}
|
|
2683
|
+
function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
|
|
2684
|
+
if (!key) return false;
|
|
2685
|
+
const normalized = normalizeSensitiveKey(key);
|
|
2686
|
+
if (!normalized) return false;
|
|
2687
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
2688
|
+
for (const sensitive of sensitiveKeys) {
|
|
2689
|
+
const s = normalizeSensitiveKey(sensitive);
|
|
2690
|
+
if (!s) continue;
|
|
2691
|
+
if (s === "token") {
|
|
2692
|
+
if (isTokenCredentialKey(normalized)) return true;
|
|
2693
|
+
continue;
|
|
2694
|
+
}
|
|
2695
|
+
if (normalized === s) return true;
|
|
2696
|
+
if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
|
|
2697
|
+
}
|
|
2698
|
+
return false;
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2581
2701
|
// packages/core/src/checks/logical-events.ts
|
|
2582
2702
|
function isRecord6(value) {
|
|
2583
2703
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -2773,6 +2893,26 @@ function projectLogicalEvents(events) {
|
|
|
2773
2893
|
}
|
|
2774
2894
|
}
|
|
2775
2895
|
if (!remapped) {
|
|
2896
|
+
if (originalParentId === event.eventId) {
|
|
2897
|
+
diagnostics.push({
|
|
2898
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
2899
|
+
message: formatProgrammaticDiagnostic(
|
|
2900
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
2901
|
+
`Removed self-parent edge on ${event.eventId}.`
|
|
2902
|
+
),
|
|
2903
|
+
eventIds: [event.eventId]
|
|
2904
|
+
});
|
|
2905
|
+
const { parentId: _drop, ...rest } = event;
|
|
2906
|
+
normalized.push({
|
|
2907
|
+
...rest,
|
|
2908
|
+
projection: {
|
|
2909
|
+
...event.projection,
|
|
2910
|
+
parentNormalized: true,
|
|
2911
|
+
originalParentId
|
|
2912
|
+
}
|
|
2913
|
+
});
|
|
2914
|
+
continue;
|
|
2915
|
+
}
|
|
2776
2916
|
if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
|
|
2777
2917
|
const mapping = event.attributes?.parentMapping;
|
|
2778
2918
|
const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
|
|
@@ -2788,6 +2928,26 @@ function projectLogicalEvents(events) {
|
|
|
2788
2928
|
normalized.push(event);
|
|
2789
2929
|
continue;
|
|
2790
2930
|
}
|
|
2931
|
+
if (nextParent === event.eventId) {
|
|
2932
|
+
diagnostics.push({
|
|
2933
|
+
code: "AI_LOGICAL_SELF_PARENT_REMOVED",
|
|
2934
|
+
message: formatProgrammaticDiagnostic(
|
|
2935
|
+
"AI_TRACE_RELATIONSHIP_SELF_PARENT",
|
|
2936
|
+
`Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`
|
|
2937
|
+
),
|
|
2938
|
+
eventIds: [event.eventId]
|
|
2939
|
+
});
|
|
2940
|
+
const { parentId: _drop, ...rest } = event;
|
|
2941
|
+
normalized.push({
|
|
2942
|
+
...rest,
|
|
2943
|
+
projection: {
|
|
2944
|
+
...event.projection,
|
|
2945
|
+
parentNormalized: true,
|
|
2946
|
+
originalParentId
|
|
2947
|
+
}
|
|
2948
|
+
});
|
|
2949
|
+
continue;
|
|
2950
|
+
}
|
|
2791
2951
|
diagnostics.push({
|
|
2792
2952
|
code: "AI_LOGICAL_PARENT_REMAPPED",
|
|
2793
2953
|
message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
|
|
@@ -2860,7 +3020,45 @@ function summarizeSemanticParity(events) {
|
|
|
2860
3020
|
diagnostics: projection.diagnostics
|
|
2861
3021
|
};
|
|
2862
3022
|
}
|
|
2863
|
-
|
|
3023
|
+
var TRACE_FACTS_INPUT_NOT_NORMALIZED = formatProgrammaticDiagnostic(
|
|
3024
|
+
"AI_TRACE_FACTS_INPUT_NOT_NORMALIZED"
|
|
3025
|
+
);
|
|
3026
|
+
function isTraceReadResult(input) {
|
|
3027
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
3028
|
+
return false;
|
|
3029
|
+
}
|
|
3030
|
+
const record = input;
|
|
3031
|
+
return Array.isArray(record.events) && Array.isArray(record.runs) && typeof record.format === "string" && Array.isArray(record.warnings);
|
|
3032
|
+
}
|
|
3033
|
+
function looksLikeRawV01TraceEvents(input) {
|
|
3034
|
+
if (!Array.isArray(input) || input.length === 0) return false;
|
|
3035
|
+
const first = input[0];
|
|
3036
|
+
if (typeof first !== "object" || first === null) return false;
|
|
3037
|
+
const row = first;
|
|
3038
|
+
return typeof row.event === "string" && (row.schemaVersion === "0.1" || row.eventId === void 0);
|
|
3039
|
+
}
|
|
3040
|
+
function isPersistedInspectEventArray(input) {
|
|
3041
|
+
if (!Array.isArray(input)) return false;
|
|
3042
|
+
if (input.length === 0) return true;
|
|
3043
|
+
const first = input[0];
|
|
3044
|
+
if (typeof first !== "object" || first === null) return false;
|
|
3045
|
+
const row = first;
|
|
3046
|
+
return typeof row.eventId === "string" && (row.schemaVersion === "0.2" || row.schemaVersion === "1.0" || row.schemaVersion === "0.1") && typeof row.event !== "string";
|
|
3047
|
+
}
|
|
3048
|
+
function resolveTraceFactsEvents(input) {
|
|
3049
|
+
if (isTraceReadResult(input)) {
|
|
3050
|
+
return input.events;
|
|
3051
|
+
}
|
|
3052
|
+
if (looksLikeRawV01TraceEvents(input)) {
|
|
3053
|
+
throw new TypeError(TRACE_FACTS_INPUT_NOT_NORMALIZED);
|
|
3054
|
+
}
|
|
3055
|
+
if (isPersistedInspectEventArray(input)) {
|
|
3056
|
+
return input;
|
|
3057
|
+
}
|
|
3058
|
+
throw new TypeError(TRACE_FACTS_INPUT_NOT_NORMALIZED);
|
|
3059
|
+
}
|
|
3060
|
+
function buildTraceFacts(input) {
|
|
3061
|
+
const events = resolveTraceFactsEvents(input);
|
|
2864
3062
|
const projection = projectLogicalEvents(events);
|
|
2865
3063
|
const toolsByName = /* @__PURE__ */ new Map();
|
|
2866
3064
|
const llmEvents = [];
|
|
@@ -2904,16 +3102,7 @@ var STATUS_RANK = {
|
|
|
2904
3102
|
warning: 1,
|
|
2905
3103
|
pass: 2
|
|
2906
3104
|
};
|
|
2907
|
-
var DEFAULT_SENSITIVE_KEYS =
|
|
2908
|
-
"authorization",
|
|
2909
|
-
"cookie",
|
|
2910
|
-
"token",
|
|
2911
|
-
"apikey",
|
|
2912
|
-
"api_key",
|
|
2913
|
-
"password",
|
|
2914
|
-
"secret",
|
|
2915
|
-
"email"
|
|
2916
|
-
];
|
|
3105
|
+
var DEFAULT_SENSITIVE_KEYS = DEFAULT_CREDENTIAL_SENSITIVE_KEYS;
|
|
2917
3106
|
var DEFAULT_RAW_CONTENT_KEYS = [
|
|
2918
3107
|
"body",
|
|
2919
3108
|
"headers",
|
|
@@ -3071,7 +3260,13 @@ function resolveSelectedRun(input, runId) {
|
|
|
3071
3260
|
if (input.read.runs.length === 0) {
|
|
3072
3261
|
return {
|
|
3073
3262
|
diagnostics: [
|
|
3074
|
-
diagnostic(
|
|
3263
|
+
diagnostic(
|
|
3264
|
+
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
3265
|
+
formatProgrammaticDiagnostic(
|
|
3266
|
+
"AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
3267
|
+
"No runs are available for checks."
|
|
3268
|
+
)
|
|
3269
|
+
)
|
|
3075
3270
|
]
|
|
3076
3271
|
};
|
|
3077
3272
|
}
|
|
@@ -3079,7 +3274,7 @@ function resolveSelectedRun(input, runId) {
|
|
|
3079
3274
|
diagnostics: [
|
|
3080
3275
|
diagnostic(
|
|
3081
3276
|
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
3082
|
-
"
|
|
3277
|
+
formatProgrammaticDiagnostic("AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED")
|
|
3083
3278
|
)
|
|
3084
3279
|
]
|
|
3085
3280
|
};
|
|
@@ -3268,9 +3463,7 @@ function hasRedactionMarker(value, markers) {
|
|
|
3268
3463
|
return markers.some((marker) => value.includes(marker)) || /^\[HASH:[A-Za-z0-9_-]+\]$/.test(value);
|
|
3269
3464
|
}
|
|
3270
3465
|
function isSensitiveKey(key, sensitiveKeys) {
|
|
3271
|
-
|
|
3272
|
-
const normalized = normalizedKey(key);
|
|
3273
|
-
return sensitiveKeys.some((sensitive) => normalized.includes(normalizedKey(sensitive)));
|
|
3466
|
+
return isCredentialSensitiveKey(key, sensitiveKeys);
|
|
3274
3467
|
}
|
|
3275
3468
|
function isRawContentKey(key, forbiddenKeys) {
|
|
3276
3469
|
if (!key) return false;
|
|
@@ -3840,6 +4033,20 @@ function traceEventsToPersistedInspectEvents(events, options) {
|
|
|
3840
4033
|
function inc(map, key) {
|
|
3841
4034
|
map[key] = (map[key] ?? 0) + 1;
|
|
3842
4035
|
}
|
|
4036
|
+
function confidenceRank(confidence) {
|
|
4037
|
+
switch (confidence) {
|
|
4038
|
+
case "unknown":
|
|
4039
|
+
return 0;
|
|
4040
|
+
case "heuristic":
|
|
4041
|
+
return 1;
|
|
4042
|
+
case "correlated":
|
|
4043
|
+
return 2;
|
|
4044
|
+
case "explicit":
|
|
4045
|
+
return 3;
|
|
4046
|
+
default:
|
|
4047
|
+
return 0;
|
|
4048
|
+
}
|
|
4049
|
+
}
|
|
3843
4050
|
function computeRunStatus(events) {
|
|
3844
4051
|
let runTerminal;
|
|
3845
4052
|
let sawRunEvent = false;
|
|
@@ -3860,6 +4067,84 @@ function computeRunStatus(events) {
|
|
|
3860
4067
|
}
|
|
3861
4068
|
return hasRunning ? "running" : "ok";
|
|
3862
4069
|
}
|
|
4070
|
+
function linkNodesVisibilityFirst(nodes) {
|
|
4071
|
+
let selfParentCount = 0;
|
|
4072
|
+
let unresolvedParentCount = 0;
|
|
4073
|
+
let normalizedEdgeCount = 0;
|
|
4074
|
+
let cycleCount = 0;
|
|
4075
|
+
const pending = [];
|
|
4076
|
+
for (const node of nodes.values()) {
|
|
4077
|
+
const parentId = node.event.parentId;
|
|
4078
|
+
if (!parentId) continue;
|
|
4079
|
+
if (parentId === node.event.eventId) {
|
|
4080
|
+
selfParentCount += 1;
|
|
4081
|
+
normalizedEdgeCount += 1;
|
|
4082
|
+
continue;
|
|
4083
|
+
}
|
|
4084
|
+
if (!nodes.has(parentId)) {
|
|
4085
|
+
unresolvedParentCount += 1;
|
|
4086
|
+
continue;
|
|
4087
|
+
}
|
|
4088
|
+
pending.push({
|
|
4089
|
+
childId: node.event.eventId,
|
|
4090
|
+
parentId,
|
|
4091
|
+
childTimestamp: node.event.timestamp,
|
|
4092
|
+
childConfidence: node.event.confidence
|
|
4093
|
+
});
|
|
4094
|
+
}
|
|
4095
|
+
pending.sort((a, b) => {
|
|
4096
|
+
const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
|
|
4097
|
+
if (conf !== 0) return conf;
|
|
4098
|
+
return a.childTimestamp - b.childTimestamp;
|
|
4099
|
+
});
|
|
4100
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
4101
|
+
for (const edge of pending) {
|
|
4102
|
+
parentOf.set(edge.childId, edge.parentId);
|
|
4103
|
+
let cursor = edge.parentId;
|
|
4104
|
+
const seen = /* @__PURE__ */ new Set([edge.childId]);
|
|
4105
|
+
let cyclic = false;
|
|
4106
|
+
while (cursor) {
|
|
4107
|
+
if (seen.has(cursor)) {
|
|
4108
|
+
cyclic = true;
|
|
4109
|
+
break;
|
|
4110
|
+
}
|
|
4111
|
+
seen.add(cursor);
|
|
4112
|
+
cursor = parentOf.get(cursor);
|
|
4113
|
+
}
|
|
4114
|
+
if (cyclic) {
|
|
4115
|
+
parentOf.delete(edge.childId);
|
|
4116
|
+
cycleCount += 1;
|
|
4117
|
+
normalizedEdgeCount += 1;
|
|
4118
|
+
}
|
|
4119
|
+
}
|
|
4120
|
+
for (const [childId, parentId] of parentOf) {
|
|
4121
|
+
nodes.get(parentId).children.push(nodes.get(childId));
|
|
4122
|
+
}
|
|
4123
|
+
const roots = [];
|
|
4124
|
+
for (const node of nodes.values()) {
|
|
4125
|
+
if (!parentOf.has(node.event.eventId)) {
|
|
4126
|
+
roots.push(node);
|
|
4127
|
+
}
|
|
4128
|
+
}
|
|
4129
|
+
const assignDepth = (n, depth, stack) => {
|
|
4130
|
+
if (stack.has(n.event.eventId)) return;
|
|
4131
|
+
n.depth = depth;
|
|
4132
|
+
stack.add(n.event.eventId);
|
|
4133
|
+
for (const c of n.children) assignDepth(c, depth + 1, stack);
|
|
4134
|
+
stack.delete(n.event.eventId);
|
|
4135
|
+
};
|
|
4136
|
+
for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
|
|
4137
|
+
return {
|
|
4138
|
+
roots,
|
|
4139
|
+
summary: {
|
|
4140
|
+
rootCount: roots.length,
|
|
4141
|
+
selfParentCount,
|
|
4142
|
+
cycleCount,
|
|
4143
|
+
unresolvedParentCount,
|
|
4144
|
+
normalizedEdgeCount
|
|
4145
|
+
}
|
|
4146
|
+
};
|
|
4147
|
+
}
|
|
3863
4148
|
var TreeBuilder = class {
|
|
3864
4149
|
constructor(options) {
|
|
3865
4150
|
void options?.config;
|
|
@@ -3877,20 +4162,7 @@ var TreeBuilder = class {
|
|
|
3877
4162
|
for (const e of sorted) {
|
|
3878
4163
|
nodes.set(e.eventId, { event: e, children: [], depth: 0 });
|
|
3879
4164
|
}
|
|
3880
|
-
const roots =
|
|
3881
|
-
for (const node of nodes.values()) {
|
|
3882
|
-
const parentId = node.event.parentId;
|
|
3883
|
-
if (parentId && nodes.has(parentId)) {
|
|
3884
|
-
nodes.get(parentId).children.push(node);
|
|
3885
|
-
} else {
|
|
3886
|
-
roots.push(node);
|
|
3887
|
-
}
|
|
3888
|
-
}
|
|
3889
|
-
const assignDepth = (n, depth) => {
|
|
3890
|
-
n.depth = depth;
|
|
3891
|
-
for (const c of n.children) assignDepth(c, depth + 1);
|
|
3892
|
-
};
|
|
3893
|
-
for (const r of roots) assignDepth(r, 0);
|
|
4165
|
+
const { roots, summary } = linkNodesVisibilityFirst(nodes);
|
|
3894
4166
|
const confidenceBreakdown = {
|
|
3895
4167
|
explicit: 0,
|
|
3896
4168
|
correlated: 0,
|
|
@@ -3918,7 +4190,8 @@ var TreeBuilder = class {
|
|
|
3918
4190
|
metadata: {
|
|
3919
4191
|
totalEvents: sorted.length,
|
|
3920
4192
|
confidenceBreakdown,
|
|
3921
|
-
kinds
|
|
4193
|
+
kinds,
|
|
4194
|
+
relationshipSummary: summary
|
|
3922
4195
|
}
|
|
3923
4196
|
});
|
|
3924
4197
|
}
|
|
@@ -4147,6 +4420,38 @@ var TraceReadError = class extends Error {
|
|
|
4147
4420
|
this.warnings = warnings;
|
|
4148
4421
|
}
|
|
4149
4422
|
};
|
|
4423
|
+
var TRACE_INPUT_INVALID_MESSAGE = formatProgrammaticDiagnostic(
|
|
4424
|
+
"AI_TRACE_INPUT_INVALID"
|
|
4425
|
+
);
|
|
4426
|
+
function isTraceInput(input) {
|
|
4427
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) {
|
|
4428
|
+
return false;
|
|
4429
|
+
}
|
|
4430
|
+
const record = input;
|
|
4431
|
+
switch (record.type) {
|
|
4432
|
+
case "file":
|
|
4433
|
+
case "directory":
|
|
4434
|
+
return typeof record.path === "string";
|
|
4435
|
+
case "string":
|
|
4436
|
+
return typeof record.content === "string";
|
|
4437
|
+
case "buffer":
|
|
4438
|
+
return Buffer.isBuffer(record.content);
|
|
4439
|
+
case "stdin":
|
|
4440
|
+
return true;
|
|
4441
|
+
default:
|
|
4442
|
+
return false;
|
|
4443
|
+
}
|
|
4444
|
+
}
|
|
4445
|
+
function assertTraceInput(input) {
|
|
4446
|
+
if (isTraceInput(input)) return;
|
|
4447
|
+
throw new TraceReadError("invalid_input", TRACE_INPUT_INVALID_MESSAGE, [
|
|
4448
|
+
{
|
|
4449
|
+
code: "AI_TRACE_INPUT_INVALID",
|
|
4450
|
+
message: TRACE_INPUT_INVALID_MESSAGE,
|
|
4451
|
+
severity: "error"
|
|
4452
|
+
}
|
|
4453
|
+
]);
|
|
4454
|
+
}
|
|
4150
4455
|
function normalizeCandidate(reader, candidate) {
|
|
4151
4456
|
const confidence = Number.isFinite(candidate.confidence) ? Math.max(0, Math.min(1, candidate.confidence)) : 0;
|
|
4152
4457
|
return {
|
|
@@ -5501,6 +5806,7 @@ var DEFAULT_TRACE_READERS = [
|
|
|
5501
5806
|
otlpJsonReader
|
|
5502
5807
|
];
|
|
5503
5808
|
async function detectTraceFormat(input, options = {}) {
|
|
5809
|
+
assertTraceInput(input);
|
|
5504
5810
|
const readers = options.readers ?? DEFAULT_TRACE_READERS;
|
|
5505
5811
|
if (options.format !== void 0) {
|
|
5506
5812
|
const reader = findReaderByFormat(options.format, readers);
|
|
@@ -5597,19 +5903,20 @@ async function detectTraceFormat(input, options = {}) {
|
|
|
5597
5903
|
};
|
|
5598
5904
|
}
|
|
5599
5905
|
async function readTrace(input, options = {}) {
|
|
5906
|
+
assertTraceInput(input);
|
|
5600
5907
|
const readers = options.readers ?? DEFAULT_TRACE_READERS;
|
|
5601
5908
|
const detection = await detectTraceFormat(input, options);
|
|
5602
5909
|
if (detection.status === "unsupported" || detection.format === void 0) {
|
|
5603
5910
|
throw new TraceReadError(
|
|
5604
5911
|
"unsupported_format",
|
|
5605
|
-
"
|
|
5912
|
+
formatProgrammaticDiagnostic("AI_TRACE_FORMAT_UNSUPPORTED"),
|
|
5606
5913
|
detection.warnings
|
|
5607
5914
|
);
|
|
5608
5915
|
}
|
|
5609
5916
|
if (detection.status === "ambiguous") {
|
|
5610
5917
|
throw new TraceReadError(
|
|
5611
5918
|
"ambiguous_format",
|
|
5612
|
-
"
|
|
5919
|
+
formatProgrammaticDiagnostic("AI_TRACE_FORMAT_AMBIGUOUS"),
|
|
5613
5920
|
detection.warnings
|
|
5614
5921
|
);
|
|
5615
5922
|
}
|
|
@@ -5617,7 +5924,10 @@ async function readTrace(input, options = {}) {
|
|
|
5617
5924
|
if (!reader) {
|
|
5618
5925
|
throw new TraceReadError(
|
|
5619
5926
|
"unsupported_format",
|
|
5620
|
-
|
|
5927
|
+
formatProgrammaticDiagnostic(
|
|
5928
|
+
"AI_TRACE_FORMAT_UNSUPPORTED",
|
|
5929
|
+
`No trace reader is registered for format "${detection.format}".`
|
|
5930
|
+
),
|
|
5621
5931
|
detection.warnings
|
|
5622
5932
|
);
|
|
5623
5933
|
}
|
|
@@ -6332,6 +6642,53 @@ function exportRunTree(tree, options) {
|
|
|
6332
6642
|
}
|
|
6333
6643
|
}
|
|
6334
6644
|
}
|
|
6645
|
+
|
|
6646
|
+
// packages/redact/src/sensitive-key.ts
|
|
6647
|
+
function normalizeSensitiveKey2(value) {
|
|
6648
|
+
return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
|
|
6649
|
+
}
|
|
6650
|
+
var NON_CREDENTIAL_TOKEN_CONFIG_KEYS2 = new Set(
|
|
6651
|
+
[
|
|
6652
|
+
"tokens",
|
|
6653
|
+
"max_tokens",
|
|
6654
|
+
"min_tokens",
|
|
6655
|
+
"ls_max_tokens",
|
|
6656
|
+
"token_count",
|
|
6657
|
+
"token_limit",
|
|
6658
|
+
"token_budget",
|
|
6659
|
+
"input_tokens",
|
|
6660
|
+
"output_tokens",
|
|
6661
|
+
"total_tokens",
|
|
6662
|
+
"cached_tokens",
|
|
6663
|
+
"prompt_tokens",
|
|
6664
|
+
"completion_tokens"
|
|
6665
|
+
].map(normalizeSensitiveKey2)
|
|
6666
|
+
);
|
|
6667
|
+
function isTokenCredentialKey2(normalized) {
|
|
6668
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
|
|
6669
|
+
if (normalized === "token") return true;
|
|
6670
|
+
if (normalized.endsWith("tokens")) return false;
|
|
6671
|
+
return normalized.endsWith("token");
|
|
6672
|
+
}
|
|
6673
|
+
function isCredentialSensitiveKey2(key, sensitiveKeys) {
|
|
6674
|
+
if (!key) return false;
|
|
6675
|
+
const normalized = normalizeSensitiveKey2(key);
|
|
6676
|
+
if (!normalized) return false;
|
|
6677
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS2.has(normalized)) return false;
|
|
6678
|
+
for (const sensitive of sensitiveKeys) {
|
|
6679
|
+
const s = normalizeSensitiveKey2(sensitive);
|
|
6680
|
+
if (!s) continue;
|
|
6681
|
+
if (s === "token") {
|
|
6682
|
+
if (isTokenCredentialKey2(normalized)) return true;
|
|
6683
|
+
continue;
|
|
6684
|
+
}
|
|
6685
|
+
if (normalized === s) return true;
|
|
6686
|
+
if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
|
|
6687
|
+
}
|
|
6688
|
+
return false;
|
|
6689
|
+
}
|
|
6690
|
+
|
|
6691
|
+
// packages/redact/src/index.ts
|
|
6335
6692
|
var DEFAULT_REDACT_KEYS2 = [
|
|
6336
6693
|
"authorization",
|
|
6337
6694
|
"cookie",
|
|
@@ -6393,6 +6750,12 @@ function isRecord11(value) {
|
|
|
6393
6750
|
function toKey2(key) {
|
|
6394
6751
|
return key.toLowerCase();
|
|
6395
6752
|
}
|
|
6753
|
+
function findCompiledKeyRule(key, rules) {
|
|
6754
|
+
const exact = toKey2(key);
|
|
6755
|
+
const direct = rules.find((candidate) => candidate.key === exact);
|
|
6756
|
+
if (direct) return direct;
|
|
6757
|
+
return rules.find((candidate) => isCredentialSensitiveKey2(key, [candidate.key]));
|
|
6758
|
+
}
|
|
6396
6759
|
function stableHash2(value) {
|
|
6397
6760
|
const hash = crypto__default.default.createHash("sha256").update(value, "utf8").digest("hex");
|
|
6398
6761
|
return hash.slice(0, 8);
|
|
@@ -6714,7 +7077,7 @@ var Redactor2 = class {
|
|
|
6714
7077
|
return "[Truncated]";
|
|
6715
7078
|
}
|
|
6716
7079
|
if (key !== void 0) {
|
|
6717
|
-
const rule = this.#rules
|
|
7080
|
+
const rule = findCompiledKeyRule(key, this.#rules);
|
|
6718
7081
|
if (rule) {
|
|
6719
7082
|
this.#recordFinding(
|
|
6720
7083
|
state,
|