Repository: ray-project/ray
File: python/ray/llm/examples/sglang/modules/sglang_engine.py (Python)

Code before:
            kwargs.update(chat_template_kwargs)

        return kwargs

    def _render_chat_prompt(
        self,
        request: ChatCompletionRequest,
        messages: List[dict[str, Any]],
    ) -> str:
        tokenizer = getattr(
            getattr(self.engine, "tokenizer_manager", None), "tokenizer", None
        )

        if tokenizer is not None and hasattr(tokenizer, "apply_chat_template"):
            template_kwargs = self._build_chat_template_kwargs(request)
            try:
                return tokenizer.apply_chat_template(
                    messages,
                    tokenize=False,
                    add_generation_prompt=True,
                    **template_kwargs,
                )
            except TypeError:
                # Keep broad tokenizer compatibility by retrying with fewer kwargs.
                fallback_kwargs = dict(template_kwargs)
                fallback_kwargs.pop("tokenize", None)
                fallback_kwargs.pop("reasoning_effort", None)
                fallback_kwargs.pop("tools", None)
                try:
                    return tokenizer.apply_chat_template(
                        messages,
                        add_generation_prompt=True,
                        **fallback_kwargs,
                    )
                except TypeError:
                    return tokenizer.apply_chat_template(
                        messages,
                        add_generation_prompt=True,
                    )
            except Exception:
                pass

        # Fallback prompt format for tokenizers without chat-template support.
        prompt_lines: List[str] = []
        for message in messages:
            role = str(message.get("role", "user"))
            content = message.get("content", "")
            prompt_lines.append(f"{role}: {content}")
        prompt_lines.append("assistant:")
        return "\n".join(prompt_lines)


Review comment (suggestion):
I think we can replace this block with something more like:
```
  kwargs = {}
  if getattr(request, "tools", None) is not None:
      kwargs["tools"] = request.tools
  if getattr(request, "reasoning_effort", None) is not None:
      kwargs["reasoning_effort"] = request.reasoning_effort
  if isinstance(getattr(request, "chat_template_kwargs", None), dict):
      kwargs.update(request.chat_template_kwargs)

  return tokenizer.apply_chat_template(
      messages,
      tokenize=False,
      add_generation_prompt=True,
      **kwargs,
  )
```

Code after:
            kwargs.update(chat_template_kwargs)

        return kwargs

    def _render_chat_prompt(
        self,
        request: ChatCompletionRequest,
        messages: List[dict[str, Any]],
    ) -> str:
        tokenizer = self.engine.tokenizer_manager.tokenizer
        # SGLang supports --skip-tokenizer-init, where tokenizer is intentionally
        # None and text prompt rendering is not available.
        if tokenizer is None:
            return self._render_fallback_prompt(messages)

        template_kwargs = self._build_chat_template_kwargs(request)
        return tokenizer.apply_chat_template(
            messages,
            tokenize=False,
            add_generation_prompt=True,
            **template_kwargs,
        )

    @staticmethod
    def _render_fallback_prompt(messages: List[dict[str, Any]]) -> str:
        # Fallback prompt format for tokenizers without chat-template support.
        prompt_lines: List[str] = []
        for message in messages:
            role = str(message.get("role", "user"))
            content = message.get("content", "")
            if content is None:
                content = ""
            prompt_lines.append(f"{role}: {content}")
        prompt_lines.append("assistant:")
        return "\n".join(prompt_lines)

    async def start(self) -> None:
        # Engine is initialized in __init__; keep start idempotent for protocol
        # compatibility.
        return

    async def check_health(self) -> None:
        # SGLang's in-process Engine API does not expose a health-check method.
        # Its health endpoints exist only in HTTP/gRPC server entrypoints, which
        # this integration does not run. Keep the protocol hook as a no-op.
        return

    async def _generate_raw(
        self,
        request: Any,
        prompt: Any,