@vercel/agent-eval 2.4.1 → 2.5.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/cli.js +27 -21
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/agents/claude-code/agent.d.ts.map +1 -1
- package/dist/lib/agents/claude-code/agent.js +5 -1
- package/dist/lib/agents/claude-code/agent.js.map +1 -1
- package/dist/lib/agents/codex/agent.d.ts.map +1 -1
- package/dist/lib/agents/codex/agent.js +5 -1
- package/dist/lib/agents/codex/agent.js.map +1 -1
- package/dist/lib/agents/cursor/agent.d.ts.map +1 -1
- package/dist/lib/agents/cursor/agent.js +5 -0
- package/dist/lib/agents/cursor/agent.js.map +1 -1
- package/dist/lib/agents/fx/agent.d.ts.map +1 -1
- package/dist/lib/agents/fx/agent.js +3 -0
- package/dist/lib/agents/fx/agent.js.map +1 -1
- package/dist/lib/agents/fx/run.mjs +26 -0
- package/dist/lib/agents/gemini/agent.d.ts.map +1 -1
- package/dist/lib/agents/gemini/agent.js +5 -1
- package/dist/lib/agents/gemini/agent.js.map +1 -1
- package/dist/lib/agents/index.d.ts +1 -0
- package/dist/lib/agents/index.d.ts.map +1 -1
- package/dist/lib/agents/index.js +2 -0
- package/dist/lib/agents/index.js.map +1 -1
- package/dist/lib/agents/opencode/agent.d.ts.map +1 -1
- package/dist/lib/agents/opencode/agent.js +6 -0
- package/dist/lib/agents/opencode/agent.js.map +1 -1
- package/dist/lib/agents/plugin/contract.d.ts +40 -0
- package/dist/lib/agents/plugin/contract.d.ts.map +1 -1
- package/dist/lib/agents/plugin/contract.js.map +1 -1
- package/dist/lib/agents/plugin/orchestrator.d.ts +19 -0
- package/dist/lib/agents/plugin/orchestrator.d.ts.map +1 -1
- package/dist/lib/agents/plugin/orchestrator.js +265 -52
- package/dist/lib/agents/plugin/orchestrator.js.map +1 -1
- package/dist/lib/agents/redact.d.ts +34 -3
- package/dist/lib/agents/redact.d.ts.map +1 -1
- package/dist/lib/agents/redact.js +148 -35
- package/dist/lib/agents/redact.js.map +1 -1
- package/dist/lib/agents/shared.d.ts +24 -1
- package/dist/lib/agents/shared.d.ts.map +1 -1
- package/dist/lib/agents/shared.js +48 -13
- package/dist/lib/agents/shared.js.map +1 -1
- package/dist/lib/agents/types.d.ts +24 -1
- package/dist/lib/agents/types.d.ts.map +1 -1
- package/dist/lib/agents/verifier.d.ts +96 -0
- package/dist/lib/agents/verifier.d.ts.map +1 -0
- package/dist/lib/agents/verifier.js +176 -0
- package/dist/lib/agents/verifier.js.map +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +23 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/dashboard.d.ts +3 -1
- package/dist/lib/dashboard.d.ts.map +1 -1
- package/dist/lib/dashboard.js +12 -1
- package/dist/lib/dashboard.js.map +1 -1
- package/dist/lib/docker-sandbox.d.ts +9 -0
- package/dist/lib/docker-sandbox.d.ts.map +1 -1
- package/dist/lib/docker-sandbox.js +15 -0
- package/dist/lib/docker-sandbox.js.map +1 -1
- package/dist/lib/fingerprint.d.ts +3 -0
- package/dist/lib/fingerprint.d.ts.map +1 -1
- package/dist/lib/fingerprint.js +34 -0
- package/dist/lib/fingerprint.js.map +1 -1
- package/dist/lib/o11y/index.d.ts +2 -2
- package/dist/lib/o11y/index.d.ts.map +1 -1
- package/dist/lib/o11y/index.js +1 -1
- package/dist/lib/o11y/index.js.map +1 -1
- package/dist/lib/o11y/parsers/claude-code.d.ts +19 -1
- package/dist/lib/o11y/parsers/claude-code.d.ts.map +1 -1
- package/dist/lib/o11y/parsers/claude-code.js +72 -1
- package/dist/lib/o11y/parsers/claude-code.js.map +1 -1
- package/dist/lib/o11y/parsers/codex.d.ts +13 -1
- package/dist/lib/o11y/parsers/codex.d.ts.map +1 -1
- package/dist/lib/o11y/parsers/codex.js +68 -1
- package/dist/lib/o11y/parsers/codex.js.map +1 -1
- package/dist/lib/o11y/parsers/fx.d.ts +2 -1
- package/dist/lib/o11y/parsers/fx.d.ts.map +1 -1
- package/dist/lib/o11y/parsers/fx.js +21 -1
- package/dist/lib/o11y/parsers/fx.js.map +1 -1
- package/dist/lib/o11y/parsers/gemini.d.ts +13 -1
- package/dist/lib/o11y/parsers/gemini.d.ts.map +1 -1
- package/dist/lib/o11y/parsers/gemini.js +35 -1
- package/dist/lib/o11y/parsers/gemini.js.map +1 -1
- package/dist/lib/o11y/parsers/index.d.ts +6 -1
- package/dist/lib/o11y/parsers/index.d.ts.map +1 -1
- package/dist/lib/o11y/parsers/index.js +13 -1
- package/dist/lib/o11y/parsers/index.js.map +1 -1
- package/dist/lib/o11y/parsers/opencode.d.ts +17 -1
- package/dist/lib/o11y/parsers/opencode.d.ts.map +1 -1
- package/dist/lib/o11y/parsers/opencode.js +47 -4
- package/dist/lib/o11y/parsers/opencode.js.map +1 -1
- package/dist/lib/o11y/types.d.ts +30 -0
- package/dist/lib/o11y/types.d.ts.map +1 -1
- package/dist/lib/o11y/usage.d.ts +27 -0
- package/dist/lib/o11y/usage.d.ts.map +1 -0
- package/dist/lib/o11y/usage.js +75 -0
- package/dist/lib/o11y/usage.js.map +1 -0
- package/dist/lib/reporters.d.ts +101 -0
- package/dist/lib/reporters.d.ts.map +1 -0
- package/dist/lib/reporters.js +176 -0
- package/dist/lib/reporters.js.map +1 -0
- package/dist/lib/results.d.ts +15 -2
- package/dist/lib/results.d.ts.map +1 -1
- package/dist/lib/results.js +75 -4
- package/dist/lib/results.js.map +1 -1
- package/dist/lib/runner.d.ts +16 -1
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/runner.js +85 -3
- package/dist/lib/runner.js.map +1 -1
- package/dist/lib/sandbox.d.ts +9 -0
- package/dist/lib/sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox.js +14 -1
- package/dist/lib/sandbox.js.map +1 -1
- package/dist/lib/types.d.ts +184 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/version.d.ts +7 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +8 -0
- package/dist/lib/version.js.map +1 -0
- package/package.json +1 -1
|
@@ -6,42 +6,93 @@ export const REDACTED = '[REDACTED]';
|
|
|
6
6
|
* replace every empty string in the output.
|
|
7
7
|
*/
|
|
8
8
|
const MIN_SECRET_LENGTH = 16;
|
|
9
|
-
/**
|
|
10
|
-
function
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
/** Escape one UTF-16 code unit as `\uXXXX`. */
|
|
10
|
+
function unicodeEscape(code, upper) {
|
|
11
|
+
const hex = code.toString(16).padStart(4, '0');
|
|
12
|
+
return `\\u${upper ? hex.toUpperCase() : hex}`;
|
|
13
|
+
}
|
|
14
|
+
const SHORT_ESCAPES = {
|
|
15
|
+
'"': '\\"',
|
|
16
|
+
'\\': '\\\\',
|
|
17
|
+
'\n': '\\n',
|
|
18
|
+
'\r': '\\r',
|
|
19
|
+
'\t': '\\t',
|
|
20
|
+
'\b': '\\b',
|
|
21
|
+
'\f': '\\f',
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* JSON string escaping with configurable `\uXXXX` coverage: control
|
|
25
|
+
* characters always, plus whatever `escapeAlso` selects.
|
|
26
|
+
*/
|
|
27
|
+
function escapeJson(text, escapeAlso, upper) {
|
|
28
|
+
let out = '';
|
|
29
|
+
for (let i = 0; i < text.length; i++) {
|
|
30
|
+
const char = text[i];
|
|
31
|
+
const code = text.charCodeAt(i);
|
|
32
|
+
if (SHORT_ESCAPES[char])
|
|
33
|
+
out += SHORT_ESCAPES[char];
|
|
34
|
+
else if (code < 0x20 || escapeAlso(code))
|
|
35
|
+
out += unicodeEscape(code, upper);
|
|
36
|
+
else
|
|
37
|
+
out += char;
|
|
15
38
|
}
|
|
16
|
-
return
|
|
39
|
+
return out;
|
|
17
40
|
}
|
|
18
|
-
/**
|
|
19
|
-
|
|
41
|
+
/**
|
|
42
|
+
* The text a secret can turn into inside JSON output: as written, escaped once
|
|
43
|
+
* by the encoders the agent CLIs and common tools use, and escaped twice (JSON
|
|
44
|
+
* inside a JSON string, such as a tool's JSON output recorded in a JSONL
|
|
45
|
+
* transcript).
|
|
46
|
+
*
|
|
47
|
+
* Encoders agree on quotes, backslashes, and control characters but differ on
|
|
48
|
+
* the rest, so each style is covered: plain (JavaScript, Rust), ASCII-only with
|
|
49
|
+
* `\u` escapes for every non-ASCII character (Python's default), HTML-safe
|
|
50
|
+
* `<`, `>`, `&`, U+2028, and U+2029 (Go's default), and escaped slashes. Hex
|
|
51
|
+
* digits appear in both cases. A secret made only of characters no encoder
|
|
52
|
+
* escapes has a single form: itself.
|
|
53
|
+
*/
|
|
54
|
+
export function encodedForms(secret) {
|
|
55
|
+
const htmlUnsafe = (code) => code === 0x3c || code === 0x3e || code === 0x26 || code === 0x2028 || code === 0x2029;
|
|
56
|
+
const nonAscii = (code) => code > 0x7f;
|
|
57
|
+
const plain = JSON.stringify(secret).slice(1, -1);
|
|
58
|
+
const once = new Set([plain, plain.replace(/\//g, '\\/')]);
|
|
59
|
+
for (const upper of [false, true]) {
|
|
60
|
+
once.add(escapeJson(secret, nonAscii, upper));
|
|
61
|
+
once.add(escapeJson(secret, htmlUnsafe, upper));
|
|
62
|
+
}
|
|
63
|
+
const forms = new Set([secret, ...once]);
|
|
64
|
+
for (const form of once)
|
|
65
|
+
forms.add(JSON.stringify(form).slice(1, -1));
|
|
66
|
+
return [...forms];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Every string to replace for these secrets: each usable secret in all of its
|
|
70
|
+
* encoded forms, deduped and ordered longest-first so overlaps redact whole.
|
|
71
|
+
*/
|
|
72
|
+
function redactionNeedles(secrets) {
|
|
73
|
+
const needles = new Set();
|
|
74
|
+
for (const secret of secrets) {
|
|
75
|
+
if (!secret || secret.length < MIN_SECRET_LENGTH)
|
|
76
|
+
continue;
|
|
77
|
+
for (const form of encodedForms(secret))
|
|
78
|
+
needles.add(form);
|
|
79
|
+
}
|
|
80
|
+
return [...needles].sort((a, b) => b.length - a.length);
|
|
81
|
+
}
|
|
82
|
+
function replaceText(text, needles) {
|
|
20
83
|
let out = text;
|
|
21
|
-
for (const
|
|
84
|
+
for (const needle of needles) {
|
|
22
85
|
// split/join rather than RegExp: the secret is arbitrary text and must not be
|
|
23
86
|
// interpreted as a pattern.
|
|
24
|
-
out = out.split(
|
|
87
|
+
out = out.split(needle).join(REDACTED);
|
|
25
88
|
}
|
|
26
89
|
return out;
|
|
27
90
|
}
|
|
28
91
|
const REDACTED_BYTES = Buffer.from(REDACTED, 'utf-8');
|
|
29
|
-
|
|
30
|
-
* Buffer-level equivalent of {@link redactSecrets}.
|
|
31
|
-
*
|
|
32
|
-
* `generatedFiles` holds raw bytes so that binary assets survive collection
|
|
33
|
-
* intact. Redaction therefore cannot route through a string: decoding to UTF-8
|
|
34
|
-
* and re-encoding replaces every non-UTF-8 byte with U+FFFD, which would corrupt
|
|
35
|
-
* exactly the files byte-fidelity exists to protect. Passing a Buffer to
|
|
36
|
-
* {@link redactSecrets} is worse still — Buffer has no `split`, so it throws.
|
|
37
|
-
*
|
|
38
|
-
* Credentials are ASCII, so their UTF-8 byte sequence is located and spliced out
|
|
39
|
-
* directly and every other byte is copied through untouched.
|
|
40
|
-
*/
|
|
41
|
-
export function redactSecretsBuffer(content, secrets) {
|
|
92
|
+
function replaceBuffer(content, needles) {
|
|
42
93
|
let out = content;
|
|
43
|
-
for (const
|
|
44
|
-
const needle = Buffer.from(
|
|
94
|
+
for (const text of needles) {
|
|
95
|
+
const needle = Buffer.from(text, 'utf-8');
|
|
45
96
|
let found = out.indexOf(needle);
|
|
46
97
|
if (found === -1)
|
|
47
98
|
continue;
|
|
@@ -57,8 +108,27 @@ export function redactSecretsBuffer(content, secrets) {
|
|
|
57
108
|
}
|
|
58
109
|
return out;
|
|
59
110
|
}
|
|
60
|
-
|
|
61
|
-
|
|
111
|
+
/** Replace every occurrence of each secret, in any of its {@link encodedForms}, with {@link REDACTED}. */
|
|
112
|
+
export function redactSecrets(text, secrets) {
|
|
113
|
+
return replaceText(text, redactionNeedles(secrets));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Buffer-level equivalent of {@link redactSecrets}.
|
|
117
|
+
*
|
|
118
|
+
* `generatedFiles` holds raw bytes so that binary assets survive collection
|
|
119
|
+
* intact. Redaction therefore cannot route through a string: decoding to UTF-8
|
|
120
|
+
* and re-encoding replaces every non-UTF-8 byte with U+FFFD, which would corrupt
|
|
121
|
+
* exactly the files byte-fidelity exists to protect. Passing a Buffer to
|
|
122
|
+
* {@link redactSecrets} is worse still — Buffer has no `split`, so it throws.
|
|
123
|
+
*
|
|
124
|
+
* Each secret form's UTF-8 byte sequence is located and spliced out directly,
|
|
125
|
+
* and every other byte is copied through untouched.
|
|
126
|
+
*/
|
|
127
|
+
export function redactSecretsBuffer(content, secrets) {
|
|
128
|
+
return replaceBuffer(content, redactionNeedles(secrets));
|
|
129
|
+
}
|
|
130
|
+
function redactScriptResult(result, needles) {
|
|
131
|
+
return { ...result, output: replaceText(result.output, needles) };
|
|
62
132
|
}
|
|
63
133
|
/**
|
|
64
134
|
* Redact every text-bearing field of a run result. Returns a new object; the
|
|
@@ -71,33 +141,76 @@ function redactScriptResult(result, secrets) {
|
|
|
71
141
|
* model names, deleted-file paths — are passed through untouched.
|
|
72
142
|
*/
|
|
73
143
|
export function redactRunResult(result, secrets) {
|
|
74
|
-
|
|
144
|
+
const needles = redactionNeedles(secrets);
|
|
145
|
+
if (needles.length === 0)
|
|
75
146
|
return result;
|
|
76
147
|
const redacted = {
|
|
77
148
|
...result,
|
|
78
|
-
output:
|
|
149
|
+
output: replaceText(result.output, needles),
|
|
79
150
|
};
|
|
80
151
|
if (result.transcript !== undefined) {
|
|
81
|
-
redacted.transcript =
|
|
152
|
+
redacted.transcript = replaceText(result.transcript, needles);
|
|
82
153
|
}
|
|
83
154
|
if (result.error !== undefined) {
|
|
84
|
-
redacted.error =
|
|
155
|
+
redacted.error = replaceText(result.error, needles);
|
|
85
156
|
}
|
|
86
157
|
if (result.testResult) {
|
|
87
|
-
redacted.testResult = redactScriptResult(result.testResult,
|
|
158
|
+
redacted.testResult = redactScriptResult(result.testResult, needles);
|
|
88
159
|
}
|
|
89
160
|
if (result.scriptsResults) {
|
|
90
161
|
redacted.scriptsResults = Object.fromEntries(Object.entries(result.scriptsResults).map(([name, script]) => [
|
|
91
162
|
name,
|
|
92
|
-
redactScriptResult(script,
|
|
163
|
+
redactScriptResult(script, needles),
|
|
93
164
|
]));
|
|
94
165
|
}
|
|
95
166
|
if (result.generatedFiles) {
|
|
96
167
|
redacted.generatedFiles = Object.fromEntries(Object.entries(result.generatedFiles).map(([path, content]) => [
|
|
97
168
|
path,
|
|
98
|
-
|
|
169
|
+
replaceBuffer(content, needles),
|
|
99
170
|
]));
|
|
100
171
|
}
|
|
101
172
|
return redacted;
|
|
102
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Redact every string (and Buffer) inside an arbitrary value. Used for payloads
|
|
176
|
+
* that leave the run as plain data, such as reporter events, where the value
|
|
177
|
+
* carries user-attached fields (`analysis`, `metadata`) that
|
|
178
|
+
* {@link redactRunResult} never saw.
|
|
179
|
+
*
|
|
180
|
+
* Returns a copy: arrays and plain objects are rebuilt, strings and Buffers are
|
|
181
|
+
* redacted, and everything else (numbers, functions, class instances such as
|
|
182
|
+
* Date) is passed through by reference. The input is not mutated.
|
|
183
|
+
*/
|
|
184
|
+
export function redactValue(value, secrets) {
|
|
185
|
+
const needles = redactionNeedles(secrets);
|
|
186
|
+
if (needles.length === 0)
|
|
187
|
+
return value;
|
|
188
|
+
const copies = new Map();
|
|
189
|
+
const visit = (current) => {
|
|
190
|
+
if (typeof current === 'string')
|
|
191
|
+
return replaceText(current, needles);
|
|
192
|
+
if (Buffer.isBuffer(current))
|
|
193
|
+
return replaceBuffer(current, needles);
|
|
194
|
+
if (current === null || typeof current !== 'object')
|
|
195
|
+
return current;
|
|
196
|
+
if (copies.has(current))
|
|
197
|
+
return copies.get(current);
|
|
198
|
+
if (Array.isArray(current)) {
|
|
199
|
+
const copy = [];
|
|
200
|
+
copies.set(current, copy);
|
|
201
|
+
for (const item of current)
|
|
202
|
+
copy.push(visit(item));
|
|
203
|
+
return copy;
|
|
204
|
+
}
|
|
205
|
+
const prototype = Object.getPrototypeOf(current);
|
|
206
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
207
|
+
return current;
|
|
208
|
+
const copy = {};
|
|
209
|
+
copies.set(current, copy);
|
|
210
|
+
for (const [key, item] of Object.entries(current))
|
|
211
|
+
copy[key] = visit(item);
|
|
212
|
+
return copy;
|
|
213
|
+
};
|
|
214
|
+
return visit(value);
|
|
215
|
+
}
|
|
103
216
|
//# sourceMappingURL=redact.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/lib/agents/redact.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../../src/lib/agents/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { ScriptResult } from './types.js';
|
|
5
5
|
import type { SandboxManager } from '../sandbox.js';
|
|
6
6
|
import type { DockerSandboxManager } from '../docker-sandbox.js';
|
|
7
|
+
import { type TokenUsage } from '../o11y/index.js';
|
|
7
8
|
import type { ValidationMode } from '../types.js';
|
|
8
9
|
/** Union type for sandbox implementations */
|
|
9
10
|
type AnySandbox = SandboxManager | DockerSandboxManager;
|
|
@@ -75,11 +76,29 @@ export declare function ensureValidationRunner(sandbox: AnySandbox): Promise<voi
|
|
|
75
76
|
* Run validation scripts in the sandbox.
|
|
76
77
|
*/
|
|
77
78
|
export declare function runValidation(sandbox: AnySandbox, scripts: string[], validation?: ValidationMode, env?: Record<string, string>): Promise<ValidationResults>;
|
|
79
|
+
/**
|
|
80
|
+
* Identity variables set on the agent and validation processes so the agent
|
|
81
|
+
* sees a generic user rather than the sandbox's own account name.
|
|
82
|
+
*/
|
|
83
|
+
export declare const NEUTRAL_WORKSPACE_ENV: Readonly<Record<string, string>>;
|
|
78
84
|
export declare function prepareNeutralWorkspace(sandbox: AnySandbox): Promise<NeutralWorkspace>;
|
|
79
85
|
export declare function initGitAndCommit(sandbox: AnySandbox): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Whether `path` is a canonical path inside the workspace, the only kind git
|
|
88
|
+
* prints for a tracked file: relative, with no `.` or `..` segments, no empty
|
|
89
|
+
* segments, no trailing slash, and nothing inside a `.git` directory.
|
|
90
|
+
*
|
|
91
|
+
* Diff capture runs git in the agent's sandbox, where the agent can put its own
|
|
92
|
+
* `git` first on PATH. Every path it reports is therefore untrusted input, and
|
|
93
|
+
* anything that fails this check is dropped before it is read, written, or
|
|
94
|
+
* deleted anywhere: `../` could otherwise reach outside a results directory on
|
|
95
|
+
* the host, and an alias like `./EVAL.ts` could slip past a glob.
|
|
96
|
+
*/
|
|
97
|
+
export declare function isWorkspacePath(path: string): boolean;
|
|
80
98
|
/**
|
|
81
99
|
* Capture source files generated by the agent.
|
|
82
100
|
* Returns both modified/added files (with content) and deleted file paths.
|
|
101
|
+
* Paths that aren't canonical workspace paths are dropped (see {@link isWorkspacePath}).
|
|
83
102
|
*/
|
|
84
103
|
export declare function captureGeneratedFiles(sandbox: AnySandbox): Promise<{
|
|
85
104
|
generatedFiles: Record<string, Buffer>;
|
|
@@ -93,9 +112,13 @@ export declare function createVitestConfig(sandbox: AnySandbox): Promise<void>;
|
|
|
93
112
|
* Inject transcript context into the sandbox so EVAL.ts tests can assert on agent behavior.
|
|
94
113
|
* Writes parsed transcript summary to `__agent_eval__/results.json`.
|
|
95
114
|
*
|
|
115
|
+
* `usage` is token usage the agent reported outside its transcript. It takes
|
|
116
|
+
* precedence over the transcript's own usage, the same order the run's result
|
|
117
|
+
* uses, so EVAL.ts and result.json agree.
|
|
118
|
+
*
|
|
96
119
|
* This is best-effort: failures are silently ignored since it's supplementary data.
|
|
97
120
|
*/
|
|
98
|
-
export declare function injectTranscriptContext(sandbox: AnySandbox, rawTranscript: string | undefined, agentName: string, model?: string): Promise<void>;
|
|
121
|
+
export declare function injectTranscriptContext(sandbox: AnySandbox, rawTranscript: string | undefined, agentName: string, model?: string, usage?: TokenUsage): Promise<void>;
|
|
99
122
|
/**
|
|
100
123
|
* AI Gateway configuration.
|
|
101
124
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/lib/agents/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/lib/agents/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared utilities for agent implementations.
|
|
3
3
|
*/
|
|
4
|
+
import { posix } from 'node:path';
|
|
4
5
|
import { parseTranscript } from '../o11y/index.js';
|
|
5
6
|
/**
|
|
6
7
|
* Well-known directory where transcript context is written inside the sandbox.
|
|
@@ -140,8 +141,16 @@ env) {
|
|
|
140
141
|
}
|
|
141
142
|
return results;
|
|
142
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Identity variables set on the agent and validation processes so the agent
|
|
146
|
+
* sees a generic user rather than the sandbox's own account name.
|
|
147
|
+
*/
|
|
148
|
+
export const NEUTRAL_WORKSPACE_ENV = Object.freeze({
|
|
149
|
+
USER: 'user',
|
|
150
|
+
LOGNAME: 'user',
|
|
151
|
+
});
|
|
143
152
|
export async function prepareNeutralWorkspace(sandbox) {
|
|
144
|
-
const neutralEnv = {
|
|
153
|
+
const neutralEnv = { ...NEUTRAL_WORKSPACE_ENV };
|
|
145
154
|
const currentWorkingDirectory = sandbox.getWorkingDirectory();
|
|
146
155
|
await sandbox.runShell('git remote remove origin 2>/dev/null || true; rm -rf .git/logs');
|
|
147
156
|
if (!currentWorkingDirectory.includes('/vercel/')) {
|
|
@@ -171,24 +180,46 @@ export async function initGitAndCommit(sandbox) {
|
|
|
171
180
|
// the generated files
|
|
172
181
|
await sandbox.runShell('git init && git config user.email "agent-eval@localhost" && git config user.name "agent-eval" && git add . && git commit -m "init"');
|
|
173
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Whether `path` is a canonical path inside the workspace, the only kind git
|
|
185
|
+
* prints for a tracked file: relative, with no `.` or `..` segments, no empty
|
|
186
|
+
* segments, no trailing slash, and nothing inside a `.git` directory.
|
|
187
|
+
*
|
|
188
|
+
* Diff capture runs git in the agent's sandbox, where the agent can put its own
|
|
189
|
+
* `git` first on PATH. Every path it reports is therefore untrusted input, and
|
|
190
|
+
* anything that fails this check is dropped before it is read, written, or
|
|
191
|
+
* deleted anywhere: `../` could otherwise reach outside a results directory on
|
|
192
|
+
* the host, and an alias like `./EVAL.ts` could slip past a glob.
|
|
193
|
+
*/
|
|
194
|
+
export function isWorkspacePath(path) {
|
|
195
|
+
if (!path || path.includes('\0') || path.startsWith('/'))
|
|
196
|
+
return false;
|
|
197
|
+
if (posix.normalize(path) !== path)
|
|
198
|
+
return false;
|
|
199
|
+
return path.split('/').every((segment) => segment !== '' && segment !== '.' && segment !== '..' && segment !== '.git');
|
|
200
|
+
}
|
|
174
201
|
/**
|
|
175
202
|
* Capture source files generated by the agent.
|
|
176
203
|
* Returns both modified/added files (with content) and deleted file paths.
|
|
204
|
+
* Paths that aren't canonical workspace paths are dropped (see {@link isWorkspacePath}).
|
|
177
205
|
*/
|
|
178
206
|
export async function captureGeneratedFiles(sandbox) {
|
|
179
207
|
const generatedFiles = {};
|
|
180
208
|
const deletedFiles = [];
|
|
181
209
|
try {
|
|
182
|
-
//
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
210
|
+
// --name-status distinguishes added/modified from deleted. --no-renames is
|
|
211
|
+
// needed because `git diff` detects renames by default and reports a moved
|
|
212
|
+
// file as one `R<score>\t<old>\t<new>` entry, which would lose both the old
|
|
213
|
+
// path's deletion and the new path's content. -z keeps paths verbatim:
|
|
214
|
+
// without it, git C-quotes paths containing quotes, backslashes, control
|
|
215
|
+
// characters, or non-ASCII bytes, and the quoted form can't be read back.
|
|
216
|
+
const findResult = await sandbox.runShell('git add . && git diff HEAD --name-status --no-renames -z');
|
|
217
|
+
// Records are "<status>\0<path>\0".
|
|
218
|
+
const fields = findResult.stdout.split('\0');
|
|
219
|
+
for (let i = 0; i + 1 < fields.length; i += 2) {
|
|
220
|
+
const status = fields[i].trim();
|
|
221
|
+
const filePath = fields[i + 1];
|
|
222
|
+
if (!isWorkspacePath(filePath))
|
|
192
223
|
continue;
|
|
193
224
|
if (status === 'D') {
|
|
194
225
|
deletedFiles.push(filePath);
|
|
@@ -247,15 +278,19 @@ export default defineConfig({
|
|
|
247
278
|
* Inject transcript context into the sandbox so EVAL.ts tests can assert on agent behavior.
|
|
248
279
|
* Writes parsed transcript summary to `__agent_eval__/results.json`.
|
|
249
280
|
*
|
|
281
|
+
* `usage` is token usage the agent reported outside its transcript. It takes
|
|
282
|
+
* precedence over the transcript's own usage, the same order the run's result
|
|
283
|
+
* uses, so EVAL.ts and result.json agree.
|
|
284
|
+
*
|
|
250
285
|
* This is best-effort: failures are silently ignored since it's supplementary data.
|
|
251
286
|
*/
|
|
252
|
-
export async function injectTranscriptContext(sandbox, rawTranscript, agentName, model) {
|
|
287
|
+
export async function injectTranscriptContext(sandbox, rawTranscript, agentName, model, usage) {
|
|
253
288
|
try {
|
|
254
289
|
const transcript = rawTranscript
|
|
255
290
|
? parseTranscript(rawTranscript, agentName, model)
|
|
256
291
|
: null;
|
|
257
292
|
const context = {
|
|
258
|
-
o11y: transcript
|
|
293
|
+
o11y: transcript ? { ...transcript.summary, ...(usage ? { usage } : {}) } : null,
|
|
259
294
|
};
|
|
260
295
|
await sandbox.writeFiles({
|
|
261
296
|
[TRANSCRIPT_CONTEXT_PATH]: JSON.stringify(context, null, 2),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/lib/agents/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/lib/agents/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent interface and common types for all agents.
|
|
3
3
|
*/
|
|
4
|
-
import type { JudgeConfig, ModelPolicy, ModelTier, SetupFunction, SandboxBackend, ValidationMode } from '../types.js';
|
|
4
|
+
import type { JudgeConfig, ModelPolicy, ModelTier, RunProvenance, SetupFunction, SandboxBackend, ValidationMode, VerifierMode } from '../types.js';
|
|
5
|
+
import type { TokenUsage } from '../o11y/types.js';
|
|
5
6
|
import type { AgentDefinition } from './plugin/contract.js';
|
|
6
7
|
/**
|
|
7
8
|
* Common options for all agents.
|
|
@@ -59,6 +60,16 @@ export interface AgentRunOptions {
|
|
|
59
60
|
/** Pin the agentic LLM judge to a fixed agent+model. Undefined → the judge
|
|
60
61
|
* self-grades with this run's agent+model. */
|
|
61
62
|
judge?: JudgeConfig;
|
|
63
|
+
/** Extra environment variables for the agent process only (see
|
|
64
|
+
* `ExperimentConfig.agentEnv`). Default undefined: the agent's environment is
|
|
65
|
+
* unchanged. */
|
|
66
|
+
agentEnv?: Record<string, string>;
|
|
67
|
+
/** Where validation runs (see `ExperimentConfig.verifier`). Default
|
|
68
|
+
* undefined: validation runs in the agent's sandbox, as before. */
|
|
69
|
+
verifier?: VerifierMode;
|
|
70
|
+
/** Globs the agent must not change (see `ExperimentConfig.protectedPaths`).
|
|
71
|
+
* Default undefined: no tampering report in shared mode. */
|
|
72
|
+
protectedPaths?: string[];
|
|
62
73
|
}
|
|
63
74
|
/**
|
|
64
75
|
* Result from running a script.
|
|
@@ -95,6 +106,18 @@ export interface AgentRunResult {
|
|
|
95
106
|
observedModel?: string;
|
|
96
107
|
/** Codex only: model re-stated explicitly by the shell-tool repair (see RunnerResult.modelRepair) */
|
|
97
108
|
modelRepair?: string;
|
|
109
|
+
/** Token usage reported by the agent. When omitted, agent-eval reads it from
|
|
110
|
+
* the transcript with the agent's transcript parser. */
|
|
111
|
+
usage?: TokenUsage;
|
|
112
|
+
/** What ran (harness and agent CLI versions, sandbox environment). Set by the
|
|
113
|
+
* shared orchestrator; custom agents may set it themselves. */
|
|
114
|
+
provenance?: RunProvenance;
|
|
115
|
+
/** `'separate'` when validation ran in a separate verifier sandbox. */
|
|
116
|
+
verifier?: VerifierMode;
|
|
117
|
+
/** Id of the separate verifier sandbox, for debugging. */
|
|
118
|
+
verifierSandboxId?: string;
|
|
119
|
+
/** Protected paths the agent changed, sorted (see `EvalRunResult.tampering`). */
|
|
120
|
+
tampering?: string[];
|
|
98
121
|
}
|
|
99
122
|
/**
|
|
100
123
|
* Agent interface that all agents must implement.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/agents/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/agents/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnJ,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC;IAClC;mFAC+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;qCAEiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;8DAC0D;IAC1D,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC;kDAC8C;IAC9C,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;oBAEgB;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;uEACmE;IACnE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB;gEAC4D;IAC5D,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,sCAAsC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9C,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qGAAqG;IACrG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;4DACwD;IACxD,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;mEAC+D;IAC/D,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IAEb,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IAEpB,iCAAiC;IACjC,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAE5E,+DAA+D;IAC/D,eAAe,IAAI,MAAM,CAAC;IAE1B,2CAA2C;IAC3C,eAAe,IAAI,SAAS,CAAC;IAE7B;mFAC+E;IAC/E,UAAU,EAAE,eAAe,CAAC;CAC7B"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Building blocks for grading an agent's work somewhere the agent couldn't touch.
|
|
3
|
+
*
|
|
4
|
+
* With the shared verifier, tests are uploaded into the agent's own sandbox
|
|
5
|
+
* after it finishes, so anything the agent left behind there (a patched
|
|
6
|
+
* `node_modules`, a global binary, a background process, an edited test config)
|
|
7
|
+
* can change what the grader runs. The separate verifier instead captures the
|
|
8
|
+
* agent's file changes as a diff, boots a fresh sandbox, rebuilds the workspace
|
|
9
|
+
* from the original fixture, and applies only those changes, minus protected
|
|
10
|
+
* paths. These helpers do the capture, the protection check, and the apply.
|
|
11
|
+
*
|
|
12
|
+
* The capture itself runs git in the agent's sandbox, and the agent controls
|
|
13
|
+
* that sandbox: it can put its own `git` first on PATH and print whatever it
|
|
14
|
+
* likes. Captured paths are therefore untrusted input. Only canonical workspace
|
|
15
|
+
* paths are ever read or replayed; anything else (`./EVAL.ts`, `x/../data`,
|
|
16
|
+
* `../outside`) counts as protected and is reported as tampering. The
|
|
17
|
+
* guarantee is that protected paths never reach the verifier. Tampering
|
|
18
|
+
* reports are best effort: a replaced git can also hide changes, which are then
|
|
19
|
+
* simply not applied.
|
|
20
|
+
*/
|
|
21
|
+
import type { SandboxManager } from '../sandbox.js';
|
|
22
|
+
import type { DockerSandboxManager } from '../docker-sandbox.js';
|
|
23
|
+
import type { InstallStep } from './plugin/contract.js';
|
|
24
|
+
type AnySandbox = SandboxManager | DockerSandboxManager;
|
|
25
|
+
/**
|
|
26
|
+
* Paths the separate verifier always protects, on top of `protectedPaths`:
|
|
27
|
+
* the eval's own files wherever they appear, vitest's config and workspace
|
|
28
|
+
* files (which decide what runs and how), the harness's `__agent_eval__`
|
|
29
|
+
* directory, and `node_modules`, which the verifier installs fresh. The agent
|
|
30
|
+
* can only get `node_modules` into its diff by un-ignoring it, which is itself
|
|
31
|
+
* a way to ship a patched test runner.
|
|
32
|
+
*/
|
|
33
|
+
export declare const VERIFIER_PROTECTED_PATHS: readonly string[];
|
|
34
|
+
/**
|
|
35
|
+
* True when a path matches any of the globs, or isn't a canonical workspace
|
|
36
|
+
* path at all. Globs match lexically, so an alias such as `./EVAL.ts` or
|
|
37
|
+
* `src/../EVAL.ts` would slip past `**\/EVAL.ts`; git never prints one, so it
|
|
38
|
+
* can only come from a tampered capture and is treated as protected.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createProtectedPathMatcher(patterns: readonly string[]): (path: string) => boolean;
|
|
41
|
+
/** The agent's file changes relative to the git baseline. */
|
|
42
|
+
export interface AgentChanges {
|
|
43
|
+
/** Added or modified files, with their raw bytes. */
|
|
44
|
+
generatedFiles: Record<string, Buffer>;
|
|
45
|
+
/** Deleted files. */
|
|
46
|
+
deletedFiles: string[];
|
|
47
|
+
/** Added or modified files whose mode is executable. */
|
|
48
|
+
executableFiles: string[];
|
|
49
|
+
/** Paths the capture reported that aren't canonical workspace paths. Never
|
|
50
|
+
* read or replayed; reported as tampering. */
|
|
51
|
+
rejectedPaths: string[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Capture every change the agent made relative to the git baseline, before
|
|
55
|
+
* anything else is written to the workspace.
|
|
56
|
+
*
|
|
57
|
+
* Like {@link captureGeneratedFiles}, renames are reported as a deletion plus
|
|
58
|
+
* an addition and paths are read NUL-separated so none are lost. Unlike it,
|
|
59
|
+
* this capture has to be replayable: executable modes are kept, so a script
|
|
60
|
+
* the agent made runnable stays runnable, and a failed capture throws instead
|
|
61
|
+
* of quietly returning nothing, since grading an empty diff would record a
|
|
62
|
+
* false failure.
|
|
63
|
+
*/
|
|
64
|
+
export declare function captureAgentChanges(sandbox: AnySandbox): Promise<AgentChanges>;
|
|
65
|
+
/**
|
|
66
|
+
* Record the workspace as it is right before the agent runs and return the git
|
|
67
|
+
* tree id. Install steps run after the git baseline and leave files behind (a
|
|
68
|
+
* lockfile, a CLI config file), so comparing against this snapshot rather than
|
|
69
|
+
* the baseline means tampering only ever reports the agent's own changes.
|
|
70
|
+
*/
|
|
71
|
+
export declare function snapshotWorkspace(sandbox: AnySandbox): Promise<string>;
|
|
72
|
+
/** Paths added, modified, or deleted since {@link snapshotWorkspace} returned `tree`. */
|
|
73
|
+
export declare function pathsChangedSince(sandbox: AnySandbox, tree: string): Promise<string[]>;
|
|
74
|
+
/** Changed paths that match the protected globs, sorted and de-duplicated. */
|
|
75
|
+
export declare function findTampering(paths: Iterable<string>, isProtected: (path: string) => boolean): string[];
|
|
76
|
+
/** Replay the agent's changes into the verifier's workspace, skipping protected paths. */
|
|
77
|
+
export declare function applyAgentChanges(sandbox: AnySandbox, changes: AgentChanges, isProtected: (path: string) => boolean): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Install steps the separate verifier re-runs for the project's dependencies.
|
|
80
|
+
* Definitions that mark no step with a scope get every step, since there is
|
|
81
|
+
* no way to tell their project install from their CLI install.
|
|
82
|
+
*/
|
|
83
|
+
export declare function projectInstallSteps(steps: InstallStep[]): InstallStep[];
|
|
84
|
+
/** Install steps for the agent CLI, for a verifier whose eval uses the judge. */
|
|
85
|
+
export declare function agentInstallSteps(steps: InstallStep[]): InstallStep[];
|
|
86
|
+
/**
|
|
87
|
+
* Whether any fixture file imports the judge matchers, in which case the
|
|
88
|
+
* verifier needs the judge agent's CLI installed. EVAL files are checked along
|
|
89
|
+
* with every other fixture file, so a shared test helper that imports the
|
|
90
|
+
* judge counts too.
|
|
91
|
+
*/
|
|
92
|
+
export declare function fixtureUsesJudge(files: ReadonlyArray<{
|
|
93
|
+
content: Buffer | string;
|
|
94
|
+
}>): boolean;
|
|
95
|
+
export {};
|
|
96
|
+
//# sourceMappingURL=verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../../src/lib/agents/verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,KAAK,UAAU,GAAG,cAAc,GAAG,oBAAoB,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAMrD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAEjG;AAED,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,qBAAqB;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,wDAAwD;IACxD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;kDAC8C;IAC9C,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAgCpF;AAQD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5E;AAED,yFAAyF;AACzF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ5F;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,EAAE,CAEvG;AAkBD,0FAA0F;AAC1F,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACrC,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAEvE;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAErE;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,GAAG,OAAO,CAI5F"}
|