Spaces:
Sleeping
Sleeping
| import os | |
| import time | |
| import traceback | |
| from dotenv import load_dotenv | |
| from langchain_core.messages import convert_to_messages | |
| from langchain_core.tools import tool | |
| from langchain_groq import ChatGroq | |
| from langchain_tavily import TavilySearch | |
| from langgraph.prebuilt import create_react_agent | |
| from langgraph_supervisor import create_supervisor | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langsmith import traceable | |
| from e2b_code_interpreter import Sandbox | |
| from langchain_chroma import Chroma | |
| from langchain_community.graphs import Neo4jGraph | |
| from langchain_cohere import ChatCohere, CohereEmbeddings | |
| from langchain_community.chains.graph_qa.cypher import GraphCypherQAChain | |
| from langchain_core.prompts import PromptTemplate | |
| from langchain_community.document_loaders import PyPDFLoader | |
| from langchain_text_splitters import RecursiveCharacterTextSplitter | |
| from langchain_experimental.graph_transformers import LLMGraphTransformer | |
| from langchain_mistralai import ChatMistralAI | |
| # --- WRAPPER FUNCTION START --- | |
| def get_agent_app(): | |
| # --- Load Environment --- | |
| load_dotenv() | |
| # --- Environment Keys (Inside function to capture runtime env) --- | |
| # --- Environment Keys --- | |
| tavily_api_key = os.environ.get("TAVILY_API_KEY") | |
| groq_api_key = os.environ.get("GROQ_API_KEY") | |
| # FIX 1: os.environ() galat tha, os.getenv() sahi hai | |
| google_api_key = os.getenv("GOOGLE_API_KEY") | |
| e2b_api_key = os.environ.get("E2B_API_KEY") | |
| cohere_api_key = os.environ.get("COHERE_API_KEY") | |
| mistralai_api_key = os.environ.get("MISTRALAI_API_KEY") | |
| # Graph Keys | |
| os.environ["NEO4J_URI"] = os.environ.get("NEO4J_URI") | |
| os.environ["NEO4J_USERNAME"] = os.environ.get("NEO4J_USERNAME") | |
| os.environ["NEO4J_PASSWORD"] = os.environ.get("NEO4J_PASSWORD") | |
| # --- Tools Setup --- | |
| web_search = TavilySearch(api_key=tavily_api_key, max_results=3) | |
| # 1. Setup Connection | |
| embeddings = CohereEmbeddings(model="embed-english-v3.0", cohere_api_key=os.environ["COHERE_API_KEY"]) | |
| # Path './' kar diya hai taaki hosting par chale | |
| vector_store = Chroma( | |
| persist_directory="./chroma_db_groq_v1", | |
| embedding_function=embeddings, | |
| collection_name="rag_groq_final" | |
| ) | |
| def vector_tool(query: str) -> str: | |
| """ | |
| Use this tool to find Context, from internal documents. | |
| Input: A search query (e.g., 'AutoDev project architecture'). | |
| """ | |
| print(f" ⚡ [Vector Tool]: Searching Docs for '{query}'...") | |
| try: | |
| results = vector_store.similarity_search(query, k=4) | |
| if not results: | |
| return "VECTOR_FAILURE: No info found in docs." | |
| return "\n\n".join([doc.page_content for doc in results]) | |
| except Exception as e: | |
| return f"Vector Error: {e}" | |
| # 1. Setup Graph & Smart Prompt | |
| try: | |
| graph = Neo4jGraph() | |
| # --- 🔥 UPDATED STRONG PROMPT --- | |
| cypher_template = """ | |
| You are a Neo4j Expert. | |
| Schema: {schema} | |
| Goal: Generate a Cypher query to retrieve ALL connections (Skills, Projects, Education) for the user. | |
| ⚠️ CRITICAL RULES: | |
| 1. **Case-Insensitive:** ALWAYS use `WHERE toLower(p.name) CONTAINS toLower('avneesh')`. | |
| 2. **Relationship Syntax:** When matching multiple relationships, DO NOT repeat the colon. | |
| - ❌ WRONG: `[:HAS_SKILL|:WORKED_ON|:HAS_DEGREE]` | |
| - ✅ CORRECT: `[:HAS_SKILL|WORKED_ON|HAS_DEGREE]` | |
| 3. **Pattern:** `MATCH (p:Person)-[r]->(related) WHERE toLower(p.name) CONTAINS toLower('{question_keyword}') RETURN p, r, related LIMIT 50` | |
| Question: {question} | |
| Cypher Query: | |
| """ | |
| cypher_prompt = PromptTemplate( | |
| template=cypher_template, | |
| input_variables=["schema", "question"] | |
| ) | |
| # Graph logic ke liye GPT-4o best hai (Syntax errors kam karta hai) | |
| cypher_chain = GraphCypherQAChain.from_llm( | |
| llm=ChatGoogleGenerativeAI(model="gemini-2.5-pro",api_key=google_api_key), | |
| graph=graph, | |
| verbose=True, | |
| cypher_prompt=cypher_prompt, | |
| allow_dangerous_requests=True | |
| ) | |
| def graph_tool(query: str) -> str: | |
| """ | |
| Use this tool to find Skills, Relationships, Connections, or Tech Stacks. | |
| """ | |
| print(f" 🔗 [Graph Tool]: Reasoning for '{query}'...") | |
| try: | |
| result = cypher_chain.invoke(query) | |
| data = result['result'] | |
| # Agar Graph khali hai, to Supervisor ko signal do | |
| if not data or "I don't know" in data or data == "[]": | |
| return "GRAPH_FAILURE: No direct match. SUGGESTION: Ask Vector_Specialist." | |
| return str(data) | |
| except Exception as e: | |
| return f"Graph Error: {e}" | |
| except: | |
| # Fallback if graph fails | |
| def graph_tool(query: str) -> str: return "Graph Connection Failed" | |
| # --- Models --- | |
| def create_groq_supervisor_model(): | |
| return ChatGroq(model="qwen/qwen3-32b", api_key=groq_api_key )# Powerful model for reasoning | |
| def create_groq_coding_model(): | |
| return ChatGroq(model="llama-3.3-70b-versatile", api_key=groq_api_key) # Powerful model for coding | |
| def create_google_coding2_model(): | |
| return ChatGoogleGenerativeAI(model="gemini-2.5-flash",api_key=google_api_key) # Powerful model for coding | |
| def create_groq_coding3_model(): | |
| return ChatGroq(model="openai/gpt-oss-20b", api_key=groq_api_key) # Powerful model for coding | |
| def create_mistralai_coding4_model(): | |
| return ChatMistralAI(api_key=mistralai_api_key, | |
| model="ministral-3b-latest", # Using the stable and powerful model | |
| max_retries=3, | |
| temperature=0.7) # max_token removed to avoid errors | |
| sup_model = create_groq_supervisor_model() | |
| coding_model = create_groq_coding_model() | |
| coding_model2 = create_google_coding2_model() | |
| coding_model3 = create_groq_coding3_model() | |
| coding_model4 = create_mistralai_coding4_model() | |
| graph_agent = create_react_agent( | |
| model=coding_model3, | |
| tools=[graph_tool], | |
| prompt=( | |
| """tool` to query the Knowledge Graph. | |
| **Instructions:** | |
| 1. Analyze the user's question and extract key entities (Names, Technologies). | |
| 2. Use the tool to query the database. | |
| 3. **If Data Found:** Return the exact facts found (e.g., "Avneesh knows Python, Java"). | |
| 4. **If No Data/Empty:** Return exactly: "GRAPH_FAILURE: No relevant data found in the knowledge graph." | |
| 5. pass answer to supervisor but do not call any tool respond with the exact message: "graph_info passed successfully to supervisor.""" | |
| ), | |
| name="graph_agent", | |
| ) | |
| #_-- vector Agent --- | |
| vector_agent = create_react_agent( | |
| model=coding_model, | |
| tools=[vector_tool], | |
| prompt=( | |
| """ | |
| "You are a vector expert. Use `vector_tool` to find document context." | |
| "When you get the information, just output the answer directly as text." | |
| "pass answer to supervisor but do not call any tool respond with the exact message: "vector passed successfully to supervisor.""" | |
| ), | |
| name="vector_agent", | |
| ) | |
| web_agent = create_react_agent( | |
| model=sup_model, | |
| tools=[web_search], | |
| prompt=( | |
| """ | |
| "You are a web expert. Use `web_search_tool` to find real-time context." | |
| "When you get the information, just output the answer directly as text." | |
| "pass answer to supervisor but do not call any tool respond with the exact message: "web_info passed successfully to supervisor.""" | |
| ), | |
| name="web_agent", | |
| ) | |
| # --- Supervisor --- | |
| supervisor = create_supervisor( | |
| model=coding_model2, | |
| agents=[vector_agent,graph_agent, web_agent], | |
| prompt=( | |
| """ | |
| You are a Senior Technical Project Manager (Supervisor). | |
| Your goal is to answer user queries by orchestrating a team of agents in a SPECIFIC ORDER. | |
| ⚠️ **INTELLIGENT WORKFLOW (FOLLOW STRICTLY):** | |
| **STEP 1: IDENTIFY (Graph_Agent)** | |
| - ALWAYS call `Graph_Agent` FIRST. | |
| - Ask it to find the *relationships* and *facts* about the entities in the user's query. | |
| - *Goal:* Figure out "What is this?" (e.g., Is 'AutoDev' a person, a project, or a skill?). | |
| **STEP 2: STRATEGIZE (Internal Thought)** | |
| - Analyze the Graph_Agent's output. | |
| - IF Graph says "X is a Project" -> You know you need architecture/code details. | |
| - IF Graph says "X is a Person" -> You might need their resume/bio. | |
| **STEP 3: DEEP DIVE (Vector_Agent)** | |
| - Based on Step 2, formulate a *Specific Query* for the `Vector_Agent`. | |
| - ❌ DO NOT just pass the user's raw question. | |
| - ✅ PASS A TARGETED QUERY. | |
| - *Bad:* "Tell me about AutoDev." | |
| - *Good:* "Search documents for 'AutoDev' architecture diagrams, tech stack, and deployment steps." | |
| **STEP 4: EXECUTE/REFINE (Coder_Agent / Web_Agent)** | |
| - If you need to calculate something or run code, use `Coder_Agent` with the data gathered from Step 1 & 3. | |
| - Use `Web_Agent` ONLY if the data is missing from both Graph and Docs (e.g., live stock prices). | |
| **FINAL OUTPUT:** | |
| - Synthesize all info into a clear, professional answer. | |
| """ | |
| ), | |
| sanitize_names=True, | |
| add_handoff_back_messages=True, | |
| output_mode="full_history", | |
| ).compile() | |
| # --- Return Statement (Ab ye indented hai, isliye error nahi aayega) --- | |
| return supervisor |