fin étape 2 (dev_agent) + automatisation lancement projet/arrêt projet + séparation des docker-compose

This commit is contained in:
Chevallier
2026-06-22 15:55:59 +02:00
parent 981cfb6f2e
commit 17e887b268
18 changed files with 633 additions and 212 deletions

View File

@@ -4,6 +4,7 @@ from app.agents.dev_agent import run_dev_agent
from app.agents.qa_agent import run_qa_agent
from app.services.retrieval_service import find_existing_project
from app.graph.state import WorkflowState
from langchain_core.runnables import RunnableConfig
async def pm_node(state: WorkflowState):
history = state.get("chat_history", []) or []
@@ -32,8 +33,13 @@ async def pm_node(state: WorkflowState):
"loop_count": 0,
}
async def retrieval_node(state: WorkflowState):
existing_project = await find_existing_project(state["user_input"])
async def retrieval_node(state: WorkflowState, config: RunnableConfig):
qdrant_repo = config.get("configurable", {}).get("qdrant_repo")
if not qdrant_repo:
raise ValueError("❌ Erreur : Le repository Qdrant n'a pas été transmis au graphe.")
existing_project = await find_existing_project(qdrant_repo, state["user_input"])
return {
"existing_project": existing_project,
"status": "existing_found" if existing_project else "no_existing_project",
@@ -69,45 +75,4 @@ async def human_review_node(state: WorkflowState):
"existing_project_approved": True,
"is_completed": True,
"status": "approved_by_human"
}
# def inspect_specifications_gaps(spec_dict: dict) -> list[str]:
# missing_fields = []
# # 1. Vérifications globales (clés alignées sur ProjectSpec)
# if not spec_dict.get("title"): missing_fields.append("title")
# if not spec_dict.get("description"): missing_fields.append("description")
# if not spec_dict.get("requirements"): missing_fields.append("requirements")
# # 2. Entrées/Sorties
# io = spec_dict.get("io_config", {})
# if io.get("has_inputs") is True and not io.get("input_type"):
# missing_fields.append("io_config.input_type")
# if io.get("has_outputs") is True and not io.get("output_type"):
# missing_fields.append("io_config.output_type")
# # 3. Authentification
# auth = spec_dict.get("auth_config", {})
# if auth.get("requires_auth") is True and not auth.get("auth_method"):
# missing_fields.append("auth_config.auth_method")
# return missing_fields
# def generate_clarifying_questions_prompt(missing_fields: list[str]) -> str:
# # Le mapping utilise désormais les EXACTES mêmes clés
# mapping_instructions = {
# "title": "- Préciser un titre pour le projet.",
# "description": "- Expliquer le but global du script.",
# "requirements": "- Lister les fonctionnalités attendues étape par étape.",
# "io_config.input_type": "- Préciser le type et le format des fichiers/données d'entrée (CSV, dossier, etc.).",
# "io_config.output_type": "- Préciser le type et le format attendus en sortie (Excel, PDF, log, etc.).",
# "auth_config.auth_method": "- Clarifier la méthode d'accès ou d'authentification exigée pour l'outil tiers."
# }
# bullet_points = "\n".join([mapping_instructions[field] for field in missing_fields if field in mapping_instructions])
# return f"""
# ATTENTION : Les données suivantes sont obligatoires mais absentes.
# Vous devez formuler une question naturelle et polie pour demander à l'utilisateur de préciser :
# {bullet_points}
# """
}