> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Prepared Turn Context

> One immutable plan per agent turn, shared by every runtime (native, plugin, CLI).

Build one frozen turn plan from an `Agent` and prompt — any runtime (native, plugin, CLI) executes the same context.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonaiagents.runtime import default_context_builder

agent = Agent(name="Researcher", instructions="Find facts and cite sources.")
context = default_context_builder.build_context(agent, "Who built the Eiffel Tower?")
print(context.to_dict())
```

The user sends a prompt; the runtime builds one shared PreparedTurnContext for the turn.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    Agent[🤖 Agent] --> Builder[📋 ContextBuilder]
    Builder --> Plan[(PreparedTurnContext)]
    Plan --> Native[Native runtime]
    Plan --> Plugin[Plugin harness]
    Plan --> CLI[CLI backend]

    classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff

    class Agent input
    class Builder,Plan process
    class Native,Plugin,CLI result
```

## Quick Start

<Steps>
  <Step title="Simple Usage">
    Inspect what the agent will send on the next turn:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonaiagents.runtime import default_context_builder

    agent = Agent(name="Writer", instructions="Summarise pull requests.")
    context = default_context_builder.build_context(agent, "Summarise this PR")

    print(context.has_tools(), context.get_message_count())
    print(context.to_dict())
    ```
  </Step>

  <Step title="With Configuration">
    Run the same context through a custom harness:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    import asyncio
    from praisonaiagents import Agent
    from praisonaiagents.runtime import default_context_builder
    from praisonaiagents.runtime.example_harness import PluginHarnessRuntime

    agent = Agent(name="Writer", instructions="Summarise pull requests.")
    context = default_context_builder.build_context(agent, "Summarise this PR")

    async def run():
        return await PluginHarnessRuntime().run_turn(context)

    asyncio.run(run())
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant Builder as DefaultTurnContextBuilder
    participant Context as PreparedTurnContext
    participant Runtime

    User->>Agent: prompt
    Agent->>Builder: build_context(agent, prompt)
    Builder->>Context: freeze immutable plan
    Agent->>Runtime: run_turn(context)
    Runtime-->>User: response
```

| Stage   | What happens                                             |
| ------- | -------------------------------------------------------- |
| Build   | Resolves model, tools, transcript, delivery, correlation |
| Freeze  | Context is immutable after construction                  |
| Execute | Any `TurnRuntimeProtocol` runs the same plan             |

Key imports: `PreparedTurnContext`, `default_context_builder`, `RuntimeMode`, `DeliveryChannels`.

***

## Configuration Options

| Field          | Type                 | Notes                                         |
| -------------- | -------------------- | --------------------------------------------- |
| `runtime_mode` | `RuntimeMode`        | `SYNC`, `ASYNC`, `STREAM`, `ASYNC_STREAM`     |
| `delivery`     | `DeliveryChannels`   | Required for streaming modes                  |
| `correlation`  | `SessionCorrelation` | `session_id`, `turn_id`, `agent_id`, `run_id` |

`STREAM` and `ASYNC_STREAM` raise `ValueError` if `delivery.has_streaming()` is false.

***

## Best Practices

<AccordionGroup>
  <Accordion title="Treat context as read-only">
    Fields are frozen — mutate via hooks, not assignment.
  </Accordion>

  <Accordion title="Build one context per turn">
    Do not cache plans across turns in multi-agent setups.
  </Accordion>

  <Accordion title="Reuse default_context_builder">
    It is a module-level singleton — no need to instantiate your own builder.
  </Accordion>

  <Accordion title="Match runtime_mode to delivery">
    Enable `DeliveryChannels(enable_streaming=True, ...)` before choosing stream modes.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Runtime Selection" icon="play" href="/docs/features/runtime-selection">
    Model-scoped runtime configuration
  </Card>

  <Card title="Streaming" icon="signal-stream" href="/docs/features/streaming">
    Stream agent output token-by-token
  </Card>
</CardGroup>
