@tangle-network/agent-bench 0.4.1 → 0.4.4

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 (195) hide show
  1. package/CHANGELOG.md +14 -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 +18 -15
  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/pier-trial-controller.test.mts +15 -7
  116. package/src/profile-coordinates.ts +2 -2
  117. package/src/rollout-ledger/backfill-swe-arena.mts +5 -1
  118. package/src/rollout-ledger/settle-capture.mts +7 -1
  119. package/src/search-bench/profiles.ts +1 -1
  120. package/src/skill-sandbox-smoke.mts +2 -1
  121. package/src/swe-arena/gepa-seat.mts +1 -1
  122. package/src/swe-arena/ledger-orphans.test.mts +36 -34
  123. package/dist/benchmarks/cadbench.js.map +0 -1
  124. package/dist/benchmarks/cadgenbench.js.map +0 -1
  125. package/dist/benchmarks/types.js.map +0 -1
  126. package/dist/chunk-53UPUNBZ.js +0 -325
  127. package/dist/chunk-53UPUNBZ.js.map +0 -1
  128. package/dist/chunk-5FEQDSCT.js +0 -211
  129. package/dist/chunk-5FEQDSCT.js.map +0 -1
  130. package/dist/chunk-5H5XV76F.js +0 -240
  131. package/dist/chunk-5H5XV76F.js.map +0 -1
  132. package/dist/chunk-67ACKDCX.js +0 -118
  133. package/dist/chunk-67ACKDCX.js.map +0 -1
  134. package/dist/chunk-7FKBWOQT.js +0 -147
  135. package/dist/chunk-7FKBWOQT.js.map +0 -1
  136. package/dist/chunk-BEN6IF2X.js +0 -221
  137. package/dist/chunk-BEN6IF2X.js.map +0 -1
  138. package/dist/chunk-BZY5QARD.js +0 -120
  139. package/dist/chunk-BZY5QARD.js.map +0 -1
  140. package/dist/chunk-C7T7WEK2.js +0 -103
  141. package/dist/chunk-C7T7WEK2.js.map +0 -1
  142. package/dist/chunk-CLIKAXKH.js +0 -276
  143. package/dist/chunk-CLIKAXKH.js.map +0 -1
  144. package/dist/chunk-CWIOBFSP.js +0 -197
  145. package/dist/chunk-CWIOBFSP.js.map +0 -1
  146. package/dist/chunk-CXDUTWQE.js +0 -318
  147. package/dist/chunk-CXDUTWQE.js.map +0 -1
  148. package/dist/chunk-DWALFME7.js +0 -182
  149. package/dist/chunk-DWALFME7.js.map +0 -1
  150. package/dist/chunk-EEOC6QPJ.js +0 -144
  151. package/dist/chunk-EEOC6QPJ.js.map +0 -1
  152. package/dist/chunk-EIETHPD5.js +0 -321
  153. package/dist/chunk-EIETHPD5.js.map +0 -1
  154. package/dist/chunk-GC2EPS6L.js +0 -130
  155. package/dist/chunk-GC2EPS6L.js.map +0 -1
  156. package/dist/chunk-GCHL6XPM.js +0 -169
  157. package/dist/chunk-GCHL6XPM.js.map +0 -1
  158. package/dist/chunk-HQ5HCCKF.js +0 -142
  159. package/dist/chunk-HQ5HCCKF.js.map +0 -1
  160. package/dist/chunk-HVW25KSX.js +0 -208
  161. package/dist/chunk-HVW25KSX.js.map +0 -1
  162. package/dist/chunk-INNOYXCP.js +0 -387
  163. package/dist/chunk-INNOYXCP.js.map +0 -1
  164. package/dist/chunk-J6BU3NTM.js +0 -251
  165. package/dist/chunk-J6BU3NTM.js.map +0 -1
  166. package/dist/chunk-JSQOUKXS.js +0 -149
  167. package/dist/chunk-JSQOUKXS.js.map +0 -1
  168. package/dist/chunk-JTHWEDEW.js +0 -32
  169. package/dist/chunk-JTHWEDEW.js.map +0 -1
  170. package/dist/chunk-NRMGT25X.js +0 -116
  171. package/dist/chunk-NRMGT25X.js.map +0 -1
  172. package/dist/chunk-PA2ZKHJC.js +0 -230
  173. package/dist/chunk-PA2ZKHJC.js.map +0 -1
  174. package/dist/chunk-PUIRNYI7.js +0 -189
  175. package/dist/chunk-PUIRNYI7.js.map +0 -1
  176. package/dist/chunk-QZZEAHWJ.js +0 -136
  177. package/dist/chunk-QZZEAHWJ.js.map +0 -1
  178. package/dist/chunk-SEVJPLZC.js +0 -260
  179. package/dist/chunk-SEVJPLZC.js.map +0 -1
  180. package/dist/chunk-TBKU5XQI.js +0 -228
  181. package/dist/chunk-TBKU5XQI.js.map +0 -1
  182. package/dist/chunk-UPAMRDX4.js +0 -233
  183. package/dist/chunk-UPAMRDX4.js.map +0 -1
  184. package/dist/chunk-VQRS7VUC.js +0 -342
  185. package/dist/chunk-VQRS7VUC.js.map +0 -1
  186. package/dist/chunk-WG7TM7UV.js +0 -30
  187. package/dist/chunk-WG7TM7UV.js.map +0 -1
  188. package/dist/chunk-X3BTXCJ4.js +0 -262
  189. package/dist/chunk-X3BTXCJ4.js.map +0 -1
  190. package/dist/chunk-XXFF3RRD.js +0 -162
  191. package/dist/chunk-XXFF3RRD.js.map +0 -1
  192. package/dist/chunk-ZFNOM7WR.js +0 -27
  193. package/dist/chunk-ZFNOM7WR.js.map +0 -1
  194. package/dist/chunk-ZNCCYTFG.js +0 -170
  195. package/dist/chunk-ZNCCYTFG.js.map +0 -1
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-bench",
3
- "version": "0.4.1",
3
+ "version": "0.4.4",
4
4
  "type": "module",
5
- "description": "The unified benchmark suite for agent-runtime agents: 31 adapters (commit0, enterpriseops-gym, ragbench, crag, nomiracl, open-rag-bench, t2-ragbench, tau3-banking, bfcl, finresearchbench, …) behind one resolveAdapter registry, each with a real judge or fail-loud unsupported scorer. Score any profile/skill/prompt change against them. Map: bench/HARNESS.md.",
5
+ "description": "Benchmark adapters and execution for agent-runtime across coding, tool-use, RAG, memory, browser, and terminal tasks.",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/tangle-network/agent-runtime.git",
@@ -25,20 +25,22 @@
25
25
  }
26
26
  },
27
27
  "dependencies": {
28
- "@tangle-network/agent-eval": "0.126.6",
29
- "@tangle-network/agent-interface": "0.32.0",
30
- "@tangle-network/agent-knowledge": "5.0.1",
31
- "@tangle-network/sandbox": "^0.12.0",
32
- "@tangle-network/agent-runtime": "0.105.0"
28
+ "@tangle-network/agent-eval": "0.133.0",
29
+ "@tangle-network/agent-interface": "0.36.0",
30
+ "@tangle-network/agent-knowledge": "6.1.2",
31
+ "@tangle-network/sandbox": "0.15.0",
32
+ "@tangle-network/agent-runtime": "0.107.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@types/node": "^25.9.3",
36
- "tsx": "^4.22.4",
37
- "tsup": "^8.5.1",
38
- "typescript": "^5.7.0"
35
+ "@arethetypeswrong/cli": "0.18.5",
36
+ "@types/node": "26.1.1",
37
+ "publint": "0.3.22",
38
+ "tsdown": "0.22.14",
39
+ "tsx": "4.23.1",
40
+ "typescript": "6.0.3"
39
41
  },
40
42
  "engines": {
41
- "node": ">=20.19.0"
43
+ "node": ">=22.13.0"
42
44
  },
43
45
  "files": [
44
46
  "dist",
@@ -61,7 +63,7 @@
61
63
  },
62
64
  "scripts": {
63
65
  "prebuild": "pnpm --dir .. build",
64
- "build": "tsup",
66
+ "build": "tsdown",
65
67
  "gate": "tsx src/corpus-replay.mts corpus/finsearch.jsonl --selector",
66
68
  "gate-cli": "tsx src/gate-cli.mts",
67
69
  "run-benchmarks": "tsx src/run-benchmarks-cli.mts",
@@ -69,8 +71,9 @@
69
71
  "terminal-compare": "tsx src/terminal-compare.ts",
70
72
  "test": "node scripts/run-package-tests.mjs",
71
73
  "typecheck:public": "tsc -p tsconfig.public.json",
72
- "verify:package": "node scripts/verify-packed-consumer.mjs",
73
- "verify:package:local-runtime": "node scripts/verify-packed-consumer.mjs --local-runtime",
74
+ "verify:package": "pnpm run verify:package:static && node scripts/verify-packed-consumer.mjs",
75
+ "verify:package:local-runtime": "pnpm run verify:package:static && node scripts/verify-packed-consumer.mjs --local-runtime",
76
+ "verify:package:static": "pnpm run build && publint && attw --pack --profile esm-only .",
74
77
  "verify:pier": "tsx scripts/verify-pier-pair.mts"
75
78
  }
76
79
  }
@@ -52,11 +52,13 @@ async function resolveRuntimePackage(packDir) {
52
52
 
53
53
  try {
54
54
  const packDir = path.join(scratch, 'pack')
55
+ const unpackDir = path.join(scratch, 'unpack')
55
56
  const runtimePackDir = path.join(scratch, 'runtime-pack')
56
57
  const consumerDir = path.join(scratch, 'consumer')
57
58
  const terminalBenchVenv = path.join(scratch, 'terminal-bench-venv')
58
59
  const terminalBenchBinDir = path.join(terminalBenchVenv, 'bin')
59
60
  await mkdir(packDir)
61
+ await mkdir(unpackDir)
60
62
  await mkdir(runtimePackDir)
61
63
  await mkdir(consumerDir)
62
64
  await mkdir(terminalBenchBinDir, { recursive: true })
@@ -115,21 +117,14 @@ writeFileSync(
115
117
  throw new Error(`expected one packed agent-bench tarball, found ${packedFiles.length}`)
116
118
  }
117
119
  const tarball = path.join(packDir, packedFiles[0])
120
+ await run('tar', ['-xzf', tarball, '-C', unpackDir], benchDir)
118
121
  const runtimePackage = await resolveRuntimePackage(runtimePackDir)
119
- const manifest = JSON.parse(await readFile(path.join(benchDir, 'package.json'), 'utf8'))
120
- const devDependencies = manifest.devDependencies
121
- if (
122
- typeof devDependencies?.['@types/node'] !== 'string' ||
123
- typeof devDependencies.typescript !== 'string' ||
124
- typeof devDependencies.tsx !== 'string' ||
125
- !devDependencies['@types/node'] ||
126
- !devDependencies.typescript ||
127
- !devDependencies.tsx
128
- ) {
129
- throw new Error(
130
- 'package verification requires @types/node, typescript, and tsx devDependencies',
131
- )
132
- }
122
+ const packedManifest = JSON.parse(
123
+ await readFile(path.join(unpackDir, 'package', 'package.json'), 'utf8'),
124
+ )
125
+ const nodeTypes = requiredPackedDevelopmentDependency(packedManifest, '@types/node')
126
+ requiredPackedDevelopmentDependency(packedManifest, 'typescript')
127
+ const tsx = requiredPackedDevelopmentDependency(packedManifest, 'tsx')
133
128
  const publicTsconfig = JSON.parse(
134
129
  await readFile(path.join(benchDir, 'tsconfig.public.json'), 'utf8'),
135
130
  )
@@ -150,9 +145,9 @@ writeFileSync(
150
145
  : {}),
151
146
  },
152
147
  devDependencies: {
153
- '@types/node': devDependencies['@types/node'],
148
+ '@types/node': nodeTypes,
154
149
  typescript: TYPESCRIPT_5,
155
- tsx: devDependencies.tsx,
150
+ tsx,
156
151
  },
157
152
  },
158
153
  null,
@@ -292,8 +287,16 @@ for name in sorted(expected):
292
287
  })
293
288
  }
294
289
  console.log(
295
- `packed consumer verified: ${manifest.name}@${manifest.version} with @tangle-network/agent-runtime@${runtimeManifest.version}, TypeScript ${TYPESCRIPT_5} and ${TYPESCRIPT_6}, absolute Terminal-Bench venv; prepared ${prepareProof.executionPlanDigest}`,
290
+ `packed consumer verified: ${packedManifest.name}@${packedManifest.version} with @tangle-network/agent-runtime@${runtimeManifest.version}, TypeScript ${TYPESCRIPT_5} and ${TYPESCRIPT_6}, absolute Terminal-Bench venv; prepared ${prepareProof.executionPlanDigest}`,
296
291
  )
297
292
  } finally {
298
293
  await rm(scratch, { recursive: true, force: true })
299
294
  }
295
+
296
+ function requiredPackedDevelopmentDependency(packageJson, name) {
297
+ const version = packageJson.devDependencies?.[name]
298
+ if (typeof version !== 'string' || version.length === 0 || version.startsWith('catalog:')) {
299
+ throw new Error(`packed consumer requires a resolved ${name} development dependency`)
300
+ }
301
+ return version
302
+ }
@@ -109,6 +109,8 @@ const baseRec = (attempts: AttemptRecord[], over: Partial<RunRecord> = {}): RunR
109
109
  assert.equal(r0?.commitSha, 'abc123')
110
110
  assert.equal(r0?.tokenUsage.input, 100, 'real tokens carried (not zeroed)')
111
111
  assert.equal(r0?.costUsd, 0.01, 'real cost carried')
112
+ assert.deepEqual(r0?.costProvenance, { kind: 'observed', usd: 0.01 }, 'reported cost remains observed')
113
+ assert.equal(r0?.terminalOutcome, 'succeeded', 'failed task quality is not an execution failure')
112
114
  assert.equal(r0?.prompt, 'q0', 'verbatim prompt survives the validator')
113
115
  assert.equal(r0?.completion, 'alpha', 'verbatim completion survives the validator')
114
116
  assert.equal(r0?.outcome.searchScore, 0, 'search split → searchScore from attempt score')
@@ -117,6 +119,17 @@ const baseRec = (attempts: AttemptRecord[], over: Partial<RunRecord> = {}): RunR
117
119
  assert.notEqual(r0?.runId, r1?.runId, 'per-attempt runIds are distinct')
118
120
  }
119
121
 
122
+ // --- attempt error is execution state, not a fabricated zero-quality label ---
123
+ {
124
+ const { records, unmappable } = await benchRecordToCorpusRecords(
125
+ baseRec([{ ...measuredAttempt(0, 'partial output', false), error: 'provider disconnected' }]),
126
+ { commitSha: 'abc123', model: 'gpt-5-2025-08-07' },
127
+ )
128
+ assert.equal(unmappable.length, 0)
129
+ assert.equal(records[0]?.terminalOutcome, 'failed')
130
+ assert.equal(records[0]?.outcome.searchScore, 0, 'task quality remains independently recorded')
131
+ }
132
+
120
133
  // --- unmeasured economics → unmappable, never forged with phantom zeros ---
121
134
  {
122
135
  const bare: AttemptRecord = { round: 0, prompt: 'q', output: 'x', valid: true, eventCount: 0, eventTypes: {} }
package/src/corpus.ts CHANGED
@@ -288,7 +288,11 @@ export async function benchRecordToCorpusRecords(
288
288
  commitSha: opts.commitSha,
289
289
  wallMs: a.wallMs as number,
290
290
  costUsd: a.costUsd as number,
291
+ // Attempt costs are present only when the worker reported them. Missing
292
+ // costs exited above rather than becoming a made-up zero.
293
+ costProvenance: { kind: 'observed', usd: a.costUsd as number },
291
294
  tokenUsage: { input: a.tokensIn as number, output: a.tokensOut as number },
295
+ terminalOutcome: a.error === undefined ? 'succeeded' : 'failed',
292
296
  outcome: {
293
297
  ...(splitTag === 'holdout' ? { holdoutScore: score } : { searchScore: score }),
294
298
  raw: { valid: a.valid === true ? 1 : 0, score },
@@ -85,18 +85,20 @@ test('the Pier result wait does not add time beyond an expired deadline', async
85
85
  await chmod(fakeDocker, 0o700)
86
86
  await writeFile(
87
87
  supervisorPath,
88
- `import { createReadStream } from 'node:fs'
89
- import { writeFileSync } from 'node:fs'
88
+ `import { createReadStream, renameSync, writeFileSync } from 'node:fs'
90
89
  import path from 'node:path'
91
90
  const directory = process.argv[2]
92
91
  process.on('SIGTERM', () => {
93
- writeFileSync(path.join(directory, 'terminal.json'), JSON.stringify({
92
+ const target = path.join(directory, 'terminal.json')
93
+ const temporary = path.join(directory, '.terminal.json.tmp')
94
+ writeFileSync(temporary, JSON.stringify({
94
95
  schemaVersion: 1,
95
96
  kind: 'pier-trial-terminal',
96
97
  status: 'stopped',
97
98
  processExited: true,
98
99
  containersRemoved: true,
99
100
  }))
101
+ renameSync(temporary, target)
100
102
  process.exit(0)
101
103
  })
102
104
  for await (const _chunk of createReadStream('', { fd: 3 })) {}
@@ -156,7 +158,7 @@ test('the supervisor receives only launch data and no inherited evaluator enviro
156
158
  await chmod(fakeDocker, 0o700)
157
159
  await writeFile(
158
160
  supervisorPath,
159
- `import { createReadStream, writeFileSync } from 'node:fs'
161
+ `import { createReadStream, renameSync, writeFileSync } from 'node:fs'
160
162
  import path from 'node:path'
161
163
  const chunks = []
162
164
  for await (const chunk of createReadStream('', { fd: 3 })) chunks.push(Buffer.from(chunk))
@@ -165,7 +167,9 @@ const isolated = process.env.PIER_SUPERVISOR_MODE === 'explicit' &&
165
167
  process.env.PIER_PARENT_SECRET === undefined &&
166
168
  launch.env.PIER_PARENT_SECRET === undefined &&
167
169
  launch.env.PIER_CHILD_SECRET === 'child-only'
168
- writeFileSync(path.join(process.argv[2], 'terminal.json'), JSON.stringify({
170
+ const target = path.join(process.argv[2], 'terminal.json')
171
+ const temporary = path.join(process.argv[2], '.terminal.json.tmp')
172
+ writeFileSync(temporary, JSON.stringify({
169
173
  schemaVersion: 1,
170
174
  kind: 'pier-trial-terminal',
171
175
  status: isolated ? 'completed' : 'failed',
@@ -173,6 +177,7 @@ writeFileSync(path.join(process.argv[2], 'terminal.json'), JSON.stringify({
173
177
  containersRemoved: true,
174
178
  ...(isolated ? {} : { error: 'supervisor inherited evaluator environment' }),
175
179
  }))
180
+ renameSync(temporary, target)
176
181
  `,
177
182
  )
178
183
  const controller = new FilePierCandidateTrialController({
@@ -224,10 +229,12 @@ test('terminal acknowledgements reject unknown fields', async () => {
224
229
  await chmod(fakeDocker, 0o700)
225
230
  await writeFile(
226
231
  supervisorPath,
227
- `import { createReadStream, writeFileSync } from 'node:fs'
232
+ `import { createReadStream, renameSync, writeFileSync } from 'node:fs'
228
233
  import path from 'node:path'
229
234
  for await (const _chunk of createReadStream('', { fd: 3 })) {}
230
- writeFileSync(path.join(process.argv[2], 'terminal.json'), JSON.stringify({
235
+ const target = path.join(process.argv[2], 'terminal.json')
236
+ const temporary = path.join(process.argv[2], '.terminal.json.tmp')
237
+ writeFileSync(temporary, JSON.stringify({
231
238
  schemaVersion: 1,
232
239
  kind: 'pier-trial-terminal',
233
240
  status: 'completed',
@@ -235,6 +242,7 @@ writeFileSync(path.join(process.argv[2], 'terminal.json'), JSON.stringify({
235
242
  containersRemoved: true,
236
243
  containerRemoved: true,
237
244
  }))
245
+ renameSync(temporary, target)
238
246
  `,
239
247
  )
240
248
  const controller = new FilePierCandidateTrialController({
@@ -14,8 +14,8 @@
14
14
  */
15
15
  import { readFileSync, readdirSync } from 'node:fs'
16
16
  import { join } from 'node:path'
17
- import type { AgentProfile } from '@tangle-network/sandbox'
18
- import { defineInlineResource } from '@tangle-network/sandbox'
17
+ import type { AgentProfile } from '@tangle-network/agent-interface'
18
+ import { defineInlineResource } from '@tangle-network/agent-interface'
19
19
 
20
20
  export interface ProfileCoordinate {
21
21
  /** Coordinate id (the COORDINATE= knob value). */
@@ -141,10 +141,11 @@ interface Ctx {
141
141
  stats: BackfillStats
142
142
  }
143
143
 
144
- function baseLine(ctx: Ctx): Pick<RolloutLine, 'schema' | 'run_id' | 'provenance'> {
144
+ function baseLine(ctx: Ctx): Pick<RolloutLine, 'schema' | 'run_id' | 'experiment_id' | 'provenance'> {
145
145
  return {
146
146
  schema: ROLLOUT_SCHEMA,
147
147
  run_id: ctx.runId,
148
+ experiment_id: null,
148
149
  provenance: { captured_at: ctx.capturedAt, capture: 'backfill' },
149
150
  }
150
151
  }
@@ -216,6 +217,7 @@ async function emitCellLines(
216
217
  reward,
217
218
  reward_source: reward === null ? null : OFFICIAL_JUDGE,
218
219
  verdict: judgeVerdict,
220
+ realness_gated: false,
219
221
  metrics: {
220
222
  resolved: artifact?.resolved ?? null,
221
223
  verify_pass: artifact?.verifyPass ?? null,
@@ -335,6 +337,7 @@ function workerLine(
335
337
  reward,
336
338
  reward_source: reward === null ? null : `${OFFICIAL_JUDGE}/inherited`,
337
339
  verdict: null,
340
+ realness_gated: false,
338
341
  metrics: {
339
342
  worker_cwd: cwd,
340
343
  session_agent: session?.agent ?? null,
@@ -504,6 +507,7 @@ async function emitProposerLines(ctx: Ctx, lines: RolloutLine[], entries: Rollou
504
507
  reward,
505
508
  reward_source: reward === null ? null : `${OFFICIAL_JUDGE}/candidate-resolved-fraction`,
506
509
  verdict: null,
510
+ realness_gated: false,
507
511
  metrics: {
508
512
  resolved_count: entry?.outcome.resolvedCount ?? null,
509
513
  instance_count: ctx.instanceCount,
@@ -194,9 +194,12 @@ export function createSettleCapture(opts: SettleCaptureOptions): SettleCapture {
194
194
  const log = opts.log ?? (() => {})
195
195
  const dbPath = opts.opencodeDb ?? DEFAULT_OPENCODE_DB
196
196
 
197
- const base = (capturedAt: string): Pick<RolloutLine, 'schema' | 'run_id'> & { provenance: RolloutLine['provenance'] } => ({
197
+ const base = (
198
+ capturedAt: string,
199
+ ): Pick<RolloutLine, 'schema' | 'run_id' | 'experiment_id'> & { provenance: RolloutLine['provenance'] } => ({
198
200
  schema: ROLLOUT_SCHEMA,
199
201
  run_id: opts.runId,
202
+ experiment_id: null,
200
203
  provenance: { captured_at: capturedAt, capture: 'settle-time' },
201
204
  })
202
205
 
@@ -232,6 +235,7 @@ export function createSettleCapture(opts: SettleCaptureOptions): SettleCapture {
232
235
  reward,
233
236
  reward_source: reward === null ? null : OFFICIAL_JUDGE,
234
237
  verdict: args.judgeVerdict,
238
+ realness_gated: false,
235
239
  metrics: {
236
240
  ...args.metrics,
237
241
  ...(args.splitVisibility !== null ? { split_visibility: args.splitVisibility } : {}),
@@ -311,6 +315,7 @@ export function createSettleCapture(opts: SettleCaptureOptions): SettleCapture {
311
315
  reward: v2.reward,
312
316
  reward_source: v2.reward === null && v2.deliveredMatch !== 'unknown' ? null : WORKER_REWARD_SOURCE_V2,
313
317
  verdict: null,
318
+ realness_gated: false,
314
319
  metrics: {
315
320
  worker_label: worker.label,
316
321
  worker_cwd: worker.cwd,
@@ -400,6 +405,7 @@ export function createSettleCapture(opts: SettleCaptureOptions): SettleCapture {
400
405
  reward,
401
406
  reward_source: PROPOSER_REWARD_SOURCE_V2,
402
407
  verdict: null,
408
+ realness_gated: false,
403
409
  metrics: {
404
410
  resolved_count: args.candResolved,
405
411
  baseline_resolved_count: args.baselineResolved,
@@ -17,7 +17,7 @@
17
17
  * shape — a `transport:'http'` server at the router's `/v1/search/mcp` endpoint,
18
18
  * provider pinned via the `?provider=` query param.
19
19
  */
20
- import type { AgentProfile } from '@tangle-network/sandbox'
20
+ import type { AgentProfile } from '@tangle-network/agent-interface'
21
21
 
22
22
  export type SearchArm = 'native' | 'off' | { provider: string }
23
23
 
@@ -14,7 +14,8 @@
14
14
  *
15
15
  * Run: dotenvx run -f ~/company/devops/secrets/.env.keys -- pnpm exec tsx bench/src/skill-sandbox-smoke.mts
16
16
  */
17
- import { Sandbox, defineInlineResource } from '@tangle-network/sandbox'
17
+ import { defineInlineResource } from '@tangle-network/agent-interface'
18
+ import { Sandbox } from '@tangle-network/sandbox'
18
19
 
19
20
  const must = (k: string): string => {
20
21
  const v = process.env[k]
@@ -233,7 +233,7 @@ export function innerSmokeJudge(): JudgeConfig<SmokeVerdict, GepaSeatScenario> {
233
233
  // ---------------------------------------------------------------------------
234
234
 
235
235
  export const GEPA_PYTHON_INSTALL_HINT =
236
- 'install `agent-eval-rpc==0.126.6`, then install ' +
236
+ 'install `agent-eval-rpc==0.131.0`, then install ' +
237
237
  '`gepa[full] @ git+https://github.com/gepa-ai/gepa.git@f919db0a622e2e9f9204779b81fe00cc1b2d808f`'
238
238
 
239
239
  export type GepaMethodFactory = (
@@ -7,7 +7,8 @@
7
7
  * path improve() rides.
8
8
  */
9
9
 
10
- import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs'
10
+ import { execFileSync } from 'node:child_process'
11
+ import { mkdtempSync, readFileSync } from 'node:fs'
11
12
  import { tmpdir } from 'node:os'
12
13
  import { join } from 'node:path'
13
14
  import { describe, expect, it } from 'vitest'
@@ -22,40 +23,41 @@ import {
22
23
 
23
24
  const ATTRIBUTION = { channel: 'agent', phase: 'search.baseline', model: 'm' }
24
25
 
25
- /** A durable event line in the exact shape cost-ledger.jsonl persists. */
26
- const line = (record: Record<string, unknown>): string =>
27
- `${JSON.stringify({ version: 1, record })}\n`
28
-
29
- /** Write a synthetic ledger: one settled pair + one crash-orphaned pending. */
26
+ /**
27
+ * Write one settled receipt and then terminate a process with a real pending
28
+ * call. The child uses the public ledger API so this fixture cannot shadow its
29
+ * private JSONL event format.
30
+ */
30
31
  function writeCrashedLedger(dir: string): void {
31
- const settledPending = {
32
- status: 'pending',
33
- callId: 'settled-1',
34
- ...ATTRIBUTION,
35
- actor: 'worker:astropy#r0',
36
- timestamp: 1_000,
37
- }
38
- const settledReceipt = {
39
- ...settledPending,
40
- status: 'settled',
41
- inputTokens: 10,
42
- outputTokens: 5,
43
- costUsd: 0.01,
44
- costUnknown: false,
45
- actualCostUsd: 0.01,
46
- }
47
- const orphanPending = {
48
- status: 'pending',
49
- callId: 'orphan-1',
50
- ...ATTRIBUTION,
51
- actor: 'worker:xarray#r0',
52
- timestamp: 2_000,
53
- tags: { cellId: 'pydata__xarray-4687:0' },
54
- }
55
- writeFileSync(
56
- join(dir, 'cost-ledger.jsonl'),
57
- line(settledPending) + line(settledReceipt) + line(orphanPending),
58
- )
32
+ const child = `
33
+ import { createRunCostLedger, fsCampaignStorage } from '@tangle-network/agent-eval/campaign'
34
+ const runDir = process.env.COST_LEDGER_RUN_DIR
35
+ if (typeof runDir !== 'string' || runDir.length === 0) throw new Error('missing COST_LEDGER_RUN_DIR')
36
+ const attribution = { channel: 'agent', phase: 'search.baseline', model: 'm' }
37
+ const ledger = createRunCostLedger({ storage: fsCampaignStorage(), runDir })
38
+ await ledger.runPaidCall({
39
+ ...attribution,
40
+ callId: 'settled-1',
41
+ actor: 'worker:astropy#r0',
42
+ execute: async () => 'settled',
43
+ receipt: () => ({ model: 'm', inputTokens: 10, outputTokens: 5, actualCostUsd: 0.01 }),
44
+ })
45
+ let started
46
+ const pending = new Promise((resolve) => { started = resolve })
47
+ void ledger.runPaidCall({
48
+ ...attribution,
49
+ callId: 'orphan-1',
50
+ actor: 'worker:xarray#r0',
51
+ tags: { cellId: 'pydata__xarray-4687:0' },
52
+ execute: async () => { started(); return await new Promise(() => {}) },
53
+ receipt: () => ({ model: 'm', inputTokens: 0, outputTokens: 0, actualCostUsd: 0 }),
54
+ })
55
+ await pending
56
+ `
57
+ execFileSync(process.execPath, ['--input-type=module', '--eval', child], {
58
+ cwd: process.cwd(),
59
+ env: { ...process.env, COST_LEDGER_RUN_DIR: dir },
60
+ })
59
61
  }
60
62
 
61
63
  const openLedger = (dir: string) =>
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}