@tangle-network/agent-bench 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/adapters.d.ts +4 -11
  3. package/dist/adapters.js +78 -41
  4. package/dist/adapters.js.map +1 -1
  5. package/dist/benchmarks/_harness.d.ts +48 -66
  6. package/dist/benchmarks/_harness.js +329 -33
  7. package/dist/benchmarks/_harness.js.map +1 -1
  8. package/dist/benchmarks/aec-bench.d.ts +4 -25
  9. package/dist/benchmarks/aec-bench.js +242 -7
  10. package/dist/benchmarks/aec-bench.js.map +1 -1
  11. package/dist/benchmarks/agentbench.d.ts +5 -13
  12. package/dist/benchmarks/agentbench.js +114 -9
  13. package/dist/benchmarks/agentbench.js.map +1 -1
  14. package/dist/benchmarks/appworld.d.ts +9 -29
  15. package/dist/benchmarks/appworld.js +317 -12
  16. package/dist/benchmarks/appworld.js.map +1 -1
  17. package/dist/benchmarks/bfcl.d.ts +5 -15
  18. package/dist/benchmarks/bfcl.js +264 -9
  19. package/dist/benchmarks/bfcl.js.map +1 -1
  20. package/dist/benchmarks/cad-design.d.ts +16 -41
  21. package/dist/benchmarks/cad-design.js +512 -6
  22. package/dist/benchmarks/cad-design.js.map +1 -1
  23. package/dist/benchmarks/cadbench.d.ts +4 -17
  24. package/dist/benchmarks/cadbench.js +2 -8
  25. package/dist/benchmarks/cadgenbench.d.ts +4 -20
  26. package/dist/benchmarks/cadgenbench.js +2 -8
  27. package/dist/benchmarks/commit0.d.ts +5 -27
  28. package/dist/benchmarks/commit0.js +187 -9
  29. package/dist/benchmarks/commit0.js.map +1 -1
  30. package/dist/benchmarks/crag.d.ts +4 -12
  31. package/dist/benchmarks/crag.js +110 -8
  32. package/dist/benchmarks/crag.js.map +1 -1
  33. package/dist/benchmarks/dabstep.d.ts +5 -15
  34. package/dist/benchmarks/dabstep.js +177 -9
  35. package/dist/benchmarks/dabstep.js.map +1 -1
  36. package/dist/benchmarks/enterpriseops-gym.d.ts +5 -34
  37. package/dist/benchmarks/enterpriseops-gym.js +236 -9
  38. package/dist/benchmarks/enterpriseops-gym.js.map +1 -1
  39. package/dist/benchmarks/finresearchbench.d.ts +4 -13
  40. package/dist/benchmarks/finresearchbench.js +218 -7
  41. package/dist/benchmarks/finresearchbench.js.map +1 -1
  42. package/dist/benchmarks/finsearchcomp.d.ts +8 -39
  43. package/dist/benchmarks/finsearchcomp.js +267 -6
  44. package/dist/benchmarks/finsearchcomp.js.map +1 -1
  45. package/dist/benchmarks/frames.d.ts +15 -37
  46. package/dist/benchmarks/frames.js +408 -11
  47. package/dist/benchmarks/frames.js.map +1 -1
  48. package/dist/benchmarks/hotpotqa.d.ts +4 -24
  49. package/dist/benchmarks/hotpotqa.js +250 -14
  50. package/dist/benchmarks/hotpotqa.js.map +1 -1
  51. package/dist/benchmarks/humaneval.d.ts +19 -37
  52. package/dist/benchmarks/humaneval.js +279 -16
  53. package/dist/benchmarks/humaneval.js.map +1 -1
  54. package/dist/benchmarks/mind2web.d.ts +7 -34
  55. package/dist/benchmarks/mind2web.js +257 -8
  56. package/dist/benchmarks/mind2web.js.map +1 -1
  57. package/dist/benchmarks/nomiracl.d.ts +4 -13
  58. package/dist/benchmarks/nomiracl.js +146 -8
  59. package/dist/benchmarks/nomiracl.js.map +1 -1
  60. package/dist/benchmarks/open-rag-bench.d.ts +4 -12
  61. package/dist/benchmarks/open-rag-bench.js +110 -8
  62. package/dist/benchmarks/open-rag-bench.js.map +1 -1
  63. package/dist/benchmarks/programbench.d.ts +5 -29
  64. package/dist/benchmarks/programbench.js +161 -9
  65. package/dist/benchmarks/programbench.js.map +1 -1
  66. package/dist/benchmarks/rag-shared.d.ts +21 -20
  67. package/dist/benchmarks/rag-shared.js +245 -38
  68. package/dist/benchmarks/rag-shared.js.map +1 -1
  69. package/dist/benchmarks/ragbench.d.ts +4 -14
  70. package/dist/benchmarks/ragbench.js +127 -8
  71. package/dist/benchmarks/ragbench.js.map +1 -1
  72. package/dist/benchmarks/simpleqa.d.ts +17 -44
  73. package/dist/benchmarks/simpleqa.js +293 -10
  74. package/dist/benchmarks/simpleqa.js.map +1 -1
  75. package/dist/benchmarks/swe-bench.d.ts +23 -36
  76. package/dist/benchmarks/swe-bench.js +234 -13
  77. package/dist/benchmarks/swe-bench.js.map +1 -1
  78. package/dist/benchmarks/t2-ragbench.d.ts +4 -12
  79. package/dist/benchmarks/t2-ragbench.js +118 -8
  80. package/dist/benchmarks/t2-ragbench.js.map +1 -1
  81. package/dist/benchmarks/tau-bench-shared.d.ts +14 -22
  82. package/dist/benchmarks/tau-bench-shared.js +169 -9
  83. package/dist/benchmarks/tau-bench-shared.js.map +1 -1
  84. package/dist/benchmarks/tau2-bench.d.ts +5 -5
  85. package/dist/benchmarks/tau2-bench.js +28 -10
  86. package/dist/benchmarks/tau2-bench.js.map +1 -1
  87. package/dist/benchmarks/tau3-banking.d.ts +4 -13
  88. package/dist/benchmarks/tau3-banking.js +28 -8
  89. package/dist/benchmarks/tau3-banking.js.map +1 -1
  90. package/dist/benchmarks/terminal-bench.d.ts +4 -22
  91. package/dist/benchmarks/terminal-bench.js +140 -7
  92. package/dist/benchmarks/terminal-bench.js.map +1 -1
  93. package/dist/benchmarks/toollm.d.ts +5 -13
  94. package/dist/benchmarks/toollm.js +184 -9
  95. package/dist/benchmarks/toollm.js.map +1 -1
  96. package/dist/benchmarks/trata-hedge.d.ts +4 -30
  97. package/dist/benchmarks/trata-hedge.js +336 -6
  98. package/dist/benchmarks/trata-hedge.js.map +1 -1
  99. package/dist/benchmarks/types.d.ts +85 -94
  100. package/dist/benchmarks/types.js +1 -1
  101. package/dist/benchmarks/webarena-verified.d.ts +5 -13
  102. package/dist/benchmarks/webarena-verified.js +152 -9
  103. package/dist/benchmarks/webarena-verified.js.map +1 -1
  104. package/dist/cadbench-DpQWZHp4.js +285 -0
  105. package/dist/cadbench-DpQWZHp4.js.map +1 -0
  106. package/dist/cadgenbench-DRhczfsG.js +151 -0
  107. package/dist/cadgenbench-DRhczfsG.js.map +1 -0
  108. package/dist/index.d.ts +245 -293
  109. package/dist/index.js +1669 -1791
  110. package/dist/index.js.map +1 -1
  111. package/package.json +17 -14
  112. package/scripts/verify-packed-consumer.mjs +20 -17
  113. package/src/corpus.test.mts +13 -0
  114. package/src/corpus.ts +4 -0
  115. package/src/profile-coordinates.ts +2 -2
  116. package/src/rollout-ledger/backfill-swe-arena.mts +5 -1
  117. package/src/rollout-ledger/settle-capture.mts +7 -1
  118. package/src/search-bench/profiles.ts +1 -1
  119. package/src/skill-sandbox-smoke.mts +2 -1
  120. package/src/swe-arena/gepa-seat.mts +1 -1
  121. package/src/swe-arena/ledger-orphans.test.mts +36 -34
  122. package/dist/benchmarks/cadbench.js.map +0 -1
  123. package/dist/benchmarks/cadgenbench.js.map +0 -1
  124. package/dist/benchmarks/types.js.map +0 -1
  125. package/dist/chunk-53UPUNBZ.js +0 -325
  126. package/dist/chunk-53UPUNBZ.js.map +0 -1
  127. package/dist/chunk-5FEQDSCT.js +0 -211
  128. package/dist/chunk-5FEQDSCT.js.map +0 -1
  129. package/dist/chunk-5H5XV76F.js +0 -240
  130. package/dist/chunk-5H5XV76F.js.map +0 -1
  131. package/dist/chunk-67ACKDCX.js +0 -118
  132. package/dist/chunk-67ACKDCX.js.map +0 -1
  133. package/dist/chunk-7FKBWOQT.js +0 -147
  134. package/dist/chunk-7FKBWOQT.js.map +0 -1
  135. package/dist/chunk-BEN6IF2X.js +0 -221
  136. package/dist/chunk-BEN6IF2X.js.map +0 -1
  137. package/dist/chunk-BZY5QARD.js +0 -120
  138. package/dist/chunk-BZY5QARD.js.map +0 -1
  139. package/dist/chunk-C7T7WEK2.js +0 -103
  140. package/dist/chunk-C7T7WEK2.js.map +0 -1
  141. package/dist/chunk-CLIKAXKH.js +0 -276
  142. package/dist/chunk-CLIKAXKH.js.map +0 -1
  143. package/dist/chunk-CWIOBFSP.js +0 -197
  144. package/dist/chunk-CWIOBFSP.js.map +0 -1
  145. package/dist/chunk-CXDUTWQE.js +0 -318
  146. package/dist/chunk-CXDUTWQE.js.map +0 -1
  147. package/dist/chunk-DWALFME7.js +0 -182
  148. package/dist/chunk-DWALFME7.js.map +0 -1
  149. package/dist/chunk-EEOC6QPJ.js +0 -144
  150. package/dist/chunk-EEOC6QPJ.js.map +0 -1
  151. package/dist/chunk-EIETHPD5.js +0 -321
  152. package/dist/chunk-EIETHPD5.js.map +0 -1
  153. package/dist/chunk-GC2EPS6L.js +0 -130
  154. package/dist/chunk-GC2EPS6L.js.map +0 -1
  155. package/dist/chunk-GCHL6XPM.js +0 -169
  156. package/dist/chunk-GCHL6XPM.js.map +0 -1
  157. package/dist/chunk-HQ5HCCKF.js +0 -142
  158. package/dist/chunk-HQ5HCCKF.js.map +0 -1
  159. package/dist/chunk-HVW25KSX.js +0 -208
  160. package/dist/chunk-HVW25KSX.js.map +0 -1
  161. package/dist/chunk-INNOYXCP.js +0 -387
  162. package/dist/chunk-INNOYXCP.js.map +0 -1
  163. package/dist/chunk-J6BU3NTM.js +0 -251
  164. package/dist/chunk-J6BU3NTM.js.map +0 -1
  165. package/dist/chunk-JSQOUKXS.js +0 -149
  166. package/dist/chunk-JSQOUKXS.js.map +0 -1
  167. package/dist/chunk-JTHWEDEW.js +0 -32
  168. package/dist/chunk-JTHWEDEW.js.map +0 -1
  169. package/dist/chunk-NRMGT25X.js +0 -116
  170. package/dist/chunk-NRMGT25X.js.map +0 -1
  171. package/dist/chunk-PA2ZKHJC.js +0 -230
  172. package/dist/chunk-PA2ZKHJC.js.map +0 -1
  173. package/dist/chunk-PUIRNYI7.js +0 -189
  174. package/dist/chunk-PUIRNYI7.js.map +0 -1
  175. package/dist/chunk-QZZEAHWJ.js +0 -136
  176. package/dist/chunk-QZZEAHWJ.js.map +0 -1
  177. package/dist/chunk-SEVJPLZC.js +0 -260
  178. package/dist/chunk-SEVJPLZC.js.map +0 -1
  179. package/dist/chunk-TBKU5XQI.js +0 -228
  180. package/dist/chunk-TBKU5XQI.js.map +0 -1
  181. package/dist/chunk-UPAMRDX4.js +0 -233
  182. package/dist/chunk-UPAMRDX4.js.map +0 -1
  183. package/dist/chunk-VQRS7VUC.js +0 -342
  184. package/dist/chunk-VQRS7VUC.js.map +0 -1
  185. package/dist/chunk-WG7TM7UV.js +0 -30
  186. package/dist/chunk-WG7TM7UV.js.map +0 -1
  187. package/dist/chunk-X3BTXCJ4.js +0 -262
  188. package/dist/chunk-X3BTXCJ4.js.map +0 -1
  189. package/dist/chunk-XXFF3RRD.js +0 -162
  190. package/dist/chunk-XXFF3RRD.js.map +0 -1
  191. package/dist/chunk-ZFNOM7WR.js +0 -27
  192. package/dist/chunk-ZFNOM7WR.js.map +0 -1
  193. package/dist/chunk-ZNCCYTFG.js +0 -170
  194. package/dist/chunk-ZNCCYTFG.js.map +0 -1
@@ -1,325 +0,0 @@
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
@@ -1 +0,0 @@
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":[]}
@@ -1,211 +0,0 @@
1
- import {
2
- benchRoot,
3
- runVenvScriptStdin
4
- } from "./chunk-EIETHPD5.js";
5
-
6
- // src/benchmarks/enterpriseops-gym.ts
7
- import { mkdir, readFile, rm, writeFile } from "fs/promises";
8
- import { join } from "path";
9
- var FIXTURES = join(benchRoot, "fixtures", "enterpriseops-gym.json");
10
- var JUDGE = join(benchRoot, "scripts", "enterpriseops_gym_judge.py");
11
- var judgeCallSeq = 0;
12
- var DATASET = "ServiceNow-AI/EnterpriseOps-Gym";
13
- var DEFAULT_MODE = "oracle";
14
- var DEFAULT_DOMAIN = "itsm";
15
- var rowsApi = (mode, domain) => `https://datasets-server.huggingface.co/rows?dataset=${encodeURIComponent(DATASET)}&config=${encodeURIComponent(mode)}&split=${encodeURIComponent(domain)}`;
16
- var enterpriseOpsTranscriptOutput = {
17
- parse(events) {
18
- let text = "";
19
- for (const ev of events) {
20
- const d = ev?.data;
21
- const t = d?.finalText ?? d?.text ?? d?.result;
22
- if (typeof t === "string" && t.length > 0) text = t;
23
- }
24
- const fences = [...text.matchAll(/```(?:json)?\s*\n([\s\S]*?)```/g)];
25
- return (fences.at(-1)?.[1] ?? text).trim();
26
- }
27
- };
28
- function asArray(v) {
29
- return typeof v === "string" ? JSON.parse(v) : v;
30
- }
31
- function workerContract(tools) {
32
- return [
33
- "",
34
- `You have exactly these tools available (call NO others): ${tools.join(", ")}.`,
35
- "Plan the full sequence of tool calls that brings the enterprise database to the required final state, honoring every policy in the role above.",
36
- "Emit your COMPLETE plan as the LAST thing in your reply, in a single fenced ```json block, as an object:",
37
- '{ "calls": [ { "tool": "<tool_name>", "arguments": { ... } } ] }',
38
- "Include one entry per tool call in execution order. Nothing after the closing fence."
39
- ].join("\n");
40
- }
41
- function rowToTask(row, mode) {
42
- const servers = asArray(row.gym_servers_config);
43
- const verifiers = asArray(row.verifiers);
44
- const meta = {
45
- taskId: row.task_id,
46
- domain: row.domain,
47
- mode,
48
- selectedTools: row.selected_tools,
49
- servers,
50
- verifiers
51
- };
52
- return {
53
- id: row.task_id,
54
- split: row.domain,
55
- prompt: [row.system_prompt, "", row.user_prompt, workerContract(row.selected_tools)].join("\n"),
56
- metadata: meta
57
- };
58
- }
59
- function readMeta(task) {
60
- const md = task.metadata;
61
- if (!md || typeof md.taskId !== "string" || !Array.isArray(md.servers) || !Array.isArray(md.verifiers) || md.verifiers.length === 0) {
62
- throw new Error(`enterpriseops-gym task ${task.id} missing metadata \u2014 loadTasks did not populate it`);
63
- }
64
- return md;
65
- }
66
- function selectRows(rows, mode, opts) {
67
- let tasks = rows.map((r) => rowToTask(r, mode));
68
- if (opts.ids) {
69
- const want = new Set(opts.ids);
70
- tasks = tasks.filter((t) => want.has(t.id));
71
- } else if (opts.limit !== void 0) {
72
- tasks = tasks.slice(0, opts.limit);
73
- }
74
- return tasks;
75
- }
76
- async function loadFixtures(mode, opts) {
77
- const rows = JSON.parse(await readFile(FIXTURES, "utf8"));
78
- console.warn(
79
- `[enterpriseops-gym] EOPS_FIXTURES=1 \u2014 loading ${rows.length} committed sample rows from ${FIXTURES} (no HF fetch)`
80
- );
81
- const domain = opts.split;
82
- const scoped = domain ? rows.filter((r) => r.domain === domain) : rows;
83
- return selectRows(scoped, mode, opts);
84
- }
85
- async function fetchRows(mode, domain, opts) {
86
- const target = opts.ids ? opts.ids.length * 4 : opts.limit ?? 16;
87
- const rows = [];
88
- const want = opts.ids ? new Set(opts.ids) : null;
89
- const page = 100;
90
- const base = rowsApi(mode, domain);
91
- for (let offset = 0; offset < 1024 && rows.length < target; offset += page) {
92
- const res = await fetch(`${base}&offset=${offset}&length=${page}`);
93
- if (!res.ok) {
94
- throw new Error(`enterpriseops-gym rows HTTP ${res.status} (offset ${offset}): ${(await res.text()).slice(0, 200)}`);
95
- }
96
- const body = await res.json();
97
- const got = body.rows ?? [];
98
- if (got.length === 0) break;
99
- for (const r of got) {
100
- if (want && !want.has(r.row.task_id)) continue;
101
- rows.push(r.row);
102
- }
103
- if (got.length < page) break;
104
- }
105
- if (rows.length === 0) throw new Error(`enterpriseops-gym: no rows matched ${JSON.stringify(opts)} for ${mode}/${domain}`);
106
- return rows;
107
- }
108
- async function runJudge(meta, artifact) {
109
- const taskJsonPath = join(
110
- benchRoot,
111
- ".eops-task-cache",
112
- `${meta.taskId}-${process.pid}-${judgeCallSeq++}.json`
113
- );
114
- await writeTaskCache(taskJsonPath, meta);
115
- let stdout;
116
- try {
117
- stdout = await runVenvScriptStdin(JUDGE, ["judge", "--task-json", taskJsonPath], artifact, { cwd: benchRoot });
118
- } catch (err) {
119
- const e = err;
120
- throw new Error(
121
- `enterpriseops-gym judge failed for ${meta.taskId}: ${(e.message || String(err)).slice(0, 1500)}
122
- Fix: (1) run the ${meta.domain} gym server \u2014 docker pull shivakrishnareddyma225/enterpriseops-gym-mcp-${meta.domain}:latest ; docker run -d -p <host>:8005 shivakrishnareddyma225/enterpriseops-gym-mcp-${meta.domain}:latest ; (2) unzip gym_dbs.zip (ServiceNow/EnterpriseOps-Gym) and export EOPS_GYM_DBS_DIR to its dir (the judge seeds each task's database from seed_database_file).`
123
- );
124
- } finally {
125
- await rm(taskJsonPath, { force: true }).catch(() => {
126
- });
127
- }
128
- const report = JSON.parse(stdout.trim().split("\n").at(-1) ?? "{}");
129
- if (report.error) throw new Error(`enterpriseops-gym judge error for ${meta.taskId}: ${report.error}`);
130
- if (typeof report.passes !== "number" || typeof report.total !== "number") {
131
- throw new Error(`enterpriseops-gym judge returned no {passes,total}: ${stdout.slice(0, 400)}`);
132
- }
133
- const score = report.total > 0 ? report.passes / report.total : 0;
134
- return {
135
- resolved: report.success === true && report.total > 0 && report.passes === report.total,
136
- score,
137
- detail: JSON.stringify({ taskId: meta.taskId, domain: meta.domain, passes: report.passes, total: report.total })
138
- };
139
- }
140
- async function writeTaskCache(path, meta) {
141
- await mkdir(join(path, ".."), { recursive: true });
142
- await writeFile(
143
- path,
144
- JSON.stringify({ task_id: meta.taskId, domain: meta.domain, gym_servers_config: meta.servers, verifiers: meta.verifiers })
145
- );
146
- }
147
- async function probeServers(servers, domain) {
148
- for (const s of servers) {
149
- const url = `${s.mcp_server_url.replace(/\/$/, "")}/api/sql-runner`;
150
- try {
151
- const res = await fetch(url, { method: "POST", headers: { "content-type": "application/json" }, body: "{}" });
152
- void res.status;
153
- } catch (err) {
154
- throw new Error(
155
- `enterpriseops-gym preflight: ${s.mcp_server_name} unreachable at ${url}: ${err instanceof Error ? err.message : err}
156
- Fix: docker pull shivakrishnareddyma225/enterpriseops-gym-mcp-${domain}:latest ; docker run -d -p <port>:<port> shivakrishnareddyma225/enterpriseops-gym-mcp-${domain}:latest ; seed from gym_dbs.zip. Set EOPS_FIXTURES=1 to load sample tasks offline (judge still needs a live server).`
157
- );
158
- }
159
- }
160
- }
161
- function createEnterpriseOpsGymAdapter() {
162
- const fixturesMode = process.env.EOPS_FIXTURES === "1";
163
- const mode = process.env.EOPS_MODE ?? DEFAULT_MODE;
164
- return {
165
- name: "enterpriseops-gym",
166
- output: enterpriseOpsTranscriptOutput,
167
- async preflight() {
168
- if (fixturesMode) {
169
- await readFile(FIXTURES, "utf8").catch((err) => {
170
- throw new Error(`EOPS_FIXTURES=1 but ${FIXTURES} unreadable: ${err instanceof Error ? err.message : err}`);
171
- });
172
- return;
173
- }
174
- const sample = await loadFixtures(mode, { split: DEFAULT_DOMAIN, limit: 1 }).catch(() => []);
175
- const servers = sample[0] ? readMeta(sample[0]).servers : [];
176
- if (servers.length === 0) {
177
- throw new Error(
178
- `enterpriseops-gym preflight: no gym_servers_config to probe. Set EOPS_FIXTURES=1 to load offline, or ensure the dataset rows carry gym_servers_config.`
179
- );
180
- }
181
- await probeServers(servers, DEFAULT_DOMAIN);
182
- },
183
- async loadTasks(opts = {}) {
184
- const domain = opts.split ?? DEFAULT_DOMAIN;
185
- if (fixturesMode) return loadFixtures(mode, opts);
186
- let rows;
187
- try {
188
- rows = await fetchRows(mode, domain, opts);
189
- } catch (err) {
190
- console.warn(
191
- `[enterpriseops-gym] live rows fetch failed (${err instanceof Error ? err.message : err}); falling back to committed sample at ${FIXTURES}`
192
- );
193
- return loadFixtures(mode, opts);
194
- }
195
- return selectRows(rows, mode, opts);
196
- },
197
- async goldArtifact() {
198
- return void 0;
199
- },
200
- async judge(task, artifact) {
201
- const meta = readMeta(task);
202
- return runJudge(meta, artifact);
203
- }
204
- };
205
- }
206
-
207
- export {
208
- enterpriseOpsTranscriptOutput,
209
- createEnterpriseOpsGymAdapter
210
- };
211
- //# sourceMappingURL=chunk-5FEQDSCT.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/benchmarks/enterpriseops-gym.ts"],"sourcesContent":["/**\n * EnterpriseOps-Gym adapter (ServiceNow-AI/EnterpriseOps-Gym, Apache-2.0) —\n * stateful agentic planning + tool use in enterprise settings. Each record is an\n * enterprise-ops task (Customer Service, HR, ITSM, Calendar, Email, Drive, Teams,\n * Hybrid) handed to the agent with a domain `system_prompt`, a `selected_tools`\n * allow-list, and one or more containerized gym MCP servers (`gym_servers_config`).\n * Worker artifact = the ordered tool-call transcript the agent would issue against\n * those servers, emitted as a single fenced ```json block of\n * `{ \"calls\": [ { \"tool\": ..., \"arguments\": {...}, \"gym_name\"?: ... } ] }`.\n *\n * Judge = the benchmark's OWN deterministic state-checker. The driver replays the\n * transcript against a freshly-seeded gym server (mutating its database), then runs\n * each task's `database_state` verifier — an SQL SELECT executed via the gym\n * server's /api/sql-runner endpoint, compared to `expected_value` under\n * `comparison_type` (equals/greater_than/less_than/contains). GRADED: score =\n * (verifiers passing) / (total verifiers) = the bench's verifier_level_pass_rate;\n * binary `resolved` = ALL verifiers pass = the bench's overall_success_rate. Fully\n * deterministic — no LLM judge.\n *\n * loadTasks enumerates the real suite from the HF rows server (config = tool-set\n * MODE oracle|plus_5_tools|plus_10_tools|plus_15_tools; split = DOMAIN); a committed\n * sample (bench/fixtures/enterpriseops-gym.json) loads offline.\n *\n * Requires for a LIVE judge run: a Docker daemon with the domain gym images\n * (`docker pull shivakrishnareddyma225/enterpriseops-gym-mcp-<domain>:latest`) up\n * on the ports in `gym_servers_config`, seeded from gym_dbs.zip. preflight + judge\n * fail loud with the exact pull/run/unzip step when a server is unreachable — never\n * a fabricated score. No portable gold artifact ships, so goldArtifact is undefined.\n */\n\nimport { mkdir, readFile, rm, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { OutputAdapter } from '@tangle-network/agent-runtime/loops'\nimport { benchRoot, runVenvScriptStdin } from './_harness'\nimport type { BenchmarkAdapter, BenchScore, BenchTask, LoadOptions } from './types'\n\nconst FIXTURES = join(benchRoot, 'fixtures', 'enterpriseops-gym.json')\nconst JUDGE = join(benchRoot, 'scripts', 'enterpriseops_gym_judge.py')\n\n/** Monotonic discriminator so concurrent judge calls stage distinct task-cache files. */\nlet judgeCallSeq = 0\n\nconst DATASET = 'ServiceNow-AI/EnterpriseOps-Gym'\n/** Tool-set mode = HF config; oracle ships exact tools, plus_N adds N distractors. */\nconst DEFAULT_MODE = 'oracle'\n/** Domain = HF split. */\nconst DEFAULT_DOMAIN = 'itsm'\n\nconst rowsApi = (mode: string, domain: string) =>\n `https://datasets-server.huggingface.co/rows?dataset=${encodeURIComponent(DATASET)}&config=${encodeURIComponent(mode)}&split=${encodeURIComponent(domain)}`\n\ninterface GymServerConfig {\n mcp_server_name: string\n mcp_server_url: string\n seed_database_file: string\n context?: Record<string, string>\n user_info?: Record<string, unknown>\n}\n\ninterface Verifier {\n verifier_type: string\n name: string\n description?: string\n gym_name: string\n validation_config: { query: string; expected_value: unknown; comparison_type: string }\n}\n\ninterface EopsRow {\n task_id: string\n domain: string\n system_prompt: string\n user_prompt: string\n selected_tools: string[]\n restricted_tools: string[]\n mcp_endpoint: string\n number_of_runs: number\n reset_database_between_runs: boolean\n /** HF parquet stores these as JSON strings; fixtures store them as parsed arrays. */\n gym_servers_config: string | GymServerConfig[]\n verifiers: string | Verifier[]\n}\n\ninterface EopsMeta {\n taskId: string\n domain: string\n mode: string\n selectedTools: string[]\n servers: GymServerConfig[]\n verifiers: Verifier[]\n}\n\n/** Worker transcript = the last fenced ```json block, else the raw text. */\nexport const enterpriseOpsTranscriptOutput: 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(/```(?:json)?\\s*\\n([\\s\\S]*?)```/g)]\n return (fences.at(-1)?.[1] ?? text).trim()\n },\n}\n\nfunction asArray<T>(v: string | T[]): T[] {\n return typeof v === 'string' ? (JSON.parse(v) as T[]) : v\n}\n\nfunction workerContract(tools: string[]): string {\n return [\n '',\n `You have exactly these tools available (call NO others): ${tools.join(', ')}.`,\n 'Plan the full sequence of tool calls that brings the enterprise database to the required final state, honoring every policy in the role above.',\n 'Emit your COMPLETE plan as the LAST thing in your reply, in a single fenced ```json block, as an object:',\n '{ \"calls\": [ { \"tool\": \"<tool_name>\", \"arguments\": { ... } } ] }',\n 'Include one entry per tool call in execution order. Nothing after the closing fence.',\n ].join('\\n')\n}\n\nfunction rowToTask(row: EopsRow, mode: string): BenchTask {\n const servers = asArray<GymServerConfig>(row.gym_servers_config)\n const verifiers = asArray<Verifier>(row.verifiers)\n const meta: EopsMeta = {\n taskId: row.task_id,\n domain: row.domain,\n mode,\n selectedTools: row.selected_tools,\n servers,\n verifiers,\n }\n return {\n id: row.task_id,\n split: row.domain,\n prompt: [row.system_prompt, '', row.user_prompt, workerContract(row.selected_tools)].join('\\n'),\n metadata: meta as unknown as Record<string, unknown>,\n }\n}\n\nfunction readMeta(task: BenchTask): EopsMeta {\n const md = task.metadata\n if (\n !md ||\n typeof md.taskId !== 'string' ||\n !Array.isArray(md.servers) ||\n !Array.isArray(md.verifiers) ||\n (md.verifiers as unknown[]).length === 0\n ) {\n throw new Error(`enterpriseops-gym task ${task.id} missing metadata — loadTasks did not populate it`)\n }\n return md as unknown as EopsMeta\n}\n\nfunction selectRows(rows: EopsRow[], mode: string, opts: LoadOptions): BenchTask[] {\n let tasks = rows.map((r) => rowToTask(r, mode))\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(mode: string, opts: LoadOptions): Promise<BenchTask[]> {\n const rows = JSON.parse(await readFile(FIXTURES, 'utf8')) as EopsRow[]\n console.warn(\n `[enterpriseops-gym] EOPS_FIXTURES=1 — loading ${rows.length} committed sample rows from ${FIXTURES} (no HF fetch)`,\n )\n const domain = opts.split\n const scoped = domain ? rows.filter((r) => r.domain === domain) : rows\n return selectRows(scoped, mode, opts)\n}\n\n/** Pull real rows from the HF rows server (paged) for one mode/domain. Throws loud on a non-OK response. */\nasync function fetchRows(mode: string, domain: string, opts: LoadOptions): Promise<EopsRow[]> {\n const target = opts.ids ? opts.ids.length * 4 : (opts.limit ?? 16)\n const rows: EopsRow[] = []\n const want = opts.ids ? new Set(opts.ids) : null\n const page = 100\n const base = rowsApi(mode, domain)\n for (let offset = 0; offset < 1024 && rows.length < target; offset += page) {\n const res = await fetch(`${base}&offset=${offset}&length=${page}`)\n if (!res.ok) {\n throw new Error(`enterpriseops-gym rows HTTP ${res.status} (offset ${offset}): ${(await res.text()).slice(0, 200)}`)\n }\n const body = (await res.json()) as { rows?: Array<{ row: EopsRow }> }\n const got = body.rows ?? []\n if (got.length === 0) break\n for (const r of got) {\n if (want && !want.has(r.row.task_id)) continue\n rows.push(r.row)\n }\n if (got.length < page) break\n }\n if (rows.length === 0) throw new Error(`enterpriseops-gym: no rows matched ${JSON.stringify(opts)} for ${mode}/${domain}`)\n return rows\n}\n\n/**\n * Run the benchmark's own state-checker for one task over the worker's transcript.\n * The driver replays the tool calls against the live gym server, runs each\n * database_state verifier's SQL via /api/sql-runner, and reports {passes,total}.\n * Score = passes/total (verifier_level_pass_rate); resolved = all pass\n * (overall_success_rate). This is the expensive Docker-backed boundary — delegated\n * to the python driver, not reimplemented. The transcript is piped on stdin via the\n * shared stdin-aware runner (execFile's `input` is not honored async and hangs the\n * reader).\n */\nasync function runJudge(meta: EopsMeta, artifact: string): Promise<BenchScore> {\n // Stage the full task record (servers + verifiers) so the driver has the live\n // server URLs/contexts and the SQL it must run. The path is UNIQUE per call: the gate\n // runs k judges for one task concurrently, so a `${taskId}.json` shared path would race.\n const taskJsonPath = join(\n benchRoot,\n '.eops-task-cache',\n `${meta.taskId}-${process.pid}-${judgeCallSeq++}.json`,\n )\n await writeTaskCache(taskJsonPath, meta)\n let stdout: string\n try {\n stdout = await runVenvScriptStdin(JUDGE, ['judge', '--task-json', taskJsonPath], artifact, { cwd: benchRoot })\n } catch (err) {\n const e = err as { message?: string }\n throw new Error(\n `enterpriseops-gym judge failed for ${meta.taskId}: ${(e.message || String(err)).slice(0, 1500)}\\n` +\n `Fix: (1) run the ${meta.domain} gym server — ` +\n `docker pull shivakrishnareddyma225/enterpriseops-gym-mcp-${meta.domain}:latest ; ` +\n `docker run -d -p <host>:8005 shivakrishnareddyma225/enterpriseops-gym-mcp-${meta.domain}:latest ; ` +\n `(2) unzip gym_dbs.zip (ServiceNow/EnterpriseOps-Gym) and export EOPS_GYM_DBS_DIR to its dir ` +\n `(the judge seeds each task's database from seed_database_file).`,\n )\n } finally {\n await rm(taskJsonPath, { force: true }).catch(() => {})\n }\n const report = JSON.parse(stdout.trim().split('\\n').at(-1) ?? '{}') as {\n success?: boolean\n passes?: number\n total?: number\n error?: string\n }\n if (report.error) throw new Error(`enterpriseops-gym judge error for ${meta.taskId}: ${report.error}`)\n if (typeof report.passes !== 'number' || typeof report.total !== 'number') {\n throw new Error(`enterpriseops-gym judge returned no {passes,total}: ${stdout.slice(0, 400)}`)\n }\n const score = report.total > 0 ? report.passes / report.total : 0\n return {\n resolved: report.success === true && report.total > 0 && report.passes === report.total,\n score,\n detail: JSON.stringify({ taskId: meta.taskId, domain: meta.domain, passes: report.passes, total: report.total }),\n }\n}\n\nasync function writeTaskCache(path: string, meta: EopsMeta): Promise<void> {\n await mkdir(join(path, '..'), { recursive: true })\n await writeFile(\n path,\n JSON.stringify({ task_id: meta.taskId, domain: meta.domain, gym_servers_config: meta.servers, verifiers: meta.verifiers }),\n )\n}\n\n/** Ping the configured gym servers' SQL endpoint; throw loud with the docker fix if any is unreachable. */\nasync function probeServers(servers: GymServerConfig[], domain: string): Promise<void> {\n for (const s of servers) {\n const url = `${s.mcp_server_url.replace(/\\/$/, '')}/api/sql-runner`\n try {\n // A HEAD/empty POST just proves reachability; a real query runs in judge.\n const res = await fetch(url, { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })\n // Any HTTP response (even an error status) proves the server is up. Only a\n // transport failure (refused/ENOTFOUND) means the container is not running.\n void res.status\n } catch (err) {\n throw new Error(\n `enterpriseops-gym preflight: ${s.mcp_server_name} unreachable at ${url}: ${err instanceof Error ? err.message : err}\\n` +\n `Fix: docker pull shivakrishnareddyma225/enterpriseops-gym-mcp-${domain}:latest ; ` +\n `docker run -d -p <port>:<port> shivakrishnareddyma225/enterpriseops-gym-mcp-${domain}:latest ; ` +\n `seed from gym_dbs.zip. Set EOPS_FIXTURES=1 to load sample tasks offline (judge still needs a live server).`,\n )\n }\n }\n}\n\nexport function createEnterpriseOpsGymAdapter(): BenchmarkAdapter {\n const fixturesMode = process.env.EOPS_FIXTURES === '1'\n const mode = process.env.EOPS_MODE ?? DEFAULT_MODE\n\n return {\n name: 'enterpriseops-gym',\n output: enterpriseOpsTranscriptOutput,\n\n async preflight() {\n // Fixtures mode proves only that the sample file is readable; a live judge\n // still requires running gym servers (and fails loud there if absent).\n if (fixturesMode) {\n await readFile(FIXTURES, 'utf8').catch((err) => {\n throw new Error(`EOPS_FIXTURES=1 but ${FIXTURES} unreadable: ${err instanceof Error ? err.message : err}`)\n })\n return\n }\n // Live mode: probe the gym servers for the default domain (the suite's tasks\n // each carry their own server config; preflight verifies reachability up\n // front so a batch fails fast with the docker fix rather than mid-run).\n const sample = await loadFixtures(mode, { split: DEFAULT_DOMAIN, limit: 1 }).catch(() => [])\n const servers = sample[0] ? readMeta(sample[0]).servers : []\n if (servers.length === 0) {\n throw new Error(\n `enterpriseops-gym preflight: no gym_servers_config to probe. ` +\n `Set EOPS_FIXTURES=1 to load offline, or ensure the dataset rows carry gym_servers_config.`,\n )\n }\n await probeServers(servers, DEFAULT_DOMAIN)\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n const domain = opts.split ?? DEFAULT_DOMAIN\n if (fixturesMode) return loadFixtures(mode, opts)\n let rows: EopsRow[]\n try {\n rows = await fetchRows(mode, domain, opts)\n } catch (err) {\n console.warn(\n `[enterpriseops-gym] live rows fetch failed (${err instanceof Error ? err.message : err}); falling back to committed sample at ${FIXTURES}`,\n )\n return loadFixtures(mode, opts)\n }\n return selectRows(rows, mode, opts)\n },\n\n async goldArtifact() {\n // The benchmark ships no portable per-task oracle transcript — the reference\n // is the seeded final DB state the verifiers check, not a tool-call script.\n // Judge correctness is proven by replaying a real solve against the live gym\n // server, not by a synthetic gold transcript. Returns undefined (documented,\n // not faked).\n return undefined\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const meta = readMeta(task)\n return runJudge(meta, artifact)\n },\n }\n}\n"],"mappings":"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","names":[]}