From d06167028521847b3e56f4b7c48ee51d9c3396d8 Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sat, 20 Dec 2025 21:58:43 +0800 Subject: [PATCH 1/8] feat: template no_feature_coordinates --- openevolve/prompt/sampler.py | 6 ++++-- openevolve/prompts/defaults/fragments.json | 3 ++- openevolve/utils/metrics_utils.py | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index f0c05cd0e..768f74dad 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -205,11 +205,13 @@ def _identify_improvement_areas( # Note feature exploration (not good/bad, just informational) if feature_dimensions: feature_coords = format_feature_coordinates(metrics, feature_dimensions) - if feature_coords != "No feature coordinates": + if feature_coords == "": + msg = self.template_manager.get_fragment("no_feature_coordinates") + else: msg = self.template_manager.get_fragment( "exploring_region", features=feature_coords ) - improvement_areas.append(msg) + improvement_areas.append(msg) # Code length check (configurable threshold) threshold = ( diff --git a/openevolve/prompts/defaults/fragments.json b/openevolve/prompts/defaults/fragments.json index 47b6bb4b1..dba144f24 100644 --- a/openevolve/prompts/defaults/fragments.json +++ b/openevolve/prompts/defaults/fragments.json @@ -14,5 +14,6 @@ "metrics_improved": "Metrics showing improvement: {metrics}. Consider continuing with similar approaches.", "metrics_regressed": "Metrics showing changes: {metrics}. Consider different approaches in these areas.", "code_simplification": "Consider simplifying the code to improve readability and maintainability", - "default_improvement": "Focus on improving the fitness score while exploring diverse solutions" + "default_improvement": "Focus on improving the fitness score while exploring diverse solutions", + "no_feature_coordinates": "No feature coordinates" } \ No newline at end of file diff --git a/openevolve/utils/metrics_utils.py b/openevolve/utils/metrics_utils.py index 3ea0ffa23..3efd18e25 100644 --- a/openevolve/utils/metrics_utils.py +++ b/openevolve/utils/metrics_utils.py @@ -139,7 +139,7 @@ def format_feature_coordinates(metrics: Dict[str, Any], feature_dimensions: List else: feature_values.append(f"{dim}={value}") - if not feature_values: - return "No feature coordinates" + if not feature_values: # No valid feature coordinates found will return empty string + return "" return ", ".join(feature_values) From 7711dd691f1ecda1668e94117fbf6cb5aa8aeaf5 Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sat, 20 Dec 2025 22:13:10 +0800 Subject: [PATCH 2/8] feat: template aritifact and diverse program title --- openevolve/prompt/sampler.py | 4 ++-- openevolve/prompts/defaults/fragments.json | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index 768f74dad..f76f2a92f 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -356,7 +356,7 @@ def _format_evolution_history( # Use random sampling to get diverse programs diverse_programs = random.sample(remaining_programs, num_diverse) - diverse_programs_str += "\n\n## Diverse Programs\n\n" + diverse_programs_str += "\n\n## " + self.template_manager.get_fragment("diverse_programs_title") + "\n\n" for i, program in enumerate(diverse_programs): # Use the full program code @@ -589,7 +589,7 @@ def _render_artifacts(self, artifacts: Dict[str, Union[str, bytes]]) -> str: sections.append(f"### {key}\n```\n{content}\n```") if sections: - return "## Last Execution Output\n\n" + "\n\n".join(sections) + return "## " + self.template_manager.get_fragment("artifact_title") + "\n\n" + "\n\n".join(sections) else: return "" diff --git a/openevolve/prompts/defaults/fragments.json b/openevolve/prompts/defaults/fragments.json index dba144f24..618fe1f01 100644 --- a/openevolve/prompts/defaults/fragments.json +++ b/openevolve/prompts/defaults/fragments.json @@ -15,5 +15,7 @@ "metrics_regressed": "Metrics showing changes: {metrics}. Consider different approaches in these areas.", "code_simplification": "Consider simplifying the code to improve readability and maintainability", "default_improvement": "Focus on improving the fitness score while exploring diverse solutions", - "no_feature_coordinates": "No feature coordinates" + "no_feature_coordinates": "No feature coordinates", + "artifact_title": "Last Execution Output", + "diverse_programs_title": "Diverse Programs" } \ No newline at end of file From c05bd7abdbe30b3c0103f2522365bf8826b8f606 Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sat, 20 Dec 2025 22:19:35 +0800 Subject: [PATCH 3/8] feat: template attempt metrics result compare hint --- openevolve/prompt/sampler.py | 6 +++--- openevolve/prompts/defaults/fragments.json | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index f76f2a92f..cfe6076d2 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -263,7 +263,7 @@ def _format_evolution_history( # Determine outcome based on comparison with parent (only numeric metrics) parent_metrics = program.get("metadata", {}).get("parent_metrics", {}) - outcome = "Mixed results" + outcome = self.template_manager.get_fragment("attempt_mixed_metrics") # Safely compare only numeric metrics program_metrics = program.get("metrics", {}) @@ -290,9 +290,9 @@ def _format_evolution_history( # Determine outcome based on numeric comparisons if numeric_comparisons_improved and all(numeric_comparisons_improved): - outcome = "Improvement in all metrics" + outcome = self.template_manager.get_fragment("attempt_all_metrics_improved") elif numeric_comparisons_regressed and all(numeric_comparisons_regressed): - outcome = "Regression in all metrics" + outcome = self.template_manager.get_fragment("attempt_all_metrics_regressed") previous_attempts_str += ( previous_attempt_template.format( diff --git a/openevolve/prompts/defaults/fragments.json b/openevolve/prompts/defaults/fragments.json index 618fe1f01..890c66a01 100644 --- a/openevolve/prompts/defaults/fragments.json +++ b/openevolve/prompts/defaults/fragments.json @@ -17,5 +17,8 @@ "default_improvement": "Focus on improving the fitness score while exploring diverse solutions", "no_feature_coordinates": "No feature coordinates", "artifact_title": "Last Execution Output", - "diverse_programs_title": "Diverse Programs" + "diverse_programs_title": "Diverse Programs", + "attempt_all_metrics_improved": "Improvement in all metrics", + "attempt_all_metrics_regressed": "Regression in all metrics", + "attempt_mixed_metrics": "Mixed results" } \ No newline at end of file From ade1165e9ca32ee943d6807b1d30aef3cebf74ee Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sat, 20 Dec 2025 22:29:17 +0800 Subject: [PATCH 4/8] feat: template top and diverse program metrics prefix --- openevolve/prompt/sampler.py | 8 ++++---- openevolve/prompts/defaults/fragments.json | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index cfe6076d2..408f9cf50 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -322,11 +322,11 @@ def _format_evolution_history( for name, value in program.get("metrics", {}).items(): if isinstance(value, (int, float)): try: - key_features.append(f"Performs well on {name} ({value:.4f})") + key_features.append(self.template_manager.get_fragment("top_program_metrics_prefix") + f" {name} ({value:.4f})") except (ValueError, TypeError): - key_features.append(f"Performs well on {name} ({value})") + key_features.append(self.template_manager.get_fragment("top_program_metrics_prefix") + f" {name} ({value})") else: - key_features.append(f"Performs well on {name} ({value})") + key_features.append(self.template_manager.get_fragment("top_program_metrics_prefix") + f" {name} ({value})") key_features_str = ", ".join(key_features) @@ -369,7 +369,7 @@ def _format_evolution_history( key_features = program.get("key_features", []) if not key_features: key_features = [ - f"Alternative approach to {name}" + self.template_manager.get_fragment("diverse_program_metrics_prefix") + f" {name}" for name in list(program.get("metrics", {}).keys())[ :2 ] # Just first 2 metrics diff --git a/openevolve/prompts/defaults/fragments.json b/openevolve/prompts/defaults/fragments.json index 890c66a01..3b895cd3c 100644 --- a/openevolve/prompts/defaults/fragments.json +++ b/openevolve/prompts/defaults/fragments.json @@ -20,5 +20,7 @@ "diverse_programs_title": "Diverse Programs", "attempt_all_metrics_improved": "Improvement in all metrics", "attempt_all_metrics_regressed": "Regression in all metrics", - "attempt_mixed_metrics": "Mixed results" + "attempt_mixed_metrics": "Mixed results", + "top_program_metrics_prefix": "Performs well on", + "diverse_program_metrics_prefix": "Alternative approach to" } \ No newline at end of file From 58fc6cb40ed03440cd662912eb7978e1d57d06e5 Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sat, 20 Dec 2025 22:37:00 +0800 Subject: [PATCH 5/8] feat: template inspiration program type --- openevolve/prompt/sampler.py | 15 +++++++-------- openevolve/prompts/defaults/fragments.json | 9 ++++++++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index 408f9cf50..e13f6a76f 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -474,21 +474,20 @@ def _determine_program_type( # Check metadata for explicit type markers if metadata.get("diverse", False): - return "Diverse" + return self.template_manager.get_fragment("inspiration_type_diverse") if metadata.get("migrant", False): - return "Migrant" + return self.template_manager.get_fragment("inspiration_type_migrant") if metadata.get("random", False): - return "Random" - + return self.template_manager.get_fragment("inspiration_type_random") # Classify based on score ranges if score >= 0.8: - return "High-Performer" + return self.template_manager.get_fragment("inspiration_type_score_high_performer") elif score >= 0.6: - return "Alternative" + return self.template_manager.get_fragment("inspiration_type_score_alternative") elif score >= 0.4: - return "Experimental" + return self.template_manager.get_fragment("inspiration_type_score_experimental") else: - return "Exploratory" + return self.template_manager.get_fragment("inspiration_type_score_exploratory") def _extract_unique_features(self, program: Dict[str, Any]) -> str: """ diff --git a/openevolve/prompts/defaults/fragments.json b/openevolve/prompts/defaults/fragments.json index 3b895cd3c..9a797f4ff 100644 --- a/openevolve/prompts/defaults/fragments.json +++ b/openevolve/prompts/defaults/fragments.json @@ -22,5 +22,12 @@ "attempt_all_metrics_regressed": "Regression in all metrics", "attempt_mixed_metrics": "Mixed results", "top_program_metrics_prefix": "Performs well on", - "diverse_program_metrics_prefix": "Alternative approach to" + "diverse_program_metrics_prefix": "Alternative approach to", + "inspiration_type_diverse": "Diverse", + "inspiration_type_migrant": "Migrant", + "inspiration_type_random": "Random", + "inspiration_type_score_high_performer": "High-Performer", + "inspiration_type_score_alternative": "Alternative", + "inspiration_type_score_experimental": "Experimental", + "inspiration_type_score_exploratory": "Exploratory" } \ No newline at end of file From 3187e67b6e7e68baa20676d733577e7816c76b39 Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sat, 20 Dec 2025 22:58:18 +0800 Subject: [PATCH 6/8] feat: template inspiration code content and feature --- openevolve/prompt/sampler.py | 18 +++++++++--------- openevolve/prompts/defaults/fragments.json | 11 ++++++++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index e13f6a76f..71447fb1d 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -510,42 +510,42 @@ def _extract_unique_features(self, program: Dict[str, Any]) -> str: and self.config.include_changes_under_chars and len(changes) < self.config.include_changes_under_chars ): - features.append(f"Modification: {changes}") + features.append(self.template_manager.get_fragment("inspiration_changes_prefix").format(changes=changes)) # Analyze metrics for standout characteristics metrics = program.get("metrics", {}) for metric_name, value in metrics.items(): if isinstance(value, (int, float)): if value >= 0.9: - features.append(f"Excellent {metric_name} ({value:.3f})") + features.append(f"{self.template_manager.get_fragment('inspiration_metrics_excellent').format(metric_name=metric_name, value=value)}") elif value <= 0.3: - features.append(f"Alternative {metric_name} approach") + features.append(f"{self.template_manager.get_fragment('inspiration_metrics_alternative').format(metric_name=metric_name)}") # Code-based features (simple heuristics) code = program.get("code", "") if code: code_lower = code.lower() if "class" in code_lower and "def __init__" in code_lower: - features.append("Object-oriented approach") + features.append(self.template_manager.get_fragment("inspiration_code_with_class")) if "numpy" in code_lower or "np." in code_lower: - features.append("NumPy-based implementation") + features.append(self.template_manager.get_fragment("inspiration_code_with_numpy")) if "for" in code_lower and "while" in code_lower: - features.append("Mixed iteration strategies") + features.append(self.template_manager.get_fragment("inspiration_code_with_mixed_iteration")) if ( self.config.concise_implementation_max_lines and len(code.split("\n")) <= self.config.concise_implementation_max_lines ): - features.append("Concise implementation") + features.append(self.template_manager.get_fragment("inspiration_code_with_concise_line")) elif ( self.config.comprehensive_implementation_min_lines and len(code.split("\n")) >= self.config.comprehensive_implementation_min_lines ): - features.append("Comprehensive implementation") + features.append(self.template_manager.get_fragment("inspiration_code_with_comprehensive_line")) # Default if no specific features found if not features: program_type = self._determine_program_type(program) - features.append(f"{program_type} approach to the problem") + features.append(self.template_manager.get_fragment("inspiration_no_features_postfix").format(program_type=program_type)) # Use num_top_programs as limit for features (similar to how we limit programs) feature_limit = self.config.num_top_programs diff --git a/openevolve/prompts/defaults/fragments.json b/openevolve/prompts/defaults/fragments.json index 9a797f4ff..39f2fa6ad 100644 --- a/openevolve/prompts/defaults/fragments.json +++ b/openevolve/prompts/defaults/fragments.json @@ -29,5 +29,14 @@ "inspiration_type_score_high_performer": "High-Performer", "inspiration_type_score_alternative": "Alternative", "inspiration_type_score_experimental": "Experimental", - "inspiration_type_score_exploratory": "Exploratory" + "inspiration_type_score_exploratory": "Exploratory", + "inspiration_changes_prefix": "Modification:", + "inspiration_metrics_excellent": "Excellent {metric_name} ({value:.3f})", + "inspiration_metrics_alternative": "Alternative {metric_name} approach", + "inspiration_code_with_class": "Object-oriented approach", + "inspiration_code_with_numpy": "NumPy-based implementation", + "inspiration_code_with_mixed_iteration": "Mixed iteration strategies", + "inspiration_code_with_concise_line": "Concise implementation", + "inspiration_code_with_comprehensive_line": "Comprehensive implementation", + "inspiration_no_features_postfix": "approach to the problem" } \ No newline at end of file From ff7c7f1c44dc915ca3f8b7ebc64002eaf4834fe8 Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sat, 20 Dec 2025 23:34:22 +0800 Subject: [PATCH 7/8] feat: template attempt unknown changes --- openevolve/prompt/sampler.py | 2 +- openevolve/prompts/defaults/fragments.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index 71447fb1d..a2294b337 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -247,7 +247,7 @@ def _format_evolution_history( for i, program in enumerate(reversed(selected_previous)): attempt_number = len(previous_programs) - i - changes = program.get("metadata", {}).get("changes", "Unknown changes") + changes = program.get("metadata", {}).get("changes", self.template_manager.get_fragment("attempt_no_changes")) # Format performance metrics using safe formatting performance_parts = [] diff --git a/openevolve/prompts/defaults/fragments.json b/openevolve/prompts/defaults/fragments.json index 39f2fa6ad..b59410405 100644 --- a/openevolve/prompts/defaults/fragments.json +++ b/openevolve/prompts/defaults/fragments.json @@ -18,6 +18,7 @@ "no_feature_coordinates": "No feature coordinates", "artifact_title": "Last Execution Output", "diverse_programs_title": "Diverse Programs", + "attempt_unknown_changes": "Unknown changes", "attempt_all_metrics_improved": "Improvement in all metrics", "attempt_all_metrics_regressed": "Regression in all metrics", "attempt_mixed_metrics": "Mixed results", From 88a50e6001fa1e9bb5bc8d1cdb80a21348d3a3dd Mon Sep 17 00:00:00 2001 From: fun_melon Date: Sun, 21 Dec 2025 00:02:35 +0800 Subject: [PATCH 8/8] fix the wrong fragment name in sampler --- openevolve/prompt/sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openevolve/prompt/sampler.py b/openevolve/prompt/sampler.py index a2294b337..8f6a6a57a 100644 --- a/openevolve/prompt/sampler.py +++ b/openevolve/prompt/sampler.py @@ -247,7 +247,7 @@ def _format_evolution_history( for i, program in enumerate(reversed(selected_previous)): attempt_number = len(previous_programs) - i - changes = program.get("metadata", {}).get("changes", self.template_manager.get_fragment("attempt_no_changes")) + changes = program.get("metadata", {}).get("changes", self.template_manager.get_fragment("attempt_unknown_changes")) # Format performance metrics using safe formatting performance_parts = []