Skip to main content

opi_agent/
tool.rs

1//! Tool calling abstraction (S8.2).
2
3use std::future::Future;
4use std::pin::Pin;
5
6use opi_ai::message::{OutputContent, ToolDef};
7use tokio_util::sync::CancellationToken;
8
9/// Callback for progress updates during tool execution.
10pub type UpdateCallback = Box<dyn Fn(serde_json::Value) + Send + Sync>;
11
12/// Tool trait — each concrete tool implements this.
13pub trait Tool: Send + Sync {
14    /// Return the tool's definition (name, description, JSON Schema for input).
15    fn definition(&self) -> ToolDef;
16
17    /// Execute the tool with validated arguments.
18    fn execute(
19        &self,
20        call_id: &str,
21        arguments: serde_json::Value,
22        signal: CancellationToken,
23        on_update: Option<UpdateCallback>,
24    ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send>>;
25
26    /// Whether this tool must run sequentially.
27    fn execution_mode(&self) -> ExecutionMode {
28        ExecutionMode::Parallel
29    }
30}
31
32/// Result of a tool execution.
33#[derive(Clone)]
34pub struct ToolResult {
35    pub content: Vec<OutputContent>,
36    pub details: Option<serde_json::Value>,
37    pub is_error: bool,
38    pub terminate: bool,
39}
40
41impl ToolResult {
42    /// Create an error tool result from a validation error.
43    pub fn from_validation_error(err: crate::validation::ValidationError) -> Self {
44        let message = err.to_string();
45        Self {
46            content: vec![OutputContent::Text { text: message }],
47            details: None,
48            is_error: true,
49            terminate: false,
50        }
51    }
52}
53
54/// Errors from tool execution.
55#[derive(Debug, thiserror::Error)]
56pub enum ToolError {
57    #[error("execution failed: {0}")]
58    ExecutionFailed(String),
59    #[error("cancelled")]
60    Cancelled,
61}
62
63/// Whether a tool runs sequentially or in parallel with others.
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum ExecutionMode {
66    Sequential,
67    Parallel,
68}