#[non_exhaustive]pub enum ToolOutcome {
Success,
Error(ToolFailure),
Skipped,
Denied,
}Expand description
The structured outcome of a tool call: what happened, independent of the model-visible text.
This is Rig’s answer to “was that a success or an error?” without inspecting
the result string. It mirrors Pydantic AI’s outcome: 'success' | 'failed' | 'denied' and the Vercel AI SDK’s tool-result vs tool-error distinction.
§Skipped vs Denied
Both mean the tool body did not run, but they come from opposite sides — the framework vs. the tool — and are not synonyms:
Skippedis produced by the framework when aToolCallhook returnsFlow::Skip. Approval-policy denials useFlow::Skip, so they surface asSkipped, notDenied— there is noFlow::Deny. A policy that wants to distinguish its denials from other skips can key off the skip reason it supplied, or attach its own metadata.Deniedis authored by the tool, viaToolReturn::denied/ToolExecutionResult::denied— the tool ran its own check and refused the call (e.g. an internal authorization check). This is the tool-side counterpart to a hook skip: tools express refusal asDenied, notSkipped(there is no tool-authored skip constructor).
So is_skipped means “a hook skipped the call” and
is_denied means “the tool refused it” — unambiguously,
because the split is enforced by the type system: a tool authors a
ToolReturnOutcome, which has no Skipped variant, and the observed
Skipped outcome can be produced only inside the crate (the framework). A
tool cannot construct a return or a ToolExecutionResult that claims to
have been skipped.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Success
The tool ran and produced output normally.
Error(ToolFailure)
The tool failed. Carries the structured ToolFailure; the model still
receives ToolExecutionResult::model_output as feedback.
Skipped
The tool body did not run because a
ToolCall hook returned
Flow::Skip. This is a framework outcome
and includes approval-policy denials, which are expressed as Flow::Skip
(see the type-level note).
Denied
A tool declared the call denied by returning ToolReturn::denied /
ToolExecutionResult::denied — it ran its own check and refused. This is
not produced by a hook Flow::Skip (those are
Skipped); it is the tool-side counterpart to a skip (see
the type-level note).
Implementations§
Source§impl ToolOutcome
impl ToolOutcome
Sourcepub const fn as_str(&self) -> &'static str
pub const fn as_str(&self) -> &'static str
A stable, machine-friendly identifier for the outcome, for tracing/metrics.
Sourcepub const fn is_success(&self) -> bool
pub const fn is_success(&self) -> bool
Whether the tool ran successfully.
Sourcepub const fn is_skipped(&self) -> bool
pub const fn is_skipped(&self) -> bool
Whether a hook skipped the call (Flow::Skip) before execution — a
framework outcome that includes approval-policy denials (see the
type-level note).
Sourcepub const fn is_denied(&self) -> bool
pub const fn is_denied(&self) -> bool
Whether a tool refused the call (via ToolReturn::denied). Hook /
approval-policy Flow::Skip denials are Skipped, not
Denied (see the type-level note).
Sourcepub const fn failure(&self) -> Option<&ToolFailure>
pub const fn failure(&self) -> Option<&ToolFailure>
The ToolFailure if this is an Error, else None.
Sourcepub const fn error_kind(&self) -> Option<ToolFailureKind>
pub const fn error_kind(&self) -> Option<ToolFailureKind>
The ToolFailureKind if this is an Error, else None.
Sourcepub fn is_error_kind(&self, kind: ToolFailureKind) -> bool
pub fn is_error_kind(&self, kind: ToolFailureKind) -> bool
Whether this is an Error of exactly kind.
The predicate a hook uses to react to a specific failure class:
use rig_core::tool::{ToolFailure, ToolFailureKind, ToolOutcome};
let outcome = ToolOutcome::Error(ToolFailure::timeout("slow upstream"));
assert!(outcome.is_error_kind(ToolFailureKind::Timeout));
assert!(!outcome.is_error_kind(ToolFailureKind::NotFound));Trait Implementations§
Source§impl Clone for ToolOutcome
impl Clone for ToolOutcome
Source§fn clone(&self) -> ToolOutcome
fn clone(&self) -> ToolOutcome
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ToolOutcome
impl Debug for ToolOutcome
impl Eq for ToolOutcome
Source§impl From<ToolReturnOutcome> for ToolOutcome
impl From<ToolReturnOutcome> for ToolOutcome
Source§fn from(outcome: ToolReturnOutcome) -> Self
fn from(outcome: ToolReturnOutcome) -> Self
Source§impl PartialEq for ToolOutcome
impl PartialEq for ToolOutcome
impl StructuralPartialEq for ToolOutcome
Auto Trait Implementations§
impl Freeze for ToolOutcome
impl RefUnwindSafe for ToolOutcome
impl Send for ToolOutcome
impl Sync for ToolOutcome
impl Unpin for ToolOutcome
impl UnsafeUnpin for ToolOutcome
impl UnwindSafe for ToolOutcome
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneDebuggableStorage for Twhere
T: DebuggableStorage + Clone,
impl<T> CloneDebuggableStorage for Twhere
T: DebuggableStorage + Clone,
fn clone_storage(&self) -> Box<dyn CloneDebuggableStorage>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> CloneableStorage for T
impl<T> CloneableStorage for T
fn clone_storage(&self) -> Box<dyn CloneableStorage>
impl<T> DebuggableStorage for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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