[model-gateway]: Tool parser for glm47 (#15520)
This commit is contained in:
@@ -239,7 +239,8 @@ impl ParserFactory {
|
||||
registry.register_parser("pythonic", || Box::new(PythonicParser::new()));
|
||||
registry.register_parser("llama", || Box::new(LlamaParser::new()));
|
||||
registry.register_parser("deepseek", || Box::new(DeepSeekParser::new()));
|
||||
registry.register_parser("glm4_moe", || Box::new(Glm4MoeParser::new()));
|
||||
registry.register_parser("glm45_moe", || Box::new(Glm4MoeParser::glm45()));
|
||||
registry.register_parser("glm47_moe", || Box::new(Glm4MoeParser::glm47()));
|
||||
registry.register_parser("step3", || Box::new(Step3Parser::new()));
|
||||
registry.register_parser("kimik2", || Box::new(KimiK2Parser::new()));
|
||||
registry.register_parser("minimax_m2", || Box::new(MinimaxM2Parser::new()));
|
||||
@@ -281,8 +282,9 @@ impl ParserFactory {
|
||||
registry.map_model("deepseek-*", "pythonic");
|
||||
|
||||
// GLM models
|
||||
registry.map_model("glm-4.5*", "glm4_moe");
|
||||
registry.map_model("glm-4.6*", "glm4_moe");
|
||||
registry.map_model("glm-4.5*", "glm45_moe");
|
||||
registry.map_model("glm-4.6*", "glm45_moe");
|
||||
registry.map_model("glm-4.7*", "glm47_moe");
|
||||
registry.map_model("glm-*", "json");
|
||||
|
||||
// Step3 models
|
||||
|
||||
@@ -14,8 +14,9 @@ use crate::{
|
||||
|
||||
/// GLM-4 MoE format parser for tool calls
|
||||
///
|
||||
/// Handles the GLM-4 MoE specific format:
|
||||
/// `<tool_call>{name}\n<arg_key>{key}</arg_key>\n<arg_value>{value}</arg_value>\n</tool_call>`
|
||||
/// Handles both GLM-4 MoE and GLM-4.7 MoE formats:
|
||||
/// - GLM-4: `<tool_call>{name}\n<arg_key>{key}</arg_key>\n<arg_value>{value}</arg_value>\n</tool_call>`
|
||||
/// - GLM-4.7: `<tool_call>{name}<arg_key>{key}</arg_key><arg_value>{value}</arg_value></tool_call>`
|
||||
///
|
||||
/// Features:
|
||||
/// - XML-style tags for tool calls
|
||||
@@ -47,13 +48,17 @@ pub struct Glm4MoeParser {
|
||||
}
|
||||
|
||||
impl Glm4MoeParser {
|
||||
/// Create a new GLM-4 MoE parser
|
||||
pub fn new() -> Self {
|
||||
/// Create a new generic GLM MoE parser with a custom func_detail_extractor pattern
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `func_detail_pattern`: Regex pattern for extracting function name and arguments
|
||||
/// - For GLM-4: `r"(?s)<tool_call>([^\n]*)\n(.*)</tool_call>"`
|
||||
/// - For GLM-4.7: `r"(?s)<tool_call>\s*([^<\s]+)\s*(.*?)</tool_call>"`
|
||||
pub(crate) fn new(func_detail_pattern: &str) -> Self {
|
||||
// Use (?s) flag for DOTALL mode to handle newlines
|
||||
let tool_call_pattern = r"(?s)<tool_call>.*?</tool_call>";
|
||||
let tool_call_extractor = Regex::new(tool_call_pattern).expect("Valid regex pattern");
|
||||
|
||||
let func_detail_pattern = r"(?s)<tool_call>([^\n]*)\n(.*)</tool_call>";
|
||||
let func_detail_extractor = Regex::new(func_detail_pattern).expect("Valid regex pattern");
|
||||
|
||||
let arg_pattern = r"(?s)<arg_key>(.*?)</arg_key>\s*<arg_value>(.*?)</arg_value>";
|
||||
@@ -72,6 +77,16 @@ impl Glm4MoeParser {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new GLM-4.5/4.6 MoE parser (with newline-based format)
|
||||
pub fn glm45() -> Self {
|
||||
Self::new(r"(?s)<tool_call>([^\n]*)\n(.*)</tool_call>")
|
||||
}
|
||||
|
||||
/// Create a new GLM-4.7 MoE parser (with whitespace-based format)
|
||||
pub fn glm47() -> Self {
|
||||
Self::new(r"(?s)<tool_call>\s*([^<\s]+)\s*(.*?)</tool_call>")
|
||||
}
|
||||
|
||||
/// Parse arguments from key-value pairs
|
||||
fn parse_arguments(&self, args_text: &str) -> ParserResult<serde_json::Map<String, Value>> {
|
||||
let mut arguments = serde_json::Map::new();
|
||||
@@ -136,7 +151,6 @@ impl Glm4MoeParser {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse and return StreamingParseResult (mirrors Python's detect_and_parse)
|
||||
/// Parse all tool calls from text (shared logic for complete and incremental parsing)
|
||||
fn parse_tool_calls_from_text(&self, text: &str) -> ParserResult<Vec<ToolCall>> {
|
||||
let mut tools = Vec::new();
|
||||
@@ -158,7 +172,7 @@ impl Glm4MoeParser {
|
||||
|
||||
impl Default for Glm4MoeParser {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
Self::glm45()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +271,7 @@ impl ToolParser for Glm4MoeParser {
|
||||
tracing::debug!("Invalid tool name '{}' - skipping", tool_call.function.name);
|
||||
helpers::reset_current_tool_state(
|
||||
&mut self.buffer,
|
||||
&mut false, // glm4_moe doesn't track name_sent per tool
|
||||
&mut false, // glm45_moe/glm47_moe doesn't track name_sent per tool
|
||||
&mut self.streamed_args_for_tool,
|
||||
&self.prev_tool_call_arr,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user