fix: emit assistant update for tool-call-only messages from OpenAI-compatible providers

When an OpenAI-compatible provider (e.g. vLLM) returns a response with
only tool calls and no text content, handleMessageEnd silently skips
emitting the assistant update event. This prevents the tool execution
round-trip from completing, causing the session to go idle without
executing the requested tools.

The fix adds a check for toolCall content blocks alongside the existing
text and media checks, ensuring tool-call-only responses are properly
signalled to downstream handlers.

Partially addresses #13603
This commit is contained in:
chad gibson 2026-03-20 22:28:10 -07:00
parent 9fb78453e0
commit f8c73a3428

View File

@ -321,7 +321,15 @@ export function handleMessageEnd(
}
}
if (!ctx.state.emittedAssistantUpdate && (cleanedText || hasMedia)) {
// Tool-call-only responses from OpenAI-compatible providers (e.g. vLLM) may have
// no text or media content. Without this check, handleMessageEnd silently skips
// emitting the assistant update, which prevents downstream tool execution from
// being signalled. See: https://github.com/openclaw/openclaw/issues/13603
const hasToolCalls =
Array.isArray(assistantMessage.content) &&
assistantMessage.content.some((b: { type?: string }) => b.type === "toolCall");
if (!ctx.state.emittedAssistantUpdate && (cleanedText || hasMedia || hasToolCalls)) {
const data = buildAssistantStreamData({
text: cleanedText,
delta: cleanedText,