mudassir032's picture
Update app.py
ef526b0 verified
import time
from langchain_groq import ChatGroq
import streamlit as st
from crewai import Agent
import os
# Initialize LLM
llm = ChatGroq(temperature=0.4, model_name="meta-llama/llama-4-maverick-17b-128e-instruct")
# File to store history
HISTORY_FILE = "history.txt"
# Load question history from file
def load_history():
if os.path.exists(HISTORY_FILE):
with open(HISTORY_FILE, "r") as f:
return [line.strip() for line in f.readlines()]
return []
# Save question history to file
def save_history(history):
with open(HISTORY_FILE, "w") as f:
for question in history:
f.write(question + "\n")
# Initialize session state
if "level" not in st.session_state:
st.session_state.level = 1
st.session_state.points = 0
st.session_state.history = load_history() # Load history at startup
st.session_state.questions_answered = 0
st.session_state.current_question = None
st.session_state.hint = None
st.session_state.lives = 3
# Define Agents
class NarratorAgent(Agent):
def act(self, level):
return f"Welcome to Level {level}, prepare to face your next challenge!"
class QuestionAgent(Agent):
def act(self, level, history):
"""Generate a unique question that is not in history"""
for _ in range(10): # Try multiple times to get a unique question
question = llm.invoke(
f"Generate a general knowledge question for a Q and A game. The player is at level {level}. "
f"Avoid repeating questions from this list: {history}. "
f"Do not include MCQs, only a single general knowledge question."
f"Only include the question nothing else no any extra message"
).content.strip()
if question and question not in history:
return question
return "No new questions available. Try again later."
class HintAgent(Agent):
def act(self, level, question):
return llm.invoke(f"Generate a hint for this question: {question}. The player is at level {level}, so don't reveal too much detail.").content
class AnswerCheckerAgent(Agent):
def act(self, question, answer):
return llm.invoke(f"Check if the user's answer: '{answer}' is correct for the question: '{question}'. Only respond with 'yes' or 'no'.").content.lower().strip()
# Instantiate agents
narrator = NarratorAgent(role="Narrator", goal="Guide the story forward", backstory="Knows all details of the world and its characters.")
questioner = QuestionAgent(role="Questioner", goal="Generate a general knowledge question", backstory="Knows all general knowledge.")
hinter = HintAgent(role="Hinter", goal="Provide hints about the question", backstory="Knows the correct answer but gives limited hints.")
validator = AnswerCheckerAgent(role="Validator", goal="Check if the answer is correct", backstory="Knows the correct answer.")
# Streamlit App
st.title("🏰 Knowledge Dungeon 🏰")
# Sidebar for Level, Points & Lives Display
st.sidebar.header("πŸ“œ Game Stats")
st.sidebar.warning('Type "hint" to get hints from Gandalf ✨')
st.sidebar.write(f"**πŸ† Level:** {st.session_state.level}")
st.sidebar.write(f"**πŸ’° Points:** {st.session_state.points}")
st.sidebar.write(f"**❀️ Lives:** {st.session_state.lives}")
MAX_LEVEL = 10
QUESTIONS_PER_LEVEL = 3
POINTS_PER_CORRECT = 10
def generate_new_question():
"""Generates a unique new question and stores it in session state."""
question = questioner.act(st.session_state.level, st.session_state.history)
if question != "No new questions available. Try again later.":
st.session_state.current_question = question
st.session_state.history.append(question)
st.session_state.hint = hinter.act(st.session_state.level, question)
save_history(st.session_state.history) # Save immediately to prevent duplicates
else:
st.session_state.current_question = "No more questions available!"
def main():
level = st.session_state.level
if level > MAX_LEVEL:
st.success("πŸŽ‰ Congratulations! You have won the game! πŸŽ‰")
st.stop()
if st.session_state.lives <= 0:
st.error("πŸ’€ You have lost all your lives! Game Over!")
st.stop()
# Display Narration
st.write(f"πŸ“œ {narrator.act(level)}")
# Generate a new question if needed
if not st.session_state.current_question:
generate_new_question()
# Display the question
st.write(f"**Sauron:** A feeble mortal dares to challenge me? Hah! Answer this question, or be doomed to eternal failure!")
st.write(f"πŸ”Ή {st.session_state.current_question}")
# User input
answer = st.text_input("Your Answer:")
if st.button("Submit Answer"):
if answer.lower().strip() == "hint":
st.info(f"πŸ’‘ Hint: {st.session_state.hint}")
elif answer.strip():
response = validator.act(st.session_state.current_question, answer)
if response in ['yes', 'yes.']:
st.success("βœ… Correct! You defeated the enemy.")
st.session_state.points += POINTS_PER_CORRECT
st.session_state.questions_answered += 1
time.sleep(3)
# Move to next level if necessary
if st.session_state.questions_answered >= QUESTIONS_PER_LEVEL:
if st.session_state.level == MAX_LEVEL:
st.success("πŸŽ‰ Congratulations! You have won the game! πŸŽ‰")
st.stop()
else:
st.session_state.level += 1
st.session_state.questions_answered = 0
st.success(f"πŸ”Ί Level Up! Welcome to Level {st.session_state.level}.")
time.sleep(3)
generate_new_question()
st.rerun()
else:
st.error("❌ Wrong answer! Try again.")
st.session_state.lives -= 1
time.sleep(3)
st.rerun() # Force refresh to update lives in sidebar
main()