Skip to content

Commit c89a6c5

Browse files
committed
release v2.0
2 parents 4ed4783 + 156fd57 commit c89a6c5

File tree

182 files changed

+17876
-140
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+17876
-140
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ cython_debug/
160160
# and can be added to the global gitignore or merged into this file. For a more nuclear
161161
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
162162
#.idea/
163-
.idea
163+
.idea/
164164
.vscode
165165
.DS_Store
166166
figs
@@ -169,3 +169,6 @@ frontend
169169
g_push.sh
170170
raw/
171171
!ui/src/**
172+
results
173+
tmp/
174+
data/toolbench

agentverse/__init__.py

+16-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
from .tasks import *
22

3+
34
# from .agents import Agent
45
from .environments import env_registry
5-
from .environments.rules import Rule
6-
from .environments.rules.order import order_registry
7-
from .environments.rules.describer import describer_registry
8-
from .environments.rules.selector import selector_registry
9-
from .environments.rules.updater import updater_registry
10-
from .environments.rules.visibility import visibility_registry
11-
from .agentverse import AgentVerse
6+
from .environments.simulation_env.rules.order import order_registry
7+
from .environments.simulation_env.rules.describer import describer_registry
8+
from .environments.simulation_env.rules.selector import selector_registry
9+
from .environments.simulation_env.rules.updater import updater_registry
10+
from .environments.simulation_env.rules.visibility import visibility_registry
11+
12+
13+
from .environments.tasksolving_env.rules.decision_maker import decision_maker_registry
14+
from .environments.tasksolving_env.rules.evaluator import evaluator_registry
15+
from .environments.tasksolving_env.rules.executor import executor_registry
16+
from .environments.tasksolving_env.rules.role_assigner import role_assigner_registry
17+
18+
19+
from .simulation import Simulation
20+
from .tasksolving import TaskSolving
1221
from .initialization import (
1322
prepare_task_config,
1423
load_agent,
1524
load_environment,
16-
load_tools,
1725
load_llm,
1826
load_memory,
1927
)

agentverse/agents/__init__.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,18 @@
33

44
agent_registry = Registry(name="AgentRegistry")
55

6+
67
from .base import BaseAgent
7-
from .conversation_agent import ConversationAgent
8-
from .tool_agent import ToolAgent
8+
from agentverse.agents.simulation_agent.conversation import ConversationAgent
9+
from agentverse.agents.simulation_agent.tool import ToolAgent
10+
from agentverse.agents.simulation_agent.prisoner_dilemma import (
11+
PoliceAgent,
12+
PrisonerAgent,
13+
)
914

10-
from .prisoner_dilemma_agent import PoliceAgent, PrisonerAgent
11-
from .reflection_agent import ReflectionAgent
15+
from agentverse.agents.tasksolving_agent.role_assigner import RoleAssignerAgent
16+
from agentverse.agents.tasksolving_agent.critic import CriticAgent
17+
from agentverse.agents.tasksolving_agent.evaluator import EvaluatorAgent
18+
from agentverse.agents.tasksolving_agent.solver import SolverAgent
19+
from agentverse.agents.tasksolving_agent.manager import ManagerAgent
20+
from agentverse.agents.tasksolving_agent.executor import ExecutorAgent

agentverse/agents/base.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
from abc import abstractmethod
33
from typing import List, NamedTuple, Set, Union
4+
from string import Template
45

56
from pydantic import BaseModel, Field
67

@@ -14,7 +15,9 @@ class BaseAgent(BaseModel):
1415
name: str
1516
llm: BaseLLM
1617
output_parser: OutputParser
17-
prompt_template: str
18+
prepend_prompt_template: str = Field(default="")
19+
append_prompt_template: str = Field(default="")
20+
prompt_template: str = Field(default="")
1821
role_description: str = Field(default="")
1922
memory: BaseMemory = Field(default_factory=ChatHistoryMemory)
2023
memory_manipulator: BaseMemoryManipulator = Field(default_factory=BaseMemoryManipulator)
@@ -42,6 +45,13 @@ def add_message_to_memory(self, messages: List[Message]) -> None:
4245
"""Add a message to the memory"""
4346
pass
4447

48+
def get_all_prompts(self, **kwargs):
49+
prepend_prompt = Template(self.prepend_prompt_template).safe_substitute(
50+
**kwargs
51+
)
52+
append_prompt = Template(self.append_prompt_template).safe_substitute(**kwargs)
53+
return prepend_prompt, append_prompt
54+
4555
def get_receiver(self) -> Set[str]:
4656
return self.receiver
4757

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
from __future__ import annotations
2+
from colorama import Fore
3+
4+
# import logging
5+
from agentverse.logging import get_logger
6+
import bdb
7+
from string import Template
8+
from typing import TYPE_CHECKING, List
9+
10+
from agentverse.message import Message
11+
12+
#from . import agent_registry
13+
#from .base import BaseAgent
14+
from agentverse.agents import agent_registry
15+
from agentverse.agents.base import BaseAgent
16+
17+
logger = get_logger()
18+
19+
20+
@agent_registry.register("conversation")
21+
class ConversationAgent(BaseAgent):
22+
def step(self, env_description: str = "") -> Message:
23+
prompt = self._fill_prompt_template(env_description)
24+
25+
parsed_response = None
26+
for i in range(self.max_retry):
27+
try:
28+
response = self.llm.generate_response(prompt)
29+
parsed_response = self.output_parser.parse(response)
30+
break
31+
except KeyboardInterrupt:
32+
raise
33+
except Exception as e:
34+
logger.error(e)
35+
logger.warn("Retrying...")
36+
continue
37+
38+
if parsed_response is None:
39+
logger.error(f"{self.name} failed to generate valid response.")
40+
41+
message = Message(
42+
content=""
43+
if parsed_response is None
44+
else parsed_response.return_values["output"],
45+
sender=self.name,
46+
receiver=self.get_receiver(),
47+
)
48+
return message
49+
50+
async def astep(self, env_description: str = "") -> Message:
51+
"""Asynchronous version of step"""
52+
prompt = self._fill_prompt_template(env_description)
53+
54+
parsed_response = None
55+
for i in range(self.max_retry):
56+
try:
57+
# if self.name == "Code Reviewer":
58+
logger.debug(prompt, "Prompt", Fore.CYAN)
59+
response = await self.llm.agenerate_response(prompt)
60+
61+
# logging.info(f"{self.name}'s request result:"
62+
# f" {response.content}")
63+
parsed_response = self.output_parser.parse(response)
64+
break
65+
except (KeyboardInterrupt, bdb.BdbQuit):
66+
raise
67+
except Exception as e:
68+
logger.error(e)
69+
logger.warning("Retrying...")
70+
continue
71+
72+
if parsed_response is None:
73+
logger.error(f"{self.name} failed to generate valid response.")
74+
75+
message = Message(
76+
content=""
77+
if parsed_response is None
78+
else parsed_response.return_values["output"],
79+
sender=self.name,
80+
receiver=self.get_receiver(),
81+
)
82+
return message
83+
84+
def _fill_prompt_template(self, env_description: str = "") -> str:
85+
"""Fill the placeholders in the prompt template
86+
87+
In the conversation agent, three placeholders are supported:
88+
- ${agent_name}: the name of the agent
89+
- ${env_description}: the description of the environment
90+
- ${role_description}: the description of the role of the agent
91+
- ${chat_history}: the chat history of the agent
92+
"""
93+
input_arguments = {
94+
"agent_name": self.name,
95+
"env_description": env_description,
96+
"role_description": self.role_description,
97+
"chat_history": self.memory.to_string(add_sender_prefix=True),
98+
}
99+
return Template(self.prompt_template).safe_substitute(input_arguments)
100+
101+
def add_message_to_memory(self, messages: List[Message]) -> None:
102+
self.memory.add_message(messages)
103+
104+
def reset(self) -> None:
105+
"""Reset the agent"""
106+
self.memory.reset()
107+
# TODO: reset receiver
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
from __future__ import annotations
2+
3+
import logging
4+
from string import Template
5+
from typing import TYPE_CHECKING, List
6+
7+
from agentverse.message import Message
8+
9+
#from . import agent_registry
10+
#from .base import BaseAgent
11+
from agentverse.agents import agent_registry
12+
from agentverse.agents.base import BaseAgent
13+
14+
if TYPE_CHECKING:
15+
from agentverse.environments.base import BaseEnvironment
16+
17+
18+
class PrisonerDilemaAgent(BaseAgent):
19+
def step(
20+
self,
21+
environment: BaseEnvironment,
22+
env_description: str = "",
23+
) -> Message:
24+
prompt = self._fill_prompt_template(env_description)
25+
26+
parsed_response = None
27+
for i in range(self.max_retry):
28+
try:
29+
response = self.llm.generate_response(prompt)
30+
parsed_response = self.output_parser.parse(self, environment, response)
31+
break
32+
except Exception as e:
33+
logging.error(e)
34+
logging.warning("Retrying...")
35+
continue
36+
37+
if parsed_response is None:
38+
logging.error(f"{self.name} failed to generate valid response.")
39+
40+
message = Message(
41+
content=""
42+
if parsed_response is None
43+
else parsed_response.return_values["output"],
44+
sender=self.name,
45+
receiver=self.get_receiver(),
46+
)
47+
return message
48+
49+
async def astep(
50+
self, environment: BaseEnvironment, env_description: str = ""
51+
) -> Message:
52+
"""Asynchronous version of step"""
53+
prompt = self._fill_prompt_template(env_description)
54+
55+
parsed_response = None
56+
for i in range(self.max_retry):
57+
try:
58+
response = await self.llm.agenerate_response(prompt)
59+
parsed_response = self.output_parser.parse(self, environment, response)
60+
break
61+
except Exception as e:
62+
logging.error(e)
63+
logging.warning("Retrying...")
64+
continue
65+
66+
if parsed_response is None:
67+
logging.error(f"{self.name} failed to generate valid response.")
68+
69+
message = Message(
70+
content=""
71+
if parsed_response is None
72+
else parsed_response.return_values["output"],
73+
sender=self.name,
74+
receiver=self.get_receiver(),
75+
)
76+
return message
77+
78+
def _fill_prompt_template(self, env_description: str = "") -> str:
79+
"""Fill the placeholders in the prompt template
80+
81+
In the conversation agent, three placeholders are supported:
82+
- ${agent_name}: the name of the agent
83+
- ${env_description}: the description of the environment
84+
- ${role_description}: the description of the role of the agent
85+
- ${chat_history}: the chat history of the agent
86+
"""
87+
input_arguments = {
88+
"agent_name": self.name,
89+
"env_description": env_description,
90+
"role_description": self.role_description,
91+
"chat_history": self.memory.to_string(add_sender_prefix=True),
92+
}
93+
return Template(self.prompt_template).safe_substitute(input_arguments)
94+
95+
def add_message_to_memory(self, messages: List[Message]) -> None:
96+
self.memory.add_message(messages)
97+
98+
def reset(self) -> None:
99+
"""Reset the agent"""
100+
self.memory.reset()
101+
# TODO: reset receiver
102+
103+
104+
@agent_registry.register("police")
105+
class PoliceAgent(PrisonerDilemaAgent):
106+
interrogating_form: str
107+
108+
def _fill_prompt_template(self, env_description: str = "") -> str:
109+
"""Fill the placeholders in the prompt template
110+
111+
In the conversation agent, three placeholders are supported:
112+
- ${agent_name}: the name of the agent
113+
- ${env_description}: the description of the environment
114+
- ${role_description}: the description of the role of the agent
115+
- ${chat_history}: the chat history of the agent
116+
"""
117+
input_arguments = {
118+
"agent_name": self.name,
119+
"env_description": env_description,
120+
"role_description": self.role_description,
121+
"chat_history": self.memory.to_string(add_sender_prefix=True),
122+
}
123+
124+
role_argument = {
125+
"interrogating_form": self.interrogating_form,
126+
}
127+
128+
role_description = Template(self.role_description).safe_substitute(
129+
role_argument
130+
)
131+
input_arguments["role_description"] = role_description
132+
133+
return Template(self.prompt_template).safe_substitute(input_arguments)
134+
135+
136+
@agent_registry.register("prisoner")
137+
class PrisonerAgent(PrisonerDilemaAgent):
138+
personality: str
139+
relationship_with_another: str
140+
141+
def _fill_prompt_template(self, env_description: str = "") -> str:
142+
"""Fill the placeholders in the prompt template
143+
144+
In the conversation agent, three placeholders are supported:
145+
- ${agent_name}: the name of the agent
146+
- ${env_description}: the description of the environment
147+
- ${role_description}: the description of the role of the agent
148+
- ${chat_history}: the chat history of the agent
149+
"""
150+
input_arguments = {
151+
"agent_name": self.name,
152+
"env_description": env_description,
153+
"role_description": self.role_description,
154+
"chat_history": self.memory.to_string(add_sender_prefix=True),
155+
}
156+
157+
role_argument = {
158+
"personality": self.personality,
159+
"relationship_with_another": self.relationship_with_another,
160+
}
161+
162+
role_description = Template(self.role_description).safe_substitute(
163+
role_argument
164+
)
165+
input_arguments["role_description"] = role_description
166+
167+
return Template(self.prompt_template).safe_substitute(input_arguments)

0 commit comments

Comments
 (0)