funera_core/event_bus/
tool_bus.rs1use 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}