mistral-api/README.md

315 lines
16 KiB
Markdown
Raw Permalink Normal View History

2025-11-06 13:48:51 +00:00
# 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`, `piper` TTS, Meili/Chroma-clients, `gitpython`, `sentence-transformers`, `rank-bm25`.
---
## Inhoudsopgave
* [Architectuur in 3 onderdelen](#architectuur-in-3-onderdelen)
* [Belangrijkste features](#belangrijkste-features)
* [Snel starten](#snel-starten)
* [Docker (aanbevolen)](#docker-aanbevolen)
* [Zonder Docker (dev)](#zonder-docker-dev)
* [Configuratie (ENV)](#configuratie-env)
* [Endpoints](#endpoints)
* [Hoe het werkt (flow prompt → diffs/qa)](#hoe-het-werkt-flow-prompt--diffsqa)
* [Retrieval & indexing](#retrieval--indexing)
* [Chunking & contextbudget](#chunking--contextbudget)
* [Laravel-bewust + lichte graaf-boost](#laravel-bewust--lichte-graaf-boost)
* [Veiligheid: diff-guard & apply](#veiligheid-diff-guard--apply)
* [Troubleshooting](#troubleshooting)
* [Roadmap (suggesties)](#roadmap-suggesties)
* [Licentie](#licentie)
---
## 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)**
```dockerfile
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**
```bash
# 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)
```bash
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 (01). | `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:
```bash
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:
```bash
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 writes
* `POST /agent/apply`**schrijf & push** (na akkoord)
* `POST /qa/ask` — Repo-QA met paden als bronnen
Voorbeelden:
```bash
# 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):**
1. **Prompt binnen** → intent & scope (optioneel refine; NL/EN synonyms).
2. **Repo selecteren** → clone/update op basisbranch; meelifall-cache.
3. **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.
4. **Slim chunken**: functie/section-grenzen; overlap; metadata (path, class/method, blade-section, start/end).
5. **Contextbouw (RAG)**: top-chunks + korte file/dir-summaries → compact context.
6. **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.
7. **Diff-guard & checks**: deletieratio drempel; syntaxis/parse waar mogelijk.
8. **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/content` als 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 → alineas; 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** (READMEs, 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)**:
1. gerichte literal-replaces (quotes, fallbacks),
2. scoped HTML/Blade vervanging,
3. LLM edit-plan (max 4 bewerkingen),
4. 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_TOKEN` en repo-rechten; branch bestaat al?
* **STT/TTS werkt niet** → controleer `ffmpeg` in container en piper/faster-whisper install (zitten in Dockerfile).
* **Lage precisie** → verhoog `RAG_PER_QUERY_K` en `RAG_N_RESULTS`, zet `RAG_GRAPH_ENABLE=1`, gebruik `LLM_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 -l` op 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
```