Skip to content

Configuration reference

Every setting the bot reads, with the environment variable that sets it. A row shows the short alias application.properties defines for it where there is one; every thrillhousebot.* key also accepts its standard Quarkus name (the key in uppercase with each . and - replaced by _), which overrides the alias. What the features do is described in the README's Configuration section.

Durations take Quarkus' format (10s, 5m, 24h, or an ISO-8601 value such as PT1M). A list is comma-separated.

These variables set Quarkus and LangChain4j keys rather than a thrillhousebot.* key.

VariableDescriptionDefaultSets
AI_API_KEYAPI key for the AI provider. Required.(none)quarkus.langchain4j.openai.api-key
quarkus.langchain4j.openai.concise.api-key
AI_BASE_URLOpenAI-compatible base URL of the AI provider.https://api.deepseek.com/v1quarkus.langchain4j.openai.base-url
quarkus.langchain4j.openai.concise.base-url
AI_MODELChat model name. It also selects the model's entry in the per-model settings and the pricing map.deepseek-chatquarkus.langchain4j.openai.chat-model.model-name
quarkus.langchain4j.openai.concise.chat-model.model-name
AI_TIMEOUTPer-request timeout of an AI call.300squarkus.langchain4j.openai.timeout
quarkus.langchain4j.openai.concise.timeout
DATABASE_URLJDBC URL of the production database (jdbc:postgresql://db:5432/thrillhouse in Docker Compose).%prod: jdbc:postgresql://localhost:5432/thrillhousequarkus.datasource.jdbc.url
DATASOURCE_DB_KINDh2 or postgresql. Quarkus fixes this at build time, so released images are PostgreSQL builds and ignore h2.h2; %prod: postgresqlquarkus.datasource.db-kind
DS_INPUT_PRICEPrice of 1,000 input tokens on deepseek-chat, in US dollars.0.00014thrillhousebot.ai.pricing.deepseek-chat.input-per-1k
DS_OUTPUT_PRICEPrice of 1,000 output tokens on deepseek-chat, in US dollars.0.00028thrillhousebot.ai.pricing.deepseek-chat.output-per-1k
OTEL_EXPORTER_ENDPOINTOTLP endpoint traces, metrics and logs are exported to.http://localhost:4317quarkus.otel.exporter.otlp.endpoint
OTEL_EXPORTER_TIMEOUTHow long one OTLP export may wait for the collector. Keep it above the collector's 60-second HTTP/2 keep-alive: below it, an export after an idle pause can be sent twice.65squarkus.otel.exporter.otlp.traces.timeout
quarkus.otel.exporter.otlp.metrics.timeout
quarkus.otel.exporter.otlp.logs.timeout
OTEL_HTTP_SERVER_METRICS_ENABLEDRecord Quarkus's HTTP server metrics (http.server.request.duration), exported over OTLP and served on /metrics.truequarkus.otel.instrument.http-server-metrics
OTEL_JVM_METRICS_ENABLEDRecord Quarkus's JVM metrics (jvm.*), exported over OTLP and served on /metrics.truequarkus.otel.instrument.jvm-metrics
OTEL_LOGS_ENABLEDAlso export the bot's log records over OTLP, beside the console. Off by default, so a collector does not start receiving every log line without an opt-in.falsequarkus.otel.logs.handler.enabled
OTEL_SDK_DISABLEDTurn telemetry off: nothing is exported over OTLP and the Prometheus endpoint answers 404.falsequarkus.otel.sdk.disabled
PORTHTTP port the bot listens on (webhooks, dashboard, health and metrics).8080quarkus.http.port
REVIEW_CONCISE_MAX_OUTPUT_TOKENSResponse cap (max_tokens) for the calls on the concise model: the summary call, the verifier and replies. A summary cut at this cap is salvaged or replaced by a counts-only summary, and the findings are kept. Set it empty to send no cap.8192quarkus.langchain4j.openai.concise.chat-model.max-tokens
VariableDescriptionTypeDefault
HTTP_CONNECT_TIMEOUT
thrillhousebot.http-connect-timeout
Outbound HTTP connect timeout (GitHub API, OAuth).duration10s
HTTP_REQUEST_TIMEOUT
thrillhousebot.http-request-timeout
Outbound HTTP request timeout (GitHub API, OAuth).duration10s
WEBSOCKET_KEEPALIVE_MS
thrillhousebot.websocket-keepalive-ms
Dashboard WebSocket keepalive in milliseconds, so reverse proxies do not close idle connections. 0 or less disables it and stale replay-buffer eviction.integer25000
VariableDescriptionTypeDefault
(follows quarkus.langchain4j.openai.base-url)
thrillhousebot.ai.base-url
The AI base URL, read from AI_BASE_URL; used to derive the telemetry provider when AI_PROVIDER is unset. Set AI_BASE_URL rather than this key.stringhttps://api.deepseek.com/v1
AI_MAX_CONCURRENT_CALLS
thrillhousebot.ai.max-concurrent-calls
Most model calls in flight at once across the process (review batches, summaries, the verifier, replies and commands). A call past it waits for a slot, up to THRILLHOUSEBOT_REVIEW_AI_TIMEOUT_SECONDS, and a wait over 5 seconds is logged at INFO. A provider's rate-limit or concurrent-slot refusal is retried after 30 seconds either way. 0 means no limit.integer0
AI_PROVIDER
thrillhousebot.ai.provider-name
Provider label for telemetry (gen_ai.provider.name); derived from AI_BASE_URL when unset.string(none)

Model-specific settings, keyed by the model name (the AI_MODEL value). Only the active model's entry is read, so you can keep entries for several models and switch AI_MODEL freely. Quote a model name that contains . or / (thrillhousebot.ai.models."gpt-5.5".max-input-tokens). From the environment, hyphen-only names use underscores (THRILLHOUSEBOT_AI_MODELS_DEEPSEEK_V4_PRO_MAX_INPUT_TOKENS=1000000) and dotted names the quoted form (THRILLHOUSEBOT_AI_MODELS__GPT_5_5__MAX_INPUT_TOKENS=256000); either needs an empty max-input-tokens= line for that model in application.properties, which ships one for the models it knows. See Per-model AI settings.

VariableDescriptionTypeDefault
THRILLHOUSEBOT_AI_MODELS_<MODEL>_CONTEXT_TOKENS
thrillhousebot.ai.models.<model>.context-tokens
The model's total context window. On a shared window the prompt and the completion are both charged to it, so boot fails when max-input-tokens + max-output-tokens does not fit inside it, or when the effective budget plus the largest response cap in play (max-output-tokens or REVIEW_CONCISE_MAX_OUTPUT_TOKENS) does not. Unset, the ceiling is not checked.integer(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_FREQUENCY_PENALTY
thrillhousebot.ai.models.<model>.frequency-penalty
frequency_penalty sent on every chat call, in [-2, 2]. Positive values discourage repeating tokens in proportion to how often they already appeared. Unset keeps the provider default.number(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_MAX_INPUT_TOKENS
thrillhousebot.ai.models.<model>.max-input-tokens
Input-token cap for this model. The effective review budget is the smaller of REVIEW_MAX_INPUT_TOKENS and this cap; a model without one gets 128000. It is a cap, not the budget: to go beyond it on a large-context model, raise both. Startup logs a warning when the cap lowers the budget.integer(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_MAX_OUTPUT_TOKENS
thrillhousebot.ai.models.<model>.max-output-tokens
Response cap (max_tokens) sent on the review call and the command generators. output-buffer-tokens only reserves room in the input budget, so set both when you cap output. Unset leaves the provider default.integer(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_OUTPUT_BUFFER_TOKENS
thrillhousebot.ai.models.<model>.output-buffer-tokens
This model's REVIEW_OUTPUT_BUFFER_TOKENS: tokens reserved from the input budget for the response. On a shared window it must be at least max-output-tokens, or boot fails. Ignored with separate-output-budget set.integer(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_PRESENCE_PENALTY
thrillhousebot.ai.models.<model>.presence-penalty
presence_penalty sent on every chat call, in [-2, 2]. Positive values discourage repeating any token that already appeared. Unset keeps the provider default.number(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_SEED
thrillhousebot.ai.models.<model>.seed
seed sent on every chat call, asking for repeatable sampling on providers that support it; others ignore it. For steadier reviews, lower temperature first. Unset sends no seed.integer(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_SEPARATE_OUTPUT_BUDGET
thrillhousebot.ai.models.<model>.separate-output-budget
Set true only when the provider bills the response outside the context window (1M in with 384K out on top, rather than 384K carved out of the 1M). It switches off both the output-buffer-tokens reservation and the context-tokens ceiling. Getting it wrong is costly either way; check the provider's documented window first.boolean(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_TEMPERATURE
thrillhousebot.ai.models.<model>.temperature
Sampling temperature sent on every chat call, in [0, 2]. Unset keeps the default (1.0).number(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_TOKEN_SAFETY_MARGIN
thrillhousebot.ai.models.<model>.token-safety-margin
This model's REVIEW_TOKEN_SAFETY_MARGIN: the fraction of the input budget actually used, to absorb token-estimate error.number(none)
THRILLHOUSEBOT_AI_MODELS_<MODEL>_TOP_P
thrillhousebot.ai.models.<model>.top-p
Nucleus-sampling top_p sent on every chat call, in (0, 1]. Unset keeps the default (1.0). top_k is not part of the OpenAI-compatible API, so it cannot be set.number(none)

Prices used for cost tracking, keyed by model name (the AI_MODEL value) like the per-model settings. application.properties ships prices for the models it knows. When you change AI_MODEL, add a matching pair; without one, tokens are still recorded and the model's sessions are flagged "no pricing" in the dashboard instead of showing $0.

VariableDescriptionTypeDefault
THRILLHOUSEBOT_AI_PRICING_<MODEL>_INPUT_PER_1K
thrillhousebot.ai.pricing.<model>.input-per-1k
Price of 1,000 input tokens, in US dollars.number(none)
THRILLHOUSEBOT_AI_PRICING_<MODEL>_OUTPUT_PER_1K
thrillhousebot.ai.pricing.<model>.output-per-1k
Price of 1,000 output tokens, in US dollars.number(none)
VariableDescriptionTypeDefault
AI_REASONING_EFFORT_CONCISE
thrillhousebot.ai.reasoning.concise-effort
Effort for the calls on the concise model (summary, verifier, replies), which do not follow AI_REASONING_EFFORT. Same values. Unset means low, or AI_REASONING_EFFORT when that is lower.string(none)
AI_REASONING_EFFORT
thrillhousebot.ai.reasoning.effort
Effort for the review and the on-demand commands: none, low, medium, high, xhigh or max. Reasoning tokens are billed as output. A provider that does not know a tier rejects the call. See Per-model AI settings.stringlow
AI_REASONING_ENABLED
thrillhousebot.ai.reasoning.enabled
Send a reasoning-effort hint (reasoning_effort). When false, no reasoning parameter is sent and the provider default applies, except on the one repeat of a call that spent its whole output cap reasoning, which sends the lane's effort.booleanfalse
AI_REASONING_REPEAT_EFFORT
thrillhousebot.ai.reasoning.repeat-effort
Effort for the one repeat of a call that stopped at its response cap with no content, its reasoning having spent the whole allowance (#839). Same values. Unset means low while reasoning is enabled, with no repeat on a lane that already sends low or none; while it is off, the lane's effort as it would go out enabled. A value equal to what the first call sent makes no repeat.string(none)
VariableDescriptionTypeDefault
AI_FALLBACK_MODEL
thrillhousebot.ai.routing.fallback-model
Secondary model for the streamed review and summary calls. When an attempt fails with a provider error (HTTP 5xx, an unknown model) or a rate limit, the call's remaining retries go to this model instead. Unset keeps every retry on the first model.string(none)
AI_ROUTING_HIGH_RISK_PATHS
thrillhousebot.ai.routing.high-risk-paths
Comma-separated gitignore-style globs of high-risk files, under the new or the old name of a renamed file. A pull request touching one is never routed to the low-risk model, however small it is and even when the file also matches AI_ROUTING_LOW_RISK_PATHS.list.github/workflows/, **/*.sql, **/migrations/, **/auth/, **/security/, **/Dockerfile
AI_ROUTING_LOW_RISK_MAX_CHANGED_LINES
thrillhousebot.ai.routing.low-risk-max-changed-lines
Most changed lines (additions plus deletions over the reviewable files) a pull request may have to count as low risk by size. 0 routes by paths alone; a negative value is rejected at boot.integer100
AI_ROUTING_LOW_RISK_MODEL
thrillhousebot.ai.routing.low-risk-model
Cheaper model for low-risk pull requests: those that touch no AI_ROUTING_HIGH_RISK_PATHS file and either have every reviewable file matching AI_ROUTING_LOW_RISK_PATHS or change at most AI_ROUTING_LOW_RISK_MAX_CHANGED_LINES lines. Only the review calls are routed; the summary call, the verifier and the commands keep their own models. Unset turns routing off.string(none)
AI_ROUTING_LOW_RISK_PATHS
thrillhousebot.ai.routing.low-risk-paths
Comma-separated gitignore-style globs of low-risk files (docs, text, lockfiles). A pull request whose every reviewable file matches is routed to AI_ROUTING_LOW_RISK_MODEL whatever its size, unless one of them also matches AI_ROUTING_HIGH_RISK_PATHS. Same pattern syntax as THRILLHOUSEBOT_REVIEW_IGNORED_FILES.list**/*.md, **/*.mdx, **/*.rst, **/*.txt, **/*.adoc, docs/, **/*.lock, **/go.sum
VariableDescriptionTypeDefault
THRILLHOUSEBOT_DASHBOARD_GITHUB_ACCOUNT_OWNER
thrillhousebot.dashboard.github.account-owner
Optional. When set, the dashboard serves only the installation on this account. Unset serves every installation the signed-in user can access. Either way a user sees only the repositories GitHub lets them read.string(none)
GITHUB_CLIENT_ID
thrillhousebot.dashboard.github.client-id
OAuth client ID for dashboard login, from the GitHub App's settings. Leave it and GITHUB_CLIENT_SECRET unset to disable login.string(none)
GITHUB_CLIENT_SECRET
thrillhousebot.dashboard.github.client-secret
OAuth client secret for dashboard login, from the GitHub App's settings.string(none)
GITHUB_OAUTH_URL
thrillhousebot.dashboard.github.oauth-url
Base URL of GitHub's OAuth endpoints.stringhttps://github.com/login/oauth
THRILLHOUSEBOT_DASHBOARD_GITHUB_REDIRECT_URI
thrillhousebot.dashboard.github.redirect-uri
OAuth callback URL registered on the GitHub App; follows DASHBOARD_URL.string${DASHBOARD_URL}/api/auth/callback
DASHBOARD_REASONING_STREAM_ENABLED
thrillhousebot.dashboard.reasoning-stream-enabled
Streams the review call's reasoning to the dashboard's live activity page (#66), apart from its output. Only a provider that returns its reasoning as reasoning_content on the OpenAI-compatible stream sends any. Off by default: the reasoning can quote the reviewed code, and it is shown to every dashboard user who may read the repository.booleanfalse
DASHBOARD_URL
thrillhousebot.dashboard.url
Public dashboard URL, used for the OAuth callback and the session links posted to GitHub.stringhttp://localhost:8080
VariableDescriptionTypeDefault
GITHUB_ALLOWED_ACCOUNTS
thrillhousebot.github.allowed-accounts
Comma-separated logins of the accounts whose installations the bot serves. An event from an installation on any other account is ignored before any work, and the dashboard lists no other installation. Set it when the GitHub App is public, which dashboard sign-in for anyone but the App's owner requires, since anyone can install a public App. Unset serves every installation.list(none)
GITHUB_APP_ID
thrillhousebot.github.app-id
GitHub App ID, from the App's settings page. Required.string(none)
GITHUB_BOT_LOGINS
thrillhousebot.github.bot-logins
Comma-separated bot logins the bot ignores so it never answers itself. Override when the App slug differs (<app-slug>[bot]).listthrillhousebot[bot], thrillhouse-bot[bot]
GITHUB_PRIVATE_KEY
thrillhousebot.github.private-key
GitHub App private key (PEM), on one line with each newline written as \n, unquoted. Required.string(none)
GITHUB_WEBHOOK_SECRET
thrillhousebot.github.webhook-secret
The GitHub App's webhook secret, used to check each delivery's HMAC signature. Required.string(none)
GITHUB_WRITE_MAX_WAIT
thrillhousebot.github.write-max-wait
Longest one caller waits for its write slot before it goes out unpaced and the backoff handles any refusal.duration90s
GITHUB_WRITE_MIN_INTERVAL
thrillhousebot.github.write-min-interval
Minimum spacing between two content-creating GitHub calls (comments, review comments, replies, reviews), shared by the whole process. GitHub's guidance is at most one per second; it answers faster writes with 403, 429 or a 422 "was submitted too quickly". When GitHub throttles a write anyway, every queued write waits with it. 0 disables pacing.duration1s
GITHUB_WRITE_RETRY_BUDGET
thrillhousebot.github.write-retry-budget
Longest one review may spend waiting on GitHub's rate limit across all its writes. Once spent, later throttled writes are not retried, and the review body names the findings they carried and asks for a re-run. 0 disables the limit.duration5m
VariableDescriptionTypeDefault
PROMETHEUS_METRICS_ENABLED
thrillhousebot.metrics.prometheus-enabled
Serves the OpenTelemetry metrics in Prometheus text format at GET /metrics on the main HTTP port, alongside the OTLP export. Off by default: the endpoint is unauthenticated, so shield it at the proxy before enabling it on internet-facing deployments.booleanfalse
VariableDescriptionTypeDefault
NOTIFICATIONS_WEBHOOK_ALLOW_HTTP
thrillhousebot.notifications.webhook.allow-http
Accept a plain http:// URL, for local testing.booleanfalse
NOTIFICATIONS_WEBHOOK_EVENTS
thrillhousebot.notifications.webhook.events
Comma-separated outcomes to send: completed, failed.listcompleted, failed
NOTIFICATIONS_WEBHOOK_FORMAT
thrillhousebot.notifications.webhook.format
Body format: json (the structured payload), slack or discord (an incoming-webhook message for that chat service).stringjson
NOTIFICATIONS_WEBHOOK_INCLUDE_CONTENT
thrillhousebot.notifications.webhook.include-content
Also send the PR title and each finding's severity, file, line and title.booleanfalse
NOTIFICATIONS_WEBHOOK_MAX_ATTEMPTS
thrillhousebot.notifications.webhook.max-attempts
Attempts per notification (1–5). A timeout, connection failure, 429 or 5xx is retried after 1, 2, 4 and 8 seconds, then dropped with a WARN.integer3
NOTIFICATIONS_WEBHOOK_SECRET
thrillhousebot.notifications.webhook.secret
HMAC-SHA256 key; when set, each request carries X-Thrillhousebot-Signature-256: sha256=<hex> computed over the exact request body.string(none)
NOTIFICATIONS_WEBHOOK_TIMEOUT
thrillhousebot.notifications.webhook.timeout
Per-attempt timeout (at most 60s).duration10s
NOTIFICATIONS_WEBHOOK_URL
thrillhousebot.notifications.webhook.url
Receiver of review-outcome notifications; unset turns them off. Must be https://. Treated as a secret and logged only as scheme, host and port. See Outgoing notifications.string(none)
VariableDescriptionTypeDefault
ACK_REACTION_TIMEOUT
thrillhousebot.review.ack-reaction-timeout
Time limit on posting the 👀 reaction to a command; the reaction may land late.duration3s
REVIEW_ADD_DOCS_ENABLED
thrillhousebot.review.add-docs-enabled
Allow /add-docs, which posts generated docs for the changed symbols as committable suggestions.booleantrue
THRILLHOUSEBOT_REVIEW_AI_RETRY_BASE_DELAY_MS
thrillhousebot.review.ai-retry-base-delay-ms
Base delay of the exponential retry backoff, in milliseconds.integer2000
THRILLHOUSEBOT_REVIEW_AI_TIMEOUT_SECONDS
thrillhousebot.review.ai-timeout-seconds
Client-side wait per streaming attempt, in seconds. Keep it at or above AI_TIMEOUT so a timed-out attempt does not leave a stream open at the provider. A second timeout fails the call.integer300
AUTO_REVIEW_MIN_INTERVAL
thrillhousebot.review.auto-review-min-interval
Minimum time between automatic reviews of one PR. Pushes inside the window are skipped, even on a new head (in memory, per replica). /review always runs. 0 reviews every push.duration0
REVIEW_BLOCKING_STRICTNESS
thrillhousebot.review.blocking-strictness
Which findings request changes: balanced, strict or lenient. See Blocking strictness.stringbalanced
REVIEW_CI_GATING
thrillhousebot.review.ci-gating
How CI affects approval: strict holds approval while required CI is pending, failing or unreadable; warn approves and notes the CI state; off ignores CI. See CI gating.stringstrict
REVIEW_CONVERSATIONAL_REPLIES_ENABLED
thrillhousebot.review.conversational-replies-enabled
Answer @thrillhousebot mentions in PR threads and replies to findings.booleantrue
REVIEW_DECLINE_RECHECK_ENABLED
thrillhousebot.review.decline-recheck-enabled
Check a maintainer's decline against the reviewed code before recording the finding justified. See Re-checking declines. false makes any reply final.booleantrue
REVIEW_DIMENSION_ROUTING_ENABLED
thrillhousebot.review.dimension-routing-enabled
Give each review call only the review-dimension blocks its files can use, instead of all ten. See Dimension routing.booleanfalse
REVIEW_GENERATE_TESTS_ENABLED
thrillhousebot.review.generate-tests-enabled
Allow /generate-tests, which posts proposed unit tests for the changed code as a comment to copy in. Nothing is committed.booleantrue
THRILLHOUSEBOT_REVIEW_IGNORED_FILES
thrillhousebot.review.ignored-files
Comma-separated gitignore-style globs never reviewed. A pattern without / matches at any depth (*.lock, vendor); one with / is anchored at the root (docs/generated/**); a trailing / means the directory's tree; * does not cross /. Write a {a,b} alternation as separate patterns. Setting it replaces the default list, which covers lockfiles, generated and minified code, sourcemaps, and build and vendor trees. Build manifests such as pom.xml, package.json and Cargo.toml are reviewed; every file the list excludes is named in the summary's scope note.list**/package-lock.json, **/pnpm-lock.yaml, **/go.sum, **/*.lock, **/*.generated.*, **/*.pb.go, **/*_pb2.py, **/*.min.js, **/*.min.css, **/*.map, **/target/**, **/node_modules/**, **/dist/**, **/build/**, **/out/**, **/.next/**, **/vendor/**, **/__pycache__/**, **/.venv/**, **/bin/**, **/obj/**
REVIEW_IMPROVE_ENABLED
thrillhousebot.review.improve-enabled
Allow /improve, which posts a whole-PR improvement pass as committable suggestions.booleantrue
THRILLHOUSEBOT_REVIEW_INSTRUCTIONS_FILE
thrillhousebot.review.instructions-file
Repository path of the review instructions file.string.github/thrillhousebot.md
THRILLHOUSEBOT_REVIEW_MANUAL_TRIGGER_ALLOWED_LOGINS
thrillhousebot.review.manual-trigger-allowed-logins
Comma-separated logins allowed to run slash commands without write access. Does not apply to the resolved and declined directives. Unset means only users with write access.list(none)
MANUAL_TRIGGER_AUTH_TIMEOUT
thrillhousebot.review.manual-trigger-auth-timeout
Time limit on the write-access check for a command. Slower answers from GitHub deny the command.duration5s
REVIEW_MAX_AI_CALLS
thrillhousebot.review.max-ai-calls
Most AI calls per review (batch calls plus the summary call) and per command run (batch calls plus, for /describe and /changelog, the merge call). At 1, a review that makes its review call has none left for the summary and posts a counts-only summary that says so. Verifier calls are not counted.integer6
THRILLHOUSEBOT_REVIEW_MAX_AI_RETRIES
thrillhousebot.review.max-ai-retries
Attempts per failed AI call. At most two may end in a timeout.integer5
REVIEW_MAX_DIFF_LINES
thrillhousebot.review.max-diff-lines
Line cap for single-call diff renders (replies, base comparison, reviews with budgeting off). Token-budgeted reviews and the batched commands ignore it. 0 disables it.integer5000
REVIEW_MAX_INPUT_TOKENS
thrillhousebot.review.max-input-tokens
Input-token budget per call for reviews and the batched commands; larger PRs are split into batches. Capped by the model's max-input-tokens (see the per-model settings). 0 disables budgeting.integer48000
THRILLHOUSEBOT_REVIEW_MAX_REVIEW_COMMENTS
thrillhousebot.review.max-review-comments
Most inline comments per review; the rest are listed in the summary.integer50
REVIEW_MAX_TOKENS_PER_REVIEW
thrillhousebot.review.max-tokens-per-review
Most tokens one review may use across all its calls, as the provider reports them, retries and the summary call included. Once reached, no further call is made: the remaining batches are named as not reviewed, the summary degrades to counts only, and the findings already paid for are kept. An on-request command or a maintainer reply that reached it only skips the repeat of a call that spent its whole cap reasoning. 0 disables it.integer0
REVIEW_OUTPUT_BUFFER_TOKENS
thrillhousebot.review.output-buffer-tokens
Tokens reserved from the input budget for the response. A model with separate-output-budget set reserves nothing.integer8192
THRILLHOUSEBOT_REVIEW_REPO_CONFIG_ENABLED
thrillhousebot.review.repo-config-enabled
Read .github/thrillhousebot.yml from each repository (extra ignore globs, path-scoped rules, coverage artifact). See Repository configuration.booleantrue
REVIEW_RESPONSE_REPAIR_ENABLED
thrillhousebot.review.response-repair-enabled
When a review or summary answer is not valid review JSON, send only that answer and the parser's error in one small call and ask for the same content in the required shape, before resending the whole prompt. Also asks again for the walkthrough's file summaries when the summary answer wrote them as a string. See AI call budget.booleantrue
REVIEW_SUMMARY_VERIFICATION_ENABLED
thrillhousebot.review.summary-verification-enabled
Check the summary's sentences, walkthrough rows and diagram against the diff and the findings, and remove what they contradict. One more call per review. See AI call budget.booleanfalse
REVIEW_TOKEN_SAFETY_MARGIN
thrillhousebot.review.token-safety-margin
Fraction of the input budget actually used, to absorb token-estimate error.number0.9
REVIEW_TRIAGE_ENABLED
thrillhousebot.review.triage-enabled
Pack a large pull request's files into batches by review priority (#666): build manifests, then files matching AI_ROUTING_HIGH_RISK_PATHS, then the rest, then files matching AI_ROUTING_LOW_RISK_PATHS, the larger change first within each. When the call cap leaves files out, the low-risk ones go first. Off, the order is build manifests then size.booleanfalse
REVIEW_VERIFIER_ENABLED
thrillhousebot.review.verifier-enabled
Run a second, skeptical pass that re-checks each finding against the diff and drops or downgrades what it cannot confirm. See AI call budget.booleantrue
VariableDescriptionTypeDefault
REVIEW_CI_CONTEXT_ENABLED
thrillhousebot.review.ci-context.enabled
Include the checks that had already failed on the head commit. See CI-failure context.booleanfalse
REVIEW_CI_CONTEXT_INCLUDE_LOGS
thrillhousebot.review.ci-context.include-logs
Also include the last 30 lines of up to two failing GitHub Actions job logs. Ignored unless REVIEW_CI_CONTEXT_ENABLED is on.booleanfalse
REVIEW_CI_CONTEXT_MAX_CHARS
thrillhousebot.review.ci-context.max-chars
Character cap on the CI section (500–20000).integer4000
VariableDescriptionTypeDefault
REVIEW_DIAGRAM_ENABLED
thrillhousebot.review.diagram.enabled
Add a Mermaid control-flow diagram to the summary.booleanfalse
VariableDescriptionTypeDefault
REVIEW_FOLLOW_UP_SUMMARY_ENABLED
thrillhousebot.review.follow-up-summary.enabled
Include new, resolved and still-open counts in the follow-up review outcome, naming closed findings once. No separate delta comment; nothing is added when no finding is raised or closed.booleanfalse
VariableDescriptionTypeDefault
REVIEW_LABELS_ALLOW_CREATE
thrillhousebot.review.labels.allow-create
Allow creating a suggested label that does not exist yet.booleanfalse
REVIEW_LABELS_APPLY
thrillhousebot.review.labels.apply
Add the labels to the PR instead of suggesting them in a comment.booleanfalse
REVIEW_LABELS_BLOCKED
thrillhousebot.review.labels.blocked
Comma-separated label names the bot never suggests, applies or creates, matched ignoring case: labels a team keeps for its own workflow, such as review. They are left out of the list the model sees and dropped from its suggestions.list(none)
REVIEW_LABELS_ENABLED
thrillhousebot.review.labels.enabled
Suggest PR labels. See PR labels.booleanfalse
REVIEW_LABELS_MAX
thrillhousebot.review.labels.max-labels
Most labels applied or suggested per PR.integer3
VariableDescriptionTypeDefault
REVIEW_LARGE_PR_NUDGE_ENABLED
thrillhousebot.review.large-pr-nudge.enabled
On a large PR whose review opened no inline finding and left no earlier finding open, add a note to the summary pointing at /review and /improve. No extra AI call; the verdict is unchanged.booleanfalse
REVIEW_LARGE_PR_NUDGE_MIN_CHANGED_LINES
thrillhousebot.review.large-pr-nudge.min-changed-lines
Added plus deleted lines at which a PR counts as large; either test is enough. 0 turns this test off.integer1000
REVIEW_LARGE_PR_NUDGE_MIN_FILES
thrillhousebot.review.large-pr-nudge.min-files
Changed files (ignored files included) at which a PR counts as large. 0 turns this test off.integer20
VariableDescriptionTypeDefault
REVIEW_LEARNINGS_ENABLED
thrillhousebot.review.learnings.enabled
Remember maintainer declines and /remember conventions per repository and show them to later reviews. See Review learnings. Startup fails if this is on while REVIEW_DECLINE_RECHECK_ENABLED is off.booleanfalse
REVIEW_LEARNINGS_MAX_PER_REPO
thrillhousebot.review.learnings.max-per-repo
Active learnings one repository may hold (1–1000). At the cap a new learning is refused, not evicted; two captures racing at the cap can each add one.integer100
REVIEW_LEARNINGS_PROMPT_MAX_CHARS
thrillhousebot.review.learnings.prompt-max-chars
Character cap on the learnings section (500–20000).integer3000
REVIEW_LEARNINGS_PROMPT_MAX_ITEMS
thrillhousebot.review.learnings.prompt-max-items
Most learnings in one review prompt (1–50).integer10
VariableDescriptionTypeDefault
REVIEW_PATCH_COVERAGE_ENABLED
thrillhousebot.review.patch-coverage.enabled
Tell the review which added lines the repository's own coverage report never ran. Needs coverage-artifact in .github/thrillhousebot.yml (see Repository configuration).booleanfalse
VariableDescriptionTypeDefault
REVIEW_SECRET_SCAN_ENTROPY_THRESHOLD
thrillhousebot.review.security-scan.entropy-threshold
Minimum Shannon entropy (bits per character) for the generic credential-assignment rule; the known token formats ignore it. Must be in (0, 8].number3.5
REVIEW_IAC_SCAN_ENABLED
thrillhousebot.review.security-scan.iac-enabled
Scan added lines for risky infrastructure-as-code settings (Terraform, Kubernetes, CloudFormation, Dockerfiles).booleanfalse
REVIEW_SECRET_SCAN_ENABLED
thrillhousebot.review.security-scan.secrets-enabled
Scan added lines for leaked credentials (provider token formats, private keys, JWTs, assignments). See Security scan.booleanfalse
REVIEW_SECURITY_SCAN_SKIPPED_FILES
thrillhousebot.review.security-scan.skipped-files
Comma-separated globs the scan skips on top of the review's ignore list, for fixtures and snapshots where token-shaped sample data is expected.list**/fixtures/**, **/__fixtures__/**, **/testdata/**, **/test-data/**, **/__snapshots__/**, **/*.snap
VariableDescriptionTypeDefault
REVIEW_TICKET_CONTEXT_ENABLED
thrillhousebot.review.ticket-context.enabled
Include the issues the PR links and list unaddressed acceptance criteria in the summary. See Linked-issue context.booleanfalse
REVIEW_TICKET_CONTEXT_FROM_BRANCH
thrillhousebot.review.ticket-context.from-branch
Also take an issue number from the head branch name (issue-57, fix/57-short-name) when nothing else links one.booleanfalse
REVIEW_TICKET_CONTEXT_MAX_CHARS
thrillhousebot.review.ticket-context.max-chars
Character cap on the linked-issue section (1000–20000).integer6000
REVIEW_TICKET_CONTEXT_MAX_ISSUES
thrillhousebot.review.ticket-context.max-issues
Linked issues read per review (1–5); once this many are read, later references are ignored.integer3
REVIEW_TICKET_CONTEXT_PROVIDER
thrillhousebot.review.ticket-context.provider
Where linked issues are read from. Only github exists.stringgithub
VariableDescriptionTypeDefault
WEBHOOK_DEDUP_TTL
thrillhousebot.webhook.dedup-ttl
How long a webhook delivery id (X-GitHub-Delivery) is remembered, to ignore GitHub redeliveries instead of reviewing twice. Kept in memory, per replica.duration24h
VariableDescriptionTypeDefault
WEBHOOK_BASE_BRANCHES
thrillhousebot.webhook.triggers.base-branches
Comma-separated globs; auto-review only PRs whose base branch matches one (main,release/*). * does not cross /; use ** for that. Unset means every base branch.list(none)
WEBHOOK_EXCLUDED_AUTHORS
thrillhousebot.webhook.triggers.excluded-authors
Comma-separated logins; skip auto-review of PRs opened by any (case-insensitive exact match, dependabot[bot]). Unlike a label, the author is in every opened payload, so it holds when a bot labels its PR after opening it.list(none)
WEBHOOK_EXCLUDED_LABELS
thrillhousebot.webhook.triggers.excluded-labels
Comma-separated labels; skip auto-review of PRs carrying any (case-insensitive exact match). Wins over WEBHOOK_REQUIRED_LABELS.list(none)
WEBHOOK_IGNORED_BASE_BRANCHES
thrillhousebot.webhook.triggers.ignored-base-branches
Comma-separated globs; skip auto-review of PRs whose base branch matches one (gh-pages). Wins over WEBHOOK_BASE_BRANCHES.list(none)
WEBHOOK_REQUIRED_LABELS
thrillhousebot.webhook.triggers.required-labels
Comma-separated labels; auto-review only PRs carrying at least one (case-insensitive exact match). Unset means no label is required.list(none)
WEBHOOK_SKIP_DRAFTS
thrillhousebot.webhook.triggers.skip-drafts
Do not auto-review drafts; the PR is reviewed once marked ready (ready_for_review).booleanfalse