diff --git a/python/sglang/srt/entrypoints/openai/protocol.py b/python/sglang/srt/entrypoints/openai/protocol.py index b0825dfba342..6e46ac6a31b1 100644 --- a/python/sglang/srt/entrypoints/openai/protocol.py +++ b/python/sglang/srt/entrypoints/openai/protocol.py @@ -475,7 +475,7 @@ class CompletionResponseChoice(BaseModel): finish_reason: Optional[Literal["stop", "length", "content_filter", "abort"]] = None matched_stop: Union[None, int, str] = None hidden_states: Optional[object] = None - token_ids: Optional[List[int]] = None + response_token_ids: Optional[List[int]] = None prompt_token_ids: Optional[List[int]] = None @model_serializer(mode="wrap") @@ -483,8 +483,8 @@ def _serialize(self, handler): data = handler(self) if self.hidden_states is None: data.pop("hidden_states", None) - if self.token_ids is None: - data.pop("token_ids", None) + if self.response_token_ids is None: + data.pop("response_token_ids", None) if self.prompt_token_ids is None: data.pop("prompt_token_ids", None) return data @@ -515,7 +515,7 @@ class CompletionResponseStreamChoice(BaseModel): finish_reason: Optional[Literal["stop", "length", "content_filter", "abort"]] = None matched_stop: Union[None, int, str] = None hidden_states: Optional[object] = None - token_ids: Optional[List[int]] = None + response_token_ids: Optional[List[int]] = None prompt_token_ids: Optional[List[int]] = None @model_serializer(mode="wrap") @@ -523,8 +523,8 @@ def _serialize(self, handler): data = handler(self) if self.hidden_states is None: data.pop("hidden_states", None) - if self.token_ids is None: - data.pop("token_ids", None) + if self.response_token_ids is None: + data.pop("response_token_ids", None) if self.prompt_token_ids is None: data.pop("prompt_token_ids", None) return data diff --git a/python/sglang/srt/entrypoints/openai/serving_completions.py b/python/sglang/srt/entrypoints/openai/serving_completions.py index b7da6fdf2b7a..6c797d2be460 100644 --- a/python/sglang/srt/entrypoints/openai/serving_completions.py +++ b/python/sglang/srt/entrypoints/openai/serving_completions.py @@ -374,7 +374,7 @@ async def _generate_completion_stream( if finish_reason and "matched" in finish_reason else None ), - token_ids=chunk_token_ids, + response_token_ids=chunk_token_ids, prompt_token_ids=chunk_prompt_token_ids, ) chunk = CompletionStreamResponse( @@ -609,7 +609,7 @@ def _build_completion_response( else None ), hidden_states=hidden_states, - token_ids=( + response_token_ids=( ret_item["output_ids"] if request.return_token_ids else None ), prompt_token_ids=( diff --git a/test/registered/unit/entrypoints/openai/test_serving_completions.py b/test/registered/unit/entrypoints/openai/test_serving_completions.py index 289d09ec2e43..9f1f3d549157 100644 --- a/test/registered/unit/entrypoints/openai/test_serving_completions.py +++ b/test/registered/unit/entrypoints/openai/test_serving_completions.py @@ -249,8 +249,11 @@ def test_non_streaming_response(self): self.assertEqual(len(response.choices), 1) self.assertEqual(response.choices[0].text, " world") self.assertEqual(len(response.choices[0].logprobs.top_logprobs), 0) - self.assertEqual(response.choices[0].token_ids, [3, 4]) + self.assertEqual(response.choices[0].response_token_ids, [3, 4]) self.assertEqual(response.choices[0].prompt_token_ids, [1, 2]) + dumped_choice = response.model_dump()["choices"][0] + self.assertNotIn("token_ids", dumped_choice) + self.assertEqual(dumped_choice["response_token_ids"], [3, 4]) def test_streaming_abort_yields_error(self): """Test that an abort finish reason during streaming correctly yields an error and stops.""" @@ -383,10 +386,14 @@ async def run_stream(): data = json.loads(raw[len("data: ") :]) choices.extend(data.get("choices", [])) - token_ids = [tid for c in choices for tid in c.get("token_ids", [])] + token_ids = [ + tid for c in choices for tid in c.get("response_token_ids", []) + ] text = "".join(c["text"] for c in choices) self.assertEqual(text, "abc") self.assertEqual(token_ids, [5, 6, 7]) + for choice in choices: + self.assertNotIn("token_ids", choice) self.assertEqual(choices[0]["prompt_token_ids"], [1, 2]) for choice in choices[1:]: self.assertNotIn("prompt_token_ids", choice)