Merge commit 'refs/pr/585'

# Conflicts:
#	apps/aether-gateway/src/ai_serving/planner/passthrough/provider/family/request.rs
#	apps/aether-gateway/src/tests/ai_execute/stream_provider_gemini/local_cli.rs
#	apps/aether-gateway/src/tests/ai_execute/sync/gemini/cli.rs
#	apps/aether-gateway/src/tests/control/admin/provider_query.rs
#	crates/aether-provider-transport/src/gemini_cli/mod.rs
#	crates/aether-provider-transport/src/gemini_cli/request.rs
#	crates/aether-provider-transport/src/gemini_cli/url.rs
#	crates/aether-provider-transport/src/lib.rs
This commit is contained in:
fawney19
2026-05-28 13:19:42 +08:00
21 changed files with 867 additions and 404 deletions
@@ -42,12 +42,8 @@ pub fn force_upstream_streaming_for_provider(
provider_type: &str,
provider_api_format: &str,
) -> bool {
let provider_type = provider_type.trim();
(provider_type.eq_ignore_ascii_case("codex")
&& aether_ai_formats::is_openai_responses_format(provider_api_format))
|| (provider_type.eq_ignore_ascii_case("gemini_cli")
&& aether_ai_formats::normalize_api_format_alias(provider_api_format)
== "gemini:generate_content")
provider_type.trim().eq_ignore_ascii_case("codex")
&& aether_ai_formats::is_openai_responses_format(provider_api_format)
}
pub(crate) fn parse_upstream_stream_policy(
@@ -209,15 +205,11 @@ mod tests {
}
#[test]
fn forces_streaming_for_gemini_cli_generate_content() {
assert!(force_upstream_streaming_for_provider(
fn does_not_force_streaming_for_gemini_cli_generate_content() {
assert!(!force_upstream_streaming_for_provider(
"gemini_cli",
"gemini:generate_content"
));
assert!(force_upstream_streaming_for_provider(
" GEMINI_CLI ",
"gemini:generate_content"
));
assert!(!force_upstream_streaming_for_provider(
"google",
"gemini:generate_content"
@@ -1,4 +1,5 @@
pub const ANTIGRAVITY_PROVIDER_TYPE: &str = "antigravity";
pub const GEMINI_CLI_PROVIDER_TYPE: &str = "gemini_cli";
pub const KIRO_PROVIDER_TYPE: &str = "kiro";
pub const WINDSURF_PROVIDER_TYPE: &str = "windsurf";
pub const KIRO_ENVELOPE_NAME: &str = "kiro:generateAssistantResponse";
@@ -53,10 +54,10 @@ const PROVIDER_ADAPTATION_SURFACES: &[ProviderAdaptationDescriptor] = &[
},
ProviderAdaptationDescriptor {
surface: ProviderAdaptationSurface::GeminiCliV1Internal,
provider_type: None,
provider_type: Some(GEMINI_CLI_PROVIDER_TYPE),
envelope_name: GEMINI_CLI_V1INTERNAL_ENVELOPE_NAME,
anchor_api_format: "gemini:generate_content",
supports_request_bridge: false,
supports_request_bridge: true,
supports_sync_finalize_bridge: true,
supports_stream_bridge: true,
requires_eventstream_accept: false,
@@ -153,9 +154,11 @@ pub fn provider_adaptation_should_unwrap_stream_envelope(
mod tests {
use super::{
provider_adaptation_allows_sync_finalize_envelope, provider_adaptation_anchor_api_format,
provider_adaptation_descriptor_for_provider_type,
provider_adaptation_requires_eventstream_accept,
provider_adaptation_should_unwrap_stream_envelope, ANTIGRAVITY_V1INTERNAL_ENVELOPE_NAME,
GEMINI_CLI_V1INTERNAL_ENVELOPE_NAME, KIRO_ENVELOPE_NAME, WINDSURF_ENVELOPE_NAME,
GEMINI_CLI_PROVIDER_TYPE, GEMINI_CLI_V1INTERNAL_ENVELOPE_NAME, KIRO_ENVELOPE_NAME,
WINDSURF_ENVELOPE_NAME,
};
#[test]
@@ -194,6 +197,12 @@ mod tests {
GEMINI_CLI_V1INTERNAL_ENVELOPE_NAME,
"gemini:generate_content"
));
let gemini_cli_descriptor = provider_adaptation_descriptor_for_provider_type(
GEMINI_CLI_PROVIDER_TYPE,
"gemini:generate_content",
)
.expect("gemini cli descriptor should resolve by provider type");
assert!(gemini_cli_descriptor.supports_request_bridge);
assert!(provider_adaptation_requires_eventstream_accept(
Some(KIRO_ENVELOPE_NAME),
"claude:messages"