@tangle-network/agent-bench 0.1.0 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/HARNESS.md +302 -0
- package/README.md +39 -2
- package/dist/adapters.d.ts +15 -0
- package/dist/adapters.js +43 -0
- package/dist/adapters.js.map +1 -0
- package/dist/benchmarks/_harness.d.ts +125 -0
- package/dist/benchmarks/_harness.js +33 -0
- package/dist/benchmarks/_harness.js.map +1 -0
- package/dist/benchmarks/aec-bench.d.ts +27 -0
- package/dist/benchmarks/aec-bench.js +8 -0
- package/dist/benchmarks/aec-bench.js.map +1 -0
- package/dist/benchmarks/agentbench.d.ts +16 -0
- package/dist/benchmarks/agentbench.js +10 -0
- package/dist/benchmarks/agentbench.js.map +1 -0
- package/dist/benchmarks/appworld.d.ts +37 -0
- package/dist/benchmarks/appworld.js +14 -0
- package/dist/benchmarks/appworld.js.map +1 -0
- package/dist/benchmarks/bfcl.d.ts +18 -0
- package/dist/benchmarks/bfcl.js +10 -0
- package/dist/benchmarks/bfcl.js.map +1 -0
- package/dist/benchmarks/cad-design.d.ts +45 -0
- package/dist/benchmarks/cad-design.js +7 -0
- package/dist/benchmarks/cad-design.js.map +1 -0
- package/dist/benchmarks/cadbench.d.ts +19 -0
- package/dist/benchmarks/cadbench.js +8 -0
- package/dist/benchmarks/cadbench.js.map +1 -0
- package/dist/benchmarks/cadgenbench.d.ts +22 -0
- package/dist/benchmarks/cadgenbench.js +8 -0
- package/dist/benchmarks/cadgenbench.js.map +1 -0
- package/dist/benchmarks/commit0.d.ts +31 -0
- package/dist/benchmarks/commit0.js +10 -0
- package/dist/benchmarks/commit0.js.map +1 -0
- package/dist/benchmarks/crag.d.ts +14 -0
- package/dist/benchmarks/crag.js +9 -0
- package/dist/benchmarks/crag.js.map +1 -0
- package/dist/benchmarks/dabstep.d.ts +18 -0
- package/dist/benchmarks/dabstep.js +10 -0
- package/dist/benchmarks/dabstep.js.map +1 -0
- package/dist/benchmarks/enterpriseops-gym.d.ts +38 -0
- package/dist/benchmarks/enterpriseops-gym.js +10 -0
- package/dist/benchmarks/enterpriseops-gym.js.map +1 -0
- package/dist/benchmarks/finresearchbench.d.ts +15 -0
- package/dist/benchmarks/finresearchbench.js +8 -0
- package/dist/benchmarks/finresearchbench.js.map +1 -0
- package/dist/benchmarks/finsearchcomp.d.ts +49 -0
- package/dist/benchmarks/finsearchcomp.js +7 -0
- package/dist/benchmarks/finsearchcomp.js.map +1 -0
- package/dist/benchmarks/frames.d.ts +59 -0
- package/dist/benchmarks/frames.js +13 -0
- package/dist/benchmarks/frames.js.map +1 -0
- package/dist/benchmarks/hotpotqa.d.ts +48 -0
- package/dist/benchmarks/hotpotqa.js +15 -0
- package/dist/benchmarks/hotpotqa.js.map +1 -0
- package/dist/benchmarks/humaneval.d.ts +53 -0
- package/dist/benchmarks/humaneval.js +15 -0
- package/dist/benchmarks/humaneval.js.map +1 -0
- package/dist/benchmarks/mind2web.d.ts +41 -0
- package/dist/benchmarks/mind2web.js +9 -0
- package/dist/benchmarks/mind2web.js.map +1 -0
- package/dist/benchmarks/nomiracl.d.ts +15 -0
- package/dist/benchmarks/nomiracl.js +9 -0
- package/dist/benchmarks/nomiracl.js.map +1 -0
- package/dist/benchmarks/open-rag-bench.d.ts +14 -0
- package/dist/benchmarks/open-rag-bench.js +9 -0
- package/dist/benchmarks/open-rag-bench.js.map +1 -0
- package/dist/benchmarks/programbench.d.ts +38 -0
- package/dist/benchmarks/programbench.js +10 -0
- package/dist/benchmarks/programbench.js.map +1 -0
- package/dist/benchmarks/rag-shared.d.ts +42 -0
- package/dist/benchmarks/rag-shared.js +39 -0
- package/dist/benchmarks/rag-shared.js.map +1 -0
- package/dist/benchmarks/ragbench.d.ts +16 -0
- package/dist/benchmarks/ragbench.js +9 -0
- package/dist/benchmarks/ragbench.js.map +1 -0
- package/dist/benchmarks/simpleqa.d.ts +64 -0
- package/dist/benchmarks/simpleqa.js +11 -0
- package/dist/benchmarks/simpleqa.js.map +1 -0
- package/dist/benchmarks/swe-bench.d.ts +56 -0
- package/dist/benchmarks/swe-bench.js +14 -0
- package/dist/benchmarks/swe-bench.js.map +1 -0
- package/dist/benchmarks/t2-ragbench.d.ts +14 -0
- package/dist/benchmarks/t2-ragbench.js +9 -0
- package/dist/benchmarks/t2-ragbench.js.map +1 -0
- package/dist/benchmarks/tau-bench-shared.d.ts +26 -0
- package/dist/benchmarks/tau-bench-shared.js +10 -0
- package/dist/benchmarks/tau-bench-shared.js.map +1 -0
- package/dist/benchmarks/tau2-bench.d.ts +7 -0
- package/dist/benchmarks/tau2-bench.js +11 -0
- package/dist/benchmarks/tau2-bench.js.map +1 -0
- package/dist/benchmarks/tau3-banking.d.ts +15 -0
- package/dist/benchmarks/tau3-banking.js +9 -0
- package/dist/benchmarks/tau3-banking.js.map +1 -0
- package/dist/benchmarks/terminal-bench.d.ts +24 -0
- package/dist/benchmarks/terminal-bench.js +8 -0
- package/dist/benchmarks/terminal-bench.js.map +1 -0
- package/dist/benchmarks/toollm.d.ts +16 -0
- package/dist/benchmarks/toollm.js +10 -0
- package/dist/benchmarks/toollm.js.map +1 -0
- package/dist/benchmarks/trata-hedge.d.ts +32 -0
- package/dist/benchmarks/trata-hedge.js +7 -0
- package/dist/benchmarks/trata-hedge.js.map +1 -0
- package/dist/benchmarks/types.d.ts +107 -0
- package/dist/benchmarks/types.js +1 -0
- package/dist/benchmarks/types.js.map +1 -0
- package/dist/benchmarks/webarena-verified.d.ts +16 -0
- package/dist/benchmarks/webarena-verified.js +10 -0
- package/dist/benchmarks/webarena-verified.js.map +1 -0
- package/dist/chunk-2PVVP7GN.js +197 -0
- package/dist/chunk-2PVVP7GN.js.map +1 -0
- package/dist/chunk-2XU6OGEN.js +170 -0
- package/dist/chunk-2XU6OGEN.js.map +1 -0
- package/dist/chunk-53UPUNBZ.js +325 -0
- package/dist/chunk-53UPUNBZ.js.map +1 -0
- package/dist/chunk-5SBJCB6W.js +144 -0
- package/dist/chunk-5SBJCB6W.js.map +1 -0
- package/dist/chunk-7WSD27QQ.js +118 -0
- package/dist/chunk-7WSD27QQ.js.map +1 -0
- package/dist/chunk-C7T7WEK2.js +103 -0
- package/dist/chunk-C7T7WEK2.js.map +1 -0
- package/dist/chunk-CKUVRZ2T.js +251 -0
- package/dist/chunk-CKUVRZ2T.js.map +1 -0
- package/dist/chunk-HBSWHQNJ.js +30 -0
- package/dist/chunk-HBSWHQNJ.js.map +1 -0
- package/dist/chunk-HHXFIHXC.js +116 -0
- package/dist/chunk-HHXFIHXC.js.map +1 -0
- package/dist/chunk-IFAV6KEM.js +276 -0
- package/dist/chunk-IFAV6KEM.js.map +1 -0
- package/dist/chunk-INNOYXCP.js +387 -0
- package/dist/chunk-INNOYXCP.js.map +1 -0
- package/dist/chunk-J3KDJNX2.js +182 -0
- package/dist/chunk-J3KDJNX2.js.map +1 -0
- package/dist/chunk-JRWWGMK7.js +148 -0
- package/dist/chunk-JRWWGMK7.js.map +1 -0
- package/dist/chunk-JTHWEDEW.js +32 -0
- package/dist/chunk-JTHWEDEW.js.map +1 -0
- package/dist/chunk-KDIKRJGB.js +120 -0
- package/dist/chunk-KDIKRJGB.js.map +1 -0
- package/dist/chunk-LRRD7NAG.js +301 -0
- package/dist/chunk-LRRD7NAG.js.map +1 -0
- package/dist/chunk-ODT47UAY.js +221 -0
- package/dist/chunk-ODT47UAY.js.map +1 -0
- package/dist/chunk-PA2ZKHJC.js +230 -0
- package/dist/chunk-PA2ZKHJC.js.map +1 -0
- package/dist/chunk-PPYSEKFM.js +182 -0
- package/dist/chunk-PPYSEKFM.js.map +1 -0
- package/dist/chunk-PUIRNYI7.js +189 -0
- package/dist/chunk-PUIRNYI7.js.map +1 -0
- package/dist/chunk-R36V2VP7.js +169 -0
- package/dist/chunk-R36V2VP7.js.map +1 -0
- package/dist/chunk-R67DFVLO.js +142 -0
- package/dist/chunk-R67DFVLO.js.map +1 -0
- package/dist/chunk-SEVJPLZC.js +260 -0
- package/dist/chunk-SEVJPLZC.js.map +1 -0
- package/dist/chunk-SYDW647C.js +318 -0
- package/dist/chunk-SYDW647C.js.map +1 -0
- package/dist/chunk-TBKU5XQI.js +228 -0
- package/dist/chunk-TBKU5XQI.js.map +1 -0
- package/dist/chunk-TSWPNOYM.js +147 -0
- package/dist/chunk-TSWPNOYM.js.map +1 -0
- package/dist/chunk-UAIOHCUK.js +27 -0
- package/dist/chunk-UAIOHCUK.js.map +1 -0
- package/dist/chunk-UPAMRDX4.js +233 -0
- package/dist/chunk-UPAMRDX4.js.map +1 -0
- package/dist/chunk-VQRS7VUC.js +342 -0
- package/dist/chunk-VQRS7VUC.js.map +1 -0
- package/dist/chunk-X3BTXCJ4.js +262 -0
- package/dist/chunk-X3BTXCJ4.js.map +1 -0
- package/dist/chunk-X5YKXC6V.js +211 -0
- package/dist/chunk-X5YKXC6V.js.map +1 -0
- package/dist/chunk-Y6O2OCUO.js +130 -0
- package/dist/chunk-Y6O2OCUO.js.map +1 -0
- package/dist/chunk-YCGY7UIZ.js +208 -0
- package/dist/chunk-YCGY7UIZ.js.map +1 -0
- package/dist/chunk-Z7ML6L77.js +162 -0
- package/dist/chunk-Z7ML6L77.js.map +1 -0
- package/dist/chunk-ZEWMTR5M.js +136 -0
- package/dist/chunk-ZEWMTR5M.js.map +1 -0
- package/dist/index.d.ts +355 -0
- package/dist/index.js +1908 -0
- package/dist/index.js.map +1 -0
- package/fixtures/aec-bench.json +18 -0
- package/fixtures/agentbench-dbbench.json +22 -0
- package/fixtures/bfcl.json +45 -0
- package/fixtures/commit0.json +72 -0
- package/fixtures/crag.json +10 -0
- package/fixtures/dabstep.json +22 -0
- package/fixtures/enterpriseops-gym.json +103 -0
- package/fixtures/finresearchbench.json +21 -0
- package/fixtures/finsearchcomp.json +66 -0
- package/fixtures/frames.json +26 -0
- package/fixtures/hotpotqa.json +182 -0
- package/fixtures/nomiracl.json +26 -0
- package/fixtures/open-rag-bench.json +16 -0
- package/fixtures/pier-agent/no-model-task/environment/Dockerfile +16 -0
- package/fixtures/pier-agent/no-model-task/environment/seed/src/status.txt +1 -0
- package/fixtures/pier-agent/no-model-task/instruction.md +6 -0
- package/fixtures/pier-agent/no-model-task/pre_artifacts.sh +6 -0
- package/fixtures/pier-agent/no-model-task/task.toml +35 -0
- package/fixtures/pier-agent/no-model-task/tests/Dockerfile +17 -0
- package/fixtures/pier-agent/no-model-task/tests/seed/src/status.txt +1 -0
- package/fixtures/pier-agent/no-model-task/tests/test.sh +19 -0
- package/fixtures/programbench.json +17 -0
- package/fixtures/ragbench.json +21 -0
- package/fixtures/simpleqa.json +121 -0
- package/fixtures/t2-ragbench.json +13 -0
- package/fixtures/tau2-bench.json +16 -0
- package/fixtures/tau3-banking.json +16 -0
- package/fixtures/toollm.json +28 -0
- package/fixtures/webarena-verified.json +20 -0
- package/package.json +60 -20
- package/pier_agents/__init__.py +18 -0
- package/pier_agents/candidate_contract.py +755 -0
- package/pier_agents/process_boundary.py +321 -0
- package/pier_agents/tangle_candidate.py +907 -0
- package/pier_agents/workspace_boundary.py +368 -0
- package/scripts/appworld_driver.py +359 -0
- package/scripts/cadbench_prepare.py +22 -0
- package/scripts/cadgenbench_hard_parts.py +48 -0
- package/scripts/clbench_codebase_judge.py +73 -0
- package/scripts/commit0_judge.py +170 -0
- package/scripts/dabstep_judge.py +42 -0
- package/scripts/enterpriseops_gym_judge.py +281 -0
- package/scripts/programbench_judge.py +120 -0
- package/scripts/render-gate-chart.mjs +176 -0
- package/scripts/run-package-tests.mjs +56 -0
- package/scripts/terminate-pier-trial.mts +66 -0
- package/scripts/trata-hedge/README.md +56 -0
- package/scripts/trata-hedge/run.sh +60 -0
- package/scripts/trata-hedge/solve.py +83 -0
- package/scripts/verify-packed-consumer.mjs +235 -0
- package/scripts/verify-pier-agent.mts +715 -0
- package/scripts/verify-pier-pair.mts +74 -0
- package/scripts/verify-pier-recovery.mts +139 -0
- package/src/adapters.ts +26 -0
- package/src/benchmarks/_harness.test.mts +178 -0
- package/src/benchmarks/_harness.ts +239 -16
- package/src/benchmarks/agentbench.ts +163 -0
- package/src/benchmarks/appworld.test.mts +15 -9
- package/src/benchmarks/bfcl.ts +346 -0
- package/src/benchmarks/crag.ts +137 -0
- package/src/benchmarks/dabstep.test.mts +70 -0
- package/src/benchmarks/dabstep.ts +212 -0
- package/src/benchmarks/external-adapters.test.mts +150 -0
- package/src/benchmarks/finresearchbench.ts +269 -0
- package/src/benchmarks/humaneval.ts +20 -8
- package/src/benchmarks/nomiracl.ts +180 -0
- package/src/benchmarks/open-rag-bench.ts +153 -0
- package/src/benchmarks/rag-benchmarks.test.mts +138 -0
- package/src/benchmarks/rag-shared.ts +327 -0
- package/src/benchmarks/ragbench.ts +171 -0
- package/src/benchmarks/swe-bench.test.mts +61 -0
- package/src/benchmarks/swe-bench.ts +201 -19
- package/src/benchmarks/t2-ragbench.ts +166 -0
- package/src/benchmarks/tau-bench-shared.ts +214 -0
- package/src/benchmarks/tau2-bench.ts +30 -0
- package/src/benchmarks/tau3-banking.ts +29 -0
- package/src/benchmarks/terminal-bench.test.mts +33 -0
- package/src/benchmarks/terminal-bench.ts +23 -8
- package/src/benchmarks/toollm.ts +254 -0
- package/src/benchmarks/types.ts +42 -0
- package/src/benchmarks/webarena-verified.ts +200 -0
- package/src/commit0-prereqs.sh +0 -0
- package/src/coordination-mcp-container-reach.mts +181 -0
- package/src/decoder-live.mts +1 -1
- package/src/examples/README.md +103 -39
- package/src/examples/benchmark-matrix.mts +101 -0
- package/src/examples/lean-proof-gate.README.md +77 -0
- package/src/examples/lean-proof-gate.mts +162 -0
- package/src/examples/lean-verify.ts +95 -0
- package/src/examples/lean.Dockerfile +12 -0
- package/src/examples/math-demo.mts +9 -7
- package/src/examples/strategy-demo.mts +10 -12
- package/src/gate.ts +3 -2
- package/src/hev-eval.mts +69 -0
- package/src/hev-improve.mts +169 -0
- package/src/hev-structural.mts +688 -0
- package/src/index.ts +73 -0
- package/src/mbpp-structural.mts +662 -0
- package/src/pier-agent.test-fixtures.mts +19 -0
- package/src/pier-agent.test.mts +363 -0
- package/src/pier-agent.ts +657 -0
- package/src/pier-result-grader.mjs +30 -0
- package/src/pier-result-grader.test.mts +62 -0
- package/src/pier-result-grader.ts +108 -0
- package/src/pier-task-outcome.test.mts +117 -0
- package/src/pier-task-outcome.ts +240 -0
- package/src/pier-trial-controller.test.mts +412 -0
- package/src/pier-trial-controller.ts +858 -0
- package/src/pier-trial-supervisor.mjs +352 -0
- package/src/resolve-client.ts +25 -2
- package/src/run-benchmarks-cli.mts +72 -0
- package/src/run-benchmarks-report.ts +66 -0
- package/src/run-benchmarks.test.mts +231 -0
- package/src/run-benchmarks.ts +589 -0
- package/src/smoke-structural-rollout.mts +393 -0
- package/src/swe-bench-env.test.ts +207 -0
- package/src/swe-bench-env.ts +554 -0
- package/src/swe-jail.ts +293 -0
- package/src/swe-self-improve.mts +84 -0
- package/src/swe-structural-judge-policy.test.ts +117 -0
- package/src/swe-structural-judge-policy.ts +133 -0
- package/src/swe-structural-policy.test.ts +124 -0
- package/src/swe-structural-policy.ts +132 -0
- package/src/swe-structural-provenance.test.ts +93 -0
- package/src/swe-structural-provenance.ts +138 -0
- package/src/swe-structural.mts +1260 -0
- package/src/swe-temp.ts +14 -0
- package/src/tb-container-executor.mts +234 -0
- package/src/tb-container-executor.test.mts +99 -0
- package/src/tb-supervisor-sidecar.mts +222 -0
- package/src/trata-gepa.mts +1 -1
- package/steerers/eops-itsm-population.json +1 -0
- package/tb_agents/opencode_refine_agent.py +117 -0
- package/tb_agents/opencode_router_agent.py +406 -0
- package/tb_agents/opencode_supervisor_agent.py +239 -0
- package/tb_agents/script_agent.py +66 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline test for the bench unifier: a stub adapter (in-memory tasks + deterministic judge) and a
|
|
3
|
+
* stub shot prove the matrix expansion, the adapter-judged aggregation, the error accounting, and
|
|
4
|
+
* the fail-loud guards — without a model, sandbox, or dataset. Run: `tsx bench/src/run-benchmarks.test.mts`.
|
|
5
|
+
*/
|
|
6
|
+
import assert from 'node:assert/strict'
|
|
7
|
+
import type { BenchmarkAdapter, BenchScore, BenchTask } from './benchmarks/types'
|
|
8
|
+
import { runBenchmarks, type BenchShot } from './run-benchmarks'
|
|
9
|
+
|
|
10
|
+
function stubAdapter(name: string, n: number): BenchmarkAdapter {
|
|
11
|
+
const tasks: BenchTask[] = Array.from({ length: n }, (_, i) => ({
|
|
12
|
+
id: `${name}-${i}`,
|
|
13
|
+
prompt: `solve ${name} ${i}`,
|
|
14
|
+
metadata: { gold: `GOLD-${name}-${i}` },
|
|
15
|
+
}))
|
|
16
|
+
return {
|
|
17
|
+
name,
|
|
18
|
+
preflight: async () => {},
|
|
19
|
+
loadTasks: async (o) => {
|
|
20
|
+
let t = tasks
|
|
21
|
+
if (o?.ids) t = t.filter((x) => o.ids!.includes(x.id))
|
|
22
|
+
if (o?.limit !== undefined) t = t.slice(0, o.limit)
|
|
23
|
+
return t
|
|
24
|
+
},
|
|
25
|
+
judge: async (task, artifact): Promise<BenchScore> => {
|
|
26
|
+
const gold = String(task.metadata?.gold)
|
|
27
|
+
return { resolved: artifact === gold, score: artifact === gold ? 1 : 0 }
|
|
28
|
+
},
|
|
29
|
+
goldArtifact: async (task) => String(task.metadata?.gold),
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const REGISTRY: Record<string, BenchmarkAdapter> = { alpha: stubAdapter('alpha', 4), beta: stubAdapter('beta', 4) }
|
|
34
|
+
const resolveStub = (key: string): BenchmarkAdapter => {
|
|
35
|
+
const a = REGISTRY[key]
|
|
36
|
+
if (!a) throw new Error(`unknown benchmark: ${key}`)
|
|
37
|
+
return a
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** A perfect cell returns each task's gold; a half cell solves even-indexed tasks; a broken cell throws. */
|
|
41
|
+
const shot: BenchShot = async ({ adapter, task, cell }) => {
|
|
42
|
+
const gold = String(task.metadata?.gold)
|
|
43
|
+
if (cell.label === 'broken') throw new Error('harness down')
|
|
44
|
+
if (cell.label === 'perfect') return { artifact: gold, ok: true }
|
|
45
|
+
const idx = Number(task.id.split('-').pop())
|
|
46
|
+
return idx % 2 === 0 ? { artifact: gold, ok: true } : { artifact: 'WRONG', ok: true }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function main(): Promise<void> {
|
|
50
|
+
// Matrix: 2 benchmarks × 3 cells × 4 tasks = 24 shots.
|
|
51
|
+
const report = await runBenchmarks({
|
|
52
|
+
benchmarks: ['alpha', 'beta'],
|
|
53
|
+
cells: [{ label: 'perfect', model: 'm' }, { label: 'half', model: 'm' }, { label: 'broken', model: 'm' }],
|
|
54
|
+
routerBaseUrl: 'x',
|
|
55
|
+
routerKey: 'x',
|
|
56
|
+
runShot: shot,
|
|
57
|
+
resolveAdapter: resolveStub,
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
assert.equal(report.perTask.length, 24, 'matrix expands to benchmarks × cells × tasks')
|
|
61
|
+
assert.equal(report.rows.length, 6, 'one row per (benchmark × cell)')
|
|
62
|
+
|
|
63
|
+
const row = (b: string, c: string) => report.rows.find((r) => r.benchmark === b && r.cell === c)!
|
|
64
|
+
assert.equal(row('alpha', 'perfect').resolveRate, 1, 'perfect cell resolves every task')
|
|
65
|
+
assert.equal(row('alpha', 'half').resolveRate, 0.5, 'half cell resolves the even tasks')
|
|
66
|
+
assert.equal(row('alpha', 'half').meanScore, 0.5, 'mean graded score tracks resolveRate here')
|
|
67
|
+
|
|
68
|
+
const broken = row('alpha', 'broken')
|
|
69
|
+
assert.equal(broken.errored, 4, 'a throwing shot is errored, not scored')
|
|
70
|
+
assert.equal(broken.resolved, 0, 'broken cell resolves nothing')
|
|
71
|
+
assert.equal(broken.resolveRate, 0, 'errored shots leave resolveRate at 0 (denominator floored at 1)')
|
|
72
|
+
|
|
73
|
+
// Leaderboard sort: within a benchmark, descending resolveRate.
|
|
74
|
+
const alpha = report.rows.filter((r) => r.benchmark === 'alpha')
|
|
75
|
+
assert.deepEqual(alpha.map((r) => r.cell), ['perfect', 'half', 'broken'], 'rows sorted by descending resolveRate')
|
|
76
|
+
|
|
77
|
+
// Subset: ids + n restrict the task set.
|
|
78
|
+
const subset = await runBenchmarks({
|
|
79
|
+
benchmarks: ['alpha'],
|
|
80
|
+
cells: [{ label: 'perfect', model: 'm' }],
|
|
81
|
+
routerBaseUrl: 'x', routerKey: 'x', runShot: shot, resolveAdapter: resolveStub,
|
|
82
|
+
ids: ['alpha-0', 'alpha-2'],
|
|
83
|
+
})
|
|
84
|
+
assert.equal(subset.perTask.length, 2, 'ids restrict the task subset')
|
|
85
|
+
|
|
86
|
+
// reps multiply shots per task.
|
|
87
|
+
const repped = await runBenchmarks({
|
|
88
|
+
benchmarks: ['alpha'], cells: [{ label: 'perfect', model: 'm' }],
|
|
89
|
+
routerBaseUrl: 'x', routerKey: 'x', runShot: shot, resolveAdapter: resolveStub, reps: 3, n: 2,
|
|
90
|
+
})
|
|
91
|
+
assert.equal(repped.perTask.length, 6, 'reps × tasks')
|
|
92
|
+
|
|
93
|
+
// Looped cells feed safe failure feedback into the next attempt and stop once the judge passes.
|
|
94
|
+
let prompts: string[] = []
|
|
95
|
+
const retryShot: BenchShot = async ({ task, prompt }) => {
|
|
96
|
+
prompts.push(prompt ?? task.prompt)
|
|
97
|
+
return { artifact: prompts.length === 1 ? 'WRONG' : String(task.metadata?.gold), ok: true }
|
|
98
|
+
}
|
|
99
|
+
const oneShot = await runBenchmarks({
|
|
100
|
+
benchmarks: ['alpha'], cells: [{ label: 'retrying', model: 'm' }],
|
|
101
|
+
routerBaseUrl: 'x', routerKey: 'x', runShot: retryShot, resolveAdapter: resolveStub, n: 1,
|
|
102
|
+
})
|
|
103
|
+
assert.equal(oneShot.rows[0]!.resolveRate, 0, 'without the loop, the first bad attempt fails')
|
|
104
|
+
prompts = []
|
|
105
|
+
const looped = await runBenchmarks({
|
|
106
|
+
benchmarks: ['alpha'], cells: [{ label: 'retrying', model: 'm' }],
|
|
107
|
+
routerBaseUrl: 'x', routerKey: 'x', runShot: retryShot, resolveAdapter: resolveStub, n: 1, loopAttempts: 2,
|
|
108
|
+
})
|
|
109
|
+
assert.equal(looped.rows[0]!.resolveRate, 1, 'with loopAttempts=2, the retry can pass')
|
|
110
|
+
assert.equal(prompts.length, 2, 'loop stops after the passing second attempt')
|
|
111
|
+
assert.match(prompts[1]!, /Previous attempts and safe checker feedback/)
|
|
112
|
+
assert.match(looped.perTask[0]!.detail ?? '', /"mode":"refine-loop"/)
|
|
113
|
+
|
|
114
|
+
// A benchmark's detail may include hidden answer fields; those must never be fed back as hints.
|
|
115
|
+
const leakyGold = 'SECRET-GOLD'
|
|
116
|
+
const leaky: BenchmarkAdapter = {
|
|
117
|
+
name: 'leaky',
|
|
118
|
+
preflight: async () => {},
|
|
119
|
+
loadTasks: async () => [{ id: 'leaky-0', prompt: 'Answer the hidden task.', metadata: { gold: leakyGold } }],
|
|
120
|
+
judge: async (_task, artifact) => ({
|
|
121
|
+
resolved: artifact === leakyGold,
|
|
122
|
+
score: artifact === leakyGold ? 1 : 0,
|
|
123
|
+
detail: JSON.stringify({ bestGold: leakyGold, expectedAnswer: leakyGold, publicHint: 'retry' }),
|
|
124
|
+
}),
|
|
125
|
+
goldArtifact: async () => leakyGold,
|
|
126
|
+
}
|
|
127
|
+
const leakyPrompts: string[] = []
|
|
128
|
+
const leakyShot: BenchShot = async ({ prompt }) => {
|
|
129
|
+
leakyPrompts.push(prompt ?? '')
|
|
130
|
+
return { artifact: leakyPrompts.length === 1 ? 'WRONG' : leakyGold, ok: true }
|
|
131
|
+
}
|
|
132
|
+
await runBenchmarks({
|
|
133
|
+
benchmarks: ['leaky'], cells: [{ label: 'retrying', model: 'm' }],
|
|
134
|
+
routerBaseUrl: 'x', routerKey: 'x', runShot: leakyShot, resolveAdapter: () => leaky, loopAttempts: 2,
|
|
135
|
+
})
|
|
136
|
+
assert.equal(leakyPrompts.length, 2)
|
|
137
|
+
assert.equal(leakyPrompts[1]!.includes(leakyGold), false, 'retry prompt redacts hidden gold fields')
|
|
138
|
+
assert.match(leakyPrompts[1]!, /publicHint/)
|
|
139
|
+
|
|
140
|
+
const runtime = await import('@tangle-network/agent-runtime/loops')
|
|
141
|
+
if (runtime.openSandboxRun.toString().includes('beforeStart')) {
|
|
142
|
+
// The default shot path supports benchmark-owned box setup/extract without real sandbox infra.
|
|
143
|
+
const order: string[] = []
|
|
144
|
+
const fakeClient = {
|
|
145
|
+
async create() {
|
|
146
|
+
return {
|
|
147
|
+
id: 'box-default-shot',
|
|
148
|
+
async exec(command: string, options?: { sessionId?: string }) {
|
|
149
|
+
order.push(`exec:${command}:streams=${order.filter((x) => x.startsWith('stream:')).length}:session=${options?.sessionId ? 'yes' : 'no'}`)
|
|
150
|
+
return { exitCode: 0, stdout: command === 'extract-patch' ? 'PATCH' : '', stderr: '' }
|
|
151
|
+
},
|
|
152
|
+
async *streamPrompt(_prompt: string, options?: { sessionId?: string }) {
|
|
153
|
+
order.push(`stream:session=${options?.sessionId ? 'yes' : 'no'}`)
|
|
154
|
+
yield { type: 'result', data: { finalText: 'fallback text' } }
|
|
155
|
+
},
|
|
156
|
+
async delete() {
|
|
157
|
+
order.push('delete')
|
|
158
|
+
},
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
async criuStatus() {
|
|
162
|
+
return { available: false }
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
const boxAdapter: BenchmarkAdapter = {
|
|
166
|
+
name: 'boxy',
|
|
167
|
+
preflight: async () => {},
|
|
168
|
+
loadTasks: async () => [{ id: 'boxy-0', prompt: 'edit repo', metadata: {} }],
|
|
169
|
+
judge: async (_task, artifact) => ({ resolved: artifact === 'PATCH', score: artifact === 'PATCH' ? 1 : 0 }),
|
|
170
|
+
goldArtifact: async () => 'PATCH',
|
|
171
|
+
boxSetup: () => ({ command: 'setup-repo' }),
|
|
172
|
+
boxExtract: () => ({ command: 'extract-patch' }),
|
|
173
|
+
}
|
|
174
|
+
const boxy = await runBenchmarks({
|
|
175
|
+
benchmarks: ['boxy'],
|
|
176
|
+
cells: [{ label: 'default-shot', model: 'm', backend: 'sandbox' }],
|
|
177
|
+
routerBaseUrl: 'x',
|
|
178
|
+
routerKey: 'x',
|
|
179
|
+
resolveAdapter: () => boxAdapter,
|
|
180
|
+
resolveClient: () => fakeClient as never,
|
|
181
|
+
})
|
|
182
|
+
assert.equal(boxy.rows[0]!.resolveRate, 1, 'boxExtract artifact is judged instead of fallback text')
|
|
183
|
+
assert.deepEqual(
|
|
184
|
+
order.slice(0, 3),
|
|
185
|
+
['exec:setup-repo:streams=0:session=yes', 'stream:session=yes', 'exec:extract-patch:streams=1:session=yes'],
|
|
186
|
+
'setup runs before the prompt stream, extract runs after the prompt stream, both in the same session',
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// An unavailable benchmark (preflight throws) is skipped, not fatal; the sweep still runs the rest.
|
|
191
|
+
const flaky: Record<string, BenchmarkAdapter> = {
|
|
192
|
+
ok: stubAdapter('ok', 2),
|
|
193
|
+
down: { ...stubAdapter('down', 2), preflight: async () => { throw new Error('no docker') } },
|
|
194
|
+
}
|
|
195
|
+
const mixed = await runBenchmarks({
|
|
196
|
+
benchmarks: ['ok', 'down'], cells: [{ label: 'perfect', model: 'm' }],
|
|
197
|
+
routerBaseUrl: 'x', routerKey: 'x', runShot: shot,
|
|
198
|
+
resolveAdapter: (k) => { const a = flaky[k]; if (!a) throw new Error(`unknown: ${k}`); return a },
|
|
199
|
+
})
|
|
200
|
+
assert.equal(mixed.unavailable.length, 1, 'the unavailable benchmark is recorded')
|
|
201
|
+
assert.equal(mixed.unavailable[0]!.benchmark, 'down')
|
|
202
|
+
assert.ok(mixed.rows.every((r) => r.benchmark === 'ok'), 'only the available benchmark produced rows')
|
|
203
|
+
|
|
204
|
+
// Judge self-verification: a miscalibrated judge (rejects its own gold) marks the bench unavailable.
|
|
205
|
+
const miscalibrated: BenchmarkAdapter = { ...stubAdapter('mis', 2), judge: async () => ({ resolved: false, score: 0 }) }
|
|
206
|
+
const guarded = await runBenchmarks({
|
|
207
|
+
benchmarks: ['mis'], cells: [{ label: 'perfect', model: 'm' }],
|
|
208
|
+
routerBaseUrl: 'x', routerKey: 'x', runShot: shot,
|
|
209
|
+
resolveAdapter: () => miscalibrated, verifyJudge: true,
|
|
210
|
+
})
|
|
211
|
+
assert.equal(guarded.unavailable.length, 1, 'a judge that rejects its own gold is caught before spending')
|
|
212
|
+
assert.equal(guarded.perTask.length, 0, 'no shots run against a miscalibrated judge')
|
|
213
|
+
|
|
214
|
+
// Fail-loud guards.
|
|
215
|
+
await assert.rejects(
|
|
216
|
+
runBenchmarks({ benchmarks: [], cells: [{ label: 'x', model: 'm' }], routerBaseUrl: 'x', routerKey: 'x', runShot: shot, resolveAdapter: resolveStub }),
|
|
217
|
+
/no benchmarks/,
|
|
218
|
+
)
|
|
219
|
+
await assert.rejects(
|
|
220
|
+
runBenchmarks({ benchmarks: ['alpha'], cells: [], routerBaseUrl: 'x', routerKey: 'x', runShot: shot, resolveAdapter: resolveStub }),
|
|
221
|
+
/no cells/,
|
|
222
|
+
)
|
|
223
|
+
await assert.rejects(
|
|
224
|
+
runBenchmarks({ benchmarks: ['nope'], cells: [{ label: 'x', model: 'm' }], routerBaseUrl: 'x', routerKey: 'x', runShot: shot, resolveAdapter: resolveStub, verifyJudge: false }),
|
|
225
|
+
/unknown benchmark/,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
console.log('run-benchmarks.test: OK (24-shot matrix, subset, reps, unavailable-skip, judge self-check, guards)')
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
void main()
|