diff --git a/src/plyngent/lmproto/deepseek/openai_compat/client.py b/src/plyngent/lmproto/deepseek/openai_compat/client.py index 2a9c2a3..a195a51 100644 --- a/src/plyngent/lmproto/deepseek/openai_compat/client.py +++ b/src/plyngent/lmproto/deepseek/openai_compat/client.py @@ -1,3 +1,6 @@ +from __future__ import annotations + +import json from typing import TYPE_CHECKING, Literal, overload import msgspec @@ -13,6 +16,19 @@ if TYPE_CHECKING: from .model import ChatCompletionsParam +def _inject_thinking(data: bytes) -> bytes: + """Inject ``thinking: {type: "enabled"}`` into the encoded request body. + + DeepSeek's reasoning model requires the ``thinking`` parameter to be + explicitly set (default is ``enabled``). The agent loop constructs the + base ``ChatCompletionsParam`` which lacks this field, so we add it + after msgspec encoding. + """ + body = json.loads(data) + body["thinking"] = {"type": "enabled"} + return json.dumps(body, separators=(",", ":")).encode("utf-8") + + class DeepseekOpenAIClient(BaseOpenAIClient): def __init__(self, config: OpenAIConfig) -> None: super().__init__(config) @@ -31,7 +47,7 @@ class DeepseekOpenAIClient(BaseOpenAIClient): self, param: ChatCompletionsParam, *, stream: bool = False ) -> ChatCompletionResponse | AsyncIterator[ChatCompletionChunk]: param = coerce_chat_completions_param_any(msgspec.structs.replace(param, stream=stream)) - data = self.encoder.encode(param) + data = _inject_thinking(self.encoder.encode(param)) if stream: resp = await self.session.post( "/chat/completions",