feat(codex): add OAuth fingerprint convergence

This commit is contained in:
elky
2026-08-13 09:57:17 +08:00
parent 654c4f6978
commit 8cf381b0c3
16 changed files with 1111 additions and 4 deletions
@@ -151,6 +151,8 @@ pub(crate) struct AdminProviderCreateRequest {
#[serde(default)]
pub(crate) keep_priority_on_conversion: Option<bool>,
#[serde(default)]
pub(crate) codex_fingerprint_convergence_enabled: Option<bool>,
#[serde(default)]
pub(crate) is_active: Option<bool>,
#[serde(default)]
pub(crate) concurrent_limit: Option<i32>,
@@ -210,6 +212,8 @@ pub(crate) struct AdminProviderUpdateRequest {
#[serde(default)]
pub(crate) keep_priority_on_conversion: Option<bool>,
#[serde(default)]
pub(crate) codex_fingerprint_convergence_enabled: Option<bool>,
#[serde(default)]
pub(crate) is_active: Option<bool>,
#[serde(default)]
pub(crate) concurrent_limit: Option<i32>,
@@ -218,6 +218,10 @@ pub(crate) fn build_admin_provider_summary_value(
"ops_architecture_id": ops_architecture_id,
"kiro_simulated_cache_enabled": kiro_simulated_cache_enabled,
"codex_cyber_flag_passthrough_enabled": codex_cyber_flag_passthrough_enabled(&provider.provider_type, provider.config.as_ref()),
"codex_fingerprint_convergence_enabled": crate::provider_transport::codex_fingerprint_convergence_enabled(
&provider.provider_type,
provider.config.as_ref(),
),
"ops_quota_alert_enabled": ops_quota_alert_enabled,
"created_at": endpoint_timestamp_or_now(provider.created_at_unix_ms, now_unix_secs),
"updated_at": endpoint_timestamp_or_now(provider.updated_at_unix_secs, now_unix_secs),
@@ -140,6 +140,28 @@ pub(crate) async fn build_admin_create_provider_record(
if let Some(value) = normalize_pool_advanced_config(payload.pool_advanced)? {
config_map.insert("pool_advanced".to_string(), value);
}
if let Some(enabled) = payload.codex_fingerprint_convergence_enabled {
if provider_type != "codex" && enabled {
return Err(
"codex_fingerprint_convergence_enabled 仅适用于 provider_type=codex".to_string(),
);
}
if provider_type == "codex" {
let codex_config = config_map
.entry(crate::provider_transport::CODEX_FINGERPRINT_CONFIG_NAMESPACE.to_string())
.or_insert_with(|| json!({}));
let Some(codex_config) = codex_config.as_object_mut() else {
return Err("config.codex 必须是 JSON 对象".to_string());
};
codex_config.insert(
crate::provider_transport::CODEX_FINGERPRINT_ENABLED_CONFIG_KEY.to_string(),
json!(enabled),
);
}
}
if provider_type != "codex" {
remove_codex_fingerprint_config(&mut config_map);
}
if let Some(value) = normalize_json_object(payload.failover_rules, "failover_rules")? {
config_map.insert("failover_rules".to_string(), value);
}
@@ -204,3 +226,46 @@ pub(crate) async fn build_admin_create_provider_record(
Ok((record, shift_existing_priorities_from))
}
fn remove_codex_fingerprint_config(config_map: &mut serde_json::Map<String, serde_json::Value>) {
let namespace = crate::provider_transport::CODEX_FINGERPRINT_CONFIG_NAMESPACE;
let key = crate::provider_transport::CODEX_FINGERPRINT_ENABLED_CONFIG_KEY;
let mut remove_namespace = false;
if let Some(codex_config) = config_map
.get_mut(namespace)
.and_then(|value| value.as_object_mut())
{
codex_config.remove(key);
remove_namespace = codex_config.is_empty();
}
if remove_namespace {
config_map.remove(namespace);
}
}
#[cfg(test)]
mod tests {
use serde_json::json;
#[test]
fn removing_fingerprint_setting_preserves_other_codex_config() {
let mut config = json!({
"codex": {
"fingerprint_convergence_enabled": true,
"pass_through_cyber_flag_interrupt": true
},
"other": {"kept": true}
})
.as_object()
.expect("config object")
.clone();
super::remove_codex_fingerprint_config(&mut config);
assert_eq!(
config["codex"],
json!({"pass_through_cyber_flag_interrupt": true})
);
assert_eq!(config["other"], json!({"kept": true}));
}
}
@@ -244,6 +244,32 @@ pub(crate) async fn build_admin_update_provider_record(
}
}
if fields.contains("codex_fingerprint_convergence_enabled") {
let Some(enabled) = payload.codex_fingerprint_convergence_enabled else {
return Err("codex_fingerprint_convergence_enabled 必须是布尔值".to_string());
};
if target_provider_type != "codex" && enabled {
return Err(
"codex_fingerprint_convergence_enabled 仅适用于 provider_type=codex".to_string(),
);
}
if target_provider_type == "codex" {
let codex_config = config_map
.entry(crate::provider_transport::CODEX_FINGERPRINT_CONFIG_NAMESPACE.to_string())
.or_insert_with(|| json!({}));
let Some(codex_config) = codex_config.as_object_mut() else {
return Err("config.codex 必须是 JSON 对象".to_string());
};
codex_config.insert(
crate::provider_transport::CODEX_FINGERPRINT_ENABLED_CONFIG_KEY.to_string(),
json!(enabled),
);
}
}
if target_provider_type != "codex" {
remove_codex_fingerprint_config(&mut config_map);
}
for (field_name, payload_value) in [
(
PROVIDER_MAX_TRANSFER_COUNT_CONFIG_KEY,
@@ -322,3 +348,46 @@ pub(crate) async fn build_admin_update_provider_record(
.map(|duration| duration.as_secs());
Ok(updated)
}
fn remove_codex_fingerprint_config(config_map: &mut serde_json::Map<String, serde_json::Value>) {
let namespace = crate::provider_transport::CODEX_FINGERPRINT_CONFIG_NAMESPACE;
let key = crate::provider_transport::CODEX_FINGERPRINT_ENABLED_CONFIG_KEY;
let mut remove_namespace = false;
if let Some(codex_config) = config_map
.get_mut(namespace)
.and_then(|value| value.as_object_mut())
{
codex_config.remove(key);
remove_namespace = codex_config.is_empty();
}
if remove_namespace {
config_map.remove(namespace);
}
}
#[cfg(test)]
mod tests {
use serde_json::json;
#[test]
fn removing_fingerprint_setting_preserves_other_codex_config() {
let mut config = json!({
"codex": {
"fingerprint_convergence_enabled": true,
"pass_through_cyber_flag_interrupt": true
},
"other": {"kept": true}
})
.as_object()
.expect("config object")
.clone();
super::remove_codex_fingerprint_config(&mut config);
assert_eq!(
config["codex"],
json!({"pass_through_cyber_flag_interrupt": true})
);
assert_eq!(config["other"], json!({"kept": true}));
}
}