Skip to main content

runifold_tool/
tool.rs

1use std::{future::Future, pin::Pin};
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use crate::{ToolContext, ToolDescriptor, ToolError};
7
8/// A boxed, sendable future returned by a tool.
9#[cfg(not(target_arch = "wasm32"))]
10pub type ToolFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
11
12/// A boxed Tool future on single-threaded WASM.
13#[cfg(target_arch = "wasm32")]
14pub type ToolFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
15
16/// Successful canonical tool output.
17#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
18pub struct ToolOutput {
19    /// Structured output value.
20    pub value: Value,
21    /// Whether the value is safe to expose verbatim to a model.
22    pub model_visible: bool,
23}
24
25impl ToolOutput {
26    /// Creates model-visible output.
27    pub const fn model_visible(value: Value) -> Self {
28        Self {
29            value,
30            model_visible: true,
31        }
32    }
33}
34
35/// Object-safe execution boundary implemented by tools.
36pub trait Tool: Send + Sync {
37    /// Returns the tool's immutable semantic contract.
38    fn descriptor(&self) -> &ToolDescriptor;
39
40    /// Executes one invocation.
41    fn invoke(
42        &self,
43        input: Value,
44        context: ToolContext,
45    ) -> ToolFuture<'_, Result<ToolOutput, ToolError>>;
46}