Skip to content

Commit dbf7f87

Browse files
committed
resolve confilict
2 parents 2f9361b + 65cbbe8 commit dbf7f87

7 files changed

Lines changed: 520 additions & 8 deletions

File tree

openevolve/config.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,18 @@ class Config:
486486
@classmethod
487487
def from_yaml(cls, path: Union[str, Path]) -> "Config":
488488
"""Load configuration from a YAML file"""
489-
with open(path, "r") as f:
489+
config_path = Path(path).resolve()
490+
with open(config_path, "r") as f:
490491
config_dict = yaml.safe_load(f)
491-
return cls.from_dict(config_dict)
492+
config = cls.from_dict(config_dict)
493+
494+
# Resolve template_dir relative to config file location
495+
if config.prompt.template_dir:
496+
template_path = Path(config.prompt.template_dir)
497+
if not template_path.is_absolute():
498+
config.prompt.template_dir = str((config_path.parent / template_path).resolve())
499+
500+
return config
492501

493502
@classmethod
494503
def from_dict(cls, config_dict: Dict[str, Any]) -> "Config":

openevolve/process_parallel.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class SerializableResult:
3939
iteration: int = 0
4040
error: Optional[str] = None
4141
template_id: Optional[str] = None # For prompt meta-evolution tracking
42+
target_island: Optional[int] = None # Island where child should be placed
4243

4344

4445
def _worker_init(config_dict: dict, evaluation_file: str, parent_env: dict = None) -> None:
@@ -335,6 +336,8 @@ def _run_iteration_worker(
335336

336337
# Extract template_id for meta-evolution tracking (if present)
337338
template_id = prompt.get("template_id") if prompt else None
339+
# Get target island from snapshot (where child should be placed)
340+
target_island = db_snapshot.get("sampling_island")
338341

339342
return SerializableResult(
340343
child_program_dict=child_program.to_dict(),
@@ -345,6 +348,7 @@ def _run_iteration_worker(
345348
artifacts=artifacts,
346349
iteration=iteration,
347350
template_id=template_id,
351+
target_island=target_island,
348352
)
349353

350354
except Exception as e:
@@ -588,9 +592,14 @@ async def run_evolution(
588592
# Reconstruct program from dict
589593
child_program = Program(**result.child_program_dict)
590594

591-
# Add to database (will auto-inherit parent's island)
592-
# No need to specify target_island - database will handle parent island inheritance
593-
self.database.add(child_program, iteration=completed_iteration)
595+
# Add to database with explicit target_island to ensure proper island placement
596+
# This fixes issue #391: children should go to the target island, not inherit
597+
# from the parent (which may be from a different island due to fallback sampling)
598+
self.database.add(
599+
child_program,
600+
iteration=completed_iteration,
601+
target_island=result.target_island,
602+
)
594603

595604
# Store artifacts
596605
if result.artifacts:

openevolve/prompt/meta_evolution.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ def sample_template(self) -> PromptTemplate:
256256
templates = list(self.templates.values())
257257
weights = []
258258
for t in templates:
259-
# Score-based weight with exploration bonus for under-used templates
259+
# Exploration bonus for under-used templates: linearly decreases from 0.3 to 0
260+
# as uses increase from 0 to 20. This ensures new templates get enough trials
261+
# before being judged solely on their score.
260262
exploration_bonus = max(0, 1.0 - t.uses / 20) * 0.3
261263
weights.append(self.get_template_score(t) + exploration_bonus)
262264

@@ -361,6 +363,12 @@ def to_dict(self) -> Dict[str, Any]:
361363
"min_uses_for_evolution": self.min_uses_for_evolution,
362364
"elite_fraction": self.elite_fraction,
363365
"exploration_rate": self.exploration_rate,
366+
# Scoring configuration
367+
"score_weight_success": self.score_weight_success,
368+
"score_weight_improvement": self.score_weight_improvement,
369+
"score_weight_fitness_delta": self.score_weight_fitness_delta,
370+
"score_min_uses": self.score_min_uses,
371+
"score_neutral_prior": self.score_neutral_prior,
364372
"default_template_id": self.default_template_id,
365373
"templates": {tid: t.to_dict() for tid, t in self.templates.items()},
366374
}
@@ -373,6 +381,12 @@ def from_dict(cls, data: Dict[str, Any]) -> "PromptArchive":
373381
min_uses_for_evolution=data.get("min_uses_for_evolution", 10),
374382
elite_fraction=data.get("elite_fraction", 0.3),
375383
exploration_rate=data.get("exploration_rate", 0.2),
384+
# Scoring configuration
385+
score_weight_success=data.get("score_weight_success", 0.3),
386+
score_weight_improvement=data.get("score_weight_improvement", 0.4),
387+
score_weight_fitness_delta=data.get("score_weight_fitness_delta", 0.3),
388+
score_min_uses=data.get("score_min_uses", 5),
389+
score_neutral_prior=data.get("score_neutral_prior", 0.5),
376390
)
377391
archive.default_template_id = data.get("default_template_id")
378392

openevolve/prompt/templates.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
import os
66
import json
7+
import logging
78
from pathlib import Path
89
from typing import Dict, List, Optional, Union, Any
910

11+
logger = logging.getLogger(__name__)
12+
1013
# Base system message template for evolution
1114
BASE_SYSTEM_TEMPLATE = """You are an expert software developer tasked with iteratively improving a codebase.
1215
Your job is to analyze the current program and suggest improvements based on feedback from previous attempts.
@@ -185,8 +188,13 @@ def __init__(self, custom_template_dir: Optional[str] = None):
185188
self._load_from_directory(self.default_dir)
186189

187190
# 2. Override with custom templates (if provided)
188-
if self.custom_dir and self.custom_dir.exists():
189-
self._load_from_directory(self.custom_dir)
191+
if self.custom_dir:
192+
if self.custom_dir.exists():
193+
self._load_from_directory(self.custom_dir)
194+
else:
195+
logger.warning(
196+
f"Custom template directory does not exist, using default prompt."
197+
)
190198

191199
def _load_from_directory(self, directory: Path) -> None:
192200
"""Load all templates and fragments from a directory"""

0 commit comments

Comments
 (0)