woot upgraded guarded to support odds-or-evens game.
modified: ../app.py new file: activity22-odds-or-evens.yaml modified: guarded_ai.py
This commit is contained in:
parent
3902ff48da
commit
14dd105d03
3 changed files with 174 additions and 14 deletions
20
app.py
20
app.py
|
|
@ -2045,6 +2045,17 @@ def display_activity_metadata(room_name, username):
|
|||
)
|
||||
|
||||
|
||||
def execute_processing_script(metadata, script):
|
||||
# Prepare the local environment for the script
|
||||
local_env = {"metadata": metadata, "script_result": None}
|
||||
|
||||
# Execute the script
|
||||
exec(script, {}, local_env)
|
||||
|
||||
# Return the result from the script
|
||||
return local_env["script_result"]
|
||||
|
||||
|
||||
def handle_activity_response(room_name, user_response, username):
|
||||
with app.app_context():
|
||||
room = get_room(room_name)
|
||||
|
|
@ -2230,6 +2241,15 @@ def handle_activity_response(room_name, user_response, username):
|
|||
metadata_tmp_keys.append(random_key)
|
||||
activity_state.add_metadata(random_key, random_value)
|
||||
|
||||
# Execute the processing script if it exists
|
||||
if "processing_script" in step:
|
||||
result = execute_processing_script(
|
||||
activity_state.dict_metadata, step["processing_script"]
|
||||
)
|
||||
# Add the result to the temporary metadata for use in AI feedback
|
||||
metadata_tmp_keys.append("processing_script_result")
|
||||
activity_state.add_metadata("processing_script_result", result)
|
||||
|
||||
print(activity_state.dict_metadata)
|
||||
|
||||
# Commit the changes after the loop
|
||||
|
|
|
|||
101
research/activity22-odds-or-evens.yaml
Normal file
101
research/activity22-odds-or-evens.yaml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
default_max_attempts_per_step: 30
|
||||
sections:
|
||||
- section_id: "section_1"
|
||||
title: "Odds and Evens with History"
|
||||
steps:
|
||||
|
||||
- step_id: "step_0"
|
||||
title: "Challenge a Historical Figure"
|
||||
content_blocks:
|
||||
- "Welcome to the Odds and Evens challenge! 🎮"
|
||||
- "You will be playing against a random historical figure."
|
||||
|
||||
- step_id: "step_1"
|
||||
title: "Throw Your Fingers"
|
||||
tokens_for_ai: |
|
||||
Careful to check if user is trying to 'set_language' and do that first. Otherwise, figure out if they are picking a number between 0 and 5.
|
||||
feedback_tokens_for_ai: |
|
||||
Important, you do not have to calculate the winner, we have
|
||||
under processing_script_result for you that determines the winner.
|
||||
|
||||
Important, you do not pick a random move, it was selected for you:
|
||||
|
||||
* 'ai_choice_finger': it's your number of fingers up that you will announce to the user.
|
||||
* 'ai_choice': it's your guess of odd or even that you will announce to the user.
|
||||
|
||||
Speaking in first person as a historical figure, first always announce the move
|
||||
selected for you and then move to a new line.
|
||||
|
||||
The rules are simple, the processing_script_result to determines winner or tie.
|
||||
|
||||
* Sum the numbers.
|
||||
* If the sum of the fingers is even, the player who chose "even" wins.
|
||||
* If the sum is odd, the player who chose "odd" wins.
|
||||
* If both players are wrong or right about "odd" or "even" it's a tie.
|
||||
* A user cannot win unless they have a match with the game name "odd" or "even"
|
||||
|
||||
Careful it's easy to add wrong or say a number is odd when it's even and vice versa.
|
||||
|
||||
Finally, continue to provide a witty fact as the figure. Don't ever mention AI.
|
||||
The figure should also comment on the 'attempts' number and how many times played!
|
||||
If you feel like it, jeer at the player about an early 'exit' & suggest they quit.
|
||||
|
||||
processing_script: |
|
||||
user_input = metadata["user_choice"].split()
|
||||
user_fingers = None
|
||||
user_choice = None
|
||||
for item in user_input:
|
||||
if item.isdigit():
|
||||
user_fingers = int(item)
|
||||
elif item in ["odd", "even"]:
|
||||
user_choice = item
|
||||
ai_fingers = int(metadata["ai_choice_finger"]) # Ensure ai_fingers is an integer
|
||||
ai_choice = metadata["ai_choice"]
|
||||
total_fingers = user_fingers + ai_fingers
|
||||
result = "even" if total_fingers % 2 == 0 else "odd"
|
||||
user_wins = (result == user_choice)
|
||||
ai_wins = (result == ai_choice)
|
||||
if user_wins and not ai_wins:
|
||||
winner = "User wins!"
|
||||
elif ai_wins and not user_wins:
|
||||
winner = "AI wins!"
|
||||
else:
|
||||
winner = "It's a tie!"
|
||||
script_result = {"sum": total_fingers, "result": result, "winner": winner}
|
||||
|
||||
question: "How many fingers do you throw? (Choose a number between 0 and 5 & either even or odd.) 🤔"
|
||||
buckets:
|
||||
- throw_fingers
|
||||
- set_language
|
||||
- exit
|
||||
transitions:
|
||||
throw_fingers:
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Declare your move and then determine who wins the game and provide a witty fact from the historical figure's perspective."
|
||||
metadata_add:
|
||||
attempts: "n+1"
|
||||
metadata_tmp_add:
|
||||
user_choice: "the-users-response"
|
||||
ai_choice_finger: "n+random(0,5)"
|
||||
metadata_tmp_random:
|
||||
ai_choice: odd
|
||||
ai_choice: even
|
||||
next_section_and_step: "section_1:step_1"
|
||||
set_language:
|
||||
content_blocks:
|
||||
- "Language preference updated. Please continue in your preferred language."
|
||||
ai_feedback:
|
||||
tokens_for_ai: "Acknowledge the language change and confirm the update."
|
||||
metadata_add:
|
||||
language: "the-users-response"
|
||||
counts_as_attempt: false
|
||||
exit:
|
||||
next_section_and_step: "section_2:step_1"
|
||||
|
||||
- section_id: "section_2"
|
||||
title: "Goodbye"
|
||||
steps:
|
||||
- step_id: "step_1"
|
||||
title: "Exit"
|
||||
content_blocks:
|
||||
- "Thank you for playing! We hope you enjoyed the game. Have a great day! 🌟"
|
||||
|
|
@ -43,7 +43,7 @@ def categorize_response(question, response, buckets, tokens_for_ai):
|
|||
|
||||
|
||||
# Generate AI feedback using gpt-4o-mini
|
||||
def generate_ai_feedback(category, question, user_response, tokens_for_ai):
|
||||
def generate_ai_feedback(category, question, user_response, tokens_for_ai, metadata):
|
||||
messages = [
|
||||
{
|
||||
"role": "system",
|
||||
|
|
@ -51,7 +51,7 @@ def generate_ai_feedback(category, question, user_response, tokens_for_ai):
|
|||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"Question: {question}\nResponse: {user_response}\nCategory: {category}",
|
||||
"content": f"Question: {question}\nResponse: {user_response}\nCategory: {category},\nMetadata: {metadata}",
|
||||
},
|
||||
]
|
||||
|
||||
|
|
@ -67,19 +67,36 @@ def generate_ai_feedback(category, question, user_response, tokens_for_ai):
|
|||
|
||||
# Provide feedback based on the category
|
||||
def provide_feedback(
|
||||
transition, category, question, user_response, user_language, tokens_for_ai
|
||||
transition,
|
||||
category,
|
||||
question,
|
||||
user_response,
|
||||
user_language,
|
||||
tokens_for_ai,
|
||||
metadata,
|
||||
):
|
||||
feedback = ""
|
||||
if "ai_feedback" in transition:
|
||||
tokens_for_ai += f" Provide the feedback in {user_language}. {transition['ai_feedback'].get('tokens_for_ai', '')}."
|
||||
ai_feedback = generate_ai_feedback(
|
||||
category, question, user_response, tokens_for_ai
|
||||
category, question, user_response, tokens_for_ai, metadata
|
||||
)
|
||||
feedback += f"\n\nAI Feedback: {ai_feedback}"
|
||||
|
||||
return feedback
|
||||
|
||||
|
||||
def execute_processing_script(metadata, script):
|
||||
# Prepare the local environment for the script
|
||||
local_env = {"metadata": metadata, "script_result": None}
|
||||
|
||||
# Execute the script
|
||||
exec(script, {}, local_env)
|
||||
|
||||
# Return the result from the script
|
||||
return local_env["script_result"]
|
||||
|
||||
|
||||
def get_next_section_and_step(activity_content, current_section_id, current_step_id):
|
||||
for section in activity_content["sections"]:
|
||||
if section["section_id"] == current_section_id:
|
||||
|
|
@ -208,16 +225,6 @@ def simulate_activity(yaml_file_path):
|
|||
)
|
||||
print(translated_transition_content)
|
||||
|
||||
feedback = provide_feedback(
|
||||
transition,
|
||||
category,
|
||||
question,
|
||||
user_response,
|
||||
user_language,
|
||||
step["tokens_for_ai"],
|
||||
)
|
||||
print(f"\nFeedback: {feedback}")
|
||||
|
||||
# Track temporary metadata keys
|
||||
metadata_tmp_keys = []
|
||||
|
||||
|
|
@ -246,6 +253,20 @@ def simulate_activity(yaml_file_path):
|
|||
for key, value in transition["metadata_tmp_add"].items():
|
||||
if value == "the-users-response":
|
||||
value = user_response
|
||||
elif isinstance(value, str):
|
||||
if value.startswith("n+random(") and value.endswith(")"):
|
||||
# Extract the range and apply the random increment
|
||||
range_values = value[9:-1].split(",")
|
||||
if len(range_values) == 2:
|
||||
x, y = map(int, range_values)
|
||||
value = random.randint(x, y)
|
||||
elif value.startswith("n+") or value.startswith("n-"):
|
||||
# Extract the numeric part c and apply the operation +/-
|
||||
c = int(value[1:])
|
||||
if value.startswith("n+"):
|
||||
value = metadata.get(key, 0) + c
|
||||
elif value.startswith("n-"):
|
||||
value = metadata.get(key, 0) - c
|
||||
metadata[key] = value
|
||||
metadata_tmp_keys.append(key) # Track temporary keys
|
||||
|
||||
|
|
@ -268,8 +289,26 @@ def simulate_activity(yaml_file_path):
|
|||
metadata[random_key] = random_value
|
||||
metadata_tmp_keys.append(random_key) # Track temporary keys
|
||||
|
||||
# Execute the processing script if it exists
|
||||
if "processing_script" in step:
|
||||
result = execute_processing_script(metadata, step["processing_script"])
|
||||
metadata["processing_script_result"] = result
|
||||
metadata_tmp_keys.append("processing_script_result")
|
||||
|
||||
print(f"\nMetadata: {json.dumps(metadata, indent=2)}")
|
||||
|
||||
# Provide feedback based on the category
|
||||
feedback = provide_feedback(
|
||||
transition,
|
||||
category,
|
||||
question,
|
||||
user_response,
|
||||
user_language,
|
||||
step.get("feedback_tokens_for_ai", ""),
|
||||
metadata,
|
||||
)
|
||||
print(f"\nFeedback: {feedback}")
|
||||
|
||||
if category not in [
|
||||
"partial_understanding",
|
||||
"limited_effort",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue