tarsk 0.5.65 → 0.5.67
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/bundled-skills/skill-creator/eval-viewer/generate_review.js +41 -40
- package/dist/bundled-skills/skill-creator/scripts/aggregate_benchmark.js +106 -98
- package/dist/bundled-skills/skill-creator/scripts/generate_report.js +78 -67
- package/dist/bundled-skills/skill-creator/scripts/improve_description.js +119 -72
- package/dist/bundled-skills/skill-creator/scripts/run_eval.js +76 -54
- package/dist/bundled-skills/skill-creator/scripts/run_loop.js +221 -142
- package/dist/index.js +51645 -47173
- package/dist/public/assets/{account-view-Dp0PfqVq.js → account-view-BlK6g38q.js} +1 -1
- package/dist/public/assets/{alert-dialog-Ge-FFGao.js → alert-dialog-B6An1LDY.js} +1 -1
- package/dist/public/assets/{async-error-boundary-B0tQed36.js → async-error-boundary-Rf-s2_Ez.js} +1 -1
- package/dist/public/assets/browser-tab-BJxPUVJi.js +12 -0
- package/dist/public/assets/{card-xQfAy2Rx.js → card-BDQUHsPD.js} +1 -1
- package/dist/public/assets/chat-dock-context-DyKjqpND.js +1 -0
- package/dist/public/assets/commit-dialog-CYb1kJCq.js +1 -0
- package/dist/public/assets/commit-error-dialog-DvxaNRcH.js +1 -0
- package/dist/public/assets/commit-method-fields-Dijc502F.js +1 -0
- package/dist/public/assets/context-menu-C51M1WGZ.js +1 -0
- package/dist/public/assets/conversation-history-view-w_6Jd3d-.js +1 -0
- package/dist/public/assets/create-project-dialog-CSVkngnF.js +6 -0
- package/dist/public/assets/create-repo-dialog-CcFA8pXz.js +1 -0
- package/dist/public/assets/{delete-confirm-dialog-Dy0dOtPe.js → delete-confirm-dialog-uTSX_x-i.js} +1 -1
- package/dist/public/assets/diff-view-XN5G5F6E.js +4 -0
- package/dist/public/assets/dist-IeRYu0zQ.js +142 -0
- package/dist/public/assets/{explorer-tab-context-8bs_tiCO.js → explorer-tab-context-BdjTEbFh.js} +1 -1
- package/dist/public/assets/explorer-tab-view-A2ICDFPB.js +2 -0
- package/dist/public/assets/explorer-tree-B04Ba59E.js +1 -0
- package/dist/public/assets/explorer-view-CofaKFiu.js +75 -0
- package/dist/public/assets/git-history-dialog-V3kaff2G.js +1 -0
- package/dist/public/assets/index-B0xy4BkI.js +3360 -0
- package/dist/public/assets/index-Cndc50ux.css +1 -0
- package/dist/public/assets/interactive-BrHVRHmQ.js +21 -0
- package/dist/public/assets/{main-tab-context-DHeKIUsf.js → main-tab-context-zQSuRQQG.js} +1 -1
- package/dist/public/assets/mcp-server-card-DOsP-SQ8.js +1 -0
- package/dist/public/assets/merged-pr-dialog-BerRzLlh.js +1 -0
- package/dist/public/assets/model-list-controls-Dw98tMn7.js +1 -0
- package/dist/public/assets/{monaco-setup-x3evbdq3.js → monaco-setup-C87kBr4u.js} +1 -1
- package/dist/public/assets/onboarding-DVc9-yKJ.js +46 -0
- package/dist/public/assets/project-env-vars-view-BQwUd7y6.js +1 -0
- package/dist/public/assets/project-model-aliases-view-CobSp09z.js +1 -0
- package/dist/public/assets/project-settings-view-CPTd5lEi.js +1 -0
- package/dist/public/assets/{project-tools-view-C44y08lY.js → project-tools-view-DShQghoz.js} +1 -1
- package/dist/public/assets/providers-list-view-Da9VMcuP.js +1 -0
- package/dist/public/assets/pull-request-dialog-BAarT9EM.js +1 -0
- package/dist/public/assets/pull-with-changes-dialog-BcF25mjQ.js +1 -0
- package/dist/public/assets/push-before-pr-dialog-BF0NzV2u.js +1 -0
- package/dist/public/assets/react-vendor-B7jFrulV.js +22 -0
- package/dist/public/assets/settings-general-view-DT4nElcL.js +1 -0
- package/dist/public/assets/settings-instructions-view-Bsr8wRMf.js +1 -0
- package/dist/public/assets/settings-list-B9wyVzKw.js +1 -0
- package/dist/public/assets/settings-logs-view-CyaGqUKH.js +5 -0
- package/dist/public/assets/settings-mcp-servers-view-BTUWHB5K.js +5 -0
- package/dist/public/assets/settings-models-view-DFwkVdt3.js +1 -0
- package/dist/public/assets/settings-rules-view-BhA9tjVh.js +8 -0
- package/dist/public/assets/settings-skills-view-BFoO9oZk.js +3 -0
- package/dist/public/assets/{settings-slack-view-OFUhhjTj.js → settings-slack-view-D4mrQ9C9.js} +1 -1
- package/dist/public/assets/settings-slash-commands-view-BLKPDUVG.js +1 -0
- package/dist/public/assets/settings-statistics-view-fa6iBiP8.js +1 -0
- package/dist/public/assets/settings-storage-view-LaiAi5gv.js +1 -0
- package/dist/public/assets/settings-subagents-view-BjMz2Ri_.js +2 -0
- package/dist/public/assets/settings-system-prompt-view-DNh1yqZh.js +1 -0
- package/dist/public/assets/settings-view-BoC66Wji.js +2 -0
- package/dist/public/assets/skeleton-CJSNEi3C.js +1 -0
- package/dist/public/assets/store-B_cK-gsT.js +8 -0
- package/dist/public/assets/{table-CYWF-RhQ.js → table-Cb2C1rQy.js} +1 -1
- package/dist/public/assets/tasks-view-B049aXpC.js +2 -0
- package/dist/public/assets/{terminal-panel-BxUHr-tZ.js → terminal-panel-Pv5xqCpm.js} +3 -3
- package/dist/public/assets/thread-tool-blocks-D9HUkPHB.js +1 -0
- package/dist/public/assets/{ui-components-DjoQfi8k.js → ui-components-DJLsrr5e.js} +1 -1
- package/dist/public/assets/{use-active-dock-panel-instance-BE69kVdb.js → use-active-dock-panel-instance-BlRDPUlZ.js} +1 -1
- package/dist/public/assets/{use-deferred-search-DXrcdbyC.js → use-deferred-search-0sV7mSzX.js} +1 -1
- package/dist/public/assets/use-installed-ai-files-DmLnugpj.js +1 -0
- package/dist/public/assets/{use-settings-page-loading-BC_wP7pl.js → use-settings-page-loading-BU2CDnfE.js} +1 -1
- package/dist/public/assets/{use-suspense-resource-rX-GqyWi.js → use-suspense-resource-CExc4Svq.js} +1 -1
- package/dist/public/assets/{use-toast-BFQ85Ly5.js → use-toast-hxHsVv6a.js} +1 -1
- package/dist/public/assets/{utils-Rlf65JHq.js → utils-SsF94Pkg.js} +1 -1
- package/dist/public/assets/{web-Q-tJsXNN.js → web-BidDZaMC.js} +1 -1
- package/dist/public/assets/{web-D8z4Nni0.js → web-C_HuLxHj.js} +1 -1
- package/dist/public/assets/{web-CxBqU2BU.js → web-DHUv7oQP.js} +1 -1
- package/dist/public/assets/{web-DTwF_7w-.js → web-JMCxQg4N.js} +1 -1
- package/dist/public/browser-preview-rpc.js +465 -7
- package/dist/public/index.html +14 -16
- package/dist/recommended-models.txt +5 -5
- package/package.json +1 -14
- package/dist/public/assets/api-BsPadLpi.js +0 -1
- package/dist/public/assets/browser-tab-hcbTzpVn.js +0 -8
- package/dist/public/assets/chat-dock-context-yQDhSXnw.js +0 -1
- package/dist/public/assets/commit-dialog-DK-NP7EN.js +0 -1
- package/dist/public/assets/commit-method-fields-DG3NtLE2.js +0 -1
- package/dist/public/assets/context-menu-M5y1Qb8G.js +0 -1
- package/dist/public/assets/conversation-history-view-YGPt-fC9.js +0 -1
- package/dist/public/assets/create-project-dialog-DW4oGrl2.js +0 -6
- package/dist/public/assets/create-repo-dialog-BFBOFZ2W.js +0 -1
- package/dist/public/assets/diff-view-Cy5PjlG_.js +0 -4
- package/dist/public/assets/dist-oojFghRi.js +0 -134
- package/dist/public/assets/explorer-tab-view-D6t9Ce05.js +0 -2
- package/dist/public/assets/explorer-tree-BCs2U0De.js +0 -1
- package/dist/public/assets/explorer-view-CxN4GRyn.js +0 -75
- package/dist/public/assets/git-history-dialog-fm9qhkgI.js +0 -1
- package/dist/public/assets/git-ops-button-DO1ng45p.js +0 -2
- package/dist/public/assets/index-B7qJtiRL.js +0 -3307
- package/dist/public/assets/index-GYexJ6QO.css +0 -1
- package/dist/public/assets/interactive-WtOIgeV4.js +0 -21
- package/dist/public/assets/local-tool-blocks-DlqmJ7__.js +0 -1
- package/dist/public/assets/mcp-server-card-V4Ddsgv3.js +0 -1
- package/dist/public/assets/merged-pr-dialog-Bi5pJzTO.js +0 -1
- package/dist/public/assets/model-list-controls-oiBE9X9_.js +0 -1
- package/dist/public/assets/onboarding-dbhmRuxw.js +0 -46
- package/dist/public/assets/project-env-vars-view-OVck-YEy.js +0 -1
- package/dist/public/assets/project-model-aliases-view-Cu-n2j94.js +0 -1
- package/dist/public/assets/project-settings-view-DKkLgg3C.js +0 -1
- package/dist/public/assets/providers-list-view-BEXiqKg8.js +0 -1
- package/dist/public/assets/pull-request-dialog-BOl1VloY.js +0 -1
- package/dist/public/assets/pull-with-changes-dialog-CJKvLUaf.js +0 -1
- package/dist/public/assets/push-before-pr-dialog-BZLScOoO.js +0 -1
- package/dist/public/assets/react-vendor-wGLyNWf9.js +0 -22
- package/dist/public/assets/settings-general-view-LnCQ2zkv.js +0 -1
- package/dist/public/assets/settings-instructions-view-B7lADJZh.js +0 -1
- package/dist/public/assets/settings-list-C5MACtux.js +0 -1
- package/dist/public/assets/settings-logs-view-YWMyQqu5.js +0 -5
- package/dist/public/assets/settings-mcp-servers-view-CN7JO2UD.js +0 -5
- package/dist/public/assets/settings-models-view-CswWfeDN.js +0 -1
- package/dist/public/assets/settings-rules-view-__5f33ot.js +0 -8
- package/dist/public/assets/settings-skills-view-Dvfrl9kz.js +0 -3
- package/dist/public/assets/settings-slash-commands-view-B1pO-Yie.js +0 -1
- package/dist/public/assets/settings-statistics-view-Bp624KXI.js +0 -1
- package/dist/public/assets/settings-storage-view-CHpGieRu.js +0 -1
- package/dist/public/assets/settings-subagents-view-CFggo62r.js +0 -2
- package/dist/public/assets/settings-system-prompt-view-BWD6RrX8.js +0 -1
- package/dist/public/assets/settings-view-ZgVxZhur.js +0 -2
- package/dist/public/assets/skeleton-B_xdlo2b.js +0 -1
- package/dist/public/assets/slug-utils-C5rnmMMP.js +0 -1
- package/dist/public/assets/store-CSyJjyNs.js +0 -7
- package/dist/public/assets/tasks-view-4yyCDYbV.js +0 -2
- package/dist/public/assets/thread-tool-blocks-BfowiaTH.js +0 -1
- package/dist/public/assets/use-installed-ai-files-CZIOFhcX.js +0 -1
|
@@ -95,7 +95,7 @@ function findRunsRecursive(root, current, runs) {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
function
|
|
98
|
+
function readEvalMetadata(runDir) {
|
|
99
99
|
let prompt = "";
|
|
100
100
|
let evalId = null;
|
|
101
101
|
|
|
@@ -114,57 +114,69 @@ function buildRun(root, runDir) {
|
|
|
114
114
|
if (prompt) break;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
117
|
+
return { prompt, evalId };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function extractPromptFromTranscript(runDir) {
|
|
121
|
+
for (const candidate of [
|
|
122
|
+
path.join(runDir, "transcript.md"),
|
|
123
|
+
path.join(runDir, "outputs", "transcript.md"),
|
|
124
|
+
]) {
|
|
125
|
+
if (!fs.existsSync(candidate)) continue;
|
|
126
|
+
try {
|
|
127
|
+
const text = fs.readFileSync(candidate, "utf-8");
|
|
128
|
+
const match = text.match(/## Eval Prompt\n\n([\s\S]*?)(?=\n##|$)/);
|
|
129
|
+
if (match) return match[1].trim();
|
|
130
|
+
} catch {
|
|
131
|
+
// ignore
|
|
131
132
|
}
|
|
132
133
|
}
|
|
134
|
+
return "";
|
|
135
|
+
}
|
|
133
136
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const runId = path.relative(root, runDir).split(path.sep).join("-");
|
|
137
|
+
function collectOutputFiles(runDir) {
|
|
137
138
|
const outputsDir = path.join(runDir, "outputs");
|
|
138
139
|
const outputFiles = [];
|
|
139
|
-
if (fs.existsSync(outputsDir)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
if (!fs.existsSync(outputsDir) || !fs.statSync(outputsDir).isDirectory()) {
|
|
141
|
+
return outputFiles;
|
|
142
|
+
}
|
|
143
|
+
for (const name of fs.readdirSync(outputsDir).sort()) {
|
|
144
|
+
const filePath = path.join(outputsDir, name);
|
|
145
|
+
if (fs.statSync(filePath).isFile() && !METADATA_FILES.has(name)) {
|
|
146
|
+
outputFiles.push(embedFile(filePath));
|
|
145
147
|
}
|
|
146
148
|
}
|
|
149
|
+
return outputFiles;
|
|
150
|
+
}
|
|
147
151
|
|
|
148
|
-
|
|
152
|
+
function readGrading(runDir) {
|
|
149
153
|
for (const candidate of [
|
|
150
154
|
path.join(runDir, "grading.json"),
|
|
151
155
|
path.join(runDir, "..", "grading.json"),
|
|
152
156
|
]) {
|
|
153
157
|
if (!fs.existsSync(candidate)) continue;
|
|
154
158
|
try {
|
|
155
|
-
grading = JSON.parse(fs.readFileSync(candidate, "utf-8"));
|
|
159
|
+
const grading = JSON.parse(fs.readFileSync(candidate, "utf-8"));
|
|
160
|
+
if (grading) return grading;
|
|
156
161
|
} catch {
|
|
157
162
|
// ignore
|
|
158
163
|
}
|
|
159
|
-
if (grading) break;
|
|
160
164
|
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function buildRun(root, runDir) {
|
|
169
|
+
const { prompt: metadataPrompt, evalId } = readEvalMetadata(runDir);
|
|
170
|
+
const prompt = metadataPrompt || extractPromptFromTranscript(runDir) || "(No prompt found)";
|
|
171
|
+
|
|
172
|
+
const runId = path.relative(root, runDir).split(path.sep).join("-");
|
|
161
173
|
|
|
162
174
|
return {
|
|
163
175
|
id: runId,
|
|
164
176
|
prompt,
|
|
165
177
|
eval_id: evalId,
|
|
166
|
-
outputs:
|
|
167
|
-
grading,
|
|
178
|
+
outputs: collectOutputFiles(runDir),
|
|
179
|
+
grading: readGrading(runDir),
|
|
168
180
|
};
|
|
169
181
|
}
|
|
170
182
|
|
|
@@ -531,14 +543,3 @@ function main() {
|
|
|
531
543
|
if (require.main === module) {
|
|
532
544
|
main();
|
|
533
545
|
}
|
|
534
|
-
|
|
535
|
-
module.exports = {
|
|
536
|
-
findRuns,
|
|
537
|
-
buildRun,
|
|
538
|
-
embedFile,
|
|
539
|
-
loadPreviousIteration,
|
|
540
|
-
generateHtml,
|
|
541
|
-
createReviewServer,
|
|
542
|
-
killPort,
|
|
543
|
-
openUrl,
|
|
544
|
-
};
|
|
@@ -38,117 +38,131 @@ function globEvalDirs(dir) {
|
|
|
38
38
|
.map((entry) => path.join(dir, entry.name));
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function
|
|
41
|
+
function resolveSearchDir(benchmarkDir) {
|
|
42
42
|
const runsDir = path.join(benchmarkDir, "runs");
|
|
43
|
-
let searchDir;
|
|
44
43
|
if (fs.existsSync(runsDir) && fs.statSync(runsDir).isDirectory()) {
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
console.log(
|
|
50
|
-
`No eval directories found in ${benchmarkDir} or ${path.join(benchmarkDir, "runs")}`,
|
|
51
|
-
);
|
|
52
|
-
return {};
|
|
44
|
+
return runsDir;
|
|
45
|
+
}
|
|
46
|
+
if (globEvalDirs(benchmarkDir).length > 0) {
|
|
47
|
+
return benchmarkDir;
|
|
53
48
|
}
|
|
49
|
+
console.log(`No eval directories found in ${benchmarkDir} or ${path.join(benchmarkDir, "runs")}`);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
function resolveEvalId(evalDir, evalIdx) {
|
|
54
|
+
const metadataPath = path.join(evalDir, "eval_metadata.json");
|
|
55
|
+
if (fs.existsSync(metadataPath)) {
|
|
56
|
+
try {
|
|
57
|
+
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf-8"));
|
|
58
|
+
return metadata.eval_id ?? evalIdx;
|
|
59
|
+
} catch {
|
|
60
|
+
return evalIdx;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const parts = path.basename(evalDir).split("-");
|
|
64
|
+
const parsed = parseInt(parts[1], 10);
|
|
65
|
+
return Number.isNaN(parsed) ? evalIdx : parsed;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function listRunDirs(configDir) {
|
|
69
|
+
return fs
|
|
70
|
+
.readdirSync(configDir)
|
|
71
|
+
.filter((name) => name.startsWith("run-"))
|
|
72
|
+
.map((name) => path.join(configDir, name))
|
|
73
|
+
.sort();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function loadGrading(runDir) {
|
|
77
|
+
const gradingFile = path.join(runDir, "grading.json");
|
|
78
|
+
if (!fs.existsSync(gradingFile)) {
|
|
79
|
+
console.log(`Warning: grading.json not found in ${runDir}`);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
return JSON.parse(fs.readFileSync(gradingFile, "utf-8"));
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.log(`Warning: Invalid JSON in ${gradingFile}: ${error.message}`);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function buildResult(evalId, runNumber, grading, runDir) {
|
|
91
|
+
const result = {
|
|
92
|
+
eval_id: evalId,
|
|
93
|
+
run_number: runNumber,
|
|
94
|
+
pass_rate: grading.summary?.pass_rate ?? 0.0,
|
|
95
|
+
passed: grading.summary?.passed ?? 0,
|
|
96
|
+
failed: grading.summary?.failed ?? 0,
|
|
97
|
+
total: grading.summary?.total ?? 0,
|
|
98
|
+
};
|
|
56
99
|
|
|
100
|
+
const timing = grading.timing ?? {};
|
|
101
|
+
result.time_seconds = timing.total_duration_seconds ?? 0.0;
|
|
102
|
+
const timingFile = path.join(runDir, "timing.json");
|
|
103
|
+
if (result.time_seconds === 0.0 && fs.existsSync(timingFile)) {
|
|
104
|
+
try {
|
|
105
|
+
const timingData = JSON.parse(fs.readFileSync(timingFile, "utf-8"));
|
|
106
|
+
result.time_seconds = timingData.total_duration_seconds ?? 0.0;
|
|
107
|
+
result.tokens = timingData.total_tokens ?? 0;
|
|
108
|
+
} catch {
|
|
109
|
+
// ignore invalid timing.json
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const metrics = grading.execution_metrics ?? {};
|
|
114
|
+
result.tool_calls = metrics.total_tool_calls ?? 0;
|
|
115
|
+
if (!result.tokens) {
|
|
116
|
+
result.tokens = metrics.output_chars ?? 0;
|
|
117
|
+
}
|
|
118
|
+
result.errors = metrics.errors_encountered ?? 0;
|
|
119
|
+
|
|
120
|
+
const rawExpectations = grading.expectations ?? [];
|
|
121
|
+
for (const exp of rawExpectations) {
|
|
122
|
+
if (!("text" in exp) || !("passed" in exp)) {
|
|
123
|
+
console.log(
|
|
124
|
+
`Warning: expectation in ${path.join(runDir, "grading.json")} missing required fields (text, passed, evidence): ${JSON.stringify(exp)}`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
result.expectations = rawExpectations;
|
|
129
|
+
|
|
130
|
+
const notesSummary = grading.user_notes_summary ?? {};
|
|
131
|
+
result.notes = [
|
|
132
|
+
...(notesSummary.uncertainties ?? []),
|
|
133
|
+
...(notesSummary.needs_review ?? []),
|
|
134
|
+
...(notesSummary.workarounds ?? []),
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function loadRunResults(benchmarkDir) {
|
|
141
|
+
const searchDir = resolveSearchDir(benchmarkDir);
|
|
142
|
+
if (!searchDir) return {};
|
|
143
|
+
|
|
144
|
+
const results = {};
|
|
57
145
|
const evalDirs = globEvalDirs(searchDir).sort();
|
|
58
146
|
for (let evalIdx = 0; evalIdx < evalDirs.length; evalIdx++) {
|
|
59
147
|
const evalDir = evalDirs[evalIdx];
|
|
60
|
-
const
|
|
61
|
-
let evalId = evalIdx;
|
|
62
|
-
if (fs.existsSync(metadataPath)) {
|
|
63
|
-
try {
|
|
64
|
-
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf-8"));
|
|
65
|
-
evalId = metadata.eval_id ?? evalIdx;
|
|
66
|
-
} catch {
|
|
67
|
-
evalId = evalIdx;
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
const parts = path.basename(evalDir).split("-");
|
|
71
|
-
const parsed = parseInt(parts[1], 10);
|
|
72
|
-
evalId = Number.isNaN(parsed) ? evalIdx : parsed;
|
|
73
|
-
}
|
|
148
|
+
const evalId = resolveEvalId(evalDir, evalIdx);
|
|
74
149
|
|
|
75
150
|
for (const configName of fs.readdirSync(evalDir).sort()) {
|
|
76
151
|
const configDir = path.join(evalDir, configName);
|
|
77
152
|
if (!fs.statSync(configDir).isDirectory()) continue;
|
|
78
153
|
|
|
79
|
-
const runDirs =
|
|
80
|
-
.readdirSync(configDir)
|
|
81
|
-
.filter((name) => name.startsWith("run-"))
|
|
82
|
-
.map((name) => path.join(configDir, name));
|
|
154
|
+
const runDirs = listRunDirs(configDir);
|
|
83
155
|
if (runDirs.length === 0) continue;
|
|
84
156
|
|
|
85
157
|
if (!results[configName]) {
|
|
86
158
|
results[configName] = [];
|
|
87
159
|
}
|
|
88
160
|
|
|
89
|
-
for (const runDir of runDirs
|
|
161
|
+
for (const runDir of runDirs) {
|
|
90
162
|
const runNumber = parseInt(path.basename(runDir).split("-")[1], 10);
|
|
91
|
-
const
|
|
92
|
-
if (!
|
|
93
|
-
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
let grading;
|
|
98
|
-
try {
|
|
99
|
-
grading = JSON.parse(fs.readFileSync(gradingFile, "utf-8"));
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.log(`Warning: Invalid JSON in ${gradingFile}: ${error.message}`);
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const result = {
|
|
106
|
-
eval_id: evalId,
|
|
107
|
-
run_number: runNumber,
|
|
108
|
-
pass_rate: grading.summary?.pass_rate ?? 0.0,
|
|
109
|
-
passed: grading.summary?.passed ?? 0,
|
|
110
|
-
failed: grading.summary?.failed ?? 0,
|
|
111
|
-
total: grading.summary?.total ?? 0,
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const timing = grading.timing ?? {};
|
|
115
|
-
result.time_seconds = timing.total_duration_seconds ?? 0.0;
|
|
116
|
-
const timingFile = path.join(runDir, "timing.json");
|
|
117
|
-
if (result.time_seconds === 0.0 && fs.existsSync(timingFile)) {
|
|
118
|
-
try {
|
|
119
|
-
const timingData = JSON.parse(fs.readFileSync(timingFile, "utf-8"));
|
|
120
|
-
result.time_seconds = timingData.total_duration_seconds ?? 0.0;
|
|
121
|
-
result.tokens = timingData.total_tokens ?? 0;
|
|
122
|
-
} catch {
|
|
123
|
-
// ignore invalid timing.json
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const metrics = grading.execution_metrics ?? {};
|
|
128
|
-
result.tool_calls = metrics.total_tool_calls ?? 0;
|
|
129
|
-
if (!result.tokens) {
|
|
130
|
-
result.tokens = metrics.output_chars ?? 0;
|
|
131
|
-
}
|
|
132
|
-
result.errors = metrics.errors_encountered ?? 0;
|
|
133
|
-
|
|
134
|
-
const rawExpectations = grading.expectations ?? [];
|
|
135
|
-
for (const exp of rawExpectations) {
|
|
136
|
-
if (!("text" in exp) || !("passed" in exp)) {
|
|
137
|
-
console.log(
|
|
138
|
-
`Warning: expectation in ${gradingFile} missing required fields (text, passed, evidence): ${JSON.stringify(exp)}`,
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
result.expectations = rawExpectations;
|
|
143
|
-
|
|
144
|
-
const notesSummary = grading.user_notes_summary ?? {};
|
|
145
|
-
result.notes = [
|
|
146
|
-
...(notesSummary.uncertainties ?? []),
|
|
147
|
-
...(notesSummary.needs_review ?? []),
|
|
148
|
-
...(notesSummary.workarounds ?? []),
|
|
149
|
-
];
|
|
150
|
-
|
|
151
|
-
results[configName].push(result);
|
|
163
|
+
const grading = loadGrading(runDir);
|
|
164
|
+
if (!grading) continue;
|
|
165
|
+
results[configName].push(buildResult(evalId, runNumber, grading, runDir));
|
|
152
166
|
}
|
|
153
167
|
}
|
|
154
168
|
}
|
|
@@ -368,10 +382,4 @@ if (require.main === module) {
|
|
|
368
382
|
main();
|
|
369
383
|
}
|
|
370
384
|
|
|
371
|
-
module.exports = {
|
|
372
|
-
calculateStats,
|
|
373
|
-
loadRunResults,
|
|
374
|
-
aggregateResults,
|
|
375
|
-
generateBenchmark,
|
|
376
|
-
generateMarkdown,
|
|
377
|
-
};
|
|
385
|
+
module.exports = { calculateStats, buildResult, aggregateResults, generateMarkdown };
|
|
@@ -37,26 +37,8 @@ function scoreClass(correct, total) {
|
|
|
37
37
|
return "score-bad";
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
const titlePrefix = skillName ? escapeHtml(`${skillName} \u2014 `) : "";
|
|
43
|
-
|
|
44
|
-
const trainQueries = [];
|
|
45
|
-
const testQueries = [];
|
|
46
|
-
if (history.length) {
|
|
47
|
-
for (const r of history[0].train_results ?? history[0].results ?? []) {
|
|
48
|
-
trainQueries.push({ query: r.query, should_trigger: r.should_trigger ?? true });
|
|
49
|
-
}
|
|
50
|
-
if (history[0].test_results) {
|
|
51
|
-
for (const r of history[0].test_results) {
|
|
52
|
-
testQueries.push({ query: r.query, should_trigger: r.should_trigger ?? true });
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const refreshTag = autoRefresh ? ' <meta http-equiv="refresh" content="5">\n' : "";
|
|
58
|
-
const htmlParts = [
|
|
59
|
-
`<!DOCTYPE html>
|
|
40
|
+
function buildHead(titlePrefix, refreshTag) {
|
|
41
|
+
return `<!DOCTYPE html>
|
|
60
42
|
<html>
|
|
61
43
|
<head>
|
|
62
44
|
<meta charset="utf-8">
|
|
@@ -175,20 +157,23 @@ ${refreshTag} <title>${titlePrefix}Skill Description Optimization</title>
|
|
|
175
157
|
<div class="explainer">
|
|
176
158
|
<strong>Optimizing your skill's description.</strong> This page updates automatically as Tarsk tests different versions of your skill's description. Each row is an iteration — a new description attempt. The columns show test queries: green checkmarks mean the skill triggered correctly (or correctly didn't trigger), red crosses mean it got it wrong. The "Train" score shows performance on queries used to improve the description; the "Test" score shows performance on held-out queries the optimizer hasn't seen. When it's done, Tarsk will apply the best-performing description to your skill.
|
|
177
159
|
</div>
|
|
178
|
-
|
|
179
|
-
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
180
162
|
|
|
163
|
+
function buildSummary(data) {
|
|
181
164
|
const bestTestScore = data.best_test_score;
|
|
182
|
-
|
|
165
|
+
return `
|
|
183
166
|
<div class="summary">
|
|
184
167
|
<p><strong>Original:</strong> ${escapeHtml(data.original_description ?? "N/A")}</p>
|
|
185
168
|
<p class="best"><strong>Best:</strong> ${escapeHtml(data.best_description ?? "N/A")}</p>
|
|
186
169
|
<p><strong>Best Score:</strong> ${data.best_score ?? "N/A"} ${bestTestScore ? "(test)" : "(train)"}</p>
|
|
187
170
|
<p><strong>Iterations:</strong> ${data.iterations_run ?? 0} | <strong>Train:</strong> ${data.train_size ?? "?"} | <strong>Test:</strong> ${data.test_size ?? "?"}</p>
|
|
188
171
|
</div>
|
|
189
|
-
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
190
174
|
|
|
191
|
-
|
|
175
|
+
function buildLegend() {
|
|
176
|
+
return `
|
|
192
177
|
<div class="legend">
|
|
193
178
|
<span style="font-weight:600">Query columns:</span>
|
|
194
179
|
<span class="legend-item"><span class="legend-swatch swatch-positive"></span> Should trigger</span>
|
|
@@ -196,9 +181,12 @@ ${refreshTag} <title>${titlePrefix}Skill Description Optimization</title>
|
|
|
196
181
|
<span class="legend-item"><span class="legend-swatch swatch-train"></span> Train</span>
|
|
197
182
|
<span class="legend-item"><span class="legend-swatch swatch-test"></span> Test</span>
|
|
198
183
|
</div>
|
|
199
|
-
|
|
184
|
+
`;
|
|
185
|
+
}
|
|
200
186
|
|
|
201
|
-
|
|
187
|
+
function buildTableHeader(trainQueries, testQueries) {
|
|
188
|
+
const parts = [
|
|
189
|
+
`
|
|
202
190
|
<div class="table-container">
|
|
203
191
|
<table>
|
|
204
192
|
<thead>
|
|
@@ -207,37 +195,53 @@ ${refreshTag} <title>${titlePrefix}Skill Description Optimization</title>
|
|
|
207
195
|
<th>Train</th>
|
|
208
196
|
<th>Test</th>
|
|
209
197
|
<th class="query-col">Description</th>
|
|
210
|
-
|
|
211
|
-
|
|
198
|
+
`,
|
|
199
|
+
];
|
|
212
200
|
for (const qinfo of trainQueries) {
|
|
213
201
|
const polarity = qinfo.should_trigger ? "positive-col" : "negative-col";
|
|
214
|
-
|
|
202
|
+
parts.push(` <th class="${polarity}">${escapeHtml(qinfo.query)}</th>\n`);
|
|
215
203
|
}
|
|
216
204
|
for (const qinfo of testQueries) {
|
|
217
205
|
const polarity = qinfo.should_trigger ? "positive-col" : "negative-col";
|
|
218
|
-
|
|
206
|
+
parts.push(
|
|
219
207
|
` <th class="test-col ${polarity}">${escapeHtml(qinfo.query)}</th>\n`,
|
|
220
208
|
);
|
|
221
209
|
}
|
|
222
|
-
|
|
223
|
-
htmlParts.push(` </tr>
|
|
210
|
+
parts.push(` </tr>
|
|
224
211
|
</thead>
|
|
225
212
|
<tbody>
|
|
226
213
|
`);
|
|
214
|
+
return parts.join("");
|
|
215
|
+
}
|
|
227
216
|
|
|
228
|
-
|
|
217
|
+
function buildResultCell(qinfo, byQuery, isTest) {
|
|
218
|
+
const r = byQuery[qinfo.query] ?? {};
|
|
219
|
+
const didPass = r.pass ?? false;
|
|
220
|
+
const triggers = r.triggers ?? 0;
|
|
221
|
+
const runs = r.runs ?? 0;
|
|
222
|
+
const icon = didPass ? "✓" : "✗";
|
|
223
|
+
const cssClass = didPass ? "pass" : "fail";
|
|
224
|
+
const testClass = isTest ? "test-result " : "";
|
|
225
|
+
return ` <td class="result ${testClass}${cssClass}">${icon}<span class="rate">${triggers}/${runs}</span></td>\n`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function findBestIteration(history, testQueries) {
|
|
229
229
|
if (testQueries.length) {
|
|
230
|
-
|
|
230
|
+
return history.reduce(
|
|
231
231
|
(best, h) => ((h.test_passed ?? 0) > (best.test_passed ?? 0) ? h : best),
|
|
232
232
|
history[0],
|
|
233
233
|
).iteration;
|
|
234
|
-
} else {
|
|
235
|
-
bestIter = history.reduce(
|
|
236
|
-
(best, h) =>
|
|
237
|
-
(h.train_passed ?? h.passed ?? 0) > (best.train_passed ?? best.passed ?? 0) ? h : best,
|
|
238
|
-
history[0],
|
|
239
|
-
).iteration;
|
|
240
234
|
}
|
|
235
|
+
return history.reduce(
|
|
236
|
+
(best, h) =>
|
|
237
|
+
(h.train_passed ?? h.passed ?? 0) > (best.train_passed ?? best.passed ?? 0) ? h : best,
|
|
238
|
+
history[0],
|
|
239
|
+
).iteration;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function buildTableRows(history, trainQueries, testQueries) {
|
|
243
|
+
const parts = [];
|
|
244
|
+
const bestIter = findBestIteration(history, testQueries);
|
|
241
245
|
|
|
242
246
|
for (const h of history) {
|
|
243
247
|
const iteration = h.iteration ?? "?";
|
|
@@ -248,55 +252,62 @@ ${refreshTag} <title>${titlePrefix}Skill Description Optimization</title>
|
|
|
248
252
|
const testByQuery = testResults.length
|
|
249
253
|
? Object.fromEntries(testResults.map((r) => [r.query, r]))
|
|
250
254
|
: {};
|
|
251
|
-
|
|
252
255
|
const [trainCorrect, trainRuns] = aggregateRuns(trainResults);
|
|
253
256
|
const [testCorrect, testRuns] = aggregateRuns(testResults);
|
|
254
257
|
const trainClass = scoreClass(trainCorrect, trainRuns);
|
|
255
258
|
const testClass = scoreClass(testCorrect, testRuns);
|
|
256
259
|
const rowClass = iteration === bestIter ? "best-row" : "";
|
|
257
260
|
|
|
258
|
-
|
|
261
|
+
parts.push(` <tr class="${rowClass}">
|
|
259
262
|
<td>${iteration}</td>
|
|
260
263
|
<td><span class="score ${trainClass}">${trainCorrect}/${trainRuns}</span></td>
|
|
261
264
|
<td><span class="score ${testClass}">${testCorrect}/${testRuns}</span></td>
|
|
262
265
|
<td class="description">${escapeHtml(description)}</td>
|
|
263
266
|
`);
|
|
264
|
-
|
|
265
267
|
for (const qinfo of trainQueries) {
|
|
266
|
-
|
|
267
|
-
const didPass = r.pass ?? false;
|
|
268
|
-
const triggers = r.triggers ?? 0;
|
|
269
|
-
const runs = r.runs ?? 0;
|
|
270
|
-
const icon = didPass ? "✓" : "✗";
|
|
271
|
-
const cssClass = didPass ? "pass" : "fail";
|
|
272
|
-
htmlParts.push(
|
|
273
|
-
` <td class="result ${cssClass}">${icon}<span class="rate">${triggers}/${runs}</span></td>\n`,
|
|
274
|
-
);
|
|
268
|
+
parts.push(buildResultCell(qinfo, trainByQuery, false));
|
|
275
269
|
}
|
|
276
|
-
|
|
277
270
|
for (const qinfo of testQueries) {
|
|
278
|
-
|
|
279
|
-
const didPass = r.pass ?? false;
|
|
280
|
-
const triggers = r.triggers ?? 0;
|
|
281
|
-
const runs = r.runs ?? 0;
|
|
282
|
-
const icon = didPass ? "✓" : "✗";
|
|
283
|
-
const cssClass = didPass ? "pass" : "fail";
|
|
284
|
-
htmlParts.push(
|
|
285
|
-
` <td class="result test-result ${cssClass}">${icon}<span class="rate">${triggers}/${runs}</span></td>\n`,
|
|
286
|
-
);
|
|
271
|
+
parts.push(buildResultCell(qinfo, testByQuery, true));
|
|
287
272
|
}
|
|
288
|
-
|
|
289
|
-
htmlParts.push(" </tr>\n");
|
|
273
|
+
parts.push(" </tr>\n");
|
|
290
274
|
}
|
|
291
275
|
|
|
292
|
-
|
|
276
|
+
parts.push(` </tbody>
|
|
293
277
|
</table>
|
|
294
278
|
</div>
|
|
295
279
|
</body>
|
|
296
280
|
</html>
|
|
297
281
|
`);
|
|
282
|
+
return parts.join("");
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function generateHtml(data, autoRefresh = false, skillName = "") {
|
|
286
|
+
const history = data.history ?? [];
|
|
287
|
+
const titlePrefix = skillName ? escapeHtml(`${skillName} \u2014 `) : "";
|
|
288
|
+
|
|
289
|
+
const trainQueries = [];
|
|
290
|
+
const testQueries = [];
|
|
291
|
+
if (history.length) {
|
|
292
|
+
for (const r of history[0].train_results ?? history[0].results ?? []) {
|
|
293
|
+
trainQueries.push({ query: r.query, should_trigger: r.should_trigger ?? true });
|
|
294
|
+
}
|
|
295
|
+
if (history[0].test_results) {
|
|
296
|
+
for (const r of history[0].test_results) {
|
|
297
|
+
testQueries.push({ query: r.query, should_trigger: r.should_trigger ?? true });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const refreshTag = autoRefresh ? ' <meta http-equiv="refresh" content="5">\n' : "";
|
|
298
303
|
|
|
299
|
-
return
|
|
304
|
+
return (
|
|
305
|
+
buildHead(titlePrefix, refreshTag) +
|
|
306
|
+
buildSummary(data) +
|
|
307
|
+
buildLegend() +
|
|
308
|
+
buildTableHeader(trainQueries, testQueries) +
|
|
309
|
+
buildTableRows(history, trainQueries, testQueries)
|
|
310
|
+
);
|
|
300
311
|
}
|
|
301
312
|
|
|
302
313
|
function parseArgs(argv) {
|