@tangle-network/agent-bench 0.7.1 → 0.8.1

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 (155) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/HARNESS.md +2 -2
  3. package/dist/adapters.js +6 -2
  4. package/dist/adapters.js.map +1 -1
  5. package/dist/benchmarks/appworld.d.ts +61 -2
  6. package/dist/benchmarks/appworld.js +111 -40
  7. package/dist/benchmarks/appworld.js.map +1 -1
  8. package/dist/benchmarks/cadbench.js +1 -1
  9. package/dist/benchmarks/cadgenbench.js +1 -1
  10. package/dist/benchmarks/finresearchbench.js +16 -22
  11. package/dist/benchmarks/finresearchbench.js.map +1 -1
  12. package/dist/benchmarks/finsearchcomp.js +16 -22
  13. package/dist/benchmarks/finsearchcomp.js.map +1 -1
  14. package/dist/benchmarks/frames.js +18 -20
  15. package/dist/benchmarks/frames.js.map +1 -1
  16. package/dist/benchmarks/mcad-bench.d.ts +106 -0
  17. package/dist/benchmarks/mcad-bench.js +569 -0
  18. package/dist/benchmarks/mcad-bench.js.map +1 -0
  19. package/dist/benchmarks/mcad-cq-bench.d.ts +82 -0
  20. package/dist/benchmarks/mcad-cq-bench.js +339 -0
  21. package/dist/benchmarks/mcad-cq-bench.js.map +1 -0
  22. package/dist/benchmarks/mcad-cq-golds.d.ts +36 -0
  23. package/dist/benchmarks/mcad-cq-golds.js +342 -0
  24. package/dist/benchmarks/mcad-cq-golds.js.map +1 -0
  25. package/dist/benchmarks/mcad-golds.d.ts +20 -0
  26. package/dist/benchmarks/mcad-golds.js +318 -0
  27. package/dist/benchmarks/mcad-golds.js.map +1 -0
  28. package/dist/benchmarks/mcad-tasks.d.ts +66 -0
  29. package/dist/benchmarks/mcad-tasks.js +508 -0
  30. package/dist/benchmarks/mcad-tasks.js.map +1 -0
  31. package/dist/benchmarks/simpleqa.js +15 -19
  32. package/dist/benchmarks/simpleqa.js.map +1 -1
  33. package/dist/benchmarks/trata-hedge.js +20 -23
  34. package/dist/benchmarks/trata-hedge.js.map +1 -1
  35. package/dist/{cadbench-BrpwOU6A.js → cadbench-BLSyxR1N.js} +21 -20
  36. package/dist/cadbench-BLSyxR1N.js.map +1 -0
  37. package/dist/{cadgenbench-DF7hYHdl.js → cadgenbench-x2OFkf8y.js} +2 -2
  38. package/dist/cadgenbench-x2OFkf8y.js.map +1 -0
  39. package/dist/index.d.ts +0 -1
  40. package/dist/index.js +10 -9
  41. package/dist/index.js.map +1 -1
  42. package/dist/router-turn-C2wMiDoo.js +31 -0
  43. package/dist/router-turn-C2wMiDoo.js.map +1 -0
  44. package/package.json +7 -7
  45. package/scripts/appworld_driver.py +1 -170
  46. package/scripts/run-package-tests.mjs +56 -36
  47. package/scripts/run-package-tests.test.mjs +33 -0
  48. package/scripts/trata-hedge/README.md +3 -3
  49. package/scripts/trata-hedge/run.sh +6 -2
  50. package/src/adapters.ts +11 -0
  51. package/src/aec-gate.mts +30 -9
  52. package/src/agent-graphs-gen2.mts +523 -0
  53. package/src/agent-graphs-gen3.mts +660 -0
  54. package/src/agent-graphs-improve/offline-seams.mts +128 -0
  55. package/src/agent-graphs-improve.mts +747 -0
  56. package/src/atom-humaneval.mts +76 -55
  57. package/src/atom-mcp-e2e.mts +27 -13
  58. package/src/benchmarks/appworld.test.mts +119 -1
  59. package/src/benchmarks/appworld.ts +156 -33
  60. package/src/benchmarks/cadbench.ts +21 -8
  61. package/src/benchmarks/finresearchbench.ts +20 -16
  62. package/src/benchmarks/finsearchcomp.ts +20 -20
  63. package/src/benchmarks/frames.ts +19 -18
  64. package/src/benchmarks/mcad-bench.test.mts +455 -0
  65. package/src/benchmarks/mcad-bench.ts +561 -0
  66. package/src/benchmarks/mcad-cq-bench.ts +423 -0
  67. package/src/benchmarks/mcad-cq-golds.ts +374 -0
  68. package/src/benchmarks/mcad-cq.test.mts +386 -0
  69. package/src/benchmarks/mcad-golds.ts +359 -0
  70. package/src/benchmarks/mcad-tasks.ts +490 -0
  71. package/src/benchmarks/simpleqa.ts +19 -17
  72. package/src/benchmarks/trata-hedge.ts +26 -18
  73. package/src/browser/ui-reviewer.ts +1 -1
  74. package/src/clbench-context-gate.mts +45 -9
  75. package/src/cloud-loop.mts +24 -6
  76. package/src/commit0-env-run.mts +6 -3
  77. package/src/commit0-env.ts +2 -3
  78. package/src/commit0-gate.mts +53 -24
  79. package/src/corpus.ts +3 -3
  80. package/src/david-attribution.mts +28 -9
  81. package/src/david-goliath.mts +31 -12
  82. package/src/egress-probe.mts +3 -3
  83. package/src/examples/lean-proof-gate.mts +10 -3
  84. package/src/examples/math-demo.mts +10 -3
  85. package/src/examples/strategy-demo.mts +10 -4
  86. package/src/fleet.mts +30 -8
  87. package/src/gate-cli.mts +9 -4
  88. package/src/gate.test.mts +7 -2
  89. package/src/gate.ts +23 -75
  90. package/src/generate-eval/certify.ts +13 -5
  91. package/src/hev-eval.mts +39 -10
  92. package/src/hev-improve.mts +28 -16
  93. package/src/hev-structural.mts +28 -20
  94. package/src/humaneval-gate.mts +24 -8
  95. package/src/humaneval-object-ablation.mts +52 -14
  96. package/src/humaneval-repair-gate.mts +53 -14
  97. package/src/mbpp-structural.mts +28 -20
  98. package/src/mcp-mount-probe.mts +23 -11
  99. package/src/official-optimizer-config.mts +61 -12
  100. package/src/official-optimizer-config.test.mts +72 -3
  101. package/src/quant-arena/profiles/quant-researcher.profile.json +6 -1
  102. package/src/quant-arena/quant-loop.mts +88 -61
  103. package/src/research-shot.ts +21 -11
  104. package/src/resolve-client.ts +6 -8
  105. package/src/rollout-ledger/backfill-swe-arena.test.mts +7 -2
  106. package/src/router-executor.ts +1 -1
  107. package/src/router-turn.ts +135 -0
  108. package/src/run-benchmarks.ts +7 -2
  109. package/src/sandbox-run.ts +23 -41
  110. package/src/search-bench/bridge.ts +66 -8
  111. package/src/search-bench/parametric-check.mts +19 -4
  112. package/src/search-bench/profiles.ts +24 -9
  113. package/src/search-bench/run.mts +3 -4
  114. package/src/smoke-structural-rollout.mts +21 -5
  115. package/src/supervisor-arena.mts +28 -20
  116. package/src/swe-arena/arms.ts +73 -15
  117. package/src/swe-arena/capacity.ts +44 -41
  118. package/src/swe-arena/diagnosis-ensemble.ts +51 -48
  119. package/src/swe-arena/execution.test.mts +12 -12
  120. package/src/swe-arena/gepa-seat.mts +12 -5
  121. package/src/swe-arena/gepa-seat.test.mts +45 -33
  122. package/src/swe-arena/outer-loop.mts +94 -70
  123. package/src/swe-arena/premeasured-from-cells.mts +16 -1
  124. package/src/swe-arena/premeasured-from-cells.test.mts +21 -1
  125. package/src/swe-arena/profiles/deepseek-author.profile.json +12 -0
  126. package/src/swe-arena/profiles/default-author.profile.json +9 -1
  127. package/src/swe-arena/proposer-fanout.mts +52 -99
  128. package/src/swe-arena/proposer-fanout.test.mts +92 -57
  129. package/src/swe-arena/proposer-provenance.mts +1 -1
  130. package/src/swe-code-improve.mts +30 -52
  131. package/src/swe-emit-patch.mts +26 -5
  132. package/src/swe-improve.mts +27 -8
  133. package/src/swe-jail.test.ts +128 -0
  134. package/src/swe-jail.ts +106 -22
  135. package/src/swe-local-proof.mts +27 -5
  136. package/src/swe-repro-calibrate.mts +5 -0
  137. package/src/swe-self-improve.mts +45 -10
  138. package/src/swe-stream.mts +68 -6
  139. package/src/swe-structural.mts +46 -7
  140. package/src/tb-container-executor.mts +38 -6
  141. package/src/tb-container-executor.test.mts +11 -3
  142. package/src/tb-supervisor-sidecar.mts +11 -27
  143. package/src/terminal-compare.ts +38 -18
  144. package/src/trata-gate.mts +26 -26
  145. package/src/trata-gepa.mts +25 -16
  146. package/src/trata-hedge-solve.mts +80 -0
  147. package/src/worker-blender.ts +21 -11
  148. package/src/worker-browser.ts +18 -5
  149. package/src/worker-build123d.ts +17 -8
  150. package/src/worker-cad.ts +31 -12
  151. package/src/worker.ts +1 -1
  152. package/tb_agents/opencode_router_agent.py +84 -42
  153. package/dist/cadbench-BrpwOU6A.js.map +0 -1
  154. package/dist/cadgenbench-DF7hYHdl.js.map +0 -1
  155. package/scripts/trata-hedge/solve.py +0 -83
@@ -1 +0,0 @@
1
- {"version":3,"file":"cadgenbench-DF7hYHdl.js","names":["execFileAsync"],"sources":["../src/worker-build123d.ts","../src/benchmarks/cadgenbench.ts"],"sourcesContent":["/**\n * CADGenBench worker. The deliverable is a STEP B-rep solid (output.step). We\n * author a build123d (Python on the OpenCascade kernel) script via the router,\n * execute it in the CADGenBench venv, and read back the produced output.step —\n * exactly the reference baseline's contract. The artifact returned IS the STEP\n * text, which the CADGenBench geometric scorer grades against the ground truth.\n *\n * The build123d authoring directive is the GEPA-optimizable surface; the\n * build123d API cheat sheet (shipped in the cadgenbench package) is appended as\n * fixed reference context. Requires the CADGenBench venv (CADGENBENCH_VENV) +\n * its clone (CADGENBENCH_DIR for the cheat sheet).\n */\n\nimport { execFile } from 'node:child_process'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\nimport type { Span } from '@tangle-network/agent-eval'\nimport type { BenchTask } from './benchmarks/types'\nimport { DEFAULT_BUILD123D_DIRECTIVE } from './directives'\nimport { runRefineLoop } from './refine-loop'\nimport { routerChatWithUsage } from '@tangle-network/agent-runtime/kernel'\n\nexport { DEFAULT_BUILD123D_DIRECTIVE } from './directives'\n\nconst execFileAsync = promisify(execFile)\n\nexport const CGB_VENV_PY = process.env.CADGENBENCH_VENV ?? '/tmp/cgb-venv/bin/python'\nexport const CGB_DIR = process.env.CADGENBENCH_DIR ?? '/tmp/cadgenbench'\n\nasync function runLocal(cmd: string, args: string[], cwd: string, timeoutMs = 120_000): Promise<{ code: number; stdout: string; stderr: string }> {\n try {\n const { stdout, stderr } = await execFileAsync(cmd, args, { cwd, maxBuffer: 1 << 26, timeout: timeoutMs })\n return { code: 0, stdout, stderr }\n } catch (err) {\n const e = err as { code?: number; stdout?: string; stderr?: string; message?: string }\n return { code: typeof e.code === 'number' ? e.code : 1, stdout: e.stdout ?? '', stderr: e.stderr ?? e.message ?? String(err) }\n }\n}\n\nfunction extractPy(text: string): string {\n const fence = /```(?:python|py)?\\s*\\n([\\s\\S]*?)```/i.exec(text)\n return (fence ? fence[1] : text).trim()\n}\n\nlet _cheat: string | null = null\nfunction cheatSheet(): string {\n if (_cheat != null) return _cheat\n const p = join(CGB_DIR, 'src/cadgenbench/baseline/build123d_cheat_sheet.md')\n _cheat = existsSync(p) ? readFileSync(p, 'utf8').slice(0, 12000) : ''\n return _cheat\n}\n\nexport interface Build123dConfig {\n routerBaseUrl: string\n routerKey: string\n model: string\n rounds?: number\n /** The build123d authoring directive — the GEPA-optimizable surface. */\n directive?: string\n}\n\nexport interface Build123dShot {\n /** The produced STEP text (the artifact the CADGenBench scorer grades). */\n artifact: string\n /** The Python source the agent wrote. */\n source: string\n trace: Span[]\n usage: { input: number; output: number }\n ok: boolean\n built: boolean\n detail?: string\n}\n\n/** Author a build123d script via the router, execute it in the CADGenBench venv,\n * read back output.step. Refine on execution error / missing STEP. */\nexport async function solveBuild123dLocal(task: BenchTask, cfg: Build123dConfig): Promise<Build123dShot> {\n const rounds = Math.max(1, cfg.rounds ?? 2)\n const directive = cfg.directive ?? DEFAULT_BUILD123D_DIRECTIVE\n const sys = `${directive}\\n\\nbuild123d API reference:\\n${cheatSheet()}`\n const trace: Span[] = []\n const runId = `cadgenbench-${task.id}`\n let ts = Date.now()\n const tick = () => (ts += 1)\n const usage = { input: 0, output: 0 }\n // Carried across rounds in closures (the round Artifact is the Python source; the\n // STEP text + built flag + lastErr persist outside the loop). usage is REAL.\n let step = ''\n let built = false\n let lastErr = ''\n\n trace.push({ spanId: 's-brief', runId, kind: 'llm', name: 'brief', model: cfg.model, messages: [{ role: 'user', content: task.prompt }], startedAt: tick(), endedAt: tick(), status: 'ok' } as Span)\n\n // Migrated onto runRefineLoop: the mkdtemp scratch dir is the Ctx; built (STEP\n // produced) is the early-stop, modeled as a judge so default-decide stops the\n // loop. The round-2+ steer carries lastErr + the prior source verbatim.\n const res = await runRefineLoop<string, string>({\n rounds,\n setup: () => mkdtemp(join(tmpdir(), 'b123d-')),\n prompt: (round, history) =>\n round === 1\n ? task.prompt\n : `Your previous build123d script failed:\\n${lastErr}\\n\\nPrevious script:\\n${history[history.length - 1]?.artifact ?? ''}\\n\\nFix it so it runs in python and writes a valid output.step. Brief:\\n${task.prompt}`,\n runShot: async (user, round, dir) => {\n const scriptPath = join(dir, 'build.py')\n const stepPath = join(dir, 'output.step')\n const { content, usage: u } = await routerChatWithUsage(cfg, [\n { role: 'system', content: sys },\n { role: 'user', content: user },\n ])\n if (u) {\n usage.input += u.input\n usage.output += u.output\n }\n const source = extractPy(content)\n trace.push({ spanId: `s-author-${round}`, runId, kind: 'llm', name: `author r${round}`, model: cfg.model, messages: [{ role: 'user', content: round === 1 ? task.prompt : 'refine' }], output: content.slice(0, 600), startedAt: tick(), endedAt: tick(), status: 'ok' } as Span)\n trace.push({ spanId: `s-write-${round}`, runId, kind: 'tool', name: 'write_file', toolName: 'create_file', args: { path: 'build.py', content: source }, startedAt: tick(), endedAt: tick(), status: 'ok' } as Span)\n\n await writeFile(scriptPath, source)\n const run = await runLocal(CGB_VENV_PY, [scriptPath], dir)\n const got = existsSync(stepPath) ? await readFile(stepPath, 'utf8').catch(() => '') : ''\n built = got.includes('ISO-10303-21') && got.length > 200\n lastErr = built ? '' : `${run.stdout}\\n${run.stderr}`.trim().slice(-800) || 'no output.step written'\n if (built) step = got\n trace.push({ spanId: `s-exec-${round}`, runId, kind: 'tool', name: `build123d r${round}`, toolName: 'shell.exec', args: 'python build.py', result: (built ? 'wrote output.step' : lastErr).slice(0, 1500), startedAt: tick(), endedAt: tick(), status: built ? 'ok' : 'error', error: built ? undefined : `exit ${run.code}` } as Span)\n return { artifact: source }\n },\n judge: async () => ({ valid: built }),\n teardown: (dir) => rm(dir, { recursive: true, force: true }).then(() => {}, () => {}),\n })\n\n return {\n artifact: step,\n source: res.final.artifact,\n trace,\n usage,\n ok: res.final.artifact.trim().length > 0,\n built,\n detail: built ? 'exported output.step' : `did not produce a STEP in ${rounds} rounds${lastErr ? `; last: ${lastErr.slice(0, 140)}` : ''}`,\n }\n}\n","/**\n * CADGenBench adapter (huggingface/cadgenbench, Apache-2.0). Task = a part\n * description → a STEP B-rep solid (output.step). Score = the benchmark's OWN\n * deterministic geometric metric (cad_score): validity gate → PCA/ICP align to\n * the ground truth → point-cloud F1 + volume IoU + edge F1 + topology match.\n * NOT an LLM judge, NOT self-defined checks — the published CAD kernel decides.\n *\n * The official task set (private GT, server-side graded) isn't released yet, so\n * tasks here are seeded from the repo's dimension-named geometry fixtures (real\n * GT STEPs scored by the real scorer). When CADGENBENCH_DATA_DIR is set, swap\n * loadTasks to read the published fixtures' description.yaml + ground_truth.step.\n *\n * Requires the CADGenBench venv (CADGENBENCH_VENV) + clone (CADGENBENCH_DIR) +\n * xvfb (the scorer's alignment renders need a display).\n */\n\nimport { execFile } from 'node:child_process'\nimport { mkdtemp, rm, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\nimport type { BenchScore, BenchTask, BenchmarkAdapter, LoadOptions } from './types'\nimport { CGB_DIR, CGB_VENV_PY } from '../worker-build123d'\n\nconst execFileAsync = promisify(execFile)\n\n/** Self-contained scorer wrapper (written to a temp file, run in the venv).\n * Scores a candidate STEP against a ground-truth STEP via the benchmark's own\n * evaluate_result, printing the cad_score line. */\nconst SCORE_PY = `\nimport sys, json, tempfile, shutil\nfrom pathlib import Path\nfrom cadgenbench.eval.evaluate import evaluate_result\ncand, gt = Path(sys.argv[1]), Path(sys.argv[2])\nwith tempfile.TemporaryDirectory() as rd, tempfile.TemporaryDirectory() as gd:\n rd, gd = Path(rd), Path(gd)\n (rd / 'result.json').write_text('{}')\n shutil.copy(gt, gd / 'ground_truth.step')\n try:\n evaluate_result(rd, gd, candidate_step=cand)\n d = json.loads((rd / 'result.json').read_text())\n print('CGB_SCORE ' + json.dumps({'cad_score': d.get('cad_score', 0.0), 'status': d.get('status', 'unknown')}))\n except Exception as e:\n print('CGB_SCORE ' + json.dumps({'cad_score': 0.0, 'status': 'error', 'error': str(e)[:200]}))\n`.trim()\n\ninterface CgbMeta {\n gtStep: string\n resolveThreshold: number\n}\n\n/** Fixture-seeded tasks (real GT STEPs from the repo, dim-named so the spec is\n * exact). Replaced by the published dataset when CADGENBENCH_DATA_DIR is set. */\nfunction fixtureTasks(): Array<{ id: string; prompt: string; gtStep: string }> {\n const g = join(CGB_DIR, 'tests/fixtures/geometry')\n return [\n { id: 'box-10x20x30', prompt: 'A rectangular solid box, 10 units wide (X), 20 units deep (Y), and 30 units tall (Z).', gtStep: join(g, 'box_10_20_30.step') },\n { id: 'cube-10', prompt: 'A cube, 10 units on every side.', gtStep: join(g, 'box_10_10_10.step') },\n { id: 'sphere-10', prompt: 'A sphere of radius 10 units, centered at the origin.', gtStep: join(g, 'sphere_10.step') },\n ]\n}\n\nexport function createCadGenBenchAdapter(): BenchmarkAdapter {\n return {\n name: 'cadgenbench',\n\n async preflight() {\n const r = await execFileAsync(CGB_VENV_PY, ['-c', 'import cadgenbench.eval.evaluate, build123d, trimesh, manifold3d; print(\"ok\")'], { timeout: 60_000 }).catch(\n (e) => ({ stdout: '', stderr: e instanceof Error ? e.message : String(e) }),\n )\n if (!/ok/.test(r.stdout)) {\n throw new Error(\n `cadgenbench preflight failed (venv=${CGB_VENV_PY}): ${r.stderr.slice(0, 200)}\\n` +\n `Fix: git clone https://github.com/huggingface/cadgenbench ${CGB_DIR}; python3 -m venv $CADGENBENCH_VENV; $CADGENBENCH_VENV/bin/pip install -e ${CGB_DIR}`,\n )\n }\n },\n\n async loadTasks(opts: LoadOptions = {}) {\n // CGB_HARD_DIR (a dir with tasks.json = [{id,prompt,gtStep}]) overrides the\n // trivial fixture primitives with hard multi-feature parts (real headroom).\n let tasks = fixtureTasks()\n const hard = process.env.CGB_HARD_DIR\n if (hard) {\n const { readFile } = await import('node:fs/promises')\n tasks = JSON.parse(await readFile(join(hard, 'tasks.json'), 'utf8')) as Array<{ id: string; prompt: string; gtStep: string }>\n }\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 const meta = (gtStep: string): CgbMeta => ({ gtStep, resolveThreshold: Number(process.env.CGB_RESOLVE_THRESHOLD ?? 0.9) })\n return tasks.map((t): BenchTask => ({ id: t.id, prompt: t.prompt, metadata: meta(t.gtStep) as unknown as Record<string, unknown> }))\n },\n\n async goldArtifact() {\n return undefined // GT is a STEP file scored by the kernel, not a returnable artifact\n },\n\n async judge(task: BenchTask, artifact: string): Promise<BenchScore> {\n const { gtStep, resolveThreshold } = task.metadata as unknown as CgbMeta\n if (!artifact.includes('ISO-10303-21')) return { resolved: false, score: 0, detail: 'artifact is not a STEP file' }\n const dir = await mkdtemp(join(tmpdir(), 'cgb-judge-'))\n const cand = join(dir, 'candidate.step')\n const scorer = join(dir, 'score.py')\n try {\n await writeFile(cand, artifact)\n await writeFile(scorer, SCORE_PY)\n // xvfb: the scorer's alignment step renders; needs a display.\n const r = await execFileAsync('xvfb-run', ['-a', CGB_VENV_PY, scorer, cand, gtStep], { maxBuffer: 1 << 26, timeout: 180_000 }).catch(\n (e) => ({ stdout: (e as { stdout?: string }).stdout ?? '', stderr: e instanceof Error ? e.message : String(e) }),\n )\n const m = /CGB_SCORE (\\{.*\\})/.exec(r.stdout)\n if (!m) return { resolved: false, score: 0, detail: `scorer produced no verdict: ${(r.stderr || r.stdout).slice(0, 160)}` }\n const v = JSON.parse(m[1]) as { cad_score: number; status: string; error?: string }\n const score = typeof v.cad_score === 'number' ? v.cad_score : 0\n return { resolved: score >= resolveThreshold, score, detail: `cad_score=${score.toFixed(3)} status=${v.status}${v.error ? ` (${v.error})` : ''}` }\n } finally {\n await rm(dir, { recursive: true, force: true }).catch(() => {})\n }\n },\n }\n}\n"],"mappings":"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"}
@@ -1,83 +0,0 @@
1
- """trata-hedge-bench solver — our system's analyst, graded by THEIR Gemini judge.
2
-
3
- Reads a task's instruction.md + data corpus, writes a cited analysis to answer.txt.
4
- The corpus is large (~5MB/task), so a single-shot router call is a LOWER-BOUND
5
- baseline (it sees only what fits in context) — the bench is built for agentic
6
- exploration, which our sandbox runtime provides (see README; pending sandbox health).
7
-
8
- Notes learned the hard way:
9
- - router.tangle.tools is behind Cloudflare bot-fight: a default Python-urllib
10
- User-Agent gets 403 (CF 1010) on large bodies → send a browser UA.
11
- - gpt-4.1 is NOT keyed for direct router calls (403); gpt-4o / claude-sonnet-4-6 /
12
- gpt-4o-mini are. Very large bodies (~350KB) can 503 — keep DATA_BUDGET in range.
13
-
14
- WORKER_MODEL=gpt-4o DATA_BUDGET=160000 python3 solve.py <env-dir> <out.txt>
15
- """
16
- import json
17
- import os
18
- import sys
19
- import urllib.request
20
- from pathlib import Path
21
-
22
- env = Path(sys.argv[1])
23
- out = sys.argv[2] if len(sys.argv) > 2 else "/tmp/thb-answer.txt"
24
- model = os.environ.get("WORKER_MODEL", "gpt-4o")
25
- budget = int(os.environ.get("DATA_BUDGET", "160000"))
26
- instruction = (env / "instruction.md").read_text()
27
- data_dir = env / "environment" / "data"
28
-
29
-
30
- def rank(p: Path) -> int:
31
- s = str(p)
32
- return (0 if "earnings_call" in s else 1 if "financials" in s else 2 if "company_profiles" in s
33
- else 3 if "press_releases" in s else 4)
34
-
35
-
36
- files = sorted((p for p in data_dir.rglob("*") if p.is_file()), key=rank)
37
- blocks, used, cited = [], 0, []
38
- for p in files:
39
- rel = p.relative_to(data_dir)
40
- try:
41
- c = p.read_text(errors="replace")
42
- except Exception:
43
- continue
44
- if used + len(c) > budget:
45
- continue
46
- used += len(c)
47
- cited.append(str(rel))
48
- blocks.append(f"\n=== FILE: data/{rel} ===\n{c}")
49
- print(f"[solve] {len(cited)}/{len(files)} files in context ({used} chars)", file=sys.stderr)
50
-
51
- prompt = (
52
- instruction
53
- + "\n\n--- AVAILABLE DATA (cite files by their `data/<path>` name inline) ---\n"
54
- + "".join(blocks)
55
- + "\n\n--- END DATA ---\nWrite ONLY the full analysis (no preamble). Inline-cite every claim with its `data/<path>`."
56
- )
57
-
58
- key = os.environ["TANGLE_API_KEY"]
59
- base = os.environ.get("ROUTER_BASE", "https://router.tangle.tools/v1")
60
- body = json.dumps({
61
- "model": model,
62
- "messages": [{"role": "user", "content": prompt}],
63
- "temperature": float(os.environ.get("TEMPERATURE", "0.5")),
64
- "max_tokens": int(os.environ.get("MAX_TOKENS", "6000")),
65
- }).encode()
66
- req = urllib.request.Request(
67
- f"{base}/chat/completions", data=body,
68
- headers={
69
- "Authorization": f"Bearer {key}",
70
- "Content-Type": "application/json",
71
- # browser UA: router is behind Cloudflare bot-fight, default urllib UA → 403 on big bodies
72
- "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
73
- },
74
- )
75
- try:
76
- with urllib.request.urlopen(req, timeout=300) as r:
77
- resp = json.load(r)
78
- except urllib.error.HTTPError as e:
79
- print(f"[solve] HTTP {e.code}: {e.read().decode(errors='replace')[:400]}", file=sys.stderr)
80
- raise
81
- answer = resp["choices"][0]["message"]["content"]
82
- Path(out).write_text(answer)
83
- print(f"[solve] wrote {len(answer)} chars -> {out} (model={model})", file=sys.stderr)