Add a Plugin
Use this for cross-cutting behavior such as policy checks, approval gates, reminders, and observability.
Prerequisites
- You know which phase should emit behavior (
RunStart,BeforeInference,BeforeToolExecute,AfterToolExecute,RunEnd, etc.). - Plugin side effects are explicit and bounded.
Steps
- Implement
AgentBehaviorand assign a stableid(). - Return phase actions with
ActionSet<...>from the phase hooks you need. - Register behavior in
AgentOsBuilder::with_registered_behavior("id", plugin). - Attach behavior id in
AgentDefinition.behavior_idsorwith_behavior_id(...).
Minimal Pattern
use async_trait::async_trait;
use tirea::contracts::runtime::phase::{ActionSet, BeforeInferenceAction};
use tirea::contracts::{AgentBehavior, ReadOnlyContext};
struct AuditBehavior;
#[async_trait]
impl AgentBehavior for AuditBehavior {
fn id(&self) -> &str {
"audit"
}
async fn before_inference(
&self,
_ctx: &ReadOnlyContext<'_>,
) -> ActionSet<BeforeInferenceAction> {
ActionSet::single(BeforeInferenceAction::AddSystemContext(
"Audit: request entering inference".to_string(),
))
}
}
Verify
- Behavior hook runs at the intended phase.
- Event/thread output contains expected behavior side effects.
- Runs are unchanged when behavior preconditions are not met.
Common Errors
- Registering behavior but forgetting to include its id in
AgentDefinition.behavior_ids. - Using the wrong phase (effect appears too early or too late).
- Unbounded mutations in a behavior, making runs hard to reason about.
Related Example
examples/src/travel.rsshows a productionLLMMetryPluginregistration pathexamples/src/starter_backend/mod.rswires permission and tool-policy behaviors into multiple agents
Key Files
crates/tirea-contract/src/runtime/behavior.rscrates/tirea-agentos/src/composition/builder.rscrates/tirea-extension-reminder/src/lib.rscrates/tirea-extension-permission/src/plugin.rs