personal-agent-benchmark 0.0.0-stage → 0.2.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/README.md +128 -2
- package/bin/pab.js +5 -0
- package/dist/src/browser.d.ts +29 -0
- package/dist/src/browser.js +37 -0
- package/dist/src/browser.js.map +1 -0
- package/dist/src/cli.d.ts +20 -0
- package/dist/src/cli.js +331 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/core/archive.d.ts +49 -0
- package/dist/src/core/archive.js +213 -0
- package/dist/src/core/archive.js.map +1 -0
- package/dist/src/core/audit.d.ts +15 -0
- package/dist/src/core/audit.js +85 -0
- package/dist/src/core/audit.js.map +1 -0
- package/dist/src/core/bundle.d.ts +42 -0
- package/dist/src/core/bundle.js +80 -0
- package/dist/src/core/bundle.js.map +1 -0
- package/dist/src/core/lookup.d.ts +15 -0
- package/dist/src/core/lookup.js +82 -0
- package/dist/src/core/lookup.js.map +1 -0
- package/dist/src/core/normalize.d.ts +45 -0
- package/dist/src/core/normalize.js +143 -0
- package/dist/src/core/normalize.js.map +1 -0
- package/dist/src/core/rules.d.ts +38 -0
- package/dist/src/core/rules.js +187 -0
- package/dist/src/core/rules.js.map +1 -0
- package/dist/src/core/store.d.ts +26 -0
- package/dist/src/core/store.js +78 -0
- package/dist/src/core/store.js.map +1 -0
- package/dist/src/core/types.d.ts +125 -0
- package/dist/src/core/types.js +3 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/core/util.d.ts +21 -0
- package/dist/src/core/util.js +150 -0
- package/dist/src/core/util.js.map +1 -0
- package/dist/src/core/warc.d.ts +55 -0
- package/dist/src/core/warc.js +258 -0
- package/dist/src/core/warc.js.map +1 -0
- package/dist/src/core/writer.d.ts +26 -0
- package/dist/src/core/writer.js +119 -0
- package/dist/src/core/writer.js.map +1 -0
- package/dist/src/grading.d.ts +63 -0
- package/dist/src/grading.js +173 -0
- package/dist/src/grading.js.map +1 -0
- package/dist/src/judge.d.ts +25 -0
- package/dist/src/judge.js +119 -0
- package/dist/src/judge.js.map +1 -0
- package/dist/src/paths.d.ts +2 -0
- package/dist/src/paths.js +40 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/replay/clock.d.ts +19 -0
- package/dist/src/replay/clock.js +60 -0
- package/dist/src/replay/clock.js.map +1 -0
- package/dist/src/replay/engine.d.ts +53 -0
- package/dist/src/replay/engine.js +280 -0
- package/dist/src/replay/engine.js.map +1 -0
- package/dist/src/replay/launcher.d.ts +36 -0
- package/dist/src/replay/launcher.js +163 -0
- package/dist/src/replay/launcher.js.map +1 -0
- package/dist/src/replay/whistle-plugin.d.ts +24 -0
- package/dist/src/replay/whistle-plugin.js +82 -0
- package/dist/src/replay/whistle-plugin.js.map +1 -0
- package/dist/src/report.d.ts +3 -0
- package/dist/src/report.js +143 -0
- package/dist/src/report.js.map +1 -0
- package/dist/src/scoring.d.ts +87 -0
- package/dist/src/scoring.js +232 -0
- package/dist/src/scoring.js.map +1 -0
- package/dist/src/tasks.d.ts +61 -0
- package/dist/src/tasks.js +152 -0
- package/dist/src/tasks.js.map +1 -0
- package/docs/bundle-format.md +114 -0
- package/docs/deploy.md +78 -0
- package/docs/grading.md +81 -0
- package/docs/site-rules.md +114 -0
- package/docs/tasks.md +63 -0
- package/package.json +121 -4
- package/plugins/whistle.bench-replay/index.js +1 -0
- package/plugins/whistle.bench-replay/package.json +7 -0
- package/sites/_default.yaml +80 -0
- package/sites/amazon.com.yaml +125 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderReport = renderReport;
|
|
4
|
+
/** report.html: a self-contained page rendered from result.json. */
|
|
5
|
+
function renderReport(r) {
|
|
6
|
+
const title = r.task.title ?? r.task.id;
|
|
7
|
+
const required = r.items.filter((i) => i.required);
|
|
8
|
+
const weighted = r.items.filter((i) => !i.required);
|
|
9
|
+
const score = r.score === undefined ? 'not graded' : `${Math.round(r.score * 1000) / 10}%`;
|
|
10
|
+
const summary = [
|
|
11
|
+
required.length ? `required ${required.filter((i) => i.passed).length}/${required.length}` : '',
|
|
12
|
+
weighted.length ? `weighted ${weighted.filter((i) => i.passed).length}/${weighted.length}` : '',
|
|
13
|
+
`${r.pages.not_found.length} page${r.pages.not_found.length === 1 ? '' : 's'} returned 404`,
|
|
14
|
+
].filter(Boolean);
|
|
15
|
+
return `<!doctype html>
|
|
16
|
+
<html lang="en">
|
|
17
|
+
<head>
|
|
18
|
+
<meta charset="utf-8">
|
|
19
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
20
|
+
<title>${esc(title)} - run report</title>
|
|
21
|
+
<style>${CSS}</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<main>
|
|
25
|
+
<header>
|
|
26
|
+
<p class="eyebrow">${esc(r.task.id)}</p>
|
|
27
|
+
<h1>${esc(title)}</h1>
|
|
28
|
+
<p class="meta">graded ${esc(r.graded_at)}${r.grader ? ` by ${esc(r.grader.model)} (${esc(r.grader.via)})` : ''}${r.replay_log ? ` · replay log ${esc(r.replay_log)}` : ''}</p>
|
|
29
|
+
</header>
|
|
30
|
+
<section class="score ${r.score === undefined ? 'none' : r.score > 0 ? 'ok' : 'bad'}">
|
|
31
|
+
<div class="big">${esc(score)}</div>
|
|
32
|
+
<div>${summary.map(esc).join(' · ')}</div>
|
|
33
|
+
</section>
|
|
34
|
+
${r.notes.map((n) => `<p class="note">${esc(n)}</p>`).join('\n')}
|
|
35
|
+
<section>
|
|
36
|
+
<h2>Pages that returned 404 <span class="count">${r.pages.not_found.length}</span></h2>
|
|
37
|
+
<p class="hint">Pages the agent opened in a tab during the replay (not frames, scripts or styles) that came back 404. "not recorded": the recording has no copy, so recording it would let the agent see it. "recorded as 404": the site itself answered 404 while recording.</p>
|
|
38
|
+
${r.pages.not_found.length ? pageTable(r.pages.not_found, false) : '<p class="empty">None.</p>'}
|
|
39
|
+
</section>
|
|
40
|
+
${r.items.length ? `<section>
|
|
41
|
+
<h2>Items</h2>
|
|
42
|
+
<div class="table"><table>
|
|
43
|
+
<thead><tr><th>Result</th><th>Item</th><th>Test</th><th>Reason</th></tr></thead>
|
|
44
|
+
<tbody>${r.items.map(itemRow).join('')}</tbody>
|
|
45
|
+
</table></div>
|
|
46
|
+
</section>` : ''}
|
|
47
|
+
${Object.keys(r.fields).length ? `<section>
|
|
48
|
+
<h2>Extracted fields</h2>
|
|
49
|
+
<div class="table"><table>
|
|
50
|
+
<thead><tr><th>Field</th><th>Value</th></tr></thead>
|
|
51
|
+
<tbody>${Object.entries(r.fields).map(([k, v]) => `<tr><td><code>${esc(k)}</code></td><td>${v === null ? '<span class="muted">not stated</span>' : esc(JSON.stringify(v))}</td></tr>`).join('')}</tbody>
|
|
52
|
+
</table></div>
|
|
53
|
+
</section>` : ''}
|
|
54
|
+
<section>
|
|
55
|
+
<details>
|
|
56
|
+
<summary><h2>All pages opened <span class="count">${r.pages.opened.length}</span></h2></summary>
|
|
57
|
+
${r.pages.opened.length ? pageTable(r.pages.opened, true) : '<p class="empty">None.</p>'}
|
|
58
|
+
</details>
|
|
59
|
+
</section>
|
|
60
|
+
${r.answer !== undefined ? `<section>
|
|
61
|
+
<h2>Agent answer</h2>
|
|
62
|
+
<pre class="answer">${esc(r.answer)}</pre>
|
|
63
|
+
</section>` : ''}
|
|
64
|
+
${r.task.prompt ? `<section>
|
|
65
|
+
<details>
|
|
66
|
+
<summary><h2>Task</h2></summary>
|
|
67
|
+
<pre class="answer">${esc(r.task.prompt)}</pre>
|
|
68
|
+
</details>
|
|
69
|
+
</section>` : ''}
|
|
70
|
+
</main>
|
|
71
|
+
</body>
|
|
72
|
+
</html>
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
function itemRow(i) {
|
|
76
|
+
const tag = i.required ? 'required' : `weight ${i.weight}`;
|
|
77
|
+
return `<tr class="${i.passed ? 'pass' : 'fail'}">
|
|
78
|
+
<td><span class="badge">${i.passed ? 'pass' : 'fail'}</span></td>
|
|
79
|
+
<td><code>${esc(i.id)}</code><div class="muted">${esc(i.kind)} · ${esc(tag)}</div></td>
|
|
80
|
+
<td>${esc(i.test)}</td>
|
|
81
|
+
<td>${esc(i.reason)}</td>
|
|
82
|
+
</tr>`;
|
|
83
|
+
}
|
|
84
|
+
const SOURCE = { miss: 'not recorded', blocked: 'blocked by a rule' };
|
|
85
|
+
function pageTable(pages, all) {
|
|
86
|
+
const rows = pages.map((p) => {
|
|
87
|
+
const how = p.status === 404 ? (p.source === 'miss' ? 'not recorded' : 'recorded as 404') : SOURCE[p.source] ?? p.source;
|
|
88
|
+
return `<tr${p.status === 404 ? ' class="fail"' : ''}>
|
|
89
|
+
${all ? `<td>${p.status}</td>` : ''}
|
|
90
|
+
<td>${esc(p.site)}</td>
|
|
91
|
+
<td><div class="route">${p.method === 'GET' ? '' : `${esc(p.method)} `}${esc(p.route)}</div><div class="url muted">${esc(p.url)}</div></td>
|
|
92
|
+
<td class="num">${p.count}</td>
|
|
93
|
+
<td class="nowrap">${esc(how)}</td>
|
|
94
|
+
<td class="muted nowrap">${esc(p.first.slice(11, 19))}</td>
|
|
95
|
+
</tr>`;
|
|
96
|
+
});
|
|
97
|
+
return `<div class="table"><table>
|
|
98
|
+
<thead><tr>${all ? '<th>Status</th>' : ''}<th>Site</th><th>Route</th><th>Times</th><th>${all ? 'Answered' : 'Why'}</th><th>First</th></tr></thead>
|
|
99
|
+
<tbody>${rows.join('')}</tbody>
|
|
100
|
+
</table></div>`;
|
|
101
|
+
}
|
|
102
|
+
function esc(s) {
|
|
103
|
+
return String(s).replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' })[c]);
|
|
104
|
+
}
|
|
105
|
+
const CSS = `
|
|
106
|
+
:root { --bg: #fafaf9; --panel: #ffffff; --text: #1c1917; --muted: #78716c; --line: #e7e5e4; --ok: #15803d; --ok-bg: #f0fdf4; --bad: #b91c1c; --bad-bg: #fef2f2; --none-bg: #f5f5f4; --code: #f5f5f4; }
|
|
107
|
+
@media (prefers-color-scheme: dark) { :root { --bg: #1c1917; --panel: #262220; --text: #f5f5f4; --muted: #a8a29e; --line: #3a3532; --ok: #4ade80; --ok-bg: #14261b; --bad: #f87171; --bad-bg: #2d1717; --none-bg: #292524; --code: #322d2a; } }
|
|
108
|
+
* { box-sizing: border-box; }
|
|
109
|
+
body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
|
|
110
|
+
main { max-width: 1120px; margin: 0 auto; padding: 32px 16px 64px; }
|
|
111
|
+
h1 { font-size: 24px; margin: 4px 0 6px; }
|
|
112
|
+
h2 { font-size: 17px; margin: 0 0 8px; display: inline-block; }
|
|
113
|
+
section { margin-top: 28px; }
|
|
114
|
+
.eyebrow { margin: 0; color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
|
|
115
|
+
.meta, .hint, .muted { color: var(--muted); }
|
|
116
|
+
.meta { margin: 0; font-size: 12px; word-break: break-all; }
|
|
117
|
+
.hint { margin: 0 0 10px; font-size: 13px; }
|
|
118
|
+
.score { display: flex; gap: 20px; align-items: baseline; flex-wrap: wrap; padding: 16px 20px; border-radius: 10px; border: 1px solid var(--line); }
|
|
119
|
+
.score.ok { background: var(--ok-bg); } .score.bad { background: var(--bad-bg); } .score.none { background: var(--none-bg); }
|
|
120
|
+
.score .big { font-size: 32px; font-weight: 650; font-variant-numeric: tabular-nums; }
|
|
121
|
+
.score.ok .big { color: var(--ok); } .score.bad .big { color: var(--bad); }
|
|
122
|
+
.note { margin: 12px 0 0; padding: 10px 14px; border-left: 3px solid var(--bad); background: var(--panel); }
|
|
123
|
+
.count { display: inline-block; min-width: 22px; padding: 0 7px; margin-left: 4px; border-radius: 11px; background: var(--code); color: var(--muted); font-size: 12px; text-align: center; vertical-align: 2px; }
|
|
124
|
+
.table { overflow-x: auto; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; }
|
|
125
|
+
table { width: 100%; border-collapse: collapse; }
|
|
126
|
+
td.nowrap, .nowrap { white-space: nowrap; }
|
|
127
|
+
th, td { text-align: left; vertical-align: top; padding: 8px 10px; border-bottom: 1px solid var(--line); }
|
|
128
|
+
th { font-size: 12px; font-weight: 600; color: var(--muted); white-space: nowrap; }
|
|
129
|
+
tbody tr:last-child td { border-bottom: 0; }
|
|
130
|
+
td.num { text-align: right; font-variant-numeric: tabular-nums; }
|
|
131
|
+
.route { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; word-break: break-all; }
|
|
132
|
+
.url { font-size: 11.5px; word-break: break-all; margin-top: 2px; }
|
|
133
|
+
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; background: var(--code); padding: 1px 5px; border-radius: 4px; }
|
|
134
|
+
.badge { display: inline-block; padding: 1px 8px; border-radius: 10px; font-size: 12px; font-weight: 600; }
|
|
135
|
+
tr.pass .badge { color: var(--ok); background: var(--ok-bg); }
|
|
136
|
+
tr.fail .badge { color: var(--bad); background: var(--bad-bg); }
|
|
137
|
+
tr.fail td:first-child { box-shadow: inset 3px 0 0 var(--bad); }
|
|
138
|
+
.empty { color: var(--muted); margin: 0; }
|
|
139
|
+
details > summary { cursor: pointer; list-style-position: outside; margin-left: 16px; }
|
|
140
|
+
details[open] > summary { margin-bottom: 8px; }
|
|
141
|
+
pre.answer { white-space: pre-wrap; word-break: break-word; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px; margin: 0; font: 13px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
142
|
+
`;
|
|
143
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { RuleSet } from './core/rules';
|
|
2
|
+
import type { Grading } from './grading';
|
|
3
|
+
import type { Judge } from './judge';
|
|
4
|
+
/**
|
|
5
|
+
* Scores one agent run (docs/grading.md) and lists the pages the agent opened in the replay, so
|
|
6
|
+
* pages that came back 404 can be added to the recording.
|
|
7
|
+
*/
|
|
8
|
+
/** A line of the replay request log (ReplayEngine.record). */
|
|
9
|
+
export interface LogLine {
|
|
10
|
+
t: string;
|
|
11
|
+
method: string;
|
|
12
|
+
url: string;
|
|
13
|
+
key: string;
|
|
14
|
+
class: string;
|
|
15
|
+
/** sec-fetch-dest; absent in logs written before it was recorded and for non-browser clients. */
|
|
16
|
+
dest?: string;
|
|
17
|
+
source: string;
|
|
18
|
+
status: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ItemResult {
|
|
21
|
+
kind: 'require' | 'check' | 'trace';
|
|
22
|
+
id: string;
|
|
23
|
+
/** What was tested: the question, the expected value or the request. */
|
|
24
|
+
test: string;
|
|
25
|
+
required: boolean;
|
|
26
|
+
weight?: number;
|
|
27
|
+
passed: boolean;
|
|
28
|
+
reason: string;
|
|
29
|
+
}
|
|
30
|
+
/** A page (one normalized key) opened in a browser tab during the replay. */
|
|
31
|
+
export interface PageResult {
|
|
32
|
+
site: string;
|
|
33
|
+
/** The normalized key without its method: host, path and the query parameters that matter. */
|
|
34
|
+
route: string;
|
|
35
|
+
method: string;
|
|
36
|
+
/** The first URL the agent opened for it. */
|
|
37
|
+
url: string;
|
|
38
|
+
count: number;
|
|
39
|
+
status: number;
|
|
40
|
+
/** How replay answered: exact, fuzzy, search, promo, blocked, or miss (not in the recording). */
|
|
41
|
+
source: string;
|
|
42
|
+
first: string;
|
|
43
|
+
}
|
|
44
|
+
export interface RunResult {
|
|
45
|
+
task: {
|
|
46
|
+
id: string;
|
|
47
|
+
title?: string;
|
|
48
|
+
prompt?: string;
|
|
49
|
+
};
|
|
50
|
+
graded_at: string;
|
|
51
|
+
replay_log?: string;
|
|
52
|
+
answer?: string;
|
|
53
|
+
grader?: {
|
|
54
|
+
via: string;
|
|
55
|
+
model: string;
|
|
56
|
+
};
|
|
57
|
+
/** 0 to 1; absent when the run could not be graded (see notes). */
|
|
58
|
+
score?: number;
|
|
59
|
+
fields: Record<string, unknown>;
|
|
60
|
+
items: ItemResult[];
|
|
61
|
+
/** Pages in browser tabs, not frames, scripts or styles. not_found: those answered with 404. */
|
|
62
|
+
pages: {
|
|
63
|
+
opened: PageResult[];
|
|
64
|
+
not_found: PageResult[];
|
|
65
|
+
};
|
|
66
|
+
notes: string[];
|
|
67
|
+
}
|
|
68
|
+
export interface RunInput {
|
|
69
|
+
task: RunResult['task'];
|
|
70
|
+
grading?: Grading;
|
|
71
|
+
answer?: string;
|
|
72
|
+
log: LogLine[];
|
|
73
|
+
logFile?: string;
|
|
74
|
+
rules: RuleSet;
|
|
75
|
+
/** Each site's recorded 404 page (manifest not_found): recorder probes, not pages anyone opened. */
|
|
76
|
+
probes?: string[];
|
|
77
|
+
judge?: Judge;
|
|
78
|
+
}
|
|
79
|
+
export declare function scoreRun(input: RunInput): Promise<RunResult>;
|
|
80
|
+
/** 0 when a required item failed; otherwise the passed share of the weighted checks, or 1. */
|
|
81
|
+
export declare function score(items: ItemResult[]): number;
|
|
82
|
+
/** Writes result.json and report.html (rendered from it) into `dir`. */
|
|
83
|
+
export declare function writeRun(result: RunResult, dir: string): {
|
|
84
|
+
json: string;
|
|
85
|
+
html: string;
|
|
86
|
+
};
|
|
87
|
+
export declare function isPage(r: LogLine): boolean;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.scoreRun = scoreRun;
|
|
37
|
+
exports.score = score;
|
|
38
|
+
exports.writeRun = writeRun;
|
|
39
|
+
exports.isPage = isPage;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
|
+
const util_1 = require("./core/util");
|
|
43
|
+
const report_1 = require("./report");
|
|
44
|
+
async function scoreRun(input) {
|
|
45
|
+
const { grading, answer } = input;
|
|
46
|
+
const result = {
|
|
47
|
+
task: input.task,
|
|
48
|
+
graded_at: new Date().toISOString(),
|
|
49
|
+
replay_log: input.logFile,
|
|
50
|
+
answer,
|
|
51
|
+
fields: {},
|
|
52
|
+
items: [],
|
|
53
|
+
pages: pagesOf(input.log, input.rules, new Set(input.probes ?? [])),
|
|
54
|
+
notes: [],
|
|
55
|
+
};
|
|
56
|
+
if (!grading) {
|
|
57
|
+
result.notes.push('not graded: the task has no grading.yaml');
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
if (answer === undefined) {
|
|
61
|
+
result.notes.push('not graded: no answer was given (--answer)');
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
const extract = grading.extract ?? {};
|
|
65
|
+
const checks = grading.checks ?? [];
|
|
66
|
+
let reply = { fields: {}, checks: {} };
|
|
67
|
+
if (Object.keys(extract).length || checks.length) {
|
|
68
|
+
if (!input.judge)
|
|
69
|
+
throw new Error('grading needs a judge');
|
|
70
|
+
result.grader = { via: input.judge.via, model: input.judge.model };
|
|
71
|
+
try {
|
|
72
|
+
const asked = await input.judge.ask(judgeRequest(input.task, grading, answer));
|
|
73
|
+
reply = asked.output;
|
|
74
|
+
result.grader.model = asked.model;
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
result.notes.push(`not graded: the grader failed (${err.message})`);
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
result.fields = reply.fields ?? {};
|
|
82
|
+
for (const r of grading.require ?? []) {
|
|
83
|
+
const type = extract[r.field]?.type ?? 'text';
|
|
84
|
+
result.items.push({ kind: 'require', id: r.field, test: describe(r), required: true, ...compare(r, type, result.fields[r.field]) });
|
|
85
|
+
}
|
|
86
|
+
for (const c of checks) {
|
|
87
|
+
const got = reply.checks?.[c.id];
|
|
88
|
+
const weighted = c.weight !== undefined;
|
|
89
|
+
result.items.push({
|
|
90
|
+
kind: 'check',
|
|
91
|
+
id: c.id,
|
|
92
|
+
test: c.question,
|
|
93
|
+
required: !weighted,
|
|
94
|
+
...(weighted ? { weight: c.weight } : {}),
|
|
95
|
+
passed: got?.pass === true,
|
|
96
|
+
reason: got?.reason ?? 'the grader gave no answer',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
for (const t of grading.trace ?? []) {
|
|
100
|
+
const rule = (t.must ?? t.must_not);
|
|
101
|
+
const found = input.log.filter((r) => matches(r, rule));
|
|
102
|
+
const first = found[0] && `${found[0].method} ${found[0].url}${found.length > 1 ? ` (and ${found.length - 1} more)` : ''}`;
|
|
103
|
+
const passed = t.must ? found.length > 0 : found.length === 0;
|
|
104
|
+
result.items.push({ kind: 'trace', id: t.id, test: `${t.must ? 'must' : 'must not'} request ${matchText(rule)}`, required: true, passed, reason: first ?? 'no such request' });
|
|
105
|
+
}
|
|
106
|
+
result.score = score(result.items);
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/** 0 when a required item failed; otherwise the passed share of the weighted checks, or 1. */
|
|
110
|
+
function score(items) {
|
|
111
|
+
if (items.some((i) => i.required && !i.passed))
|
|
112
|
+
return 0;
|
|
113
|
+
const weighted = items.filter((i) => i.weight !== undefined);
|
|
114
|
+
const total = weighted.reduce((s, i) => s + i.weight, 0);
|
|
115
|
+
return total ? weighted.filter((i) => i.passed).reduce((s, i) => s + i.weight, 0) / total : 1;
|
|
116
|
+
}
|
|
117
|
+
/** Writes result.json and report.html (rendered from it) into `dir`. */
|
|
118
|
+
function writeRun(result, dir) {
|
|
119
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
120
|
+
const json = path.join(dir, 'result.json');
|
|
121
|
+
const html = path.join(dir, 'report.html');
|
|
122
|
+
fs.writeFileSync(json, JSON.stringify(result, null, 2) + '\n');
|
|
123
|
+
fs.writeFileSync(html, (0, report_1.renderReport)(result));
|
|
124
|
+
return { json, html };
|
|
125
|
+
}
|
|
126
|
+
// ---- pages
|
|
127
|
+
const ASSET = /\.(m?js|css|map|json|xml|txt|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|mp4|webm|mp3|wasm)$/i;
|
|
128
|
+
const NOT_REPLAYED = new Set(['control', 'preflight']);
|
|
129
|
+
function isPage(r) {
|
|
130
|
+
if (NOT_REPLAYED.has(r.source))
|
|
131
|
+
return false;
|
|
132
|
+
// a request without sec-fetch-dest (older logs, non-browser clients) counts when replay classed it as a page
|
|
133
|
+
if (r.dest !== undefined ? r.dest !== 'document' : r.class !== 'document')
|
|
134
|
+
return false;
|
|
135
|
+
try {
|
|
136
|
+
return !ASSET.test(new URL(r.url).pathname);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function pagesOf(log, rules, probes) {
|
|
143
|
+
const byKey = new Map();
|
|
144
|
+
for (const r of log) {
|
|
145
|
+
if (!isPage(r) || probes.has(r.url))
|
|
146
|
+
continue;
|
|
147
|
+
const id = `${r.status} ${r.key}`;
|
|
148
|
+
const seen = byKey.get(id);
|
|
149
|
+
if (seen) {
|
|
150
|
+
seen.count++;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const host = new URL(r.url).host;
|
|
154
|
+
const route = r.key ? r.key.slice(r.key.indexOf(' ') + 1) : host + new URL(r.url).pathname;
|
|
155
|
+
byKey.set(id, { site: rules.siteFor(host)?.site ?? host, route, method: r.method, url: r.url, count: 1, status: r.status, source: r.source, first: r.t });
|
|
156
|
+
}
|
|
157
|
+
const opened = [...byKey.values()];
|
|
158
|
+
return { opened, not_found: opened.filter((p) => p.status === 404) };
|
|
159
|
+
}
|
|
160
|
+
const SYSTEM = [
|
|
161
|
+
'You grade the answer a personal AI agent gave to a task it was set.',
|
|
162
|
+
'Extract the listed fields from the answer and answer each yes/no question about the answer.',
|
|
163
|
+
'Take values only from what the answer says; when the answer does not state a field, return null for it.',
|
|
164
|
+
'For each question give a short reason first, quoting or pointing to the part of the answer it rests on, then pass: true for yes and false for no.',
|
|
165
|
+
].join(' ');
|
|
166
|
+
const JSON_TYPE = { money: 'number', number: 'number', text: 'string', boolean: 'boolean' };
|
|
167
|
+
function judgeRequest(task, g, answer) {
|
|
168
|
+
const extract = Object.entries(g.extract ?? {});
|
|
169
|
+
const checks = g.checks ?? [];
|
|
170
|
+
const properties = {};
|
|
171
|
+
if (extract.length) {
|
|
172
|
+
properties.fields = {
|
|
173
|
+
type: 'object',
|
|
174
|
+
properties: Object.fromEntries(extract.map(([name, f]) => [name, { anyOf: [{ type: JSON_TYPE[f.type] }, { type: 'null' }], ...(f.description ? { description: f.description } : {}) }])),
|
|
175
|
+
required: extract.map(([name]) => name),
|
|
176
|
+
additionalProperties: false,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
if (checks.length) {
|
|
180
|
+
const verdict = { type: 'object', properties: { reason: { type: 'string' }, pass: { type: 'boolean' } }, required: ['reason', 'pass'], additionalProperties: false };
|
|
181
|
+
properties.checks = { type: 'object', properties: Object.fromEntries(checks.map((c) => [c.id, verdict])), required: checks.map((c) => c.id), additionalProperties: false };
|
|
182
|
+
}
|
|
183
|
+
const lines = [`<task>\n${task.prompt ?? task.title ?? task.id}\n</task>`, `<answer>\n${answer}\n</answer>`];
|
|
184
|
+
if (extract.length)
|
|
185
|
+
lines.push('Fields to extract (money and number as plain numbers, without currency signs):', ...extract.map(([name, f]) => `- ${name} (${f.type})${f.description ? `: ${f.description}` : ''}`));
|
|
186
|
+
if (checks.length)
|
|
187
|
+
lines.push('Questions:', ...checks.map((c) => `- ${c.id}: ${c.question}`));
|
|
188
|
+
return { system: SYSTEM, prompt: lines.join('\n\n'), schema: { type: 'object', properties, required: Object.keys(properties), additionalProperties: false } };
|
|
189
|
+
}
|
|
190
|
+
// ---- program-checked items
|
|
191
|
+
const squash = (s) => String(s).replace(/\s+/g, ' ').trim().toLowerCase();
|
|
192
|
+
function describe(r) {
|
|
193
|
+
const parts = [];
|
|
194
|
+
if (r.equals !== undefined)
|
|
195
|
+
parts.push(`equals ${r.equals}${r.tolerance !== undefined ? ` (±${r.tolerance})` : ''}`);
|
|
196
|
+
if (r.min !== undefined)
|
|
197
|
+
parts.push(`at least ${r.min}`);
|
|
198
|
+
if (r.max !== undefined)
|
|
199
|
+
parts.push(`at most ${r.max}`);
|
|
200
|
+
if (r.one_of !== undefined)
|
|
201
|
+
parts.push(`one of ${r.one_of.join(', ')}`);
|
|
202
|
+
if (r.contains !== undefined)
|
|
203
|
+
parts.push(`contains "${r.contains}"`);
|
|
204
|
+
return `${r.field} ${parts.join(', ')}`;
|
|
205
|
+
}
|
|
206
|
+
function compare(r, type, value) {
|
|
207
|
+
if (value === null || value === undefined)
|
|
208
|
+
return { passed: false, reason: 'not stated in the answer' };
|
|
209
|
+
const got = `got ${JSON.stringify(value)}`;
|
|
210
|
+
if (type === 'money' || type === 'number') {
|
|
211
|
+
const v = Number(value);
|
|
212
|
+
const tol = r.tolerance ?? 0.01;
|
|
213
|
+
const near = (x) => Math.abs(v - Number(x)) <= tol + 1e-9;
|
|
214
|
+
const ok = !Number.isNaN(v) && (r.equals === undefined || near(r.equals)) && (r.min === undefined || v >= r.min) && (r.max === undefined || v <= r.max) && (r.one_of === undefined || r.one_of.some(near));
|
|
215
|
+
return { passed: ok, reason: got };
|
|
216
|
+
}
|
|
217
|
+
if (type === 'boolean')
|
|
218
|
+
return { passed: value === r.equals, reason: got };
|
|
219
|
+
const v = squash(value);
|
|
220
|
+
const ok = (r.equals === undefined || v === squash(r.equals)) && (r.one_of === undefined || r.one_of.some((o) => v === squash(o))) && (r.contains === undefined || v.includes(squash(r.contains)));
|
|
221
|
+
return { passed: ok, reason: got };
|
|
222
|
+
}
|
|
223
|
+
const NOT_FROM_RECORDING = new Set(['miss', 'blocked', 'preflight', 'control']);
|
|
224
|
+
function matches(r, m) {
|
|
225
|
+
if (m.method && r.method.toUpperCase() !== m.method.toUpperCase())
|
|
226
|
+
return false;
|
|
227
|
+
if (m.hit && NOT_FROM_RECORDING.has(r.source))
|
|
228
|
+
return false;
|
|
229
|
+
return (0, util_1.globToRegExp)(m.url).test(r.url);
|
|
230
|
+
}
|
|
231
|
+
const matchText = (m) => `${m.method ? `${m.method.toUpperCase()} ` : ''}${m.url}${m.hit ? ' (answered from the recording)' : ''}`;
|
|
232
|
+
//# sourceMappingURL=scoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/scoring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tasks/<id>/ in this repository:
|
|
3
|
+
* task.yaml the task card (what the agent is asked)
|
|
4
|
+
* recording/ the recording, in the published layout (core/archive.ts, docs/bundle-format.md)
|
|
5
|
+
* rules/ site rules for this task: <site>.auto.yaml inferred from the recording,
|
|
6
|
+
* <site>.yaml written by people (wins over auto and over sites/)
|
|
7
|
+
* grading.yaml how answers to the task are scored (docs/grading.md)
|
|
8
|
+
*/
|
|
9
|
+
export interface TaskCard {
|
|
10
|
+
id: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
/** The instruction given to the agent. */
|
|
13
|
+
prompt?: string;
|
|
14
|
+
/** The browser's language and time zone while recording; replay keeps them. */
|
|
15
|
+
capture?: {
|
|
16
|
+
locale?: string;
|
|
17
|
+
timezone?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Everything a replay needs: the recording and the rules layered over it. */
|
|
21
|
+
export interface ReplayTarget {
|
|
22
|
+
name: string;
|
|
23
|
+
bundleDir: string;
|
|
24
|
+
/** Rule directories layered over the bundle's own rules/ (later wins). */
|
|
25
|
+
rulesDirs: string[];
|
|
26
|
+
task?: Task;
|
|
27
|
+
}
|
|
28
|
+
export declare class Repo {
|
|
29
|
+
readonly root: string;
|
|
30
|
+
constructor(root: string);
|
|
31
|
+
/** $PAB_REPO, or the checkout this code runs from. */
|
|
32
|
+
static default(): Repo;
|
|
33
|
+
get sitesDir(): string;
|
|
34
|
+
get tasksDir(): string;
|
|
35
|
+
/** Unpacked bundles and replay logs ($PAB_CACHE, default .cache/ in the repository). */
|
|
36
|
+
get cacheDir(): string;
|
|
37
|
+
taskIds(): string[];
|
|
38
|
+
task(id: string): Task;
|
|
39
|
+
}
|
|
40
|
+
export declare class Task {
|
|
41
|
+
readonly repo: Repo;
|
|
42
|
+
readonly dir: string;
|
|
43
|
+
constructor(repo: Repo, dir: string);
|
|
44
|
+
get id(): string;
|
|
45
|
+
get cardPath(): string;
|
|
46
|
+
get recordingDir(): string;
|
|
47
|
+
get rulesDir(): string;
|
|
48
|
+
/** grading.yaml: how answers are scored (see grading.ts). */
|
|
49
|
+
get gradingPath(): string;
|
|
50
|
+
card(): TaskCard;
|
|
51
|
+
/** Files of the recording; empty when the task has none yet. */
|
|
52
|
+
recordingFiles(): string[];
|
|
53
|
+
/** Unpacks the recording into the cache (once per recording content) and returns its directory. */
|
|
54
|
+
bundleDir(): Promise<string>;
|
|
55
|
+
target(): Promise<ReplayTarget>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolves a command-line argument to a replay target: a task id, a task directory, or a bundle
|
|
59
|
+
* directory (one with manifest.json, replayed with its own rules/).
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveTarget(arg: string, repo?: Repo): Promise<ReplayTarget>;
|