vip11017 commited on
Commit
b9b1114
·
1 Parent(s): f84dd58

updated production code and addedx mongodb functions

Browse files
app/chatbot/prod_rag.py CHANGED
@@ -236,7 +236,7 @@ async def get_response(query, session_id, name, email, rag_config, config) -> di
236
 
237
  print(f"Response: {result['response']}")
238
 
239
- log_chat(
240
  session_id=session_id,
241
  company_id=rag_config.get('company_id'),
242
  chatbot_id=rag_config.get('chatbot_id'),
@@ -246,6 +246,6 @@ async def get_response(query, session_id, name, email, rag_config, config) -> di
246
  answer=result.get("response", ""),
247
  latency_ms= latency_ms,
248
  metadata=metadata
249
- )
250
 
251
  return result
 
236
 
237
  print(f"Response: {result['response']}")
238
 
239
+ """log_chat(
240
  session_id=session_id,
241
  company_id=rag_config.get('company_id'),
242
  chatbot_id=rag_config.get('chatbot_id'),
 
246
  answer=result.get("response", ""),
247
  latency_ms= latency_ms,
248
  metadata=metadata
249
+ )"""
250
 
251
  return result
app/chatbot/prod_route.py CHANGED
@@ -1,7 +1,9 @@
1
  from fastapi import APIRouter, HTTPException
2
  from pydantic import BaseModel
3
  from app.chatbot.demo_rag import get_response
4
- from app.config import demo_chatbot_configs
 
 
5
 
6
  router = APIRouter()
7
  chatbot_sessions = {} # chatbot_id -> loaded config/session
@@ -12,19 +14,26 @@ class ChatInput(BaseModel):
12
  name: str
13
  email: str
14
 
 
 
 
 
 
 
 
 
15
 
16
  @router.post("/prod/{chatbot_id}")
17
  async def prod_chat(chatbot_id: str, input: ChatInput):
18
  # Lazy-load chatbot config
19
  print(f"got question: {input.question} for chatbot_id: {chatbot_id} and session_id: {input.session_id}")
20
  if chatbot_id not in chatbot_sessions:
21
- rag_config = demo_chatbot_configs.find_one({"chatbot_id": chatbot_id})
22
  if not rag_config:
23
  raise HTTPException(status_code=404, detail="Chatbot not found")
24
  chatbot_sessions[chatbot_id] = rag_config
25
 
26
  rag_config = chatbot_sessions[chatbot_id]
27
- print(rag_config)
28
 
29
  config = {
30
  'configurable': {
@@ -41,3 +50,43 @@ async def prod_chat(chatbot_id: str, input: ChatInput):
41
  config=config
42
  )
43
  return {"answer": response['response']}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from fastapi import APIRouter, HTTPException
2
  from pydantic import BaseModel
3
  from app.chatbot.demo_rag import get_response
4
+ from app.config import prod_chatbot_configs
5
+ from app.chatbot.prod_rag import session_histories, HumanMessage, AIMessage, log_chat
6
+
7
 
8
  router = APIRouter()
9
  chatbot_sessions = {} # chatbot_id -> loaded config/session
 
14
  name: str
15
  email: str
16
 
17
+ #FAQ logging endpoint
18
+ class FAQInput(BaseModel):
19
+ session_id: str
20
+ question: str
21
+ answer: str
22
+ name: str
23
+ email: str
24
+
25
 
26
  @router.post("/prod/{chatbot_id}")
27
  async def prod_chat(chatbot_id: str, input: ChatInput):
28
  # Lazy-load chatbot config
29
  print(f"got question: {input.question} for chatbot_id: {chatbot_id} and session_id: {input.session_id}")
30
  if chatbot_id not in chatbot_sessions:
31
+ rag_config = prod_chatbot_configs.find_one({"chatbot_id": chatbot_id})
32
  if not rag_config:
33
  raise HTTPException(status_code=404, detail="Chatbot not found")
34
  chatbot_sessions[chatbot_id] = rag_config
35
 
36
  rag_config = chatbot_sessions[chatbot_id]
 
37
 
38
  config = {
39
  'configurable': {
 
50
  config=config
51
  )
52
  return {"answer": response['response']}
53
+
54
+ #Log FAQ in conversation History even though RAG not being called so future RAG calls have access to info
55
+ @router.post("/faq/{chatbot_id}")
56
+ async def log_faq(chatbot_id: str, faq: FAQInput):
57
+ print(f'{chatbot_id}')
58
+ session_id = faq.session_id
59
+ question = faq.question
60
+ answer = faq.answer
61
+ name = faq.name
62
+ email = faq.email
63
+
64
+ # Load RAG config
65
+ if chatbot_id not in chatbot_sessions:
66
+ rag_config = prod_chatbot_configs.find_one({"chatbot_id": chatbot_id})
67
+ if not rag_config:
68
+ raise HTTPException(status_code=404, detail="Chatbot not found")
69
+ chatbot_sessions[chatbot_id] = rag_config
70
+ rag_config = chatbot_sessions[chatbot_id]
71
+
72
+ # Ensure session exists
73
+ if session_id not in session_histories:
74
+ session_histories[session_id] = []
75
+
76
+ # Append FAQ to session history
77
+ session_histories[session_id].append(HumanMessage(content=question))
78
+ session_histories[session_id].append(AIMessage(content=answer))
79
+
80
+ # Log to DB
81
+ log_chat(
82
+ session_id=session_id,
83
+ company_id=rag_config.get('company_id'),
84
+ chatbot_id=rag_config.get('chatbot_id'),
85
+ name=name,
86
+ email=email,
87
+ query=question,
88
+ answer=answer,
89
+ metadata={"source": "FAQ"}
90
+ )
91
+
92
+ return {"status": "success"}
app/config.py CHANGED
@@ -29,11 +29,17 @@ try:
29
  print("Pinged your deployment. You successfully connected to MongoDB!")
30
 
31
  demo_database = client["Demo"]
 
 
 
32
  demo_form_submissions = demo_database["demo_form_submissions"]
33
  demo_chatbot_configs = demo_database["demo_chatbot_config"]
34
 
 
 
35
  admin_database = client["AdminLogs"]
36
- chat_logs = admin_database["ChatLogs"]
 
37
  print("Connected to MongoDB collection successfully!")
38
  except Exception as e:
39
  print(e)
 
29
  print("Pinged your deployment. You successfully connected to MongoDB!")
30
 
31
  demo_database = client["Demo"]
32
+ chatbot_database = client['Chatbot']
33
+ logs_databse = client["Logs"]
34
+
35
  demo_form_submissions = demo_database["demo_form_submissions"]
36
  demo_chatbot_configs = demo_database["demo_chatbot_config"]
37
 
38
+ prod_chatbot_configs = chatbot_database['rag_configs']
39
+
40
  admin_database = client["AdminLogs"]
41
+ chat_logs = logs_databse["ChatLogs"]
42
+
43
  print("Connected to MongoDB collection successfully!")
44
  except Exception as e:
45
  print(e)
app/main.py CHANGED
@@ -2,6 +2,7 @@ from fastapi import FastAPI
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from app.ingestion.routes import router as ingestion_router
4
  from app.chatbot.demo_routes import router as demo_router
 
5
 
6
  app = FastAPI(
7
  title="Chatbot Platform - Demo Ingestion",
@@ -22,4 +23,5 @@ app.add_middleware(
22
  )
23
 
24
  app.include_router(ingestion_router, prefix="/ingestion", tags=["ingestion"])
25
- app.include_router(demo_router, prefix="/chatbot", tags=["demochatbot"])
 
 
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from app.ingestion.routes import router as ingestion_router
4
  from app.chatbot.demo_routes import router as demo_router
5
+ from app.chatbot.prod_route import router as prod_router
6
 
7
  app = FastAPI(
8
  title="Chatbot Platform - Demo Ingestion",
 
23
  )
24
 
25
  app.include_router(ingestion_router, prefix="/ingestion", tags=["ingestion"])
26
+ app.include_router(demo_router, prefix="/chatbot", tags=["demochatbot"])
27
+ app.include_router(prod_router, prefix="/prodchatbot", tags=['production'])
app/mongodb_functions.ipynb ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "id": "a8200051",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "name": "stdout",
11
+ "output_type": "stream",
12
+ "text": [
13
+ "Pinged your deployment. You successfully connected to MongoDB!\n",
14
+ "Connected to MongoDB collection successfully!\n"
15
+ ]
16
+ }
17
+ ],
18
+ "source": [
19
+ "from config import demo_chatbot_configs, prod_chatbot_configs"
20
+ ]
21
+ },
22
+ {
23
+ "cell_type": "code",
24
+ "execution_count": 2,
25
+ "id": "a8c62f9e",
26
+ "metadata": {},
27
+ "outputs": [],
28
+ "source": [
29
+ "def get_demo_config(submission_id):\n",
30
+ " return demo_chatbot_configs.find_one({\"submission_id\": submission_id})\n",
31
+ "\n",
32
+ "def get_prod_config(chatbot_id):\n",
33
+ " return prod_chatbot_configs.find_one({\"chatbot_id\": chatbot_id})"
34
+ ]
35
+ },
36
+ {
37
+ "cell_type": "code",
38
+ "execution_count": null,
39
+ "id": "6392c44a",
40
+ "metadata": {},
41
+ "outputs": [],
42
+ "source": [
43
+ "def convert_demo_to_prod(demo_config, new_chatbot_id=None, prompt=None):\n",
44
+ " \"\"\"\n",
45
+ " Convert a demo chatbot config to a production RAG config.\n",
46
+ " \"\"\"\n",
47
+ " prod_config = {\n",
48
+ " \"chatbot_id\": new_chatbot_id or demo_config[\"chatbot_id\"],\n",
49
+ " \"company_id\": demo_config[\"company_id\"],\n",
50
+ " \"company_name\": demo_config[\"company_name\"],\n",
51
+ " \"prompt_template\": prompt or demo_config[\"prompt_template\"],\n",
52
+ " \"retrievers\": demo_config.get(\"retrievers\", [])\n",
53
+ " }\n",
54
+ " return prod_config\n"
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "code",
59
+ "execution_count": null,
60
+ "id": "2ac76531",
61
+ "metadata": {},
62
+ "outputs": [],
63
+ "source": [
64
+ "def update_prod_prompt(chatbot_id, new_prompt):\n",
65
+ " prod_chatbot_configs.update_one(\n",
66
+ " {\"chatbot_id\": chatbot_id},\n",
67
+ " {\"$set\": {\"prompt_template\": new_prompt}}\n",
68
+ " )\n",
69
+ "\n",
70
+ "def update_prod_retrievers(chatbot_id, new_retrievers):\n",
71
+ " prod_chatbot_configs.update_one(\n",
72
+ " {\"chatbot_id\": chatbot_id},\n",
73
+ " {\"$set\": {\"retrievers\": new_retrievers}}\n",
74
+ " )"
75
+ ]
76
+ },
77
+ {
78
+ "cell_type": "code",
79
+ "execution_count": null,
80
+ "id": "fbd14ade",
81
+ "metadata": {},
82
+ "outputs": [],
83
+ "source": [
84
+ "def override_demo_prompt(submission_id, new_prompt):\n",
85
+ " demo_chatbot_configs.update_one(\n",
86
+ " {\"submission_id\": submission_id},\n",
87
+ " {\"$set\": {\"prompt_template\": new_prompt}}\n",
88
+ " )"
89
+ ]
90
+ },
91
+ {
92
+ "cell_type": "code",
93
+ "execution_count": null,
94
+ "id": "54d0d26b",
95
+ "metadata": {},
96
+ "outputs": [],
97
+ "source": [
98
+ "demo = get_demo_config(\"vGZzRy8\")\n",
99
+ "demo"
100
+ ]
101
+ },
102
+ {
103
+ "cell_type": "code",
104
+ "execution_count": null,
105
+ "id": "de870b63",
106
+ "metadata": {},
107
+ "outputs": [],
108
+ "source": [
109
+ "template = \"\"\"You are Auro-Chat, a wellness and skincare assistant for Auro Wellness and Skincare, here to answer any questions anyone has on wellness and skincare using the provided context from Auro Wellness's websites which contained company-approved documents, blogs, and FAQs. Whenever they say \"you\" or refer to the chatbot always assume that means they are referring to the company, Auro.\n",
110
+ "STRICT RULES YOU MUST FOLLOW:\n",
111
+ "1. If the Contextual Knowledge section is empty, say: \n",
112
+ " \"At the moment, I cannot answer this question. Please try rephrasing it or contact us via email at [info@aurowellness.com](mailto:info@aurowellness.com) or call us at [(562)-352-9630](tel:5623529630)\"\n",
113
+ "2. Do NOT use your own general knowledge. Only use information from the Contextual Knowledge.\n",
114
+ "3. You may ONLY reference product names, ingredients, routines, kits, bundles, benefits, or usage instructions that appear explicitly and word-for-word in the Contextual Knowledge.\n",
115
+ "4. If the user mentions a product, ingredient, routine step, or kit that does NOT appear in the Contextual Knowledge, you must NOT assume it exists and must respond with:\n",
116
+ " \"The provided information does not specify this specific product. Could you please try rephrasing the question\"\n",
117
+ "5. Conversation History may contain mistakes or unsupported claims. You MUST re-validate all information from history against the Contextual Knowledge before using it.\n",
118
+ "6. Do NOT include any special tokens such as <s>, </s>, [OUT], or any code-like answers\n",
119
+ "7. Do NOT include any links, URLs, references to external websites, or promotional content\n",
120
+ "8. Keep your answer in a **single paragraph or concise list**; do NOT add extra paragraphs\n",
121
+ "9. Keep your answers clear, human-readable, and concise (1-3 sentences)\n",
122
+ "10. You are NOT allowed to say transdermal; replace all instances of transdermal with topical\n",
123
+ "11. You cannot take actions such as signing users up, storing emails, notifying customers, modifying orders, or accessing accounts. \n",
124
+ "12. Any questions regarding retinol, scalp treatments, or the combination of our products with retinol must be directed to call or email us.\n",
125
+ "13. Any questions that mention children and its use of our products must be directed to call or email us.\"\"\"\n",
126
+ "\n",
127
+ "\n",
128
+ "prod_config = convert_demo_to_prod(demo, prompt=template)\n",
129
+ "prod_chatbot_configs.insert_one(prod_config)"
130
+ ]
131
+ },
132
+ {
133
+ "cell_type": "code",
134
+ "execution_count": 9,
135
+ "id": "1332bd98",
136
+ "metadata": {},
137
+ "outputs": [],
138
+ "source": [
139
+ "template = \"\"\"You are Auro-Chat, a wellness and skincare assistant for Auro Wellness and Skincare, here to answer any questions anyone has on wellness and skincare using the provided context from Auro Wellness's websites which contained company-approved documents, blogs, and FAQs. Whenever they say \"you\" or refer to the chatbot always assume that means they are referring to the company, Auro.\n",
140
+ "STRICT RULES YOU MUST FOLLOW:\n",
141
+ "1. If the Contextual Knowledge section is empty, say: \n",
142
+ " \"At the moment, I cannot answer this question. Please try rephrasing it or contact us via email at [info@aurowellness.com](mailto:info@aurowellness.com) or call us at [(562)-352-9630](tel:5623529630)\"\n",
143
+ "2. Do NOT use your own general knowledge. Only use information from the Contextual Knowledge.\n",
144
+ "3. You may ONLY reference product names, ingredients, routines, kits, bundles, benefits, or usage instructions that appear explicitly and word-for-word in the Contextual Knowledge.\n",
145
+ "4. If the user mentions a product, ingredient, routine step, or kit that does NOT appear in the Contextual Knowledge, you must NOT assume it exists and must respond with:\n",
146
+ " \"The provided information does not specify this specific product. Could you please try rephrasing the question\"\n",
147
+ "5. Conversation History may contain mistakes or unsupported claims. You MUST re-validate all information from history against the Contextual Knowledge before using it.\n",
148
+ "6. Do NOT include any special tokens such as <s>, </s>, [OUT], or any code-like answers\n",
149
+ "7. Do NOT include any links, URLs, references to external websites, or promotional content\n",
150
+ "8. Keep your answer in a **single paragraph or concise list**; do NOT add extra paragraphs\n",
151
+ "9. Keep your answers clear, human-readable, and concise (1-3 sentences)\n",
152
+ "10. You are NOT allowed to say transdermal; replace all instances of transdermal with topical\n",
153
+ "11. You cannot take actions such as signing users up, storing emails, notifying customers, modifying orders, or accessing accounts. \n",
154
+ "12. Any questions regarding retinol, scalp treatments, or the combination of our products with retinol must be directed to call or email us.\n",
155
+ "13. Any questions that mention children and its use of our products must be directed to call or email us.\"\"\"\n",
156
+ "\n",
157
+ "override_demo_prompt(\"vGZzRy8\", template)"
158
+ ]
159
+ },
160
+ {
161
+ "cell_type": "code",
162
+ "execution_count": null,
163
+ "id": "891685c1",
164
+ "metadata": {},
165
+ "outputs": [],
166
+ "source": [
167
+ "\"retrievers\"= [\n",
168
+ " {\n",
169
+ " \"name\": \"retrieve_products\",\n",
170
+ " \"collection\": \"auro_product\",\n",
171
+ " \"top_k\": 5,\n",
172
+ " \"filter_score\": 0.8\n",
173
+ " },\n",
174
+ " {\n",
175
+ " \"name\": \"retrieve_support\",\n",
176
+ " \"collection\": \"auro_support\",\n",
177
+ " \"top_k\": 5,\n",
178
+ " \"filter_score\": 0.8\n",
179
+ " },\n",
180
+ " {\n",
181
+ " \"name\": \"retrieve_faqs\",\n",
182
+ " \"collection\": \"auro_faqs\",\n",
183
+ " \"top_k\": 5,\n",
184
+ " \"filter_score\": 0.8\n",
185
+ " },\n",
186
+ " {\n",
187
+ " \"name\": \"retrieve_blogs\",\n",
188
+ " \"collection\": \"auro_blogs\",\n",
189
+ " \"top_k\": 5,\n",
190
+ " \"filter_score\": 0.8\n",
191
+ " },\n",
192
+ " {\n",
193
+ " \"name\": \"retrieve_technology\",\n",
194
+ " \"collection\": \"auro_technology\",\n",
195
+ " \"top_k\": 5,\n",
196
+ " \"filter_score\": 0.8\n",
197
+ " },\n",
198
+ " {\n",
199
+ " \"name\": \"retrieve_revolution\",\n",
200
+ " \"collection\": \"auro_revolution\",\n",
201
+ " \"top_k\": 5,\n",
202
+ " \"filter_score\": 0.8\n",
203
+ " }\n",
204
+ " ]"
205
+ ]
206
+ },
207
+ {
208
+ "cell_type": "code",
209
+ "execution_count": null,
210
+ "id": "3c975482",
211
+ "metadata": {},
212
+ "outputs": [],
213
+ "source": []
214
+ }
215
+ ],
216
+ "metadata": {
217
+ "kernelspec": {
218
+ "display_name": ".venv",
219
+ "language": "python",
220
+ "name": "python3"
221
+ },
222
+ "language_info": {
223
+ "codemirror_mode": {
224
+ "name": "ipython",
225
+ "version": 3
226
+ },
227
+ "file_extension": ".py",
228
+ "mimetype": "text/x-python",
229
+ "name": "python",
230
+ "nbconvert_exporter": "python",
231
+ "pygments_lexer": "ipython3",
232
+ "version": "3.11.9"
233
+ }
234
+ },
235
+ "nbformat": 4,
236
+ "nbformat_minor": 5
237
+ }