Files
pi-qmem/gateway/README.md
T
Matteo Benedetto b7809fc92d feat(version): endpoint /v1/version + git_commit nel build Docker
- GET /v1/version (pubblico): espone version, git_commit, guardrail_version,
  guardrail_enabled, soglie, embedding_model
- /v1/status include version, git_commit, guardrail_version
- Dockerfile: ARG GIT_COMMIT / ENV GIT_COMMIT (default unknown)
- GATEWAY_VERSION 2.7.0, GIT_COMMIT da env
- Test: 2 nuovi (version endpoint, status git_commit) — 30/30 passano
2026-08-18 16:19:36 +02:00

91 lines
3.8 KiB
Markdown
Raw 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.
# Memory Gateway — deploy
Componente server di **pi-qmem**: FastAPI + Qdrant 1.19 + Ollama (BGE-M3).
Nessun LLM in scrittura: l'agente salva record deliberati e strutturati.
```
pi (estensione pi-qmem) ──HTTPS/VPN──▶ Memory Gateway (FastAPI:8082) ──▶ Qdrant 1.19 (6333)
└──▶ Ollama BGE-M3 (11434, nativo host)
```
## Deploy (Docker Compose)
```bash
# 1. Prepara l'ambiente (vedi qmem-gateway/docker-compose.yml come riferimento)
cp .env.example .env
chmod 600 .env
# genera le chiavi:
# QDRANT_ADMIN_API_KEY=$(openssl rand -hex 32)
# QDRANT_READ_ONLY_API_KEY=$(openssl rand -hex 32)
# API_KEYS=$(openssl rand -hex 32) # chiave condivisa per gli agenti
# 2. Avvia
docker compose up -d --build
# 3. Verifica
curl http://127.0.0.1:8082/v1/status
```
Requisiti: Docker + Compose v2, Ollama con modello `bge-m3` sul host
(`ollama pull bge-m3`), porta 8082 libera sull'interfaccia VPN.
## API
| Endpoint | Descrizione |
|---|---|
| `POST /v1/memories` | Crea record (text, kind, agent_id, scope, **project_id obbligatorio**, source, expires_at, supersedes_id, supersede_reason). Applica il guardrail di similarità pre-scrittura |
| `POST /v1/memories:search` | Ricerca semantica (query, kind, project_id, scope, top_k, include_superseded, min_score) |
| `GET /v1/memories/{id}` | Recupera per UUID |
| `DELETE /v1/memories/{id}` | Elimina per UUID |
| `GET /v1/meta/overview` | Discovery: scope×kind, progetti, agenti, superseduti (cache 60s) |
| `GET /v1/status` | Health + statistiche |
Auth: header `X-API-Key` (chiave condivisa, accesso completo). Rate limit 120 req/min per chiave. Audit log in JSON lines (docker logs).
## Versione del codice
`GET /v1/version` (pubblico) espone la versione del codice in esecuzione, inclusa l'hash del commit Git da cui è stato costruito il container:
```json
{"version": "2.7.0", "git_commit": "eccb2cb...", "guardrail_version": "similarity-v1", ...}
```
Anche `GET /v1/status` include `version`, `git_commit` e `guardrail_version`. L'hash è iniettato al build via `ARG GIT_COMMIT`/`ENV GIT_COMMIT` nel Dockerfile (default `unknown`). Per costruire con l'hash:
```bash
docker compose build --build-arg GIT_COMMIT=$(git rev-parse HEAD) gateway
# o nel compose: build: { context: ./gateway, args: { GIT_COMMIT: ${GIT_COMMIT:-unknown} } }
```
## Guardrail di similarità (v1)
Enforcement deterministico FUORI dall'LLM, prima di ogni scrittura su `POST /v1/memories`:
1. **Strato 1 — hash esatto**: SHA-256 del testo normalizzato (`text_hash` nel payload). Se esiste un record attivo con lo stesso hash → `409 BLOCK (EXACT_DUPLICATE)`.
2. **Strato 2 — similarità semantica top-3**: embedding BGE-M3 cosine sui record attivi (esclusi i superseded).
- top-1 ≥ `GUARDRAIL_BLOCK_THRESHOLD` (default 0.85) → `409 BLOCK (KNOWN_SOLUTION)`
- top-1 ≥ `GUARDRAIL_WARN_THRESHOLD` (default 0.70) → `WARN`: salva con flag `guardrail` nel payload
- altrimenti → `ALLOW`
Il **supersede esplicito** (`supersedes_id`) è una correzione intenzionale: bypassa il guardrail.
Configurazione (env): `GUARDRAIL_ENABLED` (default true), `GUARDRAIL_BLOCK_THRESHOLD`, `GUARDRAIL_WARN_THRESHOLD`. Soglie di partenza da calibrare sul corpus reale.
Risposta BLOCK (409):
```json
{"detail": {"error": "duplicate_memory", "reason": "KNOWN_SOLUTION", "matches": [{"memory_id": "...", "score": 0.92}], "message": "..."}}
```
## Sicurezza
- Qdrant bindato su 127.0.0.1; gateway solo su interfaccia VPN
- Chiavi in `.env` (0600), mai committate
- JWT RBAC su Qdrant (admin + read-only)
- Backup: snapshot Qdrant + rotazione 7 giorni (cron: `0 3 * * * /opt/memory/backup.sh`)
## Dettagli operativi
Procedure complete (teardown, restore, nginx, troubleshooting): vedi
`docs/playbook.md` nel repo pi-qmem.