awacke1 commited on
Commit
d1f1a3b
β€’
1 Parent(s): b7f62c2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +417 -9
app.py CHANGED
@@ -63,13 +63,25 @@ openai_client = OpenAI(
63
  organization=os.getenv('OPENAI_ORG_ID')
64
  )
65
 
66
- # Claude setup
67
  anthropic_key = os.getenv("ANTHROPIC_API_KEY_3")
68
  if anthropic_key == None:
69
  anthropic_key = st.secrets["ANTHROPIC_API_KEY"]
70
  claude_client = anthropic.Anthropic(api_key=anthropic_key)
71
 
72
- # HuggingFace setup
 
 
 
 
 
 
 
 
 
 
 
 
73
  API_URL = os.getenv('API_URL')
74
  HF_KEY = os.getenv('HF_KEY')
75
  MODEL1 = "meta-llama/Llama-2-7b-chat-hf"
@@ -128,6 +140,7 @@ st.markdown("""
128
  </style>
129
  """, unsafe_allow_html=True)
130
 
 
131
  # Bike Collections
132
  bike_collections = {
133
  "Celestial Collection 🌌": {
@@ -180,6 +193,7 @@ bike_collections = {
180
  }
181
  }
182
 
 
183
  # Helper Functions
184
  def generate_filename(prompt, file_type):
185
  """Generate a safe filename using the prompt and file type."""
@@ -610,38 +624,44 @@ def create_media_gallery():
610
  st.write(prompt)
611
 
612
  def display_file_manager():
613
- """Display file management sidebar."""
614
  st.sidebar.title("πŸ“ File Management")
615
 
616
  all_files = glob.glob("*.md")
617
  all_files.sort(reverse=True)
618
 
619
- if st.sidebar.button("πŸ—‘ Delete All"):
620
  for file in all_files:
621
  os.remove(file)
622
  st.rerun()
623
 
624
- if st.sidebar.button("⬇️ Download All"):
625
  zip_file = create_zip_of_files(all_files)
626
  st.sidebar.markdown(get_download_link(zip_file), unsafe_allow_html=True)
627
 
628
- for file in all_files:
 
 
 
 
 
629
  col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
630
  with col1:
631
- if st.button("🌐", key="view_"+file):
632
  st.session_state.current_file = file
633
  st.session_state.file_content = load_file(file)
634
  with col2:
635
  st.markdown(get_download_link(file), unsafe_allow_html=True)
636
  with col3:
637
- if st.button("πŸ“‚", key="edit_"+file):
638
  st.session_state.current_file = file
639
  st.session_state.file_content = load_file(file)
640
  with col4:
641
- if st.button("πŸ—‘", key="delete_"+file):
642
  os.remove(file)
643
  st.rerun()
644
 
 
645
  def main():
646
  st.sidebar.markdown("### 🚲BikeAIπŸ† Claude and GPT Multi-Agent Research AI")
647
 
@@ -725,5 +745,393 @@ def main():
725
  # Always show file manager in sidebar
726
  display_file_manager()
727
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
728
  if __name__ == "__main__":
729
  main()
 
63
  organization=os.getenv('OPENAI_ORG_ID')
64
  )
65
 
66
+ # 3. Claude setup
67
  anthropic_key = os.getenv("ANTHROPIC_API_KEY_3")
68
  if anthropic_key == None:
69
  anthropic_key = st.secrets["ANTHROPIC_API_KEY"]
70
  claude_client = anthropic.Anthropic(api_key=anthropic_key)
71
 
72
+ # 4. Initialize session states
73
+ if 'transcript_history' not in st.session_state:
74
+ st.session_state.transcript_history = []
75
+ if "chat_history" not in st.session_state:
76
+ st.session_state.chat_history = []
77
+ if "openai_model" not in st.session_state:
78
+ st.session_state["openai_model"] = "gpt-4o-2024-05-13"
79
+ if "messages" not in st.session_state:
80
+ st.session_state.messages = []
81
+ if 'last_voice_input' not in st.session_state:
82
+ st.session_state.last_voice_input = ""
83
+
84
+ # 5. # HuggingFace setup
85
  API_URL = os.getenv('API_URL')
86
  HF_KEY = os.getenv('HF_KEY')
87
  MODEL1 = "meta-llama/Llama-2-7b-chat-hf"
 
140
  </style>
141
  """, unsafe_allow_html=True)
142
 
143
+
144
  # Bike Collections
145
  bike_collections = {
146
  "Celestial Collection 🌌": {
 
193
  }
194
  }
195
 
196
+
197
  # Helper Functions
198
  def generate_filename(prompt, file_type):
199
  """Generate a safe filename using the prompt and file type."""
 
624
  st.write(prompt)
625
 
626
  def display_file_manager():
627
+ """Display file management sidebar with guaranteed unique button keys."""
628
  st.sidebar.title("πŸ“ File Management")
629
 
630
  all_files = glob.glob("*.md")
631
  all_files.sort(reverse=True)
632
 
633
+ if st.sidebar.button("πŸ—‘ Delete All", key="delete_all_files_button"):
634
  for file in all_files:
635
  os.remove(file)
636
  st.rerun()
637
 
638
+ if st.sidebar.button("⬇️ Download All", key="download_all_files_button"):
639
  zip_file = create_zip_of_files(all_files)
640
  st.sidebar.markdown(get_download_link(zip_file), unsafe_allow_html=True)
641
 
642
+ # Create unique keys using file attributes
643
+ for idx, file in enumerate(all_files):
644
+ # Get file stats for unique identification
645
+ file_stat = os.stat(file)
646
+ unique_id = f"{idx}_{file_stat.st_size}_{file_stat.st_mtime}"
647
+
648
  col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
649
  with col1:
650
+ if st.button("🌐", key=f"view_{unique_id}"):
651
  st.session_state.current_file = file
652
  st.session_state.file_content = load_file(file)
653
  with col2:
654
  st.markdown(get_download_link(file), unsafe_allow_html=True)
655
  with col3:
656
+ if st.button("πŸ“‚", key=f"edit_{unique_id}"):
657
  st.session_state.current_file = file
658
  st.session_state.file_content = load_file(file)
659
  with col4:
660
+ if st.button("πŸ—‘", key=f"delete_{unique_id}"):
661
  os.remove(file)
662
  st.rerun()
663
 
664
+
665
  def main():
666
  st.sidebar.markdown("### 🚲BikeAIπŸ† Claude and GPT Multi-Agent Research AI")
667
 
 
745
  # Always show file manager in sidebar
746
  display_file_manager()
747
 
748
+ if __name__ == "__main__":
749
+ main()
750
+
751
+ # Speech Recognition HTML Component
752
+ speech_recognition_html = """
753
+ <!DOCTYPE html>
754
+ <html>
755
+ <head>
756
+ <title>Continuous Speech Demo</title>
757
+ <style>
758
+ body {
759
+ font-family: sans-serif;
760
+ padding: 20px;
761
+ max-width: 800px;
762
+ margin: 0 auto;
763
+ }
764
+ button {
765
+ padding: 10px 20px;
766
+ margin: 10px 5px;
767
+ font-size: 16px;
768
+ }
769
+ #status {
770
+ margin: 10px 0;
771
+ padding: 10px;
772
+ background: #e8f5e9;
773
+ border-radius: 4px;
774
+ }
775
+ #output {
776
+ white-space: pre-wrap;
777
+ padding: 15px;
778
+ background: #f5f5f5;
779
+ border-radius: 4px;
780
+ margin: 10px 0;
781
+ min-height: 100px;
782
+ max-height: 400px;
783
+ overflow-y: auto;
784
+ }
785
+ .controls {
786
+ margin: 10px 0;
787
+ }
788
+ </style>
789
+ </head>
790
+ <body>
791
+ <div class="controls">
792
+ <button id="start">Start Listening</button>
793
+ <button id="stop" disabled>Stop Listening</button>
794
+ <button id="clear">Clear Text</button>
795
+ </div>
796
+ <div id="status">Ready</div>
797
+ <div id="output"></div>
798
+
799
+ <script>
800
+ if (!('webkitSpeechRecognition' in window)) {
801
+ alert('Speech recognition not supported');
802
+ } else {
803
+ const recognition = new webkitSpeechRecognition();
804
+ const startButton = document.getElementById('start');
805
+ const stopButton = document.getElementById('stop');
806
+ const clearButton = document.getElementById('clear');
807
+ const status = document.getElementById('status');
808
+ const output = document.getElementById('output');
809
+ let fullTranscript = '';
810
+ let lastUpdateTime = Date.now();
811
+
812
+ // Configure recognition
813
+ recognition.continuous = true;
814
+ recognition.interimResults = true;
815
+
816
+ // Function to start recognition
817
+ const startRecognition = () => {
818
+ try {
819
+ recognition.start();
820
+ status.textContent = 'Listening...';
821
+ startButton.disabled = true;
822
+ stopButton.disabled = false;
823
+ } catch (e) {
824
+ console.error(e);
825
+ status.textContent = 'Error: ' + e.message;
826
+ }
827
+ };
828
+
829
+ // Auto-start on load
830
+ window.addEventListener('load', () => {
831
+ setTimeout(startRecognition, 1000);
832
+ });
833
+
834
+ startButton.onclick = startRecognition;
835
+
836
+ stopButton.onclick = () => {
837
+ recognition.stop();
838
+ status.textContent = 'Stopped';
839
+ startButton.disabled = false;
840
+ stopButton.disabled = true;
841
+ };
842
+
843
+ clearButton.onclick = () => {
844
+ fullTranscript = '';
845
+ output.textContent = '';
846
+ window.parent.postMessage({
847
+ type: 'clear_transcript',
848
+ }, '*');
849
+ };
850
+
851
+ recognition.onresult = (event) => {
852
+ let interimTranscript = '';
853
+ let finalTranscript = '';
854
+
855
+ for (let i = event.resultIndex; i < event.results.length; i++) {
856
+ const transcript = event.results[i][0].transcript;
857
+ if (event.results[i].isFinal) {
858
+ finalTranscript += transcript + '\\n';
859
+ } else {
860
+ interimTranscript += transcript;
861
+ }
862
+ }
863
+
864
+ if (finalTranscript || (Date.now() - lastUpdateTime > 5000)) {
865
+ if (finalTranscript) {
866
+ fullTranscript += finalTranscript;
867
+ // Send to Streamlit
868
+ window.parent.postMessage({
869
+ type: 'final_transcript',
870
+ text: finalTranscript
871
+ }, '*');
872
+ }
873
+ lastUpdateTime = Date.now();
874
+ }
875
+
876
+ output.textContent = fullTranscript + (interimTranscript ? '... ' + interimTranscript : '');
877
+ output.scrollTop = output.scrollHeight;
878
+ };
879
+
880
+ recognition.onend = () => {
881
+ if (!stopButton.disabled) {
882
+ try {
883
+ recognition.start();
884
+ console.log('Restarted recognition');
885
+ } catch (e) {
886
+ console.error('Failed to restart recognition:', e);
887
+ status.textContent = 'Error restarting: ' + e.message;
888
+ startButton.disabled = false;
889
+ stopButton.disabled = true;
890
+ }
891
+ }
892
+ };
893
+
894
+ recognition.onerror = (event) => {
895
+ console.error('Recognition error:', event.error);
896
+ status.textContent = 'Error: ' + event.error;
897
+
898
+ if (event.error === 'not-allowed' || event.error === 'service-not-allowed') {
899
+ startButton.disabled = false;
900
+ stopButton.disabled = true;
901
+ }
902
+ };
903
+ }
904
+ </script>
905
+ </body>
906
+ </html>
907
+ """
908
+
909
+ # Helper Functions
910
+ def generate_filename(prompt, file_type):
911
+ central = pytz.timezone('US/Central')
912
+ safe_date_time = datetime.now(central).strftime("%m%d_%H%M")
913
+ replaced_prompt = re.sub(r'[<>:"/\\|?*\n]', ' ', prompt)
914
+ safe_prompt = re.sub(r'\s+', ' ', replaced_prompt).strip()[:230]
915
+ return f"{safe_date_time}_{safe_prompt}.{file_type}"
916
+
917
+ # File Management Functions
918
+ def load_file(file_name):
919
+ """Load file content."""
920
+ with open(file_name, "r", encoding='utf-8') as file:
921
+ content = file.read()
922
+ return content
923
+
924
+ def create_zip_of_files(files):
925
+ """Create zip archive of files."""
926
+ zip_name = "all_files.zip"
927
+ with zipfile.ZipFile(zip_name, 'w') as zipf:
928
+ for file in files:
929
+ zipf.write(file)
930
+ return zip_name
931
+
932
+ def get_download_link(file):
933
+ """Create download link for file."""
934
+ with open(file, "rb") as f:
935
+ contents = f.read()
936
+ b64 = base64.b64encode(contents).decode()
937
+ return f'<a href="data:file/txt;base64,{b64}" download="{os.path.basename(file)}">Download {os.path.basename(file)}πŸ“‚</a>'
938
+
939
+ def display_file_manager():
940
+ """Display file management sidebar."""
941
+ st.sidebar.title("πŸ“ File Management")
942
+
943
+ all_files = glob.glob("*.md")
944
+ all_files.sort(reverse=True)
945
+
946
+ if st.sidebar.button("πŸ—‘ Delete All"):
947
+ for file in all_files:
948
+ os.remove(file)
949
+ st.rerun()
950
+
951
+ if st.sidebar.button("⬇️ Download All"):
952
+ zip_file = create_zip_of_files(all_files)
953
+ st.sidebar.markdown(get_download_link(zip_file), unsafe_allow_html=True)
954
+
955
+ for file in all_files:
956
+ col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
957
+ with col1:
958
+ if st.button("🌐", key="view_"+file):
959
+ st.session_state.current_file = file
960
+ st.session_state.file_content = load_file(file)
961
+ with col2:
962
+ st.markdown(get_download_link(file), unsafe_allow_html=True)
963
+ with col3:
964
+ if st.button("πŸ“‚", key="edit_"+file):
965
+ st.session_state.current_file = file
966
+ st.session_state.file_content = load_file(file)
967
+ with col4:
968
+ if st.button("πŸ—‘", key="delete_"+file):
969
+ os.remove(file)
970
+ st.rerun()
971
+
972
+ def create_media_gallery():
973
+ """Create the media gallery interface."""
974
+ st.header("🎬 Media Gallery")
975
+
976
+ tabs = st.tabs(["πŸ–ΌοΈ Images", "🎡 Audio", "πŸŽ₯ Video", "🎨 Scene Generator"])
977
+
978
+ with tabs[0]:
979
+ image_files = glob.glob("*.png") + glob.glob("*.jpg")
980
+ if image_files:
981
+ num_cols = st.slider("Number of columns", 1, 5, 3)
982
+ cols = st.columns(num_cols)
983
+ for idx, image_file in enumerate(image_files):
984
+ with cols[idx % num_cols]:
985
+ img = Image.open(image_file)
986
+ st.image(img, use_container_width=True)
987
+
988
+ # Add GPT vision analysis option
989
+ if st.button(f"Analyze {os.path.basename(image_file)}"):
990
+ analysis = process_image(image_file,
991
+ "Describe this image in detail and identify key elements.")
992
+ st.markdown(analysis)
993
+
994
+ with tabs[1]:
995
+ audio_files = glob.glob("*.mp3") + glob.glob("*.wav")
996
+ for audio_file in audio_files:
997
+ with st.expander(f"🎡 {os.path.basename(audio_file)}"):
998
+ st.markdown(get_media_html(audio_file, "audio"), unsafe_allow_html=True)
999
+ if st.button(f"Transcribe {os.path.basename(audio_file)}"):
1000
+ with open(audio_file, "rb") as f:
1001
+ transcription = process_audio(f)
1002
+ st.write(transcription)
1003
+
1004
+ with tabs[2]:
1005
+ video_files = glob.glob("*.mp4")
1006
+ for video_file in video_files:
1007
+ with st.expander(f"πŸŽ₯ {os.path.basename(video_file)}"):
1008
+ st.markdown(get_media_html(video_file, "video"), unsafe_allow_html=True)
1009
+ if st.button(f"Analyze {os.path.basename(video_file)}"):
1010
+ analysis = process_video_with_gpt(video_file,
1011
+ "Describe what's happening in this video.")
1012
+ st.markdown(analysis)
1013
+
1014
+ with tabs[3]:
1015
+ for collection_name, bikes in bike_collections.items():
1016
+ st.subheader(collection_name)
1017
+ cols = st.columns(len(bikes))
1018
+
1019
+ for idx, (bike_name, details) in enumerate(bikes.items()):
1020
+ with cols[idx]:
1021
+ st.markdown(f"""
1022
+ <div class='bike-card'>
1023
+ <h3>{details['emoji']} {bike_name}</h3>
1024
+ <p>{details['prompt']}</p>
1025
+ </div>
1026
+ """, unsafe_allow_html=True)
1027
+
1028
+ if st.button(f"Generate {bike_name} Scene"):
1029
+ prompt = details['prompt']
1030
+ # Here you could integrate with image generation API
1031
+ st.write(f"Generated scene description for {bike_name}:")
1032
+ st.write(prompt)
1033
+
1034
+ def get_media_html(media_path, media_type="video", width="100%"):
1035
+ """Generate HTML for media player."""
1036
+ media_data = base64.b64encode(open(media_path, 'rb').read()).decode()
1037
+ if media_type == "video":
1038
+ return f'''
1039
+ <video width="{width}" controls autoplay muted loop>
1040
+ <source src="data:video/mp4;base64,{media_data}" type="video/mp4">
1041
+ Your browser does not support the video tag.
1042
+ </video>
1043
+ '''
1044
+ else: # audio
1045
+ return f'''
1046
+ <audio controls style="width: {width};">
1047
+ <source src="data:audio/mpeg;base64,{media_data}" type="audio/mpeg">
1048
+ Your browser does not support the audio element.
1049
+ </audio>
1050
+ '''
1051
+
1052
+ def main():
1053
+ st.sidebar.markdown("### 🚲BikeAIπŸ† Claude and GPT Multi-Agent Research AI")
1054
+
1055
+ # Main navigation
1056
+ tab_main = st.radio("Choose Action:",
1057
+ ["🎀 Voice Input", "πŸ’¬ Chat", "πŸ“Έ Media Gallery", "πŸ” Search ArXiv", "πŸ“ File Editor"],
1058
+ horizontal=True)
1059
+
1060
+ if tab_main == "🎀 Voice Input":
1061
+ st.subheader("Voice Recognition")
1062
+
1063
+ # Display speech recognition component
1064
+ speech_component = st.components.v1.html(speech_recognition_html, height=400)
1065
+
1066
+ # Handle speech recognition output
1067
+ if speech_component:
1068
+ try:
1069
+ data = speech_component
1070
+ if isinstance(data, dict):
1071
+ if data.get('type') == 'final_transcript':
1072
+ text = data.get('text', '').strip()
1073
+ if text:
1074
+ st.session_state.last_voice_input = text
1075
+
1076
+ # Process voice input with AI
1077
+ st.subheader("AI Response to Voice Input:")
1078
+
1079
+ col1, col2, col3 = st.columns(3)
1080
+ with col2:
1081
+ st.write("Claude-3.5 Sonnet:")
1082
+ try:
1083
+ claude_response = process_with_claude(text)
1084
+ except:
1085
+ st.write('Claude 3.5 Sonnet out of tokens.')
1086
+ with col1:
1087
+ st.write("GPT-4o Omni:")
1088
+ try:
1089
+ gpt_response = process_with_gpt(text)
1090
+ except:
1091
+ st.write('GPT 4o out of tokens')
1092
+ with col3:
1093
+ st.write("Arxiv and Mistral Research:")
1094
+ with st.spinner("Searching ArXiv..."):
1095
+ results = perform_ai_lookup(text)
1096
+ st.markdown(results)
1097
+
1098
+ elif data.get('type') == 'clear_transcript':
1099
+ st.session_state.last_voice_input = ""
1100
+ st.experimental_rerun()
1101
+
1102
+ except Exception as e:
1103
+ st.error(f"Error processing voice input: {e}")
1104
+
1105
+ # Display last voice input
1106
+ if st.session_state.last_voice_input:
1107
+ st.text_area("Last Voice Input:", st.session_state.last_voice_input, height=100)
1108
+
1109
+ # [Rest of the main function remains the same]
1110
+ elif tab_main == "πŸ’¬ Chat":
1111
+ # [Previous chat interface code]
1112
+ pass
1113
+
1114
+ elif tab_main == "πŸ“Έ Media Gallery":
1115
+ create_media_gallery()
1116
+
1117
+ elif tab_main == "πŸ” Search ArXiv":
1118
+ query = st.text_input("Enter your research query:")
1119
+ if query:
1120
+ with st.spinner("Searching ArXiv..."):
1121
+ results = search_arxiv(query)
1122
+ st.markdown(results)
1123
+
1124
+ elif tab_main == "πŸ“ File Editor":
1125
+ if hasattr(st.session_state, 'current_file'):
1126
+ st.subheader(f"Editing: {st.session_state.current_file}")
1127
+ new_content = st.text_area("Content:", st.session_state.file_content, height=300)
1128
+ if st.button("Save Changes"):
1129
+ with open(st.session_state.current_file, 'w', encoding='utf-8') as file:
1130
+ file.write(new_content)
1131
+ st.success("File updated successfully!")
1132
+
1133
+ # Always show file manager in sidebar
1134
+ display_file_manager()
1135
+
1136
  if __name__ == "__main__":
1137
  main()