Skip to main content

neuron_runtime/
sandbox.rs

1//! Tool execution sandboxing.
2//!
3//! The [`Sandbox`] trait wraps tool execution with isolation, resource limits,
4//! or security boundaries. [`NoOpSandbox`] passes through directly.
5
6use std::future::Future;
7
8use neuron_types::{SandboxError, ToolContext, ToolDyn, ToolOutput, WasmCompatSend, WasmCompatSync};
9
10/// Sandbox for isolating tool execution.
11///
12/// Implementations can wrap tool calls with filesystem isolation,
13/// network restrictions, resource limits, or container boundaries.
14///
15/// # Example
16///
17/// ```ignore
18/// use neuron_runtime::*;
19/// use neuron_types::*;
20///
21/// struct NoOpSandbox;
22/// impl Sandbox for NoOpSandbox {
23///     fn execute_tool(
24///         &self,
25///         tool: &dyn ToolDyn,
26///         input: serde_json::Value,
27///         ctx: &ToolContext,
28///     ) -> impl Future<Output = Result<ToolOutput, SandboxError>> + Send {
29///         async move {
30///             tool.call_dyn(input, ctx)
31///                 .await
32///                 .map_err(|e| SandboxError::ExecutionFailed(e.to_string()))
33///         }
34///     }
35/// }
36/// ```
37pub trait Sandbox: WasmCompatSend + WasmCompatSync {
38    /// Execute a tool within the sandbox.
39    fn execute_tool(
40        &self,
41        tool: &dyn ToolDyn,
42        input: serde_json::Value,
43        ctx: &ToolContext,
44    ) -> impl Future<Output = Result<ToolOutput, SandboxError>> + WasmCompatSend;
45}
46
47/// A no-op sandbox that passes tool execution through directly.
48///
49/// Use this when no sandboxing is needed.
50pub struct NoOpSandbox;
51
52impl Sandbox for NoOpSandbox {
53    async fn execute_tool(
54        &self,
55        tool: &dyn ToolDyn,
56        input: serde_json::Value,
57        ctx: &ToolContext,
58    ) -> Result<ToolOutput, SandboxError> {
59        tool.call_dyn(input, ctx)
60            .await
61            .map_err(|e| SandboxError::ExecutionFailed(e.to_string()))
62    }
63}