Spaces:
Sleeping
Sleeping
Ara Yeroyan
commited on
Commit
Β·
1154c8d
1
Parent(s):
9490389
refactor
Browse files- multi_agent_chatbot.py +12 -13
multi_agent_chatbot.py
CHANGED
|
@@ -8,24 +8,26 @@ This system implements a 3-agent architecture:
|
|
| 8 |
|
| 9 |
Each agent has specialized prompts and responsibilities.
|
| 10 |
"""
|
|
|
|
| 11 |
import json
|
| 12 |
import time
|
| 13 |
import logging
|
|
|
|
| 14 |
from pathlib import Path
|
| 15 |
from datetime import datetime
|
| 16 |
from dataclasses import dataclass
|
| 17 |
from typing import Dict, List, Any, Optional, TypedDict
|
| 18 |
|
| 19 |
-
|
| 20 |
from langchain_core.tools import tool
|
| 21 |
from langgraph.graph import StateGraph, END
|
| 22 |
-
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
|
| 23 |
from langchain_core.prompts import ChatPromptTemplate
|
|
|
|
| 24 |
|
| 25 |
|
| 26 |
from src.pipeline import PipelineManager
|
| 27 |
-
from src.config.loader import load_config
|
| 28 |
from src.llm.adapters import get_llm_client
|
|
|
|
|
|
|
| 29 |
|
| 30 |
|
| 31 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
@@ -46,6 +48,7 @@ class QueryContext:
|
|
| 46 |
needs_follow_up: bool = False
|
| 47 |
follow_up_question: Optional[str] = None
|
| 48 |
|
|
|
|
| 49 |
class MultiAgentState(TypedDict):
|
| 50 |
"""State for the multi-agent conversation flow"""
|
| 51 |
conversation_id: str
|
|
@@ -61,6 +64,7 @@ class MultiAgentState(TypedDict):
|
|
| 61 |
session_start_time: float
|
| 62 |
last_ai_message_time: float
|
| 63 |
|
|
|
|
| 64 |
class MultiAgentRAGChatbot:
|
| 65 |
"""Multi-agent RAG chatbot with specialized agents"""
|
| 66 |
|
|
@@ -112,7 +116,6 @@ class MultiAgentRAGChatbot:
|
|
| 112 |
logger.info("β
Pipeline manager initialized and models loaded")
|
| 113 |
except Exception as e:
|
| 114 |
logger.error(f"β Failed to initialize pipeline manager: {e}")
|
| 115 |
-
import traceback
|
| 116 |
traceback.print_exc()
|
| 117 |
raise RuntimeError(f"Pipeline manager initialization failed: {e}")
|
| 118 |
|
|
@@ -129,7 +132,6 @@ class MultiAgentRAGChatbot:
|
|
| 129 |
raise # Re-raise RuntimeError as-is
|
| 130 |
except Exception as e:
|
| 131 |
logger.error(f"β Error during vector store connection: {e}")
|
| 132 |
-
import traceback
|
| 133 |
traceback.print_exc()
|
| 134 |
raise RuntimeError(f"Vector store connection failed: {e}")
|
| 135 |
|
|
@@ -139,8 +141,8 @@ class MultiAgentRAGChatbot:
|
|
| 139 |
# Build the multi-agent graph
|
| 140 |
self.graph = self._build_graph()
|
| 141 |
|
| 142 |
-
# Conversations directory - use
|
| 143 |
-
self.conversations_dir =
|
| 144 |
try:
|
| 145 |
# Use 777 permissions for maximum compatibility (HF Spaces runs as different user)
|
| 146 |
self.conversations_dir.mkdir(parents=True, mode=0o777, exist_ok=True)
|
|
@@ -158,9 +160,9 @@ class MultiAgentRAGChatbot:
|
|
| 158 |
|
| 159 |
def _load_dynamic_data(self):
|
| 160 |
"""Load dynamic data from filter_options.json and add_district_metadata.py"""
|
| 161 |
-
# Load filter options
|
| 162 |
try:
|
| 163 |
-
fo =
|
| 164 |
if fo.exists():
|
| 165 |
with open(fo) as f:
|
| 166 |
data = json.load(f)
|
|
@@ -178,7 +180,7 @@ class MultiAgentRAGChatbot:
|
|
| 178 |
self.source_whitelist = ['Consolidated', 'Local Government', 'Ministry, Department and Agency']
|
| 179 |
self.district_whitelist = ['Kampala', 'Gulu', 'Kalangala']
|
| 180 |
|
| 181 |
-
# Enrich district list from add_district_metadata.py
|
| 182 |
try:
|
| 183 |
from add_district_metadata import DistrictMetadataProcessor
|
| 184 |
proc = DistrictMetadataProcessor()
|
|
@@ -590,7 +592,6 @@ Analyze this query using ONLY the exact values provided above:""")
|
|
| 590 |
# Clean and parse JSON with better error handling
|
| 591 |
try:
|
| 592 |
# Remove comments (// and /* */) from JSON
|
| 593 |
-
import re
|
| 594 |
# Remove single-line comments
|
| 595 |
content = re.sub(r'//.*?$', '', content, flags=re.MULTILINE)
|
| 596 |
# Remove multi-line comments
|
|
@@ -603,7 +604,6 @@ Analyze this query using ONLY the exact values provided above:""")
|
|
| 603 |
logger.error(f"β Raw content: {content[:200]}...")
|
| 604 |
|
| 605 |
# Try to extract JSON from text if embedded
|
| 606 |
-
import re
|
| 607 |
json_match = re.search(r'\{.*\}', content, re.DOTALL)
|
| 608 |
if json_match:
|
| 609 |
try:
|
|
@@ -1178,7 +1178,6 @@ Generate a conversational response based on your knowledge:""")
|
|
| 1178 |
|
| 1179 |
except Exception as e:
|
| 1180 |
logger.error(f"Could not save conversation: {e}")
|
| 1181 |
-
import traceback
|
| 1182 |
logger.error(f"Traceback: {traceback.format_exc()}")
|
| 1183 |
|
| 1184 |
|
|
|
|
| 8 |
|
| 9 |
Each agent has specialized prompts and responsibilities.
|
| 10 |
"""
|
| 11 |
+
import re
|
| 12 |
import json
|
| 13 |
import time
|
| 14 |
import logging
|
| 15 |
+
import traceback
|
| 16 |
from pathlib import Path
|
| 17 |
from datetime import datetime
|
| 18 |
from dataclasses import dataclass
|
| 19 |
from typing import Dict, List, Any, Optional, TypedDict
|
| 20 |
|
|
|
|
| 21 |
from langchain_core.tools import tool
|
| 22 |
from langgraph.graph import StateGraph, END
|
|
|
|
| 23 |
from langchain_core.prompts import ChatPromptTemplate
|
| 24 |
+
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
|
| 25 |
|
| 26 |
|
| 27 |
from src.pipeline import PipelineManager
|
|
|
|
| 28 |
from src.llm.adapters import get_llm_client
|
| 29 |
+
from src.config.paths import PROJECT_DIR, CONVERSATIONS_DIR
|
| 30 |
+
from src.config.loader import load_config, get_embedding_model_for_collection
|
| 31 |
|
| 32 |
|
| 33 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
|
| 48 |
needs_follow_up: bool = False
|
| 49 |
follow_up_question: Optional[str] = None
|
| 50 |
|
| 51 |
+
|
| 52 |
class MultiAgentState(TypedDict):
|
| 53 |
"""State for the multi-agent conversation flow"""
|
| 54 |
conversation_id: str
|
|
|
|
| 64 |
session_start_time: float
|
| 65 |
last_ai_message_time: float
|
| 66 |
|
| 67 |
+
|
| 68 |
class MultiAgentRAGChatbot:
|
| 69 |
"""Multi-agent RAG chatbot with specialized agents"""
|
| 70 |
|
|
|
|
| 116 |
logger.info("β
Pipeline manager initialized and models loaded")
|
| 117 |
except Exception as e:
|
| 118 |
logger.error(f"β Failed to initialize pipeline manager: {e}")
|
|
|
|
| 119 |
traceback.print_exc()
|
| 120 |
raise RuntimeError(f"Pipeline manager initialization failed: {e}")
|
| 121 |
|
|
|
|
| 132 |
raise # Re-raise RuntimeError as-is
|
| 133 |
except Exception as e:
|
| 134 |
logger.error(f"β Error during vector store connection: {e}")
|
|
|
|
| 135 |
traceback.print_exc()
|
| 136 |
raise RuntimeError(f"Vector store connection failed: {e}")
|
| 137 |
|
|
|
|
| 141 |
# Build the multi-agent graph
|
| 142 |
self.graph = self._build_graph()
|
| 143 |
|
| 144 |
+
# Conversations directory - use PROJECT_DIR for local vs deployed compatibility
|
| 145 |
+
self.conversations_dir = CONVERSATIONS_DIR
|
| 146 |
try:
|
| 147 |
# Use 777 permissions for maximum compatibility (HF Spaces runs as different user)
|
| 148 |
self.conversations_dir.mkdir(parents=True, mode=0o777, exist_ok=True)
|
|
|
|
| 160 |
|
| 161 |
def _load_dynamic_data(self):
|
| 162 |
"""Load dynamic data from filter_options.json and add_district_metadata.py"""
|
| 163 |
+
# Load filter options - use PROJECT_DIR relative path
|
| 164 |
try:
|
| 165 |
+
fo = PROJECT_DIR / "src" / "config" / "filter_options.json"
|
| 166 |
if fo.exists():
|
| 167 |
with open(fo) as f:
|
| 168 |
data = json.load(f)
|
|
|
|
| 180 |
self.source_whitelist = ['Consolidated', 'Local Government', 'Ministry, Department and Agency']
|
| 181 |
self.district_whitelist = ['Kampala', 'Gulu', 'Kalangala']
|
| 182 |
|
| 183 |
+
# Enrich district list from add_district_metadata.py (if available)
|
| 184 |
try:
|
| 185 |
from add_district_metadata import DistrictMetadataProcessor
|
| 186 |
proc = DistrictMetadataProcessor()
|
|
|
|
| 592 |
# Clean and parse JSON with better error handling
|
| 593 |
try:
|
| 594 |
# Remove comments (// and /* */) from JSON
|
|
|
|
| 595 |
# Remove single-line comments
|
| 596 |
content = re.sub(r'//.*?$', '', content, flags=re.MULTILINE)
|
| 597 |
# Remove multi-line comments
|
|
|
|
| 604 |
logger.error(f"β Raw content: {content[:200]}...")
|
| 605 |
|
| 606 |
# Try to extract JSON from text if embedded
|
|
|
|
| 607 |
json_match = re.search(r'\{.*\}', content, re.DOTALL)
|
| 608 |
if json_match:
|
| 609 |
try:
|
|
|
|
| 1178 |
|
| 1179 |
except Exception as e:
|
| 1180 |
logger.error(f"Could not save conversation: {e}")
|
|
|
|
| 1181 |
logger.error(f"Traceback: {traceback.format_exc()}")
|
| 1182 |
|
| 1183 |
|