🇬🇧 English | 🇨🇳 简体中文
A team-oriented code review agent platform built from scratch with TypeScript. Supports three agentic architectures (ReAct / Plan & Execute / Reflection), asynchronous PR review, human-in-the-loop evaluation, and streaming SSE output.
Live Demo: code-agent-rosy.vercel.app
┌──────────────────────────────────────────────────────────────────────┐
│ Browser │
│ ┌────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ TaskSidebar │ │ InputPanel │ │ ResultPanel │ │
│ │ multi-task │ │ code + PR │ │ agent stream │ │
│ │ management │ │ URL input │ │ + eval label │ │
│ └────────────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ useAgent (useReducer) ──┘ │
│ + usage limit (localStorage) │
└─────────────────────────┼────────────────────────────────────────────┘
│ SSE stream
┌─────────────────────────┼────────────────────────────────────────────┐
│ Next.js 15 (App Router) │
│ │ │
│ ┌───────────────────────┴──────────────────────────┐ │
│ │ Orchestrate Stream │ │
│ │ dispatch(mode) → phase: executing │ │
│ │ ├─ react-runtime (while loop) │ │
│ │ ├─ plan-execute-runtime (plan → exec → summary)│ │
│ │ └─ reflection-runtime (actor → eval → reflect)│ │
│ │ → phase: verifying (optional) │ │
│ │ └─ independent verifier checks output quality │ │
│ └───────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌──────────┐ ┌─────┴──────┐ ┌──────────────┐ │
│ │ Memory │ │ Tool Exec │ │ Safety │ │
│ │ ├─short │ │ ├─readFile│ │ ├─path sandbox│ │
│ │ ├─context│ │ ├─search │ │ ├─dedup check │ │
│ │ └─durable│ │ ├─listDir │ │ ├─secret redact│ │
│ └──────────┘ │ ├─write │ │ └─approval │ │
│ │ └─analyze │ └──────────────┘ │
│ └─────┬──────┘ │
│ │ │
│ ┌───────────────────┴───────────────────┐ │
│ │ PostgreSQL (Prisma) │ │
│ │ ├─ Task (multi-session persistence) │ │
│ │ ├─ Evaluation (human labels) │ │
│ │ ├─ PrReview (PR diff cache) │ │
│ │ └─ UsageLimit (rate limiting) │ │
│ └───────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
| Layer | Technology | Notes |
|---|---|---|
| Framework | Next.js 15 (App Router) | API Routes, SSE streaming, React 19 |
| Language | TypeScript 5.7 | Strict mode, full type coverage |
| Styling | Tailwind CSS v4 + shadcn/ui | Dark mode, design tokens, responsive |
| Icons | Lucide React | Consistent icon system |
| Database | PostgreSQL (Prisma ORM v7) | Pg adapter, Neon serverless |
| AI SDK | @anthropic-ai/sdk |
DeepSeek v4 via Anthropic-compatible protocol |
| Embedding | BGE-M3 (SiliconFlow API) | 1024-dim vectors |
| Deployment | Vercel | Auto-deploy on push |
git clone https://github.com/Zoella-w/code-agent.git
cd code-agent
npm installCreate .env.local:
ANTHROPIC_API_KEY=your-deepseek-api-key
SILICONFLOW_API_KEY=your-siliconflow-api-key
DATABASE_URL=your-postgres-connection-string
MODEL_PROVIDER=deepseek # deepseek | claude
DEMO_OWNER_SECRET=your-random-secret # optional, for usage-limit bypassnpx prisma db push # sync schema to database
npm run dev # start at http://localhost:3000src/
├── agent/ # Core Agent Engine
│ ├── orchestrate.ts # Unified orchestration entry (mode dispatch + optional verify)
│ ├── react-runtime.ts # ReAct loop: Thought → Action → Observation
│ ├── plan-execute-runtime.ts # Plan & Execute: plan → exec steps → summarize
│ ├── reflection-runtime.ts # Reflection: actor → evaluator → reflector (≤3 rounds)
│ ├── model-client.ts # LLM client (Anthropic-compatible, multi-provider)
│ ├── prompt-builder.ts # System prompt assembly
│ ├── tool-defs.ts # 5-tool schema definitions
│ ├── tools.ts # Tool registry (getAllNames / getAllDefs)
│ ├── tool-executor.ts # Tool execution + safety guardrails
│ ├── memory.ts # Short-term memory (conversation + file summaries)
│ ├── context-manager.ts # 3-tier progressive context compression
│ ├── durable-memory.ts # Long-term memory (file persistence)
│ ├── episodic-notes.ts # Episodic notes (12-cap, tag-weighted retrieval)
│ ├── executor-store.ts # Approval mode state management
│ ├── run-store.ts # Run/trace persistence (JSONL + JSON)
│ ├── workspace.ts # Git-aware project context scanner
│ ├── eval-store.ts # Human-label evaluation samples
│ └── rag/ # RAG subsystem
│ ├── rag-pipeline.ts
│ ├── document-loader.ts
│ ├── multi-format-loader.ts
│ ├── mem-vector-store.ts
│ ├── siliconflow-embedding.ts
│ ├── bm25.ts
│ ├── hybrid-search.ts # RRF fusion
│ ├── rerank.ts # BGE-Reranker
│ ├── evaluate.ts # Faithfulness + Answer Relevancy
│ └── parsers/ # text / pdf / image parsers
├── app/
│ ├── layout.tsx # Root layout (branded header + theme toggle)
│ ├── page.tsx # Main page (3-panel layout)
│ ├── globals.css # Design tokens + dark mode
│ └── api/agent/
│ ├── orchestrate/route.ts # Main SSE endpoint (all modes)
│ ├── pr-review/route.ts # GitHub PR review endpoint
│ ├── pr-comment/route.ts # Post review as PR comment
│ ├── approve/route.ts # Tool approval resolution
│ ├── eval/route.ts # Evaluation CRUD
│ ├── tasks/route.ts # Task persistence
│ └── memory/route.ts # Durable memory CRUD
├── components/
│ ├── InputPanel.tsx # Code editor + PR URL + mode selector
│ ├── ResultPanel.tsx # 4-state display (idle/running/done/error)
│ ├── TaskSidebar.tsx # Multi-task management
│ ├── TraceViewer.tsx # Execution trace bottom sheet
│ ├── ToolCallCard.tsx # Collapsible tool call detail card
│ ├── EvalDashboard.tsx # Evaluation statistics
│ ├── EvalLabeler.tsx # Human label submission
│ ├── MarkdownRenderer.tsx # Markdown with syntax highlighting
│ ├── tool-icons.ts # Lucide icon mapping for tools
│ ├── theme-provider.tsx # Dark/light theme context
│ └── ui/ # shadcn/ui primitives
├── hooks/
│ ├── useAgent.ts # Global state (useReducer) + SSE consumption + usage limit
│ └── useDarkMode.ts # Reactive dark mode detection
├── lib/
│ ├── prisma.ts # Prisma client singleton
│ ├── usage-limit.ts # IP-based rate limiting (atomic upsert)
│ └── utils.ts # cn() helper
└── prompts/
└── prompt-templates.ts # Reusable prompt library
| Mode | Mechanism | Best For |
|---|---|---|
| ReAct | Thought → Action → Observation loop | General code review |
| Plan & Execute | Plan steps → Execute each → Summarize | Complex multi-step analysis |
| Reflection | Actor → Evaluator → Reflector (≤3 rounds) | Self-correcting reviews |
After any mode completes, an independent verifier LLM inspects the output for false positives, missed issues, and overall quality. Outputs a structured VERDICT: PASS / FAIL with a detailed report. This is a post-hoc quality gate — orthogonal to the Reflection architecture's internal self-improvement loop.
| Tool | Function | Risk |
|---|---|---|
read_file |
Read file with line range | Safe |
search_code |
Regex code search | Safe |
list_directory |
Recursive directory listing | Safe |
write_file |
Write to file system | Requires approval |
analyze_code |
In-memory static analysis | Safe |
- Path sandbox: All paths converge to workspace root
- Duplicate detection: Identical tool+args calls blocked
- Secret redaction: Scans env values → replaces in output
- Approval mode: Dangerous operations require human confirmation via SSE
Short-term (memory.ts) → Conversation history + File summaries + SHA256 freshness
Context (context-manager.ts) → 3-tier compression: recent full / mid truncated / far summarized
Durable (durable-memory.ts) → File persistence + topic classification + dedup + API endpoint
Episodic (episodic-notes.ts) → 12-entry cap + tag-weighted keyword retrieval
| Tier | Range | Strategy |
|---|---|---|
| Recent | ≤ 3 turns | Keep full messages |
| Mid | 4–6 turns | Truncate content to 180 chars |
| Far | > 6 turns | Replace entire turn with one-line summary |
Measured: 11 turns, 5,587 → 985 tokens (82% compression).
Upload → MultiFormatLoader (text/pdf/image)
→ RecursiveSplitter (chunk=500, overlap=50)
→ BGE-M3 Embedding (SiliconFlow, 1024-dim)
→ MemVectorStore
→ HybridSearch (BM25 + vector + RRF fusion)
→ BGE-Reranker
→ Prompt assembly (role → docs+sources → rules → question)
Evaluation: Faithfulness (atomic claim verification) + Answer Relevancy (reverse question generation scoring).
Every review output can be labeled as accurate / inaccurate / partial with optional comments. Labels persist to PostgreSQL and feed a real-time accuracy dashboard. This closes the eval flywheel: human feedback → accuracy tracking → model/prompt improvement.
Per-IP rate limiting (3 requests) with atomic PostgreSQL upsert. The frontend intercepts via localStorage before any API call; the backend enforces at the route level before any LLM invocation. PR review mode only counts after a successful diff fetch (failed pulls don't consume quota). Author exemption via DEMO_OWNER_SECRET + x-demo-owner header.
Hand-written. Every line of the ReAct loop, tool execution, and prompt assembly is explainable in an interview. LangChain abstracts away the internals — you can't talk about what you didn't build.
DeepSeek. Supports Anthropic Messages API compatibility (api.deepseek.com/anthropic), costs < 1/10 of Claude. The ModelClient interface abstracts the provider — switching is a one-class change.
Unified dispatch. The orchestration layer (orchestrate.ts) routes to the correct runtime based on mode, then optionally runs the verification ring. This keeps the API surface clean (one endpoint) while demonstrating architectural depth.
Reflection is an execution strategy (self-correct within the runtime). Verification is a post-hoc quality gate (independent LLM inspects output). They are orthogonal and stackable: Reflection iterates to improve internally, Verification provides an external trust signal.
SSE. Agent output is a unidirectional stream (server → client). SSE is lighter than WebSocket: native HTTP, automatic reconnection, no handshake overhead. Next.js API Routes support it natively.
In-memory for now. Code review datasets are typically small (tens of files). The VectorStore interface is abstracted — swapping to Pinecone or pgvector is a one-class change, not an architecture rewrite.
Cosine. BGE-M3 vectors are normalized — cosine measures direction, not magnitude. Two semantically similar documents can have different vector lengths due to text length variance. Euclidean distance gets misled by length; cosine doesn't.
Progressive. A sliding window drops old but critical information (e.g., the user's original question). Three-tier compression preserves recent conversation fidelity while summarizing distant turns semantically — 82% token reduction without quality loss.
Deployed on Vercel with automatic git push deploy. Required environment variables:
| Variable | Purpose |
|---|---|
ANTHROPIC_API_KEY |
DeepSeek API key (Anthropic-compatible protocol) |
SILICONFLOW_API_KEY |
SiliconFlow API key (BGE-M3 + Reranker) |
DATABASE_URL |
PostgreSQL connection string (Neon serverless) |
MODEL_PROVIDER |
deepseek or claude |
DEMO_OWNER_SECRET |
Author bypass key for usage limit (optional) |
MIT