mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-30 06:12:06 +00:00
fix: prevent testing agents from running indefinitely
This fix addresses two root causes that caused testing agents to
accumulate (10-12 agents) instead of maintaining a 1:1 ratio with
coding agents:
1. Testing agents now exit after one session (agent.py)
- Added `or agent_type == "testing"` to the exit condition
- Previously, testing agents never hit the exit condition since
they're spawned with feature_id=None
2. Testing agents now spawn when coding agents START, not complete
- Moved spawn logic from _on_agent_complete() to start_feature()
- Removed the old spawn logic from _on_agent_complete()
- This ensures proper 1:1 ratio and prevents accumulation
Expected behavior after fix:
- First coding agent: no testing agent (no passing features yet)
- Subsequent coding agents: one testing agent spawns per start
- Each testing agent tests ONE feature then terminates immediately
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
7
agent.py
7
agent.py
@@ -306,8 +306,11 @@ async def run_autonomous_agent(
|
||||
print("The autonomous agent has finished its work.")
|
||||
break
|
||||
|
||||
# Single-feature mode: exit after one session (orchestrator manages agents)
|
||||
if feature_id is not None:
|
||||
# Single-feature mode OR testing agent: exit after one session
|
||||
if feature_id is not None or agent_type == "testing":
|
||||
if agent_type == "testing":
|
||||
print("\nTesting agent complete. Terminating session.")
|
||||
else:
|
||||
print(f"\nSingle-feature mode: Feature #{feature_id} session complete.")
|
||||
break
|
||||
|
||||
|
||||
@@ -412,9 +412,16 @@ class ParallelOrchestrator:
|
||||
if not success:
|
||||
return False, message
|
||||
|
||||
# NOTE: Testing agents are spawned in _on_agent_complete() after a coding agent
|
||||
# succeeds, not here. This ensures we only spawn testing agents when there are
|
||||
# actually passing features to test.
|
||||
# Spawn ONE testing agent when coding agent STARTS (if not YOLO mode and passing features exist)
|
||||
# Testing agents exit after one test, so we spawn fresh ones with each coding agent start
|
||||
if not self.yolo_mode and self.testing_agent_ratio > 0:
|
||||
passing_count = self.get_passing_count()
|
||||
if passing_count > 0:
|
||||
print(f"[DEBUG] Coding agent started, spawning testing agent (passing_count={passing_count})", flush=True)
|
||||
debug_log.log("TESTING", "Spawning testing agent on coding agent start",
|
||||
feature_id=feature_id,
|
||||
passing_count=passing_count)
|
||||
self._spawn_testing_agent()
|
||||
|
||||
return True, f"Started feature {feature_id}"
|
||||
|
||||
@@ -724,23 +731,8 @@ class ParallelOrchestrator:
|
||||
# CRITICAL: This print triggers the WebSocket to emit agent_update with state='error' or 'success'
|
||||
print(f"Feature #{feature_id} {status}", flush=True)
|
||||
|
||||
# Spawn testing agents after successful coding agent completion
|
||||
# This is the correct place to spawn testing agents - after we know there are
|
||||
# passing features (the one this agent just completed, plus any previous ones)
|
||||
if return_code == 0 and not self.yolo_mode and self.testing_agent_ratio > 0:
|
||||
passing_count = self.get_passing_count()
|
||||
print(f"[DEBUG] Coding agent completed successfully, passing_count={passing_count}", flush=True)
|
||||
debug_log.log("TESTING", "Checking if testing agents should spawn",
|
||||
yolo_mode=self.yolo_mode,
|
||||
testing_agent_ratio=self.testing_agent_ratio,
|
||||
passing_count=passing_count)
|
||||
if passing_count > 0:
|
||||
print(f"[DEBUG] Spawning testing agents (ratio={self.testing_agent_ratio})", flush=True)
|
||||
debug_log.log("TESTING", f"Spawning {self.testing_agent_ratio} testing agent(s)")
|
||||
self._spawn_testing_agents()
|
||||
elif return_code == 0:
|
||||
debug_log.log("TESTING", "Skipping testing agents",
|
||||
reason="yolo_mode" if self.yolo_mode else f"ratio={self.testing_agent_ratio}")
|
||||
# NOTE: Testing agents are now spawned in start_feature() when coding agents START,
|
||||
# not here when they complete. This ensures 1:1 ratio and proper termination.
|
||||
|
||||
def stop_feature(self, feature_id: int) -> tuple[bool, str]:
|
||||
"""Stop a running coding agent and all its child processes."""
|
||||
|
||||
Reference in New Issue
Block a user