Repository navigation
code_executors/cube: support Tencent AGS client configuration - #340
Conversation
Add a provider-specific configuration adapter for Tencent Cloud Agent Sandbox while preserving the existing Cube sandbox client and workspace runtime. Cover endpoint precedence, request options, creation metadata, public exports, and bilingual documentation. RELEASE NOTES: Cube workspaces can now connect to Tencent Cloud Agent Sandbox through TencentAGSClientConfig.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #340 +/- ##
==========================================
Coverage ? 87.32594%
==========================================
Files ? 527
Lines ? 50915
Branches ? 0
==========================================
Hits ? 44462
Misses ? 6453
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
AI Code Review审查结论不通过 审查范围:46f98c6..b0c9350,共 10 个文件、+346/-14。计划“code_executors/cube: support Tencent AGS client configuration”总体已实现:新增 TencentAGSClientConfig(domain/E2B_DOMAIN、validate_api_key、request_timeout、metadata 字段及校验),在 CubeClientConfig 上增加 _e2b_connection_kwargs/_e2b_create_kwargs 提供者适配缝,CubeSandboxClient.open_new/open_existing 改经该缝转发;导出、文档(中英文)、示例 README 与 144 行单元测试配套齐全;基础 CubeClientConfig 的 kwargs 与变更前逐字一致(test_sandbox.py 有断言),dataclasses.replace/auto_recover 重建路径对子类兼容。主要风险:端点选择的优先级契约与真实 e2b SDK 行为不一致——当选择 domain 时不传 api_url,SDK 的 ConnectionConfig 会回退读取 E2B_API_URL 环境变量并覆盖显式 domain(SDK 源码证实),导致 AGS 流量被静默路由到错误端点;新增测试仅断言 mock 层 kwargs,固化了与真实 SDK 相反的错误契约。次要问题:示例 README 的 AGS 引导与示例代码(仍要求 E2B_API_URL 的 CubeClientConfig)及 .env 占位符不一致;domain 字段缺少格式校验,完整 URL 会被 SDK 拼出非法端点。测试影响:20 个左右的单元测试覆盖了默认值、环境变量回退、kwargs 形状、超时校验、metadata 拷贝等成功/失败路径,质量良好,但所有 e2b 交互均经 fake 模拟,无法捕获 SDK 侧环境变量合并行为(即 SEVERE 问题的根因)。门禁结论:存在由本变更引入、可复现且使核心 AGS 连接功能在真实环境中失效的高置信缺陷,判定 FAILED。 发现的问题严重
问题: 触发条件: 用户按 docs/mkdocs 或 examples 的 AGS 用法传入 实际影响: AGS API Key 会被发送到 修正方向: 在生成 kwargs 时消除 SDK 的环境变量回退窗口:当选择 较低
问题: 本次变更删除了示例对环境变量清单中 触发条件: 用户按更新后的 README 只设置 实际影响: 运行示例时 修正方向: 要么将 较低
问题: 新增的 触发条件: 用户把 AGS 控制台展示的完整端点(如 实际影响: SDK 拼出 修正方向: 在 |
| def _e2b_connection_kwargs(self) -> dict[str, Any]: | ||
| if self.api_url: | ||
| endpoint = {"api_url": self.api_url} | ||
| elif self.domain: | ||
| endpoint = {"domain": self.domain} | ||
| else: | ||
| api_url = os.getenv(ENV_API_URL) | ||
| endpoint = {"api_url": api_url} if api_url else {"domain": self.resolve_domain()} | ||
| kwargs: dict[str, Any] = { | ||
| **endpoint, | ||
| "api_key": self.resolve_api_key(), | ||
| "validate_api_key": self.validate_api_key, | ||
| } | ||
| if self.request_timeout is not None: | ||
| kwargs["request_timeout"] = self.request_timeout | ||
| return kwargs |
There was a problem hiding this comment.
问题: _e2b_connection_kwargs() 在选择 domain 端点时不输出 api_url 键,但底层 e2b SDK 的 ConnectionConfig.__init__ 会按 api_url = 显式参数 or os.getenv("E2B_API_URL") or f"https://api.{domain}" 解析(见 e2b-dev/e2b 仓库 packages/python-sdk/e2b/connection_config.py)。因此只要进程环境里残留 E2B_API_URL,SDK 就会忽略显式传入的 domain,实际连接环境变量指向的端点——与本方法及本提交新增文档声明的“显式字段始终优先于环境变量”“显式 api_url 优先于 domain”契约相反。新增测试 test_explicit_domain_takes_precedence_over_environment_api_url 只断言 mock 收到的 kwargs 不含 api_url 并据此宣称 domain 优先,属于断言了与真实 SDK 行为相反的契约,给该缺陷提供了虚假的保护。
触发条件: 用户按 docs/mkdocs 或 examples 的 AGS 用法传入 TencentAGSClientConfig(domain="ap-guangzhou.tencentags.com", api_key=..., ...),同时进程环境仍保留 E2B_API_URL(本仓库历来把该变量文档化为通用 Cube/E2B 网关标准变量,见 examples/code_executors/cube_demo.py、docs/mkdocs/en/code_executor.md,且本次变更未改动的 examples/skills_with_cube/.env 仍包含其占位符);从通用 E2B 迁移到 AGS 的用户几乎必然携带该环境变量。
实际影响: AGS API Key 会被发送到 E2B_API_URL 指向的错误网关,产生不明原因的 401/template-not-found;若该环境变量恰好指向其他地域的 AGS 兼容网关,则沙箱会被静默创建在错误地域(数据驻留违规),且无任何诊断信息;同一份配置在有无该环境变量的两台机器上行为不同,甚至一个用户先跑过通用 E2B 示例就足以踩中。
修正方向: 在生成 kwargs 时消除 SDK 的环境变量回退窗口:当选择 domain 分支时,若检测到 E2B_API_URL 环境变量已设置,应显式计算并同时传入 api_url(如按 SDK 规则生成 https://api.{domain})或在构造期抛出明确冲突错误;同时补充一个集成式测试用真实 SDK 语义(而非仅 mock kwargs)验证“显式 domain 覆盖环境变量”,并修正 test_explicit_domain_takes_precedence_over_environment_api_url 当前的错误断言(它断言的是传递形状,不是实际生效端点)。
| - `E2B_API_KEY=your-e2b-api-key` | ||
|
|
||
| 通用 E2B/Cube 网关配置: | ||
|
|
||
| - `E2B_API_URL=your-e2b-api-url` | ||
|
|
||
| 腾讯云 Agent Sandbox 可改用 `TencentAGSClientConfig`,并配置: | ||
|
|
||
| - `E2B_DOMAIN=ap-guangzhou.tencentags.com` | ||
|
|
||
| ```python | ||
| from trpc_agent_sdk.code_executors.cube import TencentAGSClientConfig | ||
|
|
||
| cfg = TencentAGSClientConfig( | ||
| request_timeout=60, | ||
| metadata={"application": "skills-with-cube"}, | ||
| auto_recover=True, | ||
| ) | ||
| ``` | ||
|
|
||
| `TencentAGSClientConfig` 默认关闭 E2B SDK 对 AGS API Key 的本地格式校验; |
There was a problem hiding this comment.
问题: 本次变更删除了示例对环境变量清单中 E2B_API_URL 的必填表述,并新增“腾讯云 Agent Sandbox 可改用 TencentAGSClientConfig,配置 E2B_DOMAIN 即可”的引导(含一段直接使用 TencentAGSClientConfig 的示例代码),但同一示例的 agent/tools.py(第 36-40 行 _cube_client_config())仍构造普通 CubeClientConfig 且不传 api_url,其端点解析硬性要求 E2B_API_URL;示例 run_agent.py 也并未改用 TencentAGSClientConfig。README 与示例代码之间形成了不一致的契约。
触发条件: 用户按更新后的 README 只设置 E2B_API_KEY、E2B_DOMAIN=ap-guangzhou.tencentags.com 而不设置 E2B_API_URL,直接运行 python3 run_agent.py;或按 README 的 AGS 小节尝试把 .env 改为仅提供 E2B_DOMAIN。
实际影响: 运行示例时 create_cube_sandbox_client 在 resolve_api_url() 抛出 ValueError: Cube sandbox requires api_url or E2B_API_URL env.,示例无法按新文档指引运行;若用户为让示例跑起来而把 .env 的 E2B_API_URL 填成真实旧值,又会触发前述 SEVERE 问题(环境变量覆盖 domain)导致连到错误网关。
修正方向: 要么将 agent/tools.py 的 _cube_client_config() 改为按 E2B_DOMAIN/TencentAGSClientConfig 可配置,要么在 README 中明确说明“本示例仍使用通用 E2B 网关,AGS 需自行按上文 TencentAGSClientConfig 代码接入”,并同步清理 .env 中的 E2B_API_URL 占位符,避免引导用户配置互相矛盾。
| def resolve_domain(self) -> str: | ||
| """Resolve the Tencent AGS domain from the field or environment.""" | ||
| value = self.domain or os.getenv(ENV_TENCENT_AGS_DOMAIN) | ||
| if not value: | ||
| raise ValueError("Tencent AGS requires `domain`, E2B_DOMAIN, or an explicit " | ||
| "`api_url` / E2B_API_URL.") | ||
| return value |
There was a problem hiding this comment.
问题: 新增的 domain 字段与 resolve_domain() 均未对取值做任何格式校验,值被原样透传给 SDK,而 e2b SDK 会把它拼进 f"https://api.{domain}"。同类新字段(request_timeout、validate_api_key)以及基类字段(idle_timeout、execute_timeout)在 __post_init__ 都有校验,唯独 domain 例外——任何字符串(包括带 scheme 的完整 URL、含路径的地址)都会静默通过构造期校验。
触发条件: 用户把 AGS 控制台展示的完整端点(如 https://ap-guangzhou.tencentags.com)当作 domain 传入(新文档将 domain 描述为“地域域名/endpoint”,容易按完整 URL 填写)。
实际影响: SDK 拼出 https://api.https://ap-guangzhou.tencentags.com 这类非法 URL,在请求阶段才以一次含混的 DNS/连接错误失败,用户无法从报错联想到是 domain 配置格式问题;而同类字段的错误都在构造期以明确消息暴露。
修正方向: 在 __post_init__ 中对 domain 增加轻量校验(拒绝 scheme、/、空白,或至少拒绝含 :// 与路径分隔符的取值,提示应填写裸域名或改用 api_url 字段),使非法配置在构造期即失败并给出可操作原因。
Derive and pass the AGS control-plane URL alongside its domain so stale E2B_API_URL values cannot override provider configuration. Validate bare domains, cover the real E2B ConnectionConfig behavior, and keep the generic Cube example provider-neutral. RELEASE NOTES: Tencent AGS Cube configuration now reliably overrides stale E2B endpoint environment values and rejects malformed domains early.
AI Code Review审查结论通过 审查范围:46f98c6..a5b5cfb(code_executors/cube: support Tencent AGS client configuration),共 9 个文件、397 增/13 删,含新增 发现的问题中等
问题: 触发条件: 环境中实际解析到的 e2b 版本低于 2.29.1(如 2026-06-16 之前创建、沿用旧上界 pin/锁文件的 Python ≥3.10 环境),或 实际影响: 老版本 e2b 上 AGS 功能以硬性 修正方向: 在声明依赖处加下界 中等
问题: 触发条件: 用户显式配置 实际影响: 前一种场景下,e2b SDK 的沙箱路由 修正方向: 将环境变量读取限制在无显式端点字段的情形: |
| kwargs: dict[str, Any] = { | ||
| **endpoint, | ||
| "api_key": self.resolve_api_key(), | ||
| "validate_api_key": self.validate_api_key, | ||
| } | ||
| if self.request_timeout is not None: | ||
| kwargs["request_timeout"] = self.request_timeout |
There was a problem hiding this comment.
问题: _e2b_connection_kwargs() 无条件向 AsyncSandbox.create/connect 透传 validate_api_key(以及 domain/request_timeout)关键字,但仓库依赖下限 e2b-code-interpreter>=2.0.0(pyproject.toml:128/172、requirements-test.txt:32,无上界、无锁文件)允许解析到不支持这些参数的老版本 e2b:api_url 参数自 e2b 2.3.4(2025-10-20,commit 8c77cb04)才加入,validate_api_key 自 e2b 2.29.1(2026-06-16,commit 78c200af)才加入,2.3.3 及更早版本的 ConnectionConfig.__init__ 没有 **kwargs 兜底。而 _sandbox.py 的 open_new/open_existing 已改为 create(**cfg._e2b_create_kwargs())、connect(cfg.sandbox_id, **cfg._e2b_connection_kwargs()),老 SDK 会将未知关键字展开进 ConnectionConfig(**opts) 直接崩溃。
触发条件: 环境中实际解析到的 e2b 版本低于 2.29.1(如 2026-06-16 之前创建、沿用旧上界 pin/锁文件的 Python ≥3.10 环境),或 e2b-code-interpreter 2.9.0 及更早(其约束为 e2b>=2.26.0,<3.0.0,可解析到不含 validate_api_key 的 2.26.0–2.29.0);此时任意 TencentAGSClientConfig(含默认 validate_api_key=False)调用 open_new/open_existing 即触发;且 CI 构建环境解析最新版 SDK,无法在合入时拦截。
实际影响: 老版本 e2b 上 AGS 功能以硬性 TypeError: ConnectionConfig.__init__() got an unexpected keyword argument 直接失败,无降级路径,且报错与 SDK 版本毫无关联,难以排查。
修正方向: 在声明依赖处加下界 e2b-code-interpreter>=2.10.0(其保证 e2b>=2.44.0,均含这两个参数),或在运行时对 ConnectionConfig.__init__ 做参数支持性探测并给出明确的版本升级指引。
| configured_domain = self.domain or os.getenv(ENV_TENCENT_AGS_DOMAIN) | ||
| domain = self.resolve_domain() if configured_domain else None | ||
|
|
||
| if self.api_url: | ||
| endpoint = {"api_url": self.api_url} | ||
| if domain is not None: | ||
| endpoint["domain"] = domain |
There was a problem hiding this comment.
问题: configured_domain = self.domain or os.getenv(ENV_TENCENT_AGS_DOMAIN) 在 self.api_url 已显式设置时仍读取并校验环境变量 E2B_DOMAIN,随后在第 91 行把该 env domain 作为 domain 关键字一并传入——直接违反类 docstring(第 30-32 行)与中英文档明文契约「Environment values are consulted only when neither endpoint field is set / 环境变量仅在两个端点字段都未设置时才生效」。
触发条件: 用户显式配置 api_url(文档推荐的网关/代理用法)而 domain 字段留空,且环境中残留或误设了 E2B_DOMAIN;包括两种子场景:环境值为合法但不同的域名(如旧配置 ap-shanghai.tencentags.com),或环境值为非法域名(如带 https:// 前缀,_validate_domain 会抛 ValueError)。
实际影响: 前一种场景下,e2b SDK 的沙箱路由 get_sandbox_url/Sandbox.__init__ 在网关响应未携带 sandbox_domain 时回退 self.domain 并生成 https://{port}-{id}.{env_domain},使沙箱数据面请求被劫持到错误的 region/域名,表现为偶发连不上或串区;后一种场景则让一个本可正常工作的 api_url-only 配置直接以 ValueError 崩溃。现有 182 行测试未覆盖「显式 api_url + 环境 E2B_DOMAIN」组合,两个子场景均无回归保护。
修正方向: 将环境变量读取限制在无显式端点字段的情形:configured_domain = self.domain or (None if self.api_url else os.getenv(ENV_TENCENT_AGS_DOMAIN)),并对该组合补充单元测试。
AI Code Review审查结论通过 审查范围:46f98c6..657a670,共 3 个提交、9 个文件(新增 TencentAGSClientConfig 配置类型、重构 CubeSandboxClient 的 SDK 参数构造、187 行新测试、文档)。通过与 PyPI 及 e2b 官方仓库多版本(2.0.0–2.51.0)源码逐一比对验证:该变更引入了确定性的版本兼容性缺陷—— 发现的问题中等
问题: 触发条件: 用户环境通过旧锁文件或既有约束固定了 实际影响: e2b 内部 修正方向: 在 较低
问题: 触发条件: 用户进程环境残留 实际影响: SDK 的 修正方向: 在显式 |
| **endpoint, | ||
| "api_key": self.resolve_api_key(), | ||
| "validate_api_key": self.validate_api_key, | ||
| } | ||
| if self.request_timeout is not None: | ||
| kwargs["request_timeout"] = self.request_timeout | ||
| return kwargs |
There was a problem hiding this comment.
问题: _e2b_connection_kwargs() 无条件向 e2b SDK 传入 validate_api_key 关键字参数,但该参数直到 e2b 2.31.0 才被加入 ConnectionConfig.__init__。仓库 pyproject.toml 声明的依赖为 e2b-code-interpreter>=2.0.0(无上限),而现有 e2b-code-interpreter 2.7.0(要求 e2b>=2.23.1)、2.8.0/2.8.1(要求 e2b>=2.26.0)等合法组合会解析到 e2b 2.23.1–2.30.x。这些版本中 AsyncSandbox.create/connect 的调用链(_create_sandbox→ConnectionConfig(**opts)、_cls_connect→ConnectionConfig(**opts))均无过滤地直传全部 kwargs(已逐一核对 2.0.0/2.23.1/2.26.0/2.29.0/2.30.0/2.31.0 标签源码确认)。
触发条件: 用户环境通过旧锁文件或既有约束固定了 e2b-code-interpreter 2.7.0–2.9.x(或其解析到 e2b < 2.31.0),然后使用新增的 TencentAGSClientConfig 调用 create_cube_sandbox_client/CubeSandboxClient.open_new/open_existing。
实际影响: e2b 内部 ConnectionConfig(**opts) 抛 TypeError: __init__() got an unexpected keyword argument 'validate_api_key'(已模拟复现),新功能在完全满足仓库声明的版本约束的安装组合下直接崩溃,且错误信息不指向根因,用户无法归因到版本问题。
修正方向: 在 pyproject.toml(cube extra 与 dev 两处)将依赖下限提升到 e2b-code-interpreter>=2.10.0(其强制 e2b>=2.44.0,validate_api_key 已存在)或在文档中明确声明所需 e2b 最低版本;亦可考虑在 TencentAGSClientConfig._e2b_connection_kwargs 中先探测 SDK 是否接受该参数(如 inspect.signature)以优雅降级,两者择一即可。
| def _e2b_connection_kwargs(self) -> dict[str, Any]: | ||
| configured_domain = self.domain or os.getenv(ENV_TENCENT_AGS_DOMAIN) | ||
| domain = self.resolve_domain() if configured_domain else None | ||
|
|
||
| if self.api_url: | ||
| endpoint = {"api_url": self.api_url} | ||
| if domain is not None: | ||
| endpoint["domain"] = domain | ||
| elif domain is not None: | ||
| # ConnectionConfig resolves api_url as: explicit value, |
There was a problem hiding this comment.
问题: _e2b_connection_kwargs() 的 self.api_url 分支同样接受 configured_domain(含 E2B_DOMAIN 环境变量)并把它与原样传入的 api_url 一起交给 SDK:当用户显式配置 api_url(用于私有网关/代理,文档声明的场景)而环境变量 E2B_DOMAIN 恰好残留时,沙箱路由域名会悄悄来自环境变量,覆盖用户对路由域的控制。
触发条件: 用户进程环境残留 E2B_DOMAIN(例如曾用 AGS 域名部署过),随后改用显式 api_url + 未显式设置 domain 字段的 TencentAGSClientConfig。
实际影响: SDK 的 ConnectionConfig.domain 取到残留 E2B_DOMAIN 值,envd 沙箱数据面流量(get_sandbox_url/get_sandbox_direct_url,即 {port}-{sandbox_id}.{domain} 或 https://sandbox.<domain> 形式的主机)发往与 api_url 控制面不匹配的域名,导致命令执行/文件上传下载等数据面请求失败或打到错误端点,且失败信息不提示域名来源。
修正方向: 在显式 api_url 的分支中仅在 self.domain(字段,非环境变量)显式设置时才携带 domain kwarg,环境变量 E2B_DOMAIN 仅应用于字段与 env 均缺失的纯环境配置路径;并补充一个「显式 api_url + 环境残留 E2B_DOMAIN 时 domain 不被传入」的测试用例。
Summary
TencentAGSClientConfigas a provider-specific adapter for Tencent Cloud Agent SandboxCubeSandboxClientandCubeWorkspaceRuntimeprovider-neutral through config-owned E2B connection/create optionsdomain, API key format validation control, request timeout, and creation metadataDesign
TencentAGSClientConfigextendsCubeClientConfigand only adapts E2B SDK options. It does not introduce a second sandbox client or workspace runtime. Explicit endpoint fields take precedence over environment variables;api_urlwins when both endpoint fields are provided. Creation-only metadata is not forwarded when attaching to an existing sandbox.Tests
pytest -p no:cacheprovider tests/code_executors/cube/test_tencent_ags.py tests/code_executors/cube/test_types.py tests/code_executors/cube/test_sandbox.py tests/code_executors/cube/test_package_imports.py— 83 passedflake8on changed Python files — passedtest_bug5_glob_pattern_with_space), reproduced on unmodifiedupstream/mainRelease notes
Cube workspaces can now connect to Tencent Cloud Agent Sandbox through
TencentAGSClientConfig.