Skip to main content

talos_plugin/
handler.rs

1//! Hook handler traits and context.
2
3use std::path::PathBuf;
4use std::time::Duration;
5
6use async_trait::async_trait;
7
8use crate::event::{HookEvent, HookEventKind, TurnId};
9
10/// Shared context passed to every hook handler invocation.
11#[derive(Debug, Clone)]
12pub struct HookContext {
13    /// Current turn identifier.
14    pub turn_id: TurnId,
15    /// Workspace root associated with the agent.
16    pub workspace_root: PathBuf,
17}
18
19impl HookContext {
20    /// Creates a new hook context.
21    #[must_use]
22    pub fn new(turn_id: TurnId, workspace_root: PathBuf) -> Self {
23        Self {
24            turn_id,
25            workspace_root,
26        }
27    }
28}
29
30/// The outcome returned by an individual hook handler.
31#[derive(Debug)]
32pub enum HookResult {
33    /// Continue dispatching to the next subscribed handler.
34    Continue,
35    /// Stop dispatching and ask the caller to skip the wrapped action.
36    Skip,
37    /// Stop dispatching and deny the wrapped action.
38    Deny {
39        /// Human-readable denial reason.
40        reason: String,
41    },
42    /// Replace the current event and continue dispatching.
43    Modify(HookEvent<'static>),
44}
45
46/// A lifecycle hook handler.
47#[async_trait]
48pub trait HookHandler: Send + Sync {
49    /// Stable handler name used in logs and tests.
50    fn name(&self) -> &str;
51
52    /// Events this handler subscribes to.
53    fn subscribed(&self) -> &'static [HookEventKind];
54
55    /// Maximum time the framework will wait for `on_event`.
56    fn timeout(&self) -> Duration {
57        Duration::from_millis(500)
58    }
59
60    /// Handles a runtime event.
61    async fn on_event(&self, ctx: &HookContext, event: &mut HookEvent<'_>) -> HookResult;
62}