refactor: remove delegation stub and double-loop

- Remove runAgentLoop → runAgentLoopImpl indirection: rename
  runAgentLoopImpl back to runAgentLoop in loop_run.go, delete the
  1-line stub from loop.go
- Remove registerAllOrchestrationTools double-loop: restore al
  parameter to registerSharedTools and call registerOrchestrationTools
  inline in the same agent loop

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dj-oyu 2026-03-15 19:09:26 +09:00
parent c74dbd4c19
commit 3e636ec52a
3 changed files with 9 additions and 32 deletions

View file

@ -155,11 +155,8 @@ func NewAgentLoop(
// Initialize fork-specific fields (stats, sessions, orchestration, gcLoop). // Initialize fork-specific fields (stats, sessions, orchestration, gcLoop).
al.initLoopExt(cfg, registry, len(enableStats) > 0 && enableStats[0]) al.initLoopExt(cfg, registry, len(enableStats) > 0 && enableStats[0])
// Register shared tools to all agents. // Register shared tools to all agents (needs al for orchestration reporter).
registerSharedTools(cfg, msgBus, registry, provider) registerSharedTools(cfg, msgBus, registry, provider, al)
// Register fork-specific orchestration tools (needs al for reporter injection).
al.registerAllOrchestrationTools(cfg, registry, provider, msgBus)
return al return al
} }
@ -170,6 +167,7 @@ func registerSharedTools(
msgBus *bus.MessageBus, msgBus *bus.MessageBus,
registry *AgentRegistry, registry *AgentRegistry,
provider providers.LLMProvider, provider providers.LLMProvider,
al *AgentLoop,
) { ) {
for _, agentID := range registry.ListAgentIDs() { for _, agentID := range registry.ListAgentIDs() {
agent, ok := registry.GetAgent(agentID) agent, ok := registry.GetAgent(agentID)
@ -299,6 +297,9 @@ func registerSharedTools(
} }
} }
// Orchestration tools (spawn, subagent, answer, review_plan)
registerOrchestrationTools(cfg, agent, agentID, registry, provider, msgBus, al)
// Update context builder with the complete tools registry // Update context builder with the complete tools registry
agent.ContextBuilder.SetToolsRegistry(agent.Tools) agent.ContextBuilder.SetToolsRegistry(agent.Tools)
} }
@ -642,8 +643,7 @@ func (al *AgentLoop) ReloadProviderAndConfig(
} }
// Ensure shared tools are re-registered on the new registry // Ensure shared tools are re-registered on the new registry
registerSharedTools(cfg, al.bus, registry, provider) registerSharedTools(cfg, al.bus, registry, provider, al)
al.registerAllOrchestrationTools(cfg, registry, provider, al.bus)
// Atomically swap the config and registry under write lock // Atomically swap the config and registry under write lock
// This ensures readers see a consistent pair // This ensures readers see a consistent pair
@ -1094,10 +1094,6 @@ func (al *AgentLoop) withTelegramThread(channel, chatID string, threadID int) st
return fmt.Sprintf("%s/%d", baseChatID, threadID) return fmt.Sprintf("%s/%d", baseChatID, threadID)
} }
func (al *AgentLoop) runAgentLoop(ctx context.Context, agent *AgentInstance, opts processOptions) (string, error) {
return al.runAgentLoopImpl(ctx, agent, opts)
}
func (al *AgentLoop) targetReasoningChannelID(channelName string) (chatID string) { func (al *AgentLoop) targetReasoningChannelID(channelName string) (chatID string) {
if al.channelManager == nil { if al.channelManager == nil {
return "" return ""

View file

@ -107,24 +107,6 @@ func (al *AgentLoop) SetHeartbeatThreadUpdater(fn func(int)) {
al.onHeartbeatThreadUpdate = fn al.onHeartbeatThreadUpdate = fn
} }
// registerAllOrchestrationTools iterates all agents and registers orchestration
// tools for those with subagents enabled. Called from NewAgentLoop after
// registerSharedTools, keeping the upstream function signature clean.
func (al *AgentLoop) registerAllOrchestrationTools(
cfg *config.Config,
registry *AgentRegistry,
provider providers.LLMProvider,
msgBus *bus.MessageBus,
) {
for _, agentID := range registry.ListAgentIDs() {
agent, ok := registry.GetAgent(agentID)
if !ok {
continue
}
registerOrchestrationTools(cfg, agent, agentID, registry, provider, msgBus, al)
}
}
// registerOrchestrationTools registers spawn, subagent, answer, and review_plan // registerOrchestrationTools registers spawn, subagent, answer, and review_plan
// tools for agents with orchestration enabled. // tools for agents with orchestration enabled.
func registerOrchestrationTools( func registerOrchestrationTools(

View file

@ -19,9 +19,8 @@ import (
"github.com/sipeed/picoclaw/pkg/utils" "github.com/sipeed/picoclaw/pkg/utils"
) )
// runAgentLoopImpl is the full implementation of runAgentLoop, extracted // runAgentLoop is the main message processing loop for a single agent session.
// to keep loop.go minimal and reduce upstream merge conflicts. func (al *AgentLoop) runAgentLoop(ctx context.Context, agent *AgentInstance, opts processOptions) (string, error) {
func (al *AgentLoop) runAgentLoopImpl(ctx context.Context, agent *AgentInstance, opts processOptions) (string, error) {
// -1. Acquire per-session lock to prevent concurrent access on the same session // -1. Acquire per-session lock to prevent concurrent access on the same session
if !al.acquireSessionLock(ctx, opts.SessionKey) { if !al.acquireSessionLock(ctx, opts.SessionKey) {