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