fix: prefer client session adapters

This commit is contained in:
RWDai
2026-05-05 12:25:07 +08:00
parent 17b06bd4d6
commit 82e7a0080e

View File

@@ -31,10 +31,11 @@ pub(crate) fn client_session_affinity_from_request(
let request = ClientSessionAffinityRequest { headers, body_json };
let client_family = detect_client_family(&request);
let session_key = explicit_aether_session_key(&request)
.or_else(|| extract_session_key_for_client_family(&request, client_family.as_str()))
.or_else(|| GenericSessionAffinityAdapter.extract_session_key(&request))
.or_else(|| CodexSessionAffinityAdapter.extract_session_key(&request))
.or_else(|| ClaudeCodeSessionAffinityAdapter.extract_session_key(&request))
.or_else(|| OpenCodeSessionAffinityAdapter.extract_session_key(&request));
.or_else(|| {
extract_session_key_from_other_specific_adapters(&request, client_family.as_str())
});
session_key
.map(|session_key| ClientSessionAffinity::new(Some(client_family), Some(session_key)))
@@ -64,6 +65,26 @@ fn specific_client_session_affinity_adapters() -> [&'static dyn ClientSessionAff
]
}
fn extract_session_key_for_client_family(
request: &ClientSessionAffinityRequest<'_>,
client_family: &str,
) -> Option<String> {
specific_client_session_affinity_adapters()
.into_iter()
.find(|adapter| adapter.family() == client_family)
.and_then(|adapter| adapter.extract_session_key(request))
}
fn extract_session_key_from_other_specific_adapters(
request: &ClientSessionAffinityRequest<'_>,
client_family: &str,
) -> Option<String> {
specific_client_session_affinity_adapters()
.into_iter()
.filter(|adapter| adapter.family() != client_family)
.find_map(|adapter| adapter.extract_session_key(request))
}
impl ClientSessionAffinityAdapter for GenericSessionAffinityAdapter {
fn family(&self) -> &'static str {
"generic"
@@ -325,6 +346,33 @@ mod tests {
);
}
#[test]
fn specific_adapter_wins_over_generic_body_session() {
let mut headers = HeaderMap::new();
headers.insert(
http::header::USER_AGENT,
HeaderValue::from_static("OpenCode/0.9"),
);
headers.insert(
"x-opencode-session-id",
HeaderValue::from_static("oc-session"),
);
headers.insert("x-opencode-agent-id", HeaderValue::from_static("reviewer"));
let body = json!({
"session_id": "body-session",
"agent_id": "body-agent"
});
let affinity = client_session_affinity_from_request(&headers, Some(&body))
.expect("affinity should build");
assert_eq!(affinity.client_family.as_deref(), Some("opencode"));
assert_eq!(
affinity.session_key.as_deref(),
Some("session=oc-session;agent=reviewer")
);
}
#[test]
fn missing_session_signal_returns_none() {
let headers = HeaderMap::new();