pub struct FunctionTool { /* private fields */ }Expand description
A concrete, locally executable tool built from a closure.
This is the Rust analogue of upstream’s FunctionTool / the @tool
decorator (formerly AIFunction / @ai_function).
Implementations§
Source§impl FunctionTool
impl FunctionTool
Sourcepub fn new<F, Fut>(
name: impl Into<String>,
description: impl Into<String>,
parameters: Value,
func: F,
) -> Self
pub fn new<F, Fut>( name: impl Into<String>, description: impl Into<String>, parameters: Value, func: F, ) -> Self
Create a function tool from a hand-written JSON Schema.
parametersis the JSON Schema for the arguments object.funcreceives the parsed JSON arguments and returns a JSON result.
Prefer FunctionTool::typed when the arguments can be expressed as a
#[derive(Deserialize, JsonSchema)] struct.
Sourcepub fn typed<Args, Ret, F, Fut>(
name: impl Into<String>,
description: impl Into<String>,
f: F,
) -> Selfwhere
Args: DeserializeOwned + JsonSchema + Send + 'static,
Ret: Serialize,
F: Fn(Args) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Ret>> + Send + 'static,
pub fn typed<Args, Ret, F, Fut>(
name: impl Into<String>,
description: impl Into<String>,
f: F,
) -> Selfwhere
Args: DeserializeOwned + JsonSchema + Send + 'static,
Ret: Serialize,
F: Fn(Args) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<Ret>> + Send + 'static,
Create a function tool whose parameters schema and argument
deserialization are derived from a Rust type, instead of a
hand-written serde_json::Value schema.
Args must implement schemars::JsonSchema (to derive the
parameters schema) and serde::de::DeserializeOwned (to parse the
model-supplied arguments); Ret need only implement
serde::Serialize – return serde_json::Value directly (as in
the example below), or any other serializable type.
§Parameters schema
The schema is generated once, at construction, via schemars’
SchemaGenerator (the machinery behind its schema_for! macro, which
cannot itself target a type parameter), then lightly post-processed
for OpenAI-style function parameters: the top-level $schema and
title keys are stripped. For a “simple” struct (only
primitive/string/number/bool/Vec/Option fields) this leaves
exactly {"type": "object", "properties": {...}, "required": [...]}
– a field is listed in required unless it is an Option<_> or
carries #[serde(default)]. Nested structs and enums keep
schemars’ own representation: a top-level definitions map with
$refs into it (schemars 0.8’s convention for referenceable types).
This is not inlined – every provider converter in this workspace
forwards ToolDefinition::parameters to the wire unmodified, so a
$ref/definitions pair round-trips exactly like any other
JSON-Schema keyword this crate doesn’t otherwise interpret.
§Argument errors
If the model-supplied JSON arguments don’t deserialize into Args
(e.g. a required field is missing or mistyped), Tool::invoke
returns Err(Error::Tool) rather than panicking or silently
substituting a default – the same Result-propagation shape used
for every other tool-execution failure (a closure error from
FunctionTool::new, an FunctionTool::max_invocations limit, …),
which the function-invocation loop turns into an error
crate::types::FunctionResultContent exactly as it would for any
of those.
§Example
use agent_framework_core::tools::FunctionTool;
#[derive(serde::Deserialize, schemars::JsonSchema)]
struct WeatherArgs {
city: String,
#[serde(default)]
units: Option<String>,
}
let _tool = FunctionTool::typed(
"get_weather",
"Get the weather.",
|args: WeatherArgs| async move {
Ok(serde_json::json!({ "city": args.city, "temp": 21 }))
},
);Sourcepub fn with_approval_mode(self, mode: ApprovalMode) -> Self
pub fn with_approval_mode(self, mode: ApprovalMode) -> Self
Builder: set the human-in-the-loop approval mode (default
ApprovalMode::NeverRequire). Carried through to the
ToolDefinition produced by FunctionTool::into_definition.
Sourcepub fn max_invocations(self, max: usize) -> Self
pub fn max_invocations(self, max: usize) -> Self
Builder: cap the number of times this function may be invoked.
Once FunctionTool::invocation_count reaches max, further calls to
Tool::invoke return Err(Error::Tool) instead of running
the function again – mirrors Python’s
AIFunction(max_invocations=...) (_tools.py:599-600, 687-690).
None (the default) means no limit.
Unlike Python, which raises ValueError at construction for a value
less than 1, a value of 0 is accepted here: it simply means the
limit is already reached, so every invocation errors immediately
(the same terminal state Python’s validation exists to prevent
constructing in the first place).
The counter is shared by every Clone of this FunctionTool (see the
note on FunctionTool’s fields), not reset per clone.
Sourcepub fn max_invocation_exceptions(self, max: usize) -> Self
pub fn max_invocation_exceptions(self, max: usize) -> Self
Builder: cap the number of invocation failures this function tolerates.
Every Tool::invoke call that returns Err – whether from
argument deserialization (see FunctionTool::typed), the wrapped
closure itself, or result serialization – increments
FunctionTool::invocation_exception_count. Once that count reaches
max, further calls return Err(Error::Tool) immediately
without re-attempting the function. None (the default) means no
limit. Mirrors Python’s AIFunction(max_invocation_exceptions=...)
(_tools.py:601-602, 691-698); see FunctionTool::max_invocations
for how the 0 case differs from Python’s constructor-time
validation.
Sourcepub fn invocation_count(&self) -> usize
pub fn invocation_count(&self) -> usize
The number of times Tool::invoke has run the wrapped function
(i.e. got past any FunctionTool::max_invocations/
FunctionTool::max_invocation_exceptions gate). Mirrors Python’s
public invocation_count attribute.
Sourcepub fn invocation_exception_count(&self) -> usize
pub fn invocation_exception_count(&self) -> usize
The number of those invocations that returned Err. Mirrors
Python’s public invocation_exception_count attribute.
Sourcepub fn into_definition(self) -> ToolDefinition
pub fn into_definition(self) -> ToolDefinition
Convert into a ToolDefinition for use in chat options.
Trait Implementations§
Source§impl Clone for FunctionTool
impl Clone for FunctionTool
Source§fn clone(&self) -> FunctionTool
fn clone(&self) -> FunctionTool
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Tool for FunctionTool
impl Tool for FunctionTool
Source§fn invoke<'life0, 'async_trait>(
&'life0 self,
arguments: Value,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn invoke<'life0, 'async_trait>(
&'life0 self,
arguments: Value,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Run the wrapped function, first enforcing
FunctionTool::max_invocations and
FunctionTool::max_invocation_exceptions (mirrors Python’s
AIFunction.__call__, _tools.py:683-707): a limit that has already
been reached errors before the function runs and before
FunctionTool::invocation_count is bumped again, so calling an
already-exhausted function any number of further times does not
drift its counters.
The invocation slot is reserved atomically (fetch_update), because
the function-invocation loop executes a model’s parallel calls to the
same tool concurrently — a plain check-then-increment would let two
racing calls both slip under max_invocations.
Source§fn description(&self) -> &str
fn description(&self) -> &str
Source§fn parameters_schema(&self) -> Value
fn parameters_schema(&self) -> Value
Source§fn invoke_in_context<'life0, 'life1, 'async_trait>(
&'life0 self,
arguments: Value,
_ctx: &'life1 FunctionInvocationContext,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn invoke_in_context<'life0, 'life1, 'async_trait>(
&'life0 self,
arguments: Value,
_ctx: &'life1 FunctionInvocationContext,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
FunctionInvocationContext
(the agent session, middleware metadata, …). Read more