IDP_webapp / app /app.py
gb3105
modified prompts
cd82452
Raw
History Blame Contribute Delete
21.7 kB
from flask import Flask, render_template, request, redirect, url_for, flash, session, jsonify
from .agent import GroqAgent
PERSONALITY_PROMPTS = {
"vriendelijke_ouder": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like a warm, ordinary parent. You are kind, calm, and encouraging. You give simple advice and sometimes add a gentle explanation. Keep answers short and natural, like something a parent might quickly say at home. Answer in 1 sentence (maximum 2), no more than 20 words . Communicate exclusively in Dutch. Do not say things like: great question!",
"professor": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like an enthusiastic professor who loves explaining things. You use slightly smarter words and give extra information. You may answer a bit longer than the others, but still keep it understandable for a child. Answer in 1 sentences (maximum 2), no more than 20 words . Communicate exclusively in Dutch. Do not say things like: great question!",
"wetenschapper": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like a curious scientist. You like evidence, experiments, and asking why. You explain things clearly and logically. Keep answers short unless the question needs more detail. Answer in 1 sentence (maximum 2), no more than 20 words . Communicate exclusively in Dutch. Do not say things like: great question!",
"strenge_ouder": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like a parent who values rules, responsibility, and good behaviour. You are not mean, but you are firm and practical. Keep answers short, clear, and sensible. Answer in 1 sentence (maximum 2), no more than 20 words . Communicate exclusively in Dutch. Do not say things like: great question!",
"grappige_ouder": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like a playful parent who likes making small jokes. You are cheerful, lighthearted, and a little silly, but still helpful. Keep answers short and avoid long explanations. Answer in 1 sentence (maximum 2), no more than 20 words. Communicate exclusively in Dutch. Do not say things like: great question!",
"piraat": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like a friendly pirate. You use pirate-style language such as ahoy or matey, but not so much that it becomes hard to understand. Keep answers playful and short. Answer in 1 sentence (maximum 2), no more than 20 words. Communicate exclusively in Dutch. Do not say things like: great question!",
"alien": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like a friendly alien visiting Earth. You find normal human things strange and interesting. You answer with curiosity and wonder. Keep answers short and funny. Answer in 1 sentence (maximum 2), no more than 20 words. Communicate exclusively in Dutch. Do not say things like: great question!",
"tovenaar": "You are taking part in a child-friendly guessing game. Keep your answer natural, short, and easy for a child to understand. You respond like a wise but playful wizard. You use magical language and imaginative ideas, but still answer the child's question clearly. Keep it short and mysterious. Answer in 1 sentence (maximum 2), no more than 20 words. Communicate exclusively in Dutch. Do not say things like: great question!",
}
refresh_needed = False
class FlaskApp:
def __init__(self, agents):
self.agents = agents # [None (admin), agent1, agent2, agent3]
self.flask_app = Flask(__name__)
self.flask_app.secret_key = "supersecretkey"
self.difficulty_limits = {"easy": 5, "medium": 3, "hard": 1}
self.difficulty = "easy"
self.max_questions = self.difficulty_limits[self.difficulty]
self.questions_asked = 0
self.game_over = False
self.last_result = None
# screen_assignment maps screen position (1,2,3) to role (Human, AI1, AI2)
self.screen_assignment = {"1": "AI1", "2": "Human", "3": "AI2"}
self.rounds = []
self.pending_round = None
self.discarded_ai_responses = []
self.routes_registered = False
self.register_routes()
self.first_guess = None
def register_routes(self):
if not self.routes_registered:
@self.flask_app.route('/dashboard', methods=['GET', 'POST'])
def user_dashboard():
global refresh_needed
if request.method == 'POST':
user_message = request.form.get('message')
if user_message:
if self.game_over or self.pending_round is not None:
flash('Wacht op het volgende spel of de admin-reactie.', 'warning')
return redirect(url_for('user_dashboard'))
if self.questions_asked >= self.max_questions:
flash('Je hebt je laatste vraag al gesteld. Maak je keuze.', 'warning')
return redirect(url_for('user_dashboard'))
ai_options = []
for agent_index, agent in enumerate(self.agents):
if agent is None:
continue
llm_response = agent.request_llm_response(user_message)
ai_options.append({
'agent': f'llm{agent_index}',
'content': llm_response
})
self.questions_asked += 1
self.pending_round = {
'question': user_message,
'ai_options': ai_options
}
flash('Je vraag is verstuurd. Wacht op de admin.', 'success')
return redirect(url_for('user_dashboard'))
refresh_needed = True
return render_template('dashboard.html')
@self.flask_app.route('/admin_dashboard', methods=['GET', 'POST'])
def admin_dashboard():
global refresh_needed
if request.method == 'POST':
action = request.form.get('action')
if action == 'send_round':
human_response = request.form.get('human_response')
if self.pending_round is None:
flash('Er is geen open vraag van de gebruiker.', 'warning')
return redirect(url_for('admin_dashboard'))
if not human_response:
flash('Schrijf eerst een menselijk antwoord.', 'warning')
return redirect(url_for('admin_dashboard'))
# Use current ai_options from pending_round
self.rounds.append({
'question': self.pending_round['question'],
'ai_options': self.pending_round['ai_options'],
'human_response': human_response
})
self.pending_round = None
flash('Antwoorden zijn verstuurd naar de gebruiker.', 'success')
return redirect(url_for('admin_dashboard'))
if action == 'reload_ai':
agent_index = int(request.form.get('agent_index'))
if self.pending_round is not None:
question = self.pending_round['question']
agent = self.agents[agent_index]
if agent is not None:
new_response = agent.request_llm_response(question)
for option in self.pending_round['ai_options']:
if option['agent'] == f'llm{agent_index}':
self.discarded_ai_responses.append({
'question': question,
'agent': option['agent'],
'content': option['content']
})
option['content'] = new_response
break
return redirect(url_for('admin_dashboard'))
refresh_needed = True
return render_template('admin_dashboard.html',
pending_round=self.pending_round,
discarded_ai_responses=self.discarded_ai_responses,
screen_assignment=self.screen_assignment,
difficulty=self.difficulty,
questions_left=max(self.max_questions - self.questions_asked, 0),
max_questions=self.max_questions)
@self.flask_app.route('/setup_prompts', methods=['GET', 'POST'])
def setup_prompts():
if request.method == 'POST':
llm_1_key = request.form.get('llm_1_system_content')
llm_2_key = request.form.get('llm_2_system_content')
if llm_1_key in PERSONALITY_PROMPTS:
self.agents[1].system_content = PERSONALITY_PROMPTS[llm_1_key]
if llm_2_key in PERSONALITY_PROMPTS:
self.agents[2].system_content = PERSONALITY_PROMPTS[llm_2_key]
self.selected_llm_1 = llm_1_key
self.selected_llm_2 = llm_2_key
return redirect(url_for('setup_screens'))
return render_template('setup_prompts.html',
selected_llm_1=getattr(self, 'selected_llm_1', 'vriendelijke_ouder'),
selected_llm_2=getattr(self, 'selected_llm_2', 'grappige_ouder'))
@self.flask_app.route('/setup_screens', methods=['GET', 'POST'])
def setup_screens():
import random
if request.method == 'POST':
return redirect(url_for('admin_dashboard'))
roles = ["Human", "AI1", "AI2"]
random.shuffle(roles)
self.screen_assignment = {"1": roles[0], "2": roles[1], "3": roles[2]}
human_screen = [k for k, v in self.screen_assignment.items() if v == "Human"][0]
print("Human screen:", human_screen) # add this to check in terminal
return render_template('setup_screens.html', human_screen=human_screen)
@self.flask_app.route('/reinitialize', methods=['POST'])
def reinitialize_dashboards():
session.clear()
self.questions_asked = 0
self.game_over = False
self.last_result = None
self.rounds = []
self.pending_round = None
self.discarded_ai_responses = []
self.screen_assignment = {"1": "AI1", "2": "Human", "3": "AI2"}
self.first_guess = None
return redirect(url_for('admin_rules'))
@self.flask_app.route('/reset_game', methods=['POST'])
def reset_game():
self.questions_asked = 0
self.game_over = False
self.last_result = None
self.rounds = []
self.pending_round = None
self.discarded_ai_responses = []
self.first_guess = None
next_url = request.form.get('next')
if next_url:
return redirect(next_url)
return redirect(url_for('user_dashboard'))
@self.flask_app.route('/set_difficulty', methods=['POST'])
def set_difficulty():
difficulty = request.form.get('difficulty')
if difficulty in self.difficulty_limits and self.questions_asked == 0 and self.pending_round is None:
self.difficulty = difficulty
self.max_questions = self.difficulty_limits[difficulty]
next_url = request.form.get('next')
if next_url:
return redirect(next_url)
return redirect(url_for('user_rules'))
@self.flask_app.route('/submit_guess', methods=['POST'])
def submit_guess():
if self.game_over or self.pending_round is not None:
return jsonify({"ok": False, "reason": "not_ready"})
if self.questions_asked == 0:
return jsonify({"ok": False, "reason": "no_questions"})
screen = request.form.get('screen')
if screen not in {"1", "2", "3"}:
return jsonify({"ok": False, "reason": "invalid"})
# First guess
if not hasattr(self, 'first_guess') or self.first_guess is None:
self.first_guess = screen
return jsonify({"ok": True, "status": "first_guess", "screen": screen})
# Second guess — must be different screen
if screen == self.first_guess:
return jsonify({"ok": False, "reason": "same_screen"})
second_guess = screen
guess1 = self.first_guess
guess2 = second_guess
self.first_guess = None
self.game_over = True
# Check results
role1 = self.screen_assignment[guess1]
role2 = self.screen_assignment[guess2]
correct1 = role1 in ("AI1", "AI2")
correct2 = role2 in ("AI1", "AI2")
if correct1 and correct2:
result = "victory"
elif correct1 or correct2:
result = "partial"
else:
result = "defeat"
# Find human screen
human_screen = [k for k, v in self.screen_assignment.items() if v == "Human"][0]
self.last_result = {
"result": result,
"guess1": guess1,
"guess2": guess2,
"correct1": correct1,
"correct2": correct2,
"human_screen": human_screen
}
return jsonify({"ok": True, "status": "done", "result": result,
"guess1": guess1, "guess2": guess2,
"correct1": correct1, "correct2": correct2,
"human_screen": human_screen})
@self.flask_app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
if username == 'admin':
session['username'] = 'admin'
return redirect(url_for('admin_rules'))
elif username == 'user':
session['username'] = 'user'
return redirect(url_for('user_rules'))
else:
return "Ongeldige gebruikersnaam. Gebruik 'user' of 'admin'."
return render_template('login.html')
@self.flask_app.route('/rules/user')
def user_rules():
return render_template('rules_user.html',
difficulty=self.difficulty,
can_change_settings=self.questions_asked == 0 and self.pending_round is None,
questions_left=max(self.max_questions - self.questions_asked, 0),
max_questions=self.max_questions,
game_over=self.game_over)
@self.flask_app.route('/rules/admin')
def admin_rules():
return render_template('rules_admin.html',
difficulty=self.difficulty,
can_change_settings=self.questions_asked == 0 and self.pending_round is None,
questions_left=max(self.max_questions - self.questions_asked, 0),
max_questions=self.max_questions,
game_over=self.game_over)
@self.flask_app.route('/logout')
def logout():
session.clear()
return redirect(url_for('login'))
@self.flask_app.route('/')
def index():
return render_template('index.html')
@self.flask_app.route('/check_refresh')
def check_refresh():
global refresh_needed
return jsonify({"refresh_needed": refresh_needed})
@self.flask_app.route('/reset_refresh', methods=['POST'])
def reset_refresh():
global refresh_needed
refresh_needed = False
return '', 204
@self.flask_app.route('/get_game_state', methods=['GET'])
def get_game_state():
screen_history = {"1": [], "2": [], "3": []}
screen_current = {"1": "Nog geen reacties.", "2": "Nog geen reacties.", "3": "Nog geen reacties."}
for round_item in self.rounds:
for screen_num, role in self.screen_assignment.items():
if role == "Human":
answer = round_item["human_response"]
elif role == "AI1":
answer = round_item["ai_options"][0]["content"] if round_item["ai_options"] else ""
else: # AI2
answer = round_item["ai_options"][1]["content"] if len(round_item["ai_options"]) > 1 else ""
screen_history[screen_num].append({
"question": round_item["question"],
"answer": answer
})
for screen_num in ["1", "2", "3"]:
if screen_history[screen_num]:
screen_current[screen_num] = screen_history[screen_num][-1]["answer"]
questions_left = max(self.max_questions - self.questions_asked, 0)
pending = self.pending_round is not None
return jsonify({
"current": screen_current,
"history": screen_history,
"questions_left": questions_left,
"questions_asked": self.questions_asked,
"max_questions": self.max_questions,
"pending": pending,
"game_over": self.game_over,
"result": self.last_result,
"can_ask": (not self.game_over) and (not pending) and (self.questions_asked < self.max_questions),
"can_guess": (not self.game_over) and (not pending) and (self.questions_asked > 0),
"ready_to_guess": (not self.game_over) and (not pending) and (self.questions_asked >= self.max_questions),
"first_guess": self.first_guess if hasattr(self, 'first_guess') else None
})
@self.flask_app.route('/get_admin_state', methods=['GET'])
def get_admin_state():
return jsonify({
"pending_round": self.pending_round,
"rounds": self.rounds,
"discarded": self.discarded_ai_responses,
"questions_left": max(self.max_questions - self.questions_asked, 0),
"max_questions": self.max_questions,
"difficulty": self.difficulty,
"screen_assignment": self.screen_assignment,
"can_change_settings": self.questions_asked == 0 and self.pending_round is None
})
self.routes_registered = True
if __name__ == '__main__':
agent_1 = GroqAgent(PERSONALITY_PROMPTS["vriendelijke_ouder"])
agent_2 = GroqAgent(PERSONALITY_PROMPTS["grappige_ouder"])
admin = None
agents = [admin, agent_1, agent_2]
refresh_needed = False
app = FlaskApp(agents)
app.flask_app.run(debug=True)