awacke1 commited on
Commit
d250d87
Β·
verified Β·
1 Parent(s): b0cf278

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -59
app.py CHANGED
@@ -8,7 +8,6 @@ import edge_tts
8
  import streamlit.components.v1 as components
9
 
10
  # -------------------- Configuration --------------------
11
- # Exactly 11 user names and 11 voices (as an example)
12
  USER_NAMES = [
13
  "Aria", "Guy", "Sonia", "Tony", "Jenny", "Davis", "Libby", "Clara", "Liam", "Natasha", "William"
14
  ]
@@ -20,24 +19,18 @@ ENGLISH_VOICES = [
20
  ]
21
 
22
  USER_VOICES = dict(zip(USER_NAMES, ENGLISH_VOICES))
23
-
24
  SAVED_INPUTS_DIR = "saved_inputs"
25
  os.makedirs(SAVED_INPUTS_DIR, exist_ok=True)
26
 
27
- # Session state
28
  if 'user_name' not in st.session_state:
29
  st.session_state['user_name'] = USER_NAMES[0]
30
-
31
  if 'old_val' not in st.session_state:
32
  st.session_state['old_val'] = None
33
-
34
  if 'should_rerun' not in st.session_state:
35
  st.session_state['should_rerun'] = False
36
-
37
  if 'viewing_prefix' not in st.session_state:
38
  st.session_state['viewing_prefix'] = None
39
 
40
- # -------------------- Utility Functions --------------------
41
  def clean_for_speech(text: str) -> str:
42
  text = text.replace("\n", " ")
43
  text = text.replace("</s>", " ")
@@ -118,16 +111,26 @@ def arxiv_search(query, max_results=3):
118
  for entry in entries:
119
  title = entry.find('a:title', ns).text.strip()
120
  summary = entry.find('a:summary', ns).text.strip()
 
 
 
 
 
 
121
  summary_short = summary[:300] + "..."
122
- results.append((title, summary_short))
 
 
 
 
 
123
  return results
124
  return []
125
 
126
  def summarize_arxiv_results(results):
127
- lines = []
128
- for i, (title, summary) in enumerate(results, 1):
129
- lines.append(f"Result {i}: {title}\n{summary}\n")
130
- return "\n\n".join(lines)
131
 
132
  def concatenate_mp3(files, output_file):
133
  with open(output_file, 'wb') as outfile:
@@ -135,21 +138,6 @@ def concatenate_mp3(files, output_file):
135
  with open(f, 'rb') as infile:
136
  outfile.write(infile.read())
137
 
138
- def load_groups():
139
- files = list_saved_inputs()
140
- groups = defaultdict(list)
141
- for fpath in files:
142
- fname = os.path.basename(fpath)
143
- prefix = fname[:10]
144
- groups[prefix].append(fpath)
145
- for prefix in groups:
146
- groups[prefix].sort(key=lambda x: os.path.getmtime(x), reverse=True)
147
- sorted_prefixes = sorted(groups.keys(),
148
- key=lambda pre: max(os.path.getmtime(x) for x in groups[pre]),
149
- reverse=True)
150
- return groups, sorted_prefixes
151
-
152
- # -------------------- Main Application --------------------
153
  st.title("πŸŽ™οΈ Voice Chat & ArXiv Search")
154
 
155
  with st.sidebar:
@@ -169,55 +157,45 @@ with st.sidebar:
169
  st.success("All history cleared!")
170
  st.experimental_rerun()
171
 
172
- # Voice input component (replace path with your component)
173
  mycomponent = components.declare_component("mycomponent", path="mycomponent")
174
  voice_val = mycomponent(my_input_value="Start speaking...")
175
 
176
- tabs = st.tabs(["🎀 Voice Chat", "πŸ” ArXiv Search", "πŸ’Ύ History", "βš™οΈ Settings"])
177
 
178
  # ------------------ Voice Chat Tab -------------------------
179
  with tabs[0]:
180
  st.subheader("🎀 Voice Chat")
181
  if voice_val:
182
  voice_text = voice_val.strip()
183
- edited_input = st.text_area("✏️ Edit Voice Input:", value=voice_text, height=100)
184
- autorun = st.checkbox("⚑ Auto-Run", value=True)
185
  input_changed = (voice_text != st.session_state.get('old_val'))
 
 
 
186
 
187
- if autorun and input_changed:
188
- st.session_state['old_val'] = voice_text
189
- # Save input right away
190
- saved_path = save_input_as_md(st.session_state['user_name'], edited_input, prefix="input")
191
- st.success("Saved input!")
192
-
193
- if st.button("πŸ“ Save Input Manually"):
194
- saved_path = save_input_as_md(st.session_state['user_name'], edited_input, prefix="input")
195
- st.success("Saved input!")
196
-
197
- st.write("Use the sidebar to select user and the voice input component above to record messages.")
198
-
199
- # ------------------ ArXiv Search Tab -------------------------
200
- with tabs[1]:
201
- st.subheader("πŸ” ArXiv Search")
202
- query = st.text_input("Enter Query:")
203
- if query and st.button("πŸ” Search ArXiv"):
204
- with st.spinner("Searching..."):
205
- results = arxiv_search(query)
206
- if results:
207
  summary = summarize_arxiv_results(results)
208
  # Save as response
209
  save_input_as_md(st.session_state['user_name'], summary, prefix="arxiv")
210
  st.write(summary)
211
- # Read aloud summary
 
212
  voice = USER_VOICES.get(st.session_state['user_name'], "en-US-AriaNeural")
213
  audio_file = speak_with_edge_tts(summary, voice=voice)
214
  if audio_file:
215
  play_and_download_audio(audio_file)
216
- else:
217
- st.warning("No results found.")
 
 
 
 
 
 
218
 
219
  # ------------------ History Tab -------------------------
220
- with tabs[2]:
221
  st.subheader("πŸ’Ύ History")
222
  files = list_saved_inputs()
223
  conversation = []
@@ -225,7 +203,6 @@ with tabs[2]:
225
  user, ts, content = parse_md_file(fpath)
226
  conversation.append((user, ts, content, fpath))
227
 
228
- # Show conversation and read aloud each line
229
  for i, (user, ts, content, fpath) in enumerate(reversed(conversation), start=1):
230
  with st.expander(f"{ts} - {user}", expanded=False):
231
  st.write(content)
@@ -235,7 +212,6 @@ with tabs[2]:
235
  if audio_file:
236
  play_and_download_audio(audio_file)
237
 
238
- # Read entire conversation
239
  if st.button("πŸ“œ Read Entire Conversation"):
240
  conversation_chrono = list(reversed(conversation))
241
  mp3_files = []
@@ -254,9 +230,9 @@ with tabs[2]:
254
  play_and_download_audio(combined_file)
255
 
256
  # ------------------ Settings Tab -------------------------
257
- with tabs[3]:
258
  st.subheader("βš™οΈ Settings")
259
- st.write("Adjust parameters in the sidebar. Currently, no other settings to configure.")
260
 
261
  if st.session_state.should_rerun:
262
  st.session_state.should_rerun = False
 
8
  import streamlit.components.v1 as components
9
 
10
  # -------------------- Configuration --------------------
 
11
  USER_NAMES = [
12
  "Aria", "Guy", "Sonia", "Tony", "Jenny", "Davis", "Libby", "Clara", "Liam", "Natasha", "William"
13
  ]
 
19
  ]
20
 
21
  USER_VOICES = dict(zip(USER_NAMES, ENGLISH_VOICES))
 
22
  SAVED_INPUTS_DIR = "saved_inputs"
23
  os.makedirs(SAVED_INPUTS_DIR, exist_ok=True)
24
 
 
25
  if 'user_name' not in st.session_state:
26
  st.session_state['user_name'] = USER_NAMES[0]
 
27
  if 'old_val' not in st.session_state:
28
  st.session_state['old_val'] = None
 
29
  if 'should_rerun' not in st.session_state:
30
  st.session_state['should_rerun'] = False
 
31
  if 'viewing_prefix' not in st.session_state:
32
  st.session_state['viewing_prefix'] = None
33
 
 
34
  def clean_for_speech(text: str) -> str:
35
  text = text.replace("\n", " ")
36
  text = text.replace("</s>", " ")
 
111
  for entry in entries:
112
  title = entry.find('a:title', ns).text.strip()
113
  summary = entry.find('a:summary', ns).text.strip()
114
+ # Extract links (PDF) if available
115
+ links = entry.findall('a:link', ns)
116
+ pdf_link = None
117
+ for link in links:
118
+ if link.get('type') == 'application/pdf':
119
+ pdf_link = link.get('href')
120
  summary_short = summary[:300] + "..."
121
+ # Include PDF link and title
122
+ if pdf_link:
123
+ formatted = f"Title: {title}\nPDF: {pdf_link}\nSummary: {summary_short}"
124
+ else:
125
+ formatted = f"Title: {title}\n(No PDF link)\nSummary: {summary_short}"
126
+ results.append(formatted)
127
  return results
128
  return []
129
 
130
  def summarize_arxiv_results(results):
131
+ if not results:
132
+ return "No results found."
133
+ return "\n\n".join(results)
 
134
 
135
  def concatenate_mp3(files, output_file):
136
  with open(output_file, 'wb') as outfile:
 
138
  with open(f, 'rb') as infile:
139
  outfile.write(infile.read())
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  st.title("πŸŽ™οΈ Voice Chat & ArXiv Search")
142
 
143
  with st.sidebar:
 
157
  st.success("All history cleared!")
158
  st.experimental_rerun()
159
 
 
160
  mycomponent = components.declare_component("mycomponent", path="mycomponent")
161
  voice_val = mycomponent(my_input_value="Start speaking...")
162
 
163
+ tabs = st.tabs(["🎀 Voice Chat", "πŸ’Ύ History", "βš™οΈ Settings"])
164
 
165
  # ------------------ Voice Chat Tab -------------------------
166
  with tabs[0]:
167
  st.subheader("🎀 Voice Chat")
168
  if voice_val:
169
  voice_text = voice_val.strip()
 
 
170
  input_changed = (voice_text != st.session_state.get('old_val'))
171
+ if input_changed and voice_text:
172
+ # 1. Save user input
173
+ save_input_as_md(st.session_state['user_name'], voice_text, prefix="input")
174
 
175
+ # 2. Perform ArXiv search automatically
176
+ with st.spinner("Searching ArXiv..."):
177
+ results = arxiv_search(voice_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  summary = summarize_arxiv_results(results)
179
  # Save as response
180
  save_input_as_md(st.session_state['user_name'], summary, prefix="arxiv")
181
  st.write(summary)
182
+
183
+ # 3. Convert summary to audio and auto-play
184
  voice = USER_VOICES.get(st.session_state['user_name'], "en-US-AriaNeural")
185
  audio_file = speak_with_edge_tts(summary, voice=voice)
186
  if audio_file:
187
  play_and_download_audio(audio_file)
188
+
189
+ # 4. Update old_val to avoid repeated searches for same input
190
+ st.session_state['old_val'] = voice_text
191
+
192
+ # 5. Clear displayed text and re-run so next utterance starts fresh
193
+ st.experimental_rerun()
194
+
195
+ st.write("Speak a query to automatically run an ArXiv search and read results aloud.")
196
 
197
  # ------------------ History Tab -------------------------
198
+ with tabs[1]:
199
  st.subheader("πŸ’Ύ History")
200
  files = list_saved_inputs()
201
  conversation = []
 
203
  user, ts, content = parse_md_file(fpath)
204
  conversation.append((user, ts, content, fpath))
205
 
 
206
  for i, (user, ts, content, fpath) in enumerate(reversed(conversation), start=1):
207
  with st.expander(f"{ts} - {user}", expanded=False):
208
  st.write(content)
 
212
  if audio_file:
213
  play_and_download_audio(audio_file)
214
 
 
215
  if st.button("πŸ“œ Read Entire Conversation"):
216
  conversation_chrono = list(reversed(conversation))
217
  mp3_files = []
 
230
  play_and_download_audio(combined_file)
231
 
232
  # ------------------ Settings Tab -------------------------
233
+ with tabs[2]:
234
  st.subheader("βš™οΈ Settings")
235
+ st.write("Currently no additional settings. Use the sidebar to pick a user.")
236
 
237
  if st.session_state.should_rerun:
238
  st.session_state.should_rerun = False