fix(agent): validation robuste des modeles Nvidia (payload production + repli 404/410) + logo noir/blanc
FlowDeck CI / test (push) Failing after 15s
FlowDeck CI / docker (push) Skipped

Validation:
- _validate_chat_models utilise le payload de production (temperature 0.2,
  sans max_tokens) : un 200 a la validation == 200 a l'usage reel.
- Race corrigee : payload reconstruit par modele (plus de noms croises entre
  requetes concurrentes) — la v5.1.8 retombait par intermittence sur la liste
  brute (68 modeles dont la plupart en 404/410).
- Retente une fois sur timeout/5xx (les modeles lents mais fonctionnels
  survivent) ; rejette les 4xx (404 inconnu, 410 retire) ; garde les 429.
- Verifie en live contre l'API NVIDIA : 12 modeles valides au lieu de 68.

Repli runtime:
- LLMClient._http_complete : sur 404/410, retente une fois avec le modele par
  defaut du provider et marque un notice dans LLMResponse.
- AgentEngine emet un evenement SSE "notice" (bandeau .fd-ap-notice dans le
  panneau Agent, reset a chaque conversation) ; le modele reel est persistee.

UI:
- FAB (rond bas droite) et logo header du panneau : rond noir/blanc qui suit
  le theme clair/sombre (--text-primary / --bg-primary), eclair monochrome
  SVG a la place de l'emoji robot.

Tests:
- 2 nouveaux tests (429 garde / 410 retire ; repli runtime sur 410).
- 278 tests passent.
This commit is contained in:
2026-09-07 14:45:28 -04:00
parent b15289b4bc
commit bd582866d1
8 changed files with 215 additions and 76 deletions
+7 -1
View File
@@ -154,6 +154,7 @@ class AgentEngine:
tool_schema = self.tools.schema(scope)
final_text = None
used_model = model or "" # peut être ajusté par un repli de modèle (404/410)
try:
for step in range(settings.agent_max_iterations or MAX_ITERATIONS):
@@ -167,6 +168,11 @@ class AgentEngine:
)
self._tokens += response.usage.get("total_tokens", 0) or 0
if getattr(response, "notice", ""):
yield self._event("notice", {"message": response.notice})
used_model = getattr(response, "model", "") or used_model
if response.text and response.text.strip():
yield self._event("reasoning", {"content": response.text})
@@ -242,7 +248,7 @@ class AgentEngine:
yield self._event("final", {"content": final_text})
self._persist_message(conversation_id, "assistant", final_text,
model=model, tokens=self._tokens)
model=used_model, tokens=self._tokens)
await self._autotitle(conversation_id, objective, final_text)
except Exception as exc: # noqa: BLE001