From 9768c50d90f6e9f200d11cb4d2e0a0c9a1c94303 Mon Sep 17 00:00:00 2001 From: Simo Lin Date: Wed, 27 Aug 2025 06:05:53 -0700 Subject: [PATCH] [router] restructure tool parser module folder (#9693) --- sgl-router/src/tool_parser/mod.rs | 17 +++++++---------- .../tool_parser/{ => parsers}/json_parser.rs | 9 +++++---- .../tool_parser/{ => parsers}/llama_parser.rs | 2 +- .../tool_parser/{ => parsers}/mistral_parser.rs | 0 sgl-router/src/tool_parser/parsers/mod.rs | 16 ++++++++++++++++ .../{ => parsers}/pythonic_parser.rs | 0 .../tool_parser/{ => parsers}/qwen_parser.rs | 0 sgl-router/src/tool_parser/registry.rs | 8 +++----- sgl-router/src/tool_parser/tests.rs | 7 +++---- 9 files changed, 35 insertions(+), 24 deletions(-) rename sgl-router/src/tool_parser/{ => parsers}/json_parser.rs (97%) rename sgl-router/src/tool_parser/{ => parsers}/llama_parser.rs (99%) rename sgl-router/src/tool_parser/{ => parsers}/mistral_parser.rs (100%) create mode 100644 sgl-router/src/tool_parser/parsers/mod.rs rename sgl-router/src/tool_parser/{ => parsers}/pythonic_parser.rs (100%) rename sgl-router/src/tool_parser/{ => parsers}/qwen_parser.rs (100%) diff --git a/sgl-router/src/tool_parser/mod.rs b/sgl-router/src/tool_parser/mod.rs index ce83bf112..ae0e66ca4 100644 --- a/sgl-router/src/tool_parser/mod.rs +++ b/sgl-router/src/tool_parser/mod.rs @@ -1,30 +1,27 @@ /// Tool parser module for handling function/tool calls in model outputs /// /// This module provides infrastructure for parsing tool calls from various model formats. +// Core modules pub mod errors; -pub mod json_parser; -pub mod llama_parser; -pub mod mistral_parser; pub mod partial_json; pub mod python_literal_parser; -pub mod pythonic_parser; -pub mod qwen_parser; pub mod registry; pub mod state; pub mod traits; pub mod types; +// Parser implementations +pub mod parsers; + #[cfg(test)] mod tests; // Re-export commonly used types pub use errors::{ToolParserError, ToolParserResult}; -pub use json_parser::JsonParser; -pub use llama_parser::LlamaParser; -pub use mistral_parser::MistralParser; -pub use pythonic_parser::PythonicParser; -pub use qwen_parser::QwenParser; pub use registry::ParserRegistry; pub use state::{ParsePhase, ParseState}; pub use traits::{PartialJsonParser, ToolParser}; pub use types::{FunctionCall, PartialToolCall, StreamResult, TokenConfig, ToolCall}; + +// Re-export parsers for convenience +pub use parsers::{JsonParser, LlamaParser, MistralParser, PythonicParser, QwenParser}; diff --git a/sgl-router/src/tool_parser/json_parser.rs b/sgl-router/src/tool_parser/parsers/json_parser.rs similarity index 97% rename from sgl-router/src/tool_parser/json_parser.rs rename to sgl-router/src/tool_parser/parsers/json_parser.rs index 01321b6b5..117435b7f 100644 --- a/sgl-router/src/tool_parser/json_parser.rs +++ b/sgl-router/src/tool_parser/parsers/json_parser.rs @@ -291,7 +291,8 @@ impl ToolParser for JsonParser { // Clear buffer since we consumed everything state.buffer.clear(); - // Return the first tool as complete (simplified for Phase 2) + // Return the first tool as complete + // TODO simplified version, address more complex version if let Some(tool) = tools.into_iter().next() { return Ok(StreamResult::ToolComplete(tool)); } @@ -299,7 +300,7 @@ impl ToolParser for JsonParser { } else { // Partial JSON, try to extract tool name if let Some(name) = value.get("name").and_then(|v| v.as_str()) { - // Simple implementation for Phase 2 + // TODO simplified version, address more complex version // Just return the tool name once we see it if !state.in_string { state.in_string = true; // Use as a flag for "name sent" @@ -430,12 +431,12 @@ mod tests { #[tokio::test] async fn test_streaming_parse() { - // Phase 2 simplified streaming test // Just verify that streaming eventually produces a complete tool call let parser = JsonParser::new(); let mut state = ParseState::new(); - // Send complete JSON in one go (simplified for Phase 2) + // Send complete JSON in one go + // TODO simplified version, address more complex version let full_json = r#"{"name": "get_weather", "arguments": {"location": "SF"}}"#; let result = parser diff --git a/sgl-router/src/tool_parser/llama_parser.rs b/sgl-router/src/tool_parser/parsers/llama_parser.rs similarity index 99% rename from sgl-router/src/tool_parser/llama_parser.rs rename to sgl-router/src/tool_parser/parsers/llama_parser.rs index 677945d85..678c964c5 100644 --- a/sgl-router/src/tool_parser/llama_parser.rs +++ b/sgl-router/src/tool_parser/parsers/llama_parser.rs @@ -1,8 +1,8 @@ use async_trait::async_trait; +use super::json_parser::JsonParser; use crate::tool_parser::{ errors::ToolParserResult, - json_parser::JsonParser, state::ParseState, traits::ToolParser, types::{StreamResult, TokenConfig, ToolCall}, diff --git a/sgl-router/src/tool_parser/mistral_parser.rs b/sgl-router/src/tool_parser/parsers/mistral_parser.rs similarity index 100% rename from sgl-router/src/tool_parser/mistral_parser.rs rename to sgl-router/src/tool_parser/parsers/mistral_parser.rs diff --git a/sgl-router/src/tool_parser/parsers/mod.rs b/sgl-router/src/tool_parser/parsers/mod.rs new file mode 100644 index 000000000..a5c2b0c28 --- /dev/null +++ b/sgl-router/src/tool_parser/parsers/mod.rs @@ -0,0 +1,16 @@ +/// Parser implementations for different model formats +/// +/// This module contains concrete parser implementations for various model-specific +/// tool/function call formats. +// Individual parser modules +pub mod json_parser; +pub mod llama_parser; +pub mod mistral_parser; +pub mod pythonic_parser; +pub mod qwen_parser; + +pub use json_parser::JsonParser; +pub use llama_parser::LlamaParser; +pub use mistral_parser::MistralParser; +pub use pythonic_parser::PythonicParser; +pub use qwen_parser::QwenParser; diff --git a/sgl-router/src/tool_parser/pythonic_parser.rs b/sgl-router/src/tool_parser/parsers/pythonic_parser.rs similarity index 100% rename from sgl-router/src/tool_parser/pythonic_parser.rs rename to sgl-router/src/tool_parser/parsers/pythonic_parser.rs diff --git a/sgl-router/src/tool_parser/qwen_parser.rs b/sgl-router/src/tool_parser/parsers/qwen_parser.rs similarity index 100% rename from sgl-router/src/tool_parser/qwen_parser.rs rename to sgl-router/src/tool_parser/parsers/qwen_parser.rs diff --git a/sgl-router/src/tool_parser/registry.rs b/sgl-router/src/tool_parser/registry.rs index a71fd6232..078d1c49d 100644 --- a/sgl-router/src/tool_parser/registry.rs +++ b/sgl-router/src/tool_parser/registry.rs @@ -1,8 +1,6 @@ -use crate::tool_parser::json_parser::JsonParser; -use crate::tool_parser::llama_parser::LlamaParser; -use crate::tool_parser::mistral_parser::MistralParser; -use crate::tool_parser::pythonic_parser::PythonicParser; -use crate::tool_parser::qwen_parser::QwenParser; +use crate::tool_parser::parsers::{ + JsonParser, LlamaParser, MistralParser, PythonicParser, QwenParser, +}; use crate::tool_parser::traits::ToolParser; use std::collections::HashMap; use std::sync::Arc; diff --git a/sgl-router/src/tool_parser/tests.rs b/sgl-router/src/tool_parser/tests.rs index a9284586a..4aec1f172 100644 --- a/sgl-router/src/tool_parser/tests.rs +++ b/sgl-router/src/tool_parser/tests.rs @@ -1,5 +1,5 @@ use super::*; -use crate::tool_parser::json_parser::JsonParser; +use crate::tool_parser::parsers::JsonParser; use crate::tool_parser::partial_json::{ compute_diff, find_common_prefix, is_complete_json, PartialJson, }; @@ -387,11 +387,10 @@ fn test_json_parser_format_detection() { #[tokio::test] async fn test_json_parser_streaming() { - // Phase 2 simplified streaming test let parser = JsonParser::new(); let mut state = ParseState::new(); - // Test with complete JSON (simplified for Phase 2) + // Test with complete JSON let full_json = r#"{"name": "get_weather", "arguments": {"location": "San Francisco"}}"#; let result = parser @@ -739,7 +738,7 @@ mod edge_cases { _ => panic!("Expected ToolComplete for complete JSON"), } - // Test 3: Partial JSON with name - Phase 2 behavior + // Test 3: Partial JSON with name // The PartialJson parser can complete partial JSON by filling in missing values let mut state3 = ParseState::new(); let partial_with_name = r#"{"name": "test", "argum"#;