diff --git a/examples/openclaw-plugin/context-engine.ts b/examples/openclaw-plugin/context-engine.ts index 244f75ad0..ba895dd5a 100644 --- a/examples/openclaw-plugin/context-engine.ts +++ b/examples/openclaw-plugin/context-engine.ts @@ -806,7 +806,7 @@ export function createMemoryOpenVikingContextEngine(params: { ? afterTurnParams.prePromptMessageCount : 0; - const { texts: newTexts, newCount } = extractNewTurnTexts(messages, start); + const { texts: newTexts, newCount } = extractNewTurnTexts(messages, start, true); if (newTexts.length === 0) { diag("afterTurn_skip", OVSessionId, { diff --git a/examples/openclaw-plugin/text-utils.ts b/examples/openclaw-plugin/text-utils.ts index 0e5bea927..38c74efb6 100644 --- a/examples/openclaw-plugin/text-utils.ts +++ b/examples/openclaw-plugin/text-utils.ts @@ -419,6 +419,7 @@ function formatToolResultContent(content: unknown): string { export function extractNewTurnTexts( messages: unknown[], startIndex: number, + ensureLastUserMessage?: boolean, ): { texts: string[]; newCount: number } { const texts: string[] = []; let count = 0; @@ -452,6 +453,36 @@ export function extractNewTurnTexts( } } } + // Defensive fix: ensure the last user message is included even if + // startIndex skipped it (OpenClaw prePromptMessageCount off-by-one) + // See: https://github.com/volcengine/OpenViking/issues/1248 + if (ensureLastUserMessage && messages.length > 0) { + let lastUserText: string | null = null; + for (let i = messages.length - 1; i >= 0; i--) { + const msg = messages[i] as Record; + if (!msg || typeof msg !== "object") continue; + if (msg.role === "user") { + const content = msg.content; + if (typeof content === "string" && content.trim()) { + lastUserText = `[user]: ${content.trim()}`; + } else if (Array.isArray(content)) { + for (const block of content) { + const b = block as Record; + if (b?.type === "text" && typeof b.text === "string" && b.text.trim()) { + lastUserText = `[user]: ${b.text.trim()}`; + break; + } + } + } + break; + } + } + if (lastUserText && !texts.some((t) => t.startsWith("[user]:"))) { + texts.unshift(lastUserText); + count++; + } + } + return { texts, newCount: count }; }