camel-ai 0.2.58__py3-none-any.whl → 0.2.60__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 (44) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +126 -9
  3. camel/agents/critic_agent.py +73 -8
  4. camel/benchmarks/__init__.py +2 -0
  5. camel/benchmarks/browsecomp.py +854 -0
  6. camel/configs/cohere_config.py +1 -1
  7. camel/configs/mistral_config.py +1 -1
  8. camel/configs/openai_config.py +3 -0
  9. camel/configs/reka_config.py +1 -1
  10. camel/configs/samba_config.py +2 -2
  11. camel/datagen/cot_datagen.py +29 -34
  12. camel/embeddings/jina_embedding.py +8 -1
  13. camel/embeddings/sentence_transformers_embeddings.py +2 -2
  14. camel/embeddings/vlm_embedding.py +9 -2
  15. camel/human.py +14 -0
  16. camel/memories/records.py +3 -0
  17. camel/messages/base.py +15 -3
  18. camel/models/azure_openai_model.py +1 -0
  19. camel/models/model_factory.py +2 -2
  20. camel/retrievers/bm25_retriever.py +1 -2
  21. camel/retrievers/hybrid_retrival.py +2 -2
  22. camel/societies/role_playing.py +50 -0
  23. camel/societies/workforce/role_playing_worker.py +17 -8
  24. camel/societies/workforce/workforce.py +70 -14
  25. camel/storages/vectordb_storages/oceanbase.py +1 -2
  26. camel/toolkits/async_browser_toolkit.py +5 -1
  27. camel/toolkits/base.py +4 -2
  28. camel/toolkits/browser_toolkit.py +6 -3
  29. camel/toolkits/dalle_toolkit.py +4 -0
  30. camel/toolkits/excel_toolkit.py +11 -3
  31. camel/toolkits/github_toolkit.py +43 -25
  32. camel/toolkits/image_analysis_toolkit.py +3 -0
  33. camel/toolkits/jina_reranker_toolkit.py +194 -77
  34. camel/toolkits/mcp_toolkit.py +60 -16
  35. camel/toolkits/page_script.js +40 -28
  36. camel/toolkits/twitter_toolkit.py +6 -1
  37. camel/toolkits/video_analysis_toolkit.py +3 -0
  38. camel/toolkits/video_download_toolkit.py +3 -0
  39. camel/toolkits/wolfram_alpha_toolkit.py +46 -22
  40. camel/types/enums.py +14 -5
  41. {camel_ai-0.2.58.dist-info → camel_ai-0.2.60.dist-info}/METADATA +7 -9
  42. {camel_ai-0.2.58.dist-info → camel_ai-0.2.60.dist-info}/RECORD +44 -43
  43. {camel_ai-0.2.58.dist-info → camel_ai-0.2.60.dist-info}/WHEEL +0 -0
  44. {camel_ai-0.2.58.dist-info → camel_ai-0.2.60.dist-info}/licenses/LICENSE +0 -0
@@ -12,6 +12,9 @@
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
+ # Enables postponed evaluation of annotations (for string-based type hints)
16
+ from __future__ import annotations
17
+
15
18
  import datetime
16
19
  import io
17
20
  import json
@@ -38,8 +41,6 @@ from typing import (
38
41
 
39
42
  from PIL import Image, ImageDraw, ImageFont
40
43
 
41
- if TYPE_CHECKING:
42
- from camel.agents import ChatAgent
43
44
  from camel.logger import get_logger
44
45
  from camel.messages import BaseMessage
45
46
  from camel.models import BaseModelBackend, ModelFactory
@@ -53,6 +54,9 @@ from camel.utils import (
53
54
  sanitize_filename,
54
55
  )
55
56
 
57
+ if TYPE_CHECKING:
58
+ from camel.agents import ChatAgent
59
+
56
60
  logger = get_logger(__name__)
57
61
 
58
62
  TOP_NO_LABEL_ZONE = 20
@@ -577,7 +581,6 @@ class BaseBrowser:
577
581
  image and the path to the image file if saved, otherwise
578
582
  :obj:`None`.
579
583
  """
580
-
581
584
  image_data = self.page.screenshot(timeout=60000)
582
585
  image = Image.open(io.BytesIO(image_data))
583
586
 
@@ -11,6 +11,10 @@
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
+
15
+ # Enables postponed evaluation of annotations (for string-based type hints)
16
+ from __future__ import annotations
17
+
14
18
  import base64
15
19
  import os
16
20
  import uuid
@@ -12,15 +12,20 @@
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
- from typing import List, Optional
15
+ # Enables postponed evaluation of annotations (for string-based type hints)
16
+ from __future__ import annotations
16
17
 
17
- import pandas as pd
18
+ from typing import TYPE_CHECKING, List, Optional
18
19
 
19
20
  from camel.logger import get_logger
20
21
  from camel.toolkits.base import BaseToolkit
21
22
  from camel.toolkits.function_tool import FunctionTool
22
23
  from camel.utils import MCPServer
23
24
 
25
+ # Import only for type hints (not executed at runtime)
26
+ if TYPE_CHECKING:
27
+ import pandas as pd
28
+
24
29
  logger = get_logger(__name__)
25
30
 
26
31
 
@@ -29,7 +34,9 @@ class ExcelToolkit(BaseToolkit):
29
34
  r"""A class representing a toolkit for extract detailed cell information
30
35
  from an Excel file.
31
36
 
32
- This class provides method for processing excel files.
37
+ This class provides methods extracting detailed content from Excel files
38
+ (including .xls, .xlsx,.csv), and converting the data into
39
+ Markdown formatted table.
33
40
  """
34
41
 
35
42
  def __init__(
@@ -69,6 +76,7 @@ class ExcelToolkit(BaseToolkit):
69
76
  Returns:
70
77
  str: Extracted excel information, including details of each sheet.
71
78
  """
79
+ import pandas as pd
72
80
  from openpyxl import load_workbook
73
81
  from xls2xlsx import XLS2XLSX
74
82
 
@@ -32,7 +32,6 @@ class GithubToolkit(BaseToolkit):
32
32
  specific issues, and creating pull requests in a GitHub repository.
33
33
 
34
34
  Args:
35
- repo_name (str): The name of the GitHub repository.
36
35
  access_token (str, optional): The access token to authenticate with
37
36
  GitHub. If not provided, it will be obtained using the
38
37
  `get_github_access_token` method.
@@ -41,7 +40,6 @@ class GithubToolkit(BaseToolkit):
41
40
  @dependencies_required('github')
42
41
  def __init__(
43
42
  self,
44
- repo_name: str,
45
43
  access_token: Optional[str] = None,
46
44
  timeout: Optional[float] = None,
47
45
  ) -> None:
@@ -61,7 +59,6 @@ class GithubToolkit(BaseToolkit):
61
59
  access_token = self.get_github_access_token()
62
60
 
63
61
  self.github = Github(auth=Token(access_token))
64
- self.repo = self.github.get_repo(repo_name)
65
62
 
66
63
  def get_github_access_token(self) -> str:
67
64
  r"""Retrieve the GitHub access token from environment variables.
@@ -85,6 +82,7 @@ class GithubToolkit(BaseToolkit):
85
82
 
86
83
  def create_pull_request(
87
84
  self,
85
+ repo_name: str,
88
86
  file_path: str,
89
87
  new_content: str,
90
88
  pr_title: str,
@@ -98,6 +96,7 @@ class GithubToolkit(BaseToolkit):
98
96
  description contains information about the issue title and number.
99
97
 
100
98
  Args:
99
+ repo_name (str): The name of the GitHub repository.
101
100
  file_path (str): The path of the file to be updated in the
102
101
  repository.
103
102
  new_content (str): The specified new content of the specified file.
@@ -111,12 +110,13 @@ class GithubToolkit(BaseToolkit):
111
110
  str: A formatted report of whether the pull request was created
112
111
  successfully or not.
113
112
  """
114
- sb = self.repo.get_branch(self.repo.default_branch)
113
+ repo = self.github.get_repo(repo_name)
114
+ default_branch = repo.get_branch(repo.default_branch)
115
115
  from github.GithubException import GithubException
116
116
 
117
117
  try:
118
- self.repo.create_git_ref(
119
- ref=f"refs/heads/{branch_name}", sha=sb.commit.sha
118
+ repo.create_git_ref(
119
+ ref=f"refs/heads/{branch_name}", sha=default_branch.commit.sha
120
120
  )
121
121
  except GithubException as e:
122
122
  if e.message == "Reference already exists":
@@ -128,19 +128,19 @@ class GithubToolkit(BaseToolkit):
128
128
  else:
129
129
  raise
130
130
 
131
- file = self.repo.get_contents(file_path)
131
+ file = repo.get_contents(file_path)
132
132
 
133
133
  from github.ContentFile import ContentFile
134
134
 
135
135
  if isinstance(file, ContentFile):
136
- self.repo.update_file(
136
+ repo.update_file(
137
137
  file.path, body, new_content, file.sha, branch=branch_name
138
138
  )
139
- pr = self.repo.create_pull(
139
+ pr = repo.create_pull(
140
140
  title=pr_title,
141
141
  body=body,
142
142
  head=branch_name,
143
- base=self.repo.default_branch,
143
+ base=repo.default_branch,
144
144
  )
145
145
 
146
146
  if pr is not None:
@@ -151,11 +151,12 @@ class GithubToolkit(BaseToolkit):
151
151
  raise ValueError("PRs with multiple files aren't supported yet.")
152
152
 
153
153
  def get_issue_list(
154
- self, state: Literal["open", "closed", "all"] = "all"
154
+ self, repo_name: str, state: Literal["open", "closed", "all"] = "all"
155
155
  ) -> List[Dict[str, object]]:
156
156
  r"""Retrieves all issues from the GitHub repository.
157
157
 
158
158
  Args:
159
+ repo_name (str): The name of the GitHub repository.
159
160
  state (Literal["open", "closed", "all"]): The state of pull
160
161
  requests to retrieve. (default: :obj: `all`)
161
162
  Options are:
@@ -167,35 +168,39 @@ class GithubToolkit(BaseToolkit):
167
168
  List[Dict[str, object]]: A list of dictionaries where each
168
169
  dictionary contains the issue number and title.
169
170
  """
171
+ repo = self.github.get_repo(repo_name)
170
172
  issues_info = []
171
- issues = self.repo.get_issues(state=state)
173
+ issues = repo.get_issues(state=state)
172
174
 
173
175
  for issue in issues:
174
176
  issues_info.append({"number": issue.number, "title": issue.title})
175
177
 
176
178
  return issues_info
177
179
 
178
- def get_issue_content(self, issue_number: int) -> str:
180
+ def get_issue_content(self, repo_name: str, issue_number: int) -> str:
179
181
  r"""Retrieves the content of a specific issue by its number.
180
182
 
181
183
  Args:
184
+ repo_name (str): The name of the GitHub repository.
182
185
  issue_number (int): The number of the issue to retrieve.
183
186
 
184
187
  Returns:
185
188
  str: issues content details.
186
189
  """
187
190
  try:
188
- issue = self.repo.get_issue(number=issue_number)
191
+ repo = self.github.get_repo(repo_name)
192
+ issue = repo.get_issue(number=issue_number)
189
193
  return issue.body
190
194
  except Exception as e:
191
195
  return f"can't get Issue number {issue_number}: {e!s}"
192
196
 
193
197
  def get_pull_request_list(
194
- self, state: Literal["open", "closed", "all"] = "all"
198
+ self, repo_name: str, state: Literal["open", "closed", "all"] = "all"
195
199
  ) -> List[Dict[str, object]]:
196
200
  r"""Retrieves all pull requests from the GitHub repository.
197
201
 
198
202
  Args:
203
+ repo_name (str): The name of the GitHub repository.
199
204
  state (Literal["open", "closed", "all"]): The state of pull
200
205
  requests to retrieve. (default: :obj: `all`)
201
206
  Options are:
@@ -207,18 +212,22 @@ class GithubToolkit(BaseToolkit):
207
212
  list: A list of dictionaries where each dictionary contains the
208
213
  pull request number and title.
209
214
  """
215
+ repo = self.github.get_repo(repo_name)
210
216
  pull_requests_info = []
211
- pull_requests = self.repo.get_pulls(state=state)
217
+ pull_requests = repo.get_pulls(state=state)
212
218
 
213
219
  for pr in pull_requests:
214
220
  pull_requests_info.append({"number": pr.number, "title": pr.title})
215
221
 
216
222
  return pull_requests_info
217
223
 
218
- def get_pull_request_code(self, pr_number: int) -> List[Dict[str, str]]:
224
+ def get_pull_request_code(
225
+ self, repo_name: str, pr_number: int
226
+ ) -> List[Dict[str, str]]:
219
227
  r"""Retrieves the code changes of a specific pull request.
220
228
 
221
229
  Args:
230
+ repo_name (str): The name of the GitHub repository.
222
231
  pr_number (int): The number of the pull request to retrieve.
223
232
 
224
233
  Returns:
@@ -226,8 +235,9 @@ class GithubToolkit(BaseToolkit):
226
235
  contains the file name and the corresponding code changes
227
236
  (patch).
228
237
  """
238
+ repo = self.github.get_repo(repo_name)
229
239
  # Retrieve the specific pull request
230
- pr = self.repo.get_pull(number=pr_number)
240
+ pr = repo.get_pull(number=pr_number)
231
241
 
232
242
  # Collect the file changes from the pull request
233
243
  files_changed = []
@@ -244,19 +254,21 @@ class GithubToolkit(BaseToolkit):
244
254
  return files_changed
245
255
 
246
256
  def get_pull_request_comments(
247
- self, pr_number: int
257
+ self, repo_name: str, pr_number: int
248
258
  ) -> List[Dict[str, str]]:
249
259
  r"""Retrieves the comments from a specific pull request.
250
260
 
251
261
  Args:
262
+ repo_name (str): The name of the GitHub repository.
252
263
  pr_number (int): The number of the pull request to retrieve.
253
264
 
254
265
  Returns:
255
266
  List[Dict[str, str]]: A list of dictionaries where each dictionary
256
267
  contains the user ID and the comment body.
257
268
  """
269
+ repo = self.github.get_repo(repo_name)
258
270
  # Retrieve the specific pull request
259
- pr = self.repo.get_pull(number=pr_number)
271
+ pr = repo.get_pull(number=pr_number)
260
272
 
261
273
  # Collect the comments from the pull request
262
274
  comments = []
@@ -266,10 +278,11 @@ class GithubToolkit(BaseToolkit):
266
278
 
267
279
  return comments
268
280
 
269
- def get_all_file_paths(self, path: str = "") -> List[str]:
281
+ def get_all_file_paths(self, repo_name: str, path: str = "") -> List[str]:
270
282
  r"""Recursively retrieves all file paths in the GitHub repository.
271
283
 
272
284
  Args:
285
+ repo_name (str): The name of the GitHub repository.
273
286
  path (str): The repository path to start the traversal from.
274
287
  empty string means starts from the root directory.
275
288
  (default: :obj: `""`)
@@ -280,11 +293,13 @@ class GithubToolkit(BaseToolkit):
280
293
  """
281
294
  from github.ContentFile import ContentFile
282
295
 
296
+ repo = self.github.get_repo(repo_name)
297
+
283
298
  files: List[str] = []
284
299
 
285
300
  # Retrieves all contents of the current directory
286
- contents: Union[List[ContentFile], ContentFile] = (
287
- self.repo.get_contents(path)
301
+ contents: Union[List[ContentFile], ContentFile] = repo.get_contents(
302
+ path
288
303
  )
289
304
 
290
305
  if isinstance(contents, ContentFile):
@@ -299,10 +314,11 @@ class GithubToolkit(BaseToolkit):
299
314
  files.append(content.path)
300
315
  return files
301
316
 
302
- def retrieve_file_content(self, file_path: str) -> str:
317
+ def retrieve_file_content(self, repo_name: str, file_path: str) -> str:
303
318
  r"""Retrieves the content of a file from the GitHub repository.
304
319
 
305
320
  Args:
321
+ repo_name (str): The name of the GitHub repository.
306
322
  file_path (str): The path of the file to retrieve.
307
323
 
308
324
  Returns:
@@ -310,7 +326,9 @@ class GithubToolkit(BaseToolkit):
310
326
  """
311
327
  from github.ContentFile import ContentFile
312
328
 
313
- file_content = self.repo.get_contents(file_path)
329
+ repo = self.github.get_repo(repo_name)
330
+
331
+ file_content = repo.get_contents(file_path)
314
332
  if isinstance(file_content, ContentFile):
315
333
  return file_content.decoded_content.decode()
316
334
  else:
@@ -12,6 +12,9 @@
12
12
  # limitations under the License.
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
+ # Enables postponed evaluation of annotations (for string-based type hints)
16
+ from __future__ import annotations
17
+
15
18
  from io import BytesIO
16
19
  from typing import List, Optional
17
20
  from urllib.parse import urlparse