import streamlit as st import time import requests from streamlit.components.v1 import html import os from dotenv import load_dotenv # Voice input dependencies import torchaudio import numpy as np import torch from io import BytesIO import hashlib from audio_recorder_streamlit import audio_recorder from transformers import pipeline ###################################### # Voice Input Helper Functions ###################################### @st.cache_resource def load_voice_model(): return pipeline("automatic-speech-recognition", model="openai/whisper-base") def process_audio(audio_bytes): waveform, sample_rate = torchaudio.load(BytesIO(audio_bytes)) if waveform.shape[0] > 1: waveform = torch.mean(waveform, dim=0, keepdim=True) if sample_rate != 16000: resampler = torchaudio.transforms.Resample(orig_freq=sample_rate, new_freq=16000) waveform = resampler(waveform) return {"raw": waveform.numpy().squeeze(), "sampling_rate": 16000} def get_voice_transcription(state_key): if state_key not in st.session_state: st.session_state[state_key] = "" audio_bytes = audio_recorder( key=state_key + "_audio", pause_threshold=0.8, text="🎙️ Speak your message", recording_color="#e8b62c", neutral_color="#6aa36f" ) if audio_bytes: current_hash = hashlib.md5(audio_bytes).hexdigest() last_hash_key = state_key + "_last_hash" if st.session_state.get(last_hash_key, "") != current_hash: st.session_state[last_hash_key] = current_hash try: audio_input = process_audio(audio_bytes) whisper = load_voice_model() transcribed_text = whisper(audio_input)["text"] st.info(f"📝 Transcribed: {transcribed_text}") st.session_state[state_key] += (" " + transcribed_text).strip() st.experimental_rerun() except Exception as e: st.error(f"Voice input error: {str(e)}") return st.session_state[state_key] ###################################### # Game Functions & Styling ###################################### @st.cache_resource def get_help_agent(): return pipeline("conversational", model="facebook/blenderbot-400M-distill") def inject_custom_css(): st.markdown(""" """, unsafe_allow_html=True) def show_confetti(): html(""" """) def ask_llama(conversation_history, category, is_final_guess=False): api_url = "https://api.groq.com/openai/v1/chat/completions" headers = { "Authorization": f"Bearer {os.getenv('GROQ_API_KEY')}", "Content-Type": "application/json" } system_prompt = f"""You're playing 20 questions to guess a {category}. Rules: 1. Ask strategic, non-repeating yes/no questions to narrow down. 2. Use all previous answers smartly. 3. If you're 80%+ sure, say: Final Guess: [your guess] 4. For places: ask about continent, country, landmarks, etc. 5. For people: ask if real, profession, gender, etc. 6. For objects: ask about use, size, material, etc.""" prompt = f"""Based on these answers about a {category}, provide ONLY your final guess with no extra text: {conversation_history}""" if is_final_guess else "Ask your next smart yes/no question." messages = [{"role": "system", "content": system_prompt}] messages += conversation_history messages.append({"role": "user", "content": prompt}) data = { "model": "llama-3-70b-8192", "messages": messages, "temperature": 0.8, "max_tokens": 100 } try: res = requests.post(api_url, headers=headers, json=data) res.raise_for_status() return res.json()["choices"][0]["message"]["content"] except Exception as e: st.error(f"❌ LLaMA API error: {e}") return "..." ###################################### # Main App Logic Here (UI, Game Loop) ###################################### def main(): load_dotenv() inject_custom_css() st.title("🎮 Guess It! - 20 Questions Game") st.markdown("
Think of a person, place, or object. LLaMA will try to guess it!
", unsafe_allow_html=True) category = st.selectbox("Category of your secret:", ["Person", "Place", "Object"]) if "conversation" not in st.session_state: st.session_state.conversation = [] st.session_state.last_bot_msg = "" if st.button("🔄 Restart Game"): st.session_state.conversation = [] st.session_state.last_bot_msg = "" st.rerun() if not st.session_state.conversation: st.session_state.last_bot_msg = ask_llama([], category) st.session_state.conversation.append({"role": "assistant", "content": st.session_state.last_bot_msg}) st.markdown(f"
LLaMA: {st.session_state.last_bot_msg}
", unsafe_allow_html=True) user_input = get_voice_transcription("voice_input") or st.text_input("💬 Your answer (yes/no/sometimes):") if st.button("Submit Answer") and user_input: st.session_state.conversation.append({"role": "user", "content": user_input}) with st.spinner("Thinking..."): response = ask_llama(st.session_state.conversation, category) st.session_state.last_bot_msg = response st.session_state.conversation.append({"role": "assistant", "content": response}) st.rerun() if st.button("🤔 Make Final Guess"): with st.spinner("Making final guess..."): final_guess = ask_llama(st.session_state.conversation, category, is_final_guess=True) st.markdown(f"
🤯 Final Guess: {final_guess}
", unsafe_allow_html=True) show_confetti() if __name__ == "__main__": main()