Skip to content

feat(harness): goals dispatcher — autoforge.yml 駆動の non-interactive 実行 (#33 / #30 PR3)#36

Open
k-buchi4696 wants to merge 1 commit into
feature/32-cli-mode-backendfrom
feature/33-goals-dispatch
Open

feat(harness): goals dispatcher — autoforge.yml 駆動の non-interactive 実行 (#33 / #30 PR3)#36
k-buchi4696 wants to merge 1 commit into
feature/32-cli-mode-backendfrom
feature/33-goals-dispatch

Conversation

@k-buchi4696

Copy link
Copy Markdown
Collaborator

Summary

issue #30 を 4 PR で実装する内、PR3 (goals execution flow) に相当(sub-issue #33)。

`autoforge.yml` の `goals` 配列を順次読み、各 goal を agent CLI に prompt として渡して解かせるオーケストレータを実装。`autoforge loop --mode goals --backend codex --dry-run` で「実行されようとする中身」を確認できる。

Stacked on #35 (PR2)。#31#35 → 本 PR の順でマージ予定。

変更内容

新規 `autoforge/harness/goals_runner.py` (~140 行)

  • `Goal` (frozen dataclass): `type`, `description`, `raw`(yaml の元 dict 保持で前方互換)
  • `GoalRunResult` (frozen dataclass): goal + agent_result
  • `load_goals(config_path)`: autoforge.yml の `goals:` を読み、不正 entry はスキップ
  • `build_prompt(goal, repo_dir=None)`: backend 中立 prompt(harness tools の使い方・制約・workflow を含む)
  • `run_goals(goals, backend, *, cwd, timeout, max_goals, dry_run)`: 順次 `run_agent` を呼び結果を返す。1 goal 失敗で残りを継続

`autoforge/cli.py` (+45 行)

  • `loop_parser` に追加: `--dry-run` / `--max-goals` / `--goal-timeout`
  • `_run_loop_goals` を PR2 stub から実機実装に置換: `load_goals` → `run_goals` を実行し `Goals finished: N/M succeeded` を表示

`tests/harness/test_goals_runner.py` (新規 14 件)

  • `TestLoadGoals`: missing file / missing key / well-formed / malformed skip / type default
  • `TestBuildPrompt`: 内容含有 / harness tools 言及 / constraints / repo_dir 反映
  • `TestRunGoals`: 各 goal で run_agent 呼び出し / failure 後継続 / max_goals 切り詰め / dry_run / cwd・timeout 透過

`tests/test_cli.py`

  • 既存 stub-依存テスト 2 件を新形式に更新
  • 新規 2 件: `--dry-run` で run_agent 非呼び出し、`--max-goals 1` で `running 1/3 goal(s)`

Test Plan

  • `pytest tests/harness/test_goals_runner.py tests/test_cli.py -v` — 26 passed
  • `pytest tests/` — 582 passed (PR2 の 566 + 新規 16, pipeline モード回帰なし)
  • レビュアー: 実機で `autoforge loop --mode goals --backend codex --dry-run` が autoforge.yml の goals 数だけ argv 概要を表示すること
  • レビュアー: 実機で `autoforge loop --mode goals --backend codex` を 1 goal だけ走らせて (`--max-goals 1`) agent CLI が起動・進捗ログが出ることを確認

スコープ外

Refs

🤖 Generated with Claude Code

#33 / #30 PR3)

issue #30 の PR3 (goals execution flow) を実装。autoforge.yml の goals 配列を
順次読み、各 goal を agent CLI に prompt として渡して解かせるオーケストレータ。

新規 autoforge/harness/goals_runner.py:
- Goal (frozen dataclass): type, description, raw (yaml の元 dict を保持)
- GoalRunResult (frozen dataclass): goal + agent_result
- load_goals(config_path): autoforge.yml から goals: を読み Goal[] に。
  ファイル無し / goals 無し / 不正 entry はスキップして空 or 部分結果
- build_prompt(goal, repo_dir=None): backend 中立の prompt を生成。harness
  tools の使い方・制約・workflow を含む
- run_goals(goals, backend, *, cwd, timeout, max_goals, dry_run): 順次
  run_agent を呼び GoalRunResult[] を返す。1 goal 失敗で残りを継続。
  dry_run=True で subprocess を呼ばず argv 概要を表示

autoforge/cli.py:
- loop_parser に追加:
  - --dry-run (action store_true)
  - --max-goals (int default 0 = all)
  - --goal-timeout (int default 600)
- _run_loop_goals: PR2 stub を実機実装に置換。autoforge.yml をロードし
  goals_runner.run_goals に dispatch。空 goals の時は instruction を
  表示して return。完了時に Goals finished: N/M succeeded を表示

tests/harness/test_goals_runner.py (新規 14 件):
- TestLoadGoals: missing file / missing key / well-formed / malformed
  entry skip / type default
- TestBuildPrompt: description+type 含む / harness tools 言及 /
  constraints 文言 / repo_dir 反映
- TestRunGoals: 各 goal で run_agent 呼び出し / failure 後継続 /
  max_goals 切り詰め / dry_run で subprocess 非起動 /
  cwd/timeout 透過

tests/test_cli.py:
- 既存 stub-依存テスト 2 件を新形式に更新 (PR2 stub 文字列 → 実機の
  No goals found / Goals finished メッセージ)
- 新規: --dry-run で goals_runner が走り run_agent が呼ばれないこと
- 新規: --max-goals 1 で running 1/3 goal(s) 表示

582 tests pass (既存 566 + 新規 16)。pipeline モード回帰なし。

スコープ外: ドキュメント整備 → PR4 (#34)

Refs #30, #33

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant