Skip to main content

funera_core/event_bus/
react_bus.rs

1use crate::chat::message::FuneraMessage;
2use serde_json::Value as JsonValue;
3use tokio::sync::broadcast;
4
5#[derive(Debug, Clone)]
6pub struct ToolCallRequest {
7    pub index: usize,
8    pub call_id: String,
9    pub name: String,
10    pub args: JsonValue,
11}
12
13#[derive(Debug, Clone)]
14pub struct ToolCallResponse {
15    pub call_id: String,
16    pub name: String,
17    pub result: String,
18}
19
20#[derive(Debug, Clone)]
21pub struct ToolCallErrorInfo {
22    pub call_id: String,
23    pub name: String,
24    pub error: String,
25}
26
27#[derive(Debug, Clone)]
28pub enum ReactEvent {
29    TurnStart,
30    TurnEnd,
31    MessageQueued(FuneraMessage),
32    ToolExecRequest(ToolCallRequest),
33    ToolExecResponse(Result<ToolCallResponse, ToolCallErrorInfo>),
34    /// A tool call requires user approval before it can proceed.
35    #[cfg(feature = "security")]
36    ToolApprovalRequired {
37        call_id: String,
38        tool_name: String,
39        paths: Vec<PathBuf>,
40        reason: String,
41    },
42}
43
44#[derive(Debug, Clone)]
45pub struct ReactBus {
46    react_tx: broadcast::Sender<ReactEvent>,
47}
48
49impl ReactBus {
50    pub fn new() -> Self {
51        let (react_tx, _) = broadcast::channel(30);
52        Self { react_tx }
53    }
54
55    pub fn subscribe(&self) -> broadcast::Receiver<ReactEvent> {
56        self.react_tx.subscribe()
57    }
58    pub fn sender(&self) -> broadcast::Sender<ReactEvent> {
59        self.react_tx.clone()
60    }
61    pub fn send(&self, event: ReactEvent) -> anyhow::Result<usize> {
62        self.react_tx.send(event).map_err(|e| e.into())
63    }
64}
65
66impl Default for ReactBus {
67    fn default() -> Self {
68        Self::new()
69    }
70}