An opinionated, LLM‑powered pull request triage and review service. It ingests GitHub PR webhooks, fetches the diff and changed files, then runs a small LangGraph workflow of focused “agents” to produce a concise, actionable review in Markdown.
- Stack: FastAPI, LangChain, LangGraph, Groq (Llama 3.x), httpx
- Agents: Router → Diff Analyst → Standards → Test → Reviewer
- Output: A single structured Markdown review (currently printed to logs; posting back to GitHub can be added easily).
- Webhook endpoint for GitHub
pull_requestevents - GitHub API integration to fetch unified diff and changed files (auth optional for public repos)
- Multi‑agent workflow (LangGraph) specialized for:
- Diff summarization and risk detection
- Repository standards/guidelines checks
- Test coverage and missing test suggestions
- Final synthesized review with actionable items
- Configurable limits via environment variables to keep within model context
- GitHub sends a
pull_requestwebhook (opened,synchronize, orready_for_review) to this service. - The service fetches the PR diff and the list of changed files from the GitHub API (using
GITHUB_TOKENif provided). - A LangGraph pipeline runs:
- Router infers domains (backend/frontend/infra/docs)
- Diff Analyst summarizes changes and risks
- Standards checks against
constants.REPO_GUIDELINES - Test Agent suggests missing tests
- Reviewer synthesizes a final Markdown review
- The review is returned in the API response preview and logged. (Hooking this up to comment on the PR is straightforward to add next.)
server.py– FastAPI app exposingGET /andPOST /webhook/githubreview_core.py– Multi‑agent orchestration and public API (run_pr_workflow,generate_pr_review)agents/– Individual agents (router.py,diff_analyst.py,standards.py,test_agent.py,reviewer.py,types.py,utils.py)llm_client.py– Groq client setup and_call_llmhelperconstants.py– Repository guidelines (REPO_GUIDELINES) used by the Standards Agenttext_utils.py– Helpers to truncate large inputsrequirements.txt– Python dependencies
- Python 3.10+
- A Groq API key (required)
- Optionally a GitHub token (recommended for higher rate limits and private repos)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtCreate a .env file in the project root:
cp .env.example .env # if you create one; otherwise make it manuallyMinimum required entries:
GROQ_API_KEY=your_groq_api_key_here
# Optional overrides:
GROQ_MODEL=llama-3.1-8b-instant
GITHUB_TOKEN=ghp_... # optional but recommended- LLM:
GROQ_API_KEY(required)GROQ_MODEL(default:llama-3.1-8b-instant)
- GitHub:
GITHUB_TOKEN(optional) – used for diff/files fetching; unauthenticated fallback is attempted for public repos
- Truncation / sizing knobs:
MAX_DIFF_CHARS(default: 20000) – trim incoming PR diff before the workflowMAX_CHANGED_FILES(default: 200) – limit number of file paths passed to agentsAGENT_DIFF_MAX_CHARS– per‑agent diff trim (agents use their own sensible defaults)REVIEWER_SECTION_MAX_CHARS– per‑section cap inside Reviewer
You can also customize repository guidelines by editing constants.py (REPO_GUIDELINES).
uvicorn server:app --host 0.0.0.0 --port 8000 --reloadHealth check:
curl http://localhost:8000/Expect:
{"status":"ok","message":"PR triage assistant is running"}- In your GitHub repo: Settings → Webhooks → Add webhook
- Payload URL:
https://YOUR_DOMAIN/webhook/github(or your ngrok URL) - Content type:
application/json - Secret: (not required by this server as-is; you may add verification later)
- Events: “Let me select individual events” → enable only “Pull requests”
- Active: checked
The server currently processes only these actions: opened, synchronize, ready_for_review.
If you prefer to receive real GitHub webhooks locally, you can expose your machine using a tunnel. This repo includes ngrok binaries for convenience.
./ngrok http 8000
# copy the https URL it prints, e.g. https://abcd-12-34-56-78.ngrok-free.app
# set your GitHub webhook Payload URL to: https://<ngrok-host>/webhook/githubYou can simulate a minimal pull_request event to check request handling (note this won’t fetch a real diff without valid repo info):
curl -X POST http://localhost:8000/webhook/github \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: pull_request" \
-d '{
"action": "opened",
"pull_request": {
"title": "Sample PR",
"body": "Adds a new feature",
"number": 1,
"url": "https://api.github.com/repos/owner/repo/pulls/1",
"diff_url": "https://github.com/owner/repo/pull/1.diff"
},
"repository": {
"name": "repo",
"owner": { "login": "owner" }
}
}'If the GitHub endpoints are reachable and the PR exists (and access is permitted), the server will fetch the diff and files, run the workflow, and log the review.
Use generate_pr_review directly if you already have the diff and file list:
from review_core import generate_pr_review
pr_title = "Improve retry logic"
pr_body = "Refactors client and increases resilience; no API changes."
diff_text = "... unified diff ..."
changed_files = ["src/client.py", "tests/test_client.py"]
review_markdown = generate_pr_review(pr_title, pr_body, diff_text, changed_files)
print(review_markdown)Or run the full graph via run_pr_workflow (same signature; trims inputs and executes the agent pipeline).
- Post the review back to GitHub:
- After
run_pr_workflow, call the GitHub Issues/PRs Comments API to create a comment with the generated Markdown.
- After
- Add/modify agents:
- Add a new agent in
agents/and wire it into the graph inreview_core.py.
- Add a new agent in
- Customize standards:
- Edit
constants.py(REPO_GUIDELINES) to reflect your org’s policies.
- Edit
- “GROQ_API_KEY is not set” at startup
- Create
.envwithGROQ_API_KEY=...or export it in your shell
- Create
- Receiving 401/403 on GitHub API calls
- Ensure
GITHUB_TOKENhas repo read access, or test with a public repo
- Ensure
- Large PRs get truncated
- Increase
MAX_DIFF_CHARS/MAX_CHANGED_FILESor the agent‑specific caps, mindful of model context limits
- Increase
- Empty review or very short output
- Check logs for LLM errors/rate limits; reduce input size or retry
- Be mindful that PR contents will be sent to the LLM provider (Groq). Review your data handling and provider policies before enabling on private code.
- If needed, route through a proxy or implement redaction.
Apache-2.0 (or update to your chosen license).