How to invoke PR-AF, what inputs it accepts, what outputs it produces, and how to integrate it into CI/CD pipelines.
PR-AF accepts reviews through three input modes, each with different context richness and speed tradeoffs.
POST /api/v1/execute/async/pr-af.review
{
"input": {
"pr_url": "https://github.com/owner/repo/pull/123",
"depth": "auto",
"max_cost_usd": 2.00
}
}What's fetched via GitHub API:
- PR metadata: title, description, labels, linked issues, author, reviewers
- Commit messages and commit SHAs (base + head)
- Diff: unified diff format with all changed files
- Full file contents at both base and head commits
- Repository file tree (for blast radius computation)
What's cloned (optional, for deep review):
- Full repository at HEAD for
.harness()agents to navigate freely - Configurable:
--clone(full clone),--shallow(depth=1),--no-clone(API only)
Authentication:
GH_TOKENenv var (personal access token or GitHub App installation token)- GitHub App: preferred for CI/CD (fine-grained permissions, higher rate limits)
Best for: CI/CD pipelines, GitHub Action triggers, full-featured review.
POST /api/v1/execute/async/pr-af.review
{
"input": {
"diff": "--- a/file.py\n+++ b/file.py\n@@ -1,3 +1,4 @@\n...",
"depth": "quick",
"max_cost_usd": 0.50
}
}What's available:
- The raw unified diff only
- No repo context, no PR metadata, no blast radius
- Limited to what's visible in the diff hunks
Limitations:
- Can't follow references or check blast radius
- Can't verify imports or check existing code patterns
- Planner generates fewer dimensions (less context to reason from)
- No GitHub comment output (no PR to post to)
Best for: Pre-commit hooks, local development, quick sanity checks, non-GitHub repos.
POST /api/v1/execute/async/pr-af.review
{
"input": {
"repo_path": "/path/to/repo",
"base_ref": "main",
"head_ref": "feature-branch",
"depth": "standard",
"max_cost_usd": 1.50
}
}What's available:
- Full repository on disk (fastest — no cloning needed)
- Git diff computed locally between base and head
- Full file contents at both commits
- Complete blast radius analysis
Output options: Markdown to stdout, JSON file, or post to GitHub if --pr <number> is provided.
Best for: Local development, self-hosted Git, testing the review before pushing.
name: PR Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
review:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for diff analysis
- uses: agentfield/pr-af-action@v1
with:
# Required
github-token: ${{ secrets.GITHUB_TOKEN }}
# Review depth (default: auto)
# auto: determines from PR size (small→quick, large→deep)
# quick: 2-3 dimensions, budget models, fast
# standard: 4-6 dimensions, mid-tier models
# deep: 8-12 dimensions, premium models, full coverage
depth: auto
# Focus areas (default: auto)
# auto: planner decides based on PR content
# Or specify: security, correctness, performance, tests, style
focus: auto
# Budget caps
max-cost: "2.00" # USD
max-duration: "300" # seconds
# Comment behavior
comment-mode: inline # inline | summary-only | both
review-event: auto # auto | comment | approve | request-changes
# Ignore patterns (glob)
ignore-paths: |
docs/**
*.md
.github/**
# AgentField configuration
agentfield-api-key: ${{ secrets.AGENTFIELD_API_KEY }}
model-tier: standard # budget | standard | premium
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}For organizations that want a persistent bot reviewer:
- Install the PR-AF GitHub App on your org/repo
- Configure via
.pr-af.ymlin repo root (see Configuration) - PR-AF automatically reviews all PRs that match the configured rules
- Posts reviews as
pr-af[bot]with configurable avatar
# Call the API endpoint with curl or httpx
curl -X POST https://agentfield.example.com/api/v1/execute/async/pr-af.review \
-H "Authorization: Bearer $AGENTFIELD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"diff": "'"$(git diff $CI_MERGE_REQUEST_DIFF_BASE_SHA...$CI_COMMIT_SHA)"'",
"depth": "standard",
"max_cost_usd": 2.00
}
}' \
-o review.json
# Post-process the JSON output with your platform's comment APIFor event-driven architectures:
# Start the PR-AF server
pr-af serve --port 8080
# Configure GitHub webhook:
# URL: https://your-server/webhook
# Events: Pull requests
# Content type: application/jsonThe server accepts GitHub webhook payloads and processes reviews asynchronously. Status is available via /jobs/{id}.
A single GitHub review with inline comments:
Review Summary:
Found 5 issues: 1 critical, 2 important, 2 suggestions
🔴 [Critical] SQL injection in user input handling
src/api/users.py:42
The raw query parameter is interpolated directly into the SQL query...
🟠 [Important] Missing error handling on payment callback
src/services/payment.py:87
If the Stripe webhook fails, the order status is never updated...
...
Each inline comment:
### 🟠 Missing null check before dereference
The `user.profile` access on line 42 can throw if `user` is null,
which happens when the auth middleware passes through anonymous requests
(see `src/middleware/auth.py:28`).
```suggestion
if user is None:
raise HTTPException(status_code=401, detail="Authentication required")
profile = user.profileFound by: Authorization Completeness · Confidence: 0.85 · correctness
### 2. Structured JSON
```json
{
"review_id": "rev_abc123",
"pr_url": "https://github.com/owner/repo/pull/123",
"review_event": "COMMENT",
"summary": {
"total_findings": 5,
"by_severity": {"critical": 1, "important": 2, "suggestion": 2},
"review_dimensions": 4,
"ai_generated_confidence": 0.1,
"cost_usd": 1.23,
"duration_seconds": 45
},
"findings": [
{
"id": "f_001",
"dimension": "Input Validation",
"file_path": "src/api/users.py",
"line_start": 42,
"line_end": 42,
"severity": "critical",
"confidence": 0.92,
"title": "SQL injection in user input handling",
"body": "The raw query parameter `user_id` is interpolated...",
"suggestion": "Use parameterized queries: `cursor.execute('SELECT * FROM users WHERE id = %s', (user_id,))`",
"evidence": "src/api/users.py:42 — `f\"SELECT * FROM users WHERE id = {user_id}\"`",
"tags": ["security", "injection", "cwe-89"],
"score": 1.196,
"multipliers": ["adversary_confirmed"]
}
],
"metadata": {
"intake": {"pr_type": "feature", "complexity": "standard"},
"anatomy": {"clusters": 3, "blast_radius_files": 12},
"plan": {"dimensions": 4, "ai_adjusted": false},
"budget": {"spent_usd": 1.23, "cap_usd": 2.00}
}
}
For GitHub Security tab integration:
{
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
"version": "2.1.0",
"runs": [{
"tool": {"driver": {"name": "PR-AF", "version": "1.0.0"}},
"results": [{
"ruleId": "pr-af/input-validation",
"level": "error",
"message": {"text": "SQL injection in user input handling"},
"locations": [{
"physicalLocation": {
"artifactLocation": {"uri": "src/api/users.py"},
"region": {"startLine": 42}
}
}]
}]
}]
}pr-af review --output markdown --output-file review.mdFull report with executive summary, findings by severity, and recommendations.
# .pr-af.yml — checked into repo root
# Review depth
depth: auto # auto | quick | standard | deep
# Budget
budget:
max_cost_usd: 2.00
max_duration_seconds: 300
model_tier: standard # budget | standard | premium
# Ignore patterns (glob)
ignore:
- "docs/**"
- "*.md"
- ".github/**"
- "vendor/**"
- "node_modules/**"
- "**/*.generated.*"
# Auto-depth rules (override 'auto' behavior)
depth_rules:
- match: "src/auth/**"
depth: deep # Always deep-review auth changes
- match: "migrations/**"
depth: deep # Always deep-review schema changes
- match: "scripts/**"
depth: quick # Light review for scripts
- match_label: "hotfix"
depth: deep # Hotfixes get deep review
# Custom review hints
# These are passed to the planner as additional context
# (not hardcoded rules — the planner decides how to use them)
hints:
- "This project uses SQLAlchemy ORM — raw SQL queries are a code smell"
- "All API endpoints must use Pydantic models for request/response validation"
- "Payment-related code must handle idempotency"
# Comment preferences
comments:
min_severity: suggestion # Only post suggestion+ (skip nitpicks)
max_comments: 20 # Cap inline comments to avoid overwhelming
include_suggestions: true # Include ```suggestion blocks
group_by_file: false # Or group related findings| Variable | Required | Description |
|---|---|---|
GH_TOKEN |
Yes (for GitHub output) | GitHub PAT or App installation token |
AGENTFIELD_API_KEY |
Yes | AgentField platform API key |
OPENROUTER_API_KEY |
Yes | LLM provider API key |
PR_AF_CONFIG |
No | Path to config file (default: .pr-af.yml) |
PR_AF_DEPTH |
No | Override review depth |
PR_AF_MAX_COST |
No | Override max cost |
Cost depends on PR size and review depth. These assume standard complexity.
| PR Size | Quick | Standard | Deep |
|---|---|---|---|
| Small (< 100 lines, 1-3 files) | ~$0.10-$0.20 | ~$0.30-$0.60 | ~$0.80-$1.50 |
| Medium (100-500 lines, 4-10 files) | ~$0.20-$0.40 | ~$0.60-$1.20 | ~$1.50-$3.00 |
| Large (500-2000 lines, 10-30 files) | ~$0.40-$0.80 | ~$1.00-$2.00 | ~$3.00-$6.00 |
| Massive (2000+ lines, 30+ files) | ~$0.60-$1.20 | ~$1.50-$3.00 | ~$5.00-$10.00 |
The auto depth setting uses PR size to select: small → quick, medium → standard, large+ → deep.
Budget caps prevent runaway costs. If a review hits the cost cap, it stops gracefully: posts whatever findings it has, notes the early termination in the summary, and reports partial coverage.