Skip to content

fix(tool_calling): recover naked <function=...> calls emitted by Qwen3-Coder#844

Open
mrtkrcm wants to merge 2 commits intojundot:mainfrom
mrtkrcm:fix/tool-calling-naked-function
Open

fix(tool_calling): recover naked <function=...> calls emitted by Qwen3-Coder#844
mrtkrcm wants to merge 2 commits intojundot:mainfrom
mrtkrcm:fix/tool-calling-naked-function

Conversation

@mrtkrcm
Copy link
Copy Markdown
Contributor

@mrtkrcm mrtkrcm commented Apr 18, 2026

Summary

Recover Qwen-style naked <function=...>...</function> tool calls when the model omits the outer <tool_call> wrapper.

Changes

  • Add a fallback parser for naked function blocks.
  • Parse <parameter=...> values with JSON coercion when possible.
  • Strip recovered function markup and stray tool wrapper fragments from content.
  • Add regression coverage for single and multiple naked function calls.

Local validation

Built and installed from this branch into /Applications/oMLX.app (0.3.8.dev2), with port 8801 owned by the visible app process.

  • Focused tests: 201 passed, 12 deselected for tests/test_tool_calling.py, tests/integration/test_e2e_streaming.py, and tests/test_admin_profiles_api.py.
  • Live model: Qwen3-Coder-30B-A3B-Instruct-4bit forced read_file; response returned structured tool_calls and no raw <function=...> markup.
  • Benchmark smoke row: Qwen3-Coder-30B-A3B-Instruct-4bit load 2.8s, canary 25.1 tok/s, code 23.7 tok/s, tool OK in 2.3s.
  • Control model: Ternary-Bonsai-8B-mlx-2bit returned ready; benchmark tool OK in 0.6s.

Note: benchmark host was not clean; preflight saw active desktop/client load, so throughput is smoke data only.

Test Plan

  • uv run pytest tests/test_tool_calling.py -q
  • python3 -m py_compile omlx/api/tool_calling.py tests/test_tool_calling.py

@mrtkrcm mrtkrcm force-pushed the fix/tool-calling-naked-function branch from 42765dc to 6907419 Compare April 18, 2026 15:21
@mrtkrcm mrtkrcm force-pushed the fix/tool-calling-naked-function branch from 6907419 to e1bc50f Compare April 25, 2026 13:59
Murat Karacam and others added 2 commits April 28, 2026 19:01
…3-Coder

Qwen3-Coder-30B (and other Qwen-Coder variants) sometimes emits
<function=name>...</function> without the outer <tool_call> wrapper
that mlx_lm.tool_parsers.qwen3_coder expects. Without this branch
the structured call leaks into content with an empty tool_calls[],
producing a visible score regression on tool-routing benchmarks.

Add a fallback after the XML-wrapper branch that recognises the
naked envelope + embedded <parameter=key>val</parameter> pairs,
rebuilds a proper ToolCall, and strips residual tags from content.

Kern quick-suite: 1/9 -> 5/9 for Qwen3-Coder-30B.
@mrtkrcm mrtkrcm force-pushed the fix/tool-calling-naked-function branch from e1bc50f to 8a9cc38 Compare April 28, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant