openfunctions_rs/runtime/
mod.rs

1//! Runtime for executing tools and agent functions.
2//!
3//! This module provides the `Runtime`, which is responsible for safely
4//! executing tools in a sandboxed environment. It manages the execution
5//! lifecycle, including setting up the environment, invoking the tool,
6//! and capturing the results.
7
8use crate::core::{Config, Registry, Tool};
9use crate::models::{ExecutionResult, FunctionCall};
10use anyhow::Result;
11use tracing::info;
12
13pub mod environment;
14pub mod executor;
15pub mod sandbox;
16
17pub use environment::Environment;
18pub use executor::Executor;
19pub use sandbox::Sandbox;
20
21/// The runtime for executing tools.
22///
23/// The `Runtime` orchestrates the execution of tools, using an `Executor`
24/// to run the tool's code in a controlled `Sandbox` with a prepared
25/// `Environment`.
26pub struct Runtime {
27    #[allow(dead_code)]
28    config: Config,
29    // TODO: executor: executor::Executor,
30}
31
32impl Runtime {
33    /// Creates a new `Runtime` with the given configuration.
34    pub fn new(config: Config) -> Self {
35        Self {
36            config,
37            // TODO: executor: executor::Executor::new(&config.runtime),
38        }
39    }
40
41    /// Executes a tool with the given arguments.
42    ///
43    /// # Arguments
44    /// * `tool` - The tool to execute.
45    /// * `args` - The arguments for the tool, as a JSON value.
46    pub async fn execute_tool(
47        &self,
48        tool: &Tool,
49        args: serde_json::Value,
50    ) -> Result<ExecutionResult> {
51        info!(tool = %tool.name, args = ?args, "Executing tool");
52        // TODO: Implement the full execution logic.
53        // This will involve:
54        // 1. Creating an environment for the execution.
55        // 2. Preparing the arguments.
56        // 3. Using the executor to run the tool in a sandbox.
57        // 4. Capturing and returning the ExecutionResult.
58
59        let start_time = std::time::Instant::now();
60
61        Ok(ExecutionResult {
62            success: true,
63            output: "Executing tool... (not yet implemented)".to_string(),
64            error: None,
65            duration: start_time.elapsed(),
66            metadata: std::collections::HashMap::new(),
67        })
68    }
69
70    /// Executes a function call request.
71    ///
72    /// This is a convenience method that looks up the tool in the registry
73    /// and then calls `execute_tool`.
74    ///
75    /// # Arguments
76    /// * `call` - The `FunctionCall` request.
77    /// * `registry` - The `Registry` to look up the tool in.
78    pub async fn execute_function_call(
79        &self,
80        call: &FunctionCall,
81        registry: &Registry,
82    ) -> Result<ExecutionResult> {
83        info!(function_name = %call.name, "Executing function call");
84        let tool = registry
85            .get_tool(&call.name)
86            .ok_or_else(|| anyhow::anyhow!("Tool not found: {}", call.name))?;
87
88        self.execute_tool(tool, call.arguments.clone()).await
89    }
90}