Skip to content

The Lightspeed manual

The agent loop and durability

A conversation may last much longer than the process that happens to be running it. An agent can call a model, wait for tools or a human decision, and continue after its worker has restarted. To make that possible, Lightspeed records the facts that determine the session’s next step. The process holds a working copy of state; durable history allows another process to reconstruct it.

The core loop is straightforward: admit work, record facts, reduce them into state, and decide what should happen next. The care is in the boundaries. A proposed event must be committed before it changes authoritative state, and an external effect must be represented by its recorded result before replay can rely on it.

Separate requests, facts, and decisions

Four terms describe the core’s work:

Term Meaning
Command A request to change the session, such as starting a run, steering it, or deciding an approval.
Event A fact admitted into the session’s ordered log.
State The result of reducing committed events in order.
Effect intent A description of outside work needed to make progress, such as a model generation or tool invocation.

Admission validates a command against current state and proposes the events that should result. It may instead reject the command or recognize that an equivalent request was already admitted. Planning examines the resulting state and determines which internal transition or external operation should follow.

Those are deterministic operations. Time is passed into the engine explicitly; the hosted workflow supplies its workflow clock. The engine does not read the wall clock, open a database connection, or ask a provider what happened last time.

The drive machine first emits an append action with an expected session head. The host commits that append and returns the committed entries. Only then does the reducer apply them. It checks their sequence and advances the state to the committed position.

flowchart TD
  Command[Command] --> Admission[Validate against current state]
  Admission --> Proposed[Proposed events and expected head]
  Proposed --> Storage[Storage activity commits events]
  Storage --> Log[(Lightspeed session event log)]
  Storage --> Committed[Committed entries]
  Committed --> Reduce[Reduce into state]
  Reduce --> Decide[Decide the next action]
  Decide -->|internal transition| Proposed
  Decide -->|effect intent| Effect[Model or tool activity]
  Effect -->|result facts| Proposed
  Decide --> Wait[Idle, waiting, or closed]

The persistence step sits outside the core. An event proposal is not already a durable fact, and an intent is not proof that an external operation completed. Keeping those distinctions explicit makes recovery understandable.

Follow one run

Return to the release editor. The user asks it to read changes.md and prepare release notes. The gateway validates and materializes the input, then sends an admission to the session workflow. session/runs/start returns when the run is accepted; it does not wait for the release notes to be finished.

The accepted request joins the session’s queue. When the active slot is available, the planner starts that run and assembles the next model turn from the recorded configuration and context references. The generation activity loads the content, resolves credentials, builds the provider request, and performs the network call.

Suppose the model asks for two file reads. The adapter stores the provider payload and returns the decision facts the core needs: the generation outcome, context references, and admitted tool calls. Those facts become committed events. The planner can now issue tool work.

The tool adapters read the files and return their results. Each committed result advances the batch’s state. Once the required results are available, the planner can request another model turn. The model writes the notes, receives the write result, and produces an answer. Run completion records the terminal outcome and output descriptor.

This is one run with several turns and tool operations. Completing it normally leaves the session open. A later request to revise the notes starts another run in the same session, with the continuity described in Context and storage.

Waiting is a state of the work

A session has one active run slot and can retain queued submissions behind it. The active run can be executing, parked, or cancelling before reaching a terminal outcome. These are separate from the session’s new, open, and closed lifecycle.

When the drive has no immediately executable action, the workflow may still have work to wait for. A parked run can be waiting on an MCP approval, a timer, a tool promise, or another workflow’s result. The workflow waits for a signal or a relevant deadline and resumes when that fact arrives. It does not need to occupy a provider call or a sleeping activity merely to represent the wait.

Consequently, an idle drive does not necessarily mean the run is complete, and a completed run does not mean the session is closed. The session workflow finishes after session closure and the draining of its pending deliveries. Tools and controller workflows explains how outstanding work is represented by durable promises.

There are two histories

Lightspeed runs an event-sourced agent inside a durable workflow. Each layer records the history needed for its own responsibility:

History What it records What it reconstructs
Lightspeed session log Configuration and context changes, accepted runs, turns, tool results, approvals, promises, and lifecycle facts. The agent’s domain state and the history exposed to clients.
Temporal workflow history Workflow starts, delivered signals, activity results, timers, and orchestration progress. The execution of the workflow code coordinating that work.

Temporal replay lets workflow code encounter the recorded result of an activity without executing that completed activity again. Session replay lets the engine reconstruct its state from the committed domain events without asking the model to reproduce its old answer.

These mechanisms complement each other. Temporal can contain an admission or delivery that has not yet become a committed session event. The session log also remains useful independently of the current Temporal execution: it serves history reads and can reconstruct the agent after workflow rollover. Neither history is an interchangeable backup of the other.

There is another distinction at the payload boundary. An activity’s recorded result can contain content references instead of the provider’s full response. Replaying the orchestration therefore does not require carrying all historical payload bytes in Temporal. The referenced storage must still exist when an activity or client needs to read that content.

Reconstruct state without replaying every old event every time

The session log is authoritative, but repeatedly reducing an entire long conversation would be unnecessary work. Lightspeed stores reducer checkpoints: the reduced state at a known position in the session history.

To reconstruct a session, a storage activity loads a valid checkpoint and replays the tail through a captured head. The loader checks the checkpoint’s format, lineage, position, and recorded byte length, and verifies that the required tail is complete. If the checkpoint cannot be used, it falls back to the event log. A missing checkpoint is therefore a performance issue; missing authoritative events are a correctness issue and fail explicitly.

The activity returns reduced state, its head, and the run-submission index to the workflow. It does not send the entire event history through the activity result. The same distinction lets a transcript reader load a bounded event range without reconstructing the full execution state first.

The checkpoint loader implements this recovery boundary. Checkpoints are accelerators, not a second source of truth that can silently override the log.

Continue with a new Temporal execution

Even small workflow events accumulate over a long conversation. Temporal continue-as-new starts a fresh execution of the same logical workflow so the old execution’s history no longer has to grow with every new turn.

Lightspeed makes rollover due when Temporal suggests it or when the configured history threshold is reached. It then waits for a safe committed boundary. This can happen during an active run; the agent does not have to finish the whole task first.

The safe boundary matters because not every piece of transport state has already become reconstructible session state. Pending admissions, emissions, tool resumes, promise/source deliveries, and local retry or cancellation deadline state can delay rollover. The workflow drains or settles that work before continuing. Parked batches and durable promises can survive the boundary because their facts are already in session state.

The new execution loads the session through the storage activity and resumes the drive. An active run does not require another user message to wake it. The logical session ID and Lightspeed run ID remain the same, while the Temporal execution ID changes.

This is how a session can span many workflow executions. It is not an absolute bound on all state: unsafe transport state can delay rollover, and reduced bootstrap metadata still has a size budget. Large payload offloading, compaction, history rollover, and retention each address a different source of growth.

Accept control while work is in flight

The session workflow listens for admissions while generation and tool activities run. New queued work, cancellation, steering, approval decisions, and promise facts can be recorded without waiting for a slow model call to return.

That responsiveness does not mean the request already sent to the provider can be edited. A turn uses frozen context and configuration revisions. Steering admitted during generation is materialized at a subsequent turn boundary. Mutations that would invalidate the in-flight generation wait for the appropriate boundary. Standalone compaction temporarily holds admissions until the compaction operation finishes.

Cancellation changes the authoritative run state and requests cancellation of its executing activities or owned work. Obsolete results cannot turn the cancelled task back into a successful active run. A watchdog can recover a run that remains stuck in cancellation, but neither that watchdog nor an API acknowledgment reverses a remote operation that already happened.

For the user-facing choices between queueing, steering, and cancellation, see Sessions and runs.

Make retries converge at explicit boundaries

Suppose a storage activity commits an append and loses its completion response. Temporal may retry the activity. The storage activity recognizes an exact repeat at the expected position by comparing the already committed entries, including their sequence and event contents. It can return that committed result instead of appending duplicates. A conflicting append remains an error.

Client submissions have a similar boundary. Reusing a submission_id with the same submission resolves to the accepted run. Reusing it with different input, configuration, or notification intent is rejected. The identifier makes the retry recognizable; it is not a request to create another run.

External effects need their own policy. Read-only or explicitly retry-safe tools receive bounded retries. Other calls, including process operations, use one attempt. Completed tool siblings have their results committed independently, so retrying unfinished work does not require re-executing those completed calls. Provider generation and compaction have bounded handling for transient failures; exhausted retries become visible failures rather than an endless model call.

Deterministic replay and external exactly-once execution are different claims. If a remote service performed an operation but its response was lost, the runtime may not be able to infer the result. Stable operation IDs, appropriate provider idempotency, and effect-specific recovery are still necessary. An email already sent or a machine command already run is not undone by replaying the session.

These are the practical limits of durability: compatible workflow code and retained histories let processing resume; recorded events reconstruct decisions; effect adapters handle the uncertainty at their external boundaries. The operations and recovery guides explain how to inspect those boundaries in a deployment.