ai-agent 0.13.4

Idiomatic agent sdk inspired by the claude code source leak
Documentation
use serde_json::Value;

pub fn normalize_control_message_keys(obj: Value) -> Value {
    match obj {
        Value::Object(mut map) => {
            if let Some(request_id) = map.remove("requestId") {
                if !map.contains_key("request_id") {
                    map.insert("request_id".to_string(), request_id);
                }
            }

            if let Some(response) = map.get_mut("response") {
                if let Value::Object(resp_map) = response {
                    if let Some(request_id) = resp_map.remove("requestId") {
                        if !resp_map.contains_key("request_id") {
                            resp_map.insert("request_id".to_string(), request_id);
                        }
                    }
                }
            }

            Value::Object(map)
        }
        other => other,
    }
}

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

    #[test]
    fn test_normalize_request_id() {
        let input = json!({
            "requestId": "test-123",
            "data": "value"
        });
        let result = normalize_control_message_keys(input);
        assert_eq!(result.get("request_id").unwrap(), "test-123");
        assert!(!result.get("requestId").is_some());
    }

    #[test]
    fn test_normalize_nested_request_id() {
        let input = json!({
            "response": {
                "requestId": "nested-123"
            }
        });
        let result = normalize_control_message_keys(input);
        assert_eq!(
            result.get("response").unwrap().get("request_id").unwrap(),
            "nested-123"
        );
    }
}