//! GLM-4.7 MoE Parser Integration Tests use smg::tool_parser::{Glm4MoeParser, ToolParser}; use crate::common::create_test_tools; #[tokio::test] async fn test_glm47_complete_parsing() { let parser = Glm4MoeParser::glm47(); let input = r#"Let me search for that. get_weathercityBeijingdate2024-12-25 The weather will be..."#; let (normal_text, tools) = parser.parse_complete(input).await.unwrap(); assert_eq!(tools.len(), 1); assert_eq!(normal_text, "Let me search for that.\n"); assert_eq!(tools[0].function.name, "get_weather"); let args: serde_json::Value = serde_json::from_str(&tools[0].function.arguments).unwrap(); assert_eq!(args["city"], "Beijing"); assert_eq!(args["date"], "2024-12-25"); } #[tokio::test] async fn test_glm47_multiple_tools() { let parser = Glm4MoeParser::glm47(); let input = r#"searchqueryrust tutorialstranslatetextHello Worldtarget_langzh"#; let (normal_text, tools) = parser.parse_complete(input).await.unwrap(); assert_eq!(tools.len(), 2); assert_eq!(normal_text, ""); assert_eq!(tools[0].function.name, "search"); assert_eq!(tools[1].function.name, "translate"); } #[tokio::test] async fn test_glm47_type_conversion() { let parser = Glm4MoeParser::glm47(); let input = r#"processcount42rate1.5enabledtruedatanulltextstring value"#; let (normal_text, tools) = parser.parse_complete(input).await.unwrap(); assert_eq!(tools.len(), 1); assert_eq!(normal_text, ""); let args: serde_json::Value = serde_json::from_str(&tools[0].function.arguments).unwrap(); assert_eq!(args["count"], 42); assert_eq!(args["rate"], 1.5); assert_eq!(args["enabled"], true); assert_eq!(args["data"], serde_json::Value::Null); assert_eq!(args["text"], "string value"); } #[tokio::test] async fn test_glm47_streaming() { let mut parser = Glm4MoeParser::glm47(); let tools = create_test_tools(); // Simulate streaming chunks let chunks = vec![ "", "get_weather", "city", "Shanghai", "units", "celsius", "", ]; let mut found_name = false; for chunk in chunks { let result = parser.parse_incremental(chunk, &tools).await.unwrap(); for call in result.calls { if let Some(name) = call.name { assert_eq!(name, "get_weather"); found_name = true; } } } assert!(found_name, "Should have found tool name during streaming"); } #[test] fn test_glm47_format_detection() { let parser = Glm4MoeParser::glm47(); // Should detect GLM-4 format assert!(parser.has_tool_markers("")); assert!(parser.has_tool_markers("text with marker")); // Should not detect other formats assert!(!parser.has_tool_markers("[TOOL_CALLS]")); assert!(!parser.has_tool_markers("<|tool▁calls▁begin|>")); assert!(!parser.has_tool_markers("plain text")); } #[tokio::test] async fn test_python_literals() { let parser = Glm4MoeParser::glm47(); let input = r#"test_funcbool_trueTruebool_falseFalsenone_valNone"#; let (_normal_text, tools) = parser.parse_complete(input).await.unwrap(); assert_eq!(tools.len(), 1); assert_eq!(tools[0].function.name, "test_func"); let args: serde_json::Value = serde_json::from_str(&tools[0].function.arguments).unwrap(); assert_eq!(args["bool_true"], true); assert_eq!(args["bool_false"], false); assert_eq!(args["none_val"], serde_json::Value::Null); } #[tokio::test] async fn test_glm47_nested_json_in_arg_values() { let parser = Glm4MoeParser::glm47(); let input = r#"processdata{"nested": {"key": "value"}}list[1, 2, 3]"#; let (_normal_text, tools) = parser.parse_complete(input).await.unwrap(); assert_eq!(tools.len(), 1); let args: serde_json::Value = serde_json::from_str(&tools[0].function.arguments).unwrap(); assert!(args["data"].is_object()); assert!(args["list"].is_array()); }