Files
Aperant/auto-claude/spec/phases/planning_phases.py
T
AndyMik90 26725286d5 feat: introduce phase configuration module and enhance agent profiles
This commit adds a new phase configuration module that manages model and thinking level settings for different execution phases. It reads configurations from `task_metadata.json` and provides resolved model IDs for various phases, including spec creation, planning, coding, and QA.

Key changes include:
- New `phase_config.py` file to handle model ID mappings and thinking budgets.
- Updates to agent files (`coder.py`, `planner.py`, `loop.py`) to utilize phase-specific models and thinking levels.
- Modifications to the CLI and UI components to support per-phase configuration, enhancing the user experience for task creation and editing.

The new structure allows for optimized model selection and thinking depth based on the phase, improving overall task execution efficiency.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-12-19 10:24:44 +01:00

176 lines
6.8 KiB
Python

"""
Planning and Validation Phase Implementations
==============================================
Phases for implementation planning and final validation.
"""
from typing import TYPE_CHECKING
from task_logger import LogEntryType, LogPhase
from .. import writer
from .models import MAX_RETRIES, PhaseResult
if TYPE_CHECKING:
pass
class PlanningPhaseMixin:
"""Mixin for planning and validation phase methods."""
async def phase_planning(self) -> PhaseResult:
"""Create the implementation plan."""
from ..validate_pkg.auto_fix import auto_fix_plan
plan_file = self.spec_dir / "implementation_plan.json"
if plan_file.exists():
result = self.spec_validator.validate_implementation_plan()
if result.valid:
self.ui.print_status(
"implementation_plan.json already exists and is valid", "success"
)
return PhaseResult("planning", True, [str(plan_file)], [], 0)
self.ui.print_status("Plan exists but invalid, regenerating...", "warning")
errors = []
# Try Python script first (deterministic)
self.ui.print_status("Trying planner.py (deterministic)...", "progress")
success, output = self._run_script(
"planner.py", ["--spec-dir", str(self.spec_dir)]
)
if success and plan_file.exists():
result = self.spec_validator.validate_implementation_plan()
if result.valid:
self.ui.print_status(
"Created valid implementation_plan.json via script", "success"
)
stats = writer.get_plan_stats(self.spec_dir)
if stats:
self.task_logger.log(
f"Implementation plan created with {stats.get('total_subtasks', 0)} subtasks",
LogEntryType.SUCCESS,
LogPhase.PLANNING,
)
return PhaseResult("planning", True, [str(plan_file)], [], 0)
else:
if auto_fix_plan(self.spec_dir):
result = self.spec_validator.validate_implementation_plan()
if result.valid:
self.ui.print_status(
"Auto-fixed implementation_plan.json", "success"
)
return PhaseResult("planning", True, [str(plan_file)], [], 0)
errors.append(f"Script output invalid: {result.errors}")
# Fall back to agent
self.ui.print_status("Falling back to planner agent...", "progress")
for attempt in range(MAX_RETRIES):
self.ui.print_status(
f"Running planner agent (attempt {attempt + 1})...", "progress"
)
success, output = await self.run_agent_fn(
"planner.md",
phase_name="planning",
)
if success and plan_file.exists():
result = self.spec_validator.validate_implementation_plan()
if result.valid:
self.ui.print_status(
"Created valid implementation_plan.json via agent", "success"
)
return PhaseResult("planning", True, [str(plan_file)], [], attempt)
else:
if auto_fix_plan(self.spec_dir):
result = self.spec_validator.validate_implementation_plan()
if result.valid:
self.ui.print_status(
"Auto-fixed implementation_plan.json", "success"
)
return PhaseResult(
"planning", True, [str(plan_file)], [], attempt
)
errors.append(f"Agent attempt {attempt + 1}: {result.errors}")
self.ui.print_status("Plan created but invalid", "error")
else:
errors.append(f"Agent attempt {attempt + 1}: Did not create plan file")
return PhaseResult("planning", False, [], errors, MAX_RETRIES)
async def phase_validation(self) -> PhaseResult:
"""Final validation of all spec files with auto-fix retry."""
for attempt in range(MAX_RETRIES):
results = self.spec_validator.validate_all()
all_valid = all(r.valid for r in results)
for result in results:
if result.valid:
self.ui.print_status(f"{result.checkpoint}: PASS", "success")
else:
self.ui.print_status(f"{result.checkpoint}: FAIL", "error")
for err in result.errors:
print(f" {self.ui.muted('Error:')} {err}")
if all_valid:
print()
self.ui.print_status("All validation checks passed", "success")
return PhaseResult("validation", True, [], [], attempt)
# If not valid, try to auto-fix with AI agent
if attempt < MAX_RETRIES - 1:
print()
self.ui.print_status(
f"Attempting auto-fix (attempt {attempt + 1}/{MAX_RETRIES - 1})...",
"progress",
)
# Collect all errors for the fixer agent
error_details = []
for result in results:
if not result.valid:
error_details.append(
f"**{result.checkpoint}** validation failed:"
)
for err in result.errors:
error_details.append(f" - {err}")
if result.fixes:
error_details.append(" Suggested fixes:")
for fix in result.fixes:
error_details.append(f" - {fix}")
context_str = f"""
**Spec Directory**: {self.spec_dir}
## Validation Errors to Fix
{chr(10).join(error_details)}
## Files in Spec Directory
The following files exist in the spec directory:
- context.json
- requirements.json
- spec.md
- implementation_plan.json
- project_index.json (if exists)
Read the failed files, understand the errors, and fix them.
"""
success, output = await self.run_agent_fn(
"validation_fixer.md",
additional_context=context_str,
phase_name="validation",
)
if not success:
self.ui.print_status("Auto-fix agent failed", "warning")
# All retries exhausted
errors = [f"{r.checkpoint}: {err}" for r in results for err in r.errors]
return PhaseResult("validation", False, [], errors, MAX_RETRIES)