diff --git a/src/microsoft/opentelemetry/a365/hosting/scope_helpers/utils.py b/src/microsoft/opentelemetry/a365/hosting/scope_helpers/utils.py index a02da39d..9476f5ed 100644 --- a/src/microsoft/opentelemetry/a365/hosting/scope_helpers/utils.py +++ b/src/microsoft/opentelemetry/a365/hosting/scope_helpers/utils.py @@ -37,7 +37,7 @@ def get_caller_pairs(activity: Activity) -> Iterator[tuple[str, Any]]: frm = activity.from_property if not frm: return - yield USER_ID_KEY, frm.aad_object_id + yield USER_ID_KEY, frm.aad_object_id or frm.agentic_user_id or frm.id yield USER_NAME_KEY, frm.name yield USER_EMAIL_KEY, frm.agentic_user_id diff --git a/tests/a365/hosting/scope_helpers/test_scope_helper_utils.py b/tests/a365/hosting/scope_helpers/test_scope_helper_utils.py index 8d0ee845..07f5a63f 100644 --- a/tests/a365/hosting/scope_helpers/test_scope_helper_utils.py +++ b/tests/a365/hosting/scope_helpers/test_scope_helper_utils.py @@ -83,6 +83,64 @@ def test_get_channel_pairs(): assert (CHANNEL_LINK_KEY, None) in result +def test_get_caller_pairs_fallback_to_frm_id(): + """Test get_caller_pairs falls back to frm.id when aad_object_id is None (non-Teams channel).""" + from_account = ChannelAccount( + id="slack-user-123", + name="Slack User", + agentic_user_id=None, + aad_object_id=None, + ) + activity = Activity(type="message", from_property=from_account) + + result = list(get_caller_pairs(activity)) + + assert (USER_ID_KEY, "slack-user-123") in result + + +def test_get_caller_pairs_fallback_to_agentic_user_id(): + """Test get_caller_pairs falls back to agentic_user_id for A2A when aad_object_id is None.""" + from_account = ChannelAccount( + id="raw-id", + name="Agent Caller", + agentic_user_id="agent-auid-456", + aad_object_id=None, + ) + activity = Activity(type="message", from_property=from_account) + + result = list(get_caller_pairs(activity)) + + assert (USER_ID_KEY, "agent-auid-456") in result + + +def test_get_caller_pairs_aad_object_id_takes_precedence(): + """Test get_caller_pairs uses aad_object_id when all identifiers are set.""" + from_account = ChannelAccount( + id="raw-id", + name="Teams User", + agentic_user_id="agent-auid", + aad_object_id="aad-wins", + ) + activity = Activity(type="message", from_property=from_account) + + result = list(get_caller_pairs(activity)) + + assert (USER_ID_KEY, "aad-wins") in result + + +def test_get_caller_pairs_a2a_guid_agentic_user_id(): + """Test userId resolves to GUID AgenticUserId in A2A scenario.""" + from_account = ChannelAccount( + id="29:1sH5NArUwkWAX", + name="Agent Caller", + agentic_user_id="bef730f4-d6f5-4ffb-b759-26ffa449ed7e", + aad_object_id=None, + ) + activity = Activity(type="message", from_property=from_account) + result = list(get_caller_pairs(activity)) + assert (USER_ID_KEY, "bef730f4-d6f5-4ffb-b759-26ffa449ed7e") in result + + def test_get_conversation_pairs(): """Test get_conversation_pairs extracts conversation information.""" conversation = ConversationAccount(id="conversation-123")