mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 18:07:47 +08:00
feat(gateway): add Codex Live and OpenAI Realtime
Implement preflighted Live/Realtime WebSocket transports, protocol-aware authentication, usage auditing, UI filtering, and legacy Codex permission migration.
This commit is contained in:
@@ -1188,7 +1188,7 @@ async fn gateway_creates_admin_provider_locally_with_trusted_admin_principal() {
|
||||
.list_endpoints_by_provider_ids(std::slice::from_ref(&created.id))
|
||||
.await
|
||||
.expect("endpoints should list");
|
||||
assert_eq!(endpoints.len(), 4);
|
||||
assert_eq!(endpoints.len(), 5);
|
||||
let responses_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:responses")
|
||||
@@ -1205,6 +1205,10 @@ async fn gateway_creates_admin_provider_locally_with_trusted_admin_principal() {
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:image")
|
||||
.expect("image endpoint should exist");
|
||||
let live_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "codex:live")
|
||||
.expect("Codex Live endpoint should exist");
|
||||
assert_eq!(
|
||||
responses_endpoint.base_url,
|
||||
"https://chatgpt.com/backend-api/codex"
|
||||
@@ -1225,6 +1229,14 @@ async fn gateway_creates_admin_provider_locally_with_trusted_admin_principal() {
|
||||
assert_eq!(compact_endpoint.max_retries, Some(7));
|
||||
assert_eq!(search_endpoint.max_retries, Some(7));
|
||||
assert_eq!(image_endpoint.max_retries, Some(7));
|
||||
assert_eq!(live_endpoint.api_family.as_deref(), Some("codex"));
|
||||
assert_eq!(live_endpoint.endpoint_kind.as_deref(), Some("live"));
|
||||
assert_eq!(
|
||||
crate::api::ai::public_api_format_local_path(&live_endpoint.api_format),
|
||||
"/v1/live"
|
||||
);
|
||||
assert!(live_endpoint.custom_path.is_none());
|
||||
assert_eq!(live_endpoint.max_retries, Some(7));
|
||||
assert_eq!(
|
||||
responses_endpoint
|
||||
.config
|
||||
@@ -1253,6 +1265,7 @@ async fn gateway_creates_admin_provider_locally_with_trusted_admin_principal() {
|
||||
assert!(compact_endpoint.body_rules.is_none());
|
||||
assert!(search_endpoint.body_rules.is_none());
|
||||
assert!(image_endpoint.body_rules.is_none());
|
||||
assert!(live_endpoint.body_rules.is_none());
|
||||
assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0);
|
||||
|
||||
gateway_handle.abort();
|
||||
@@ -1296,6 +1309,14 @@ async fn gateway_updates_fixed_provider_and_reconciles_template_managed_endpoint
|
||||
);
|
||||
cli_endpoint.max_retries = Some(2);
|
||||
cli_endpoint.config = Some(json!({"upstream_stream_policy": "force_stream"}));
|
||||
let mut live_endpoint = sample_endpoint(
|
||||
"endpoint-codex-live",
|
||||
"provider-codex",
|
||||
"codex:live",
|
||||
"https://chatgpt.com/backend-api/codex",
|
||||
);
|
||||
live_endpoint.max_retries = Some(2);
|
||||
live_endpoint.custom_path = Some("/custom/live".to_string());
|
||||
let mut key = sample_key(
|
||||
"key-codex-oauth",
|
||||
"provider-codex",
|
||||
@@ -1307,7 +1328,7 @@ async fn gateway_updates_fixed_provider_and_reconciles_template_managed_endpoint
|
||||
|
||||
let provider_catalog_repository = Arc::new(InMemoryProviderCatalogReadRepository::seed(
|
||||
vec![provider],
|
||||
vec![cli_endpoint],
|
||||
vec![cli_endpoint, live_endpoint],
|
||||
vec![key],
|
||||
));
|
||||
|
||||
@@ -1367,7 +1388,7 @@ async fn gateway_updates_fixed_provider_and_reconciles_template_managed_endpoint
|
||||
.list_endpoints_by_provider_ids(&["provider-codex".to_string()])
|
||||
.await
|
||||
.expect("endpoints should list");
|
||||
assert_eq!(endpoints.len(), 4);
|
||||
assert_eq!(endpoints.len(), 5);
|
||||
let responses_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:responses")
|
||||
@@ -1384,11 +1405,23 @@ async fn gateway_updates_fixed_provider_and_reconciles_template_managed_endpoint
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "openai:image")
|
||||
.expect("image endpoint should exist");
|
||||
let live_endpoint = endpoints
|
||||
.iter()
|
||||
.find(|endpoint| endpoint.api_format == "codex:live")
|
||||
.expect("Codex Live endpoint should exist");
|
||||
|
||||
assert_eq!(responses_endpoint.max_retries, Some(9));
|
||||
assert_eq!(compact_endpoint.max_retries, Some(9));
|
||||
assert_eq!(search_endpoint.max_retries, Some(9));
|
||||
assert_eq!(image_endpoint.max_retries, Some(9));
|
||||
assert_eq!(live_endpoint.api_family.as_deref(), Some("codex"));
|
||||
assert_eq!(live_endpoint.endpoint_kind.as_deref(), Some("live"));
|
||||
assert_eq!(
|
||||
crate::api::ai::public_api_format_local_path(&live_endpoint.api_format),
|
||||
"/v1/live"
|
||||
);
|
||||
assert_eq!(live_endpoint.custom_path.as_deref(), Some("/custom/live"));
|
||||
assert_eq!(live_endpoint.max_retries, Some(9));
|
||||
assert_eq!(
|
||||
responses_endpoint
|
||||
.config
|
||||
|
||||
Reference in New Issue
Block a user