@tangle-network/agent-bench 0.3.5 → 0.3.7

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 (262) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +13 -1
  3. package/dist/adapters.d.ts +15 -0
  4. package/dist/adapters.js +43 -0
  5. package/dist/adapters.js.map +1 -0
  6. package/dist/benchmarks/_harness.d.ts +125 -0
  7. package/dist/benchmarks/_harness.js +33 -0
  8. package/dist/benchmarks/_harness.js.map +1 -0
  9. package/dist/benchmarks/aec-bench.d.ts +27 -0
  10. package/dist/benchmarks/aec-bench.js +8 -0
  11. package/dist/benchmarks/aec-bench.js.map +1 -0
  12. package/dist/benchmarks/agentbench.d.ts +16 -0
  13. package/dist/benchmarks/agentbench.js +10 -0
  14. package/dist/benchmarks/agentbench.js.map +1 -0
  15. package/dist/benchmarks/appworld.d.ts +37 -0
  16. package/dist/benchmarks/appworld.js +14 -0
  17. package/dist/benchmarks/appworld.js.map +1 -0
  18. package/dist/benchmarks/bfcl.d.ts +18 -0
  19. package/dist/benchmarks/bfcl.js +10 -0
  20. package/dist/benchmarks/bfcl.js.map +1 -0
  21. package/dist/benchmarks/cad-design.d.ts +45 -0
  22. package/dist/benchmarks/cad-design.js +7 -0
  23. package/dist/benchmarks/cad-design.js.map +1 -0
  24. package/dist/benchmarks/cadbench.d.ts +19 -0
  25. package/dist/benchmarks/cadbench.js +8 -0
  26. package/dist/benchmarks/cadbench.js.map +1 -0
  27. package/dist/benchmarks/cadgenbench.d.ts +22 -0
  28. package/dist/benchmarks/cadgenbench.js +8 -0
  29. package/dist/benchmarks/cadgenbench.js.map +1 -0
  30. package/dist/benchmarks/commit0.d.ts +31 -0
  31. package/dist/benchmarks/commit0.js +10 -0
  32. package/dist/benchmarks/commit0.js.map +1 -0
  33. package/dist/benchmarks/crag.d.ts +14 -0
  34. package/dist/benchmarks/crag.js +9 -0
  35. package/dist/benchmarks/crag.js.map +1 -0
  36. package/dist/benchmarks/dabstep.d.ts +18 -0
  37. package/dist/benchmarks/dabstep.js +10 -0
  38. package/dist/benchmarks/dabstep.js.map +1 -0
  39. package/dist/benchmarks/enterpriseops-gym.d.ts +38 -0
  40. package/dist/benchmarks/enterpriseops-gym.js +10 -0
  41. package/dist/benchmarks/enterpriseops-gym.js.map +1 -0
  42. package/dist/benchmarks/finresearchbench.d.ts +15 -0
  43. package/dist/benchmarks/finresearchbench.js +8 -0
  44. package/dist/benchmarks/finresearchbench.js.map +1 -0
  45. package/dist/benchmarks/finsearchcomp.d.ts +49 -0
  46. package/dist/benchmarks/finsearchcomp.js +7 -0
  47. package/dist/benchmarks/finsearchcomp.js.map +1 -0
  48. package/dist/benchmarks/frames.d.ts +59 -0
  49. package/dist/benchmarks/frames.js +13 -0
  50. package/dist/benchmarks/frames.js.map +1 -0
  51. package/dist/benchmarks/hotpotqa.d.ts +48 -0
  52. package/dist/benchmarks/hotpotqa.js +15 -0
  53. package/dist/benchmarks/hotpotqa.js.map +1 -0
  54. package/dist/benchmarks/humaneval.d.ts +62 -0
  55. package/dist/benchmarks/humaneval.js +17 -0
  56. package/dist/benchmarks/humaneval.js.map +1 -0
  57. package/dist/benchmarks/mind2web.d.ts +41 -0
  58. package/dist/benchmarks/mind2web.js +9 -0
  59. package/dist/benchmarks/mind2web.js.map +1 -0
  60. package/dist/benchmarks/nomiracl.d.ts +15 -0
  61. package/dist/benchmarks/nomiracl.js +9 -0
  62. package/dist/benchmarks/nomiracl.js.map +1 -0
  63. package/dist/benchmarks/open-rag-bench.d.ts +14 -0
  64. package/dist/benchmarks/open-rag-bench.js +9 -0
  65. package/dist/benchmarks/open-rag-bench.js.map +1 -0
  66. package/dist/benchmarks/programbench.d.ts +38 -0
  67. package/dist/benchmarks/programbench.js +10 -0
  68. package/dist/benchmarks/programbench.js.map +1 -0
  69. package/dist/benchmarks/rag-shared.d.ts +42 -0
  70. package/dist/benchmarks/rag-shared.js +39 -0
  71. package/dist/benchmarks/rag-shared.js.map +1 -0
  72. package/dist/benchmarks/ragbench.d.ts +16 -0
  73. package/dist/benchmarks/ragbench.js +9 -0
  74. package/dist/benchmarks/ragbench.js.map +1 -0
  75. package/dist/benchmarks/simpleqa.d.ts +64 -0
  76. package/dist/benchmarks/simpleqa.js +11 -0
  77. package/dist/benchmarks/simpleqa.js.map +1 -0
  78. package/dist/benchmarks/swe-bench.d.ts +56 -0
  79. package/dist/benchmarks/swe-bench.js +14 -0
  80. package/dist/benchmarks/swe-bench.js.map +1 -0
  81. package/dist/benchmarks/t2-ragbench.d.ts +14 -0
  82. package/dist/benchmarks/t2-ragbench.js +9 -0
  83. package/dist/benchmarks/t2-ragbench.js.map +1 -0
  84. package/dist/benchmarks/tau-bench-shared.d.ts +26 -0
  85. package/dist/benchmarks/tau-bench-shared.js +10 -0
  86. package/dist/benchmarks/tau-bench-shared.js.map +1 -0
  87. package/dist/benchmarks/tau2-bench.d.ts +7 -0
  88. package/dist/benchmarks/tau2-bench.js +11 -0
  89. package/dist/benchmarks/tau2-bench.js.map +1 -0
  90. package/dist/benchmarks/tau3-banking.d.ts +15 -0
  91. package/dist/benchmarks/tau3-banking.js +9 -0
  92. package/dist/benchmarks/tau3-banking.js.map +1 -0
  93. package/dist/benchmarks/terminal-bench.d.ts +24 -0
  94. package/dist/benchmarks/terminal-bench.js +8 -0
  95. package/dist/benchmarks/terminal-bench.js.map +1 -0
  96. package/dist/benchmarks/toollm.d.ts +16 -0
  97. package/dist/benchmarks/toollm.js +10 -0
  98. package/dist/benchmarks/toollm.js.map +1 -0
  99. package/dist/benchmarks/trata-hedge.d.ts +32 -0
  100. package/dist/benchmarks/trata-hedge.js +7 -0
  101. package/dist/benchmarks/trata-hedge.js.map +1 -0
  102. package/dist/benchmarks/types.d.ts +107 -0
  103. package/dist/benchmarks/types.js +1 -0
  104. package/dist/benchmarks/types.js.map +1 -0
  105. package/dist/benchmarks/webarena-verified.d.ts +16 -0
  106. package/dist/benchmarks/webarena-verified.js +10 -0
  107. package/dist/benchmarks/webarena-verified.js.map +1 -0
  108. package/dist/chunk-2PVVP7GN.js +197 -0
  109. package/dist/chunk-2PVVP7GN.js.map +1 -0
  110. package/dist/chunk-2XU6OGEN.js +170 -0
  111. package/dist/chunk-2XU6OGEN.js.map +1 -0
  112. package/dist/chunk-53UPUNBZ.js +325 -0
  113. package/dist/chunk-53UPUNBZ.js.map +1 -0
  114. package/dist/chunk-5H5XV76F.js +240 -0
  115. package/dist/chunk-5H5XV76F.js.map +1 -0
  116. package/dist/chunk-7WSD27QQ.js +118 -0
  117. package/dist/chunk-7WSD27QQ.js.map +1 -0
  118. package/dist/chunk-C7T7WEK2.js +103 -0
  119. package/dist/chunk-C7T7WEK2.js.map +1 -0
  120. package/dist/chunk-CKUVRZ2T.js +251 -0
  121. package/dist/chunk-CKUVRZ2T.js.map +1 -0
  122. package/dist/chunk-HBSWHQNJ.js +30 -0
  123. package/dist/chunk-HBSWHQNJ.js.map +1 -0
  124. package/dist/chunk-HHXFIHXC.js +116 -0
  125. package/dist/chunk-HHXFIHXC.js.map +1 -0
  126. package/dist/chunk-IFAV6KEM.js +276 -0
  127. package/dist/chunk-IFAV6KEM.js.map +1 -0
  128. package/dist/chunk-INNOYXCP.js +387 -0
  129. package/dist/chunk-INNOYXCP.js.map +1 -0
  130. package/dist/chunk-J3KDJNX2.js +182 -0
  131. package/dist/chunk-J3KDJNX2.js.map +1 -0
  132. package/dist/chunk-JRWWGMK7.js +148 -0
  133. package/dist/chunk-JRWWGMK7.js.map +1 -0
  134. package/dist/chunk-JTHWEDEW.js +32 -0
  135. package/dist/chunk-JTHWEDEW.js.map +1 -0
  136. package/dist/chunk-KDIKRJGB.js +120 -0
  137. package/dist/chunk-KDIKRJGB.js.map +1 -0
  138. package/dist/chunk-LRRD7NAG.js +301 -0
  139. package/dist/chunk-LRRD7NAG.js.map +1 -0
  140. package/dist/chunk-ODT47UAY.js +221 -0
  141. package/dist/chunk-ODT47UAY.js.map +1 -0
  142. package/dist/chunk-PA2ZKHJC.js +230 -0
  143. package/dist/chunk-PA2ZKHJC.js.map +1 -0
  144. package/dist/chunk-PUIRNYI7.js +189 -0
  145. package/dist/chunk-PUIRNYI7.js.map +1 -0
  146. package/dist/chunk-PWQVGAJB.js +144 -0
  147. package/dist/chunk-PWQVGAJB.js.map +1 -0
  148. package/dist/chunk-R36V2VP7.js +169 -0
  149. package/dist/chunk-R36V2VP7.js.map +1 -0
  150. package/dist/chunk-R67DFVLO.js +142 -0
  151. package/dist/chunk-R67DFVLO.js.map +1 -0
  152. package/dist/chunk-SEVJPLZC.js +260 -0
  153. package/dist/chunk-SEVJPLZC.js.map +1 -0
  154. package/dist/chunk-SYDW647C.js +318 -0
  155. package/dist/chunk-SYDW647C.js.map +1 -0
  156. package/dist/chunk-TBKU5XQI.js +228 -0
  157. package/dist/chunk-TBKU5XQI.js.map +1 -0
  158. package/dist/chunk-TSWPNOYM.js +147 -0
  159. package/dist/chunk-TSWPNOYM.js.map +1 -0
  160. package/dist/chunk-UAIOHCUK.js +27 -0
  161. package/dist/chunk-UAIOHCUK.js.map +1 -0
  162. package/dist/chunk-UPAMRDX4.js +233 -0
  163. package/dist/chunk-UPAMRDX4.js.map +1 -0
  164. package/dist/chunk-VQRS7VUC.js +342 -0
  165. package/dist/chunk-VQRS7VUC.js.map +1 -0
  166. package/dist/chunk-X3BTXCJ4.js +262 -0
  167. package/dist/chunk-X3BTXCJ4.js.map +1 -0
  168. package/dist/chunk-X5YKXC6V.js +211 -0
  169. package/dist/chunk-X5YKXC6V.js.map +1 -0
  170. package/dist/chunk-Y6O2OCUO.js +130 -0
  171. package/dist/chunk-Y6O2OCUO.js.map +1 -0
  172. package/dist/chunk-YCGY7UIZ.js +208 -0
  173. package/dist/chunk-YCGY7UIZ.js.map +1 -0
  174. package/dist/chunk-Z7ML6L77.js +162 -0
  175. package/dist/chunk-Z7ML6L77.js.map +1 -0
  176. package/dist/chunk-ZEWMTR5M.js +136 -0
  177. package/dist/chunk-ZEWMTR5M.js.map +1 -0
  178. package/dist/index.d.ts +355 -0
  179. package/dist/index.js +1908 -0
  180. package/dist/index.js.map +1 -0
  181. package/package.json +26 -9
  182. package/scripts/run-package-tests.mjs +30 -8
  183. package/scripts/verify-packed-consumer.mjs +12 -1
  184. package/scripts/verify-pier-agent.mts +1 -0
  185. package/src/benchmarks/humaneval.test.mts +122 -0
  186. package/src/benchmarks/humaneval.ts +100 -27
  187. package/src/david-attribution.mts +78 -0
  188. package/src/david-goliath.mts +149 -0
  189. package/src/hev-improve.mts +25 -6
  190. package/src/humaneval-object-ablation.mts +201 -0
  191. package/src/live-improve-campaign-mbpp.mts +641 -0
  192. package/src/live-improve-campaign.mts +500 -0
  193. package/src/mbpp-structural.mts +12 -7
  194. package/src/stream-observe.py +45 -0
  195. package/src/stream-observe.tpl.html +247 -0
  196. package/src/supervisor-arena.mts +816 -0
  197. package/src/swe-arena/analyze.ts +211 -0
  198. package/src/swe-arena/arms.ts +788 -0
  199. package/src/swe-arena/bootstrap-meta.mts +188 -0
  200. package/src/swe-arena/bootstrap-meta.test.mts +51 -0
  201. package/src/swe-arena/calibrate.ts +116 -0
  202. package/src/swe-arena/capabilities.mts +76 -0
  203. package/src/swe-arena/capabilities.test.mts +57 -0
  204. package/src/swe-arena/capacity.ts +194 -0
  205. package/src/swe-arena/cell-evidence.mts +405 -0
  206. package/src/swe-arena/cell-evidence.test.mts +248 -0
  207. package/src/swe-arena/diagnosis-ensemble.test.mts +210 -0
  208. package/src/swe-arena/diagnosis-ensemble.ts +520 -0
  209. package/src/swe-arena/execution.test.mts +1170 -0
  210. package/src/swe-arena/fixtures/analyze.py +80 -0
  211. package/src/swe-arena/fixtures/excludes.txt +8 -0
  212. package/src/swe-arena/fixtures/gen1-salvage/README.md +45 -0
  213. package/src/swe-arena/fixtures/gen1-salvage/cand0-e6d7361.diff +116 -0
  214. package/src/swe-arena/fixtures/gen1-salvage/cand1-76a8590.diff +293 -0
  215. package/src/swe-arena/fixtures/holdout-preregister.log +12 -0
  216. package/src/swe-arena/fixtures/holdout.json +44 -0
  217. package/src/swe-arena/fixtures/instances.json +146 -0
  218. package/src/swe-arena/fixtures/ledger.jsonl +12 -0
  219. package/src/swe-arena/fixtures/patches/pallets__flask-5014.solo.patch +36 -0
  220. package/src/swe-arena/fixtures/patches/pydata__xarray-4687.sup.patch +33 -0
  221. package/src/swe-arena/fixtures/rejudge.jsonl +15 -0
  222. package/src/swe-arena/fixtures/rematch.jsonl +3 -0
  223. package/src/swe-arena/fixtures/rematch2.jsonl +3 -0
  224. package/src/swe-arena/fixtures/rematch3.jsonl +3 -0
  225. package/src/swe-arena/fixtures/sup-journal-true.json +19 -0
  226. package/src/swe-arena/fixtures/verify/astropy__astropy-13033.sh +48 -0
  227. package/src/swe-arena/fixtures/verify/django__django-11532.sh +50 -0
  228. package/src/swe-arena/fixtures/verify/matplotlib__matplotlib-20826.sh +76 -0
  229. package/src/swe-arena/fixtures/verify/pydata__xarray-4687.sh +44 -0
  230. package/src/swe-arena/fixtures/verify/pytest-dev__pytest-6197.sh +32 -0
  231. package/src/swe-arena/fixtures/verify/sphinx-doc__sphinx-9658.sh +51 -0
  232. package/src/swe-arena/fixtures/worker-tokens.json +42 -0
  233. package/src/swe-arena/fixtures.ts +104 -0
  234. package/src/swe-arena/holdout-certify.mts +408 -0
  235. package/src/swe-arena/holdout-certify.test.mts +160 -0
  236. package/src/swe-arena/judge-child.mts +37 -0
  237. package/src/swe-arena/manifest.mts +293 -0
  238. package/src/swe-arena/manifest.test.mts +169 -0
  239. package/src/swe-arena/materialize.ts +142 -0
  240. package/src/swe-arena/outer-loop.mts +2145 -0
  241. package/src/swe-arena/outer-loop.test.mts +696 -0
  242. package/src/swe-arena/parity.test.mts +87 -0
  243. package/src/swe-arena/proc.test.mts +174 -0
  244. package/src/swe-arena/proc.ts +260 -0
  245. package/src/swe-arena/profiles/default-author.profile.json +4 -0
  246. package/src/swe-arena/proposer-fanout.mts +489 -0
  247. package/src/swe-arena/proposer-fanout.test.mts +372 -0
  248. package/src/swe-arena/reconcile.ts +0 -0
  249. package/src/swe-arena/replay.mts +183 -0
  250. package/src/swe-arena/replay.test.mts +300 -0
  251. package/src/swe-arena/run-experiment.mts +361 -0
  252. package/src/swe-arena/run-supervisor.mjs +297 -0
  253. package/src/swe-arena/run-supervisor.test.mts +498 -0
  254. package/src/swe-arena/serialized-judge.ts +414 -0
  255. package/src/swe-arena/types.ts +166 -0
  256. package/src/swe-code-improve.mts +328 -0
  257. package/src/swe-emit-patch.mts +104 -0
  258. package/src/swe-improve.mts +232 -0
  259. package/src/swe-jail.ts +2 -2
  260. package/src/swe-local-proof.mts +169 -0
  261. package/src/swe-repro-calibrate.mts +446 -0
  262. package/src/swe-stream.mts +1497 -0
@@ -0,0 +1,148 @@
1
+ import {
2
+ benchRoot,
3
+ preflightVenvImports,
4
+ readJsonReport,
5
+ runStagedJudge,
6
+ runVenvPython,
7
+ safeRunId,
8
+ stageFile,
9
+ venvPythonAt
10
+ } from "./chunk-LRRD7NAG.js";
11
+
12
+ // src/benchmarks/terminal-bench.ts
13
+ import { join } from "path";
14
+ var terminalBenchVenvDir = () => process.env.TERMINAL_BENCH_VENV ?? ".venv-terminal-bench";
15
+ var terminalBenchPython = () => venvPythonAt(terminalBenchVenvDir());
16
+ var terminalBenchBin = () => join(benchRoot, terminalBenchVenvDir(), "bin", "tb");
17
+ var DATASET = "terminal-bench-core";
18
+ var DATASET_VERSION = "0.1.1";
19
+ var DATASET_REF = `${DATASET}==${DATASET_VERSION}`;
20
+ var FIXTURE_IDS = ["hello-world"];
21
+ var SCRIPT_AGENT = "tb_agents.script_agent:ScriptAgent";
22
+ async function loadRows(opts) {
23
+ const ids = opts.ids ?? (opts.limit ? null : FIXTURE_IDS);
24
+ const limit = opts.limit ?? null;
25
+ const script = `
26
+ import json, sys
27
+ from pathlib import Path
28
+ from terminal_bench.dataset.dataset import Dataset
29
+ from terminal_bench.handlers.trial_handler import TaskPaths
30
+
31
+ req_ids = json.loads(sys.argv[1]) if sys.argv[1] else None
32
+ limit = json.loads(sys.argv[2]) if sys.argv[2] else None
33
+
34
+ ds = Dataset(name=${JSON.stringify(DATASET)}, version=${JSON.stringify(DATASET_VERSION)}, task_ids=req_ids, n_tasks=limit)
35
+
36
+ import yaml
37
+ out = []
38
+ for task_dir in ds:
39
+ tp = TaskPaths(task_dir)
40
+ cfg = yaml.safe_load(tp.task_config_path.read_text())
41
+ try:
42
+ sol = tp.solution_path.read_text()
43
+ except FileNotFoundError:
44
+ sol = None
45
+ out.append({
46
+ "id": task_dir.name,
47
+ "instruction": cfg["instruction"],
48
+ "task_dir": str(task_dir),
49
+ "solution": sol if (tp.solution_path.suffix == ".sh" if sol is not None else False) else None,
50
+ })
51
+ print(json.dumps(out))
52
+ `;
53
+ const stdout = await runVenvPython(
54
+ script,
55
+ [ids ? JSON.stringify(ids) : "", limit !== null ? String(limit) : ""],
56
+ 0,
57
+ terminalBenchPython()
58
+ );
59
+ return JSON.parse(stdout);
60
+ }
61
+ function createTerminalBenchAdapter() {
62
+ return {
63
+ name: "terminal-bench",
64
+ async preflight() {
65
+ await preflightVenvImports({
66
+ modules: ["terminal_bench"],
67
+ requireDocker: true,
68
+ python: terminalBenchPython(),
69
+ fix: `Fix: (1) python3 -m venv bench/${terminalBenchVenvDir()} && bench/${terminalBenchVenvDir()}/bin/pip install terminal-bench (an ISOLATED venv \u2014 Terminal-Bench/LiteLLM require Pydantic 2 while AppWorld pins Pydantic 1; override the dir with TERMINAL_BENCH_VENV) ; (2) ensure the Docker daemon is running (the judge builds per-task images on first run). The ${DATASET_REF} dataset is cached from the Terminal-Bench registry on first loadTasks.`
70
+ });
71
+ },
72
+ async loadTasks(opts = {}) {
73
+ const rows = await loadRows(opts);
74
+ if (rows.length === 0) {
75
+ throw new Error(
76
+ `terminal-bench loadTasks returned no tasks for ${JSON.stringify(opts)} (dataset ${DATASET_REF}). Check the requested ids exist in the dataset.`
77
+ );
78
+ }
79
+ return rows.map(
80
+ (r) => ({
81
+ id: r.id,
82
+ split: DATASET_VERSION,
83
+ prompt: r.instruction,
84
+ metadata: {
85
+ dataset: DATASET,
86
+ datasetVersion: DATASET_VERSION,
87
+ datasetRef: DATASET_REF,
88
+ taskDir: r.task_dir,
89
+ solution: r.solution,
90
+ instruction: r.instruction
91
+ }
92
+ })
93
+ );
94
+ },
95
+ async goldArtifact(task) {
96
+ const sol = task.metadata?.solution;
97
+ return typeof sol === "string" ? sol : void 0;
98
+ },
99
+ async judge(task, artifact) {
100
+ const runId = safeRunId("bench", `${task.id}-${Date.now()}`);
101
+ return runStagedJudge({
102
+ tmpPrefix: "tbench-",
103
+ bin: terminalBenchBin(),
104
+ cwd: () => benchRoot,
105
+ async stage(dir) {
106
+ await stageFile(join(dir, "attempt.sh"), artifact);
107
+ },
108
+ // The harness builds a fresh task container, runs ScriptAgent (which replays
109
+ // the artifact script), then runs the task's verifier. --no-livestream keeps
110
+ // stdout sane; --cleanup removes the per-run images.
111
+ argv: (dir) => [
112
+ "run",
113
+ "-d",
114
+ DATASET_REF,
115
+ "-t",
116
+ task.id,
117
+ "--agent-import-path",
118
+ SCRIPT_AGENT,
119
+ "--agent-kwarg",
120
+ `script_path=${join(dir, "attempt.sh")}`,
121
+ "--output-path",
122
+ join(dir, "runs"),
123
+ "--run-id",
124
+ runId,
125
+ "--n-concurrent",
126
+ "1",
127
+ "--no-livestream",
128
+ "--cleanup"
129
+ ],
130
+ async parseReport(dir) {
131
+ const report = await readJsonReport(join(dir, "runs", runId, "results.json"));
132
+ const resolved = (report.resolved_ids ?? []).includes(task.id);
133
+ const trial = report.results?.find((r) => r.task_id === task.id);
134
+ return {
135
+ resolved,
136
+ score: resolved ? 1 : 0,
137
+ detail: JSON.stringify(trial?.parser_results ?? report.resolved_ids ?? {})
138
+ };
139
+ }
140
+ });
141
+ }
142
+ };
143
+ }
144
+
145
+ export {
146
+ createTerminalBenchAdapter
147
+ };
148
+ //# sourceMappingURL=chunk-JRWWGMK7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/benchmarks/terminal-bench.ts"],"sourcesContent":["/**\n * Terminal-Bench adapter. Each task = a Docker environment + an English\n * instruction + a per-task verifier (run-tests.sh + pytest). The worker artifact\n * is the shell script the agent ran to attempt the task; the judge REPLAYS that\n * script in a fresh task container via the Terminal-Bench harness (`tb run` with\n * our ScriptAgent), then the task's own verifier scores the resulting state.\n * Fully deterministic — no LLM judge, no self-authored score.\n *\n * Requires: an isolated bench `.venv-terminal-bench` with `terminal-bench`\n * installed + a running Docker daemon (per-task images are built on first run).\n * Override with TERMINAL_BENCH_VENV. loadTasks caches the dataset from the\n * Terminal-Bench registry on first run.\n *\n * Process/Docker/report plumbing is shared via ./_harness; this file owns the\n * Terminal-Bench-specific pieces: the Dataset enumeration, the ScriptAgent replay\n * argv, and the results.json shape.\n */\n\nimport { join } from 'node:path'\nimport {\n benchRoot,\n preflightVenvImports,\n readJsonReport,\n runStagedJudge,\n runVenvPython,\n safeRunId,\n stageFile,\n venvPythonAt,\n} from './_harness'\nimport type { BenchmarkAdapter, BenchScore, BenchTask, LoadOptions } from './types'\n\n// Terminal-Bench imports LiteLLM/Pydantic-2 APIs, while AppWorld pins Pydantic 1.\n// Keep it out of the shared bench .venv. Resolved at call-time so tests/runs can\n// override the env without reloading this module.\nconst terminalBenchVenvDir = (): string => process.env.TERMINAL_BENCH_VENV ?? '.venv-terminal-bench'\nconst terminalBenchPython = (): string => venvPythonAt(terminalBenchVenvDir())\nconst terminalBenchBin = (): string => join(benchRoot, terminalBenchVenvDir(), 'bin', 'tb')\n\n// Pinned dataset: the 0.1.1 core set is patched for terminal-bench >=0.2.4 (the\n// installed CLI) and is the published launch task set. name==version is what `tb\n// run -d` and `tb datasets download -d` both accept.\nconst DATASET = 'terminal-bench-core'\nconst DATASET_VERSION = '0.1.1'\nconst DATASET_REF = `${DATASET}==${DATASET_VERSION}`\n\n// Bundled fixture: when no ids/limit are given, load these. hello-world is the\n// fastest deterministic task (prebuilt python image, file-write verifier) so the\n// adapter is runnable without a large pull.\nconst FIXTURE_IDS = ['hello-world']\n\n// Import path the harness uses to load our replay agent (cwd = benchRoot).\nconst SCRIPT_AGENT = 'tb_agents.script_agent:ScriptAgent'\n\ninterface TbTaskRow {\n id: string\n instruction: string\n task_dir: string\n solution: string | null\n}\n\ninterface TbReport {\n resolved_ids?: string[]\n results?: Array<{ task_id: string; is_resolved: boolean | null; parser_results?: unknown }>\n}\n\n/** Enumerate dataset tasks via tb's Dataset loader (caches from the registry on\n * first run). Reads instruction from each task.yaml and the gold solution. */\nasync function loadRows(opts: LoadOptions): Promise<TbTaskRow[]> {\n const ids = opts.ids ?? (opts.limit ? null : FIXTURE_IDS)\n const limit = opts.limit ?? null\n const script = `\nimport json, sys\nfrom pathlib import Path\nfrom terminal_bench.dataset.dataset import Dataset\nfrom terminal_bench.handlers.trial_handler import TaskPaths\n\nreq_ids = json.loads(sys.argv[1]) if sys.argv[1] else None\nlimit = json.loads(sys.argv[2]) if sys.argv[2] else None\n\nds = Dataset(name=${JSON.stringify(DATASET)}, version=${JSON.stringify(DATASET_VERSION)}, task_ids=req_ids, n_tasks=limit)\n\nimport yaml\nout = []\nfor task_dir in ds:\n tp = TaskPaths(task_dir)\n cfg = yaml.safe_load(tp.task_config_path.read_text())\n try:\n sol = tp.solution_path.read_text()\n except FileNotFoundError:\n sol = None\n out.append({\n \"id\": task_dir.name,\n \"instruction\": cfg[\"instruction\"],\n \"task_dir\": str(task_dir),\n \"solution\": sol if (tp.solution_path.suffix == \".sh\" if sol is not None else False) else None,\n })\nprint(json.dumps(out))\n`\n const stdout = await runVenvPython(\n script,\n [ids ? JSON.stringify(ids) : '', limit !== null ? String(limit) : ''],\n 0,\n terminalBenchPython(),\n )\n return JSON.parse(stdout) as TbTaskRow[]\n}\n\nexport function createTerminalBenchAdapter(): BenchmarkAdapter {\n return {\n name: 'terminal-bench',\n\n async preflight() {\n await preflightVenvImports({\n modules: ['terminal_bench'],\n requireDocker: true,\n python: terminalBenchPython(),\n fix:\n `Fix: (1) python3 -m venv bench/${terminalBenchVenvDir()} && ` +\n `bench/${terminalBenchVenvDir()}/bin/pip install terminal-bench ` +\n `(an ISOLATED venv — Terminal-Bench/LiteLLM require Pydantic 2 while AppWorld pins Pydantic 1; ` +\n `override the dir with TERMINAL_BENCH_VENV) ; ` +\n `(2) ensure the Docker daemon is running (the judge builds per-task images on first run). ` +\n `The ${DATASET_REF} dataset is cached from the Terminal-Bench registry on first loadTasks.`,\n })\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n const rows = await loadRows(opts)\n if (rows.length === 0) {\n throw new Error(\n `terminal-bench loadTasks returned no tasks for ${JSON.stringify(opts)} ` +\n `(dataset ${DATASET_REF}). Check the requested ids exist in the dataset.`,\n )\n }\n return rows.map(\n (r): BenchTask => ({\n id: r.id,\n split: DATASET_VERSION,\n prompt: r.instruction,\n metadata: {\n dataset: DATASET,\n datasetVersion: DATASET_VERSION,\n datasetRef: DATASET_REF,\n taskDir: r.task_dir,\n solution: r.solution,\n instruction: r.instruction,\n },\n }),\n )\n },\n\n async goldArtifact(task: BenchTask) {\n // Gold = the task's solution.sh (the oracle script). solution.yaml tasks have\n // no shell-script artifact form here, so they return undefined (cannot be\n // verify-judged via the script-replay seam — use a .sh-solution task).\n const sol = task.metadata?.solution\n return typeof sol === 'string' ? sol : undefined\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const runId = safeRunId('bench', `${task.id}-${Date.now()}`)\n return runStagedJudge({\n tmpPrefix: 'tbench-',\n bin: terminalBenchBin(),\n cwd: () => benchRoot,\n async stage(dir) {\n await stageFile(join(dir, 'attempt.sh'), artifact)\n },\n // The harness builds a fresh task container, runs ScriptAgent (which replays\n // the artifact script), then runs the task's verifier. --no-livestream keeps\n // stdout sane; --cleanup removes the per-run images.\n argv: (dir) => [\n 'run',\n '-d', DATASET_REF,\n '-t', task.id,\n '--agent-import-path', SCRIPT_AGENT,\n '--agent-kwarg', `script_path=${join(dir, 'attempt.sh')}`,\n '--output-path', join(dir, 'runs'),\n '--run-id', runId,\n '--n-concurrent', '1',\n '--no-livestream',\n '--cleanup',\n ],\n async parseReport(dir) {\n const report = await readJsonReport<TbReport>(join(dir, 'runs', runId, 'results.json'))\n const resolved = (report.resolved_ids ?? []).includes(task.id)\n const trial = report.results?.find((r) => r.task_id === task.id)\n return {\n resolved,\n score: resolved ? 1 : 0,\n detail: JSON.stringify(trial?.parser_results ?? report.resolved_ids ?? {}),\n }\n },\n })\n },\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,32 @@
1
+ // src/refine-loop.ts
2
+ var defaultDecide = (history) => history[history.length - 1]?.verdict?.valid === true;
3
+ async function runRefineLoop(spec) {
4
+ const rounds = Math.max(1, spec.rounds);
5
+ const decide = spec.decide ?? defaultDecide;
6
+ let ctxSet = false;
7
+ let ctx = void 0;
8
+ try {
9
+ if (spec.setup) {
10
+ ctx = await spec.setup();
11
+ ctxSet = true;
12
+ }
13
+ const history = [];
14
+ for (let r = 1; r <= rounds; r += 1) {
15
+ const prompt = spec.prompt(r, history, ctx);
16
+ const { artifact, note } = await spec.runShot(prompt, r, ctx);
17
+ const verdict = spec.judge ? await spec.judge(artifact, r) : void 0;
18
+ history.push({ round: r, prompt, artifact, verdict, note });
19
+ if (decide(history)) break;
20
+ }
21
+ const blind = history[0];
22
+ const final = history[history.length - 1];
23
+ return { rounds: history, blind, final, resolved: history.some((h) => h.verdict?.valid === true) };
24
+ } finally {
25
+ if (ctxSet && spec.teardown) await spec.teardown(ctx);
26
+ }
27
+ }
28
+
29
+ export {
30
+ runRefineLoop
31
+ };
32
+ //# sourceMappingURL=chunk-JTHWEDEW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/refine-loop.ts"],"sourcesContent":["/**\n * runRefineLoop — the ONE shared k-shot loop (see docs/architecture.md §1, §12).\n *\n * It replaces the seven hand-rolled `for (round 1..k) { shot → judge → decide →\n * carry-forward }` copies across the workers (~700 LOC of duplicated skeleton).\n * The worker is an OPAQUE `runShot`; this loop owns iteration, carry-forward\n * steering, optional per-round judging + early stop, and round bookkeeping.\n *\n * Two carry-forward channels, both first-class (the extraction found both in the\n * wild and they must stay pluggable):\n * - EXECUTION CONTEXT (`Ctx`): created once by `setup`, threaded to every shot,\n * torn down by `teardown`. This is how filesystem/session state carries — a\n * cloned repo whose edits persist (SWE refine), a shared sandbox box whose\n * session persists (sandbox research), or a scratch dir.\n * - PROMPT (`prompt(round, history, ctx)`): how textual state carries — round 1\n * is the blind prompt; rounds 2+ fold prior rounds' artifacts + a directive.\n *\n * Judging is OPTIONAL: workers that run all k rounds and let the orchestrator\n * judge omit `judge`/`decide` (the loop runs to budget); a loop that should stop\n * on the first valid answer wires `judge` (default `decide` = stop-on-valid).\n *\n * This is the inference-timescale instance of the spine's atom: `runShot` is the\n * worker Agent's `act→Output`; `prompt` is the driver Agent's `act→steer`. It is\n * deliberately corpus-agnostic — callers map `RefineLoopResult` to a RunRecord.\n */\n\n/** Minimal per-round verdict — `valid` gates early-stop, `score` is informational. */\nexport interface RoundVerdict {\n valid: boolean\n score?: number\n}\n\nexport interface RoundRecord<Artifact> {\n /** 1-based round index. */\n round: number\n prompt: string\n artifact: Artifact\n /** Present only when a `judge` is wired. */\n verdict?: RoundVerdict\n /** Non-fatal note (e.g. a liveness backstop fired this round). */\n note?: string\n}\n\nexport interface RefineLoopSpec<Artifact, Ctx = void> {\n /** Max shots. Always ≥ 1. */\n rounds: number\n /** Build the per-task execution context once (clone repo / create box / mkdtemp). */\n setup?: () => Promise<Ctx>\n /** Round `r`'s prompt. `r === 1` is the blind prompt; `r > 1` carries `history`. */\n prompt: (round: number, history: ReadonlyArray<RoundRecord<Artifact>>, ctx: Ctx) => string\n /** Run ONE shot — the opaque worker (local spawn / sandbox stream / router chat). */\n runShot: (\n prompt: string,\n round: number,\n ctx: Ctx,\n ) => Promise<{ artifact: Artifact; note?: string }>\n /** Optional per-round judge. Omit to run all `rounds` (orchestrator judges later). */\n judge?: (artifact: Artifact, round: number) => Promise<RoundVerdict>\n /** Stop after this round? Default: stop once a round's verdict is valid (else run to budget). */\n decide?: (history: ReadonlyArray<RoundRecord<Artifact>>) => boolean\n /** Always runs (even on throw) when `setup` ran. */\n teardown?: (ctx: Ctx) => Promise<void>\n}\n\nexport interface RefineLoopResult<Artifact> {\n /** Every executed round in order. */\n rounds: RoundRecord<Artifact>[]\n /** Round 1 — the blind artifact. */\n blind: RoundRecord<Artifact>\n /** The last executed round. */\n final: RoundRecord<Artifact>\n /** True iff any round was judged valid (only meaningful when `judge` is wired). */\n resolved: boolean\n}\n\nconst defaultDecide = <Artifact>(history: ReadonlyArray<RoundRecord<Artifact>>): boolean =>\n history[history.length - 1]?.verdict?.valid === true\n\nexport async function runRefineLoop<Artifact, Ctx = void>(\n spec: RefineLoopSpec<Artifact, Ctx>,\n): Promise<RefineLoopResult<Artifact>> {\n const rounds = Math.max(1, spec.rounds)\n const decide = spec.decide ?? defaultDecide\n let ctxSet = false\n let ctx = undefined as Ctx\n try {\n if (spec.setup) {\n ctx = await spec.setup()\n ctxSet = true\n }\n const history: RoundRecord<Artifact>[] = []\n for (let r = 1; r <= rounds; r += 1) {\n const prompt = spec.prompt(r, history, ctx)\n const { artifact, note } = await spec.runShot(prompt, r, ctx)\n const verdict = spec.judge ? await spec.judge(artifact, r) : undefined\n history.push({ round: r, prompt, artifact, verdict, note })\n if (decide(history)) break\n }\n // The loop runs ≥ 1 round, so history is non-empty.\n const blind = history[0] as RoundRecord<Artifact>\n const final = history[history.length - 1] as RoundRecord<Artifact>\n return { rounds: history, blind, final, resolved: history.some((h) => h.verdict?.valid === true) }\n } finally {\n if (ctxSet && spec.teardown) await spec.teardown(ctx)\n }\n}\n"],"mappings":";AA2EA,IAAM,gBAAgB,CAAW,YAC/B,QAAQ,QAAQ,SAAS,CAAC,GAAG,SAAS,UAAU;AAElD,eAAsB,cACpB,MACqC;AACrC,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM;AACtC,QAAM,SAAS,KAAK,UAAU;AAC9B,MAAI,SAAS;AACb,MAAI,MAAM;AACV,MAAI;AACF,QAAI,KAAK,OAAO;AACd,YAAM,MAAM,KAAK,MAAM;AACvB,eAAS;AAAA,IACX;AACA,UAAM,UAAmC,CAAC;AAC1C,aAAS,IAAI,GAAG,KAAK,QAAQ,KAAK,GAAG;AACnC,YAAM,SAAS,KAAK,OAAO,GAAG,SAAS,GAAG;AAC1C,YAAM,EAAE,UAAU,KAAK,IAAI,MAAM,KAAK,QAAQ,QAAQ,GAAG,GAAG;AAC5D,YAAM,UAAU,KAAK,QAAQ,MAAM,KAAK,MAAM,UAAU,CAAC,IAAI;AAC7D,cAAQ,KAAK,EAAE,OAAO,GAAG,QAAQ,UAAU,SAAS,KAAK,CAAC;AAC1D,UAAI,OAAO,OAAO,EAAG;AAAA,IACvB;AAEA,UAAM,QAAQ,QAAQ,CAAC;AACvB,UAAM,QAAQ,QAAQ,QAAQ,SAAS,CAAC;AACxC,WAAO,EAAE,QAAQ,SAAS,OAAO,OAAO,UAAU,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU,IAAI,EAAE;AAAA,EACnG,UAAE;AACA,QAAI,UAAU,KAAK,SAAU,OAAM,KAAK,SAAS,GAAG;AAAA,EACtD;AACF;","names":[]}
@@ -0,0 +1,120 @@
1
+ import {
2
+ FINAL_ANSWER_SENTINEL,
3
+ allStrings,
4
+ answerScoreToBenchScore,
5
+ contextBlock,
6
+ contextsFrom,
7
+ firstString,
8
+ isObject,
9
+ ragAnswerOutput,
10
+ readJsonRows,
11
+ scoreAnswerArtifact,
12
+ selectTasks,
13
+ stringFrom
14
+ } from "./chunk-X3BTXCJ4.js";
15
+ import {
16
+ benchRoot
17
+ } from "./chunk-LRRD7NAG.js";
18
+
19
+ // src/benchmarks/open-rag-bench.ts
20
+ import { readFile } from "fs/promises";
21
+ import { join } from "path";
22
+ var FIXTURES = join(benchRoot, "fixtures", "open-rag-bench.json");
23
+ var dataFile = () => process.env.OPEN_RAG_BENCH_DATA_FILE;
24
+ function rowToTask(raw, index) {
25
+ if (!isObject(raw)) throw new Error(`Open RAG Bench row ${index} must be an object`);
26
+ const query = firstString(raw, ["question", "query", "prompt"]);
27
+ const goldAnswers = allStrings(raw, ["answer", "answers", "reference", "reference_answer", "gold"]);
28
+ if (!query) throw new Error(`Open RAG Bench row ${index} missing question/query`);
29
+ if (goldAnswers.length === 0) throw new Error(`Open RAG Bench row ${index} missing answer`);
30
+ const contexts = contextsFrom(raw.contexts).length > 0 ? contextsFrom(raw.contexts) : contextsFrom(raw.chunks).length > 0 ? contextsFrom(raw.chunks) : contextsFrom(raw.pages);
31
+ const documentId = stringFrom(raw.document_id) ?? stringFrom(raw.doc_id) ?? stringFrom(raw.pdf_id) ?? stringFrom(raw.file_name) ?? stringFrom(raw.filename) ?? "unknown";
32
+ const modality = stringFrom(raw.modality) ?? stringFrom(raw.answer_modality) ?? "unknown";
33
+ const id = stringFrom(raw.id) ?? stringFrom(raw.query_id) ?? `open-rag-bench-${index}`;
34
+ const meta = {
35
+ benchmark: "open-rag-bench",
36
+ query,
37
+ goldAnswers,
38
+ contexts,
39
+ documentId,
40
+ modality
41
+ };
42
+ return {
43
+ id,
44
+ split: stringFrom(raw.split) ?? modality,
45
+ prompt: [
46
+ "Answer this Open RAG Bench PDF question using the supplied document context.",
47
+ "Use tables, text, and image-derived notes when present.",
48
+ "End with a single final line: `FINAL ANSWER: <answer>`.",
49
+ "",
50
+ `Question: ${query}`,
51
+ `Document: ${documentId}`,
52
+ `Modality: ${modality}`,
53
+ contexts.length > 0 ? `
54
+ Document context:
55
+ ${contextBlock(contexts)}` : void 0
56
+ ].filter(Boolean).join("\n"),
57
+ metadata: meta
58
+ };
59
+ }
60
+ function readMeta(task) {
61
+ const md = task.metadata;
62
+ if (!md || !Array.isArray(md.goldAnswers)) {
63
+ throw new Error(`Open RAG Bench task ${task.id} missing metadata \u2014 loadTasks did not populate it`);
64
+ }
65
+ return md;
66
+ }
67
+ async function loadRows(path) {
68
+ const rows = await readJsonRows(path);
69
+ if (rows.length === 0) throw new Error(`Open RAG Bench: no rows in ${path}`);
70
+ return rows;
71
+ }
72
+ async function loadFixtures(opts) {
73
+ const rows = JSON.parse(await readFile(FIXTURES, "utf8"));
74
+ console.warn(`[open-rag-bench] OPEN_RAG_BENCH_FIXTURES=1 \u2014 loading ${rows.length} adapter fixtures`);
75
+ return selectTasks(rows.map(rowToTask), opts, "Open RAG Bench");
76
+ }
77
+ function createOpenRagBenchAdapter() {
78
+ const fixturesMode = process.env.OPEN_RAG_BENCH_FIXTURES === "1";
79
+ return {
80
+ name: "open-rag-bench",
81
+ output: ragAnswerOutput,
82
+ async preflight() {
83
+ if (fixturesMode) {
84
+ await readFile(FIXTURES, "utf8");
85
+ return;
86
+ }
87
+ const path = dataFile();
88
+ if (!path) {
89
+ throw new Error(
90
+ "OPEN_RAG_BENCH_DATA_FILE is required. Fix: export vectara/open-rag-bench rows to JSONL and set OPEN_RAG_BENCH_DATA_FILE=/path/to/open-rag-bench.jsonl, or set OPEN_RAG_BENCH_FIXTURES=1 for adapter plumbing."
91
+ );
92
+ }
93
+ await loadRows(path);
94
+ },
95
+ async loadTasks(opts = {}) {
96
+ if (fixturesMode) return loadFixtures(opts);
97
+ const path = dataFile();
98
+ if (!path) throw new Error("OPEN_RAG_BENCH_DATA_FILE is required to load Open RAG Bench tasks");
99
+ return selectTasks((await loadRows(path)).map(rowToTask), opts, "Open RAG Bench");
100
+ },
101
+ async goldArtifact(task) {
102
+ return `${FINAL_ANSWER_SENTINEL} ${readMeta(task).goldAnswers[0] ?? ""}`;
103
+ },
104
+ async judge(task, artifact) {
105
+ const meta = readMeta(task);
106
+ const score = scoreAnswerArtifact(artifact, meta.goldAnswers);
107
+ return answerScoreToBenchScore(score, {
108
+ benchmark: meta.benchmark,
109
+ documentId: meta.documentId,
110
+ modality: meta.modality,
111
+ contextCount: meta.contexts.length
112
+ });
113
+ }
114
+ };
115
+ }
116
+
117
+ export {
118
+ createOpenRagBenchAdapter
119
+ };
120
+ //# sourceMappingURL=chunk-KDIKRJGB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/benchmarks/open-rag-bench.ts"],"sourcesContent":["/**\n * Open RAG Bench adapter.\n *\n * This targets Vectara-style Open RAG Bench exports over PDF-derived text,\n * table, and image contexts. The deterministic judge scores final-answer\n * agreement and surfaces modality/document metadata for diagnostics.\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', 'open-rag-bench.json')\n\ninterface OpenRagBenchMeta {\n benchmark: 'open-rag-bench'\n query: string\n goldAnswers: string[]\n contexts: RagContext[]\n documentId: string\n modality: string\n}\n\nconst dataFile = (): string | undefined => process.env.OPEN_RAG_BENCH_DATA_FILE\n\nfunction rowToTask(raw: unknown, index: number): BenchTask {\n if (!isObject(raw)) throw new Error(`Open RAG Bench row ${index} must be an object`)\n const query = firstString(raw, ['question', 'query', 'prompt'])\n const goldAnswers = allStrings(raw, ['answer', 'answers', 'reference', 'reference_answer', 'gold'])\n if (!query) throw new Error(`Open RAG Bench row ${index} missing question/query`)\n if (goldAnswers.length === 0) throw new Error(`Open RAG Bench row ${index} missing answer`)\n const contexts =\n contextsFrom(raw.contexts).length > 0\n ? contextsFrom(raw.contexts)\n : contextsFrom(raw.chunks).length > 0\n ? contextsFrom(raw.chunks)\n : contextsFrom(raw.pages)\n const documentId =\n stringFrom(raw.document_id) ??\n stringFrom(raw.doc_id) ??\n stringFrom(raw.pdf_id) ??\n stringFrom(raw.file_name) ??\n stringFrom(raw.filename) ??\n 'unknown'\n const modality = stringFrom(raw.modality) ?? stringFrom(raw.answer_modality) ?? 'unknown'\n const id = stringFrom(raw.id) ?? stringFrom(raw.query_id) ?? `open-rag-bench-${index}`\n const meta: OpenRagBenchMeta = {\n benchmark: 'open-rag-bench',\n query,\n goldAnswers,\n contexts,\n documentId,\n modality,\n }\n return {\n id,\n split: stringFrom(raw.split) ?? modality,\n prompt: [\n 'Answer this Open RAG Bench PDF question using the supplied document context.',\n 'Use tables, text, and image-derived notes when present.',\n 'End with a single final line: `FINAL ANSWER: <answer>`.',\n '',\n `Question: ${query}`,\n `Document: ${documentId}`,\n `Modality: ${modality}`,\n contexts.length > 0 ? `\\nDocument context:\\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): OpenRagBenchMeta {\n const md = task.metadata\n if (!md || !Array.isArray(md.goldAnswers)) {\n throw new Error(`Open RAG Bench task ${task.id} missing metadata — loadTasks did not populate it`)\n }\n return md as unknown as OpenRagBenchMeta\n}\n\nasync function loadRows(path: string): Promise<unknown[]> {\n const rows = await readJsonRows(path)\n if (rows.length === 0) throw new Error(`Open RAG Bench: 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(`[open-rag-bench] OPEN_RAG_BENCH_FIXTURES=1 — loading ${rows.length} adapter fixtures`)\n return selectTasks(rows.map(rowToTask), opts, 'Open RAG Bench')\n}\n\nexport function createOpenRagBenchAdapter(): BenchmarkAdapter {\n const fixturesMode = process.env.OPEN_RAG_BENCH_FIXTURES === '1'\n\n return {\n name: 'open-rag-bench',\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 'OPEN_RAG_BENCH_DATA_FILE is required. Fix: export vectara/open-rag-bench rows to JSONL and set OPEN_RAG_BENCH_DATA_FILE=/path/to/open-rag-bench.jsonl, or set OPEN_RAG_BENCH_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('OPEN_RAG_BENCH_DATA_FILE is required to load Open RAG Bench tasks')\n return selectTasks((await loadRows(path)).map(rowToTask), opts, 'Open RAG Bench')\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 documentId: meta.documentId,\n modality: meta.modality,\n contextCount: meta.contexts.length,\n })\n },\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,301 @@
1
+ // src/benchmarks/_harness.ts
2
+ import { execFile, spawn } from "child_process";
3
+ import { createHash } from "crypto";
4
+ import {
5
+ cp,
6
+ lstat,
7
+ mkdir,
8
+ mkdtemp,
9
+ readFile,
10
+ readlink,
11
+ readdir,
12
+ rename,
13
+ rm,
14
+ writeFile
15
+ } from "fs/promises";
16
+ import { tmpdir } from "os";
17
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "path";
18
+ import { fileURLToPath } from "url";
19
+ import { promisify } from "util";
20
+ var execFileAsync = promisify(execFile);
21
+ var benchRoot = fileURLToPath(new URL("../..", import.meta.url));
22
+ function resolveBenchPython(env = process.env, root = benchRoot) {
23
+ const configured = env.AGENT_BENCH_PYTHON;
24
+ if (configured === void 0) return join(root, ".venv", "bin", "python");
25
+ if (!isAbsolute(configured)) {
26
+ throw new Error("AGENT_BENCH_PYTHON must be an absolute path");
27
+ }
28
+ return configured;
29
+ }
30
+ var venvPython = resolveBenchPython();
31
+ var venvPythonAt = (venvDir) => join(benchRoot, venvDir, "bin", "python");
32
+ var bigBuffer = 1024 * 1024 * 256;
33
+ function venvBin(name) {
34
+ return join(benchRoot, ".venv", "bin", name);
35
+ }
36
+ async function runVenvPython(script, args = [], timeoutMs = 0, python = venvPython) {
37
+ const { stdout } = await execFileAsync(python, ["-c", script, ...args], {
38
+ maxBuffer: bigBuffer,
39
+ timeout: timeoutMs
40
+ });
41
+ return stdout;
42
+ }
43
+ async function preflightVenvImports(opts) {
44
+ const imports = opts.modules.filter((m) => m.length > 0);
45
+ const lines = [...imports.map((m) => `import ${m}`)];
46
+ if (opts.requireDocker) lines.push("import docker", "docker.from_env().ping()");
47
+ lines.push("print('ok')");
48
+ try {
49
+ await runVenvPython(lines.join("\n"), [], 0, opts.python ?? venvPython);
50
+ } catch (err) {
51
+ const msg = err instanceof Error ? err.message : String(err);
52
+ throw new Error(`${msg}
53
+ ${opts.fix}`);
54
+ }
55
+ }
56
+ function runVenvScriptStdin(scriptPath, args, input, opts = {}) {
57
+ return new Promise((resolve2, reject) => {
58
+ const child = spawn(opts.python ?? venvPython, [scriptPath, ...args], {
59
+ cwd: opts.cwd ?? benchRoot,
60
+ ...opts.timeoutMs ? { timeout: opts.timeoutMs } : {}
61
+ });
62
+ let stdout = "";
63
+ let stderr = "";
64
+ let bytes = 0;
65
+ child.stdout.on("data", (c) => {
66
+ bytes += c.length;
67
+ if (bytes <= bigBuffer) stdout += c.toString("utf8");
68
+ });
69
+ child.stderr.on("data", (c) => {
70
+ stderr += c.toString("utf8");
71
+ });
72
+ child.on("error", (err) => reject(err));
73
+ child.on("close", (code) => {
74
+ if (code === 0) resolve2(stdout);
75
+ else reject(new Error((stderr || stdout || `exit ${code}`).slice(0, 1500)));
76
+ });
77
+ child.stdin.end(input);
78
+ });
79
+ }
80
+ var StagedJudgeError = class extends Error {
81
+ judgeArtifacts;
82
+ constructor(message, judgeArtifacts, options) {
83
+ super(message, options);
84
+ this.name = "StagedJudgeError";
85
+ this.judgeArtifacts = judgeArtifacts;
86
+ }
87
+ };
88
+ function sha256(bytes) {
89
+ return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
90
+ }
91
+ function portablePath(path) {
92
+ return path.split(sep).join("/");
93
+ }
94
+ function compareText(left, right) {
95
+ return left < right ? -1 : left > right ? 1 : 0;
96
+ }
97
+ async function collectArtifactFiles(root, current) {
98
+ const absolute = join(root, current);
99
+ const entries = await readdir(absolute, { withFileTypes: true });
100
+ const files = [];
101
+ for (const entry of entries.sort((left, right) => compareText(left.name, right.name))) {
102
+ const relativePath = join(current, entry.name);
103
+ const path = join(root, relativePath);
104
+ if (entry.isDirectory()) {
105
+ files.push(...await collectArtifactFiles(root, relativePath));
106
+ continue;
107
+ }
108
+ if (entry.isFile()) {
109
+ const bytes = await readFile(path);
110
+ files.push({
111
+ path: portablePath(relativePath),
112
+ byteLength: bytes.byteLength,
113
+ sha256: sha256(bytes),
114
+ kind: "file"
115
+ });
116
+ continue;
117
+ }
118
+ if (entry.isSymbolicLink()) {
119
+ const targetBytes = await readlink(path, { encoding: "buffer" });
120
+ files.push({
121
+ path: portablePath(relativePath),
122
+ byteLength: targetBytes.byteLength,
123
+ sha256: sha256(targetBytes),
124
+ kind: "symlink"
125
+ });
126
+ continue;
127
+ }
128
+ throw new Error(`staged judge capture does not support ${relativePath}`);
129
+ }
130
+ return files;
131
+ }
132
+ function isWithin(parent, candidate) {
133
+ const path = relative(parent, candidate);
134
+ return path === "" || !path.startsWith(`..${sep}`) && path !== ".." && !isAbsolute(path);
135
+ }
136
+ async function assertDestinationAbsent(destination) {
137
+ try {
138
+ await lstat(destination);
139
+ } catch (error) {
140
+ if (error.code === "ENOENT") return;
141
+ throw error;
142
+ }
143
+ throw new Error(`staged judge capture destination already exists: ${destination}`);
144
+ }
145
+ async function captureStagedRun(sourceDirectory, spec, processOutput, evaluatorSucceeded) {
146
+ const source = resolve(sourceDirectory);
147
+ const destination = resolve(spec.destination);
148
+ if (isWithin(source, destination)) {
149
+ throw new Error("staged judge capture destination must be outside the evaluator directory");
150
+ }
151
+ await mkdir(dirname(destination), { recursive: true });
152
+ await assertDestinationAbsent(destination);
153
+ const staging = await mkdtemp(join(dirname(destination), `.${basename(destination)}-capture-`));
154
+ try {
155
+ await cp(source, join(staging, "evaluator"), {
156
+ recursive: true,
157
+ errorOnExist: true,
158
+ force: false,
159
+ preserveTimestamps: true,
160
+ verbatimSymlinks: true
161
+ });
162
+ await mkdir(join(staging, "process"));
163
+ await writeFile(join(staging, "process", "stdout.bin"), processOutput.stdout);
164
+ await writeFile(join(staging, "process", "stderr.bin"), processOutput.stderr);
165
+ const files = [
166
+ ...await collectArtifactFiles(staging, "evaluator"),
167
+ ...await collectArtifactFiles(staging, "process")
168
+ ].sort((left, right) => compareText(left.path, right.path));
169
+ const byteLength = files.reduce((total, file) => total + file.byteLength, 0);
170
+ const treeBytes = Buffer.from(
171
+ files.map((file) => `${file.path}\0${file.kind}\0${file.byteLength}\0${file.sha256}
172
+ `).join(""),
173
+ "utf8"
174
+ );
175
+ const receipt = {
176
+ schema: "agent-bench/judge-artifacts/v1",
177
+ directory: destination,
178
+ evaluatorDirectory: join(destination, "evaluator"),
179
+ manifestPath: join(destination, "receipt.json"),
180
+ evaluatorSucceeded,
181
+ files,
182
+ fileCount: files.length,
183
+ byteLength,
184
+ treeSha256: sha256(treeBytes)
185
+ };
186
+ await writeFile(join(staging, "receipt.json"), `${JSON.stringify(receipt, null, 2)}
187
+ `);
188
+ await rename(staging, destination);
189
+ return receipt;
190
+ } catch (error) {
191
+ await rm(staging, { recursive: true, force: true }).catch(() => {
192
+ });
193
+ throw error;
194
+ }
195
+ }
196
+ function processBytes(value) {
197
+ if (Buffer.isBuffer(value)) return value;
198
+ if (value === void 0 || value === null) return Buffer.alloc(0);
199
+ return Buffer.from(String(value), "utf8");
200
+ }
201
+ async function runStagedJudge(spec) {
202
+ const dir = await mkdtemp(join(tmpdir(), spec.tmpPrefix));
203
+ let stdout = Buffer.alloc(0);
204
+ let stderr = Buffer.alloc(0);
205
+ let evaluatorSucceeded = false;
206
+ let score;
207
+ let failure;
208
+ try {
209
+ try {
210
+ await spec.stage(dir);
211
+ const bin = spec.bin ?? venvPython;
212
+ const argv = spec.argv(dir);
213
+ try {
214
+ const output = await execFileAsync(bin, argv, {
215
+ cwd: spec.cwd ? spec.cwd(dir) : dir,
216
+ encoding: "buffer",
217
+ maxBuffer: bigBuffer,
218
+ ...spec.timeoutMs ? { timeout: spec.timeoutMs } : {}
219
+ });
220
+ stdout = processBytes(output.stdout);
221
+ stderr = processBytes(output.stderr);
222
+ evaluatorSucceeded = true;
223
+ } catch (err) {
224
+ const e = err;
225
+ stdout = processBytes(e.stdout);
226
+ stderr = processBytes(e.stderr);
227
+ const detail = processBytes(e.stderr ?? e.stdout ?? e.message ?? String(err)).toString("utf8").slice(0, 2e3);
228
+ throw new Error(`${spec.tmpPrefix.replace(/-$/, "")} evaluator failed (${bin} ${argv.join(" ")}):
229
+ ${detail}`);
230
+ }
231
+ score = await spec.parseReport(dir);
232
+ } catch (err) {
233
+ failure = err;
234
+ }
235
+ } finally {
236
+ let judgeArtifacts;
237
+ if (spec.capture) {
238
+ try {
239
+ judgeArtifacts = await captureStagedRun(
240
+ dir,
241
+ spec.capture,
242
+ { stdout, stderr },
243
+ evaluatorSucceeded
244
+ );
245
+ } catch (captureError) {
246
+ failure = new Error(
247
+ `staged judge failed to capture evaluator artifacts: ${captureError instanceof Error ? captureError.message : captureError}`,
248
+ { cause: failure ?? captureError }
249
+ );
250
+ }
251
+ }
252
+ if (!spec.keepTmp) await rm(dir, { recursive: true, force: true }).catch(() => {
253
+ });
254
+ if (failure) {
255
+ throw new StagedJudgeError(
256
+ failure instanceof Error ? failure.message : String(failure),
257
+ judgeArtifacts,
258
+ { cause: failure }
259
+ );
260
+ }
261
+ if (!score) throw new StagedJudgeError("staged judge completed without a score", judgeArtifacts);
262
+ return judgeArtifacts ? { ...score, judgeArtifacts } : score;
263
+ }
264
+ }
265
+ async function readJsonReport(path) {
266
+ let raw;
267
+ try {
268
+ raw = await readFile(path, "utf8");
269
+ } catch (err) {
270
+ throw new Error(`expected report not written: ${path} (${err instanceof Error ? err.message : err})`);
271
+ }
272
+ try {
273
+ return JSON.parse(raw);
274
+ } catch (err) {
275
+ throw new Error(`report not valid JSON at ${path}: ${err instanceof Error ? err.message : err}`);
276
+ }
277
+ }
278
+ async function stageFile(path, content) {
279
+ await writeFile(path, content);
280
+ }
281
+ function safeRunId(prefix, id) {
282
+ return `${prefix}-${id}`.replace(/[^a-zA-Z0-9_.-]/g, "_");
283
+ }
284
+
285
+ export {
286
+ benchRoot,
287
+ resolveBenchPython,
288
+ venvPython,
289
+ venvPythonAt,
290
+ bigBuffer,
291
+ venvBin,
292
+ runVenvPython,
293
+ preflightVenvImports,
294
+ runVenvScriptStdin,
295
+ StagedJudgeError,
296
+ runStagedJudge,
297
+ readJsonReport,
298
+ stageFile,
299
+ safeRunId
300
+ };
301
+ //# sourceMappingURL=chunk-LRRD7NAG.js.map