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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions