liveBook · Manning

Execution context

As explained in Build an AI Agent (From Scratch)

An execution context is a structured container for an agent execution session's identifier, event history, step counter, mutable state, and final result.

An execution context is the shared container for one agent execution. Instead of passing an event history, step count, intermediate data, and result separately through the think–act loop, the agent passes one ExecutionContext. New execution data can then be added without changing every method signature. section 4.2.2

A minimal Python dataclass holds five fields:

  • execution_id identifies the session, including when inspecting errors. section 4.3.2
  • events records the chronological execution history; add_event() appends to it. section 4.3.2
  • current_step counts think–act cycles; increment_step() advances it so the agent can enforce max_steps. section 4.3.2
  • state is a flexible dictionary for data such as tool configuration or intermediate results. section 4.3.2
  • final_result holds the answer once execution completes; it can be text or a Pydantic model. section 4.3.2
Listing 4.4 Implementing ExecutionContext
@dataclass
class ExecutionContext:
    """Central storage for all execution state."""

    execution_id: str = field(default_factory=lambda: str(uuid.uuid4()))
    events: List[Event] = field(default_factory=list)
    current_step: int = 0
    state: Dict[str, Any] = field(default_factory=dict)
    final_result: Optional[str | BaseModel] = None

    def add_event(self, event: Event):
        """Append an event to the execution history."""
        self.events.append(event)

    def increment_step(self):
        """Move to the next execution step."""
        self.current_step += 1

The dataclass listing shows the default values and the two small methods that update execution history and step count. section 4.3.2

The agent’s run() method creates a context unless one is supplied, records the user input as an Event, and calls step() until it finds a final response or reaches the step limit. Each step prepares an LlmRequest, records the LLM response, executes any requested tools, records their results, and increments current_step. AgentResult returns both the output and its context, leaving the trace available for inspection. section 4.6.2 section 4.6.3

ExecutionContext is not the LLM request. It retains the full execution history, while LlmRequest contains the information selected for a particular call. The current request builder flattens all events; it could instead summarize older messages or omit irrelevant tool results without altering the stored history. Tools receive the context too: a context-aware tool can inspect previous events or state, while a wrapped function that has no context parameter can run unchanged. section 4.6.3 section 4.4.3

Inspecting an agent run

After an agent answers a calculation request, read result.output for the answer and result.context.current_step for the number of steps. For a failed run, inspect result.context.events or visualize the context with display_trace() to locate the troublesome LLM response or tool result. section 4.6.2 section 4.8.2

How Build an AI Agent (From Scratch) covers it

How deep it goes
Implements the container as a Python dataclass, then follows its creation and updates through run() and step().
Examples
Uses a dataclass listing, an agent calculation, and display_trace() on a multistep question.
What it assumes
Builds on agent tool use while defining the context container and its role in the loop.
What you can do after
Build it from scratch to share execution state, enforce step limits, and inspect completed runs.
How it connects
Connects ReAct, tool calling, event histories, LlmRequest, context engineering, and execution traces.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build an AI Agent (From Scratch). The section links point to the parts of the book it draws on.