Skip to main content

AgentRuntime

Trait AgentRuntime 

Source
pub trait AgentRuntime: Send + Sync {
    // Required methods
    fn provision<'life0, 'async_trait>(
        &'life0 self,
        spec: AgentSpec,
    ) -> Pin<Box<dyn Future<Output = Result<AgentId, RuntimeError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn recover<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<Recovered<AgentId>, RuntimeError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn start<'life0, 'life1, 'async_trait>(
        &'life0 self,
        id: &'life1 AgentId,
    ) -> Pin<Box<dyn Future<Output = Result<(), RuntimeError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn stop<'life0, 'life1, 'async_trait>(
        &'life0 self,
        id: &'life1 AgentId,
    ) -> Pin<Box<dyn Future<Output = Result<(), RuntimeError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn health<'life0, 'life1, 'async_trait>(
        &'life0 self,
        id: &'life1 AgentId,
    ) -> Pin<Box<dyn Future<Output = Result<RuntimeHealth, RuntimeError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn list<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<RuntimeStatus>, RuntimeError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn logs<'life0, 'life1, 'async_trait>(
        &'life0 self,
        id: &'life1 AgentId,
        tail: Option<usize>,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, RuntimeError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
}
Expand description

The capability the platform needs to run agents: provision, start, stop, health-check, and list managed instances. One trait per capability (hex rule 2); implemented by LocalProcessRuntime today, a container or control-plane adapter later.

Required Methods§

Source

fn provision<'life0, 'async_trait>( &'life0 self, spec: AgentSpec, ) -> Pin<Box<dyn Future<Output = Result<AgentId, RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Register an agent to be run, without starting it. Returns its AgentId.

Source

fn recover<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Recovered<AgentId>, RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Adopt the instances this backend is already running, so a restarted supervisor manages the fleet it left behind instead of a blank slate.

Every adapter must answer, and the answer must be honest — there is deliberately no default. A backend whose state dies with this process returns Recovered::Ephemeral rather than an empty list, because a caller cannot otherwise tell “nothing was running” from “I have no idea what is running”, and only the first of those is safe to report as an empty fleet.

Call it once at startup, before serving. Adoption is expected to be idempotent: re-adopting an instance already in the map is not an error.

Source

fn start<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 AgentId, ) -> Pin<Box<dyn Future<Output = Result<(), RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Start a provisioned agent. RuntimeError::AlreadyRunning if it is already live, RuntimeError::NotFound if it was never provisioned.

Source

fn stop<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 AgentId, ) -> Pin<Box<dyn Future<Output = Result<(), RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Stop a running agent. Idempotent: stopping an already-stopped agent is Ok. RuntimeError::NotFound if it was never provisioned.

Source

fn health<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 AgentId, ) -> Pin<Box<dyn Future<Output = Result<RuntimeHealth, RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Report an agent’s current RuntimeHealth.

Source

fn list<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<RuntimeStatus>, RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

List every provisioned agent with its current status.

Source

fn logs<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 AgentId, tail: Option<usize>, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>, RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

The agent’s captured output, oldest line first, limited to the last tail lines when given.

This is the one question an operator asks that health cannot answer: Unhealthy says the card probe is failing, not why, and the why is in the agent’s own log. Supervising something without being able to read what it printed makes every failure a matter of guessing.

Not every backend can capture output, so an adapter that cannot must say so with RuntimeError::Unsupported rather than return an empty list — “nothing was logged” and “I do not keep logs” send an operator to very different places. Same reasoning as Recovered::Ephemeral, and the reason there is deliberately no default implementation.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§