Skip to main content

agent_air_tui/widgets/
conversation.rs

1//! ConversationView trait for conversation/chat display widgets.
2//!
3//! This trait defines the interface for widgets that display conversation history,
4//! supporting streaming, tool messages, and session state management.
5
6use ratatui::{Frame, layout::Rect};
7use std::any::Any;
8
9use super::ToolStatus;
10use crate::themes::Theme;
11
12/// Trait for conversation/chat display widgets.
13///
14/// This trait is separate from the Widget trait - a ConversationView may also
15/// implement Widget, but this trait focuses specifically on conversation display
16/// functionality.
17///
18/// # Session State
19///
20/// ConversationView supports saving and restoring state for session switching:
21/// - `save_state()` returns an opaque state object
22/// - `restore_state()` restores from a previously saved state
23/// - `clear()` resets the view while preserving configuration
24///
25/// # Example Implementation
26///
27/// ```ignore
28/// impl ConversationView for MyChatView {
29///     fn add_user_message(&mut self, content: String) {
30///         self.messages.push(Message::user(content));
31///     }
32///     // ... implement other methods
33/// }
34/// ```
35pub trait ConversationView: Send + 'static {
36    // --- Message Operations ---
37
38    /// Add a user message to the conversation
39    fn add_user_message(&mut self, content: String);
40
41    /// Add an assistant message to the conversation
42    fn add_assistant_message(&mut self, content: String);
43
44    /// Add a system message to the conversation
45    fn add_system_message(&mut self, content: String);
46
47    // --- Streaming ---
48
49    /// Append text to the current streaming response
50    fn append_streaming(&mut self, text: &str);
51
52    /// Complete the streaming response and finalize it as a message
53    fn complete_streaming(&mut self);
54
55    /// Discard the streaming buffer without saving (used on cancel)
56    fn discard_streaming(&mut self);
57
58    /// Check if currently streaming a response
59    fn is_streaming(&self) -> bool;
60
61    // --- Tool Messages ---
62
63    /// Add a tool execution message
64    fn add_tool_message(&mut self, tool_use_id: &str, display_name: &str, display_title: &str);
65
66    /// Update the status of a tool message
67    fn update_tool_status(&mut self, tool_use_id: &str, status: ToolStatus);
68
69    // --- Scrolling ---
70
71    /// Scroll up by the implementation's scroll step
72    fn scroll_up(&mut self);
73
74    /// Scroll down by the implementation's scroll step
75    fn scroll_down(&mut self);
76
77    /// Enable auto-scroll and scroll to bottom (called when user submits a message)
78    fn enable_auto_scroll(&mut self);
79
80    // --- Rendering ---
81
82    /// Render the conversation view
83    ///
84    /// # Arguments
85    /// * `frame` - The ratatui frame to render to
86    /// * `area` - The area to render within
87    /// * `theme` - The current theme
88    /// * `pending_status` - Optional pending status message (e.g., "running tools...")
89    fn render(
90        &mut self,
91        frame: &mut Frame,
92        area: Rect,
93        theme: &Theme,
94        pending_status: Option<&str>,
95    );
96
97    // --- Animation ---
98
99    /// Advance the spinner animation (called periodically during activity)
100    fn step_spinner(&mut self);
101
102    // --- Session State ---
103
104    /// Save the current state for session switching
105    ///
106    /// Returns an opaque state object that can be restored later.
107    fn save_state(&self) -> Box<dyn Any + Send>;
108
109    /// Restore state from a previously saved state
110    ///
111    /// If the state cannot be downcast to the expected type, this is a no-op.
112    fn restore_state(&mut self, state: Box<dyn Any + Send>);
113
114    /// Clear conversation content while preserving configuration
115    ///
116    /// This resets messages, streaming state, and scroll position,
117    /// but keeps settings like title, theme configuration, and renderers.
118    fn clear(&mut self);
119}
120
121/// Type alias for conversation view factory functions.
122///
123/// A factory is called to create a new ConversationView instance,
124/// typically when creating a new session or clearing the current one.
125///
126/// # Example
127///
128/// ```ignore
129/// let factory: ConversationViewFactory = Box::new(|| {
130///     Box::new(ChatView::new()
131///         .with_title("My Agent")
132///         .with_initial_content(welcome_renderer))
133/// });
134/// ```
135pub type ConversationViewFactory = Box<dyn Fn() -> Box<dyn ConversationView> + Send + Sync>;