guardrail-game-app / app-running.py
pratikshahp's picture
Rename app.py to app-running.py
c98cee8 verified
import gradio as gr
import random
from helper import load_world, save_world
from together import Together
from helper import get_together_api_key
# Initialize Together client
client = Together(api_key=get_together_api_key())
# Load the world data from the JSON file
world_data = load_world('./YourWorld_L1.json')
# Set the content policy
safe_content_policy = {
"policy": """O1: Violence and Hate.
Should not
- Express hateful, derogatory, or demeaning sentiments against people based on sensitive personal characteristics.
- Use slurs based on personal characteristics
- Write gruesome / graphic violence.
Can
- Write tame fantasy violence
O2: Sexual Content.
Should not
- Write any somewhat sexual content that mentions sexual functions or sexual body parts.
- Write any content that would be inappropriate for kids.
Can
- Write romantic content (including kissing, flirting etc...)
O3: Self-Harm.
Should not
- Encourage people to harm themselves.
- Romanticize or condone self-harm or suicide.
- Write story depicting suicide.
O4: Profanity.
Should not
- Write with any profane language that wouldn't be appropriate for kids.
Can
- Write with kid appropriate language
O5: Regulated or Controlled Substances.
Should not
- Write stories that depicts, glorifies or encourages drug use."""
}
# Function to randomly select a world, kingdom, town, and character
def randomly_select_from_json(world_data):
world_name = world_data["name"]
world_description = world_data["description"]
valid_kingdoms = {
k_name: k_data
for k_name, k_data in world_data["kingdoms"].items()
if any("npcs" in town_data and town_data["npcs"] for town_data in k_data["towns"].values())
}
if not valid_kingdoms:
raise ValueError("No kingdoms with valid towns and NPCs found.")
kingdom_name, kingdom_data = random.choice(list(valid_kingdoms.items()))
kingdom_description = kingdom_data["description"]
valid_towns = {
t_name: t_data
for t_name, t_data in kingdom_data["towns"].items()
if "npcs" in t_data and t_data["npcs"]
}
if not valid_towns:
raise ValueError(f"No towns with NPCs found in kingdom: {kingdom_name}")
town_name, town_data = random.choice(list(valid_towns.items()))
town_description = town_data["description"]
npcs = town_data["npcs"]
character_name, character_data = random.choice(list(npcs.items()))
character_description = character_data["description"]
return {
"world": {"name": world_name, "description": world_description},
"kingdom": {"name": kingdom_name, "description": kingdom_description},
"town": {"name": town_name, "description": town_description},
"character": {"name": character_name, "description": character_description},
}
# Function to initialize or reinitialize the game state
def initialize_game_state():
random_state = randomly_select_from_json(world_data)
world = random_state["world"]
kingdom = random_state["kingdom"]
town = random_state["town"]
character = random_state["character"]
system_prompt = """You are an AI Game master. Your job is to create a
start to an adventure based on the world, kingdom, town, and character
a player is playing as.
Instructions:
- You must use only 2-4 sentences.
- Please use simple and clear language that is easy for children to understand.
- Write in second person, e.g., "You are Jack."
- Write in present tense, e.g., "You stand at..."
- First describe the character and their backstory.
- Then describe where they start and what they see around them."""
world_info = f"""
World: {world['description']}
Kingdom: {kingdom['description']}
Town: {town['description']}
Your Character: {character['description']}
"""
model_output = client.chat.completions.create(
model="meta-llama/Llama-3-70b-chat-hf",
temperature=1.0,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": world_info + '\nYour Start:'}
],
)
start = model_output.choices[0].message.content
return {
"world": world["description"],
"kingdom": kingdom["description"],
"town": town["description"],
"character": character["description"],
"start": start,
}
def is_safe (message):
prompt = f"""[INST] Task: Check if there is unsafe content in
'user' messages in conversations according to our safety policy
with the below categories.
<BEGIN UNSAFE CONTENT CATEGORIES>
{safe_content_policy['policy']}
<END UNSAFE CONTENT CATEGORIES>
<BEGIN CONVERSATION>
user: {message}
Provide your safety assessment for user in the above conversation:
- First line must read 'safe' or 'unsafe'.
- If unsafe, a second line must include a comma-separated list of
violated categories. [/INST]"""
response = client.completions.create(
model="Meta-Llama/LlamaGuard-2-8b",
prompt=prompt,
)
result = response.choices[0].text
return result.strip() == 'safe'
# Initialize the game state
game_state = initialize_game_state()
game_running = True # Flag to manage game status
# Function to process user input and actions
def run_action(message, history):
global game_state, game_running # Access the global game state and game status
if not game_running:
return "The game has ended. Type 'restart the game' to play again."
if message.lower() == "start game":
return game_state["start"]
if message.lower() == "restart the game":
game_state = initialize_game_state()
return "Game restarted! " + game_state["start"]
if message.lower() == "exit":
game_running = False
return "The game has ended. Type 'restart the game' to play again."
system_prompt = """You are an AI Game master. Your job is to write what \
happens next in a player's adventure game.\
Instructions: \
- Write only 1-3 sentences. \
- Please use simple and clear language that is easy for children to understand.
- Always write in second person, e.g., "You look north and see..." \
- Write in present tense."""
world_info = f"""
World: {game_state['world']}
Kingdom: {game_state['kingdom']}
Town: {game_state['town']}
Your Character: {game_state['character']}"""
# Build the context for the conversation
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": world_info},
]
for action in history:
if isinstance(action, tuple) and len(action) == 2:
messages.append({"role": "assistant", "content": action[0]})
messages.append({"role": "user", "content": action[1]})
# Add the user's current action
messages.append({"role": "user", "content": message})
# Get the model's response
model_output = client.chat.completions.create(
model="meta-llama/Llama-3-70b-chat-hf",
messages=messages,
)
return model_output.choices[0].message.content
def main_loop(message, history):
if not is_safe(message):
return 'Invalid action.'
result = run_action(message, history)
safe = is_safe(result)
if(safe):
return result # only if safe?
else:
return 'Invalid output.'
# Gradio ChatInterface
demo = gr.ChatInterface(
main_loop,
chatbot=gr.Chatbot(
height=300,
placeholder="Type 'start game' to begin, 'restart the game' to restart, or 'exit' to end the game.",
type="messages", # Ensures proper rendering
),
textbox=gr.Textbox(
placeholder="What do you do next?",
container=False,
scale=7,
),
title="AI RPG",
theme="Monochrome",
examples=["Look around", "Continue the story"],
cache_examples=False,
)
# Launch the Gradio app
demo.launch(share=True, server_name="0.0.0.0")