| agent_repo.py | ||
| app.py | ||
| Dockerfile | ||
| llm_client.py | ||
| mistral-api.sh | ||
| queue_helper.py | ||
| README.md | ||
| requirements.txt | ||
| smart_rag.py | ||
| windowing_utils.py | ||
Repo Agent & QA — LLM Proxy • OpenWebUI Tools • Agent Repo/QA
Een compacte, productierijpe stack om (1) chat/LLM-verzoeken af te handelen, (2) OpenWebUI-compatibele tools (STT/TTS/Retrieval) aan te bieden, en (3) een Repo Agent te draaien die kandidaten zoekt, diffs genereert (dry-run) en — na akkoord — schrijft & pusht op een nieuwe branch. Inclusief Repo-QA (vraag-antwoord over je codebase met padverwijzingen), Laravel-bewuste heuristiek, hybride retrieval (Meili/BM25 + embeddings/Chroma), slim chunking, niet-destructieve guards en een lichte graaf-boost (route ⇄ controller ⇄ view ⇄ lang).
Dockerfile inbegrepen (Python 3.11-slim), met o.a.
faster-whisper,piperTTS, Meili/Chroma-clients,gitpython,sentence-transformers,rank-bm25.
Inhoudsopgave
Architectuur in 3 onderdelen
| Onderdeel | Doel | Taken | Bestanden in deze repo |
|---|---|---|---|
| LLM Proxy | Dunne HTTP-laag voor chat/LLM + (optioneel) tool-calls; OpenWebUI-vriendelijk. | /chat endpoint, promptverrijking, streaming; kan tools/agent aanroepen. |
app.py (routes) |
| OpenWebUI-compatible Tools | Kleine helper-endpoints die je rechtstreeks vanuit OpenWebUI of de proxy kunt aanroepen. | STT (faster-whisper), TTS (piper), retrieval (Meili/BM25/Chroma), PDF/afbeelding utils. | app.py (tool-routes), helpers in queue_helper.py |
| Agent Repo & Repo QA | “De smid”: zoekt relevante files, bouwt context, maakt diffs (dry-run), en kan apply & push doen op nieuwe branch. QA over repo. | Kandidaten zoeken, slim chunken, LLM-editplannen, diff-guards, branch & push. Repo-QA antwoord met padbronnen. | agent_repo.py, smart_rag.py, windowing_utils.py, queue_helper.py |
Mijn advies (prod vs dev):
- Prod: scheid LLM Proxy + Tools (publiek) van Agent Repo/QA (afschermen; heeft Gitea-rechten).
- Dev: alles in één Uvicorn-app (zoals in deze Dockerfile) is prima.
Belangrijkste features
- Hybride retrieval: Meili/BM25 (file-niveau harde signalen) + Chroma/embeddings (chunk-niveau semantiek).
- Laravel-bewuste heuristiek: routes scannen, controller ↔ view ↔ lang keys, FormRequests/Policies.
- Slim chunken: taalspecifiek (PHP/Blade/JS/MD), functie/section-grenzen; overlap; contextbudget.
- Lichte graaf-boost: route ⇄ controller ⇄ view ⇄ lang relaties wegen mee in ranking.
- Niet-destructieve patches: diff-guard op deletieratio; kleine, anker-gebaseerde edits; sanity-checks.
- Repo-QA: compacte, bronverwijzende antwoorden (“Bronnen: padnamen”).
- OpenWebUI-tools: STT (faster-whisper), TTS (piper), retrieval als losse endpoints.
- Dry-run → Apply: eerst diffs tonen; na “Akkoord apply” nieuwe branch + push.
Snel starten
Docker (aanbevolen)
Dockerfile (samenvatting)
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN apt-get update && apt-get -y install git curl ffmpeg libcairo2 libpango-1.0-0 libgdk-pixbuf2.0-0 apt-utils
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install PyPDF2 python-multipart gitpython chromadb httpx meilisearch pandas openpyxl python-pptx faster-whisper==1.0.0 cairosvg sentence-transformers rank-bm25
# piper TTS
RUN apt-get update && apt-get install -y --no-install-recommends wget ca-certificates libstdc++6 libatomic1 \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /opt/piper \
&& set -eux; URL="https://github.com/rhasspy/piper/releases/download/2023.11.14-2/piper_linux_x86_64.tar.gz"; \
wget -O /tmp/piper.tgz "$URL"; tar -xzf /tmp/piper.tgz -C /opt/piper --strip-components=1; \
ln -sf /opt/piper/piper /usr/local/bin/piper; rm -f /tmp/piper.tgz
COPY app.py .
COPY queue_helper.py .
COPY agent_repo.py .
COPY windowing_utils.py .
COPY smart_rag.py .
EXPOSE 8080
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]
Build & run
# 1) Build
docker build -t repo-agent:latest .
# 2) Run (met voorbeeld-ENV; pas aan op jouw omgeving)
docker run --rm -p 8080:8080 \
-e MEILI_URL=http://host.docker.internal:7700 \
-e MEILI_MASTER_KEY=your_meili_key \
-e GITEA_URL=http://host.docker.internal:3000 \
-e GITEA_TOKEN=your_gitea_token \
-e REPO_AGENT_SMART=1 \
-e AGENT_DESTRUCTIVE_RATIO=0.25 \
-e RAG_GRAPH_ENABLE=1 \
repo-agent:latest
Tip: start MeiliSearch naast deze container (of gebruik bestaande). Chroma is optioneel; zonder Chroma valt retrieval semantisch terug op BM25/Meili.
Zonder Docker (dev)
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pip install PyPDF2 python-multipart gitpython chromadb httpx meilisearch pandas openpyxl python-pptx faster-whisper==1.0.0 cairosvg sentence-transformers rank-bm25
uvicorn app:app --host 0.0.0.0 --port 8080 --reload
Configuratie (ENV)
| Variabele | Betekenis | Default / Opmerking |
|---|---|---|
MEILI_URL, MEILI_MASTER_KEY |
MeiliSearch voor file-retrieval & (optioneel) indexing. | Aanbevolen. |
REPO_AGENT_SMART |
Schakel intent-/expansie + hybride retrieval in de agent. | 1 (aan) |
GITEA_URL, GITEA_TOKEN |
Nodig voor private repos en apply/push. | Sterk aanbevolen voor Agent. |
AGENT_DEFAULT_BRANCH |
Basisbranch om op te clonen/indexeren. | main (fallback master) |
AGENT_DESTRUCTIVE_RATIO |
Max. deletieratio vóór blokkeren (0–1). | 0.25 (voorbeeld) |
RAG_GRAPH_ENABLE |
Lichte graaf-boost op ranking inschakelen. | 1 (aan) |
RAG_EMB_WEIGHT |
Gewicht embeddings t.o.v. lexicaal signaal. | 0.6 typisch |
RAG_PER_QUERY_K, RAG_N_RESULTS |
Recall parameters hybrid retrieval. | 30 / 18 (voorbeeld) |
RAG_NEIGHBORS |
Laravel “buren” (routes→controllers→views). | 1 (aan) |
LLM_PRIORS_ENABLE, LLM_PRIORS_K |
LLM-gebaseerde pad-prior suggesties. | 1 / 12 |
LARAVEL_PRIORS_K |
Max #Laravel priors vóór RAG. | 8 |
CHUNK_CHARS_LARAVEL, CHUNK_OVERLAP_LARAVEL |
Chunkgrootte/overlap voor Laravel-stacks. | 1800 / 300 |
CHUNK_CHARS_DEFAULT, CHUNK_OVERLAP_DEFAULT |
Idem voor generieke stacks. | 2600 / 350 |
AGENT_QA_CTX_BUDGET_TOKENS |
Tokenbudget voor Repo-QA context. | 6000 |
QA_MIN_PER_SNIPPET, QA_MAX_PER_SNIPPET |
Contextdistributie per snippet. | 180 / 900 |
QA_KEEP_TOP_K |
Max snippets na trimming. | 8 |
NB: Veel van bovenstaande komen rechtstreeks terug in
agent_repo.py(zie env-reads aldaar). Waarden hierboven zijn “goede defaults”.
Endpoints
Endpoints staan in
app.py. Onderstaande is het standaardpatroon in deze setup.
1) LLM Proxy
POST /chat— voer een chat uit (optioneel met tool-calls)
Voorbeeld:
curl -X POST http://localhost:8080/chat \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"Geef een korte samenvatting van de meldingenmodule."}]}'
2) OpenWebUI-compatible Tools
POST /tools/stt— audio → tekst (faster-whisper)POST /tools/tts— tekst → audio (piper)POST /tools/retrieve— retrieval (Meili/BM25 + embeddings)
Voorbeeld:
curl -X POST http://localhost:8080/tools/retrieve \
-H "Content-Type: application/json" \
-d '{"query":"waar staat het wachtwoordbeleid?", "k": 12}'
3) Agent Repo & Repo QA
POST /agent/dryrun— genereer diffs, geen writesPOST /agent/apply— schrijf & push (na akkoord)POST /qa/ask— Repo-QA met paden als bronnen
Voorbeelden:
# Dry-run diffs
curl -X POST http://localhost:8080/agent/dryrun \
-H "Content-Type: application/json" \
-d '{"repo":"owner/project","user_goal":"Vervang \"Versturen\" → \"Verzenden\" in meldingen-create"}'
# Apply (na akkoord)
curl -X POST http://localhost:8080/agent/apply \
-H "Content-Type: application/json" \
-d '{"repo":"owner/project","confirm":"Akkoord apply"}'
# Repo-QA
curl -X POST http://localhost:8080/qa/ask \
-H "Content-Type: application/json" \
-d '{"repo":"owner/project","question":"Waar wordt de storing-aanmaak afgehandeld?"}'
Hoe het werkt (flow prompt → diffs/qa)
Samengevatte pipeline (Agent Repo):
-
Prompt binnen → intent & scope (optioneel refine; NL/EN synonyms).
-
Repo selecteren → clone/update op basisbranch; meelifall-cache.
-
Candidate discovery (hybride)
- Meili/BM25 (file-niveau, hard signal): top-N files.
- LLM-priors + Laravel-heuristiek: routes, controllers, views, lang-keys.
- Chroma/embeddings (chunk-niveau, zacht signaal).
- Lichte graaf-boost: route ⇄ controller ⇄ view ⇄ lang.
-
Slim chunken: functie/section-grenzen; overlap; metadata (path, class/method, blade-section, start/end).
-
Contextbouw (RAG): top-chunks + korte file/dir-summaries → compact context.
-
Patchvoorstel per bestand
- Veilige literal-replaces (UI-labels) → minimaal.
- LLM edit-plan met regex/insert/replace-operaties (max 4 stappen).
- Volledige rewrite (guarded) als laatste redmiddel.
-
Diff-guard & checks: deletieratio drempel; syntaxis/parse waar mogelijk.
-
Resultaat: toon diffs + “waarom geselecteerd”; Akkoord apply → branch + push.
Repo-QA:
- Zelfde discovery/ctx, maar i.p.v. diffs levert QA een kort antwoord + bronpaden.
Retrieval & indexing
- MeiliSearch: snelle file-retriever. Gebruik
name/path/summary/contentals searchable; boost bekende paden (routes/**,resources/views/**,app/Http/Controllers/**) bij route/view/vertaling-taken. - BM25 fallback: aanwezig als Meili niet beschikbaar is.
- Chroma (optioneel): embeddings per chunk met metadata (
path,lang,class,function,route,blade_section,start/end). Wordt gebruikt als zachte rankingbron naast Meili.
Reranking (vuistregel)
FinalScore(file) = 0.55 * Meili + 0.35 * Embeddings + 0.10 * Heuristiek + PathBoost + Recency
Chunking & contextbudget
-
Taalspecifiek:
- PHP → class/method/closure; docblocks mee.
- Blade →
@section, componenten, top-level HTML-blokken. - JS/TS → function/module-grenzen.
- MD/Tekst → alinea’s; headers intact.
-
Budget: context trimmer verdeelt tokens over snippets (
QA_MIN/MAX_PER_SNIPPET,QA_KEEP_TOP_K), deduplication, novelty-score en overlap.
Laravel-bewust & lichte graaf-boost
- Route-mapping: scan
routes/web.php/api.php→Controller@method. - View & lang-koppeling:
return view('foo.bar')→resources/views/foo/bar.blade.php;__('key'),@lang('key')→resources/lang/**. - Neighbors: controller → view(s), route → controller, view → partials/layouts (dichtbij).
- Graph-boost (aan): deze relaties wegen mee in ranking (standaard aan via
RAG_GRAPH_ENABLE=1).
Tree + samenvattingen
- Projecttree krijgt korte omschrijvingen per dir/file (README’s, docblocks, eerste regels) zodat de LLM snapt welke lagen er zijn. Deze summaries worden hergebruikt in retrieval en prompt-context.
Veiligheid: diff-guard & apply
-
Destructiviteits-guard: schat deletieratio met
difflib.ndiff; blokkeer als> AGENT_DESTRUCTIVE_RATIO(files < ~6 regels worden soepeler behandeld). -
Editstrategie (minimaal eerst):
- gerichte literal-replaces (quotes, fallbacks),
- scoped HTML/Blade vervanging,
- LLM edit-plan (max 4 bewerkingen),
- guarded rewrite.
-
Apply: alleen na “Akkoord apply” → nieuwe branch
task/<slug>-YYYYMMDD-HHMMSS→ push (Gitea token vereist).
Troubleshooting
- Geen kandidaten gevonden → specificeer een route, bestand of label-tekst; controleer Meili/Chroma beschikbaarheid.
- Apply faalt → check
GITEA_URL/GITEA_TOKENen repo-rechten; branch bestaat al? - STT/TTS werkt niet → controleer
ffmpegin container en piper/faster-whisper install (zitten in Dockerfile). - Lage precisie → verhoog
RAG_PER_QUERY_KenRAG_N_RESULTS, zetRAG_GRAPH_ENABLE=1, gebruikLLM_PRIORS_ENABLE=1.
Roadmap (suggesties)
- AST-chunking voor PHP (nikic/php-parser) voor nog scherpere grenzen.
- Cross-encoder reranker (klein model) bovenop cosine.
- Blade compile-check (sanity) en
php -lop changed files. - Auto test-suggesties bij diffs.
- Meer tools (PDF tabel-extractie, image-OCR) als OpenWebUI-endpoints.
Licentie
Kies een licentie (MIT/Apache-2.0/GPL-3.0). Voeg LICENSE toe aan de repo.
Bestandsoverzicht
app.py # Uvicorn/FastAPI app; /chat, tools, agent/qa routes
agent_repo.py # Repo Agent & Repo QA: retrieval, chunking, diffs, apply
smart_rag.py # Intent/expansie, hybride retrieval helpers
windowing_utils.py # Chunking & contextbudget utils
queue_helper.py # Hulpfuncties voor taken/IO
Dockerfile # Container build (Python 3.11-slim, piper, faster-whisper, Meili/Chroma clients)
requirements.txt # Basis Python dependencies