Repository navigation
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #311 and the request for a comparison example.
An opponent change also changes fitness: keeping the previous scores can make a population select a program that no longer performs well. This adds
run_coevolution, which alternates two independently configured OpenEvolve engines. Each phase freezes a cohort of opposing champions, re-evaluates the active population and rebuilds its selection state before generating new programs.The coordinator keeps the two program populations separate, retains internal island scheduling and lineage, and commits both population state and the completed-phase cursor together. Resume checks the evaluator/task identity, configurations, seeds and phase settings. A failed phase restarts against the same committed opponent cohort; external calls may repeat. The bounded opponent history contains recent distinct champions. Existing single-population APIs are unchanged.
The executable CPU example evolves an attack policy and a defender's inspection allocation over three channels. It uses the real APIs and process workers with a local scripted proposal endpoint, not an LLM. It compares competition with the existing engine against fixed opponents, using both equal proposal counts and a larger static-baseline match budget. Counts include refreshes and every cross-match.
For final-version seeds 0, 1 and 2 in both single-channel and mixed-attacker variants, worst-channel detection was 1/3 with competition versus 0 for both static baselines. Mean detection remained 1/3 throughout. The three single-channel runs used 561/567/579 matches in total; the larger static baselines used 940/955/969. Complete counts, source hashes, commands and the earlier exploratory mixed-attacker no-gain result are included in the example. This is a controlled finite-policy demonstration, not evidence of real LLM quality, unseen-task generalization or Nash convergence.
Validation on macOS arm64 / Python 3.12.3:
OPENAI_API_KEY=test-key-for-unit-tests python -m unittest discover -s tests -p 'test_*.py': 588 tests passed, including 14 new tests. These cover score refresh, population isolation, phase failure/resume, context mismatch, stale artifacts, island counters and a real process-worker run.isort,black) andgit diff --checkpassed.Recovery is single-writer and phase-level. Evaluators/programs and their serialized wrappers require the same trust as existing OpenEvolve runs; external effects are not exactly-once. Returned champion scores belong to each population's last opponent cohort. No paid model, GPU, distributed or real-model quality experiment was run.