robit_agent/frontend.rs
1//! Frontend trait — abstract interface between Agent and UI.
2//!
3//! The Agent doesn't know whether the frontend is a TUI, Feishu bot, or QQ bot.
4//! It only interacts through this trait.
5
6use async_trait::async_trait;
7use tokio::sync::mpsc;
8
9use crate::error::Result;
10use crate::event::{AgentEvent, FrontendMessage};
11use crate::tool::ToolCallInfo;
12
13/// Abstract frontend interface. Implementations handle rendering events and
14/// collecting user input.
15#[async_trait]
16pub trait Frontend: Send + Sync {
17 /// Agent pushes events to the frontend (text deltas, tool calls, errors, etc.).
18 async fn on_event(&self, event: AgentEvent) -> Result<()>;
19
20 /// Request user confirmation for a tool call. Blocks until user responds.
21 /// Returns `true` if the user approved, `false` if rejected.
22 async fn request_tool_confirmation(&self, info: &ToolCallInfo) -> Result<bool>;
23}
24
25/// Channel pair for Agent <-> Frontend communication.
26///
27/// The Agent holds `event_tx` (to send events) and `message_rx` (to receive user messages).
28/// The Frontend holds the other ends.
29pub struct AgentChannels {
30 /// Agent uses this to send events to the Frontend.
31 pub event_tx: mpsc::Sender<AgentEvent>,
32 /// Agent uses this to receive messages from the Frontend.
33 pub message_rx: mpsc::Receiver<FrontendMessage>,
34}
35
36/// Frontend-side channel ends.
37pub struct FrontendChannels {
38 /// Frontend uses this to receive events from the Agent.
39 pub event_rx: mpsc::Receiver<AgentEvent>,
40 /// Frontend uses this to send messages to the Agent.
41 pub message_tx: mpsc::Sender<FrontendMessage>,
42}
43
44/// Create a matched pair of Agent and Frontend channels.
45pub fn create_channels(
46 event_buffer: usize,
47 message_buffer: usize,
48) -> (AgentChannels, FrontendChannels) {
49 let (event_tx, event_rx) = mpsc::channel(event_buffer);
50 let (message_tx, message_rx) = mpsc::channel(message_buffer);
51
52 let agent_channels = AgentChannels {
53 event_tx,
54 message_rx,
55 };
56
57 let frontend_channels = FrontendChannels {
58 event_rx,
59 message_tx,
60 };
61
62 (agent_channels, frontend_channels)
63}