From 08e22b592be8cd0a19f7edb3f827e0edb9fa5db0 Mon Sep 17 00:00:00 2001 From: OhYee Date: Mon, 9 Mar 2026 11:22:56 +0800 Subject: [PATCH 1/2] feat(server): add health check endpoint with tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add /health endpoint to server for health checking and monitoring. Include comprehensive tests covering GET requests, method restrictions, and compatibility with custom protocols. Added _register_health_check method to AgentRunServer that registers a /health route returning {"status": "ok"} for GET requests while ensuring other methods are properly restricted. 添加用于健康检查和监控的 /health 端点。 包括涵盖 GET 请求、方法限制和自定义协议兼容性的全面测试。 在 AgentRunServer 中添加 _register_health_check 方法,该方法注册 一个 /health 路由,对 GET 请求返回 {"status": "ok"},同时 确保其他方法被正确限制。 Change-Id: I7718d675242179379935b81f6e323a2942d71bd8 Signed-off-by: OhYee --- agentrun/server/server.py | 10 ++++++++ tests/unittests/server/test_server.py | 37 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/agentrun/server/server.py b/agentrun/server/server.py index cb5eb67..5799349 100644 --- a/agentrun/server/server.py +++ b/agentrun/server/server.py @@ -132,6 +132,9 @@ def __init__( self.agent_invoker = AgentInvoker(invoke_agent) + # 注册 health check 路由 + self._register_health_check() + # 配置 CORS self._setup_cors(config.cors_origins if config else None) @@ -145,6 +148,13 @@ def __init__( # 挂载所有协议的 Router self._mount_protocols(protocols) + def _register_health_check(self): + """注册 /health 健康检查路由 / Register /health health check route""" + + @self.app.get("/health") + async def health_check(): + return {"status": "ok"} + def _wrap_with_memory( self, invoke_agent: InvokeAgentHandler, diff --git a/tests/unittests/server/test_server.py b/tests/unittests/server/test_server.py index 20150b6..9d926c6 100644 --- a/tests/unittests/server/test_server.py +++ b/tests/unittests/server/test_server.py @@ -124,6 +124,43 @@ def get_client(self, invoke_agent): return TestClient(app) + async def test_health_check(self): + """测试 /health 健康检查路由""" + + client = self.get_client(self.get_invoke_agent_non_streaming()) + + response = client.get("/health") + + assert response.status_code == 200 + assert response.json() == {"status": "ok"} + + async def test_health_check_post_not_allowed(self): + """测试 POST /health 不被允许""" + + client = self.get_client(self.get_invoke_agent_non_streaming()) + + response = client.post("/health") + + # FastAPI 对不匹配的方法返回 405 + assert response.status_code == 405 + + async def test_health_check_with_custom_protocols(self): + """测试自定义协议列表时 /health 仍可用""" + from agentrun.server.openai_protocol import OpenAIProtocolHandler + + server = AgentRunServer( + invoke_agent=self.get_invoke_agent_non_streaming(), + protocols=[OpenAIProtocolHandler()], + ) + from fastapi.testclient import TestClient + + client = TestClient(server.as_fastapi_app()) + + response = client.get("/health") + + assert response.status_code == 200 + assert response.json() == {"status": "ok"} + async def test_server_non_streaming_protocols(self): """测试非流式的 OpenAI 和 AGUI 服务器响应功能""" From b69c5f8b26ab08f78d8c6064511aec2382b088a9 Mon Sep 17 00:00:00 2001 From: OhYee Date: Mon, 9 Mar 2026 13:39:11 +0800 Subject: [PATCH 2/2] refactor(agui): remove health check endpoint and update tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The health check endpoint was removed from the AGUI protocol handler as it's no longer needed. All related test cases have been updated to reflect the new health check location at the root path. BREAKING CHANGE: The /ag-ui/agent/health endpoint has been removed and health checks are now available at /health 移除 AGUI 协议的健康检查端点并更新测试 AGUI 协议处理器中的健康检查端点已被移除, 因为它不再需要。所有相关测试用例都已更新以反映 新健康检查位置在根路径。 重大变更:/ag-ui/agent/health 端点已被移除, 健康检查现在可在 /health 路径获取 Change-Id: I7afd3abc03a90ec0e9ab989529197b6ce158ba76 Signed-off-by: OhYee --- agentrun/server/agui_protocol.py | 5 ----- .../langchain/test_agent_invoke_methods.py | 2 +- .../test_langchain_agui_integration.py | 2 +- tests/unittests/server/test_agui_protocol.py | 16 ---------------- 4 files changed, 2 insertions(+), 23 deletions(-) diff --git a/agentrun/server/agui_protocol.py b/agentrun/server/agui_protocol.py index 164dc66..89b640a 100644 --- a/agentrun/server/agui_protocol.py +++ b/agentrun/server/agui_protocol.py @@ -206,11 +206,6 @@ async def run_agent(request: Request): headers=sse_headers, ) - @router.get("/health") - async def health_check(): - """健康检查端点""" - return {"status": "ok", "protocol": "ag-ui", "version": "1.0"} - return router async def parse_request( diff --git a/tests/unittests/integration/langchain/test_agent_invoke_methods.py b/tests/unittests/integration/langchain/test_agent_invoke_methods.py index 4f5237c..0fccd91 100644 --- a/tests/unittests/integration/langchain/test_agent_invoke_methods.py +++ b/tests/unittests/integration/langchain/test_agent_invoke_methods.py @@ -100,7 +100,7 @@ def _start_server(app: FastAPI) -> tuple: base_url = f"http://127.0.0.1:{port}" for i in range(50): try: - httpx.get(f"{base_url}/ag-ui/agent/health", timeout=0.2) + httpx.get(f"{base_url}/health", timeout=0.2) break except Exception: if i == 49: diff --git a/tests/unittests/integration/test_langchain_agui_integration.py b/tests/unittests/integration/test_langchain_agui_integration.py index 0824a56..2e88c16 100644 --- a/tests/unittests/integration/test_langchain_agui_integration.py +++ b/tests/unittests/integration/test_langchain_agui_integration.py @@ -671,7 +671,7 @@ async def invoke_agent(request: AgentRequest): base_url = f"http://127.0.0.1:{port}" for i in range(50): try: - httpx.get(f"{base_url}/ag-ui/agent/health", timeout=0.2) + httpx.get(f"{base_url}/health", timeout=0.2) break except Exception: if i == 49: diff --git a/tests/unittests/server/test_agui_protocol.py b/tests/unittests/server/test_agui_protocol.py index 47b7974..e7196cb 100644 --- a/tests/unittests/server/test_agui_protocol.py +++ b/tests/unittests/server/test_agui_protocol.py @@ -43,22 +43,6 @@ def get_client(self, invoke_agent): server = AgentRunServer(invoke_agent=invoke_agent) return TestClient(server.as_fastapi_app()) - @pytest.mark.asyncio - async def test_health_check(self): - """测试健康检查端点""" - - def invoke_agent(request: AgentRequest): - return "Hello" - - client = self.get_client(invoke_agent) - response = client.get("/ag-ui/agent/health") - - assert response.status_code == 200 - data = response.json() - assert data["status"] == "ok" - assert data["protocol"] == "ag-ui" - assert data["version"] == "1.0" - @pytest.mark.asyncio async def test_value_error_handling(self): """测试 ValueError 处理"""