Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
before. `--migrate-config` drops any leftover `require_tls`/`ssrf_protection` keys from an
existing `[a2a]` table, warning the user, without erroring (#5885).

- **ACP**: removed `DynSchedulerExecutor`, a hand-maintained `ToolExecutor` wrapper around
`Arc<SchedulerExecutor>` that forwarded 9 of the trait's 13 methods (omitting
`execute_confirmed`, `set_skill_env`, `set_effective_trust`, `is_tool_retryable`) — the 8th+
recurrence of the "leaf type gains a trait method, some Arc wrapper silently drifts" defect
class (#5899/#5905/#5906/#5985). The scheduler's ACP tool executor is now wired through the
existing `zeph_tools::DynExecutor`/`ErasedToolExecutor` erasure path (already used by every
other dynamically-composed executor), which forwards all 13 methods by construction — no
bespoke wrapper to drift. `DynSchedulerExecutor` was `pub(crate)`, not a public API, so this
is an internal refactor with no behavior change (#6000).

### Docs

- **LLM**: `AnyProvider`/`Router`/`Triage`'s `capability_delegation_advisory()` rustdoc comments
Expand Down
3 changes: 1 addition & 2 deletions src/acp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1869,8 +1869,7 @@ async fn spawn_acp_agent(
agent = agent.with_custom_task_rx(rx);
}
if let Some(sched_exec) = scheduler_executor {
agent = agent
.add_tool_executor(crate::scheduler_executor::DynSchedulerExecutor(sched_exec));
agent = agent.add_tool_executor(zeph_tools::DynExecutor(sched_exec));
}
}

Expand Down
57 changes: 11 additions & 46 deletions src/scheduler_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,52 +516,6 @@ impl ToolExecutor for SchedulerExecutor {
zeph_tools::tool_executor_no_inner_defaults!();
}

/// `Arc`-wrapper so `SchedulerExecutor` can be shared across ACP sessions without `Clone`.
#[cfg(feature = "acp")]
pub(crate) struct DynSchedulerExecutor(pub(crate) std::sync::Arc<SchedulerExecutor>);

#[cfg(feature = "acp")]
impl ToolExecutor for DynSchedulerExecutor {
async fn execute(&self, response: &str) -> Result<Option<ToolOutput>, ToolError> {
self.0.execute(response).await
}

fn tool_definitions(&self) -> Vec<ToolDef> {
self.0.tool_definitions()
}

async fn execute_tool_call(&self, call: &ToolCall) -> Result<Option<ToolOutput>, ToolError> {
self.0.execute_tool_call(call).await
}

fn requires_confirmation(&self, call: &ToolCall) -> bool {
self.0.requires_confirmation(call)
}

async fn execute_tool_call_confirmed(
&self,
call: &ToolCall,
) -> Result<Option<ToolOutput>, ToolError> {
self.0.execute_tool_call_confirmed(call).await
}

fn checkpoint_undo(&self, n: usize) -> zeph_tools::CheckpointActionResult {
self.0.checkpoint_undo(n)
}

fn checkpoint_redo(&self) -> zeph_tools::CheckpointActionResult {
self.0.checkpoint_redo()
}

fn checkpoint_list(&self) -> zeph_tools::CheckpointListResult {
self.0.checkpoint_list()
}

fn is_tool_speculatable(&self, tool_id: &str) -> bool {
self.0.is_tool_speculatable(tool_id)
}
}

#[cfg(test)]
mod tests {
use std::sync::Arc;
Expand Down Expand Up @@ -756,6 +710,17 @@ mod tests {
assert_eq!(exec.tool_definitions().len(), 4);
}

#[cfg(feature = "acp")]
#[tokio::test]
async fn dyn_executor_erasure_path_dispatches() {
let (exec, _rx) = make_executor().await;
let dyn_exec = zeph_tools::DynExecutor(Arc::new(exec));
assert_eq!(dyn_exec.tool_definitions().len(), 4);
let call = make_call("list_tasks", serde_json::json!({}));
let result = dyn_exec.execute_tool_call(&call).await.unwrap().unwrap();
assert!(result.summary.contains("No active scheduled tasks"));
}

#[tokio::test]
async fn list_tasks_empty() {
let (exec, _rx) = make_executor().await;
Expand Down
Loading