opencode-config/docs/decisions/029-pr-69-agent-steps-150.md
Sergey 063044450f
feat(agents): increase step limit to 150 (#69)
* feat(agents): increase step limit to 150

* test(agents): update step limit assertions to 150

* docs(adr): add ADR-029 agent step limit 100 to 150

* docs(project-map): update tree with PR#68 changes

* docs(handoff): add PR 69 handoff for agent steps 150

* docs(project-map): fix PR tags to PR#69 (actual PR number)

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-26 01:19:17 +03:00

3.7 KiB
Raw Permalink Blame History

ADR-029: Agent step limit 100 → 150

Статус: Accepted (2026-07-25, PR 69)

Контекст

На PR#67 reviewer subagent упёрся в MAXIMUM STEPS REACHED — не успел вызвать post-review (оркестратор делал 1 retry вручную). Сообщение хардкожено в opencode.exe (бинарник от 2026-07-24): при iteration_count >= agent.steps вызывается failUnsettledTools("Tools are disabled after the maximum agent steps") → tools disabled. Это hard stop, не soft hint.

Memory technical/opencode-log-subagent-stumbles-analysis.md (2026-07-20) утверждала «steps: НЕ хард-лимит — агенты routinely превышают. Это hint, не enforcement». Устарело: бинарник 2026-07-24 уже hard enforcement. Подтверждено на PR#67.

ADR-020 (PR#49) унифицировал лимит до 100 для всех 4 настроенных агентов (reviewer, docs-reviewer, memory-syncer, general) как guard против doom loops. Исторически было 40/25/15/100 — но это были soft hints, превышались routinely (general до 216, reviewer до 80, docs-reviewer до 93). Сейчас 100 — hard stop, и 100 оказалось тесно для reviewer на PR с 6+ файлами diff.

Текущие значения: reviewer.md:5, docs-reviewer.md:5, memory-syncer.md:5 — frontmatter steps: 100; opencode.json:319agent.general.steps: 100. Тест test_agent_frontmatter.py:154 pin'ит fm["steps"] == "100" для всех 3 .md (uniformity). Тест test_permissions.py:119 pin'ит general.steps == 100 (int, JSON).

Решение

Повысить лимит шагов subagent-ов со 100 до 150 для всех 4 настроенных агентов (reviewer, docs-reviewer, memory-syncer, general). Uniformity сохранена (ADR-020 principle) — memory-syncer безвредно получит 150 (редко доходит до лимита, задача простая). Trade-off: +50% budget → +50% doom-loop risk, но guard сохранён. Без архитектурного рефакторинга (вынос explore-фазы reviewer'а в отдельный explore subagent) — отложено в отдельный PR если 150 снова станет тесно.

Soft Investigation Budget в reviewer.md:103-108 (~15 шагов) остаётся рекомендацией, hard limit 150 — guard.

Тесты обновлены: test_steps_100_presenttest_steps_150_present, assertion fm["steps"] == "150", test_permissions.py assertion general.steps == 150.

Альтернативы

  • 200/300 — отклонено: избыточный doom-loop риск, +100%/+200% budget без явной необходимости.
  • ∞ (убрать лимит) — отклонено: нет guard'а вообще, doom loop может длиться часами (контр-показания из memory opencode-log-subagent-stumbles-analysis.md).
  • Рефакторинг (вынос explore-фазы reviewer'а в отдельный explore subagent с ∞ steps) — отклонено в этом PR: scope creep. Отдельный PR если 150 снова станет тесно.
  • Per-agent разные значения (нарушить uniformity) — отклонено: ADR-020 principle — uniformity упрощает тестирование и reasoning. memory-syncer мог бы остаться на 100, но это усложнило бы тест (per-agent expected map) без выгоды.