mirror of
https://github.com/vegu-ai/talemate.git
synced 2026-08-29 10:08:58 +02:00
0.26.0 (#133)
* implement manually disabling and enabling clients * relock * fix warning spam * start moving stuff around * move more stuff * start separating world state manager into more managable submodules * character title * scroll home to top always * finish separating character state editor into components * fix defered nav to character sections * separate components for pin and contextdb managing * fix issue with context character filter search * fix world state manage ux state reset issues * wsm menu refactor allow updating character image from wsm cover image layout fixes * remove debug spam * fix client deletion / disabling rubber banding issue * deactivate / activate / delete characters through wsm * reload character instead * fix koboldcpp client jiggle arguments * save scene title * fix deferred nav * fix issue where blanking a character detail would bug out * some layout changes * character import copies cover image * remove debug message * character import via wsm * deactivate imported characters * images nav option placeholder * start move towards new world state templating system * prompt tweak * add templates/world-state/*.yaml * switch to new world state template system in manager * template editor progress * more wsm template changes * template applicator component * template applicate added to attributes and details * selective template application * fix issue with template editing * attribute and detail templates dont require instructions * adjust character attributes and details template applicator integration * add gpt-4o add gpt-4o-2024-05-13 * autocomplete prompt and postprocessing tweaks * prompt tweaks * fix issue where saving a new scene could cause recent config changes to revert * only download punkt if its not downloaded yet * working character attribute templates * character detail generate working move template generate logic to worldstate.templates * character creator first steps * support contextual generate when character doesn't exist * move talemate wsm templates to their own dir, add supports_spice and supports_style flags * wsm character creator progress * character creator progress * character creator progress and wire up image creation in character editor * templating progress * contextual generate generation options * ux tweaks * wirte up writing style and spice to generation * wire spice / writing style to detail generation * notify when spice is applied * tweaks to generation spice notifications * add some help / information to template editor * fix some issues with detail and attribute generation * some context gen tweaks * character gen tweaks * character color changer * link to templates form gen option ux * gen options for dialogue example genrate * ctrl click to max spice level * unify spice application notification into a component for reuse * improvements to example dialogue generation * some refinements to character editor * remove some old cruft from scene schema * wsm scene editor progress * relock * relock * debug message cleanup * fix issue with tab selection when loading a scene * scene editor progress * centralized generation options * pass generation settings through to character creator * save changes from wsm view * scene settings save copy * refactor world entry / states editor * fix issue with applying non-character world state templates * layout fixes * allow updating of scene cover image * move history manager to world editor * add phi-3 base template * dialogue cleanup improvements * refactor scoped game-engine api * separate legacy creator functions to own file * remove cruft * some cleanup and fixes * add photo style * remove noisy log message * better handling of active scene * some fixes to pin editor * don't enforce height * active scene context fixes * fix intro and scene description generration * tweak preset for scene direction and summarization tasks * ensure memory db is open * update frontend dependencies * update frontend dependencies * fix issue with prompt query_memory function returning None * typo * default world state templates * new scene creation fixes remove legacy creator ux * scene export * fix scene loading from upload * add claude 3.5 sonnet * fix automatic client selection when the current client is disabled * remove cruft * agent modal extended to support multiple config panels visual agent prompt prefixes and suffixes addeed * fix issue with world state template group saving * resolve attribute name issue `copy` * RequestInput: fix form validation and keystroke submit * support chara load from json files also refactor character loading to load.py * implement simple act-as feature using tab to cycle through active characters in the scene * docs progress * tts settings tweaks * fix issue with loading older talemate scenes * docs progress * fix issue with config validation on new installs * some tweaks for agent setting modals * default template changed to alpaca * docs dependencies * gemma2 template * nemotron4 template * docs * docs * docs * change prompt template section to autocomplete * fix agent config not loading for some agents * allow deletion of player character * fix some oddities with scene outline commit * automatically active player characters and create player characters with the correct actor class * also set the first npc created as immediately acitve * add has_active_npcs property and re-emit message history when scene outline is updated. * indicate when visualizer is busy in the scene tools * check for busy instead * prompt tweaks for movie script type dialogue format * gemma2 prompt fixed * scene message colors updated * act as narrator * move to _old * scene message appearance tweaks * fix rubberbanding when editing text field in agent configs * fix autocompletionm when acting as different character or narrator * disable autocomplete during command execution * remove autocomplete button from scene tools * docs * relock * docs * docs * improve context pins in dialogue context * better approximate token count * fix pin condition editing * fix issue where scene save as would lose long term memory entries * immediately clean message history when loading a new scene * docs * ensure intro text has formatting markers * narrator messages written by the player can now be deleted. * scene editor * move docs around * start character editor docs * more character editor docs: * fix some ux bugs * fix template group deletrion not removing the file * docs * typos * docs * relock * docs * notify image generation errors * linting * gh pages workflow * use poetry * dont use poetry * link to docs site * set site_url * add trailing slash * fix image paths * re-add tabbyai link * fix image generation error triggering incorrectly * fix intro formatting incosistencies * remove cruft * add time passed label to history view * date adjustments * tests * add gpt-4o-mini * fix links * remove hard ntlk requirement for voice generation chunking ntlk error handling fix typo * docs * fix issdue with dupe character card intro text * disable character forms while templates are being applied. * failure during context generate no longer locks ux * refactor client and agent status display in system bar * llama 3.1 8b claude * fix format * adjustments to automcomplete dialogue instructions * add mistral nemo * debug info * fix system agent status getting stuck * readme * readme * fix autocomplete responses when they are framed by quotes
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
"archived_history": [
|
||||
{
|
||||
"text": "Captain Elmer and Kaira first met during their rigorous training for the Infinity Quest mission. Their initial interactions were marked by a sense of mutual respect and curiosity.",
|
||||
"ts": "PT1S"
|
||||
"ts": "P1M"
|
||||
},
|
||||
{
|
||||
"text": "Over the course of several months, as they trained together, Elmer and Kaira developed a strong bond. They often spent their free time discussing their dreams of exploring the cosmos.",
|
||||
@@ -25,6 +25,10 @@
|
||||
{
|
||||
"text": "One memorable evening, while gazing at the stars through the ship's observation deck, Elmer and Kaira shared personal stories from their past. This intimate conversation deepened their connection and understanding of each other.",
|
||||
"ts": "P11M"
|
||||
},
|
||||
{
|
||||
"text": "You awaken on board of your ship, disoriented.",
|
||||
"ts": "P12M"
|
||||
}
|
||||
],
|
||||
"character_states": {},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
def game(TM):
|
||||
|
||||
|
||||
MSG_PROCESSED_INSTRUCTIONS = "Simulation suite processed instructions"
|
||||
|
||||
MSG_HELP = "Instructions to the simulation computer are only processed if the computer is directly addressed at the beginning of the instruction. Please state your commands by addressing the computer by stating \"Computer,\" followed by an instruction. For example ... \"Computer, i want to experience being on a derelict spaceship.\""
|
||||
@@ -30,20 +30,27 @@ def game(TM):
|
||||
return ""
|
||||
|
||||
class SimulationSuite:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
"""
|
||||
This is initialized at the beginning of each round of the simulation suite
|
||||
"""
|
||||
|
||||
# do we update the world state at the end of the round
|
||||
self.update_world_state = False
|
||||
|
||||
self.simulation_reset = False
|
||||
|
||||
# will keep track of any npcs added during the current round
|
||||
self.added_npcs = []
|
||||
|
||||
TM.log.debug("SIMULATION SUITE INIT...")
|
||||
|
||||
self.player_character = TM.scene.get_player_character()
|
||||
self.player_message = TM.scene.last_player_message()
|
||||
TM.log.debug("SIMULATION SUITE INIT!", scene=TM.scene)
|
||||
self.player_message = TM.scene.last_player_message
|
||||
self.last_processed_call = TM.game_state.get_var("instr.lastprocessed_call", -1)
|
||||
|
||||
# determine whether the player / user input is an instruction
|
||||
# to the simulation computer
|
||||
#
|
||||
# we do this by checking if the message starts with "Computer,"
|
||||
self.player_message_is_instruction = (
|
||||
self.player_message and
|
||||
self.player_message.raw.lower().startswith("computer") and
|
||||
@@ -51,14 +58,21 @@ def game(TM):
|
||||
not self.last_processed_call > self.player_message.id
|
||||
)
|
||||
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Main entry point for the simulation suite
|
||||
"""
|
||||
|
||||
if not TM.game_state.has_var("instr.simulation_stopped"):
|
||||
# simulation is still running
|
||||
self.simulation()
|
||||
|
||||
self.finalize_round()
|
||||
|
||||
def simulation(self):
|
||||
"""
|
||||
Simulation suite logic
|
||||
"""
|
||||
|
||||
if not TM.game_state.has_var("instr.simulation_started"):
|
||||
self.startup()
|
||||
@@ -68,28 +82,47 @@ def game(TM):
|
||||
if self.update_world_state:
|
||||
self.run_update_world_state(force=True)
|
||||
|
||||
|
||||
def startup(self):
|
||||
TM.emit_status("busy", "Simulation suite powering up.", as_scene_message=True)
|
||||
|
||||
"""
|
||||
Scene startup logic
|
||||
"""
|
||||
|
||||
# we are at the beginning of the simulation
|
||||
TM.signals.status("busy", "Simulation suite powering up.", as_scene_message=True)
|
||||
TM.game_state.set_var("instr.simulation_started", "yes", commit=False)
|
||||
|
||||
# add narration for the introduction
|
||||
TM.agents.narrator.action_to_narration(
|
||||
action_name="progress_story",
|
||||
narrative_direction=PROMPT_STARTUP,
|
||||
emit_message=False
|
||||
)
|
||||
|
||||
# add narration for the instructions on how to interact with the simulation
|
||||
# this is a passthrough since we don't want the AI to paraphrase this
|
||||
TM.agents.narrator.action_to_narration(
|
||||
action_name="passthrough",
|
||||
narration=MSG_HELP
|
||||
)
|
||||
TM.agents.world_state.manager(
|
||||
action_name="save_world_entry",
|
||||
|
||||
# create a world state entry letting the AI know that characters
|
||||
# interacting in the simulation are not aware of the computer or the simulation
|
||||
TM.agents.world_state.save_world_entry(
|
||||
entry_id="sim.quarantined",
|
||||
text=CTX_PIN_UNAWARE,
|
||||
meta={},
|
||||
# this should always be pinned
|
||||
pin=True
|
||||
)
|
||||
|
||||
# set flag that we have started the simulation
|
||||
TM.game_state.set_var("instr.simulation_started", "yes", commit=False)
|
||||
TM.emit_status("success", "Simulation suite ready", as_scene_message=True)
|
||||
|
||||
# signal to the UX that the simulation suite is ready
|
||||
TM.signals.status("success", "Simulation suite ready", as_scene_message=True)
|
||||
|
||||
# we want to update the world state at the end of the round
|
||||
self.update_world_state = True
|
||||
|
||||
def simulation_calls(self):
|
||||
@@ -98,6 +131,7 @@ def game(TM):
|
||||
simulation calls
|
||||
"""
|
||||
|
||||
# we only process instructions that are not hidden and are not the last processed call
|
||||
if not self.player_message_is_instruction or self.player_message.id == self.last_processed_call:
|
||||
return
|
||||
|
||||
@@ -105,14 +139,15 @@ def game(TM):
|
||||
if not TM.game_state.has_var("instr.has_issued_instructions"):
|
||||
|
||||
# determine the context of the simulation
|
||||
|
||||
context_context = TM.agents.creator.determine_content_context_for_description(
|
||||
description=self.player_message.raw,
|
||||
)
|
||||
TM.scene.set_content_context(context_context)
|
||||
|
||||
|
||||
calls = TM.client.render_and_request(
|
||||
# Render the `computer` template and send it to the LLM for processing
|
||||
# The LLM will return a list of calls that the simulation suite will process
|
||||
# The calls are pseudo code that the simulation suite will interpret and execute
|
||||
calls = TM.prompt.request(
|
||||
"computer",
|
||||
dedupe_enabled=False,
|
||||
player_instruction=self.player_message.raw,
|
||||
@@ -138,9 +173,13 @@ def game(TM):
|
||||
TM.log.debug("SIMULATION SUITE CALLS", calls=processed)
|
||||
TM.game_state.set_var("instr.has_issued_instructions", "yes", commit=False)
|
||||
|
||||
TM.emit_status("busy", "Simulation suite altering environment.", as_scene_message=True)
|
||||
TM.signals.status("busy", "Simulation suite altering environment.", as_scene_message=True)
|
||||
compiled = "\n".join(processed)
|
||||
|
||||
if not self.simulation_reset and compiled:
|
||||
|
||||
# send the compiled calls to the narrator to generate a narrative based
|
||||
# on them
|
||||
narration = TM.agents.narrator.action_to_narration(
|
||||
action_name="progress_story",
|
||||
narrative_direction=f"The computer calls the following functions:\n\n```\n{compiled}\n```\n\nand the simulation adjusts the environment according to the user's wishes.\n\nWrite the narrative that describes the changes to the player in the context of the simulation starting up. YOU MUST NOT REFERENCE THE COMPUTER OR THE SIMULATION.",
|
||||
@@ -151,9 +190,9 @@ def game(TM):
|
||||
# or the simulation from the previous narration
|
||||
is_initial_narration = TM.game_state.get_var("instr.intro_narration", False)
|
||||
if not is_initial_narration:
|
||||
TM.scene.set_description(str(narration))
|
||||
TM.scene.set_intro(str(narration))
|
||||
TM.log.debug("SIMULATION SUITE: initial narration", intro=str(narration))
|
||||
TM.scene.set_description(narration.raw)
|
||||
TM.scene.set_intro(narration.raw)
|
||||
TM.log.debug("SIMULATION SUITE: initial narration", intro=narration.raw)
|
||||
TM.scene.pop_history(typ="narrator", all=True, reverse=True)
|
||||
TM.scene.pop_history(typ="director", all=True, reverse=True)
|
||||
TM.game_state.set_var("instr.intro_narration", True, commit=False)
|
||||
@@ -162,6 +201,7 @@ def game(TM):
|
||||
|
||||
self.set_simulation_title(compiled)
|
||||
|
||||
|
||||
def set_simulation_title(self, compiled_calls):
|
||||
|
||||
"""
|
||||
@@ -212,7 +252,7 @@ def game(TM):
|
||||
TM.log.debug("SIMULATION SUITE: prepare calls - moved set_player_persona call", calls=calls)
|
||||
|
||||
return calls
|
||||
|
||||
|
||||
def process_call(self, call:str) -> str:
|
||||
"""
|
||||
Processes a simulation call
|
||||
@@ -239,15 +279,13 @@ def game(TM):
|
||||
return getattr(self, f"call_{function_name}")(call, inject)
|
||||
|
||||
return call
|
||||
|
||||
|
||||
|
||||
def call_set_simulation_goal(self, call:str, inject:str) -> str:
|
||||
"""
|
||||
Set's the simulation goal as a permanent pin
|
||||
"""
|
||||
TM.emit_status("busy", "Simulation suite setting goal.", as_scene_message=True)
|
||||
TM.agents.world_state.manager(
|
||||
action_name="save_world_entry",
|
||||
TM.signals.status("busy", "Simulation suite setting goal.", as_scene_message=True)
|
||||
TM.agents.world_state.save_world_entry(
|
||||
entry_id="sim.goal",
|
||||
text=self.player_message.raw,
|
||||
meta={},
|
||||
@@ -294,14 +332,18 @@ def game(TM):
|
||||
The simulation suite is altering the player persona
|
||||
"""
|
||||
|
||||
TM.emit_status("busy", "Simulation suite altering user persona.", as_scene_message=True)
|
||||
character_attributes = TM.agents.world_state.extract_character_sheet(
|
||||
name=self.player_character.name, text=inject, alteration_instructions=self.player_message.raw
|
||||
)
|
||||
self.player_character.update(base_attributes=character_attributes)
|
||||
player_character = TM.scene.get_player_character()
|
||||
|
||||
TM.signals.status("busy", "Simulation suite altering user persona.", as_scene_message=True)
|
||||
character_attributes = TM.agents.world_state.extract_character_sheet(
|
||||
name=player_character.name, text=inject, alteration_instructions=self.player_message.raw
|
||||
)
|
||||
TM.scene.set_character_attributes(player_character.name, character_attributes)
|
||||
|
||||
character_description = TM.agents.creator.determine_character_description(player_character.name)
|
||||
|
||||
TM.scene.set_character_description(player_character.name, character_description)
|
||||
|
||||
character_description = TM.agents.creator.determine_character_description(character=self.player_character)
|
||||
self.player_character.update(description=character_description)
|
||||
TM.log.debug("SIMULATION SUITE: transform player", attributes=character_attributes, description=character_description)
|
||||
|
||||
TM.agents.director.log_action(
|
||||
@@ -310,19 +352,19 @@ def game(TM):
|
||||
)
|
||||
|
||||
return call
|
||||
|
||||
|
||||
|
||||
def call_set_player_name(self, call:str, inject:str) -> str:
|
||||
|
||||
"""
|
||||
The simulation suite is altering the player name
|
||||
"""
|
||||
player_character = TM.scene.get_player_character()
|
||||
|
||||
TM.emit_status("busy", "Simulation suite adjusting user identity.", as_scene_message=True)
|
||||
character_name = TM.agents.creator.determine_character_name(character_name=f"{inject} - What is a fitting name for the player persona? Respond with the current name if it still fits.")
|
||||
TM.signals.status("busy", "Simulation suite adjusting user identity.", as_scene_message=True)
|
||||
character_name = TM.agents.creator.determine_character_name(instructions=f"{inject} - What is a fitting name for the player persona? Respond with the current name if it still fits.")
|
||||
TM.log.debug("SIMULATION SUITE: player name", character_name=character_name)
|
||||
if character_name != self.player_character.name:
|
||||
self.player_character.rename(character_name)
|
||||
if character_name != player_character.name:
|
||||
TM.scene.set_character_name(player_character.name, character_name)
|
||||
|
||||
TM.agents.director.log_action(
|
||||
action=parse_sim_call_arguments(call),
|
||||
@@ -330,13 +372,13 @@ def game(TM):
|
||||
)
|
||||
|
||||
return call
|
||||
|
||||
|
||||
|
||||
def call_add_ai_character(self, call:str, inject:str) -> str:
|
||||
|
||||
# sometimes the AI will call this function an pass an inanimate object as the parameter
|
||||
# we need to determine if this is the case and just ignore it
|
||||
is_inanimate = TM.client.query_text_eval(f"does the function `{call}` add an inanimate object, concept or abstract idea? (ANYTHING THAT IS NOT A CHARACTER THAT COULD BE PORTRAYED BY AN ACTOR)", call)
|
||||
is_inanimate = TM.agents.world_state.answer_query_true_or_false(f"does the function `{call}` add an inanimate object, concept or abstract idea? (ANYTHING THAT IS NOT A CHARACTER THAT COULD BE PORTRAYED BY AN ACTOR)", call)
|
||||
|
||||
if is_inanimate:
|
||||
TM.log.debug("SIMULATION SUITE: add npc - inanimate object / abstact idea - skipped", call=call)
|
||||
@@ -344,25 +386,25 @@ def game(TM):
|
||||
|
||||
# sometimes the AI will ask if the function adds a group of characters, we need to
|
||||
# determine if this is the case
|
||||
adds_group = TM.client.query_text_eval(f"does the function `{call}` add MULTIPLE ai characters?", call)
|
||||
adds_group = TM.agents.world_state.answer_query_true_or_false(f"does the function `{call}` add MULTIPLE ai characters?", call)
|
||||
|
||||
TM.log.debug("SIMULATION SUITE: add npc", adds_group=adds_group)
|
||||
|
||||
TM.emit_status("busy", "Simulation suite adding character.", as_scene_message=True)
|
||||
TM.signals.status("busy", "Simulation suite adding character.", as_scene_message=True)
|
||||
|
||||
if not adds_group:
|
||||
character_name = TM.agents.creator.determine_character_name(character_name=f"{inject} - what is the name of the character to be added to the scene? If no name can extracted from the text, extract a short descriptive name instead. Respond only with the name.")
|
||||
character_name = TM.agents.creator.determine_character_name(instructions=f"{inject} - what is the name of the character to be added to the scene? If no name can extracted from the text, extract a short descriptive name instead. Respond only with the name.")
|
||||
else:
|
||||
character_name = TM.agents.creator.determine_character_name(character_name=f"{inject} - what is the name of the group of characters to be added to the scene? If no name can extracted from the text, extract a short descriptive name instead. Respond only with the name.", group=True)
|
||||
character_name = TM.agents.creator.determine_character_name(instructions=f"{inject} - what is the name of the group of characters to be added to the scene? If no name can extracted from the text, extract a short descriptive name instead. Respond only with the name.", group=True)
|
||||
|
||||
# sometimes add_ai_character and change_ai_character are called in the same instruction targeting
|
||||
# the same character, if this happens we need to combine into a single add_ai_character call
|
||||
|
||||
has_change_ai_character_call = TM.client.query_text_eval(f"Are there any calls to `change_ai_character` in the instruction for {character_name}?", "\n".join(self.calls))
|
||||
has_change_ai_character_call = TM.agents.world_state.answer_query_true_or_false(f"Are there any calls to `change_ai_character` in the instruction for {character_name}?", "\n".join(self.calls))
|
||||
|
||||
if has_change_ai_character_call:
|
||||
|
||||
combined_arg = TM.client.render_and_request(
|
||||
combined_arg = TM.prompt.request(
|
||||
"combine-add-and-alter-ai-character",
|
||||
dedupe_enabled=False,
|
||||
calls="\n".join(self.calls),
|
||||
@@ -374,18 +416,17 @@ def game(TM):
|
||||
inject = f"The computer executes the function `{call}`"
|
||||
|
||||
|
||||
TM.emit_status("busy", f"Simulation suite adding character: {character_name}", as_scene_message=True)
|
||||
TM.signals.status("busy", f"Simulation suite adding character: {character_name}", as_scene_message=True)
|
||||
|
||||
TM.log.debug("SIMULATION SUITE: add npc", name=character_name)
|
||||
|
||||
npc = TM.agents.director.persist_character(name=character_name, content=self.player_message.raw+f"\n\n{inject}", determine_name=False)
|
||||
npc = TM.agents.director.persist_character(character_name=character_name, content=self.player_message.raw+f"\n\n{inject}", determine_name=False)
|
||||
|
||||
self.added_npcs.append(npc.name)
|
||||
|
||||
TM.agents.world_state.manager(
|
||||
action_name="add_detail_reinforcement",
|
||||
TM.agents.world_state.add_detail_reinforcement(
|
||||
character_name=npc.name,
|
||||
question="Goal",
|
||||
detail="Goal",
|
||||
instructions=f"Generate a goal for {npc.name}, based on the user's chosen simulation",
|
||||
interval=25,
|
||||
run_immediately=True
|
||||
@@ -400,19 +441,20 @@ def game(TM):
|
||||
action_description=f"The computer adds {npc.name} to the simulation."
|
||||
)
|
||||
|
||||
return call
|
||||
return call
|
||||
|
||||
####
|
||||
|
||||
def call_remove_ai_character(self, call:str, inject:str) -> str:
|
||||
TM.emit_status("busy", "Simulation suite removing character.", as_scene_message=True)
|
||||
TM.signals.status("busy", "Simulation suite removing character.", as_scene_message=True)
|
||||
|
||||
character_name = TM.agents.creator.determine_character_name(character_name=f"{inject} - what is the name of the character being removed?", allowed_names=TM.scene.npc_character_names())
|
||||
character_name = TM.agents.creator.determine_character_name(instructions=f"{inject} - what is the name of the character being removed?", allowed_names=TM.scene.npc_character_names())
|
||||
|
||||
npc = TM.scene.get_character(character_name)
|
||||
|
||||
if npc:
|
||||
TM.log.debug("SIMULATION SUITE: remove npc", npc=npc.name)
|
||||
TM.agents.world_state.manager(action_name="deactivate_character", character_name=npc.name)
|
||||
TM.agents.world_state.deactivate_character(action_name="deactivate_character", character_name=npc.name)
|
||||
|
||||
TM.agents.director.log_action(
|
||||
action=parse_sim_call_arguments(call),
|
||||
@@ -422,33 +464,33 @@ def game(TM):
|
||||
return call
|
||||
|
||||
def call_change_ai_character(self, call:str, inject:str) -> str:
|
||||
TM.emit_status("busy", "Simulation suite altering character.", as_scene_message=True)
|
||||
TM.signals.status("busy", "Simulation suite altering character.", as_scene_message=True)
|
||||
|
||||
character_name = TM.agents.creator.determine_character_name(character_name=f"{inject} - what is the name of the character receiving the changes (before the change)?", allowed_names=TM.scene.npc_character_names())
|
||||
character_name = TM.agents.creator.determine_character_name(instructions=f"{inject} - what is the name of the character receiving the changes (before the change)?", allowed_names=TM.scene.npc_character_names())
|
||||
|
||||
if character_name in self.added_npcs:
|
||||
# we dont want to change the character if it was just added
|
||||
return
|
||||
|
||||
character_name_after = TM.agents.creator.determine_character_name(character_name=f"{inject} - what is the name of the character receiving the changes (after the changes)?")
|
||||
character_name_after = TM.agents.creator.determine_character_name(instructions=f"{inject} - what is the name of the character receiving the changes (after the changes)?")
|
||||
|
||||
npc = TM.scene.get_character(character_name)
|
||||
|
||||
if npc:
|
||||
TM.emit_status("busy", f"Changing {character_name} -> {character_name_after}", as_scene_message=True)
|
||||
TM.signals.status("busy", f"Changing {character_name} -> {character_name_after}", as_scene_message=True)
|
||||
|
||||
TM.log.debug("SIMULATION SUITE: transform npc", npc=npc)
|
||||
|
||||
character_attributes = TM.agents.world_state.extract_character_sheet(name=npc.name, alteration_instructions=self.player_message.raw)
|
||||
|
||||
npc.update(base_attributes=character_attributes)
|
||||
character_description = TM.agents.creator.determine_character_description(character=npc)
|
||||
TM.scene.set_character_attributes(npc.name, character_attributes)
|
||||
character_description = TM.agents.creator.determine_character_description(npc.name)
|
||||
|
||||
npc.update(description=character_description)
|
||||
TM.scene.set_character_description(npc.name, character_description)
|
||||
TM.log.debug("SIMULATION SUITE: transform npc", attributes=character_attributes, description=character_description)
|
||||
|
||||
if character_name_after != character_name:
|
||||
npc.rename(character_name_after)
|
||||
TM.scene.set_character_name(npc.name, character_name_after)
|
||||
|
||||
TM.agents.director.log_action(
|
||||
action=parse_sim_call_arguments(call),
|
||||
@@ -459,13 +501,15 @@ def game(TM):
|
||||
|
||||
def call_end_simulation(self, call:str, inject:str) -> str:
|
||||
|
||||
explicit_command = TM.client.query_text_eval("has the player explicitly asked to end the simulation?", self.player_message.raw)
|
||||
player_character = TM.scene.get_player_character()
|
||||
|
||||
explicit_command = TM.agents.world_state.answer_query_true_or_false("has the player explicitly asked to end the simulation?", self.player_message.raw)
|
||||
|
||||
if explicit_command:
|
||||
TM.emit_status("busy", "Simulation suite ending current simulation.", as_scene_message=True)
|
||||
TM.signals.status("busy", "Simulation suite ending current simulation.", as_scene_message=True)
|
||||
TM.agents.narrator.action_to_narration(
|
||||
action_name="progress_story",
|
||||
narrative_direction=f"Narrate the computer ending the simulation, dissolving the environment and all artificial characters, erasing all memory of it and finally returning the player to the inactive simulation suite. List of artificial characters: {', '.join(TM.scene.npc_character_names())}. The player is also transformed back to their normal, non-descript persona as the form of {self.player_character.name} ceases to exist.",
|
||||
narrative_direction=f"Narrate the computer ending the simulation, dissolving the environment and all artificial characters, erasing all memory of it and finally returning the player to the inactive simulation suite. List of artificial characters: {', '.join(TM.scene.npc_character_names)}. The player is also transformed back to their normal, non-descript persona as the form of {player_character.name} ceases to exist.",
|
||||
emit_message=True
|
||||
)
|
||||
TM.scene.restore()
|
||||
@@ -495,20 +539,20 @@ def game(TM):
|
||||
self.run_update_world_state()
|
||||
|
||||
if self.player_message_is_instruction:
|
||||
self.player_message.hide()
|
||||
TM.scene.hide_message(self.player_message.id)
|
||||
TM.game_state.set_var("instr.lastprocessed_call", self.player_message.id, commit=False)
|
||||
TM.emit_status("success", MSG_PROCESSED_INSTRUCTIONS, as_scene_message=True)
|
||||
TM.signals.status("success", MSG_PROCESSED_INSTRUCTIONS, as_scene_message=True)
|
||||
|
||||
elif self.player_message and not has_issued_instructions:
|
||||
# simulation started, player message is NOT an instruction, and player has not given
|
||||
# any instructions
|
||||
self.guide_player()
|
||||
|
||||
elif self.player_message and not TM.scene.npc_character_names():
|
||||
elif self.player_message and not TM.scene.npc_character_names:
|
||||
# simulation started, player message is NOT an instruction, but there are no npcs to interact with
|
||||
self.narrate_round()
|
||||
|
||||
elif rounds % AUTO_NARRATE_INTERVAL == 0 and rounds and TM.scene.npc_character_names() and has_issued_instructions:
|
||||
elif rounds % AUTO_NARRATE_INTERVAL == 0 and rounds and TM.scene.npc_character_names and has_issued_instructions:
|
||||
# every N rounds, narrate the round
|
||||
self.narrate_round()
|
||||
|
||||
@@ -528,8 +572,9 @@ def game(TM):
|
||||
|
||||
def run_update_world_state(self, force=False):
|
||||
TM.log.debug("SIMULATION SUITE: update world state", force=force)
|
||||
TM.emit_status("busy", "Simulation suite updating world state.", as_scene_message=True)
|
||||
TM.signals.status("busy", "Simulation suite updating world state.", as_scene_message=True)
|
||||
TM.agents.world_state.update_world_state(force=force)
|
||||
TM.emit_status("success", "Simulation suite updated world state.", as_scene_message=True)
|
||||
|
||||
SimulationSuite().run()
|
||||
TM.signals.status("success", "Simulation suite updated world state.", as_scene_message=True)
|
||||
|
||||
SimulationSuite().run()
|
||||
|
||||
Reference in New Issue
Block a user