levi-evolve 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- levi/__init__.py +124 -0
- levi/artifacts/__init__.py +7 -0
- levi/artifacts/base.py +80 -0
- levi/artifacts/code.py +231 -0
- levi/artifacts/prompt.py +609 -0
- levi/behavior/__init__.py +8 -0
- levi/behavior/extractor.py +215 -0
- levi/behavior/features.py +139 -0
- levi/clients/__init__.py +14 -0
- levi/clients/_cli_common.py +31 -0
- levi/clients/base.py +45 -0
- levi/clients/claude_code.py +122 -0
- levi/clients/codex.py +135 -0
- levi/clients/lm.py +225 -0
- levi/config/__init__.py +35 -0
- levi/config/models.py +260 -0
- levi/core/__init__.py +12 -0
- levi/core/evaluation.py +31 -0
- levi/core/program.py +25 -0
- levi/core/types.py +11 -0
- levi/demos/__init__.py +15 -0
- levi/demos/aime.py +121 -0
- levi/demos/circle_packing.py +119 -0
- levi/equilibrium/__init__.py +11 -0
- levi/equilibrium/equilibrium.py +511 -0
- levi/equilibrium/prompts.py +187 -0
- levi/init/__init__.py +6 -0
- levi/init/diversifier.py +888 -0
- levi/init/proxy_benchmark.py +223 -0
- levi/methods/__init__.py +9 -0
- levi/methods/levi.py +568 -0
- levi/pipeline/__init__.py +16 -0
- levi/pipeline/consumer.py +300 -0
- levi/pipeline/producer.py +157 -0
- levi/pipeline/runner.py +432 -0
- levi/pipeline/state.py +553 -0
- levi/pool/__init__.py +10 -0
- levi/pool/cvt_map_elites.py +772 -0
- levi/pool/protocol.py +72 -0
- levi/prompt_opt/__init__.py +5 -0
- levi/prompt_opt/optimizer.py +597 -0
- levi/prompts/__init__.py +19 -0
- levi/prompts/builder.py +155 -0
- levi/prompts/bundle.py +188 -0
- levi/selection/__init__.py +17 -0
- levi/selection/component.py +242 -0
- levi/utils/__init__.py +19 -0
- levi/utils/code_extraction.py +73 -0
- levi/utils/evaluation.py +161 -0
- levi/utils/ids.py +8 -0
- levi/utils/preflight.py +77 -0
- levi/utils/resilient_pool.py +165 -0
- levi_evolve-0.1.0.dist-info/METADATA +203 -0
- levi_evolve-0.1.0.dist-info/RECORD +56 -0
- levi_evolve-0.1.0.dist-info/WHEEL +4 -0
- levi_evolve-0.1.0.dist-info/licenses/LICENSE +21 -0
levi/__init__.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Levi: Evolutionary optimization framework for algorithms.
|
|
3
|
+
|
|
4
|
+
Simple usage::
|
|
5
|
+
|
|
6
|
+
import levi
|
|
7
|
+
|
|
8
|
+
result = levi.evolve_code(
|
|
9
|
+
"Optimize bin packing to minimize wasted space",
|
|
10
|
+
function_signature="def pack(items, bin_capacity):",
|
|
11
|
+
seed_program="def pack(items, bin_capacity): ...",
|
|
12
|
+
score_fn=my_scorer,
|
|
13
|
+
model="openai/gpt-4o-mini",
|
|
14
|
+
budget_dollars=5.0,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
Power users can pass any LeviConfig field as a keyword argument::
|
|
18
|
+
|
|
19
|
+
result = levi.evolve_code(
|
|
20
|
+
...,
|
|
21
|
+
paradigm_model="openai/gpt-4o",
|
|
22
|
+
mutation_model="openai/gpt-4o-mini",
|
|
23
|
+
budget_dollars=10.0,
|
|
24
|
+
punctuated_equilibrium=levi.PunctuatedEquilibriumConfig(enabled=True),
|
|
25
|
+
pipeline=levi.PipelineConfig(n_llm_workers=8),
|
|
26
|
+
)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Core types
|
|
30
|
+
# Behavior
|
|
31
|
+
from .behavior import BehaviorExtractor, FeatureVector
|
|
32
|
+
from .clients import LM, BaseClient, ClaudeCodeClient, ClientResult, CodexClient
|
|
33
|
+
|
|
34
|
+
# Config types
|
|
35
|
+
from .config import (
|
|
36
|
+
BehaviorConfig,
|
|
37
|
+
BudgetConfig,
|
|
38
|
+
CascadeConfig,
|
|
39
|
+
CVTConfig,
|
|
40
|
+
InitConfig,
|
|
41
|
+
LeviConfig,
|
|
42
|
+
LeviResult,
|
|
43
|
+
MetaAdviceConfig,
|
|
44
|
+
PipelineConfig,
|
|
45
|
+
PromptOptConfig,
|
|
46
|
+
ProxyBenchmarkConfig,
|
|
47
|
+
PunctuatedEquilibriumConfig,
|
|
48
|
+
SamplerModelPair,
|
|
49
|
+
)
|
|
50
|
+
from .core import EvaluationResult, MetricDict, Program
|
|
51
|
+
|
|
52
|
+
# Methods
|
|
53
|
+
from .methods import evolve_code, evolve_prompts
|
|
54
|
+
|
|
55
|
+
# Protocols and pools
|
|
56
|
+
from .pool import CVTMAPElitesPool, ProgramPool, SampleResult
|
|
57
|
+
|
|
58
|
+
# Prompts
|
|
59
|
+
from .prompts import (
|
|
60
|
+
OutputMode,
|
|
61
|
+
ProgramWithScore,
|
|
62
|
+
PromptBuilder,
|
|
63
|
+
PromptBundle,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Selection
|
|
67
|
+
from .selection import (
|
|
68
|
+
ComponentSelector,
|
|
69
|
+
RoundRobinComponentSelector,
|
|
70
|
+
StagnationComponentSelector,
|
|
71
|
+
UCBComponentSelector,
|
|
72
|
+
make_component_selector,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
__version__ = "0.1.0"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
__all__ = [
|
|
79
|
+
# Core
|
|
80
|
+
"Program",
|
|
81
|
+
"EvaluationResult",
|
|
82
|
+
"MetricDict",
|
|
83
|
+
# Pool
|
|
84
|
+
"ProgramPool",
|
|
85
|
+
"SampleResult",
|
|
86
|
+
"CVTMAPElitesPool",
|
|
87
|
+
# Clients
|
|
88
|
+
"BaseClient",
|
|
89
|
+
"LM",
|
|
90
|
+
"ClientResult",
|
|
91
|
+
"CodexClient",
|
|
92
|
+
"ClaudeCodeClient",
|
|
93
|
+
# Prompts
|
|
94
|
+
"PromptBuilder",
|
|
95
|
+
"ProgramWithScore",
|
|
96
|
+
"OutputMode",
|
|
97
|
+
"PromptBundle",
|
|
98
|
+
# Selection
|
|
99
|
+
"ComponentSelector",
|
|
100
|
+
"UCBComponentSelector",
|
|
101
|
+
"RoundRobinComponentSelector",
|
|
102
|
+
"StagnationComponentSelector",
|
|
103
|
+
"make_component_selector",
|
|
104
|
+
# Behavior
|
|
105
|
+
"BehaviorExtractor",
|
|
106
|
+
"FeatureVector",
|
|
107
|
+
# Config types
|
|
108
|
+
"LeviConfig",
|
|
109
|
+
"LeviResult",
|
|
110
|
+
"BudgetConfig",
|
|
111
|
+
"SamplerModelPair",
|
|
112
|
+
"CVTConfig",
|
|
113
|
+
"InitConfig",
|
|
114
|
+
"MetaAdviceConfig",
|
|
115
|
+
"BehaviorConfig",
|
|
116
|
+
"CascadeConfig",
|
|
117
|
+
"PipelineConfig",
|
|
118
|
+
"PunctuatedEquilibriumConfig",
|
|
119
|
+
"PromptOptConfig",
|
|
120
|
+
"ProxyBenchmarkConfig",
|
|
121
|
+
# Methods
|
|
122
|
+
"evolve_code",
|
|
123
|
+
"evolve_prompts",
|
|
124
|
+
]
|
levi/artifacts/base.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Internal artifact adapter abstractions for Levi."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from collections.abc import Mapping, Sequence
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from ..clients.base import ClientSpec
|
|
10
|
+
from ..core import Program
|
|
11
|
+
from ..prompts import ProgramWithScore
|
|
12
|
+
from ..utils import ResilientProcessPool
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ArtifactAdapter(ABC):
|
|
16
|
+
"""Internal boundary between the generic engine and an artifact domain."""
|
|
17
|
+
|
|
18
|
+
artifact_type: str = "artifact"
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def make_program(self, content: str, metadata: dict[str, Any] | None = None) -> Program:
|
|
22
|
+
"""Wrap raw artifact content into a Program."""
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def snapshot_content(self, elite_data: Mapping[str, Any]) -> str:
|
|
26
|
+
"""Extract canonical content from a serialized snapshot entry."""
|
|
27
|
+
|
|
28
|
+
@abstractmethod
|
|
29
|
+
async def evaluate(
|
|
30
|
+
self,
|
|
31
|
+
executor: ResilientProcessPool,
|
|
32
|
+
content: str,
|
|
33
|
+
*,
|
|
34
|
+
inputs: list[Any] | None = None,
|
|
35
|
+
timeout: float | None = None,
|
|
36
|
+
) -> dict[str, Any]:
|
|
37
|
+
"""Evaluate artifact content with the domain-specific harness."""
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def build_mutation_prompt(
|
|
41
|
+
self,
|
|
42
|
+
parents: Sequence[ProgramWithScore],
|
|
43
|
+
*,
|
|
44
|
+
meta_advice: str | None = None,
|
|
45
|
+
model: ClientSpec | None = None,
|
|
46
|
+
use_diff: bool = False,
|
|
47
|
+
) -> str:
|
|
48
|
+
"""Build the main mutation prompt for the producer pipeline."""
|
|
49
|
+
|
|
50
|
+
@abstractmethod
|
|
51
|
+
def extract_candidate(
|
|
52
|
+
self,
|
|
53
|
+
response_text: str,
|
|
54
|
+
*,
|
|
55
|
+
parent_content: str | None = None,
|
|
56
|
+
use_diff: bool = False,
|
|
57
|
+
) -> str | None:
|
|
58
|
+
"""Extract candidate content from a model response."""
|
|
59
|
+
|
|
60
|
+
@abstractmethod
|
|
61
|
+
def build_diversity_prompt(self, existing_candidates: Sequence[tuple[str, float]]) -> str:
|
|
62
|
+
"""Build the init-phase diversity prompt."""
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def build_init_variant_prompt(self, parents: Sequence[ProgramWithScore]) -> str:
|
|
66
|
+
"""Build the init-phase local-variation prompt."""
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def build_paradigm_shift_prompt(
|
|
70
|
+
self,
|
|
71
|
+
representatives: Sequence[tuple[int, Any]],
|
|
72
|
+
*,
|
|
73
|
+
n_evaluations: int,
|
|
74
|
+
budget_progress: float = 0.0,
|
|
75
|
+
) -> str:
|
|
76
|
+
"""Build the punctuated-equilibrium paradigm prompt."""
|
|
77
|
+
|
|
78
|
+
@abstractmethod
|
|
79
|
+
def build_variant_prompt(self, base_content: str, base_score: float) -> str:
|
|
80
|
+
"""Build a local-variation prompt around a paradigm-shift result."""
|
levi/artifacts/code.py
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"""Code artifact adapter for Levi's existing public API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from collections.abc import Mapping, Sequence
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from ..clients.base import ClientSpec, client_name
|
|
10
|
+
from ..config import LeviConfig
|
|
11
|
+
from ..core import Program
|
|
12
|
+
from ..equilibrium.prompts import PARADIGM_SHIFT_PROMPTS, VARIANT_GENERATION_PROMPT, get_budget_stage
|
|
13
|
+
from ..prompts import OutputMode, ProgramWithScore, PromptBuilder
|
|
14
|
+
from ..utils import ResilientProcessPool, evaluate_code, extract_code, extract_fn_name
|
|
15
|
+
from .base import ArtifactAdapter
|
|
16
|
+
|
|
17
|
+
DIVERSITY_SEED_PROMPT = """# {problem_title}
|
|
18
|
+
|
|
19
|
+
## Problem
|
|
20
|
+
{problem_description}
|
|
21
|
+
|
|
22
|
+
## Function Signature
|
|
23
|
+
```python
|
|
24
|
+
{function_signature}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Your Task: ALGORITHMIC DIVERSITY
|
|
28
|
+
|
|
29
|
+
You MUST design a solution using a **FUNDAMENTALLY DIFFERENT ALGORITHM** than the existing seeds.
|
|
30
|
+
|
|
31
|
+
**DO NOT:**
|
|
32
|
+
- Make minor variations or parameter tweaks to existing approaches
|
|
33
|
+
- Use the same core algorithm with different constants
|
|
34
|
+
- Reorder or refactor existing logic
|
|
35
|
+
|
|
36
|
+
**DO:**
|
|
37
|
+
- Analyze what algorithmic paradigm each existing seed uses
|
|
38
|
+
- Identify what aspects of the problem they exploit (or ignore)
|
|
39
|
+
- Design from first principles using a completely different strategy
|
|
40
|
+
- Think about what information in the problem they are NOT using
|
|
41
|
+
- Consider entirely different ways to model or decompose the problem
|
|
42
|
+
|
|
43
|
+
The goal is to explore different regions of the algorithm design space. A population of diverse algorithms will outperform a population of similar ones.
|
|
44
|
+
|
|
45
|
+
## Existing Seeds (analyze their algorithms, then do something DIFFERENT):
|
|
46
|
+
{existing_seeds}
|
|
47
|
+
|
|
48
|
+
## Output
|
|
49
|
+
Output ONLY the complete Python code in a ```python block.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def apply_diff(original: str, diff_response: str) -> str | None:
|
|
54
|
+
"""Apply SEARCH/REPLACE diff blocks to original code."""
|
|
55
|
+
result = original
|
|
56
|
+
|
|
57
|
+
pattern = r"<<<<<<< SEARCH\s*(.*?)\s*=======\s*(.*?)\s*>>>>>>> REPLACE"
|
|
58
|
+
matches = re.findall(pattern, diff_response, re.DOTALL)
|
|
59
|
+
|
|
60
|
+
if not matches:
|
|
61
|
+
return extract_code(diff_response)
|
|
62
|
+
|
|
63
|
+
for search, replace in matches:
|
|
64
|
+
search = search.strip()
|
|
65
|
+
replace = replace.strip()
|
|
66
|
+
if search in result:
|
|
67
|
+
result = result.replace(search, replace, 1)
|
|
68
|
+
else:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
return result
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class CodeAdapter(ArtifactAdapter):
|
|
75
|
+
"""Adapter for Levi's existing code-evolution behavior."""
|
|
76
|
+
|
|
77
|
+
artifact_type = "code"
|
|
78
|
+
|
|
79
|
+
def __init__(self, config: LeviConfig):
|
|
80
|
+
self.config = config
|
|
81
|
+
self.fn_name = extract_fn_name(config.function_signature)
|
|
82
|
+
|
|
83
|
+
def make_program(self, content: str, metadata: dict[str, Any] | None = None) -> Program:
|
|
84
|
+
return Program(content=content, metadata=metadata or {})
|
|
85
|
+
|
|
86
|
+
def snapshot_content(self, elite_data: Mapping[str, Any]) -> str:
|
|
87
|
+
content = elite_data.get("content")
|
|
88
|
+
if isinstance(content, str):
|
|
89
|
+
return content
|
|
90
|
+
|
|
91
|
+
legacy_code = elite_data.get("code")
|
|
92
|
+
if isinstance(legacy_code, str):
|
|
93
|
+
return legacy_code
|
|
94
|
+
|
|
95
|
+
raise KeyError("content")
|
|
96
|
+
|
|
97
|
+
async def evaluate(
|
|
98
|
+
self,
|
|
99
|
+
executor: ResilientProcessPool,
|
|
100
|
+
content: str,
|
|
101
|
+
*,
|
|
102
|
+
inputs: list[Any] | None = None,
|
|
103
|
+
timeout: float | None = None,
|
|
104
|
+
) -> dict[str, Any]:
|
|
105
|
+
return await executor.run(
|
|
106
|
+
evaluate_code,
|
|
107
|
+
content,
|
|
108
|
+
self.config.score_fn,
|
|
109
|
+
self.config.inputs if inputs is None else inputs,
|
|
110
|
+
self.fn_name,
|
|
111
|
+
timeout=self.config.pipeline.eval_timeout if timeout is None else timeout,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def build_mutation_prompt(
|
|
115
|
+
self,
|
|
116
|
+
parents: Sequence[ProgramWithScore],
|
|
117
|
+
*,
|
|
118
|
+
meta_advice: str | None = None,
|
|
119
|
+
model: ClientSpec | None = None,
|
|
120
|
+
use_diff: bool = False,
|
|
121
|
+
) -> str:
|
|
122
|
+
builder = PromptBuilder()
|
|
123
|
+
builder.add_section("Problem", self.config.problem_description, priority=10)
|
|
124
|
+
builder.add_section("Signature", f"```python\n{self.config.function_signature}\n```", priority=20)
|
|
125
|
+
builder.add_parents(list(parents), priority=30)
|
|
126
|
+
|
|
127
|
+
mutation_overrides = self.config.prompt_overrides.get("mutation", {})
|
|
128
|
+
model_key = client_name(model) if model is not None else None
|
|
129
|
+
if model_key and model_key in mutation_overrides:
|
|
130
|
+
builder.set_custom_output(mutation_overrides[model_key])
|
|
131
|
+
else:
|
|
132
|
+
builder.set_output_mode(OutputMode.DIFF if use_diff else OutputMode.FULL)
|
|
133
|
+
|
|
134
|
+
if meta_advice:
|
|
135
|
+
builder.add_section("Meta-Advice", meta_advice, priority=100)
|
|
136
|
+
|
|
137
|
+
return builder.build()
|
|
138
|
+
|
|
139
|
+
def extract_candidate(
|
|
140
|
+
self,
|
|
141
|
+
response_text: str,
|
|
142
|
+
*,
|
|
143
|
+
parent_content: str | None = None,
|
|
144
|
+
use_diff: bool = False,
|
|
145
|
+
) -> str | None:
|
|
146
|
+
if use_diff:
|
|
147
|
+
if parent_content is None:
|
|
148
|
+
raise ValueError("parent_content is required when use_diff=True")
|
|
149
|
+
return apply_diff(parent_content, response_text)
|
|
150
|
+
return extract_code(response_text)
|
|
151
|
+
|
|
152
|
+
def build_diversity_prompt(self, existing_candidates: Sequence[tuple[str, float]]) -> str:
|
|
153
|
+
existing_seeds_text = "\n\n---\n\n".join(
|
|
154
|
+
[
|
|
155
|
+
f"### Seed {idx + 1} (Score: {score:.17g}):\n```python\n{content}\n```"
|
|
156
|
+
for idx, (content, score) in enumerate(existing_candidates)
|
|
157
|
+
]
|
|
158
|
+
)
|
|
159
|
+
prompt_template = self.config.init.diversity_prompt or DIVERSITY_SEED_PROMPT
|
|
160
|
+
return prompt_template.format(
|
|
161
|
+
problem_title="Algorithm Optimization",
|
|
162
|
+
problem_description=self.config.problem_description,
|
|
163
|
+
function_signature=self.config.function_signature,
|
|
164
|
+
existing_seeds=existing_seeds_text,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def build_init_variant_prompt(self, parents: Sequence[ProgramWithScore]) -> str:
|
|
168
|
+
builder = PromptBuilder()
|
|
169
|
+
builder.add_section("Problem", self.config.problem_description, priority=10)
|
|
170
|
+
builder.add_section("Signature", f"```python\n{self.config.function_signature}\n```", priority=20)
|
|
171
|
+
builder.add_parents(list(parents), priority=30)
|
|
172
|
+
builder.set_output_mode(OutputMode.FULL)
|
|
173
|
+
return builder.build()
|
|
174
|
+
|
|
175
|
+
def build_paradigm_shift_prompt(
|
|
176
|
+
self,
|
|
177
|
+
representatives: Sequence[tuple[int, Any]],
|
|
178
|
+
*,
|
|
179
|
+
n_evaluations: int,
|
|
180
|
+
budget_progress: float = 0.0,
|
|
181
|
+
) -> str:
|
|
182
|
+
stage = get_budget_stage(budget_progress)
|
|
183
|
+
|
|
184
|
+
rep_text_parts = []
|
|
185
|
+
for idx, (cluster_id, elite) in enumerate(representatives):
|
|
186
|
+
score = elite.result.primary_score
|
|
187
|
+
content = elite.program.content
|
|
188
|
+
rep_text_parts.append(
|
|
189
|
+
f"### Region {idx + 1} (Cluster {cluster_id}, Score: {score:.17g})\n```python\n{content}\n```"
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
representative_solutions = "\n\n".join(rep_text_parts)
|
|
193
|
+
|
|
194
|
+
override = self.config.prompt_overrides.get("paradigm_shift")
|
|
195
|
+
if override:
|
|
196
|
+
return f"""# Algorithmic Paradigm Shift Challenge
|
|
197
|
+
|
|
198
|
+
## Problem
|
|
199
|
+
{self.config.problem_description}
|
|
200
|
+
|
|
201
|
+
## Function Signature
|
|
202
|
+
```python
|
|
203
|
+
{self.config.function_signature}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Current Best Solutions ({len(representatives)} regions, {n_evaluations} evaluations)
|
|
207
|
+
|
|
208
|
+
{representative_solutions}
|
|
209
|
+
|
|
210
|
+
## Your Task
|
|
211
|
+
{override}
|
|
212
|
+
|
|
213
|
+
Output ONLY complete, runnable Python code in a ```python block.
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
template = PARADIGM_SHIFT_PROMPTS[stage]
|
|
217
|
+
return template.format(
|
|
218
|
+
problem_description=self.config.problem_description,
|
|
219
|
+
function_signature=self.config.function_signature,
|
|
220
|
+
n_evaluations=n_evaluations,
|
|
221
|
+
n_regions=len(representatives),
|
|
222
|
+
representative_solutions=representative_solutions,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
def build_variant_prompt(self, base_content: str, base_score: float) -> str:
|
|
226
|
+
return VARIANT_GENERATION_PROMPT.format(
|
|
227
|
+
problem_description=self.config.problem_description,
|
|
228
|
+
function_signature=self.config.function_signature,
|
|
229
|
+
base_code=base_content,
|
|
230
|
+
base_score=base_score,
|
|
231
|
+
)
|