Run the evolution loop for the specified number of cycles.
(self, cycles: int | None = None)
| 66 | self.trial = TrialRunner(self.agent, self.benchmark) |
| 67 | |
| 68 | def run(self, cycles: int | None = None) -> EvolutionResult: |
| 69 | """Run the evolution loop for the specified number of cycles.""" |
| 70 | max_cycles = cycles or self.config.max_cycles |
| 71 | evolution_dir = self.agent.workspace.root / "evolution" |
| 72 | |
| 73 | self.versioning.init() |
| 74 | |
| 75 | score_history: list[float] = [] |
| 76 | |
| 77 | for cycle in range(max_cycles): |
| 78 | cycle_num = cycle + 1 |
| 79 | logger.info("=== Evolution Cycle %d/%d ===", cycle_num, max_cycles) |
| 80 | |
| 81 | # 1. SOLVE |
| 82 | tasks = self.benchmark.get_tasks(split="train", limit=self.config.batch_size) |
| 83 | observations: list[Observation] = [] |
| 84 | |
| 85 | for task in tasks: |
| 86 | try: |
| 87 | trajectory = self.agent.solve(task) |
| 88 | feedback = self.benchmark.evaluate(task, trajectory) |
| 89 | observations.append(Observation(task=task, trajectory=trajectory, feedback=feedback)) |
| 90 | except Exception as e: |
| 91 | logger.error("Error solving task %s: %s", task.id, e) |
| 92 | |
| 93 | # 2. OBSERVE |
| 94 | self.agent.export_to_fs() |
| 95 | batch_path = self.observer.collect(observations) |
| 96 | |
| 97 | cycle_score = ( |
| 98 | sum(o.feedback.score for o in observations) / len(observations) |
| 99 | if observations |
| 100 | else 0.0 |
| 101 | ) |
| 102 | score_history.append(cycle_score) |
| 103 | logger.info("Cycle %d score: %.3f", cycle_num, cycle_score) |
| 104 | |
| 105 | # 3. PRE-EVOLVE SNAPSHOT |
| 106 | self.versioning.commit( |
| 107 | message=f"pre-evo-{cycle_num}: score={cycle_score:.3f}", |
| 108 | tag=f"pre-evo-{cycle_num}", |
| 109 | ) |
| 110 | |
| 111 | # 4. ENGINE STEP |
| 112 | step_result = self.engine.step( |
| 113 | workspace=self.agent.workspace, |
| 114 | observations=observations, |
| 115 | history=self.history, |
| 116 | trial=self.trial, |
| 117 | ) |
| 118 | |
| 119 | # 5. POST-EVOLVE SNAPSHOT |
| 120 | if step_result.mutated: |
| 121 | self.versioning.commit( |
| 122 | message=f"evo-{cycle_num}: {step_result.summary}", |
| 123 | tag=f"evo-{cycle_num}", |
| 124 | ) |
| 125 | else: |
no test coverage detected