Benchmark home/terminal-bench-2-1 · tb-v3 · deepseek-v4.1-flash-1017
EXPERIMENT · TERMINAL-BENCH-2-1 · TB-V3 · DEEPSEEK-V4.1-FLASH

tb-v3 × deepseek-v4.1-flash: 64/89 · 0.7191

Same 0.7191 as mimo — but 60% of the zeros are runtime, not model. Two time black holes eat the budget before the model ever gets to think.

Harness: tb-v3 (parent tb-v2) · provider_error.max_retries 3→6 · base_delay 0.5→2 Model: deepseek/deepseek-v4.1-flash-1017 via OpenRouter · LLM_TEMPERATURE=0 89 trials · timeout_multiplier 3.0 · reward 1.0: 64 / 0.0: 25 jobs/terminal-bench-2-1-tb-v3-deepseekv4.1-flash-1017/ job id 88e36da2-ed1d-4f57-9a82-a918fa0da700
PASS RATE
64/89 · 0.7191
64×1.0 / 25×0.0 — all-or-nothing rewards
WALL-CLOCK KILLS
8 (12 hit)
CancelledError at base×3.0 exactly; 4 more hit it but finished first
STREAM-IDLE DEATHS
7
120s no-first-packet → 5 retries replay → whole turn voided
EX-RUNTIME SCORE
~0.80
72/89 = 0.809 after removing 15 runtime + 2 env wrongs
Verdict: 15/25 (60%) of zeros are model-independent runtime losses; tb-v3 cut infra failures 22→15, but deepseek-v4.1-flash on OpenRouter still pays 15 where mimo pays 0 — a model-specific first-packet behavior, not a harness bug.
01 · CROSS-JOB

Same dataset, three different failure mixes

passed wall-clock kill stream-idle death verifier fail 64 8 7 10
89 trials = 64 passed + 25 zero. Sources: per-trial result.json + verifier ctrf/reward/test-stdout + agent-runtime.jsonl + trial.log + task.toml base timeouts.
JobHarness / ModelZerosInfra-classTrue capability
terminal-bench-2-1-tb-v2tb-v2 / deepseek-v435 (39.8%)22 (15 stream + 7 timeout)13
terminal-bench-2-1-tb-v2-mimo-2.6-pro-ultraspeedtb-v2 / mimo-2.6-pro25 (28.1%)025
terminal-bench-2-1-tb-v3-deepseekv4.1-flash-1017tb-v3 / deepseek-v4.1-flash25 (28.1%)1510
tb-v3 provider_error 3→6 retries moved infra 22→15 — but the same harness with mimo shows 0. The residual 15 is deepseek-v4.1-flash's extremely slow first packet on OpenRouter, not harness debt.
02 · WALL-CLOCK KILLS

8 killed by the clock — signature: CancelledError at exactly base×3.0

result.json agent_runtime.error = {"type": "CancelledError"} and wall time equals task.toml [agent] timeout_sec × 3.0. 4 more trials hit the same wall but finished first (filter-js-from-html 5400s, torch-pipeline/torch-tensor 2700s, tune-mjcf 2700s) — 12 wall hits total, 8 fatal.

CaseBase → ×3 actualSummary burnLong toolsIters
cobol-modernization900s → 2700s1.0 min—56
count-dataset-tokens900s → 2700s0.1 min2×901s37
gcode-to-text900s → 2700s22.6 min2×120s63
make-doom-for-mips900s → 2700s8.9 min4×(250~380)s39
large-scale-text-editing1200s → 3600s0 min51.2 min45
make-mips-interpreter1800s → 5400s46.7 min—86
schemelike-metacircular-eval2400s → 7200s104.8 min (87% of budget)—28
train-fasttext3600s → 10800s0 min176.8 min34

Black hole 1 · memory.llm_summary — 202 calls / 4.98h

memory.py:378-396 _generate_summary re-sends the whole history via non-streaming llm.chat() — no idle timeout, no size cap. Single summaries cost 250~700s: schemelike 15 summaries ate 104.8/120 min (agent reasoning left ~15 min), make-mips-interpreter 46.7/90, gcode-to-text 22.6/45, video-processing 55.2/85. Compression often fails open: request_chars 70k~78k > 60k budget (video-processing original_chars → 394k), re-triggering summaries in O(n²) growth.

Black hole 2 · unbounded tool timeout — no budget awareness

run_command schema (tools.py:92) + execute_code (code.py:223) accept any timeout number; the model passes 600/900/1200s and the executor obeys. train-fasttext: 17 long commands (600~1201s), 176.8/180 min in tools, re-running the same timed-out train command. Tool budget and agent wall budget have no linkage.

Tracing trap: trace.span() hides the kill

trace.py:99-109 span() only catches Exception — asyncio.CancelledError inherits BaseException since Py3.8, so status = "error" if failed else "success" in finally always lands on success. All 8 killed trials end their trace with agent.end {status: "success"} while result.json says CancelledError. Reading trace alone yields the wrong conclusion ("agent finished normally").

03 · STREAM-IDLE DEATHS

7 dead on first packet — TTFT p99 sits exactly on the 120s cliff

adaptive-rejection-sampler · circuit-fibsqrt · feal-linear-cryptanalysis · gpt2-codegolf · path-tracing-reverse · regex-chess · write-compressor. Uniform error: LLM stream produced no chunk for 120 seconds (chat.py:143-148).

Why retries can't save it

AGENT_RUNTIME_STREAM_IDLE_TIMEOUT defaults to 120s; tb-v3 stream_idle_timeout.max_retries=5 means replaying the same request 5× = 10 idle minutes, then loop.py:273-277 raises _TurnFailure and the whole turn ends — discarding 13~40 completed rounds. Failed iterations received chunk count = 0: not mid-stream interruption but TTFT timeout. Job-wide TTFT over 4247 successful calls: p50 2.4s · p90 18.7s · p99 119.4s · max 708.9s — the 120s threshold sits exactly on the cliff edge. 99 retries = 3.3h pure waiting; 24/89 trials triggered at least once. All 5 retries replay the identical request — for "first reasoning packet inherently >120s" requests, retry deterministically reproduces the failure.

04 · VERIFIER FAILURES

10 finished-but-failed — 2 wrongful, 8 real

Env faults — wrongful (2)

qemu-alpine-ssh · qemu-startup — verifier's own test.sh never ran (same bullseye 404 → curl → uv → uvx chain as tb-v2/mimo). Only 2/89 hit it. Rerun or fix the image.

Real gaps — near-miss flavor (8)

caffe-cifar-10 (acc gap 0.0823 > 0.05) · dna-assembly (BsaI ggtctc missing ≥1nt clamp, assert i ≥ 1) · install-windows-3.11 (VNC key <10% image diff) · pytorch-model-cli (15 test images nearly all misclassified) · rstan-to-pystan (beta[0] posterior -0.1455 outside [-0.07, 0]) · sam-cell-seg (IoU 0.4930 < 0.5, off 0.007) · video-processing (jump frame 98 vs [219,223]) · extract-moves-from-video (121/120 iters exhausted, never wrote /app/solution.txt).

05 · LEDGER

All 25 zeros, one table

CaseClassStateRetrySummariesSummary timeTrace span
adaptive-rejection-sampler2 streamfailed500.0 min32.6 min
circuit-fibsqrt2 streamfailed500.0 min14.0 min
feal-linear-cryptanalysis2 streamfailed500.0 min12.3 min
gpt2-codegolf2 streamfailed600.0 min17.3 min
path-tracing-reverse2 streamfailed841.5 min30.5 min
regex-chess2 streamfailed500.0 min12.3 min
write-compressor2 streamfailed800.0 min19.1 min
cobol-modernization1 wall-clockfailed831.0 min45.0 min
count-dataset-tokens1 wall-clockfailed010.1 min45.0 min
gcode-to-text1 wall-clockfailed0722.6 min45.0 min
large-scale-text-editing1 wall-clockfailed000.0 min60.0 min
make-doom-for-mips1 wall-clockfailed178.9 min45.0 min
make-mips-interpreter1 wall-clockfailed101146.7 min90.0 min
schemelike-metacircular-eval1 wall-clockfailed215104.8 min120.0 min
train-fasttext1 wall-clockfailed000.0 min180.0 min
caffe-cifar-103 verifycompleted010.3 min73.4 min
dna-assembly3 verifycompleted631.3 min49.5 min
extract-moves-from-video3 verifycompleted0146.9 min68.9 min
install-windows-3.113 verifycompleted061.7 min27.8 min
pytorch-model-cli3 verifycompleted010.2 min6.7 min
qemu-alpine-ssh3 verify (env)completed041.4 min29.0 min
qemu-startup3 verify (env)completed012.6 min22.6 min
rstan-to-pystan3 verifycompleted030.7 min81.3 min
sam-cell-seg3 verifycompleted040.8 min160.7 min
video-processing3 verifycompleted01855.2 min85.2 min
06 · RECOMMENDATIONS

Six fixes, in priority order

  1. Fix trace.span exception capture (trace.py:99): catch BaseException so CancelledError kills surface as error instead of success.
  2. Cap the summary layer: faster model via AGENT_RUNTIME_SUMMARY_MODEL, or streaming + own timeout, or deterministic compact_observations; cap summary input size (currently 186k~394k chars) and keep request_chars under context_budget.
  3. Stream idle 120s → 300s+ (chat.py:19); on retry exhaustion degrade (treat as empty reply, keep iterating) instead of ending the turn; backoff + request rewrite (e.g. shorter reasoning) instead of identical replay.
  4. Cap tool timeout and link it to remaining budget: min(user value, remaining budget × 20%); tell the model in the system prompt not to set hundred-second timeouts.
  5. Fix the qemu verifier image: pin apt to archive.debian.org or preinstall curl/expect/uv.
  6. Rerun the 8 wall-clock-killed + 2 env-fault trials, then re-rate the true capability level.
07 · REPRODUCTION

Artifacts & record

Job
jobs/terminal-bench-2-1-tb-v3-deepseekv4.1-flash-1017/
Job id
88e36da2-ed1d-4f57-9a82-a918fa0da700
Model
deepseek-v4.1-flash-1017 · T=0
Report
evaluation/analysis/terminal-bench-2-1-tb-v3-deepseekv4.1-flash-1017.md
TTFT stats over 4247 successful calls: p50 2.4s / p90 18.7s / p99 119.4s / max 708.9s. Summary stats: 202 calls / 4.98h; stream retries: 99 / 3.3h. Data and conclusions as published in the analysis report.
← Previoustb-v2 · 0.596 — the harness this run builds on Back to leaderboard ↑SunAgent Harness Benchmark home Next →tb-v4 · deepseek-v4.1-flash — continued