From c1fe688d40d57ce513d633d8a7682383ddc6fdef Mon Sep 17 00:00:00 2001 From: Sid Date: Tue, 24 Feb 2026 11:33:37 +0800 Subject: [PATCH] fix(gateway): safely extract text from content arrays in prompt builder (#24946) * fix(gateway): safely extract text from message content arrays in prompt builder When HistoryEntry.body is a content array (e.g. [{type:"text", text:"hello"}]) rather than a plain string, template literal interpolation produces "[object Object]" instead of the actual message text. This affects users whose session messages were stored with array content format. Add a safeBody helper that detects non-string body values and uses extractTextFromChatContent to extract the text, preventing the [object Object] serialization in both the current-message return path and the history formatting path. Fixes openclaw#24688 Co-authored-by: Cursor * fix: format gateway agent prompt helper (#24946) --------- Co-authored-by: Cursor Co-authored-by: Peter Steinberger --- src/gateway/agent-prompt.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/gateway/agent-prompt.ts b/src/gateway/agent-prompt.ts index 58e12bacd..5904726b9 100644 --- a/src/gateway/agent-prompt.ts +++ b/src/gateway/agent-prompt.ts @@ -1,10 +1,23 @@ import { buildHistoryContextFromEntries, type HistoryEntry } from "../auto-reply/reply/history.js"; +import { extractTextFromChatContent } from "../shared/chat-content.js"; export type ConversationEntry = { role: "user" | "assistant" | "tool"; entry: HistoryEntry; }; +/** + * Coerce body to string. Handles cases where body is a content array + * (e.g. [{type:"text", text:"hello"}]) that would serialize as + * [object Object] if used directly in a template literal. + */ +function safeBody(body: unknown): string { + if (typeof body === "string") { + return body; + } + return extractTextFromChatContent(body) ?? ""; +} + export function buildAgentMessageFromConversationEntries(entries: ConversationEntry[]): string { if (entries.length === 0) { return ""; @@ -31,10 +44,10 @@ export function buildAgentMessageFromConversationEntries(entries: ConversationEn const historyEntries = entries.slice(0, currentIndex).map((e) => e.entry); if (historyEntries.length === 0) { - return currentEntry.body; + return safeBody(currentEntry.body); } - const formatEntry = (entry: HistoryEntry) => `${entry.sender}: ${entry.body}`; + const formatEntry = (entry: HistoryEntry) => `${entry.sender}: ${safeBody(entry.body)}`; return buildHistoryContextFromEntries({ entries: [...historyEntries, currentEntry], currentMessage: formatEntry(currentEntry),