Spaces:
Build error
Build error
Merge pull request #59 from DL4DS/minor_fix
Browse files- .gitignore +2 -1
- code/.chainlit/config.toml +5 -5
- code/main.py +27 -19
- code/modules/chat/chat_model_loader.py +1 -1
- code/modules/chat/helpers.py +6 -2
- code/modules/chat/langchain/langchain_rag.py +3 -3
- code/modules/chat/langchain/utils.py +8 -3
- code/modules/config/config.yml +2 -1
- code/public/avatars/{ai-tutor.png → ai_tutor.png} +0 -0
- code/public/test.css +0 -19
- requirements.txt +1 -1
.gitignore
CHANGED
|
@@ -169,4 +169,5 @@ code/.chainlit/translations/
|
|
| 169 |
storage/logs/*
|
| 170 |
vectorstores/*
|
| 171 |
|
| 172 |
-
*/.files/*
|
|
|
|
|
|
| 169 |
storage/logs/*
|
| 170 |
vectorstores/*
|
| 171 |
|
| 172 |
+
*/.files/*
|
| 173 |
+
code/storage/models/
|
code/.chainlit/config.toml
CHANGED
|
@@ -61,11 +61,11 @@ name = "AI Tutor"
|
|
| 61 |
# Large size content are by default collapsed for a cleaner ui
|
| 62 |
default_collapse_content = true
|
| 63 |
|
| 64 |
-
#
|
| 65 |
-
|
| 66 |
|
| 67 |
# Link to your github repo. This will add a github button in the UI's header.
|
| 68 |
-
|
| 69 |
|
| 70 |
# Specify a CSS file that can be used to customize the user interface.
|
| 71 |
# The CSS file can be served from the public directory or via an external link.
|
|
@@ -87,7 +87,7 @@ custom_meta_image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/
|
|
| 87 |
# custom_build = "./public/build"
|
| 88 |
|
| 89 |
[UI.theme]
|
| 90 |
-
default = "
|
| 91 |
#layout = "wide"
|
| 92 |
#font_family = "Inter, sans-serif"
|
| 93 |
# Override default MUI light theme. (Check theme.ts)
|
|
@@ -117,4 +117,4 @@ custom_meta_image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/
|
|
| 117 |
#secondary = "#BDBDBD"
|
| 118 |
|
| 119 |
[meta]
|
| 120 |
-
generated_by = "1.1.
|
|
|
|
| 61 |
# Large size content are by default collapsed for a cleaner ui
|
| 62 |
default_collapse_content = true
|
| 63 |
|
| 64 |
+
# Chain of Thought (CoT) display mode. Can be "hidden", "tool_call" or "full".
|
| 65 |
+
cot = "hidden"
|
| 66 |
|
| 67 |
# Link to your github repo. This will add a github button in the UI's header.
|
| 68 |
+
github = "https://github.com/DL4DS/dl4ds_tutor"
|
| 69 |
|
| 70 |
# Specify a CSS file that can be used to customize the user interface.
|
| 71 |
# The CSS file can be served from the public directory or via an external link.
|
|
|
|
| 87 |
# custom_build = "./public/build"
|
| 88 |
|
| 89 |
[UI.theme]
|
| 90 |
+
default = "light"
|
| 91 |
#layout = "wide"
|
| 92 |
#font_family = "Inter, sans-serif"
|
| 93 |
# Override default MUI light theme. (Check theme.ts)
|
|
|
|
| 117 |
#secondary = "#BDBDBD"
|
| 118 |
|
| 119 |
[meta]
|
| 120 |
+
generated_by = "1.1.402"
|
code/main.py
CHANGED
|
@@ -23,11 +23,11 @@ from chainlit.types import ThreadDict
|
|
| 23 |
import time
|
| 24 |
|
| 25 |
USER_TIMEOUT = 60_000
|
| 26 |
-
SYSTEM = "System
|
| 27 |
-
LLM = "
|
| 28 |
-
AGENT = "Agent
|
| 29 |
-
YOU = "
|
| 30 |
-
ERROR = "Error
|
| 31 |
|
| 32 |
with open("modules/config/config.yml", "r") as f:
|
| 33 |
config = yaml.safe_load(f)
|
|
@@ -111,11 +111,6 @@ class Chatbot:
|
|
| 111 |
) # update only llm attributes that are changed
|
| 112 |
self.chain = self.llm_tutor.qa_bot(
|
| 113 |
memory=conversation_list,
|
| 114 |
-
callbacks=(
|
| 115 |
-
[cl.LangchainCallbackHandler()]
|
| 116 |
-
if cl_data._data_layer and self.config["chat_logging"]["callbacks"]
|
| 117 |
-
else None
|
| 118 |
-
),
|
| 119 |
)
|
| 120 |
|
| 121 |
cl.user_session.set("chain", self.chain)
|
|
@@ -279,7 +274,7 @@ class Chatbot:
|
|
| 279 |
Returns:
|
| 280 |
str: The renamed author.
|
| 281 |
"""
|
| 282 |
-
rename_dict = {"Chatbot":
|
| 283 |
return rename_dict.get(orig_author, orig_author)
|
| 284 |
|
| 285 |
async def start(self, config=None):
|
|
@@ -318,11 +313,6 @@ class Chatbot:
|
|
| 318 |
|
| 319 |
self.chain = self.llm_tutor.qa_bot(
|
| 320 |
memory=memory,
|
| 321 |
-
callbacks=(
|
| 322 |
-
[cl.LangchainCallbackHandler()]
|
| 323 |
-
if cl_data._data_layer and self.config["chat_logging"]["callbacks"]
|
| 324 |
-
else None
|
| 325 |
-
),
|
| 326 |
)
|
| 327 |
self.question_generator = self.llm_tutor.question_generator
|
| 328 |
cl.user_session.set("llm_tutor", self.llm_tutor)
|
|
@@ -375,7 +365,12 @@ class Chatbot:
|
|
| 375 |
"user_id": self.user["user_id"],
|
| 376 |
"conversation_id": self.user["session_id"],
|
| 377 |
"memory_window": self.config["llm_params"]["memory_window"],
|
| 378 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
}
|
| 380 |
|
| 381 |
if stream:
|
|
@@ -400,11 +395,20 @@ class Chatbot:
|
|
| 400 |
|
| 401 |
if self.config["llm_params"]["generate_follow_up"]:
|
| 402 |
start_time = time.time()
|
| 403 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 404 |
query=user_query_dict["input"],
|
| 405 |
response=answer,
|
| 406 |
chat_history=res.get("chat_history"),
|
| 407 |
context=res.get("context"),
|
|
|
|
| 408 |
)
|
| 409 |
|
| 410 |
for question in list_of_questions:
|
|
@@ -456,7 +460,11 @@ class Chatbot:
|
|
| 456 |
type="user_message",
|
| 457 |
author=self.user["user_id"],
|
| 458 |
).send()
|
| 459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 460 |
|
| 461 |
|
| 462 |
chatbot = Chatbot(config=config)
|
|
|
|
| 23 |
import time
|
| 24 |
|
| 25 |
USER_TIMEOUT = 60_000
|
| 26 |
+
SYSTEM = "System"
|
| 27 |
+
LLM = "AI Tutor"
|
| 28 |
+
AGENT = "Agent"
|
| 29 |
+
YOU = "User"
|
| 30 |
+
ERROR = "Error"
|
| 31 |
|
| 32 |
with open("modules/config/config.yml", "r") as f:
|
| 33 |
config = yaml.safe_load(f)
|
|
|
|
| 111 |
) # update only llm attributes that are changed
|
| 112 |
self.chain = self.llm_tutor.qa_bot(
|
| 113 |
memory=conversation_list,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
)
|
| 115 |
|
| 116 |
cl.user_session.set("chain", self.chain)
|
|
|
|
| 274 |
Returns:
|
| 275 |
str: The renamed author.
|
| 276 |
"""
|
| 277 |
+
rename_dict = {"Chatbot": LLM}
|
| 278 |
return rename_dict.get(orig_author, orig_author)
|
| 279 |
|
| 280 |
async def start(self, config=None):
|
|
|
|
| 313 |
|
| 314 |
self.chain = self.llm_tutor.qa_bot(
|
| 315 |
memory=memory,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
)
|
| 317 |
self.question_generator = self.llm_tutor.question_generator
|
| 318 |
cl.user_session.set("llm_tutor", self.llm_tutor)
|
|
|
|
| 365 |
"user_id": self.user["user_id"],
|
| 366 |
"conversation_id": self.user["session_id"],
|
| 367 |
"memory_window": self.config["llm_params"]["memory_window"],
|
| 368 |
+
},
|
| 369 |
+
"callbacks": (
|
| 370 |
+
[cl.LangchainCallbackHandler()]
|
| 371 |
+
if cl_data._data_layer and self.config["chat_logging"]["callbacks"]
|
| 372 |
+
else None
|
| 373 |
+
),
|
| 374 |
}
|
| 375 |
|
| 376 |
if stream:
|
|
|
|
| 395 |
|
| 396 |
if self.config["llm_params"]["generate_follow_up"]:
|
| 397 |
start_time = time.time()
|
| 398 |
+
config = {
|
| 399 |
+
"callbacks": (
|
| 400 |
+
[cl.LangchainCallbackHandler()]
|
| 401 |
+
if cl_data._data_layer and self.config["chat_logging"]["callbacks"]
|
| 402 |
+
else None
|
| 403 |
+
)
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
list_of_questions = await self.question_generator.generate_questions(
|
| 407 |
query=user_query_dict["input"],
|
| 408 |
response=answer,
|
| 409 |
chat_history=res.get("chat_history"),
|
| 410 |
context=res.get("context"),
|
| 411 |
+
config=config,
|
| 412 |
)
|
| 413 |
|
| 414 |
for question in list_of_questions:
|
|
|
|
| 460 |
type="user_message",
|
| 461 |
author=self.user["user_id"],
|
| 462 |
).send()
|
| 463 |
+
async with cl.Step(
|
| 464 |
+
name="on_follow_up", type="run", parent_id=message.id
|
| 465 |
+
) as step:
|
| 466 |
+
await self.main(message)
|
| 467 |
+
step.output = message.content
|
| 468 |
|
| 469 |
|
| 470 |
chatbot = Chatbot(config=config)
|
code/modules/chat/chat_model_loader.py
CHANGED
|
@@ -28,7 +28,7 @@ class ChatModelLoader:
|
|
| 28 |
elif self.config["llm_params"]["llm_loader"] == "local_llm":
|
| 29 |
n_batch = 512 # Should be between 1 and n_ctx, consider the amount of VRAM in your GPU.
|
| 30 |
model_path = self._verify_model_cache(
|
| 31 |
-
self.config["llm_params"]["local_llm_params"]["
|
| 32 |
)
|
| 33 |
llm = LlamaCpp(
|
| 34 |
model_path=model_path,
|
|
|
|
| 28 |
elif self.config["llm_params"]["llm_loader"] == "local_llm":
|
| 29 |
n_batch = 512 # Should be between 1 and n_ctx, consider the amount of VRAM in your GPU.
|
| 30 |
model_path = self._verify_model_cache(
|
| 31 |
+
self.config["llm_params"]["local_llm_params"]["model_path"]
|
| 32 |
)
|
| 33 |
llm = LlamaCpp(
|
| 34 |
model_path=model_path,
|
code/modules/chat/helpers.py
CHANGED
|
@@ -110,6 +110,7 @@ def get_prompt(config, prompt_type):
|
|
| 110 |
return prompts["openai"]["rephrase_prompt"]
|
| 111 |
|
| 112 |
|
|
|
|
| 113 |
def get_history_chat_resume(steps, k, SYSTEM, LLM):
|
| 114 |
conversation_list = []
|
| 115 |
count = 0
|
|
@@ -119,14 +120,17 @@ def get_history_chat_resume(steps, k, SYSTEM, LLM):
|
|
| 119 |
conversation_list.append(
|
| 120 |
{"type": "user_message", "content": step["output"]}
|
| 121 |
)
|
|
|
|
| 122 |
elif step["type"] == "assistant_message":
|
| 123 |
if step["name"] == LLM:
|
| 124 |
conversation_list.append(
|
| 125 |
{"type": "ai_message", "content": step["output"]}
|
| 126 |
)
|
|
|
|
| 127 |
else:
|
| 128 |
-
|
| 129 |
-
|
|
|
|
| 130 |
if count >= 2 * k: # 2 * k to account for both user and assistant messages
|
| 131 |
break
|
| 132 |
conversation_list = conversation_list[::-1]
|
|
|
|
| 110 |
return prompts["openai"]["rephrase_prompt"]
|
| 111 |
|
| 112 |
|
| 113 |
+
# TODO: Do this better
|
| 114 |
def get_history_chat_resume(steps, k, SYSTEM, LLM):
|
| 115 |
conversation_list = []
|
| 116 |
count = 0
|
|
|
|
| 120 |
conversation_list.append(
|
| 121 |
{"type": "user_message", "content": step["output"]}
|
| 122 |
)
|
| 123 |
+
count += 1
|
| 124 |
elif step["type"] == "assistant_message":
|
| 125 |
if step["name"] == LLM:
|
| 126 |
conversation_list.append(
|
| 127 |
{"type": "ai_message", "content": step["output"]}
|
| 128 |
)
|
| 129 |
+
count += 1
|
| 130 |
else:
|
| 131 |
+
pass
|
| 132 |
+
# raise ValueError("Invalid message type")
|
| 133 |
+
# count += 1
|
| 134 |
if count >= 2 * k: # 2 * k to account for both user and assistant messages
|
| 135 |
break
|
| 136 |
conversation_list = conversation_list[::-1]
|
code/modules/chat/langchain/langchain_rag.py
CHANGED
|
@@ -100,8 +100,8 @@ class QuestionGenerator:
|
|
| 100 |
def __init__(self):
|
| 101 |
pass
|
| 102 |
|
| 103 |
-
def generate_questions(self, query, response, chat_history, context):
|
| 104 |
-
questions = return_questions(query, response, chat_history, context)
|
| 105 |
return questions
|
| 106 |
|
| 107 |
|
|
@@ -204,7 +204,7 @@ class Langchain_RAG_V2(BaseRAG):
|
|
| 204 |
is_shared=True,
|
| 205 |
),
|
| 206 |
],
|
| 207 |
-
)
|
| 208 |
|
| 209 |
if callbacks is not None:
|
| 210 |
self.rag_chain = self.rag_chain.with_config(callbacks=callbacks)
|
|
|
|
| 100 |
def __init__(self):
|
| 101 |
pass
|
| 102 |
|
| 103 |
+
def generate_questions(self, query, response, chat_history, context, config):
|
| 104 |
+
questions = return_questions(query, response, chat_history, context, config)
|
| 105 |
return questions
|
| 106 |
|
| 107 |
|
|
|
|
| 204 |
is_shared=True,
|
| 205 |
),
|
| 206 |
],
|
| 207 |
+
).with_config(run_name="Langchain_RAG_V2")
|
| 208 |
|
| 209 |
if callbacks is not None:
|
| 210 |
self.rag_chain = self.rag_chain.with_config(callbacks=callbacks)
|
code/modules/chat/langchain/utils.py
CHANGED
|
@@ -280,7 +280,8 @@ def create_retrieval_chain(
|
|
| 280 |
return retrieval_chain
|
| 281 |
|
| 282 |
|
| 283 |
-
|
|
|
|
| 284 |
|
| 285 |
system = (
|
| 286 |
"You are someone that suggests a question based on the student's input and chat history. "
|
|
@@ -303,13 +304,17 @@ def return_questions(query, response, chat_history_str, context):
|
|
| 303 |
)
|
| 304 |
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
|
| 305 |
question_generator = prompt | llm | StrOutputParser()
|
| 306 |
-
|
|
|
|
|
|
|
|
|
|
| 307 |
{
|
| 308 |
"chat_history_str": chat_history_str,
|
| 309 |
"context": context,
|
| 310 |
"query": query,
|
| 311 |
"response": response,
|
| 312 |
-
}
|
|
|
|
| 313 |
)
|
| 314 |
|
| 315 |
list_of_questions = new_questions.split("...")
|
|
|
|
| 280 |
return retrieval_chain
|
| 281 |
|
| 282 |
|
| 283 |
+
# TODO: Remove Hard-coded values
|
| 284 |
+
async def return_questions(query, response, chat_history_str, context, config):
|
| 285 |
|
| 286 |
system = (
|
| 287 |
"You are someone that suggests a question based on the student's input and chat history. "
|
|
|
|
| 304 |
)
|
| 305 |
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
|
| 306 |
question_generator = prompt | llm | StrOutputParser()
|
| 307 |
+
question_generator = question_generator.with_config(
|
| 308 |
+
run_name="follow_up_question_generator"
|
| 309 |
+
)
|
| 310 |
+
new_questions = await question_generator.ainvoke(
|
| 311 |
{
|
| 312 |
"chat_history_str": chat_history_str,
|
| 313 |
"context": context,
|
| 314 |
"query": query,
|
| 315 |
"response": response,
|
| 316 |
+
},
|
| 317 |
+
config=config,
|
| 318 |
)
|
| 319 |
|
| 320 |
list_of_questions = new_questions.split("...")
|
code/modules/config/config.yml
CHANGED
|
@@ -37,13 +37,14 @@ llm_params:
|
|
| 37 |
temperature: 0.7 # float
|
| 38 |
repo_id: 'TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF' # HuggingFace repo id
|
| 39 |
filename: 'tinyllama-1.1b-chat-v1.0.Q5_0.gguf' # Specific name of gguf file in the repo
|
|
|
|
| 40 |
stream: False # bool
|
| 41 |
pdf_reader: 'gpt' # str [llama, pymupdf, gpt]
|
| 42 |
|
| 43 |
chat_logging:
|
| 44 |
log_chat: True # bool
|
| 45 |
platform: 'literalai'
|
| 46 |
-
callbacks:
|
| 47 |
|
| 48 |
splitter_options:
|
| 49 |
use_splitter: True # bool
|
|
|
|
| 37 |
temperature: 0.7 # float
|
| 38 |
repo_id: 'TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF' # HuggingFace repo id
|
| 39 |
filename: 'tinyllama-1.1b-chat-v1.0.Q5_0.gguf' # Specific name of gguf file in the repo
|
| 40 |
+
model_path: 'storage/models/tinyllama-1.1b-chat-v1.0.Q5_0.gguf' # Path to the model file
|
| 41 |
stream: False # bool
|
| 42 |
pdf_reader: 'gpt' # str [llama, pymupdf, gpt]
|
| 43 |
|
| 44 |
chat_logging:
|
| 45 |
log_chat: True # bool
|
| 46 |
platform: 'literalai'
|
| 47 |
+
callbacks: True # bool
|
| 48 |
|
| 49 |
splitter_options:
|
| 50 |
use_splitter: True # bool
|
code/public/avatars/{ai-tutor.png → ai_tutor.png}
RENAMED
|
File without changes
|
code/public/test.css
CHANGED
|
@@ -13,10 +13,6 @@ a[href*='https://github.com/Chainlit/chainlit'] {
|
|
| 13 |
border-radius: 50%; /* Maintain circular shape */
|
| 14 |
}
|
| 15 |
|
| 16 |
-
/* Hide the default image */
|
| 17 |
-
.MuiAvatar-root.MuiAvatar-circular.css-m2icte .MuiAvatar-img.css-1hy9t21 {
|
| 18 |
-
display: none;
|
| 19 |
-
}
|
| 20 |
|
| 21 |
.MuiAvatar-root.MuiAvatar-circular.css-v72an7 {
|
| 22 |
background-image: url('/public/avatars/ai-tutor.png'); /* Replace with your custom image URL */
|
|
@@ -26,18 +22,3 @@ a[href*='https://github.com/Chainlit/chainlit'] {
|
|
| 26 |
height: 40px; /* Ensure the dimensions match the original */
|
| 27 |
border-radius: 50%; /* Maintain circular shape */
|
| 28 |
}
|
| 29 |
-
|
| 30 |
-
/* Hide the default image */
|
| 31 |
-
.MuiAvatar-root.MuiAvatar-circular.css-v72an7 .MuiAvatar-img.css-1hy9t21 {
|
| 32 |
-
display: none;
|
| 33 |
-
}
|
| 34 |
-
|
| 35 |
-
/* Hide the new chat button
|
| 36 |
-
#new-chat-button {
|
| 37 |
-
display: none;
|
| 38 |
-
} */
|
| 39 |
-
|
| 40 |
-
/* Hide the open sidebar button
|
| 41 |
-
#open-sidebar-button {
|
| 42 |
-
display: none;
|
| 43 |
-
} */
|
|
|
|
| 13 |
border-radius: 50%; /* Maintain circular shape */
|
| 14 |
}
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
.MuiAvatar-root.MuiAvatar-circular.css-v72an7 {
|
| 18 |
background-image: url('/public/avatars/ai-tutor.png'); /* Replace with your custom image URL */
|
|
|
|
| 22 |
height: 40px; /* Ensure the dimensions match the original */
|
| 23 |
border-radius: 50%; /* Maintain circular shape */
|
| 24 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
|
@@ -23,7 +23,7 @@ llama-cpp-python
|
|
| 23 |
pymupdf
|
| 24 |
websockets
|
| 25 |
langchain-openai
|
| 26 |
-
|
| 27 |
html2text
|
| 28 |
PyPDF2
|
| 29 |
pdf2image
|
|
|
|
| 23 |
pymupdf
|
| 24 |
websockets
|
| 25 |
langchain-openai
|
| 26 |
+
langchain-experimental
|
| 27 |
html2text
|
| 28 |
PyPDF2
|
| 29 |
pdf2image
|