Chat UI & Composer
Relevant source files
The following files were used as context for generating this wiki page:
- src/renderer/components/chat/AgentChatPanel.tsx
- src/renderer/components/chat/ChatInputBar.tsx
- src/renderer/components/chat/use-chat-composer.ts
- src/renderer/components/chat/ChatMessage.tsx
- src/renderer/components/chat/composer/ChatComposerEditor.tsx
- src/renderer/components/chat/ChatInputBar.test.tsx
The Chat UI and Composer system provides the primary interface for user interaction with AI agents within the Termul environment. It handles message threading, rich-text input, attachment management, and agent-specific configurations. The system is designed to treat workspaces as first-class citizens, maintaining context-aware interactions through project-based sessions.
Sources: README.md:5-9, src/renderer/components/chat/AgentChatPanel.tsx:55-60
Architecture Overview
The Chat UI is structured into three primary layers: the host panel, the input bar, and the rich-text editor logic.
- AgentChatPanel: Acts as the top-level container for a specific session. It manages the message timeline, active turn status, and specific UI states like permission prompts and structured questions.
- ChatInputBar: Orchestrates the input surface, including attachment drop zones, command menus, and session configuration chips (models, modes, thinking levels).
- ChatComposerEditor: A Tiptap-based rich-text editor that handles specialized inline "pills" for skills, commands, and file mentions.
Component Relationship
The following diagram illustrates the data flow between the core Chat UI components:
The Chat Composer
The composer uses a sentinel-token format for the internal representation of specialized inputs. This format allows the editor to render interactive UI "pills" while maintaining a byte-identical wire payload for agent communication and draft persistence.
Input Tokenization
The composer identifies and manages three main types of inline tokens:
- Skill Tokens: Prefixed with
\uE002, represent specialized agent capabilities. - Command Tokens: Prefixed with
\uE004, representing slash commands like/compact. - File Tokens: Managed via
@mentions, representing project-local file references.
Sources: src/renderer/components/chat/use-chat-composer.ts:72-85, src/renderer/components/chat/ChatInputBar.tsx:455-465
Message Processing Flow
When a user submits a message, the composer processes the content through several stages to ensure the agent receives the correct context while the UI retains the rich formatting.
Feature Breakdown
| Feature | Implementation | Description |
|---|---|---|
| Draft Persistence | persistenceApi | Unsent messages are saved per-session to survive reloads. |
| Attachments | useComposerAttachments | Supports drag-and-drop and clipboard pasting of images and text. |
| Skill Selection | SlashCommandMenu | Triggered by /, allows users to insert specialized capability pills. |
| File Mentions | FileMentionMenu | Triggered by @, uses a ripgrep stream to find project files. |
| Context Indicator | ContextUsageIndicator | Visual ring showing token usage relative to the context window. |
Sources: src/renderer/components/chat/ChatInputBar.tsx:143-160, src/renderer/components/chat/ChatInputBar.tsx:238-250, src/renderer/components/chat/ChatInputBar.test.tsx:645-660
Attachment Handling
The composer supports structured content blocks, distinguishing between simple text and embedded resources.
- Image Capability: If
imageCapableis true, the composer accepts inline image blocks (drag/paste). - Embed Capability: If
embedCapableis true, the composer acceptsresourceblocks for text files. - Temp Cleanup: App-owned temporary files (like pasted screenshots) are registered with the session for cleanup upon session closure.
Sources: src/renderer/components/chat/ChatInputBar.tsx:75-85, src/renderer/components/chat/ChatInputBar.tsx:530-535
Responsive Toolbar
The ChatInputBar adjusts its layout based on the available pane width using the useComposerToolbarMode hook.
- Wide Mode: A single row containing all configuration chips and agent selectors.
- Narrow Mode: Chips are split into two scrollable rows to prevent stacking that would obscure the message timeline.
Sources: src/renderer/components/chat/ChatInputBar.tsx:635-675, src/renderer/components/chat/chat-responsive.test.tsx:210-235
Message Rendering
Messages are rendered in the ChatMessageList using the Streamdown engine for markdown and specialized renderers for Termul-specific content.
Renderer Logic
The ChatMessage component handles:
- Markdown Parsing: standard GFM plus code block enhancements.
- Skill Chips: Renders
\uE002sentinels asSkillChipcomponents. - Command Chips: Renders
/namepills for slash commands. - Inline Images: Resolves relative paths against the session CWD via
readAttachmentBytesin Tauri contexts.
Sources: src/renderer/components/chat/ChatMessage.tsx:254-275, src/renderer/components/chat/ChatMessage.test.tsx:240-265
Session Lifecycle and Rehydration
Sessions are identified by a unique sessionId and associated with a projectId.
- Rehydration: When a hidden chat tab becomes active,
AgentChatPanelchecks for a missing session record. If history exists, it invokesopenHistorySession. - Opening History: Prevents background spawning of agents by only triggering rehydration for visible panels.
- Turn Management: The
busystate disables sending new messages and enables theonCancelaction for the active turn.
Sources: src/renderer/components/chat/AgentChatPanel.tsx:180-200, src/renderer/components/chat/AgentChatPanel.tsx:435-445
The Chat UI & Composer system serves as a complex bridge between user intent and agent action, leveraging rich-text editing and structured data blocks to maintain high-fidelity communication within project contexts.