123 lines
4.5 KiB
Python
123 lines
4.5 KiB
Python
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() |