fix(core): settle a non-interactive agent's status before its exception unwinds

An exception escaping a non-interactive cycle re-raised before the status
handling, so a dying child stayed 'running' and its parent waited out the
timeout on a completion report the child could no longer send. Set the
terminal status and wake the parent on the way out too.
This commit is contained in:
Ahmed Allam
2026-08-04 06:14:54 +03:00
committed by Ahmed Allam
parent 7a0693cd6f
commit 54eed025b1
2 changed files with 40 additions and 3 deletions
+33
View File
@@ -855,6 +855,39 @@ async def test_structured_provider_refusal_fails_noninteractive_child(
session.close()
@pytest.mark.asyncio
async def test_crashing_noninteractive_child_settles_and_wakes_its_parent(
monkeypatch: pytest.MonkeyPatch,
) -> None:
# The exception ends the child's task, so its status and the parent's wake-up
# have to be settled on the way out or the parent waits on a dead child.
def _boom(*_args: Any, **_kwargs: Any) -> Any:
raise RuntimeError("sandbox died mid-turn")
monkeypatch.setattr("strix.core.execution.Runner.run_streamed", _boom)
coordinator = AgentCoordinator()
await coordinator.register("root", "strix", parent_id=None)
await coordinator.register("child", "recon", parent_id="root")
with pytest.raises(RuntimeError, match="sandbox died mid-turn"):
await execution._run_cycle(
MagicMock(),
coordinator,
"child",
input_data="task",
run_config=MagicMock(),
context={"parent_id": "root"},
max_turns=5,
session=None,
interactive=False,
event_sink=None,
hooks=None,
)
assert coordinator.statuses["child"] == "crashed"
assert coordinator.pending_counts.get("root", 0) > 0
@pytest.mark.asyncio
async def test_run_agent_loop_seeds_identity_before_first_cycle(
tmp_path: Any, monkeypatch: pytest.MonkeyPatch