-
Notifications
You must be signed in to change notification settings - Fork 2
multi_tab_chat_architecture
github-actions[bot] edited this page Sep 20, 2026
·
1 revision
Multi-tab chat enables parallel, independent agent sessions within a single browser window. This architecture is built on a Session-First principle, ensuring that state is never leaked between tabs.
-
Session Isolation: Every tab is strictly bound to a unique
session_id. - Stateless Components: UI components (ChatArea, Sidebar) derive their entire state from the session configuration in the store.
-
Unified API Communication: All requests to the
agent_gobackend must include theX-Session-IDheader.
The global store tracks all active tabs and their configurations:
interface ChatTab {
id: string; // session_id
type: 'chat' | 'workflow';
config: TabConfig; // MCP servers, skills, browser settings, etc.
isRestoring: boolean;
}To prevent duplicate tabs from being created during simultaneous auto-restoration and manual session detection, the system uses a global sessionsBeingRestored Set.
- Check: Before creating a new tab, the system checks if the ID is in this set.
- Lock: If not present, it adds the ID and proceeds with tab creation.
- Release: Once the tab is fully initialized and events have been polled, the ID is removed from the set.
-
Header Injection: The
api.tsservice automatically injects theX-Session-IDheader into every request. -
Polling Scoping: The event polling mechanism (
PollingProvider) scopes its requests using the active tab's session ID. This ensures that the event stream only contains messages relevant to the current view. -
Session Stopping: When a tab is closed, the frontend explicitly calls
/api/session/stopto terminate any background LLM processes for that specific session.
- Creation: A tab is created via the "New Chat" button or by clicking a previous session in the history.
-
Configuration Injection: The
TabConfig(selected servers, browser mode, etc.) is loaded from the database or preset. -
Active Monitoring: The
PollingProviderstarts a long-polling loop for that session. - Persistence: Every message and configuration change is persisted to the backend SQLite database in real-time.
- Termination: Closing the tab removes it from the UI but keeps the session in history unless explicitly deleted.
- Strict Tab Activation: Switching tabs now triggers an immediate event poll to ensure the UI is up-to-date.
- Memory Management: Ephemeral chat tabs (those not yet saved to history) are automatically cleaned up if the user navigates away without sending a message.
- Cross-Tab Awareness: The "Stop" button in the toolbar correctly identifies which session to terminate, even if multiple agents are running in the background.
- Browser Tab Isolation: Multi-tab chat works within a single browser tab. Opening the app in two separate browser windows/tabs will create two independent polling loops, which may cause performance overhead on the backend.
Auto-synced from docs/ on main. Edit there, not here.