#145 / vLLM #39056 are STREAMING-only tool-call bugs, and our gates were
structurally blind to them: benchlocal-cli runs every pack non-streaming
(benchlocal-cli#68, closed wrong-layer), and verify-full had check_tools
(non-streaming) and check_streaming (no tools) as SEPARATE checks — the bug
lives in their untested intersection (tools × streaming × thinking-on). That's
how the MTP-streaming drop (#39598, un-mitigated since Genesis retired) shipped
silently into the dual composes.
- scripts/verify-full.sh: new [6/9] check_streaming_tools — stream:true + tools
+ tool_choice=auto + enable_thinking=true, reassembles the SSE deltas, and
asserts delta.tool_calls (get_weather) + finish_reason=tool_calls + no
<tool_call> leak into delta.content. Uses tool_choice=auto (the clean path on
v0.22.0); hard-fails on the leak signature (the #145/#39056 class). NB:
tool_choice=required + MTP is a known-open drop (#39598) — the check notes it
but uses auto so it's a green gate on shipped composes. Gated by SKIP_TOOLS.
Renumbered the suite 8 -> 9 checks. Live-validated: vllm/dual all 9 pass.
- scripts/stream-toolcall-probe.py: the deep-sweep instrument behind the #400
investigation (thinking-on, multi-prompt, auto+required, SSE reassembly,
PASS/DROP/OTHER classification, exit-1 on any DROP). It's what proved
qwen3_coder == qwen3_xml and isolated the #39598 MTP-gating. Run it twice
(control vs candidate) for a streaming A/B.
- scripts/tests/test-stream-toolcall-probe.sh: offline mock-SSE gate (clean +
#145-drop modes) — no GPU needed.
Full suite green (test-compose-registry-disk fails pre-existing on an unrelated
untracked model dir).
Co-authored-by: noonghunna <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>