name: PR Agent # AI pull-request review (PR-Agent, the original open-source reviewer: repo id # 662766482, same repo the qodo-ai/Codium-ai names redirect to). Replaces the # Greptile bot that went silent after #682. # # Supply-chain hardening: # * Pinned to an immutable commit SHA (v0.36.0), NOT a movable tag, because the # repo now sits under a recently-created, unverified org (The-PR-Agent). # * Runs on a DEDICATED, minimal IAM key (bedrock:InvokeModel only) supplied via # PR_AGENT_AWS_* secrets: never the app's general AWS credentials. A leaked # PR-Agent key can do nothing but invoke the one Bedrock model. # # Scope: ONLY /review runs automatically. /describe and /improve are disabled so # the bot never overwrites hand-written PR descriptions. Users can still invoke # any command interactively by commenting e.g. "/describe" or "/improve" on a PR. on: pull_request: types: [opened, reopened, ready_for_review, synchronize] issue_comment: types: [created, edited] # One run per PR *per event type*; a new push (pull_request:synchronize) cancels # a superseded review. The event_name suffix is critical: without it, the # pull_request and issue_comment triggers share a group, so a bot comment # (Vercel/Supabase/compliance preview bots fire within ~2s of opening a PR) # queues an issue_comment run that cancel-in-progress kills the real review with, # before the job-level `if: sender.type != 'Bot'` ever gets to skip it. Keeping the # groups separate lets comment runs cancel only each other (all skipped, harmless) # and never the open/push review. concurrency: group: pr-agent-${{ github.event.pull_request.number || github.event.issue.number }}-${{ github.event_name }} cancel-in-progress: true permissions: contents: read pull-requests: write issues: write jobs: pr_agent: # Skip bot-authored events (vercel/supabase/etc.) to avoid feedback loops. if: ${{ github.event.sender.type != 'Bot' }} runs-on: ubuntu-latest name: The PR Agent steps: - name: The PR Agent # Pinned to the v0.36.0 commit SHA (immutable): do not switch to @v0.36.0. uses: The-PR-Agent/pr-agent@8e4d32e5497defd43c023a404f73560c62728961 # v0.39.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # ── DEDICATED Bedrock IAM key (bedrock:InvokeModel only): NOT the # app's AWS_* secrets. litellm reads AWS_REGION_NAME; AWS_REGION is # set too for safety. Create these three repo/org secrets: # PR_AGENT_AWS_ACCESS_KEY_ID, PR_AGENT_AWS_SECRET_ACCESS_KEY, # PR_AGENT_AWS_REGION (an EU region, e.g. eu-west-1). AWS_ACCESS_KEY_ID: ${{ secrets.PR_AGENT_AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.PR_AGENT_AWS_SECRET_ACCESS_KEY }} AWS_REGION_NAME: ${{ secrets.PR_AGENT_AWS_REGION }} AWS_REGION: ${{ secrets.PR_AGENT_AWS_REGION }} # ── Model: Claude Sonnet 5 via the EU Bedrock inference profile. The # strong and weak slots both point at it: this account has no larger # model enabled, so a second id would only be the same model under # another name. custom_model_max_tokens is required because this id # is not in PR-Agent's built-in map. CONFIG.MODEL: "bedrock/eu.anthropic.claude-sonnet-5" CONFIG.MODEL_WEAK: "bedrock/eu.anthropic.claude-sonnet-5" # Emptied explicitly. This block previously said it set no fallback # list, but "unset" is not "none": PR-Agent's own default is # ["gpt-5.6-terra"], visible in the resolved config it logs on every # run. Only AWS credentials reach this container, so that fallback # could never have authenticated, but a silent third-party model in # the path of every PR diff should be absent by intent, not by a # missing key. CONFIG.FALLBACK_MODELS: "[]" CONFIG.CUSTOM_MODEL_MAX_TOKENS: "1000000" # Input window PR-Agent prunes the diff to fit. Default (~32k) truncated # large PRs; raise it so the whole diff is reviewed (Sonnet 5 = 1M ctx). # 64000 was tuned against Sonnet 4.6's tokenizer. Sonnet 5 tokenizes the # same text into roughly 30% more tokens, so that budget silently held # ~30% less real diff after #1218; 96000 restores parity with headroom. CONFIG.MAX_MODEL_TOKENS: "96000" LITELLM.DROP_PARAMS: "true" # ── pr_actions = which GitHub PR *event actions* trigger the bot # (NOT a command list). Default omits 'synchronize', so pushes are # skipped; we add it so every push is reviewed too. GITHUB_ACTION_CONFIG.PR_ACTIONS: '["opened", "reopened", "ready_for_review", "review_requested", "synchronize"]' # ── Which commands actually run on a handled event. Only review: # describe/improve off so the bot never rewrites the PR body or # pushes code suggestions. GITHUB_ACTION_CONFIG.AUTO_REVIEW: "true" GITHUB_ACTION_CONFIG.AUTO_DESCRIBE: "false" GITHUB_ACTION_CONFIG.AUTO_IMPROVE: "false"