Spaces:
Running
Running
sravan
commited on
Commit
·
8e70769
1
Parent(s):
39ecd8e
rag app
Browse files- app/.DS_Store → .DS_Store +0 -0
- .gitignore +4 -1
- Dockerfile +0 -20
- app.py +2 -6
- app/Backend/Dockerfile +0 -20
- app/Backend/app.py +0 -5
- app/Backend/requirements.txt +0 -9
- app/Frontend/README.md +0 -12
- app/Frontend/app.py +0 -12
- app/Frontend/pages/__pycache__/page_base.cpython-310.pyc +0 -0
- app/Frontend/pages/filtered_rag_page.py +0 -9
- app/Frontend/pages/formatted_page.py +0 -9
- app/Frontend/pages/history_page.py +0 -9
- app/Frontend/pages/page_base.py +0 -48
- app/Frontend/pages/rag_page.py +0 -9
- app/Frontend/pages/simple_page.py +0 -12
- app/Frontend/requirements.txt +0 -1
- app/Backend/app/callbacks.py → callbacks.py +13 -1
- app/Backend/app/chains.py → chains.py +23 -7
- app/Backend/app/crud.py → crud.py +23 -2
- app/Backend/app/data_indexing.py → data_indexing.py +37 -20
- app/Backend/app/database.py → database.py +0 -0
- app/Backend/app/main.py → main.py +103 -7
- app/Backend/app/models.py → models.py +9 -1
- app/Backend/app/prompts.py → prompts.py +45 -11
- requirements.txt +109 -2
- app/Backend/app/schemas.py → schemas.py +16 -2
- test.db +0 -0
app/.DS_Store → .DS_Store
RENAMED
Binary files a/app/.DS_Store and b/.DS_Store differ
|
|
.gitignore
CHANGED
@@ -1 +1,4 @@
|
|
1 |
-
myenv
|
|
|
|
|
|
|
|
1 |
+
myenv
|
2 |
+
*pycache*
|
3 |
+
|
4 |
+
|
Dockerfile
DELETED
@@ -1,20 +0,0 @@
|
|
1 |
-
FROM python:3.12
|
2 |
-
# Create a new user named 'user' with user ID 1000 and create their home directory
|
3 |
-
RUN useradd -m -u 1000 user
|
4 |
-
# Switch to the newly created user
|
5 |
-
USER user
|
6 |
-
# Add the user's local bin directory to the PATH
|
7 |
-
ENV PATH="/home/user/.local/bin:$PATH"
|
8 |
-
# Set the working directory in the container to /app
|
9 |
-
WORKDIR /app
|
10 |
-
# Copy the requirements.txt file from the host to the container
|
11 |
-
# The --chown=user ensures the copied file is owned by our 'user'
|
12 |
-
# RUN --mount=type=secret,id=HF_TOKEN,mode=0444,required=true
|
13 |
-
COPY --chown=user ./requirements.txt requirements.txt
|
14 |
-
# Install the Python dependencies listed in requirements.txt
|
15 |
-
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
16 |
-
# Copy the rest of the application code from the host to the container
|
17 |
-
# Again, ensure the copied files are owned by 'user'
|
18 |
-
COPY --chown=user . /app
|
19 |
-
# Specify the command to run when the container starts
|
20 |
-
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
CHANGED
@@ -1,9 +1,5 @@
|
|
1 |
from fastapi import FastAPI
|
2 |
-
|
3 |
app = FastAPI()
|
4 |
-
|
5 |
@app.get("/")
|
6 |
-
def
|
7 |
-
return {"Hello": "World"}
|
8 |
-
|
9 |
-
|
|
|
1 |
from fastapi import FastAPI
|
|
|
2 |
app = FastAPI()
|
|
|
3 |
@app.get("/")
|
4 |
+
def greet_json():
|
5 |
+
return {"Hello": "World!"}
|
|
|
|
app/Backend/Dockerfile
DELETED
@@ -1,20 +0,0 @@
|
|
1 |
-
FROM python:3.12
|
2 |
-
# Create a new user named 'user' with user ID 1000 and create their home directory
|
3 |
-
RUN useradd -m -u 1000 user
|
4 |
-
# Switch to the newly created user
|
5 |
-
USER user
|
6 |
-
# Add the user's local bin directory to the PATH
|
7 |
-
ENV PATH="/home/user/.local/bin:$PATH"
|
8 |
-
# Set the working directory in the container to /app
|
9 |
-
WORKDIR /app
|
10 |
-
# Copy the requirements.txt file from the host to the container
|
11 |
-
# The --chown=user ensures the copied file is owned by our 'user'
|
12 |
-
RUN --mount=type=secret,id=HF_TOKEN,mode=0444,required=true
|
13 |
-
COPY --chown=user ./requirements.txt requirements.txt
|
14 |
-
# Install the Python dependencies listed in requirements.txt
|
15 |
-
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
16 |
-
# Copy the rest of the application code from the host to the container
|
17 |
-
# Again, ensure the copied files are owned by 'user'
|
18 |
-
COPY --chown=user . /app
|
19 |
-
# Specify the command to run when the container starts
|
20 |
-
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Backend/app.py
DELETED
@@ -1,5 +0,0 @@
|
|
1 |
-
from fastapi import FastAPI
|
2 |
-
app = FastAPI()
|
3 |
-
@app.get("/")
|
4 |
-
def greet_json():
|
5 |
-
return {"Hello": "World!"}
|
|
|
|
|
|
|
|
|
|
|
|
app/Backend/requirements.txt
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
fastapi
|
2 |
-
uvicorn[standard]
|
3 |
-
sse-starlette
|
4 |
-
langchain-core
|
5 |
-
langserve
|
6 |
-
sqlalchemy
|
7 |
-
langchain-huggingface
|
8 |
-
transformers
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/README.md
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Frontend
|
3 |
-
emoji: 🚀
|
4 |
-
colorFrom: indigo
|
5 |
-
colorTo: purple
|
6 |
-
sdk: streamlit
|
7 |
-
sdk_version: 1.37.1
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
---
|
11 |
-
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/app.py
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
|
3 |
-
pg = st.navigation([
|
4 |
-
st.Page("pages/simple_page.py"),
|
5 |
-
st.Page("pages/formatted_page.py"),
|
6 |
-
st.Page("pages/history_page.py"),
|
7 |
-
st.Page("pages/rag_page.py"),
|
8 |
-
st.Page("pages/filtered_rag_page.py"),
|
9 |
-
])
|
10 |
-
pg.run()
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/pages/__pycache__/page_base.cpython-310.pyc
DELETED
Binary file (1.35 kB)
|
|
app/Frontend/pages/filtered_rag_page.py
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
from streamlit.runtime.scriptrunner import get_script_run_ctx
|
2 |
-
from pages.page_base import chat_interface
|
3 |
-
|
4 |
-
|
5 |
-
chat_title = "Filtered RAG Chat App"
|
6 |
-
url = "[YOUR FILTERED RAG URL]"
|
7 |
-
page_hash = get_script_run_ctx().page_script_hash
|
8 |
-
|
9 |
-
chat_interface(chat_title, page_hash, url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/pages/formatted_page.py
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
from streamlit.runtime.scriptrunner import get_script_run_ctx
|
2 |
-
from pages.page_base import chat_interface
|
3 |
-
|
4 |
-
|
5 |
-
chat_title = "Formatted Chat App"
|
6 |
-
url = "[YOUR FORMATTED CHAT URL]"
|
7 |
-
page_hash = get_script_run_ctx().page_script_hash
|
8 |
-
|
9 |
-
chat_interface(chat_title, page_hash, url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/pages/history_page.py
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
from streamlit.runtime.scriptrunner import get_script_run_ctx
|
2 |
-
from pages.page_base import chat_interface
|
3 |
-
|
4 |
-
|
5 |
-
chat_title = "History Chat App"
|
6 |
-
url = "[YOUR HISTORY CHAT URL]"
|
7 |
-
page_hash = get_script_run_ctx().page_script_hash
|
8 |
-
|
9 |
-
chat_interface(chat_title, page_hash, url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/pages/page_base.py
DELETED
@@ -1,48 +0,0 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
from langserve.client import RemoteRunnable
|
3 |
-
|
4 |
-
def get_response(user_input, url, username):
|
5 |
-
response_placeholder = st.empty()
|
6 |
-
full_response = ""
|
7 |
-
chain = RemoteRunnable(url)
|
8 |
-
stream = chain.stream(input={'question': user_input, 'username': username})
|
9 |
-
for chunk in stream:
|
10 |
-
full_response += chunk
|
11 |
-
response_placeholder.markdown(full_response)
|
12 |
-
|
13 |
-
return full_response
|
14 |
-
|
15 |
-
def chat_interface(chat_title, page_hash ,url):
|
16 |
-
st.title(chat_title)
|
17 |
-
|
18 |
-
# Add username input at the top of the page
|
19 |
-
username = st.text_input("Enter your username:", key="username_input", value="Guest")
|
20 |
-
|
21 |
-
# Initialize page-specific chat history
|
22 |
-
if "chat_histories" not in st.session_state:
|
23 |
-
st.session_state.chat_histories = {}
|
24 |
-
|
25 |
-
if page_hash not in st.session_state.chat_histories:
|
26 |
-
st.session_state.chat_histories[page_hash] = []
|
27 |
-
|
28 |
-
# Display chat messages from history for the current page
|
29 |
-
for message in st.session_state.chat_histories[page_hash]:
|
30 |
-
with st.chat_message(message["role"]):
|
31 |
-
st.markdown(message["content"])
|
32 |
-
|
33 |
-
# React to user input
|
34 |
-
if prompt := st.chat_input("What is your message?"):
|
35 |
-
# Display user message in chat message container
|
36 |
-
st.chat_message("user").markdown(prompt)
|
37 |
-
# Add user message to chat history
|
38 |
-
st.session_state.chat_histories[page_hash].append({"role": "user", "content": prompt})
|
39 |
-
|
40 |
-
# Get streaming response
|
41 |
-
with st.chat_message("assistant"):
|
42 |
-
full_response = get_response(prompt, url, username)
|
43 |
-
|
44 |
-
# Add assistant response to chat history
|
45 |
-
st.session_state.chat_histories[page_hash].append({"role": "assistant", "content": full_response})
|
46 |
-
|
47 |
-
if __name__ == "__main__":
|
48 |
-
chat_interface()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/pages/rag_page.py
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
from streamlit.runtime.scriptrunner import get_script_run_ctx
|
2 |
-
from pages.page_base import chat_interface
|
3 |
-
|
4 |
-
|
5 |
-
chat_title = "RAG Chat App"
|
6 |
-
url = "[YOUR RAG CHAT URL]"
|
7 |
-
page_hash = get_script_run_ctx().page_script_hash
|
8 |
-
|
9 |
-
chat_interface(chat_title, page_hash, url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/pages/simple_page.py
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
# import streamlit as st
|
2 |
-
# import time
|
3 |
-
# from langserve import RemoteRunnable
|
4 |
-
from streamlit.runtime.scriptrunner import get_script_run_ctx
|
5 |
-
import streamlit as st
|
6 |
-
from pages.page_base import chat_interface
|
7 |
-
|
8 |
-
chat_title = "Simple Chat App"
|
9 |
-
url = "https://damienbenveniste-backend.hf.space/simple"
|
10 |
-
page_hash = get_script_run_ctx().page_script_hash
|
11 |
-
|
12 |
-
chat_interface(chat_title, page_hash, url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Frontend/requirements.txt
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
langserve[client]
|
|
|
|
app/Backend/app/callbacks.py → callbacks.py
RENAMED
@@ -15,7 +15,19 @@ class LogResponseCallback(BaseCallbackHandler):
|
|
15 |
"""Run when llm ends running."""
|
16 |
# TODO: The function on_llm_end is going to be called when the LLM stops sending
|
17 |
# the response. Use the crud.add_message function to capture that response.
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
def on_llm_start(
|
21 |
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
|
|
|
15 |
"""Run when llm ends running."""
|
16 |
# TODO: The function on_llm_end is going to be called when the LLM stops sending
|
17 |
# the response. Use the crud.add_message function to capture that response.
|
18 |
+
type = 'AI'
|
19 |
+
user_data = crud.get_or_create(db, self.user_request.username)
|
20 |
+
user_id = user_data.user_id
|
21 |
+
timestamp = datetime.now()
|
22 |
+
message = outputs.generations[0][0].text # answer from the prompt message
|
23 |
+
message_to_add = schemas.MessageBase(
|
24 |
+
user_id = user_id,
|
25 |
+
message = message,
|
26 |
+
type = type,
|
27 |
+
timestamp = timestamp
|
28 |
+
)
|
29 |
+
_ = crud.add_message(self.db, message_to_add, self.user_request.username )
|
30 |
+
# raise NotImplemented
|
31 |
|
32 |
def on_llm_start(
|
33 |
self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
|
app/Backend/app/chains.py → chains.py
RENAMED
@@ -1,50 +1,66 @@
|
|
1 |
import os
|
2 |
from langchain_huggingface import HuggingFaceEndpoint
|
3 |
from langchain_core.runnables import RunnablePassthrough
|
|
|
4 |
import schemas
|
|
|
5 |
from prompts import (
|
6 |
raw_prompt,
|
7 |
raw_prompt_formatted,
|
8 |
format_context,
|
9 |
-
|
|
|
|
|
10 |
)
|
11 |
from data_indexing import DataIndexer
|
|
|
12 |
|
13 |
data_indexer = DataIndexer()
|
14 |
|
|
|
|
|
15 |
llm = HuggingFaceEndpoint(
|
16 |
repo_id="meta-llama/Meta-Llama-3-8B-Instruct",
|
|
|
17 |
huggingfacehub_api_token=os.environ['HF_TOKEN'],
|
18 |
max_new_tokens=512,
|
19 |
stop_sequences=[tokenizer.eos_token],
|
20 |
streaming=True,
|
|
|
|
|
21 |
)
|
22 |
|
23 |
simple_chain = (raw_prompt | llm).with_types(input_type=schemas.UserQuestion)
|
24 |
|
25 |
# TODO: create formatted_chain by piping raw_prompt_formatted and the LLM endpoint.
|
26 |
-
formatted_chain = (raw_prompt_formatted | llm).with_types(
|
27 |
|
28 |
# TODO: use history_prompt_formatted and HistoryInput to create the history_chain
|
29 |
-
history_chain =
|
30 |
|
31 |
# TODO: Let's construct the standalone_chain by piping standalone_prompt_formatted with the LLM
|
32 |
-
standalone_chain =
|
33 |
|
34 |
input_1 = RunnablePassthrough.assign(new_question=standalone_chain)
|
35 |
input_2 = {
|
36 |
'context': lambda x: format_context(data_indexer.search(x['new_question'])),
|
37 |
-
'standalone_question': lambda x: x['new_question']
|
38 |
}
|
39 |
input_to_rag_chain = input_1 | input_2
|
40 |
|
41 |
# TODO: use input_to_rag_chain, rag_prompt_formatted,
|
42 |
# HistoryInput and the LLM to build the rag_chain.
|
43 |
-
rag_chain =
|
44 |
|
45 |
# TODO: Implement the filtered_rag_chain. It should be the
|
46 |
# same as the rag_chain but with hybrid_search = True.
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
|
50 |
|
|
|
1 |
import os
|
2 |
from langchain_huggingface import HuggingFaceEndpoint
|
3 |
from langchain_core.runnables import RunnablePassthrough
|
4 |
+
|
5 |
import schemas
|
6 |
+
import prompts
|
7 |
from prompts import (
|
8 |
raw_prompt,
|
9 |
raw_prompt_formatted,
|
10 |
format_context,
|
11 |
+
history_prompt_formatted,
|
12 |
+
standalone_prompt_formatted,
|
13 |
+
rag_prompt_formatted
|
14 |
)
|
15 |
from data_indexing import DataIndexer
|
16 |
+
from transformers import AutoTokenizer
|
17 |
|
18 |
data_indexer = DataIndexer()
|
19 |
|
20 |
+
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
|
21 |
+
|
22 |
llm = HuggingFaceEndpoint(
|
23 |
repo_id="meta-llama/Meta-Llama-3-8B-Instruct",
|
24 |
+
|
25 |
huggingfacehub_api_token=os.environ['HF_TOKEN'],
|
26 |
max_new_tokens=512,
|
27 |
stop_sequences=[tokenizer.eos_token],
|
28 |
streaming=True,
|
29 |
+
# task="conversational",
|
30 |
+
task="text-generation",
|
31 |
)
|
32 |
|
33 |
simple_chain = (raw_prompt | llm).with_types(input_type=schemas.UserQuestion)
|
34 |
|
35 |
# TODO: create formatted_chain by piping raw_prompt_formatted and the LLM endpoint.
|
36 |
+
formatted_chain = (raw_prompt_formatted | llm).with_types(input_type=schemas.UserQuestion)
|
37 |
|
38 |
# TODO: use history_prompt_formatted and HistoryInput to create the history_chain
|
39 |
+
history_chain = (history_prompt_formatted | llm).with_types(input_type=schemas.HistoryInput)
|
40 |
|
41 |
# TODO: Let's construct the standalone_chain by piping standalone_prompt_formatted with the LLM
|
42 |
+
standalone_chain = (standalone_prompt_formatted | llm).with_types(input_type=schemas.HistoryInput)
|
43 |
|
44 |
input_1 = RunnablePassthrough.assign(new_question=standalone_chain)
|
45 |
input_2 = {
|
46 |
'context': lambda x: format_context(data_indexer.search(x['new_question'])),
|
47 |
+
'standalone_question': lambda x: x['new_question'] # new question was the parameter in input1
|
48 |
}
|
49 |
input_to_rag_chain = input_1 | input_2
|
50 |
|
51 |
# TODO: use input_to_rag_chain, rag_prompt_formatted,
|
52 |
# HistoryInput and the LLM to build the rag_chain.
|
53 |
+
rag_chain = (input_to_rag_chain | rag_prompt_formatted | llm).with_types(input_type=schemas.RagInput)
|
54 |
|
55 |
# TODO: Implement the filtered_rag_chain. It should be the
|
56 |
# same as the rag_chain but with hybrid_search = True.
|
57 |
+
|
58 |
+
input_2_hybrid_search = {
|
59 |
+
'context': lambda x: format_context(data_indexer.search(x['new_question'], hybrid_search=True)),
|
60 |
+
'standalone_question': lambda x: x['new_question']
|
61 |
+
}
|
62 |
+
|
63 |
+
filtered_rag_chain = (input_1 | input_2_hybrid_search | rag_prompt_formatted | llm ).with_types(input_type=schemas.RagInput)
|
64 |
|
65 |
|
66 |
|
app/Backend/app/crud.py → crud.py
RENAMED
@@ -17,7 +17,28 @@ def add_message(db: Session, message: schemas.MessageBase, username: str):
|
|
17 |
# - create a models.Message instance
|
18 |
# - pass the retrieved user to the message instance
|
19 |
# - save the message instance to the database
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
def get_user_chat_history(db: Session, username: str):
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
# - create a models.Message instance
|
18 |
# - pass the retrieved user to the message instance
|
19 |
# - save the message instance to the database
|
20 |
+
user_data = get_or_create_user(db, username)
|
21 |
+
db_message = models.Message(
|
22 |
+
message=message.message,
|
23 |
+
type=message.type,
|
24 |
+
timestamp=message.timestamp,
|
25 |
+
user_id=user_data.id
|
26 |
+
)
|
27 |
+
db.add(db_message)
|
28 |
+
db.commit()
|
29 |
+
db.refresh(db_message)
|
30 |
+
# raise NotImplemented
|
31 |
+
return message
|
32 |
|
33 |
def get_user_chat_history(db: Session, username: str):
|
34 |
+
# chat_history = db.
|
35 |
+
user_data = get_or_create_user(db, username)
|
36 |
+
messages = db.query(models.Message.message,
|
37 |
+
models.Message.type,
|
38 |
+
models.Message.timestamp
|
39 |
+
).filter(models.Message.user_id==user_data.id).all()
|
40 |
+
|
41 |
+
if not messages:
|
42 |
+
return []
|
43 |
+
return messages
|
44 |
+
# raise NotImplemented
|
app/Backend/app/data_indexing.py → data_indexing.py
RENAMED
@@ -5,6 +5,7 @@ from pinecone.grpc import PineconeGRPC as Pinecone
|
|
5 |
from pinecone import ServerlessSpec
|
6 |
from langchain_community.vectorstores import Chroma
|
7 |
from langchain_openai import OpenAIEmbeddings
|
|
|
8 |
|
9 |
current_dir = Path(__file__).resolve().parent
|
10 |
|
@@ -16,22 +17,31 @@ class DataIndexer:
|
|
16 |
def __init__(self, index_name='langchain-repo') -> None:
|
17 |
|
18 |
# TODO: choose your embedding model
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
self.
|
|
|
|
|
|
|
|
|
24 |
self.index_name = index_name
|
25 |
self.pinecone_client = Pinecone(api_key=os.environ.get('PINECONE_API_KEY'))
|
26 |
|
27 |
if index_name not in self.pinecone_client.list_indexes().names():
|
28 |
# TODO: create your index if it doesn't exist. Use the create_index function.
|
29 |
# Make sure to choose the dimension that corresponds to your embedding model
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
32 |
self.index = self.pinecone_client.Index(self.index_name)
|
33 |
# TODO: make sure to build the index.
|
34 |
-
self.source_index =
|
35 |
|
36 |
def get_source_index(self):
|
37 |
if not os.path.isfile(self.source_file):
|
@@ -60,21 +70,23 @@ class DataIndexer:
|
|
60 |
|
61 |
# TODO: create a list of the vector representations of each text data in the batch
|
62 |
# TODO: choose your embedding model
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
# values = self.embedding_client.feature_extraction([
|
68 |
# doc.page_content for doc in batch
|
69 |
# ])
|
70 |
-
values = None
|
71 |
|
72 |
# TODO: create a list of unique identifiers for each element in the batch with the uuid package.
|
73 |
-
vector_ids =
|
74 |
|
75 |
# TODO: create a list of dictionaries representing the metadata. Capture the text data
|
76 |
# with the "text" key, and make sure to capture the rest of the doc.metadata.
|
77 |
-
metadatas =
|
|
|
|
|
78 |
|
79 |
# create a list of dictionaries with keys "id" (the unique identifiers), "values"
|
80 |
# (the vector representation), and "metadata" (the metadata).
|
@@ -86,8 +98,8 @@ class DataIndexer:
|
|
86 |
|
87 |
try:
|
88 |
# TODO: Use the function upsert to upload the data to the database.
|
89 |
-
upsert_response =
|
90 |
-
print(upsert_response)
|
91 |
except Exception as e:
|
92 |
print(e)
|
93 |
|
@@ -103,17 +115,22 @@ class DataIndexer:
|
|
103 |
# TODO: embed the text_query by using the embedding model
|
104 |
# TODO: choose your embedding model
|
105 |
# vector = self.embedding_client.feature_extraction(text_query)
|
106 |
-
|
107 |
-
vector = None
|
108 |
|
109 |
# TODO: use the vector representation of the text_query to
|
110 |
# search the database by using the query function.
|
111 |
-
result =
|
|
|
|
|
|
|
|
|
112 |
|
113 |
docs = []
|
114 |
for res in result["matches"]:
|
115 |
# TODO: From the result's metadata, extract the "text" element.
|
116 |
-
|
|
|
117 |
|
118 |
return docs
|
119 |
|
|
|
5 |
from pinecone import ServerlessSpec
|
6 |
from langchain_community.vectorstores import Chroma
|
7 |
from langchain_openai import OpenAIEmbeddings
|
8 |
+
from huggingface_hub import InferenceClient
|
9 |
|
10 |
current_dir = Path(__file__).resolve().parent
|
11 |
|
|
|
17 |
def __init__(self, index_name='langchain-repo') -> None:
|
18 |
|
19 |
# TODO: choose your embedding model
|
20 |
+
self.embedding_client = InferenceClient(
|
21 |
+
"dunzhang/stella_en_1.5B_v5",
|
22 |
+
token=os.environ['HF_TOKEN'],
|
23 |
+
)
|
24 |
+
self.spec = ServerlessSpec(
|
25 |
+
cloud = 'aws',
|
26 |
+
region='us-east-1'
|
27 |
+
)
|
28 |
+
# self.embedding_client = OpenAIEmbeddings()
|
29 |
self.index_name = index_name
|
30 |
self.pinecone_client = Pinecone(api_key=os.environ.get('PINECONE_API_KEY'))
|
31 |
|
32 |
if index_name not in self.pinecone_client.list_indexes().names():
|
33 |
# TODO: create your index if it doesn't exist. Use the create_index function.
|
34 |
# Make sure to choose the dimension that corresponds to your embedding model
|
35 |
+
self.pinecone_client.create_index(
|
36 |
+
name=index_name,
|
37 |
+
dimension=1024,
|
38 |
+
metric='cosine',
|
39 |
+
spec=self.spec
|
40 |
+
)
|
41 |
+
|
42 |
self.index = self.pinecone_client.Index(self.index_name)
|
43 |
# TODO: make sure to build the index.
|
44 |
+
self.source_index = self.get_source_index()
|
45 |
|
46 |
def get_source_index(self):
|
47 |
if not os.path.isfile(self.source_file):
|
|
|
70 |
|
71 |
# TODO: create a list of the vector representations of each text data in the batch
|
72 |
# TODO: choose your embedding model
|
73 |
+
values = self.embedding_client.embed_documents([
|
74 |
+
doc.page_content for doc in batch
|
75 |
+
])
|
76 |
|
77 |
# values = self.embedding_client.feature_extraction([
|
78 |
# doc.page_content for doc in batch
|
79 |
# ])
|
80 |
+
# values = None
|
81 |
|
82 |
# TODO: create a list of unique identifiers for each element in the batch with the uuid package.
|
83 |
+
vector_ids = [uuid.uuid4() for _ in batch]
|
84 |
|
85 |
# TODO: create a list of dictionaries representing the metadata. Capture the text data
|
86 |
# with the "text" key, and make sure to capture the rest of the doc.metadata.
|
87 |
+
metadatas = [{"text": doc.page_content,
|
88 |
+
**doc.metadata
|
89 |
+
} for doc in batch]
|
90 |
|
91 |
# create a list of dictionaries with keys "id" (the unique identifiers), "values"
|
92 |
# (the vector representation), and "metadata" (the metadata).
|
|
|
98 |
|
99 |
try:
|
100 |
# TODO: Use the function upsert to upload the data to the database.
|
101 |
+
upsert_response = self.index.upsert(vectors)
|
102 |
+
print(f"successfully indexed batch {upsert_response}")
|
103 |
except Exception as e:
|
104 |
print(e)
|
105 |
|
|
|
115 |
# TODO: embed the text_query by using the embedding model
|
116 |
# TODO: choose your embedding model
|
117 |
# vector = self.embedding_client.feature_extraction(text_query)
|
118 |
+
vector = self.embedding_client.embed_query(text_query)
|
119 |
+
# vector = None
|
120 |
|
121 |
# TODO: use the vector representation of the text_query to
|
122 |
# search the database by using the query function.
|
123 |
+
result = self.index.query(vector,
|
124 |
+
filter=filter,
|
125 |
+
top_k=top_k,
|
126 |
+
include_values=True
|
127 |
+
)
|
128 |
|
129 |
docs = []
|
130 |
for res in result["matches"]:
|
131 |
# TODO: From the result's metadata, extract the "text" element.
|
132 |
+
docs.append(res['metadata']['text'])
|
133 |
+
# pass
|
134 |
|
135 |
return docs
|
136 |
|
app/Backend/app/database.py → database.py
RENAMED
File without changes
|
app/Backend/app/main.py → main.py
RENAMED
@@ -5,13 +5,24 @@ from sse_starlette.sse import EventSourceResponse
|
|
5 |
from langserve.serialization import WellKnownLCSerializer
|
6 |
from typing import List
|
7 |
from sqlalchemy.orm import Session
|
|
|
8 |
|
9 |
import schemas
|
10 |
-
from
|
|
|
|
|
11 |
import crud, models, schemas
|
12 |
from database import SessionLocal, engine
|
13 |
from callbacks import LogResponseCallback
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
models.Base.metadata.create_all(bind=engine)
|
17 |
|
@@ -42,9 +53,18 @@ async def simple_stream(request: Request):
|
|
42 |
@app.post("/formatted/stream")
|
43 |
async def formatted_stream(request: Request):
|
44 |
# TODO: use the formatted_chain to implement the "/formatted/stream" endpoint.
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
# raise NotImplemented
|
49 |
|
50 |
|
@@ -57,7 +77,34 @@ async def history_stream(request: Request, db: Session = Depends(get_db)):
|
|
57 |
# - We add as part of the user history the current question by using add_message.
|
58 |
# - We create an instance of HistoryInput by using format_chat_history.
|
59 |
# - We use the history input within the history chain.
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
|
63 |
@app.post("/rag/stream")
|
@@ -69,7 +116,27 @@ async def rag_stream(request: Request, db: Session = Depends(get_db)):
|
|
69 |
# - We add as part of the user history the current question by using add_message.
|
70 |
# - We create an instance of HistoryInput by using format_chat_history.
|
71 |
# - We use the history input within the rag chain.
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
|
75 |
@app.post("/filtered_rag/stream")
|
@@ -81,7 +148,36 @@ async def filtered_rag_stream(request: Request, db: Session = Depends(get_db)):
|
|
81 |
# - We add as part of the user history the current question by using add_message.
|
82 |
# - We create an instance of HistoryInput by using format_chat_history.
|
83 |
# - We use the history input within the filtered rag chain.
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
|
87 |
|
|
|
5 |
from langserve.serialization import WellKnownLCSerializer
|
6 |
from typing import List
|
7 |
from sqlalchemy.orm import Session
|
8 |
+
from datetime import datetime
|
9 |
|
10 |
import schemas
|
11 |
+
from models import Message
|
12 |
+
from chains import simple_chain, formatted_chain, history_chain, rag_chain
|
13 |
+
from prompts import format_chat_history
|
14 |
import crud, models, schemas
|
15 |
from database import SessionLocal, engine
|
16 |
from callbacks import LogResponseCallback
|
17 |
|
18 |
+
# temporary
|
19 |
+
from database import engine
|
20 |
+
import models
|
21 |
+
|
22 |
+
# drop all tables and recreate
|
23 |
+
models.Base.metadata.drop_all(bind=engine)
|
24 |
+
models.Base.metadata.create_all(bind=engine)
|
25 |
+
|
26 |
|
27 |
models.Base.metadata.create_all(bind=engine)
|
28 |
|
|
|
53 |
@app.post("/formatted/stream")
|
54 |
async def formatted_stream(request: Request):
|
55 |
# TODO: use the formatted_chain to implement the "/formatted/stream" endpoint.
|
56 |
+
try:
|
57 |
+
data = await request.json()
|
58 |
+
user_question = schemas.UserQuestion(**data['input'])
|
59 |
+
return EventSourceResponse(
|
60 |
+
generate_stream(
|
61 |
+
input_data = user_question,
|
62 |
+
runnable = formatted_chain )
|
63 |
+
)
|
64 |
+
except ValueError as e:
|
65 |
+
raise HTTPException(status_code=400, detail=str(e))
|
66 |
+
except Exception as e:
|
67 |
+
raise HTTPException(status_code=500, detail=str(e))
|
68 |
# raise NotImplemented
|
69 |
|
70 |
|
|
|
77 |
# - We add as part of the user history the current question by using add_message.
|
78 |
# - We create an instance of HistoryInput by using format_chat_history.
|
79 |
# - We use the history input within the history chain.
|
80 |
+
data = await request.json()
|
81 |
+
user_request = schemas.UserRequest(**data['input'])
|
82 |
+
# user_data = await crud.get_or_create(db, user_request.username)
|
83 |
+
# since history stream means
|
84 |
+
# we have existing user's no need to check for a user
|
85 |
+
chat_history = crud.get_user_chat_history(db, user_request.username)
|
86 |
+
history_input = schemas.HistoryInput(
|
87 |
+
chat_history = format_chat_history(chat_history),
|
88 |
+
question=user_request.question
|
89 |
+
)
|
90 |
+
|
91 |
+
## adding messgae to message database
|
92 |
+
type = 'Human'
|
93 |
+
user_data = crud.get_or_create_user(db, user_request.username)
|
94 |
+
user_id = user_data.id
|
95 |
+
timestamp = str(datetime.now())
|
96 |
+
add_message = schemas.MessageBase(
|
97 |
+
user_id = user_id,
|
98 |
+
message = user_request.question,
|
99 |
+
type = type,
|
100 |
+
timestamp = timestamp,
|
101 |
+
user=user_request.username,
|
102 |
+
)
|
103 |
+
|
104 |
+
_ = crud.add_message(db,add_message, username = user_request.username)
|
105 |
+
# chat history contains: [{ message, type, timestamp}]
|
106 |
+
return EventSourceResponse(generate_stream(history_input, history_chain))
|
107 |
+
# raise NotImplemented
|
108 |
|
109 |
|
110 |
@app.post("/rag/stream")
|
|
|
116 |
# - We add as part of the user history the current question by using add_message.
|
117 |
# - We create an instance of HistoryInput by using format_chat_history.
|
118 |
# - We use the history input within the rag chain.
|
119 |
+
data = await request.json()
|
120 |
+
user_request = schemas.UserRequest(**data['input'])
|
121 |
+
messages = crud.get_user_chat_history(db, user_request.username)
|
122 |
+
chat_history = format_chat_history(messages)
|
123 |
+
|
124 |
+
history_input = schemas.HistoryInput( chat_history = format_chat_history(chat_history), question=user_request.question)
|
125 |
+
## adding messgae to message database
|
126 |
+
type = 'Human'
|
127 |
+
user_data = crud.get_or_create_user(db, user_request.username)
|
128 |
+
user_id = user_data.id
|
129 |
+
timestamp = str(datetime.now())
|
130 |
+
add_message = schemas.MessageBase(
|
131 |
+
user_id = user_id,
|
132 |
+
message = user_request.question,
|
133 |
+
type = type,
|
134 |
+
timestamp = timestamp
|
135 |
+
)
|
136 |
+
|
137 |
+
_ = crud.add_message(db,add_message, username = user_request.username)
|
138 |
+
return EventSourceResponse(generate_stream(history_input, rag_chain))
|
139 |
+
# raise NotImplemented
|
140 |
|
141 |
|
142 |
@app.post("/filtered_rag/stream")
|
|
|
148 |
# - We add as part of the user history the current question by using add_message.
|
149 |
# - We create an instance of HistoryInput by using format_chat_history.
|
150 |
# - We use the history input within the filtered rag chain.
|
151 |
+
data = await request.json()
|
152 |
+
user_request = models.UserRequest(data)
|
153 |
+
|
154 |
+
messages = db.Query(
|
155 |
+
Message.message,
|
156 |
+
Message.type,
|
157 |
+
Message.timestamp
|
158 |
+
).filter(Message.user_id == user_request.username)
|
159 |
+
chat_history = format_chat_history(messages)
|
160 |
+
|
161 |
+
history_input = schemas.HistoryInput(
|
162 |
+
chat_history = format_chat_history(chat_history),
|
163 |
+
question=user_request.question
|
164 |
+
)
|
165 |
+
## adding messgae to message database
|
166 |
+
type = 'Human'
|
167 |
+
user_data = crud.get_or_create_user(db, user_request.username)
|
168 |
+
user_id = user_data.id
|
169 |
+
timestamp = str(datetime.now())
|
170 |
+
add_message = schemas.MessageBase(
|
171 |
+
user_id = user_id,
|
172 |
+
message = user_request.question,
|
173 |
+
type = type,
|
174 |
+
timestamp = timestamp
|
175 |
+
)
|
176 |
+
|
177 |
+
_ = crud.add_message(db,add_message, username = user_request.username)
|
178 |
+
|
179 |
+
return EventSourceResponse(generate_stream(history_input, filtered_rag_chain))
|
180 |
+
# raise NotImplemented
|
181 |
|
182 |
|
183 |
|
app/Backend/app/models.py → models.py
RENAMED
@@ -3,6 +3,7 @@ from sqlalchemy.orm import relationship
|
|
3 |
|
4 |
from database import Base
|
5 |
|
|
|
6 |
class User(Base):
|
7 |
__tablename__ = "users"
|
8 |
|
@@ -18,4 +19,11 @@ class User(Base):
|
|
18 |
# attribute as a foreign key.
|
19 |
class Message(Base):
|
20 |
__tablename__ = "messages"
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
from database import Base
|
5 |
|
6 |
+
|
7 |
class User(Base):
|
8 |
__tablename__ = "users"
|
9 |
|
|
|
19 |
# attribute as a foreign key.
|
20 |
class Message(Base):
|
21 |
__tablename__ = "messages"
|
22 |
+
|
23 |
+
id = Column(Integer, primary_key=True, index=True)
|
24 |
+
message = Column(String)
|
25 |
+
type = Column(String)
|
26 |
+
timestamp = Column(DateTime)
|
27 |
+
user_id = Column(Integer, ForeignKey('users.id'))
|
28 |
+
user = relationship("User",back_populates="messages")
|
29 |
+
|
app/Backend/app/prompts.py → prompts.py
RENAMED
@@ -6,15 +6,15 @@ import models
|
|
6 |
def format_prompt(prompt) -> PromptTemplate:
|
7 |
# TODO: format the input prompt by using the model specific instruction template
|
8 |
template = f"""
|
9 |
-
<|begin_of_text|><|start_header_id|>system
|
10 |
You are a helpful assistant.<|eot_id|>
|
11 |
<|start_header_id|>user<|end_header_id|>
|
12 |
{prompt}<|eot_id|>
|
13 |
<|start_header_id|>assistant<|end_header_id|>
|
14 |
-
|
15 |
"""
|
|
|
16 |
prompt_template = PromptTemplate(
|
17 |
-
input_variables=["question"],
|
18 |
template = template
|
19 |
)
|
20 |
# TODO: return a langchain PromptTemplate
|
@@ -24,39 +24,73 @@ def format_prompt(prompt) -> PromptTemplate:
|
|
24 |
def format_chat_history(messages: List[models.Message]):
|
25 |
# TODO: implement format_chat_history to format
|
26 |
# the list of Message into a text of chat history.
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
def format_context(docs: List[str]):
|
30 |
# TODO: the output of the DataIndexer.search is a list of text,
|
31 |
# so we need to concatenate that list into a text that can fit into
|
32 |
# the rag_prompt_formatted. Implement format_context that takes a
|
33 |
# like of strings and returns the context as one string.
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
raw_prompt = "{question}"
|
37 |
|
38 |
# TODO: Create the history_prompt prompt that will capture the question and the conversation history.
|
39 |
# The history_prompt needs a {chat_history} placeholder and a {question} placeholder.
|
40 |
-
history_prompt: str =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
# TODO: Create the standalone_prompt prompt that will capture the question and the chat history
|
43 |
# to generate a standalone question. It needs a {chat_history} placeholder and a {question} placeholder,
|
44 |
-
standalone_prompt: str =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
# TODO: Create the rag_prompt that will capture the context and the standalone question to generate
|
47 |
# a final answer to the question.
|
48 |
-
rag_prompt: str =
|
|
|
|
|
|
|
|
|
49 |
|
50 |
# TODO: create raw_prompt_formatted by using format_prompt
|
51 |
raw_prompt_formatted = format_prompt(raw_prompt)
|
52 |
raw_prompt = PromptTemplate.from_template(raw_prompt)
|
53 |
|
54 |
# TODO: use format_prompt to create history_prompt_formatted
|
55 |
-
history_prompt_formatted: PromptTemplate =
|
56 |
# TODO: use format_prompt to create standalone_prompt_formatted
|
57 |
-
standalone_prompt_formatted: PromptTemplate =
|
58 |
# TODO: use format_prompt to create rag_prompt_formatted
|
59 |
-
rag_prompt_formatted: PromptTemplate =
|
60 |
|
61 |
|
62 |
|
|
|
6 |
def format_prompt(prompt) -> PromptTemplate:
|
7 |
# TODO: format the input prompt by using the model specific instruction template
|
8 |
template = f"""
|
9 |
+
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
|
10 |
You are a helpful assistant.<|eot_id|>
|
11 |
<|start_header_id|>user<|end_header_id|>
|
12 |
{prompt}<|eot_id|>
|
13 |
<|start_header_id|>assistant<|end_header_id|>
|
|
|
14 |
"""
|
15 |
+
|
16 |
prompt_template = PromptTemplate(
|
17 |
+
# input_variables=["question"], the variables will be auto detected by langchain package
|
18 |
template = template
|
19 |
)
|
20 |
# TODO: return a langchain PromptTemplate
|
|
|
24 |
def format_chat_history(messages: List[models.Message]):
|
25 |
# TODO: implement format_chat_history to format
|
26 |
# the list of Message into a text of chat history.
|
27 |
+
chat_history = ""
|
28 |
+
for msg in messages:
|
29 |
+
chat_history += msg['message']
|
30 |
+
chat_history += "\n---\n"
|
31 |
+
# combined all messages from the list for sending it to the model prompt.
|
32 |
+
return chat_history
|
33 |
+
# raise NotImplemented
|
34 |
|
35 |
def format_context(docs: List[str]):
|
36 |
# TODO: the output of the DataIndexer.search is a list of text,
|
37 |
# so we need to concatenate that list into a text that can fit into
|
38 |
# the rag_prompt_formatted. Implement format_context that takes a
|
39 |
# like of strings and returns the context as one string.
|
40 |
+
if not docs:
|
41 |
+
return ""
|
42 |
+
combined_text = ""
|
43 |
+
combined_text = "\n\n---\n\n".join(
|
44 |
+
doc.strip() for doc in docs if doc.strip()
|
45 |
+
)
|
46 |
+
# raise NotImplemented
|
47 |
+
return combined_text
|
48 |
|
49 |
raw_prompt = "{question}"
|
50 |
|
51 |
# TODO: Create the history_prompt prompt that will capture the question and the conversation history.
|
52 |
# The history_prompt needs a {chat_history} placeholder and a {question} placeholder.
|
53 |
+
history_prompt: str = """
|
54 |
+
Given the following conversation provide a helpful answer to the following up question.
|
55 |
+
|
56 |
+
Chat History:
|
57 |
+
|
58 |
+
{chat_history}
|
59 |
+
|
60 |
+
Follow Up Question: {question}
|
61 |
+
|
62 |
+
helpful answer:
|
63 |
+
"""
|
64 |
|
65 |
# TODO: Create the standalone_prompt prompt that will capture the question and the chat history
|
66 |
# to generate a standalone question. It needs a {chat_history} placeholder and a {question} placeholder,
|
67 |
+
standalone_prompt: str = """
|
68 |
+
Given the following conversation and a follow up question, rephrase the
|
69 |
+
follow up question to be a standalone question, in its original language.
|
70 |
+
Chat History:
|
71 |
+
{chat_history}
|
72 |
+
Follow Up Input: {question}
|
73 |
+
Standalone question:
|
74 |
+
"""
|
75 |
|
76 |
# TODO: Create the rag_prompt that will capture the context and the standalone question to generate
|
77 |
# a final answer to the question.
|
78 |
+
rag_prompt: str = """
|
79 |
+
Answer the question based only on the following context:
|
80 |
+
{context}
|
81 |
+
Question: {standalone_question}
|
82 |
+
"""
|
83 |
|
84 |
# TODO: create raw_prompt_formatted by using format_prompt
|
85 |
raw_prompt_formatted = format_prompt(raw_prompt)
|
86 |
raw_prompt = PromptTemplate.from_template(raw_prompt)
|
87 |
|
88 |
# TODO: use format_prompt to create history_prompt_formatted
|
89 |
+
history_prompt_formatted: PromptTemplate = format_prompt(history_prompt)
|
90 |
# TODO: use format_prompt to create standalone_prompt_formatted
|
91 |
+
standalone_prompt_formatted: PromptTemplate = format_prompt(standalone_prompt)
|
92 |
# TODO: use format_prompt to create rag_prompt_formatted
|
93 |
+
rag_prompt_formatted: PromptTemplate = format_prompt(rag_prompt)
|
94 |
|
95 |
|
96 |
|
requirements.txt
CHANGED
@@ -1,2 +1,109 @@
|
|
1 |
-
|
2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
aiohappyeyeballs==2.6.1
|
2 |
+
aiohttp==3.12.15
|
3 |
+
aiosignal==1.4.0
|
4 |
+
altair==5.5.0
|
5 |
+
annotated-types==0.7.0
|
6 |
+
anyio==4.10.0
|
7 |
+
appier==1.34.6
|
8 |
+
async-timeout==4.0.3
|
9 |
+
attrs==25.3.0
|
10 |
+
blinker==1.9.0
|
11 |
+
cachetools==5.5.2
|
12 |
+
certifi==2025.8.3
|
13 |
+
charset-normalizer==3.4.2
|
14 |
+
click==8.2.1
|
15 |
+
dataclasses-json==0.6.7
|
16 |
+
distro==1.9.0
|
17 |
+
exceptiongroup==1.3.0
|
18 |
+
fastapi==0.116.1
|
19 |
+
filelock==3.18.0
|
20 |
+
frozenlist==1.7.0
|
21 |
+
fsspec==2025.7.0
|
22 |
+
gitdb==4.0.12
|
23 |
+
GitPython==3.1.45
|
24 |
+
google-api==0.1.12
|
25 |
+
google-api-core==2.25.1
|
26 |
+
google-auth==2.40.3
|
27 |
+
google-cloud-core==2.4.3
|
28 |
+
googleapis-common-protos==1.70.0
|
29 |
+
grpcio==1.74.0
|
30 |
+
grpcio-tools==1.74.0
|
31 |
+
h11==0.16.0
|
32 |
+
hf-xet==1.1.5
|
33 |
+
httpcore==1.0.9
|
34 |
+
httpx==0.28.1
|
35 |
+
httpx-sse==0.4.1
|
36 |
+
huggingface-hub==0.34.3
|
37 |
+
idna==3.10
|
38 |
+
Jinja2==3.1.6
|
39 |
+
jiter==0.10.0
|
40 |
+
jsonpatch==1.33
|
41 |
+
jsonpointer==3.0.0
|
42 |
+
jsonschema==4.25.0
|
43 |
+
jsonschema-specifications==2025.4.1
|
44 |
+
langchain==0.3.27
|
45 |
+
langchain-community==0.3.27
|
46 |
+
langchain-core==0.3.72
|
47 |
+
langchain-huggingface==0.3.1
|
48 |
+
langchain-openai==0.3.28
|
49 |
+
langchain-text-splitters==0.3.9
|
50 |
+
langserve==0.3.1
|
51 |
+
langsmith==0.4.11
|
52 |
+
MarkupSafe==3.0.2
|
53 |
+
marshmallow==3.26.1
|
54 |
+
multidict==6.6.3
|
55 |
+
mypy_extensions==1.1.0
|
56 |
+
narwhals==2.0.1
|
57 |
+
numpy==2.2.6
|
58 |
+
openai==1.98.0
|
59 |
+
orjson==3.11.1
|
60 |
+
packaging==24.2
|
61 |
+
pandas==2.3.1
|
62 |
+
pathlib==1.0.1
|
63 |
+
pillow==11.3.0
|
64 |
+
pinecone==7.3.0
|
65 |
+
pinecone-plugin-assistant==1.7.0
|
66 |
+
pinecone-plugin-interface==0.0.7
|
67 |
+
propcache==0.3.2
|
68 |
+
proto-plus==1.26.1
|
69 |
+
protobuf==6.31.1
|
70 |
+
pyarrow==21.0.0
|
71 |
+
pyasn1==0.6.1
|
72 |
+
pyasn1_modules==0.4.2
|
73 |
+
pydantic==2.11.7
|
74 |
+
pydantic-settings==2.10.1
|
75 |
+
pydantic_core==2.33.2
|
76 |
+
pydeck==0.9.1
|
77 |
+
python-dateutil==2.9.0.post0
|
78 |
+
python-dotenv==1.1.1
|
79 |
+
pytz==2025.2
|
80 |
+
PyYAML==6.0.2
|
81 |
+
referencing==0.36.2
|
82 |
+
regex==2025.7.34
|
83 |
+
requests==2.32.4
|
84 |
+
requests-toolbelt==1.0.0
|
85 |
+
rpds-py==0.26.0
|
86 |
+
rsa==4.9.1
|
87 |
+
safetensors==0.5.3
|
88 |
+
six==1.17.0
|
89 |
+
smmap==5.0.2
|
90 |
+
sniffio==1.3.1
|
91 |
+
SQLAlchemy==2.0.42
|
92 |
+
sse-starlette==3.0.2
|
93 |
+
starlette==0.47.2
|
94 |
+
streamlit==1.47.1
|
95 |
+
tenacity==9.1.2
|
96 |
+
tiktoken==0.9.0
|
97 |
+
tokenizers==0.21.4
|
98 |
+
toml==0.10.2
|
99 |
+
tornado==6.5.1
|
100 |
+
tqdm==4.67.1
|
101 |
+
transformers==4.54.1
|
102 |
+
typing-inspect==0.9.0
|
103 |
+
typing-inspection==0.4.1
|
104 |
+
typing_extensions==4.14.1
|
105 |
+
tzdata==2025.2
|
106 |
+
urllib3==2.5.0
|
107 |
+
uvicorn==0.35.0
|
108 |
+
yarl==1.20.1
|
109 |
+
zstandard==0.23.0
|
app/Backend/app/schemas.py → schemas.py
RENAMED
@@ -1,4 +1,5 @@
|
|
1 |
from pydantic.v1 import BaseModel
|
|
|
2 |
|
3 |
|
4 |
class UserQuestion(BaseModel):
|
@@ -6,14 +7,27 @@ class UserQuestion(BaseModel):
|
|
6 |
|
7 |
# TODO: create a HistoryInput data model with a chat_history and question attributes.
|
8 |
class HistoryInput(BaseModel):
|
9 |
-
|
|
|
10 |
|
11 |
# TODO: let's create a UserRequest data model with a question and username attribute.
|
12 |
# This will be used to parse the input request.
|
13 |
class UserRequest(BaseModel):
|
14 |
username: str
|
|
|
|
|
15 |
|
16 |
# TODO: implement MessageBase as a schema mapping from the database model to the
|
17 |
# FastAPI data model. Basically MessageBase should have the same attributes as models.Message
|
18 |
class MessageBase(BaseModel):
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
from pydantic.v1 import BaseModel
|
2 |
+
from datetime import datetime
|
3 |
|
4 |
|
5 |
class UserQuestion(BaseModel):
|
|
|
7 |
|
8 |
# TODO: create a HistoryInput data model with a chat_history and question attributes.
|
9 |
class HistoryInput(BaseModel):
|
10 |
+
question: str
|
11 |
+
chat_history: str
|
12 |
|
13 |
# TODO: let's create a UserRequest data model with a question and username attribute.
|
14 |
# This will be used to parse the input request.
|
15 |
class UserRequest(BaseModel):
|
16 |
username: str
|
17 |
+
question: str
|
18 |
+
|
19 |
|
20 |
# TODO: implement MessageBase as a schema mapping from the database model to the
|
21 |
# FastAPI data model. Basically MessageBase should have the same attributes as models.Message
|
22 |
class MessageBase(BaseModel):
|
23 |
+
# id: int
|
24 |
+
message: str
|
25 |
+
timestamp: datetime
|
26 |
+
type: str
|
27 |
+
user_id: int
|
28 |
+
user: str
|
29 |
+
|
30 |
+
# created additional
|
31 |
+
class RagInput(BaseModel):
|
32 |
+
standalone_question: str
|
33 |
+
context: str
|
test.db
ADDED
Binary file (24.6 kB). View file
|
|