awacke1 commited on
Commit
a5ff92b
·
verified ·
1 Parent(s): 1ded060

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -134
app.py CHANGED
@@ -16,19 +16,17 @@ import streamlit as st
16
  import streamlit.components.v1 as components
17
 
18
  # If you do model inference via huggingface_hub:
19
- from huggingface_hub import InferenceClient
20
 
21
- # ----------------------------
22
- # Configurable BASE_URL
23
- # ----------------------------
24
  BASE_URL = "https://huggingface.co/spaces/awacke1/MermaidMarkdownDiagramEditor"
25
 
26
- # Example placeholders for prompt prefixes
27
  PromptPrefix = "AI-Search: "
28
  PromptPrefix2 = "AI-Refine: "
29
  PromptPrefix3 = "AI-JS: "
30
 
31
- # Example roleplaying glossary
32
  roleplaying_glossary = {
33
  "Core Rulebooks": {
34
  "Dungeons and Dragons": ["Player's Handbook", "Dungeon Master's Guide", "Monster Manual"],
@@ -39,61 +37,68 @@ roleplaying_glossary = {
39
  }
40
  }
41
 
42
- # Example transhuman glossary
43
  transhuman_glossary = {
44
  "Neural Interfaces": ["Cortex Jack", "Mind-Machine Fusion"],
45
  "Cybernetics": ["Robotic Limbs", "Augmented Eyes"],
46
  }
47
 
48
- # Simple function stubs
49
  def process_text(text):
 
50
  st.write(f"process_text called with: {text}")
51
 
52
  def search_arxiv(text):
 
53
  st.write(f"search_arxiv called with: {text}")
54
 
55
  def SpeechSynthesis(text):
 
56
  st.write(f"SpeechSynthesis called with: {text}")
57
 
58
  def process_image(image_file, prompt):
59
- return f"[process_image placeholder] Processing {image_file} with prompt: {prompt}"
 
60
 
61
  def process_video(video_file, seconds_per_frame):
62
- st.write(f"[process_video placeholder] Video: {video_file}, seconds/frame: {seconds_per_frame}")
 
63
 
64
- # Stub if you have a Hugging Face endpoint
65
  API_URL = "https://huggingface-inference-endpoint-placeholder"
66
  API_KEY = "hf_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
67
 
68
  @st.cache_resource
69
  def InferenceLLM(prompt):
 
70
  return f"[InferenceLLM placeholder response to prompt: {prompt}]"
71
 
72
- # ------------------------------------------
73
- # Glossary & File Utility
74
- # ------------------------------------------
 
75
  @st.cache_resource
76
  def display_glossary_entity(k):
77
  """
78
  Creates multiple link emojis for a single entity.
 
79
  """
80
  search_urls = {
81
- "🚀🌌ArXiv": lambda x: f"/?q={quote(x)}",
82
- "🃏Analyst": lambda x: f"/?q={quote(x)}-{quote(PromptPrefix)}",
83
- "📚PyCoder": lambda x: f"/?q={quote(x)}-{quote(PromptPrefix2)}",
84
- "🔬JSCoder": lambda x: f"/?q={quote(x)}-{quote(PromptPrefix3)}",
85
- "📖": lambda x: f"https://en.wikipedia.org/wiki/{quote(x)}",
86
- "🔍": lambda x: f"https://www.google.com/search?q={quote(x)}",
87
- "🔎": lambda x: f"https://www.bing.com/search?q={quote(x)}",
88
- "🎥": lambda x: f"https://www.youtube.com/results?search_query={quote(x)}",
89
- "🐦": lambda x: f"https://twitter.com/search?q={quote(x)}",
90
  }
91
  links_md = ' '.join([f"[{emoji}]({url(k)})" for emoji, url in search_urls.items()])
92
  st.markdown(f"**{k}** <small>{links_md}</small>", unsafe_allow_html=True)
93
 
 
94
  def display_content_or_image(query):
95
  """
96
- If a query matches something in transhuman_glossary or a local image, show it.
 
97
  """
98
  for category, term_list in transhuman_glossary.items():
99
  for term in term_list:
@@ -109,16 +114,15 @@ def display_content_or_image(query):
109
  return False
110
 
111
  def clear_query_params():
112
- """
113
- For clearing URL params, you'd typically use a new link or st.experimental_set_query_params().
114
- Here, we just warn the user.
115
- """
116
  st.warning("Define a redirect or link without query params if you want to truly clear them.")
117
 
118
- # -----------------------
119
- # File Handling
120
- # -----------------------
 
121
  def load_file(file_path):
 
122
  try:
123
  with open(file_path, "r", encoding='utf-8') as f:
124
  return f.read()
@@ -127,6 +131,7 @@ def load_file(file_path):
127
 
128
  @st.cache_resource
129
  def create_zip_of_files(files):
 
130
  zip_name = "Arxiv-Paper-Search-QA-RAG-Streamlit-Gradio-AP.zip"
131
  with zipfile.ZipFile(zip_name, 'w') as zipf:
132
  for file in files:
@@ -135,6 +140,7 @@ def create_zip_of_files(files):
135
 
136
  @st.cache_resource
137
  def get_zip_download_link(zip_file):
 
138
  with open(zip_file, 'rb') as f:
139
  data = f.read()
140
  b64 = base64.b64encode(data).decode()
@@ -143,6 +149,7 @@ def get_zip_download_link(zip_file):
143
  def get_table_download_link(file_path):
144
  """
145
  Creates a download link for a single file from your snippet.
 
146
  """
147
  try:
148
  with open(file_path, 'r', encoding='utf-8') as file:
@@ -151,13 +158,13 @@ def get_table_download_link(file_path):
151
  file_name = os.path.basename(file_path)
152
  ext = os.path.splitext(file_name)[1]
153
  mime_map = {
154
- '.txt': 'text/plain',
155
- '.py': 'text/plain',
156
  '.xlsx': 'text/plain',
157
- '.csv': 'text/plain',
158
- '.htm': 'text/html',
159
- '.md': 'text/markdown',
160
- '.wav': 'audio/wav'
161
  }
162
  mime_type = mime_map.get(ext, 'application/octet-stream')
163
  return f'<a href="data:{mime_type};base64,{b64}" target="_blank" download="{file_name}">{file_name}</a>'
@@ -165,6 +172,7 @@ def get_table_download_link(file_path):
165
  return ''
166
 
167
  def get_file_size(file_path):
 
168
  return os.path.getsize(file_path)
169
 
170
  def FileSidebar():
@@ -172,7 +180,7 @@ def FileSidebar():
172
  Renders .md files, providing open/view/delete/run logic in the sidebar.
173
  """
174
  all_files = glob.glob("*.md")
175
- # Exclude short-named or special files if needed
176
  all_files = [f for f in all_files if len(os.path.splitext(f)[0]) >= 5]
177
  all_files.sort(key=lambda x: (os.path.splitext(x)[1], x), reverse=True)
178
 
@@ -192,9 +200,9 @@ def FileSidebar():
192
  next_action = ''
193
 
194
  for file in all_files:
195
- col1, col2, col3, col4, col5 = st.sidebar.columns([1, 6, 1, 1, 1])
196
  with col1:
197
- if st.button("🌐", key="md_" + file):
198
  file_contents = load_file(file)
199
  file_name = file
200
  next_action = 'md'
@@ -202,7 +210,7 @@ def FileSidebar():
202
  with col2:
203
  st.markdown(get_table_download_link(file), unsafe_allow_html=True)
204
  with col3:
205
- if st.button("📂", key="open_" + file):
206
  file_contents = load_file(file)
207
  file_name = file
208
  next_action = 'open'
@@ -211,45 +219,42 @@ def FileSidebar():
211
  st.session_state['filetext'] = file_contents
212
  st.session_state['next_action'] = next_action
213
  with col4:
214
- if st.button("▶️", key="read_" + file):
215
  file_contents = load_file(file)
216
  file_name = file
217
  next_action = 'search'
218
  st.session_state['next_action'] = next_action
219
  with col5:
220
- if st.button("🗑", key="delete_" + file):
221
  os.remove(file)
222
  st.rerun()
223
 
224
- # If we loaded a file
225
  if file_contents:
226
  if next_action == 'open':
227
- open1, open2 = st.columns([0.8, 0.2])
228
  with open1:
229
  file_name_input = st.text_input('File Name:', file_name, key='file_name_input')
230
  file_content_area = st.text_area('File Contents:', file_contents, height=300, key='file_content_area')
231
-
232
  if st.button('💾 Save File'):
233
  with open(file_name_input, 'w', encoding='utf-8') as f:
234
  f.write(file_content_area)
235
  st.markdown(f'Saved {file_name_input} successfully.')
236
-
237
  elif next_action == 'search':
238
  file_content_area = st.text_area("File Contents:", file_contents, height=500)
239
  user_prompt = PromptPrefix2 + file_contents
240
  st.markdown(user_prompt)
241
  if st.button('🔍Re-Code'):
242
  search_arxiv(file_contents)
243
-
244
  elif next_action == 'md':
245
  st.markdown(file_contents)
246
  SpeechSynthesis(file_contents)
247
  if st.button("🔍Run"):
248
  st.write("Running GPT logic placeholder...")
249
 
250
- # ---------------------------
251
- # Scoring / Glossaries
252
- # ---------------------------
 
253
  score_dir = "scores"
254
  os.makedirs(score_dir, exist_ok=True)
255
 
@@ -293,17 +298,17 @@ def display_buttons_with_scores(num_columns_text):
293
  "Changeling": "🍃",
294
  }
295
  topic_emojis = {
296
- "Core Rulebooks": "📚",
297
- "Maps & Settings": "🗺️",
298
- "Game Mechanics & Tools": "⚙️",
299
- "Monsters & Adversaries": "👹",
300
- "Campaigns & Adventures": "📜",
301
- "Creatives & Assets": "🎨",
302
- "Game Master Resources": "🛠️",
303
- "Lore & Background": "📖",
304
- "Character Development": "🧍",
305
- "Homebrew Content": "🔧",
306
- "General Topics": "🌍",
307
  }
308
 
309
  for category, games in roleplaying_glossary.items():
@@ -318,10 +323,12 @@ def display_buttons_with_scores(num_columns_text):
318
  newscore = update_score(key.replace('?', ''))
319
  st.markdown(f"Scored **{category} - {game} - {term}** -> {newscore}")
320
 
321
- # -------------------------------
322
- # Image & Video
323
- # -------------------------------
 
324
  def display_images_and_wikipedia_summaries(num_columns=4):
 
325
  image_files = [f for f in os.listdir('.') if f.endswith('.png')]
326
  if not image_files:
327
  st.write("No PNG images found in the current directory.")
@@ -347,6 +354,7 @@ def display_images_and_wikipedia_summaries(num_columns=4):
347
  col_index += 1
348
 
349
  def display_videos_and_links(num_columns=4):
 
350
  video_files = [f for f in os.listdir('.') if f.endswith(('.mp4', '.webm'))]
351
  if not video_files:
352
  st.write("No MP4 or WEBM videos found in the current directory.")
@@ -370,9 +378,10 @@ def display_videos_and_links(num_columns=4):
370
  st.error("Invalid input for seconds per frame!")
371
  col_index += 1
372
 
373
- # --------------------------------
374
- # MERMAID DIAGRAM
375
- # --------------------------------
 
376
  def generate_mermaid_html(mermaid_code: str) -> str:
377
  """
378
  Returns HTML that centers the Mermaid diagram, loading from a CDN.
@@ -421,39 +430,43 @@ def inject_base_url(url: str) -> str:
421
  return url
422
  return f"{BASE_URL}{url}"
423
 
424
- DEFAULT_MERMAID = """
425
  flowchart LR
426
- U((User 😎)) -- "Talk 🗣️" --> LLM[LLM Agent 🤖\\nExtract Info]
427
  click U "/?q=User%20😎" _self
428
  click LLM "/?q=LLM%20Agent%20Extract%20Info" _blank
429
 
430
- LLM -- "Query 🔍" --> HS[Hybrid Search 🔎\\nVector+NER+Lexical]
431
  click HS "/?q=Hybrid%20Search%20Vector+NER+Lexical" _blank
432
 
433
- HS -- "Reason 🤔" --> RE[Reasoning Engine 🛠️\\nNeuralNetwork+Medical]
434
  click RE "/?q=Reasoning%20Engine%20NeuralNetwork+Medical" _blank
435
 
436
- RE -- "Link 📡" --> KG((Knowledge Graph 📚\\nOntology+GAR+RAG))
437
  click KG "/?q=Knowledge%20Graph%20Ontology+GAR+RAG" _blank
438
  """
439
 
 
 
 
 
440
  def main():
441
  st.set_page_config(page_title="Mermaid + Clickable Links with Base URL", layout="wide")
442
 
443
- # ---------------------------------------------
444
- # Query Param Parsing (non-experimental)
445
- # ---------------------------------------------
446
  query_params = st.query_params
447
- query_list = (query_params.get('q') or query_params.get('query') or [''])
448
- q_or_query = query_list[0] if query_list else ''
449
- if q_or_query.strip():
450
- # If there's a q= or query= param, do some processing
451
- search_payload = PromptPrefix + q_or_query
452
- st.markdown(search_payload)
453
- process_text(search_payload)
454
-
455
- if 'action' in st.query_params:
456
- action_list = st.query_params['action']
 
 
457
  if action_list:
458
  action = action_list[0]
459
  if action == 'show_message':
@@ -461,63 +474,54 @@ def main():
461
  elif action == 'clear':
462
  clear_query_params()
463
 
464
- # If a 'query' param is present, show content or image
465
- if 'query' in st.query_params:
466
- query_val = st.query_params['query'][0]
467
- display_content_or_image(query_val)
468
 
469
- # ---------------------------------------------
470
- # Let user pick if we want ?model=1
471
- # ---------------------------------------------
472
  st.sidebar.write("## Diagram Link Settings")
473
  model_selected = st.sidebar.checkbox("Append ?model=1 to each link?")
474
 
475
- # ---------------------------------------------
476
- # Rebuild the clickable lines in the Mermaid code
477
- # ---------------------------------------------
478
- base_diagram = DEFAULT_MERMAID
479
- lines = base_diagram.strip().split("\n")
480
  new_lines = []
481
  for line in lines:
482
- if "click " in line and '"/?' in line:
483
- parts = re.split(r'click\s+\S+\s+"([^"]+)"\s+(\S+)', line.strip())
484
- # e.g. line: click U "/?q=User%20😎" _self
485
- # parts might be:
486
- # [ 'click U ', '/?q=User%20😎', '_self', '' ]
487
- if len(parts) >= 3:
488
- prefix = parts[0] # e.g. "click U "
489
- old_url = parts[1] # e.g. /?q=User%20😎
490
- target = parts[2] # e.g. _self or _blank
491
 
492
  new_url = inject_base_url(old_url)
493
  new_url = append_model_param(new_url, model_selected)
494
 
495
- new_line = f'{prefix}"{new_url}" {target}'
496
  new_lines.append(new_line)
497
  else:
 
498
  new_lines.append(line)
499
  else:
500
  new_lines.append(line)
501
 
502
- mermaid_code = "\n".join(new_lines)
503
 
504
- # ---------------------------------------------
505
- # Render the top-centered Mermaid diagram
506
- # ---------------------------------------------
507
- st.sidebar.markdown("Mermaid Diagram with Base URL Injection")
508
- diagram_html = generate_mermaid_html(mermaid_code)
509
  components.html(diagram_html, height=400, scrolling=True)
510
 
511
- # ---------------------------------------------
512
- # Two-column interface: Markdown & Mermaid
513
- # ---------------------------------------------
514
  left_col, right_col = st.columns(2)
515
 
516
- # --- Left: Markdown Editor
517
  with left_col:
518
  st.subheader("Markdown Side 📝")
519
  if "markdown_text" not in st.session_state:
520
- st.session_state["markdown_text"] = "## Hello!\nType some *Markdown* here.\n"
 
521
  markdown_text = st.text_area(
522
  "Edit Markdown:",
523
  value=st.session_state["markdown_text"],
@@ -525,6 +529,7 @@ def main():
525
  )
526
  st.session_state["markdown_text"] = markdown_text
527
 
 
528
  colA, colB = st.columns(2)
529
  with colA:
530
  if st.button("🔄 Refresh Markdown"):
@@ -538,12 +543,10 @@ def main():
538
  st.markdown("**Preview:**")
539
  st.markdown(markdown_text)
540
 
541
- # --- Right: Mermaid Editor
542
  with right_col:
543
  st.subheader("Mermaid Side 🧜‍♂️")
544
-
545
  if "current_mermaid" not in st.session_state:
546
- st.session_state["current_mermaid"] = mermaid_code
547
 
548
  mermaid_input = st.text_area(
549
  "Edit Mermaid Code:",
@@ -566,9 +569,7 @@ def main():
566
  st.markdown("**Mermaid Source:**")
567
  st.code(mermaid_input, language="python", line_numbers=True)
568
 
569
- # ---------------------------------------------
570
- # Media Galleries
571
- # ---------------------------------------------
572
  st.markdown("---")
573
  st.header("Media Galleries")
574
 
@@ -578,23 +579,18 @@ def main():
578
  num_columns_video = st.slider("Choose Number of Video Columns", 1, 15, 5, key="num_columns_video")
579
  display_videos_and_links(num_columns_video)
580
 
581
- # If you want extended UI for text or glossary
582
  showExtendedTextInterface = False
583
  if showExtendedTextInterface:
584
- # For example:
585
- # display_glossary_grid(roleplaying_glossary)
586
  # num_columns_text = st.slider("Choose Number of Text Columns", 1, 15, 4)
587
  # display_buttons_with_scores(num_columns_text)
588
  pass
589
 
590
- # ---------------------------------------------
591
- # File Sidebar
592
- # ---------------------------------------------
593
  FileSidebar()
594
 
595
- # ---------------------------------------------
596
- # Random Title at the bottom
597
- # ---------------------------------------------
598
  titles = [
599
  "🧠🎭 Semantic Symphonies & Episodic Encores",
600
  "🌌🎼 AI Rhythms of Memory Lane",
 
16
  import streamlit.components.v1 as components
17
 
18
  # If you do model inference via huggingface_hub:
19
+ # from huggingface_hub import InferenceClient
20
 
21
+ ########################################################################################
22
+ # 1) GLOBAL CONFIG & PLACEHOLDERS
23
+ ########################################################################################
24
  BASE_URL = "https://huggingface.co/spaces/awacke1/MermaidMarkdownDiagramEditor"
25
 
 
26
  PromptPrefix = "AI-Search: "
27
  PromptPrefix2 = "AI-Refine: "
28
  PromptPrefix3 = "AI-JS: "
29
 
 
30
  roleplaying_glossary = {
31
  "Core Rulebooks": {
32
  "Dungeons and Dragons": ["Player's Handbook", "Dungeon Master's Guide", "Monster Manual"],
 
37
  }
38
  }
39
 
 
40
  transhuman_glossary = {
41
  "Neural Interfaces": ["Cortex Jack", "Mind-Machine Fusion"],
42
  "Cybernetics": ["Robotic Limbs", "Augmented Eyes"],
43
  }
44
 
 
45
  def process_text(text):
46
+ """🕵️ process_text: detective style—prints lines to Streamlit for debugging."""
47
  st.write(f"process_text called with: {text}")
48
 
49
  def search_arxiv(text):
50
+ """🔭 search_arxiv: pretend to search ArXiv, just prints debug."""
51
  st.write(f"search_arxiv called with: {text}")
52
 
53
  def SpeechSynthesis(text):
54
+ """🗣 Simple logging for text-to-speech placeholders."""
55
  st.write(f"SpeechSynthesis called with: {text}")
56
 
57
  def process_image(image_file, prompt):
58
+ """📷 Simple placeholder for image AI pipeline."""
59
+ return f"[process_image placeholder] {image_file} => {prompt}"
60
 
61
  def process_video(video_file, seconds_per_frame):
62
+ """🎞 Simple placeholder for video AI pipeline."""
63
+ st.write(f"[process_video placeholder] {video_file}, {seconds_per_frame} sec/frame")
64
 
 
65
  API_URL = "https://huggingface-inference-endpoint-placeholder"
66
  API_KEY = "hf_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
67
 
68
  @st.cache_resource
69
  def InferenceLLM(prompt):
70
+ """🔮 Stub returning mock response for 'prompt'."""
71
  return f"[InferenceLLM placeholder response to prompt: {prompt}]"
72
 
73
+ ########################################################################################
74
+ # 2) GLOSSARY & FILE UTILITY
75
+ ########################################################################################
76
+
77
  @st.cache_resource
78
  def display_glossary_entity(k):
79
  """
80
  Creates multiple link emojis for a single entity.
81
+ Each link might point to /?q=..., /?q=<prefix>..., or external sites.
82
  """
83
  search_urls = {
84
+ "🚀🌌ArXiv": lambda x: f"/?q={quote(x)}",
85
+ "🃏Analyst": lambda x: f"/?q={quote(x)}-{quote(PromptPrefix)}",
86
+ "📚PyCoder": lambda x: f"/?q={quote(x)}-{quote(PromptPrefix2)}",
87
+ "🔬JSCoder": lambda x: f"/?q={quote(x)}-{quote(PromptPrefix3)}",
88
+ "📖": lambda x: f"https://en.wikipedia.org/wiki/{quote(x)}",
89
+ "🔍": lambda x: f"https://www.google.com/search?q={quote(x)}",
90
+ "🔎": lambda x: f"https://www.bing.com/search?q={quote(x)}",
91
+ "🎥": lambda x: f"https://www.youtube.com/results?search_query={quote(x)}",
92
+ "🐦": lambda x: f"https://twitter.com/search?q={quote(x)}",
93
  }
94
  links_md = ' '.join([f"[{emoji}]({url(k)})" for emoji, url in search_urls.items()])
95
  st.markdown(f"**{k}** <small>{links_md}</small>", unsafe_allow_html=True)
96
 
97
+
98
  def display_content_or_image(query):
99
  """
100
+ If 'query' is in transhuman_glossary or there's an image matching 'images/<query>.png',
101
+ show it. Otherwise warn.
102
  """
103
  for category, term_list in transhuman_glossary.items():
104
  for term in term_list:
 
114
  return False
115
 
116
  def clear_query_params():
117
+ """Warn about clearing. Full clearing requires a redirect or st.experimental_set_query_params()."""
 
 
 
118
  st.warning("Define a redirect or link without query params if you want to truly clear them.")
119
 
120
+ ########################################################################################
121
+ # 3) FILE-HANDLING (MD files, etc.)
122
+ ########################################################################################
123
+
124
  def load_file(file_path):
125
+ """Load file contents as UTF-8 text, or return empty on error."""
126
  try:
127
  with open(file_path, "r", encoding='utf-8') as f:
128
  return f.read()
 
131
 
132
  @st.cache_resource
133
  def create_zip_of_files(files):
134
+ """Combine multiple local .md files into a single .zip for user to download."""
135
  zip_name = "Arxiv-Paper-Search-QA-RAG-Streamlit-Gradio-AP.zip"
136
  with zipfile.ZipFile(zip_name, 'w') as zipf:
137
  for file in files:
 
140
 
141
  @st.cache_resource
142
  def get_zip_download_link(zip_file):
143
+ """Return an <a> link to download the given zip_file (base64-encoded)."""
144
  with open(zip_file, 'rb') as f:
145
  data = f.read()
146
  b64 = base64.b64encode(data).decode()
 
149
  def get_table_download_link(file_path):
150
  """
151
  Creates a download link for a single file from your snippet.
152
+ Encodes it as base64 data.
153
  """
154
  try:
155
  with open(file_path, 'r', encoding='utf-8') as file:
 
158
  file_name = os.path.basename(file_path)
159
  ext = os.path.splitext(file_name)[1]
160
  mime_map = {
161
+ '.txt': 'text/plain',
162
+ '.py': 'text/plain',
163
  '.xlsx': 'text/plain',
164
+ '.csv': 'text/plain',
165
+ '.htm': 'text/html',
166
+ '.md': 'text/markdown',
167
+ '.wav': 'audio/wav'
168
  }
169
  mime_type = mime_map.get(ext, 'application/octet-stream')
170
  return f'<a href="data:{mime_type};base64,{b64}" target="_blank" download="{file_name}">{file_name}</a>'
 
172
  return ''
173
 
174
  def get_file_size(file_path):
175
+ """Get file size in bytes."""
176
  return os.path.getsize(file_path)
177
 
178
  def FileSidebar():
 
180
  Renders .md files, providing open/view/delete/run logic in the sidebar.
181
  """
182
  all_files = glob.glob("*.md")
183
+ # Exclude short-named or special files if needed:
184
  all_files = [f for f in all_files if len(os.path.splitext(f)[0]) >= 5]
185
  all_files.sort(key=lambda x: (os.path.splitext(x)[1], x), reverse=True)
186
 
 
200
  next_action = ''
201
 
202
  for file in all_files:
203
+ col1, col2, col3, col4, col5 = st.sidebar.columns([1,6,1,1,1])
204
  with col1:
205
+ if st.button("🌐", key="md_"+file):
206
  file_contents = load_file(file)
207
  file_name = file
208
  next_action = 'md'
 
210
  with col2:
211
  st.markdown(get_table_download_link(file), unsafe_allow_html=True)
212
  with col3:
213
+ if st.button("📂", key="open_"+file):
214
  file_contents = load_file(file)
215
  file_name = file
216
  next_action = 'open'
 
219
  st.session_state['filetext'] = file_contents
220
  st.session_state['next_action'] = next_action
221
  with col4:
222
+ if st.button("▶️", key="read_"+file):
223
  file_contents = load_file(file)
224
  file_name = file
225
  next_action = 'search'
226
  st.session_state['next_action'] = next_action
227
  with col5:
228
+ if st.button("🗑", key="delete_"+file):
229
  os.remove(file)
230
  st.rerun()
231
 
 
232
  if file_contents:
233
  if next_action == 'open':
234
+ open1, open2 = st.columns([0.8,0.2])
235
  with open1:
236
  file_name_input = st.text_input('File Name:', file_name, key='file_name_input')
237
  file_content_area = st.text_area('File Contents:', file_contents, height=300, key='file_content_area')
 
238
  if st.button('💾 Save File'):
239
  with open(file_name_input, 'w', encoding='utf-8') as f:
240
  f.write(file_content_area)
241
  st.markdown(f'Saved {file_name_input} successfully.')
 
242
  elif next_action == 'search':
243
  file_content_area = st.text_area("File Contents:", file_contents, height=500)
244
  user_prompt = PromptPrefix2 + file_contents
245
  st.markdown(user_prompt)
246
  if st.button('🔍Re-Code'):
247
  search_arxiv(file_contents)
 
248
  elif next_action == 'md':
249
  st.markdown(file_contents)
250
  SpeechSynthesis(file_contents)
251
  if st.button("🔍Run"):
252
  st.write("Running GPT logic placeholder...")
253
 
254
+ ########################################################################################
255
+ # 4) SCORING / GLOSSARIES
256
+ ########################################################################################
257
+
258
  score_dir = "scores"
259
  os.makedirs(score_dir, exist_ok=True)
260
 
 
298
  "Changeling": "🍃",
299
  }
300
  topic_emojis = {
301
+ "Core Rulebooks": "📚",
302
+ "Maps & Settings": "🗺️",
303
+ "Game Mechanics & Tools": "⚙️",
304
+ "Monsters & Adversaries": "👹",
305
+ "Campaigns & Adventures": "📜",
306
+ "Creatives & Assets": "🎨",
307
+ "Game Master Resources": "🛠️",
308
+ "Lore & Background": "📖",
309
+ "Character Development": "🧍",
310
+ "Homebrew Content": "🔧",
311
+ "General Topics": "🌍",
312
  }
313
 
314
  for category, games in roleplaying_glossary.items():
 
323
  newscore = update_score(key.replace('?', ''))
324
  st.markdown(f"Scored **{category} - {game} - {term}** -> {newscore}")
325
 
326
+ ########################################################################################
327
+ # 5) IMAGES & VIDEOS
328
+ ########################################################################################
329
+
330
  def display_images_and_wikipedia_summaries(num_columns=4):
331
+ """Display .png images in a grid, referencing the name as a 'keyword'."""
332
  image_files = [f for f in os.listdir('.') if f.endswith('.png')]
333
  if not image_files:
334
  st.write("No PNG images found in the current directory.")
 
354
  col_index += 1
355
 
356
  def display_videos_and_links(num_columns=4):
357
+ """Displays all .mp4/.webm in a grid, plus text input for prompts."""
358
  video_files = [f for f in os.listdir('.') if f.endswith(('.mp4', '.webm'))]
359
  if not video_files:
360
  st.write("No MP4 or WEBM videos found in the current directory.")
 
378
  st.error("Invalid input for seconds per frame!")
379
  col_index += 1
380
 
381
+ ########################################################################################
382
+ # 6) MERMAID
383
+ ########################################################################################
384
+
385
  def generate_mermaid_html(mermaid_code: str) -> str:
386
  """
387
  Returns HTML that centers the Mermaid diagram, loading from a CDN.
 
430
  return url
431
  return f"{BASE_URL}{url}"
432
 
433
+ DEFAULT_MERMAID = r"""
434
  flowchart LR
435
+ U((User 😎)) -- "Talk 🗣️" --> LLM[LLM Agent 🤖\nExtract Info]
436
  click U "/?q=User%20😎" _self
437
  click LLM "/?q=LLM%20Agent%20Extract%20Info" _blank
438
 
439
+ LLM -- "Query 🔍" --> HS[Hybrid Search 🔎\nVector+NER+Lexical]
440
  click HS "/?q=Hybrid%20Search%20Vector+NER+Lexical" _blank
441
 
442
+ HS -- "Reason 🤔" --> RE[Reasoning Engine 🛠️\nNeuralNetwork+Medical]
443
  click RE "/?q=Reasoning%20Engine%20NeuralNetwork+Medical" _blank
444
 
445
+ RE -- "Link 📡" --> KG((Knowledge Graph 📚\nOntology+GAR+RAG))
446
  click KG "/?q=Knowledge%20Graph%20Ontology+GAR+RAG" _blank
447
  """
448
 
449
+ ########################################################################################
450
+ # 7) MAIN UI
451
+ ########################################################################################
452
+
453
  def main():
454
  st.set_page_config(page_title="Mermaid + Clickable Links with Base URL", layout="wide")
455
 
456
+ # 1) Query Param Parsing
 
 
457
  query_params = st.query_params
458
+ q_list = (query_params.get('q') or query_params.get('query') or [''])
459
+ if q_list:
460
+ q_val = q_list[0].strip()
461
+ if q_val:
462
+ # If there's a q= or query= param, do some processing
463
+ search_payload = PromptPrefix + q_val
464
+ st.markdown(search_payload)
465
+ process_text(search_payload)
466
+
467
+ # If 'action' param is present
468
+ if 'action' in query_params:
469
+ action_list = query_params['action']
470
  if action_list:
471
  action = action_list[0]
472
  if action == 'show_message':
 
474
  elif action == 'clear':
475
  clear_query_params()
476
 
477
+ # If a 'query=' param is present, show content or image
478
+ if 'query' in query_params:
479
+ paramQ = query_params['query'][0]
480
+ display_content_or_image(paramQ)
481
 
482
+ # 2) Let user pick if we want ?model=1
 
 
483
  st.sidebar.write("## Diagram Link Settings")
484
  model_selected = st.sidebar.checkbox("Append ?model=1 to each link?")
485
 
486
+ # 3) We'll do minimal injection for the "click" lines
487
+ lines = DEFAULT_MERMAID.strip().split("\n")
 
 
 
488
  new_lines = []
489
  for line in lines:
490
+ if line.strip().startswith("click ") and '"/?' in line:
491
+ # e.g. click U "/?q=User%20😎" _self
492
+ pattern = r'(click\s+\S+\s+)"([^"]+)"\s+(\S+)'
493
+ match = re.match(pattern, line.strip())
494
+ if match:
495
+ prefix_part = match.group(1) # e.g. "click U "
496
+ old_url = match.group(2) # e.g. /?q=User%20😎
497
+ target = match.group(3) # e.g. _self or _blank
 
498
 
499
  new_url = inject_base_url(old_url)
500
  new_url = append_model_param(new_url, model_selected)
501
 
502
+ new_line = f'{prefix_part}"{new_url}" {target}'
503
  new_lines.append(new_line)
504
  else:
505
+ # If not matched, keep line as is
506
  new_lines.append(line)
507
  else:
508
  new_lines.append(line)
509
 
510
+ final_mermaid = "\n".join(new_lines)
511
 
512
+ # 4) Render the top-centered Mermaid diagram
513
+ st.sidebar.markdown("**Mermaid Diagram** with Base URL Injection")
514
+ diagram_html = generate_mermaid_html(final_mermaid)
 
 
515
  components.html(diagram_html, height=400, scrolling=True)
516
 
517
+ # 5) Two-column layout: Markdown & Mermaid Editors
 
 
518
  left_col, right_col = st.columns(2)
519
 
 
520
  with left_col:
521
  st.subheader("Markdown Side 📝")
522
  if "markdown_text" not in st.session_state:
523
+ st.session_state["markdown_text"] = "## Hello!\nYou can type some *Markdown* here.\n"
524
+
525
  markdown_text = st.text_area(
526
  "Edit Markdown:",
527
  value=st.session_state["markdown_text"],
 
529
  )
530
  st.session_state["markdown_text"] = markdown_text
531
 
532
+ # Row of buttons
533
  colA, colB = st.columns(2)
534
  with colA:
535
  if st.button("🔄 Refresh Markdown"):
 
543
  st.markdown("**Preview:**")
544
  st.markdown(markdown_text)
545
 
 
546
  with right_col:
547
  st.subheader("Mermaid Side 🧜‍♂️")
 
548
  if "current_mermaid" not in st.session_state:
549
+ st.session_state["current_mermaid"] = final_mermaid
550
 
551
  mermaid_input = st.text_area(
552
  "Edit Mermaid Code:",
 
569
  st.markdown("**Mermaid Source:**")
570
  st.code(mermaid_input, language="python", line_numbers=True)
571
 
572
+ # 6) Media Galleries
 
 
573
  st.markdown("---")
574
  st.header("Media Galleries")
575
 
 
579
  num_columns_video = st.slider("Choose Number of Video Columns", 1, 15, 5, key="num_columns_video")
580
  display_videos_and_links(num_columns_video)
581
 
582
+ # 7) Optional Extended text interface
583
  showExtendedTextInterface = False
584
  if showExtendedTextInterface:
585
+ # e.g. display_glossary_grid(roleplaying_glossary)
 
586
  # num_columns_text = st.slider("Choose Number of Text Columns", 1, 15, 4)
587
  # display_buttons_with_scores(num_columns_text)
588
  pass
589
 
590
+ # 8) File Sidebar
 
 
591
  FileSidebar()
592
 
593
+ # 9) Random Title
 
 
594
  titles = [
595
  "🧠🎭 Semantic Symphonies & Episodic Encores",
596
  "🌌🎼 AI Rhythms of Memory Lane",