Session Management
Relevant source files
The following files were used as context for generating this wiki page:
Session management in the Open Claude Cowork application is a multi-layered system designed to maintain conversation state, persist chat history, and manage active AI provider connections. It bridges the frontend Electron renderer, the Node.js Express backend, and external AI SDKs (Claude Agent SDK and Opencode SDK) to ensure a seamless multi-turn conversation experience.
The system handles three primary types of sessions:
- Frontend Chat Sessions: Local persistence of message history, todos, and tool calls.
- Backend Provider Sessions: Mapping of local chat IDs to external SDK session identifiers.
- Tooling (Composio) Sessions: User-specific authentication sessions for executing MCP tool calls.
Sources: README.md:144-148, server/server.js:58-62
Frontend Session Persistence
The renderer process manages multiple concurrent chat sessions using a local state and localStorage for persistence across application restarts. Each session is identified by a unique chatId generated on the first message.
Data Structures and Storage
The frontend maintains an allChats array and a currentChatId. The session state is saved to localStorage under the keys allChats and currentChatId whenever a message is sent, a response completes, or a chat is switched.
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier (e.g., chat_1710...) |
title | String | Derived from the first message content |
messages | Array | Objects containing class (user/assistant), content, and rendered HTML |
todos | Array | Task list state from TodoWrite tool calls |
toolCalls | Array | History of tool executions and results |
provider | String | Selected AI provider (Claude/Opencode) |
model | String | Specific model used for the session |
Sources: renderer/renderer.js:52-120
Session Lifecycle Flow
The following diagram illustrates how the frontend initializes and switches between chat sessions.
Backend Provider Sessions
The backend manages the mapping between the client-side chatId and the provider-specific session IDs (e.g., Claude Agent SDK session IDs). This allows the application to "resume" conversations, maintaining full server-side context for the LLM.
Session Mapping Logic
The BaseProvider class (inherited by ClaudeProvider) maintains a sessions Map. In the ClaudeProvider, when a request is received, it checks if a session ID exists for the given chatId. If it does, it passes this ID as the resume option to the Claude Agent SDK.
Session ID Capture
The backend captures the session ID from the Claude Agent SDK's initial system message.
- Trigger: System message with
subtype: 'init'. - Storage: The
newSessionIdis stored in the provider's local session map. - Persistence: This map is transient (in-memory) on the server but is reconciled using the persistent
chatIdsent by the renderer.
Sources: server/providers/claude-provider.js:103-125
Composio and Tooling Sessions
The application integrates with Composio for tool execution, which requires its own session management for user authentication and MCP (Model Context Protocol) server URL routing.
Initialization
Upon server startup, a default Composio session is pre-initialized to provide an MCP URL. For subsequent user requests, a session is either retrieved from composioSessions (a Map keyed by userId) or created on the fly.
// server/server.js:75-86
let composioSession = composioSessions.get(userId);
if (!composioSession) {
console.log('[COMPOSIO] Creating new session for user:', userId);
composioSession = await composio.create(userId);
composioSessions.set(userId, composioSession);
// Update opencode.json with the MCP config for Opencode provider
updateOpencodeConfig(composioSession.mcp.url, composioSession.mcp.headers);
}
MCP Configuration
The session's MCP URL and headers are passed into the AI provider's query options. This ensures that tool calls made during a session are routed through the correct authenticated tunnel.
Sources: server/server.js:25-50, server/server.js:100-110
Request Aborting and Cleanup
Active sessions can be interrupted. The system provides an abort mechanism to stop both client-side streaming and server-side processing.
- Client-Side: The
preload.jsscript manages acurrentAbortControllerthat cancels thefetchrequest. - Server-Side: The
/api/abortendpoint instructs the specific provider (e.g.,ClaudeProvider) to invokeabort()on theAbortControllerassociated with thatchatId. - Cleanup: On abortion, the
abortControllersmap in the provider is cleared to prevent memory leaks.
Sources: preload.js:11-20, server/providers/claude-provider.js:34-45, server/server.js:175-200
Session Configuration Summary
| Feature | Provider: Claude | Provider: Opencode |
|---|---|---|
| Resumption | Via resume option with SDK session ID | Per-chat conversation state |
| Storage Location | SDK Server-side + Local Map | SDK Server-side + Local Map |
| Tracking ID | session_id | Part of conversation stream |
| Skills Context | settingSources: ['user', 'project'] | Project-based |
Sources: README.md:144-155, server/providers/claude-provider.js:65-75
The robust session management system ensures that users can maintain long-term workflows, track complex tasks through the Todo system, and switch between multiple concurrent tasks without losing progress or context.