mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-11 11:49:50 +08:00
@@ -190,15 +190,18 @@ pub(crate) async fn resolve_local_standard_candidate_payload_parts(
|
||||
});
|
||||
}
|
||||
|
||||
let Some(conversion_kind) =
|
||||
crate::ai_serving::request_conversion_kind(spec_metadata.api_format, provider_api_format)
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if let Some(skip_reason) = crate::ai_serving::request_conversion_transport_unsupported_reason(
|
||||
if !crate::ai_serving::request_pair_allowed_for_transport(
|
||||
transport,
|
||||
conversion_kind,
|
||||
spec_metadata.api_format,
|
||||
provider_api_format,
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(skip_reason) = crate::ai_serving::request_pair_transport_unsupported_reason(
|
||||
transport,
|
||||
spec_metadata.api_format,
|
||||
provider_api_format,
|
||||
) {
|
||||
mark_skipped_local_standard_candidate(
|
||||
state,
|
||||
@@ -271,7 +274,7 @@ pub(crate) async fn resolve_local_standard_candidate_payload_parts(
|
||||
planner_state,
|
||||
transport,
|
||||
candidate,
|
||||
crate::ai_serving::request_conversion_direct_auth(transport, conversion_kind),
|
||||
crate::ai_serving::request_pair_direct_auth(transport, provider_api_format),
|
||||
oauth_context,
|
||||
)
|
||||
.await
|
||||
@@ -353,6 +356,29 @@ pub(crate) async fn resolve_local_standard_candidate_payload_parts(
|
||||
upstream_is_stream,
|
||||
request_requires_body_stream_field(body_json, force_body_stream_field),
|
||||
);
|
||||
if let Err(err) = apply_transport_request_body_semantics(
|
||||
&mut provider_request_body,
|
||||
transport,
|
||||
provider_api_format,
|
||||
) {
|
||||
mark_skipped_local_standard_candidate_with_failure_diagnostic(
|
||||
state,
|
||||
input,
|
||||
trace_id,
|
||||
candidate,
|
||||
attempt.candidate_index,
|
||||
&attempt.candidate_id,
|
||||
"transport_request_body_semantics_failed",
|
||||
CandidateFailureDiagnostic::request_conversion_failed(
|
||||
spec_metadata.api_format,
|
||||
provider_api_format,
|
||||
"standard_family_transport_body_semantics",
|
||||
err.to_string(),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
return None;
|
||||
}
|
||||
if let Some(mapping) =
|
||||
crate::system_features::reasoning_model_directive_mapping_for_api_format_and_model(
|
||||
state,
|
||||
@@ -373,6 +399,29 @@ pub(crate) async fn resolve_local_standard_candidate_payload_parts(
|
||||
upstream_is_stream,
|
||||
request_requires_body_stream_field(body_json, force_body_stream_field),
|
||||
);
|
||||
if let Err(err) = apply_transport_request_body_semantics(
|
||||
&mut provider_request_body,
|
||||
transport,
|
||||
provider_api_format,
|
||||
) {
|
||||
mark_skipped_local_standard_candidate_with_failure_diagnostic(
|
||||
state,
|
||||
input,
|
||||
trace_id,
|
||||
candidate,
|
||||
attempt.candidate_index,
|
||||
&attempt.candidate_id,
|
||||
"transport_request_body_semantics_failed",
|
||||
CandidateFailureDiagnostic::request_conversion_failed(
|
||||
spec_metadata.api_format,
|
||||
provider_api_format,
|
||||
"standard_family_transport_body_semantics_after_model_directives",
|
||||
err.to_string(),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(kiro_auth) = kiro_auth.as_ref() {
|
||||
@@ -401,6 +450,7 @@ pub(crate) async fn resolve_local_standard_candidate_payload_parts(
|
||||
&prepared_candidate.mapped_model,
|
||||
provider_api_format,
|
||||
upstream_is_stream,
|
||||
Some(&provider_request_body),
|
||||
) {
|
||||
Some(url) => url,
|
||||
None => {
|
||||
@@ -480,6 +530,18 @@ pub(crate) async fn resolve_local_standard_candidate_payload_parts(
|
||||
})
|
||||
}
|
||||
|
||||
fn apply_transport_request_body_semantics(
|
||||
provider_request_body: &mut Value,
|
||||
transport: &GatewayProviderTransportSnapshot,
|
||||
provider_api_format: &str,
|
||||
) -> Result<(), crate::ai_serving::transport::TransportRequestBodySemanticsError> {
|
||||
crate::ai_serving::transport::apply_transport_request_body_semantics(
|
||||
provider_request_body,
|
||||
transport,
|
||||
provider_api_format,
|
||||
)
|
||||
}
|
||||
|
||||
async fn resolve_local_gemini_image_to_openai_image_candidate_payload_parts(
|
||||
state: &AppState,
|
||||
parts: &http::request::Parts,
|
||||
|
||||
@@ -40,6 +40,7 @@ pub(crate) use self::openai::{
|
||||
map_openai_reasoning_effort_to_gemini_budget, maybe_build_stream_local_decision_payload,
|
||||
maybe_build_stream_local_openai_responses_decision_payload,
|
||||
maybe_build_sync_local_decision_payload,
|
||||
maybe_build_sync_local_openai_embedding_decision_payload,
|
||||
maybe_build_sync_local_openai_responses_decision_payload, parse_openai_stop_sequences,
|
||||
resolve_openai_chat_max_tokens, set_local_openai_chat_execution_exhausted_diagnostic,
|
||||
value_as_u64,
|
||||
@@ -68,14 +69,16 @@ pub(crate) fn build_standard_upstream_url(
|
||||
mapped_model: &str,
|
||||
provider_api_format: &str,
|
||||
upstream_is_stream: bool,
|
||||
provider_request_body: Option<&serde_json::Value>,
|
||||
) -> Option<String> {
|
||||
crate::ai_serving::build_provider_transport_request_url(
|
||||
crate::ai_serving::build_provider_transport_request_url_for_request_body(
|
||||
transport,
|
||||
provider_api_format,
|
||||
Some(mapped_model),
|
||||
upstream_is_stream,
|
||||
parts.uri.query(),
|
||||
None,
|
||||
provider_request_body,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -87,6 +90,14 @@ pub(crate) async fn maybe_build_sync_local_standard_decision_payload(
|
||||
body_json: &serde_json::Value,
|
||||
plan_kind: &str,
|
||||
) -> Result<Option<AiExecutionDecision>, GatewayError> {
|
||||
if let Some(payload) = self::openai::maybe_build_sync_local_openai_embedding_decision_payload(
|
||||
state, parts, trace_id, decision, body_json, plan_kind,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
return Ok(Some(payload));
|
||||
}
|
||||
|
||||
if let Some(payload) = self::claude::maybe_build_sync_local_claude_decision_payload(
|
||||
state, parts, trace_id, decision, body_json, plan_kind,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
use crate::ai_serving::resolve_openai_embedding_sync_spec as resolve_surface_sync_spec;
|
||||
use crate::ai_serving::GatewayControlDecision;
|
||||
use crate::{AiExecutionDecision, AppState, GatewayError};
|
||||
|
||||
use super::super::family::maybe_build_sync_via_standard_family_payload;
|
||||
|
||||
pub(crate) fn resolve_sync_spec(
|
||||
plan_kind: &str,
|
||||
) -> Option<super::super::family::LocalStandardSpec> {
|
||||
resolve_surface_sync_spec(plan_kind)
|
||||
}
|
||||
|
||||
pub(crate) async fn maybe_build_sync_local_openai_embedding_decision_payload(
|
||||
state: &AppState,
|
||||
parts: &http::request::Parts,
|
||||
trace_id: &str,
|
||||
decision: &GatewayControlDecision,
|
||||
body_json: &serde_json::Value,
|
||||
plan_kind: &str,
|
||||
) -> Result<Option<AiExecutionDecision>, GatewayError> {
|
||||
maybe_build_sync_via_standard_family_payload(
|
||||
state,
|
||||
parts,
|
||||
trace_id,
|
||||
decision,
|
||||
body_json,
|
||||
plan_kind,
|
||||
resolve_sync_spec,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
mod chat;
|
||||
mod image_intent;
|
||||
mod embedding;
|
||||
mod responses;
|
||||
|
||||
pub(crate) use crate::ai_serving::{
|
||||
@@ -16,6 +17,7 @@ pub(crate) use chat::{
|
||||
set_local_openai_chat_execution_exhausted_diagnostic,
|
||||
};
|
||||
pub(super) use image_intent::openai_request_is_image_generation_intent;
|
||||
pub(crate) use embedding::maybe_build_sync_local_openai_embedding_decision_payload;
|
||||
pub(crate) use responses::{
|
||||
build_local_openai_responses_stream_attempt_source_for_kind,
|
||||
build_local_openai_responses_stream_plan_and_reports_for_kind,
|
||||
|
||||
Reference in New Issue
Block a user