fix(stt-server): retry brain + timeout par tentative + log timing effectif

Suite au déploiement 0.2.0, deux points observés en pilotant l'app en direct :

- Le log de timing (`ask … recall/gen/total`) n'émettait pas : uvicorn ne
  configure que ses propres loggers → on attache un handler INFO sur `stt_server`.
- La chaîne LiteLLM→llama-server (ROCm gfx1031) se fige par à-coups (~1-2 min,
  502 pour tous les appels, cf. incidents-llm-gpu.md). Résilience côté STT :
  brain tente 2× (fermeture du client httpx entre les essais → connexion neuve si
  le pool est vicié) et le timeout passe à 30s PAR tentative (≤ ~2× au pire).
  Un blip transitoire devient une requête récupérée au lieu d'un 502.

bump serveur 0.2.0 → 0.2.1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
alkatrazz 2026-06-19 15:46:03 +02:00
parent ced79658cf
commit 917ffcfc32
5 changed files with 32 additions and 5 deletions

View file

@ -59,8 +59,25 @@ async def ask(
"temperature": settings.temperature,
}
headers = {"Authorization": f"Bearer {settings.litellm_key}"}
r = await _get_client().post(settings.litellm_url, json=payload, headers=headers)
r.raise_for_status()
# Résilience : la chaîne LiteLLM→llama-server (ROCm) se fige par à-coups. Une 2ᵉ tentative
# récupère un blip transitoire (ex. connexion keep-alive périmée) au lieu de renvoyer 502.
# Timeout PAR tentative (`request_timeout`) → on ne dépasse pas ~2× ce budget au pire.
last_exc: Exception | None = None
for attempt in range(2):
try:
r = await _get_client().post(
settings.litellm_url,
json=payload,
headers=headers,
timeout=settings.request_timeout,
)
r.raise_for_status()
break
except httpx.HTTPError as e:
last_exc = e
await aclose() # repart sur une connexion neuve (pool potentiellement vicié)
else:
raise last_exc # type: ignore[misc]
msg = r.json()["choices"][0]["message"]
# Filet de sécurité : si un modèle « thinking » renvoie un content vide (tout parti
# en reasoning_content), on récupère le raisonnement plutôt que de renvoyer "".