Add parent directory to path for imports

""" Iris Refine Orchestrator

BeanSparrow 3 updated 5mo ago
Claude CodeGeneric
View source ↗
#!/usr/bin/env python3
"""
Iris Refine Orchestrator

Manages Ralph Wiggum-style iterative refinement loop.
Handles database operations, configuration, and reporting for the refine phase.

Version: 1.0.0
"""

import json
import argparse
import sys
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional, Any
from dataclasses import dataclass

# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent))
from database.db_manager import DatabaseManager


@dataclass
class RefineConfig:
    """Configuration for refine phase based on complexity"""
    complexity: str
    max_iterations: int
    reviewer_count: int
    review_focus_areas: List[str]

    @classmethod
    def from_complexity(cls, complexity: str) -> 'RefineConfig':
        """Create config based on project complexity"""
        configs = {
            'MICRO': {
                'max_iterations': 5,
                'reviewer_count': 2,
                'review_focus_areas': ['gaps', 'quality']
            },
            'SMALL': {
                'max_iterations': 5,
                'reviewer_count': 3,
                'review_focus_areas': ['gaps', 'quality', 'edge_cases']
            },
            'MEDIUM': {
                'max_iterations': 6,
                'reviewer_count': 4,
                'review_focus_areas': ['gaps', 'quality', 'integration', 'edge_cases']
            },
            'LARGE': {
                'max_iterations': 8,
                'reviewer_count': 5,
                'review_focus_areas': ['gaps', 'quality', 'integration', 'edge_cases', 'security']
            },
            'ENTERPRISE': {
                'max_iterations': 10,
                'reviewer_count': 6,
                'review_focus_areas': ['gaps', 'quality', 'integration', 'edge_cases', 'security', 'performance']
            }
        }

        config = configs.get(complexity.upper(), configs['MEDIUM'])
        return cls(
            complexity=complexity.upper(),
            max_iterations=config['max_iterations'],
            reviewer_count=config['reviewer_count'],
            review_focus_areas=config['review_focus_areas']
        )


class RefineOrchestrator:
    """Orchestrates the Ralph Wiggum-style refinement loop"""

    def __init__(self, db_path: Optional[str] = None):
        self.db = DatabaseManager(db_path)

    def get_config(self) -> RefineConfig:
        """Get refine configuration from database"""
        with self.db.get_connection() as conn:
            # Get complexity
            result = conn.execute(
                "SELECT value FROM project_metadata WHERE key = 'project_complexity'"
            ).fetchone()
            complexity = result['value'] if result else 'MEDIUM'

            # Check for custom max_iterations override
            iter_result = conn.execute(
                "SELECT value FROM project_state WHERE key = 'refine_max_iterations'"
            ).fetchone()

            config = RefineConfig.from_complexity(complexity)

            # Apply override if set
            if iter_result and iter_result['value']:
                config.max_iterations = max(5, int(iter_result['value']))  # Minimum 5

            return config

    def initialize_refine_phase(self) -> Dict[str, Any]:
        """Initialize the refine phase"""
        config = self.get_config()

        with self.db.get_connection() as conn:
            conn.execute(
                "INSERT OR REPLACE INTO project_state (key, value) VALUES (?, ?)",
                ('refine_phase_status', 'in_progress')
            )
            conn.execute(
                "INSERT OR REPLACE INTO project_state (key, value) VALUES (?, ?)",
                ('refine_current_iteration', '0')
            )
            conn.execute(
                "INSERT OR REPLACE INTO project_state (key, value) VALUES (?, ?)",
                ('refine_max_iterations', str(config.max_iterations))
            )
            conn.execute(
                "INSERT OR REPLACE INTO project_metadata (key, value) VALUES (?, ?)",
                ('refine_started_at', datetime.now().isoformat())
            )
            conn.commit()

        return {
            'status': 'initialized',
            'complexity': config.complexity,
            'max_iterations': config.max_iterations,
            'reviewer_count': config.reviewer_count,
            'review_focus_areas': config.review_focus_areas
        }

    def start_iteration(self, iteration_number: int) -> int:
        """Start a new iteration and return its ID"""
        with self.db.get_connection() as conn:
            conn.execute(
                """INSERT INTO refine_iterations (iteration_number, status, started_at)
                   VALUES (?, 'in_progress', datetime('now'))""",
                (iteration_number,)
            )
            conn.execute(
                "INSERT OR REPLACE INTO project_state (key, value) VALUES (?, ?)",
                ('refine_current_iteration', str(iteration_number))
            )
            conn.commit()

            result = conn.execute("SELECT last_insert_rowid()").fetchone()
            return result[0]

    def store_finding(self, iteration_id: int, finding: Dict[str, Any]) -> int:
        """Store a finding from a review agent"""
        with self.db.get_connection() as conn:
            conn.execute(
                """INSERT INTO refine_findings
                   (iteration_id, reviewer_focus, severity, category, file_path,
                    line_number, description, suggestion, prd_reference)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
                (
                    iteration_id,
                    finding.get('focus_area', 'unknown'),
                    finding.get('severity', 'MEDIUM'),
                    finding.get('category', finding.get('focus_area', 'unknown')),
                    finding.get('file'),
                    finding.get('line'),
                    finding.get('des

Maintain Add parent directory to path for imports?

Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.

[Add parent directory to path for imports on getagentictools](https://getagentictools.com/loops/beansparrow-add-parent-directory-to-path-for-imports?ref=badge)