@@ -128,12 +128,20 @@ pub struct SessionOptions {
128128 /// aborting in non-streaming mode (overrides default of 3).
129129 /// `None` uses the `AgentConfig` default.
130130 pub circuit_breaker_threshold : Option < u32 > ,
131- /// Optional sandbox configuration.
131+ /// Optional sandbox configuration (kept for backward compatibility) .
132132 ///
133- /// When set, `bash` tool commands are routed through an A3S Box MicroVM
134- /// sandbox instead of `std::process::Command`. Requires the `sandbox`
135- /// Cargo feature to be enabled.
133+ /// Setting this alone has no effect; the host application must also supply
134+ /// a concrete [`BashSandbox`] implementation via [`with_sandbox_handle`].
135+ ///
136+ /// [`BashSandbox`]: crate::sandbox::BashSandbox
137+ /// [`with_sandbox_handle`]: Self::with_sandbox_handle
136138 pub sandbox_config : Option < crate :: sandbox:: SandboxConfig > ,
139+ /// Optional concrete sandbox implementation.
140+ ///
141+ /// When set, `bash` tool commands are routed through this sandbox instead
142+ /// of `std::process::Command`. The host application constructs and owns
143+ /// the implementation (e.g., an A3S Box–backed handle).
144+ pub sandbox_handle : Option < Arc < dyn crate :: sandbox:: BashSandbox > > ,
137145 /// Enable auto-compaction when context usage exceeds threshold.
138146 pub auto_compact : bool ,
139147 /// Context usage percentage threshold for auto-compaction (0.0 - 1.0).
@@ -469,6 +477,21 @@ impl SessionOptions {
469477 self
470478 }
471479
480+ /// Provide a concrete [`BashSandbox`] implementation for this session.
481+ ///
482+ /// When set, `bash` tool commands are routed through the given sandbox
483+ /// instead of `std::process::Command`. The host application is responsible
484+ /// for constructing and lifecycle-managing the sandbox.
485+ ///
486+ /// [`BashSandbox`]: crate::sandbox::BashSandbox
487+ pub fn with_sandbox_handle (
488+ mut self ,
489+ handle : Arc < dyn crate :: sandbox:: BashSandbox > ,
490+ ) -> Self {
491+ self . sandbox_handle = Some ( handle) ;
492+ self
493+ }
494+
472495 /// Enable auto-compaction when context usage exceeds threshold.
473496 ///
474497 /// When enabled, the agent loop automatically prunes large tool outputs
@@ -1186,23 +1209,13 @@ impl Agent {
11861209 }
11871210 tool_context = tool_context. with_agent_event_tx ( agent_event_tx) ;
11881211
1189- // Wire sandbox when configured.
1190- #[ cfg( feature = "sandbox" ) ]
1191- if let Some ( ref sandbox_cfg) = opts. sandbox_config {
1192- let handle: Arc < dyn crate :: sandbox:: BashSandbox > =
1193- Arc :: new ( crate :: sandbox:: BoxSandboxHandle :: new (
1194- sandbox_cfg. clone ( ) ,
1195- canonical. display ( ) . to_string ( ) ,
1196- ) ) ;
1197- // Update the registry's default context so that direct
1198- // `AgentSession::bash()` calls also use the sandbox.
1212+ // Wire sandbox when a concrete handle is provided by the host application.
1213+ if let Some ( handle) = opts. sandbox_handle . clone ( ) {
11991214 tool_executor. registry ( ) . set_sandbox ( Arc :: clone ( & handle) ) ;
12001215 tool_context = tool_context. with_sandbox ( handle) ;
1201- }
1202- #[ cfg( not( feature = "sandbox" ) ) ]
1203- if opts. sandbox_config . is_some ( ) {
1216+ } else if opts. sandbox_config . is_some ( ) {
12041217 tracing:: warn!(
1205- "sandbox_config is set but the `sandbox` Cargo feature is not enabled \
1218+ "sandbox_config is set but no sandbox_handle was provided \
12061219 — bash commands will run locally"
12071220 ) ;
12081221 }
0 commit comments