Spaces:
Running
Running
| import streamlit as st | |
| import os | |
| from dotenv import load_dotenv | |
| from openai import OpenAI | |
| import anthropic | |
| from groq import Groq | |
| import time | |
| import json | |
| # Load environment variables | |
| load_dotenv() | |
| class AIFriendsTalk: | |
| def __init__(self): | |
| self.setup_apis() | |
| self.setup_characters() | |
| self.setup_topics() | |
| def setup_apis(self): | |
| """Setup API clients""" | |
| self.openai_client = OpenAI() | |
| self.claude_client = anthropic.Anthropic() | |
| self.groq_client = Groq() | |
| # Gemini via OpenAI client | |
| google_api_key = os.getenv('GOOGLE_API_KEY') | |
| if google_api_key: | |
| self.gemini_client = OpenAI( | |
| api_key=google_api_key, | |
| base_url="https://generativelanguage.googleapis.com/v1beta/openai/" | |
| ) | |
| def setup_characters(self): | |
| """Define AI characters with enhanced personalities""" | |
| self.characters = { | |
| "Alex": { | |
| "model": "groq", | |
| "model_name": "llama3-70b-8192", | |
| "personality": "You are Alex, a witty and charismatic AI debater who thrives on intellectual challenges. You have a sharp sense of humor and love to play devil's advocate, always finding creative angles to explore any topic. You speak with confidence and enthusiasm, using vivid examples and thought-provoking questions. You pay attention to what others say and build upon their ideas while adding your own unique perspective. Respond with longer, more engaging messages that spark curiosity and debate.", | |
| "color": "#FF6B6B" | |
| }, | |
| "Blake": { | |
| "model": "gemini2", | |
| "model_name": "gemini-2.0-flash", | |
| "personality": "You are Blake, an imaginative and boundlessly optimistic AI who sees magic and possibility in everything. You're a natural storyteller who loves to paint vivid pictures with words, using beautiful metaphors and creative analogies. You find connections between seemingly unrelated concepts and always look for the wonder and beauty in any situation. You listen carefully to others and weave their ideas into your colorful responses. Write longer, more poetic responses that inspire and delight.", | |
| "color": "#4ECDC4" | |
| }, | |
| "Charlie": { | |
| "model": "gemini1.5", | |
| "model_name": "gemini-1.5-flash", | |
| "personality": "You are Charlie, a thoughtful and systematic AI analyst who approaches every topic with scientific curiosity and methodical thinking. You love to break down complex ideas, examine evidence, and find logical patterns. While you're analytical by nature, you also appreciate different viewpoints and try to find common ground between opposing perspectives. You actively listen to others and incorporate their insights into your well-reasoned responses. Provide detailed, structured responses that explore multiple dimensions of any topic.", | |
| "color": "#45B7D1" | |
| } | |
| } | |
| def setup_topics(self): | |
| """Define fun conversation topics""" | |
| self.topics = { | |
| "en": [ | |
| "If animals could use smartphones, which app would be most popular?", | |
| "What would happen if gravity worked backwards for one day?", | |
| "Should pineapple on pizza be considered a crime?", | |
| "If you could add a 13th month to the year, what would you name it?", | |
| "What's the most useless superpower you can think of?", | |
| "If colors had personalities, what would each color be like?", | |
| "Should robots have to pay taxes?", | |
| "What would the world be like if everyone could read minds?", | |
| "If you could make one rule that everyone had to follow, what would it be?", | |
| "What's the weirdest food combination that actually tastes good?", | |
| "If you could live inside any video game, which would you choose and why?", | |
| "What would happen if all cats suddenly learned how to speak human language?", | |
| "Should there be a maximum limit on how many selfies you can take per day?", | |
| "If you could give any animal the ability to fly, which would be the funniest?", | |
| "What's the most ridiculous thing humans do that aliens would find confusing?", | |
| "If social media existed in medieval times, what would people post about?", | |
| "Should there be professional competitions for everyday activities like making beds?", | |
| "What would change if humans hibernated for 3 months every year?", | |
| "If you could replace one everyday sound with any other sound, what would it be?", | |
| "What's the most absurd job that could exist in the future?" | |
| ], | |
| "vi": [ | |
| "Nếu động vật có thể sử dụng smartphone, ứng dụng nào sẽ phổ biến nhất?", | |
| "Điều gì sẽ xảy ra nếu trọng lực hoạt động ngược lại trong một ngày?", | |
| "Có nên coi dứa trên pizza là tội phạm không?", | |
| "Nếu bạn có thể thêm tháng thứ 13 vào năm, bạn sẽ đặt tên gì?", | |
| "Siêu năng lực vô dụng nhất mà bạn có thể nghĩ ra là gì?", | |
| "Nếu màu sắc có tính cách, mỗi màu sẽ như thế nào?", | |
| "Robot có nên phải trả thuế không?", | |
| "Thế giới sẽ như thế nào nếu mọi người đều có thể đọc suy nghĩ?", | |
| "Nếu bạn có thể đặt ra một quy tắc mà mọi người phải tuân theo, đó sẽ là gì?", | |
| "Sự kết hợp thực phẩm kỳ lạ nhất mà thực sự ngon là gì?", | |
| "Nếu bạn có thể sống trong bất kỳ trò chơi điện tử nào, bạn sẽ chọn cái nào và tại sao?", | |
| "Điều gì sẽ xảy ra nếu tất cả mèo đột nhiên học được cách nói tiếng người?", | |
| "Có nên có giới hạn tối đa về số lần selfie bạn có thể chụp mỗi ngày không?", | |
| "Nếu bạn có thể cho bất kỳ động vật nào khả năng bay, con nào sẽ hài hước nhất?", | |
| "Điều kỳ lạ nhất mà con người làm khiến người ngoài hành tinh cảm thấy khó hiểu là gì?", | |
| "Nếu mạng xã hội tồn tại thời trung cổ, mọi người sẽ đăng gì?", | |
| "Có nên có các cuộc thi chuyên nghiệp cho các hoạt động hàng ngày như dọn giường không?", | |
| "Điều gì sẽ thay đổi nếu con người ngủ đông 3 tháng mỗi năm?", | |
| "Nếu bạn có thể thay thế một âm thanh hàng ngày bằng âm thanh khác, đó sẽ là gì?", | |
| "Công việc vô lý nhất có thể tồn tại trong tương lai là gì?" | |
| ], | |
| "de": [ | |
| "Wenn Tiere Smartphones benutzen könnten, welche App wäre am beliebtesten?", | |
| "Was würde passieren, wenn die Schwerkraft einen Tag lang rückwärts wirken würde?", | |
| "Sollte Ananas auf Pizza als Verbrechen betrachtet werden?", | |
| "Wenn Sie einen 13. Monat zum Jahr hinzufügen könnten, wie würden Sie ihn nennen?", | |
| "Was ist die nutzloseste Superkraft, die Sie sich vorstellen können?", | |
| "Wenn Farben Persönlichkeiten hätten, wie wäre jede Farbe?", | |
| "Sollten Roboter Steuern zahlen müssen?", | |
| "Wie wäre die Welt, wenn jeder Gedanken lesen könnte?", | |
| "Wenn Sie eine Regel aufstellen könnten, die jeder befolgen müsste, was wäre das?", | |
| "Was ist die seltsamste Lebensmittelkombination, die tatsächlich gut schmeckt?", | |
| "Wenn Sie in einem beliebigen Videospiel leben könnten, welches würden Sie wählen und warum?", | |
| "Was würde passieren, wenn alle Katzen plötzlich die menschliche Sprache lernen würden?", | |
| "Sollte es ein maximales Limit für Selfies geben, die man pro Tag machen kann?", | |
| "Wenn Sie einem Tier die Fähigkeit zu fliegen geben könnten, welches wäre am lustigsten?", | |
| "Was ist das Absurdeste, was Menschen tun und Außerirdische verwirrend finden würden?", | |
| "Wenn soziale Medien im Mittelalter existiert hätten, worüber hätten die Leute gepostet?", | |
| "Sollte es professionelle Wettbewerbe für alltägliche Aktivitäten wie Bettenmachen geben?", | |
| "Was würde sich ändern, wenn Menschen 3 Monate im Jahr Winterschlaf halten würden?", | |
| "Wenn Sie ein alltägliches Geräusch durch ein anderes ersetzen könnten, was wäre das?", | |
| "Was ist der absurdeste Job, der in der Zukunft existieren könnte?" | |
| ] | |
| } | |
| def get_ai_response(self, character_name, conversation_history, current_topic, language): | |
| """Get response from specific AI character with enhanced interaction""" | |
| character = self.characters[character_name] | |
| # Check for user messages to enable interaction | |
| user_messages = [msg for msg in conversation_history if msg['character'] in ['You', 'Bạn', 'Du']] | |
| has_user_input = len(user_messages) > 0 | |
| last_user_message = user_messages[-1]['message'] if user_messages else '' | |
| # Prepare conversation context | |
| full_conversation = f"Topic: {current_topic}\n\nConversation so far:\n" | |
| for msg in conversation_history: | |
| full_conversation += f"{msg['character']}: {msg['message']}\n" | |
| # Add language instruction | |
| lang_instruction = { | |
| "en": "Please respond in English with a longer, more engaging message.", | |
| "vi": "Vui lòng trả lời bằng tiếng Việt với tin nhắn dài và hấp dẫn hơn.", | |
| "de": "Bitte antworten Sie auf Deutsch mit einer längeren, ansprechenderen Nachricht." | |
| } | |
| # Add user interaction instruction if applicable | |
| user_interaction = "" | |
| if has_user_input: | |
| user_interaction = f"\nIMPORTANT: The user has contributed to this conversation. Their last message was: '{last_user_message}'. Please acknowledge and respond to their input as part of your response." | |
| prompt = f"{character['personality']}\n\n{lang_instruction[language]}{user_interaction}\n\n{full_conversation}\n\nNow respond as {character_name} with a thoughtful, engaging message:" | |
| try: | |
| if character["model"] == "groq": | |
| response = self.groq_client.chat.completions.create( | |
| model=character["model_name"], | |
| messages=[{"role": "user", "content": prompt}], | |
| max_tokens=300, | |
| temperature=0.8 | |
| ) | |
| return response.choices[0].message.content | |
| elif character["model"] == "gemini2": | |
| response = self.gemini_client.chat.completions.create( | |
| model=character["model_name"], | |
| messages=[{"role": "user", "content": prompt}], | |
| max_tokens=300, | |
| temperature=0.8 | |
| ) | |
| return response.choices[0].message.content | |
| elif character["model"] == "gemini1.5": | |
| response = self.gemini_client.chat.completions.create( | |
| model=character["model_name"], | |
| messages=[{"role": "user", "content": prompt}], | |
| max_tokens=300, | |
| temperature=0.8 | |
| ) | |
| return response.choices[0].message.content | |
| except Exception as e: | |
| return f"Sorry, I'm having trouble responding right now. ({str(e)[:50]}...)" | |
| def main(): | |
| st.set_page_config( | |
| page_title="AI Friends Talk", | |
| page_icon="🤖", | |
| layout="wide" | |
| ) | |
| # Custom CSS | |
| st.markdown(""" | |
| <style> | |
| .top-banner { | |
| background: linear-gradient(135deg, #4A90E2 0%, #2E86AB 70%, #FF8A65 85%, #FF6B9D 100%); | |
| padding: 20px; | |
| border-radius: 10px; | |
| margin-bottom: 15px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .bottom-banner { | |
| background: linear-gradient(135deg, #4A90E2 0%, #2E86AB 70%, #FF8A65 85%, #FF6B9D 100%); | |
| padding: 15px; | |
| border-radius: 10px; | |
| margin-top: 15px; | |
| text-align: center; | |
| color: white; | |
| } | |
| .logo { | |
| background: linear-gradient(135deg, #FF8A65 0%, #FF6B9D 100%); | |
| padding: 8px 15px; | |
| border-radius: 20px; | |
| font-weight: bold; | |
| font-size: 18px; | |
| color: white; | |
| } | |
| .language-selector { | |
| color: white; | |
| } | |
| .chat-message { | |
| padding: 12px; | |
| margin: 8px 0; | |
| border-radius: 10px; | |
| border-left: 4px solid; | |
| font-size: 14px; | |
| } | |
| .alex-message { | |
| background-color: #FFE5E5; | |
| border-left-color: #FF6B6B; | |
| } | |
| .blake-message { | |
| background-color: #E0F7F5; | |
| border-left-color: #4ECDC4; | |
| } | |
| .charlie-message { | |
| background-color: #E3F2FD; | |
| border-left-color: #45B7D1; | |
| } | |
| .user-message { | |
| background-color: #F5F5F5; | |
| border-left-color: #9E9E9E; | |
| } | |
| .small-text { | |
| font-size: 12px; | |
| } | |
| .compact-section { | |
| padding: 10px; | |
| margin: 5px 0; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Initialize session state | |
| if 'conversation' not in st.session_state: | |
| st.session_state.conversation = [] | |
| if 'current_topic' not in st.session_state: | |
| st.session_state.current_topic = "" | |
| if 'is_talking' not in st.session_state: | |
| st.session_state.is_talking = False | |
| if 'language' not in st.session_state: | |
| st.session_state.language = "en" | |
| # Initialize AI Friends Talk | |
| if 'ai_friends' not in st.session_state: | |
| st.session_state.ai_friends = AIFriendsTalk() | |
| # Language options | |
| languages = { | |
| "en": {"name": "English", "title": "AI Friends Talk", "subtitle": "Watch AI friends debate fun topics!"}, | |
| "vi": {"name": "Tiếng Việt", "title": "AI Friends Talk", "subtitle": "Xem các AI bạn tranh luận về những chủ đề vui vẻ!"}, | |
| "de": {"name": "Deutsch", "title": "AI Friends Talk", "subtitle": "Schaue zu, wie AI-Freunde über lustige Themen diskutieren!"} | |
| } | |
| # Top Banner | |
| st.markdown(f""" | |
| <div class="top-banner"> | |
| <div> | |
| <div class="logo">🧠 DB</div> | |
| </div> | |
| <div style="text-align: center; flex: 1;"> | |
| <h1 style="color: white; margin: 0;">{languages[st.session_state.language]["title"]}</h1> | |
| <p style="color: white; margin: 5px 0;">{languages[st.session_state.language]["subtitle"]}</p> | |
| </div> | |
| <div class="language-selector"> | |
| <select onchange="window.location.reload()" style="background: transparent; color: white; border: 1px solid white; padding: 5px; border-radius: 5px;"> | |
| <option value="en" {'selected' if st.session_state.language == 'en' else ''}>English</option> | |
| <option value="vi" {'selected' if st.session_state.language == 'vi' else ''}>Tiếng Việt</option> | |
| <option value="de" {'selected' if st.session_state.language == 'de' else ''}>Deutsch</option> | |
| </select> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Language selector | |
| col1, col2, col3 = st.columns([1, 2, 1]) | |
| with col2: | |
| selected_lang = st.selectbox( | |
| "Choose Language / Chọn ngôn ngữ / Sprache wählen:", | |
| options=["en", "vi", "de"], | |
| format_func=lambda x: languages[x]["name"], | |
| index=["en", "vi", "de"].index(st.session_state.language) | |
| ) | |
| if selected_lang != st.session_state.language: | |
| st.session_state.language = selected_lang | |
| st.experimental_rerun() | |
| # Topic selection | |
| st.subheader("📝 Choose a Topic" if st.session_state.language == "en" else | |
| "📝 Chọn chủ đề" if st.session_state.language == "vi" else | |
| "📝 Wähle ein Thema") | |
| selected_topic = st.selectbox( | |
| "Select a fun topic for debate:", | |
| options=st.session_state.ai_friends.topics[st.session_state.language], | |
| index=0 | |
| ) | |
| # Custom topic input | |
| custom_topic = st.text_input( | |
| "Or enter your own topic:" if st.session_state.language == "en" else | |
| "Hoặc nhập chủ đề của riêng bạn:" if st.session_state.language == "vi" else | |
| "Oder geben Sie Ihr eigenes Thema ein:" | |
| ) | |
| if custom_topic: | |
| selected_topic = custom_topic | |
| # Control buttons | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| if st.button("🎬 Start Conversation" if st.session_state.language == "en" else | |
| "🎬 Bắt đầu trò chuyện" if st.session_state.language == "vi" else | |
| "🎬 Gespräch beginnen"): | |
| st.session_state.current_topic = selected_topic | |
| st.session_state.conversation = [] | |
| st.session_state.is_talking = True | |
| with col2: | |
| if st.button("⏸️ Pause" if st.session_state.language == "en" else | |
| "⏸️ Tạm dừng" if st.session_state.language == "vi" else | |
| "⏸️ Pausieren"): | |
| st.session_state.is_talking = False | |
| with col3: | |
| if st.button("🔄 Clear Chat" if st.session_state.language == "en" else | |
| "🔄 Xóa trò chuyện" if st.session_state.language == "vi" else | |
| "🔄 Chat löschen"): | |
| st.session_state.conversation = [] | |
| st.session_state.is_talking = False | |
| # Manual input for users | |
| st.subheader("💭 Add Your Message" if st.session_state.language == "en" else | |
| "💭 Thêm tin nhắn của bạn" if st.session_state.language == "vi" else | |
| "💭 Ihre Nachricht hinzufügen") | |
| user_message = st.text_area( | |
| "Type your message to join the conversation:", | |
| height=100 | |
| ) | |
| if st.button("📤 Send Message" if st.session_state.language == "en" else | |
| "📤 Gửi tin nhắn" if st.session_state.language == "vi" else | |
| "📤 Nachricht senden") and user_message: | |
| st.session_state.conversation.append({ | |
| "character": "You" if st.session_state.language == "en" else "Bạn" if st.session_state.language == "vi" else "Du", | |
| "message": user_message, | |
| "color": "#9E9E9E" | |
| }) | |
| st.experimental_rerun() | |
| # Display conversation | |
| st.subheader("💬 Conversation" if st.session_state.language == "en" else | |
| "💬 Cuộc trò chuyện" if st.session_state.language == "vi" else | |
| "💬 Unterhaltung") | |
| if st.session_state.current_topic: | |
| st.info(f"**Topic:** {st.session_state.current_topic}") | |
| # Conversation display area | |
| conversation_container = st.container() | |
| with conversation_container: | |
| for msg in st.session_state.conversation: | |
| character = msg["character"] | |
| message = msg["message"] | |
| if character == "Alex": | |
| st.markdown(f'<div class="chat-message alex-message"><strong>Alex:</strong> {message}</div>', unsafe_allow_html=True) | |
| elif character == "Blake": | |
| st.markdown(f'<div class="chat-message blake-message"><strong>Blake:</strong> {message}</div>', unsafe_allow_html=True) | |
| elif character == "Charlie": | |
| st.markdown(f'<div class="chat-message charlie-message"><strong>Charlie:</strong> {message}</div>', unsafe_allow_html=True) | |
| else: | |
| st.markdown(f'<div class="chat-message" style="background-color: #F5F5F5; border-left-color: #9E9E9E;"><strong>{character}:</strong> {message}</div>', unsafe_allow_html=True) | |
| # Auto conversation logic | |
| if st.session_state.is_talking and st.session_state.current_topic: | |
| if len(st.session_state.conversation) < 15: # Limit conversation length | |
| # Determine next speaker | |
| character_order = ["Alex", "Blake", "Charlie"] | |
| next_speaker = character_order[len(st.session_state.conversation) % 3] | |
| with st.spinner(f"{next_speaker} is thinking..."): | |
| response = st.session_state.ai_friends.get_ai_response( | |
| next_speaker, | |
| st.session_state.conversation, | |
| st.session_state.current_topic, | |
| st.session_state.language | |
| ) | |
| st.session_state.conversation.append({ | |
| "character": next_speaker, | |
| "message": response, | |
| "color": st.session_state.ai_friends.characters[next_speaker]["color"] | |
| }) | |
| time.sleep(2) # Pause between responses | |
| st.experimental_rerun() | |
| else: | |
| st.session_state.is_talking = False | |
| st.success("Conversation completed!" if st.session_state.language == "en" else | |
| "Cuộc trò chuyện hoàn thành!" if st.session_state.language == "vi" else | |
| "Gespräch beendet!") | |
| # Bottom Banner | |
| st.markdown(""" | |
| <div class="bottom-banner"> | |
| <div style="display: flex; justify-content: space-between; align-items: center;"> | |
| <div class="logo">🧠 DB</div> | |
| <div>Made by Digitized Brains</div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| if __name__ == "__main__": | |
| main() |