diff --git a/light/graph/builders/one_room_builder.py b/light/graph/builders/one_room_builder.py index b84bb55ed..ba51f423b 100644 --- a/light/graph/builders/one_room_builder.py +++ b/light/graph/builders/one_room_builder.py @@ -330,7 +330,7 @@ def add_new_agent_to_graph(self, g, char, room_node): agent_node = g.add_agent( use_desc, self._props_from_char(char), db_id=char.db_id ) - # added as a NPC Nothing needs to be done as agent is added as x._human = False + # added as a NPC agent_node.move_to(room_node) objs = {} if self.suggestion_type != "model": diff --git a/light/graph/builders/starspace_all.py b/light/graph/builders/starspace_all.py index 550545108..7c729ac29 100644 --- a/light/graph/builders/starspace_all.py +++ b/light/graph/builders/starspace_all.py @@ -367,7 +367,7 @@ def add_new_agent_to_graph(self, g, char, room_node): agent_node = g.add_agent( use_desc, self._props_from_char(char), db_id=char.db_id ) - # added as a NPC Nothing needs to be done as agent is added as x._human = False + # added as a NPC agent_node.move_to(room_node) objs = {} if self.suggestion_type != "model": diff --git a/light/graph/builders/starspace_assisted.py b/light/graph/builders/starspace_assisted.py index 72d51cdc2..7ca840606 100644 --- a/light/graph/builders/starspace_assisted.py +++ b/light/graph/builders/starspace_assisted.py @@ -374,7 +374,7 @@ def add_new_agent_to_graph(self, g, char, room_node): agent_node = g.add_agent( use_desc, self._props_from_char(char), db_id=char.db_id ) - # added as a NPC Nothing needs to be done as agent is added as x._human = False + # added as a NPC agent_node.move_to(room_node) objs = {} if self.suggestion_type != "model": diff --git a/light/graph/builders/tests/test_user.py b/light/graph/builders/tests/test_user.py index 7733e540a..61c72b52c 100644 --- a/light/graph/builders/tests/test_user.py +++ b/light/graph/builders/tests/test_user.py @@ -120,9 +120,6 @@ def test_builder_adds_random_agent_to_graph_adds_another_to_some_room(self): contained_room_1 = len(self.testGraph.get_node(gRoomId).contained_nodes) contained_room_2 = len(self.testGraph.get_node(gRoomId2).contained_nodes) self.assertTrue(contained_room_1 == 3 or contained_room_2 == 3) - # Trying to add again will not work, since all characters in world! - self.graphBuilder.add_random_new_agent_to_graph(self.testWorld) - self.assertEqual(len(self.testGraph.agents), 3) def test_builder_returns_graph(self): self.assertIsInstance(self.testGraph, OOGraph) diff --git a/light/graph/elements/graph_nodes.py b/light/graph/elements/graph_nodes.py index 6a3ea16f0..66ddf8360 100644 --- a/light/graph/elements/graph_nodes.py +++ b/light/graph/elements/graph_nodes.py @@ -588,7 +588,7 @@ def __init__(self, node_id, name, props=None, db_id=None): self.dead = False # Flag to resolve when a death event is in the stack, but possibly not processed self._dying = False - self.is_player = self._props.get("is_player", False) + self.is_player = self._props.get("is_player", self._props.get("_human", False)) self.usually_npc = self._props.get("usually_npc", False) self.pacifist = self._props.get("pacifist", False) self.tags = self._props.get("tags", self.DEFAULT_TAGS) @@ -619,7 +619,6 @@ def __init__(self, node_id, name, props=None, db_id=None): self.mission = self._props.get("mission", "") # Game properties to track for this agent, TODO move to other class? - self._human = False self._current_player = None self.clear_memory() @@ -754,7 +753,7 @@ def get_observations(self): def set_player(self, current_player): """Have a new player take over this agent. None returns to npc""" - self._human = current_player is not None + self.is_player = current_player is not None self.clear_memory() self._current_player = current_player diff --git a/light/graph/structured_graph.py b/light/graph/structured_graph.py index 02ed53e7b..4430f3796 100644 --- a/light/graph/structured_graph.py +++ b/light/graph/structured_graph.py @@ -318,9 +318,7 @@ def get_npcs(self): """Get a list of agent nodes that aren't currently being played by a human character""" return [ - x - for x in self.agents.values() - if x._human is False and not x.is_player and not x.get_prop("dead") + x for x in self.agents.values() if x.is_player and not x.get_prop("dead") ] def set_desc(self, id, desc): diff --git a/light/world/content_loggers.py b/light/world/content_loggers.py index a572c25ae..f0021bcd5 100644 --- a/light/world/content_loggers.py +++ b/light/world/content_loggers.py @@ -296,7 +296,6 @@ def __init__( for node_id in self.graph.all_nodes[self.room_id].contained_nodes: if self.graph.all_nodes[node_id].agent and ( self.graph.all_nodes[node_id].is_player - or self.graph.all_nodes[node_id]._human ): self._add_player() @@ -406,7 +405,6 @@ def observe_event(self, event): def human_controlled(self, event): """ - Determines if an event is controlled by a human or not - - need ._human for legacy (web) + Determines if an event is controlled by a human or not """ - return event.actor.is_player or event.actor._human + return event.actor.is_player diff --git a/light/world/souls/README.md b/light/world/souls/README.md index 1d4e07fbe..4d7857819 100644 --- a/light/world/souls/README.md +++ b/light/world/souls/README.md @@ -14,4 +14,4 @@ When a `Soul`'s time is up, either due to the `GraphAgent` being removed from th Some `Soul`'s set flags on `GraphAgent`'s to be able to be interpreted by other `Soul`'s or elements of the world. These generally should be prepended with an `_` such that they don't get compressed into the saved formats. Current flags: -- `is_human`: Set by `PlayerSoul` to designate `GraphAgent`'s that are inhabited by a real player. Used by the world to ensure we don't doubly assign a `GraphAgent` to two different players, and by `ModelSoul`'s to differentiate between inter-model chat and chat with a human. +- `is_player`: Set by `PlayerSoul` to designate `GraphAgent`'s that are inhabited by a real player. Used by the world to ensure we don't doubly assign a `GraphAgent` to two different players, and by `ModelSoul`'s to differentiate between inter-model chat and chat with a human. diff --git a/light/world/souls/models/generative_heuristic_model_soul.py b/light/world/souls/models/generative_heuristic_model_soul.py index ffedaa6d6..654a9dd7e 100644 --- a/light/world/souls/models/generative_heuristic_model_soul.py +++ b/light/world/souls/models/generative_heuristic_model_soul.py @@ -399,7 +399,7 @@ def npc_dialogue(self, obs=None): self.dialogue_switch_partner(agent, partner) # TODO refactor with is_human when human flag is refactored - if not ALLOW_INTERBOT_CHAT and not partner._human: + if not ALLOW_INTERBOT_CHAT and not partner.is_player: return quest_txt = None @@ -422,7 +422,7 @@ def npc_dialogue(self, obs=None): event.skip_safety = True event.execute(self.world) return - + # Send to model to process msg = {"text": context, "episode_done": True} self.npc_dialog_model.observe(msg) diff --git a/light/world/souls/player_soul.py b/light/world/souls/player_soul.py index ab940d1f5..db2b601d0 100644 --- a/light/world/souls/player_soul.py +++ b/light/world/souls/player_soul.py @@ -12,7 +12,7 @@ import random import time from light.graph.events.graph_events import SystemMessageEvent - + if TYPE_CHECKING: from light.graph.elements.graph_nodes import GraphAgent from light.world.world import World @@ -43,9 +43,7 @@ def __init__( """ super().__init__(target_node, world) assert not target_node.is_player, "Cannot have two players in the same agent!" - # TODO merge these flags across LIGHT target_node.is_player = True - target_node._human = True target_node._last_action_time = time.time() self.player_id = player_id self.provider = provider # TODO link with real provider @@ -78,7 +76,12 @@ def handle_act(self, act_text, event_id: Optional[str] = None): # print debug information about humans playing instead humans = self.world.oo_graph.get_humans() num = len(humans) - txt = "There are " + str(num) + " LIGHT denizen(s) from your world on this plane: " + str(humans) + txt = ( + "There are " + + str(num) + + " LIGHT denizen(s) from your world on this plane: " + + str(humans) + ) event = SystemMessageEvent(self.target_node, [], text_content=txt) event.skip_safety = True event.execute(self.world) @@ -87,8 +90,7 @@ def handle_act(self, act_text, event_id: Optional[str] = None): actor = self.target_node actor._last_action_time = time.time() self.world.parse_exec(self.target_node, act_text, event_id=event_id) - - + def new_quest(self): if random.random() > 0.01: # Turn these mostly off for now. @@ -139,7 +141,6 @@ def reap(self): """ super().reap() self.target_node.is_player = False - self.target_node._human = False self.target_node.persona = self.target_node.persona.split(QUEST_TEXT)[0] self.world.oo_graph.room_id_to_loggers[ self.target_node.get_room().node_id diff --git a/light/world/souls/repeat_soul.py b/light/world/souls/repeat_soul.py index 973678e64..d4c4d80d6 100644 --- a/light/world/souls/repeat_soul.py +++ b/light/world/souls/repeat_soul.py @@ -32,7 +32,7 @@ async def observe_event(self, event: "GraphEvent"): """ if event.actor == self.target_node: return - if not (event.actor.is_player or event.actor._human): + if not (event.actor.is_player): return if self.target_node.is_dying(): return # Going to die, can't do anything diff --git a/light/world/world.py b/light/world/world.py index 7ae0b951f..c7f0378da 100644 --- a/light/world/world.py +++ b/light/world/world.py @@ -252,77 +252,6 @@ def node_contains(self, id): # TODO deprecate calls here, go to oo_graph return [x.node_id for x in self.oo_graph.get_node(id).get_contents()] - def get_available_actions_fast(self, agent_id): - """Get available actions quickly, some of these may not be possible. - NOTE: Jack can clean up later, but this seems to do everything need for NPCs - right now. Essentially I think such a function shouldn't be using strings - at all during reasoning, only ids all the way down until the last conversion - to action strings, which the existing code didn't seem to do..? - NOTE2: I've only included here actions actually in the LIGHT Turked dataset. - Easy to add more of course, such as wield. - This code is fairly fast (i measured like 10,000 calls in 0.8 secs). - """ - # TODO improve with graphs - acts = [] - room_id = self.room(agent_id) - nearby_ids = self.node_contains(room_id) - carrying_ids = self.node_contains(agent_id) - container_ids = [] - - for id in nearby_ids: - if id == agent_id: - continue - id_txt = self.node_to_desc(id).lower() - if self.has_prop(id, "agent"): - acts.append("hit " + id_txt) - acts.append("hug " + id_txt) - acts.append("examine " + id_txt) - for id2 in carrying_ids: - id2_txt = self.node_to_desc(id2).lower() - acts.append("give " + id2_txt + " to " + id_txt) - neighbor_carrying_ids = self.node_contains(id) - for id2 in neighbor_carrying_ids: - id2_txt = self.node_to_desc(id2).lower() - acts.append("steal " + id2_txt + " from " + id_txt) - if self.has_prop(id, "object"): - if not self.has_prop(id, "not_gettable"): - acts.append("get " + id_txt) - if not self.has_prop(id, "not_gettable") or self.has_prop(id, "human"): - # objects are examinable, - # except for non-gettable by NPCs, as it's boring. - acts.append("examine " + id_txt) - if self.has_prop(id, "container"): - container_ids.append(id) - - for id in carrying_ids: - if self.has_prop(id, "container"): - container_ids.append(id) - - for id in carrying_ids: - id_txt = self.node_to_desc(id).lower() - acts.append("examine " + id_txt) - acts.append("drop " + id_txt) - if self.has_prop(id, "equipped"): - acts.append("remove " + id_txt) - elif self.has_prop(id, "wearable"): - acts.append("wear " + id_txt) - if self.has_prop(id, "food"): - acts.append("eat " + id_txt) - if self.has_prop(id, "drink"): - acts.append("drink " + id_txt) - for id2 in container_ids: - id2_txt = self.node_to_desc(id2).lower() - acts.append("put " + id_txt + " in " + id2_txt) - - for id in container_ids: - id_txt = self.node_to_desc(id).lower() - inside_ids = self.node_contains(id) - for id2 in inside_ids: - id2_txt = self.node_to_desc(id2).lower() - acts.append("get " + id_txt + " from " + id2_txt) - - return acts - @deprecated def desc_to_nodes(self, desc, nearbyid=None, nearbytype=None): """Get nodes nearby to a given node from that node's perspective"""