Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @Tyronita @lLegon
242 changes: 144 additions & 98 deletions README.md

Large diffs are not rendered by default.

Binary file modified docs/figures/fig1_pipeline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/figures/fig3_golden_gate_frames.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 14 additions & 14 deletions docs/figures/src/pipeline.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,30 @@
.levels div { flex:1; font-size:12px; color:var(--ink2); border-left:3px solid var(--line); padding-left:8px; }
</style></head>
<body><div class="wrap">
<div class="band">1 · Build tasks from papers</div>
<div class="band">A · Build tasks from papers</div>
<div class="row">
<div class="stage"><h3><span class="key" style="background:var(--orange)"></span>Paper + authors' code</h3><p>36 papers, 123 experiments in <code>sources/</code>. Code kept aside as an independent check, never an input.</p></div>
<div class="stage"><h3><span class="key" style="background:var(--orange)"></span>Paper + authors' robot code</h3><p>48 papers, 166 experiments. The authors' code is kept aside as an independent check, never an input.</p></div>
<div class="arrow">→</div>
<div class="stage"><h3><span class="key" style="background:var(--orange)"></span>paper2protocol</h3><p><code>list</code> the experiments, <code>assess</code> if one has enough detail, <code>convert</code> it to instructions + a protocol IR.</p></div>
<div class="stage"><h3><span class="key" style="background:var(--orange)"></span>Extraction</h3><p>An LLM pipeline lists the experiments, keeps those with enough detail, and writes each as instructions and a structured protocol (ground truth).</p></div>
<div class="arrow">→</div>
<div class="stage"><h3><span class="key" style="background:var(--orange)"></span>Harbor task</h3><p>Fixed deck, reference protocol, <code>rubric.json</code>, 10 traps.</p>
<div class="levels"><div><b>Easy</b>: exact steps and quantities</div><div><b>Hard</b>: goal + paper at <code>/data</code></div></div></div>
<div class="stage"><h3><span class="key" style="background:var(--orange)"></span>Task</h3><p>A fixed deck, a reference protocol, a grading rubric and 9 reward-hacking traps.</p>
<div class="levels"><div><b>Easy</b>: every step and quantity given</div><div><b>Paper-only</b>: a goal and the paper</div></div></div>
</div>
<div class="down">↓</div>
<div class="band">2 · Run the agent in a Harbor sandbox (Modal or Docker)</div>
<div class="band">B · Run the agent in an isolated sandbox, then grade</div>
<div class="row">
<div class="stage"><h3><span class="key" style="background:var(--blue)"></span>Claude Code agent</h3><p>Reads <code>instruction.md</code> (and the paper on hard tasks), writes <code>/app/protocol.py</code>. Opus 5.5, Sonnet 5.5, Fable 5.1.</p></div>
<div class="stage"><h3><span class="key" style="background:var(--blue)"></span>LLM agent</h3><p>Reads the task (and the paper, on paper-only tasks) and writes an OT-2 Python protocol. Six models from four providers, all run in the same Claude Code harness.</p></div>
<div class="arrow">→</div>
<div class="stage" style="flex:2.6"><h3><span class="key" style="background:var(--aqua)"></span>Verifier <code>tests/test.sh</code>, copied in only after the agent finishes</h3>
<div class="stage" style="flex:2.6"><h3><span class="key" style="background:var(--aqua)"></span>Verifier, copied into the sandbox only after the agent finishes</h3>
<div class="layers">
<div class="layer"><b>Lint</b><span>fail → 0</span></div>
<div class="layer"><b>Hack traps</b><span>10 traps, any → 0</span></div>
<div class="layer"><b>Simulator</b><span><code>opentrons_simulate</code>, fail → 0</span></div>
<div class="layer"><b>Checks</b><span>end state or run log</span></div>
<div class="layer"><b>Lint</b><span>unsafe code → 0</span></div>
<div class="layer"><b>Traps</b><span>9 traps, any → 0</span></div>
<div class="layer"><b>Simulator</b><span>Opentrons simulator, error → 0</span></div>
<div class="layer"><b>Checks</b><span>end state vs ground truth; tips, contamination</span></div>
<div class="layer judge"><b>LLM judge</b><span>3 core items 75%, task items 25%, each pass/fail</span></div>
<div class="layer cap"><b>Critical cap</b><span>reward ≤ 0.3</span></div>
<div class="layer cap"><b>Critical cap</b><span>critical fail → ≤ 0.3</span></div>
</div></div>
<div class="arrow">→</div>
<div class="stage" style="flex:.8"><h3>reward.json</h3><p>0 to 1, plus every rubric item and trap.</p></div>
<div class="stage" style="flex:.8"><h3>Reward</h3><p>0 to 1, with every check, rubric item and trap recorded.</p></div>
</div>
</div></body></html>
Binary file modified docs/preprint/figures/fig6_corpus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/preprint/figures/run_means_cost.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/preprint/figures/run_where_lost.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/preprint/make_figures.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

uv run --no-project --with matplotlib python docs/preprint/make_figures.py

Reads docs/harbor-results/analysis/{rounds,errors}.json and sources/master.csv; writes docs/preprint/figures/*.png.
Reads results/archive/2026-10-04-harbor-results/analysis/{rounds,errors}.json and sources/master.csv; writes docs/preprint/figures/*.png.
"""
import collections, csv, json, pathlib, statistics

Expand All @@ -11,7 +11,7 @@
import matplotlib.pyplot as plt

ROOT = pathlib.Path(__file__).resolve().parents[2]
A = ROOT / "docs/harbor-results/analysis"
A = ROOT / "results/archive/2026-10-04-harbor-results/analysis"
OUT = ROOT / "docs/preprint/figures"
OUT.mkdir(parents=True, exist_ok=True)

Expand Down
6 changes: 3 additions & 3 deletions docs/preprint/make_run_figures.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ def xgrid(ax): ax.xaxis.grid(True, color=GRID, lw=0.6); ax.set_axisbelow(True)
a.legend(loc="upper center", bbox_to_anchor=(.5, -.2), ncol=(len(MODELS) + 1) // 2 if len(MODELS) > 4 else len(MODELS), fontsize=7.5)
a.set_title("Refused tasks are not scored"); panel(a, "a")
for m in MODELS:
cost = sum(trials[(m, k)].get("cost_usd") or 0 for k in TASKS)
cost = sum(trials[(m, k)].get("cost_usd") or 0 for k in common)
v = rules[0][1](m)
b.scatter(cost, v, s=90, color=COL[m], zorder=3)
nref = sum(refused(m, k) for k in TASKS)
b.annotate(f"{NAME[m]}, {nref} refused" if nref else NAME[m], (cost, v), xytext=(8, -3), textcoords="offset points", fontsize=7.5, color=INK2)
b.set_xlabel("Agent cost for the tasks it answered (USD)"); b.set_ylabel(f"Mean over the {len(common)} tasks all answered")
costs = [sum(trials[(m, k)].get("cost_usd") or 0 for k in TASKS) for m in MODELS]
b.set_xlabel(f"Agent cost for the {len(common)} tasks all answered (USD)"); b.set_ylabel(f"Mean over the {len(common)} tasks all answered")
costs = [sum(trials[(m, k)].get("cost_usd") or 0 for k in common) for m in MODELS]
vals = [rules[0][1](m) for m in MODELS]
b.set_xlim(0, max(costs) * 1.75); b.set_ylim(min(vals) - .05, min(1.02, max(vals) + .05)); ygrid(b); xgrid(b)
b.set_title("Cost against reward"); panel(b, "b")
Expand Down
Loading
Loading