mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-30 22:32:06 +00:00
refactor: remove testing agent claim mechanism for concurrent testing
Remove the testing_in_progress claim/release mechanism from the testing agent architecture. Multiple testing agents can now test the same feature concurrently, simplifying the system and eliminating potential stale lock issues. Changes: - parallel_orchestrator.py: - Remove claim_feature_for_testing() and release_testing_claim() methods - Remove _cleanup_stale_testing_locks() periodic cleanup - Replace with simple _get_random_passing_feature() selection - Remove startup stale lock cleanup code - Remove STALE_TESTING_LOCK_MINUTES constant - Remove unused imports (timedelta, text) - api/database.py: - Remove testing_in_progress and last_tested_at columns from Feature model - Update to_dict() to exclude these fields - Convert _migrate_add_testing_columns() to no-op for backwards compat - mcp_server/feature_mcp.py: - Remove feature_release_testing tool entirely - Remove unused datetime import - prompts.py: - Update testing prompt to remove feature_release_testing instruction - Testing agents now just verify and exit (no cleanup needed) - server/websocket.py: - Update AgentTracker to use composite keys (feature_id, agent_type) - Prevents ghost agent creation from ambiguous [Feature #X] messages - Proper separation of coding vs testing agent tracking Benefits: - Eliminates artificial bottleneck from claim coordination - No stale locks to clean up after crashes - Simpler crash recovery (no testing state to restore) - Reduced database writes (no claim/release transactions) - Matches intended design: random, concurrent regression testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,6 @@ Tools:
|
||||
- feature_mark_in_progress: Mark a feature as in-progress
|
||||
- feature_claim_and_get: Atomically claim and get feature details
|
||||
- feature_clear_in_progress: Clear in-progress status
|
||||
- feature_release_testing: Release testing lock on a feature
|
||||
- feature_create_bulk: Create multiple features at once
|
||||
- feature_create: Create a single feature
|
||||
- feature_add_dependency: Add a dependency between features
|
||||
@@ -33,7 +32,6 @@ import os
|
||||
import sys
|
||||
import threading
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Annotated
|
||||
|
||||
@@ -228,57 +226,6 @@ def feature_get_summary(
|
||||
session.close()
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def feature_release_testing(
|
||||
feature_id: Annotated[int, Field(description="The ID of the feature to release", ge=1)],
|
||||
tested_ok: Annotated[bool, Field(description="True if the feature passed testing, False if regression found")] = True
|
||||
) -> str:
|
||||
"""Release a feature after regression testing completes.
|
||||
|
||||
Clears the testing_in_progress flag and updates last_tested_at timestamp.
|
||||
|
||||
This should be called after testing is complete, whether the feature
|
||||
passed or failed. If tested_ok=False, the feature was marked as failing
|
||||
by a previous call to feature_mark_failing.
|
||||
|
||||
Args:
|
||||
feature_id: The ID of the feature that was being tested
|
||||
tested_ok: True if testing passed, False if a regression was found
|
||||
|
||||
Returns:
|
||||
JSON with release confirmation or error message.
|
||||
"""
|
||||
session = get_session()
|
||||
try:
|
||||
feature = session.query(Feature).filter(Feature.id == feature_id).first()
|
||||
|
||||
if feature is None:
|
||||
return json.dumps({"error": f"Feature with ID {feature_id} not found"})
|
||||
|
||||
if not feature.testing_in_progress:
|
||||
return json.dumps({
|
||||
"warning": f"Feature {feature_id} was not being tested",
|
||||
"feature": feature.to_dict()
|
||||
})
|
||||
|
||||
# Clear testing flag and update timestamp
|
||||
feature.testing_in_progress = False
|
||||
feature.last_tested_at = datetime.now(timezone.utc)
|
||||
session.commit()
|
||||
session.refresh(feature)
|
||||
|
||||
status = "passed" if tested_ok else "failed (regression detected)"
|
||||
return json.dumps({
|
||||
"message": f"Feature #{feature_id} testing {status}",
|
||||
"feature": feature.to_dict()
|
||||
})
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
return json.dumps({"error": f"Failed to release testing claim: {str(e)}"})
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def feature_mark_passing(
|
||||
feature_id: Annotated[int, Field(description="The ID of the feature to mark as passing", ge=1)]
|
||||
|
||||
Reference in New Issue
Block a user