From fe3430f0f5f3129c327a709398d4ccb6111d3181 Mon Sep 17 00:00:00 2001 From: Asankhaya Sharma Date: Wed, 23 Jul 2025 07:44:40 +0800 Subject: [PATCH 1/2] Update prompt sampling and config for artifacts Added artifact rendering options to default_config.yaml, including size and security filter settings. Refactored process_parallel.py to use config values for program selection limits. Updated prompt/sampler.py to display full program code instead of truncated snippets and to use config-based limits for key features. --- configs/default_config.yaml | 5 +++++ openevolve/process_parallel.py | 5 +++-- openevolve/prompt/sampler.py | 25 +++++++++---------------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/configs/default_config.yaml b/configs/default_config.yaml index 7a9863240..ab54d6a5e 100644 --- a/configs/default_config.yaml +++ b/configs/default_config.yaml @@ -63,6 +63,11 @@ prompt: - "I suggest the following improvements:" - "We can enhance this code by:" + # Artifact rendering + include_artifacts: true # Include execution outputs/errors in prompt + max_artifact_bytes: 20480 # Maximum artifact size in bytes (20KB default) + artifact_security_filter: true # Apply security filtering to artifacts + # Note: meta-prompting features are not yet implemented # Database configuration diff --git a/openevolve/process_parallel.py b/openevolve/process_parallel.py index 6e3b9255f..3dc98b62d 100644 --- a/openevolve/process_parallel.py +++ b/openevolve/process_parallel.py @@ -145,8 +145,9 @@ def _run_iteration_worker( reverse=True ) - island_top_programs = island_programs[:5] - island_previous_programs = island_programs[:3] + # Use config values for limits instead of hardcoding + island_top_programs = island_programs[:_worker_config.prompt.num_top_programs + _worker_config.prompt.num_diverse_programs] + island_previous_programs = island_programs[:_worker_config.prompt.num_top_programs] # Build prompt prompt = _worker_prompt_sampler.build_prompt( diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index af0d2eb04..65f15b3ec 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -309,11 +309,8 @@ def _format_evolution_history( selected_top = top_programs[: min(self.config.num_top_programs, len(top_programs))] for i, program in enumerate(selected_top): - # Extract a snippet (first 10 lines) for display + # Use the full program code program_code = program.get("code", "") - program_snippet = "\n".join(program_code.split("\n")[:10]) - if len(program_code.split("\n")) > 10: - program_snippet += "\n# ... (truncated for brevity)" # Calculate a composite score using safe numeric average score = safe_numeric_average(program.get("metrics", {})) @@ -338,7 +335,7 @@ def _format_evolution_history( program_number=i + 1, score=f"{score:.4f}", language=language, - program_snippet=program_snippet, + program_snippet=program_code, key_features=key_features_str, ) + "\n\n" @@ -362,11 +359,8 @@ def _format_evolution_history( diverse_programs_str += "\n\n## Diverse Programs\n\n" for i, program in enumerate(diverse_programs): - # Extract a snippet (first 5 lines for diversity) + # Use the full program code program_code = program.get("code", "") - program_snippet = "\n".join(program_code.split("\n")[:5]) - if len(program_code.split("\n")) > 5: - program_snippet += "\n# ... (truncated)" # Calculate a composite score using safe numeric average score = safe_numeric_average(program.get("metrics", {})) @@ -388,7 +382,7 @@ def _format_evolution_history( program_number=f"D{i + 1}", score=f"{score:.4f}", language=language, - program_snippet=program_snippet, + program_snippet=program_code, key_features=key_features_str, ) + "\n\n" @@ -430,11 +424,8 @@ def _format_inspirations_section( inspiration_programs_str = "" for i, program in enumerate(inspirations): - # Extract a snippet (first 8 lines) for display + # Use the full program code program_code = program.get("code", "") - program_snippet = "\n".join(program_code.split("\n")[:8]) - if len(program_code.split("\n")) > 8: - program_snippet += "\n# ... (truncated for brevity)" # Calculate a composite score using safe numeric average score = safe_numeric_average(program.get("metrics", {})) @@ -451,7 +442,7 @@ def _format_inspirations_section( score=f"{score:.4f}", program_type=program_type, language=language, - program_snippet=program_snippet, + program_snippet=program_code, unique_features=unique_features, ) + "\n\n" @@ -540,7 +531,9 @@ def _extract_unique_features(self, program: Dict[str, Any]) -> str: program_type = self._determine_program_type(program) features.append(f"{program_type} approach to the problem") - return ", ".join(features[:3]) # Limit to top 3 features + # Use num_top_programs as limit for features (similar to how we limit programs) + feature_limit = self.config.num_top_programs + return ", ".join(features[:feature_limit]) def _apply_template_variations(self, template: str) -> str: """Apply stochastic variations to the template""" From 3f2a57543d0c979c4f47f55e3f1f6f54225b5589 Mon Sep 17 00:00:00 2001 From: Asankhaya Sharma Date: Wed, 23 Jul 2025 07:50:27 +0800 Subject: [PATCH 2/2] Clarify artifact serialization limit in comments Expanded comments to explain the rationale for limiting artifact serialization to the first 100 programs, detailing the impact on memory usage and worker initialization speed. No functional changes were made. --- openevolve/process_parallel.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openevolve/process_parallel.py b/openevolve/process_parallel.py index 3dc98b62d..ec14aec92 100644 --- a/openevolve/process_parallel.py +++ b/openevolve/process_parallel.py @@ -343,7 +343,12 @@ def _create_database_snapshot(self) -> Dict[str, Any]: } # Include artifacts for programs that might be selected - # (limit to reduce serialization overhead) + # IMPORTANT: This limits artifacts (execution outputs/errors) to first 100 programs only. + # This does NOT affect program code - all programs are fully serialized above. + # With max_artifact_bytes=20KB and population_size=1000, artifacts could be 20MB total, + # which would significantly slow worker process initialization. The limit of 100 keeps + # artifact data under 2MB while still providing execution context for recent programs. + # Workers can still evolve properly as they have access to ALL program code. for pid in list(self.database.programs.keys())[:100]: artifacts = self.database.get_artifacts(pid) if artifacts: