Composite
composite ¶
Composite stopper for combining multiple stop conditions.
This module provides a CompositeStopper that combines multiple stoppers with configurable AND/OR logic, enabling complex stopping rules like "stop after 5 minutes OR when score >= 0.95".
| ATTRIBUTE | DESCRIPTION |
|---|---|
CompositeStopper | Combine multiple stoppers with AND/OR logic. TYPE: |
Examples:
Combining stoppers with OR logic (stop if any fires):
from gepa_adk.adapters.stoppers import (
CompositeStopper,
ScoreThresholdStopper,
TimeoutStopper,
)
# Stop after 5 minutes OR when score >= 0.95
composite = CompositeStopper(
[TimeoutStopper(300), ScoreThresholdStopper(0.95)],
mode="any",
)
Combining stoppers with AND logic (stop only if all fire):
# Stop only when BOTH conditions met
composite = CompositeStopper(
[TimeoutStopper(60), ScoreThresholdStopper(0.8)],
mode="all",
)
Note
This composite stopper is useful for building complex termination policies from simpler building blocks.
CompositeStopper ¶
Combine multiple stoppers with AND/OR logic.
A meta-stopper that composes multiple stoppers into a single stopping condition with configurable logic. Use mode='any' for OR semantics (stop if any stopper fires) or mode='all' for AND semantics (stop only if all stoppers fire).
| ATTRIBUTE | DESCRIPTION |
|---|---|
stoppers | The sequence of stoppers to combine. TYPE: |
mode | Combination mode - 'any' for OR, 'all' for AND. TYPE: |
Examples:
Stop after 5 minutes OR when score reaches 95%:
from gepa_adk.adapters.stoppers import (
CompositeStopper,
ScoreThresholdStopper,
TimeoutStopper,
)
from gepa_adk.domain.stopper import StopperState
composite = CompositeStopper(
[TimeoutStopper(300), ScoreThresholdStopper(0.95)],
mode="any",
)
state = StopperState(
iteration=10,
best_score=0.97, # Exceeds threshold
stagnation_counter=2,
total_evaluations=50,
candidates_count=3,
elapsed_seconds=120.0, # Below timeout
)
composite(state) # Returns True (score threshold met)
Stop only when minimum time AND score threshold are both met:
Note
A composite stopper can contain other composite stoppers for arbitrarily complex stopping conditions like "(A OR B) AND (C OR D)".
Source code in src/gepa_adk/adapters/stoppers/composite.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
__init__ ¶
__init__(
stoppers: Sequence[StopperProtocol],
mode: Literal["any", "all"] = "any",
) -> None
Initialize composite stopper with child stoppers and mode.
| PARAMETER | DESCRIPTION |
|---|---|
stoppers | Sequence of stoppers to combine. Must contain at least one stopper. Each stopper must implement StopperProtocol. TYPE: |
mode | Combination logic - 'any' (OR) or 'all' (AND). Defaults to 'any'. TYPE: |
| RAISES | DESCRIPTION |
|---|---|
ValueError | If stoppers sequence is empty. |
ValueError | If mode is not 'any' or 'all'. |
Examples:
# OR logic - stop if either condition met
composite = CompositeStopper(
[TimeoutStopper(300), ScoreThresholdStopper(0.95)],
mode="any",
)
# AND logic - stop only if both conditions met
composite = CompositeStopper(
[TimeoutStopper(60), ScoreThresholdStopper(0.8)],
mode="all",
)
Note
Consider using 'any' mode for fail-safe conditions (timeout OR resource limit) and 'all' mode for minimum requirements.
Source code in src/gepa_adk/adapters/stoppers/composite.py
__call__ ¶
__call__(state: StopperState) -> bool
Check if evolution should stop based on combined stopper logic.
| PARAMETER | DESCRIPTION |
|---|---|
state | Current evolution state snapshot passed to all child stoppers. TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
bool | For mode='any': True if any child stopper returns True. |
bool | For mode='all': True only if all child stoppers return True. |
Examples:
composite = CompositeStopper(
[TimeoutStopper(60), ScoreThresholdStopper(0.9)],
mode="any",
)
# Below both thresholds
state1 = StopperState(
iteration=5,
best_score=0.5,
stagnation_counter=0,
total_evaluations=25,
candidates_count=1,
elapsed_seconds=30.0,
)
composite(state1) # False
# Score threshold met
state2 = StopperState(
iteration=10,
best_score=0.95,
stagnation_counter=1,
total_evaluations=50,
candidates_count=2,
elapsed_seconds=45.0,
)
composite(state2) # True (any mode - score threshold met)
Note
Often called after each iteration. For 'any' mode, evaluation short-circuits on first True. For 'all' mode, short-circuits on first False.
Source code in src/gepa_adk/adapters/stoppers/composite.py
__repr__ ¶
Return string representation of the composite stopper.
| RETURNS | DESCRIPTION |
|---|---|
str | String showing the stoppers list and mode. |
Examples:
composite = CompositeStopper(
[TimeoutStopper(60), ScoreThresholdStopper(0.9)],
mode="any",
)
repr(composite)
# "CompositeStopper([TimeoutStopper(...), ScoreThresholdStopper(...)], mode='any')"