feat(stt): mémoire long-terme sémantique via Qdrant (5b) (#10)

Serveur : longterm.py — collection Qdrant stt-memory (embeddings Qwen3 gpu-01, dim auto,
Cosine), recall top-k injecté au prompt, remember des tours user. Tout dégrade proprement
si Qdrant/embeddings injoignables (la mémoire court-terme tient). Env STT_MEMORY_LONGTERM,
STT_QDRANT_URL, STT_EMBED_URL, STT_MEMORY_TOPK.

Testé en process : dégradation OK (Qdrant down → mem=0, pas de crash, court-terme tient).
Qdrant réparé le 17/06 (5c). Recherche sémantique réelle à valider sur cluster.


Claude-Session: https://claude.ai/code/session_013FmcxGsyXZXogiAHQLjnZT

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
ALI YESILKAYA 2026-06-17 16:52:33 +02:00 committed by GitHub
parent 70499b7d84
commit 1986ab56d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 148 additions and 13 deletions

View file

@ -14,10 +14,12 @@ from pydantic import BaseModel
from stt_server import __version__
from stt_server.brain import ask as brain_ask
from stt_server.config import settings
from stt_server.longterm import LongTermMemory
from stt_server.memory import SessionStore
app = FastAPI(title="STT-server", version=__version__)
sessions = SessionStore()
longterm = LongTermMemory() if settings.memory_longterm else None
class AskRequest(BaseModel):
@ -60,13 +62,16 @@ async def v1_ask(req: AskRequest) -> AskReply:
detail=f"modèle '{model}' non autorisé ; dispo : {settings.allowed_models}",
)
history = sessions.history(req.session_id) if req.session_id else None
memories = await longterm.recall(text) if longterm else None
try:
reply = await brain_ask(text, model, history)
reply = await brain_ask(text, model, history, memories)
except httpx.HTTPError as e:
raise HTTPException(status_code=502, detail=f"upstream LiteLLM : {e}") from e
if req.session_id:
sessions.add(req.session_id, "user", text)
sessions.add(req.session_id, "assistant", reply)
if longterm:
await longterm.remember(req.session_id or "anon", text)
return AskReply(reply=reply, model=model)