import gradio as gr from gradio_client import Client # Start the Qwen API client. client = Client("Qwen/Qwen2.5-72B-Instruct") SYSTEM_PROMPT = ( "You are an assistant and you will ask yes or no questions about sea creatures. " "Your goal is to guess the sea creature that the user has in mind from these questions. " "You will never deviate from this task. Only when you find the answer, write it between tags. " "Start asking now. If your answer is wrong, continue asking. Never ask the user for the answer." ) def start_game(): """ Starts the game; retrieves the first question. The question box is visible, the final guess area is cleared, the answer buttons are visible, the evaluation and restart/continue buttons are hidden. """ history = [] result = client.predict( query="", history=history, system=SYSTEM_PROMPT, api_name="/model_chat" ) assistant_message = result[1][-1][1] history.append(("", assistant_message)) answer_buttons_update = gr.update(visible=True) eval_buttons_update = gr.update(visible=False) restart_update = gr.update(visible=False) continue_update = gr.update(visible=False) return ( gr.update(visible=True, value=assistant_message), # assistant_display gr.update(visible=True, value=""), # final_answer_display history, # state answer_buttons_update, # btn_yes answer_buttons_update, # btn_no answer_buttons_update, # btn_dont_know eval_buttons_update, # btn_correct eval_buttons_update, # btn_incorrect "", # final_state restart_update, # btn_restart continue_update # btn_continue ) def process_turn(user_answer, history): """ Sends the user's answer to the API. If the API's response contains tags, the final guess has been made. - In this case, the question box is hidden, - The final guess is displayed in large and bold, - The answer buttons are hidden, - The evaluation buttons are visible. If there is no final guess, the assistant's answer (question) is updated. """ result = client.predict( query=user_answer, history=history, system=SYSTEM_PROMPT, api_name="/model_chat" ) assistant_message = result[1][-1][1] history.append((user_answer, assistant_message)) final_answer = "" if "" in assistant_message and "" in assistant_message: start_idx = assistant_message.index("") + len("") end_idx = assistant_message.index("") final_answer = assistant_message[start_idx:end_idx].strip() if final_answer: # Final guess made. assistant_update = gr.update(visible=False) final_text = f"**My guess:** **{final_answer}**" answer_update = gr.update(visible=False) eval_update = gr.update(visible=True) restart_update = gr.update(visible=False) continue_update = gr.update(visible=False) else: assistant_update = gr.update(visible=True, value=assistant_message) final_text = "" answer_update = gr.update(visible=True) eval_update = gr.update(visible=False) restart_update = gr.update(visible=False) continue_update = gr.update(visible=False) return ( assistant_update, # assistant_display final_text, # final_answer_display history, # state answer_update, # btn_yes answer_update, # btn_no answer_update, # btn_dont_know eval_update, # btn_correct eval_update, # btn_incorrect final_answer, # final_state restart_update, # btn_restart continue_update # btn_continue ) def process_yes(history): return process_turn("Yes", history) def process_no(history): return process_turn("No", history) def process_dont_know(history): return process_turn("I don't know", history) def evaluate_correct(final_state): """ If the final guess is correct: - The final text is updated to "My guess is correct! Shall we play again?" - The evaluation buttons are hidden. - The "Play Again" button becomes visible. - The "Continue" button remains hidden. """ new_text = "**My guess is correct! Shall we play again?**" return ( new_text, gr.update(visible=False), # btn_correct hidden gr.update(visible=False), # btn_incorrect hidden gr.update(visible=True, value="Play Again"), # btn_restart visible gr.update(visible=False) # btn_continue hidden ) def evaluate_incorrect(final_state): """ If the final guess is incorrect: - The final text is updated to "Let's continue, press the continue button." - The evaluation buttons are hidden. - The "Continue" button becomes visible. """ new_text = "**Let's continue, press the continue button.**" return ( new_text, gr.update(visible=False), # btn_correct hidden gr.update(visible=False), # btn_incorrect hidden gr.update(visible=False), # btn_restart hidden gr.update(visible=True, value="Continue") # btn_continue visible ) def continue_game(history): """ When the "Continue" button is clicked, the assistant asks a new question with the current history. The conversation history is preserved, the question box and answer buttons are reactivated. """ result = client.predict( query="", history=history, system=SYSTEM_PROMPT, api_name="/model_chat" ) assistant_message = result[1][-1][1] history.append(("", assistant_message)) return ( gr.update(visible=True, value=assistant_message), # assistant_display gr.update(visible=True, value=""), # final_answer_display history, # state gr.update(visible=True), # btn_yes gr.update(visible=True), # btn_no gr.update(visible=True), # btn_dont_know gr.update(visible=False), # btn_correct gr.update(visible=False), # btn_incorrect "", # final_state gr.update(visible=False), # btn_restart gr.update(visible=False) # btn_continue ) def restart_game(): """ When the "Play Again" button is clicked, the game starts over (history is reset). """ global client client = Client("Qwen/Qwen2.5-72B-Instruct") return start_game() # Custom CSS: css = """ .question-box { border: 2px solid #ccc; padding: 10px; border-radius: 5px; margin: 10px auto; width: 80%; text-align: center; } .final-answer { font-size: 2em; font-weight: bold; text-align: center; margin: 20px; } .button-group { display: flex; justify-content: center; gap: 20px; } """ with gr.Blocks(css=css) as demo: gr.Markdown("### TUBITECH # 9694 - Sea Creature Akinator") # The question asked by the assistant. assistant_display = gr.Markdown(label="Question", elem_classes="question-box") # Final guess area. final_answer_display = gr.Markdown("", label="Guess", elem_classes="final-answer") # Answer buttons: Yes, No, I don't know. with gr.Row(elem_classes="button-group"): btn_yes = gr.Button("Yes") btn_no = gr.Button("No") btn_dont_know = gr.Button("I don't know") # Evaluation buttons: Correct, Incorrect (hidden initially). with gr.Row(elem_classes="button-group"): btn_correct = gr.Button("Correct", visible=False) btn_incorrect = gr.Button("Incorrect", visible=False) # Buttons displayed in the final state: # - If correct, "Play Again" btn_restart = gr.Button("Play Again", visible=False) # - If incorrect, "Continue" btn_continue = gr.Button("Continue", visible=False) # Hidden states: state = gr.State([]) final_state = gr.State("") # Start the game when the page loads. demo.load( fn=start_game, outputs=[ assistant_display, final_answer_display, state, btn_yes, btn_no, btn_dont_know, btn_correct, btn_incorrect, final_state, btn_restart, btn_continue ] ) # When answer buttons are clicked: btn_yes.click( fn=process_yes, inputs=[state], outputs=[ assistant_display, final_answer_display, state, btn_yes, btn_no, btn_dont_know, btn_correct, btn_incorrect, final_state, btn_restart, btn_continue ] ) btn_no.click( fn=process_no, inputs=[state], outputs=[ assistant_display, final_answer_display, state, btn_yes, btn_no, btn_dont_know, btn_correct, btn_incorrect, final_state, btn_restart, btn_continue ] ) btn_dont_know.click( fn=process_dont_know, inputs=[state], outputs=[ assistant_display, final_answer_display, state, btn_yes, btn_no, btn_dont_know, btn_correct, btn_incorrect, final_state, btn_restart, btn_continue ] ) # Evaluation buttons: btn_correct.click( fn=evaluate_correct, inputs=[final_state], outputs=[ final_answer_display, btn_correct, btn_incorrect, btn_restart, btn_continue ] ) btn_incorrect.click( fn=evaluate_incorrect, inputs=[final_state], outputs=[ final_answer_display, btn_correct, btn_incorrect, btn_restart, btn_continue ] ) # When the "Play Again" button is clicked: btn_restart.click( fn=restart_game, inputs=[], outputs=[ assistant_display, final_answer_display, state, btn_yes, btn_no, btn_dont_know, btn_correct, btn_incorrect, final_state, btn_restart, btn_continue ] ) # When the "Continue" button is clicked: btn_continue.click( fn=continue_game, inputs=[state], outputs=[ assistant_display, final_answer_display, state, btn_yes, btn_no, btn_dont_know, btn_correct, btn_incorrect, final_state, btn_restart, btn_continue ] ) demo.launch(debug=True, show_error=True)