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
@@ -0,0 +1,216 @@
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 re
16
+ from abc import ABC, abstractmethod
17
+ from typing import List
18
+
19
+ from rouge import Rouge
20
+
21
+ from camel.models.reward import BaseRewardModel
22
+
23
+
24
+ class FilterFunction(ABC):
25
+ r"""A base abstract class for filter functions.
26
+
27
+ Subclasses must implement the `apply` method, which determines whether
28
+ a given instruction passes the filter criteria.
29
+ """
30
+
31
+ @abstractmethod
32
+ def apply(self, instruction: str) -> bool:
33
+ r"""Evaluate the given instruction based on the filter's criteria.
34
+
35
+ Args:
36
+ instruction (str): The instruction to evaluate.
37
+
38
+ Returns:
39
+ bool: True if the instruction passes the filter, False otherwise.
40
+ """
41
+ pass
42
+
43
+
44
+ class LengthFilter(FilterFunction):
45
+ r"""Filters instructions based on their word count.
46
+
47
+ Args:
48
+ min_len (int): The minimum word count required for an instruction.
49
+ (default::obj:`5`)
50
+ max_len (int): The maximum word count allowed for an instruction.
51
+ (default::obj:`200`)
52
+ """
53
+
54
+ def __init__(self, min_len: int = 5, max_len: int = 200):
55
+ self.min_len = min_len
56
+ self.max_len = max_len
57
+
58
+ def apply(self, instruction: str) -> bool:
59
+ r"""Filter the instruction
60
+
61
+ Args:
62
+ instruction (str): the instruction to be filtered.
63
+
64
+ Returns:
65
+ bool: True if the length of the instruction is within the range
66
+ of [min_len, max_len]
67
+ """
68
+ word_count = len(instruction.split())
69
+ return self.min_len <= word_count <= self.max_len
70
+
71
+
72
+ class KeywordFilter(FilterFunction):
73
+ r"""Filters instructions that contain specific undesirable keywords.
74
+
75
+ Args:
76
+ keywords (List[str]): A list of keywords to filter out.
77
+ """
78
+
79
+ def __init__(self, keywords: List[str]):
80
+ self.keywords = [keyword.lower() for keyword in keywords]
81
+
82
+ def apply(self, instruction: str) -> bool:
83
+ r"""Filter the instruction
84
+
85
+ Args:
86
+ instruction (str): the instruction to be filtered.
87
+
88
+ Returns:
89
+ bool: True Instruction must NOT contain any of the keywords.
90
+ """
91
+ lower_instr = instruction.lower()
92
+ return not any(keyword in lower_instr for keyword in self.keywords)
93
+
94
+
95
+ class PunctuationFilter(FilterFunction):
96
+ r"""Filters instructions that begin with a non-alphanumeric character."""
97
+
98
+ def apply(self, instruction: str) -> bool:
99
+ r"""Filter the instruction
100
+
101
+ Args:
102
+ instruction (str): the instruction to be filtered.
103
+
104
+ Returns:
105
+ bool: True if the instruction does not start with punctuation.
106
+ """
107
+ return not re.match(r'^[^\w\s]', instruction)
108
+
109
+
110
+ class NonEnglishFilter(FilterFunction):
111
+ r"""Filters instructions that do not begin with English letters."""
112
+
113
+ def apply(self, instruction: str) -> bool:
114
+ r"""Filter the instruction
115
+
116
+ Args:
117
+ instruction (str): the instruction to be filtered.
118
+
119
+ Returns:
120
+ bool: True if the instruction starts with an English letter.
121
+ """
122
+ return bool(re.match(r'^[A-Za-z]', instruction))
123
+
124
+
125
+ class RougeSimilarityFilter(FilterFunction):
126
+ r"""Filters instructions that are too similar to existing instructions
127
+ based on ROUGE scores.
128
+
129
+ Args:
130
+ existing_instructions (List[str]): A list of existing instructions to
131
+ compare against.
132
+ threshold (float): The similarity threshold for filtering.
133
+ (default::obj:`0.7`)
134
+ """
135
+
136
+ def __init__(
137
+ self, existing_instructions: List[str], threshold: float = 0.7
138
+ ):
139
+ self.existing_instructions = existing_instructions
140
+ self.threshold = threshold
141
+ self.rouge = Rouge()
142
+
143
+ def apply(self, instruction: str) -> bool:
144
+ r"""Filter the instruction
145
+
146
+ Args:
147
+ instruction (str): the instruction to be filtered.
148
+
149
+ Returns:
150
+ bool: True if the instruction's similarity to any existing
151
+ instruction is below the threshold.
152
+ """
153
+ if not self.existing_instructions:
154
+ return True
155
+
156
+ for existing_instr in self.existing_instructions:
157
+ scores = self.rouge.get_scores(instruction, existing_instr)
158
+ score = scores[0]['rouge-l']['f']
159
+ if score > self.threshold:
160
+ return False
161
+
162
+ return True
163
+
164
+
165
+ class RewardModelFilter(FilterFunction):
166
+ r"""Filters instructions based on scores provided by a reward model.
167
+
168
+ Args:
169
+ reward_model (BaseRewardModel): The reward model used to evaluate
170
+ the instructions.
171
+ threshold (float): The minimum score required for an instruction
172
+ to pass the filter.
173
+ """
174
+
175
+ def __init__(
176
+ self,
177
+ reward_model: BaseRewardModel,
178
+ threshold: float = 0.5,
179
+ ):
180
+ self.prompt = ""
181
+ self.reward_model = reward_model
182
+ self.threshold = threshold
183
+
184
+ def apply(self, instruction: str) -> bool:
185
+ r"""Filter the instruction
186
+
187
+ Args:
188
+ instruction (str): The instruction to be filtered.
189
+
190
+ Returns:
191
+ bool: True if the instruction's score is above the threshold.
192
+
193
+ Raises:
194
+ ValueError: ValueError: If `score_types` is empty or if the
195
+ required score is not found in `scores`.
196
+ """
197
+
198
+ data = [
199
+ {"role": "user", "content": self.prompt},
200
+ {"role": "assistant", "content": instruction},
201
+ ]
202
+ scores = self.reward_model.evaluate(data)
203
+ score_types = self.reward_model.get_scores_types()
204
+ if not score_types:
205
+ raise ValueError("No score types available from the reward model.")
206
+
207
+ score_type = score_types[0]
208
+ score = scores.get(score_type, None)
209
+
210
+ if score is None:
211
+ raise ValueError(
212
+ f"Score type '{score_type}' is not found in the "
213
+ "evaluation scores."
214
+ )
215
+
216
+ return score >= self.threshold
@@ -0,0 +1,56 @@
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 typing import Any, Callable, Dict
15
+
16
+ from .filter_function import (
17
+ FilterFunction,
18
+ KeywordFilter,
19
+ LengthFilter,
20
+ NonEnglishFilter,
21
+ PunctuationFilter,
22
+ RewardModelFilter,
23
+ RougeSimilarityFilter,
24
+ )
25
+
26
+ FILTER_REGISTRY: Dict[str, Callable[[Dict[str, Any]], FilterFunction]] = {
27
+ "length": lambda kwargs: LengthFilter(
28
+ min_len=kwargs.get("min_len", 5), max_len=kwargs.get("max_len", 200)
29
+ ),
30
+ "keyword": lambda kwargs: KeywordFilter(
31
+ keywords=kwargs.get("keywords", ["image", "data"])
32
+ ),
33
+ "punctuation": lambda kwargs: PunctuationFilter(),
34
+ "non_english": lambda kwargs: NonEnglishFilter(),
35
+ "rouge_similarity": lambda kwargs: RougeSimilarityFilter(
36
+ existing_instructions=kwargs.get("existing_instructions", []),
37
+ threshold=kwargs.get("threshold", 0.7),
38
+ ),
39
+ "reward": lambda kwargs: RewardModelFilter(
40
+ reward_model=kwargs.get("reward_model"), # type:ignore[arg-type]
41
+ threshold=kwargs.get("threshold", 0.7),
42
+ ),
43
+ }
44
+
45
+
46
+ def register_filter(
47
+ name: str, constructor: Callable[[Dict[str, Any]], FilterFunction]
48
+ ):
49
+ r"""Registers a new filter constructor in FILTER_REGISTRY.
50
+
51
+ Args:
52
+ name (str): Unique name of the filter.
53
+ constructor (Callable[[Dict[str, Any]], FilterFunction]): Function to
54
+ create the filter using a dictionary of parameters.
55
+ """
56
+ FILTER_REGISTRY[name] = constructor
@@ -0,0 +1,81 @@
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 typing import Any, Dict, List
15
+
16
+ from .filter_function import FilterFunction, RewardModelFilter
17
+ from .filter_registry import FILTER_REGISTRY
18
+
19
+
20
+ class InstructionFilter:
21
+ def __init__(self, filters_config: Dict[str, Dict[str, Any]]):
22
+ r"""Initialize the InstructionFilter with a dictionary of filter
23
+ configurations.
24
+
25
+ Args:
26
+ filters_config(Dict[str, Dict[str, Any]]):
27
+ Example filters_config:
28
+ {
29
+ "length": {"min_len": 5, "max_len": 100},
30
+ "keyword": {"keywords": ["image", "video"]},
31
+ "non_english": {},
32
+ "rouge_similarity": {
33
+ "existing_instructions": ["Some existing text"],
34
+ "threshold": 0.6
35
+ }
36
+ }
37
+ Each key in filters_config corresponds to a filter name
38
+ (registered in FILTER_REGISTRY).
39
+ Each value is a dict of parameters for that filter.
40
+ """
41
+ self.filters: List[FilterFunction] = []
42
+ for filter_name, params in filters_config.items():
43
+ if filter_name not in FILTER_REGISTRY:
44
+ raise ValueError(f"Unknown filter function: {filter_name}")
45
+ self.filters.append(FILTER_REGISTRY[filter_name](params))
46
+
47
+ def add_filter(self, filter_function: FilterFunction):
48
+ r"""Add a custom filter function to the InstructionFilter.
49
+ This allows adding filters that are not in the registry.
50
+
51
+ Args:
52
+ filter_function (FilterFunction): The filter function to be added
53
+ """
54
+ self.filters.append(filter_function)
55
+
56
+ def filter(
57
+ self, prompt: str, instruction: str, return_details: bool = False
58
+ ):
59
+ r"""Check if the given instruction passes all filter functions.
60
+
61
+ Args:
62
+ prompt (str): The prompt of generating the instruction.
63
+ instruction (str): The instruction to evaluate.
64
+ return_details (bool): If True, returns a tuple (bool, List[str])
65
+ where the list contains the names of filters that failed.
66
+ (default::obj:`False`)
67
+
68
+ Returns:
69
+ bool: True if the instruction passes all filters, False otherwise.
70
+ OR (bool, List[str]) if return_details is True.
71
+ """
72
+ failed_filters = []
73
+ for f in self.filters:
74
+ if isinstance(f, RewardModelFilter):
75
+ f.prompt = prompt
76
+ if not f.apply(instruction):
77
+ failed_filters.append(type(f).__name__)
78
+
79
+ if return_details:
80
+ return len(failed_filters) == 0, failed_filters
81
+ return len(failed_filters) == 0