@@ -387,6 +387,110 @@ describe("Store", () => {
387387
388388 expect ( getState ( ) . isProcessing ) . toBe ( false )
389389 } )
390+
391+ test ( "abortRequest should save partially streamed message to chat history" , ( ) => {
392+ const { getState, actions } = setup ( )
393+
394+ const controller = new AbortController ( )
395+ actions . setAbortController ( controller )
396+ actions . setIsProcessing ( true )
397+ actions . setCurrentAssistantMessage ( "This is a partial response..." )
398+
399+ actions . abortRequest ( )
400+
401+ const state = getState ( )
402+
403+ // Message should be saved to chat history
404+ expect ( state . chatHistory ) . toHaveLength ( 1 )
405+ expect ( state . chatHistory [ 0 ] ) . toEqual ( {
406+ type : "message" ,
407+ role : "assistant" ,
408+ content : "This is a partial response..." ,
409+ } )
410+
411+ // Current message should be cleared
412+ expect ( state . currentAssistantMessage ) . toBe ( "" )
413+
414+ // Stats should indicate abort
415+ expect ( state . stats ) . toBe ( "User aborted the request." )
416+
417+ // Processing should be stopped
418+ expect ( state . isProcessing ) . toBe ( false )
419+ } )
420+
421+ test ( "abortRequest should not save empty message to chat history" , ( ) => {
422+ const { getState, actions } = setup ( )
423+
424+ const controller = new AbortController ( )
425+ actions . setAbortController ( controller )
426+ actions . setIsProcessing ( true )
427+ actions . setCurrentAssistantMessage ( "" )
428+
429+ actions . abortRequest ( )
430+
431+ const state = getState ( )
432+
433+ // No message should be added to history
434+ expect ( state . chatHistory ) . toHaveLength ( 0 )
435+
436+ // Current message should still be empty
437+ expect ( state . currentAssistantMessage ) . toBe ( "" )
438+
439+ // Stats should still indicate abort
440+ expect ( state . stats ) . toBe ( "User aborted the request." )
441+ } )
442+
443+ test ( "abortRequest should not save whitespace-only message to chat history" , ( ) => {
444+ const { getState, actions } = setup ( )
445+
446+ const controller = new AbortController ( )
447+ actions . setAbortController ( controller )
448+ actions . setIsProcessing ( true )
449+ actions . setCurrentAssistantMessage ( " \n \t " )
450+
451+ actions . abortRequest ( )
452+
453+ const state = getState ( )
454+
455+ // No message should be added to history (whitespace is trimmed)
456+ expect ( state . chatHistory ) . toHaveLength ( 0 )
457+
458+ // Current message should still be empty
459+ expect ( state . currentAssistantMessage ) . toBe ( "" )
460+ } )
461+
462+ test ( "abortRequest should preserve existing chat history when adding partial message" , ( ) => {
463+ const { getState, actions } = setup ( )
464+
465+ // Add existing history
466+ actions . addChatHistoryEntry ( {
467+ type : "message" ,
468+ role : "user" ,
469+ content : "Hello" ,
470+ } )
471+
472+ const controller = new AbortController ( )
473+ actions . setAbortController ( controller )
474+ actions . setIsProcessing ( true )
475+ actions . setCurrentAssistantMessage ( "Partial response" )
476+
477+ actions . abortRequest ( )
478+
479+ const state = getState ( )
480+
481+ // Should have both messages
482+ expect ( state . chatHistory ) . toHaveLength ( 2 )
483+ expect ( state . chatHistory [ 0 ] ) . toEqual ( {
484+ type : "message" ,
485+ role : "user" ,
486+ content : "Hello" ,
487+ } )
488+ expect ( state . chatHistory [ 1 ] ) . toEqual ( {
489+ type : "message" ,
490+ role : "assistant" ,
491+ content : "Partial response" ,
492+ } )
493+ } )
390494 } )
391495
392496 describe ( "reset action" , ( ) => {
0 commit comments