Host-owned, single-agent turn.
turn/3 advances an AgentEngine.Session by one exchange — it appends
the user message (or host-resolved tool results), calls the host-supplied
LLM function once, and records the assistant reply. It is distilled from the
public turn/recomposition path of host applications: one LLM call per
invocation, then either a completed reply or a suspension awaiting tool
results. AgentEngine never executes host tools and performs no provider
routing — the :llm function is the host's seam for both.
Frozen success shape
{:ok, content, updated_runtime, signals}The shape is frozen and must not change without a major version bump:
content— the assistant's final text (a binary), ornilwhen the turn suspended awaiting tool results.updated_runtime— anAgentEngine.Turn.Runtimethat embeds the advancedAgentEngine.Sessionplus the working transcript, so a suspended turn can be resumed by passing it back intoturn/3.signals— a list produced by the optional:extract_signalscallback, defaulting to[]when no extractor is supplied.
Tool-call round trip
When the LLM requests tool calls, the turn suspends:
{:ok, nil, runtime, []}The host executes the calls, then resumes by passing the runtime back with
:tool_results:
Turn.turn(runtime, nil, llm: llm, tool_results: results)If a new user message is submitted while tool calls are still pending, the
turn refuses with {:error, {:tool_results_required, ids}}.
Options
:llm(required) —(messages, llm_opts) -> {:ok, response} | {:error, term()}whereresponseis anLlmCore.LLM.Response(or any map withcontentandtool_callsfields).messagesis the normalized transcript.:tools— list ofLlmToolkit.Toolstructs forwarded to the LLM (default[]). AgentEngine advertises them generically; it never runs them.:tool_results— list ofLlmToolkit.Tool.Resultstructs (or maps) used to resume a suspended turn (default[]).:system_prompt— optional system message prepended once to a fresh transcript.:llm_opts— extra keyword options merged into the LLM call options.:extract_signals— optional(content -> [term()])callback applied to the final assistant content. Absent extractor ⇒signals == [].
Summary
Functions
Run a single agent turn.
Types
@type opts() :: [ llm: llm(), tools: [LlmToolkit.Tool.t()], tool_results: [map() | struct()], system_prompt: String.t(), llm_opts: keyword(), extract_signals: signal_extractor() | nil ]
Functions
@spec turn( AgentEngine.Session.t() | AgentEngine.Turn.Runtime.t(), String.t() | nil, opts() ) :: {:ok, String.t() | nil, AgentEngine.Turn.Runtime.t(), [term()]} | {:error, term()}
Run a single agent turn.
Accepts either a bare AgentEngine.Session (for the first turn of a
conversation) or a previously returned AgentEngine.Turn.Runtime (to
continue). Returns the frozen success shape, or an error.