pub struct AgentSupervisor<P: Platform> { /* private fields */ }Expand description
Manages the lifecycle of kernel-managed agent processes.
The supervisor sits between the CLI/API surface and the core
AgentLoop, providing:
- Spawn: creates a process entry, assigns capabilities, allocates a PID, and tracks the agent in the process table.
- Stop: signals cancellation (graceful) or immediate termination.
- Restart: stops then re-spawns with the same configuration.
- Inspect: returns full process entry with capabilities and resource usage.
- Watch: returns a receiver for process state changes.
The supervisor does not own the actual AgentLoop execution; that
remains the responsibility of the caller (kernel boot or CLI).
Instead, the supervisor manages the process table entries and
provides the cancellation tokens that control agent lifecycle.
Implementations§
Source§impl<P: Platform> AgentSupervisor<P>
impl<P: Platform> AgentSupervisor<P>
Sourcepub fn new(
process_table: Arc<ProcessTable>,
kernel_ipc: Arc<KernelIpc>,
default_capabilities: AgentCapabilities,
) -> Self
pub fn new( process_table: Arc<ProcessTable>, kernel_ipc: Arc<KernelIpc>, default_capabilities: AgentCapabilities, ) -> Self
Create a new agent supervisor.
§Arguments
process_table- Shared process table (also held by Kernel)kernel_ipc- IPC subsystem for sending lifecycle signalsdefault_capabilities- Capabilities assigned to agents that don’t specify their own
Sourcepub fn with_a2a_router(
self,
a2a_router: Arc<A2ARouter>,
cron_service: Arc<CronService>,
) -> Self
pub fn with_a2a_router( self, a2a_router: Arc<A2ARouter>, cron_service: Arc<CronService>, ) -> Self
Configure A2A router and cron service.
When set, spawn_and_run will create per-agent inboxes via the
A2ARouter and pass the cron service handle to the agent work loop.
Sourcepub fn a2a_router(&self) -> Option<&Arc<A2ARouter>>
pub fn a2a_router(&self) -> Option<&Arc<A2ARouter>>
Get the A2A router (if configured).
Sourcepub fn cron_service(&self) -> Option<&Arc<CronService>>
pub fn cron_service(&self) -> Option<&Arc<CronService>>
Get the cron service (if configured).
Sourcepub fn with_exochain(
self,
tree_manager: Option<Arc<TreeManager>>,
chain_manager: Option<Arc<ChainManager>>,
) -> Self
pub fn with_exochain( self, tree_manager: Option<Arc<TreeManager>>, chain_manager: Option<Arc<ChainManager>>, ) -> Self
Configure exochain integration (tree + chain managers).
When set, agent spawn/stop/restart events are recorded in the resource tree and hash chain.
Sourcepub fn spawn(&self, request: SpawnRequest) -> KernelResult<SpawnResult>
pub fn spawn(&self, request: SpawnRequest) -> KernelResult<SpawnResult>
Spawn a new supervised agent process.
This creates a process table entry and returns the assigned PID.
The actual agent execution (AgentLoop) must be started separately
by the caller using the returned SpawnResult and the
cancellation token from the process entry.
§Errors
Returns KernelError::ProcessTableFull if the process table
has reached its maximum capacity.
Sourcepub fn spawn_and_run<F, Fut>(
&self,
request: SpawnRequest,
work: F,
) -> KernelResult<SpawnResult>
pub fn spawn_and_run<F, Fut>( &self, request: SpawnRequest, work: F, ) -> KernelResult<SpawnResult>
Spawn a supervised agent and run its work as a tokio task.
Unlike spawn, this method also:
- Transitions the process to
Running - Registers the agent in the resource tree (if exochain enabled)
- Spawns a tokio task to execute the provided work closure
- On completion: transitions to
Exited, unregisters from tree, logs chain events, and cleans up the task handle
The work closure receives the assigned PID and a
CancellationToken; it should return an exit code (0 = success).
§Errors
Returns KernelError::ProcessTableFull if the process table
has reached its maximum capacity.
Sourcepub fn stop(&self, pid: Pid, graceful: bool) -> KernelResult<()>
pub fn stop(&self, pid: Pid, graceful: bool) -> KernelResult<()>
Stop a supervised agent process.
If graceful is true, the process is moved to Stopping state
and its cancellation token is cancelled, allowing the agent to
finish its current work. If graceful is false, the process is
immediately moved to Exited(-1).
Stopping an already-exited process is idempotent and returns Ok.
§Errors
Returns KernelError::ProcessNotFound if the PID is not in
the process table.
Sourcepub fn restart(&self, pid: Pid) -> KernelResult<SpawnResult>
pub fn restart(&self, pid: Pid) -> KernelResult<SpawnResult>
Restart a supervised agent process.
Stops the existing process (gracefully), then spawns a new one
with the same agent_id and capabilities. The new process gets
a fresh PID; the old entry remains in the table with
Exited(0) state.
The parent_pid of the new process is set to the restarted
PID, creating a restart lineage.
§Errors
Returns KernelError::ProcessNotFound if the PID is not in
the process table.
Sourcepub fn inspect(&self, pid: Pid) -> KernelResult<ProcessEntry>
pub fn inspect(&self, pid: Pid) -> KernelResult<ProcessEntry>
Inspect a supervised agent process.
Returns a clone of the full ProcessEntry including
capabilities and resource usage.
§Errors
Returns KernelError::ProcessNotFound if the PID is not in
the process table.
Sourcepub fn list_by_state(&self, state: ProcessState) -> Vec<ProcessEntry>
pub fn list_by_state(&self, state: ProcessState) -> Vec<ProcessEntry>
List processes filtered by state.
Sourcepub fn list_agents(&self) -> Vec<ProcessEntry>
pub fn list_agents(&self) -> Vec<ProcessEntry>
List all running agent processes (excludes kernel PID 0).
Sourcepub fn process_table(&self) -> &Arc<ProcessTable>
pub fn process_table(&self) -> &Arc<ProcessTable>
Get a reference to the shared process table.
Sourcepub fn default_capabilities(&self) -> &AgentCapabilities
pub fn default_capabilities(&self) -> &AgentCapabilities
Get the default capabilities assigned to new agents.
Sourcepub fn running_count(&self) -> usize
pub fn running_count(&self) -> usize
Count running processes (excluding kernel PID 0).
Sourcepub fn running_task_count(&self) -> usize
pub fn running_task_count(&self) -> usize
Get the number of actively tracked running agent tasks.
Sourcepub async fn watchdog_sweep(&self) -> Vec<(Pid, i32)>
pub async fn watchdog_sweep(&self) -> Vec<(Pid, i32)>
Sweep finished agent handles that were not cleaned up normally.
Iterates running_agents, checks is_finished() on each
JoinHandle, and for any that are finished:
- Removes the handle from the map
- If the process table still shows
Running, transitions toExited(-2)(watchdog reap) orExited(-3)(panic reap) - Logs a chain event (when exochain is enabled)
Returns a list of (pid, exit_code) for all reaped processes.
Sourcepub async fn shutdown_all(&self, timeout: Duration) -> Vec<(Pid, i32)>
pub async fn shutdown_all(&self, timeout: Duration) -> Vec<(Pid, i32)>
Gracefully shut down all running agents with a timeout.
- Cancels all agent cancellation tokens via the process table
- Drains all JoinHandles from
running_agents - Waits for all tasks to complete, with a timeout
- On timeout, aborts any remaining tasks
Returns a list of (pid, exit_code) for all agents.
Sourcepub fn tree_manager(&self) -> Option<&Arc<TreeManager>>
pub fn tree_manager(&self) -> Option<&Arc<TreeManager>>
Get the tree manager (when exochain feature is enabled).
Sourcepub fn chain_manager(&self) -> Option<&Arc<ChainManager>>
pub fn chain_manager(&self) -> Option<&Arc<ChainManager>>
Get the chain manager (when exochain feature is enabled).
Auto Trait Implementations§
impl<P> Freeze for AgentSupervisor<P>
impl<P> !RefUnwindSafe for AgentSupervisor<P>
impl<P> Send for AgentSupervisor<P>
impl<P> Sync for AgentSupervisor<P>
impl<P> Unpin for AgentSupervisor<P>where
P: Unpin,
impl<P> UnsafeUnpin for AgentSupervisor<P>
impl<P> !UnwindSafe for AgentSupervisor<P>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more