Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
echo "Extracted version: ${VERSION}"
- name: Update pyproject.toml
run: |
sed -i 's/version = "[^"]*"/version = "'${VERSION}'"/' pyproject.toml
sed -i 's/^version = "[^"]*"/version = "'${VERSION}'"/' pyproject.toml
echo "Updated pyproject.toml version to ${VERSION}"
- name: Update __version__ in __init__.py
run: |
Expand Down
31 changes: 28 additions & 3 deletions agentrun/sandbox/__sandbox_async_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from agentrun.sandbox.aio_sandbox import AioSandbox
from agentrun.sandbox.browser_sandbox import BrowserSandbox
from agentrun.sandbox.code_interpreter_sandbox import CodeInterpreterSandbox
from agentrun.sandbox.custom_sandbox import CustomSandbox
from agentrun.sandbox.model import (
ListSandboxesInput,
ListSandboxesOutput,
Expand Down Expand Up @@ -117,6 +118,20 @@ async def create_async(
) -> "AioSandbox":
...

@classmethod
@overload
async def create_async(
cls,
template_type: Literal[TemplateType.CUSTOM],
template_name: Optional[str] = None,
sandbox_idle_timeout_seconds: Optional[int] = 600,
nas_config: Optional["NASConfig"] = None,
oss_mount_config: Optional["OSSMountConfig"] = None,
polar_fs_config: Optional["PolarFsConfig"] = None,
config: Optional[Config] = None,
) -> "CustomSandbox":
...

@classmethod
async def create_async(
cls,
Expand All @@ -127,7 +142,12 @@ async def create_async(
oss_mount_config: Optional["OSSMountConfig"] = None,
polar_fs_config: Optional["PolarFsConfig"] = None,
config: Optional[Config] = None,
) -> Union["CodeInterpreterSandbox", "BrowserSandbox", "AioSandbox"]:
) -> Union[
"CodeInterpreterSandbox",
"BrowserSandbox",
"AioSandbox",
"CustomSandbox",
]:

if template_name is None:
# todo 可以考虑为用户创建一个模板?
Expand All @@ -142,6 +162,7 @@ async def create_async(
from agentrun.sandbox.code_interpreter_sandbox import (
CodeInterpreterSandbox,
)
from agentrun.sandbox.custom_sandbox import CustomSandbox

if template_type != template.template_type:
raise ValueError(
Expand Down Expand Up @@ -172,6 +193,10 @@ async def create_async(
sandbox = AioSandbox.model_validate(
base_sandbox.model_dump(by_alias=False)
)
elif template.template_type == TemplateType.CUSTOM:
sandbox = CustomSandbox.model_validate(
base_sandbox.model_dump(by_alias=False)
)
else:
raise ValueError(
f"template_type {template.template_type} is not supported"
Expand All @@ -194,7 +219,7 @@ async def stop_by_id_async(cls, sandbox_id: str):
if sandbox_id is None:
raise ValueError("sandbox_id is required")
# todo 后续适配后使用 stop()
return await cls.__get_client().delete_sandbox_async(sandbox_id)
return await cls.__get_client().stop_sandbox_async(sandbox_id)

@classmethod
async def delete_by_id_async(cls, sandbox_id: str):
Expand Down Expand Up @@ -460,4 +485,4 @@ async def stop_async(self):
if self.sandbox_id is None:
raise ValueError("sandbox_id is required to stop a Sandbox")
# todo 后续适配后使用 stop()
return await self.delete_by_id_async(self.sandbox_id)
return await self.stop_by_id_async(self.sandbox_id)
24 changes: 24 additions & 0 deletions agentrun/sandbox/custom_sandbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import Optional

from agentrun.sandbox.model import TemplateType
from agentrun.utils.config import Config
from agentrun.utils.data_api import DataAPI, ResourceType

from .sandbox import Sandbox


class CustomSandbox(Sandbox):
"""Custom Sandbox"""

_template_type = TemplateType.CUSTOM

def get_base_url(self, config: Optional[Config] = None):
"""Get the base URL for the custom sandbox template."""
api = DataAPI(
resource_name="",
resource_type=ResourceType.Template,
namespace="sandboxes",
config=config,
)

return api.with_path("")
8 changes: 8 additions & 0 deletions agentrun/sandbox/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class TemplateType(str, Enum):
"""浏览器 / Browser"""
AIO = "AllInOne"
"""All-in-One 沙箱 / All-in-One Sandbox"""
CUSTOM = "CustomImage"
"""自定义镜像 / Custom Image"""


class TemplateNetworkMode(str, Enum):
Expand Down Expand Up @@ -218,6 +220,12 @@ class TemplateContainerConfiguration(BaseModel):
"""容器镜像地址 / Container Image Address"""
command: Optional[List[str]] = None
"""容器启动命令 / Container Start Command"""
acr_instance_id: Optional[str] = None
"""ACR 实例 ID / ACR Instance ID"""
image_registry_type: Optional[str] = None
"""镜像注册表类型 / Image Registry Type"""
port: Optional[int] = None
"""端口 / Port"""


class TemplateMcpOptions(BaseModel):
Expand Down
61 changes: 55 additions & 6 deletions agentrun/sandbox/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from agentrun.sandbox.aio_sandbox import AioSandbox
from agentrun.sandbox.browser_sandbox import BrowserSandbox
from agentrun.sandbox.code_interpreter_sandbox import CodeInterpreterSandbox
from agentrun.sandbox.custom_sandbox import CustomSandbox
from agentrun.sandbox.model import (
ListSandboxesInput,
ListSandboxesOutput,
Expand Down Expand Up @@ -169,6 +170,34 @@ def create(
) -> "AioSandbox":
...

@classmethod
@overload
async def create_async(
cls,
template_type: Literal[TemplateType.CUSTOM],
template_name: Optional[str] = None,
sandbox_idle_timeout_seconds: Optional[int] = 600,
nas_config: Optional["NASConfig"] = None,
oss_mount_config: Optional["OSSMountConfig"] = None,
polar_fs_config: Optional["PolarFsConfig"] = None,
config: Optional[Config] = None,
) -> "CustomSandbox":
...

@classmethod
@overload
def create(
cls,
template_type: Literal[TemplateType.CUSTOM],
template_name: Optional[str] = None,
sandbox_idle_timeout_seconds: Optional[int] = 600,
nas_config: Optional["NASConfig"] = None,
oss_mount_config: Optional["OSSMountConfig"] = None,
polar_fs_config: Optional["PolarFsConfig"] = None,
config: Optional[Config] = None,
) -> "CustomSandbox":
...

@classmethod
async def create_async(
cls,
Expand All @@ -179,7 +208,12 @@ async def create_async(
oss_mount_config: Optional["OSSMountConfig"] = None,
polar_fs_config: Optional["PolarFsConfig"] = None,
config: Optional[Config] = None,
) -> Union["CodeInterpreterSandbox", "BrowserSandbox", "AioSandbox"]:
) -> Union[
"CodeInterpreterSandbox",
"BrowserSandbox",
"AioSandbox",
"CustomSandbox",
]:

if template_name is None:
# todo 可以考虑为用户创建一个模板?
Expand All @@ -194,6 +228,7 @@ async def create_async(
from agentrun.sandbox.code_interpreter_sandbox import (
CodeInterpreterSandbox,
)
from agentrun.sandbox.custom_sandbox import CustomSandbox

if template_type != template.template_type:
raise ValueError(
Expand Down Expand Up @@ -224,6 +259,10 @@ async def create_async(
sandbox = AioSandbox.model_validate(
base_sandbox.model_dump(by_alias=False)
)
elif template.template_type == TemplateType.CUSTOM:
sandbox = CustomSandbox.model_validate(
base_sandbox.model_dump(by_alias=False)
)
else:
raise ValueError(
f"template_type {template.template_type} is not supported"
Expand All @@ -242,7 +281,12 @@ def create(
oss_mount_config: Optional["OSSMountConfig"] = None,
polar_fs_config: Optional["PolarFsConfig"] = None,
config: Optional[Config] = None,
) -> Union["CodeInterpreterSandbox", "BrowserSandbox", "AioSandbox"]:
) -> Union[
"CodeInterpreterSandbox",
"BrowserSandbox",
"AioSandbox",
"CustomSandbox",
]:

if template_name is None:
# todo 可以考虑为用户创建一个模板?
Expand All @@ -257,6 +301,7 @@ def create(
from agentrun.sandbox.code_interpreter_sandbox import (
CodeInterpreterSandbox,
)
from agentrun.sandbox.custom_sandbox import CustomSandbox

if template_type != template.template_type:
raise ValueError(
Expand Down Expand Up @@ -287,6 +332,10 @@ def create(
sandbox = AioSandbox.model_validate(
base_sandbox.model_dump(by_alias=False)
)
elif template.template_type == TemplateType.CUSTOM:
sandbox = CustomSandbox.model_validate(
base_sandbox.model_dump(by_alias=False)
)
else:
raise ValueError(
f"template_type {template.template_type} is not supported"
Expand All @@ -309,7 +358,7 @@ async def stop_by_id_async(cls, sandbox_id: str):
if sandbox_id is None:
raise ValueError("sandbox_id is required")
# todo 后续适配后使用 stop()
return await cls.__get_client().delete_sandbox_async(sandbox_id)
return await cls.__get_client().stop_sandbox_async(sandbox_id)

@classmethod
def stop_by_id(cls, sandbox_id: str):
Expand All @@ -325,7 +374,7 @@ def stop_by_id(cls, sandbox_id: str):
if sandbox_id is None:
raise ValueError("sandbox_id is required")
# todo 后续适配后使用 stop()
return cls.__get_client().delete_sandbox(sandbox_id)
return cls.__get_client().stop_sandbox(sandbox_id)

@classmethod
async def delete_by_id_async(cls, sandbox_id: str):
Expand Down Expand Up @@ -839,10 +888,10 @@ async def stop_async(self):
if self.sandbox_id is None:
raise ValueError("sandbox_id is required to stop a Sandbox")
# todo 后续适配后使用 stop()
return await self.delete_by_id_async(self.sandbox_id)
return await self.stop_by_id_async(self.sandbox_id)

def stop(self):
if self.sandbox_id is None:
raise ValueError("sandbox_id is required to stop a Sandbox")
# todo 后续适配后使用 stop()
return self.delete_by_id(self.sandbox_id)
return self.stop_by_id(self.sandbox_id)
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies = [
"litellm>=1.79.3",
"alibabacloud-devs20230714>=2.4.1",
"pydash>=8.0.5",
"alibabacloud-agentrun20250910>=5.2.0",
"alibabacloud-agentrun20250910>=5.3.1",
"alibabacloud_tea_openapi>=0.4.2",
"alibabacloud_bailian20231229>=2.6.2",
"agentrun-mem0ai>=0.0.10",
Expand Down Expand Up @@ -104,7 +104,7 @@ known_third_party = ["alibabacloud_tea_openapi", "alibabacloud_devs20230714", "a
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]

[tool.mypy]
python_version = "0.0.15"
python_version = "3.10"
exclude = "tests/"
plugins = ["pydantic.mypy"]
# Start with non-strict mode, and switch to strict mode later.
Expand Down
Loading