diff --git a/crates/tool_parser/src/parsers/glm4_moe.rs b/crates/tool_parser/src/parsers/glm4_moe.rs
index 2eec81c03e..de86b3854f 100644
--- a/crates/tool_parser/src/parsers/glm4_moe.rs
+++ b/crates/tool_parser/src/parsers/glm4_moe.rs
@@ -1,3 +1,5 @@
+use std::collections::HashMap;
+
use async_trait::async_trait;
use openai_protocol::common::Tool;
use regex::Regex;
@@ -89,37 +91,22 @@ impl Glm4MoeParser {
Self::new(r"(?s)\s*([^<\s]+)\s*(.*?)")
}
- /// Parse arguments from key-value pairs
- fn parse_arguments(&self, args_text: &str) -> serde_json::Map {
+ /// Parse arguments, coercing each value by its declared schema type and
+ /// falling back to [`infer_value`] when the type is unknown.
+ fn parse_arguments(
+ &self,
+ args_text: &str,
+ param_types: &HashMap,
+ ) -> serde_json::Map {
let mut arguments = serde_json::Map::new();
for capture in self.arg_extractor.captures_iter(args_text) {
let key = capture.get(1).map_or("", |m| m.as_str()).trim();
let value_str = capture.get(2).map_or("", |m| m.as_str()).trim();
- // Try to parse the value as JSON first, fallback to string
- let value = if let Ok(json_val) = serde_json::from_str::(value_str) {
- json_val
- } else {
- // Try parsing as Python literal (similar to Python's ast.literal_eval)
- if value_str == "true" || value_str == "True" {
- Value::Bool(true)
- } else if value_str == "false" || value_str == "False" {
- Value::Bool(false)
- } else if value_str == "null" || value_str == "None" {
- Value::Null
- } else if let Ok(num) = value_str.parse::() {
- Value::Number(num.into())
- } else if let Ok(num) = value_str.parse::() {
- if let Some(n) = serde_json::Number::from_f64(num) {
- Value::Number(n)
- } else {
- Value::String(value_str.to_string())
- }
- } else {
- Value::String(value_str.to_string())
- }
- };
+ let value =
+ helpers::coerce_by_schema_type(value_str, param_types.get(key).map(String::as_str))
+ .unwrap_or_else(|| infer_value(value_str));
arguments.insert(key.to_string(), value);
}
@@ -128,7 +115,7 @@ impl Glm4MoeParser {
}
/// Parse a single tool call block
- fn parse_tool_call(&self, block: &str) -> ParserResult