camel-ai 0.2.73a4__py3-none-any.whl → 0.2.80a2__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.
- camel/__init__.py +1 -1
- camel/agents/_utils.py +38 -0
- camel/agents/chat_agent.py +2217 -519
- camel/agents/mcp_agent.py +30 -27
- camel/configs/__init__.py +15 -0
- camel/configs/aihubmix_config.py +88 -0
- camel/configs/amd_config.py +70 -0
- camel/configs/cometapi_config.py +104 -0
- camel/configs/minimax_config.py +93 -0
- camel/configs/nebius_config.py +103 -0
- camel/data_collectors/alpaca_collector.py +15 -6
- camel/datasets/base_generator.py +39 -10
- camel/environments/single_step.py +28 -3
- camel/environments/tic_tac_toe.py +1 -1
- camel/interpreters/__init__.py +2 -0
- camel/interpreters/docker/Dockerfile +3 -12
- camel/interpreters/e2b_interpreter.py +34 -1
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/loaders/__init__.py +11 -2
- camel/loaders/chunkr_reader.py +9 -0
- camel/memories/agent_memories.py +48 -4
- camel/memories/base.py +26 -0
- camel/memories/blocks/chat_history_block.py +122 -4
- camel/memories/context_creators/score_based.py +25 -384
- camel/memories/records.py +88 -8
- camel/messages/base.py +153 -34
- camel/models/__init__.py +10 -0
- camel/models/aihubmix_model.py +83 -0
- camel/models/aiml_model.py +1 -16
- camel/models/amd_model.py +101 -0
- camel/models/anthropic_model.py +6 -19
- camel/models/aws_bedrock_model.py +2 -33
- camel/models/azure_openai_model.py +114 -89
- camel/models/base_audio_model.py +3 -1
- camel/models/base_model.py +32 -14
- camel/models/cohere_model.py +1 -16
- camel/models/cometapi_model.py +83 -0
- camel/models/crynux_model.py +1 -16
- camel/models/deepseek_model.py +1 -16
- camel/models/fish_audio_model.py +6 -0
- camel/models/gemini_model.py +36 -18
- camel/models/groq_model.py +1 -17
- camel/models/internlm_model.py +1 -16
- camel/models/litellm_model.py +1 -16
- camel/models/lmstudio_model.py +1 -17
- camel/models/minimax_model.py +83 -0
- camel/models/mistral_model.py +1 -16
- camel/models/model_factory.py +27 -1
- camel/models/modelscope_model.py +1 -16
- camel/models/moonshot_model.py +105 -24
- camel/models/nebius_model.py +83 -0
- camel/models/nemotron_model.py +0 -5
- camel/models/netmind_model.py +1 -16
- camel/models/novita_model.py +1 -16
- camel/models/nvidia_model.py +1 -16
- camel/models/ollama_model.py +4 -19
- camel/models/openai_compatible_model.py +62 -41
- camel/models/openai_model.py +62 -57
- camel/models/openrouter_model.py +1 -17
- camel/models/ppio_model.py +1 -16
- camel/models/qianfan_model.py +1 -16
- camel/models/qwen_model.py +1 -16
- camel/models/reka_model.py +1 -16
- camel/models/samba_model.py +34 -47
- camel/models/sglang_model.py +64 -31
- camel/models/siliconflow_model.py +1 -16
- camel/models/stub_model.py +0 -4
- camel/models/togetherai_model.py +1 -16
- camel/models/vllm_model.py +1 -16
- camel/models/volcano_model.py +0 -17
- camel/models/watsonx_model.py +1 -16
- camel/models/yi_model.py +1 -16
- camel/models/zhipuai_model.py +60 -16
- camel/parsers/__init__.py +18 -0
- camel/parsers/mcp_tool_call_parser.py +176 -0
- camel/retrievers/auto_retriever.py +1 -0
- camel/runtimes/daytona_runtime.py +11 -12
- camel/societies/__init__.py +2 -0
- camel/societies/workforce/__init__.py +2 -0
- camel/societies/workforce/events.py +122 -0
- camel/societies/workforce/prompts.py +146 -66
- camel/societies/workforce/role_playing_worker.py +15 -11
- camel/societies/workforce/single_agent_worker.py +302 -65
- camel/societies/workforce/structured_output_handler.py +30 -18
- camel/societies/workforce/task_channel.py +163 -27
- camel/societies/workforce/utils.py +107 -13
- camel/societies/workforce/workflow_memory_manager.py +772 -0
- camel/societies/workforce/workforce.py +1949 -579
- camel/societies/workforce/workforce_callback.py +74 -0
- camel/societies/workforce/workforce_logger.py +168 -145
- camel/societies/workforce/workforce_metrics.py +33 -0
- camel/storages/key_value_storages/json.py +15 -2
- camel/storages/key_value_storages/mem0_cloud.py +48 -47
- camel/storages/object_storages/google_cloud.py +1 -1
- camel/storages/vectordb_storages/oceanbase.py +13 -13
- camel/storages/vectordb_storages/qdrant.py +3 -3
- camel/storages/vectordb_storages/tidb.py +8 -6
- camel/tasks/task.py +4 -3
- camel/toolkits/__init__.py +20 -7
- camel/toolkits/aci_toolkit.py +45 -0
- camel/toolkits/base.py +6 -4
- camel/toolkits/code_execution.py +28 -1
- camel/toolkits/context_summarizer_toolkit.py +684 -0
- camel/toolkits/dappier_toolkit.py +5 -1
- camel/toolkits/dingtalk.py +1135 -0
- camel/toolkits/edgeone_pages_mcp_toolkit.py +11 -31
- camel/toolkits/excel_toolkit.py +1 -1
- camel/toolkits/{file_write_toolkit.py → file_toolkit.py} +430 -36
- camel/toolkits/function_tool.py +13 -3
- camel/toolkits/github_toolkit.py +104 -17
- camel/toolkits/gmail_toolkit.py +1839 -0
- camel/toolkits/google_calendar_toolkit.py +38 -4
- camel/toolkits/google_drive_mcp_toolkit.py +12 -31
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +15 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +77 -8
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +884 -88
- camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +5 -612
- camel/toolkits/hybrid_browser_toolkit/ts/package.json +0 -1
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +959 -89
- camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +9 -2
- camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +281 -213
- camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +23 -3
- camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +72 -7
- camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +582 -132
- camel/toolkits/hybrid_browser_toolkit_py/actions.py +158 -0
- camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +55 -8
- camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +43 -0
- camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +321 -8
- camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +10 -4
- camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +45 -4
- camel/toolkits/{openai_image_toolkit.py → image_generation_toolkit.py} +151 -53
- camel/toolkits/klavis_toolkit.py +5 -1
- camel/toolkits/markitdown_toolkit.py +27 -1
- camel/toolkits/math_toolkit.py +64 -10
- camel/toolkits/mcp_toolkit.py +366 -71
- camel/toolkits/memory_toolkit.py +5 -1
- camel/toolkits/message_integration.py +18 -13
- camel/toolkits/minimax_mcp_toolkit.py +195 -0
- camel/toolkits/note_taking_toolkit.py +19 -10
- camel/toolkits/notion_mcp_toolkit.py +16 -26
- camel/toolkits/openbb_toolkit.py +5 -1
- camel/toolkits/origene_mcp_toolkit.py +8 -49
- camel/toolkits/playwright_mcp_toolkit.py +12 -31
- camel/toolkits/resend_toolkit.py +168 -0
- camel/toolkits/search_toolkit.py +264 -91
- camel/toolkits/slack_toolkit.py +64 -10
- camel/toolkits/terminal_toolkit/__init__.py +18 -0
- camel/toolkits/terminal_toolkit/terminal_toolkit.py +957 -0
- camel/toolkits/terminal_toolkit/utils.py +532 -0
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/video_analysis_toolkit.py +17 -11
- camel/toolkits/wechat_official_toolkit.py +483 -0
- camel/toolkits/zapier_toolkit.py +5 -1
- camel/types/__init__.py +2 -2
- camel/types/enums.py +274 -7
- camel/types/openai_types.py +2 -2
- camel/types/unified_model_type.py +15 -0
- camel/utils/commons.py +36 -5
- camel/utils/constants.py +3 -0
- camel/utils/context_utils.py +1003 -0
- camel/utils/mcp.py +138 -4
- camel/utils/token_counting.py +43 -20
- {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/METADATA +223 -83
- {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/RECORD +170 -141
- camel/loaders/pandas_reader.py +0 -368
- camel/toolkits/openai_agent_toolkit.py +0 -135
- camel/toolkits/terminal_toolkit.py +0 -1550
- {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.73a4.dist-info → camel_ai-0.2.80a2.dist-info}/licenses/LICENSE +0 -0
|
@@ -103,34 +103,6 @@ class Mem0Storage(BaseKeyValueStorage):
|
|
|
103
103
|
}
|
|
104
104
|
return {k: v for k, v in options.items() if v is not None}
|
|
105
105
|
|
|
106
|
-
def _prepare_filters(
|
|
107
|
-
self,
|
|
108
|
-
agent_id: Optional[str] = None,
|
|
109
|
-
user_id: Optional[str] = None,
|
|
110
|
-
filters: Optional[Dict[str, Any]] = None,
|
|
111
|
-
) -> Dict[str, Any]:
|
|
112
|
-
r"""Helper method to prepare filters for Mem0 API calls.
|
|
113
|
-
|
|
114
|
-
Args:
|
|
115
|
-
agent_id (Optional[str], optional): Agent ID to filter by
|
|
116
|
-
(default: :obj:`None`).
|
|
117
|
-
user_id (Optional[str], optional): User ID to filter by (default:
|
|
118
|
-
:obj:`None`).
|
|
119
|
-
filters (Optional[Dict[str, Any]], optional): Additional filters
|
|
120
|
-
(default: :obj:`None`).
|
|
121
|
-
|
|
122
|
-
Returns:
|
|
123
|
-
Dict[str, Any]: Prepared filters dictionary for API calls.
|
|
124
|
-
"""
|
|
125
|
-
base_filters: Dict[str, Any] = {"AND": []}
|
|
126
|
-
if filters:
|
|
127
|
-
base_filters["AND"].append(filters)
|
|
128
|
-
if agent_id or self.agent_id:
|
|
129
|
-
base_filters["AND"].append({"agent_id": agent_id or self.agent_id})
|
|
130
|
-
if user_id or self.user_id:
|
|
131
|
-
base_filters["AND"].append({"user_id": user_id or self.user_id})
|
|
132
|
-
return base_filters if base_filters["AND"] else {}
|
|
133
|
-
|
|
134
106
|
def _prepare_messages(
|
|
135
107
|
self,
|
|
136
108
|
records: List[Dict[str, Any]],
|
|
@@ -164,11 +136,11 @@ class Mem0Storage(BaseKeyValueStorage):
|
|
|
164
136
|
agent_id=self.agent_id,
|
|
165
137
|
user_id=self.user_id,
|
|
166
138
|
metadata=self.metadata,
|
|
139
|
+
version="v2",
|
|
167
140
|
)
|
|
168
141
|
self.client.add(messages, **options)
|
|
169
142
|
except Exception as e:
|
|
170
143
|
logger.error(f"Error adding memory: {e}")
|
|
171
|
-
logger.error(f"Error: {e}")
|
|
172
144
|
|
|
173
145
|
def load(self) -> List[Dict[str, Any]]:
|
|
174
146
|
r"""Loads all stored records from the Mem0 storage system.
|
|
@@ -178,47 +150,76 @@ class Mem0Storage(BaseKeyValueStorage):
|
|
|
178
150
|
represents a stored record.
|
|
179
151
|
"""
|
|
180
152
|
try:
|
|
181
|
-
filters
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
153
|
+
# Build filters for get_all using proper Mem0 filter format
|
|
154
|
+
filters = {}
|
|
155
|
+
if self.agent_id:
|
|
156
|
+
filters = {"AND": [{"user_id": self.agent_id}]}
|
|
157
|
+
if self.user_id:
|
|
158
|
+
filters = {"AND": [{"user_id": self.user_id}]}
|
|
159
|
+
|
|
160
|
+
results = self.client.get_all(version="v2", filters=filters)
|
|
186
161
|
|
|
187
162
|
# Transform results into MemoryRecord objects
|
|
188
163
|
transformed_results = []
|
|
189
164
|
for result in results:
|
|
165
|
+
# Ensure metadata is a dictionary, not None
|
|
166
|
+
metadata = result.get("metadata") or {}
|
|
167
|
+
|
|
190
168
|
memory_record = MemoryRecord(
|
|
191
169
|
uuid=UUID(result["id"]),
|
|
192
170
|
message=BaseMessage(
|
|
193
|
-
role_name="
|
|
171
|
+
role_name="memory",
|
|
194
172
|
role_type=RoleType.USER,
|
|
195
|
-
meta_dict=
|
|
173
|
+
meta_dict=metadata,
|
|
196
174
|
content=result["memory"],
|
|
197
175
|
),
|
|
198
176
|
role_at_backend=OpenAIBackendRole.USER,
|
|
199
|
-
extra_info=
|
|
177
|
+
extra_info=metadata,
|
|
200
178
|
timestamp=datetime.fromisoformat(
|
|
201
|
-
result["created_at"]
|
|
179
|
+
result["created_at"].replace('Z', '+00:00')
|
|
202
180
|
).timestamp(),
|
|
203
|
-
agent_id=result.get("agent_id", ""),
|
|
181
|
+
agent_id=result.get("agent_id", self.agent_id or ""),
|
|
204
182
|
)
|
|
205
183
|
transformed_results.append(memory_record.to_dict())
|
|
206
184
|
|
|
207
185
|
return transformed_results
|
|
208
186
|
except Exception as e:
|
|
209
|
-
logger.error(f"Error
|
|
187
|
+
logger.error(f"Error loading memories: {e}")
|
|
210
188
|
return []
|
|
211
189
|
|
|
212
190
|
def clear(
|
|
213
191
|
self,
|
|
192
|
+
agent_id: Optional[str] = None,
|
|
193
|
+
user_id: Optional[str] = None,
|
|
214
194
|
) -> None:
|
|
215
|
-
r"""Removes all records from the Mem0 storage system.
|
|
195
|
+
r"""Removes all records from the Mem0 storage system.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
agent_id (Optional[str]): Specific agent ID to clear memories for.
|
|
199
|
+
user_id (Optional[str]): Specific user ID to clear memories for.
|
|
200
|
+
"""
|
|
216
201
|
try:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
202
|
+
# Use provided IDs or fall back to instance defaults
|
|
203
|
+
target_user_id = user_id or self.user_id
|
|
204
|
+
target_agent_id = agent_id or self.agent_id
|
|
205
|
+
|
|
206
|
+
# Build kwargs for delete_users method
|
|
207
|
+
kwargs = {}
|
|
208
|
+
if target_user_id:
|
|
209
|
+
kwargs['user_id'] = target_user_id
|
|
210
|
+
if target_agent_id:
|
|
211
|
+
kwargs['agent_id'] = target_agent_id
|
|
212
|
+
|
|
213
|
+
if kwargs:
|
|
214
|
+
# Use delete_users (plural) - this is the correct method name
|
|
215
|
+
self.client.delete_users(**kwargs)
|
|
216
|
+
logger.info(
|
|
217
|
+
f"Successfully cleared memories with filters: {kwargs}"
|
|
218
|
+
)
|
|
219
|
+
else:
|
|
220
|
+
logger.warning(
|
|
221
|
+
"No user_id or agent_id available for clearing memories"
|
|
222
|
+
)
|
|
223
|
+
|
|
222
224
|
except Exception as e:
|
|
223
225
|
logger.error(f"Error deleting memories: {e}")
|
|
224
|
-
logger.error(f"Error: {e}")
|
|
@@ -46,7 +46,7 @@ class GoogleCloudStorage(BaseObjectStorage):
|
|
|
46
46
|
create_if_not_exists: bool = True,
|
|
47
47
|
anonymous: bool = False,
|
|
48
48
|
) -> None:
|
|
49
|
-
from google.cloud import storage
|
|
49
|
+
from google.cloud import storage # type: ignore[attr-defined]
|
|
50
50
|
|
|
51
51
|
self.create_if_not_exists = create_if_not_exists
|
|
52
52
|
|
|
@@ -74,7 +74,6 @@ class OceanBaseStorage(BaseVectorStorage):
|
|
|
74
74
|
ObVecClient,
|
|
75
75
|
)
|
|
76
76
|
from pyobvector.client.index_param import (
|
|
77
|
-
IndexParam,
|
|
78
77
|
IndexParams,
|
|
79
78
|
)
|
|
80
79
|
from pyobvector.schema import VECTOR
|
|
@@ -112,20 +111,21 @@ class OceanBaseStorage(BaseVectorStorage):
|
|
|
112
111
|
|
|
113
112
|
# Create vector index
|
|
114
113
|
index_params: IndexParams = IndexParams()
|
|
115
|
-
index_params.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
ef_construction=256,
|
|
123
|
-
)
|
|
114
|
+
index_params.add_index(
|
|
115
|
+
field_name="embedding",
|
|
116
|
+
index_type="hnsw",
|
|
117
|
+
index_name="embedding_idx",
|
|
118
|
+
distance=self.distance,
|
|
119
|
+
m=16,
|
|
120
|
+
ef_construction=256,
|
|
124
121
|
)
|
|
125
122
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
# Get the first index parameter
|
|
124
|
+
first_index_param = next(iter(index_params), None)
|
|
125
|
+
if first_index_param is not None:
|
|
126
|
+
self._client.create_vidx_with_vec_index_param(
|
|
127
|
+
table_name=self.table_name, vidx_param=first_index_param
|
|
128
|
+
)
|
|
129
129
|
|
|
130
130
|
logger.info(f"Created table {self.table_name} with vector index")
|
|
131
131
|
else:
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import logging
|
|
15
15
|
from datetime import datetime
|
|
16
16
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union, cast
|
|
17
|
+
from uuid import UUID
|
|
17
18
|
|
|
18
19
|
if TYPE_CHECKING:
|
|
19
20
|
from qdrant_client import QdrantClient
|
|
@@ -251,7 +252,6 @@ class QdrantStorage(BaseVectorStorage):
|
|
|
251
252
|
else None,
|
|
252
253
|
"vector_count": collection_info.points_count,
|
|
253
254
|
"status": collection_info.status,
|
|
254
|
-
"vectors_count": collection_info.vectors_count,
|
|
255
255
|
"config": collection_info.config,
|
|
256
256
|
}
|
|
257
257
|
|
|
@@ -304,7 +304,7 @@ class QdrantStorage(BaseVectorStorage):
|
|
|
304
304
|
"""
|
|
305
305
|
from qdrant_client.http.models import PointIdsList, UpdateStatus
|
|
306
306
|
|
|
307
|
-
points = cast(List[Union[str,
|
|
307
|
+
points = cast(List[Union[int, str, UUID]], ids)
|
|
308
308
|
|
|
309
309
|
op_info = self._client.set_payload(
|
|
310
310
|
collection_name=self.collection_name,
|
|
@@ -376,7 +376,7 @@ class QdrantStorage(BaseVectorStorage):
|
|
|
376
376
|
op_info = self._client.delete(
|
|
377
377
|
collection_name=self.collection_name,
|
|
378
378
|
points_selector=PointIdsList(
|
|
379
|
-
points=cast(List[Union[int, str]], ids)
|
|
379
|
+
points=cast(List[Union[int, str, UUID]], ids)
|
|
380
380
|
),
|
|
381
381
|
**kwargs,
|
|
382
382
|
)
|
|
@@ -44,7 +44,7 @@ class TiDBStorage(BaseVectorStorage):
|
|
|
44
44
|
r"""An implementation of the `BaseVectorStorage` for interacting with TiDB.
|
|
45
45
|
|
|
46
46
|
The detailed information about TiDB is available at:
|
|
47
|
-
`TiDB Vector Search <https://
|
|
47
|
+
`TiDB Vector Search <https://pingcap.com/ai>`_
|
|
48
48
|
|
|
49
49
|
Args:
|
|
50
50
|
vector_dim (int): The dimension of storing vectors.
|
|
@@ -107,10 +107,10 @@ class TiDBStorage(BaseVectorStorage):
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
def _get_table_model(self, collection_name: str) -> Any:
|
|
110
|
+
from pytidb.datatype import JSON
|
|
110
111
|
from pytidb.schema import Field, TableModel, VectorField
|
|
111
|
-
from sqlalchemy import JSON
|
|
112
112
|
|
|
113
|
-
class
|
|
113
|
+
class VectorDBRecordBase(TableModel, table=False):
|
|
114
114
|
id: Optional[str] = Field(None, primary_key=True)
|
|
115
115
|
vector: list[float] = VectorField(self.vector_dim)
|
|
116
116
|
payload: Optional[dict[str, Any]] = Field(None, sa_type=JSON)
|
|
@@ -119,7 +119,7 @@ class TiDBStorage(BaseVectorStorage):
|
|
|
119
119
|
# class names.
|
|
120
120
|
return type(
|
|
121
121
|
f"VectorDBRecord_{collection_name}",
|
|
122
|
-
(
|
|
122
|
+
(VectorDBRecordBase,),
|
|
123
123
|
{"__tablename__": collection_name},
|
|
124
124
|
table=True,
|
|
125
125
|
)
|
|
@@ -128,8 +128,9 @@ class TiDBStorage(BaseVectorStorage):
|
|
|
128
128
|
r"""Opens an existing table or creates a new table in TiDB."""
|
|
129
129
|
table = self._client.open_table(self.collection_name)
|
|
130
130
|
if table is None:
|
|
131
|
+
table_model = self._get_table_model(self.collection_name)
|
|
131
132
|
table = self._client.create_table(
|
|
132
|
-
schema=
|
|
133
|
+
schema=table_model, if_exists="skip"
|
|
133
134
|
)
|
|
134
135
|
return table
|
|
135
136
|
|
|
@@ -166,6 +167,7 @@ class TiDBStorage(BaseVectorStorage):
|
|
|
166
167
|
table.
|
|
167
168
|
"""
|
|
168
169
|
vector_count = self._table.rows()
|
|
170
|
+
|
|
169
171
|
# Get vector dimension from table schema
|
|
170
172
|
columns = self._table.columns()
|
|
171
173
|
dim_value = None
|
|
@@ -303,7 +305,7 @@ class TiDBStorage(BaseVectorStorage):
|
|
|
303
305
|
for row in rows:
|
|
304
306
|
query_results.append(
|
|
305
307
|
VectorDBQueryResult.create(
|
|
306
|
-
similarity=float(row['
|
|
308
|
+
similarity=float(row['_score']),
|
|
307
309
|
id=str(row['id']),
|
|
308
310
|
payload=row['payload'],
|
|
309
311
|
vector=row['vector'],
|
camel/tasks/task.py
CHANGED
|
@@ -237,8 +237,9 @@ class Task(BaseModel):
|
|
|
237
237
|
(default: :obj:`[]`)
|
|
238
238
|
additional_info (Optional[Dict[str, Any]]): Additional information for
|
|
239
239
|
the task. (default: :obj:`None`)
|
|
240
|
-
image_list (Optional[List[Image.Image]]): Optional list
|
|
241
|
-
objects associated with the
|
|
240
|
+
image_list (Optional[List[Union[Image.Image, str]]]): Optional list
|
|
241
|
+
of PIL Image objects or image URLs (strings) associated with the
|
|
242
|
+
task. (default: :obj:`None`)
|
|
242
243
|
image_detail (Literal["auto", "low", "high"]): Detail level of the
|
|
243
244
|
images associated with the task. (default: :obj:`auto`)
|
|
244
245
|
video_bytes (Optional[bytes]): Optional bytes of a video associated
|
|
@@ -271,7 +272,7 @@ class Task(BaseModel):
|
|
|
271
272
|
|
|
272
273
|
additional_info: Optional[Dict[str, Any]] = None
|
|
273
274
|
|
|
274
|
-
image_list: Optional[List[Image.Image]] = None
|
|
275
|
+
image_list: Optional[List[Union[Image.Image, str]]] = None
|
|
275
276
|
|
|
276
277
|
image_detail: Literal["auto", "low", "high"] = "auto"
|
|
277
278
|
|
camel/toolkits/__init__.py
CHANGED
|
@@ -23,7 +23,7 @@ from .open_api_specs.security_config import openapi_security_config
|
|
|
23
23
|
from .math_toolkit import MathToolkit
|
|
24
24
|
from .search_toolkit import SearchToolkit
|
|
25
25
|
from .weather_toolkit import WeatherToolkit
|
|
26
|
-
from .
|
|
26
|
+
from .image_generation_toolkit import ImageGenToolkit, OpenAIImageToolkit
|
|
27
27
|
from .ask_news_toolkit import AskNewsToolkit, AsyncAskNewsToolkit
|
|
28
28
|
from .linkedin_toolkit import LinkedInToolkit
|
|
29
29
|
from .reddit_toolkit import RedditToolkit
|
|
@@ -37,9 +37,12 @@ from .code_execution import CodeExecutionToolkit
|
|
|
37
37
|
from .github_toolkit import GithubToolkit
|
|
38
38
|
from .google_scholar_toolkit import GoogleScholarToolkit
|
|
39
39
|
from .google_calendar_toolkit import GoogleCalendarToolkit
|
|
40
|
+
from .gmail_toolkit import GmailToolkit
|
|
40
41
|
from .arxiv_toolkit import ArxivToolkit
|
|
41
42
|
from .slack_toolkit import SlackToolkit
|
|
42
43
|
from .whatsapp_toolkit import WhatsAppToolkit
|
|
44
|
+
from .wechat_official_toolkit import WeChatOfficialToolkit
|
|
45
|
+
from .dingtalk import DingtalkToolkit
|
|
43
46
|
from .twitter_toolkit import TwitterToolkit
|
|
44
47
|
from .open_api_toolkit import OpenAPIToolkit
|
|
45
48
|
from .retrieval_toolkit import RetrievalToolkit
|
|
@@ -61,14 +64,13 @@ from .image_analysis_toolkit import ImageAnalysisToolkit
|
|
|
61
64
|
from .mcp_toolkit import MCPToolkit
|
|
62
65
|
from .browser_toolkit import BrowserToolkit
|
|
63
66
|
from .async_browser_toolkit import AsyncBrowserToolkit
|
|
64
|
-
from .
|
|
67
|
+
from .file_toolkit import FileToolkit, FileWriteToolkit
|
|
65
68
|
from .pptx_toolkit import PPTXToolkit
|
|
66
69
|
from .terminal_toolkit import TerminalToolkit
|
|
67
70
|
from .pubmed_toolkit import PubMedToolkit
|
|
68
71
|
from .data_commons_toolkit import DataCommonsToolkit
|
|
69
72
|
from .thinking_toolkit import ThinkingToolkit
|
|
70
73
|
from .pyautogui_toolkit import PyAutoGUIToolkit
|
|
71
|
-
from .openai_agent_toolkit import OpenAIAgentToolkit
|
|
72
74
|
from .searxng_toolkit import SearxNGToolkit
|
|
73
75
|
from .jina_reranker_toolkit import JinaRerankerToolkit
|
|
74
76
|
from .pulse_mcp_search_toolkit import PulseMCPSearchToolkit
|
|
@@ -76,6 +78,7 @@ from .klavis_toolkit import KlavisToolkit
|
|
|
76
78
|
from .aci_toolkit import ACIToolkit
|
|
77
79
|
from .origene_mcp_toolkit import OrigeneToolkit
|
|
78
80
|
from .playwright_mcp_toolkit import PlaywrightMCPToolkit
|
|
81
|
+
from .resend_toolkit import ResendToolkit
|
|
79
82
|
from .wolfram_alpha_toolkit import WolframAlphaToolkit
|
|
80
83
|
from .task_planning_toolkit import TaskPlanningToolkit
|
|
81
84
|
from .hybrid_browser_toolkit import HybridBrowserToolkit
|
|
@@ -88,7 +91,10 @@ from .message_agent_toolkit import AgentCommunicationToolkit
|
|
|
88
91
|
from .web_deploy_toolkit import WebDeployToolkit
|
|
89
92
|
from .screenshot_toolkit import ScreenshotToolkit
|
|
90
93
|
from .message_integration import ToolkitMessageIntegration
|
|
94
|
+
from .context_summarizer_toolkit import ContextSummarizerToolkit
|
|
91
95
|
from .notion_mcp_toolkit import NotionMCPToolkit
|
|
96
|
+
from .vertex_ai_veo_toolkit import VertexAIVeoToolkit
|
|
97
|
+
from .minimax_mcp_toolkit import MinimaxMCPToolkit
|
|
92
98
|
|
|
93
99
|
__all__ = [
|
|
94
100
|
'BaseToolkit',
|
|
@@ -103,7 +109,9 @@ __all__ = [
|
|
|
103
109
|
'SearchToolkit',
|
|
104
110
|
'SlackToolkit',
|
|
105
111
|
'WhatsAppToolkit',
|
|
106
|
-
'
|
|
112
|
+
'WeChatOfficialToolkit',
|
|
113
|
+
'DingtalkToolkit',
|
|
114
|
+
'ImageGenToolkit',
|
|
107
115
|
'TwitterToolkit',
|
|
108
116
|
'WeatherToolkit',
|
|
109
117
|
'RetrievalToolkit',
|
|
@@ -115,6 +123,7 @@ __all__ = [
|
|
|
115
123
|
'AsyncAskNewsToolkit',
|
|
116
124
|
'GoogleScholarToolkit',
|
|
117
125
|
'GoogleCalendarToolkit',
|
|
126
|
+
'GmailToolkit',
|
|
118
127
|
'NotionToolkit',
|
|
119
128
|
'ArxivToolkit',
|
|
120
129
|
'HumanToolkit',
|
|
@@ -136,14 +145,14 @@ __all__ = [
|
|
|
136
145
|
'ImageAnalysisToolkit',
|
|
137
146
|
'BrowserToolkit',
|
|
138
147
|
'AsyncBrowserToolkit',
|
|
139
|
-
'
|
|
148
|
+
'FileToolkit',
|
|
149
|
+
'FileWriteToolkit', # Deprecated, use FileToolkit instead
|
|
140
150
|
'PPTXToolkit',
|
|
141
151
|
'TerminalToolkit',
|
|
142
152
|
'PubMedToolkit',
|
|
143
153
|
'DataCommonsToolkit',
|
|
144
154
|
'ThinkingToolkit',
|
|
145
155
|
'PyAutoGUIToolkit',
|
|
146
|
-
'OpenAIAgentToolkit',
|
|
147
156
|
'SearxNGToolkit',
|
|
148
157
|
'JinaRerankerToolkit',
|
|
149
158
|
'OrigeneToolkit',
|
|
@@ -151,9 +160,10 @@ __all__ = [
|
|
|
151
160
|
'KlavisToolkit',
|
|
152
161
|
'ACIToolkit',
|
|
153
162
|
'PlaywrightMCPToolkit',
|
|
163
|
+
'ResendToolkit',
|
|
154
164
|
'WolframAlphaToolkit',
|
|
155
165
|
'BohriumToolkit',
|
|
156
|
-
'OpenAIImageToolkit',
|
|
166
|
+
'OpenAIImageToolkit', # Backward compatibility
|
|
157
167
|
'TaskPlanningToolkit',
|
|
158
168
|
'HybridBrowserToolkit',
|
|
159
169
|
'EdgeOnePagesMCPToolkit',
|
|
@@ -166,5 +176,8 @@ __all__ = [
|
|
|
166
176
|
'ScreenshotToolkit',
|
|
167
177
|
'RegisteredAgentToolkit',
|
|
168
178
|
'ToolkitMessageIntegration',
|
|
179
|
+
'ContextSummarizerToolkit',
|
|
169
180
|
'NotionMCPToolkit',
|
|
181
|
+
'VertexAIVeoToolkit',
|
|
182
|
+
'MinimaxMCPToolkit',
|
|
170
183
|
]
|
camel/toolkits/aci_toolkit.py
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
# limitations under the License.
|
|
13
13
|
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
|
|
15
|
+
import asyncio
|
|
15
16
|
import os
|
|
16
17
|
from typing import TYPE_CHECKING, Dict, List, Optional, Union
|
|
17
18
|
|
|
@@ -408,6 +409,38 @@ class ACIToolkit(BaseToolkit):
|
|
|
408
409
|
)
|
|
409
410
|
return result
|
|
410
411
|
|
|
412
|
+
async def aexecute_function(
|
|
413
|
+
self,
|
|
414
|
+
function_name: str,
|
|
415
|
+
function_arguments: Dict,
|
|
416
|
+
linked_account_owner_id: str,
|
|
417
|
+
allowed_apps_only: bool = False,
|
|
418
|
+
) -> Dict:
|
|
419
|
+
r"""Execute a function call asynchronously.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
function_name (str): Name of the function to execute.
|
|
423
|
+
function_arguments (Dict): Arguments to pass to the function.
|
|
424
|
+
linked_account_owner_id (str): To specify the end-user (account
|
|
425
|
+
owner) on behalf of whom you want to execute functions
|
|
426
|
+
You need to first link corresponding account with the same
|
|
427
|
+
owner id in the ACI dashboard (https://platform.aci.dev).
|
|
428
|
+
allowed_apps_only (bool): If true, only returns functions/apps
|
|
429
|
+
that are allowed to be used by the agent/accessor, identified
|
|
430
|
+
by the api key. (default: :obj:`False`)
|
|
431
|
+
|
|
432
|
+
Returns:
|
|
433
|
+
Dict: Result of the function execution
|
|
434
|
+
"""
|
|
435
|
+
result = await asyncio.to_thread(
|
|
436
|
+
self.client.handle_function_call,
|
|
437
|
+
function_name,
|
|
438
|
+
function_arguments,
|
|
439
|
+
linked_account_owner_id,
|
|
440
|
+
allowed_apps_only,
|
|
441
|
+
)
|
|
442
|
+
return result
|
|
443
|
+
|
|
411
444
|
def get_tools(self) -> List[FunctionTool]:
|
|
412
445
|
r"""Get a list of tools (functions) available in the configured apps.
|
|
413
446
|
|
|
@@ -434,6 +467,8 @@ class ACIToolkit(BaseToolkit):
|
|
|
434
467
|
FunctionTool(self.delete_linked_account),
|
|
435
468
|
FunctionTool(self.function_definition),
|
|
436
469
|
FunctionTool(self.search_function),
|
|
470
|
+
FunctionTool(self.execute_function),
|
|
471
|
+
FunctionTool(self.aexecute_function),
|
|
437
472
|
]
|
|
438
473
|
|
|
439
474
|
for function in _all_function:
|
|
@@ -448,6 +483,16 @@ class ACIToolkit(BaseToolkit):
|
|
|
448
483
|
linked_account_owner_id=self.linked_account_owner_id,
|
|
449
484
|
)
|
|
450
485
|
|
|
486
|
+
async def async_dummy_func(*, schema=schema, **kwargs):
|
|
487
|
+
return await self.aexecute_function(
|
|
488
|
+
function_name=schema['function']['name'],
|
|
489
|
+
function_arguments=kwargs,
|
|
490
|
+
linked_account_owner_id=self.linked_account_owner_id,
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
# Add async_call method to the sync function for compatibility
|
|
494
|
+
dummy_func.async_call = async_dummy_func # type: ignore[attr-defined]
|
|
495
|
+
|
|
451
496
|
tool = FunctionTool(
|
|
452
497
|
func=dummy_func,
|
|
453
498
|
openai_tool_schema=schema,
|
camel/toolkits/base.py
CHANGED
|
@@ -16,7 +16,7 @@ from typing import TYPE_CHECKING, List, Literal, Optional
|
|
|
16
16
|
|
|
17
17
|
from camel.logger import get_logger
|
|
18
18
|
from camel.toolkits import FunctionTool
|
|
19
|
-
from camel.utils import AgentOpsMeta, with_timeout
|
|
19
|
+
from camel.utils import AgentOpsMeta, Constants, with_timeout
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING:
|
|
22
22
|
from camel.agents import ChatAgent
|
|
@@ -35,9 +35,9 @@ class BaseToolkit(metaclass=AgentOpsMeta):
|
|
|
35
35
|
from mcp.server import FastMCP
|
|
36
36
|
|
|
37
37
|
mcp: FastMCP
|
|
38
|
-
timeout: Optional[float] =
|
|
38
|
+
timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD
|
|
39
39
|
|
|
40
|
-
def __init__(self, timeout: Optional[float] =
|
|
40
|
+
def __init__(self, timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD):
|
|
41
41
|
# check if timeout is a positive number
|
|
42
42
|
if timeout is not None and timeout <= 0:
|
|
43
43
|
raise ValueError("Timeout must be a positive number.")
|
|
@@ -48,7 +48,9 @@ class BaseToolkit(metaclass=AgentOpsMeta):
|
|
|
48
48
|
super().__init_subclass__(**kwargs)
|
|
49
49
|
for attr_name, attr_value in cls.__dict__.items():
|
|
50
50
|
if callable(attr_value) and not attr_name.startswith("__"):
|
|
51
|
-
|
|
51
|
+
# Skip methods that have manual timeout management
|
|
52
|
+
if not getattr(attr_value, '_manual_timeout', False):
|
|
53
|
+
setattr(cls, attr_name, with_timeout(attr_value))
|
|
52
54
|
|
|
53
55
|
def get_tools(self) -> List[FunctionTool]:
|
|
54
56
|
r"""Returns a list of FunctionTool objects representing the
|
camel/toolkits/code_execution.py
CHANGED
|
@@ -18,6 +18,7 @@ from camel.interpreters import (
|
|
|
18
18
|
E2BInterpreter,
|
|
19
19
|
InternalPythonInterpreter,
|
|
20
20
|
JupyterKernelInterpreter,
|
|
21
|
+
MicrosandboxInterpreter,
|
|
21
22
|
SubprocessInterpreter,
|
|
22
23
|
)
|
|
23
24
|
from camel.logger import get_logger
|
|
@@ -43,18 +44,31 @@ class CodeExecutionToolkit(BaseToolkit):
|
|
|
43
44
|
(default: :obj:`None`)
|
|
44
45
|
require_confirm (bool): Whether to require confirmation before
|
|
45
46
|
executing code. (default: :obj:`False`)
|
|
47
|
+
timeout (Optional[float]): General timeout for toolkit operations.
|
|
48
|
+
(default: :obj:`None`)
|
|
49
|
+
microsandbox_config (Optional[dict]): Configuration for microsandbox
|
|
50
|
+
interpreter. Available keys: 'server_url', 'api_key',
|
|
51
|
+
'namespace', 'sandbox_name', 'timeout'.
|
|
52
|
+
If None, uses default configuration. (default: :obj:`None`)
|
|
46
53
|
"""
|
|
47
54
|
|
|
48
55
|
def __init__(
|
|
49
56
|
self,
|
|
50
57
|
sandbox: Literal[
|
|
51
|
-
"internal_python",
|
|
58
|
+
"internal_python",
|
|
59
|
+
"jupyter",
|
|
60
|
+
"docker",
|
|
61
|
+
"subprocess",
|
|
62
|
+
"e2b",
|
|
63
|
+
"microsandbox",
|
|
52
64
|
] = "subprocess",
|
|
53
65
|
verbose: bool = False,
|
|
54
66
|
unsafe_mode: bool = False,
|
|
55
67
|
import_white_list: Optional[List[str]] = None,
|
|
56
68
|
require_confirm: bool = False,
|
|
57
69
|
timeout: Optional[float] = None,
|
|
70
|
+
# Microsandbox configuration dictionary
|
|
71
|
+
microsandbox_config: Optional[dict] = None,
|
|
58
72
|
) -> None:
|
|
59
73
|
super().__init__(timeout=timeout)
|
|
60
74
|
self.verbose = verbose
|
|
@@ -68,6 +82,7 @@ class CodeExecutionToolkit(BaseToolkit):
|
|
|
68
82
|
DockerInterpreter,
|
|
69
83
|
SubprocessInterpreter,
|
|
70
84
|
E2BInterpreter,
|
|
85
|
+
MicrosandboxInterpreter,
|
|
71
86
|
]
|
|
72
87
|
|
|
73
88
|
if sandbox == "internal_python":
|
|
@@ -95,6 +110,18 @@ class CodeExecutionToolkit(BaseToolkit):
|
|
|
95
110
|
)
|
|
96
111
|
elif sandbox == "e2b":
|
|
97
112
|
self.interpreter = E2BInterpreter(require_confirm=require_confirm)
|
|
113
|
+
elif sandbox == "microsandbox":
|
|
114
|
+
# Extract parameters with proper types for microsandbox
|
|
115
|
+
config = microsandbox_config or {}
|
|
116
|
+
|
|
117
|
+
self.interpreter = MicrosandboxInterpreter(
|
|
118
|
+
require_confirm=require_confirm,
|
|
119
|
+
server_url=config.get("server_url"),
|
|
120
|
+
api_key=config.get("api_key"),
|
|
121
|
+
namespace=config.get("namespace", "default"),
|
|
122
|
+
sandbox_name=config.get("sandbox_name"),
|
|
123
|
+
timeout=config.get("timeout", 30),
|
|
124
|
+
)
|
|
98
125
|
else:
|
|
99
126
|
raise RuntimeError(
|
|
100
127
|
f"The sandbox type `{sandbox}` is not supported."
|