Skip to content

Commit cffa5d9

Browse files
fluffy314cursoragent
authored andcommitted
fix(autoresearch): retry allens worker restart
Wait for launchd unload and service readiness so deployment races cannot crash the supervisor or mask the original experiment error. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 8e7f16f commit cffa5d9

2 files changed

Lines changed: 77 additions & 5 deletions

File tree

autoresearch/prefill/supervisor.py

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,50 @@ def deploy_candidate(worker_ssh: str, chunk_tokens: int) -> None:
219219
os.chmod(t,0o644)
220220
t.replace(p)
221221
PY
222-
launchctl bootout gui/$(id -u)/ai.kakeya.prefill-worker 2>/dev/null || true
223-
sleep 3
224-
launchctl bootstrap gui/$(id -u) \"$HOME/Library/LaunchAgents/ai.kakeya.prefill-worker.plist\"
225-
launchctl kickstart -k gui/$(id -u)/ai.kakeya.prefill-worker
222+
domain=gui/$(id -u)
223+
label=ai.kakeya.prefill-worker
224+
service=\"$domain/$label\"
225+
plist=\"$HOME/Library/LaunchAgents/$label.plist\"
226+
launchctl bootout \"$service\" 2>/dev/null || true
227+
for delay in 1 1 2 3 5; do
228+
if ! launchctl print \"$service\" >/dev/null 2>&1; then
229+
break
230+
fi
231+
sleep \"$delay\"
232+
done
233+
if launchctl print \"$service\" >/dev/null 2>&1; then
234+
echo \"worker service did not unload\" >&2
235+
exit 70
236+
fi
237+
loaded=0
238+
for delay in 1 2 3 5; do
239+
if launchctl bootstrap \"$domain\" \"$plist\"; then
240+
loaded=1
241+
break
242+
fi
243+
if launchctl print \"$service\" >/dev/null 2>&1; then
244+
loaded=1
245+
break
246+
fi
247+
sleep \"$delay\"
248+
done
249+
if [ \"$loaded\" -ne 1 ]; then
250+
echo \"worker service did not bootstrap\" >&2
251+
exit 71
252+
fi
253+
launchctl kickstart -k \"$service\"
254+
for attempt in $(seq 1 120); do
255+
if nc -G 2 -z 127.0.0.1 53051 >/dev/null 2>&1; then
256+
exit 0
257+
fi
258+
if ! launchctl print \"$service\" >/dev/null 2>&1; then
259+
echo \"worker service disappeared during startup\" >&2
260+
exit 72
261+
fi
262+
sleep 1
263+
done
264+
echo \"worker did not become ready on port 53051\" >&2
265+
exit 73
226266
"""
227267
subprocess.run(
228268
["ssh", "-o", "BatchMode=yes", worker_ssh, remote],
@@ -563,7 +603,14 @@ def run_iteration(args, iteration: int) -> dict:
563603
candidate_path.write_bytes(previous_candidate)
564604
_restore(state_path, previous_state)
565605
_restore(ledger_path, previous_ledger)
566-
deploy_candidate(args.worker_ssh, previous_chunk)
606+
try:
607+
deploy_candidate(args.worker_ssh, previous_chunk)
608+
except Exception as rollback_exc:
609+
print(
610+
"[autoresearch] phase=rollback-worker-failed "
611+
f"error={type(rollback_exc).__name__}: {rollback_exc}",
612+
flush=True,
613+
)
567614
raise
568615

569616

tests/inference_engine/bench/test_autoresearch_supervisor.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from autoresearch.prefill.supervisor import (
22
append_result,
33
best_kept,
4+
deploy_candidate,
45
parse_research_verdict,
56
read_results,
67
render_candidate,
@@ -139,6 +140,30 @@ def test_append_result_migrates_legacy_results_header(tmp_path):
139140
assert rows[1]["hypothesis_sha256"] == "sha"
140141

141142

143+
def test_worker_deploy_waits_for_unload_and_readiness(monkeypatch):
144+
captured = []
145+
146+
class Result:
147+
stdout = "--prefill-compute-chunk-tokens 128"
148+
149+
def fake_run(command, **kwargs):
150+
captured.append((command, kwargs))
151+
return Result()
152+
153+
monkeypatch.setattr(
154+
"autoresearch.prefill.supervisor._wait_port",
155+
lambda *_args: None,
156+
)
157+
monkeypatch.setattr("subprocess.run", fake_run)
158+
deploy_candidate("allens", 128)
159+
remote = captured[0][0][-1]
160+
assert captured[0][1]["check"] is True
161+
assert "worker service did not unload" in remote
162+
assert "launchctl bootstrap" in remote
163+
assert "nc -G 2 -z 127.0.0.1 53051" in remote
164+
assert "a[i+1]='128'" in remote
165+
166+
142167
def test_supervisor_predeploys_before_real_strategy_proposal():
143168
source = (
144169
Path(__file__).resolve().parents[3]

0 commit comments

Comments
 (0)