Unverified Commit c112bcc4 authored by Chang Su's avatar Chang Su Committed by GitHub
Browse files

[router] global tool parser registry (#9840)

parent 5e194b21
...@@ -64,6 +64,7 @@ prost-types = "0.13" ...@@ -64,6 +64,7 @@ prost-types = "0.13"
deadpool = { version = "0.12", features = ["managed", "rt_tokio_1"] } deadpool = { version = "0.12", features = ["managed", "rt_tokio_1"] }
backoff = { version = "0.4", features = ["tokio"] } backoff = { version = "0.4", features = ["tokio"] }
strum = { version = "0.26", features = ["derive"] } strum = { version = "0.26", features = ["derive"] }
once_cell = "1.21.3"
[build-dependencies] [build-dependencies]
tonic-build = "0.12" tonic-build = "0.12"
......
...@@ -23,6 +23,8 @@ use crate::tool_parser::{ ...@@ -23,6 +23,8 @@ use crate::tool_parser::{
pub struct PythonicParser { pub struct PythonicParser {
/// Regex to detect tool calls in Pythonic format /// Regex to detect tool calls in Pythonic format
tool_call_regex: Regex, tool_call_regex: Regex,
/// Regex to parse function calls - cached for reuse
call_regex: Regex,
} }
impl PythonicParser { impl PythonicParser {
...@@ -33,7 +35,13 @@ impl PythonicParser { ...@@ -33,7 +35,13 @@ impl PythonicParser {
let pattern = r"\[[a-zA-Z_]\w*\("; let pattern = r"\[[a-zA-Z_]\w*\(";
let tool_call_regex = Regex::new(pattern).expect("Valid regex pattern"); let tool_call_regex = Regex::new(pattern).expect("Valid regex pattern");
Self { tool_call_regex } // Compile the function call regex once
let call_regex = Regex::new(r"(?s)^([a-zA-Z_]\w*)\((.*)\)$").expect("Valid regex pattern");
Self {
tool_call_regex,
call_regex,
}
} }
/// Extract tool calls using bracket counting (similar to MistralParser) /// Extract tool calls using bracket counting (similar to MistralParser)
...@@ -120,10 +128,8 @@ impl PythonicParser { ...@@ -120,10 +128,8 @@ impl PythonicParser {
/// Parse a single function call from Python syntax /// Parse a single function call from Python syntax
fn parse_function_call(&self, call_str: &str) -> ToolParserResult<Option<ToolCall>> { fn parse_function_call(&self, call_str: &str) -> ToolParserResult<Option<ToolCall>> {
// Match function_name(args) - use (?s) to make . match newlines // Use cached regex instead of creating new one
let call_regex = Regex::new(r"(?s)^([a-zA-Z_]\w*)\((.*)\)$").unwrap(); if let Some(captures) = self.call_regex.captures(call_str.trim()) {
if let Some(captures) = call_regex.captures(call_str.trim()) {
let function_name = captures.get(1).unwrap().as_str(); let function_name = captures.get(1).unwrap().as_str();
let args_str = captures.get(2).unwrap().as_str(); let args_str = captures.get(2).unwrap().as_str();
......
...@@ -3,9 +3,13 @@ use crate::tool_parser::parsers::{ ...@@ -3,9 +3,13 @@ use crate::tool_parser::parsers::{
MistralParser, PythonicParser, QwenParser, Step3Parser, MistralParser, PythonicParser, QwenParser, Step3Parser,
}; };
use crate::tool_parser::traits::ToolParser; use crate::tool_parser::traits::ToolParser;
use once_cell::sync::Lazy;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
/// Global singleton registry instance - created once and reused
pub static GLOBAL_REGISTRY: Lazy<ParserRegistry> = Lazy::new(ParserRegistry::new_internal);
/// Registry for tool parsers and model mappings /// Registry for tool parsers and model mappings
pub struct ParserRegistry { pub struct ParserRegistry {
/// Map of parser name to parser instance /// Map of parser name to parser instance
...@@ -17,8 +21,19 @@ pub struct ParserRegistry { ...@@ -17,8 +21,19 @@ pub struct ParserRegistry {
} }
impl ParserRegistry { impl ParserRegistry {
/// Create a new parser registry with default mappings /// Get the global singleton instance
pub fn new() -> Self { pub fn new() -> &'static Self {
&GLOBAL_REGISTRY
}
/// Create a new instance for testing (not the singleton)
#[cfg(test)]
pub fn new_for_testing() -> Self {
Self::new_internal()
}
/// Internal constructor for creating the singleton instance
fn new_internal() -> Self {
let mut registry = Self { let mut registry = Self {
parsers: HashMap::new(), parsers: HashMap::new(),
model_mapping: HashMap::new(), model_mapping: HashMap::new(),
...@@ -202,8 +217,8 @@ impl ParserRegistry { ...@@ -202,8 +217,8 @@ impl ParserRegistry {
} }
} }
impl Default for ParserRegistry { impl Default for &'static ParserRegistry {
fn default() -> Self { fn default() -> Self {
Self::new() ParserRegistry::new()
} }
} }
...@@ -74,7 +74,7 @@ fn test_parser_registry() { ...@@ -74,7 +74,7 @@ fn test_parser_registry() {
#[test] #[test]
fn test_parser_registry_pattern_matching() { fn test_parser_registry_pattern_matching() {
let mut registry = ParserRegistry::new(); let mut registry = ParserRegistry::new_for_testing();
// Test that model mappings work by checking the list // Test that model mappings work by checking the list
registry.map_model("test-model", "json"); registry.map_model("test-model", "json");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment