Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions agentrun/agent_runtime/__endpoint_async_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
AgentRuntimeEndpointUpdateInput,
)
from agentrun.utils.config import Config
from agentrun.utils.model import PageableInput
from agentrun.utils.resource import ResourceBase


Expand Down Expand Up @@ -160,6 +161,45 @@ async def get_by_id_async(
config=config,
)

@classmethod
async def _list_page_async(
cls,
page_input: PageableInput,
config: Optional[Config] = None,
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type hint for the config parameter is inconsistent with other resources in the codebase. In agentrun/agent_runtime/runtime.py and agentrun/credential/credential.py, the _list_page_async methods use "Config | None" instead of "Optional[Config]". While both are functionally equivalent, using "Config | None" maintains consistency with the established pattern in similar resource classes.

Suggested change
config: Optional[Config] = None,
config: Config | None = None,

Copilot uses AI. Check for mistakes.
**kwargs,
) -> List["AgentRuntimeEndpoint"]:
"""分页列出端点 / List endpoints by page

此方法是 ResourceBase 要求实现的抽象方法,用于支持分页查询。
This method is an abstract method required by ResourceBase to support pagination.

Args:
page_input: 分页参数 / Pagination parameters
config: 配置对象,可选 / Configuration object, optional
**kwargs: 其他参数,必须包含 agent_runtime_id / Other parameters, must include agent_runtime_id

Returns:
List[AgentRuntimeEndpoint]: 端点对象列表 / List of endpoint objects

Raises:
ValueError: 当 agent_runtime_id 未提供时 / When agent_runtime_id is not provided
HTTPError: HTTP 请求错误 / HTTP request error
"""
agent_runtime_id = kwargs.get("agent_runtime_id")
if not agent_runtime_id:
raise ValueError(
"agent_runtime_id is required for listing endpoints"
)

return await cls.__get_client().list_endpoints_async(
agent_runtime_id,
AgentRuntimeEndpointListInput(
page_number=page_input.page_number,
page_size=page_input.page_size,
),
config=config,
)

@classmethod
async def list_by_id_async(
cls, agent_runtime_id: str, config: Optional[Config] = None
Expand Down
79 changes: 79 additions & 0 deletions agentrun/agent_runtime/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
AgentRuntimeEndpointUpdateInput,
)
from agentrun.utils.config import Config
from agentrun.utils.model import PageableInput
from agentrun.utils.resource import ResourceBase


Expand Down Expand Up @@ -286,6 +287,84 @@ def get_by_id(
config=config,
)

@classmethod
async def _list_page_async(
cls,
page_input: PageableInput,
config: Optional[Config] = None,
**kwargs,
Comment on lines +291 to +295
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type hint for the config parameter is inconsistent with other resources in the codebase. In agentrun/agent_runtime/runtime.py and agentrun/credential/credential.py, the _list_page and _list_page_async methods use "Config | None" instead of "Optional[Config]". While both are functionally equivalent, using "Config | None" maintains consistency with the established pattern in similar resource classes.

Copilot uses AI. Check for mistakes.
) -> List["AgentRuntimeEndpoint"]:
"""分页列出端点 / List endpoints by page

此方法是 ResourceBase 要求实现的抽象方法,用于支持分页查询。
This method is an abstract method required by ResourceBase to support pagination.

Args:
page_input: 分页参数 / Pagination parameters
config: 配置对象,可选 / Configuration object, optional
**kwargs: 其他参数,必须包含 agent_runtime_id / Other parameters, must include agent_runtime_id

Returns:
List[AgentRuntimeEndpoint]: 端点对象列表 / List of endpoint objects

Raises:
ValueError: 当 agent_runtime_id 未提供时 / When agent_runtime_id is not provided
HTTPError: HTTP 请求错误 / HTTP request error
"""
agent_runtime_id = kwargs.get("agent_runtime_id")
if not agent_runtime_id:
raise ValueError(
"agent_runtime_id is required for listing endpoints"
)

return await cls.__get_client().list_endpoints_async(
agent_runtime_id,
AgentRuntimeEndpointListInput(
page_number=page_input.page_number,
page_size=page_input.page_size,
),
config=config,
)

Comment on lines +290 to +328
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method order is inconsistent with other resources in the codebase. Based on the pattern in agentrun/agent_runtime/runtime.py, agentrun/credential/credential.py, and other resource files, the synchronous _list_page method should be defined before the asynchronous _list_page_async method. This maintains consistency with the established codebase pattern where sync methods are defined first, followed by their async counterparts.

Copilot uses AI. Check for mistakes.
@classmethod
def _list_page(
cls,
page_input: PageableInput,
config: Optional[Config] = None,
**kwargs,
Comment on lines +330 to +334
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type hint for the config parameter is inconsistent with other resources in the codebase. In agentrun/agent_runtime/runtime.py and agentrun/credential/credential.py, the _list_page and _list_page_async methods use "Config | None" instead of "Optional[Config]". While both are functionally equivalent, using "Config | None" maintains consistency with the established pattern in similar resource classes.

Copilot uses AI. Check for mistakes.
) -> List["AgentRuntimeEndpoint"]:
"""分页列出端点 / List endpoints by page

此方法是 ResourceBase 要求实现的抽象方法,用于支持分页查询。
This method is an abstract method required by ResourceBase to support pagination.

Args:
page_input: 分页参数 / Pagination parameters
config: 配置对象,可选 / Configuration object, optional
**kwargs: 其他参数,必须包含 agent_runtime_id / Other parameters, must include agent_runtime_id

Returns:
List[AgentRuntimeEndpoint]: 端点对象列表 / List of endpoint objects

Raises:
ValueError: 当 agent_runtime_id 未提供时 / When agent_runtime_id is not provided
HTTPError: HTTP 请求错误 / HTTP request error
"""
agent_runtime_id = kwargs.get("agent_runtime_id")
if not agent_runtime_id:
raise ValueError(
"agent_runtime_id is required for listing endpoints"
)

return cls.__get_client().list_endpoints(
agent_runtime_id,
AgentRuntimeEndpointListInput(
page_number=page_input.page_number,
page_size=page_input.page_size,
),
config=config,
)

@classmethod
async def list_by_id_async(
cls, agent_runtime_id: str, config: Optional[Config] = None
Expand Down
112 changes: 112 additions & 0 deletions tests/unittests/agent_runtime/test_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,115 @@ def test_invoke_openai(self, mock_client_class, mock_data_api_class):
def test_invoke_openai_async(self, mock_client_class, mock_data_api_class):
"""测试 invoke_openai_async - 跳过因为私有属性问题"""
pass


class TestAgentRuntimeEndpointAbstractMethods:
"""测试 AgentRuntimeEndpoint 抽象方法实现

此测试类用于验证 AgentRuntimeEndpoint 正确实现了 ResourceBase 要求的抽象方法。
这是为了防止类似于 Issue #XXX 的问题再次发生,确保 from_inner_object 能够正常实例化对象。
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment references a placeholder "Issue #XXX" which should be replaced with the actual issue number if one exists, or the placeholder should be removed. Since the PR description doesn't specify an issue number, consider removing the phrase "类似于 Issue #XXX 的问题" and simply stating "这是为了防止问题再次发生,确保 from_inner_object 能够正常实例化对象。"

Suggested change
这是为了防止类似于 Issue #XXX 的问题再次发生,确保 from_inner_object 能够正常实例化对象。
这是为了防止问题再次发生确保 from_inner_object 能够正常实例化对象

Copilot uses AI. Check for mistakes.
"""

def test_from_inner_object_instantiation(self):
"""测试 from_inner_object 能够正常实例化对象

这个测试确保 AgentRuntimeEndpoint 类实现了所有必需的抽象方法。
如果抽象方法未实现,from_inner_object 会抛出 TypeError。
"""

# 准备一个最小的有效数据
class MockDaraModel:

def to_map(self):
return {
"agentRuntimeEndpointId": "are-test-123",
"agentRuntimeEndpointName": "test-endpoint",
"agentRuntimeId": "ar-test-123",
"status": "READY",
}

inner_obj = MockDaraModel()

# 这里不应该抛出 TypeError: Can't instantiate abstract class
endpoint = AgentRuntimeEndpoint.from_inner_object(inner_obj)

# 验证对象正确创建
assert endpoint is not None
assert endpoint.agent_runtime_endpoint_id == "are-test-123"
assert endpoint.agent_runtime_endpoint_name == "test-endpoint"

def test_list_page_method_exists(self):
"""测试 _list_page 方法存在且可调用"""
# 验证类有 _list_page 方法
assert hasattr(AgentRuntimeEndpoint, "_list_page")
assert callable(getattr(AgentRuntimeEndpoint, "_list_page"))

def test_list_page_async_method_exists(self):
"""测试 _list_page_async 方法存在且可调用"""
# 验证类有 _list_page_async 方法
assert hasattr(AgentRuntimeEndpoint, "_list_page_async")
assert callable(getattr(AgentRuntimeEndpoint, "_list_page_async"))

@patch(CLIENT_PATH)
def test_list_page_requires_agent_runtime_id(self, mock_client_class):
"""测试 _list_page 需要 agent_runtime_id 参数"""
from agentrun.utils.model import PageableInput

# 不提供 agent_runtime_id 应该抛出 ValueError
with pytest.raises(ValueError, match="agent_runtime_id is required"):
AgentRuntimeEndpoint._list_page(
PageableInput(page_number=1, page_size=10)
)

@patch(CLIENT_PATH)
def test_list_page_async_requires_agent_runtime_id(self, mock_client_class):
"""测试 _list_page_async 需要 agent_runtime_id 参数"""
from agentrun.utils.model import PageableInput

# 不提供 agent_runtime_id 应该抛出 ValueError
with pytest.raises(ValueError, match="agent_runtime_id is required"):
asyncio.run(
AgentRuntimeEndpoint._list_page_async(
PageableInput(page_number=1, page_size=10)
)
)

@patch(CLIENT_PATH)
def test_list_page_with_agent_runtime_id(self, mock_client_class):
"""测试 _list_page 正确传递 agent_runtime_id"""
from agentrun.utils.model import PageableInput

mock_client = MagicMock()
mock_client.list_endpoints.return_value = []
mock_client_class.return_value = mock_client

# 提供 agent_runtime_id 应该正常执行
result = AgentRuntimeEndpoint._list_page(
PageableInput(page_number=1, page_size=10),
agent_runtime_id="ar-test-123",
)

# 验证调用了 list_endpoints
mock_client.list_endpoints.assert_called_once()
assert result == []

@patch(CLIENT_PATH)
def test_list_page_async_with_agent_runtime_id(self, mock_client_class):
"""测试 _list_page_async 正确传递 agent_runtime_id"""
from agentrun.utils.model import PageableInput

mock_client = MagicMock()
mock_client.list_endpoints_async = AsyncMock(return_value=[])
mock_client_class.return_value = mock_client

# 提供 agent_runtime_id 应该正常执行
result = asyncio.run(
AgentRuntimeEndpoint._list_page_async(
PageableInput(page_number=1, page_size=10),
agent_runtime_id="ar-test-123",
)
)

# 验证调用了 list_endpoints_async
mock_client.list_endpoints_async.assert_called_once()
assert result == []
Loading