import streamlit as st import time import requests from streamlit.components.v1 import html # Import transformers and cache the help agent for performance @st.cache_resource def get_help_agent(): from transformers import pipeline # Using BlenderBot 400M Distill as the public conversational model return pipeline("conversational", model="facebook/blenderbot-400M-distill") # Custom CSS for professional look (fixed text color) def inject_custom_css(): st.markdown(""" """, unsafe_allow_html=True) # Confetti animation def show_confetti(): html(""" """) # Enhanced AI question generation for guessing game using Llama model def ask_llama(conversation_history, category, is_final_guess=False): api_url = "https://api.groq.com/openai/v1/chat/completions" headers = { "Authorization": "Bearer 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", "Content-Type": "application/json" } system_prompt = f"""You're playing 20 questions to guess a {category}. Follow these rules: 1. Ask strategic, non-repeating yes/no questions that narrow down possibilities. 2. Consider all previous answers carefully before asking the next question. 3. If you're very confident (80%+ sure), respond with "Final Guess: [your guess]". 4. For places: ask about continent, climate, famous landmarks, country, city or population. 5. For people: ask about fictional or real, profession, gender, alive/dead, nationality, or fame. 6. For objects: ask about size, color, usage, material, or where it's found. 7. Never repeat questions and always make progress toward guessing. 8. If the guess is generic (e.g. "bed") and the player confirms it with "yes", end the game. 9. If the guess is generic but the answer is "no", ask additional questions to refine the guess.""" if is_final_guess: prompt = f"""Based on these answers about a {category}, provide ONLY your final guess with no extra text: {conversation_history}""" else: prompt = "Ask your next strategic yes/no question that will best narrow down the possibilities." messages = [ {"role": "system", "content": system_prompt}, *conversation_history, {"role": "user", "content": prompt} ] data = { "model": "llama-3.3-70b-versatile", "messages": messages, "temperature": 0.7 if is_final_guess else 0.8, "max_tokens": 100 } try: response = requests.post(api_url, headers=headers, json=data) response.raise_for_status() return response.json()["choices"][0]["message"]["content"] except Exception as e: st.error(f"Error calling Llama API: {str(e)}") return "Could not generate question" # New function for the help AI assistant using a Hugging Face chatbot model def ask_help_agent(query): from transformers import Conversation # Get the cached help agent (BlenderBot) help_agent = get_help_agent() conversation = Conversation(query) result = help_agent(conversation) # The generated response is stored in generated_responses list return result.generated_responses[-1] # Main game logic def main(): inject_custom_css() st.markdown('
KASOTI
', unsafe_allow_html=True) st.markdown('
The Smart Guessing Game
', unsafe_allow_html=True) if 'game_state' not in st.session_state: st.session_state.game_state = "start" st.session_state.questions = [] st.session_state.current_q = 0 st.session_state.answers = [] st.session_state.conversation_history = [] st.session_state.category = None st.session_state.final_guess = None st.session_state.help_conversation = [] # separate history for help agent # Start screen if st.session_state.game_state == "start": st.markdown("""

Welcome to KASOTI 🎯

Think of something and I'll try to guess it in 20 questions or less!

Choose a category:

Type your category below to begin:

""", unsafe_allow_html=True) with st.form("start_form"): category_input = st.text_input("Enter category (person/place/object):").strip().lower() if st.form_submit_button("Start Game"): if not category_input: st.error("Please enter a category!") elif category_input not in ["person", "place", "object"]: st.error("Please enter either 'person', 'place', or 'object'!") else: st.session_state.category = category_input first_question = ask_llama([ {"role": "user", "content": "Ask your first strategic yes/no question."} ], category_input) st.session_state.questions = [first_question] st.session_state.conversation_history = [ {"role": "assistant", "content": first_question} ] st.session_state.game_state = "gameplay" st.session_state.current_q = 0 # start at question 0 st.rerun() # Gameplay screen elif st.session_state.game_state == "gameplay": current_question = st.session_state.questions[st.session_state.current_q] # If the AI made a final guess, switch to confirmation if "Final Guess:" in current_question: st.session_state.final_guess = current_question.split("Final Guess:")[1].strip() st.session_state.game_state = "confirm_guess" st.rerun() st.markdown(f'
Question {st.session_state.current_q + 1}/20:

' f'{current_question}
', unsafe_allow_html=True) with st.form("answer_form"): answer_input = st.text_input("Your answer (yes/no/both):", key=f"answer_{st.session_state.current_q}").strip().lower() if st.form_submit_button("Submit"): if answer_input not in ["yes", "no", "both"]: st.error("Please answer with 'yes', 'no', or 'both'!") else: st.session_state.answers.append(answer_input) st.session_state.conversation_history.append( {"role": "user", "content": answer_input} ) # Generate next response from Llama next_response = ask_llama( st.session_state.conversation_history, st.session_state.category ) if "Final Guess:" in next_response: st.session_state.final_guess = next_response.split("Final Guess:")[1].strip() st.session_state.game_state = "confirm_guess" else: st.session_state.questions.append(next_response) st.session_state.conversation_history.append( {"role": "assistant", "content": next_response} ) st.session_state.current_q += 1 # Stop after 20 questions max if st.session_state.current_q >= 20: st.session_state.game_state = "result" st.rerun() # Side Help Option: independent chat with an AI help assistant (Hugging Face model) with st.expander("Need Help? Chat with AI Assistant"): help_query = st.text_input("Enter your help query:", key="help_query") if st.button("Send", key="send_help"): if help_query: help_response = ask_help_agent(help_query) st.session_state.help_conversation.append({"query": help_query, "response": help_response}) else: st.error("Please enter a query!") if st.session_state.help_conversation: for msg in st.session_state.help_conversation: st.markdown(f"**You:** {msg['query']}") st.markdown(f"**Help Assistant:** {msg['response']}") # Confirm guess screen elif st.session_state.game_state == "confirm_guess": st.markdown(f'
🤖 My Final Guess:

' f'Is it {st.session_state.final_guess}?
', unsafe_allow_html=True) with st.form("confirm_form"): confirm_input = st.text_input("Type your answer (yes/no/both):", key="confirm_input").strip().lower() if st.form_submit_button("Submit"): if confirm_input not in ["yes", "no", "both"]: st.error("Please answer with 'yes', 'no', or 'both'!") else: if confirm_input == "yes": st.session_state.game_state = "result" st.rerun() else: # Add the negative response to history and continue gameplay st.session_state.conversation_history.append( {"role": "user", "content": "no"} ) st.session_state.game_state = "gameplay" next_response = ask_llama( st.session_state.conversation_history, st.session_state.category ) st.session_state.questions.append(next_response) st.session_state.conversation_history.append( {"role": "assistant", "content": next_response} ) st.session_state.current_q += 1 st.rerun() # Result screen elif st.session_state.game_state == "result": if not st.session_state.final_guess: # Generate final guess if not already made qa_history = "\n".join( [f"Q{i+1}: {q}\nA: {a}" for i, (q, a) in enumerate(zip(st.session_state.questions, st.session_state.answers))] ) final_guess = ask_llama( [{"role": "user", "content": qa_history}], st.session_state.category, is_final_guess=True ) st.session_state.final_guess = final_guess.split("Final Guess:")[-1].strip() show_confetti() st.markdown(f'
🎉 It\'s...
', unsafe_allow_html=True) time.sleep(1) st.markdown(f'
{st.session_state.final_guess}
', unsafe_allow_html=True) st.markdown(f"

Guessed in {st.session_state.current_q + 1} questions

", unsafe_allow_html=True) if st.button("Play Again", key="play_again"): st.session_state.clear() st.rerun() if __name__ == "__main__": main()