TUI Architecture Documentation
Overviewβ
The Radium TUI (Terminal User Interface) is a unified prompt-based interface built with ratatui that provides an interactive CLI experience for working with AI agents, orchestration, and MCP integrations. This document describes the architecture, component structure, and design patterns used throughout the TUI implementation.
Architecture Diagramβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β main.rs β
β - Terminal initialization (crossterm) β
β - Event loop (keyboard input polling) β
β - Render loop (ratatui frame drawing) β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β App β
β - Main application state β
β - Keyboard event handling β
β - Command execution β
β - Orchestration service integration β
β - MCP integration β
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββ¬βββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β PromptData β β SetupWizard β
β - Input buffer β β - State machine β
β - Output buffer β β - Provider selection β
β - Conversation history β β - API key input β
β - Command suggestions β β - Credential storage β
β - Command palette β ββββββββββββββββββββββββββββββββ
βββββββββββββ¬ββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Views Layer β
β - prompt.rs - Main unified prompt interface β
β - header.rs - Header with session info β
β - splash.rs - Startup splash screen β
β - loading.rs - Loading indicators β
β - markdown.rs - Markdown rendering β
β - sessions.rs - Session list view β
β - model_selector.rs - Model selection UI β
β - split.rs - Split view for complex workflows β
βββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Components Layer β
β - output_window.rs - Output display with scrolling β
β - agent_timeline.rs - Agent execution timeline β
β - telemetry_bar.rs - Token/metrics display β
β - checkpoint_modal.rs - Checkpoint management UI β
β - log_viewer.rs - Log viewing component β
β - loop_indicator.rs - Loop execution indicator β
β - status_footer.rs - Status footer β
βββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β State Layer β
β - workflow_state.rs - Workflow execution tracking β
β - agent_state.rs - Individual agent state β
β - telemetry_state.rs - Token/metrics tracking β
β - checkpoint_state.rs - Checkpoint management β
β - OutputBuffer - Bounded output buffer β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Core Componentsβ
1. Application Entry Point (main.rs)β
The entry point initializes the terminal, sets up logging, and runs the main event loop.
Key Responsibilities:
- Terminal setup (raw mode, alternate screen)
- Splash screen rendering
- Event polling and routing to
App - Frame rendering coordination
Event Flow:
Terminal Event β crossterm β main.rs β App::handle_key() β State Update β Render
2. Application Core (app.rs)β
The App struct is the central coordinator for all TUI functionality.
State Management:
PromptData- Unified prompt interface stateSetupWizard- Optional setup wizard stateWorkspaceStatus- Workspace initialization stateOrchestrationService- AI orchestration integrationMcpIntegration- MCP tool integration
Key Methods:
handle_key()- Routes keyboard events to appropriate handlersexecute_command()- Executes slash commands (/help,/chat, etc.)handle_orchestrated_input()- Routes natural language to orchestrationsend_chat_message()- Sends messages to AI agents
Event Routing:
Keyboard Event β App::handle_key()
ββ Setup wizard active? β SetupWizard::handle_key()
ββ Command palette active? β Update palette suggestions
ββ Slash command? β execute_command()
ββ Regular input β handle_orchestrated_input() or send_chat_message()
3. Unified Prompt Interface (views/prompt.rs)β
The PromptData struct and render_prompt() function provide a unified interface that adapts to different display contexts.
Display Contexts:
Chat- Active chat session with an agentAgentList- List of available agentsSessionList- List of chat sessionsDashboard- System dashboardHelp- Help informationModelSelector- Model selection interface
Key Features:
- Command autocomplete with suggestions
- Command palette (Ctrl+P) with fuzzy search
- Scrollback buffer for conversation history
- Markdown rendering for agent responses
4. Setup Wizard (setup.rs)β
State machine-based wizard for first-time user setup.
States:
Welcome- Initial welcome screenProviderSelection- Select AI providers (Gemini, OpenAI)ApiKeyInput- Enter API key for selected providerValidating- Validating API key (future)Complete- Setup complete
State Transitions:
Welcome β ProviderSelection β ApiKeyInput β Complete
β β
ββββββββββββββββββββββ (Esc to go back)
5. State Management (state/)β
Modular state management for workflow execution and agent tracking.
Workflow State (workflow_state.rs)β
Tracks overall workflow execution:
- Workflow status (Idle, Running, Paused, Completed, Failed, Cancelled)
- Step progression
- Agent registration and state
- Output buffer management
- Telemetry tracking
Agent State (agent_state.rs)β
Tracks individual agent execution:
- Agent status and sub-agent states
- Execution timeline
- Output per agent
Telemetry State (telemetry_state.rs)β
Tracks token usage and metrics:
- Input/output token counts
- Cost estimation
- Request timing
Checkpoint State (checkpoint_state.rs)β
Manages workflow checkpoints:
- Checkpoint creation and restoration
- Checkpoint metadata
Output Buffer (state/mod.rs)β
Bounded buffer for output lines:
- Fixed capacity (default 1000 lines)
- Automatic oldest-line removal
- Scroll position management
- Viewport culling support
6. View Components (views/)β
View modules handle rendering of different UI contexts.
Prompt View (prompt.rs)β
- Main unified interface rendering
- Context-aware content display
- Command palette overlay
- Markdown rendering integration
Header View (header.rs)β
- Session information display
- Status indicators
- Branding
Markdown View (markdown.rs)β
- Converts markdown text to ratatui
Lineobjects - Supports bold, italic, code, lists
- Handles code blocks
Model Selector (model_selector.rs)β
- Model selection interface
- Provider grouping
- Default model indication
Sessions View (sessions.rs)β
- Session list display
- Session metadata (message count, last active)
Split View (split.rs)β
- Side-by-side content display
- Useful for complex workflows
7. UI Components (components/)β
Reusable UI components for specific functionality.
Output Window (output_window.rs)β
- Displays
OutputBuffercontent - Scroll indicators
- Status line with scroll position
- Split view support
Agent Timeline (agent_timeline.rs)β
- Visual timeline of agent execution
- Status indicators per agent
- Sub-agent hierarchy
Telemetry Bar (telemetry_bar.rs)β
- Token usage display
- Cost estimation
- Request metrics
Checkpoint Modal (checkpoint_modal.rs)β
- Checkpoint creation UI
- Checkpoint restoration interface
Log Viewer (log_viewer.rs)β
- Structured log display
- Log level filtering
Loop Indicator (loop_indicator.rs)β
- Visual indicator for loop execution
- Iteration count
Status Footer (status_footer.rs)β
- Bottom status bar
- Contextual information
Event Flowβ
Keyboard Input Flowβ
1. crossterm polls for events (main.rs)
2. Event received β App::handle_key()
3. Route based on current state:
- Setup wizard active? β SetupWizard::handle_key()
- Command palette active? β Update palette
- Slash command? β Command::parse() β execute_command()
- Regular input? β handle_orchestrated_input() or send_chat_message()
4. State updated in App/PromptData
5. Next frame render β views render updated state
Command Execution Flowβ
1. User types "/chat agent-1"
2. Command::parse() creates Command struct
3. App::execute_command() matches command name
4. Command handler executes:
- Loads agent configuration
- Creates/retrieves session
- Updates DisplayContext to Chat
- Updates PromptData with agent info
5. Next render shows chat interface
Orchestration Flowβ
1. User types natural language (no "/")
2. App::handle_orchestrated_input() called
3. OrchestrationService processes input
4. Service determines actions/agents needed
5. Execution happens asynchronously
6. Results streamed to conversation buffer
7. UI updates with streaming output
Integration Pointsβ
radium_core Integrationβ
Authentication:
CredentialStore- API key storage and retrievalProviderType- AI provider enumeration
Workspace:
Workspace- Workspace initialization and management
Agents:
- Agent discovery from
./agents/or~/.radium/agents/ - Agent configuration loading
MCP:
McpIntegration- MCP server connection and tool executionSlashCommandRegistry- MCP-provided slash commands
Orchestration Service Integrationβ
Initialization:
OrchestrationServicecreated with workspace config- Service handles natural language input
- Routes to appropriate agents/tools
Event Handling:
- Completion events streamed to UI
- Progress updates via telemetry
- Error handling and recovery
Design Patternsβ
1. State Machine Patternβ
Used in SetupWizard for managing setup flow:
- Clear state transitions
- State-specific behavior
- Error recovery
2. Component-Based UIβ
Views and components are modular:
- Reusable components
- Clear separation of concerns
- Easy to test and maintain
3. Event-Driven Architectureβ
Async/await for AI interactions:
- Non-blocking UI updates
- Streaming responses
- Concurrent operations
4. Unified Interface Patternβ
Single PromptData struct adapts to multiple contexts:
- Reduces code duplication
- Consistent user experience
- Easy to add new contexts
Configurationβ
Theme System (theme.rs)β
The RadiumTheme struct provides consistent colors:
- Primary/secondary brand colors
- Status colors (success, warning, error, info)
- Text and background colors
- Border colors
Currently hardcoded, but designed for future config file support.
Workspace Configurationβ
Workspace initialized from:
- Current directory (if
.radium/exists) ~/.radium/(fallback)
Testing Strategyβ
Unit Testsβ
State modules have comprehensive unit tests:
workflow_state.rs- Workflow lifecycle testsstate/mod.rs- OutputBuffer tests
Integration Testsβ
Located in apps/tui/tests/:
integration_test.rs- Basic integration testsorchestration_commands_test.rs- Orchestration command tests
Test Fixturesβ
Common test scenarios:
- Mock credential store
- Mock workspace
- Mock AI responses
Performance Considerationsβ
Current Limitationsβ
- Output Buffer: Limited to 1000 lines (good)
- Conversation History: Grows unbounded (needs optimization)
- Rendering: Full re-render on every frame (needs viewport culling)
- Markdown: Parsed on every render (could be cached)
Optimization Opportunitiesβ
- Viewport Culling: Only render visible lines
- Conversation Limits: Archive old messages to disk
- Markdown Caching: Cache parsed markdown
- Incremental Rendering: Only re-render changed areas
Future Enhancementsβ
- Theme Customization: Config file support for themes
- Keyboard Shortcuts Help: In-app shortcut reference
- Performance Optimization: Viewport culling and conversation limits
- Plugin System: Extensible command system
- Multi-language Support: i18n for internationalization
File Structureβ
apps/tui/src/
βββ main.rs # Entry point, event loop
βββ app.rs # Main application logic
βββ lib.rs # Library exports
βββ commands.rs # Command parsing
βββ setup.rs # Setup wizard
βββ theme.rs # Theme system
βββ icons.rs # Status icons
βββ errors.rs # Error handling
βββ workspace.rs # Workspace initialization
βββ session_manager.rs # Session management
βββ chat_executor.rs # Chat execution
βββ navigation.rs # Navigation helpers
βββ views/ # View layer
β βββ prompt.rs # Main prompt interface
β βββ header.rs # Header view
β βββ splash.rs # Splash screen
β βββ loading.rs # Loading indicators
β βββ markdown.rs # Markdown rendering
β βββ sessions.rs # Session list
β βββ model_selector.rs # Model selection
β βββ split.rs # Split view
βββ components/ # Reusable components
β βββ output_window.rs
β βββ agent_timeline.rs
β βββ telemetry_bar.rs
β βββ checkpoint_modal.rs
β βββ log_viewer.rs
β βββ loop_indicator.rs
β βββ status_footer.rs
βββ state/ # State management
βββ workflow_state.rs
βββ agent_state.rs
βββ telemetry_state.rs
βββ checkpoint_state.rs
βββ mod.rs
API Referenceβ
Appβ
pub struct App {
pub should_quit: bool,
pub prompt_data: PromptData,
pub current_agent: Option<String>,
pub current_session: Option<String>,
pub setup_complete: bool,
pub available_commands: Vec<(&'static str, &'static str)>,
pub setup_wizard: Option<SetupWizard>,
pub workspace_status: Option<WorkspaceStatus>,
pub orchestration_service: Option<Arc<OrchestrationService>>,
pub orchestration_enabled: bool,
pub mcp_integration: Option<Arc<Mutex<McpIntegration>>>,
pub mcp_slash_registry: SlashCommandRegistry,
}
impl App {
pub fn new() -> Self;
pub async fn handle_key(&mut self, key: KeyCode, modifiers: KeyModifiers) -> Result<()>;
pub async fn execute_command(&mut self, cmd: Command) -> Result<()>;
pub async fn handle_orchestrated_input(&mut self, input: String) -> Result<()>;
pub async fn send_chat_message(&mut self, message: String) -> Result<()>;
}
PromptDataβ
pub struct PromptData {
pub context: DisplayContext,
pub input: String,
pub output: Vec<String>,
pub conversation: Vec<String>,
pub agents: Vec<(String, String)>,
pub sessions: Vec<(String, usize)>,
pub selected_index: usize,
pub command_suggestions: Vec<String>,
pub selected_suggestion_index: usize,
pub scrollback_offset: usize,
pub command_palette_active: bool,
pub command_palette_query: String,
}
impl PromptData {
pub fn new() -> Self;
pub fn push_char(&mut self, c: char);
pub fn pop_char(&mut self);
pub fn clear_input(&mut self);
pub fn add_output(&mut self, line: String);
pub fn clear_output(&mut self);
}
SetupWizardβ
pub enum SetupState {
Welcome,
ProviderSelection { selected_providers: Vec<ProviderType>, cursor: usize },
ApiKeyInput { provider: ProviderType, input: String },
Validating { provider: ProviderType },
Complete,
}
pub struct SetupWizard {
pub state: SetupState,
pub error_message: Option<String>,
}
impl SetupWizard {
pub fn new() -> Self;
pub fn new_skip_welcome() -> Self;
pub fn is_needed() -> bool;
pub async fn handle_key(&mut self, key: KeyCode, modifiers: KeyModifiers) -> Result<bool>;
pub fn display_lines(&self) -> Vec<String>;
pub fn title(&self) -> String;
}
WorkflowUIStateβ
pub enum WorkflowStatus {
Idle,
Running,
Paused,
Completed,
Failed,
Cancelled,
}
pub struct WorkflowUIState {
pub workflow_id: String,
pub workflow_name: String,
pub status: WorkflowStatus,
pub start_time: Option<Instant>,
pub end_time: Option<Instant>,
pub current_step: usize,
pub total_steps: usize,
pub agents: HashMap<String, AgentState>,
pub output_buffer: OutputBuffer,
pub telemetry: TelemetryState,
pub checkpoint: CheckpointState,
pub error_message: Option<String>,
}
impl WorkflowUIState {
pub fn new(workflow_id: String, workflow_name: String, total_steps: usize) -> Self;
pub fn start(&mut self);
pub fn pause(&mut self);
pub fn resume(&mut self);
pub fn complete(&mut self);
pub fn fail(&mut self, error: String);
pub fn cancel(&mut self);
pub fn next_step(&mut self);
pub fn register_agent(&mut self, agent_id: String, agent_name: String);
pub fn progress_percentage(&self) -> u8;
}
Conclusionβ
The TUI architecture follows a clear separation of concerns with modular components, state management, and view layers. The unified prompt interface provides a consistent user experience while supporting multiple display contexts. The event-driven, async architecture ensures responsive UI updates during AI interactions.
For questions or contributions, refer to the main project documentation and development guidelines.