pub trait Agent: Send + Sync {
// Required methods
fn name(&self) -> &str;
fn dependencies(&self) -> &[ContextKey];
fn accepts(&self, ctx: &Context) -> bool;
fn execute(&self, ctx: &Context) -> AgentEffect;
}Expand description
A semantic capability that observes context and emits effects.
§Contract
Agents must:
- Declare their dependencies (which context keys they care about)
- Be pure in
accepts()— no side effects - Only read context in
execute()— never mutate - Return effects, not modify state directly
Agents must NOT:
- Call other agents
- Control execution flow
- Decide when to terminate
§Example
ⓘ
struct SeedAgent;
impl Agent for SeedAgent {
fn name(&self) -> &str { "SeedAgent" }
fn dependencies(&self) -> &[ContextKey] { &[] }
fn accepts(&self, ctx: &Context) -> bool {
!ctx.has(ContextKey::Seeds)
}
fn execute(&self, _ctx: &Context) -> AgentEffect {
AgentEffect::with_fact(Fact { ... })
}
}Required Methods§
Sourcefn dependencies(&self) -> &[ContextKey]
fn dependencies(&self) -> &[ContextKey]
Context keys this agent depends on.
The engine uses this to build the dependency index. An agent is only considered for re-evaluation when one of its dependencies changes.
Return &[] for agents that should run on every cycle
(e.g., seed agents that check for absence of data).
Sourcefn accepts(&self, ctx: &Context) -> bool
fn accepts(&self, ctx: &Context) -> bool
Returns true if this agent should execute given the current context.
This must be:
- Pure (no side effects)
- Deterministic (same context → same result)
- Fast (called frequently)
Sourcefn execute(&self, ctx: &Context) -> AgentEffect
fn execute(&self, ctx: &Context) -> AgentEffect
Execute the agent’s logic and return effects.
The agent receives immutable access to context.
All contributions must be returned as an AgentEffect.
This may:
- Read context
- Call external tools (LLMs, APIs)
- Perform computation
This must NOT:
- Mutate any shared state
- Call other agents
- Block indefinitely (respect timeouts)