mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
Merge branch 'aether-rust-pioneer' of https://github.com/fawney19/Aether into codex/codex-image-progress-heartbeat
# Conflicts: # frontend/src/features/usage/components/__tests__/HorizontalRequestTimeline.spec.ts
This commit is contained in:
@@ -58,6 +58,17 @@ pub use crate::formats::openai::shared::{
|
||||
pub use crate::formats::shared::error_body::{
|
||||
build_core_error_body_for_client_format, is_core_error_finalize_kind, LocalCoreSyncErrorKind,
|
||||
};
|
||||
pub use crate::formats::shared::image_bridge::{
|
||||
build_gemini_image_request_body_from_openai_image_request,
|
||||
build_gemini_image_response_from_openai_image_response,
|
||||
build_gemini_image_response_from_openai_responses_image_response,
|
||||
build_openai_image_provider_body_from_response_stream_sync_body,
|
||||
build_openai_image_request_body_from_gemini_image_request,
|
||||
build_openai_image_response_from_gemini_response,
|
||||
build_openai_image_response_from_response_stream_sync_body, gemini_request_is_image_generation,
|
||||
resolve_requested_gemini_image_model_for_request, GeminiImageRequestForOpenAi,
|
||||
OpenAiImageRequestForGemini,
|
||||
};
|
||||
pub use crate::formats::shared::model_directives::{
|
||||
apply_model_directive_mapping_patch, apply_model_directive_overrides_from_model,
|
||||
apply_model_directive_overrides_from_request, claude_model_uses_adaptive_effort,
|
||||
|
||||
@@ -368,6 +368,7 @@ pub fn maybe_build_openai_image_sync_finalize_product(
|
||||
report_kind: &str,
|
||||
status_code: u16,
|
||||
report_context: Option<&Value>,
|
||||
body_json: Option<&Value>,
|
||||
body_base64: Option<&str>,
|
||||
) -> Result<Option<OpenAiImageSyncFinalizeProduct>, AiSurfaceFinalizeError> {
|
||||
if report_kind != OPENAI_IMAGE_SYNC_FINALIZE_REPORT_KIND || status_code >= 400 {
|
||||
@@ -384,6 +385,45 @@ pub fn maybe_build_openai_image_sync_finalize_product(
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
let provider_api_format = report_context
|
||||
.get("provider_api_format")
|
||||
.and_then(Value::as_str)
|
||||
.map(str::trim)
|
||||
.unwrap_or_default();
|
||||
if provider_api_format == "gemini:generate_content" {
|
||||
let Some(provider_body_json) = body_json else {
|
||||
return Ok(None);
|
||||
};
|
||||
let Some(client_body_json) =
|
||||
crate::formats::shared::image_bridge::build_openai_image_response_from_gemini_response(
|
||||
provider_body_json,
|
||||
Some(report_context),
|
||||
)
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
return Ok(Some(OpenAiImageSyncFinalizeProduct {
|
||||
client_body_json,
|
||||
provider_body_json: provider_body_json.clone(),
|
||||
}));
|
||||
}
|
||||
if provider_api_format != "openai:image" {
|
||||
return Ok(None);
|
||||
}
|
||||
if let Some(provider_body_json) = body_json {
|
||||
if provider_body_json.get("output").is_some() && provider_body_json.get("data").is_none() {
|
||||
let Some(client_body_json) = crate::formats::shared::image_bridge::build_openai_image_response_from_response_stream_sync_body(
|
||||
provider_body_json,
|
||||
Some(report_context),
|
||||
) else {
|
||||
return Ok(None);
|
||||
};
|
||||
return Ok(Some(OpenAiImageSyncFinalizeProduct {
|
||||
client_body_json,
|
||||
provider_body_json: provider_body_json.clone(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
let Some(body_base64) = body_base64 else {
|
||||
return Ok(None);
|
||||
};
|
||||
@@ -689,6 +729,7 @@ mod tests {
|
||||
"openai_image_sync_finalize",
|
||||
200,
|
||||
Some(&report_context),
|
||||
None,
|
||||
Some(&body_base64),
|
||||
)
|
||||
.expect("finalize should succeed")
|
||||
|
||||
1043
crates/aether-ai-formats/src/formats/shared/image_bridge.rs
Normal file
1043
crates/aether-ai-formats/src/formats/shared/image_bridge.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@ use std::fmt;
|
||||
|
||||
pub mod error_body;
|
||||
pub mod family;
|
||||
pub mod image_bridge;
|
||||
pub mod model_directives;
|
||||
pub mod passthrough;
|
||||
pub mod request;
|
||||
|
||||
@@ -595,6 +595,17 @@ pub fn maybe_build_standard_cross_format_sync_product(
|
||||
let provider_api_format = provider_api_format.trim().to_ascii_lowercase();
|
||||
let client_api_format = client_api_format.trim().to_ascii_lowercase();
|
||||
|
||||
if provider_api_format == "openai:image" && client_api_format == "gemini:generate_content" {
|
||||
let client_body_json = crate::formats::shared::image_bridge::build_gemini_image_response_from_openai_responses_image_response(
|
||||
&provider_body_json,
|
||||
Some(report_context),
|
||||
)?;
|
||||
return Some(StandardCrossFormatSyncProduct {
|
||||
client_body_json,
|
||||
provider_body_json,
|
||||
});
|
||||
}
|
||||
|
||||
let client_body_json = if is_standard_chat_finalize_kind(report_kind) {
|
||||
sync_chat_response_conversion_kind(&provider_api_format, &client_api_format)?;
|
||||
convert_standard_chat_response(
|
||||
|
||||
@@ -27,7 +27,12 @@ pub fn maybe_bridge_standard_sync_json_to_stream(
|
||||
) -> Result<Option<SyncToStreamBridgeOutcome>, AiSurfaceFinalizeError> {
|
||||
let provider_api_format = normalize_api_format(provider_api_format);
|
||||
let client_api_format = normalize_api_format(client_api_format);
|
||||
if provider_api_format == "openai:image" && client_api_format == "openai:image" {
|
||||
if client_api_format == "openai:image"
|
||||
&& matches!(
|
||||
provider_api_format.as_str(),
|
||||
"openai:image" | "gemini:generate_content"
|
||||
)
|
||||
{
|
||||
return maybe_bridge_openai_image_sync_json_to_stream(provider_body_json, report_context);
|
||||
}
|
||||
if !is_standard_api_format(provider_api_format.as_str())
|
||||
@@ -67,6 +72,36 @@ fn maybe_bridge_openai_image_sync_json_to_stream(
|
||||
provider_body_json: &Value,
|
||||
report_context: Option<&Value>,
|
||||
) -> Result<Option<SyncToStreamBridgeOutcome>, AiSurfaceFinalizeError> {
|
||||
let provider_api_format = report_context
|
||||
.and_then(|value| value.get("provider_api_format"))
|
||||
.and_then(Value::as_str)
|
||||
.map(str::trim)
|
||||
.unwrap_or("openai:image");
|
||||
let owned_response;
|
||||
let provider_body_json = if provider_api_format == "gemini:generate_content" {
|
||||
let Some(converted) =
|
||||
crate::formats::shared::image_bridge::build_openai_image_response_from_gemini_response(
|
||||
provider_body_json,
|
||||
report_context,
|
||||
)
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
owned_response = converted;
|
||||
&owned_response
|
||||
} else if provider_body_json.get("output").is_some() && provider_body_json.get("data").is_none()
|
||||
{
|
||||
let Some(converted) = crate::formats::shared::image_bridge::build_openai_image_response_from_response_stream_sync_body(
|
||||
provider_body_json,
|
||||
report_context,
|
||||
) else {
|
||||
return Ok(None);
|
||||
};
|
||||
owned_response = converted;
|
||||
&owned_response
|
||||
} else {
|
||||
provider_body_json
|
||||
};
|
||||
let Some(response) = provider_body_json.as_object() else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user