metadata_random is a new way to randomly assign metadata when a play

reaches this category.

	modified:   app.py
	modified:   research/activity17-choose-adventure.yaml
This commit is contained in:
Russell Ballestrini 2024-08-04 15:15:42 -04:00
parent 1ff5a364d3
commit b4684a8e6d
2 changed files with 214 additions and 81 deletions

79
app.py
View file

@ -11,6 +11,8 @@ import json
import yaml
import os
import random
import boto3
import tiktoken
import together
@ -2015,6 +2017,36 @@ def handle_activity_response(room_name, user_response, username):
)
return
# this gives the llm context on what changed.
new_metadata = {}
# Update metadata based on user actions
if "metadata_add" in step["transitions"][category]:
for key, value in step["transitions"][category][
"metadata_add"
].items():
new_metadata[key] = value
activity_state.add_metadata(key, value)
if "metadata_remove" in step["transitions"][category]:
for key in step["transitions"][category]["metadata_remove"]:
activity_state.remove_metadata(key)
# Handle metadata_random
if "metadata_random" in step["transitions"][category]:
random_key = random.choice(
list(step["transitions"][category]["metadata_random"].keys())
)
random_value = step["transitions"][category]["metadata_random"][
random_key
]
new_metadata[random_key] = random_value
activity_state.add_metadata(random_key, random_value)
# Commit the changes after the loop
db.session.add(activity_state)
db.session.commit()
# Provide feedback based on the category
feedback, next_section_and_step = provide_feedback(
activity_content,
@ -2025,6 +2057,7 @@ def handle_activity_response(room_name, user_response, username):
user_response,
username,
activity_state.json_metadata,
json.dumps(new_metadata),
)
# Store and emit the feedback
@ -2066,21 +2099,6 @@ def handle_activity_response(room_name, user_response, username):
room=room_name,
)
# Update metadata based on user actions
if "metadata_add" in step["transitions"][category]:
for key, value in step["transitions"][category][
"metadata_add"
].items():
activity_state.add_metadata(key, value)
if "metadata_remove" in step["transitions"][category]:
for key in step["transitions"][category]["metadata_remove"]:
activity_state.remove_metadata(key)
# Commit the changes after the loop
db.session.add(activity_state)
db.session.commit()
# if "correct" or max_attempts reached.
if (
category
@ -2154,12 +2172,15 @@ def handle_activity_response(room_name, user_response, username):
)
except Exception as e:
import traceback
msg = traceback.format_exc()
socketio.emit(
"message",
{
"id": None,
"username": "System",
"content": f"Error processing activity response: {e}",
"content": f"Error processing activity response: {e}\n\n{msg}",
},
room=room_name,
)
@ -2314,7 +2335,7 @@ def categorize_response(question, response, buckets, tokens_for_ai):
completion = openai_client.chat.completions.create(
model=model_name,
messages=messages,
max_tokens=5,
max_tokens=10,
temperature=0,
)
category = (
@ -2326,7 +2347,15 @@ def categorize_response(question, response, buckets, tokens_for_ai):
# Generate AI feedback
def generate_ai_feedback(category, question, user_response, tokens_for_ai, username, json_metadata):
def generate_ai_feedback(
category,
question,
user_response,
tokens_for_ai,
username,
json_metadata,
json_new_metadata,
):
openai_client, model_name = get_openai_client_and_model()
messages = [
{
@ -2335,7 +2364,7 @@ def generate_ai_feedback(category, question, user_response, tokens_for_ai, usern
},
{
"role": "user",
"content": f"Username: {username}\nQuestion: {question}\nResponse: {user_response}\nCategory: {category}\nMetadata: {json_metadata}",
"content": f"Username: {username}\nQuestion: {question}\nResponse: {user_response}\nCategory: {category}\nMetadata: {json_metadata}\n New Metadata: {json_new_metadata}",
},
]
@ -2350,7 +2379,15 @@ def generate_ai_feedback(category, question, user_response, tokens_for_ai, usern
def provide_feedback(
yaml_content, section_id, step_id, category, question, user_response, username, json_metadata
yaml_content,
section_id,
step_id,
category,
question,
user_response,
username,
json_metadata,
json_new_metadata,
):
section = next(
(s for s in yaml_content["sections"] if s["section_id"] == section_id), None
@ -2372,7 +2409,7 @@ def provide_feedback(
step["tokens_for_ai"] + " " + transition["ai_feedback"]["tokens_for_ai"]
)
ai_feedback = generate_ai_feedback(
category, question, user_response, tokens_for_ai, username, json_metadata
category, question, user_response, tokens_for_ai, username, json_metadata, json_new_metadata,
)
feedback += f"\n\nAI Feedback: {ai_feedback}"

View file

@ -12,81 +12,39 @@ sections:
content_blocks:
- "You have entered the prize room! 🎁"
- "A prize is randomly selected for you from the room."
tokens_for_ai: "Randomly select one of the following items as the user's prize. DO NOT select go_back unless you are sure the user wants to go back to the temple pit."
- "You can also go to the temple pit from here."
tokens_for_ai: "DO NOT select go_back unless the users says 'go back' in their message."
question: "You have received a prize! Guess what it could be? 🤔"
buckets:
- prize_1
- prize_2
- prize_3
- prize_4
- prize_5
- prize_6
- prize_7
- prize_8
- prize_9
- prize_10
- random_prize_guess
- go_to_temple_pit
- go_back
transitions:
prize_1:
random_prize_guess:
ai_feedback:
tokens_for_ai: "cheer for the player, they got a new item. list them all from metadata. now make a joke about their guess!"
content_blocks:
- "You received Prize 1: A golden keychain. 🗝"
next_section_and_step: "section_2:step_1"
metadata_add:
- "You received a random prize! 🎲"
next_section_and_step: "section_1:step_1"
metadata_random:
golden_keychain: true
prize_2:
content_blocks:
- "You received Prize 2: A mysterious amulet. 🧿"
next_section_and_step: "section_2:step_1"
metadata_add:
mysterious_amulet: true
prize_3:
content_blocks:
- "You received Prize 3: A rare gemstone. 💎"
next_section_and_step: "section_2:step_1"
metadata_add:
rare_gemstone: true
prize_4:
content_blocks:
- "You received Prize 4: An ancient scroll. 📜"
next_section_and_step: "section_2:step_1"
metadata_add:
ancient_scroll: true
prize_5:
content_blocks:
- "You received Prize 5: A magical wand. 🪄"
next_section_and_step: "section_2:step_1"
metadata_add:
magical_wand: true
prize_6:
content_blocks:
- "You received Prize 6: A treasure map. 🗺"
next_section_and_step: "section_2:step_1"
metadata_add:
treasure_map: true
prize_7:
content_blocks:
- "You received Prize 7: A silver coin. 🪙"
next_section_and_step: "section_2:step_1"
metadata_add:
silver_coin: true
prize_8:
content_blocks:
- "You received Prize 8: A mystical ring. 💍"
next_section_and_step: "section_2:step_1"
metadata_add:
mystical_ring: true
prize_9:
content_blocks:
- "You received Prize 9: A rare book. 📚"
next_section_and_step: "section_2:step_1"
metadata_add:
rare_book: true
prize_10:
content_blocks:
- "You received Prize 10: A magical potion. 🧪"
next_section_and_step: "section_2:step_1"
metadata_add:
magical_potion: true
shadow_charm: true
flame_charm: true
go_to_temple_pit:
content_blocks:
- "You chose to go to the temple pit room. 🏛"
next_section_and_step: "section_2:step_1"
go_back:
content_blocks:
- "You chose to go back to the temple pit room. 🏛"
@ -113,6 +71,8 @@ sections:
- offer_mystical_ring
- offer_rare_book
- offer_magical_potion
- offer_shadow_charm
- offer_flame_charm
- go_back
- off_topic
transitions:
@ -226,6 +186,24 @@ sections:
golden_keychain: true
metadata_remove:
magical_potion: true
offer_shadow_charm:
metadata_conditions:
shadow_charm: true
metadata_remove:
shadow_charm: true
content_blocks:
- "You offered the Shadow Charm to the god. 🖤"
- "The god summons the Shadow Beast! Prepare for battle!"
next_section_and_step: "section_3:step_1"
offer_flame_charm:
metadata_conditions:
flame_charm: true
metadata_remove:
flame_charm: true
content_blocks:
- "You offered the Flame Charm to the god. 🔥"
- "The god summons the Fire Drake! Prepare for battle!"
next_section_and_step: "section_4:step_1"
go_back:
content_blocks:
- "You chose to go back to the prize room. 🎁"
@ -234,3 +212,121 @@ sections:
ai_feedback:
tokens_for_ai: "Gently guide the user back to the story in a supportive manner. DO NOT ask any questions. Use emojis like 🔄 and 🧭."
next_section_and_step: "section_2:step_1"
- section_id: "section_3"
title: "The Dark Cavern"
steps:
- step_id: "step_1"
title: "Battle the Shadow Beast"
content_blocks:
- "You have entered the Dark Cavern. The air is thick with darkness, and a menacing growl echoes around you."
- "A Shadow Beast emerges from the shadows, ready to attack!"
tokens_for_ai: "Guide the user to choose their action based on their items."
question: "Do you fight the Shadow Beast? (You need the Magical Wand or Mystical Ring to win!)"
buckets:
- fight_with_wand
- fight_with_ring
- flee
transitions:
fight_with_wand:
metadata_conditions:
magical_wand: true
content_blocks:
- "You wield the Magical Wand and unleash a powerful spell!"
- "The Shadow Beast is defeated! You find a Shadow Crystal. 💎"
next_section_and_step: "section_5:step_1"
metadata_add:
shadow_crystal: true
fight_with_ring:
metadata_conditions:
mystical_ring: true
content_blocks:
- "You use the Mystical Ring to channel your inner light!"
- "The Shadow Beast is defeated! You find a Shadow Crystal. 💎"
next_section_and_step: "section_5:step_1"
metadata_add:
shadow_crystal: true
flee:
content_blocks:
- "You attempt to flee, but the Shadow Beast catches you. You have met your end. 💀"
next_section_and_step: "death_ending:step_1"
- section_id: "section_4"
title: "The Fiery Lair"
steps:
- step_id: "step_1"
title: "Battle the Fire Drake"
content_blocks:
- "You have entered the Fiery Lair. The heat is intense, and flames flicker around you."
- "A Fire Drake roars, ready to defend its territory!"
tokens_for_ai: "Guide the user to choose their action based on their items."
question: "Do you fight the Fire Drake? (You need the Treasure Map or Ancient Scroll to win!)"
buckets:
- fight_with_map
- fight_with_scroll
- flee
transitions:
fight_with_map:
metadata_conditions:
treasure_map: true
content_blocks:
- "You use the Treasure Map to find the Drake's weak spot!"
- "The Fire Drake is defeated! You find a Flame Pendant. 🔥"
next_section_and_step: "section_5:step_1"
metadata_add:
flame_pendant: true
fight_with_scroll:
metadata_conditions:
ancient_scroll: true
content_blocks:
- "You read the Ancient Scroll and summon a powerful fire shield!"
- "The Fire Drake is defeated! You find a Flame Pendant. 🔥"
next_section_and_step: "section_5:step_1"
metadata_add:
flame_pendant: true
flee:
content_blocks:
- "You attempt to flee, but the Fire Drake incinerates you. You have met your end. 💀"
next_section_and_step: "death_ending_fire:step_1"
- section_id: "section_5"
title: "The Final Path"
steps:
- step_id: "step_1"
title: "The Final Path"
content_blocks:
- "You have defeated the monster and continue on your journey."
- "You see a path leading to the final destination."
tokens_for_ai: "Guide the user to the final victory."
question: "Do you continue on the path to victory? 🤔"
buckets:
- continue_to_victory
transitions:
continue_to_victory:
content_blocks:
- "You walk down the path and reach the final destination. You are victorious! 🏆"
next_section_and_step: "victory:step_1"
- section_id: "death_ending"
title: "The Abyss of Shadows"
steps:
- step_id: "step_1"
title: "Death Ending"
content_blocks:
- "Game Over."
- section_id: "death_ending_fire"
title: "The Ashen Wastes"
steps:
- step_id: "step_1"
title: "Death Ending"
content_blocks:
- "Game Over."
- section_id: "victory"
title: "Victory"
steps:
- step_id: "step_1"
title: "Victory"
content_blocks:
- "Thank you for playing!"