from schemas import AgentState, SupervisorDecision from core.llm_router import get_llm def supervisor_node(state: AgentState): """ Supervisor (Router) z 2026 r. zintegrowany z Blackboard. Kieruje wiadomości lub wywołuje wykonanie kolejnego zdefiniowanego kroku w task_plan. """ if not state.messages: return {"current_agent": "planner"} # Check if there is an active plan in blackboard to execute if state.task_plan and len(state.task_plan) > 0: next_task = state.task_plan[0].lower() if "profil" in next_task: return {"current_agent": "profiler"} elif "dopasowa" in next_task or "match" in next_task: return {"current_agent": "matcher"} # Logika oparta na planie będzie o wiele bardziej rozbudowana w produkcji. last_msg = ( state.messages[-1].get("content", "") if isinstance(state.messages[-1], dict) else getattr(state.messages[-1], "content", "") ) prompt = f""" Jesteś supervisorem (dyrektorem) systemu 'GrantForge AI'. Mamy następujące działy (agentów): - planner: planowanie działań - profiler: zbieranie danych firmy z KRS/chatu - researcher: eksploracja dotacji - matcher: dopasowanie znanych dotacji - verifier: sprawdzanie formalne - wizard: pisanie wniosku, wymyślanie treści - risk_scoring: punktowanie szans i ryzyk wniosku - document_gap_analyzer: analiza braków dokumentu - compliance_guardian: sprawdzanie RODO - end: koniec procesu, oddanie głosu klientowi Na podstawie ostatniej wiadomości opisz krótko powód (reason) i wskaż jednoznaczną wartość next_agent z listy powyżej. Wiadomość z systemu klienta: {last_msg} """ try: llm = get_llm(task_type="standard", structured_output_schema=SupervisorDecision) decision = llm.invoke(prompt) valid_agents = [ "planner", "profiler", "researcher", "matcher", "verifier", "wizard", "risk_scoring", "document_gap_analyzer", "compliance_guardian", "end", ] if decision.next_agent in valid_agents: # W przyszłości reason można wykorzystać do logowania logiki routing-u return {"current_agent": decision.next_agent} except Exception as e: print(f"Błąd supervisora LLM: {str(e)}") return {"current_agent": "end"}