feat(run-loop): lift the interactive continuation loop — applies to all agents

The previous commit only kept the root agent alive across cycles. But
``interactive`` propagates to children via ``make_child_factory``, and
the legacy harness's continuation loop applied to every interactive
agent in the tree — children also stayed alive after ``agent_finish``,
ready to receive follow-up messages from the parent or siblings.

Lift the demo-loop pattern out of ``entry.run_strix_scan`` into a
shared helper :func:`strix.run_loop.run_with_continuation` and use it
at both call sites:

- ``entry.run_strix_scan`` for the root agent.
- ``tools.agents_graph.tools.create_agent`` for child agents — the
  ``asyncio.create_task(Runner.run(...))`` becomes
  ``asyncio.create_task(run_with_continuation(...))``.

``StrixOrchestrationHooks.on_agent_end`` drops the ``parent_id is None``
constraint — any interactive agent parks instead of finalizing.
Children that crash still finalize so parents stop waiting on them.

Cancellation propagates correctly: ``bus.cancel_descendants`` cancels
the task; ``run_with_continuation``'s ``await bus.wait_for_message``
catches ``CancelledError`` and returns the last result.

Lint at baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
0xallam
2026-04-25 17:02:44 -07:00
parent 00f5ab33d6
commit 1afd1766cb
4 changed files with 127 additions and 61 deletions
+8 -4
View File
@@ -21,11 +21,12 @@ import logging
import uuid
from typing import TYPE_CHECKING, Any, Literal
from agents import RunContextWrapper, Runner, function_tool
from agents import RunContextWrapper, function_tool
from agents.items import TResponseInputItem
from strix.orchestration.hooks import StrixOrchestrationHooks
from strix.run_config_factory import make_agent_context, make_run_config
from strix.run_loop import run_with_continuation
if TYPE_CHECKING:
@@ -464,13 +465,16 @@ async def create_agent(
)
task_handle = asyncio.create_task(
Runner.run(
child_agent,
input=initial_input,
run_with_continuation(
agent=child_agent,
initial_input=initial_input,
run_config=child_run_config,
context=child_ctx,
hooks=StrixOrchestrationHooks(),
max_turns=int(inner.get("max_turns", 300)),
bus=bus,
agent_id=child_id,
interactive=bool(inner.get("interactive", False)),
),
name=f"agent-{name}-{child_id}",
)