awacke1 commited on
Commit
f4742a7
·
verified ·
1 Parent(s): 73e1438

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -458
app.py CHANGED
@@ -4,45 +4,50 @@ import glob
4
  import re
5
  import base64
6
  import pytz
7
- import time
8
- import streamlit.components.v1 as components
9
-
10
- from urllib.parse import quote
11
- from gradio_client import Client
12
  from datetime import datetime
13
-
14
- # Page configuration
15
- Site_Name = 'AI Knowledge Tree Builder 📈🌿 Grow Smarter with Every Click'
16
- title = "🌳✨AI Knowledge Tree Builder🛠️🤓"
17
- helpURL = 'https://huggingface.co/spaces/awacke1/AIKnowledgeTreeBuilder/'
18
- bugURL = 'https://huggingface.co/spaces/awacke1/AIKnowledgeTreeBuilder/'
19
- icons = '🌳✨🛠️🤓'
20
-
21
- SidebarOutline = """🌳🤖 Designed with the following tenets:
22
- 1 📱 **Portability** - Universal access via any device & link sharing
23
- 2. **Speed of Build** - Rapid deployments < 2min to production
24
- 3. 🔗 **Linkiness** - Programmatic access to AI knowledge sources
25
- 4. 🎯 **Abstractive** - Core stays lean isolating high-maintenance components
26
- 5. 🧠 **Memory** - Shareable flows deep-linked research paths
27
- 6. 👤 **Personalized** - Rapidly adapts knowledge base to user needs
28
- 7. 🐦 **Living Brevity** - Easily cloneable, self modify data public share results.
29
- """
30
-
31
- st.set_page_config(
32
- page_title=title,
33
- page_icon=icons,
34
- layout="wide",
35
- initial_sidebar_state="auto",
36
- menu_items={
37
- 'Get Help': helpURL,
38
- 'Report a bug': bugURL,
39
- 'About': title
40
- }
41
- )
42
-
43
- st.sidebar.markdown(SidebarOutline)
44
-
45
- # Initialize session state variables
 
 
 
 
 
 
 
 
 
 
46
  if 'selected_file' not in st.session_state:
47
  st.session_state.selected_file = None
48
  if 'view_mode' not in st.session_state:
@@ -50,440 +55,58 @@ if 'view_mode' not in st.session_state:
50
  if 'files' not in st.session_state:
51
  st.session_state.files = []
52
 
53
- # --- MoE System Prompts Setup ---
54
- moe_prompts_data = """1. Create a python streamlit app.py demonstrating the topic and show top 3 arxiv papers discussing this as reference.
55
- 2. Create a python gradio app.py demonstrating the topic and show top 3 arxiv papers discussing this as reference.
56
- 3. Create a mermaid model of the knowledge tree around concepts and parts of this topic. Use appropriate emojis.
57
- 4. Create a top three list of tools and techniques for this topic with markdown and emojis.
58
- 5. Create a specification in markdown outline with emojis for this topic.
59
- 6. Create an image generation prompt for this with Bosch and Turner oil painting influences.
60
- 7. Generate an image which describes this as a concept and area of study.
61
- 8. List top ten glossary terms with emojis related to this topic as markdown outline."""
62
- # Split the data by lines and remove the numbering/period (assume each line has "number. " at the start)
63
- moe_prompts_list = [line.split('. ', 1)[1].strip() for line in moe_prompts_data.splitlines() if '. ' in line]
64
- moe_options = [""] + moe_prompts_list # blank is default
65
-
66
- # Place the selectbox at the top of the app; store selection in session_state key "selected_moe"
67
- selected_moe = st.selectbox("Choose a MoE system prompt", options=moe_options, index=0, key="selected_moe")
68
-
69
- # --- Utility Functions ---
70
-
71
- def get_display_name(filename):
72
- """Extract text from parentheses or return filename as is."""
73
- match = re.search(r'\((.*?)\)', filename)
74
- if match:
75
- return match.group(1)
76
- return filename
77
-
78
- def get_time_display(filename):
79
- """Extract just the time portion from the filename."""
80
- time_match = re.match(r'(\d{2}\d{2}[AP]M)', filename)
81
- if time_match:
82
- return time_match.group(1)
83
- return filename
84
 
 
85
  def sanitize_filename(text):
86
- """Create a safe filename from text while preserving spaces."""
87
- safe_text = re.sub(r'[^\w\s-]', ' ', text)
88
- safe_text = re.sub(r'\s+', ' ', safe_text)
89
- safe_text = safe_text.strip()
90
- return safe_text[:50]
91
 
92
  def generate_timestamp_filename(query):
93
- """Generate filename with format: 1103AM 11032024 (Query).md"""
94
  central = pytz.timezone('US/Central')
95
- current_time = datetime.now(central)
96
- time_str = current_time.strftime("%I%M%p")
97
- date_str = current_time.strftime("%m%d%Y")
98
- safe_query = sanitize_filename(query)
99
- filename = f"{time_str} {date_str} ({safe_query}).md"
100
- return filename
101
 
102
- def delete_file(file_path):
103
- """Delete a file and return success status."""
104
- try:
105
- os.remove(file_path)
106
- return True
107
- except Exception as e:
108
- st.error(f"Error deleting file: {e}")
109
- return False
110
-
111
- def save_ai_interaction(query, ai_result, is_rerun=False):
112
- """Save AI interaction to a markdown file with new filename format."""
113
  filename = generate_timestamp_filename(query)
114
- if is_rerun:
115
- content = f"""# Rerun Query
116
- Original file content used for rerun:
117
-
118
- {query}
119
-
120
- # AI Response (Fun Version)
121
- {ai_result}
122
- """
123
- else:
124
- content = f"""# Query: {query}
125
-
126
- ## AI Response
127
- {ai_result}
128
- """
129
- try:
130
- with open(filename, 'w', encoding='utf-8') as f:
131
- f.write(content)
132
- return filename
133
- except Exception as e:
134
- st.error(f"Error saving file: {e}")
135
- return None
136
-
137
- def get_file_download_link(file_path):
138
- """Generate a base64 download link for a file."""
139
- try:
140
- with open(file_path, 'r', encoding='utf-8') as f:
141
- content = f.read()
142
- b64 = base64.b64encode(content.encode()).decode()
143
- filename = os.path.basename(file_path)
144
- return f'<a href="data:text/markdown;base64,{b64}" download="{filename}">{get_display_name(filename)}</a>'
145
- except Exception as e:
146
- st.error(f"Error creating download link: {e}")
147
- return None
148
-
149
- # --- New Functions for Markdown File Parsing and Link Tree ---
150
-
151
- def clean_item_text(line):
152
- """
153
- Remove emoji and numbered prefix from a line.
154
- E.g., "🔧 1. Low-level system integrations compilers Cplusplus" becomes
155
- "Low-level system integrations compilers Cplusplus".
156
- Also remove any bold markdown markers.
157
- """
158
- # Remove leading emoji and number+period
159
- cleaned = re.sub(r'^[^\w]*(\d+\.\s*)', '', line)
160
- # Remove any remaining emoji (simple unicode range) and ** markers
161
- cleaned = re.sub(r'[\U0001F300-\U0001FAFF]', '', cleaned)
162
- cleaned = cleaned.replace("**", "")
163
- return cleaned.strip()
164
-
165
- def clean_header_text(header_line):
166
- """
167
- Extract header text from a markdown header line.
168
- E.g., "🔧 **Systems, Infrastructure & Low-Level Engineering**" becomes
169
- "Systems, Infrastructure & Low-Level Engineering".
170
- """
171
- match = re.search(r'\*\*(.*?)\*\*', header_line)
172
- if match:
173
- return match.group(1).strip()
174
- return header_line.strip()
175
-
176
- def parse_markdown_sections(md_text):
177
- """
178
- Parse markdown text into sections.
179
- Each section starts with a header line containing bold text.
180
- Returns a list of dicts with keys: 'header' and 'items' (list of lines).
181
- Skips any content before the first header.
182
- """
183
- sections = []
184
- current_section = None
185
- lines = md_text.splitlines()
186
- for line in lines:
187
- if line.strip() == "":
188
- continue
189
- # Check if line is a header (contains bold markdown and an emoji)
190
- if '**' in line:
191
- header = clean_header_text(line)
192
- current_section = {'header': header, 'raw': line, 'items': []}
193
- sections.append(current_section)
194
- elif current_section is not None:
195
- # Only add lines that appear to be list items (start with an emoji and number)
196
- if re.match(r'^[^\w]*\d+\.\s+', line):
197
- current_section['items'].append(line)
198
- else:
199
- if current_section['items']:
200
- current_section['items'][-1] += " " + line.strip()
201
- else:
202
- current_section['items'].append(line)
203
- return sections
204
-
205
- def display_section_items(items):
206
- """
207
- Display list of items as links.
208
- For each item, clean the text and generate search links using your original link set.
209
- If a MoE system prompt is selected (non-blank), prepend it—with three spaces—before the cleaned text.
210
- """
211
- # Retrieve the current selected MoE prompt (if any)
212
- moe_prefix = st.session_state.get("selected_moe", "")
213
- search_urls = {
214
- "📚📖ArXiv": lambda k: f"/?q={quote(k)}",
215
- "🔮<sup>Google</sup>": lambda k: f"https://www.google.com/search?q={quote(k)}",
216
- "📺<sup>Youtube</sup>": lambda k: f"https://www.youtube.com/results?search_query={quote(k)}",
217
- "🔭<sup>Bing</sup>": lambda k: f"https://www.bing.com/search?q={quote(k)}",
218
- "💡<sup>Claude</sup>": lambda k: f"https://claude.ai/new?q={quote(k)}",
219
- "📱X": lambda k: f"https://twitter.com/search?q={quote(k)}",
220
- "🤖<sup>GPT</sup>": lambda k: f"https://chatgpt.com/?model=o3-mini-high&q={quote(k)}",
221
- }
222
- for item in items:
223
- cleaned_text = clean_item_text(item)
224
- # If a MoE prompt is selected (non-blank), prepend it (with three spaces) to the cleaned text.
225
- final_query = (moe_prefix + " " if moe_prefix else "") + cleaned_text
226
- links_md = ' '.join([f"[{emoji}]({url(final_query)})" for emoji, url in search_urls.items()])
227
- st.markdown(f"- **{cleaned_text}** {links_md}", unsafe_allow_html=True)
228
-
229
- def display_markdown_tree():
230
- """
231
- Allow user to upload a .md file or load README.md.
232
- Parse the markdown into sections and display each section in a collapsed expander
233
- with the original markdown and a link tree of items.
234
- """
235
- st.markdown("## Markdown Tree Parser")
236
- uploaded_file = st.file_uploader("Upload a Markdown file", type=["md"])
237
- if uploaded_file is not None:
238
- md_content = uploaded_file.read().decode("utf-8")
239
- else:
240
- if os.path.exists("README.md"):
241
- with open("README.md", "r", encoding="utf-8") as f:
242
- md_content = f.read()
243
- else:
244
- st.info("No Markdown file uploaded and README.md not found.")
245
- return
246
-
247
- sections = parse_markdown_sections(md_content)
248
- if not sections:
249
- st.info("No sections found in the markdown file.")
250
- return
251
-
252
- for sec in sections:
253
- with st.expander(sec['header'], expanded=False):
254
- st.markdown(f"**Original Markdown:**\n\n{sec['raw']}\n")
255
- if sec['items']:
256
- st.markdown("**Link Tree:**")
257
- display_section_items(sec['items'])
258
- else:
259
- st.write("No items found in this section.")
260
-
261
- # --- Existing AI and File Management Functions ---
262
-
263
- def search_arxiv(query):
264
- st.write("Performing AI Lookup...")
265
- client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
266
- result1 = client.predict(
267
- prompt=query,
268
- llm_model_picked="mistralai/Mixtral-8x7B-Instruct-v0.1",
269
- stream_outputs=True,
270
- api_name="/ask_llm"
271
- )
272
- st.markdown("### Mixtral-8x7B-Instruct-v0.1 Result")
273
- st.markdown(result1)
274
- result2 = client.predict(
275
- prompt=query,
276
- llm_model_picked="mistralai/Mistral-7B-Instruct-v0.2",
277
- stream_outputs=True,
278
- api_name="/ask_llm"
279
- )
280
- st.markdown("### Mistral-7B-Instruct-v0.2 Result")
281
- st.markdown(result2)
282
- combined_result = f"{result1}\n\n{result2}"
283
- return combined_result
284
-
285
- @st.cache_resource
286
- def SpeechSynthesis(result):
287
- documentHTML5 = '''
288
- <!DOCTYPE html>
289
- <html>
290
- <head>
291
- <title>Read It Aloud</title>
292
- <script type="text/javascript">
293
- function readAloud() {
294
- const text = document.getElementById("textArea").value;
295
- const speech = new SpeechSynthesisUtterance(text);
296
- window.speechSynthesis.speak(speech);
297
- }
298
- </script>
299
- </head>
300
- <body>
301
- <h1>🔊 Read It Aloud</h1>
302
- <textarea id="textArea" rows="10" cols="80">
303
- '''
304
- documentHTML5 += result
305
- documentHTML5 += '''
306
- </textarea>
307
- <br>
308
- <button onclick="readAloud()">🔊 Read Aloud</button>
309
- </body>
310
- </html>
311
- '''
312
- components.html(documentHTML5, width=1280, height=300)
313
-
314
- def display_file_content(file_path):
315
- """Display file content with editing capabilities."""
316
- try:
317
- with open(file_path, 'r', encoding='utf-8') as f:
318
- content = f.read()
319
- if st.session_state.view_mode == 'view':
320
- st.markdown(content)
321
- else:
322
- edited_content = st.text_area(
323
- "Edit content",
324
- content,
325
- height=400,
326
- key=f"edit_{os.path.basename(file_path)}"
327
- )
328
- if st.button("Save Changes", key=f"save_{os.path.basename(file_path)}"):
329
- try:
330
- with open(file_path, 'w', encoding='utf-8') as f:
331
- f.write(edited_content)
332
- st.success(f"Successfully saved changes to {file_path}")
333
- except Exception as e:
334
- st.error(f"Error saving changes: {e}")
335
- except Exception as e:
336
- st.error(f"Error reading file: {e}")
337
-
338
- def file_management_sidebar():
339
- """Redesigned sidebar with improved layout and additional functionality."""
340
- st.sidebar.title("📁 File Management")
341
- md_files = [file for file in glob.glob("*.md") if file.lower() != 'readme.md']
342
- md_files.sort()
343
- st.session_state.files = md_files
344
- if md_files:
345
- st.sidebar.markdown("### Saved Files")
346
- for idx, file in enumerate(md_files):
347
- st.sidebar.markdown("---")
348
- st.sidebar.text(get_time_display(file))
349
- download_link = get_file_download_link(file)
350
- if download_link:
351
- st.sidebar.markdown(download_link, unsafe_allow_html=True)
352
- col1, col2, col3, col4 = st.sidebar.columns(4)
353
- with col1:
354
- if st.button("📄View", key=f"view_{idx}"):
355
- st.session_state.selected_file = file
356
- st.session_state.view_mode = 'view'
357
- with col2:
358
- if st.button("✏️Edit", key=f"edit_{idx}"):
359
- st.session_state.selected_file = file
360
- st.session_state.view_mode = 'edit'
361
- with col3:
362
- if st.button("🔄Run", key=f"rerun_{idx}"):
363
- try:
364
- with open(file, 'r', encoding='utf-8') as f:
365
- content = f.read()
366
- rerun_prefix = """For the markdown below reduce the text to a humorous fun outline with emojis and markdown outline levels in outline that convey all the facts and adds wise quotes and funny statements to engage the reader:
367
-
368
- """
369
- full_prompt = rerun_prefix + content
370
- ai_result = perform_ai_lookup(full_prompt)
371
- saved_file = save_ai_interaction(content, ai_result, is_rerun=True)
372
- if saved_file:
373
- st.success(f"Created fun version in {saved_file}")
374
- st.session_state.selected_file = saved_file
375
- st.session_state.view_mode = 'view'
376
- except Exception as e:
377
- st.error(f"Error during rerun: {e}")
378
- with col4:
379
- if st.button("🗑️Delete", key=f"delete_{idx}"):
380
- if delete_file(file):
381
- st.success(f"Deleted {file}")
382
- st.rerun()
383
- else:
384
- st.error(f"Failed to delete {file}")
385
- st.sidebar.markdown("---")
386
- if st.sidebar.button("📝 Create New Note"):
387
- filename = generate_timestamp_filename("New Note")
388
- with open(filename, 'w', encoding='utf-8') as f:
389
- f.write("# New Markdown File\n")
390
- st.sidebar.success(f"Created: {filename}")
391
- st.session_state.selected_file = filename
392
- st.session_state.view_mode = 'edit'
393
- else:
394
- st.sidebar.write("No markdown files found.")
395
- if st.sidebar.button("📝 Create First Note"):
396
- filename = generate_timestamp_filename("New Note")
397
- with open(filename, 'w', encoding='utf-8') as f:
398
- f.write("# New Markdown File\n")
399
- st.sidebar.success(f"Created: {filename}")
400
- st.session_state.selected_file = filename
401
- st.session_state.view_mode = 'edit'
402
-
403
- def perform_ai_lookup(query):
404
- start_time = time.strftime("%Y-%m-%d %H:%M:%S")
405
- client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
406
- response1 = client.predict(
407
- query,
408
- 20,
409
- "Semantic Search",
410
- "mistralai/Mixtral-8x7B-Instruct-v0.1",
411
- api_name="/update_with_rag_md"
412
- )
413
- Question = '### 🔎 ' + query + '\r\n'
414
- References = response1[0]
415
- ReferenceLinks = ""
416
- results = ""
417
- RunSecondQuery = True
418
- if RunSecondQuery:
419
- response2 = client.predict(
420
- query,
421
- "mistralai/Mixtral-8x7B-Instruct-v0.1",
422
- True,
423
- api_name="/ask_llm"
424
- )
425
- if len(response2) > 10:
426
- Answer = response2
427
- SpeechSynthesis(Answer)
428
- results = Question + '\r\n' + Answer + '\r\n' + References + '\r\n' + ReferenceLinks
429
- st.markdown(results)
430
- st.write('🔍Run of Multi-Agent System Paper Summary Spec is Complete')
431
- end_time = time.strftime("%Y-%m-%d %H:%M:%S")
432
- start_timestamp = time.mktime(time.strptime(start_time, "%Y-%m-%d %H:%M:%S"))
433
- end_timestamp = time.mktime(time.strptime(end_time, "%Y-%m-%d %H:%M:%S"))
434
- elapsed_seconds = end_timestamp - start_timestamp
435
- st.write(f"Start time: {start_time}")
436
- st.write(f"Finish time: {end_time}")
437
- st.write(f"Elapsed time: {elapsed_seconds:.2f} seconds")
438
- filename = generate_filename(query, "md")
439
- create_file(filename, query, results)
440
- return results
441
-
442
- def generate_filename(prompt, file_type):
443
- central = pytz.timezone('US/Central')
444
- safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
445
- safe_prompt = re.sub(r'\W+', '_', prompt)[:90]
446
- return f"{safe_date_time}_{safe_prompt}.{file_type}"
447
-
448
- def create_file(filename, prompt, response):
449
- with open(filename, 'w', encoding='utf-8') as file:
450
- file.write(prompt + "\n\n" + response)
451
 
452
- # --- Main Application ---
 
 
 
 
453
 
 
454
  def main():
455
- st.markdown("### AI Knowledge Tree Builder 🧠🌱 Cultivate Your AI Mindscape!")
456
- query_params = st.query_params
457
- query = query_params.get('q', '')
458
- show_initial_content = True
459
 
460
  if query:
461
- show_initial_content = False
462
- st.write(f"### Search query received: {query}")
463
  try:
464
- ai_result = perform_ai_lookup(query)
465
- saved_file = save_ai_interaction(query, ai_result)
466
- if saved_file:
467
- st.success(f"Saved interaction to {saved_file}")
468
- st.session_state.selected_file = saved_file
469
- st.session_state.view_mode = 'view'
470
  except Exception as e:
471
- st.error(f"Error during AI lookup: {e}")
472
-
473
- file_management_sidebar()
474
-
 
 
 
 
 
475
  if st.session_state.selected_file:
476
- show_initial_content = False
477
- if os.path.exists(st.session_state.selected_file):
478
- st.markdown(f"### Current File: {st.session_state.selected_file}")
479
- display_file_content(st.session_state.selected_file)
480
- else:
481
- st.error("Selected file no longer exists.")
482
- st.session_state.selected_file = None
483
- st.rerun()
484
-
485
- if show_initial_content:
486
- display_markdown_tree()
487
 
488
  if __name__ == "__main__":
489
- main()
 
4
  import re
5
  import base64
6
  import pytz
 
 
 
 
 
7
  from datetime import datetime
8
+ from transformers.agents import CodeAgent, ReactCodeAgent, ReactJsonAgent, load_tool
9
+
10
+ # Page config
11
+ st.set_page_config(page_title="🌳✨ AI Knowledge Tree Builder 🛠️🤓", page_icon="🌳", layout="wide")
12
+ st.sidebar.markdown("""
13
+ 🌳🤖 **AI Knowledge Tree Builder**
14
+ 1. 📱 Universal access
15
+ 2. ⚡ Rapid builds (<2min)
16
+ 3. 🔗 Linked AI sources
17
+ 4. 🎯 Lean core
18
+ 5. 🧠 Shareable memory
19
+ 6. 👤 Personalized
20
+ 7. 🐦 Cloneable brevity
21
+ """)
22
+
23
+ # Initialize Agents
24
+ tools = [load_tool("text-to-speech"), load_tool("image_question_answering")]
25
+ agents = {
26
+ "CodeCrafter": CodeAgent(tools=tools, system_prompt="Craft code like a pro! 🖥️"),
27
+ "StepSage": ReactCodeAgent(tools=tools, system_prompt="Step-by-step wisdom! 🧠"),
28
+ "JsonJugger": ReactJsonAgent(tools=tools, system_prompt="JSON-powered antics! 🤡"),
29
+ "OutlineOracle": ReactCodeAgent(tools=tools, system_prompt="Outline everything! 📋"),
30
+ "ToolTitan": CodeAgent(tools=tools, system_prompt="List tools with swagger! 🔧"),
31
+ "SpecSpinner": ReactJsonAgent(tools=tools, system_prompt="Spin specs with style! 📜"),
32
+ "ImageImp": CodeAgent(tools=tools, system_prompt="Dream up image prompts! 🎨"),
33
+ "VisualVortex": ReactCodeAgent(tools=tools, system_prompt="Generate visuals! 🖼️"),
34
+ "GlossGuru": ReactJsonAgent(tools=tools, system_prompt="Define terms with pizzazz! 📖"),
35
+ }
36
+
37
+ # MoE Prompts mapped to agents
38
+ moe_prompts = {
39
+ "Create a python streamlit app.py...": "CodeCrafter",
40
+ "Create a python gradio app.py...": "CodeCrafter",
41
+ "Create a mermaid model...": "OutlineOracle",
42
+ "Create a top three list of tools...": "ToolTitan",
43
+ "Create a specification in markdown...": "SpecSpinner",
44
+ "Create an image generation prompt...": "ImageImp",
45
+ "Generate an image which describes...": "VisualVortex",
46
+ "List top ten glossary terms...": "GlossGuru",
47
+ "": "StepSage" # Default agent for blank selection
48
+ }
49
+
50
+ # Session state
51
  if 'selected_file' not in st.session_state:
52
  st.session_state.selected_file = None
53
  if 'view_mode' not in st.session_state:
 
55
  if 'files' not in st.session_state:
56
  st.session_state.files = []
57
 
58
+ # MoE Selection
59
+ moe_options = list(moe_prompts.keys())
60
+ selected_moe = st.selectbox("Pick an MoE Adventure! 🎲", moe_options, index=0, key="selected_moe")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ # Utility Functions (simplified for brevity, reusing yours where unchanged)
63
  def sanitize_filename(text):
64
+ return re.sub(r'[^\w\s-]', ' ', text.strip())[:50]
 
 
 
 
65
 
66
  def generate_timestamp_filename(query):
 
67
  central = pytz.timezone('US/Central')
68
+ now = datetime.now(central)
69
+ return f"{now.strftime('%I%M%p %m%d%Y')} ({sanitize_filename(query)}).md"
 
 
 
 
70
 
71
+ def save_ai_interaction(query, result, is_rerun=False):
 
 
 
 
 
 
 
 
 
 
72
  filename = generate_timestamp_filename(query)
73
+ content = f"# {'Rerun' if is_rerun else 'Query'}: {query}\n\n## AI Response\n{result}"
74
+ with open(filename, 'w', encoding='utf-8') as f:
75
+ f.write(content)
76
+ return filename
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
+ def run_agent(task, agent_name):
79
+ agent = agents[agent_name]
80
+ if isinstance(agent, CodeAgent):
81
+ return agent.run(task, return_generated_code=True)
82
+ return agent.run(task)
83
 
84
+ # Main App
85
  def main():
86
+ st.markdown("### 🌳 AI Knowledge Tree Builder 🧠🌱 Let’s Grow Some Smarts!")
87
+ query = st.text_input("Ask Away! 🤔", placeholder="E.g., 'Explain transformers!'")
 
 
88
 
89
  if query:
90
+ agent_name = moe_prompts[selected_moe]
 
91
  try:
92
+ result = run_agent(f"{selected_moe} {query}" if selected_moe else query, agent_name)
93
+ st.markdown(f"🎉 {agent_name} says: {result}")
94
+ saved_file = save_ai_interaction(query, result)
95
+ st.success(f"Saved to {saved_file}")
96
+ st.session_state.selected_file = saved_file
 
97
  except Exception as e:
98
+ st.error(f"😱 Oops! {e}")
99
+
100
+ # File Management (simplified)
101
+ st.sidebar.title("📁 Files")
102
+ md_files = sorted([f for f in glob.glob("*.md") if f.lower() != 'readme.md'])
103
+ for file in md_files:
104
+ st.sidebar.write(file)
105
+ if st.sidebar.button(f"View {file}", key=f"v_{file}"):
106
+ st.session_state.selected_file = file
107
  if st.session_state.selected_file:
108
+ with open(st.session_state.selected_file, 'r') as f:
109
+ st.markdown(f.read())
 
 
 
 
 
 
 
 
 
110
 
111
  if __name__ == "__main__":
112
+ main()