@tangle-network/agent-bench 0.4.0 → 0.4.3

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.
Files changed (200) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/adapters.d.ts +4 -11
  3. package/dist/adapters.js +78 -41
  4. package/dist/adapters.js.map +1 -1
  5. package/dist/benchmarks/_harness.d.ts +51 -66
  6. package/dist/benchmarks/_harness.js +329 -31
  7. package/dist/benchmarks/_harness.js.map +1 -1
  8. package/dist/benchmarks/aec-bench.d.ts +4 -25
  9. package/dist/benchmarks/aec-bench.js +242 -7
  10. package/dist/benchmarks/aec-bench.js.map +1 -1
  11. package/dist/benchmarks/agentbench.d.ts +5 -13
  12. package/dist/benchmarks/agentbench.js +114 -9
  13. package/dist/benchmarks/agentbench.js.map +1 -1
  14. package/dist/benchmarks/appworld.d.ts +9 -29
  15. package/dist/benchmarks/appworld.js +317 -12
  16. package/dist/benchmarks/appworld.js.map +1 -1
  17. package/dist/benchmarks/bfcl.d.ts +5 -15
  18. package/dist/benchmarks/bfcl.js +264 -9
  19. package/dist/benchmarks/bfcl.js.map +1 -1
  20. package/dist/benchmarks/cad-design.d.ts +16 -41
  21. package/dist/benchmarks/cad-design.js +512 -6
  22. package/dist/benchmarks/cad-design.js.map +1 -1
  23. package/dist/benchmarks/cadbench.d.ts +4 -17
  24. package/dist/benchmarks/cadbench.js +2 -8
  25. package/dist/benchmarks/cadgenbench.d.ts +4 -20
  26. package/dist/benchmarks/cadgenbench.js +2 -8
  27. package/dist/benchmarks/commit0.d.ts +5 -27
  28. package/dist/benchmarks/commit0.js +187 -9
  29. package/dist/benchmarks/commit0.js.map +1 -1
  30. package/dist/benchmarks/crag.d.ts +4 -12
  31. package/dist/benchmarks/crag.js +110 -8
  32. package/dist/benchmarks/crag.js.map +1 -1
  33. package/dist/benchmarks/dabstep.d.ts +5 -15
  34. package/dist/benchmarks/dabstep.js +177 -9
  35. package/dist/benchmarks/dabstep.js.map +1 -1
  36. package/dist/benchmarks/enterpriseops-gym.d.ts +5 -34
  37. package/dist/benchmarks/enterpriseops-gym.js +236 -9
  38. package/dist/benchmarks/enterpriseops-gym.js.map +1 -1
  39. package/dist/benchmarks/finresearchbench.d.ts +4 -13
  40. package/dist/benchmarks/finresearchbench.js +218 -7
  41. package/dist/benchmarks/finresearchbench.js.map +1 -1
  42. package/dist/benchmarks/finsearchcomp.d.ts +8 -39
  43. package/dist/benchmarks/finsearchcomp.js +267 -6
  44. package/dist/benchmarks/finsearchcomp.js.map +1 -1
  45. package/dist/benchmarks/frames.d.ts +15 -37
  46. package/dist/benchmarks/frames.js +408 -11
  47. package/dist/benchmarks/frames.js.map +1 -1
  48. package/dist/benchmarks/hotpotqa.d.ts +4 -24
  49. package/dist/benchmarks/hotpotqa.js +250 -14
  50. package/dist/benchmarks/hotpotqa.js.map +1 -1
  51. package/dist/benchmarks/humaneval.d.ts +19 -37
  52. package/dist/benchmarks/humaneval.js +279 -16
  53. package/dist/benchmarks/humaneval.js.map +1 -1
  54. package/dist/benchmarks/mind2web.d.ts +7 -34
  55. package/dist/benchmarks/mind2web.js +257 -8
  56. package/dist/benchmarks/mind2web.js.map +1 -1
  57. package/dist/benchmarks/nomiracl.d.ts +4 -13
  58. package/dist/benchmarks/nomiracl.js +146 -8
  59. package/dist/benchmarks/nomiracl.js.map +1 -1
  60. package/dist/benchmarks/open-rag-bench.d.ts +4 -12
  61. package/dist/benchmarks/open-rag-bench.js +110 -8
  62. package/dist/benchmarks/open-rag-bench.js.map +1 -1
  63. package/dist/benchmarks/programbench.d.ts +5 -29
  64. package/dist/benchmarks/programbench.js +161 -9
  65. package/dist/benchmarks/programbench.js.map +1 -1
  66. package/dist/benchmarks/rag-shared.d.ts +21 -20
  67. package/dist/benchmarks/rag-shared.js +245 -38
  68. package/dist/benchmarks/rag-shared.js.map +1 -1
  69. package/dist/benchmarks/ragbench.d.ts +4 -14
  70. package/dist/benchmarks/ragbench.js +127 -8
  71. package/dist/benchmarks/ragbench.js.map +1 -1
  72. package/dist/benchmarks/simpleqa.d.ts +17 -44
  73. package/dist/benchmarks/simpleqa.js +293 -10
  74. package/dist/benchmarks/simpleqa.js.map +1 -1
  75. package/dist/benchmarks/swe-bench.d.ts +23 -36
  76. package/dist/benchmarks/swe-bench.js +234 -13
  77. package/dist/benchmarks/swe-bench.js.map +1 -1
  78. package/dist/benchmarks/t2-ragbench.d.ts +4 -12
  79. package/dist/benchmarks/t2-ragbench.js +118 -8
  80. package/dist/benchmarks/t2-ragbench.js.map +1 -1
  81. package/dist/benchmarks/tau-bench-shared.d.ts +14 -22
  82. package/dist/benchmarks/tau-bench-shared.js +169 -9
  83. package/dist/benchmarks/tau-bench-shared.js.map +1 -1
  84. package/dist/benchmarks/tau2-bench.d.ts +5 -5
  85. package/dist/benchmarks/tau2-bench.js +28 -10
  86. package/dist/benchmarks/tau2-bench.js.map +1 -1
  87. package/dist/benchmarks/tau3-banking.d.ts +4 -13
  88. package/dist/benchmarks/tau3-banking.js +28 -8
  89. package/dist/benchmarks/tau3-banking.js.map +1 -1
  90. package/dist/benchmarks/terminal-bench.d.ts +4 -22
  91. package/dist/benchmarks/terminal-bench.js +140 -7
  92. package/dist/benchmarks/terminal-bench.js.map +1 -1
  93. package/dist/benchmarks/toollm.d.ts +5 -13
  94. package/dist/benchmarks/toollm.js +184 -9
  95. package/dist/benchmarks/toollm.js.map +1 -1
  96. package/dist/benchmarks/trata-hedge.d.ts +4 -30
  97. package/dist/benchmarks/trata-hedge.js +336 -6
  98. package/dist/benchmarks/trata-hedge.js.map +1 -1
  99. package/dist/benchmarks/types.d.ts +85 -94
  100. package/dist/benchmarks/types.js +1 -1
  101. package/dist/benchmarks/webarena-verified.d.ts +5 -13
  102. package/dist/benchmarks/webarena-verified.js +152 -9
  103. package/dist/benchmarks/webarena-verified.js.map +1 -1
  104. package/dist/cadbench-DpQWZHp4.js +285 -0
  105. package/dist/cadbench-DpQWZHp4.js.map +1 -0
  106. package/dist/cadgenbench-DRhczfsG.js +151 -0
  107. package/dist/cadgenbench-DRhczfsG.js.map +1 -0
  108. package/dist/index.d.ts +245 -293
  109. package/dist/index.js +1669 -1791
  110. package/dist/index.js.map +1 -1
  111. package/package.json +17 -14
  112. package/pier_agents/candidate_contract.py +238 -24
  113. package/pier_agents/tangle_candidate.py +75 -5
  114. package/scripts/verify-packed-consumer.mjs +84 -17
  115. package/scripts/verify-pier-agent.mts +6 -4
  116. package/src/benchmarks/_harness.test.mts +16 -1
  117. package/src/benchmarks/_harness.ts +9 -2
  118. package/src/benchmarks/terminal-bench.ts +2 -1
  119. package/src/corpus.test.mts +13 -0
  120. package/src/corpus.ts +4 -0
  121. package/src/profile-coordinates.ts +2 -2
  122. package/src/rollout-ledger/backfill-swe-arena.mts +5 -1
  123. package/src/rollout-ledger/settle-capture.mts +7 -1
  124. package/src/search-bench/profiles.ts +1 -1
  125. package/src/skill-sandbox-smoke.mts +2 -1
  126. package/src/swe-arena/gepa-seat.mts +1 -1
  127. package/src/swe-arena/ledger-orphans.test.mts +36 -34
  128. package/dist/benchmarks/cadbench.js.map +0 -1
  129. package/dist/benchmarks/cadgenbench.js.map +0 -1
  130. package/dist/benchmarks/types.js.map +0 -1
  131. package/dist/chunk-3U5TXJZS.js +0 -251
  132. package/dist/chunk-3U5TXJZS.js.map +0 -1
  133. package/dist/chunk-53UPUNBZ.js +0 -325
  134. package/dist/chunk-53UPUNBZ.js.map +0 -1
  135. package/dist/chunk-5H5XV76F.js +0 -240
  136. package/dist/chunk-5H5XV76F.js.map +0 -1
  137. package/dist/chunk-7GRVHU22.js +0 -208
  138. package/dist/chunk-7GRVHU22.js.map +0 -1
  139. package/dist/chunk-C7T7WEK2.js +0 -103
  140. package/dist/chunk-C7T7WEK2.js.map +0 -1
  141. package/dist/chunk-HWST3SED.js +0 -162
  142. package/dist/chunk-HWST3SED.js.map +0 -1
  143. package/dist/chunk-IA2FBTWC.js +0 -318
  144. package/dist/chunk-IA2FBTWC.js.map +0 -1
  145. package/dist/chunk-IFVINJ4B.js +0 -142
  146. package/dist/chunk-IFVINJ4B.js.map +0 -1
  147. package/dist/chunk-INNOYXCP.js +0 -387
  148. package/dist/chunk-INNOYXCP.js.map +0 -1
  149. package/dist/chunk-IZ5M6OAC.js +0 -169
  150. package/dist/chunk-IZ5M6OAC.js.map +0 -1
  151. package/dist/chunk-JTHWEDEW.js +0 -32
  152. package/dist/chunk-JTHWEDEW.js.map +0 -1
  153. package/dist/chunk-K3BQGZCT.js +0 -221
  154. package/dist/chunk-K3BQGZCT.js.map +0 -1
  155. package/dist/chunk-KP5KD6EN.js +0 -276
  156. package/dist/chunk-KP5KD6EN.js.map +0 -1
  157. package/dist/chunk-MQMRLGOG.js +0 -136
  158. package/dist/chunk-MQMRLGOG.js.map +0 -1
  159. package/dist/chunk-NQG5XDSB.js +0 -147
  160. package/dist/chunk-NQG5XDSB.js.map +0 -1
  161. package/dist/chunk-PA2ZKHJC.js +0 -230
  162. package/dist/chunk-PA2ZKHJC.js.map +0 -1
  163. package/dist/chunk-PB64GYIG.js +0 -118
  164. package/dist/chunk-PB64GYIG.js.map +0 -1
  165. package/dist/chunk-PUIRNYI7.js +0 -189
  166. package/dist/chunk-PUIRNYI7.js.map +0 -1
  167. package/dist/chunk-RCYQEFNX.js +0 -30
  168. package/dist/chunk-RCYQEFNX.js.map +0 -1
  169. package/dist/chunk-RH5F53JT.js +0 -182
  170. package/dist/chunk-RH5F53JT.js.map +0 -1
  171. package/dist/chunk-SEVJPLZC.js +0 -260
  172. package/dist/chunk-SEVJPLZC.js.map +0 -1
  173. package/dist/chunk-SFLA7OH3.js +0 -27
  174. package/dist/chunk-SFLA7OH3.js.map +0 -1
  175. package/dist/chunk-SHM6MRRF.js +0 -130
  176. package/dist/chunk-SHM6MRRF.js.map +0 -1
  177. package/dist/chunk-SHYIRB7I.js +0 -120
  178. package/dist/chunk-SHYIRB7I.js.map +0 -1
  179. package/dist/chunk-SVR2LKYI.js +0 -116
  180. package/dist/chunk-SVR2LKYI.js.map +0 -1
  181. package/dist/chunk-TBKU5XQI.js +0 -228
  182. package/dist/chunk-TBKU5XQI.js.map +0 -1
  183. package/dist/chunk-UPAMRDX4.js +0 -233
  184. package/dist/chunk-UPAMRDX4.js.map +0 -1
  185. package/dist/chunk-V7AEBY6U.js +0 -144
  186. package/dist/chunk-V7AEBY6U.js.map +0 -1
  187. package/dist/chunk-VQRS7VUC.js +0 -342
  188. package/dist/chunk-VQRS7VUC.js.map +0 -1
  189. package/dist/chunk-WSKWVEQB.js +0 -317
  190. package/dist/chunk-WSKWVEQB.js.map +0 -1
  191. package/dist/chunk-X3BTXCJ4.js +0 -262
  192. package/dist/chunk-X3BTXCJ4.js.map +0 -1
  193. package/dist/chunk-XKEFIFIC.js +0 -197
  194. package/dist/chunk-XKEFIFIC.js.map +0 -1
  195. package/dist/chunk-XYA4XSNU.js +0 -148
  196. package/dist/chunk-XYA4XSNU.js.map +0 -1
  197. package/dist/chunk-YSMEKBTD.js +0 -211
  198. package/dist/chunk-YSMEKBTD.js.map +0 -1
  199. package/dist/chunk-Z4TZ76N7.js +0 -170
  200. package/dist/chunk-Z4TZ76N7.js.map +0 -1
@@ -1,31 +1,9 @@
1
- import { OutputAdapter } from '@tangle-network/agent-runtime/loops';
2
- import { BenchmarkAdapter } from './types.js';
3
-
4
- /**
5
- * Commit0 adapter (wentingzhao/commit0_combined) — implement-a-library-from-scratch.
6
- * Each record is a Python repo stubbed at `base_commit` (public function bodies
7
- * emptied to `pass`) + the full test suite + a natural-language spec URL. Worker
8
- * artifact = a unified diff that fills in `src_dir`. Judge = the official
9
- * `commit0` test harness: it stages the starter repo, applies the worker's diff,
10
- * builds the library's deps and runs `pytest`, writing a per-repo pytest-json
11
- * `report.json`. Score = (passed + xfail) / total — GRADED / partial-credit (the
12
- * macro-averaged unit-test pass-rate the leaderboard reports). Fully
13
- * deterministic — no LLM judge.
14
- *
15
- * The OutputAdapter is stream-only (the SWE wrinkle), so the worker emits its
16
- * implementation as a fenced ```diff against the stubbed repo — same deliverable
17
- * shape as swe-bench. The expensive per-repo clone+build+test is delegated to the
18
- * real `commit0` harness on a local Docker backend (NOT reimplemented here).
19
- *
20
- * Requires for a live run: an ISOLATED `.venv-commit0` with `commit0` installed
21
- * (its deps conflict with the shared bench `.venv`; override with COMMIT0_VENV) +
22
- * a Docker daemon (`--backend local`). For offline/CI dataset listing set
23
- * COMMIT0_FIXTURES=1 to load the committed lite rows (bench/fixtures/commit0.json)
24
- * — judging still needs the harness + Docker and fails loud, never a fabricated score.
25
- */
26
-
1
+ import { BenchmarkAdapter } from "./types.js";
2
+ import { OutputAdapter } from "@tangle-network/agent-runtime/loops";
3
+ //#region src/benchmarks/commit0.d.ts
27
4
  /** Reuse the SWE patch extractor shape: last fenced diff/patch, else raw text. */
28
5
  declare const commit0DiffOutput: OutputAdapter<string>;
29
6
  declare function createCommit0Adapter(): BenchmarkAdapter;
30
-
7
+ //#endregion
31
8
  export { commit0DiffOutput, createCommit0Adapter };
9
+ //# sourceMappingURL=commit0.d.ts.map
@@ -1,10 +1,188 @@
1
- import {
2
- commit0DiffOutput,
3
- createCommit0Adapter
4
- } from "../chunk-Z4TZ76N7.js";
5
- import "../chunk-WSKWVEQB.js";
6
- export {
7
- commit0DiffOutput,
8
- createCommit0Adapter
9
- };
1
+ import { benchRoot, preflightVenvImports, runVenvScriptStdin, venvPythonAt } from "./_harness.js";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ //#region src/benchmarks/commit0.ts
5
+ /**
6
+ * Commit0 adapter (wentingzhao/commit0_combined) — implement-a-library-from-scratch.
7
+ * Each record is a Python repo stubbed at `base_commit` (public function bodies
8
+ * emptied to `pass`) + the full test suite + a natural-language spec URL. Worker
9
+ * artifact = a unified diff that fills in `src_dir`. Judge = the official
10
+ * `commit0` test harness: it stages the starter repo, applies the worker's diff,
11
+ * builds the library's deps and runs `pytest`, writing a per-repo pytest-json
12
+ * `report.json`. Score = (passed + xfail) / total — GRADED / partial-credit (the
13
+ * macro-averaged unit-test pass-rate the leaderboard reports). Fully
14
+ * deterministic — no LLM judge.
15
+ *
16
+ * The OutputAdapter is stream-only (the SWE wrinkle), so the worker emits its
17
+ * implementation as a fenced ```diff against the stubbed repo — same deliverable
18
+ * shape as swe-bench. The expensive per-repo clone+build+test is delegated to the
19
+ * real `commit0` harness on a local Docker backend (NOT reimplemented here).
20
+ *
21
+ * Requires for a live run: an ISOLATED `.venv-commit0` with `commit0` installed
22
+ * (its deps conflict with the shared bench `.venv`; override with COMMIT0_VENV) +
23
+ * a Docker daemon (`--backend local`). For offline/CI dataset listing set
24
+ * COMMIT0_FIXTURES=1 to load the committed lite rows (bench/fixtures/commit0.json)
25
+ * — judging still needs the harness + Docker and fails loud, never a fabricated score.
26
+ */
27
+ const FIXTURES = join(benchRoot, "fixtures", "commit0.json");
28
+ const commit0VenvDir = () => process.env.COMMIT0_VENV ?? ".venv-commit0";
29
+ const commit0Python = () => venvPythonAt(commit0VenvDir());
30
+ const DATASET = "wentingzhao/commit0_combined";
31
+ const DATASET_SPLIT = "test";
32
+ const ROWS_API = `https://datasets-server.huggingface.co/rows?dataset=${encodeURIComponent(DATASET)}&config=default&split=${DATASET_SPLIT}`;
33
+ /** Reuse the SWE patch extractor shape: last fenced diff/patch, else raw text. */
34
+ const commit0DiffOutput = { parse(events) {
35
+ let text = "";
36
+ for (const ev of events) {
37
+ const d = ev?.data;
38
+ const t = d?.finalText ?? d?.text ?? d?.result;
39
+ if (typeof t === "string" && t.length > 0) text = t;
40
+ }
41
+ const body = ([...text.matchAll(/```(?:diff|patch)?\s*\n([\s\S]*?)```/g)].at(-1)?.[1] ?? text).trim();
42
+ return body.length > 0 ? `${body}\n` : body;
43
+ } };
44
+ function rowToTask(row) {
45
+ const meta = {
46
+ instanceId: row.instance_id,
47
+ repo: row.repo,
48
+ originalRepo: row.original_repo,
49
+ baseCommit: row.base_commit,
50
+ referenceCommit: row.reference_commit,
51
+ srcDir: row.src_dir,
52
+ testDir: row.test.test_dir,
53
+ testCmd: row.test.test_cmd,
54
+ specification: row.setup.specification
55
+ };
56
+ return {
57
+ id: row.instance_id,
58
+ split: DATASET_SPLIT,
59
+ prompt: [
60
+ `Clone https://github.com/${row.repo} into /work, then \`cd /work && git checkout ${row.base_commit}\`.`,
61
+ `This is the STUBBED library: the public functions/classes under \`${row.src_dir}\` have empty bodies (\`pass\`/\`...\`).`,
62
+ `Fill in COMPLETE implementations under \`${row.src_dir}\` so the existing test suite under \`${row.test.test_dir}\` passes. Read those tests and the spec to learn the required behavior.`,
63
+ `Specification / docs: ${row.setup.specification}`,
64
+ "Do NOT edit the test files — the evaluation re-runs the existing tests on a fresh clone. Implement only the source.",
65
+ `When done, from /work run EXACTLY: \`git add -A && git diff --cached -- ${row.src_dir}\` and END your reply with its COMPLETE output as the LAST thing, fenced exactly as \`\`\`diff … \`\`\` (nothing after the closing fence). That fenced diff (against ${row.base_commit}) is the only deliverable.`
66
+ ].join("\n"),
67
+ metadata: meta
68
+ };
69
+ }
70
+ function readMeta(task) {
71
+ const md = task.metadata;
72
+ if (!md || typeof md.instanceId !== "string" || typeof md.referenceCommit !== "string" || typeof md.srcDir !== "string") throw new Error(`commit0 task ${task.id} missing metadata — loadTasks did not populate it`);
73
+ return md;
74
+ }
75
+ function selectRows(rows, opts) {
76
+ let tasks = rows.map(rowToTask);
77
+ if (opts.ids) {
78
+ const want = new Set(opts.ids);
79
+ tasks = tasks.filter((t) => want.has(t.id));
80
+ } else if (opts.limit !== void 0) tasks = tasks.slice(0, opts.limit);
81
+ return tasks;
82
+ }
83
+ async function loadFixtures(opts) {
84
+ const rows = JSON.parse(await readFile(FIXTURES, "utf8"));
85
+ console.warn(`[commit0] COMMIT0_FIXTURES=1 — loading ${rows.length} committed lite rows from ${FIXTURES} (no HF fetch)`);
86
+ return selectRows(rows, opts);
87
+ }
88
+ /** Pull real rows from the HF rows server (paged). limit caps the pull; ids
89
+ * filtered client-side. Throws on a non-OK response (fail loud). */
90
+ async function fetchRows(opts) {
91
+ const target = opts.ids ? opts.ids.length * 4 : opts.limit ?? 16;
92
+ const rows = [];
93
+ const want = opts.ids ? new Set(opts.ids) : null;
94
+ const page = 100;
95
+ for (let offset = 0; offset < 64 && rows.length < target; offset += page) {
96
+ const res = await fetch(`${ROWS_API}&offset=${offset}&length=${page}`);
97
+ if (!res.ok) throw new Error(`commit0 rows HTTP ${res.status} (offset ${offset}): ${(await res.text()).slice(0, 200)}`);
98
+ const got = (await res.json()).rows ?? [];
99
+ if (got.length === 0) break;
100
+ for (const r of got) {
101
+ if (want && !want.has(r.row.instance_id)) continue;
102
+ rows.push(r.row);
103
+ }
104
+ if (got.length < page) break;
105
+ }
106
+ if (rows.length === 0) throw new Error(`commit0: no rows matched ${JSON.stringify(opts)} from ${DATASET}`);
107
+ return rows;
108
+ }
109
+ /**
110
+ * Run the official commit0 harness for one repo over the worker's diff. The
111
+ * harness clones base_commit, applies the diff into src_dir, installs deps and
112
+ * runs pytest, then writes a per-repo pytest-json report. We read that report and
113
+ * compute (passed + xfail) / total — the leaderboard's per-repo pass-rate.
114
+ *
115
+ * This is the expensive, Docker-backed boundary; it is DELEGATED to `commit0`,
116
+ * not reimplemented. The driver script lives in scripts/commit0_judge.py so the
117
+ * harness call + report parse are one auditable python entrypoint.
118
+ */
119
+ async function runHarness(meta, artifact) {
120
+ const judge = join(benchRoot, "scripts", "commit0_judge.py");
121
+ let stdout;
122
+ try {
123
+ stdout = await runVenvScriptStdin(judge, [
124
+ "--dataset",
125
+ DATASET,
126
+ "--split",
127
+ DATASET_SPLIT,
128
+ "--instance",
129
+ meta.instanceId,
130
+ "--src-dir",
131
+ meta.srcDir
132
+ ], artifact, {
133
+ cwd: benchRoot,
134
+ python: commit0Python()
135
+ });
136
+ } catch (err) {
137
+ const e = err;
138
+ throw new Error(`commit0 harness failed for ${meta.instanceId}: ${(e.message || String(err)).slice(0, 1500)}`);
139
+ }
140
+ const report = JSON.parse(stdout.trim().split("\n").at(-1) ?? "{}");
141
+ if (report.error) throw new Error(`commit0 harness error for ${meta.instanceId}: ${report.error}`);
142
+ if (typeof report.passed !== "number" || typeof report.total !== "number") throw new Error(`commit0 judge returned no {passed,total}: ${stdout.slice(0, 400)}`);
143
+ if (report.total <= 0) throw new Error(`commit0 judge measured no tests for ${meta.instanceId} (total=0): ${stdout.slice(0, 400)}`);
144
+ const score = report.passed / report.total;
145
+ return {
146
+ resolved: report.passed === report.total,
147
+ score,
148
+ detail: JSON.stringify({
149
+ instanceId: meta.instanceId,
150
+ passed: report.passed,
151
+ total: report.total
152
+ })
153
+ };
154
+ }
155
+ function createCommit0Adapter() {
156
+ const fixturesMode = process.env.COMMIT0_FIXTURES === "1";
157
+ return {
158
+ name: "commit0",
159
+ output: commit0DiffOutput,
160
+ async preflight() {
161
+ await preflightVenvImports({
162
+ modules: ["commit0"],
163
+ requireDocker: true,
164
+ python: commit0Python(),
165
+ fix: `Fix: (1) python3 -m venv bench/${commit0VenvDir()} && bench/${commit0VenvDir()}/bin/pip install commit0 datasets (an ISOLATED venv — commit0's deps conflict with the shared bench/.venv; override the dir with COMMIT0_VENV) ; (2) ensure the Docker daemon is running (commit0 --backend local builds per-repo images). Dataset rows come from the HF rows server; set COMMIT0_FIXTURES=1 to list the committed lite rows offline.`
166
+ });
167
+ },
168
+ async loadTasks(opts = {}) {
169
+ if (fixturesMode) return loadFixtures(opts);
170
+ let rows;
171
+ try {
172
+ rows = await fetchRows(opts);
173
+ } catch (err) {
174
+ console.warn(`[commit0] live rows fetch failed (${err instanceof Error ? err.message : err}); falling back to committed fixtures at ${FIXTURES}`);
175
+ return loadFixtures(opts);
176
+ }
177
+ return selectRows(rows, opts);
178
+ },
179
+ async goldArtifact() {},
180
+ async judge(task, artifact) {
181
+ return runHarness(readMeta(task), artifact);
182
+ }
183
+ };
184
+ }
185
+ //#endregion
186
+ export { commit0DiffOutput, createCommit0Adapter };
187
+
10
188
  //# sourceMappingURL=commit0.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"file":"commit0.js","names":[],"sources":["../../src/benchmarks/commit0.ts"],"sourcesContent":["/**\n * Commit0 adapter (wentingzhao/commit0_combined) — implement-a-library-from-scratch.\n * Each record is a Python repo stubbed at `base_commit` (public function bodies\n * emptied to `pass`) + the full test suite + a natural-language spec URL. Worker\n * artifact = a unified diff that fills in `src_dir`. Judge = the official\n * `commit0` test harness: it stages the starter repo, applies the worker's diff,\n * builds the library's deps and runs `pytest`, writing a per-repo pytest-json\n * `report.json`. Score = (passed + xfail) / total — GRADED / partial-credit (the\n * macro-averaged unit-test pass-rate the leaderboard reports). Fully\n * deterministic — no LLM judge.\n *\n * The OutputAdapter is stream-only (the SWE wrinkle), so the worker emits its\n * implementation as a fenced ```diff against the stubbed repo — same deliverable\n * shape as swe-bench. The expensive per-repo clone+build+test is delegated to the\n * real `commit0` harness on a local Docker backend (NOT reimplemented here).\n *\n * Requires for a live run: an ISOLATED `.venv-commit0` with `commit0` installed\n * (its deps conflict with the shared bench `.venv`; override with COMMIT0_VENV) +\n * a Docker daemon (`--backend local`). For offline/CI dataset listing set\n * COMMIT0_FIXTURES=1 to load the committed lite rows (bench/fixtures/commit0.json)\n * — judging still needs the harness + Docker and fails loud, never a fabricated score.\n */\n\nimport { join } from 'node:path'\nimport { readFile } from 'node:fs/promises'\nimport type { OutputAdapter } from '@tangle-network/agent-runtime/loops'\nimport { benchRoot, preflightVenvImports, runVenvScriptStdin, venvPythonAt } from './_harness'\nimport type { BenchmarkAdapter, BenchScore, BenchTask, LoadOptions } from './types'\n\nconst FIXTURES = join(benchRoot, 'fixtures', 'commit0.json')\n\n// commit0's pip deps (pydantic/sqlalchemy v1, modal, …) conflict with the shared\n// bench .venv, so its harness runs in an ISOLATED venv. Override with COMMIT0_VENV.\n// Resolved at call-time so the env is honored at run-time (not frozen at import).\nconst commit0VenvDir = (): string => process.env.COMMIT0_VENV ?? '.venv-commit0'\nconst commit0Python = (): string => venvPythonAt(commit0VenvDir())\n\nconst DATASET = 'wentingzhao/commit0_combined'\nconst DATASET_SPLIT = 'test'\n// HF rows server — columnar pull with no `datasets` install required for listing.\nconst ROWS_API = `https://datasets-server.huggingface.co/rows?dataset=${encodeURIComponent(DATASET)}&config=default&split=${DATASET_SPLIT}`\n\n/** Reuse the SWE patch extractor shape: last fenced diff/patch, else raw text. */\nexport const commit0DiffOutput: OutputAdapter<string> = {\n parse(events) {\n let text = ''\n for (const ev of events) {\n const d = (ev as { data?: Record<string, unknown> })?.data\n const t = d?.finalText ?? d?.text ?? d?.result\n if (typeof t === 'string' && t.length > 0) text = t\n }\n const fences = [...text.matchAll(/```(?:diff|patch)?\\s*\\n([\\s\\S]*?)```/g)]\n const body = (fences.at(-1)?.[1] ?? text).trim()\n // `git apply` rejects a patch that is not newline-terminated (\"corrupt patch at\n // line N+1\"); the .trim() above strips the final newline, so restore exactly one.\n return body.length > 0 ? `${body}\\n` : body\n },\n}\n\ninterface Commit0Setup {\n install: string\n packages: string[] | null\n pip_packages: string[] | null\n pre_install: string[] | null\n python: string\n specification: string\n}\n\ninterface Commit0Row {\n instance_id: string\n repo: string\n original_repo: string\n base_commit: string\n reference_commit: string\n setup: Commit0Setup\n test: { test_cmd: string; test_dir: string }\n src_dir: string\n}\n\ninterface Commit0Meta {\n instanceId: string\n repo: string\n originalRepo: string\n baseCommit: string\n referenceCommit: string\n srcDir: string\n testDir: string\n testCmd: string\n specification: string\n}\n\nfunction rowToTask(row: Commit0Row): BenchTask {\n const meta: Commit0Meta = {\n instanceId: row.instance_id,\n repo: row.repo,\n originalRepo: row.original_repo,\n baseCommit: row.base_commit,\n referenceCommit: row.reference_commit,\n srcDir: row.src_dir,\n testDir: row.test.test_dir,\n testCmd: row.test.test_cmd,\n specification: row.setup.specification,\n }\n return {\n id: row.instance_id,\n split: DATASET_SPLIT,\n prompt: [\n `Clone https://github.com/${row.repo} into /work, then \\`cd /work && git checkout ${row.base_commit}\\`.`,\n `This is the STUBBED library: the public functions/classes under \\`${row.src_dir}\\` have empty bodies (\\`pass\\`/\\`...\\`).`,\n `Fill in COMPLETE implementations under \\`${row.src_dir}\\` so the existing test suite under \\`${row.test.test_dir}\\` passes. Read those tests and the spec to learn the required behavior.`,\n `Specification / docs: ${row.setup.specification}`,\n 'Do NOT edit the test files — the evaluation re-runs the existing tests on a fresh clone. Implement only the source.',\n `When done, from /work run EXACTLY: \\`git add -A && git diff --cached -- ${row.src_dir}\\` and END your reply with its COMPLETE output as the LAST thing, fenced exactly as \\`\\`\\`diff … \\`\\`\\` (nothing after the closing fence). That fenced diff (against ${row.base_commit}) is the only deliverable.`,\n ].join('\\n'),\n metadata: meta as unknown as Record<string, unknown>,\n }\n}\n\nfunction readMeta(task: BenchTask): Commit0Meta {\n const md = task.metadata\n if (!md || typeof md.instanceId !== 'string' || typeof md.referenceCommit !== 'string' || typeof md.srcDir !== 'string') {\n throw new Error(`commit0 task ${task.id} missing metadata — loadTasks did not populate it`)\n }\n return md as unknown as Commit0Meta\n}\n\nfunction selectRows(rows: Commit0Row[], opts: LoadOptions): BenchTask[] {\n let tasks = rows.map(rowToTask)\n if (opts.ids) {\n const want = new Set(opts.ids)\n tasks = tasks.filter((t) => want.has(t.id))\n } else if (opts.limit !== undefined) {\n tasks = tasks.slice(0, opts.limit)\n }\n return tasks\n}\n\nasync function loadFixtures(opts: LoadOptions): Promise<BenchTask[]> {\n const rows = JSON.parse(await readFile(FIXTURES, 'utf8')) as Commit0Row[]\n console.warn(\n `[commit0] COMMIT0_FIXTURES=1 — loading ${rows.length} committed lite rows from ${FIXTURES} (no HF fetch)`,\n )\n return selectRows(rows, opts)\n}\n\n/** Pull real rows from the HF rows server (paged). limit caps the pull; ids\n * filtered client-side. Throws on a non-OK response (fail loud). */\nasync function fetchRows(opts: LoadOptions): Promise<Commit0Row[]> {\n const target = opts.ids ? opts.ids.length * 4 : (opts.limit ?? 16)\n const rows: Commit0Row[] = []\n const want = opts.ids ? new Set(opts.ids) : null\n const page = 100\n for (let offset = 0; offset < 64 && rows.length < target; offset += page) {\n const res = await fetch(`${ROWS_API}&offset=${offset}&length=${page}`)\n if (!res.ok) throw new Error(`commit0 rows HTTP ${res.status} (offset ${offset}): ${(await res.text()).slice(0, 200)}`)\n const body = (await res.json()) as { rows?: Array<{ row: Commit0Row }>; num_rows_total?: number }\n const got = body.rows ?? []\n if (got.length === 0) break\n for (const r of got) {\n if (want && !want.has(r.row.instance_id)) continue\n rows.push(r.row)\n }\n if (got.length < page) break\n }\n if (rows.length === 0) throw new Error(`commit0: no rows matched ${JSON.stringify(opts)} from ${DATASET}`)\n return rows\n}\n\n/**\n * Run the official commit0 harness for one repo over the worker's diff. The\n * harness clones base_commit, applies the diff into src_dir, installs deps and\n * runs pytest, then writes a per-repo pytest-json report. We read that report and\n * compute (passed + xfail) / total — the leaderboard's per-repo pass-rate.\n *\n * This is the expensive, Docker-backed boundary; it is DELEGATED to `commit0`,\n * not reimplemented. The driver script lives in scripts/commit0_judge.py so the\n * harness call + report parse are one auditable python entrypoint.\n */\nasync function runHarness(meta: Commit0Meta, artifact: string): Promise<BenchScore> {\n const judge = join(benchRoot, 'scripts', 'commit0_judge.py')\n let stdout: string\n try {\n // The worker's diff is piped to the driver's stdin (shared stdin-aware runner —\n // execFile's `input` option is not honored async and hangs the reader).\n stdout = await runVenvScriptStdin(\n judge,\n ['--dataset', DATASET, '--split', DATASET_SPLIT, '--instance', meta.instanceId, '--src-dir', meta.srcDir],\n artifact,\n { cwd: benchRoot, python: commit0Python() },\n )\n } catch (err) {\n const e = err as { message?: string }\n throw new Error(`commit0 harness failed for ${meta.instanceId}: ${(e.message || String(err)).slice(0, 1500)}`)\n }\n const report = JSON.parse(stdout.trim().split('\\n').at(-1) ?? '{}') as {\n passed?: number\n total?: number\n error?: string\n }\n if (report.error) throw new Error(`commit0 harness error for ${meta.instanceId}: ${report.error}`)\n if (typeof report.passed !== 'number' || typeof report.total !== 'number') {\n throw new Error(`commit0 judge returned no {passed,total}: ${stdout.slice(0, 400)}`)\n }\n // total=0 means the harness MEASURED NOTHING (collection error with no declared\n // test ids) — an unmeasured attempt, not a 0% one. Throw so the caller excludes\n // it as infra instead of recording a fabricated zero.\n if (report.total <= 0) {\n throw new Error(`commit0 judge measured no tests for ${meta.instanceId} (total=0): ${stdout.slice(0, 400)}`)\n }\n const score = report.passed / report.total\n return {\n resolved: report.passed === report.total,\n score,\n detail: JSON.stringify({ instanceId: meta.instanceId, passed: report.passed, total: report.total }),\n }\n}\n\nexport function createCommit0Adapter(): BenchmarkAdapter {\n const fixturesMode = process.env.COMMIT0_FIXTURES === '1'\n\n return {\n name: 'commit0',\n output: commit0DiffOutput,\n\n async preflight() {\n await preflightVenvImports({\n modules: ['commit0'],\n requireDocker: true,\n python: commit0Python(),\n fix:\n `Fix: (1) python3 -m venv bench/${commit0VenvDir()} && bench/${commit0VenvDir()}/bin/pip install commit0 datasets ` +\n `(an ISOLATED venv — commit0's deps conflict with the shared bench/.venv; override the dir with COMMIT0_VENV) ; ` +\n `(2) ensure the Docker daemon is running (commit0 --backend local builds per-repo images). ` +\n `Dataset rows come from the HF rows server; set COMMIT0_FIXTURES=1 to list the committed lite rows offline.`,\n })\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n if (fixturesMode) return loadFixtures(opts)\n let rows: Commit0Row[]\n try {\n rows = await fetchRows(opts)\n } catch (err) {\n console.warn(\n `[commit0] live rows fetch failed (${err instanceof Error ? err.message : err}); falling back to committed fixtures at ${FIXTURES}`,\n )\n return loadFixtures(opts)\n }\n return selectRows(rows, opts)\n },\n\n async goldArtifact() {\n // The oracle is the reference_commit's src_dir, which the commit0 harness\n // checks out by ref — not expressible as a portable diff string without\n // cloning. verify-judge against this adapter requires the live harness, so\n // we return undefined (no offline gold-diff). Judge correctness is proven by\n // running the harness on a real solve, not by a synthetic gold patch.\n return undefined\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const meta = readMeta(task)\n return runHarness(meta, artifact)\n },\n }\n}\n"],"mappings":"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"}
@@ -1,14 +1,6 @@
1
- import { BenchmarkAdapter } from './types.js';
2
- import '@tangle-network/agent-runtime/loops';
3
-
4
- /**
5
- * CRAG adapter (Comprehensive RAG Benchmark).
6
- *
7
- * Live mode expects an official or compatible CRAG JSON/JSONL export. The
8
- * adapter preserves CRAG domain/type/dynamism tags in metadata and scores final
9
- * answers deterministically against the provided gold answer list.
10
- */
11
-
1
+ import { BenchmarkAdapter } from "./types.js";
2
+ //#region src/benchmarks/crag.d.ts
12
3
  declare function createCragAdapter(): BenchmarkAdapter;
13
-
4
+ //#endregion
14
5
  export { createCragAdapter };
6
+ //# sourceMappingURL=crag.d.ts.map
@@ -1,9 +1,111 @@
1
- import {
2
- createCragAdapter
3
- } from "../chunk-SVR2LKYI.js";
4
- import "../chunk-X3BTXCJ4.js";
5
- import "../chunk-WSKWVEQB.js";
6
- export {
7
- createCragAdapter
8
- };
1
+ import { benchRoot } from "./_harness.js";
2
+ import { FINAL_ANSWER_SENTINEL, allStrings, answerScoreToBenchScore, firstString, isObject, ragAnswerOutput, readJsonRows, scoreAnswerArtifact, selectTasks, stringFrom } from "./rag-shared.js";
3
+ import { readFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ //#region src/benchmarks/crag.ts
6
+ /**
7
+ * CRAG adapter (Comprehensive RAG Benchmark).
8
+ *
9
+ * Live mode expects an official or compatible CRAG JSON/JSONL export. The
10
+ * adapter preserves CRAG domain/type/dynamism tags in metadata and scores final
11
+ * answers deterministically against the provided gold answer list.
12
+ */
13
+ const FIXTURES = join(benchRoot, "fixtures", "crag.json");
14
+ const dataFile = () => process.env.CRAG_DATA_FILE;
15
+ function rowToTask(raw, index) {
16
+ if (!isObject(raw)) throw new Error(`CRAG row ${index} must be an object`);
17
+ const query = firstString(raw, [
18
+ "query",
19
+ "question",
20
+ "prompt"
21
+ ]);
22
+ const goldAnswers = allStrings(raw, [
23
+ "answer",
24
+ "answers",
25
+ "gold",
26
+ "gold_answer",
27
+ "expected_answer"
28
+ ]);
29
+ if (!query) throw new Error(`CRAG row ${index} missing query`);
30
+ if (goldAnswers.length === 0) throw new Error(`CRAG row ${index} missing gold answer`);
31
+ const domain = stringFrom(raw.domain) ?? "unknown";
32
+ const questionType = stringFrom(raw.question_type) ?? stringFrom(raw.questionType) ?? "unknown";
33
+ const dynamism = stringFrom(raw.static_or_dynamic) ?? stringFrom(raw.dynamism) ?? "unknown";
34
+ const id = stringFrom(raw.id) ?? stringFrom(raw.query_id) ?? `crag-${index}`;
35
+ const meta = {
36
+ benchmark: "crag",
37
+ query,
38
+ goldAnswers,
39
+ domain,
40
+ questionType,
41
+ dynamism
42
+ };
43
+ return {
44
+ id,
45
+ split: stringFrom(raw.split) ?? domain,
46
+ prompt: [
47
+ "Answer this CRAG factual question.",
48
+ "Return a concise answer and do not guess when the evidence is insufficient.",
49
+ "End with a single final line: `FINAL ANSWER: <answer>`.",
50
+ "",
51
+ `Question: ${query}`,
52
+ `Domain: ${domain}`,
53
+ `Question type: ${questionType}`,
54
+ `Dynamism: ${dynamism}`
55
+ ].join("\n"),
56
+ metadata: meta
57
+ };
58
+ }
59
+ function readMeta(task) {
60
+ const md = task.metadata;
61
+ if (!md || !Array.isArray(md.goldAnswers)) throw new Error(`CRAG task ${task.id} missing metadata — loadTasks did not populate it`);
62
+ return md;
63
+ }
64
+ async function loadRows(path) {
65
+ const rows = await readJsonRows(path);
66
+ if (rows.length === 0) throw new Error(`CRAG: no rows in ${path}`);
67
+ return rows;
68
+ }
69
+ async function loadFixtures(opts) {
70
+ const rows = JSON.parse(await readFile(FIXTURES, "utf8"));
71
+ console.warn(`[crag] CRAG_FIXTURES=1 — loading ${rows.length} adapter fixtures`);
72
+ return selectTasks(rows.map(rowToTask), opts, "CRAG");
73
+ }
74
+ function createCragAdapter() {
75
+ const fixturesMode = process.env.CRAG_FIXTURES === "1";
76
+ return {
77
+ name: "crag",
78
+ output: ragAnswerOutput,
79
+ async preflight() {
80
+ if (fixturesMode) {
81
+ await readFile(FIXTURES, "utf8");
82
+ return;
83
+ }
84
+ const path = dataFile();
85
+ if (!path) throw new Error("CRAG_DATA_FILE is required. Fix: export facebookresearch/CRAG rows to JSONL and set CRAG_DATA_FILE=/path/to/crag.jsonl, or set CRAG_FIXTURES=1 for adapter plumbing.");
86
+ await loadRows(path);
87
+ },
88
+ async loadTasks(opts = {}) {
89
+ if (fixturesMode) return loadFixtures(opts);
90
+ const path = dataFile();
91
+ if (!path) throw new Error("CRAG_DATA_FILE is required to load CRAG tasks");
92
+ return selectTasks((await loadRows(path)).map(rowToTask), opts, "CRAG");
93
+ },
94
+ async goldArtifact(task) {
95
+ return `${FINAL_ANSWER_SENTINEL} ${readMeta(task).goldAnswers[0] ?? ""}`;
96
+ },
97
+ async judge(task, artifact) {
98
+ const meta = readMeta(task);
99
+ return answerScoreToBenchScore(scoreAnswerArtifact(artifact, meta.goldAnswers), {
100
+ benchmark: meta.benchmark,
101
+ domain: meta.domain,
102
+ questionType: meta.questionType,
103
+ dynamism: meta.dynamism
104
+ });
105
+ }
106
+ };
107
+ }
108
+ //#endregion
109
+ export { createCragAdapter };
110
+
9
111
  //# sourceMappingURL=crag.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"file":"crag.js","names":[],"sources":["../../src/benchmarks/crag.ts"],"sourcesContent":["/**\n * CRAG adapter (Comprehensive RAG Benchmark).\n *\n * Live mode expects an official or compatible CRAG JSON/JSONL export. The\n * adapter preserves CRAG domain/type/dynamism tags in metadata and scores final\n * answers deterministically against the provided gold answer list.\n */\n\nimport { readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { benchRoot } from './_harness'\nimport type { BenchmarkAdapter, BenchScore, BenchTask, LoadOptions } from './types'\nimport {\n FINAL_ANSWER_SENTINEL,\n allStrings,\n answerScoreToBenchScore,\n firstString,\n isObject,\n ragAnswerOutput,\n readJsonRows,\n scoreAnswerArtifact,\n selectTasks,\n stringFrom,\n} from './rag-shared'\n\nconst FIXTURES = join(benchRoot, 'fixtures', 'crag.json')\n\ninterface CragMeta {\n benchmark: 'crag'\n query: string\n goldAnswers: string[]\n domain: string\n questionType: string\n dynamism: string\n}\n\nconst dataFile = (): string | undefined => process.env.CRAG_DATA_FILE\n\nfunction rowToTask(raw: unknown, index: number): BenchTask {\n if (!isObject(raw)) throw new Error(`CRAG row ${index} must be an object`)\n const query = firstString(raw, ['query', 'question', 'prompt'])\n const goldAnswers = allStrings(raw, ['answer', 'answers', 'gold', 'gold_answer', 'expected_answer'])\n if (!query) throw new Error(`CRAG row ${index} missing query`)\n if (goldAnswers.length === 0) throw new Error(`CRAG row ${index} missing gold answer`)\n const domain = stringFrom(raw.domain) ?? 'unknown'\n const questionType = stringFrom(raw.question_type) ?? stringFrom(raw.questionType) ?? 'unknown'\n const dynamism = stringFrom(raw.static_or_dynamic) ?? stringFrom(raw.dynamism) ?? 'unknown'\n const id = stringFrom(raw.id) ?? stringFrom(raw.query_id) ?? `crag-${index}`\n const meta: CragMeta = {\n benchmark: 'crag',\n query,\n goldAnswers,\n domain,\n questionType,\n dynamism,\n }\n return {\n id,\n split: stringFrom(raw.split) ?? domain,\n prompt: [\n 'Answer this CRAG factual question.',\n 'Return a concise answer and do not guess when the evidence is insufficient.',\n 'End with a single final line: `FINAL ANSWER: <answer>`.',\n '',\n `Question: ${query}`,\n `Domain: ${domain}`,\n `Question type: ${questionType}`,\n `Dynamism: ${dynamism}`,\n ].join('\\n'),\n metadata: meta as unknown as Record<string, unknown>,\n }\n}\n\nfunction readMeta(task: BenchTask): CragMeta {\n const md = task.metadata\n if (!md || !Array.isArray(md.goldAnswers)) {\n throw new Error(`CRAG task ${task.id} missing metadata — loadTasks did not populate it`)\n }\n return md as unknown as CragMeta\n}\n\nasync function loadRows(path: string): Promise<unknown[]> {\n const rows = await readJsonRows(path)\n if (rows.length === 0) throw new Error(`CRAG: no rows in ${path}`)\n return rows\n}\n\nasync function loadFixtures(opts: LoadOptions): Promise<BenchTask[]> {\n const rows = JSON.parse(await readFile(FIXTURES, 'utf8')) as unknown[]\n console.warn(`[crag] CRAG_FIXTURES=1 — loading ${rows.length} adapter fixtures`)\n return selectTasks(rows.map(rowToTask), opts, 'CRAG')\n}\n\nexport function createCragAdapter(): BenchmarkAdapter {\n const fixturesMode = process.env.CRAG_FIXTURES === '1'\n\n return {\n name: 'crag',\n output: ragAnswerOutput,\n\n async preflight() {\n if (fixturesMode) {\n await readFile(FIXTURES, 'utf8')\n return\n }\n const path = dataFile()\n if (!path) {\n throw new Error(\n 'CRAG_DATA_FILE is required. Fix: export facebookresearch/CRAG rows to JSONL and set CRAG_DATA_FILE=/path/to/crag.jsonl, or set CRAG_FIXTURES=1 for adapter plumbing.',\n )\n }\n await loadRows(path)\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n if (fixturesMode) return loadFixtures(opts)\n const path = dataFile()\n if (!path) throw new Error('CRAG_DATA_FILE is required to load CRAG tasks')\n return selectTasks((await loadRows(path)).map(rowToTask), opts, 'CRAG')\n },\n\n async goldArtifact(task: BenchTask) {\n return `${FINAL_ANSWER_SENTINEL} ${readMeta(task).goldAnswers[0] ?? ''}`\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const meta = readMeta(task)\n const score = scoreAnswerArtifact(artifact, meta.goldAnswers)\n return answerScoreToBenchScore(score, {\n benchmark: meta.benchmark,\n domain: meta.domain,\n questionType: meta.questionType,\n dynamism: meta.dynamism,\n })\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;AAyBA,MAAM,WAAW,KAAK,WAAW,YAAY,WAAW;AAWxD,MAAM,iBAAqC,QAAQ,IAAI;AAEvD,SAAS,UAAU,KAAc,OAA0B;CACzD,IAAI,CAAC,SAAS,GAAG,GAAG,MAAM,IAAI,MAAM,YAAY,MAAM,mBAAmB;CACzE,MAAM,QAAQ,YAAY,KAAK;EAAC;EAAS;EAAY;CAAQ,CAAC;CAC9D,MAAM,cAAc,WAAW,KAAK;EAAC;EAAU;EAAW;EAAQ;EAAe;CAAiB,CAAC;CACnG,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,YAAY,MAAM,eAAe;CAC7D,IAAI,YAAY,WAAW,GAAG,MAAM,IAAI,MAAM,YAAY,MAAM,qBAAqB;CACrF,MAAM,SAAS,WAAW,IAAI,MAAM,KAAK;CACzC,MAAM,eAAe,WAAW,IAAI,aAAa,KAAK,WAAW,IAAI,YAAY,KAAK;CACtF,MAAM,WAAW,WAAW,IAAI,iBAAiB,KAAK,WAAW,IAAI,QAAQ,KAAK;CAClF,MAAM,KAAK,WAAW,IAAI,EAAE,KAAK,WAAW,IAAI,QAAQ,KAAK,QAAQ;CACrE,MAAM,OAAiB;EACrB,WAAW;EACX;EACA;EACA;EACA;EACA;CACF;CACA,OAAO;EACL;EACA,OAAO,WAAW,IAAI,KAAK,KAAK;EAChC,QAAQ;GACN;GACA;GACA;GACA;GACA,aAAa;GACb,WAAW;GACX,kBAAkB;GAClB,aAAa;EACf,CAAC,CAAC,KAAK,IAAI;EACX,UAAU;CACZ;AACF;AAEA,SAAS,SAAS,MAA2B;CAC3C,MAAM,KAAK,KAAK;CAChB,IAAI,CAAC,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,GACtC,MAAM,IAAI,MAAM,aAAa,KAAK,GAAG,kDAAkD;CAEzF,OAAO;AACT;AAEA,eAAe,SAAS,MAAkC;CACxD,MAAM,OAAO,MAAM,aAAa,IAAI;CACpC,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,MAAM,oBAAoB,MAAM;CACjE,OAAO;AACT;AAEA,eAAe,aAAa,MAAyC;CACnE,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS,UAAU,MAAM,CAAC;CACxD,QAAQ,KAAK,oCAAoC,KAAK,OAAO,kBAAkB;CAC/E,OAAO,YAAY,KAAK,IAAI,SAAS,GAAG,MAAM,MAAM;AACtD;AAEA,SAAgB,oBAAsC;CACpD,MAAM,eAAe,QAAQ,IAAI,kBAAkB;CAEnD,OAAO;EACL,MAAM;EACN,QAAQ;EAER,MAAM,YAAY;GAChB,IAAI,cAAc;IAChB,MAAM,SAAS,UAAU,MAAM;IAC/B;GACF;GACA,MAAM,OAAO,SAAS;GACtB,IAAI,CAAC,MACH,MAAM,IAAI,MACR,sKACF;GAEF,MAAM,SAAS,IAAI;EACrB;EAEA,MAAM,UAAU,OAAoB,CAAC,GAAG;GACtC,IAAI,cAAc,OAAO,aAAa,IAAI;GAC1C,MAAM,OAAO,SAAS;GACtB,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,+CAA+C;GAC1E,OAAO,aAAa,MAAM,SAAS,IAAI,EAAA,CAAG,IAAI,SAAS,GAAG,MAAM,MAAM;EACxE;EAEA,MAAM,aAAa,MAAiB;GAClC,OAAO,GAAG,sBAAsB,GAAG,SAAS,IAAI,CAAC,CAAC,YAAY,MAAM;EACtE;EAEA,MAAM,MAAM,MAAiB,UAAuC;GAClE,MAAM,OAAO,SAAS,IAAI;GAE1B,OAAO,wBADO,oBAAoB,UAAU,KAAK,WACd,GAAG;IACpC,WAAW,KAAK;IAChB,QAAQ,KAAK;IACb,cAAc,KAAK;IACnB,UAAU,KAAK;GACjB,CAAC;EACH;CACF;AACF"}
@@ -1,18 +1,8 @@
1
- import { OutputAdapter } from '@tangle-network/agent-runtime/loops';
2
- import { BenchmarkAdapter } from './types.js';
3
-
4
- /**
5
- * DABStep adapter (EnvCommons/DABStep) — data-analysis questions over synthetic
6
- * payment files. Worker artifact = final answer text. Judge = the official
7
- * DABStep `grade.py` normalization/matching function. No LLM judge.
8
- *
9
- * Live tasks require `DABSTEP_DIR` pointing at an official DABStep checkout that
10
- * includes `dataset.csv`, `splits/*.txt`, `files/*`, and `grade.py`. The adapter
11
- * exposes `metadata.resourceRoot` so runners can mount the benchmark files into
12
- * AgentProfile.resources.files; it does not paste the dataset into prompt text.
13
- */
14
-
1
+ import { BenchmarkAdapter } from "./types.js";
2
+ import { OutputAdapter } from "@tangle-network/agent-runtime/loops";
3
+ //#region src/benchmarks/dabstep.d.ts
15
4
  declare const dabstepAnswerOutput: OutputAdapter<string>;
16
5
  declare function createDabstepAdapter(): BenchmarkAdapter;
17
-
6
+ //#endregion
18
7
  export { createDabstepAdapter, dabstepAnswerOutput };
8
+ //# sourceMappingURL=dabstep.d.ts.map
@@ -1,10 +1,178 @@
1
- import {
2
- createDabstepAdapter,
3
- dabstepAnswerOutput
4
- } from "../chunk-RH5F53JT.js";
5
- import "../chunk-WSKWVEQB.js";
6
- export {
7
- createDabstepAdapter,
8
- dabstepAnswerOutput
9
- };
1
+ import { benchRoot, runVenvPython, runVenvScriptStdin } from "./_harness.js";
2
+ import { access, readFile, stat } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ //#region src/benchmarks/dabstep.ts
5
+ /**
6
+ * DABStep adapter (EnvCommons/DABStep) — data-analysis questions over synthetic
7
+ * payment files. Worker artifact = final answer text. Judge = the official
8
+ * DABStep `grade.py` normalization/matching function. No LLM judge.
9
+ *
10
+ * Live tasks require `DABSTEP_DIR` pointing at an official DABStep checkout that
11
+ * includes `dataset.csv`, `splits/*.txt`, `files/*`, and `grade.py`. The adapter
12
+ * exposes `metadata.resourceRoot` so runners can mount the benchmark files into
13
+ * AgentProfile.resources.files; it does not paste the dataset into prompt text.
14
+ */
15
+ const FIXTURES = join(benchRoot, "fixtures", "dabstep.json");
16
+ const DEFAULT_SPLIT = "easy";
17
+ const dabstepDir = () => process.env.DABSTEP_DIR;
18
+ const gradeFile = (dir) => join(dir, "grade.py");
19
+ const resourceRoot = (dir) => join(dir, "files");
20
+ async function assertFile(path, label) {
21
+ try {
22
+ await access(path);
23
+ } catch (err) {
24
+ throw new Error(`DABStep: missing ${label} at ${path} (${err instanceof Error ? err.message : err})`);
25
+ }
26
+ }
27
+ async function assertOfficialFiles(dir, split) {
28
+ await assertFile(join(dir, "dataset.csv"), "released dataset.csv");
29
+ await assertFile(join(dir, "splits", `${split}.txt`), `${split} split file`);
30
+ await assertFile(gradeFile(dir), "official grade.py");
31
+ const files = resourceRoot(dir);
32
+ try {
33
+ if (!(await stat(files)).isDirectory()) throw new Error("not a directory");
34
+ } catch (err) {
35
+ throw new Error(`DABStep: missing benchmark files directory at ${files} (${err instanceof Error ? err.message : err})`);
36
+ }
37
+ }
38
+ const dabstepAnswerOutput = { parse(events) {
39
+ let text = "";
40
+ for (const ev of events) {
41
+ const d = ev?.data;
42
+ const t = d?.finalText ?? d?.text ?? d?.result;
43
+ if (typeof t === "string" && t.length > 0) text = t;
44
+ }
45
+ return ([...text.matchAll(/```(?:text|answer)?\s*\n([\s\S]*?)```/g)].at(-1)?.[1] ?? text).trim();
46
+ } };
47
+ function rowToTask(row, split, dir) {
48
+ const meta = {
49
+ taskId: row.task_id,
50
+ split,
51
+ golds: row.all_golds_by_task,
52
+ ...dir ? { resourceRoot: resourceRoot(dir) } : {}
53
+ };
54
+ return {
55
+ id: String(row.task_id),
56
+ split,
57
+ prompt: [
58
+ "Solve this DABStep data-analysis task using the mounted payment files.",
59
+ "Use code or shell commands as needed, then return only the final answer.",
60
+ "",
61
+ row.instructions
62
+ ].join("\n"),
63
+ metadata: meta
64
+ };
65
+ }
66
+ function readMeta(task) {
67
+ const md = task.metadata;
68
+ if (!md || typeof md.taskId !== "number" || !Array.isArray(md.golds)) throw new Error(`dabstep task ${task.id} missing metadata — loadTasks did not populate it`);
69
+ return md;
70
+ }
71
+ function selectRows(rows, opts, split, dir) {
72
+ let tasks = rows.map((row) => rowToTask(row, split, dir));
73
+ if (opts.ids) {
74
+ const want = new Set(opts.ids);
75
+ tasks = tasks.filter((task) => want.has(task.id));
76
+ } else if (opts.limit !== void 0) tasks = tasks.slice(0, opts.limit);
77
+ if (tasks.length === 0) throw new Error(`DABStep: no tasks matched ${JSON.stringify(opts)} for split=${split}`);
78
+ return tasks;
79
+ }
80
+ async function loadFixtures(opts, split) {
81
+ const rows = JSON.parse(await readFile(FIXTURES, "utf8"));
82
+ console.warn(`[dabstep] DABSTEP_FIXTURES=1 — loading ${rows.length} adapter fixtures from ${FIXTURES}`);
83
+ return selectRows(rows, opts, split);
84
+ }
85
+ async function loadOfficialTasks(dir, opts, split) {
86
+ const stdout = await runVenvPython(`
87
+ import ast, csv, json, sys
88
+ from pathlib import Path
89
+
90
+ root = Path(sys.argv[1])
91
+ split = sys.argv[2]
92
+ limit = None if sys.argv[3] == "" else int(sys.argv[3])
93
+ ids = set(json.loads(sys.argv[4]))
94
+ dataset = root / "dataset.csv"
95
+ split_file = root / "splits" / f"{split}.txt"
96
+ if not dataset.exists():
97
+ raise SystemExit(f"missing official DABStep dataset.csv at {dataset}")
98
+ if not split_file.exists():
99
+ raise SystemExit(f"missing official DABStep split file at {split_file}")
100
+ split_ids = {int(line.strip()) for line in split_file.read_text().splitlines() if line.strip()}
101
+ out = []
102
+ with dataset.open(newline="") as f:
103
+ for row in csv.DictReader(f):
104
+ task_id = int(row["task_id"])
105
+ if task_id not in split_ids:
106
+ continue
107
+ if ids and str(task_id) not in ids:
108
+ continue
109
+ out.append({
110
+ "task_id": task_id,
111
+ "instructions": f"{row['question']}\\n{row['guidelines']}",
112
+ "all_golds_by_task": ast.literal_eval(str(row["all_golds_by_task"])),
113
+ })
114
+ if limit is not None and len(out) >= limit:
115
+ break
116
+ if not out:
117
+ raise SystemExit(f"no DABStep rows matched split={split} ids={sorted(ids)} limit={limit}")
118
+ print(json.dumps(out))
119
+ `, [
120
+ dir,
121
+ split,
122
+ opts.limit === void 0 ? "" : String(opts.limit),
123
+ JSON.stringify(opts.ids ?? [])
124
+ ]);
125
+ return selectRows(JSON.parse(stdout), opts, split, dir);
126
+ }
127
+ function createDabstepAdapter() {
128
+ const fixturesMode = process.env.DABSTEP_FIXTURES === "1";
129
+ return {
130
+ name: "dabstep",
131
+ output: dabstepAnswerOutput,
132
+ async preflight() {
133
+ if (fixturesMode) return;
134
+ const dir = dabstepDir();
135
+ if (!dir) throw new Error("DABSTEP_DIR is required. Fix: clone https://github.com/EnvCommons/DABStep, add the released dataset.csv under that checkout, then set DABSTEP_DIR=/path/to/DABStep.");
136
+ await assertOfficialFiles(dir, DEFAULT_SPLIT);
137
+ await loadOfficialTasks(dir, { limit: 1 }, DEFAULT_SPLIT);
138
+ },
139
+ async loadTasks(opts = {}) {
140
+ const split = opts.split ?? DEFAULT_SPLIT;
141
+ if (fixturesMode) return loadFixtures(opts, split);
142
+ const dir = dabstepDir();
143
+ if (!dir) throw new Error("DABSTEP_DIR is required to load official DABStep tasks");
144
+ return loadOfficialTasks(dir, opts, split);
145
+ },
146
+ async goldArtifact(task) {
147
+ const first = readMeta(task).golds[0];
148
+ if (!first) return void 0;
149
+ const value = first.value;
150
+ return value === void 0 ? void 0 : String(value);
151
+ },
152
+ async judge(task, artifact) {
153
+ const meta = readMeta(task);
154
+ const dir = dabstepDir();
155
+ if (!dir) throw new Error("DABSTEP_DIR is required to judge DABStep tasks with the official grade.py");
156
+ const stdout = await runVenvScriptStdin(join(benchRoot, "scripts", "dabstep_judge.py"), ["--grade-file", gradeFile(dir)], JSON.stringify({
157
+ prediction: artifact,
158
+ golds: meta.golds
159
+ }), { cwd: benchRoot });
160
+ const report = JSON.parse(stdout.trim().split("\n").at(-1) ?? "{}");
161
+ if (report.error) throw new Error(`DABStep judge error for ${task.id}: ${report.error}`);
162
+ const score = typeof report.score === "number" ? report.score : 0;
163
+ return {
164
+ resolved: report.correct === true,
165
+ score,
166
+ detail: JSON.stringify({
167
+ taskId: meta.taskId,
168
+ split: meta.split,
169
+ correct: report.correct
170
+ })
171
+ };
172
+ }
173
+ };
174
+ }
175
+ //#endregion
176
+ export { createDabstepAdapter, dabstepAnswerOutput };
177
+
10
178
  //# sourceMappingURL=dabstep.js.map