agent-inspect 6.31.3 → 6.31.4
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 +8 -0
- package/README.md +1 -1
- package/SECURITY.md +2 -0
- package/docs/GETTING-STARTED.md +2 -0
- package/docs/SAFE-TRACE-SHARING.md +1 -0
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-SJ6FRNOE.mjs → chunk-LKEPABND.mjs} +86 -80
- package/packages/cli/dist/chunk-LKEPABND.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +399 -91
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +307 -14
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-YNEJOPRA.mjs → src-4WYF5RFI.mjs} +3 -3
- package/packages/cli/dist/{src-YNEJOPRA.mjs.map → src-4WYF5RFI.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +97 -30
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +13 -13
- package/packages/core/dist/checks.cjs +51 -49
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +5 -5
- package/packages/core/dist/{chunk-PBNBQRXV.mjs → chunk-2KJR6X4V.mjs} +9 -9
- package/packages/core/dist/chunk-2KJR6X4V.mjs.map +1 -0
- package/packages/core/dist/{chunk-26YJSETN.mjs → chunk-7DHSWDKB.mjs} +19 -6
- package/packages/core/dist/chunk-7DHSWDKB.mjs.map +1 -0
- package/packages/core/dist/{chunk-BGF5JDJN.mjs → chunk-INE5IWLN.mjs} +3 -3
- package/packages/core/dist/{chunk-BGF5JDJN.mjs.map → chunk-INE5IWLN.mjs.map} +1 -1
- package/packages/core/dist/{chunk-ZFJ2ICTC.mjs → chunk-MTMTXTJL.mjs} +5 -5
- package/packages/core/dist/{chunk-ZFJ2ICTC.mjs.map → chunk-MTMTXTJL.mjs.map} +1 -1
- package/packages/core/dist/{chunk-KWBO36PH.mjs → chunk-NY4ILMXK.mjs} +4 -4
- package/packages/core/dist/{chunk-KWBO36PH.mjs.map → chunk-NY4ILMXK.mjs.map} +1 -1
- package/packages/core/dist/{chunk-WN5PT4GV.mjs → chunk-OSGNGRHF.mjs} +3 -3
- package/packages/core/dist/{chunk-WN5PT4GV.mjs.map → chunk-OSGNGRHF.mjs.map} +1 -1
- package/packages/core/dist/{chunk-CBPWLHNQ.mjs → chunk-PKDBFBJ7.mjs} +5 -76
- package/packages/core/dist/chunk-PKDBFBJ7.mjs.map +1 -0
- package/packages/core/dist/{chunk-VU6O5QAH.mjs → chunk-VLVCLAPB.mjs} +83 -5
- package/packages/core/dist/chunk-VLVCLAPB.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +217 -6
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +118 -9
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/index.cjs +97 -8
- package/packages/core/dist/index.cjs.map +1 -1
- package/packages/core/dist/index.mjs +6 -6
- package/packages/core/dist/logs.cjs +80 -2
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.d.cts +2 -0
- package/packages/core/dist/logs.d.ts +2 -0
- package/packages/core/dist/logs.mjs +2 -2
- package/packages/core/dist/readers.cjs +2 -0
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +2 -2
- package/packages/core/dist/writers.cjs +96 -8
- package/packages/core/dist/writers.cjs.map +1 -1
- package/packages/core/dist/writers.mjs +7 -8
- package/packages/core/dist/writers.mjs.map +1 -1
- package/packages/cli/dist/chunk-SJ6FRNOE.mjs.map +0 -1
- package/packages/core/dist/chunk-26YJSETN.mjs.map +0 -1
- package/packages/core/dist/chunk-CBPWLHNQ.mjs.map +0 -1
- package/packages/core/dist/chunk-PBNBQRXV.mjs.map +0 -1
- package/packages/core/dist/chunk-VU6O5QAH.mjs.map +0 -1
|
@@ -62,6 +62,80 @@ function buildRunStartedMetadata(options) {
|
|
|
62
62
|
}
|
|
63
63
|
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
64
64
|
}
|
|
65
|
+
|
|
66
|
+
// packages/core/src/safety/sensitive-key.ts
|
|
67
|
+
function keyHasExplicitSeparator(value) {
|
|
68
|
+
return /[_\-.]/.test(value);
|
|
69
|
+
}
|
|
70
|
+
function normalizeSensitiveKey(value) {
|
|
71
|
+
return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
72
|
+
}
|
|
73
|
+
var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
|
|
74
|
+
[
|
|
75
|
+
"tokens",
|
|
76
|
+
"max_tokens",
|
|
77
|
+
"min_tokens",
|
|
78
|
+
"ls_max_tokens",
|
|
79
|
+
"token_count",
|
|
80
|
+
"token_limit",
|
|
81
|
+
"token_budget",
|
|
82
|
+
"input_tokens",
|
|
83
|
+
"output_tokens",
|
|
84
|
+
"total_tokens",
|
|
85
|
+
"cached_tokens",
|
|
86
|
+
"prompt_tokens",
|
|
87
|
+
"completion_tokens"
|
|
88
|
+
].map(normalizeSensitiveKey)
|
|
89
|
+
);
|
|
90
|
+
var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
|
|
91
|
+
"authorization",
|
|
92
|
+
"cookie",
|
|
93
|
+
"token",
|
|
94
|
+
"access_token",
|
|
95
|
+
"accesstoken",
|
|
96
|
+
"auth_token",
|
|
97
|
+
"authtoken",
|
|
98
|
+
"refresh_token",
|
|
99
|
+
"refreshtoken",
|
|
100
|
+
"id_token",
|
|
101
|
+
"idtoken",
|
|
102
|
+
"bearer_token",
|
|
103
|
+
"bearertoken",
|
|
104
|
+
"api_token",
|
|
105
|
+
"apitoken",
|
|
106
|
+
"apikey",
|
|
107
|
+
"api_key",
|
|
108
|
+
"password",
|
|
109
|
+
"secret",
|
|
110
|
+
"email"
|
|
111
|
+
];
|
|
112
|
+
function isTokenCredentialKey(normalized) {
|
|
113
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
114
|
+
if (normalized === "token") return true;
|
|
115
|
+
if (normalized.endsWith("tokens")) return false;
|
|
116
|
+
return normalized.endsWith("token");
|
|
117
|
+
}
|
|
118
|
+
function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
|
|
119
|
+
if (!key) return false;
|
|
120
|
+
const normalized = normalizeSensitiveKey(key);
|
|
121
|
+
if (!normalized) return false;
|
|
122
|
+
if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
|
|
123
|
+
const allowPrefixCompound = keyHasExplicitSeparator(key);
|
|
124
|
+
for (const sensitive of sensitiveKeys) {
|
|
125
|
+
const s = normalizeSensitiveKey(sensitive);
|
|
126
|
+
if (!s) continue;
|
|
127
|
+
if (s === "token") {
|
|
128
|
+
if (isTokenCredentialKey(normalized)) return true;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (normalized === s) return true;
|
|
132
|
+
if (normalized.endsWith(`_${s}`)) return true;
|
|
133
|
+
if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// packages/core/src/logs/redactor.ts
|
|
65
139
|
var DEFAULT_REDACT_KEYS = [
|
|
66
140
|
"authorization",
|
|
67
141
|
"cookie",
|
|
@@ -85,7 +159,7 @@ function compileRules(rules, extraKeys) {
|
|
|
85
159
|
const out = /* @__PURE__ */ new Map();
|
|
86
160
|
const set = (r) => {
|
|
87
161
|
const k = toKey(r.key);
|
|
88
|
-
out.set(k, { ...r, key: k });
|
|
162
|
+
out.set(k, { ...r, key: k, raw: r.raw ?? r.key });
|
|
89
163
|
};
|
|
90
164
|
for (const k of DEFAULT_REDACT_KEYS) {
|
|
91
165
|
set({ key: k, strategy: "full" });
|
|
@@ -114,9 +188,13 @@ var Redactor = class {
|
|
|
114
188
|
constructor(options) {
|
|
115
189
|
this.#rules = compileRules(options?.rules, options?.extraKeys);
|
|
116
190
|
}
|
|
191
|
+
/** Field names this redactor treats as sensitive, for value-level helpers. */
|
|
192
|
+
get sensitiveKeys() {
|
|
193
|
+
return this.#rules.map((rule) => rule.raw ?? rule.key);
|
|
194
|
+
}
|
|
117
195
|
redactValue(key, value) {
|
|
118
196
|
const k = toKey(key);
|
|
119
|
-
const rule = this.#rules.find((r) => r.key === k);
|
|
197
|
+
const rule = this.#rules.find((r) => r.key === k) ?? this.#rules.find((r) => isCredentialSensitiveKey(key, [r.raw ?? r.key]));
|
|
120
198
|
if (!rule) {
|
|
121
199
|
return this.#redactNested(value);
|
|
122
200
|
}
|
|
@@ -156,7 +234,7 @@ var Redactor = class {
|
|
|
156
234
|
};
|
|
157
235
|
|
|
158
236
|
// packages/core/src/safety/credential-value-patterns.ts
|
|
159
|
-
var KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=([^\s"'\\]{8,})/i;
|
|
237
|
+
var KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=(?!\[(?:REDACTED(?::[^\]]*)?|HASH:[0-9a-f]{8})\](?![^\s"'\\&#?;/]))([^\s"'\\]{8,})/i;
|
|
160
238
|
var HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
|
|
161
239
|
/^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
|
|
162
240
|
/\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
|
|
@@ -435,6 +513,17 @@ function nanoid(size = 21) {
|
|
|
435
513
|
}
|
|
436
514
|
return id;
|
|
437
515
|
}
|
|
516
|
+
var TRACE_DIR_MODE = 448;
|
|
517
|
+
var TRACE_FILE_MODE = 384;
|
|
518
|
+
async function mkdirTraceDir(dirPath) {
|
|
519
|
+
await promises.mkdir(dirPath, { recursive: true, mode: TRACE_DIR_MODE });
|
|
520
|
+
}
|
|
521
|
+
async function createEmptyTraceFile(filePath) {
|
|
522
|
+
await promises.writeFile(filePath, "", { encoding: "utf-8", mode: TRACE_FILE_MODE });
|
|
523
|
+
}
|
|
524
|
+
async function appendTraceFile(filePath, data) {
|
|
525
|
+
await promises.appendFile(filePath, data, { encoding: "utf-8", mode: TRACE_FILE_MODE });
|
|
526
|
+
}
|
|
438
527
|
|
|
439
528
|
// packages/core/src/utils/duration.ts
|
|
440
529
|
function formatDuration(ms) {
|
|
@@ -501,13 +590,13 @@ function getTraceFilePath(runId, traceDir) {
|
|
|
501
590
|
async function ensureTraceDir(traceDir) {
|
|
502
591
|
const primary = path__default.default.resolve(traceDir);
|
|
503
592
|
try {
|
|
504
|
-
await
|
|
593
|
+
await mkdirTraceDir(primary);
|
|
505
594
|
return primary;
|
|
506
595
|
} catch {
|
|
507
596
|
warn(`Failed to create trace directory: ${primary}`);
|
|
508
597
|
const fallback = path__default.default.resolve(FALLBACK_TRACE_DIR);
|
|
509
598
|
try {
|
|
510
|
-
await
|
|
599
|
+
await mkdirTraceDir(fallback);
|
|
511
600
|
return fallback;
|
|
512
601
|
} catch {
|
|
513
602
|
warn(`Failed to create fallback trace directory: ${fallback}`);
|
|
@@ -635,7 +724,7 @@ async function initializeTraceFile(runId, traceDir) {
|
|
|
635
724
|
try {
|
|
636
725
|
const usable = await ensureTraceDir(traceDir);
|
|
637
726
|
const filePath = getTraceFilePath(runId, usable);
|
|
638
|
-
await
|
|
727
|
+
await createEmptyTraceFile(filePath);
|
|
639
728
|
return filePath;
|
|
640
729
|
} catch (e) {
|
|
641
730
|
warn("Failed to initialize trace file", e);
|
|
@@ -643,7 +732,7 @@ async function initializeTraceFile(runId, traceDir) {
|
|
|
643
732
|
try {
|
|
644
733
|
const usable = await ensureTraceDir(FALLBACK_TRACE_DIR);
|
|
645
734
|
const filePath = getTraceFilePath(runId, usable);
|
|
646
|
-
await
|
|
735
|
+
await createEmptyTraceFile(filePath);
|
|
647
736
|
return filePath;
|
|
648
737
|
} catch (e) {
|
|
649
738
|
warn("Failed to initialize trace file on fallback directory", e);
|
|
@@ -674,7 +763,7 @@ async function writeTraceEvent(event, traceDir) {
|
|
|
674
763
|
try {
|
|
675
764
|
const usable = await ensureTraceDir(dir);
|
|
676
765
|
const filePath = getTraceFilePath(event.runId, usable);
|
|
677
|
-
await
|
|
766
|
+
await appendTraceFile(filePath, payload);
|
|
678
767
|
return true;
|
|
679
768
|
} catch {
|
|
680
769
|
return false;
|