Skip to content
Merged
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ venv/
.mypy_cache/
.vscode/
.venv
.DS_Store

# docs
documents.txt
credentials.json

# virtualenv
.venv
Expand Down
2 changes: 1 addition & 1 deletion backend/src/agents/retriever_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def route(self, state: AgentState) -> list[str]:
return ["retrieve_general"]

if self.inbuit_tool_calling:
tool_names = [tool["name"] for tool in tools if "name" in tool] # type: ignore
tool_names = [tool["name"] for tool in tools if "name" in tool] # type: ignore
return tool_names
else:
return tools
Expand Down
1 change: 0 additions & 1 deletion backend/src/api/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from fastapi import FastAPI

from .routers import graphs, healthcheck

app = FastAPI()
Expand Down
1 change: 1 addition & 0 deletions common/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MONGO_DB_URI = YOUR_MONGO_DB_URI
151 changes: 151 additions & 0 deletions common/mongoClient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
from pymongo import MongoClient
from pymongo.database import Database
from dotenv import load_dotenv
import os

load_dotenv()

# HARDCODED collection names
feedback_collection_name = "feedback"
context_collection_name = "context"

def get_mongo_db_client() -> Database:
"""
Get the MongoDB client.

Returns:
- DatabaseClient: The Database client.

Note:
MongoDB doesn't create a collection or a database until it gets content, so no need to check if the data already exists or not.
"""

uri = os.getenv("MONGO_DB_URI")
client = MongoClient(uri)
# this is the database that is returned by the client
return client["feedback_db"]

def submit_feedback():
"""
Submit feedback Record to the MongoDB database.

Args:
- question (str): The question for which feedback is being submitted.
- answer (str): The generated answer to the question.
- sources (list[str]): Source data used for the answer.
- context (list[str]): Additional context from the RAG.
- issue (str): Details about the issue.
- version (str): Version information.

Returns:
- None
"""

feedback_db_client = get_mongo_client()

try:
if not check_collection_exists(feedback_collection_name,feedback_db_client,):
create_collection(feedback_collection_name,feedback_db_client, validator={
'$jsonSchema': {
'bsonType': 'object',
'required': ['question', 'answer', 'sources', 'context_ids', 'issue', 'version', 'timestamp'],
'properties': {
'question': {
'bsonType': 'string',
'description': 'must be a string and is required'
},
'answer': {
'bsonType': 'string',
'description': 'must be a string and is required'
},
'sources': {
'bsonType': 'array',
'items': {
'bsonType': 'objectId'
},
'description': 'must be an array of ObjectIds referencing the sources and is required'
},
'context': {
'bsonType': 'array',
'items': {
'bsonType': 'string'
},
'description': 'must be an array of strings and is required'
},
'issue': {
'bsonType': 'string',
'description': 'must be a string and is required'
},
'version': {
'bsonType': 'string',
'description': 'must be a string and is required'
},
'timestamp': {
'bsonType': 'date',
'description': 'must be a date and is required'
},
'status': {
'enum': ['new', 'processing', 'resolved'],
'description': 'can only be one of the enum values'
}
}
}
})
if not check_collection_exists(context_collection_name,feedback_db_client):
create_collection(context_collection_name,feedback_db_client,{
'bsonType': 'object',
'required': ['source', 'timestamp'],
'properties': {
'source': {
'bsonType': 'string',
'description': 'must be a string and is required'
},
'metadata': {
'bsonType': 'object',
'description': 'additional metadata for the context'
},
'timestamp': {
'bsonType': 'date',
'description': 'must be a date and is required'
}
}
}
)

except Exception as e:
print(f"Failed to submit feedback: {e}")
return None

def check_collection_exists(collection_name:str,client_database:Database)->bool:
"""
Check if the collection exists in the database.

Args:
- collection_name (str): The name of the collection to check.
- client_database (Database): The database to check.

Returns:
- None
"""
return collection_name in client_database.list_collection_names()

def create_collection(collection_name:str,client_database:Database,validator:object)->None:
"""
Create a collection in the database.

Args:
- collection_name (str): The name of the collection to create.
- client_database (Database): The database to create the collection in.

Returns:
- None
"""
try:
client_database.create_collection(collection_name,validator=validator)
print("Collection created successfully")
except Exception as e:
print(f"Failed to create collection: {e}")
return None

if __name__ == "__main__":
submit_feedback()
2 changes: 2 additions & 0 deletions common/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pymongo==4.6.2
python-dotenv==1.0.1
14 changes: 10 additions & 4 deletions frontend/utils/feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def submit_feedback_to_google_sheet(
]

creds = Credentials.from_service_account_file(service_account_file, scopes=scope)
# this is the place where the client is coming from, need to change this for mongoDB client
client = gspread.authorize(creds)

sheet_id = os.getenv("FEEDBACK_SHEET_ID", "")
Expand Down Expand Up @@ -170,8 +171,13 @@ def show_feedback_form(
feedback = st.sidebar.text_area("Please provide your feedback or report an issue:")

if selected_question:
sources = [metadata[selected_question].get("sources", "N/A")]
context = [metadata[selected_question].get("context", "N/A")]
sources = metadata[selected_question].get("sources", ["N/A"])
if isinstance(sources, str):
sources = [sources]

context = metadata[selected_question].get("context", ["N/A"])
if isinstance(context, str):
context = [context]

if st.sidebar.button("Submit"):
selected_index = questions[selected_question]
Expand All @@ -180,8 +186,8 @@ def show_feedback_form(
submit_feedback_to_google_sheet(
question=selected_question,
answer=gen_ans,
sources=sources,
context=context,
sources=sources, # Now passing as list
context=context, # Now passing as list
issue=feedback,
version=os.getenv("RAG_VERSION", get_git_commit_hash()),
)
Expand Down