Inline Feedback

Inline Feedback

The inline feedback feature lets developers interact with the bot directly from inline PR comment threads using @botai commands.

Commands

@botai resolved and @botai dismiss only work inside an inline thread (a PR review comment reply), since they act on one specific finding. @botai explain and @botai ask also require inline context but don't require the parent to be a bot finding. @botai approved, @botai review, @botai ask, and @botai learn also work from a general PR comment.

ReplyWhereWhat happens
@botai approvedInline thread or general commentThe bot acknowledges, dismisses its own prior CHANGES_REQUESTED reviews, submits a GitHub APPROVE, and suppresses open findings so they are not re-flagged on later pushes. Escape hatch after false-positive blocks. If APPROVE fails (permissions), it replies with an error. Note: a failed Actions check from exit code 1 on an earlier REQUEST_CHANGES is separate — re-run that job or do not treat it as a required check if you rely on this override.
@botai review """your explanation"""Inline threadThe bot reads your explanation, fetches the current file state, and asks the LLM whether that one finding is resolved. It always posts a reply with its decision
@botai reviewGeneral commentRe-runs the full PR review, feeding in your explanation (quoted with """...""" in the same comment, or written in earlier general comments since the bot's last review) so the model can recognize when a previously flagged concern is already addressed instead of repeating it
@botai resolvedInline threadThe bot immediately marks the finding as resolved and closes the thread. If all open bot findings are now resolved, it auto-approves the PR
@botai ask """question"""Inline thread or general commentAnswers a free-form question — inline it uses the surrounding code, general comment it uses the PR summary. Never triggers a re-review
@botai learn """rule"""Inline thread or general commentSaves the rule to a repo-level Learnings file, applied to every future review of the PR's base branch — requires learnings.enabled: true

Setup

1. Enable in config

Add to .ai-review.yml:

feedback:
  enabled: true

2. Add the workflow job

The handle-feedback command must run on the pull_request_review_comment event (inline replies) and the issue_comment event (general PR comments, needed for @botai approved/@botai review outside a thread). Add it alongside your existing ai-review job:

name: AI Code Review
 
on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
  pull_request_review_comment:
    types: [created]
  issue_comment:
    types: [created]
 
jobs:
  ai-review:
    if: github.event_name == 'pull_request' && github.event.pull_request.draft == false
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: git fetch origin ${{ github.base_ref }}
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npx -y @giolabsuy/ai-code-reviewer@latest review-pr
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
  handle-feedback:
    if: github.event_name == 'pull_request_review_comment' || github.event_name == 'issue_comment'
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      # `contents: write` is only required if `learnings.enabled: true` — @botai learn
      # and the auto-capture on @botai dismiss commit .ai-review-learnings.md directly
      # to the PR's base branch. Use `contents: read` if you don't enable Learnings.
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npx -y @giolabsuy/ai-code-reviewer@latest handle-feedback
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITHUB_EVENT_PATH: ${{ github.event_path }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_ACTOR: ${{ github.actor }}

The GITHUB_ACTOR variable is set automatically by GitHub Actions. It identifies who triggered the workflow, which the handler uses to skip its own bot replies.

How it works

When a developer replies to a bot inline comment:

  1. The pull_request_review_comment event fires.
  2. The handle-feedback workflow job starts.
  3. The CLI reads the event payload from GITHUB_EVENT_PATH.
  4. It checks that the commenter is not the bot itself.
  5. It looks for @botai <command> in the reply body.
  6. The matching handler runs (see command details below).

If the reply does not contain @botai, the event is ignored silently.

@botai approved

Use this command to approve the PR from any inline thread reply — regardless of which finding the thread belongs to.

Bot: 🟡 major — Missing input validation on /upload endpoint

Developer (reply): @botai approved

Bot: @lucasgio approved this PR. Proceeding to approve.
[GitHub shows: ✅ lucasgio via @botai approved this pull request]

@botai review

Use this command when you've addressed a finding and want the bot to verify. Put your explanation between """ delimiters — the bot will read it along with the current state of the file to decide if the finding is resolved.

Bot: 🔴 critical — Missing authentication guard

       This endpoint has no @UseGuards() decorator. Any unauthenticated
       user can call it.

Developer (reply): @botai review """Added @UseGuards(JwtAuthGuard) to
the controller method in the latest commit (abc1234)."""

Bot: The guard is now present on the method. The finding is resolved. ✅

If the bot determines the fix is insufficient, it replies with maintained and explains what's still missing.

@botai review from a general comment

Use this when you want the bot to reconsider the review as a whole — not one specific finding — after you've explained yourself in the PR conversation. This re-runs a full review, not just a single-finding check.

Developer (general comment): ## Response to AI review

Thanks — both findings addressed in `513e60f`, with one clarification.

### 🟠 MAJOR — "adapter-registration factory may not run at runtime"

The alarming conclusion is a false positive. NestJS eagerly instantiates
all default-scope providers during application bootstrap, regardless of
whether their token is injected elsewhere. See the new
`channels.module.spec.ts` integration test that proves it.

Developer (general comment): @botai review

Bot: Re-revisando el PR teniendo en cuenta tu feedback...
[a new full review runs and posts an updated summary + review event]

You don't need to repeat your explanation inside """...""" — the bot collects every general comment posted since its last review summary (skipping its own comments) and feeds that conversation to the model as context, so a bare @botai review after an explanation comment works exactly like the example above. If you prefer to be explicit, @botai review """your explanation""" also works from a general comment and that quoted text is included too.

The re-review runs the same pipeline as a normal push-triggered review (stack detection, per-group LLM calls, merged result) and updates the existing summary comment and review event in place — it does not create a duplicate.

@botai resolved

Use this command to unconditionally close a finding without LLM evaluation — useful when the finding is a false positive or was addressed in a way that's hard to explain in text.

Bot: 🟡 major — Potential race condition in upload handler

Developer (reply): @botai resolved

Bot: Finding resolved by @lucasgio.

If this was the last open bot finding on the PR, the bot also submits an APPROVE review automatically.

@botai ask

Ask anything about the PR without anchoring to one specific finding, and without triggering a re-review. Works two ways:

# Inline — uses the code around the comment
Bot: 🟠 major — Registry not populated at bootstrap

Developer (reply): @botai ask """why does this only affect mercado_libre and not tiendanube?"""

Bot: Because only mercado_libre is registered in the CHANNEL_PROVIDERS_FACTORY
in channels.module.ts — tiendanube has no adapter wired yet, so it's...

# General comment — uses the PR's AI Code Review summary
Developer (general comment): @botai ask """what does this PR change in the public API?"""

Bot: This PR doesn't change any existing endpoint contracts. It adds capability
resolution to GET /channels/available — status and capabilities[] are now...

@botai learn

Requires learnings.enabled: true in .ai-review.yml (opt-in — see Configuration). Saves a rule to .ai-review-learnings.md, committed directly to the PR's base branch, and every future review of that branch includes it in the system prompt — not just this PR.

Developer (general comment): @botai learn """No reportar console.log en scripts/migrations/**, es intencional para logging de migración."""

Bot: Aprendizaje guardado en `.ai-review-learnings.md` (rama `develop`). Se va
a tener en cuenta en las próximas reviews de este repo.

@botai dismiss on an inline finding also auto-captures an entry (the finding's title plus your dismiss reason, if you gave one) — you don't need to also run @botai learn for a one-off false positive you've already dismissed. Use @botai learn for rules you want applied before they'd otherwise be flagged.

The file is plain markdown — open it and delete a line directly to retract a learning; there's no @botai forget command.

Auto-resolve on push

When new commits are pushed to the PR branch, the reviewer checks if any previously flagged lines have changed. If a finding's line was modified, the comment thread is resolved automatically.

Auto-approve when all findings are resolved

Whenever @botai resolved (or @botai review with a resolved outcome) closes the last open bot finding on the PR, the bot submits a GitHub APPROVE review. This means developers don't need to run @botai approved separately once every finding is closed.