Kashif12334 commited on
Commit
4bf7565
·
verified ·
1 Parent(s): 873767b

Upload 5 files

Browse files
Files changed (5) hide show
  1. .env +4 -0
  2. app.py +453 -0
  3. chat_history.json +18 -0
  4. preferences.json +3 -0
  5. requirements.txt +17 -0
.env ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ GROQ_API_KEY=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
2
+ BRIGHT_API_KEY=ded1bc00-4d84-4dee-b4d6-c896cadf2417
3
+ BRIGHT_ZONE=web_unlocker2
4
+ OPENAI_API_KEY= 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
app.py ADDED
@@ -0,0 +1,453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import requests
4
+ import re
5
+ import tempfile
6
+ import torch
7
+ import soundfile as sf
8
+
9
+ from bs4 import BeautifulSoup
10
+ from groq import Groq
11
+ import gradio as gr
12
+ from dotenv import load_dotenv
13
+ from youtube_transcript_api import YouTubeTranscriptApi
14
+
15
+ from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech, SpeechT5HifiGan
16
+
17
+ load_dotenv()
18
+
19
+ # API KEYS
20
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
21
+ BRIGHT_API_KEY = os.getenv("BRIGHT_API_KEY")
22
+ BRIGHT_ZONE = os.getenv("BRIGHT_ZONE")
23
+
24
+ client = Groq(api_key=GROQ_API_KEY)
25
+
26
+ CHAT_FILE = "chat_history.json"
27
+ PREF_FILE = "preferences.json"
28
+
29
+
30
+ # SAFE JSON FUNCTIONS
31
+
32
+ def load_json(file, default):
33
+ if os.path.exists(file):
34
+ try:
35
+ with open(file, "r") as f:
36
+ return json.load(f)
37
+ except:
38
+ return default
39
+ return default
40
+
41
+
42
+ def save_json(file, data):
43
+ with open(file, "w") as f:
44
+ json.dump(data, f, indent=4)
45
+
46
+
47
+ conversation_history = load_json(CHAT_FILE, [])
48
+ user_preferences = load_json(PREF_FILE, {"style": "Default"})
49
+
50
+
51
+
52
+ # LOAD TTS MODEL (Version 4)
53
+
54
+
55
+ print("Loading SpeechT5 model...")
56
+
57
+ processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
58
+ tts_model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
59
+ vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
60
+
61
+ speaker_embeddings = torch.randn(1, 512)
62
+
63
+ print("TTS Model Loaded")
64
+
65
+
66
+
67
+ # VERSION 1 — WEBSITE SCRAPER
68
+
69
+
70
+ def brightdata_request(target_url):
71
+
72
+ response = requests.post(
73
+ "https://api.brightdata.com/request",
74
+ headers={
75
+ "Content-Type": "application/json",
76
+ "Authorization": f"Bearer {BRIGHT_API_KEY}"
77
+ },
78
+ json={
79
+ "zone": BRIGHT_ZONE,
80
+ "url": target_url,
81
+ "format": "raw"
82
+ }
83
+ )
84
+
85
+ return response.text
86
+
87
+
88
+ def scrape_goodreads(url):
89
+
90
+ html = brightdata_request(url)
91
+
92
+ soup = BeautifulSoup(html, "html.parser")
93
+
94
+ books = []
95
+
96
+ rows = soup.find_all("tr")
97
+
98
+ for row in rows:
99
+
100
+ title_tag = row.find("a", class_="bookTitle")
101
+ author_tag = row.find("a", class_="authorName")
102
+ rating_tag = row.find("span", class_="minirating")
103
+
104
+ if title_tag and author_tag and rating_tag:
105
+
106
+ books.append({
107
+ "title": title_tag.get_text(strip=True),
108
+ "author": author_tag.get_text(strip=True),
109
+ "rating": rating_tag.get_text(strip=True)
110
+ })
111
+
112
+ return books[:10]
113
+
114
+
115
+ def qa_bot(url, question):
116
+
117
+ books = scrape_goodreads(url)
118
+
119
+ if not books:
120
+ return "No book data found."
121
+
122
+ context = "\n".join(
123
+ [f"{i+1}. {b['title']} by {b['author']} - {b['rating']}"
124
+ for i, b in enumerate(books)]
125
+ )
126
+
127
+ system_prompt = f"""
128
+ You are a helpful assistant.
129
+ Answer ONLY using the following scraped Goodreads data.
130
+
131
+ {context}
132
+ """
133
+
134
+ response = client.chat.completions.create(
135
+ model="llama-3.1-8b-instant",
136
+ messages=[
137
+ {"role": "system", "content": system_prompt},
138
+ {"role": "user", "content": question}
139
+ ]
140
+ )
141
+
142
+ return response.choices[0].message.content
143
+
144
+
145
+
146
+ # VERSION 2 — YOUTUBE QA
147
+
148
+
149
+ def extract_video_id(url):
150
+
151
+ pattern = r"(?:v=|youtu\.be/)([a-zA-Z0-9_-]{11})"
152
+
153
+ match = re.search(pattern, url)
154
+
155
+ return match.group(1) if match else None
156
+
157
+
158
+ def get_youtube_transcript(url):
159
+
160
+ video_id = extract_video_id(url)
161
+
162
+ if not video_id:
163
+ return "Invalid YouTube URL."
164
+
165
+ try:
166
+ transcript = YouTubeTranscriptApi.get_transcript(video_id)
167
+
168
+ full_text = " ".join([entry["text"] for entry in transcript])
169
+
170
+ return full_text
171
+
172
+ except:
173
+ return "No transcript available for this video."
174
+
175
+
176
+ def youtube_qa(video_url, question):
177
+
178
+ transcript = get_youtube_transcript(video_url)
179
+
180
+ if transcript.startswith("No") or transcript.startswith("Invalid"):
181
+ return transcript
182
+
183
+ system_prompt = f"""
184
+ You are a helpful assistant.
185
+ Answer ONLY using this transcript.
186
+
187
+ Transcript:
188
+ {transcript[:6000]}
189
+ """
190
+
191
+ response = client.chat.completions.create(
192
+ model="llama-3.1-8b-instant",
193
+ messages=[
194
+ {"role": "system", "content": system_prompt},
195
+ {"role": "user", "content": question}
196
+ ]
197
+ )
198
+
199
+ return response.choices[0].message.content
200
+
201
+
202
+
203
+ # VERSION 3 — MEMORY CHAT
204
+
205
+
206
+ def chat_with_memory(user_message, preference_text):
207
+
208
+ global conversation_history, user_preferences
209
+
210
+ if preference_text and preference_text.strip():
211
+
212
+ user_preferences["style"] = preference_text
213
+
214
+ save_json(PREF_FILE, user_preferences)
215
+
216
+ system_prompt = f"""
217
+ You are a helpful AI assistant.
218
+
219
+ User Preferences:
220
+ {user_preferences.get("style","Default")}
221
+
222
+ Follow the preferred style in all responses.
223
+ Maintain conversational memory.
224
+ """
225
+
226
+ messages = [{"role": "system", "content": system_prompt}]
227
+
228
+ messages.extend(conversation_history)
229
+
230
+ messages.append({"role": "user", "content": user_message})
231
+
232
+ response = client.chat.completions.create(
233
+ model="llama-3.1-8b-instant",
234
+ messages=messages
235
+ )
236
+
237
+ assistant_reply = response.choices[0].message.content
238
+
239
+ conversation_history.append({"role": "user", "content": user_message})
240
+
241
+ conversation_history.append({"role": "assistant", "content": assistant_reply})
242
+
243
+ save_json(CHAT_FILE, conversation_history)
244
+
245
+ return assistant_reply
246
+
247
+
248
+ def clear_memory():
249
+
250
+ global conversation_history
251
+
252
+ conversation_history = []
253
+
254
+ save_json(CHAT_FILE, [])
255
+
256
+ return []
257
+
258
+
259
+
260
+ # VERSION 4 — VOICE AI
261
+
262
+
263
+ def transcribe_audio(audio_path):
264
+
265
+ with open(audio_path, "rb") as audio_file:
266
+
267
+ transcription = client.audio.transcriptions.create(
268
+ file=audio_file,
269
+ model="whisper-large-v3"
270
+ )
271
+
272
+ return transcription.text
273
+
274
+
275
+ def text_to_speech(text):
276
+
277
+ inputs = processor(text=text, return_tensors="pt")
278
+
279
+ speech = tts_model.generate_speech(
280
+ inputs["input_ids"],
281
+ speaker_embeddings,
282
+ vocoder=vocoder
283
+ )
284
+
285
+ temp_audio = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
286
+
287
+ sf.write(temp_audio.name, speech.numpy(), samplerate=16000)
288
+
289
+ return temp_audio.name
290
+
291
+
292
+ def process_text(user_message, preference_text, chat_display):
293
+
294
+ if not user_message.strip():
295
+ return "", chat_display, None
296
+
297
+ assistant_reply = chat_with_memory(user_message, preference_text)
298
+
299
+ chat_display.append({"role": "user", "content": user_message})
300
+ chat_display.append({"role": "assistant", "content": assistant_reply})
301
+
302
+ audio_output = text_to_speech(assistant_reply)
303
+
304
+ return "", chat_display, audio_output
305
+
306
+
307
+ def process_voice(audio_file, preference_text, chat_display):
308
+
309
+ if audio_file is None:
310
+ return chat_display, None
311
+
312
+ user_text = transcribe_audio(audio_file)
313
+
314
+ assistant_reply = chat_with_memory(user_text, preference_text)
315
+
316
+ chat_display.append({"role": "user", "content": user_text})
317
+ chat_display.append({"role": "assistant", "content": assistant_reply})
318
+
319
+ audio_output = text_to_speech(assistant_reply)
320
+
321
+ return chat_display, audio_output
322
+
323
+
324
+
325
+ # GRADIO UI
326
+
327
+
328
+ with gr.Blocks() as demo:
329
+
330
+ gr.Markdown("# 🚀 Full AI Assistant (V1 + V2 + V3 + V4)")
331
+
332
+ # TAB 1
333
+ with gr.Tab("🌐 Website Scraper Q&A"):
334
+
335
+ url_input = gr.Textbox(
336
+ label="Enter Goodreads URL",
337
+ value="https://www.goodreads.com/list/show/1.Best_Books_Ever"
338
+ )
339
+
340
+ question_input = gr.Textbox(label="Ask your question")
341
+
342
+ output1 = gr.Textbox(label="Answer")
343
+
344
+ btn1 = gr.Button("Submit")
345
+
346
+ btn1.click(
347
+ qa_bot,
348
+ inputs=[url_input, question_input],
349
+ outputs=output1
350
+ )
351
+
352
+ # TAB 2
353
+ with gr.Tab("🎥 YouTube Transcript Q&A"):
354
+
355
+ video_input = gr.Textbox(label="Enter YouTube URL")
356
+
357
+ yt_question = gr.Textbox(label="Ask your question")
358
+
359
+ output2 = gr.Textbox(label="Answer")
360
+
361
+ btn2 = gr.Button("Submit")
362
+
363
+ btn2.click(
364
+ youtube_qa,
365
+ inputs=[video_input, yt_question],
366
+ outputs=output2
367
+ )
368
+
369
+ # TAB 3
370
+ with gr.Tab("🧠 Memory Chatbot"):
371
+
372
+ chatbot = gr.Chatbot(label="Conversation", value=conversation_history)
373
+
374
+ preference_input = gr.Textbox(
375
+ label="User Preferences (Optional)"
376
+ )
377
+
378
+ user_message = gr.Textbox(label="Your Message")
379
+
380
+ send_btn = gr.Button("Send")
381
+
382
+ clear_btn = gr.Button("Clear Memory")
383
+
384
+ def chat_interface(user_message, preference_text, chat_display):
385
+
386
+ if not user_message.strip():
387
+ return "", chat_display
388
+
389
+ assistant_reply = chat_with_memory(user_message, preference_text)
390
+
391
+ chat_display.append({"role": "user", "content": user_message})
392
+
393
+ chat_display.append({"role": "assistant", "content": assistant_reply})
394
+
395
+ return "", chat_display
396
+
397
+ send_btn.click(
398
+ chat_interface,
399
+ inputs=[user_message, preference_input, chatbot],
400
+ outputs=[user_message, chatbot]
401
+ )
402
+
403
+ clear_btn.click(
404
+ clear_memory,
405
+ outputs=chatbot
406
+ )
407
+
408
+ # TAB 4
409
+ with gr.Tab("🎙️ Voice AI Assistant"):
410
+
411
+ chatbot_v4 = gr.Chatbot(label="Conversation", value=conversation_history)
412
+
413
+ preference_input_v4 = gr.Textbox(
414
+ label="User Preferences (Optional)"
415
+ )
416
+
417
+ user_message_v4 = gr.Textbox(label="Type your message")
418
+
419
+ audio_input = gr.Audio(
420
+ sources=["microphone"],
421
+ type="filepath",
422
+ label="Speak your question"
423
+ )
424
+
425
+ audio_output = gr.Audio(label="Assistant Voice Response")
426
+
427
+ send_btn_v4 = gr.Button("Send Text")
428
+
429
+ voice_btn = gr.Button("Send Voice")
430
+
431
+ clear_btn_v4 = gr.Button("Clear Memory")
432
+
433
+ send_btn_v4.click(
434
+ process_text,
435
+ inputs=[user_message_v4, preference_input_v4, chatbot_v4],
436
+ outputs=[user_message_v4, chatbot_v4, audio_output]
437
+ )
438
+
439
+ voice_btn.click(
440
+ process_voice,
441
+ inputs=[audio_input, preference_input_v4, chatbot_v4],
442
+ outputs=[chatbot_v4, audio_output]
443
+ )
444
+
445
+ clear_btn_v4.click(
446
+ clear_memory,
447
+ outputs=chatbot_v4
448
+ )
449
+
450
+
451
+ if __name__ == "__main__":
452
+
453
+ demo.launch()
chat_history.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "role": "user",
4
+ "content": " In the hall of."
5
+ },
6
+ {
7
+ "role": "assistant",
8
+ "content": "mirrors, I sense a sense of unease. What draws you to this place, with its endless reflections and whispers of the past?"
9
+ },
10
+ {
11
+ "role": "user",
12
+ "content": "can you tell me my name?"
13
+ },
14
+ {
15
+ "role": "assistant",
16
+ "content": "I'm a little curious now, but unfortunately, I don't have any information about your identity. We just started our little conversation, and I don't seem to recall any previous encounters. Can you give me a hint or tell me your name yourself? I'm all ears... or should I say, all circuitry?"
17
+ }
18
+ ]
preferences.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "style": "hello"
3
+ }
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ groq
3
+ requests
4
+ beautifulsoup4
5
+ python-dotenv
6
+ youtube-transcript-api
7
+ gradio
8
+ groq
9
+ openai
10
+ python-dotenv
11
+ gradio
12
+ groq
13
+ python-dotenv
14
+ torch
15
+ transformers
16
+ datasets
17
+ soundfile