@tangle-network/agent-bench 0.3.7 → 0.4.0
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 +11 -0
- package/HARNESS.md +43 -0
- package/README.md +7 -0
- package/dist/adapters.js +23 -23
- package/dist/benchmarks/_harness.d.ts +1 -1
- package/dist/benchmarks/_harness.js +1 -1
- package/dist/benchmarks/aec-bench.js +2 -2
- package/dist/benchmarks/agentbench.js +2 -2
- package/dist/benchmarks/appworld.js +2 -2
- package/dist/benchmarks/bfcl.js +2 -2
- package/dist/benchmarks/commit0.js +2 -2
- package/dist/benchmarks/crag.js +2 -2
- package/dist/benchmarks/dabstep.js +2 -2
- package/dist/benchmarks/enterpriseops-gym.js +2 -2
- package/dist/benchmarks/finresearchbench.js +2 -2
- package/dist/benchmarks/nomiracl.js +2 -2
- package/dist/benchmarks/open-rag-bench.js +2 -2
- package/dist/benchmarks/programbench.js +2 -2
- package/dist/benchmarks/ragbench.js +2 -2
- package/dist/benchmarks/swe-bench.js +2 -2
- package/dist/benchmarks/t2-ragbench.js +2 -2
- package/dist/benchmarks/tau-bench-shared.js +2 -2
- package/dist/benchmarks/tau2-bench.js +3 -3
- package/dist/benchmarks/tau3-banking.js +3 -3
- package/dist/benchmarks/terminal-bench.js +2 -2
- package/dist/benchmarks/toollm.js +2 -2
- package/dist/benchmarks/webarena-verified.js +2 -2
- package/dist/{chunk-CKUVRZ2T.js → chunk-3U5TXJZS.js} +2 -2
- package/dist/{chunk-YCGY7UIZ.js → chunk-7GRVHU22.js} +2 -2
- package/dist/{chunk-Z7ML6L77.js → chunk-HWST3SED.js} +2 -2
- package/dist/{chunk-SYDW647C.js → chunk-IA2FBTWC.js} +2 -2
- package/dist/{chunk-R67DFVLO.js → chunk-IFVINJ4B.js} +2 -2
- package/dist/{chunk-R36V2VP7.js → chunk-IZ5M6OAC.js} +2 -2
- package/dist/{chunk-ODT47UAY.js → chunk-K3BQGZCT.js} +2 -2
- package/dist/{chunk-IFAV6KEM.js → chunk-KP5KD6EN.js} +2 -2
- package/dist/{chunk-ZEWMTR5M.js → chunk-MQMRLGOG.js} +2 -2
- package/dist/{chunk-TSWPNOYM.js → chunk-NQG5XDSB.js} +2 -2
- package/dist/{chunk-7WSD27QQ.js → chunk-PB64GYIG.js} +2 -2
- package/dist/{chunk-HBSWHQNJ.js → chunk-RCYQEFNX.js} +3 -3
- package/dist/{chunk-J3KDJNX2.js → chunk-RH5F53JT.js} +2 -2
- package/dist/{chunk-UAIOHCUK.js → chunk-SFLA7OH3.js} +3 -3
- package/dist/{chunk-Y6O2OCUO.js → chunk-SHM6MRRF.js} +2 -2
- package/dist/{chunk-KDIKRJGB.js → chunk-SHYIRB7I.js} +2 -2
- package/dist/{chunk-HHXFIHXC.js → chunk-SVR2LKYI.js} +2 -2
- package/dist/{chunk-PWQVGAJB.js → chunk-V7AEBY6U.js} +21 -21
- package/dist/{chunk-LRRD7NAG.js → chunk-WSKWVEQB.js} +18 -2
- package/dist/chunk-WSKWVEQB.js.map +1 -0
- package/dist/{chunk-2PVVP7GN.js → chunk-XKEFIFIC.js} +2 -2
- package/dist/{chunk-JRWWGMK7.js → chunk-XYA4XSNU.js} +2 -2
- package/dist/{chunk-X5YKXC6V.js → chunk-YSMEKBTD.js} +2 -2
- package/dist/{chunk-2XU6OGEN.js → chunk-Z4TZ76N7.js} +2 -2
- package/dist/index.js +23 -23
- package/package.json +5 -5
- package/scripts/trata-hedge/README.md +6 -5
- package/scripts/verify-packed-consumer.mjs +1 -1
- package/src/benchmarks/_harness.ts +20 -2
- package/src/benchmarks/humaneval.test.mts +2 -2
- package/src/gate.ts +1 -1
- package/src/hev-eval.mts +5 -2
- package/src/hev-improve.mts +118 -73
- package/src/official-optimizer-config.mts +89 -0
- package/src/official-optimizer-config.test.mts +88 -0
- package/src/profiles.ts +2 -2
- package/src/quant-arena/README.md +144 -0
- package/src/quant-arena/backtest.test.mts +135 -0
- package/src/quant-arena/backtest.ts +218 -0
- package/src/quant-arena/data.test.mts +44 -0
- package/src/quant-arena/data.ts +141 -0
- package/src/quant-arena/driver.test.mts +253 -0
- package/src/quant-arena/driver.ts +219 -0
- package/src/quant-arena/fixtures/data/PROVENANCE.md +26 -0
- package/src/quant-arena/fixtures/data/holdout/IDX.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S01.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S02.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S03.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S04.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S05.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S06.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S07.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S08.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S09.csv +523 -0
- package/src/quant-arena/fixtures/data/holdout/S10.csv +523 -0
- package/src/quant-arena/fixtures/data/insample/IDX.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S01.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S02.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S03.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S04.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S05.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S06.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S07.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S08.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S09.csv +2087 -0
- package/src/quant-arena/fixtures/data/insample/S10.csv +2087 -0
- package/src/quant-arena/fixtures/demo-campaign/cost-ledger.jsonl +16 -0
- package/src/quant-arena/fixtures/demo-campaign/notebook.jsonl +5 -0
- package/src/quant-arena/fixtures/demo-campaign/rollout-manifest.json +171 -0
- package/src/quant-arena/fixtures/demo-campaign/strategies/cand-001-default-author/strategy.ts +119 -0
- package/src/quant-arena/fixtures/demo-campaign/strategies/cand-002-default-author/strategy.ts +119 -0
- package/src/quant-arena/fixtures/demo-campaign/strategies/cand-003-quant-researcher/strategy.ts +105 -0
- package/src/quant-arena/fixtures/demo-campaign/strategies/cand-004-quant-researcher/strategy.ts +102 -0
- package/src/quant-arena/fixtures/demo-campaign-v2/cost-ledger.jsonl +4 -0
- package/src/quant-arena/fixtures/demo-campaign-v2/notebook.jsonl +2 -0
- package/src/quant-arena/fixtures/demo-campaign-v2/rollout-manifest.json +84 -0
- package/src/quant-arena/fixtures/demo-campaign-v2/strategies/cand-001-quant-researcher/strategy.ts +117 -0
- package/src/quant-arena/holdout-certify.mts +206 -0
- package/src/quant-arena/holdout-certify.test.mts +82 -0
- package/src/quant-arena/leak-audit.test.mts +79 -0
- package/src/quant-arena/leak-audit.ts +95 -0
- package/src/quant-arena/make-fixtures.mts +161 -0
- package/src/quant-arena/multiplicity.test.mts +68 -0
- package/src/quant-arena/multiplicity.ts +87 -0
- package/src/quant-arena/nautilus-certify.ts +31 -0
- package/src/quant-arena/oms.ts +90 -0
- package/src/quant-arena/profiles/quant-researcher.profile.json +7 -0
- package/src/quant-arena/python/pyproject.toml +8 -0
- package/src/quant-arena/python/uv.lock +1297 -0
- package/src/quant-arena/python/vbt-worker.py +192 -0
- package/src/quant-arena/quant-loop.mts +813 -0
- package/src/quant-arena/quant-loop.test.mts +75 -0
- package/src/quant-arena/strategies/buy-hold-index/strategy.ts +11 -0
- package/src/quant-arena/strategies/equal-weight/strategy.ts +20 -0
- package/src/quant-arena/strategies/sma-crossover/strategy.ts +42 -0
- package/src/quant-arena/types.ts +133 -0
- package/src/quant-arena/vbt-client.ts +321 -0
- package/src/quant-arena/vbt-parity.test.mts +183 -0
- package/src/quant-arena/windows.test.mts +45 -0
- package/src/quant-arena/windows.ts +54 -0
- package/src/rollout-ledger/backfill-swe-arena.mts +606 -0
- package/src/rollout-ledger/backfill-swe-arena.test.mts +342 -0
- package/src/rollout-ledger/settle-capture.mts +442 -0
- package/src/rollout-ledger/settle-capture.test.mts +270 -0
- package/src/smoke-structural-rollout.mts +15 -9
- package/src/swe-arena/activation.mts +225 -0
- package/src/swe-arena/activation.test.mts +300 -0
- package/src/swe-arena/arms.ts +30 -14
- package/src/swe-arena/briefing.mts +217 -0
- package/src/swe-arena/briefing.test.mts +178 -0
- package/src/swe-arena/calibrate.ts +102 -1
- package/src/swe-arena/cell-evidence.mts +41 -9
- package/src/swe-arena/factory-command-container.ts +284 -0
- package/src/swe-arena/factory-judge-child.mts +228 -0
- package/src/swe-arena/factory.test.mts +643 -0
- package/src/swe-arena/fixtures/factory/agent-eval-309/calibration.md +51 -0
- package/src/swe-arena/fixtures/factory/agent-eval-309/manifest.json +29 -0
- package/src/swe-arena/fixtures/factory/agent-eval-309/spec.md +64 -0
- package/src/swe-arena/fixtures/factory/agent-runtime-232/calibration.md +48 -0
- package/src/swe-arena/fixtures/factory/agent-runtime-232/manifest.json +29 -0
- package/src/swe-arena/fixtures/factory/agent-runtime-232/spec.md +48 -0
- package/src/swe-arena/fixtures/factory/loops-28/calibration.md +47 -0
- package/src/swe-arena/fixtures/factory/loops-28/manifest.json +30 -0
- package/src/swe-arena/fixtures/factory/loops-28/spec.md +50 -0
- package/src/swe-arena/fixtures/run-report/README.md +43 -0
- package/src/swe-arena/fixtures/run-report/factory-agent-eval-309-FSUP0.json +173 -0
- package/src/swe-arena/fixtures/run-report/factory-agent-eval-309-FSUP0.md +100 -0
- package/src/swe-arena/fixtures/run-report/gen3-rollup.json +551 -0
- package/src/swe-arena/fixtures/run-report/gen3-rollup.md +64 -0
- package/src/swe-arena/fixtures.ts +135 -2
- package/src/swe-arena/gepa-seat.mts +877 -0
- package/src/swe-arena/gepa-seat.test.mts +1059 -0
- package/src/swe-arena/implementation-ref.test.mts +64 -0
- package/src/swe-arena/implementation-ref.ts +62 -0
- package/src/swe-arena/ledger-orphans.mts +77 -0
- package/src/swe-arena/ledger-orphans.test.mts +147 -0
- package/src/swe-arena/outer-loop.mts +710 -33
- package/src/swe-arena/premeasured-from-cells.mts +281 -0
- package/src/swe-arena/premeasured-from-cells.test.mts +180 -0
- package/src/swe-arena/proposer-fanout.mts +327 -31
- package/src/swe-arena/proposer-fanout.test.mts +246 -0
- package/src/swe-arena/proposer-provenance.mts +172 -0
- package/src/swe-arena/proposer-provenance.test.mts +106 -0
- package/src/swe-arena/run-experiment.mts +367 -1
- package/src/swe-arena/run-report.mts +75 -0
- package/src/swe-arena/run-supervisor.test.mts +5 -3
- package/src/swe-arena/score-split.mts +140 -0
- package/src/swe-arena/score-split.test.mts +123 -0
- package/src/swe-arena/scratch-worktree.test.mts +55 -0
- package/src/swe-arena/scratch-worktree.ts +34 -0
- package/src/swe-arena/types.ts +52 -0
- package/src/swe-code-improve.mts +24 -25
- package/src/swe-improve.mts +129 -96
- package/src/swe-local-proof.mts +6 -1
- package/src/swe-stream.mts +4 -2
- package/src/swe-structural.mts +245 -837
- package/src/tb-container-executor.test.mts +30 -6
- package/src/tb-supervisor-sidecar.mts +2 -1
- package/src/trata-gepa.mts +182 -245
- package/dist/chunk-LRRD7NAG.js.map +0 -1
- package/src/live-improve-campaign-mbpp.mts +0 -641
- package/src/live-improve-campaign.mts +0 -500
- /package/dist/{chunk-CKUVRZ2T.js.map → chunk-3U5TXJZS.js.map} +0 -0
- /package/dist/{chunk-YCGY7UIZ.js.map → chunk-7GRVHU22.js.map} +0 -0
- /package/dist/{chunk-Z7ML6L77.js.map → chunk-HWST3SED.js.map} +0 -0
- /package/dist/{chunk-SYDW647C.js.map → chunk-IA2FBTWC.js.map} +0 -0
- /package/dist/{chunk-R67DFVLO.js.map → chunk-IFVINJ4B.js.map} +0 -0
- /package/dist/{chunk-R36V2VP7.js.map → chunk-IZ5M6OAC.js.map} +0 -0
- /package/dist/{chunk-ODT47UAY.js.map → chunk-K3BQGZCT.js.map} +0 -0
- /package/dist/{chunk-IFAV6KEM.js.map → chunk-KP5KD6EN.js.map} +0 -0
- /package/dist/{chunk-ZEWMTR5M.js.map → chunk-MQMRLGOG.js.map} +0 -0
- /package/dist/{chunk-TSWPNOYM.js.map → chunk-NQG5XDSB.js.map} +0 -0
- /package/dist/{chunk-7WSD27QQ.js.map → chunk-PB64GYIG.js.map} +0 -0
- /package/dist/{chunk-HBSWHQNJ.js.map → chunk-RCYQEFNX.js.map} +0 -0
- /package/dist/{chunk-J3KDJNX2.js.map → chunk-RH5F53JT.js.map} +0 -0
- /package/dist/{chunk-UAIOHCUK.js.map → chunk-SFLA7OH3.js.map} +0 -0
- /package/dist/{chunk-Y6O2OCUO.js.map → chunk-SHM6MRRF.js.map} +0 -0
- /package/dist/{chunk-KDIKRJGB.js.map → chunk-SHYIRB7I.js.map} +0 -0
- /package/dist/{chunk-HHXFIHXC.js.map → chunk-SVR2LKYI.js.map} +0 -0
- /package/dist/{chunk-PWQVGAJB.js.map → chunk-V7AEBY6U.js.map} +0 -0
- /package/dist/{chunk-2PVVP7GN.js.map → chunk-XKEFIFIC.js.map} +0 -0
- /package/dist/{chunk-JRWWGMK7.js.map → chunk-XYA4XSNU.js.map} +0 -0
- /package/dist/{chunk-X5YKXC6V.js.map → chunk-YSMEKBTD.js.map} +0 -0
- /package/dist/{chunk-2XU6OGEN.js.map → chunk-Z4TZ76N7.js.map} +0 -0
package/src/swe-improve.mts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Official GEPA prompt optimization on the local SWE-bench path.
|
|
3
3
|
*
|
|
4
|
-
* Composes
|
|
5
|
-
* 1. `improve({
|
|
6
|
-
*
|
|
7
|
-
* candidate prompt on real instances and gates the winner on a held-out split.
|
|
4
|
+
* Composes three pieces:
|
|
5
|
+
* 1. `improve({ method: officialGepa(...) })` runs GEPA's upstream
|
|
6
|
+
* Optimize Anything engine on explicit train and selection partitions.
|
|
8
7
|
* 2. Per candidate + scenario, the `agent` fn runs the LOCAL SWE env
|
|
9
8
|
* (`createSweBenchEnvironment` + `runAgentic`): clone the instance repo to a
|
|
10
9
|
* host tmpdir, run the jailed list/read/edit tool loop with the CANDIDATE
|
|
@@ -16,23 +15,33 @@
|
|
|
16
15
|
* IN-LOOP score is a cheap patch-exists proxy (NOT the Docker judge) so the ONLY
|
|
17
16
|
* Docker run per cell is the improve judge — one deterministic verdict per cell.
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* GENERATIONS=1 POPULATION=1 WORKER_MODEL=glm-4.6 REFLECT_MODEL=glm-4.6 \
|
|
18
|
+
* TANGLE_API_KEY=... dotenvx run -f .../agent-state.env -- \
|
|
19
|
+
* TRAIN_IDS=psf__requests-2931 SELECTION_IDS=pallets__flask-5014 \
|
|
20
|
+
* TEST_IDS=psf__requests-1142,psf__requests-1921 \
|
|
21
|
+
* MAX_EVALUATIONS=4 MAX_PROPOSER_COST_USD=2 \
|
|
24
22
|
* node_modules/.bin/tsx bench/src/swe-improve.mts
|
|
25
23
|
*/
|
|
26
24
|
import { execFile } from 'node:child_process'
|
|
27
25
|
import { promisify } from 'node:util'
|
|
28
|
-
import {
|
|
29
|
-
|
|
26
|
+
import {
|
|
27
|
+
improve,
|
|
28
|
+
officialGepa,
|
|
29
|
+
type ReadonlyAgentProfile,
|
|
30
|
+
} from '@tangle-network/agent-runtime'
|
|
31
|
+
import {
|
|
32
|
+
canonicalCandidateDigest,
|
|
33
|
+
type AgentProfile,
|
|
34
|
+
} from '@tangle-network/agent-interface'
|
|
30
35
|
import type { AgenticSurface, ArtifactHandle, SurfaceScore } from '@tangle-network/agent-runtime/loops'
|
|
31
36
|
import { refine, runAgentic } from '@tangle-network/agent-runtime/loops'
|
|
32
37
|
import type { DispatchContext, JudgeConfig, Scenario } from '@tangle-network/agent-eval/contract'
|
|
33
|
-
import { gepaProposer } from '@tangle-network/agent-eval/campaign'
|
|
34
38
|
import { createSweBenchAdapter } from './benchmarks/swe-bench'
|
|
35
39
|
import type { BenchTask } from './benchmarks/types'
|
|
40
|
+
import {
|
|
41
|
+
assertCompleteCost,
|
|
42
|
+
officialOptimizerModel,
|
|
43
|
+
requiredTokenPricing,
|
|
44
|
+
} from './official-optimizer-config.mjs'
|
|
36
45
|
import { createSweBenchEnvironment, SWE_SEED_PROMPT, SWE_SEED_PROMPT_WITH_RUN } from './swe-bench-env'
|
|
37
46
|
|
|
38
47
|
const exec = promisify(execFile)
|
|
@@ -42,36 +51,47 @@ async function main(): Promise<void> {
|
|
|
42
51
|
if (!routerKey) throw new Error('TANGLE_API_KEY required (the worker + reflection call the router)')
|
|
43
52
|
const routerBaseUrl = process.env.ROUTER_BASE ?? 'https://router.tangle.tools/v1'
|
|
44
53
|
const workerModel = process.env.WORKER_MODEL ?? 'glm-4.6'
|
|
54
|
+
const reflectBase = process.env.REFLECT_BASE ?? routerBaseUrl
|
|
55
|
+
const reflectKey = process.env.REFLECT_KEY ?? routerKey
|
|
45
56
|
const reflectModel = process.env.REFLECT_MODEL ?? 'glm-4.6'
|
|
46
57
|
const trainIds = (process.env.TRAIN_IDS ?? 'psf__requests-2931').split(',').map((s) => s.trim()).filter(Boolean)
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
58
|
+
const selectionIds = (process.env.SELECTION_IDS ?? 'pallets__flask-5014').split(',').map((s) => s.trim()).filter(Boolean)
|
|
59
|
+
const testIds = (process.env.TEST_IDS ?? 'psf__requests-1142,psf__requests-1921').split(',').map((s) => s.trim()).filter(Boolean)
|
|
60
|
+
const maxEvaluations = Number(process.env.MAX_EVALUATIONS ?? 4)
|
|
61
|
+
const maxProposerCostUsd = Number(process.env.MAX_PROPOSER_COST_USD ?? 2)
|
|
50
62
|
const innerTurns = Number(process.env.INNER_TURNS ?? 40)
|
|
51
63
|
const workerMaxTokens = Number(process.env.MAX_TOKENS ?? 8000)
|
|
52
64
|
const reflectMaxTokens = Number(process.env.REFLECT_MAX_TOKENS ?? 12000)
|
|
53
65
|
const maxConcurrency = Number(process.env.MAX_CONCURRENCY ?? 1)
|
|
54
66
|
const budgetShots = Number(process.env.BUDGET ?? 1)
|
|
67
|
+
const runDir = process.env.RUN_DIR ?? '.runs/swe-official-gepa'
|
|
55
68
|
// WITH-TOOLS arm: RUN_TOOL=1 exposes the jailed `run` tool AND swaps the seed to the run-aware prompt.
|
|
56
69
|
// Default OFF ⇒ reproduces the read/edit-only baseline denominator unchanged.
|
|
57
70
|
const enableRun = ['1', 'true', 'yes'].includes((process.env.RUN_TOOL ?? '').toLowerCase())
|
|
58
71
|
const SEED_PROMPT = enableRun ? SWE_SEED_PROMPT_WITH_RUN : SWE_SEED_PROMPT
|
|
72
|
+
const allIds = [...new Set([...trainIds, ...selectionIds, ...testIds])]
|
|
59
73
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
console.log(
|
|
64
|
-
console.log(`
|
|
65
|
-
console.log(`train=[${trainIds.join(', ')}] holdout=[${holdoutIds.join(', ')}]`)
|
|
66
|
-
console.log(`generations=${generations} population=${population} innerTurns=${innerTurns} workerMaxTokens=${workerMaxTokens} reflectMaxTokens=${reflectMaxTokens} runTool=${enableRun}`)
|
|
67
|
-
console.log(`≈ ${cellsMax} cells max (each = 1 clone + 1 runAgentic + 1 Docker judge)\n`)
|
|
74
|
+
console.log('=== SWE-bench prompt optimization with official GEPA ===')
|
|
75
|
+
console.log(`worker=${workerModel} reflect=${reflectModel} router=${routerBaseUrl}`)
|
|
76
|
+
console.log(`train=[${trainIds.join(', ')}] selection=[${selectionIds.join(', ')}] test=[${testIds.join(', ')}]`)
|
|
77
|
+
console.log(`maxEvaluations=${maxEvaluations} maxProposerCostUsd=${maxProposerCostUsd} innerTurns=${innerTurns} workerMaxTokens=${workerMaxTokens} runTool=${enableRun}`)
|
|
78
|
+
console.log(`runDir=${runDir}\n`)
|
|
68
79
|
|
|
69
80
|
if (process.env.DRYRUN) {
|
|
70
81
|
// Import + wiring smoke: prove every module resolves and the plan is well-formed
|
|
71
82
|
// WITHOUT paying for a clone / model call / Docker judge.
|
|
72
|
-
console.log(`DRYRUN: imports OK (improve=${typeof improve},
|
|
83
|
+
console.log(`DRYRUN: imports OK (improve=${typeof improve}, officialGepa=${typeof officialGepa}, runAgentic=${typeof runAgentic}, refine=${typeof refine})`)
|
|
73
84
|
return
|
|
74
85
|
}
|
|
86
|
+
const workerPricing = requiredTokenPricing(process.env, 'WORKER')
|
|
87
|
+
const optimizer = officialOptimizerModel({
|
|
88
|
+
env: process.env,
|
|
89
|
+
model: reflectModel,
|
|
90
|
+
baseUrl: reflectBase,
|
|
91
|
+
apiKey: reflectKey,
|
|
92
|
+
maxCostUsd: maxProposerCostUsd,
|
|
93
|
+
maxOutputTokensPerRequest: reflectMaxTokens,
|
|
94
|
+
})
|
|
75
95
|
|
|
76
96
|
const { environment, adapter } = await createSweBenchEnvironment(allIds.length, { ids: allIds, enableRun })
|
|
77
97
|
const pool = await adapter.loadTasks({ ids: allIds, split: 'test' })
|
|
@@ -82,8 +102,9 @@ async function main(): Promise<void> {
|
|
|
82
102
|
// one instance, return the git-diff patch. A per-call proxy captures the patch in
|
|
83
103
|
// score() BEFORE runAgentic closes (rm) the workspace; its score is a cheap
|
|
84
104
|
// patch-exists proxy so the ONLY Docker run per cell is the improve judge.
|
|
85
|
-
const agent = async (
|
|
86
|
-
const promptText =
|
|
105
|
+
const agent = async (candidate: ReadonlyAgentProfile, scenario: Scenario, ctx: DispatchContext): Promise<string | null> => {
|
|
106
|
+
const promptText = candidate.prompt?.systemPrompt
|
|
107
|
+
if (promptText === undefined) throw new Error('agent: candidate profile has no system prompt')
|
|
87
108
|
const bt = byId.get(scenario.id)
|
|
88
109
|
if (!bt) throw new Error(`agent: unknown scenario ${scenario.id}`)
|
|
89
110
|
const task = { id: bt.id, systemPrompt: promptText, userPrompt: bt.prompt, meta: { instanceId: bt.id } }
|
|
@@ -111,40 +132,44 @@ async function main(): Promise<void> {
|
|
|
111
132
|
},
|
|
112
133
|
}
|
|
113
134
|
const t0 = Date.now()
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
strategy: refine,
|
|
118
|
-
routerBaseUrl,
|
|
119
|
-
routerKey,
|
|
135
|
+
const paid = await ctx.cost.runPaidCall({
|
|
136
|
+
channel: 'agent',
|
|
137
|
+
actor: 'swe-worker',
|
|
120
138
|
model: workerModel,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
139
|
+
execute: () =>
|
|
140
|
+
runAgentic({
|
|
141
|
+
surface: proxy,
|
|
142
|
+
task,
|
|
143
|
+
strategy: refine,
|
|
144
|
+
routerBaseUrl,
|
|
145
|
+
routerKey,
|
|
146
|
+
model: workerModel,
|
|
147
|
+
maxTokens: workerMaxTokens,
|
|
148
|
+
innerTurns,
|
|
149
|
+
budget: budgetShots,
|
|
150
|
+
}),
|
|
151
|
+
receipt: (result) => {
|
|
152
|
+
const inputTokens = result.tokens.input ?? 0
|
|
153
|
+
const outputTokens = result.tokens.output ?? 0
|
|
154
|
+
const usageUnknown = inputTokens === 0 && outputTokens === 0
|
|
155
|
+
return {
|
|
156
|
+
model: workerModel,
|
|
157
|
+
inputTokens,
|
|
158
|
+
outputTokens,
|
|
159
|
+
customTokenPricing: workerPricing,
|
|
160
|
+
...(usageUnknown ? { usageUnknown: true } : {}),
|
|
161
|
+
}
|
|
162
|
+
},
|
|
124
163
|
})
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// patch with an UNPOPULATED usage block (a router telemetry gap on some
|
|
128
|
-
// reasoning-model responses — NOT a stub: the cell made real tool calls and
|
|
129
|
-
// produced a patch). In that gap case report a nominal floor so the stub-guard
|
|
130
|
-
// (artifact + zero usage) cannot abort the whole campaign on a telemetry gap.
|
|
131
|
-
// The lift metric is judge-derived, so a floored count does not distort it; only
|
|
132
|
-
// cost accounting undercounts those few cells (disclosed). No-patch cells return
|
|
133
|
-
// null below and are skipped by the guard's own contract, so this floor only
|
|
134
|
-
// ever applies to a cell that genuinely produced a patch.
|
|
164
|
+
if (!paid.succeeded) throw paid.error
|
|
165
|
+
const r = paid.value
|
|
135
166
|
const zeroUsage = (r.tokens.input ?? 0) === 0 && (r.tokens.output ?? 0) === 0
|
|
136
167
|
const hasPatch = capturedPatch.trim().length > 0
|
|
137
|
-
ctx.cost.observe(zeroUsage && hasPatch ? Math.max(r.usd ?? 0, 0.0001) : r.usd ?? 0, workerModel)
|
|
138
|
-
ctx.cost.observeTokens(
|
|
139
|
-
zeroUsage && hasPatch
|
|
140
|
-
? { input: Math.max(r.tokens.input ?? 0, 1), output: Math.max(r.tokens.output ?? 0, 1) }
|
|
141
|
-
: { input: r.tokens.input, output: r.tokens.output },
|
|
142
|
-
)
|
|
143
168
|
const files = capturedPatch ? [...capturedPatch.matchAll(/^diff --git a\/(\S+)/gm)].map((m) => m[1]) : []
|
|
144
169
|
console.log(
|
|
145
170
|
` [agent] ${scenario.id} prompt=${promptText.length}c tools(l/r/e+/e-/run/run!)=${stats.list}/${stats.read}/${stats.edit_ok}/${stats.edit_fail}/${stats.run}/${stats.run_err} ` +
|
|
146
|
-
`patch=${capturedPatch.length}b files=[${files.join(', ') || 'none'}] tok=in:${r.tokens.input}/out:${r.tokens.output}
|
|
147
|
-
`${zeroUsage ?
|
|
171
|
+
`patch=${capturedPatch.length}b files=[${files.join(', ') || 'none'}] tok=in:${r.tokens.input}/out:${r.tokens.output} ${Math.round((Date.now() - t0) / 1000)}s` +
|
|
172
|
+
`${zeroUsage ? ' [provider usage unavailable]' : ''}`,
|
|
148
173
|
)
|
|
149
174
|
// A cell with no patch produced NO artifact. Return null (not '') so the
|
|
150
175
|
// backend-integrity guard's own contract (`artifact == null → skip`) applies:
|
|
@@ -156,7 +181,7 @@ async function main(): Promise<void> {
|
|
|
156
181
|
|
|
157
182
|
// The judge: the OFFICIAL swebench Docker harness. Deterministic FAIL_TO_PASS +
|
|
158
183
|
// PASS_TO_PASS → resolved 0/1. This is the held-out gate's scoring axis.
|
|
159
|
-
const judge: JudgeConfig<string, Scenario> = {
|
|
184
|
+
const judge: JudgeConfig<string | null, Scenario> = {
|
|
160
185
|
name: 'swebench-docker',
|
|
161
186
|
dimensions: [{ key: 'resolved', description: 'FAIL_TO_PASS + PASS_TO_PASS resolved by the official swebench Docker harness' }],
|
|
162
187
|
async score({ artifact, scenario }) {
|
|
@@ -177,53 +202,61 @@ async function main(): Promise<void> {
|
|
|
177
202
|
}
|
|
178
203
|
|
|
179
204
|
const profile: AgentProfile = { name: 'swe-agent-glm46', prompt: { systemPrompt: SEED_PROMPT } }
|
|
180
|
-
const
|
|
181
|
-
llm: { baseUrl: routerBaseUrl, apiKey: routerKey },
|
|
182
|
-
model: reflectModel,
|
|
183
|
-
target: 'the system prompt of a coding agent that fixes real GitHub bugs via list_files/read_file/edit_file tools',
|
|
184
|
-
maxTokens: reflectMaxTokens,
|
|
185
|
-
temperature: 0.7,
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
const scenarios: Scenario[] = allIds.map((id) => ({ id, kind: 'swe-bench-verified' }))
|
|
189
|
-
const holdoutScenarios: Scenario[] = holdoutIds.map((id) => ({ id, kind: 'swe-bench-verified' }))
|
|
205
|
+
const scenario = (id: string): Scenario => ({ id, kind: 'swe-bench-verified' })
|
|
190
206
|
|
|
191
|
-
const out = await improve(profile,
|
|
207
|
+
const out = await improve(profile, {
|
|
192
208
|
surface: 'prompt',
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
209
|
+
executionRef: canonicalCandidateDigest({
|
|
210
|
+
callback: 'bench/swe-improve',
|
|
211
|
+
model: workerModel,
|
|
212
|
+
endpoint: new URL(routerBaseUrl).origin,
|
|
213
|
+
innerTurns,
|
|
214
|
+
maxTokens: workerMaxTokens,
|
|
215
|
+
budgetShots,
|
|
216
|
+
enableRun,
|
|
217
|
+
}),
|
|
218
|
+
method: officialGepa<Scenario, string | null>({
|
|
219
|
+
objective:
|
|
220
|
+
'Improve the system prompt of a coding agent that fixes real GitHub bugs with list_files, read_file, edit_file, and optional run tools.',
|
|
221
|
+
background:
|
|
222
|
+
'Return the complete system prompt. Preserve tool names and require evidence from repository files and tests.',
|
|
223
|
+
recipe: {
|
|
224
|
+
kind: 'engine',
|
|
225
|
+
run: {
|
|
226
|
+
engine: 'gepa',
|
|
227
|
+
maxEvaluations,
|
|
228
|
+
maxProposerCostUsd,
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
optimizer,
|
|
232
|
+
resume: 'if-compatible',
|
|
233
|
+
trustResumeState: true,
|
|
234
|
+
describeScenario: (item) => ({ prompt: byId.get(item.id)?.prompt ?? item.id }),
|
|
235
|
+
}),
|
|
236
|
+
trainScenarios: trainIds.map(scenario),
|
|
237
|
+
selectionScenarios: selectionIds.map(scenario),
|
|
238
|
+
testScenarios: testIds.map(scenario),
|
|
239
|
+
judges: [judge],
|
|
197
240
|
agent,
|
|
198
|
-
// glm-5.2 occasionally returns a real patch with an unpopulated usage block
|
|
199
|
-
// (a router telemetry gap on some reasoning-model responses — NOT a stub: the
|
|
200
|
-
// cell made real tool calls and produced a patch). 'assert' would abort the
|
|
201
|
-
// whole campaign on such a cell; 'warn' logs it and continues. The lift metric
|
|
202
|
-
// (resolved) is judge-derived, so a missing token count does not distort it —
|
|
203
|
-
// only the cost accounting undercounts those cells, which is disclosed.
|
|
204
241
|
expectUsage: 'warn',
|
|
205
|
-
|
|
206
|
-
|
|
242
|
+
maxConcurrency,
|
|
243
|
+
reps: 1,
|
|
244
|
+
runDir,
|
|
245
|
+
optimizationRunOptions: {
|
|
246
|
+
expectUsage: 'warn',
|
|
247
|
+
maxConcurrency,
|
|
248
|
+
reps: 1,
|
|
249
|
+
},
|
|
207
250
|
})
|
|
208
251
|
|
|
209
|
-
|
|
210
|
-
console.log(
|
|
211
|
-
console.log(`
|
|
212
|
-
console.log(`
|
|
213
|
-
console.log(`
|
|
214
|
-
console.log(`
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// Per-candidate verdicts on the train set (the "real swebench verdict per candidate").
|
|
219
|
-
for (const gen of out.raw.generations ?? []) {
|
|
220
|
-
console.log(`\n── generation ${gen.record.generationIndex} candidates ──`)
|
|
221
|
-
for (const c of gen.record.candidates) {
|
|
222
|
-
const perScenario = (c as { scenarios?: Array<{ scenarioId: string; composite: number }> }).scenarios ?? []
|
|
223
|
-
const detail = perScenario.map((s) => `${s.scenarioId}=${s.composite}`).join(' ')
|
|
224
|
-
console.log(` candidate ${c.surfaceHash.slice(0, 8)} composite=${c.composite}${c.label ? ` "${c.label}"` : ''} [${detail}]`)
|
|
225
|
-
}
|
|
226
|
-
}
|
|
252
|
+
assertCompleteCost('SWE-bench official GEPA run', out.cost)
|
|
253
|
+
console.log('\n=== RESULT ===')
|
|
254
|
+
console.log(`decision=${out.decision} lift=${out.lift} interval=[${out.liftInterval.low}, ${out.liftInterval.high}]`)
|
|
255
|
+
console.log(`baseline test composite=${out.raw.best.baselineComposite}`)
|
|
256
|
+
console.log(`winner test composite=${out.raw.best.winnerComposite}`)
|
|
257
|
+
console.log(`test scenarios=${JSON.stringify(out.raw.best.scenarioScores)}`)
|
|
258
|
+
console.log(`cost=${JSON.stringify(out.cost)}`)
|
|
259
|
+
console.log(`candidate prompt:\n${String(out.candidate.value).slice(0, 2000)}`)
|
|
227
260
|
}
|
|
228
261
|
|
|
229
262
|
main().catch((e) => {
|
package/src/swe-local-proof.mts
CHANGED
|
@@ -46,6 +46,9 @@ async function main(): Promise<void> {
|
|
|
46
46
|
|
|
47
47
|
const { environment, tasks, adapter } = await createSweBenchEnvironment(ids.length, { ids, enableRun })
|
|
48
48
|
const taskList = await tasks(0, ids.length)
|
|
49
|
+
const benchTaskById = new Map(
|
|
50
|
+
(await adapter.loadTasks({ ids, split: 'test' })).map((task) => [task.id, task]),
|
|
51
|
+
)
|
|
49
52
|
|
|
50
53
|
// One shot per pinned id: proxy score() to capture the exact judged bytes + a NON-DESTRUCTIVE
|
|
51
54
|
// apply-coherence check, then delegate the verdict to the real Docker judge.
|
|
@@ -123,7 +126,9 @@ async function main(): Promise<void> {
|
|
|
123
126
|
// Cached judge: identical patch ⇒ identical verdict; don't pay for a second Docker run.
|
|
124
127
|
let s = judged.get(effPatch)
|
|
125
128
|
if (!s) {
|
|
126
|
-
|
|
129
|
+
const benchTask = benchTaskById.get(task.id)
|
|
130
|
+
if (!benchTask) throw new Error(`swe-local-proof: unknown benchmark task ${task.id}`)
|
|
131
|
+
s = await adapter.judge(benchTask, effPatch)
|
|
127
132
|
judged.set(effPatch, s)
|
|
128
133
|
}
|
|
129
134
|
rec.score = s
|
package/src/swe-stream.mts
CHANGED
|
@@ -700,6 +700,8 @@ async function acquireRepro(
|
|
|
700
700
|
// hands the worker a no-code plan. Primitives replicated from supervisor-arena.mts (that file runs
|
|
701
701
|
// main() on import, so it cannot be imported) — evidence from execution-verified inputs only. ----------
|
|
702
702
|
|
|
703
|
+
type RepairFailureKind = 'wrong-fix' | 'apply-failed' | 'empty-diff'
|
|
704
|
+
|
|
703
705
|
/** Evidence for the supervisor: the issue, the worker's own candidate diff, and the tail of the
|
|
704
706
|
* gold-verified reproduction's output on that diff. Execution-verified / model-visible ONLY — never
|
|
705
707
|
* FAIL_TO_PASS, never the gold patch, never any worker self-report. Bounded to maxChars. */
|
|
@@ -709,7 +711,7 @@ function renderRepairEvidence(
|
|
|
709
711
|
reproTail: string,
|
|
710
712
|
reproExit: number | null,
|
|
711
713
|
maxChars: number,
|
|
712
|
-
failureKind:
|
|
714
|
+
failureKind: RepairFailureKind = 'wrong-fix',
|
|
713
715
|
): string {
|
|
714
716
|
const header =
|
|
715
717
|
failureKind === 'apply-failed'
|
|
@@ -789,7 +791,7 @@ async function superviseRepair(
|
|
|
789
791
|
reproExit: number | null,
|
|
790
792
|
marks: readonly string[],
|
|
791
793
|
deadlineAt: number,
|
|
792
|
-
failureKind:
|
|
794
|
+
failureKind: RepairFailureKind = 'wrong-fix',
|
|
793
795
|
): Promise<SupervisorPlanReceipt> {
|
|
794
796
|
const md = bt.metadata as Record<string, string>
|
|
795
797
|
const evidence = renderRepairEvidence(String(md.problem_statement ?? ''), candidateDiff, reproTail, reproExit, 14_000, failureKind)
|