# `vllm_mlx.reasoning.gemma4_parser`

Reasoning parser for Gemma 4 models.

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

## 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.reasoning.gemma4_parser
    options:
      members:
        - _THOUGHT_PREFIX
        - _RESPONSE_MARKER
        - _THOUGHT_MARKER
        - _strip_channel_name
        - _strip_channel_tokens
        - Gemma4ReasoningParser
      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.reasoning.gemma4_parser._strip_channel_name" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser._strip_channel_name</code> · function</summary>

```python
vllm_mlx.reasoning.gemma4_parser._strip_channel_name(text: str, prefix: str) -> str
```

Strip channel name and leading whitespace/newline from text start.

**Parameters**

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

**Returns**

- Type: `str`
- Direct return expressions: `text.lstrip('\n')`

**Exceptions and behavior**

Function `_strip_channel_name` calls `text.startswith`, `len`, `text.lstrip`; returns `text.lstrip('\n')`.
No direct `raise` statement appears in this definition.

[View source #L46-L50](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L46-L50).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser._strip_channel_tokens" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser._strip_channel_tokens</code> · function</summary>

```python
vllm_mlx.reasoning.gemma4_parser._strip_channel_tokens(text: str) -> str
```

Remove all channel special tokens and bare channel names from text.

**Parameters**

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

**Returns**

- Type: `str`
- Direct return expressions: `text.strip()`

**Exceptions and behavior**

Function `_strip_channel_tokens` calls `text.replace`, `text.split`, `line.strip`, `cleaned.append`; returns `text.strip()`.
No direct `raise` statement appears in this definition.

[View source #L53-L82](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L53-L82).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser</code> · class</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser(tokenizer = None)
```

Reasoning parser for Gemma 4 models.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `tokenizer` | `not annotated` | `no` | `None` | Optional positional or keyword input; defaults to `None`. |

**Returns**

- Constructs: `vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser`

**Exceptions and behavior**

Class `Gemma4ReasoningParser` derives from `BaseThinkingReasoningParser` and declares 10 direct member(s).
No direct `raise` statement appears in this definition.

[View source #L85-L386](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L85-L386).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.start_token" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.start_token</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.start_token() -> str
```

Return Gemma's marker for entering the thought channel.

**Parameters**

This callable has no explicit inputs.

**Returns**

- Type: `str`
- Direct return expressions: `'<|channel>'`

**Exceptions and behavior**

Method `Gemma4ReasoningParser.start_token` returns `'<|channel>'`.
No direct `raise` statement appears in this definition.

[View source #L115-L118](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L115-L118).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.end_token" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.end_token</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.end_token() -> str
```

Return Gemma's marker for entering the response channel.

**Parameters**

This callable has no explicit inputs.

**Returns**

- Type: `str`
- Direct return expressions: `'<channel|>'`

**Exceptions and behavior**

Method `Gemma4ReasoningParser.end_token` returns `'<channel|>'`.
No direct `raise` statement appears in this definition.

[View source #L121-L124](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L121-L124).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.__init__" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.__init__</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.__init__(tokenizer = None) -> not annotated
```

Method `Gemma4ReasoningParser.__init__` updates `self._pending`, `self._content_seen`; calls `super().__init__`, `super`.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `tokenizer` | `not annotated` | `no` | `None` | Optional positional or keyword input; defaults to `None`. |

**Returns**

- Type: `not annotated`

**Exceptions and behavior**

Method `Gemma4ReasoningParser.__init__` updates `self._pending`, `self._content_seen`; calls `super().__init__`, `super`.
No direct `raise` statement appears in this definition.

[View source #L126-L133](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L126-L133).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.reset_state" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.reset_state</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.reset_state() -> not annotated
```

Reset base parsing state and buffered Gemma channel markers.

**Parameters**

This callable has no explicit inputs.

**Returns**

- Type: `not annotated`

**Exceptions and behavior**

Method `Gemma4ReasoningParser.reset_state` updates `self._pending`, `self._content_seen`; calls `super().reset_state`, `super`.
No direct `raise` statement appears in this definition.

[View source #L135-L140](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L135-L140).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._trailing_partial_marker_len" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._trailing_partial_marker_len</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._trailing_partial_marker_len(text: str) -> int
```

Return length of trailing substring of `text` that is a proper prefix of any transition marker (<channel|>, <|channel>response, <|channel>).

**Parameters**

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

**Returns**

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

**Exceptions and behavior**

Method `Gemma4ReasoningParser._trailing_partial_marker_len` calls `range`, `min`, `len`, `text.endswith`; returns `max_len`.
No direct `raise` statement appears in this definition.

[View source #L142-L166](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L142-L166).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.finalize_stream" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.finalize_stream</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.finalize_stream() -> DeltaMessage | None
```

Flush any buffered partial marker at the end of stream.

**Parameters**

This callable has no explicit inputs.

**Returns**

- Type: `DeltaMessage | None`
- Direct return expressions: `None`; `DeltaMessage(content=pending)`; `DeltaMessage(reasoning=pending)`

**Exceptions and behavior**

Method `Gemma4ReasoningParser.finalize_stream` updates `self._pending`; calls `DeltaMessage`; has 3 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L168-L183](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L168-L183).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning(model_output: str) -> tuple[str | None, str | None]
```

Extract reasoning from complete output.

**Parameters**

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

**Returns**

- Type: `tuple[str | None, str | None]`
- Direct return expressions: `(reasoning or None, content or None)`; `(reasoning or None, None)`; `(None, model_output)`

**Exceptions and behavior**

Method `Gemma4ReasoningParser.extract_reasoning` calls `text.partition`, `after_start.rpartition`, `_strip_channel_tokens`, `text.count`; has 3 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L185-L233](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L185-L233).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning_streaming" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning_streaming</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning_streaming(previous_text: str, current_text: str, delta_text: str) -> DeltaMessage | None
```

Extract reasoning from streaming delta.

**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. |

**Returns**

- Type: `DeltaMessage | None`
- Direct return expressions: `None`; `self._extract_from_safe_text(safe_previous, safe_current, safe_delta)`

**Exceptions and behavior**

Method `Gemma4ReasoningParser.extract_reasoning_streaming` updates `self._pending`; calls `self._trailing_partial_marker_len`, `len`, `self._extract_from_safe_text`; has 2 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L235-L272](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L235-L272).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._strip_channel_tokens_from_delta" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._strip_channel_tokens_from_delta</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._strip_channel_tokens_from_delta(msg: DeltaMessage | None) -> DeltaMessage | None
```

Strip channel special tokens from content and reasoning in a delta.

**Parameters**

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `msg` | `DeltaMessage \| None` | `yes` | `none` | Required positional or keyword input. |

**Returns**

- Type: `DeltaMessage | None`
- Direct return expressions: `None`; `msg`; `DeltaMessage(reasoning=r or None, content=c or None)`

**Exceptions and behavior**

Method `Gemma4ReasoningParser._strip_channel_tokens_from_delta` calls `c.replace('<channel|>', '').replace`, `c.replace`, `r.replace('<channel|>', '').replace`, `r.replace`; has 3 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L275-L291](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L275-L291).

</details>

<details class="api-contract" id="contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._extract_from_safe_text" markdown="1">
<summary><code>vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._extract_from_safe_text</code> · method</summary>

```python
vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._extract_from_safe_text(previous_text: str, current_text: str, delta_text: str) -> DeltaMessage | None
```

Parse safe (non-buffered) text.

**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. |

**Returns**

- Type: `DeltaMessage | None`
- Direct return expressions: `DeltaMessage(content=delta_text)`; `self._strip_channel_tokens_from_delta(DeltaMessage(content=after_marker))`; `None`; `DeltaMessage(content=after)`; `self._strip_channel_tokens_from_delta(DeltaMessage(content=stripped))`; `self._strip_channel_tokens_from_delta(DeltaMessage(content=delta_text))`; `DeltaMessage(reasoning=r) if r else None`; `DeltaMessage(reasoning=delta_text) if delta_text else None`

**Exceptions and behavior**

Method `Gemma4ReasoningParser._extract_from_safe_text` updates `self._phase`, `self._content_seen`; calls `DeltaMessage`, `current_text.find`, `len`, `after_marker.lstrip`; has 8 explicit return paths.
No direct `raise` statement appears in this definition.

[View source #L293-L386](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L293-L386).

</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 |
| --- | --- | --- | --- | --- |
| [`_strip_channel_name`](#contract-vllm_mlx.reasoning.gemma4_parser._strip_channel_name) | function | `_strip_channel_name(text: str, prefix: str) -> str` | Strip channel name and leading whitespace/newline from text start. | [#L46-L50](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L46-L50) |
| [`_strip_channel_tokens`](#contract-vllm_mlx.reasoning.gemma4_parser._strip_channel_tokens) | function | `_strip_channel_tokens(text: str) -> str` | Remove all channel special tokens and bare channel names from text. | [#L53-L82](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L53-L82) |
| [`Gemma4ReasoningParser`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser) | class | `Gemma4ReasoningParser(tokenizer = None)` | Reasoning parser for Gemma 4 models. | [#L85-L386](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L85-L386) |
| [`Gemma4ReasoningParser.start_token`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.start_token) | method | `Gemma4ReasoningParser.start_token() -> str` | Return Gemma's marker for entering the thought channel. | [#L115-L118](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L115-L118) |
| [`Gemma4ReasoningParser.end_token`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.end_token) | method | `Gemma4ReasoningParser.end_token() -> str` | Return Gemma's marker for entering the response channel. | [#L121-L124](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L121-L124) |
| [`Gemma4ReasoningParser.__init__`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.__init__) | method | `Gemma4ReasoningParser.__init__(tokenizer = None) -> not annotated` | Method `Gemma4ReasoningParser.__init__` updates `self._pending`, `self._content_seen`; calls `super().__init__`, `super`. | [#L126-L133](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L126-L133) |
| [`Gemma4ReasoningParser.reset_state`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.reset_state) | method | `Gemma4ReasoningParser.reset_state() -> not annotated` | Reset base parsing state and buffered Gemma channel markers. | [#L135-L140](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L135-L140) |
| [`Gemma4ReasoningParser._trailing_partial_marker_len`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._trailing_partial_marker_len) | method | `Gemma4ReasoningParser._trailing_partial_marker_len(text: str) -> int` | Return length of trailing substring of `text` that is a proper prefix of any transition marker (<channel\|>, <\|channel>response, <\|channel>). | [#L142-L166](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L142-L166) |
| [`Gemma4ReasoningParser.finalize_stream`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.finalize_stream) | method | `Gemma4ReasoningParser.finalize_stream() -> DeltaMessage \| None` | Flush any buffered partial marker at the end of stream. | [#L168-L183](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L168-L183) |
| [`Gemma4ReasoningParser.extract_reasoning`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning) | method | `Gemma4ReasoningParser.extract_reasoning(model_output: str) -> tuple[str \| None, str \| None]` | Extract reasoning from complete output. | [#L185-L233](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L185-L233) |
| [`Gemma4ReasoningParser.extract_reasoning_streaming`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser.extract_reasoning_streaming) | method | `Gemma4ReasoningParser.extract_reasoning_streaming(previous_text: str, current_text: str, delta_text: str) -> DeltaMessage \| None` | Extract reasoning from streaming delta. | [#L235-L272](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L235-L272) |
| [`Gemma4ReasoningParser._strip_channel_tokens_from_delta`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._strip_channel_tokens_from_delta) | method | `Gemma4ReasoningParser._strip_channel_tokens_from_delta(msg: DeltaMessage \| None) -> DeltaMessage \| None` | Strip channel special tokens from content and reasoning in a delta. | [#L275-L291](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L275-L291) |
| [`Gemma4ReasoningParser._extract_from_safe_text`](#contract-vllm_mlx.reasoning.gemma4_parser.Gemma4ReasoningParser._extract_from_safe_text) | method | `Gemma4ReasoningParser._extract_from_safe_text(previous_text: str, current_text: str, delta_text: str) -> DeltaMessage \| None` | Parse safe (non-buffered) text. | [#L293-L386](https://github.com/waybarrios/vllm-mlx/blob/a69d47912bcb21d8fe04d48f75fa896b620ffcfa/vllm_mlx/reasoning/gemma4_parser.py#L293-L386) |
