Skip to main content

bamboo_agent_core/agent/
hooks.rs

1//! Agent lifecycle hook trait.
2//!
3//! Hooks are invoked at well-defined points in the agent loop (see
4//! [`AgentHookPoint`](bamboo_domain::AgentHookPoint)).
5//! They can inspect state, mutate session, and control flow via
6//! [`HookResult`](bamboo_domain::HookResult).
7
8use async_trait::async_trait;
9use bamboo_domain::{AgentHookPoint, HookPayload, HookResult};
10
11use super::types::Session;
12
13/// Trait for agent lifecycle hooks.
14///
15/// Implementations must be `Send + Sync` because hooks may be invoked
16/// from multiple concurrent agent runs.
17#[async_trait]
18pub trait AgentHook: Send + Sync {
19    /// Which hook point this hook subscribes to.
20    fn point(&self) -> AgentHookPoint;
21
22    /// Execute the hook.
23    ///
24    /// Receives immutable access to the session, the current hook point, and a
25    /// point-specific payload.
26    /// Returns a [`HookResult`] to control flow.
27    async fn run(
28        &self,
29        point: AgentHookPoint,
30        payload: &HookPayload,
31        session: &Session,
32    ) -> HookResult;
33
34    /// Whether this hook applies to the point-specific payload.
35    ///
36    /// The default accepts every payload. Configured tool hooks override this
37    /// to apply their tool-name matcher without spawning a process or emitting
38    /// a misleading execution checkpoint for non-matching calls.
39    fn matches(&self, _payload: &HookPayload) -> bool {
40        true
41    }
42
43    /// Whether this hook can request a resumable suspension. Unknown native
44    /// hooks conservatively can. Hosts may declare a hook non-suspending only
45    /// when it never returns `Suspend`; violating that declaration aborts the
46    /// operation rather than creating a wait. The declaration is frozen at
47    /// registration. Allow/Deny/Ask remain independent.
48    fn may_suspend(&self) -> bool {
49        true
50    }
51
52    /// Optional priority (lower runs first). Default is 100.
53    fn priority(&self) -> u32 {
54        100
55    }
56
57    /// Optional name for logging and debugging.
58    fn name(&self) -> &str {
59        "unnamed_hook"
60    }
61}