@@ -9,7 +9,6 @@ import { clearSessionTranscriptIndexCache } from "./session-transcript-index.fs.
99import {
1010 archiveSessionTranscripts ,
1111 readFirstUserMessageFromTranscript ,
12- readLastMessagePreviewFromTranscript ,
1312 readLatestSessionUsageFromTranscript ,
1413 readLatestSessionUsageFromTranscriptAsync ,
1514 readLatestRecentSessionUsageFromTranscriptAsync ,
@@ -275,176 +274,6 @@ describe("readFirstUserMessageFromTranscript", () => {
275274 } ) ;
276275} ) ;
277276
278- describe ( "readLastMessagePreviewFromTranscript" , ( ) => {
279- let tmpDir : string ;
280- let storePath : string ;
281-
282- registerTempSessionStore ( "openclaw-session-fs-test-" , ( nextTmpDir , nextStorePath ) => {
283- tmpDir = nextTmpDir ;
284- storePath = nextStorePath ;
285- } ) ;
286-
287- test ( "returns null for empty file" , ( ) => {
288- const sessionId = "test-last-empty" ;
289- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
290- fs . writeFileSync ( transcriptPath , "" , "utf-8" ) ;
291-
292- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
293- expect ( result ) . toBeNull ( ) ;
294- } ) ;
295-
296- test . each ( [
297- {
298- sessionId : "test-last-user" ,
299- lines : [
300- JSON . stringify ( { message : { role : "user" , content : "First user" } } ) ,
301- JSON . stringify ( { message : { role : "assistant" , content : "First assistant" } } ) ,
302- JSON . stringify ( { message : { role : "user" , content : "Last user message" } } ) ,
303- ] ,
304- expected : "Last user message" ,
305- } ,
306- {
307- sessionId : "test-last-assistant" ,
308- lines : [
309- JSON . stringify ( { message : { role : "user" , content : "User question" } } ) ,
310- JSON . stringify ( { message : { role : "assistant" , content : "Final assistant reply" } } ) ,
311- ] ,
312- expected : "Final assistant reply" ,
313- } ,
314- ] as const ) (
315- "returns the last user or assistant message from transcript for $sessionId" ,
316- ( { sessionId, lines, expected } ) => {
317- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
318- fs . writeFileSync ( transcriptPath , lines . join ( "\n" ) , "utf-8" ) ;
319- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
320- expect ( result ) . toBe ( expected ) ;
321- } ,
322- ) ;
323-
324- test ( "skips system messages to find last user/assistant" , ( ) => {
325- const sessionId = "test-last-skip-system" ;
326- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
327- const lines = [
328- JSON . stringify ( { message : { role : "user" , content : "Real last" } } ) ,
329- JSON . stringify ( { message : { role : "system" , content : "System at end" } } ) ,
330- ] ;
331- fs . writeFileSync ( transcriptPath , lines . join ( "\n" ) , "utf-8" ) ;
332-
333- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
334- expect ( result ) . toBe ( "Real last" ) ;
335- } ) ;
336-
337- test ( "returns null when no user/assistant messages exist" , ( ) => {
338- const sessionId = "test-last-no-match" ;
339- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
340- const lines = [
341- JSON . stringify ( { type : "session" , version : 1 , id : sessionId } ) ,
342- JSON . stringify ( { message : { role : "system" , content : "Only system" } } ) ,
343- ] ;
344- fs . writeFileSync ( transcriptPath , lines . join ( "\n" ) , "utf-8" ) ;
345-
346- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
347- expect ( result ) . toBeNull ( ) ;
348- } ) ;
349-
350- test ( "handles malformed JSON lines gracefully (last preview)" , ( ) => {
351- const sessionId = "test-last-malformed" ;
352- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
353- const lines = [
354- JSON . stringify ( { message : { role : "user" , content : "Valid first" } } ) ,
355- "not valid json at end" ,
356- ] ;
357- fs . writeFileSync ( transcriptPath , lines . join ( "\n" ) , "utf-8" ) ;
358-
359- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
360- expect ( result ) . toBe ( "Valid first" ) ;
361- } ) ;
362-
363- test . each ( [
364- {
365- sessionId : "test-last-array" ,
366- message : {
367- role : "assistant" ,
368- content : [ { type : "text" , text : "Array content response" } ] ,
369- } ,
370- expected : "Array content response" ,
371- } ,
372- {
373- sessionId : "test-last-output-text" ,
374- message : {
375- role : "assistant" ,
376- content : [ { type : "output_text" , text : "Output text response" } ] ,
377- } ,
378- expected : "Output text response" ,
379- } ,
380- ] as const ) (
381- "handles array/output_text content format for $sessionId" ,
382- ( { sessionId, message, expected } ) => {
383- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
384- fs . writeFileSync ( transcriptPath , JSON . stringify ( { message } ) , "utf-8" ) ;
385- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
386- expect ( result , sessionId ) . toBe ( expected ) ;
387- } ,
388- ) ;
389-
390- test ( "skips empty content to find previous message" , ( ) => {
391- const sessionId = "test-last-skip-empty" ;
392- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
393- const lines = [
394- JSON . stringify ( { message : { role : "assistant" , content : "Has content" } } ) ,
395- JSON . stringify ( { message : { role : "user" , content : "" } } ) ,
396- ] ;
397- fs . writeFileSync ( transcriptPath , lines . join ( "\n" ) , "utf-8" ) ;
398-
399- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
400- expect ( result ) . toBe ( "Has content" ) ;
401- } ) ;
402-
403- test ( "reads from end of large file (16KB window)" , ( ) => {
404- const sessionId = "test-last-large" ;
405- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
406- const padding = JSON . stringify ( { message : { role : "user" , content : "x" . repeat ( 500 ) } } ) ;
407- const lines : string [ ] = [ ] ;
408- for ( let i = 0 ; i < 30 ; i ++ ) {
409- lines . push ( padding ) ;
410- }
411- lines . push ( JSON . stringify ( { message : { role : "assistant" , content : "Last in large file" } } ) ) ;
412- fs . writeFileSync ( transcriptPath , lines . join ( "\n" ) , "utf-8" ) ;
413-
414- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
415- expect ( result ) . toBe ( "Last in large file" ) ;
416- } ) ;
417-
418- test ( "handles valid UTF-8 content" , ( ) => {
419- const sessionId = "test-last-utf8" ;
420- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
421- const validLine = JSON . stringify ( {
422- message : { role : "user" , content : "Valid UTF-8: 你好世界 🌍" } ,
423- } ) ;
424- fs . writeFileSync ( transcriptPath , validLine , "utf-8" ) ;
425-
426- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
427- expect ( result ) . toBe ( "Valid UTF-8: 你好世界 🌍" ) ;
428- } ) ;
429-
430- test ( "strips inline directives from last preview text" , ( ) => {
431- const sessionId = "test-last-strip-inline-directives" ;
432- const transcriptPath = path . join ( tmpDir , `${ sessionId } .jsonl` ) ;
433- const lines = [
434- JSON . stringify ( {
435- message : {
436- role : "assistant" ,
437- content : "Hello [[reply_to_current]] world [[audio_as_voice]]" ,
438- } ,
439- } ) ,
440- ] ;
441- fs . writeFileSync ( transcriptPath , lines . join ( "\n" ) , "utf-8" ) ;
442-
443- const result = readLastMessagePreviewFromTranscript ( sessionId , storePath ) ;
444- expect ( result ) . toBe ( "Hello world" ) ;
445- } ) ;
446- } ) ;
447-
448277describe ( "shared transcript read behaviors" , ( ) => {
449278 let tmpDir : string ;
450279 let storePath : string ;
@@ -456,13 +285,11 @@ describe("shared transcript read behaviors", () => {
456285
457286 test ( "returns null for missing transcript files" , ( ) => {
458287 expect ( readFirstUserMessageFromTranscript ( "missing-session" , storePath ) ) . toBeNull ( ) ;
459- expect ( readLastMessagePreviewFromTranscript ( "missing-session" , storePath ) ) . toBeNull ( ) ;
460288 } ) ;
461289
462290 test ( "uses sessionFile overrides when provided" , ( ) => {
463291 const sessionId = "test-shared-custom" ;
464292 const firstPath = path . join ( tmpDir , "custom-first.jsonl" ) ;
465- const lastPath = path . join ( tmpDir , "custom-last.jsonl" ) ;
466293
467294 fs . writeFileSync (
468295 firstPath ,
@@ -472,37 +299,22 @@ describe("shared transcript read behaviors", () => {
472299 ] . join ( "\n" ) ,
473300 "utf-8" ,
474301 ) ;
475- fs . writeFileSync (
476- lastPath ,
477- JSON . stringify ( { message : { role : "assistant" , content : "Custom file last" } } ) ,
478- "utf-8" ,
479- ) ;
480302
481303 expect ( readFirstUserMessageFromTranscript ( sessionId , storePath , firstPath ) ) . toBe (
482304 "Custom file message" ,
483305 ) ;
484- expect ( readLastMessagePreviewFromTranscript ( sessionId , storePath , lastPath ) ) . toBe (
485- "Custom file last" ,
486- ) ;
487306 } ) ;
488307
489308 test ( "trims whitespace in extracted previews" , ( ) => {
490309 const firstSessionId = "test-shared-first-trim" ;
491- const lastSessionId = "test-shared-last-trim" ;
492310
493311 fs . writeFileSync (
494312 path . join ( tmpDir , `${ firstSessionId } .jsonl` ) ,
495313 JSON . stringify ( { message : { role : "user" , content : " Padded message " } } ) ,
496314 "utf-8" ,
497315 ) ;
498- fs . writeFileSync (
499- path . join ( tmpDir , `${ lastSessionId } .jsonl` ) ,
500- JSON . stringify ( { message : { role : "assistant" , content : " Padded response " } } ) ,
501- "utf-8" ,
502- ) ;
503316
504317 expect ( readFirstUserMessageFromTranscript ( firstSessionId , storePath ) ) . toBe ( "Padded message" ) ;
505- expect ( readLastMessagePreviewFromTranscript ( lastSessionId , storePath ) ) . toBe ( "Padded response" ) ;
506318 } ) ;
507319} ) ;
508320
0 commit comments