Dev Mind is an intelligent, agentic system designed to autonomously analyze GitHub repositories for security vulnerabilities, propose fixes, and automatically create Pull Requests with the corrected code. It leverages a sophisticated multi-layered architecture combining LangGraph for workflow orchestration and FastAPI for high-performance API handling.
At its core, Dev Mind acts as an autonomous security engineer that can:
- Ingest Repositories: Pull entire codebases from GitHub via the GitHub API.
- Intelligent Triage: Identify high-risk files likely to contain vulnerabilities.
- Deep Security Analysis: Perform line-by-line code analysis using specialized LLMs.
- Human-in-the-Loop (HITL): Present proposed fixes to the user for approval.
- Automated Remediation: Automatically create a Pull Request with the security fixes once approved.
This eliminates manual security auditing and allows developers to receive instant, actionable security improvements for their repositories.
The system is divided into two primary components:
The gateway is a stateless, asynchronous FastAPI application that serves as the bridge between the frontend client and the complex agentic backend. It handles all incoming requests, manages conversation threads, and ensures smooth communication.
Key Features:
- Asynchronous & Stateless: Built on
async/awaitpatterns, capable of handling multiple concurrent requests efficiently without maintaining server-side session state. - PostgreSQL Checkpointing: Uses
AsyncPostgresSaverto persist agent state (conversation history, files loaded, pending fixes) per thread. This allows the agent to resume exactly where it left off, even after server restarts. - Rate Limiting: Integrated with
slowapito apply rate limits (e.g., 60 requests/minute) per client IP, ensuring fair usage and system stability. - Interrupt Handling: The gateway detects when the agent pauses at a breakpoint (waiting for human approval) and returns a special
interruptresponse to the client. The client can then prompt the user and send a/resumerequest with their decision. - Response Processing: A custom
_build_response()function strips internal tool-call messages and enriches responses with metadata like token usage, latency, and reasoning content.
API Endpoints:
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/api/v1/chat |
POST | Send a message to the agent |
/api/v1/chat/resume |
POST | Resume an interrupted workflow |
/api/v1/chat/history |
GET | Get conversation history |
/api/v1/chat/delete |
DELETE | Delete a thread |
The agent is built using LangGraph, a framework for building stateful, multi-step LLM applications. It uses a graph-based workflow where each node performs a specific task, and edges define how the agent transitions between tasks.
The main agent handles general conversation and orchestrates the security analysis pipeline.
Nodes:
summarizeNode: Before sending messages to the LLM, this node checks if the conversation is getting too long. If the token count exceeds a threshold (5000 tokens) or if recent messages exceeds 10, it summarizes older messages. This prevents hitting model limits and reduces costs.llmNode: Invokes the llm with system prompt + list of messages. To no exceed the context window agent only select messages after no. of messages summarized in order to have best of both, in one you are getting summary of previous messages as well as you are limiting to reach the context windowagentNode: The core reasoning node. It uses a dual-LLM strategy:- Fast LLM (e.g.,
openai/gpt-oss-120b): Handles routing, tool selection, and general conversation. - Reasoning LLM (e.g.,
groq/compound): Used for deep security analysis in the security subgraph.
- Fast LLM (e.g.,
toolsNode: Executes tool calls requested by the LLM (e.g., fetching GitHub user info, loading repositories).securityNode: Triggers the Security Subgraph when vulnerability analysis is required.
Routing Logic (should_continue):
- If the LLM requests a tool → go to
toolsnode. - If files are loaded in state (
injection_toolwas called) → go tosecuritynode. - Otherwise → end the flow.
The security subgraph is a specialized, isolated workflow for vulnerability analysis. It is invoked by the main agent when a user requests security analysis.
Nodes:
-
vulnerability_node(Triage): Analyzes the list of loaded files and identifies high-risk files based on naming patterns (e.g.,auth,login,db,sql,config). It uses fan-out to send multiple files to the next node in parallel. -
analyze_and_fix_node: For each risky file, this node performs a deep, line-by-line security audit using the Reasoning LLM. It checks for:- Injection flaws (SQL, Command, LDAP)
- Broken authentication & hardcoded secrets
- Sensitive data exposure
- XSS, SSRF, insecure deserialization
- Path traversal, IDOR vulnerabilities
If a vulnerability is found, it generates a fixed version of the code.
-
hitlNode: This is a critical interrupt point. It pauses execution and prompts the user (via the gateway) with the question: "Do you want to raise a PR?" with options["Yes", "No"]. -
raise_prNode: If the user approves, this node uses the GitHub API to:- Create a new branch (
security-fixes-{timestamp}) - Create blobs (file contents) for each fixed file
- Create a commit with all fixes
- Open a Pull Request against the base branch
- Create a new branch (
-
reset_node: Clears the security state (files, pending fixes, repo context) and returns control to the main agent.
The agent has access to several tools that it can call during conversation:
| Tool | Description |
|---|---|
injection_tool |
Fetches an entire GitHub repository (username + repo_name + branch) via the GitHub API, filters out binaries/ignored files, and loads the file contents into the agent's state. |
get_github_user |
Fetches the authenticated user's profile from GitHub, including their public data and profile README. |
find_project |
(In tools) Allows the user to select a repository and branch for security analysis. |
The agent uses typed state dictionaries to manage data flow:
AgentState: The main state containing messages, summary, files, repo context, and user context.SecurityState: A specialized state for the security subgraph, includingpending_fixes(dictionary of file paths to proposed fixes) andpr_approval(boolean).
Here is the step-by-step flow when a user requests security analysis:
- User Request: The user sends
/securityanalysisvia the gateway. - Tool Invocation: The main agent invokes the
find_projecttool to let the user select a repo and branch. - Repository Injection: The agent calls
injection_toolwith the selected username, repo, and branch. - State Update: The tool fetches the repo via GitHub API, filters it, and stores all file contents in the agent's state (
state["files"]). - Security Trigger: The
should_continuefunction detects that files are loaded and routes to thesecuritynode. - Subgraph Invocation: The security subgraph is invoked with the files and repo context.
- Triage:
vulnerability_nodeanalyzes the file list and identifies risky files (e.g., files with "auth", "db", "config" in their names). - Parallel Analysis: For each risky file,
analyze_and_fix_noderuns in parallel, analyzing the code and generating fixes if vulnerabilities are found. - Human-in-the-Loop: The
hitl_nodeinterrupts the flow and sends an interrupt response to the gateway. - User Approval: The gateway returns the interrupt to the frontend. The user sees the proposed fixes and clicks "Yes" to approve.
- Resume: The frontend sends a
/resumerequest with"Yes". - PR Creation: The
raise_pr_nodecreates a new branch, commits the fixes, and opens a Pull Request. - Reset: The
reset_nodeclears the security state and returns control to the main agent. - Response: The gateway returns the final response to the user, including the PR URL.
| Model | Score |
|---|---|
| openai/120b | 4.81/5 |
| qwen3.6/27b | 4.88/5 |
| llama/70b | 3.81/5 |
| Model | p50 | p99 |
|---|---|---|
| openai/120b | 3.8 | 9.54 |
| qwen3.6/27b | 3.51 | 4.12 |
| llama/70b | 2.09 | 2.5 |
| Model | Input_Tokens | Output_Tokens |
|---|---|---|
| openai/120b | 2.1k | 6.2k |
| qwen3.6/27b | 2.8k | 6.4k |
| llama/70b | 2.6 | 3 |
-
Token Limit Management: Models like Groq and local LLMs have strict token limits (~6k total). Implemented a summarization node that compresses old conversation history into bullet points, capping input tokens and preventing "out-of-context" errors.
-
Complex State & Graph Design: Designing state schemas (
AgentState,SecurityState) and orchestrating the main graph with the security subgraph required careful handling of data flow, parallel execution (fan-out), and state isolation. This was solved using LangGraph'sSendfor parallel node invocation. -
Stateless Async Gateway: Built a fully asynchronous FastAPI gateway that maintains no internal state but relies on PostgreSQL for persistent checkpointing, ensuring scalability and fault tolerance.
-
Frontend Interrupt Handling: Solved the challenge of integrating agent interrupts (LangGraph's
interrupt()) with a stateless HTTP API. The gateway detects paused states, returns a special interrupt response, and provides a/resumeendpoint for the frontend to continue the workflow. -
End-to-End Automation: Successfully orchestrated the entire pipeline from repository ingestion → vulnerability analysis → code fixing → GitHub API interactions → Pull Request creation.
This project forms the core foundation for a broader suite of developer tools. Two additional projects are built on top of this architecture, extending its capabilities:
All three projects share the same core architectural patterns (LangGraph orchestration, async gateway, HITL interrupts) and are designed to work together as a unified developer productivity platform.
