Skip to content

feat(budget): env-driven defaults for review reasoner caps#17

Merged
AbirAbbas merged 1 commit into
mainfrom
feat/env-driven-budget-defaults
May 5, 2026
Merged

feat(budget): env-driven defaults for review reasoner caps#17
AbirAbbas merged 1 commit into
mainfrom
feat/env-driven-budget-defaults

Conversation

@AbirAbbas
Copy link
Copy Markdown
Contributor

Summary

The review reasoner had hard-coded max_duration_seconds=300 (5 min) and max_cost_usd=2.0 defaults. On the Railway test deployment, this fires BudgetExhaustedError("Budget exhausted before meta-selectors") ~6 minutes into every real PR review — the docs themselves say a 500-line PR takes 35–50 min, so 300s never had a chance.

Upstream callers (e.g. github-buddy) intentionally don't thread budget overrides through app.call("pr-af.review", ...) (its CLAUDE.md explicitly forbids it), so deployments currently have no way to lift the caps without editing this repo's source.

This PR makes the three budget defaults read from env at module load:

  • PR_AF_NO_BUDGET (bool, default false) — when true, disables all cost/duration enforcement.
  • PR_AF_MAX_DURATION_SECONDS (int, default 300) — wall-clock cap.
  • PR_AF_MAX_COST_USD (float, default 2.0) — global cost cap.

Hard-coded fallbacks preserve current behavior for callers that don't set the env. The BudgetConfig.no_budget short-circuit in _budget_or_timeout_exhausted already exists — this just lets a deployment flip it.

How this resolves the Railway hang

A real review on the deployment now needs PR_AF_NO_BUDGET=true (recommended) or PR_AF_MAX_DURATION_SECONDS=1800 set on the pr-af service env. Combined with the underlying error-propagation fix in agentfield (separate PR), the 9+ hour "running" UI state goes away.

Test plan

  • python3 -m py_compile src/pr_af/app.py (done locally — passes).
  • Run a review with PR_AF_NO_BUDGET=true set in the deployment env and confirm meta-selectors complete.
  • Run a review without the env set and confirm the prior 300s/$2 behavior is unchanged (i.e. BudgetExhaustedError still fires for callers depending on it).
  • Smoke: app.call("pr-af.review", pr_url=..., max_duration_seconds=600) still wins over the env default (kwargs always override).

🤖 Generated with Claude Code

The review reasoner had hard-coded 300s wall-clock and $2 cost caps that
fire as `BudgetExhaustedError("Budget exhausted before meta-selectors")`
on real-world PRs (the docs say a 500-line PR takes 35–50min — 300s
never had a chance). Callers like github-buddy intentionally don't
thread budget overrides through `app.call`, so deployments had no way
to retune without a code change.

Read the defaults from env (PR_AF_NO_BUDGET, PR_AF_MAX_DURATION_SECONDS,
PR_AF_MAX_COST_USD) at module load. Hard-coded fallbacks preserve the
prior behavior for callers that don't set the env. Setting
PR_AF_NO_BUDGET=true on a deployment disables enforcement entirely
(the existing `no_budget` short-circuit in BudgetConfig).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AbirAbbas AbirAbbas merged commit afd1f37 into main May 5, 2026
2 checks passed
@AbirAbbas AbirAbbas deleted the feat/env-driven-budget-defaults branch May 5, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant