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§
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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,
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".