Skip to main content

AgentStream

Struct AgentStream 

Source
pub struct AgentStream<'a> { /* private fields */ }
Expand description

Stream of agent events during execution

Implementations§

Source§

impl<'a> AgentStream<'a>

Source

pub async fn next(&mut self) -> Option<AgentEvent>

Get the next event from the agent stream

Examples found in repository?
examples/agent_streaming/main.rs (line 138)
96async fn main() -> Result<()> {
97    // Build the model
98    // Using a model that supports tool calling (e.g., Llama 3.1, Qwen, Mistral)
99    let model = TextModelBuilder::new("../hf_models/qwen3_4b")
100        .with_isq(IsqType::Q4K)
101        .with_logging()
102        .with_paged_attn(|| PagedAttentionMetaBuilder::default().build())?
103        .build()
104        .await?;
105
106    // Create the agent with registered tools
107    // - get_weather is a sync tool (runs in spawn_blocking)
108    // - web_search is an async tool (runs natively async)
109    // Both can execute in parallel when the model calls multiple tools
110    let agent = AgentBuilder::new(model)
111        .with_system_prompt(
112            "You are a helpful assistant with access to weather and web search tools. \
113             Use them when needed to answer user questions accurately.",
114        )
115        .with_max_iterations(5)
116        .with_parallel_tool_execution(true) // Enable parallel tool execution (default)
117        .register_tool(get_weather_tool_with_callback())
118        .register_tool(web_search_tool_with_callback())
119        .build();
120
121    println!("=== Agent with Streaming Output ===\n");
122    println!(
123        "User: What's the weather like in Boston, and can you find me some good restaurants there?\n"
124    );
125    print!("Assistant: ");
126
127    // Run the agent with streaming output
128    let mut stream = agent
129        .run_stream(
130            "What's the weather like in Boston, and can you find me some good restaurants there?",
131        )
132        .await?;
133
134    let stdout = std::io::stdout();
135    let mut handle = stdout.lock();
136
137    // Process streaming events
138    while let Some(event) = stream.next().await {
139        match event {
140            AgentEvent::TextDelta(text) => {
141                // Print text as it streams - this gives real-time output
142                write!(handle, "{}", text)?;
143                handle.flush()?;
144            }
145            AgentEvent::ToolCallsStart(calls) => {
146                // Model is about to call tools
147                writeln!(handle, "\n\n[Calling {} tool(s)...]", calls.len())?;
148                for call in &calls {
149                    writeln!(
150                        handle,
151                        "  - {}: {}",
152                        call.function.name, call.function.arguments
153                    )?;
154                }
155            }
156            AgentEvent::ToolResult(result) => {
157                // A single tool finished execution
158                let status = if result.result.is_ok() { "OK" } else { "ERROR" };
159                writeln!(
160                    handle,
161                    "  [Tool {} completed: {}]",
162                    result.tool_name, status
163                )?;
164            }
165            AgentEvent::ToolCallsComplete => {
166                // All tools finished, model will continue generating
167                writeln!(handle, "[All tools completed, continuing...]\n")?;
168                write!(handle, "Assistant: ")?;
169                handle.flush()?;
170            }
171            AgentEvent::Complete(response) => {
172                // Agent finished executing
173                writeln!(handle, "\n\n=== Agent Execution Summary ===")?;
174                writeln!(handle, "Completed in {} iteration(s)", response.iterations)?;
175                writeln!(handle, "Stop reason: {:?}", response.stop_reason)?;
176                writeln!(handle, "Steps taken: {}", response.steps.len())?;
177
178                match response.stop_reason {
179                    AgentStopReason::TextResponse => {
180                        writeln!(handle, "Final response delivered successfully.")?;
181                    }
182                    AgentStopReason::MaxIterations => {
183                        writeln!(
184                            handle,
185                            "Agent reached maximum iterations without producing a final response."
186                        )?;
187                    }
188                    AgentStopReason::NoAction => {
189                        writeln!(handle, "Agent produced no response.")?;
190                    }
191                    AgentStopReason::Error(e) => {
192                        writeln!(handle, "Agent encountered an error: {}", e)?;
193                    }
194                }
195            }
196        }
197    }
198
199    Ok(())
200}

Auto Trait Implementations§

§

impl<'a> Freeze for AgentStream<'a>

§

impl<'a> !RefUnwindSafe for AgentStream<'a>

§

impl<'a> Send for AgentStream<'a>

§

impl<'a> Sync for AgentStream<'a>

§

impl<'a> Unpin for AgentStream<'a>

§

impl<'a> !UnwindSafe for AgentStream<'a>

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> AsAny for T
where T: Any,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Source§

fn type_name(&self) -> &'static str

Gets the type name of self
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> Downcast for T
where T: AsAny + ?Sized,

Source§

fn is<T>(&self) -> bool
where T: AsAny,

Returns true if the boxed type is the same as T. Read more
Source§

fn downcast_ref<T>(&self) -> Option<&T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

fn downcast_mut<T>(&mut self) -> Option<&mut T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

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: 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: 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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
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
Source§

impl<T> ErasedDestructor for T
where T: 'static,