@@ -193,12 +193,21 @@ describe('registerDashboardAttachmentUiDefinition', () => {
193193 let deps : ReturnType < typeof createMockDeps > ;
194194 let uiDefinition : AttachmentUIDefinition < DashboardAttachment > ;
195195 let unregister : ( ) => void ;
196- let chat$ : Subject < ChatEvent > ;
197196 let currentAppId$ : BehaviorSubject < string | null > ;
198197
199198 const createMockDeps = ( ) => {
200- chat$ = new Subject < ChatEvent > ( ) ;
201199 currentAppId$ = new BehaviorSubject < string | null > ( 'agentBuilder' ) ;
200+ const chatEventsByConversationId = new Map < string , Subject < ChatEvent > > ( ) ;
201+ const getChatEvents = ( conversationId : string ) => {
202+ let chatEvents$ = chatEventsByConversationId . get ( conversationId ) ;
203+
204+ if ( ! chatEvents$ ) {
205+ chatEvents$ = new Subject < ChatEvent > ( ) ;
206+ chatEventsByConversationId . set ( conversationId , chatEvents$ ) ;
207+ }
208+
209+ return chatEvents$ ;
210+ } ;
202211 const dashboardAppClientApi$ = new Subject < DashboardApi | undefined > ( ) ;
203212 const addAttachmentType = jest . fn ( ) ;
204213 const updateAttachmentOrigin = jest . fn ( ) . mockResolvedValue ( undefined ) ;
@@ -216,7 +225,9 @@ describe('registerDashboardAttachmentUiDefinition', () => {
216225 addAttachment : mockAddAttachment ,
217226 updateAttachmentOrigin,
218227 events : {
219- chat$,
228+ getChatEvents$ : jest . fn ( ( conversationId : string ) =>
229+ getChatEvents ( conversationId ) . asObservable ( )
230+ ) ,
220231 ui : { activeConversation$ : activeConversation$ . asObservable ( ) } ,
221232 } ,
222233 } as unknown as AgentBuilderPluginStart ;
@@ -252,7 +263,9 @@ describe('registerDashboardAttachmentUiDefinition', () => {
252263 updateAttachmentOrigin,
253264 findDashboardsService,
254265 emitConversationChange,
255- chat$,
266+ emitChatEvent : ( conversationId : string , event : ChatEvent ) => {
267+ getChatEvents ( conversationId ) . next ( event ) ;
268+ } ,
256269 currentAppId$,
257270 } ;
258271 } ;
@@ -329,7 +342,7 @@ describe('registerDashboardAttachmentUiDefinition', () => {
329342 addAttachment : jest . fn ( ) ,
330343 updateAttachmentOrigin : jest . fn ( ) . mockResolvedValue ( undefined ) ,
331344 events : {
332- chat $ : new Subject < ChatEvent > ( ) ,
345+ getChatEvents $ : jest . fn ( ( ) => new Subject < ChatEvent > ( ) . asObservable ( ) ) ,
333346 ui : {
334347 activeConversation$ : new BehaviorSubject < ActiveConversation | null > (
335348 null
@@ -555,7 +568,7 @@ describe('registerDashboardAttachmentUiDefinition', () => {
555568 } ) ;
556569 } ) ;
557570
558- describe ( 'dashboard app integration - live changes from chat$ ' , ( ) => {
571+ describe ( 'dashboard app integration - live changes from Agent Builder events ' , ( ) => {
559572 beforeEach ( ( ) => {
560573 jest . useFakeTimers ( ) ;
561574 } ) ;
@@ -575,7 +588,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
575588
576589 // Updated operation triggers state update
577590 const versionedAttachment = createMockVersionedAttachment ( 'attachment-1' ) ;
578- chat$ . next (
591+ deps . emitChatEvent (
592+ 'conversation-1' ,
579593 createMockRoundCompleteEvent (
580594 [ versionedAttachment ] ,
581595 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
@@ -589,7 +603,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
589603
590604 // Created operation also triggers
591605 mockApi . setState . mockClear ( ) ;
592- chat$ . next (
606+ deps . emitChatEvent (
607+ 'conversation-1' ,
593608 createMockRoundCompleteEvent (
594609 [ versionedAttachment ] ,
595610 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . created } ]
@@ -600,6 +615,28 @@ describe('registerDashboardAttachmentUiDefinition', () => {
600615 cleanup ?.( ) ;
601616 } ) ;
602617
618+ it ( 'ignores roundComplete events from other conversations' , async ( ) => {
619+ const { getAttachment } = createMockAttachment ( 'attachment-1' ) ;
620+ const mockApi = createMockDashboardApi ( ) ;
621+
622+ const cleanup = await mountAttachment ( {
623+ getAttachment,
624+ api : mockApi as unknown as DashboardApi ,
625+ conversationId : 'conversation-1' ,
626+ } ) ;
627+
628+ deps . emitChatEvent (
629+ 'conversation-2' ,
630+ createMockRoundCompleteEvent (
631+ [ createMockVersionedAttachment ( 'attachment-1' ) ] ,
632+ [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
633+ )
634+ ) ;
635+
636+ expect ( mockApi . setState ) . not . toHaveBeenCalled ( ) ;
637+ cleanup ?.( ) ;
638+ } ) ;
639+
603640 it ( 'does not update state for read-only operations or missing attachments' , async ( ) => {
604641 const { getAttachment } = createMockAttachment ( 'attachment-1' ) ;
605642 const mockApi = createMockDashboardApi ( ) ;
@@ -610,7 +647,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
610647 } ) ;
611648
612649 // Read operation - no update
613- chat$ . next (
650+ deps . emitChatEvent (
651+ 'conversation-1' ,
614652 createMockRoundCompleteEvent (
615653 [ createMockVersionedAttachment ( 'attachment-1' ) ] ,
616654 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . read } ]
@@ -619,7 +657,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
619657 expect ( mockApi . setState ) . not . toHaveBeenCalled ( ) ;
620658
621659 // No attachment in event - no update
622- chat$ . next (
660+ deps . emitChatEvent (
661+ 'conversation-1' ,
623662 createMockRoundCompleteEvent (
624663 [ ] ,
625664 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
@@ -628,7 +667,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
628667 expect ( mockApi . setState ) . not . toHaveBeenCalled ( ) ;
629668
630669 // Attachment without versions - no update
631- chat$ . next (
670+ deps . emitChatEvent (
671+ 'conversation-1' ,
632672 createMockRoundCompleteEvent (
633673 [ createMockVersionedAttachment ( 'attachment-1' , undefined , false ) ] ,
634674 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
@@ -652,7 +692,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
652692 api : mockApi1 as unknown as DashboardApi ,
653693 } ) ;
654694
655- chat$ . next (
695+ deps . emitChatEvent (
696+ 'conversation-1' ,
656697 createMockRoundCompleteEvent (
657698 [ createMockVersionedAttachment ( 'attachment-1' , 'original-dashboard-id' ) ] ,
658699 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
@@ -678,7 +719,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
678719 api : mockApi2 as unknown as DashboardApi ,
679720 } ) ;
680721
681- chat$ . next (
722+ deps . emitChatEvent (
723+ 'conversation-1' ,
682724 createMockRoundCompleteEvent (
683725 [ createMockVersionedAttachment ( 'attachment-1' , 'same-dashboard-id' ) ] ,
684726 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
@@ -688,7 +730,7 @@ describe('registerDashboardAttachmentUiDefinition', () => {
688730 cleanup2 ?.( ) ;
689731 } ) ;
690732
691- it ( 'cleans up chat$ subscription on cleanup or API unavailable' , async ( ) => {
733+ it ( 'cleans up Agent Builder events subscription on cleanup or API unavailable' , async ( ) => {
692734 const { getAttachment } = createMockAttachment ( 'attachment-1' ) ;
693735 const mockApi = createMockDashboardApi ( ) ;
694736
@@ -699,7 +741,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
699741
700742 // API becomes unavailable
701743 deps . dashboardAppClientApi$ . next ( undefined ) ;
702- chat$ . next (
744+ deps . emitChatEvent (
745+ 'conversation-1' ,
703746 createMockRoundCompleteEvent (
704747 [ createMockVersionedAttachment ( 'attachment-1' ) ] ,
705748 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
@@ -710,7 +753,8 @@ describe('registerDashboardAttachmentUiDefinition', () => {
710753 // After cleanup
711754 deps . dashboardAppClientApi$ . next ( mockApi as unknown as DashboardApi ) ;
712755 cleanup ?.( ) ;
713- chat$ . next (
756+ deps . emitChatEvent (
757+ 'conversation-1' ,
714758 createMockRoundCompleteEvent (
715759 [ createMockVersionedAttachment ( 'attachment-1' ) ] ,
716760 [ { attachment_id : 'attachment-1' , operation : ATTACHMENT_REF_OPERATION . updated } ]
0 commit comments