pub struct ToolResult {
pub content: Vec<Content>,
pub structured_content: Option<JsonObject>,
pub is_error: bool,
pub result_type: Option<String>,
pub extensions: Extensions,
}Expand description
The result of calling a tool.
Fields§
§content: Vec<Content>The result’s content blocks.
structured_content: Option<JsonObject>Structured output, 2025-06-18 and later (PR #371).
is_error: boolWhether the call failed. Every revision.
result_type: Option<String>The result’s type, 2026-07-28 and later.
Required rather than optional from 2026-07-28, where the schema
types it String and not Option<String>. That asymmetry is why this
is Option here and still needs a value on the wire: the IR is a
superset, so it cannot make a field mandatory for a revision that
predates it — but a codec targeting 2026-07-28 does have to supply
one, and that is a lowering decision rather than a lift.
extensions: ExtensionsUnmodelled fields.
Implementations§
Source§impl ToolResult
impl ToolResult
Sourcepub const fn new(content: Vec<Content>) -> Self
pub const fn new(content: Vec<Content>) -> Self
A result with the given content and no structured output.
Sourcepub fn with_structured(
self,
json: impl Into<String>,
) -> Result<Self, JsonObjectError>
pub fn with_structured( self, json: impl Into<String>, ) -> Result<Self, JsonObjectError>
Attaches structured output, which is what makes this a
2025-06-18-or-later value.
§Errors
JsonObjectError when json is
not a JSON object.
Sourcepub fn required_features(&self) -> FeatureSet
pub fn required_features(&self) -> FeatureSet
The features this result needs in order to be expressed.
The union of what every content block needs, plus
Feature::ToolStructuredOutput when there is structured output. Both
halves matter: a result of three audio blocks needs
ToolAudioContent exactly as much as a lone one does.
Sourcepub fn is_lossless_anywhere(&self) -> bool
pub fn is_lossless_anywhere(&self) -> bool
Whether this result can be expressed without losing anything.
This is the question lowering asks, and it is not the same as “the session has the features” — a result with no structured output and no exotic content needs nothing and is lowerable everywhere.
Sourcepub fn downgrade_structured_output(&mut self) -> Option<Downgrade>
pub fn downgrade_structured_output(&mut self) -> Option<Downgrade>
Applies the structured-output-downlevel fallback.
Appends the serialised structuredContent as a text content block and
clears the field. Returns None when there is nothing to downgrade, so
a caller can write if let Some(downgrade) = ... and only record a
report when a real change happened — a result that was already
lowerable must not produce a spurious entry in a TranslationReport.
§Examples
use protocol_droid::domain::ir::{Content, ToolResult};
let mut result = ToolResult::text("done").with_structured(r#"{"ok":true}"#)?;
assert_eq!(result.required_features().len(), 1);
let downgrade = result.downgrade_structured_output().unwrap();
assert_eq!(downgrade.lost, protocol_droid::domain::Feature::ToolStructuredOutput);
// The original text survived, and the JSON was appended.
assert_eq!(result.content.len(), 2);
assert!(result.structured_content.is_none());
// And it is now expressible at every revision.
assert!(result.is_lossless_anywhere());