pub struct ToolOutput { /* private fields */ }Expand description
The return value of a Rust tool execution.
Every tool produces a ToolOutput containing:
content: the text sent back to the model.metadata: an optional structured key-value map available to hooks, policies, and logging pipelines — but never sent to the model.
§Ergonomics
ToolOutput implements From<String>, From<&str>, and Display, so
simple tools can return plain strings without ceremony:
use llm_tool::ToolOutput;
use serde::Serialize;
// From a String
let out: ToolOutput = "hello".to_string().into();
assert_eq!(out.content(), "hello");
assert!(out.metadata().is_empty());
// From &str
let out: ToolOutput = "world".into();
assert_eq!(out.content(), "world");
// Structured metadata from a typed struct (preferred)
#[derive(Serialize)]
struct ReadMeta {
bytes_read: usize,
cached: bool,
}
let out = ToolOutput::new("file contents…")
.with_metadata(&ReadMeta {
bytes_read: 1024,
cached: true,
})
.unwrap();
assert_eq!(out.metadata()["bytes_read"], 1024);
assert_eq!(out.metadata()["cached"], true);
// Single ad-hoc entry
let out = ToolOutput::new("done").with_meta("exit_code", serde_json::json!(0));
assert_eq!(out.metadata()["exit_code"], 0);Implementations§
Source§impl ToolOutput
impl ToolOutput
Sourcepub fn quarantined(self) -> Self
pub fn quarantined(self) -> Self
Return a quarantined copy of this ToolOutput, neutralizing control
delimiters and wrapping the content in <tool_output_quarantine> tags.
Idempotent when called on an already-quarantined output.
Sourcepub fn is_quarantined(&self) -> bool
pub fn is_quarantined(&self) -> bool
Returns true if this output’s content is wrapped in a verified
<tool_output_quarantine> envelope with no un-neutralized delimiters.
Source§impl ToolOutput
impl ToolOutput
Sourcepub fn new(content: impl Into<String>) -> Self
pub fn new(content: impl Into<String>) -> Self
Create a new ToolOutput with the given content and no metadata.
Sourcepub fn json<T: Serialize>(value: &T) -> Result<Self, ToolError>
pub fn json<T: Serialize>(value: &T) -> Result<Self, ToolError>
Serialize a value to JSON and wrap it as tool output.
The JSON string becomes the content sent to the model, but no
metadata is attached. For the zero-redundancy path that populates
both content and metadata from the same struct, use
from_metadata.
use llm_tool::{ToolOutput, ToolError};
let data = serde_json::json!({"temp": 72, "unit": "F"});
let output = ToolOutput::json(&data).unwrap();
assert!(output.content().contains("72"));
assert!(output.metadata().is_empty()); // no metadata attached§Errors
Returns Err(ToolError) if serialization fails.
Sourcepub fn from_metadata<T: Serialize>(value: &T) -> Result<Self, ToolError>
pub fn from_metadata<T: Serialize>(value: &T) -> Result<Self, ToolError>
Create a ToolOutput where both the content and metadata come
from the same serializable value.
- Content (sent to the model): the JSON representation of
value. - Metadata (hooks / policies / logging): the flattened object fields.
This is the zero-redundancy path: define one struct, derive
Serialize, and everything is populated automatically.
§Errors
Returns Err(ToolError) if value doesn’t serialize to a JSON object.
§Example
use llm_tool::ToolOutput;
use serde::Serialize;
#[derive(Serialize)]
struct Weather {
location: String,
temp_f: i32,
condition: String,
}
let out = ToolOutput::from_metadata(&Weather {
location: "Seattle".into(),
temp_f: 72,
condition: "Sunny".into(),
})
.unwrap();
// Model sees the JSON string
assert!(out.content().contains("Seattle"));
assert!(out.content().contains("72"));
// Hooks see typed fields
assert_eq!(out.metadata()["location"], "Seattle");
assert_eq!(out.metadata()["temp_f"], 72);Sourcepub fn with_meta(self, key: impl Into<String>, value: Value) -> Self
pub fn with_meta(self, key: impl Into<String>, value: Value) -> Self
Attach a single metadata key-value pair. Chainable.
For attaching multiple fields at once, prefer
with_metadata with a typed struct.
Sourcepub fn with_metadata<T: Serialize>(self, value: &T) -> Result<Self, ToolError>
pub fn with_metadata<T: Serialize>(self, value: &T) -> Result<Self, ToolError>
Attach structured metadata from a serializable value.
The value is serialized to a JSON object and its fields are merged into the metadata map. This is the preferred way to attach metadata because it avoids stringly-typed keys and data duplication.
§Errors
Returns Err(ToolError) if value doesn’t serialize to a JSON object
(e.g. it serializes to a scalar or array).
§Example
use llm_tool::ToolOutput;
use serde::Serialize;
#[derive(Serialize)]
struct FileMeta {
bytes_read: usize,
source: String,
}
let out = ToolOutput::new("file contents")
.with_metadata(&FileMeta {
bytes_read: 1024,
source: "/etc/hosts".into(),
})
.unwrap();
assert_eq!(out.metadata()["bytes_read"], 1024);
assert_eq!(out.metadata()["source"], "/etc/hosts");Sourcepub fn into_content(self) -> String
pub fn into_content(self) -> String
Consume self and return the owned content string.
Sourcepub fn truncated(self, policy: &TruncationPolicy) -> Self
pub fn truncated(self, policy: &TruncationPolicy) -> Self
Truncate the output text content according to the given TruncationPolicy.
Sourcepub fn truncate_detailed(
&mut self,
policy: &TruncationPolicy,
) -> Result<TruncationOutcome<'static>, SpillError>
pub fn truncate_detailed( &mut self, policy: &TruncationPolicy, ) -> Result<TruncationOutcome<'static>, SpillError>
Truncate the output text content according to the given TruncationPolicy,
returning a detailed TruncationOutcome.
§Errors
Returns SpillError if an OutputSpillSink is configured and fails.
Sourcepub fn truncate_detailed_with_context(
&mut self,
policy: &TruncationPolicy,
ctx: &SpillContext<'_>,
) -> Result<TruncationOutcome<'static>, SpillError>
pub fn truncate_detailed_with_context( &mut self, policy: &TruncationPolicy, ctx: &SpillContext<'_>, ) -> Result<TruncationOutcome<'static>, SpillError>
Truncate the output text content with caller context according to TruncationPolicy.
§Errors
Returns SpillError if an OutputSpillSink is configured and fails.