Fix Ollama chat reliability

This commit is contained in:
Michael committed 2026-06-30 10:36:29 +02:00
1 parent d47f7476ed
commit e9c83e3a0d
5 files changed
+297 -78

No files matched your search

+49 -15
View File
@@ -9,6 +9,7 @@ Flux :
from __future__ import annotations
import json
import logging
from fastapi import APIRouter, HTTPException
from fastapi.responses import StreamingResponse
@@ -19,6 +20,7 @@ from ..agent import run_agent
from ..config import settings
router = APIRouter(prefix="/api", tags=["chat"])
logger = logging.getLogger(__name__)
class ChatRequest(BaseModel):
@@ -54,20 +56,38 @@ async def chat(req: ChatRequest) -> StreamingResponse:
yield _sse("start", {"model": model})
final_content = ""
tools_meta: list[dict] = []
error_message = ""
async for ev in run_agent(
model,
convo,
options=agent_config.ollama_options(cfg),
enabled_tools=agent_config.enabled_tool_names(cfg),
confirm_shell=cfg.get("confirm_shell", True),
):
etype = ev.pop("type")
if etype in ("token", "tool_call", "tool_result", "tool_confirm", "error"):
yield _sse(etype, ev)
elif etype == "final":
final_content = ev["content"]
tools_meta = ev["tools"]
try:
async for ev in run_agent(
model,
convo,
options=agent_config.ollama_options(cfg),
enabled_tools=agent_config.enabled_tool_names(cfg),
confirm_shell=cfg.get("confirm_shell", True),
):
etype = ev.pop("type")
if etype in (
"token",
"status",
"notice",
"tool_call",
"tool_result",
"tool_confirm",
):
yield _sse(etype, ev)
elif etype == "error":
error_message = ev.get("message", "Erreur Ollama inconnue")
yield _sse("error", {"message": error_message})
elif etype == "final":
final_content = ev["content"]
tools_meta = ev["tools"]
except Exception as exc:
# Après l'envoi des en-têtes SSE, une exception non gérée coupe le
# socket sans explication et laisse l'interface bloquée.
logger.exception("Échec inattendu du flux de chat")
error_message = f"Erreur interne du chat : {exc}"
yield _sse("error", {"message": error_message})
if final_content or tools_meta:
db.add_message(
@@ -77,6 +97,20 @@ async def chat(req: ChatRequest) -> StreamingResponse:
model,
meta={"tools": tools_meta} if tools_meta else None,
)
yield _sse("done", {"content": final_content, "tools": tools_meta})
yield _sse(
"done",
{
"content": final_content,
"tools": tools_meta,
"error": error_message or None,
},
)
return StreamingResponse(event_stream(), media_type="text/event-stream")
return StreamingResponse(
event_stream(),
media_type="text/event-stream",
headers={
"Cache-Control": "no-cache, no-transform",
"X-Accel-Buffering": "no",
},
)