from agents.planning_agent import planning_agent from agents.reasoning_agent import reasoning_agent from src.helper import convert_messages def run_conversation_pipeline(messages): """ Main orchestration pipeline. Flow: messages ↓ planner ↓ retrieval routing ↓ reasoning ↓ final response assembly """ # ========================================== # Convert FastAPI Messages → LangChain Messages # ========================================== lc_messages = convert_messages(messages) # ========================================== # PLANNER LAYER # ========================================== planner_response = planning_agent(lc_messages) print("Planner Layer") planner_type = planner_response.get("type") # ========================================== # CASE 1 — PRE-RETRIEVAL CLARIFICATION # ========================================== if planner_type == "clarification": print("Pre Retrieval Clarification") return { "reply": planner_response["message"], "recommendations": [], "end_of_conversation": False } # ========================================== # CASE 2 — REFUSAL / INJECTION # ========================================== elif planner_type == "refusal": print("Refusal/Injection") return { "reply": planner_response["message"], "recommendations": [], "end_of_conversation": False } # ========================================== # CASE 3 — RETRIEVAL # ========================================== elif planner_type == "retrieval": print("Retrieval -> Moving to Reasoning Layer") retrieved_docs = planner_response["docs"] # ========================================== # REASONING LAYER # ========================================== reasoning_response = reasoning_agent( messages=lc_messages, docs=retrieved_docs ) print("Reasoning Layer") reasoning_type = reasoning_response.get("type") # ========================================== # CASE 3A — POST-RETRIEVAL CLARIFICATION # ========================================== if reasoning_type == "clarification": print("Post Retrieval Clarification") return { "reply": reasoning_response["message"], "recommendations": [], "end_of_conversation": False } # ========================================== # CASE 3B — COMPARISON # ========================================== elif reasoning_type == "comparison": print("Comparison") return { "reply": reasoning_response["message"], "recommendations": [], "end_of_conversation": False } # ========================================== # CASE 3C — FINAL RECOMMENDATIONS # ========================================== elif reasoning_type == "recommendation": print("Final Recommendations" if reasoning_response["end_of_conversation"] else "Recommendations") return { "reply": reasoning_response["message"], "recommendations": reasoning_response["recommendations"], "end_of_conversation": reasoning_response["end_of_conversation"] } # ========================================== # FALLBACK # ========================================== else: print("Reasoning Layer Fallback") return { "reply": reasoning_response.get( "message", "Unable to process reasoning response." ), "recommendations": [], "end_of_conversation": False } # ========================================== # GLOBAL FALLBACK # ========================================== print("Planning Layer Fallback") return { "reply": planner_response.get( "message", "Unable to process request." ), "recommendations": [], "end_of_conversation": False }