From 2ded22820251d54efba619361b3d7230f1147f4e Mon Sep 17 00:00:00 2001 From: Chevallier Date: Thu, 9 Jul 2026 10:23:04 +0200 Subject: [PATCH] ajout boucle refus projet final, TODO : correction QA, verif arborescence mini --- backend/app/graph/nodes.py | 2 +- backend/chainlit_app.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/app/graph/nodes.py b/backend/app/graph/nodes.py index 9a0750e..4b1783c 100644 --- a/backend/app/graph/nodes.py +++ b/backend/app/graph/nodes.py @@ -12,7 +12,7 @@ from langchain_core.runnables import RunnableConfig async def pm_node(state: WorkflowState): history = state.get("chat_history", []) or [] - if state.get("status") == "spec_incomplete" and state.get("user_feedback"): + if state.get("status") in ["spec_incomplete", "human_refused"] and state.get("user_feedback"): current_input = state["user_feedback"] full_user_input = f"{state['user_input']}\n{current_input}" else: diff --git a/backend/chainlit_app.py b/backend/chainlit_app.py index d597fac..8eeac03 100644 --- a/backend/chainlit_app.py +++ b/backend/chainlit_app.py @@ -145,7 +145,7 @@ async def render_workflow_state(new_state: dict): res = await cl.AskActionMessage( content="**Souhaitez-vous valider et packager ce livrable ?**", actions=[ - cl.Action(name="valider_projet", payload={"value": "approve"}, label="🚀 Valider & Livrer", description="Génère l'archive et indexe le projet"), + cl.Action(name="valider_projet", payload={"value": "approve"}, label="✅ Valider & Livrer", description="Génère l'archive et indexe le projet"), cl.Action(name="refuser_projet", payload={"value": "refuse"}, label="❌ Refuser et corriger", description="Renvoie le projet au PM avec vos commentaires") ], timeout=3600 @@ -163,16 +163,14 @@ async def render_workflow_state(new_state: dict): cl.user_session.set("graph_state", final_state) elif res and res.get("name") == "refuser_projet": - await cl.Message(content="❌ **Projet refusé.**").send() feedback_user = await cl.AskUserMessage( - content="📝 Veuillez décrire les corrections ou les modifications à apporter au projet :", + content="Veuillez décrire les corrections ou les modifications à apporter au projet.", timeout=600 ).send() if feedback_user: new_state["status"] = "human_refused" new_state["user_feedback"] = feedback_user["output"] - new_state["status"] = "spec_incomplete" cl.user_session.set("graph_state", new_state) await cl.Message(content="🔄 **Feedback transmis.** Prise en compte des modifications...").send() @@ -183,9 +181,7 @@ async def render_workflow_state(new_state: dict): loop_state = resp.json() cl.user_session.set("graph_state", loop_state) - if loop_state.get("status") == "spec_incomplete": - question = loop_state.get("spec", {}).get("clarifying_question") - await cl.Message(content=f"**ARC a analysé vos retours mais a besoin d'une précision :**\n\n{question}").send() + await render_workflow_state(loop_state) elif current_status == "delivered": await cl.Message(content="✅ Ce projet a déjà été traité et livré.").send() @@ -201,6 +197,10 @@ async def on_open_file(action: cl.Action): filename = action.payload.get("filename") files = cl.user_session.get("current_files", {}) content = files.get(filename, "") + if content is None: + content = "" + if not str(content).strip(): + content = "(Fichier vide)" ext = filename.split(".")[-1] if "." in filename else "text" is_md = ext in ("md", "markdown") @@ -214,7 +214,7 @@ async def on_open_file(action: cl.Action): new_viewer = cl.Text( name=filename, - content=content, + content=str(content), language=None if is_md else ext, display="side", )