diff --git a/AGENTS.md b/AGENTS.md index ad5ff65..65cf54f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -447,3 +447,27 @@ A: 建议: - [Python SDK 文档](./python/README.md) - [示例代码](./python/examples/) - [阿里云 AgentRun 官方文档](https://help.aliyun.com/zh/agentrun/) + +## 工作流程 + +### 为特定模块增加参数 + +名词解释 +- AgentRun SDK:当前项目 +- 底层 SDK:我们会依赖底层 SDK 与平台进行交互,如果是 python sdk,则为 `agentrun-20250910`;如果是 nodejs sdk,则为 `@alicloud/agentrun20250910` +- 要修改模块:sandbox、model 等 + +此时,应该遵循如下流程 + +该模块的代码位于 ${component} 目录,包含如下部分 +- api/ 和底层 SDK 交互的逻辑。你可以根据该文件的调用方式,跳转到底层 sdk 的逻辑,进行检查 +- client 为用户封装的客户端,你需要检查一下是否需要修改 +- model 相关类型描述,你需要严格检查当前文件是否需要修改,这里可能存在大量修改 +- 其他文件 你也需要一并检查,如果是 nodejs sdk,需要检查 class 的属性 +- _xxx_async_template.py python sdk 中生成 xxx.py 文件的模板,只需要声明 async 即可(使用 `make codegen` 进行生成) + +1. 请严格检查底层 SDK 的输入、输出参数,并对照现有类型定义,整理出新增的参数列表 +2. 根据新增的参数列表,在 agentrun sdk 中进行修改,补充对应的中英文注释 +3. 执行相关模块的 ut 测试,确保可以正确执行 +4. 进行修改内容的总结汇报 +5. 根据汇报内容进行检查,重新检查底层 SDK 和 AgentRun SDK 的定义 diff --git a/agentrun/agent_runtime/api/control.py b/agentrun/agent_runtime/api/control.py index 9529cf4..8b76d45 100644 --- a/agentrun/agent_runtime/api/control.py +++ b/agentrun/agent_runtime/api/control.py @@ -35,7 +35,7 @@ ) from alibabacloud_tea_openapi.exceptions._client import ClientException from alibabacloud_tea_openapi.exceptions._server import ServerException -from alibabacloud_tea_util.models import RuntimeOptions +from darabonba.runtime import RuntimeOptions import pydash from agentrun.utils.config import Config diff --git a/agentrun/credential/api/control.py b/agentrun/credential/api/control.py index e4b499e..9506129 100644 --- a/agentrun/credential/api/control.py +++ b/agentrun/credential/api/control.py @@ -25,7 +25,7 @@ ) from alibabacloud_tea_openapi.exceptions._client import ClientException from alibabacloud_tea_openapi.exceptions._server import ServerException -from alibabacloud_tea_util.models import RuntimeOptions +from darabonba.runtime import RuntimeOptions import pydash from agentrun.utils.config import Config diff --git a/agentrun/model/api/control.py b/agentrun/model/api/control.py index acf1aac..2790e99 100644 --- a/agentrun/model/api/control.py +++ b/agentrun/model/api/control.py @@ -32,7 +32,7 @@ ) from alibabacloud_tea_openapi.exceptions._client import ClientException from alibabacloud_tea_openapi.exceptions._server import ServerException -from alibabacloud_tea_util.models import RuntimeOptions +from darabonba.runtime import RuntimeOptions import pydash from agentrun.utils.config import Config diff --git a/agentrun/sandbox/__client_async_template.py b/agentrun/sandbox/__client_async_template.py index f79eaa7..f87c34b 100644 --- a/agentrun/sandbox/__client_async_template.py +++ b/agentrun/sandbox/__client_async_template.py @@ -5,7 +5,7 @@ """ import time -from typing import List, Optional, TYPE_CHECKING +from typing import Any, Dict, List, Optional, TYPE_CHECKING from alibabacloud_agentrun20250910.models import ( CreateTemplateInput, @@ -18,7 +18,10 @@ from agentrun.sandbox.model import ( ListSandboxesInput, ListSandboxesOutput, + NASConfig, + OSSMountConfig, PageableInput, + PolarFsConfig, TemplateInput, ) from agentrun.utils.config import Config @@ -273,25 +276,47 @@ async def create_sandbox_async( self, template_name: str, 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, ) -> Sandbox: - """创建 Sandbox(异步) + """创建 Sandbox(异步) / Create Sandbox (async) Args: - input: Sandbox 配置 - config: 配置对象 + template_name: 模板名称 / Template name + sandbox_idle_timeout_seconds: 沙箱空闲超时时间(秒) / Sandbox idle timeout (seconds) + nas_config: NAS 配置 / NAS configuration + oss_mount_config: OSS 挂载配置 / OSS mount configuration + polar_fs_config: PolarFS 配置 / PolarFS configuration + config: 配置对象 / Config object Returns: - Sandbox: 创建的 Sandbox 对象 + Sandbox: 创建的 Sandbox 对象 / Created Sandbox object Raises: - ClientError: 客户端错误 - ServerError: 服务器错误 + ClientError: 客户端错误 / Client error + ServerError: 服务器错误 / Server error """ + # 将配置对象转换为字典格式 + nas_config_dict: Optional[Dict[str, Any]] = None + if nas_config is not None: + nas_config_dict = nas_config.model_dump(by_alias=True) + + oss_mount_config_dict: Optional[Dict[str, Any]] = None + if oss_mount_config is not None: + oss_mount_config_dict = oss_mount_config.model_dump(by_alias=True) + + polar_fs_config_dict: Optional[Dict[str, Any]] = None + if polar_fs_config is not None: + polar_fs_config_dict = polar_fs_config.model_dump(by_alias=True) result = await self.__sandbox_data_api.create_sandbox_async( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, + nas_config=nas_config_dict, + oss_mount_config=oss_mount_config_dict, + polar_fs_config=polar_fs_config_dict, config=config, ) diff --git a/agentrun/sandbox/__init__.py b/agentrun/sandbox/__init__.py index 34e6b1f..b37d1ca 100644 --- a/agentrun/sandbox/__init__.py +++ b/agentrun/sandbox/__init__.py @@ -10,7 +10,12 @@ CodeLanguage, ListSandboxesInput, ListSandboxesOutput, + NASConfig, + NASMountConfig, + OSSMountConfig, + OSSMountPoint, PageableInput, + PolarFsConfig, SandboxInput, TemplateArmsConfiguration, TemplateContainerConfiguration, @@ -55,4 +60,10 @@ "ListSandboxesOutput", "CodeLanguage", "TemplateOSSPermission", + "NASConfig", + "NASMountConfig", + "OSSMountConfig", + "OSSMountPoint", + "PolarFsConfig", + "PolarFsConfig", ] diff --git a/agentrun/sandbox/__sandbox_async_template.py b/agentrun/sandbox/__sandbox_async_template.py index 659416c..016711c 100644 --- a/agentrun/sandbox/__sandbox_async_template.py +++ b/agentrun/sandbox/__sandbox_async_template.py @@ -4,7 +4,16 @@ This module defines the high-level API for sandbox resources. """ -from typing import List, Literal, Optional, overload, TYPE_CHECKING, Union +from typing import ( + Any, + Dict, + List, + Literal, + Optional, + overload, + TYPE_CHECKING, + Union, +) from agentrun.sandbox.model import TemplateType from agentrun.utils.config import Config @@ -17,7 +26,10 @@ from agentrun.sandbox.model import ( ListSandboxesInput, ListSandboxesOutput, + NASConfig, + OSSMountConfig, PageableInput, + PolarFsConfig, TemplateInput, ) from agentrun.sandbox.template import Template @@ -32,23 +44,29 @@ class Sandbox(BaseModel): _template_type: Optional[TemplateType] created_at: Optional[str] = None - """沙箱创建时间""" + """沙箱创建时间 / Sandbox creation time""" + ended_at: Optional[str] = None + """沙箱结束时间 / Sandbox end time""" last_updated_at: Optional[str] = None - """最后更新时间""" + """最后更新时间 / Last updated time""" + metadata: Optional[Dict[str, Any]] = None + """元数据 / Metadata""" sandbox_arn: Optional[str] = None - """沙箱全局唯一资源名称""" + """沙箱全局唯一资源名称 / Sandbox ARN""" sandbox_id: Optional[str] = None - """沙箱 ID""" + """沙箱 ID / Sandbox ID""" + sandbox_idle_ttlin_seconds: Optional[int] = None + """沙箱空闲 TTL(秒) / Sandbox Idle TTL (seconds)""" sandbox_idle_timeout_seconds: Optional[int] = None - """沙箱空闲超时时间(秒)""" + """沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)""" status: Optional[str] = None - """沙箱状态""" + """沙箱状态 / Sandbox status""" template_id: Optional[str] = None - """模板 ID""" + """模板 ID / Template ID""" template_name: Optional[str] = None - """模板名称""" + """模板名称 / Template name""" _config: Optional[Config] = None - """配置对象,用于子类的 data_api 初始化""" + """配置对象,用于子类的 data_api 初始化 / Config object for data_api initialization""" @classmethod def __get_client(cls): @@ -64,6 +82,9 @@ async def create_async( template_type: Literal[TemplateType.CODE_INTERPRETER], 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, ) -> "CodeInterpreterSandbox": ... @@ -75,6 +96,9 @@ async def create_async( template_type: Literal[TemplateType.BROWSER], 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, ) -> "BrowserSandbox": ... @@ -86,6 +110,9 @@ async def create_async( template_type: Literal[TemplateType.AIO], 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, ) -> "AioSandbox": ... @@ -96,6 +123,9 @@ async def create_async( template_type: TemplateType, 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, ) -> Union["CodeInterpreterSandbox", "BrowserSandbox", "AioSandbox"]: @@ -123,6 +153,9 @@ async def create_async( base_sandbox = await cls.__get_client().create_sandbox_async( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, + nas_config=nas_config, + oss_mount_config=oss_mount_config, + polar_fs_config=polar_fs_config, ) # 根据 template 类型转换为对应的子类实例 diff --git a/agentrun/sandbox/__template_async_template.py b/agentrun/sandbox/__template_async_template.py index 0b54a69..bcebe07 100644 --- a/agentrun/sandbox/__template_async_template.py +++ b/agentrun/sandbox/__template_async_template.py @@ -29,59 +29,61 @@ class Template(BaseModel): """ template_id: Optional[str] = None - """模板 ID""" + """模板 ID / Template ID""" template_name: Optional[str] = None - """模板名称""" + """模板名称 / Template Name""" template_version: Optional[str] = None - """模板版本""" + """模板版本 / Template Version""" template_arn: Optional[str] = None - """模板 ARN""" + """模板 ARN / Template ARN""" resource_name: Optional[str] = None - """资源名称""" + """资源名称 / Resource Name""" template_type: Optional[TemplateType] = None - """模板类型""" + """模板类型 / Template Type""" cpu: Optional[float] = None - """CPU 核数""" + """CPU 核数 / CPU Cores""" memory: Optional[int] = None - """内存大小(MB)""" + """内存大小(MB) / Memory Size (MB)""" disk_size: Optional[int] = None - """磁盘大小(GB)""" + """磁盘大小(GB) / Disk Size (GB)""" description: Optional[str] = None - """描述""" + """描述 / Description""" execution_role_arn: Optional[str] = None - """执行角色 ARN""" + """执行角色 ARN / Execution Role ARN""" sandbox_idle_timeout_in_seconds: Optional[int] = None - """沙箱空闲超时时间(秒)""" + """沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)""" sandbox_ttlin_seconds: Optional[int] = None - """沙箱存活时间(秒)""" + """沙箱存活时间(秒) / Sandbox TTL (seconds)""" share_concurrency_limit_per_sandbox: Optional[int] = None - """每个沙箱的最大并发会话数""" + """每个沙箱的最大并发会话数 / Max Concurrency Limit Per Sandbox""" template_configuration: Optional[Dict] = None - """模板配置""" + """模板配置 / Template Configuration""" environment_variables: Optional[Dict] = None - """环境变量""" + """环境变量 / Environment Variables""" network_configuration: Optional[TemplateNetworkConfiguration] = None - """网络配置""" + """网络配置 / Network Configuration""" oss_configuration: Optional[List[TemplateOssConfiguration]] = None - """OSS 配置列表""" + """OSS 配置列表 / OSS Configuration List""" log_configuration: Optional[TemplateLogConfiguration] = None - """日志配置""" + """日志配置 / Log Configuration""" credential_configuration: Optional[TemplateCredentialConfiguration] = None - """凭证配置""" + """凭证配置 / Credential Configuration""" container_configuration: Optional[TemplateContainerConfiguration] = None - """容器配置""" + """容器配置 / Container Configuration""" mcp_options: Optional[TemplateMcpOptions] = None - """MCP 选项""" + """MCP 选项 / MCP Options""" mcp_state: Optional[TemplateMcpState] = None - """MCP 状态""" + """MCP 状态 / MCP State""" + allow_anonymous_manage: Optional[bool] = None + """是否允许匿名管理 / Whether to allow anonymous management""" created_at: Optional[str] = None - """创建时间""" + """创建时间 / Creation Time""" last_updated_at: Optional[str] = None - """最后更新时间""" + """最后更新时间 / Last Updated Time""" status: Optional[str] = None - """状态""" + """状态 / Status""" status_reason: Optional[str] = None - """状态原因""" + """状态原因 / Status Reason""" @classmethod def __get_client(cls, config: Optional[Config] = None): diff --git a/agentrun/sandbox/aio_sandbox.py b/agentrun/sandbox/aio_sandbox.py index 7b4d5e3..d848021 100644 --- a/agentrun/sandbox/aio_sandbox.py +++ b/agentrun/sandbox/aio_sandbox.py @@ -763,8 +763,7 @@ def __enter__(self): except Exception as e: logger.error( - f"[{retry_count}/{max_retries}] Health check failed," - f" retrying: {e}" + f"[{retry_count}/{max_retries}] Health check failed: {e}" ) if retry_count < max_retries: @@ -806,8 +805,12 @@ async def check_health_async(self): """Check sandbox health status (async).""" return await self.data_api.check_health_async() + # ======================================== + # Browser API Methods + # ======================================== + def check_health(self): - """Check sandbox health status (sync).""" + """Check sandbox health status (async).""" return self.data_api.check_health() # ======================================== @@ -868,8 +871,12 @@ async def delete_recording_async(self, filename: str): """Delete a recording file (async).""" return await self.data_api.delete_recording_async(filename) + # ======================================== + # Code Interpreter API Properties + # ======================================== + def delete_recording(self, filename: str): - """Delete a recording file (sync).""" + """Delete a recording file (async).""" return self.data_api.delete_recording(filename) # ======================================== diff --git a/agentrun/sandbox/api/__sandbox_data_async_template.py b/agentrun/sandbox/api/__sandbox_data_async_template.py index dbd2db6..1cfd165 100644 --- a/agentrun/sandbox/api/__sandbox_data_async_template.py +++ b/agentrun/sandbox/api/__sandbox_data_async_template.py @@ -4,7 +4,7 @@ This template is used to generate sandbox data API code. """ -from typing import Optional +from typing import Any, Dict, Optional from agentrun.utils.config import Config from agentrun.utils.data_api import DataAPI, ResourceType @@ -70,16 +70,23 @@ async def create_sandbox_async( self, template_name: str, sandbox_idle_timeout_seconds: Optional[int] = 600, + nas_config: Optional[Dict[str, Any]] = None, + oss_mount_config: Optional[Dict[str, Any]] = None, + polar_fs_config: Optional[Dict[str, Any]] = None, config: Optional[Config] = None, ): self.__refresh_access_token(template_name=template_name, config=config) - return await self.post_async( - "/", - data={ - "templateName": template_name, - "sandboxIdleTimeoutSeconds": sandbox_idle_timeout_seconds, - }, - ) + data: Dict[str, Any] = { + "templateName": template_name, + "sandboxIdleTimeoutSeconds": sandbox_idle_timeout_seconds, + } + if nas_config is not None: + data["nasConfig"] = nas_config + if oss_mount_config is not None: + data["ossMountConfig"] = oss_mount_config + if polar_fs_config is not None: + data["polarFsConfig"] = polar_fs_config + return await self.post_async("/", data=data) async def delete_sandbox_async( self, sandbox_id: str, config: Optional[Config] = None diff --git a/agentrun/sandbox/api/control.py b/agentrun/sandbox/api/control.py index 0a8fbe5..c1fc3d0 100644 --- a/agentrun/sandbox/api/control.py +++ b/agentrun/sandbox/api/control.py @@ -30,7 +30,7 @@ ) from alibabacloud_tea_openapi.exceptions._client import ClientException from alibabacloud_tea_openapi.exceptions._server import ServerException -from alibabacloud_tea_util.models import RuntimeOptions +from darabonba.runtime import RuntimeOptions import pydash from agentrun.utils.config import Config diff --git a/agentrun/sandbox/api/sandbox_data.py b/agentrun/sandbox/api/sandbox_data.py index aa2c299..e97834a 100644 --- a/agentrun/sandbox/api/sandbox_data.py +++ b/agentrun/sandbox/api/sandbox_data.py @@ -14,7 +14,7 @@ This template is used to generate sandbox data API code. """ -from typing import Optional +from typing import Any, Dict, Optional from agentrun.utils.config import Config from agentrun.utils.data_api import DataAPI, ResourceType @@ -83,31 +83,45 @@ async def create_sandbox_async( self, template_name: str, sandbox_idle_timeout_seconds: Optional[int] = 600, + nas_config: Optional[Dict[str, Any]] = None, + oss_mount_config: Optional[Dict[str, Any]] = None, + polar_fs_config: Optional[Dict[str, Any]] = None, config: Optional[Config] = None, ): self.__refresh_access_token(template_name=template_name, config=config) - return await self.post_async( - "/", - data={ - "templateName": template_name, - "sandboxIdleTimeoutSeconds": sandbox_idle_timeout_seconds, - }, - ) + data: Dict[str, Any] = { + "templateName": template_name, + "sandboxIdleTimeoutSeconds": sandbox_idle_timeout_seconds, + } + if nas_config is not None: + data["nasConfig"] = nas_config + if oss_mount_config is not None: + data["ossMountConfig"] = oss_mount_config + if polar_fs_config is not None: + data["polarFsConfig"] = polar_fs_config + return await self.post_async("/", data=data) def create_sandbox( self, template_name: str, sandbox_idle_timeout_seconds: Optional[int] = 600, + nas_config: Optional[Dict[str, Any]] = None, + oss_mount_config: Optional[Dict[str, Any]] = None, + polar_fs_config: Optional[Dict[str, Any]] = None, config: Optional[Config] = None, ): self.__refresh_access_token(template_name=template_name, config=config) - return self.post( - "/", - data={ - "templateName": template_name, - "sandboxIdleTimeoutSeconds": sandbox_idle_timeout_seconds, - }, - ) + data: Dict[str, Any] = { + "templateName": template_name, + "sandboxIdleTimeoutSeconds": sandbox_idle_timeout_seconds, + } + if nas_config is not None: + data["nasConfig"] = nas_config + if oss_mount_config is not None: + data["ossMountConfig"] = oss_mount_config + if polar_fs_config is not None: + data["polarFsConfig"] = polar_fs_config + return self.post("/", data=data) async def delete_sandbox_async( self, sandbox_id: str, config: Optional[Config] = None diff --git a/agentrun/sandbox/browser_sandbox.py b/agentrun/sandbox/browser_sandbox.py index f9639cd..42b05f3 100644 --- a/agentrun/sandbox/browser_sandbox.py +++ b/agentrun/sandbox/browser_sandbox.py @@ -51,7 +51,7 @@ async def __aenter__(self): logger.debug( f"[{retry_count}/{max_retries}] Health status:" - f" {health.get('code')} { health.get('message')}", + f" {health.get('code')} {health.get('message')}", ) except Exception as e: @@ -88,7 +88,7 @@ def __enter__(self): logger.debug( f"[{retry_count}/{max_retries}] Health status:" - f" {health.get('code')} { health.get('message')}", + f" {health.get('code')} {health.get('message')}", ) except Exception as e: diff --git a/agentrun/sandbox/client.py b/agentrun/sandbox/client.py index 245e2db..e5ea9b7 100644 --- a/agentrun/sandbox/client.py +++ b/agentrun/sandbox/client.py @@ -15,7 +15,7 @@ """ import time -from typing import List, Optional, TYPE_CHECKING +from typing import Any, Dict, List, Optional, TYPE_CHECKING from alibabacloud_agentrun20250910.models import ( CreateTemplateInput, @@ -28,7 +28,10 @@ from agentrun.sandbox.model import ( ListSandboxesInput, ListSandboxesOutput, + NASConfig, + OSSMountConfig, PageableInput, + PolarFsConfig, TemplateInput, ) from agentrun.utils.config import Config @@ -495,25 +498,47 @@ async def create_sandbox_async( self, template_name: str, 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, ) -> Sandbox: - """创建 Sandbox(异步) + """创建 Sandbox(异步) / Create Sandbox (async) Args: - input: Sandbox 配置 - config: 配置对象 + template_name: 模板名称 / Template name + sandbox_idle_timeout_seconds: 沙箱空闲超时时间(秒) / Sandbox idle timeout (seconds) + nas_config: NAS 配置 / NAS configuration + oss_mount_config: OSS 挂载配置 / OSS mount configuration + polar_fs_config: PolarFS 配置 / PolarFS configuration + config: 配置对象 / Config object Returns: - Sandbox: 创建的 Sandbox 对象 + Sandbox: 创建的 Sandbox 对象 / Created Sandbox object Raises: - ClientError: 客户端错误 - ServerError: 服务器错误 + ClientError: 客户端错误 / Client error + ServerError: 服务器错误 / Server error """ + # 将配置对象转换为字典格式 + nas_config_dict: Optional[Dict[str, Any]] = None + if nas_config is not None: + nas_config_dict = nas_config.model_dump(by_alias=True) + + oss_mount_config_dict: Optional[Dict[str, Any]] = None + if oss_mount_config is not None: + oss_mount_config_dict = oss_mount_config.model_dump(by_alias=True) + + polar_fs_config_dict: Optional[Dict[str, Any]] = None + if polar_fs_config is not None: + polar_fs_config_dict = polar_fs_config.model_dump(by_alias=True) result = await self.__sandbox_data_api.create_sandbox_async( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, + nas_config=nas_config_dict, + oss_mount_config=oss_mount_config_dict, + polar_fs_config=polar_fs_config_dict, config=config, ) @@ -535,25 +560,47 @@ def create_sandbox( self, template_name: str, 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, ) -> Sandbox: - """创建 Sandbox(同步) + """创建 Sandbox(同步) / Create Sandbox (async) Args: - input: Sandbox 配置 - config: 配置对象 + template_name: 模板名称 / Template name + sandbox_idle_timeout_seconds: 沙箱空闲超时时间(秒) / Sandbox idle timeout (seconds) + nas_config: NAS 配置 / NAS configuration + oss_mount_config: OSS 挂载配置 / OSS mount configuration + polar_fs_config: PolarFS 配置 / PolarFS configuration + config: 配置对象 / Config object Returns: - Sandbox: 创建的 Sandbox 对象 + Sandbox: 创建的 Sandbox 对象 / Created Sandbox object Raises: - ClientError: 客户端错误 - ServerError: 服务器错误 + ClientError: 客户端错误 / Client error + ServerError: 服务器错误 / Server error """ + # 将配置对象转换为字典格式 + nas_config_dict: Optional[Dict[str, Any]] = None + if nas_config is not None: + nas_config_dict = nas_config.model_dump(by_alias=True) + + oss_mount_config_dict: Optional[Dict[str, Any]] = None + if oss_mount_config is not None: + oss_mount_config_dict = oss_mount_config.model_dump(by_alias=True) + + polar_fs_config_dict: Optional[Dict[str, Any]] = None + if polar_fs_config is not None: + polar_fs_config_dict = polar_fs_config.model_dump(by_alias=True) result = self.__sandbox_data_api.create_sandbox( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, + nas_config=nas_config_dict, + oss_mount_config=oss_mount_config_dict, + polar_fs_config=polar_fs_config_dict, config=config, ) diff --git a/agentrun/sandbox/model.py b/agentrun/sandbox/model.py index 2249e93..8301396 100644 --- a/agentrun/sandbox/model.py +++ b/agentrun/sandbox/model.py @@ -5,7 +5,7 @@ """ from enum import Enum -from typing import Dict, List, Optional, TYPE_CHECKING +from typing import Any, Dict, List, Optional, TYPE_CHECKING import uuid from pydantic import model_validator @@ -53,6 +53,108 @@ class CodeLanguage(str, Enum): PYTHON = "python" +# ==================== NAS 配置相关 ==================== + + +class NASMountConfig(BaseModel): + """NAS 挂载配置 / NAS Mount Configuration + + 定义 NAS 文件系统的挂载配置。 + Defines the mount configuration for NAS file system. + """ + + enable_tls: Optional[bool] = None + """是否启用 TLS 加密 / Whether to enable TLS encryption""" + mount_dir: Optional[str] = None + """挂载目录 / Mount Directory""" + server_addr: Optional[str] = None + """NAS 服务器地址 / NAS Server Address""" + + +class NASConfig(BaseModel): + """NAS 配置 / NAS Configuration + + 定义 NAS 文件系统的配置。 + Defines the configuration for NAS file system. + """ + + group_id: Optional[int] = None + """组 ID / Group ID""" + mount_points: Optional[List[NASMountConfig]] = None + """挂载点列表 / Mount Points List""" + user_id: Optional[int] = None + """用户 ID / User ID""" + + +# ==================== OSS 挂载配置相关 ==================== + + +class OSSMountPoint(BaseModel): + """OSS 挂载点 / OSS Mount Point + + 定义 OSS 存储的挂载点配置。 + Defines the mount point configuration for OSS storage. + """ + + bucket_name: Optional[str] = None + """OSS 存储桶名称 / OSS Bucket Name""" + bucket_path: Optional[str] = None + """OSS 存储桶路径 / OSS Bucket Path""" + endpoint: Optional[str] = None + """OSS 端点 / OSS Endpoint""" + mount_dir: Optional[str] = None + """挂载目录 / Mount Directory""" + read_only: Optional[bool] = None + """是否只读 / Read Only""" + + +class OSSMountConfig(BaseModel): + """OSS 挂载配置 / OSS Mount Configuration + + 定义 OSS 存储的挂载配置。 + Defines the mount configuration for OSS storage. + """ + + mount_points: Optional[List[OSSMountPoint]] = None + """挂载点列表 / Mount Points List""" + + +# ==================== PolarFS 配置相关 ==================== + + +class PolarFsMountConfig(BaseModel): + """PolarFS 挂载配置 / PolarFS Mount Configuration + + 定义 PolarFS 文件系统的挂载配置。 + Defines the mount configuration for PolarFS file system. + """ + + instance_id: Optional[str] = None + """实例 ID / Instance ID""" + mount_dir: Optional[str] = None + """挂载目录 / Mount Directory""" + remote_dir: Optional[str] = None + """远程目录 / Remote Directory""" + + +class PolarFsConfig(BaseModel): + """PolarFS 配置 / PolarFS Configuration + + 定义 PolarFS 文件系统的配置。 + Defines the configuration for PolarFS file system. + """ + + group_id: Optional[int] = None + """组 ID / Group ID""" + mount_points: Optional[List[PolarFsMountConfig]] = None + """挂载点列表 / Mount Points List""" + user_id: Optional[int] = None + """用户 ID / User ID""" + + +# ==================== 模板配置相关 ==================== + + class TemplateNetworkConfiguration(BaseModel): """沙箱模板网络配置 / Sandbox Template Network Configuration""" @@ -180,6 +282,8 @@ class TemplateInput(BaseModel): """容器配置 / Container Configuration""" disk_size: Optional[int] = None """磁盘大小(GB) / Disk Size (GB)""" + allow_anonymous_manage: Optional[bool] = None + """是否允许匿名管理 / Whether to allow anonymous management""" @model_validator(mode="before") @classmethod @@ -256,6 +360,14 @@ class SandboxInput(BaseModel): """模板名称 / Template Name""" sandbox_idle_timeout_seconds: Optional[int] = 600 """沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)""" + sandbox_id: Optional[str] = None + """沙箱 ID(可选,用户可指定) / Sandbox ID (optional, user can specify)""" + nas_config: Optional[NASConfig] = None + """NAS 配置 / NAS Configuration""" + oss_mount_config: Optional[OSSMountConfig] = None + """OSS 挂载配置 / OSS Mount Configuration""" + polar_fs_config: Optional[PolarFsConfig] = None + """PolarFS 配置 / PolarFS Configuration""" class ListSandboxesInput(BaseModel): diff --git a/agentrun/sandbox/sandbox.py b/agentrun/sandbox/sandbox.py index 57653bb..dcffab0 100644 --- a/agentrun/sandbox/sandbox.py +++ b/agentrun/sandbox/sandbox.py @@ -14,7 +14,16 @@ This module defines the high-level API for sandbox resources. """ -from typing import List, Literal, Optional, overload, TYPE_CHECKING, Union +from typing import ( + Any, + Dict, + List, + Literal, + Optional, + overload, + TYPE_CHECKING, + Union, +) from agentrun.sandbox.model import TemplateType from agentrun.utils.config import Config @@ -27,7 +36,10 @@ from agentrun.sandbox.model import ( ListSandboxesInput, ListSandboxesOutput, + NASConfig, + OSSMountConfig, PageableInput, + PolarFsConfig, TemplateInput, ) from agentrun.sandbox.template import Template @@ -42,23 +54,29 @@ class Sandbox(BaseModel): _template_type: Optional[TemplateType] created_at: Optional[str] = None - """沙箱创建时间""" + """沙箱创建时间 / Sandbox creation time""" + ended_at: Optional[str] = None + """沙箱结束时间 / Sandbox end time""" last_updated_at: Optional[str] = None - """最后更新时间""" + """最后更新时间 / Last updated time""" + metadata: Optional[Dict[str, Any]] = None + """元数据 / Metadata""" sandbox_arn: Optional[str] = None - """沙箱全局唯一资源名称""" + """沙箱全局唯一资源名称 / Sandbox ARN""" sandbox_id: Optional[str] = None - """沙箱 ID""" + """沙箱 ID / Sandbox ID""" + sandbox_idle_ttlin_seconds: Optional[int] = None + """沙箱空闲 TTL(秒) / Sandbox Idle TTL (seconds)""" sandbox_idle_timeout_seconds: Optional[int] = None - """沙箱空闲超时时间(秒)""" + """沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)""" status: Optional[str] = None - """沙箱状态""" + """沙箱状态 / Sandbox status""" template_id: Optional[str] = None - """模板 ID""" + """模板 ID / Template ID""" template_name: Optional[str] = None - """模板名称""" + """模板名称 / Template name""" _config: Optional[Config] = None - """配置对象,用于子类的 data_api 初始化""" + """配置对象,用于子类的 data_api 初始化 / Config object for data_api initialization""" @classmethod def __get_client(cls): @@ -74,6 +92,9 @@ async def create_async( template_type: Literal[TemplateType.CODE_INTERPRETER], 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, ) -> "CodeInterpreterSandbox": ... @@ -85,6 +106,9 @@ def create( template_type: Literal[TemplateType.CODE_INTERPRETER], 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, ) -> "CodeInterpreterSandbox": ... @@ -96,6 +120,9 @@ async def create_async( template_type: Literal[TemplateType.BROWSER], 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, ) -> "BrowserSandbox": ... @@ -107,6 +134,9 @@ def create( template_type: Literal[TemplateType.BROWSER], 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, ) -> "BrowserSandbox": ... @@ -118,6 +148,9 @@ async def create_async( template_type: Literal[TemplateType.AIO], 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, ) -> "AioSandbox": ... @@ -129,6 +162,9 @@ def create( template_type: Literal[TemplateType.AIO], 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, ) -> "AioSandbox": ... @@ -139,6 +175,9 @@ async def create_async( template_type: TemplateType, 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, ) -> Union["CodeInterpreterSandbox", "BrowserSandbox", "AioSandbox"]: @@ -166,6 +205,9 @@ async def create_async( base_sandbox = await cls.__get_client().create_sandbox_async( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, + nas_config=nas_config, + oss_mount_config=oss_mount_config, + polar_fs_config=polar_fs_config, ) # 根据 template 类型转换为对应的子类实例 @@ -196,6 +238,9 @@ def create( template_type: TemplateType, 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, ) -> Union["CodeInterpreterSandbox", "BrowserSandbox", "AioSandbox"]: @@ -223,6 +268,9 @@ def create( base_sandbox = cls.__get_client().create_sandbox( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, + nas_config=nas_config, + oss_mount_config=oss_mount_config, + polar_fs_config=polar_fs_config, ) # 根据 template 类型转换为对应的子类实例 diff --git a/agentrun/sandbox/template.py b/agentrun/sandbox/template.py index 59ab741..f5bbb4d 100644 --- a/agentrun/sandbox/template.py +++ b/agentrun/sandbox/template.py @@ -39,59 +39,61 @@ class Template(BaseModel): """ template_id: Optional[str] = None - """模板 ID""" + """模板 ID / Template ID""" template_name: Optional[str] = None - """模板名称""" + """模板名称 / Template Name""" template_version: Optional[str] = None - """模板版本""" + """模板版本 / Template Version""" template_arn: Optional[str] = None - """模板 ARN""" + """模板 ARN / Template ARN""" resource_name: Optional[str] = None - """资源名称""" + """资源名称 / Resource Name""" template_type: Optional[TemplateType] = None - """模板类型""" + """模板类型 / Template Type""" cpu: Optional[float] = None - """CPU 核数""" + """CPU 核数 / CPU Cores""" memory: Optional[int] = None - """内存大小(MB)""" + """内存大小(MB) / Memory Size (MB)""" disk_size: Optional[int] = None - """磁盘大小(GB)""" + """磁盘大小(GB) / Disk Size (GB)""" description: Optional[str] = None - """描述""" + """描述 / Description""" execution_role_arn: Optional[str] = None - """执行角色 ARN""" + """执行角色 ARN / Execution Role ARN""" sandbox_idle_timeout_in_seconds: Optional[int] = None - """沙箱空闲超时时间(秒)""" + """沙箱空闲超时时间(秒) / Sandbox Idle Timeout (seconds)""" sandbox_ttlin_seconds: Optional[int] = None - """沙箱存活时间(秒)""" + """沙箱存活时间(秒) / Sandbox TTL (seconds)""" share_concurrency_limit_per_sandbox: Optional[int] = None - """每个沙箱的最大并发会话数""" + """每个沙箱的最大并发会话数 / Max Concurrency Limit Per Sandbox""" template_configuration: Optional[Dict] = None - """模板配置""" + """模板配置 / Template Configuration""" environment_variables: Optional[Dict] = None - """环境变量""" + """环境变量 / Environment Variables""" network_configuration: Optional[TemplateNetworkConfiguration] = None - """网络配置""" + """网络配置 / Network Configuration""" oss_configuration: Optional[List[TemplateOssConfiguration]] = None - """OSS 配置列表""" + """OSS 配置列表 / OSS Configuration List""" log_configuration: Optional[TemplateLogConfiguration] = None - """日志配置""" + """日志配置 / Log Configuration""" credential_configuration: Optional[TemplateCredentialConfiguration] = None - """凭证配置""" + """凭证配置 / Credential Configuration""" container_configuration: Optional[TemplateContainerConfiguration] = None - """容器配置""" + """容器配置 / Container Configuration""" mcp_options: Optional[TemplateMcpOptions] = None - """MCP 选项""" + """MCP 选项 / MCP Options""" mcp_state: Optional[TemplateMcpState] = None - """MCP 状态""" + """MCP 状态 / MCP State""" + allow_anonymous_manage: Optional[bool] = None + """是否允许匿名管理 / Whether to allow anonymous management""" created_at: Optional[str] = None - """创建时间""" + """创建时间 / Creation Time""" last_updated_at: Optional[str] = None - """最后更新时间""" + """最后更新时间 / Last Updated Time""" status: Optional[str] = None - """状态""" + """状态 / Status""" status_reason: Optional[str] = None - """状态原因""" + """状态原因 / Status Reason""" @classmethod def __get_client(cls, config: Optional[Config] = None): diff --git a/agentrun/toolset/api/control.py b/agentrun/toolset/api/control.py index 80531e5..9a37db9 100644 --- a/agentrun/toolset/api/control.py +++ b/agentrun/toolset/api/control.py @@ -21,7 +21,7 @@ ) from alibabacloud_tea_openapi.exceptions._client import ClientException from alibabacloud_tea_openapi.exceptions._server import ServerException -from alibabacloud_tea_util.models import RuntimeOptions +from darabonba.runtime import RuntimeOptions import pydash from agentrun.utils.config import Config diff --git a/agentrun/toolset/toolset.py b/agentrun/toolset/toolset.py index 3373f85..bd417fb 100644 --- a/agentrun/toolset/toolset.py +++ b/agentrun/toolset/toolset.py @@ -22,6 +22,7 @@ from agentrun.utils.log import logger from agentrun.utils.model import BaseModel +from .api.openapi import OpenAPI from .model import ( MCPServerConfig, SchemaType, diff --git a/codegen/templates/control_api.jinja2 b/codegen/templates/control_api.jinja2 index 298d9ca..ab248d9 100644 --- a/codegen/templates/control_api.jinja2 +++ b/codegen/templates/control_api.jinja2 @@ -15,7 +15,7 @@ from agentrun.utils.control_api import ControlAPI {% endfor %} from alibabacloud_agentrun20250910.models import {{ method.return_type }} {% endfor %} -from alibabacloud_tea_util.models import RuntimeOptions +from darabonba.runtime import RuntimeOptions from agentrun.utils.exception import ClientError, ServerError from alibabacloud_tea_openapi.exceptions._client import ClientException from alibabacloud_tea_openapi.exceptions._server import ServerException diff --git a/codegen/templates/devs_api.jinja2 b/codegen/templates/devs_api.jinja2 index b185165..515ec84 100644 --- a/codegen/templates/devs_api.jinja2 +++ b/codegen/templates/devs_api.jinja2 @@ -15,7 +15,7 @@ from agentrun.utils.control_api import ControlAPI {% endfor %} from alibabacloud_devs20230714.models import {{ method.return_type }} {% endfor %} -from alibabacloud_tea_util.models import RuntimeOptions +from darabonba.runtime import RuntimeOptions from agentrun.utils.exception import ClientError, ServerError from alibabacloud_tea_openapi.exceptions._client import ClientException from alibabacloud_tea_openapi.exceptions._server import ServerException diff --git a/pyproject.toml b/pyproject.toml index bd6afb4..1a7efd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "litellm>=1.79.3", "alibabacloud-devs20230714>=2.4.1", "pydash>=8.0.5", - "alibabacloud-agentrun20250910>=4.0.3", + "alibabacloud-agentrun20250910>=5.0.0", "alibabacloud_tea_openapi>=0.4.2", ]