Skip to main content

llmy_agent/
agent.rs

1//! Outcome of one step of an agent loop.
2//!
3//! A "step" is a single round-trip with the model: the caller sends the
4//! current conversation, the model responds, and the response either ends
5//! the turn ([`StepResult::Stop`]) or asks for tools to be executed
6//! ([`StepResult::Toolcalled`]). Higher-level loops (see `llmy-harness`)
7//! drive these steps until a `Stop` is observed.
8
9/// The result of running one agent step.
10#[derive(Debug, Clone)]
11pub enum StepResult {
12    /// The model produced a final assistant message and did not request any
13    /// further tool calls. The wrapped string is that assistant message.
14    Stop(String),
15    /// The model issued one or more tool calls. The wrapped value is the
16    /// optional assistant text emitted alongside the tool calls (some
17    /// providers include reasoning or commentary in this field, others
18    /// leave it empty, hence the `Option`).
19    Toolcalled(Option<String>),
20}
21
22impl StepResult {
23    /// Returns the assistant text associated with this step, if any.
24    ///
25    /// For [`StepResult::Stop`] this is always the final message; for
26    /// [`StepResult::Toolcalled`] it is the optional text the model attached
27    /// to the tool-call response.
28    pub fn assistant_message(&self) -> Option<&String> {
29        match self {
30            Self::Stop(v) => Some(v),
31            Self::Toolcalled(v) => v.as_ref(),
32        }
33    }
34
35    /// Returns `true` if the model requested tool calls in this step.
36    pub fn did_tool_call(&self) -> bool {
37        matches!(self, Self::Toolcalled(_))
38    }
39
40    /// Returns `true` if the model finished its turn with a final message.
41    pub fn did_stop(&self) -> bool {
42        matches!(self, Self::Stop(_))
43    }
44}