Funk-lab/stt/server/stt_server/memory.py
ALI YESILKAYA 815beaf37c
feat(stt): mémoire court-terme de session côté serveur (5a) (#8)
Serveur : SessionStore (historique borné + TTL, en mémoire), /v1/ask accepte session_id
et injecte l'historique dans l'appel LLM, /v1/reset l'efface. Dockerfile en 1 worker
(cohérence mémoire process).

Client : session_id généré par run (uuid), envoyé à chaque requête ; commande /reset
en mode texte.

Testé en process (TestClient) : historique croît 0→2→4, reset→0, sessions isolées,
sans session_id = sans état.

Mémoire long-terme Qdrant (5b) + réparation Qdrant (5c) à suivre.


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

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-17 16:15:57 +02:00

38 lines
1.3 KiB
Python

"""Mémoire court-terme côté serveur : historique de conversation par session.
En mémoire (process), borné et avec TTL. Suffisant pour un usage mono-utilisateur ;
le Deployment tourne en 1 worker pour que les sessions soient cohérentes.
La mémoire long-terme sémantique (Qdrant) viendra en phase 5b.
"""
from __future__ import annotations
import time
from collections import deque
class SessionStore:
def __init__(self, max_turns: int = 10, ttl_sec: int = 3600):
self.max_turns = max_turns # paires user/assistant conservées
self.ttl = ttl_sec
self._data: dict[str, dict] = {} # sid -> {"turns": deque, "ts": float}
def _gc(self) -> None:
now = time.time()
for sid in [s for s, v in self._data.items() if now - v["ts"] > self.ttl]:
del self._data[sid]
def history(self, sid: str) -> list[dict]:
self._gc()
sess = self._data.get(sid)
return list(sess["turns"]) if sess else []
def add(self, sid: str, role: str, content: str) -> None:
sess = self._data.setdefault(
sid, {"turns": deque(maxlen=self.max_turns * 2), "ts": time.time()}
)
sess["turns"].append({"role": role, "content": content})
sess["ts"] = time.time()
def reset(self, sid: str) -> None:
self._data.pop(sid, None)