From 04a733637597475adf3cd59c5c29892f0b6746e7 Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 17:40:29 -0500 Subject: [PATCH 01/11] (chore) added .DS_Store to .gitignore Signed-off-by: Kannav02 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 14a3dc29..5c322055 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ venv/ .mypy_cache/ .vscode/ .venv +.DS_Store # docs documents.txt From 49533246694656171a82ffad4cca93a22a7191aa Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 17:52:17 -0500 Subject: [PATCH 02/11] changes made for my refernce Signed-off-by: Kannav02 --- backend/src/api/main.py | 4 ++-- frontend/streamlit_app.py | 2 ++ frontend/utils/feedback.py | 15 +++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/backend/src/api/main.py b/backend/src/api/main.py index 976660ae..67b7bace 100644 --- a/backend/src/api/main.py +++ b/backend/src/api/main.py @@ -1,8 +1,8 @@ from fastapi import FastAPI - -from .routers import graphs, healthcheck +from .routers import graphs, healthcheck,chains app = FastAPI() app.include_router(healthcheck.router) app.include_router(graphs.router) +app.include_router(chains.router) diff --git a/frontend/streamlit_app.py b/frontend/streamlit_app.py index df9911a8..212b1ef9 100644 --- a/frontend/streamlit_app.py +++ b/frontend/streamlit_app.py @@ -217,11 +217,13 @@ def update_state() -> None: or st.session_state.feedback_button ): try: + print("I am above feeedback form") show_feedback_form( question_dict, st.session_state.metadata, st.session_state.chat_history, ) + except Exception as e: st.error(f"Failed to load feedback form: {e}") diff --git a/frontend/utils/feedback.py b/frontend/utils/feedback.py index 56e786e6..c3721437 100644 --- a/frontend/utils/feedback.py +++ b/frontend/utils/feedback.py @@ -170,8 +170,15 @@ 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] @@ -180,8 +187,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()), ) From b7039e82e996f1655c3df11cbbd5a028ca0ac109 Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 18:29:32 -0500 Subject: [PATCH 03/11] (chore) added requirements.txt file for common folder Signed-off-by: Kannav02 --- common/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 common/requirements.txt diff --git a/common/requirements.txt b/common/requirements.txt new file mode 100644 index 00000000..6bebc3e1 --- /dev/null +++ b/common/requirements.txt @@ -0,0 +1,2 @@ +pymongo==4.6.2 +python-dotenv==1.0.1 From 285c7ac997395917260ca9d297a5e1082fd32b67 Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 18:32:24 -0500 Subject: [PATCH 04/11] (feat): added the .env.example file for mongoDB Signed-off-by: Kannav02 --- common/.env.example | 1 + 1 file changed, 1 insertion(+) create mode 100644 common/.env.example diff --git a/common/.env.example b/common/.env.example new file mode 100644 index 00000000..84c52bf4 --- /dev/null +++ b/common/.env.example @@ -0,0 +1 @@ +MONGO_DB_URI = YOUR_MONGO_DB_URI \ No newline at end of file From 009c106fa6cd84c084c073cb75d8768c312df08f Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 19:25:28 -0500 Subject: [PATCH 05/11] (feat) added the basic mongoDB functions to run Signed-off-by: Kannav02 --- common/mongoClient.py | 86 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 common/mongoClient.py diff --git a/common/mongoClient.py b/common/mongoClient.py new file mode 100644 index 00000000..0e852ef0 --- /dev/null +++ b/common/mongoClient.py @@ -0,0 +1,86 @@ +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_client() -> Database: + """ + Get the MongoDB client. + + Returns: + - MongoClient: The MongoDB 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_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) + if not check_collection_exists(context_collection_name,feedback_db_client): + create_collection(context_collection_name,feedback_db_client) + + 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)->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) + print("Collection created successfully") + except Exception as e: + print(f"Failed to create collection: {e}") + return None \ No newline at end of file From 00ea85dc9ff70b3856638ec39035f9894c67c0c6 Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 21:17:34 -0500 Subject: [PATCH 06/11] (feat) design for mongoDB schemas made and added Signed-off-by: Kannav02 --- common/mongoClient.py | 81 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/common/mongoClient.py b/common/mongoClient.py index 0e852ef0..d9cd8731 100644 --- a/common/mongoClient.py +++ b/common/mongoClient.py @@ -9,6 +9,8 @@ feedback_collection_name = "feedback" context_collection_name = "context" +print(os.getenv("MONGO_DB_URI")) + def get_mongo_client() -> Database: """ @@ -21,7 +23,7 @@ def get_mongo_client() -> Database: 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_URI") + uri = os.getenv("MONGO_DB_URI") client = MongoClient(uri) # this is the database that is returned by the client return client["feedback_db"] @@ -45,10 +47,73 @@ def submit_feedback(): 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) + 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) + 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}") @@ -67,7 +132,7 @@ def check_collection_exists(collection_name:str,client_database:Database)->bool: """ return collection_name in client_database.list_collection_names() -def create_collection(collection_name:str,client_database:Database)->None: +def create_collection(collection_name:str,client_database:Database,validator:object)->None: """ Create a collection in the database. @@ -79,8 +144,10 @@ def create_collection(collection_name:str,client_database:Database)->None: - None """ try: - client_database.create_collection(collection_name) + 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 \ No newline at end of file + return None + +submit_feedback() \ No newline at end of file From 982799628eff4c9d69217808e4e5c1e2ac4dba3e Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 21:25:02 -0500 Subject: [PATCH 07/11] added a comment Signed-off-by: Kannav02 --- frontend/utils/feedback.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/utils/feedback.py b/frontend/utils/feedback.py index c3721437..6296adb3 100644 --- a/frontend/utils/feedback.py +++ b/frontend/utils/feedback.py @@ -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", "") From 7dc2b8cccf70851927e5c03a0913295f0b5606a1 Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Mon, 18 Nov 2024 21:39:15 -0500 Subject: [PATCH 08/11] (chore) removed debug statements and added credentials.json to gitignore Signed-off-by: Kannav02 --- .gitignore | 1 + backend/src/api/main.py | 3 +-- frontend/streamlit_app.py | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 5c322055..9dbfefc0 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ venv/ # docs documents.txt +credentials.json # virtualenv .venv diff --git a/backend/src/api/main.py b/backend/src/api/main.py index 67b7bace..8fedc3c6 100644 --- a/backend/src/api/main.py +++ b/backend/src/api/main.py @@ -1,8 +1,7 @@ from fastapi import FastAPI -from .routers import graphs, healthcheck,chains +from .routers import graphs, healthcheck app = FastAPI() app.include_router(healthcheck.router) app.include_router(graphs.router) -app.include_router(chains.router) diff --git a/frontend/streamlit_app.py b/frontend/streamlit_app.py index 212b1ef9..d5995188 100644 --- a/frontend/streamlit_app.py +++ b/frontend/streamlit_app.py @@ -217,13 +217,11 @@ def update_state() -> None: or st.session_state.feedback_button ): try: - print("I am above feeedback form") show_feedback_form( question_dict, st.session_state.metadata, st.session_state.chat_history, - ) - + ) except Exception as e: st.error(f"Failed to load feedback form: {e}") From 09828d763606a2ed212568b78a1c195b79fa39d1 Mon Sep 17 00:00:00 2001 From: Kannav02 Date: Tue, 19 Nov 2024 16:50:28 -0500 Subject: [PATCH 09/11] (fix): fixed inconsistenicies in the code and removed debug statements Signed-off-by: Kannav02 --- common/mongoClient.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/common/mongoClient.py b/common/mongoClient.py index d9cd8731..d009b68b 100644 --- a/common/mongoClient.py +++ b/common/mongoClient.py @@ -9,15 +9,12 @@ feedback_collection_name = "feedback" context_collection_name = "context" -print(os.getenv("MONGO_DB_URI")) - - -def get_mongo_client() -> Database: +def get_mongo_db_client() -> Database: """ Get the MongoDB client. Returns: - - MongoClient: The MongoDB client. + - 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. @@ -149,5 +146,6 @@ def create_collection(collection_name:str,client_database:Database,validator:obj except Exception as e: print(f"Failed to create collection: {e}") return None - -submit_feedback() \ No newline at end of file + +if __name__ == "__main__": + submit_feedback() From f0194b74ffe82737cf95d388d3798ab4d8e5be7e Mon Sep 17 00:00:00 2001 From: Song Luar Date: Wed, 20 Nov 2024 20:23:15 +0800 Subject: [PATCH 10/11] Update frontend/streamlit_app.py Signed-off-by: Song Luar Signed-off-by: Jack Luar --- frontend/streamlit_app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/streamlit_app.py b/frontend/streamlit_app.py index d5995188..df9911a8 100644 --- a/frontend/streamlit_app.py +++ b/frontend/streamlit_app.py @@ -221,7 +221,7 @@ def update_state() -> None: question_dict, st.session_state.metadata, st.session_state.chat_history, - ) + ) except Exception as e: st.error(f"Failed to load feedback form: {e}") From caad6769ec829417abcadd2f17df5cfb517c8051 Mon Sep 17 00:00:00 2001 From: Jack Luar Date: Wed, 20 Nov 2024 15:33:50 +0000 Subject: [PATCH 11/11] fix checks Signed-off-by: Jack Luar --- backend/src/agents/retriever_graph.py | 2 +- frontend/utils/feedback.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/src/agents/retriever_graph.py b/backend/src/agents/retriever_graph.py index d90f7c77..ddac3a12 100644 --- a/backend/src/agents/retriever_graph.py +++ b/backend/src/agents/retriever_graph.py @@ -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 diff --git a/frontend/utils/feedback.py b/frontend/utils/feedback.py index 6296adb3..9c87ecf3 100644 --- a/frontend/utils/feedback.py +++ b/frontend/utils/feedback.py @@ -173,12 +173,10 @@ def show_feedback_form( if selected_question: 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"):