Skip to content

Commit fd5e15a

Browse files
committed
Fix candidate evaluation for multi-file projects
- Add support for evaluating programs that depend on multiple files - For non-Python programs, copy the source directory to temp and replace the evolving file - This ensures fixed files are available during evaluation Fixes #402
1 parent 65cbbe8 commit fd5e15a

1 file changed

Lines changed: 26 additions & 4 deletions

File tree

openevolve/evaluator.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import json
88
import logging
99
import os
10+
import shutil
1011
import subprocess
1112
import sys
1213
import tempfile
@@ -45,13 +46,15 @@ def __init__(
4546
prompt_sampler: Optional[PromptSampler] = None,
4647
database: Optional[ProgramDatabase] = None,
4748
suffix: Optional[str] = ".py",
49+
initial_program_path: Optional[str] = None,
4850
):
4951
self.config = config
5052
self.evaluation_file = evaluation_file
5153
self.program_suffix = suffix
5254
self.llm_ensemble = llm_ensemble
5355
self.prompt_sampler = prompt_sampler
5456
self.database = database
57+
self.initial_program_path = initial_program_path
5558

5659
# Create a task pool for parallel evaluation
5760
self.task_pool = TaskPool(max_concurrency=config.parallel_evaluations)
@@ -153,10 +156,29 @@ async def evaluate_program(
153156
# Retry logic for evaluation
154157
last_exception = None
155158
for attempt in range(self.config.max_retries + 1):
156-
# Create a temporary file for the program
157-
with tempfile.NamedTemporaryFile(suffix=self.program_suffix, delete=False) as temp_file:
158-
temp_file.write(program_code.encode("utf-8"))
159-
temp_file_path = temp_file.name
159+
# Create a temporary file or directory for the program
160+
if self.initial_program_path and self.program_suffix != ".py":
161+
# For non-Python files, create temp directory with all files from source directory
162+
temp_dir = tempfile.mkdtemp()
163+
src_dir = os.path.dirname(os.path.abspath(self.initial_program_path))
164+
initial_file_name = os.path.basename(self.initial_program_path)
165+
166+
# Copy all files from source directory except the initial program file
167+
for file_name in os.listdir(src_dir):
168+
if file_name != initial_file_name:
169+
src_file = os.path.join(src_dir, file_name)
170+
if os.path.isfile(src_file):
171+
shutil.copy2(src_file, temp_dir)
172+
173+
# Write the program_code to the initial file name in temp directory
174+
temp_file_path = os.path.join(temp_dir, initial_file_name)
175+
with open(temp_file_path, "w", encoding="utf-8") as f:
176+
f.write(program_code)
177+
else:
178+
# Standard temp file creation for Python or when no initial_program_path
179+
with tempfile.NamedTemporaryFile(suffix=self.program_suffix, delete=False) as temp_file:
180+
temp_file.write(program_code.encode("utf-8"))
181+
temp_file_path = temp_file.name
160182

161183
try:
162184
# Run evaluation

0 commit comments

Comments
 (0)