diff --git a/src/plyngent/lmproto/anthropic/model.py b/src/plyngent/lmproto/anthropic/model.py index 41135cd..b3e140d 100644 --- a/src/plyngent/lmproto/anthropic/model.py +++ b/src/plyngent/lmproto/anthropic/model.py @@ -67,9 +67,13 @@ class AnthropicThinkingConfig(Struct, omit_defaults=True): ``budget_tokens`` is the reasoning budget the model may spend before it answers; the API requires it to be at least 1024 and smaller than ``max_tokens`` (see ``agent.messages_bridge``, which keeps both valid). + + ``type`` carries no default: ``omit_defaults`` would drop a defaulted one, + and the server reads the block as malformed without it — DeepSeek answers + ``thinking: missing field ``type``. """ - type: Literal["enabled", "disabled"] = "enabled" + type: Literal["enabled", "disabled"] budget_tokens: int | Unset = UNSET diff --git a/tests/test_lmproto/test_anthropic.py b/tests/test_lmproto/test_anthropic.py index b4ed462..26f71b9 100644 --- a/tests/test_lmproto/test_anthropic.py +++ b/tests/test_lmproto/test_anthropic.py @@ -11,6 +11,7 @@ from plyngent.lmproto.anthropic.model import ( AnthropicMessagesParam, AnthropicMessageStop, AnthropicResponseText, + AnthropicThinkingConfig, AnthropicUsage, AnthropicUserMessage, AnthropicWebSearchToolResultContent, @@ -114,6 +115,17 @@ def test_messages_param_encodes_server_tool_dicts() -> None: assert data["tools"] == [{"type": "web_search_20250305", "name": "web_search", "max_uses": 3}] +def test_messages_param_keeps_the_thinking_type_on_the_wire() -> None: + """``omit_defaults`` must not drop the block's ``type`` discriminator.""" + param = AnthropicMessagesParam( + model="deepseek-flash", + messages=[AnthropicUserMessage(content="hi")], + thinking=AnthropicThinkingConfig(type="enabled", budget_tokens=16384), + ) + data = msgspec.json.decode(msgspec.json.encode(param)) + assert data["thinking"] == {"type": "enabled", "budget_tokens": 16384} + + async def test_client_messages_create(monkeypatch: pytest.MonkeyPatch) -> None: client = AnthropicClient(AnthropicConfig(api_key="sk-test", base_url="https://example/v1"))