Skip to content

Index

review

AI code review module for Marianne.

Provides automated code quality assessment after batch execution.

Classes

AIReviewer

AIReviewer(backend, config, diff_provider=None)

Performs AI-powered code review using a backend.

Uses the same backend as Marianne execution to send the diff for review and parse the scoring response.

Initialize reviewer.

Parameters:

Name Type Description Default
backend Backend

Execution backend for AI calls.

required
config AIReviewConfig

AI review configuration.

required
diff_provider GitDiffProvider | None

Provider for git diffs. Defaults to GitDiffProvider.

None
Source code in src/marianne/review/scorer.py
def __init__(
    self,
    backend: "Backend",
    config: "AIReviewConfig",
    diff_provider: GitDiffProvider | None = None,
) -> None:
    """Initialize reviewer.

    Args:
        backend: Execution backend for AI calls.
        config: AI review configuration.
        diff_provider: Provider for git diffs. Defaults to GitDiffProvider.
    """
    self.backend = backend
    self.config = config
    self.diff_provider = diff_provider or GitDiffProvider()
Functions
review async
review(workspace)

Perform AI review on workspace changes.

Parameters:

Name Type Description Default
workspace Path

Directory to review.

required

Returns:

Type Description
AIReviewResult

AIReviewResult with score and feedback.

Source code in src/marianne/review/scorer.py
async def review(self, workspace: Path) -> AIReviewResult:
    """Perform AI review on workspace changes.

    Args:
        workspace: Directory to review.

    Returns:
        AIReviewResult with score and feedback.
    """
    if not self.config.enabled:
        return AIReviewResult(
            score=100,
            summary="AI review disabled",
        )

    # Get the diff
    diff = self.diff_provider.get_diff(workspace)

    if not diff or not diff.strip():
        _logger.debug("No diff to review")
        return AIReviewResult(
            score=100,
            summary="No changes to review",
        )

    # Truncate very large diffs
    max_diff_chars = 50000
    if len(diff) > max_diff_chars:
        diff = diff[:max_diff_chars] + "\n\n... [diff truncated] ..."

    # Build review prompt
    prompt_template = self.config.review_prompt_template or DEFAULT_REVIEW_PROMPT
    prompt = prompt_template.format(diff=diff)

    try:
        # Execute review using backend
        result = await self.backend.execute(prompt)

        if result.success and result.output:
            return self._parse_review_response(result.output)
        else:
            return AIReviewResult(
                score=0,
                error=result.error_message or "Review execution failed",
                summary="Failed to execute review",
            )
    except (OSError, TimeoutError, RuntimeError) as e:
        _logger.error("ai_review_failed", error=str(e))
        return AIReviewResult(
            score=0,
            error=str(e),
            summary="Review failed with exception",
        )
evaluate_result
evaluate_result(result)

Evaluate review result against config thresholds.

Parameters:

Name Type Description Default
result AIReviewResult

Review result to evaluate.

required

Returns:

Type Description
bool

Tuple of (passed, message).

str

passed is True if score >= min_score.

Source code in src/marianne/review/scorer.py
def evaluate_result(
    self, result: AIReviewResult
) -> tuple[bool, str]:
    """Evaluate review result against config thresholds.

    Args:
        result: Review result to evaluate.

    Returns:
        Tuple of (passed, message).
        passed is True if score >= min_score.
    """
    if result.score >= self.config.target_score:
        return True, f"High quality ({result.score}/100): {result.summary}"
    elif result.score >= self.config.min_score:
        return True, f"Acceptable ({result.score}/100): {result.summary}"
    else:
        return False, f"Below threshold ({result.score}/100): {result.summary}"

AIReviewResult dataclass

AIReviewResult(score, components=dict(), issues=list(), summary='', raw_response='', error=None)

Result of an AI code review.

Attributes
passed property
passed

Check if review passed minimum threshold (60).

high_quality property
high_quality

Check if review achieved target score (80+).

Functions
to_dict
to_dict()

Convert to dictionary.

Source code in src/marianne/review/scorer.py
def to_dict(self) -> dict[str, Any]:
    """Convert to dictionary."""
    return {
        "score": self.score,
        "components": self.components,
        "issues": [i.to_dict() for i in self.issues],
        "summary": self.summary,
        "passed": self.passed,
        "high_quality": self.high_quality,
        "error": self.error,
    }

ReviewIssue dataclass

ReviewIssue(severity, category, description, suggestion=None)

A single issue found during code review.

Functions
to_dict
to_dict()

Convert to dictionary.

Source code in src/marianne/review/scorer.py
def to_dict(self) -> dict[str, Any]:
    """Convert to dictionary."""
    return {
        "severity": self.severity,
        "category": self.category,
        "description": self.description,
        "suggestion": self.suggestion,
    }