|
import gradio as gr |
|
import re |
|
import time |
|
import json |
|
import os |
|
import jsonpickle |
|
import configparser |
|
import example_worlds |
|
|
|
from models import get_llm |
|
from prompts import prompt_narrate_current_scene, prompt_world_update, prompt_describe_objective |
|
from huggingface_hub import HfApi |
|
from huggingface_hub import login |
|
|
|
login(os.getenv("HF_key")) |
|
|
|
PATH_GAMELOGS = 'logs' |
|
|
|
|
|
config = configparser.ConfigParser() |
|
config.read('config.ini') |
|
|
|
|
|
language = config['Options']['Language'] |
|
|
|
|
|
reasoning_model_name = config['Models']['ReasoningModel'] |
|
narrative_model_name = config['Models']['NarrativeModel'] |
|
reasoning_model = get_llm(reasoning_model_name) |
|
narrative_model = get_llm(narrative_model_name) |
|
|
|
|
|
timestamp = time.time() |
|
today = time.gmtime(timestamp) |
|
log_filename = f"{today[0]}_{today[1]}_{today[2]}_{str(int(time.time()))[-5:]}.json" |
|
|
|
|
|
def game_loop(message, history): |
|
global last_player_position |
|
global number_of_turns |
|
global game_log_dictionary |
|
|
|
number_of_turns+=1 |
|
game_log_dictionary[number_of_turns] = {} |
|
game_log_dictionary[number_of_turns]["date"] = time.ctime(time.time()) |
|
game_log_dictionary[number_of_turns]["previous_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=False) |
|
game_log_dictionary[number_of_turns]["previous_rendered_world_state"] = world.render_world(language=language) |
|
game_log_dictionary[number_of_turns]["user_input"] = message |
|
|
|
|
|
answer = "" |
|
|
|
|
|
system_msg_update, user_msg_update = prompt_world_update(world.render_world(language=language), message, language=language) |
|
response_update = reasoning_model.prompt_model(system_msg=system_msg_update, user_msg=user_msg_update) |
|
|
|
|
|
print("🛠️ Predicted outcomes of the player input 🛠️") |
|
print(f"> Player input: {message}") |
|
try: |
|
predicted_outcomes = re.sub(r'#([^#]*?)#','',response_update) |
|
print(f"{predicted_outcomes}\n") |
|
game_log_dictionary[number_of_turns]["predicted_outcomes"] = predicted_outcomes |
|
|
|
except Exception as e: |
|
print (f"Error: {e}") |
|
|
|
|
|
world.update(response_update) |
|
game_log_dictionary[number_of_turns]["updated_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=True) |
|
game_log_dictionary[number_of_turns]["updated_rendered_world_state"] = world.render_world(language=language) |
|
|
|
if last_player_position is not world.player.location: |
|
|
|
last_player_position = world.player.location |
|
system_msg_new_scene, user_msg_new_scene = prompt_narrate_current_scene( |
|
world.render_world(language=language), |
|
previous_narrations = world.player.visited_locations[world.player.location.name], |
|
language=language |
|
) |
|
|
|
new_scene_narration = narrative_model.prompt_model(system_msg=system_msg_new_scene, user_msg=user_msg_new_scene) |
|
world.player.visited_locations[world.player.location.name]+=[new_scene_narration] |
|
answer += f"\n{new_scene_narration}\n\n" |
|
else: |
|
|
|
try: |
|
answer+= f"{re.findall(r'#([^#]*?)#',response_update)[0]}\n" |
|
except Exception as e: |
|
print (f"Error: {e}") |
|
|
|
|
|
print(f"\n🌎 World state 🌍\n>Player input: {message}\n{world.render_world(language=language)}\n") |
|
|
|
if world.check_objective(): |
|
if language=='es': |
|
answer += "\n\n🎯¡Completaste el objetivo!" |
|
else: |
|
answer += "\n\n🎯You have completed your quest!" |
|
|
|
game_log_dictionary[number_of_turns]["narration"] = answer |
|
|
|
|
|
with open(os.path.join(PATH_GAMELOGS,log_filename), 'w', encoding='utf-8') as f: |
|
json.dump(game_log_dictionary, f, ensure_ascii=False, indent=4) |
|
|
|
if world.check_objective() or "EXIT NOW" in message: |
|
|
|
api = HfApi() |
|
api.upload_file( |
|
path_or_fileobj=os.path.join(PATH_GAMELOGS,log_filename), |
|
path_in_repo=os.path.join(PATH_GAMELOGS,log_filename), |
|
repo_id="sgongora27/PAYADOR-experiments", |
|
repo_type="space", |
|
) |
|
|
|
return answer.replace("<",r"\<").replace(">", r"\>") |
|
|
|
|
|
|
|
world_id = config["Options"]["WorldID"] |
|
world = example_worlds.get_world(world_id, language=language) |
|
|
|
|
|
last_player_position = world.player.location |
|
number_of_turns = 0 |
|
game_log_dictionary = {} |
|
game_log_dictionary["nickname"] = "anonymous" |
|
game_log_dictionary["language"] = language |
|
game_log_dictionary["world_id"] = world_id |
|
game_log_dictionary["narrative_model_name"] = narrative_model_name |
|
game_log_dictionary["reasoning_model_name"] = reasoning_model_name |
|
|
|
print(f"\n🌎 World state 🌍\n{world.render_world(language=language)}\n") |
|
game_log_dictionary[0] = {} |
|
game_log_dictionary[0]["date"] = time.ctime(time.time()) |
|
game_log_dictionary[0]["initial_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=True) |
|
game_log_dictionary[0]["initial_rendered_world_state"] = world.render_world(language=language) |
|
|
|
|
|
system_msg_current_scene, user_msg_current_scene = prompt_narrate_current_scene( |
|
world.render_world(language=language), |
|
previous_narrations = world.player.visited_locations[world.player.location.name], |
|
language=language, |
|
starting_scene=True |
|
) |
|
starting_narration = narrative_model.prompt_model(system_msg=system_msg_current_scene, user_msg=user_msg_current_scene) |
|
world.player.visited_locations[world.player.location.name]+=[starting_narration] |
|
|
|
|
|
system_msg_objective, user_msg_objective = prompt_describe_objective(world.objective, language=language) |
|
narrated_objective = narrative_model.prompt_model(system_msg=system_msg_objective, user_msg=user_msg_objective) |
|
starting_narration += f"\n\n🎯 {re.findall(r'#([^#]*?)#',narrated_objective)[0]}" |
|
game_log_dictionary[0]["starting_narration"] = starting_narration |
|
|
|
with open(os.path.join(PATH_GAMELOGS,log_filename), 'w', encoding='utf-8') as f: |
|
json.dump(game_log_dictionary, f, ensure_ascii=False, indent=4) |
|
|
|
|
|
gradio_interface = gr.ChatInterface( |
|
fn=game_loop, |
|
chatbot = gr.Chatbot(height=500, value=[{"role": "assistant", "content": starting_narration.replace("<",r"\<").replace(">", r"\>")}], |
|
bubble_full_width = False, show_copy_button = False, type='messages'), |
|
textbox=gr.Textbox(placeholder="What do you want to do?", container=False, scale=5), |
|
title="PAYADOR", |
|
theme="Soft", |
|
type='messages', |
|
) |
|
|
|
gradio_interface.launch(inbrowser=False) |
|
|