Skip to main content

Tool

Trait Tool 

Source
pub trait Tool: Send + Sync {
    // Required methods
    fn spec(&self) -> ToolSpec;
    fn risk(&self, arguments: &Value) -> Result<ToolRisk, ToolError>;
    fn approval_summary(&self, arguments: &Value) -> Result<String, ToolError>;
    fn execute<'life0, 'async_trait>(
        &'life0 self,
        arguments: Value,
        context: ToolContext,
    ) -> Pin<Box<dyn Future<Output = Result<ToolOutput, ToolError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
}
Expand description

Something the model can call. The runtime asks for the call’s risk and approval_summary first, so both must validate the arguments without side effects; only an approved call reaches execute.

§Example

use async_trait::async_trait;
use serde_json::{Value, json};
use scv_core::{Tool, ToolContext, ToolError, ToolOutput, ToolRisk, ToolSpec};

struct Echo;

#[async_trait]
impl Tool for Echo {
    fn spec(&self) -> ToolSpec {
        ToolSpec {
            name: "echo".into(),
            description: "Repeat a value".into(),
            parameters: json!({
                "type": "object",
                "properties": {"value": {"type": "string"}},
                "required": ["value"]
            }),
        }
    }

    fn risk(&self, arguments: &Value) -> Result<ToolRisk, ToolError> {
        arguments["value"]
            .as_str()
            .ok_or_else(|| ToolError::invalid_arguments("value must be a string"))?;
        Ok(ToolRisk::ReadOnly)
    }

    fn approval_summary(&self, arguments: &Value) -> Result<String, ToolError> {
        self.risk(arguments)?;
        Ok("Repeat a value".into())
    }

    async fn execute(
        &self,
        arguments: Value,
        _context: ToolContext,
    ) -> Result<ToolOutput, ToolError> {
        Ok(ToolOutput::success(arguments["value"].as_str().unwrap_or_default()))
    }
}

let mut registry = scv_core::ToolRegistry::default();
registry.register(std::sync::Arc::new(Echo)).unwrap();
assert_eq!(registry.specs()[0].name, "echo");

Required Methods§

Source

fn spec(&self) -> ToolSpec

The name, description, and argument schema shown to the model.

Source

fn risk(&self, arguments: &Value) -> Result<ToolRisk, ToolError>

The risk of this call, which selects the approval rule.

Source

fn approval_summary(&self, arguments: &Value) -> Result<String, ToolError>

One line describing this call for a person approving it.

Source

fn execute<'life0, 'async_trait>( &'life0 self, arguments: Value, context: ToolContext, ) -> Pin<Box<dyn Future<Output = Result<ToolOutput, ToolError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Run an approved call. Honour context.cancellation.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§