mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-12 14:10:19 +08:00
refactor: 移除独立 hub/proxy/executor/gateway crate,统一为 gateway tunnel 架构
- 删除 aether-hub、aether-proxy 独立项目及其 Dockerfile/配置 - 删除 crates/aether-executor 和 crates/aether-gateway 全部模块 - 新增 apps/ 目录作为应用入口 - 将 hub 概念重构为 gateway tunnel transport - 将 executor 重构为 execution runtime - 新增 tunnel.rs 合约定义和 testkit tunnel/execution_runtime 模块 - 更新 Python 服务层和测试适配新架构命名
This commit is contained in:
@@ -9,6 +9,11 @@ def test_executor_config_defaults_to_rust_and_unix_socket(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
for key in (
|
||||
"EXECUTION_RUNTIME_BACKEND",
|
||||
"EXECUTION_RUNTIME_TRANSPORT",
|
||||
"EXECUTION_RUNTIME_SOCKET_PATH",
|
||||
"EXECUTION_RUNTIME_BASE_URL",
|
||||
"EXECUTION_RUNTIME_REQUEST_TIMEOUT",
|
||||
"EXECUTOR_BACKEND",
|
||||
"EXECUTOR_TRANSPORT",
|
||||
"EXECUTOR_SOCKET_PATH",
|
||||
@@ -20,6 +25,11 @@ def test_executor_config_defaults_to_rust_and_unix_socket(
|
||||
|
||||
cfg = Config()
|
||||
|
||||
assert cfg.execution_runtime_backend == "rust"
|
||||
assert cfg.execution_runtime_transport == "unix_socket"
|
||||
assert cfg.execution_runtime_socket_path == "/tmp/aether-executor.sock"
|
||||
assert cfg.execution_runtime_base_url == "http://127.0.0.1:5219"
|
||||
assert cfg.execution_runtime_request_timeout == cfg.http_request_timeout
|
||||
assert cfg.executor_backend == "rust"
|
||||
assert cfg.executor_transport == "unix_socket"
|
||||
assert cfg.executor_socket_path == "/tmp/aether-executor.sock"
|
||||
@@ -28,16 +38,42 @@ def test_executor_config_defaults_to_rust_and_unix_socket(
|
||||
|
||||
|
||||
def test_executor_config_accepts_env_override(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("EXECUTOR_BACKEND", "RUST")
|
||||
monkeypatch.setenv("EXECUTOR_TRANSPORT", "TCP")
|
||||
monkeypatch.setenv("EXECUTOR_SOCKET_PATH", "/var/run/aether.sock")
|
||||
monkeypatch.setenv("EXECUTOR_BASE_URL", "http://127.0.0.1:9311")
|
||||
monkeypatch.setenv("EXECUTOR_REQUEST_TIMEOUT", "12.5")
|
||||
monkeypatch.setenv("EXECUTION_RUNTIME_BACKEND", "RUST")
|
||||
monkeypatch.setenv("EXECUTION_RUNTIME_TRANSPORT", "TCP")
|
||||
monkeypatch.setenv("EXECUTION_RUNTIME_SOCKET_PATH", "/var/run/aether.sock")
|
||||
monkeypatch.setenv("EXECUTION_RUNTIME_BASE_URL", "http://127.0.0.1:9311")
|
||||
monkeypatch.setenv("EXECUTION_RUNTIME_REQUEST_TIMEOUT", "12.5")
|
||||
|
||||
cfg = Config()
|
||||
|
||||
assert cfg.execution_runtime_backend == "rust"
|
||||
assert cfg.execution_runtime_transport == "tcp"
|
||||
assert cfg.execution_runtime_socket_path == "/var/run/aether.sock"
|
||||
assert cfg.execution_runtime_base_url == "http://127.0.0.1:9311"
|
||||
assert cfg.execution_runtime_request_timeout == 12.5
|
||||
assert cfg.executor_backend == "rust"
|
||||
assert cfg.executor_transport == "tcp"
|
||||
assert cfg.executor_socket_path == "/var/run/aether.sock"
|
||||
assert cfg.executor_base_url == "http://127.0.0.1:9311"
|
||||
assert cfg.executor_request_timeout == 12.5
|
||||
|
||||
|
||||
def test_executor_config_legacy_envs_still_work(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("EXECUTOR_BACKEND", "RUST")
|
||||
monkeypatch.setenv("EXECUTOR_TRANSPORT", "TCP")
|
||||
monkeypatch.setenv("EXECUTOR_SOCKET_PATH", "/tmp/legacy-aether.sock")
|
||||
monkeypatch.setenv("EXECUTOR_BASE_URL", "http://127.0.0.1:9322")
|
||||
monkeypatch.setenv("EXECUTOR_REQUEST_TIMEOUT", "14.5")
|
||||
|
||||
cfg = Config()
|
||||
|
||||
assert cfg.execution_runtime_backend == "rust"
|
||||
assert cfg.execution_runtime_transport == "tcp"
|
||||
assert cfg.execution_runtime_socket_path == "/tmp/legacy-aether.sock"
|
||||
assert cfg.execution_runtime_base_url == "http://127.0.0.1:9322"
|
||||
assert cfg.execution_runtime_request_timeout == 14.5
|
||||
assert cfg.executor_backend == "rust"
|
||||
assert cfg.executor_transport == "tcp"
|
||||
assert cfg.executor_socket_path == "/tmp/legacy-aether.sock"
|
||||
assert cfg.executor_base_url == "http://127.0.0.1:9322"
|
||||
assert cfg.executor_request_timeout == 14.5
|
||||
|
||||
@@ -2,14 +2,14 @@ from __future__ import annotations
|
||||
|
||||
import base64
|
||||
|
||||
from src.services.request.executor_plan import PreparedExecutionPlan
|
||||
from src.services.request.executor_plan import (
|
||||
from src.services.request.execution_runtime_plan import PreparedExecutionPlan
|
||||
from src.services.request.execution_runtime_plan import (
|
||||
ExecutionPlan,
|
||||
ExecutionPlanBody,
|
||||
ExecutionPlanTimeouts,
|
||||
ExecutionProxySnapshot,
|
||||
build_execution_plan_body,
|
||||
should_bypass_remote_executor_url,
|
||||
should_bypass_remote_execution_runtime_url,
|
||||
)
|
||||
|
||||
|
||||
@@ -374,9 +374,9 @@ def test_prepared_execution_plan_remote_eligible_rejects_codex_cli_transport() -
|
||||
assert prepared.remote_eligible is False
|
||||
|
||||
|
||||
def test_should_bypass_remote_executor_url_accepts_backendapi_codex_variant() -> None:
|
||||
def test_should_bypass_remote_execution_runtime_url_accepts_backendapi_codex_variant() -> None:
|
||||
assert (
|
||||
should_bypass_remote_executor_url(
|
||||
should_bypass_remote_execution_runtime_url(
|
||||
"https://chatgpt.com/backendapi/codex/responses",
|
||||
provider_api_format="openai:cli",
|
||||
client_api_format="openai:cli",
|
||||
|
||||
+20
-11
@@ -7,8 +7,8 @@ from typing import Any
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from src.services.proxy_node.hub_config import HubConfig
|
||||
from src.services.proxy_node.hub_transport import HubTunnelTransport
|
||||
from src.services.proxy_node.gateway_tunnel_transport import GatewayTunnelTransport
|
||||
from src.services.proxy_node.tunnel_config import TunnelRelayConfig
|
||||
|
||||
|
||||
class _FakeRelayClient:
|
||||
@@ -31,19 +31,22 @@ class _FakeRelayClient:
|
||||
return None
|
||||
|
||||
|
||||
def _relay_config() -> HubConfig:
|
||||
return HubConfig(
|
||||
def _relay_config() -> TunnelRelayConfig:
|
||||
return TunnelRelayConfig(
|
||||
enabled=True,
|
||||
url="http://127.0.0.1:8085",
|
||||
url="http://127.0.0.1:8084",
|
||||
connect_timeout_seconds=1.0,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_transport_encodes_local_relay_envelope(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
transport = HubTunnelTransport("node-1", timeout=12.0)
|
||||
transport = GatewayTunnelTransport("node-1", timeout=12.0)
|
||||
fake_client = _FakeRelayClient(httpx.Response(200, content=b"ok"))
|
||||
monkeypatch.setattr("src.services.proxy_node.hub_transport.get_hub_config", _relay_config)
|
||||
monkeypatch.setattr(
|
||||
"src.services.proxy_node.gateway_tunnel_transport.get_tunnel_relay_config",
|
||||
_relay_config,
|
||||
)
|
||||
monkeypatch.setattr(transport, "_relay_client", fake_client)
|
||||
|
||||
request = httpx.Request(
|
||||
@@ -75,7 +78,7 @@ async def test_transport_encodes_local_relay_envelope(monkeypatch: pytest.Monkey
|
||||
async def test_transport_maps_relay_timeout_to_read_timeout(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
transport = HubTunnelTransport("node-1", timeout=12.0)
|
||||
transport = GatewayTunnelTransport("node-1", timeout=12.0)
|
||||
fake_client = _FakeRelayClient(
|
||||
httpx.Response(
|
||||
504,
|
||||
@@ -83,7 +86,10 @@ async def test_transport_maps_relay_timeout_to_read_timeout(
|
||||
content=b"relay timed out",
|
||||
)
|
||||
)
|
||||
monkeypatch.setattr("src.services.proxy_node.hub_transport.get_hub_config", _relay_config)
|
||||
monkeypatch.setattr(
|
||||
"src.services.proxy_node.gateway_tunnel_transport.get_tunnel_relay_config",
|
||||
_relay_config,
|
||||
)
|
||||
monkeypatch.setattr(transport, "_relay_client", fake_client)
|
||||
|
||||
request = httpx.Request("GET", "https://example.com")
|
||||
@@ -96,9 +102,12 @@ async def test_transport_maps_relay_timeout_to_read_timeout(
|
||||
async def test_transport_streams_request_body_from_async_generator(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
transport = HubTunnelTransport("node-1", timeout=12.0)
|
||||
transport = GatewayTunnelTransport("node-1", timeout=12.0)
|
||||
fake_client = _FakeRelayClient(httpx.Response(200, content=b"ok"))
|
||||
monkeypatch.setattr("src.services.proxy_node.hub_transport.get_hub_config", _relay_config)
|
||||
monkeypatch.setattr(
|
||||
"src.services.proxy_node.gateway_tunnel_transport.get_tunnel_relay_config",
|
||||
_relay_config,
|
||||
)
|
||||
monkeypatch.setattr(transport, "_relay_client", fake_client)
|
||||
|
||||
async def body() -> Any:
|
||||
+5
-5
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from src.services.proxy_node.hub_transport import HubRelayResponseStream
|
||||
from src.services.proxy_node.gateway_tunnel_transport import TunnelRelayResponseStream
|
||||
|
||||
|
||||
class _FakeResponse:
|
||||
@@ -19,9 +19,9 @@ class _FakeResponse:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_hub_relay_response_stream_closes_after_iteration() -> None:
|
||||
async def test_tunnel_relay_response_stream_closes_after_iteration() -> None:
|
||||
response = _FakeResponse([b"hello", b"world"])
|
||||
stream = HubRelayResponseStream(response) # type: ignore[arg-type]
|
||||
stream = TunnelRelayResponseStream(response) # type: ignore[arg-type]
|
||||
|
||||
chunks = []
|
||||
async for chunk in stream:
|
||||
@@ -32,9 +32,9 @@ async def test_hub_relay_response_stream_closes_after_iteration() -> None:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_hub_relay_response_stream_aclose_closes_response() -> None:
|
||||
async def test_tunnel_relay_response_stream_aclose_closes_response() -> None:
|
||||
response = _FakeResponse([])
|
||||
stream = HubRelayResponseStream(response) # type: ignore[arg-type]
|
||||
stream = TunnelRelayResponseStream(response) # type: ignore[arg-type]
|
||||
|
||||
await stream.aclose()
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
from src.services.proxy_node.hub_config import HubConfig
|
||||
|
||||
|
||||
def test_local_relay_url_uses_http_path() -> None:
|
||||
config = HubConfig(
|
||||
enabled=True,
|
||||
url="http://127.0.0.1:8085",
|
||||
connect_timeout_seconds=1.0,
|
||||
)
|
||||
|
||||
assert (
|
||||
config.local_relay_url("node a/1")
|
||||
== "http://127.0.0.1:8085/local/relay/node%20a%2F1"
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
from src.services.proxy_node.tunnel_config import TunnelRelayConfig
|
||||
|
||||
|
||||
def test_local_relay_url_uses_http_path() -> None:
|
||||
config = TunnelRelayConfig(
|
||||
enabled=True,
|
||||
url="http://127.0.0.1:8084",
|
||||
connect_timeout_seconds=1.0,
|
||||
)
|
||||
|
||||
assert (
|
||||
config.local_relay_url("node a/1")
|
||||
== "http://127.0.0.1:8084/api/internal/tunnel/relay/node%20a%2F1"
|
||||
)
|
||||
@@ -1,11 +1,11 @@
|
||||
from src.services.proxy_node.hub_transport import HubTunnelTransport
|
||||
from src.services.proxy_node.gateway_tunnel_transport import GatewayTunnelTransport
|
||||
from src.services.proxy_node.tunnel_protocol import Frame, MsgType
|
||||
from src.services.proxy_node.tunnel_transport import create_tunnel_transport
|
||||
|
||||
|
||||
def test_create_tunnel_transport_always_uses_hub_transport() -> None:
|
||||
def test_create_tunnel_transport_always_uses_gateway_tunnel_transport() -> None:
|
||||
transport = create_tunnel_transport("node-1", timeout=12.0)
|
||||
assert isinstance(transport, HubTunnelTransport)
|
||||
assert isinstance(transport, GatewayTunnelTransport)
|
||||
|
||||
|
||||
def test_tunnel_protocol_supports_node_status_msg_type() -> None:
|
||||
Reference in New Issue
Block a user