awacke1 commited on
Commit
dfadfd3
·
verified ·
1 Parent(s): 43ecec4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -547
app.py CHANGED
@@ -1,20 +1,26 @@
1
  import streamlit as st
2
 
3
- # Must be the very first Streamlit command
4
  st.set_page_config(
5
- page_title="🚲BikeAI🏆 Claude/GPT Research",
6
- page_icon="🚲🏆",
7
  layout="wide",
8
- initial_sidebar_state="auto",
9
- menu_items={
10
- 'Get Help': 'https://huggingface.co/awacke1',
11
- 'Report a bug': 'https://huggingface.co/spaces/awacke1',
12
- 'About': "🚲BikeAI🏆 Claude/GPT Research AI"
13
- }
14
  )
15
 
16
- # Now import everything else
17
- import anthropic, openai, base64, cv2, glob, json, math, os, pytz, random, re, requests, time, zipfile
 
 
 
 
 
 
 
 
 
 
 
18
  import plotly.graph_objects as go
19
  import streamlit.components.v1 as components
20
  from datetime import datetime
@@ -24,81 +30,53 @@ from collections import defaultdict, deque
24
  from dotenv import load_dotenv
25
  from gradio_client import Client
26
  from huggingface_hub import InferenceClient
27
- from io import BytesIO
28
  from PIL import Image
29
  from PyPDF2 import PdfReader
30
  from urllib.parse import quote
31
  from xml.etree import ElementTree as ET
32
  from openai import OpenAI
33
  import extra_streamlit_components as stx
34
- from streamlit.runtime.scriptrunner import get_script_run_ctx
35
  import asyncio
36
  import edge_tts
37
 
 
38
  load_dotenv()
39
 
40
- # 🔑 2. API Setup & Clients
41
- openai_api_key = os.getenv('OPENAI_API_KEY', "")
42
- anthropic_key = os.getenv('ANTHROPIC_API_KEY_3', "")
43
- xai_key = os.getenv('xai',"")
44
- if 'OPENAI_API_KEY' in st.secrets:
45
- openai_api_key = st.secrets['OPENAI_API_KEY']
46
- if 'ANTHROPIC_API_KEY' in st.secrets:
47
- anthropic_key = st.secrets["ANTHROPIC_API_KEY"]
48
 
49
  openai.api_key = openai_api_key
50
  claude_client = anthropic.Anthropic(api_key=anthropic_key)
51
  openai_client = OpenAI(api_key=openai.api_key, organization=os.getenv('OPENAI_ORG_ID'))
52
- HF_KEY = os.getenv('HF_KEY')
53
- API_URL = os.getenv('API_URL')
54
 
55
- # 📝 3. Session State Management
56
- if 'transcript_history' not in st.session_state:
57
- st.session_state['transcript_history'] = []
58
  if 'chat_history' not in st.session_state:
59
  st.session_state['chat_history'] = []
60
- if 'openai_model' not in st.session_state:
61
- st.session_state['openai_model'] = "gpt-4o-2024-05-13"
62
  if 'messages' not in st.session_state:
63
  st.session_state['messages'] = []
64
- if 'last_voice_input' not in st.session_state:
65
- st.session_state['last_voice_input'] = ""
66
- if 'editing_file' not in st.session_state:
67
- st.session_state['editing_file'] = None
68
- if 'edit_new_name' not in st.session_state:
69
- st.session_state['edit_new_name'] = ""
70
- if 'edit_new_content' not in st.session_state:
71
- st.session_state['edit_new_content'] = ""
72
- if 'viewing_prefix' not in st.session_state:
73
- st.session_state['viewing_prefix'] = None
74
- if 'should_rerun' not in st.session_state:
75
- st.session_state['should_rerun'] = False
76
  if 'old_val' not in st.session_state:
77
  st.session_state['old_val'] = None
 
 
78
 
79
- # 🎨 4. Custom CSS
80
  st.markdown("""
81
  <style>
82
  .main { background: linear-gradient(to right, #1a1a1a, #2d2d2d); color: #fff; }
83
- .stMarkdown { font-family: 'Helvetica Neue', sans-serif; }
84
  .stButton>button {
85
  margin-right: 0.5rem;
86
- }
87
- .audio-player {
88
- margin: 1rem 0;
89
- padding: 1rem;
90
- border-radius: 10px;
91
- background: #f5f5f5;
92
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
93
  }
94
  </style>
95
  """, unsafe_allow_html=True)
96
 
97
- FILE_EMOJIS = {
98
- "md": "📝",
99
- "mp3": "🎵",
100
- }
101
-
102
  def clean_for_speech(text: str) -> str:
103
  """Clean text for speech synthesis"""
104
  text = text.replace("\n", " ")
@@ -108,520 +86,101 @@ def clean_for_speech(text: str) -> str:
108
  text = re.sub(r"\s+", " ", text).strip()
109
  return text
110
 
111
- @st.cache_resource
112
- def speech_synthesis_html(result):
113
- """Create HTML for speech synthesis"""
114
- html_code = f"""
115
- <html><body>
116
- <script>
117
- var msg = new SpeechSynthesisUtterance("{result.replace('"', '')}");
118
- window.speechSynthesis.speak(msg);
119
- </script>
120
- </body></html>
121
- """
122
- components.html(html_code, height=0)
123
-
124
- async def edge_tts_generate_audio(text, voice="en-US-AriaNeural", rate=0, pitch=0):
 
 
 
 
 
125
  """Generate audio using Edge TTS"""
126
- text = clean_for_speech(text)
127
  if not text.strip():
128
  return None
129
- rate_str = f"{rate:+d}%"
130
- pitch_str = f"{pitch:+d}Hz"
131
- communicate = edge_tts.Communicate(text, voice, rate=rate_str, pitch=pitch_str)
132
- out_fn = generate_filename(text, text, "mp3")
133
- await communicate.save(out_fn)
134
- return out_fn
135
-
136
- def speak_with_edge_tts(text, voice="en-US-AriaNeural", rate=0, pitch=0):
137
- """Wrapper for edge TTS generation"""
138
- return asyncio.run(edge_tts_generate_audio(text, voice, rate, pitch))
139
-
140
- def play_and_download_audio(file_path):
141
- """Play and provide download link for audio"""
142
- if file_path and os.path.exists(file_path):
143
- st.audio(file_path)
144
- dl_link = f'<a href="data:audio/mpeg;base64,{base64.b64encode(open(file_path,"rb").read()).decode()}" download="{os.path.basename(file_path)}">Download {os.path.basename(file_path)}</a>'
145
- st.markdown(dl_link, unsafe_allow_html=True)
146
-
147
- def save_full_transcript(query, text):
148
- """Save full transcript of Arxiv results as a file."""
149
- create_file(query, text, "md")
150
-
151
- def perform_ai_lookup(q, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=False):
152
- """Perform Arxiv search and generate audio summaries"""
153
- start = time.time()
154
- client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
155
- refs = client.predict(q,20,"Semantic Search","mistralai/Mixtral-8x7B-Instruct-v0.1",api_name="/update_with_rag_md")[0]
156
- r2 = client.predict(q,"mistralai/Mixtral-8x7B-Instruct-v0.1",True,api_name="/ask_llm")
157
-
158
- result = f"### 🔎 {q}\n\n{r2}\n\n{refs}"
159
-
160
- st.markdown(result)
161
-
162
- # Generate full audio version if requested
163
- if full_audio:
164
- complete_text = f"Complete response for query: {q}. {clean_for_speech(r2)} {clean_for_speech(refs)}"
165
- audio_file_full = speak_with_edge_tts(complete_text)
166
- st.write("### 📚 Full Audio")
167
- play_and_download_audio(audio_file_full)
168
-
169
- if vocal_summary:
170
- main_text = clean_for_speech(r2)
171
- audio_file_main = speak_with_edge_tts(main_text)
172
- st.write("### 🎙 Short Audio")
173
- play_and_download_audio(audio_file_main)
174
-
175
- if extended_refs:
176
- summaries_text = "Extended references: " + refs.replace('"','')
177
- summaries_text = clean_for_speech(summaries_text)
178
- audio_file_refs = speak_with_edge_tts(summaries_text)
179
- st.write("### 📜 Long Refs")
180
- play_and_download_audio(audio_file_refs)
181
-
182
- if titles_summary:
183
- titles = []
184
- for line in refs.split('\n'):
185
- m = re.search(r"\[([^\]]+)\]", line)
186
- if m:
187
- titles.append(m.group(1))
188
- if titles:
189
- titles_text = "Titles: " + ", ".join(titles)
190
- titles_text = clean_for_speech(titles_text)
191
- audio_file_titles = speak_with_edge_tts(titles_text)
192
- st.write("### 🔖 Titles")
193
- play_and_download_audio(audio_file_titles)
194
-
195
- elapsed = time.time()-start
196
- st.write(f"**Total Elapsed:** {elapsed:.2f} s")
197
-
198
- # Create file with result
199
- create_file(q, result, "md")
200
-
201
- return result
202
-
203
- def process_with_gpt(text):
204
- """Process text with GPT-4"""
205
- if not text: return
206
- st.session_state.messages.append({"role":"user","content":text})
207
- with st.chat_message("user"):
208
- st.markdown(text)
209
- with st.chat_message("assistant"):
210
- c = openai_client.chat.completions.create(
211
- model=st.session_state["openai_model"],
212
- messages=st.session_state.messages,
213
- stream=False
214
  )
215
- ans = c.choices[0].message.content
216
- st.write("GPT-4o: " + ans)
217
- create_file(text, ans, "md")
218
- st.session_state.messages.append({"role":"assistant","content":ans})
219
- return ans
220
-
221
- def process_with_claude(text):
222
- """Process text with Claude"""
223
- if not text: return
224
- with st.chat_message("user"):
225
- st.markdown(text)
226
- with st.chat_message("assistant"):
227
- r = claude_client.messages.create(
228
- model="claude-3-sonnet-20240229",
229
- max_tokens=1000,
230
- messages=[{"role":"user","content":text}]
231
- )
232
- ans = r.content[0].text
233
- st.write("Claude-3.5: " + ans)
234
- create_file(text, ans, "md")
235
- st.session_state.chat_history.append({"user":text,"claude":ans})
236
- return ans
237
-
238
- def generate_filename(prompt, response, file_type="md"):
239
- """Generate filename with timestamp and cleaned text."""
240
- timestamp = datetime.now().strftime("%y%m_%H%M")
241
- safe_text = re.sub(r'[^\w\s-]', '', prompt[:50])
242
- return f"{timestamp}_{safe_text}.{file_type}"
243
-
244
- def create_file(prompt, response, file_type="md"):
245
- """Create file with content."""
246
- filename = generate_filename(prompt.strip(), response.strip(), file_type)
247
- with open(filename, 'w', encoding='utf-8') as f:
248
- f.write(prompt + "\n\n" + response)
249
- return filename
250
-
251
- def get_download_link(file):
252
- """Generate download link for file"""
253
- with open(file, "rb") as f:
254
- b64 = base64.b64encode(f.read()).decode()
255
- return f'<a href="data:file/zip;base64,{b64}" download="{os.path.basename(file)}">📂 Download {os.path.basename(file)}</a>'
256
-
257
- import streamlit as st
258
- import anthropic, openai, base64, cv2, glob, json, math, os, pytz, random, re, requests, time, zipfile
259
- import plotly.graph_objects as go
260
- import streamlit.components.v1 as components
261
- from datetime import datetime
262
- from audio_recorder_streamlit import audio_recorder
263
- from bs4 import BeautifulSoup
264
- from collections import defaultdict, deque
265
- from dotenv import load_dotenv
266
- from gradio_client import Client
267
- from huggingface_hub import InferenceClient
268
- from io import BytesIO
269
- from PIL import Image
270
- from PyPDF2 import PdfReader
271
- from urllib.parse import quote
272
- from xml.etree import ElementTree as ET
273
- from openai import OpenAI
274
- import extra_streamlit_components as stx
275
- from streamlit.runtime.scriptrunner import get_script_run_ctx
276
- import asyncio
277
- import edge_tts
278
-
279
- # 🎯 1. Core Configuration & Setup
280
- st.set_page_config(
281
- page_title="🚲BikeAI🏆 Claude/GPT Research",
282
- page_icon="🚲🏆",
283
- layout="wide",
284
- initial_sidebar_state="auto",
285
- menu_items={
286
- 'Get Help': 'https://huggingface.co/awacke1',
287
- 'Report a bug': 'https://huggingface.co/spaces/awacke1',
288
- 'About': "🚲BikeAI🏆 Claude/GPT Research AI"
289
- }
290
- )
291
- load_dotenv()
292
-
293
- # 🔑 2. API Setup & Clients
294
- openai_api_key = os.getenv('OPENAI_API_KEY', "")
295
- anthropic_key = os.getenv('ANTHROPIC_API_KEY_3', "")
296
- xai_key = os.getenv('xai',"")
297
- if 'OPENAI_API_KEY' in st.secrets:
298
- openai_api_key = st.secrets['OPENAI_API_KEY']
299
- if 'ANTHROPIC_API_KEY' in st.secrets:
300
- anthropic_key = st.secrets["ANTHROPIC_API_KEY"]
301
-
302
- openai.api_key = openai_api_key
303
- claude_client = anthropic.Anthropic(api_key=anthropic_key)
304
- openai_client = OpenAI(api_key=openai.api_key, organization=os.getenv('OPENAI_ORG_ID'))
305
- HF_KEY = os.getenv('HF_KEY')
306
- API_URL = os.getenv('API_URL')
307
-
308
- # 📝 3. Session State Management
309
- if 'transcript_history' not in st.session_state:
310
- st.session_state['transcript_history'] = []
311
- if 'chat_history' not in st.session_state:
312
- st.session_state['chat_history'] = []
313
- if 'openai_model' not in st.session_state:
314
- st.session_state['openai_model'] = "gpt-4o-2024-05-13"
315
- if 'messages' not in st.session_state:
316
- st.session_state['messages'] = []
317
- if 'last_voice_input' not in st.session_state:
318
- st.session_state['last_voice_input'] = ""
319
- if 'editing_file' not in st.session_state:
320
- st.session_state['editing_file'] = None
321
- if 'edit_new_name' not in st.session_state:
322
- st.session_state['edit_new_name'] = ""
323
- if 'edit_new_content' not in st.session_state:
324
- st.session_state['edit_new_content'] = ""
325
- if 'viewing_prefix' not in st.session_state:
326
- st.session_state['viewing_prefix'] = None
327
- if 'should_rerun' not in st.session_state:
328
- st.session_state['should_rerun'] = False
329
- if 'old_val' not in st.session_state:
330
- st.session_state['old_val'] = None
331
-
332
- # 🎨 4. Custom CSS
333
- st.markdown("""
334
- <style>
335
- .main { background: linear-gradient(to right, #1a1a1a, #2d2d2d); color: #fff; }
336
- .stMarkdown { font-family: 'Helvetica Neue', sans-serif; }
337
- .stButton>button {
338
- margin-right: 0.5rem;
339
- }
340
- .audio-player {
341
- margin: 1rem 0;
342
- padding: 1rem;
343
- border-radius: 10px;
344
- background: #f5f5f5;
345
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
346
- }
347
- </style>
348
- """, unsafe_allow_html=True)
349
 
350
- FILE_EMOJIS = {
351
- "md": "📝",
352
- "mp3": "🎵",
353
- }
354
 
355
- def clean_for_speech(text: str) -> str:
356
- """Clean text for speech synthesis"""
357
- text = text.replace("\n", " ")
358
- text = text.replace("</s>", " ")
359
- text = text.replace("#", "")
360
- text = re.sub(r"\(https?:\/\/[^\)]+\)", "", text)
361
- text = re.sub(r"\s+", " ", text).strip()
362
- return text
363
 
364
- @st.cache_resource
365
- def speech_synthesis_html(result):
366
- """Create HTML for speech synthesis"""
367
- html_code = f"""
368
- <html><body>
369
- <script>
370
- var msg = new SpeechSynthesisUtterance("{result.replace('"', '')}");
371
- window.speechSynthesis.speak(msg);
372
- </script>
373
- </body></html>
374
- """
375
- components.html(html_code, height=0)
376
 
377
- async def edge_tts_generate_audio(text, voice="en-US-AriaNeural", rate=0, pitch=0):
378
- """Generate audio using Edge TTS"""
379
- text = clean_for_speech(text)
380
- if not text.strip():
381
  return None
382
- rate_str = f"{rate:+d}%"
383
- pitch_str = f"{pitch:+d}Hz"
384
- communicate = edge_tts.Communicate(text, voice, rate=rate_str, pitch=pitch_str)
385
- out_fn = generate_filename(text, text, "mp3")
386
- await communicate.save(out_fn)
387
- return out_fn
388
-
389
- def speak_with_edge_tts(text, voice="en-US-AriaNeural", rate=0, pitch=0):
390
- """Wrapper for edge TTS generation"""
391
- return asyncio.run(edge_tts_generate_audio(text, voice, rate, pitch))
392
-
393
- def play_and_download_audio(file_path):
394
- """Play and provide download link for audio"""
395
- if file_path and os.path.exists(file_path):
396
- st.audio(file_path)
397
- dl_link = f'<a href="data:audio/mpeg;base64,{base64.b64encode(open(file_path,"rb").read()).decode()}" download="{os.path.basename(file_path)}">Download {os.path.basename(file_path)}</a>'
398
- st.markdown(dl_link, unsafe_allow_html=True)
399
-
400
- def save_full_transcript(query, text):
401
- """Save full transcript of Arxiv results as a file."""
402
- create_file(query, text, "md")
403
-
404
- def perform_ai_lookup(q, vocal_summary=True, extended_refs=False, titles_summary=True, full_audio=False):
405
- """Perform Arxiv search and generate audio summaries"""
406
- start = time.time()
407
- client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
408
- refs = client.predict(q,20,"Semantic Search","mistralai/Mixtral-8x7B-Instruct-v0.1",api_name="/update_with_rag_md")[0]
409
- r2 = client.predict(q,"mistralai/Mixtral-8x7B-Instruct-v0.1",True,api_name="/ask_llm")
410
-
411
- result = f"### 🔎 {q}\n\n{r2}\n\n{refs}"
412
-
413
- st.markdown(result)
414
-
415
- # Generate full audio version if requested
416
- if full_audio:
417
- complete_text = f"Complete response for query: {q}. {clean_for_speech(r2)} {clean_for_speech(refs)}"
418
- audio_file_full = speak_with_edge_tts(complete_text)
419
- st.write("### 📚 Full Audio")
420
- play_and_download_audio(audio_file_full)
421
-
422
- if vocal_summary:
423
- main_text = clean_for_speech(r2)
424
- audio_file_main = speak_with_edge_tts(main_text)
425
- st.write("### 🎙 Short Audio")
426
- play_and_download_audio(audio_file_main)
427
-
428
- if extended_refs:
429
- summaries_text = "Extended references: " + refs.replace('"','')
430
- summaries_text = clean_for_speech(summaries_text)
431
- audio_file_refs = speak_with_edge_tts(summaries_text)
432
- st.write("### 📜 Long Refs")
433
- play_and_download_audio(audio_file_refs)
434
-
435
- if titles_summary:
436
- titles = []
437
- for line in refs.split('\n'):
438
- m = re.search(r"\[([^\]]+)\]", line)
439
- if m:
440
- titles.append(m.group(1))
441
- if titles:
442
- titles_text = "Titles: " + ", ".join(titles)
443
- titles_text = clean_for_speech(titles_text)
444
- audio_file_titles = speak_with_edge_tts(titles_text)
445
- st.write("### 🔖 Titles")
446
- play_and_download_audio(audio_file_titles)
447
-
448
- elapsed = time.time()-start
449
- st.write(f"**Total Elapsed:** {elapsed:.2f} s")
450
-
451
- # Create file with result
452
- create_file(q, result, "md")
453
-
454
- return result
455
-
456
- def process_with_gpt(text):
457
- """Process text with GPT-4"""
458
- if not text: return
459
- st.session_state.messages.append({"role":"user","content":text})
460
- with st.chat_message("user"):
461
- st.markdown(text)
462
- with st.chat_message("assistant"):
463
- c = openai_client.chat.completions.create(
464
- model=st.session_state["openai_model"],
465
- messages=st.session_state.messages,
466
- stream=False
467
- )
468
- ans = c.choices[0].message.content
469
- st.write("GPT-4o: " + ans)
470
- create_file(text, ans, "md")
471
- st.session_state.messages.append({"role":"assistant","content":ans})
472
- return ans
473
-
474
- def process_with_claude(text):
475
- """Process text with Claude"""
476
- if not text: return
477
- with st.chat_message("user"):
478
- st.markdown(text)
479
- with st.chat_message("assistant"):
480
- r = claude_client.messages.create(
481
- model="claude-3-sonnet-20240229",
482
- max_tokens=1000,
483
- messages=[{"role":"user","content":text}]
484
- )
485
- ans = r.content[0].text
486
- st.write("Claude-3.5: " + ans)
487
- create_file(text, ans, "md")
488
- st.session_state.chat_history.append({"user":text,"claude":ans})
489
- return ans
490
-
491
- def generate_filename(prompt, response, file_type="md"):
492
- """Generate filename with timestamp and cleaned text."""
493
- timestamp = datetime.now().strftime("%y%m_%H%M")
494
- safe_text = re.sub(r'[^\w\s-]', '', prompt[:50])
495
- return f"{timestamp}_{safe_text}.{file_type}"
496
-
497
- def create_file(prompt, response, file_type="md"):
498
- """Create file with content."""
499
- filename = generate_filename(prompt.strip(), response.strip(), file_type)
500
- with open(filename, 'w', encoding='utf-8') as f:
501
- f.write(prompt + "\n\n" + response)
502
- return filename
503
-
504
- def get_download_link(file):
505
- """Generate download link for file"""
506
- with open(file, "rb") as f:
507
- b64 = base64.b64encode(f.read()).decode()
508
- return f'<a href="data:file/zip;base64,{b64}" download="{os.path.basename(file)}">📂 Download {os.path.basename(file)}</a>'
509
 
510
  def main():
511
- st.sidebar.markdown("### 🚲BikeAI🏆 Multi-Agent Research")
512
- tab_main = st.radio("Action:",["🎤 Voice","📸 Media","🔍 ArXiv","📝 Editor"],horizontal=True)
513
-
514
  mycomponent = components.declare_component("mycomponent", path="mycomponent")
515
  val = mycomponent(my_input_value="Hello")
516
 
517
- # Show input in text box for editing if detected
518
  if val:
519
  val_stripped = val.replace('\n', ' ')
520
  edited_input = st.text_area("✏️ Edit Input:", value=val_stripped, height=100)
521
- run_option = st.selectbox("Model:", ["Arxiv", "GPT-4o", "Claude-3.5"])
522
- col1, col2 = st.columns(2)
523
  with col1:
524
- autorun = st.checkbox(" AutoRun", value=True)
525
  with col2:
526
- full_audio = st.checkbox("📚FullAudio", value=False,
527
- help="Full audio of results")
528
- full_transcript = st.checkbox("🧾FullTranscript", value=False,
529
- help="Generate a full transcript file")
530
-
531
- if q and st.button("🔍Run"):
532
- result = perform_ai_lookup(q, vocal_summary=vocal_summary, extended_refs=extended_refs,
533
- titles_summary=titles_summary, full_audio=full_audio)
534
- if full_transcript:
535
- save_full_transcript(q, result)
536
-
537
- st.markdown("### Change Prompt & Re-Run")
538
- q_new = st.text_input("🔄 Modify Query:")
539
- if q_new and st.button("🔄 Re-Run with Modified Query"):
540
- result = perform_ai_lookup(q_new, vocal_summary=vocal_summary, extended_refs=extended_refs,
541
- titles_summary=titles_summary, full_audio=full_audio)
542
- if full_transcript:
543
- save_full_transcript(q_new, result)
544
-
545
- elif tab_main == "🎤 Voice":
546
- st.subheader("🎤 Voice Input")
547
- user_text = st.text_area("💬 Message:", height=100)
548
- user_text = user_text.strip().replace('\n', ' ')
549
- if st.button("📨 Send"):
550
- process_with_gpt(user_text)
551
- st.subheader("📜 Chat History")
552
- t1,t2=st.tabs(["Claude History","GPT-4o History"])
553
- with t1:
554
- for c in st.session_state.chat_history:
555
- st.write("**You:**", c["user"])
556
- st.write("**Claude:**", c["claude"])
557
- with t2:
558
- for m in st.session_state.messages:
559
- with st.chat_message(m["role"]):
560
- st.markdown(m["content"])
561
-
562
- elif tab_main == "📸 Media":
563
- st.header("📸 Images & 🎥 Videos")
564
- tabs = st.tabs(["🖼 Images", "🎥 Video"])
565
- with tabs[0]:
566
- imgs = glob.glob("*.png")+glob.glob("*.jpg")
567
- if imgs:
568
- c = st.slider("Cols",1,5,3)
569
- cols = st.columns(c)
570
- for i,f in enumerate(imgs):
571
- with cols[i%c]:
572
- st.image(Image.open(f),use_container_width=True)
573
- if st.button(f"👀 Analyze {os.path.basename(f)}", key=f"analyze_{f}"):
574
- a = process_image(f,"Describe this image.")
575
- st.markdown(a)
576
- else:
577
- st.write("No images found.")
578
- with tabs[1]:
579
- vids = glob.glob("*.mp4")
580
- if vids:
581
- for v in vids:
582
- with st.expander(f"🎥 {os.path.basename(v)}"):
583
- st.video(v)
584
- if st.button(f"Analyze {os.path.basename(v)}", key=f"analyze_{v}"):
585
- a = process_video_with_gpt(v,"Describe video.")
586
- st.markdown(a)
587
- else:
588
- st.write("No videos found.")
589
 
590
- elif tab_main == "📝 Editor":
591
- if getattr(st.session_state,'current_file',None):
592
- st.subheader(f"Editing: {st.session_state.current_file}")
593
- new_text = st.text_area("✏️ Content:", st.session_state.file_content, height=300)
594
- if st.button("💾 Save"):
595
- with open(st.session_state.current_file,'w',encoding='utf-8') as f:
596
- f.write(new_text)
597
- st.success("Updated!")
598
- st.session_state.should_rerun = True
599
  else:
600
- st.write("Select a file from the sidebar to edit.")
601
-
602
- groups, sorted_prefixes = load_files_for_sidebar()
603
- display_file_manager_sidebar(groups, sorted_prefixes)
604
-
605
- if st.session_state.viewing_prefix and st.session_state.viewing_prefix in groups:
606
- st.write("---")
607
- st.write(f"**Viewing Group:** {st.session_state.viewing_prefix}")
608
- for f in groups[st.session_state.viewing_prefix]:
609
- fname = os.path.basename(f)
610
- ext = os.path.splitext(fname)[1].lower().strip('.')
611
- st.write(f"### {fname}")
612
- if ext == "md":
613
- content = open(f,'r',encoding='utf-8').read()
614
- st.markdown(content)
615
- elif ext == "mp3":
616
- st.audio(f)
617
- else:
618
- st.markdown(get_download_link(f), unsafe_allow_html=True)
619
- if st.button("❌ Close"):
620
- st.session_state.viewing_prefix = None
621
-
622
- if st.session_state.should_rerun:
623
- st.session_state.should_rerun = False
624
- st.rerun()
625
 
626
  if __name__ == "__main__":
627
  main()
 
1
  import streamlit as st
2
 
3
+ # Must be first Streamlit command
4
  st.set_page_config(
5
+ page_title="ARIA Research Assistant",
6
+ page_icon="🔬",
7
  layout="wide",
8
+ initial_sidebar_state="auto"
 
 
 
 
 
9
  )
10
 
11
+ import anthropic
12
+ import openai
13
+ import base64
14
+ import cv2
15
+ import glob
16
+ import json
17
+ import os
18
+ import pytz
19
+ import random
20
+ import re
21
+ import requests
22
+ import time
23
+ import zipfile
24
  import plotly.graph_objects as go
25
  import streamlit.components.v1 as components
26
  from datetime import datetime
 
30
  from dotenv import load_dotenv
31
  from gradio_client import Client
32
  from huggingface_hub import InferenceClient
 
33
  from PIL import Image
34
  from PyPDF2 import PdfReader
35
  from urllib.parse import quote
36
  from xml.etree import ElementTree as ET
37
  from openai import OpenAI
38
  import extra_streamlit_components as stx
 
39
  import asyncio
40
  import edge_tts
41
 
42
+ # Load environment variables
43
  load_dotenv()
44
 
45
+ # API Setup & Clients
46
+ openai_api_key = os.getenv('OPENAI_API_KEY', st.secrets.get('OPENAI_API_KEY', ''))
47
+ anthropic_key = os.getenv('ANTHROPIC_API_KEY_3', st.secrets.get('ANTHROPIC_API_KEY', ''))
48
+ xai_key = os.getenv('xai', '')
 
 
 
 
49
 
50
  openai.api_key = openai_api_key
51
  claude_client = anthropic.Anthropic(api_key=anthropic_key)
52
  openai_client = OpenAI(api_key=openai.api_key, organization=os.getenv('OPENAI_ORG_ID'))
 
 
53
 
54
+ # Session State Management
 
 
55
  if 'chat_history' not in st.session_state:
56
  st.session_state['chat_history'] = []
 
 
57
  if 'messages' not in st.session_state:
58
  st.session_state['messages'] = []
 
 
 
 
 
 
 
 
 
 
 
 
59
  if 'old_val' not in st.session_state:
60
  st.session_state['old_val'] = None
61
+ if 'current_audio' not in st.session_state:
62
+ st.session_state['current_audio'] = None
63
 
64
+ # Styling
65
  st.markdown("""
66
  <style>
67
  .main { background: linear-gradient(to right, #1a1a1a, #2d2d2d); color: #fff; }
 
68
  .stButton>button {
69
  margin-right: 0.5rem;
70
+ background-color: #4CAF50;
71
+ color: white;
72
+ padding: 0.5rem 1rem;
73
+ border-radius: 5px;
74
+ border: none;
 
 
75
  }
76
  </style>
77
  """, unsafe_allow_html=True)
78
 
79
+ # Audio Functions
 
 
 
 
80
  def clean_for_speech(text: str) -> str:
81
  """Clean text for speech synthesis"""
82
  text = text.replace("\n", " ")
 
86
  text = re.sub(r"\s+", " ", text).strip()
87
  return text
88
 
89
+ def get_audio_html(audio_path):
90
+ """Create HTML for autoplaying audio"""
91
+ try:
92
+ with open(audio_path, "rb") as audio_file:
93
+ audio_bytes = audio_file.read()
94
+ audio_b64 = base64.b64encode(audio_bytes).decode()
95
+ return f'''
96
+ <audio controls autoplay>
97
+ <source src="data:audio/mpeg;base64,{audio_b64}" type="audio/mpeg">
98
+ </audio>
99
+ <a href="data:audio/mpeg;base64,{audio_b64}"
100
+ download="{os.path.basename(audio_path)}">
101
+ Download {os.path.basename(audio_path)}
102
+ </a>
103
+ '''
104
+ except Exception as e:
105
+ return f"Error loading audio: {str(e)}"
106
+
107
+ async def generate_audio(text, voice="en-US-AriaNeural"):
108
  """Generate audio using Edge TTS"""
 
109
  if not text.strip():
110
  return None
111
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
112
+ output_file = f"response_{timestamp}.mp3"
113
+ communicate = edge_tts.Communicate(text, voice)
114
+ await communicate.save(output_file)
115
+ return output_file
116
+
117
+ # Core Search Function
118
+ def perform_ai_lookup(query, vocal_summary=True, full_audio=False):
119
+ """Perform search with automatic audio generation"""
120
+ try:
121
+ client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
122
+ refs = client.predict(
123
+ query,
124
+ 20,
125
+ "Semantic Search",
126
+ "mistralai/Mixtral-8x7B-Instruct-v0.1",
127
+ api_name="/update_with_rag_md"
128
+ )[0]
129
+ summary = client.predict(
130
+ query,
131
+ "mistralai/Mixtral-8x7B-Instruct-v0.1",
132
+ True,
133
+ api_name="/ask_llm"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
+ result = f"### 🔎 Search Results\n\n{summary}\n\n### References\n\n{refs}"
137
+ st.markdown(result)
 
 
138
 
139
+ # Generate and play audio
140
+ if full_audio:
141
+ audio_file = asyncio.run(generate_audio(summary))
142
+ if audio_file:
143
+ st.markdown(get_audio_html(audio_file), unsafe_allow_html=True)
 
 
 
144
 
145
+ return result
 
 
 
 
 
 
 
 
 
 
 
146
 
147
+ except Exception as e:
148
+ st.error(f"Error in search: {str(e)}")
 
 
149
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
  def main():
152
+ st.sidebar.markdown("### Research Assistant")
153
+
154
+ # Voice component
155
  mycomponent = components.declare_component("mycomponent", path="mycomponent")
156
  val = mycomponent(my_input_value="Hello")
157
 
158
+ # Handle voice input
159
  if val:
160
  val_stripped = val.replace('\n', ' ')
161
  edited_input = st.text_area("✏️ Edit Input:", value=val_stripped, height=100)
162
+
163
+ col1, col2 = st.columns([3,1])
164
  with col1:
165
+ model = st.selectbox("Model:", ["Arxiv", "GPT-4", "Claude"])
166
  with col2:
167
+ autorun = st.checkbox("⚙ AutoRun", value=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
+ # Check for changes and autorun
170
+ input_changed = (val != st.session_state.old_val)
171
+ if autorun and input_changed:
172
+ st.session_state.old_val = val
173
+ if edited_input:
174
+ perform_ai_lookup(edited_input, vocal_summary=True, full_audio=True)
 
 
 
175
  else:
176
+ if st.button("🔍 Search"):
177
+ perform_ai_lookup(edited_input, vocal_summary=True, full_audio=True)
178
+
179
+ # Manual search tab
180
+ st.markdown("### 🔍 Direct Search")
181
+ query = st.text_input("Enter search query:")
182
+ if query and st.button("Search"):
183
+ perform_ai_lookup(query, vocal_summary=True, full_audio=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  if __name__ == "__main__":
186
  main()