Skip to main content

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}