camel-ai 0.2.38__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.
- camel/__init__.py +1 -1
- camel/agents/chat_agent.py +4 -0
- camel/agents/repo_agent.py +2 -2
- camel/benchmarks/apibank.py +1 -1
- camel/benchmarks/apibench.py +1 -1
- camel/configs/__init__.py +3 -0
- camel/configs/modelscope_config.py +59 -0
- camel/datagen/self_improving_cot.py +1 -1
- camel/datasets/__init__.py +2 -0
- camel/datasets/base_generator.py +22 -9
- camel/datasets/few_shot_generator.py +2 -3
- camel/datasets/self_instruct_generator.py +415 -0
- camel/embeddings/openai_compatible_embedding.py +13 -5
- camel/environments/models.py +1 -1
- camel/environments/single_step.py +155 -89
- camel/interpreters/docker_interpreter.py +1 -1
- camel/interpreters/internal_python_interpreter.py +1 -1
- camel/loaders/unstructured_io.py +2 -1
- camel/memories/blocks/chat_history_block.py +1 -1
- camel/memories/context_creators/score_based.py +2 -2
- camel/models/__init__.py +2 -0
- camel/models/model_factory.py +119 -0
- camel/models/modelscope_model.py +208 -0
- camel/models/openai_audio_models.py +2 -2
- camel/models/openai_model.py +49 -2
- camel/models/togetherai_model.py +2 -2
- camel/models/vllm_model.py +1 -1
- camel/models/zhipuai_model.py +2 -2
- camel/retrievers/vector_retriever.py +1 -1
- camel/storages/graph_storages/neo4j_graph.py +1 -1
- camel/storages/vectordb_storages/base.py +2 -2
- camel/storages/vectordb_storages/milvus.py +2 -2
- camel/storages/vectordb_storages/qdrant.py +2 -2
- camel/tasks/task.py +2 -2
- camel/toolkits/__init__.py +4 -1
- camel/toolkits/arxiv_toolkit.py +2 -1
- camel/toolkits/ask_news_toolkit.py +11 -3
- camel/toolkits/audio_analysis_toolkit.py +2 -0
- camel/toolkits/base.py +3 -0
- camel/toolkits/code_execution.py +3 -1
- camel/toolkits/dappier_toolkit.py +2 -1
- camel/toolkits/data_commons_toolkit.py +2 -0
- camel/toolkits/excel_toolkit.py +2 -0
- camel/toolkits/file_write_toolkit.py +2 -0
- camel/toolkits/github_toolkit.py +6 -4
- camel/toolkits/google_scholar_toolkit.py +2 -0
- camel/toolkits/human_toolkit.py +17 -1
- camel/toolkits/image_analysis_toolkit.py +2 -0
- camel/toolkits/linkedin_toolkit.py +2 -1
- camel/toolkits/math_toolkit.py +2 -0
- camel/toolkits/mcp_toolkit.py +42 -52
- camel/toolkits/meshy_toolkit.py +20 -2
- camel/toolkits/networkx_toolkit.py +2 -0
- camel/toolkits/notion_toolkit.py +7 -0
- camel/toolkits/openbb_toolkit.py +2 -1
- camel/toolkits/pubmed_toolkit.py +2 -0
- camel/toolkits/reddit_toolkit.py +2 -1
- camel/toolkits/retrieval_toolkit.py +2 -1
- camel/toolkits/search_toolkit.py +2 -1
- camel/toolkits/semantic_scholar_toolkit.py +2 -0
- camel/toolkits/slack_toolkit.py +2 -0
- camel/toolkits/stripe_toolkit.py +2 -1
- camel/toolkits/sympy_toolkit.py +2 -0
- camel/toolkits/terminal_toolkit.py +2 -0
- camel/toolkits/twitter_toolkit.py +2 -1
- camel/toolkits/video_analysis_toolkit.py +2 -1
- camel/toolkits/video_download_toolkit.py +2 -1
- camel/toolkits/weather_toolkit.py +2 -0
- camel/toolkits/whatsapp_toolkit.py +2 -1
- camel/toolkits/zapier_toolkit.py +2 -1
- camel/types/enums.py +65 -0
- camel/types/unified_model_type.py +5 -0
- camel/utils/__init__.py +2 -0
- camel/utils/chunker/code_chunker.py +9 -9
- camel/utils/commons.py +50 -30
- camel/utils/constants.py +2 -2
- camel/utils/mcp.py +79 -0
- camel/verifiers/__init__.py +2 -0
- camel/verifiers/base.py +15 -15
- camel/verifiers/math_verifier.py +182 -0
- camel/verifiers/python_verifier.py +18 -26
- {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/METADATA +3 -1
- {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/RECORD +85 -80
- {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
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
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
from camel.extractors.base import BaseExtractor
|
|
18
|
+
from camel.logger import get_logger
|
|
19
|
+
from camel.verifiers import BaseVerifier
|
|
20
|
+
from camel.verifiers.models import VerificationOutcome, VerificationResult
|
|
21
|
+
|
|
22
|
+
logger = get_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MathVerifier(BaseVerifier):
|
|
26
|
+
r"""Verifier for mathematical expressions using Math-Verify.
|
|
27
|
+
|
|
28
|
+
Features:
|
|
29
|
+
- Supports LaTeX and plain mathematical expressions
|
|
30
|
+
- Handles complex numbers, matrices, and sets
|
|
31
|
+
- Configurable precision for floating-point comparisons
|
|
32
|
+
- Optional LaTeX wrapping to ensure proper parsing and rendering
|
|
33
|
+
- Comprehensive error handling and logging
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
extractor: Optional[BaseExtractor] = None,
|
|
39
|
+
timeout: Optional[float] = 30.0,
|
|
40
|
+
float_rounding: int = 6,
|
|
41
|
+
numeric_precision: int = 15,
|
|
42
|
+
enable_wrapping: Optional[bool] = False,
|
|
43
|
+
**kwargs,
|
|
44
|
+
):
|
|
45
|
+
r"""Initializes the MathVerifier.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
extractor (Optional[BaseExtractor], optional): The extractor to use
|
|
49
|
+
for extracting code from the solution. (default: :obj:`None`)
|
|
50
|
+
timeout (Optional[float], optional): The execution timeout in
|
|
51
|
+
seconds. (default: :obj:`30.0`)
|
|
52
|
+
float_rounding (int, optional): The number of decimal places to
|
|
53
|
+
round floating-point numbers. (default: :obj:`6`)
|
|
54
|
+
numeric_precision (int, optional): The numeric precision for
|
|
55
|
+
floating-point comparisons. (default: :obj:`15`)
|
|
56
|
+
enable_wrapping (Optional[bool], optional): Whether to wrap LaTeX
|
|
57
|
+
expressions in math mode delimiters. (default: :obj:`False`)
|
|
58
|
+
"""
|
|
59
|
+
super().__init__(extractor=extractor, timeout=timeout, **kwargs)
|
|
60
|
+
self.float_rounding = float_rounding
|
|
61
|
+
self.numeric_precision = numeric_precision
|
|
62
|
+
self.enable_wrapping = enable_wrapping
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _latex_wrapping(s: str) -> str:
|
|
66
|
+
r"""Wrap a LaTeX expression in math mode delimiters.
|
|
67
|
+
|
|
68
|
+
This function checks whether the input string is already in a LaTeX
|
|
69
|
+
math environment (e.g., $, \[, \begin{}, etc.). If not, it wraps the
|
|
70
|
+
expression in $$...$$ to ensure proper parsing and rendering as a
|
|
71
|
+
mathematical expression.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
s (str): The input LaTeX string.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
str: The LaTeX string wrapped in math mode if necessary.
|
|
78
|
+
"""
|
|
79
|
+
s_stripped = s.strip()
|
|
80
|
+
if (
|
|
81
|
+
not any(
|
|
82
|
+
s_stripped.startswith(prefix)
|
|
83
|
+
for prefix in ("$", "\\(", "\\[", "\\begin")
|
|
84
|
+
)
|
|
85
|
+
and "\\boxed" not in s_stripped
|
|
86
|
+
):
|
|
87
|
+
s = f"$$ {s_stripped} $$"
|
|
88
|
+
return s
|
|
89
|
+
|
|
90
|
+
async def _setup(self, **kwargs) -> None:
|
|
91
|
+
r"""No special setup needed for math verification."""
|
|
92
|
+
pass
|
|
93
|
+
|
|
94
|
+
async def _cleanup(self) -> None:
|
|
95
|
+
r"""No cleanup needed for math verification."""
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
async def _verify_implementation(
|
|
99
|
+
self, solution: str, reference_answer: Optional[str]
|
|
100
|
+
) -> VerificationResult:
|
|
101
|
+
r"""Verify mathematical expressions using Math-Verify.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
solution: The solution to verify
|
|
105
|
+
reference_answer: The expected answer to compare against
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
VerificationResult containing the verification status and details
|
|
109
|
+
"""
|
|
110
|
+
from math_verify import parse, verify
|
|
111
|
+
from math_verify.parser import (
|
|
112
|
+
ExprExtractionConfig,
|
|
113
|
+
LatexExtractionConfig,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if reference_answer is None:
|
|
117
|
+
return VerificationResult(
|
|
118
|
+
status=VerificationOutcome.ERROR,
|
|
119
|
+
result="",
|
|
120
|
+
error_message=(
|
|
121
|
+
"Ground truth is required for " "mathematical verification"
|
|
122
|
+
),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
# Apply LaTeX wrapping if enabled
|
|
127
|
+
if self.enable_wrapping:
|
|
128
|
+
solution = self._latex_wrapping(solution)
|
|
129
|
+
reference_answer = self._latex_wrapping(reference_answer)
|
|
130
|
+
logger.debug("Applied LaTeX wrapping")
|
|
131
|
+
|
|
132
|
+
# Parse both expressions with LaTeX and plain expression support
|
|
133
|
+
parsed_reference_answer = parse(
|
|
134
|
+
reference_answer,
|
|
135
|
+
extraction_config=[
|
|
136
|
+
LatexExtractionConfig(boxed_match_priority=0),
|
|
137
|
+
ExprExtractionConfig(),
|
|
138
|
+
],
|
|
139
|
+
)
|
|
140
|
+
parsed_solution = parse(
|
|
141
|
+
solution,
|
|
142
|
+
extraction_config=[
|
|
143
|
+
LatexExtractionConfig(),
|
|
144
|
+
ExprExtractionConfig(),
|
|
145
|
+
],
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if not parsed_reference_answer or not parsed_solution:
|
|
149
|
+
return VerificationResult(
|
|
150
|
+
status=VerificationOutcome.ERROR,
|
|
151
|
+
result="",
|
|
152
|
+
error_message="Failed to parse expressions",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Order matters! reference_answer must be first argument
|
|
156
|
+
is_correct = verify(
|
|
157
|
+
parsed_reference_answer,
|
|
158
|
+
parsed_solution,
|
|
159
|
+
float_rounding=self.float_rounding,
|
|
160
|
+
numeric_precision=self.numeric_precision,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
if is_correct:
|
|
164
|
+
logger.debug("Mathematical verification succeeded")
|
|
165
|
+
return VerificationResult(
|
|
166
|
+
status=VerificationOutcome.SUCCESS, result=solution
|
|
167
|
+
)
|
|
168
|
+
else:
|
|
169
|
+
logger.debug("Mathematical verification failed")
|
|
170
|
+
return VerificationResult(
|
|
171
|
+
status=VerificationOutcome.FAILURE,
|
|
172
|
+
result=solution,
|
|
173
|
+
error_message="Solution does not match ground truth",
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
except Exception as error:
|
|
177
|
+
logger.error(f"Mathematical verification error: {error!s}")
|
|
178
|
+
return VerificationResult(
|
|
179
|
+
status=VerificationOutcome.ERROR,
|
|
180
|
+
result="",
|
|
181
|
+
error_message=f"Mathematical verification error: {error!s}",
|
|
182
|
+
)
|
|
@@ -76,15 +76,19 @@ class PythonVerifier(BaseVerifier):
|
|
|
76
76
|
|
|
77
77
|
async def _setup(self, **kwargs) -> None:
|
|
78
78
|
r"""Set up a virtual environment and install required packages."""
|
|
79
|
-
|
|
80
|
-
if uv
|
|
79
|
+
# Check if we're in a uv environment and use uv if available
|
|
80
|
+
if kwargs.get("uv", False) or self._is_uv_environment():
|
|
81
81
|
logger.info("[UV] Detected uv environment. Using uv for setup.")
|
|
82
82
|
self._setup_with_uv()
|
|
83
83
|
return
|
|
84
84
|
|
|
85
85
|
self.venv_path = tempfile.mkdtemp()
|
|
86
86
|
try:
|
|
87
|
-
|
|
87
|
+
# Use system=True to ensure that the virtual environment uses the
|
|
88
|
+
# system Python libraries
|
|
89
|
+
venv.create(
|
|
90
|
+
self.venv_path, with_pip=True, system_site_packages=True
|
|
91
|
+
)
|
|
88
92
|
logger.info(f"Virtual environment created at {self.venv_path}")
|
|
89
93
|
except Exception as e:
|
|
90
94
|
logger.error(f"Failed to create virtual environment: {e}")
|
|
@@ -138,7 +142,7 @@ class PythonVerifier(BaseVerifier):
|
|
|
138
142
|
self.venv_path = tempfile.mkdtemp()
|
|
139
143
|
try:
|
|
140
144
|
subprocess.run(
|
|
141
|
-
["uv", "venv", self.venv_path],
|
|
145
|
+
["uv", "venv", "--python", sys.executable, self.venv_path],
|
|
142
146
|
check=True,
|
|
143
147
|
capture_output=True,
|
|
144
148
|
timeout=self._timeout,
|
|
@@ -218,7 +222,7 @@ class PythonVerifier(BaseVerifier):
|
|
|
218
222
|
self.venv_path = None
|
|
219
223
|
|
|
220
224
|
async def _verify_implementation(
|
|
221
|
-
self, solution: str,
|
|
225
|
+
self, solution: str, reference_answer: Optional[str]
|
|
222
226
|
) -> VerificationResult:
|
|
223
227
|
r"""Executes the provided Python solution in an isolated environment
|
|
224
228
|
and verifies its output against an expected ground truth expression.
|
|
@@ -234,7 +238,7 @@ class PythonVerifier(BaseVerifier):
|
|
|
234
238
|
Args:
|
|
235
239
|
solution (str): The Python code or expression to execute and
|
|
236
240
|
verify.
|
|
237
|
-
|
|
241
|
+
reference_answer (Optional[str]): The expected value as a Python
|
|
238
242
|
expression. If None, only execution success is verified.
|
|
239
243
|
|
|
240
244
|
Returns:
|
|
@@ -259,9 +263,9 @@ class PythonVerifier(BaseVerifier):
|
|
|
259
263
|
error_message=f"Expression evaluation error: {e}",
|
|
260
264
|
)
|
|
261
265
|
|
|
262
|
-
if
|
|
266
|
+
if reference_answer is not None:
|
|
263
267
|
try:
|
|
264
|
-
gt_val = ast.literal_eval(
|
|
268
|
+
gt_val = ast.literal_eval(reference_answer)
|
|
265
269
|
except Exception as e:
|
|
266
270
|
return VerificationResult(
|
|
267
271
|
status=VerificationOutcome.ERROR,
|
|
@@ -311,29 +315,17 @@ class PythonVerifier(BaseVerifier):
|
|
|
311
315
|
error_message=f"Solution code error:\n{sol_err}",
|
|
312
316
|
)
|
|
313
317
|
|
|
314
|
-
if
|
|
318
|
+
if reference_answer is not None:
|
|
315
319
|
try:
|
|
316
320
|
# First, try to evaluate the output as-is.
|
|
317
321
|
sol_val = ast.literal_eval(sol_out)
|
|
318
322
|
except Exception as e:
|
|
319
|
-
logger.warning(
|
|
320
|
-
|
|
321
|
-
)
|
|
322
|
-
try:
|
|
323
|
-
# Try to convert sol_out to a literal
|
|
324
|
-
# by wrapping it with repr.
|
|
325
|
-
# FIXME: may be unnecessary
|
|
326
|
-
sol_val = ast.literal_eval(repr(sol_out))
|
|
327
|
-
except Exception as e2:
|
|
328
|
-
logger.warning(
|
|
329
|
-
f"repr eval also failed: {e2}."
|
|
330
|
-
"Falling back to string comparison."
|
|
331
|
-
)
|
|
332
|
-
sol_val = None
|
|
323
|
+
logger.warning(f"Direct eval failed: {e}.")
|
|
324
|
+
sol_val = None
|
|
333
325
|
|
|
334
326
|
if sol_val is not None:
|
|
335
327
|
try:
|
|
336
|
-
gt_val = ast.literal_eval(
|
|
328
|
+
gt_val = ast.literal_eval(reference_answer)
|
|
337
329
|
except Exception as e:
|
|
338
330
|
return VerificationResult(
|
|
339
331
|
status=VerificationOutcome.ERROR,
|
|
@@ -355,7 +347,7 @@ class PythonVerifier(BaseVerifier):
|
|
|
355
347
|
)
|
|
356
348
|
else:
|
|
357
349
|
# Fallback: string comparison
|
|
358
|
-
if sol_out.strip() ==
|
|
350
|
+
if sol_out.strip() == reference_answer.strip():
|
|
359
351
|
return VerificationResult(
|
|
360
352
|
status=VerificationOutcome.SUCCESS,
|
|
361
353
|
result=sol_out,
|
|
@@ -365,7 +357,7 @@ class PythonVerifier(BaseVerifier):
|
|
|
365
357
|
status=VerificationOutcome.FAILURE,
|
|
366
358
|
result=sol_out,
|
|
367
359
|
error_message="Fallback string mismatch: "
|
|
368
|
-
f"'{sol_out}' != '{
|
|
360
|
+
f"'{sol_out}' != '{reference_answer}'",
|
|
369
361
|
)
|
|
370
362
|
else:
|
|
371
363
|
return VerificationResult(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: camel-ai
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.39
|
|
4
4
|
Summary: Communicative Agents for AI Society Study
|
|
5
5
|
Project-URL: Homepage, https://www.camel-ai.org/
|
|
6
6
|
Project-URL: Repository, https://github.com/camel-ai/camel
|
|
@@ -55,6 +55,7 @@ Requires-Dist: ipykernel<7,>=6.0.0; extra == 'all'
|
|
|
55
55
|
Requires-Dist: jupyter-client<9,>=8.6.2; extra == 'all'
|
|
56
56
|
Requires-Dist: linkup-sdk<0.3,>=0.2.1; extra == 'all'
|
|
57
57
|
Requires-Dist: litellm<2,>=1.38.1; extra == 'all'
|
|
58
|
+
Requires-Dist: math-verify<0.8,>=0.7.0; extra == 'all'
|
|
58
59
|
Requires-Dist: mcp>=1.3.0; extra == 'all'
|
|
59
60
|
Requires-Dist: mem0ai>=0.1.67; extra == 'all'
|
|
60
61
|
Requires-Dist: mistralai<2,>=1.1.0; extra == 'all'
|
|
@@ -133,6 +134,7 @@ Provides-Extra: data-tools
|
|
|
133
134
|
Requires-Dist: aiosqlite<0.21,>=0.20.0; extra == 'data-tools'
|
|
134
135
|
Requires-Dist: datacommons-pandas<0.0.4,>=0.0.3; extra == 'data-tools'
|
|
135
136
|
Requires-Dist: datacommons<2,>=1.4.3; extra == 'data-tools'
|
|
137
|
+
Requires-Dist: math-verify<0.8,>=0.7.0; extra == 'data-tools'
|
|
136
138
|
Requires-Dist: networkx<4,>=3.4.2; extra == 'data-tools'
|
|
137
139
|
Requires-Dist: numpy~=1.26; extra == 'data-tools'
|
|
138
140
|
Requires-Dist: pandas<2,>=1.5.3; extra == 'data-tools'
|