@tangle-network/agent-bench 0.1.0 → 0.3.6

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 (317) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/HARNESS.md +302 -0
  3. package/README.md +39 -2
  4. package/dist/adapters.d.ts +15 -0
  5. package/dist/adapters.js +43 -0
  6. package/dist/adapters.js.map +1 -0
  7. package/dist/benchmarks/_harness.d.ts +125 -0
  8. package/dist/benchmarks/_harness.js +33 -0
  9. package/dist/benchmarks/_harness.js.map +1 -0
  10. package/dist/benchmarks/aec-bench.d.ts +27 -0
  11. package/dist/benchmarks/aec-bench.js +8 -0
  12. package/dist/benchmarks/aec-bench.js.map +1 -0
  13. package/dist/benchmarks/agentbench.d.ts +16 -0
  14. package/dist/benchmarks/agentbench.js +10 -0
  15. package/dist/benchmarks/agentbench.js.map +1 -0
  16. package/dist/benchmarks/appworld.d.ts +37 -0
  17. package/dist/benchmarks/appworld.js +14 -0
  18. package/dist/benchmarks/appworld.js.map +1 -0
  19. package/dist/benchmarks/bfcl.d.ts +18 -0
  20. package/dist/benchmarks/bfcl.js +10 -0
  21. package/dist/benchmarks/bfcl.js.map +1 -0
  22. package/dist/benchmarks/cad-design.d.ts +45 -0
  23. package/dist/benchmarks/cad-design.js +7 -0
  24. package/dist/benchmarks/cad-design.js.map +1 -0
  25. package/dist/benchmarks/cadbench.d.ts +19 -0
  26. package/dist/benchmarks/cadbench.js +8 -0
  27. package/dist/benchmarks/cadbench.js.map +1 -0
  28. package/dist/benchmarks/cadgenbench.d.ts +22 -0
  29. package/dist/benchmarks/cadgenbench.js +8 -0
  30. package/dist/benchmarks/cadgenbench.js.map +1 -0
  31. package/dist/benchmarks/commit0.d.ts +31 -0
  32. package/dist/benchmarks/commit0.js +10 -0
  33. package/dist/benchmarks/commit0.js.map +1 -0
  34. package/dist/benchmarks/crag.d.ts +14 -0
  35. package/dist/benchmarks/crag.js +9 -0
  36. package/dist/benchmarks/crag.js.map +1 -0
  37. package/dist/benchmarks/dabstep.d.ts +18 -0
  38. package/dist/benchmarks/dabstep.js +10 -0
  39. package/dist/benchmarks/dabstep.js.map +1 -0
  40. package/dist/benchmarks/enterpriseops-gym.d.ts +38 -0
  41. package/dist/benchmarks/enterpriseops-gym.js +10 -0
  42. package/dist/benchmarks/enterpriseops-gym.js.map +1 -0
  43. package/dist/benchmarks/finresearchbench.d.ts +15 -0
  44. package/dist/benchmarks/finresearchbench.js +8 -0
  45. package/dist/benchmarks/finresearchbench.js.map +1 -0
  46. package/dist/benchmarks/finsearchcomp.d.ts +49 -0
  47. package/dist/benchmarks/finsearchcomp.js +7 -0
  48. package/dist/benchmarks/finsearchcomp.js.map +1 -0
  49. package/dist/benchmarks/frames.d.ts +59 -0
  50. package/dist/benchmarks/frames.js +13 -0
  51. package/dist/benchmarks/frames.js.map +1 -0
  52. package/dist/benchmarks/hotpotqa.d.ts +48 -0
  53. package/dist/benchmarks/hotpotqa.js +15 -0
  54. package/dist/benchmarks/hotpotqa.js.map +1 -0
  55. package/dist/benchmarks/humaneval.d.ts +53 -0
  56. package/dist/benchmarks/humaneval.js +15 -0
  57. package/dist/benchmarks/humaneval.js.map +1 -0
  58. package/dist/benchmarks/mind2web.d.ts +41 -0
  59. package/dist/benchmarks/mind2web.js +9 -0
  60. package/dist/benchmarks/mind2web.js.map +1 -0
  61. package/dist/benchmarks/nomiracl.d.ts +15 -0
  62. package/dist/benchmarks/nomiracl.js +9 -0
  63. package/dist/benchmarks/nomiracl.js.map +1 -0
  64. package/dist/benchmarks/open-rag-bench.d.ts +14 -0
  65. package/dist/benchmarks/open-rag-bench.js +9 -0
  66. package/dist/benchmarks/open-rag-bench.js.map +1 -0
  67. package/dist/benchmarks/programbench.d.ts +38 -0
  68. package/dist/benchmarks/programbench.js +10 -0
  69. package/dist/benchmarks/programbench.js.map +1 -0
  70. package/dist/benchmarks/rag-shared.d.ts +42 -0
  71. package/dist/benchmarks/rag-shared.js +39 -0
  72. package/dist/benchmarks/rag-shared.js.map +1 -0
  73. package/dist/benchmarks/ragbench.d.ts +16 -0
  74. package/dist/benchmarks/ragbench.js +9 -0
  75. package/dist/benchmarks/ragbench.js.map +1 -0
  76. package/dist/benchmarks/simpleqa.d.ts +64 -0
  77. package/dist/benchmarks/simpleqa.js +11 -0
  78. package/dist/benchmarks/simpleqa.js.map +1 -0
  79. package/dist/benchmarks/swe-bench.d.ts +56 -0
  80. package/dist/benchmarks/swe-bench.js +14 -0
  81. package/dist/benchmarks/swe-bench.js.map +1 -0
  82. package/dist/benchmarks/t2-ragbench.d.ts +14 -0
  83. package/dist/benchmarks/t2-ragbench.js +9 -0
  84. package/dist/benchmarks/t2-ragbench.js.map +1 -0
  85. package/dist/benchmarks/tau-bench-shared.d.ts +26 -0
  86. package/dist/benchmarks/tau-bench-shared.js +10 -0
  87. package/dist/benchmarks/tau-bench-shared.js.map +1 -0
  88. package/dist/benchmarks/tau2-bench.d.ts +7 -0
  89. package/dist/benchmarks/tau2-bench.js +11 -0
  90. package/dist/benchmarks/tau2-bench.js.map +1 -0
  91. package/dist/benchmarks/tau3-banking.d.ts +15 -0
  92. package/dist/benchmarks/tau3-banking.js +9 -0
  93. package/dist/benchmarks/tau3-banking.js.map +1 -0
  94. package/dist/benchmarks/terminal-bench.d.ts +24 -0
  95. package/dist/benchmarks/terminal-bench.js +8 -0
  96. package/dist/benchmarks/terminal-bench.js.map +1 -0
  97. package/dist/benchmarks/toollm.d.ts +16 -0
  98. package/dist/benchmarks/toollm.js +10 -0
  99. package/dist/benchmarks/toollm.js.map +1 -0
  100. package/dist/benchmarks/trata-hedge.d.ts +32 -0
  101. package/dist/benchmarks/trata-hedge.js +7 -0
  102. package/dist/benchmarks/trata-hedge.js.map +1 -0
  103. package/dist/benchmarks/types.d.ts +107 -0
  104. package/dist/benchmarks/types.js +1 -0
  105. package/dist/benchmarks/types.js.map +1 -0
  106. package/dist/benchmarks/webarena-verified.d.ts +16 -0
  107. package/dist/benchmarks/webarena-verified.js +10 -0
  108. package/dist/benchmarks/webarena-verified.js.map +1 -0
  109. package/dist/chunk-2PVVP7GN.js +197 -0
  110. package/dist/chunk-2PVVP7GN.js.map +1 -0
  111. package/dist/chunk-2XU6OGEN.js +170 -0
  112. package/dist/chunk-2XU6OGEN.js.map +1 -0
  113. package/dist/chunk-53UPUNBZ.js +325 -0
  114. package/dist/chunk-53UPUNBZ.js.map +1 -0
  115. package/dist/chunk-5SBJCB6W.js +144 -0
  116. package/dist/chunk-5SBJCB6W.js.map +1 -0
  117. package/dist/chunk-7WSD27QQ.js +118 -0
  118. package/dist/chunk-7WSD27QQ.js.map +1 -0
  119. package/dist/chunk-C7T7WEK2.js +103 -0
  120. package/dist/chunk-C7T7WEK2.js.map +1 -0
  121. package/dist/chunk-CKUVRZ2T.js +251 -0
  122. package/dist/chunk-CKUVRZ2T.js.map +1 -0
  123. package/dist/chunk-HBSWHQNJ.js +30 -0
  124. package/dist/chunk-HBSWHQNJ.js.map +1 -0
  125. package/dist/chunk-HHXFIHXC.js +116 -0
  126. package/dist/chunk-HHXFIHXC.js.map +1 -0
  127. package/dist/chunk-IFAV6KEM.js +276 -0
  128. package/dist/chunk-IFAV6KEM.js.map +1 -0
  129. package/dist/chunk-INNOYXCP.js +387 -0
  130. package/dist/chunk-INNOYXCP.js.map +1 -0
  131. package/dist/chunk-J3KDJNX2.js +182 -0
  132. package/dist/chunk-J3KDJNX2.js.map +1 -0
  133. package/dist/chunk-JRWWGMK7.js +148 -0
  134. package/dist/chunk-JRWWGMK7.js.map +1 -0
  135. package/dist/chunk-JTHWEDEW.js +32 -0
  136. package/dist/chunk-JTHWEDEW.js.map +1 -0
  137. package/dist/chunk-KDIKRJGB.js +120 -0
  138. package/dist/chunk-KDIKRJGB.js.map +1 -0
  139. package/dist/chunk-LRRD7NAG.js +301 -0
  140. package/dist/chunk-LRRD7NAG.js.map +1 -0
  141. package/dist/chunk-ODT47UAY.js +221 -0
  142. package/dist/chunk-ODT47UAY.js.map +1 -0
  143. package/dist/chunk-PA2ZKHJC.js +230 -0
  144. package/dist/chunk-PA2ZKHJC.js.map +1 -0
  145. package/dist/chunk-PPYSEKFM.js +182 -0
  146. package/dist/chunk-PPYSEKFM.js.map +1 -0
  147. package/dist/chunk-PUIRNYI7.js +189 -0
  148. package/dist/chunk-PUIRNYI7.js.map +1 -0
  149. package/dist/chunk-R36V2VP7.js +169 -0
  150. package/dist/chunk-R36V2VP7.js.map +1 -0
  151. package/dist/chunk-R67DFVLO.js +142 -0
  152. package/dist/chunk-R67DFVLO.js.map +1 -0
  153. package/dist/chunk-SEVJPLZC.js +260 -0
  154. package/dist/chunk-SEVJPLZC.js.map +1 -0
  155. package/dist/chunk-SYDW647C.js +318 -0
  156. package/dist/chunk-SYDW647C.js.map +1 -0
  157. package/dist/chunk-TBKU5XQI.js +228 -0
  158. package/dist/chunk-TBKU5XQI.js.map +1 -0
  159. package/dist/chunk-TSWPNOYM.js +147 -0
  160. package/dist/chunk-TSWPNOYM.js.map +1 -0
  161. package/dist/chunk-UAIOHCUK.js +27 -0
  162. package/dist/chunk-UAIOHCUK.js.map +1 -0
  163. package/dist/chunk-UPAMRDX4.js +233 -0
  164. package/dist/chunk-UPAMRDX4.js.map +1 -0
  165. package/dist/chunk-VQRS7VUC.js +342 -0
  166. package/dist/chunk-VQRS7VUC.js.map +1 -0
  167. package/dist/chunk-X3BTXCJ4.js +262 -0
  168. package/dist/chunk-X3BTXCJ4.js.map +1 -0
  169. package/dist/chunk-X5YKXC6V.js +211 -0
  170. package/dist/chunk-X5YKXC6V.js.map +1 -0
  171. package/dist/chunk-Y6O2OCUO.js +130 -0
  172. package/dist/chunk-Y6O2OCUO.js.map +1 -0
  173. package/dist/chunk-YCGY7UIZ.js +208 -0
  174. package/dist/chunk-YCGY7UIZ.js.map +1 -0
  175. package/dist/chunk-Z7ML6L77.js +162 -0
  176. package/dist/chunk-Z7ML6L77.js.map +1 -0
  177. package/dist/chunk-ZEWMTR5M.js +136 -0
  178. package/dist/chunk-ZEWMTR5M.js.map +1 -0
  179. package/dist/index.d.ts +355 -0
  180. package/dist/index.js +1908 -0
  181. package/dist/index.js.map +1 -0
  182. package/fixtures/aec-bench.json +18 -0
  183. package/fixtures/agentbench-dbbench.json +22 -0
  184. package/fixtures/bfcl.json +45 -0
  185. package/fixtures/commit0.json +72 -0
  186. package/fixtures/crag.json +10 -0
  187. package/fixtures/dabstep.json +22 -0
  188. package/fixtures/enterpriseops-gym.json +103 -0
  189. package/fixtures/finresearchbench.json +21 -0
  190. package/fixtures/finsearchcomp.json +66 -0
  191. package/fixtures/frames.json +26 -0
  192. package/fixtures/hotpotqa.json +182 -0
  193. package/fixtures/nomiracl.json +26 -0
  194. package/fixtures/open-rag-bench.json +16 -0
  195. package/fixtures/pier-agent/no-model-task/environment/Dockerfile +16 -0
  196. package/fixtures/pier-agent/no-model-task/environment/seed/src/status.txt +1 -0
  197. package/fixtures/pier-agent/no-model-task/instruction.md +6 -0
  198. package/fixtures/pier-agent/no-model-task/pre_artifacts.sh +6 -0
  199. package/fixtures/pier-agent/no-model-task/task.toml +35 -0
  200. package/fixtures/pier-agent/no-model-task/tests/Dockerfile +17 -0
  201. package/fixtures/pier-agent/no-model-task/tests/seed/src/status.txt +1 -0
  202. package/fixtures/pier-agent/no-model-task/tests/test.sh +19 -0
  203. package/fixtures/programbench.json +17 -0
  204. package/fixtures/ragbench.json +21 -0
  205. package/fixtures/simpleqa.json +121 -0
  206. package/fixtures/t2-ragbench.json +13 -0
  207. package/fixtures/tau2-bench.json +16 -0
  208. package/fixtures/tau3-banking.json +16 -0
  209. package/fixtures/toollm.json +28 -0
  210. package/fixtures/webarena-verified.json +20 -0
  211. package/package.json +60 -20
  212. package/pier_agents/__init__.py +18 -0
  213. package/pier_agents/candidate_contract.py +755 -0
  214. package/pier_agents/process_boundary.py +321 -0
  215. package/pier_agents/tangle_candidate.py +907 -0
  216. package/pier_agents/workspace_boundary.py +368 -0
  217. package/scripts/appworld_driver.py +359 -0
  218. package/scripts/cadbench_prepare.py +22 -0
  219. package/scripts/cadgenbench_hard_parts.py +48 -0
  220. package/scripts/clbench_codebase_judge.py +73 -0
  221. package/scripts/commit0_judge.py +170 -0
  222. package/scripts/dabstep_judge.py +42 -0
  223. package/scripts/enterpriseops_gym_judge.py +281 -0
  224. package/scripts/programbench_judge.py +120 -0
  225. package/scripts/render-gate-chart.mjs +176 -0
  226. package/scripts/run-package-tests.mjs +56 -0
  227. package/scripts/terminate-pier-trial.mts +66 -0
  228. package/scripts/trata-hedge/README.md +56 -0
  229. package/scripts/trata-hedge/run.sh +60 -0
  230. package/scripts/trata-hedge/solve.py +83 -0
  231. package/scripts/verify-packed-consumer.mjs +235 -0
  232. package/scripts/verify-pier-agent.mts +715 -0
  233. package/scripts/verify-pier-pair.mts +74 -0
  234. package/scripts/verify-pier-recovery.mts +139 -0
  235. package/src/adapters.ts +26 -0
  236. package/src/benchmarks/_harness.test.mts +178 -0
  237. package/src/benchmarks/_harness.ts +239 -16
  238. package/src/benchmarks/agentbench.ts +163 -0
  239. package/src/benchmarks/appworld.test.mts +15 -9
  240. package/src/benchmarks/bfcl.ts +346 -0
  241. package/src/benchmarks/crag.ts +137 -0
  242. package/src/benchmarks/dabstep.test.mts +70 -0
  243. package/src/benchmarks/dabstep.ts +212 -0
  244. package/src/benchmarks/external-adapters.test.mts +150 -0
  245. package/src/benchmarks/finresearchbench.ts +269 -0
  246. package/src/benchmarks/humaneval.ts +20 -8
  247. package/src/benchmarks/nomiracl.ts +180 -0
  248. package/src/benchmarks/open-rag-bench.ts +153 -0
  249. package/src/benchmarks/rag-benchmarks.test.mts +138 -0
  250. package/src/benchmarks/rag-shared.ts +327 -0
  251. package/src/benchmarks/ragbench.ts +171 -0
  252. package/src/benchmarks/swe-bench.test.mts +61 -0
  253. package/src/benchmarks/swe-bench.ts +201 -19
  254. package/src/benchmarks/t2-ragbench.ts +166 -0
  255. package/src/benchmarks/tau-bench-shared.ts +214 -0
  256. package/src/benchmarks/tau2-bench.ts +30 -0
  257. package/src/benchmarks/tau3-banking.ts +29 -0
  258. package/src/benchmarks/terminal-bench.test.mts +33 -0
  259. package/src/benchmarks/terminal-bench.ts +23 -8
  260. package/src/benchmarks/toollm.ts +254 -0
  261. package/src/benchmarks/types.ts +42 -0
  262. package/src/benchmarks/webarena-verified.ts +200 -0
  263. package/src/commit0-prereqs.sh +0 -0
  264. package/src/coordination-mcp-container-reach.mts +181 -0
  265. package/src/decoder-live.mts +1 -1
  266. package/src/examples/README.md +103 -39
  267. package/src/examples/benchmark-matrix.mts +101 -0
  268. package/src/examples/lean-proof-gate.README.md +77 -0
  269. package/src/examples/lean-proof-gate.mts +162 -0
  270. package/src/examples/lean-verify.ts +95 -0
  271. package/src/examples/lean.Dockerfile +12 -0
  272. package/src/examples/math-demo.mts +9 -7
  273. package/src/examples/strategy-demo.mts +10 -12
  274. package/src/gate.ts +3 -2
  275. package/src/hev-eval.mts +69 -0
  276. package/src/hev-improve.mts +169 -0
  277. package/src/hev-structural.mts +688 -0
  278. package/src/index.ts +73 -0
  279. package/src/mbpp-structural.mts +662 -0
  280. package/src/pier-agent.test-fixtures.mts +19 -0
  281. package/src/pier-agent.test.mts +363 -0
  282. package/src/pier-agent.ts +657 -0
  283. package/src/pier-result-grader.mjs +30 -0
  284. package/src/pier-result-grader.test.mts +62 -0
  285. package/src/pier-result-grader.ts +108 -0
  286. package/src/pier-task-outcome.test.mts +117 -0
  287. package/src/pier-task-outcome.ts +240 -0
  288. package/src/pier-trial-controller.test.mts +412 -0
  289. package/src/pier-trial-controller.ts +858 -0
  290. package/src/pier-trial-supervisor.mjs +352 -0
  291. package/src/resolve-client.ts +25 -2
  292. package/src/run-benchmarks-cli.mts +72 -0
  293. package/src/run-benchmarks-report.ts +66 -0
  294. package/src/run-benchmarks.test.mts +231 -0
  295. package/src/run-benchmarks.ts +589 -0
  296. package/src/smoke-structural-rollout.mts +393 -0
  297. package/src/swe-bench-env.test.ts +207 -0
  298. package/src/swe-bench-env.ts +554 -0
  299. package/src/swe-jail.ts +293 -0
  300. package/src/swe-self-improve.mts +84 -0
  301. package/src/swe-structural-judge-policy.test.ts +117 -0
  302. package/src/swe-structural-judge-policy.ts +133 -0
  303. package/src/swe-structural-policy.test.ts +124 -0
  304. package/src/swe-structural-policy.ts +132 -0
  305. package/src/swe-structural-provenance.test.ts +93 -0
  306. package/src/swe-structural-provenance.ts +138 -0
  307. package/src/swe-structural.mts +1260 -0
  308. package/src/swe-temp.ts +14 -0
  309. package/src/tb-container-executor.mts +234 -0
  310. package/src/tb-container-executor.test.mts +99 -0
  311. package/src/tb-supervisor-sidecar.mts +222 -0
  312. package/src/trata-gepa.mts +1 -1
  313. package/steerers/eops-itsm-population.json +1 -0
  314. package/tb_agents/opencode_refine_agent.py +117 -0
  315. package/tb_agents/opencode_router_agent.py +406 -0
  316. package/tb_agents/opencode_supervisor_agent.py +239 -0
  317. package/tb_agents/script_agent.py +66 -0
@@ -0,0 +1,170 @@
1
+ import {
2
+ benchRoot,
3
+ preflightVenvImports,
4
+ runVenvScriptStdin,
5
+ venvPythonAt
6
+ } from "./chunk-LRRD7NAG.js";
7
+
8
+ // src/benchmarks/commit0.ts
9
+ import { join } from "path";
10
+ import { readFile } from "fs/promises";
11
+ var FIXTURES = join(benchRoot, "fixtures", "commit0.json");
12
+ var commit0VenvDir = () => process.env.COMMIT0_VENV ?? ".venv-commit0";
13
+ var commit0Python = () => venvPythonAt(commit0VenvDir());
14
+ var DATASET = "wentingzhao/commit0_combined";
15
+ var DATASET_SPLIT = "test";
16
+ var ROWS_API = `https://datasets-server.huggingface.co/rows?dataset=${encodeURIComponent(DATASET)}&config=default&split=${DATASET_SPLIT}`;
17
+ var commit0DiffOutput = {
18
+ parse(events) {
19
+ let text = "";
20
+ for (const ev of events) {
21
+ const d = ev?.data;
22
+ const t = d?.finalText ?? d?.text ?? d?.result;
23
+ if (typeof t === "string" && t.length > 0) text = t;
24
+ }
25
+ const fences = [...text.matchAll(/```(?:diff|patch)?\s*\n([\s\S]*?)```/g)];
26
+ const body = (fences.at(-1)?.[1] ?? text).trim();
27
+ return body.length > 0 ? `${body}
28
+ ` : body;
29
+ }
30
+ };
31
+ function rowToTask(row) {
32
+ const meta = {
33
+ instanceId: row.instance_id,
34
+ repo: row.repo,
35
+ originalRepo: row.original_repo,
36
+ baseCommit: row.base_commit,
37
+ referenceCommit: row.reference_commit,
38
+ srcDir: row.src_dir,
39
+ testDir: row.test.test_dir,
40
+ testCmd: row.test.test_cmd,
41
+ specification: row.setup.specification
42
+ };
43
+ return {
44
+ id: row.instance_id,
45
+ split: DATASET_SPLIT,
46
+ prompt: [
47
+ `Clone https://github.com/${row.repo} into /work, then \`cd /work && git checkout ${row.base_commit}\`.`,
48
+ `This is the STUBBED library: the public functions/classes under \`${row.src_dir}\` have empty bodies (\`pass\`/\`...\`).`,
49
+ `Fill in COMPLETE implementations under \`${row.src_dir}\` so the existing test suite under \`${row.test.test_dir}\` passes. Read those tests and the spec to learn the required behavior.`,
50
+ `Specification / docs: ${row.setup.specification}`,
51
+ "Do NOT edit the test files \u2014 the evaluation re-runs the existing tests on a fresh clone. Implement only the source.",
52
+ `When done, from /work run EXACTLY: \`git add -A && git diff --cached -- ${row.src_dir}\` and END your reply with its COMPLETE output as the LAST thing, fenced exactly as \`\`\`diff \u2026 \`\`\` (nothing after the closing fence). That fenced diff (against ${row.base_commit}) is the only deliverable.`
53
+ ].join("\n"),
54
+ metadata: meta
55
+ };
56
+ }
57
+ function readMeta(task) {
58
+ const md = task.metadata;
59
+ if (!md || typeof md.instanceId !== "string" || typeof md.referenceCommit !== "string" || typeof md.srcDir !== "string") {
60
+ throw new Error(`commit0 task ${task.id} missing metadata \u2014 loadTasks did not populate it`);
61
+ }
62
+ return md;
63
+ }
64
+ function selectRows(rows, opts) {
65
+ let tasks = rows.map(rowToTask);
66
+ if (opts.ids) {
67
+ const want = new Set(opts.ids);
68
+ tasks = tasks.filter((t) => want.has(t.id));
69
+ } else if (opts.limit !== void 0) {
70
+ tasks = tasks.slice(0, opts.limit);
71
+ }
72
+ return tasks;
73
+ }
74
+ async function loadFixtures(opts) {
75
+ const rows = JSON.parse(await readFile(FIXTURES, "utf8"));
76
+ console.warn(
77
+ `[commit0] COMMIT0_FIXTURES=1 \u2014 loading ${rows.length} committed lite rows from ${FIXTURES} (no HF fetch)`
78
+ );
79
+ return selectRows(rows, opts);
80
+ }
81
+ async function fetchRows(opts) {
82
+ const target = opts.ids ? opts.ids.length * 4 : opts.limit ?? 16;
83
+ const rows = [];
84
+ const want = opts.ids ? new Set(opts.ids) : null;
85
+ const page = 100;
86
+ for (let offset = 0; offset < 64 && rows.length < target; offset += page) {
87
+ const res = await fetch(`${ROWS_API}&offset=${offset}&length=${page}`);
88
+ if (!res.ok) throw new Error(`commit0 rows HTTP ${res.status} (offset ${offset}): ${(await res.text()).slice(0, 200)}`);
89
+ const body = await res.json();
90
+ const got = body.rows ?? [];
91
+ if (got.length === 0) break;
92
+ for (const r of got) {
93
+ if (want && !want.has(r.row.instance_id)) continue;
94
+ rows.push(r.row);
95
+ }
96
+ if (got.length < page) break;
97
+ }
98
+ if (rows.length === 0) throw new Error(`commit0: no rows matched ${JSON.stringify(opts)} from ${DATASET}`);
99
+ return rows;
100
+ }
101
+ async function runHarness(meta, artifact) {
102
+ const judge = join(benchRoot, "scripts", "commit0_judge.py");
103
+ let stdout;
104
+ try {
105
+ stdout = await runVenvScriptStdin(
106
+ judge,
107
+ ["--dataset", DATASET, "--split", DATASET_SPLIT, "--instance", meta.instanceId, "--src-dir", meta.srcDir],
108
+ artifact,
109
+ { cwd: benchRoot, python: commit0Python() }
110
+ );
111
+ } catch (err) {
112
+ const e = err;
113
+ throw new Error(`commit0 harness failed for ${meta.instanceId}: ${(e.message || String(err)).slice(0, 1500)}`);
114
+ }
115
+ const report = JSON.parse(stdout.trim().split("\n").at(-1) ?? "{}");
116
+ if (report.error) throw new Error(`commit0 harness error for ${meta.instanceId}: ${report.error}`);
117
+ if (typeof report.passed !== "number" || typeof report.total !== "number") {
118
+ throw new Error(`commit0 judge returned no {passed,total}: ${stdout.slice(0, 400)}`);
119
+ }
120
+ if (report.total <= 0) {
121
+ throw new Error(`commit0 judge measured no tests for ${meta.instanceId} (total=0): ${stdout.slice(0, 400)}`);
122
+ }
123
+ const score = report.passed / report.total;
124
+ return {
125
+ resolved: report.passed === report.total,
126
+ score,
127
+ detail: JSON.stringify({ instanceId: meta.instanceId, passed: report.passed, total: report.total })
128
+ };
129
+ }
130
+ function createCommit0Adapter() {
131
+ const fixturesMode = process.env.COMMIT0_FIXTURES === "1";
132
+ return {
133
+ name: "commit0",
134
+ output: commit0DiffOutput,
135
+ async preflight() {
136
+ await preflightVenvImports({
137
+ modules: ["commit0"],
138
+ requireDocker: true,
139
+ python: commit0Python(),
140
+ fix: `Fix: (1) python3 -m venv bench/${commit0VenvDir()} && bench/${commit0VenvDir()}/bin/pip install commit0 datasets (an ISOLATED venv \u2014 commit0's deps conflict with the shared bench/.venv; override the dir with COMMIT0_VENV) ; (2) ensure the Docker daemon is running (commit0 --backend local builds per-repo images). Dataset rows come from the HF rows server; set COMMIT0_FIXTURES=1 to list the committed lite rows offline.`
141
+ });
142
+ },
143
+ async loadTasks(opts = {}) {
144
+ if (fixturesMode) return loadFixtures(opts);
145
+ let rows;
146
+ try {
147
+ rows = await fetchRows(opts);
148
+ } catch (err) {
149
+ console.warn(
150
+ `[commit0] live rows fetch failed (${err instanceof Error ? err.message : err}); falling back to committed fixtures at ${FIXTURES}`
151
+ );
152
+ return loadFixtures(opts);
153
+ }
154
+ return selectRows(rows, opts);
155
+ },
156
+ async goldArtifact() {
157
+ return void 0;
158
+ },
159
+ async judge(task, artifact) {
160
+ const meta = readMeta(task);
161
+ return runHarness(meta, artifact);
162
+ }
163
+ };
164
+ }
165
+
166
+ export {
167
+ commit0DiffOutput,
168
+ createCommit0Adapter
169
+ };
170
+ //# sourceMappingURL=chunk-2XU6OGEN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/benchmarks/commit0.ts"],"sourcesContent":["/**\n * Commit0 adapter (wentingzhao/commit0_combined) — implement-a-library-from-scratch.\n * Each record is a Python repo stubbed at `base_commit` (public function bodies\n * emptied to `pass`) + the full test suite + a natural-language spec URL. Worker\n * artifact = a unified diff that fills in `src_dir`. Judge = the official\n * `commit0` test harness: it stages the starter repo, applies the worker's diff,\n * builds the library's deps and runs `pytest`, writing a per-repo pytest-json\n * `report.json`. Score = (passed + xfail) / total — GRADED / partial-credit (the\n * macro-averaged unit-test pass-rate the leaderboard reports). Fully\n * deterministic — no LLM judge.\n *\n * The OutputAdapter is stream-only (the SWE wrinkle), so the worker emits its\n * implementation as a fenced ```diff against the stubbed repo — same deliverable\n * shape as swe-bench. The expensive per-repo clone+build+test is delegated to the\n * real `commit0` harness on a local Docker backend (NOT reimplemented here).\n *\n * Requires for a live run: an ISOLATED `.venv-commit0` with `commit0` installed\n * (its deps conflict with the shared bench `.venv`; override with COMMIT0_VENV) +\n * a Docker daemon (`--backend local`). For offline/CI dataset listing set\n * COMMIT0_FIXTURES=1 to load the committed lite rows (bench/fixtures/commit0.json)\n * — judging still needs the harness + Docker and fails loud, never a fabricated score.\n */\n\nimport { join } from 'node:path'\nimport { readFile } from 'node:fs/promises'\nimport type { OutputAdapter } from '@tangle-network/agent-runtime/loops'\nimport { benchRoot, preflightVenvImports, runVenvScriptStdin, venvPythonAt } from './_harness'\nimport type { BenchmarkAdapter, BenchScore, BenchTask, LoadOptions } from './types'\n\nconst FIXTURES = join(benchRoot, 'fixtures', 'commit0.json')\n\n// commit0's pip deps (pydantic/sqlalchemy v1, modal, …) conflict with the shared\n// bench .venv, so its harness runs in an ISOLATED venv. Override with COMMIT0_VENV.\n// Resolved at call-time so the env is honored at run-time (not frozen at import).\nconst commit0VenvDir = (): string => process.env.COMMIT0_VENV ?? '.venv-commit0'\nconst commit0Python = (): string => venvPythonAt(commit0VenvDir())\n\nconst DATASET = 'wentingzhao/commit0_combined'\nconst DATASET_SPLIT = 'test'\n// HF rows server — columnar pull with no `datasets` install required for listing.\nconst ROWS_API = `https://datasets-server.huggingface.co/rows?dataset=${encodeURIComponent(DATASET)}&config=default&split=${DATASET_SPLIT}`\n\n/** Reuse the SWE patch extractor shape: last fenced diff/patch, else raw text. */\nexport const commit0DiffOutput: OutputAdapter<string> = {\n parse(events) {\n let text = ''\n for (const ev of events) {\n const d = (ev as { data?: Record<string, unknown> })?.data\n const t = d?.finalText ?? d?.text ?? d?.result\n if (typeof t === 'string' && t.length > 0) text = t\n }\n const fences = [...text.matchAll(/```(?:diff|patch)?\\s*\\n([\\s\\S]*?)```/g)]\n const body = (fences.at(-1)?.[1] ?? text).trim()\n // `git apply` rejects a patch that is not newline-terminated (\"corrupt patch at\n // line N+1\"); the .trim() above strips the final newline, so restore exactly one.\n return body.length > 0 ? `${body}\\n` : body\n },\n}\n\ninterface Commit0Setup {\n install: string\n packages: string[] | null\n pip_packages: string[] | null\n pre_install: string[] | null\n python: string\n specification: string\n}\n\ninterface Commit0Row {\n instance_id: string\n repo: string\n original_repo: string\n base_commit: string\n reference_commit: string\n setup: Commit0Setup\n test: { test_cmd: string; test_dir: string }\n src_dir: string\n}\n\ninterface Commit0Meta {\n instanceId: string\n repo: string\n originalRepo: string\n baseCommit: string\n referenceCommit: string\n srcDir: string\n testDir: string\n testCmd: string\n specification: string\n}\n\nfunction rowToTask(row: Commit0Row): BenchTask {\n const meta: Commit0Meta = {\n instanceId: row.instance_id,\n repo: row.repo,\n originalRepo: row.original_repo,\n baseCommit: row.base_commit,\n referenceCommit: row.reference_commit,\n srcDir: row.src_dir,\n testDir: row.test.test_dir,\n testCmd: row.test.test_cmd,\n specification: row.setup.specification,\n }\n return {\n id: row.instance_id,\n split: DATASET_SPLIT,\n prompt: [\n `Clone https://github.com/${row.repo} into /work, then \\`cd /work && git checkout ${row.base_commit}\\`.`,\n `This is the STUBBED library: the public functions/classes under \\`${row.src_dir}\\` have empty bodies (\\`pass\\`/\\`...\\`).`,\n `Fill in COMPLETE implementations under \\`${row.src_dir}\\` so the existing test suite under \\`${row.test.test_dir}\\` passes. Read those tests and the spec to learn the required behavior.`,\n `Specification / docs: ${row.setup.specification}`,\n 'Do NOT edit the test files — the evaluation re-runs the existing tests on a fresh clone. Implement only the source.',\n `When done, from /work run EXACTLY: \\`git add -A && git diff --cached -- ${row.src_dir}\\` and END your reply with its COMPLETE output as the LAST thing, fenced exactly as \\`\\`\\`diff … \\`\\`\\` (nothing after the closing fence). That fenced diff (against ${row.base_commit}) is the only deliverable.`,\n ].join('\\n'),\n metadata: meta as unknown as Record<string, unknown>,\n }\n}\n\nfunction readMeta(task: BenchTask): Commit0Meta {\n const md = task.metadata\n if (!md || typeof md.instanceId !== 'string' || typeof md.referenceCommit !== 'string' || typeof md.srcDir !== 'string') {\n throw new Error(`commit0 task ${task.id} missing metadata — loadTasks did not populate it`)\n }\n return md as unknown as Commit0Meta\n}\n\nfunction selectRows(rows: Commit0Row[], opts: LoadOptions): BenchTask[] {\n let tasks = rows.map(rowToTask)\n if (opts.ids) {\n const want = new Set(opts.ids)\n tasks = tasks.filter((t) => want.has(t.id))\n } else if (opts.limit !== undefined) {\n tasks = tasks.slice(0, opts.limit)\n }\n return tasks\n}\n\nasync function loadFixtures(opts: LoadOptions): Promise<BenchTask[]> {\n const rows = JSON.parse(await readFile(FIXTURES, 'utf8')) as Commit0Row[]\n console.warn(\n `[commit0] COMMIT0_FIXTURES=1 — loading ${rows.length} committed lite rows from ${FIXTURES} (no HF fetch)`,\n )\n return selectRows(rows, opts)\n}\n\n/** Pull real rows from the HF rows server (paged). limit caps the pull; ids\n * filtered client-side. Throws on a non-OK response (fail loud). */\nasync function fetchRows(opts: LoadOptions): Promise<Commit0Row[]> {\n const target = opts.ids ? opts.ids.length * 4 : (opts.limit ?? 16)\n const rows: Commit0Row[] = []\n const want = opts.ids ? new Set(opts.ids) : null\n const page = 100\n for (let offset = 0; offset < 64 && rows.length < target; offset += page) {\n const res = await fetch(`${ROWS_API}&offset=${offset}&length=${page}`)\n if (!res.ok) throw new Error(`commit0 rows HTTP ${res.status} (offset ${offset}): ${(await res.text()).slice(0, 200)}`)\n const body = (await res.json()) as { rows?: Array<{ row: Commit0Row }>; num_rows_total?: number }\n const got = body.rows ?? []\n if (got.length === 0) break\n for (const r of got) {\n if (want && !want.has(r.row.instance_id)) continue\n rows.push(r.row)\n }\n if (got.length < page) break\n }\n if (rows.length === 0) throw new Error(`commit0: no rows matched ${JSON.stringify(opts)} from ${DATASET}`)\n return rows\n}\n\n/**\n * Run the official commit0 harness for one repo over the worker's diff. The\n * harness clones base_commit, applies the diff into src_dir, installs deps and\n * runs pytest, then writes a per-repo pytest-json report. We read that report and\n * compute (passed + xfail) / total — the leaderboard's per-repo pass-rate.\n *\n * This is the expensive, Docker-backed boundary; it is DELEGATED to `commit0`,\n * not reimplemented. The driver script lives in scripts/commit0_judge.py so the\n * harness call + report parse are one auditable python entrypoint.\n */\nasync function runHarness(meta: Commit0Meta, artifact: string): Promise<BenchScore> {\n const judge = join(benchRoot, 'scripts', 'commit0_judge.py')\n let stdout: string\n try {\n // The worker's diff is piped to the driver's stdin (shared stdin-aware runner —\n // execFile's `input` option is not honored async and hangs the reader).\n stdout = await runVenvScriptStdin(\n judge,\n ['--dataset', DATASET, '--split', DATASET_SPLIT, '--instance', meta.instanceId, '--src-dir', meta.srcDir],\n artifact,\n { cwd: benchRoot, python: commit0Python() },\n )\n } catch (err) {\n const e = err as { message?: string }\n throw new Error(`commit0 harness failed for ${meta.instanceId}: ${(e.message || String(err)).slice(0, 1500)}`)\n }\n const report = JSON.parse(stdout.trim().split('\\n').at(-1) ?? '{}') as {\n passed?: number\n total?: number\n error?: string\n }\n if (report.error) throw new Error(`commit0 harness error for ${meta.instanceId}: ${report.error}`)\n if (typeof report.passed !== 'number' || typeof report.total !== 'number') {\n throw new Error(`commit0 judge returned no {passed,total}: ${stdout.slice(0, 400)}`)\n }\n // total=0 means the harness MEASURED NOTHING (collection error with no declared\n // test ids) — an unmeasured attempt, not a 0% one. Throw so the caller excludes\n // it as infra instead of recording a fabricated zero.\n if (report.total <= 0) {\n throw new Error(`commit0 judge measured no tests for ${meta.instanceId} (total=0): ${stdout.slice(0, 400)}`)\n }\n const score = report.passed / report.total\n return {\n resolved: report.passed === report.total,\n score,\n detail: JSON.stringify({ instanceId: meta.instanceId, passed: report.passed, total: report.total }),\n }\n}\n\nexport function createCommit0Adapter(): BenchmarkAdapter {\n const fixturesMode = process.env.COMMIT0_FIXTURES === '1'\n\n return {\n name: 'commit0',\n output: commit0DiffOutput,\n\n async preflight() {\n await preflightVenvImports({\n modules: ['commit0'],\n requireDocker: true,\n python: commit0Python(),\n fix:\n `Fix: (1) python3 -m venv bench/${commit0VenvDir()} && bench/${commit0VenvDir()}/bin/pip install commit0 datasets ` +\n `(an ISOLATED venv — commit0's deps conflict with the shared bench/.venv; override the dir with COMMIT0_VENV) ; ` +\n `(2) ensure the Docker daemon is running (commit0 --backend local builds per-repo images). ` +\n `Dataset rows come from the HF rows server; set COMMIT0_FIXTURES=1 to list the committed lite rows offline.`,\n })\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n if (fixturesMode) return loadFixtures(opts)\n let rows: Commit0Row[]\n try {\n rows = await fetchRows(opts)\n } catch (err) {\n console.warn(\n `[commit0] live rows fetch failed (${err instanceof Error ? err.message : err}); falling back to committed fixtures at ${FIXTURES}`,\n )\n return loadFixtures(opts)\n }\n return selectRows(rows, opts)\n },\n\n async goldArtifact() {\n // The oracle is the reference_commit's src_dir, which the commit0 harness\n // checks out by ref — not expressible as a portable diff string without\n // cloning. verify-judge against this adapter requires the live harness, so\n // we return undefined (no offline gold-diff). Judge correctness is proven by\n // running the harness on a real solve, not by a synthetic gold patch.\n return undefined\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const meta = readMeta(task)\n return runHarness(meta, artifact)\n },\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,325 @@
1
+ // src/benchmarks/cad-design.ts
2
+ import { execFile } from "child_process";
3
+ import { mkdtemp, readFile, writeFile } from "fs/promises";
4
+ import { tmpdir } from "os";
5
+ import { join } from "path";
6
+ import { promisify } from "util";
7
+ var execFileAsync = promisify(execFile);
8
+ async function openscad(args, cwd) {
9
+ const { stdout, stderr } = await execFileAsync("xvfb-run", ["-a", "openscad", ...args], {
10
+ cwd,
11
+ maxBuffer: 1024 * 1024 * 64,
12
+ timeout: 12e4
13
+ });
14
+ return { stdout, stderr };
15
+ }
16
+ function measureStl(stl, volumesFromStderr) {
17
+ const verts = [];
18
+ const tris = [];
19
+ const re = /vertex\s+(-?[\d.eE+]+)\s+(-?[\d.eE+]+)\s+(-?[\d.eE+]+)/g;
20
+ let m;
21
+ const flat = [];
22
+ while (m = re.exec(stl)) flat.push([Number(m[1]), Number(m[2]), Number(m[3])]);
23
+ for (let i = 0; i + 2 < flat.length; i += 3) tris.push([flat[i], flat[i + 1], flat[i + 2]]);
24
+ for (const v of flat) verts.push(v);
25
+ const xs = verts.map((v) => v[0]);
26
+ const ys = verts.map((v) => v[1]);
27
+ const zs = verts.map((v) => v[2]);
28
+ const min = (a) => Math.min(...a);
29
+ const max = (a) => Math.max(...a);
30
+ const minZ = min(zs);
31
+ const maxZ = max(zs);
32
+ const h = maxZ - minZ || 1;
33
+ const footprint = (lo, hi) => {
34
+ const band = verts.filter((v) => v[2] >= minZ + lo * h && v[2] <= minZ + hi * h);
35
+ if (band.length < 3) return 0;
36
+ const bx = band.map((v) => v[0]);
37
+ const by = band.map((v) => v[1]);
38
+ return (max(bx) - min(bx)) * (max(by) - min(by));
39
+ };
40
+ let vol6 = 0;
41
+ for (const [a, b, c] of tris) {
42
+ vol6 += a[0] * (b[1] * c[2] - b[2] * c[1]) - a[1] * (b[0] * c[2] - b[2] * c[0]) + a[2] * (b[0] * c[1] - b[1] * c[0]);
43
+ }
44
+ const bbox = { x: max(xs) - min(xs), y: max(ys) - min(ys), z: maxZ - minZ };
45
+ return {
46
+ triangles: tris.length,
47
+ volumes: volumesFromStderr,
48
+ bbox,
49
+ baseFootprint: footprint(0, 0.6),
50
+ topFootprint: footprint(0.75, 1),
51
+ solidVolume: Math.abs(vol6) / 6,
52
+ bboxVolume: bbox.x * bbox.y * bbox.z || 1
53
+ };
54
+ }
55
+ function inRange(v, [lo, hi]) {
56
+ return v >= lo && v <= hi;
57
+ }
58
+ function scoreGeometry(g, spec) {
59
+ const checks = {};
60
+ if (spec.volumes) checks.volumes = inRange(g.volumes, spec.volumes);
61
+ if (spec.minTriangles != null) checks.detail = g.triangles >= spec.minTriangles;
62
+ if (spec.bbox?.x) checks.bboxX = inRange(g.bbox.x, spec.bbox.x);
63
+ if (spec.bbox?.y) checks.bboxY = inRange(g.bbox.y, spec.bbox.y);
64
+ if (spec.bbox?.z) checks.bboxZ = inRange(g.bbox.z, spec.bbox.z);
65
+ if (spec.pitchedRoof != null)
66
+ checks.pitchedRoof = g.baseFootprint > 0 && g.topFootprint < spec.pitchedRoof * g.baseFootprint;
67
+ if (spec.hollowBelow != null) checks.hollow = g.solidVolume < spec.hollowBelow * g.bboxVolume;
68
+ const vals = Object.values(checks);
69
+ const score = vals.length ? vals.filter(Boolean).length / vals.length : 0;
70
+ return { checks, score };
71
+ }
72
+ function buildingGold(w, d, sh, ns, rh, t = 3) {
73
+ return `
74
+ w=${w}; d=${d}; sh=${sh}; ns=${ns}; rh=${rh}; t=${t};
75
+ module shell(w,d,h,t){ difference(){ cube([w,d,h]); translate([t,t,-1]) cube([w-2*t,d-2*t,h+2]); } }
76
+ module roof(w,d,h){ rotate([90,0,90]) linear_extrude(height=w) polygon([[0,0],[d,0],[d/2,h]]); }
77
+ union(){
78
+ for(s=[0:ns-1]) translate([0,0,s*sh]) shell(w,d,sh,t);
79
+ for(s=[0:ns]) translate([0,0,s*sh-0.5]) cube([w,d,1]);
80
+ translate([0,0,ns*sh]) roof(w,d,rh);
81
+ for(s=[0:ns-1]) for(i=[0:floor((w-28)/22)]) translate([14+i*22,-1,s*sh+10]) cube([10,t+2,12]);
82
+ translate([w/2-7,-1,2]) cube([14,t+2,20]);
83
+ }
84
+ `.trim();
85
+ }
86
+ function buildingTask(o) {
87
+ const { id, desc, w, d, sh, ns, rh } = o;
88
+ const totalWall = ns * sh;
89
+ const totalH = totalWall + rh;
90
+ const r = Math.round;
91
+ const spec = {
92
+ volumes: [1, ns * 4 + 6],
93
+ bbox: {
94
+ x: [r(w * 0.82), r(w * 1.18)],
95
+ y: [r(d * 0.82), r((d + 1) * 1.2)],
96
+ z: [r(totalH * 0.82), r((totalH + 1) * 1.2)]
97
+ },
98
+ minTriangles: 50,
99
+ pitchedRoof: 0.55,
100
+ hollowBelow: 0.72
101
+ };
102
+ const prompt = [
103
+ `Write OpenSCAD source for ${desc}.`,
104
+ "Requirements:",
105
+ `- footprint roughly ${w} (X) by ${d} (Y) units`,
106
+ ns > 1 ? `- ${ns} stories, total wall height ~${totalWall} units` : `- one story, wall height ~${sh} units`,
107
+ "- a PITCHED / gabled roof on top that tapers toward a ridge (NOT flat)",
108
+ "- hollow shell (walls with an interior cavity), not a solid block",
109
+ "- a door opening and several windows",
110
+ "Output ONLY the .scad source, no prose, no code fences."
111
+ ].join("\n");
112
+ return { id, prompt, meta: { spec, gold: buildingGold(w, d, sh, ns, rh) } };
113
+ }
114
+ var BUILDING_CONFIGS = [
115
+ { id: "cottage", desc: "a single-story cottage", w: 50, d: 40, sh: 30, ns: 1, rh: 18 },
116
+ { id: "cabin", desc: "a small one-room cabin", w: 44, d: 36, sh: 26, ns: 1, rh: 22 },
117
+ { id: "bungalow", desc: "a wide single-story bungalow", w: 70, d: 52, sh: 28, ns: 1, rh: 20 },
118
+ { id: "barn", desc: "a long deep barn", w: 60, d: 96, sh: 42, ns: 1, rh: 26 },
119
+ { id: "warehouse", desc: "a large warehouse", w: 110, d: 80, sh: 40, ns: 1, rh: 26 },
120
+ { id: "chapel", desc: "a narrow tall chapel with a steep roof", w: 40, d: 72, sh: 48, ns: 1, rh: 34 },
121
+ { id: "farmhouse", desc: "a two-story farmhouse", w: 72, d: 56, sh: 30, ns: 2, rh: 26 },
122
+ { id: "two-story-manor", desc: "a wide two-story manor", w: 96, d: 64, sh: 32, ns: 2, rh: 28 },
123
+ { id: "townhouse", desc: "a narrow three-story townhouse", w: 42, d: 52, sh: 30, ns: 3, rh: 34 },
124
+ { id: "watchtower", desc: "a tall narrow three-story watchtower", w: 34, d: 34, sh: 30, ns: 3, rh: 32 }
125
+ ];
126
+ var WATER_TOWER_GOLD = `
127
+ $fn=48; r=24; bh=72; t=3; ch=26;
128
+ union(){
129
+ difference(){ cylinder(h=bh, r=r); translate([0,0,t]) cylinder(h=bh, r=r-t); }
130
+ translate([0,0,bh]) cylinder(h=ch, r1=r, r2=0);
131
+ }
132
+ `.trim();
133
+ var AFRAME_GOLD = `
134
+ w=44; d=60; h=66; t=3;
135
+ module tri(w,d,h){ rotate([90,0,90]) linear_extrude(height=w) polygon([[0,0],[d,0],[d/2,h]]); }
136
+ union(){
137
+ difference(){ tri(w,d,h); translate([t,0,0]) tri(w-2*t,d,h-2*t*h/d); }
138
+ translate([w/2-7,-1,0]) cube([14,t+2,24]);
139
+ }
140
+ `.trim();
141
+ var TASKS = [
142
+ {
143
+ id: "two-story-house",
144
+ prompt: [
145
+ "Write OpenSCAD source for a two-story house.",
146
+ "Requirements:",
147
+ "- footprint roughly 80 (X) by 60 (Y) units",
148
+ "- two stories, total wall height ~68 units",
149
+ "- a PITCHED / gabled roof on top (NOT a flat roof) \u2014 the roof must taper toward a ridge",
150
+ "- hollow shell (walls with an interior cavity), not a solid block",
151
+ "- at least one door opening and several windows",
152
+ "Output ONLY the .scad source, no prose, no code fences."
153
+ ].join("\n"),
154
+ meta: {
155
+ spec: {
156
+ volumes: [1, 12],
157
+ bbox: { x: [70, 110], y: [50, 80], z: [80, 130] },
158
+ minTriangles: 60,
159
+ pitchedRoof: 0.55,
160
+ hollowBelow: 0.7
161
+ },
162
+ gold: `
163
+ w=80; d=60; sh=34; t=3; rh=28;
164
+ module shell(w,d,h,t){ difference(){ cube([w,d,h]); translate([t,t,-1]) cube([w-2*t,d-2*t,h+2]); } }
165
+ module roof(w,d,h){ translate([0,0,0]) rotate([90,0,90]) linear_extrude(height=w) polygon([[0,0],[d,0],[d/2,h]]); }
166
+ union(){
167
+ for(s=[0,1]) translate([0,0,s*sh]) shell(w,d,sh,t);
168
+ for(s=[0,1,2]) translate([0,0,s*sh-1]) cube([w,d,1]);
169
+ translate([0,0,2*sh]) roof(w,d,rh);
170
+ for(s=[0,1]) for(i=[0:2]) translate([16+i*22,-1,s*sh+10]) cube([12,t+2,14]);
171
+ translate([w/2-8,-1,2]) cube([16,t+2,22]);
172
+ }
173
+ `.trim()
174
+ }
175
+ },
176
+ ...BUILDING_CONFIGS.map(buildingTask),
177
+ {
178
+ id: "water-tower",
179
+ prompt: [
180
+ "Write OpenSCAD source for a water tower: a tall hollow cylindrical tank with a conical roof.",
181
+ "Requirements:",
182
+ "- a hollow cylindrical tank, ~48 units in diameter, ~72 units tall, with an interior cavity",
183
+ "- a CONICAL roof on top that tapers to a point (a pitched roof)",
184
+ "- wall thickness around 3 units",
185
+ "Output ONLY the .scad source, no prose, no code fences."
186
+ ].join("\n"),
187
+ meta: {
188
+ spec: {
189
+ volumes: [1, 4],
190
+ bbox: { x: [40, 56], y: [40, 56], z: [88, 110] },
191
+ minTriangles: 60,
192
+ pitchedRoof: 0.55,
193
+ hollowBelow: 0.8
194
+ },
195
+ gold: WATER_TOWER_GOLD
196
+ }
197
+ },
198
+ {
199
+ id: "a-frame-cabin",
200
+ prompt: [
201
+ "Write OpenSCAD source for an A-frame cabin: a steep triangular shell where the roof forms the walls.",
202
+ "Requirements:",
203
+ "- footprint roughly 44 (X) by 60 (Y) units",
204
+ "- a STEEP triangular cross-section ~66 units tall that tapers to a ridge at the top",
205
+ "- hollow inside (an interior cavity), not a solid wedge",
206
+ "- a door opening at the front",
207
+ "Output ONLY the .scad source, no prose, no code fences."
208
+ ].join("\n"),
209
+ meta: {
210
+ spec: {
211
+ volumes: [1, 4],
212
+ bbox: { x: [36, 52], y: [50, 74], z: [56, 80] },
213
+ minTriangles: 30,
214
+ pitchedRoof: 0.45,
215
+ hollowBelow: 0.8
216
+ },
217
+ gold: AFRAME_GOLD
218
+ }
219
+ },
220
+ {
221
+ id: "hex-planter",
222
+ prompt: [
223
+ "Write OpenSCAD source for a hexagonal planter pot.",
224
+ "Requirements:",
225
+ "- a hollow hexagonal prism (6-sided), outer width ~50 units across, height ~45",
226
+ "- open at the top, closed at the bottom (a cavity for soil)",
227
+ "- a wall thickness around 3 units",
228
+ "Output ONLY the .scad source, no prose, no code fences."
229
+ ].join("\n"),
230
+ meta: {
231
+ spec: {
232
+ volumes: [1, 3],
233
+ bbox: { x: [40, 60], y: [40, 60], z: [40, 55] },
234
+ minTriangles: 30,
235
+ hollowBelow: 0.7
236
+ },
237
+ gold: `
238
+ $fn=6; or=25; h=45; t=3;
239
+ difference(){
240
+ cylinder(h=h, r=or);
241
+ translate([0,0,t]) cylinder(h=h, r=or-t);
242
+ }
243
+ `.trim()
244
+ }
245
+ }
246
+ ];
247
+ function createCadDesignAdapter() {
248
+ return {
249
+ name: "cad-design",
250
+ async preflight() {
251
+ try {
252
+ await execFileAsync("xvfb-run", ["-a", "openscad", "--version"], { timeout: 3e4 });
253
+ } catch (err) {
254
+ const msg = err instanceof Error ? err.message : String(err);
255
+ throw new Error(
256
+ `cad-design preflight failed: ${msg}
257
+ Fix: install OpenSCAD + Xvfb (Debian/Ubuntu: sudo apt-get install -y openscad xvfb). The judge runs \`xvfb-run -a openscad -o out.stl model.scad\` \u2014 both must be on PATH.`
258
+ );
259
+ }
260
+ },
261
+ async loadTasks(opts = {}) {
262
+ let tasks = TASKS;
263
+ if (opts.ids) tasks = tasks.filter((t) => opts.ids.includes(t.id));
264
+ if (opts.limit != null) tasks = tasks.slice(0, opts.limit);
265
+ return tasks.map((t) => ({ id: t.id, prompt: t.prompt, metadata: t.meta }));
266
+ },
267
+ async goldArtifact(task) {
268
+ const meta = task.metadata;
269
+ return meta?.gold;
270
+ },
271
+ async judge(task, artifact) {
272
+ const spec = task.metadata.spec;
273
+ const src = artifact.trim();
274
+ if (!src) return { resolved: false, score: 0, detail: "empty artifact" };
275
+ const dir = await mkdtemp(join(tmpdir(), "cad-"));
276
+ const scad = join(dir, "model.scad");
277
+ const stlPath = join(dir, "model.stl");
278
+ const pngPath = join(dir, "model.png");
279
+ await writeFile(scad, src);
280
+ let stderr = "";
281
+ try {
282
+ const r = await openscad(["-o", stlPath, scad], dir);
283
+ stderr = r.stderr;
284
+ } catch (err) {
285
+ const msg = err instanceof Error ? err.message : String(err);
286
+ return { resolved: false, score: 0, detail: `compile failed: ${msg.slice(0, 300)}` };
287
+ }
288
+ try {
289
+ await openscad(
290
+ ["-o", pngPath, "--imgsize=1100,850", "--camera=40,30,40,55,0,25,260", "--colorscheme=Tomorrow", scad],
291
+ dir
292
+ );
293
+ } catch {
294
+ }
295
+ let stl;
296
+ try {
297
+ stl = await readFile(stlPath, "utf8");
298
+ } catch {
299
+ return { resolved: false, score: 0, detail: "compiled but produced no STL (empty geometry)" };
300
+ }
301
+ const volumes = Number(/Volumes:\s*(\d+)/.exec(stderr)?.[1] ?? "1");
302
+ const geo = measureStl(stl, volumes);
303
+ const { checks, score } = scoreGeometry(geo, spec);
304
+ const resolved = score === 1;
305
+ const detail = JSON.stringify({
306
+ checks,
307
+ geo: {
308
+ triangles: geo.triangles,
309
+ volumes: geo.volumes,
310
+ bbox: { x: +geo.bbox.x.toFixed(1), y: +geo.bbox.y.toFixed(1), z: +geo.bbox.z.toFixed(1) },
311
+ hollowRatio: +(geo.solidVolume / geo.bboxVolume).toFixed(3),
312
+ topVsBaseFootprint: geo.baseFootprint ? +(geo.topFootprint / geo.baseFootprint).toFixed(3) : null
313
+ },
314
+ renderPath: pngPath,
315
+ stlPath
316
+ });
317
+ return { resolved, score, detail };
318
+ }
319
+ };
320
+ }
321
+
322
+ export {
323
+ createCadDesignAdapter
324
+ };
325
+ //# sourceMappingURL=chunk-53UPUNBZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/benchmarks/cad-design.ts"],"sourcesContent":["/**\n * CAD-Design adapter. Worker artifact = OpenSCAD source (`.scad`). Judge = the\n * REAL OpenSCAD engine: compile + export STL, then measure the produced solid\n * geometry against the task's spec. Fully deterministic — the authoritative CAD\n * kernel is the gate, not an LLM and not the agent's own claim.\n *\n * This is verifiable-reward CAD: an agent is far better at *writing* exact\n * parametric code than at clicking a GUI, and the kernel either produces the\n * specified geometry or it doesn't. Every judged artifact also renders a PNG,\n * so a refine loop's attempts become a watchable \"model getting better\" reel\n * (run-capsule consumes the renders).\n *\n * Spec checks are geometric and ungameable:\n * - compiles : `openscad -o out.stl` exits 0 (hard gate)\n * - volumes : disconnected-solid count within [min,max]\n * - bbox : overall X/Y/Z extent within bounds (the thing is the right size)\n * - detail : triangle count ≥ floor (not a degenerate single cube)\n * - pitchedRoof : the top band's XY footprint NARROWS vs the base — a flat\n * box can't fake this; a real gabled/hipped roof tapers\n * - hollow : interior cavity present (walls, not a solid block) — the\n * bbox volume materially exceeds the printed solid volume\n *\n * Requires only `openscad` + `xvfb-run` on PATH (no venv, no Docker, no network).\n */\n\nimport { execFile } from 'node:child_process'\nimport { mkdtemp, readFile, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\nimport type { BenchmarkAdapter, BenchScore, BenchTask, LoadOptions } from './types'\n\nconst execFileAsync = promisify(execFile)\n\n/** Spec assertions a CAD task can require. All are deterministic + geometric. */\nexport interface CadSpec {\n volumes?: [number, number]\n bbox?: { x?: [number, number]; y?: [number, number]; z?: [number, number] }\n minTriangles?: number\n /** Top-band XY footprint must be < this fraction of the base footprint. */\n pitchedRoof?: number\n /** Printed solid volume must be < this fraction of the bbox volume (hollow). */\n hollowBelow?: number\n}\n\ninterface CadTaskMeta {\n spec: CadSpec\n /** A known-good .scad that satisfies the spec — the oracle for verify-judge. */\n gold: string\n}\n\n/** Run openscad with xvfb (it needs a GL context even headless). */\nasync function openscad(args: string[], cwd: string): Promise<{ stdout: string; stderr: string }> {\n // -a => auto-pick a free display; openscad writes Facets/Volumes to stderr.\n const { stdout, stderr } = await execFileAsync('xvfb-run', ['-a', 'openscad', ...args], {\n cwd,\n maxBuffer: 1024 * 1024 * 64,\n timeout: 120_000,\n })\n return { stdout, stderr }\n}\n\ninterface Geometry {\n triangles: number\n volumes: number\n bbox: { x: number; y: number; z: number }\n /** XY footprint area (extent_x * extent_y) of the bottom 60% and top 25% z-bands. */\n baseFootprint: number\n topFootprint: number\n /** Convex-ish solid volume estimate from the STL (sum of signed tetra volumes). */\n solidVolume: number\n bboxVolume: number\n}\n\n/** Parse an ASCII STL into the geometric measures the spec checks. Pure. */\nfunction measureStl(stl: string, volumesFromStderr: number): Geometry {\n const verts: Array<[number, number, number]> = []\n const tris: Array<[[number, number, number], [number, number, number], [number, number, number]]> = []\n const re = /vertex\\s+(-?[\\d.eE+]+)\\s+(-?[\\d.eE+]+)\\s+(-?[\\d.eE+]+)/g\n let m: RegExpExecArray | null\n const flat: Array<[number, number, number]> = []\n while ((m = re.exec(stl))) flat.push([Number(m[1]), Number(m[2]), Number(m[3])])\n for (let i = 0; i + 2 < flat.length; i += 3) tris.push([flat[i]!, flat[i + 1]!, flat[i + 2]!])\n for (const v of flat) verts.push(v)\n\n const xs = verts.map((v) => v[0])\n const ys = verts.map((v) => v[1])\n const zs = verts.map((v) => v[2])\n const min = (a: number[]) => Math.min(...a)\n const max = (a: number[]) => Math.max(...a)\n const minZ = min(zs)\n const maxZ = max(zs)\n const h = maxZ - minZ || 1\n\n // Footprint of a z-band = XY extent of the vertices within it.\n const footprint = (lo: number, hi: number): number => {\n const band = verts.filter((v) => v[2] >= minZ + lo * h && v[2] <= minZ + hi * h)\n if (band.length < 3) return 0\n const bx = band.map((v) => v[0])\n const by = band.map((v) => v[1])\n return (max(bx) - min(bx)) * (max(by) - min(by))\n }\n\n // Signed volume via the divergence theorem over triangles (|Σ v0·(v1×v2)/6|).\n let vol6 = 0\n for (const [a, b, c] of tris) {\n vol6 +=\n a[0] * (b[1] * c[2] - b[2] * c[1]) -\n a[1] * (b[0] * c[2] - b[2] * c[0]) +\n a[2] * (b[0] * c[1] - b[1] * c[0])\n }\n const bbox = { x: max(xs) - min(xs), y: max(ys) - min(ys), z: maxZ - minZ }\n return {\n triangles: tris.length,\n volumes: volumesFromStderr,\n bbox,\n baseFootprint: footprint(0, 0.6),\n topFootprint: footprint(0.75, 1),\n solidVolume: Math.abs(vol6) / 6,\n bboxVolume: bbox.x * bbox.y * bbox.z || 1,\n }\n}\n\nfunction inRange(v: number, [lo, hi]: [number, number]): boolean {\n return v >= lo && v <= hi\n}\n\n/** Score the geometry against the spec — each check is a named pass/fail. */\nfunction scoreGeometry(g: Geometry, spec: CadSpec): { checks: Record<string, boolean>; score: number } {\n const checks: Record<string, boolean> = {}\n if (spec.volumes) checks.volumes = inRange(g.volumes, spec.volumes)\n if (spec.minTriangles != null) checks.detail = g.triangles >= spec.minTriangles\n if (spec.bbox?.x) checks.bboxX = inRange(g.bbox.x, spec.bbox.x)\n if (spec.bbox?.y) checks.bboxY = inRange(g.bbox.y, spec.bbox.y)\n if (spec.bbox?.z) checks.bboxZ = inRange(g.bbox.z, spec.bbox.z)\n if (spec.pitchedRoof != null)\n checks.pitchedRoof = g.baseFootprint > 0 && g.topFootprint < spec.pitchedRoof * g.baseFootprint\n if (spec.hollowBelow != null) checks.hollow = g.solidVolume < spec.hollowBelow * g.bboxVolume\n const vals = Object.values(checks)\n const score = vals.length ? vals.filter(Boolean).length / vals.length : 0\n return { checks, score }\n}\n\n/** A parametric multi-story gabled building — the gold generator for the\n * building-family tasks. They share geometry (hollow stacked shells + a gabled\n * roof that tapers to a ridge + cut openings) and differ only in dimensions, so\n * one verified generator yields a spec-passing oracle for each. */\nfunction buildingGold(w: number, d: number, sh: number, ns: number, rh: number, t = 3): string {\n return `\nw=${w}; d=${d}; sh=${sh}; ns=${ns}; rh=${rh}; t=${t};\nmodule shell(w,d,h,t){ difference(){ cube([w,d,h]); translate([t,t,-1]) cube([w-2*t,d-2*t,h+2]); } }\nmodule roof(w,d,h){ rotate([90,0,90]) linear_extrude(height=w) polygon([[0,0],[d,0],[d/2,h]]); }\nunion(){\n for(s=[0:ns-1]) translate([0,0,s*sh]) shell(w,d,sh,t);\n for(s=[0:ns]) translate([0,0,s*sh-0.5]) cube([w,d,1]);\n translate([0,0,ns*sh]) roof(w,d,rh);\n for(s=[0:ns-1]) for(i=[0:floor((w-28)/22)]) translate([14+i*22,-1,s*sh+10]) cube([10,t+2,12]);\n translate([w/2-7,-1,2]) cube([14,t+2,20]);\n}\n`.trim()\n}\n\n/** Build a building-family task (prompt + spec + gold) from its dimensions.\n * The spec's bbox is derived from the dims with a ±~18% tolerance so the agent\n * must respect the brief's size; the gold (buildingGold) lands exactly on the\n * nominal dims, so it passes by construction. Keep rh > ns*sh/3 (else the roof\n * base sits inside the top-25% band and pitchedRoof fails). */\nfunction buildingTask(o: { id: string; desc: string; w: number; d: number; sh: number; ns: number; rh: number }): {\n id: string\n prompt: string\n meta: CadTaskMeta\n} {\n const { id, desc, w, d, sh, ns, rh } = o\n const totalWall = ns * sh\n const totalH = totalWall + rh\n const r = Math.round\n const spec: CadSpec = {\n volumes: [1, ns * 4 + 6],\n bbox: {\n x: [r(w * 0.82), r(w * 1.18)],\n y: [r(d * 0.82), r((d + 1) * 1.2)],\n z: [r(totalH * 0.82), r((totalH + 1) * 1.2)],\n },\n minTriangles: 50,\n pitchedRoof: 0.55,\n hollowBelow: 0.72,\n }\n const prompt = [\n `Write OpenSCAD source for ${desc}.`,\n 'Requirements:',\n `- footprint roughly ${w} (X) by ${d} (Y) units`,\n ns > 1 ? `- ${ns} stories, total wall height ~${totalWall} units` : `- one story, wall height ~${sh} units`,\n '- a PITCHED / gabled roof on top that tapers toward a ridge (NOT flat)',\n '- hollow shell (walls with an interior cavity), not a solid block',\n '- a door opening and several windows',\n 'Output ONLY the .scad source, no prose, no code fences.',\n ].join('\\n')\n return { id, prompt, meta: { spec, gold: buildingGold(w, d, sh, ns, rh) } }\n}\n\n/** The building family — one parametric skill (hit the bbox + pitched roof +\n * hollow shell), sampled across footprints, heights, story counts, roof rises. */\nconst BUILDING_CONFIGS: Array<{ id: string; desc: string; w: number; d: number; sh: number; ns: number; rh: number }> = [\n { id: 'cottage', desc: 'a single-story cottage', w: 50, d: 40, sh: 30, ns: 1, rh: 18 },\n { id: 'cabin', desc: 'a small one-room cabin', w: 44, d: 36, sh: 26, ns: 1, rh: 22 },\n { id: 'bungalow', desc: 'a wide single-story bungalow', w: 70, d: 52, sh: 28, ns: 1, rh: 20 },\n { id: 'barn', desc: 'a long deep barn', w: 60, d: 96, sh: 42, ns: 1, rh: 26 },\n { id: 'warehouse', desc: 'a large warehouse', w: 110, d: 80, sh: 40, ns: 1, rh: 26 },\n { id: 'chapel', desc: 'a narrow tall chapel with a steep roof', w: 40, d: 72, sh: 48, ns: 1, rh: 34 },\n { id: 'farmhouse', desc: 'a two-story farmhouse', w: 72, d: 56, sh: 30, ns: 2, rh: 26 },\n { id: 'two-story-manor', desc: 'a wide two-story manor', w: 96, d: 64, sh: 32, ns: 2, rh: 28 },\n { id: 'townhouse', desc: 'a narrow three-story townhouse', w: 42, d: 52, sh: 30, ns: 3, rh: 34 },\n { id: 'watchtower', desc: 'a tall narrow three-story watchtower', w: 34, d: 34, sh: 30, ns: 3, rh: 32 },\n]\n\n/** A hollow cylindrical water tower with a conical roof — a non-box shape that\n * still exercises pitched-roof (the cone tapers to an apex) + hollow + bbox. */\nconst WATER_TOWER_GOLD = `\n$fn=48; r=24; bh=72; t=3; ch=26;\nunion(){\n difference(){ cylinder(h=bh, r=r); translate([0,0,t]) cylinder(h=bh, r=r-t); }\n translate([0,0,bh]) cylinder(h=ch, r1=r, r2=0);\n}\n`.trim()\n\n/** An A-frame: the steep roof IS the walls — a hollow triangular prism. The most\n * extreme taper in the set; tests that the agent can build a non-rectangular shell. */\nconst AFRAME_GOLD = `\nw=44; d=60; h=66; t=3;\nmodule tri(w,d,h){ rotate([90,0,90]) linear_extrude(height=w) polygon([[0,0],[d,0],[d/2,h]]); }\nunion(){\n difference(){ tri(w,d,h); translate([t,0,0]) tri(w-2*t,d,h-2*t*h/d); }\n translate([w/2-7,-1,0]) cube([14,t+2,24]);\n}\n`.trim()\n\nconst TASKS: Array<{ id: string; prompt: string; meta: CadTaskMeta }> = [\n {\n id: 'two-story-house',\n prompt: [\n 'Write OpenSCAD source for a two-story house.',\n 'Requirements:',\n '- footprint roughly 80 (X) by 60 (Y) units',\n '- two stories, total wall height ~68 units',\n '- a PITCHED / gabled roof on top (NOT a flat roof) — the roof must taper toward a ridge',\n '- hollow shell (walls with an interior cavity), not a solid block',\n '- at least one door opening and several windows',\n 'Output ONLY the .scad source, no prose, no code fences.',\n ].join('\\n'),\n meta: {\n spec: {\n volumes: [1, 12],\n bbox: { x: [70, 110], y: [50, 80], z: [80, 130] },\n minTriangles: 60,\n pitchedRoof: 0.55,\n hollowBelow: 0.7,\n },\n gold: `\nw=80; d=60; sh=34; t=3; rh=28;\nmodule shell(w,d,h,t){ difference(){ cube([w,d,h]); translate([t,t,-1]) cube([w-2*t,d-2*t,h+2]); } }\nmodule roof(w,d,h){ translate([0,0,0]) rotate([90,0,90]) linear_extrude(height=w) polygon([[0,0],[d,0],[d/2,h]]); }\nunion(){\n for(s=[0,1]) translate([0,0,s*sh]) shell(w,d,sh,t);\n for(s=[0,1,2]) translate([0,0,s*sh-1]) cube([w,d,1]);\n translate([0,0,2*sh]) roof(w,d,rh);\n for(s=[0,1]) for(i=[0:2]) translate([16+i*22,-1,s*sh+10]) cube([12,t+2,14]);\n translate([w/2-8,-1,2]) cube([16,t+2,22]);\n}\n`.trim(),\n },\n },\n ...BUILDING_CONFIGS.map(buildingTask),\n {\n id: 'water-tower',\n prompt: [\n 'Write OpenSCAD source for a water tower: a tall hollow cylindrical tank with a conical roof.',\n 'Requirements:',\n '- a hollow cylindrical tank, ~48 units in diameter, ~72 units tall, with an interior cavity',\n '- a CONICAL roof on top that tapers to a point (a pitched roof)',\n '- wall thickness around 3 units',\n 'Output ONLY the .scad source, no prose, no code fences.',\n ].join('\\n'),\n meta: {\n spec: {\n volumes: [1, 4],\n bbox: { x: [40, 56], y: [40, 56], z: [88, 110] },\n minTriangles: 60,\n pitchedRoof: 0.55,\n hollowBelow: 0.8,\n },\n gold: WATER_TOWER_GOLD,\n },\n },\n {\n id: 'a-frame-cabin',\n prompt: [\n 'Write OpenSCAD source for an A-frame cabin: a steep triangular shell where the roof forms the walls.',\n 'Requirements:',\n '- footprint roughly 44 (X) by 60 (Y) units',\n '- a STEEP triangular cross-section ~66 units tall that tapers to a ridge at the top',\n '- hollow inside (an interior cavity), not a solid wedge',\n '- a door opening at the front',\n 'Output ONLY the .scad source, no prose, no code fences.',\n ].join('\\n'),\n meta: {\n spec: {\n volumes: [1, 4],\n bbox: { x: [36, 52], y: [50, 74], z: [56, 80] },\n minTriangles: 30,\n pitchedRoof: 0.45,\n hollowBelow: 0.8,\n },\n gold: AFRAME_GOLD,\n },\n },\n {\n id: 'hex-planter',\n prompt: [\n 'Write OpenSCAD source for a hexagonal planter pot.',\n 'Requirements:',\n '- a hollow hexagonal prism (6-sided), outer width ~50 units across, height ~45',\n '- open at the top, closed at the bottom (a cavity for soil)',\n '- a wall thickness around 3 units',\n 'Output ONLY the .scad source, no prose, no code fences.',\n ].join('\\n'),\n meta: {\n spec: {\n volumes: [1, 3],\n bbox: { x: [40, 60], y: [40, 60], z: [40, 55] },\n minTriangles: 30,\n hollowBelow: 0.7,\n },\n gold: `\n$fn=6; or=25; h=45; t=3;\ndifference(){\n cylinder(h=h, r=or);\n translate([0,0,t]) cylinder(h=h, r=or-t);\n}\n`.trim(),\n },\n },\n]\n\nexport function createCadDesignAdapter(): BenchmarkAdapter {\n return {\n name: 'cad-design',\n\n async preflight() {\n try {\n await execFileAsync('xvfb-run', ['-a', 'openscad', '--version'], { timeout: 30_000 })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n throw new Error(\n `cad-design preflight failed: ${msg}\\n` +\n `Fix: install OpenSCAD + Xvfb (Debian/Ubuntu: sudo apt-get install -y openscad xvfb). ` +\n `The judge runs \\`xvfb-run -a openscad -o out.stl model.scad\\` — both must be on PATH.`,\n )\n }\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n let tasks = TASKS\n if (opts.ids) tasks = tasks.filter((t) => opts.ids!.includes(t.id))\n if (opts.limit != null) tasks = tasks.slice(0, opts.limit)\n return tasks.map((t): BenchTask => ({ id: t.id, prompt: t.prompt, metadata: t.meta as unknown as Record<string, unknown> }))\n },\n\n async goldArtifact(task: BenchTask) {\n const meta = task.metadata as unknown as CadTaskMeta | undefined\n return meta?.gold\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const spec = (task.metadata as unknown as CadTaskMeta).spec\n const src = artifact.trim()\n if (!src) return { resolved: false, score: 0, detail: 'empty artifact' }\n\n const dir = await mkdtemp(join(tmpdir(), 'cad-'))\n const scad = join(dir, 'model.scad')\n const stlPath = join(dir, 'model.stl')\n const pngPath = join(dir, 'model.png')\n await writeFile(scad, src)\n\n // GATE 1: compile + export STL. Nonzero exit / CGAL error => does not compile.\n let stderr = ''\n try {\n const r = await openscad(['-o', stlPath, scad], dir)\n stderr = r.stderr\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return { resolved: false, score: 0, detail: `compile failed: ${msg.slice(0, 300)}` }\n }\n\n // Render a PNG alongside (the artifact run-capsule animates). Non-fatal.\n try {\n await openscad(\n ['-o', pngPath, '--imgsize=1100,850', '--camera=40,30,40,55,0,25,260', '--colorscheme=Tomorrow', scad],\n dir,\n )\n } catch {\n /* render is for the reel; geometry gate already has the STL */\n }\n\n let stl: string\n try {\n stl = await readFile(stlPath, 'utf8')\n } catch {\n return { resolved: false, score: 0, detail: 'compiled but produced no STL (empty geometry)' }\n }\n const volumes = Number(/Volumes:\\s*(\\d+)/.exec(stderr)?.[1] ?? '1')\n const geo = measureStl(stl, volumes)\n const { checks, score } = scoreGeometry(geo, spec)\n const resolved = score === 1\n const detail = JSON.stringify({\n checks,\n geo: {\n triangles: geo.triangles,\n volumes: geo.volumes,\n bbox: { x: +geo.bbox.x.toFixed(1), y: +geo.bbox.y.toFixed(1), z: +geo.bbox.z.toFixed(1) },\n hollowRatio: +(geo.solidVolume / geo.bboxVolume).toFixed(3),\n topVsBaseFootprint: geo.baseFootprint ? +(geo.topFootprint / geo.baseFootprint).toFixed(3) : null,\n },\n renderPath: pngPath,\n stlPath,\n })\n return { resolved, score, detail }\n },\n }\n}\n"],"mappings":"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","names":[]}