"""agents.py — Supervisor + 4 workers. Zero if/else/for/while/try/except.""" import os def build_agent(): """Build the full supervisor graph. Called once at startup.""" from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from langgraph_supervisor import create_supervisor from langgraph.checkpoint.memory import MemorySaver from tools import search_openalex, search_tavily, search_scopus, validate_papers, run_bertopic, upload_to_storage llm = ChatOpenAI( model="Qwen/Qwen2.5-72B-Instruct", base_url="https://router.huggingface.co/v1/", api_key=os.getenv("HF_TOKEN"), temperature=0.01, ) oa = create_react_agent(llm, tools=[search_openalex], name="openalex_agent", prompt="You search OpenAlex. Extract BOTH the query and the chat_id from the user prompt. Call your tool once with the query and chat_id, return only the raw output, do nothing else.") tv = create_react_agent(llm, tools=[search_tavily], name="tavily_agent", prompt="You search Tavily. Extract BOTH the query and the chat_id from the user prompt. Call your tool once with the query and chat_id, return only the raw output, do nothing else.") sc = create_react_agent(llm, tools=[search_scopus], name="scopus_agent", prompt="You search Scopus. Extract BOTH the query and the chat_id from the user prompt. Call your tool once with the query and chat_id, return only the raw output, do nothing else.") val = create_react_agent(llm, tools=[validate_papers], name="validation_agent", prompt="You validate papers and check if they are relevant to the original query. Extract BOTH the query and the chat_id from the user prompt. Call your tool once with the query and chat_id, return only the raw output, do nothing else.") an = create_react_agent(llm, tools=[run_bertopic, upload_to_storage], name="analysis_agent", prompt="You run analysis. Extract the chat_id from the user prompt. First call run_bertopic with the chat_id, then call upload_to_storage with the chat_id. Return only the raw output, do nothing else.") workflow = create_supervisor( [oa, tv, sc, val, an], model=llm, prompt=("You are a research supervisor. For every query, you must run all 5 agents sequentially in this exact order: " "1) openalex_agent 2) tavily_agent 3) scopus_agent 4) validation_agent 5) analysis_agent. " "Always use ALL 5 agents."), output_mode="full_history") return workflow.compile(checkpointer=MemorySaver())