|
|
|
import random |
|
import time |
|
from openai import OpenAI |
|
from dotenv import load_dotenv |
|
from middle_earth_adventure.constants import FIGHT_OPTIONS, PLAYER_FEELINGS, RIDDLE_OPTIONS, ROMANCE_OPTIONS |
|
from middle_earth_adventure.prompts import FINISH_PROMPT, SYSTEM_PROMPT, START_PROMPT, CONTINUE_PROMPT |
|
from middle_earth_adventure.utils import pick_rand_items |
|
from middle_earth_adventure.schemas import Player |
|
|
|
load_dotenv() |
|
|
|
class GameCore: |
|
|
|
def __init__(self, api_key:str, text_model:str, tts_model: str) -> None: |
|
self.client = OpenAI(api_key=api_key) |
|
self.text_model = text_model |
|
self.tts_model = tts_model |
|
self.message_history = [] |
|
|
|
|
|
async def start_adventure(self, player: Player): |
|
if player is None: return None |
|
self.message_history = [] |
|
messages=[ |
|
{"role": "system", "content": SYSTEM_PROMPT}, |
|
{"role": "user", "content": START_PROMPT.format(name=player.name, sex=player.sex, type=player.type, |
|
skill1=player.skills[0], skill2=player.skills[1])} |
|
] |
|
ai_response = self.client.chat.completions.create(messages=messages, model=self.text_model) |
|
ai_response = ai_response.choices[0].to_dict()["message"] |
|
|
|
self.message_history += messages |
|
self.message_history.append(ai_response) |
|
return ai_response['content'] |
|
|
|
|
|
async def continue_adventure(self, selection: str, player: Player): |
|
if player is None: return None |
|
variants, feeling = self.get_game_variations() |
|
print('variants=', str(variants)) |
|
message= {"role": "user", "content": CONTINUE_PROMPT.format(selection=selection, feeling=feeling, variants=variants)} |
|
|
|
ai_response = self.client.chat.completions.create(messages=[*self.message_history, message], model=self.text_model) |
|
ai_response = ai_response.choices[0].to_dict()["message"] |
|
|
|
self.message_history.append(message) |
|
self.message_history.append(ai_response) |
|
return ai_response['content'] |
|
|
|
async def finish_adventure(self, player, selection): |
|
if player is None: return None |
|
message= {"role": "user", "content": FINISH_PROMPT.format(selection=selection)} |
|
|
|
ai_response = self.client.chat.completions.create(messages=[*self.message_history, message], |
|
model=self.text_model, |
|
frequency_penalty=1.0, |
|
temperature=1.7, |
|
max_tokens=100, |
|
) |
|
ai_response = ai_response.choices[0].to_dict()["message"] |
|
|
|
self.message_history.append(message) |
|
self.message_history.append(ai_response) |
|
return ai_response['content'] |
|
|
|
async def narrate_adventure_out_loud(self, text: str, narrator_voice: str): |
|
mp3_narration = self.client.audio.speech.create(model=self.tts_model, voice=narrator_voice, input=text) |
|
mp3_narration = mp3_narration.content |
|
|
|
return mp3_narration |
|
|
|
async def generate_picture_of_the_adventure(self, prompt, model): |
|
if model == "dall-e-2": size = "512x512" |
|
if model == "dall-e-3": size = "1024x1024" |
|
image = self.client.images.generate(model=model, prompt=prompt, response_format='url', |
|
size=size, quality="standard", n=1) |
|
return (image.data[0].url) |
|
|
|
def get_game_variations(self): |
|
story_variants = ["(give me a {opt} fight)".format(opt=" and ".join(random.sample(FIGHT_OPTIONS, 2))), |
|
"(give me a {opt} riddle)".format(opt=" and ".join(random.sample(RIDDLE_OPTIONS, 2))), |
|
"(give me an {opt} character encounter)".format(opt=" and ".join(random.sample(ROMANCE_OPTIONS, 2))), |
|
"(add an epic building)"] |
|
feeling = random.choice(PLAYER_FEELINGS) |
|
return random.choice(story_variants), random.choice(feeling) |
|
|