From 366199fc0c2886a9648d713488fb138e1dad6ccb Mon Sep 17 00:00:00 2001 From: worldmozara Date: Tue, 14 Jul 2026 18:52:27 +0800 Subject: [PATCH] core/lmproto: allow null assistant content and optional response fields Providers return content=null with tool_calls; relax choice logprobs, finish_reason, fingerprint, and usage for real API payloads. --- src/plyngent/agent/loop.py | 2 +- src/plyngent/lmproto/openai_compatible/model.py | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plyngent/agent/loop.py b/src/plyngent/agent/loop.py index e2d9021..24ad32d 100644 --- a/src/plyngent/agent/loop.py +++ b/src/plyngent/agent/loop.py @@ -66,7 +66,7 @@ async def run_chat_loop( # noqa: PLR0913 messages.append(assistant) yield AssistantMessageEvent(message=assistant) - if assistant.content: + if isinstance(assistant.content, str) and assistant.content: yield TextDeltaEvent(content=assistant.content) tool_calls = assistant.tool_calls diff --git a/src/plyngent/lmproto/openai_compatible/model.py b/src/plyngent/lmproto/openai_compatible/model.py index 8438eba..e14a7c0 100644 --- a/src/plyngent/lmproto/openai_compatible/model.py +++ b/src/plyngent/lmproto/openai_compatible/model.py @@ -65,7 +65,9 @@ class AssistantCustomToolCall(Struct, tag_field="type", tag="custom"): type AnyAssistantToolCall = AssistantFunctionToolCall | AssistantCustomToolCall -class AssistantChatMessage(ChatMessage, tag_field="role", tag="assistant"): +class AssistantChatMessage(Struct, tag_field="role", tag="assistant"): + # APIs often return content=null when tool_calls are present. + content: str | None | Unset = UNSET name: str | Unset = UNSET audio: IDObject | Unset = UNSET refusal: str | Unset = UNSET @@ -201,8 +203,8 @@ class ChatCompletionsParam(Struct): class ChatCompletionChoice(Struct): index: int message: AssistantChatMessage - logprobs: dict[str, Any] - finish_reason: FinishReason + logprobs: dict[str, Any] | None = None + finish_reason: FinishReason | None = None class ChatCompletionResponse(Struct): @@ -211,8 +213,8 @@ class ChatCompletionResponse(Struct): created: int model: str choices: list[ChatCompletionChoice] - system_fingerprint: str - usage: dict[str, Any] + system_fingerprint: str | Unset = UNSET + usage: dict[str, Any] | Unset = UNSET moderation: dict[str, Any] | Unset = UNSET service_tier: ServiceTier | Unset = UNSET