microsoft-agents-activity 0.7.0.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. microsoft_agents/activity/__init__.py +200 -0
  2. microsoft_agents/activity/_channel_id_field_mixin.py +95 -0
  3. microsoft_agents/activity/_load_configuration.py +33 -0
  4. microsoft_agents/activity/_model_utils.py +64 -0
  5. microsoft_agents/activity/_type_aliases.py +7 -0
  6. microsoft_agents/activity/_utils/__init__.py +6 -0
  7. microsoft_agents/activity/_utils/_deferred_string.py +34 -0
  8. microsoft_agents/activity/action_types.py +17 -0
  9. microsoft_agents/activity/activity.py +787 -0
  10. microsoft_agents/activity/activity_event_names.py +9 -0
  11. microsoft_agents/activity/activity_importance.py +10 -0
  12. microsoft_agents/activity/activity_types.py +25 -0
  13. microsoft_agents/activity/adaptive_card_invoke_action.py +27 -0
  14. microsoft_agents/activity/adaptive_card_invoke_response.py +23 -0
  15. microsoft_agents/activity/adaptive_card_invoke_value.py +25 -0
  16. microsoft_agents/activity/agents_model.py +49 -0
  17. microsoft_agents/activity/animation_card.py +57 -0
  18. microsoft_agents/activity/attachment.py +27 -0
  19. microsoft_agents/activity/attachment_data.py +24 -0
  20. microsoft_agents/activity/attachment_info.py +22 -0
  21. microsoft_agents/activity/attachment_layout_types.py +9 -0
  22. microsoft_agents/activity/attachment_view.py +18 -0
  23. microsoft_agents/activity/audio_card.py +57 -0
  24. microsoft_agents/activity/basic_card.py +33 -0
  25. microsoft_agents/activity/caller_id_constants.py +10 -0
  26. microsoft_agents/activity/card_action.py +42 -0
  27. microsoft_agents/activity/card_image.py +22 -0
  28. microsoft_agents/activity/channel_account.py +39 -0
  29. microsoft_agents/activity/channel_adapter_protocol.py +79 -0
  30. microsoft_agents/activity/channel_id.py +95 -0
  31. microsoft_agents/activity/channels.py +161 -0
  32. microsoft_agents/activity/contact_relation_update_action_types.py +9 -0
  33. microsoft_agents/activity/conversation_account.py +41 -0
  34. microsoft_agents/activity/conversation_members.py +19 -0
  35. microsoft_agents/activity/conversation_parameters.py +40 -0
  36. microsoft_agents/activity/conversation_reference.py +69 -0
  37. microsoft_agents/activity/conversation_resource_response.py +22 -0
  38. microsoft_agents/activity/conversation_update_types.py +18 -0
  39. microsoft_agents/activity/conversations_result.py +20 -0
  40. microsoft_agents/activity/delivery_modes.py +12 -0
  41. microsoft_agents/activity/end_of_conversation_codes.py +13 -0
  42. microsoft_agents/activity/entity/__init__.py +36 -0
  43. microsoft_agents/activity/entity/ai_entity.py +111 -0
  44. microsoft_agents/activity/entity/entity.py +41 -0
  45. microsoft_agents/activity/entity/entity_types.py +14 -0
  46. microsoft_agents/activity/entity/geo_coordinates.py +33 -0
  47. microsoft_agents/activity/entity/mention.py +24 -0
  48. microsoft_agents/activity/entity/place.py +33 -0
  49. microsoft_agents/activity/entity/product_info.py +20 -0
  50. microsoft_agents/activity/entity/thing.py +21 -0
  51. microsoft_agents/activity/error.py +22 -0
  52. microsoft_agents/activity/error_response.py +15 -0
  53. microsoft_agents/activity/errors/__init__.py +14 -0
  54. microsoft_agents/activity/errors/error_message.py +64 -0
  55. microsoft_agents/activity/errors/error_resources.py +52 -0
  56. microsoft_agents/activity/expected_replies.py +16 -0
  57. microsoft_agents/activity/fact.py +21 -0
  58. microsoft_agents/activity/hero_card.py +33 -0
  59. microsoft_agents/activity/inner_http_error.py +17 -0
  60. microsoft_agents/activity/input_hints.py +10 -0
  61. microsoft_agents/activity/installation_update_action_types.py +9 -0
  62. microsoft_agents/activity/invoke_response.py +27 -0
  63. microsoft_agents/activity/media_card.py +57 -0
  64. microsoft_agents/activity/media_event_value.py +15 -0
  65. microsoft_agents/activity/media_url.py +19 -0
  66. microsoft_agents/activity/message_reaction.py +16 -0
  67. microsoft_agents/activity/message_reaction_types.py +14 -0
  68. microsoft_agents/activity/message_update_types.py +10 -0
  69. microsoft_agents/activity/oauth_card.py +27 -0
  70. microsoft_agents/activity/paged_members_result.py +19 -0
  71. microsoft_agents/activity/receipt_card.py +39 -0
  72. microsoft_agents/activity/receipt_item.py +38 -0
  73. microsoft_agents/activity/resource_response.py +15 -0
  74. microsoft_agents/activity/role_types.py +12 -0
  75. microsoft_agents/activity/semantic_action.py +21 -0
  76. microsoft_agents/activity/semantic_actions_states.py +10 -0
  77. microsoft_agents/activity/sign_in_constants.py +13 -0
  78. microsoft_agents/activity/sign_in_resource.py +17 -0
  79. microsoft_agents/activity/signin_card.py +19 -0
  80. microsoft_agents/activity/suggested_actions.py +21 -0
  81. microsoft_agents/activity/teams/__init__.py +198 -0
  82. microsoft_agents/activity/teams/app_based_link_query.py +18 -0
  83. microsoft_agents/activity/teams/batch_failed_entries_response.py +15 -0
  84. microsoft_agents/activity/teams/batch_failed_entry.py +16 -0
  85. microsoft_agents/activity/teams/batch_operation_response.py +13 -0
  86. microsoft_agents/activity/teams/batch_operation_state_response.py +24 -0
  87. microsoft_agents/activity/teams/bot_config_auth.py +18 -0
  88. microsoft_agents/activity/teams/cache_info.py +18 -0
  89. microsoft_agents/activity/teams/cancel_operation_response.py +19 -0
  90. microsoft_agents/activity/teams/channel_info.py +21 -0
  91. microsoft_agents/activity/teams/config_auth_response.py +17 -0
  92. microsoft_agents/activity/teams/config_response.py +18 -0
  93. microsoft_agents/activity/teams/config_response_base.py +14 -0
  94. microsoft_agents/activity/teams/config_task_response.py +18 -0
  95. microsoft_agents/activity/teams/conversation_list.py +17 -0
  96. microsoft_agents/activity/teams/file_consent_card.py +24 -0
  97. microsoft_agents/activity/teams/file_consent_card_response.py +21 -0
  98. microsoft_agents/activity/teams/file_download_info.py +24 -0
  99. microsoft_agents/activity/teams/file_info_card.py +21 -0
  100. microsoft_agents/activity/teams/file_upload_info.py +26 -0
  101. microsoft_agents/activity/teams/meeting_details.py +23 -0
  102. microsoft_agents/activity/teams/meeting_details_base.py +21 -0
  103. microsoft_agents/activity/teams/meeting_end_event_details.py +15 -0
  104. microsoft_agents/activity/teams/meeting_event_details.py +15 -0
  105. microsoft_agents/activity/teams/meeting_info.py +24 -0
  106. microsoft_agents/activity/teams/meeting_notification.py +15 -0
  107. microsoft_agents/activity/teams/meeting_notification_base.py +14 -0
  108. microsoft_agents/activity/teams/meeting_notification_channel_data.py +16 -0
  109. microsoft_agents/activity/teams/meeting_notification_recipient_failure_info.py +20 -0
  110. microsoft_agents/activity/teams/meeting_notification_response.py +20 -0
  111. microsoft_agents/activity/teams/meeting_participant_info.py +18 -0
  112. microsoft_agents/activity/teams/meeting_participants_event_details.py +16 -0
  113. microsoft_agents/activity/teams/meeting_stage_surface.py +25 -0
  114. microsoft_agents/activity/teams/meeting_start_event_details.py +15 -0
  115. microsoft_agents/activity/teams/meeting_tab_icon_surface.py +15 -0
  116. microsoft_agents/activity/teams/message_actions_payload.py +70 -0
  117. microsoft_agents/activity/teams/message_actions_payload_app.py +29 -0
  118. microsoft_agents/activity/teams/message_actions_payload_attachment.py +30 -0
  119. microsoft_agents/activity/teams/message_actions_payload_body.py +17 -0
  120. microsoft_agents/activity/teams/message_actions_payload_conversation.py +20 -0
  121. microsoft_agents/activity/teams/message_actions_payload_from.py +25 -0
  122. microsoft_agents/activity/teams/message_actions_payload_mention.py +23 -0
  123. microsoft_agents/activity/teams/message_actions_payload_reaction.py +23 -0
  124. microsoft_agents/activity/teams/message_actions_payload_user.py +27 -0
  125. microsoft_agents/activity/teams/messaging_extension_action.py +37 -0
  126. microsoft_agents/activity/teams/messaging_extension_action_response.py +24 -0
  127. microsoft_agents/activity/teams/messaging_extension_attachment.py +32 -0
  128. microsoft_agents/activity/teams/messaging_extension_parameter.py +17 -0
  129. microsoft_agents/activity/teams/messaging_extension_query.py +27 -0
  130. microsoft_agents/activity/teams/messaging_extension_query_options.py +17 -0
  131. microsoft_agents/activity/teams/messaging_extension_response.py +21 -0
  132. microsoft_agents/activity/teams/messaging_extension_result.py +34 -0
  133. microsoft_agents/activity/teams/messaging_extension_suggested_action.py +17 -0
  134. microsoft_agents/activity/teams/notification_info.py +21 -0
  135. microsoft_agents/activity/teams/o365_connector_card.py +32 -0
  136. microsoft_agents/activity/teams/o365_connector_card_action_base.py +21 -0
  137. microsoft_agents/activity/teams/o365_connector_card_action_card.py +30 -0
  138. microsoft_agents/activity/teams/o365_connector_card_action_query.py +15 -0
  139. microsoft_agents/activity/teams/o365_connector_card_date_input.py +30 -0
  140. microsoft_agents/activity/teams/o365_connector_card_fact.py +17 -0
  141. microsoft_agents/activity/teams/o365_connector_card_http_post.py +25 -0
  142. microsoft_agents/activity/teams/o365_connector_card_image.py +18 -0
  143. microsoft_agents/activity/teams/o365_connector_card_input_base.py +28 -0
  144. microsoft_agents/activity/teams/o365_connector_card_multichoice_input.py +40 -0
  145. microsoft_agents/activity/teams/o365_connector_card_multichoice_input_choice.py +17 -0
  146. microsoft_agents/activity/teams/o365_connector_card_open_uri.py +26 -0
  147. microsoft_agents/activity/teams/o365_connector_card_open_uri_target.py +17 -0
  148. microsoft_agents/activity/teams/o365_connector_card_section.py +42 -0
  149. microsoft_agents/activity/teams/o365_connector_card_text_input.py +31 -0
  150. microsoft_agents/activity/teams/o365_connector_card_view_action.py +25 -0
  151. microsoft_agents/activity/teams/on_behalf_of.py +23 -0
  152. microsoft_agents/activity/teams/read_receipt_info.py +47 -0
  153. microsoft_agents/activity/teams/signin_state_verification_query.py +14 -0
  154. microsoft_agents/activity/teams/surface.py +18 -0
  155. microsoft_agents/activity/teams/tab_context.py +14 -0
  156. microsoft_agents/activity/teams/tab_entity_context.py +15 -0
  157. microsoft_agents/activity/teams/tab_request.py +22 -0
  158. microsoft_agents/activity/teams/tab_response.py +16 -0
  159. microsoft_agents/activity/teams/tab_response_card.py +14 -0
  160. microsoft_agents/activity/teams/tab_response_cards.py +17 -0
  161. microsoft_agents/activity/teams/tab_response_payload.py +25 -0
  162. microsoft_agents/activity/teams/tab_submit.py +23 -0
  163. microsoft_agents/activity/teams/tab_submit_data.py +18 -0
  164. microsoft_agents/activity/teams/tab_suggested_actions.py +17 -0
  165. microsoft_agents/activity/teams/targeted_meeting_notification.py +19 -0
  166. microsoft_agents/activity/teams/targeted_meeting_notification_value.py +19 -0
  167. microsoft_agents/activity/teams/task_module_card_response.py +15 -0
  168. microsoft_agents/activity/teams/task_module_continue_response.py +19 -0
  169. microsoft_agents/activity/teams/task_module_message_response.py +18 -0
  170. microsoft_agents/activity/teams/task_module_request.py +25 -0
  171. microsoft_agents/activity/teams/task_module_request_context.py +15 -0
  172. microsoft_agents/activity/teams/task_module_response.py +20 -0
  173. microsoft_agents/activity/teams/task_module_response_base.py +17 -0
  174. microsoft_agents/activity/teams/task_module_task_info.py +30 -0
  175. microsoft_agents/activity/teams/team_details.py +29 -0
  176. microsoft_agents/activity/teams/team_info.py +20 -0
  177. microsoft_agents/activity/teams/teams_batch_operation_response.py +19 -0
  178. microsoft_agents/activity/teams/teams_channel_account.py +44 -0
  179. microsoft_agents/activity/teams/teams_channel_data.py +43 -0
  180. microsoft_agents/activity/teams/teams_channel_data_settings.py +15 -0
  181. microsoft_agents/activity/teams/teams_meeting_info.py +14 -0
  182. microsoft_agents/activity/teams/teams_meeting_member.py +19 -0
  183. microsoft_agents/activity/teams/teams_meeting_participant.py +24 -0
  184. microsoft_agents/activity/teams/teams_member.py +14 -0
  185. microsoft_agents/activity/teams/teams_paged_members_result.py +19 -0
  186. microsoft_agents/activity/teams/tenant_info.py +14 -0
  187. microsoft_agents/activity/teams/user_meeting_details.py +17 -0
  188. microsoft_agents/activity/text_format_types.py +10 -0
  189. microsoft_agents/activity/text_highlight.py +19 -0
  190. microsoft_agents/activity/thumbnail_card.py +33 -0
  191. microsoft_agents/activity/thumbnail_url.py +18 -0
  192. microsoft_agents/activity/token_exchange_invoke_request.py +24 -0
  193. microsoft_agents/activity/token_exchange_invoke_response.py +24 -0
  194. microsoft_agents/activity/token_exchange_resource.py +16 -0
  195. microsoft_agents/activity/token_exchange_state.py +41 -0
  196. microsoft_agents/activity/token_or_sign_in_resource_response.py +21 -0
  197. microsoft_agents/activity/token_post_resource.py +14 -0
  198. microsoft_agents/activity/token_request.py +19 -0
  199. microsoft_agents/activity/token_response.py +46 -0
  200. microsoft_agents/activity/token_status.py +32 -0
  201. microsoft_agents/activity/transcript.py +16 -0
  202. microsoft_agents/activity/turn_context_protocol.py +68 -0
  203. microsoft_agents/activity/video_card.py +57 -0
  204. microsoft_agents_activity-0.7.0.dev0.dist-info/METADATA +173 -0
  205. microsoft_agents_activity-0.7.0.dev0.dist-info/RECORD +208 -0
  206. microsoft_agents_activity-0.7.0.dev0.dist-info/WHEEL +5 -0
  207. microsoft_agents_activity-0.7.0.dev0.dist-info/licenses/LICENSE +21 -0
  208. microsoft_agents_activity-0.7.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,787 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from __future__ import annotations
5
+
6
+ import logging
7
+ from copy import copy
8
+ from datetime import datetime, timezone
9
+ from typing import Optional, Any
10
+
11
+ from pydantic import (
12
+ Field,
13
+ SerializeAsAny,
14
+ model_serializer,
15
+ model_validator,
16
+ SerializerFunctionWrapHandler,
17
+ ModelWrapValidatorHandler,
18
+ computed_field,
19
+ ValidationError,
20
+ )
21
+
22
+ from .activity_types import ActivityTypes
23
+ from .channel_account import ChannelAccount
24
+ from .conversation_account import ConversationAccount
25
+ from .message_reaction import MessageReaction
26
+ from .resource_response import ResourceResponse
27
+ from .suggested_actions import SuggestedActions
28
+ from .attachment import Attachment
29
+ from .entity import (
30
+ Entity,
31
+ EntityTypes,
32
+ Mention,
33
+ AIEntity,
34
+ ClientCitation,
35
+ ProductInfo,
36
+ SensitivityUsageInfo,
37
+ )
38
+ from .conversation_reference import ConversationReference
39
+ from .text_highlight import TextHighlight
40
+ from .semantic_action import SemanticAction
41
+ from .agents_model import AgentsModel
42
+ from .role_types import RoleTypes
43
+ from ._channel_id_field_mixin import _ChannelIdFieldMixin
44
+ from .channel_id import ChannelId
45
+ from ._model_utils import pick_model, SkipNone
46
+ from ._type_aliases import NonEmptyString
47
+ from microsoft_agents.activity.errors import activity_errors
48
+
49
+ logger = logging.getLogger(__name__)
50
+
51
+
52
+ # TODO: A2A Agent 2 is responding with None as id, had to mark it as optional (investigate)
53
+ class Activity(AgentsModel, _ChannelIdFieldMixin):
54
+ """An Activity is the basic communication type for the protocol.
55
+
56
+ :param type: Contains the activity type. Possible values include:
57
+ 'message', 'contactRelationUpdate', 'conversationUpdate', 'typing',
58
+ 'endOfConversation', 'event', 'invoke', 'deleteUserData', 'messageUpdate',
59
+ 'messageDelete', 'installationUpdate', 'messageReaction', 'suggestion',
60
+ 'trace', 'handoff'
61
+ :type type: str or ~microsoft_agents.activity.ActivityTypes
62
+ :param id: Contains an ID that uniquely identifies the activity on the channel.
63
+ :type id: str
64
+ :param timestamp: Contains the date and time that the message was sent, in UTC, expressed in ISO-8601 format.
65
+ :type timestamp: datetime
66
+ :param local_timestamp: Contains the local date and time of the message expressed in ISO-8601 format.
67
+ For example, 2016-09-23T13:07:49.4714686-07:00.
68
+ :type local_timestamp: datetime
69
+ :param local_timezone: Contains the name of the local timezone of the message, expressed in IANA Time Zone database format.
70
+ For example, America/Los_Angeles.
71
+ :type local_timezone: str
72
+ :param service_url: Contains the URL that specifies the channel's service endpoint. Set by the channel.
73
+ :type service_url: str
74
+ :param channel_id: Contains an ID that uniquely identifies the channel (and possibly the sub-channel). Set by the channel.
75
+ :type channel_id: ~microsoft_agents.activity.ChannelId
76
+ :param from_property: Identifies the sender of the message.
77
+ :type from_property: ~microsoft_agents.activity.ChannelAccount
78
+ :param conversation: Identifies the conversation to which the activity belongs.
79
+ :type conversation: ~microsoft_agents.activity.ConversationAccount
80
+ :param recipient: Identifies the recipient of the message.
81
+ :type recipient: ~microsoft_agents.activity.ChannelAccount
82
+ :param text_format: Format of text fields Default:markdown. Possible values include: 'markdown', 'plain', 'xml'
83
+ :type text_format: str or ~microsoft_agents.activity.TextFormatTypes
84
+ :param attachment_layout: The layout hint for multiple attachments. Default: list. Possible values include: 'list', 'carousel'
85
+ :type attachment_layout: str or ~microsoft_agents.activity.AttachmentLayoutTypes
86
+ :param members_added: The collection of members added to the conversation.
87
+ :type members_added: list[~microsoft_agents.activity.ChannelAccount]
88
+ :param members_removed: The collection of members removed from the conversation.
89
+ :type members_removed: list[~microsoft_agents.activity.ChannelAccount]
90
+ :param reactions_added: The collection of reactions added to the conversation.
91
+ :type reactions_added: list[~microsoft_agents.activity.MessageReaction]
92
+ :param reactions_removed: The collection of reactions removed from the conversation.
93
+ :type reactions_removed: list[~microsoft_agents.activity.MessageReaction]
94
+ :param topic_name: The updated topic name of the conversation.
95
+ :type topic_name: str
96
+ :param history_disclosed: Indicates whether the prior history of the channel is disclosed.
97
+ :type history_disclosed: bool
98
+ :param locale: A locale name for the contents of the text field. The locale name is a combination of an ISO 639 two- or three-letter
99
+ culture code associated with a language and an ISO 3166 two-letter subculture code associated with a country or region.
100
+ The locale name can also correspond to a valid BCP-47 language tag.
101
+ :type locale: str
102
+ :param text: The text content of the message.
103
+ :type text: str
104
+ :param speak: The text to speak.
105
+ :type speak: str
106
+ :param input_hint: Indicates whether your agent is accepting, expecting, or ignoring user input after the message is delivered to the client.
107
+ Possible values include: 'acceptingInput', 'ignoringInput', 'expectingInput'
108
+ :type input_hint: str or ~microsoft_agents.activity.InputHints
109
+ :param summary: The text to display if the channel cannot render cards.
110
+ :type summary: str
111
+ :param suggested_actions: The suggested actions for the activity.
112
+ :type suggested_actions: ~microsoft_agents.activity.SuggestedActions
113
+ :param attachments: Attachments
114
+ :type attachments: list[~microsoft_agents.activity.Attachment]
115
+ :param entities: Represents the entities that were mentioned in the message.
116
+ :type entities: list[~microsoft_agents.activity.Entity]
117
+ :param channel_data: Contains channel-specific content.
118
+ :type channel_data: object
119
+ :param action: Indicates whether the recipient of a contactRelationUpdate was added or removed from the sender's contact list.
120
+ :type action: str
121
+ :param reply_to_id: Contains the ID of the message to which this message is a reply.
122
+ :type reply_to_id: str
123
+ :param label: A descriptive label for the activity.
124
+ :type label: str
125
+ :param value_type: The type of the activity's value object.
126
+ :type value_type: str
127
+ :param value: A value that is associated with the activity.
128
+ :type value: object
129
+ :param name: The name of the operation associated with an invoke or event activity.
130
+ :type name: str
131
+ :param relates_to: A reference to another conversation or activity.
132
+ :type relates_to: ~microsoft_agents.activity.ConversationReference
133
+ :param code: The a code for endOfConversation activities that indicates why the conversation ended. Possible values include: 'unknown',
134
+ 'completedSuccessfully', 'userCancelled', 'botTimedOut', 'botIssuedInvalidMessage', 'channelFailed'
135
+ :type code: str or ~microsoft_agents.activity.EndOfConversationCodes
136
+ :param expiration: The time at which the activity should be considered to be "expired" and should not be presented to the recipient.
137
+ :type expiration: datetime
138
+ :param importance: The importance of the activity. Possible values include: 'low', 'normal', 'high'
139
+ :type importance: str or ~microsoft_agents.activity.ActivityImportance
140
+ :param delivery_mode: A delivery hint to signal to the recipient alternate delivery paths for the activity.
141
+ The default delivery mode is "default". Possible values include: 'normal', 'notification', 'expectReplies', 'ephemeral'
142
+ :type delivery_mode: str or ~microsoft_agents.activity.DeliveryModes
143
+ :param listen_for: List of phrases and references that speech and language priming systems should listen for
144
+ :type listen_for: list[str]
145
+ :param text_highlights: The collection of text fragments to highlight when the activity contains a ReplyToId value.
146
+ :type text_highlights: list[~microsoft_agents.activity.TextHighlight]
147
+ :param semantic_action: An optional programmatic action accompanying this request
148
+ :type semantic_action: ~microsoft_agents.activity.SemanticAction
149
+ :param caller_id: A string containing an IRI identifying the caller of an agent. This field is not intended to be transmitted over the wire,
150
+ but is instead populated by agents and clients based on cryptographically verifiable data that asserts the identity of the callers (e.g. tokens).
151
+ :type caller_id: str
152
+ """
153
+
154
+ type: NonEmptyString
155
+ id: Optional[NonEmptyString] = None
156
+ timestamp: datetime = None
157
+ local_timestamp: datetime = None
158
+ local_timezone: NonEmptyString = None
159
+ service_url: NonEmptyString = None
160
+ from_property: ChannelAccount = Field(None, alias="from")
161
+ conversation: ConversationAccount = None
162
+ recipient: ChannelAccount = None
163
+ text_format: NonEmptyString = None
164
+ attachment_layout: NonEmptyString = None
165
+ members_added: list[ChannelAccount] = None
166
+ members_removed: list[ChannelAccount] = None
167
+ reactions_added: list[MessageReaction] = None
168
+ reactions_removed: list[MessageReaction] = None
169
+ topic_name: NonEmptyString = None
170
+ history_disclosed: bool = None
171
+ locale: NonEmptyString = None
172
+ text: str = None
173
+ speak: str = None
174
+ input_hint: NonEmptyString = None
175
+ summary: NonEmptyString = None
176
+ suggested_actions: SuggestedActions = None
177
+ attachments: list[Attachment] = None
178
+ entities: list[SerializeAsAny[Entity]] = None
179
+ channel_data: object = None
180
+ action: NonEmptyString = None
181
+ reply_to_id: NonEmptyString = None
182
+ label: NonEmptyString = None
183
+ value_type: NonEmptyString = None
184
+ value: object = None
185
+ name: NonEmptyString = None
186
+ relates_to: ConversationReference = None
187
+ code: NonEmptyString = None
188
+ expiration: datetime = None
189
+ importance: NonEmptyString = None
190
+ delivery_mode: NonEmptyString = None
191
+ listen_for: list[NonEmptyString] = None
192
+ text_highlights: list[TextHighlight] = None
193
+ semantic_action: SemanticAction = None
194
+ caller_id: NonEmptyString = None
195
+
196
+ @model_validator(mode="wrap")
197
+ @classmethod
198
+ def _validate_channel_id(
199
+ cls, data: Any, handler: ModelWrapValidatorHandler[Activity]
200
+ ) -> Activity:
201
+ """Validate the Activity, ensuring consistency between channel_id.sub_channel and productInfo entity.
202
+
203
+ :param data: The input data to validate.
204
+ :param handler: The validation handler provided by Pydantic.
205
+ :return: The validated Activity instance.
206
+ """
207
+ try:
208
+ # run Pydantic's standard validation first
209
+ activity = handler(data)
210
+
211
+ # needed to assign to a computed field
212
+ # needed because we override the mixin validator
213
+ activity._set_validated_channel_id(data)
214
+
215
+ # sync sub_channel with productInfo entity
216
+ product_info = activity.get_product_info_entity()
217
+ if product_info and activity.channel_id:
218
+ if (
219
+ activity.channel_id.sub_channel
220
+ and activity.channel_id.sub_channel != product_info.id
221
+ ):
222
+ raise Exception(str(activity_errors.ChannelIdProductInfoConflict))
223
+ activity.channel_id = ChannelId(
224
+ channel=activity.channel_id.channel,
225
+ sub_channel=product_info.id,
226
+ )
227
+
228
+ return activity
229
+ except ValidationError as exc:
230
+ logger.error("Validation error for Activity: %s", exc, exc_info=True)
231
+ raise
232
+
233
+ @model_serializer(mode="wrap")
234
+ def _serialize_sub_channel_data(
235
+ self, handler: SerializerFunctionWrapHandler
236
+ ) -> dict[str, object]:
237
+ """Serialize the Activity, ensuring consistency between channel_id.sub_channel and productInfo entity.
238
+
239
+ :param handler: The serialization handler provided by Pydantic.
240
+ :return: A dictionary representing the serialized Activity.
241
+ """
242
+
243
+ # run Pydantic's standard serialization first
244
+ serialized = handler(self)
245
+ if not self: # serialization can be called with None
246
+ return serialized
247
+
248
+ # find the ProductInfo entity
249
+ product_info = None
250
+ for i, entity in enumerate(serialized.get("entities") or []):
251
+ if entity.get("type", "") == EntityTypes.PRODUCT_INFO:
252
+ product_info = entity
253
+ break
254
+
255
+ # self.channel_id is the source of truth for serialization
256
+ if self.channel_id and self.channel_id.sub_channel:
257
+ if product_info and product_info.get("id") != self.channel_id.sub_channel:
258
+ raise Exception(str(activity_errors.ChannelIdProductInfoConflict))
259
+ elif not product_info:
260
+ if not serialized.get("entities"):
261
+ serialized["entities"] = []
262
+ serialized["entities"].append(
263
+ {
264
+ "type": EntityTypes.PRODUCT_INFO,
265
+ "id": self.channel_id.sub_channel,
266
+ }
267
+ )
268
+
269
+ # simply serialized channelId value in Activity and relatesTo
270
+ if "channelId" in serialized:
271
+ serialized["channelId"] = self.channel_id.channel
272
+ elif "channel_id" in serialized:
273
+ serialized["channel_id"] = self.channel_id.channel
274
+
275
+ elif product_info: # remove productInfo entity if sub_channel is not set
276
+ del serialized["entities"][i]
277
+ if not serialized["entities"]: # after removal above, list may be empty
278
+ del serialized["entities"]
279
+
280
+ # necessary due to computed_field serialization
281
+ self._remove_serialized_unset_channel_id(serialized)
282
+
283
+ return serialized
284
+
285
+ def apply_conversation_reference(
286
+ self, reference: ConversationReference, is_incoming: bool = False
287
+ ):
288
+ """
289
+ Updates this activity with the delivery information from an existing ConversationReference.
290
+
291
+ :param reference: The existing conversation reference.
292
+ :param is_incoming: Optional, True to treat the activity as an incoming activity, where the agent is the recipient; otherwise, False.
293
+ Default is False, and the activity will show the agent as the sender.
294
+
295
+ :returns: This activity, updated with the delivery information.
296
+
297
+ .. remarks::
298
+ Call GetConversationReference on an incoming activity to get a conversation reference that you can then use to update an
299
+ outgoing activity with the correct delivery information.
300
+ """
301
+ self.channel_id = reference.channel_id
302
+ self.service_url = reference.service_url
303
+ self.conversation = reference.conversation
304
+
305
+ if reference.locale is not None:
306
+ self.locale = reference.locale
307
+
308
+ if is_incoming:
309
+ self.from_property = reference.user
310
+ self.recipient = reference.agent
311
+
312
+ if reference.activity_id is not None:
313
+ self.id = reference.activity_id
314
+ else:
315
+ self.from_property = reference.agent
316
+ self.recipient = reference.user
317
+
318
+ if reference.activity_id is not None:
319
+ self.reply_to_id = reference.activity_id
320
+
321
+ return self
322
+
323
+ def as_contact_relation_update_activity(self):
324
+ """
325
+ Returns this activity as a ContactRelationUpdateActivity object; or None, if this is not that type of activity.
326
+
327
+ :returns: This activity as a message activity; or None.
328
+ """
329
+ return (
330
+ self if self.__is_activity(ActivityTypes.contact_relation_update) else None
331
+ )
332
+
333
+ def as_conversation_update_activity(self):
334
+ """
335
+ Returns this activity as a ConversationUpdateActivity object; or None, if this is not that type of activity.
336
+
337
+ :returns: This activity as a conversation update activity; or None.
338
+ """
339
+ return self if self.__is_activity(ActivityTypes.conversation_update) else None
340
+
341
+ def as_end_of_conversation_activity(self):
342
+ """
343
+ Returns this activity as an EndOfConversationActivity object; or None, if this is not that type of activity.
344
+
345
+ :returns: This activity as an end of conversation activity; or None.
346
+ """
347
+ return self if self.__is_activity(ActivityTypes.end_of_conversation) else None
348
+
349
+ def as_event_activity(self):
350
+ """
351
+ Returns this activity as an EventActivity object; or None, if this is not that type of activity.
352
+
353
+ :returns: This activity as an event activity; or None.
354
+ """
355
+ return self if self.__is_activity(ActivityTypes.event) else None
356
+
357
+ def as_handoff_activity(self):
358
+ """
359
+ Returns this activity as a HandoffActivity object; or None, if this is not that type of activity.
360
+
361
+ :returns: This activity as a handoff activity; or None.
362
+ """
363
+ return self if self.__is_activity(ActivityTypes.handoff) else None
364
+
365
+ def as_installation_update_activity(self):
366
+ """
367
+ Returns this activity as an InstallationUpdateActivity object; or None, if this is not that type of activity.
368
+
369
+ :returns: This activity as an installation update activity; or None.
370
+ """
371
+ return self if self.__is_activity(ActivityTypes.installation_update) else None
372
+
373
+ def as_invoke_activity(self):
374
+ """
375
+ Returns this activity as an InvokeActivity object; or None, if this is not that type of activity.
376
+
377
+ :returns: This activity as an invoke activity; or None.
378
+ """
379
+ return self if self.__is_activity(ActivityTypes.invoke) else None
380
+
381
+ def as_message_activity(self):
382
+ """
383
+ Returns this activity as a MessageActivity object; or None, if this is not that type of activity.
384
+
385
+ :returns: This activity as a message activity; or None.
386
+ """
387
+ return self if self.__is_activity(ActivityTypes.message) else None
388
+
389
+ def as_message_delete_activity(self):
390
+ """
391
+ Returns this activity as a MessageDeleteActivity object; or None, if this is not that type of activity.
392
+
393
+ :returns: This activity as a message delete request; or None.
394
+ """
395
+ return self if self.__is_activity(ActivityTypes.message_delete) else None
396
+
397
+ def as_message_reaction_activity(self):
398
+ """
399
+ Returns this activity as a MessageReactionActivity object; or None, if this is not that type of activity.
400
+
401
+ :return: This activity as a message reaction activity; or None.
402
+ """
403
+ return self if self.__is_activity(ActivityTypes.message_reaction) else None
404
+
405
+ def as_message_update_activity(self):
406
+ """
407
+ Returns this activity as an MessageUpdateActivity object; or None, if this is not that type of activity.
408
+
409
+ :returns: This activity as a message update request; or None.
410
+ """
411
+ return self if self.__is_activity(ActivityTypes.message_update) else None
412
+
413
+ def as_suggestion_activity(self):
414
+ """
415
+ Returns this activity as a SuggestionActivity object; or None, if this is not that type of activity.
416
+
417
+ :returns: This activity as a suggestion activity; or None.
418
+ """
419
+ return self if self.__is_activity(ActivityTypes.suggestion) else None
420
+
421
+ def as_trace_activity(self):
422
+ """
423
+ Returns this activity as a TraceActivity object; or None, if this is not that type of activity.
424
+
425
+ :returns: This activity as a trace activity; or None.
426
+ """
427
+ return self if self.__is_activity(ActivityTypes.trace) else None
428
+
429
+ def as_typing_activity(self):
430
+ """
431
+ Returns this activity as a TypingActivity object; or null, if this is not that type of activity.
432
+
433
+ :returns: This activity as a typing activity; or null.
434
+ """
435
+ return self if self.__is_activity(ActivityTypes.typing) else None
436
+
437
+ @staticmethod
438
+ def create_contact_relation_update_activity():
439
+ """
440
+ Creates an instance of the :class:`Activity` class as a ContactRelationUpdateActivity object.
441
+
442
+ :returns: The new contact relation update activity.
443
+ """
444
+ return Activity(type=ActivityTypes.contact_relation_update)
445
+
446
+ @staticmethod
447
+ def create_conversation_update_activity():
448
+ """
449
+ Creates an instance of the :class:`Activity` class as a ConversationUpdateActivity object.
450
+
451
+ :returns: The new conversation update activity.
452
+ """
453
+ return Activity(type=ActivityTypes.conversation_update)
454
+
455
+ @staticmethod
456
+ def create_end_of_conversation_activity():
457
+ """
458
+ Creates an instance of the :class:`Activity` class as an EndOfConversationActivity object.
459
+
460
+ :returns: The new end of conversation activity.
461
+ """
462
+ return Activity(type=ActivityTypes.end_of_conversation)
463
+
464
+ @staticmethod
465
+ def create_event_activity():
466
+ """
467
+ Creates an instance of the :class:`Activity` class as an EventActivity object.
468
+
469
+ :returns: The new event activity.
470
+ """
471
+ return Activity(type=ActivityTypes.event)
472
+
473
+ @staticmethod
474
+ def create_handoff_activity():
475
+ """
476
+ Creates an instance of the :class:`Activity` class as a HandoffActivity object.
477
+
478
+ :returns: The new handoff activity.
479
+ """
480
+ return Activity(type=ActivityTypes.handoff)
481
+
482
+ @staticmethod
483
+ def create_invoke_activity():
484
+ """
485
+ Creates an instance of the :class:`Activity` class as an InvokeActivity object.
486
+
487
+ :returns: The new invoke activity.
488
+ """
489
+ return Activity(type=ActivityTypes.invoke)
490
+
491
+ @staticmethod
492
+ def create_message_activity():
493
+ """
494
+ Creates an instance of the :class:`Activity` class as a MessageActivity object.
495
+
496
+ :returns: The new message activity.
497
+ """
498
+ return Activity(type=ActivityTypes.message)
499
+
500
+ def create_reply(self, text: str = None, locale: str = None):
501
+ """
502
+ Creates a new message activity as a response to this activity.
503
+
504
+ :param text: The text of the reply.
505
+ :param locale: The language code for the text.
506
+
507
+ :returns: The new message activity.
508
+
509
+ .. remarks::
510
+ The new activity sets up routing information based on this activity.
511
+ """
512
+ return pick_model(
513
+ Activity,
514
+ type=ActivityTypes.message,
515
+ timestamp=datetime.now(timezone.utc),
516
+ from_property=SkipNone(
517
+ ChannelAccount.pick_properties(self.recipient, ["id", "name"])
518
+ ),
519
+ recipient=SkipNone(
520
+ ChannelAccount.pick_properties(self.from_property, ["id", "name"])
521
+ ),
522
+ reply_to_id=(
523
+ SkipNone(self.id)
524
+ if type != ActivityTypes.conversation_update
525
+ or self.channel_id not in ["directline", "webchat"]
526
+ else None
527
+ ),
528
+ service_url=self.service_url,
529
+ channel_id=self.channel_id,
530
+ conversation=SkipNone(
531
+ ConversationAccount.pick_properties(
532
+ self.conversation, ["is_group", "id", "name"]
533
+ )
534
+ ),
535
+ text=text if text else "",
536
+ locale=locale if locale else SkipNone(self.locale),
537
+ attachments=[],
538
+ entities=[],
539
+ )
540
+
541
+ def create_trace(
542
+ self, name: str, value: object = None, value_type: str = None, label: str = None
543
+ ):
544
+ """
545
+ Creates a new trace activity based on this activity.
546
+
547
+ :param name: The name of the trace operation to create.
548
+ :param value: Optional, the content for this trace operation.
549
+ :param value_type: Optional, identifier for the format of the value. Default is the name of type of the value.
550
+ :param label: Optional, a descriptive label for this trace operation.
551
+
552
+ :returns: The new trace activity.
553
+ """
554
+ if not value_type and value:
555
+ value_type = type(value).__name__
556
+
557
+ return pick_model(
558
+ Activity,
559
+ type=ActivityTypes.trace,
560
+ timestamp=datetime.now(timezone.utc),
561
+ from_property=SkipNone(
562
+ ChannelAccount.pick_properties(self.recipient, ["id", "name"])
563
+ ),
564
+ recipient=SkipNone(
565
+ ChannelAccount.pick_properties(self.from_property, ["id", "name"])
566
+ ),
567
+ reply_to_id=(
568
+ SkipNone(self.id) # preserve unset
569
+ if type != ActivityTypes.conversation_update
570
+ or self.channel_id not in ["directline", "webchat"]
571
+ else None
572
+ ),
573
+ service_url=self.service_url,
574
+ channel_id=self.channel_id,
575
+ conversation=SkipNone(
576
+ ConversationAccount.pick_properties(
577
+ self.conversation, ["is_group", "id", "name"]
578
+ )
579
+ ),
580
+ name=SkipNone(name),
581
+ label=SkipNone(label),
582
+ value_type=SkipNone(value_type),
583
+ value=SkipNone(value),
584
+ ).as_trace_activity()
585
+
586
+ @staticmethod
587
+ def create_trace_activity(
588
+ name: str, value: object = None, value_type: str = None, label: str = None
589
+ ):
590
+ """
591
+ Creates an instance of the :class:`Activity` class as a TraceActivity object.
592
+
593
+ :param name: The name of the trace operation to create.
594
+ :param value: Optional, the content for this trace operation.
595
+ :param value_type: Optional, identifier for the format of the value. Default is the name of type of the value.
596
+ :param label: Optional, a descriptive label for this trace operation.
597
+
598
+ :returns: The new trace activity.
599
+ """
600
+ if not value_type and value:
601
+ value_type = type(value).__name__
602
+
603
+ return pick_model(
604
+ Activity,
605
+ type=ActivityTypes.trace,
606
+ name=name,
607
+ label=SkipNone(label),
608
+ value_type=SkipNone(value_type),
609
+ value=SkipNone(value),
610
+ )
611
+
612
+ @staticmethod
613
+ def create_typing_activity() -> "Activity":
614
+ """
615
+ Creates an instance of the :class:`Activity` class as a TypingActivity object.
616
+
617
+ :returns: The new typing activity.
618
+ """
619
+ return Activity(type=ActivityTypes.typing)
620
+
621
+ def get_conversation_reference(self) -> ConversationReference:
622
+ """
623
+ Creates a ConversationReference based on this activity.
624
+
625
+ :returns: A conversation reference for the conversation that contains this activity.
626
+ """
627
+ return pick_model(
628
+ ConversationReference,
629
+ activity_id=(
630
+ SkipNone(self.id)
631
+ if self.type != ActivityTypes.conversation_update
632
+ or self.channel_id not in ["directline", "webchat"]
633
+ else None
634
+ ),
635
+ user=copy(self.from_property),
636
+ agent=copy(self.recipient),
637
+ conversation=copy(self.conversation),
638
+ channel_id=self.channel_id,
639
+ locale=self.locale,
640
+ service_url=self.service_url,
641
+ )
642
+
643
+ def get_product_info_entity(self) -> Optional[ProductInfo]:
644
+ if not self.entities:
645
+ return None
646
+ target = EntityTypes.PRODUCT_INFO.lower()
647
+ # validated entities can be Entity, and that prevents us from
648
+ # making assumptions about the casing of the 'type' attribute
649
+ return next(filter(lambda e: e.type.lower() == target, self.entities), None)
650
+
651
+ def get_mentions(self) -> list[Mention]:
652
+ """
653
+ Resolves the mentions from the entities of this activity.
654
+
655
+ :returns: The array of mentions; or an empty array, if none are found.
656
+
657
+ .. remarks::
658
+ This method is defined on the :class:`Activity` class, but is only intended for use with a message activity,
659
+ where the activity Activity.Type is set to ActivityTypes.Message.
660
+ """
661
+ if not self.entities:
662
+ return []
663
+ return [x for x in self.entities if x.type.lower() == EntityTypes.MENTION]
664
+
665
+ def get_reply_conversation_reference(
666
+ self, reply: ResourceResponse
667
+ ) -> ConversationReference:
668
+ """
669
+ Create a ConversationReference based on this Activity's Conversation info and the ResourceResponse from sending an activity.
670
+
671
+ :param reply: ResourceResponse returned from send_activity.
672
+
673
+ :return: A ConversationReference that can be stored and used later to delete or update the activity.
674
+ """
675
+ reference = self.get_conversation_reference()
676
+ reference.activity_id = reply.id
677
+ return reference
678
+
679
+ def has_content(self) -> bool:
680
+ """
681
+ Indicates whether this activity has content.
682
+
683
+ :returns: True, if this activity has any content to send; otherwise, false.
684
+
685
+ .. remarks::
686
+ This method is defined on the :class:`Activity` class, but is only intended for use with a message activity,
687
+ where the activity Activity.Type is set to ActivityTypes.Message.
688
+ """
689
+ if self.text and self.text.strip():
690
+ return True
691
+
692
+ if self.summary and self.summary.strip():
693
+ return True
694
+
695
+ if self.attachments and len(self.attachments) > 0:
696
+ return True
697
+
698
+ if self.channel_data:
699
+ return True
700
+
701
+ return False
702
+
703
+ def is_from_streaming_connection(self) -> bool:
704
+ """
705
+ Determine if the Activity was sent via an Http/Https connection or Streaming.
706
+ This can be determined by looking at the service_url property:
707
+ (1) All channels that send messages via http/https are not streaming.
708
+ (2) Channels that send messages via streaming have a ServiceUrl that does not begin with http/https.
709
+
710
+ :returns: True if the Activity originated from a streaming connection.
711
+ """
712
+ if self.service_url:
713
+ return not self.service_url.lower().startswith("http")
714
+ return False
715
+
716
+ def __is_activity(self, activity_type: str) -> bool:
717
+ """
718
+ Indicates whether this activity is of a specified activity type.
719
+
720
+ :param activity_type: The activity type to check for.
721
+ :return: True if this activity is of the specified activity type; otherwise, False.
722
+ """
723
+ if self.type is None:
724
+ return False
725
+
726
+ type_attribute = f"ActivityTypes.{str(self.type)}".lower()
727
+ activity_type = str(activity_type).lower()
728
+
729
+ result = type_attribute.startswith(activity_type)
730
+
731
+ if result:
732
+ result = len(type_attribute) == len(activity_type)
733
+
734
+ if not result:
735
+ result = (
736
+ len(type_attribute) > len(activity_type)
737
+ and type_attribute[len(activity_type)] == "/"
738
+ )
739
+
740
+ return result
741
+
742
+ def add_ai_metadata(
743
+ self,
744
+ citations: Optional[list[ClientCitation]] = None,
745
+ usage_info: Optional[SensitivityUsageInfo] = None,
746
+ ) -> None:
747
+ """
748
+ Adds AI entity to an activity to indicate AI-generated content.
749
+
750
+ Args:
751
+ activity: The activity to modify
752
+ citations: Optional list of citations
753
+ usage_info: Optional sensitivity usage information
754
+ """
755
+ if citations:
756
+ ai_entity = AIEntity(
757
+ type="https://schema.org/Message",
758
+ schema_type="Message",
759
+ context="https://schema.org",
760
+ id="",
761
+ additional_type=["AIGeneratedContent"],
762
+ citation=citations,
763
+ usage_info=usage_info,
764
+ )
765
+
766
+ if self.entities is None:
767
+ self.entities = []
768
+
769
+ self.entities.append(ai_entity)
770
+
771
+ def is_agentic_request(self) -> bool:
772
+ return self.recipient and self.recipient.role in [
773
+ RoleTypes.agentic_identity,
774
+ RoleTypes.agentic_user,
775
+ ]
776
+
777
+ def get_agentic_instance_id(self) -> Optional[str]:
778
+ """Gets the agent instance ID from the context if it's an agentic request."""
779
+ if not self.is_agentic_request() or not self.recipient:
780
+ return None
781
+ return self.recipient.agentic_app_id
782
+
783
+ def get_agentic_user(self) -> Optional[str]:
784
+ """Gets the agentic user (agenticUserId) from the context if it's an agentic request."""
785
+ if not self.is_agentic_request() or not self.recipient:
786
+ return None
787
+ return self.recipient.agentic_user_id