Skip to content

Commit

Permalink
Fixing the bug that was breaking conversation. The observation compon…
Browse files Browse the repository at this point in the history
…ent stacks observations into its state on arrival (without update). This is why agent needs to query component state every time while building the state. This is all still threadsafe, so no problems there. Also privatised _update in the basic agent. It is up to the agent when to update

PiperOrigin-RevId: 588022532
Change-Id: I28014e30afcfe6389d5faee0cd227b2c449cf5e1
  • Loading branch information
vezhnick authored and copybara-github committed Dec 5, 2023
1 parent a36c437 commit 0fc5aa7
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 26 deletions.
24 changes: 13 additions & 11 deletions concordia/agents/basic_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
Bernstein, M.S., 2023. Generative agents: Interactive simulacra of human
behavior. arXiv preprint arXiv:2304.03442.
"""

from collections.abc import Sequence
import concurrent
import contextlib
import copy
import datetime
import threading

from concordia.associative_memory import associative_memory
from concordia.document import interactive_document
from concordia.language_model import language_model
Expand All @@ -50,7 +51,7 @@ def __init__(
memory: associative_memory.AssociativeMemory,
agent_name: str,
clock: game_clock.GameClock,
components: list[component.Component] | None = None,
components: Sequence[component.Component] | None = None,
num_memories_retrieved: int = 10,
update_interval: datetime.timedelta = datetime.timedelta(hours=1),
verbose: bool = False,
Expand All @@ -64,7 +65,9 @@ def __init__(
memory: an associative memory
agent_name: the name of the agent
clock: the game clock is needed to know when is the current time
components: components that contextualise the policies
components: components that contextualise the policies. The components
state will be added to the agents state in the order they are passed
here.
num_memories_retrieved: number of memories to retrieve for acting,
speaking, testing
update_interval: how often to update components. In game time according to
Expand Down Expand Up @@ -96,6 +99,7 @@ def __init__(
self._log = []
self._last_chain_of_thought = None
self._last_update = datetime.datetime.min
self._update()

@property
def name(self) -> str:
Expand Down Expand Up @@ -169,23 +173,21 @@ def get_last_log(self):

def state(self):
with self._state_lock:
return self._state
return '\n'.join(
f"{self._agent_name}'s " + (comp.name() + ':\n' + comp.state())
for comp in self._components.values()
)

def _maybe_update(self):
next_update = self._last_update + self._update_interval
if self._clock.now() >= next_update and not self._under_interrogation:
self.update()
self._update()

def update(self):
def _update(self):
self._last_update = self._clock.now()
with concurrent.futures.ThreadPoolExecutor() as executor:
for comp in self._components.values():
executor.submit(comp.update)
with self._state_lock:
self._state = '\n'.join(
f"{self._agent_name}'s " + (comp.name() + ':\n' + comp.state())
for comp in self._components.values()
)

def observe(self, observation: str):
if observation and not self._under_interrogation:
Expand Down
1 change: 0 additions & 1 deletion concordia/environment/components/conversation.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ def _make_npc(
],
verbose=True,
)
npc.update()
return npc

def _get_nonplayer_characters(
Expand Down
6 changes: 1 addition & 5 deletions concordia/examples/magic_beans_for_sale.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -654,11 +654,7 @@
"outputs": [],
"source": [
"for player in players:\n",
" player.observe(scenario_premise)\n",
"\n",
"with concurrent.futures.ThreadPoolExecutor(max_workers=NUM_PLAYERS) as pool:\n",
" for player in players:\n",
" pool.submit(player.update())"
" player.observe(scenario_premise)\n"
]
},
{
Expand Down
10 changes: 2 additions & 8 deletions concordia/examples/phone/calendar.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
"# @title SAX Language Model\n",
"\n",
"# Add path to your SAX server here:\n",
"SAX_PATH = '' # @param {type:\"string\"}\n",
"SAX_PATH = '' # @param {type:\"string\"}\n",
"DEFAULT_MAX_TOKENS = 300 # @param {type: 'integer'}\n",
"DEFAULT_TIMEOUT_SECONDS = 60 # @param {type: 'number'}\n",
"\n",
Expand Down Expand Up @@ -253,8 +253,6 @@
" components=[identity, plan, somatic_state, summary_obs, current_obs, time],\n",
" )\n",
"\n",
" agent.update()\n",
"\n",
" return agent"
]
},
Expand Down Expand Up @@ -475,11 +473,7 @@
"outputs": [],
"source": [
"for player in players:\n",
" player.observe( f'{player.name} is at home, they have just woken up.')\n",
"\n",
"with concurrent.futures.ThreadPoolExecutor(max_workers=len(players)) as pool:\n",
" for player in players:\n",
" pool.submit(player.update())"
" player.observe( f'{player.name} is at home, they have just woken up.')"
]
},
{
Expand Down
1 change: 0 additions & 1 deletion examples/village/day_in_riverbend.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@
" verbose=True,\n",
" components=[identity, plan, reflection, time, summary_obs, current_obs],\n",
" )\n",
" agent.update()\n",
"\n",
" return agent"
]
Expand Down

0 comments on commit 0fc5aa7

Please sign in to comment.