cc-switch-tui 0.1.1

All-in-One Assistant for Claude Code, Codex, Gemini, OpenCode, OpenClaw & Hermes
Documentation
use axum::http::HeaderMap;
use serde_json::Value;

pub fn extract_session_id(headers: &HeaderMap, body: &Value, client_format: &str) -> String {
    if matches!(client_format, "codex" | "openai") {
        for header_name in ["session_id", "x-session-id"] {
            if let Some(session_id) = headers.get(header_name).and_then(|v| v.to_str().ok()) {
                if !session_id.is_empty() {
                    return format!("codex_{session_id}");
                }
            }
        }

        if let Some(previous_response_id) =
            body.get("previous_response_id").and_then(|v| v.as_str())
        {
            if !previous_response_id.is_empty() {
                return format!("codex_{previous_response_id}");
            }
        }
    }

    if let Some(user_id) = body
        .get("metadata")
        .and_then(|metadata| metadata.get("user_id"))
        .and_then(|v| v.as_str())
    {
        if let Some((_, session_id)) = user_id.split_once("_session_") {
            if !session_id.is_empty() {
                return session_id.to_string();
            }
        }
    }

    if let Some(session_id) = body
        .get("metadata")
        .and_then(|metadata| metadata.get("session_id"))
        .and_then(|v| v.as_str())
    {
        if !session_id.is_empty() {
            return session_id.to_string();
        }
    }

    uuid::Uuid::new_v4().to_string()
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;

    #[test]
    fn extracts_claude_metadata_session_id() {
        let headers = HeaderMap::new();
        let body = json!({
            "metadata": {
                "session_id": "claude-session-123"
            }
        });

        assert_eq!(
            extract_session_id(&headers, &body, "claude"),
            "claude-session-123"
        );
    }

    #[test]
    fn extracts_codex_previous_response_id() {
        let headers = HeaderMap::new();
        let body = json!({
            "previous_response_id": "resp_abc123"
        });

        assert_eq!(
            extract_session_id(&headers, &body, "codex"),
            "codex_resp_abc123"
        );
    }
}