import chainlit as cl import httpx import json @cl.on_chat_start async def on_chat_start(): initial_state = { "user_input": "", "user_feedback": None, "chat_history": [], "spec": {}, "status": "start", "loop_count": 0, "existing_project": None, "generated_code": None, "qa_result": None, "is_completed": False } cl.user_session.set("graph_state", initial_state) await cl.Message( content="Bonjour 👋 Je suis ARC. Décris-moi ton besoin logiciel." ).send() @cl.on_message async def on_message(message: cl.Message): # 1. Récupérer le state actuel de la session state = cl.user_session.get("graph_state") if "chat_history" not in state: state["chat_history"] = [] if "status" not in state: state["status"] = "start" # 2. Déterminer si le message est une réponse à une question ou un nouveau projet if state.get("status") == "spec_incomplete": state["user_feedback"] = message.content else: state["user_input"] = message.content state["user_feedback"] = None # 3. Appel de l'API en envoyant le state COMPLET async with httpx.AsyncClient() as client: response = await client.post( "http://127.0.0.1:8000/api/workflow/run", json=state, timeout=600.0 ) # 4. Enregistrer le nouvel état retourné par le serveur new_state = response.json() cl.user_session.set("graph_state", new_state) # 5. Rendu UI intelligent dans Chainlit if new_state.get("status") == "spec_incomplete": spec = new_state.get("spec", {}) question = spec.get("clarifying_question") await cl.Message(content=f"**Spécifications incomplètes**\n\n{question}").send() elif new_state.get("status") == "spec_ready": spec = new_state.get("spec", {}) summary = "### Éléments importants à retenir de ton projet :\n\n" summary+= f"- **Nom du projet** : {spec.get('title')}\n" summary+= f"- **Description** : {spec.get('description')}\n" summary+= f"- **Actions** : {', '.join(spec.get('requirements', []))}\n" summary+= f"- **Contraintes** : {', '.join(spec.get('constraints', []))}\n" summary+= f"- **Langage** : {spec.get('language')}\n" summary += "\n**Est-ce que cela vous convient ?**" # Ajout des boutons de décision res = await cl.AskActionMessage( content=summary, actions=[ cl.Action(name="oui", payload={"value": "oui"}, label="Oui, c'est parfait 👍"), cl.Action(name="non", payload={"value": "non"}, label="Non, modifier ❌") ], timeout=3600 ).send() if res is None: await cl.Message( content="⏰ **Session expirée.** Si tu es toujours là, envoie un message pour relancer l'analyse." ).send() return if res and res.get("name") == "oui": await cl.Message(content="🚀 **Spécifications validées !** Lancement de la génération du code...").send() # On passe le statut attendu par ton graphe new_state["status"] = "spec_approved" cl.user_session.set("graph_state", new_state) # On relance immédiatement le workflow pour exécuter la suite (dev, qa...) async with httpx.AsyncClient() as client: response = await client.post( "http://127.0.0.1:8000/api/workflow/run", json=new_state, timeout=600.0 ) final_state = response.json() cl.user_session.set("graph_state", final_state) await cl.Message( content=f"Résultat workflow :\n```json\n{json.dumps(final_state, indent=2, ensure_ascii=False)}\n```" ).send() else: # Si "non" (ou si le choix a expiré) new_state["status"] = "spec_incomplete" cl.user_session.set("graph_state", new_state) await cl.Message( content="🔄 **Compris.** Qu'est-ce qui ne convient pas ? S'il te plaît, précise les éléments manquants ou à corriger :" ).send() else: await cl.Message( content=f"Résultat workflow :\n```json\n{json.dumps(new_state, indent=2, ensure_ascii=False)}\n```" ).send()