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}