How OpenMAIC Manages and Persists Agent Sessions: Client-Side Durability Architecture

OpenMAIC manages agent sessions entirely on the client side using localStorage and URL query parameters, providing durability across page reloads through functions like rememberWorkspaceSession and readLastWorkspaceSessionId in lib/workbench/workspace-session-memory.ts.

OpenMAIC is an open-source educational AI platform developed by THU-MAIC where agent sessions represent individual chat conversations tied to specific workspaces. The system implements a robust client-side session management strategy that persists conversation state without server-side storage, enabling seamless recovery of agent interactions after browser refreshes.

Understanding Agent Session Architecture

In OpenMAIC, a workspace session serves as the atomic unit binding an interactive AI agent to a user-generated conversation. Unlike server-persisted session architectures, OpenMAIC treats the browser as the source of truth for session durability.

The architecture relies on three core mechanisms:

  • localStorage Persistence: Session identifiers survive page refreshes through the browser's localStorage API, accessible via lib/workbench/workspace-session-memory.ts.
  • Pane Descriptors: The application state maintains an immutable descriptor object { sessionId, courseId } defined in lib/workbench/workspace-panes.ts, separating session identity from course content.
  • URL Encoding: Session IDs are URL-encoded using encodeURIComponent within workspaceResumeHref to enable safe deep-linking and navigation.

The Session Memory Module

The lib/workbench/workspace-session-memory.ts file exports the primary interface for session durability. It exposes five critical functions that handle the complete lifecycle of an agent session identity:

  • rememberWorkspaceSession(sessionId, storage) — Persists the active session ID to localStorage under LAST_WORKSPACE_SESSION_STORAGE_KEY.
  • readLastWorkspaceSessionId(storage) — Retrieves the cached session identifier on application initialization.
  • validateRememberedWorkspaceSession(rememberedId, availableIds, storage) — Validates whether a remembered session still exists in the current session list.
  • forgetWorkspaceSession(sessionId, storage) — Removes a specific session from localStorage and clears the "last session" memory if matched.
  • workspaceResumeHref(sessionId) — Generates the navigation URL /workspace?session=<encoded-id> for deep-linking.

Creating and Initializing New Agent Sessions

When a user initiates their first message to an AI agent, OpenMAIC generates a cryptographically random session identifier and immediately persists it to both the URL and localStorage.

The initialization flow follows this sequence:

  1. Generate an opaque session ID using crypto.randomUUID() (prefixed with session-).
  2. Construct the resume URL via workspaceResumeHref(id), which encodes the identifier for query parameter safety.
  3. Navigate to /workspace?session=<encoded-id> using Next.js router.
  4. Store the ID via rememberWorkspaceSession to enable future restoration.
// Example initialization pattern used in OpenMAIC
import { workspaceResumeHref, rememberWorkspaceSession } from '@/lib/workbench/workspace-session-memory';
import { useRouter } from 'next/router';

function startNewAgentSession() {
  const sessionId = `session-${crypto.randomUUID()}`;
  const targetUrl = workspaceResumeHref(sessionId);
  const router = useRouter();
  
  router.push(targetUrl);
  rememberWorkspaceSession(sessionId, localStorage);
}

Restoring Sessions Across Page Reloads

Durability is achieved through the coordinated use of readLastWorkspaceSessionId and validateRememberedWorkspaceSession. When the workspace component mounts, it executes a validation routine to determine whether to resume the previous agent conversation or start fresh.

The restoration logic implemented in lib/workbench/use-workbench-session.ts performs the following:

  1. Query localStorage for the LAST_WORKSPACE_SESSION_STORAGE_KEY entry.
  2. Validate the retrieved ID against the array of available session IDs using validateRememberedWorkspaceSession.
  3. If valid, reconstruct the pane descriptor and navigate to the encoded URL.
  4. If invalid (session deleted or expired), clear the storage entry to prevent orphaned references.
// Restoration pattern from use-workbench-session.ts
import { readLastWorkspaceSessionId, validateRememberedWorkspaceSession } from '@/lib/workbench/workspace-session-memory';
import { useEffect } from 'react';
import { useRouter } from 'next/router';

function useSessionRestoration(availableSessionIds: string[]) {
  const router = useRouter();
  
  useEffect(() => {
    const rememberedId = readLastWorkspaceSessionId(localStorage);
    if (!rememberedId) return;
    
    const isValid = validateRememberedWorkspaceSession(
      rememberedId, 
      availableSessionIds, 
      localStorage
    );
    
    if (isValid) {
      router.replace(workspaceResumeHref(rememberedId));
    }
  }, []);
}

Switching Between Agent Sessions

OpenMAIC supports multiple concurrent agent conversations through immutable pane descriptor updates. The withSession helper function in lib/workbench/workspace-panes.ts creates a new pane state object that swaps the session identifier while preserving the current course context.

This functional approach ensures that changing conversations does not trigger unnecessary re-renders of course content or mutate existing state references.

import { withSession, readWorkspacePanes } from '@/lib/workbench/workspace-panes';
import { useRouter } from 'next/router';

function switchAgentSession(newSessionId: string) {
  const currentPanes = readWorkspacePanes(window.location.search);
  const updatedPanes = withSession(currentPanes, newSessionId);
  
  // Construct URL preserving courseId if present
  const params = new URLSearchParams();
  params.set('session', encodeURIComponent(updatedPanes.sessionId));
  if (updatedPanes.courseId) {
    params.set('course', updatedPanes.courseId);
  }
  
  router.push(`/workspace?${params.toString()}`);
}

Session Lifecycle Termination

When users delete an agent conversation, forgetWorkspaceSession ensures complete cleanup of durability artifacts. This function removes the specific entry from localStorage and, critically, clears the "last opened session" memory if the deleted ID matches the cached value.

This prevents the application from attempting to restore a non-existent session on the next page load, avoiding invalid workspace states.

import { forgetWorkspaceSession } from '@/lib/workbench/workspace-session-memory';

function deleteAgentSession(sessionId: string) {
  // Remove from conversation list...
  
  // Clean up durability layer
  forgetWorkspaceSession(sessionId, localStorage);
}

Integration with the Workspace Rail UI

The session management system integrates with the navigation interface through lib/workbench/workspace-rail-tab.ts. The rail component maintains the "sessions" tab as the default selection (isRailTab('sessions')), displaying the available agent conversations list managed by the memory utilities.

Session renaming operations update the display metadata without altering the underlying session ID, ensuring that durability links remain intact even when conversation titles change.

Summary

  • OpenMAIC manages agent sessions as client-side workspace sessions tied to immutable pane descriptors containing sessionId and courseId.
  • Durability is achieved through localStorage using rememberWorkspaceSession and readLastWorkspaceSessionId from lib/workbench/workspace-session-memory.ts.
  • Session switching uses immutable updates via withSession in lib/workbench/workspace-panes.ts to preserve course context while changing conversations.
  • URL encoding ensures safe deep-linking through workspaceResumeHref, which applies encodeURIComponent to session identifiers.
  • Lifecycle cleanup prevents orphaned references when sessions are deleted via forgetWorkspaceSession, which validates against the remembered session cache.

Frequently Asked Questions

How does OpenMAIC persist agent sessions without a database?

OpenMAIC leverages the browser's localStorage API to persist session identifiers. The function rememberWorkspaceSession stores the active session ID under LAST_WORKSPACE_SESSION_STORAGE_KEY, while readLastWorkspaceSessionId retrieves it on application mount. This client-side approach eliminates server-side storage dependencies while enabling session recovery across page reloads.

What happens if a remembered agent session is deleted?

The system validates remembered sessions using validateRememberedWorkspaceSession, which checks the stored ID against the array of currently available sessions. If the ID is not found (indicating deletion), the function automatically clears the localStorage entry to prevent restoration attempts of non-existent conversations.

Yes. OpenMAIC encodes session IDs into URL query parameters using workspaceResumeHref, which applies encodeURIComponent to handle special characters. This generates URLs in the format /workspace?session=<encoded-id>, allowing users to bookmark or share direct links to specific agent sessions.

How does switching sessions affect the current course content?

Session switching uses the immutable withSession helper from lib/workbench/workspace-panes.ts. This function returns a new pane descriptor that updates only the sessionId field while preserving the existing courseId. Consequently, users can change agent conversations without disrupting their current course context or triggering content reloads.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →