Module supervisor — supervision of child agents
🟢 The module lets a parent agent launch child agents,
subscribe to selected events of its children, and receive an injection into
its own context when an event matches — optionally pausing
the child. No hooks are needed in the child: this is an external control-plane on top of the event bus
(events.subscribers) and the public port agent_os.Agents.
Tool supervisor
A single tool kind: supervisor with a action field:
action |
Fields | What it does |
|---|---|---|
spawn |
template, task?, session_key? |
non-blocking launch of a child; returns pid |
subscribe |
event?, inject, child?, role?, pause_child?, resume_after?, run_turn?, once? |
parent subscribes to child events; returns id |
unsubscribe |
id |
unsubscribe |
subscriptions |
— | list active subscriptions |
send |
pid, content, role? |
inject a message into the child |
pause / resume |
pid |
pause/resume the child |
stop |
pid, signal? |
pause | interrupt | terminate (default interrupt) |
status |
pid |
snapshot of the child process |
session |
pid, limit? |
live session of a running child: the latest messages of its context (role, content, tool_call_id, tool_calls); limit defaults to 50 |
Subscription and delivery
- Selector
event(all fields optional):{ kind?, tool?, success?, contains? }—kindfromProcessEvent::event_type(tool_call,tool_result,error, …). inject— MiniJinja (witheventin context), inserted into the parent's context.pause_child— pause the child before injection;resume_after— immediately resume after;run_turn— non-blockingly start the parent's turn (otherwise the parent will see the injection on its next turn);once— remove after the first trigger.- Targeting:
child: <pid>— a specific child; withoutchild— any child of the parent (resolved viaAgents.process(pid).parent). - Operations on a specific child (
send/pause/resume/stop/status/session) are allowed only for a direct child of the caller.
Shipped agent observer
The module ships, as a config bundle, a ready-made observer agent observer
(agents/observer/): it declares tool_files: [tools/supervisor.yaml] and owns
all supervise actions — spawn, subscribe, session, send,
pause/resume/stop. It is loaded alongside config/agents/ when the
module is enabled (a same-named agent from config/agents wins). A typical scenario:
observer launches coder and watches for its crashes.
Example
The tool can also be declared in your own agent:
# config/agents/supervisor-agent/tools/supervisor.yaml
kind: supervisor
name: supervise
description: Запускай код-агента и следи за его падениями.
{ "action": "spawn", "template": "coder", "task": "Почини сборку" }→pid.{ "action": "subscribe", "child": "<pid>", "event": { "kind": "tool_result", "success": false }, "inject": "Crashed: {{ event.content }}. Help fix it.", "pause_child": true, "resume_after": true, "run_turn": true }.- The parent works independently; when the child crashes, it receives an injection into its context (the child is optionally paused).
{ "action": "session", "pid": "<pid>", "limit": 50 }— see what the child is doing right now.
Global rules (alternative)
For declarative rules not tied to a specific parent, there is the
reactions module: the inject actions (including target: parent) and
signal let you notify/stop a process from a rule.