pub struct CompositeExecutor<A: ToolExecutor, B: ToolExecutor> { /* private fields */ }Expand description
Chains two ToolExecutor implementations with first-match-wins dispatch.
For each method, first is tried first. If it returns Ok(None) (i.e. it does not
handle the input), second is tried. If first returns an Err, the error propagates
immediately without consulting second.
Use this to compose a chain of specialized executors at startup instead of a dynamic
Vec<Box<dyn ...>>. Nest multiple CompositeExecutors to handle more than two backends.
Tool definitions from both executors are merged, with first taking precedence when
both define a tool with the same ID.
§Example
use zeph_tools::{
CompositeExecutor, ShellExecutor, WebScrapeExecutor, ShellConfig, ScrapeConfig,
};
let shell = ShellExecutor::new(&ShellConfig::default());
let scrape = WebScrapeExecutor::new(&ScrapeConfig::default());
let executor = CompositeExecutor::new(shell, scrape);
// executor handles both bash blocks and scrape/fetch tool calls.Implementations§
Source§impl<A: ToolExecutor, B: ToolExecutor> CompositeExecutor<A, B>
impl<A: ToolExecutor, B: ToolExecutor> CompositeExecutor<A, B>
Trait Implementations§
Source§impl<A: Debug + ToolExecutor, B: Debug + ToolExecutor> Debug for CompositeExecutor<A, B>
impl<A: Debug + ToolExecutor, B: Debug + ToolExecutor> Debug for CompositeExecutor<A, B>
Source§impl<A: ToolExecutor, B: ToolExecutor> ToolExecutor for CompositeExecutor<A, B>
impl<A: ToolExecutor, B: ToolExecutor> ToolExecutor for CompositeExecutor<A, B>
Source§fn requires_confirmation(&self, call: &ToolCall) -> bool
fn requires_confirmation(&self, call: &ToolCall) -> bool
Return true when either inner executor requires confirmation for call.
Mirrors the OR-forwarding used by Self::is_tool_retryable and
Self::is_tool_speculatable — without this override the base
ToolExecutor::requires_confirmation default (false) silently bypasses
confirmation gating for any executor composed under CompositeExecutor. See #5900.
Source§fn set_skill_env(&self, env: Option<HashMap<String, String>>)
fn set_skill_env(&self, env: Option<HashMap<String, String>>)
Forward the active skill’s env injection to BOTH inner executors.
The base ToolExecutor::set_skill_env is a no-op, so without this override the
composition tree built in agent_setup silently swallows env injection — the
underlying ShellExecutor never sees GITHUB_TOKEN etc. Each layer ignores the call
if it does not own a skill_env slot; layers that do (e.g. ShellExecutor) update
their state. See #3869.
Source§fn set_effective_trust(&self, level: SkillTrustLevel)
fn set_effective_trust(&self, level: SkillTrustLevel)
Forward the active skill’s trust level to BOTH inner executors.
Mirrors Self::set_skill_env: without this override, TrustGateExecutor never
observes a non-Trusted level when composed under CompositeExecutor, leaving
quarantine enforcement effectively bypassed. See #3869.
Source§fn checkpoint_undo(&self, n: usize) -> CheckpointActionResult
fn checkpoint_undo(&self, n: usize) -> CheckpointActionResult
Delegate undo to the first inner executor that supports checkpoints.
Source§fn checkpoint_redo(&self) -> CheckpointActionResult
fn checkpoint_redo(&self) -> CheckpointActionResult
Delegate redo to the first inner executor that supports checkpoints.
Source§fn checkpoint_list(&self) -> CheckpointListResult
fn checkpoint_list(&self) -> CheckpointListResult
Delegate list to the first inner executor that supports checkpoints.
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§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>
Auto Trait Implementations§
impl<A, B> Freeze for CompositeExecutor<A, B>
impl<A, B> RefUnwindSafe for CompositeExecutor<A, B>where
A: RefUnwindSafe,
B: RefUnwindSafe,
impl<A, B> Send for CompositeExecutor<A, B>
impl<A, B> Sync for CompositeExecutor<A, B>
impl<A, B> Unpin for CompositeExecutor<A, B>
impl<A, B> UnsafeUnpin for CompositeExecutor<A, B>where
A: UnsafeUnpin,
B: UnsafeUnpin,
impl<A, B> UnwindSafe for CompositeExecutor<A, B>where
A: UnwindSafe,
B: UnwindSafe,
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