diff --git a/src/hyrule_engineering_loop/cli.py b/src/hyrule_engineering_loop/cli.py index 30aec4e..01245dd 100644 --- a/src/hyrule_engineering_loop/cli.py +++ b/src/hyrule_engineering_loop/cli.py @@ -475,6 +475,8 @@ def daemon_command(args: argparse.Namespace) -> int: memory_dir=args.memory_dir, max_runs_per_day=args.max_runs_per_day, max_cost_usd_per_day=args.max_cost_usd_per_day, + max_iterations_per_run=args.max_iterations_per_run, + max_wall_clock_minutes_per_run=args.max_wall_clock_minutes_per_run, allowed_paths_by_repo={ repo: tuple(prefixes) for repo, prefixes in _parse_repo_paths(args.allow, option="--allow").items() @@ -832,6 +834,12 @@ def build_parser() -> argparse.ArgumentParser: daemon_parser.add_argument( "--max-cost-usd-per-day", type=float, default=DaemonConfig.max_cost_usd_per_day ) + daemon_parser.add_argument( + "--max-iterations-per-run", type=int, default=DaemonConfig.max_iterations_per_run + ) + daemon_parser.add_argument( + "--max-wall-clock-minutes-per-run", type=int, default=DaemonConfig.max_wall_clock_minutes_per_run + ) daemon_parser.add_argument( "--allow", action="append", diff --git a/tests/test_phase24_daemon.py b/tests/test_phase24_daemon.py index 8ad4e4f..c1c58df 100644 --- a/tests/test_phase24_daemon.py +++ b/tests/test_phase24_daemon.py @@ -20,6 +20,7 @@ notify_icinga, repo_name_for_issue, ) +from hyrule_engineering_loop.cli import build_parser from hyrule_engineering_loop.intake import IntakeItem from hyrule_engineering_loop.nodes import STALL_ROUND_LIMIT, delegate_implementation_node from hyrule_engineering_loop.promotion import rollback_promotions, setup_worktrees_for_state @@ -195,6 +196,20 @@ def test_idle_queue_reports_idle(tmp_path: Path) -> None: assert report.outcome == "idle" +def test_daemon_cli_per_run_budget_flags() -> None: + parser = build_parser() + # Defaults match the conservative DaemonConfig values. + default_args = parser.parse_args(["daemon", "--once"]) + assert default_args.max_iterations_per_run == DaemonConfig.max_iterations_per_run + assert default_args.max_wall_clock_minutes_per_run == DaemonConfig.max_wall_clock_minutes_per_run + # Overridable for a one-off larger run. + args = parser.parse_args( + ["daemon", "--once", "--max-iterations-per-run", "40", "--max-wall-clock-minutes-per-run", "90"] + ) + assert args.max_iterations_per_run == 40 + assert args.max_wall_clock_minutes_per_run == 90 + + def test_daemon_defaults_to_core_repos_and_low_and_slow_budget() -> None: config = DaemonConfig() assert config.repos == CORE_REPOS