ksunamprusty/Maker_Lab_1
1
1import os2import gradio as gr3 4from huggingface_hub import InferenceClient5 6from langchain_text_splitters import RecursiveCharacterTextSplitter7from langchain_community.embeddings import HuggingFaceEmbeddings8from langchain_community.vectorstores import FAISS9from langchain_community.document_loaders import TextLoader10from pathlib import Path11 12import re13 14# =====================================================15# 0. Config16# =====================================================17 18HF_TOKEN = os.environ.get("Token_Key")19 20MODEL_NAME = "HuggingFaceH4/zephyr-7b-beta" # Much better for RAG21 22# =====================================================23# 1. Load + Build Knowledge Base24# =====================================================25 26print("π Reading knowledge base...")27 28folder_path = "knowledge_base"29 30documents = []31 32for file in Path(folder_path).glob("*.txt"):33 loader = TextLoader(str(file))34 documents.extend(loader.load())35 36 37print("βοΈ Splitting documents...")38 39splitter = RecursiveCharacterTextSplitter(40 chunk_size=600,41 chunk_overlap=80,42)43 44documents = splitter.split_documents(documents)45 46 47print("π§ Building embeddings...")48 49embeddings = HuggingFaceEmbeddings(50 model_name="sentence-transformers/all-mpnet-base-v2"51)52 53 54print("π¦ Building vector store...")55 56db = FAISS.from_documents(documents, embeddings)57 58retriever = db.as_retriever(59 search_type="mmr",60 search_kwargs={61 "k": 2,62 "fetch_k": 863 }64)65 66 67print("β
Knowledge base is ready!")68 69 70# =====================================================71# 2. Prompt Builder72# =====================================================73 74def clean_context(text):75 # Remove entire QUESTION/ANSWER blocks fully76 text = re.sub(r"QUESTION:.*?(?=QUESTION:|$)", "", text, flags=re.DOTALL)77 78 # Remove leftover labels if any79 text = text.replace("QUESTION:", "")80 text = text.replace("ANSWER:", "")81 82 return text.strip()83 84def build_prompt(question, docs):85 86 context = "\n\n".join(87 clean_context(d.page_content)88 for d in docs89 )90 91 prompt = f"""92You are Sunam's AI twin.93 94IMPORTANT RULES:95- Be concise, sharp, and specific.96- Answer ONLY the user's current question.97- Do NOT generate additional questions.98- Do NOT repeat information.99- Do NOT use QUESTION/ANSWER labels.100- Provide a single focused response (max 4β5 sentences).101- Use bullet points only if helpful.102- If the answer is not in context, say "I don't know."103 104CONTEXT:105{context}106 107User Question:108{question}109 110Respond below:111"""112 113 return prompt.strip()114 115 116# =====================================================117# 3. LLM Client118# =====================================================119 120client = InferenceClient(121 model=MODEL_NAME,122 token=HF_TOKEN123)124 125 126# =====================================================127# 4. Chat Function (Fixed Retriever API)128# =====================================================129 130def chat(message, history):131 132 # New LangChain API133 docs = retriever.invoke(message)134 135 prompt = build_prompt(message, docs)136 137 messages = [138 {"role": "user", "content": prompt}139 ]140 141 response = ""142 143 for chunk in client.chat_completion(144 messages=messages,145 max_tokens=500,146 temperature=0.1,147 stream=True,148 ):149 150 if chunk.choices[0].delta.content:151 token = chunk.choices[0].delta.content152 response += token153 yield response154 155 156# =====================================================157# 5. Minimal Dark UI158# =====================================================159 160custom_css = """161.header-container {162 text-align: center;163 margin-bottom: 30px;164}165 166.header-container h1 {167 font-size: 42px;168 font-weight: 700;169 color: #d97706; /* warm orange */170 margin-bottom: 8px;171}172 173.header-container p {174 font-size: 18px;175 color: #7c2d12; /* soft brownish orange */176 opacity: 0.85;177}178body {179 background: #0f172a !important;180}181.gradio-container {182 max-width: 900px !important;183 margin: auto !important;184}185h1 {186 color: #e5e7eb;187 text-align: center;188}189.subtitle {190 text-align: center;191 color: #9ca3af;192 margin-bottom: 20px;193}194footer {195 display: none !important;196}197/* Style the textbox */198textarea,199input[type="text"] {200 height: 52px !important;201 border-radius: 12px !important;202 padding: 12px 16px !important;203 font-size: 16px !important;204}205 206/* Style the Clear button */207button {208 height: 52px !important;209 border-radius: 12px !important;210 font-size: 16px !important;211 font-weight: 600 !important;212}213/* ===== Examples Section ===== */214 215.examples-section {216 margin-top: 25px;217 margin-bottom: 10px;218}219 220.examples-title {221 font-size: 18px;222 font-weight: 600;223 color: #b45309;224 margin-bottom: 12px;225 text-align: left;226}227 228/* Style example buttons */229.examples-section + div button,230.gradio-container .examples button {231 background-color: #fb923c !important;232 border-radius: 20px !important;233 padding: 8px 16px !important;234 font-weight: 500 !important;235 border: none !important;236 transition: all 0.2s ease-in-out !important;237}238 239/* Hover effect */240.examples-section + div button:hover,241.gradio-container .examples button:hover {242 background-color: #ea580c !important;243 transform: translateY(-2px);244 box-shadow: 0 4px 10px rgba(234, 88, 12, 0.3);245}246"""247 248 249# =====================================================250# 6. App251# =====================================================252 253with gr.Blocks(254 theme=gr.themes.Soft(255 primary_hue="amber",256 neutral_hue="orange",257 ),258 css="""259 body {260 background: linear-gradient(135deg, #FFF7ED, #FFEDD5);261 }262 263 /* Main container */264 .container {265 max-width: 850px;266 margin: auto;267 padding-top: 40px;268 }269 270 /* Title */271 .title {272 text-align: center;273 font-size: 30px;274 font-weight: 700;275 margin-bottom: 5px;276 color: #C2410C;277 }278 279 /* Subtitle */280 .subtitle {281 text-align: center;282 font-size: 15px;283 color: #7C2D12;284 margin-bottom: 25px;285 }286 287 /* Chatbox card */288 .chatbox {289 border-radius: 18px;290 box-shadow: 0px 8px 25px rgba(249, 115, 22, 0.15);291 background: #ffffff;292 }293 294 /* Input row spacing */295 .input-row {296 margin-top: 15px;297 }298 299 /* Example buttons styling */300 .gradio-examples .example {301 border: 1px solid #FDBA74 !important;302 background-color: #FFEDD5 !important;303 color: #7C2D12 !important;304 border-radius: 10px !important;305 transition: all 0.2s ease-in-out !important;306 }307 308 /* Hover effect */309 .gradio-examples .example:hover {310 background-color: #F97316 !important;311 color: white !important;312 border-color: #F97316 !important;313 transform: translateY(-2px);314 }315 316 /* Clear button */317 .input-row button {318 height: 52px !important;319 padding: 0 24px !important;320 display: flex !important;321 align-items: center !important;322 justify-content: center !important;323 border-radius: 12px !important;324 background-color: #F97316 !important;325 color: white !important;326 border: none !important;327 }328 329 .input-row button:hover {330 background-color: #EA580C !important;331 }332 333 footer {display:none !important;}334 """335 336) as demo:337 338 with gr.Column(elem_classes="container"):339 340 gr.HTML(341 """342 <div class="header-container">343 <h1>Sunam's AI Twin</h1>344 <p>Ask anything about Sunamβs experience, skills, achievements or education.</p>345 </div>346 """347 )348 349 chatbot = gr.Chatbot(350 height=450,351 bubble_full_width=False,352 elem_classes="chatbox",353 )354 355 with gr.Row(elem_classes="input-row"):356 msg = gr.Textbox(357 placeholder="Type your question here...",358 show_label=False,359 scale=8360 )361 362 clear = gr.Button("Clear", scale=1)363 364 # Optional: Example prompts365 gr.Examples(366 examples=[367 "What are my skills?",368 "What projects have I done?",369 "What are my interests?",370 "What roles suit me?"371 ],372 inputs=msg373 )374 375 def user(user_message, history):376 return "", history + [[user_message, None]]377 378 def bot(history):379 user_message = history[-1][0]380 history[-1][1] = ""381 382 for chunk in chat(user_message, history):383 history[-1][1] = chunk384 yield history385 386 msg.submit(387 user,388 [msg, chatbot],389 [msg, chatbot],390 queue=False,391 ).then(392 bot,393 chatbot,394 chatbot,395 )396 397 clear.click(lambda: [], None, chatbot)398 399 400# =====================================================401# 7. Launch402# =====================================================403 404if __name__ == "__main__":405 demo.launch()