Commit Graph
22 Commits
Author SHA1 Message Date
Matteo Benedetto 94e9bb44b1 docs: sez. 11.11 istanza frigate (embedding llama.cpp) + bump v2.7.0 2026-08-18 22:48:50 +02:00
Matteo Benedetto 2626649e5a feat: backend embedding configurabile — EMBED_API=ollama|llamacpp
- llama.cpp: /v1/embeddings OpenAI-compatible con Bearer key (EMBED_API_KEY)
- ollama (default): /api/embed invariato
- EMBED_URL sostituisce OLLAMA_URL (alias retrocompatibile)
2026-08-18 22:46:26 +02:00
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
Matteo Benedetto eccb2cb870 feat(guardrail): similarità pre-scrittura su POST /v1/memories
Guardrail deterministico FUORI dall'LLM (stessa architettura di egeos-copilot):
- Strato 1: text_hash SHA-256 normalizzato -> BLOCK 409 (EXACT_DUPLICATE)
- Strato 2: similarità semantica top-3 BGE-M3 cosine -> BLOCK/WARN/ALLOW
  (soglie configurabili: GUARDRAIL_BLOCK_THRESHOLD 0.85, WARN 0.70)
- Supersede esplicito bypassa il guardrail (correzione intenzionale)
- text_hash e flag guardrail nel payload; audit create_blocked
- Indice payload su text_hash
- Test: 6 nuovi (duplicato esatto, similarità alta/moderata, nessun candidato,
  supersede bypass, disabilitato, text_hash) — 28/28 passano
2026-08-18 12:58:28 +02:00
Matteo Benedetto c4bfa1d5bf fix CRITICO: backfill usa update_vectors (non upsert) — preserva payload e vettore denso
INCIDENTE 2026-08-16: l'upsert parziale in Qdrant sostituisce l'intero punto,
cancellando payload e vettori densi di tutti i record. update_vectors aggiorna
solo il vettore specificato. Recovery: 278/330 record ricostruiti dalle sessioni
pi (qmem_store/qmem_correct con memory_id), 52 persi (agenti su altre macchine).
2026-08-16 20:39:12 +02:00
Matteo Benedetto aed962cfcd chore: bump versioni (gateway 2.6.0, estensione 1.7.0) 2026-08-16 19:56:09 +02:00
Matteo Benedetto faa4e84611 feat: metriche gateway con push a VictoriaMetrics + dashboard Grafana
- raccolta in-memory: richieste per endpoint, latenza (sum/count), errori per status, search queries/hits, punti
- push periodico (30s) a VM via /api/v1/import/prometheus (pattern energy engine, timestamp ms)
- VM_PUSH_URL/VM_PUSH_INTERVAL/METRICS_ENABLED configurabili; default host.docker.internal:8428
- endpoint /v1/metrics (auth) per verifica manuale
- dashboard Grafana versionata in monitoring/qmem-dashboard.json (provisioning: /home/enne2/domotics/grafana/dashboards/)
- verificato sul server: /v1/metrics OK, 6 serie qmem_* in VM
2026-08-16 19:51:08 +02:00
Matteo Benedetto eba9c19179 feat: campo confidence (high/medium/low, default medium) nei record
- gateway: MemoryIn + payload + risultati search; 422 su valore invalido
- estensione: confidence in qmem_store e qmem_correct (eredita dal superseduto), mostrato nei risultati
- backward compatible: record esistenti → confidence null
- verificato sul server: high/medium/default, 422 su invalida (istanza di test)
2026-08-16 19:43:30 +02:00
Matteo Benedetto 7abced1566 feat: hybrid retrieval (BM25 + vettoriale, RRF) opt-in via hybrid=true
- sparse vector bm25 (modifier IDF) + indice TEXT su text
- migrazione automatica: create_vector_name su collection esistente + backfill dei punti privi di sparse
- write: sparse vector a ogni upsert (fastembed Qdrant/bm25)
- search: hybrid=true → prefetch denso (min_score anti-rumore) + sparso, fusione RRF; default invariato (punteggi cosine)
- qdrant-client 1.13.0 → 1.19.0 (create_vector_name, query_points; search rimosso in 1.19)
- fastembed 0.5.1 + pre-download modello BM25 nel Dockerfile (appuser)
- estensione: parametro hybrid in qmem_search
- verificato sul server: migrazione + backfill OK, termine esatto trovato con RRF 1.0 (istanza di test)
2026-08-16 19:41:42 +02:00
Matteo Benedetto 2d354bfde6 feat: X-Request-ID per richiesta (header risposta + audit log)
- middleware: genera o accetta X-Request-ID, lo restituisce in header
- contextvar letto da _audit: correlazione richieste nei log
- verificato sul server: header + audit correlati (istanza di test)
2026-08-16 19:32:29 +02:00
Matteo Benedetto 3f7c3cee51 security: hash SHA-256 della query nell'audit log (niente contenuto in chiaro)
- query_hash (16 char) al posto di query[:80]
- verificato sul server: audit con query_hash, nessuna query in chiaro
2026-08-16 19:28:01 +02:00
Matteo Benedetto f30966a77c feat: rate limit leggero (30/min per IP) su /v1/status pubblico
- endpoint pubblico per healthcheck, protetto da abusi
- verificato sul server: 36 richieste → 30x200 + 6x429 (istanza di test)
2026-08-16 19:22:18 +02:00
Matteo Benedetto 87d59ccb5c feat: validazione expires_at ISO 8601 (422 con messaggio chiaro, niente fallback silenzioso)
- field_validator Pydantic su MemoryIn.expires_at
- verificato sul server: valida OK, invalida → 422 (istanza di test)
2026-08-16 19:21:01 +02:00
Matteo Benedetto 748356d769 perf: client httpx riusato per gli embedding (lazy, chiuso a shutdown)
- _get_http(): creazione lazy, keep-alive riusato tra le chiamate
- lifespan shutdown: aclose del client
- verificato sul server: status + search OK (istanza di test)
2026-08-16 19:18:41 +02:00
Matteo Benedetto ec0fdb972a refactor: lifespan al posto di @app.on_event (deprecato) + bump v2.5.0
- startup (collection+indici) e cleanup task nel context manager lifespan
- shutdown: cancel del cleanup task
- verificato sul server: startup OK, scrittura OK (istanza di test)
2026-08-16 19:17:19 +02:00
Matteo Benedetto a7d4bbb4a8 feat: idempotency su POST /v1/memories (Idempotency-Key, replay → stessa risposta, payload diverso → 409)
- gateway: tabella in-memory con TTL 24h, hash canonico del payload, scoped per API key
- estensione: crypto.randomUUID() per operazione (store e correct), riusata su retry
- from __future__ import annotations (forward-reference _payload_hash)
2026-08-16 19:10:32 +02:00
enne2 72ebb949c8 feat: project_id obbligatorio (gateway v2.4.0 + estensione v1.4.0)
- gateway: MemoryIn.project_id required (min_length=1) → POST senza project_id = 422
- estensione: qmem_store project_id Type.String (non più Optional), descrizione con obbligo e rinvio a qmem_meta; qmem_correct resta opzionale (eredita dal superseduto)
- README/playbook sez. 11.5 aggiornati
2026-08-13 13:24:22 +02:00
enne2 334f9c6b44 fix(gateway): with_vectors (plurale) in qdrant.scroll per /v1/meta/overview 2026-08-13 13:09:10 +02:00
enne2 4b1f13c118 feat: discovery endpoint GET /v1/meta/overview + tool qmem_meta
- gateway v2.3.0: /v1/meta/overview (auth) con scope×kind, progetti, agenti, superseduti; scroll aggregato su soli campi metadata + cache TTL 60s invalidata su POST/DELETE/cleanup; audit action 'meta'
- estensione v1.3.0: tool qmem_meta (nessun parametro) che guida la ricerca settorializzata
- README/playbook (sez. 11.4)/AGENTS.md aggiornati
2026-08-13 13:06:10 +02:00
enne2 f6d9c5872d feat: min_score anti-rumore nella ricerca + igiene metadata
- gateway v2.2.0: SearchIn.min_score → score_threshold a livello Qdrant (filtra sotto soglia), audit e risposta con min_score
- estensione v1.2.0: qmem_search con min_score default 0.45 (guida punteggi in descrizione), marker ⚠️ per score<0.60, messaggio dedicato quando 0 risultati rilevanti
- dati: eliminato record rumore ('valuta preferita EUR'), assegnati project_id mancanti via supersede (domotics, pi-qmem x2, agy-pi)
- AGENTS.md: sezione interpretazione punteggi
2026-08-13 13:02:37 +02:00
enne2 1713e68b82 feat: supersede di memorie false (qmem_correct, include_superseded, playbook sez. 11)
- gateway: supersedes_id validato (404/409), backlink superseded_by+superseded_at+supersede_reason sul vecchio record, indici keyword, search esclude i superseduti di default (include_superseded per lineage), risposta con lineage
- estensione: tool qmem_correct (memory_id o query), qmem_store con supersedes_id/supersede_reason, qmem_search con include_superseded
- README/playbook aggiornati, versione 1.1.0
2026-08-13 12:41:14 +02:00
enne2 eadd2a756b pi-qmem: memoria centralizzata condivisa per agenti AI (estensione pi + gateway) 2026-08-11 23:14:40 +02:00