fastevolve 0.2.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.
fastevolve/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ from importlib.metadata import PackageNotFoundError, version as _pkg_version
2
+
3
+ from .config import Config
4
+ from .controller import Controller, RunResult, apply_diff
5
+
6
+ try:
7
+ __version__ = _pkg_version("fastevolve")
8
+ except PackageNotFoundError:
9
+ __version__ = "0.0.0+unknown"
10
+
11
+ __all__ = ["Config", "Controller", "RunResult", "apply_diff", "__version__"]
fastevolve/config.py ADDED
@@ -0,0 +1,14 @@
1
+ from dataclasses import dataclass, field
2
+ from .prompt_sampler.config import PromptConfig
3
+ from .llm_ensemble.config import EnsembleConfig
4
+ from .evaluator.config import EvaluatorConfig
5
+ from .program_database.config import DatabaseConfig
6
+
7
+
8
+ @dataclass(kw_only=True)
9
+ class Config:
10
+ prompt: PromptConfig = field(default_factory=PromptConfig)
11
+ ensemble: EnsembleConfig = field(default_factory=EnsembleConfig)
12
+ evaluator: EvaluatorConfig = field(default_factory=EvaluatorConfig)
13
+ database: DatabaseConfig = field(default_factory=DatabaseConfig)
14
+ iterations: int = 100
@@ -0,0 +1,86 @@
1
+ import re
2
+ from dataclasses import dataclass, field
3
+ from typing import Optional
4
+
5
+ from rich.progress import (
6
+ BarColumn, MofNCompleteColumn, Progress, TextColumn,
7
+ TimeElapsedColumn, TimeRemainingColumn,
8
+ )
9
+
10
+ from .config import Config
11
+ from .prompt_sampler import PromptSampler, TemplateLibrary
12
+ from .llm_ensemble import LLMEnsemble
13
+ from .evaluator import Evaluator
14
+ from .program_database import ProgramDatabase, Program
15
+ from .telemetry import setup, span, timings, log
16
+
17
+
18
+ @dataclass(kw_only=True)
19
+ class RunResult:
20
+ best: Optional[Program]
21
+ iterations: int
22
+ stats: dict = field(default_factory=dict)
23
+
24
+
25
+ def apply_diff(parent_program: Program, diff: str) -> Program:
26
+ m = re.search(r"```(?:python)?\s*\n(.*?)```", diff, re.DOTALL)
27
+ code = (m.group(1) if m else diff).strip()
28
+ if not code:
29
+ code = parent_program.code
30
+ return Program(code=code, parent_id=parent_program.id, island=parent_program.island,
31
+ generation=parent_program.generation + 1)
32
+
33
+
34
+ class Controller:
35
+ def __init__(self, config: Config, *, initial_program: str):
36
+ setup()
37
+ self.config = config
38
+ lib = TemplateLibrary()
39
+ self.sampler = PromptSampler(config.prompt, library=lib)
40
+ self.ensemble = LLMEnsemble(config.ensemble, system_prompts=lib.system_prompts)
41
+ self.evaluator = Evaluator(config.evaluator)
42
+ self.database = ProgramDatabase(config.database)
43
+ seed = self.database.seed(initial_program)
44
+ self.database.add(seed, self.evaluator.execute(seed))
45
+
46
+ def run(self) -> RunResult:
47
+ best: Optional[Program] = None
48
+ cols = [
49
+ TextColumn("[bold cyan]evolve[/]"),
50
+ BarColumn(), MofNCompleteColumn(),
51
+ TextColumn("[yellow]{task.fields[stage]:>8}[/]"),
52
+ TextColumn("fit=[green]{task.fields[fit]:.3f}[/]"),
53
+ TextColumn("best=[magenta]{task.fields[best]:.3f}[/]"),
54
+ TimeElapsedColumn(), TimeRemainingColumn(),
55
+ ]
56
+ with Progress(*cols, transient=False) as prog:
57
+ task = prog.add_task("run", total=self.config.iterations, stage="init", fit=0.0, best=0.0)
58
+ for _ in range(self.config.iterations):
59
+ prog.update(task, stage="sample")
60
+ with span("sample"):
61
+ parent, insp = self.database.sample()
62
+ prog.update(task, stage="prompt")
63
+ with span("prompt"):
64
+ prompt = self.sampler.build(parent, insp)
65
+ prog.update(task, stage="generate")
66
+ with span("generate"):
67
+ diff = self.ensemble.generate(prompt)
68
+ with span("apply"):
69
+ child = apply_diff(parent, diff)
70
+ child.island = parent.island
71
+ prog.update(task, stage="evaluate")
72
+ with span("evaluate"):
73
+ result = self.evaluator.execute(child)
74
+ self.database.add(child, result)
75
+ if best is None or child.fitness > best.fitness:
76
+ best = child
77
+ prog.update(task, advance=1, fit=child.fitness,
78
+ best=best.fitness if best else 0.0)
79
+ t = timings()
80
+ log.info("done. population=%d best=%.3f", len(self.database.by_id),
81
+ best.fitness if best else 0.0)
82
+ for name, s in t.items():
83
+ log.info("[cyan]%-9s[/] n=%-4d total=%6.2fs avg=%.3fs",
84
+ name, s["n"], s["total"], s["avg"])
85
+ return RunResult(best=best, iterations=self.config.iterations,
86
+ stats={"population": len(self.database.by_id), "timings": t})
@@ -0,0 +1,5 @@
1
+ from .config import EvaluatorConfig
2
+ from .result import EvaluationResult
3
+ from .evaluator import Evaluator
4
+
5
+ __all__ = ["EvaluatorConfig", "EvaluationResult", "Evaluator"]
@@ -0,0 +1,9 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Callable, List, Tuple
3
+
4
+
5
+ @dataclass(kw_only=True)
6
+ class EvaluatorConfig:
7
+ cascade: List[Tuple[Callable, float]] = field(default_factory=list)
8
+ timeout: float = 30.0
9
+ parallelism: int = 1
@@ -0,0 +1,26 @@
1
+ from queue import PriorityQueue
2
+
3
+ from ..telemetry import log
4
+ from .result import EvaluationResult
5
+
6
+
7
+ class Evaluator:
8
+ def __init__(self, config):
9
+ self.config = config
10
+ self.pool: PriorityQueue = PriorityQueue()
11
+
12
+ def execute(self, child_program) -> EvaluationResult:
13
+ result = EvaluationResult()
14
+ for stage_fn, threshold in self.config.cascade:
15
+ name = getattr(stage_fn, "__name__", f"stage{len(result.scores)}")
16
+ try:
17
+ score = float(stage_fn(child_program))
18
+ except Exception:
19
+ log.exception("evaluator stage [yellow]%s[/] raised on program %s", name, child_program.id)
20
+ return result
21
+ result.scores[name] = score
22
+ if score < threshold:
23
+ return result
24
+ result.passed = True
25
+ result.behavior = tuple(max(0.0, min(1.0, v)) for v in result.scores.values())
26
+ return result
@@ -0,0 +1,13 @@
1
+ from dataclasses import dataclass, field
2
+
3
+
4
+ @dataclass(kw_only=True)
5
+ class EvaluationResult:
6
+ scores: dict = field(default_factory=dict)
7
+ passed: bool = False
8
+ behavior: tuple = ()
9
+ extras: dict = field(default_factory=dict)
10
+
11
+ @property
12
+ def fitness(self) -> float:
13
+ return sum(self.scores.values()) / max(1, len(self.scores))
@@ -0,0 +1,6 @@
1
+ from .config import ModelConfig, EnsembleConfig
2
+ from .base import BaseLLM
3
+ from .ollama import OllamaLLM
4
+ from .ensemble import LLMEnsemble
5
+
6
+ __all__ = ["ModelConfig", "EnsembleConfig", "BaseLLM", "OllamaLLM", "LLMEnsemble"]
@@ -0,0 +1,6 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class BaseLLM(ABC):
5
+ @abstractmethod
6
+ def generate(self, prompt: str) -> str: ...
@@ -0,0 +1,20 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import List, Literal
3
+
4
+
5
+ @dataclass(kw_only=True)
6
+ class ModelConfig:
7
+ name: str
8
+ temperature: float = 0.7
9
+ weight: float = 1.0
10
+ role: Literal["fast", "deep"] = "fast"
11
+ num_ctx: int = 4096
12
+ flash_attention: bool = True
13
+ options: dict = field(default_factory=dict)
14
+
15
+
16
+ @dataclass(kw_only=True)
17
+ class EnsembleConfig:
18
+ models: List[ModelConfig] = field(default_factory=list)
19
+ host: str = "http://localhost:11434"
20
+ timeout: float = 600.0
@@ -0,0 +1,18 @@
1
+ import random
2
+ from .ollama import OllamaLLM
3
+
4
+
5
+ class LLMEnsemble:
6
+ def __init__(self, config, *, system_prompts: dict | None = None):
7
+ self.config = config
8
+ sp = system_prompts or {}
9
+ self.llms = [OllamaLLM(m, host=config.host, timeout=config.timeout,
10
+ system_prompt=sp.get(m.name)) for m in config.models]
11
+ if not self.llms:
12
+ raise ValueError("EnsembleConfig.models is empty")
13
+
14
+ def select_model(self) -> OllamaLLM:
15
+ return random.choices(self.llms, weights=[m.cfg.weight for m in self.llms], k=1)[0]
16
+
17
+ def generate(self, prompt: str) -> str:
18
+ return self.select_model().generate(prompt)
@@ -0,0 +1,45 @@
1
+ from ollama import Client, ResponseError
2
+
3
+ from ..telemetry import log
4
+ from .base import BaseLLM
5
+
6
+
7
+ class OllamaLLM(BaseLLM):
8
+ def __init__(self, model_config, *, host: str = "http://localhost:11434", timeout: float = 600.0, system_prompt: str | None = None):
9
+ self.cfg = model_config
10
+ self.system_prompt = system_prompt
11
+ self.client = Client(host=host, timeout=timeout)
12
+ self._ensure_model()
13
+
14
+ def _ensure_model(self):
15
+ try:
16
+ self.client.show(self.cfg.name)
17
+ except ResponseError:
18
+ log.info("[ollama] pulling [bold]%s[/]...", self.cfg.name)
19
+ self.client.pull(self.cfg.name)
20
+
21
+ def generate(self, prompt: str) -> str:
22
+ try:
23
+ return self._generate(prompt)
24
+ except Exception:
25
+ log.exception("ollama generate failed for model=%s", self.cfg.name)
26
+ raise
27
+
28
+ def _options(self) -> dict:
29
+ opts = {
30
+ "temperature": self.cfg.temperature,
31
+ "num_ctx": self.cfg.num_ctx,
32
+ "flash_attn": self.cfg.flash_attention,
33
+ }
34
+ opts.update(self.cfg.options)
35
+ return opts
36
+
37
+ def _generate(self, prompt: str) -> str:
38
+ resp = self.client.generate(
39
+ model=self.cfg.name,
40
+ prompt=prompt,
41
+ system=self.system_prompt,
42
+ options=self._options(),
43
+ stream=False,
44
+ )
45
+ return resp.response
@@ -0,0 +1,6 @@
1
+ from .config import DatabaseConfig
2
+ from .program import Program
3
+ from .embedder import CodeEmbedder
4
+ from .database import ProgramDatabase
5
+
6
+ __all__ = ["DatabaseConfig", "Program", "CodeEmbedder", "ProgramDatabase"]
@@ -0,0 +1,11 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(kw_only=True)
5
+ class DatabaseConfig:
6
+ num_islands: int = 4
7
+ cell_bins: int = 10
8
+ top_k: int = 16
9
+ num_inspirations: int = 3
10
+ migration_size: int = 8
11
+ migration_every: int = 25
@@ -0,0 +1,57 @@
1
+ import heapq
2
+ import random
3
+ from collections import deque
4
+ from .program import Program
5
+ from .embedder import CodeEmbedder
6
+
7
+
8
+ class ProgramDatabase:
9
+ def __init__(self, config):
10
+ self.config = config
11
+ self.islands: list[dict] = [dict() for _ in range(config.num_islands)]
12
+ self.by_id: dict[int, Program] = {}
13
+ self.heap: list[tuple[float, int]] = []
14
+ self.migrations = [deque(maxlen=config.migration_size) for _ in range(config.num_islands)]
15
+ self.embedder = CodeEmbedder()
16
+ self.step = 0
17
+
18
+ def _cell(self, behavior):
19
+ if not behavior:
20
+ return (0,)
21
+ return tuple(min(self.config.cell_bins - 1, int(b * self.config.cell_bins)) for b in behavior)
22
+
23
+ def seed(self, code: str, *, island: int = 0) -> Program:
24
+ p = Program(code=code, island=island)
25
+ self.by_id[p.id] = p
26
+ self.islands[island][("seed", p.id)] = p
27
+ heapq.heappush(self.heap, (0.0, p.id))
28
+ self.embedder.add(self.embedder.embed(p), p.id)
29
+ return p
30
+
31
+ def add(self, child_program: Program, results):
32
+ child_program.fitness = results.fitness
33
+ child_program.behavior = results.behavior
34
+ cell = self._cell(results.behavior)
35
+ grid = self.islands[child_program.island % self.config.num_islands]
36
+ if cell not in grid or grid[cell].fitness < child_program.fitness:
37
+ grid[cell] = child_program
38
+ self.by_id[child_program.id] = child_program
39
+ heapq.heappush(self.heap, (-child_program.fitness, child_program.id))
40
+ self.embedder.add(self.embedder.embed(child_program), child_program.id)
41
+ self.step += 1
42
+ if self.step % self.config.migration_every == 0:
43
+ self._migrate()
44
+
45
+ def _migrate(self):
46
+ n = self.config.num_islands
47
+ for i, grid in enumerate(self.islands):
48
+ if grid:
49
+ self.migrations[(i + 1) % n].append(max(grid.values(), key=lambda p: p.fitness))
50
+
51
+ def sample(self):
52
+ top = heapq.nsmallest(self.config.top_k, self.heap)
53
+ live = [(f, pid) for f, pid in top if pid in self.by_id] or [(0.0, next(iter(self.by_id)))]
54
+ parent = self.by_id[random.choice(live)[1]]
55
+ ids = self.embedder.nearest(self.embedder.embed(parent), k=self.config.num_inspirations + 1)
56
+ insp = [self.by_id[i] for i in ids if i != parent.id and i in self.by_id][: self.config.num_inspirations]
57
+ return parent, insp
@@ -0,0 +1,25 @@
1
+ import math
2
+ import re
3
+ from collections import Counter
4
+
5
+
6
+ class CodeEmbedder:
7
+ def __init__(self):
8
+ self.index: list[tuple[Counter, int]] = []
9
+
10
+ def embed(self, program) -> Counter:
11
+ return Counter(re.findall(r"\w+", program.code))
12
+
13
+ def add(self, vector: Counter, program_id: int):
14
+ self.index.append((vector, program_id))
15
+
16
+ @staticmethod
17
+ def _cos(a: Counter, b: Counter) -> float:
18
+ num = sum(a[t] * b[t] for t in set(a) & set(b))
19
+ na = math.sqrt(sum(v * v for v in a.values()))
20
+ nb = math.sqrt(sum(v * v for v in b.values()))
21
+ return num / (na * nb) if na and nb else 0.0
22
+
23
+ def nearest(self, vector: Counter, *, k: int) -> list[int]:
24
+ scored = sorted(((self._cos(vector, v), pid) for v, pid in self.index), reverse=True)
25
+ return [pid for _, pid in scored[:k]]
@@ -0,0 +1,16 @@
1
+ import itertools
2
+ from dataclasses import dataclass, field
3
+ from typing import Optional, Tuple
4
+
5
+ _ids = itertools.count()
6
+
7
+
8
+ @dataclass
9
+ class Program:
10
+ code: str
11
+ id: int = field(default_factory=lambda: next(_ids), kw_only=True)
12
+ parent_id: Optional[int] = field(default=None, kw_only=True)
13
+ fitness: float = field(default=0.0, kw_only=True)
14
+ behavior: Tuple = field(default=(), kw_only=True)
15
+ island: int = field(default=0, kw_only=True)
16
+ generation: int = field(default=0, kw_only=True)
@@ -0,0 +1,5 @@
1
+ from .config import PromptConfig
2
+ from .template_library import TemplateLibrary
3
+ from .sampler import PromptSampler
4
+
5
+ __all__ = ["PromptConfig", "TemplateLibrary", "PromptSampler"]
@@ -0,0 +1,9 @@
1
+ from dataclasses import dataclass, field
2
+
3
+
4
+ @dataclass(kw_only=True)
5
+ class PromptConfig:
6
+ template: str = "default"
7
+ num_inspirations: int = 3
8
+ temperature: float = 0.7
9
+ system_prompts: dict = field(default_factory=dict)
@@ -0,0 +1,12 @@
1
+ from .template_library import TemplateLibrary
2
+
3
+
4
+ class PromptSampler:
5
+ def __init__(self, config, *, library: TemplateLibrary | None = None):
6
+ self.config = config
7
+ self.library = library or TemplateLibrary()
8
+ self.library.system_prompts.update(config.system_prompts)
9
+
10
+ def build(self, parent_program, inspirations):
11
+ insp = "\n---\n".join(p.code for p in inspirations) or "(none)"
12
+ return self.library.render(self.config.template, parent=parent_program.code, inspirations=insp)
@@ -0,0 +1,25 @@
1
+ from pathlib import Path
2
+
3
+ DEFAULT = """You are evolving a Python program. Improve the parent program.
4
+
5
+ # Parent
6
+ {parent}
7
+
8
+ # Inspirations
9
+ {inspirations}
10
+
11
+ Return ONLY the full replacement Python code (no prose, no fences)."""
12
+
13
+
14
+ class TemplateLibrary:
15
+ def __init__(self):
16
+ self.templates = {"default": DEFAULT}
17
+ self.system_prompts: dict[str, str] = {}
18
+
19
+ def load(self, path):
20
+ for f in Path(path).glob("*.txt"):
21
+ self.templates[f.stem] = f.read_text(encoding="utf-8")
22
+
23
+ def get(self, name): return self.templates[name]
24
+
25
+ def render(self, name, **vars): return self.templates[name].format(**vars)
@@ -0,0 +1,36 @@
1
+ import logging
2
+ import os
3
+ import time
4
+ from collections import defaultdict
5
+ from contextlib import contextmanager
6
+
7
+ from rich.logging import RichHandler
8
+
9
+ log = logging.getLogger("fastevolve")
10
+ _TIMINGS: dict[str, list[float]] = defaultdict(list)
11
+
12
+
13
+ def setup() -> None:
14
+ if logging.getLogger().handlers:
15
+ return
16
+ level = logging.WARNING if os.getenv("FASTEVOLVE_QUIET") else logging.INFO
17
+ logging.basicConfig(
18
+ level=level, format="%(message)s", datefmt="[%X]",
19
+ handlers=[RichHandler(rich_tracebacks=True, show_path=False, markup=True)],
20
+ )
21
+
22
+
23
+ @contextmanager
24
+ def span(name: str):
25
+ t = time.perf_counter()
26
+ try:
27
+ yield
28
+ except Exception:
29
+ log.exception("[red]%s failed after %.2fs[/]", name, time.perf_counter() - t)
30
+ raise
31
+ finally:
32
+ _TIMINGS[name].append(time.perf_counter() - t)
33
+
34
+
35
+ def timings() -> dict[str, dict[str, float]]:
36
+ return {k: {"n": len(v), "total": sum(v), "avg": sum(v) / len(v)} for k, v in _TIMINGS.items()}
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastevolve
3
+ Version: 0.2.0
4
+ Summary: Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites islands, cascade evaluation, and a local Ollama ensemble.
5
+ Project-URL: Homepage, https://github.com/tiagomonteiro/alpha_evolve_open_souce_version
6
+ Project-URL: Issues, https://github.com/tiagomonteiro/alpha_evolve_open_souce_version/issues
7
+ Author-email: Tiago Monteiro <monteiro.t@northeastern.edu>
8
+ License: MIT
9
+ Keywords: alphaevolve,evolutionary-search,llm,map-elites,ollama,program-synthesis
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: ollama>=0.4.0
17
+ Requires-Dist: rich>=13.7
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest>=8; extra == 'dev'
20
+ Requires-Dist: ruff>=0.6; extra == 'dev'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # fastevolve
24
+
25
+ Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites islands, cascade evaluation, and a local Ollama ensemble.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ uv sync
31
+ ```
32
+
33
+ ## Run the demo
34
+
35
+ Start Ollama and pull the model first:
36
+
37
+ ```bash
38
+ ollama serve
39
+ ollama pull gemma3:e4b
40
+ ```
41
+
42
+ Then:
43
+
44
+ ```bash
45
+ uv run python main.py
46
+ ```
@@ -0,0 +1,26 @@
1
+ fastevolve/__init__.py,sha256=EPOCJKvRBM-PnX-m7sdDH1nQgTqyYPtdScoJXD4ZoqM,355
2
+ fastevolve/config.py,sha256=fqq7HZM_Nh1or1MR-ajJpJY_FQqiqnFGjJfNhunilBQ,575
3
+ fastevolve/controller.py,sha256=Z6qXAffclGTicUqsxrGb2rY5rzTjCKaU3AqvYE9UecE,3653
4
+ fastevolve/telemetry.py,sha256=EpThR2zHUxqdJ835v-JjxkY2Xas1G80SvsaM4bMQVrw,997
5
+ fastevolve/evaluator/__init__.py,sha256=IvelEVdP8TDKu1vc7H35R24H2hRXfgua94HxEH-NaJ0,170
6
+ fastevolve/evaluator/config.py,sha256=QBeOeIb8nuBoLmc6LXh3leIbnb99drF_imZPKw7fDaU,255
7
+ fastevolve/evaluator/evaluator.py,sha256=xL1B8GIBQwHDpNhyKWSagcS1uAXo7mH8FBja45K3SeA,941
8
+ fastevolve/evaluator/result.py,sha256=R416-7j2x0rPhdFKte6qSe6D1POCI9vTsw7qSJPb65c,351
9
+ fastevolve/llm_ensemble/__init__.py,sha256=-1CQiNjkp45ni5F2eVO-EXBxRiB11ktpI2xqzOyYL00,222
10
+ fastevolve/llm_ensemble/base.py,sha256=958WidTEGAx6eDx3rAY3Gqp1qKj6K2NINlTUKPmtWWI,126
11
+ fastevolve/llm_ensemble/config.py,sha256=8BazEWwbmZguxnYT6jC3TfLoPLdk7zqNwqUZGfYQsm0,512
12
+ fastevolve/llm_ensemble/ensemble.py,sha256=UhLMa_08SObEMYVkEUFF5v3d-uJJZ3Sj54NJtmgvsDE,680
13
+ fastevolve/llm_ensemble/ollama.py,sha256=PKfpfnwN8ebsiMNUYQDHqTEnwSWcYEuoRdaimCxqMSk,1422
14
+ fastevolve/program_database/__init__.py,sha256=3Pgkj5AssBXy7iOMvpxKUViP1K5oWdxl09LjcvqQdyg,213
15
+ fastevolve/program_database/config.py,sha256=v8bhchs8BbDoa6LE67Vsc4MmyI_5ktfGl3fO6udcquQ,240
16
+ fastevolve/program_database/database.py,sha256=Py_o9yuSGSGTZBOT74SmoB5w6NyrG9sSrgoPTJRUfsU,2438
17
+ fastevolve/program_database/embedder.py,sha256=uQGTNzNw8-npumjLVNEKxjI4sFmWVmkEjN2CiXAry6w,842
18
+ fastevolve/program_database/program.py,sha256=KJYSmu84LmIbXXjB0p1KENU-0fFA7iWXynXpSx_T47g,506
19
+ fastevolve/prompt_sampler/__init__.py,sha256=-YtYT7Rc7GwT0uTxNKwEte3XhaWwc-kZagGYhrCWGrw,178
20
+ fastevolve/prompt_sampler/config.py,sha256=6PRqLdzzTDcP7rkWxk4UYvP0tGI9xQdntpYAJWTNM1k,232
21
+ fastevolve/prompt_sampler/sampler.py,sha256=rQQrsQE_4Ba_zSmEI18hH-gJon0OM2JooPHuyrVGmfc,519
22
+ fastevolve/prompt_sampler/template_library.py,sha256=EvPyZlK8LURQ9qngMQBYdBl43WWL0PN3PHhSduYy_fM,639
23
+ fastevolve-0.2.0.dist-info/METADATA,sha256=UoDHGoR7ACe7FF-l1yVmDaTgEmbW2Wg9vLcWNSdgyvY,1354
24
+ fastevolve-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
25
+ fastevolve-0.2.0.dist-info/entry_points.txt,sha256=IpEsShMkKymR93wiyRle9nSCY03yiQPWshXWUsSE-pY,46
26
+ fastevolve-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fastevolve-demo = main:main