Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/github/codeql-acti…
Browse files Browse the repository at this point in the history
…on-2.22.8
  • Loading branch information
jagapiou authored Dec 4, 2023
2 parents df1aaa1 + 6520408 commit b64287a
Show file tree
Hide file tree
Showing 31 changed files with 292 additions and 272 deletions.
8 changes: 0 additions & 8 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,3 @@ updates:
directory: /
schedule:
interval: monthly

- package-ecosystem: docker
directory: /.devcontainer
schedule:
interval: monthly
ignore:
- dependency-name: "vscode/devcontainers/python"
versions: [">= 3.11"]
2 changes: 1 addition & 1 deletion .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/dm-concordia
url: https://pypi.org/p/gdm-concordia
permissions:
id-token: write
timeout-minutes: 90
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pypi-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
- name: Install from PyPI
run: |
pip -vvv install dm-concordia
pip -vvv install gdm-concordia
pip list
- name: Test installation
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

*A library for generative social simulation*

[![Python](https://img.shields.io/pypi/pyversions/dm-concordia.svg)](https://pypi.python.org/pypi/dm-concordia)
[![PyPI version](https://img.shields.io/pypi/v/dm-concordia.svg)](https://pypi.python.org/pypi/dm-concordia)
[![Python](https://img.shields.io/pypi/pyversions/gdm-concordia.svg)](https://pypi.python.org/pypi/gdm-concordia)
[![PyPI version](https://img.shields.io/pypi/v/gdm-concordia.svg)](https://pypi.python.org/pypi/gdm-concordia)
[![PyPI tests](../../actions/workflows/pypi-test.yml/badge.svg)](../../actions/workflows/pypi-test.yml)
[![Tests](../../actions/workflows/test-concordia.yml/badge.svg)](../../actions/workflows/test-concordia.yml)
[![Examples](../../actions/workflows/test-examples.yml/badge.svg)](../../actions/workflows/test-examples.yml)
Expand Down
28 changes: 15 additions & 13 deletions concordia/agents/basic_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
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 Down Expand Up @@ -70,7 +70,7 @@ def __init__(
update_interval: how often to update components. In game time according to
the clock argument.
verbose: whether to print chains of thought or not
user_controlled: if True, would query user input for speach and action
user_controlled: if True, would query user input for speech and action
print_colour: which colour to use for printing
"""
self._verbose = verbose
Expand All @@ -86,6 +86,8 @@ def __init__(
self._update_interval = update_interval

self._under_interrogation = False
self._state_lock = threading.Lock()
self._state: str | None

self._components = {}
for comp in components:
Expand Down Expand Up @@ -166,10 +168,8 @@ def get_last_log(self):
return self._last_chain_of_thought

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

def _maybe_update(self):
next_update = self._last_update + self._update_interval
Expand All @@ -181,6 +181,11 @@ def update(self):
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 Expand Up @@ -257,19 +262,16 @@ def say(self, conversation: str) -> str:
f'{self._agent_name} is in the following'
f' conversation:\n{conversation}\n'
)
call_to_speach = (
f'Given the above, what should {self._agent_name} say next? Respond in'
f' the format `{self._agent_name} says: "..."` For example, '
'Cristina says: "Hello! Mighty fine weather today, right?" '
'or Ichabod says: "I wonder if the alfalfa is ready to harvest.\n'
call_to_speech = agent.DEFAULT_CALL_TO_SPEECH.format(
agent_name=self._agent_name,
)
if self._user_controlled:
utterance = self._ask_for_input(
convo_context + call_to_speach, f'{self._agent_name}:'
convo_context + call_to_speech, f'{self._agent_name}:'
)
else:
utterance = self.act(
action_spec=agent.ActionSpec(convo_context + call_to_speach, 'FREE'),
action_spec=agent.ActionSpec(convo_context + call_to_speech, 'FREE'),
)

return utterance
23 changes: 12 additions & 11 deletions concordia/agents/components/characteristic.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@


"""Agent characteristic component."""
import datetime
from typing import Callable

from concordia.associative_memory import associative_memory
from concordia.document import interactive_document
from concordia.language_model import language_model
from concordia.typing import clock as game_clock
from concordia.typing import component
import termcolor

Expand Down Expand Up @@ -50,7 +51,7 @@ def __init__(
memory: associative_memory.AssociativeMemory,
agent_name: str,
characteristic_name: str,
state_clock: game_clock.GameClock | None = None,
state_clock_now: Callable[[], datetime.datetime] | None = None,
extra_instructions: str = '',
num_memories_to_retrieve: int = 25,
verbose: bool = False,
Expand All @@ -62,7 +63,7 @@ def __init__(
memory: an associative memory
agent_name: the name of the agent
characteristic_name: the string to use in similarity search of memory
state_clock: if None then consider this component as representing a
state_clock_now: if None then consider this component as representing a
`trait`. If a clock is used then consider this component to represent a
`state`. A state is temporary whereas a trait is meant to endure.
extra_instructions: append additional instructions when asking the model
Expand All @@ -77,7 +78,7 @@ def __init__(
self._characteristic_name = characteristic_name
self._agent_name = agent_name
self._extra_instructions = extra_instructions
self._clock = state_clock
self._clock_now = state_clock_now
self._num_memories_to_retrieve = num_memories_to_retrieve

def name(self) -> str:
Expand All @@ -88,13 +89,13 @@ def state(self) -> str:

def update(self) -> None:
query = f"{self._agent_name}'s {self._characteristic_name}"
if self._clock is not None:
query = f'[{self._clock.now()}] {query}'
if self._clock_now is not None:
query = f'[{self._clock_now()}] {query}'

mems = '\n'.join(
self._memory.retrieve_associative(query,
self._num_memories_to_retrieve,
add_time=True)
self._memory.retrieve_associative(
query, self._num_memories_to_retrieve, add_time=True
)
)

prompt = interactive_document.InteractiveDocument(self._model)
Expand All @@ -105,8 +106,8 @@ def update(self) -> None:
f'{self._extra_instructions}'
f'Start the answer with "{self._agent_name} is"'
)
if self._clock is not None:
question = f'Current time: {self._clock.now()}.\n{question}'
if self._clock_now is not None:
question = f'Current time: {self._clock_now()}.\n{question}'

self._cache = prompt.open_question(
'\n'.join([question, f'Statements:\n{mems}']),
Expand Down
27 changes: 13 additions & 14 deletions concordia/agents/components/person_by_situation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
# limitations under the License.

"""Agent component for self perception."""

import datetime
from typing import Callable
from typing import Sequence

from concordia.associative_memory import associative_memory
from concordia.document import interactive_document
from concordia.language_model import language_model
from concordia.typing import clock
from concordia.typing import component
import termcolor

Expand All @@ -33,7 +34,7 @@ def __init__(
memory: associative_memory.AssociativeMemory,
agent_name: str,
components=Sequence[component.Component] | None,
state_clock: clock.GameClock | None = None,
clock_now: Callable[[], datetime.datetime] | None = None,
num_memories_to_retrieve: int = 25,
verbose: bool = False,
):
Expand All @@ -45,7 +46,7 @@ def __init__(
memory: The memory to use.
agent_name: The name of the agent.
components: The components to condition the answer on.
state_clock: The clock to use.
clock_now: time callback to use for the state.
num_memories_to_retrieve: The number of memories to retrieve.
verbose: Whether to print the state of the component.
"""
Expand All @@ -56,7 +57,7 @@ def __init__(
self._state = ''
self._components = components or []
self._agent_name = agent_name
self._clock = state_clock
self._clock_now = clock_now
self._num_memories_to_retrieve = num_memories_to_retrieve
self._name = name

Expand All @@ -77,21 +78,19 @@ def update(self) -> None:

prompt.statement(f'Memories of {self._agent_name}:\n{mems}')

component_states = '\n'.join(
[
f"{self._agent_name}'s "
+ (construct.name() + ':\n' + construct.state())
for construct in self._components
]
)
component_states = '\n'.join([
f"{self._agent_name}'s "
+ (construct.name() + ':\n' + construct.state())
for construct in self._components
])

prompt.statement(component_states)
question = (
f'What would a person like {self._agent_name} do in a situation like'
' this?'
)
if self._clock is not None:
question = f'Current time: {self._clock.now()}.\n{question}'
if self._clock_now is not None:
question = f'Current time: {self._clock_now()}.\n{question}'

self._state = prompt.open_question(
question,
Expand Down
7 changes: 3 additions & 4 deletions concordia/agents/components/report_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@

"""This components report what the get_state returns at the moment.
For example, can be used for reporting current time
For example, can be used for reporting current time
current_time_component = ReportState(
'Current time',
'Current time',
get_state=clock.current_time_interval_str)
"""

from typing import Callable
from concordia.typing import component


class ReportState(component.Component):
"""A component that shows the current time interval."""
"""A component that reports what the get_state returns at the moment."""

def __init__(self, get_state: Callable[[], str], name: str = 'State'):
"""Initializes the component.
Expand Down
13 changes: 7 additions & 6 deletions concordia/agents/components/self_perception.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
# limitations under the License.

"""Agent component for self perception."""
import datetime
from typing import Callable

from concordia.associative_memory import associative_memory
from concordia.document import interactive_document
from concordia.language_model import language_model
from concordia.typing import clock
from concordia.typing import component
import termcolor

Expand All @@ -31,7 +32,7 @@ def __init__(
model: language_model.LanguageModel,
memory: associative_memory.AssociativeMemory,
agent_name: str,
state_clock: clock.GameClock | None = None,
clock_now: Callable[[], datetime.datetime] | None = None,
num_memories_to_retrieve: int = 100,
verbose: bool = False,
):
Expand All @@ -42,7 +43,7 @@ def __init__(
model: Language model.
memory: Associative memory.
agent_name: Name of the agent.
state_clock: Clock to use for the state.
clock_now: time callback to use for the state.
num_memories_to_retrieve: Number of memories to retrieve.
verbose: Whether to print the state.
"""
Expand All @@ -52,7 +53,7 @@ def __init__(
self._memory = memory
self._state = ''
self._agent_name = agent_name
self._clock = state_clock
self._clock_now = clock_now
self._num_memories_to_retrieve = num_memories_to_retrieve
self._name = name

Expand All @@ -72,8 +73,8 @@ def update(self) -> None:
prompt = interactive_document.InteractiveDocument(self._model)
prompt.statement(f'Memories of {self._agent_name}:\n{mems}')

if self._clock is not None:
prompt.statement(f'Current time: {self._clock.now()}.\n')
if self._clock_now is not None:
prompt.statement(f'Current time: {self._clock_now()}.\n')

question = (
f'Given the memories above, what kind of person is {self._agent_name}?'
Expand Down
13 changes: 7 additions & 6 deletions concordia/agents/components/situation_perception.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
# limitations under the License.

"""Agent component for situation perception."""
import datetime
from typing import Callable

from concordia.associative_memory import associative_memory
from concordia.document import interactive_document
from concordia.language_model import language_model
from concordia.typing import clock
from concordia.typing import component
import termcolor

Expand All @@ -31,7 +32,7 @@ def __init__(
model: language_model.LanguageModel,
memory: associative_memory.AssociativeMemory,
agent_name: str,
state_clock: clock.GameClock | None = None,
clock_now: Callable[[], datetime.datetime] | None = None,
num_memories_to_retrieve: int = 25,
verbose: bool = False,
):
Expand All @@ -42,7 +43,7 @@ def __init__(
model: The language model to use.
memory: The memory to use.
agent_name: The name of the agent.
state_clock: The clock to use.
clock_now: time callback to use for the state.
num_memories_to_retrieve: The number of memories to retrieve.
verbose: Whether to print the last chain.
"""
Expand All @@ -51,7 +52,7 @@ def __init__(
self._memory = memory
self._state = ''
self._agent_name = agent_name
self._clock = state_clock
self._clock_now = clock_now
self._num_memories_to_retrieve = num_memories_to_retrieve
self._name = name

Expand All @@ -71,8 +72,8 @@ def update(self) -> None:
prompt = interactive_document.InteractiveDocument(self._model)
prompt.statement(f'Memories of {self._agent_name}:\n{mems}')

if self._clock is not None:
prompt.statement(f'Current time: {self._clock.now()}.\n')
if self._clock_now is not None:
prompt.statement(f'Current time: {self._clock_now()}.\n')

question = (
'Given the memories above, what kind of situation is'
Expand Down
Loading

0 comments on commit b64287a

Please sign in to comment.