feat(vllm-pr41800): vendor truncate_prompt_tokens overlay across all pre-fix engines (closes #139)

Resolves the HTTP 400 reported by opencode (and other agentic clients
sending `truncate_prompt_tokens` on chat-completion requests) on every
compose currently routing through `vllm-nightly-mtp` (01d4d1ad),
`vllm-nightly-dflash` (e47c98ef), or `vllm-nightly-full` (e47c98ef).
All three SHAs predate vLLM PR #41800 (merged 2026-05-06 at d5b31c95)
which adds `truncate_prompt_tokens` to `get_max_tokens()`'s signature.

This commit:

* `models/qwen3.6-27b/vllm/patches/vllm-pr41800-truncate-prompt-tokens/`
  - install.sh: Python anchor-based in-place patcher for
    `vllm/entrypoints/utils.py`. Two anchored edits:
      1. signature: insert `truncate_prompt_tokens: int | None = None,`
      2. body: insert truncation-aware `input_length = min(...)` block
         before the existing `if max_model_len < input_length:` check
    Idempotent via a sentinel comment. Post-patch AST-validated.
    Includes upstream-fix detection: if the function signature already
    accepts `truncate_prompt_tokens` (e.g. on a post-#41800 nightly),
    install.sh no-ops cleanly so composes routing through
    vllm-nightly-clean (bf610c2f, post-fix) still boot.
  - README.md: full context, wiring pattern, smoke-test command,
    drop-trigger criteria.

* Wired into 18 affected composes (every compose with
  `Engine-profile: vllm-nightly-(mtp|dflash|full)` header) plus
  `qwen3.6-27b/dual/docker-compose.yml` (the latter is on
  vllm-nightly-clean post-engine-pin-split commit a67af0f and the
  overlay no-ops there cleanly — harmless safety wiring):

  Qwen 3.6 27B:
    dual: docker-compose.yml, dflash.yml, dflash-noviz.yml, int8.yml,
          tq3-mtp.yml, tq3-mtp-genesis.yml, tq3-nomtp.yml, turbo.yml
    single: docker-compose.yml, bounded-thinking.yml, long-text.yml,
            long-text-no-mtp.yml, long-vision.yml
    multi4: dflash.yml

  Gemma 4 31B:
    dual: awq.yml, dflash.yml, dflash-int8.yml, int8.yml, int8-tq3.yml

* NVLink-variant stubs (nvlink.yml, nvlink-turbo.yml,
  nvlink-dflash.yml, nvlink-dflash-noviz.yml) inherit the overlay
  automatically via `extends:` from the base compose — no separate
  patch needed.

Smoke-tested on `vllm/vllm-openai:nightly-01d4d1ad...` (Sander's
Genesis PROD pin): get_max_tokens signature lacks truncate_prompt_tokens
before install, has it after. Idempotency confirmed (second install =
no-op). Post-fix no-op confirmed on `bf610c2f` (vllm-nightly-clean).
All 18 wired composes parse as valid YAML; test-profiles-compat.sh ok.

For Pattern-B composes (Gemma 4 31B set, plus tq3-mtp-genesis.yml)
that have a `if/then/else` exec-vllm-serve branching for NVLink mode,
the install line is placed BEFORE the `if` block at the script's base
indent so it runs regardless of the NVLink path taken.

Tracking: #139 (root cause + plan); triggered by #138 (SEVENID's
opencode failure on dual-dflash-noviz). Drop when each affected engine
pin bumps past commit d5b31c95.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
noonghunna
2026-05-15 22:18:09 +05:00
committed by noonghunna
co-authored by Claude Opus 4.7
parent e49c939748
commit 1d7aad112c
21 changed files with 326 additions and 0 deletions
@@ -78,6 +78,10 @@ services:
- ../../cache/triton_awq:/root/.triton/cache
# NVLink auto-detection — runs inside container at boot.
- ../../../../../scripts/detect_nvlink.sh:/etc/club3090/detect_nvlink.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
environment:
- NVIDIA_VISIBLE_DEVICES=${ESTATE_GPUS:-${NVIDIA_VISIBLE_DEVICES:-all}}
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-}
@@ -112,6 +116,7 @@ services:
pip install --quiet --upgrade transformers==5.8.0
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
bash /etc/club3090/install-pr41800.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
exec vllm serve "$@"
else
@@ -145,6 +145,10 @@ services:
# NVLink auto-detection — runs inside container at boot.
- ../../../../../scripts/detect_nvlink.sh:/etc/club3090/detect_nvlink.sh:ro
# --------------------------------------------------------------------
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
environment:
- NVIDIA_VISIBLE_DEVICES=${ESTATE_GPUS:-${NVIDIA_VISIBLE_DEVICES:-all}}
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-}
@@ -177,6 +181,7 @@ services:
pip install --quiet --upgrade transformers==5.8.0
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
bash /etc/club3090/install-pr41800.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
exec vllm serve "$@"
else
@@ -110,6 +110,10 @@ services:
# NVLink auto-detection — runs inside container at boot.
- ../../../../../scripts/detect_nvlink.sh:/etc/club3090/detect_nvlink.sh:ro
# --------------------------------------------------------------------
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
environment:
- NVIDIA_VISIBLE_DEVICES=${ESTATE_GPUS:-${NVIDIA_VISIBLE_DEVICES:-all}}
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-}
@@ -142,6 +146,7 @@ services:
pip install --quiet --upgrade transformers==5.8.0
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
bash /etc/club3090/install-pr41800.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
exec vllm serve "$@"
else
@@ -220,6 +220,10 @@ services:
# NVLink auto-detection — runs inside container at boot.
- ../../../../../scripts/detect_nvlink.sh:/etc/club3090/detect_nvlink.sh:ro
# --------------------------------------------------------------------
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
environment:
- NVIDIA_VISIBLE_DEVICES=${ESTATE_GPUS:-${NVIDIA_VISIBLE_DEVICES:-all}}
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-}
@@ -253,6 +257,7 @@ services:
echo "[club3090-tq3] Launching vllm serve..." >&2
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
bash /etc/club3090/install-pr41800.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
exec vllm serve "$@"
else
@@ -124,6 +124,10 @@ services:
# NVLink auto-detection — runs inside container at boot.
- ../../../../../scripts/detect_nvlink.sh:/etc/club3090/detect_nvlink.sh:ro
# --------------------------------------------------------------------
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
environment:
- NVIDIA_VISIBLE_DEVICES=${ESTATE_GPUS:-${NVIDIA_VISIBLE_DEVICES:-all}}
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-}
@@ -151,6 +155,7 @@ services:
- |
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
bash /etc/club3090/install-pr41800.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
exec vllm serve "$@"
else
@@ -75,6 +75,9 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode
# HTTP 400 on get_max_tokens(). See patches/vllm-pr41800.../README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -114,6 +117,7 @@ services:
# hardware where graph capture causes OOM or instability (e.g. WSL2).
# Install PR #35936 overlay before vllm imports (drop when upstream lands).
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
@@ -99,6 +99,9 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode
# HTTP 400 on get_max_tokens(). See patches/vllm-pr41800.../README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -138,6 +141,7 @@ services:
# hardware where graph capture causes OOM or instability (e.g. WSL2).
# Install PR #35936 overlay before vllm imports (drop when upstream lands).
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
@@ -87,6 +87,9 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode
# HTTP 400 on get_max_tokens(). See patches/vllm-pr41800.../README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -128,6 +131,7 @@ services:
# stability. See docs/HARDWARE.md "Note for WSL2 / Windows users".
# Install PR #35936 overlay before vllm imports (drop when upstream lands).
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
# NVLink auto-detection (sets NCCL env vars, _NVLINK_ENABLED).
source /etc/club3090/detect_nvlink.sh
if [ "${_NVLINK_ENABLED:-0}" = "1" ]; then
@@ -57,6 +57,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -88,6 +92,7 @@ services:
- |
# Install PR #35936 overlay before vllm imports (drop when upstream lands).
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
exec vllm serve ${VLLM_ENFORCE_EAGER:+--enforce-eager} "$@"
- --
command:
@@ -105,6 +105,10 @@ services:
# See docs/UPSTREAM.md "Community templates / model assets" + the row at
# https://huggingface.co/froggeric/Qwen-Fixed-Chat-Templates
- ../../patches/froggeric-chat-template/chat_template.jinja:/etc/qwen-froggeric-chat-template.jinja:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
environment:
- NVIDIA_VISIBLE_DEVICES=${ESTATE_GPUS:-${NVIDIA_VISIBLE_DEVICES:-all}}
- HUGGING_FACE_HUB_TOKEN=${HF_TOKEN:-}
@@ -246,6 +250,7 @@ services:
# v7.72.2 (P78 + PN34). Mounts and invocations dropped 2026-05-05.
# VLLM_ENFORCE_EAGER=1 in compose/.env disables CUDA graphs — use on
# hardware where Cliff 2 GDN activation spikes occur at runtime.
bash /etc/club3090/install-pr41800.sh
exec vllm serve ${VLLM_ENFORCE_EAGER:+--enforce-eager} "$@"
- --
command:
@@ -104,6 +104,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -136,6 +140,7 @@ services:
- |
# Install PR #35936 overlay before vllm imports (drop when upstream lands).
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
exec vllm serve ${VLLM_ENFORCE_EAGER:+--enforce-eager} "$@"
- --
command:
@@ -88,6 +88,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -119,6 +123,7 @@ services:
- |
# Install PR #35936 overlay before vllm imports (drop when upstream lands).
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
exec vllm serve ${VLLM_ENFORCE_EAGER:+--enforce-eager} "$@"
- --
command:
@@ -84,6 +84,9 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode
# HTTP 400 on get_max_tokens(). See patches/vllm-pr41800.../README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -222,6 +225,7 @@ services:
# Install PR #35936 overlay BEFORE Genesis runs so Genesis can write hooks
# to chat_completion/serving.py without hitting RO-mount errors.
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
python3 -m vllm._genesis.patches.apply_all
# Tool-parser deferred-commit fix for qwen3coder SSE-silence bug (issue #72).
# Drops out when vllm-project/vllm lands the upstream fix.
@@ -92,6 +92,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -128,6 +132,7 @@ services:
# hardware where graph capture causes OOM or instability (e.g. WSL2).
# Install PR #35936 overlay before vllm imports (drop when upstream lands).
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
exec vllm serve ${VLLM_ENFORCE_EAGER:+--enforce-eager} "$@"
- --
command:
@@ -161,6 +161,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -290,6 +294,7 @@ services:
# Install PR #35936 overlay BEFORE Genesis runs so Genesis can write hooks
# to chat_completion/serving.py without hitting RO-mount errors.
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
python3 -m vllm._genesis.patches.apply_all
# Tool-parser deferred-commit fix for qwen3coder SSE-silence bug (issue #72).
# Drops out when vllm-project/vllm lands the upstream fix.
@@ -132,6 +132,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -221,6 +225,7 @@ services:
# Install PR #35936 overlay BEFORE Genesis runs so Genesis can write hooks
# to chat_completion/serving.py without hitting RO-mount errors.
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
python3 -m vllm._genesis.patches.apply_all
# Tool-parser deferred-commit fix for qwen3coder SSE-silence bug (issue #72).
# Drops out when vllm-project/vllm lands the upstream fix.
@@ -149,6 +149,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -315,6 +319,7 @@ services:
# Install PR #35936 overlay BEFORE Genesis runs so Genesis can write hooks
# to chat_completion/serving.py without hitting RO-mount errors.
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
python3 -m vllm._genesis.patches.apply_all
# Tool-parser deferred-commit fix for qwen3coder SSE-silence bug (issue #72).
# Drops out when vllm-project/vllm lands the upstream fix.
@@ -159,6 +159,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -332,6 +336,7 @@ services:
# Install PR #35936 overlay BEFORE Genesis runs so Genesis can write hooks
# to chat_completion/serving.py without hitting RO-mount errors.
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
python3 -m vllm._genesis.patches.apply_all
# Tool-parser deferred-commit fix for qwen3coder SSE-silence bug (issue #72).
# Drops out when vllm-project/vllm lands the upstream fix.
@@ -127,6 +127,10 @@ services:
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/chat_completion/serving.py:/etc/club3090/pr35936-chat-completion-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/vllm/entrypoints/openai/engine/serving.py:/etc/club3090/pr35936-engine-serving.py:ro
- ../../patches/vllm-pr35936-required-fallback/install.sh:/etc/club3090/install-pr35936.sh:ro
# vLLM PR #41800 (truncate_prompt_tokens kwarg) overlay — fixes opencode-style
# HTTP 400 on get_max_tokens(). No-op on post-fix nightlies.
# See ../../patches/vllm-pr41800-truncate-prompt-tokens/README.md.
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
# froggeric/Qwen-Fixed-Chat-Templates qwen3.6 — fixes 7 default-template
# bugs (empty <think></think> spam, </thinking> hallucination, unclosed
# think before tool call, no-user-query crash, developer role, etc.).
@@ -256,6 +260,7 @@ services:
# Install PR #35936 overlay BEFORE Genesis runs so Genesis can write hooks
# to chat_completion/serving.py without hitting RO-mount errors.
bash /etc/club3090/install-pr35936.sh
bash /etc/club3090/install-pr41800.sh
python3 -m vllm._genesis.patches.apply_all
# Tool-parser deferred-commit fix for qwen3coder SSE-silence bug (issue #72).
# Drops out when vllm-project/vllm lands the upstream fix.
@@ -0,0 +1,94 @@
# vLLM PR #41800 overlay — `truncate_prompt_tokens` kwarg on `get_max_tokens`
## What this fixes
Agentic clients (opencode, codex-cli, and similar IDE/agent runtimes) send `truncate_prompt_tokens` on chat-completion requests. Pre-[vLLM PR #41800](https://github.com/vllm-project/vllm/pull/41800), `vllm.entrypoints.utils.get_max_tokens()` doesn't accept that kwarg — and the kwarg propagates from the request handler down into the function call — so requests fail with:
```
HTTP 400: {"error":{"message":"get_max_tokens() got an unexpected keyword argument 'truncate_prompt_tokens'",...}}
```
The fix is upstream PR #41800 (merged 2026-05-06 at commit `d5b31c95`). It adds the kwarg to the function signature and a small body block that clamps `input_length` to `min(input_length, truncate_prompt_tokens or max_model_len)` before the existing length check.
## When this overlay is needed
This overlay is needed on engines pinned to vLLM SHAs that **predate `d5b31c95`**:
| Engine | Pinned SHA | Pre-fix? |
|---|---|---|
| `vllm-nightly-mtp` | `01d4d1ad` (2026-05-04) | ✅ needs overlay |
| `vllm-nightly-dflash` | `e47c98ef` (~2026-05-05) | ✅ needs overlay (20 commits behind d5b31c95) |
| `vllm-nightly-full` | `e47c98ef` | ✅ needs overlay |
| `vllm-nightly-clean` | `bf610c2f` (2026-05-15) | ❌ already includes fix |
If a compose routes through `vllm-nightly-clean`, the overlay is unnecessary — the function signature already accepts the kwarg upstream.
## How the overlay works
`install.sh` is a Python anchor-based in-place patcher. It does two surgical edits to the in-container `/usr/local/lib/python3.12/dist-packages/vllm/entrypoints/utils.py`:
1. **Signature**: adds `truncate_prompt_tokens: int | None = None,` to `get_max_tokens`'s signature, anchored to the existing `override_max_tokens: int | None = None,` line.
2. **Body**: inserts a 6-line truncation-aware `input_length` adjustment block before the existing `if max_model_len < input_length:` check, anchored to that line.
Each insertion carries a sentinel comment (`# PATCH: truncate_prompt_tokens kwarg (club3090/pr41800)`) so re-running the install on an already-patched file is a no-op. Post-patch the file is AST-validated before write.
Why anchor-based and not full-file replacement: the PR diff is +14 / -0 across a 200-line file — replacing the full file would shadow other upstream changes in `utils.py`. Anchor-based insertion is drift-resistant to unrelated upstream movement.
## Composes that wire this overlay in (as of v0.7.3 ship)
* `models/qwen3.6-27b/vllm/compose/dual/docker-compose.yml` (gpu-mode `27b`)
* `models/qwen3.6-27b/vllm/compose/dual/turbo.yml` (gpu-mode `27b-turbo`)
* `models/qwen3.6-27b/vllm/compose/dual/dflash.yml` (gpu-mode `27b-dflash`)
* `models/qwen3.6-27b/vllm/compose/dual/dflash-noviz.yml` (gpu-mode `27b-dflash-noviz`, the compose from issue #138)
## How to add this overlay to another affected compose
In any compose that routes through `vllm-nightly-mtp` / `vllm-nightly-dflash` / `vllm-nightly-full`, add:
1. **Volume mount** in the `volumes:` block:
```yaml
- ../../patches/vllm-pr41800-truncate-prompt-tokens/install.sh:/etc/club3090/install-pr41800.sh:ro
```
2. **Install line** in the `entrypoint:` bash script, before `exec vllm serve`:
```bash
bash /etc/club3090/install-pr41800.sh
```
Run `bash install.sh` (the file in this directory) standalone to test against a transient vLLM container before wiring into a compose. See the smoke test in the next section.
## Smoke test
```bash
docker run --rm --entrypoint /bin/bash \
-v $(pwd)/install.sh:/install.sh:ro \
vllm/vllm-openai:nightly-01d4d1ad375dc5854779c593eee093bcebb0cada \
-c '
python3 -c "from vllm.entrypoints.utils import get_max_tokens; import inspect; print(inspect.signature(get_max_tokens))"
bash /install.sh
python3 -c "from vllm.entrypoints.utils import get_max_tokens; import inspect; print(inspect.signature(get_max_tokens))"
'
```
Expected: signature lacks `truncate_prompt_tokens` BEFORE install, has it AFTER. Verified on `01d4d1ad` (2026-05-15).
## When to drop this overlay
When **both** are true:
1. PR #41800 has merged upstream (it has — 2026-05-06 at `d5b31c95`)
2. The engine's pinned nightly SHA bumps past `d5b31c95`
For the Genesis-anchored engines, the bump happens with Sander's next Genesis release cycle (v7.73.x). For `vllm-nightly-dflash` and `vllm-nightly-full`, the bump happens when their respective overlays (PR #41703 DFlash, PR #42102 INT8 PTH KV) are re-validated against a newer nightly.
Track in `docs/UPSTREAM.md`.
## Source
- vLLM PR #41800: https://github.com/vllm-project/vllm/pull/41800
- Merged commit: `d5b31c95`
- Tracking issue: noonghunna/club-3090#139
- Triggered by: noonghunna/club-3090#138 (SEVENID's opencode boot failure)
- Patch summary: +7 lines in `vllm/entrypoints/utils.py` (the actual fix) + 5 call-site forward-compat additions in other files (we skip those — the signature fix alone unblocks all known TypeError reports)
@@ -0,0 +1,141 @@
#!/usr/bin/env bash
# Install vLLM PR #41800 — `truncate_prompt_tokens` kwarg on get_max_tokens.
#
# WHY THIS OVERLAY EXISTS:
# opencode (and other agentic clients like codex-cli) send `truncate_prompt_tokens`
# on chat-completion requests. Pre-#41800, vLLM's `get_max_tokens()` doesn't
# accept that kwarg — and somewhere upstream of the function the kwarg gets
# unpacked into the call — so requests fail with:
# HTTP 400: get_max_tokens() got an unexpected keyword argument 'truncate_prompt_tokens'
#
# PR: https://github.com/vllm-project/vllm/pull/41800
# Merged: 2026-05-06 at commit d5b31c95
# Affected pins on master:
# - vllm-nightly-mtp (01d4d1ad, 2026-05-04) — pre-fix
# - vllm-nightly-dflash (e47c98ef) — pre-fix
# - vllm-nightly-full (e47c98ef) — pre-fix
# (vllm-nightly-clean at bf610c2f is POST-fix; doesn't need the overlay)
#
# Tracking issue: #139 (noonghunna/club-3090)
# Triggered by: #138 — SEVENID's opencode boot failure on dual-dflash-noviz.
#
# WHY A PYTHON ANCHOR-BASED PATCHER:
# The PR is +7 lines in `vllm/entrypoints/utils.py` (the actual fix) plus a
# handful of forward-compat call-site additions in 5 other files. The
# function-signature change in utils.py is the ONLY thing required to fix
# the TypeError — once `get_max_tokens` accepts the kwarg, requests stop
# crashing. The call-site changes are nice-to-have semantic completeness
# (actually applying the truncation), so we patch those too via anchors.
#
# Idempotent: each anchor checks for a sentinel marker before inserting.
set -euo pipefail
# Container's vLLM install path. Override via env if vLLM moves.
SITE_PACKAGES="${CLUB3090_PR41800_SITE_PACKAGES:-/usr/local/lib/python3.12/dist-packages}"
UTILS_PY="$SITE_PACKAGES/vllm/entrypoints/utils.py"
if [ ! -f "$UTILS_PY" ]; then
echo "[club3090/pr41800] ERROR: $UTILS_PY not found; aborting overlay install" >&2
exit 1
fi
python3 - <<'PY'
import os
import re
import sys
site_packages = os.environ.get(
"CLUB3090_PR41800_SITE_PACKAGES",
"/usr/local/lib/python3.12/dist-packages",
)
utils_py = f"{site_packages}/vllm/entrypoints/utils.py"
SENTINEL = "# PATCH: truncate_prompt_tokens kwarg (club3090/pr41800)"
# Function signature update: add `truncate_prompt_tokens: int | None = None,`
# as a kwarg on `get_max_tokens`. Anchor on the existing line that closes
# the signature (`override_max_tokens: int | None = None,` line right before `) -> int:`).
SIGNATURE_ANCHOR_RE = re.compile(
r'^(?P<indent>[ \t]+)override_max_tokens: int \| None = None,\n(?P<close>[ \t]*\) -> int:)',
re.MULTILINE,
)
SIGNATURE_INSERT = ''' override_max_tokens: int | None = None,
truncate_prompt_tokens: int | None = None, # PATCH: truncate_prompt_tokens kwarg (club3090/pr41800)
) -> int:'''
# Body update: insert truncation-aware input_length adjustment BEFORE the
# `if max_model_len < input_length:` check. Anchor on that line.
BODY_ANCHOR_RE = re.compile(
r'^(?P<indent>[ \t]+)if max_model_len < input_length:',
re.MULTILINE,
)
BODY_INSERT = ''' # PATCH: truncate_prompt_tokens kwarg (club3090/pr41800)
if truncate_prompt_tokens is not None:
limit = truncate_prompt_tokens
input_length = min(
input_length,
max_model_len if limit == -1 else limit,
)
if max_model_len < input_length:'''
with open(utils_py, "r", encoding="utf-8") as f:
src = f.read()
if SENTINEL in src:
print(f"[club3090/pr41800] {utils_py}: sentinel present, patch already applied; no-op", file=sys.stderr)
sys.exit(0)
# Upstream-fix detection: if the function signature already accepts the kwarg
# (i.e. the engine pinned a post-#41800 nightly), the overlay is unnecessary
# and should no-op gracefully so composes that mount it on a post-fix image
# (e.g. via vllm-nightly-clean) still boot cleanly.
UPSTREAM_RE = re.compile(
r'def get_max_tokens\([^)]*truncate_prompt_tokens\b',
re.DOTALL,
)
if UPSTREAM_RE.search(src):
print(f"[club3090/pr41800] {utils_py}: upstream get_max_tokens() already accepts truncate_prompt_tokens; no-op", file=sys.stderr)
sys.exit(0)
# Apply signature patch first (so the function accepts the kwarg)
m = SIGNATURE_ANCHOR_RE.search(src)
if not m:
print(
f"[club3090/pr41800] ERROR: signature anchor "
f"'override_max_tokens: int | None = None, ... ) -> int:' not found in {utils_py}. "
f"vLLM nightly may have changed entrypoints/utils.py — overlay needs re-anchoring.",
file=sys.stderr,
)
sys.exit(1)
src = SIGNATURE_ANCHOR_RE.sub(SIGNATURE_INSERT, src, count=1)
# Apply body patch
m = BODY_ANCHOR_RE.search(src)
if not m:
print(
f"[club3090/pr41800] ERROR: body anchor 'if max_model_len < input_length:' not found in {utils_py} "
f"after signature patch. vLLM nightly diverged unexpectedly — overlay needs re-anchoring.",
file=sys.stderr,
)
sys.exit(1)
src = BODY_ANCHOR_RE.sub(BODY_INSERT, src, count=1)
with open(utils_py, "w", encoding="utf-8") as f:
f.write(src)
# Quick validity check
import ast
try:
ast.parse(src)
except SyntaxError as e:
print(f"[club3090/pr41800] ERROR: post-patch utils.py is not valid Python: {e}", file=sys.stderr)
sys.exit(1)
print(f"[club3090/pr41800] {utils_py}: signature + body patches applied (truncate_prompt_tokens kwarg)", file=sys.stderr)
PY
echo "[club3090/pr41800] install complete" >&2