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