From 389c44074089c241505b96f8a74a70f4a9a0ce4f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:53:04 +0000 Subject: [PATCH 1/2] Initial plan From 8733873f45200e29c0745ff82eb90c070bd37486 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 16:13:25 +0000 Subject: [PATCH 2/2] Fix DataAPI config propagation to with_path and Sandbox.__get_client() config forwarding Agent-Logs-Url: https://github.com/Serverless-Devs/agentrun-sdk-python/sessions/0e50b98f-f5e7-4961-a4fc-b9669d0ee8af Co-authored-by: OhYee <13498329+OhYee@users.noreply.github.com> --- agentrun/sandbox/__sandbox_async_template.py | 24 +++++------ agentrun/sandbox/sandbox.py | 44 ++++++++++---------- agentrun/utils/__data_api_async_template.py | 16 +++---- agentrun/utils/data_api.py | 32 +++++++------- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/agentrun/sandbox/__sandbox_async_template.py b/agentrun/sandbox/__sandbox_async_template.py index 2cc43f7..ce7bb16 100644 --- a/agentrun/sandbox/__sandbox_async_template.py +++ b/agentrun/sandbox/__sandbox_async_template.py @@ -74,11 +74,11 @@ class Sandbox(BaseModel): """配置对象,用于子类的 data_api 初始化 / Config object for data_api initialization""" @classmethod - def __get_client(cls): + def __get_client(cls, config: Optional[Config] = None): """获取 Sandbox 客户端""" from .client import SandboxClient - return SandboxClient() + return SandboxClient(config=config) @classmethod @overload @@ -180,7 +180,7 @@ async def create_async( ) # 创建 Sandbox(返回基类实例) - base_sandbox = await cls.__get_client().create_sandbox_async( + base_sandbox = await cls.__get_client(config=config).create_sandbox_async( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, sandbox_id=sandbox_id, @@ -231,7 +231,7 @@ async def stop_by_id_async( """ if sandbox_id is None: raise ValueError("sandbox_id is required") - return await cls.__get_client().stop_sandbox_async( + return await cls.__get_client(config=config).stop_sandbox_async( sandbox_id, config=config ) @@ -250,7 +250,7 @@ async def delete_by_id_async( """ if sandbox_id is None: raise ValueError("sandbox_id is required") - return await cls.__get_client().delete_sandbox_async( + return await cls.__get_client(config=config).delete_sandbox_async( sandbox_id, config=config ) @@ -269,7 +269,7 @@ async def list_async( Returns: ListSandboxesOutput: Sandbox 列表结果 """ - return await cls.__get_client().list_sandboxes_async(input, config) + return await cls.__get_client(config=config).list_sandboxes_async(input, config) @classmethod @overload @@ -337,7 +337,7 @@ async def connect_async( raise ValueError("sandbox_id is required") # 先获取 sandbox 信息 - sandbox = await cls.__get_client().get_sandbox_async( + sandbox = await cls.__get_client(config=config).get_sandbox_async( sandbox_id, config=config ) @@ -396,7 +396,7 @@ async def create_template_async( """ if input.template_type is None: raise ValueError("template_type is required") - return await cls.__get_client().create_template_async( + return await cls.__get_client(config=config).create_template_async( input, config=config ) @@ -415,7 +415,7 @@ async def get_template_async( """ if template_name is None: raise ValueError("template_name is required") - return await cls.__get_client().get_template_async( + return await cls.__get_client(config=config).get_template_async( template_name, config=config ) @@ -438,7 +438,7 @@ async def update_template_async( """ if template_name is None: raise ValueError("template_name is required") - return await cls.__get_client().update_template_async( + return await cls.__get_client(config=config).update_template_async( template_name, input, config=config ) @@ -457,7 +457,7 @@ async def delete_template_async( """ if template_name is None: raise ValueError("template_name is required") - return await cls.__get_client().delete_template_async( + return await cls.__get_client(config=config).delete_template_async( template_name, config=config ) @@ -476,7 +476,7 @@ async def list_templates_async( Returns: List[Template]: Template 列表 """ - return await cls.__get_client().list_templates_async( + return await cls.__get_client(config=config).list_templates_async( input, config=config ) diff --git a/agentrun/sandbox/sandbox.py b/agentrun/sandbox/sandbox.py index e0607b9..95229bb 100644 --- a/agentrun/sandbox/sandbox.py +++ b/agentrun/sandbox/sandbox.py @@ -84,11 +84,11 @@ class Sandbox(BaseModel): """配置对象,用于子类的 data_api 初始化 / Config object for data_api initialization""" @classmethod - def __get_client(cls): + def __get_client(cls, config: Optional[Config] = None): """获取 Sandbox 客户端""" from .client import SandboxClient - return SandboxClient() + return SandboxClient(config=config) @classmethod @overload @@ -250,7 +250,7 @@ async def create_async( ) # 创建 Sandbox(返回基类实例) - base_sandbox = await cls.__get_client().create_sandbox_async( + base_sandbox = await cls.__get_client(config=config).create_sandbox_async( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, sandbox_id=sandbox_id, @@ -326,7 +326,7 @@ def create( ) # 创建 Sandbox(返回基类实例) - base_sandbox = cls.__get_client().create_sandbox( + base_sandbox = cls.__get_client(config=config).create_sandbox( template_name=template_name, sandbox_idle_timeout_seconds=sandbox_idle_timeout_seconds, sandbox_id=sandbox_id, @@ -377,7 +377,7 @@ async def stop_by_id_async( """ if sandbox_id is None: raise ValueError("sandbox_id is required") - return await cls.__get_client().stop_sandbox_async( + return await cls.__get_client(config=config).stop_sandbox_async( sandbox_id, config=config ) @@ -394,7 +394,7 @@ def stop_by_id(cls, sandbox_id: str, config: Optional[Config] = None): """ if sandbox_id is None: raise ValueError("sandbox_id is required") - return cls.__get_client().stop_sandbox(sandbox_id, config=config) + return cls.__get_client(config=config).stop_sandbox(sandbox_id, config=config) @classmethod async def delete_by_id_async( @@ -411,7 +411,7 @@ async def delete_by_id_async( """ if sandbox_id is None: raise ValueError("sandbox_id is required") - return await cls.__get_client().delete_sandbox_async( + return await cls.__get_client(config=config).delete_sandbox_async( sandbox_id, config=config ) @@ -428,7 +428,7 @@ def delete_by_id(cls, sandbox_id: str, config: Optional[Config] = None): """ if sandbox_id is None: raise ValueError("sandbox_id is required") - return cls.__get_client().delete_sandbox(sandbox_id, config=config) + return cls.__get_client(config=config).delete_sandbox(sandbox_id, config=config) @classmethod async def list_async( @@ -445,7 +445,7 @@ async def list_async( Returns: ListSandboxesOutput: Sandbox 列表结果 """ - return await cls.__get_client().list_sandboxes_async(input, config) + return await cls.__get_client(config=config).list_sandboxes_async(input, config) @classmethod def list( @@ -462,7 +462,7 @@ def list( Returns: ListSandboxesOutput: Sandbox 列表结果 """ - return cls.__get_client().list_sandboxes(input, config) + return cls.__get_client(config=config).list_sandboxes(input, config) @classmethod @overload @@ -570,7 +570,7 @@ async def connect_async( raise ValueError("sandbox_id is required") # 先获取 sandbox 信息 - sandbox = await cls.__get_client().get_sandbox_async( + sandbox = await cls.__get_client(config=config).get_sandbox_async( sandbox_id, config=config ) @@ -640,7 +640,7 @@ def connect( raise ValueError("sandbox_id is required") # 先获取 sandbox 信息 - sandbox = cls.__get_client().get_sandbox(sandbox_id, config=config) + sandbox = cls.__get_client(config=config).get_sandbox(sandbox_id, config=config) resolved_type = template_type if resolved_type is None: @@ -695,7 +695,7 @@ async def create_template_async( """ if input.template_type is None: raise ValueError("template_type is required") - return await cls.__get_client().create_template_async( + return await cls.__get_client(config=config).create_template_async( input, config=config ) @@ -714,7 +714,7 @@ def create_template( """ if input.template_type is None: raise ValueError("template_type is required") - return cls.__get_client().create_template(input, config=config) + return cls.__get_client(config=config).create_template(input, config=config) @classmethod async def get_template_async( @@ -731,7 +731,7 @@ async def get_template_async( """ if template_name is None: raise ValueError("template_name is required") - return await cls.__get_client().get_template_async( + return await cls.__get_client(config=config).get_template_async( template_name, config=config ) @@ -750,7 +750,7 @@ def get_template( """ if template_name is None: raise ValueError("template_name is required") - return cls.__get_client().get_template(template_name, config=config) + return cls.__get_client(config=config).get_template(template_name, config=config) @classmethod async def update_template_async( @@ -771,7 +771,7 @@ async def update_template_async( """ if template_name is None: raise ValueError("template_name is required") - return await cls.__get_client().update_template_async( + return await cls.__get_client(config=config).update_template_async( template_name, input, config=config ) @@ -794,7 +794,7 @@ def update_template( """ if template_name is None: raise ValueError("template_name is required") - return cls.__get_client().update_template( + return cls.__get_client(config=config).update_template( template_name, input, config=config ) @@ -813,7 +813,7 @@ async def delete_template_async( """ if template_name is None: raise ValueError("template_name is required") - return await cls.__get_client().delete_template_async( + return await cls.__get_client(config=config).delete_template_async( template_name, config=config ) @@ -832,7 +832,7 @@ def delete_template( """ if template_name is None: raise ValueError("template_name is required") - return cls.__get_client().delete_template(template_name, config=config) + return cls.__get_client(config=config).delete_template(template_name, config=config) @classmethod async def list_templates_async( @@ -849,7 +849,7 @@ async def list_templates_async( Returns: List[Template]: Template 列表 """ - return await cls.__get_client().list_templates_async( + return await cls.__get_client(config=config).list_templates_async( input, config=config ) @@ -868,7 +868,7 @@ def list_templates( Returns: List[Template]: Template 列表 """ - return cls.__get_client().list_templates(input, config=config) + return cls.__get_client(config=config).list_templates(input, config=config) async def get_async(self): if self.sandbox_id is None: diff --git a/agentrun/utils/__data_api_async_template.py b/agentrun/utils/__data_api_async_template.py index 00b6cea..2b5240d 100644 --- a/agentrun/utils/__data_api_async_template.py +++ b/agentrun/utils/__data_api_async_template.py @@ -435,7 +435,7 @@ async def get_async( """ return await self._make_request_async( "GET", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), headers=headers, config=config, ) @@ -470,7 +470,7 @@ async def post_async( return await self._make_request_async( "POST", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -501,7 +501,7 @@ async def put_async( """ return await self._make_request_async( "PUT", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -532,7 +532,7 @@ async def patch_async( """ return await self._make_request_async( "PATCH", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -561,7 +561,7 @@ async def delete_async( """ return await self._make_request_async( "DELETE", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), headers=headers, config=config, ) @@ -601,7 +601,7 @@ async def post_file_async( filename = os.path.basename(local_file_path) - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) @@ -656,7 +656,7 @@ async def get_file_async( Examples: >>> await client.get_file_async("/files", save_path="/local/data.csv", query={"path": "/remote/file.csv"}) """ - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) @@ -707,7 +707,7 @@ async def get_video_async( Examples: >>> await client.get_video_async("/videos", save_path="/local/video.mkv", query={"path": "/remote/video.mp4"}) """ - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) diff --git a/agentrun/utils/data_api.py b/agentrun/utils/data_api.py index fd41183..f522f87 100644 --- a/agentrun/utils/data_api.py +++ b/agentrun/utils/data_api.py @@ -528,7 +528,7 @@ async def get_async( """ return await self._make_request_async( "GET", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), headers=headers, config=config, ) @@ -561,7 +561,7 @@ def get( """ return self._make_request( "GET", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), headers=headers, config=config, ) @@ -596,7 +596,7 @@ async def post_async( return await self._make_request_async( "POST", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -632,7 +632,7 @@ def post( return self._make_request( "POST", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -663,7 +663,7 @@ async def put_async( """ return await self._make_request_async( "PUT", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -694,7 +694,7 @@ def put( """ return self._make_request( "PUT", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -725,7 +725,7 @@ async def patch_async( """ return await self._make_request_async( "PATCH", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -756,7 +756,7 @@ def patch( """ return self._make_request( "PATCH", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), data=data, headers=headers, config=config, @@ -785,7 +785,7 @@ async def delete_async( """ return await self._make_request_async( "DELETE", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), headers=headers, config=config, ) @@ -813,7 +813,7 @@ def delete( """ return self._make_request( "DELETE", - self.with_path(path, query=query), + self.with_path(path, query=query, config=config), headers=headers, config=config, ) @@ -853,7 +853,7 @@ async def post_file_async( filename = os.path.basename(local_file_path) - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) @@ -917,7 +917,7 @@ def post_file( filename = os.path.basename(local_file_path) - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) @@ -970,7 +970,7 @@ async def get_file_async( Examples: >>> await client.get_file_async("/files", save_path="/local/data.csv", query={"path": "/remote/file.csv"}) """ - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) @@ -1021,7 +1021,7 @@ def get_file( Examples: >>> client.get_file("/files", save_path="/local/data.csv", query={"path": "/remote/file.csv"}) """ - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) @@ -1070,7 +1070,7 @@ async def get_video_async( Examples: >>> await client.get_video_async("/videos", save_path="/local/video.mkv", query={"path": "/remote/video.mp4"}) """ - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query) @@ -1121,7 +1121,7 @@ def get_video( Examples: >>> client.get_video("/videos", save_path="/local/video.mkv", query={"path": "/remote/video.mp4"}) """ - url = self.with_path(path, query=query) + url = self.with_path(path, query=query, config=config) req_headers = self.config.get_headers() req_headers.update(headers or {}) # Apply authentication (may modify URL, headers, and query)