Skip to main content

ToolCallHandle

Struct ToolCallHandle 

Source
pub struct ToolCallHandle<'a, S> { /* private fields */ }
Expand description

One open tool call.

Created by RunContext::tool_call. TOOL_CALL_START has already gone out; Drop emits TOOL_CALL_END.

Arguments stream as text because providers stream them as text — a partial delta is usually not valid JSON. The handle keeps what it emitted, so parse_args can hand you the finished struct to execute against:

#[derive(Deserialize)]
struct Query { city: String }

let mut call = ctx.tool_call("get_weather")?;
call.args(r#"{"city":"#)?;          // as the provider streams them
call.args(r#""Seoul"}"#)?;
let query: Query = call.parse_args()?;
assert_eq!(query.city, "Seoul");
call.result(r#"{"tempC":21}"#)?;    // emits TOOL_CALL_END then TOOL_CALL_RESULT

§Doing the work while the call is open

The handle borrows the run’s event sink and its state, not the run context, so the tool’s own work belongs between the arguments and the result. The protocol treats the STATE_* family as unordered, so a publish inside the brackets is a legal stream — and the one that lets a client watch the call land instead of seeing it land already done:

#[derive(Default, Serialize, Deserialize)]
struct Board { tasks: Vec<String> }

let mut call = ctx.tool_call("add_task")?;
call.args_json(&json!({"title": "ship it"}))?;

call.state_mut().tasks.push("ship it".to_owned());
call.publish_state()?;               // STATE_SNAPSHOT, with the call open

call.result_json(&json!({"ok": true}))?;
assert_eq!(ctx.state().tasks, ["ship it"]);

What the handle still cannot do is open a second message, reasoning block or tool call: it holds no run context to open one with, and the context it came from stays borrowed until it drops.

Implementations§

Source§

impl<'a, S> ToolCallHandle<'a, S>

Source

pub fn id(&self) -> &ToolCallId

The id every event of this call carries.

Source

pub fn result_message_id(&self) -> &MessageId

The id the result message will carry.

Source

pub fn args(&mut self, delta: impl AsRef<str>) -> Result<()>

Appends a fragment of the argument JSON — TOOL_CALL_ARGS.

Source

pub fn args_json<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<()>

Serializes value and emits it as the call’s arguments in one delta.

Source

pub fn raw_args(&self) -> &str

The argument JSON emitted so far, unparsed.

Source

pub fn parse_args<T: DeserializeOwned>(&self) -> Result<T>

Parses everything emitted through args into T.

Fails while the arguments are still partial, which is the point: call it once the provider has finished streaming them.

Source

pub fn encrypted_value(&mut self, value: impl Into<String>) -> Result<()>

Attaches the provider’s opaque reasoning signature for this call — REASONING_ENCRYPTED_VALUE.

Source

pub fn emit(&mut self, event: Event) -> Result<()>

Emits an unrelated event without closing the call. See MessageHandle::emit.

Source

pub fn end(self) -> Result<()>

Emits TOOL_CALL_END and consumes the handle, leaving the call unanswered.

Use it when the client executes the tool — a front-end tool’s result arrives as a message on the next request, not from here.

Source

pub fn result(self, content: impl Into<String>) -> Result<MessageId>

Emits TOOL_CALL_END then TOOL_CALL_RESULT, and consumes the handle.

Returns the id of the tool message carrying the result.

Source

pub fn result_json<T: Serialize + ?Sized>(self, value: &T) -> Result<MessageId>

Serializes value and reports it as the call’s result.

Source§

impl<S: AgentState> ToolCallHandle<'_, S>

The run’s state, reachable while the call is open. Same three methods as on RunContext, forwarded — a tool that changes the state is the ordinary case, and it changes it in the middle of the call.

Source

pub fn state(&self) -> &S

The typed state, as of the last publish.

Source

pub fn state_mut(&mut self) -> &mut S

The typed state, mutably. Nothing is emitted until you call publish_state.

Source

pub fn publish_state(&mut self) -> Result<()>

Publishes whatever state_mut left behind, as a STATE_SNAPSHOT or a STATE_DELTA between this call’s TOOL_CALL_START and its TOOL_CALL_END.

A no-op when nothing changed since the last publish.

Trait Implementations§

Source§

impl<'a, S: Debug> Debug for ToolCallHandle<'a, S>

Source§

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

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

impl<S> Drop for ToolCallHandle<'_, S>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<'a, S> !RefUnwindSafe for ToolCallHandle<'a, S>

§

impl<'a, S> !Sync for ToolCallHandle<'a, S>

§

impl<'a, S> !UnwindSafe for ToolCallHandle<'a, S>

§

impl<'a, S> Freeze for ToolCallHandle<'a, S>

§

impl<'a, S> Send for ToolCallHandle<'a, S>
where S: Send,

§

impl<'a, S> Unpin for ToolCallHandle<'a, S>

§

impl<'a, S> UnsafeUnpin for ToolCallHandle<'a, S>

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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.

§

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

§

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
§

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, 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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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