Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -311,41 +311,41 @@ 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
)

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 = (
Expand All @@ -359,34 +359,34 @@ 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",
},
)

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

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
17 changes: 10 additions & 7 deletions tests/activity/pydantic/test_activity_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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"}
],
Expand All @@ -177,15 +180,15 @@ 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"},
],
},
{
"type": "message",
"channel_id": "msteams:subchannel",
"channel_id": "msteams",
"entities": [
{"type": "other"},
{"type": EntityTypes.PRODUCT_INFO.value, "id": "subchannel"},
Expand All @@ -200,15 +203,15 @@ 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"},
],
},
{
"type": "message",
"channel_id": "msteams:misc",
"channel_id": "msteams",
"entities": [
{"type": "other"},
{"type": EntityTypes.PRODUCT_INFO.value, "id": "misc"},
Expand Down
11 changes: 6 additions & 5 deletions tests/activity/test_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,15 +436,16 @@ 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

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,
),
Expand All @@ -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,
),
Expand All @@ -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,
),
Expand All @@ -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,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
Expand All @@ -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,
),
Expand Down Expand Up @@ -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,
),
Expand Down Expand Up @@ -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,
),
Expand Down Expand Up @@ -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,
),
Expand Down Expand Up @@ -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,
),
Expand Down Expand Up @@ -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,
),
Expand Down Expand Up @@ -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,
),
Expand Down