redfernstech commited on
Commit
6d30421
·
verified ·
1 Parent(s): e02684f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +146 -385
app.py CHANGED
@@ -1,464 +1,225 @@
1
- # import os
2
- # import time
3
- # from fastapi import FastAPI,Request
4
- # from fastapi.responses import HTMLResponse
5
- # from fastapi.staticfiles import StaticFiles
6
- # from llama_index.core import StorageContext, load_index_from_storage, VectorStoreIndex, SimpleDirectoryReader, ChatPromptTemplate, Settings
7
- # from llama_index.embeddings.huggingface import HuggingFaceEmbedding
8
- # from pydantic import BaseModel
9
- # from fastapi.responses import JSONResponse
10
- # import uuid # for generating unique IDs
11
- # import datetime
12
- # from fastapi.middleware.cors import CORSMiddleware
13
- # from fastapi.templating import Jinja2Templates
14
- # from huggingface_hub import InferenceClient
15
- # import json
16
- # import re
17
- # from gradio_client import Client
18
- # from simple_salesforce import Salesforce, SalesforceLogin
19
- # from llama_index.llms.huggingface import HuggingFaceLLM
20
- # # from llama_index.llms.huggingface import HuggingFaceInferenceAPI
21
-
22
-
23
- # # Define Pydantic model for incoming request body
24
- # class MessageRequest(BaseModel):
25
- # message: str
26
- # repo_id = "meta-llama/Meta-Llama-3-8B-Instruct"
27
- # llm_client = InferenceClient(
28
- # model=repo_id,
29
- # token=os.getenv("HF_TOKEN"),
30
- # )
31
-
32
-
33
- # os.environ["HF_TOKEN"] = os.getenv("HF_TOKEN")
34
- # username = os.getenv("username")
35
- # password = os.getenv("password")
36
- # security_token = os.getenv("security_token")
37
- # domain = os.getenv("domain")# Using sandbox environment
38
- # session_id, sf_instance = SalesforceLogin(username=username, password=password, security_token=security_token, domain=domain)
39
-
40
- # # Create Salesforce object
41
- # sf = Salesforce(instance=sf_instance, session_id=session_id)
42
-
43
- # app = FastAPI()
44
-
45
-
46
- # @app.middleware("http")
47
- # async def add_security_headers(request: Request, call_next):
48
- # response = await call_next(request)
49
- # response.headers["Content-Security-Policy"] = "frame-ancestors *; frame-src *; object-src *;"
50
- # response.headers["X-Frame-Options"] = "ALLOWALL"
51
- # return response
52
-
53
-
54
- # # Allow CORS requests from any domain
55
- # app.add_middleware(
56
- # CORSMiddleware,
57
- # allow_origins=["*"],
58
- # allow_credentials=True,
59
- # allow_methods=["*"],
60
- # allow_headers=["*"],
61
- # )
62
-
63
-
64
-
65
-
66
- # @app.get("/favicon.ico")
67
- # async def favicon():
68
- # return HTMLResponse("") # or serve a real favicon if you have one
69
-
70
-
71
- # app.mount("/static", StaticFiles(directory="static"), name="static")
72
-
73
- # templates = Jinja2Templates(directory="static")
74
- # # Configure Llama index settings
75
- # Settings.llm = HuggingFaceLLM(
76
- # model_name="meta-llama/Meta-Llama-3-8B-Instruct",
77
- # tokenizer_name="meta-llama/Meta-Llama-3-8B-Instruct",
78
- # context_window=3000,
79
- # token=os.getenv("HF_TOKEN"),
80
- # max_new_tokens=512,
81
- # generate_kwargs={"temperature": 0.1},
82
- # )
83
-
84
- # Settings.embed_model = HuggingFaceEmbedding(
85
- # model_name="BAAI/bge-small-en-v1.5"
86
- # )
87
-
88
- # PERSIST_DIR = "db"
89
- # PDF_DIRECTORY = 'data'
90
-
91
- # # Ensure directories exist
92
- # os.makedirs(PDF_DIRECTORY, exist_ok=True)
93
- # os.makedirs(PERSIST_DIR, exist_ok=True)
94
- # chat_history = []
95
- # current_chat_history = []
96
- # def data_ingestion_from_directory():
97
- # documents = SimpleDirectoryReader(PDF_DIRECTORY).load_data()
98
- # storage_context = StorageContext.from_defaults()
99
- # index = VectorStoreIndex.from_documents(documents)
100
- # index.storage_context.persist(persist_dir=PERSIST_DIR)
101
-
102
- # def initialize():
103
- # start_time = time.time()
104
- # data_ingestion_from_directory() # Process PDF ingestion at startup
105
- # print(f"Data ingestion time: {time.time() - start_time} seconds")
106
- # def split_name(full_name):
107
- # # Split the name by spaces
108
- # words = full_name.strip().split()
109
-
110
- # # Logic for determining first name and last name
111
- # if len(words) == 1:
112
- # first_name = ''
113
- # last_name = words[0]
114
- # elif len(words) == 2:
115
- # first_name = words[0]
116
- # last_name = words[1]
117
- # else:
118
- # first_name = words[0]
119
- # last_name = ' '.join(words[1:])
120
-
121
- # return first_name, last_name
122
-
123
- # initialize() # Run initialization tasks
124
-
125
-
126
- # def handle_query(query):
127
- # chat_text_qa_msgs = [
128
- # (
129
- # "user",
130
- # """
131
- # You are the Clara Redfernstech chatbot. Your goal is to provide accurate, professional, and helpful answers to user queries based on the company's data. Always ensure your responses are clear and concise. Give response within 10-15 words only
132
- # {context_str}
133
- # Question:
134
- # {query_str}
135
- # """
136
- # )
137
- # ]
138
- # text_qa_template = ChatPromptTemplate.from_messages(chat_text_qa_msgs)
139
-
140
- # storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
141
- # index = load_index_from_storage(storage_context)
142
- # context_str = ""
143
- # for past_query, response in reversed(current_chat_history):
144
- # if past_query.strip():
145
- # context_str += f"User asked: '{past_query}'\nBot answered: '{response}'\n"
146
-
147
-
148
- # query_engine = index.as_query_engine(text_qa_template=text_qa_template, context_str=context_str)
149
- # answer = query_engine.query(query)
150
-
151
- # if hasattr(answer, 'response'):
152
- # response=answer.response
153
- # elif isinstance(answer, dict) and 'response' in answer:
154
- # response =answer['response']
155
- # else:
156
- # response ="Sorry, I couldn't find an answer."
157
- # current_chat_history.append((query, response))
158
- # return response
159
- # @app.get("/ch/{id}", response_class=HTMLResponse)
160
- # async def load_chat(request: Request, id: str):
161
- # return templates.TemplateResponse("index.html", {"request": request, "user_id": id})
162
- # # Route to save chat history
163
- # @app.post("/hist/")
164
- # async def save_chat_history(history: dict):
165
- # # Check if 'userId' is present in the incoming dictionary
166
- # user_id = history.get('userId')
167
- # print(user_id)
168
-
169
- # # Ensure user_id is defined before proceeding
170
- # if user_id is None:
171
- # return {"error": "userId is required"}, 400
172
-
173
- # # Construct the chat history string
174
- # hist = ''.join([f"'{entry['sender']}: {entry['message']}'\n" for entry in history['history']])
175
- # hist = "You are a Redfernstech summarize model. Your aim is to use this conversation to identify user interests solely based on that conversation: " + hist
176
- # print(hist)
177
-
178
- # # Get the summarized result from the client model
179
- # result = hist
180
-
181
- # try:
182
- # sf.Lead.update(user_id, {'Description': result})
183
- # except Exception as e:
184
- # return {"error": f"Failed to update lead: {str(e)}"}, 500
185
-
186
- # return {"summary": result, "message": "Chat history saved"}
187
- # @app.post("/webhook")
188
- # async def receive_form_data(request: Request):
189
- # form_data = await request.json()
190
- # # Log in to Salesforce
191
- # first_name, last_name = split_name(form_data['name'])
192
- # data = {
193
- # 'FirstName': first_name,
194
- # 'LastName': last_name,
195
- # 'Description': 'hii', # Static description
196
- # 'Company': form_data['company'], # Assuming company is available in form_data
197
- # 'Phone': form_data['phone'].strip(), # Phone from form data
198
- # 'Email': form_data['email'], # Email from form data
199
- # }
200
- # a=sf.Lead.create(data)
201
- # # Generate a unique ID (for tracking user)
202
- # unique_id = a['id']
203
-
204
- # # Here you can do something with form_data like saving it to a database
205
- # print("Received form data:", form_data)
206
-
207
- # # Send back the unique id to the frontend
208
- # return JSONResponse({"id": unique_id})
209
-
210
- # @app.post("/chat/")
211
- # async def chat(request: MessageRequest):
212
- # message = request.message # Access the message from the request body
213
- # response = handle_query(message) # Process the message
214
- # message_data = {
215
- # "sender": "User",
216
- # "message": message,
217
- # "response": response,
218
- # "timestamp": datetime.datetime.now().isoformat()
219
- # }
220
- # chat_history.append(message_data)
221
- # return {"response": response}
222
- # @app.get("/")
223
- # def read_root():
224
- # return {"message": "Welcome to the API"}
225
-
226
  import os
227
  import time
228
- from fastapi import FastAPI, Request, HTTPException
229
- from fastapi.responses import HTMLResponse, JSONResponse
230
  from fastapi.staticfiles import StaticFiles
231
  from llama_index.core import StorageContext, load_index_from_storage, VectorStoreIndex, SimpleDirectoryReader, ChatPromptTemplate, Settings
232
- from llama_index.core.base.llms.types import ChatMessage, MessageRole
233
- from llama_index.core.llms import LLM
234
  from llama_index.embeddings.huggingface import HuggingFaceEmbedding
235
  from pydantic import BaseModel
 
 
 
236
  from fastapi.middleware.cors import CORSMiddleware
237
  from fastapi.templating import Jinja2Templates
238
  from huggingface_hub import InferenceClient
239
- import datetime
 
 
240
  from simple_salesforce import Salesforce, SalesforceLogin
 
 
241
 
242
- # Pydantic model for request body
 
243
  class MessageRequest(BaseModel):
244
  message: str
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
- # Custom LLM class for Hugging Face Inference API
247
- class HuggingFaceInferenceLLM(LLM):
248
- def __init__(self, model_name: str, token: str):
249
- super().__init__()
250
- self.client = InferenceClient(model=model_name, token=token)
251
- self.model_name = model_name
252
-
253
- def chat(self, messages: list[ChatMessage], **kwargs) -> str:
254
- prompt = ""
255
- for msg in messages:
256
- role = "user" if msg.role == MessageRole.USER else "assistant"
257
- prompt += f"{role}: {msg.content}\n"
258
- try:
259
- response = self.client.text_generation(
260
- prompt,
261
- max_new_tokens=512,
262
- temperature=0.1,
263
- do_sample=True,
264
- stop_sequences=["\n"]
265
- )
266
- return response
267
- except Exception as e:
268
- return f"Error in API call: {str(e)}"
269
-
270
- async def achat(self, messages: list[ChatMessage], **kwargs) -> str:
271
- return self.chat(messages, **kwargs)
272
-
273
- @property
274
- def metadata(self):
275
- return {
276
- "model_name": self.model_name,
277
- "context_window": 3000,
278
- "max_new_tokens": 512
279
- }
280
-
281
- # Validate environment variables
282
- required_env_vars = ["HF_TOKEN", "username", "password", "security_token", "domain"]
283
- for var in required_env_vars:
284
- if not os.getenv(var):
285
- raise EnvironmentError(f"Missing required environment variable: {var}")
286
-
287
- # Salesforce configuration
288
- try:
289
- session_id, sf_instance = SalesforceLogin(
290
- username=os.getenv("username"),
291
- password=os.getenv("password"),
292
- security_token=os.getenv("security_token"),
293
- domain=os.getenv("domain")
294
- )
295
- sf = Salesforce(instance=sf_instance, session_id=session_id)
296
- except Exception as e:
297
- raise Exception(f"Failed to initialize Salesforce: {str(e)}")
298
-
299
- # FastAPI setup
300
  app = FastAPI()
301
 
302
- # Security headers middleware
303
  @app.middleware("http")
304
  async def add_security_headers(request: Request, call_next):
305
  response = await call_next(request)
306
- response.headers.update({
307
- "Content-Security-Policy": "default-src 'self'; frame-ancestors 'self';",
308
- "X-Frame-Options": "DENY",
309
- "X-Content-Type-Options": "nosniff",
310
- "Referrer-Policy": "strict-origin-when-cross-origin"
311
- })
312
  return response
313
 
314
- # CORS configuration
 
315
  app.add_middleware(
316
  CORSMiddleware,
317
- allow_origins=["*"], # Specify allowed origins in production
318
  allow_credentials=True,
319
  allow_methods=["*"],
320
  allow_headers=["*"],
321
  )
322
 
323
- # Static files and templates
 
 
 
 
 
 
 
324
  app.mount("/static", StaticFiles(directory="static"), name="static")
325
- templates = Jinja2Templates(directory="static")
326
 
327
- # LlamaIndex configuration
328
- Settings.llm = HuggingFaceInferenceLLM(
 
329
  model_name="meta-llama/Meta-Llama-3-8B-Instruct",
330
- token=os.getenv("HF_TOKEN")
 
 
 
 
331
  )
332
 
333
  Settings.embed_model = HuggingFaceEmbedding(
334
  model_name="BAAI/bge-small-en-v1.5"
335
  )
336
 
337
- # Directory constants
338
  PERSIST_DIR = "db"
339
- PDF_DIRECTORY = "data"
340
 
341
- # Initialize directories
342
  os.makedirs(PDF_DIRECTORY, exist_ok=True)
343
  os.makedirs(PERSIST_DIR, exist_ok=True)
344
-
345
- # Chat history storage
346
  chat_history = []
347
  current_chat_history = []
348
-
349
  def data_ingestion_from_directory():
350
- try:
351
- documents = SimpleDirectoryReader(PDF_DIRECTORY).load_data()
352
- storage_context = StorageContext.from_defaults()
353
- index = VectorStoreIndex.from_documents(documents)
354
- index.storage_context.persist(persist_dir=PERSIST_DIR)
355
- except Exception as e:
356
- raise Exception(f"Data ingestion failed: {str(e)}")
357
 
358
  def initialize():
359
  start_time = time.time()
360
- data_ingestion_from_directory()
361
- print(f"Data ingestion completed in {time.time() - start_time:.2f} seconds")
362
-
363
- def split_name(full_name: str) -> tuple:
364
  words = full_name.strip().split()
 
 
365
  if len(words) == 1:
366
- return "", words[0]
 
367
  elif len(words) == 2:
368
- return words[0], words[1]
369
- return words[0], " ".join(words[1:])
 
 
 
 
 
 
 
370
 
371
- # Run initialization
372
- initialize()
373
 
374
- def handle_query(query: str) -> str:
375
  chat_text_qa_msgs = [
376
  (
377
  "user",
378
  """
379
- You are the Clara Redfernstech chatbot. Provide accurate, professional answers in 10-15 words.
380
  {context_str}
381
- Question: {query_str}
 
382
  """
383
  )
384
  ]
385
  text_qa_template = ChatPromptTemplate.from_messages(chat_text_qa_msgs)
386
 
387
- try:
388
- storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
389
- index = load_index_from_storage(storage_context)
390
-
391
- context_str = ""
392
- for past_query, response in reversed(current_chat_history[-5:]): # Limit context to last 5 interactions
393
- if past_query.strip():
394
- context_str += f"User: '{past_query}'\nBot: '{response}'\n"
395
-
396
- query_engine = index.as_query_engine(text_qa_template=text_qa_template)
397
- answer = query_engine.query(query)
398
-
399
- response = getattr(answer, 'response', answer.get('response', "Sorry, I couldn't find an answer."))
400
- current_chat_history.append((query, response))
401
- return response
402
- except Exception as e:
403
- return f"Error processing query: {str(e)}"
404
-
405
- @app.get("/favicon.ico")
406
- async def favicon():
407
- return HTMLResponse(status_code=204)
408
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  @app.get("/ch/{id}", response_class=HTMLResponse)
410
  async def load_chat(request: Request, id: str):
411
  return templates.TemplateResponse("index.html", {"request": request, "user_id": id})
412
-
413
  @app.post("/hist/")
414
  async def save_chat_history(history: dict):
 
415
  user_id = history.get('userId')
416
- if not user_id:
417
- raise HTTPException(status_code=400, detail="userId is required")
 
 
 
 
 
 
 
 
 
 
 
418
 
419
  try:
420
- hist = ''.join([f"'{entry['sender']}: {entry['message']}'\n" for entry in history['history']])
421
- summary = f"Conversation summary for user interest analysis:\n{hist}"
422
-
423
- sf.Lead.update(user_id, {'Description': summary})
424
- return {"summary": summary, "message": "Chat history saved"}
425
  except Exception as e:
426
- raise HTTPException(status_code=500, detail=f"Failed to update lead: {str(e)}")
427
-
 
428
  @app.post("/webhook")
429
  async def receive_form_data(request: Request):
430
- try:
431
- form_data = await request.json()
432
- first_name, last_name = split_name(form_data.get('name', ''))
433
-
434
- data = {
435
- 'FirstName': first_name,
436
- 'LastName': last_name,
437
- 'Description': 'New lead from webhook',
438
- 'Company': form_data.get('company', 'Unknown'),
439
- 'Phone': form_data.get('phone', '').strip(),
440
- 'Email': form_data.get('email', ''),
441
- }
442
- result = sf.Lead.create(data)
443
- return JSONResponse({"id": result['id']})
444
- except Exception as e:
445
- raise HTTPException(status_code=500, detail=f"Failed to process webhook: {str(e)}")
 
 
 
 
446
 
447
  @app.post("/chat/")
448
  async def chat(request: MessageRequest):
449
- try:
450
- response = handle_query(request.message)
451
- message_data = {
452
- "sender": "User",
453
- "message": request.message,
454
- "response": response,
455
- "timestamp": datetime.datetime.now().isoformat()
456
- }
457
- chat_history.append(message_data)
458
- return {"response": response}
459
- except Exception as e:
460
- raise HTTPException(status_code=500, detail=f"Chat processing failed: {str(e)}")
461
-
462
  @app.get("/")
463
  def read_root():
464
- return {"message": "Welcome to the Redfernstech API"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  import time
3
+ from fastapi import FastAPI,Request
4
+ from fastapi.responses import HTMLResponse
5
  from fastapi.staticfiles import StaticFiles
6
  from llama_index.core import StorageContext, load_index_from_storage, VectorStoreIndex, SimpleDirectoryReader, ChatPromptTemplate, Settings
 
 
7
  from llama_index.embeddings.huggingface import HuggingFaceEmbedding
8
  from pydantic import BaseModel
9
+ from fastapi.responses import JSONResponse
10
+ import uuid # for generating unique IDs
11
+ import datetime
12
  from fastapi.middleware.cors import CORSMiddleware
13
  from fastapi.templating import Jinja2Templates
14
  from huggingface_hub import InferenceClient
15
+ import json
16
+ import re
17
+ from gradio_client import Client
18
  from simple_salesforce import Salesforce, SalesforceLogin
19
+ from llama_index.llms.huggingface import HuggingFaceLLM
20
+ # from llama_index.llms.huggingface import HuggingFaceInferenceAPI
21
 
22
+
23
+ # Define Pydantic model for incoming request body
24
  class MessageRequest(BaseModel):
25
  message: str
26
+ repo_id = "meta-llama/Meta-Llama-3-8B-Instruct"
27
+ llm_client = InferenceClient(
28
+ model=repo_id,
29
+ token=os.getenv("HF_TOKEN"),
30
+ )
31
+
32
+
33
+ os.environ["HF_TOKEN"] = os.getenv("HF_TOKEN")
34
+ username = os.getenv("username")
35
+ password = os.getenv("password")
36
+ security_token = os.getenv("security_token")
37
+ domain = os.getenv("domain")# Using sandbox environment
38
+ session_id, sf_instance = SalesforceLogin(username=username, password=password, security_token=security_token, domain=domain)
39
+
40
+ # Create Salesforce object
41
+ sf = Salesforce(instance=sf_instance, session_id=session_id)
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  app = FastAPI()
44
 
45
+
46
  @app.middleware("http")
47
  async def add_security_headers(request: Request, call_next):
48
  response = await call_next(request)
49
+ response.headers["Content-Security-Policy"] = "frame-ancestors *; frame-src *; object-src *;"
50
+ response.headers["X-Frame-Options"] = "ALLOWALL"
 
 
 
 
51
  return response
52
 
53
+
54
+ # Allow CORS requests from any domain
55
  app.add_middleware(
56
  CORSMiddleware,
57
+ allow_origins=["*"],
58
  allow_credentials=True,
59
  allow_methods=["*"],
60
  allow_headers=["*"],
61
  )
62
 
63
+
64
+
65
+
66
+ @app.get("/favicon.ico")
67
+ async def favicon():
68
+ return HTMLResponse("") # or serve a real favicon if you have one
69
+
70
+
71
  app.mount("/static", StaticFiles(directory="static"), name="static")
 
72
 
73
+ templates = Jinja2Templates(directory="static")
74
+ # Configure Llama index settings
75
+ Settings.llm = HuggingFaceLLM(
76
  model_name="meta-llama/Meta-Llama-3-8B-Instruct",
77
+ tokenizer_name="meta-llama/Meta-Llama-3-8B-Instruct",
78
+ context_window=3000,
79
+ token=os.getenv("HF_TOKEN"),
80
+ max_new_tokens=512,
81
+ generate_kwargs={"temperature": 0.1},
82
  )
83
 
84
  Settings.embed_model = HuggingFaceEmbedding(
85
  model_name="BAAI/bge-small-en-v1.5"
86
  )
87
 
 
88
  PERSIST_DIR = "db"
89
+ PDF_DIRECTORY = 'data'
90
 
91
+ # Ensure directories exist
92
  os.makedirs(PDF_DIRECTORY, exist_ok=True)
93
  os.makedirs(PERSIST_DIR, exist_ok=True)
 
 
94
  chat_history = []
95
  current_chat_history = []
 
96
  def data_ingestion_from_directory():
97
+ documents = SimpleDirectoryReader(PDF_DIRECTORY).load_data()
98
+ storage_context = StorageContext.from_defaults()
99
+ index = VectorStoreIndex.from_documents(documents)
100
+ index.storage_context.persist(persist_dir=PERSIST_DIR)
 
 
 
101
 
102
  def initialize():
103
  start_time = time.time()
104
+ data_ingestion_from_directory() # Process PDF ingestion at startup
105
+ print(f"Data ingestion time: {time.time() - start_time} seconds")
106
+ def split_name(full_name):
107
+ # Split the name by spaces
108
  words = full_name.strip().split()
109
+
110
+ # Logic for determining first name and last name
111
  if len(words) == 1:
112
+ first_name = ''
113
+ last_name = words[0]
114
  elif len(words) == 2:
115
+ first_name = words[0]
116
+ last_name = words[1]
117
+ else:
118
+ first_name = words[0]
119
+ last_name = ' '.join(words[1:])
120
+
121
+ return first_name, last_name
122
+
123
+ initialize() # Run initialization tasks
124
 
 
 
125
 
126
+ def handle_query(query):
127
  chat_text_qa_msgs = [
128
  (
129
  "user",
130
  """
131
+ You are the Clara Redfernstech chatbot. Your goal is to provide accurate, professional, and helpful answers to user queries based on the company's data. Always ensure your responses are clear and concise. Give response within 10-15 words only
132
  {context_str}
133
+ Question:
134
+ {query_str}
135
  """
136
  )
137
  ]
138
  text_qa_template = ChatPromptTemplate.from_messages(chat_text_qa_msgs)
139
 
140
+ storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
141
+ index = load_index_from_storage(storage_context)
142
+ context_str = ""
143
+ for past_query, response in reversed(current_chat_history):
144
+ if past_query.strip():
145
+ context_str += f"User asked: '{past_query}'\nBot answered: '{response}'\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
+
148
+ query_engine = index.as_query_engine(text_qa_template=text_qa_template, context_str=context_str)
149
+ answer = query_engine.query(query)
150
+
151
+ if hasattr(answer, 'response'):
152
+ response=answer.response
153
+ elif isinstance(answer, dict) and 'response' in answer:
154
+ response =answer['response']
155
+ else:
156
+ response ="Sorry, I couldn't find an answer."
157
+ current_chat_history.append((query, response))
158
+ return response
159
  @app.get("/ch/{id}", response_class=HTMLResponse)
160
  async def load_chat(request: Request, id: str):
161
  return templates.TemplateResponse("index.html", {"request": request, "user_id": id})
162
+ # Route to save chat history
163
  @app.post("/hist/")
164
  async def save_chat_history(history: dict):
165
+ # Check if 'userId' is present in the incoming dictionary
166
  user_id = history.get('userId')
167
+ print(user_id)
168
+
169
+ # Ensure user_id is defined before proceeding
170
+ if user_id is None:
171
+ return {"error": "userId is required"}, 400
172
+
173
+ # Construct the chat history string
174
+ hist = ''.join([f"'{entry['sender']}: {entry['message']}'\n" for entry in history['history']])
175
+ hist = "You are a Redfernstech summarize model. Your aim is to use this conversation to identify user interests solely based on that conversation: " + hist
176
+ print(hist)
177
+
178
+ # Get the summarized result from the client model
179
+ result = hist
180
 
181
  try:
182
+ sf.Lead.update(user_id, {'Description': result})
 
 
 
 
183
  except Exception as e:
184
+ return {"error": f"Failed to update lead: {str(e)}"}, 500
185
+
186
+ return {"summary": result, "message": "Chat history saved"}
187
  @app.post("/webhook")
188
  async def receive_form_data(request: Request):
189
+ form_data = await request.json()
190
+ # Log in to Salesforce
191
+ first_name, last_name = split_name(form_data['name'])
192
+ data = {
193
+ 'FirstName': first_name,
194
+ 'LastName': last_name,
195
+ 'Description': 'hii', # Static description
196
+ 'Company': form_data['company'], # Assuming company is available in form_data
197
+ 'Phone': form_data['phone'].strip(), # Phone from form data
198
+ 'Email': form_data['email'], # Email from form data
199
+ }
200
+ a=sf.Lead.create(data)
201
+ # Generate a unique ID (for tracking user)
202
+ unique_id = a['id']
203
+
204
+ # Here you can do something with form_data like saving it to a database
205
+ print("Received form data:", form_data)
206
+
207
+ # Send back the unique id to the frontend
208
+ return JSONResponse({"id": unique_id})
209
 
210
  @app.post("/chat/")
211
  async def chat(request: MessageRequest):
212
+ message = request.message # Access the message from the request body
213
+ response = handle_query(message) # Process the message
214
+ message_data = {
215
+ "sender": "User",
216
+ "message": message,
217
+ "response": response,
218
+ "timestamp": datetime.datetime.now().isoformat()
219
+ }
220
+ chat_history.append(message_data)
221
+ return {"response": response}
 
 
 
222
  @app.get("/")
223
  def read_root():
224
+ return {"message": "Welcome to the API"}
225
+