sycommon-python-lib 0.2.2a1__py3-none-any.whl → 0.2.2a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -408,21 +408,83 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
408
408
  """用户ID"""
409
409
  return self._user_id
410
410
 
411
- # 沙箱容器内用户数据的实际根目录(与 sandbox server file_ops 路径对齐)
412
- # 线上 Linux 沙箱容器固定为 /data/sycommon_sandbox
413
- # 本地调试(macOS/Windows)使用环境变量 SANDBOX_WORKSPACE 或系统临时目录
414
- _WORKSPACE_ROOT = os.environ.get(
415
- "SANDBOX_WORKSPACE",
416
- "/data/sycommon_sandbox" if sys.platform != "darwin" and sys.platform != "win32"
417
- else os.path.join(tempfile.gettempdir(), "sycommon_sandbox")
418
- )
411
+ # 沙箱容器内用户数据的实际根目录,通过 health 接口从沙箱服务端动态获取。
412
+ # 初始化为 None,首次执行命令时通过 _resolve_workspace_root() 延迟获取。
413
+ _workspace_root: Optional[str] = None
414
+
415
+ def _resolve_workspace_root(self) -> str:
416
+ """同步获取沙箱服务端的 WORKSPACE_BASE,并缓存到实例"""
417
+ if self._workspace_root is not None:
418
+ return self._workspace_root
419
+
420
+ # 优先使用环境变量覆盖
421
+ env_workspace = os.environ.get("SANDBOX_WORKSPACE")
422
+ if env_workspace:
423
+ self._workspace_root = env_workspace
424
+ SYLogger.info(f"[Sandbox] 使用环境变量 SANDBOX_WORKSPACE={env_workspace}")
425
+ return self._workspace_root
426
+
427
+ # 从沙箱服务端 health 接口获取
428
+ try:
429
+ url = f"{self._base_url}{SANDBOX_API_PREFIX}/health"
430
+ resp = requests.get(url, timeout=10)
431
+ if resp.status_code == 200:
432
+ workspace = resp.json().get("workspace", "")
433
+ if workspace:
434
+ self._workspace_root = workspace
435
+ SYLogger.info(f"[Sandbox] 从沙箱服务端获取 WORKSPACE_ROOT={workspace}")
436
+ return self._workspace_root
437
+ except Exception as e:
438
+ SYLogger.warning(f"[Sandbox] 获取沙箱 workspace 失败: {e}")
439
+
440
+ # 兜底:根据平台猜测
441
+ self._workspace_root = "/data/sycommon_sandbox" if sys.platform != "darwin" and sys.platform != "win32" else os.path.join(tempfile.gettempdir(), "sycommon_sandbox")
442
+ SYLogger.warning(f"[Sandbox] 无法获取沙箱 workspace,使用兜底值: {self._workspace_root}")
443
+ return self._workspace_root
444
+
445
+ async def _aresolve_workspace_root(self) -> str:
446
+ """异步获取沙箱服务端的 WORKSPACE_BASE,并缓存到实例"""
447
+ if self._workspace_root is not None:
448
+ return self._workspace_root
449
+
450
+ # 优先使用环境变量覆盖
451
+ env_workspace = os.environ.get("SANDBOX_WORKSPACE")
452
+ if env_workspace:
453
+ self._workspace_root = env_workspace
454
+ SYLogger.info(f"[Sandbox] 使用环境变量 SANDBOX_WORKSPACE={env_workspace}")
455
+ return self._workspace_root
456
+
457
+ # 从沙箱服务端 health 接口获取(aiohttp 异步)
458
+ try:
459
+ url = f"{self._base_url}{SANDBOX_API_PREFIX}/health"
460
+ timeout_obj = aiohttp.ClientTimeout(total=10)
461
+ async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=_SSL_CONTEXT), timeout=timeout_obj) as session:
462
+ async with session.get(url) as resp:
463
+ if resp.status == 200:
464
+ data = await resp.json()
465
+ workspace = data.get("workspace", "")
466
+ if workspace:
467
+ self._workspace_root = workspace
468
+ SYLogger.info(f"[Sandbox] 从沙箱服务端获取 WORKSPACE_ROOT={workspace}")
469
+ return self._workspace_root
470
+ except Exception as e:
471
+ SYLogger.warning(f"[Sandbox] 异步获取沙箱 workspace 失败: {e}")
472
+
473
+ # 兜底
474
+ self._workspace_root = "/data/sycommon_sandbox" if sys.platform != "darwin" and sys.platform != "win32" else os.path.join(tempfile.gettempdir(), "sycommon_sandbox")
475
+ SYLogger.warning(f"[Sandbox] 无法获取沙箱 workspace,使用兜底值: {self._workspace_root}")
476
+ return self._workspace_root
419
477
 
420
478
  def _wrap_command_isolation(self, command: str) -> str:
421
- """包裹命令,确保在用户工作目录下执行
479
+ """同步版本:包裹命令,确保在用户工作目录下执行"""
480
+ workspace_root = self._resolve_workspace_root()
481
+ user_dir = f"{workspace_root}/{self._user_id}"
482
+ return f"mkdir -p {user_dir} && cd {user_dir} && {command.strip()}"
422
483
 
423
- 仅负责工作目录定位,文件系统隔离由沙箱服务端保证。
424
- """
425
- user_dir = f"{self._WORKSPACE_ROOT}/{self._user_id}"
484
+ async def _awrap_command_isolation(self, command: str) -> str:
485
+ """异步版本:包裹命令,确保在用户工作目录下执行"""
486
+ workspace_root = await self._aresolve_workspace_root()
487
+ user_dir = f"{workspace_root}/{self._user_id}"
426
488
  return f"mkdir -p {user_dir} && cd {user_dir} && {command.strip()}"
427
489
 
428
490
  # ============== 执行命令 ==============
@@ -456,7 +518,7 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
456
518
 
457
519
  async def aexecute(self, command: str, *, timeout: int = None) -> ExecuteResponse:
458
520
  """异步执行 shell 命令(真正的异步实现,带文件系统隔离)"""
459
- isolated_command = self._wrap_command_isolation(command)
521
+ isolated_command = await self._awrap_command_isolation(command)
460
522
  SYLogger.info(f"[Sandbox] aexecute 开始: command={command}")
461
523
  await self._ensure_synced_async()
462
524
  SYLogger.info(f"[Sandbox] _ensure_synced_async 完成,开始执行命令: {command}")
@@ -715,7 +777,7 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
715
777
  async def aexecute_background(self, command: str, *, timeout: int = 600) -> dict:
716
778
  """异步后台执行 shell 命令(真正的异步实现,带文件系统隔离)"""
717
779
  await self._ensure_synced_async()
718
- isolated_command = self._wrap_command_isolation(command)
780
+ isolated_command = await self._awrap_command_isolation(command)
719
781
  SYLogger.info(f"[Sandbox] 异步后台执行: {command}")
720
782
  try:
721
783
  result = await self._post_async_with_failover(f"{SANDBOX_API_PREFIX}/execute_background", {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.2a1
3
+ Version: 0.2.2a2
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -126,7 +126,7 @@ sycommon/agent/deep_agent.py,sha256=PUJpvGQNEIgE2TXBvb2i_ux_iDCIl-sQ8iqIS1skXRo,
126
126
  sycommon/agent/multi_agent_team.py,sha256=VIV4r_lxXB6ciLOsoFeF-99l8Rv1jWg4G6QpE5J4cBc,26106
127
127
  sycommon/agent/sandbox/__init__.py,sha256=qEgMJ2FFw0xJsA53M1Ji8kP6wIi_QkTICQYbWN-1h3M,4514
128
128
  sycommon/agent/sandbox/file_ops.py,sha256=eek_hk-hxpLc4cnWzF9cvrtBoSGKhemSsCXKYifMyZY,24622
129
- sycommon/agent/sandbox/http_sandbox_backend.py,sha256=C9jUM68Uo3XgMndQXyw2KeioduD8MC9p0ikj2epJQ1M,47056
129
+ sycommon/agent/sandbox/http_sandbox_backend.py,sha256=Ve_IdycHaq08UpUO0Eq8ffgynPQOipfmkBGZTq3l1Y0,50426
130
130
  sycommon/agent/sandbox/sandbox_pool.py,sha256=eMn8sLakCWf90l6ni2-333QM8oBdX1CflV-WzneFp_k,9133
131
131
  sycommon/agent/sandbox/sandbox_recovery.py,sha256=VDhFI1q9DzSs5B3s2gee1mTmXQoxs0UCXzDrqNQ7VBY,7295
132
132
  sycommon/agent/sandbox/session.py,sha256=TjzC3yFC-VaJ75UwCyL26QX4PRTGNNfQae1FKFuOsYI,2365
@@ -246,8 +246,8 @@ sycommon/tools/syemail.py,sha256=BDFhgf7WDOQeTcjxJEQdu0dQhnHFPO_p3eI0-Ni3LhQ,561
246
246
  sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
247
247
  sycommon/xxljob/__init__.py,sha256=7eoBlQxv-B39IfRSCY2bkqdGYs1QRe1umAWd88VMEEM,86
248
248
  sycommon/xxljob/xxljob_service.py,sha256=JIEJaGXhqrTLcyxlyynSrsHg9bBnDNzX-D4qIWLRPUE,6815
249
- sycommon_python_lib-0.2.2a1.dist-info/METADATA,sha256=NoQ3Ax44ByOaVYghTZr4cvaPn01OsCtmbBCyFYyLn8I,7683
250
- sycommon_python_lib-0.2.2a1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
251
- sycommon_python_lib-0.2.2a1.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
252
- sycommon_python_lib-0.2.2a1.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
253
- sycommon_python_lib-0.2.2a1.dist-info/RECORD,,
249
+ sycommon_python_lib-0.2.2a2.dist-info/METADATA,sha256=GG6m9_Lg7cmVgZo1teSqt1KgyxjicnHCEhT4amnuDPM,7683
250
+ sycommon_python_lib-0.2.2a2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
251
+ sycommon_python_lib-0.2.2a2.dist-info/entry_points.txt,sha256=gsR4SssKxDWjRU8ggidzNcdMXDPRSKRS7UaGyNP84Qg,92
252
+ sycommon_python_lib-0.2.2a2.dist-info/top_level.txt,sha256=RgphKrg7nJyZ7irJqbxFr-5H2LUYTvI7ivoWZH2hcD0,29
253
+ sycommon_python_lib-0.2.2a2.dist-info/RECORD,,