Skip to content

Commit

Permalink
simplify actioncontext
Browse files Browse the repository at this point in the history
  • Loading branch information
neph1 committed Nov 23, 2024
1 parent 0518ff2 commit f3c762f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
10 changes: 5 additions & 5 deletions llm_config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
WORD_LIMIT: 200 # max number of words the model is encoraged to generate. not a hard limit
SHORT_WORD_LIMIT: 25 # max number of words when asked to write something short. not a hard limit
BACKEND: "kobold_cpp" # valid options: "openai", "llama_cpp", "kobold_cpp". if using ooba, use and modify openai template
BACKEND: "llama_cpp" # valid options: "openai", "llama_cpp", "kobold_cpp". if using ooba, use and modify openai template
MEMORY_SIZE: 512
UNLIMITED_REACTS: False
DIALOGUE_TEMPLATE: '{{"response":"may be both dialogue and action.", "sentiment":"sentiment based on response", "give":"if any physical item of {character2}s is given as part of the dialogue. Or nothing."}}'
Expand All @@ -16,7 +16,7 @@ DUNGEON_LOCATION_TEMPLATE: '{"index": (int), "name": "", "description": 25 words
CHARACTER_TEMPLATE: '{"name":"", "description": "50 words", "appearance": "25 words", "personality": "50 words", "money":(int), "level":"", "gender":"m/f/n", "age":(int), "race":"", "occupation":""}'
FOLLOW_TEMPLATE: '{{"response":"yes or no", "reason":"50 words"}}'
ITEM_TYPES: ["Weapon", "Wearable", "Health", "Money", "Trash"]
PRE_PROMPT: 'You are a creative game keeper for an interactive fiction story telling session. You craft detailed worlds and interesting characters with unique and deep personalities for the player to interact with. Always follow the instructions given, never acknowledge the task or speak directly to the user or respond with anything besides the request.'
PRE_PROMPT: 'You are a creative game keeper for an interactive fiction story telling session. You craft detailed worlds and interesting characters with unique and deep personalities for the player to interact with. Always follow the instructions given, never acknowledge the task or speak directly to the user or respond with anything besides the request. Do not invent new characters or locations unless prompted. Use the information provided to create a rich and engaging story. Remember to keep the story consistent with the context provided.'
BASE_PROMPT: '<context>{context}</context>\n[USER_START] Rewrite [{input_text}] in your own words. The information inside the <context> tags should be used to ensure it fits the story. Use about {max_words} words.'
DIALOGUE_PROMPT: '<context>{context}</context>\nThe following is a conversation between {character1} and {character2}; {character2}s sentiment towards {character1}: {sentiment}. Write a single response as {character2} in third person pov, using {character2} description and other information found inside the <context> tags. If {character2} has a quest active, they will discuss it based on its status. Respond in JSON using this template: """{dialogue_template}""". [USER_START]Continue the following conversation as {character2}: {previous_conversation}'
COMBAT_PROMPT: '<context>{context}</context>\nThe following is a combat scene between {attackers} and {defenders} in {location}. [USER_START] Describe the following combat result in about 150 words in vivid language, using the characters weapons and describe their health status without mentioning numbers: 1.0 is highest, 0.0 is dead. <combat result> {input_text}</combat result>'
Expand All @@ -35,14 +35,14 @@ START_LOCATION_PROMPT: '[Story context: {story_context}]; Zone info: {zone_info}
STORY_PLOT_PROMPT: "[USER_START] For an RPG described as {story_type} set in a world described as {world_mood}, {world_info}. Based on the following background: {story_background} write an innovative and engaging plot that the player can become part of. Use less than 400 words."
WORLD_ITEMS: '<context>{context}</context>\n[USER_START] Using the information supplied inside the <context> tags, come up with 7 common items that can be found in the world. Item example: {item_template}, type is one of: {item_types}; Reply with a list of items in JSON format and do not write anything else: {{"items": []}}.'
WORLD_CREATURES: '<context>{context}</context>\n[USER_START] Using the information supplied inside the <context> tags, come up with 5 creatures of various level and sentiment that can be found in the world. Consider the role of the creature in the story and whether it will be friendly or hostile to the player. Creature example: {creature_template}. Reply with a list of creatures in JSON format and do not write anything else: {{"creatures": []}}.'
GOAL_PROMPT: '[Characters:{characters}][Sentiments towards characters: {sentiments}] [Last action: {last_action}] [Location: {location}] [Known locations: {locations}][Acting character: {character}] [Actions available:{actions}] [USER_START] For {character_name}, come up with a goal that plays along with their character description that involves an item, a character or a location in the prompt. Then construct up to three tasks that will lead towards the achievement of said goal. Fill in the following JSON template: {{"goal":"", "tasks":[{"action":"", "what":""}, {"action":"", "what":""}, {"action":"", "what":""}]}}'
GOAL_PROMPT: '[Characters:{characters}][Sentiments towards characters: {sentiments}] [Last action: {last_action}] [Location: {location}] [Known locations: {locations}][Acting character: {character}] [Actions available:{actions}] [USER_START] For {character_name}, describe a goal that goes along with their character description that involves an item, a character or a location in the prompt. Then construct up to three tasks that will lead towards the achievement of said goal. Fill in the following JSON template: {{"goal":"", "tasks":[{"action":"", "what":""}, {"action":"", "what":""}, {"action":"", "what":""}]}}'
JSON_GRAMMAR: "root ::= object\nvalue ::= object | array | string | number | (\"true\" | \"false\" | \"null\") ws\n\nobject ::=\n \"{\" ws (\n string \":\" ws value\n (\",\" ws string \":\" ws value)*\n )? \"}\" ws\n\narray ::=\n \"[\" ws (\n value\n (\",\" ws value)*\n )? \"]\" ws\n\nstring ::=\n \"\\\"\" (\n [^\"\\\\] |\n \"\\\\\" ([\"\\\\/bfnrt] | \"u\" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]) # escapes\n )* \"\\\"\" ws\n\nnumber ::= (\"-\"? ([0-9] | [1-9] [0-9]*)) (\".\" [0-9]+)? ([eE] [-+]? [0-9]+)? ws\n\n# Optional space: by convention, applied in this grammar after literal chars when allowed\nws ::= ([ \\t\\n] ws)?"
PLAYER_ENTER_PROMPT: '<context>{context}</context> Zone info: {zone_info}; Npc example: {npc_template}.\n[USER_START] The player has just re-entered this location: {location_info}. Consider whether any items, npcs or mobs should be spawned. For mobs, only enter the name of race. Fill in this JSON template and do not write anything else: {{"items":[], "npcs":[] "mobs":[]}}.'
QUEST_PROMPT: '<context>{context}</context> Zone info: {zone_info}; Character: {character_card};\n[USER_START] Using the information supplied inside the <context> tags, {character_name} needs someone to perform a task. Based on the following input, come up with a suitable reason for it, using {character_name}s personality and history. Task info: {base_quest}. Fill in this JSON template and do not write anything else: {{"reason":""}} \n\n '
NOTE_QUEST_PROMPT: '<context>{context}</context> Zone info: {zone_info};\n[USER_START]Using the information supplied inside the <context> tags, generate a quest that starts from reading a note. The reader must find and talk to a person. Fill in the following JSON template and write nothing else.: {{"reason": "only what the note says. 50 words.", "type":"talk", "target":"who to talk to", "location":"", "name":"name of quest"}}'
NOTE_LORE_PROMPT: '<context>{context}</context> Zone info: {zone_info};\n[USER_START]FUsing the information supplied inside the <context> tags, decide what is written on a note that has been found. Use the provided story and world information to generate a piece of lore. Use about 50 words.'
ACTION_PROMPT: '<context>{context}</context>\n[USER_START]Act as as {character_name}.\nUsing the information supplied inside the <context> tag, pick an action according to {character_name}s description and mood. If suitable, select something to perform the action on (target). The action should be in the supplied list and should be related to {character_name}s goal and thoughts. Build on events in "History" without repeating them. Respond using JSON in the following format with up to 3 actions: """{action_template}""". Continue the sequence of events: {previous_events}'
REQUEST_FOLLOW_PROMPT: '<context>{context}</context>\n[USER_START]Act as as {character_name}.\nUsing the information supplied inside the <context> tag. {character_name} has received a request to follow {target}. Answer based on {character_name}s description and mood. Reason given by {target}: {target_reason}. Respond using JSON in the following format: {follow_template}'
ACTION_PROMPT: '<context>{context}</context>\n[USER_START]Act as as {character_name}.\nUsing the information supplied inside the <context> tags, pick an action according to {character_name}s description and mood. If suitable, select something to perform the action on (target). The action should be in the supplied list and should be related to {character_name}s goal and thoughts. Build on events in "History" without repeating them. Respond using JSON in the following format with up to 3 actions: """{action_template}""". Continue the sequence of events: {previous_events}'
REQUEST_FOLLOW_PROMPT: '<context>{context}</context>\n[USER_START]Act as {character_name}.\nUsing the information supplied inside the <context> tag. {character_name} has received a request to follow {target}. Answer based on {character_name}s description and mood. Reason given by {target}: {target_reason}. Respond using JSON in the following format: {follow_template}'
DAY_CYCLE_EVENT_PROMPT: '<context>{context}</context>\n[USER_START] Write up to two sentences describing the transition from {from_time} to {to_time} in {location_name}, using the information supplied inside the <context> tags.'
NARRATIVE_EVENT_PROMPT: '<context>{context}</context>\n[USER_START] Write a narrative event that occurs in {location_name} using the information supplied inside the <context> tags. The event should be related to the location and the characters present. Use up to 50 words.'
RANDOM_SPAWN_PROMPT: '<context>{context}</context>\n[USER_START] An npc or a mob has entered {location_name}. Select either and fill in one of the following templates using the information supplied inside the <context> tags. Respond using JSON in the following format: {npc_template}'
Expand Down
17 changes: 7 additions & 10 deletions tale/llm/contexts/ActionContext.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@


import json
import random
from tale.base import Location
from tale.llm.contexts.BaseContext import BaseContext
Expand All @@ -20,13 +17,13 @@ def __init__(self, story_context: str, story_type: str, character_name: str, cha

def to_prompt_string(self) -> str:
actions = ', '.join(self.actions)
characters = {}
characters = []
for living in self.location.livings:
if living.visible and not living.hidden and living.name != self.character_name.lower():
if living.alive:
characters[living.name] = living.short_description
else:
characters[living.name] = f"{living.short_description} (dead)"
character = f"{living.name}: {living.short_description}"
if not living.alive:
character = character + " (dead)"
characters.append(character)
exits = self.location.exits.keys()
items = [item.name for item in self.location.items if item.visible]
examples = []
Expand All @@ -35,5 +32,5 @@ def to_prompt_string(self) -> str:
if len(exits) > 0:
examples.append(f'{{"goal":"", "thoughts":"I want to go there.", "action":"move", "target":{random.choice(list(exits))}, "text":""}}')
if len(characters) > 0:
examples.append(f'{{"goal":"", "thoughts":"", "action":"say", "target":{random.choice(list(characters.values()))}, "text":""}}')
return f"Story context:{self.story_context}; Story type:{self.story_type}; Available actions: {actions}; Location:{self.location.name}, {self.location.description}; Available exits: {exits}; Self({self.character_name}): {self.character_card}; Present items: {items}; Present characters: {json.dumps(characters)}; History:{self.event_history}; Example actions: {', '.join(examples)};"
examples.append(f'{{"goal":"", "thoughts":"", "action":"say", "target":{random.choice(characters)}, "text":""}}')
return f"Story context:{self.story_context}; Story type:{self.story_type}; Available actions: {actions}; Location: {self.location.name}, {self.location.description}; Available exits: {exits}; Self({self.character_name}): {self.character_card}; Present items: {items}; Present characters: {characters}; History:{self.event_history}; Example actions: {', '.join(examples)};"
11 changes: 9 additions & 2 deletions tests/test_contexts.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


from tale.base import Location
from tale.base import Living, Location
from tale.llm.contexts.ActionContext import ActionContext
from tale.llm.contexts.DungeonLocationsContext import DungeonLocationsContext
from tale.llm.contexts.EvokeContext import EvokeContext
Expand Down Expand Up @@ -57,6 +57,10 @@ def test_action_context(self):
character_card = "{actions}"
history = "[history]"
location = Location("TestLocation")
npc1 = Living("Npc", gender="m", short_descr="A test npc")
npc_hidden = Living("Npc Hidden", gender="m")
npc_hidden.hidden = True
location.init_inventory([npc1, npc_hidden])
action_list = ["say", "take", "wear"]
action_context = ActionContext(story_context="test_context",
story_type="test type",
Expand All @@ -67,10 +71,13 @@ def test_action_context(self):
actions=action_list)

result = action_context.to_prompt_string()
assert 'npc: A test npc' in result
assert 'npc Hidden' not in result

assert character_card in result
assert character_name in result
assert "say" in result
assert 'test_context' in result
assert "say, take, wear" in result


def test_follow_context(self):
Expand Down

0 comments on commit f3c762f

Please sign in to comment.