@@ -49,7 +49,7 @@ func TestLoadAIStateCmdLoadsConversationOverRPC(t *testing.T) {
4949 rpcClient , cleanup := newAITestRPCClient (t , server )
5050 defer cleanup ()
5151
52- cmd := loadAIStateCmd (& console.SliverClient {Rpc : rpcClient }, "" )
52+ cmd := loadAIStateCmd (& console.SliverClient {Rpc : rpcClient }, aiTargetSummary {}, "" )
5353 msg := cmd ()
5454
5555 loaded , ok := msg .(aiLoadedMsg )
@@ -112,7 +112,7 @@ func TestLoadAIStateCmdCreatesConversationWhenNoneExist(t *testing.T) {
112112 rpcClient , cleanup := newAITestRPCClient (t , server )
113113 defer cleanup ()
114114
115- msg := loadAIStateCmd (& console.SliverClient {Rpc : rpcClient }, "" )()
115+ msg := loadAIStateCmd (& console.SliverClient {Rpc : rpcClient }, aiTargetSummary {}, "" )()
116116
117117 loaded , ok := msg .(aiLoadedMsg )
118118 if ! ok {
@@ -157,6 +157,7 @@ func TestSubmitPromptCmdCreatesConversationAndSavesUserMessage(t *testing.T) {
157157
158158 msg := submitPromptCmd (
159159 & console.SliverClient {Rpc : rpcClient },
160+ aiTargetSummary {SessionID : "session-1" },
160161 nil ,
161162 "openai" ,
162163 "gpt-test" ,
@@ -179,6 +180,9 @@ func TestSubmitPromptCmdCreatesConversationAndSavesUserMessage(t *testing.T) {
179180 if server .saveConversationReqs [0 ].GetTitle () != "Explain the workflow." {
180181 t .Fatalf ("unexpected conversation title: %q" , server .saveConversationReqs [0 ].GetTitle ())
181182 }
183+ if server .saveConversationReqs [0 ].GetTargetSessionID () != "session-1" {
184+ t .Fatalf ("expected target session to be forwarded, got %+v" , server .saveConversationReqs [0 ])
185+ }
182186 if len (server .saveMessageReqs ) != 1 {
183187 t .Fatalf ("expected SaveAIConversationMessage to be called once, got %d" , len (server .saveMessageReqs ))
184188 }
@@ -206,6 +210,7 @@ func TestSubmitPromptCmdUsesExistingConversationSettings(t *testing.T) {
206210
207211 msg := submitPromptCmd (
208212 & console.SliverClient {Rpc : rpcClient },
213+ aiTargetSummary {},
209214 & clientpb.AIConversation {ID : "conv-1" , Provider : "anthropic" , Model : "claude-test" , Title : "Thread" },
210215 "openai" ,
211216 "gpt-test" ,
@@ -262,10 +267,16 @@ func TestDeleteConversationCmdSendsDeleteRequest(t *testing.T) {
262267}
263268
264269func TestWaitForAIConversationEventCmdFiltersForAIEvents (t * testing.T ) {
265- conversation := & clientpb.AIConversation {ID : "conv-1" , OperatorName : "alice" }
266- data , err := proto .Marshal (conversation )
270+ eventPayload := & clientpb.AIConversationEvent {
271+ EventType : clientpb .AIConversationEventType_AI_CONVERSATION_EVENT_TYPE_CONVERSATION_UPDATED ,
272+ Conversation : & clientpb.AIConversation {
273+ ID : "conv-1" ,
274+ OperatorName : "alice" ,
275+ },
276+ }
277+ data , err := proto .Marshal (eventPayload )
267278 if err != nil {
268- t .Fatalf ("marshal conversation: %v" , err )
279+ t .Fatalf ("marshal conversation event : %v" , err )
269280 }
270281
271282 listener := make (chan * clientpb.Event , 2 )
@@ -278,8 +289,8 @@ func TestWaitForAIConversationEventCmdFiltersForAIEvents(t *testing.T) {
278289 if ! ok {
279290 t .Fatalf ("expected aiConversationEventMsg, got %T" , msg )
280291 }
281- if aiEvent .conversation == nil || aiEvent .conversation .GetID () != "conv-1" {
282- t .Fatalf ("unexpected AI conversation event payload: %+v" , aiEvent .conversation )
292+ if aiEvent .event == nil || aiEvent .event . GetConversation () == nil || aiEvent . event . GetConversation () .GetID () != "conv-1" {
293+ t .Fatalf ("unexpected AI conversation event payload: %+v" , aiEvent .event )
283294 }
284295}
285296
@@ -293,33 +304,38 @@ func TestWaitForAIConversationEventCmdReturnsClosedMessage(t *testing.T) {
293304 }
294305}
295306
296- func TestAIModelReloadsSharedConversationEvents (t * testing.T ) {
307+ func TestAIModelAppliesSharedConversationEventsWithoutReload (t * testing.T ) {
297308 listener := make (chan * clientpb.Event )
298309 close (listener )
299310
300311 model := newAIModel (nil , aiContext {
301312 connection : aiConnectionSummary {Operator : "alice" },
302313 }, listener )
303314 model .loading = false
304-
305- updated , cmd := model .Update (aiConversationEventMsg {conversation : & clientpb.AIConversation {
306- ID : "conv-2" ,
307- OperatorName : "bob" ,
315+ model .conversations = []* clientpb.AIConversation {{ID : "conv-1" , Title : "First" }}
316+
317+ updated , cmd := model .Update (aiConversationEventMsg {event : & clientpb.AIConversationEvent {
318+ EventType : clientpb .AIConversationEventType_AI_CONVERSATION_EVENT_TYPE_CONVERSATION_UPDATED ,
319+ Conversation : & clientpb.AIConversation {
320+ ID : "conv-2" ,
321+ OperatorName : "bob" ,
322+ Title : "Shared thread" ,
323+ },
308324 }})
309325
310326 nextModel := updated .(* aiModel )
311- if ! nextModel .loading {
312- t .Fatal ("expected shared conversation event to trigger a reload" )
327+ if nextModel .loading {
328+ t .Fatal ("did not expect shared conversation event to trigger a reload" )
313329 }
314- if nextModel .status != "Conversation updated on the server. Refreshing..." {
315- t .Fatalf ("unexpected reload status: %q " , nextModel .status )
330+ if conversationIndexByID ( nextModel .conversations , "conv-2" ) < 0 {
331+ t .Fatalf ("expected shared conversation to be merged locally, got %+v " , nextModel .conversations )
316332 }
317333 if cmd == nil {
318- t .Fatal ("expected shared conversation event to schedule a refresh " )
334+ t .Fatal ("expected shared conversation event to continue listening for events " )
319335 }
320336}
321337
322- func TestAIModelReloadsDeleteEventsWhileAwaitingResponse (t * testing.T ) {
338+ func TestAIModelAppliesDeleteEventsWhileAwaitingResponse (t * testing.T ) {
323339 listener := make (chan * clientpb.Event )
324340 close (listener )
325341
@@ -332,22 +348,36 @@ func TestAIModelReloadsDeleteEventsWhileAwaitingResponse(t *testing.T) {
332348 ID : "conv-2" ,
333349 OperatorName : "alice" ,
334350 UpdatedAt : 100 ,
351+ TurnState : clientpb .AIConversationTurnState_AI_TURN_STATE_IN_PROGRESS ,
335352 Messages : []* clientpb.AIConversationMessage {
336353 {Role : "user" , Content : "still waiting" },
337354 },
338355 }
356+ model .conversations = []* clientpb.AIConversation {
357+ {ID : "conv-2" , Title : "Current" },
358+ {ID : "conv-1" , Title : "Fallback" },
359+ }
339360
340- updated , cmd := model .Update (aiConversationEventMsg {conversation : & clientpb.AIConversation {
341- ID : "conv-2" ,
342- OperatorName : "bob" ,
361+ updated , cmd := model .Update (aiConversationEventMsg {event : & clientpb.AIConversationEvent {
362+ EventType : clientpb .AIConversationEventType_AI_CONVERSATION_EVENT_TYPE_CONVERSATION_DELETED ,
363+ ConversationID : "conv-2" ,
364+ Conversation : & clientpb.AIConversation {
365+ ID : "conv-2" ,
366+ },
343367 }})
344368
345369 nextModel := updated .(* aiModel )
346- if ! nextModel .loading {
347- t .Fatal ("expected delete tombstone to reload the conversation" )
370+ if nextModel .loading {
371+ t .Fatal ("did not expect delete tombstone to trigger a reload" )
372+ }
373+ if nextModel .currentConversation != nil {
374+ t .Fatalf ("expected deleted conversation to be cleared, got %+v" , nextModel .currentConversation )
375+ }
376+ if conversationIndexByID (nextModel .conversations , "conv-2" ) >= 0 {
377+ t .Fatalf ("expected deleted conversation to be removed, got %+v" , nextModel .conversations )
348378 }
349379 if cmd == nil {
350- t .Fatal ("expected delete tombstone to schedule a refresh " )
380+ t .Fatal ("expected delete tombstone to continue listening for events " )
351381 }
352382}
353383
0 commit comments