fix: connect Peg to local AI runtime
MetaBloom CI / app (push) Canceled after 0s
MetaBloom CI / api (push) Canceled after 0s

This commit is contained in:
AI Company
2026-07-21 22:06:38 +00:00
parent 02e24cbc92
commit 0c2430ad13
7 changed files with 50 additions and 8 deletions
+15 -1
View File
@@ -48,7 +48,8 @@ async def chat_with_peg(data: CoachChatIn, cfg: Settings) -> CoachChatOut:
response = await client.post(
f"{cfg.ai_base_url.rstrip('/')}/chat/completions",
headers=headers,
json={"model": cfg.ai_model, "messages": messages, "temperature": 0.4, "max_tokens": 350},
# Keep answers useful but short so a local CPU model responds reliably.
json={"model": cfg.ai_model, "messages": messages, "temperature": 0.4, "max_tokens": 160},
)
response.raise_for_status()
content = response.json()["choices"][0]["message"]["content"].strip()
@@ -60,3 +61,16 @@ async def chat_with_peg(data: CoachChatIn, cfg: Settings) -> CoachChatOut:
return CoachChatOut(message=content, source="model")
except (httpx.HTTPError, KeyError, IndexError, TypeError, ValueError):
return CoachChatOut(message="Je suis momentanément indisponible. En attendant, choisis une petite action sans risque : boire un verre deau, marcher quelques minutes si tu te sens bien, ou noter ton prochain repas. Pour une question médicale, contacte un professionnel de santé.", source="fallback")
async def peg_provider_health(cfg: Settings) -> dict[str, str | bool]:
"""Check the configured AI provider without leaking credentials or prompts."""
base_url = cfg.ai_base_url.rstrip("/")
headers = {"Authorization": f"Bearer {cfg.ai_api_key}"} if cfg.ai_api_key else {}
try:
async with httpx.AsyncClient(timeout=min(cfg.ai_timeout_seconds, 5.0)) as client:
response = await client.get(f"{base_url}/models", headers=headers)
response.raise_for_status()
return {"status": "ok", "reachable": True, "model": cfg.ai_model}
except httpx.HTTPError:
return {"status": "unavailable", "reachable": False, "model": cfg.ai_model}
+3 -2
View File
@@ -11,8 +11,9 @@ class Settings(BaseSettings):
environment: str = "development"
ai_base_url: str = "http://localhost:11434/v1"
ai_api_key: str = ""
ai_model: str = "llama3.2:3b"
ai_timeout_seconds: float = 20.0
ai_model: str = "qwen2.5:1.5b"
# Local models may need extra time for their first response while loading.
ai_timeout_seconds: float = 90.0
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
@property
+6 -1
View File
@@ -10,7 +10,7 @@ from .config import get_settings
from .db import Base, engine, get_db
from .models import Entry, Profile, User
from .schemas import CoachChatIn, CoachChatOut, EntryIn, EntryOut, ProfileIn, ProfileOut, Register, Token
from .coach import chat_with_peg
from .coach import chat_with_peg, peg_provider_health
from .security import current_user, hash_password, make_token, verify_password
cfg = get_settings()
@@ -31,6 +31,11 @@ def health():
return {"status": "ok", "medical_notice": "MetaBloom does not diagnose or replace medical care."}
@app.get("/health/ai")
async def ai_health():
return await peg_provider_health(cfg)
@app.post("/coach/chat", response_model=CoachChatOut)
async def coach_chat(data: CoachChatIn, user: User = Depends(current_user)):
return await chat_with_peg(data, cfg)