Files
Aether/_deprecated_py_src/services/request/execution_runtime_plan.py

275 lines
8.8 KiB
Python
Raw Normal View History

"""
Execution runtime 计划契约
用于在 Python 控制面和 Rust execution runtime 之间传递稳定的请求执行信息
当前阶段先服务于非流式 chat 路径的计划构建与本地执行拆分
"""
from __future__ import annotations
import base64
import json
from dataclasses import asdict, dataclass
from typing import Any
def _drop_none(value: Any) -> Any:
"""递归移除 None 字段,便于序列化为紧凑 payload。"""
if isinstance(value, dict):
return {key: _drop_none(item) for key, item in value.items() if item is not None}
if isinstance(value, list):
return [_drop_none(item) for item in value]
return value
@dataclass(slots=True)
class ExecutionPlanTimeouts:
connect_ms: int | None = None
read_ms: int | None = None
write_ms: int | None = None
pool_ms: int | None = None
total_ms: int | None = None
@dataclass(slots=True)
class ExecutionPlanBody:
json_body: Any = None
body_bytes_b64: str | None = None
body_ref: str | None = None
@dataclass(slots=True)
class ExecutionProxySnapshot:
enabled: bool
mode: str | None = None
node_id: str | None = None
label: str | None = None
url: str | None = None
extra: dict[str, Any] | None = None
@classmethod
def from_proxy_info(
cls,
proxy_info: dict[str, Any] | None,
*,
proxy_url: str | None = None,
mode_override: str | None = None,
node_id_override: str | None = None,
extra: dict[str, Any] | None = None,
) -> ExecutionProxySnapshot | None:
if not proxy_info and not proxy_url:
return None
mode = (
mode_override
or str(proxy_info.get("type") or proxy_info.get("mode") or "").strip()
or None
)
if not mode and proxy_url:
mode = proxy_url.split("://", 1)[0].strip().lower() or None
return cls(
enabled=True,
mode=mode,
node_id=node_id_override
or str((proxy_info or {}).get("node_id") or "").strip()
or None,
label=str((proxy_info or {}).get("label") or "").strip() or None,
url=str(proxy_url or (proxy_info or {}).get("url") or "").strip() or None,
extra=extra or None,
)
@dataclass(slots=True)
class ExecutionPlan:
request_id: str
candidate_id: str | None
provider_name: str
provider_id: str
endpoint_id: str
key_id: str
method: str
url: str
headers: dict[str, str]
body: ExecutionPlanBody
stream: bool
provider_api_format: str
client_api_format: str
model_name: str
content_type: str | None = None
content_encoding: str | None = None
proxy: ExecutionProxySnapshot | None = None
tls_profile: str | None = None
timeouts: ExecutionPlanTimeouts | None = None
def to_payload(self) -> dict[str, Any]:
return _drop_none(asdict(self))
_REMOTE_EXECUTION_RUNTIME_BYPASS_FORMATS = {"openai:cli", "openai:compact"}
def should_bypass_remote_execution_runtime_url(
url: str | None,
*,
provider_api_format: str | None = None,
client_api_format: str | None = None,
) -> bool:
normalized_url = str(url or "").strip().lower()
if not normalized_url:
return False
normalized_provider_api_format = str(provider_api_format or "").strip().lower()
normalized_client_api_format = str(client_api_format or "").strip().lower()
if (
normalized_provider_api_format not in _REMOTE_EXECUTION_RUNTIME_BYPASS_FORMATS
and normalized_client_api_format not in _REMOTE_EXECUTION_RUNTIME_BYPASS_FORMATS
):
return False
return "/backend-api/codex" in normalized_url or "/backendapi/codex" in normalized_url
def should_bypass_remote_execution_runtime(contract: ExecutionPlan) -> bool:
return should_bypass_remote_execution_runtime_url(
contract.url,
provider_api_format=contract.provider_api_format,
client_api_format=contract.client_api_format,
)
def is_remote_execution_runtime_proxy_supported(proxy: ExecutionProxySnapshot | None) -> bool:
proxy_mode = str((proxy.mode if proxy else "") or "").strip().lower()
return (
proxy is None
or (str(proxy.url or "").strip() != "" and proxy_mode not in {"tunnel"})
or (proxy_mode == "tunnel" and str(proxy.node_id or "").strip() != "")
)
def is_remote_execution_runtime_contract_eligible(contract: ExecutionPlan) -> bool:
content_encoding = str(contract.content_encoding or "").strip().lower()
has_json_body = contract.body.json_body is not None
has_raw_body = bool(str(contract.body.body_bytes_b64 or "").strip())
has_body = has_json_body or has_raw_body
return (
((not has_body and content_encoding == "") or has_body)
and (not has_json_body or content_encoding in {"", "gzip"} or has_raw_body)
and is_remote_execution_runtime_proxy_supported(contract.proxy)
and not should_bypass_remote_execution_runtime(contract)
)
def build_execution_plan_body(
payload: Any,
*,
content_type: str | None = None,
) -> ExecutionPlanBody:
normalized_content_type = str(content_type or "").strip().lower()
if isinstance(payload, dict):
return ExecutionPlanBody(json_body=payload)
if isinstance(payload, list) and "json" in normalized_content_type:
return ExecutionPlanBody(json_body=payload)
if isinstance(payload, (bytes, bytearray, memoryview)):
return ExecutionPlanBody(body_bytes_b64=base64.b64encode(bytes(payload)).decode("ascii"))
if isinstance(payload, str):
return ExecutionPlanBody(
body_bytes_b64=base64.b64encode(payload.encode("utf-8")).decode("ascii")
)
if payload is None:
return ExecutionPlanBody()
return ExecutionPlanBody(
body_bytes_b64=base64.b64encode(
json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
).decode("ascii")
)
@dataclass(slots=True)
class PreparedExecutionPlan:
"""本地执行所需的运行时上下文;`contract` 是可序列化的稳定边界。"""
contract: ExecutionPlan
payload: dict[str, Any]
headers: dict[str, str]
upstream_is_stream: bool
needs_conversion: bool
provider_type: str
request_timeout: float
delegate_config: dict[str, Any] | None = None
proxy_config: dict[str, Any] | None = None
envelope: Any = None
selected_base_url: str | None = None
client_content_encoding: str | None = None
proxy_info: dict[str, Any] | None = None
@property
def remote_eligible(self) -> bool:
return is_remote_execution_runtime_contract_eligible(self.contract)
async def build_proxy_snapshot(
proxy_config: dict[str, Any] | None,
*,
label: str = "adapter",
) -> ExecutionProxySnapshot | None:
if not proxy_config:
return None
try:
from src.services.proxy_node.resolver import (
build_proxy_url_async,
resolve_delegate_config_async,
resolve_proxy_info_async,
)
delegate_cfg = await resolve_delegate_config_async(proxy_config)
proxy_url: str | None = None
if proxy_config and not (delegate_cfg and delegate_cfg.get("tunnel")):
proxy_url = await build_proxy_url_async(proxy_config)
proxy_info = await resolve_proxy_info_async(proxy_config)
return ExecutionProxySnapshot.from_proxy_info(
proxy_info,
proxy_url=proxy_url,
mode_override="tunnel" if delegate_cfg and delegate_cfg.get("tunnel") else None,
node_id_override=(
str(delegate_cfg.get("node_id") or "").strip() or None
if delegate_cfg and delegate_cfg.get("tunnel")
else None
),
)
except Exception as exc:
from src.core.logger import logger
logger.warning("Build {} proxy snapshot failed: {}", label, exc)
return None
# Compatibility aliases for older call sites still using executor terminology.
should_bypass_remote_executor_url = should_bypass_remote_execution_runtime_url
should_bypass_remote_executor = should_bypass_remote_execution_runtime
is_remote_proxy_supported = is_remote_execution_runtime_proxy_supported
is_remote_contract_eligible = is_remote_execution_runtime_contract_eligible
__all__ = [
"ExecutionPlan",
"ExecutionPlanBody",
"ExecutionPlanTimeouts",
"ExecutionProxySnapshot",
"PreparedExecutionPlan",
"build_execution_plan_body",
"build_proxy_snapshot",
"is_remote_contract_eligible",
"is_remote_execution_runtime_contract_eligible",
"is_remote_execution_runtime_proxy_supported",
"is_remote_proxy_supported",
"should_bypass_remote_execution_runtime",
"should_bypass_remote_execution_runtime_url",
"should_bypass_remote_executor",
"should_bypass_remote_executor_url",
]