agnixcode commited on
Commit
1bb0780
Β·
verified Β·
1 Parent(s): 6d0c6fa

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +263 -0
app.py ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import faiss
3
+ import numpy as np
4
+ import requests
5
+ import gradio as gr
6
+ from openai import OpenAI
7
+ from pypdf import PdfReader
8
+ from sentence_transformers import SentenceTransformer
9
+ css = """
10
+
11
+ /* =========================
12
+ TELECOM ENTERPRISE THEME
13
+ Magenta AI Chatbot UI
14
+ ========================= */
15
+
16
+ /* Background */
17
+
18
+ body {
19
+ background: linear-gradient(135deg, #0B0B10, #141420);
20
+ font-family: "Segoe UI", Roboto, Arial;
21
+ color: white;
22
+ }
23
+
24
+ /* Main container */
25
+ .gradio-container {
26
+ max-width: 1100px !important;
27
+ margin: auto;
28
+ padding: 20px;
29
+ }
30
+
31
+ /* Header / Title */
32
+ h1, h2, h3 {
33
+ color: #E20074;
34
+ font-weight: 700;
35
+ letter-spacing: 0.5px;
36
+ }
37
+
38
+ /* Chat container */
39
+ .chatbot, .gradio-chatbot {
40
+ background: rgba(28, 28, 37, 0.6);
41
+ border: 1px solid rgba(226, 0, 116, 0.2);
42
+ border-radius: 18px;
43
+ backdrop-filter: blur(14px);
44
+ padding: 10px;
45
+ }
46
+
47
+ /* USER MESSAGE */
48
+ .message.user {
49
+ background: linear-gradient(135deg, #E20074, #b0005a);
50
+ color: white;
51
+ border-radius: 16px;
52
+ padding: 12px;
53
+ box-shadow: 0 6px 20px rgba(226, 0, 116, 0.3);
54
+ transition: 0.25s ease;
55
+ }
56
+
57
+ .message.user:hover {
58
+ transform: translateY(-2px);
59
+ box-shadow: 0 10px 30px rgba(226, 0, 116, 0.5);
60
+ }
61
+
62
+ /* BOT MESSAGE */
63
+ .message.bot {
64
+ background: rgba(255, 255, 255, 0.06);
65
+ color: white;
66
+ border-radius: 16px;
67
+ padding: 12px;
68
+ border-left: 3px solid #E20074;
69
+ transition: 0.25s ease;
70
+ }
71
+
72
+ .message.bot:hover {
73
+ transform: translateY(-2px);
74
+ }
75
+
76
+ /* INPUT BOX */
77
+ textarea {
78
+ background: rgba(255,255,255,0.05) !important;
79
+ border: 1px solid rgba(226, 0, 116, 0.3) !important;
80
+ border-radius: 12px !important;
81
+ color: white !important;
82
+ padding: 12px !important;
83
+ }
84
+
85
+ /* BUTTONS */
86
+ button {
87
+ background: #E20074 !important;
88
+ color: white !important;
89
+ border-radius: 10px !important;
90
+ border: none !important;
91
+ font-weight: 600;
92
+ transition: all 0.3s ease;
93
+ }
94
+
95
+ button:hover {
96
+ background: #ff2d9a !important;
97
+ transform: translateY(-2px);
98
+ box-shadow: 0 10px 25px rgba(226, 0, 116, 0.4);
99
+ }
100
+
101
+ /* INPUT FOCUS EFFECT */
102
+ textarea:focus {
103
+ outline: none !important;
104
+ border: 1px solid #E20074 !important;
105
+ box-shadow: 0 0 15px rgba(226, 0, 116, 0.4);
106
+ }
107
+
108
+ /* Card style panels (future UI elements) */
109
+ .card {
110
+ background: rgba(28, 28, 37, 0.7);
111
+ border: 1px solid rgba(226, 0, 116, 0.2);
112
+ border-radius: 16px;
113
+ padding: 15px;
114
+ transition: 0.3s;
115
+ }
116
+
117
+ .card:hover {
118
+ transform: scale(1.02);
119
+ box-shadow: 0 10px 30px rgba(0,0,0,0.4);
120
+ }
121
+
122
+ /* Scrollbar */
123
+ ::-webkit-scrollbar {
124
+ width: 8px;
125
+ }
126
+
127
+ ::-webkit-scrollbar-thumb {
128
+ background: #E20074;
129
+ border-radius: 10px;
130
+ }
131
+ """
132
+
133
+
134
+ # Globals (shared state in Gradio)
135
+ embed_model = SentenceTransformer("all-MiniLM-L6-v2")
136
+ index = None
137
+ chunks = []
138
+
139
+ # Add after globals:
140
+ # Session memory
141
+
142
+ chat_history = []
143
+
144
+ def chat(user_input, history):
145
+ global chat_history
146
+
147
+ # Build full context (PDF + conversation history)
148
+ full_context = "\n".join([
149
+ f"User: {h['user']}\nBot: {h['bot']}"
150
+ for h in chat_history[-5:]
151
+ ]) if chat_history else ""
152
+ answer = generate_answer(user_input, full_context)
153
+
154
+ # Store in memory
155
+ chat_history.append({"user": user_input, "bot": answer})
156
+
157
+ # Update UI history
158
+ new_history = history + [
159
+ {"role": "user", "content": user_input},
160
+ {"role": "assistant", "content": answer}
161
+ ]
162
+
163
+ return new_history, new_history
164
+
165
+ def generate_answer(query, conversation_context=""):
166
+ if index is None:
167
+ return "⚠️ Please load a PDF first."
168
+
169
+ rag_context = retrieve(query)
170
+ rag_text = "\n\n".join(rag_context)
171
+
172
+ # βœ… Combine RAG + Conversation Memory
173
+ full_prompt = f"""You are a smart financial AI assistant that remembers conversations.
174
+
175
+ Previous conversation:
176
+ {conversation_context}
177
+
178
+ PDF Context (use ONLY this for facts):
179
+ {rag_text}
180
+
181
+ Question: {query}
182
+
183
+ Respond naturally and helpfully, referencing past discussion when relevant."""
184
+
185
+ response = client.chat.completions.create(
186
+ model="llama-3.1-8b-instant",
187
+ messages=[{"role": "user", "content": full_prompt}],
188
+ temperature=0.7,
189
+ max_tokens=600
190
+ )
191
+ return response.choices[0].message.content
192
+
193
+ # Groq client with HF Secrets
194
+ client = OpenAI(
195
+ api_key=os.getenv("GROQ_API_KEY"),
196
+ base_url="https://api.groq.com/openai/v1",
197
+ )
198
+
199
+ def convert_drive_link(link):
200
+ try:
201
+ file_id = link.split("/d/")[1].split("/")[0]
202
+ return f"https://drive.google.com/uc?id={file_id}"
203
+ except:
204
+ return link
205
+
206
+ def load_pdf_from_link(link):
207
+ global index, chunks
208
+ url = convert_drive_link(link)
209
+ PDF_PATH = "temp.pdf"
210
+ response = requests.get(url)
211
+ with open(PDF_PATH, "wb") as f:
212
+ f.write(response.content)
213
+
214
+ reader = PdfReader(PDF_PATH)
215
+ texts = [page.extract_text() for page in reader.pages if page.extract_text()]
216
+
217
+ # Chunking
218
+ chunks = []
219
+ for t in texts:
220
+ words = t.split()
221
+ for i in range(0, len(words), 500):
222
+ chunks.append(" ".join(words[i:i+500]))
223
+
224
+ # Embeddings + FAISS
225
+ embeddings = embed_model.encode(chunks)
226
+ dim = embeddings.shape[1]
227
+ index = faiss.IndexFlatL2(dim)
228
+ index.add(np.array(embeddings).astype('float32'))
229
+
230
+ return f"βœ… PDF loaded! {len(chunks)} chunks created."
231
+
232
+ def retrieve(query, k=3):
233
+ if index is None:
234
+ return []
235
+ q_emb = embed_model.encode([query])
236
+ distances, indices = index.search(np.array(q_emb).astype('float32'), k)
237
+ return [chunks[i] for i in indices[0]]
238
+
239
+ # ... (keep all previous code until chat function)
240
+ # UI (replace entirely):
241
+ with gr.Blocks(title="Finance RAG", css=css) as app:
242
+ gr.Markdown("# πŸ“Š Dynamic Finance RAG Chatbot")
243
+
244
+ with gr.Row():
245
+ link_input = gr.Textbox(label="πŸ“Ž Google Drive PDF Link", placeholder="https://drive.google.com/file/d/...")
246
+ load_btn = gr.Button("πŸ“₯ Load PDF", variant="primary")
247
+
248
+ status = gr.Textbox(label="Status", interactive=False)
249
+
250
+ chatbot = gr.Chatbot(height=500)
251
+ msg = gr.Textbox(
252
+ label="πŸ’¬ Ask about the PDF",
253
+ placeholder="What are the key financial metrics?",
254
+ container=True
255
+ )
256
+
257
+ # Events
258
+ load_btn.click(load_pdf_from_link, inputs=link_input, outputs=status)
259
+ msg.submit(chat, inputs=[msg, chatbot], outputs=[chatbot, chatbot])
260
+ msg.submit(lambda: "", outputs=msg)
261
+
262
+ if __name__ == "__main__":
263
+ app.launch()