Robin

Robin docs: AI code review in GitHub Actions

Robin adds AI code review to a repository as a reusable GitHub Actions workflow. You add one workflow file and three secrets; Robin reviews every pull request with the LLM you choose, using your own API key. Setup takes a few minutes — here's the whole thing.

Quickstart

Run from the root of the Git repository you want Robin to review. The workflow and secrets are per repository; the companion agent skill is global per machine.

Do not run the installer from your home directory.

Install with npx — it adds the workflow file to the current repository:

npx robin-review

No npm? Install with curl instead (read the script first at /script):

curl -fsSL https://robinreview.dev/install.sh | bash

Run an installer separately in every repository that should use Robin. Re-running it keeps one canonical .github/workflows/robin.yml, archives recognized historical variants where GitHub cannot trigger them, and updates the global companion skill. Custom identity workflows stay intact; update their refs manually. Inspect and remove archived copies after confirming a migration.

Or add it manually — create .github/workflows/robin.yml:

name: Robin

on:
  pull_request:
    types: [opened, reopened, ready_for_review]
  issue_comment:
    types: [created]

permissions:
  actions: read
  contents: read
  pull-requests: write

jobs:
  review:
    uses: antongulin/robin/.github/workflows/review.yml@main
    secrets:
      LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
      LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
      LLM_MODEL: ${{ secrets.LLM_MODEL }}

The three secrets

In your repo, go to Settings → Secrets and variables → Actions and add:

  • LLM_API_KEY — your provider API key.
  • LLM_BASE_URL — the provider's OpenAI-compatible base URL.
  • LLM_MODEL — the model to review with.

That's the only configuration Robin needs to start reviewing.

Custom review identity (optional)

Robin posts as github-actions[bot] by default. Your existing workflow and three LLM secrets keep working. To post as a different account through the reusable workflow, store its token as a repository secret and add this mapping to your review job:

# Add to the secrets mapping of your existing review job:
ROBIN_TOKEN: ${{ secrets.ROBIN_TOKEN }}

Omitting the mapping or leaving the secret empty keeps the default identity. A supplied invalid token produces an API error. Use a workflow revision that supports ROBIN_TOKEN; older pinned releases reject the extra secret. A caller using secrets: inherit also passes ROBIN_TOKEN when that repository secret exists.

For your own GitHub App, create an installation token and run the direct Robin action in the same job. For new setups, use the App’s Client ID as the token action’s app-id input at @v2; existing numeric App IDs still work. Do not pass that token between jobs: GitHub hides secret outputs and the token action revokes its token when the creation job ends. Grant the App Contents: read, Pull requests: write, and Actions: read.

A personal access token posts as its owner. It cannot request changes on that owner's PR, and an older blocking review may need manual dismissal after a clean rerun. Prefer a GitHub App for automation, or use request-changes: false for PAT advisor mode.

The installers preserve custom identity workflows, including their token steps, secret aliases, and dependencies. They skip workflow regeneration and ROBIN_REF overrides for these setups. Your review triggers, LLM settings, and command permissions stay under your control. Follow the complete setup examples.

Choosing an LLM provider

Robin works with any OpenAI-compatible endpoint. Common choices for LLM_BASE_URL:

ProviderLLM_BASE_URLNotes
OpenRouter (free models)https://openrouter.ai/api/v1Free-tier models available — run Robin at $0.
OpenAIhttps://api.openai.com/v1e.g. a small, fast model for cheap reviews.
Groqhttps://api.groq.com/openai/v1Fast inference on open models.
Ollama (self-hosted)http://localhost:11434/v1Fully local; requires a self-hosted runner.

Set LLM_MODEL to any model that provider offers. If you're cost-sensitive, start with a free OpenRouter model and upgrade only if you want stronger reviews.

Models that require a fixed temperature

Robin samples at temperature 0.1 by default so reviews stay near-deterministic. A few providers accept only one fixed value — Kimi models require 1 and reject the request otherwise. Set the optional llm-temperature input in the workflow's with: block:

jobs:
  review:
    uses: antongulin/robin/.github/workflows/review.yml@main
    with:
      llm-temperature: "1" # Kimi accepts only 1
    secrets:
      LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
      LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
      LLM_MODEL: ${{ secrets.LLM_MODEL }}

The accepted range is 0–2; out-of-range or non-numeric values log a warning and fall back to 0.1. Raising the temperature makes findings less repeatable, so change it only when your provider requires it.

Commands

By default Robin reviews once when a pull request opens. You can also comment:

  • /robin — run another review pass (after pushing fixes).
  • /summary — a short overview of the PR.
  • /help — list available commands.

Fork pull requests

GitHub does not expose repository secrets to workflows triggered by fork PRs, so Robin can't auto-review an external contributor's PR. After you've looked it over, comment /robin on the PR to run the review with your secrets. This is standard GitHub Actions security behavior, not a Robin limitation.

Pinning a version

The workflow references @main, which always runs the latest release. Pin a release tag instead — @v2 for the latest 2.x, or an exact version like @v2.7.0 — if you want fully reproducible runs and to control when you pick up changes. See the repository for the list of releases.

Review on every push (opt-in)

Out of the box Robin reviews a pull request when it opens (and when you comment /robin or /review). It does not re-review on every push. To review each push to an existing PR, add the synchronize event to the trigger and set review-on-synchronize: true:

on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
  issue_comment:
    types: [created]

permissions:
  actions: read
  contents: read
  pull-requests: write

jobs:
  review:
    uses: antongulin/robin/.github/workflows/review.yml@main
    with:
      review-on-synchronize: true
    secrets:
      LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
      LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
      LLM_MODEL: ${{ secrets.LLM_MODEL }}

Both are required: the event makes GitHub deliver the push, and the boolean makes Robin act on it. Without the boolean, a synchronize run is skipped and the push is reviewed only when you comment /robin.

Agent mode (opt-in)

Robin can review beyond the diff: instead of a single request, it reads full files, greps for callers, and lists directories at the PR head commit before it decides what is a bug. Agent mode is off unless you enable it. Set it in .github/robin.yml:

# .github/robin.yml
agent-mode: auto
agent-max-turns: 40

agent-max-turns caps the tool-calling turns (default 40, maximum 100), and agent-max-diff-size caps the upfront diff (default 200000 characters). Leave agent-mode unset to keep the single-shot review. When the model does not support tool calling, Robin falls back to the single-shot review automatically.

Agent mode can send additional repository-file context to your chosen LLM endpoint and make more API calls. Leave it off to keep the single-shot diff review. Explicit workflow inputs override repository configuration for agent controls and reasoning effort.

Reasoning effort and token caps

Reasoning is provider-specific. When reasoning-effort is unset everywhere, Robin sends no reasoning control and the provider/model default applies; set it in .github/robin.yml (or the workflow with: block) to send a value, or set off to send nothing explicitly. The value is always opt-in; there is no built-in high default.

Set an optional max-output-tokens cap in the workflow's with: block. Robin chooses a token-field name; if the provider rejects it, Robin tries the other spelling (max_tokens or max_completion_tokens) and keeps the cap. If the endpoint rejects both spellings, or the value itself is invalid, the provider error surfaces instead of Robin quietly running without a cap.

Anthropic (Claude)

Set LLM_BASE_URL to https://api.anthropic.com/v1 and use your regular Anthropic API key. This OpenAI-compatible endpoint ignores response_format and reasoning controls. Robin omits reasoning controls there; it can still send a best-effort JSON schema, but relies on the prompt and review parser rather than Anthropic enforcing that schema. Guaranteed structured output would require the native Claude API, which Robin does not call.

Structured output (JSON mode)

When JSON mode is enabled, Robin requests a strict json_schema response by default, stepping down to a plain JSON object and then to no response_format if the provider rejects it. JSON mode is single-shot only, since many providers reject response_format alongside tool calls. The schema preference is automatic while JSON mode is enabled; you can disable JSON mode with use-json-response-mode: false. For providers that ignore or reject format controls, prompt/parser fallback is best-effort and cannot guarantee valid output.

Going further

Advanced configuration — self-hosted runners, strict mode, and custom rules — is documented in the repository:

New to the idea? See what Robin is or read the blog.