fastevolve 0.2.0__tar.gz
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-0.2.0/.claude/settings.local.json +15 -0
- fastevolve-0.2.0/.gitignore +11 -0
- fastevolve-0.2.0/.python-version +1 -0
- fastevolve-0.2.0/PKG-INFO +46 -0
- fastevolve-0.2.0/README.md +24 -0
- fastevolve-0.2.0/fastevolve/__init__.py +11 -0
- fastevolve-0.2.0/fastevolve/config.py +14 -0
- fastevolve-0.2.0/fastevolve/controller.py +86 -0
- fastevolve-0.2.0/fastevolve/evaluator/__init__.py +5 -0
- fastevolve-0.2.0/fastevolve/evaluator/config.py +9 -0
- fastevolve-0.2.0/fastevolve/evaluator/evaluator.py +26 -0
- fastevolve-0.2.0/fastevolve/evaluator/result.py +13 -0
- fastevolve-0.2.0/fastevolve/llm_ensemble/__init__.py +6 -0
- fastevolve-0.2.0/fastevolve/llm_ensemble/base.py +6 -0
- fastevolve-0.2.0/fastevolve/llm_ensemble/config.py +20 -0
- fastevolve-0.2.0/fastevolve/llm_ensemble/ensemble.py +18 -0
- fastevolve-0.2.0/fastevolve/llm_ensemble/ollama.py +45 -0
- fastevolve-0.2.0/fastevolve/program_database/__init__.py +6 -0
- fastevolve-0.2.0/fastevolve/program_database/config.py +11 -0
- fastevolve-0.2.0/fastevolve/program_database/database.py +57 -0
- fastevolve-0.2.0/fastevolve/program_database/embedder.py +25 -0
- fastevolve-0.2.0/fastevolve/program_database/program.py +16 -0
- fastevolve-0.2.0/fastevolve/prompt_sampler/__init__.py +5 -0
- fastevolve-0.2.0/fastevolve/prompt_sampler/config.py +9 -0
- fastevolve-0.2.0/fastevolve/prompt_sampler/sampler.py +12 -0
- fastevolve-0.2.0/fastevolve/prompt_sampler/template_library.py +25 -0
- fastevolve-0.2.0/fastevolve/telemetry.py +36 -0
- fastevolve-0.2.0/main.py +70 -0
- fastevolve-0.2.0/pyproject.toml +45 -0
- fastevolve-0.2.0/uv.lock +348 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(python -c \"from fastevolve import Config, Controller, RunResult, apply_diff; from fastevolve.llm_ensemble import ModelConfig; from fastevolve.evaluator import EvaluationResult; from fastevolve.program_database import Program, ProgramDatabase; print\\('OK'\\)\")",
|
|
5
|
+
"Bash(python -c \"import ast; ast.parse\\(open\\('main.py'\\).read\\(\\)\\); print\\('syntax OK'\\)\")",
|
|
6
|
+
"Bash(python -c \"import sys; sys.path.insert\\(0, '.'\\); import importlib.util; spec = importlib.util.spec_from_file_location\\('m', 'main.py'\\); m = importlib.util.module_from_spec\\(spec\\); print\\('imports OK'\\)\")",
|
|
7
|
+
"Bash(python -c \"import tomllib; tomllib.loads\\(open\\('pyproject.toml'\\).read\\(\\)\\); print\\('TOML valid'\\)\")",
|
|
8
|
+
"Bash(uv sync *)",
|
|
9
|
+
"Bash(uv run *)",
|
|
10
|
+
"Bash(.venv/Scripts/python.exe -m pip install \"rich>=13.7\" -q)",
|
|
11
|
+
"Bash(uv add *)",
|
|
12
|
+
"Bash(.venv/Scripts/python.exe -c 'from fastevolve.controller import Controller; from fastevolve.telemetry import setup, span, log; setup\\(\\); log.info\\('\\\\''telemetry [bold green]ok[/]'\\\\''\\); *)"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -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,24 @@
|
|
|
1
|
+
# fastevolve
|
|
2
|
+
|
|
3
|
+
Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites islands, cascade evaluation, and a local Ollama ensemble.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Run the demo
|
|
12
|
+
|
|
13
|
+
Start Ollama and pull the model first:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
ollama serve
|
|
17
|
+
ollama pull gemma3:e4b
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Then:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv run python main.py
|
|
24
|
+
```
|
|
@@ -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__"]
|
|
@@ -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,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,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,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,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()}
|
fastevolve-0.2.0/main.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Demo: evolve a Python `solve(x)` function with gemma4:e4b on Ollama.
|
|
2
|
+
|
|
3
|
+
Run from the project root (where the `fastevolve/` package sits):
|
|
4
|
+
python main.py
|
|
5
|
+
# or: uv run python main.py
|
|
6
|
+
"""
|
|
7
|
+
from fastevolve import Config, Controller
|
|
8
|
+
from fastevolve.llm_ensemble import ModelConfig
|
|
9
|
+
|
|
10
|
+
MODEL = "gemma4:e4b"
|
|
11
|
+
|
|
12
|
+
INITIAL_PROGRAM = '''def solve(x):
|
|
13
|
+
total = 0
|
|
14
|
+
for i in range(x):
|
|
15
|
+
total += x
|
|
16
|
+
if x < 0:
|
|
17
|
+
total = -total
|
|
18
|
+
return total + 1
|
|
19
|
+
'''
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def syntax_score(program) -> float:
|
|
23
|
+
try:
|
|
24
|
+
compile(program.code, "<prog>", "exec")
|
|
25
|
+
return 1.0
|
|
26
|
+
except SyntaxError:
|
|
27
|
+
return 0.0
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def correctness_score(program) -> float:
|
|
31
|
+
ns: dict = {}
|
|
32
|
+
try:
|
|
33
|
+
exec(program.code, ns)
|
|
34
|
+
except Exception:
|
|
35
|
+
return 0.0
|
|
36
|
+
fn = ns.get("solve")
|
|
37
|
+
if not callable(fn):
|
|
38
|
+
return 0.0
|
|
39
|
+
cases = [(2, 4), (3, 9), (4, 16), (5, 25)]
|
|
40
|
+
hits = sum(1 for x, y in cases if _safe(fn, x) == y)
|
|
41
|
+
return hits / len(cases)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _safe(fn, x):
|
|
45
|
+
try:
|
|
46
|
+
return fn(x)
|
|
47
|
+
except Exception:
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def main():
|
|
52
|
+
cfg = Config()
|
|
53
|
+
cfg.iterations = 20
|
|
54
|
+
cfg.ensemble.models = [
|
|
55
|
+
ModelConfig(name=MODEL, temperature=0.6, weight=1.0, role="fast",
|
|
56
|
+
num_ctx=8192, flash_attention=True),
|
|
57
|
+
ModelConfig(name=MODEL, temperature=1.0, weight=1.0, role="deep",
|
|
58
|
+
num_ctx=8192, flash_attention=True),
|
|
59
|
+
]
|
|
60
|
+
cfg.evaluator.cascade = [(syntax_score, 1.0), (correctness_score, 0.0)]
|
|
61
|
+
cfg.prompt.system_prompts = {MODEL: "You are an expert Python programmer. Output only Python code."}
|
|
62
|
+
|
|
63
|
+
result = Controller(cfg, initial_program=INITIAL_PROGRAM).run()
|
|
64
|
+
print("\n=== Best program ===")
|
|
65
|
+
print(result.best.code if result.best else "(none)")
|
|
66
|
+
print("Stats:", result.stats)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
main()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "fastevolve"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites islands, cascade evaluation, and a local Ollama ensemble."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [{ name = "Tiago Monteiro", email = "monteiro.t@northeastern.edu" }]
|
|
9
|
+
keywords = ["alphaevolve", "evolutionary-search", "llm", "ollama", "map-elites", "program-synthesis"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Intended Audience :: Science/Research",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
16
|
+
]
|
|
17
|
+
dependencies = [
|
|
18
|
+
"ollama>=0.4.0",
|
|
19
|
+
"rich>=13.7",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
dev = ["pytest>=8", "ruff>=0.6"]
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
fastevolve-demo = "main:main"
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/tiagomonteiro/alpha_evolve_open_souce_version"
|
|
30
|
+
Issues = "https://github.com/tiagomonteiro/alpha_evolve_open_souce_version/issues"
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["hatchling"]
|
|
34
|
+
build-backend = "hatchling.build"
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["fastevolve"]
|
|
38
|
+
|
|
39
|
+
[tool.ruff]
|
|
40
|
+
line-length = 110
|
|
41
|
+
target-version = "py312"
|
|
42
|
+
|
|
43
|
+
[tool.ruff.lint]
|
|
44
|
+
select = ["E", "F", "I", "UP", "B"]
|
|
45
|
+
ignore = ["E501"]
|
fastevolve-0.2.0/uv.lock
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.12"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "annotated-types"
|
|
7
|
+
version = "0.7.0"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
|
|
10
|
+
wheels = [
|
|
11
|
+
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "anyio"
|
|
16
|
+
version = "4.14.1"
|
|
17
|
+
source = { registry = "https://pypi.org/simple" }
|
|
18
|
+
dependencies = [
|
|
19
|
+
{ name = "idna" },
|
|
20
|
+
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
21
|
+
]
|
|
22
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3b/72/5562aabb8dd7181e8e860622a38bea08d17842b99ecd4c91f84ac95251b0/anyio-4.14.1.tar.gz", hash = "sha256:8d648a3544c1a700e3ff78615cd679e4c5c3f149904287e73687b2596963629e", size = 254831, upload-time = "2026-06-24T20:56:06.017Z" }
|
|
23
|
+
wheels = [
|
|
24
|
+
{ url = "https://files.pythonhosted.org/packages/b0/7b/90df4a0a816d98d6ea26f559d87836d494a2cf1fcf063be67df50a7bcc30/anyio-4.14.1-py3-none-any.whl", hash = "sha256:4e5533c5b8ff0a24f5d7a176cbe6877129cd183893f66b537f8f227d10527d72", size = 124875, upload-time = "2026-06-24T20:56:04.413Z" },
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[[package]]
|
|
28
|
+
name = "certifi"
|
|
29
|
+
version = "2026.6.17"
|
|
30
|
+
source = { registry = "https://pypi.org/simple" }
|
|
31
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" }
|
|
32
|
+
wheels = [
|
|
33
|
+
{ url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" },
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[[package]]
|
|
37
|
+
name = "colorama"
|
|
38
|
+
version = "0.4.6"
|
|
39
|
+
source = { registry = "https://pypi.org/simple" }
|
|
40
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
41
|
+
wheels = [
|
|
42
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[[package]]
|
|
46
|
+
name = "fastevolve"
|
|
47
|
+
version = "0.2.0"
|
|
48
|
+
source = { editable = "." }
|
|
49
|
+
dependencies = [
|
|
50
|
+
{ name = "ollama" },
|
|
51
|
+
{ name = "rich" },
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[package.optional-dependencies]
|
|
55
|
+
dev = [
|
|
56
|
+
{ name = "pytest" },
|
|
57
|
+
{ name = "ruff" },
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[package.metadata]
|
|
61
|
+
requires-dist = [
|
|
62
|
+
{ name = "ollama", specifier = ">=0.4.0" },
|
|
63
|
+
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8" },
|
|
64
|
+
{ name = "rich", specifier = ">=13.7" },
|
|
65
|
+
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.6" },
|
|
66
|
+
]
|
|
67
|
+
provides-extras = ["dev"]
|
|
68
|
+
|
|
69
|
+
[[package]]
|
|
70
|
+
name = "h11"
|
|
71
|
+
version = "0.16.0"
|
|
72
|
+
source = { registry = "https://pypi.org/simple" }
|
|
73
|
+
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
|
|
74
|
+
wheels = [
|
|
75
|
+
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[[package]]
|
|
79
|
+
name = "httpcore"
|
|
80
|
+
version = "1.0.9"
|
|
81
|
+
source = { registry = "https://pypi.org/simple" }
|
|
82
|
+
dependencies = [
|
|
83
|
+
{ name = "certifi" },
|
|
84
|
+
{ name = "h11" },
|
|
85
|
+
]
|
|
86
|
+
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
|
|
87
|
+
wheels = [
|
|
88
|
+
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
[[package]]
|
|
92
|
+
name = "httpx"
|
|
93
|
+
version = "0.28.1"
|
|
94
|
+
source = { registry = "https://pypi.org/simple" }
|
|
95
|
+
dependencies = [
|
|
96
|
+
{ name = "anyio" },
|
|
97
|
+
{ name = "certifi" },
|
|
98
|
+
{ name = "httpcore" },
|
|
99
|
+
{ name = "idna" },
|
|
100
|
+
]
|
|
101
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
|
|
102
|
+
wheels = [
|
|
103
|
+
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
[[package]]
|
|
107
|
+
name = "idna"
|
|
108
|
+
version = "3.18"
|
|
109
|
+
source = { registry = "https://pypi.org/simple" }
|
|
110
|
+
sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" }
|
|
111
|
+
wheels = [
|
|
112
|
+
{ url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" },
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
[[package]]
|
|
116
|
+
name = "iniconfig"
|
|
117
|
+
version = "2.3.0"
|
|
118
|
+
source = { registry = "https://pypi.org/simple" }
|
|
119
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
|
|
120
|
+
wheels = [
|
|
121
|
+
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
[[package]]
|
|
125
|
+
name = "markdown-it-py"
|
|
126
|
+
version = "4.2.0"
|
|
127
|
+
source = { registry = "https://pypi.org/simple" }
|
|
128
|
+
dependencies = [
|
|
129
|
+
{ name = "mdurl" },
|
|
130
|
+
]
|
|
131
|
+
sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" }
|
|
132
|
+
wheels = [
|
|
133
|
+
{ url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" },
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
[[package]]
|
|
137
|
+
name = "mdurl"
|
|
138
|
+
version = "0.1.2"
|
|
139
|
+
source = { registry = "https://pypi.org/simple" }
|
|
140
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
|
|
141
|
+
wheels = [
|
|
142
|
+
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
|
|
143
|
+
]
|
|
144
|
+
|
|
145
|
+
[[package]]
|
|
146
|
+
name = "ollama"
|
|
147
|
+
version = "0.6.2"
|
|
148
|
+
source = { registry = "https://pypi.org/simple" }
|
|
149
|
+
dependencies = [
|
|
150
|
+
{ name = "httpx" },
|
|
151
|
+
{ name = "pydantic" },
|
|
152
|
+
]
|
|
153
|
+
sdist = { url = "https://files.pythonhosted.org/packages/fc/72/5f12423b6b39ca8430fbe56f77fcf4ef60f63067c7c4a2e30e200ed9ec16/ollama-0.6.2.tar.gz", hash = "sha256:936d55daa684f474364c098611c933626f8d6c7d67065c5b7ae0c477b508b07f", size = 53145, upload-time = "2026-04-29T21:21:15.018Z" }
|
|
154
|
+
wheels = [
|
|
155
|
+
{ url = "https://files.pythonhosted.org/packages/c4/ab/d6722beeb2d10f7a3b9ff49375708904fde18f82b5609a0bc4aeb5996a4d/ollama-0.6.2-py3-none-any.whl", hash = "sha256:3ad7daab28e5a973445c36a73882a3ef698c2ebb00e21e308652741577509f7d", size = 15115, upload-time = "2026-04-29T21:21:13.794Z" },
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
[[package]]
|
|
159
|
+
name = "packaging"
|
|
160
|
+
version = "26.2"
|
|
161
|
+
source = { registry = "https://pypi.org/simple" }
|
|
162
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" }
|
|
163
|
+
wheels = [
|
|
164
|
+
{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" },
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
[[package]]
|
|
168
|
+
name = "pluggy"
|
|
169
|
+
version = "1.6.0"
|
|
170
|
+
source = { registry = "https://pypi.org/simple" }
|
|
171
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
|
172
|
+
wheels = [
|
|
173
|
+
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
[[package]]
|
|
177
|
+
name = "pydantic"
|
|
178
|
+
version = "2.13.4"
|
|
179
|
+
source = { registry = "https://pypi.org/simple" }
|
|
180
|
+
dependencies = [
|
|
181
|
+
{ name = "annotated-types" },
|
|
182
|
+
{ name = "pydantic-core" },
|
|
183
|
+
{ name = "typing-extensions" },
|
|
184
|
+
{ name = "typing-inspection" },
|
|
185
|
+
]
|
|
186
|
+
sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" }
|
|
187
|
+
wheels = [
|
|
188
|
+
{ url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" },
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
[[package]]
|
|
192
|
+
name = "pydantic-core"
|
|
193
|
+
version = "2.46.4"
|
|
194
|
+
source = { registry = "https://pypi.org/simple" }
|
|
195
|
+
dependencies = [
|
|
196
|
+
{ name = "typing-extensions" },
|
|
197
|
+
]
|
|
198
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" }
|
|
199
|
+
wheels = [
|
|
200
|
+
{ url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" },
|
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" },
|
|
202
|
+
{ url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" },
|
|
203
|
+
{ url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" },
|
|
204
|
+
{ url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" },
|
|
205
|
+
{ url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" },
|
|
206
|
+
{ url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" },
|
|
207
|
+
{ url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" },
|
|
208
|
+
{ url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" },
|
|
209
|
+
{ url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" },
|
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" },
|
|
211
|
+
{ url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" },
|
|
212
|
+
{ url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" },
|
|
213
|
+
{ url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" },
|
|
214
|
+
{ url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" },
|
|
215
|
+
{ url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" },
|
|
216
|
+
{ url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" },
|
|
217
|
+
{ url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" },
|
|
218
|
+
{ url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" },
|
|
219
|
+
{ url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" },
|
|
220
|
+
{ url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" },
|
|
221
|
+
{ url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" },
|
|
222
|
+
{ url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" },
|
|
223
|
+
{ url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" },
|
|
224
|
+
{ url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" },
|
|
225
|
+
{ url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" },
|
|
226
|
+
{ url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" },
|
|
227
|
+
{ url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" },
|
|
228
|
+
{ url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" },
|
|
229
|
+
{ url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" },
|
|
230
|
+
{ url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" },
|
|
231
|
+
{ url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" },
|
|
232
|
+
{ url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" },
|
|
233
|
+
{ url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" },
|
|
234
|
+
{ url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" },
|
|
235
|
+
{ url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" },
|
|
236
|
+
{ url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" },
|
|
237
|
+
{ url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" },
|
|
238
|
+
{ url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" },
|
|
239
|
+
{ url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" },
|
|
240
|
+
{ url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" },
|
|
241
|
+
{ url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" },
|
|
242
|
+
{ url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" },
|
|
243
|
+
{ url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" },
|
|
244
|
+
{ url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" },
|
|
245
|
+
{ url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" },
|
|
246
|
+
{ url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" },
|
|
247
|
+
{ url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" },
|
|
248
|
+
{ url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" },
|
|
249
|
+
{ url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" },
|
|
250
|
+
{ url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" },
|
|
251
|
+
{ url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" },
|
|
252
|
+
{ url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" },
|
|
253
|
+
{ url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" },
|
|
254
|
+
{ url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" },
|
|
255
|
+
{ url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" },
|
|
256
|
+
{ url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" },
|
|
257
|
+
{ url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" },
|
|
258
|
+
{ url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" },
|
|
259
|
+
{ url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" },
|
|
260
|
+
{ url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" },
|
|
261
|
+
{ url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" },
|
|
262
|
+
{ url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" },
|
|
263
|
+
{ url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" },
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
[[package]]
|
|
267
|
+
name = "pygments"
|
|
268
|
+
version = "2.20.0"
|
|
269
|
+
source = { registry = "https://pypi.org/simple" }
|
|
270
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
|
|
271
|
+
wheels = [
|
|
272
|
+
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
|
273
|
+
]
|
|
274
|
+
|
|
275
|
+
[[package]]
|
|
276
|
+
name = "pytest"
|
|
277
|
+
version = "9.1.1"
|
|
278
|
+
source = { registry = "https://pypi.org/simple" }
|
|
279
|
+
dependencies = [
|
|
280
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
281
|
+
{ name = "iniconfig" },
|
|
282
|
+
{ name = "packaging" },
|
|
283
|
+
{ name = "pluggy" },
|
|
284
|
+
{ name = "pygments" },
|
|
285
|
+
]
|
|
286
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
|
|
287
|
+
wheels = [
|
|
288
|
+
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
|
|
289
|
+
]
|
|
290
|
+
|
|
291
|
+
[[package]]
|
|
292
|
+
name = "rich"
|
|
293
|
+
version = "15.0.0"
|
|
294
|
+
source = { registry = "https://pypi.org/simple" }
|
|
295
|
+
dependencies = [
|
|
296
|
+
{ name = "markdown-it-py" },
|
|
297
|
+
{ name = "pygments" },
|
|
298
|
+
]
|
|
299
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" }
|
|
300
|
+
wheels = [
|
|
301
|
+
{ url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" },
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
[[package]]
|
|
305
|
+
name = "ruff"
|
|
306
|
+
version = "0.15.19"
|
|
307
|
+
source = { registry = "https://pypi.org/simple" }
|
|
308
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d5/e6/15800dfde183a1a106594016c912b4c12d050a301989d1aca6cb63759fe8/ruff-0.15.19.tar.gz", hash = "sha256:edc27f7172a93b32b102687009d6a588508815072141543ae603a8b9b0823063", size = 4772071, upload-time = "2026-06-24T01:10:46.942Z" }
|
|
309
|
+
wheels = [
|
|
310
|
+
{ url = "https://files.pythonhosted.org/packages/88/4c/9ded7626c39a0440c575bf69e2bf500d443388272c842662c59852ee7fcd/ruff-0.15.19-py3-none-linux_armv6l.whl", hash = "sha256:922d1eb283161564759bd49f507e91dc6112c15da8bd5b84ed714e086243cf86", size = 10950859, upload-time = "2026-06-24T01:10:38.491Z" },
|
|
311
|
+
{ url = "https://files.pythonhosted.org/packages/fb/ef/c211505ece1d00ef493d58e54e3b6383c946a21e9874774eb531f2512cf3/ruff-0.15.19-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4d190d8f62a0b94aba8f721116538a9ee29b1e74d26650846ba9b99f0ae21c40", size = 11294529, upload-time = "2026-06-24T01:10:36.481Z" },
|
|
312
|
+
{ url = "https://files.pythonhosted.org/packages/fe/93/78d462e7d39968e58094dc57be7d09ffb14ce37da5b68ed70338a35a1f21/ruff-0.15.19-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5a2c86ba6870dd415a9d9eb8be94d7924ebec6a26ffc7958ec7ca29d4bff967d", size = 10641416, upload-time = "2026-06-24T01:10:48.923Z" },
|
|
313
|
+
{ url = "https://files.pythonhosted.org/packages/76/c4/5cb66cfd1f865d5cca908b86c93ac785e7f572193d3c7426079ca6643e24/ruff-0.15.19-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b432bc087264aea70fd25ac198918b70bd9e2aa0db4297b0bb91bbfbbc63ce", size = 11015582, upload-time = "2026-06-24T01:10:30.089Z" },
|
|
314
|
+
{ url = "https://files.pythonhosted.org/packages/51/9f/8ecfaec10cf5eecd28fbc00ff4fb867db90a1be54bf3d39ebf93f893cd52/ruff-0.15.19-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8530a09d03b3a8c994f8b559a7dcdabc690bcd3f78ef276c38c83166798ebf56", size = 10744059, upload-time = "2026-06-24T01:10:32.48Z" },
|
|
315
|
+
{ url = "https://files.pythonhosted.org/packages/35/6b/983249d04562bc2d590edd75f32455cdb473affb3ba4bc8d883e939c697d/ruff-0.15.19-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87bf21fb3875fe69f0eacc825411657e2e85589cce633c35c0adf1113649c62b", size = 11568461, upload-time = "2026-06-24T01:10:17.435Z" },
|
|
316
|
+
{ url = "https://files.pythonhosted.org/packages/eb/39/bc7794f127b18f492a3b4ee82bba5a900c985ff13b72b46f46e3c171ba34/ruff-0.15.19-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9b229cb3ef56ecc2c1c8ebeca64b7a7740ccaef40a9eb097e78dde5a8560b83", size = 12429690, upload-time = "2026-06-24T01:10:40.638Z" },
|
|
317
|
+
{ url = "https://files.pythonhosted.org/packages/0a/3b/0de6859e698ed11c8a49e765196c8d333599b6a546c0715df39b6ba1aa2e/ruff-0.15.19-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c754515be7b76afe6e7e62df7776709571bcfc1631183828afcf3bafa869e3", size = 11693067, upload-time = "2026-06-24T01:10:25.681Z" },
|
|
318
|
+
{ url = "https://files.pythonhosted.org/packages/89/3d/0b1f30f84bee9ae6ae8d349c2ba8b6f4b040966744efdd3acc804ae7c024/ruff-0.15.19-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a498f82e0f4d8904c4e0aea5139cdfac1f39d19a3c51d491292f63a36e83b2e", size = 11616911, upload-time = "2026-06-24T01:10:44.809Z" },
|
|
319
|
+
{ url = "https://files.pythonhosted.org/packages/4d/eb/c90bd3dfc12eed9032c2c1bfe05105b93a1b2c8bce555db6308315b853ce/ruff-0.15.19-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:d48caa34488fb521fd0ef4aea2b0e8fe758298df044138f0d67b687a6a0d07ed", size = 11649343, upload-time = "2026-06-24T01:10:23.472Z" },
|
|
320
|
+
{ url = "https://files.pythonhosted.org/packages/82/91/01caa13602a2f12fae5edbe8caf78b3c1e6db1293132aee6959eecce095c/ruff-0.15.19-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4171b6613effa9363cd46dd4f75bd1827b6d1b946b5e278ed0c600d305379445", size = 10977610, upload-time = "2026-06-24T01:10:50.892Z" },
|
|
321
|
+
{ url = "https://files.pythonhosted.org/packages/3c/51/acb817922feab9ecbb3201377d4dbe7a25f1395e46545820061973f03468/ruff-0.15.19-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:27c15b2a241dd4d995557949a094fe78b8ad99122a38ccae1595849bcc947b3f", size = 10744900, upload-time = "2026-06-24T01:10:42.726Z" },
|
|
322
|
+
{ url = "https://files.pythonhosted.org/packages/84/bc/5c8ca46b8a7a3f2b16cfbec88721d772b1c93912904e8f8c2e49470fea63/ruff-0.15.19-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ed03b7862d68f0a8771d50ee129980cbf1b113f96e250b73954bc292f689e0bb", size = 11293560, upload-time = "2026-06-24T01:10:21.262Z" },
|
|
323
|
+
{ url = "https://files.pythonhosted.org/packages/81/e0/4a888cbe4d5523b3f77a2b1fa043f46cfeba1b32eac35dcfadee0578fa8a/ruff-0.15.19-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:08143f0685ae278b30727ea72e90c61e5bd9c31b91aac4f5bb989538f73d24b8", size = 11696533, upload-time = "2026-06-24T01:10:53.046Z" },
|
|
324
|
+
{ url = "https://files.pythonhosted.org/packages/98/43/c34b2fcd79262a85161764a97aaca89c3e4f574340ab61430cefa2bdd2c1/ruff-0.15.19-py3-none-win32.whl", hash = "sha256:8f47f0f92952af2557212bb10cf3e695cd4cf28b2c6e42cdb18ec6c9ebfa19da", size = 10986299, upload-time = "2026-06-24T01:10:55.185Z" },
|
|
325
|
+
{ url = "https://files.pythonhosted.org/packages/22/e8/15fd23e02b2442b56b2026b455977bc3057aa34b26e6323d1e99e8531a9f/ruff-0.15.19-py3-none-win_amd64.whl", hash = "sha256:efeca47ee3f9d4a7162655a3b8e6ee4a878646044233978d4d2c1ff8cdd914f0", size = 12123473, upload-time = "2026-06-24T01:10:27.74Z" },
|
|
326
|
+
{ url = "https://files.pythonhosted.org/packages/30/66/9a73695e31eaee04f35d8475998bf8ab354465f9c638936d76111603dcc5/ruff-0.15.19-py3-none-win_arm64.whl", hash = "sha256:6c6b607466e47349332eb1d9be52fb1467423fc07c217341af41cd0f3f0573be", size = 11376779, upload-time = "2026-06-24T01:10:34.465Z" },
|
|
327
|
+
]
|
|
328
|
+
|
|
329
|
+
[[package]]
|
|
330
|
+
name = "typing-extensions"
|
|
331
|
+
version = "4.15.0"
|
|
332
|
+
source = { registry = "https://pypi.org/simple" }
|
|
333
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
|
|
334
|
+
wheels = [
|
|
335
|
+
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
|
336
|
+
]
|
|
337
|
+
|
|
338
|
+
[[package]]
|
|
339
|
+
name = "typing-inspection"
|
|
340
|
+
version = "0.4.2"
|
|
341
|
+
source = { registry = "https://pypi.org/simple" }
|
|
342
|
+
dependencies = [
|
|
343
|
+
{ name = "typing-extensions" },
|
|
344
|
+
]
|
|
345
|
+
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
|
346
|
+
wheels = [
|
|
347
|
+
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
|
348
|
+
]
|