use regex::Regex; use std::sync::LazyLock; static ID_REGEX: LazyLock = LazyLock::new(|| Regex::new(r#""id"\s*:\s*([^,}]+)"#).unwrap()); static METHOD_REGEX: LazyLock = LazyLock::new(|| Regex::new(r#""method"\s*:\s*"([^"]+)""#).unwrap()); static TOOL_REGEX: LazyLock = LazyLock::new(|| Regex::new(r#""name"\s*:\s*"([^"]+)""#).unwrap()); static ERROR_REGEX: LazyLock = LazyLock::new(|| Regex::new(r#""error"\s*:\s*\{"#).unwrap()); static IS_ERROR_REGEX: LazyLock = LazyLock::new(|| Regex::new(r#""isError"\s*:\s*true"#).unwrap()); pub fn extract_log_prefix(json_str: &str, is_response: bool) -> String { let id = ID_REGEX .captures(json_str) .and_then(|c| c.get(1)) .map_or("null", |m| m.as_str()); if is_response { let is_error = ERROR_REGEX.is_match(json_str) || IS_ERROR_REGEX.is_match(json_str); return format!("Response id={id} [Error: {is_error}]"); } let method = METHOD_REGEX .captures(json_str) .and_then(|c| c.get(1)) .map_or("", |m| m.as_str()); if method == "tools/call" { let tool = TOOL_REGEX .captures(json_str) .and_then(|c| c.get(1)) .map_or("unknown", |m| m.as_str()); format!("ToolCall[{tool}] id={id}") } else if !method.is_empty() { format!("Request[{method}] id={id}") } else if id != "null" { format!("Response id={id}") } else { "Message".to_string() } }