Spaces:
Runtime error
Runtime error
Commit
·
520c904
1
Parent(s):
0974473
resolved random issue
Browse files- app.py +20 -25
- middle_earth_adventure/constants.py +4 -7
- middle_earth_adventure/game_core.py +14 -10
- middle_earth_adventure/prompts.py +2 -1
- middle_earth_adventure/schemas.py +0 -1
- middle_earth_adventure/utils.py +10 -3
app.py
CHANGED
@@ -20,7 +20,7 @@ if "text_area_value" not in st.session_state:
|
|
20 |
if "player" not in st.session_state:
|
21 |
st.session_state.player = None
|
22 |
if "tech_specs" not in st.session_state:
|
23 |
-
st.session_state.tech_specs = TechSpecs(narrator_voice="nova", image_model="",
|
24 |
if "image" not in st.session_state:
|
25 |
st.session_state.image = "resources/intro.jpg"
|
26 |
if "narrator_audio"not in st.session_state:
|
@@ -61,7 +61,7 @@ async def progress_game(text_to_write, selection=None, start=False):
|
|
61 |
|
62 |
# Text to image generation
|
63 |
prompt = IMAGE_PROMPT.format(narration=narration_txt, response_format='b64_json',name=name, sex=sex, type=character_type)
|
64 |
-
image_url = await game.generate_picture_of_the_adventure(prompt, tech_specs.image_model
|
65 |
st.session_state.image = image_url
|
66 |
|
67 |
# Re-run to update states
|
@@ -76,34 +76,29 @@ default_skills = pick_rand_items(ALL_SKILLS, 2)
|
|
76 |
# Title
|
77 |
st.title("Middle Earth Adventures")
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
# Character Selection
|
89 |
-
with st.expander("Character Selection", expanded=True):
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
else:
|
97 |
-
final_selection = character_type
|
98 |
-
sex = st.radio("Gender", ["she", "he"], index=0)
|
99 |
-
skills = st.multiselect("Skills (pick 2)", ALL_SKILLS, max_selections=2, help="")
|
100 |
-
if st.button("Create Character", use_container_width=True):
|
101 |
# write player
|
102 |
player = Player(name=name, type=character_type, sex=sex, skills=skills)
|
103 |
st.session_state.player = player
|
104 |
# write tech-specs
|
105 |
tech_specs = TechSpecs(narrator_voice=narrator_voice, image_model=image_model,
|
106 |
-
|
107 |
st.session_state.tech_specs = tech_specs
|
108 |
# start adventure
|
109 |
message = f"You are {name}, {sex} is a {character_type}. Your are good at {' and '.join(skills)}"
|
|
|
20 |
if "player" not in st.session_state:
|
21 |
st.session_state.player = None
|
22 |
if "tech_specs" not in st.session_state:
|
23 |
+
st.session_state.tech_specs = TechSpecs(narrator_voice="nova", image_model="", game_lenght=0)
|
24 |
if "image" not in st.session_state:
|
25 |
st.session_state.image = "resources/intro.jpg"
|
26 |
if "narrator_audio"not in st.session_state:
|
|
|
61 |
|
62 |
# Text to image generation
|
63 |
prompt = IMAGE_PROMPT.format(narration=narration_txt, response_format='b64_json',name=name, sex=sex, type=character_type)
|
64 |
+
image_url = await game.generate_picture_of_the_adventure(prompt, tech_specs.image_model)
|
65 |
st.session_state.image = image_url
|
66 |
|
67 |
# Re-run to update states
|
|
|
76 |
# Title
|
77 |
st.title("Middle Earth Adventures")
|
78 |
|
79 |
+
|
80 |
+
# Character and Game Selection
|
81 |
+
with st.form("selection_form"):
|
82 |
+
# Tech Specs
|
83 |
+
with st.expander("Technical Specs", expanded=False):
|
84 |
+
narrator_voice = st.radio("Narrator's Voice", ["nova", "echo"], index=0)
|
85 |
+
image_model = st.radio("Image Model", ['dall-e-2', 'dall-e-3'], index=1)
|
86 |
+
game_lenght = st.selectbox("Game Lenght (nr of conversation turns)", [5, 7, 10, 15, 20], index=2)
|
87 |
+
|
88 |
+
# Character Selection
|
89 |
+
with st.expander("Character Selection", expanded=True):
|
90 |
+
name = st.text_input("Name", value=default_name)
|
91 |
+
character_type = st.selectbox("Type", ALL_TYPES, index=default_type)
|
92 |
+
sex = st.radio("Gender", ["she", "he"], index=0)
|
93 |
+
skills = st.multiselect("Skills (pick 2)", ALL_SKILLS, max_selections=2, help="")
|
94 |
+
submit_button = st.form_submit_button("Create Character", use_container_width=True)
|
95 |
+
if submit_button:
|
|
|
|
|
|
|
|
|
|
|
96 |
# write player
|
97 |
player = Player(name=name, type=character_type, sex=sex, skills=skills)
|
98 |
st.session_state.player = player
|
99 |
# write tech-specs
|
100 |
tech_specs = TechSpecs(narrator_voice=narrator_voice, image_model=image_model,
|
101 |
+
game_lenght=game_lenght)
|
102 |
st.session_state.tech_specs = tech_specs
|
103 |
# start adventure
|
104 |
message = f"You are {name}, {sex} is a {character_type}. Your are good at {' and '.join(skills)}"
|
middle_earth_adventure/constants.py
CHANGED
@@ -14,15 +14,12 @@ OPENAI_KEY = os.environ.get("OPENAI_PERSONAL_KEY")
|
|
14 |
|
15 |
# Character
|
16 |
ALL_SKILLS = ["Speed", "Carisma", "Intelligence", "Force", "Deceit", "Perception", "Stealth", "Creativity", "Dexterity", "Vision"]
|
17 |
-
ALL_TYPES = ["Warrior", "Wizard's Apprentice", "Mystical Feline", "Beautiful Ghost", "Naive Wood Elf", "Oktoberfest Peasant"
|
18 |
ALL_NAMES = ["Kim", "Gearld", "Yoyo", "Jojee"]
|
19 |
|
20 |
# Game variability
|
21 |
PLAYER_FEELINGS = ["scared", "anxious", "hopeful", "intrigued", "naive"]
|
22 |
RIDDLE_OPTIONS = ["greek-inspired", "old-fashion", "funny", "fancy sounding", "human-centered", "animal-inspired"]
|
23 |
-
FIGHT_OPTIONS = ["funny", "epic", "magical", "gothic", "
|
24 |
-
ROMANCE_OPTIONS = ["
|
25 |
-
|
26 |
-
"(give me a {opt} riddle)".format(opt=" and ".join(pick_rand_items(RIDDLE_OPTIONS, nr=2))),
|
27 |
-
"(give me {opt} romance)".format(opt=" and ".join(pick_rand_items(ROMANCE_OPTIONS, nr=2))),
|
28 |
-
"(add an epic building)"]
|
|
|
14 |
|
15 |
# Character
|
16 |
ALL_SKILLS = ["Speed", "Carisma", "Intelligence", "Force", "Deceit", "Perception", "Stealth", "Creativity", "Dexterity", "Vision"]
|
17 |
+
ALL_TYPES = ["Warrior", "Wizard's Apprentice", "Mystical Feline", "Beautiful Ghost", "Naive Wood Elf", "Oktoberfest Peasant"]
|
18 |
ALL_NAMES = ["Kim", "Gearld", "Yoyo", "Jojee"]
|
19 |
|
20 |
# Game variability
|
21 |
PLAYER_FEELINGS = ["scared", "anxious", "hopeful", "intrigued", "naive"]
|
22 |
RIDDLE_OPTIONS = ["greek-inspired", "old-fashion", "funny", "fancy sounding", "human-centered", "animal-inspired"]
|
23 |
+
FIGHT_OPTIONS = ["funny", "epic", "magical", "gothic", "danger", "mystical", "scary"]
|
24 |
+
ROMANCE_OPTIONS = ["mystic", "dramatic", "adventurous", "loyal"]
|
25 |
+
|
|
|
|
|
|
middle_earth_adventure/game_core.py
CHANGED
@@ -3,14 +3,13 @@ import random
|
|
3 |
import time
|
4 |
from openai import OpenAI
|
5 |
from dotenv import load_dotenv
|
6 |
-
from middle_earth_adventure.constants import
|
7 |
from middle_earth_adventure.prompts import FINISH_PROMPT, SYSTEM_PROMPT, START_PROMPT, CONTINUE_PROMPT
|
8 |
-
from middle_earth_adventure.utils import
|
9 |
from middle_earth_adventure.schemas import Player
|
10 |
|
11 |
load_dotenv()
|
12 |
|
13 |
-
|
14 |
class GameCore:
|
15 |
|
16 |
def __init__(self, api_key:str, text_model:str, tts_model: str) -> None:
|
@@ -38,11 +37,8 @@ class GameCore:
|
|
38 |
# Continue Adventure
|
39 |
async def continue_adventure(self, selection: str, player: Player):
|
40 |
if player is None: return None
|
41 |
-
|
42 |
-
variants
|
43 |
-
feeling = random.choice(PLAYER_FEELINGS)
|
44 |
-
print('variants=', variants)
|
45 |
-
print('seed=', variants)
|
46 |
message= {"role": "user", "content": CONTINUE_PROMPT.format(selection=selection, feeling=feeling, variants=variants)}
|
47 |
|
48 |
ai_response = self.client.chat.completions.create(messages=[*self.message_history, message], model=self.text_model)
|
@@ -74,9 +70,17 @@ class GameCore:
|
|
74 |
# audio_base64 = base64.b64encode(mp3_narration).decode('utf-8')
|
75 |
return mp3_narration
|
76 |
|
77 |
-
async def generate_picture_of_the_adventure(self, prompt, model
|
78 |
if model == "dall-e-2": size = "512x512"
|
79 |
if model == "dall-e-3": size = "1024x1024"
|
80 |
image = self.client.images.generate(model=model, prompt=prompt, response_format='url',
|
81 |
-
size=size, quality=
|
82 |
return (image.data[0].url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
import time
|
4 |
from openai import OpenAI
|
5 |
from dotenv import load_dotenv
|
6 |
+
from middle_earth_adventure.constants import FIGHT_OPTIONS, PLAYER_FEELINGS, RIDDLE_OPTIONS, ROMANCE_OPTIONS
|
7 |
from middle_earth_adventure.prompts import FINISH_PROMPT, SYSTEM_PROMPT, START_PROMPT, CONTINUE_PROMPT
|
8 |
+
from middle_earth_adventure.utils import pick_rand_items
|
9 |
from middle_earth_adventure.schemas import Player
|
10 |
|
11 |
load_dotenv()
|
12 |
|
|
|
13 |
class GameCore:
|
14 |
|
15 |
def __init__(self, api_key:str, text_model:str, tts_model: str) -> None:
|
|
|
37 |
# Continue Adventure
|
38 |
async def continue_adventure(self, selection: str, player: Player):
|
39 |
if player is None: return None
|
40 |
+
variants, feeling = self.get_game_variations()
|
41 |
+
print('variants=', str(variants))
|
|
|
|
|
|
|
42 |
message= {"role": "user", "content": CONTINUE_PROMPT.format(selection=selection, feeling=feeling, variants=variants)}
|
43 |
|
44 |
ai_response = self.client.chat.completions.create(messages=[*self.message_history, message], model=self.text_model)
|
|
|
70 |
# audio_base64 = base64.b64encode(mp3_narration).decode('utf-8')
|
71 |
return mp3_narration
|
72 |
|
73 |
+
async def generate_picture_of_the_adventure(self, prompt, model):
|
74 |
if model == "dall-e-2": size = "512x512"
|
75 |
if model == "dall-e-3": size = "1024x1024"
|
76 |
image = self.client.images.generate(model=model, prompt=prompt, response_format='url',
|
77 |
+
size=size, quality="standard", n=1)
|
78 |
return (image.data[0].url)
|
79 |
+
|
80 |
+
def get_game_variations(self):
|
81 |
+
story_variants = ["(give me a {opt} fight)".format(opt=" and ".join(random.sample(FIGHT_OPTIONS, 2))),
|
82 |
+
"(give me a {opt} riddle)".format(opt=" and ".join(random.sample(RIDDLE_OPTIONS, 2))),
|
83 |
+
"(give me an {opt} character encounter)".format(opt=" and ".join(random.sample(ROMANCE_OPTIONS, 2))),
|
84 |
+
"(add an epic building)"]
|
85 |
+
feeling = random.choice(PLAYER_FEELINGS)
|
86 |
+
return random.choice(story_variants), random.choice(feeling)
|
middle_earth_adventure/prompts.py
CHANGED
@@ -39,5 +39,6 @@ Scenic context:
|
|
39 |
{narration}
|
40 |
|
41 |
Hero ({sex} is a 25 year old dutch {type}) and the landscape/situation {sex} is involved are clearly depicted.
|
42 |
-
Background is the middle-earth. No text.
|
|
|
43 |
"""
|
|
|
39 |
{narration}
|
40 |
|
41 |
Hero ({sex} is a 25 year old dutch {type}) and the landscape/situation {sex} is involved are clearly depicted.
|
42 |
+
Background is the middle-earth. No text.
|
43 |
+
I NEED to test how the tool works with extremely simple prompts. DO NOT add any detail, just use it AS-IS.
|
44 |
"""
|
middle_earth_adventure/schemas.py
CHANGED
@@ -15,5 +15,4 @@ class Player(BaseModel):
|
|
15 |
class TechSpecs(BaseModel):
|
16 |
narrator_voice: str
|
17 |
image_model: str
|
18 |
-
image_quality: str
|
19 |
game_lenght: int
|
|
|
15 |
class TechSpecs(BaseModel):
|
16 |
narrator_voice: str
|
17 |
image_model: str
|
|
|
18 |
game_lenght: int
|
middle_earth_adventure/utils.py
CHANGED
@@ -2,7 +2,7 @@ import streamlit as st
|
|
2 |
import random
|
3 |
import numpy as np
|
4 |
import base64
|
5 |
-
|
6 |
from middle_earth_adventure.schemas import Player
|
7 |
|
8 |
def check_valid_player(player: Player):
|
@@ -11,12 +11,19 @@ def check_valid_player(player: Player):
|
|
11 |
return False
|
12 |
return True
|
13 |
|
|
|
|
|
|
|
|
|
|
|
14 |
def pick_rand_index(list_to_pick: list):
|
15 |
-
|
|
|
16 |
return index
|
17 |
|
18 |
def pick_rand_items(list_to_pick: list, nr=2):
|
19 |
-
|
|
|
20 |
return random.sample(list_to_pick, nr)
|
21 |
|
22 |
def are_all_options_are_filled(player, name, character_type, sex, skills):
|
|
|
2 |
import random
|
3 |
import numpy as np
|
4 |
import base64
|
5 |
+
import time
|
6 |
from middle_earth_adventure.schemas import Player
|
7 |
|
8 |
def check_valid_player(player: Player):
|
|
|
11 |
return False
|
12 |
return True
|
13 |
|
14 |
+
def get_rand_number():
|
15 |
+
seed = time.time()
|
16 |
+
random.seed(seed)
|
17 |
+
return random.random(), seed
|
18 |
+
|
19 |
def pick_rand_index(list_to_pick: list):
|
20 |
+
rand_nr, _ = get_rand_number()
|
21 |
+
index = int(np.floor(rand_nr*len(list_to_pick)))
|
22 |
return index
|
23 |
|
24 |
def pick_rand_items(list_to_pick: list, nr=2):
|
25 |
+
_, seed = get_rand_number()
|
26 |
+
random.seed(seed)
|
27 |
return random.sample(list_to_pick, nr)
|
28 |
|
29 |
def are_all_options_are_filled(player, name, character_type, sex, skills):
|