camel-ai 0.2.75a6__py3-none-any.whl → 0.2.76a1__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 +159 -38
- camel/configs/__init__.py +3 -0
- camel/configs/amd_config.py +70 -0
- camel/interpreters/__init__.py +2 -0
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/memories/__init__.py +2 -1
- camel/memories/agent_memories.py +3 -1
- camel/memories/blocks/chat_history_block.py +17 -2
- camel/models/__init__.py +2 -0
- camel/models/amd_model.py +101 -0
- camel/models/model_factory.py +2 -0
- camel/models/openai_model.py +0 -6
- camel/runtimes/daytona_runtime.py +11 -12
- camel/societies/workforce/single_agent_worker.py +44 -38
- camel/storages/object_storages/google_cloud.py +1 -1
- camel/toolkits/__init__.py +14 -5
- camel/toolkits/aci_toolkit.py +45 -0
- camel/toolkits/code_execution.py +28 -1
- camel/toolkits/context_summarizer_toolkit.py +683 -0
- camel/toolkits/{file_write_toolkit.py → file_toolkit.py} +194 -34
- camel/toolkits/function_tool.py +6 -1
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +12 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +19 -2
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +95 -59
- 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 +401 -80
- 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/mcp_toolkit.py +39 -14
- camel/toolkits/minimax_mcp_toolkit.py +195 -0
- camel/toolkits/note_taking_toolkit.py +18 -8
- camel/toolkits/terminal_toolkit.py +12 -2
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/video_analysis_toolkit.py +16 -10
- camel/toolkits/wechat_official_toolkit.py +483 -0
- camel/types/enums.py +11 -0
- camel/utils/commons.py +2 -0
- camel/utils/context_utils.py +395 -0
- camel/utils/mcp.py +136 -2
- {camel_ai-0.2.75a6.dist-info → camel_ai-0.2.76a1.dist-info}/METADATA +6 -3
- {camel_ai-0.2.75a6.dist-info → camel_ai-0.2.76a1.dist-info}/RECORD +52 -41
- {camel_ai-0.2.75a6.dist-info → camel_ai-0.2.76a1.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.75a6.dist-info → camel_ai-0.2.76a1.dist-info}/licenses/LICENSE +0 -0
|
@@ -35,8 +35,8 @@ from camel.tasks.task import Task, TaskState, is_task_result_insufficient
|
|
|
35
35
|
class AgentPool:
|
|
36
36
|
r"""A pool of agent instances for efficient reuse.
|
|
37
37
|
|
|
38
|
-
This pool manages a collection of pre-cloned agents
|
|
39
|
-
|
|
38
|
+
This pool manages a collection of pre-cloned agents with automatic
|
|
39
|
+
scaling and idle timeout cleanup.
|
|
40
40
|
|
|
41
41
|
Args:
|
|
42
42
|
base_agent (ChatAgent): The base agent to clone from.
|
|
@@ -48,6 +48,8 @@ class AgentPool:
|
|
|
48
48
|
(default: :obj:`True`)
|
|
49
49
|
idle_timeout (float): Time in seconds after which idle agents are
|
|
50
50
|
removed. (default: :obj:`180.0`)
|
|
51
|
+
cleanup_interval (float): Fixed interval in seconds between cleanup
|
|
52
|
+
checks. (default: :obj:`60.0`)
|
|
51
53
|
"""
|
|
52
54
|
|
|
53
55
|
def __init__(
|
|
@@ -56,12 +58,14 @@ class AgentPool:
|
|
|
56
58
|
initial_size: int = 1,
|
|
57
59
|
max_size: int = 10,
|
|
58
60
|
auto_scale: bool = True,
|
|
59
|
-
idle_timeout: float = 180.0,
|
|
61
|
+
idle_timeout: float = 180.0,
|
|
62
|
+
cleanup_interval: float = 60.0,
|
|
60
63
|
):
|
|
61
64
|
self.base_agent = base_agent
|
|
62
65
|
self.max_size = max_size
|
|
63
66
|
self.auto_scale = auto_scale
|
|
64
67
|
self.idle_timeout = idle_timeout
|
|
68
|
+
self.cleanup_interval = cleanup_interval
|
|
65
69
|
|
|
66
70
|
# Pool management
|
|
67
71
|
self._available_agents: deque = deque()
|
|
@@ -73,6 +77,7 @@ class AgentPool:
|
|
|
73
77
|
self._total_borrows = 0
|
|
74
78
|
self._total_clones_created = 0
|
|
75
79
|
self._pool_hits = 0
|
|
80
|
+
self._agents_cleaned = 0
|
|
76
81
|
|
|
77
82
|
# Initialize pool
|
|
78
83
|
self._initialize_pool(initial_size)
|
|
@@ -82,6 +87,7 @@ class AgentPool:
|
|
|
82
87
|
for _ in range(min(size, self.max_size)):
|
|
83
88
|
agent = self._create_fresh_agent()
|
|
84
89
|
self._available_agents.append(agent)
|
|
90
|
+
self._agent_last_used[id(agent)] = time.time()
|
|
85
91
|
|
|
86
92
|
def _create_fresh_agent(self) -> ChatAgent:
|
|
87
93
|
r"""Create a fresh agent instance."""
|
|
@@ -94,53 +100,46 @@ class AgentPool:
|
|
|
94
100
|
async with self._lock:
|
|
95
101
|
self._total_borrows += 1
|
|
96
102
|
|
|
97
|
-
# Try to get from available agents first
|
|
98
103
|
if self._available_agents:
|
|
99
104
|
agent = self._available_agents.popleft()
|
|
100
105
|
self._in_use_agents.add(id(agent))
|
|
101
106
|
self._pool_hits += 1
|
|
102
|
-
|
|
103
|
-
# Reset the agent state
|
|
104
|
-
agent.reset()
|
|
105
107
|
return agent
|
|
106
108
|
|
|
107
|
-
# Check if we can create new
|
|
108
|
-
|
|
109
|
-
self._in_use_agents
|
|
110
|
-
)
|
|
111
|
-
if total_agents < self.max_size:
|
|
109
|
+
# Check if we can create a new agent
|
|
110
|
+
if len(self._in_use_agents) < self.max_size or self.auto_scale:
|
|
112
111
|
agent = self._create_fresh_agent()
|
|
113
112
|
self._in_use_agents.add(id(agent))
|
|
114
113
|
return agent
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
agent = self._available_agents.popleft()
|
|
126
|
-
self._in_use_agents.add(id(agent))
|
|
127
|
-
agent.reset()
|
|
128
|
-
return agent
|
|
115
|
+
# Wait for available agent
|
|
116
|
+
while True:
|
|
117
|
+
async with self._lock:
|
|
118
|
+
if self._available_agents:
|
|
119
|
+
agent = self._available_agents.popleft()
|
|
120
|
+
self._in_use_agents.add(id(agent))
|
|
121
|
+
self._pool_hits += 1
|
|
122
|
+
return agent
|
|
123
|
+
await asyncio.sleep(0.05)
|
|
129
124
|
|
|
130
125
|
async def return_agent(self, agent: ChatAgent) -> None:
|
|
131
126
|
r"""Return an agent to the pool."""
|
|
127
|
+
agent_id = id(agent)
|
|
128
|
+
|
|
132
129
|
async with self._lock:
|
|
133
|
-
agent_id
|
|
130
|
+
if agent_id not in self._in_use_agents:
|
|
131
|
+
return
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
self._in_use_agents.remove(agent_id)
|
|
133
|
+
self._in_use_agents.discard(agent_id)
|
|
137
134
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
135
|
+
# Only add back to pool if under max size
|
|
136
|
+
if len(self._available_agents) < self.max_size:
|
|
137
|
+
agent.reset()
|
|
138
|
+
self._agent_last_used[agent_id] = time.time()
|
|
139
|
+
self._available_agents.append(agent)
|
|
140
|
+
else:
|
|
141
|
+
# Remove tracking for agents not returned to pool
|
|
142
|
+
self._agent_last_used.pop(agent_id, None)
|
|
144
143
|
|
|
145
144
|
async def cleanup_idle_agents(self) -> None:
|
|
146
145
|
r"""Remove idle agents from the pool to free memory."""
|
|
@@ -148,30 +147,35 @@ class AgentPool:
|
|
|
148
147
|
return
|
|
149
148
|
|
|
150
149
|
async with self._lock:
|
|
150
|
+
if not self._available_agents:
|
|
151
|
+
return
|
|
152
|
+
|
|
151
153
|
current_time = time.time()
|
|
152
154
|
agents_to_remove = []
|
|
153
155
|
|
|
154
156
|
for agent in list(self._available_agents):
|
|
155
157
|
agent_id = id(agent)
|
|
156
158
|
last_used = self._agent_last_used.get(agent_id, current_time)
|
|
157
|
-
|
|
158
159
|
if current_time - last_used > self.idle_timeout:
|
|
159
160
|
agents_to_remove.append(agent)
|
|
160
161
|
|
|
161
162
|
for agent in agents_to_remove:
|
|
162
163
|
self._available_agents.remove(agent)
|
|
163
|
-
|
|
164
|
-
self.
|
|
164
|
+
self._agent_last_used.pop(id(agent), None)
|
|
165
|
+
self._agents_cleaned += 1
|
|
165
166
|
|
|
166
167
|
def get_stats(self) -> dict:
|
|
167
168
|
r"""Get pool statistics."""
|
|
168
169
|
return {
|
|
169
170
|
"available_agents": len(self._available_agents),
|
|
170
171
|
"in_use_agents": len(self._in_use_agents),
|
|
172
|
+
"pool_size": len(self._available_agents)
|
|
173
|
+
+ len(self._in_use_agents),
|
|
171
174
|
"total_borrows": self._total_borrows,
|
|
172
175
|
"total_clones_created": self._total_clones_created,
|
|
173
176
|
"pool_hits": self._pool_hits,
|
|
174
177
|
"hit_rate": self._pool_hits / max(self._total_borrows, 1),
|
|
178
|
+
"agents_cleaned_up": self._agents_cleaned,
|
|
175
179
|
}
|
|
176
180
|
|
|
177
181
|
|
|
@@ -477,7 +481,9 @@ class SingleAgentWorker(Worker):
|
|
|
477
481
|
r"""Periodically clean up idle agents from the pool."""
|
|
478
482
|
while True:
|
|
479
483
|
try:
|
|
480
|
-
|
|
484
|
+
# Fixed interval cleanup
|
|
485
|
+
await asyncio.sleep(self.agent_pool.cleanup_interval)
|
|
486
|
+
|
|
481
487
|
if self.agent_pool:
|
|
482
488
|
await self.agent_pool.cleanup_idle_agents()
|
|
483
489
|
except asyncio.CancelledError:
|
|
@@ -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
|
|
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,7 @@ 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
|
|
43
44
|
from .twitter_toolkit import TwitterToolkit
|
|
44
45
|
from .open_api_toolkit import OpenAPIToolkit
|
|
45
46
|
from .retrieval_toolkit import RetrievalToolkit
|
|
@@ -61,7 +62,7 @@ from .image_analysis_toolkit import ImageAnalysisToolkit
|
|
|
61
62
|
from .mcp_toolkit import MCPToolkit
|
|
62
63
|
from .browser_toolkit import BrowserToolkit
|
|
63
64
|
from .async_browser_toolkit import AsyncBrowserToolkit
|
|
64
|
-
from .
|
|
65
|
+
from .file_toolkit import FileToolkit, FileWriteToolkit
|
|
65
66
|
from .pptx_toolkit import PPTXToolkit
|
|
66
67
|
from .terminal_toolkit import TerminalToolkit
|
|
67
68
|
from .pubmed_toolkit import PubMedToolkit
|
|
@@ -87,7 +88,10 @@ from .message_agent_toolkit import AgentCommunicationToolkit
|
|
|
87
88
|
from .web_deploy_toolkit import WebDeployToolkit
|
|
88
89
|
from .screenshot_toolkit import ScreenshotToolkit
|
|
89
90
|
from .message_integration import ToolkitMessageIntegration
|
|
91
|
+
from .context_summarizer_toolkit import ContextSummarizerToolkit
|
|
90
92
|
from .notion_mcp_toolkit import NotionMCPToolkit
|
|
93
|
+
from .vertex_ai_veo_toolkit import VertexAIVeoToolkit
|
|
94
|
+
from .minimax_mcp_toolkit import MinimaxMCPToolkit
|
|
91
95
|
|
|
92
96
|
__all__ = [
|
|
93
97
|
'BaseToolkit',
|
|
@@ -102,7 +106,8 @@ __all__ = [
|
|
|
102
106
|
'SearchToolkit',
|
|
103
107
|
'SlackToolkit',
|
|
104
108
|
'WhatsAppToolkit',
|
|
105
|
-
'
|
|
109
|
+
'WeChatOfficialToolkit',
|
|
110
|
+
'ImageGenToolkit',
|
|
106
111
|
'TwitterToolkit',
|
|
107
112
|
'WeatherToolkit',
|
|
108
113
|
'RetrievalToolkit',
|
|
@@ -135,7 +140,8 @@ __all__ = [
|
|
|
135
140
|
'ImageAnalysisToolkit',
|
|
136
141
|
'BrowserToolkit',
|
|
137
142
|
'AsyncBrowserToolkit',
|
|
138
|
-
'
|
|
143
|
+
'FileToolkit',
|
|
144
|
+
'FileWriteToolkit', # Deprecated, use FileToolkit instead
|
|
139
145
|
'PPTXToolkit',
|
|
140
146
|
'TerminalToolkit',
|
|
141
147
|
'PubMedToolkit',
|
|
@@ -151,7 +157,7 @@ __all__ = [
|
|
|
151
157
|
'PlaywrightMCPToolkit',
|
|
152
158
|
'WolframAlphaToolkit',
|
|
153
159
|
'BohriumToolkit',
|
|
154
|
-
'OpenAIImageToolkit',
|
|
160
|
+
'OpenAIImageToolkit', # Backward compatibility
|
|
155
161
|
'TaskPlanningToolkit',
|
|
156
162
|
'HybridBrowserToolkit',
|
|
157
163
|
'EdgeOnePagesMCPToolkit',
|
|
@@ -164,5 +170,8 @@ __all__ = [
|
|
|
164
170
|
'ScreenshotToolkit',
|
|
165
171
|
'RegisteredAgentToolkit',
|
|
166
172
|
'ToolkitMessageIntegration',
|
|
173
|
+
'ContextSummarizerToolkit',
|
|
167
174
|
'NotionMCPToolkit',
|
|
175
|
+
'VertexAIVeoToolkit',
|
|
176
|
+
'MinimaxMCPToolkit',
|
|
168
177
|
]
|
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."
|