# How the Agent Workbench Manages Durable Sessions Across Server Restarts

> Discover how the Agent Workbench ensures durable sessions persist through server restarts by using localStorage and server validation for seamless workspace continuity.

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

---

**The OpenMAIC Agent Workbench persists the last-opened session ID in the browser’s `localStorage` and validates it against the server’s live session catalogue on startup, enabling seamless workspace resumption even after server restarts or browser closures.**

The THU-MAIC/OpenMAIC repository implements a robust durability mechanism that decouples session continuity from server runtime state. Rather than relying on ephemeral server-side memory, the Workbench stores a reference to the active workspace session client-side, then verifies its validity against the backend’s current session list. This approach ensures users can close their browser—or experience a full server restart—and still return to their exact workspace context.

## Client-Side Persistence Architecture

The durability strategy centers on the `localStorage` API, which survives browser restarts and server outages. When a user opens a workspace, the Workbench writes the current session identifier to a dedicated storage key defined as `LAST_WORKSPACE_SESSION_STORAGE_KEY`. This key stores the ID in URL-encoded format, ensuring safe string handling across page reloads.

Because the session token resides in the browser rather than server memory, the Workbench’s durability is independent of backend process lifecycles. The server merely provides a catalogue of currently active sessions, and the client-side logic in [`lib/workbench/workspace-session-memory.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/workspace-session-memory.ts) determines whether the remembered session can safely resume.

## The Session Recovery Workflow

Resuming a session follows a strict four-phase pipeline implemented in [`workspace-session-memory.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/workspace-session-memory.ts). Each phase is exposed as a discrete utility function to ensure testability and clear separation of concerns.

### Step 1: Persisting the Active Session

When a workspace gains focus, the Workbench calls `rememberWorkspaceSession(sessionId, storage)` to record the identifier. This function writes the encoded session ID to `localStorage` under the dedicated workspace key, establishing the durability anchor.

```typescript
import { rememberWorkspaceSession } from '@/lib/workbench/workspace-session-memory';

// Store the current session when the workspace opens
rememberWorkspaceSession('session-42', window.localStorage);

```

### Step 2: Reading the Stored Session

On every page load—including those following a server restart—the Workbench invokes `readLastWorkspaceSessionId(storage)` to retrieve the previously stored identifier. This function returns the decoded session ID or `null` if no valid entry exists.

```typescript
import { readLastWorkspaceSessionId } from '@/lib/workbench/workspace-session-memory';

// Retrieve the last-opened session on application startup
const lastId = readLastWorkspaceSessionId(window.localStorage);
// → 'session-42' or null if the storage is empty

```

### Step 3: Validating Against Server State

The critical durability check occurs in `validateRememberedWorkspaceSession(storedId, loadedSessionIds, storage)`. This function compares the client-side memory against the array of live session IDs fetched from the backend. If the stored ID is absent from the server’s list—indicating the session expired or was deleted during the outage—the function purges the stale entry from `localStorage` and returns `null`.

```typescript
import { validateRememberedWorkspaceSession } from '@/lib/workbench/workspace-session-memory';

const liveIds = ['session-42', 'session-99']; // Fetched from the backend API
const validId = validateRememberedWorkspaceSession(
  lastId,
  liveIds,
  window.localStorage
);
// → 'session-42' if valid, or null if the session no longer exists

```

If validation fails, the Workbench triggers a fallback mechanism defined in [`lib/workbench/workspace-rail-tab.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/workspace-rail-tab.ts), redirecting the user to the default “sessions” rail rather than attempting to resurrect a dead workspace.

### Step 4: Building the Resume URL

Once validation succeeds, `workspaceResumeHref(sessionId)` constructs the navigation target. This function returns a formatted URL string pointing to `/workspace?session=<encodedId>`, allowing the application router to restore the exact workspace context.

```typescript
import { workspaceResumeHref } from '@/lib/workbench/workspace-session-memory';

const href = workspaceResumeHref(validId!);
// → '/workspace?session=session-42'

```

## Implementation Details in workspace-session-memory.ts

The core logic resides in [`lib/workbench/workspace-session-memory.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/workspace-session-memory.ts), which exports the four primary functions governing session lifecycle memory. The module handles URL encoding automatically to prevent injection issues and storage corruption, ensuring that session identifiers containing special characters survive the round-trip through `localStorage`.

The companion test suite in [`tests/workbench/workspace-session-memory.test.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tests/workbench/workspace-session-memory.test.ts) provides comprehensive coverage of the durability logic, including edge cases such as malformed storage entries, empty server catalogues, and concurrent session overwrites. These tests verify that the Workbench correctly forgets invalid sessions and maintains storage hygiene.

## Handling Stale Sessions and Fallback Behavior

When `validateRememberedWorkspaceSession` detects a mismatch between the stored ID and the server’s live session list, it immediately clears the obsolete entry from `localStorage` to prevent infinite retry loops. The UI layer in [`lib/workbench/workspace-rail-tab.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/workspace-rail-tab.ts) detects this null state and renders the default sessions list, allowing users to select a valid workspace or create a new one. This validation step is crucial for maintaining consistency after server restarts, which wipe volatile session state while potentially preserving the session catalogue in persistent storage.

## Summary

- **Client-side storage**: The Workbench uses `localStorage` with `LAST_WORKSPACE_SESSION_STORAGE_KEY` to survive server restarts.
- **Validation layer**: The `validateRememberedWorkspaceSession` function in [`workspace-session-memory.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/workspace-session-memory.ts) filters stale IDs against the server’s live session list.
- **Automatic cleanup**: Invalid sessions are purged from storage immediately upon detection, preventing dead links.
- **Graceful fallback**: When validation fails, [`workspace-rail-tab.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/workspace-rail-tab.ts) routes users to the default sessions rail.
- **URL generation**: Valid sessions resume via `workspaceResumeHref`, which constructs `/workspace?session=<id>` navigation targets.

## Frequently Asked Questions

### Where is the session ID physically stored?

The session ID is stored in the browser’s `localStorage` under the key `LAST_WORKSPACE_SESSION_STORAGE_KEY`. This client-side storage persists across browser restarts and server outages, providing the durability mechanism that allows the Workbench to remember your last workspace even after the backend process restarts.

### What happens if my session was deleted while the server was restarting?

The `validateRememberedWorkspaceSession` function checks the stored ID against the list of active sessions returned by the server. If the ID is not found in the live catalogue, the function removes the stale entry from `localStorage` and returns `null`, causing the Workbench to display the default “sessions” rail instead of attempting to open a non-existent workspace.

### Does this mechanism work across different browsers or devices?

No. Because the implementation relies on `localStorage`, which is scoped to the specific browser origin and device, a session remembered on one browser will not automatically appear on another. The durability is per-browser, not per-user account, ensuring privacy but limiting cross-device continuity.

### How does the Workbench handle the session list after a server restart?

The Workbench fetches the current session catalogue from the backend during initialization and passes it to `validateRememberedWorkspaceSession` as the `loadedSessionIds` parameter. The server restart may change which sessions are available, but the client-side validation logic ensures only currently valid sessions are resumed, while expired ones are silently discarded.