Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 46 additions & 29 deletions CHANGELOG.md

Large diffs are not rendered by default.

39 changes: 36 additions & 3 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ sequenceDiagram
| Package | Responsibility | Notable classes |
|---|---|---|
| `webhook/` | Receives GitHub events, verifies the HMAC signature, decides whether an event triggers a review (trigger filters, per-PR pause state, auto-review rate limit), acks slash/mention commands with πŸ‘€, runs the comment commands (`/help`, `/summary`, `/describe`, `/changelog`, `/add-docs`, `/improve`, `/generate-tests`, `/resolve`, `/pause`, `/resume`), and schedules finding-feedback capture on review-thread replies | `WebhookController`, `WebhookVerifier`, `TriggerDetector`, `ReviewTriggerFilter`, `AckReactionService`, `CommentCommandService`, `PrPauseService` |
| `review/` | Orchestrates a review: plans the token budget, calls the AI layer (single-call or map-reduce), maps findings to a risk level and review state, writes the summary comment, optionally labels the PR, answers maintainer replies/mentions in PR threads, and persists maintainer finding feedback (πŸ‘/πŸ‘Ž / reply heuristics) for a future learnings pipeline | `ReviewOrchestrator`, `ReviewDispatcher`, `DiffBudgetPlanner`, `FindingPipeline`, `AutoReviewRateLimiter`, `ReviewDiffFormatter`, `FollowUpAnalyzer`, `FindingFeedbackCaptureService`, `FindingFeedbackService`, `PrSummaryGenerator`, `PrLabeler`, `MaintainerReplyService`, `MaintainerReplyDispatcher` |
| `review/ai/` | The LangChain4j layer: streams or batches model responses, parses findings, runs a second pass to verify them, applies generation/reasoning customizers, and writes conversational replies | `PrReviewer`, `AiReviewService`, `ChatModelCustomizers`, `FindingVerifier`, `FindingVerificationService`, `ReviewResponseParser`, `ReplyAssistant` |
| `github/` | Talks to the GitHub REST and GraphQL APIs: app auth, pull requests, reviews, check runs, comments, labels, reactions (create + list), and reading the repo instructions file | `GitHubAuthClient`, `GitHubReviewClient`, `GitHubCheckRunClient`, `GitHubLabelClient`, `GitHubReactionClient`, `InstructionsResolver` |
| `review/` | Orchestrates a review: plans the token budget and the per-review spend ceiling, calls the AI layer (single-call or map-reduce), maps findings to a risk level and review state, re-checks a maintainer's decline against the reviewed code, writes the summary comment, optionally labels the PR, answers maintainer replies/mentions in PR threads, and persists maintainer finding feedback (πŸ‘/πŸ‘Ž / reply heuristics) for a future learnings pipeline | `ReviewOrchestrator`, `ReviewDispatcher`, `DiffBudgetPlanner`, `FindingPipeline`, `AutoReviewRateLimiter`, `ReviewDiffFormatter`, `FollowUpAnalyzer`, `FindingFeedbackCaptureService`, `FindingFeedbackService`, `PrSummaryGenerator`, `PrLabeler`, `MaintainerReplyService`, `MaintainerReplyDispatcher`, `PrImprovementService`, `PatchCoverage`, `ConfigKeyContextResolver`, `RebuttalContradiction`, `SummarySurfaceDeduplicator`, `VerdictBuilder` |
| `review/ai/` | The LangChain4j layer: streams or batches model responses, parses findings, runs a second pass to verify them, applies generation/reasoning customizers, and writes conversational replies | `PrReviewer`, `AiReviewService`, `ChatModelCustomizers`, `FindingVerifier`, `FindingVerificationService`, `ReviewResponseParser`, `ReplyAssistant`, `TruncatedResponseSalvager`, `FindingVerifierPrompts` |
| `github/` | Talks to the GitHub REST and GraphQL APIs: app auth, pull requests, reviews, check runs, comments, labels, reactions (create + list), and reading the repo instructions file | `GitHubAuthClient`, `GitHubReviewClient`, `GitHubCheckRunClient`, `GitHubLabelClient`, `GitHubReactionClient`, `InstructionsResolver`, `GitHubWriteRetry` |
| `dashboard/` | The live UI backend: OAuth login (in-memory sessions), WebSocket broadcaster (`review.stream` / `review.batch`), review session persistence, and finding-feedback aggregates | `AuthResource`, `DashboardSessionStore`, `SessionEventBroadcaster`, `ReviewSessionRepository`, `DashboardResource` |
| `config/` | Wiring: the outbound HTTP client, the review thread pool, typed config, active-model settings (caps, generation params), fail-fast startup validation, and the shared bot-identity used to recognize the bot's own activity | `HttpClientProducer`, `ReviewExecutorProducer`, `ThrillhouseConfig`, `ActiveModelSettings`, `StartupConfigValidator`, `BotIdentity` |
| `frontend/` | The Next.js dashboard, built to a static export and served by Quarkus | β€” |
Expand All @@ -232,6 +232,39 @@ dashboard; they emit `review.batch` progress events instead. Batches run
concurrently on virtual threads; a failed batch is retried once after the
parallel pass completes.

**Cost ceiling** β€” `REVIEW_MAX_TOKENS_PER_REVIEW` bounds the tokens one review may
spend across every call it makes, counting retries, the verifier and the summary.
Once reached, remaining batches are disclosed as not reviewed by name and the
summary degrades to counts rather than making further calls. `0`, the default,
leaves it unbounded. The summary, the verifier and maintainer replies run on a
separate `concise` model binding with its own response cap
(`REVIEW_CONCISE_MAX_OUTPUT_TOKENS`) and its own reasoning effort, so they never
share a cap sized for batch review output.

**Coverage honesty** β€” a file the review never read does not pass silently. A
file GitHub reported with changes but no patch text, a file that did not fit any
batch, and a file whose batch call failed are each disclosed by name and withhold
APPROVE. A response the model cut at its length cap keeps the findings that
completed before the cut rather than being discarded whole.

**Patch coverage as review context** β€” when a PR's CI publishes a coverage
report, `PatchCoverage` reads the changed lines it does not cover and gives them
to the review, so new code with no test behind it can be named as such. Off
unless `REVIEW_PATCH_COVERAGE_ENABLED` is set.

**Repository-supplied configuration** β€” `.github/thrillhousebot.yml` carries a
repository's own ignore globs and path-scoped review instructions, read from the
default branch and cached for five minutes. Ignore globs are additive to the
deployment list; a repository can narrow its own review scope but cannot restore
a file the deployment excludes. Every failure mode (missing file, invalid YAML,
unexpected shape, uncompilable glob) is logged and skipped, leaving the
deployment configuration in force.

**Write pacing** β€” content-creating GitHub calls are spaced process-wide by
`GITHUB_WRITE_MIN_INTERVAL` so a burst of comments never reaches the secondary
rate limit in the first place, with `GITHUB_WRITE_MAX_WAIT` capping how long any
one caller waits.

Each AI call is bounded by `AI_TIMEOUT` (LangChain4j) and
`thrillhousebot.review.ai-timeout-seconds`. Cost and token metrics come from
OpenTelemetry. OAuth login sessions are opaque IDs in cookies with tokens kept
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<groupId>dev.thiagogonzaga.thrillhousebot</groupId>
<artifactId>thrillhousebot</artifactId>
<version>0.5.1-SNAPSHOT</version>
<version>0.6.0</version>

<properties>
<compiler-plugin.version>3.15.0</compiler-plugin.version>
Expand Down
5 changes: 3 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,9 @@ thrillhousebot.review.token-safety-margin=${REVIEW_TOKEN_SAFETY_MARGIN:0.9}
# max-ai-calls only counts planned calls. Once reached, remaining batches are disclosed as not
# reviewed and the summary degrades to counts-only rather than making further calls. 0 = off.
thrillhousebot.review.max-tokens-per-review=${REVIEW_MAX_TOKENS_PER_REVIEW:0}
# Line cap on single-call renders (/describe, /changelog, /add-docs, replies, base comparison,
# budgeting-disabled review). Token-budgeted review calls ignore it; 0 = off (unbounded).
# Line cap on single-call renders (replies, base comparison, budgeting-disabled review).
# Token-budgeted reviews and the batched commands (/improve, /describe, /changelog,
# /generate-tests, /add-docs) ignore it; 0 = off (unbounded).
thrillhousebot.review.max-diff-lines=${REVIEW_MAX_DIFF_LINES:5000}
thrillhousebot.review.instructions-file=.github/thrillhousebot.md
# Second-pass AI audit that drops/downgrades unverifiable findings before they are posted
Expand Down
Binary file added website/src/assets/0.5.0/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/src/assets/0.5.0/live-streaming.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/src/assets/0.5.0/pr-approval.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading