|
import json |
|
import os |
|
import time |
|
import random |
|
import string |
|
import shutil |
|
import base64 |
|
from pathlib import Path |
|
from dotenv import load_dotenv |
|
load_dotenv() |
|
|
|
import streamlit as st |
|
from streamlit_option_menu import option_menu |
|
from streamlit_lottie import st_lottie |
|
|
|
|
|
import torch |
|
from langchain_community.embeddings import HuggingFaceInstructEmbeddings |
|
from langchain_community.document_loaders import PyPDFLoader, TextLoader, WikipediaLoader |
|
from langchain_community.vectorstores import Chroma |
|
from langchain.text_splitter import RecursiveCharacterTextSplitter |
|
from langchain.document_loaders.merge import MergedDataLoader |
|
from langchain_groq import ChatGroq |
|
from langchain.chains.combine_documents import create_stuff_documents_chain |
|
from langchain_core.prompts import ChatPromptTemplate |
|
from langchain.chains import create_retrieval_chain |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def loadLottieFile(filePath: str): |
|
with open(file=filePath, mode = "r") as f: |
|
return json.load(f) |
|
|
|
|
|
def loadItOnce(container, animation, height, quality = 'high'): |
|
with container.container(): |
|
st_lottie(animation_source=animation, height=height, quality=quality) |
|
|
|
|
|
|
|
|
|
def initialRampUp(llamaAnimation): |
|
with st.lottie_spinner(llamaAnimation, height = 700): |
|
if 'filesUploadedRecords' not in st.session_state: |
|
st.session_state.filesUploadedRecords = None |
|
|
|
if 'vdbBuilt' not in st.session_state: |
|
st.session_state.vdbBuilt = {} |
|
|
|
if 'vectorDatabase' not in st.session_state: |
|
st.session_state.vectorDatabase = {} |
|
|
|
if 'collectionName' not in st.session_state: |
|
st.session_state.collectionName = str(''.join(random.choices(string.ascii_letters, k=25))) |
|
try: |
|
shutil.rmtree('Dump') |
|
except: |
|
pass |
|
os.makedirs('Dump', exist_ok=True) |
|
time.sleep(3) |
|
|
|
|
|
|
|
|
|
def image_to_base64(image_path): |
|
with open(image_path, "rb") as img_file: |
|
encoded_string = base64.b64encode(img_file.read()).decode("utf-8") |
|
return encoded_string |
|
def set_background_image(base64_image, opacity): |
|
|
|
custom_css = f""" |
|
<style> |
|
[data-testid = 'stApp'] {{ |
|
background-image: linear-gradient(rgba(255, 255, 255, {opacity}), rgba(255, 255, 255, {opacity})), url('data:image/jpeg;base64,{base64_image}'); |
|
background-size: cover; |
|
background-repeat: no-repeat; |
|
background-attachment: fixed; /* Ensures the background image remains fixed */ |
|
}} |
|
[data-testid = 'stHeader']{{ |
|
background-color: rgba(0,0,0,0); |
|
}} |
|
</style> |
|
""" |
|
|
|
|
|
st.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
|
|
def navigationBar(): |
|
|
|
|
|
options = [ |
|
{"label": "Retrieval Augmented Generation", "icon": "bezier"}, |
|
{"label": "Fine Tuning LLMs (Coming Soon)", "icon": "gpu-card"}, |
|
{"label": "Forecasting LLMs (Coming Soon)", "icon": "graph-up-arrow"} |
|
] |
|
|
|
|
|
selected = option_menu( |
|
menu_title= None, |
|
options=[option["label"] for option in options], |
|
icons=[option["icon"] for option in options], |
|
menu_icon="lightbulb-fill", |
|
default_index=0, |
|
orientation="horizontal", |
|
styles={ |
|
"container": { |
|
"display": "flex", |
|
"flex-direction": "column", |
|
"justify-content": "center", |
|
"padding": "20px 40px 20px 40px", |
|
"background-color": "#222", |
|
"border-radius": "20px", |
|
"width":"100%", |
|
"box-shadow": "0px 2px 10px rgba(0, 0, 0, 0.2)", |
|
"margin": "auto", |
|
"overflow-x": "auto", |
|
}, |
|
"menu-title": { |
|
"font-size": "36px", |
|
"font-weight": "bold", |
|
"background-color": "#222", |
|
"color": "#FFFFFF", |
|
"margin-bottom": "20px", |
|
}, |
|
"menu-icon": { |
|
"color": "#FFD700", |
|
"font-size": "36px", |
|
"margin-right": "10px", |
|
}, |
|
"icon": { |
|
"color": "#FFD700", |
|
"font-size": "36px", |
|
"margin-right": "10px", |
|
}, |
|
"nav-link": { |
|
"font-size": "20px", |
|
"text-align": "center", |
|
"color": "#FFFFFF", |
|
"padding": "10px 20px", |
|
"border-radius": "15px", |
|
"transition": "background-color 0.3s ease", |
|
|
|
}, |
|
"nav-link-selected": { |
|
"background-color": "#FF6347", |
|
"color": "#FFFFFF", |
|
} |
|
}, |
|
|
|
) |
|
return selected |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@st.cache_resource(show_spinner=False) |
|
def loadEmbeddingsModels(): |
|
DEVICE = "cuda:0" if torch.cuda.is_available() else "cpu" |
|
|
|
return HuggingFaceInstructEmbeddings( |
|
model_name = "hkunlp/instructor-base", |
|
query_instruction = "Represent the query for retrieval: ", |
|
model_kwargs = {"device": DEVICE}) |
|
|
|
|
|
|
|
def removedOrAdded(files): |
|
removed = {} |
|
|
|
|
|
if len(files) == 0: |
|
if (st.session_state.filesUploadedRecords is not None) and (len(st.session_state.filesUploadedRecords) > 0): |
|
removed = {st.session_state.filesUploadedRecords[0].file_id : st.session_state.filesUploadedRecords[0]} |
|
st.session_state.filesUploadedRecords = None |
|
return removed |
|
|
|
|
|
currentFileIds = [file_obj.file_id for file_obj in files] |
|
for file in st.session_state.filesUploadedRecords: |
|
if file.file_id not in currentFileIds: |
|
removed[file.file_id] = file |
|
|
|
|
|
for toRemove in removed.values(): |
|
st.session_state.filesUploadedRecords.remove(toRemove) |
|
return removed |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def buildVectorDatabase(files, query, addOrRemove): |
|
""" |
|
files: Either a list of fileUploader Objects with file details |
|
or that one filename which was just removed by the user and should be from the vector Database as well |
|
addOrRemove: if true, add else remove |
|
""" |
|
|
|
if addOrRemove: |
|
embeddings = loadEmbeddingsModels() |
|
collName = st.session_state.collectionName |
|
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1024, chunk_overlap=100) |
|
|
|
loader_map = { |
|
'.pdf': PyPDFLoader, |
|
'.txt': TextLoader, |
|
'wiki' : WikipediaLoader |
|
} |
|
|
|
docsMergedPDF = [ |
|
loader_map[Path(doc).suffix.lower()](file_path=doc) |
|
for doc in files |
|
] |
|
loadersPDF = MergedDataLoader(loaders=docsMergedPDF) |
|
pagesPDF = loadersPDF.load_and_split(text_splitter) |
|
|
|
|
|
pagesWiki = [] |
|
for wikiQ in query: |
|
loader = WikipediaLoader(query=wikiQ, load_max_docs=2) |
|
try: |
|
pagesW = loader.load_and_split(text_splitter) |
|
if len(pagesW) > 0: |
|
references = list(set(list(map(lambda x: x.metadata['source'], pagesW)))) |
|
st.session_state.vdbBuilt['Keyword ; ' + wikiQ.strip()] = references |
|
pagesWiki += pagesW |
|
|
|
except Exception as e: |
|
message = str(e) + '\n' + f'Looks like we could not search for your key word {wikiQ}' |
|
st.toast(body=message, icon="⚠️") |
|
_ = st.session_state.vdbBuilt.pop('Keyword ; ' + wikiQ.strip(), None) |
|
|
|
|
|
pages = pagesPDF + pagesWiki |
|
st.session_state.vectorDatabase = Chroma.from_documents(documents= pages, |
|
embedding= embeddings, |
|
collection_name= collName, |
|
) |
|
|
|
|
|
else: |
|
if files is not None: |
|
st.session_state.vectorDatabase._collection.delete(where={"source": {'$eq':files}}) |
|
for src in query: |
|
st.session_state.vectorDatabase._collection.delete(where={"source": {'$eq':src}}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
os.environ["TOKENIZERS_PARALLELISM"] = "false" |
|
|
|
class RetrievalChainGenerator: |
|
def __init__(self, model_name, vectorStore): |
|
self.model_name = model_name |
|
self.groq_api_key = os.environ['GROQ_API_KEY'] |
|
self.vectorStore = vectorStore |
|
self.chain = None |
|
self.generate_retrieval_chain() |
|
|
|
def generate_retrieval_chain(self): |
|
llm = ChatGroq(groq_api_key=self.groq_api_key, model_name=self.model_name) |
|
prompt = ChatPromptTemplate.from_template(""" |
|
Answer the following question based only on the provided context. |
|
Think step by step before providing a detailed answer. |
|
If using finance terms, briefly explain them for clarity. |
|
Always return your complete response in html format. |
|
I will tip you $200 if the user finds the answer helpful. |
|
<context> |
|
{context} |
|
</context> |
|
Question: {input}""") |
|
promptChain = create_stuff_documents_chain(llm= llm, prompt= prompt) |
|
retrieverORreferrence = self.vectorStore.as_retriever() |
|
retrievalChain = create_retrieval_chain(retrieverORreferrence, promptChain) |
|
self.chain = retrievalChain |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_main_title(title_text, container): |
|
|
|
custom_css = """ |
|
<style> |
|
@keyframes pulse { |
|
0% { transform: scale(1); box-shadow: 0 0 10px rgba(255, 99, 71, 0.7); } |
|
50% { transform: scale(1.05); box-shadow: 0 0 20px rgba(255, 99, 71, 0.9); } |
|
100% { transform: scale(1); box-shadow: 0 0 10px rgba(255, 99, 71, 0.7); } |
|
} |
|
@keyframes shimmer { |
|
0% { background-position: -100%; } |
|
25% { background-position: -50%; } |
|
50% { background-position: 0%; } |
|
75% { background-position: 50%; } |
|
100% { background-position: 100%; } |
|
} |
|
@keyframes wiggle { |
|
0% { transform: rotate(0); } |
|
25% { transform: rotate(2deg); } |
|
50% { transform: rotate(-2deg); } |
|
75% { transform: rotate(2deg); } |
|
100% { transform: rotate(0); } |
|
} |
|
@keyframes wavy { |
|
0% { transform: translateY(0); } |
|
25% { transform: translateY(-2px); } |
|
50% { transform: translateY(-1px); } |
|
75% { transform: translateY(-2px); } |
|
100% { transform: translateY(0); } |
|
} |
|
@keyframes vibration { |
|
0% { transform: translate(0, 0); } |
|
25% { transform: translate(-1px, 1px); } |
|
50% { transform: translate(1px, -1px); } |
|
75% { transform: translate(-1px, -1px); } |
|
100% { transform: translate(1px, 1px); } |
|
} |
|
|
|
.main-title-container { |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
padding: 20px; |
|
border-radius: 10px; |
|
box-shadow: 0 0 20px rgba(0,0,0,0.2); |
|
background-color: #ff6347; |
|
width: fit-content; |
|
margin: 20px auto; |
|
text-align: center; |
|
font-size: 36px; |
|
font-weight: bold; |
|
color: white; |
|
animation: pulse 2s infinite, vibration 0.1s infinite linear alternate; |
|
position: relative; |
|
overflow: hidden; |
|
} |
|
|
|
.main-title-text { |
|
animation: wavy 10s infinite, shimmer 1s linear infinite, wiggle 1s infinite; |
|
background-image: linear-gradient(to right, transparent 0%, white 50%, transparent 100%); |
|
background-size: 200% 100%; |
|
color: transparent; |
|
-webkit-background-clip: text; |
|
background-clip: text; |
|
} |
|
</style> |
|
""" |
|
|
|
|
|
st.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
container.markdown(f'<div class="main-title-container"><span class="main-title-text">{title_text}</span></div>', unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_alert_note(message, container): |
|
|
|
custom_css = """ |
|
<style> |
|
@keyframes pulse { |
|
0% { transform: scale(1); } |
|
50% { transform: scale(1.03); } |
|
100% { transform: scale(1); } |
|
} |
|
@keyframes wiggle { |
|
0% { transform: rotate(0deg); } |
|
50% { transform: rotate(6deg); } |
|
100% { transform: rotate(0deg); } |
|
} |
|
.alert-box { |
|
position: relative; |
|
padding: 20px; |
|
border-radius: 10px; |
|
background-image: linear-gradient(45deg, #ff4d4d, #ff416c); |
|
color: white; |
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); |
|
animation: pulse 2s infinite alternate; |
|
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out; |
|
overflow:visible; |
|
} |
|
.alert-box:hover { |
|
transform: scale(1.05); |
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); |
|
animation: wiggle 0.3s infinite alternate; |
|
} |
|
.alert-icon { |
|
position: absolute; |
|
top: 40px; |
|
right: 10px; |
|
font-size: 24px; |
|
} |
|
.alert-flare { |
|
|
|
} |
|
</style> |
|
""" |
|
|
|
|
|
st.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
container.markdown(f'<div class="alert-flare"></div><div class="alert-box">{message}<span class="alert-icon">⚠</span></div>', unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_attention_text(text, container): |
|
|
|
custom_css = """ |
|
<style> |
|
@keyframes slide-in { |
|
0% { |
|
transform: translateX(-50px); |
|
opacity: 0; |
|
} |
|
100% { |
|
transform: translateX(0); |
|
opacity: 1; |
|
} |
|
} |
|
|
|
@keyframes slide-in-top { |
|
0% { |
|
transform: translateY(-100%); /* Start off the screen above */ |
|
opacity: 0; /* Hidden initially */ |
|
} |
|
100% { |
|
transform: translateY(0); /* Slide in to the top */ |
|
opacity: 1; /* Fully visible */ |
|
} |
|
} |
|
|
|
.build-text-container { |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
padding: 20px; |
|
border-radius: 10px; |
|
background: linear-gradient(to bottom right, #ffd700, #ffdf80); |
|
width: fit-content; |
|
margin: 20px auto; |
|
text-align: center; |
|
font-size: 28px; |
|
font-weight: bold; |
|
color: black; |
|
overflow: hidden; |
|
} |
|
|
|
.animated-text-in-attention { |
|
display: inline-block; |
|
opacity: 0; |
|
animation: slide-in-top 2s ease-in-out forwards infinite; |
|
} |
|
|
|
/* Preserve spaces */ |
|
.animated-text-in-attention.space { |
|
width: 2ch; /* Adjust width to match character width */ |
|
visibility: hidden; |
|
} |
|
</style> |
|
""" |
|
|
|
|
|
st.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
animated_text_html = ''.join(f'<span class="animated-text-in-attention" style="animation-delay: {i * 0.0005}s;">{char}</span>' if char != ' ' else '<span class="animated-text-in-attention space"></span>' for i, char in enumerate(text)) |
|
|
|
text_html = f""" |
|
<div class="build-text-container"> |
|
{animated_text_html} |
|
</div> |
|
""" |
|
container.markdown(text_html, unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_custom_arrow(direction, container): |
|
|
|
translateX_value = '70px' if direction.lower() == 'right' else '70px' |
|
|
|
custom_css = f""" |
|
<style> |
|
.arrow-container {{ |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
padding: 20px; |
|
border-radius: 10px; |
|
border: 0px solid #ffaa00; /* Border style */ |
|
background: linear-gradient(45deg, rgba(255, 204, 0, 0), rgba(255, 102, 0, 0)); |
|
width: fit-content; |
|
overflow: visible; |
|
transition: transform 0.3s ease-in-out; /* Transition effect */ |
|
}} |
|
|
|
.arrow-svg {{ |
|
width: 100; |
|
height: 30px; |
|
fill: white; |
|
animation: arrow-bounce 1s infinite; |
|
}} |
|
|
|
@keyframes arrow-bounce {{ |
|
0%, 100% {{ transform: translateX(0); }} |
|
50% {{ transform: translateX({translateX_value}); }} |
|
}} |
|
</style> |
|
""" |
|
|
|
|
|
container.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
if direction.lower() == 'left': |
|
arrow_svg = ''' |
|
<svg class="arrow-svg" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> |
|
<path d="M14 5l-9 9 9 9" stroke="currentColor" stroke-width="4" fill="none"/> |
|
</svg> |
|
''' |
|
elif direction.lower() == 'right': |
|
arrow_svg = ''' |
|
<svg class="arrow-svg" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> |
|
<path d="M10 19l9-9-9-9" stroke="currentColor" stroke-width="4" fill="none"/> |
|
</svg> |
|
''' |
|
else: |
|
pass |
|
|
|
|
|
container.markdown(f'<div class="arrow-container">{arrow_svg}</div>', unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_heading_box(message, container): |
|
|
|
css = f""" |
|
<style> |
|
.styled-text-container {{ |
|
padding: 10px 10px; |
|
border-radius: 10px; |
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); |
|
animation: slide-in 1s ease-out forwards; /* Slide in only once */ |
|
display: flex; |
|
justify-content: center; /* Center horizontally */ |
|
align-items: center; /* Center vertically */ |
|
background: linear-gradient(135deg, #fdd835, #4caf50); /* Updated gradient colors */ |
|
color: white; |
|
width: fit-content; |
|
height: auto; /* Adjusted height */ |
|
transition: transform 0.3s ease-in-out; /* Smooth transition for transform */ |
|
margin-left: auto; /* Center horizontally */ |
|
margin-right: auto; |
|
}} |
|
|
|
@keyframes slide-in {{ |
|
from {{ |
|
transform: translateY(-10px); |
|
opacity: 0; |
|
}} |
|
to {{ |
|
transform: translateY(0); |
|
opacity: 1; |
|
}} |
|
}} |
|
|
|
.styled-text-container:hover {{ |
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); |
|
transform: scale(1.05); |
|
animation: wiggle 0.5s ease-in-out infinite alternate; /* Wiggle on hover */ |
|
}} |
|
|
|
@keyframes wiggle {{ |
|
0% {{ |
|
transform: rotate(0deg); |
|
}} |
|
25% {{ |
|
transform: rotate(-5deg); |
|
}} |
|
50% {{ |
|
transform: rotate(5deg); |
|
}} |
|
75% {{ |
|
transform: rotate(-5deg); |
|
}} |
|
100% {{ |
|
transform: rotate(0deg); |
|
}} |
|
}} |
|
</style> |
|
""" |
|
|
|
|
|
styled_html = f""" |
|
<div class="styled-text-container"> |
|
<h3>{message}</h3> |
|
</div> |
|
""" |
|
|
|
|
|
st.markdown(css, unsafe_allow_html=True) |
|
container.markdown(styled_html, unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_error_message(message, container): |
|
|
|
custom_css = """ |
|
<style> |
|
.error-container { |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
height: auto; |
|
background: linear-gradient(135deg, #ff3864, #d81e5b); |
|
padding: 20px; |
|
border-radius: 15px; |
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); |
|
overflow: hidden; |
|
width: auto; |
|
position: relative; |
|
animation: shake 0.8s cubic-bezier(0.36, 0.07, 0.19, 0.97) infinite; |
|
} |
|
|
|
.error-message { |
|
color: #ffffff; |
|
font-size: 16px; |
|
font-weight: bold; |
|
text-align: center; |
|
opacity: 0.9; |
|
} |
|
|
|
@keyframes shake { |
|
0%, 100% { transform: translateX(0); } |
|
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); } |
|
20%, 40%, 60%, 80% { transform: translateX(5px); } |
|
} |
|
</style> |
|
""" |
|
|
|
|
|
st.markdown(custom_css, unsafe_allow_html=True) |
|
container.markdown(f""" |
|
<div class="error-container"> |
|
<div class="error-message">{message}</div> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_small_text(text, container): |
|
|
|
custom_css = """ |
|
<style> |
|
@keyframes flash { |
|
0% { left: -100%; } |
|
50% { left: 100%; } |
|
100% { left: 100%; } |
|
} |
|
@keyframes wiggle { |
|
0% { transform: rotate(0); } |
|
50% { transform: rotate(2deg); } |
|
100% { transform: rotate(0); } |
|
} |
|
@keyframes vibrate { |
|
0% { transform: translate(0); } |
|
25% { transform: translate(-2px, 2px); } |
|
50% { transform: translate(2px, -2px); } |
|
75% { transform: translate(-2px, -2px); } |
|
100% { transform: translate(2px, 2px); } |
|
} |
|
|
|
.animated-text-container { |
|
position: relative; |
|
display: block; |
|
padding: 10px 50px 10px 50px; |
|
border-radius: 10px; |
|
box-shadow: 0 0 10px rgba(0,0,0,0.1); |
|
background-image: linear-gradient(45deg, #0044ff, #0099ff); |
|
transition: box-shadow 0.3s ease-in-out; |
|
width: fit-content; |
|
margin: 20px auto; |
|
text-align: center; |
|
} |
|
|
|
.animated-text-container:hover { |
|
box-shadow: 0 0 20px rgba(255,255,255,0.5); |
|
animation: vibrate 0.3s ease infinite; |
|
} |
|
.animated-text { |
|
font-size: 24px; |
|
font-weight: bold; |
|
color: white; |
|
display: inline-block; |
|
} |
|
.animated-text-container:hover .animated-text { |
|
animation: wiggle 0.5s infinite alternate; |
|
} |
|
|
|
</style> |
|
""" |
|
|
|
|
|
st.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
|
|
container.markdown(f'<div class="animated-text-container"><span class="animated-text">{text}</span></div>', unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
def display_response_message(message, container): |
|
|
|
custom_css = """ |
|
<style> |
|
.response-container { |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
background-color: #ff6347; |
|
padding: 20px; |
|
border-radius: 15px; |
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); |
|
animation: pulse 1s ease infinite alternate; |
|
} |
|
|
|
.response-message { |
|
color: white; |
|
font-size: 24px; |
|
text-align: center; |
|
opacity: 0; |
|
animation: fade-in 0.5s ease forwards, scale-up 0.5s ease forwards; |
|
} |
|
|
|
@keyframes pulse { |
|
0% { transform: scale(1); } |
|
100% { transform: scale(1.05); } |
|
} |
|
|
|
@keyframes fade-in { |
|
0% { opacity: 0; } |
|
100% { opacity: 1; } |
|
} |
|
|
|
@keyframes scale-up { |
|
0% { transform: scale(0.8); } |
|
100% { transform: scale(1); } |
|
} |
|
</style> |
|
""" |
|
|
|
|
|
st.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
response_container = f'<div class="response-container">' |
|
|
|
|
|
response_container += '<div class="response-message">' |
|
response_container += message |
|
response_container += '</div>' |
|
|
|
response_container += '</div>' |
|
|
|
|
|
container.markdown(response_container, unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
def display_question_box(container): |
|
|
|
custom_css = """ |
|
<style> |
|
.question-box { |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
padding: 20px; |
|
overflow: hidden; |
|
height: 100px; /* Adjust height based on icon size */ |
|
} |
|
|
|
.question-icon { |
|
width: 75px; |
|
height: 75px; |
|
fill: black; |
|
animation: float-vibrate 1s infinite ease-in-out alternate, |
|
rotate 2s infinite linear, |
|
pulse 1s infinite alternate, |
|
change-color 3s infinite, |
|
scale 1.5s infinite alternate; |
|
} |
|
|
|
@keyframes float-vibrate { |
|
0% { transform: translateY(0); } |
|
50% { transform: translateY(-5px); } |
|
100% { transform: translateY(0); } |
|
} |
|
|
|
@keyframes rotate { |
|
0% { transform: rotate(0deg); } |
|
100% { transform: rotate(360deg); } |
|
} |
|
|
|
@keyframes pulse { |
|
0% { opacity: 1; } |
|
50% { opacity: 0.7; } |
|
100% { opacity: 1; } |
|
} |
|
|
|
@keyframes change-color { |
|
0% { fill: black; } |
|
25% { fill: red; } |
|
50% { fill: green; } |
|
75% { fill: blue; } |
|
100% { fill: black; } |
|
} |
|
|
|
@keyframes scale { |
|
0% { transform: scale(1); } |
|
100% { transform: scale(1.2); } |
|
} |
|
</style> |
|
""" |
|
|
|
|
|
container.markdown(custom_css, unsafe_allow_html=True) |
|
|
|
|
|
question_box = f""" |
|
<div class="question-box"> |
|
<svg class="question-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> |
|
<text x="12" y="12" font-size="24" text-anchor="middle" alignment-baseline="central">?</text> |
|
</svg> |
|
<span style="color: black; font-size: 48px;">Llama3</span> |
|
</div> |
|
""" |
|
|
|
|
|
container.markdown(question_box, unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
import markdown |
|
import random |
|
def display_citations(heading, contents, container): |
|
unique_id = str(random.randint(10000000, 99999999)) |
|
|
|
css_styles = f""" |
|
<style> |
|
@keyframes move-in-from-left {{ |
|
0% {{ |
|
transform: translateX(-100%); |
|
opacity: 0; |
|
}} |
|
100% {{ |
|
transform: translateX(0); |
|
opacity: 1; |
|
}} |
|
}} |
|
.fancy-container-{unique_id} {{ |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
margin: 30px auto; |
|
animation: move-in-from-left 1s ease-out forwards; |
|
}} |
|
.fancy-card-{unique_id} {{ |
|
width: 500px; |
|
height: 200px; |
|
perspective: 1000px; |
|
position: relative; |
|
border-radius: 20px; |
|
overflow: hidden; /* Ensure contents do not overflow */ |
|
}} |
|
.fancy-card-inner-{unique_id} {{ |
|
width: 100%; |
|
height: 100%; |
|
text-align: center; |
|
transition: transform 1.25s; |
|
transform-style: preserve-3d; |
|
border-radius: 20px; |
|
}} |
|
.fancy-card-{unique_id}:hover .fancy-card-inner-{unique_id} {{ |
|
transform: rotateY(180deg); |
|
}} |
|
.fancy-card-front-{unique_id}, .fancy-card-back-{unique_id} {{ |
|
position: absolute; |
|
width: 100%; |
|
height: 100%; |
|
backface-visibility: hidden; |
|
display: flex; |
|
flex-direction: column; /* Stack elements vertically */ |
|
justify-content: center; |
|
align-items: center; |
|
font-size: 24px; |
|
padding: 20px; |
|
border-radius: 20px; |
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); |
|
overflow: hidden; /* Ensure contents do not overflow */ |
|
}} |
|
.fancy-card-front-{unique_id} {{ |
|
background: linear-gradient(to bottom right, #000, #222); |
|
color: white; |
|
animation: fancy-wiggle 0.5s ease-in-out infinite; |
|
}} |
|
.fancy-card-front-{unique_id} h2 {{ |
|
font-size: 20px; |
|
font-style: italic; |
|
color: white; |
|
margin: 0; /* Remove default margin */ |
|
padding: 10px; /* Add padding */ |
|
text-align: center; /* Center align text */ |
|
word-wrap: break-word; /* Ensure long words wrap */ |
|
overflow-wrap: break-word; /* Ensure long words wrap */ |
|
word-break: break-all; /* Ensure words break if too long */ |
|
}} |
|
@keyframes fancy-wiggle {{ |
|
0% {{ transform: translateX(-4px); }} |
|
50% {{ transform: translateX(4px); }} |
|
100% {{ transform: translateX(-4px); }} |
|
}} |
|
.fancy-card-back-{unique_id} {{ |
|
background: linear-gradient(to bottom right, #ffd700, #ffff00); |
|
background-color: #f7f7f7; |
|
color: #333; |
|
transform: rotateY(180deg); |
|
overflow: auto; /* Enable vertical and horizontal scrolling */ |
|
}} |
|
.fancy-card-back-{unique_id} p {{ |
|
margin: 10px 0px; /* Add margin to separate paragraphs */ |
|
word-break: normal; /* Ensure words break if too long */ |
|
}} |
|
.fancy-card-back-{unique_id} a {{ |
|
color: blue; /* Make links blue */ |
|
text-decoration: underline; /* Underline links */ |
|
word-wrap: break-word; /* Ensure long links wrap */ |
|
overflow-wrap: break-word; /* Ensure long links wrap */ |
|
word-break: normal; /* Ensure words break if too long */ |
|
display: inline-block; |
|
}} |
|
</style> |
|
""" |
|
|
|
|
|
|
|
html_contents = markdown.markdown(contents) |
|
|
|
|
|
html_content = f""" |
|
<div class="fancy-container-{unique_id}" id="{unique_id}"> |
|
<div class="fancy-card-{unique_id}" id="{unique_id}"> |
|
<div class="fancy-card-inner-{unique_id}" id="{unique_id}"> |
|
<div class="fancy-card-front-{unique_id}" id="{unique_id}"> |
|
<h2>{heading}</h2> |
|
</div> |
|
<div class="fancy-card-back-{unique_id}" id="{unique_id}"> |
|
{html_contents} |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
""" |
|
|
|
|
|
st.markdown(css_styles, unsafe_allow_html=True) |
|
container.markdown(html_content, unsafe_allow_html=True) |
|
|
|
|
|
def display_allCitations(resp, contain): |
|
for res in resp['context']: |
|
if res.metadata['source'].endswith('.pdf') or res.metadata['source'].endswith('.txt'): |
|
headingText = f"{res.metadata['source'].split("---")[-1]}   Page No. {res.metadata['page']}" |
|
else: |
|
headingText = f"{res.metadata['source']}" |
|
|
|
contents_text = f"A <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> Content <br><br> {res.page_content}" |
|
display_citations(headingText, contents_text, contain) |
|
time.sleep(0.5) |