diff --git a/cmd/picoclaw/cmd_agent.go b/cmd/picoclaw/cmd_agent.go index 8658c9d32..5ce0c3b99 100644 --- a/cmd/picoclaw/cmd_agent.go +++ b/cmd/picoclaw/cmd_agent.go @@ -24,6 +24,7 @@ func agentCmd() { message := "" sessionKey := "cli:default" modelOverride := "" + orchestrationEnabled := false args := os.Args[2:] for i := 0; i < len(args); i++ { @@ -46,6 +47,8 @@ func agentCmd() { modelOverride = args[i+1] i++ } + case "--orchestration": + orchestrationEnabled = true } } @@ -59,6 +62,10 @@ func agentCmd() { cfg.Agents.Defaults.Model = modelOverride } + if orchestrationEnabled { + cfg.Agents.Defaults.Orchestration = true + } + provider, modelID, err := providers.CreateProvider(cfg) if err != nil { fmt.Printf("Error creating provider: %v\n", err) diff --git a/pkg/agent/instance.go b/pkg/agent/instance.go index a767bcb04..c84a70660 100644 --- a/pkg/agent/instance.go +++ b/pkg/agent/instance.go @@ -91,6 +91,15 @@ func NewAgentInstance( skillsFilter = agentCfg.Skills } + // Apply defaults.Orchestration: if the flag is set, ensure orchestration is enabled. + if defaults.Orchestration { + if subagents == nil { + subagents = &config.SubagentsConfig{Enabled: true} + } else { + subagents.Enabled = true + } + } + maxIter := defaults.MaxToolIterations if maxIter == 0 { maxIter = 20 diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index 75284b6dc..cdcd1f608 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -216,15 +216,17 @@ func registerSharedTools( agent.Tools.Register(tools.NewFindSkillsTool(registryMgr, searchCache)) agent.Tools.Register(tools.NewInstallSkillTool(registryMgr, agent.Workspace)) - // Spawn tool with allowlist checker - subagentManager := tools.NewSubagentManager(provider, agent.Model, agent.Workspace, msgBus) - subagentManager.SetLLMOptions(agent.MaxTokens, agent.Temperature) - spawnTool := tools.NewSpawnTool(subagentManager) - currentAgentID := agentID - spawnTool.SetAllowlistChecker(func(targetAgentID string) bool { - return registry.CanSpawnSubagent(currentAgentID, targetAgentID) - }) - agent.Tools.Register(spawnTool) + // Spawn tool — only registered when orchestration is explicitly enabled. + if agent.Subagents != nil && agent.Subagents.Enabled { + subagentManager := tools.NewSubagentManager(provider, agent.Model, agent.Workspace, msgBus) + subagentManager.SetLLMOptions(agent.MaxTokens, agent.Temperature) + spawnTool := tools.NewSpawnTool(subagentManager) + currentAgentID := agentID + spawnTool.SetAllowlistChecker(func(targetAgentID string) bool { + return registry.CanSpawnSubagent(currentAgentID, targetAgentID) + }) + agent.Tools.Register(spawnTool) + } // Update context builder with the complete tools registry agent.ContextBuilder.SetToolsRegistry(agent.Tools) diff --git a/pkg/config/config.go b/pkg/config/config.go index 7ac337856..299f7334a 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -141,6 +141,7 @@ type AgentConfig struct { } type SubagentsConfig struct { + Enabled bool `json:"enabled,omitempty"` AllowAgents []string `json:"allow_agents,omitempty"` Model *AgentModelConfig `json:"model,omitempty"` } @@ -182,6 +183,7 @@ type AgentDefaults struct { Temperature *float64 `json:"temperature,omitempty" env:"PICOCLAW_AGENTS_DEFAULTS_TEMPERATURE"` MaxToolIterations int `json:"max_tool_iterations" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOOL_ITERATIONS"` TaskReminderInterval int `json:"task_reminder_interval" env:"PICOCLAW_AGENTS_DEFAULTS_TASK_REMINDER_INTERVAL"` + Orchestration bool `json:"orchestration,omitempty" env:"PICOCLAW_AGENTS_DEFAULTS_ORCHESTRATION"` } type ChannelsConfig struct {