How Maka Supports Subagent Sessions: Architecture and Implementation

Maka implements subagent sessions as isolated child conversations linked to parent sessions through a durable three-layer metadata model stored in SQLite, enabling idempotent creation and runtime delegation while maintaining clear execution lineage.

Apache Maka treats subagent sessions as first-class entities that enable parallel or delegated work within a parent conversation. The framework persists subagent metadata using a dedicated SQLite storage layer, ensuring that child sessions maintain their own execution context while preserving provenance back to the spawning tool call.

Core Metadata Model

The foundation of subagent support rests on three tightly-coupled interfaces defined in packages/core/src/session.ts (lines 114-162). These structures separate concerns between lineage tracking, runtime configuration, and spawn provenance.

SubagentSessionParent

This interface maintains the parent-child relationship. It stores the parent session ID, the specific tool call that spawned the child, and optional swarm or graph identifiers. By storing the linkage on the child side rather than the parent, Maka eliminates the need for the parent session to maintain a list of children, enabling efficient reverse lookups when needed.

SubagentSessionRuntime

This structure captures the child session’s execution snapshot, including the model configuration, available tool list, policy settings, and sandbox parameters. It ensures that each subagent runs in an isolated context independent of the parent’s runtime state.

SubagentSessionSpawn

The spawn record contains immutable fingerprint data that guarantees reproducible lineage. It tracks the initial turn ID, run ID, and a cryptographic request fingerprint that uniquely identifies the spawning event.

Persistent Storage and Idempotent Creation

Subagent metadata persists in SQLite through the SessionStore.createSubagent() method implemented in packages/storage/src/sqlite-session-metadata-store.ts (lines 1036-1084).

Idempotency is a critical characteristic of this implementation. When a tool requests a child session, the storage layer first validates the header and checks for an existing record matching the spawn fingerprint. If the child already exists, the method returns the existing SessionHeader; otherwise, it inserts a fresh session_metadata row with the complete parent, runtime, and spawn information.

// Creating a sub-agent session from the runtime (e.g., in a tool implementation)
const childHeader = await sessionStore.createSubagent({
  id: 'child-123',                     // generated UUID
  backend: parentHeader.backend,
  subagentParent: {
    kind: 'subagent',
    parentSessionId: parentHeader.id,
    spawnedBy: { parentRunId: run.id, parentTurnId: turn.id, toolCallId: toolCall.id },
    lifecycle: 'foreground',
  },
  subagentRuntime: {
    schemaVersion: 1,
    definitionVersion: 1,
    agentId: 'agent-xyz',
    agentName: 'Sub-Agent',
    profile: 'default',
    systemPrompt: '',
    toolNames: [],
    categoryPolicy: {},
  },
  subagentSpawn: {
    schemaVersion: 1,
    requestFingerprint: 'sha256:…',
    initialTurnId: turn.id,
    initialRunId: run.id,
  },
});

To retrieve a child’s metadata later (for example, when rendering the UI), the storage layer provides a standard read interface:

const childMeta = await sessionStore.read(childHeader.id);
console.log(childMeta.header.subagentParent?.parentSessionId); // → parent session ID

Runtime Orchestration via SessionManager

The SessionManager façade in packages/runtime/src/session-manager.ts (lines 594-608) orchestrates the creation flow. When a tool such as call_subagent requests a child session, the runtime invokes SessionManager.createSubagent(), which forwards the request to the storage layer.

Upon receiving the hydrated SessionHeader from storage, the manager registers the child within the active runtime, updates the parent turn with the childSessionId, and emits a ToolResultContent object with kind: 'subagent'. This event bridges the runtime and UI layers, signaling that a new isolated execution context is available.

UI Representation and Linkage

The user interface surfaces subagent sessions in the tool-activity pane through packages/ui/src/tool-activity.tsx (lines 43-71). When the UI encounters a tool result with kind: 'subagent', it extracts the agent name, current status, duration, and child session ID to render an interactive row.

Users can click a link within this row to open the child session in the main chat column, enabling side-by-side inspection of parent and child conversations. Because the storage layer maintains the parent reference within the child metadata, the UI can construct navigation links without querying the parent session’s state.

// UI component that shows a sub-agent row
function renderSubagentRow(item: ToolActivityItem) {
  if (item.result?.kind !== 'subagent') return null;
  const { agentName, status, childSessionId } = item.result;
  return (
    <div className="maka-subagent-session-label">
      <span>{agentName}</span>
      <span>{status}</span>
      <a href={`/chat/${childSessionId}`}>Open</a>
    </div>
  );
}

Summary

  • Three-layer metadata model: Maka separates subagent concerns into SubagentSessionParent (lineage), SubagentSessionRuntime (execution context), and SubagentSessionSpawn (provenance) in packages/core/src/session.ts.
  • Idempotent creation: The createSubagent() method in packages/storage/src/sqlite-session-metadata-store.ts ensures duplicate spawn attempts resolve to the same child session.
  • Reverse linkage: Parent-child relationships are stored on the child side, eliminating the need for the parent to track children while enabling efficient storage lookups.
  • Runtime integration: SessionManager in packages/runtime/src/session-manager.ts bridges storage creation with active runtime registration and UI notification.
  • Inline UI rendering: The tool-activity component in packages/ui/src/tool-activity.tsx displays subagent status and provides direct links to child sessions.

Frequently Asked Questions

How does Maka ensure idempotent subagent creation?

The SessionStore.createSubagent() method checks for an existing session matching the spawn fingerprint before inserting new metadata. If a record exists, it returns the existing SessionHeader; otherwise, it creates a new entry. This prevents duplicate sessions when tools retry or network issues cause repeated spawn requests.

What storage backend does Maka use for subagent sessions?

Maka persists subagent metadata in SQLite through the implementation found in packages/storage/src/sqlite-session-metadata-store.ts. The schema stores parent linkage, runtime configuration, and spawn provenance within the session_metadata table, enabling durable state across process restarts.

How does the UI access subagent session information?

The UI receives subagent data through ToolResultContent objects with kind: 'subagent' emitted by the runtime. The tool-activity.tsx component extracts fields such as agentName, status, and childSessionId from these results to render interactive rows that link to the child session view.

What is the relationship between parent and child sessions in Maka?

A subagent session maintains a reference to its parent through the SubagentSessionParent interface stored in its own metadata. The parent does not maintain a list of children; instead, the system performs reverse lookups via the storage read model when necessary. This design enables isolated execution while preserving clear lineage for debugging and auditing.

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 →