@@ -319,11 +319,17 @@ export function extractTextsFromUserMessages(messages: unknown[]): string[] {
319319}
320320
321321/**
322- * 提取从 startIndex 开始的新消息(user + assistant),返回格式化的文本。
322+ * Extract new messages (user + assistant) starting from startIndex.
323+ *
324+ * Defensive fix (#1248): if ensureLastUserMessage is true and the last user
325+ * message in the transcript falls before startIndex, prepend it to the result.
326+ * This handles the case where prePromptMessageCount (OpenClaw's startIndex)
327+ * excludes the current turn's user message.
323328 */
324329export function extractNewTurnTexts (
325330 messages : unknown [ ] ,
326331 startIndex : number ,
332+ ensureLastUserMessage ?: boolean ,
327333) : { texts : string [ ] ; newCount : number } {
328334 const texts : string [ ] = [ ] ;
329335 let count = 0 ;
@@ -345,6 +351,36 @@ export function extractNewTurnTexts(
345351 }
346352 }
347353 }
354+
355+ // Defensive fix: ensure the last user message is included even if
356+ // startIndex skipped it (OpenClaw prePromptMessageCount off-by-one)
357+ if ( ensureLastUserMessage && messages . length > 0 ) {
358+ let lastUserText : string | null = null ;
359+ for ( let i = messages . length - 1 ; i >= 0 ; i -- ) {
360+ const msg = messages [ i ] as Record < string , unknown > ;
361+ if ( ! msg || typeof msg !== "object" ) continue ;
362+ if ( msg . role === "user" ) {
363+ const content = msg . content ;
364+ if ( typeof content === "string" && content . trim ( ) ) {
365+ lastUserText = `[user]: ${ content . trim ( ) } ` ;
366+ } else if ( Array . isArray ( content ) ) {
367+ for ( const block of content ) {
368+ const b = block as Record < string , unknown > ;
369+ if ( b ?. type === "text" && typeof b . text === "string" && b . text . trim ( ) ) {
370+ lastUserText = `[user]: ${ b . text . trim ( ) } ` ;
371+ break ;
372+ }
373+ }
374+ }
375+ break ;
376+ }
377+ }
378+ if ( lastUserText && ! texts . some ( ( t ) => t . startsWith ( "[user]:" ) ) ) {
379+ texts . unshift ( lastUserText ) ;
380+ count ++ ;
381+ }
382+ }
383+
348384 return { texts, newCount : count } ;
349385}
350386
0 commit comments