Proposer
proposer ¶
Async reflective mutation proposer for GEPA evolution.
This module provides the AsyncReflectiveMutationProposer class that generates text mutations via LLM reflection. It takes a component's current text and component feedback containing performance data, then uses async LLM calls to propose improved text.
Terminology
- component: An evolvable unit with a name and text (like a gear in a machine)
- component_text: The current text content of a component being evolved
- trial: One performance record containing:
- input: What was given to the system
- output: What the system produced
- feedback: Critic evaluation (score, feedback_text, feedback_*)
- trajectory: Execution record (tool calls, state, events)
- trials: Collection of trial records for reflection
- proposed_component_text: The improved text for the same component
| ATTRIBUTE | DESCRIPTION |
|---|---|
AsyncReflectiveMutationProposer | Main proposer class that generates text mutations via LLM reflection. TYPE: |
ReflectionFn | Async callable signature for reflection functions: TYPE: |
ReflectiveDataset | Mapping of component names to trial sequences. TYPE: |
ProposalResult | Dictionary of proposed mutations or None. TYPE: |
Examples:
Basic proposer usage with ADK reflection:
from gepa_adk.engine import (
AsyncReflectiveMutationProposer,
create_adk_reflection_fn,
)
reflection_fn = create_adk_reflection_fn(reflection_agent, executor)
proposer = AsyncReflectiveMutationProposer(adk_reflection_fn=reflection_fn)
result = await proposer.propose(
candidate={"instruction": "Be helpful"},
reflective_dataset={"instruction": [trials]},
components_to_update=["instruction"],
)
See Also
gepa_adk.ports.proposer: Proposer protocol definition.gepa_adk.engine.async_engine: Evolution engine that uses proposers.gepa_adk.engine.adk_reflection: ADK-based reflection function factory.
Note
This module requires an ADK reflection function for proposing mutations. Use create_adk_reflection_fn() from gepa_adk.engine.adk_reflection to create a reflection function from an ADK LlmAgent.
ReflectionFn module-attribute ¶
Async callable for reflection.
Signature: (component_text: str, trials: list[dict]) -> str
Optionally supports: (component_text, trials, component_name: str | None) -> str
Takes current component text and trials, optionally with component name, returns proposed component text. The component_name parameter (when supported) enables component-aware auto-selection of reflection agents.
Note
For backward compatibility, reflection functions can accept either: - 2 parameters: (component_text, trials) - 3 parameters: (component_text, trials, component_name)
The proposer will inspect the function signature and call appropriately.
AsyncReflectiveMutationProposer ¶
Generates text mutations via LLM reflection.
This proposer takes a candidate's current component texts and feedback data, then uses an ADK reflection function to generate improved versions. It handles empty datasets gracefully by returning None without making LLM calls.
Terminology
- component: Evolvable unit with name + text (the "gear" being tuned)
- component_text: The text content of a component
- trial: One record {input, output, feedback, trajectory}
- trials: Collection of trial records for reflection
- proposed_component_text: The improved text for the same component
| ATTRIBUTE | DESCRIPTION |
|---|---|
adk_reflection_fn | ADK reflection function for proposing mutations. Created via TYPE: |
Examples:
Standard usage with ADK reflection agent:
from gepa_adk.engine import create_adk_reflection_fn
reflection_fn = create_adk_reflection_fn(reflection_agent, executor)
proposer = AsyncReflectiveMutationProposer(adk_reflection_fn=reflection_fn)
result = await proposer.propose(
candidate={"instruction": "Be helpful"},
reflective_dataset={"instruction": [trials]},
components_to_update=["instruction"],
)
Note
ADK-based reflection via adk_reflection_fn is the only supported approach. Use create_adk_reflection_fn() from gepa_adk.engine.adk_reflection to create the reflection function.
Source code in src/gepa_adk/engine/proposer.py
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 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | |
__init__ ¶
__init__(adk_reflection_fn: ReflectionFn) -> None
Initialize the mutation proposer.
| PARAMETER | DESCRIPTION |
|---|---|
adk_reflection_fn | Async callable for ADK-based reflection. Takes (component_text, trials) and returns proposed text. Create with TYPE: |
| RAISES | DESCRIPTION |
|---|---|
ValueError | If adk_reflection_fn is None. |
Examples:
from gepa_adk.engine import create_adk_reflection_fn
reflection_fn = create_adk_reflection_fn(reflection_agent, executor)
proposer = AsyncReflectiveMutationProposer(adk_reflection_fn=reflection_fn)
Note
Configuration validation happens immediately to fail fast rather than waiting until the first propose() call.
Source code in src/gepa_adk/engine/proposer.py
propose async ¶
propose(
candidate: dict[str, str],
reflective_dataset: ReflectiveDataset,
components_to_update: list[str],
) -> ProposalResult
Propose mutated component text via LLM reflection.
| PARAMETER | DESCRIPTION |
|---|---|
candidate | Current candidate component texts. Keys are component names, values are component text. Example: {"instruction": "Be helpful and concise"} TYPE: |
reflective_dataset | Trials per component name. Each trial contains input, output, feedback, and optional trajectory. Example: {"instruction": [{ "input": "Hello", "output": "Hi there!", "feedback": {"score": 0.75, "feedback_text": "Could be more formal"}, "trajectory": {...} }]} TYPE: |
components_to_update | Component names to generate proposals for. Example: ["instruction"] TYPE: |
| RETURNS | DESCRIPTION |
|---|---|
ProposalResult | Dictionary mapping component names to proposed component text, or None if the reflective dataset is empty or has no entries for the requested components. TYPE: |
| RAISES | DESCRIPTION |
|---|---|
EvolutionError | If ADK reflection returns invalid response. |
Examples:
result = await proposer.propose(
candidate={"instruction": "Be helpful"},
reflective_dataset={
"instruction": [
{
"input": "I am the King",
"output": "Hey!",
"feedback": {"score": 0.3, "feedback_text": "Too casual"},
"trajectory": {...},
}
]
},
components_to_update=["instruction"],
)
# result: {"instruction": "Greet users formally..."}
Note
Output validation ensures that empty or None LLM responses raise EvolutionError rather than breaking the evolution loop silently.
Source code in src/gepa_adk/engine/proposer.py
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 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | |