falconiere/Toolu AI Code Review

Automated AI code review for pull requests. Reviews every changed file against an 8-dimension checklist (correctness, security, performance, test coverage, doc accuracy, tight assertions, migration warnings, and adherence to the project's own convention files read from the base ref) and posts a structured verdict with actionable findings. Runs on OpenRouter (any OpenAI-compatible model) or the native DeepSeek API, via the Vercel AI SDK with structured-output validation and retries.

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Activelast commit Jul 10, 2026
License
MIT

Pinned Snippet

workflow.ymlSHA-pinned
uses: falconiere/toolu-code-review@0e3ed0879dba12514512a3547809892bac3fec49 # v6.0.1

tags can be moved; commit SHAs can't. why a SHA?

namedescriptionrequireddefault
PROVIDERLLM backend: "openrouter" (default — any OpenAI-compatible model via OpenRouter) or "deepseek" (native api.deepseek.com). Any other value fails with an error.noopenrouter
MODEL_IDModel id for the chosen provider. Defaults per provider: openrouter -> deepseek/deepseek-v4-pro, deepseek -> deepseek-v4-flash. Use a "<vendor>/<model>" id for OpenRouter; a bare id like "deepseek-v4-flash" for native DeepSeek.no
API_KEYAPI key for the chosen provider (Authorization: Bearer). Required. Prefer passing via a step-level env: block for better secret hygiene.yes
MAX_TOKENSMax completion tokens per request. Always sent — omitting it makes the provider reserve the model's full output capacity against your credit budget. A truncated (finish_reason "length") chunk is retried with a doubled budget up to 32768.no8192
MIN_CONFIDENCEDrop findings below this confidence unless severity is blocker/high. One of: high, mediumnohigh
INLINE_COMMENTSWhen true, post per-line review comments (with committable code suggestions) via the GitHub Reviews API, in addition to the summary comment. Set false for summary-onlynotrue
MANAGE_LABELSWhen true, set a real PR label chip matching the verdict (merge-approved / request-changes) and remove the opposite one. Requires issues: write. Set false to leave PR labels untouchednotrue
BASE_BRANCHBase branch for diff comparisonnomain
REVIEW_PROMPT_FILEPath to a markdown file (relative to repo root) containing a custom review prompt. Overrides the default 8-dimension checklist. Project conventions are still gathered and injected for the custom prompt to use.no
CODEBASE_OVERVIEWHigh-level description of the codebase (framework, patterns, business context) to give the reviewer contextno
CHECK_PROJECT_RULESWhen true (default), auto-read the repo's own convention files from the BASE ref (CLAUDE.md, AGENTS.md, .cursor/rules, .cursorrules, .windsurfrules, .github/copilot-instructions.md, plus CONVENTIONS.md/CONTRIBUTING.md/docs/conventions) and review the diff against them via the CONVENTION ADHERENCE dimension. Reading from the base ref means a PR cannot inject rules. Set false to disable.notrue
RULES_GLOBExtra path globs (relative to repo root, newline- or comma-separated) to include as project rules, e.g. "docs/architecture/**". Matched against tracked files at the rules ref (see RULES_REF). Empty (default) = the well-known convention files only.no""
RULES_REFWhich ref the convention files are read from: "base" (default) reads the base-branch tip, so a PR cannot modify the rules it is reviewed against (the anti rule-injection default); "merge" reads them from the checked-out PR merge ref, so a same-repo PR that legitimately updates a convention file is reviewed against its own updated text. SECURITY TRADE-OFF: "merge" lets a PR modify the rules it is reviewed against — only enable it on repos where PR authors are already trusted (same-repo branches, protected by required review), never on repos accepting fork PRs. Any other value warns and falls back to "base".nobase
EXCLUDE_GLOBSExtra path globs (relative to repo root, newline- or comma-separated) to EXCLUDE from the AI review diff, on top of the built-in generated/vendored/lockfile set and any .gitattributes linguist-generated paths. e.g. "migrations/**, **/*.snap". Excluded files are still committed and CI-checked; they are only kept out of the LLM review.no""
RULES_MAX_BYTESTotal byte cap on the gathered project-rules text. Files are added in priority order until the cap; whole files past it are dropped with a truncation notice. Default: 32768.no32768
MAX_FILESMaximum number of changed files before the action skips. 0 (default) = unlimited; the only ceiling is your OpenRouter billing balance. Set a positive value to opt into a hard skip.no0
MAX_DIFF_LINESMaximum diff lines before truncation (first N lines kept, lexicographic by file path). 0 (default) = unlimited; review the whole diff. Set a positive value to opt into truncation. Applied BEFORE chunking.no0
MAX_CHUNK_LINESPer-chunk diff-line budget. When the diff exceeds this, it is split into chunks of whole files (≤ this many primed lines each) reviewed in separate model calls and merged — so large PRs no longer overwhelm one call. 0 = never chunk (single call). Default 1500.no1500
MAX_CHUNKSMaximum number of chunks (= model calls) per review, bounding cost and wall-clock on very large PRs. Files beyond the limit are not reviewed and the comment says so. 0 = unlimited. Default 20.no20
REQUEST_TIMEOUT_MSPer-attempt model deadline in milliseconds. Each chunk gets up to this long per attempt (retried a few times) before it is aborted and the chunk abstains ("This operation was aborted"). Raise it for slow/large models, lower it to fail faster. Default 180000 (3 min).no180000
TOKENGitHub token for posting/editing commentsno${{ github.token }}
APP_IDGitHub App id. Set together with APP_PRIVATE_KEY to post review comments as a custom-branded App ("Toolu - Code Review") instead of github-actions[bot]. Both must be set or the action falls back to the default identity.no
APP_PRIVATE_KEYGitHub App private key. Accepts the raw PEM or a base64-encoded PEM (auto-decoded) — base64 is handy for storing a multiline key in a single-line secret. Pair with APP_ID. Pass via a secret; never inline. Used only to mint a short-lived installation token — never logged.no
TRIGGER_PHRASEMention prefix that re-triggers a review from a PR comment, e.g. "@toolu review focus on auth". Requires the workflow to also listen on issue_comment.no@toolu
MIN_TRIGGER_PERMISSIONMinimum repo permission a commenter needs to trigger a review via @mention: write or admin. The check fails closed (denied on any error).nowrite
BOT_NAMEDisplay name shown in the comment body header.noToolu — Code Review
BOT_LOGO_URLLogo image shown in the comment body header.nohttps://raw.githubusercontent.com/falconiere/toolu-ghactions/main/code-review/assets/logo.png
REVIEW_MEMORYWhen true, recap what changed since the last review (resolved / still-open / new) and keep a collapsed history, using a hidden state marker in the sticky comment. Set false to disable memory.notrue
MAX_ROUNDSReview-round surrender cap. A generative reviewer can produce a fresh findings batch on every push, so "zero findings" is not a reachable fixpoint on some PRs and a "changes" verdict would block forever. When set to N > 0 and this is review round N (or later; rounds counted from the REVIEW_MEMORY history), a "changes" verdict whose findings are ALL below blocker severity is downgraded to "approved" — the findings stay listed as advisory, the comment carries an explicit "Round cap" callout, and FAIL_ON stops failing the job. A single blocker finding disables the cap for that round. Requires REVIEW_MEMORY. 0 (default) = never surrender.no0
VERBOSITYVerdict-comment verbosity: "compact" (default) collapses the checklist to a single line and renders recap buckets as `path:line` refs; "full" restores the multi-line checklist and inline recap text. Findings, the Findings heading, and the state marker are identical in both modes. Any other value warns and falls back to compact.nocompact
FAIL_ONComma-separated verdicts that FAIL the job (turning this check red so branch protection can block the PR): changes, error, or both. Defaults to "changes" — the job goes red when the bot requests changes. Set "none" to keep the job green on every verdict (advisory only), or "changes,error" to also block when the review could not run. The comment, label, and outputs are posted regardless; only the exit code changes. This governs the verdict-driven gate only; a thrown infra error still fails the job regardless of FAIL_ON. Mark this check Required in branch protection for the red to block.nochanges
RUN_SECRET_SCANRun the deterministic secret scan (gitleaks) before the LLM review. Its findings feed the LLM as triage context and upload to the Code Scanning tab. Set false to skip.notrue
RUN_SASTRun the deterministic SAST pass (Opengrep) before the LLM review. Its findings feed the LLM as triage context and upload to the Code Scanning tab. Set false to skip.notrue
SAST_RULESOpengrep rule config(s) for the SAST pass (comma-separated). Default: p/typescript.nop/typescript
namedescription
verdictReview verdict: approved, changes, skip, or error
findings-countNumber of findings reported
comment-urlURL of the posted verdict comment