From ef072f6e594a927862e27eb7265020344cbd1ba9 Mon Sep 17 00:00:00 2001 From: Egbert Eich Date: Tue, 9 Jun 2026 15:28:01 +0200 Subject: [PATCH] Make subagent inherit tools from parent (#51) While the tool list of the main agent could be controlled by several options, subagent used to be equipped with all available tools (except for the subagent tool itself). With this change the list of tools is taken from the parent, the subagent tool itself is removed and the remaining tool list is added to the subagent. Signed-off-by: Egbert Eich --- internal/extbridge/extbridge.go | 1 + pkg/kit/kit.go | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/internal/extbridge/extbridge.go b/internal/extbridge/extbridge.go index 4d8d7aa5..85580413 100644 --- a/internal/extbridge/extbridge.go +++ b/internal/extbridge/extbridge.go @@ -66,6 +66,7 @@ func SpawnSubagent(ctx context.Context, k *kit.Kit, cfg extensions.SubagentConfi SystemPrompt: cfg.SystemPrompt, Timeout: cfg.Timeout, NoSession: cfg.NoSession, + Tools: k.GetToolsForSubagent(), } if cfg.OnEvent != nil { sdkCfg.OnEvent = func(e kit.Event) { diff --git a/pkg/kit/kit.go b/pkg/kit/kit.go index 51c8524f..f46b8c2a 100644 --- a/pkg/kit/kit.go +++ b/pkg/kit/kit.go @@ -138,6 +138,19 @@ func (m *Kit) GetToolNames() []string { return names } +// GetToolsForSubagent like GetTools but eliminates subagent tool +// to avoid infinite recursion. +func (m *Kit) GetToolsForSubagent() []Tool { + var tools []Tool + for _, t := range m.agent.GetTools() { + if t.Info().Name == "subagent" { + continue + } + tools = append(tools, t) + } + return tools +} + // GetLoadingMessage returns the agent's startup info message (e.g. GPU // fallback info), or empty string if none. func (m *Kit) GetLoadingMessage() string { @@ -1814,8 +1827,14 @@ type SubagentConfig struct { // Empty string uses a minimal default prompt. SystemPrompt string - // Tools overrides the tool set. If nil, SubagentTools() is used (all - // core tools except subagent, preventing infinite recursion). + // Tools overrides the tool set available to the subagent. + // If nil and the subagent is created via the SDK (Kit.Subagent()), the + // static SubagentTools() set (all core tools except "subagent") is used. + // When spawned internally by the agent loop, the parent's active tools + // minus "subagent" are used instead (see GetToolsForSubagent()). + // Pass m.GetToolsForSubagent() explicitly to opt into inheritance from + // SDK call sites. + // (The subagent tool is dropped to prevent infinite recursion.) Tools []Tool // NoSession, when true, uses an in-memory ephemeral session. When false @@ -2076,6 +2095,7 @@ func (m *Kit) generate(ctx context.Context, messages []fantasy.Message) (*agent. SystemPrompt: systemPrompt, Timeout: timeout, OnEvent: onEvent, + Tools: m.GetToolsForSubagent(), }) m.cleanupSubagentListeners(toolCallID) if result == nil {