camel-ai 0.2.75a5__py3-none-any.whl → 0.2.76__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 +1148 -298
- camel/agents/mcp_agent.py +30 -27
- camel/configs/__init__.py +9 -0
- camel/configs/amd_config.py +70 -0
- camel/configs/cometapi_config.py +104 -0
- camel/configs/nebius_config.py +103 -0
- camel/data_collectors/alpaca_collector.py +15 -6
- camel/environments/tic_tac_toe.py +1 -1
- camel/interpreters/__init__.py +2 -0
- camel/interpreters/docker/Dockerfile +3 -12
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/loaders/__init__.py +11 -2
- camel/loaders/chunkr_reader.py +9 -0
- camel/memories/__init__.py +2 -1
- camel/memories/agent_memories.py +3 -1
- camel/memories/blocks/chat_history_block.py +21 -3
- camel/memories/records.py +88 -8
- camel/messages/base.py +127 -34
- camel/models/__init__.py +6 -0
- camel/models/amd_model.py +101 -0
- camel/models/azure_openai_model.py +0 -6
- camel/models/base_model.py +30 -0
- camel/models/cometapi_model.py +83 -0
- camel/models/model_factory.py +6 -0
- camel/models/nebius_model.py +83 -0
- camel/models/ollama_model.py +3 -3
- camel/models/openai_compatible_model.py +0 -6
- camel/models/openai_model.py +0 -6
- camel/models/zhipuai_model.py +61 -2
- 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/workforce/prompts.py +131 -50
- camel/societies/workforce/single_agent_worker.py +434 -49
- camel/societies/workforce/structured_output_handler.py +30 -18
- camel/societies/workforce/task_channel.py +163 -27
- camel/societies/workforce/utils.py +105 -12
- camel/societies/workforce/workforce.py +1357 -314
- camel/societies/workforce/workforce_logger.py +24 -5
- camel/storages/key_value_storages/json.py +15 -2
- camel/storages/object_storages/google_cloud.py +1 -1
- camel/storages/vectordb_storages/oceanbase.py +10 -11
- camel/storages/vectordb_storages/tidb.py +8 -6
- camel/tasks/task.py +4 -3
- camel/toolkits/__init__.py +18 -5
- camel/toolkits/aci_toolkit.py +45 -0
- camel/toolkits/code_execution.py +28 -1
- camel/toolkits/context_summarizer_toolkit.py +684 -0
- camel/toolkits/dingtalk.py +1135 -0
- camel/toolkits/edgeone_pages_mcp_toolkit.py +11 -31
- camel/toolkits/{file_write_toolkit.py → file_toolkit.py} +194 -34
- camel/toolkits/function_tool.py +6 -1
- camel/toolkits/github_toolkit.py +104 -17
- camel/toolkits/google_drive_mcp_toolkit.py +12 -31
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +12 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +79 -2
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +95 -59
- 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 +619 -95
- camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +7 -2
- camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +115 -219
- 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 +1 -0
- camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +39 -6
- camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +412 -133
- camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +9 -5
- camel/toolkits/{openai_image_toolkit.py → image_generation_toolkit.py} +98 -31
- camel/toolkits/markitdown_toolkit.py +27 -1
- camel/toolkits/math_toolkit.py +64 -10
- camel/toolkits/mcp_toolkit.py +348 -348
- camel/toolkits/message_integration.py +3 -0
- camel/toolkits/minimax_mcp_toolkit.py +195 -0
- camel/toolkits/note_taking_toolkit.py +18 -8
- camel/toolkits/notion_mcp_toolkit.py +16 -26
- 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 +13 -2
- camel/toolkits/slack_toolkit.py +50 -1
- camel/toolkits/terminal_toolkit/__init__.py +18 -0
- camel/toolkits/terminal_toolkit/terminal_toolkit.py +924 -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/types/enums.py +155 -1
- camel/types/unified_model_type.py +10 -0
- camel/utils/commons.py +17 -0
- camel/utils/context_utils.py +804 -0
- camel/utils/mcp.py +136 -2
- camel/utils/token_counting.py +25 -17
- {camel_ai-0.2.75a5.dist-info → camel_ai-0.2.76.dist-info}/METADATA +158 -67
- {camel_ai-0.2.75a5.dist-info → camel_ai-0.2.76.dist-info}/RECORD +101 -80
- camel/loaders/pandas_reader.py +0 -368
- camel/toolkits/terminal_toolkit.py +0 -1788
- {camel_ai-0.2.75a5.dist-info → camel_ai-0.2.76.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.75a5.dist-info → camel_ai-0.2.76.dist-info}/licenses/LICENSE +0 -0
|
@@ -495,6 +495,11 @@ class WorkforceLogger:
|
|
|
495
495
|
|
|
496
496
|
tasks_handled_by_worker: Dict[str, int] = {}
|
|
497
497
|
|
|
498
|
+
# Track unique task final states to avoid double-counting
|
|
499
|
+
task_final_states: Dict[
|
|
500
|
+
str, str
|
|
501
|
+
] = {} # task_id -> 'completed' or 'failed'
|
|
502
|
+
|
|
498
503
|
# Helper function to check if a task is the main task (has no parent)
|
|
499
504
|
def is_main_task(task_id: str) -> bool:
|
|
500
505
|
return (
|
|
@@ -528,7 +533,9 @@ class WorkforceLogger:
|
|
|
528
533
|
elif event_type == 'task_completed':
|
|
529
534
|
# Exclude main task from total count
|
|
530
535
|
if not is_main_task(task_id):
|
|
531
|
-
|
|
536
|
+
# Track final state - a completed task overwrites any
|
|
537
|
+
# previous failed state
|
|
538
|
+
task_final_states[task_id] = 'completed'
|
|
532
539
|
# Count tasks handled by worker (only for non-main tasks)
|
|
533
540
|
if 'worker_id' in entry and entry['worker_id'] is not None:
|
|
534
541
|
worker_id = entry['worker_id']
|
|
@@ -550,7 +557,11 @@ class WorkforceLogger:
|
|
|
550
557
|
elif event_type == 'task_failed':
|
|
551
558
|
# Exclude main task from total count
|
|
552
559
|
if not is_main_task(task_id):
|
|
553
|
-
|
|
560
|
+
# Only track as failed if not already completed
|
|
561
|
+
# (in case of retries, the final completion overwrites
|
|
562
|
+
# failed state)
|
|
563
|
+
if task_final_states.get(task_id) != 'completed':
|
|
564
|
+
task_final_states[task_id] = 'failed'
|
|
554
565
|
# Count tasks handled by worker (only for non-main tasks)
|
|
555
566
|
if 'worker_id' in entry and entry['worker_id'] is not None:
|
|
556
567
|
worker_id = entry['worker_id']
|
|
@@ -565,6 +576,14 @@ class WorkforceLogger:
|
|
|
565
576
|
kpis['total_workforce_running_time_seconds'] = (
|
|
566
577
|
last_timestamp - first_timestamp
|
|
567
578
|
).total_seconds()
|
|
579
|
+
|
|
580
|
+
# Count unique tasks by final state
|
|
581
|
+
for _task_id, state in task_final_states.items():
|
|
582
|
+
if state == 'completed':
|
|
583
|
+
kpis['total_tasks_completed'] += 1
|
|
584
|
+
elif state == 'failed':
|
|
585
|
+
kpis['total_tasks_failed'] += 1
|
|
586
|
+
|
|
568
587
|
# Calculate worker utilization based on proportion of tasks handled
|
|
569
588
|
total_tasks_processed_for_utilization = (
|
|
570
589
|
kpis['total_tasks_completed'] + kpis['total_tasks_failed']
|
|
@@ -610,9 +629,9 @@ class WorkforceLogger:
|
|
|
610
629
|
|
|
611
630
|
kpis['total_workers_created'] = len(self._worker_information)
|
|
612
631
|
|
|
613
|
-
# Current pending tasks
|
|
614
|
-
kpis['current_pending_tasks'] = kpis['total_tasks_created'] - (
|
|
615
|
-
|
|
632
|
+
# Current pending tasks - tasks created but not yet completed or failed
|
|
633
|
+
kpis['current_pending_tasks'] = kpis['total_tasks_created'] - len(
|
|
634
|
+
task_final_states
|
|
616
635
|
)
|
|
617
636
|
|
|
618
637
|
return kpis
|
|
@@ -17,6 +17,8 @@ from enum import EnumMeta
|
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from typing import Any, ClassVar, Dict, List, Optional
|
|
19
19
|
|
|
20
|
+
from pydantic import BaseModel
|
|
21
|
+
|
|
20
22
|
from camel.storages.key_value_storages import BaseKeyValueStorage
|
|
21
23
|
from camel.types import (
|
|
22
24
|
ModelType,
|
|
@@ -27,8 +29,13 @@ from camel.types import (
|
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class CamelJSONEncoder(json.JSONEncoder):
|
|
30
|
-
r"""A custom JSON encoder for serializing
|
|
31
|
-
|
|
32
|
+
r"""A custom JSON encoder for serializing CAMEL-specific types.
|
|
33
|
+
|
|
34
|
+
Handles serialization of:
|
|
35
|
+
- Enumerated types (RoleType, TaskType, ModelType, OpenAIBackendRole)
|
|
36
|
+
- Pydantic BaseModel objects (from structured outputs)
|
|
37
|
+
|
|
38
|
+
Ensures these types can be stored in and retrieved from JSON format.
|
|
32
39
|
"""
|
|
33
40
|
|
|
34
41
|
CAMEL_ENUMS: ClassVar[Dict[str, EnumMeta]] = {
|
|
@@ -39,8 +46,14 @@ class CamelJSONEncoder(json.JSONEncoder):
|
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
def default(self, obj) -> Any:
|
|
49
|
+
# Handle CAMEL enum types
|
|
42
50
|
if type(obj) in self.CAMEL_ENUMS.values():
|
|
43
51
|
return {"__enum__": str(obj)}
|
|
52
|
+
|
|
53
|
+
# Handle Pydantic BaseModel objects (e.g., from structured outputs)
|
|
54
|
+
if isinstance(obj, BaseModel):
|
|
55
|
+
return obj.model_dump()
|
|
56
|
+
|
|
44
57
|
# Let the base class default method raise the TypeError
|
|
45
58
|
return json.JSONEncoder.default(self, obj)
|
|
46
59
|
|
|
@@ -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,19 +111,19 @@ 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
|
|
|
123
|
+
# Get the first index parameter
|
|
124
|
+
first_index_param = next(iter(index_params))
|
|
126
125
|
self._client.create_vidx_with_vec_index_param(
|
|
127
|
-
table_name=self.table_name, vidx_param=
|
|
126
|
+
table_name=self.table_name, vidx_param=first_index_param
|
|
128
127
|
)
|
|
129
128
|
|
|
130
129
|
logger.info(f"Created table {self.table_name} with vector index")
|
|
@@ -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
|
|
@@ -40,6 +40,8 @@ from .google_calendar_toolkit import GoogleCalendarToolkit
|
|
|
40
40
|
from .arxiv_toolkit import ArxivToolkit
|
|
41
41
|
from .slack_toolkit import SlackToolkit
|
|
42
42
|
from .whatsapp_toolkit import WhatsAppToolkit
|
|
43
|
+
from .wechat_official_toolkit import WeChatOfficialToolkit
|
|
44
|
+
from .dingtalk import DingtalkToolkit
|
|
43
45
|
from .twitter_toolkit import TwitterToolkit
|
|
44
46
|
from .open_api_toolkit import OpenAPIToolkit
|
|
45
47
|
from .retrieval_toolkit import RetrievalToolkit
|
|
@@ -61,7 +63,7 @@ from .image_analysis_toolkit import ImageAnalysisToolkit
|
|
|
61
63
|
from .mcp_toolkit import MCPToolkit
|
|
62
64
|
from .browser_toolkit import BrowserToolkit
|
|
63
65
|
from .async_browser_toolkit import AsyncBrowserToolkit
|
|
64
|
-
from .
|
|
66
|
+
from .file_toolkit import FileToolkit, FileWriteToolkit
|
|
65
67
|
from .pptx_toolkit import PPTXToolkit
|
|
66
68
|
from .terminal_toolkit import TerminalToolkit
|
|
67
69
|
from .pubmed_toolkit import PubMedToolkit
|
|
@@ -75,6 +77,7 @@ from .klavis_toolkit import KlavisToolkit
|
|
|
75
77
|
from .aci_toolkit import ACIToolkit
|
|
76
78
|
from .origene_mcp_toolkit import OrigeneToolkit
|
|
77
79
|
from .playwright_mcp_toolkit import PlaywrightMCPToolkit
|
|
80
|
+
from .resend_toolkit import ResendToolkit
|
|
78
81
|
from .wolfram_alpha_toolkit import WolframAlphaToolkit
|
|
79
82
|
from .task_planning_toolkit import TaskPlanningToolkit
|
|
80
83
|
from .hybrid_browser_toolkit import HybridBrowserToolkit
|
|
@@ -87,7 +90,10 @@ from .message_agent_toolkit import AgentCommunicationToolkit
|
|
|
87
90
|
from .web_deploy_toolkit import WebDeployToolkit
|
|
88
91
|
from .screenshot_toolkit import ScreenshotToolkit
|
|
89
92
|
from .message_integration import ToolkitMessageIntegration
|
|
93
|
+
from .context_summarizer_toolkit import ContextSummarizerToolkit
|
|
90
94
|
from .notion_mcp_toolkit import NotionMCPToolkit
|
|
95
|
+
from .vertex_ai_veo_toolkit import VertexAIVeoToolkit
|
|
96
|
+
from .minimax_mcp_toolkit import MinimaxMCPToolkit
|
|
91
97
|
|
|
92
98
|
__all__ = [
|
|
93
99
|
'BaseToolkit',
|
|
@@ -102,7 +108,9 @@ __all__ = [
|
|
|
102
108
|
'SearchToolkit',
|
|
103
109
|
'SlackToolkit',
|
|
104
110
|
'WhatsAppToolkit',
|
|
105
|
-
'
|
|
111
|
+
'WeChatOfficialToolkit',
|
|
112
|
+
'DingtalkToolkit',
|
|
113
|
+
'ImageGenToolkit',
|
|
106
114
|
'TwitterToolkit',
|
|
107
115
|
'WeatherToolkit',
|
|
108
116
|
'RetrievalToolkit',
|
|
@@ -135,7 +143,8 @@ __all__ = [
|
|
|
135
143
|
'ImageAnalysisToolkit',
|
|
136
144
|
'BrowserToolkit',
|
|
137
145
|
'AsyncBrowserToolkit',
|
|
138
|
-
'
|
|
146
|
+
'FileToolkit',
|
|
147
|
+
'FileWriteToolkit', # Deprecated, use FileToolkit instead
|
|
139
148
|
'PPTXToolkit',
|
|
140
149
|
'TerminalToolkit',
|
|
141
150
|
'PubMedToolkit',
|
|
@@ -149,9 +158,10 @@ __all__ = [
|
|
|
149
158
|
'KlavisToolkit',
|
|
150
159
|
'ACIToolkit',
|
|
151
160
|
'PlaywrightMCPToolkit',
|
|
161
|
+
'ResendToolkit',
|
|
152
162
|
'WolframAlphaToolkit',
|
|
153
163
|
'BohriumToolkit',
|
|
154
|
-
'OpenAIImageToolkit',
|
|
164
|
+
'OpenAIImageToolkit', # Backward compatibility
|
|
155
165
|
'TaskPlanningToolkit',
|
|
156
166
|
'HybridBrowserToolkit',
|
|
157
167
|
'EdgeOnePagesMCPToolkit',
|
|
@@ -164,5 +174,8 @@ __all__ = [
|
|
|
164
174
|
'ScreenshotToolkit',
|
|
165
175
|
'RegisteredAgentToolkit',
|
|
166
176
|
'ToolkitMessageIntegration',
|
|
177
|
+
'ContextSummarizerToolkit',
|
|
167
178
|
'NotionMCPToolkit',
|
|
179
|
+
'VertexAIVeoToolkit',
|
|
180
|
+
'MinimaxMCPToolkit',
|
|
168
181
|
]
|
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/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."
|