> ## 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.

# Turn Executor Protocol • AI Agent SDK

> TurnExecutorProtocol: Contract for *where* a session's agent turn executes (Issue #4011).

# TurnExecutorProtocol

> Defined in the [**protocols**](../modules/protocols) module.

<Badge color="blue">AI Agent</Badge>

Contract for *where* a session's agent turn executes (Issue #4011).

The gateway calls :meth:`place` to obtain a :class:`TurnPlacement` for a
session, then :meth:`execute_turn` to run the turn on that placement, and
:meth:`teardown` to reclaim a placement's worker. The default
:class:`InProcessTurnExecutor` runs the turn on the current event loop,
reproducing today's behaviour exactly; an isolated executor (subprocess /
container / remote, in the wrapper) runs it on its own worker so a wedged,
runaway, or crashed turn is contained to its session.

Contract:

* :meth:`place` returns the placement that owns `session_id`'s
  turns. Implementations may cache a placement per session and bump
  its `epoch` when the backing worker is replaced.
* :meth:`execute_turn` runs `turn` (an `async` no-arg callable the
  gateway already built for this turn) on `placement` and returns
  its result. The in-process default awaits `turn` directly on the
  current loop. An isolated executor does **not** ship this live
  callable (and its captured loop/agent state) across a process
  boundary — the worker owns the session (via :meth:`place`) and
  rebuilds/dispatches the turn from serialisable inputs on its own
  side; `turn` then acts as the gateway-side await point for that
  worker's result. `cancel_token` carries the per-turn interrupt so
  the existing cancellation seam is preserved. `limits` optionally
  bounds the worker's CPU/memory/wall time (honoured by isolated
  executors; ignored in-process). It raises :class:`WorkerWedgedError`
  if the placement's worker can no longer make progress.
* :meth:`teardown` reclaims `placement`'s worker (kills the
  subprocess/container/remote worker, or is a no-op in-process),
  scoped to the owning session only.

A worker fault must fail *scoped*: tear down the offending placement and
re-place its session, never the whole gateway — mirroring the fail-safe,
blast-radius-contained defaults elsewhere.

## Methods

<CardGroup cols={2}>
  <Card title="place()" icon="function" href="../functions/TurnExecutorProtocol-place">
    Return the placement that owns `session_id`'s turns.
  </Card>

  <Card title="execute_turn()" icon="function" href="../functions/TurnExecutorProtocol-execute_turn">
    Run `turn` on `placement` and return its result.
  </Card>

  <Card title="teardown()" icon="function" href="../functions/TurnExecutorProtocol-teardown">
    Reclaim `placement`'s worker (scoped to its session).
  </Card>
</CardGroup>

## Source

<Card title="View on GitHub" icon="github" href="https://github.com/MervinPraison/PraisonAI/blob/main/src/praisonai-agents/praisonaiagents/gateway/protocols.py#L5672">
  `praisonaiagents/gateway/protocols.py` at line 5672
</Card>
