mistral-api/README.md
2025-11-06 14:48:51 +01:00

315 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```