Preserve live trial results across cleanup timeouts
This commit is contained in:
parent
b59bee8844
commit
9f7913eaec
2 changed files with 49 additions and 25 deletions
|
|
@ -882,30 +882,33 @@ def fetch_remote_report(
|
||||||
) -> dict[str, Any] | None:
|
) -> dict[str, Any] | None:
|
||||||
report_path = f"/tmp/{report_prefix}-{run_id}.json"
|
report_path = f"/tmp/{report_prefix}-{run_id}.json"
|
||||||
unlink_line = " p.unlink()\n" if unlink else ""
|
unlink_line = " p.unlink()\n" if unlink else ""
|
||||||
proc = subprocess.run(
|
try:
|
||||||
[
|
proc = subprocess.run(
|
||||||
"ssh",
|
[
|
||||||
"-i",
|
"ssh",
|
||||||
str(SSH_KEY),
|
"-i",
|
||||||
"-o",
|
str(SSH_KEY),
|
||||||
"BatchMode=yes",
|
"-o",
|
||||||
"-o",
|
"BatchMode=yes",
|
||||||
"StrictHostKeyChecking=accept-new",
|
"-o",
|
||||||
VPS,
|
"StrictHostKeyChecking=accept-new",
|
||||||
"sudo -u teleo -H /home/teleo/.hermes/hermes-agent/venv/bin/python -",
|
VPS,
|
||||||
],
|
"sudo -u teleo -H /home/teleo/.hermes/hermes-agent/venv/bin/python -",
|
||||||
input=(
|
],
|
||||||
"import json\n"
|
input=(
|
||||||
"from pathlib import Path\n"
|
"import json\n"
|
||||||
f"p = Path({report_path!r})\n"
|
"from pathlib import Path\n"
|
||||||
"if p.exists():\n"
|
f"p = Path({report_path!r})\n"
|
||||||
" print(p.read_text(encoding='utf-8'))\n"
|
"if p.exists():\n"
|
||||||
f"{unlink_line}"
|
" print(p.read_text(encoding='utf-8'))\n"
|
||||||
),
|
f"{unlink_line}"
|
||||||
text=True,
|
),
|
||||||
capture_output=True,
|
text=True,
|
||||||
timeout=60,
|
capture_output=True,
|
||||||
)
|
timeout=180,
|
||||||
|
)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
return None
|
||||||
if proc.returncode != 0 or not proc.stdout.strip():
|
if proc.returncode != 0 or not proc.stdout.strip():
|
||||||
return None
|
return None
|
||||||
return json.loads(redact(proc.stdout.strip()))
|
return json.loads(redact(proc.stdout.strip()))
|
||||||
|
|
@ -966,7 +969,9 @@ def run_remote(
|
||||||
result["parsed"] = fetched
|
result["parsed"] = fetched
|
||||||
result["parsed_from_report_file"] = True
|
result["parsed_from_report_file"] = True
|
||||||
else:
|
else:
|
||||||
fetch_remote_report(run_id, report_prefix=report_prefix)
|
result["remote_report_cleanup_confirmed"] = (
|
||||||
|
fetch_remote_report(run_id, report_prefix=report_prefix) is not None
|
||||||
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,25 @@ def test_successful_stdout_is_redacted_before_json_parsing(monkeypatch) -> None:
|
||||||
assert secret not in json.dumps(result)
|
assert secret not in json.dumps(result)
|
||||||
|
|
||||||
|
|
||||||
|
def test_successful_stdout_survives_remote_report_cleanup_timeout(monkeypatch) -> None:
|
||||||
|
completed = subprocess.CompletedProcess([], 0, stdout=json.dumps({"run_id": "complete"}) + "\n", stderr="")
|
||||||
|
calls = 0
|
||||||
|
|
||||||
|
def fake_run(*args, **kwargs):
|
||||||
|
nonlocal calls
|
||||||
|
calls += 1
|
||||||
|
if calls == 1:
|
||||||
|
return completed
|
||||||
|
raise subprocess.TimeoutExpired(args[0], timeout=180)
|
||||||
|
|
||||||
|
monkeypatch.setattr(suite.subprocess, "run", fake_run)
|
||||||
|
|
||||||
|
result = suite.run_remote(prompts=[])
|
||||||
|
|
||||||
|
assert result["parsed"] == {"run_id": "complete"}
|
||||||
|
assert result["remote_report_cleanup_confirmed"] is False
|
||||||
|
|
||||||
|
|
||||||
def test_safety_gate_passes_only_for_complete_no_send_no_write_run() -> None:
|
def test_safety_gate_passes_only_for_complete_no_send_no_write_run() -> None:
|
||||||
report = safe_report()
|
report = safe_report()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue