Spaces:
Sleeping
Sleeping
File size: 9,756 Bytes
90eaf96 c608440 90eaf96 c608440 f0fb393 c608440 90eaf96 69b6831 90eaf96 c608440 90eaf96 c948f7b c608440 90eaf96 f0fb393 c608440 90eaf96 c608440 90eaf96 dea87eb 90eaf96 c608440 90eaf96 987ec40 90eaf96 987ec40 02227a8 90eaf96 987ec40 90eaf96 c608440 90eaf96 f0fb393 90eaf96 f0fb393 90eaf96 f0fb393 90eaf96 02227a8 90eaf96 02227a8 90eaf96 f0fb393 90eaf96 8417629 90eaf96 2cb95cb 90eaf96 02227a8 c608440 90eaf96 f0fb393 e85789d 90eaf96 c608440 02227a8 c608440 90eaf96 a142f83 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
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"
)
@tool
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
)
@tool
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
@tool
def graph_tool(query: str) -> str: return "Graph Connection Failed"
# --- Models ---
@traceable
def create_groq_supervisor_model():
return ChatGroq(model="qwen/qwen3-32b", api_key=groq_api_key )# Powerful model for reasoning
@traceable
def create_groq_coding_model():
return ChatGroq(model="llama-3.3-70b-versatile", api_key=groq_api_key) # Powerful model for coding
@traceable
def create_google_coding2_model():
return ChatGoogleGenerativeAI(model="gemini-2.5-flash",api_key=google_api_key) # Powerful model for coding
@traceable
def create_groq_coding3_model():
return ChatGroq(model="openai/gpt-oss-20b", api_key=groq_api_key) # Powerful model for coding
@traceable
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 |