Skip to content

vllm_mlx.tool_parsers.gemma4_tool_parser

Gemma 4 tool call parser for vllm-mlx.

View the complete module source at #L1-L513.

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

Gemma 4 tool call parser for vllm-mlx.

Handles Gemma 4's native tool call format: <|tool_call>call:func_name{<|"|>key<|"|>: <|"|>value<|"|>, num: 42}

Gemma 4 uses special tokens instead of JSON: - <|tool_call> / delimit tool call blocks - <|"|> replaces " for string values - Keys are unquoted bare identifiers - Multiple call:name{...} can appear in a single block

Fallback forms (issue #80): under long system prompts + multi-turn + several tools, Gemma 4 frequently abandons the canonical brace form and instead emits its call as plain text in content, using Python-style call syntax:

e4b: <|tool_call>call:radarr_get_movies(search="Dune") e2b: tool_code radarr_get_movies(search="Dune") e2b: tool_code = radarr_get_movies(search="Dune") print(tool_code)

These are parsed by a fallback layer (ast-based) when the canonical parse finds no calls, so the host can still dispatch the tool.

Reference: mlx-lm PR #1105, vllm PR #38837

vllm_mlx.tool_parsers.gemma4_tool_parser.logger module-attribute

logger = logging.getLogger(__name__)

vllm_mlx.tool_parsers.gemma4_tool_parser.TOOL_CALL_START module-attribute

TOOL_CALL_START = '<|tool_call>'

vllm_mlx.tool_parsers.gemma4_tool_parser.TOOL_CALL_END module-attribute

TOOL_CALL_END = '<tool_call|>'

vllm_mlx.tool_parsers.gemma4_tool_parser._PLACEHOLDER_RE module-attribute

_PLACEHOLDER_RE = re.compile('\\x00(\\d+)\\x00')

vllm_mlx.tool_parsers.gemma4_tool_parser._STRING_DELIM_RE module-attribute

_STRING_DELIM_RE = re.compile('<\\|"\\|>(.*?)<\\|"\\|>', re.DOTALL)

vllm_mlx.tool_parsers.gemma4_tool_parser._CALL_PREFIX module-attribute

_CALL_PREFIX = re.compile('call:(\\w+)\\s*\\{')

vllm_mlx.tool_parsers.gemma4_tool_parser._BARE_KEY module-attribute

_BARE_KEY = re.compile('(?<=[{,])\\s*(\\w+)\\s*:')

vllm_mlx.tool_parsers.gemma4_tool_parser._BARE_VALUE module-attribute

_BARE_VALUE = re.compile('(?<=[:\\[,])(\\s*)([A-Za-z_][\\w\\-]*)(?=\\s*[,}\\]])')

vllm_mlx.tool_parsers.gemma4_tool_parser._JSON_LITERALS module-attribute

_JSON_LITERALS = frozenset({'true', 'false', 'null'})

vllm_mlx.tool_parsers.gemma4_tool_parser._MAX_ARG_BLOCK_LEN module-attribute

_MAX_ARG_BLOCK_LEN = 1048576

vllm_mlx.tool_parsers.gemma4_tool_parser._CALL_PAREN_RE module-attribute

_CALL_PAREN_RE = re.compile('call:(\\w+)\\s*\\(')

vllm_mlx.tool_parsers.gemma4_tool_parser._TOOL_CODE_FENCE_RE module-attribute

_TOOL_CODE_FENCE_RE = re.compile('```tool_code\\b[^\\n]*\\n(.*?)```', re.DOTALL)

vllm_mlx.tool_parsers.gemma4_tool_parser._TOOL_CODE_ASSIGN_RE module-attribute

_TOOL_CODE_ASSIGN_RE = re.compile('(?m)^[ \\t]*tool_code\\s*=\\s*(\\w+)\\s*\\(')

vllm_mlx.tool_parsers.gemma4_tool_parser._FALLBACK_MARKER_RE module-attribute

_FALLBACK_MARKER_RE = re.compile('```tool_code\\b|call:\\w+\\s*\\(|tool_code\\s*=\\s*\\w+\\s*\\(')

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser

Gemma4ToolParser(tokenizer: PreTrainedTokenizerBase | None = None)

Bases: ToolParser

Tool call parser for Gemma 4 models.

Parses: <|tool_call>call:func{<|"|>key<|"|>: <|"|>val<|"|>}

Used when --enable-auto-tool-choice --tool-call-parser gemma4 are set.

Source code in vllm_mlx/tool_parsers/abstract_tool_parser.py
def __init__(self, tokenizer: PreTrainedTokenizerBase | None = None):
    """
    Initialize the tool parser.

    Args:
        tokenizer: The tokenizer for the model (optional, some parsers need it)
    """
    self.model_tokenizer = tokenizer
    # State for streaming parsing
    self.current_tool_id: int = -1
    self.prev_tool_call_arr: list[dict] = []

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser.extra_stop_tokens class-attribute instance-attribute

extra_stop_tokens = ['<|tool_response>']

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser.extract_tool_calls

extract_tool_calls(model_output: str, request: dict[str, Any] | None = None) -> ExtractedToolCallInformation

Extract tool calls from a complete Gemma 4 model response.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def extract_tool_calls(
    self, model_output: str, request: dict[str, Any] | None = None
) -> ExtractedToolCallInformation:
    """Extract tool calls from a complete Gemma 4 model response."""
    cleaned = self.strip_think_tags(model_output)

    # 1. Canonical <|"|>-delimited brace form.
    tool_calls, content_before = self._extract_canonical(cleaned)
    if tool_calls:
        return ExtractedToolCallInformation(
            tools_called=True,
            tool_calls=tool_calls,
            content=content_before,
        )

    # 2. Fallback: Gemma often emits the call as plain content using Python
    #    call syntax — `call:fn(...)` or a ```tool_code``` block — instead of
    #    the brace form. Recover those so the host can dispatch. Ref: #80.
    fallback = self._extract_fallback(cleaned)
    if fallback is not None:
        return fallback

    return ExtractedToolCallInformation(
        tools_called=False, tool_calls=[], content=model_output
    )

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._extract_canonical

_extract_canonical(cleaned: str) -> tuple[list[dict[str, Any]], str | None]

Parse the canonical <|tool_call>call:fn{...} form.

Returns (tool_calls, content_before). tool_calls is empty when the canonical markers/braces aren't present.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _extract_canonical(
    self, cleaned: str
) -> tuple[list[dict[str, Any]], str | None]:
    """Parse the canonical <|tool_call>call:fn{...}<tool_call|> form.

    Returns (tool_calls, content_before). tool_calls is empty when the
    canonical markers/braces aren't present.
    """
    start_idx = cleaned.find(TOOL_CALL_START)
    if start_idx == -1:
        return [], None

    content_before = cleaned[:start_idx].strip() or None

    block_start = start_idx + len(TOOL_CALL_START)
    end_idx = cleaned.find(TOOL_CALL_END, block_start)
    if end_idx == -1:
        block = cleaned[block_start:]
    else:
        block = cleaned[block_start:end_idx]

    tool_calls: list[dict[str, Any]] = []

    pos = 0
    while pos < len(block):
        m = _CALL_PREFIX.search(block, pos)
        if not m:
            break

        func_name = m.group(1)
        brace_start = m.end() - 1

        brace_end = _find_balanced_brace(block, brace_start)
        if brace_end == -1:
            pos = m.end()
            continue

        args_raw = block[brace_start : brace_end + 1]
        try:
            args_json = _gemma4_args_to_json(args_raw)
            json.loads(args_json)
            tool_calls.append(
                {
                    "id": generate_tool_id(),
                    "name": func_name,
                    "arguments": args_json,
                }
            )
        except (json.JSONDecodeError, ValueError) as e:
            logger.warning(
                f"Gemma 4 tool parser: failed to parse args for "
                f"call:{func_name}: {e}"
            )

        pos = brace_end + 1

    return tool_calls, content_before

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._extract_fallback

_extract_fallback(cleaned: str) -> ExtractedToolCallInformation | None

Parse the Python-style fallback forms (issue #80).

Handles tool_code blocks (bare fn(...) calls) and the parenthesized call:fn(...) form. Returns None if neither is present.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _extract_fallback(self, cleaned: str) -> ExtractedToolCallInformation | None:
    """Parse the Python-style fallback forms (issue #80).

    Handles ```tool_code``` blocks (bare `fn(...)` calls) and the
    parenthesized `call:fn(...)` form. Returns None if neither is present.
    """
    tool_calls: list[dict[str, Any]] = []
    spans: list[tuple[int, int]] = []

    # ```tool_code``` fenced blocks — may contain one or more bare calls.
    for m in _TOOL_CODE_FENCE_RE.finditer(cleaned):
        for name, args in _parse_calls_from_code(m.group(1)):
            tool_calls.append(
                {
                    "id": generate_tool_id(),
                    "name": name,
                    "arguments": json.dumps(args),
                }
            )
        spans.append((m.start(), m.end()))

    # Parenthesized `call:fn(...)` form (outside any code fence).
    for m in _CALL_PAREN_RE.finditer(cleaned):
        if any(s <= m.start() < e for s, e in spans):
            continue  # already covered by a code-fence span
        paren_open = m.end() - 1
        paren_close = _find_balanced_paren(cleaned, paren_open)
        if paren_close == -1:
            continue
        call_src = m.group(1) + cleaned[paren_open : paren_close + 1]
        parsed = _parse_python_call(call_src)
        if parsed is None:
            continue
        name, args = parsed
        tool_calls.append(
            {
                "id": generate_tool_id(),
                "name": name,
                "arguments": json.dumps(args),
            }
        )
        spans.append((m.start(), paren_close + 1))

    # Unfenced `tool_code = fn(...)` assignment form (e2b, issue #83).
    # Only handle lines NOT already captured by a fence or call: span.
    for m in _TOOL_CODE_ASSIGN_RE.finditer(cleaned):
        if any(s <= m.start() < e for s, e in spans):
            continue  # inside an already-captured block
        paren_open = m.end() - 1
        paren_close = _find_balanced_paren(cleaned, paren_open)
        if paren_close == -1:
            continue
        call_src = m.group(1) + cleaned[paren_open : paren_close + 1]
        parsed = _parse_python_call(call_src)
        if parsed is None:
            continue
        name, args = parsed
        tool_calls.append(
            {
                "id": generate_tool_id(),
                "name": name,
                "arguments": json.dumps(args),
            }
        )
        spans.append((m.start(), paren_close + 1))

    if not tool_calls:
        return None

    content = _strip_spans(cleaned, spans)
    # Drop any stray Gemma tool-call markers left in the surrounding text.
    content = content.replace(TOOL_CALL_START, "").replace(TOOL_CALL_END, "")
    # Drop residual `print(tool_code)` lines left by the unfenced assignment
    # convention — they are bookkeeping noise, not reply content.
    content = re.sub(r"(?m)^[ \t]*print\([^\n]*\)[ \t]*$", "", content)
    content = content.strip() or None

    return ExtractedToolCallInformation(
        tools_called=True, tool_calls=tool_calls, content=content
    )

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._format_streaming

_format_streaming(result: ExtractedToolCallInformation) -> dict[str, Any]

Render extracted tool calls into the streaming delta shape.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _format_streaming(self, result: ExtractedToolCallInformation) -> dict[str, Any]:
    """Render extracted tool calls into the streaming delta shape."""
    return {
        "tool_calls": [
            {
                "index": i,
                "id": tc["id"],
                "type": "function",
                "function": {
                    "name": tc["name"],
                    "arguments": tc["arguments"],
                },
            }
            for i, tc in enumerate(result.tool_calls)
        ]
    }

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser.extract_tool_calls_streaming

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 Gemma 4 model output.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def extract_tool_calls_streaming(
    self,
    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 Gemma 4 model output."""
    has_canonical = TOOL_CALL_START in current_text
    has_fallback = bool(_FALLBACK_MARKER_RE.search(current_text))

    if not has_canonical and not has_fallback:
        return {"content": delta_text}

    # Canonical brace form: emit when the end delimiter arrives in this delta.
    if has_canonical and TOOL_CALL_END in delta_text:
        result = self.extract_tool_calls(current_text)
        if result.tools_called:
            return self._format_streaming(result)
        return None

    # Fallback forms (`call:fn(...)` / ```tool_code```) have no end delimiter.
    # Emit once, on the delta that first makes the call parseable.
    if has_fallback and not self.extract_tool_calls(previous_text).tools_called:
        result = self.extract_tool_calls(current_text)
        if result.tools_called:
            return self._format_streaming(result)

    return None

vllm_mlx.tool_parsers.gemma4_tool_parser._find_balanced_brace

_find_balanced_brace(text: str, start: int) -> int

Find the index of the closing } that balances the { at start.

Before counting braces, <|"|>-delimited strings are conceptually opaque -- we skip over <|"|>...<|"|> regions so that braces inside string values (e.g. code snippets) don't affect depth counting.

Parameters:

  • text (str) –

    The string to search (may contain <|"|> tokens)

  • start (int) –

    Index of the opening {

Returns:

  • int

    Index of the matching } in the ORIGINAL text, or -1 if not found

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _find_balanced_brace(text: str, start: int) -> int:
    """Find the index of the closing } that balances the { at `start`.

    Before counting braces, <|"|>-delimited strings are conceptually opaque --
    we skip over <|"|>...<|"|> regions so that braces inside string values
    (e.g. code snippets) don't affect depth counting.

    Args:
        text: The string to search (may contain <|"|> tokens)
        start: Index of the opening {

    Returns:
        Index of the matching } in the ORIGINAL text, or -1 if not found
    """
    if len(text) - start > _MAX_ARG_BLOCK_LEN:
        return -1

    depth = 0
    i = start
    in_string = False
    while i < len(text):
        if text.startswith('<|"|>', i):
            in_string = not in_string
            i += 5
            continue
        if not in_string:
            if text[i] == "{":
                depth += 1
            elif text[i] == "}":
                depth -= 1
                if depth == 0:
                    return i
        i += 1
    return -1

vllm_mlx.tool_parsers.gemma4_tool_parser._find_balanced_paren

_find_balanced_paren(text: str, start: int) -> int

Find the index of the closing ) that balances the ( at start.

Python string literals ('...'/"...") are treated as opaque so that parens inside string argument values don't affect depth counting.

Returns the index of the matching ) in text, or -1 if not found.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _find_balanced_paren(text: str, start: int) -> int:
    """Find the index of the closing ) that balances the ( at `start`.

    Python string literals ('...'/"...") are treated as opaque so that parens
    inside string argument values don't affect depth counting.

    Returns the index of the matching ) in `text`, or -1 if not found.
    """
    if len(text) - start > _MAX_ARG_BLOCK_LEN:
        return -1

    depth = 0
    i = start
    quote: str | None = None
    while i < len(text):
        c = text[i]
        if quote is not None:
            if c == "\\":
                i += 2
                continue
            if c == quote:
                quote = None
        elif c in ("'", '"'):
            quote = c
        elif c == "(":
            depth += 1
        elif c == ")":
            depth -= 1
            if depth == 0:
                return i
        i += 1
    return -1

vllm_mlx.tool_parsers.gemma4_tool_parser._quote_bare_value

_quote_bare_value(m: Match) -> str

Substitution callback for _BARE_VALUE — quotes bare identifiers that are not JSON literals (true/false/null).

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _quote_bare_value(m: re.Match) -> str:
    """Substitution callback for _BARE_VALUE — quotes bare identifiers that
    are not JSON literals (true/false/null)."""
    ws, word = m.group(1), m.group(2)
    if word in _JSON_LITERALS:
        return m.group(0)
    return f'{ws}"{word}"'

vllm_mlx.tool_parsers.gemma4_tool_parser._gemma4_args_to_json

_gemma4_args_to_json(text: str) -> str

Convert Gemma 4 tool call args to valid JSON.

Four-step conversion (ORDER MATTERS): 1. Extract <|"|>-delimited strings into numbered \x00N\x00 placeholders. This protects string contents from step 2's bare-key quoting -- without this, a string value like "key: value" would be corrupted. 2. Quote bare keys (word: -> "word":) now that strings are safe. 3. Quote bare string VALUES that the template emitted without <|"|> wrappers. Happens with nullable/enum schemas where the STRING branch of the template isn't taken. 4. Restore placeholders as properly JSON-escaped strings via json.dumps(). Uses a single re.sub pass (O(len(text))) instead of per-placeholder replace.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _gemma4_args_to_json(text: str) -> str:
    """Convert Gemma 4 tool call args to valid JSON.

    Four-step conversion (ORDER MATTERS):
    1. Extract <|"|>-delimited strings into numbered \\x00N\\x00 placeholders.
       This protects string contents from step 2's bare-key quoting -- without
       this, a string value like "key: value" would be corrupted.
    2. Quote bare keys (word: -> "word":) now that strings are safe.
    3. Quote bare string VALUES that the template emitted without <|"|>
       wrappers. Happens with nullable/enum schemas where the STRING branch
       of the template isn't taken.
    4. Restore placeholders as properly JSON-escaped strings via json.dumps().
       Uses a single re.sub pass (O(len(text))) instead of per-placeholder replace.
    """
    strings: list[str] = []

    def _capture(m: re.Match) -> str:
        strings.append(m.group(1))
        return f"\x00{len(strings) - 1}\x00"

    # Step 1: Extract <|"|>-delimited strings
    text = _STRING_DELIM_RE.sub(_capture, text)

    # Step 2: Quote bare keys
    text = _BARE_KEY.sub(r'"\1":', text)

    # Step 3: Quote bare string values (nullable / enum-without-type schemas)
    text = _BARE_VALUE.sub(_quote_bare_value, text)

    # Step 4: Restore captured strings as properly escaped JSON strings
    def _restore(m: re.Match) -> str:
        idx = int(m.group(1))
        return json.dumps(strings[idx]) if idx < len(strings) else m.group(0)

    text = _PLACEHOLDER_RE.sub(_restore, text)

    return text

vllm_mlx.tool_parsers.gemma4_tool_parser._call_node_to_tool

_call_node_to_tool(call: Call) -> tuple[str, dict[str, Any]] | None

Map a Python ast.Call node to (function_name, kwargs_dict).

Only keyword arguments are mapped (Gemma emits its tool calls as kwargs); positional args are ignored because the parameter names aren't recoverable. Returns None if the name or any argument value isn't a plain literal.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _call_node_to_tool(call: ast.Call) -> tuple[str, dict[str, Any]] | None:
    """Map a Python `ast.Call` node to (function_name, kwargs_dict).

    Only keyword arguments are mapped (Gemma emits its tool calls as kwargs);
    positional args are ignored because the parameter names aren't recoverable.
    Returns None if the name or any argument value isn't a plain literal.
    """
    func = call.func
    if isinstance(func, ast.Name):
        name = func.id
    elif isinstance(func, ast.Attribute):
        name = func.attr  # e.g. module.fn -> fn
    else:
        return None

    args: dict[str, Any] = {}
    for kw in call.keywords:
        if kw.arg is None:  # **kwargs splat — can't represent
            continue
        try:
            args[kw.arg] = ast.literal_eval(kw.value)
        except (ValueError, SyntaxError):
            return None
    return name, args

vllm_mlx.tool_parsers.gemma4_tool_parser._parse_python_call

_parse_python_call(src: str) -> tuple[str, dict[str, Any]] | None

Parse a single fn(...) Python call expression into (name, kwargs).

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _parse_python_call(src: str) -> tuple[str, dict[str, Any]] | None:
    """Parse a single `fn(...)` Python call expression into (name, kwargs)."""
    try:
        node = ast.parse(src.strip(), mode="eval")
    except SyntaxError:
        return None
    if not isinstance(node.body, ast.Call):
        return None
    return _call_node_to_tool(node.body)

vllm_mlx.tool_parsers.gemma4_tool_parser._parse_calls_from_code

_parse_calls_from_code(code: str) -> list[tuple[str, dict[str, Any]]]

Parse every top-level fn(...) call statement in a code-fence body.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _parse_calls_from_code(code: str) -> list[tuple[str, dict[str, Any]]]:
    """Parse every top-level `fn(...)` call statement in a code-fence body."""
    results: list[tuple[str, dict[str, Any]]] = []
    try:
        module = ast.parse(textwrap.dedent(code).strip(), mode="exec")
    except SyntaxError:
        return results
    for stmt in module.body:
        if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Call):
            parsed = _call_node_to_tool(stmt.value)
            if parsed is not None:
                results.append(parsed)
    return results

vllm_mlx.tool_parsers.gemma4_tool_parser._strip_spans

_strip_spans(text: str, spans: list[tuple[int, int]]) -> str

Remove the given [start, end) spans from text (handles overlaps).

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def _strip_spans(text: str, spans: list[tuple[int, int]]) -> str:
    """Remove the given [start, end) spans from `text` (handles overlaps)."""
    if not spans:
        return text
    out: list[str] = []
    last = 0
    for start, end in sorted(spans):
        if start < last:  # overlapping / contained — extend the cut
            last = max(last, end)
            continue
        out.append(text[last:start])
        last = end
    out.append(text[last:])
    return "".join(out)

vllm_mlx.tool_parsers.gemma4_tool_parser.generate_tool_id

generate_tool_id() -> str

Generate a unique tool call ID.

Source code in vllm_mlx/tool_parsers/gemma4_tool_parser.py
def generate_tool_id() -> str:
    """Generate a unique tool call ID."""
    return f"call_{uuid.uuid4().hex[:8]}"

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.

vllm_mlx.tool_parsers.gemma4_tool_parser._find_balanced_brace · function
vllm_mlx.tool_parsers.gemma4_tool_parser._find_balanced_brace(text: str, start: int) -> int

Find the index of the closing } that balances the { at start.

Parameters

Name Type Required Default Description
text str yes none The string to search (may contain <|"|> tokens)
start int yes none Index of the opening {

Returns

  • Type: int
  • Direct return expressions: -1; i

Exceptions and behavior

Function _find_balanced_brace calls len, text.startswith; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L92-L125.

vllm_mlx.tool_parsers.gemma4_tool_parser._find_balanced_paren · function
vllm_mlx.tool_parsers.gemma4_tool_parser._find_balanced_paren(text: str, start: int) -> int

Find the index of the closing ) that balances the ( at start.

Parameters

Name Type Required Default Description
text str yes none Required positional or keyword input.
start int yes none Required positional or keyword input.

Returns

  • Type: int
  • Direct return expressions: -1; i

Exceptions and behavior

Function _find_balanced_paren calls len; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L128-L159.

vllm_mlx.tool_parsers.gemma4_tool_parser._quote_bare_value · function
vllm_mlx.tool_parsers.gemma4_tool_parser._quote_bare_value(m: re.Match) -> str

Substitution callback for _BARE_VALUE — quotes bare identifiers that are not JSON literals (true/false/null).

Parameters

Name Type Required Default Description
m re.Match yes none Required positional or keyword input.

Returns

  • Type: str
  • Direct return expressions: m.group(0); f'{ws}"{word}"'

Exceptions and behavior

Function _quote_bare_value calls m.group; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L162-L168.

vllm_mlx.tool_parsers.gemma4_tool_parser._gemma4_args_to_json · function
vllm_mlx.tool_parsers.gemma4_tool_parser._gemma4_args_to_json(text: str) -> str

Convert Gemma 4 tool call args to valid JSON.

Parameters

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

Returns

  • Type: str
  • Direct return expressions: text

Exceptions and behavior

Function _gemma4_args_to_json calls _STRING_DELIM_RE.sub, _BARE_KEY.sub, _BARE_VALUE.sub, _PLACEHOLDER_RE.sub; returns text. No direct raise statement appears in this definition.

View source #L171-L207.

vllm_mlx.tool_parsers.gemma4_tool_parser._gemma4_args_to_json._capture · nested function
vllm_mlx.tool_parsers.gemma4_tool_parser._gemma4_args_to_json._capture(m: re.Match) -> str

Nested Function _gemma4_args_to_json._capture calls strings.append, m.group, len; returns f'\x00{len(strings) - 1}\x00'.

Parameters

Name Type Required Default Description
m re.Match yes none Required positional or keyword input.

Returns

  • Type: str
  • Direct return expressions: f'\x00{len(strings) - 1}\x00'

Exceptions and behavior

Nested Function _gemma4_args_to_json._capture calls strings.append, m.group, len; returns f'\x00{len(strings) - 1}\x00'. No direct raise statement appears in this definition.

View source #L187-L189.

vllm_mlx.tool_parsers.gemma4_tool_parser._gemma4_args_to_json._restore · nested function
vllm_mlx.tool_parsers.gemma4_tool_parser._gemma4_args_to_json._restore(m: re.Match) -> str

Nested Function _gemma4_args_to_json._restore calls int, m.group, len, json.dumps; returns json.dumps(strings[idx]) if idx < len(strings) else m.group(0).

Parameters

Name Type Required Default Description
m re.Match yes none Required positional or keyword input.

Returns

  • Type: str
  • Direct return expressions: json.dumps(strings[idx]) if idx < len(strings) else m.group(0)

Exceptions and behavior

Nested Function _gemma4_args_to_json._restore calls int, m.group, len, json.dumps; returns json.dumps(strings[idx]) if idx < len(strings) else m.group(0). No direct raise statement appears in this definition.

View source #L201-L203.

vllm_mlx.tool_parsers.gemma4_tool_parser._call_node_to_tool · function
vllm_mlx.tool_parsers.gemma4_tool_parser._call_node_to_tool(call: ast.Call) -> tuple[str, dict[str, Any]] | None

Map a Python ast.Call node to (function_name, kwargs_dict).

Parameters

Name Type Required Default Description
call ast.Call yes none Required positional or keyword input.

Returns

  • Type: tuple[str, dict[str, Any]] | None
  • Direct return expressions: None; (name, args)

Exceptions and behavior

Function _call_node_to_tool calls isinstance, ast.literal_eval; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L210-L233.

vllm_mlx.tool_parsers.gemma4_tool_parser._parse_python_call · function
vllm_mlx.tool_parsers.gemma4_tool_parser._parse_python_call(src: str) -> tuple[str, dict[str, Any]] | None

Parse a single fn(...) Python call expression into (name, kwargs).

Parameters

Name Type Required Default Description
src str yes none Required positional or keyword input.

Returns

  • Type: tuple[str, dict[str, Any]] | None
  • Direct return expressions: None; _call_node_to_tool(node.body)

Exceptions and behavior

Function _parse_python_call calls ast.parse, src.strip, isinstance, _call_node_to_tool; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L236-L244.

vllm_mlx.tool_parsers.gemma4_tool_parser._parse_calls_from_code · function
vllm_mlx.tool_parsers.gemma4_tool_parser._parse_calls_from_code(code: str) -> list[tuple[str, dict[str, Any]]]

Parse every top-level fn(...) call statement in a code-fence body.

Parameters

Name Type Required Default Description
code str yes none Required positional or keyword input.

Returns

  • Type: list[tuple[str, dict[str, Any]]]
  • Direct return expressions: results

Exceptions and behavior

Function _parse_calls_from_code calls ast.parse, textwrap.dedent(code).strip, textwrap.dedent, isinstance; returns results. No direct raise statement appears in this definition.

View source #L247-L259.

vllm_mlx.tool_parsers.gemma4_tool_parser._strip_spans · function
vllm_mlx.tool_parsers.gemma4_tool_parser._strip_spans(text: str, spans: list[tuple[int, int]]) -> str

Remove the given [start, end) spans from text (handles overlaps).

Parameters

Name Type Required Default Description
text str yes none Required positional or keyword input.
spans list[tuple[int, int]] yes none Required positional or keyword input.

Returns

  • Type: str
  • Direct return expressions: text; ''.join(out)

Exceptions and behavior

Function _strip_spans calls sorted, max, out.append, ''.join; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L262-L275.

vllm_mlx.tool_parsers.gemma4_tool_parser.generate_tool_id · function
vllm_mlx.tool_parsers.gemma4_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 #L278-L280.

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser · class
vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser()

Tool call parser for Gemma 4 models.

Parameters

This callable has no explicit inputs.

Returns

  • Constructs: vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser

Exceptions and behavior

Class Gemma4ToolParser derives from ToolParser and declares 5 direct member(s). No direct raise statement appears in this definition.

View source #L284-L513.

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser.extract_tool_calls · method
vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser.extract_tool_calls(model_output: str, request: dict[str, Any] | None = None) -> ExtractedToolCallInformation

Extract tool calls from a complete Gemma 4 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=content_before); fallback; ExtractedToolCallInformation(tools_called=False, tool_calls=[], content=model_output)

Exceptions and behavior

Method Gemma4ToolParser.extract_tool_calls calls self.strip_think_tags, self._extract_canonical, ExtractedToolCallInformation, self._extract_fallback; has 3 explicit return paths. No direct raise statement appears in this definition.

View source #L300-L324.

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._extract_canonical · method
vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._extract_canonical(cleaned: str) -> tuple[list[dict[str, Any]], str | None]

Parse the canonical <|tool_call>call:fn{...} form.

Parameters

Name Type Required Default Description
cleaned str yes none Required positional or keyword input.

Returns

  • Type: tuple[list[dict[str, Any]], str | None]
  • Direct return expressions: ([], None); (tool_calls, content_before)

Exceptions and behavior

Method Gemma4ToolParser._extract_canonical calls cleaned.find, cleaned[:start_idx].strip, len, _CALL_PREFIX.search; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L326-L382.

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._extract_fallback · method
vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._extract_fallback(cleaned: str) -> ExtractedToolCallInformation | None

Parse the Python-style fallback forms (issue #80).

Parameters

Name Type Required Default Description
cleaned str yes none Required positional or keyword input.

Returns

  • Type: ExtractedToolCallInformation | None
  • Direct return expressions: None; ExtractedToolCallInformation(tools_called=True, tool_calls=tool_calls, content=content)

Exceptions and behavior

Method Gemma4ToolParser._extract_fallback calls _TOOL_CODE_FENCE_RE.finditer, _parse_calls_from_code, m.group, tool_calls.append; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L384-L463.

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._format_streaming · method
vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser._format_streaming(result: ExtractedToolCallInformation) -> dict[str, Any]

Render extracted tool calls into the streaming delta shape.

Parameters

Name Type Required Default Description
result ExtractedToolCallInformation yes none Required positional or keyword input.

Returns

  • Type: dict[str, Any]
  • Direct return expressions: {'tool_calls': [{'index': i, 'id': tc['id'], 'type': 'function', 'function': {'name': tc['name'], 'arguments': tc['argu…

Exceptions and behavior

Method Gemma4ToolParser._format_streaming calls enumerate; returns {'tool_calls': [{'index': i, 'id': tc['id'], 'type': 'function', 'function': {'name': tc['name'], 'arguments': tc['argu…. No direct raise statement appears in this definition.

View source #L465-L480.

vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser.extract_tool_calls_streaming · method
vllm_mlx.tool_parsers.gemma4_tool_parser.Gemma4ToolParser.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 Gemma 4 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}; self._format_streaming(result); None

Exceptions and behavior

Method Gemma4ToolParser.extract_tool_calls_streaming calls bool, _FALLBACK_MARKER_RE.search, self.extract_tool_calls, self._format_streaming; has 3 explicit return paths. No direct raise statement appears in this definition.

View source #L482-L513.

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
_find_balanced_brace function _find_balanced_brace(text: str, start: int) -> int Find the index of the closing } that balances the { at start. #L92-L125
_find_balanced_paren function _find_balanced_paren(text: str, start: int) -> int Find the index of the closing ) that balances the ( at start. #L128-L159
_quote_bare_value function _quote_bare_value(m: re.Match) -> str Substitution callback for _BARE_VALUE — quotes bare identifiers that are not JSON literals (true/false/null). #L162-L168
_gemma4_args_to_json function _gemma4_args_to_json(text: str) -> str Convert Gemma 4 tool call args to valid JSON. #L171-L207
_gemma4_args_to_json._capture nested function _gemma4_args_to_json._capture(m: re.Match) -> str Nested Function _gemma4_args_to_json._capture calls strings.append, m.group, len; returns f'\x00{len(strings) - 1}\x00'. #L187-L189
_gemma4_args_to_json._restore nested function _gemma4_args_to_json._restore(m: re.Match) -> str Nested Function _gemma4_args_to_json._restore calls int, m.group, len, json.dumps; returns json.dumps(strings[idx]) if idx < len(strings) else m.group(0). #L201-L203
_call_node_to_tool function _call_node_to_tool(call: ast.Call) -> tuple[str, dict[str, Any]] \| None Map a Python ast.Call node to (function_name, kwargs_dict). #L210-L233
_parse_python_call function _parse_python_call(src: str) -> tuple[str, dict[str, Any]] \| None Parse a single fn(...) Python call expression into (name, kwargs). #L236-L244
_parse_calls_from_code function _parse_calls_from_code(code: str) -> list[tuple[str, dict[str, Any]]] Parse every top-level fn(...) call statement in a code-fence body. #L247-L259
_strip_spans function _strip_spans(text: str, spans: list[tuple[int, int]]) -> str Remove the given [start, end) spans from text (handles overlaps). #L262-L275
generate_tool_id function generate_tool_id() -> str Generate a unique tool call ID. #L278-L280
Gemma4ToolParser class Gemma4ToolParser() Tool call parser for Gemma 4 models. #L284-L513
Gemma4ToolParser.extract_tool_calls method Gemma4ToolParser.extract_tool_calls(model_output: str, request: dict[str, Any] \| None = None) -> ExtractedToolCallInformation Extract tool calls from a complete Gemma 4 model response. #L300-L324
Gemma4ToolParser._extract_canonical method Gemma4ToolParser._extract_canonical(cleaned: str) -> tuple[list[dict[str, Any]], str \| None] Parse the canonical <|tool_call>call:fn{...} form. #L326-L382
Gemma4ToolParser._extract_fallback method Gemma4ToolParser._extract_fallback(cleaned: str) -> ExtractedToolCallInformation \| None Parse the Python-style fallback forms (issue #80). #L384-L463
Gemma4ToolParser._format_streaming method Gemma4ToolParser._format_streaming(result: ExtractedToolCallInformation) -> dict[str, Any] Render extracted tool calls into the streaming delta shape. #L465-L480
Gemma4ToolParser.extract_tool_calls_streaming method Gemma4ToolParser.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 Gemma 4 model output. #L482-L513