An AI-powered agent that automatically reviews GitHub Pull Requests and posts a detailed, human-like code review as a comment β complete with critical fixes, suggestions, and emojis. π
Built on top of OpenAI Agents, Inngest (event-driven, durable step functions), Octokit (GitHub API), and Express.
- Overview
- Features
- Architecture
- How It Works
- Tech Stack
- Project Structure
- Getting Started
- Configuration
- Triggering a Review
- Agent Output Schema
- Security Notes
The GitHub PR Review Agent listens for a github/pullrequest.review event. When triggered, it:
- Fetches the pull request metadata from GitHub.
- Collects all the file changes (diffs / patches) in the PR.
- Sends everything to an LLM-powered reviewer agent (
gpt-4o). - Posts the structured review back to the PR as a comment.
The whole flow is orchestrated as durable steps using Inngest, so each stage is retried independently and survives failures.
- π§ AI Code Review β Uses OpenAI's
gpt-4omodel to analyze code changes. - π Durable & Retryable β Each stage runs as an isolated Inngest step.
- π¦ Structured Output β Enforced via a
zodschema (criticalFixes,suggestions,content,event). - π¦ Smart Skipping β Skips closed PRs or PRs with no changes.
- π¬ Auto-Commenting β Posts a formatted review comment directly on the PR.
- π Natural Tone β Reviews include emojis to feel human-friendly.
flowchart LR
A[GitHub PR Event] -->|github/pullrequest.review| B[Inngest Function]
B --> C[Express Server<br/>/api/inngest]
C --> D{{Durable Steps}}
D --> E[Octokit<br/>GitHub API]
D --> F[OpenAI Agent<br/>gpt-4o]
F -->|Structured Review| D
D -->|Post Comment| E
E --> G[(Pull Request<br/>Comment)]
The core logic lives in inngest/functions/github-review.js and executes four durable steps:
sequenceDiagram
participant EV as Event Trigger
participant FN as Inngest Function
participant GH as GitHub (Octokit)
participant AI as OpenAI Agent
EV->>FN: github/pullrequest.review<br/>{ owner, repo, pull_number }
Note over FN,GH: Step 1 β Fetch PR Info
FN->>GH: pulls.get()
GH-->>FN: PR metadata
alt PR not found or not open
FN-->>EV: Skip review βοΈ
end
Note over FN,GH: Step 2 β Fetch Changes
FN->>GH: pulls.listFiles() (paginated)
GH-->>FN: file diffs / patches
alt No changes
FN-->>EV: Skip review βοΈ
end
Note over FN,AI: Step 3 β AI Analysis
FN->>AI: run(agent, PR info + changes)
AI-->>FN: { criticalFixes, suggestions, content, event }
Note over FN,GH: Step 4 β Post Comment
FN->>GH: issues.createComment()
GH-->>FN: β
Comment posted
| Step | Name | Description |
|---|---|---|
| 1οΈβ£ | fetch-pull-request-information |
Gets PR title, state, number, commits, head ref/sha, etc. Skips if not found or not open. |
| 2οΈβ£ | fetch-changes |
Paginates through all changed files and extracts filename, status, patch, additions, deletions. Skips if empty. |
| 3οΈβ£ | ai-analysis |
Runs the OpenAI agent with the PR info + changes and returns a structured review. |
| 4οΈβ£ | post-comment |
Formats the review into sections and posts it as a GitHub PR comment. |
| Layer | Technology |
|---|---|
| Runtime | Node.js (ES Modules) |
| Web Server | Express v5 |
| Orchestration | Inngest β durable event-driven functions |
| AI Agent | @openai/agents (gpt-4o) |
| Schema Validation | Zod |
| GitHub API | @octokit/rest |
| Config | dotenv |
Github-PR-Review-Agent/
βββ agents/
β βββ github-pr-review-agent.js # OpenAI agent + zod output schema
βββ inngest/
β βββ client.js # Inngest client setup
β βββ functions/
β βββ github-review.js # Main 4-step review workflow
β βββ index.js # Exported functions array
βββ lib/
β βββ github.js # Octokit (GitHub API) client
βββ index.js # Express server + Inngest serve handler
βββ package.json
βββ Pipeline.png # Architecture diagram
βββ README.md
- Node.js 18+ (ES Modules support)
- A GitHub Personal Access Token (PAT) with repo access
- An OpenAI API key
- Inngest Dev Server (for local development)
# 1. Clone the repository
git clone <your-repo-url>
cd Github-PR-Review-Agent
# 2. Install dependencies
npm install
# 3. Create your environment file (see Configuration below)
cp .env.example .env
# 4. Start the server
node index.jsThe Express server starts on http://localhost:3000, exposing the Inngest endpoint at /api/inngest.
In a separate terminal, start the Inngest dev server so it can discover and trigger your functions:
npx inngest-cli@latest devThen open the Inngest Dev UI (usually at http://localhost:8288) to inspect and manually trigger events.
Create a .env file in the project root. Use the template below as .env.example:
# OpenAI API key used by the review agent
OPENAI_API_KEY="sk-..."
# GitHub Personal Access Token (repo scope)
GITHUB_PAT="github_pat_..."
# Enables Inngest dev mode
INNGEST_DEV="1"| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
β | API key used by @openai/agents to call gpt-4o. |
GITHUB_PAT |
β | GitHub token used by Octokit to read PRs and post comments. |
INNGEST_DEV |
βοΈ | Set to 1 for local Inngest development. |
The workflow listens for the github/pullrequest.review event. Send an event with the following payload:
{
"name": "github/pullrequest.review",
"data": {
"owner": "your-github-username",
"repo": "your-repo-name",
"pull_number": 42
}
}You can trigger it from the Inngest Dev UI, or programmatically:
import { inngest } from './inngest/client.js';
await inngest.send({
name: 'github/pullrequest.review',
data: { owner: 'octocat', repo: 'hello-world', pull_number: 42 },
});π‘ In production you'd typically wire a GitHub Webhook (on
pull_requestopened/synchronized) to forward these events to Inngest.
The agent returns a validated object (via zod) defined in agents/github-pr-review-agent.js:
{
criticalFixes?: string[] | null, // Must-fix issues
suggestions?: string[] | null, // Optional improvements
content: string, // Main review body
event: 'APPROVE' | 'COMMENT' | 'REQUEST_CHANGES'
}The post-comment step formats this into Markdown sections:
<content>
**Critical Changes:**
- ...
**Suggestions:**
- ...
- Never commit your
.envβ it is already listed in.gitignore. - Treat your
OPENAI_API_KEYandGITHUB_PATas secrets. If they are ever exposed, rotate them immediately. - Scope your GitHub PAT to the minimum permissions required (read PRs + write comments).
ISC Β© Contributors
