diff --git a/backend/app/routes/chat.py b/backend/app/routes/chat.py index 43c1505..d5512a1 100644 --- a/backend/app/routes/chat.py +++ b/backend/app/routes/chat.py @@ -425,6 +425,12 @@ async def chat(req: ChatRequest) -> StreamingResponse: if cfg.get("ponytail", True) and is_code_like: convo.insert(1, {"role": "system", "content": skills.PONYTAIL_GUIDANCE}) + # Appli web : contraintes dures (fichier autonome, zéro dépendance + # externe, rendu réel) pour que ça marche vraiment hors-ligne. + want_web = is_code_like and skills.is_web_task(req.content) + if want_web: + convo.insert(1, {"role": "system", "content": skills.WEBAPP_GUIDANCE}) + if plan: yield _sse("plan", {"steps": plan}) @@ -443,7 +449,9 @@ async def chat(req: ChatRequest) -> StreamingResponse: if recap: extra = f"\n\n{recap}" + extra # Le moteur code (Aider) ne voit pas convo : on lui redonne Ponytail - # directement dans la consigne. + # (et les contraintes web) directement dans la consigne. + if want_web: + extra = "\n\n" + skills.WEBAPP_GUIDANCE + extra if cfg.get("ponytail", True): extra = "\n\n" + skills.PONYTAIL_GUIDANCE + extra code_files = _mentioned_files(req.content) or session_files[:8] diff --git a/backend/app/skills.py b/backend/app/skills.py index b9814c7..4867bf3 100644 --- a/backend/app/skills.py +++ b/backend/app/skills.py @@ -64,6 +64,43 @@ def _load() -> dict[str, dict]: return out +_WEB_RE = re.compile( + r"\b(html|css|javascript|js|page|site|web|appli|application|interface|" + r"bouton|formulaire|canvas|animation|jeu|game|échiquier|echiquier|" + r"dashboard|landing|maquette|ui|front)\b", + re.I, +) + + +def is_web_task(message: str) -> bool: + """La demande porte-t-elle sur une page / appli web ?""" + return bool(_WEB_RE.search(message or "")) + + +# Contraintes « appli web » : le sandbox de prévisualisation est HORS-LIGNE et +# isolé (pas de CDN, pas de WASM téléchargé). Sans ces règles, les modèles +# promettent des libs (Stockfish, React…) qui ne se chargent jamais, éclatent +# le code en plusieurs fichiers incohérents, puis déclarent « ça marche ». +WEBAPP_GUIDANCE = ( + "Contraintes STRICTES pour une page/appli web :\n" + "1. UN SEUL fichier index.html AUTONOME : tout le CSS dans