Skip to content

Evolution result

evolution_result

Protocol definition for evolution result types.

Defines a shared protocol that both EvolutionResult and MultiAgentEvolutionResult satisfy structurally, enabling engine and utility code to accept either result type without type unions.

This is the project's first data-attribute protocol. Existing protocols in ports/ are method-only. Data annotations were chosen here because the shared surface consists of frozen dataclass fields — data annotations match the structural reality exactly.

ATTRIBUTE DESCRIPTION
EvolutionResultProtocol

Protocol for evolution result types that both single-agent and multi-agent results satisfy.

TYPE: protocol

Examples:

Type-annotate a function that accepts any result type:

from gepa_adk.ports import EvolutionResultProtocol


def summarize(result: EvolutionResultProtocol) -> str:
    pct = result.improvement * 100
    return f"Improved by {pct:.1f}% over {result.total_iterations} iterations"

Verify protocol compliance at runtime:

from gepa_adk.domain.models import EvolutionResult
from gepa_adk.ports import EvolutionResultProtocol

result = EvolutionResult(
    original_score=0.5,
    final_score=0.8,
    evolved_components={"instruction": "Be helpful"},
    iteration_history=[],
    total_iterations=5,
)
assert isinstance(result, EvolutionResultProtocol)
assert result.schema_version == 1
See Also
Note

The protocol deliberately excludes mode-specific fields (valset_score, primary_agent). Consumers needing those fields should use the concrete result types directly.

EvolutionResultProtocol

Bases: Protocol


              flowchart TD
              gepa_adk.ports.evolution_result.EvolutionResultProtocol[EvolutionResultProtocol]

              

              click gepa_adk.ports.evolution_result.EvolutionResultProtocol href "" "gepa_adk.ports.evolution_result.EvolutionResultProtocol"
            

Protocol for evolution result types.

Both EvolutionResult and MultiAgentEvolutionResult satisfy this protocol structurally. Consumers that need the common shape program against this protocol; consumers that need mode-specific data (valset_score, primary_agent) use the concrete type.

ATTRIBUTE DESCRIPTION
schema_version

Schema version for forward-compatible serialization.

TYPE: int

stop_reason

Why the evolution run terminated.

TYPE: StopReason

original_score

Starting performance score (baseline).

TYPE: float

final_score

Ending performance score (best achieved).

TYPE: float

evolved_components

Maps component names to their final evolved text values.

TYPE: dict[str, str]

iteration_history

Chronological list of iteration records.

TYPE: list[IterationRecord]

total_iterations

Number of iterations performed.

TYPE: int

Examples:

Accept any evolution result type:

from gepa_adk.ports import EvolutionResultProtocol


def log_result(result: EvolutionResultProtocol) -> None:
    print(f"Score: {result.original_score} -> {result.final_score}")
    print(f"Improved: {result.improved} ({result.improvement:+.2f})")

Runtime isinstance check:

from gepa_adk.domain.models import MultiAgentEvolutionResult
from gepa_adk.ports import EvolutionResultProtocol

result = MultiAgentEvolutionResult(
    evolved_components={"agent.instruction": "Be precise"},
    original_score=0.4,
    final_score=0.7,
    primary_agent="agent",
    iteration_history=[],
    total_iterations=8,
)
assert isinstance(result, EvolutionResultProtocol)
assert result.schema_version == 1
Source code in src/gepa_adk/ports/evolution_result.py
@runtime_checkable
class EvolutionResultProtocol(Protocol):
    """Protocol for evolution result types.

    Both ``EvolutionResult`` and ``MultiAgentEvolutionResult`` satisfy this
    protocol structurally. Consumers that need the common shape program
    against this protocol; consumers that need mode-specific data
    (``valset_score``, ``primary_agent``) use the concrete type.

    Attributes:
        schema_version (int): Schema version for forward-compatible
            serialization.
        stop_reason (StopReason): Why the evolution run terminated.
        original_score (float): Starting performance score (baseline).
        final_score (float): Ending performance score (best achieved).
        evolved_components (dict[str, str]): Maps component names to their
            final evolved text values.
        iteration_history (list[IterationRecord]): Chronological list of
            iteration records.
        total_iterations (int): Number of iterations performed.

    Examples:
        Accept any evolution result type:

        ```python
        from gepa_adk.ports import EvolutionResultProtocol


        def log_result(result: EvolutionResultProtocol) -> None:
            print(f"Score: {result.original_score} -> {result.final_score}")
            print(f"Improved: {result.improved} ({result.improvement:+.2f})")
        ```

        Runtime isinstance check:

        ```python
        from gepa_adk.domain.models import MultiAgentEvolutionResult
        from gepa_adk.ports import EvolutionResultProtocol

        result = MultiAgentEvolutionResult(
            evolved_components={"agent.instruction": "Be precise"},
            original_score=0.4,
            final_score=0.7,
            primary_agent="agent",
            iteration_history=[],
            total_iterations=8,
        )
        assert isinstance(result, EvolutionResultProtocol)
        assert result.schema_version == 1
        ```
    """

    schema_version: int
    stop_reason: StopReason
    original_score: float
    final_score: float
    evolved_components: dict[str, str]
    iteration_history: list[IterationRecord]
    total_iterations: int

    @property
    def improvement(self) -> float:
        """Calculate score improvement from original to final.

        Returns:
            Difference between final_score and original_score.
        """
        ...

    @property
    def improved(self) -> bool:
        """Check if the final score is better than the original.

        Returns:
            True if final_score > original_score.
        """
        ...

improvement property

improvement: float

Calculate score improvement from original to final.

RETURNS DESCRIPTION
float

Difference between final_score and original_score.

improved property

improved: bool

Check if the final score is better than the original.

RETURNS DESCRIPTION
bool

True if final_score > original_score.