Skip to main content

funera_core/event_bus/
tool_bus.rs

1use serde_json::Value as JsonValue;
2use tokio::sync::{mpsc, oneshot};
3
4use crate::event_bus::react_bus::ReactBus;
5use crate::re_act::tool::ToolCallError;
6
7pub struct ToolExecCommand {
8    pub call_id: String,
9    pub name: String,
10    pub args: JsonValue,
11    pub resp_tx: oneshot::Sender<Result<String, ToolCallError>>,
12    pub react_bus: Option<ReactBus>,
13}
14
15#[derive(Clone)]
16pub struct ToolBus {
17    exec_tx: mpsc::Sender<ToolExecCommand>,
18}
19
20impl ToolBus {
21    pub fn new() -> (Self, mpsc::Receiver<ToolExecCommand>) {
22        let (exec_tx, exec_rx) = mpsc::channel(10);
23        (Self { exec_tx }, exec_rx)
24    }
25
26    pub async fn execute(
27        &self,
28        call_id: String,
29        name: String,
30        args: JsonValue,
31        react_bus: Option<ReactBus>,
32    ) -> Result<String, ToolCallError> {
33        let (resp_tx, resp_rx) = oneshot::channel();
34        self.exec_tx
35            .send(ToolExecCommand {
36                call_id,
37                name,
38                args,
39                resp_tx,
40                react_bus,
41            })
42            .await
43            .map_err(|_| ToolCallError::ToolExecutionError(anyhow::anyhow!("tool bus closed")))?;
44        resp_rx
45            .await
46            .unwrap_or(Err(ToolCallError::ToolExecutionError(anyhow::anyhow!(
47                "tool executor dropped"
48            ))))
49    }
50}