Summary
When a user has both a 1:1 and a channel/group conversation with the bot, proactive sends initiated from a 1:1 chat (e.g. agent sending an Adaptive Card via the send tool) may be delivered to the channel conversation instead.
Root Cause
For DMs, the inbound context sets To as user:{aadObjectId} (not conversation:{conversationId}). When the send tool resolves the target via findByUserId in conversation-store-fs.ts, it returns the first matching conversation for that user — which may be a channel or group chat rather than the originating 1:1 conversation.
findByUserId iterates Object.entries() on the conversation store JSON and returns the first match with no recency or conversation-type awareness.
Possible Fixes
- Track recency: Add an
updatedAt timestamp to stored conversation references and have findByUserId return the most recently active conversation.
- Use conversation ID for DMs: Change the
To value for DMs from user:{senderId} to conversation:{conversationId} so resolveMSTeamsSendContext does an exact conversation lookup instead of a user-based search.
- Pass originating conversation through: Have the agent's
send tool inherit the originating conversation ID from the session context rather than resolving by user.
Reproduction
- Have a bot added to both a 1:1 chat and a team channel
- In the 1:1 chat, ask the bot to send you an Adaptive Card (or any proactive message via the
send tool)
- The card may appear in the channel instead of the 1:1 chat
Files
extensions/msteams/src/conversation-store-fs.ts — findByUserId returns first match
extensions/msteams/src/monitor-handler/message-handler.ts — sets To as user:{id} for DMs
extensions/msteams/src/send-context.ts — resolveMSTeamsSendContext uses findByUserId for user targets
Summary
When a user has both a 1:1 and a channel/group conversation with the bot, proactive sends initiated from a 1:1 chat (e.g. agent sending an Adaptive Card via the
sendtool) may be delivered to the channel conversation instead.Root Cause
For DMs, the inbound context sets
Toasuser:{aadObjectId}(notconversation:{conversationId}). When thesendtool resolves the target viafindByUserIdinconversation-store-fs.ts, it returns the first matching conversation for that user — which may be a channel or group chat rather than the originating 1:1 conversation.findByUserIditeratesObject.entries()on the conversation store JSON and returns the first match with no recency or conversation-type awareness.Possible Fixes
updatedAttimestamp to stored conversation references and havefindByUserIdreturn the most recently active conversation.Tovalue for DMs fromuser:{senderId}toconversation:{conversationId}soresolveMSTeamsSendContextdoes an exact conversation lookup instead of a user-based search.sendtool inherit the originating conversation ID from the session context rather than resolving by user.Reproduction
sendtool)Files
extensions/msteams/src/conversation-store-fs.ts—findByUserIdreturns first matchextensions/msteams/src/monitor-handler/message-handler.ts— setsToasuser:{id}for DMsextensions/msteams/src/send-context.ts—resolveMSTeamsSendContextusesfindByUserIdfor user targets