RAG_Regulatorik / rag_execute.py
smash1pump's picture
Upload folder using huggingface_hub
9d90398 verified
import os
import queue
from threading import Thread
from dotenv import load_dotenv
print(f"Start loading .env")
load_dotenv()
print(f"Finish loading .env")
from langchain.callbacks.base import BaseCallbackHandler
print(f"Start importing from rag_func")
from rag_func import prepare_RAG, retrieve_RAG, generate_RAG
print(f"Finish importing from rag_func")
import gradio as gr
# ----------------- Context Setup -----------------
# For local execution, where the user can select the directory
# user_input = input("Enter a subfolder inside 'context' (press Enter for full 'context'): ").strip()
# if user_input:
# user_dir = os.path.join("context", user_input)
# else:
# user_dir = "context"
# print(f"[Info] Using context directory: {user_dir}")
# For gradio deploy. The user cannot choose the directory
user_dir = "context"
pinecone_API = os.getenv("PINECONE_API")
index_name = "regulatorik"
#llm_model = os.getenv("MODELNAME")
llm_model="gpt-5-nano"
index, pc, llm = prepare_RAG(pinecone_API, index_name, llm_model=llm_model, dir_name=user_dir)
# ----------------- Chat Functions -----------------
def add_user_message(message, history):
history = history or []
history.append({"role": "user", "content": message})
return "", history, history
import time
# ----------------- Streaming Handler -----------------
class StreamHandler(BaseCallbackHandler):
def __init__(self, q: queue.Queue):
self.q = q
self.first_token_received = False
self.ttft = None # time to first token
def on_llm_new_token(self, token: str, **kwargs):
if not self.first_token_received:
self.ttft = time.time() - self.start_time
self.first_token_received = True
self.q.put(token)
def on_llm_end(self, *args, **kwargs):
self.total_time = time.time() - self.start_time
self.q.put("[[END]]")
# ----------------- Chat Functions with timing -----------------
def generate_bot_response(history):
if not history or history[-1]["role"] != "user":
yield history, history
return
user_msg = history[-1]["content"]
retrieved_chunks = retrieve_RAG(user_msg, pc, index)
q = queue.Queue()
handler = StreamHandler(q)
handler.start_time = time.time()
model_name = getattr(llm, "model_name", getattr(llm, "model", None))
streaming_llm = llm.__class__(model=model_name, streaming=True, callbacks=[handler])
def run_llm():
try:
generate_RAG(user_msg, streaming_llm, retrieved_chunks)
finally:
q.put("[[END]]")
Thread(target=run_llm, daemon=True).start()
partial = ""
history.append({"role": "assistant", "content": ""})
while True:
token = q.get()
if token == "[[END]]":
print(f"[Timing] TTFT: {handler.ttft:.3f} s, Total: {handler.total_time:.3f} s")
break
partial += token
history[-1]["content"] = partial
yield history, history
# ----------------- Simplified CSS for Default Gradio Font -----------------
custom_css = """
:root {
--brand-blue: #17428f;
--brand-orange: #f39719;
--text-dark: #111827; /* very dark grey (near black) */
--text-gray: #4B5563; /* medium grey for messages */
color-scheme: only light;
}
body, .gradio-container {
/* Default Gradio font will be used */
background: linear-gradient(135deg, var(--brand-blue) 0%, var(--brand-orange) 100%);
min-height: 100vh;
color: var(--text-dark);
}
/* Top bar transparent */
#topbar { background: transparent !important; }
/* Header text over gradient */
#header h1, #header h2, #header h3, #header h4, #header h5, #header h6,
#header p {
color: #ffffff;
text-align: center;
}
/* Chatbox container */
#chatbot {
height: 600px;
border-radius: 14px;
border: 2px solid var(--brand-blue);
background-color: #ffffff;
padding: 8px;
overflow-y: auto;
}
/* Chat text */
#chatbot, #chatbot * { color: var(--text-gray) !important; }
/* Bubble styling */
#chatbot .message.user {
background: #fff4e1;
border-radius: 10px;
padding: 6px 12px;
color: var(--text-gray) !important;
text-align: right;
}
#chatbot .message.bot {
background: #f0f0f0;
border-radius: 10px;
padding: 6px 12px;
color: var(--text-gray) !important;
text-align: left;
}
/* Fallback selectors for other Gradio versions */
#chatbot [data-testid*="message"] { border-radius: 10px; padding: 6px 12px; }
#chatbot [data-testid="user-message"] { background: #fff4e1; color: var(--text-gray) !important; text-align: right; }
#chatbot [data-testid="assistant-message"] { background: #f0f0f0; color: var(--text-gray) !important; text-align: left; }
/* Inputs */
input[type="text"], textarea, .gr-text-input input, .gr-textbox textarea {
border-radius: 10px;
padding: 10px;
font-size: 16px;
border: 2px solid var(--brand-orange);
}
input:focus, textarea:focus, .gr-text-input input:focus, .gr-textbox textarea:focus {
border-color: var(--brand-blue);
outline: none;
box-shadow: 0 0 6px rgba(23, 66, 143, 0.5);
}
/* Buttons (global gradient) */
.gr-button, button {
border-radius: 10px;
font-weight: 600;
background: linear-gradient(90deg, var(--brand-blue), var(--brand-orange));
color: white;
border: none;
}
.gr-button:hover, button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
/* Chat area: icon-only buttons */
#chatbot {
--icon-light: #9CA3AF;
--icon-hover: #6B7280;
}
/* Tint SVG icons */
#chatbot button svg,
#chatbot [role="button"] svg,
#chatbot .icon svg,
#chatbot [class*="icon"] svg,
#chatbot [data-testid*="icon"] svg,
#chatbot [data-testid*="message"] .tools svg,
#chatbot .message-tools svg {
color: var(--icon-light) !important;
fill: var(--icon-light) !important;
stroke: var(--icon-light) !important;
opacity: 0.95;
}
/* Remove gradient background only on small icon-only buttons */
#chatbot :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient) {
background: transparent !important;
background-image: none !important;
border: none !important;
box-shadow: none !important;
padding: 6px !important;
border-radius: 8px !important;
color: var(--icon-light) !important;
}
/* Hover/focus/active states */
#chatbot :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient):hover {
background-color: rgba(0,0,0,0.05) !important;
}
#chatbot :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient):focus-visible {
outline: none !important;
box-shadow: 0 0 0 2px rgba(23, 66, 143, 0.35) !important;
background-color: rgba(0,0,0,0.06) !important;
}
#chatbot :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient):active {
background-color: rgba(0,0,0,0.08) !important;
}
/* Optional 'danger' icons */
#chatbot .danger svg { color: var(--icon-light) !important; fill: var(--icon-light) !important; stroke: var(--icon-light) !important; }
#chatbot .danger:hover svg { color: #ef4444 !important; fill: #ef4444 !important; stroke: #ef4444 !important; }
#topbar .gr-button.keep-gradient,
#topbar .gr-button:not(:has(svg)) {
background: linear-gradient(90deg, var(--brand-blue), var(--brand-orange)) !important;
color: #fff !important;
}
/* Icon-only buttons in topbar: transparent */
#topbar :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient) {
background: transparent !important;
border: none !important;
box-shadow: none !important;
padding: 6px !important;
border-radius: 8px !important;
color: var(--icon-light) !important;
}
/* Tint SVGs in topbar */
#topbar :is(button,[role="button"]):has(> svg) > svg {
color: var(--icon-light) !important;
fill: var(--icon-light) !important;
stroke: var(--icon-light) !important;
opacity: 0.95;
}
/* Hover/focus/active for topbar icons */
#topbar :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient):hover {
background-color: rgba(0,0,0,0.05) !important;
}
#topbar :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient):focus-visible {
outline: none !important;
box-shadow: 0 0 0 2px rgba(23, 66, 143, 0.35) !important;
background-color: rgba(0,0,0,0.06) !important;
}
#topbar :is(button,[role="button"]):is([aria-label],[title], :has(> svg)):not(.keep-gradient):active {
background-color: rgba(0,0,0,0.08) !important;
}
"""
js_force_light = """ function refresh() { const url = new URL(window.location); if (url.searchParams.get('__theme') !== 'light') { url.searchParams.set('__theme', 'light'); window.location.replace(url); } } """
# ----------------- Gradio App -----------------
with gr.Blocks(css=custom_css, fill_height=True, js=js_force_light) as demo:
gr.Markdown(
"<h1>📚 RAG Chat Assistant</h1>"
"<p>Ask questions and get accurate answers from your documents.</p>",
elem_id="header"
)
chatbot = gr.Chatbot(type="messages", label="Conversation", elem_id="chatbot", height=600)
msg = gr.Textbox(label="Your message", placeholder="Type your question here...")
state = gr.State([])
msg.submit(add_user_message, inputs=[msg, state], outputs=[msg, chatbot, state]) \
.then(generate_bot_response, inputs=[state], outputs=[chatbot, state])
# Launch
if __name__ == "__main__":
demo.launch(share=True)