Skip to main content

TurnResult

Struct TurnResult 

Source
pub struct TurnResult {
    pub messages: Vec<Message>,
    pub usage: Usage,
    pub stop: Option<StopReason>,
    pub pending_approvals: Vec<PendingApproval>,
    pub handoff: Option<HandoffRequest>,
    pub unattended_denials: Vec<UnattendedDenial>,
    pub mid_stream_failure: Option<MidStreamFailure>,
    pub delegate_records: Vec<DelegateRecord>,
    pub grounded: bool,
    pub pending_questions: Vec<PendingQuestion>,
}
Expand description

Output of one run_turn call.

Carries the wire messages produced (assistant text and tool results), the aggregated usage across every provider call in the loop, and the stop reason from the final step.

When Self::pending_approvals is non-empty the turn is paused: the model asked for one or more sensitive tools, run_turn short- circuited before executing them, and the caller must capture a human-in-the-loop decision (idiomatic Temporal “signal” pattern) before re-driving. The choice to surface this as a result field rather than an out-of-band callback keeps run_turn pure (no side-effect handle), keeps the durability boundary at the caller (the event log already gives us replay), and lets the per-conversation Mutex / Lease release while we wait — matching the durable-workflow pattern.

Fields§

§messages: Vec<Message>

Wire messages — assistant text + tool result messages, in order.

§usage: Usage

Sum of input_tokens / output_tokens across every provider call this turn made (the function-calling loop may iterate multiple times).

§stop: Option<StopReason>

Stop reason of the final provider step.

§pending_approvals: Vec<PendingApproval>

Tool calls awaiting human approval. Empty in the common case; when non-empty, the turn paused before executing any tool in this batch.

§handoff: Option<HandoffRequest>

Populated when the model emits the reserved __handoff_to tool call. The loop suspends before it executes more tools. The control plane emits a signed polyc_proto::proto::polychrome::handoff::v1::Handoff event into the parent event log. The transfer is one-way.

If multiple __handoff_to calls appear in the same tool batch (the model emitted two at once), only the first is honored — fan-out is a V2 concern and the wire shape doesn’t model parallel children today.

§unattended_denials: Vec<UnattendedDenial>

Gated calls an unattended turn denied fail-closed (#623): one entry per tool call the capability gate would have escalated on a turn with RunTurnOptions::unattended set. Each never ran and never paused; the model saw a legible denial result. Empty for every attended turn and for an unattended turn whose calls all cleared the gate. The control plane appends one durable, signed audit event per entry so the forensics trail records what was attempted and why it did not run — a tracing line cannot satisfy PRD §12.

§mid_stream_failure: Option<MidStreamFailure>

Set when the provider stream failed mid-turn — after complete_with_retry exhausted the connect/initial-response retry boundary, or during collect_turn’s fold of an already-open stream (#798).

The loop returns Ok with this populated rather than propagating the error via ?, so Self::messages / Self::usage still carry whatever earlier iterations already executed (tool calls, produced text) instead of discarding it. None on an ordinary turn. The caller (the harness loop / control plane) is expected to persist the partial result AND fail the turn with a typed error — never treat a Some here as a successful completion.

§delegate_records: Vec<DelegateRecord>

One entry per __delegate_to call this turn dispatched (#872): the forensic record of a worker sub-agent invocation, surfaced so the control plane can append a signed subagent_spawn/subagent_result pair plus a subagent_model_call determinism record — the delegation’s own forensic trail, attributed per sub-agent rather than folded into Self::usage. Empty for every turn that never called __delegate_to.

§grounded: bool

Whether native search grounding (CompletionRequest::web_search) was allowed for ANY step this turn made, conservatively treated as having ingested untrusted web content — grounding never produces a tool_result for worker_ingested_untrusted_content (private) to see, so a worker (or top-level turn) that grounded would otherwise come back laundered as fully first-party. The turn’s provider decides mid- generation whether it actually grounded; this flag doesn’t know either way, so it fails safe by tainting whenever grounding was merely allowed, not only when it was demonstrably used. false for a turn that never had the primitive granted or ran entirely under taint (which denies it outright).

§pending_questions: Vec<PendingQuestion>

Questions from an ask_question call awaiting an answer (#1660). Empty in the common case; when non-empty, the turn paused before executing any tool in this batch — mirroring Self::pending_approvals, but as an independent pause path (a clarifying question is not a danger/permission decision, so it never enters the HITL approval gate).

Trait Implementations§

Source§

impl Clone for TurnResult

Source§

fn clone(&self) -> TurnResult

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TurnResult

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TurnResult

Source§

fn default() -> TurnResult

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more