An AI coding agent that runs against a local codebase from the command line. RepoPilot reads, edits, and searches your codebase, runs git operations, and answers questions about how the code works using tool-calling, backed by semantic code search and persistent conversation memory.
$ python cli/app.py chat .
> where is the retry logic for failed LLM calls?
[RepoPilot] calling search_codebase({'query': 'retry logic failed LLM calls'})
...
RepoPilot exploring an unfamiliar codebase on its own — reading the repo structure, pulling the relevant file, and summarizing it without being told where to look:
- Agent loop with real tool use — the LLM drives a
read → search → edit → verifyloop via OpenAI-style function calling, orchestrated by a Router → Planner → Critic pipeline (trivial requests skip planning; the Critic can send a plan back for up to 2 retries). - Semantic code search (RAG) — the repository is chunked, embedded locally (
st-codesearch-distilroberta-base, runs on CPU, no API calls), and indexed in a persistent Chroma vector store. - Python-aware code intelligence — symbol lookup, reference finding, and signature extraction via Python's
astmodule. - Git-native tools — status, diff, log, blame, show, branch, stash, add, commit, checkout, all as thin subprocess wrappers over the real
gitbinary. - Persistent memory — conversation history is summarized and embedded across sessions, so the agent recalls earlier context about the repo without replaying full transcripts.
- Confirmation gating — destructive tools (write/edit/delete) require explicit confirmation before executing.
- Bounded tool loop — a global iteration budget caps how many tool calls a single request can make, including across Critic retries, so a bad plan can't loop forever.
| Category | Tools |
|---|---|
| File ops | read_file, write_file, edit_file, delete_file, list_files, search_files |
| Git | git_log, git_status, git_diff, git_blame, git_show, git_branch, git_stash, git_add, git_commit, git_checkout |
| Code intelligence | search_codebase (semantic RAG), find_symbol, find_references, get_signature |
| Repository | project_structure, repo_summary |
| Code quality | format_code |
cli/ entry point, argument parsing, first-run setup
src/agent/ agent loop, system prompt, conversation memory, context building
src/llm/ LLM client (OpenAI-compatible + LangChain), provider fallback
src/retrieval/ embeddings, Chroma vector store, symbol extraction, index manager
src/tools/ one module per tool, registered in a central ToolRegistry
src/repository/ language/framework detection, repo summarization
Each tool implements a small base class (name, description, parameters, run(**kwargs)) and is registered in src/tools/registery.py, which also converts the registry into OpenAI-style function schemas for the LLM. Adding a new tool is one file plus one registration line.
git clone https://github.com/Youssef-Bahaa/RepoPilot.git
cd RepoPilot
pip install -r requirements.txt
cp .env.example .env # fill in at least one LLM provider keyThe first sentence-transformers run downloads the embedding model (~500MB) from Hugging Face and caches it locally; expect a one-time delay on first use.
RepoPilot uses two different models for two different jobs:
| Job | Model | Where it runs | Cost |
|---|---|---|---|
| Chat / tool-calling (the agent itself) | Mistral or OpenRouter model, cascaded | Remote API | Per your provider's pricing (free tiers available on both) |
| Semantic code search (RAG) | flax-sentence-embeddings/st-codesearch-distilroberta-base |
Local, CPU | Free, no API key needed |
| Long-term memory embeddings | sentence-transformers/all-MiniLM-L6-v2 |
Local, CPU | Free, no API key needed |
Only the chat model needs an API key. Embeddings never leave your machine.
You need at least one of the two below. RepoPilot tries Mistral first, then falls back to OpenRouter if the request fails.
Mistral (primary provider)
- Go to console.mistral.ai and create an account.
- Navigate to API Keys in the left sidebar.
- Click Create new key, name it, and copy the value.
- Paste it into
.envasMISTRAL_API_KEY. Mistral has a free tier (rate-limited); no card required to start.
OpenRouter (fallback provider, optional but recommended)
- Go to openrouter.ai and sign in.
- Go to openrouter.ai/settings/keys.
- Click Create Key, name it, and copy the value.
- Paste it into
.envasOPENROUTER_API_KEY. OpenRouter gives access to several free-tier models from different labs through one key — useful as a backstop if Mistral is rate-limited. The default fallback model is set insrc/llm/config.py.
python cli/app.py chat <path-to-repo> # interactive session
python cli/app.py ask <path-to-repo> "<msg>" # single question, then exit
python cli/app.py reset <path-to-repo> # clear this repo's memoryUseful flags:
| Flag | Applies to | Effect |
|---|---|---|
--name NAME |
all commands | Display name for the repo (defaults to the folder name) |
--no-memory |
all commands | Disable long-term memory (skips Chroma + summarization) |
--yes |
ask |
Auto-approve all write/delete/format actions, no confirmation prompt |
--no-confirm |
ask |
Auto-reject all write actions (dry-run style) |
On first run with no provider key configured, the CLI will prompt for your Mistral key interactively and offer to save it to ~/.repopilot/.env (chmod 600) so you don't need to re-enter it per project.
Example session:
$ python cli/app.py ask . "what does the Executor class do?"
thinking...
The Executor orchestrates the Router -> Planner -> Critic pipeline: trivial
requests are handled directly, more complex ones get a plan from the
Planner, which the Critic can send back for revision (up to 2 retries)
before tools are executed.Actively developed, Python-only scope.
