camel-ai 0.1.1__py3-none-any.whl → 0.1.4__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.

Files changed (117) hide show
  1. camel/__init__.py +1 -11
  2. camel/agents/__init__.py +7 -5
  3. camel/agents/chat_agent.py +134 -86
  4. camel/agents/critic_agent.py +28 -17
  5. camel/agents/deductive_reasoner_agent.py +235 -0
  6. camel/agents/embodied_agent.py +92 -40
  7. camel/agents/knowledge_graph_agent.py +221 -0
  8. camel/agents/role_assignment_agent.py +27 -17
  9. camel/agents/task_agent.py +60 -34
  10. camel/agents/tool_agents/base.py +0 -1
  11. camel/agents/tool_agents/hugging_face_tool_agent.py +7 -4
  12. camel/configs/__init__.py +29 -0
  13. camel/configs/anthropic_config.py +73 -0
  14. camel/configs/base_config.py +22 -0
  15. camel/{configs.py → configs/openai_config.py} +37 -64
  16. camel/embeddings/__init__.py +2 -0
  17. camel/embeddings/base.py +3 -2
  18. camel/embeddings/openai_embedding.py +10 -5
  19. camel/embeddings/sentence_transformers_embeddings.py +65 -0
  20. camel/functions/__init__.py +18 -3
  21. camel/functions/google_maps_function.py +335 -0
  22. camel/functions/math_functions.py +7 -7
  23. camel/functions/open_api_function.py +380 -0
  24. camel/functions/open_api_specs/coursera/__init__.py +13 -0
  25. camel/functions/open_api_specs/coursera/openapi.yaml +82 -0
  26. camel/functions/open_api_specs/klarna/__init__.py +13 -0
  27. camel/functions/open_api_specs/klarna/openapi.yaml +87 -0
  28. camel/functions/open_api_specs/speak/__init__.py +13 -0
  29. camel/functions/open_api_specs/speak/openapi.yaml +151 -0
  30. camel/functions/openai_function.py +346 -42
  31. camel/functions/retrieval_functions.py +61 -0
  32. camel/functions/search_functions.py +100 -35
  33. camel/functions/slack_functions.py +275 -0
  34. camel/functions/twitter_function.py +484 -0
  35. camel/functions/weather_functions.py +36 -23
  36. camel/generators.py +65 -46
  37. camel/human.py +17 -11
  38. camel/interpreters/__init__.py +25 -0
  39. camel/interpreters/base.py +49 -0
  40. camel/{utils/python_interpreter.py → interpreters/internal_python_interpreter.py} +129 -48
  41. camel/interpreters/interpreter_error.py +19 -0
  42. camel/interpreters/subprocess_interpreter.py +190 -0
  43. camel/loaders/__init__.py +22 -0
  44. camel/{functions/base_io_functions.py → loaders/base_io.py} +38 -35
  45. camel/{functions/unstructured_io_fuctions.py → loaders/unstructured_io.py} +199 -110
  46. camel/memories/__init__.py +17 -7
  47. camel/memories/agent_memories.py +156 -0
  48. camel/memories/base.py +97 -32
  49. camel/memories/blocks/__init__.py +21 -0
  50. camel/memories/{chat_history_memory.py → blocks/chat_history_block.py} +34 -34
  51. camel/memories/blocks/vectordb_block.py +101 -0
  52. camel/memories/context_creators/__init__.py +3 -2
  53. camel/memories/context_creators/score_based.py +32 -20
  54. camel/memories/records.py +6 -5
  55. camel/messages/__init__.py +2 -2
  56. camel/messages/base.py +99 -16
  57. camel/messages/func_message.py +7 -4
  58. camel/models/__init__.py +6 -2
  59. camel/models/anthropic_model.py +146 -0
  60. camel/models/base_model.py +10 -3
  61. camel/models/model_factory.py +17 -11
  62. camel/models/open_source_model.py +25 -13
  63. camel/models/openai_audio_models.py +251 -0
  64. camel/models/openai_model.py +20 -13
  65. camel/models/stub_model.py +10 -5
  66. camel/prompts/__init__.py +7 -5
  67. camel/prompts/ai_society.py +21 -14
  68. camel/prompts/base.py +54 -47
  69. camel/prompts/code.py +22 -14
  70. camel/prompts/evaluation.py +8 -5
  71. camel/prompts/misalignment.py +26 -19
  72. camel/prompts/object_recognition.py +35 -0
  73. camel/prompts/prompt_templates.py +14 -8
  74. camel/prompts/role_description_prompt_template.py +16 -10
  75. camel/prompts/solution_extraction.py +9 -5
  76. camel/prompts/task_prompt_template.py +24 -21
  77. camel/prompts/translation.py +9 -5
  78. camel/responses/agent_responses.py +5 -2
  79. camel/retrievers/__init__.py +26 -0
  80. camel/retrievers/auto_retriever.py +330 -0
  81. camel/retrievers/base.py +69 -0
  82. camel/retrievers/bm25_retriever.py +140 -0
  83. camel/retrievers/cohere_rerank_retriever.py +108 -0
  84. camel/retrievers/vector_retriever.py +183 -0
  85. camel/societies/__init__.py +1 -1
  86. camel/societies/babyagi_playing.py +56 -32
  87. camel/societies/role_playing.py +188 -133
  88. camel/storages/__init__.py +18 -0
  89. camel/storages/graph_storages/__init__.py +23 -0
  90. camel/storages/graph_storages/base.py +82 -0
  91. camel/storages/graph_storages/graph_element.py +74 -0
  92. camel/storages/graph_storages/neo4j_graph.py +582 -0
  93. camel/storages/key_value_storages/base.py +1 -2
  94. camel/storages/key_value_storages/in_memory.py +1 -2
  95. camel/storages/key_value_storages/json.py +8 -13
  96. camel/storages/vectordb_storages/__init__.py +33 -0
  97. camel/storages/vectordb_storages/base.py +202 -0
  98. camel/storages/vectordb_storages/milvus.py +396 -0
  99. camel/storages/vectordb_storages/qdrant.py +373 -0
  100. camel/terminators/__init__.py +1 -1
  101. camel/terminators/base.py +2 -3
  102. camel/terminators/response_terminator.py +21 -12
  103. camel/terminators/token_limit_terminator.py +5 -3
  104. camel/toolkits/__init__.py +21 -0
  105. camel/toolkits/base.py +22 -0
  106. camel/toolkits/github_toolkit.py +245 -0
  107. camel/types/__init__.py +18 -6
  108. camel/types/enums.py +129 -15
  109. camel/types/openai_types.py +10 -5
  110. camel/utils/__init__.py +20 -13
  111. camel/utils/commons.py +170 -85
  112. camel/utils/token_counting.py +135 -15
  113. {camel_ai-0.1.1.dist-info → camel_ai-0.1.4.dist-info}/METADATA +123 -75
  114. camel_ai-0.1.4.dist-info/RECORD +119 -0
  115. {camel_ai-0.1.1.dist-info → camel_ai-0.1.4.dist-info}/WHEEL +1 -1
  116. camel/memories/context_creators/base.py +0 -72
  117. camel_ai-0.1.1.dist-info/RECORD +0 -75
@@ -0,0 +1,183 @@
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, List, Optional
15
+
16
+ from camel.embeddings import BaseEmbedding, OpenAIEmbedding
17
+ from camel.loaders import UnstructuredIO
18
+ from camel.retrievers.base import BaseRetriever
19
+ from camel.storages import (
20
+ BaseVectorStorage,
21
+ QdrantStorage,
22
+ VectorDBQuery,
23
+ VectorRecord,
24
+ )
25
+
26
+ DEFAULT_TOP_K_RESULTS = 1
27
+ DEFAULT_SIMILARITY_THRESHOLD = 0.75
28
+
29
+
30
+ class VectorRetriever(BaseRetriever):
31
+ r"""An implementation of the `BaseRetriever` by using vector storage and
32
+ embedding model.
33
+
34
+ This class facilitates the retriever of relevant information using a
35
+ query-based approach, backed by vector embeddings.
36
+
37
+ Attributes:
38
+ embedding_model (BaseEmbedding): Embedding model used to generate
39
+ vector embeddings.
40
+ storage (BaseVectorStorage): Vector storage to query.
41
+ similarity_threshold (float, optional): The similarity threshold
42
+ for filtering results. Defaults to `DEFAULT_SIMILARITY_THRESHOLD`.
43
+ unstructured_modules (UnstructuredIO): A module for parsing files and
44
+ URLs and chunking content based on specified parameters.
45
+ """
46
+
47
+ def __init__(
48
+ self,
49
+ similarity_threshold: float = DEFAULT_SIMILARITY_THRESHOLD,
50
+ embedding_model: Optional[BaseEmbedding] = None,
51
+ storage: Optional[BaseVectorStorage] = None,
52
+ ) -> None:
53
+ r"""Initializes the retriever class with an optional embedding model.
54
+
55
+ Args:
56
+ similarity_threshold (float, optional): The similarity threshold
57
+ for filtering results. Defaults to
58
+ `DEFAULT_SIMILARITY_THRESHOLD`.
59
+ embedding_model (Optional[BaseEmbedding]): The embedding model
60
+ instance. Defaults to `OpenAIEmbedding` if not provided.
61
+ storage (BaseVectorStorage): Vector storage to query.
62
+ """
63
+ self.embedding_model = embedding_model or OpenAIEmbedding()
64
+ self.storage = (
65
+ storage
66
+ if storage is not None
67
+ else QdrantStorage(vector_dim=self.embedding_model.get_output_dim())
68
+ )
69
+ self.similarity_threshold = similarity_threshold
70
+ self.unstructured_modules: UnstructuredIO = UnstructuredIO()
71
+
72
+ def process(
73
+ self,
74
+ content_input_path: str,
75
+ chunk_type: str = "chunk_by_title",
76
+ **kwargs: Any,
77
+ ) -> None:
78
+ r"""Processes content from a file or URL, divides it into chunks by
79
+ using `Unstructured IO`, and stores their embeddings in the specified
80
+ vector storage.
81
+
82
+ Args:
83
+ content_input_path (str): File path or URL of the content to be
84
+ processed.
85
+ chunk_type (str): Type of chunking going to apply. Defaults to
86
+ "chunk_by_title".
87
+ **kwargs (Any): Additional keyword arguments for content parsing.
88
+ """
89
+ elements = self.unstructured_modules.parse_file_or_url(
90
+ content_input_path, **kwargs
91
+ )
92
+ chunks = self.unstructured_modules.chunk_elements(
93
+ chunk_type=chunk_type, elements=elements
94
+ )
95
+ # Iterate to process and store embeddings, set batch of 50
96
+ for i in range(0, len(chunks), 50):
97
+ batch_chunks = chunks[i : i + 50]
98
+ batch_vectors = self.embedding_model.embed_list(
99
+ objs=[str(chunk) for chunk in batch_chunks]
100
+ )
101
+
102
+ records = []
103
+ # Prepare the payload for each vector record, includes the content
104
+ # path, chunk metadata, and chunk text
105
+ for vector, chunk in zip(batch_vectors, batch_chunks):
106
+ content_path_info = {"content path": content_input_path}
107
+ chunk_metadata = {"metadata": chunk.metadata.to_dict()}
108
+ chunk_text = {"text": str(chunk)}
109
+ combined_dict = {
110
+ **content_path_info,
111
+ **chunk_metadata,
112
+ **chunk_text,
113
+ }
114
+
115
+ records.append(
116
+ VectorRecord(vector=vector, payload=combined_dict)
117
+ )
118
+
119
+ self.storage.add(records=records)
120
+
121
+ def query(
122
+ self,
123
+ query: str,
124
+ top_k: int = DEFAULT_TOP_K_RESULTS,
125
+ ) -> List[Dict[str, Any]]:
126
+ r"""Executes a query in vector storage and compiles the retrieved
127
+ results into a dictionary.
128
+
129
+ Args:
130
+ query (str): Query string for information retriever.
131
+ top_k (int, optional): The number of top results to return during
132
+ retriever. Must be a positive integer. Defaults to 1.
133
+
134
+ Returns:
135
+ List[Dict[str, Any]]: Concatenated list of the query results.
136
+
137
+ Raises:
138
+ ValueError: If 'top_k' is less than or equal to 0, if vector
139
+ storage is empty, if payload of vector storage is None.
140
+ """
141
+
142
+ if top_k <= 0:
143
+ raise ValueError("top_k must be a positive integer.")
144
+
145
+ # Load the storage incase it's hosted remote
146
+ self.storage.load()
147
+
148
+ query_vector = self.embedding_model.embed(obj=query)
149
+ db_query = VectorDBQuery(query_vector=query_vector, top_k=top_k)
150
+ query_results = self.storage.query(query=db_query)
151
+
152
+ if query_results[0].record.payload is None:
153
+ raise ValueError(
154
+ "Payload of vector storage is None, please check the collection."
155
+ )
156
+
157
+ # format the results
158
+ formatted_results = []
159
+ for result in query_results:
160
+ if (
161
+ result.similarity >= self.similarity_threshold
162
+ and result.record.payload is not None
163
+ ):
164
+ result_dict = {
165
+ 'similarity score': str(result.similarity),
166
+ 'content path': result.record.payload.get(
167
+ 'content path', ''
168
+ ),
169
+ 'metadata': result.record.payload.get('metadata', {}),
170
+ 'text': result.record.payload.get('text', ''),
171
+ }
172
+ formatted_results.append(result_dict)
173
+
174
+ content_path = query_results[0].record.payload.get('content path', '')
175
+
176
+ if not formatted_results:
177
+ return [
178
+ {
179
+ 'text': f"""No suitable information retrieved from {content_path} \
180
+ with similarity_threshold = {self.similarity_threshold}."""
181
+ }
182
+ ]
183
+ return formatted_results
@@ -11,8 +11,8 @@
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
13
  # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
14
- from .role_playing import RolePlaying
15
14
  from .babyagi_playing import BabyAGI
15
+ from .role_playing import RolePlaying
16
16
 
17
17
  __all__ = [
18
18
  'RolePlaying',
@@ -80,13 +80,17 @@ class BabyAGI:
80
80
  self.task_type = task_type
81
81
  self.task_prompt = task_prompt
82
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)
83
+ self.init_specified_task_prompt(
84
+ assistant_role_name,
85
+ user_role_name,
86
+ task_specify_agent_kwargs,
87
+ extend_task_specify_meta_dict,
88
+ output_language,
89
+ )
87
90
 
88
91
  sys_msg_generator = SystemMessageGenerator(
89
- task_type=self.task_type, **(sys_msg_generator_kwargs or {}))
92
+ task_type=self.task_type, **(sys_msg_generator_kwargs or {})
93
+ )
90
94
 
91
95
  init_assistant_sys_msg = sys_msg_generator.from_dicts(
92
96
  meta_dicts=[
@@ -105,20 +109,27 @@ class BabyAGI:
105
109
  self.assistant_sys_msg: BaseMessage
106
110
  self.task_creation_agent: TaskCreationAgent
107
111
  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
+ self.init_agents(
113
+ init_assistant_sys_msg[0],
114
+ assistant_agent_kwargs,
115
+ task_creation_agent_kwargs,
116
+ task_prioritization_agent_kwargs,
117
+ output_language,
118
+ message_window_size,
119
+ )
112
120
 
113
121
  self.subtasks: deque = deque([])
114
122
  self.solved_subtasks: List[str] = []
115
123
  self.MAX_TASK_HISTORY = max_task_history
116
124
 
117
125
  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]):
126
+ self,
127
+ assistant_role_name: str,
128
+ user_role_name: str,
129
+ task_specify_agent_kwargs: Optional[Dict],
130
+ extend_task_specify_meta_dict: Optional[Dict],
131
+ output_language: Optional[str],
132
+ ):
122
133
  r"""Use a task specify agent to generate a specified task prompt.
123
134
  Generated specified task prompt will be used to replace original
124
135
  task prompt. If there is no task specify agent, specified task
@@ -138,8 +149,10 @@ class BabyAGI:
138
149
  task_specify_meta_dict = dict()
139
150
  if self.task_type in [TaskType.AI_SOCIETY, TaskType.MISALIGNMENT]:
140
151
  task_specify_meta_dict.update(
141
- dict(assistant_role=assistant_role_name,
142
- user_role=user_role_name))
152
+ dict(
153
+ assistant_role=assistant_role_name, user_role=user_role_name
154
+ )
155
+ )
143
156
  task_specify_meta_dict.update(extend_task_specify_meta_dict or {})
144
157
  task_specify_agent = TaskSpecifyAgent(
145
158
  task_type=self.task_type,
@@ -151,12 +164,15 @@ class BabyAGI:
151
164
  meta_dict=task_specify_meta_dict,
152
165
  )
153
166
 
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):
167
+ def init_agents(
168
+ self,
169
+ init_assistant_sys_msg: BaseMessage,
170
+ assistant_agent_kwargs: Optional[Dict],
171
+ task_creation_agent_kwargs: Optional[Dict],
172
+ task_prioritization_agent_kwargs: Optional[Dict],
173
+ output_language: Optional[str],
174
+ message_window_size: Optional[int] = None,
175
+ ):
160
176
  r"""Initialize assistant and user agents with their system messages.
161
177
 
162
178
  Args:
@@ -215,12 +231,14 @@ class BabyAGI:
215
231
  if not self.subtasks:
216
232
  new_subtask_list = self.task_creation_agent.run(task_list=[])
217
233
  prioritized_subtask_list = self.task_prioritization_agent.run(
218
- new_subtask_list)
234
+ new_subtask_list
235
+ )
219
236
  self.subtasks = deque(prioritized_subtask_list)
220
237
 
221
238
  task_name = self.subtasks.popleft()
222
239
  assistant_msg_msg = BaseMessage.make_user_message(
223
- role_name=self.assistant_sys_msg.role_name, content=f"{task_name}")
240
+ role_name=self.assistant_sys_msg.role_name, content=f"{task_name}"
241
+ )
224
242
 
225
243
  assistant_response = self.assistant_agent.step(assistant_msg_msg)
226
244
  assistant_msg = assistant_response.msgs[0]
@@ -232,12 +250,14 @@ class BabyAGI:
232
250
  past_tasks = self.solved_subtasks + list(self.subtasks)
233
251
 
234
252
  new_subtask_list = self.task_creation_agent.run(
235
- task_list=past_tasks[-self.MAX_TASK_HISTORY:])
253
+ task_list=past_tasks[-self.MAX_TASK_HISTORY :]
254
+ )
236
255
 
237
256
  if new_subtask_list:
238
257
  self.subtasks.extend(new_subtask_list)
239
258
  prioritized_subtask_list = self.task_prioritization_agent.run(
240
- task_list=list(self.subtasks)[-self.MAX_TASK_HISTORY:])
259
+ task_list=list(self.subtasks)[-self.MAX_TASK_HISTORY :]
260
+ )
241
261
  self.subtasks = deque(prioritized_subtask_list)
242
262
  else:
243
263
  print("no new tasks")
@@ -245,10 +265,14 @@ class BabyAGI:
245
265
  assistant_response.info['subtasks'] = list(self.subtasks)
246
266
  if not self.subtasks:
247
267
  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)
268
+ assistant_response.info['termination_reasons'] = (
269
+ "All tasks are solved"
270
+ )
271
+ return ChatAgentResponse(
272
+ [assistant_msg], terminated, assistant_response.info
273
+ )
274
+ return ChatAgentResponse(
275
+ [assistant_msg],
276
+ assistant_response.terminated,
277
+ assistant_response.info,
278
+ )