# `Jido.AI.Turn`
[🔗](https://github.com/agentjido/jido_ai/blob/v2.4.0/lib/jido_ai/turn.ex#L1)

Canonical representation of a single LLM turn.

A turn captures the normalized response shape consumed by strategies and
directives:

- Response classification (`:tool_calls` or `:final_answer`)
- Ordered multimodal content, extracted text, and optional thinking content
- Normalized tool calls
- Usage/model metadata
- Optional executed tool results

# `execute_opts`

```elixir
@type execute_opts() :: [
  timeout: pos_integer() | nil,
  tools: tools_map() | [module()] | module() | nil,
  telemetry_metadata: map()
]
```

# `execute_result`

```elixir
@type execute_result() :: {:ok, term(), [term()]} | {:error, term(), [term()]}
```

# `response_type`

```elixir
@type response_type() :: :tool_calls | :final_answer
```

# `run_opts`

```elixir
@type run_opts() :: [
  timeout: pos_integer() | nil,
  tools: map() | [module()] | module() | nil
]
```

# `t`

```elixir
@type t() :: %Jido.AI.Turn{
  content_parts: [ReqLLM.Message.ContentPart.t()],
  finish_reason: atom() | nil,
  message_metadata: map(),
  model: String.t() | nil,
  reasoning_details: list() | nil,
  text: String.t(),
  thinking_content: String.t() | nil,
  tool_calls: [term()],
  tool_results: [tool_result()],
  type: response_type(),
  usage: map() | nil
}
```

# `tool_result`

```elixir
@type tool_result() :: %{
  id: String.t(),
  name: String.t(),
  content: tool_result_content(),
  raw_result: execute_result()
}
```

# `tool_result_content`

```elixir
@type tool_result_content() :: String.t() | [ReqLLM.Message.ContentPart.t()]
```

# `tools_map`

```elixir
@type tools_map() :: %{required(String.t()) =&gt; module()}
```

# `assistant_content`

```elixir
@spec assistant_content(t()) :: String.t() | [ReqLLM.Message.ContentPart.t()]
```

Returns the ordered visible content for assistant-message projection.

# `assistant_message`

```elixir
@spec assistant_message(t()) :: ReqLLM.Message.t()
```

Projects the turn into an assistant message compatible with ReqLLM context.

# `build_tools_map`

```elixir
@spec build_tools_map(module() | [module()]) :: tools_map()
```

Builds a tools map from action modules.

# `execute`

```elixir
@spec execute(String.t(), map(), map(), execute_opts()) :: execute_result()
```

Executes a tool by name using a tools map and returns raw action output.

# `execute_module`

```elixir
@spec execute_module(module(), map(), map(), execute_opts()) :: execute_result()
```

Executes an action module directly without registry lookup.

# `extract_from_content`

```elixir
@spec extract_from_content(term()) :: String.t()
```

Extracts text from a content value (not wrapped in response structure).

# `extract_text`

```elixir
@spec extract_text(term()) :: String.t()
```

Extracts text content from an LLM response or content value.

This supports the canonical response/content normalization shapes used
across actions and strategy flows.

# `format_tool_result_content`

```elixir
@spec format_tool_result_content(execute_result() | {:ok, term()} | {:error, term()}) ::
  tool_result_content()
```

Formats a raw tool execution result into tool message content.

# `from_response`

```elixir
@spec from_response(map() | ReqLLM.Response.t() | t(), keyword()) :: t()
```

Builds a turn from a ReqLLM response.

Options:

- `:model` - Override model from the response payload

# `from_result_map`

```elixir
@spec from_result_map(map() | t()) :: t()
```

Builds a turn from a map that is already in classified result shape.

# `images`

```elixir
@spec images(t()) :: [ReqLLM.Message.ContentPart.t()]
```

Returns generated image content parts in response order.

# `needs_tools?`

```elixir
@spec needs_tools?(t()) :: boolean()
```

Returns true when the turn requests tool execution.

# `normalize_params`

```elixir
@spec normalize_params(map(), keyword() | struct()) :: map()
```

Normalizes parameters from LLM format to schema-compliant format.

# `result`

```elixir
@spec result(t()) :: String.t() | [ReqLLM.Message.ContentPart.t()]
```

Returns text for text-only turns or ordered content parts for multimodal turns.

# `run_tool_calls`

```elixir
@spec run_tool_calls([term()], map(), run_opts()) :: {:ok, [tool_result()]}
```

Executes normalized tool calls and returns normalized tool results.

# `run_tools`

```elixir
@spec run_tools(t(), map(), run_opts()) :: {:ok, t()} | {:error, term()}
```

Executes all requested tools for the turn and returns the updated turn.

# `to_result_map`

```elixir
@spec to_result_map(t()) :: map()
```

Converts a turn to a plain result map for public action/plugin outputs.

# `tool_messages`

```elixir
@spec tool_messages(t() | [map()]) :: [ReqLLM.Message.t()]
```

Projects tool results into `role: :tool` messages.

# `with_tool_results`

```elixir
@spec with_tool_results(t(), [map()]) :: t()
```

Returns a copy of the turn with normalized tool results attached.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
