descry-tool-core 0.3.1

Core traits and types for descry-tool framework
Documentation
//! Tower middleware example
//!
//! Demonstrates how to use Tower Service with tools.

use descry_tool_core::{
    tower::{tool_service, ToolRequest},
    ToolContext, ToolError,
};
use descry_tool_macros::tool;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::time::Duration;
use tower::Service;

// Define a tool
#[derive(Deserialize, JsonSchema)]
struct ProcessParams {
    input: String,
}

#[derive(Serialize, JsonSchema)]
struct ProcessOutput {
    output: String,
    length: usize,
}

#[tool(
    name = "process",
    description = "Process a string and return its length"
)]
async fn process(_ctx: Arc<ToolContext>, params: ProcessParams) -> Result<ProcessOutput, ToolError> {
    // Simulate some processing
    tokio::time::sleep(Duration::from_millis(10)).await;
    
    Ok(ProcessOutput {
        output: params.input.to_uppercase(),
        length: params.input.len(),
    })
}

#[tokio::main]
async fn main() {
    println!("=== Tower Service Example ===\n");

    // Create a tool service
    let mut service = tool_service();

    // Test 1: Normal request
    println!("Test 1: Normal request");
    let req = ToolRequest {
        name: "process".to_string(),
        params: serde_json::json!({"input": "hello world"}),
        ctx: Arc::new(ToolContext::new()),
    };

    match service.call(req).await {
        Ok(response) => {
            println!("Success!");
            println!("Output: {}", serde_json::to_string_pretty(&response.output).unwrap());
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }
    println!();

    // Test 2: Request with non-existent tool
    println!("Test 2: Non-existent tool");
    let req = ToolRequest {
        name: "nonexistent".to_string(),
        params: serde_json::json!({}),
        ctx: Arc::new(ToolContext::new()),
    };

    match service.call(req).await {
        Ok(response) => {
            println!("Unexpected success: {:?}", response);
        }
        Err(e) => {
            println!("Expected error: {}", e);
        }
    }
    println!();

    // Test 3: Multiple requests
    println!("Test 3: Multiple requests");
    
    for i in 0..3 {
        let req = ToolRequest {
            name: "process".to_string(),
            params: serde_json::json!({"input": &format!("request {}", i)}),
            ctx: Arc::new(ToolContext::new()),
        };

        match service.call(req).await {
            Ok(response) => {
                println!("Request {}: {:?}", i + 1, response.output);
            }
            Err(e) => {
                println!("Request {} failed: {}", i + 1, e);
            }
        }
    }
}