Agent Control Plane (ACP) — subagent spawning, session management, and runtime execution control.
ACP provides a control plane for managing agent execution with pause/resume/step/cancel capabilities and subagent spawning with thread binding.
AcpControlPlane— Central control plane managing subagents, threads, and sessionsExecutionController— Pause/resume/step/cancel state machine inserted into the agent's tool-call loop- Session Actor Loop — Per-session serial message queue (
mpsc::channel) withExecutionControllercoordination - ACP Actor Loop — Routes commands to the appropriate session actor
CrashRecoveryConfig— Automatic crash recovery with retry and backoff for subagents
The default agent builder closure receives the subagent id being constructed (Fn(&str) -> Result<Agent>), so the spawned Agent is tagged with it as Agent.agent_id. Subagent turn records (observe JSON files and SQLite metric rows) are therefore attributed to the subagent that handled them. Bridge agents (ExecuteForBridge, not named subagents) pass an empty id and keep their default identity.
| Mode | Behavior |
|---|---|
Run |
One-shot execution, context discarded after completion |
Session |
Persistent session, context kept across turns |
Idle ──▶ Running ──▶ Paused ◀──▶ Stepping
│ │ │
▼ ▼ ▼
Cancelled (terminal)
New— Isolated thread for the subagentParent— Inherit parent's threadThread(id)— Bind to a specific threadAuto— Automatic based on context
pub struct AcpControlPlane {
subagents: Arc<RwLock<HashMap<String, SubagentHandle>>>,
threads: Arc<RwLock<HashMap<String, ThreadContext>>>,
sessions: Arc<RwLock<HashMap<AcpSessionId, AcpSession>>>,
command_tx: mpsc::Sender<AcpCommand>,
max_iterations: usize,
}
pub struct ExecutionController {
state: RwLock<RuntimeState>,
notify: tokio::sync::Notify,
iteration: AtomicUsize,
}
pub enum AcpCommand {
ExecuteSession { agent, message, respond_to },
ExecuteRun { agent, message, respond_to },
ExecuteSessionWithProgress { agent, message, progress_cb, respond_to },
Pause { session_id },
Resume { session_id },
Step { session_id },
Cancel { session_id },
GetStatus { session_id, respond_to },
Shutdown,
}
pub enum RuntimeState {
Idle,
Running,
Paused,
Stepping,
Cancelled,
}
pub enum SpawnMode {
Run,
Session,
}
pub enum ThreadBinding {
New,
Parent,
Thread(String),
Auto,
}Gateway ──▶ AcpControlPlane ──▶ ACP Actor Loop
│
├──▶ Session Actor (serial queue)
│ └──▶ Agent::process_message()
│ └──▶ ExecutionController::check_and_wait()
└──▶ Session Actor 2
AcpSessionToolandAcpSpawnToolintools/expose ACP to the agentAgent::process_message_with_controller()checksExecutionControllerbetween iterationsSubagentHandleprovidescommand_txfor parent-child communication
- Subagent spawning with thread binding modes
- Session actor queue for serialized execution
- Execution controller with pause/resume/step/cancel
- Runtime state machine with atomic iteration counting
- Crash recovery with configurable retry and backoff
- Progress callback support for long-running sessions
- ACP tools for agent-facing subagent control
- Parent-child communication via command channels
- Subagent id tagging of constructed agents for per-subagent observability