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}