pub struct ShellExecutor { /* private fields */ }Expand description
Bash block extraction and execution via tokio::process::Command.
Parses ```bash fenced blocks from LLM responses (legacy path) and handles
structured bash tool calls (modern path). Use ShellExecutor::new with a
ShellConfig and chain optional builder methods to attach audit logging,
event streaming, permission policies, and cancellation.
§Example
use zeph_tools::{ShellExecutor, ToolExecutor, ShellConfig};
let executor = ShellExecutor::new(&ShellConfig::default());
// Execute a fenced bash block.
let response = "```bash\npwd\n```";
if let Ok(Some(output)) = executor.execute(response).await {
println!("{}", output.summary);
}Implementations§
Source§impl ShellExecutor
impl ShellExecutor
Sourcepub fn new(config: &ShellConfig) -> Self
pub fn new(config: &ShellConfig) -> Self
Create a new ShellExecutor from configuration.
Merges the built-in DEFAULT_BLOCKED_COMMANDS with any additional blocked
commands from config, then subtracts any explicitly allowed commands.
No subprocess is spawned at construction time.
Sourcepub fn with_sandbox(
self,
sandbox: Arc<dyn Sandbox>,
policy: SandboxPolicy,
) -> Self
pub fn with_sandbox( self, sandbox: Arc<dyn Sandbox>, policy: SandboxPolicy, ) -> Self
Attach an OS-level sandbox backend and a pre-snapshotted policy.
The policy is snapshotted at construction and never re-resolved per call (no TOCTOU).
If a different policy is needed, create a new ShellExecutor via the builder chain.
Sourcepub fn with_risk_chain(self, accumulator: Arc<RiskChainAccumulator>) -> Self
pub fn with_risk_chain(self, accumulator: Arc<RiskChainAccumulator>) -> Self
Attach a per-turn risk chain accumulator for multi-step attack detection.
When set, each command is recorded into the accumulator. If the cumulative
risk score exceeds threshold, the command is blocked before execution.
Sourcepub fn with_execution_config(
self,
config: &ExecutionConfig,
) -> Result<Self, String>
pub fn with_execution_config( self, config: &ExecutionConfig, ) -> Result<Self, String>
Build the environment registry from [execution] config and wire it in one step.
Convenience wrapper for agent startup. Converts zeph_config::ExecutionConfig
entries into trusted ExecutionContext instances and passes them to
Self::with_environments.
§Errors
Returns an error string when any registry entry’s cwd cannot be canonicalized
or escapes allowed_paths.
Sourcepub fn with_environments(
self,
environments: HashMap<String, ExecutionContext>,
default_env: Option<String>,
) -> Result<Self, String>
pub fn with_environments( self, environments: HashMap<String, ExecutionContext>, default_env: Option<String>, ) -> Result<Self, String>
Wire the named execution environment registry from [execution] config.
Builds trusted ExecutionContext instances from the operator-authored TOML
entries and canonicalizes their cwd paths at construction time.
§Errors
Returns an error string (surfaced at agent startup) when a registry entry’s
cwd path does not exist, cannot be canonicalized, or escapes allowed_paths.
Sourcepub fn set_skill_env(&self, env: Option<HashMap<String, String>>)
pub fn set_skill_env(&self, env: Option<HashMap<String, String>>)
Set environment variables to inject when executing the active skill’s bash blocks.
Sourcepub fn with_audit(self, logger: Arc<AuditLogger>) -> Self
pub fn with_audit(self, logger: Arc<AuditLogger>) -> Self
Attach an audit logger. Each shell invocation will emit an AuditEntry.
Sourcepub fn with_tool_event_tx(self, tx: ToolEventTx) -> Self
pub fn with_tool_event_tx(self, tx: ToolEventTx) -> Self
Attach a tool-event sender for streaming output to the TUI or channel adapter.
When set, ToolEvent::Started, ToolEvent::OutputChunk, and
ToolEvent::Completed events are sent on tx during execution.
Sourcepub fn with_background_completion_tx(
self,
tx: Sender<BackgroundCompletion>,
) -> Self
pub fn with_background_completion_tx( self, tx: Sender<BackgroundCompletion>, ) -> Self
Attach a dedicated sender for routing BackgroundCompletion payloads to the agent.
This channel is separate from ToolEventTx (which goes to the TUI). The agent holds
the receiver end and drains it at the start of each turn to inject deferred completions
into the message history as a single merged user-role block.
Sourcepub fn with_task_supervisor(self, supervisor: TaskSupervisor) -> Self
pub fn with_task_supervisor(self, supervisor: TaskSupervisor) -> Self
Attach a TaskSupervisor so background shell run tasks are registered and observable.
When set, each spawn_background_with_context call registers the run task under its
RunId in the supervisor, making it visible to TUI status panels and gracefully
aborted on supervisor shutdown.
Sourcepub fn with_permissions(self, policy: PermissionPolicy) -> Self
pub fn with_permissions(self, policy: PermissionPolicy) -> Self
Attach a permission policy for confirmation-gate enforcement.
Commands matching the policy’s rules may require user approval before execution proceeds.
Sourcepub fn with_cancel_token(self, token: CancellationToken) -> Self
pub fn with_cancel_token(self, token: CancellationToken) -> Self
Attach a cancellation token. When the token is cancelled, the running subprocess
is killed and the executor returns ToolError::Cancelled.
Sourcepub fn with_output_filters(self, registry: OutputFilterRegistry) -> Self
pub fn with_output_filters(self, registry: OutputFilterRegistry) -> Self
Attach an output filter registry. Filters are applied to stdout+stderr before
the summary is stored in ToolOutput and sent to the LLM.
Sourcepub fn background_runs_snapshot(&self) -> Vec<BackgroundRunSnapshot>
pub fn background_runs_snapshot(&self) -> Vec<BackgroundRunSnapshot>
Snapshot all in-flight background runs.
Acquires the lock once, maps each BackgroundHandle to a
BackgroundRunSnapshot, then drops the guard before returning.
Safe to call from any thread.
Sourcepub fn policy_handle(&self) -> ShellPolicyHandle
pub fn policy_handle(&self) -> ShellPolicyHandle
Return a clonable handle for live policy rebuilds on hot-reload.
Clone the handle out at construction time and store it on the agent.
Calling ShellPolicyHandle::rebuild atomically swaps the effective
blocked_commands without recreating the executor.
Sourcepub async fn execute_confirmed(
&self,
response: &str,
) -> Result<Option<ToolOutput>, ToolError>
pub async fn execute_confirmed( &self, response: &str, ) -> Result<Option<ToolOutput>, ToolError>
Execute a bash block bypassing the confirmation check (called after user confirms).
§Errors
Returns ToolError on blocked commands, sandbox violations, or execution failures.
Source§impl ShellExecutor
impl ShellExecutor
Trait Implementations§
Source§impl Debug for ShellExecutor
impl Debug for ShellExecutor
Source§impl ToolExecutor for ShellExecutor
impl ToolExecutor for ShellExecutor
Source§async fn execute(&self, response: &str) -> Result<Option<ToolOutput>, ToolError>
async fn execute(&self, response: &str) -> Result<Option<ToolOutput>, ToolError>
response for fenced tool blocks and execute them. Read moreSource§async fn execute_confirmed(
&self,
response: &str,
) -> Result<Option<ToolOutput>, ToolError>
async fn execute_confirmed( &self, response: &str, ) -> Result<Option<ToolOutput>, ToolError>
Source§fn tool_definitions(&self) -> Vec<ToolDef>
fn tool_definitions(&self) -> Vec<ToolDef>
Source§async fn execute_tool_call(
&self,
call: &ToolCall,
) -> Result<Option<ToolOutput>, ToolError>
async fn execute_tool_call( &self, call: &ToolCall, ) -> Result<Option<ToolOutput>, ToolError>
Source§fn set_skill_env(&self, env: Option<HashMap<String, String>>)
fn set_skill_env(&self, env: Option<HashMap<String, String>>)
Source§fn checkpoint_undo(&self, n: usize) -> CheckpointActionResult
fn checkpoint_undo(&self, n: usize) -> CheckpointActionResult
n checkpointed write commands. Read moreSource§fn checkpoint_redo(&self) -> CheckpointActionResult
fn checkpoint_redo(&self) -> CheckpointActionResult
Source§fn checkpoint_list(&self) -> CheckpointListResult
fn checkpoint_list(&self) -> CheckpointListResult
Source§fn requires_confirmation(&self, _call: &ToolCall) -> bool
fn requires_confirmation(&self, _call: &ToolCall) -> bool
Source§async fn execute_tool_call_confirmed(
&self,
call: &ToolCall,
) -> Result<Option<ToolOutput>, ToolError>
async fn execute_tool_call_confirmed( &self, call: &ToolCall, ) -> Result<Option<ToolOutput>, ToolError>
Source§fn is_tool_speculatable(&self, _tool_id: &str) -> bool
fn is_tool_speculatable(&self, _tool_id: &str) -> bool
Source§fn set_effective_trust(&self, _level: SkillTrustLevel)
fn set_effective_trust(&self, _level: SkillTrustLevel)
Auto Trait Implementations§
impl !Freeze for ShellExecutor
impl !RefUnwindSafe for ShellExecutor
impl !UnwindSafe for ShellExecutor
impl Send for ShellExecutor
impl Sync for ShellExecutor
impl Unpin for ShellExecutor
impl UnsafeUnpin for ShellExecutor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> ErasedToolExecutor for Twhere
T: ToolExecutor,
impl<T> ErasedToolExecutor for Twhere
T: ToolExecutor,
fn execute_erased<'a>( &'a self, response: &'a str, ) -> Pin<Box<dyn Future<Output = Result<Option<ToolOutput>, ToolError>> + Send + 'a>>
fn execute_confirmed_erased<'a>( &'a self, response: &'a str, ) -> Pin<Box<dyn Future<Output = Result<Option<ToolOutput>, ToolError>> + Send + 'a>>
fn tool_definitions_erased(&self) -> Vec<ToolDef>
fn execute_tool_call_erased<'a>( &'a self, call: &'a ToolCall, ) -> Pin<Box<dyn Future<Output = Result<Option<ToolOutput>, ToolError>> + Send + 'a>>
Source§fn execute_tool_call_confirmed_erased<'a>(
&'a self,
call: &'a ToolCall,
) -> Pin<Box<dyn Future<Output = Result<Option<ToolOutput>, ToolError>> + Send + 'a>>
fn execute_tool_call_confirmed_erased<'a>( &'a self, call: &'a ToolCall, ) -> Pin<Box<dyn Future<Output = Result<Option<ToolOutput>, ToolError>> + Send + 'a>>
ToolExecutor::execute_tool_call_confirmed reach it through the blanket impl below.
Other implementors should fall back to
execute_tool_call_erased (normal
enforcement path) unless they need to replicate confirmed-path-specific behavior
(e.g. a fallback that only applies on the unconfirmed path must be mirrored
explicitly, not assumed). See
erased_tool_executor_no_inner_defaults!
for leaf executors with no wrapped inner.Source§fn set_skill_env(&self, env: Option<HashMap<String, String>>)
fn set_skill_env(&self, env: Option<HashMap<String, String>>)
Source§fn set_effective_trust(&self, level: SkillTrustLevel)
fn set_effective_trust(&self, level: SkillTrustLevel)
Source§fn checkpoint_undo_erased(&self, n: usize) -> CheckpointActionResult
fn checkpoint_undo_erased(&self, n: usize) -> CheckpointActionResult
n checkpointed write commands. Read moreSource§fn checkpoint_redo_erased(&self) -> CheckpointActionResult
fn checkpoint_redo_erased(&self) -> CheckpointActionResult
Source§fn checkpoint_list_erased(&self) -> CheckpointListResult
fn checkpoint_list_erased(&self) -> CheckpointListResult
Source§fn is_tool_retryable_erased(&self, tool_id: &str) -> bool
fn is_tool_retryable_erased(&self, tool_id: &str) -> bool
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request