Skip to content

[Feature Request] SandboxToolSet 及其子类应支持 oss_mount_config 参数透传 #54

@XeonYang

Description

@XeonYang

优先级: P2(功能缺失,有 workaround)
agentrun-sdk 版本: 0.0.21(PyPI 最新)
GitHub: https://github.com/Serverless-Devs/agentrun-sdk-python


问题描述

底层 Sandbox.create() API 对所有模板类型(CODE_INTERPRETERBROWSERAIOCUSTOM)都支持 oss_mount_config 参数,可以在创建沙箱时动态添加 OSS 挂载点。但上层的 SandboxToolSet(以及继承它的 CodeInterpreterToolSetBrowserToolSet)完全没有暴露此参数,导致用户无法通过 ToolSet 使用实例级 OSS 挂载功能。

根因分析

1. 底层 API 支持 oss_mount_config

agentrun/sandbox/sandbox.pySandbox.create() 的签名(以 BROWSER 为例):

# sandbox.py line 133-143 (overload for BROWSER)
@classmethod
@overload
def create(
    cls,
    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":
    ...

所有四种模板类型的 overload 都包含 oss_mount_config 参数,最终传递给 create_sandbox() 发送到 AgentRun 云端 API。

2. ToolSet 层没有透传

agentrun/integration/builtin/sandbox.py 中基类 SandboxToolSet 的构造函数和 _ensure_sandbox 方法:

# sandbox.py line 22-67
class SandboxToolSet(CommonToolSet):
    def __init__(
        self,
        template_name: str,
        template_type: TemplateType,
        *,
        sandbox_idle_timeout_seconds: int,
        config: Optional[Config],
        # ← 没有 oss_mount_config 参数
    ):
        ...

    def _ensure_sandbox(self):
        if self.sandbox is not None:
            return self.sandbox
        with self.lock:
            if self.sandbox is None:
                self.sandbox = Sandbox.create(
                    template_type=self.template_type,
                    template_name=self.template_name,
                    sandbox_idle_timeout_seconds=self.sandbox_idle_timeout_seconds,
                    config=self.config,
                    # ← 没有传递 oss_mount_config
                )
                ...

两个子类 CodeInterpreterToolSetBrowserToolSet 的构造函数同样没有 oss_mount_config

# CodeInterpreterToolSet.__init__
def __init__(self, template_name, config, sandbox_idle_timeout_seconds):
    super().__init__(template_name=..., template_type=TemplateType.CODE_INTERPRETER, ...)

# BrowserToolSet.__init__
def __init__(self, template_name, config, sandbox_idle_timeout_seconds):
    super().__init__(template_name=..., template_type=TemplateType.BROWSER, ...)

影响

使用 ToolSet 高层 API 的用户完全无法为沙箱添加实例级 OSS 挂载,必须通过 monkey-patch _ensure_sandbox 方法绕过。这对于需要为每个会话创建独立 OSS 挂载路径的场景(如多用户隔离的文件读写)来说是必要功能。

当前 Workaround

我们通过创建 wrapper 类(如 CodeInterpreterToolSetWithOSSBrowserToolSetWithOSS),在内部 monkey-patch _ensure_sandbox 方法来注入 oss_mount_config

class CodeInterpreterToolSetWithOSS:
    def __init__(self, template_name, sandbox_idle_timeout_seconds, oss_mount_config=None, ...):
        self._toolset = CodeInterpreterToolSet(template_name=..., config=None, ...)
        if oss_mount_config:
            self._patch_sandbox_creation()

    def _patch_sandbox_creation(self):
        toolset = self._toolset
        oss_config = self._oss_mount_config

        def patched_ensure_sandbox():
            if toolset.sandbox is not None:
                return toolset.sandbox
            with toolset.lock:
                if toolset.sandbox is None:
                    toolset.sandbox = Sandbox.create(
                        template_type=TemplateType.CODE_INTERPRETER,
                        template_name=toolset.template_name,
                        sandbox_idle_timeout_seconds=toolset.sandbox_idle_timeout_seconds,
                        oss_mount_config=oss_config,  # ← 手动注入
                        config=toolset.config,
                    )
                    ...
        self._toolset._ensure_sandbox = patched_ensure_sandbox

BrowserToolSet 同理。

建议修复方案

SandboxToolSet 基类中增加 oss_mount_config 参数支持:

class SandboxToolSet(CommonToolSet):
    def __init__(
        self,
        template_name: str,
        template_type: TemplateType,
        *,
        sandbox_idle_timeout_seconds: int,
        config: Optional[Config],
        oss_mount_config: Optional[OSSMountConfig] = None,    # 新增
        nas_config: Optional[NASConfig] = None,               # 新增(一致性)
    ):
        ...
        self.oss_mount_config = oss_mount_config
        self.nas_config = nas_config

    def _ensure_sandbox(self):
        ...
        self.sandbox = Sandbox.create(
            template_type=self.template_type,
            template_name=self.template_name,
            sandbox_idle_timeout_seconds=self.sandbox_idle_timeout_seconds,
            oss_mount_config=self.oss_mount_config,    # 透传
            nas_config=self.nas_config,                # 透传
            config=self.config,
        )

同步修改 CodeInterpreterToolSet.__init__BrowserToolSet.__init__ 的签名,将 oss_mount_config 透传给基类。


环境信息

项目
agentrun-sdk 版本 0.0.21(PyPI 最新)
Python 版本 3.12
OS macOS (darwin 23.6.0)
影响的 ToolSet CodeInterpreterToolSet、BrowserToolSet
影响的沙箱类型 所有类型(CODE_INTERPRETER、BROWSER、AIO、CUSTOM)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions