How OpenMAIC Manages Agent Sessions: Client-Side Persistence and Deep Linking
OpenMAIC manages agent sessions entirely on the client side using localStorage to persist workspace session IDs across page reloads, enabling seamless conversation continuity through URL-encoded deep links and a React hook that synchronizes URL state with pane descriptors.
The THU-MAIC/OpenMAIC repository implements a robust client-side session management system that treats each interactive chat as a workspace session. This architecture stores session identifiers in the browser's localStorage and coordinates state through specialized utility functions in the workbench layer, ensuring agents maintain conversation context across navigation events and browser refreshes.
The Workspace Session Architecture
OpenMAIC conceptualizes an agent session as a workspace unit that binds an interactive chat interface to a specific user-generated conversation. The system maintains strict separation between session state (the conversation thread) and course state (the educational content), allowing users to switch contexts without losing progress.
The architecture relies on three coordinated layers:
- Persistence Layer (
lib/workbench/workspace-session-memory.ts): Handles localStorage operations for session retention - Pane Descriptor Layer (
lib/workbench/workspace-panes.ts): Manages URL-serializable state objects containingsessionIdandcourseId - Integration Layer (
lib/workbench/use-workbench-session.ts): Connects React components to the persistence and pane systems
Core Session Management Functions
Session Persistence Layer (workspace-session-memory.ts)
The primary storage mechanism resides in lib/workbench/workspace-session-memory.ts, which exports utility functions for managing the session lifecycle. The module uses the constant LAST_WORKSPACE_SESSION_STORAGE_KEY to identify the most recently accessed session in localStorage.
Key functions include:
rememberWorkspaceSession(sessionId, storage): Persists a session ID as the "last opened" session when users initiate or switch conversationsreadLastWorkspaceSessionId(storage): Retrieves the stored session ID during application initializationvalidateRememberedWorkspaceSession(rememberedId, availableIds, storage): Verifies whether a stored session ID still exists in the current session list, clearing stale entries automaticallyforgetWorkspaceSession(sessionId, storage): Removes a session from localStorage and clears the remembered ID if it matches the deleted sessionworkspaceResumeHref(sessionId): Constructs deep-linkable URLs usingencodeURIComponentto safely encode session identifiers containing spaces or symbols, returning paths like/workspace?session=<encoded-id>
Pane State Descriptors (workspace-panes.ts)
The lib/workbench/workspace-panes.ts module defines the pane descriptor structure—an object containing { sessionId, courseId } pairs that represent the current workspace configuration. This separation allows independent navigation of courses and conversations.
The withSession(panes, newSessionId) function creates a new pane descriptor that preserves the current course while updating only the session component. This enables session switching without disrupting the user's educational context.
React Hook Integration (use-workbench-session.ts)
The lib/workbench/use-workbench-session.ts hook serves as the bridge between UI components and the session management infrastructure. It ensures:
- The current pane descriptor always reflects the URL query parameters
- Route changes update both the URL and the stored "last session" entry
- Agent backend requests include the current
sessionId, enabling the LLM to retrieve the correct conversation history
Session Lifecycle Implementation
Creating New Sessions
When a user sends their first message in a new conversation, OpenMAIC generates an opaque session ID using the pattern session-<uuid>. The application immediately invokes workspaceResumeHref(sessionId) to construct an encoded URL and navigates to /workspace?session=<encoded-id>, simultaneously calling rememberWorkspaceSession to persist the ID in localStorage.
import { workspaceResumeHref, rememberWorkspaceSession } from '@/lib/workbench/workspace-session-memory';
import { useRouter } from 'next/router';
function startNewSession() {
const id = `session-${crypto.randomUUID()}`;
const url = workspaceResumeHref(id);
router.push(url);
rememberWorkspaceSession(id, localStorage);
}
Restoring Sessions on Reload
During workspace initialization, the application calls readLastWorkspaceSessionId(localStorage) to retrieve the most recent session. If validateRememberedWorkspaceSession confirms the ID exists in the available sessions list, the application redirects to the encoded URL, restoring the exact conversation state prior to the refresh.
import { readLastWorkspaceSessionId, workspaceResumeHref } from '@/lib/workbench/workspace-session-memory';
import { useEffect } from 'react';
import { useRouter } from 'next/router';
function Workspace() {
const router = useRouter();
useEffect(() => {
const lastId = readLastWorkspaceSessionId(localStorage);
if (lastId) {
router.replace(workspaceResumeHref(lastId));
}
}, []);
}
Switching Between Sessions
Session switching utilizes withSession(panes, newSessionId) to generate an updated pane descriptor while preserving the currently open course. The UI updates the URL query parameter (session=) and invokes rememberWorkspaceSession to set the new default, enabling rapid context changes without full page reloads.
import { withSession, readWorkspacePanes } from '@/lib/workbench/workspace-panes';
import { rememberWorkspaceSession } from '@/lib/workbench/workspace-session-memory';
import { useRouter } from 'next/router';
function switchSession(newId: string) {
const panes = readWorkspacePanes(location.search);
const newPanes = withSession(panes, newId);
router.replace(`/workspace?session=${encodeURIComponent(newId)}${newPanes.courseId ? `&course=${newPanes.courseId}` : ''}`);
rememberWorkspaceSession(newId, localStorage);
}
Deleting and Cleanup
When users delete a session through the workspace rail interface (lib/workbench/workspace-rail-tab.ts), the system invokes forgetWorkspaceSession(sessionId, storage). This function removes the entry from localStorage and conditionally clears the remembered session ID if it matches the deleted session. The rail tab remains selected on the "sessions" view (isRailTab('sessions')), maintaining UI consistency while the underlying data updates.
Integration with Agent Backend
The session management system ensures that agents (the LLM backend components) receive the current sessionId with every request. This identifier allows the backend to fetch the appropriate conversation history, maintaining continuity even when users switch between multiple parallel discussions. The session title module manages display names independently from the underlying ID, enabling user-friendly renaming without breaking the session reference chain.
Summary
- Client-side persistence: OpenMAIC stores agent session IDs in localStorage using
LAST_WORKSPACE_SESSION_STORAGE_KEYto survive page reloads - Deep linking support: The
workspaceResumeHreffunction URL-encodes session identifiers for safe sharing and navigation - Pane separation: Session and course states remain independent through the
withSessionutility, allowing flexible context switching - Validation layer:
validateRememberedWorkspaceSessionprevents restoration of deleted or stale sessions - Hook integration:
use-workbench-session.tssynchronizes URL state, localStorage, and LLM backend requests
Frequently Asked Questions
Where are agent session IDs stored in OpenMAIC?
Agent session IDs persist in the browser's localStorage under the key defined by LAST_WORKSPACE_SESSION_STORAGE_KEY. The lib/workbench/workspace-session-memory.ts module provides rememberWorkspaceSession and readLastWorkspaceSessionId functions to write and retrieve these values, ensuring sessions survive browser refreshes without server-side storage.
How does OpenMAIC handle session persistence across browser refreshes?
On page load, the use-workbench-session.ts hook invokes readLastWorkspaceSessionId to retrieve the previously stored ID. It then calls validateRememberedWorkspaceSession to verify the ID exists in the current session list. If valid, the application redirects to workspaceResumeHref(lastId), restoring the exact conversation state through URL-encoded deep linking.
Can users deep-link to specific agent sessions in OpenMAIC?
Yes. The workspaceResumeHref function in lib/workbench/workspace-session-memory.ts uses encodeURIComponent to safely encode session IDs into URL query parameters (e.g., /workspace?session=session-abc123). Users can bookmark or share these URLs, and the validation logic ensures the session loads correctly if it still exists in localStorage.
What happens when a user deletes a workspace session?
The system invokes forgetWorkspaceSession(sessionId, localStorage), which removes the specific session entry from storage. If the deleted ID matches the currently remembered session, the function automatically clears LAST_WORKSPACE_SESSION_STORAGE_KEY, preventing the application from attempting to restore a non-existent session on the next reload. The UI updates immediately while preserving the current course context.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →