Skip to content

Commit e2d089f

Browse files
committed
fix: Catch case where current_changes_description is None
1 parent 65cbbe8 commit e2d089f

File tree

1 file changed

+70
-30
lines changed

1 file changed

+70
-30
lines changed

openevolve/prompt/sampler.py

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,17 @@ def build_prompt(
110110

111111
if self.config.programs_as_changes_description:
112112
if self.config.system_message_changes_description:
113-
system_message_changes_description = self.config.system_message_changes_description.strip()
113+
system_message_changes_description = (
114+
self.config.system_message_changes_description.strip()
115+
)
114116
else:
115-
system_message_changes_description = self.template_manager.get_template("system_message_changes_description")
117+
system_message_changes_description = self.template_manager.get_template(
118+
"system_message_changes_description"
119+
)
116120

117-
system_message = self.template_manager.get_template("system_message_with_changes_description").format(
121+
system_message = self.template_manager.get_template(
122+
"system_message_with_changes_description"
123+
).format(
118124
system_message=system_message,
119125
system_message_changes_description=system_message_changes_description,
120126
)
@@ -160,8 +166,10 @@ def build_prompt(
160166
**kwargs,
161167
)
162168

163-
if self.config.programs_as_changes_description:
164-
user_message = self.template_manager.get_template("user_message_with_changes_description").format(
169+
if self.config.programs_as_changes_description and current_changes_description is not None:
170+
user_message = self.template_manager.get_template(
171+
"user_message_with_changes_description"
172+
).format(
165173
user_message=user_message,
166174
changes_description=current_changes_description.rstrip(),
167175
)
@@ -265,11 +273,8 @@ def _format_evolution_history(
265273

266274
for i, program in enumerate(reversed(selected_previous)):
267275
attempt_number = len(previous_programs) - i
268-
changes = (
269-
program.get("changes_description")
270-
or program.get("metadata", {}).get(
271-
"changes", self.template_manager.get_fragment("attempt_unknown_changes")
272-
)
276+
changes = program.get("changes_description") or program.get("metadata", {}).get(
277+
"changes", self.template_manager.get_fragment("attempt_unknown_changes")
273278
)
274279

275280
# Format performance metrics using safe formatting
@@ -334,9 +339,7 @@ def _format_evolution_history(
334339
for i, program in enumerate(selected_top):
335340
use_changes = self.config.programs_as_changes_description
336341
program_code = (
337-
program.get("changes_description", "")
338-
if use_changes
339-
else program.get("code", "")
342+
program.get("changes_description", "") if use_changes else program.get("code", "")
340343
)
341344
if not program_code:
342345
program_code = "<missing changes_description>" if use_changes else ""
@@ -351,11 +354,20 @@ def _format_evolution_history(
351354
for name, value in program.get("metrics", {}).items():
352355
if isinstance(value, (int, float)):
353356
try:
354-
key_features.append(self.template_manager.get_fragment("top_program_metrics_prefix") + f" {name} ({value:.4f})")
357+
key_features.append(
358+
self.template_manager.get_fragment("top_program_metrics_prefix")
359+
+ f" {name} ({value:.4f})"
360+
)
355361
except (ValueError, TypeError):
356-
key_features.append(self.template_manager.get_fragment("top_program_metrics_prefix") + f" {name} ({value})")
362+
key_features.append(
363+
self.template_manager.get_fragment("top_program_metrics_prefix")
364+
+ f" {name} ({value})"
365+
)
357366
else:
358-
key_features.append(self.template_manager.get_fragment("top_program_metrics_prefix") + f" {name} ({value})")
367+
key_features.append(
368+
self.template_manager.get_fragment("top_program_metrics_prefix")
369+
+ f" {name} ({value})"
370+
)
359371

360372
key_features_str = ", ".join(key_features)
361373

@@ -385,7 +397,11 @@ def _format_evolution_history(
385397
# Use random sampling to get diverse programs
386398
diverse_programs = random.sample(remaining_programs, num_diverse)
387399

388-
diverse_programs_str += "\n\n## " + self.template_manager.get_fragment("diverse_programs_title") + "\n\n"
400+
diverse_programs_str += (
401+
"\n\n## "
402+
+ self.template_manager.get_fragment("diverse_programs_title")
403+
+ "\n\n"
404+
)
389405

390406
for i, program in enumerate(diverse_programs):
391407
use_changes = self.config.programs_as_changes_description
@@ -404,7 +420,8 @@ def _format_evolution_history(
404420
key_features = program.get("key_features", [])
405421
if not key_features:
406422
key_features = [
407-
self.template_manager.get_fragment("diverse_program_metrics_prefix") + f" {name}"
423+
self.template_manager.get_fragment("diverse_program_metrics_prefix")
424+
+ f" {name}"
408425
for name in list(program.get("metrics", {}).keys())[
409426
:2
410427
] # Just first 2 metrics
@@ -416,7 +433,9 @@ def _format_evolution_history(
416433
top_program_template.format(
417434
program_number=f"D{i + 1}",
418435
score=f"{score:.4f}",
419-
language=("text" if self.config.programs_as_changes_description else language),
436+
language=(
437+
"text" if self.config.programs_as_changes_description else language
438+
),
420439
program_snippet=program_code,
421440
key_features=key_features_str,
422441
)
@@ -466,9 +485,7 @@ def _format_inspirations_section(
466485
for i, program in enumerate(inspirations):
467486
use_changes = self.config.programs_as_changes_description
468487
program_code = (
469-
program.get("changes_description", "")
470-
if use_changes
471-
else program.get("code", "")
488+
program.get("changes_description", "") if use_changes else program.get("code", "")
472489
)
473490
if not program_code:
474491
program_code = "<missing changes_description>" if use_changes else ""
@@ -551,16 +568,24 @@ def _extract_unique_features(self, program: Dict[str, Any]) -> str:
551568
and self.config.include_changes_under_chars
552569
and len(changes) < self.config.include_changes_under_chars
553570
):
554-
features.append(self.template_manager.get_fragment("inspiration_changes_prefix").format(changes=changes))
571+
features.append(
572+
self.template_manager.get_fragment("inspiration_changes_prefix").format(
573+
changes=changes
574+
)
575+
)
555576

556577
# Analyze metrics for standout characteristics
557578
metrics = program.get("metrics", {})
558579
for metric_name, value in metrics.items():
559580
if isinstance(value, (int, float)):
560581
if value >= 0.9:
561-
features.append(f"{self.template_manager.get_fragment('inspiration_metrics_excellent').format(metric_name=metric_name, value=value)}")
582+
features.append(
583+
f"{self.template_manager.get_fragment('inspiration_metrics_excellent').format(metric_name=metric_name, value=value)}"
584+
)
562585
elif value <= 0.3:
563-
features.append(f"{self.template_manager.get_fragment('inspiration_metrics_alternative').format(metric_name=metric_name)}")
586+
features.append(
587+
f"{self.template_manager.get_fragment('inspiration_metrics_alternative').format(metric_name=metric_name)}"
588+
)
564589

565590
# Code-based features (simple heuristics)
566591
code = program.get("code", "")
@@ -571,22 +596,32 @@ def _extract_unique_features(self, program: Dict[str, Any]) -> str:
571596
if "numpy" in code_lower or "np." in code_lower:
572597
features.append(self.template_manager.get_fragment("inspiration_code_with_numpy"))
573598
if "for" in code_lower and "while" in code_lower:
574-
features.append(self.template_manager.get_fragment("inspiration_code_with_mixed_iteration"))
599+
features.append(
600+
self.template_manager.get_fragment("inspiration_code_with_mixed_iteration")
601+
)
575602
if (
576603
self.config.concise_implementation_max_lines
577604
and len(code.split("\n")) <= self.config.concise_implementation_max_lines
578605
):
579-
features.append(self.template_manager.get_fragment("inspiration_code_with_concise_line"))
606+
features.append(
607+
self.template_manager.get_fragment("inspiration_code_with_concise_line")
608+
)
580609
elif (
581610
self.config.comprehensive_implementation_min_lines
582611
and len(code.split("\n")) >= self.config.comprehensive_implementation_min_lines
583612
):
584-
features.append(self.template_manager.get_fragment("inspiration_code_with_comprehensive_line"))
613+
features.append(
614+
self.template_manager.get_fragment("inspiration_code_with_comprehensive_line")
615+
)
585616

586617
# Default if no specific features found
587618
if not features:
588619
program_type = self._determine_program_type(program)
589-
features.append(self.template_manager.get_fragment("inspiration_no_features_postfix").format(program_type=program_type))
620+
features.append(
621+
self.template_manager.get_fragment("inspiration_no_features_postfix").format(
622+
program_type=program_type
623+
)
624+
)
590625

591626
# Use num_top_programs as limit for features (similar to how we limit programs)
592627
feature_limit = self.config.num_top_programs
@@ -629,7 +664,12 @@ def _render_artifacts(self, artifacts: Dict[str, Union[str, bytes]]) -> str:
629664
sections.append(f"### {key}\n```\n{content}\n```")
630665

631666
if sections:
632-
return "## " + self.template_manager.get_fragment("artifact_title") + "\n\n" + "\n\n".join(sections)
667+
return (
668+
"## "
669+
+ self.template_manager.get_fragment("artifact_title")
670+
+ "\n\n"
671+
+ "\n\n".join(sections)
672+
)
633673
else:
634674
return ""
635675

0 commit comments

Comments
 (0)