camel-ai 0.2.69a4__py3-none-any.whl → 0.2.69a7__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 +220 -7
- camel/interpreters/internal_python_interpreter.py +51 -2
- camel/memories/context_creators/score_based.py +11 -6
- camel/messages/base.py +2 -2
- camel/models/base_model.py +91 -2
- camel/societies/workforce/workforce.py +214 -22
- camel/storages/__init__.py +2 -0
- camel/storages/vectordb_storages/__init__.py +2 -0
- camel/storages/vectordb_storages/chroma.py +731 -0
- camel/tasks/task.py +30 -2
- camel/toolkits/__init__.py +8 -1
- camel/toolkits/craw4ai_toolkit.py +73 -0
- camel/toolkits/edgeone_pages_mcp_toolkit.py +69 -0
- camel/toolkits/excel_toolkit.py +814 -69
- camel/toolkits/google_drive_mcp_toolkit.py +73 -0
- camel/toolkits/markitdown_toolkit.py +78 -0
- camel/toolkits/mcp_toolkit.py +31 -1
- camel/toolkits/non_visual_browser_toolkit/browser_non_visual_toolkit.py +91 -57
- camel/types/enums.py +6 -6
- {camel_ai-0.2.69a4.dist-info → camel_ai-0.2.69a7.dist-info}/METADATA +5 -6
- {camel_ai-0.2.69a4.dist-info → camel_ai-0.2.69a7.dist-info}/RECORD +24 -19
- {camel_ai-0.2.69a4.dist-info → camel_ai-0.2.69a7.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.69a4.dist-info → camel_ai-0.2.69a7.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
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 List, Optional
|
|
16
|
+
|
|
17
|
+
from camel.toolkits import BaseToolkit, FunctionTool
|
|
18
|
+
|
|
19
|
+
from .mcp_toolkit import MCPToolkit
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class GoogleDriveMCPToolkit(BaseToolkit):
|
|
23
|
+
r"""GoogleDriveMCPToolkit provides an interface for interacting with
|
|
24
|
+
Google Drive using the Google Drive MCP server.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
timeout (Optional[float]): Connection timeout in seconds.
|
|
28
|
+
(default: :obj:`None`)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
timeout: Optional[float] = None,
|
|
34
|
+
credentials_path: Optional[str] = None,
|
|
35
|
+
) -> None:
|
|
36
|
+
r"""Initializes the GoogleDriveMCPToolkit.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
timeout (Optional[float]): Connection timeout in seconds.
|
|
40
|
+
(default: :obj:`None`)
|
|
41
|
+
credentials_path (Optional[str]): Path to the Google Drive
|
|
42
|
+
credentials file. (default: :obj:`None`)
|
|
43
|
+
"""
|
|
44
|
+
super().__init__(timeout=timeout)
|
|
45
|
+
|
|
46
|
+
self._mcp_toolkit = MCPToolkit(
|
|
47
|
+
config_dict={
|
|
48
|
+
"mcpServers": {
|
|
49
|
+
"gdrive": {
|
|
50
|
+
"command": "npx",
|
|
51
|
+
"args": ["-y", "@modelcontextprotocol/server-gdrive"],
|
|
52
|
+
"env": {"GDRIVE_CREDENTIALS_PATH": credentials_path},
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
timeout=timeout,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
async def connect(self):
|
|
60
|
+
r"""Explicitly connect to the Google Drive MCP server."""
|
|
61
|
+
await self._mcp_toolkit.connect()
|
|
62
|
+
|
|
63
|
+
async def disconnect(self):
|
|
64
|
+
r"""Explicitly disconnect from the Google Drive MCP server."""
|
|
65
|
+
await self._mcp_toolkit.disconnect()
|
|
66
|
+
|
|
67
|
+
def get_tools(self) -> List[FunctionTool]:
|
|
68
|
+
r"""Returns a list of tools provided by the GoogleDriveMCPToolkit.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
List[FunctionTool]: List of available tools.
|
|
72
|
+
"""
|
|
73
|
+
return self._mcp_toolkit.get_tools()
|
|
@@ -0,0 +1,78 @@
|
|
|
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 Dict, List, Optional
|
|
16
|
+
|
|
17
|
+
from camel.loaders.markitdown import MarkItDownLoader
|
|
18
|
+
from camel.logger import get_logger
|
|
19
|
+
from camel.toolkits.base import BaseToolkit
|
|
20
|
+
from camel.toolkits.function_tool import FunctionTool
|
|
21
|
+
from camel.utils import MCPServer
|
|
22
|
+
|
|
23
|
+
logger = get_logger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@MCPServer()
|
|
27
|
+
class MarkItDownToolkit(BaseToolkit):
|
|
28
|
+
r"""A class representing a toolkit for MarkItDown."""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
timeout: Optional[float] = None,
|
|
33
|
+
):
|
|
34
|
+
super().__init__(timeout=timeout)
|
|
35
|
+
|
|
36
|
+
def load_files(self, file_paths: List[str]) -> Dict[str, str]:
|
|
37
|
+
r"""Scrapes content from a list of files and converts it to Markdown.
|
|
38
|
+
|
|
39
|
+
This function takes a list of local file paths, attempts to convert
|
|
40
|
+
each file into Markdown format, and returns the converted content.
|
|
41
|
+
The conversion is performed in parallel for efficiency.
|
|
42
|
+
|
|
43
|
+
Supported file formats include:
|
|
44
|
+
- PDF (.pdf)
|
|
45
|
+
- Microsoft Office: Word (.doc, .docx), Excel (.xls, .xlsx),
|
|
46
|
+
PowerPoint (.ppt, .pptx)
|
|
47
|
+
- EPUB (.epub)
|
|
48
|
+
- HTML (.html, .htm)
|
|
49
|
+
- Images (.jpg, .jpeg, .png) for OCR
|
|
50
|
+
- Audio (.mp3, .wav) for transcription
|
|
51
|
+
- Text-based formats (.csv, .json, .xml, .txt)
|
|
52
|
+
- ZIP archives (.zip)
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
file_paths (List[str]): A list of local file paths to be
|
|
56
|
+
converted.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Dict[str, str]: A dictionary where keys are the input file paths
|
|
60
|
+
and values are the corresponding content in Markdown format.
|
|
61
|
+
If conversion of a file fails, the value will contain an
|
|
62
|
+
error message.
|
|
63
|
+
"""
|
|
64
|
+
return MarkItDownLoader().convert_files(
|
|
65
|
+
file_paths=file_paths, parallel=True
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def get_tools(self) -> List[FunctionTool]:
|
|
69
|
+
r"""Returns a list of FunctionTool objects representing the
|
|
70
|
+
functions in the toolkit.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
List[FunctionTool]: A list of FunctionTool objects
|
|
74
|
+
representing the functions in the toolkit.
|
|
75
|
+
"""
|
|
76
|
+
return [
|
|
77
|
+
FunctionTool(self.load_files),
|
|
78
|
+
]
|
camel/toolkits/mcp_toolkit.py
CHANGED
|
@@ -457,7 +457,37 @@ class MCPToolkit(BaseToolkit):
|
|
|
457
457
|
try:
|
|
458
458
|
schema = tool.get_openai_tool_schema()
|
|
459
459
|
|
|
460
|
-
# Check if the
|
|
460
|
+
# Check if any object in the schema has additionalProperties: true
|
|
461
|
+
def _has_additional_properties_true(obj):
|
|
462
|
+
r"""Recursively check if any object has additionalProperties: true""" # noqa: E501
|
|
463
|
+
if isinstance(obj, dict):
|
|
464
|
+
if obj.get("additionalProperties") is True:
|
|
465
|
+
return True
|
|
466
|
+
for value in obj.values():
|
|
467
|
+
if _has_additional_properties_true(value):
|
|
468
|
+
return True
|
|
469
|
+
elif isinstance(obj, list):
|
|
470
|
+
for item in obj:
|
|
471
|
+
if _has_additional_properties_true(item):
|
|
472
|
+
return True
|
|
473
|
+
return False
|
|
474
|
+
|
|
475
|
+
# FIRST: Check if the schema contains additionalProperties: true
|
|
476
|
+
# This must be checked before strict mode validation
|
|
477
|
+
if _has_additional_properties_true(schema):
|
|
478
|
+
# Force strict mode to False and log warning
|
|
479
|
+
if "function" in schema:
|
|
480
|
+
schema["function"]["strict"] = False
|
|
481
|
+
tool.set_openai_tool_schema(schema)
|
|
482
|
+
logger.warning(
|
|
483
|
+
f"Tool '{tool.get_function_name()}' contains "
|
|
484
|
+
f"additionalProperties: true which is incompatible with "
|
|
485
|
+
f"OpenAI strict mode. Setting strict=False for this tool."
|
|
486
|
+
)
|
|
487
|
+
return tool
|
|
488
|
+
|
|
489
|
+
# SECOND: Check if the tool already has strict mode enabled
|
|
490
|
+
# Only do this if there are no additionalProperties conflicts
|
|
461
491
|
if schema.get("function", {}).get("strict") is True:
|
|
462
492
|
return tool
|
|
463
493
|
|
|
@@ -115,16 +115,19 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
115
115
|
async def open_browser(
|
|
116
116
|
self, start_url: Optional[str] = None
|
|
117
117
|
) -> Dict[str, str]:
|
|
118
|
-
r"""
|
|
118
|
+
r"""Launches a new browser session. This should be the first step.
|
|
119
119
|
|
|
120
120
|
Args:
|
|
121
|
-
start_url (Optional[str]):
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
start_url (Optional[str]): The URL to navigate to after the browser
|
|
122
|
+
launches. If not provided, the browser will open with a blank
|
|
123
|
+
page. (default: :obj:`None`)
|
|
124
124
|
|
|
125
125
|
Returns:
|
|
126
|
-
Dict[str, str]:
|
|
127
|
-
|
|
126
|
+
Dict[str, str]: A dictionary containing the result of the action
|
|
127
|
+
and a snapshot of the page. The keys are "result" and
|
|
128
|
+
"snapshot". The "snapshot" is a YAML-like representation of
|
|
129
|
+
the page's DOM structure, including element references
|
|
130
|
+
(e.g., "e3") that can be used in other tool calls.
|
|
128
131
|
"""
|
|
129
132
|
await self._session.ensure_browser()
|
|
130
133
|
if start_url:
|
|
@@ -136,10 +139,12 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
136
139
|
return {"result": "Browser session started.", "snapshot": snapshot}
|
|
137
140
|
|
|
138
141
|
async def close_browser(self) -> str:
|
|
139
|
-
r"""
|
|
142
|
+
r"""Closes the current browser session, freeing up all associated
|
|
143
|
+
resources. This should be called when the browsing task is complete.
|
|
140
144
|
|
|
141
145
|
Returns:
|
|
142
|
-
str:
|
|
146
|
+
str: A confirmation message indicating the session has been
|
|
147
|
+
closed.
|
|
143
148
|
"""
|
|
144
149
|
# Close agent if it exists
|
|
145
150
|
if self._agent is not None:
|
|
@@ -154,14 +159,17 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
154
159
|
return "Browser session closed."
|
|
155
160
|
|
|
156
161
|
async def visit_page(self, url: str) -> Dict[str, str]:
|
|
157
|
-
r"""
|
|
162
|
+
r"""Navigates the current browser page to a new URL.
|
|
158
163
|
|
|
159
164
|
Args:
|
|
160
|
-
url (str): The
|
|
165
|
+
url (str): The URL to navigate to. Must be a fully qualified URL
|
|
166
|
+
(e.g., "https://www.google.com").
|
|
161
167
|
|
|
162
168
|
Returns:
|
|
163
|
-
Dict[str, str]:
|
|
164
|
-
|
|
169
|
+
Dict[str, str]: A dictionary containing the navigation result and a
|
|
170
|
+
snapshot of the new page. The keys are "result" and
|
|
171
|
+
"snapshot". The "snapshot" provides a fresh view of the
|
|
172
|
+
page's DOM structure.
|
|
165
173
|
"""
|
|
166
174
|
if not url or not isinstance(url, str):
|
|
167
175
|
raise ValueError("visit_page(): 'url' must be a non-empty string")
|
|
@@ -192,14 +200,16 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
192
200
|
)
|
|
193
201
|
|
|
194
202
|
async def click(self, *, ref: str) -> Dict[str, str]:
|
|
195
|
-
r"""
|
|
203
|
+
r"""Performs a click action on a specified element on the current page.
|
|
196
204
|
|
|
197
205
|
Args:
|
|
198
|
-
ref (str):
|
|
199
|
-
(e.g
|
|
206
|
+
ref (str): The reference ID of the element to click. This ID is
|
|
207
|
+
obtained from the page snapshot (e.g., "e12").
|
|
200
208
|
|
|
201
209
|
Returns:
|
|
202
|
-
Dict[str, str]:
|
|
210
|
+
Dict[str, str]: A dictionary containing the result of the action.
|
|
211
|
+
If the click causes a change in the page's structure, a
|
|
212
|
+
"snapshot" key will be included with a diff of the changes.
|
|
203
213
|
"""
|
|
204
214
|
self._validate_ref(ref, "click")
|
|
205
215
|
|
|
@@ -207,15 +217,16 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
207
217
|
return await self._exec_with_snapshot(action)
|
|
208
218
|
|
|
209
219
|
async def type(self, *, ref: str, text: str) -> Dict[str, str]:
|
|
210
|
-
r"""
|
|
220
|
+
r"""Types text into an input field or textarea on the current page.
|
|
211
221
|
|
|
212
222
|
Args:
|
|
213
|
-
ref (str):
|
|
214
|
-
(e.g
|
|
215
|
-
text (str): The text to
|
|
223
|
+
ref (str): The reference ID of the input element. This ID is
|
|
224
|
+
obtained from the page snapshot (e.g., "e25").
|
|
225
|
+
text (str): The text to be typed into the element.
|
|
216
226
|
|
|
217
227
|
Returns:
|
|
218
|
-
Dict[str, str]:
|
|
228
|
+
Dict[str, str]: A dictionary containing the result of the action.
|
|
229
|
+
The key is "result".
|
|
219
230
|
"""
|
|
220
231
|
self._validate_ref(ref, "type")
|
|
221
232
|
|
|
@@ -223,14 +234,17 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
223
234
|
return await self._exec_with_snapshot(action)
|
|
224
235
|
|
|
225
236
|
async def select(self, *, ref: str, value: str) -> Dict[str, str]:
|
|
226
|
-
r"""
|
|
237
|
+
r"""Selects an option from a dropdown (<select>) element on the page.
|
|
227
238
|
|
|
228
239
|
Args:
|
|
229
|
-
ref (str):
|
|
230
|
-
|
|
240
|
+
ref (str): The reference ID of the <select> element. This ID is
|
|
241
|
+
obtained from the page snapshot.
|
|
242
|
+
value (str): The value of the option to be selected. This should
|
|
243
|
+
match the 'value' attribute of an <option> tag.
|
|
231
244
|
|
|
232
245
|
Returns:
|
|
233
|
-
Dict[str, str]:
|
|
246
|
+
Dict[str, str]: A dictionary containing the result of the action.
|
|
247
|
+
The key is "result".
|
|
234
248
|
"""
|
|
235
249
|
self._validate_ref(ref, "select")
|
|
236
250
|
|
|
@@ -238,15 +252,16 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
238
252
|
return await self._exec_with_snapshot(action)
|
|
239
253
|
|
|
240
254
|
async def scroll(self, *, direction: str, amount: int) -> Dict[str, str]:
|
|
241
|
-
r"""
|
|
255
|
+
r"""Scrolls the current page up or down by a specified amount.
|
|
242
256
|
|
|
243
257
|
Args:
|
|
244
|
-
direction (str):
|
|
245
|
-
|
|
246
|
-
amount (int):
|
|
258
|
+
direction (str): The direction to scroll. Must be either "up" or
|
|
259
|
+
"down".
|
|
260
|
+
amount (int): The number of pixels to scroll.
|
|
247
261
|
|
|
248
262
|
Returns:
|
|
249
|
-
Dict[str, str]:
|
|
263
|
+
Dict[str, str]: A dictionary containing the result of the action.
|
|
264
|
+
The key is "result".
|
|
250
265
|
"""
|
|
251
266
|
if direction not in ("up", "down"):
|
|
252
267
|
logger.error("scroll(): 'direction' must be 'up' or 'down'")
|
|
@@ -258,53 +273,72 @@ class BrowserNonVisualToolkit(BaseToolkit):
|
|
|
258
273
|
return await self._exec_with_snapshot(action)
|
|
259
274
|
|
|
260
275
|
async def enter(self, *, ref: str) -> Dict[str, str]:
|
|
261
|
-
r"""
|
|
276
|
+
r"""Simulates pressing the Enter key on a specific element.
|
|
277
|
+
This is often used to submit forms.
|
|
262
278
|
|
|
263
279
|
Args:
|
|
264
|
-
ref (str):
|
|
280
|
+
ref (str): The reference ID of the element to focus before
|
|
281
|
+
pressing Enter. This ID is obtained from the page snapshot.
|
|
265
282
|
|
|
266
283
|
Returns:
|
|
267
|
-
Dict[str, str]:
|
|
284
|
+
Dict[str, str]: A dictionary containing the result of the action.
|
|
285
|
+
If pressing Enter causes a page navigation or DOM change, a
|
|
286
|
+
"snapshot" key will be included with a diff of the changes.
|
|
268
287
|
"""
|
|
269
288
|
self._validate_ref(ref, "enter")
|
|
270
289
|
|
|
271
290
|
action: Dict[str, Any] = {"type": "enter", "ref": ref}
|
|
272
291
|
return await self._exec_with_snapshot(action)
|
|
273
292
|
|
|
274
|
-
async def wait_user(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
293
|
+
async def wait_user(
|
|
294
|
+
self,
|
|
295
|
+
timeout_sec: Optional[float] = None,
|
|
296
|
+
) -> Dict[str, str]:
|
|
297
|
+
r"""Pauses the agent's execution and waits for human intervention.
|
|
298
|
+
This is useful for tasks that require manual steps, like solving a
|
|
299
|
+
CAPTCHA. The agent will print a message and wait for the user to
|
|
300
|
+
press the Enter key in the console.
|
|
281
301
|
|
|
282
302
|
Args:
|
|
283
|
-
|
|
284
|
-
|
|
303
|
+
timeout_sec (Optional[float]): The maximum time in seconds to wait
|
|
304
|
+
for the user. If `None`, it will wait indefinitely. Defaults
|
|
305
|
+
to `None`. (default: :obj:`None`)
|
|
285
306
|
|
|
286
307
|
Returns:
|
|
287
|
-
Dict[str, str]:
|
|
308
|
+
Dict[str, str]: A dictionary containing a result message and a
|
|
309
|
+
full snapshot of the current page after the user has acted.
|
|
310
|
+
The keys are "result" and "snapshot".
|
|
288
311
|
"""
|
|
289
|
-
if seconds is None or seconds <= 0:
|
|
290
|
-
logger.error("wait_time(): 'seconds' must be a positive number")
|
|
291
|
-
return {
|
|
292
|
-
"result": "wait_time(): 'seconds' must be a positive number"
|
|
293
|
-
}
|
|
294
312
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
313
|
+
import asyncio
|
|
314
|
+
|
|
315
|
+
prompt = (
|
|
316
|
+
"🕑 Agent is waiting for human input. "
|
|
317
|
+
"Complete the required action in the browser, then press Enter "
|
|
318
|
+
"to continue..."
|
|
319
|
+
)
|
|
299
320
|
|
|
300
|
-
|
|
301
|
-
|
|
321
|
+
logger.info(f"\n{prompt}\n")
|
|
322
|
+
|
|
323
|
+
async def _await_enter():
|
|
324
|
+
await asyncio.to_thread(input, ">>> Press Enter to resume <<<\n")
|
|
325
|
+
|
|
326
|
+
try:
|
|
327
|
+
if timeout_sec is not None:
|
|
328
|
+
await asyncio.wait_for(_await_enter(), timeout=timeout_sec)
|
|
329
|
+
result_msg = "User resumed."
|
|
330
|
+
else:
|
|
331
|
+
await _await_enter()
|
|
332
|
+
result_msg = "User resumed."
|
|
333
|
+
except asyncio.TimeoutError:
|
|
334
|
+
result_msg = f"Timeout {timeout_sec}s reached, auto-resumed."
|
|
302
335
|
|
|
303
|
-
# Always return a *full* snapshot after the pause
|
|
304
336
|
snapshot = await self._session.get_snapshot(
|
|
305
|
-
force_refresh=True,
|
|
337
|
+
force_refresh=True,
|
|
338
|
+
diff_only=False,
|
|
306
339
|
)
|
|
307
|
-
|
|
340
|
+
|
|
341
|
+
return {"result": result_msg, "snapshot": snapshot}
|
|
308
342
|
|
|
309
343
|
# Helper to run through ActionExecutor
|
|
310
344
|
async def _exec(self, action: Dict[str, Any]) -> str:
|
camel/types/enums.py
CHANGED
|
@@ -185,8 +185,8 @@ class ModelType(UnifiedModelType, Enum):
|
|
|
185
185
|
NVIDIA_LLAMA3_3_70B_INSTRUCT = "meta/llama-3.3-70b-instruct"
|
|
186
186
|
|
|
187
187
|
# Gemini models
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
GEMINI_2_5_FLASH = "gemini-2.5-flash"
|
|
189
|
+
GEMINI_2_5_PRO = "gemini-2.5-pro"
|
|
190
190
|
GEMINI_2_0_FLASH = "gemini-2.0-flash"
|
|
191
191
|
GEMINI_2_0_FLASH_EXP = "gemini-2.0-flash-exp"
|
|
192
192
|
GEMINI_2_0_FLASH_THINKING = "gemini-2.0-flash-thinking-exp"
|
|
@@ -674,8 +674,8 @@ class ModelType(UnifiedModelType, Enum):
|
|
|
674
674
|
bool: Whether this type of models is gemini.
|
|
675
675
|
"""
|
|
676
676
|
return self in {
|
|
677
|
-
ModelType.
|
|
678
|
-
ModelType.
|
|
677
|
+
ModelType.GEMINI_2_5_FLASH,
|
|
678
|
+
ModelType.GEMINI_2_5_PRO,
|
|
679
679
|
ModelType.GEMINI_2_0_FLASH,
|
|
680
680
|
ModelType.GEMINI_2_0_FLASH_EXP,
|
|
681
681
|
ModelType.GEMINI_2_0_FLASH_THINKING,
|
|
@@ -1278,8 +1278,8 @@ class ModelType(UnifiedModelType, Enum):
|
|
|
1278
1278
|
}:
|
|
1279
1279
|
return 512_000
|
|
1280
1280
|
elif self in {
|
|
1281
|
-
ModelType.
|
|
1282
|
-
ModelType.
|
|
1281
|
+
ModelType.GEMINI_2_5_FLASH,
|
|
1282
|
+
ModelType.GEMINI_2_5_PRO,
|
|
1283
1283
|
ModelType.GEMINI_2_0_FLASH,
|
|
1284
1284
|
ModelType.GEMINI_2_0_FLASH_EXP,
|
|
1285
1285
|
ModelType.GEMINI_2_0_FLASH_THINKING,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: camel-ai
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.69a7
|
|
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
|
|
@@ -31,6 +31,7 @@ Requires-Dist: arxiv<3,>=2.1.3; extra == 'all'
|
|
|
31
31
|
Requires-Dist: azure-storage-blob<13,>=12.21.0; extra == 'all'
|
|
32
32
|
Requires-Dist: beautifulsoup4<5,>=4; extra == 'all'
|
|
33
33
|
Requires-Dist: botocore<2,>=1.35.3; extra == 'all'
|
|
34
|
+
Requires-Dist: chromadb<1.0.0,>=0.6.0; extra == 'all'
|
|
34
35
|
Requires-Dist: chunkr-ai>=0.0.50; extra == 'all'
|
|
35
36
|
Requires-Dist: cohere<6,>=5.11.0; extra == 'all'
|
|
36
37
|
Requires-Dist: crawl4ai>=0.3.745; extra == 'all'
|
|
@@ -176,7 +177,7 @@ Requires-Dist: types-pyyaml<7,>=6.0.12; extra == 'dev'
|
|
|
176
177
|
Requires-Dist: types-requests<3,>=2.31.0; extra == 'dev'
|
|
177
178
|
Requires-Dist: types-setuptools<70,>=69.2.0; extra == 'dev'
|
|
178
179
|
Requires-Dist: types-tqdm<5,>=4.66.0; extra == 'dev'
|
|
179
|
-
Requires-Dist: uv
|
|
180
|
+
Requires-Dist: uv<0.8,>=0.7.0; extra == 'dev'
|
|
180
181
|
Provides-Extra: dev-tools
|
|
181
182
|
Requires-Dist: aci-sdk>=1.0.0b1; extra == 'dev-tools'
|
|
182
183
|
Requires-Dist: agentops<0.4,>=0.3.21; extra == 'dev-tools'
|
|
@@ -288,6 +289,7 @@ Requires-Dist: wikipedia<2,>=1; extra == 'owl'
|
|
|
288
289
|
Requires-Dist: xls2xlsx>=0.2.0; extra == 'owl'
|
|
289
290
|
Requires-Dist: yt-dlp<2025,>=2024.11.4; extra == 'owl'
|
|
290
291
|
Provides-Extra: rag
|
|
292
|
+
Requires-Dist: chromadb<1.0.0,>=0.6.0; extra == 'rag'
|
|
291
293
|
Requires-Dist: chunkr-ai>=0.0.50; extra == 'rag'
|
|
292
294
|
Requires-Dist: cohere<6,>=5.11.0; extra == 'rag'
|
|
293
295
|
Requires-Dist: crawl4ai>=0.3.745; extra == 'rag'
|
|
@@ -311,6 +313,7 @@ Requires-Dist: scholarly[tor]==1.7.11; extra == 'research-tools'
|
|
|
311
313
|
Provides-Extra: storage
|
|
312
314
|
Requires-Dist: azure-storage-blob<13,>=12.21.0; extra == 'storage'
|
|
313
315
|
Requires-Dist: botocore<2,>=1.35.3; extra == 'storage'
|
|
316
|
+
Requires-Dist: chromadb<1.0.0,>=0.6.0; extra == 'storage'
|
|
314
317
|
Requires-Dist: faiss-cpu<2,>=1.7.2; extra == 'storage'
|
|
315
318
|
Requires-Dist: google-cloud-storage<3,>=2.18.0; extra == 'storage'
|
|
316
319
|
Requires-Dist: mem0ai>=0.1.73; extra == 'storage'
|
|
@@ -322,10 +325,6 @@ Requires-Dist: pytidb-experimental==0.0.1.dev4; extra == 'storage'
|
|
|
322
325
|
Requires-Dist: qdrant-client<2,>=1.9.0; extra == 'storage'
|
|
323
326
|
Requires-Dist: redis<6,>=5.0.6; extra == 'storage'
|
|
324
327
|
Requires-Dist: weaviate-client>=4.15.0; extra == 'storage'
|
|
325
|
-
Provides-Extra: test
|
|
326
|
-
Requires-Dist: mock<6,>=5; extra == 'test'
|
|
327
|
-
Requires-Dist: pytest-asyncio<0.24,>=0.23.0; extra == 'test'
|
|
328
|
-
Requires-Dist: pytest<8,>=7; extra == 'test'
|
|
329
328
|
Provides-Extra: web-tools
|
|
330
329
|
Requires-Dist: apify-client<2,>=1.8.1; extra == 'web-tools'
|
|
331
330
|
Requires-Dist: beautifulsoup4<5,>=4; extra == 'web-tools'
|