How Apache Maka Manages Sessions and Turns: A Three-Layer Architecture Guide

Apache Maka manages Sessions and Turns through a three-layer architecture that separates SQLite persistence, runtime orchestration, and client-side virtualization to handle long conversational transcripts efficiently.

Apache Maka implements a robust conversation management system where Sessions and Turns are handled across distinct persistence, runtime, and UI layers. This architecture ensures durable storage of conversation history while maintaining smooth scrolling performance even with thousands of turns. Understanding how these components interact reveals the engineering decisions behind Maka's scalable approach to stateful AI conversations.

The Three-Layer Architecture for Session and Turn Management

Maka splits responsibility for Sessions and Turns across three architectural layers:

Persistence Layer and SessionStore

The SessionStore class in packages/storage/src/session-store.ts provides the canonical storage implementation for Sessions and Turns. It validates session IDs using isSafeSessionId (lines 99-100) before persistence and manages SQLite tables defined in sqlite-session-metadata-store.ts.

When creating a session, the store generates a UUID and returns a SessionHeaderSnapshot (lines 31-34). For querying, it projects a session catalog via SessionCatalogRecord (lines 42-45), enabling efficient listing and summary operations. The store also handles safe deletion through probeSessionRemoval and removeSession (lines 136-140), preserving immutable audit trails while retiring session rows.

Runtime Layer and SessionManager

The SessionManager class in packages/runtime/src/session-manager.ts serves as the primary interface for Sessions and Turns manipulation. It coordinates between SessionStore, the AI AgentBackend, and the ExecutionBoundary sandbox.

Key responsibilities include:

  1. Creating sessions via createSession(), which internally calls createStableSession
  2. Managing turn lifecycle through appendTurn()
  3. Providing read models via RuntimeReadModel to answer queries about session lists, summaries, and transcript pages

Client Layer and Turn Virtualization

For UI performance, Maka implements turn virtualization in packages/ui/src/use-turn-virtualizer.ts. This React hook builds a TurnVirtualLayout that maps turn IDs to cumulative heights and manages a TurnVirtualWindow representing the currently rendered subset. The revealTurn(turnId) function (lines 72-78) scrolls specific turns into view, while reconcileTurnVirtualWindow (lines 90-122) adjusts the visible slice based on scroll position.

Session Lifecycle Implementation

Creation and ID Validation

Sessions begin with validation. The SessionStore validates IDs using isSafeSessionId before accepting any operation. The creation flow generates a UUID and persists session headers to SQLite, returning a SessionHeaderSnapshot that serves as the authoritative read model.

Turn Aggregation and Storage

Turns are stored as TurnRecord objects (imported in session-store.ts:84-85). The runtime aggregates raw messages into turns using deriveTurnRecords (runtime-manager.ts:100-102), ensuring each turn maintains sequence integrity within the session transcript.

Turn Management Protocol

Server-Side Protocol Definitions

The wire format for Turns is defined in packages/runtime-host/src/protocol/session-turns.ts. The SessionTurnContribution interface specifies:

export interface SessionTurnContribution {
  readonly turnId: string;
  readonly firstSequence: number;
  readonly latestState: { readonly sequence: number; readonly message: TurnStateMessage } | null;
  readonly userPromptPreview: string | null;
  readonly hasAssistantMessage: boolean;
}

Before transmission, projectSessionTurnContributionForWire (lines 20-44) sanitizes contributions by truncating large strings via truncateUtf8 and validating IDs through requireEntityId. These contributions stream to clients via SessionTurnsQueryResult (lines 88-94).

Cross-Layer Turn Flow

When a new turn generates:

  1. SessionManager records the TurnStateMessage in SQLite
  2. RuntimeReadModel aggregates the turn into a SessionTurnContribution
  3. The client receives the contribution via WebSocket/RPC
  4. use-turn-virtualizer.ts updates the TurnVirtualLayout; if the turn falls outside the current TurnVirtualWindow, the virtualizer slides the window to include it while preserving scroll position

Practical Implementation Examples

Creating a Session

import { SessionManager } from '@maka/runtime';

async function startNewSession(name: string, sessionManager: SessionManager) {
  const input = {
    sessionName: name,
  };
  const result = await sessionManager.createSession(input);
  console.log('New session ID:', result.sessionId);
}

This orchestrates createStableSession in SessionStore, which validates the ID and writes to SQLite.

Appending a Turn

import { TurnRecord } from '@maka/core/session';

const turn: TurnRecord = {
  turnId: 'turn-1',
  firstSequence: 1,
  // ...additional fields
};

await sessionManager.appendTurn(sessionId, turn);

The appendTurn method persists to SQLite and updates the read model for immediate client availability.

Virtualized Turn Navigation

import { useTurns } from '@maka/ui';

function SessionTranscript({ sessionId, scrollRef }) {
  const { turnIds, revealTurn } = useTurns({
    sessionId,
    scrollRef,
  });
  
  // Scroll to specific turn
  const handleJump = () => revealTurn('turn-42');
  
  return (
    // Render only turns in the virtual window
  );
}

The revealTurn function (lines 72-78 in use-turn-virtualizer.ts) handles scrolling and window reconciliation.

Summary

  • Sessions persist in SQLite through SessionStore (packages/storage/src/session-store.ts), which validates IDs via isSafeSessionId and manages metadata through SessionHeaderSnapshot and SessionCatalogRecord projections.
  • Turns flow from TurnRecord storage through SessionTurnContribution wire formats defined in session-turns.ts, sanitized by projectSessionTurnContributionForWire.
  • Runtime orchestration occurs in SessionManager (packages/runtime/src/session-manager.ts), bridging storage, AI backends, and sandbox boundaries.
  • UI scalability relies on use-turn-virtualizer.ts, which implements TurnVirtualWindow and revealTurn to render only visible turns from potentially thousands of conversation entries.

Frequently Asked Questions

How does Apache Maka validate session IDs?

Maka validates session IDs through the isSafeSessionId function in packages/storage/src/session-store.ts (lines 99-100). This safety check runs before any persistence operation to ensure IDs meet canonical format requirements and prevent injection attacks.

What is the TurnVirtualWindow in Maka's UI layer?

The TurnVirtualWindow is a client-side construct managed by use-turn-virtualizer.ts (packages/ui/src/use-turn-virtualizer.ts) that represents the subset of turns currently rendered in the DOM. It works with TurnVirtualLayout to compute cumulative heights and enable smooth scrolling through long transcripts while maintaining minimal memory footprint.

How are turns persisted in Maka's storage layer?

Turns are stored as TurnRecord objects within the session transcript. The SessionStore persists these to SQLite alongside session metadata. The runtime aggregates messages into turns using deriveTurnRecords (runtime-manager.ts:100-102) before storage, ensuring sequence integrity and immutable audit trails.

What happens when a new turn is generated in a Maka session?

When a new turn generates, SessionManager first records the TurnStateMessage in SQLite through SessionStore. The RuntimeReadModel then aggregates this into a SessionTurnContribution and streams it to the client via the protocol defined in session-turns.ts. The UI layer receives the contribution, updates its virtual layout, and if necessary, slides the TurnVirtualWindow to include the new turn while preserving the user's scroll position.

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 →