fix(agent): enhance SubTurn robustness and fix race conditions

Major improvements to SubTurn implementation:

**Fixes:**
- Channel close race condition (sync.Once)
- Semaphore blocking timeout (30s)
- Redundant context wrapping
- Memory accumulation (auto-truncate at 50 msgs)
- Channel draining on Finish()
- Missing depth limit logging
- Model validation

**Enhancements:**
- Comprehensive documentation (150+ lines)
- 11 new tests covering edge cases
- Improved error messages

All tests pass. Production-ready.

Related: #1316
This commit is contained in:
Administrator
2026-03-17 12:50:32 +08:00
parent 672d11c7d4
commit 12a8590ada
7 changed files with 1466 additions and 178 deletions
+8 -1
View File
@@ -300,10 +300,16 @@ func registerSharedTools(
spawnTool.SetAllowlistChecker(func(targetAgentID string) bool {
return registry.CanSpawnSubagent(currentAgentID, targetAgentID)
})
// Set SubTurnSpawner for direct sub-turn execution
spawner := NewSubTurnSpawner(al)
spawnTool.SetSpawner(spawner)
agent.Tools.Register(spawnTool)
// Also register the synchronous subagent tool
subagentTool := tools.NewSubagentTool(subagentManager)
subagentTool.SetSpawner(spawner)
agent.Tools.Register(subagentTool)
} else {
logger.WarnCF("agent", "spawn tool requires subagent to be enabled", nil)
@@ -988,6 +994,7 @@ func (al *AgentLoop) runAgentLoop(
concurrencySem: make(chan struct{}, 5), // maxConcurrentSubTurns
}
ctx = withTurnState(ctx, rootTS)
ctx = WithAgentLoop(ctx, al) // Inject AgentLoop for tool access
isRootTurn = true
// Register this root turn state so HardAbort can find it