camel-ai 0.2.15a0__py3-none-any.whl → 0.2.16__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 (61) hide show
  1. camel/__init__.py +1 -1
  2. camel/benchmarks/__init__.py +11 -1
  3. camel/benchmarks/apibank.py +560 -0
  4. camel/benchmarks/apibench.py +496 -0
  5. camel/benchmarks/gaia.py +2 -2
  6. camel/benchmarks/nexus.py +518 -0
  7. camel/datagen/__init__.py +6 -2
  8. camel/datagen/{o1datagen.py → cotdatagen.py} +19 -6
  9. camel/datagen/self_instruct/__init__.py +36 -0
  10. camel/datagen/self_instruct/filter/__init__.py +34 -0
  11. camel/datagen/self_instruct/filter/filter_function.py +216 -0
  12. camel/datagen/self_instruct/filter/filter_registry.py +56 -0
  13. camel/datagen/self_instruct/filter/instruction_filter.py +81 -0
  14. camel/datagen/self_instruct/self_instruct.py +393 -0
  15. camel/datagen/self_instruct/templates.py +384 -0
  16. camel/datahubs/huggingface.py +12 -2
  17. camel/datahubs/models.py +2 -3
  18. camel/embeddings/mistral_embedding.py +5 -1
  19. camel/embeddings/openai_compatible_embedding.py +6 -1
  20. camel/embeddings/openai_embedding.py +5 -1
  21. camel/interpreters/e2b_interpreter.py +5 -1
  22. camel/loaders/apify_reader.py +5 -1
  23. camel/loaders/chunkr_reader.py +5 -1
  24. camel/loaders/firecrawl_reader.py +0 -30
  25. camel/logger.py +11 -5
  26. camel/models/anthropic_model.py +5 -1
  27. camel/models/azure_openai_model.py +1 -2
  28. camel/models/cohere_model.py +5 -1
  29. camel/models/deepseek_model.py +5 -1
  30. camel/models/gemini_model.py +5 -1
  31. camel/models/groq_model.py +5 -1
  32. camel/models/mistral_model.py +5 -1
  33. camel/models/nemotron_model.py +5 -1
  34. camel/models/nvidia_model.py +5 -1
  35. camel/models/openai_model.py +5 -1
  36. camel/models/qwen_model.py +5 -1
  37. camel/models/reka_model.py +5 -1
  38. camel/models/reward/nemotron_model.py +5 -1
  39. camel/models/samba_model.py +5 -1
  40. camel/models/togetherai_model.py +5 -1
  41. camel/models/yi_model.py +5 -1
  42. camel/models/zhipuai_model.py +5 -1
  43. camel/schemas/openai_converter.py +5 -1
  44. camel/storages/graph_storages/nebula_graph.py +89 -20
  45. camel/storages/graph_storages/neo4j_graph.py +138 -0
  46. camel/toolkits/__init__.py +4 -0
  47. camel/toolkits/arxiv_toolkit.py +20 -3
  48. camel/toolkits/dappier_toolkit.py +196 -0
  49. camel/toolkits/function_tool.py +61 -61
  50. camel/toolkits/meshy_toolkit.py +5 -1
  51. camel/toolkits/notion_toolkit.py +1 -1
  52. camel/toolkits/openbb_toolkit.py +869 -0
  53. camel/toolkits/search_toolkit.py +91 -5
  54. camel/toolkits/stripe_toolkit.py +5 -1
  55. camel/toolkits/twitter_toolkit.py +24 -16
  56. camel/utils/__init__.py +2 -0
  57. camel/utils/commons.py +104 -19
  58. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.16.dist-info}/METADATA +16 -4
  59. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.16.dist-info}/RECORD +61 -49
  60. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.16.dist-info}/LICENSE +0 -0
  61. {camel_ai-0.2.15a0.dist-info → camel_ai-0.2.16.dist-info}/WHEEL +0 -0
@@ -13,9 +13,10 @@
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
  import os
15
15
  import xml.etree.ElementTree as ET
16
- from typing import Any, Dict, List, Optional, TypeAlias, Union
16
+ from typing import Any, Dict, List, Literal, Optional, Type, TypeAlias, Union
17
17
 
18
18
  import requests
19
+ from pydantic import BaseModel
19
20
 
20
21
  from camel.toolkits.base import BaseToolkit
21
22
  from camel.toolkits.function_tool import FunctionTool
@@ -63,6 +64,82 @@ class SearchToolkit(BaseToolkit):
63
64
 
64
65
  return result
65
66
 
67
+ @dependencies_required("linkup")
68
+ @api_keys_required(
69
+ [
70
+ (None, "LINKUP_API_KEY"),
71
+ ]
72
+ )
73
+ def search_linkup(
74
+ self,
75
+ query: str,
76
+ depth: Literal["standard", "deep"] = "standard",
77
+ output_type: Literal[
78
+ "searchResults", "sourcedAnswer", "structured"
79
+ ] = "searchResults",
80
+ structured_output_schema: Union[Type[BaseModel], str, None] = None,
81
+ ) -> Dict[str, Any]:
82
+ r"""Search for a query in the Linkup API and return results in various
83
+ formats.
84
+
85
+ Args:
86
+ query (str): The search query.
87
+ depth (Literal["standard", "deep"]): The depth of the search.
88
+ "standard" for a straightforward search, "deep" for a more
89
+ comprehensive search.
90
+ output_type (Literal["searchResults", "sourcedAnswer",
91
+ "structured"]): The type of output:
92
+ - "searchResults" for raw search results,
93
+ - "sourcedAnswer" for an answer with supporting sources,
94
+ - "structured" for output based on a provided schema.
95
+ structured_output_schema (Union[Type[BaseModel], str, None]): If
96
+ `output_type` is "structured",specify the schema of the
97
+ output. Can be a Pydantic BaseModel or a JSON schema string.
98
+
99
+ Returns:
100
+ Dict[str, Any]: A dictionary representing the search result. The
101
+ structure depends on the `output_type`. If an error occurs,
102
+ returns an error message.
103
+ """
104
+ try:
105
+ from linkup import LinkupClient
106
+
107
+ # Initialize the Linkup client with the API key
108
+ LINKUP_API_KEY = os.getenv("LINKUP_API_KEY")
109
+ client = LinkupClient(api_key=LINKUP_API_KEY)
110
+
111
+ # Perform the search using the specified output_type
112
+ response = client.search(
113
+ query=query,
114
+ depth=depth,
115
+ output_type=output_type,
116
+ structured_output_schema=structured_output_schema,
117
+ )
118
+
119
+ if output_type == "searchResults":
120
+ results = [
121
+ item.__dict__
122
+ for item in response.__dict__.get('results', [])
123
+ ]
124
+ return {"results": results}
125
+
126
+ elif output_type == "sourcedAnswer":
127
+ answer = response.__dict__.get('answer', '')
128
+ sources = [
129
+ item.__dict__
130
+ for item in response.__dict__.get('sources', [])
131
+ ]
132
+ return {"answer": answer, "sources": sources}
133
+
134
+ elif output_type == "structured" and structured_output_schema:
135
+ return response.__dict__
136
+
137
+ else:
138
+ return {"error": f"Invalid output_type: {output_type}"}
139
+
140
+ except Exception as e:
141
+ return {"error": f"An unexpected error occurred: {e!s}"}
142
+
66
143
  @dependencies_required("duckduckgo_search")
67
144
  def search_duckduckgo(
68
145
  self, query: str, source: str = "text", max_results: int = 5
@@ -151,7 +228,11 @@ class SearchToolkit(BaseToolkit):
151
228
  # If no answer found, return an empty list
152
229
  return responses
153
230
 
154
- @api_keys_required("BRAVE_API_KEY")
231
+ @api_keys_required(
232
+ [
233
+ (None, 'BRAVE_API_KEY'),
234
+ ]
235
+ )
155
236
  def search_brave(
156
237
  self,
157
238
  q: str,
@@ -297,7 +378,12 @@ class SearchToolkit(BaseToolkit):
297
378
  data = response.json()["web"]
298
379
  return data
299
380
 
300
- @api_keys_required("GOOGLE_API_KEY", "SEARCH_ENGINE_ID")
381
+ @api_keys_required(
382
+ [
383
+ (None, 'GOOGLE_API_KEY'),
384
+ (None, 'SEARCH_ENGINE_ID'),
385
+ ]
386
+ )
301
387
  def search_google(
302
388
  self, query: str, num_result_pages: int = 5
303
389
  ) -> List[Dict[str, Any]]:
@@ -429,8 +515,7 @@ class SearchToolkit(BaseToolkit):
429
515
  if not WOLFRAMALPHA_APP_ID:
430
516
  raise ValueError(
431
517
  "`WOLFRAMALPHA_APP_ID` not found in environment "
432
- "variables. Get `WOLFRAMALPHA_APP_ID` here: "
433
- "`https://products.wolframalpha.com/api/`."
518
+ "variables. Get `WOLFRAMALPHA_APP_ID` here: `https://products.wolframalpha.com/api/`."
434
519
  )
435
520
 
436
521
  try:
@@ -618,6 +703,7 @@ class SearchToolkit(BaseToolkit):
618
703
  """
619
704
  return [
620
705
  FunctionTool(self.search_wiki),
706
+ FunctionTool(self.search_linkup),
621
707
  FunctionTool(self.search_google),
622
708
  FunctionTool(self.search_duckduckgo),
623
709
  FunctionTool(self.query_wolfram_alpha),
@@ -36,7 +36,11 @@ class StripeToolkit(BaseToolkit):
36
36
  logger (Logger): a logger to write logs.
37
37
  """
38
38
 
39
- @api_keys_required("STRIPE_API_KEY")
39
+ @api_keys_required(
40
+ [
41
+ (None, "STRIPE_API_KEY"),
42
+ ]
43
+ )
40
44
  def __init__(self, retries: int = 3):
41
45
  r"""Initializes the StripeToolkit with the specified number of
42
46
  retries.
@@ -31,10 +31,12 @@ logger = get_logger(__name__)
31
31
 
32
32
 
33
33
  @api_keys_required(
34
- "TWITTER_CONSUMER_KEY",
35
- "TWITTER_CONSUMER_SECRET",
36
- "TWITTER_ACCESS_TOKEN",
37
- "TWITTER_ACCESS_TOKEN_SECRET",
34
+ [
35
+ (None, "TWITTER_CONSUMER_KEY"),
36
+ (None, "TWITTER_CONSUMER_SECRET"),
37
+ (None, "TWITTER_ACCESS_TOKEN"),
38
+ (None, "TWITTER_ACCESS_TOKEN_SECRET"),
39
+ ]
38
40
  )
39
41
  def create_tweet(
40
42
  text: str,
@@ -132,10 +134,12 @@ def create_tweet(
132
134
 
133
135
 
134
136
  @api_keys_required(
135
- "TWITTER_CONSUMER_KEY",
136
- "TWITTER_CONSUMER_SECRET",
137
- "TWITTER_ACCESS_TOKEN",
138
- "TWITTER_ACCESS_TOKEN_SECRET",
137
+ [
138
+ (None, "TWITTER_CONSUMER_KEY"),
139
+ (None, "TWITTER_CONSUMER_SECRET"),
140
+ (None, "TWITTER_ACCESS_TOKEN"),
141
+ (None, "TWITTER_ACCESS_TOKEN_SECRET"),
142
+ ]
139
143
  )
140
144
  def delete_tweet(tweet_id: str) -> str:
141
145
  r"""Deletes a tweet with the specified ID for an authorized user.
@@ -187,10 +191,12 @@ def delete_tweet(tweet_id: str) -> str:
187
191
 
188
192
 
189
193
  @api_keys_required(
190
- "TWITTER_CONSUMER_KEY",
191
- "TWITTER_CONSUMER_SECRET",
192
- "TWITTER_ACCESS_TOKEN",
193
- "TWITTER_ACCESS_TOKEN_SECRET",
194
+ [
195
+ (None, "TWITTER_CONSUMER_KEY"),
196
+ (None, "TWITTER_CONSUMER_SECRET"),
197
+ (None, "TWITTER_ACCESS_TOKEN"),
198
+ (None, "TWITTER_ACCESS_TOKEN_SECRET"),
199
+ ]
194
200
  )
195
201
  def get_my_user_profile() -> str:
196
202
  r"""Retrieves the authenticated user's Twitter profile info.
@@ -214,10 +220,12 @@ def get_my_user_profile() -> str:
214
220
 
215
221
 
216
222
  @api_keys_required(
217
- "TWITTER_CONSUMER_KEY",
218
- "TWITTER_CONSUMER_SECRET",
219
- "TWITTER_ACCESS_TOKEN",
220
- "TWITTER_ACCESS_TOKEN_SECRET",
223
+ [
224
+ (None, "TWITTER_CONSUMER_KEY"),
225
+ (None, "TWITTER_CONSUMER_SECRET"),
226
+ (None, "TWITTER_ACCESS_TOKEN"),
227
+ (None, "TWITTER_ACCESS_TOKEN_SECRET"),
228
+ ]
221
229
  )
222
230
  def get_user_by_username(username: str) -> str:
223
231
  r"""Retrieves one user's Twitter profile info by username (handle).
camel/utils/__init__.py CHANGED
@@ -19,6 +19,7 @@ from .commons import (
19
19
  check_server_running,
20
20
  create_chunks,
21
21
  dependencies_required,
22
+ download_github_subdirectory,
22
23
  download_tasks,
23
24
  func_string_to_callable,
24
25
  generate_prompt_for_structured_output,
@@ -79,5 +80,6 @@ __all__ = [
79
80
  "track_agent",
80
81
  "handle_http_error",
81
82
  "get_pydantic_model",
83
+ "download_github_subdirectory",
82
84
  "generate_prompt_for_structured_output",
83
85
  ]
camel/utils/commons.py CHANGED
@@ -21,6 +21,7 @@ import time
21
21
  import zipfile
22
22
  from functools import wraps
23
23
  from http import HTTPStatus
24
+ from pathlib import Path
24
25
  from typing import (
25
26
  Any,
26
27
  Callable,
@@ -29,6 +30,7 @@ from typing import (
29
30
  Mapping,
30
31
  Optional,
31
32
  Set,
33
+ Tuple,
32
34
  Type,
33
35
  TypeVar,
34
36
  cast,
@@ -231,41 +233,79 @@ def is_module_available(module_name: str) -> bool:
231
233
  return False
232
234
 
233
235
 
234
- def api_keys_required(*required_keys: str) -> Callable[[F], F]:
235
- r"""A decorator to check if the required API keys are
236
- presented in the environment variables or as an instance attribute.
236
+ def api_keys_required(
237
+ param_env_list: List[Tuple[Optional[str], str]],
238
+ ) -> Callable[[F], F]:
239
+ r"""A decorator to check if the required API keys are provided in the
240
+ environment variables or as function arguments.
237
241
 
238
242
  Args:
239
- required_keys (str): The required API keys to be checked.
243
+ param_env_list (List[Tuple[Optional[str], str]]): A list of tuples
244
+ where each tuple contains a function argument name (as the first
245
+ element, or None) and the corresponding environment variable name
246
+ (as the second element) that holds the API key.
240
247
 
241
248
  Returns:
242
- Callable[[F], F]: The original function with the added check
243
- for required API keys.
249
+ Callable[[F], F]: The original function wrapped with the added check
250
+ for the required API keys.
244
251
 
245
252
  Raises:
246
- ValueError: If any of the required API keys are missing in the
247
- environment variables and the instance attribute.
253
+ ValueError: If any of the required API keys are missing, either
254
+ from the function arguments or environment variables.
248
255
 
249
256
  Example:
250
257
  ::
251
258
 
252
- @api_keys_required('API_KEY_1', 'API_KEY_2')
253
- def some_api_function():
254
- # Function implementation...
259
+ @api_keys_required([
260
+ ('api_key_arg', 'API_KEY_1'),
261
+ ('another_key_arg', 'API_KEY_2'),
262
+ (None, 'API_KEY_3'),
263
+ ])
264
+ def some_api_function(api_key_arg=None, another_key_arg=None):
265
+ # Function implementation that requires API keys
255
266
  """
267
+ import inspect
256
268
 
257
269
  def decorator(func: F) -> F:
258
270
  @wraps(func)
259
271
  def wrapper(*args: Any, **kwargs: Any) -> Any:
260
- missing_environment_keys = [
261
- k for k in required_keys if k not in os.environ
262
- ]
263
- if (
264
- not (args and getattr(args[0], '_api_key', None))
265
- and missing_environment_keys
266
- ):
272
+ signature = inspect.signature(func)
273
+ bound_arguments = signature.bind(*args, **kwargs)
274
+ bound_arguments.apply_defaults()
275
+ arguments = bound_arguments.arguments
276
+
277
+ missing_keys = []
278
+ for param_name, env_var_name in param_env_list:
279
+ if not isinstance(env_var_name, str):
280
+ raise TypeError(
281
+ f"Environment variable name must be a string, got"
282
+ f" {type(env_var_name)}"
283
+ )
284
+
285
+ value = None
286
+ if (
287
+ param_name
288
+ ): # If param_name is provided, check function argument first
289
+ if not isinstance(param_name, str):
290
+ raise TypeError(
291
+ f"Parameter name must be a string, "
292
+ f"got {type(param_name)}"
293
+ )
294
+ value = arguments.get(param_name)
295
+ # If we found a valid value in arguments, continue to next
296
+ # item
297
+ if value:
298
+ continue
299
+
300
+ # Check environment variable if no valid value found yet
301
+ value = os.environ.get(env_var_name)
302
+ if not value or value.strip() == "":
303
+ missing_keys.append(env_var_name)
304
+
305
+ if missing_keys:
267
306
  raise ValueError(
268
- f"Missing API keys: {', '.join(missing_environment_keys)}"
307
+ "Missing or empty required API keys in "
308
+ f"environment variables: {', '.join(missing_keys)}"
269
309
  )
270
310
  return func(*args, **kwargs)
271
311
 
@@ -609,6 +649,51 @@ def retry_request(
609
649
  raise
610
650
 
611
651
 
652
+ def download_github_subdirectory(
653
+ repo: str, subdir: str, data_dir: Path, branch="main"
654
+ ):
655
+ r"""Download subdirectory of the Github repo of
656
+ the benchmark.
657
+
658
+ This function downloads all files and subdirectories from a
659
+ specified subdirectory of a GitHub repository and
660
+ saves them to a local directory.
661
+
662
+ Args:
663
+ repo (str): The name of the GitHub repository
664
+ in the format "owner/repo".
665
+ subdir (str): The path to the subdirectory
666
+ within the repository to download.
667
+ data_dir (Path): The local directory where
668
+ the files will be saved.
669
+ branch (str, optional): The branch of the repository to use.
670
+ Defaults to "main".
671
+ """
672
+ from tqdm import tqdm
673
+
674
+ api_url = (
675
+ f"https://api.github.com/repos/{repo}/contents/{subdir}?ref={branch}"
676
+ )
677
+ headers = {"Accept": "application/vnd.github.v3+json"}
678
+ response = requests.get(api_url, headers=headers)
679
+ response.raise_for_status()
680
+ files = response.json()
681
+ os.makedirs(data_dir, exist_ok=True)
682
+
683
+ for file in tqdm(files, desc="Downloading"):
684
+ file_path = data_dir / file["name"]
685
+
686
+ if file["type"] == "file":
687
+ file_url = file["download_url"]
688
+ file_response = requests.get(file_url)
689
+ with open(file_path, "wb") as f:
690
+ f.write(file_response.content)
691
+ elif file["type"] == "dir":
692
+ download_github_subdirectory(
693
+ repo, f'{subdir}/{file["name"]}', file_path, branch
694
+ )
695
+
696
+
612
697
  def generate_prompt_for_structured_output(
613
698
  response_format: Optional[Type[BaseModel]],
614
699
  user_message: str,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: camel-ai
3
- Version: 0.2.15a0
3
+ Version: 0.2.16
4
4
  Summary: Communicative Agents for AI Society Study
5
5
  Home-page: https://www.camel-ai.org/
6
6
  License: Apache-2.0
@@ -40,9 +40,10 @@ Requires-Dist: botocore (>=1.35.3,<2.0.0) ; extra == "object-storages" or extra
40
40
  Requires-Dist: cohere (>=5.11.0,<6.0.0) ; extra == "rag" or extra == "model-platforms" or extra == "retrievers" or extra == "all" or extra == "all"
41
41
  Requires-Dist: colorama (>=0,<1)
42
42
  Requires-Dist: curl_cffi (==0.6.2)
43
+ Requires-Dist: dappier (>=0.3.3,<0.4.0) ; extra == "tools" or extra == "all"
43
44
  Requires-Dist: datacommons (>=1.4.3,<2.0.0) ; extra == "tools" or extra == "all"
44
45
  Requires-Dist: datacommons_pandas (>=0.0.3,<0.0.4) ; extra == "tools" or extra == "all"
45
- Requires-Dist: datasets (>=2,<3) ; extra == "huggingface-agent" or extra == "all"
46
+ Requires-Dist: datasets (>=3,<4) ; extra == "huggingface-agent" or extra == "all"
46
47
  Requires-Dist: diffusers (>=0,<1) ; extra == "huggingface-agent" or extra == "all"
47
48
  Requires-Dist: discord.py (>=2.3.2,<3.0.0) ; extra == "tools" or extra == "all"
48
49
  Requires-Dist: docker (>=7.1.0,<8.0.0) ; extra == "tools" or extra == "runtime" or extra == "all"
@@ -62,6 +63,7 @@ Requires-Dist: imageio[pyav] (>=2.34.2,<3.0.0) ; extra == "tools" or extra == "a
62
63
  Requires-Dist: ipykernel (>=6.0.0,<7.0.0) ; extra == "tools" or extra == "all"
63
64
  Requires-Dist: jsonschema (>=4,<5)
64
65
  Requires-Dist: jupyter_client (>=8.6.2,<9.0.0) ; extra == "tools" or extra == "all"
66
+ Requires-Dist: linkup-sdk (>=0.2.1,<0.3.0) ; extra == "search-tools" or extra == "tools" or extra == "all"
65
67
  Requires-Dist: litellm (>=1.38.1,<2.0.0) ; extra == "model-platforms" or extra == "all"
66
68
  Requires-Dist: mistralai (>=1.1.0,<2.0.0) ; extra == "model-platforms" or extra == "all"
67
69
  Requires-Dist: mock (>=5,<6) ; extra == "test"
@@ -72,8 +74,10 @@ Requires-Dist: notion-client (>=2.2.1,<3.0.0) ; extra == "tools" or extra == "al
72
74
  Requires-Dist: numpy (>=1,<2)
73
75
  Requires-Dist: openai (>=1.58.1,<2.0.0)
74
76
  Requires-Dist: openapi-spec-validator (>=0.7.1,<0.8.0) ; extra == "tools" or extra == "all"
77
+ Requires-Dist: openbb (>=4.3.5,<5.0.0) ; extra == "tools" or extra == "all"
75
78
  Requires-Dist: opencv-python (>=4,<5) ; extra == "huggingface-agent" or extra == "all"
76
79
  Requires-Dist: outlines (>=0.1.7,<0.2.0) ; extra == "tools" or extra == "all"
80
+ Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "tools" or extra == "all"
77
81
  Requires-Dist: pandoc
78
82
  Requires-Dist: pathlib (>=1.0.1,<2.0.0)
79
83
  Requires-Dist: pdfplumber (>=0.11.0,<0.12.0) ; extra == "tools" or extra == "all"
@@ -95,6 +99,7 @@ Requires-Dist: rank-bm25 (>=0.2.2,<0.3.0) ; extra == "rag" or extra == "retrieve
95
99
  Requires-Dist: redis (>=5.0.6,<6.0.0) ; extra == "kv-stroages" or extra == "all"
96
100
  Requires-Dist: reka-api (>=3.0.8,<4.0.0) ; extra == "model-platforms" or extra == "all"
97
101
  Requires-Dist: requests_oauthlib (>=1.3.1,<2.0.0) ; extra == "tools" or extra == "all"
102
+ Requires-Dist: rouge (>=1.0.1,<2.0.0) ; extra == "tools" or extra == "all"
98
103
  Requires-Dist: scholarly[tor] (==1.7.11) ; extra == "tools" or extra == "all"
99
104
  Requires-Dist: sentence-transformers (>=3.0.1,<4.0.0) ; extra == "rag" or extra == "encoders" or extra == "all"
100
105
  Requires-Dist: sentencepiece (>=0,<1) ; extra == "huggingface-agent" or extra == "all"
@@ -109,7 +114,9 @@ Requires-Dist: tiktoken (>=0.7.0,<0.8.0)
109
114
  Requires-Dist: torch (==2.2.1) ; (platform_system == "Darwin" and platform_machine != "arm64") and (extra == "huggingface-agent" or extra == "all")
110
115
  Requires-Dist: torch (>=2,<3) ; (platform_system != "Darwin" or platform_machine == "arm64") and (extra == "huggingface-agent" or extra == "all")
111
116
  Requires-Dist: transformers (>=4,<5) ; extra == "huggingface-agent" or extra == "all"
112
- Requires-Dist: unstructured[all-docs] (==0.16.11) ; extra == "rag" or extra == "tools" or extra == "all" or extra == "all"
117
+ Requires-Dist: tree-sitter (>=0.23.2,<0.24.0) ; extra == "tools" or extra == "all"
118
+ Requires-Dist: tree-sitter-python (>=0.23.6,<0.24.0) ; extra == "tools" or extra == "all"
119
+ Requires-Dist: unstructured[all-docs] (==0.16.11) ; extra == "rag" or extra == "tools" or extra == "all"
113
120
  Requires-Dist: wikipedia (>=1,<2) ; extra == "search-tools" or extra == "tools" or extra == "all"
114
121
  Requires-Dist: wolframalpha (>=5.0.0,<6.0.0) ; extra == "search-tools" or extra == "tools" or extra == "all"
115
122
  Requires-Dist: yt-dlp (>=2024.11.4,<2025.0.0) ; extra == "tools" or extra == "all"
@@ -263,7 +270,7 @@ conda create --name camel python=3.10
263
270
  conda activate camel
264
271
 
265
272
  # Clone github repo
266
- git clone -b v0.2.15a0 https://github.com/camel-ai/camel.git
273
+ git clone -b v0.2.16 https://github.com/camel-ai/camel.git
267
274
 
268
275
  # Change directory into project directory
269
276
  cd camel
@@ -444,6 +451,9 @@ Practical guides and tutorials for implementing specific functionalities in CAME
444
451
  | **[Customer Service Discord Bot with Agentic RAG](https://docs.camel-ai.org/cookbooks/customer_service_Discord_bot_with_agentic_RAG.html)** | Learn how to build a robust customer service bot for Discord using Agentic RAG. |
445
452
  | **[Create AI Agents that work with your PDFs using Chunkr & Mistral AI](https://docs.camel-ai.org/cookbooks/agent_with_chunkr_for_pdf_parsing.html)** | Learn how to create AI agents that work with your PDFs using Chunkr and Mistral AI. |
446
453
  | **[Data Gen with Real Function Calls and Hermes Format](https://docs.camel-ai.org/cookbooks/data_gen_with_real_function_calls_and_hermes_format.html)** | Explore how to generate data with real function calls and the Hermes format. |
454
+ | **[CoT Data Generation and Upload Data to Huggingface](https://docs.camel-ai.org/cookbooks/cot_data_gen_upload_to_huggingface.html)** | Uncover how to generate CoT data with CAMEL and seamlessly upload it to Huggingface. |
455
+ | **[CoT Data Generation and SFT Qwen with Unsolth, Uploading Data and Model to Hugging Face](https://docs.camel-ai.org/cookbooks/cot_data_gen_sft_qwen_unsolth_upload_huggingface.html)** | Discover how to generate CoT data using CAMEL and SFT Qwen with Unsolth, and seamlessly upload your data and model to Huggingface. |
456
+ | **[Customer Service Discord Bot with Agentic RAG supports local model deployment](https://docs.camel-ai.org/cookbooks/customer_service_Discord_bot_using_local_model_with_agentic_RAG.html)** | Learn how to build a robust customer service bot for Discord using Agentic RAG which supports local deployment. |
447
457
 
448
458
  ## Utilize Various LLMs as Backends
449
459
 
@@ -473,6 +483,8 @@ We implemented amazing research ideas from other works for you to build, compare
473
483
 
474
484
  - `PersonaHub` from *Tao Ge et al.*: [Scaling Synthetic Data Creation with 1,000,000,000 Personas](https://arxiv.org/pdf/2406.20094). [[Example](https://github.com/camel-ai/camel/blob/master/examples/personas/personas_generation.py)]
475
485
 
486
+ - `Self-Instruct` from *Yizhong Wang et al.*: [SELF-INSTRUCT: Aligning Language Models with Self-Generated Instructions](https://arxiv.org/pdf/2212.10560). [[Example](https://github.com/camel-ai/camel/blob/master/examples/datagen/self_instruct/self_instruct.py)]
487
+
476
488
  ## Other Research Works Based on Camel
477
489
  - [Agent Trust](http://agent-trust.camel-ai.org/): Can Large Language Model Agents Simulate Human Trust Behavior?
478
490