pub struct ToolCall { /* private fields */ }Expand description
One call to one tool.
Built through ToolCatalog, so a tool nobody declared cannot be
constructed — the refusal happens before an effect exists, rather than inside
one.
Implementations§
Source§impl ToolCall
impl ToolCall
Sourcepub fn prepare(
catalog: &ToolCatalog,
client: Arc<dyn ToolClient>,
id: ToolId,
arguments: Value,
egress: Option<&Egress>,
) -> Result<Self, ToolError>
pub fn prepare( catalog: &ToolCatalog, client: Arc<dyn ToolClient>, id: ToolId, arguments: Value, egress: Option<&Egress>, ) -> Result<Self, ToolError>
Prepare a call, if the operator permits this tool.
§Prefer StepCtx::call_tool
This takes whatever catalogue it is handed, and nothing here binds that
catalogue to the manifest governing the caller. A hand-built one —
which is the obvious thing to write, and what an older version of
examples/governed_transfer.rs demonstrated — compiles, runs, and can be
laxer than the declaration: a ToolSafety::read_only entry for a tool
the manifest calls mutating exempts it from the whole-value taint gate and
carries Recovery::Retry, so a timed-out money-moving call is sent
again. The plane’s own catalogue is refused at build for exactly that
divergence; a skill’s is not checked by anything.
StepCtx::call_tool dispatches
over the plane’s checked catalogue and makes the drift unrepresentable.
Where a skill genuinely needs its own — a catalogue assembled before a
runtime exists, or one for a test — build it with
ToolCatalog::from_manifest, which derives the reach from the
declaration rather than restating it.
§Errors
ToolError::Unreachable when the tool is not in the catalogue. It is
deliberately not a separate “unknown tool” error at the call site: from
the run’s point of view an undeclared tool is one it cannot reach, and
treating it as anything softer invites a fallback.
Sourcepub fn answering(
self,
call: &ToolCall,
offered: &ToolDeclaration,
) -> Result<Self, ToolError>
pub fn answering( self, call: &ToolCall, offered: &ToolDeclaration, ) -> Result<Self, ToolError>
Mark this execution as the answer to a model’s call made to offered,
so its span carries the provider’s call id (gen_ai.tool.call.id).
Telemetry only: the id is in neither the effect key nor the journal’s descriptor. An id over 256 bytes is not recorded.
§Errors
ToolError::Unreachable when the call named another offer, or the
offer stands for another tool: a span joining this execution to the
call would say the model asked for what ran.
Trait Implementations§
Source§impl Effect for ToolCall
impl Effect for ToolCall
Source§fn gen_ai_request(&self) -> Option<GenAiRequest>
fn gen_ai_request(&self) -> Option<GenAiRequest>
No provider: a tool call names what ran, not who served it.
Source§fn trust(&self) -> Trust
fn trust(&self) -> Trust
A tool result is the outside world’s data.
Stated rather than inherited, because this is the one effect where a reader is most likely to wonder whether the catalogue could relax it. It cannot: the catalogue governs authority, not provenance.
Source§fn source(&self) -> SourceId
fn source(&self) -> SourceId
The tool’s own reference, so a source rule can name this tool.
tool://server/name — the spelling a manifest grants and a reviewer
reads. Under the family-level default every granted tool answered as
effect:tool.call, so a ProtectedField::from_sources rule could not
distinguish the CRM lookup from the ticket search: “the recipient must
come from the CRM” was unsatisfiable strictly, and satisfiable loosely
by whichever tool an injected prompt reached first.
Source§type Output = Value
type Output = Value
Source§fn gen_ai_operation(&self) -> Option<&'static str>
fn gen_ai_operation(&self) -> Option<&'static str>
Source§fn descriptor(&self) -> EffectDescriptor
fn descriptor(&self) -> EffectDescriptor
Source§fn recovery(&self) -> Recovery
fn recovery(&self) -> Recovery
InDoubt failure. The two are the
same situation reached from different directions.Source§fn retry(&self) -> RetryPolicy
fn retry(&self) -> RetryPolicy
Source§fn retries_landed(&self) -> bool
fn retries_landed(&self) -> bool
Source§fn max_sensitivity(&self) -> Sensitivity
fn max_sensitivity(&self) -> Sensitivity
Source§fn sink_arguments(&self) -> Option<&Value>
fn sink_arguments(&self) -> Option<&Value>
Source§fn rebind(&mut self, arguments: Value) -> bool
fn rebind(&mut self, arguments: Value) -> bool
arguments in place of the ones this effect was built over,
where it can — what a declared redaction at a sink needs. Read moreSource§fn protected_fields(&self) -> &[ProtectedField]
fn protected_fields(&self) -> &[ProtectedField]
Source§fn output_sensitivity(&self) -> Sensitivity
fn output_sensitivity(&self) -> Sensitivity
Source§fn attach(&mut self, provenance: &Provenance)
fn attach(&mut self, provenance: &Provenance)
Source§fn perform<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Value, EffectError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn perform<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Value, EffectError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn gen_ai_response(&self, output: &Self::Output) -> Option<GenAiResponse>
fn gen_ai_response(&self, output: &Self::Output) -> Option<GenAiResponse>
Source§fn carried(&self) -> Option<Tainted<Value>>
fn carried(&self) -> Option<Tainted<Value>>
Source§fn rebind_carried(&mut self, _carried: Value) -> bool
fn rebind_carried(&mut self, _carried: Value) -> bool
Source§fn outbound_bytes(&self) -> u64
fn outbound_bytes(&self) -> u64
Source§fn credential_binding(&self) -> Option<CredentialBinding>
fn credential_binding(&self) -> Option<CredentialBinding>
Auto Trait Implementations§
impl !RefUnwindSafe for ToolCall
impl !UnwindSafe for ToolCall
impl Freeze for ToolCall
impl Send for ToolCall
impl Sync for ToolCall
impl Unpin for ToolCall
impl UnsafeUnpin for ToolCall
Blanket Implementations§
Source§impl<E> AnyEffect for Ewhere
E: Effect,
impl<E> AnyEffect for Ewhere
E: Effect,
Source§fn spend_erased(&self, output: &Value) -> Spend
fn spend_erased(&self, output: &Value) -> Spend
Round-trips the output to ask the typed effect what it cost.
A type that cannot be deserialized from its own serialization is already
broken for replay — Effect::Output requires the round-trip, and the
journal reconstructs every output that way. Charging zero here is the
same answer replay would reach, and the defect surfaces where it belongs.
Source§fn gen_ai_response_erased(&self, output: &Value) -> Option<GenAiResponse>
fn gen_ai_response_erased(&self, output: &Value) -> Option<GenAiResponse>
Round-trips the output, for the reason
spend_erased does.
fn descriptor(&self) -> EffectDescriptor
fn attach_erased(&mut self, provenance: &Provenance)
fn gen_ai_operation(&self) -> Option<&'static str>
fn mutates(&self) -> bool
fn recovery(&self) -> Recovery
fn retry(&self) -> RetryPolicy
fn retries_landed(&self) -> bool
fn max_sensitivity(&self) -> Sensitivity
fn sink_arguments(&self) -> Option<&Value>
fn rebind_erased(&mut self, arguments: Value) -> bool
fn carried(&self) -> Option<Tainted<Value>>
fn rebind_carried_erased(&mut self, carried: Value) -> bool
fn outbound_bytes(&self) -> u64
fn credential_binding(&self) -> Option<CredentialBinding>
fn protected_fields(&self) -> &[ProtectedField]
fn delegation_depth(&self) -> Option<usize>
fn source(&self) -> SourceId
fn trust(&self) -> Trust
fn output_sensitivity(&self) -> Sensitivity
fn gen_ai_request(&self) -> Option<GenAiRequest>
fn perform_erased<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Value, EffectError>> + Send + 'async_trait>>where
'life0: 'async_trait,
E: 'async_trait,
fn reconcile_erased<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Reconciliation<Value>, EffectError>> + Send + 'async_trait>>where
'life0: 'async_trait,
E: 'async_trait,
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
Source§impl<E> BuildsEffect<E> for Ewhere
E: Effect,
impl<E> BuildsEffect<E> for Ewhere
E: Effect,
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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