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
@@ -14,9 +14,8 @@
14
14
 
15
15
  import base64
16
16
  import os
17
- import uuid
18
17
  from io import BytesIO
19
- from typing import List, Literal, Optional
18
+ from typing import ClassVar, List, Literal, Optional, Tuple, Union
20
19
 
21
20
  from openai import OpenAI
22
21
  from PIL import Image
@@ -30,21 +29,32 @@ logger = get_logger(__name__)
30
29
 
31
30
 
32
31
  @MCPServer()
33
- class OpenAIImageToolkit(BaseToolkit):
34
- r"""A class toolkit for image generation using OpenAI's
35
- Image Generation API.
36
- """
37
-
38
- @api_keys_required(
39
- [
40
- ("api_key", "OPENAI_API_KEY"),
41
- ]
42
- )
32
+ class ImageGenToolkit(BaseToolkit):
33
+ r"""A class toolkit for image generation using Grok and OpenAI models."""
34
+
35
+ GROK_MODELS: ClassVar[List[str]] = [
36
+ "grok-2-image",
37
+ "grok-2-image-latest",
38
+ "grok-2-image-1212",
39
+ ]
40
+ OPENAI_MODELS: ClassVar[List[str]] = [
41
+ "gpt-image-1",
42
+ "dall-e-3",
43
+ "dall-e-2",
44
+ ]
45
+
43
46
  def __init__(
44
47
  self,
45
48
  model: Optional[
46
- Literal["gpt-image-1", "dall-e-3", "dall-e-2"]
47
- ] = "gpt-image-1",
49
+ Literal[
50
+ "gpt-image-1",
51
+ "dall-e-3",
52
+ "dall-e-2",
53
+ "grok-2-image",
54
+ "grok-2-image-latest",
55
+ "grok-2-image-1212",
56
+ ]
57
+ ] = "dall-e-3",
48
58
  timeout: Optional[float] = None,
49
59
  api_key: Optional[str] = None,
50
60
  url: Optional[str] = None,
@@ -64,19 +74,21 @@ class OpenAIImageToolkit(BaseToolkit):
64
74
  Literal["auto", "low", "medium", "high", "standard", "hd"]
65
75
  ] = "standard",
66
76
  response_format: Optional[Literal["url", "b64_json"]] = "b64_json",
67
- n: Optional[int] = 1,
68
77
  background: Optional[
69
78
  Literal["transparent", "opaque", "auto"]
70
79
  ] = "auto",
71
80
  style: Optional[Literal["vivid", "natural"]] = None,
72
81
  working_directory: Optional[str] = "image_save",
73
82
  ):
74
- r"""Initializes a new instance of the OpenAIImageToolkit class.
83
+ # NOTE: Some arguments are set in the constructor to prevent the agent
84
+ # from making invalid API calls with model-specific parameters. For
85
+ # example, the 'style' argument is only supported by 'dall-e-3'.
86
+ r"""Initializes a new instance of the ImageGenToolkit class.
75
87
 
76
88
  Args:
77
89
  api_key (Optional[str]): The API key for authenticating
78
- with the OpenAI service. (default: :obj:`None`)
79
- url (Optional[str]): The url to the OpenAI service.
90
+ with the image model service. (default: :obj:`None`)
91
+ url (Optional[str]): The url to the image model service.
80
92
  (default: :obj:`None`)
81
93
  model (Optional[str]): The model to use.
82
94
  (default: :obj:`"dall-e-3"`)
@@ -94,8 +106,6 @@ class OpenAIImageToolkit(BaseToolkit):
94
106
  (default: :obj:`"standard"`)
95
107
  response_format (Optional[Literal["url", "b64_json"]]):
96
108
  The format of the response.(default: :obj:`"b64_json"`)
97
- n (Optional[int]): The number of images to generate.
98
- (default: :obj:`1`)
99
109
  background (Optional[Literal["transparent", "opaque", "auto"]]):
100
110
  The background of the image.(default: :obj:`"auto"`)
101
111
  style (Optional[Literal["vivid", "natural"]]): The style of the
@@ -104,14 +114,27 @@ class OpenAIImageToolkit(BaseToolkit):
104
114
  image.(default: :obj:`"image_save"`)
105
115
  """
106
116
  super().__init__(timeout=timeout)
107
- api_key = api_key or os.environ.get("OPENAI_API_KEY")
108
- url = url or os.environ.get("OPENAI_API_BASE_URL")
109
- self.client = OpenAI(api_key=api_key, base_url=url)
117
+ if model not in self.GROK_MODELS + self.OPENAI_MODELS:
118
+ available_models = sorted(self.OPENAI_MODELS + self.GROK_MODELS)
119
+ raise ValueError(
120
+ f"Unsupported model: {model}. "
121
+ f"Supported models are: {available_models}"
122
+ )
123
+
124
+ # Set default url for Grok models
125
+ url = "https://api.x.ai/v1" if model in self.GROK_MODELS else url
126
+
127
+ api_key, base_url = (
128
+ self.get_openai_credentials(url, api_key)
129
+ if model in self.OPENAI_MODELS
130
+ else self.get_grok_credentials(url, api_key)
131
+ )
132
+
133
+ self.client = OpenAI(api_key=api_key, base_url=base_url)
110
134
  self.model = model
111
135
  self.size = size
112
136
  self.quality = quality
113
137
  self.response_format = response_format
114
- self.n = n
115
138
  self.background = background
116
139
  self.style = style
117
140
  self.working_directory: str = working_directory or "image_save"
@@ -140,11 +163,12 @@ class OpenAIImageToolkit(BaseToolkit):
140
163
  )
141
164
  return None
142
165
 
143
- def _build_base_params(self, prompt: str) -> dict:
144
- r"""Build base parameters dict for OpenAI API calls.
166
+ def _build_base_params(self, prompt: str, n: Optional[int] = None) -> dict:
167
+ r"""Build base parameters dict for Image Model API calls.
145
168
 
146
169
  Args:
147
170
  prompt (str): The text prompt for the image operation.
171
+ n (Optional[int]): The number of images to generate.
148
172
 
149
173
  Returns:
150
174
  dict: Parameters dictionary with non-None values.
@@ -152,8 +176,12 @@ class OpenAIImageToolkit(BaseToolkit):
152
176
  params = {"prompt": prompt, "model": self.model}
153
177
 
154
178
  # basic parameters supported by all models
155
- if self.n is not None:
156
- params["n"] = self.n # type: ignore[assignment]
179
+ if n is not None:
180
+ params["n"] = n # type: ignore[assignment]
181
+
182
+ if self.model in self.GROK_MODELS:
183
+ return params
184
+
157
185
  if self.size is not None:
158
186
  params["size"] = self.size
159
187
 
@@ -180,27 +208,48 @@ class OpenAIImageToolkit(BaseToolkit):
180
208
  params["quality"] = self.quality
181
209
  if self.background is not None:
182
210
  params["background"] = self.background
183
-
184
211
  return params
185
212
 
186
213
  def _handle_api_response(
187
- self, response, image_name: str, operation: str
214
+ self,
215
+ response,
216
+ image_name: Union[str, List[str]],
217
+ operation: str,
188
218
  ) -> str:
189
- r"""Handle API response from OpenAI image operations.
219
+ r"""Handle API response from image operations.
190
220
 
191
221
  Args:
192
- response: The response object from OpenAI API.
193
- image_name (str): Name for the saved image file.
222
+ response: The response object from image model API.
223
+ image_name (Union[str, List[str]]): Name(s) for the saved image
224
+ file(s). If str, the same name is used for all images (will
225
+ cause error for multiple images). If list, must have exactly
226
+ the same length as the number of images generated.
194
227
  operation (str): Operation type for success message ("generated").
195
228
 
196
229
  Returns:
197
230
  str: Success message with image path/URL or error message.
198
231
  """
232
+ source = "Grok" if self.model in self.GROK_MODELS else "OpenAI"
199
233
  if response.data is None or len(response.data) == 0:
200
- error_msg = "No image data returned from OpenAI API."
234
+ error_msg = f"No image data returned from {source} API."
201
235
  logger.error(error_msg)
202
236
  return error_msg
203
237
 
238
+ # Validate image_name parameter
239
+ if isinstance(image_name, list):
240
+ if len(image_name) != len(response.data):
241
+ error_msg = (
242
+ f"Error: Number of image names"
243
+ f" ({len(image_name)}) does not match number of "
244
+ f"images generated({len(response.data)})"
245
+ )
246
+ logger.error(error_msg)
247
+ return error_msg
248
+ image_names = image_name
249
+ else:
250
+ # If string, use same name for all images
251
+ image_names = [image_name] * len(response.data)
252
+
204
253
  results = []
205
254
 
206
255
  for i, image_data in enumerate(response.data):
@@ -215,18 +264,27 @@ class OpenAIImageToolkit(BaseToolkit):
215
264
  image_bytes = base64.b64decode(image_b64)
216
265
  os.makedirs(self.working_directory, exist_ok=True)
217
266
 
218
- # Add index to filename when multiple images
219
- if len(response.data) > 1:
220
- filename = f"{image_name}_{i+1}_{uuid.uuid4().hex}.png"
221
- else:
222
- filename = f"{image_name}_{uuid.uuid4().hex}.png"
267
+ filename = f"{image_names[i]}"
223
268
 
224
269
  image_path = os.path.join(self.working_directory, filename)
225
270
 
226
- with open(image_path, "wb") as f:
227
- f.write(image_bytes)
228
-
229
- results.append(f"Image saved to {image_path}")
271
+ # Check if file already exists
272
+ if os.path.exists(image_path):
273
+ error_msg = (
274
+ f"Error: File '{image_path}' already exists. "
275
+ "Please use a different image_name."
276
+ )
277
+ logger.error(error_msg)
278
+ return error_msg
279
+
280
+ try:
281
+ with open(image_path, "wb") as f:
282
+ f.write(image_bytes)
283
+ results.append(f"Image saved to {image_path}")
284
+ except Exception as e:
285
+ error_msg = f"Error saving image to '{image_path}': {e!s}"
286
+ logger.error(error_msg)
287
+ return error_msg
230
288
  else:
231
289
  error_msg = (
232
290
  f"No valid image data (URL or base64) found in image {i+1}"
@@ -254,23 +312,28 @@ class OpenAIImageToolkit(BaseToolkit):
254
312
  def generate_image(
255
313
  self,
256
314
  prompt: str,
257
- image_name: str = "image",
315
+ image_name: Union[str, List[str]] = "image.png",
316
+ n: int = 1,
258
317
  ) -> str:
259
- r"""Generate an image using OpenAI's Image Generation models.
318
+ r"""Generate an image using image models.
260
319
  The generated image will be saved locally (for ``b64_json`` response
261
320
  formats) or an image URL will be returned (for ``url`` response
262
321
  formats).
263
322
 
264
323
  Args:
265
324
  prompt (str): The text prompt to generate the image.
266
- image_name (str): The name of the image to save.
267
- (default: :obj:`"image"`)
325
+ image_name (Union[str, List[str]]): The name(s) of the image(s) to
326
+ save. The image name must end with `.png`. If str: same name
327
+ used for all images (causes error if n > 1). If list: must
328
+ match the number of images being generated (n parameter).
329
+ (default: :obj:`"image.png"`)
330
+ n (int): The number of images to generate. (default: :obj:`1`)
268
331
 
269
332
  Returns:
270
333
  str: the content of the model response or format of the response.
271
334
  """
272
335
  try:
273
- params = self._build_base_params(prompt)
336
+ params = self._build_base_params(prompt, n)
274
337
  response = self.client.images.generate(**params)
275
338
  return self._handle_api_response(response, image_name, "generated")
276
339
  except Exception as e:
@@ -278,15 +341,50 @@ class OpenAIImageToolkit(BaseToolkit):
278
341
  logger.error(error_msg)
279
342
  return error_msg
280
343
 
344
+ @api_keys_required([("api_key", "XAI_API_KEY")])
345
+ def get_grok_credentials(self, url, api_key) -> Tuple[str, str]: # type: ignore[return-value]
346
+ r"""Get API credentials for the specified Grok model.
347
+
348
+ Args:
349
+ url (str): The base URL for the Grok API.
350
+ api_key (str): The API key for the Grok API.
351
+
352
+ Returns:
353
+ tuple: (api_key, base_url)
354
+ """
355
+
356
+ # Get credentials based on model type
357
+ api_key = api_key or os.getenv("XAI_API_KEY")
358
+ return api_key, url
359
+
360
+ @api_keys_required([("api_key", "OPENAI_API_KEY")])
361
+ def get_openai_credentials(self, url, api_key) -> Tuple[str, str | None]: # type: ignore[return-value]
362
+ r"""Get API credentials for the specified OpenAI model.
363
+
364
+ Args:
365
+ url (str): The base URL for the OpenAI API.
366
+ api_key (str): The API key for the OpenAI API.
367
+
368
+ Returns:
369
+ Tuple[str, str | None]: (api_key, base_url)
370
+ """
371
+
372
+ api_key = api_key or os.getenv("OPENAI_API_KEY")
373
+ base_url = url or os.getenv("OPENAI_API_BASE_URL")
374
+ return api_key, base_url
375
+
281
376
  def get_tools(self) -> List[FunctionTool]:
282
- r"""Returns a list of FunctionTool objects representing the
283
- functions in the toolkit.
377
+ r"""Returns a list of FunctionTool objects representing the functions
378
+ in the toolkit.
284
379
 
285
380
  Returns:
286
- List[FunctionTool]: A list of FunctionTool objects
287
- representing the functions in the toolkit.
381
+ List[FunctionTool]: A list of FunctionTool objects representing the
382
+ functions in the toolkit.
288
383
  """
289
384
  return [
290
385
  FunctionTool(self.generate_image),
291
- # could add edit_image function later
292
386
  ]
387
+
388
+
389
+ # Backward compatibility alias
390
+ OpenAIImageToolkit = ImageGenToolkit
@@ -21,7 +21,11 @@ import requests
21
21
  from camel.logger import get_logger
22
22
  from camel.toolkits.base import BaseToolkit
23
23
  from camel.toolkits.function_tool import FunctionTool
24
- from camel.utils import MCPServer, api_keys_required, dependencies_required
24
+ from camel.utils import (
25
+ MCPServer,
26
+ api_keys_required,
27
+ dependencies_required,
28
+ )
25
29
 
26
30
  logger = get_logger(__name__)
27
31
 
@@ -25,12 +25,38 @@ logger = get_logger(__name__)
25
25
 
26
26
  @MCPServer()
27
27
  class MarkItDownToolkit(BaseToolkit):
28
- r"""A class representing a toolkit for MarkItDown."""
28
+ r"""A class representing a toolkit for MarkItDown.
29
+
30
+ .. deprecated::
31
+ MarkItDownToolkit is deprecated. Use FileToolkit instead, which now
32
+ includes the same functionality through its read_file method that
33
+ supports both single files and multiple files.
34
+
35
+ Example migration:
36
+ # Old way
37
+ from camel.toolkits import MarkItDownToolkit
38
+ toolkit = MarkItDownToolkit()
39
+ content = toolkit.read_files(['file1.pdf', 'file2.docx'])
40
+
41
+ # New way
42
+ from camel.toolkits import FileToolkit
43
+ toolkit = FileToolkit()
44
+ content = toolkit.read_file(['file1.pdf', 'file2.docx'])
45
+ """
29
46
 
30
47
  def __init__(
31
48
  self,
32
49
  timeout: Optional[float] = None,
33
50
  ):
51
+ import warnings
52
+
53
+ warnings.warn(
54
+ "MarkItDownToolkit is deprecated and will be removed in a future "
55
+ "version. Please use FileToolkit instead, which now includes "
56
+ "read_file method that supports both single and multiple files.",
57
+ DeprecationWarning,
58
+ stacklevel=2,
59
+ )
34
60
  super().__init__(timeout=timeout)
35
61
 
36
62
  def read_files(self, file_paths: List[str]) -> Dict[str, str]:
@@ -12,6 +12,7 @@
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
+ import warnings
15
16
  from typing import List
16
17
 
17
18
  from camel.toolkits.base import BaseToolkit
@@ -27,7 +28,7 @@ class MathToolkit(BaseToolkit):
27
28
  addition, subtraction, multiplication, division, and rounding.
28
29
  """
29
30
 
30
- def add(self, a: float, b: float) -> float:
31
+ def math_add(self, a: float, b: float) -> float:
31
32
  r"""Adds two numbers.
32
33
 
33
34
  Args:
@@ -39,7 +40,7 @@ class MathToolkit(BaseToolkit):
39
40
  """
40
41
  return a + b
41
42
 
42
- def sub(self, a: float, b: float) -> float:
43
+ def math_subtract(self, a: float, b: float) -> float:
43
44
  r"""Do subtraction between two numbers.
44
45
 
45
46
  Args:
@@ -51,7 +52,9 @@ class MathToolkit(BaseToolkit):
51
52
  """
52
53
  return a - b
53
54
 
54
- def multiply(self, a: float, b: float, decimal_places: int = 2) -> float:
55
+ def math_multiply(
56
+ self, a: float, b: float, decimal_places: int = 2
57
+ ) -> float:
55
58
  r"""Multiplies two numbers.
56
59
 
57
60
  Args:
@@ -65,7 +68,9 @@ class MathToolkit(BaseToolkit):
65
68
  """
66
69
  return round(a * b, decimal_places)
67
70
 
68
- def divide(self, a: float, b: float, decimal_places: int = 2) -> float:
71
+ def math_divide(
72
+ self, a: float, b: float, decimal_places: int = 2
73
+ ) -> float:
69
74
  r"""Divides two numbers.
70
75
 
71
76
  Args:
@@ -79,7 +84,7 @@ class MathToolkit(BaseToolkit):
79
84
  """
80
85
  return round(a / b, decimal_places)
81
86
 
82
- def round(self, a: float, decimal_places: int = 0) -> float:
87
+ def math_round(self, a: float, decimal_places: int = 0) -> float:
83
88
  r"""Rounds a number to a specified number of decimal places.
84
89
 
85
90
  Args:
@@ -101,9 +106,58 @@ class MathToolkit(BaseToolkit):
101
106
  representing the functions in the toolkit.
102
107
  """
103
108
  return [
104
- FunctionTool(self.add),
105
- FunctionTool(self.sub),
106
- FunctionTool(self.multiply),
107
- FunctionTool(self.divide),
108
- FunctionTool(self.round),
109
+ FunctionTool(self.math_add),
110
+ FunctionTool(self.math_subtract),
111
+ FunctionTool(self.math_multiply),
112
+ FunctionTool(self.math_divide),
113
+ FunctionTool(self.math_round),
109
114
  ]
115
+
116
+ # Deprecated method aliases for backward compatibility
117
+ def add(self, *args, **kwargs):
118
+ r"""Deprecated: Use math_add instead."""
119
+ warnings.warn(
120
+ "add is deprecated. Use math_add instead.",
121
+ DeprecationWarning,
122
+ stacklevel=2,
123
+ )
124
+ return self.math_add(*args, **kwargs)
125
+
126
+ def sub(self, *args, **kwargs):
127
+ r"""Deprecated: Use math_subtract instead."""
128
+ warnings.warn(
129
+ "sub is deprecated. Use math_subtract instead.",
130
+ DeprecationWarning,
131
+ stacklevel=2,
132
+ )
133
+ return self.math_subtract(*args, **kwargs)
134
+
135
+ def multiply(self, *args, **kwargs):
136
+ r"""Deprecated: Use math_multiply instead."""
137
+ warnings.warn(
138
+ "multiply is deprecated. Use math_multiply instead.",
139
+ DeprecationWarning,
140
+ stacklevel=2,
141
+ )
142
+ return self.math_multiply(*args, **kwargs)
143
+
144
+ def divide(self, *args, **kwargs):
145
+ r"""Deprecated: Use math_divide instead."""
146
+ warnings.warn(
147
+ "divide is deprecated. Use math_divide instead.",
148
+ DeprecationWarning,
149
+ stacklevel=2,
150
+ )
151
+ return self.math_divide(*args, **kwargs)
152
+
153
+ def round(self, *args, **kwargs):
154
+ r"""Deprecated: Use math_round instead. Note: This was shadowing
155
+ Python's built-in round().
156
+ """
157
+ warnings.warn(
158
+ "round is deprecated. Use math_round instead. This was "
159
+ "shadowing Python's built-in round().",
160
+ DeprecationWarning,
161
+ stacklevel=2,
162
+ )
163
+ return self.math_round(*args, **kwargs)