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() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_extract_log_prefix_response() { let json_str = r#"{"jsonrpc":"2.0","id":123,"result":{}}"#; assert_eq!( extract_log_prefix(json_str, true), "Response id=123 [Error: false]" ); let err_json = r#"{"jsonrpc":"2.0","id":456,"error":{"code":-32600,"message":"Invalid Request"}}"#; assert_eq!( extract_log_prefix(err_json, true), "Response id=456 [Error: true]" ); let is_err_json = r#"{"jsonrpc":"2.0","id":789,"result":{"isError":true}}"#; assert_eq!( extract_log_prefix(is_err_json, true), "Response id=789 [Error: true]" ); } #[test] fn test_extract_log_prefix_tool_call() { let json_str = r#"{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search"}}"#; assert_eq!(extract_log_prefix(json_str, false), "ToolCall[search] id=1"); let unknown_tool = r#"{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{}}"#; assert_eq!( extract_log_prefix(unknown_tool, false), "ToolCall[unknown] id=2" ); } #[test] fn test_extract_log_prefix_request() { let json_str = r#"{"jsonrpc":"2.0","id":10,"method":"initialize"}"#; assert_eq!( extract_log_prefix(json_str, false), "Request[initialize] id=10" ); } #[test] fn test_extract_log_prefix_response_as_request() { let json_str = r#"{"jsonrpc":"2.0","id":99,"result":true}"#; assert_eq!(extract_log_prefix(json_str, false), "Response id=99"); } #[test] fn test_extract_log_prefix_generic_message() { let json_str = r#"{"foo":"bar"}"#; assert_eq!(extract_log_prefix(json_str, false), "Message"); } }