sglang 0.4.7 + deepseek v3-0324 Unsupported tool call ?

code `package com.ruoyi.controller;

import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

@RestController @RequestMapping("/client/ai") public class ChatController {

private static final Logger logger = LoggerFactory.getLogger(ChatController.class);

private final ChatClient chatClient;

public ChatController(ChatClient.Builder chatClientBuilder) {
    this.chatClient = chatClientBuilder.build();
}

@Resource
private ToolCallbackProvider toolCallbackProvider;

@GetMapping("/chat")
public String chat(String message){
    System.out.println("message:"+message);
    String answer = chatClient
            .prompt()
            .user(message)
            .tools(toolCallbackProvider)
            .call().chatResponse().getResult().getOutput().getText();
    System.out.println("answer:"+answer);
    return answer;
}

}`

`package com.ruoyi.tool;

import org.springframework.ai.tool.annotation.Tool; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service("weatherServiceTool") public class WeatherServiceTool {

@Tool(description = "获取指定城市的天气")
public WeatherInfo getWeather(String cityName) {
    System.out.println("调用工具1:获取指定城市的天气");
    if ("北京".equals(cityName)) {
        return new WeatherInfo("北京", "晴", 28);
    } else if ("上海".equals(cityName)) {
        return new WeatherInfo("上海", "多云", 26);
    } else {
        return new WeatherInfo(cityName, "未知", -999);
    }
}

@Tool(description = "获取当前用户所在的时区时间")
String getCurrentDateTime() {
    System.out.println("调用工具2:获取当前用户所在的时区时间");
    return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
}

}

`

error sglang [2025-06-19 02:07:56] INFO: [172.30.213.120:59018](http://172.30.213.120:59018/) - "POST /v1/chat/completions HTTP/1.1" 500 Internal Server Error [2025-06-19 02:07:56] ERROR: Exception in ASGI application Traceback (most recent call last): File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__ return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 187, in __call__ raise exc File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 165, in __call__ await self.app(scope, receive, _send) File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/cors.py", line 85, in __call__ await self.app(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app raise exc File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app await app(scope, receive, sender) File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 714, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 734, in app await route.handle(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 288, in handle await self.app(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 76, in app await wrap_app_handling_exceptions(app, request)(scope, receive, send) File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app raise exc File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app await app(scope, receive, sender) File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 73, in app response = await f(request) ^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 301, in app raw_response = await run_endpoint_function( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 212, in run_endpoint_function return await dependant.call(**values) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/sgl-workspace/sglang/python/sglang/srt/entrypoints/http_server.py", line 629, in openai_v1_chat_completions return await v1_chat_completions(_global_state.tokenizer_manager, raw_request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/sgl-workspace/sglang/python/sglang/srt/openai_api/adapter.py", line 1541, in v1_chat_completions all_requests = [ChatCompletionRequest(**request_json)] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/dist-packages/pydantic/main.py", line 253, in __init__ validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pydantic_core._pydantic_core.ValidationError: 3 validation errors for ChatCompletionRequest messages.1.ChatCompletionMessageGenericParam.content Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict] For further information visit https://errors.pydantic.dev/2.11/v/missing messages.1.ChatCompletionMessageUserParam.role Input should be 'user' [type=literal_error, input_value='assistant', input_type=str] For further information visit https://errors.pydantic.dev/2.11/v/literal_error messages.1.ChatCompletionMessageUserParam.content Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict] For further information visit https://errors.pydantic.dev/2.11/v/missing

Reproduction

h20 96G 8* 2

model:DeepSeek V3

Environment

docker run -d --gpus all \ --shm-size 500g \ --network=host \ -v /home/nvme01:/model \ --name sglang_deepseek-V3-01 \ -it \ --rm \ --ipc=host \ -e VLLM_HOST_IP=172.17.42.4 \ -e NCCL_IB_HCA=mlx5_ \ -e NCCL_IB_GID_INDEX=3 \ -e GLOO_SOCKET_IFNAME=eth0 \ -e NCCL_SOCKET_IFNAME=eth0 \ -e NCCL_DEBUG=info \ -e NCCL_IB_DISABLE=0 \ lmsysorg/sglang:v0.4.7.post1-cu124 \ python3 -m sglang.launch_server --model-path /model/DeepSeek-V3 --served-model-name=DeepSeek-V3 --tp 16 --dist-init-addr 172.17.42.4:6379 --nnodes 2 --node-rank 0 --trust-remote-code --host 0.0.0.0 --port 8000 --tool-call-parser deepseekv3 --chat-template ./sglang/examples/chat_template/tool_chat_template_deepseekv3.jinja

docker run -d --gpus all \ --shm-size 500g \ --network=host \ -v /home/nvme01:/model \ --name sglang_deepseek-V3-02 \ -it \ --rm \ --ipc=host \ --ipc=host \ -e VLLM_HOST_IP=172.17.42.5 \ -e NCCL_IB_HCA=mlx5_ \ -e NCCL_IB_GID_INDEX=3 \ -e GLOO_SOCKET_IFNAME=eth0 \ -e NCCL_SOCKET_IFNAME=eth0 \ -e NCCL_DEBUG=info \ -e NCCL_IB_DISABLE=0 \ lmsysorg/sglang:v0.4.7.post1-cu124 \ python3 -m sglang.launch_server --model-path /model/DeepSeek-V3 --served-model-name=DeepSeek-V3 --tp 16 --dist-init-addr 172.17.42.4:6379 --nnodes 2 --node-rank 1 --trust-remote-code --host 0.0.0.0 --port 8000 --tool-call-parser deepseekv3 --chat-template ./sglang/examples/chat_template/tool_chat_template_deepseekv3.jinja

Comment From: dev-jonghoonpark

I'm cleaning up log for future reviewers.

3 validation errors for ChatCompletionRequest messages.

ChatCompletionMessageGenericParam.content Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict] For further information visit https://errors.pydantic.dev/2.11/v/missing messages.

ChatCompletionMessageUserParam.role Input should be 'user' [type=literal_error, input_value='assistant', input_type=str] For further information visit https://errors.pydantic.dev/2.11/v/literal_error messages.

ChatCompletionMessageUserParam.content Field required [type=missing, input_value={'role': 'assistant', 'to...ityName": "北京"}'}}]}, input_type=dict] For further information visit https://errors.pydantic.dev/2.11/v/missing

Comment From: start-dzl

The same code runs without any issues on vLLM combined with DeepSeek.