Skip to main content

distri_types/
hooks.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4use crate::{ExecutionResult, Message, PlanStep};
5
6#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq, Hash)]
7#[serde(rename_all = "snake_case")]
8pub enum HookKind {
9    PlanStart,
10    PlanEnd,
11    BeforeExecute,
12    StepEnd,
13}
14
15#[derive(Debug, Deserialize, Serialize, Clone)]
16pub struct HookContext {
17    pub agent_id: String,
18    pub thread_id: String,
19    pub task_id: String,
20    pub run_id: String,
21}
22
23impl HookContext {
24    pub fn from_parts(agent_id: &str, thread_id: &str, task_id: &str, run_id: &str) -> Self {
25        Self {
26            agent_id: agent_id.to_string(),
27            thread_id: thread_id.to_string(),
28            task_id: task_id.to_string(),
29            run_id: run_id.to_string(),
30        }
31    }
32}
33
34#[derive(Debug, Deserialize, Serialize, Clone)]
35pub struct HookMutation {
36    #[serde(default)]
37    pub dynamic_values: HashMap<String, serde_json::Value>,
38}
39
40impl HookMutation {
41    pub fn none() -> Self {
42        Self {
43            dynamic_values: HashMap::new(),
44        }
45    }
46}
47
48#[derive(Debug, Deserialize, Serialize, Clone)]
49pub struct InlineHookRequest {
50    pub hook: String,
51    pub hook_id: String,
52    pub context: HookContext,
53    pub timeout_ms: u64,
54    #[serde(default)]
55    pub fire_and_forget: bool,
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub message: Option<Message>,
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub plan: Option<Vec<PlanStep>>,
60    #[serde(default, skip_serializing_if = "Option::is_none")]
61    pub result: Option<ExecutionResult>,
62}
63
64#[derive(Debug, Deserialize, Serialize, Clone)]
65pub struct InlineHookResponse {
66    pub hook_id: String,
67    pub mutation: HookMutation,
68}