Spaces:
Sleeping
Sleeping
Commit
·
0b2c9fd
1
Parent(s):
abd776c
next commit
Browse files- README.md +1 -1
- api/routers/analytics_chatbot.py +4 -6
- app.py +1 -1
- config/__init__.py +0 -0
- config/logger_config.py +58 -0
- config/redis_config.py +17 -0
- logger_config.py +56 -56
- logs/access.log +54 -0
- src/genai/analytics_chatbot/agent.py +9 -4
- src/genai/analytics_chatbot/utils/nodes.py +62 -23
- src/genai/analytics_chatbot/utils/prompts.py +15 -4
- src/genai/analytics_chatbot/utils/state.py +2 -1
- src/genai/analytics_chatbot/utils/tools.py +1 -29
- src/genai/analytics_chatbot/utils/utils.py +3 -0
- src/genai/utils/models_loader.py +1 -0
README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
|
| 2 |
---
|
| 3 |
-
title:
|
| 4 |
sdk: docker
|
| 5 |
emoji: 🚀
|
| 6 |
colorFrom: blue
|
|
|
|
| 1 |
|
| 2 |
---
|
| 3 |
+
title: rt-genai-fastapi
|
| 4 |
sdk: docker
|
| 5 |
emoji: 🚀
|
| 6 |
colorFrom: blue
|
api/routers/analytics_chatbot.py
CHANGED
|
@@ -10,17 +10,16 @@ from api.stored_data import stored_data
|
|
| 10 |
from src.genai.analytics_chatbot.agent import ChatbotAgent
|
| 11 |
from src.genai.analytics_chatbot.utils.utils import process_query
|
| 12 |
from api.schemas.analytics_chatbot import UserMessage
|
|
|
|
|
|
|
| 13 |
|
| 14 |
app_logger = logging.getLogger("app_logger")
|
| 15 |
error_logger = logging.getLogger("error_logger")
|
| 16 |
-
|
| 17 |
-
host = os.environ['REDIS_HOST']
|
| 18 |
-
port = os.environ['REDIS_PORT']
|
| 19 |
|
| 20 |
router = APIRouter()
|
| 21 |
agent=ChatbotAgent()
|
| 22 |
graph = agent.chatbot_graph()
|
| 23 |
-
redis_client = Redis(host=host, port=port, db=0, decode_responses=True, username="default",password=password)
|
| 24 |
|
| 25 |
@router.get("/analytics-chatbot")
|
| 26 |
def get_analytics(msg:str):
|
|
@@ -45,6 +44,5 @@ def get_analytics(msg:str):
|
|
| 45 |
}
|
| 46 |
|
| 47 |
# Save to Redis with TTL (e.g., 1 hour)
|
| 48 |
-
redis_client.set(cache_key, json.dumps(response_to_cache), ex=
|
| 49 |
-
|
| 50 |
return response_to_cache
|
|
|
|
| 10 |
from src.genai.analytics_chatbot.agent import ChatbotAgent
|
| 11 |
from src.genai.analytics_chatbot.utils.utils import process_query
|
| 12 |
from api.schemas.analytics_chatbot import UserMessage
|
| 13 |
+
from config.redis_config import redis_client
|
| 14 |
+
|
| 15 |
|
| 16 |
app_logger = logging.getLogger("app_logger")
|
| 17 |
error_logger = logging.getLogger("error_logger")
|
| 18 |
+
|
|
|
|
|
|
|
| 19 |
|
| 20 |
router = APIRouter()
|
| 21 |
agent=ChatbotAgent()
|
| 22 |
graph = agent.chatbot_graph()
|
|
|
|
| 23 |
|
| 24 |
@router.get("/analytics-chatbot")
|
| 25 |
def get_analytics(msg:str):
|
|
|
|
| 44 |
}
|
| 45 |
|
| 46 |
# Save to Redis with TTL (e.g., 1 hour)
|
| 47 |
+
redis_client.set(cache_key, json.dumps(response_to_cache), ex=1) # ex=seconds
|
|
|
|
| 48 |
return response_to_cache
|
app.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
from fastapi import FastAPI, Request
|
| 2 |
-
from logger_config import setup_loggers
|
| 3 |
import logging
|
| 4 |
from api.routers import orchestration, context_analysis, ideation , brainstorm , generate_final_story , generate_image, show_analytics, analytics_chatbot
|
| 5 |
|
|
|
|
| 1 |
from fastapi import FastAPI, Request
|
| 2 |
+
from config.logger_config import setup_loggers
|
| 3 |
import logging
|
| 4 |
from api.routers import orchestration, context_analysis, ideation , brainstorm , generate_final_story , generate_image, show_analytics, analytics_chatbot
|
| 5 |
|
config/__init__.py
ADDED
|
File without changes
|
config/logger_config.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# logger_config.py
|
| 2 |
+
import logging
|
| 3 |
+
import os
|
| 4 |
+
|
| 5 |
+
class RelativePathFormatter(logging.Formatter):
|
| 6 |
+
def format(self, record):
|
| 7 |
+
record.relpath = os.path.relpath(record.pathname, os.getcwd())
|
| 8 |
+
return super().format(record)
|
| 9 |
+
|
| 10 |
+
def setup_loggers():
|
| 11 |
+
os.makedirs("logs", exist_ok=True)
|
| 12 |
+
|
| 13 |
+
# === Format ===
|
| 14 |
+
# formatter = logging.Formatter("%(asctime)s | %(levelname)s | %(name)s | %(message)s")
|
| 15 |
+
formatter = RelativePathFormatter("%(asctime)s | %(levelname)s | %(name)s | %(relpath)s:%(lineno)d | %(message)s")
|
| 16 |
+
|
| 17 |
+
# === App Logger ===
|
| 18 |
+
app_logger = logging.getLogger("app_logger")
|
| 19 |
+
app_handler = logging.FileHandler("logs/app.log")
|
| 20 |
+
app_handler.setLevel(logging.INFO)
|
| 21 |
+
app_handler.setFormatter(formatter)
|
| 22 |
+
app_logger.setLevel(logging.INFO)
|
| 23 |
+
app_logger.addHandler(app_handler)
|
| 24 |
+
|
| 25 |
+
# === Error Logger ===
|
| 26 |
+
error_logger = logging.getLogger("error_logger")
|
| 27 |
+
error_handler = logging.FileHandler("logs/errors.log")
|
| 28 |
+
error_handler.setLevel(logging.ERROR)
|
| 29 |
+
error_handler.setFormatter(formatter)
|
| 30 |
+
error_logger.setLevel(logging.ERROR)
|
| 31 |
+
error_logger.addHandler(error_handler)
|
| 32 |
+
|
| 33 |
+
# === Access Logger === (optional for request logs)
|
| 34 |
+
access_logger = logging.getLogger("access_logger")
|
| 35 |
+
access_handler = logging.FileHandler("logs/access.log")
|
| 36 |
+
access_handler.setLevel(logging.INFO)
|
| 37 |
+
access_handler.setFormatter(formatter)
|
| 38 |
+
access_logger.setLevel(logging.INFO)
|
| 39 |
+
access_logger.addHandler(access_handler)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
# === Warning Logger ===
|
| 43 |
+
warning_logger = logging.getLogger("warning_logger")
|
| 44 |
+
warning_handler = logging.FileHandler("logs/warnings.log")
|
| 45 |
+
warning_handler.setLevel(logging.WARNING) # WARNING, ERROR, CRITICAL
|
| 46 |
+
warning_handler.setFormatter(formatter)
|
| 47 |
+
warning_logger.setLevel(logging.WARNING)
|
| 48 |
+
warning_logger.addHandler(warning_handler)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
# Optional: also log to console
|
| 52 |
+
console_handler = logging.StreamHandler()
|
| 53 |
+
console_handler.setFormatter(formatter)
|
| 54 |
+
app_logger.addHandler(console_handler)
|
| 55 |
+
error_logger.addHandler(console_handler)
|
| 56 |
+
access_logger.addHandler(console_handler)
|
| 57 |
+
warning_logger.addHandler(console_handler)
|
| 58 |
+
|
config/redis_config.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from redis import Redis
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
# Load Redis credentials from environment
|
| 5 |
+
password = os.environ['REDIS_PASSWORD']
|
| 6 |
+
host = os.environ['REDIS_HOST']
|
| 7 |
+
port = os.environ.get('REDIS_PORT', 6379) # default fallback
|
| 8 |
+
|
| 9 |
+
# Initialize Redis client
|
| 10 |
+
redis_client = Redis(
|
| 11 |
+
host=host,
|
| 12 |
+
port=port,
|
| 13 |
+
db=0,
|
| 14 |
+
decode_responses=True,
|
| 15 |
+
username="default",
|
| 16 |
+
password=password
|
| 17 |
+
)
|
logger_config.py
CHANGED
|
@@ -1,58 +1,58 @@
|
|
| 1 |
-
# logger_config.py
|
| 2 |
-
import logging
|
| 3 |
-
import os
|
| 4 |
-
|
| 5 |
-
class RelativePathFormatter(logging.Formatter):
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
|
| 10 |
-
def setup_loggers():
|
| 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 |
|
|
|
|
| 1 |
+
# # logger_config.py
|
| 2 |
+
# import logging
|
| 3 |
+
# import os
|
| 4 |
+
|
| 5 |
+
# class RelativePathFormatter(logging.Formatter):
|
| 6 |
+
# def format(self, record):
|
| 7 |
+
# record.relpath = os.path.relpath(record.pathname, os.getcwd())
|
| 8 |
+
# return super().format(record)
|
| 9 |
|
| 10 |
+
# def setup_loggers():
|
| 11 |
+
# os.makedirs("logs", exist_ok=True)
|
| 12 |
+
|
| 13 |
+
# # === Format ===
|
| 14 |
+
# # formatter = logging.Formatter("%(asctime)s | %(levelname)s | %(name)s | %(message)s")
|
| 15 |
+
# formatter = RelativePathFormatter("%(asctime)s | %(levelname)s | %(name)s | %(relpath)s:%(lineno)d | %(message)s")
|
| 16 |
+
|
| 17 |
+
# # === App Logger ===
|
| 18 |
+
# app_logger = logging.getLogger("app_logger")
|
| 19 |
+
# app_handler = logging.FileHandler("logs/app.log")
|
| 20 |
+
# app_handler.setLevel(logging.INFO)
|
| 21 |
+
# app_handler.setFormatter(formatter)
|
| 22 |
+
# app_logger.setLevel(logging.INFO)
|
| 23 |
+
# app_logger.addHandler(app_handler)
|
| 24 |
+
|
| 25 |
+
# # === Error Logger ===
|
| 26 |
+
# error_logger = logging.getLogger("error_logger")
|
| 27 |
+
# error_handler = logging.FileHandler("logs/errors.log")
|
| 28 |
+
# error_handler.setLevel(logging.ERROR)
|
| 29 |
+
# error_handler.setFormatter(formatter)
|
| 30 |
+
# error_logger.setLevel(logging.ERROR)
|
| 31 |
+
# error_logger.addHandler(error_handler)
|
| 32 |
+
|
| 33 |
+
# # === Access Logger === (optional for request logs)
|
| 34 |
+
# access_logger = logging.getLogger("access_logger")
|
| 35 |
+
# access_handler = logging.FileHandler("logs/access.log")
|
| 36 |
+
# access_handler.setLevel(logging.INFO)
|
| 37 |
+
# access_handler.setFormatter(formatter)
|
| 38 |
+
# access_logger.setLevel(logging.INFO)
|
| 39 |
+
# access_logger.addHandler(access_handler)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
# # === Warning Logger ===
|
| 43 |
+
# warning_logger = logging.getLogger("warning_logger")
|
| 44 |
+
# warning_handler = logging.FileHandler("logs/warnings.log")
|
| 45 |
+
# warning_handler.setLevel(logging.WARNING) # WARNING, ERROR, CRITICAL
|
| 46 |
+
# warning_handler.setFormatter(formatter)
|
| 47 |
+
# warning_logger.setLevel(logging.WARNING)
|
| 48 |
+
# warning_logger.addHandler(warning_handler)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
# # Optional: also log to console
|
| 52 |
+
# console_handler = logging.StreamHandler()
|
| 53 |
+
# console_handler.setFormatter(formatter)
|
| 54 |
+
# app_logger.addHandler(console_handler)
|
| 55 |
+
# error_logger.addHandler(console_handler)
|
| 56 |
+
# access_logger.addHandler(console_handler)
|
| 57 |
+
# warning_logger.addHandler(console_handler)
|
| 58 |
|
logs/access.log
CHANGED
|
@@ -1537,3 +1537,57 @@
|
|
| 1537 |
2025-10-26 15:34:26,248 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1538 |
2025-10-26 15:41:29,547 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=I%20want%20sentiment%20distribution%20of%20divya%20dhakal
|
| 1539 |
2025-10-26 15:41:32,818 | INFO | access_logger | app.py:20 | Response status: 200
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1537 |
2025-10-26 15:34:26,248 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1538 |
2025-10-26 15:41:29,547 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=I%20want%20sentiment%20distribution%20of%20divya%20dhakal
|
| 1539 |
2025-10-26 15:41:32,818 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1540 |
+
2025-10-27 12:15:41,325 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/
|
| 1541 |
+
2025-10-27 12:15:41,326 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1542 |
+
2025-10-27 12:15:41,805 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/favicon.ico
|
| 1543 |
+
2025-10-27 12:15:41,807 | INFO | access_logger | app.py:20 | Response status: 404
|
| 1544 |
+
2025-10-27 12:15:44,388 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/docs
|
| 1545 |
+
2025-10-27 12:15:44,389 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1546 |
+
2025-10-27 12:15:44,535 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/openapi.json
|
| 1547 |
+
2025-10-27 12:15:44,543 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1548 |
+
2025-10-27 15:05:10,775 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=is%20the%20analytics%20of%20divya%20dhakal%20good%20or%20bad%3F
|
| 1549 |
+
2025-10-27 15:05:27,085 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1550 |
+
2025-10-27 15:07:29,247 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=is%20the%20analytics%20of%20divya%20dhakal%20good%20or%20bad%3F
|
| 1551 |
+
2025-10-27 15:07:31,099 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1552 |
+
2025-10-27 15:08:27,971 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=is%20the%20analytics%20of%20divya%20dhakal%20good%20or%20bad%3F
|
| 1553 |
+
2025-10-27 15:08:29,879 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1554 |
+
2025-10-27 15:09:01,555 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=is%20the%20overall%20analytics%20of%20divya%20dhakal%20good%20or%20bad%3F
|
| 1555 |
+
2025-10-27 15:09:08,484 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1556 |
+
2025-10-27 15:10:29,900 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=Which%20influencer%20is%20more%20close%20to%20the%20audience%3F
|
| 1557 |
+
2025-10-27 15:10:35,983 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1558 |
+
2025-10-27 15:17:11,285 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=is%20the%20analytics%20of%20divya%20dhakal%20good%20or%20bad%3F
|
| 1559 |
+
2025-10-27 15:17:11,613 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1560 |
+
2025-10-27 15:17:49,986 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=which%20influencer%20is%20more%20close%20to%20the%20audience%3F
|
| 1561 |
+
2025-10-27 15:18:00,905 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1562 |
+
2025-10-27 15:39:42,259 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=which%20influencer%20is%20more%20close%20to%20the%20audience%3F
|
| 1563 |
+
2025-10-27 15:39:56,557 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1564 |
+
2025-10-28 13:44:52,420 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/
|
| 1565 |
+
2025-10-28 13:44:52,420 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1566 |
+
2025-10-28 13:44:52,918 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/favicon.ico
|
| 1567 |
+
2025-10-28 13:44:52,919 | INFO | access_logger | app.py:20 | Response status: 404
|
| 1568 |
+
2025-10-28 13:44:55,371 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/docs
|
| 1569 |
+
2025-10-28 13:44:55,372 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1570 |
+
2025-10-28 13:44:55,491 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/openapi.json
|
| 1571 |
+
2025-10-28 13:44:55,497 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1572 |
+
2025-10-28 13:45:19,086 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=Which%20influencer%20has%20got%20more%20audience%3F
|
| 1573 |
+
2025-10-28 13:45:52,641 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1574 |
+
2025-10-28 13:54:45,938 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=Which%20influencer%20has%20got%20more%20audience%3F
|
| 1575 |
+
2025-10-28 13:54:54,946 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1576 |
+
2025-10-28 14:04:53,103 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=Which%20influencer%20has%20got%20more%20audience%3F
|
| 1577 |
+
2025-10-28 14:05:07,615 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1578 |
+
2025-10-28 14:06:20,111 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=Which%20influencer%20has%20got%20more%20audience%3F
|
| 1579 |
+
2025-10-28 14:06:29,195 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1580 |
+
2025-10-28 14:11:15,115 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=Which%20influencer%20is%20good%20overall%3F
|
| 1581 |
+
2025-10-28 14:11:27,010 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1582 |
+
2025-10-28 14:15:32,566 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=I%20want%20to%20compare%20the%20analytics%20of%20muna%20and%20divya
|
| 1583 |
+
2025-10-28 15:04:15,698 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=I%20want%20to%20compare%20the%20analytics%20of%20muna%20and%20divya
|
| 1584 |
+
2025-10-28 15:04:29,863 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1585 |
+
2025-10-29 11:44:41,699 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/
|
| 1586 |
+
2025-10-29 11:44:41,700 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1587 |
+
2025-10-29 11:44:42,220 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/favicon.ico
|
| 1588 |
+
2025-10-29 11:44:42,221 | INFO | access_logger | app.py:20 | Response status: 404
|
| 1589 |
+
2025-10-29 11:44:44,605 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/docs
|
| 1590 |
+
2025-10-29 11:44:44,606 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1591 |
+
2025-10-29 11:44:44,718 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/openapi.json
|
| 1592 |
+
2025-10-29 11:44:44,726 | INFO | access_logger | app.py:20 | Response status: 200
|
| 1593 |
+
2025-10-29 11:46:57,249 | INFO | access_logger | app.py:18 | Request: GET http://127.0.0.1:8000/api/analytics-chatbot?msg=which%20influencer%20has%20the%20largest%20audeince%3F
|
src/genai/analytics_chatbot/agent.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
from langgraph.graph import StateGraph, START, END
|
| 2 |
from langgraph.checkpoint.memory import MemorySaver
|
| 3 |
from .utils.state import State
|
| 4 |
-
from .utils.nodes import FetchDataNode , FetchLastMessage , RetrievePossibleEndpoints , FetchParametersNode , RetrieveExactEndpoint, BackupRetrievalNode,
|
| 5 |
|
| 6 |
fetch_last_message_node = FetchLastMessage()
|
| 7 |
retrieve_api_endpoints_node = RetrievePossibleEndpoints()
|
|
@@ -9,6 +9,7 @@ retrieve_exact_endpoint_node = RetrieveExactEndpoint()
|
|
| 9 |
fetch_parameters_node = FetchParametersNode()
|
| 10 |
fetch_data_node = FetchDataNode()
|
| 11 |
backup_response_node = BackupRetrievalNode()
|
|
|
|
| 12 |
|
| 13 |
class ChatbotAgent:
|
| 14 |
def __init__(self):
|
|
@@ -19,19 +20,23 @@ class ChatbotAgent:
|
|
| 19 |
graph_builder.add_node("fetch_last_message", fetch_last_message_node.run)
|
| 20 |
graph_builder.add_node("retrieve_api_endpoints", retrieve_api_endpoints_node.run)
|
| 21 |
graph_builder.add_node("retrieve_exact_endpoint", retrieve_exact_endpoint_node.run)
|
|
|
|
|
|
|
| 22 |
graph_builder.add_node("fetch_parameters", fetch_parameters_node.run)
|
| 23 |
graph_builder.add_node("fetch_data", fetch_data_node.run)
|
| 24 |
graph_builder.add_node("backup_response", backup_response_node.run)
|
|
|
|
| 25 |
|
| 26 |
graph_builder.add_edge(START, "fetch_last_message")
|
| 27 |
graph_builder.add_edge("fetch_last_message", 'retrieve_api_endpoints')
|
| 28 |
graph_builder.add_edge("retrieve_api_endpoints", 'retrieve_exact_endpoint')
|
| 29 |
-
graph_builder.add_edge("retrieve_exact_endpoint", '
|
|
|
|
| 30 |
graph_builder.add_edge("fetch_parameters", 'fetch_data')
|
| 31 |
graph_builder.add_edge("fetch_data", END)
|
| 32 |
graph_builder.add_edge("backup_response", END)
|
| 33 |
|
| 34 |
-
graph_builder.add_conditional_edges("fetch_parameters",
|
| 35 |
-
graph_builder.add_conditional_edges("fetch_data",
|
| 36 |
|
| 37 |
return graph_builder.compile(checkpointer=self.memory)
|
|
|
|
| 1 |
from langgraph.graph import StateGraph, START, END
|
| 2 |
from langgraph.checkpoint.memory import MemorySaver
|
| 3 |
from .utils.state import State
|
| 4 |
+
from .utils.nodes import FetchDataNode , FetchLastMessage , RetrievePossibleEndpoints , FetchParametersNode , RetrieveExactEndpoint, BackupRetrievalNode, BackupRoutingNode, QueryCheckNode
|
| 5 |
|
| 6 |
fetch_last_message_node = FetchLastMessage()
|
| 7 |
retrieve_api_endpoints_node = RetrievePossibleEndpoints()
|
|
|
|
| 9 |
fetch_parameters_node = FetchParametersNode()
|
| 10 |
fetch_data_node = FetchDataNode()
|
| 11 |
backup_response_node = BackupRetrievalNode()
|
| 12 |
+
query_check_node = QueryCheckNode()
|
| 13 |
|
| 14 |
class ChatbotAgent:
|
| 15 |
def __init__(self):
|
|
|
|
| 20 |
graph_builder.add_node("fetch_last_message", fetch_last_message_node.run)
|
| 21 |
graph_builder.add_node("retrieve_api_endpoints", retrieve_api_endpoints_node.run)
|
| 22 |
graph_builder.add_node("retrieve_exact_endpoint", retrieve_exact_endpoint_node.run)
|
| 23 |
+
graph_builder.add_node("check_query_type", query_check_node.run)
|
| 24 |
+
|
| 25 |
graph_builder.add_node("fetch_parameters", fetch_parameters_node.run)
|
| 26 |
graph_builder.add_node("fetch_data", fetch_data_node.run)
|
| 27 |
graph_builder.add_node("backup_response", backup_response_node.run)
|
| 28 |
+
|
| 29 |
|
| 30 |
graph_builder.add_edge(START, "fetch_last_message")
|
| 31 |
graph_builder.add_edge("fetch_last_message", 'retrieve_api_endpoints')
|
| 32 |
graph_builder.add_edge("retrieve_api_endpoints", 'retrieve_exact_endpoint')
|
| 33 |
+
graph_builder.add_edge("retrieve_exact_endpoint", 'check_query_type')
|
| 34 |
+
graph_builder.add_edge("check_query_type", 'fetch_parameters')
|
| 35 |
graph_builder.add_edge("fetch_parameters", 'fetch_data')
|
| 36 |
graph_builder.add_edge("fetch_data", END)
|
| 37 |
graph_builder.add_edge("backup_response", END)
|
| 38 |
|
| 39 |
+
graph_builder.add_conditional_edges("fetch_parameters", BackupRoutingNode().run,{'execute_backup':'backup_response', 'go_on':"fetch_data"})
|
| 40 |
+
graph_builder.add_conditional_edges("fetch_data", BackupRoutingNode().run,{'execute_backup':'backup_response', 'go_on':END})
|
| 41 |
|
| 42 |
return graph_builder.compile(checkpointer=self.memory)
|
src/genai/analytics_chatbot/utils/nodes.py
CHANGED
|
@@ -3,7 +3,7 @@ from langchain_core.messages import SystemMessage , HumanMessage , FunctionMessa
|
|
| 3 |
from .state import State
|
| 4 |
from .tools import RetrieverBackup
|
| 5 |
from .schemas import ResponseFormatter , CompareBodyFormatter, ParameterFormatter, EndpointFormatter
|
| 6 |
-
from .prompts import
|
| 7 |
from .utils import generate_api_knowledge , process_query, get_endpoint_info
|
| 8 |
from src.genai.utils.models_loader import llm_gpt
|
| 9 |
import numpy as np
|
|
@@ -37,7 +37,7 @@ class RetrievePossibleEndpoints:
|
|
| 37 |
def run(self,state:State):
|
| 38 |
print('Gone to retrieve possible endpoints')
|
| 39 |
query_embedding = np.array(embedding_model.embed_query(state['latest_message'])).reshape(1, -1).astype('float32')
|
| 40 |
-
distances, indices = self.index.search(query_embedding,
|
| 41 |
for idx in indices[0]:
|
| 42 |
row = self.df.iloc[idx]
|
| 43 |
print('Endpoint:',row['endpoint'])
|
|
@@ -69,7 +69,24 @@ class RetrieveExactEndpoint:
|
|
| 69 |
"needed_parameters": endpoint_info["parameters"]
|
| 70 |
}
|
| 71 |
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
class FetchParametersNode:
|
| 74 |
def __init__(self):
|
| 75 |
self.llm = llm_gpt
|
|
@@ -78,25 +95,25 @@ class FetchParametersNode:
|
|
| 78 |
try:
|
| 79 |
print('Entered to fetch parameters')
|
| 80 |
print(state['method'])
|
| 81 |
-
|
| 82 |
-
|
| 83 |
template = fetch_parameters_prompt
|
| 84 |
-
messages=[SystemMessage(content=template),
|
| 85 |
-
HumanMessage(content=f'''The query is: {state['latest_message']}\n. The needed parameters: {str(state['needed_parameters'])}''')
|
| 86 |
-
]
|
| 87 |
print('messages:', messages)
|
| 88 |
result = self.llm.with_structured_output(ParameterFormatter, method='function_calling').invoke(messages)
|
| 89 |
-
# parameters_values={key: process_query(value) for key, value in result.parameters_values.items()}
|
| 90 |
parameters_values = {k: (process_query(v) if isinstance(v, str) else v) for k, v in result.parameters_values.items()}
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
| 100 |
except Exception as e:
|
| 101 |
print('Error occoured:', e)
|
| 102 |
return {'error_message': str(e)}
|
|
@@ -116,9 +133,8 @@ class FetchDataNode:
|
|
| 116 |
try:
|
| 117 |
print('Entered to fetch data')
|
| 118 |
url = f'''{self.base_url}{state['endpoint']}'''
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
elif state['endpoint'] == '/api/v1/compare/':
|
| 122 |
print('Condition satisfied')
|
| 123 |
messages = [SystemMessage(content=get_body_prompt()),
|
| 124 |
HumanMessage(content=str(state['messages']))]
|
|
@@ -136,8 +152,29 @@ class FetchDataNode:
|
|
| 136 |
}
|
| 137 |
|
| 138 |
response = requests.post(url, json=payload, headers=headers)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
|
| 140 |
-
return {'response':response.json()}
|
| 141 |
except Exception as e:
|
| 142 |
print('Error occoured:', e)
|
| 143 |
return {'error_message': str(e)}
|
|
@@ -151,7 +188,9 @@ class BackupRetrievalNode:
|
|
| 151 |
retrieval=RetrieverBackup().retrieve(state['latest_message'])
|
| 152 |
return {'backup_data': retrieval}
|
| 153 |
|
| 154 |
-
|
|
|
|
|
|
|
| 155 |
def __init__(self):
|
| 156 |
pass
|
| 157 |
|
|
|
|
| 3 |
from .state import State
|
| 4 |
from .tools import RetrieverBackup
|
| 5 |
from .schemas import ResponseFormatter , CompareBodyFormatter, ParameterFormatter, EndpointFormatter
|
| 6 |
+
from .prompts import query_check_prompt , get_body_prompt , fetch_last_message_prompt , fetch_parameters_prompt, fetch_endpoint_prompt, backup_retrieval_prompt
|
| 7 |
from .utils import generate_api_knowledge , process_query, get_endpoint_info
|
| 8 |
from src.genai.utils.models_loader import llm_gpt
|
| 9 |
import numpy as np
|
|
|
|
| 37 |
def run(self,state:State):
|
| 38 |
print('Gone to retrieve possible endpoints')
|
| 39 |
query_embedding = np.array(embedding_model.embed_query(state['latest_message'])).reshape(1, -1).astype('float32')
|
| 40 |
+
distances, indices = self.index.search(query_embedding, 5)
|
| 41 |
for idx in indices[0]:
|
| 42 |
row = self.df.iloc[idx]
|
| 43 |
print('Endpoint:',row['endpoint'])
|
|
|
|
| 69 |
"needed_parameters": endpoint_info["parameters"]
|
| 70 |
}
|
| 71 |
|
| 72 |
+
class QueryCheckNode:
|
| 73 |
+
def __init__(self):
|
| 74 |
+
self.llm = llm_gpt
|
| 75 |
+
|
| 76 |
+
def run(self, state:State):
|
| 77 |
+
try:
|
| 78 |
+
print('Entered to query checking')
|
| 79 |
+
messages = [SystemMessage(content=query_check_prompt),
|
| 80 |
+
HumanMessage(content=f'''The user query is: {state['latest_message']}''')]
|
| 81 |
+
result = self.llm.invoke(messages)
|
| 82 |
+
print(result.content)
|
| 83 |
+
return{'query_type': result.content}
|
| 84 |
+
|
| 85 |
+
except Exception as e:
|
| 86 |
+
print('Error occoured:', e)
|
| 87 |
+
return {'error_message': str(e)}
|
| 88 |
+
|
| 89 |
+
|
| 90 |
class FetchParametersNode:
|
| 91 |
def __init__(self):
|
| 92 |
self.llm = llm_gpt
|
|
|
|
| 95 |
try:
|
| 96 |
print('Entered to fetch parameters')
|
| 97 |
print(state['method'])
|
| 98 |
+
|
| 99 |
+
if state['method']=='GET':
|
| 100 |
template = fetch_parameters_prompt
|
| 101 |
+
messages=[SystemMessage(content=template),HumanMessage(content=f'''The query is: {state['latest_message']}\n. The needed parameters: {str(state['needed_parameters'])}''')]
|
|
|
|
|
|
|
| 102 |
print('messages:', messages)
|
| 103 |
result = self.llm.with_structured_output(ParameterFormatter, method='function_calling').invoke(messages)
|
|
|
|
| 104 |
parameters_values = {k: (process_query(v) if isinstance(v, str) else v) for k, v in result.parameters_values.items()}
|
| 105 |
+
|
| 106 |
+
if 'single_influencer_query' in state['query_type']:
|
| 107 |
+
print('The parameter values:', parameters_values)
|
| 108 |
+
return {
|
| 109 |
+
'parameters_values':parameters_values
|
| 110 |
+
}
|
| 111 |
+
elif 'aggregate_query' in state['query_type']:
|
| 112 |
+
parameters_values['influencer_username'] = ['divyadhakal_','munachiya','mydarlingfood','_its.me.muskan_']
|
| 113 |
+
print('The parameter values:', parameters_values)
|
| 114 |
+
return{
|
| 115 |
+
'parameters_values': parameters_values
|
| 116 |
+
}
|
| 117 |
except Exception as e:
|
| 118 |
print('Error occoured:', e)
|
| 119 |
return {'error_message': str(e)}
|
|
|
|
| 133 |
try:
|
| 134 |
print('Entered to fetch data')
|
| 135 |
url = f'''{self.base_url}{state['endpoint']}'''
|
| 136 |
+
|
| 137 |
+
if state['endpoint'] == '/api/v1/compare/':
|
|
|
|
| 138 |
print('Condition satisfied')
|
| 139 |
messages = [SystemMessage(content=get_body_prompt()),
|
| 140 |
HumanMessage(content=str(state['messages']))]
|
|
|
|
| 152 |
}
|
| 153 |
|
| 154 |
response = requests.post(url, json=payload, headers=headers)
|
| 155 |
+
return {'response': response.json()}
|
| 156 |
+
|
| 157 |
+
elif 'single_influencer_query' in state['query_type']:
|
| 158 |
+
response = requests.get(url, params=state['parameters_values'],headers=self.headers)
|
| 159 |
+
return {'response':response.json()}
|
| 160 |
+
|
| 161 |
+
elif 'aggregate_query' in state['query_type']:
|
| 162 |
+
print('Entered to aggregrated query execution')
|
| 163 |
+
print(state['parameters_values'])
|
| 164 |
+
params = state["parameters_values"]
|
| 165 |
+
if "influencer_username" in params and isinstance(params["influencer_username"], list):
|
| 166 |
+
results = {}
|
| 167 |
+
|
| 168 |
+
# Iterate through each influencer username
|
| 169 |
+
for username in params["influencer_username"]:
|
| 170 |
+
current_params = params.copy()
|
| 171 |
+
current_params["influencer_username"] = username
|
| 172 |
+
|
| 173 |
+
response = requests.get(url, params=current_params, headers=self.headers)
|
| 174 |
+
results[username] = response.json() # Store influencer-wise response
|
| 175 |
+
|
| 176 |
+
return {"response": results}
|
| 177 |
|
|
|
|
| 178 |
except Exception as e:
|
| 179 |
print('Error occoured:', e)
|
| 180 |
return {'error_message': str(e)}
|
|
|
|
| 188 |
retrieval=RetrieverBackup().retrieve(state['latest_message'])
|
| 189 |
return {'backup_data': retrieval}
|
| 190 |
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
class BackupRoutingNode:
|
| 194 |
def __init__(self):
|
| 195 |
pass
|
| 196 |
|
src/genai/analytics_chatbot/utils/prompts.py
CHANGED
|
@@ -54,15 +54,16 @@ Return the result strictly in this JSON format:
|
|
| 54 |
"names": ["<influencer_1>", "<influencer_2>", ...],
|
| 55 |
"frequency": "<frequency_value>"
|
| 56 |
}
|
|
|
|
| 57 |
|
| 58 |
Example:
|
| 59 |
-
If the query is :"I want to compare the analytics of divyadhakal_ and munachiya in
|
| 60 |
-
|
| 61 |
-
Then the expected output is:
|
| 62 |
{
|
| 63 |
"names": ["divyadhakal_", "munachiya"],
|
| 64 |
-
"frequency": "
|
| 65 |
}
|
|
|
|
| 66 |
'''
|
| 67 |
|
| 68 |
fetch_last_message_prompt = '''
|
|
@@ -110,4 +111,14 @@ endpoint: /api/v1/analytics/engagement
|
|
| 110 |
backup_retrieval_prompt = '''
|
| 111 |
You are provided with the retrieved data as a function message and the user query.
|
| 112 |
Respond to the user query only through the context of retrieved data. Don't give hallucinated responses.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
'''
|
|
|
|
| 54 |
"names": ["<influencer_1>", "<influencer_2>", ...],
|
| 55 |
"frequency": "<frequency_value>"
|
| 56 |
}
|
| 57 |
+
If the frequency is not provided to you, use 'weekly' as default.
|
| 58 |
|
| 59 |
Example:
|
| 60 |
+
If the query is :"I want to compare the analytics of divyadhakal_ and munachiya in monthly basis", then
|
| 61 |
+
output:
|
|
|
|
| 62 |
{
|
| 63 |
"names": ["divyadhakal_", "munachiya"],
|
| 64 |
+
"frequency": "monthly"
|
| 65 |
}
|
| 66 |
+
|
| 67 |
'''
|
| 68 |
|
| 69 |
fetch_last_message_prompt = '''
|
|
|
|
| 111 |
backup_retrieval_prompt = '''
|
| 112 |
You are provided with the retrieved data as a function message and the user query.
|
| 113 |
Respond to the user query only through the context of retrieved data. Don't give hallucinated responses.
|
| 114 |
+
'''
|
| 115 |
+
|
| 116 |
+
query_check_prompt = '''
|
| 117 |
+
You are an intent classification assistant.
|
| 118 |
+
Given a user query about influencer analytics, classify it as one of the following types:
|
| 119 |
+
|
| 120 |
+
1. single_influencer_query — if the query refers to one specific influencer (e.g., "Show Muna's engagement rate"). Simply if the query includes the name of influencer.
|
| 121 |
+
2. aggregate_query — if the query involves comparing multiple influencers, rankings, or overall statistics (e.g., "Who has the highest engagement?").
|
| 122 |
+
|
| 123 |
+
Return only one label: "single_influencer_query" or "aggregate_query".
|
| 124 |
'''
|
src/genai/analytics_chatbot/utils/state.py
CHANGED
|
@@ -12,4 +12,5 @@ class State(TypedDict):
|
|
| 12 |
error_message:str
|
| 13 |
latest_message:str
|
| 14 |
parameters_values:str
|
| 15 |
-
backup_data:str
|
|
|
|
|
|
| 12 |
error_message:str
|
| 13 |
latest_message:str
|
| 14 |
parameters_values:str
|
| 15 |
+
backup_data:str
|
| 16 |
+
query_type: str
|
src/genai/analytics_chatbot/utils/tools.py
CHANGED
|
@@ -35,34 +35,6 @@ class RetrieverBackup:
|
|
| 35 |
else:
|
| 36 |
return self.df
|
| 37 |
|
| 38 |
-
|
| 39 |
-
def retrieve_old(self, query):
|
| 40 |
-
query_embedding = np.array(embedding_model.embed_query(str(query))).reshape(1, -1).astype('float32')
|
| 41 |
-
print('Embeddings Generated')
|
| 42 |
-
faiss.normalize_L2(query_embedding)
|
| 43 |
-
print('Query embedded')
|
| 44 |
-
filtered_df = self._filter_dataset(query)
|
| 45 |
-
distances, indices = self.index.search(query_embedding, len(filtered_df))
|
| 46 |
-
similarity_threshold = 0.35
|
| 47 |
-
selected = [(idx, sim) for idx, sim in zip(indices[0], distances[0]) if sim >= similarity_threshold]
|
| 48 |
-
if not selected:
|
| 49 |
-
return "No influencers found."
|
| 50 |
-
|
| 51 |
-
outer_list = []
|
| 52 |
-
for rank, (idx, sim) in enumerate(selected, 1):
|
| 53 |
-
row = filtered_df.iloc[idx]
|
| 54 |
-
inner_list = [
|
| 55 |
-
f"[{rank}]. The influencer name is: **{row['username']}** — Likes: **{row['likesCount']}**, Comments: **{row['commentCount']}**",
|
| 56 |
-
f"The branding or promotion done is:\n{row['visible_texts_or_brandings']}",
|
| 57 |
-
f"The details of product or service is:\n{row['product_or_service_details']}"
|
| 58 |
-
]
|
| 59 |
-
outer_list.append(inner_list)
|
| 60 |
-
|
| 61 |
-
cleaned_response = clean_text(str(outer_list))
|
| 62 |
-
print('response cleaned')
|
| 63 |
-
tokens = encoding_model.encode(cleaned_response)[:500]
|
| 64 |
-
print('tokens got')
|
| 65 |
-
return encoding_model.decode(tokens)
|
| 66 |
|
| 67 |
def retrieve(self, query):
|
| 68 |
query_embedding = np.array(embedding_model.embed_query(str(query))).reshape(1, -1).astype('float32')
|
|
@@ -70,7 +42,7 @@ class RetrieverBackup:
|
|
| 70 |
|
| 71 |
# Search on full dataset (index is built on full df)
|
| 72 |
distances, indices = self.index.search(query_embedding, len(self.df))
|
| 73 |
-
similarity_threshold = 0.
|
| 74 |
|
| 75 |
# Prepare matched usernames
|
| 76 |
usernames = self.df["username"].dropna().unique()
|
|
|
|
| 35 |
else:
|
| 36 |
return self.df
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
def retrieve(self, query):
|
| 40 |
query_embedding = np.array(embedding_model.embed_query(str(query))).reshape(1, -1).astype('float32')
|
|
|
|
| 42 |
|
| 43 |
# Search on full dataset (index is built on full df)
|
| 44 |
distances, indices = self.index.search(query_embedding, len(self.df))
|
| 45 |
+
similarity_threshold = 0.1
|
| 46 |
|
| 47 |
# Prepare matched usernames
|
| 48 |
usernames = self.df["username"].dropna().unique()
|
src/genai/analytics_chatbot/utils/utils.py
CHANGED
|
@@ -103,3 +103,6 @@ def process_query(user_query: str) -> str:
|
|
| 103 |
|
| 104 |
|
| 105 |
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
|
| 105 |
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
|
src/genai/utils/models_loader.py
CHANGED
|
@@ -24,6 +24,7 @@ llm_gpt_small = ChatOpenAI(model="gpt-3.5-turbo",temperature=0.3)
|
|
| 24 |
llm_gpt = ChatOpenAI(model="gpt-3.5-turbo",temperature=0.3)
|
| 25 |
llm_gpt_high = ChatOpenAI(model="gpt-5-nano",temperature=0.5)
|
| 26 |
encoding_model = tiktoken.encoding_for_model('gpt-4o-mini')
|
|
|
|
| 27 |
|
| 28 |
|
| 29 |
captioning_model = "meta-llama/llama-4-scout-17b-16e-instruct"
|
|
|
|
| 24 |
llm_gpt = ChatOpenAI(model="gpt-3.5-turbo",temperature=0.3)
|
| 25 |
llm_gpt_high = ChatOpenAI(model="gpt-5-nano",temperature=0.5)
|
| 26 |
encoding_model = tiktoken.encoding_for_model('gpt-4o-mini')
|
| 27 |
+
# encoding_model = 'encoding_model'
|
| 28 |
|
| 29 |
|
| 30 |
captioning_model = "meta-llama/llama-4-scout-17b-16e-instruct"
|