camel-ai 0.2.73a4__py3-none-any.whl → 0.2.80a2__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.
Files changed (173) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/_utils.py +38 -0
  3. camel/agents/chat_agent.py +2217 -519
  4. camel/agents/mcp_agent.py +30 -27
  5. camel/configs/__init__.py +15 -0
  6. camel/configs/aihubmix_config.py +88 -0
  7. camel/configs/amd_config.py +70 -0
  8. camel/configs/cometapi_config.py +104 -0
  9. camel/configs/minimax_config.py +93 -0
  10. camel/configs/nebius_config.py +103 -0
  11. camel/data_collectors/alpaca_collector.py +15 -6
  12. camel/datasets/base_generator.py +39 -10
  13. camel/environments/single_step.py +28 -3
  14. camel/environments/tic_tac_toe.py +1 -1
  15. camel/interpreters/__init__.py +2 -0
  16. camel/interpreters/docker/Dockerfile +3 -12
  17. camel/interpreters/e2b_interpreter.py +34 -1
  18. camel/interpreters/microsandbox_interpreter.py +395 -0
  19. camel/loaders/__init__.py +11 -2
  20. camel/loaders/chunkr_reader.py +9 -0
  21. camel/memories/agent_memories.py +48 -4
  22. camel/memories/base.py +26 -0
  23. camel/memories/blocks/chat_history_block.py +122 -4
  24. camel/memories/context_creators/score_based.py +25 -384
  25. camel/memories/records.py +88 -8
  26. camel/messages/base.py +153 -34
  27. camel/models/__init__.py +10 -0
  28. camel/models/aihubmix_model.py +83 -0
  29. camel/models/aiml_model.py +1 -16
  30. camel/models/amd_model.py +101 -0
  31. camel/models/anthropic_model.py +6 -19
  32. camel/models/aws_bedrock_model.py +2 -33
  33. camel/models/azure_openai_model.py +114 -89
  34. camel/models/base_audio_model.py +3 -1
  35. camel/models/base_model.py +32 -14
  36. camel/models/cohere_model.py +1 -16
  37. camel/models/cometapi_model.py +83 -0
  38. camel/models/crynux_model.py +1 -16
  39. camel/models/deepseek_model.py +1 -16
  40. camel/models/fish_audio_model.py +6 -0
  41. camel/models/gemini_model.py +36 -18
  42. camel/models/groq_model.py +1 -17
  43. camel/models/internlm_model.py +1 -16
  44. camel/models/litellm_model.py +1 -16
  45. camel/models/lmstudio_model.py +1 -17
  46. camel/models/minimax_model.py +83 -0
  47. camel/models/mistral_model.py +1 -16
  48. camel/models/model_factory.py +27 -1
  49. camel/models/modelscope_model.py +1 -16
  50. camel/models/moonshot_model.py +105 -24
  51. camel/models/nebius_model.py +83 -0
  52. camel/models/nemotron_model.py +0 -5
  53. camel/models/netmind_model.py +1 -16
  54. camel/models/novita_model.py +1 -16
  55. camel/models/nvidia_model.py +1 -16
  56. camel/models/ollama_model.py +4 -19
  57. camel/models/openai_compatible_model.py +62 -41
  58. camel/models/openai_model.py +62 -57
  59. camel/models/openrouter_model.py +1 -17
  60. camel/models/ppio_model.py +1 -16
  61. camel/models/qianfan_model.py +1 -16
  62. camel/models/qwen_model.py +1 -16
  63. camel/models/reka_model.py +1 -16
  64. camel/models/samba_model.py +34 -47
  65. camel/models/sglang_model.py +64 -31
  66. camel/models/siliconflow_model.py +1 -16
  67. camel/models/stub_model.py +0 -4
  68. camel/models/togetherai_model.py +1 -16
  69. camel/models/vllm_model.py +1 -16
  70. camel/models/volcano_model.py +0 -17
  71. camel/models/watsonx_model.py +1 -16
  72. camel/models/yi_model.py +1 -16
  73. camel/models/zhipuai_model.py +60 -16
  74. camel/parsers/__init__.py +18 -0
  75. camel/parsers/mcp_tool_call_parser.py +176 -0
  76. camel/retrievers/auto_retriever.py +1 -0
  77. camel/runtimes/daytona_runtime.py +11 -12
  78. camel/societies/__init__.py +2 -0
  79. camel/societies/workforce/__init__.py +2 -0
  80. camel/societies/workforce/events.py +122 -0
  81. camel/societies/workforce/prompts.py +146 -66
  82. camel/societies/workforce/role_playing_worker.py +15 -11
  83. camel/societies/workforce/single_agent_worker.py +302 -65
  84. camel/societies/workforce/structured_output_handler.py +30 -18
  85. camel/societies/workforce/task_channel.py +163 -27
  86. camel/societies/workforce/utils.py +107 -13
  87. camel/societies/workforce/workflow_memory_manager.py +772 -0
  88. camel/societies/workforce/workforce.py +1949 -579
  89. camel/societies/workforce/workforce_callback.py +74 -0
  90. camel/societies/workforce/workforce_logger.py +168 -145
  91. camel/societies/workforce/workforce_metrics.py +33 -0
  92. camel/storages/key_value_storages/json.py +15 -2
  93. camel/storages/key_value_storages/mem0_cloud.py +48 -47
  94. camel/storages/object_storages/google_cloud.py +1 -1
  95. camel/storages/vectordb_storages/oceanbase.py +13 -13
  96. camel/storages/vectordb_storages/qdrant.py +3 -3
  97. camel/storages/vectordb_storages/tidb.py +8 -6
  98. camel/tasks/task.py +4 -3
  99. camel/toolkits/__init__.py +20 -7
  100. camel/toolkits/aci_toolkit.py +45 -0
  101. camel/toolkits/base.py +6 -4
  102. camel/toolkits/code_execution.py +28 -1
  103. camel/toolkits/context_summarizer_toolkit.py +684 -0
  104. camel/toolkits/dappier_toolkit.py +5 -1
  105. camel/toolkits/dingtalk.py +1135 -0
  106. camel/toolkits/edgeone_pages_mcp_toolkit.py +11 -31
  107. camel/toolkits/excel_toolkit.py +1 -1
  108. camel/toolkits/{file_write_toolkit.py → file_toolkit.py} +430 -36
  109. camel/toolkits/function_tool.py +13 -3
  110. camel/toolkits/github_toolkit.py +104 -17
  111. camel/toolkits/gmail_toolkit.py +1839 -0
  112. camel/toolkits/google_calendar_toolkit.py +38 -4
  113. camel/toolkits/google_drive_mcp_toolkit.py +12 -31
  114. camel/toolkits/hybrid_browser_toolkit/config_loader.py +15 -0
  115. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +77 -8
  116. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +884 -88
  117. camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
  118. camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +5 -612
  119. camel/toolkits/hybrid_browser_toolkit/ts/package.json +0 -1
  120. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +959 -89
  121. camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +9 -2
  122. camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +281 -213
  123. camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
  124. camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
  125. camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
  126. camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +23 -3
  127. camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +72 -7
  128. camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +582 -132
  129. camel/toolkits/hybrid_browser_toolkit_py/actions.py +158 -0
  130. camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +55 -8
  131. camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +43 -0
  132. camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +321 -8
  133. camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +10 -4
  134. camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +45 -4
  135. camel/toolkits/{openai_image_toolkit.py → image_generation_toolkit.py} +151 -53
  136. camel/toolkits/klavis_toolkit.py +5 -1
  137. camel/toolkits/markitdown_toolkit.py +27 -1
  138. camel/toolkits/math_toolkit.py +64 -10
  139. camel/toolkits/mcp_toolkit.py +366 -71
  140. camel/toolkits/memory_toolkit.py +5 -1
  141. camel/toolkits/message_integration.py +18 -13
  142. camel/toolkits/minimax_mcp_toolkit.py +195 -0
  143. camel/toolkits/note_taking_toolkit.py +19 -10
  144. camel/toolkits/notion_mcp_toolkit.py +16 -26
  145. camel/toolkits/openbb_toolkit.py +5 -1
  146. camel/toolkits/origene_mcp_toolkit.py +8 -49
  147. camel/toolkits/playwright_mcp_toolkit.py +12 -31
  148. camel/toolkits/resend_toolkit.py +168 -0
  149. camel/toolkits/search_toolkit.py +264 -91
  150. camel/toolkits/slack_toolkit.py +64 -10
  151. camel/toolkits/terminal_toolkit/__init__.py +18 -0
  152. camel/toolkits/terminal_toolkit/terminal_toolkit.py +957 -0
  153. camel/toolkits/terminal_toolkit/utils.py +532 -0
  154. camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
  155. camel/toolkits/video_analysis_toolkit.py +17 -11
  156. camel/toolkits/wechat_official_toolkit.py +483 -0
  157. camel/toolkits/zapier_toolkit.py +5 -1
  158. camel/types/__init__.py +2 -2
  159. camel/types/enums.py +274 -7
  160. camel/types/openai_types.py +2 -2
  161. camel/types/unified_model_type.py +15 -0
  162. camel/utils/commons.py +36 -5
  163. camel/utils/constants.py +3 -0
  164. camel/utils/context_utils.py +1003 -0
  165. camel/utils/mcp.py +138 -4
  166. camel/utils/token_counting.py +43 -20
  167. {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/METADATA +223 -83
  168. {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/RECORD +170 -141
  169. camel/loaders/pandas_reader.py +0 -368
  170. camel/toolkits/openai_agent_toolkit.py +0 -135
  171. camel/toolkits/terminal_toolkit.py +0 -1550
  172. {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/WHEEL +0 -0
  173. {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/licenses/LICENSE +0 -0
@@ -34,6 +34,12 @@ class ChunkrReaderConfig:
34
34
  high_resolution (bool, optional): Whether to use high resolution OCR.
35
35
  (default: :obj:`True`)
36
36
  ocr_strategy (str, optional): The OCR strategy. Defaults to 'Auto'.
37
+ **kwargs: Additional keyword arguments to pass to the Chunkr
38
+ Configuration. This accepts all other Configuration parameters
39
+ such as expires_in, pipeline, segment_processing,
40
+ segmentation_strategy, etc.
41
+ See: https://github.com/lumina-ai-inc/chunkr/blob/main/core/src/
42
+ models/task.rs#L749
37
43
  """
38
44
 
39
45
  def __init__(
@@ -41,10 +47,12 @@ class ChunkrReaderConfig:
41
47
  chunk_processing: int = 512,
42
48
  high_resolution: bool = True,
43
49
  ocr_strategy: str = "Auto",
50
+ **kwargs,
44
51
  ):
45
52
  self.chunk_processing = chunk_processing
46
53
  self.high_resolution = high_resolution
47
54
  self.ocr_strategy = ocr_strategy
55
+ self.kwargs = kwargs
48
56
 
49
57
 
50
58
  class ChunkrReader:
@@ -190,4 +198,5 @@ class ChunkrReader:
190
198
  "Auto": OcrStrategy.AUTO,
191
199
  "All": OcrStrategy.ALL,
192
200
  }.get(chunkr_config.ocr_strategy, OcrStrategy.ALL),
201
+ **chunkr_config.kwargs,
193
202
  )
@@ -51,7 +51,9 @@ class ChatHistoryMemory(AgentMemory):
51
51
  raise ValueError("`window_size` must be non-negative.")
52
52
  self._context_creator = context_creator
53
53
  self._window_size = window_size
54
- self._chat_history_block = ChatHistoryBlock(storage=storage)
54
+ self._chat_history_block = ChatHistoryBlock(
55
+ storage=storage,
56
+ )
55
57
  self._agent_id = agent_id
56
58
 
57
59
  @property
@@ -116,17 +118,35 @@ class ChatHistoryMemory(AgentMemory):
116
118
  indices_to_remove.append(i)
117
119
  # Mark ASSISTANT messages with tool_calls for removal
118
120
  elif role == OpenAIBackendRole.ASSISTANT.value:
119
- meta_dict = record.get('meta_dict', {})
120
- if meta_dict and 'tool_calls' in meta_dict:
121
+ message_dict = record.get('message', {})
122
+ # Check for tool_calls in message
123
+ has_tool_calls = 'tool_calls' in message_dict
124
+ is_func_calling = (
125
+ message_dict.get('__class__') == 'FunctionCallingMessage'
126
+ and 'args' in message_dict
127
+ )
128
+
129
+ if has_tool_calls or is_func_calling:
121
130
  indices_to_remove.append(i)
122
131
 
123
132
  # Remove records in-place
124
133
  for i in reversed(indices_to_remove):
125
134
  del record_dicts[i]
126
135
 
127
- # Save the modified records back to storage
136
+ # Clear storage and save the modified records back
137
+ self._chat_history_block.storage.clear()
128
138
  self._chat_history_block.storage.save(record_dicts)
129
139
 
140
+ def pop_records(self, count: int) -> List[MemoryRecord]:
141
+ r"""Removes the most recent records from chat history memory."""
142
+ return self._chat_history_block.pop_records(count)
143
+
144
+ def remove_records_by_indices(
145
+ self, indices: List[int]
146
+ ) -> List[MemoryRecord]:
147
+ r"""Removes records at specified indices from chat history memory."""
148
+ return self._chat_history_block.remove_records_by_indices(indices)
149
+
130
150
 
131
151
  class VectorDBMemory(AgentMemory):
132
152
  r"""An agent memory wrapper of :obj:`VectorDBBlock`. This memory queries
@@ -191,6 +211,20 @@ class VectorDBMemory(AgentMemory):
191
211
  r"""Removes all records from the vector database memory."""
192
212
  self._vectordb_block.clear()
193
213
 
214
+ def pop_records(self, count: int) -> List[MemoryRecord]:
215
+ r"""Rolling back is unsupported for vector database memory."""
216
+ raise NotImplementedError(
217
+ "VectorDBMemory does not support removing historical records."
218
+ )
219
+
220
+ def remove_records_by_indices(
221
+ self, indices: List[int]
222
+ ) -> List[MemoryRecord]:
223
+ r"""Removing by indices is unsupported for vector database memory."""
224
+ raise NotImplementedError(
225
+ "VectorDBMemory does not support removing records by indices."
226
+ )
227
+
194
228
 
195
229
  class LongtermAgentMemory(AgentMemory):
196
230
  r"""An implementation of the :obj:`AgentMemory` abstract base class for
@@ -275,3 +309,13 @@ class LongtermAgentMemory(AgentMemory):
275
309
  r"""Removes all records from the memory."""
276
310
  self.chat_history_block.clear()
277
311
  self.vector_db_block.clear()
312
+
313
+ def pop_records(self, count: int) -> List[MemoryRecord]:
314
+ r"""Removes recent chat history records while leaving vector memory."""
315
+ return self.chat_history_block.pop_records(count)
316
+
317
+ def remove_records_by_indices(
318
+ self, indices: List[int]
319
+ ) -> List[MemoryRecord]:
320
+ r"""Removes records at specified indices from chat history."""
321
+ return self.chat_history_block.remove_records_by_indices(indices)
camel/memories/base.py CHANGED
@@ -45,6 +45,32 @@ class MemoryBlock(ABC):
45
45
  """
46
46
  self.write_records([record])
47
47
 
48
+ def pop_records(self, count: int) -> List[MemoryRecord]:
49
+ r"""Removes records from the memory and returns the removed records.
50
+
51
+ Args:
52
+ count (int): Number of records to remove.
53
+
54
+ Returns:
55
+ List[MemoryRecord]: The records that were removed from the memory
56
+ in their original order.
57
+ """
58
+ raise NotImplementedError
59
+
60
+ def remove_records_by_indices(
61
+ self, indices: List[int]
62
+ ) -> List[MemoryRecord]:
63
+ r"""Removes records at specified indices from the memory.
64
+
65
+ Args:
66
+ indices (List[int]): List of indices to remove. Indices should be
67
+ valid positions in the current record list.
68
+
69
+ Returns:
70
+ List[MemoryRecord]: The removed records in their original order.
71
+ """
72
+ raise NotImplementedError
73
+
48
74
  @abstractmethod
49
75
  def clear(self) -> None:
50
76
  r"""Clears all messages from the memory."""
@@ -11,7 +11,6 @@
11
11
  # See the License for the specific language governing permissions and
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
- import warnings
15
14
  from typing import List, Optional
16
15
 
17
16
  from camel.memories.base import MemoryBlock
@@ -39,7 +38,7 @@ class ChatHistoryBlock(MemoryBlock):
39
38
  last message is 1.0, and with each step taken backward, the score
40
39
  of the message is multiplied by the `keep_rate`. Higher `keep_rate`
41
40
  leads to high possibility to keep history messages during context
42
- creation.
41
+ creation. (default: :obj:`0.9`)
43
42
  """
44
43
 
45
44
  def __init__(
@@ -70,7 +69,8 @@ class ChatHistoryBlock(MemoryBlock):
70
69
  """
71
70
  record_dicts = self.storage.load()
72
71
  if len(record_dicts) == 0:
73
- warnings.warn("The `ChatHistoryMemory` is empty.")
72
+ # Empty memory is a valid state (e.g., during initialization).
73
+ # Users can check if memory is empty by checking the returned list.
74
74
  return list()
75
75
 
76
76
  if window_size is not None and window_size >= 0:
@@ -81,7 +81,10 @@ class ChatHistoryBlock(MemoryBlock):
81
81
  if (
82
82
  record_dicts
83
83
  and record_dicts[0]['role_at_backend']
84
- in {OpenAIBackendRole.SYSTEM, OpenAIBackendRole.DEVELOPER}
84
+ in {
85
+ OpenAIBackendRole.SYSTEM.value,
86
+ OpenAIBackendRole.DEVELOPER.value,
87
+ }
85
88
  )
86
89
  else 0
87
90
  )
@@ -164,3 +167,118 @@ class ChatHistoryBlock(MemoryBlock):
164
167
  def clear(self) -> None:
165
168
  r"""Clears all chat messages from the memory."""
166
169
  self.storage.clear()
170
+
171
+ def pop_records(self, count: int) -> List[MemoryRecord]:
172
+ r"""Removes the most recent records from the memory.
173
+
174
+ Args:
175
+ count (int): Number of records to remove from the end of the
176
+ conversation history. A value of 0 results in no changes.
177
+
178
+ Returns:
179
+ List[MemoryRecord]: The removed records in chronological order.
180
+ """
181
+ if not isinstance(count, int):
182
+ raise TypeError("`count` must be an integer.")
183
+ if count < 0:
184
+ raise ValueError("`count` must be non-negative.")
185
+ if count == 0:
186
+ return []
187
+
188
+ record_dicts = self.storage.load()
189
+ if not record_dicts:
190
+ return []
191
+
192
+ # Preserve initial system/developer instruction if present.
193
+ protected_prefix = (
194
+ 1
195
+ if (
196
+ record_dicts
197
+ and record_dicts[0]['role_at_backend']
198
+ in {
199
+ OpenAIBackendRole.SYSTEM.value,
200
+ OpenAIBackendRole.DEVELOPER.value,
201
+ }
202
+ )
203
+ else 0
204
+ )
205
+
206
+ removable_count = max(len(record_dicts) - protected_prefix, 0)
207
+ if removable_count == 0:
208
+ return []
209
+
210
+ pop_count = min(count, removable_count)
211
+ split_index = len(record_dicts) - pop_count
212
+
213
+ popped_dicts = record_dicts[split_index:]
214
+ remaining_dicts = record_dicts[:split_index]
215
+
216
+ self.storage.clear()
217
+ if remaining_dicts:
218
+ self.storage.save(remaining_dicts)
219
+
220
+ return [MemoryRecord.from_dict(record) for record in popped_dicts]
221
+
222
+ def remove_records_by_indices(
223
+ self, indices: List[int]
224
+ ) -> List[MemoryRecord]:
225
+ r"""Removes records at specified indices from the memory.
226
+
227
+ Args:
228
+ indices (List[int]): List of indices to remove. Indices are
229
+ positions in the current record list (0-based).
230
+ System/developer messages at index 0 are protected and will
231
+ not be removed.
232
+
233
+ Returns:
234
+ List[MemoryRecord]: The removed records in their original order.
235
+ """
236
+ if not indices:
237
+ return []
238
+
239
+ record_dicts = self.storage.load()
240
+ if not record_dicts:
241
+ return []
242
+
243
+ # Preserve initial system/developer instruction if present.
244
+ protected_prefix = (
245
+ 1
246
+ if (
247
+ record_dicts
248
+ and record_dicts[0]['role_at_backend']
249
+ in {
250
+ OpenAIBackendRole.SYSTEM.value,
251
+ OpenAIBackendRole.DEVELOPER.value,
252
+ }
253
+ )
254
+ else 0
255
+ )
256
+
257
+ # Filter out protected indices and invalid ones
258
+ valid_indices = sorted(
259
+ {
260
+ idx
261
+ for idx in indices
262
+ if idx >= protected_prefix and idx < len(record_dicts)
263
+ }
264
+ )
265
+
266
+ if not valid_indices:
267
+ return []
268
+
269
+ # Extract records to remove (in original order)
270
+ removed_records = [record_dicts[idx] for idx in valid_indices]
271
+
272
+ # Build remaining records by excluding removed indices
273
+ remaining_dicts = [
274
+ record
275
+ for idx, record in enumerate(record_dicts)
276
+ if idx not in valid_indices
277
+ ]
278
+
279
+ # Save back to storage
280
+ self.storage.clear()
281
+ if remaining_dicts:
282
+ self.storage.save(remaining_dicts)
283
+
284
+ return [MemoryRecord.from_dict(record) for record in removed_records]