How the Pro Workbench in OpenMAIC Implements Durable Session Architecture

The Pro workbench leverages the same durable session backbone as the classic interface, reconstructing UI state by folding immutable server-persisted events while applying transient layout adjustments for the 16∶9 canvas mode.

The OpenMAIC platform provides a sophisticated workspace for AI-assisted development, with the Pro workbench offering an expanded full-screen canvas experience. Unlike traditional session management that relies on mutable state, the Pro workbench utilizes a durable session architecture built on event sourcing principles. This design ensures that conversations, tool cards, and classroom panes survive navigation, reloads, and mode switches between the classic and Pro interfaces.

Event Sourcing: The Immutable Foundation

The durable session architecture treats all state changes as immutable events. Rather than mutating a database record, the system appends events to a log and reconstructs state by folding over that history.

The Durable Event Log

Server-persisted events form the authoritative source of truth. The client receives a stream of PersistedEvent objects from the endpoint /api/agent/sessions/:id/events and maintains the last processed event ID (lastEventId) to track progress. Each new event is applied using the pure function foldEvent, defined in lib/workbench/session-store.ts at lines 12–30.

Because foldEvent is a pure function of the event prefix, replaying the entire log after a disconnect yields exactly the same UI state. This property ensures eventual consistency between client and server, regardless of network interruptions.

Separating Persistent and Transient State

The architecture strictly divides state into two categories in lib/workbench/session-store.ts (lines 84–110):

  • WorkbenchSessionState – Contains the immutable transcript, conversation history, and tool results. This is the durable fold that survives restarts.
  • WorkbenchState – Houses transient UI flags such as panelOpen and playbackOn. These preferences reset when the session reloads.

This separation guarantees that resetting a session always restores a complete, consistent state derived from the server-side event log, while UI cosmetic choices remain disposable.

Pro Mode UI Adaptations

While the underlying session architecture remains identical between classic and Pro modes, the Pro workbench applies specific UI transformations to maximize screen real estate.

Full-Screen Canvas Sizing

When the Pro workbench activates, the useWorkbenchProEditing hook (located in lib/workbench/use-workbench-pro-edit.ts at lines 15–22) forces the canvas to occupy 100% of the available area. This fills the 16∶9 workbench card completely.

// Enable Pro‑mode canvas sizing (fills the 16:9 card)
import { useWorkbenchProEditing } from '@/lib/workbench/use-workbench-pro-edit';

export default function ProWorkspace() {
  useWorkbenchProEditing();          // forces canvasPercentage = 100%
  return <YourWorkspaceComponents />;
}

Importantly, this hook does not interact with the durable fold. It only adjusts the rendering layout, ensuring the session state remains identical regardless of which view mode renders it.

Seamless Route Transitions

Switching between the classic (/) and Pro (/workspace) routes utilizes a shared-element view-transition implemented in lib/workbench/pro-swap.ts (lines 1–53). The startProSwap function orchestrates the transition while preserving the product lock-up and Pro badge animations.

// Switch to the Pro workbench with a smooth transition
import { startProSwap } from '@/lib/workbench/pro-swap';
import { useRouter } from 'next/router';

export function goToPro() {
  const router = useRouter();
  startProSwap('/workspace', router.push);
}

During this transition, the underlying session identifier (sessionId) remains unchanged. Consequently, the durable event stream continues uninterrupted, and the fold resumes exactly where it left off—no state synchronization is required because the client simply continues receiving the same SSE stream.

Session Recovery and Replay

The durable architecture excels at handling network volatility and browser navigation. When connectivity restores, the system reconciles state automatically.

Handling Reconnections and Orphaned Events

If the client loses connection, the fold resumes from the saved lastEventId. The durable log may contain "repaired" tool calls with orphaned IDs; the fold settles any still-running tool cards so that the UI never displays a stale "running" state. This logic resides in lib/workbench/session-store.ts within the session_resumed handler (lines 1010–1040) and the settleRunningToolCards function (lines 1089–1104).

// Recover after a disconnect – the fold continues from the saved ID
import { foldEvent } from '@/lib/workbench/session-store';

// Event received from SSE:
const newFold = foldEvent(currentFold, incomingEvent);
// The UI automatically reflects the updated fold.

This guarantees that a Pro session always reflects the latest durable state, even after a navigation or crash.

Practical Implementation

To attach to a durable session from either workbench mode, use the useWorkbenchStream hook from lib/workbench/use-workbench-session.ts:

// Attach to a durable session (common to both classic and Pro)
import { useWorkbenchStream } from '@/lib/workbench/use-workbench-session';

// When the component mounts:
useWorkbenchStream({
  sessionId: 'abc123',               // Durable session identifier
  stageId: null,                     // Optional stage link
});

This hook connects to the server-sent event stream and manages the local fold, ensuring that both the classic and Pro workbenches display identical conversation states derived from the same immutable source.

Summary

  • Event sourcing backbone: The Pro workbench relies on a pure foldEvent function applied to a server-persisted log of PersistedEvents, ensuring state consistency across reconnections.
  • State separation: WorkbenchSessionState holds durable conversation data while WorkbenchState manages transient UI flags, preventing corruption of session history.
  • UI-only adaptations: Pro mode uses useWorkbenchProEditing to scale the canvas without affecting the underlying session fold.
  • Seamless mode switching: The startProSwap transition preserves sessionId continuity, allowing the event stream to persist across route changes.
  • Automatic recovery: The architecture handles orphaned tool calls and resumed sessions via settleRunningToolCards, ensuring the UI never displays stale execution states.

Frequently Asked Questions

Does the Pro workbench use a separate session model from the classic workbench?

No. According to the OpenMAIC source code, the Pro workbench does not introduce a separate session model. It reuses the identical durable event stream and foldEvent logic defined in session-store.ts. The only differences are UI-layer adjustments for canvas sizing and route transitions.

How does OpenMAIC ensure session continuity when switching between classic and Pro modes?

The startProSwap function in pro-swap.ts manages the view transition between routes while maintaining the same sessionId. Because the session identifier persists across the navigation, the client continues consuming the same server-sent event stream without reinitialization. The fold resumes from lastEventId, ensuring zero state loss.

What happens to running tool calls when the client reconnects after a disconnect?

The durable event log may contain repaired or orphaned tool call events. When the session resumes, the foldEvent function processes these events and calls settleRunningToolCards (lines 1089–1104 in session-store.ts) to reconcile any still-running tool cards. This ensures the UI reflects the actual server state rather than displaying phantom "running" indicators.

Where is the durable session state stored versus transient UI state?

In lib/workbench/session-store.ts, the architecture defines WorkbenchSessionState (lines 84–110) for immutable data including the conversation transcript, while WorkbenchState extends it with transient flags like panelOpen. The workspace-session-memory.ts file maintains the in-memory fold and transient flags, but only the WorkbenchSessionState subset persists to the server event log.

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 →