XThomasBU commited on
Commit
e19e333
1 Parent(s): 5a7dbeb

final commit - callbacks logging needs work

Browse files
code/.chainlit/config.toml CHANGED
@@ -23,7 +23,7 @@ allow_origins = ["*"]
23
  unsafe_allow_html = false
24
 
25
  # Process and display mathematical expressions. This can clash with "$" characters in messages.
26
- latex = false
27
 
28
  # Automatically tag threads with the current chat profile (if a chat profile is used)
29
  auto_tag_thread = true
 
23
  unsafe_allow_html = false
24
 
25
  # Process and display mathematical expressions. This can clash with "$" characters in messages.
26
+ latex = true
27
 
28
  # Automatically tag threads with the current chat profile (if a chat profile is used)
29
  auto_tag_thread = true
code/main.py CHANGED
@@ -70,11 +70,12 @@ class Chatbot:
70
  start_time = time.time()
71
 
72
  llm_settings = cl.user_session.get("llm_settings", {})
73
- chat_profile, retriever_method, memory_window, llm_style = (
74
  llm_settings.get("chat_model"),
75
  llm_settings.get("retriever_method"),
76
  llm_settings.get("memory_window"),
77
  llm_settings.get("llm_style"),
 
78
  )
79
 
80
  chain = cl.user_session.get("chain")
@@ -87,22 +88,24 @@ class Chatbot:
87
  ),
88
  )
89
  conversation_list = get_history_setup_llm(memory_list)
90
- print("\n\n\n")
91
- print("history at setup_llm", conversation_list)
92
- print("\n\n\n")
93
 
94
  old_config = copy.deepcopy(self.config)
95
  self.config["vectorstore"]["db_option"] = retriever_method
96
  self.config["llm_params"]["memory_window"] = memory_window
97
  self.config["llm_params"]["llm_style"] = llm_style
98
  self.config["llm_params"]["llm_loader"] = chat_profile
 
99
 
100
  self.llm_tutor.update_llm(
101
  old_config, self.config
102
- ) # update only attributes that are changed
103
  self.chain = self.llm_tutor.qa_bot(
104
  memory=conversation_list,
105
- callbacks=[cl.LangchainCallbackHandler()] if cl_data._data_layer else None,
 
 
 
 
106
  )
107
 
108
  tags = [chat_profile, self.config["vectorstore"]["db_option"]]
@@ -165,7 +168,14 @@ class Chatbot:
165
  id="view_sources", label="View Sources", initial=False
166
  ),
167
  cl.input_widget.Switch(
168
- id="stream_response", label="Stream response", initial=False
 
 
 
 
 
 
 
169
  ),
170
  cl.input_widget.Select(
171
  id="llm_style",
@@ -193,6 +203,7 @@ class Chatbot:
193
  else 0
194
  ),
195
  "view_sources": llm_settings.get("view_sources"),
 
196
  }
197
  await cl.Message(
198
  author=SYSTEM,
@@ -270,21 +281,21 @@ class Chatbot:
270
  "user_id": user.identifier,
271
  "session_id": cl.context.session.thread_id,
272
  }
273
- print(self.user)
274
 
275
  memory = cl.user_session.get("memory", [])
276
 
277
  cl.user_session.set("user", self.user)
278
  self.llm_tutor = LLMTutor(self.config, user=self.user)
279
 
280
- print(cl.LangchainCallbackHandler())
281
- print(cl_data._data_layer)
282
  self.chain = self.llm_tutor.qa_bot(
283
  memory=memory,
284
- callbacks=[cl.LangchainCallbackHandler()] if cl_data._data_layer else None,
 
 
 
 
285
  )
286
  self.question_generator = self.llm_tutor.question_generator
287
- print(self.question_generator)
288
  cl.user_session.set("llm_tutor", self.llm_tutor)
289
  cl.user_session.set("chain", self.chain)
290
 
@@ -324,22 +335,10 @@ class Chatbot:
324
 
325
  chain = cl.user_session.get("chain")
326
 
327
- print("\n\n\n")
328
- print(
329
- "session history",
330
- chain.get_session_history(
331
- self.user["user_id"],
332
- self.user["session_id"],
333
- self.config["llm_params"]["memory_window"],
334
- ),
335
- )
336
- print("\n\n\n")
337
-
338
  llm_settings = cl.user_session.get("llm_settings", {})
339
  view_sources = llm_settings.get("view_sources", False)
340
- stream = (llm_settings.get("stream_response", True)) or (
341
- not self.config["llm_params"]["stream"]
342
- )
343
  user_query_dict = {"input": message.content}
344
  # Define the base configuration
345
  chain_config = {
@@ -350,8 +349,6 @@ class Chatbot:
350
  }
351
  }
352
 
353
- stream = False
354
-
355
  if stream:
356
  res = chain.stream(user_query=user_query_dict, config=chain_config)
357
  res = await self.stream_response(res)
@@ -385,31 +382,33 @@ class Chatbot:
385
  answer_with_sources, source_elements, sources_dict = get_sources(
386
  res, answer, stream=stream, view_sources=view_sources
387
  )
 
388
 
389
  print("Time taken to process the message: ", time.time() - start_time)
390
 
391
- list_of_questions = self.question_generator.generate_questions(
392
- query=user_query_dict["input"],
393
- response=answer,
394
- chat_history=res.get("chat_history"),
395
- context=res.get("context"),
396
- )
397
 
398
- print("\n\n\n")
399
- print("Questions: ", list_of_questions)
400
- print("\n\n\n")
 
 
 
 
 
401
 
402
- actions = []
403
- for question in list_of_questions:
404
-
405
- actions.append(
406
- cl.Action(
407
- name="follow up question",
408
- value="example_value",
409
- description=question,
410
- label=question,
411
  )
412
- )
 
413
 
414
  await cl.Message(
415
  content=answer_with_sources,
@@ -422,11 +421,6 @@ class Chatbot:
422
  steps = thread["steps"]
423
  k = self.config["llm_params"]["memory_window"]
424
  conversation_list = get_history_chat_resume(steps, k, SYSTEM, LLM)
425
-
426
- print("\n\n\n")
427
- print("history at on_chat_resume", conversation_list)
428
- print(len(conversation_list))
429
- print("\n\n\n")
430
  cl.user_session.set("memory", conversation_list)
431
  await self.start()
432
 
@@ -439,9 +433,11 @@ class Chatbot:
439
  ) -> Optional[cl.User]:
440
  return default_user
441
 
442
- async def on_action(self, action: cl.Action):
443
  message = await cl.Message(
444
- content=action.description, type="user_message"
 
 
445
  ).send()
446
  await self.main(message)
447
 
@@ -449,11 +445,8 @@ class Chatbot:
449
  chatbot = Chatbot(config=config)
450
 
451
 
452
- async def start():
453
- print("Setting up data layer...")
454
  cl_data._data_layer = await setup_data_layer()
455
- print("Data layer set up.")
456
- print(cl_data._data_layer)
457
  chatbot.literal_client = cl_data._data_layer.client if cl_data._data_layer else None
458
  cl.set_starters(chatbot.set_starters)
459
  cl.author_rename(chatbot.rename)
@@ -461,7 +454,7 @@ async def start():
461
  cl.on_chat_resume(chatbot.on_chat_resume)
462
  cl.on_message(chatbot.main)
463
  cl.on_settings_update(chatbot.update_llm)
464
- cl.action_callback("follow up question")(chatbot.on_action)
465
 
466
 
467
- asyncio.run(start())
 
70
  start_time = time.time()
71
 
72
  llm_settings = cl.user_session.get("llm_settings", {})
73
+ chat_profile, retriever_method, memory_window, llm_style, generate_follow_up = (
74
  llm_settings.get("chat_model"),
75
  llm_settings.get("retriever_method"),
76
  llm_settings.get("memory_window"),
77
  llm_settings.get("llm_style"),
78
+ llm_settings.get("follow_up_questions"),
79
  )
80
 
81
  chain = cl.user_session.get("chain")
 
88
  ),
89
  )
90
  conversation_list = get_history_setup_llm(memory_list)
 
 
 
91
 
92
  old_config = copy.deepcopy(self.config)
93
  self.config["vectorstore"]["db_option"] = retriever_method
94
  self.config["llm_params"]["memory_window"] = memory_window
95
  self.config["llm_params"]["llm_style"] = llm_style
96
  self.config["llm_params"]["llm_loader"] = chat_profile
97
+ self.config["llm_params"]["generate_follow_up"] = generate_follow_up
98
 
99
  self.llm_tutor.update_llm(
100
  old_config, self.config
101
+ ) # update only llm attributes that are changed
102
  self.chain = self.llm_tutor.qa_bot(
103
  memory=conversation_list,
104
+ callbacks=(
105
+ [cl.LangchainCallbackHandler()]
106
+ if cl_data._data_layer and self.config["chat_logging"]["callbacks"]
107
+ else None
108
+ ),
109
  )
110
 
111
  tags = [chat_profile, self.config["vectorstore"]["db_option"]]
 
168
  id="view_sources", label="View Sources", initial=False
169
  ),
170
  cl.input_widget.Switch(
171
+ id="stream_response",
172
+ label="Stream response",
173
+ initial=config["llm_params"]["stream"],
174
+ ),
175
+ cl.input_widget.Switch(
176
+ id="follow_up_questions",
177
+ label="Generate follow up questions",
178
+ initial=False,
179
  ),
180
  cl.input_widget.Select(
181
  id="llm_style",
 
203
  else 0
204
  ),
205
  "view_sources": llm_settings.get("view_sources"),
206
+ "follow_up_questions": llm_settings.get("follow_up_questions"),
207
  }
208
  await cl.Message(
209
  author=SYSTEM,
 
281
  "user_id": user.identifier,
282
  "session_id": cl.context.session.thread_id,
283
  }
 
284
 
285
  memory = cl.user_session.get("memory", [])
286
 
287
  cl.user_session.set("user", self.user)
288
  self.llm_tutor = LLMTutor(self.config, user=self.user)
289
 
 
 
290
  self.chain = self.llm_tutor.qa_bot(
291
  memory=memory,
292
+ callbacks=(
293
+ [cl.LangchainCallbackHandler()]
294
+ if cl_data._data_layer and self.config["chat_logging"]["callbacks"]
295
+ else None
296
+ ),
297
  )
298
  self.question_generator = self.llm_tutor.question_generator
 
299
  cl.user_session.set("llm_tutor", self.llm_tutor)
300
  cl.user_session.set("chain", self.chain)
301
 
 
335
 
336
  chain = cl.user_session.get("chain")
337
 
 
 
 
 
 
 
 
 
 
 
 
338
  llm_settings = cl.user_session.get("llm_settings", {})
339
  view_sources = llm_settings.get("view_sources", False)
340
+ stream = llm_settings.get("stream_response", False)
341
+ steam = False # Fix streaming
 
342
  user_query_dict = {"input": message.content}
343
  # Define the base configuration
344
  chain_config = {
 
349
  }
350
  }
351
 
 
 
352
  if stream:
353
  res = chain.stream(user_query=user_query_dict, config=chain_config)
354
  res = await self.stream_response(res)
 
382
  answer_with_sources, source_elements, sources_dict = get_sources(
383
  res, answer, stream=stream, view_sources=view_sources
384
  )
385
+ answer_with_sources = answer_with_sources.replace("$$", "$")
386
 
387
  print("Time taken to process the message: ", time.time() - start_time)
388
 
389
+ actions = []
 
 
 
 
 
390
 
391
+ if self.config["llm_params"]["generate_follow_up"]:
392
+ start_time = time.time()
393
+ list_of_questions = self.question_generator.generate_questions(
394
+ query=user_query_dict["input"],
395
+ response=answer,
396
+ chat_history=res.get("chat_history"),
397
+ context=res.get("context"),
398
+ )
399
 
400
+ for question in list_of_questions:
401
+
402
+ actions.append(
403
+ cl.Action(
404
+ name="follow up question",
405
+ value="example_value",
406
+ description=question,
407
+ label=question,
408
+ )
409
  )
410
+
411
+ print("Time taken to generate questions: ", time.time() - start_time)
412
 
413
  await cl.Message(
414
  content=answer_with_sources,
 
421
  steps = thread["steps"]
422
  k = self.config["llm_params"]["memory_window"]
423
  conversation_list = get_history_chat_resume(steps, k, SYSTEM, LLM)
 
 
 
 
 
424
  cl.user_session.set("memory", conversation_list)
425
  await self.start()
426
 
 
433
  ) -> Optional[cl.User]:
434
  return default_user
435
 
436
+ async def on_follow_up(self, action: cl.Action):
437
  message = await cl.Message(
438
+ content=action.description,
439
+ type="user_message",
440
+ author=self.user["user_id"],
441
  ).send()
442
  await self.main(message)
443
 
 
445
  chatbot = Chatbot(config=config)
446
 
447
 
448
+ async def start_app():
 
449
  cl_data._data_layer = await setup_data_layer()
 
 
450
  chatbot.literal_client = cl_data._data_layer.client if cl_data._data_layer else None
451
  cl.set_starters(chatbot.set_starters)
452
  cl.author_rename(chatbot.rename)
 
454
  cl.on_chat_resume(chatbot.on_chat_resume)
455
  cl.on_message(chatbot.main)
456
  cl.on_settings_update(chatbot.update_llm)
457
+ cl.action_callback("follow up question")(chatbot.on_follow_up)
458
 
459
 
460
+ asyncio.run(start_app())
code/modules/chat/helpers.py CHANGED
@@ -6,11 +6,6 @@ def get_sources(res, answer, stream=True, view_sources=False):
6
  source_elements = []
7
  source_dict = {} # Dictionary to store URL elements
8
 
9
- print("\n\n\n")
10
- print(res["context"])
11
- print(len(res["context"]))
12
- print("\n\n\n")
13
-
14
  for idx, source in enumerate(res["context"]):
15
  source_metadata = source.metadata
16
  url = source_metadata.get("source", "N/A")
@@ -25,9 +20,6 @@ def get_sources(res, answer, stream=True, view_sources=False):
25
  source_type = source_metadata.get("source_type", "N/A")
26
 
27
  url_name = f"{url}_{page}"
28
- print("url")
29
- print(url_name)
30
- print("\n\n\n")
31
  if url_name not in source_dict:
32
  source_dict[url_name] = {
33
  "text": source.page_content,
@@ -122,7 +114,6 @@ def get_history_chat_resume(steps, k, SYSTEM, LLM):
122
  conversation_list = []
123
  count = 0
124
  for step in reversed(steps):
125
- print(step["type"])
126
  if step["name"] not in [SYSTEM]:
127
  if step["type"] == "user_message":
128
  conversation_list.append(
 
6
  source_elements = []
7
  source_dict = {} # Dictionary to store URL elements
8
 
 
 
 
 
 
9
  for idx, source in enumerate(res["context"]):
10
  source_metadata = source.metadata
11
  url = source_metadata.get("source", "N/A")
 
20
  source_type = source_metadata.get("source_type", "N/A")
21
 
22
  url_name = f"{url}_{page}"
 
 
 
23
  if url_name not in source_dict:
24
  source_dict[url_name] = {
25
  "text": source.page_content,
 
114
  conversation_list = []
115
  count = 0
116
  for step in reversed(steps):
 
117
  if step["name"] not in [SYSTEM]:
118
  if step["type"] == "user_message":
119
  conversation_list.append(
code/modules/chat/langchain/utils.py CHANGED
@@ -198,13 +198,7 @@ class CustomRunnableWithHistory(RunnableWithMessageHistory):
198
  List[BaseMessage]: The last k conversations.
199
  """
200
  hist: BaseChatMessageHistory = config["configurable"]["message_history"]
201
-
202
- print("\n\n\n")
203
- print("Hist: ", hist)
204
- print("\n\n\n")
205
  messages = (await hist.aget_messages()).copy()
206
- print("messages: ", messages)
207
-
208
  if not self.history_messages_key:
209
  # return all messages
210
  input_val = (
@@ -220,9 +214,6 @@ class CustomRunnableWithHistory(RunnableWithMessageHistory):
220
 
221
  messages = self._get_chat_history(messages)
222
 
223
- print("\n\n\n")
224
- print("Messages: ", messages)
225
- print("\n\n\n")
226
  return messages
227
 
228
 
 
198
  List[BaseMessage]: The last k conversations.
199
  """
200
  hist: BaseChatMessageHistory = config["configurable"]["message_history"]
 
 
 
 
201
  messages = (await hist.aget_messages()).copy()
 
 
202
  if not self.history_messages_key:
203
  # return all messages
204
  input_val = (
 
214
 
215
  messages = self._get_chat_history(messages)
216
 
 
 
 
217
  return messages
218
 
219
 
code/modules/chat/llm_tutor.py CHANGED
@@ -41,10 +41,6 @@ class LLMTutor:
41
  """
42
  changes = self.get_config_changes(old_config, new_config)
43
 
44
- print("\n\n\n")
45
- print("Changes: ", changes)
46
- print("\n\n\n")
47
-
48
  if "llm_params.llm_loader" in changes:
49
  self.llm = self.load_llm() # Reinitialize LLM if chat_model changes
50
 
 
41
  """
42
  changes = self.get_config_changes(old_config, new_config)
43
 
 
 
 
 
44
  if "llm_params.llm_loader" in changes:
45
  self.llm = self.load_llm() # Reinitialize LLM if chat_model changes
46
 
code/modules/chat_processor/literal_ai.py CHANGED
@@ -37,8 +37,8 @@ class CustomLiteralDataLayer(ChainlitDataLayer):
37
  if step_dict.get("isError"):
38
  step["error"] = step_dict.get("output")
39
 
40
- print("\n\n\n")
41
- print("Step: ", step)
42
- print("\n\n\n")
43
 
44
  await self.client.api.send_steps([step])
 
37
  if step_dict.get("isError"):
38
  step["error"] = step_dict.get("output")
39
 
40
+ # print("\n\n\n")
41
+ # print("Step: ", step)
42
+ # print("\n\n\n")
43
 
44
  await self.client.api.send_steps([step])
code/modules/config/config.yml CHANGED
@@ -3,7 +3,7 @@ log_chunk_dir: '../storage/logs/chunks' # str
3
  device: 'cpu' # str [cuda, cpu]
4
 
5
  vectorstore:
6
- load_from_HF: False # bool
7
  embedd_files: False # bool
8
  data_path: '../storage/data' # str
9
  url_file_path: '../storage/data/urls.txt' # str
@@ -25,8 +25,9 @@ vectorstore:
25
  index_name: "new_idx" # str
26
 
27
  llm_params:
28
- llm_arch: 'langchain' # [langchain, langgraph_agentic]
29
  use_history: True # bool
 
30
  memory_window: 3 # int
31
  llm_style: 'Normal' # str [Normal, ELI5]
32
  llm_loader: 'gpt-4o-mini' # str [local_llm, gpt-3.5-turbo-1106, gpt-4, gpt-4o-mini]
@@ -34,12 +35,12 @@ llm_params:
34
  temperature: 0.7 # float
35
  local_llm_params:
36
  temperature: 0.7 # float
37
- stream: True # bool
38
 
39
  chat_logging:
40
- log_chat: False # bool
41
  platform: 'literalai'
42
- callbacks: True # bool
43
 
44
  splitter_options:
45
  use_splitter: True # bool
 
3
  device: 'cpu' # str [cuda, cpu]
4
 
5
  vectorstore:
6
+ load_from_HF: True # bool
7
  embedd_files: False # bool
8
  data_path: '../storage/data' # str
9
  url_file_path: '../storage/data/urls.txt' # str
 
25
  index_name: "new_idx" # str
26
 
27
  llm_params:
28
+ llm_arch: 'langchain' # [langchain]
29
  use_history: True # bool
30
+ generate_follow_up: False # bool
31
  memory_window: 3 # int
32
  llm_style: 'Normal' # str [Normal, ELI5]
33
  llm_loader: 'gpt-4o-mini' # str [local_llm, gpt-3.5-turbo-1106, gpt-4, gpt-4o-mini]
 
35
  temperature: 0.7 # float
36
  local_llm_params:
37
  temperature: 0.7 # float
38
+ stream: False # bool
39
 
40
  chat_logging:
41
+ log_chat: True # bool
42
  platform: 'literalai'
43
+ callbacks: False # bool
44
 
45
  splitter_options:
46
  use_splitter: True # bool
code/modules/config/prompts.py CHANGED
@@ -16,7 +16,9 @@ prompts = {
16
  "You are an AI Tutor for the course DS598, taught by Prof. Thomas Gardos. Answer the user's question using the provided context. Only use the context if it is relevant. The context is ordered by relevance. "
17
  "If you don't know the answer, do your best without making things up. Keep the conversation flowing naturally. "
18
  "Use chat history and context as guides but avoid repeating past responses. Provide links from the source_file metadata. Use the source context that is most relevant. "
 
19
  "Speak in a friendly and engaging manner, like talking to a friend. Avoid sounding repetitive or robotic.\n\n"
 
20
  "Chat History:\n{chat_history}\n\n"
21
  "Context:\n{context}\n\n"
22
  "Answer the student's question below in a friendly, concise, and engaging manner. Use the context and history only if relevant, otherwise, engage in a free-flowing conversation.\n"
@@ -24,15 +26,17 @@ prompts = {
24
  "AI Tutor:"
25
  ),
26
  "eli5": (
27
- "You are an AI Tutor for the course DS598, taught by Prof. Thomas Gardos. Answer the user's question in the simplest way possible, like explaining to someone new to the topic. Use the provided context to help clarify your explanation."
28
- "If you don't know the answer, do your best without making things up. Keep the conversation straightforward and easy to follow."
29
- "Use chat history and context as guides but avoid repeating past responses. Provide links from the source_file metadata when relevant. Use the source context that is most relevant."
30
- "Speak in a friendly and engaging manner, like talking to someone who is curious and eager to learn. Avoid using complex terms and jargon."
31
- "Use examples wherever possible to aid in understanding."
 
 
32
  "Chat History:\n{chat_history}\n\n"
33
  "Context:\n{context}\n\n"
34
- "Answer the student's question below in a friendly, simple, and engaging manner. Use the context and history only if relevant, otherwise, engage in a free-flowing conversation."
35
- "Give a clear and detailed explanation with examples to make it easier to understand."
36
  "Student: {input}\n"
37
  "AI Tutor:"
38
  ),
 
16
  "You are an AI Tutor for the course DS598, taught by Prof. Thomas Gardos. Answer the user's question using the provided context. Only use the context if it is relevant. The context is ordered by relevance. "
17
  "If you don't know the answer, do your best without making things up. Keep the conversation flowing naturally. "
18
  "Use chat history and context as guides but avoid repeating past responses. Provide links from the source_file metadata. Use the source context that is most relevant. "
19
+ "Render math equations in LaTeX format between $ or $$ signs, stick to the parameter and variable icons found in your context. Be sure to explain the parameters and variables in the equations."
20
  "Speak in a friendly and engaging manner, like talking to a friend. Avoid sounding repetitive or robotic.\n\n"
21
+ "Do not get influenced by the style of conversation in the chat history. Follow the instructions given here."
22
  "Chat History:\n{chat_history}\n\n"
23
  "Context:\n{context}\n\n"
24
  "Answer the student's question below in a friendly, concise, and engaging manner. Use the context and history only if relevant, otherwise, engage in a free-flowing conversation.\n"
 
26
  "AI Tutor:"
27
  ),
28
  "eli5": (
29
+ "You are an AI Tutor for the course DS598, taught by Prof. Thomas Gardos. Your job is to explain things in the simplest and most engaging way possible, just like the 'Explain Like I'm 5' (ELI5) concept."
30
+ "If you don't know the answer, do your best without making things up. Keep your explanations straightforward and very easy to understand."
31
+ "Use the chat history and context to help you, but avoid repeating past responses. Provide links from the source_file metadata when they're helpful."
32
+ "Use very simple language and examples to explain any math equations, and put the equations in LaTeX format between $ or $$ signs."
33
+ "Be friendly and engaging, like you're chatting with a young child who's curious and eager to learn. Avoid complex terms and jargon."
34
+ "Include simple and clear examples wherever you can to make things easier to understand."
35
+ "Do not get influenced by the style of conversation in the chat history. Follow the instructions given here."
36
  "Chat History:\n{chat_history}\n\n"
37
  "Context:\n{context}\n\n"
38
+ "Answer the student's question below in a friendly, simple, and engaging way, just like the ELI5 concept. Use the context and history only if they're relevant, otherwise, just have a natural conversation."
39
+ "Give a clear and detailed explanation with simple examples to make it easier to understand. Remember, your goal is to break down complex topics into very simple terms, just like ELI5."
40
  "Student: {input}\n"
41
  "AI Tutor:"
42
  ),