From 039f35563e6222da0acac3a1dada2f27e6174bec Mon Sep 17 00:00:00 2001 From: xiaoen <2768753269@qq.com> Date: Wed, 15 Apr 2026 21:29:29 +0800 Subject: [PATCH] feat(agent): wire delegate tool registration for multi-agent setups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register the delegate tool in registerSharedTools when multiple agents are configured. Gated independently from the subagent tool — delegate uses SubTurn directly and does not depend on SubagentManager. Self-delegation is prevented by injecting the current agent ID. Permission is enforced via CanSpawnSubagent (reuses allow_agents config). Single-agent setups are unaffected: the tool is not registered when only one agent exists in the registry. Ref: #2148 --- pkg/agent/loop.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index a856c0fca..d31d2af45 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -440,6 +440,20 @@ func registerSharedTools( } else if (spawnEnabled || spawnStatusEnabled) && !cfg.Tools.IsToolEnabled("subagent") { logger.WarnCF("agent", "spawn/spawn_status tools require subagent to be enabled", nil) } + + // Register delegate tool for multi-agent setups. + // Delegation uses the SubTurn mechanism directly (not SubagentManager), + // so it does not depend on the subagent tool being enabled. + if cfg.Tools.IsToolEnabled("delegate") && len(registry.ListAgentIDs()) > 1 { + delegateTool := tools.NewDelegateTool() + delegateTool.SetSpawner(NewSubTurnSpawner(al)) + currentAgentID := agentID + delegateTool.SetSelfAgentID(currentAgentID) + delegateTool.SetAllowlistChecker(func(targetAgentID string) bool { + return registry.CanSpawnSubagent(currentAgentID, targetAgentID) + }) + agent.Tools.Register(delegateTool) + } } }