@tangle-network/agent-bench 0.4.1 → 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 (194) hide show
  1. package/CHANGELOG.md +9 -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 +48 -66
  6. package/dist/benchmarks/_harness.js +329 -33
  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/scripts/verify-packed-consumer.mjs +20 -17
  113. package/src/corpus.test.mts +13 -0
  114. package/src/corpus.ts +4 -0
  115. package/src/profile-coordinates.ts +2 -2
  116. package/src/rollout-ledger/backfill-swe-arena.mts +5 -1
  117. package/src/rollout-ledger/settle-capture.mts +7 -1
  118. package/src/search-bench/profiles.ts +1 -1
  119. package/src/skill-sandbox-smoke.mts +2 -1
  120. package/src/swe-arena/gepa-seat.mts +1 -1
  121. package/src/swe-arena/ledger-orphans.test.mts +36 -34
  122. package/dist/benchmarks/cadbench.js.map +0 -1
  123. package/dist/benchmarks/cadgenbench.js.map +0 -1
  124. package/dist/benchmarks/types.js.map +0 -1
  125. package/dist/chunk-53UPUNBZ.js +0 -325
  126. package/dist/chunk-53UPUNBZ.js.map +0 -1
  127. package/dist/chunk-5FEQDSCT.js +0 -211
  128. package/dist/chunk-5FEQDSCT.js.map +0 -1
  129. package/dist/chunk-5H5XV76F.js +0 -240
  130. package/dist/chunk-5H5XV76F.js.map +0 -1
  131. package/dist/chunk-67ACKDCX.js +0 -118
  132. package/dist/chunk-67ACKDCX.js.map +0 -1
  133. package/dist/chunk-7FKBWOQT.js +0 -147
  134. package/dist/chunk-7FKBWOQT.js.map +0 -1
  135. package/dist/chunk-BEN6IF2X.js +0 -221
  136. package/dist/chunk-BEN6IF2X.js.map +0 -1
  137. package/dist/chunk-BZY5QARD.js +0 -120
  138. package/dist/chunk-BZY5QARD.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-CLIKAXKH.js +0 -276
  142. package/dist/chunk-CLIKAXKH.js.map +0 -1
  143. package/dist/chunk-CWIOBFSP.js +0 -197
  144. package/dist/chunk-CWIOBFSP.js.map +0 -1
  145. package/dist/chunk-CXDUTWQE.js +0 -318
  146. package/dist/chunk-CXDUTWQE.js.map +0 -1
  147. package/dist/chunk-DWALFME7.js +0 -182
  148. package/dist/chunk-DWALFME7.js.map +0 -1
  149. package/dist/chunk-EEOC6QPJ.js +0 -144
  150. package/dist/chunk-EEOC6QPJ.js.map +0 -1
  151. package/dist/chunk-EIETHPD5.js +0 -321
  152. package/dist/chunk-EIETHPD5.js.map +0 -1
  153. package/dist/chunk-GC2EPS6L.js +0 -130
  154. package/dist/chunk-GC2EPS6L.js.map +0 -1
  155. package/dist/chunk-GCHL6XPM.js +0 -169
  156. package/dist/chunk-GCHL6XPM.js.map +0 -1
  157. package/dist/chunk-HQ5HCCKF.js +0 -142
  158. package/dist/chunk-HQ5HCCKF.js.map +0 -1
  159. package/dist/chunk-HVW25KSX.js +0 -208
  160. package/dist/chunk-HVW25KSX.js.map +0 -1
  161. package/dist/chunk-INNOYXCP.js +0 -387
  162. package/dist/chunk-INNOYXCP.js.map +0 -1
  163. package/dist/chunk-J6BU3NTM.js +0 -251
  164. package/dist/chunk-J6BU3NTM.js.map +0 -1
  165. package/dist/chunk-JSQOUKXS.js +0 -149
  166. package/dist/chunk-JSQOUKXS.js.map +0 -1
  167. package/dist/chunk-JTHWEDEW.js +0 -32
  168. package/dist/chunk-JTHWEDEW.js.map +0 -1
  169. package/dist/chunk-NRMGT25X.js +0 -116
  170. package/dist/chunk-NRMGT25X.js.map +0 -1
  171. package/dist/chunk-PA2ZKHJC.js +0 -230
  172. package/dist/chunk-PA2ZKHJC.js.map +0 -1
  173. package/dist/chunk-PUIRNYI7.js +0 -189
  174. package/dist/chunk-PUIRNYI7.js.map +0 -1
  175. package/dist/chunk-QZZEAHWJ.js +0 -136
  176. package/dist/chunk-QZZEAHWJ.js.map +0 -1
  177. package/dist/chunk-SEVJPLZC.js +0 -260
  178. package/dist/chunk-SEVJPLZC.js.map +0 -1
  179. package/dist/chunk-TBKU5XQI.js +0 -228
  180. package/dist/chunk-TBKU5XQI.js.map +0 -1
  181. package/dist/chunk-UPAMRDX4.js +0 -233
  182. package/dist/chunk-UPAMRDX4.js.map +0 -1
  183. package/dist/chunk-VQRS7VUC.js +0 -342
  184. package/dist/chunk-VQRS7VUC.js.map +0 -1
  185. package/dist/chunk-WG7TM7UV.js +0 -30
  186. package/dist/chunk-WG7TM7UV.js.map +0 -1
  187. package/dist/chunk-X3BTXCJ4.js +0 -262
  188. package/dist/chunk-X3BTXCJ4.js.map +0 -1
  189. package/dist/chunk-XXFF3RRD.js +0 -162
  190. package/dist/chunk-XXFF3RRD.js.map +0 -1
  191. package/dist/chunk-ZFNOM7WR.js +0 -27
  192. package/dist/chunk-ZFNOM7WR.js.map +0 -1
  193. package/dist/chunk-ZNCCYTFG.js +0 -170
  194. package/dist/chunk-ZNCCYTFG.js.map +0 -1
@@ -1,14 +1,235 @@
1
- import {
2
- createSweBenchAdapter,
3
- scoreSweReport,
4
- sweEvaluationArgv,
5
- swePatchOutput
6
- } from "../chunk-J6BU3NTM.js";
7
- import "../chunk-EIETHPD5.js";
8
- export {
9
- createSweBenchAdapter,
10
- scoreSweReport,
11
- sweEvaluationArgv,
12
- swePatchOutput
13
- };
1
+ import { preflightVenvImports, readJsonReport, runStagedJudge, runVenvPython, safeRunId, stageFile } from "./_harness.js";
2
+ import { join } from "node:path";
3
+ //#region src/benchmarks/swe-bench.ts
4
+ /**
5
+ * SWE-bench Verified adapter. Worker artifact = a unified-diff patch. Judge =
6
+ * the official `swebench` harness: apply the patch in the instance's Docker
7
+ * image, run FAIL_TO_PASS + PASS_TO_PASS, report `resolved`. Fully deterministic
8
+ * — no LLM judge.
9
+ *
10
+ * Requires: the bench `.venv` with `swebench` installed + a running Docker
11
+ * daemon (per-instance images are pulled/built on first run).
12
+ *
13
+ * Process/Docker/report plumbing is shared via ./_harness; this file owns the
14
+ * SWE-specific pieces: the patch OutputAdapter, the dataset dump, and the
15
+ * predictions-file → run_evaluation argv → report-shape mapping.
16
+ */
17
+ /**
18
+ * Fixed in-box path the agent clones the instance repo into. It is the SINGLE
19
+ * source of truth shared by the prompt template (which tells the agent to clone
20
+ * here) and `boxExtract` (which runs `git diff` here after the shot) — so the
21
+ * harness always knows exactly where the agent's edits live, for any instance.
22
+ */
23
+ const SWE_REPO_DIR = "/work";
24
+ /**
25
+ * The SWE deliverable's FALLBACK parser, from the agent's event STREAM.
26
+ *
27
+ * The PRIMARY deliverable is `boxExtract` below: a `git diff` of the agent's
28
+ * actual edits, read from the cloned repo's STATE inside the box (standard
29
+ * SWE-bench practice). This event-stream parse only runs when that diff is empty
30
+ * — a model that edited the source correctly but never printed a fenced diff (the
31
+ * exact failure this replaces) still scores off its real changes, not its prose.
32
+ */
33
+ const swePatchOutput = { parse(events) {
34
+ let text = "";
35
+ for (const ev of events) {
36
+ const d = ev?.data;
37
+ const t = d?.finalText ?? d?.text ?? d?.result;
38
+ if (typeof t === "string" && t.length > 0) text = t;
39
+ }
40
+ return ([...text.matchAll(/```(?:diff|patch)?\s*\n([\s\S]*?)```/g)].at(-1)?.[1] ?? text).trim();
41
+ } };
42
+ const DATASET = "princeton-nlp/SWE-bench_Verified";
43
+ const SWE_CACHE_LEVELS = /* @__PURE__ */ new Set([
44
+ "none",
45
+ "base",
46
+ "env",
47
+ "instance"
48
+ ]);
49
+ function scorerNamespace() {
50
+ const namespace = process.env.SWEBENCH_NAMESPACE ?? "swebench";
51
+ if (namespace !== "swebench" && namespace !== "none") throw new Error(`SWEBENCH_NAMESPACE must be swebench|none, got "${namespace}"`);
52
+ return namespace;
53
+ }
54
+ const TEST_FILE_EXCLUDES = [
55
+ "':(exclude,glob)**/tests/**'",
56
+ "':(exclude,glob)**/test/**'",
57
+ "':(exclude,glob)test_*.py'",
58
+ "':(exclude,glob)**/test_*.py'",
59
+ "':(exclude,glob)*_test.py'",
60
+ "':(exclude,glob)**/*_test.py'",
61
+ "':(exclude,glob)conftest.py'",
62
+ "':(exclude,glob)**/conftest.py'"
63
+ ].join(" ");
64
+ function stringIds(report, key) {
65
+ const value = report[key];
66
+ if (value === void 0) return [];
67
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) throw new Error(`swe-bench: malformed ${key}`);
68
+ return value;
69
+ }
70
+ /** Convert one official report into a score without turning evaluator failures into agent failures. */
71
+ function scoreSweReport(taskId, value) {
72
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("swe-bench: report must be an object");
73
+ const report = value;
74
+ const statusIds = {
75
+ resolved: stringIds(report, "resolved_ids"),
76
+ unresolved: stringIds(report, "unresolved_ids"),
77
+ emptyPatch: stringIds(report, "empty_patch_ids"),
78
+ completed: stringIds(report, "completed_ids"),
79
+ incomplete: stringIds(report, "incomplete_ids"),
80
+ error: stringIds(report, "error_ids")
81
+ };
82
+ const submitted = stringIds(report, "submitted_ids");
83
+ if (Object.values(statusIds).flat().some((id) => id !== taskId) || submitted.length > 0 && (submitted.length !== 1 || submitted[0] !== taskId)) throw new Error(`swe-bench: report identity mismatch for ${taskId}`);
84
+ if (statusIds.error.includes(taskId) || statusIds.incomplete.includes(taskId)) throw new Error(`swe-bench: evaluator failed for ${taskId}`);
85
+ const outcomes = [
86
+ statusIds.resolved.includes(taskId),
87
+ statusIds.unresolved.includes(taskId),
88
+ statusIds.emptyPatch.includes(taskId)
89
+ ];
90
+ if (outcomes.filter(Boolean).length !== 1) throw new Error(`swe-bench: report has no unique outcome for ${taskId}`);
91
+ if ((outcomes[0] || outcomes[1]) && !statusIds.completed.includes(taskId)) throw new Error(`swe-bench: report lacks a completed evaluation for ${taskId}`);
92
+ const resolved = outcomes[0];
93
+ return {
94
+ resolved,
95
+ score: resolved ? 1 : 0,
96
+ detail: JSON.stringify(report)
97
+ };
98
+ }
99
+ function sweEvaluationArgv(args) {
100
+ return [
101
+ "-m",
102
+ "swebench.harness.run_evaluation",
103
+ "--dataset_name",
104
+ DATASET,
105
+ "--predictions_path",
106
+ args.predictionsPath,
107
+ "--run_id",
108
+ args.runId,
109
+ "--instance_ids",
110
+ args.instanceId,
111
+ "--max_workers",
112
+ "1",
113
+ "--namespace",
114
+ args.namespace ?? scorerNamespace(),
115
+ "--cache_level",
116
+ args.cacheLevel
117
+ ];
118
+ }
119
+ function shellQuote(value) {
120
+ return `'${value.replace(/'/g, `'\\''`)}'`;
121
+ }
122
+ function sweMetadata(task) {
123
+ const repo = String(task.metadata?.repo ?? "");
124
+ const base = String(task.metadata?.base_commit ?? "");
125
+ if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repo)) throw new Error(`swe-bench: invalid repo metadata for ${task.id}: ${repo}`);
126
+ if (!/^[0-9a-f]{7,40}$/i.test(base)) throw new Error(`swe-bench: invalid base_commit metadata for ${task.id}: ${base}`);
127
+ return {
128
+ repo,
129
+ base
130
+ };
131
+ }
132
+ function createSweBenchAdapter(options = {}) {
133
+ if (options.timeoutMs !== void 0 && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs <= 0)) throw new Error("swe-bench: timeoutMs must be a positive integer");
134
+ const cacheLevel = options.cacheLevel ?? "env";
135
+ if (!SWE_CACHE_LEVELS.has(cacheLevel)) throw new Error("swe-bench: invalid cacheLevel");
136
+ if (options.captureEvaluatorArtifacts !== void 0 && typeof options.captureEvaluatorArtifacts !== "function") throw new Error("swe-bench: captureEvaluatorArtifacts must be a function");
137
+ let attemptSequence = 0;
138
+ return {
139
+ name: "swe-bench-verified",
140
+ output: swePatchOutput,
141
+ boxSetup(task) {
142
+ const { repo, base } = sweMetadata(task);
143
+ return { command: `rm -rf ${shellQuote(SWE_REPO_DIR)} && git clone --quiet ${shellQuote(`https://github.com/${repo}`)} ${shellQuote(SWE_REPO_DIR)} && git -C ${shellQuote(SWE_REPO_DIR)} checkout --quiet ${shellQuote(base)}` };
144
+ },
145
+ boxExtract() {
146
+ return { command: `git -C ${shellQuote(SWE_REPO_DIR)} add -A && git -C ${shellQuote(SWE_REPO_DIR)} diff --cached -- . ${TEST_FILE_EXCLUDES}` };
147
+ },
148
+ async preflight() {
149
+ await preflightVenvImports({
150
+ modules: ["swebench"],
151
+ requireDocker: true,
152
+ fix: "Fix: (1) python3 -m venv bench/.venv && bench/.venv/bin/pip install swebench ; (2) ensure the Docker daemon is running (the judge builds per-instance images)."
153
+ });
154
+ },
155
+ async loadTasks(opts = {}) {
156
+ const limit = opts.limit ?? 10;
157
+ const split = opts.split ?? "test";
158
+ const stdout = await runVenvPython(`
159
+ import json, sys
160
+ from datasets import load_dataset
161
+ ds = load_dataset(${JSON.stringify(DATASET)}, split=${JSON.stringify(split)})
162
+ ids = set(json.loads(sys.argv[1])) if len(sys.argv) > 1 and sys.argv[1] else None
163
+ out = []
164
+ for r in ds:
165
+ if ids is not None and r["instance_id"] not in ids:
166
+ continue
167
+ out.append({
168
+ "instance_id": r["instance_id"], "repo": r["repo"], "base_commit": r["base_commit"],
169
+ "problem_statement": r["problem_statement"], "patch": r["patch"], "test_patch": r["test_patch"],
170
+ "FAIL_TO_PASS": r["FAIL_TO_PASS"], "PASS_TO_PASS": r["PASS_TO_PASS"],
171
+ "version": r.get("version"), "environment_setup_commit": r.get("environment_setup_commit"),
172
+ })
173
+ if ids is None and len(out) >= ${limit}:
174
+ break
175
+ print(json.dumps(out))
176
+ `, [opts.ids ? JSON.stringify(opts.ids) : ""]);
177
+ return JSON.parse(stdout).map((r) => ({
178
+ id: String(r.instance_id),
179
+ split,
180
+ prompt: [
181
+ `Repository: ${r.repo} @ ${r.base_commit}`,
182
+ "",
183
+ `The repository is ALREADY cloned at ${SWE_REPO_DIR}, checked out at commit ${r.base_commit}. Work there directly (\`cd ${SWE_REPO_DIR}\`); do not re-clone.`,
184
+ "",
185
+ "Resolve this issue by editing the repository SOURCE so the failing tests pass without breaking the passing ones. Do NOT edit test files — the evaluation runs hidden tests on a fresh checkout, so editing tests does not count. Keep the change minimal and confined to the cloned repo.",
186
+ "Work iteratively: reproduce the issue, implement the fix in the source, and re-run the relevant tests until they pass. You do NOT need to print the diff — the harness reads your committed edits directly from the repo.",
187
+ "",
188
+ "--- Issue ---",
189
+ String(r.problem_statement ?? "")
190
+ ].join("\n"),
191
+ metadata: r
192
+ }));
193
+ },
194
+ async goldArtifact(task) {
195
+ const gold = task.metadata?.patch;
196
+ return typeof gold === "string" ? gold : void 0;
197
+ },
198
+ async judge(task, artifact) {
199
+ const runId = safeRunId("bench", task.id);
200
+ const capture = options.captureEvaluatorArtifacts?.({
201
+ taskId: task.id,
202
+ runId,
203
+ attemptSequence: ++attemptSequence
204
+ });
205
+ return runStagedJudge({
206
+ tmpPrefix: "swebench-",
207
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
208
+ ...capture === void 0 ? {} : { capture },
209
+ ...process.env.SWEBENCH_KEEP_TMP ? { keepTmp: true } : {},
210
+ async stage(dir) {
211
+ await stageFile(join(dir, "preds.json"), JSON.stringify([{
212
+ instance_id: task.id,
213
+ model_name_or_path: "agent-runtime-bench",
214
+ model_patch: artifact
215
+ }]));
216
+ },
217
+ argv: (dir) => sweEvaluationArgv({
218
+ predictionsPath: join(dir, "preds.json"),
219
+ runId,
220
+ instanceId: task.id,
221
+ cacheLevel,
222
+ namespace: scorerNamespace()
223
+ }),
224
+ async parseReport(dir) {
225
+ const report = await readJsonReport(join(dir, `agent-runtime-bench.${runId}.json`));
226
+ return scoreSweReport(task.id, report);
227
+ }
228
+ });
229
+ }
230
+ };
231
+ }
232
+ //#endregion
233
+ export { createSweBenchAdapter, scoreSweReport, sweEvaluationArgv, swePatchOutput };
234
+
14
235
  //# sourceMappingURL=swe-bench.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"file":"swe-bench.js","names":[],"sources":["../../src/benchmarks/swe-bench.ts"],"sourcesContent":["/**\n * SWE-bench Verified adapter. Worker artifact = a unified-diff patch. Judge =\n * the official `swebench` harness: apply the patch in the instance's Docker\n * image, run FAIL_TO_PASS + PASS_TO_PASS, report `resolved`. Fully deterministic\n * — no LLM judge.\n *\n * Requires: the bench `.venv` with `swebench` installed + a running Docker\n * daemon (per-instance images are pulled/built on first run).\n *\n * Process/Docker/report plumbing is shared via ./_harness; this file owns the\n * SWE-specific pieces: the patch OutputAdapter, the dataset dump, and the\n * predictions-file → run_evaluation argv → report-shape mapping.\n */\n\nimport { join } from 'node:path'\nimport type { OutputAdapter } from '@tangle-network/agent-runtime/loops'\nimport {\n preflightVenvImports,\n readJsonReport,\n runStagedJudge,\n runVenvPython,\n safeRunId,\n stageFile,\n type StagedRunCaptureSpec,\n} from './_harness'\nimport type { BenchmarkAdapter, BenchScore, BenchTask, LoadOptions } from './types'\n\n/**\n * Fixed in-box path the agent clones the instance repo into. It is the SINGLE\n * source of truth shared by the prompt template (which tells the agent to clone\n * here) and `boxExtract` (which runs `git diff` here after the shot) — so the\n * harness always knows exactly where the agent's edits live, for any instance.\n */\nconst SWE_REPO_DIR = '/work'\n\n/**\n * The SWE deliverable's FALLBACK parser, from the agent's event STREAM.\n *\n * The PRIMARY deliverable is `boxExtract` below: a `git diff` of the agent's\n * actual edits, read from the cloned repo's STATE inside the box (standard\n * SWE-bench practice). This event-stream parse only runs when that diff is empty\n * — a model that edited the source correctly but never printed a fenced diff (the\n * exact failure this replaces) still scores off its real changes, not its prose.\n */\nexport const swePatchOutput: 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 // Last ```diff/```patch fenced block (the contract the prompt asks for);\n // fall back to the raw text so a fence-less but valid diff still reaches the judge.\n const fences = [...text.matchAll(/```(?:diff|patch)?\\s*\\n([\\s\\S]*?)```/g)]\n const last = fences.at(-1)?.[1]\n return (last ?? text).trim()\n },\n}\n\nconst DATASET = 'princeton-nlp/SWE-bench_Verified'\nexport type SweBenchCacheLevel = 'none' | 'base' | 'env' | 'instance'\n\nexport interface SweBenchArtifactCaptureContext {\n readonly taskId: string\n readonly runId: string\n /** One-based sequence unique within this adapter instance. */\n readonly attemptSequence: number\n}\n\nexport interface SweBenchAdapterOptions {\n readonly timeoutMs?: number\n readonly cacheLevel?: SweBenchCacheLevel\n /**\n * Return a unique destination for any attempt whose complete official\n * evaluator directory and process logs should be retained.\n */\n readonly captureEvaluatorArtifacts?: (\n context: SweBenchArtifactCaptureContext,\n ) => StagedRunCaptureSpec | undefined\n}\n\nconst SWE_CACHE_LEVELS = new Set<SweBenchCacheLevel>(['none', 'base', 'env', 'instance'])\n\nfunction scorerNamespace(): 'swebench' | 'none' {\n const namespace = process.env.SWEBENCH_NAMESPACE ?? 'swebench'\n if (namespace !== 'swebench' && namespace !== 'none') {\n throw new Error(`SWEBENCH_NAMESPACE must be swebench|none, got \"${namespace}\"`)\n }\n return namespace\n}\nconst TEST_FILE_EXCLUDES = [\n \"':(exclude,glob)**/tests/**'\",\n \"':(exclude,glob)**/test/**'\",\n \"':(exclude,glob)test_*.py'\",\n \"':(exclude,glob)**/test_*.py'\",\n \"':(exclude,glob)*_test.py'\",\n \"':(exclude,glob)**/*_test.py'\",\n \"':(exclude,glob)conftest.py'\",\n \"':(exclude,glob)**/conftest.py'\",\n].join(' ')\n\ninterface SweReport {\n resolved_instances?: number\n resolved_ids?: string[]\n unresolved_ids?: string[]\n empty_patch_ids?: string[]\n completed_ids?: string[]\n incomplete_ids?: string[]\n error_ids?: string[]\n submitted_ids?: string[]\n}\n\nfunction stringIds(report: Record<string, unknown>, key: keyof SweReport): string[] {\n const value = report[key]\n if (value === undefined) return []\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {\n throw new Error(`swe-bench: malformed ${key}`)\n }\n return value\n}\n\n/** Convert one official report into a score without turning evaluator failures into agent failures. */\nexport function scoreSweReport(taskId: string, value: unknown): BenchScore {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('swe-bench: report must be an object')\n }\n const report = value as Record<string, unknown>\n const statusIds = {\n resolved: stringIds(report, 'resolved_ids'),\n unresolved: stringIds(report, 'unresolved_ids'),\n emptyPatch: stringIds(report, 'empty_patch_ids'),\n completed: stringIds(report, 'completed_ids'),\n incomplete: stringIds(report, 'incomplete_ids'),\n error: stringIds(report, 'error_ids'),\n }\n const submitted = stringIds(report, 'submitted_ids')\n const mentioned = Object.values(statusIds).flat()\n if (\n mentioned.some((id) => id !== taskId)\n || (submitted.length > 0 && (submitted.length !== 1 || submitted[0] !== taskId))\n ) {\n throw new Error(`swe-bench: report identity mismatch for ${taskId}`)\n }\n if (statusIds.error.includes(taskId) || statusIds.incomplete.includes(taskId)) {\n throw new Error(`swe-bench: evaluator failed for ${taskId}`)\n }\n const outcomes = [\n statusIds.resolved.includes(taskId),\n statusIds.unresolved.includes(taskId),\n statusIds.emptyPatch.includes(taskId),\n ]\n if (outcomes.filter(Boolean).length !== 1) {\n throw new Error(`swe-bench: report has no unique outcome for ${taskId}`)\n }\n if ((outcomes[0] || outcomes[1]) && !statusIds.completed.includes(taskId)) {\n throw new Error(`swe-bench: report lacks a completed evaluation for ${taskId}`)\n }\n const resolved = outcomes[0]\n return { resolved, score: resolved ? 1 : 0, detail: JSON.stringify(report) }\n}\n\nexport function sweEvaluationArgv(args: {\n readonly predictionsPath: string\n readonly runId: string\n readonly instanceId: string\n readonly cacheLevel: SweBenchCacheLevel\n readonly namespace?: 'swebench' | 'none'\n}): string[] {\n return [\n '-m', 'swebench.harness.run_evaluation',\n '--dataset_name', DATASET,\n '--predictions_path', args.predictionsPath,\n '--run_id', args.runId,\n '--instance_ids', args.instanceId,\n '--max_workers', '1',\n '--namespace', args.namespace ?? scorerNamespace(),\n '--cache_level', args.cacheLevel,\n ]\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`\n}\n\nfunction sweMetadata(task: BenchTask): { repo: string; base: string } {\n const repo = String(task.metadata?.repo ?? '')\n const base = String(task.metadata?.base_commit ?? '')\n if (!/^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/.test(repo)) {\n throw new Error(`swe-bench: invalid repo metadata for ${task.id}: ${repo}`)\n }\n if (!/^[0-9a-f]{7,40}$/i.test(base)) {\n throw new Error(`swe-bench: invalid base_commit metadata for ${task.id}: ${base}`)\n }\n return { repo, base }\n}\n\nexport function createSweBenchAdapter(options: SweBenchAdapterOptions = {}): BenchmarkAdapter {\n if (\n options.timeoutMs !== undefined\n && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs <= 0)\n ) throw new Error('swe-bench: timeoutMs must be a positive integer')\n const cacheLevel = options.cacheLevel ?? 'env'\n if (!SWE_CACHE_LEVELS.has(cacheLevel)) throw new Error('swe-bench: invalid cacheLevel')\n if (\n options.captureEvaluatorArtifacts !== undefined\n && typeof options.captureEvaluatorArtifacts !== 'function'\n ) throw new Error('swe-bench: captureEvaluatorArtifacts must be a function')\n let attemptSequence = 0\n return {\n name: 'swe-bench-verified',\n output: swePatchOutput,\n\n // Extract the patch from repo STATE, not printed text: stage every edit the\n // agent made in the cloned repo and diff it against the checked-out\n // base_commit (`HEAD`). Test files are excluded — the judge applies the gold\n // `test_patch` itself, so an agent edit to a test would collide on apply. The\n // paths come out `a/<repo-relative>` (cwd = repo root), matching the gold\n // patch format the swebench judge's `git apply` expects.\n // Pre-stage: clone the instance repo at base_commit into SWE_REPO_DIR so the\n // agent only edits (the harness owns the checkout — a stochastic model can't be\n // trusted to clone to an exact path). `--quiet` keeps the exec output small.\n boxSetup(task) {\n const { repo, base } = sweMetadata(task)\n return {\n command: `rm -rf ${shellQuote(SWE_REPO_DIR)} && git clone --quiet ${shellQuote(`https://github.com/${repo}`)} ${shellQuote(SWE_REPO_DIR)} && git -C ${shellQuote(SWE_REPO_DIR)} checkout --quiet ${shellQuote(base)}`,\n }\n },\n boxExtract() {\n return {\n command: `git -C ${shellQuote(SWE_REPO_DIR)} add -A && git -C ${shellQuote(SWE_REPO_DIR)} diff --cached -- . ${TEST_FILE_EXCLUDES}`,\n }\n },\n\n async preflight() {\n await preflightVenvImports({\n modules: ['swebench'],\n requireDocker: true,\n fix:\n `Fix: (1) python3 -m venv bench/.venv && bench/.venv/bin/pip install swebench ; ` +\n `(2) ensure the Docker daemon is running (the judge builds per-instance images).`,\n })\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n const limit = opts.limit ?? 10\n const split = opts.split ?? 'test'\n // Dump instances as JSON via the datasets loader (HF download on first run).\n const script = `\nimport json, sys\nfrom datasets import load_dataset\nds = load_dataset(${JSON.stringify(DATASET)}, split=${JSON.stringify(split)})\nids = set(json.loads(sys.argv[1])) if len(sys.argv) > 1 and sys.argv[1] else None\nout = []\nfor r in ds:\n if ids is not None and r[\"instance_id\"] not in ids:\n continue\n out.append({\n \"instance_id\": r[\"instance_id\"], \"repo\": r[\"repo\"], \"base_commit\": r[\"base_commit\"],\n \"problem_statement\": r[\"problem_statement\"], \"patch\": r[\"patch\"], \"test_patch\": r[\"test_patch\"],\n \"FAIL_TO_PASS\": r[\"FAIL_TO_PASS\"], \"PASS_TO_PASS\": r[\"PASS_TO_PASS\"],\n \"version\": r.get(\"version\"), \"environment_setup_commit\": r.get(\"environment_setup_commit\"),\n })\n if ids is None and len(out) >= ${limit}:\n break\nprint(json.dumps(out))\n`\n const stdout = await runVenvPython(script, [opts.ids ? JSON.stringify(opts.ids) : ''])\n const rows = JSON.parse(stdout) as Array<Record<string, unknown>>\n return rows.map(\n (r): BenchTask => ({\n id: String(r.instance_id),\n split,\n prompt: [\n `Repository: ${r.repo} @ ${r.base_commit}`,\n '',\n `The repository is ALREADY cloned at ${SWE_REPO_DIR}, checked out at commit ${r.base_commit}. Work there directly (\\`cd ${SWE_REPO_DIR}\\`); do not re-clone.`,\n '',\n 'Resolve this issue by editing the repository SOURCE so the failing tests pass without breaking the passing ones. Do NOT edit test files — the evaluation runs hidden tests on a fresh checkout, so editing tests does not count. Keep the change minimal and confined to the cloned repo.',\n 'Work iteratively: reproduce the issue, implement the fix in the source, and re-run the relevant tests until they pass. You do NOT need to print the diff — the harness reads your committed edits directly from the repo.',\n '',\n '--- Issue ---',\n String(r.problem_statement ?? ''),\n ].join('\\n'),\n metadata: r,\n }),\n )\n },\n\n async goldArtifact(task: BenchTask) {\n const gold = task.metadata?.patch\n return typeof gold === 'string' ? gold : undefined\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const runId = safeRunId('bench', task.id)\n const capture = options.captureEvaluatorArtifacts?.({\n taskId: task.id,\n runId,\n attemptSequence: ++attemptSequence,\n })\n return runStagedJudge({\n tmpPrefix: 'swebench-',\n ...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),\n ...(capture === undefined ? {} : { capture }),\n // Debug: retain the staged dir (holds swebench's per-instance apply/run\n // logs) for post-mortem when SWEBENCH_KEEP_TMP is set. Off by default.\n ...(process.env.SWEBENCH_KEEP_TMP ? { keepTmp: true } : {}),\n async stage(dir) {\n await stageFile(\n join(dir, 'preds.json'),\n JSON.stringify([\n { instance_id: task.id, model_name_or_path: 'agent-runtime-bench', model_patch: artifact },\n ]),\n )\n },\n // The official evaluation harness. Pulls/builds the instance image, applies\n // the patch, runs the test spec, writes a per-run report JSON in cwd.\n argv: (dir) => sweEvaluationArgv({\n predictionsPath: join(dir, 'preds.json'),\n runId,\n instanceId: task.id,\n cacheLevel,\n namespace: scorerNamespace(),\n }),\n async parseReport(dir) {\n // Report file: agent-runtime-bench.<run_id>.json\n const report = await readJsonReport<SweReport>(join(dir, `agent-runtime-bench.${runId}.json`))\n return scoreSweReport(task.id, report)\n },\n })\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
- * T2-RAGBench adapter.
6
- *
7
- * T2-RAGBench stresses text+table retrieval and numerical reasoning over
8
- * financial documents. The judge uses the shared deterministic answer scorer
9
- * with numeric tolerance enabled by default.
10
- */
11
-
1
+ import { BenchmarkAdapter } from "./types.js";
2
+ //#region src/benchmarks/t2-ragbench.d.ts
12
3
  declare function createT2RagBenchAdapter(): BenchmarkAdapter;
13
-
4
+ //#endregion
14
5
  export { createT2RagBenchAdapter };
6
+ //# sourceMappingURL=t2-ragbench.d.ts.map
@@ -1,9 +1,119 @@
1
- import {
2
- createT2RagBenchAdapter
3
- } from "../chunk-GC2EPS6L.js";
4
- import "../chunk-X3BTXCJ4.js";
5
- import "../chunk-EIETHPD5.js";
6
- export {
7
- createT2RagBenchAdapter
8
- };
1
+ import { benchRoot } from "./_harness.js";
2
+ import { FINAL_ANSWER_SENTINEL, allStrings, answerScoreToBenchScore, contextBlock, contextsFrom, 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/t2-ragbench.ts
6
+ /**
7
+ * T2-RAGBench adapter.
8
+ *
9
+ * T2-RAGBench stresses text+table retrieval and numerical reasoning over
10
+ * financial documents. The judge uses the shared deterministic answer scorer
11
+ * with numeric tolerance enabled by default.
12
+ */
13
+ const FIXTURES = join(benchRoot, "fixtures", "t2-ragbench.json");
14
+ const dataFile = () => process.env.T2_RAGBENCH_DATA_FILE;
15
+ function rowToTask(raw, index) {
16
+ if (!isObject(raw)) throw new Error(`T2-RAGBench row ${index} must be an object`);
17
+ const query = firstString(raw, [
18
+ "question",
19
+ "query",
20
+ "prompt"
21
+ ]);
22
+ const goldAnswers = allStrings(raw, [
23
+ "program_answer",
24
+ "original_answer",
25
+ "answer",
26
+ "answers",
27
+ "reference",
28
+ "reference_answer",
29
+ "gold"
30
+ ]);
31
+ if (!query) throw new Error(`T2-RAGBench row ${index} missing question/query`);
32
+ if (goldAnswers.length === 0) throw new Error(`T2-RAGBench row ${index} missing answer`);
33
+ const baseContexts = contextsFrom(raw.context).length > 0 ? contextsFrom(raw.context) : contextsFrom(raw.contexts).length > 0 ? contextsFrom(raw.contexts) : contextsFrom(raw.chunks).length > 0 ? contextsFrom(raw.chunks) : contextsFrom(raw.passages);
34
+ const table = stringFrom(raw.table) ?? stringFrom(raw.table_text);
35
+ const contexts = table ? [...baseContexts, {
36
+ id: "table",
37
+ title: "Table",
38
+ text: table
39
+ }] : baseContexts;
40
+ const subset = stringFrom(raw.subset) ?? stringFrom(raw.dataset) ?? "unknown";
41
+ const documentId = stringFrom(raw.context_id) ?? stringFrom(raw.document_id) ?? stringFrom(raw.doc_id) ?? stringFrom(raw.file_name) ?? "unknown";
42
+ const id = stringFrom(raw.id) ?? stringFrom(raw.qid) ?? stringFrom(raw.query_id) ?? `t2-ragbench-${index}`;
43
+ const meta = {
44
+ benchmark: "t2-ragbench",
45
+ query,
46
+ goldAnswers,
47
+ contexts,
48
+ subset,
49
+ documentId
50
+ };
51
+ return {
52
+ id,
53
+ split: stringFrom(raw.split) ?? subset,
54
+ prompt: [
55
+ "Answer this T2-RAGBench text-and-table financial question.",
56
+ "Do the required numerical reasoning from the supplied context before giving the final value.",
57
+ "End with a single final line: `FINAL ANSWER: <answer>`.",
58
+ "",
59
+ `Question: ${query}`,
60
+ `Document: ${documentId}`,
61
+ `Subset: ${subset}`,
62
+ contexts.length > 0 ? `\nContext:\n${contextBlock(contexts)}` : void 0
63
+ ].filter(Boolean).join("\n"),
64
+ metadata: meta
65
+ };
66
+ }
67
+ function readMeta(task) {
68
+ const md = task.metadata;
69
+ if (!md || !Array.isArray(md.goldAnswers)) throw new Error(`T2-RAGBench task ${task.id} missing metadata — loadTasks did not populate it`);
70
+ return md;
71
+ }
72
+ async function loadRows(path) {
73
+ const rows = await readJsonRows(path);
74
+ if (rows.length === 0) throw new Error(`T2-RAGBench: no rows in ${path}`);
75
+ return rows;
76
+ }
77
+ async function loadFixtures(opts) {
78
+ const rows = JSON.parse(await readFile(FIXTURES, "utf8"));
79
+ console.warn(`[t2-ragbench] T2_RAGBENCH_FIXTURES=1 — loading ${rows.length} adapter fixtures`);
80
+ return selectTasks(rows.map(rowToTask), opts, "T2-RAGBench");
81
+ }
82
+ function createT2RagBenchAdapter() {
83
+ const fixturesMode = process.env.T2_RAGBENCH_FIXTURES === "1";
84
+ return {
85
+ name: "t2-ragbench",
86
+ output: ragAnswerOutput,
87
+ async preflight() {
88
+ if (fixturesMode) {
89
+ await readFile(FIXTURES, "utf8");
90
+ return;
91
+ }
92
+ const path = dataFile();
93
+ if (!path) throw new Error("T2_RAGBENCH_DATA_FILE is required. Fix: export T2-RAGBench rows to JSONL and set T2_RAGBENCH_DATA_FILE=/path/to/t2-ragbench.jsonl, or set T2_RAGBENCH_FIXTURES=1 for adapter plumbing.");
94
+ await loadRows(path);
95
+ },
96
+ async loadTasks(opts = {}) {
97
+ if (fixturesMode) return loadFixtures(opts);
98
+ const path = dataFile();
99
+ if (!path) throw new Error("T2_RAGBENCH_DATA_FILE is required to load T2-RAGBench tasks");
100
+ return selectTasks((await loadRows(path)).map(rowToTask), opts, "T2-RAGBench");
101
+ },
102
+ async goldArtifact(task) {
103
+ return `${FINAL_ANSWER_SENTINEL} ${readMeta(task).goldAnswers[0] ?? ""}`;
104
+ },
105
+ async judge(task, artifact) {
106
+ const meta = readMeta(task);
107
+ return answerScoreToBenchScore(scoreAnswerArtifact(artifact, meta.goldAnswers, { numericTolerance: .01 }), {
108
+ benchmark: meta.benchmark,
109
+ subset: meta.subset,
110
+ documentId: meta.documentId,
111
+ contextCount: meta.contexts.length
112
+ });
113
+ }
114
+ };
115
+ }
116
+ //#endregion
117
+ export { createT2RagBenchAdapter };
118
+
9
119
  //# sourceMappingURL=t2-ragbench.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"file":"t2-ragbench.js","names":[],"sources":["../../src/benchmarks/t2-ragbench.ts"],"sourcesContent":["/**\n * T2-RAGBench adapter.\n *\n * T2-RAGBench stresses text+table retrieval and numerical reasoning over\n * financial documents. The judge uses the shared deterministic answer scorer\n * with numeric tolerance enabled by default.\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 contextBlock,\n contextsFrom,\n firstString,\n isObject,\n ragAnswerOutput,\n readJsonRows,\n scoreAnswerArtifact,\n selectTasks,\n stringFrom,\n type RagContext,\n} from './rag-shared'\n\nconst FIXTURES = join(benchRoot, 'fixtures', 't2-ragbench.json')\n\ninterface T2RagBenchMeta {\n benchmark: 't2-ragbench'\n query: string\n goldAnswers: string[]\n contexts: RagContext[]\n subset: string\n documentId: string\n}\n\nconst dataFile = (): string | undefined => process.env.T2_RAGBENCH_DATA_FILE\n\nfunction rowToTask(raw: unknown, index: number): BenchTask {\n if (!isObject(raw)) throw new Error(`T2-RAGBench row ${index} must be an object`)\n const query = firstString(raw, ['question', 'query', 'prompt'])\n const goldAnswers = allStrings(raw, [\n 'program_answer',\n 'original_answer',\n 'answer',\n 'answers',\n 'reference',\n 'reference_answer',\n 'gold',\n ])\n if (!query) throw new Error(`T2-RAGBench row ${index} missing question/query`)\n if (goldAnswers.length === 0) throw new Error(`T2-RAGBench row ${index} missing answer`)\n const baseContexts =\n contextsFrom(raw.context).length > 0\n ? contextsFrom(raw.context)\n : contextsFrom(raw.contexts).length > 0\n ? contextsFrom(raw.contexts)\n : contextsFrom(raw.chunks).length > 0\n ? contextsFrom(raw.chunks)\n : contextsFrom(raw.passages)\n const table = stringFrom(raw.table) ?? stringFrom(raw.table_text)\n const contexts = table\n ? [...baseContexts, { id: 'table', title: 'Table', text: table }]\n : baseContexts\n const subset = stringFrom(raw.subset) ?? stringFrom(raw.dataset) ?? 'unknown'\n const documentId =\n stringFrom(raw.context_id) ??\n stringFrom(raw.document_id) ??\n stringFrom(raw.doc_id) ??\n stringFrom(raw.file_name) ??\n 'unknown'\n const id = stringFrom(raw.id) ?? stringFrom(raw.qid) ?? stringFrom(raw.query_id) ?? `t2-ragbench-${index}`\n const meta: T2RagBenchMeta = {\n benchmark: 't2-ragbench',\n query,\n goldAnswers,\n contexts,\n subset,\n documentId,\n }\n return {\n id,\n split: stringFrom(raw.split) ?? subset,\n prompt: [\n 'Answer this T2-RAGBench text-and-table financial question.',\n 'Do the required numerical reasoning from the supplied context before giving the final value.',\n 'End with a single final line: `FINAL ANSWER: <answer>`.',\n '',\n `Question: ${query}`,\n `Document: ${documentId}`,\n `Subset: ${subset}`,\n contexts.length > 0 ? `\\nContext:\\n${contextBlock(contexts)}` : undefined,\n ]\n .filter(Boolean)\n .join('\\n'),\n metadata: meta as unknown as Record<string, unknown>,\n }\n}\n\nfunction readMeta(task: BenchTask): T2RagBenchMeta {\n const md = task.metadata\n if (!md || !Array.isArray(md.goldAnswers)) {\n throw new Error(`T2-RAGBench task ${task.id} missing metadata — loadTasks did not populate it`)\n }\n return md as unknown as T2RagBenchMeta\n}\n\nasync function loadRows(path: string): Promise<unknown[]> {\n const rows = await readJsonRows(path)\n if (rows.length === 0) throw new Error(`T2-RAGBench: 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(`[t2-ragbench] T2_RAGBENCH_FIXTURES=1 — loading ${rows.length} adapter fixtures`)\n return selectTasks(rows.map(rowToTask), opts, 'T2-RAGBench')\n}\n\nexport function createT2RagBenchAdapter(): BenchmarkAdapter {\n const fixturesMode = process.env.T2_RAGBENCH_FIXTURES === '1'\n\n return {\n name: 't2-ragbench',\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 'T2_RAGBENCH_DATA_FILE is required. Fix: export T2-RAGBench rows to JSONL and set T2_RAGBENCH_DATA_FILE=/path/to/t2-ragbench.jsonl, or set T2_RAGBENCH_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('T2_RAGBENCH_DATA_FILE is required to load T2-RAGBench tasks')\n return selectTasks((await loadRows(path)).map(rowToTask), opts, 'T2-RAGBench')\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, { numericTolerance: 0.01 })\n return answerScoreToBenchScore(score, {\n benchmark: meta.benchmark,\n subset: meta.subset,\n documentId: meta.documentId,\n contextCount: meta.contexts.length,\n })\n },\n }\n}\n"],"mappings":"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"}
@@ -1,26 +1,18 @@
1
- import { OutputAdapter } from '@tangle-network/agent-runtime/loops';
2
- import { BenchmarkAdapter } from './types.js';
3
-
4
- /**
5
- * Shared tau-bench adapter spine.
6
- *
7
- * tau2 and tau3 live in the same upstream repository/package namespace today:
8
- * `sierra-research/tau2-bench`, Python package `tau2`. Keep one implementation
9
- * for task loading and reward recomputation so the domain/version adapters only
10
- * choose env names, default domain, and fixture file.
11
- */
12
-
1
+ import { BenchmarkAdapter } from "./types.js";
2
+ import { OutputAdapter } from "@tangle-network/agent-runtime/loops";
3
+ //#region src/benchmarks/tau-bench-shared.d.ts
13
4
  interface TauBenchConfig {
14
- name: string;
15
- fixturePath: string;
16
- fixturesEnv: string;
17
- dirEnv: string;
18
- domainEnv: string;
19
- defaultDomain: string;
20
- installHint: string;
21
- taskIntro: string;
5
+ name: string;
6
+ fixturePath: string;
7
+ fixturesEnv: string;
8
+ dirEnv: string;
9
+ domainEnv: string;
10
+ defaultDomain: string;
11
+ installHint: string;
12
+ taskIntro: string;
22
13
  }
23
14
  declare const tauResultsOutput: OutputAdapter<string>;
24
15
  declare function createTauBenchAdapter(config: TauBenchConfig): BenchmarkAdapter;
25
-
26
- export { type TauBenchConfig, createTauBenchAdapter, tauResultsOutput };
16
+ //#endregion
17
+ export { TauBenchConfig, createTauBenchAdapter, tauResultsOutput };
18
+ //# sourceMappingURL=tau-bench-shared.d.ts.map