# How OpenMAIC Manages Agent Sessions: Client-Side Persistence and Deep Linking

> Discover how OpenMAIC manages agent sessions client-side with localStorage persistence and deep linking for uninterrupted workspace continuity.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: internals
- Published: 2026-09-09

---

**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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/workspace-session-memory.ts)): Handles localStorage operations for session retention
- **Pane Descriptor Layer** ([`lib/workbench/workspace-panes.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/workspace-panes.ts)): Manages URL-serializable state objects containing `sessionId` and `courseId`
- **Integration Layer** ([`lib/workbench/use-workbench-session.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/workspace-session-memory.ts))

The primary storage mechanism resides in [`lib/workbench/workspace-session-memory.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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 conversations
- **`readLastWorkspaceSessionId(storage)`**: Retrieves the stored session ID during application initialization
- **`validateRememberedWorkspaceSession(rememberedId, availableIds, storage)`**: Verifies whether a stored session ID still exists in the current session list, clearing stale entries automatically
- **`forgetWorkspaceSession(sessionId, storage)`**: Removes a session from localStorage and clears the remembered ID if it matches the deleted session
- **`workspaceResumeHref(sessionId)`**: Constructs deep-linkable URLs using `encodeURIComponent` to safely encode session identifiers containing spaces or symbols, returning paths like `/workspace?session=<encoded-id>`

### Pane State Descriptors ([`workspace-panes.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/workspace-panes.ts))

The [`lib/workbench/workspace-panes.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/use-workbench-session.ts))

The [`lib/workbench/use-workbench-session.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.

```typescript
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.

```typescript
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.

```typescript
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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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_KEY` to survive page reloads
- **Deep linking support**: The **`workspaceResumeHref`** function URL-encodes session identifiers for safe sharing and navigation
- **Pane separation**: Session and course states remain independent through the **`withSession`** utility, allowing flexible context switching
- **Validation layer**: **`validateRememberedWorkspaceSession`** prevents restoration of deleted or stale sessions
- **Hook integration**: **[`use-workbench-session.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/use-workbench-session.ts)** synchronizes 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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.