From cfd2ca31026b8fb597e9fcd6f50f53a25504aa33 Mon Sep 17 00:00:00 2001 From: Ari Webb Date: Thu, 12 Feb 2026 15:06:32 -0800 Subject: [PATCH] fix: zai clear empty messages (#9466) --- letta/llm_api/zai_client.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/letta/llm_api/zai_client.py b/letta/llm_api/zai_client.py index d0ad8075..87d577ef 100644 --- a/letta/llm_api/zai_client.py +++ b/letta/llm_api/zai_client.py @@ -68,6 +68,32 @@ class ZAIClient(OpenAIClient): } } + # Sanitize empty text content — ZAI rejects empty text blocks + if "messages" in data: + for msg in data["messages"]: + content = msg.get("content") if isinstance(msg, dict) else getattr(msg, "content", None) + # String content: replace empty with None (assistant+tool_calls) or "." + if isinstance(content, str) and not content.strip(): + role = msg.get("role") if isinstance(msg, dict) else getattr(msg, "role", None) + has_tool_calls = msg.get("tool_calls") if isinstance(msg, dict) else getattr(msg, "tool_calls", None) + if role == "assistant" and has_tool_calls: + # assistant + tool_calls: null content is valid in OpenAI format + if isinstance(msg, dict): + msg["content"] = None + else: + msg.content = None + else: + if isinstance(msg, dict): + msg["content"] = "." + else: + msg.content = "." + # List content: fix empty text blocks within arrays + elif isinstance(content, list): + for block in content: + if isinstance(block, dict) and block.get("type") == "text": + if not block.get("text", "").strip(): + block["text"] = "." + return data @trace_method