pub struct ExecTool { /* private fields */ }Expand description
Unified execution tool for agents.
Wraps both shell-string and structured binary+args execution behind a
single AgentTool implementation that uses a mode parameter to
dispatch to the appropriate method.
Access control is enforced based on agent_name:
- shell_exec: audit logging (cannot sandbox arbitrary shell).
- structured_exec: pre-flight permission check via
AccessManager.
Implementations§
Source§impl ExecTool
impl ExecTool
Sourcepub fn new(
config: SharedExecConfig,
access: Arc<Mutex<AccessManager>>,
context: AgentContext,
) -> Self
pub fn new( config: SharedExecConfig, access: Arc<Mutex<AccessManager>>, context: AgentContext, ) -> Self
Create a new ExecTool with an AgentContext (production path).
All executions are attributed to the agent and pass through access checks.
Sourcepub fn new_gated(
config: SharedExecConfig,
context: AgentContext,
gate: Arc<AccessGate>,
) -> Self
pub fn new_gated( config: SharedExecConfig, context: AgentContext, gate: Arc<AccessGate>, ) -> Self
Create a gated ExecTool with both context and access gate.
Sourcepub fn from_kernel_with_context(
kernel: &KernelHandle,
context: AgentContext,
) -> Self
pub fn from_kernel_with_context( kernel: &KernelHandle, context: AgentContext, ) -> Self
Create an ExecTool from a [KernelHandle] with an agent context.
This is the primary production constructor.
Sourcepub fn from_kernel(kernel: &KernelHandle) -> Self
pub fn from_kernel(kernel: &KernelHandle) -> Self
Create an ExecTool from a [KernelHandle] (legacy, no context).
Binds the tool to the default agent name "oxios-agent".
Prefer from_kernel_with_context for full security.
Sourcepub fn for_agent(
config: SharedExecConfig,
access: Arc<Mutex<AccessManager>>,
_agent_name: String,
) -> Self
pub fn for_agent( config: SharedExecConfig, access: Arc<Mutex<AccessManager>>, _agent_name: String, ) -> Self
Create a new ExecTool bound to a specific agent name (legacy).
Prefer new() with AgentContext for full security.
Sourcepub fn new_unrestricted(
config: SharedExecConfig,
access: Arc<Mutex<AccessManager>>,
) -> Self
pub fn new_unrestricted( config: SharedExecConfig, access: Arc<Mutex<AccessManager>>, ) -> Self
Legacy constructor without agent context (for backward compatibility).
Warning: This bypasses the new AgentContext / AccessGate path.
Use only for migration or testing.
Sourcepub async fn shell_exec(
&self,
command: &str,
timeout_ms: u64,
shutdown: Option<Receiver<()>>,
) -> Result<ExecResult, String>
pub async fn shell_exec( &self, command: &str, timeout_ms: u64, shutdown: Option<Receiver<()>>, ) -> Result<ExecResult, String>
Execute a raw command string via bash -c <cmd>.
Primary shell execution path.
The entire command string is forwarded to bash -c, so pipelines,
redirects, and compound commands all work.
If a shutdown signal is provided and fires before the command
completes, the child process is killed and an error is returned.
Sourcepub async fn structured_exec(
&self,
binary: &str,
args: Vec<String>,
timeout_ms: u64,
shutdown: Option<Receiver<()>>,
) -> Result<ExecResult, String>
pub async fn structured_exec( &self, binary: &str, args: Vec<String>, timeout_ms: u64, shutdown: Option<Receiver<()>>, ) -> Result<ExecResult, String>
Execute a binary with explicit args, enforcing allowlist + metachar blocking.
Primary structured execution path. Security checks:
- Binary must be a bare name (no
/or..). - Binary must be in the allowlist (or allowlist is empty = dev mode).
- Arguments must not contain shell metacharacters or path traversal.
If a shutdown signal is provided and fires before the command
completes, the child process is killed and an error is returned.
Trait Implementations§
Source§impl AgentTool for ExecTool
impl AgentTool for ExecTool
Source§fn description(&self) -> &'static str
fn description(&self) -> &'static str
Source§fn parameters_schema(&self) -> Value
fn parameters_schema(&self) -> Value
Source§fn execute<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_tool_call_id: &'life1 str,
params: Value,
shutdown: Option<Receiver<()>>,
_ctx: &'life2 ToolContext,
) -> Pin<Box<dyn Future<Output = Result<AgentToolResult, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn execute<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_tool_call_id: &'life1 str,
params: Value,
shutdown: Option<Receiver<()>>,
_ctx: &'life2 ToolContext,
) -> Pin<Box<dyn Future<Output = Result<AgentToolResult, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn essential(&self) -> bool
fn essential(&self) -> bool
Source§fn on_progress(&self, _callback: Arc<dyn Fn(String) + Send + Sync>)
fn on_progress(&self, _callback: Arc<dyn Fn(String) + Send + Sync>)
Source§fn on_browse_progress(
&self,
_callback: Arc<dyn Fn(BrowseProgress) + Send + Sync>,
)
fn on_browse_progress( &self, _callback: Arc<dyn Fn(BrowseProgress) + Send + Sync>, )
ToolCallContext with structured
data from BrowseProgress events.Source§fn render_call(&self, _params: &Value) -> Option<RenderOutput>
fn render_call(&self, _params: &Value) -> Option<RenderOutput>
Source§fn render_result(&self, _result: &AgentToolResult) -> Option<RenderOutput>
fn render_result(&self, _result: &AgentToolResult) -> Option<RenderOutput>
Source§fn execution_mode(&self) -> ToolExecutionMode
fn execution_mode(&self) -> ToolExecutionMode
Source§fn current_tab_id(&self) -> Option<Uuid>
fn current_tab_id(&self) -> Option<Uuid>
None. Browser tools override this to return the tab ID
of the currently-open tab during execution, so the agent loop can
populate ToolExecutionUpdate.tab_id.Source§fn set_tab_id_slot(&self, _slot: Arc<Mutex<RawMutex, Option<Uuid>>>)
fn set_tab_id_slot(&self, _slot: Arc<Mutex<RawMutex, Option<Uuid>>>)
on_progress;
the tool writes Some(tab_id) when it opens a tab and None when
it closes it. Defaults to a no-op — only tab-aware tools override.Source§fn to_definition(&self) -> ToolDefinition
fn to_definition(&self) -> ToolDefinition
Auto Trait Implementations§
impl !RefUnwindSafe for ExecTool
impl !UnwindSafe for ExecTool
impl Freeze for ExecTool
impl Send for ExecTool
impl Sync for ExecTool
impl Unpin for ExecTool
impl UnsafeUnpin for ExecTool
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
impl<T> ErasedDestructor for Twhere
T: 'static,
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 moreimpl<T> MaybeSendSync for T
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.