feat: bootstrap artifact loop engine package

This commit is contained in:
sladro 2026-04-02 11:10:28 +08:00
parent 2968ec63a9
commit 726e512603
5 changed files with 173 additions and 0 deletions

27
engine/__init__.py Normal file
View File

@ -0,0 +1,27 @@
from .models import (
ArtifactsConfig,
BudgetConfig,
ConstraintConfig,
LoggingConfig,
MutationConfig,
ObjectiveConfig,
PolicyConfig,
RunnerConfig,
ScorerConfig,
ScorerParseConfig,
TaskConfig,
)
__all__ = [
"ArtifactsConfig",
"BudgetConfig",
"ConstraintConfig",
"LoggingConfig",
"MutationConfig",
"ObjectiveConfig",
"PolicyConfig",
"RunnerConfig",
"ScorerConfig",
"ScorerParseConfig",
"TaskConfig",
]

84
engine/models.py Normal file
View File

@ -0,0 +1,84 @@
from dataclasses import dataclass, field
from typing import Literal
@dataclass(frozen=True)
class ArtifactsConfig:
include: list[str] = field(default_factory=list)
exclude: list[str] = field(default_factory=list)
max_files_per_iteration: int = 0
@dataclass(frozen=True)
class MutationConfig:
mode: str = ""
allowed_file_types: list[str] = field(default_factory=list)
max_changed_lines: int = 0
@dataclass(frozen=True)
class RunnerConfig:
command: str = ""
cwd: str = "."
timeout_seconds: int = 0
@dataclass(frozen=True)
class ScorerParseConfig:
format: str = ""
score_field: str = ""
metrics_field: str = ""
@dataclass(frozen=True)
class ScorerConfig:
type: str = ""
command: str = ""
parse: ScorerParseConfig = field(default_factory=ScorerParseConfig)
@dataclass(frozen=True)
class ObjectiveConfig:
primary_metric: str = ""
direction: Literal["maximize", "minimize"] = "maximize"
@dataclass(frozen=True)
class ConstraintConfig:
metric: str = ""
op: str = ""
value: int | float = 0
@dataclass(frozen=True)
class PolicyConfig:
keep_if: str = ""
tie_breakers: list[str] = field(default_factory=list)
on_failure: str = ""
@dataclass(frozen=True)
class BudgetConfig:
max_iterations: int = 0
max_failures: int = 0
@dataclass(frozen=True)
class LoggingConfig:
results_file: str = ""
candidate_dir: str = ""
@dataclass(frozen=True)
class TaskConfig:
id: str = ""
description: str = ""
artifacts: ArtifactsConfig = field(default_factory=ArtifactsConfig)
mutation: MutationConfig = field(default_factory=MutationConfig)
runner: RunnerConfig = field(default_factory=RunnerConfig)
scorer: ScorerConfig = field(default_factory=ScorerConfig)
objective: ObjectiveConfig = field(default_factory=ObjectiveConfig)
constraints: list[ConstraintConfig] = field(default_factory=list)
policy: PolicyConfig = field(default_factory=PolicyConfig)
budget: BudgetConfig = field(default_factory=BudgetConfig)
logging: LoggingConfig = field(default_factory=LoggingConfig)

View File

@ -11,6 +11,7 @@ dependencies = [
"pandas>=2.3.3",
"pyarrow>=21.0.0",
"requests>=2.32.0",
"PyYAML>=6.0.2",
"rustbpe>=0.1.0",
"tiktoken>=0.11.0",
"torch==2.9.1",

1
tests/__init__.py Normal file
View File

@ -0,0 +1 @@

60
tests/test_task_loader.py Normal file
View File

@ -0,0 +1,60 @@
from pathlib import Path
import tempfile
import unittest
from engine.task_loader import load_task
class TaskLoaderSmokeTest(unittest.TestCase):
def test_loads_minimal_task(self) -> None:
task_yaml = """
id: demo
description: Demo task
artifacts:
include:
- tasks/demo/sample.txt
exclude: []
max_files_per_iteration: 1
mutation:
mode: direct_edit
allowed_file_types: [".txt"]
max_changed_lines: 10
runner:
command: "python -c \\\"print('run')\\\""
cwd: "."
timeout_seconds: 10
scorer:
type: command
command: "python -c \\\"import json; print(json.dumps({'score': 1, 'metrics': {'violation_count': 0}}))\\\""
parse:
format: json
score_field: "score"
metrics_field: "metrics"
objective:
primary_metric: score
direction: maximize
constraints:
- metric: violation_count
op: "<="
value: 0
policy:
keep_if: better_primary
tie_breakers: []
on_failure: discard
budget:
max_iterations: 3
max_failures: 1
logging:
results_file: work/results.jsonl
candidate_dir: work/candidates
"""
with tempfile.TemporaryDirectory() as tmp:
task_path = Path(tmp) / "task.yaml"
task_path.write_text(task_yaml, encoding="utf-8")
task = load_task(task_path)
self.assertEqual(task.id, "demo")
self.assertEqual(task.objective.direction, "maximize")
if __name__ == "__main__":
unittest.main()