pub struct DynamicTool { /* private fields */ }Expand description
A tool defined at runtime: its definition and a callback over JSON
arguments. It is its own handler (Serve), keyed
by its name. The optional liveness probe supports registry retirement;
serving does not consult it.
Implementations§
Source§impl DynamicTool
impl DynamicTool
Sourcepub fn new<F>(
name: ToolName,
description: impl Into<String>,
parameters: Value,
callback: F,
) -> Selfwhere
F: Fn(Value) -> WasmBoxedFuture<'static, Result<ToolOutput, ToolExecutionError>> + WasmCompatSend + WasmCompatSync + 'static,
pub fn new<F>(
name: ToolName,
description: impl Into<String>,
parameters: Value,
callback: F,
) -> Selfwhere
F: Fn(Value) -> WasmBoxedFuture<'static, Result<ToolOutput, ToolExecutionError>> + WasmCompatSend + WasmCompatSync + 'static,
Define a tool from a context-free callback over owned arguments.
Sourcepub fn new_with_context<F>(
name: ToolName,
description: impl Into<String>,
parameters: Value,
callback: F,
) -> Selfwhere
F: ToolCallback + 'static,
pub fn new_with_context<F>(
name: ToolName,
description: impl Into<String>,
parameters: Value,
callback: F,
) -> Selfwhere
F: ToolCallback + 'static,
Define a tool from a callback over the dispatch-scoped context.
Sourcepub fn with_annotations(self, annotations: ToolAnnotations) -> Self
pub fn with_annotations(self, annotations: ToolAnnotations) -> Self
The same tool, stating what calling it does to the world.
Sourcepub fn with_liveness<F>(self, is_live: F) -> Self
pub fn with_liveness<F>(self, is_live: F) -> Self
Attach a liveness probe.
Sourcepub fn definition(&self) -> ToolDefinition
pub fn definition(&self) -> ToolDefinition
The tool’s definition.
Sourcepub fn into_parts(self) -> (ToolDefinition, ErasedHandler, Option<LivenessFn>)
pub fn into_parts(self) -> (ToolDefinition, ErasedHandler, Option<LivenessFn>)
Consumes the tool into its definition, its erased handler, and its optional liveness probe.
Sourcepub async fn run(&self, args: Value) -> Result<ToolOutput, ToolExecutionError>
pub async fn run(&self, args: Value) -> Result<ToolOutput, ToolExecutionError>
Runs the tool on JSON args with an empty ToolContext, as
Self::run_with does.
use rig_core::{message::ToolName, tool::{DynamicTool, ToolExecutionError, ToolOutput}};
use serde_json::json;
let add = DynamicTool::new(ToolName::new("add")?, "Adds a and b", json!({}), |args| {
Box::pin(async move {
let int = |key| args.get(key).and_then(serde_json::Value::as_i64);
let sum = int("a").zip(int("b")).map(|(a, b)| a + b);
sum.map(|sum| ToolOutput::json(json!(sum)))
.ok_or_else(|| ToolExecutionError::invalid_args("a and b must be integers"))
})
});
let output = futures::executor::block_on(add.run(json!({ "a": 2, "b": 3 })))?;
assert_eq!(output.as_json(), Some(&json!(5)));
assert!(futures::executor::block_on(add.run(json!({ "a": "two" }))).is_err());Sourcepub async fn run_with(
&self,
context: &mut ToolContext,
args: Value,
) -> Result<ToolOutput, ToolExecutionError>
pub async fn run_with( &self, context: &mut ToolContext, args: Value, ) -> Result<ToolOutput, ToolExecutionError>
Runs the tool on JSON args as a dispatch of its call runs it, and
returns its output or its error (invalid arguments included). The
tool sees context’s inbound values, and what it publishes with
insert_result lands in context. No registry or agent is involved.
use rig_core::{message::ToolName, tool::{ContextValue, DynamicTool, ToolContext, ToolOutput}};
use serde_json::json;
#[derive(serde::Serialize, serde::Deserialize)]
struct User(String);
impl ContextValue for User { const KEY: &'static str = "user"; }
#[derive(serde::Serialize, serde::Deserialize)]
struct Greeted(bool);
impl ContextValue for Greeted { const KEY: &'static str = "greeted"; }
let greet = DynamicTool::new_with_context(ToolName::new("greet")?, "Greets the user", json!({}),
|context, _args| Box::pin(async move {
let user = context.require::<User>()?;
context.insert_result(Greeted(true))?;
Ok(ToolOutput::text(format!("hello {}", user.0)))
}));
let mut context = ToolContext::new();
context.insert(User("ada".into()))?;
let output = futures::executor::block_on(greet.run_with(&mut context, json!({})))?;
assert_eq!(output.as_text(), Some("hello ada"));
assert_eq!(context.result::<Greeted>()?.map(|greeted| greeted.0), Some(true));Trait Implementations§
Source§impl Clone for DynamicTool
impl Clone for DynamicTool
Source§impl Debug for DynamicTool
impl Debug for DynamicTool
Source§impl Serve for DynamicTool
impl Serve for DynamicTool
Source§fn descriptor(&self) -> HandlerDescriptor
fn descriptor(&self) -> HandlerDescriptor
Source§fn key(&self) -> HandlerKey
fn key(&self) -> HandlerKey
Source§async fn serve(&self, kind: EffectKind, dispatch: Dispatch) -> Reply
async fn serve(&self, kind: EffectKind, dispatch: Dispatch) -> Reply
Source§fn footprint(&self, kind: &EffectKind) -> Option<Touches>
fn footprint(&self, kind: &EffectKind) -> Option<Touches>
kind may read and change, for a tool’s handler
(Tool::footprint); None when it
cannot say, such as for arguments that do not parse.Source§fn check(&self, kind: &EffectKind) -> Vec<UnsupportedOption>
fn check(&self, kind: &EffectKind) -> Vec<UnsupportedOption>
kind this handler would leave out when it serves
it, with nothing sent: for a model’s handler, what its wire or model
cannot honour (DynModel::check).
Empty when it leaves nothing out or cannot say, as by default.Auto Trait Implementations§
impl !RefUnwindSafe for DynamicTool
impl !UnwindSafe for DynamicTool
impl Freeze for DynamicTool
impl Send for DynamicTool
impl Sync for DynamicTool
impl Unpin for DynamicTool
impl UnsafeUnpin for DynamicTool
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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