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
@@ -1,368 +0,0 @@
1
- # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
- # Licensed under the Apache License, Version 2.0 (the "License");
3
- # you may not use this file except in compliance with the License.
4
- # You may obtain a copy of the License at
5
- #
6
- # http://www.apache.org/licenses/LICENSE-2.0
7
- #
8
- # Unless required by applicable law or agreed to in writing, software
9
- # distributed under the License is distributed on an "AS IS" BASIS,
10
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
- # See the License for the specific language governing permissions and
12
- # limitations under the License.
13
- # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
- from functools import wraps
15
- from pathlib import Path
16
- from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
17
-
18
- if TYPE_CHECKING:
19
- from pandas import DataFrame
20
- from pandasai import SmartDataframe
21
-
22
-
23
- def check_suffix(valid_suffixs: List[str]) -> Callable:
24
- r"""A decorator to check the file suffix of a given file path.
25
-
26
- Args:
27
- valid_suffix (str): The required file suffix.
28
-
29
- Returns:
30
- Callable: The decorator function.
31
- """
32
-
33
- def decorator(func: Callable):
34
- @wraps(func)
35
- def wrapper(
36
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
37
- ) -> "DataFrame":
38
- suffix = Path(file_path).suffix
39
- if suffix not in valid_suffixs:
40
- raise ValueError(
41
- f"Only {', '.join(valid_suffixs)} files are supported"
42
- )
43
- return func(self, file_path, *args, **kwargs)
44
-
45
- return wrapper
46
-
47
- return decorator
48
-
49
-
50
- class PandasReader:
51
- def __init__(self, config: Optional[Dict[str, Any]] = None) -> None:
52
- r"""Initializes the PandasReader class.
53
-
54
- Args:
55
- config (Optional[Dict[str, Any]], optional): The configuration
56
- dictionary that can include LLM API settings for LLM-based
57
- processing. If not provided, no LLM will be configured by
58
- default. You can customize the LLM configuration by providing
59
- a 'llm' key in the config dictionary. (default: :obj:`None`)
60
- """
61
- self.config = config or {}
62
-
63
- self.__LOADER = {
64
- ".csv": self.read_csv,
65
- ".xlsx": self.read_excel,
66
- ".xls": self.read_excel,
67
- ".json": self.read_json,
68
- ".parquet": self.read_parquet,
69
- ".sql": self.read_sql,
70
- ".html": self.read_html,
71
- ".feather": self.read_feather,
72
- ".dta": self.read_stata,
73
- ".sas": self.read_sas,
74
- ".pkl": self.read_pickle,
75
- ".h5": self.read_hdf,
76
- ".orc": self.read_orc,
77
- }
78
-
79
- def load(
80
- self,
81
- data: Union["DataFrame", str],
82
- *args: Any,
83
- **kwargs: Dict[str, Any],
84
- ) -> Union["DataFrame", "SmartDataframe"]:
85
- r"""Loads a file or DataFrame and returns a DataFrame or
86
- SmartDataframe object.
87
-
88
- If an LLM is configured in the config dictionary, a SmartDataframe
89
- will be returned, otherwise a regular pandas DataFrame will be
90
- returned.
91
-
92
- args:
93
- data (Union[DataFrame, str]): The data to load.
94
- *args (Any): Additional positional arguments.
95
- **kwargs (Dict[str, Any]): Additional keyword arguments.
96
-
97
- Returns:
98
- Union[DataFrame, SmartDataframe]: The DataFrame or SmartDataframe
99
- object.
100
- """
101
- from pandas import DataFrame
102
-
103
- # Load the data into a pandas DataFrame
104
- if isinstance(data, DataFrame):
105
- df = data
106
- else:
107
- file_path = str(data)
108
- path = Path(file_path)
109
- if not file_path.startswith("http") and not path.exists():
110
- raise FileNotFoundError(f"File {file_path} not found")
111
- if path.suffix in self.__LOADER:
112
- df = self.__LOADER[path.suffix](file_path, *args, **kwargs) # type: ignore[operator]
113
- else:
114
- raise ValueError(f"Unsupported file format: {path.suffix}")
115
-
116
- # If an LLM is configured, return a SmartDataframe, otherwise return a
117
- # regular DataFrame
118
- if "llm" in self.config:
119
- from pandasai import SmartDataframe
120
-
121
- return SmartDataframe(df, config=self.config)
122
- else:
123
- return df
124
-
125
- @check_suffix([".csv"])
126
- def read_csv(
127
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
128
- ) -> "DataFrame":
129
- r"""Reads a CSV file and returns a DataFrame.
130
-
131
- Args:
132
- file_path (str): The path to the CSV file.
133
- *args (Any): Additional positional arguments.
134
- **kwargs (Dict[str, Any]): Additional keyword arguments.
135
-
136
- Returns:
137
- DataFrame: The DataFrame object.
138
- """
139
- import pandas as pd
140
-
141
- return pd.read_csv(file_path, *args, **kwargs)
142
-
143
- @check_suffix([".xlsx", ".xls"])
144
- def read_excel(
145
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
146
- ) -> "DataFrame":
147
- r"""Reads an Excel file and returns a DataFrame.
148
-
149
- Args:
150
- file_path (str): The path to the Excel file.
151
- *args (Any): Additional positional arguments.
152
- **kwargs (Dict[str, Any]): Additional keyword arguments.
153
-
154
- Returns:
155
- DataFrame: The DataFrame object.
156
- """
157
- import pandas as pd
158
-
159
- return pd.read_excel(file_path, *args, **kwargs)
160
-
161
- @check_suffix([".json"])
162
- def read_json(
163
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
164
- ) -> "DataFrame":
165
- r"""Reads a JSON file and returns a DataFrame.
166
-
167
- Args:
168
- file_path (str): The path to the JSON file.
169
- *args (Any): Additional positional arguments.
170
- **kwargs (Dict[str, Any]): Additional keyword arguments.
171
-
172
- Returns:
173
- DataFrame: The DataFrame object.
174
- """
175
- import pandas as pd
176
-
177
- return pd.read_json(file_path, *args, **kwargs)
178
-
179
- @check_suffix([".parquet"])
180
- def read_parquet(
181
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
182
- ) -> "DataFrame":
183
- r"""Reads a Parquet file and returns a DataFrame.
184
-
185
- Args:
186
- file_path (str): The path to the Parquet file.
187
- *args (Any): Additional positional arguments.
188
- **kwargs (Dict[str, Any]): Additional keyword arguments.
189
-
190
- Returns:
191
- DataFrame: The DataFrame object.
192
- """
193
- import pandas as pd
194
-
195
- return pd.read_parquet(file_path, *args, **kwargs)
196
-
197
- def read_sql(self, *args: Any, **kwargs: Dict[str, Any]) -> "DataFrame":
198
- r"""Reads a SQL file and returns a DataFrame.
199
-
200
- Args:
201
- *args (Any): Additional positional arguments.
202
- **kwargs (Dict[str, Any]): Additional keyword arguments.
203
-
204
- Returns:
205
- DataFrame: The DataFrame object.
206
- """
207
- import pandas as pd
208
-
209
- return pd.read_sql(*args, **kwargs)
210
-
211
- def read_table(
212
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
213
- ) -> "DataFrame":
214
- r"""Reads a table and returns a DataFrame.
215
-
216
- Args:
217
- file_path (str): The path to the table.
218
- *args (Any): Additional positional arguments.
219
- **kwargs (Dict[str, Any]): Additional keyword arguments.
220
-
221
- Returns:
222
- DataFrame: The DataFrame object.
223
- """
224
- import pandas as pd
225
-
226
- return pd.read_table(file_path, *args, **kwargs)
227
-
228
- def read_clipboard(
229
- self, *args: Any, **kwargs: Dict[str, Any]
230
- ) -> "DataFrame":
231
- r"""Reads a clipboard and returns a DataFrame.
232
-
233
- Args:
234
- *args (Any): Additional positional arguments.
235
- **kwargs (Dict[str, Any]): Additional keyword arguments.
236
-
237
- Returns:
238
- DataFrame: The DataFrame object.
239
- """
240
- import pandas as pd
241
-
242
- return pd.read_clipboard(*args, **kwargs)
243
-
244
- @check_suffix([".html"])
245
- def read_html(
246
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
247
- ) -> "DataFrame":
248
- r"""Reads an HTML file and returns a DataFrame.
249
-
250
- Args:
251
- file_path (str): The path to the HTML file.
252
- *args (Any): Additional positional arguments.
253
- **kwargs (Dict[str, Any]): Additional keyword arguments.
254
-
255
- Returns:
256
- DataFrame: The DataFrame object.
257
- """
258
- import pandas as pd
259
-
260
- return pd.read_html(file_path, *args, **kwargs)
261
-
262
- @check_suffix([".feather"])
263
- def read_feather(
264
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
265
- ) -> "DataFrame":
266
- r"""Reads a Feather file and returns a DataFrame.
267
-
268
- Args:
269
- file_path (str): The path to the Feather file.
270
- *args (Any): Additional positional arguments.
271
- **kwargs (Dict[str, Any]): Additional keyword arguments.
272
-
273
- Returns:
274
- DataFrame: The DataFrame object.
275
- """
276
- import pandas as pd
277
-
278
- return pd.read_feather(file_path, *args, **kwargs)
279
-
280
- @check_suffix([".dta"])
281
- def read_stata(
282
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
283
- ) -> "DataFrame":
284
- r"""Reads a Stata file and returns a DataFrame.
285
-
286
- Args:
287
- file_path (str): The path to the Stata file.
288
- *args (Any): Additional positional arguments.
289
- **kwargs (Dict[str, Any]): Additional keyword arguments.
290
-
291
- Returns:
292
- DataFrame: The DataFrame object.
293
- """
294
- import pandas as pd
295
-
296
- return pd.read_stata(file_path, *args, **kwargs)
297
-
298
- @check_suffix([".sas"])
299
- def read_sas(
300
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
301
- ) -> "DataFrame":
302
- r"""Reads a SAS file and returns a DataFrame.
303
-
304
- Args:
305
- file_path (str): The path to the SAS file.
306
- *args (Any): Additional positional arguments.
307
- **kwargs (Dict[str, Any]): Additional keyword arguments.
308
-
309
- Returns:
310
- DataFrame: The DataFrame object.
311
- """
312
- import pandas as pd
313
-
314
- return pd.read_sas(file_path, *args, **kwargs)
315
-
316
- @check_suffix([".pkl"])
317
- def read_pickle(
318
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
319
- ) -> "DataFrame":
320
- r"""Reads a Pickle file and returns a DataFrame.
321
-
322
- Args:
323
- file_path (str): The path to the Pickle file.
324
- *args (Any): Additional positional arguments.
325
- **kwargs (Dict[str, Any]): Additional keyword arguments.
326
-
327
- Returns:
328
- DataFrame: The DataFrame object.
329
- """
330
- import pandas as pd
331
-
332
- return pd.read_pickle(file_path, *args, **kwargs)
333
-
334
- @check_suffix([".h5"])
335
- def read_hdf(
336
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
337
- ) -> "DataFrame":
338
- r"""Reads an HDF file and returns a DataFrame.
339
-
340
- Args:
341
- file_path (str): The path to the HDF file.
342
- *args (Any): Additional positional arguments.
343
- **kwargs (Dict[str, Any]): Additional keyword arguments.
344
-
345
- Returns:
346
- DataFrame: The DataFrame object.
347
- """
348
- import pandas as pd
349
-
350
- return pd.read_hdf(file_path, *args, **kwargs)
351
-
352
- @check_suffix([".orc"])
353
- def read_orc(
354
- self, file_path: str, *args: Any, **kwargs: Dict[str, Any]
355
- ) -> "DataFrame":
356
- r"""Reads an ORC file and returns a DataFrame.
357
-
358
- Args:
359
- file_path (str): The path to the ORC file.
360
- *args (Any): Additional positional arguments.
361
- **kwargs (Dict[str, Any]): Additional keyword arguments.
362
-
363
- Returns:
364
- DataFrame: The DataFrame object.
365
- """
366
- import pandas as pd
367
-
368
- return pd.read_orc(file_path, *args, **kwargs)
@@ -1,135 +0,0 @@
1
- # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
2
- # Licensed under the Apache License, Version 2.0 (the "License");
3
- # you may not use this file except in compliance with the License.
4
- # You may obtain a copy of the License at
5
- #
6
- # http://www.apache.org/licenses/LICENSE-2.0
7
- #
8
- # Unless required by applicable law or agreed to in writing, software
9
- # distributed under the License is distributed on an "AS IS" BASIS,
10
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
- # See the License for the specific language governing permissions and
12
- # limitations under the License.
13
- # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
-
15
- import os
16
- from typing import List, Optional
17
-
18
- from openai import OpenAI
19
-
20
- from camel.logger import get_logger
21
- from camel.models import BaseModelBackend, ModelFactory
22
- from camel.toolkits.base import BaseToolkit
23
- from camel.toolkits.function_tool import FunctionTool
24
- from camel.types import ModelPlatformType, ModelType
25
- from camel.utils import api_keys_required
26
-
27
- logger = get_logger(__name__)
28
-
29
-
30
- class OpenAIAgentToolkit(BaseToolkit):
31
- r"""Toolkit for accessing OpenAI's agent tools including web search and
32
- file search.
33
-
34
- Provides access to OpenAI's web search and file search capabilities
35
- through the Responses API, allowing agents to retrieve information from
36
- the web and search through uploaded files.
37
- """
38
-
39
- @api_keys_required(
40
- [
41
- (None, "OPENAI_API_KEY"),
42
- ]
43
- )
44
- def __init__(
45
- self,
46
- model: Optional[BaseModelBackend] = None,
47
- api_key: Optional[str] = None,
48
- timeout: Optional[float] = None,
49
- ) -> None:
50
- r"""Initialize the OpenAI agent toolkit.
51
-
52
- Args:
53
- model (BaseModelBackend): The OpenAI model to use for responses.
54
- If None, defaults to gpt-4o-mini. (default: :obj:`None`)
55
- api_key (str): OpenAI API key. If not provided, will attempt to
56
- use OPENAI_API_KEY environment variable. (default: :obj:`None`)
57
- timeout (Optional[float]): The timeout value for API requests
58
- in seconds. If None, no timeout is applied.
59
- (default: :obj:`None`)
60
- """
61
- super().__init__(timeout=timeout)
62
- self.api_key = api_key or os.getenv("OPENAI_API_KEY")
63
- self.client = OpenAI(api_key=self.api_key)
64
- self.model = model or ModelFactory.create(
65
- model_platform=ModelPlatformType.OPENAI,
66
- model_type=ModelType.GPT_4O_MINI,
67
- )
68
-
69
- def web_search(self, query: str) -> str:
70
- r"""Perform a web search using OpenAI's web search tool.
71
-
72
- Args:
73
- query (str): The search query.
74
-
75
- Returns:
76
- str: The search result or error message.
77
- """
78
- try:
79
- response = self.client.responses.create(
80
- model=str(self.model.model_type),
81
- tools=[{"type": "web_search_preview"}],
82
- input=query,
83
- )
84
- return response.output_text
85
-
86
- except Exception as e:
87
- logger.error(f"Web search failed: {e!s}")
88
- return f"Web search failed: {e!s}"
89
-
90
- def file_search(
91
- self,
92
- query: str,
93
- vector_store_id: str,
94
- ) -> str:
95
- r"""Search through files using OpenAI's file search tool.
96
-
97
- Args:
98
- query (str): The search query.
99
- vector_store_id (str): The vector store ID to search in.
100
-
101
- Returns:
102
- str: The search result or error message.
103
- """
104
- if not vector_store_id.strip():
105
- logger.error("Empty vector store ID provided.")
106
- return "Empty vector store ID provided, it cannot be empty."
107
-
108
- try:
109
- response = self.client.responses.create(
110
- model=str(self.model.model_type),
111
- tools=[
112
- {
113
- "type": "file_search",
114
- "vector_store_ids": [vector_store_id],
115
- }
116
- ],
117
- input=query,
118
- )
119
- return response.output_text
120
-
121
- except Exception as e:
122
- logger.error(f"File search failed: {e!s}")
123
- return f"File search failed: {e!s}"
124
-
125
- def get_tools(self) -> List[FunctionTool]:
126
- r"""Retrieve available toolkit functions as FunctionTool objects.
127
-
128
- Returns:
129
- List[FunctionTool]: Collection of FunctionTool objects representing
130
- the available search functions in this toolkit.
131
- """
132
- return [
133
- FunctionTool(self.web_search),
134
- FunctionTool(self.file_search),
135
- ]