Spaces:
				
			
			
	
			
			
		Sleeping
		
	
	
	
			
			
	
	
	
	
		
		
		Sleeping
		
	Create backup11.app.py
Browse files- backup11.app.py +953 -0
    	
        backup11.app.py
    ADDED
    
    | @@ -0,0 +1,953 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            import streamlit as st
         | 
| 2 | 
            +
            import anthropic, openai, base64, cv2, glob, json, math, os, pytz, random, re, requests, textract, time, zipfile
         | 
| 3 | 
            +
            import plotly.graph_objects as go
         | 
| 4 | 
            +
            import streamlit.components.v1 as components
         | 
| 5 | 
            +
            from datetime import datetime
         | 
| 6 | 
            +
            from audio_recorder_streamlit import audio_recorder
         | 
| 7 | 
            +
            from bs4 import BeautifulSoup
         | 
| 8 | 
            +
            from collections import defaultdict, deque, Counter
         | 
| 9 | 
            +
            from dotenv import load_dotenv
         | 
| 10 | 
            +
            from gradio_client import Client
         | 
| 11 | 
            +
            from huggingface_hub import InferenceClient
         | 
| 12 | 
            +
            from io import BytesIO
         | 
| 13 | 
            +
            from PIL import Image
         | 
| 14 | 
            +
            from PyPDF2 import PdfReader
         | 
| 15 | 
            +
            from urllib.parse import quote
         | 
| 16 | 
            +
            from xml.etree import ElementTree as ET
         | 
| 17 | 
            +
            from openai import OpenAI
         | 
| 18 | 
            +
            import extra_streamlit_components as stx
         | 
| 19 | 
            +
            from streamlit.runtime.scriptrunner import get_script_run_ctx
         | 
| 20 | 
            +
            import asyncio
         | 
| 21 | 
            +
            import edge_tts
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            # 🎯 1. Core Configuration & Setup
         | 
| 24 | 
            +
            st.set_page_config(
         | 
| 25 | 
            +
                page_title="🚲TalkingAIResearcher🏆",
         | 
| 26 | 
            +
                page_icon="🚲🏆",
         | 
| 27 | 
            +
                layout="wide",
         | 
| 28 | 
            +
                initial_sidebar_state="auto",
         | 
| 29 | 
            +
                menu_items={
         | 
| 30 | 
            +
                    'Get Help': 'https://huggingface.co/awacke1',
         | 
| 31 | 
            +
                    'Report a bug': 'https://huggingface.co/spaces/awacke1',
         | 
| 32 | 
            +
                    'About': "🚲TalkingAIResearcher🏆"
         | 
| 33 | 
            +
                }
         | 
| 34 | 
            +
            )
         | 
| 35 | 
            +
            load_dotenv()
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            # Add available English voices for Edge TTS
         | 
| 38 | 
            +
            EDGE_TTS_VOICES = [
         | 
| 39 | 
            +
                "en-US-AriaNeural",  # Default voice
         | 
| 40 | 
            +
                "en-US-GuyNeural", 
         | 
| 41 | 
            +
                "en-US-JennyNeural",
         | 
| 42 | 
            +
                "en-GB-SoniaNeural",
         | 
| 43 | 
            +
                "en-GB-RyanNeural",
         | 
| 44 | 
            +
                "en-AU-NatashaNeural",
         | 
| 45 | 
            +
                "en-AU-WilliamNeural",
         | 
| 46 | 
            +
                "en-CA-ClaraNeural",
         | 
| 47 | 
            +
                "en-CA-LiamNeural"
         | 
| 48 | 
            +
            ]
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            # Initialize session state variables
         | 
| 51 | 
            +
            if 'tts_voice' not in st.session_state:
         | 
| 52 | 
            +
                st.session_state['tts_voice'] = EDGE_TTS_VOICES[0]  # Default voice
         | 
| 53 | 
            +
            if 'audio_format' not in st.session_state:
         | 
| 54 | 
            +
                st.session_state['audio_format'] = 'mp3'  # 🆕 Default audio format
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            # 🔑 2. API Setup & Clients
         | 
| 57 | 
            +
            openai_api_key = os.getenv('OPENAI_API_KEY', "")
         | 
| 58 | 
            +
            anthropic_key = os.getenv('ANTHROPIC_API_KEY_3', "")
         | 
| 59 | 
            +
            xai_key = os.getenv('xai',"")
         | 
| 60 | 
            +
            if 'OPENAI_API_KEY' in st.secrets:
         | 
| 61 | 
            +
                openai_api_key = st.secrets['OPENAI_API_KEY']
         | 
| 62 | 
            +
            if 'ANTHROPIC_API_KEY' in st.secrets:
         | 
| 63 | 
            +
                anthropic_key = st.secrets["ANTHROPIC_API_KEY"]
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            openai.api_key = openai_api_key
         | 
| 66 | 
            +
            claude_client = anthropic.Anthropic(api_key=anthropic_key)
         | 
| 67 | 
            +
            openai_client = OpenAI(api_key=openai.api_key, organization=os.getenv('OPENAI_ORG_ID'))
         | 
| 68 | 
            +
            HF_KEY = os.getenv('HF_KEY')
         | 
| 69 | 
            +
            API_URL = os.getenv('API_URL')
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            # 📝 3. Session State Management
         | 
| 72 | 
            +
            if 'transcript_history' not in st.session_state:
         | 
| 73 | 
            +
                st.session_state['transcript_history'] = []
         | 
| 74 | 
            +
            if 'chat_history' not in st.session_state:
         | 
| 75 | 
            +
                st.session_state['chat_history'] = []
         | 
| 76 | 
            +
            if 'openai_model' not in st.session_state:
         | 
| 77 | 
            +
                st.session_state['openai_model'] = "gpt-4o-2024-05-13"
         | 
| 78 | 
            +
            if 'messages' not in st.session_state:
         | 
| 79 | 
            +
                st.session_state['messages'] = []
         | 
| 80 | 
            +
            if 'last_voice_input' not in st.session_state:
         | 
| 81 | 
            +
                st.session_state['last_voice_input'] = ""
         | 
| 82 | 
            +
            if 'editing_file' not in st.session_state:
         | 
| 83 | 
            +
                st.session_state['editing_file'] = None
         | 
| 84 | 
            +
            if 'edit_new_name' not in st.session_state:
         | 
| 85 | 
            +
                st.session_state['edit_new_name'] = ""
         | 
| 86 | 
            +
            if 'edit_new_content' not in st.session_state:
         | 
| 87 | 
            +
                st.session_state['edit_new_content'] = ""
         | 
| 88 | 
            +
            if 'viewing_prefix' not in st.session_state:
         | 
| 89 | 
            +
                st.session_state['viewing_prefix'] = None
         | 
| 90 | 
            +
            if 'should_rerun' not in st.session_state:
         | 
| 91 | 
            +
                st.session_state['should_rerun'] = False
         | 
| 92 | 
            +
            if 'old_val' not in st.session_state:
         | 
| 93 | 
            +
                st.session_state['old_val'] = None
         | 
| 94 | 
            +
            if 'last_query' not in st.session_state:
         | 
| 95 | 
            +
                st.session_state['last_query'] = ""  # 🆕 Store the last query for zip naming
         | 
| 96 | 
            +
             | 
| 97 | 
            +
            # 🎨 4. Custom CSS
         | 
| 98 | 
            +
            st.markdown("""
         | 
| 99 | 
            +
            <style>
         | 
| 100 | 
            +
                .main { background: linear-gradient(to right, #1a1a1a, #2d2d2d); color: #fff; }
         | 
| 101 | 
            +
                .stMarkdown { font-family: 'Helvetica Neue', sans-serif; }
         | 
| 102 | 
            +
                .stButton>button {
         | 
| 103 | 
            +
                    margin-right: 0.5rem;
         | 
| 104 | 
            +
                }
         | 
| 105 | 
            +
            </style>
         | 
| 106 | 
            +
            """, unsafe_allow_html=True)
         | 
| 107 | 
            +
             | 
| 108 | 
            +
            FILE_EMOJIS = {
         | 
| 109 | 
            +
                "md": "📝",
         | 
| 110 | 
            +
                "mp3": "🎵",
         | 
| 111 | 
            +
                "wav": "🔊"  # 🆕 Add emoji for WAV
         | 
| 112 | 
            +
            }
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            # 🧠 5. High-Information Content Extraction
         | 
| 115 | 
            +
            def get_high_info_terms(text: str, top_n=10) -> list:
         | 
| 116 | 
            +
                """Extract high-information terms from text, including key phrases."""
         | 
| 117 | 
            +
                stop_words = set([
         | 
| 118 | 
            +
                    'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with',
         | 
| 119 | 
            +
                    'by', 'from', 'up', 'about', 'into', 'over', 'after', 'is', 'are', 'was', 'were',
         | 
| 120 | 
            +
                    'be', 'been', 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would',
         | 
| 121 | 
            +
                    'should', 'could', 'might', 'must', 'shall', 'can', 'may', 'this', 'that', 'these',
         | 
| 122 | 
            +
                    'those', 'i', 'you', 'he', 'she', 'it', 'we', 'they', 'what', 'which', 'who',
         | 
| 123 | 
            +
                    'when', 'where', 'why', 'how', 'all', 'any', 'both', 'each', 'few', 'more', 'most',
         | 
| 124 | 
            +
                    'other', 'some', 'such', 'than', 'too', 'very', 'just', 'there'
         | 
| 125 | 
            +
                ])
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                key_phrases = [
         | 
| 128 | 
            +
                    'artificial intelligence', 'machine learning', 'deep learning', 'neural network',
         | 
| 129 | 
            +
                    'personal assistant', 'natural language', 'computer vision', 'data science',
         | 
| 130 | 
            +
                    'reinforcement learning', 'knowledge graph', 'semantic search', 'time series',
         | 
| 131 | 
            +
                    'large language model', 'transformer model', 'attention mechanism',
         | 
| 132 | 
            +
                    'autonomous system', 'edge computing', 'quantum computing', 'blockchain technology',
         | 
| 133 | 
            +
                    'cognitive science', 'human computer', 'decision making', 'arxiv search',
         | 
| 134 | 
            +
                    'research paper', 'scientific study', 'empirical analysis'
         | 
| 135 | 
            +
                ]
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                # Extract bi-grams and uni-grams
         | 
| 138 | 
            +
                words = re.findall(r'\b\w+(?:-\w+)*\b', text.lower())
         | 
| 139 | 
            +
                bi_grams = [' '.join(pair) for pair in zip(words, words[1:])]
         | 
| 140 | 
            +
                combined = words + bi_grams
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                # Filter out stop words and short words
         | 
| 143 | 
            +
                filtered = [
         | 
| 144 | 
            +
                    term for term in combined
         | 
| 145 | 
            +
                    if term not in stop_words
         | 
| 146 | 
            +
                    and len(term.split()) <= 2  # Limit to uni-grams and bi-grams
         | 
| 147 | 
            +
                    and any(c.isalpha() for c in term)
         | 
| 148 | 
            +
                ]
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                # Count frequencies
         | 
| 151 | 
            +
                counter = Counter(filtered)
         | 
| 152 | 
            +
                most_common = [term for term, freq in counter.most_common(top_n)]
         | 
| 153 | 
            +
                return most_common
         | 
| 154 | 
            +
             | 
| 155 | 
            +
            def clean_text_for_filename(text: str) -> str:
         | 
| 156 | 
            +
                """Remove punctuation and short filler words, return a compact string."""
         | 
| 157 | 
            +
                text = text.lower()
         | 
| 158 | 
            +
                text = re.sub(r'[^\w\s-]', '', text)
         | 
| 159 | 
            +
                words = text.split()
         | 
| 160 | 
            +
                stop_short = set(['the','and','for','with','this','that','from','just','very','then','been','only','also','about'])
         | 
| 161 | 
            +
                filtered = [w for w in words if len(w)>3 and w not in stop_short]
         | 
| 162 | 
            +
                return '_'.join(filtered)[:200]
         | 
| 163 | 
            +
             | 
| 164 | 
            +
            # 📁 6. File Operations
         | 
| 165 | 
            +
            def generate_filename(prompt, response, file_type="md"):
         | 
| 166 | 
            +
                """
         | 
| 167 | 
            +
                Generate filename with meaningful terms and short dense clips from prompt & response.
         | 
| 168 | 
            +
                The filename should be about 150 chars total, include high-info terms, and a clipped snippet.
         | 
| 169 | 
            +
                """
         | 
| 170 | 
            +
                prefix = datetime.now().strftime("%y%m_%H%M") + "_"
         | 
| 171 | 
            +
                combined = (prompt + " " + response).strip()
         | 
| 172 | 
            +
                info_terms = get_high_info_terms(combined, top_n=10)
         | 
| 173 | 
            +
                
         | 
| 174 | 
            +
                # Include a short snippet from prompt and response
         | 
| 175 | 
            +
                snippet = (prompt[:100] + " " + response[:100]).strip()
         | 
| 176 | 
            +
                snippet_cleaned = clean_text_for_filename(snippet)
         | 
| 177 | 
            +
                
         | 
| 178 | 
            +
                # Combine info terms and snippet
         | 
| 179 | 
            +
                name_parts = info_terms + [snippet_cleaned]
         | 
| 180 | 
            +
                full_name = '_'.join(name_parts)
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                # Trim to ~150 chars
         | 
| 183 | 
            +
                if len(full_name) > 150:
         | 
| 184 | 
            +
                    full_name = full_name[:150]
         | 
| 185 | 
            +
                
         | 
| 186 | 
            +
                filename = f"{prefix}{full_name}.{file_type}"
         | 
| 187 | 
            +
                return filename
         | 
| 188 | 
            +
             | 
| 189 | 
            +
            def create_file(prompt, response, file_type="md"):
         | 
| 190 | 
            +
                """Create file with intelligent naming"""
         | 
| 191 | 
            +
                filename = generate_filename(prompt.strip(), response.strip(), file_type)
         | 
| 192 | 
            +
                with open(filename, 'w', encoding='utf-8') as f:
         | 
| 193 | 
            +
                    f.write(prompt + "\n\n" + response)
         | 
| 194 | 
            +
                return filename
         | 
| 195 | 
            +
             | 
| 196 | 
            +
            def get_download_link(file, file_type="zip"):
         | 
| 197 | 
            +
                """Generate download link for file"""
         | 
| 198 | 
            +
                with open(file, "rb") as f:
         | 
| 199 | 
            +
                    b64 = base64.b64encode(f.read()).decode()
         | 
| 200 | 
            +
                if file_type == "zip":
         | 
| 201 | 
            +
                    return f'<a href="data:application/zip;base64,{b64}" download="{os.path.basename(file)}">📂 Download {os.path.basename(file)}</a>'
         | 
| 202 | 
            +
                elif file_type == "mp3":
         | 
| 203 | 
            +
                    return f'<a href="data:audio/mpeg;base64,{b64}" download="{os.path.basename(file)}">🎵 Download {os.path.basename(file)}</a>'
         | 
| 204 | 
            +
                elif file_type == "wav":
         | 
| 205 | 
            +
                    return f'<a href="data:audio/wav;base64,{b64}" download="{os.path.basename(file)}">🔊 Download {os.path.basename(file)}</a>'  # 🆕 WAV download link
         | 
| 206 | 
            +
                elif file_type == "md":
         | 
| 207 | 
            +
                    return f'<a href="data:text/markdown;base64,{b64}" download="{os.path.basename(file)}">📝 Download {os.path.basename(file)}</a>'
         | 
| 208 | 
            +
                else:
         | 
| 209 | 
            +
                    return f'<a href="data:application/octet-stream;base64,{b64}" download="{os.path.basename(file)}">Download {os.path.basename(file)}</a>'
         | 
| 210 | 
            +
             | 
| 211 | 
            +
            # 🔊 7. Audio Processing
         | 
| 212 | 
            +
            def clean_for_speech(text: str) -> str:
         | 
| 213 | 
            +
                """Clean text for speech synthesis"""
         | 
| 214 | 
            +
                text = text.replace("\n", " ")
         | 
| 215 | 
            +
                text = text.replace("</s>", " ")
         | 
| 216 | 
            +
                text = text.replace("#", "")
         | 
| 217 | 
            +
                text = re.sub(r"\(https?:\/\/[^\)]+\)", "", text)
         | 
| 218 | 
            +
                text = re.sub(r"\s+", " ", text).strip()
         | 
| 219 | 
            +
                return text
         | 
| 220 | 
            +
             | 
| 221 | 
            +
            @st.cache_resource
         | 
| 222 | 
            +
            def speech_synthesis_html(result):
         | 
| 223 | 
            +
                """Create HTML for speech synthesis"""
         | 
| 224 | 
            +
                html_code = f"""
         | 
| 225 | 
            +
                <html><body>
         | 
| 226 | 
            +
                <script>
         | 
| 227 | 
            +
                var msg = new SpeechSynthesisUtterance("{result.replace('"', '')}");
         | 
| 228 | 
            +
                window.speechSynthesis.speak(msg);
         | 
| 229 | 
            +
                </script>
         | 
| 230 | 
            +
                </body></html>
         | 
| 231 | 
            +
                """
         | 
| 232 | 
            +
                components.html(html_code, height=0)
         | 
| 233 | 
            +
             | 
| 234 | 
            +
            async def edge_tts_generate_audio(text, voice="en-US-AriaNeural", rate=0, pitch=0, file_format="mp3"):
         | 
| 235 | 
            +
                """Generate audio using Edge TTS"""
         | 
| 236 | 
            +
                text = clean_for_speech(text)
         | 
| 237 | 
            +
                if not text.strip():
         | 
| 238 | 
            +
                    return None
         | 
| 239 | 
            +
                rate_str = f"{rate:+d}%"
         | 
| 240 | 
            +
                pitch_str = f"{pitch:+d}Hz"
         | 
| 241 | 
            +
                communicate = edge_tts.Communicate(text, voice, rate=rate_str, pitch=pitch_str)
         | 
| 242 | 
            +
                out_fn = generate_filename(text, text, file_type=file_format)
         | 
| 243 | 
            +
                await communicate.save(out_fn)
         | 
| 244 | 
            +
                return out_fn
         | 
| 245 | 
            +
             | 
| 246 | 
            +
            def speak_with_edge_tts(text, voice="en-US-AriaNeural", rate=0, pitch=0, file_format="mp3"):
         | 
| 247 | 
            +
                """Wrapper for edge TTS generation"""
         | 
| 248 | 
            +
                return asyncio.run(edge_tts_generate_audio(text, voice, rate, pitch, file_format))
         | 
| 249 | 
            +
             | 
| 250 | 
            +
            def play_and_download_audio(file_path, file_type="mp3"):
         | 
| 251 | 
            +
                """Play and provide download link for audio"""
         | 
| 252 | 
            +
                if file_path and os.path.exists(file_path):
         | 
| 253 | 
            +
                    if file_type == "mp3":
         | 
| 254 | 
            +
                        st.audio(file_path)
         | 
| 255 | 
            +
                    elif file_type == "wav":
         | 
| 256 | 
            +
                        st.audio(file_path)
         | 
| 257 | 
            +
                    dl_link = get_download_link(file_path, file_type=file_type)
         | 
| 258 | 
            +
                    st.markdown(dl_link, unsafe_allow_html=True)
         | 
| 259 | 
            +
             | 
| 260 | 
            +
            # 🎬 8. Media Processing
         | 
| 261 | 
            +
            def process_image(image_path, user_prompt):
         | 
| 262 | 
            +
                """Process image with GPT-4V"""
         | 
| 263 | 
            +
                with open(image_path, "rb") as imgf:
         | 
| 264 | 
            +
                    image_data = imgf.read()
         | 
| 265 | 
            +
                b64img = base64.b64encode(image_data).decode("utf-8")
         | 
| 266 | 
            +
                resp = openai_client.chat.completions.create(
         | 
| 267 | 
            +
                    model=st.session_state["openai_model"],
         | 
| 268 | 
            +
                    messages=[
         | 
| 269 | 
            +
                        {"role": "system", "content": "You are a helpful assistant."},
         | 
| 270 | 
            +
                        {"role": "user", "content": [
         | 
| 271 | 
            +
                            {"type": "text", "text": user_prompt},
         | 
| 272 | 
            +
                            {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64img}"}}
         | 
| 273 | 
            +
                        ]}
         | 
| 274 | 
            +
                    ],
         | 
| 275 | 
            +
                    temperature=0.0,
         | 
| 276 | 
            +
                )
         | 
| 277 | 
            +
                return resp.choices[0].message.content
         | 
| 278 | 
            +
             | 
| 279 | 
            +
            def process_audio_file(audio_path):
         | 
| 280 | 
            +
                """Process audio with Whisper"""
         | 
| 281 | 
            +
                with open(audio_path, "rb") as f:
         | 
| 282 | 
            +
                    transcription = openai_client.audio.transcriptions.create(model="whisper-1", file=f)
         | 
| 283 | 
            +
                st.session_state.messages.append({"role": "user", "content": transcription.text})
         | 
| 284 | 
            +
                return transcription.text
         | 
| 285 | 
            +
             | 
| 286 | 
            +
            def process_video(video_path, seconds_per_frame=1):
         | 
| 287 | 
            +
                """Extract frames from video"""
         | 
| 288 | 
            +
                vid = cv2.VideoCapture(video_path)
         | 
| 289 | 
            +
                total = int(vid.get(cv2.CAP_PROP_FRAME_COUNT))
         | 
| 290 | 
            +
                fps = vid.get(cv2.CAP_PROP_FPS)
         | 
| 291 | 
            +
                skip = int(fps*seconds_per_frame)
         | 
| 292 | 
            +
                frames_b64 = []
         | 
| 293 | 
            +
                for i in range(0, total, skip):
         | 
| 294 | 
            +
                    vid.set(cv2.CAP_PROP_POS_FRAMES, i)
         | 
| 295 | 
            +
                    ret, frame = vid.read()
         | 
| 296 | 
            +
                    if not ret: 
         | 
| 297 | 
            +
                        break
         | 
| 298 | 
            +
                    _, buf = cv2.imencode(".jpg", frame)
         | 
| 299 | 
            +
                    frames_b64.append(base64.b64encode(buf).decode("utf-8"))
         | 
| 300 | 
            +
                vid.release()
         | 
| 301 | 
            +
                return frames_b64
         | 
| 302 | 
            +
             | 
| 303 | 
            +
            def process_video_with_gpt(video_path, prompt):
         | 
| 304 | 
            +
                """Analyze video frames with GPT-4V"""
         | 
| 305 | 
            +
                frames = process_video(video_path)
         | 
| 306 | 
            +
                resp = openai_client.chat.completions.create(
         | 
| 307 | 
            +
                    model=st.session_state["openai_model"],
         | 
| 308 | 
            +
                    messages=[
         | 
| 309 | 
            +
                        {"role":"system","content":"Analyze video frames."},
         | 
| 310 | 
            +
                        {"role":"user","content":[
         | 
| 311 | 
            +
                            {"type":"text","text":prompt},
         | 
| 312 | 
            +
                            *[{"type":"image_url","image_url":{"url":f"data:image/jpeg;base64,{fr}"}} for fr in frames]
         | 
| 313 | 
            +
                        ]}
         | 
| 314 | 
            +
                    ]
         | 
| 315 | 
            +
                )
         | 
| 316 | 
            +
                return resp.choices[0].message.content
         | 
| 317 | 
            +
             | 
| 318 | 
            +
            # 🤖 9. AI Model Integration
         | 
| 319 | 
            +
             | 
| 320 | 
            +
            def save_full_transcript(query, text):
         | 
| 321 | 
            +
                """Save full transcript of Arxiv results as a file."""
         | 
| 322 | 
            +
                create_file(query, text, "md")
         | 
| 323 | 
            +
             | 
| 324 | 
            +
            def parse_arxiv_refs(ref_text: str):
         | 
| 325 | 
            +
                """
         | 
| 326 | 
            +
                Parse papers by finding lines with two pipe characters as title lines.
         | 
| 327 | 
            +
                Returns list of paper dictionaries with audio files.
         | 
| 328 | 
            +
                """
         | 
| 329 | 
            +
                if not ref_text:
         | 
| 330 | 
            +
                    return []
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                results = []
         | 
| 333 | 
            +
                current_paper = {}
         | 
| 334 | 
            +
                lines = ref_text.split('\n')
         | 
| 335 | 
            +
                
         | 
| 336 | 
            +
                for i, line in enumerate(lines):
         | 
| 337 | 
            +
                    # Check if this is a title line (contains exactly 2 pipe characters)
         | 
| 338 | 
            +
                    if line.count('|') == 2:
         | 
| 339 | 
            +
                        # If we have a previous paper, add it to results
         | 
| 340 | 
            +
                        if current_paper:
         | 
| 341 | 
            +
                            results.append(current_paper)
         | 
| 342 | 
            +
                            if len(results) >= 20:  # Limit to 20 papers
         | 
| 343 | 
            +
                                break
         | 
| 344 | 
            +
                        
         | 
| 345 | 
            +
                        # Parse new paper header
         | 
| 346 | 
            +
                        try:
         | 
| 347 | 
            +
                            # Remove ** and split by |
         | 
| 348 | 
            +
                            header_parts = line.strip('* ').split('|')
         | 
| 349 | 
            +
                            date = header_parts[0].strip()
         | 
| 350 | 
            +
                            title = header_parts[1].strip()
         | 
| 351 | 
            +
                            # Extract arXiv URL if present
         | 
| 352 | 
            +
                            url_match = re.search(r'(https://arxiv.org/\S+)', line)
         | 
| 353 | 
            +
                            url = url_match.group(1) if url_match else f"paper_{len(results)}"
         | 
| 354 | 
            +
                            
         | 
| 355 | 
            +
                            current_paper = {
         | 
| 356 | 
            +
                                'date': date,
         | 
| 357 | 
            +
                                'title': title,
         | 
| 358 | 
            +
                                'url': url,
         | 
| 359 | 
            +
                                'authors': '',
         | 
| 360 | 
            +
                                'summary': '',
         | 
| 361 | 
            +
                                'content_start': i + 1  # Track where content begins
         | 
| 362 | 
            +
                            }
         | 
| 363 | 
            +
                        except Exception as e:
         | 
| 364 | 
            +
                            st.warning(f"Error parsing paper header: {str(e)}")
         | 
| 365 | 
            +
                            current_paper = {}
         | 
| 366 | 
            +
                            continue
         | 
| 367 | 
            +
                    
         | 
| 368 | 
            +
                    # If we have a current paper and this isn't a title line, add to content
         | 
| 369 | 
            +
                    elif current_paper:
         | 
| 370 | 
            +
                        if not current_paper['authors']:  # First line after title is authors
         | 
| 371 | 
            +
                            current_paper['authors'] = line.strip('* ')
         | 
| 372 | 
            +
                        else:  # Rest is summary
         | 
| 373 | 
            +
                            if current_paper['summary']:
         | 
| 374 | 
            +
                                current_paper['summary'] += ' ' + line.strip()
         | 
| 375 | 
            +
                            else:
         | 
| 376 | 
            +
                                current_paper['summary'] = line.strip()
         | 
| 377 | 
            +
                
         | 
| 378 | 
            +
                # Don't forget the last paper
         | 
| 379 | 
            +
                if current_paper:
         | 
| 380 | 
            +
                    results.append(current_paper)
         | 
| 381 | 
            +
                
         | 
| 382 | 
            +
                return results[:20]  # Ensure we return maximum 20 papers
         | 
| 383 | 
            +
             | 
| 384 | 
            +
            def create_paper_audio_files(papers, input_question):
         | 
| 385 | 
            +
                """
         | 
| 386 | 
            +
                Create audio files for each paper's content and add file paths to paper dict.
         | 
| 387 | 
            +
                Also, display each audio as it's generated.
         | 
| 388 | 
            +
                """
         | 
| 389 | 
            +
                # Collect all content for combined summary
         | 
| 390 | 
            +
                combined_titles = []
         | 
| 391 | 
            +
             | 
| 392 | 
            +
                for paper in papers:
         | 
| 393 | 
            +
                    try:
         | 
| 394 | 
            +
                        # Generate audio for full content only
         | 
| 395 | 
            +
                        full_text = f"{paper['title']} by {paper['authors']}. {paper['summary']}"
         | 
| 396 | 
            +
                        full_text = clean_for_speech(full_text)
         | 
| 397 | 
            +
                        # Determine file format based on user selection
         | 
| 398 | 
            +
                        file_format = st.session_state['audio_format']
         | 
| 399 | 
            +
                        full_file = speak_with_edge_tts(full_text, voice=st.session_state['tts_voice'], file_format=file_format)
         | 
| 400 | 
            +
                        paper['full_audio'] = full_file
         | 
| 401 | 
            +
             | 
| 402 | 
            +
                        # Display the audio immediately after generation
         | 
| 403 | 
            +
                        st.write(f"### {FILE_EMOJIS.get(file_format, '')} {os.path.basename(full_file)}")
         | 
| 404 | 
            +
                        play_and_download_audio(full_file, file_type=file_format)
         | 
| 405 | 
            +
                        
         | 
| 406 | 
            +
                        combined_titles.append(paper['title'])
         | 
| 407 | 
            +
                    
         | 
| 408 | 
            +
                    except Exception as e:
         | 
| 409 | 
            +
                        st.warning(f"Error generating audio for paper {paper['title']}: {str(e)}")
         | 
| 410 | 
            +
                        paper['full_audio'] = None
         | 
| 411 | 
            +
             | 
| 412 | 
            +
                # After all individual audios, create a combined summary audio
         | 
| 413 | 
            +
                if combined_titles:
         | 
| 414 | 
            +
                    combined_text = f"Here are the titles of the papers related to your query: {'; '.join(combined_titles)}. Your original question was: {input_question}"
         | 
| 415 | 
            +
                    file_format = st.session_state['audio_format']
         | 
| 416 | 
            +
                    combined_file = speak_with_edge_tts(combined_text, voice=st.session_state['tts_voice'], file_format=file_format)
         | 
| 417 | 
            +
                    st.write(f"### {FILE_EMOJIS.get(file_format, '')} Combined Summary Audio")
         | 
| 418 | 
            +
                    play_and_download_audio(combined_file, file_type=file_format)
         | 
| 419 | 
            +
                    papers.append({'title': 'Combined Summary', 'full_audio': combined_file})
         | 
| 420 | 
            +
             | 
| 421 | 
            +
            def display_papers(papers):
         | 
| 422 | 
            +
                """
         | 
| 423 | 
            +
                Display papers with their audio controls using URLs as unique keys.
         | 
| 424 | 
            +
                """
         | 
| 425 | 
            +
                st.write("## Research Papers")
         | 
| 426 | 
            +
                papercount=0
         | 
| 427 | 
            +
                for idx, paper in enumerate(papers):
         | 
| 428 | 
            +
                    papercount = papercount + 1
         | 
| 429 | 
            +
                    if (papercount<=20):
         | 
| 430 | 
            +
                        with st.expander(f"{papercount}. 📄 {paper['title']}", expanded=True):
         | 
| 431 | 
            +
                            st.markdown(f"**{paper['date']} | {paper['title']} | ⬇️**")
         | 
| 432 | 
            +
                            st.markdown(f"*{paper['authors']}*")
         | 
| 433 | 
            +
                            st.markdown(paper['summary'])
         | 
| 434 | 
            +
                            
         | 
| 435 | 
            +
                            # Single audio control for full content
         | 
| 436 | 
            +
                            if paper.get('full_audio'):
         | 
| 437 | 
            +
                                st.write("📚 Paper Audio")
         | 
| 438 | 
            +
                                file_ext = os.path.splitext(paper['full_audio'])[1].lower().strip('.')
         | 
| 439 | 
            +
                                if file_ext == "mp3":
         | 
| 440 | 
            +
                                    st.audio(paper['full_audio'])
         | 
| 441 | 
            +
                                elif file_ext == "wav":
         | 
| 442 | 
            +
                                    st.audio(paper['full_audio'])
         | 
| 443 | 
            +
             | 
| 444 | 
            +
            def perform_ai_lookup(q, vocal_summary=True, extended_refs=False, 
         | 
| 445 | 
            +
                                 titles_summary=True, full_audio=False):
         | 
| 446 | 
            +
                """Perform Arxiv search with audio generation per paper."""
         | 
| 447 | 
            +
                start = time.time()
         | 
| 448 | 
            +
             | 
| 449 | 
            +
                # Query the HF RAG pipeline
         | 
| 450 | 
            +
                client = Client("awacke1/Arxiv-Paper-Search-And-QA-RAG-Pattern")
         | 
| 451 | 
            +
                refs = client.predict(q, 20, "Semantic Search", 
         | 
| 452 | 
            +
                                     "mistralai/Mixtral-8x7B-Instruct-v0.1",
         | 
| 453 | 
            +
                                     api_name="/update_with_rag_md")[0]
         | 
| 454 | 
            +
                r2 = client.predict(q, "mistralai/Mixtral-8x7B-Instruct-v0.1", 
         | 
| 455 | 
            +
                                   True, api_name="/ask_llm")
         | 
| 456 | 
            +
             | 
| 457 | 
            +
                # Combine for final text output
         | 
| 458 | 
            +
                result = f"### 🔎 {q}\n\n{r2}\n\n{refs}"
         | 
| 459 | 
            +
                st.markdown(result)
         | 
| 460 | 
            +
             | 
| 461 | 
            +
                # Parse and process papers
         | 
| 462 | 
            +
                papers = parse_arxiv_refs(refs)
         | 
| 463 | 
            +
                if papers:
         | 
| 464 | 
            +
                    create_paper_audio_files(papers, input_question=q)
         | 
| 465 | 
            +
                    display_papers(papers)
         | 
| 466 | 
            +
                else:
         | 
| 467 | 
            +
                    st.warning("No papers found in the response.")
         | 
| 468 | 
            +
             | 
| 469 | 
            +
                elapsed = time.time()-start
         | 
| 470 | 
            +
                st.write(f"**Total Elapsed:** {elapsed:.2f} s")
         | 
| 471 | 
            +
             | 
| 472 | 
            +
                # Save full transcript
         | 
| 473 | 
            +
                create_file(q, result, "md")
         | 
| 474 | 
            +
                return result
         | 
| 475 | 
            +
             | 
| 476 | 
            +
            def process_with_gpt(text):
         | 
| 477 | 
            +
                """Process text with GPT-4"""
         | 
| 478 | 
            +
                if not text: 
         | 
| 479 | 
            +
                    return
         | 
| 480 | 
            +
                st.session_state.messages.append({"role":"user","content":text})
         | 
| 481 | 
            +
                with st.chat_message("user"):
         | 
| 482 | 
            +
                    st.markdown(text)
         | 
| 483 | 
            +
                with st.chat_message("assistant"):
         | 
| 484 | 
            +
                    c = openai_client.chat.completions.create(
         | 
| 485 | 
            +
                        model=st.session_state["openai_model"],
         | 
| 486 | 
            +
                        messages=st.session_state.messages,
         | 
| 487 | 
            +
                        stream=False
         | 
| 488 | 
            +
                    )
         | 
| 489 | 
            +
                    ans = c.choices[0].message.content
         | 
| 490 | 
            +
                    st.write("GPT-4o: " + ans)
         | 
| 491 | 
            +
                    create_file(text, ans, "md")
         | 
| 492 | 
            +
                    st.session_state.messages.append({"role":"assistant","content":ans})
         | 
| 493 | 
            +
                return ans
         | 
| 494 | 
            +
             | 
| 495 | 
            +
            def process_with_claude(text):
         | 
| 496 | 
            +
                """Process text with Claude"""
         | 
| 497 | 
            +
                if not text: 
         | 
| 498 | 
            +
                    return
         | 
| 499 | 
            +
                with st.chat_message("user"):
         | 
| 500 | 
            +
                    st.markdown(text)
         | 
| 501 | 
            +
                with st.chat_message("assistant"):
         | 
| 502 | 
            +
                    r = claude_client.messages.create(
         | 
| 503 | 
            +
                        model="claude-3-sonnet-20240229",
         | 
| 504 | 
            +
                        max_tokens=1000,
         | 
| 505 | 
            +
                        messages=[{"role":"user","content":text}]
         | 
| 506 | 
            +
                    )
         | 
| 507 | 
            +
                    ans = r.content[0].text
         | 
| 508 | 
            +
                    st.write("Claude-3.5: " + ans)
         | 
| 509 | 
            +
                    create_file(text, ans, "md")
         | 
| 510 | 
            +
                    st.session_state.chat_history.append({"user":text,"claude":ans})
         | 
| 511 | 
            +
                return ans
         | 
| 512 | 
            +
             | 
| 513 | 
            +
            # 📂 10. File Management
         | 
| 514 | 
            +
            def create_zip_of_files(md_files, mp3_files, wav_files, input_question):
         | 
| 515 | 
            +
                """Create zip with intelligent naming based on top 10 common words."""
         | 
| 516 | 
            +
                # Exclude 'readme.md'
         | 
| 517 | 
            +
                md_files = [f for f in md_files if os.path.basename(f).lower() != 'readme.md']
         | 
| 518 | 
            +
                all_files = md_files + mp3_files + wav_files
         | 
| 519 | 
            +
                if not all_files:
         | 
| 520 | 
            +
                    return None
         | 
| 521 | 
            +
             | 
| 522 | 
            +
                # Collect content for high-info term extraction
         | 
| 523 | 
            +
                all_content = []
         | 
| 524 | 
            +
                for f in all_files:
         | 
| 525 | 
            +
                    if f.endswith('.md'):
         | 
| 526 | 
            +
                        with open(f, 'r', encoding='utf-8') as file:
         | 
| 527 | 
            +
                            all_content.append(file.read())
         | 
| 528 | 
            +
                    elif f.endswith('.mp3') or f.endswith('.wav'):
         | 
| 529 | 
            +
                        # Replace underscores with spaces and extract basename without extension
         | 
| 530 | 
            +
                        basename = os.path.splitext(os.path.basename(f))[0]
         | 
| 531 | 
            +
                        words = basename.replace('_', ' ')
         | 
| 532 | 
            +
                        all_content.append(words)
         | 
| 533 | 
            +
                
         | 
| 534 | 
            +
                # Include the input question
         | 
| 535 | 
            +
                all_content.append(input_question)
         | 
| 536 | 
            +
                
         | 
| 537 | 
            +
                combined_content = " ".join(all_content)
         | 
| 538 | 
            +
                info_terms = get_high_info_terms(combined_content, top_n=10)
         | 
| 539 | 
            +
                
         | 
| 540 | 
            +
                timestamp = datetime.now().strftime("%y%m_%H%M")
         | 
| 541 | 
            +
                name_text = '_'.join(term.replace(' ', '-') for term in info_terms[:10])
         | 
| 542 | 
            +
                zip_name = f"{timestamp}_{name_text}.zip"
         | 
| 543 | 
            +
                
         | 
| 544 | 
            +
                with zipfile.ZipFile(zip_name,'w') as z:
         | 
| 545 | 
            +
                    for f in all_files:
         | 
| 546 | 
            +
                        z.write(f)
         | 
| 547 | 
            +
                
         | 
| 548 | 
            +
                return zip_name
         | 
| 549 | 
            +
             | 
| 550 | 
            +
            def load_files_for_sidebar():
         | 
| 551 | 
            +
                """Load and group files for sidebar display"""
         | 
| 552 | 
            +
                md_files = glob.glob("*.md")
         | 
| 553 | 
            +
                mp3_files = glob.glob("*.mp3")
         | 
| 554 | 
            +
                wav_files = glob.glob("*.wav")  # 🆕 Load WAV files
         | 
| 555 | 
            +
             | 
| 556 | 
            +
                md_files = [f for f in md_files if os.path.basename(f).lower() != 'readme.md']
         | 
| 557 | 
            +
                all_files = md_files + mp3_files + wav_files
         | 
| 558 | 
            +
             | 
| 559 | 
            +
                groups = defaultdict(list)
         | 
| 560 | 
            +
                for f in all_files:
         | 
| 561 | 
            +
                    # Treat underscores as spaces and split into words
         | 
| 562 | 
            +
                    words = os.path.basename(f).replace('_', ' ').split()
         | 
| 563 | 
            +
                    # Extract keywords from filename
         | 
| 564 | 
            +
                    keywords = get_high_info_terms(' '.join(words), top_n=5)
         | 
| 565 | 
            +
                    group_name = '_'.join(keywords) if keywords else 'Miscellaneous'
         | 
| 566 | 
            +
                    groups[group_name].append(f)
         | 
| 567 | 
            +
             | 
| 568 | 
            +
                # Sort groups based on latest file modification time
         | 
| 569 | 
            +
                sorted_groups = sorted(groups.items(), key=lambda x: max(os.path.getmtime(f) for f in x[1]), reverse=True)
         | 
| 570 | 
            +
                return sorted_groups
         | 
| 571 | 
            +
             | 
| 572 | 
            +
            def extract_keywords_from_md(files):
         | 
| 573 | 
            +
                """Extract keywords from markdown files"""
         | 
| 574 | 
            +
                text = ""
         | 
| 575 | 
            +
                for f in files:
         | 
| 576 | 
            +
                    if f.endswith(".md"):
         | 
| 577 | 
            +
                        c = open(f,'r',encoding='utf-8').read()
         | 
| 578 | 
            +
                        text += " " + c
         | 
| 579 | 
            +
                return get_high_info_terms(text, top_n=5)
         | 
| 580 | 
            +
             | 
| 581 | 
            +
            def display_file_manager_sidebar(groups_sorted):
         | 
| 582 | 
            +
                """Display file manager in sidebar"""
         | 
| 583 | 
            +
                st.sidebar.title("🎵 Audio & Docs Manager")
         | 
| 584 | 
            +
             | 
| 585 | 
            +
                all_md = []
         | 
| 586 | 
            +
                all_mp3 = []
         | 
| 587 | 
            +
                all_wav = []  # 🆕 List to hold WAV files
         | 
| 588 | 
            +
                for group_name, files in groups_sorted:
         | 
| 589 | 
            +
                    for f in files:
         | 
| 590 | 
            +
                        if f.endswith(".md"):
         | 
| 591 | 
            +
                            all_md.append(f)
         | 
| 592 | 
            +
                        elif f.endswith(".mp3"):
         | 
| 593 | 
            +
                            all_mp3.append(f)
         | 
| 594 | 
            +
                        elif f.endswith(".wav"):
         | 
| 595 | 
            +
                            all_wav.append(f)  # 🆕 Append WAV files
         | 
| 596 | 
            +
             | 
| 597 | 
            +
                top_bar = st.sidebar.columns(4)  # 🆕 Adjusted columns to accommodate WAV
         | 
| 598 | 
            +
                with top_bar[0]:
         | 
| 599 | 
            +
                    if st.button("🗑 DelAllMD"):
         | 
| 600 | 
            +
                        for f in all_md:
         | 
| 601 | 
            +
                            os.remove(f)
         | 
| 602 | 
            +
                        st.session_state.should_rerun = True
         | 
| 603 | 
            +
                with top_bar[1]:
         | 
| 604 | 
            +
                    if st.button("🗑 DelAllMP3"):
         | 
| 605 | 
            +
                        for f in all_mp3:
         | 
| 606 | 
            +
                            os.remove(f)
         | 
| 607 | 
            +
                        st.session_state.should_rerun = True
         | 
| 608 | 
            +
                with top_bar[2]:
         | 
| 609 | 
            +
                    if st.button("🗑 DelAllWAV"):
         | 
| 610 | 
            +
                        for f in all_wav:
         | 
| 611 | 
            +
                            os.remove(f)
         | 
| 612 | 
            +
                        st.session_state.should_rerun = True
         | 
| 613 | 
            +
                with top_bar[3]:
         | 
| 614 | 
            +
                    if st.button("⬇️ ZipAll"):
         | 
| 615 | 
            +
                        zip_name = create_zip_of_files(all_md, all_mp3, all_wav, input_question=st.session_state.get('last_query', ''))
         | 
| 616 | 
            +
                        if zip_name:
         | 
| 617 | 
            +
                            st.sidebar.markdown(get_download_link(zip_name, file_type="zip"), unsafe_allow_html=True)
         | 
| 618 | 
            +
             | 
| 619 | 
            +
                for group_name, files in groups_sorted:
         | 
| 620 | 
            +
                    keywords_str = group_name.replace('_', ' ') if group_name else "No Keywords"
         | 
| 621 | 
            +
                    with st.sidebar.expander(f"{FILE_EMOJIS.get('md', '')} {group_name} Files ({len(files)}) - KW: {keywords_str}", expanded=True):
         | 
| 622 | 
            +
                        c1,c2 = st.columns(2)
         | 
| 623 | 
            +
                        with c1:
         | 
| 624 | 
            +
                            if st.button("👀ViewGrp", key="view_group_"+group_name):
         | 
| 625 | 
            +
                                st.session_state.viewing_prefix = group_name
         | 
| 626 | 
            +
                        with c2:
         | 
| 627 | 
            +
                            if st.button("🗑DelGrp", key="del_group_"+group_name):
         | 
| 628 | 
            +
                                for f in files:
         | 
| 629 | 
            +
                                    os.remove(f)
         | 
| 630 | 
            +
                                st.success(f"Deleted group {group_name}!")
         | 
| 631 | 
            +
                                st.session_state.should_rerun = True
         | 
| 632 | 
            +
             | 
| 633 | 
            +
                        for f in files:
         | 
| 634 | 
            +
                            fname = os.path.basename(f)
         | 
| 635 | 
            +
                            ctime = datetime.fromtimestamp(os.path.getmtime(f)).strftime("%Y-%m-%d %H:%M:%S")
         | 
| 636 | 
            +
                            st.write(f"**{fname}** - {ctime}")
         | 
| 637 | 
            +
             | 
| 638 | 
            +
            # 🎯 11. Main Application
         | 
| 639 | 
            +
            def main():
         | 
| 640 | 
            +
                st.sidebar.markdown("### 🚲BikeAI🏆 Multi-Agent Research")
         | 
| 641 | 
            +
                
         | 
| 642 | 
            +
                # Add voice selector to sidebar
         | 
| 643 | 
            +
                st.sidebar.markdown("### 🎤 Voice Settings")
         | 
| 644 | 
            +
                selected_voice = st.sidebar.selectbox(
         | 
| 645 | 
            +
                    "Select TTS Voice:",
         | 
| 646 | 
            +
                    options=EDGE_TTS_VOICES,
         | 
| 647 | 
            +
                    index=EDGE_TTS_VOICES.index(st.session_state['tts_voice'])
         | 
| 648 | 
            +
                )
         | 
| 649 | 
            +
                
         | 
| 650 | 
            +
                # Add audio format selector to sidebar
         | 
| 651 | 
            +
                st.sidebar.markdown("### 🔊 Audio Format")
         | 
| 652 | 
            +
                selected_format = st.sidebar.radio(
         | 
| 653 | 
            +
                    "Choose Audio Format:",
         | 
| 654 | 
            +
                    options=["MP3", "WAV"],
         | 
| 655 | 
            +
                    index=0  # Default to MP3
         | 
| 656 | 
            +
                )
         | 
| 657 | 
            +
                
         | 
| 658 | 
            +
                # Update session state if voice or format changes
         | 
| 659 | 
            +
                if selected_voice != st.session_state['tts_voice']:
         | 
| 660 | 
            +
                    st.session_state['tts_voice'] = selected_voice
         | 
| 661 | 
            +
                    st.rerun()
         | 
| 662 | 
            +
                if selected_format.lower() != st.session_state['audio_format']:
         | 
| 663 | 
            +
                    st.session_state['audio_format'] = selected_format.lower()
         | 
| 664 | 
            +
                    st.rerun()
         | 
| 665 | 
            +
             | 
| 666 | 
            +
                tab_main = st.radio("Action:",["🎤 Voice","📸 Media","🔍 ArXiv","📝 Editor"],horizontal=True)
         | 
| 667 | 
            +
             | 
| 668 | 
            +
                mycomponent = components.declare_component("mycomponent", path="mycomponent")
         | 
| 669 | 
            +
                val = mycomponent(my_input_value="Hello")
         | 
| 670 | 
            +
             | 
| 671 | 
            +
                # Show input in a text box for editing if detected
         | 
| 672 | 
            +
                if val:
         | 
| 673 | 
            +
                    val_stripped = val.replace('\\n', ' ')
         | 
| 674 | 
            +
                    edited_input = st.text_area("✏️ Edit Input:", value=val_stripped, height=100)
         | 
| 675 | 
            +
                    #edited_input = edited_input.replace('\n', ' ')
         | 
| 676 | 
            +
                    
         | 
| 677 | 
            +
                    run_option = st.selectbox("Model:", ["Arxiv", "GPT-4o", "Claude-3.5"])
         | 
| 678 | 
            +
                    col1, col2 = st.columns(2)
         | 
| 679 | 
            +
                    with col1:
         | 
| 680 | 
            +
                        autorun = st.checkbox("⚙ AutoRun", value=True)
         | 
| 681 | 
            +
                    with col2:
         | 
| 682 | 
            +
                        full_audio = st.checkbox("📚FullAudio", value=False, 
         | 
| 683 | 
            +
                                                 help="Generate full audio response")
         | 
| 684 | 
            +
             | 
| 685 | 
            +
                    input_changed = (val != st.session_state.old_val)
         | 
| 686 | 
            +
             | 
| 687 | 
            +
                    if autorun and input_changed:
         | 
| 688 | 
            +
                        st.session_state.old_val = val
         | 
| 689 | 
            +
                        st.session_state.last_query = edited_input  # Store the last query for zip naming
         | 
| 690 | 
            +
                        if run_option == "Arxiv":
         | 
| 691 | 
            +
                            perform_ai_lookup(edited_input, vocal_summary=True, extended_refs=False, 
         | 
| 692 | 
            +
                                              titles_summary=True, full_audio=full_audio)
         | 
| 693 | 
            +
                        else:
         | 
| 694 | 
            +
                            if run_option == "GPT-4o":
         | 
| 695 | 
            +
                                process_with_gpt(edited_input)
         | 
| 696 | 
            +
                            elif run_option == "Claude-3.5":
         | 
| 697 | 
            +
                                process_with_claude(edited_input)
         | 
| 698 | 
            +
                    else:
         | 
| 699 | 
            +
                        if st.button("▶ Run"):
         | 
| 700 | 
            +
                            st.session_state.old_val = val
         | 
| 701 | 
            +
                            st.session_state.last_query = edited_input  # Store the last query for zip naming
         | 
| 702 | 
            +
                            if run_option == "Arxiv":
         | 
| 703 | 
            +
                                perform_ai_lookup(edited_input, vocal_summary=True, extended_refs=False, 
         | 
| 704 | 
            +
                                                  titles_summary=True, full_audio=full_audio)
         | 
| 705 | 
            +
                            else:
         | 
| 706 | 
            +
                                if run_option == "GPT-4o":
         | 
| 707 | 
            +
                                    process_with_gpt(edited_input)
         | 
| 708 | 
            +
                                elif run_option == "Claude-3.5":
         | 
| 709 | 
            +
                                    process_with_claude(edited_input)
         | 
| 710 | 
            +
             | 
| 711 | 
            +
                if tab_main == "🔍 ArXiv":
         | 
| 712 | 
            +
                    st.subheader("🔍 Query ArXiv")
         | 
| 713 | 
            +
                    q = st.text_input("🔍 Query:")
         | 
| 714 | 
            +
             | 
| 715 | 
            +
                    st.markdown("### 🎛 Options")
         | 
| 716 | 
            +
                    vocal_summary = st.checkbox("🎙ShortAudio", value=True)
         | 
| 717 | 
            +
                    extended_refs = st.checkbox("📜LongRefs", value=False)
         | 
| 718 | 
            +
                    titles_summary = st.checkbox("🔖TitlesOnly", value=True)
         | 
| 719 | 
            +
                    full_audio = st.checkbox("📚FullAudio", value=False,
         | 
| 720 | 
            +
                                             help="Full audio of results")
         | 
| 721 | 
            +
                    full_transcript = st.checkbox("🧾FullTranscript", value=False,
         | 
| 722 | 
            +
                                                  help="Generate a full transcript file")
         | 
| 723 | 
            +
             | 
| 724 | 
            +
                    if q and st.button("🔍Run"):
         | 
| 725 | 
            +
                        st.session_state.last_query = q  # Store the last query for zip naming
         | 
| 726 | 
            +
                        result = perform_ai_lookup(q, vocal_summary=vocal_summary, extended_refs=extended_refs, 
         | 
| 727 | 
            +
                                                   titles_summary=titles_summary, full_audio=full_audio)
         | 
| 728 | 
            +
                        if full_transcript:
         | 
| 729 | 
            +
                            save_full_transcript(q, result)
         | 
| 730 | 
            +
             | 
| 731 | 
            +
                    st.markdown("### Change Prompt & Re-Run")
         | 
| 732 | 
            +
                    q_new = st.text_input("🔄 Modify Query:")
         | 
| 733 | 
            +
                    if q_new and st.button("🔄 Re-Run with Modified Query"):
         | 
| 734 | 
            +
                        st.session_state.last_query = q_new  # Update last query
         | 
| 735 | 
            +
                        result = perform_ai_lookup(q_new, vocal_summary=vocal_summary, extended_refs=extended_refs, 
         | 
| 736 | 
            +
                                                   titles_summary=titles_summary, full_audio=full_audio)
         | 
| 737 | 
            +
                        if full_transcript:
         | 
| 738 | 
            +
                            save_full_transcript(q_new, result)
         | 
| 739 | 
            +
             | 
| 740 | 
            +
                elif tab_main == "🎤 Voice":
         | 
| 741 | 
            +
                    st.subheader("🎤 Voice Input")
         | 
| 742 | 
            +
                    user_text = st.text_area("💬 Message:", height=100)
         | 
| 743 | 
            +
                    user_text = user_text.strip().replace('\n', ' ')
         | 
| 744 | 
            +
                    if st.button("📨 Send"):
         | 
| 745 | 
            +
                        process_with_gpt(user_text)
         | 
| 746 | 
            +
                    st.subheader("📜 Chat History")
         | 
| 747 | 
            +
                    t1,t2=st.tabs(["Claude History","GPT-4o History"])
         | 
| 748 | 
            +
                    with t1:
         | 
| 749 | 
            +
                        for c in st.session_state.chat_history:
         | 
| 750 | 
            +
                            st.write("**You:**", c["user"])
         | 
| 751 | 
            +
                            st.write("**Claude:**", c["claude"])
         | 
| 752 | 
            +
                    with t2:
         | 
| 753 | 
            +
                        for m in st.session_state.messages:
         | 
| 754 | 
            +
                            with st.chat_message(m["role"]):
         | 
| 755 | 
            +
                                st.markdown(m["content"])
         | 
| 756 | 
            +
             | 
| 757 | 
            +
                elif tab_main == "📸 Media":
         | 
| 758 | 
            +
                    st.header("📸 Images & 🎥 Videos")
         | 
| 759 | 
            +
                    tabs = st.tabs(["🖼 Images", "🎥 Video"])
         | 
| 760 | 
            +
                    with tabs[0]:
         | 
| 761 | 
            +
                        imgs = glob.glob("*.png")+glob.glob("*.jpg")
         | 
| 762 | 
            +
                        if imgs:
         | 
| 763 | 
            +
                            c = st.slider("Cols",1,5,3)
         | 
| 764 | 
            +
                            cols = st.columns(c)
         | 
| 765 | 
            +
                            for i,f in enumerate(imgs):
         | 
| 766 | 
            +
                                with cols[i%c]:
         | 
| 767 | 
            +
                                    st.image(Image.open(f),use_container_width=True)
         | 
| 768 | 
            +
                                    if st.button(f"👀 Analyze {os.path.basename(f)}", key=f"analyze_{f}"):
         | 
| 769 | 
            +
                                        a = process_image(f,"Describe this image.")
         | 
| 770 | 
            +
                                        st.markdown(a)
         | 
| 771 | 
            +
                        else:
         | 
| 772 | 
            +
                            st.write("No images found.")
         | 
| 773 | 
            +
                    with tabs[1]:
         | 
| 774 | 
            +
                        vids = glob.glob("*.mp4")
         | 
| 775 | 
            +
                        if vids:
         | 
| 776 | 
            +
                            for v in vids:
         | 
| 777 | 
            +
                                with st.expander(f"🎥 {os.path.basename(v)}"):
         | 
| 778 | 
            +
                                    st.video(v)
         | 
| 779 | 
            +
                                    if st.button(f"Analyze {os.path.basename(v)}", key=f"analyze_{v}"):
         | 
| 780 | 
            +
                                        a = process_video_with_gpt(v,"Describe video.")
         | 
| 781 | 
            +
                                        st.markdown(a)
         | 
| 782 | 
            +
                        else:
         | 
| 783 | 
            +
                            st.write("No videos found.")
         | 
| 784 | 
            +
             | 
| 785 | 
            +
                elif tab_main == "📝 Editor":
         | 
| 786 | 
            +
                    if getattr(st.session_state,'current_file',None):
         | 
| 787 | 
            +
                        st.subheader(f"Editing: {st.session_state.current_file}")
         | 
| 788 | 
            +
                        new_text = st.text_area("✏️ Content:", st.session_state.file_content, height=300)
         | 
| 789 | 
            +
                        if st.button("💾 Save"):
         | 
| 790 | 
            +
                            with open(st.session_state.current_file,'w',encoding='utf-8') as f:
         | 
| 791 | 
            +
                                f.write(new_text)
         | 
| 792 | 
            +
                            st.success("Updated!")
         | 
| 793 | 
            +
                            st.session_state.should_rerun = True
         | 
| 794 | 
            +
                    else:
         | 
| 795 | 
            +
                        st.write("Select a file from the sidebar to edit.")
         | 
| 796 | 
            +
             | 
| 797 | 
            +
                # Load and display files in the sidebar
         | 
| 798 | 
            +
                groups_sorted = load_files_for_sidebar()
         | 
| 799 | 
            +
                display_file_manager_sidebar(groups_sorted)
         | 
| 800 | 
            +
             | 
| 801 | 
            +
                if st.session_state.viewing_prefix and any(st.session_state.viewing_prefix == group for group, _ in groups_sorted):
         | 
| 802 | 
            +
                    st.write("---")
         | 
| 803 | 
            +
                    st.write(f"**Viewing Group:** {st.session_state.viewing_prefix}")
         | 
| 804 | 
            +
                    for group_name, files in groups_sorted:
         | 
| 805 | 
            +
                        if group_name == st.session_state.viewing_prefix:
         | 
| 806 | 
            +
                            for f in files:
         | 
| 807 | 
            +
                                fname = os.path.basename(f)
         | 
| 808 | 
            +
                                ext = os.path.splitext(fname)[1].lower().strip('.')
         | 
| 809 | 
            +
                                st.write(f"### {fname}")
         | 
| 810 | 
            +
                                if ext == "md":
         | 
| 811 | 
            +
                                    content = open(f,'r',encoding='utf-8').read()
         | 
| 812 | 
            +
                                    st.markdown(content)
         | 
| 813 | 
            +
                                elif ext == "mp3":
         | 
| 814 | 
            +
                                    st.audio(f)
         | 
| 815 | 
            +
                                elif ext == "wav":
         | 
| 816 | 
            +
                                    st.audio(f)  # 🆕 Handle WAV files
         | 
| 817 | 
            +
                                else:
         | 
| 818 | 
            +
                                    st.markdown(get_download_link(f), unsafe_allow_html=True)
         | 
| 819 | 
            +
                            break
         | 
| 820 | 
            +
                    if st.button("❌ Close"):
         | 
| 821 | 
            +
                        st.session_state.viewing_prefix = None
         | 
| 822 | 
            +
             | 
| 823 | 
            +
                markdownPapers = """
         | 
| 824 | 
            +
                
         | 
| 825 | 
            +
                # Levels of AGI
         | 
| 826 | 
            +
             | 
| 827 | 
            +
            ## 1. Performance (rows) x Generality (columns)
         | 
| 828 | 
            +
            - **Narrow**  
         | 
| 829 | 
            +
              - *clearly scoped or set of tasks*  
         | 
| 830 | 
            +
            - **General**  
         | 
| 831 | 
            +
              - *wide range of non-physical tasks, including metacognitive abilities like learning new skills*  
         | 
| 832 | 
            +
             | 
| 833 | 
            +
            ## 2. Levels of AGI
         | 
| 834 | 
            +
             | 
| 835 | 
            +
            ### 2.1 Level 0: No AI
         | 
| 836 | 
            +
            - **Narrow Non-AI**  
         | 
| 837 | 
            +
              - Calculator software; compiler  
         | 
| 838 | 
            +
            - **General Non-AI**  
         | 
| 839 | 
            +
              - Human-in-the-loop computing, e.g., Amazon Mechanical Turk  
         | 
| 840 | 
            +
             | 
| 841 | 
            +
            ### 2.2 Level 1: Emerging  
         | 
| 842 | 
            +
            *equal to or somewhat better than an unskilled human*  
         | 
| 843 | 
            +
            - **Emerging Narrow AI**  
         | 
| 844 | 
            +
              - GOFAI; simple rule-based systems  
         | 
| 845 | 
            +
              - Example: SHRDLU  
         | 
| 846 | 
            +
                - *Reference:* Winograd, T. (1971). **Procedures as a Representation for Data in a Computer Program for Understanding Natural Language**. MIT AI Technical Report. [Link](https://dspace.mit.edu/handle/1721.1/7095)  
         | 
| 847 | 
            +
            - **Emerging AGI**  
         | 
| 848 | 
            +
              - ChatGPT (OpenAI, 2023)  
         | 
| 849 | 
            +
              - Bard (Anil et al., 2023)  
         | 
| 850 | 
            +
                - *Reference:* Anil, R., et al. (2023). **Bard: Google’s AI Chatbot**. [arXiv](https://arxiv.org/abs/2303.12712)  
         | 
| 851 | 
            +
              - LLaMA 2 (Touvron et al., 2023)  
         | 
| 852 | 
            +
                - *Reference:* Touvron, H., et al. (2023). **LLaMA 2: Open and Efficient Foundation Language Models**. [arXiv](https://arxiv.org/abs/2307.09288)  
         | 
| 853 | 
            +
             | 
| 854 | 
            +
            ### 2.3 Level 2: Competent  
         | 
| 855 | 
            +
            *at least 50th percentile of skilled adults*  
         | 
| 856 | 
            +
            - **Competent Narrow AI**  
         | 
| 857 | 
            +
              - Toxicity detectors such as Jigsaw  
         | 
| 858 | 
            +
                - *Reference:* Das, S., et al. (2022). **Toxicity Detection at Scale with Jigsaw**. [arXiv](https://arxiv.org/abs/2204.06905)  
         | 
| 859 | 
            +
              - Smart Speakers (Apple, Amazon, Google)  
         | 
| 860 | 
            +
              - VQA systems (PaLI)  
         | 
| 861 | 
            +
                - *Reference:* Chen, T., et al. (2023). **PaLI: Pathways Language and Image model**. [arXiv](https://arxiv.org/abs/2301.01298)  
         | 
| 862 | 
            +
              - Watson (IBM)  
         | 
| 863 | 
            +
              - SOTA LLMs for subsets of tasks  
         | 
| 864 | 
            +
            - **Competent AGI**  
         | 
| 865 | 
            +
              - Not yet achieved  
         | 
| 866 | 
            +
             | 
| 867 | 
            +
            ### 2.4 Level 3: Expert  
         | 
| 868 | 
            +
            *at least 90th percentile of skilled adults*  
         | 
| 869 | 
            +
            - **Expert Narrow AI**  
         | 
| 870 | 
            +
              - Spelling & grammar checkers (Grammarly, 2023)  
         | 
| 871 | 
            +
              - Generative image models  
         | 
| 872 | 
            +
                - Example: Imagen  
         | 
| 873 | 
            +
                  - *Reference:* Saharia, C., et al. (2022). **Imagen: Photorealistic Text-to-Image Diffusion Models**. [arXiv](https://arxiv.org/abs/2205.11487)  
         | 
| 874 | 
            +
                - Example: DALL·E 2  
         | 
| 875 | 
            +
                  - *Reference:* Ramesh, A., et al. (2022). **Hierarchical Text-Conditional Image Generation with CLIP Latents**. [arXiv](https://arxiv.org/abs/2204.06125)  
         | 
| 876 | 
            +
            - **Expert AGI**  
         | 
| 877 | 
            +
              - Not yet achieved  
         | 
| 878 | 
            +
             | 
| 879 | 
            +
            ### 2.5 Level 4: Virtuoso  
         | 
| 880 | 
            +
            *at least 99th percentile of skilled adults*  
         | 
| 881 | 
            +
            - **Virtuoso Narrow AI**  
         | 
| 882 | 
            +
              - Deep Blue  
         | 
| 883 | 
            +
                - *Reference:* Campbell, M., et al. (2002). **Deep Blue**. IBM Journal of Research and Development. [Link](https://research.ibm.com/publications/deep-blue)  
         | 
| 884 | 
            +
              - AlphaGo  
         | 
| 885 | 
            +
                - *Reference:* Silver, D., et al. (2016, 2017). **Mastering the Game of Go with Deep Neural Networks and Tree Search**. [Nature](https://www.nature.com/articles/nature16961)  
         | 
| 886 | 
            +
            - **Virtuoso AGI**  
         | 
| 887 | 
            +
              - Not yet achieved  
         | 
| 888 | 
            +
             | 
| 889 | 
            +
            ### 2.6 Level 5: Superhuman  
         | 
| 890 | 
            +
            *outperforms 100% of humans*  
         | 
| 891 | 
            +
            - **Superhuman Narrow AI**  
         | 
| 892 | 
            +
              - AlphaFold  
         | 
| 893 | 
            +
                - *Reference:* Jumper, J., et al. (2021). **Highly Accurate Protein Structure Prediction with AlphaFold**. [Nature](https://www.nature.com/articles/s41586-021-03819-2)  
         | 
| 894 | 
            +
              - AlphaZero  
         | 
| 895 | 
            +
                - *Reference:* Silver, D., et al. (2018). **A General Reinforcement Learning Algorithm that Masters Chess, Shogi, and Go through Self-Play**. [Science](https://www.science.org/doi/10.1126/science.aar6404)  
         | 
| 896 | 
            +
              - StockFish  
         | 
| 897 | 
            +
                - *Reference:* Stockfish (2023). **Stockfish Chess Engine**. [Website](https://stockfishchess.org)  
         | 
| 898 | 
            +
            - **Artificial Superintelligence (ASI)**  
         | 
| 899 | 
            +
              - Not yet achieved  
         | 
| 900 | 
            +
             | 
| 901 | 
            +
             | 
| 902 | 
            +
            # 🧬 Innovative Architecture of AlphaFold2: A Hybrid System
         | 
| 903 | 
            +
             | 
| 904 | 
            +
            ## 1. 🔢 Input Sequence  
         | 
| 905 | 
            +
            - The process starts with an **input sequence** (protein sequence).  
         | 
| 906 | 
            +
             | 
| 907 | 
            +
            ## 2. 🗄️ Database Searches  
         | 
| 908 | 
            +
            - **Genetic database search** 🔍  
         | 
| 909 | 
            +
              - Searches genetic databases to retrieve related sequences.  
         | 
| 910 | 
            +
            - **Structure database search** 🔍  
         | 
| 911 | 
            +
              - Searches structural databases for template structures.  
         | 
| 912 | 
            +
            - **Pairing** 🤝  
         | 
| 913 | 
            +
              - Aligns sequences and structures for further analysis.  
         | 
| 914 | 
            +
             | 
| 915 | 
            +
            ## 3. 🧩 MSA (Multiple Sequence Alignment)  
         | 
| 916 | 
            +
            - **MSA representation** 📊 (r,c)  
         | 
| 917 | 
            +
              - Representation of multiple aligned sequences used as input.  
         | 
| 918 | 
            +
             | 
| 919 | 
            +
            ## 4. 📑 Templates  
         | 
| 920 | 
            +
            - Template structures are paired to assist the model.  
         | 
| 921 | 
            +
             | 
| 922 | 
            +
            ## 5. 🔄 Evoformer (48 blocks)  
         | 
| 923 | 
            +
            - A **deep learning module** that refines representations:  
         | 
| 924 | 
            +
              - **MSA representation** 🧱  
         | 
| 925 | 
            +
              - **Pair representation** 🧱 (r,c)  
         | 
| 926 | 
            +
             | 
| 927 | 
            +
            ## 6. 🧱 Structure Module (8 blocks)  
         | 
| 928 | 
            +
            - Converts the representations into:  
         | 
| 929 | 
            +
              - **Single representation** (r,c)  
         | 
| 930 | 
            +
              - **Pair representation** (r,c)  
         | 
| 931 | 
            +
             | 
| 932 | 
            +
            ## 7. 🧬 3D Structure Prediction  
         | 
| 933 | 
            +
            - The structure module predicts the **3D protein structure**.  
         | 
| 934 | 
            +
            - **Confidence levels**:  
         | 
| 935 | 
            +
              - 🔵 *High confidence*  
         | 
| 936 | 
            +
              - 🟠 *Low confidence*  
         | 
| 937 | 
            +
             | 
| 938 | 
            +
            ## 8. ♻️ Recycling (Three Times)  
         | 
| 939 | 
            +
            - The model **recycles** its output up to three times to refine the prediction.  
         | 
| 940 | 
            +
             | 
| 941 | 
            +
            ## 9. 📚 Reference  
         | 
| 942 | 
            +
            **Jumper, J., et al. (2021).** Highly Accurate Protein Structure Prediction with AlphaFold. *Nature.*  
         | 
| 943 | 
            +
            🔗 [Nature Publication Link](https://www.nature.com/articles/s41586-021-03819-2)  
         | 
| 944 | 
            +
             | 
| 945 | 
            +
                """
         | 
| 946 | 
            +
                st.sidebar.markdown(markdownPapers)
         | 
| 947 | 
            +
                
         | 
| 948 | 
            +
                if st.session_state.should_rerun:
         | 
| 949 | 
            +
                    st.session_state.should_rerun = False
         | 
| 950 | 
            +
                    st.rerun()
         | 
| 951 | 
            +
             | 
| 952 | 
            +
            if __name__=="__main__":
         | 
| 953 | 
            +
                main()
         | 
