[Bugfix][Frontend] Honor request_id and X-Request-Id in chat and completions render (#61236)

Signed-off-by: Martin Hickey <martin.hickey@ie.ibm.com>
This commit is contained in:
Martin Hickey
2026-10-12 19:17:12 +00:00
committed by GitHub
parent d0948f754d
commit 08582942d8
3 changed files with 83 additions and 8 deletions
@@ -367,6 +367,74 @@ async def test_completion_render_multiple_prompts(client):
assert prompt["request_id"].startswith("cmpl-")
CHAT_BODY = {
"model": MODEL_NAME,
"messages": [{"role": "user", "content": "Hello"}],
}
@pytest.mark.asyncio
async def test_chat_render_honors_body_request_id(client):
response = await client.post(
"/v1/chat/completions/render", json={**CHAT_BODY, "request_id": "abc"}
)
assert response.status_code == 200
assert response.json()["request_id"] == "chatcmpl-abc"
@pytest.mark.asyncio
async def test_chat_render_header_request_id_wins(client):
response = await client.post(
"/v1/chat/completions/render",
json={**CHAT_BODY, "request_id": "abc"},
headers={"X-Request-Id": "hdr"},
)
assert response.status_code == 200
assert response.json()["request_id"] == "chatcmpl-hdr"
@pytest.mark.asyncio
async def test_chat_render_generates_unique_request_ids(client):
ids = set()
for _ in range(2):
response = await client.post("/v1/chat/completions/render", json=CHAT_BODY)
assert response.status_code == 200
request_id = response.json()["request_id"]
assert request_id.startswith("chatcmpl-")
ids.add(request_id)
assert len(ids) == 2
@pytest.mark.asyncio
async def test_completion_render_request_id_single_prompt(client):
response = await client.post(
"/v1/completions/render",
json={"model": MODEL_NAME, "prompt": "Hello world", "request_id": "abc"},
)
assert response.status_code == 200
assert [r["request_id"] for r in response.json()] == ["cmpl-abc"]
@pytest.mark.asyncio
async def test_completion_render_request_id_multiple_prompts(client):
response = await client.post(
"/v1/completions/render",
json={
"model": MODEL_NAME,
"prompt": ["Hello world", "Goodbye world"],
"request_id": "abc",
},
headers={"X-Request-Id": "hdr"},
)
assert response.status_code == 200
assert [r["request_id"] for r in response.json()] == ["cmpl-hdr-0", "cmpl-hdr-1"]
@pytest.mark.asyncio
async def test_chat_completion_render_multi_turn(client):
"""Test chat completion render with multi-turn conversation."""
@@ -43,7 +43,7 @@ async def render_chat_completion(request: ChatCompletionRequest, raw_request: Re
"The model does not support Chat Completions Render API"
)
result = await handler.render_chat_request(request)
result = await handler.render_chat_request(request, raw_request)
if isinstance(result, ErrorResponse):
return JSONResponse(content=result.model_dump(), status_code=result.error.code)
@@ -67,7 +67,7 @@ async def render_messages(request: AnthropicMessagesRequest, raw_request: Reques
if handler is None:
raise NotImplementedError("The model does not support Messages Render API")
result = await handler.render_messages_request(request)
result = await handler.render_messages_request(request, raw_request)
if isinstance(result, ErrorResponse):
return JSONResponse(content=result.model_dump(), status_code=result.error.code)
@@ -90,7 +90,7 @@ async def render_completion(request: CompletionRequest, raw_request: Request):
if handler is None:
raise NotImplementedError("The model does not support Completions Render API")
result = await handler.render_completion_request(request)
result = await handler.render_completion_request(request, raw_request)
if isinstance(result, ErrorResponse):
return JSONResponse(content=result.model_dump(), status_code=result.error.code)
+12 -5
View File
@@ -2,6 +2,8 @@
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from typing import TYPE_CHECKING
from fastapi import Request
from vllm.entrypoints.anthropic.protocol import AnthropicMessagesRequest
from vllm.entrypoints.anthropic.serving import AnthropicServingMessages
from vllm.entrypoints.openai.chat_completion.protocol import ChatCompletionRequest
@@ -31,7 +33,6 @@ from vllm.renderers.inputs.preprocess import (
extract_prompt_len,
)
from vllm.renderers.online_renderer import OnlineRenderer
from vllm.utils import random_uuid
logger = init_logger(__name__)
@@ -77,6 +78,7 @@ class ServingRender(BaseServing):
async def render_chat_request(
self,
request: ChatCompletionRequest,
raw_request: Request | None = None,
) -> GenerateRequest | ErrorResponse:
"""Validate the model and preprocess a chat completion request.
@@ -139,7 +141,9 @@ class ServingRender(BaseServing):
)
reasoning_ended = request.resolve_reasoning_ended(parser, token_ids)
request_id = f"chatcmpl-{random_uuid()}"
request_id = (
f"chatcmpl-{self._base_request_id(raw_request, request.request_id)}"
)
return GenerateRequest(
request_id=request_id,
@@ -161,6 +165,7 @@ class ServingRender(BaseServing):
async def render_messages_request(
self,
request: AnthropicMessagesRequest,
raw_request: Request | None = None,
) -> GenerateRequest | ErrorResponse:
"""Validate the model and preprocess an Anthropic Messages request.
@@ -172,11 +177,12 @@ class ServingRender(BaseServing):
request, merge_inline_system=self._merge_inline_system
)
chat_req.return_mm_kwargs = request.return_mm_kwargs
return await self.render_chat_request(chat_req)
return await self.render_chat_request(chat_req, raw_request)
async def render_completion_request(
self,
request: CompletionRequest,
raw_request: Request | None = None,
) -> list[GenerateRequest] | ErrorResponse:
"""Validate the model and preprocess a completion request.
@@ -197,8 +203,9 @@ class ServingRender(BaseServing):
)
if isinstance(result, ErrorResponse):
return result
base_id = f"cmpl-{self._base_request_id(raw_request, request.request_id)}"
generate_requests: list[GenerateRequest] = []
for engine_input in result:
for i, engine_input in enumerate(result):
prompt_components = extract_prompt_components(
self.model_config, engine_input
)
@@ -220,7 +227,7 @@ class ServingRender(BaseServing):
max_tokens, self.default_sampling_params
)
request_id = f"cmpl-{random_uuid()}"
request_id = base_id if len(result) == 1 else f"{base_id}-{i}"
generate_requests.append(
GenerateRequest(