camel-ai 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of camel-ai might be problematic. Click here for more details.
- camel/__init__.py +30 -0
- camel/agents/__init__.py +40 -0
- camel/agents/base.py +29 -0
- camel/agents/chat_agent.py +539 -0
- camel/agents/critic_agent.py +179 -0
- camel/agents/embodied_agent.py +138 -0
- camel/agents/role_assignment_agent.py +117 -0
- camel/agents/task_agent.py +382 -0
- camel/agents/tool_agents/__init__.py +20 -0
- camel/agents/tool_agents/base.py +40 -0
- camel/agents/tool_agents/hugging_face_tool_agent.py +203 -0
- camel/configs.py +159 -0
- camel/embeddings/__init__.py +20 -0
- camel/embeddings/base.py +65 -0
- camel/embeddings/openai_embedding.py +74 -0
- camel/functions/__init__.py +27 -0
- camel/functions/base_io_functions.py +261 -0
- camel/functions/math_functions.py +61 -0
- camel/functions/openai_function.py +88 -0
- camel/functions/search_functions.py +309 -0
- camel/functions/unstructured_io_fuctions.py +616 -0
- camel/functions/weather_functions.py +136 -0
- camel/generators.py +263 -0
- camel/human.py +130 -0
- camel/memories/__init__.py +28 -0
- camel/memories/base.py +75 -0
- camel/memories/chat_history_memory.py +111 -0
- camel/memories/context_creators/__init__.py +18 -0
- camel/memories/context_creators/base.py +72 -0
- camel/memories/context_creators/score_based.py +130 -0
- camel/memories/records.py +92 -0
- camel/messages/__init__.py +38 -0
- camel/messages/base.py +223 -0
- camel/messages/func_message.py +106 -0
- camel/models/__init__.py +26 -0
- camel/models/base_model.py +110 -0
- camel/models/model_factory.py +59 -0
- camel/models/open_source_model.py +144 -0
- camel/models/openai_model.py +103 -0
- camel/models/stub_model.py +106 -0
- camel/prompts/__init__.py +38 -0
- camel/prompts/ai_society.py +121 -0
- camel/prompts/base.py +227 -0
- camel/prompts/code.py +111 -0
- camel/prompts/evaluation.py +40 -0
- camel/prompts/misalignment.py +84 -0
- camel/prompts/prompt_templates.py +117 -0
- camel/prompts/role_description_prompt_template.py +53 -0
- camel/prompts/solution_extraction.py +44 -0
- camel/prompts/task_prompt_template.py +56 -0
- camel/prompts/translation.py +42 -0
- camel/responses/__init__.py +18 -0
- camel/responses/agent_responses.py +42 -0
- camel/societies/__init__.py +20 -0
- camel/societies/babyagi_playing.py +254 -0
- camel/societies/role_playing.py +456 -0
- camel/storages/__init__.py +23 -0
- camel/storages/key_value_storages/__init__.py +23 -0
- camel/storages/key_value_storages/base.py +57 -0
- camel/storages/key_value_storages/in_memory.py +51 -0
- camel/storages/key_value_storages/json.py +97 -0
- camel/terminators/__init__.py +23 -0
- camel/terminators/base.py +44 -0
- camel/terminators/response_terminator.py +118 -0
- camel/terminators/token_limit_terminator.py +55 -0
- camel/types/__init__.py +54 -0
- camel/types/enums.py +176 -0
- camel/types/openai_types.py +39 -0
- camel/utils/__init__.py +47 -0
- camel/utils/commons.py +243 -0
- camel/utils/python_interpreter.py +435 -0
- camel/utils/token_counting.py +220 -0
- camel_ai-0.1.1.dist-info/METADATA +311 -0
- camel_ai-0.1.1.dist-info/RECORD +75 -0
- camel_ai-0.1.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
import warnings
|
|
15
|
+
from typing import Any, Optional
|
|
16
|
+
|
|
17
|
+
from camel.prompts import TaskPromptTemplateDict, TextPrompt
|
|
18
|
+
from camel.types import RoleType, TaskType
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PromptTemplateGenerator:
|
|
22
|
+
r"""A class for generating prompt templates for tasks.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
task_prompt_template_dict (TaskPromptTemplateDict, optional):
|
|
26
|
+
A dictionary of task prompt templates for each task type. If not
|
|
27
|
+
provided, an empty dictionary is used as default.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
task_prompt_template_dict: Optional[TaskPromptTemplateDict] = None,
|
|
33
|
+
) -> None:
|
|
34
|
+
self.task_prompt_template_dict = (task_prompt_template_dict
|
|
35
|
+
or TaskPromptTemplateDict())
|
|
36
|
+
|
|
37
|
+
def get_prompt_from_key(self, task_type: TaskType, key: Any) -> TextPrompt:
|
|
38
|
+
r"""Generates a text prompt using the specified :obj:`task_type` and
|
|
39
|
+
:obj:`key`.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
task_type (TaskType): The type of task.
|
|
43
|
+
key (Any): The key used to generate the prompt.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
TextPrompt: The generated text prompt.
|
|
47
|
+
|
|
48
|
+
Raises:
|
|
49
|
+
KeyError: If failed to generate prompt using the specified
|
|
50
|
+
:obj:`task_type` and :obj:`key`.
|
|
51
|
+
"""
|
|
52
|
+
try:
|
|
53
|
+
return self.task_prompt_template_dict[task_type][key]
|
|
54
|
+
|
|
55
|
+
except KeyError:
|
|
56
|
+
raise KeyError("Failed to get generate prompt template for "
|
|
57
|
+
f"task: {task_type.value} from key: {key}.")
|
|
58
|
+
|
|
59
|
+
def get_system_prompt(
|
|
60
|
+
self,
|
|
61
|
+
task_type: TaskType,
|
|
62
|
+
role_type: RoleType,
|
|
63
|
+
) -> TextPrompt:
|
|
64
|
+
r"""Generates a text prompt for the system role, using the specified
|
|
65
|
+
:obj:`task_type` and :obj:`role_type`.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
task_type (TaskType): The type of task.
|
|
69
|
+
role_type (RoleType): The type of role, either "USER" or
|
|
70
|
+
"ASSISTANT".
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
TextPrompt: The generated text prompt.
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
KeyError: If failed to generate prompt using the specified
|
|
77
|
+
:obj:`task_type` and :obj:`role_type`.
|
|
78
|
+
"""
|
|
79
|
+
try:
|
|
80
|
+
return self.get_prompt_from_key(task_type, role_type)
|
|
81
|
+
|
|
82
|
+
except KeyError:
|
|
83
|
+
prompt = "You are a helpful assistant."
|
|
84
|
+
|
|
85
|
+
warnings.warn("Failed to get system prompt template for "
|
|
86
|
+
f"task: {task_type.value}, role: {role_type.value}. "
|
|
87
|
+
f"Set template to: {prompt}")
|
|
88
|
+
|
|
89
|
+
return TextPrompt(prompt)
|
|
90
|
+
|
|
91
|
+
def get_generate_tasks_prompt(
|
|
92
|
+
self,
|
|
93
|
+
task_type: TaskType,
|
|
94
|
+
) -> TextPrompt:
|
|
95
|
+
r"""Gets the prompt for generating tasks for a given task type.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
task_type (TaskType): The type of the task.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
TextPrompt: The generated prompt for generating tasks.
|
|
102
|
+
"""
|
|
103
|
+
return self.get_prompt_from_key(task_type, "generate_tasks")
|
|
104
|
+
|
|
105
|
+
def get_task_specify_prompt(
|
|
106
|
+
self,
|
|
107
|
+
task_type: TaskType,
|
|
108
|
+
) -> TextPrompt:
|
|
109
|
+
r"""Gets the prompt for specifying a task for a given task type.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
task_type (TaskType): The type of the task.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
TextPrompt: The generated prompt for specifying a task.
|
|
116
|
+
"""
|
|
117
|
+
return self.get_prompt_from_key(task_type, "task_specify_prompt")
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from camel.prompts import AISocietyPromptTemplateDict, TextPrompt
|
|
17
|
+
from camel.types import RoleType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# flake8: noqa :E501
|
|
21
|
+
class RoleDescriptionPromptTemplateDict(AISocietyPromptTemplateDict):
|
|
22
|
+
r"""A dictionary containing :obj:`TextPrompt` used in the `role description`
|
|
23
|
+
task.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
ROLE_DESCRIPTION_PROMPT (TextPrompt): A default prompt to
|
|
27
|
+
describe the role descriptions.
|
|
28
|
+
ASSISTANT_PROMPT (TextPrompt): A system prompt for the AI assistant
|
|
29
|
+
that outlines the rules of the conversation and provides
|
|
30
|
+
instructions for completing tasks.
|
|
31
|
+
USER_PROMPT (TextPrompt): A system prompt for the AI user that
|
|
32
|
+
outlines the rules of the conversation and provides instructions
|
|
33
|
+
for giving instructions to the AI assistant.
|
|
34
|
+
"""
|
|
35
|
+
ROLE_DESCRIPTION_PROMPT = TextPrompt("""===== ROLES WITH DESCRIPTION =====
|
|
36
|
+
{user_role} and {assistant_role} are collaborating to complete a task: {task}.
|
|
37
|
+
Competencies, characteristics, duties and workflows of {user_role} to complete the task: {user_description}
|
|
38
|
+
{assistant_role}'s competencies, characteristics, duties and workflows to complete the task: {assistant_description}
|
|
39
|
+
""")
|
|
40
|
+
|
|
41
|
+
ASSISTANT_PROMPT = TextPrompt(ROLE_DESCRIPTION_PROMPT +
|
|
42
|
+
AISocietyPromptTemplateDict.ASSISTANT_PROMPT)
|
|
43
|
+
|
|
44
|
+
USER_PROMPT = TextPrompt(ROLE_DESCRIPTION_PROMPT +
|
|
45
|
+
AISocietyPromptTemplateDict.USER_PROMPT)
|
|
46
|
+
|
|
47
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
48
|
+
super().__init__(*args, **kwargs)
|
|
49
|
+
self.update({
|
|
50
|
+
"role_description": self.ROLE_DESCRIPTION_PROMPT,
|
|
51
|
+
RoleType.ASSISTANT: self.ASSISTANT_PROMPT,
|
|
52
|
+
RoleType.USER: self.USER_PROMPT,
|
|
53
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from camel.prompts import TextPrompt, TextPromptDict
|
|
17
|
+
from camel.types import RoleType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# flake8: noqa
|
|
21
|
+
class SolutionExtractionPromptTemplateDict(TextPromptDict):
|
|
22
|
+
r"""A dictionary containing :obj:`TextPrompt` used in the `SolutionExtraction`
|
|
23
|
+
task.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
ASSISTANT_PROMPT (TextPrompt): A system prompt for the AI assistant
|
|
27
|
+
that outlines the rules of the conversation and provides
|
|
28
|
+
instructions for completing tasks.
|
|
29
|
+
"""
|
|
30
|
+
ASSISTANT_PROMPT = TextPrompt(
|
|
31
|
+
"""You are an experienced solution extracting agent.
|
|
32
|
+
Your task is to extract full and complete solutions by looking at the conversation between a user and an assistant with particular specializations.
|
|
33
|
+
You should present me with a final and detailed solution purely based on the conversation.
|
|
34
|
+
You should present the solution as if its yours.
|
|
35
|
+
Use present tense and as if you are the one presenting the solution.
|
|
36
|
+
You should not miss any necessary details or examples.
|
|
37
|
+
Keep all provided explanations and codes provided throughout the conversation.
|
|
38
|
+
Remember your task is not to summarize rather to extract the full solution.""")
|
|
39
|
+
|
|
40
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
41
|
+
super().__init__(*args, **kwargs)
|
|
42
|
+
self.update({
|
|
43
|
+
RoleType.ASSISTANT: self.ASSISTANT_PROMPT,
|
|
44
|
+
})
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from typing import Any, Dict
|
|
15
|
+
|
|
16
|
+
from camel.prompts import (
|
|
17
|
+
AISocietyPromptTemplateDict,
|
|
18
|
+
CodePromptTemplateDict,
|
|
19
|
+
EvaluationPromptTemplateDict,
|
|
20
|
+
MisalignmentPromptTemplateDict,
|
|
21
|
+
RoleDescriptionPromptTemplateDict,
|
|
22
|
+
SolutionExtractionPromptTemplateDict,
|
|
23
|
+
TextPromptDict,
|
|
24
|
+
TranslationPromptTemplateDict,
|
|
25
|
+
)
|
|
26
|
+
from camel.types import TaskType
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TaskPromptTemplateDict(Dict[Any, TextPromptDict]):
|
|
30
|
+
r"""A dictionary (:obj:`Dict[Any, TextPromptDict]`) of task prompt
|
|
31
|
+
templates keyed by task type. This dictionary is used to map from
|
|
32
|
+
a task type to its corresponding prompt template dictionary.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
*args: Positional arguments passed to the :obj:`dict` constructor.
|
|
36
|
+
**kwargs: Keyword arguments passed to the :obj:`dict` constructor.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
40
|
+
super().__init__(*args, **kwargs)
|
|
41
|
+
self.update({
|
|
42
|
+
TaskType.AI_SOCIETY:
|
|
43
|
+
AISocietyPromptTemplateDict(),
|
|
44
|
+
TaskType.CODE:
|
|
45
|
+
CodePromptTemplateDict(),
|
|
46
|
+
TaskType.MISALIGNMENT:
|
|
47
|
+
MisalignmentPromptTemplateDict(),
|
|
48
|
+
TaskType.TRANSLATION:
|
|
49
|
+
TranslationPromptTemplateDict(),
|
|
50
|
+
TaskType.EVALUATION:
|
|
51
|
+
EvaluationPromptTemplateDict(),
|
|
52
|
+
TaskType.SOLUTION_EXTRACTION:
|
|
53
|
+
SolutionExtractionPromptTemplateDict(),
|
|
54
|
+
TaskType.ROLE_DESCRIPTION:
|
|
55
|
+
RoleDescriptionPromptTemplateDict(),
|
|
56
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from camel.prompts import TextPrompt, TextPromptDict
|
|
17
|
+
from camel.types import RoleType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# flake8: noqa :E501
|
|
21
|
+
class TranslationPromptTemplateDict(TextPromptDict):
|
|
22
|
+
r"""A dictionary containing :obj:`TextPrompt` used in the `Translation`
|
|
23
|
+
task.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
ASSISTANT_PROMPT (TextPrompt): A system prompt for the AI assistant
|
|
27
|
+
that outlines the rules of the conversation and provides
|
|
28
|
+
instructions for completing tasks.
|
|
29
|
+
"""
|
|
30
|
+
ASSISTANT_PROMPT = TextPrompt(
|
|
31
|
+
"""You are an expert English to {language} translator.
|
|
32
|
+
Your sole purpose is to accurately translate any text presented to you from English to {language}.
|
|
33
|
+
Please provide the {language} translation for the given text.
|
|
34
|
+
If you are presented with an empty string, simply return an empty string as the translation.
|
|
35
|
+
Only text in between ```TEXT``` should not be translated.
|
|
36
|
+
Do not provide any explanation. Just provide a translation.""")
|
|
37
|
+
|
|
38
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
39
|
+
super().__init__(*args, **kwargs)
|
|
40
|
+
self.update({
|
|
41
|
+
RoleType.ASSISTANT: self.ASSISTANT_PROMPT,
|
|
42
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from .agent_responses import ChatAgentResponse
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'ChatAgentResponse',
|
|
18
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from typing import Any, Dict, List
|
|
16
|
+
|
|
17
|
+
from camel.messages import BaseMessage
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class ChatAgentResponse:
|
|
22
|
+
r"""Response of a ChatAgent.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
msgs (List[BaseMessage]): A list of zero, one or several messages.
|
|
26
|
+
If the list is empty, there is some error in message generation.
|
|
27
|
+
If the list has one message, this is normal mode.
|
|
28
|
+
If the list has several messages, this is the critic mode.
|
|
29
|
+
terminated (bool): A boolean indicating whether the agent decided
|
|
30
|
+
to terminate the chat session.
|
|
31
|
+
info (Dict[str, Any]): Extra information about the chat message.
|
|
32
|
+
"""
|
|
33
|
+
msgs: List[BaseMessage]
|
|
34
|
+
terminated: bool
|
|
35
|
+
info: Dict[str, Any]
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def msg(self):
|
|
39
|
+
if len(self.msgs) != 1:
|
|
40
|
+
raise RuntimeError("Property msg is only available "
|
|
41
|
+
"for a single message in msgs.")
|
|
42
|
+
return self.msgs[0]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from .role_playing import RolePlaying
|
|
15
|
+
from .babyagi_playing import BabyAGI
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
'RolePlaying',
|
|
19
|
+
'BabyAGI',
|
|
20
|
+
]
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the “License”);
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an “AS IS” BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
|
|
14
|
+
from collections import deque
|
|
15
|
+
from typing import Dict, List, Optional
|
|
16
|
+
|
|
17
|
+
from camel.agents import (
|
|
18
|
+
ChatAgent,
|
|
19
|
+
TaskCreationAgent,
|
|
20
|
+
TaskPrioritizationAgent,
|
|
21
|
+
TaskSpecifyAgent,
|
|
22
|
+
)
|
|
23
|
+
from camel.agents.chat_agent import ChatAgentResponse
|
|
24
|
+
from camel.generators import SystemMessageGenerator
|
|
25
|
+
from camel.messages import BaseMessage
|
|
26
|
+
from camel.prompts import TextPrompt
|
|
27
|
+
from camel.types import RoleType, TaskType
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class BabyAGI:
|
|
31
|
+
r"""The BabyAGI Agent adapted from `"Task-driven Autonomous Agent"
|
|
32
|
+
<https://github.com/yoheinakajima/babyagi>`_.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
assistant_role_name (str): The name of the role played by the
|
|
36
|
+
assistant.
|
|
37
|
+
user_role_name (str): The name of the role played by the user.
|
|
38
|
+
task_prompt (str, optional): A prompt for the task to be performed.
|
|
39
|
+
(default: :obj:`""`)
|
|
40
|
+
task_type (TaskType, optional): The type of task to perform.
|
|
41
|
+
(default: :obj:`TaskType.AI_SOCIETY`)
|
|
42
|
+
max_task_history (int): The maximum number of previous tasks
|
|
43
|
+
information to include in the task agent.
|
|
44
|
+
(default: :obj:10)
|
|
45
|
+
assistant_agent_kwargs (Dict, optional): Additional arguments to pass
|
|
46
|
+
to the assistant agent. (default: :obj:`None`)
|
|
47
|
+
task_specify_agent_kwargs (Dict, optional): Additional arguments to
|
|
48
|
+
pass to the task specify agent. (default: :obj:`None`)
|
|
49
|
+
task_creation_agent_kwargs (Dict, optional): Additional arguments to
|
|
50
|
+
pass to the task creation agent. (default: :obj:`None`)
|
|
51
|
+
task_prioritization_agent_kwargs (Dict, optional): Additional arguments
|
|
52
|
+
to pass to the task prioritization agent. (default: :obj:`None`)
|
|
53
|
+
sys_msg_generator_kwargs (Dict, optional): Additional arguments to
|
|
54
|
+
pass to the system message generator. (default: :obj:`None`)
|
|
55
|
+
extend_task_specify_meta_dict (Dict, optional): A dict to extend the
|
|
56
|
+
task specify meta dict with. (default: :obj:`None`)
|
|
57
|
+
output_language (str, optional): The language to be output by the
|
|
58
|
+
agents. (default: :obj:`None`)
|
|
59
|
+
message_window_size (int, optional): The maximum number of previous
|
|
60
|
+
messages to include in the context window. If `None`, no windowing
|
|
61
|
+
is performed. (default: :obj:`None`)
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
assistant_role_name: str,
|
|
67
|
+
user_role_name: str,
|
|
68
|
+
task_prompt: str = "",
|
|
69
|
+
task_type: TaskType = TaskType.AI_SOCIETY,
|
|
70
|
+
max_task_history: int = 10,
|
|
71
|
+
assistant_agent_kwargs: Optional[Dict] = None,
|
|
72
|
+
task_specify_agent_kwargs: Optional[Dict] = None,
|
|
73
|
+
task_creation_agent_kwargs: Optional[Dict] = None,
|
|
74
|
+
task_prioritization_agent_kwargs: Optional[Dict] = None,
|
|
75
|
+
sys_msg_generator_kwargs: Optional[Dict] = None,
|
|
76
|
+
extend_task_specify_meta_dict: Optional[Dict] = None,
|
|
77
|
+
output_language: Optional[str] = None,
|
|
78
|
+
message_window_size: Optional[int] = None,
|
|
79
|
+
) -> None:
|
|
80
|
+
self.task_type = task_type
|
|
81
|
+
self.task_prompt = task_prompt
|
|
82
|
+
self.specified_task_prompt: TextPrompt
|
|
83
|
+
self.init_specified_task_prompt(assistant_role_name, user_role_name,
|
|
84
|
+
task_specify_agent_kwargs,
|
|
85
|
+
extend_task_specify_meta_dict,
|
|
86
|
+
output_language)
|
|
87
|
+
|
|
88
|
+
sys_msg_generator = SystemMessageGenerator(
|
|
89
|
+
task_type=self.task_type, **(sys_msg_generator_kwargs or {}))
|
|
90
|
+
|
|
91
|
+
init_assistant_sys_msg = sys_msg_generator.from_dicts(
|
|
92
|
+
meta_dicts=[
|
|
93
|
+
dict(
|
|
94
|
+
assistant_role=assistant_role_name,
|
|
95
|
+
user_role=user_role_name,
|
|
96
|
+
task=self.specified_task_prompt,
|
|
97
|
+
)
|
|
98
|
+
],
|
|
99
|
+
role_tuples=[
|
|
100
|
+
(assistant_role_name, RoleType.ASSISTANT),
|
|
101
|
+
],
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
self.assistant_agent: ChatAgent
|
|
105
|
+
self.assistant_sys_msg: BaseMessage
|
|
106
|
+
self.task_creation_agent: TaskCreationAgent
|
|
107
|
+
self.task_prioritization_agent: TaskPrioritizationAgent
|
|
108
|
+
self.init_agents(init_assistant_sys_msg[0], assistant_agent_kwargs,
|
|
109
|
+
task_creation_agent_kwargs,
|
|
110
|
+
task_prioritization_agent_kwargs, output_language,
|
|
111
|
+
message_window_size)
|
|
112
|
+
|
|
113
|
+
self.subtasks: deque = deque([])
|
|
114
|
+
self.solved_subtasks: List[str] = []
|
|
115
|
+
self.MAX_TASK_HISTORY = max_task_history
|
|
116
|
+
|
|
117
|
+
def init_specified_task_prompt(
|
|
118
|
+
self, assistant_role_name: str, user_role_name: str,
|
|
119
|
+
task_specify_agent_kwargs: Optional[Dict],
|
|
120
|
+
extend_task_specify_meta_dict: Optional[Dict],
|
|
121
|
+
output_language: Optional[str]):
|
|
122
|
+
r"""Use a task specify agent to generate a specified task prompt.
|
|
123
|
+
Generated specified task prompt will be used to replace original
|
|
124
|
+
task prompt. If there is no task specify agent, specified task
|
|
125
|
+
prompt will not be generated.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
assistant_role_name (str): The name of the role played by the
|
|
129
|
+
assistant.
|
|
130
|
+
user_role_name (str): The name of the role played by the user.
|
|
131
|
+
task_specify_agent_kwargs (Dict, optional): Additional arguments
|
|
132
|
+
to pass to the task specify agent.
|
|
133
|
+
extend_task_specify_meta_dict (Dict, optional): A dict to extend
|
|
134
|
+
the task specify meta dict with.
|
|
135
|
+
output_language (str, optional): The language to be output by the
|
|
136
|
+
agents.
|
|
137
|
+
"""
|
|
138
|
+
task_specify_meta_dict = dict()
|
|
139
|
+
if self.task_type in [TaskType.AI_SOCIETY, TaskType.MISALIGNMENT]:
|
|
140
|
+
task_specify_meta_dict.update(
|
|
141
|
+
dict(assistant_role=assistant_role_name,
|
|
142
|
+
user_role=user_role_name))
|
|
143
|
+
task_specify_meta_dict.update(extend_task_specify_meta_dict or {})
|
|
144
|
+
task_specify_agent = TaskSpecifyAgent(
|
|
145
|
+
task_type=self.task_type,
|
|
146
|
+
output_language=output_language,
|
|
147
|
+
**(task_specify_agent_kwargs or {}),
|
|
148
|
+
)
|
|
149
|
+
self.specified_task_prompt = task_specify_agent.run(
|
|
150
|
+
self.task_prompt,
|
|
151
|
+
meta_dict=task_specify_meta_dict,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def init_agents(self, init_assistant_sys_msg: BaseMessage,
|
|
155
|
+
assistant_agent_kwargs: Optional[Dict],
|
|
156
|
+
task_creation_agent_kwargs: Optional[Dict],
|
|
157
|
+
task_prioritization_agent_kwargs: Optional[Dict],
|
|
158
|
+
output_language: Optional[str],
|
|
159
|
+
message_window_size: Optional[int] = None):
|
|
160
|
+
r"""Initialize assistant and user agents with their system messages.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
init_assistant_sys_msg (BaseMessage): Assistant agent's initial
|
|
164
|
+
system message.
|
|
165
|
+
assistant_agent_kwargs (Dict, optional): Additional arguments to
|
|
166
|
+
pass to the assistant agent.
|
|
167
|
+
task_creation_agent_kwargs (Dict, optional): Additional arguments
|
|
168
|
+
to pass to the task creation agent.
|
|
169
|
+
task_prioritization_agent_kwargs (Dict, optional): Additional
|
|
170
|
+
arguments to pass to the task prioritization agent.
|
|
171
|
+
output_language (str, optional): The language to be output by the
|
|
172
|
+
agents.
|
|
173
|
+
message_window_size (int, optional): The maximum number of previous
|
|
174
|
+
messages to include in the context window. If `None`, no
|
|
175
|
+
windowing is performed. (default: :obj:`None`)
|
|
176
|
+
"""
|
|
177
|
+
self.assistant_agent = ChatAgent(
|
|
178
|
+
init_assistant_sys_msg,
|
|
179
|
+
output_language=output_language,
|
|
180
|
+
message_window_size=message_window_size,
|
|
181
|
+
**(assistant_agent_kwargs or {}),
|
|
182
|
+
)
|
|
183
|
+
self.assistant_sys_msg = self.assistant_agent.system_message
|
|
184
|
+
self.assistant_agent.reset()
|
|
185
|
+
|
|
186
|
+
self.task_creation_agent = TaskCreationAgent(
|
|
187
|
+
objective=self.specified_task_prompt,
|
|
188
|
+
role_name=self.assistant_sys_msg.role_name,
|
|
189
|
+
output_language=output_language,
|
|
190
|
+
message_window_size=message_window_size,
|
|
191
|
+
**(task_creation_agent_kwargs or {}),
|
|
192
|
+
)
|
|
193
|
+
self.task_creation_agent.reset()
|
|
194
|
+
|
|
195
|
+
self.task_prioritization_agent = TaskPrioritizationAgent(
|
|
196
|
+
objective=self.specified_task_prompt,
|
|
197
|
+
output_language=output_language,
|
|
198
|
+
message_window_size=message_window_size,
|
|
199
|
+
**(task_prioritization_agent_kwargs or {}),
|
|
200
|
+
)
|
|
201
|
+
self.task_prioritization_agent.reset()
|
|
202
|
+
|
|
203
|
+
def step(self) -> ChatAgentResponse:
|
|
204
|
+
r"""BabyAGI agent would pull the first task from the task list,
|
|
205
|
+
complete the task based on the context, then creates new tasks and
|
|
206
|
+
re-prioritizes the task list based on the objective and the result of
|
|
207
|
+
the previous task. It returns assistant message.
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
ChatAgentResponse: it contains the resulting assistant message,
|
|
211
|
+
whether the assistant agent terminated the conversation,
|
|
212
|
+
and any additional assistant information.
|
|
213
|
+
|
|
214
|
+
"""
|
|
215
|
+
if not self.subtasks:
|
|
216
|
+
new_subtask_list = self.task_creation_agent.run(task_list=[])
|
|
217
|
+
prioritized_subtask_list = self.task_prioritization_agent.run(
|
|
218
|
+
new_subtask_list)
|
|
219
|
+
self.subtasks = deque(prioritized_subtask_list)
|
|
220
|
+
|
|
221
|
+
task_name = self.subtasks.popleft()
|
|
222
|
+
assistant_msg_msg = BaseMessage.make_user_message(
|
|
223
|
+
role_name=self.assistant_sys_msg.role_name, content=f"{task_name}")
|
|
224
|
+
|
|
225
|
+
assistant_response = self.assistant_agent.step(assistant_msg_msg)
|
|
226
|
+
assistant_msg = assistant_response.msgs[0]
|
|
227
|
+
self.assistant_agent.record_message(assistant_msg)
|
|
228
|
+
self.task_creation_agent.record_message(assistant_msg)
|
|
229
|
+
self.task_prioritization_agent.record_message(assistant_msg)
|
|
230
|
+
|
|
231
|
+
self.solved_subtasks.append(task_name)
|
|
232
|
+
past_tasks = self.solved_subtasks + list(self.subtasks)
|
|
233
|
+
|
|
234
|
+
new_subtask_list = self.task_creation_agent.run(
|
|
235
|
+
task_list=past_tasks[-self.MAX_TASK_HISTORY:])
|
|
236
|
+
|
|
237
|
+
if new_subtask_list:
|
|
238
|
+
self.subtasks.extend(new_subtask_list)
|
|
239
|
+
prioritized_subtask_list = self.task_prioritization_agent.run(
|
|
240
|
+
task_list=list(self.subtasks)[-self.MAX_TASK_HISTORY:])
|
|
241
|
+
self.subtasks = deque(prioritized_subtask_list)
|
|
242
|
+
else:
|
|
243
|
+
print("no new tasks")
|
|
244
|
+
assistant_response.info['task_name'] = task_name
|
|
245
|
+
assistant_response.info['subtasks'] = list(self.subtasks)
|
|
246
|
+
if not self.subtasks:
|
|
247
|
+
terminated = True
|
|
248
|
+
assistant_response.info[
|
|
249
|
+
'termination_reasons'] = "All tasks are solved"
|
|
250
|
+
return ChatAgentResponse([assistant_msg], terminated,
|
|
251
|
+
assistant_response.info)
|
|
252
|
+
return ChatAgentResponse([assistant_msg],
|
|
253
|
+
assistant_response.terminated,
|
|
254
|
+
assistant_response.info)
|