Skip to content

Commit

Permalink
Babyagi agent support (#243)
Browse files Browse the repository at this point in the history
  • Loading branch information
hychen-naza committed Oct 2, 2023
1 parent a37d5f5 commit 50c9c97
Show file tree
Hide file tree
Showing 7 changed files with 487 additions and 79 deletions.
105 changes: 54 additions & 51 deletions camel/agents/task_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,11 @@ class TaskCreationAgent(ChatAgent):
`BabyAGI <https://github.com/yoheinakajima/babyagi>`_.
Attributes:
task_creation_prompt (TextPrompt): A prompt for the agent to create
new tasks.
task_creation_prompt (TextPrompt): A prompt for the agent to
create new tasks.
Args:
role_name (str): The role name of the Agent to create the task.
objective (Union[str, TextPrompt]): The objective of the Agent to
perform the task.
model (ModelType, optional): The type of model to use for the agent.
Expand All @@ -201,36 +202,47 @@ class TaskCreationAgent(ChatAgent):
(default: :obj:`None`)
output_language (str, optional): The language to be output by the
agent. (default: :obj:`None`)
message_window_size (int, optional): The maximum number of previous
messages to include in the context window. If `None`, no windowing
is performed. (default: :obj:`None`)
max_task_num (int, optional): The maximum number of planned
tasks in one round. (default: :obj:3)
"""

def __init__(
self,
role_name: str,
objective: Union[str, TextPrompt],
model: Optional[ModelType] = None,
model_config: Optional[Any] = None,
output_language: Optional[str] = None,
message_window_size: Optional[int] = None,
max_task_num: Optional[int] = 3,
) -> None:

task_creation_prompt = TextPrompt(
"""Create new tasks with the following objective: {objective}.
The last completed task has the result:
{task_result}.
This result was based on this task: {task}.
Based on the result, return a list of tasks to be completed in order to meet \
the objective.
{unsolved_tasks}
Return one task per line in your response.
"""Create new a task with the following objective: {objective}.
Never forget you are a Task Creator of {role_name}.
You must instruct me based on my expertise and your needs to solve the task.
You should consider past solved tasks and in-progress tasks: {task_list}.
The new created tasks must not overlap with these past tasks.
The result must be a numbered list in the format:
1. First task
2. Second task
#. First Task
#. Second Task
#. Third Task
The number of each entry must be followed by a period. Be concise.""")
You can only give me up to {max_task_num} tasks at a time. \
Each task shoud be concise, concrete and doable for a {role_name}.
You should make task plan and not ask me questions.
If you think no new tasks are needed right now, write "No tasks to add."
Now start to give me new tasks one by one. No more than three tasks.
Be concrete.
""")

self.task_creation_prompt = task_creation_prompt.format(
objective=objective)
objective=objective, role_name=role_name,
max_task_num=max_task_num)
self.objective = objective

system_message = BaseMessage(
Expand All @@ -241,45 +253,32 @@ def __init__(
)

super().__init__(system_message, model, model_config,
output_language=output_language)
output_language=output_language,
message_window_size=message_window_size)

def run(
self,
previous_task: Union[str, TextPrompt],
task_result: Union[str, TextPrompt],
task_list: Optional[List[str]] = None,
task_list: List[str],
) -> List[str]:
r"""Generate subtasks based on the previous task results and
incomplete task list.
Args:
previous_task (Union[str, TextPrompt]): The last completed task to
be used to create future plans.
task_result (Union[str, TextPrompt]): The result of last completed
task to be used to create future plans.
task_list (List[str], optional): The incomplete task list
which should not overlap with new created tasks.
(default: :obj:`None`)
task_list (List[str]): The completed or in-progress
tasks which should not overlap with new created tasks.
Returns:
List[str]: The new task list generated by the Agent.
"""
self.reset()
task_creation_prompt = self.task_creation_prompt.format(
task=previous_task, task_result=task_result)
if task_list is not None:
unsolved = (
f"These are unsolved tasks: {task_list}.\n"
"These new tasks must not overlap with incomplete tasks.")

task_creation_prompt = task_creation_prompt.format(
unsolved_tasks=unsolved)

if len(task_list) > 0:
task_creation_prompt = self.task_creation_prompt.format(
task_list=task_list)
else:
task_creation_prompt = task_creation_prompt.format(
unsolved_tasks="")
task_creation_prompt = self.task_creation_prompt.format(
task_list="")

task_msg = BaseMessage.make_user_message(role_name="Task Creator",
content=task_creation_prompt)

task_response = self.step(task_msg)

if len(task_response.msgs) == 0:
Expand Down Expand Up @@ -309,6 +308,9 @@ class TaskPrioritizationAgent(ChatAgent):
(default: :obj:`None`)
output_language (str, optional): The language to be output by the
agent. (default: :obj:`None`)
message_window_size (int, optional): The maximum number of previous
messages to include in the context window. If `None`, no windowing
is performed. (default: :obj:`None`)
"""

def __init__(
Expand All @@ -317,23 +319,24 @@ def __init__(
model: Optional[ModelType] = None,
model_config: Optional[Any] = None,
output_language: Optional[str] = None,
message_window_size: Optional[int] = None,
) -> None:

task_prioritization_prompt = TextPrompt(
"""Prioritize the following tasks : {task_list}.
Consider the ultimate objective of you: {objective}.
Tasks should be sorted from highest to lowest priority,
where higher-priority tasks are those that act as pre-requisites \
or are more essential for meeting the objective.
Return one task per line in your response. Do not remove any tasks.
Tasks should be sorted from highest to lowest priority, where higher-priority \
tasks are those that act as pre-requisites or are more essential for meeting \
the objective. Return one task per line in your response.
Do not remove or modify any tasks.
The result must be a numbered list in the format:
1. First task
2. Second task
#. First task
#. Second task
The entries must be consecutively numbered, starting with 1.
The number of each entry must be followed by a period.
Be concise.""")
Do not include any headers before your ranked list or follow your list \
with any other output.""")

self.task_prioritization_prompt = task_prioritization_prompt.format(
objective=objective)
Expand All @@ -347,7 +350,8 @@ def __init__(
)

super().__init__(system_message, model, model_config,
output_language=output_language)
output_language=output_language,
message_window_size=message_window_size)

def run(
self,
Expand All @@ -356,11 +360,10 @@ def run(
r"""Prioritize the task list given the agent objective.
Args:
task_list (List[str]): The un-prioritized task list of agent.
task_list (List[str]): The unprioritized tasks of agent.
Returns:
List[str]: The new prioritized task list generated by the Agent.
"""
self.reset()
task_prioritization_prompt = self.task_prioritization_prompt.format(
task_list=task_list)

Expand Down
2 changes: 2 additions & 0 deletions camel/societies/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
# limitations under the License.
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
from .role_playing import RolePlaying
from .babyagi_playing import BabyAGI

__all__ = [
'RolePlaying',
'BabyAGI',
]
Loading

0 comments on commit 50c9c97

Please sign in to comment.