mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
refactor: 移除 Python upstream 依赖,清理全部 legacy/Python 兼容层
- 移除 upstream_base_url 参数及 AETHER_GATEWAY_UPSTREAM 环境变量,gateway 不再需要指向 Python 宿主 - 删除所有 LEGACY_*/PYTHON_* 常量、路由组、header 定义及 sunset/phaseout 机制 - 将 legacy_gateway_bridge 重命名为 internal_gateway,executor 相关命名统一为 execution_runtime - dev.sh 新增 Postgres/Redis 预检查,移除 upstream 相关启动参数和提示 - 新增 ai_public 路由处理器 - 全量适配 handler、test、state、control 等模块的命名和接口变更
This commit is contained in:
@@ -1,12 +1,38 @@
|
||||
use super::*;
|
||||
use crate::gateway::ai_pipeline::{planner as ai_planner, runtime as ai_runtime};
|
||||
use super::{
|
||||
attach_execution_path_header, build_internal_control_error_response,
|
||||
build_internal_finalize_decision, build_internal_gateway_fallback_plan_payload,
|
||||
build_internal_gateway_header_map, build_internal_gateway_passthrough_payload,
|
||||
build_internal_gateway_proxy_public_response, build_internal_gateway_request_parts,
|
||||
build_internal_gateway_resolve_payload, build_internal_gateway_uri,
|
||||
build_internal_tunnel_heartbeat_ack, build_management_token_payload, gateway_error_message,
|
||||
maybe_build_internal_finalize_video_response, parse_internal_tunnel_heartbeat_request,
|
||||
parse_internal_tunnel_node_status_request,
|
||||
};
|
||||
use crate::gateway::ai_pipeline::planner as ai_planner;
|
||||
use crate::gateway::constants::{
|
||||
CONTROL_EXECUTED_HEADER, EXECUTION_PATH_EXECUTION_RUNTIME_STREAM,
|
||||
EXECUTION_PATH_EXECUTION_RUNTIME_SYNC,
|
||||
};
|
||||
use crate::gateway::handlers::{
|
||||
InternalGatewayAuthContextRequest, InternalGatewayExecuteRequest, InternalGatewayResolveRequest,
|
||||
};
|
||||
use crate::gateway::{
|
||||
execute_execution_runtime_stream, execute_execution_runtime_sync,
|
||||
maybe_build_stream_plan_payload, maybe_build_sync_finalize_outcome,
|
||||
maybe_build_sync_plan_payload, AppState, GatewayControlDecision, GatewayError,
|
||||
GatewayPublicRequestContext, ProxyNodeHeartbeatMutation, ProxyNodeTunnelStatusMutation,
|
||||
};
|
||||
use axum::body::{Body, Bytes};
|
||||
use axum::http::{self, HeaderName, HeaderValue, Response};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::Json;
|
||||
use serde_json::json;
|
||||
|
||||
pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
remote_addr: &std::net::SocketAddr,
|
||||
request_body: Option<&axum::body::Bytes>,
|
||||
legacy_internal_gateway_allowed: bool,
|
||||
request_body: Option<&Bytes>,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(decision) = request_context.control_decision.as_ref() else {
|
||||
return Ok(None);
|
||||
@@ -14,17 +40,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
if decision.route_class.as_deref() != Some("internal_proxy") {
|
||||
return Ok(None);
|
||||
}
|
||||
if decision.route_family.as_deref() == Some("gateway_legacy") {
|
||||
if !legacy_internal_gateway_allowed {
|
||||
return Ok(Some(build_retired_internal_gateway_response()));
|
||||
}
|
||||
state.record_fallback_metric(
|
||||
GatewayFallbackMetricKind::LegacyInternalBridge,
|
||||
Some(decision),
|
||||
None,
|
||||
Some("legacy_internal_bridge"),
|
||||
GatewayFallbackReason::LegacyInternalGateway,
|
||||
);
|
||||
if decision.route_family.as_deref() == Some("internal_gateway") {
|
||||
if !remote_addr.ip().is_loopback() {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
http::StatusCode::FORBIDDEN,
|
||||
@@ -40,7 +56,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayResolveRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayResolveRequest>(request_body) {
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -95,7 +111,8 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayAuthContextRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayAuthContextRequest>(request_body)
|
||||
{
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -115,7 +132,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
let mut synthetic_decision = GatewayControlDecision::synthetic(
|
||||
"/",
|
||||
Some("internal_proxy".to_string()),
|
||||
Some("gateway_legacy".to_string()),
|
||||
Some("internal_gateway".to_string()),
|
||||
Some("auth_context".to_string()),
|
||||
Some(payload.auth_endpoint_signature),
|
||||
);
|
||||
@@ -145,7 +162,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayExecuteRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayExecuteRequest>(request_body) {
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -247,7 +264,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayExecuteRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayExecuteRequest>(request_body) {
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -270,6 +287,12 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
.as_deref()
|
||||
.unwrap_or(request_context.trace_id.as_str())
|
||||
.to_string();
|
||||
let body_is_empty = payload.body_base64.is_none()
|
||||
&& payload
|
||||
.body_json
|
||||
.as_object()
|
||||
.map(|value| value.is_empty())
|
||||
.unwrap_or(false);
|
||||
let Some(mut resolved) = crate::gateway::resolve_control_route(
|
||||
state,
|
||||
&parts.method,
|
||||
@@ -341,7 +364,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayExecuteRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayExecuteRequest>(request_body) {
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -370,10 +393,6 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
.as_object()
|
||||
.map(|value| value.is_empty())
|
||||
.unwrap_or(false);
|
||||
let body_bytes = match decode_legacy_gateway_request_body_bytes(&payload) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(response) => return Ok(Some(response)),
|
||||
};
|
||||
let Some(mut resolved) = crate::gateway::resolve_control_route(
|
||||
state,
|
||||
&parts.method,
|
||||
@@ -405,20 +424,6 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
}
|
||||
return Ok(Some(Json(planned).into_response()));
|
||||
}
|
||||
if let Some(executed_response) = ai_runtime::maybe_execute_sync_request(
|
||||
state,
|
||||
&parts,
|
||||
&body_bytes,
|
||||
trace_id.as_str(),
|
||||
Some(&resolved),
|
||||
)
|
||||
.await?
|
||||
{
|
||||
return Ok(Some(attach_execution_path_header(
|
||||
executed_response,
|
||||
EXECUTION_PATH_EXECUTION_RUNTIME_SYNC,
|
||||
)));
|
||||
}
|
||||
return Ok(Some(build_internal_gateway_proxy_public_response()));
|
||||
}
|
||||
Some("plan_stream")
|
||||
@@ -431,7 +436,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayExecuteRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayExecuteRequest>(request_body) {
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -454,10 +459,6 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
.as_deref()
|
||||
.unwrap_or(request_context.trace_id.as_str())
|
||||
.to_string();
|
||||
let body_bytes = match decode_legacy_gateway_request_body_bytes(&payload) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(response) => return Ok(Some(response)),
|
||||
};
|
||||
let Some(mut resolved) = crate::gateway::resolve_control_route(
|
||||
state,
|
||||
&parts.method,
|
||||
@@ -487,20 +488,6 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
}
|
||||
return Ok(Some(Json(planned).into_response()));
|
||||
}
|
||||
if let Some(executed_response) = ai_runtime::maybe_execute_stream_request(
|
||||
state,
|
||||
&parts,
|
||||
&body_bytes,
|
||||
trace_id.as_str(),
|
||||
Some(&resolved),
|
||||
)
|
||||
.await?
|
||||
{
|
||||
return Ok(Some(attach_execution_path_header(
|
||||
executed_response,
|
||||
EXECUTION_PATH_EXECUTION_RUNTIME_STREAM,
|
||||
)));
|
||||
}
|
||||
return Ok(Some(build_internal_gateway_proxy_public_response()));
|
||||
}
|
||||
Some("execute_sync")
|
||||
@@ -513,7 +500,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayExecuteRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayExecuteRequest>(request_body) {
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -536,10 +523,12 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
.as_deref()
|
||||
.unwrap_or(request_context.trace_id.as_str())
|
||||
.to_string();
|
||||
let body_bytes = match decode_legacy_gateway_request_body_bytes(&payload) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(response) => return Ok(Some(response)),
|
||||
};
|
||||
let body_is_empty = payload.body_base64.is_none()
|
||||
&& payload
|
||||
.body_json
|
||||
.as_object()
|
||||
.map(|value| value.is_empty())
|
||||
.unwrap_or(false);
|
||||
let Some(mut resolved) = crate::gateway::resolve_control_route(
|
||||
state,
|
||||
&parts.method,
|
||||
@@ -562,7 +551,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
&resolved,
|
||||
&payload.body_json,
|
||||
payload.body_base64.as_deref(),
|
||||
body_bytes.is_empty(),
|
||||
body_is_empty,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
@@ -589,21 +578,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(executed_response) = ai_runtime::maybe_execute_sync_request(
|
||||
state,
|
||||
&parts,
|
||||
&body_bytes,
|
||||
trace_id.as_str(),
|
||||
Some(&resolved),
|
||||
)
|
||||
.await?
|
||||
{
|
||||
return Ok(Some(attach_execution_path_header(
|
||||
executed_response,
|
||||
EXECUTION_PATH_EXECUTION_RUNTIME_SYNC,
|
||||
)));
|
||||
}
|
||||
return Ok(None);
|
||||
return Ok(Some(build_internal_gateway_proxy_public_response()));
|
||||
}
|
||||
Some("execute_stream")
|
||||
if request_context.request_path == "/api/internal/gateway/execute-stream" =>
|
||||
@@ -615,7 +590,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
};
|
||||
let payload =
|
||||
match serde_json::from_slice::<LegacyGatewayExecuteRequest>(request_body) {
|
||||
match serde_json::from_slice::<InternalGatewayExecuteRequest>(request_body) {
|
||||
Ok(payload) => payload,
|
||||
Err(_) => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
@@ -638,10 +613,6 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
.as_deref()
|
||||
.unwrap_or(request_context.trace_id.as_str())
|
||||
.to_string();
|
||||
let body_bytes = match decode_legacy_gateway_request_body_bytes(&payload) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(response) => return Ok(Some(response)),
|
||||
};
|
||||
let Some(mut resolved) = crate::gateway::resolve_control_route(
|
||||
state,
|
||||
&parts.method,
|
||||
@@ -688,21 +659,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(executed_response) = ai_runtime::maybe_execute_stream_request(
|
||||
state,
|
||||
&parts,
|
||||
&body_bytes,
|
||||
trace_id.as_str(),
|
||||
Some(&resolved),
|
||||
)
|
||||
.await?
|
||||
{
|
||||
return Ok(Some(attach_execution_path_header(
|
||||
executed_response,
|
||||
EXECUTION_PATH_EXECUTION_RUNTIME_STREAM,
|
||||
)));
|
||||
}
|
||||
return Ok(None);
|
||||
return Ok(Some(build_internal_gateway_proxy_public_response()));
|
||||
}
|
||||
Some("report_sync")
|
||||
if request_context.request_path == "/api/internal/gateway/report-sync" =>
|
||||
@@ -773,7 +730,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
)));
|
||||
}
|
||||
};
|
||||
let Some(synthetic_decision) = build_legacy_finalize_decision(&payload) else {
|
||||
let Some(synthetic_decision) = build_internal_finalize_decision(&payload) else {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
"Unsupported gateway sync finalize kind",
|
||||
@@ -797,7 +754,7 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
);
|
||||
return Ok(Some(response));
|
||||
}
|
||||
if let Some(response) = maybe_build_legacy_finalize_video_response(
|
||||
if let Some(response) = maybe_build_internal_finalize_video_response(
|
||||
state,
|
||||
trace_id.as_str(),
|
||||
&synthetic_decision,
|
||||
@@ -812,7 +769,12 @@ pub(crate) async fn maybe_build_local_internal_proxy_response_impl(
|
||||
"Unsupported gateway sync finalize kind",
|
||||
)));
|
||||
}
|
||||
_ => return Ok(None),
|
||||
_ => {
|
||||
return Ok(Some(build_internal_control_error_response(
|
||||
http::StatusCode::NOT_FOUND,
|
||||
"unsupported internal gateway route",
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if !remote_addr.ip().is_loopback() {
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
use super::*;
|
||||
|
||||
pub(crate) fn build_retired_internal_gateway_response() -> Response<Body> {
|
||||
attach_legacy_internal_gateway_deprecation_headers(
|
||||
(
|
||||
http::StatusCode::GONE,
|
||||
Json(json!({
|
||||
"detail": "legacy internal gateway route removed; use public proxy",
|
||||
})),
|
||||
)
|
||||
.into_response(),
|
||||
)
|
||||
}
|
||||
use crate::gateway::constants::{
|
||||
CONTROL_ACTION_HEADER, CONTROL_ACTION_PROXY_PUBLIC, CONTROL_EXECUTED_HEADER,
|
||||
CONTROL_EXECUTION_RUNTIME_CANDIDATE_KEY, EXECUTION_PATH_CONTROL_EXECUTE_STREAM,
|
||||
EXECUTION_PATH_CONTROL_EXECUTE_SYNC, EXECUTION_PATH_DISTRIBUTED_OVERLOADED,
|
||||
EXECUTION_PATH_EXECUTION_RUNTIME_STREAM, EXECUTION_PATH_EXECUTION_RUNTIME_SYNC,
|
||||
EXECUTION_PATH_HEADER, EXECUTION_PATH_LOCAL_AUTH_DENIED, EXECUTION_PATH_LOCAL_OVERLOADED,
|
||||
EXECUTION_PATH_LOCAL_RATE_LIMITED, EXECUTION_PATH_PUBLIC_PROXY_PASSTHROUGH,
|
||||
};
|
||||
use crate::gateway::handlers::admin::build_internal_control_error_response;
|
||||
use crate::gateway::handlers::{
|
||||
unix_secs_to_rfc3339, InternalTunnelHeartbeatRequest, InternalTunnelNodeStatusRequest,
|
||||
};
|
||||
use crate::gateway::{AppState, GatewayControlDecision, GatewayError, StoredProxyNode};
|
||||
use aether_data::repository::management_tokens::{
|
||||
StoredManagementToken, StoredManagementTokenUserSummary,
|
||||
};
|
||||
use axum::body::Body;
|
||||
use axum::http::{self, header::HeaderName, header::HeaderValue, Response};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::Json;
|
||||
use serde_json::{json, Value};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
fn insert_execution_runtime_candidate_fields(
|
||||
payload: &mut serde_json::Map<String, serde_json::Value>,
|
||||
value: bool,
|
||||
) {
|
||||
payload.insert(
|
||||
CONTROL_LEGACY_EXECUTION_RUNTIME_CANDIDATE_KEY.to_string(),
|
||||
json!(value),
|
||||
);
|
||||
payload.insert(
|
||||
CONTROL_EXECUTION_RUNTIME_CANDIDATE_KEY.to_string(),
|
||||
json!(value),
|
||||
@@ -85,32 +90,12 @@ pub(crate) fn build_internal_gateway_fallback_plan_payload(
|
||||
}
|
||||
|
||||
pub(crate) fn build_internal_gateway_proxy_public_response() -> Response<Body> {
|
||||
attach_legacy_internal_gateway_deprecation_headers(
|
||||
(
|
||||
http::StatusCode::CONFLICT,
|
||||
[(CONTROL_ACTION_HEADER, CONTROL_ACTION_PROXY_PUBLIC)],
|
||||
Json(json!({ "action": CONTROL_ACTION_PROXY_PUBLIC })),
|
||||
)
|
||||
.into_response(),
|
||||
(
|
||||
http::StatusCode::CONFLICT,
|
||||
[(CONTROL_ACTION_HEADER, CONTROL_ACTION_PROXY_PUBLIC)],
|
||||
Json(json!({ "action": CONTROL_ACTION_PROXY_PUBLIC })),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn attach_legacy_internal_gateway_deprecation_headers(
|
||||
mut response: Response<Body>,
|
||||
) -> Response<Body> {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static(LEGACY_INTERNAL_GATEWAY_PHASEOUT_HEADER),
|
||||
HeaderValue::from_static(LEGACY_INTERNAL_GATEWAY_PHASEOUT_STATUS),
|
||||
);
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static(LEGACY_INTERNAL_GATEWAY_SUNSET_DATE_HEADER),
|
||||
HeaderValue::from_static(LEGACY_INTERNAL_GATEWAY_SUNSET_DATE),
|
||||
);
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("sunset"),
|
||||
HeaderValue::from_static(LEGACY_INTERNAL_GATEWAY_SUNSET_HTTP_DATE),
|
||||
);
|
||||
response
|
||||
.into_response()
|
||||
}
|
||||
|
||||
pub(crate) fn attach_execution_path_header(
|
||||
@@ -141,51 +126,11 @@ pub(crate) fn resolve_local_proxy_execution_path(
|
||||
Some(EXECUTION_PATH_LOCAL_RATE_LIMITED) => EXECUTION_PATH_LOCAL_RATE_LIMITED,
|
||||
Some(EXECUTION_PATH_LOCAL_OVERLOADED) => EXECUTION_PATH_LOCAL_OVERLOADED,
|
||||
Some(EXECUTION_PATH_DISTRIBUTED_OVERLOADED) => EXECUTION_PATH_DISTRIBUTED_OVERLOADED,
|
||||
Some(EXECUTION_PATH_PUBLIC_PROXY_AFTER_EXECUTION_RUNTIME_MISS)
|
||||
| Some(LEGACY_EXECUTION_PATH_PUBLIC_PROXY_AFTER_EXECUTION_RUNTIME_MISS) => {
|
||||
EXECUTION_PATH_PUBLIC_PROXY_AFTER_EXECUTION_RUNTIME_MISS
|
||||
}
|
||||
Some(EXECUTION_PATH_PUBLIC_PROXY_PASSTHROUGH) => EXECUTION_PATH_PUBLIC_PROXY_PASSTHROUGH,
|
||||
_ => default_execution_path,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn decode_legacy_gateway_request_body_bytes(
|
||||
payload: &LegacyGatewayExecuteRequest,
|
||||
) -> Result<Bytes, Response<Body>> {
|
||||
if let Some(body_base64) = payload.body_base64.as_deref() {
|
||||
let decoded = base64::engine::general_purpose::STANDARD
|
||||
.decode(body_base64)
|
||||
.map_err(|_| {
|
||||
build_internal_control_error_response(
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
"invalid internal gateway body payload",
|
||||
)
|
||||
})?;
|
||||
return Ok(Bytes::from(decoded));
|
||||
}
|
||||
|
||||
let body_json = payload.body_json.clone();
|
||||
if body_json.is_null() {
|
||||
return Ok(Bytes::new());
|
||||
}
|
||||
if body_json
|
||||
.as_object()
|
||||
.map(|value| value.is_empty())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Ok(Bytes::new());
|
||||
}
|
||||
|
||||
let encoded = serde_json::to_vec(&body_json).map_err(|_| {
|
||||
build_internal_control_error_response(
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
"invalid internal gateway body payload",
|
||||
)
|
||||
})?;
|
||||
Ok(Bytes::from(encoded))
|
||||
}
|
||||
|
||||
pub(crate) fn build_internal_gateway_header_map(
|
||||
headers: &BTreeMap<String, String>,
|
||||
) -> Result<http::HeaderMap, Response<Body>> {
|
||||
@@ -267,7 +212,7 @@ pub(crate) fn build_internal_gateway_uri(
|
||||
})
|
||||
}
|
||||
|
||||
fn infer_legacy_finalize_signature(
|
||||
fn infer_internal_finalize_signature(
|
||||
payload: &crate::gateway::GatewaySyncReportRequest,
|
||||
) -> Option<String> {
|
||||
let report_context = payload.report_context.as_ref()?;
|
||||
@@ -317,10 +262,10 @@ fn infer_legacy_finalize_signature(
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn build_legacy_finalize_decision(
|
||||
pub(crate) fn build_internal_finalize_decision(
|
||||
payload: &crate::gateway::GatewaySyncReportRequest,
|
||||
) -> Option<GatewayControlDecision> {
|
||||
let signature = infer_legacy_finalize_signature(payload)?;
|
||||
let signature = infer_internal_finalize_signature(payload)?;
|
||||
let (public_path, route_family, route_kind) = match signature.as_str() {
|
||||
"openai:chat" => ("/v1/chat/completions", "openai", "chat"),
|
||||
"openai:cli" => ("/v1/responses", "openai", "cli"),
|
||||
@@ -345,10 +290,10 @@ pub(crate) fn build_legacy_finalize_decision(
|
||||
)
|
||||
}
|
||||
|
||||
fn build_legacy_finalize_video_plan(
|
||||
fn build_internal_finalize_video_plan(
|
||||
payload: &crate::gateway::GatewaySyncReportRequest,
|
||||
) -> Option<aether_contracts::ExecutionPlan> {
|
||||
let signature = infer_legacy_finalize_signature(payload)?;
|
||||
let signature = infer_internal_finalize_signature(payload)?;
|
||||
if !matches!(signature.as_str(), "openai:video" | "gemini:video") {
|
||||
return None;
|
||||
}
|
||||
@@ -380,9 +325,9 @@ fn build_legacy_finalize_video_plan(
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!({}));
|
||||
let url = match signature.as_str() {
|
||||
"openai:video" => "https://legacy.internal.invalid/v1/videos".to_string(),
|
||||
"openai:video" => "https://internal.gateway.invalid/v1/videos".to_string(),
|
||||
"gemini:video" => format!(
|
||||
"https://legacy.internal.invalid/v1beta/models/{}:predictLongRunning",
|
||||
"https://internal.gateway.invalid/v1beta/models/{}:predictLongRunning",
|
||||
model_name.clone().unwrap_or_else(|| "veo-3".to_string())
|
||||
),
|
||||
_ => return None,
|
||||
@@ -393,17 +338,17 @@ fn build_legacy_finalize_video_plan(
|
||||
candidate_id: None,
|
||||
provider_name: Some(provider_name.clone()),
|
||||
provider_id: context_text("provider_id")
|
||||
.unwrap_or_else(|| format!("legacy-{provider_name}-video-provider")),
|
||||
.unwrap_or_else(|| format!("internal-{provider_name}-video-provider")),
|
||||
endpoint_id: context_text("endpoint_id")
|
||||
.unwrap_or_else(|| format!("legacy-{provider_name}-video-endpoint")),
|
||||
.unwrap_or_else(|| format!("internal-{provider_name}-video-endpoint")),
|
||||
key_id: context_text("key_id")
|
||||
.or_else(|| context_text("api_key_id"))
|
||||
.unwrap_or_else(|| format!("legacy-{provider_name}-video-key")),
|
||||
.unwrap_or_else(|| format!("internal-{provider_name}-video-key")),
|
||||
method: "POST".to_string(),
|
||||
url,
|
||||
headers: std::collections::BTreeMap::from([(
|
||||
"authorization".to_string(),
|
||||
"Bearer legacy-internal-gateway".to_string(),
|
||||
"Bearer internal-gateway".to_string(),
|
||||
)]),
|
||||
content_type: Some("application/json".to_string()),
|
||||
content_encoding: None,
|
||||
@@ -425,10 +370,10 @@ fn build_legacy_finalize_video_plan(
|
||||
})
|
||||
}
|
||||
|
||||
fn build_legacy_finalize_video_request_path(
|
||||
fn build_internal_finalize_video_request_path(
|
||||
payload: &crate::gateway::GatewaySyncReportRequest,
|
||||
) -> Option<String> {
|
||||
let signature = infer_legacy_finalize_signature(payload)?;
|
||||
let signature = infer_internal_finalize_signature(payload)?;
|
||||
let report_context = payload.report_context.as_ref().and_then(Value::as_object);
|
||||
let context_text = |key: &str| {
|
||||
report_context
|
||||
@@ -475,13 +420,13 @@ fn build_legacy_finalize_video_request_path(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn maybe_build_legacy_finalize_video_response(
|
||||
pub(crate) async fn maybe_build_internal_finalize_video_response(
|
||||
state: &AppState,
|
||||
trace_id: &str,
|
||||
decision: &GatewayControlDecision,
|
||||
payload: &crate::gateway::GatewaySyncReportRequest,
|
||||
) -> Result<Option<Response<Body>>, GatewayError> {
|
||||
let Some(plan) = build_legacy_finalize_video_plan(payload) else {
|
||||
let Some(plan) = build_internal_finalize_video_plan(payload) else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
@@ -520,7 +465,7 @@ pub(crate) async fn maybe_build_legacy_finalize_video_response(
|
||||
if let Some(mut response) =
|
||||
crate::gateway::maybe_build_local_sync_finalize_response(trace_id, decision, payload)?
|
||||
{
|
||||
if let Some(request_path) = build_legacy_finalize_video_request_path(payload) {
|
||||
if let Some(request_path) = build_internal_finalize_video_request_path(payload) {
|
||||
state
|
||||
.video_tasks
|
||||
.apply_finalize_mutation(request_path.as_str(), payload.report_kind.as_str());
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
pub(crate) use super::*;
|
||||
use super::admin::build_internal_control_error_response;
|
||||
|
||||
mod gateway_helpers;
|
||||
pub(crate) use self::gateway_helpers::*;
|
||||
use self::gateway_helpers::*;
|
||||
pub(crate) use self::gateway_helpers::{
|
||||
build_management_token_payload, resolve_local_proxy_execution_path,
|
||||
};
|
||||
mod gateway;
|
||||
pub(crate) use self::gateway::maybe_build_local_internal_proxy_response_impl;
|
||||
|
||||
Reference in New Issue
Block a user