ConorWang commited on
Commit
8003f69
·
verified ·
1 Parent(s): 4203b81

Clear repository except README

Browse files
Files changed (43) hide show
  1. .gitattributes +0 -35
  2. chat_template.jinja +0 -117
  3. config.json +0 -44
  4. generation_config.json +0 -13
  5. merges.txt +0 -0
  6. model.safetensors.index.json +0 -0
  7. qwen3_coder_detector_sgl.py +0 -474
  8. qwen3coder_tool_parser_vllm.py +0 -690
  9. tokenizer.json +0 -0
  10. tokenizer_config.json +0 -239
  11. veriloop-coder-00001-of-00032.safetensors +0 -3
  12. veriloop-coder-00002-of-00032.safetensors +0 -3
  13. veriloop-coder-00003-of-00032.safetensors +0 -3
  14. veriloop-coder-00004-of-00032.safetensors +0 -3
  15. veriloop-coder-00005-of-00032.safetensors +0 -3
  16. veriloop-coder-00006-of-00032.safetensors +0 -3
  17. veriloop-coder-00007-of-00032.safetensors +0 -3
  18. veriloop-coder-00008-of-00032.safetensors +0 -3
  19. veriloop-coder-00009-of-00032.safetensors +0 -3
  20. veriloop-coder-00010-of-00032.safetensors +0 -3
  21. veriloop-coder-00011-of-00032.safetensors +0 -3
  22. veriloop-coder-00012-of-00032.safetensors +0 -3
  23. veriloop-coder-00013-of-00032.safetensors +0 -3
  24. veriloop-coder-00014-of-00032.safetensors +0 -3
  25. veriloop-coder-00015-of-00032.safetensors +0 -3
  26. veriloop-coder-00016-of-00032.safetensors +0 -3
  27. veriloop-coder-00017-of-00032.safetensors +0 -3
  28. veriloop-coder-00018-of-00032.safetensors +0 -3
  29. veriloop-coder-00019-of-00032.safetensors +0 -3
  30. veriloop-coder-00020-of-00032.safetensors +0 -3
  31. veriloop-coder-00021-of-00032.safetensors +0 -3
  32. veriloop-coder-00022-of-00032.safetensors +0 -3
  33. veriloop-coder-00023-of-00032.safetensors +0 -3
  34. veriloop-coder-00024-of-00032.safetensors +0 -3
  35. veriloop-coder-00025-of-00032.safetensors +0 -3
  36. veriloop-coder-00026-of-00032.safetensors +0 -3
  37. veriloop-coder-00027-of-00032.safetensors +0 -3
  38. veriloop-coder-00028-of-00032.safetensors +0 -3
  39. veriloop-coder-00029-of-00032.safetensors +0 -3
  40. veriloop-coder-00030-of-00032.safetensors +0 -3
  41. veriloop-coder-00031-of-00032.safetensors +0 -3
  42. veriloop-coder-00032-of-00032.safetensors +0 -3
  43. vocab.json +0 -0
.gitattributes DELETED
@@ -1,35 +0,0 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
chat_template.jinja DELETED
@@ -1,117 +0,0 @@
1
- {% macro render_extra_keys(json_dict, handled_keys) %}
2
- {%- if json_dict is mapping %}
3
- {%- for json_key in json_dict if json_key not in handled_keys %}
4
- {%- if json_dict[json_key] is string %}
5
- {{-'\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | string) ~ '</' ~ json_key ~ '>' }}
6
- {%- else %}
7
- {{- '\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | tojson | safe) ~ '</' ~ json_key ~ '>' }}
8
- {%- endif %}
9
- {%- endfor %}
10
- {%- endif %}
11
- {%- endmacro %}
12
-
13
- {%- if messages[0]["role"] == "system" %}
14
- {%- set system_message = messages[0]["content"] %}
15
- {%- set loop_messages = messages[1:] %}
16
- {%- else %}
17
- {%- set loop_messages = messages %}
18
- {%- endif %}
19
-
20
- {%- if not tools is defined %}
21
- {%- set tools = [] %}
22
- {%- endif %}
23
-
24
- {%- if system_message is defined %}
25
- {{- "<|im_start|>system\n" + system_message }}
26
- {%- else %}
27
- {%- if tools is iterable and tools | length > 0 %}
28
- {{- "<|im_start|>system\nYou are Qwen, a helpful AI assistant that can interact with a computer to solve tasks." }}
29
- {%- endif %}
30
- {%- endif %}
31
- {%- if tools is iterable and tools | length > 0 %}
32
- {{- "\n\n# Tools\n\nYou have access to the following functions:\n\n" }}
33
- {{- "<tools>" }}
34
- {%- for tool in tools %}
35
- {%- if tool.function is defined %}
36
- {%- set tool = tool.function %}
37
- {%- endif %}
38
- {{- "\n<function>\n<name>" ~ tool.name ~ "</name>" }}
39
- {%- if tool.description is defined %}
40
- {{- '\n<description>' ~ (tool.description | trim) ~ '</description>' }}
41
- {%- endif %}
42
- {{- '\n<parameters>' }}
43
- {%- if tool.parameters is defined and tool.parameters is mapping and tool.parameters.properties is defined and tool.parameters.properties is mapping %}
44
- {%- for param_name, param_fields in tool.parameters.properties|items %}
45
- {{- '\n<parameter>' }}
46
- {{- '\n<name>' ~ param_name ~ '</name>' }}
47
- {%- if param_fields.type is defined %}
48
- {{- '\n<type>' ~ (param_fields.type | string) ~ '</type>' }}
49
- {%- endif %}
50
- {%- if param_fields.description is defined %}
51
- {{- '\n<description>' ~ (param_fields.description | trim) ~ '</description>' }}
52
- {%- endif %}
53
- {%- set handled_keys = ['name', 'type', 'description'] %}
54
- {{- render_extra_keys(param_fields, handled_keys) }}
55
- {{- '\n</parameter>' }}
56
- {%- endfor %}
57
- {%- endif %}
58
- {%- set handled_keys = ['type', 'properties'] %}
59
- {{- render_extra_keys(tool.parameters, handled_keys) }}
60
- {{- '\n</parameters>' }}
61
- {%- set handled_keys = ['type', 'name', 'description', 'parameters'] %}
62
- {{- render_extra_keys(tool, handled_keys) }}
63
- {{- '\n</function>' }}
64
- {%- endfor %}
65
- {{- "\n</tools>" }}
66
- {{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
67
- {%- endif %}
68
- {%- if system_message is defined %}
69
- {{- '<|im_end|>\n' }}
70
- {%- else %}
71
- {%- if tools is iterable and tools | length > 0 %}
72
- {{- '<|im_end|>\n' }}
73
- {%- endif %}
74
- {%- endif %}
75
- {%- for message in loop_messages %}
76
- {%- if message.role == "assistant" and message.tool_calls is defined and message.tool_calls is iterable and message.tool_calls | length > 0 %}
77
- {{- '<|im_start|>' + message.role }}
78
- {%- if message.content is defined and message.content is string and message.content | trim | length > 0 %}
79
- {{- '\n' + message.content | trim + '\n' }}
80
- {%- endif %}
81
- {%- for tool_call in message.tool_calls %}
82
- {%- if tool_call.function is defined %}
83
- {%- set tool_call = tool_call.function %}
84
- {%- endif %}
85
- {{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
86
- {%- if tool_call.arguments is defined %}
87
- {%- for args_name, args_value in tool_call.arguments|items %}
88
- {{- '<parameter=' + args_name + '>\n' }}
89
- {%- set args_value = args_value if args_value is string else args_value | tojson | safe %}
90
- {{- args_value }}
91
- {{- '\n</parameter>\n' }}
92
- {%- endfor %}
93
- {%- endif %}
94
- {{- '</function>\n</tool_call>' }}
95
- {%- endfor %}
96
- {{- '<|im_end|>\n' }}
97
- {%- elif message.role == "user" or message.role == "system" or message.role == "assistant" %}
98
- {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
99
- {%- elif message.role == "tool" %}
100
- {%- if loop.previtem and loop.previtem.role != "tool" %}
101
- {{- '<|im_start|>user' }}
102
- {%- endif %}
103
- {{- '\n<tool_response>\n' }}
104
- {{- message.content }}
105
- {{- '\n</tool_response>' }}
106
- {%- if not loop.last and loop.nextitem.role != "tool" %}
107
- {{- '<|im_end|>\n' }}
108
- {%- elif loop.last %}
109
- {{- '<|im_end|>\n' }}
110
- {%- endif %}
111
- {%- else %}
112
- {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>\n' }}
113
- {%- endif %}
114
- {%- endfor %}
115
- {%- if add_generation_prompt %}
116
- {{- '<|im_start|>assistant\n' }}
117
- {%- endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
config.json DELETED
@@ -1,44 +0,0 @@
1
- {
2
- "architectures": [
3
- "Qwen3NextForCausalLM"
4
- ],
5
- "attention_bias": false,
6
- "attention_dropout": 0,
7
- "bos_token_id": 151643,
8
- "decoder_sparse_step": 1,
9
- "eos_token_id": 151645,
10
- "full_attention_interval": 4,
11
- "head_dim": 256,
12
- "hidden_act": "silu",
13
- "hidden_size": 2048,
14
- "initializer_range": 0.02,
15
- "intermediate_size": 5120,
16
- "linear_conv_kernel_dim": 4,
17
- "linear_key_head_dim": 128,
18
- "linear_num_key_heads": 16,
19
- "linear_num_value_heads": 32,
20
- "linear_value_head_dim": 128,
21
- "max_position_embeddings": 262144,
22
- "mlp_only_layers": [],
23
- "model_type": "qwen3_next",
24
- "moe_intermediate_size": 512,
25
- "norm_topk_prob": true,
26
- "num_attention_heads": 16,
27
- "num_experts": 512,
28
- "num_experts_per_tok": 10,
29
- "num_hidden_layers": 48,
30
- "num_key_value_heads": 2,
31
- "output_router_logits": false,
32
- "partial_rotary_factor": 0.25,
33
- "rms_norm_eps": 1e-06,
34
- "rope_scaling": null,
35
- "rope_theta": 5000000,
36
- "router_aux_loss_coef": 0.001,
37
- "shared_expert_intermediate_size": 512,
38
- "tie_word_embeddings": false,
39
- "torch_dtype": "bfloat16",
40
- "transformers_version": "4.57.0.dev0",
41
- "use_cache": true,
42
- "use_sliding_window": false,
43
- "vocab_size": 151936
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
generation_config.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "bos_token_id": 151643,
3
- "do_sample": true,
4
- "eos_token_id": [
5
- 151645,
6
- 151643
7
- ],
8
- "pad_token_id": 151643,
9
- "temperature": 1.0,
10
- "top_k": 40,
11
- "top_p": 0.95,
12
- "transformers_version": "4.57.3"
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
merges.txt DELETED
The diff for this file is too large to render. See raw diff
 
model.safetensors.index.json DELETED
The diff for this file is too large to render. See raw diff
 
qwen3_coder_detector_sgl.py DELETED
@@ -1,474 +0,0 @@
1
- import ast
2
- import json
3
- import logging
4
- import re
5
- from typing import Any, List, Optional
6
-
7
- from sglang.srt.entrypoints.openai.protocol import Tool
8
- from sglang.srt.function_call.base_format_detector import BaseFormatDetector
9
- from sglang.srt.function_call.core_types import (
10
- StreamingParseResult,
11
- ToolCallItem,
12
- _GetInfoFunc,
13
- )
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
-
18
- class Qwen3CoderDetector(BaseFormatDetector):
19
- def __init__(self):
20
- super().__init__()
21
-
22
- # Sentinel tokens
23
- self.tool_call_start_token: str = "<tool_call>"
24
- self.tool_call_end_token: str = "</tool_call>"
25
- self.tool_call_prefix: str = "<function="
26
- self.function_end_token: str = "</function>"
27
- self.parameter_prefix: str = "<parameter="
28
- self.parameter_end_token: str = "</parameter>"
29
-
30
- # Regex for non-streaming fallback
31
- self.tool_call_regex = re.compile(r"<tool_call>(.*?)</tool_call>", re.DOTALL)
32
- self.tool_call_function_regex = re.compile(
33
- r"<function=(.*?)</function>|<function=(.*)$", re.DOTALL
34
- )
35
- self.tool_call_parameter_regex = re.compile(
36
- r"<parameter=(.*?)(?:</parameter>|(?=<parameter=)|(?=</function>)|$)",
37
- re.DOTALL,
38
- )
39
-
40
- # Streaming State
41
- # Base class already initializes _buffer, we just use it directly
42
- # No need to check with hasattr - we control the lifecycle through inheritance
43
-
44
- # Index pointing to the next character to be processed in buffer
45
- self.parsed_pos: int = 0
46
- # Parameter count inside the current tool being processed, used to determine whether to add comma
47
- self.current_tool_param_count: int = 0
48
- # Flag indicating whether current tool has already sent '{'
49
- self.json_started: bool = False
50
-
51
- # [FIX] New state flag: mark whether inside tool_call structure block
52
- self.is_inside_tool_call: bool = False
53
-
54
- # Initialize attributes that were missing in the original PR
55
- self.current_func_name: Optional[str] = None
56
-
57
- def has_tool_call(self, text: str) -> bool:
58
- return self.tool_call_start_token in text
59
-
60
- def _get_arguments_config(
61
- self, func_name: str, tools: Optional[list[Tool]]
62
- ) -> dict:
63
- """Extract argument configuration for a function."""
64
- if tools is None:
65
- return {}
66
- for config in tools:
67
- try:
68
- config_type = config.type
69
- config_function = config.function
70
- config_function_name = config_function.name
71
- except AttributeError:
72
- continue
73
-
74
- if config_type == "function" and config_function_name == func_name:
75
- try:
76
- params = config_function.parameters
77
- except AttributeError:
78
- return {}
79
-
80
- if isinstance(params, dict) and "properties" in params:
81
- return params["properties"]
82
- elif isinstance(params, dict):
83
- return params
84
- else:
85
- return {}
86
- logger.warning(f"Tool '{func_name}' is not defined in the tools list.")
87
- return {}
88
-
89
- def _convert_param_value(
90
- self, param_value: str, param_name: str, param_config: dict, func_name: str
91
- ) -> Any:
92
- """Convert parameter value based on its type in the schema."""
93
- # Handle null value for any type
94
- if param_value.lower() == "null":
95
- return None
96
-
97
- if param_name not in param_config:
98
- if param_config != {}:
99
- logger.warning(
100
- f"Parsed parameter '{param_name}' is not defined in the tool "
101
- f"parameters for tool '{func_name}', directly returning the string value."
102
- )
103
- return param_value
104
-
105
- if (
106
- isinstance(param_config[param_name], dict)
107
- and "type" in param_config[param_name]
108
- ):
109
- param_type = str(param_config[param_name]["type"]).strip().lower()
110
- else:
111
- param_type = "string"
112
- if param_type in ["string", "str", "text", "varchar", "char", "enum"]:
113
- return param_value
114
- elif (
115
- param_type.startswith("int")
116
- or param_type.startswith("uint")
117
- or param_type.startswith("long")
118
- or param_type.startswith("short")
119
- or param_type.startswith("unsigned")
120
- ):
121
- try:
122
- param_value = int(param_value)
123
- except Exception:
124
- logger.warning(
125
- f"Parsed value '{param_value}' of parameter '{param_name}' is not an integer in tool "
126
- f"'{func_name}', degenerating to string."
127
- )
128
- return param_value
129
- elif param_type.startswith("num") or param_type.startswith("float"):
130
- try:
131
- maybe_convert = (
132
- False if "." in param_value or "e" in param_value.lower() else True
133
- )
134
- param_value: float = float(param_value)
135
- if maybe_convert and param_value.is_integer():
136
- param_value = int(param_value)
137
- except Exception:
138
- logger.warning(
139
- f"Parsed value '{param_value}' of parameter '{param_name}' is not a float in tool "
140
- f"'{func_name}', degenerating to string."
141
- )
142
- return param_value
143
- elif param_type in ["boolean", "bool", "binary"]:
144
- param_value = param_value.lower()
145
- if param_value not in ["true", "false"]:
146
- logger.warning(
147
- f"Parsed value '{param_value}' of parameter '{param_name}' is not a boolean (`true` of `false`) in tool '{func_name}', degenerating to false."
148
- )
149
- return param_value == "true"
150
- else:
151
- if (
152
- param_type in ["object", "array", "arr"]
153
- or param_type.startswith("dict")
154
- or param_type.startswith("list")
155
- ):
156
- try:
157
- param_value = json.loads(param_value)
158
- return param_value
159
- except Exception:
160
- logger.warning(
161
- f"Parsed value '{param_value}' of parameter '{param_name}' cannot be parsed with json.loads in tool "
162
- f"'{func_name}', will try other methods to parse it."
163
- )
164
- try:
165
- param_value = ast.literal_eval(param_value) # safer
166
- except Exception:
167
- logger.warning(
168
- f"Parsed value '{param_value}' of parameter '{param_name}' cannot be converted via Python `ast.literal_eval()` in tool '{func_name}', degenerating to string."
169
- )
170
- return param_value
171
-
172
- def detect_and_parse(self, text: str, tools: List[Tool]) -> StreamingParseResult:
173
- """One-shot parsing for non-streaming scenarios."""
174
- if self.tool_call_start_token not in text:
175
- return StreamingParseResult(normal_text=text)
176
-
177
- calls = []
178
- try:
179
- # Simple cleanup of the text to find tool calls
180
- # Note: This is a simplified regex approach consistent with vLLM
181
- raw_tool_calls = self.tool_call_regex.findall(text)
182
- if not raw_tool_calls:
183
- # Fallback: maybe the whole text is inside the tag or tags are stripped
184
- if self.tool_call_prefix in text:
185
- raw_tool_calls = [text]
186
-
187
- tool_idx = 0
188
- for tool_content in raw_tool_calls:
189
- # Find function calls
190
- funcs = self.tool_call_function_regex.findall(tool_content)
191
- for func_match in funcs:
192
- func_body = func_match[0] or func_match[1]
193
- if ">" not in func_body:
194
- continue
195
-
196
- name_end = func_body.index(">")
197
- func_name = func_body[:name_end]
198
- params_str = func_body[name_end + 1 :]
199
-
200
- param_config = self._get_arguments_config(func_name, tools)
201
- parsed_params = {}
202
-
203
- for p_match in self.tool_call_parameter_regex.findall(params_str):
204
- if ">" not in p_match:
205
- continue
206
- p_idx = p_match.index(">")
207
- p_name = p_match[:p_idx]
208
- p_val = p_match[p_idx + 1 :]
209
- # Remove prefixing and trailing \n
210
- if p_val.startswith("\n"):
211
- p_val = p_val[1:]
212
- if p_val.endswith("\n"):
213
- p_val = p_val[:-1]
214
-
215
- parsed_params[p_name] = self._convert_param_value(
216
- p_val, p_name, param_config, func_name
217
- )
218
-
219
- calls.append(
220
- ToolCallItem(
221
- tool_index=tool_idx,
222
- name=func_name,
223
- parameters=json.dumps(parsed_params, ensure_ascii=False),
224
- )
225
- )
226
- tool_idx += 1
227
-
228
- # Determine normal text (text before the first tool call)
229
- start_idx = text.find(self.tool_call_start_token)
230
- if start_idx == -1:
231
- start_idx = text.find(self.tool_call_prefix)
232
- normal_text = text[:start_idx] if start_idx > 0 else ""
233
-
234
- return StreamingParseResult(normal_text=normal_text, calls=calls)
235
-
236
- except Exception as e:
237
- logger.error(f"Error in detect_and_parse: {e}")
238
- return StreamingParseResult(normal_text=text)
239
-
240
- def parse_streaming_increment(
241
- self, new_text: str, tools: List[Tool]
242
- ) -> StreamingParseResult:
243
- """
244
- Robust cursor-based streaming parser.
245
- """
246
- self._buffer += new_text
247
-
248
- # Guard against empty buffer
249
- if not self._buffer:
250
- return StreamingParseResult()
251
-
252
- calls = []
253
- normal_text_chunks = []
254
-
255
- while True:
256
- # Working text slice
257
- current_slice = self._buffer[self.parsed_pos :]
258
-
259
- # Optimization: If almost empty, wait for more
260
- if not current_slice:
261
- break
262
-
263
- # -------------------------------------------------------
264
- # 1. Priority detection: check if it's the start of Tool Call
265
- # -------------------------------------------------------
266
- if current_slice.startswith(self.tool_call_start_token):
267
- self.parsed_pos += len(self.tool_call_start_token)
268
- self.is_inside_tool_call = True
269
- continue
270
-
271
- # -------------------------------------------------------
272
- # 2. Function Name: <function=name>
273
- # -------------------------------------------------------
274
- if current_slice.startswith(self.tool_call_prefix):
275
- end_angle = current_slice.find(">")
276
- if end_angle != -1:
277
- func_name = current_slice[len(self.tool_call_prefix) : end_angle]
278
-
279
- self.current_tool_id += 1
280
- self.current_tool_name_sent = True
281
- self.current_tool_param_count = 0
282
- self.json_started = False
283
- self.current_func_name = func_name
284
-
285
- calls.append(
286
- ToolCallItem(
287
- tool_index=self.current_tool_id,
288
- name=func_name,
289
- parameters="",
290
- )
291
- )
292
-
293
- self.parsed_pos += end_angle + 1
294
- continue
295
- else:
296
- # Incomplete tag
297
- break
298
-
299
- # -------------------------------------------------------
300
- # 3. Parameter: <parameter=name>value...
301
- # -------------------------------------------------------
302
- if current_slice.startswith(self.parameter_prefix):
303
- name_end = current_slice.find(">")
304
- if name_end != -1:
305
- value_start_idx = name_end + 1
306
- rest_of_slice = current_slice[value_start_idx:]
307
-
308
- # A parameter can end in multiple ways:
309
- # 1. [Normal] Encounter </parameter>
310
- # 2. [Abnormal] Encounter next <parameter=
311
- # 3. [Abnormal] Encounter </function>
312
- # So we need to find the smallest one as the parameter end position.
313
- cand_end_param = rest_of_slice.find(self.parameter_end_token)
314
- cand_next_param = rest_of_slice.find(self.parameter_prefix)
315
- cand_end_func = rest_of_slice.find(self.function_end_token)
316
-
317
- candidates = []
318
- if cand_end_param != -1:
319
- candidates.append(
320
- (cand_end_param, len(self.parameter_end_token))
321
- )
322
- if cand_next_param != -1:
323
- candidates.append((cand_next_param, 0))
324
- if cand_end_func != -1:
325
- candidates.append((cand_end_func, 0))
326
-
327
- if candidates:
328
- best_cand = min(candidates, key=lambda x: x[0])
329
- end_pos = best_cand[0]
330
- end_token_len = best_cand[1]
331
-
332
- param_name = current_slice[
333
- len(self.parameter_prefix) : name_end
334
- ]
335
- raw_value = rest_of_slice[:end_pos]
336
-
337
- # Cleanup value
338
- if raw_value.startswith("\n"):
339
- raw_value = raw_value[1:]
340
- if raw_value.endswith("\n"):
341
- raw_value = raw_value[:-1]
342
-
343
- # JSON Construction
344
- if not self.json_started:
345
- calls.append(
346
- ToolCallItem(
347
- tool_index=self.current_tool_id, parameters="{"
348
- )
349
- )
350
- self.json_started = True
351
-
352
- param_config = self._get_arguments_config(
353
- self.current_func_name, tools
354
- )
355
- converted_val = self._convert_param_value(
356
- raw_value, param_name, param_config, self.current_func_name
357
- )
358
-
359
- # Construct JSON fragment: "key": value
360
- # Note: We must be careful with json.dumps to ensure valid JSON streaming
361
- json_key_val = f"{json.dumps(param_name)}: {json.dumps(converted_val, ensure_ascii=False)}"
362
-
363
- if self.current_tool_param_count > 0:
364
- fragment = f", {json_key_val}"
365
- else:
366
- fragment = json_key_val
367
-
368
- calls.append(
369
- ToolCallItem(
370
- tool_index=self.current_tool_id, parameters=fragment
371
- )
372
- )
373
- self.current_tool_param_count += 1
374
-
375
- # Advance cursor
376
- total_len = (name_end + 1) + end_pos + end_token_len
377
- self.parsed_pos += total_len
378
- continue
379
-
380
- # Incomplete parameter tag or value
381
- break
382
-
383
- # -------------------------------------------------------
384
- # 4. Function End: </function>
385
- # -------------------------------------------------------
386
- if current_slice.startswith(self.function_end_token):
387
- if not self.json_started:
388
- calls.append(
389
- ToolCallItem(tool_index=self.current_tool_id, parameters="{")
390
- )
391
- self.json_started = True
392
-
393
- calls.append(
394
- ToolCallItem(tool_index=self.current_tool_id, parameters="}")
395
- )
396
- self.parsed_pos += len(self.function_end_token)
397
- self.current_func_name = None
398
- continue
399
-
400
- # -------------------------------------------------------
401
- # 5. Tool Call End: </tool_call>
402
- # -------------------------------------------------------
403
- if current_slice.startswith(self.tool_call_end_token):
404
- self.parsed_pos += len(self.tool_call_end_token)
405
- self.is_inside_tool_call = False # [FIX] Exit tool call region
406
- continue
407
-
408
- # -------------------------------------------------------
409
- # 6. Handling content / whitespace / normal text
410
- # -------------------------------------------------------
411
- # If current position is not the start of a tag (i.e., doesn't start with <), it might be plain text,
412
- # or a newline between two tags.
413
- # But we need to be careful not to output truncated tags like "<fun" as text.
414
-
415
- next_open_angle = current_slice.find("<")
416
-
417
- if next_open_angle == -1:
418
- # This entire segment is plain text
419
- if not self.is_inside_tool_call:
420
- normal_text_chunks.append(current_slice)
421
- # [FIX] If inside tool call, discard this text (usually \n), don't append
422
- self.parsed_pos += len(current_slice)
423
- continue
424
-
425
- elif next_open_angle == 0:
426
- # Looks like a Tag, but doesn't match any known Tag above
427
-
428
- possible_tags = [
429
- self.tool_call_start_token,
430
- self.tool_call_end_token,
431
- self.tool_call_prefix,
432
- self.function_end_token,
433
- self.parameter_prefix,
434
- self.parameter_end_token,
435
- ]
436
-
437
- is_potential_tag = False
438
- for tag in possible_tags:
439
- if tag.startswith(current_slice):
440
- is_potential_tag = True
441
- break
442
-
443
- if is_potential_tag:
444
- break # Wait for more
445
- else:
446
- # Just a plain '<' symbol
447
- if not self.is_inside_tool_call:
448
- normal_text_chunks.append("<")
449
- self.parsed_pos += 1
450
- continue
451
-
452
- else:
453
- # '<' is in the middle
454
- text_segment = current_slice[:next_open_angle]
455
- if not self.is_inside_tool_call:
456
- normal_text_chunks.append(text_segment)
457
- # [FIX] If inside tool call, discard whitespace/text before Tag
458
- self.parsed_pos += next_open_angle
459
- continue
460
-
461
- # Memory Cleanup: Slice the buffer
462
- # Keep unparsed part, discard parsed part
463
- if self.parsed_pos > 0:
464
- self._buffer = self._buffer[self.parsed_pos :]
465
- self.parsed_pos = 0
466
-
467
- normal_text = "".join(normal_text_chunks) if normal_text_chunks else ""
468
- return StreamingParseResult(calls=calls, normal_text=normal_text)
469
-
470
- def supports_structural_tag(self) -> bool:
471
- return False
472
-
473
- def structure_info(self) -> _GetInfoFunc:
474
- raise NotImplementedError
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
qwen3coder_tool_parser_vllm.py DELETED
@@ -1,690 +0,0 @@
1
- # SPDX-License-Identifier: Apache-2.0
2
- # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
- import ast
4
- import json
5
- import uuid
6
- from collections.abc import Sequence
7
- from typing import Any, List, Optional, Union
8
-
9
- import regex as re
10
-
11
- from vllm.entrypoints.openai.protocol import (ChatCompletionRequest,
12
- ChatCompletionToolsParam,
13
- DeltaFunctionCall, DeltaMessage,
14
- DeltaToolCall,
15
- ExtractedToolCallInformation,
16
- FunctionCall, ToolCall)
17
- from vllm.entrypoints.openai.tool_parsers.abstract_tool_parser import (
18
- ToolParser, ToolParserManager)
19
- from vllm.logger import init_logger
20
- from vllm.transformers_utils.tokenizer import AnyTokenizer
21
-
22
- logger = init_logger(__name__)
23
-
24
-
25
- @ToolParserManager.register_module("qwen3_coder")
26
- class Qwen3CoderToolParser(ToolParser):
27
-
28
- def __init__(self, tokenizer: AnyTokenizer):
29
- super().__init__(tokenizer)
30
-
31
- self.current_tool_name_sent: bool = False
32
- self.prev_tool_call_arr: list[dict] = []
33
- self.current_tool_id: int = -1
34
- self.streamed_args_for_tool: list[str] = []
35
-
36
- # Sentinel tokens for streaming mode
37
- self.tool_call_start_token: str = "<tool_call>"
38
- self.tool_call_end_token: str = "</tool_call>"
39
- self.tool_call_prefix: str = "<function="
40
- self.function_end_token: str = "</function>"
41
- self.parameter_prefix: str = "<parameter="
42
- self.parameter_end_token: str = "</parameter>"
43
- self.is_tool_call_started: bool = False
44
- self.failed_count: int = 0
45
-
46
- # Enhanced streaming state - reset for each new message
47
- self._reset_streaming_state()
48
-
49
- # Regex patterns
50
- self.tool_call_complete_regex = re.compile(
51
- r"<tool_call>(.*?)</tool_call>", re.DOTALL)
52
- self.tool_call_regex = re.compile(
53
- r"<tool_call>(.*?)</tool_call>|<tool_call>(.*?)$", re.DOTALL)
54
- self.tool_call_function_regex = re.compile(
55
- r"<function=(.*?)</function>|<function=(.*)$", re.DOTALL)
56
- self.tool_call_parameter_regex = re.compile(
57
- r"<parameter=(.*?)(?:</parameter>|(?=<parameter=)|(?=</function>)|$)",
58
- re.DOTALL)
59
-
60
- if not self.model_tokenizer:
61
- raise ValueError(
62
- "The model tokenizer must be passed to the ToolParser "
63
- "constructor during construction.")
64
-
65
- self.tool_call_start_token_id = self.vocab.get(
66
- self.tool_call_start_token)
67
- self.tool_call_end_token_id = self.vocab.get(self.tool_call_end_token)
68
-
69
- if self.tool_call_start_token_id is None or self.tool_call_end_token_id is None:
70
- raise RuntimeError(
71
- "Qwen3 XML Tool parser could not locate tool call start/end "
72
- "tokens in the tokenizer!")
73
-
74
- logger.info(
75
- f"vLLM Successfully import tool parser {self.__class__.__name__} !"
76
- )
77
-
78
- def _generate_tool_call_id(self) -> str:
79
- """Generate a unique tool call ID."""
80
- return f"call_{uuid.uuid4().hex[:24]}"
81
-
82
- def _reset_streaming_state(self):
83
- """Reset all streaming state."""
84
- self.current_tool_index = 0
85
- self.is_tool_call_started = False
86
- self.header_sent = False
87
- self.current_tool_id = None
88
- self.current_function_name = None
89
- self.current_param_name = None
90
- self.current_param_value = ""
91
- self.param_count = 0
92
- self.in_param = False
93
- self.in_function = False
94
- self.accumulated_text = ""
95
- self.json_started = False
96
- self.json_closed = False
97
- # Store accumulated parameters for type conversion
98
- self.accumulated_params = {}
99
- self.streaming_request = None
100
-
101
- def _get_arguments_config(
102
- self, func_name: str,
103
- tools: Optional[list[ChatCompletionToolsParam]]) -> dict:
104
- """Extract argument configuration for a function."""
105
- if tools is None:
106
- return {}
107
- for config in tools:
108
- if not hasattr(config, "type") or not (hasattr(
109
- config, "function") and hasattr(config.function, "name")):
110
- continue
111
- if config.type == "function" and config.function.name == func_name:
112
- if not hasattr(config.function, "parameters"):
113
- return {}
114
- params = config.function.parameters
115
- if isinstance(params, dict) and "properties" in params:
116
- return params["properties"]
117
- elif isinstance(params, dict):
118
- return params
119
- else:
120
- return {}
121
- logger.warning(f"Tool '{func_name}' is not defined in the tools list.")
122
- return {}
123
-
124
- def _convert_param_value(self, param_value: str, param_name: str,
125
- param_config: dict, func_name: str) -> Any:
126
- """Convert parameter value based on its type in the schema."""
127
- # Handle null value for any type
128
- if param_value.lower() == "null":
129
- return None
130
-
131
- if param_name not in param_config:
132
- if param_config != {}:
133
- logger.warning(
134
- f"Parsed parameter '{param_name}' is not defined in the tool "
135
- f"parameters for tool '{func_name}', directly returning the string value."
136
- )
137
- return param_value
138
-
139
- if isinstance(param_config[param_name],
140
- dict) and "type" in param_config[param_name]:
141
- param_type = str(param_config[param_name]["type"]).strip().lower()
142
- else:
143
- param_type = "string"
144
- if param_type in ["string", "str", "text", "varchar", "char", "enum"]:
145
- return param_value
146
- elif param_type.startswith("int") or param_type.startswith(
147
- "uint") or param_type.startswith(
148
- "long") or param_type.startswith(
149
- "short") or param_type.startswith("unsigned"):
150
- try:
151
- param_value = int(param_value)
152
- except:
153
- logger.warning(
154
- f"Parsed value '{param_value}' of parameter '{param_name}' is not an integer in tool "
155
- f"'{func_name}', degenerating to string.")
156
- return param_value
157
- elif param_type.startswith("num") or param_type.startswith("float"):
158
- try:
159
- maybe_convert = False if "." in param_value or "e" in param_value.lower() else True
160
- param_value: float = float(param_value)
161
- if maybe_convert and param_value.is_integer():
162
- param_value = int(param_value)
163
- except:
164
- logger.warning(
165
- f"Parsed value '{param_value}' of parameter '{param_name}' is not a float in tool "
166
- f"'{func_name}', degenerating to string.")
167
- return param_value
168
- elif param_type in ["boolean", "bool", "binary"]:
169
- param_value = param_value.lower()
170
- if param_value not in ["true", "false"]:
171
- logger.warning(
172
- f"Parsed value '{param_value}' of parameter '{param_name}' is not a boolean (`true` of `false`) in tool '{func_name}', degenerating to false."
173
- )
174
- return param_value == "true"
175
- else:
176
- if param_type in ["object", "array", "arr"
177
- ] or param_type.startswith(
178
- "dict") or param_type.startswith("list"):
179
- try:
180
- param_value = json.loads(param_value)
181
- return param_value
182
- except:
183
- logger.warning(
184
- f"Parsed value '{param_value}' of parameter '{param_name}' cannot be parsed with json.loads in tool "
185
- f"'{func_name}', will try other methods to parse it.")
186
- try:
187
- param_value = ast.literal_eval(param_value) # safer
188
- except:
189
- logger.warning(
190
- f"Parsed value '{param_value}' of parameter '{param_name}' cannot be converted via Python `ast.literal_eval()` in tool '{func_name}', degenerating to string."
191
- )
192
- return param_value
193
-
194
- def _parse_xml_function_call(
195
- self, function_call_str: str,
196
- tools: Optional[list[ChatCompletionToolsParam]]
197
- ) -> Optional[ToolCall]:
198
-
199
- # Extract function name
200
- end_index = function_call_str.index(">")
201
- function_name = function_call_str[:end_index]
202
- param_config = self._get_arguments_config(function_name, tools)
203
- parameters = function_call_str[end_index + 1:]
204
- param_dict = {}
205
- for match_text in self.tool_call_parameter_regex.findall(parameters):
206
- idx = match_text.index(">")
207
- param_name = match_text[:idx]
208
- param_value = str(match_text[idx + 1:])
209
- # Remove prefix and trailing \n
210
- if param_value.startswith("\n"):
211
- param_value = param_value[1:]
212
- if param_value.endswith("\n"):
213
- param_value = param_value[:-1]
214
-
215
- param_dict[param_name] = self._convert_param_value(
216
- param_value, param_name, param_config, function_name)
217
- return ToolCall(
218
- type="function",
219
- function=FunctionCall(name=function_name,
220
- arguments=json.dumps(param_dict,
221
- ensure_ascii=False)),
222
- )
223
-
224
- def _get_function_calls(self, model_output: str) -> List[str]:
225
- # Find all tool calls
226
- matched_ranges = self.tool_call_regex.findall(model_output)
227
- raw_tool_calls = [
228
- match[0] if match[0] else match[1] for match in matched_ranges
229
- ]
230
-
231
- # Back-off strategy if no tool_call tags found
232
- if len(raw_tool_calls) == 0:
233
- raw_tool_calls = [model_output]
234
-
235
- raw_function_calls = []
236
- for tool_call in raw_tool_calls:
237
- raw_function_calls.extend(
238
- self.tool_call_function_regex.findall(tool_call))
239
-
240
- function_calls = [
241
- match[0] if match[0] else match[1] for match in raw_function_calls
242
- ]
243
- return function_calls
244
-
245
- def extract_tool_calls(
246
- self,
247
- model_output: str,
248
- request: ChatCompletionRequest,
249
- ) -> ExtractedToolCallInformation:
250
- # Quick check to avoid unnecessary processing
251
- if self.tool_call_prefix not in model_output:
252
- return ExtractedToolCallInformation(tools_called=False,
253
- tool_calls=[],
254
- content=model_output)
255
-
256
- try:
257
- function_calls = self._get_function_calls(model_output)
258
- if len(function_calls) == 0:
259
- return ExtractedToolCallInformation(tools_called=False,
260
- tool_calls=[],
261
- content=model_output)
262
-
263
- tool_calls = [
264
- self._parse_xml_function_call(function_call_str, request.tools)
265
- for function_call_str in function_calls
266
- ]
267
-
268
- # Populate prev_tool_call_arr for serving layer to set finish_reason
269
- self.prev_tool_call_arr.clear() # Clear previous calls
270
- for tool_call in tool_calls:
271
- if tool_call:
272
- self.prev_tool_call_arr.append({
273
- "name":
274
- tool_call.function.name,
275
- "arguments":
276
- tool_call.function.arguments,
277
- })
278
-
279
- # Extract content before tool calls
280
- content_index = model_output.find(self.tool_call_start_token)
281
- content_index = content_index if content_index >= 0 else model_output.find(
282
- self.tool_call_prefix)
283
- content = model_output[:content_index] # .rstrip()
284
-
285
- return ExtractedToolCallInformation(
286
- tools_called=(len(tool_calls) > 0),
287
- tool_calls=tool_calls,
288
- content=content if content else None,
289
- )
290
-
291
- except Exception:
292
- logger.exception("Error in extracting tool call from response.")
293
- return ExtractedToolCallInformation(tools_called=False,
294
- tool_calls=[],
295
- content=model_output)
296
-
297
- def extract_tool_calls_streaming(
298
- self,
299
- previous_text: str,
300
- current_text: str,
301
- delta_text: str,
302
- previous_token_ids: Sequence[int],
303
- current_token_ids: Sequence[int],
304
- delta_token_ids: Sequence[int],
305
- request: ChatCompletionRequest,
306
- ) -> Union[DeltaMessage, None]:
307
- # Store request for type conversion
308
- if not previous_text:
309
- self._reset_streaming_state()
310
- self.streaming_request = request
311
-
312
- # If no delta text, return None unless it's an EOS token after tool calls
313
- if not delta_text:
314
- # Check if this is an EOS token after all tool calls are complete
315
- # We check for tool calls in the text even if is_tool_call_started is False
316
- # because it might have been reset after processing all tools
317
- if delta_token_ids and self.tool_call_end_token_id not in delta_token_ids:
318
- # Count complete tool calls
319
- complete_calls = len(
320
- self.tool_call_complete_regex.findall(current_text))
321
-
322
- # If we have completed tool calls and populated prev_tool_call_arr
323
- if complete_calls > 0 and len(self.prev_tool_call_arr) > 0:
324
- # Check if all tool calls are closed
325
- open_calls = current_text.count(
326
- self.tool_call_start_token) - current_text.count(
327
- self.tool_call_end_token)
328
- if open_calls == 0:
329
- # Return empty delta message to allow finish_reason processing
330
- return DeltaMessage(content="")
331
- elif not self.is_tool_call_started and current_text:
332
- # This is a regular content response that's now complete
333
- return DeltaMessage(content="")
334
- return None
335
-
336
- # Update accumulated text
337
- self.accumulated_text = current_text
338
-
339
- # Check if we need to advance to next tool
340
- if self.json_closed and not self.in_function:
341
- # Check if this tool call has ended
342
- tool_ends = current_text.count(self.tool_call_end_token)
343
- if tool_ends > self.current_tool_index:
344
- # This tool has ended, advance to next
345
- self.current_tool_index += 1
346
- self.header_sent = False
347
- self.param_count = 0
348
- self.json_started = False
349
- self.json_closed = False
350
- self.accumulated_params = {}
351
-
352
- # Check if there are more tool calls
353
- tool_starts = current_text.count(self.tool_call_start_token)
354
- if self.current_tool_index >= tool_starts:
355
- # No more tool calls
356
- self.is_tool_call_started = False
357
- # Continue processing next tool
358
- return None
359
-
360
- # Handle normal content before tool calls
361
- if not self.is_tool_call_started:
362
- # Check if tool call is starting
363
- if self.tool_call_start_token_id in delta_token_ids or self.tool_call_start_token in delta_text:
364
- self.is_tool_call_started = True
365
- # Return any content before the tool call
366
- if self.tool_call_start_token in delta_text:
367
- content_before = delta_text[:delta_text.index(
368
- self.tool_call_start_token)]
369
- if content_before:
370
- return DeltaMessage(content=content_before)
371
- return None
372
- else:
373
- # Check if we're between tool calls - skip whitespace
374
- if current_text.rstrip().endswith(self.tool_call_end_token):
375
- # We just ended a tool call, skip whitespace
376
- if delta_text.strip() == "":
377
- return None
378
- # Normal content, no tool call
379
- return DeltaMessage(content=delta_text)
380
-
381
- # Check if we're between tool calls (waiting for next one)
382
- # Count tool calls we've seen vs processed
383
- tool_starts_count = current_text.count(self.tool_call_start_token)
384
- if self.current_tool_index >= tool_starts_count:
385
- # We're past all tool calls, shouldn't be here
386
- return None
387
-
388
- # We're in a tool call, find the current tool call portion
389
- # Need to find the correct tool call based on current_tool_index
390
- tool_starts = []
391
- idx = 0
392
- while True:
393
- idx = current_text.find(self.tool_call_start_token, idx)
394
- if idx == -1:
395
- break
396
- tool_starts.append(idx)
397
- idx += len(self.tool_call_start_token)
398
-
399
- if self.current_tool_index >= len(tool_starts):
400
- # No more tool calls to process yet
401
- return None
402
-
403
- tool_start_idx = tool_starts[self.current_tool_index]
404
- # Find where this tool call ends (or current position if not ended yet)
405
- tool_end_idx = current_text.find(self.tool_call_end_token,
406
- tool_start_idx)
407
- if tool_end_idx == -1:
408
- tool_text = current_text[tool_start_idx:]
409
- else:
410
- tool_text = current_text[tool_start_idx:tool_end_idx +
411
- len(self.tool_call_end_token)]
412
-
413
- # Looking for function header
414
- if not self.header_sent:
415
- if self.tool_call_prefix in tool_text:
416
- func_start = tool_text.find(self.tool_call_prefix) + len(
417
- self.tool_call_prefix)
418
- func_end = tool_text.find(">", func_start)
419
-
420
- if func_end != -1:
421
- # Found complete function name
422
- self.current_function_name = tool_text[func_start:func_end]
423
- self.current_tool_id = self._generate_tool_call_id()
424
- self.header_sent = True
425
- self.in_function = True
426
-
427
- # IMPORTANT: Add to prev_tool_call_arr immediately when we detect a tool call
428
- # This ensures finish_reason="tool_calls" even if parsing isn't complete
429
- already_added = any(
430
- tool.get("name") == self.current_function_name
431
- for tool in self.prev_tool_call_arr)
432
- if not already_added:
433
- self.prev_tool_call_arr.append({
434
- "name": self.current_function_name,
435
- "arguments":
436
- "{}", # Placeholder, will be updated later
437
- })
438
-
439
- # Send header with function info
440
- return DeltaMessage(tool_calls=[
441
- DeltaToolCall(
442
- index=self.current_tool_index,
443
- id=self.current_tool_id,
444
- function=DeltaFunctionCall(
445
- name=self.current_function_name, arguments=""),
446
- type="function",
447
- )
448
- ])
449
- return None
450
-
451
- # We've sent header, now handle function body
452
- if self.in_function:
453
- # Send opening brace if not sent yet
454
- if not self.json_started and self.parameter_prefix not in delta_text:
455
- self.json_started = True
456
- return DeltaMessage(tool_calls=[
457
- DeltaToolCall(
458
- index=self.current_tool_index,
459
- function=DeltaFunctionCall(arguments="{"),
460
- )
461
- ])
462
-
463
- # Make sure json_started is set if we're processing parameters
464
- if not self.json_started:
465
- self.json_started = True
466
-
467
- # Check for function end in accumulated text
468
- if not self.json_closed and self.function_end_token in tool_text:
469
- # Close JSON
470
- self.json_closed = True
471
-
472
- # Extract the complete tool call to update prev_tool_call_arr with final arguments
473
- # Find the function content
474
- func_start = tool_text.find(self.tool_call_prefix) + len(
475
- self.tool_call_prefix)
476
- func_content_end = tool_text.find(self.function_end_token,
477
- func_start)
478
- if func_content_end != -1:
479
- func_content = tool_text[func_start:func_content_end]
480
- # Parse to get the complete arguments
481
- try:
482
- parsed_tool = self._parse_xml_function_call(
483
- func_content, self.streaming_request.tools
484
- if self.streaming_request else None)
485
- if parsed_tool:
486
- # Update existing entry in prev_tool_call_arr with complete arguments
487
- for i, tool in enumerate(self.prev_tool_call_arr):
488
- if tool.get(
489
- "name") == parsed_tool.function.name:
490
- self.prev_tool_call_arr[i][
491
- "arguments"] = parsed_tool.function.arguments
492
- break
493
- except Exception:
494
- pass # Ignore parsing errors during streaming
495
-
496
- result = DeltaMessage(tool_calls=[
497
- DeltaToolCall(
498
- index=self.current_tool_index,
499
- function=DeltaFunctionCall(arguments="}"),
500
- )
501
- ])
502
-
503
- # Reset state for next tool
504
- self.in_function = False
505
- self.json_closed = True
506
- self.accumulated_params = {}
507
-
508
- return result
509
-
510
- # Look for parameters
511
- # Find all parameter starts
512
- param_starts = []
513
- idx = 0
514
- while True:
515
- idx = tool_text.find(self.parameter_prefix, idx)
516
- if idx == -1:
517
- break
518
- param_starts.append(idx)
519
- idx += len(self.parameter_prefix)
520
-
521
- # Check if we should start a new parameter
522
- if not self.in_param and self.param_count < len(param_starts):
523
-
524
- if len(param_starts) > self.param_count:
525
- # Process the next parameter
526
- param_idx = param_starts[self.param_count]
527
- param_start = param_idx + len(self.parameter_prefix)
528
- remaining = tool_text[param_start:]
529
-
530
- if ">" in remaining:
531
- # We have the complete parameter name
532
- name_end = remaining.find(">")
533
- self.current_param_name = remaining[:name_end]
534
-
535
- # Find the parameter value
536
- value_start = param_start + name_end + 1
537
- value_text = tool_text[value_start:]
538
- if value_text.startswith("\n"):
539
- value_text = value_text[1:]
540
-
541
- # Find where this parameter ends
542
- param_end_idx = value_text.find(
543
- self.parameter_end_token)
544
- if param_end_idx == -1:
545
- # No closing tag, look for next parameter or function end
546
- next_param_idx = value_text.find(
547
- self.parameter_prefix)
548
- func_end_idx = value_text.find(
549
- self.function_end_token)
550
-
551
- if next_param_idx != -1 and (func_end_idx == -1
552
- or next_param_idx
553
- < func_end_idx):
554
- param_end_idx = next_param_idx
555
- elif func_end_idx != -1:
556
- param_end_idx = func_end_idx
557
- else:
558
- # Neither found, check if tool call is complete
559
- if self.tool_call_end_token in tool_text:
560
- # Tool call is complete, so parameter must be complete too
561
- # Use all remaining text before function end as value
562
- param_end_idx = len(value_text)
563
- else:
564
- # Still streaming, wait for more content
565
- return None
566
-
567
- if param_end_idx != -1:
568
- # Complete parameter found
569
- param_value = value_text[:param_end_idx]
570
- if param_value.endswith("\n"):
571
- param_value = param_value[:-1]
572
-
573
- # Store raw value for later processing
574
- self.accumulated_params[
575
- self.current_param_name] = param_value
576
-
577
- # Get parameter configuration for type conversion
578
- param_config = self._get_arguments_config(
579
- self.current_function_name,
580
- self.streaming_request.tools
581
- if self.streaming_request else None)
582
-
583
- # Convert the parameter value to the appropriate type
584
- converted_value = self._convert_param_value(
585
- param_value, self.current_param_name,
586
- param_config, self.current_function_name)
587
-
588
- # Build JSON fragment based on the converted type
589
- # Use json.dumps to properly serialize the value
590
- serialized_value = json.dumps(converted_value,
591
- ensure_ascii=False)
592
-
593
- if self.param_count == 0:
594
- json_fragment = f'"{self.current_param_name}": {serialized_value}'
595
- else:
596
- json_fragment = f', "{self.current_param_name}": {serialized_value}'
597
-
598
- self.param_count += 1
599
-
600
- return DeltaMessage(tool_calls=[
601
- DeltaToolCall(
602
- index=self.current_tool_index,
603
- function=DeltaFunctionCall(
604
- arguments=json_fragment),
605
- )
606
- ])
607
-
608
- # Continue parameter value - Not used in the current implementation
609
- # since we process complete parameters above
610
- if self.in_param:
611
- if self.parameter_end_token in delta_text:
612
- # End of parameter
613
- end_idx = delta_text.find(self.parameter_end_token)
614
- value_chunk = delta_text[:end_idx]
615
-
616
- # Skip past > if at start
617
- if not self.current_param_value and ">" in value_chunk:
618
- gt_idx = value_chunk.find(">")
619
- value_chunk = value_chunk[gt_idx + 1:]
620
-
621
- if not self.current_param_value and value_chunk.startswith(
622
- "\n"):
623
- value_chunk = value_chunk[1:]
624
-
625
- # Store complete value
626
- full_value = self.current_param_value + value_chunk
627
- self.accumulated_params[
628
- self.current_param_name] = full_value
629
-
630
- # Get parameter configuration for type conversion
631
- param_config = self._get_arguments_config(
632
- self.current_function_name,
633
- self.streaming_request.tools
634
- if self.streaming_request else None)
635
-
636
- # Convert the parameter value to the appropriate type
637
- converted_value = self._convert_param_value(
638
- full_value, self.current_param_name, param_config,
639
- self.current_function_name)
640
-
641
- # Serialize the converted value
642
- serialized_value = json.dumps(converted_value,
643
- ensure_ascii=False)
644
-
645
- # Since we've been streaming the quoted version, we need to close it properly
646
- # This is complex - for now just complete the value
647
- self.in_param = False
648
- self.current_param_value = ""
649
-
650
- # Just close the current parameter string
651
- return DeltaMessage(tool_calls=[
652
- DeltaToolCall(
653
- index=self.current_tool_index,
654
- function=DeltaFunctionCall(
655
- arguments='"'), # Close the string quote
656
- )
657
- ])
658
- else:
659
- # Continue accumulating value
660
- value_chunk = delta_text
661
-
662
- # Handle first chunk after param name
663
- if not self.current_param_value and ">" in value_chunk:
664
- gt_idx = value_chunk.find(">")
665
- value_chunk = value_chunk[gt_idx + 1:]
666
-
667
- if not self.current_param_value and value_chunk.startswith(
668
- "\n"):
669
- value_chunk = value_chunk[1:]
670
-
671
- if value_chunk:
672
- # Stream the escaped delta
673
- prev_escaped = json.dumps(
674
- self.current_param_value, ensure_ascii=False
675
- )[1:-1] if self.current_param_value else ""
676
- self.current_param_value += value_chunk
677
- full_escaped = json.dumps(self.current_param_value,
678
- ensure_ascii=False)[1:-1]
679
- delta_escaped = full_escaped[len(prev_escaped):]
680
-
681
- if delta_escaped:
682
- return DeltaMessage(tool_calls=[
683
- DeltaToolCall(
684
- index=self.current_tool_index,
685
- function=DeltaFunctionCall(
686
- arguments=delta_escaped),
687
- )
688
- ])
689
-
690
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tokenizer.json DELETED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json DELETED
@@ -1,239 +0,0 @@
1
- {
2
- "add_prefix_space": false,
3
- "added_tokens_decoder": {
4
- "151643": {
5
- "content": "<|endoftext|>",
6
- "lstrip": false,
7
- "normalized": false,
8
- "rstrip": false,
9
- "single_word": false,
10
- "special": true
11
- },
12
- "151644": {
13
- "content": "<|im_start|>",
14
- "lstrip": false,
15
- "normalized": false,
16
- "rstrip": false,
17
- "single_word": false,
18
- "special": true
19
- },
20
- "151645": {
21
- "content": "<|im_end|>",
22
- "lstrip": false,
23
- "normalized": false,
24
- "rstrip": false,
25
- "single_word": false,
26
- "special": true
27
- },
28
- "151646": {
29
- "content": "<|object_ref_start|>",
30
- "lstrip": false,
31
- "normalized": false,
32
- "rstrip": false,
33
- "single_word": false,
34
- "special": true
35
- },
36
- "151647": {
37
- "content": "<|object_ref_end|>",
38
- "lstrip": false,
39
- "normalized": false,
40
- "rstrip": false,
41
- "single_word": false,
42
- "special": true
43
- },
44
- "151648": {
45
- "content": "<|box_start|>",
46
- "lstrip": false,
47
- "normalized": false,
48
- "rstrip": false,
49
- "single_word": false,
50
- "special": true
51
- },
52
- "151649": {
53
- "content": "<|box_end|>",
54
- "lstrip": false,
55
- "normalized": false,
56
- "rstrip": false,
57
- "single_word": false,
58
- "special": true
59
- },
60
- "151650": {
61
- "content": "<|quad_start|>",
62
- "lstrip": false,
63
- "normalized": false,
64
- "rstrip": false,
65
- "single_word": false,
66
- "special": true
67
- },
68
- "151651": {
69
- "content": "<|quad_end|>",
70
- "lstrip": false,
71
- "normalized": false,
72
- "rstrip": false,
73
- "single_word": false,
74
- "special": true
75
- },
76
- "151652": {
77
- "content": "<|vision_start|>",
78
- "lstrip": false,
79
- "normalized": false,
80
- "rstrip": false,
81
- "single_word": false,
82
- "special": true
83
- },
84
- "151653": {
85
- "content": "<|vision_end|>",
86
- "lstrip": false,
87
- "normalized": false,
88
- "rstrip": false,
89
- "single_word": false,
90
- "special": true
91
- },
92
- "151654": {
93
- "content": "<|vision_pad|>",
94
- "lstrip": false,
95
- "normalized": false,
96
- "rstrip": false,
97
- "single_word": false,
98
- "special": true
99
- },
100
- "151655": {
101
- "content": "<|image_pad|>",
102
- "lstrip": false,
103
- "normalized": false,
104
- "rstrip": false,
105
- "single_word": false,
106
- "special": true
107
- },
108
- "151656": {
109
- "content": "<|video_pad|>",
110
- "lstrip": false,
111
- "normalized": false,
112
- "rstrip": false,
113
- "single_word": false,
114
- "special": true
115
- },
116
- "151657": {
117
- "content": "<tool_call>",
118
- "lstrip": false,
119
- "normalized": false,
120
- "rstrip": false,
121
- "single_word": false,
122
- "special": false
123
- },
124
- "151658": {
125
- "content": "</tool_call>",
126
- "lstrip": false,
127
- "normalized": false,
128
- "rstrip": false,
129
- "single_word": false,
130
- "special": false
131
- },
132
- "151659": {
133
- "content": "<|fim_prefix|>",
134
- "lstrip": false,
135
- "normalized": false,
136
- "rstrip": false,
137
- "single_word": false,
138
- "special": false
139
- },
140
- "151660": {
141
- "content": "<|fim_middle|>",
142
- "lstrip": false,
143
- "normalized": false,
144
- "rstrip": false,
145
- "single_word": false,
146
- "special": false
147
- },
148
- "151661": {
149
- "content": "<|fim_suffix|>",
150
- "lstrip": false,
151
- "normalized": false,
152
- "rstrip": false,
153
- "single_word": false,
154
- "special": false
155
- },
156
- "151662": {
157
- "content": "<|fim_pad|>",
158
- "lstrip": false,
159
- "normalized": false,
160
- "rstrip": false,
161
- "single_word": false,
162
- "special": false
163
- },
164
- "151663": {
165
- "content": "<|repo_name|>",
166
- "lstrip": false,
167
- "normalized": false,
168
- "rstrip": false,
169
- "single_word": false,
170
- "special": false
171
- },
172
- "151664": {
173
- "content": "<|file_sep|>",
174
- "lstrip": false,
175
- "normalized": false,
176
- "rstrip": false,
177
- "single_word": false,
178
- "special": false
179
- },
180
- "151665": {
181
- "content": "<tool_response>",
182
- "lstrip": false,
183
- "normalized": false,
184
- "rstrip": false,
185
- "single_word": false,
186
- "special": false
187
- },
188
- "151666": {
189
- "content": "</tool_response>",
190
- "lstrip": false,
191
- "normalized": false,
192
- "rstrip": false,
193
- "single_word": false,
194
- "special": false
195
- },
196
- "151667": {
197
- "content": "<think>",
198
- "lstrip": false,
199
- "normalized": false,
200
- "rstrip": false,
201
- "single_word": false,
202
- "special": false
203
- },
204
- "151668": {
205
- "content": "</think>",
206
- "lstrip": false,
207
- "normalized": false,
208
- "rstrip": false,
209
- "single_word": false,
210
- "special": false
211
- }
212
- },
213
- "additional_special_tokens": [
214
- "<|im_start|>",
215
- "<|im_end|>",
216
- "<|object_ref_start|>",
217
- "<|object_ref_end|>",
218
- "<|box_start|>",
219
- "<|box_end|>",
220
- "<|quad_start|>",
221
- "<|quad_end|>",
222
- "<|vision_start|>",
223
- "<|vision_end|>",
224
- "<|vision_pad|>",
225
- "<|image_pad|>",
226
- "<|video_pad|>"
227
- ],
228
- "bos_token": null,
229
- "chat_template": "{% macro render_extra_keys(json_dict, handled_keys) %}\n {%- if json_dict is mapping %}\n {%- for json_key in json_dict if json_key not in handled_keys %}\n {%- if json_dict[json_key] is string %}\n {{-'\\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | string) ~ '</' ~ json_key ~ '>' }}\n {%- else %}\n {{- '\\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | tojson | safe) ~ '</' ~ json_key ~ '>' }}\n {%- endif %}\n {%- endfor %}\n {%- endif %}\n{%- endmacro %}\n\n{%- if messages[0][\"role\"] == \"system\" %}\n {%- set system_message = messages[0][\"content\"] %}\n {%- set loop_messages = messages[1:] %}\n{%- else %}\n {%- set loop_messages = messages %}\n{%- endif %}\n\n{%- if not tools is defined %}\n {%- set tools = [] %}\n{%- endif %}\n\n{%- if system_message is defined %}\n {{- \"<|im_start|>system\\n\" + system_message }}\n{%- else %}\n {%- if tools is iterable and tools | length > 0 %}\n {{- \"<|im_start|>system\\nYou are Qwen, a helpful AI assistant that can interact with a computer to solve tasks.\" }}\n {%- endif %}\n{%- endif %}\n{%- if tools is iterable and tools | length > 0 %}\n {{- \"\\n\\n# Tools\\n\\nYou have access to the following functions:\\n\\n\" }}\n {{- \"<tools>\" }}\n {%- for tool in tools %}\n {%- if tool.function is defined %}\n {%- set tool = tool.function %}\n {%- endif %}\n {{- \"\\n<function>\\n<name>\" ~ tool.name ~ \"</name>\" }}\n {%- if tool.description is defined %}\n {{- '\\n<description>' ~ (tool.description | trim) ~ '</description>' }}\n {%- endif %}\n {{- '\\n<parameters>' }}\n {%- if tool.parameters is defined and tool.parameters is mapping and tool.parameters.properties is defined and tool.parameters.properties is mapping %}\n {%- for param_name, param_fields in tool.parameters.properties|items %}\n {{- '\\n<parameter>' }}\n {{- '\\n<name>' ~ param_name ~ '</name>' }}\n {%- if param_fields.type is defined %}\n {{- '\\n<type>' ~ (param_fields.type | string) ~ '</type>' }}\n {%- endif %}\n {%- if param_fields.description is defined %}\n {{- '\\n<description>' ~ (param_fields.description | trim) ~ '</description>' }}\n {%- endif %}\n {%- set handled_keys = ['name', 'type', 'description'] %}\n {{- render_extra_keys(param_fields, handled_keys) }}\n {{- '\\n</parameter>' }}\n {%- endfor %}\n {%- endif %}\n {%- set handled_keys = ['type', 'properties'] %}\n {{- render_extra_keys(tool.parameters, handled_keys) }}\n {{- '\\n</parameters>' }}\n {%- set handled_keys = ['type', 'name', 'description', 'parameters'] %}\n {{- render_extra_keys(tool, handled_keys) }}\n {{- '\\n</function>' }}\n {%- endfor %}\n {{- \"\\n</tools>\" }}\n {{- '\\n\\nIf you choose to call a function ONLY reply in the following format with NO suffix:\\n\\n<tool_call>\\n<function=example_function_name>\\n<parameter=example_parameter_1>\\nvalue_1\\n</parameter>\\n<parameter=example_parameter_2>\\nThis is the value for the second parameter\\nthat can span\\nmultiple lines\\n</parameter>\\n</function>\\n</tool_call>\\n\\n<IMPORTANT>\\nReminder:\\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\\n- Required parameters MUST be specified\\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\\n</IMPORTANT>' }}\n{%- endif %}\n{%- if system_message is defined %}\n {{- '<|im_end|>\\n' }}\n{%- else %}\n {%- if tools is iterable and tools | length > 0 %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n{%- endif %}\n{%- for message in loop_messages %}\n {%- if message.role == \"assistant\" and message.tool_calls is defined and message.tool_calls is iterable and message.tool_calls | length > 0 %}\n {{- '<|im_start|>' + message.role }}\n {%- if message.content is defined and message.content is string and message.content | trim | length > 0 %}\n {{- '\\n' + message.content | trim + '\\n' }}\n {%- endif %}\n {%- for tool_call in message.tool_calls %}\n {%- if tool_call.function is defined %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '\\n<tool_call>\\n<function=' + tool_call.name + '>\\n' }}\n {%- if tool_call.arguments is defined %}\n {%- for args_name, args_value in tool_call.arguments|items %}\n {{- '<parameter=' + args_name + '>\\n' }}\n {%- set args_value = args_value if args_value is string else args_value | tojson | safe %}\n {{- args_value }}\n {{- '\\n</parameter>\\n' }}\n {%- endfor %}\n {%- endif %}\n {{- '</function>\\n</tool_call>' }}\n {%- endfor %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"user\" or message.role == \"system\" or message.role == \"assistant\" %}\n {{- '<|im_start|>' + message.role + '\\n' + message.content + '<|im_end|>' + '\\n' }}\n {%- elif message.role == \"tool\" %}\n {%- if loop.previtem and loop.previtem.role != \"tool\" %}\n {{- '<|im_start|>user' }}\n {%- endif %}\n {{- '\\n<tool_response>\\n' }}\n {{- message.content }}\n {{- '\\n</tool_response>' }}\n {%- if not loop.last and loop.nextitem.role != \"tool\" %}\n {{- '<|im_end|>\\n' }}\n {%- elif loop.last %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n {%- else %}\n {{- '<|im_start|>' + message.role + '\\n' + message.content + '<|im_end|>\\n' }}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|im_start|>assistant\\n' }}\n{%- endif %}",
230
- "clean_up_tokenization_spaces": false,
231
- "eos_token": "<|im_end|>",
232
- "errors": "replace",
233
- "model_max_length": 1048576,
234
- "pad_token": "<|endoftext|>",
235
- "split_special_tokens": false,
236
- "tokenizer_class": "Qwen2Tokenizer",
237
- "unk_token": null,
238
- "add_bos_token": false
239
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
veriloop-coder-00001-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:c89934c258f0f5acd3ce2dbf311fa3d2ff41751dda53f89b3597d66074e3377f
3
- size 3999619256
 
 
 
 
veriloop-coder-00002-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:dc31a76af8f4f6167c5ee5c00af334ce23194e21e1f60ca2ce7d5bd6b19542a1
3
- size 3999841784
 
 
 
 
veriloop-coder-00003-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:4b02ecb9cfcb7a9e0cda77f9fc8f0e235aea0097b4809099272b36cb56855a4a
3
- size 3999515584
 
 
 
 
veriloop-coder-00004-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6b4b0da4cb9394fa08ac752f9bda9008b4e6f5b8de7e5291e8704482daff8ccb
3
- size 7999685256
 
 
 
 
veriloop-coder-00005-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:60350080c02054d48a6fd17b325abafd25fa0b86657d37014c75df484c23c7c8
3
- size 3999853216
 
 
 
 
veriloop-coder-00006-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:aa7cded8114dfd22e7bdc43d48b8a32503a66ef1c8d9a6c89f517a04fb4e43f9
3
- size 3999841912
 
 
 
 
veriloop-coder-00007-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:55cbd3e60fb0a1a055043ae996dbce063aac1591d68f149799aca582ef6ea811
3
- size 3999842000
 
 
 
 
veriloop-coder-00008-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0c47f55654ad72a8ac749a6e0fd2c942a8e2d40c3e38d6e4a9d93dc396830f66
3
- size 7999362056
 
 
 
 
veriloop-coder-00009-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:f8ef5fe9f9355d5ad6ed8e880a08baf6a7b06c7a3a05f44456b9c8b7f6f4d767
3
- size 4000181296
 
 
 
 
veriloop-coder-00010-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:d973d1b1605fda5ccd5de4a0ac8d3afc192f43fe6f22ffc20b2eab31035bc41d
3
- size 3999843880
 
 
 
 
veriloop-coder-00011-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:167b69cb389dc18cfbf7eb3a106ad8e2d705552c0a71db7d92b44a8ebc1d2195
3
- size 3999517472
 
 
 
 
veriloop-coder-00012-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6e47317518854d30f4d3162a12b19fee0c1b2b39a75d48e483e10eb6c596c65e
3
- size 8000026728
 
 
 
 
veriloop-coder-00013-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b5e7c3bcdb221eb4a2bb7df03e0d8c56fa7a06a448217d75b63dc077f1627cfc
3
- size 3999517256
 
 
 
 
veriloop-coder-00014-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6e69d4dde8ea6ea8deac8afb435c6de896750a5acc94aae2943991a00afb8644
3
- size 3999843880
 
 
 
 
veriloop-coder-00015-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:737892dff0624b51a7bd06255d7c0e3e97d29ab539af3d43f5a648b0dd4456ab
3
- size 3999843880
 
 
 
 
veriloop-coder-00016-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:82d48d3ba46f7a991f71de8a8913754821568b96ee362c4fe849456425b852bb
3
- size 7999700184
 
 
 
 
veriloop-coder-00017-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:9c53b02373a5a194fd8f7a9165b4535105b1b6dbbafff582bdc3df5ea10c0f5c
3
- size 3999843792
 
 
 
 
veriloop-coder-00018-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:c1f187aa4808d54963bf45cfbe5010f72f3c3d81b6584bceb69fddef82e239e9
3
- size 3999843880
 
 
 
 
veriloop-coder-00019-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:5286e5b13a884128b9708d2292071c3323dbba8cca78c4af353e8cac9f85d6ec
3
- size 3999517464
 
 
 
 
veriloop-coder-00020-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:172a1d0591c51ae14663fe7b25b8b637c17e3e55c136458a6bf25a4a260bb7bc
3
- size 8000026560
 
 
 
 
veriloop-coder-00021-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:709d90cf4589d741c3b8937042322d4c309d78eba1f303b7b284756b7f8fa71f
3
- size 3999517472
 
 
 
 
veriloop-coder-00022-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:01c374c13cef0c83ba569bbc0e1599da0ccc49e7e6d078c9bf24fff66ddef933
3
- size 3999843880
 
 
 
 
veriloop-coder-00023-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:314f820942b2bf4e2934fda07346ad5020132d147d4d182084718c7de3ed70a7
3
- size 3999843984
 
 
 
 
veriloop-coder-00024-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:c3f249fa9c68669ed1f0a54b3e0bb7020612919b7a0ff13d0084e5cfbc1bbefb
3
- size 7999700048
 
 
 
 
veriloop-coder-00025-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:686af3d1671569a4b4412bbad8ef78ba915332f4ae13e6a58d68887c0c2ab3a1
3
- size 3999843880
 
 
 
 
veriloop-coder-00026-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:eb3852b6b899bacc68803b2ba2fa04d955bb34b94ddecb8f72a899bb5eb7d155
3
- size 3999843880
 
 
 
 
veriloop-coder-00027-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:76e735fe4b0974e99754a0cc6b90e17a38066cfd2889415e523638c8dcc94394
3
- size 3999517688
 
 
 
 
veriloop-coder-00028-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b8d90f301aa8e63e6522efc7712107497730e99da12b4a5cd2714ea92ffb6709
3
- size 8000026336
 
 
 
 
veriloop-coder-00029-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:5e09b49eab76341aa5577852cda15f9841ad28bd2f94f141e5ab41a5658aaee5
3
- size 3999517472
 
 
 
 
veriloop-coder-00030-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:19355aff4f4e0c6b3cd737360fced4c5c70ac3508d41baf1c08c821d21479851
3
- size 3999843872
 
 
 
 
veriloop-coder-00031-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:e7deeba55a043cb909602eda1a2f90cb07f0a607b1f7ab237ff49f7874fb75be
3
- size 3999844264
 
 
 
 
veriloop-coder-00032-of-00032.safetensors DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:883708543caeaf44fe9fd6445f77c6e115c1a9b15c3923d2c598997f2d629ec8
3
- size 7365428440
 
 
 
 
vocab.json DELETED
The diff for this file is too large to render. See raw diff