@post-print/agent-test 0.1.10 → 0.1.13
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/README.md +52 -6
- package/dist/cli-entry.d.ts.map +1 -1
- package/dist/cli-entry.js +1 -1
- package/dist/cli-entry.js.map +1 -1
- package/dist/cli.js +54 -5
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +49 -0
- package/dist/doctor.js.map +1 -0
- package/dist/html-report.d.ts +11 -0
- package/dist/html-report.d.ts.map +1 -0
- package/dist/html-report.js +462 -0
- package/dist/html-report.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/live-isolation.d.ts +23 -0
- package/dist/live-isolation.d.ts.map +1 -1
- package/dist/live-isolation.js +125 -14
- package/dist/live-isolation.js.map +1 -1
- package/dist/live-timeout.d.ts +11 -0
- package/dist/live-timeout.d.ts.map +1 -0
- package/dist/live-timeout.js +29 -0
- package/dist/live-timeout.js.map +1 -0
- package/dist/progress.d.ts.map +1 -1
- package/dist/progress.js +2 -1
- package/dist/progress.js.map +1 -1
- package/dist/record-trace.d.ts +18 -0
- package/dist/record-trace.d.ts.map +1 -1
- package/dist/record-trace.js +47 -7
- package/dist/record-trace.js.map +1 -1
- package/dist/run-suite.d.ts +6 -0
- package/dist/run-suite.d.ts.map +1 -1
- package/dist/run-suite.js +124 -52
- package/dist/run-suite.js.map +1 -1
- package/dist/scenario-seed.d.ts +8 -0
- package/dist/scenario-seed.d.ts.map +1 -1
- package/dist/scenario-seed.js +31 -0
- package/dist/scenario-seed.js.map +1 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +3 -9
- package/dist/theme.js.map +1 -1
- package/dist/types.d.ts +3 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/warnings.d.ts.map +1 -1
- package/dist/warnings.js +1 -2
- package/dist/warnings.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
function escapeHtml(value) {
|
|
5
|
+
return value
|
|
6
|
+
.replaceAll("&", "&")
|
|
7
|
+
.replaceAll("<", "<")
|
|
8
|
+
.replaceAll(">", ">")
|
|
9
|
+
.replaceAll('"', """)
|
|
10
|
+
.replaceAll("'", "'");
|
|
11
|
+
}
|
|
12
|
+
function formatDuration(ms) {
|
|
13
|
+
if (ms < 1000) {
|
|
14
|
+
return `${Math.round(ms)}ms`;
|
|
15
|
+
}
|
|
16
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
17
|
+
}
|
|
18
|
+
function statusLabel(result) {
|
|
19
|
+
if (result.skipped) {
|
|
20
|
+
return "skipped";
|
|
21
|
+
}
|
|
22
|
+
return result.passed ? "passed" : "failed";
|
|
23
|
+
}
|
|
24
|
+
function statusClass(result) {
|
|
25
|
+
if (result.skipped) {
|
|
26
|
+
return "status-skipped";
|
|
27
|
+
}
|
|
28
|
+
return result.passed ? "status-passed" : "status-failed";
|
|
29
|
+
}
|
|
30
|
+
/** Human-readable label + one-line explanation for the matcher codes assertRubric/judge emit. */
|
|
31
|
+
const MATCHER_LABELS = {
|
|
32
|
+
runAgent: { label: "Agent run", hint: "The agent session itself failed or was cut short." },
|
|
33
|
+
must: {
|
|
34
|
+
label: "Missing requirement",
|
|
35
|
+
hint: "A required behavior did not show up in the transcript.",
|
|
36
|
+
},
|
|
37
|
+
mustNot: { label: "Forbidden behavior", hint: "The agent did something it was told not to do." },
|
|
38
|
+
mustRun: { label: "Missing command", hint: "An expected command never ran." },
|
|
39
|
+
mustInvokeSkill: {
|
|
40
|
+
label: "Missing skill",
|
|
41
|
+
hint: "The agent didn't read a skill it was expected to use.",
|
|
42
|
+
},
|
|
43
|
+
mustNotInvokeSkill: {
|
|
44
|
+
label: "Unexpected skill",
|
|
45
|
+
hint: "The agent read a skill it should have avoided.",
|
|
46
|
+
},
|
|
47
|
+
routingBlock: { label: "Routing", hint: "The routing announcement didn't match expectations." },
|
|
48
|
+
workingTreeLeak: {
|
|
49
|
+
label: "Working tree leak",
|
|
50
|
+
hint: "The agent's edits leaked outside its isolated worktree.",
|
|
51
|
+
},
|
|
52
|
+
recordTrace: { label: "Recording failed", hint: "Saving the trace to disk failed." },
|
|
53
|
+
judge: { label: "Judge", hint: "The LLM judge flagged this scenario." },
|
|
54
|
+
};
|
|
55
|
+
function humanizeMatcher(matcher) {
|
|
56
|
+
const [base] = matcher.split(":");
|
|
57
|
+
const known = MATCHER_LABELS[base ?? matcher];
|
|
58
|
+
if (known) {
|
|
59
|
+
if (matcher.includes(":")) {
|
|
60
|
+
const suffix = matcher.slice(matcher.indexOf(":") + 1);
|
|
61
|
+
return { label: `${known.label} — ${suffix}`, hint: known.hint };
|
|
62
|
+
}
|
|
63
|
+
return known;
|
|
64
|
+
}
|
|
65
|
+
return { label: matcher };
|
|
66
|
+
}
|
|
67
|
+
const ROLE_META = {
|
|
68
|
+
user: { label: "User", side: "right" },
|
|
69
|
+
assistant: { label: "Agent", side: "left" },
|
|
70
|
+
system: { label: "System", side: "center" },
|
|
71
|
+
tool: { label: "Tool", side: "center" },
|
|
72
|
+
};
|
|
73
|
+
function renderMessageBubble(message) {
|
|
74
|
+
const meta = ROLE_META[message.role] ?? { label: message.role, side: "center" };
|
|
75
|
+
return `
|
|
76
|
+
<div class="chat-row side-${meta.side}">
|
|
77
|
+
<div class="bubble role-${escapeHtml(message.role)}">
|
|
78
|
+
<div class="bubble-label">${escapeHtml(meta.label)}</div>
|
|
79
|
+
<div class="bubble-text">${escapeHtml(message.content)}</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>`;
|
|
82
|
+
}
|
|
83
|
+
/** Truncate long single-line arg values so a stray file body doesn't blow up the card. */
|
|
84
|
+
function formatArgValue(value) {
|
|
85
|
+
const text = typeof value === "string" ? value : JSON.stringify(value);
|
|
86
|
+
const oneLine = text.replaceAll("\n", " ↵ ");
|
|
87
|
+
return oneLine.length > 140 ? `${oneLine.slice(0, 140)}…` : oneLine;
|
|
88
|
+
}
|
|
89
|
+
function renderToolArgs(args) {
|
|
90
|
+
const entries = args ? Object.entries(args) : [];
|
|
91
|
+
if (entries.length === 0) {
|
|
92
|
+
return "";
|
|
93
|
+
}
|
|
94
|
+
const rows = entries
|
|
95
|
+
.map(([key, value]) => `<div class="tool-arg"><span class="tool-arg-key">${escapeHtml(key)}</span><code>${escapeHtml(formatArgValue(value))}</code></div>`)
|
|
96
|
+
.join("");
|
|
97
|
+
return `<div class="tool-args">${rows}</div>`;
|
|
98
|
+
}
|
|
99
|
+
function renderToolCallCard(call) {
|
|
100
|
+
return `
|
|
101
|
+
<div class="chat-row side-left">
|
|
102
|
+
<div class="tool-card">
|
|
103
|
+
<div class="tool-card-head"><span class="tool-icon">⚙</span><span class="tool-name">${escapeHtml(call.name)}</span></div>
|
|
104
|
+
${renderToolArgs(call.args)}
|
|
105
|
+
</div>
|
|
106
|
+
</div>`;
|
|
107
|
+
}
|
|
108
|
+
/** Interleave messages and tool calls chronologically when the trace recorded emission order. */
|
|
109
|
+
function buildOrderedTimeline(trace) {
|
|
110
|
+
const items = [
|
|
111
|
+
...trace.messages.map((message) => message.seq === undefined
|
|
112
|
+
? undefined
|
|
113
|
+
: { kind: "message", seq: message.seq, message }),
|
|
114
|
+
...trace.toolCalls.map((call) => call.seq === undefined ? undefined : { kind: "tool", seq: call.seq, call }),
|
|
115
|
+
].filter((item) => item !== undefined);
|
|
116
|
+
const totalItems = trace.messages.length + trace.toolCalls.length;
|
|
117
|
+
if (items.length !== totalItems || totalItems === 0) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
return items.sort((a, b) => a.seq - b.seq);
|
|
121
|
+
}
|
|
122
|
+
function renderChat(trace) {
|
|
123
|
+
if (!trace) {
|
|
124
|
+
return `<p class="empty">No transcript recorded for this scenario.</p>`;
|
|
125
|
+
}
|
|
126
|
+
const parts = [];
|
|
127
|
+
const timeline = buildOrderedTimeline(trace);
|
|
128
|
+
if (timeline) {
|
|
129
|
+
parts.push(`<div class="chat">`);
|
|
130
|
+
for (const item of timeline) {
|
|
131
|
+
parts.push(item.kind === "message" ? renderMessageBubble(item.message) : renderToolCallCard(item.call));
|
|
132
|
+
}
|
|
133
|
+
parts.push(`</div>`);
|
|
134
|
+
}
|
|
135
|
+
else if (trace.messages.length > 0 || trace.toolCalls.length > 0) {
|
|
136
|
+
parts.push(`<p class="empty note">Emission order wasn't recorded for this trace — messages and tool calls are shown in separate groups below.</p>`);
|
|
137
|
+
if (trace.messages.length > 0) {
|
|
138
|
+
parts.push(`<div class="chat">`);
|
|
139
|
+
for (const message of trace.messages) {
|
|
140
|
+
parts.push(renderMessageBubble(message));
|
|
141
|
+
}
|
|
142
|
+
parts.push(`</div>`);
|
|
143
|
+
}
|
|
144
|
+
if (trace.toolCalls.length > 0) {
|
|
145
|
+
parts.push(`<h4>Tool calls</h4><div class="chat">`);
|
|
146
|
+
for (const call of trace.toolCalls) {
|
|
147
|
+
parts.push(renderToolCallCard(call));
|
|
148
|
+
}
|
|
149
|
+
parts.push(`</div>`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
parts.push(`<p class="empty">No messages in transcript.</p>`);
|
|
154
|
+
}
|
|
155
|
+
if (trace.shellCommands.length > 0) {
|
|
156
|
+
parts.push(`<h4>Shell commands</h4><ul class="shell-commands">`);
|
|
157
|
+
for (const command of trace.shellCommands) {
|
|
158
|
+
parts.push(`<li><code>${escapeHtml(command)}</code></li>`);
|
|
159
|
+
}
|
|
160
|
+
parts.push(`</ul>`);
|
|
161
|
+
}
|
|
162
|
+
return parts.join("\n");
|
|
163
|
+
}
|
|
164
|
+
function renderJudgeVerdicts(result) {
|
|
165
|
+
const verdicts = result.judgeVerdicts;
|
|
166
|
+
if (!verdicts || verdicts.length === 0) {
|
|
167
|
+
return "";
|
|
168
|
+
}
|
|
169
|
+
const items = verdicts
|
|
170
|
+
.map((verdict) => {
|
|
171
|
+
const badge = verdict.pass ? "pass" : "fail";
|
|
172
|
+
const icon = verdict.pass ? "✓" : "✗";
|
|
173
|
+
return `
|
|
174
|
+
<article class="verdict verdict-${badge}">
|
|
175
|
+
<p class="question"><span class="verdict-icon">${icon}</span>${escapeHtml(verdict.question)}</p>
|
|
176
|
+
<p class="rationale">${escapeHtml(verdict.rationale)}</p>
|
|
177
|
+
</article>`;
|
|
178
|
+
})
|
|
179
|
+
.join("\n");
|
|
180
|
+
return `<div class="verdicts">${items}</div>`;
|
|
181
|
+
}
|
|
182
|
+
function renderFailures(result) {
|
|
183
|
+
if (result.failures.length === 0) {
|
|
184
|
+
return "";
|
|
185
|
+
}
|
|
186
|
+
const items = result.failures
|
|
187
|
+
.map((failure) => {
|
|
188
|
+
const { label, hint } = humanizeMatcher(failure.matcher);
|
|
189
|
+
return `
|
|
190
|
+
<li>
|
|
191
|
+
<p class="failure-label">${escapeHtml(label)}</p>
|
|
192
|
+
${hint ? `<p class="failure-hint">${escapeHtml(hint)}</p>` : ""}
|
|
193
|
+
<p class="failure-message">${escapeHtml(failure.message)}</p>
|
|
194
|
+
</li>`;
|
|
195
|
+
})
|
|
196
|
+
.join("\n");
|
|
197
|
+
return `<ul class="failures">${items}</ul>`;
|
|
198
|
+
}
|
|
199
|
+
function renderScenario(result) {
|
|
200
|
+
const open = result.passed || result.skipped ? "" : " open";
|
|
201
|
+
const failures = renderFailures(result);
|
|
202
|
+
const judgeVerdicts = renderJudgeVerdicts(result);
|
|
203
|
+
const diagnostics = failures || judgeVerdicts
|
|
204
|
+
? `<div class="diagnostics">
|
|
205
|
+
${failures ? `<section><h3>What went wrong</h3>${failures}</section>` : ""}
|
|
206
|
+
${judgeVerdicts ? `<section><h3>Judge verdict</h3>${judgeVerdicts}</section>` : ""}
|
|
207
|
+
</div>`
|
|
208
|
+
: "";
|
|
209
|
+
return `
|
|
210
|
+
<details class="scenario ${statusClass(result)}"${open}>
|
|
211
|
+
<summary>
|
|
212
|
+
<span class="badge ${statusClass(result)}">${statusLabel(result)}</span>
|
|
213
|
+
<span class="scenario-name">${escapeHtml(result.scenario)}</span>
|
|
214
|
+
<span class="duration">${escapeHtml(formatDuration(result.durationMs))}</span>
|
|
215
|
+
</summary>
|
|
216
|
+
<div class="scenario-body">
|
|
217
|
+
${diagnostics}
|
|
218
|
+
<section class="conversation">
|
|
219
|
+
<h3>Conversation</h3>
|
|
220
|
+
${renderChat(result.trace)}
|
|
221
|
+
</section>
|
|
222
|
+
</div>
|
|
223
|
+
</details>`;
|
|
224
|
+
}
|
|
225
|
+
function renderSuite(report) {
|
|
226
|
+
const scenarios = report.results.map(renderScenario).join("\n");
|
|
227
|
+
return `
|
|
228
|
+
<section class="suite">
|
|
229
|
+
<header class="suite-header">
|
|
230
|
+
<div><h2>${escapeHtml(report.suite)}</h2><span class="host">${escapeHtml(report.host)}</span></div>
|
|
231
|
+
<p class="suite-counts">${report.passed} passed · ${report.failed} failed · ${report.skipped} skipped</p>
|
|
232
|
+
</header>
|
|
233
|
+
${scenarios}
|
|
234
|
+
</section>`;
|
|
235
|
+
}
|
|
236
|
+
/** Build a self-contained HTML report for a completed suite run. */
|
|
237
|
+
export function renderHtmlReport(reports, meta = {}) {
|
|
238
|
+
const generatedAt = meta.generatedAt ?? new Date();
|
|
239
|
+
const totalPassed = reports.reduce((sum, report) => sum + report.passed, 0);
|
|
240
|
+
const totalFailed = reports.reduce((sum, report) => sum + report.failed, 0);
|
|
241
|
+
const totalSkipped = reports.reduce((sum, report) => sum + report.skipped, 0);
|
|
242
|
+
const host = meta.host ?? reports[0]?.host ?? "unknown";
|
|
243
|
+
const suitesHtml = reports.map(renderSuite).join("\n");
|
|
244
|
+
return `<!DOCTYPE html>
|
|
245
|
+
<html lang="en">
|
|
246
|
+
<head>
|
|
247
|
+
<meta charset="utf-8" />
|
|
248
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
249
|
+
<title>agent-test report</title>
|
|
250
|
+
<style>
|
|
251
|
+
:root {
|
|
252
|
+
--bg: #0f1419;
|
|
253
|
+
--panel: #1a2332;
|
|
254
|
+
--panel-2: #141c28;
|
|
255
|
+
--text: #e7ecf3;
|
|
256
|
+
--muted: #8b9bb4;
|
|
257
|
+
--border: #2a3548;
|
|
258
|
+
--pass: #3dd68c;
|
|
259
|
+
--fail: #f07178;
|
|
260
|
+
--skip: #ffcc66;
|
|
261
|
+
--user-bubble: #24406b;
|
|
262
|
+
--assistant-bubble: #1f2f26;
|
|
263
|
+
--system-bubble: #241f38;
|
|
264
|
+
--tool: #e0af68;
|
|
265
|
+
--tool-bubble: #2a2214;
|
|
266
|
+
}
|
|
267
|
+
* { box-sizing: border-box; }
|
|
268
|
+
body {
|
|
269
|
+
margin: 0;
|
|
270
|
+
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, sans-serif;
|
|
271
|
+
background: var(--bg);
|
|
272
|
+
color: var(--text);
|
|
273
|
+
line-height: 1.45;
|
|
274
|
+
}
|
|
275
|
+
main { max-width: 1180px; margin: 0 auto; padding: 1.25rem 1.25rem 3rem; }
|
|
276
|
+
h1 { font-size: 1.45rem; margin: 0; letter-spacing: -0.02em; }
|
|
277
|
+
h2 { font-size: 1.1rem; margin: 0; }
|
|
278
|
+
h3 { font-size: 0.78rem; margin: 0 0 0.5rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.07em; }
|
|
279
|
+
h4 { font-size: 0.72rem; margin: 0.9rem 0 0.35rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
|
|
280
|
+
.muted { color: var(--muted); }
|
|
281
|
+
.empty { color: var(--muted); font-size: 0.85rem; font-style: italic; margin: 0; }
|
|
282
|
+
.empty.note { margin-bottom: 0.5rem; }
|
|
283
|
+
.report-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.65rem; }
|
|
284
|
+
.report-kicker { color: var(--muted); font-size: 0.78rem; }
|
|
285
|
+
.summary {
|
|
286
|
+
background: var(--panel);
|
|
287
|
+
border: 1px solid var(--border);
|
|
288
|
+
border-radius: 10px;
|
|
289
|
+
padding: 0.7rem 0.9rem;
|
|
290
|
+
display: flex;
|
|
291
|
+
align-items: center;
|
|
292
|
+
justify-content: space-between;
|
|
293
|
+
gap: 1rem;
|
|
294
|
+
}
|
|
295
|
+
.stats { display: flex; gap: 0.45rem; align-items: center; }
|
|
296
|
+
.stat { padding: 0.3rem 0.55rem; border-radius: 6px; background: #111923; font-size: 0.8rem; }
|
|
297
|
+
.stat strong { font-size: 1rem; margin-right: 0.25rem; }
|
|
298
|
+
.stat-pass strong { color: var(--pass); }
|
|
299
|
+
.stat-fail strong { color: var(--fail); }
|
|
300
|
+
.stat-skip strong { color: var(--skip); }
|
|
301
|
+
.summary dl {
|
|
302
|
+
display: flex;
|
|
303
|
+
flex-wrap: wrap;
|
|
304
|
+
justify-content: flex-end;
|
|
305
|
+
gap: 0.15rem 1rem;
|
|
306
|
+
margin: 0;
|
|
307
|
+
font-size: 0.78rem;
|
|
308
|
+
}
|
|
309
|
+
.summary dt { color: var(--muted); margin-right: -0.7rem; }
|
|
310
|
+
.summary dd { margin: 0; }
|
|
311
|
+
.suite { margin-top: 1.25rem; }
|
|
312
|
+
.suite-header { display: flex; align-items: end; justify-content: space-between; margin: 0 0 0.5rem; padding: 0 0.2rem; }
|
|
313
|
+
.suite-header > div { display: flex; align-items: center; gap: 0.5rem; }
|
|
314
|
+
.host { color: var(--muted); font-size: 0.72rem; background: var(--panel); border: 1px solid var(--border); border-radius: 999px; padding: 0.1rem 0.4rem; }
|
|
315
|
+
.suite-counts { color: var(--muted); margin: 0; font-size: 0.78rem; }
|
|
316
|
+
details.scenario {
|
|
317
|
+
background: var(--panel);
|
|
318
|
+
border: 1px solid var(--border);
|
|
319
|
+
border-radius: 10px;
|
|
320
|
+
margin: 0.45rem 0;
|
|
321
|
+
overflow: hidden;
|
|
322
|
+
}
|
|
323
|
+
details.scenario summary {
|
|
324
|
+
cursor: pointer;
|
|
325
|
+
display: flex;
|
|
326
|
+
flex-wrap: wrap;
|
|
327
|
+
gap: 0.45rem 0.65rem;
|
|
328
|
+
align-items: center;
|
|
329
|
+
list-style: none;
|
|
330
|
+
padding: 0.55rem 0.7rem;
|
|
331
|
+
}
|
|
332
|
+
details.scenario[open] summary { border-bottom: 1px solid var(--border); background: #17202d; }
|
|
333
|
+
details.scenario summary::-webkit-details-marker { display: none; }
|
|
334
|
+
.scenario-name { font-weight: 600; font-size: 0.9rem; }
|
|
335
|
+
.duration { color: var(--muted); margin-left: auto; font-variant-numeric: tabular-nums; }
|
|
336
|
+
.badge {
|
|
337
|
+
display: inline-block;
|
|
338
|
+
font-size: 0.66rem;
|
|
339
|
+
font-weight: 700;
|
|
340
|
+
text-transform: uppercase;
|
|
341
|
+
letter-spacing: 0.04em;
|
|
342
|
+
padding: 0.1rem 0.4rem;
|
|
343
|
+
border-radius: 999px;
|
|
344
|
+
border: 1px solid transparent;
|
|
345
|
+
}
|
|
346
|
+
.status-passed { color: var(--pass); border-color: color-mix(in srgb, var(--pass) 40%, transparent); }
|
|
347
|
+
.status-failed { color: var(--fail); border-color: color-mix(in srgb, var(--fail) 40%, transparent); }
|
|
348
|
+
.status-skipped { color: var(--skip); border-color: color-mix(in srgb, var(--skip) 40%, transparent); }
|
|
349
|
+
.scenario-body { padding: 0.7rem; }
|
|
350
|
+
.diagnostics { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 0.7rem; margin-bottom: 0.9rem; }
|
|
351
|
+
.diagnostics section { background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px; padding: 0.65rem 0.7rem; min-width: 0; }
|
|
352
|
+
.conversation { min-width: 0; }
|
|
353
|
+
|
|
354
|
+
.failures { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
|
|
355
|
+
.failures li { border-left: 3px solid var(--fail); padding-left: 0.6rem; }
|
|
356
|
+
.failure-label { margin: 0; font-weight: 600; font-size: 0.85rem; color: var(--fail); }
|
|
357
|
+
.failure-hint { margin: 0.1rem 0 0; font-size: 0.78rem; color: var(--muted); }
|
|
358
|
+
.failure-message { margin: 0.3rem 0 0; font-size: 0.82rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre-wrap; word-break: break-word; background: #0b1017; border: 1px solid var(--border); border-radius: 6px; padding: 0.45rem 0.55rem; }
|
|
359
|
+
|
|
360
|
+
.verdicts { display: flex; flex-direction: column; gap: 0.55rem; }
|
|
361
|
+
.verdict { border-left: 3px solid var(--border); padding-left: 0.6rem; }
|
|
362
|
+
.verdict-pass { border-left-color: var(--pass); }
|
|
363
|
+
.verdict-fail { border-left-color: var(--fail); }
|
|
364
|
+
.verdict-icon { display: inline-block; width: 1.1rem; font-weight: 700; }
|
|
365
|
+
.verdict-pass .verdict-icon { color: var(--pass); }
|
|
366
|
+
.verdict-fail .verdict-icon { color: var(--fail); }
|
|
367
|
+
.question { margin: 0; font-size: 0.85rem; font-weight: 600; }
|
|
368
|
+
.rationale { margin: 0.3rem 0 0; font-size: 0.82rem; color: var(--muted); }
|
|
369
|
+
|
|
370
|
+
.chat { display: flex; flex-direction: column; gap: 0.5rem; }
|
|
371
|
+
.chat-row { display: flex; }
|
|
372
|
+
.chat-row.side-left { justify-content: flex-start; }
|
|
373
|
+
.chat-row.side-right { justify-content: flex-end; }
|
|
374
|
+
.chat-row.side-center { justify-content: center; }
|
|
375
|
+
.bubble { max-width: 78%; border-radius: 12px; padding: 0.5rem 0.7rem; border: 1px solid var(--border); }
|
|
376
|
+
.bubble-label { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin-bottom: 0.25rem; }
|
|
377
|
+
.bubble-text { white-space: pre-wrap; word-break: break-word; font-size: 0.85rem; }
|
|
378
|
+
.bubble.role-user { background: var(--user-bubble); border-top-right-radius: 3px; }
|
|
379
|
+
.bubble.role-assistant { background: var(--assistant-bubble); border-top-left-radius: 3px; }
|
|
380
|
+
.bubble.role-system, .bubble.role-tool { background: var(--system-bubble); font-size: 0.8rem; max-width: 90%; }
|
|
381
|
+
|
|
382
|
+
.tool-card {
|
|
383
|
+
max-width: 82%;
|
|
384
|
+
border-radius: 10px;
|
|
385
|
+
padding: 0.5rem 0.65rem;
|
|
386
|
+
border: 1px solid color-mix(in srgb, var(--tool) 35%, var(--border));
|
|
387
|
+
background: var(--tool-bubble);
|
|
388
|
+
}
|
|
389
|
+
.tool-card-head {
|
|
390
|
+
display: flex;
|
|
391
|
+
align-items: center;
|
|
392
|
+
gap: 0.4rem;
|
|
393
|
+
font-size: 0.8rem;
|
|
394
|
+
font-weight: 700;
|
|
395
|
+
color: var(--tool);
|
|
396
|
+
}
|
|
397
|
+
.tool-icon { font-size: 0.85rem; }
|
|
398
|
+
.tool-name { font-weight: 700; }
|
|
399
|
+
.tool-args {
|
|
400
|
+
margin-top: 0.4rem;
|
|
401
|
+
display: flex;
|
|
402
|
+
flex-direction: column;
|
|
403
|
+
gap: 0.25rem;
|
|
404
|
+
padding-top: 0.4rem;
|
|
405
|
+
border-top: 1px solid color-mix(in srgb, var(--tool) 20%, var(--border));
|
|
406
|
+
}
|
|
407
|
+
.tool-arg { display: flex; gap: 0.5rem; align-items: baseline; font-size: 0.78rem; }
|
|
408
|
+
.tool-arg-key { color: var(--muted); flex-shrink: 0; }
|
|
409
|
+
.tool-arg code {
|
|
410
|
+
color: var(--text);
|
|
411
|
+
background: #0b1017;
|
|
412
|
+
border-radius: 4px;
|
|
413
|
+
padding: 0.05rem 0.35rem;
|
|
414
|
+
word-break: break-word;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.shell-commands { margin: 0; padding-left: 0; list-style: none; display: flex; flex-direction: column; gap: 0.3rem; }
|
|
418
|
+
.shell-commands li { font-size: 0.8rem; background: #0b1017; border: 1px solid var(--border); border-radius: 6px; padding: 0.3rem 0.5rem; }
|
|
419
|
+
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85em; }
|
|
420
|
+
@media (max-width: 720px) {
|
|
421
|
+
main { padding: 0.75rem; }
|
|
422
|
+
.summary { align-items: flex-start; flex-direction: column; }
|
|
423
|
+
.summary dl { justify-content: flex-start; }
|
|
424
|
+
.suite-header { align-items: flex-start; flex-direction: column; gap: 0.2rem; }
|
|
425
|
+
.diagnostics { grid-template-columns: 1fr; }
|
|
426
|
+
.bubble, .tool-card { max-width: 92%; }
|
|
427
|
+
}
|
|
428
|
+
</style>
|
|
429
|
+
</head>
|
|
430
|
+
<body>
|
|
431
|
+
<main>
|
|
432
|
+
<header class="report-header">
|
|
433
|
+
<h1>agent-test report</h1>
|
|
434
|
+
<span class="report-kicker">${reports.length} suite${reports.length === 1 ? "" : "s"}</span>
|
|
435
|
+
</header>
|
|
436
|
+
<div class="summary">
|
|
437
|
+
<div class="stats">
|
|
438
|
+
<span class="stat stat-pass"><strong>${totalPassed}</strong> passed</span>
|
|
439
|
+
<span class="stat stat-fail"><strong>${totalFailed}</strong> failed</span>
|
|
440
|
+
<span class="stat stat-skip"><strong>${totalSkipped}</strong> skipped</span>
|
|
441
|
+
</div>
|
|
442
|
+
<dl>
|
|
443
|
+
<dt>Host</dt><dd>${escapeHtml(String(host))}</dd>
|
|
444
|
+
<dt>Generated</dt><dd>${escapeHtml(generatedAt.toISOString())}</dd>
|
|
445
|
+
${meta.suitesDir ? `<dt>Suites</dt><dd>${escapeHtml(meta.suitesDir)}</dd>` : ""}
|
|
446
|
+
</dl>
|
|
447
|
+
</div>
|
|
448
|
+
${suitesHtml}
|
|
449
|
+
</main>
|
|
450
|
+
</body>
|
|
451
|
+
</html>
|
|
452
|
+
`;
|
|
453
|
+
}
|
|
454
|
+
/** Write an HTML report under a fresh temp directory; returns the report file path. */
|
|
455
|
+
export async function writeHtmlReport(reports, meta = {}) {
|
|
456
|
+
const dir = await mkdtemp(join(tmpdir(), "agent-test-report-"));
|
|
457
|
+
const path = join(dir, "report.html");
|
|
458
|
+
const html = renderHtmlReport(reports, meta);
|
|
459
|
+
await writeFile(path, html, "utf8");
|
|
460
|
+
return path;
|
|
461
|
+
}
|
|
462
|
+
//# sourceMappingURL=html-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-report.js","sourceRoot":"","sources":["../src/html-report.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { assertRubric, expectTrace, TraceAssertion } from "./expect.js";
|
|
2
|
+
export { type HtmlReportMeta, renderHtmlReport, writeHtmlReport } from "./html-report.js";
|
|
2
3
|
export { loadSuiteFile } from "./load-suite.js";
|
|
3
4
|
export { assertLiveDogfoodPreflight } from "./preflight.js";
|
|
4
|
-
export { cleanupLegacyRepoRecordings, cleanupStagingSession, createLiveStagingSessionId, getLiveStagingRoot, getLiveStagingSessionRoot, type RecordingPathKind, type ResolvedRecordingPath, recordTrace, resolveRecordingPath, } from "./record-trace.js";
|
|
5
|
+
export { cleanupLegacyRepoRecordings, cleanupStagingSession, createLiveStagingSessionId, getLiveStagingRoot, getLiveStagingSessionRoot, getStagingResultPath, type LiveScenarioResultSidecar, loadStagingResult, type RecordingPathKind, type ResolvedRecordingPath, recordTrace, resolveRecordingPath, writeStagingResult, } from "./record-trace.js";
|
|
5
6
|
export { discoverSuites, type RunSuiteOptions, runAllSuites, runSuite, } from "./run-suite.js";
|
|
6
7
|
export type { AgentScenario, AgentSuiteFile, AssertionFailure, JudgeRubricItem, JudgeVerdictResult, ScenarioResult, ScenarioRubric, SuiteRunReport, } from "./types.js";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,KAAK,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EACN,2BAA2B,EAC3B,qBAAqB,EACrB,0BAA0B,EAC1B,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,WAAW,EACX,oBAAoB,EACpB,kBAAkB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,cAAc,EACd,KAAK,eAAe,EACpB,YAAY,EACZ,QAAQ,GACR,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,cAAc,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { assertRubric, expectTrace, TraceAssertion } from "./expect.js";
|
|
2
|
+
export { renderHtmlReport, writeHtmlReport } from "./html-report.js";
|
|
2
3
|
export { loadSuiteFile } from "./load-suite.js";
|
|
3
4
|
export { assertLiveDogfoodPreflight } from "./preflight.js";
|
|
4
|
-
export { cleanupLegacyRepoRecordings, cleanupStagingSession, createLiveStagingSessionId, getLiveStagingRoot, getLiveStagingSessionRoot, recordTrace, resolveRecordingPath, } from "./record-trace.js";
|
|
5
|
+
export { cleanupLegacyRepoRecordings, cleanupStagingSession, createLiveStagingSessionId, getLiveStagingRoot, getLiveStagingSessionRoot, getStagingResultPath, loadStagingResult, recordTrace, resolveRecordingPath, writeStagingResult, } from "./record-trace.js";
|
|
5
6
|
export { discoverSuites, runAllSuites, runSuite, } from "./run-suite.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAuB,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EACN,2BAA2B,EAC3B,qBAAqB,EACrB,0BAA0B,EAC1B,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EAEpB,iBAAiB,EAGjB,WAAW,EACX,oBAAoB,EACpB,kBAAkB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,cAAc,EAEd,YAAY,EACZ,QAAQ,GACR,MAAM,gBAAgB,CAAC"}
|
package/dist/live-isolation.d.ts
CHANGED
|
@@ -16,6 +16,12 @@ export interface SpawnLiveScenarioOptions {
|
|
|
16
16
|
scenarioIndex?: number;
|
|
17
17
|
/** Total scenarios in the full suite (for child CLI counters). */
|
|
18
18
|
scenarioTotal?: number;
|
|
19
|
+
/** In-process harness timeout (parent adds a kill backstop). */
|
|
20
|
+
timeoutMs?: number;
|
|
21
|
+
/** Disable harness deadline in the child (forwards --no-timeout). */
|
|
22
|
+
noTimeout?: boolean;
|
|
23
|
+
/** Allow AskQuestion-style tools (default false — live is single-shot). */
|
|
24
|
+
allowUserInput?: boolean;
|
|
19
25
|
}
|
|
20
26
|
export interface LiveScenarioCommand {
|
|
21
27
|
command: string;
|
|
@@ -24,9 +30,26 @@ export interface LiveScenarioCommand {
|
|
|
24
30
|
}
|
|
25
31
|
/** Build the Node subprocess command for one live scenario (same CLI entry as the parent). */
|
|
26
32
|
export declare function buildLiveScenarioCommand(options: SpawnLiveScenarioOptions): LiveScenarioCommand;
|
|
33
|
+
/** Delay from agent-start marker until parent SIGTERM (harness deadline + cleanup slack). */
|
|
34
|
+
export declare function subprocessKillDelayMs(agentStartMs: number, agentTimeoutMs: number): number;
|
|
27
35
|
/** Run one live scenario in a fresh Node subprocess; inherit stdio for live progress. */
|
|
28
36
|
export declare function spawnLiveScenario(options: SpawnLiveScenarioOptions): Promise<number>;
|
|
29
37
|
export declare function subprocessFailureMessage(exitCode: number): string;
|
|
38
|
+
export interface LiveSubprocessStagingResult {
|
|
39
|
+
passed: boolean;
|
|
40
|
+
failures: Array<{
|
|
41
|
+
matcher: string;
|
|
42
|
+
message: string;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Map isolated child exit + optional staging sidecar to parent failures.
|
|
47
|
+
* A persisted pass sidecar wins over a late timeout kill (exit 124).
|
|
48
|
+
*/
|
|
49
|
+
export declare function failuresForLiveSubprocessExit(exitCode: number, childResult: LiveSubprocessStagingResult | undefined): Array<{
|
|
50
|
+
matcher: string;
|
|
51
|
+
message: string;
|
|
52
|
+
}>;
|
|
30
53
|
/** Parent-provided counters for isolated child runs (1-based index). */
|
|
31
54
|
export declare function parentScenarioCounters(): {
|
|
32
55
|
index: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-isolation.d.ts","sourceRoot":"","sources":["../src/live-isolation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"live-isolation.d.ts","sourceRoot":"","sources":["../src/live-isolation.ts"],"names":[],"mappings":"AAYA,mGAAmG;AACnG,wBAAgB,4BAA4B,IAAI,OAAO,CAEtD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAIzC;AAED,MAAM,WAAW,wBAAwB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,8FAA8F;AAC9F,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,wBAAwB,GAAG,mBAAmB,CAsC/F;AA4BD,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAE1F;AAED,yFAAyF;AACzF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgH1F;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQjE;AAED,MAAM,WAAW,2BAA2B;IAC3C,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtD;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC5C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,2BAA2B,GAAG,SAAS,GAClD,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB7C;AAED,wEAAwE;AACxE,wBAAgB,sBAAsB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAOrF"}
|