Skip to content

Commit

Permalink
Merge branch 'main' of github.com:OpenBMB/AgentVerse into main
Browse files Browse the repository at this point in the history
  • Loading branch information
chenweize1998 committed Oct 27, 2023
2 parents 81a964c + 64db306 commit f0ddd0e
Show file tree
Hide file tree
Showing 31 changed files with 642 additions and 242 deletions.
18 changes: 16 additions & 2 deletions agentverse/agents/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
from string import Template

from pydantic import BaseModel, Field

from agentverse.llms import BaseLLM

from agentverse.llms.utils import count_string_tokens
from agentverse.memory import BaseMemory, ChatHistoryMemory
from agentverse.message import Message
from agentverse.output_parser import OutputParser
Expand Down Expand Up @@ -62,7 +63,20 @@ def get_all_prompts(self, **kwargs):
**kwargs
)
append_prompt = Template(self.append_prompt_template).safe_substitute(**kwargs)
return prepend_prompt, append_prompt

# TODO: self.llm.args.model is not generalizable
num_prepend_prompt_token = count_string_tokens(
prepend_prompt, self.llm.args.model
)
num_append_prompt_token = count_string_tokens(
append_prompt, self.llm.args.model
)

return (
prepend_prompt,
append_prompt,
num_prepend_prompt_token + num_append_prompt_token,
)

def get_receiver(self) -> Set[str]:
return self.receiver
Expand Down
13 changes: 11 additions & 2 deletions agentverse/agents/tasksolving_agent/critic.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async def astep(
) -> CriticMessage:
"""Asynchronous version of step"""
logger.debug("", self.name, Fore.MAGENTA)
prepend_prompt, append_prompt = self.get_all_prompts(
prepend_prompt, append_prompt, prompt_token = self.get_all_prompts(
preliminary_solution=preliminary_solution,
advice=advice,
task_description=task_description,
Expand All @@ -72,7 +72,16 @@ async def astep(
# tool_names=self.tool_names,
tool_descriptions=self.tool_descriptions,
)
history = self.memory.to_messages(self.name, start_index=-self.max_history)

max_send_token = self.llm.send_token_limit(self.llm.args.model)
max_send_token -= prompt_token

history = await self.memory.to_messages(
self.name,
start_index=-self.max_history,
max_send_token=max_send_token,
model=self.llm.args.model,
)
parsed_response: Union[AgentCriticism, None] = None
for i in range(self.max_retry):
try:
Expand Down
33 changes: 25 additions & 8 deletions agentverse/agents/tasksolving_agent/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,47 @@

@agent_registry.register("evaluator")
class EvaluatorAgent(BaseAgent):
max_history: int = 5

def step(
self,
solution: str,
result: str,
task_description: str,
all_role_description: str,
) -> EvaluatorMessage:
pass
# return parsed_response

async def astep(
self,
solution: str,
result: str,
task_description: str,
all_role_description: str,
) -> EvaluatorMessage:
"""Asynchronous version of step"""
logger.debug("", self.name, Fore.MAGENTA)
prepend_prompt, append_prompt = self.get_all_prompts(
prepend_prompt, append_prompt, prompt_token = self.get_all_prompts(
solution=solution,
result=result,
task_description=task_description,
all_role_description=all_role_description,
)
history = self.memory.to_messages(self.name)

max_send_token = self.llm.send_token_limit(self.llm.args.model)
max_send_token -= prompt_token

history = await self.memory.to_messages(
self.name,
start_index=-self.max_history,
max_send_token=max_send_token,
model=self.llm.args.model,
)
parsed_response = None
for i in range(self.max_retry):
try:
response = self.llm.generate_response(
response = await self.llm.agenerate_response(
prepend_prompt, history, append_prompt
)
parsed_response = self.output_parser.parse(response)
Expand All @@ -58,11 +80,6 @@ def step(
advice=parsed_response[1] if parsed_response is not None else "",
)
return message
# return parsed_response

async def astep(self, solution: str) -> EvaluatorMessage:
"""Asynchronous version of step"""
pass

def _fill_prompt_template(self, solution: str, task_description: str) -> str:
"""Fill the placeholders in the prompt template
Expand Down
59 changes: 11 additions & 48 deletions agentverse/agents/tasksolving_agent/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,65 +23,28 @@ class ExecutorAgent(BaseAgent):
def step(
self, task_description: str, solution: str, tools: List[dict] = [], **kwargs
) -> ExecutorMessage:
logger.debug("", self.name, Fore.MAGENTA)
prepend_prompt, append_prompt = self.get_all_prompts(
task_description=task_description,
solution=solution,
agent_name=self.name,
**kwargs,
)

history = self.memory.to_messages(self.name, start_index=-self.max_history)
parsed_response = None
for i in range(self.max_retry):
try:
response = self.llm.generate_response(
prepend_prompt, history, append_prompt, tools
)
parsed_response = self.output_parser.parse(response)
break
except (KeyboardInterrupt, bdb.BdbQuit):
raise
except Exception as e:
logger.error(e)
logger.warn("Retrying...")
continue

if parsed_response is None:
logger.error(f"{self.name} failed to generate valid response.")
if isinstance(parsed_response, AgentFinish):
message = ExecutorMessage(
content=parsed_response.return_values["output"],
sender=self.name,
sender_agent=self,
)
elif isinstance(parsed_response, AgentAction):
message = ExecutorMessage(
content=parsed_response.log,
sender=self.name,
sender_agent=self,
tool_name=parsed_response.tool,
tool_input=parsed_response.tool_input,
)
else:
raise ValueError(
f"Error response type: {type(parsed_response)}. Only support \
AgentFinish and AgentAction. Modify your output parser."
)
return message
pass

async def astep(
self, task_description: str, solution: str, tools: List[dict] = [], **kwargs
) -> ExecutorMessage:
logger.debug("", self.name, Fore.MAGENTA)
prepend_prompt, append_prompt = self.get_all_prompts(
prepend_prompt, append_prompt, prompt_token = self.get_all_prompts(
task_description=task_description,
solution=solution,
agent_name=self.name,
**kwargs,
)

history = self.memory.to_messages(self.name, start_index=-self.max_history)
max_send_token = self.llm.send_token_limit(self.llm.args.model)
max_send_token -= prompt_token

history = await self.memory.to_messages(
self.name,
start_index=-self.max_history,
max_send_token=max_send_token,
model=self.llm.args.model,
)
parsed_response = None
for i in range(self.max_retry):
try:
Expand Down
27 changes: 20 additions & 7 deletions agentverse/agents/tasksolving_agent/role_assigner.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,37 @@

@agent_registry.register("role_assigner")
class RoleAssignerAgent(BaseAgent):
max_history: int = 5

def step(
self, advice: str, task_description: str, cnt_critic_agents: int
) -> RoleAssignerMessage:
pass

async def astep(
self, advice: str, task_description: str, cnt_critic_agents: int
) -> RoleAssignerMessage:
"""Asynchronous version of step"""
logger.debug("", self.name, Fore.MAGENTA)
prepend_prompt, append_prompt = self.get_all_prompts(
prepend_prompt, append_prompt, prompt_token = self.get_all_prompts(
advice=advice,
task_description=task_description,
cnt_critic_agents=cnt_critic_agents,
)
history = self.memory.to_messages(self.name)

max_send_token = self.llm.send_token_limit(self.llm.args.model)
max_send_token -= prompt_token

history = await self.memory.to_messages(
self.name,
start_index=-self.max_history,
max_send_token=max_send_token,
model=self.llm.args.model,
)
parsed_response = None
for i in range(self.max_retry):
try:
response = self.llm.generate_response(
response = await self.llm.agenerate_response(
prepend_prompt, history, append_prompt
)
parsed_response = self.output_parser.parse(response)
Expand All @@ -58,10 +75,6 @@ def step(
)
return message

async def astep(self, env_description: str = "") -> RoleAssignerMessage:
"""Asynchronous version of step"""
pass

def _fill_prompt_template(
self, advice, task_description: str, cnt_critic_agents: int
) -> str:
Expand Down
28 changes: 19 additions & 9 deletions agentverse/agents/tasksolving_agent/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,47 @@
from agentverse.agents.base import BaseAgent
from agentverse.utils import AgentCriticism


logger = get_logger()


@agent_registry.register("solver")
class SolverAgent(BaseAgent):
max_history: int = 3
max_history: int = 5

def step(
self, former_solution: str, advice: str, task_description: str = "", **kwargs
) -> SolverMessage:
pass

async def astep(
self, former_solution: str, advice: str, task_description: str = "", **kwargs
) -> SolverMessage:
"""Asynchronous version of step"""
logger.debug("", self.name, Fore.MAGENTA)
# prompt = self._fill_prompt_template(
# former_solution, critic_opinions, advice, task_description
# )
prepend_prompt, append_prompt = self.get_all_prompts(
prepend_prompt, append_prompt, prompt_token = self.get_all_prompts(
former_solution=former_solution,
task_description=task_description,
advice=advice,
role_description=self.role_description,
**kwargs,
)
history = self.memory.to_messages(self.name, start_index=-self.max_history)

max_send_token = self.llm.send_token_limit(self.llm.args.model)
max_send_token -= prompt_token

history = await self.memory.to_messages(
self.name,
start_index=-self.max_history,
max_send_token=max_send_token,
model=self.llm.args.model,
)
parsed_response = None
for i in range(self.max_retry):
try:
response = self.llm.generate_response(
response = await self.llm.agenerate_response(
prepend_prompt, history, append_prompt
)
parsed_response = self.output_parser.parse(response)
Expand All @@ -65,10 +79,6 @@ def step(
)
return message

async def astep(self, env_description: str = "") -> SolverMessage:
"""Asynchronous version of step"""
pass

def _fill_prompt_template(
self,
former_solution: str,
Expand Down
4 changes: 2 additions & 2 deletions agentverse/environments/tasksolving_env/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async def step(
logger.info(f"Loop Round {self.cnt_turn}")

# ================== EXPERT RECRUITMENT ==================
agents = self.rule.role_assign(
agents = await self.rule.role_assign(
self.task_description, self.agents, self.cnt_turn, advice
)
description = "\n".join([agent.role_description for agent in agents])
Expand Down Expand Up @@ -79,7 +79,7 @@ async def step(
# ================== EXECUTION ==================

# ================== EVALUATION ==================
score, advice = self.rule.evaluate(
score, advice = await self.rule.evaluate(
self.task_description, self.agents, plan, result
)
logs.append(
Expand Down
8 changes: 4 additions & 4 deletions agentverse/environments/tasksolving_env/rules/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def build_components(config: Dict, registry):
**kwargs,
)

def role_assign(
async def role_assign(
self,
task_description: str,
agents: List[BaseAgent],
Expand All @@ -79,7 +79,7 @@ def role_assign(
if self.role_assign_only_once and cnt_turn > 0:
agents = [agents[AGENT_TYPES.SOLVER]] + agents[AGENT_TYPES.CRITIC]
else:
agents = self.role_assigner.step(
agents = await self.role_assigner.astep(
role_assigner=agents[AGENT_TYPES.ROLE_ASSIGNMENT],
group_members=[agents[AGENT_TYPES.SOLVER]] + agents[AGENT_TYPES.CRITIC],
advice=advice,
Expand Down Expand Up @@ -137,7 +137,7 @@ async def execute(
agents[AGENT_TYPES.SOLVER].add_message_to_memory(results)
return results

def evaluate(
async def evaluate(
self,
task_description: str,
agents: List[BaseAgent],
Expand All @@ -162,7 +162,7 @@ def evaluate(
# logger.error("Bad response from human evaluator!")
# return ([comprehensiveness, detailedness, feasibility, novelty], advice)
# else:
evaluation = self.evaluator.step(
evaluation = await self.evaluator.astep(
agent=agents[AGENT_TYPES.EVALUATION],
solution=solution,
result=result,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async def astep(
Fore.YELLOW,
)

result = agents[0].step(previous_plan, advice, task_description)
result = await agents[0].astep(previous_plan, advice, task_description)
for agent in agents:
agent.memory.reset()
self.broadcast_messages(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async def astep(
),
)
agents[1].add_message_to_memory([result])
result = agents[0].step(
result = await agents[0].astep(
previous_plan, advice, task_description, chat_record=result.content
)
return [result]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async def astep(
last_reviews = nonempty_reviews

agents[0].add_message_to_memory(last_reviews)
result = agents[0].step(previous_plan, advice, task_description)
result = await agents[0].astep(previous_plan, advice, task_description)
# agents[0].add_message_to_memory([result])
self.broadcast_messages(agents, [result])
return [result]
Expand Down
Loading

0 comments on commit f0ddd0e

Please sign in to comment.