# `vllm_mlx.tool_parsers.qwen_tool_parser`

Qwen tool call parser for vllm-mlx.

[View the complete module source at #L1-L351](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L1-L351).

## API details

Each callable below includes its exact signature, type annotations, inputs, defaults, return contract, documented exceptions, implementation source, and parsed docstring sections when the source provides them.

::: vllm_mlx.tool_parsers.qwen_tool_parser
    options:
      members:
        - _parse_param_value
        - generate_tool_id
        - QwenToolParser
      filters: []
      show_if_no_docstring: true

## Complete contract reference

Expand any definition for its exact inputs, annotations, defaults, return contract, directly raised exceptions, source-grounded behavior, and immutable line link. This section includes private and nested definitions that ordinary API generators omit.

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser._parse_param_value" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser._parse_param_value</code> · function</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser._parse_param_value(val: str) -> Any
```

Parse a parameter value, handling JSON literals and plain strings.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `val` | `str` | `yes` | `none` | Required positional or keyword input. |

**Returns**

- Type: `Any`
- Direct return expressions: `json.loads(val)`; `val`; `python_val`

**Exceptions and behavior**

Function `_parse_param_value` calls `json.loads`, `ast.literal_eval`, `isinstance`, `sorted`; has 3 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L25-L40](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L25-L40).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.generate_tool_id" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.generate_tool_id</code> · function</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.generate_tool_id() -> str
```

Generate a unique tool call ID.

**Parameters**

This callable has no explicit inputs.

**Returns**

- Type: `str`
- Direct return expressions: `f'call_{uuid.uuid4().hex[:8]}'`

**Exceptions and behavior**

Function `generate_tool_id` calls `uuid.uuid4`; returns `f'call_{uuid.uuid4().hex[:8]}'`.
No direct `raise` statement appears in this definition.

[View source #L43-L45](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L43-L45).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser</code> · class</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser()
```

Tool call parser for Qwen models.

**Parameters**

This callable has no explicit inputs.

**Returns**

- Constructs: `vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser`

**Exceptions and behavior**

Class `QwenToolParser` derives from `ToolParser` and declares 6 direct member(s).
No direct `raise` statement appears in this definition.

[View source #L49-L351](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L49-L351).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls</code> · method</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls(model_output: str, request: dict[str, Any] | None = None) -> ExtractedToolCallInformation
```

Extract tool calls from a complete Qwen model response.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `model_output` | `str` | `yes` | `none` | Required positional or keyword input. |
| `request` | `dict[str, Any] \| None` | `no` | `None` | Optional positional or keyword input; defaults to `None`. |

**Returns**

- Type: `ExtractedToolCallInformation`
- Direct return expressions: `ExtractedToolCallInformation(tools_called=True, tool_calls=tool_calls, content=cleaned_text if cleaned_text else None)`; `ExtractedToolCallInformation(tools_called=False, tool_calls=[], content=stripped)`

**Exceptions and behavior**

Method `QwenToolParser.extract_tool_calls` calls `self.strip_think_tags`, `self.BRACKET_PATTERN.findall`, `json.loads`, `tool_calls.append`; has 2 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L78-L197](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L78-L197).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._strip_unclosed_markup" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._strip_unclosed_markup</code> · method</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._strip_unclosed_markup(text: str) -> str
```

Strip a trailing unclosed tool-call marker (truncated output).

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `text` | `str` | `yes` | `none` | Required positional or keyword input. |

**Returns**

- Type: `str`
- Direct return expressions: `text`; `text[:earliest].rstrip()`

**Exceptions and behavior**

Method `QwenToolParser._strip_unclosed_markup` calls `len`, `text.rfind`, `min`, `text[:earliest].rstrip`; has 2 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L200-L228](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L200-L228).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._has_partial_marker" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._has_partial_marker</code> · method</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._has_partial_marker(text: str) -> bool
```

Check if text ends with an incomplete tool call marker prefix.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `text` | `str` | `yes` | `none` | Required positional or keyword input. |

**Returns**

- Type: `bool`
- Direct return expressions: `self._get_partial_marker_len(text) > 0`

**Exceptions and behavior**

Method `QwenToolParser._has_partial_marker` calls `self._get_partial_marker_len`; returns `self._get_partial_marker_len(text) > 0`.
No direct `raise` statement appears in this definition.

[View source #L235-L237](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L235-L237).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._get_partial_marker_len" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._get_partial_marker_len</code> · method</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._get_partial_marker_len(text: str) -> int
```

Return the length of a partial tool call marker suffix at end of text.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `text` | `str` | `yes` | `none` | Required positional or keyword input. |

**Returns**

- Type: `int`
- Direct return expressions: `best`

**Exceptions and behavior**

Method `QwenToolParser._get_partial_marker_len` calls `range`, `len`, `tail.endswith`; returns `best`.
No direct `raise` statement appears in this definition.

[View source #L239-L248](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L239-L248).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._was_buffering" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._was_buffering</code> · method</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._was_buffering(previous_text: str) -> bool
```

Check if the previous call was buffering a partial marker.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `previous_text` | `str` | `yes` | `none` | Required positional or keyword input. |

**Returns**

- Type: `bool`
- Direct return expressions: `self._has_partial_marker(previous_text)`

**Exceptions and behavior**

Method `QwenToolParser._was_buffering` calls `self._has_partial_marker`; returns `self._has_partial_marker(previous_text)`.
No direct `raise` statement appears in this definition.

[View source #L250-L252](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L250-L252).

</details>

<details class="api-contract" id="contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls_streaming" markdown="1">
<summary><code>vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls_streaming</code> · method</summary>

```python
vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls_streaming(previous_text: str, current_text: str, delta_text: str, previous_token_ids: Sequence[int] | None = None, current_token_ids: Sequence[int] | None = None, delta_token_ids: Sequence[int] | None = None, request: dict[str, Any] | None = None) -> dict[str, Any] | None
```

Extract tool calls from streaming Qwen model output.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `previous_text` | `str` | `yes` | `none` | Required positional or keyword input. |
| `current_text` | `str` | `yes` | `none` | Required positional or keyword input. |
| `delta_text` | `str` | `yes` | `none` | Required positional or keyword input. |
| `previous_token_ids` | `Sequence[int] \| None` | `no` | `None` | Optional positional or keyword input; defaults to `None`. |
| `current_token_ids` | `Sequence[int] \| None` | `no` | `None` | Optional positional or keyword input; defaults to `None`. |
| `delta_token_ids` | `Sequence[int] \| None` | `no` | `None` | Optional positional or keyword input; defaults to `None`. |
| `request` | `dict[str, Any] \| None` | `no` | `None` | Optional positional or keyword input; defaults to `None`. |

**Returns**

- Type: `dict[str, Any] | None`
- Direct return expressions: `{'content': delta_text[:safe_chars]}`; `None`; `{'content': prefix + delta_text}`; `{'content': delta_text}`; `{'tool_calls': [{'index': prev_func_close + i, 'id': tc['id'], 'type': 'function', 'function': {'name': tc['name'], 'ar…`; `{'tool_calls': [{'index': i, 'id': tc['id'], 'type': 'function', 'function': {'name': tc['name'], 'arguments': tc['argu…`

**Exceptions and behavior**

Method `QwenToolParser.extract_tool_calls_streaming` calls `self._has_partial_marker`, `self._get_partial_marker_len`, `len`, `self._was_buffering`; has 6 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L254-L351](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L254-L351).

</details>

## Complete symbol map

This map also includes private definitions and nested helpers. The signature column exposes every explicit input even when an internal helper has no dedicated parameter prose.

| Symbol | Kind | Signature and inputs | What it does | Source |
| --- | --- | --- | --- | --- |
| [`_parse_param_value`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser._parse_param_value) | function | `_parse_param_value(val: str) -> Any` | Parse a parameter value, handling JSON literals and plain strings. | [#L25-L40](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L25-L40) |
| [`generate_tool_id`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.generate_tool_id) | function | `generate_tool_id() -> str` | Generate a unique tool call ID. | [#L43-L45](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L43-L45) |
| [`QwenToolParser`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser) | class | `QwenToolParser()` | Tool call parser for Qwen models. | [#L49-L351](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L49-L351) |
| [`QwenToolParser.extract_tool_calls`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls) | method | `QwenToolParser.extract_tool_calls(model_output: str, request: dict[str, Any] \| None = None) -> ExtractedToolCallInformation` | Extract tool calls from a complete Qwen model response. | [#L78-L197](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L78-L197) |
| [`QwenToolParser._strip_unclosed_markup`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._strip_unclosed_markup) | method | `QwenToolParser._strip_unclosed_markup(text: str) -> str` | Strip a trailing unclosed tool-call marker (truncated output). | [#L200-L228](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L200-L228) |
| [`QwenToolParser._has_partial_marker`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._has_partial_marker) | method | `QwenToolParser._has_partial_marker(text: str) -> bool` | Check if text ends with an incomplete tool call marker prefix. | [#L235-L237](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L235-L237) |
| [`QwenToolParser._get_partial_marker_len`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._get_partial_marker_len) | method | `QwenToolParser._get_partial_marker_len(text: str) -> int` | Return the length of a partial tool call marker suffix at end of text. | [#L239-L248](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L239-L248) |
| [`QwenToolParser._was_buffering`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser._was_buffering) | method | `QwenToolParser._was_buffering(previous_text: str) -> bool` | Check if the previous call was buffering a partial marker. | [#L250-L252](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L250-L252) |
| [`QwenToolParser.extract_tool_calls_streaming`](#contract-vllm_mlx.tool_parsers.qwen_tool_parser.QwenToolParser.extract_tool_calls_streaming) | method | `QwenToolParser.extract_tool_calls_streaming(previous_text: str, current_text: str, delta_text: str, previous_token_ids: Sequence[int] \| None = None, current_token_ids: Sequence[int] \| None = None, delta_token_ids: Sequence[int] \| None = None, request: dict[str, Any] \| None = None) -> dict[str, Any] \| None` | Extract tool calls from streaming Qwen model output. | [#L254-L351](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/tool_parsers/qwen_tool_parser.py#L254-L351) |
