diff --git a/libraries/microsoft-agents-activity/microsoft_agents/activity/activity.py b/libraries/microsoft-agents-activity/microsoft_agents/activity/activity.py index 6b610579..c038d0f5 100644 --- a/libraries/microsoft-agents-activity/microsoft_agents/activity/activity.py +++ b/libraries/microsoft-agents-activity/microsoft_agents/activity/activity.py @@ -253,7 +253,7 @@ def _serialize_sub_channel_data( product_info = entity break - # maintain consistency between ProductInfo entity and sub channel + # self.channel_id is the source of truth for serialization if self.channel_id and self.channel_id.sub_channel: if product_info and product_info.get("id") != self.channel_id.sub_channel: raise Exception( @@ -268,6 +268,13 @@ def _serialize_sub_channel_data( "id": self.channel_id.sub_channel, } ) + + # simply serialized channelId value in Activity and relatesTo + if "channelId" in serialized: + serialized["channelId"] = self.channel_id.channel + elif "channel_id" in serialized: + serialized["channel_id"] = self.channel_id.channel + elif product_info: # remove productInfo entity if sub_channel is not set del serialized["entities"][i] if not serialized["entities"]: # after removal above, list may be empty @@ -777,7 +784,7 @@ def get_agentic_instance_id(self) -> Optional[str]: return self.recipient.agentic_app_id def get_agentic_user(self) -> Optional[str]: - """Gets the agentic user (UPN) from the context if it's an agentic request.""" + """Gets the agentic user (agenticUserId) from the context if it's an agentic request.""" if not self.is_agentic_request() or not self.recipient: return None - return self.recipient.id + return self.recipient.agentic_user_id diff --git a/libraries/microsoft-agents-authentication-msal/microsoft_agents/authentication/msal/msal_auth.py b/libraries/microsoft-agents-authentication-msal/microsoft_agents/authentication/msal/msal_auth.py index 2f0d34d9..aed16156 100644 --- a/libraries/microsoft-agents-authentication-msal/microsoft_agents/authentication/msal/msal_auth.py +++ b/libraries/microsoft-agents-authentication-msal/microsoft_agents/authentication/msal/msal_auth.py @@ -311,28 +311,28 @@ async def get_agentic_instance_token( return agentic_instance_token["access_token"], agent_token_result async def get_agentic_user_token( - self, agent_app_instance_id: str, upn: str, scopes: list[str] + self, agent_app_instance_id: str, agentic_user_id: str, scopes: list[str] ) -> Optional[str]: - """Gets the agentic user token for the given agent application instance ID and user principal name and the scopes. + """Gets the agentic user token for the given agent application instance ID and agentic user Id and the scopes. :param agent_app_instance_id: The agent application instance ID. :type agent_app_instance_id: str - :param upn: The user principal name. - :type upn: str + :param agentic_user_id: The agentic user ID. + :type agentic_user_id: str :param scopes: The scopes to request for the token. :type scopes: list[str] :return: The agentic user token, or None if not found. :rtype: Optional[str] """ - if not agent_app_instance_id or not upn: + if not agent_app_instance_id or not agentic_user_id: raise ValueError( - "Agent application instance Id and user principal name must be provided." + "Agent application instance Id and agentic user Id must be provided." ) logger.info( - "Attempting to get agentic user token from agent_app_instance_id %s and upn %s", + "Attempting to get agentic user token from agent_app_instance_id %s and agentic_user_id %s", agent_app_instance_id, - upn, + agentic_user_id, ) instance_token, agent_token = await self.get_agentic_instance_token( agent_app_instance_id @@ -340,12 +340,12 @@ async def get_agentic_user_token( if not instance_token or not agent_token: logger.error( - "Failed to acquire instance token or agent token for agent_app_instance_id %s and upn %s", + "Failed to acquire instance token or agent token for agent_app_instance_id %s and agentic_user_id %s", agent_app_instance_id, - upn, + agentic_user_id, ) raise Exception( - f"Failed to acquire instance token or agent token for agent_app_instance_id {agent_app_instance_id} and upn {upn}" + f"Failed to acquire instance token or agent token for agent_app_instance_id {agent_app_instance_id} and agentic_user_id {agentic_user_id}" ) authority = ( @@ -359,14 +359,14 @@ async def get_agentic_user_token( ) logger.info( - "Acquiring agentic user token for agent_app_instance_id %s and upn %s", + "Acquiring agentic user token for agent_app_instance_id %s and agentic_user_id %s", agent_app_instance_id, - upn, + agentic_user_id, ) auth_result_payload = instance_app.acquire_token_for_client( scopes, data={ - "username": upn, + "user_id": agentic_user_id, "user_federated_identity_credential": instance_token, "grant_type": "user_fic", }, @@ -374,9 +374,9 @@ async def get_agentic_user_token( if not auth_result_payload: logger.error( - "Failed to acquire agentic user token for agent_app_instance_id %s and upn %s, %s", + "Failed to acquire agentic user token for agent_app_instance_id %s and agentic_user_id %s, %s", agent_app_instance_id, - upn, + agentic_user_id, auth_result_payload, ) return None @@ -384,9 +384,9 @@ async def get_agentic_user_token( access_token = auth_result_payload.get("access_token") if not access_token: logger.error( - "Failed to acquire agentic user token for agent_app_instance_id %s and upn %s, %s", + "Failed to acquire agentic user token for agent_app_instance_id %s and agentic_user_id %s, %s", agent_app_instance_id, - upn, + agentic_user_id, auth_result_payload, ) return None diff --git a/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py b/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py index 7c8a5a30..eaabdf8c 100644 --- a/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py +++ b/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py @@ -118,20 +118,20 @@ async def get_agentic_user_token( connection = self._connection_manager.get_token_provider( context.identity, "agentic" ) - upn = context.activity.get_agentic_user() + agentic_user_id = context.activity.get_agentic_user() agentic_instance_id = context.activity.get_agentic_instance_id() - if not upn or not agentic_instance_id: + if not agentic_user_id or not agentic_instance_id: logger.error( - "Unable to retrieve agentic user token: missing UPN or agentic instance ID. UPN: %s, Agentic Instance ID: %s", - upn, + "Unable to retrieve agentic user token: missing agentic user Id or agentic instance Id. agentic_user_id: %s, Agentic Instance ID: %s", + agentic_user_id, agentic_instance_id, ) raise ValueError( - f"Unable to retrieve agentic user token: missing UPN or agentic instance ID. UPN: {upn}, Agentic Instance ID: {agentic_instance_id}" + f"Unable to retrieve agentic user token: missing agentic User Id or agentic instance Id. agentic_user_id: {agentic_user_id}, Agentic Instance ID: {agentic_instance_id}" ) token = await connection.get_agentic_user_token( - agentic_instance_id, upn, scopes + agentic_instance_id, agentic_user_id, scopes ) return TokenResponse(token=token) if token else TokenResponse() diff --git a/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/access_token_provider_base.py b/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/access_token_provider_base.py index d319c3fd..4d0a593d 100644 --- a/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/access_token_provider_base.py +++ b/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/access_token_provider_base.py @@ -43,6 +43,6 @@ async def get_agentic_instance_token( raise NotImplementedError() async def get_agentic_user_token( - self, agent_app_instance_id: str, upn: str, scopes: list[str] + self, agent_app_instance_id: str, agentic_user_id: str, scopes: list[str] ) -> Optional[str]: raise NotImplementedError() diff --git a/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/anonymous_token_provider.py b/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/anonymous_token_provider.py index 29c3de8c..d262c586 100644 --- a/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/anonymous_token_provider.py +++ b/libraries/microsoft-agents-hosting-core/microsoft_agents/hosting/core/authorization/anonymous_token_provider.py @@ -33,6 +33,6 @@ async def get_agentic_instance_token( return "", "" async def get_agentic_user_token( - self, agent_app_instance_id: str, upn: str, scopes: list[str] + self, agent_app_instance_id: str, agentic_user_id: str, scopes: list[str] ) -> Optional[str]: return "" diff --git a/tests/activity/pydantic/test_activity_io.py b/tests/activity/pydantic/test_activity_io.py index d60b11c3..2ca8734b 100644 --- a/tests/activity/pydantic/test_activity_io.py +++ b/tests/activity/pydantic/test_activity_io.py @@ -132,7 +132,10 @@ def test_channel_id_unset_becomes_set_at_init(self): activity = Activity(type="message") activity.channel_id = "channel:sub_channel" data = activity.model_dump(mode="json", exclude_unset=True, by_alias=True) - assert data["channelId"] == "channel:sub_channel" + assert data["channelId"] == "channel" + assert data["entities"] == [ + {"type": EntityTypes.PRODUCT_INFO.value, "id": "sub_channel"} + ] def test_channel_id_unset_at_init_not_included(self): activity = Activity(type="message") @@ -156,14 +159,14 @@ def test_product_info_avoids_error_no_parent_channel(self): Activity(type="message", channel_id="msteams:subchannel"), { "type": "message", - "channelId": "msteams:subchannel", + "channelId": "msteams", "entities": [ {"type": EntityTypes.PRODUCT_INFO.value, "id": "subchannel"} ], }, { "type": "message", - "channel_id": "msteams:subchannel", + "channel_id": "msteams", "entities": [ {"type": EntityTypes.PRODUCT_INFO.value, "id": "subchannel"} ], @@ -177,7 +180,7 @@ def test_product_info_avoids_error_no_parent_channel(self): ), { "type": "message", - "channelId": "msteams:subchannel", + "channelId": "msteams", "entities": [ {"type": "other"}, {"type": EntityTypes.PRODUCT_INFO.value, "id": "subchannel"}, @@ -185,7 +188,7 @@ def test_product_info_avoids_error_no_parent_channel(self): }, { "type": "message", - "channel_id": "msteams:subchannel", + "channel_id": "msteams", "entities": [ {"type": "other"}, {"type": EntityTypes.PRODUCT_INFO.value, "id": "subchannel"}, @@ -200,7 +203,7 @@ def test_product_info_avoids_error_no_parent_channel(self): ), { "type": "message", - "channelId": "msteams:misc", + "channelId": "msteams", "entities": [ {"type": "other"}, {"type": EntityTypes.PRODUCT_INFO.value, "id": "misc"}, @@ -208,7 +211,7 @@ def test_product_info_avoids_error_no_parent_channel(self): }, { "type": "message", - "channel_id": "msteams:misc", + "channel_id": "msteams", "entities": [ {"type": "other"}, {"type": EntityTypes.PRODUCT_INFO.value, "id": "misc"}, diff --git a/tests/activity/test_activity.py b/tests/activity/test_activity.py index 24d70008..7794a387 100644 --- a/tests/activity/test_activity.py +++ b/tests/activity/test_activity.py @@ -436,7 +436,8 @@ def agentic_role(self, request): ) def test_is_agentic_request(self, role, expected): activity = Activity( - type="message", recipient=ChannelAccount(id="bot", name="bot", role=role) + type="message", + recipient=ChannelAccount(agentic_user_id="bot", name="bot", role=role), ) assert activity.is_agentic_request() == expected @@ -444,7 +445,7 @@ def test_get_agentic_instance_id_is_agentic(self, mocker, agentic_role): activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ), @@ -455,7 +456,7 @@ def test_get_agentic_instance_id_not_agentic(self, non_agentic_role): activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=non_agentic_role, ), @@ -466,7 +467,7 @@ def test_get_agentic_user_is_agentic(self, agentic_role): activity = Activity( type="message", recipient=ChannelAccount( - id=DEFAULTS.agentic_user_id, + agentic_user_id=DEFAULTS.agentic_user_id, agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ), @@ -477,7 +478,7 @@ def test_get_agentic_user_not_agentic(self, non_agentic_role): activity = Activity( type="message", recipient=ChannelAccount( - id=DEFAULTS.agentic_user_id, + agentic_user_id=DEFAULTS.agentic_user_id, agentic_app_id=DEFAULTS.agentic_instance_id, role=non_agentic_role, ), diff --git a/tests/hosting_core/app/_oauth/_handlers/test_agentic_user_authorization.py b/tests/hosting_core/app/_oauth/_handlers/test_agentic_user_authorization.py index 78f2c512..579623b0 100644 --- a/tests/hosting_core/app/_oauth/_handlers/test_agentic_user_authorization.py +++ b/tests/hosting_core/app/_oauth/_handlers/test_agentic_user_authorization.py @@ -85,7 +85,7 @@ async def test_get_agentic_instance_token_not_agentic( activity = Activity( type="message", recipient=ChannelAccount( - id=DEFAULTS.agentic_user_id, + agentic_user_id=DEFAULTS.agentic_user_id, agentic_app_id=DEFAULTS.agentic_instance_id, role=non_agentic_role, ), @@ -100,7 +100,7 @@ async def test_get_agentic_user_token_not_agentic( activity = Activity( type="message", recipient=ChannelAccount( - id=DEFAULTS.agentic_user_id, + agentic_user_id=DEFAULTS.agentic_user_id, agentic_app_id=DEFAULTS.agentic_instance_id, role=non_agentic_role, ), @@ -145,7 +145,7 @@ async def test_get_agentic_instance_token_is_agentic( activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ), @@ -177,7 +177,7 @@ async def test_get_agentic_user_token_is_agentic( activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ), @@ -221,7 +221,7 @@ async def test_sign_in_success( activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ), @@ -266,7 +266,7 @@ async def test_sign_in_failure( activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ), @@ -311,7 +311,7 @@ async def test_get_refreshed_token_success( activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ), @@ -357,7 +357,7 @@ async def test_get_refreshed_token_failure( activity = Activity( type="message", recipient=ChannelAccount( - id="some_id", + agentic_user_id="some_id", agentic_app_id=DEFAULTS.agentic_instance_id, role=agentic_role, ),