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>
This commit is contained in:
ALI YESILKAYA 2026-06-17 16:15:57 +02:00 committed by GitHub
parent bcdb4f8b2a
commit 815beaf37c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 107 additions and 17 deletions

View file

@ -7,6 +7,7 @@ choisit le modèle (alias LiteLLM) et le passe au serveur par requête.
from __future__ import annotations
import uuid
from typing import Any
@ -15,13 +16,19 @@ class ServerClient:
self.url = cfg["url"].rstrip("/")
self.timeout = cfg.get("timeout_sec", 90)
self.model = cfg.get("model", "hermes-default")
# une session par run → mémoire court-terme côté serveur
self.session_id = uuid.uuid4().hex
def ask(self, text: str, model: str | None = None) -> str:
import requests
r = requests.post(
f"{self.url}/v1/ask",
json={"text": text, "model": model or self.model},
json={
"text": text,
"model": model or self.model,
"session_id": self.session_id,
},
timeout=self.timeout,
)
if r.status_code == 400:
@ -29,6 +36,18 @@ class ServerClient:
r.raise_for_status()
return r.json()["reply"].strip()
def reset(self) -> None:
import requests
try:
requests.post(
f"{self.url}/v1/reset",
json={"text": "", "session_id": self.session_id},
timeout=10,
)
except requests.RequestException:
pass
def models(self) -> dict:
"""{'default': ..., 'available': [...]} depuis le serveur."""
import requests

View file

@ -41,7 +41,7 @@ def _cmd_text(args) -> int:
print(f"STT (texte) — serveur {client.url} — modèle '{client.model}'")
if not client.healthy():
print(" ⚠️ serveur injoignable — vérifie [server] url et le réseau")
print(" commandes : /model <nom>, /models, /quit\n")
print(" commandes : /model <nom>, /models, /reset, /quit\n")
from stt.config import resolve_model
@ -55,6 +55,10 @@ def _cmd_text(args) -> int:
continue
if line in ("/quit", "/exit", "/q"):
return 0
if line == "/reset":
client.reset()
print(" → mémoire de session effacée\n")
continue
if line == "/models":
try:
m = client.models()