okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
a229862
main
1// These regressions exercise event ordering and row identity inside the TUI, 2// which daemon E2E cannot inspect or deliver twice at a chosen boundary. 3package tui 4 5import ( 6"testing" 7 8"albedo/cli/internal/daemon" 9) 10 11func TestEmptyProviderRecordsDoNotDuplicateStreamedReply (t * testing.T ) { 12for _ ,settled := range []bool {false ,true } { 13model := newTestChatModel (t ,& daemon.Session {ID :"parent" }) 14model .SetSize (120 ,30 ) 15model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventUser ,Text :"launch a child" ,Source :"chat" }) 16reply := "Launched a subagent to write the Python love song." 17model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventText ,Text :reply ,MessageID :"live-reply" }) 18if settled { 19model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventUsage }) 20 } 21for _ ,id := range []string {"2-provider" ,"3-provider" } { 22model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventMessage ,EntryID :id }) 23 } 24final := daemon.StreamEvent {Type :daemon .EventMessage ,EntryID :"4" ,Position :4 ,Text :reply } 25model .handleStreamEvent (final ) 26model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventCommitted ,Seq :4 ,ReplacesLiveIDs : []string {"live-reply" }}) 27model .handleStreamEvent (final ) 28model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventTurnCompleted }) 29count ,footers := 0 ,0 30for _ ,entry := range model .History .Entries () { 31if entry .Kind == EntryAssistant { 32if entry .Text != reply || entry .ID != "4" { 33t .Fatalf ("wrong saved reply: %#v" ,entry ) 34 } 35count ++ 36 } 37if entry .Kind == EntryTurnEnd { 38footers ++ 39 } 40 } 41if count != 1 || footers != 1 { 42t .Fatalf ("settled=%v: got %d replies and %d footers" ,settled ,count ,footers ) 43 } 44 } 45} 46 47func TestMailIdentityPreservesDistinctMessagesAndTurnOwnership (t * testing.T ) { 48model := newTestChatModel (t ,& daemon.Session {ID :"parent" }) 49model .SetSize (100 ,30 ) 50model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventUser ,Source :"chat" ,Text :"start" }) 51model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventText ,Text :"working" }) 52turn := model .transcript .turn 53:= daemon.StreamEvent {Type :daemon .EventUser ,Source :"mail" ,Speaker :"You" ,MailKind :"result" ,EntryID :"7" ,Position :7 ,Text :"finished" } 54model .handleStreamEvent (if model .transcript .turn != turn { 56t .Fatal ("a sender named You reopened the parent's turn" ) 57 } 58model .handleStreamEvent (Text = "finished with evidence" 60model .handleStreamEvent (EntryID ,Position = "8" ,8 62model .handleStreamEvent (count := 0 64for _ ,entry := range model .History .Entries () { 65if entry .Source == "mail" { 66count ++ 67if entry .Speaker != "You" || entry .Text != Text { 68t .Fatalf ("mail update lost attribution: %#v" ,entry ) 69 } 70 } 71 } 72if count != 2 { 73t .Fatalf ("distinct identical letters must remain distinct, got %d" ,count ) 74 } 75model .loadingOlder = true 76model .showOlder (ChatOlderLoadedMsg {SessionID :model .SessionID ,Generation :model .Generation ,Page :& daemon.HistoryPage {Events : []daemon.StreamEvent {Before :8 }}) 77if model .History .Len ()!= 4 { 78t .Fatalf ("overlapping history added rows: %#v" ,model .History .Entries ()) 79 } 80model .handleStreamEvent (daemon.StreamEvent {Type :daemon .EventReset }) 81Replayed = true 82model .handleStreamEvent (if model .History .Len ()!= 1 || model .History .Entries ()[0 ].Speaker != "You" { 84t .Fatal ("reset failed to replace the transcript with attributed history" ) 85 } 86}