camel-ai 0.2.37__py3-none-any.whl → 0.2.39__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 (122) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +4 -0
  3. camel/agents/repo_agent.py +2 -2
  4. camel/benchmarks/apibank.py +1 -1
  5. camel/benchmarks/apibench.py +1 -1
  6. camel/configs/__init__.py +3 -0
  7. camel/configs/modelscope_config.py +59 -0
  8. camel/datagen/evol_instruct/__init__.py +20 -0
  9. camel/datagen/evol_instruct/evol_instruct.py +424 -0
  10. camel/datagen/evol_instruct/scorer.py +166 -0
  11. camel/datagen/evol_instruct/templates.py +268 -0
  12. camel/datagen/self_improving_cot.py +1 -1
  13. camel/datasets/__init__.py +2 -0
  14. camel/datasets/base_generator.py +22 -9
  15. camel/datasets/few_shot_generator.py +2 -3
  16. camel/datasets/self_instruct_generator.py +415 -0
  17. camel/embeddings/openai_compatible_embedding.py +13 -5
  18. camel/environments/models.py +10 -4
  19. camel/environments/single_step.py +181 -41
  20. camel/interpreters/docker_interpreter.py +2 -2
  21. camel/interpreters/e2b_interpreter.py +1 -1
  22. camel/interpreters/internal_python_interpreter.py +1 -1
  23. camel/interpreters/subprocess_interpreter.py +1 -1
  24. camel/loaders/__init__.py +2 -2
  25. camel/loaders/{panda_reader.py → pandas_reader.py} +61 -30
  26. camel/loaders/unstructured_io.py +2 -1
  27. camel/memories/blocks/chat_history_block.py +1 -1
  28. camel/memories/context_creators/score_based.py +198 -67
  29. camel/models/__init__.py +2 -0
  30. camel/models/aiml_model.py +9 -3
  31. camel/models/anthropic_model.py +11 -3
  32. camel/models/azure_openai_model.py +9 -3
  33. camel/models/base_audio_model.py +6 -0
  34. camel/models/base_model.py +4 -0
  35. camel/models/deepseek_model.py +9 -3
  36. camel/models/gemini_model.py +9 -3
  37. camel/models/groq_model.py +9 -3
  38. camel/models/internlm_model.py +8 -2
  39. camel/models/model_factory.py +123 -0
  40. camel/models/modelscope_model.py +208 -0
  41. camel/models/moonshot_model.py +8 -2
  42. camel/models/nemotron_model.py +9 -3
  43. camel/models/nvidia_model.py +9 -3
  44. camel/models/ollama_model.py +9 -3
  45. camel/models/openai_audio_models.py +7 -5
  46. camel/models/openai_compatible_model.py +9 -3
  47. camel/models/openai_model.py +58 -5
  48. camel/models/openrouter_model.py +9 -3
  49. camel/models/qwen_model.py +9 -3
  50. camel/models/samba_model.py +9 -3
  51. camel/models/sglang_model.py +11 -4
  52. camel/models/siliconflow_model.py +8 -2
  53. camel/models/stub_model.py +2 -1
  54. camel/models/togetherai_model.py +11 -5
  55. camel/models/vllm_model.py +10 -4
  56. camel/models/yi_model.py +9 -3
  57. camel/models/zhipuai_model.py +11 -5
  58. camel/retrievers/auto_retriever.py +14 -0
  59. camel/retrievers/vector_retriever.py +1 -1
  60. camel/storages/__init__.py +2 -0
  61. camel/storages/graph_storages/neo4j_graph.py +1 -1
  62. camel/storages/vectordb_storages/__init__.py +2 -0
  63. camel/storages/vectordb_storages/base.py +2 -2
  64. camel/storages/vectordb_storages/milvus.py +2 -2
  65. camel/storages/vectordb_storages/qdrant.py +2 -2
  66. camel/storages/vectordb_storages/tidb.py +332 -0
  67. camel/tasks/task.py +2 -2
  68. camel/toolkits/__init__.py +9 -1
  69. camel/toolkits/arxiv_toolkit.py +2 -1
  70. camel/toolkits/ask_news_toolkit.py +11 -3
  71. camel/toolkits/audio_analysis_toolkit.py +2 -0
  72. camel/toolkits/base.py +3 -0
  73. camel/toolkits/browser_toolkit.py +84 -61
  74. camel/toolkits/code_execution.py +3 -1
  75. camel/toolkits/dappier_toolkit.py +2 -1
  76. camel/toolkits/data_commons_toolkit.py +2 -0
  77. camel/toolkits/excel_toolkit.py +2 -0
  78. camel/toolkits/file_write_toolkit.py +2 -0
  79. camel/toolkits/github_toolkit.py +6 -4
  80. camel/toolkits/google_scholar_toolkit.py +2 -0
  81. camel/toolkits/human_toolkit.py +17 -1
  82. camel/toolkits/image_analysis_toolkit.py +2 -0
  83. camel/toolkits/linkedin_toolkit.py +2 -1
  84. camel/toolkits/math_toolkit.py +2 -0
  85. camel/toolkits/mcp_toolkit.py +42 -52
  86. camel/toolkits/meshy_toolkit.py +20 -2
  87. camel/toolkits/networkx_toolkit.py +2 -0
  88. camel/toolkits/notion_toolkit.py +7 -0
  89. camel/toolkits/openai_agent_toolkit.py +131 -0
  90. camel/toolkits/openbb_toolkit.py +2 -1
  91. camel/toolkits/pubmed_toolkit.py +2 -0
  92. camel/toolkits/reddit_toolkit.py +2 -1
  93. camel/toolkits/retrieval_toolkit.py +2 -1
  94. camel/toolkits/search_toolkit.py +2 -1
  95. camel/toolkits/searxng_toolkit.py +207 -0
  96. camel/toolkits/semantic_scholar_toolkit.py +2 -0
  97. camel/toolkits/slack_toolkit.py +2 -0
  98. camel/toolkits/stripe_toolkit.py +2 -1
  99. camel/toolkits/sympy_toolkit.py +2 -0
  100. camel/toolkits/terminal_toolkit.py +2 -0
  101. camel/toolkits/thinking_toolkit.py +168 -12
  102. camel/toolkits/twitter_toolkit.py +2 -1
  103. camel/toolkits/video_analysis_toolkit.py +2 -1
  104. camel/toolkits/video_download_toolkit.py +2 -1
  105. camel/toolkits/weather_toolkit.py +2 -0
  106. camel/toolkits/whatsapp_toolkit.py +2 -1
  107. camel/toolkits/zapier_toolkit.py +2 -1
  108. camel/types/enums.py +66 -0
  109. camel/types/unified_model_type.py +5 -0
  110. camel/utils/__init__.py +2 -0
  111. camel/utils/chunker/code_chunker.py +9 -9
  112. camel/utils/commons.py +50 -30
  113. camel/utils/constants.py +2 -2
  114. camel/utils/mcp.py +79 -0
  115. camel/verifiers/__init__.py +2 -0
  116. camel/verifiers/base.py +15 -15
  117. camel/verifiers/math_verifier.py +182 -0
  118. camel/verifiers/python_verifier.py +28 -28
  119. {camel_ai-0.2.37.dist-info → camel_ai-0.2.39.dist-info}/METADATA +54 -4
  120. {camel_ai-0.2.37.dist-info → camel_ai-0.2.39.dist-info}/RECORD +122 -110
  121. {camel_ai-0.2.37.dist-info → camel_ai-0.2.39.dist-info}/WHEEL +0 -0
  122. {camel_ai-0.2.37.dist-info → camel_ai-0.2.39.dist-info}/licenses/LICENSE +0 -0
@@ -27,6 +27,7 @@ from typing import (
27
27
  BinaryIO,
28
28
  Dict,
29
29
  List,
30
+ Literal,
30
31
  Optional,
31
32
  Tuple,
32
33
  TypedDict,
@@ -51,37 +52,37 @@ logger = get_logger(__name__)
51
52
  TOP_NO_LABEL_ZONE = 20
52
53
 
53
54
  AVAILABLE_ACTIONS_PROMPT = """
54
- 1. `fill_input_id(identifier: Union[str, int], text: str)`: Fill an input
55
+ 1. `fill_input_id(identifier: Union[str, int], text: str)`: Fill an input
55
56
  field (e.g. search box) with the given text and press Enter.
56
57
  2. `click_id(identifier: Union[str, int])`: Click an element with the given ID.
57
- 3. `hover_id(identifier: Union[str, int])`: Hover over an element with the
58
+ 3. `hover_id(identifier: Union[str, int])`: Hover over an element with the
58
59
  given ID.
59
- 4. `download_file_id(identifier: Union[str, int])`: Download a file with the
60
- given ID. It returns the path to the downloaded file. If the file is
61
- successfully downloaded, you can stop the simulation and report the path to
60
+ 4. `download_file_id(identifier: Union[str, int])`: Download a file with the
61
+ given ID. It returns the path to the downloaded file. If the file is
62
+ successfully downloaded, you can stop the simulation and report the path to
62
63
  the downloaded file for further processing.
63
64
  5. `scroll_to_bottom()`: Scroll to the bottom of the page.
64
65
  6. `scroll_to_top()`: Scroll to the top of the page.
65
- 7. `scroll_up()`: Scroll up the page. It is suitable when you want to see the
66
+ 7. `scroll_up()`: Scroll up the page. It is suitable when you want to see the
66
67
  elements above the current viewport.
67
- 8. `scroll_down()`: Scroll down the page. It is suitable when you want to see
68
- the elements below the current viewport. If the webpage does not change, It
68
+ 8. `scroll_down()`: Scroll down the page. It is suitable when you want to see
69
+ the elements below the current viewport. If the webpage does not change, It
69
70
  means that the webpage has scrolled to the bottom.
70
- 9. `back()`: Navigate back to the previous page. This is useful when you want
71
+ 9. `back()`: Navigate back to the previous page. This is useful when you want
71
72
  to go back to the previous page, as current page is not useful.
72
- 10. `stop()`: Stop the action process, because the task is completed or failed
73
- (impossible to find the answer). In this situation, you should provide your
73
+ 10. `stop()`: Stop the action process, because the task is completed or failed
74
+ (impossible to find the answer). In this situation, you should provide your
74
75
  answer in your output.
75
76
  11. `get_url()`: Get the current URL of the current page.
76
- 12. `find_text_on_page(search_text: str)`: Find the next given text on the
77
- current whole page, and scroll the page to the targeted text. It is equivalent
78
- to pressing Ctrl + F and searching for the text, and is powerful when you want
77
+ 12. `find_text_on_page(search_text: str)`: Find the next given text on the
78
+ current whole page, and scroll the page to the targeted text. It is equivalent
79
+ to pressing Ctrl + F and searching for the text, and is powerful when you want
79
80
  to fast-check whether the current page contains some specific text.
80
81
  13. `visit_page(url: str)`: Go to the specific url page.
81
- 14. `click_blank_area()`: Click a blank area of the page to unfocus the
82
- current element. It is useful when you have clicked an element but it cannot
82
+ 14. `click_blank_area()`: Click a blank area of the page to unfocus the
83
+ current element. It is useful when you have clicked an element but it cannot
83
84
  unfocus itself (e.g. Menu bar) to automatically render the updated webpage.
84
- 15. `ask_question_about_video(question: str)`: Ask a question about the
85
+ 15. `ask_question_about_video(question: str)`: Ask a question about the
85
86
  current webpage which contains video, e.g. youtube websites.
86
87
  """
87
88
 
@@ -424,12 +425,20 @@ def _get_random_color(identifier: int) -> Tuple[int, int, int, int]:
424
425
 
425
426
 
426
427
  class BaseBrowser:
427
- def __init__(self, headless=True, cache_dir: Optional[str] = None):
428
- r"""Initialize the WebBrowserToolkit instance.
428
+ def __init__(
429
+ self,
430
+ headless=True,
431
+ cache_dir: Optional[str] = None,
432
+ channel: Literal["chrome", "msedge", "chromium"] = "chromium",
433
+ ):
434
+ r"""Initialize the WebBrowser instance.
429
435
 
430
436
  Args:
431
437
  headless (bool): Whether to run the browser in headless mode.
432
438
  cache_dir (Union[str, None]): The directory to store cache files.
439
+ channel (Literal["chrome", "msedge", "chromium"]): The browser
440
+ channel to use. Must be one of "chrome", "msedge", or
441
+ "chromium".
433
442
 
434
443
  Returns:
435
444
  None
@@ -438,9 +447,10 @@ class BaseBrowser:
438
447
  sync_playwright,
439
448
  )
440
449
 
441
- self._ensure_browser_installed()
442
450
  self.history: list = []
443
451
  self.headless = headless
452
+ self.channel = channel
453
+ self._ensure_browser_installed()
444
454
  self.playwright = sync_playwright().start()
445
455
  self.page_history: list = [] # stores the history of visited pages
446
456
 
@@ -464,7 +474,9 @@ class BaseBrowser:
464
474
  def init(self) -> None:
465
475
  r"""Initialize the browser."""
466
476
  # Launch the browser, if headless is False, the browser will display
467
- self.browser = self.playwright.chromium.launch(headless=self.headless)
477
+ self.browser = self.playwright.chromium.launch(
478
+ headless=self.headless, channel=self.channel
479
+ )
468
480
  # Create a new context
469
481
  self.context = self.browser.new_context(accept_downloads=True)
470
482
  # Create a new page
@@ -558,7 +570,7 @@ class BaseBrowser:
558
570
 
559
571
  Args:
560
572
  scroll_ratio (float): The ratio of viewport height to scroll each
561
- step (default: 0.8).
573
+ step. (default: :obj:`0.8`)
562
574
 
563
575
  Returns:
564
576
  List[str]: A list of paths to the screenshot files.
@@ -925,7 +937,7 @@ class BaseBrowser:
925
937
  from playwright.sync_api import sync_playwright
926
938
 
927
939
  with sync_playwright() as p:
928
- browser = p.chromium.launch()
940
+ browser = p.chromium.launch(channel=self.channel)
929
941
  browser.close()
930
942
  except Exception:
931
943
  logger.info("Installing Chromium browser...")
@@ -936,7 +948,7 @@ class BaseBrowser:
936
948
  "-m",
937
949
  "playwright",
938
950
  "install",
939
- "chromium",
951
+ self.channel,
940
952
  ],
941
953
  check=True,
942
954
  capture_output=True,
@@ -948,7 +960,7 @@ class BaseBrowser:
948
960
  "-m",
949
961
  "playwright",
950
962
  "install-deps",
951
- "chromium",
963
+ self.channel,
952
964
  ],
953
965
  check=True,
954
966
  capture_output=True,
@@ -969,6 +981,7 @@ class BrowserToolkit(BaseToolkit):
969
981
  self,
970
982
  headless: bool = False,
971
983
  cache_dir: Optional[str] = None,
984
+ channel: Literal["chrome", "msedge", "chromium"] = "chromium",
972
985
  history_window: int = 5,
973
986
  web_agent_model: Optional[BaseModelBackend] = None,
974
987
  planning_agent_model: Optional[BaseModelBackend] = None,
@@ -979,15 +992,24 @@ class BrowserToolkit(BaseToolkit):
979
992
  Args:
980
993
  headless (bool): Whether to run the browser in headless mode.
981
994
  cache_dir (Union[str, None]): The directory to store cache files.
995
+ channel (Literal["chrome", "msedge", "chromium"]): The browser
996
+ channel to use. Must be one of "chrome", "msedge", or
997
+ "chromium".
982
998
  history_window (int): The window size for storing the history of
983
999
  actions.
984
1000
  web_agent_model (Optional[BaseModelBackend]): The model backend
985
1001
  for the web agent.
986
1002
  planning_agent_model (Optional[BaseModelBackend]): The model
987
1003
  backend for the planning agent.
1004
+ output_language (str): The language to use for output.
1005
+ (default: :obj:`"en`")
988
1006
  """
989
1007
 
990
- self.browser = BaseBrowser(headless=headless, cache_dir=cache_dir)
1008
+ self.browser = BaseBrowser(
1009
+ headless=headless, cache_dir=cache_dir, channel=channel
1010
+ )
1011
+ # This needs to be called explicitly
1012
+ self.browser.init()
991
1013
 
992
1014
  self.history_window = history_window
993
1015
  self.web_agent_model = web_agent_model
@@ -1026,7 +1048,7 @@ class BrowserToolkit(BaseToolkit):
1026
1048
 
1027
1049
  system_prompt = """
1028
1050
  You are a helpful web agent that can assist users in browsing the web.
1029
- Given a high-level task, you can leverage predefined browser tools to help
1051
+ Given a high-level task, you can leverage predefined browser tools to help
1030
1052
  users achieve their goals.
1031
1053
  """
1032
1054
 
@@ -1037,7 +1059,7 @@ users achieve their goals.
1037
1059
  )
1038
1060
 
1039
1061
  planning_system_prompt = """
1040
- You are a helpful planning agent that can assist users in planning complex
1062
+ You are a helpful planning agent that can assist users in planning complex
1041
1063
  tasks which need multi-step browser interaction.
1042
1064
  """
1043
1065
 
@@ -1058,17 +1080,17 @@ tasks which need multi-step browser interaction.
1058
1080
 
1059
1081
  if detailed_plan is not None:
1060
1082
  detailed_plan_prompt = f"""
1061
- Here is a plan about how to solve the task step-by-step which you must follow:
1083
+ Here is a plan about how to solve the task step-by-step which you must follow:
1062
1084
  <detailed_plan>{detailed_plan}<detailed_plan>
1063
1085
  """
1064
1086
 
1065
1087
  observe_prompt = f"""
1066
- Please act as a web agent to help me complete the following high-level task:
1088
+ Please act as a web agent to help me complete the following high-level task:
1067
1089
  <task>{task_prompt}</task>
1068
- Now, I have made screenshot (only the current viewport, not the full webpage)
1069
- based on the current browser state, and marked interactive elements in the
1090
+ Now, I have made screenshot (only the current viewport, not the full webpage)
1091
+ based on the current browser state, and marked interactive elements in the
1070
1092
  webpage.
1071
- Please carefully examine the requirements of the task, and current state of
1093
+ Please carefully examine the requirements of the task, and current state of
1072
1094
  the browser, and provide the next appropriate action to take.
1073
1095
 
1074
1096
  {detailed_plan_prompt}
@@ -1082,14 +1104,14 @@ Here are the latest {self.history_window} trajectory (at most) you have taken:
1082
1104
  </history>
1083
1105
 
1084
1106
  Your output should be in json format, including the following fields:
1085
- - `observation`: The detailed image description about the current viewport. Do
1086
- not over-confident about the correctness of the history actions. You should
1087
- always check the current viewport to make sure the correctness of the next
1107
+ - `observation`: The detailed image description about the current viewport. Do
1108
+ not over-confident about the correctness of the history actions. You should
1109
+ always check the current viewport to make sure the correctness of the next
1088
1110
  action.
1089
- - `reasoning`: The reasoning about the next action you want to take, and the
1090
- possible obstacles you may encounter, and how to solve them. Do not forget to
1111
+ - `reasoning`: The reasoning about the next action you want to take, and the
1112
+ possible obstacles you may encounter, and how to solve them. Do not forget to
1091
1113
  check the history actions to avoid the same mistakes.
1092
- - `action_code`: The action code you want to take. It is only one step action
1114
+ - `action_code`: The action code you want to take. It is only one step action
1093
1115
  code, without any other texts (such as annotation)
1094
1116
 
1095
1117
  Here is two example of the output:
@@ -1108,37 +1130,37 @@ Here is two example of the output:
1108
1130
 
1109
1131
  Here are some tips for you:
1110
1132
  - Never forget the overall question: **{task_prompt}**
1111
- - Maybe after a certain operation (e.g. click_id), the page content has not
1112
- changed. You can check whether the action step is successful by looking at the
1113
- `success` of the action step in the history. If successful, it means that the
1133
+ - Maybe after a certain operation (e.g. click_id), the page content has not
1134
+ changed. You can check whether the action step is successful by looking at the
1135
+ `success` of the action step in the history. If successful, it means that the
1114
1136
  page content is indeed the same after the click. You need to try other methods.
1115
- - If using one way to solve the problem is not successful, try other ways.
1137
+ - If using one way to solve the problem is not successful, try other ways.
1116
1138
  Make sure your provided ID is correct!
1117
- - Some cases are very complex and need to be achieve by an iterative process.
1118
- You can use the `back()` function to go back to the previous page to try other
1139
+ - Some cases are very complex and need to be achieve by an iterative process.
1140
+ You can use the `back()` function to go back to the previous page to try other
1119
1141
  methods.
1120
- - There are many links on the page, which may be useful for solving the
1121
- problem. You can use the `click_id()` function to click on the link to see if
1142
+ - There are many links on the page, which may be useful for solving the
1143
+ problem. You can use the `click_id()` function to click on the link to see if
1122
1144
  it is useful.
1123
- - Always keep in mind that your action must be based on the ID shown in the
1145
+ - Always keep in mind that your action must be based on the ID shown in the
1124
1146
  current image or viewport, not the ID shown in the history.
1125
- - Do not use `stop()` lightly. Always remind yourself that the image only
1126
- shows a part of the full page. If you cannot find the answer, try to use
1127
- functions like `scroll_up()` and `scroll_down()` to check the full content of
1128
- the webpage before doing anything else, because the answer or next key step
1147
+ - Do not use `stop()` lightly. Always remind yourself that the image only
1148
+ shows a part of the full page. If you cannot find the answer, try to use
1149
+ functions like `scroll_up()` and `scroll_down()` to check the full content of
1150
+ the webpage before doing anything else, because the answer or next key step
1129
1151
  may be hidden in the content below.
1130
- - If the webpage needs human verification, you must avoid processing it.
1152
+ - If the webpage needs human verification, you must avoid processing it.
1131
1153
  Please use `back()` to go back to the previous page, and try other ways.
1132
- - If you have tried everything and still cannot resolve the issue, please stop
1154
+ - If you have tried everything and still cannot resolve the issue, please stop
1133
1155
  the simulation, and report issues you have encountered.
1134
- - Check the history actions carefully, detect whether you have repeatedly made
1156
+ - Check the history actions carefully, detect whether you have repeatedly made
1135
1157
  the same actions or not.
1136
- - When dealing with wikipedia revision history related tasks, you need to
1137
- think about the solution flexibly. First, adjust the browsing history
1138
- displayed on a single page to the maximum, and then make use of the
1139
- find_text_on_page function. This is extremely useful which can quickly locate
1158
+ - When dealing with wikipedia revision history related tasks, you need to
1159
+ think about the solution flexibly. First, adjust the browsing history
1160
+ displayed on a single page to the maximum, and then make use of the
1161
+ find_text_on_page function. This is extremely useful which can quickly locate
1140
1162
  the text you want to find and skip massive amount of useless information.
1141
- - Flexibly use interactive elements like slide down selection bar to filter
1163
+ - Flexibly use interactive elements like slide down selection bar to filter
1142
1164
  out the information you need. Sometimes they are extremely useful.
1143
1165
  ```
1144
1166
  """
@@ -1398,7 +1420,8 @@ Your output should be in json format, including the following fields:
1398
1420
  Args:
1399
1421
  task_prompt (str): The task prompt to solve.
1400
1422
  start_url (str): The start URL to visit.
1401
- round_limit (int): The round limit to solve the task (default: 12).
1423
+ round_limit (int): The round limit to solve the task.
1424
+ (default: :obj:`12`).
1402
1425
 
1403
1426
  Returns:
1404
1427
  str: The simulation result to the task.
@@ -22,10 +22,12 @@ from camel.interpreters import (
22
22
  )
23
23
  from camel.toolkits import FunctionTool
24
24
  from camel.toolkits.base import BaseToolkit
25
+ from camel.utils import MCPServer
25
26
 
26
27
 
28
+ @MCPServer()
27
29
  class CodeExecutionToolkit(BaseToolkit):
28
- r"""A tookit for code execution.
30
+ r"""A toolkit for code execution.
29
31
 
30
32
  Args:
31
33
  sandbox (str): The environment type used to execute code.
@@ -16,9 +16,10 @@ from typing import Dict, List, Literal, Optional, Union
16
16
 
17
17
  from camel.toolkits.base import BaseToolkit
18
18
  from camel.toolkits.function_tool import FunctionTool
19
- from camel.utils import api_keys_required, dependencies_required
19
+ from camel.utils import MCPServer, api_keys_required, dependencies_required
20
20
 
21
21
 
22
+ @MCPServer()
22
23
  class DappierToolkit(BaseToolkit):
23
24
  r"""A class representing a toolkit for interacting with the Dappier API.
24
25
 
@@ -16,10 +16,12 @@ from typing import Any, Dict, List, Optional, Union
16
16
 
17
17
  from camel.toolkits import FunctionTool
18
18
  from camel.toolkits.base import BaseToolkit
19
+ from camel.utils import MCPServer
19
20
 
20
21
  logger = logging.getLogger(__name__)
21
22
 
22
23
 
24
+ @MCPServer()
23
25
  class DataCommonsToolkit(BaseToolkit):
24
26
  r"""A class representing a toolkit for Data Commons.
25
27
 
@@ -19,10 +19,12 @@ import pandas as pd
19
19
  from camel.logger import get_logger
20
20
  from camel.toolkits.base import BaseToolkit
21
21
  from camel.toolkits.function_tool import FunctionTool
22
+ from camel.utils import MCPServer
22
23
 
23
24
  logger = get_logger(__name__)
24
25
 
25
26
 
27
+ @MCPServer()
26
28
  class ExcelToolkit(BaseToolkit):
27
29
  r"""A class representing a toolkit for extract detailed cell information
28
30
  from an Excel file.
@@ -21,6 +21,7 @@ from typing import List, Optional, Union
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
24
25
 
25
26
  logger = get_logger(__name__)
26
27
 
@@ -28,6 +29,7 @@ logger = get_logger(__name__)
28
29
  DEFAULT_FORMAT = '.md'
29
30
 
30
31
 
32
+ @MCPServer()
31
33
  class FileWriteToolkit(BaseToolkit):
32
34
  r"""A toolkit for creating, writing, and modifying text in files.
33
35
 
@@ -18,11 +18,12 @@ from typing import Dict, List, Literal, Optional, Union
18
18
 
19
19
  from camel.toolkits import FunctionTool
20
20
  from camel.toolkits.base import BaseToolkit
21
- from camel.utils import dependencies_required
21
+ from camel.utils import MCPServer, dependencies_required
22
22
 
23
23
  logger = logging.getLogger(__name__)
24
24
 
25
25
 
26
+ @MCPServer()
26
27
  class GithubToolkit(BaseToolkit):
27
28
  r"""A class representing a toolkit for interacting with GitHub
28
29
  repositories.
@@ -53,12 +54,13 @@ class GithubToolkit(BaseToolkit):
53
54
  `get_github_access_token` method.
54
55
  """
55
56
  super().__init__(timeout=timeout)
56
- from github import Auth, Github
57
+ from github.Auth import Token
58
+ from github.MainClass import Github
57
59
 
58
60
  if access_token is None:
59
61
  access_token = self.get_github_access_token()
60
62
 
61
- self.github = Github(auth=Auth.Token(access_token))
63
+ self.github = Github(auth=Token(access_token))
62
64
  self.repo = self.github.get_repo(repo_name)
63
65
 
64
66
  def get_github_access_token(self) -> str:
@@ -110,7 +112,7 @@ class GithubToolkit(BaseToolkit):
110
112
  successfully or not.
111
113
  """
112
114
  sb = self.repo.get_branch(self.repo.default_branch)
113
- from github import GithubException
115
+ from github.GithubException import GithubException
114
116
 
115
117
  try:
116
118
  self.repo.create_git_ref(
@@ -16,8 +16,10 @@ from typing import Any, Dict, List, Optional
16
16
 
17
17
  from camel.toolkits import FunctionTool
18
18
  from camel.toolkits.base import BaseToolkit
19
+ from camel.utils import MCPServer
19
20
 
20
21
 
22
+ @MCPServer()
21
23
  class GoogleScholarToolkit(BaseToolkit):
22
24
  r"""A toolkit for retrieving information about authors and their
23
25
  publications from Google Scholar.
@@ -39,6 +39,19 @@ class HumanToolkit(BaseToolkit):
39
39
  logger.info(f"User reply: {reply}")
40
40
  return reply
41
41
 
42
+ def send_message_to_user(self, message: str) -> None:
43
+ r"""Send a message to the user, without waiting for
44
+ a response. This will send to stdout in a noticeable way.
45
+
46
+ This is guaranteed to reach the user regardless of
47
+ actual user interface.
48
+
49
+ Args:
50
+ message (str): The message to send to the user.
51
+ """
52
+ print(f"\nAgent Message:\n{message}")
53
+ logger.info(f"\nAgent Message:\n{message}")
54
+
42
55
  def get_tools(self) -> List[FunctionTool]:
43
56
  r"""Returns a list of FunctionTool objects representing the
44
57
  functions in the toolkit.
@@ -47,4 +60,7 @@ class HumanToolkit(BaseToolkit):
47
60
  List[FunctionTool]: A list of FunctionTool objects
48
61
  representing the functions in the toolkit.
49
62
  """
50
- return [FunctionTool(self.ask_human_via_console)]
63
+ return [
64
+ FunctionTool(self.ask_human_via_console),
65
+ FunctionTool(self.send_message_to_user),
66
+ ]
@@ -25,10 +25,12 @@ from camel.models import BaseModelBackend, ModelFactory
25
25
  from camel.toolkits import FunctionTool
26
26
  from camel.toolkits.base import BaseToolkit
27
27
  from camel.types import ModelPlatformType, ModelType
28
+ from camel.utils import MCPServer
28
29
 
29
30
  logger = get_logger(__name__)
30
31
 
31
32
 
33
+ @MCPServer()
32
34
  class ImageAnalysisToolkit(BaseToolkit):
33
35
  r"""A toolkit for comprehensive image analysis and understanding.
34
36
  The toolkit uses vision-capable language models to perform these tasks.
@@ -21,11 +21,12 @@ import requests
21
21
 
22
22
  from camel.toolkits import FunctionTool
23
23
  from camel.toolkits.base import BaseToolkit
24
- from camel.utils import handle_http_error
24
+ from camel.utils import MCPServer, handle_http_error
25
25
 
26
26
  LINKEDIN_POST_LIMIT = 1300
27
27
 
28
28
 
29
+ @MCPServer()
29
30
  class LinkedInToolkit(BaseToolkit):
30
31
  r"""A class representing a toolkit for LinkedIn operations.
31
32
 
@@ -16,8 +16,10 @@ from typing import List
16
16
 
17
17
  from camel.toolkits.base import BaseToolkit
18
18
  from camel.toolkits.function_tool import FunctionTool
19
+ from camel.utils import MCPServer
19
20
 
20
21
 
22
+ @MCPServer()
21
23
  class MathToolkit(BaseToolkit):
22
24
  r"""A class representing a toolkit for mathematical operations.
23
25