How to Configure the Runner for Agent Execution in AISuite: A Complete Guide

The Runner class is the central orchestration component that drives agent execution through configurable parameters like max_turns, state_store, and tool_policy, enabling multi-turn tool loops, persistent conversations, and detailed observability.

The Runner in the AISuite framework manages the complete lifecycle of an agent interaction, from initial message construction through optional multi-turn tool execution and state persistence. When configuring the Runner for agent execution, you control conversation limits, tool permissions, tracing behavior, and storage backends. This guide examines the configuration options defined in aisuite/agents/runner.py and demonstrates how to implement production-ready agent workflows.

Core Runner Configuration Parameters

The Runner.run_sync() and Runner.run() methods accept a comprehensive set of keyword arguments that define execution behavior. These parameters are processed at the start of the run to initialize the execution context.

Connection and Identity

  • client: Supplies a pre-configured Client instance. If omitted, the Runner instantiates a new Client() automatically via aisuite/client.py.
  • run_name, parent_run_id, group_id: Enable hierarchical organization of runs for complex workflow orchestration. These identifiers appear in every trace event emitted during execution.

Execution Control

  • max_turns: Enables multi-turn tool loops by specifying the maximum number of model-tool interaction cycles. The Runner repeatedly calls the model while tool calls are present, up to this limit.
  • tool_policy: A callable or ToolPolicy object that decides whether a specific tool may execute. The Runner forwards this policy and a context dictionary to the underlying tool runner.

Observability and Metadata

  • tags / metadata: Attach arbitrary string tags or key-value dictionaries that propagate to every trace event, enabling filtering and correlation in downstream observability platforms.
  • trace_sinks: List of TraceSink objects receiving trace events; defaults to globally configured sinks from aisuite/tracing/sinks.py.
  • tracing_disabled: Boolean flag to skip all tracing initialization, eliminating the overhead of trace ID generation and event emission.

State Persistence

  • state_store / thread_id: Persist the run state for later continuation. Both must be supplied together; the store queries for existing thread state before starting execution via state_store.load_state().
  • artifact_store: Handles large artifacts such as files and images by dehydrating them when persisting state and rehydrating upon retrieval.

Model Overrides

  • **kwargs: Any additional model-specific arguments (e.g., temperature, top_p) are merged with the agent’s model_settings and passed to Client.chat.completions.create().

The Agent Execution Flow

The execution logic in aisuite/agents/runner.py follows a strict seven-step pipeline:

  1. Input Normalisation: If the input is a RunState, the Runner copies stored messages and merges run-level overrides; otherwise, it builds a new message list via Runner._build_messages (lines 97-105).
  2. Trace Initialisation: Allocates a new trace ID unless tracing is disabled; resolves trace sinks via get_configured_sinks (lines 101-106).
  3. Emit run.started Event: Records the run start, including the full input payload (lines 163-173).
  4. Model Call: Invokes Client.chat.completions.create with merged model settings. If agent.tools is defined, the request includes tool schemas and respects max_turns (lines 134-140).
  5. Error Handling: Catches exceptions, emits a run.failed trace event, and re-raises the original error.
  6. Response Processing: Extracts final output, assembles response steps via _build_response_steps and tool steps via _build_tool_steps, then constructs a RunResult object (lines 260-284).
  7. Final Trace Events: Emits model.response (if not already emitted by the client) and run.completed events, optionally persisting state via state_store.save_state (lines 286-306).

Practical Configuration Examples

Basic Synchronous Execution with Tracing

from aisuite import Agent, Runner, Client

agent = Agent(
    name="simple-agent",
    model="openai:gpt-4o-mini",
    instructions="You are a helpful assistant.",
)

result = Runner.run_sync(
    agent,
    "Explain the difference between a list and a tuple.",
    max_turns=3,
    tags=["demo"],
    metadata={"request_id": "12345"},
)
print(result.final_output)

This call creates a trace ID, emits run.started, calls the model, and finally emits run.completed.

Multi-Turn Tool Execution

from aisuite import Agent, Runner, Tools

def list_files(path: str) -> str:
    import os; return "\n".join(os.listdir(path))

agent = Agent(
    name="file-explorer",
    model="openai:gpt-4o-mini",
    tools=Tools([list_files]).tools(),
)

result = Runner.run_sync(
    agent,
    "List the files in the current directory.",
    max_turns=5,                 # Enable tool loop

    tool_policy=lambda ctx, tool: True,  # Allow all tools

)
print(result.final_output)

The Runner calls list_files when the model produces a tool_calls entry and continues for up to 5 turns.

Persisted Conversations with State Store

from aisuite import Agent, Runner, InMemoryStateStore

store = InMemoryStateStore()
thread = "demo-thread"

# First run – creates a persisted thread

first = Runner.run_sync(
    agent,
    "Tell me a short story about a robot.",
    state_store=store,
    thread_id=thread,
)

# Continue the same thread later

second = Runner.continue_sync(
    first,
    "Add a twist where the robot meets a cat.",
    state_store=store,
    thread_id=thread,
)

print(second.final_output)

Both calls share the same thread_id; the state store automatically saves and loads the conversation via state_store.save_state and state_store.load_state.

Disabling Tracing for Performance

result = Runner.run_sync(
    agent,
    "Compute the 20th Fibonacci number.",
    tracing_disabled=True,   # No trace events emitted

)

Continuing a Persisted Agent Run

To resume a persisted conversation, use Runner.continue_sync(target, input, ...). This method, implemented in aisuite/agents/runner.py (lines 374-394), loads the stored RunState, appends the new user message, and re-executes the run with the same configuration. It updates the stored state atomically, preserving the revision token to prevent conflicts in concurrent environments.

Key Integration Points

Client: The Client class provides the underlying provider implementation and handles tool execution through _tool_runner. See aisuite/client.py (lines 57-66) for the pipeline details.

TraceSink: Any object implementing emit_event can receive trace payloads. The default sinks are configured in aisuite/tracing/sinks.py.

StateStore: Concrete implementations like InMemoryStateStore or PostgresStateStore provide load_state, save_state, and version handling interfaces defined in aisuite/agents/state_store.py.

Summary

  • The Runner class in aisuite/agents/runner.py is the central orchestration component for agent execution.
  • Configure multi-turn tool loops using the max_turns parameter and control tool permissions with tool_policy.
  • Persist conversation state across sessions by providing both state_store and thread_id arguments.
  • Implement observability by configuring trace_sinks, tags, and metadata, or disable tracing entirely with tracing_disabled.
  • Resume existing conversations using Runner.continue_sync(), which atomically updates the stored RunState.

Frequently Asked Questions

What is the difference between run_sync and run in AISuite?

The run_sync() method provides a synchronous interface for agent execution, blocking until the full conversation or tool loop completes. The run() method is the asynchronous counterpart that returns a coroutine, suitable for async/await patterns in high-concurrency applications. Both methods accept identical configuration parameters and execute the same underlying logic in aisuite/agents/runner.py.

How do I enable multi-turn tool execution in the Runner?

Set the max_turns parameter to an integer greater than 1 when calling Runner.run_sync(). The Runner will then enter a loop where it calls the model, executes any returned tool calls, and feeds the results back to the model, repeating this process up to the specified limit. You must also define tools in your Agent instance and optionally configure a tool_policy to control which tools may execute.

How does state persistence work in AISuite?

State persistence requires a StateStore implementation (such as InMemoryStateStore) and a unique thread_id string. When both are provided to Runner.run_sync(), the Runner calls state_store.save_state() after completion, storing the RunState object containing message history and metadata. To resume, call Runner.continue_sync() with the same thread_id and store instance; the Runner loads the previous state via state_store.load_state() before appending new messages.

Can I disable tracing for specific runs in production?

Yes. Pass tracing_disabled=True to Runner.run_sync() to suppress all trace events for that specific execution. This eliminates the overhead of trace ID generation and event emission, making it ideal for high-throughput benchmarks or sensitive operations where observability data should not be recorded. Note that this only affects the specific run; global trace sink configuration remains unchanged.

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 →