mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +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,14 +9,14 @@ import src.api.handlers.base.chat_sync_executor as chat_sync_mod
|
||||
from src.api.handlers.base.chat_sync_executor import ChatSyncExecutor
|
||||
from src.core.exceptions import EmbeddedErrorException
|
||||
from src.core.exceptions import ProviderNotAvailableException
|
||||
from src.services.request.executor_plan import (
|
||||
from src.services.request.execution_runtime_plan import (
|
||||
ExecutionPlan,
|
||||
ExecutionPlanBody,
|
||||
PreparedExecutionPlan,
|
||||
)
|
||||
from src.services.request.rust_executor_client import (
|
||||
RustExecutorClientError,
|
||||
RustExecutorSyncResult,
|
||||
from src.services.request.execution_runtime_client import (
|
||||
ExecutionRuntimeClientError,
|
||||
ExecutionRuntimeSyncResult,
|
||||
)
|
||||
|
||||
|
||||
@@ -138,16 +138,16 @@ async def test_execute_sync_plan_uses_rust_executor_when_available(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.request_id == "req-test"
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"id": "chatcmpl-1"},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -172,17 +172,17 @@ async def test_execute_sync_plan_allows_supported_proxy_urls_for_rust(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.proxy is not None
|
||||
assert plan.proxy.url == "http://proxy.internal:8080"
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"id": "chatcmpl-proxy"},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -205,18 +205,18 @@ async def test_execute_sync_plan_allows_tunnel_delegate_for_rust(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.proxy is not None
|
||||
assert plan.proxy.mode == "tunnel"
|
||||
assert plan.proxy.node_id == "node-1"
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"id": "chatcmpl-tunnel"},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -239,16 +239,16 @@ async def test_execute_sync_plan_allows_tls_profile_for_rust(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.tls_profile == "claude_code_nodejs"
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"id": "chatcmpl-tls"},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -272,15 +272,15 @@ async def test_execute_sync_plan_applies_envelope_postprocessing_after_rust(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
return RustExecutorSyncResult(
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"payload": {"id": "wrapped-1", "message": "ok"}},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -330,16 +330,16 @@ async def test_execute_sync_plan_applies_format_conversion_after_rust(
|
||||
"source_id": response_json["provider_id"],
|
||||
}
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.provider_api_format == "gemini:chat"
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"provider_id": "gemini-1"},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -389,16 +389,16 @@ async def test_execute_sync_plan_aggregates_upstream_stream_after_rust(
|
||||
assert request_id == "req-test"
|
||||
return SimpleNamespace(id="agg-1")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.stream is True
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_body_bytes=b"data: {\"id\":\"chunk-1\"}\n\ndata: [DONE]\n\n",
|
||||
headers={"content-type": "text/event-stream"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -432,16 +432,16 @@ async def test_execute_sync_plan_turns_rust_http_error_into_httpx_status_error(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.url.endswith("/chat/completions")
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=429,
|
||||
response_json={"error": {"message": "slow down"}},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -466,9 +466,9 @@ async def test_execute_sync_plan_preserves_embedded_error_semantics_from_rust(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.provider_api_format == "openai:chat"
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={
|
||||
"error": {
|
||||
@@ -481,7 +481,7 @@ async def test_execute_sync_plan_preserves_embedded_error_semantics_from_rust(
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -506,12 +506,12 @@ async def test_execute_sync_plan_raises_when_rust_unavailable(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
assert plan.request_id == "req-test"
|
||||
raise RustExecutorClientError("executor down")
|
||||
raise ExecutionRuntimeClientError("executor down")
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -541,12 +541,12 @@ async def test_execute_sync_plan_raises_when_remote_contract_is_ineligible(
|
||||
|
||||
monkeypatch.setattr(chat_sync_mod.config, "executor_backend", "rust")
|
||||
|
||||
async def _should_not_call_rust(self: object, plan: ExecutionPlan) -> RustExecutorSyncResult:
|
||||
async def _should_not_call_rust(self: object, plan: ExecutionPlan) -> ExecutionRuntimeSyncResult:
|
||||
del self, plan
|
||||
raise AssertionError("rust executor should not be called")
|
||||
|
||||
monkeypatch.setattr(
|
||||
chat_sync_mod.RustExecutorClient,
|
||||
chat_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_should_not_call_rust,
|
||||
)
|
||||
|
||||
@@ -12,9 +12,9 @@ import src.services.proxy_node.resolver as proxymod
|
||||
from src.api.handlers.base.chat_handler_base import ChatHandlerBase
|
||||
from src.api.handlers.base.stream_context import StreamContext
|
||||
from src.core.exceptions import ProviderNotAvailableException
|
||||
from src.services.request.rust_executor_client import (
|
||||
RustExecutorClientError,
|
||||
RustExecutorStreamResult,
|
||||
from src.services.request.execution_runtime_client import (
|
||||
ExecutionRuntimeClientError,
|
||||
ExecutionRuntimeStreamResult,
|
||||
)
|
||||
|
||||
|
||||
@@ -265,9 +265,9 @@ async def test_execute_stream_request_uses_rust_executor_when_available(
|
||||
|
||||
dummy_ctx = _DummyStreamResponseCtx()
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "stream") is True
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "text/event-stream", "x-upstream-test": "true"},
|
||||
byte_iterator=_iter_chunks(
|
||||
@@ -279,7 +279,7 @@ async def test_execute_stream_request_uses_rust_executor_when_available(
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
stream = await handler._execute_stream_request(
|
||||
ctx,
|
||||
@@ -359,7 +359,7 @@ async def test_execute_stream_request_uses_rust_sync_executor_for_non_stream_ups
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
async def _should_not_call_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _should_not_call_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
del self, plan
|
||||
raise AssertionError("stream executor should not be used")
|
||||
|
||||
@@ -378,8 +378,8 @@ async def test_execute_stream_request_uses_rust_sync_executor_for_non_stream_ups
|
||||
lambda internal_resp: [{"kind": "chunk"}],
|
||||
)
|
||||
monkeypatch.setattr(chatmod, "get_parser_for_format", lambda _format: _FakeParser())
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_sync_json", _fake_execute_sync_json)
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _should_not_call_stream)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_sync_json", _fake_execute_sync_json)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _should_not_call_stream)
|
||||
monkeypatch.setattr(
|
||||
"src.clients.http_client.HTTPClientPool.get_upstream_client",
|
||||
_should_not_get_http_client,
|
||||
@@ -432,9 +432,9 @@ async def test_execute_stream_request_accepts_async_generator_stream_processor(
|
||||
|
||||
dummy_ctx = _DummyStreamResponseCtx()
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "stream") is True
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "text/event-stream"},
|
||||
byte_iterator=_iter_chunks(
|
||||
@@ -446,7 +446,7 @@ async def test_execute_stream_request_accepts_async_generator_stream_processor(
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
stream = await handler._execute_stream_request(
|
||||
ctx,
|
||||
@@ -501,18 +501,18 @@ async def test_execute_stream_request_allows_tunnel_delegate_for_rust(
|
||||
|
||||
dummy_ctx = _DummyStreamResponseCtx()
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "proxy") is not None
|
||||
assert getattr(plan.proxy, "mode") == "tunnel"
|
||||
assert getattr(plan.proxy, "node_id") == "node-1"
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "text/event-stream"},
|
||||
byte_iterator=_iter_chunks([b"data: [DONE]\n\n"]),
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
stream = await handler._execute_stream_request(
|
||||
ctx,
|
||||
@@ -577,16 +577,16 @@ async def test_execute_stream_request_allows_tls_profile_for_rust(
|
||||
_fake_prepare_provider_request,
|
||||
)
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "tls_profile") == "claude_code_nodejs"
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "text/event-stream"},
|
||||
byte_iterator=_iter_chunks([b"data: [DONE]\n\n"]),
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
stream = await handler._execute_stream_request(
|
||||
ctx,
|
||||
@@ -629,16 +629,16 @@ async def test_execute_stream_request_turns_rust_upstream_error_into_http_status
|
||||
|
||||
dummy_ctx = _DummyStreamResponseCtx()
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "stream") is True
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=429,
|
||||
headers={"content-type": "application/json"},
|
||||
byte_iterator=_iter_chunks([b'{"error":{"message":"slow down"}}']),
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
with pytest.raises(httpx.HTTPStatusError) as exc_info:
|
||||
await handler._execute_stream_request(
|
||||
@@ -678,14 +678,14 @@ async def test_execute_stream_request_raises_when_rust_unavailable(
|
||||
output_limit=None,
|
||||
)
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
del plan
|
||||
raise RustExecutorClientError("executor down")
|
||||
raise ExecutionRuntimeClientError("executor down")
|
||||
|
||||
async def _fake_get_upstream_client(*args: Any, **kwargs: Any) -> object:
|
||||
raise AssertionError("python fallback should not be used")
|
||||
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(
|
||||
"src.clients.http_client.HTTPClientPool.get_upstream_client",
|
||||
_fake_get_upstream_client,
|
||||
@@ -728,15 +728,15 @@ async def test_execute_stream_request_raises_when_remote_contract_is_ineligible(
|
||||
output_limit=None,
|
||||
)
|
||||
|
||||
async def _should_not_call_rust(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _should_not_call_rust(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
del self, plan
|
||||
raise AssertionError("rust executor should not be called")
|
||||
|
||||
async def _fake_get_upstream_client(*args: Any, **kwargs: Any) -> object:
|
||||
raise AssertionError("python fallback should not be used")
|
||||
|
||||
monkeypatch.setattr(chatmod, "is_remote_contract_eligible", lambda plan: False)
|
||||
monkeypatch.setattr(chatmod.RustExecutorClient, "execute_stream", _should_not_call_rust)
|
||||
monkeypatch.setattr(chatmod, "is_remote_execution_runtime_contract_eligible", lambda plan: False)
|
||||
monkeypatch.setattr(chatmod.ExecutionRuntimeClient, "execute_stream", _should_not_call_rust)
|
||||
monkeypatch.setattr(
|
||||
"src.clients.http_client.HTTPClientPool.get_upstream_client",
|
||||
_fake_get_upstream_client,
|
||||
|
||||
@@ -15,10 +15,10 @@ from src.api.handlers.base.cli_stream_mixin import CliStreamMixin
|
||||
from src.api.handlers.base.cli_sync_mixin import CliSyncMixin
|
||||
from src.api.handlers.base.stream_context import StreamContext
|
||||
from src.core.exceptions import ProviderNotAvailableException
|
||||
from src.services.request.rust_executor_client import (
|
||||
RustExecutorClientError,
|
||||
RustExecutorStreamResult,
|
||||
RustExecutorSyncResult,
|
||||
from src.services.request.execution_runtime_client import (
|
||||
ExecutionRuntimeClientError,
|
||||
ExecutionRuntimeStreamResult,
|
||||
ExecutionRuntimeSyncResult,
|
||||
)
|
||||
|
||||
|
||||
@@ -278,9 +278,9 @@ async def test_cli_process_sync_uses_rust_executor_when_available(
|
||||
pool_summary=None,
|
||||
)
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> ExecutionRuntimeSyncResult:
|
||||
assert getattr(plan, "provider_api_format") == "openai:cli"
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"id": "resp-rust-cli"},
|
||||
headers={"content-type": "application/json"},
|
||||
@@ -288,7 +288,7 @@ async def test_cli_process_sync_uses_rust_executor_when_available(
|
||||
|
||||
monkeypatch.setattr(taskmod, "TaskService", _FakeTaskService)
|
||||
monkeypatch.setattr(
|
||||
cli_sync_mod.RustExecutorClient,
|
||||
cli_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -376,10 +376,10 @@ async def test_cli_process_sync_aggregates_upstream_stream_after_rust(
|
||||
assert request_id == "req-cli-sync"
|
||||
return SimpleNamespace(id="agg-cli-1")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> ExecutionRuntimeSyncResult:
|
||||
assert getattr(plan, "provider_api_format") == "openai:cli"
|
||||
assert getattr(plan, "stream") is True
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_body_bytes=b"data: {\"id\":\"chunk-1\"}\n\ndata: [DONE]\n\n",
|
||||
headers={"content-type": "text/event-stream"},
|
||||
@@ -390,7 +390,7 @@ async def test_cli_process_sync_aggregates_upstream_stream_after_rust(
|
||||
|
||||
monkeypatch.setattr(taskmod, "TaskService", _FakeTaskService)
|
||||
monkeypatch.setattr(
|
||||
cli_sync_mod.RustExecutorClient,
|
||||
cli_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -451,16 +451,16 @@ async def test_cli_process_sync_raises_when_rust_unavailable(
|
||||
await kwargs["request_func"](provider, endpoint, key, candidate)
|
||||
raise AssertionError("task service should not reach Python local execution")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> ExecutionRuntimeSyncResult:
|
||||
del self, plan
|
||||
raise RustExecutorClientError("executor down")
|
||||
raise ExecutionRuntimeClientError("executor down")
|
||||
|
||||
async def _fake_get_upstream_client(*args: Any, **kwargs: Any) -> object:
|
||||
raise AssertionError("python fallback should not be used")
|
||||
|
||||
monkeypatch.setattr(taskmod, "TaskService", _FakeTaskService)
|
||||
monkeypatch.setattr(
|
||||
cli_sync_mod.RustExecutorClient,
|
||||
cli_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -485,7 +485,7 @@ async def test_cli_process_sync_raises_when_remote_contract_is_ineligible(
|
||||
) -> None:
|
||||
handler = _DummySyncHandler()
|
||||
monkeypatch.setattr(cli_sync_mod.config, "executor_backend", "rust")
|
||||
monkeypatch.setattr(cli_sync_mod, "is_remote_contract_eligible", lambda plan: False)
|
||||
monkeypatch.setattr(cli_sync_mod, "is_remote_execution_runtime_contract_eligible", lambda plan: False)
|
||||
_patch_proxy_resolver(monkeypatch)
|
||||
|
||||
class _FakeTaskService:
|
||||
@@ -512,7 +512,7 @@ async def test_cli_process_sync_raises_when_remote_contract_is_ineligible(
|
||||
await kwargs["request_func"](provider, endpoint, key, candidate)
|
||||
raise AssertionError("task service should not complete after local upstream attempt")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> ExecutionRuntimeSyncResult:
|
||||
raise AssertionError("rust executor should not be used when contract is ineligible")
|
||||
|
||||
async def _fake_get_upstream_client(*args: Any, **kwargs: Any) -> object:
|
||||
@@ -520,7 +520,7 @@ async def test_cli_process_sync_raises_when_remote_contract_is_ineligible(
|
||||
|
||||
monkeypatch.setattr(taskmod, "TaskService", _FakeTaskService)
|
||||
monkeypatch.setattr(
|
||||
cli_sync_mod.RustExecutorClient,
|
||||
cli_sync_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -550,9 +550,9 @@ async def test_cli_execute_stream_request_uses_rust_sync_bridge(
|
||||
monkeypatch.setattr(cli_stream_mod.config, "executor_backend", "rust")
|
||||
_patch_proxy_resolver(monkeypatch)
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> ExecutionRuntimeSyncResult:
|
||||
assert getattr(plan, "stream") is False
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"id": "sync-bridge-rust"},
|
||||
headers={"content-type": "application/json"},
|
||||
@@ -563,7 +563,7 @@ async def test_cli_execute_stream_request_uses_rust_sync_bridge(
|
||||
yield b"data: cli-bridge\n\n"
|
||||
|
||||
monkeypatch.setattr(
|
||||
cli_stream_mod.RustExecutorClient,
|
||||
cli_stream_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -641,22 +641,22 @@ async def test_cli_execute_stream_request_raises_when_rust_unavailable(
|
||||
)
|
||||
|
||||
if upstream_is_stream:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
del self, plan
|
||||
raise RustExecutorClientError("executor down")
|
||||
raise ExecutionRuntimeClientError("executor down")
|
||||
|
||||
monkeypatch.setattr(
|
||||
cli_stream_mod.RustExecutorClient,
|
||||
cli_stream_mod.ExecutionRuntimeClient,
|
||||
"execute_stream",
|
||||
_fake_execute_stream,
|
||||
)
|
||||
else:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> ExecutionRuntimeSyncResult:
|
||||
del self, plan
|
||||
raise RustExecutorClientError("executor down")
|
||||
raise ExecutionRuntimeClientError("executor down")
|
||||
|
||||
monkeypatch.setattr(
|
||||
cli_stream_mod.RustExecutorClient,
|
||||
cli_stream_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
@@ -690,16 +690,16 @@ async def test_cli_execute_stream_request_raises_when_remote_contract_is_ineligi
|
||||
ctx.client_api_format = "openai:cli"
|
||||
|
||||
monkeypatch.setattr(cli_stream_mod.config, "executor_backend", "rust")
|
||||
monkeypatch.setattr(cli_stream_mod, "is_remote_contract_eligible", lambda plan: False)
|
||||
monkeypatch.setattr(cli_stream_mod, "is_remote_execution_runtime_contract_eligible", lambda plan: False)
|
||||
_patch_proxy_resolver(monkeypatch)
|
||||
|
||||
async def _fake_get_upstream_client(*args: Any, **kwargs: Any) -> object:
|
||||
raise AssertionError("python fallback should not be used")
|
||||
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> RustExecutorSyncResult:
|
||||
async def _fake_execute_sync_json(self: object, plan: object) -> ExecutionRuntimeSyncResult:
|
||||
raise AssertionError("rust sync executor should not be used when contract is ineligible")
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
raise AssertionError("rust stream executor should not be used when contract is ineligible")
|
||||
|
||||
monkeypatch.setattr(
|
||||
@@ -707,12 +707,12 @@ async def test_cli_execute_stream_request_raises_when_remote_contract_is_ineligi
|
||||
_fake_get_upstream_client,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
cli_stream_mod.RustExecutorClient,
|
||||
cli_stream_mod.ExecutionRuntimeClient,
|
||||
"execute_sync_json",
|
||||
_fake_execute_sync_json,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
cli_stream_mod.RustExecutorClient,
|
||||
cli_stream_mod.ExecutionRuntimeClient,
|
||||
"execute_stream",
|
||||
_fake_execute_stream,
|
||||
)
|
||||
@@ -763,9 +763,9 @@ async def test_cli_execute_stream_request_uses_rust_native_stream(
|
||||
monkeypatch.setattr(cli_stream_mod.config, "executor_backend", "rust")
|
||||
_patch_proxy_resolver(monkeypatch)
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "stream") is True
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "text/event-stream", "x-upstream-test": "true"},
|
||||
byte_iterator=_iter_chunks(
|
||||
@@ -778,7 +778,7 @@ async def test_cli_execute_stream_request_uses_rust_native_stream(
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
cli_stream_mod.RustExecutorClient,
|
||||
cli_stream_mod.ExecutionRuntimeClient,
|
||||
"execute_stream",
|
||||
_fake_execute_stream,
|
||||
)
|
||||
|
||||
@@ -6,9 +6,9 @@ from unittest.mock import AsyncMock
|
||||
import pytest
|
||||
|
||||
from src.api.handlers.base.endpoint_checker import EndpointCheckRequest, HttpRequestExecutor
|
||||
from src.services.request.rust_executor_client import (
|
||||
RustExecutorStreamResult,
|
||||
RustExecutorSyncResult,
|
||||
from src.services.request.execution_runtime_client import (
|
||||
ExecutionRuntimeStreamResult,
|
||||
ExecutionRuntimeSyncResult,
|
||||
)
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ async def test_endpoint_checker_sync_prefers_rust_executor(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
from src.api.handlers.base import endpoint_checker as mod
|
||||
from src.services.request import rust_executor_client as rust_mod
|
||||
from src.services.request import execution_runtime_client as rust_mod
|
||||
|
||||
monkeypatch.setattr(mod.config, "executor_backend", "rust")
|
||||
|
||||
@@ -42,15 +42,15 @@ async def test_endpoint_checker_sync_prefers_rust_executor(
|
||||
async def _fake_execute_sync_json(
|
||||
self: object,
|
||||
plan: Any,
|
||||
) -> RustExecutorSyncResult:
|
||||
) -> ExecutionRuntimeSyncResult:
|
||||
captured["plan"] = plan
|
||||
return RustExecutorSyncResult(
|
||||
return ExecutionRuntimeSyncResult(
|
||||
status_code=200,
|
||||
response_json={"id": "resp_1", "usage": {"prompt_tokens": 1, "completion_tokens": 2}},
|
||||
headers={"content-type": "application/json"},
|
||||
)
|
||||
|
||||
monkeypatch.setattr(rust_mod.RustExecutorClient, "execute_sync_json", _fake_execute_sync_json)
|
||||
monkeypatch.setattr(rust_mod.ExecutionRuntimeClient, "execute_sync_json", _fake_execute_sync_json)
|
||||
|
||||
result = await executor.execute(
|
||||
EndpointCheckRequest(
|
||||
@@ -80,7 +80,7 @@ async def test_endpoint_checker_stream_prefers_rust_executor(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
from src.api.handlers.base import endpoint_checker as mod
|
||||
from src.services.request import rust_executor_client as rust_mod
|
||||
from src.services.request import execution_runtime_client as rust_mod
|
||||
|
||||
monkeypatch.setattr(mod.config, "executor_backend", "rust")
|
||||
|
||||
@@ -98,15 +98,15 @@ async def test_endpoint_checker_stream_prefers_rust_executor(
|
||||
|
||||
stream_ctx = _DummyStreamContext()
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: Any) -> RustExecutorStreamResult:
|
||||
return RustExecutorStreamResult(
|
||||
async def _fake_execute_stream(self: object, plan: Any) -> ExecutionRuntimeStreamResult:
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "text/event-stream"},
|
||||
byte_iterator=_byte_iter(),
|
||||
response_ctx=stream_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(rust_mod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(rust_mod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
result = await executor.execute(
|
||||
EndpointCheckRequest(
|
||||
|
||||
@@ -11,11 +11,11 @@ from fastapi.responses import JSONResponse, StreamingResponse
|
||||
|
||||
import src.api.handlers.gemini.video_handler as video_mod
|
||||
import src.services.proxy_node.resolver as resolver_mod
|
||||
import src.services.request.rust_executor_client as rust_client_mod
|
||||
import src.services.request.execution_runtime_client as rust_client_mod
|
||||
from src.api.handlers.gemini.video_handler import GeminiVeoHandler
|
||||
from src.core.api_format.conversion.internal_video import VideoStatus
|
||||
from src.core.exceptions import ProviderNotAvailableException
|
||||
from src.services.request.rust_executor_client import RustExecutorStreamResult
|
||||
from src.services.request.execution_runtime_client import ExecutionRuntimeStreamResult
|
||||
|
||||
|
||||
class _DummyStreamResponseCtx:
|
||||
@@ -189,19 +189,19 @@ async def test_handle_download_content_uses_rust_executor_with_proxy_snapshot(
|
||||
_fake_resolve_proxy_info_async,
|
||||
)
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "method") == "GET"
|
||||
assert getattr(plan, "url") == "https://storage.example.com/video.mp4"
|
||||
assert getattr(plan, "headers") == {"x-goog-api-key": "upstream-key"}
|
||||
assert getattr(plan, "proxy").url == "http://proxy.local:8080"
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "video/mp4", "x-rust-download": "true"},
|
||||
byte_iterator=_iter_chunks([b"gemini-", b"video"]),
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(rust_client_mod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(rust_client_mod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
response = await handler.handle_download_content(
|
||||
task_id="operations/ext-1",
|
||||
http_request=SimpleNamespace(),
|
||||
|
||||
@@ -11,9 +11,9 @@ import src.api.handlers.openai.video_handler as video_mod
|
||||
from src.api.handlers.openai.video_handler import OpenAIVideoHandler
|
||||
from src.core.api_format.conversion.internal_video import VideoStatus
|
||||
from src.core.exceptions import ProviderNotAvailableException
|
||||
from src.services.request.rust_executor_client import (
|
||||
RustExecutorClientError,
|
||||
RustExecutorStreamResult,
|
||||
from src.services.request.execution_runtime_client import (
|
||||
ExecutionRuntimeClientError,
|
||||
ExecutionRuntimeStreamResult,
|
||||
)
|
||||
|
||||
|
||||
@@ -61,19 +61,19 @@ async def test_handle_download_content_uses_rust_executor_for_direct_video_url(
|
||||
),
|
||||
)
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "method") == "GET"
|
||||
assert getattr(plan, "url") == "https://cdn.example.com/video.mp4"
|
||||
assert getattr(plan, "body").json_body is None
|
||||
assert getattr(plan, "body").body_bytes_b64 is None
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "video/mp4", "x-rust-download": "true"},
|
||||
byte_iterator=_iter_chunks([b"video-", b"bytes"]),
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(video_mod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(video_mod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
response = await handler.handle_download_content(
|
||||
task_id="task-1",
|
||||
@@ -128,21 +128,21 @@ async def test_handle_download_content_uses_rust_executor_for_upstream_content_e
|
||||
lambda original_headers, upstream_key, endpoint: {"authorization": f"Bearer {upstream_key}"},
|
||||
)
|
||||
|
||||
async def _fake_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _fake_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
assert getattr(plan, "method") == "GET"
|
||||
assert getattr(plan, "url") == "https://api.openai.com/v1/videos/ext-1/content"
|
||||
assert getattr(plan, "headers") == {"authorization": "Bearer upstream-key"}
|
||||
assert getattr(plan, "provider_id") == "prov-1"
|
||||
assert getattr(plan, "endpoint_id") == "ep-1"
|
||||
assert getattr(plan, "key_id") == "key-1"
|
||||
return RustExecutorStreamResult(
|
||||
return ExecutionRuntimeStreamResult(
|
||||
status_code=200,
|
||||
headers={"content-type": "video/mp4", "x-rust-download": "true"},
|
||||
byte_iterator=_iter_chunks([b"upstream-", b"video"]),
|
||||
response_ctx=dummy_ctx,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(video_mod.RustExecutorClient, "execute_stream", _fake_execute_stream)
|
||||
monkeypatch.setattr(video_mod.ExecutionRuntimeClient, "execute_stream", _fake_execute_stream)
|
||||
|
||||
response = await handler.handle_download_content(
|
||||
task_id="task-1",
|
||||
@@ -175,11 +175,11 @@ async def test_handle_download_content_raises_when_rust_executor_unavailable(
|
||||
),
|
||||
)
|
||||
|
||||
async def _failing_execute_stream(self: object, plan: object) -> RustExecutorStreamResult:
|
||||
async def _failing_execute_stream(self: object, plan: object) -> ExecutionRuntimeStreamResult:
|
||||
del self, plan
|
||||
raise RustExecutorClientError("executor down")
|
||||
raise ExecutionRuntimeClientError("executor down")
|
||||
|
||||
monkeypatch.setattr(video_mod.RustExecutorClient, "execute_stream", _failing_execute_stream)
|
||||
monkeypatch.setattr(video_mod.ExecutionRuntimeClient, "execute_stream", _failing_execute_stream)
|
||||
with pytest.raises(ProviderNotAvailableException):
|
||||
await handler.handle_download_content(
|
||||
task_id="task-1",
|
||||
|
||||
Reference in New Issue
Block a user