feat: capture worker artifacts before teardown and carry native limits
All checks were successful
ci / validate (push) Successful in 2m39s
All checks were successful
ci / validate (push) Successful in 2m39s
Assistant: codex Assistant-Model: gpt-5.6-luna Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
44991600f3
commit
fb57c0228f
9 changed files with 159 additions and 3 deletions
|
|
@ -553,3 +553,47 @@ def test_reachability_preparation_failure_is_reported_and_destroyed():
|
|||
assert 'private owner detail' not in str(post.call_args)
|
||||
assert rein.calls == []
|
||||
manager.destroy.assert_called_once_with('sbx1')
|
||||
|
||||
|
||||
def test_artifact_capture_occurs_after_cleanup_before_destroy():
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
rein = _FakeRein()
|
||||
order = []
|
||||
rein.cleanup_session = lambda session: order.append("cleanup")
|
||||
manager.destroy.side_effect = lambda sandbox: order.append("destroy")
|
||||
def capture(sandbox, summary):
|
||||
assert summary.commit_sha == "deadbeef"
|
||||
assert sandbox._owner_execute is not None
|
||||
order.append("capture")
|
||||
result = run_execution(_request(), catalog=_catalog_with_readiness(), rein=rein,
|
||||
manager=manager, artifact_capture=capture)
|
||||
assert result.ok
|
||||
assert order == ["cleanup", "capture", "destroy"]
|
||||
assert "bundle" not in result.model_dump_json()
|
||||
|
||||
|
||||
def test_artifact_capture_failure_still_destroys_sandbox():
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
def capture(*args):
|
||||
raise ValueError("invalid artifact")
|
||||
result = run_execution(_request(), catalog=_catalog_with_readiness(), rein=_FakeRein(),
|
||||
manager=manager, artifact_capture=capture)
|
||||
assert not result.ok
|
||||
assert result.evidence.failure_stage == "artifact_capture"
|
||||
assert result.evidence.sandbox_destroy == "succeeded"
|
||||
manager.destroy.assert_called_once_with("sbx1")
|
||||
|
||||
|
||||
def test_cleanup_failure_never_captures_artifact():
|
||||
manager = MagicMock()
|
||||
manager.create.return_value = _fake_status()
|
||||
rein = _FakeRein()
|
||||
rein.cleanup_session = MagicMock(side_effect=ValueError("cleanup"))
|
||||
capture = MagicMock()
|
||||
result = run_execution(_request(), catalog=_catalog_with_readiness(), rein=rein,
|
||||
manager=manager, artifact_capture=capture)
|
||||
assert not result.ok
|
||||
capture.assert_not_called()
|
||||
manager.destroy.assert_called_once()
|
||||
|
|
|
|||
|
|
@ -210,3 +210,19 @@ def test_cleanup_session_removes_only_generated_task_file() -> None:
|
|||
{"transport": transport, "task_file": "/sandbox/task.json", "generated_task_file": False}
|
||||
)
|
||||
transport.remove_file.assert_not_called()
|
||||
|
||||
|
||||
def test_profile_native_limits_are_carried_in_owned_task_file():
|
||||
from glas_harness.contract import ExecutionLimits
|
||||
profile = ProfileCatalog().resolve("harness.agent-dev-local@1.0.0")[0].model_copy(update={
|
||||
"limits":ExecutionLimits(max_budget_usd=.25,max_turns=3,timeout_seconds=30)})
|
||||
transport=MagicMock(spec=ExecutionTransport)
|
||||
transport.workspace="/sandbox"
|
||||
transport.git_head.return_value="a"*40
|
||||
rein=ReinAharness()
|
||||
with patch("glas_harness.reins.rein_aharness.transport_from_sandbox",return_value=transport):
|
||||
rein.start_session(profile,{"title":"task","description":"prompt asks for unlimited money"},SandboxHandle(sandbox_id="fixture",host="localhost"))
|
||||
assert transport.write_task_file.call_args.args[0]["max_budget_usd"] == .25
|
||||
assert transport.write_task_file.call_args.args[0]["max_turns"] == 3
|
||||
with pytest.raises(ValueError,match="Glas-generated"):
|
||||
rein.start_session(profile,{"task_file":"/untrusted.json"},object())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue