English | 简体中文
A GitLab Merge Request reviewer agent built with github-copilot-sdk, FastAPI, and React.
- Automatically configures a GitLab project webhook from the web UI
- Listens for Merge Request note events from GitLab
- Triggers a review when a comment contains a configured keyword such as
/copilot-review - Clones the MR code, analyzes the diff with the Copilot SDK, and posts the review back to GitLab
- Posts both a summary note and inline discussions
- Supports per-project review language configuration
- Stores job status, logs, and project settings locally
- Streams live Copilot job logs over SSE
- Displays timestamps in
Asia/Shanghai
backend/: Python FastAPIfrontend/: React + Vite
flowchart LR
User -->|configure webhook| BE[Backend FastAPI]
BE -->|register webhook| GitLab
User -->|comment /copilot-review| GitLab
GitLab -->|note webhook| BE
BE -->|clone + diff + prompt| SDK[Copilot SDK]
SDK -->|default| CopilotSub[GitHub Copilot subscription]
SDK -->|custom provider| OpenAI[OpenAI-compatible API\ne.g. Ollama / Azure / DeepSeek]
SDK -->|structured review| BE
BE -->|post comments| GitLab
BE -->|SSE log stream| User
- The user opens the web UI and enters a GitLab project URL.
- The frontend calls
/api/projects/setupon FastAPI. - The backend uses the GitLab API to create or update a Merge Request note webhook.
- The backend stores the project configuration locally, including the webhook secret, trigger keyword, and review language.
- The user comments a trigger keyword such as
/copilot-reviewon a GitLab Merge Request. - GitLab sends a note webhook to
/api/webhooks/gitlab. - The backend validates the webhook token, checks that the event is an MR note, and verifies that the trigger keyword is present.
- If valid, the backend creates a review job and schedules it in the background.
- The review service fetches Merge Request metadata and changed files from GitLab.
- The backend clones or updates a local repository snapshot and generates a unified diff.
- The backend starts a Copilot SDK session, sends the review prompt, and streams model events into the job log.
- The Copilot SDK returns a structured review result.
- The backend converts that result into a summary note plus inline discussions and posts them back to GitLab.
- The frontend reads review job status and historical logs from the backend.
- The frontend subscribes to the SSE log stream for live Copilot execution output.
- The user sees queued, running, completed, or failed status in the UI and can inspect the full Copilot log stream.
- Use the repo-local Python environment:
./.venv - Copy
.env.exampleto.envand fill in the required values - Ensure GitHub Copilot is already authenticated on the machine
- Node.js and npm are required for frontend build/dev
Create your local config first:
cp .env.example .envRequired variables:
GITLAB_TOKEN: GitLab token with API accessPUBLIC_BASE_URL: Public base URL reachable by GitLab webhook delivery
Common optional variables:
APP_PORT: Backend/UI unified port in production, default8001CORS_ORIGINS: Comma-separated list or JSON arrayREVIEW_TRIGGER_KEYWORD: Default trigger keywordDEFAULT_REVIEW_LANGUAGE: Default review languageCOPILOT_MODEL: Copilot model nameCOPILOT_TIMEOUT_SECONDS: Copilot review timeout in seconds, default3600INLINE_MIN_SEVERITY: Minimum inline severity, defaultmedium
See .env.example for the full variable list.
Backend:
./.venv/bin/pip install -r backend/requirements.txt
./.venv/bin/python backend/run.pyFrontend:
cd frontend
npm install
npm run devDevelopment URLs:
- Frontend:
http://localhost:5173 - Backend API:
http://localhost:8001
Notes:
- In development, Vite now proxies
/apitohttp://localhost:8001 - You usually do not need to set
VITE_API_BASE
In production, the frontend is built once and served by FastAPI on the same port as the backend API.
That means both UI pages and /api/* are exposed from a single service, defaulting to port 8001.
./.venv/bin/pip install -r backend/requirements.txt
cd frontend
npm ci
cd ..cd frontend
npm run build
cd ..This generates frontend/dist, which FastAPI serves automatically.
./.venv/bin/python backend/run.pyProduction URL:
- App + API:
http://localhost:8001
Examples:
- UI homepage:
http://localhost:8001/ - API health:
http://localhost:8001/api/health - GitLab webhook:
http://localhost:8001/api/webhooks/gitlab
If you place Nginx or another reverse proxy in front, keep FastAPI on 127.0.0.1:8001 and proxy all traffic to it.
Because the frontend is already served by FastAPI, you still only need one upstream app port.
- Open the web UI
- Enter a GitLab project URL
- Choose the trigger keyword and review language
- Click Configure Webhook
- Add the trigger keyword in an MR comment, for example
/copilot-review - Wait for Copilot to finish and post the review back to the MR
- Open the job log viewer to inspect the live SSE stream
- GitLab Project:
https://gitlab.com/agentic-devops/demo-app-02 - Public Webhook Base URL:
https://lkjdp2fh-8001.jpe1.devtunnels.ms - Default trigger keyword:
/copilot-review
- Project configs:
backend/data/project_configs.json - Review jobs:
backend/data/review_jobs.json - Job logs:
backend/data/job_logs/

