Repository navigation
Fit oversized PR diffs to the LLM review token budget - #280
Merged
Merged
Conversation
Very large import PRs crash the LLM review outright: on #278 (and #124 before it) the 3.1M-char diff hit OpenAI's 922k input-token limit (BadRequestError at 1.56M tokens), so the review gate never ran. Instead of crashing, review.py now fits the diff to a budget first: - Estimate tokens up front at 2.0 chars/token — the worst density actually measured (on #278's machine-generated interval arithmetic; ordinary Lean runs ~4) — against an 800k-token budget. - When over budget, elide the largest per-file patch bodies first, keeping every file's path, patch line counts, and opening lines (for added Lean files: the module docstring and imports). Falls back to smaller heads, then a hard tail cut, so a fit always exists. - Tell the model about the elisions, and prepend a clear partial-review notice to the posted comment. The sticky marker, comment format, and head-SHA keying are unchanged, as are all gating semantics. - If the API still rejects the input as too large (the estimate is approximate by nature), halve the budget, refit, and retry. Replayed on #278's actual diff: 43 of 317 file bodies elided, 3.11M -> 1.57M chars, projecting to ~789k input tokens at that PR's measured density — under the limit, with the other 274 files reviewed in full. The competing per-file openai stubs in tests (whichever test module loaded first won setdefault, and the triage one lacked BadRequestError) are consolidated into one canonical stub in tests/conftest.py that mirrors the real exception hierarchy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The LLM review workflow dies on very large PRs: on #278 (73k-line import)
lean_pool.review.request_reviewcrashed withso the PR's review gate never ran. #124 hit the same failure earlier.
review.pysent the whole diff unconditionally.Fix
review.pynow fits the diff to a token budget before calling the model, and degrades gracefully instead of crashing:[elided by lean-pool llm-review: N of M patch lines omitted …]markers, keeping every file's path, patch line counts, and opening lines (for added Lean files that's the copyright header, module docstring, and imports — the most review-relevant part). If eliding everything still overflows it refits with minimal heads, then hard-cuts the tail as a guaranteed last resort.## Diff size noticesection tells the model what was elided (and to say so in its summary), and the posted comment gets a deterministic> ⚠️ Partial review — diff exceeded the size budgetbanner.Contract intact: sticky
<!-- lean-pool-llm-review -->marker, comment format (unchanged byte-for-byte when no truncation), and**Reviewed head:**SHA keying are untouched; no gating semantics change and.github/workflows/llm-review.ymlis not modified. Infra-only — touchespython/exclusively.Validation
Replayed the production fit on #278's actual diff: 43 of 317 file bodies elided, 3.11M → 1.57M chars, projecting to ~789k input tokens at that PR's measured density — under the 922k limit, with the other 274 files still reviewed in full and all 317 paths visible.
Tests: 7 new pytest cases (untouched-under-budget, largest-first elision with path/head/count preservation, hard-truncate backstop, overflow→refit retry against a fake client, unrelated-400 re-raise, comment banner, no banner when untruncated). Enabling them surfaced that
tests/test_review.pyandtests/aggregator/test_triage.pyeach registered a competingopenaistub viasys.modules.setdefault— whichever loaded first won, and the triage one lackedBadRequestError— so the stub is consolidated into one canonicaltests/conftest.pymirroring the real exception hierarchy.uv run ruff check,uv run ruff format, anduv run --group test pytestall pass (186 tests).🤖 Generated with Claude Code