kasoti / app.py
rahideer's picture
Update app.py
d600c78 verified
import os
import gradio as gr
import speech_recognition as sr
import numpy as np
import tempfile
import scipy.io.wavfile
import requests
# Set your API keys
os.environ["MISTRAL_API_KEY"] = "R1ISnVkHrj7fSd5Dh6ZSZHqCJhhct0ZR"
os.environ["GROQ_API_KEY"] = "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"
state = {
"started": False,
"history": [],
"current_q": "",
"question_num": 0,
"hint_mode": False,
"final_answer": ""
}
def convert_audio_to_text(audio, lang_choices):
if audio is None:
return ""
try:
sr_rate, audio_data = audio
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as fp:
scipy.io.wavfile.write(fp.name, sr_rate, audio_data)
recog = sr.Recognizer()
with sr.AudioFile(fp.name) as src:
recorded = recog.record(src)
lang = "en-US" if "English" in lang_choices else "ur-PK" if "Urdu" in lang_choices else "en-US"
return recog.recognize_google(recorded, language=lang).lower()
except Exception as e:
return f"[Error] Couldn't transcribe: {str(e)}"
def query_llm(api, messages, model=None):
headers = {
"Authorization": f"Bearer {os.environ[f'{api}_API_KEY']}",
"Content-Type": "application/json"
}
payload = {
"messages": messages,
"model": model or ("llama3-70b-8192" if api == "GROQ" else "mistral-medium")
}
endpoint = {
"MISTRAL": "https://api.mistral.ai/v1/chat/completions",
"GROQ": "https://api.groq.com/openai/v1/chat/completions"
}[api]
response = requests.post(endpoint, headers=headers, json=payload)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"].strip()
else:
return f"[{api} Error] {response.status_code} - {response.text}"
def begin_game():
state["started"] = True
state["history"] = []
state["question_num"] = 1
state["hint_mode"] = False
state["final_answer"] = ""
state["current_q"] = "Does it belong to the world of living things?"
return (
f"Question 1: {state['current_q']}",
"",
gr.update(visible=False),
gr.update(visible=True),
gr.update(visible=False),
state["question_num"]
)
def interpret_answer(user_answer):
if not state["started"]:
return "⛔ Please start a new game.", "", gr.update(visible=False), "", gr.update(visible=False), state["question_num"]
normalized = user_answer.strip().lower()
if normalized not in ["yes", "no", "ہاں", "نہیں"]:
return "⚠️ Respond with 'yes' or 'no' (or ہاں/نہیں).", user_answer, gr.update(visible=False), "", gr.update(visible=False), state["question_num"]
state["history"].append((state["current_q"], normalized))
if state["question_num"] >= 20:
state["started"] = False
guess = generate_final_guess()
state["final_answer"] = guess
return "Game Over!", user_answer, gr.update(visible=True), "", gr.update(value=guess, visible=True), state["question_num"]
if state["question_num"] % 5 == 0:
guess = generate_final_guess()
if "i think" in guess.lower() or "maybe" in guess.lower():
state["current_q"] = f"{guess} Am I right?"
return state["current_q"], user_answer, gr.update(visible=False), "", gr.update(visible=False), state["question_num"]
state["question_num"] += 1
state["current_q"] = get_next_question()
return (
f"Question {state['question_num']}: {state['current_q']}",
user_answer,
gr.update(visible=False),
"",
gr.update(visible=False),
state["question_num"]
)
def get_next_question():
history_prompt = "\n".join([f"Q: {q}\nA: {a}" for q, a in state["history"]])
prompt = (
"You're playing a guessing game. Only respond with a yes/no question, nothing else.\n"
"Based on the following history, ask the next smart question:\n\n"
f"{history_prompt}\n\n"
"Next question only:"
)
return query_llm("MISTRAL", [{"role": "user", "content": prompt}])
def generate_final_guess():
history = "\n".join([f"Q: {q}\nA: {a}" for q, a in state["history"]])
prompt = f"""Guess the secret concept based on these Q&A. If you're not sure, say "I need more clues."\n\n{history}\n\nYour guess:"""
return query_llm("MISTRAL", [{"role": "user", "content": prompt}])
def hint_response():
if not state["hint_mode"] or not state["started"]:
return "Hint mode is off or game not active."
question = state["current_q"]
history = "\n".join([f"{q} - {a}" for q, a in state["history"]])
prompt = f"""The player seems confused by this question: "{question}". Previous Q&A were:\n{history}\n\nGive a helpful, simple hint."""
return query_llm("MISTRAL", [{"role": "user", "content": prompt}])
def toggle_hint_mode():
state["hint_mode"] = not state["hint_mode"]
return (
"Hint Mode: ON" if state["hint_mode"] else "Hint Mode: OFF",
gr.update(visible=True)
)
# UI
with gr.Blocks(title="Kasoti", theme=gr.themes.Soft(primary_hue="pink", secondary_hue="blue")) as demo:
gr.Markdown(
"""
<link href="https://fonts.googleapis.com/css2?family=Comic+Neue&display=swap" rel="stylesheet">
<style>
* { font-family: 'Comic Neue', cursive; }
body {
background: linear-gradient(120deg, #ffe0f0 0%, #e0f7ff 100%);
}
.gr-button {
border-radius: 12px !important;
font-size: 16px !important;
padding: 10px 18px !important;
}
.title-text {
text-align: center;
font-size: 32px;
color: #ff69b4;
font-weight: bold;
margin-bottom: 0;
}
.subtitle-text {
text-align: center;
font-size: 16px;
color: #555;
margin-top: 0;
}
</style>
<div class='title-text'>🧠 Kasoti - The Mind Reading Game</div>
<p class='subtitle-text'>Think of something and answer my yes/no questions — let's see if I can guess it in 20 tries! 🕵️‍♀️</p>
"""
)
with gr.Row():
start = gr.Button("🎲 Start Game")
hint_toggle = gr.Button("💡 Toggle Hint Mode")
hint_status = gr.Textbox(value="Hint Mode: OFF", show_label=False, interactive=False)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 🎤 Your Answer")
lang_sel = gr.CheckboxGroup(["English", "Urdu"], label="🌐 Choose Language", value=["English"])
mic_input = gr.Audio(sources=["microphone"], type="numpy", label="🎙️ Speak Your Answer")
transcribe = gr.Button("📝 Transcribe Voice")
typed_ans = gr.Textbox(label="✍️ Or Type Your Answer")
submit = gr.Button("✅ Yep, Here You Go!")
with gr.Column(scale=2):
gr.Markdown("### 🎮 Game Progress")
question_progress = gr.Slider(minimum=1, maximum=20, value=1, label="❓ Question Number", interactive=False)
game_q_box = gr.Textbox(label="🧩 Current Question", interactive=False, lines=2)
game_history = gr.Textbox(label="📜 Game Updates", interactive=False, lines=3)
final_answer_box = gr.Textbox(label="🎯 Final Guess", visible=False, lines=2, interactive=False)
# Button logic
start.click(
fn=begin_game,
outputs=[game_q_box, game_history, final_answer_box, submit, final_answer_box, question_progress]
)
hint_toggle.click(fn=toggle_hint_mode, outputs=[hint_status, game_history])
hint_toggle.click(fn=hint_response, outputs=[game_history])
transcribe.click(fn=convert_audio_to_text, inputs=[mic_input, lang_sel], outputs=[typed_ans])
submit.click(
fn=interpret_answer,
inputs=[typed_ans],
outputs=[game_q_box, typed_ans, final_answer_box, game_history, final_answer_box, question_progress]
)
demo.launch()