"vllm/vscode:/vscode.git/clone" did not exist on "0bd7f8fca521295c4880a0a5a44c41204fd83db7"
config.rs 11.6 KB
Newer Older
1
// SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
3
// SPDX-License-Identifier: Apache-2.0

4
5
use super::json::JsonParserType;

6
7
8
9
10
11
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct JsonParserConfig {
    /// Start token for individual tool calls (e.g., "<TOOLCALL>")
    pub tool_call_start_tokens: Vec<String>,
    /// End token for individual tool calls (e.g., "</TOOLCALL>")
    pub tool_call_end_tokens: Vec<String>,
12
13
14
15
    /// Separator tokens between function name and arguments
    /// (e.g., "<|tool▁sep|>" for DeepSeek v3.1)
    /// Used by some models to separate function name from arguments
    pub tool_call_separator_tokens: Vec<String>,
16
17
18
19
20
21
22
23
    /// The key for the function name in the tool call
    /// i.e. `{"name": "function", "arguments": {...}}` it would be
    /// "name"
    pub function_name_keys: Vec<String>,
    /// The key for the arguments in the tool call
    /// i.e. `{"name": "function", "arguments": {...}}` it would be
    /// "arguments"
    pub arguments_keys: Vec<String>,
24
25
26
27

    /// The type of JSON parser to use
    #[serde(default)]
    pub parser_type: JsonParserType,
28
29
30
31
32
33
34
}

impl Default for JsonParserConfig {
    fn default() -> Self {
        Self {
            tool_call_start_tokens: vec!["<TOOLCALL>".to_string(), "<|python_tag|>".to_string()],
            tool_call_end_tokens: vec!["</TOOLCALL>".to_string(), "".to_string()],
35
            tool_call_separator_tokens: vec![],
36
37
            function_name_keys: vec!["name".to_string()],
            arguments_keys: vec!["arguments".to_string(), "parameters".to_string()],
38
            parser_type: JsonParserType::Basic,
39
40
41
42
        }
    }
}

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct XmlParserConfig {
    /// Start token for individual tool calls (e.g., "<tool_call>")
    pub tool_call_start_token: String,
    /// End token for individual tool calls (e.g., "</tool_call>")
    pub tool_call_end_token: String,
    /// Start token for function name (e.g., "<function=")
    pub function_start_token: String,
    /// End token for function (e.g., "</function>")
    pub function_end_token: String,
    /// Start token for parameter (e.g., "<parameter=")
    pub parameter_start_token: String,
    /// End token for parameter (e.g., "</parameter>")
    pub parameter_end_token: String,
}

impl Default for XmlParserConfig {
    fn default() -> Self {
        Self {
            tool_call_start_token: "<tool_call>".to_string(),
            tool_call_end_token: "</tool_call>".to_string(),
            function_start_token: "<function=".to_string(),
            function_end_token: "</function>".to_string(),
            parameter_start_token: "<parameter=".to_string(),
            parameter_end_token: "</parameter>".to_string(),
        }
    }
}

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/// Configuration for DSML-style tool call parser (DeepSeek V3.2+)
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct DsmlParserConfig {
    /// Start token for function_calls block (e.g., "<|DSML|function_calls>")
    pub function_calls_start: String,
    /// End token for function_calls block (e.g., "</|DSML|function_calls>")
    pub function_calls_end: String,
    /// Start prefix for invoke (e.g., "<|DSML|invoke name=")
    pub invoke_start_prefix: String,
    /// End token for invoke (e.g., "</|DSML|invoke>")
    pub invoke_end: String,
    /// Start prefix for parameter (e.g., "<|DSML|parameter name=")
    pub parameter_prefix: String,
    /// End token for parameter (e.g., "</|DSML|parameter>")
    pub parameter_end: String,
}

impl Default for DsmlParserConfig {
    fn default() -> Self {
        Self {
            function_calls_start: "<|DSML|function_calls>".to_string(),
            function_calls_end: "</|DSML|function_calls>".to_string(),
            invoke_start_prefix: "<|DSML|invoke name=".to_string(),
            invoke_end: "</|DSML|invoke>".to_string(),
            parameter_prefix: "<|DSML|parameter name=".to_string(),
            parameter_end: "</|DSML|parameter>".to_string(),
        }
    }
}

102
103
104
105
106
107
108
109
110
/// Parser-specific configuration
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ParserConfig {
    Json(JsonParserConfig),
    Xml(XmlParserConfig),
    Pythonic,
    Harmony(JsonParserConfig),
    Typescript,
111
    Dsml(DsmlParserConfig),
112
113
114
115
116
117
118
119
120
121
122
123
}

impl ParserConfig {
    /// Get the tool call start tokens for this parser configuration
    /// Returns a vector of start tokens that indicate the beginning of a tool call
    pub fn tool_call_start_tokens(&self) -> Vec<String> {
        match self {
            ParserConfig::Json(config) => config.tool_call_start_tokens.clone(),
            ParserConfig::Harmony(config) => config.tool_call_start_tokens.clone(),
            ParserConfig::Xml(config) => vec![config.tool_call_start_token.clone()],
            ParserConfig::Pythonic => vec![],
            ParserConfig::Typescript => vec![],
124
            ParserConfig::Dsml(config) => vec![config.function_calls_start.clone()],
125
126
127
128
129
130
131
132
133
134
135
136
        }
    }

    /// Get the tool call end tokens for this parser configuration
    /// Returns a vector of end tokens that indicate the end of a tool call
    pub fn tool_call_end_tokens(&self) -> Vec<String> {
        match self {
            ParserConfig::Json(config) => config.tool_call_end_tokens.clone(),
            ParserConfig::Harmony(config) => config.tool_call_end_tokens.clone(),
            ParserConfig::Xml(config) => vec![config.tool_call_end_token.clone()],
            ParserConfig::Pythonic => vec![],
            ParserConfig::Typescript => vec![],
137
            ParserConfig::Dsml(config) => vec![config.function_calls_end.clone()],
138
139
140
141
        }
    }
}

142
143
144
/// Configuration for parsing tool calls with different formats
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct ToolCallConfig {
145
146
    /// Parser-specific configuration.
    pub parser_config: ParserConfig,
147
148
149
150
151
}

impl Default for ToolCallConfig {
    fn default() -> Self {
        Self {
152
            parser_config: ParserConfig::Json(JsonParserConfig::default()),
153
154
155
156
157
158
159
160
161
        }
    }
}

impl ToolCallConfig {
    /// Default configuration for hermes tool calls
    /// <tool_call>{"name": "get_weather", "arguments": {"location": "San Francisco, CA", "unit": "fahrenheit"}}\n</tool_call>
    pub fn hermes() -> Self {
        Self {
162
            parser_config: ParserConfig::Json(JsonParserConfig {
163
                tool_call_start_tokens: vec!["<tool_call>".to_string()],
164
                tool_call_end_tokens: vec!["</tool_call>".to_string()],
165
                ..Default::default()
166
            }),
167
168
169
170
171
172
173
        }
    }

    /// Default configuration for nemotron tool calls
    /// <TOOLCALL>[{"name": "get_weather", "arguments": {"location": "San Francisco, CA", "unit": "fahrenheit"}}]</TOOLCALL>
    pub fn nemotron_deci() -> Self {
        Self {
174
            parser_config: ParserConfig::Json(JsonParserConfig {
175
176
177
                tool_call_start_tokens: vec!["<TOOLCALL>".to_string()],
                tool_call_end_tokens: vec!["</TOOLCALL>".to_string()],
                ..Default::default()
178
            }),
179
180
181
182
183
184
185
        }
    }

    pub fn llama3_json() -> Self {
        // <|python_tag|>{ "name": "get_weather", "arguments": {"location": "San Francisco, CA", "unit": "fahrenheit"} }
        // or { "name": "get_weather", "arguments": {"location": "San Francisco, CA", "unit": "fahrenheit"} }
        Self {
186
            parser_config: ParserConfig::Json(JsonParserConfig {
187
188
189
                tool_call_start_tokens: vec!["<|python_tag|>".to_string()],
                tool_call_end_tokens: vec!["".to_string()],
                ..Default::default()
190
            }),
191
192
193
194
195
        }
    }

    pub fn mistral() -> Self {
        Self {
196
            parser_config: ParserConfig::Json(JsonParserConfig {
197
                tool_call_start_tokens: vec!["[TOOL_CALLS]".to_string()],
198
                tool_call_end_tokens: vec!["[/TOOL_CALLS]".to_string(), "".to_string()],
199
                ..Default::default()
200
            }),
201
202
203
204
205
        }
    }

    pub fn phi4() -> Self {
        Self {
206
            parser_config: ParserConfig::Json(JsonParserConfig {
207
208
209
                tool_call_start_tokens: vec!["functools".to_string()],
                tool_call_end_tokens: vec!["".to_string()],
                ..Default::default()
210
            }),
211
212
213
214
215
        }
    }

    pub fn pythonic() -> Self {
        Self {
216
            parser_config: ParserConfig::Pythonic,
217
218
        }
    }
219
220
221

    pub fn harmony() -> Self {
        Self {
222
            parser_config: ParserConfig::Harmony(JsonParserConfig {
223
224
225
                tool_call_start_tokens: vec!["<|start|>assistant<|channel|>commentary".to_string()],
                tool_call_end_tokens: vec!["<|call|>".to_string()],
                ..Default::default()
226
            }),
227
228
        }
    }
229
230

    pub fn deepseek_v3_1() -> Self {
231
232
233
234
235
236
        // The whole tool calls block is wrapped between
        // <|tool▁calls▁begin|> ... <|tool▁calls▁end|>
        // regardless of number of tool calls. For external use of this
        // config, we want them to only be operating on the whole block,
        // so the tool parser can properly consume all tool call tokens.
        // https://huggingface.co/deepseek-ai/DeepSeek-V3.1#toolcall
237
        Self {
238
            parser_config: ParserConfig::Json(JsonParserConfig {
239
240
                tool_call_start_tokens: vec![
                    "<|tool▁calls▁begin|>".to_string(),
241
                    // "<|tool▁call▁begin|>".to_string(),
242
                ],
243
244
                tool_call_end_tokens: vec![
                    "<|tool▁calls▁end|>".to_string(),
245
                    // "<|tool▁call▁end|>".to_string(),
246
247
                ],
                tool_call_separator_tokens: vec!["<|tool▁sep|>".to_string()],
248
249
                parser_type: JsonParserType::DeepseekV31,
                ..Default::default()
250
            }),
251
252
        }
    }
253
254
255
256
257
258

    pub fn deepseek_v3() -> Self {
        // DeepSeek V3 format:
        // <|tool▁calls▁begin|><|tool▁call▁begin|>{type}<|tool▁sep|>{function_name}\n```json\n{arguments}\n```<|tool▁call▁end|><|tool▁calls▁end|>
        // There are some differences between DeepSeek V3 and DeepSeek V3.1
        Self {
259
            parser_config: ParserConfig::Json(JsonParserConfig {
260
261
262
263
264
                tool_call_start_tokens: vec!["<|tool▁calls▁begin|>".to_string()],
                tool_call_end_tokens: vec!["<|tool▁calls▁end|>".to_string()],
                tool_call_separator_tokens: vec!["<|tool▁sep|>".to_string()],
                parser_type: JsonParserType::DeepseekV3,
                ..Default::default()
265
            }),
266
267
        }
    }
268
269
270
271

    pub fn qwen3_coder() -> Self {
        // <tool_call><function=name><parameter=key>value</parameter></function></tool_call>
        Self {
272
            parser_config: ParserConfig::Xml(XmlParserConfig::default()),
273
274
        }
    }
275
276
277
278
279
280
281
282
283
284

    pub fn jamba() -> Self {
        Self {
            parser_config: ParserConfig::Json(JsonParserConfig {
                tool_call_start_tokens: vec!["<tool_calls>".to_string()],
                tool_call_end_tokens: vec!["</tool_calls>".to_string()],
                ..Default::default()
            }),
        }
    }
285
286
287
288
289
290
291
292
293
294
295
296

    pub fn deepseek_v3_2() -> Self {
        // DeepSeek V3.2 format (DSML):
        // <|DSML|function_calls>
        // <|DSML|invoke name="function_name">
        // <|DSML|parameter name="param_name" string="true|false">value</|DSML|parameter>
        // </|DSML|invoke>
        // </|DSML|function_calls>
        Self {
            parser_config: ParserConfig::Dsml(DsmlParserConfig::default()),
        }
    }
297
}