@@ -753,6 +753,23 @@ def model_post_init(self, context):
753753 return super ().model_post_init (context )
754754
755755 class NeMoRLOpenAIServingMixin :
756+ def _validate_chat_completion_prompt_token_ids (
757+ self , request , prompt_token_ids : list [int ]
758+ ) -> None :
759+ """Validate the final prompt after authoritative token replacement.
760+
761+ vLLM validates the chat-template rendering before this mixin replaces
762+ its prefix with authoritative trajectory tokens. The replacement can
763+ make the actual engine prompt longer than the rendering that vLLM
764+ checked, so every chat-completion return path must validate the final
765+ token IDs again. Tokenize requests intentionally remain unrestricted.
766+ """
767+ if isinstance (request , NeMoRLChatCompletionRequest ):
768+ validate_prompt_token_count (
769+ prompt_token_count = len (prompt_token_ids ),
770+ max_prompt_tokens = self .model_config .max_model_len - 1 ,
771+ )
772+
756773 @staticmethod
757774 def _set_max_tokens (request , max_tokens : int ) -> None :
758775 """Set the request's max output tokens.
@@ -950,12 +967,16 @@ async def preprocess_chat(
950967 not hasattr (request , "required_prefix_token_ids" )
951968 or request .required_prefix_token_ids is None
952969 ):
970+ final_prompt_token_ids = res [1 ][0 ]["prompt_token_ids" ]
971+ self ._validate_chat_completion_prompt_token_ids (
972+ request , final_prompt_token_ids
973+ )
953974 # Clamp the request's max output tokens so that input + output <= max_model_len.
954975 if actual_request_max_tokens is not None :
955976 self ._clamp_max_tokens (
956977 request ,
957978 actual_request_max_tokens ,
958- res [ 1 ][ 0 ][ "prompt_token_ids" ] ,
979+ final_prompt_token_ids ,
959980 )
960981 return res
961982
@@ -1006,6 +1027,10 @@ async def preprocess_chat(
10061027
10071028 engine_prompt ["prompt_token_ids" ] = final_prompt_token_ids
10081029
1030+ self ._validate_chat_completion_prompt_token_ids (
1031+ request , final_prompt_token_ids
1032+ )
1033+
10091034 # Clamp after prefix replacement since the prompt length may have changed.
10101035 if actual_request_max_tokens is not None :
10111036 self ._clamp_max_tokens (
0 commit comments