How Apache Maka Handles the Agent Execution Lifecycle: Inside the AgentRun Class
Apache Maka manages the agent execution lifecycle through the AgentRun class, which orchestrates a single turn from initialization through durable logging, tool execution, and graceful termination via nine distinct stages coordinated by the Runtime Host.
Apache Maka is an open-source framework for building reliable AI agents. At the heart of its reliability guarantees lies the AgentRun class located in packages/runtime/src/agent-run.ts, which implements a durable, recoverable lifecycle for each agent turn. This article examines how Apache Maka handles the agent execution lifecycle through the AgentRun implementation, from initial registration to crash recovery.
The AgentRun Class: Core of the Execution Lifecycle
The AgentRun class serves as the execution authority for a single agent turn. According to the Apache Maka source code, a "run" represents one complete turn—from the moment a user message is received, through tool invocations and possible continuations, to final termination. The class maintains the canonical state in the AgentRunStore and writes immutable events to the Runtime Event Log, ensuring that every action is durably recorded in SQLite stores under packages/storage.
The lifecycle operates through cooperation between the Runtime Host, which owns session identity and permissions, and the Agent Graph, which schedules sub-agents. The AgentRun instance bridges these components while guaranteeing that the ledger remains consistent even during crashes or graceful stops.
The Nine Stages of the Agent Execution Lifecycle
The Apache Maka agent execution lifecycle breaks down into nine distinct stages, each implemented by dedicated components and hooks.
1. Run Creation and Registration
A client (CLI, TUI, desktop application, or bot) requests a new turn via the Runtime Host. The host constructs an AgentRunInput object and instantiates the AgentRun class. During construction (lines 69-84 in packages/runtime/src/agent-run.ts), the AgentRunHooks.reserveRun method registers the run in an active-session map called AgentRunActiveSession, establishing the run's identity before any processing begins.
2. Input Validation and Orchestration
Before execution starts, the run resolves its orchestration mode and tool permissions. The resolveEffectiveOrchestration method (lines 99-101) determines how the agent will coordinate with sub-agents, while tool-mode checks (lines 99-104) validate whether the run operates in DEFAULT_TOOL_MODE or another configured mode. Invalid or missing data triggers early errors here, preventing corrupted runs from entering the event stream.
3. Runtime Event Stream Initialization
The run creates an invocation opening event (RuntimeEventInvocationOpenedContent) that marks the start of execution. The isSessionInline() method (lines 54-60) determines whether the execution runs session-inline or out-of-line, affecting how the runtime buffers events. This opening event becomes the first entry in the Runtime Event Log, establishing the canonical source of truth for the turn.
4. Tool Execution and Logging
During the turn, the agent may invoke LLM-powered tools. Each tool call generates a Tool Ledger entry with the type MODEL_CALL_ATTEMPT_EVENT_TYPE. The run persists these events through the AgentRunStore API, using methods like appendTurnState and appendMessage to write to both the durable AgentRunStore and the RuntimeEventStore. This dual-write pattern ensures that tool interactions remain recoverable even if the host process terminates unexpectedly.
5. Continuation Handling
When a turn spawns a continuation—such as a sub-session or a resumed run—the run creates a Continuation Start Admission Proof via createRuntimeContinuationStartAdmissionProof (lines 66-70). The commitContinuationStart method commits a claimed opening to the durable ledger before the backend begins execution. This guarantees that the continuation survives host crashes and can be resumed later without data loss.
6. Graceful Stop Requests
The host or user can request termination via run.stop(source) (lines 25-33). This method records a terminal claim in the run's state and prevents further events from being appended. The hasPendingStop() and completeStop() methods (lines 62-68) manage the stop lifecycle, ensuring that in-flight operations complete gracefully while new operations are rejected.
7. Finalization and Terminal Claims
When the backend signals completion, the finalize() method (called from runCompositionWrite and flushRuntimePartialBuffer) writes the terminal run fact to the durable store. The settleStopTerminal() method (lines 81-99) ensures that any pending stop claim is "cashed," marking the run as definitively terminated in the ledger. The terminalRunFactCommitted flag (lines 54-56) prevents duplicate finalization.
8. Recovery and Inspection
After a crash or during continuation resume, the AgentRunRecovery machinery in packages/runtime/src/agent-run-recovery.ts re-hydrates the run from the AgentRun event stream and Runtime Event Log. The recovery process validates ledger consistency and can replay missing events. Developers can inspect run diagnostics through AgentRunInspectDiagnostic in packages/runtime/src/agent-run-inspect.ts, which provides visibility into the lifecycle state.
9. Agent Graph Coordination
For parallel sub-agents or complex workflows, the Agent Graph (packages/runtime/src/agent-graph.ts) schedules child sessions through the Agent Graph Control Plane. The run propagates lineage metadata (parent run/turn IDs, retry information) to child sessions and collects results back through the Runtime Host, maintaining a unified event log across distributed execution.
Implementing the Lifecycle: Code Examples
Starting an Agent Run
The following TypeScript example demonstrates initializing a run with the required stores and hooks:
import { createSqliteAgentRunStore } from '@maka/storage';
import { SessionManager } from '@maka/runtime';
import { AgentBackend } from '@maka/core';
// 1. Prepare the stores
const runStore = createSqliteAgentRunStore('/path/to/workspace');
const runtimeEventStore = /* …create RuntimeEventStore… */;
// 2. Build the input payload
const input = {
sessionId: 'sess-123',
header: {/* SessionHeader */},
userInput: {/* UserMessageInput */},
store: { /* Session store */ },
runStore,
runtimeEventStore,
newId: () => crypto.randomUUID(),
now: () => Date.now(),
hooks: {
reserveRun: async (sid, hdr, run) => ({
sessionId: sid,
backend: {/* … */} as AgentBackend,
cachedHeader: hdr,
activeRuns: new Map([[run.runId, run]]),
turnToRunId: new Map(),
}),
updateHeader: async () => ({/* … */}),
updateStatus: async () => {},
appendTurnState: async () => {},
},
};
// 3. Create the run – this runs the constructor logic (initialisation, lineage, etc.)
const run = new AgentRun(input);
// 4. Start the backend (e.g., a LLM model) – the `run.begin()` method returns the initial runtime events
const beginResult = await run.begin();
Stopping a Run Gracefully
To initiate a graceful shutdown from the UI or a scheduler:
const stopped = run.stop({ source: 'user', workHubActionId: 'task-456' });
if (stopped) {
console.log('Run stop scheduled – terminal claim recorded');
}
Handling Continuations
When suspending a turn for later resumption:
// The backend decides to continue the turn in a later session.
await run.commitContinuationStart(Date.now()); // writes the start admission proof
// Later, when the continuation resumes, the runtime will call `run.beginContinuation()`
Recovering from Crashes
To recover a run after a host restart:
import { recoverAgentRun } from '@maka/runtime/agent-run-recovery';
const recoveredRun = await recoverAgentRun({
sessionId: 'sess-123',
runId: 'run-abc',
runStore,
runtimeEventStore,
});
Key Source Files for the Execution Lifecycle
packages/runtime/src/agent-run.ts– Implements the fullAgentRunclass including construction, stop handling, terminal claim settlement (settleStopTerminal), and interaction with durable stores.packages/runtime/src/agent-run-recovery.ts– ContainsAgentRunRecoverylogic for re-hydrating runs after crashes and validating ledger consistency.packages/runtime/src/agent-run-inspect.ts– ProvidesAgentRunInspectDiagnosticutilities for debugging lifecycle states.packages/storage/src/sqlite-agent-run-store.ts– Persists the immutable AgentRun event stream to SQLite, serving as the authoritative source for "what happened."packages/runtime/src/agent-graph.ts– Implements the Agent Graph Control Plane for scheduling sub-agents and propagating lineage.ARCHITECTURE.md(root) – Describes the high-level relationship between the Runtime Host, Session Manager, AgentRun, and Agent Graph components.
Summary
- The
AgentRunclass inpackages/runtime/src/agent-run.tsmanages a single agent turn as a durable, recoverable unit of work. - The lifecycle spans nine stages: creation, validation, event stream initialization, tool execution, continuations, stop requests, finalization, recovery, and graph coordination.
- Durable stores (
AgentRunStoreandRuntimeEventStore) ensure that every event is persisted to SQLite before acknowledgment, enabling crash recovery. - Graceful stops use terminal claims (
terminalClaim) andsettleStopTerminalto ensure clean termination without data loss. - Continuations use admission proofs to survive host crashes and resume execution later.
- Recovery machinery in
agent-run-recovery.tsre-hydrates runs from the event stream, validating consistency before resuming.
Frequently Asked Questions
What is the difference between AgentRun and SessionManager in Apache Maka?
The AgentRun class governs a single turn within a session—the execution of one user request through completion—while the SessionManager (located in packages/runtime/src/session-manager.ts) coordinates multiple turns and tracks active sessions over time. The SessionManager creates AgentRun instances and manages the Runtime Host identity, whereas AgentRun handles the specific lifecycle of one turn's event stream and durable ledger.
How does Apache Maka ensure durability during agent execution?
Apache Maka ensures durability through immediate persistence to SQLite-backed stores. Every significant event—invocation openings, tool calls, and terminal claims—is written to the AgentRunStore and RuntimeEventStore before the runtime acknowledges progress. The commitContinuationStart method writes admission proofs before spawning sub-sessions, and the finalize method commits terminal facts before releasing resources, ensuring the ledger remains consistent even if the host crashes.
Can Apache Maka recover an agent turn after a host crash?
Yes. The AgentRunRecovery mechanism in packages/runtime/src/agent-run-recovery.ts can re-hydrate a run from the AgentRun event stream and Runtime Event Log after a crash. The recovery process validates that the ledger is consistent and can replay missing events. Because continutations write Continuation Start Admission Proofs before beginning work, even interrupted sub-sessions can be resumed without data loss.
How does the Agent Graph interact with the agent execution lifecycle?
The Agent Graph (packages/runtime/src/agent-graph.ts) extends the lifecycle to parallel and hierarchical execution. When a run spawns sub-agents, the Agent Graph Control Plane schedules child sessions, propagates lineage metadata (parent run IDs and retry contexts) through the Runtime Host, and collects results back into the parent run's event stream. This integration allows AgentRun to manage complex multi-agent workflows while maintaining a unified, durable audit 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →