How the OpenMAIC Agent Runtime Handles Sessions: Architecture and Lifecycle

The OpenMAIC agent runtime manages sessions as opaque identifiers that bind user conversations to specific classroom states, coordinating between server-side session creation, URL-based routing, and localStorage persistence to maintain isolated conversational contexts.

The THU-MAIC/OpenMAIC repository implements a sophisticated agent runtime session handling system that treats each session as a unique identifier sandboxing conversation history while maintaining associations with specific course contexts. This architecture enables students to maintain multiple parallel conversations with AI agents, each tied to distinct learning materials, without state bleeding between contexts.

Core Components of the Session Architecture

URL Generation and Routing (session-urls.ts)

Located at lib/server/agent-runtime/session-urls.ts, this module generates type-safe URLs for session operations. The workspaceResumeHref(sessionId) function encodes session identifiers for safe inclusion in workspace URLs, while sessionCreateUrl() points to the /api/agent/sessions endpoint. These utilities ensure that session transitions remain bookmarkable and shareable through standard HTTP routes.

Client-Side Persistence (workspace-session-memory.ts)

The lib/workbench/workspace-session-memory.ts file manages the last-opened session in the browser's localStorage. Key functions include:

  • rememberWorkspaceSession(id, storage) — Stores the ID under LAST_WORKSPACE_SESSION_STORAGE_KEY
  • readLastWorkspaceSessionId(storage) — Retrieves the stored identifier
  • forgetWorkspaceSession(id, storage) — Removes stale entries when sessions are deleted
  • validateRememberedWorkspaceSession(id, loadedIds, storage) — Validates that remembered IDs still exist among currently loaded sessions

Pane State Management (workspace-panes.ts)

The runtime represents the UI layout through "panes" defined in lib/workbench/workspace-panes.ts. Each pane maintains a sessionId and courseId pair. Functions like withSession(panes, newSessionId) and withCourse(panes, newCourseId) update specific dimensions while preserving the other, enabling users to switch sessions without losing their current course context. The workspaceLayout(panes) function returns 'session', 'course', or 'both' to control the visible interface layout.

The Session Lifecycle

Creating a New Session

Session creation begins with a POST request to /api/agent/sessions. The agent server generates a fresh, opaque sessionId, records the owner, and returns the identifier as JSON. This server-side generation guarantees uniqueness while establishing the initial ownership context for the conversation.

Persisting Session State

After creation, the client persists the session using rememberWorkspaceSession(newSessionId, localStorage). Simultaneously, the application updates the browser URL via workspaceResumeHref(sessionId), encoding the identifier as a query parameter for subsequent page loads.

Resuming Sessions from URLs

When users navigate to the workspace, lib/server/agent-runtime/resume.ts parses the ?session= query parameter. The resume.ts module validates the identifier and reconstructs the agent's conversation context, loading the associated classroom state and history. This URL-driven approach enables deep-linking to specific conversational contexts.

Switching Between Sessions

Users can switch sessions via the session rail interface. The runtime invokes withSession(currentPanes, 'new-session-id') to update the pane state while optionally preserving the courseId. This operation updates the URL to reflect the new session without triggering a full page reload, maintaining the existing course context when applicable.

Cleanup and Validation

When sessions are deleted, forgetWorkspaceSession removes the identifier from localStorage. The validateRememberedWorkspaceSession function prevents stale IDs from being resumed by checking against currently loaded sessions, ensuring that only valid, active sessions can be restored.

Session Isolation and Ownership

The runtime enforces session isolation through predicates like agentOwnsActiveCourse and agentOwnsPaneCourse. These functions verify that an agent-created course remains editable only within the session that created it. This ownership model prevents cross-session contamination while allowing intentional session-course coupling when a session owns specific educational content.

Implementation Examples

Creating and navigating to a new session:

// Request new session from agent runtime
const response = await fetch('/api/agent/sessions', { method: 'POST' });
const { sessionId } = await response.json();

// Generate resumable URL and navigate
import { workspaceResumeHref } from '@/lib/workbench/workspace-panes';
window.location.href = workspaceResumeHref(sessionId);

Persisting to localStorage:

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

// Store for future retrieval
rememberWorkspaceSession(sessionId, localStorage);

Switching sessions while preserving course context:

import { withSession } from '@/lib/workbench/workspace-panes';

// Update session while keeping current course
const updatedPanes = withSession(currentPanes, 'session-42');
// URL becomes: /workspace?session=session-42&course=currentCourseId

Summary

  • The OpenMAIC agent runtime uses opaque session identifiers to isolate conversational contexts and bind them to specific classroom states.
  • URL-driven state in session-urls.ts and resume.ts enables deep-linking and shareable conversation contexts through query parameters.
  • localStorage persistence via workspace-session-memory.ts maintains the last-opened session across browser restarts while validating against stale entries.
  • Pane-based architecture in workspace-panes.ts decouples session and course state, allowing flexible switching between conversations while preserving educational content context.
  • Ownership predicates enforce that agent-created courses remain editable only within their originating sessions, preventing cross-session contamination.

Frequently Asked Questions

How does OpenMAIC store session state between page reloads?

The runtime persists session identifiers in the browser's localStorage using the functions in lib/workbench/workspace-session-memory.ts. Specifically, rememberWorkspaceSession stores the ID under LAST_WORKSPACE_SESSION_STORAGE_KEY, while lib/server/agent-runtime/resume.ts reads the ?session= query parameter on initialization to restore the full conversation context. This dual approach ensures sessions survive browser restarts while remaining addressable via shareable URLs.

Can users switch between multiple agent sessions without losing their course progress?

Yes. The workspace-panes.ts module manages sessionId and courseId as independent dimensions. When calling withSession(panes, newSessionId), the runtime updates only the session identifier while preserving the existing courseId. This allows students to switch between different conversational contexts while maintaining their position in course materials and preventing disruption to their learning flow.

What prevents a session from accessing courses created by other sessions?

The runtime implements ownership predicates agentOwnsActiveCourse and agentOwnsPaneCourse that verify whether the current session ID matches the creator of the active course. These checks ensure session isolation, guaranteeing that agent-generated content remains editable only within the session that instantiated it. This prevents accidental cross-session interference while maintaining strict boundaries between different user conversations.

Where does the session ID originate in the OpenMAIC architecture?

Session IDs are generated server-side by the agent runtime endpoint at /api/agent/sessions. When the client sends a POST request, the backend creates a new database entry, assigns an opaque unique identifier, records the owner, and returns the ID to the client. This server-authoritative approach ensures global uniqueness and establishes the security context for subsequent agent operations.

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 →