feat: 引入 Rust executor/gateway sidecar 及 Python 侧双后端适配

- 新增 Rust workspace crates: aether-contracts, aether-executor, aether-gateway
- aether-executor: 支持 Unix Socket/TCP 双传输模式,处理同步/流式上游请求
- aether-gateway: 作为本地主入口代理,集成 /api/internal/gateway/resolve 认证预解析
- Python 侧新增 ExecutionPlan 契约和 RustExecutorClient,各 handler 支持
  executor_backend=rust 时将可序列化请求转发给 Rust executor 执行
- 重构 dev.sh 支持 executor/gateway 进程编排与生命周期管理
- 新增 internal gateway 路由,提供 resolve/passthrough 端点
- handler 层(chat/cli/video/endpoint_checker 等)全面适配 Rust executor 回退逻辑
- pipeline 层支持 trusted auth context 跳过重复认证
- 新增 Rust CI workflow 及对应测试用例
This commit is contained in:
fawney19
2026-03-21 12:57:09 +08:00
parent 46737d32f8
commit d735b6316f
79 changed files with 19032 additions and 522 deletions

View File

@@ -0,0 +1,173 @@
from __future__ import annotations
from types import SimpleNamespace
from unittest.mock import AsyncMock
import pytest
import src.services.task.video.cancel as cancel_mod
import src.services.request.rust_executor_client as rust_client_mod
from src.core.api_format.conversion.internal_video import VideoStatus
from src.services.request.rust_executor_client import RustExecutorSyncResult
from src.services.task.video.cancel import VideoTaskCancelService
class _Query:
def __init__(self, result: object) -> None:
self._result = result
def filter(self, *args: object, **kwargs: object) -> "_Query":
del args, kwargs
return self
def first(self) -> object:
return self._result
class _FakeDB:
def __init__(self, *results: object) -> None:
self._results = list(results)
self.committed = False
def query(self, model: object) -> _Query:
del model
return _Query(self._results.pop(0))
def commit(self) -> None:
self.committed = True
@pytest.mark.asyncio
async def test_video_cancel_service_uses_rust_for_openai_delete(
monkeypatch: pytest.MonkeyPatch,
) -> None:
endpoint = SimpleNamespace(
id="ep-1",
provider_id="prov-1",
api_family="openai",
endpoint_kind="video",
base_url="https://api.openai.com",
)
key = SimpleNamespace(id="key-1", api_key="encrypted")
db = _FakeDB(endpoint, key)
service = VideoTaskCancelService(db)
task = SimpleNamespace(
id="task-1",
status=VideoStatus.PROCESSING.value,
external_task_id="ext-1",
endpoint_id="ep-1",
key_id="key-1",
request_id="req-1",
model="sora-2",
completed_at=None,
updated_at=None,
)
monkeypatch.setattr(cancel_mod.config, "executor_backend", "rust")
monkeypatch.setattr(
rust_client_mod.RustExecutorClient,
"execute_sync_json",
AsyncMock(
return_value=RustExecutorSyncResult(
status_code=204,
headers={},
response_json=None,
response_body_bytes=None,
)
),
)
monkeypatch.setattr(
"src.core.crypto.crypto_service.decrypt",
lambda value: "upstream-key",
)
monkeypatch.setattr(
"src.core.api_format.build_upstream_headers_for_endpoint",
lambda *args, **kwargs: {"authorization": "Bearer upstream-key"},
)
monkeypatch.setattr(
"src.services.provider.transport.build_provider_url",
lambda endpoint, is_stream=False, key=None: "https://api.openai.com/v1/videos",
)
monkeypatch.setattr(
"src.clients.http_client.HTTPClientPool.get_default_client_async",
AsyncMock(side_effect=AssertionError("python fallback should not run")),
)
monkeypatch.setattr(cancel_mod.UsageService, "finalize_void", lambda *args, **kwargs: True)
result = await service.cancel_task(
task=task,
task_id="task-1",
original_headers={"x-test": "1"},
)
assert result is None
assert db.committed is True
assert task.status == VideoStatus.CANCELLED.value
@pytest.mark.asyncio
async def test_video_cancel_service_uses_rust_for_gemini_cancel(
monkeypatch: pytest.MonkeyPatch,
) -> None:
endpoint = SimpleNamespace(
id="ep-1",
provider_id="prov-1",
api_family="gemini",
endpoint_kind="video",
base_url="https://generativelanguage.googleapis.com",
)
key = SimpleNamespace(id="key-1", api_key="encrypted")
db = _FakeDB(endpoint, key)
service = VideoTaskCancelService(db)
task = SimpleNamespace(
id="task-1",
status=VideoStatus.PROCESSING.value,
external_task_id="operations/ext-1",
endpoint_id="ep-1",
key_id="key-1",
request_id="req-1",
model="veo-3",
completed_at=None,
updated_at=None,
)
monkeypatch.setattr(cancel_mod.config, "executor_backend", "rust")
execute_sync = AsyncMock(
return_value=RustExecutorSyncResult(
status_code=200,
headers={"content-type": "application/json"},
response_json={"ok": True},
response_body_bytes=None,
)
)
monkeypatch.setattr(rust_client_mod.RustExecutorClient, "execute_sync_json", execute_sync)
monkeypatch.setattr(
"src.core.crypto.crypto_service.decrypt",
lambda value: "upstream-key",
)
monkeypatch.setattr(
"src.core.api_format.build_upstream_headers_for_endpoint",
lambda *args, **kwargs: {"x-goog-api-key": "upstream-key"},
)
monkeypatch.setattr(
"src.services.provider.auth.get_provider_auth",
AsyncMock(return_value=SimpleNamespace(auth_header="authorization", auth_value="Bearer token")),
)
monkeypatch.setattr(
"src.clients.http_client.HTTPClientPool.get_default_client_async",
AsyncMock(side_effect=AssertionError("python fallback should not run")),
)
monkeypatch.setattr(cancel_mod.UsageService, "finalize_void", lambda *args, **kwargs: True)
result = await service.cancel_task(
task=task,
task_id="task-1",
original_headers={"x-test": "1"},
)
assert result is None
assert db.committed is True
assert task.status == VideoStatus.CANCELLED.value
plan = execute_sync.await_args.args[0]
assert plan.method == "POST"
assert plan.body.json_body == {}