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:
ZheFox
2026-08-21 04:27:34 +08:00
parent fe38dcd294
commit 2c89202001
105 changed files with 7553 additions and 947 deletions
@@ -1640,6 +1640,21 @@ fn push_postgres_usage_client_family_filter(
.push_bind(client_family.to_ascii_lowercase());
}
fn push_postgres_usage_websocket_filter(
builder: &mut QueryBuilder<'_, Postgres>,
has_where: &mut bool,
is_websocket: Option<bool>,
) {
let Some(is_websocket) = is_websocket else {
return;
};
push_postgres_usage_where(builder, has_where);
builder
.push("LOWER(COALESCE(\"usage\".request_metadata->>'websocket_mode', 'false')) = ")
.push_bind(if is_websocket { "true" } else { "false" });
}
fn push_postgres_usage_exclude_unknown_filter(
builder: &mut QueryBuilder<'_, Postgres>,
has_where: &mut bool,
@@ -3015,6 +3030,7 @@ ORDER BY request_count DESC, "usage".provider_name ASC
has_where = true;
builder.push("\"usage\".is_stream = ").push_bind(is_stream);
}
push_postgres_usage_websocket_filter(&mut builder, &mut has_where, query.is_websocket);
if query.error_only {
builder.push(if has_where { " AND " } else { " WHERE " });
builder.push(
@@ -3127,6 +3143,7 @@ OR (\"usage\".error_message IS NOT NULL AND BTRIM(\"usage\".error_message) <> ''
has_where = true;
builder.push("\"usage\".is_stream = ").push_bind(is_stream);
}
push_postgres_usage_websocket_filter(&mut builder, &mut has_where, query.is_websocket);
if query.error_only {
builder.push(if has_where { " AND " } else { " WHERE " });
has_where = true;
@@ -3320,6 +3337,7 @@ OR (\"usage\".error_message IS NOT NULL AND BTRIM(\"usage\".error_message) <> ''
has_where = true;
builder.push("\"usage\".is_stream = ").push_bind(is_stream);
}
push_postgres_usage_websocket_filter(&mut builder, &mut has_where, query.is_websocket);
if query.error_only {
builder.push(if has_where { " AND " } else { " WHERE " });
builder.push(
@@ -3421,6 +3439,7 @@ OR (\"usage\".error_message IS NOT NULL AND BTRIM(\"usage\".error_message) <> ''
has_where = true;
builder.push("\"usage\".is_stream = ").push_bind(is_stream);
}
push_postgres_usage_websocket_filter(&mut builder, &mut has_where, query.is_websocket);
if query.error_only {
builder.push(if has_where { " AND " } else { " WHERE " });
has_where = true;
@@ -1,6 +1,6 @@
use chrono::{TimeZone, Utc};
use serde_json::json;
use sqlx::Row;
use sqlx::{Postgres, QueryBuilder, Row};
use std::sync::Arc;
use super::{
@@ -8,14 +8,15 @@ use super::{
attach_usage_routing_snapshot_metadata, attach_usage_settlement_pricing_snapshot_metadata,
clear_previous_request_body_facts, inflate_usage_json_value,
prepare_request_metadata_for_body_storage, prepare_usage_body_storage,
prepare_usage_upsert_context, request_body_capture_replaces_derived_facts,
resolved_read_usage_body_ref, resolved_write_usage_body_ref,
split_dashboard_daily_aggregate_range, split_dashboard_hourly_aggregate_range,
usage_body_capture_state_for_storage, usage_body_ref, usage_capture_update_allowed,
usage_effective_input_tokens, usage_http_audit_body_refs, usage_http_audit_capture_mode,
usage_routing_snapshot_from_usage, usage_settlement_pricing_snapshot_from_usage,
usage_total_input_context, AggregateRangeSplit, SqlxUsageReadRepository, UsageHttpAuditRefs,
UsageRoutingSnapshot, UsageSettlementPricingSnapshot, MAX_INLINE_USAGE_BODY_BYTES,
prepare_usage_upsert_context, push_postgres_usage_websocket_filter,
request_body_capture_replaces_derived_facts, resolved_read_usage_body_ref,
resolved_write_usage_body_ref, split_dashboard_daily_aggregate_range,
split_dashboard_hourly_aggregate_range, usage_body_capture_state_for_storage, usage_body_ref,
usage_capture_update_allowed, usage_effective_input_tokens, usage_http_audit_body_refs,
usage_http_audit_capture_mode, usage_routing_snapshot_from_usage,
usage_settlement_pricing_snapshot_from_usage, usage_total_input_context, AggregateRangeSplit,
SqlxUsageReadRepository, UsageHttpAuditRefs, UsageRoutingSnapshot,
UsageSettlementPricingSnapshot, MAX_INLINE_USAGE_BODY_BYTES,
SELECT_STALE_PENDING_USAGE_BATCH_SQL,
};
use crate::{PostgresPoolConfig, PostgresPoolFactory};
@@ -3247,6 +3248,26 @@ fn usage_sql_admin_record_filters_are_pushed_into_postgres_queries() {
assert!(source.contains("request_metadata->>'client_family'"));
assert!(source.contains("exclude_unknown_model_or_provider"));
assert!(source.contains("NOT IN ('unknown', 'unknow')"));
assert_eq!(
source
.matches("push_postgres_usage_websocket_filter(")
.count(),
5,
"the WebSocket filter must cover list/count and keyword list/count"
);
}
#[test]
fn usage_sql_websocket_filter_compares_json_metadata_without_boolean_casts() {
let mut builder = QueryBuilder::<Postgres>::new("SELECT * FROM usage");
let mut has_where = false;
push_postgres_usage_websocket_filter(&mut builder, &mut has_where, Some(true));
assert!(has_where);
assert!(builder
.sql()
.contains("LOWER(COALESCE(\"usage\".request_metadata->>'websocket_mode', 'false'))"));
assert!(!builder.sql().contains("::boolean"));
}
#[test]