camel-ai 0.2.59__py3-none-any.whl → 0.2.61__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 (55) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +158 -7
  3. camel/configs/anthropic_config.py +6 -5
  4. camel/configs/cohere_config.py +1 -1
  5. camel/configs/mistral_config.py +1 -1
  6. camel/configs/openai_config.py +3 -0
  7. camel/configs/reka_config.py +1 -1
  8. camel/configs/samba_config.py +2 -2
  9. camel/datagen/cot_datagen.py +29 -34
  10. camel/datagen/evol_instruct/scorer.py +22 -23
  11. camel/datagen/evol_instruct/templates.py +46 -46
  12. camel/datasets/static_dataset.py +144 -0
  13. camel/embeddings/jina_embedding.py +8 -1
  14. camel/embeddings/sentence_transformers_embeddings.py +2 -2
  15. camel/embeddings/vlm_embedding.py +9 -2
  16. camel/loaders/__init__.py +5 -2
  17. camel/loaders/chunkr_reader.py +117 -91
  18. camel/loaders/mistral_reader.py +148 -0
  19. camel/memories/blocks/chat_history_block.py +1 -2
  20. camel/memories/records.py +3 -0
  21. camel/messages/base.py +15 -3
  22. camel/models/azure_openai_model.py +1 -0
  23. camel/models/model_factory.py +2 -2
  24. camel/models/model_manager.py +7 -3
  25. camel/retrievers/bm25_retriever.py +1 -2
  26. camel/retrievers/hybrid_retrival.py +2 -2
  27. camel/societies/workforce/workforce.py +65 -24
  28. camel/storages/__init__.py +2 -0
  29. camel/storages/vectordb_storages/__init__.py +2 -0
  30. camel/storages/vectordb_storages/faiss.py +712 -0
  31. camel/storages/vectordb_storages/oceanbase.py +1 -2
  32. camel/toolkits/__init__.py +2 -0
  33. camel/toolkits/async_browser_toolkit.py +80 -524
  34. camel/toolkits/bohrium_toolkit.py +318 -0
  35. camel/toolkits/browser_toolkit.py +221 -541
  36. camel/toolkits/browser_toolkit_commons.py +568 -0
  37. camel/toolkits/dalle_toolkit.py +4 -0
  38. camel/toolkits/excel_toolkit.py +8 -2
  39. camel/toolkits/file_write_toolkit.py +76 -29
  40. camel/toolkits/github_toolkit.py +43 -25
  41. camel/toolkits/image_analysis_toolkit.py +3 -0
  42. camel/toolkits/jina_reranker_toolkit.py +194 -77
  43. camel/toolkits/mcp_toolkit.py +134 -16
  44. camel/toolkits/page_script.js +40 -28
  45. camel/toolkits/twitter_toolkit.py +6 -1
  46. camel/toolkits/video_analysis_toolkit.py +3 -0
  47. camel/toolkits/video_download_toolkit.py +3 -0
  48. camel/toolkits/wolfram_alpha_toolkit.py +51 -23
  49. camel/types/enums.py +27 -6
  50. camel/utils/__init__.py +2 -0
  51. camel/utils/commons.py +27 -0
  52. {camel_ai-0.2.59.dist-info → camel_ai-0.2.61.dist-info}/METADATA +17 -9
  53. {camel_ai-0.2.59.dist-info → camel_ai-0.2.61.dist-info}/RECORD +55 -51
  54. {camel_ai-0.2.59.dist-info → camel_ai-0.2.61.dist-info}/WHEEL +0 -0
  55. {camel_ai-0.2.59.dist-info → camel_ai-0.2.61.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,318 @@
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
+ import os
15
+ from typing import Any, Dict, List, Optional
16
+
17
+ try:
18
+ import yaml
19
+
20
+ HAS_YAML = True
21
+ except ImportError:
22
+ HAS_YAML = False
23
+
24
+ from camel.logger import get_logger
25
+ from camel.toolkits.base import BaseToolkit
26
+ from camel.toolkits.function_tool import FunctionTool
27
+ from camel.utils import MCPServer, api_keys_required
28
+
29
+ logger = get_logger(__name__)
30
+
31
+
32
+ @MCPServer()
33
+ class BohriumToolkit(BaseToolkit):
34
+ r"""A class representing a toolkit for interacting with Bohrium services.
35
+
36
+ Args:
37
+ timeout (Optional[float], optional): The timeout for BohriumToolkit.
38
+ (default: :obj:`None`)
39
+ api_key (Optional[str], optional): The API key for Bohrium client.
40
+ (default: :obj:`None`)
41
+ project_id (Optional[int], optional): The project ID for Bohrium
42
+ client. (default: :obj:`None`)
43
+ yaml_path (Optional[str], optional): The path to the YAML file
44
+ containing the job parameters. (default: :obj:`None`)
45
+ """
46
+
47
+ @api_keys_required(
48
+ [
49
+ ("api_key", "BOHRIUM_API_KEY"),
50
+ ]
51
+ )
52
+ def __init__(
53
+ self,
54
+ timeout: Optional[float] = None,
55
+ api_key: Optional[str] = None,
56
+ project_id: Optional[int] = None,
57
+ yaml_path: Optional[str] = None,
58
+ _test_mode: bool = False, # Used for testing without dependency
59
+ ):
60
+ super().__init__(timeout=timeout)
61
+
62
+ # Special path for testing without bohrium installed
63
+ if _test_mode:
64
+ self._client = None
65
+ self._job = None
66
+ self._project_id = project_id
67
+ self._yaml_path = yaml_path
68
+ return
69
+
70
+ try:
71
+ # Only import bohrium if not in test mode
72
+ from bohrium._client import Bohrium
73
+ from bohrium.resources import Job
74
+ except ImportError:
75
+ logger.error(
76
+ "bohrium is not installed, install it from "
77
+ "https://github.com/dptech-corp"
78
+ "/bohrium-openapi-python-sdk"
79
+ )
80
+ raise
81
+
82
+ api_key = api_key or os.environ.get("BOHRIUM_API_KEY")
83
+ self._client = Bohrium(access_key=api_key, project_id=project_id)
84
+ self._job = Job(self._client)
85
+ self._project_id = project_id
86
+ self._yaml_path = yaml_path
87
+
88
+ # refactor insert method
89
+ self._job.insert = self._custom_insert
90
+
91
+ def _custom_insert(self, data):
92
+ r"""refactor insert method, ensure return jobId information"""
93
+
94
+ response = self._client.post("/openapi/v2/job/add", json=data)
95
+ result = response.json()
96
+
97
+ return result
98
+
99
+ def submit_job(
100
+ self,
101
+ job_name: str = "bohr-job",
102
+ machine_type: str = "c2_m4_cpu",
103
+ cmd: str = "mpirun -n 2 lmp_mpi -i in.shear",
104
+ image_address: str = "registry.dp.tech/dptech/lammps:29Sep2021",
105
+ ) -> Dict[str, Any]:
106
+ r"""Submit a job to Bohrium.
107
+
108
+ Args:
109
+ job_name (str): The name of the job. It will be updated when yaml
110
+ file is provided. The yaml file might be set when initialize
111
+ BohriumToolkit.
112
+ (default: :obj:`bohr-job`)
113
+ machine_type (str): The type of machine to use. It will be updated
114
+ when yaml file is provided. The yaml file might be set when
115
+ initialize BohriumToolkit.
116
+ (default: :obj:`c2_m4_cpu`)
117
+ cmd (str): The command to run. It will be updated when yaml file
118
+ is provided. The yaml file might be set when initialize
119
+ (default: :obj:`mpirun -n 2 lmp_mpi -i in.shear`)
120
+ image_address (str): The address of the image to use. It will be
121
+ updated when yaml file is provided. The yaml file might be set
122
+ when initialize BohriumToolkit.
123
+ (default: :obj:`registry.dp.tech/dptech/lammps:29Sep2021`)
124
+
125
+ Returns:
126
+ Dict[str, Any]: The result of the job submission.
127
+ """
128
+ # Initialize params with default values
129
+ params: Dict[str, Any] = {
130
+ "project_id": self._project_id,
131
+ "job_name": job_name,
132
+ "machine_type": machine_type,
133
+ "cmd": cmd,
134
+ "image_address": image_address,
135
+ "work_dir": "",
136
+ "result": "",
137
+ "dataset_path": [],
138
+ "log_files": [],
139
+ "out_files": [],
140
+ }
141
+
142
+ # First load from YAML file if provided
143
+ if self._yaml_path and HAS_YAML:
144
+ try:
145
+ with open(self._yaml_path, 'r') as file:
146
+ yaml_params = yaml.safe_load(file)
147
+ if yaml_params:
148
+ params.update(yaml_params)
149
+ except yaml.YAMLError as e:
150
+ logger.error(f"Error parsing YAML file: {e}")
151
+ return {"error": f"YAML parsing error: {e!s}"}
152
+ except FileNotFoundError:
153
+ logger.error(f"YAML file not found: {self._yaml_path}")
154
+ return {"error": f"File not found: {self._yaml_path}"}
155
+ except Exception as e:
156
+ logger.error(f"Error loading YAML file: {e}")
157
+ return {"error": str(e)}
158
+ elif self._yaml_path and not HAS_YAML:
159
+ logger.warning(
160
+ "PyYAML is not installed. YAML file will be ignored."
161
+ )
162
+ return {"warning": "PyYAML is not installed. YAML file ignored."}
163
+
164
+ try:
165
+ result = self._job.submit( # type: ignore[union-attr]
166
+ project_id=params["project_id"],
167
+ job_name=params["job_name"],
168
+ machine_type=params["machine_type"],
169
+ cmd=params["cmd"],
170
+ image_address=params["image_address"],
171
+ job_group_id=params.get("job_group_id", 0),
172
+ work_dir=params["work_dir"],
173
+ result=params["result"],
174
+ dataset_path=params["dataset_path"],
175
+ log_files=params["log_files"],
176
+ out_files=params["out_files"],
177
+ )
178
+
179
+ return {"status": "Job submitted successfully", "result": result}
180
+
181
+ except Exception as e:
182
+ logger.error(f"Error submitting job: {e}")
183
+ return {"error": str(e)}
184
+
185
+ def get_job_details(self, job_id: int) -> Dict[str, Any]:
186
+ r"""Get details for a specific job.
187
+
188
+ Args:
189
+ job_id (int): The ID of the job.
190
+
191
+ Returns:
192
+ Dict[str, Any]: The job details.
193
+ """
194
+ try:
195
+ return self._job.detail(job_id) # type: ignore[union-attr]
196
+ except Exception as e:
197
+ logger.error(f"Error getting job details: {e}")
198
+ return {"error": str(e)}
199
+
200
+ def terminate_job(self, job_id: int) -> Dict[str, Any]:
201
+ r"""Terminate a running job.
202
+
203
+ Args:
204
+ job_id (int): The ID of the job to terminate.
205
+
206
+ Returns:
207
+ Dict[str, Any]: The result of the termination request.
208
+ """
209
+ try:
210
+ self._job.terminate(job_id) # type: ignore[union-attr]
211
+ return {"status": "Job terminated successfully"}
212
+ except Exception as e:
213
+ logger.error(f"Error terminating job: {e}")
214
+ return {"error": str(e)}
215
+
216
+ def kill_job(self, job_id: int) -> Dict[str, Any]:
217
+ r"""Kill a running job.
218
+
219
+ Args:
220
+ job_id (int): The ID of the job to kill.
221
+
222
+ Returns:
223
+ Dict[str, Any]: The result of the kill request.
224
+ """
225
+ try:
226
+ self._job.kill(job_id) # type: ignore[union-attr]
227
+ return {"status": "Job killed successfully"}
228
+ except Exception as e:
229
+ logger.error(f"Error killing job: {e}")
230
+ return {"error": str(e)}
231
+
232
+ def get_job_logs(
233
+ self,
234
+ job_id: int,
235
+ log_file: str = "STDOUTERR",
236
+ page: int = -1,
237
+ page_size: int = 8192,
238
+ ) -> str:
239
+ r"""Get logs for a specific job.
240
+
241
+ Args:
242
+ job_id (int): The ID of the job.
243
+ log_file (str, optional): The log file to get.
244
+ (default: :obj:`STDOUTERR`)
245
+ page (int, optional): The page number.
246
+ (default: :obj:`-1`)
247
+ page_size (int, optional): The page size.
248
+ (default: :obj:`8192`)
249
+
250
+ Returns:
251
+ str: The log contents.
252
+ """
253
+ try:
254
+ return self._job.log( # type: ignore[union-attr]
255
+ job_id, log_file=log_file, page=page, page_size=page_size
256
+ )
257
+ except Exception as e:
258
+ logger.error(f"Error getting job logs: {e}")
259
+ return f"Error retrieving logs: {e!s}"
260
+
261
+ def create_job_group(
262
+ self, project_id: int, job_group_name: str
263
+ ) -> Dict[str, Any]:
264
+ r"""Create a job group.
265
+
266
+ Args:
267
+ project_id (int): The ID of the project.
268
+ job_group_name (str): The name of the job group.
269
+
270
+ Returns:
271
+ Dict[str, Any]: The result of the job group creation.
272
+ """
273
+ try:
274
+ self._job.create_job_group(project_id, job_group_name) # type: ignore[union-attr]
275
+ return {"status": "Job group created successfully"}
276
+ except Exception as e:
277
+ logger.error(f"Error creating job group: {e}")
278
+ return {"error": str(e)}
279
+
280
+ def download_job_results(
281
+ self, job_id: int, save_path: str
282
+ ) -> Dict[str, Any]:
283
+ r"""Download the results of a job.
284
+
285
+ Args:
286
+ job_id (int): The ID of the job.
287
+ save_path (str): The path to save the results to.
288
+
289
+ Returns:
290
+ Dict[str, Any]: The result of the download request.
291
+ """
292
+ try:
293
+ self._job.download(job_id, save_path) # type: ignore[union-attr]
294
+ return {
295
+ "status": "Job results downloaded successfully",
296
+ "path": save_path,
297
+ }
298
+ except Exception as e:
299
+ logger.error(f"Error downloading job results: {e}")
300
+ return {"error": str(e)}
301
+
302
+ def get_tools(self) -> List[FunctionTool]:
303
+ r"""Returns a list of FunctionTool objects representing the
304
+ functions in the toolkit.
305
+
306
+ Returns:
307
+ List[FunctionTool]: A list of FunctionTool objects
308
+ representing the functions in the toolkit.
309
+ """
310
+ return [
311
+ FunctionTool(self.submit_job),
312
+ FunctionTool(self.get_job_details),
313
+ FunctionTool(self.terminate_job),
314
+ FunctionTool(self.kill_job),
315
+ FunctionTool(self.get_job_logs),
316
+ FunctionTool(self.create_job_group),
317
+ FunctionTool(self.download_job_results),
318
+ ]