Funk-lab/stt/client/stt/api.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

66 lines
1.9 KiB
Python

"""Client HTTP vers le STT-server (in-cluster).
Le client n'a plus de cerveau : il envoie le texte transcrit au serveur, qui
orchestre l'inférence (LiteLLM → Qwen3/Claude) et renvoie la réponse. Le client
choisit le modèle (alias LiteLLM) et le passe au serveur par requête.
"""
from __future__ import annotations
import uuid
from typing import Any
class ServerClient:
def __init__(self, cfg: dict[str, Any]):
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,
"session_id": self.session_id,
},
timeout=self.timeout,
)
if r.status_code == 400:
raise RuntimeError(r.json().get("detail", "requête invalide"))
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
r = requests.get(f"{self.url}/v1/models", timeout=10)
r.raise_for_status()
return r.json()
def healthy(self) -> bool:
import requests
try:
r = requests.get(f"{self.url}/healthz", timeout=5)
return r.ok
except requests.RequestException:
return False