microsoft-agents-hosting-core 1.9.0.dev0__tar.gz → 1.9.0.dev3__tar.gz

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 (203) hide show
  1. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/PKG-INFO +3 -3
  2. microsoft_agents_hosting_core-1.9.0.dev3/VERSION.txt +1 -0
  3. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/__init__.py +3 -1
  4. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/_http_adapter_base.py +3 -3
  5. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/attachment_downloader.py +43 -19
  6. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/m365_attachment_downloader.py +48 -21
  7. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/streaming/streaming_response.py +44 -18
  8. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/client/connector_client.py +5 -6
  9. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/client/user_token_client.py +5 -7
  10. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/mcs/mcs_connector_client.py +8 -0
  11. microsoft_agents_hosting_core-1.9.0.dev3/microsoft_agents/hosting/core/security/__init__.py +14 -0
  12. microsoft_agents_hosting_core-1.9.0.dev3/microsoft_agents/hosting/core/security/_connector.py +58 -0
  13. microsoft_agents_hosting_core-1.9.0.dev3/microsoft_agents/hosting/core/security/_middleware.py +31 -0
  14. microsoft_agents_hosting_core-1.9.0.dev3/microsoft_agents/hosting/core/security/_utils.py +76 -0
  15. microsoft_agents_hosting_core-1.9.0.dev3/microsoft_agents/hosting/core/security/_validator.py +35 -0
  16. microsoft_agents_hosting_core-1.9.0.dev3/microsoft_agents/hosting/core/security/outbound_host_validator.py +242 -0
  17. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents_hosting_core.egg-info/PKG-INFO +3 -3
  18. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents_hosting_core.egg-info/SOURCES.txt +6 -1
  19. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents_hosting_core.egg-info/requires.txt +2 -2
  20. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/setup.py +1 -1
  21. microsoft_agents_hosting_core-1.9.0.dev0/VERSION.txt +0 -1
  22. microsoft_agents_hosting_core-1.9.0.dev0/microsoft_agents/hosting/core/outbound_host_validator.py +0 -117
  23. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/LICENSE +0 -0
  24. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/MANIFEST.in +0 -0
  25. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/_oauth/__init__.py +0 -0
  26. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/_oauth/_flow_state.py +0 -0
  27. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/_oauth/_flow_storage_client.py +0 -0
  28. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/_oauth/_oauth_flow.py +0 -0
  29. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/_utils/__init__.py +0 -0
  30. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/_utils/_service_set.py +0 -0
  31. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/activity_handler.py +0 -0
  32. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/agent.py +0 -0
  33. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/__init__.py +0 -0
  34. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/_routes/__init__.py +0 -0
  35. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/_routes/_route.py +0 -0
  36. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/_routes/_route_list.py +0 -0
  37. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/_routes/route_rank.py +0 -0
  38. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/_type_defs.py +0 -0
  39. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/_utils.py +0 -0
  40. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/adaptive_card/__init__.py +0 -0
  41. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/adaptive_card/_type_defs.py +0 -0
  42. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/adaptive_card/adaptive_card.py +0 -0
  43. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/adaptive_card/factory.py +0 -0
  44. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/adaptive_card/models.py +0 -0
  45. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/agent_application.py +0 -0
  46. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/app_error.py +0 -0
  47. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/app_options.py +0 -0
  48. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/input_file.py +0 -0
  49. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/__init__.py +0 -0
  50. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/_handlers/__init__.py +0 -0
  51. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/_handlers/_authorization_handler.py +0 -0
  52. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/_handlers/_user_authorization.py +0 -0
  53. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py +0 -0
  54. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/_handlers/connector_user_authorization.py +0 -0
  55. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/_sign_in_response.py +0 -0
  56. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/_sign_in_state.py +0 -0
  57. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/auth_handler.py +0 -0
  58. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/authorization.py +0 -0
  59. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/telemetry/__init__.py +0 -0
  60. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/telemetry/constants.py +0 -0
  61. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/oauth/telemetry/spans.py +0 -0
  62. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/__init__.py +0 -0
  63. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/conversation.py +0 -0
  64. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/conversation_builder.py +0 -0
  65. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/conversation_reference_builder.py +0 -0
  66. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/create_conversation_options.py +0 -0
  67. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/proactive.py +0 -0
  68. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/proactive_options.py +0 -0
  69. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/telemetry/__init__.py +0 -0
  70. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/telemetry/_utils.py +0 -0
  71. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/telemetry/constants.py +0 -0
  72. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/proactive/telemetry/spans.py +0 -0
  73. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/query.py +0 -0
  74. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/state/__init__.py +0 -0
  75. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/state/conversation_state.py +0 -0
  76. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/state/state.py +0 -0
  77. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/state/temp_state.py +0 -0
  78. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/state/turn_state.py +0 -0
  79. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/streaming/__init__.py +0 -0
  80. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/streaming/citation.py +0 -0
  81. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/streaming/citation_util.py +0 -0
  82. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/telemetry/__init__.py +0 -0
  83. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/telemetry/constants.py +0 -0
  84. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/telemetry/metrics.py +0 -0
  85. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/telemetry/spans.py +0 -0
  86. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/app/typing_indicator.py +0 -0
  87. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/__init__.py +0 -0
  88. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/_entra_issuers.py +0 -0
  89. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/_helpers.py +0 -0
  90. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/_log_config.py +0 -0
  91. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/access_token_provider_base.py +0 -0
  92. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/agent_auth_configuration.py +0 -0
  93. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/anonymous_token_provider.py +0 -0
  94. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/auth_types.py +0 -0
  95. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/authentication_constants.py +0 -0
  96. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/claims_identity.py +0 -0
  97. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/connection_manager.py +0 -0
  98. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/connection_settings_base.py +0 -0
  99. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/connections.py +0 -0
  100. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/jwt/__init__.py +0 -0
  101. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/jwt/_authorize_request.py +0 -0
  102. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/jwt/jwt_token_validator.py +0 -0
  103. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/telemetry/__init__.py +0 -0
  104. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/telemetry/constants.py +0 -0
  105. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/telemetry/metrics.py +0 -0
  106. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/authorization/telemetry/spans.py +0 -0
  107. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/card_factory.py +0 -0
  108. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/channel_adapter.py +0 -0
  109. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/channel_api_handler_protocol.py +0 -0
  110. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/channel_service_adapter.py +0 -0
  111. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/channel_service_client_factory_base.py +0 -0
  112. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/__init__.py +0 -0
  113. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/agent_conversation_reference.py +0 -0
  114. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/channel_factory_protocol.py +0 -0
  115. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/channel_host_protocol.py +0 -0
  116. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/channel_info_protocol.py +0 -0
  117. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/channel_protocol.py +0 -0
  118. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/channels_configuration.py +0 -0
  119. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/configuration_channel_host.py +0 -0
  120. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/conversation_constants.py +0 -0
  121. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/conversation_id_factory.py +0 -0
  122. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/conversation_id_factory_options.py +0 -0
  123. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/conversation_id_factory_protocol.py +0 -0
  124. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/http_agent_channel.py +0 -0
  125. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/client/http_agent_channel_factory.py +0 -0
  126. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/__init__.py +0 -0
  127. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/_utils.py +0 -0
  128. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/agent_sign_in_base.py +0 -0
  129. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/attachments_base.py +0 -0
  130. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/client/__init__.py +0 -0
  131. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/client/_base_client.py +0 -0
  132. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/client/agent_sign_in.py +0 -0
  133. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/client/user_token.py +0 -0
  134. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/connector_client_base.py +0 -0
  135. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/conversations_base.py +0 -0
  136. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/get_product_info.py +0 -0
  137. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/mcs/__init__.py +0 -0
  138. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/teams/__init__.py +0 -0
  139. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/teams/teams_connector_client.py +0 -0
  140. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/telemetry/__init__.py +0 -0
  141. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/telemetry/_request_span_wrapper.py +0 -0
  142. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/telemetry/connector_spans.py +0 -0
  143. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/telemetry/constants.py +0 -0
  144. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/telemetry/metrics.py +0 -0
  145. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/telemetry/user_token_client_spans.py +0 -0
  146. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/user_token_base.py +0 -0
  147. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/connector/user_token_client_base.py +0 -0
  148. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/errors/__init__.py +0 -0
  149. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/errors/error_resources.py +0 -0
  150. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/header_propagation/__init__.py +0 -0
  151. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/header_propagation/agentic_header_provider.py +0 -0
  152. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/header_propagation/header_propagation_context.py +0 -0
  153. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/header_propagation/header_value_provider.py +0 -0
  154. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/http/__init__.py +0 -0
  155. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/http/_channel_service_routes.py +0 -0
  156. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/http/_http_request_protocol.py +0 -0
  157. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/http/_http_response.py +0 -0
  158. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/message_factory.py +0 -0
  159. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/middleware_set.py +0 -0
  160. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/py.typed +0 -0
  161. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/rest_channel_service_client_factory.py +0 -0
  162. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/state/__init__.py +0 -0
  163. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/state/agent_state.py +0 -0
  164. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/state/state_property_accessor.py +0 -0
  165. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/state/user_state.py +0 -0
  166. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/__init__.py +0 -0
  167. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/_type_aliases.py +0 -0
  168. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/error_handling.py +0 -0
  169. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/memory_storage.py +0 -0
  170. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/storage.py +0 -0
  171. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/store_item.py +0 -0
  172. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/telemetry/__init__.py +0 -0
  173. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/telemetry/constants.py +0 -0
  174. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/telemetry/metrics.py +0 -0
  175. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/telemetry/spans.py +0 -0
  176. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/transcript/__init__.py +0 -0
  177. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/transcript/transcript_file_store.py +0 -0
  178. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/transcript/transcript_info.py +0 -0
  179. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/transcript/transcript_logger.py +0 -0
  180. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/transcript/transcript_memory_store.py +0 -0
  181. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/storage/transcript/transcript_store.py +0 -0
  182. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/__init__.py +0 -0
  183. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/adapter/__init__.py +0 -0
  184. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/adapter/constants.py +0 -0
  185. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/adapter/metrics.py +0 -0
  186. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/adapter/spans.py +0 -0
  187. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/attributes.py +0 -0
  188. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/core/__init__.py +0 -0
  189. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/core/_agents_telemetry.py +0 -0
  190. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/core/base_span_wrapper.py +0 -0
  191. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/core/resource.py +0 -0
  192. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/core/simple_span_wrapper.py +0 -0
  193. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/core/type_defs.py +0 -0
  194. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/turn_context/__init__.py +0 -0
  195. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/turn_context/constants.py +0 -0
  196. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/turn_context/spans.py +0 -0
  197. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/telemetry/utils.py +0 -0
  198. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents/hosting/core/turn_context.py +0 -0
  199. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents_hosting_core.egg-info/dependency_links.txt +0 -0
  200. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/microsoft_agents_hosting_core.egg-info/top_level.txt +0 -0
  201. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/pyproject.toml +0 -0
  202. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/readme.md +0 -0
  203. {microsoft_agents_hosting_core-1.9.0.dev0 → microsoft_agents_hosting_core-1.9.0.dev3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-hosting-core
3
- Version: 1.9.0.dev0
3
+ Version: 1.9.0.dev3
4
4
  Summary: Core library for Microsoft Agents
5
5
  Author: Microsoft Corporation
6
6
  License-Expression: MIT
@@ -15,13 +15,13 @@ Classifier: Operating System :: OS Independent
15
15
  Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: microsoft-agents-activity==1.9.0.dev0
18
+ Requires-Dist: microsoft-agents-activity==1.9.0.dev3
19
19
  Requires-Dist: pyjwt>=2.10.1
20
20
  Requires-Dist: isodate>=0.6.1
21
21
  Requires-Dist: python-dotenv>=1.1.1
22
22
  Requires-Dist: opentelemetry-api>=1.27.0
23
23
  Requires-Dist: opentelemetry-sdk>=1.27.0
24
- Requires-Dist: aiohttp>=3.11.11
24
+ Requires-Dist: aiohttp>=3.12
25
25
  Requires-Dist: yarl<2.0,>=1.17.0
26
26
  Requires-Dist: azure-core
27
27
  Dynamic: license-file
@@ -0,0 +1 @@
1
+ 1.9.0.dev3
@@ -9,7 +9,9 @@ from .message_factory import MessageFactory
9
9
  from .middleware_set import Middleware, MiddlewareSet
10
10
  from .rest_channel_service_client_factory import RestChannelServiceClientFactory
11
11
  from .turn_context import TurnContext
12
- from .outbound_host_validator import OutboundHostValidator
12
+
13
+ # Security
14
+ from .security import OutboundHostValidator
13
15
 
14
16
  # HTTP abstractions
15
17
  from .http import (
@@ -23,7 +23,7 @@ from .http._http_response import HttpResponse, HttpResponseFactory
23
23
  from .message_factory import MessageFactory
24
24
  from .rest_channel_service_client_factory import RestChannelServiceClientFactory
25
25
  from .turn_context import TurnContext
26
- from .outbound_host_validator import OutboundHostValidator, _try_create_url
26
+ from .security import OutboundHostValidator, _try_create_url
27
27
 
28
28
  logger = logging.getLogger(__name__)
29
29
 
@@ -80,7 +80,7 @@ class HttpAdapterBase(ChannelServiceAdapter, ABC):
80
80
  connection_manager,
81
81
  **(channel_service_client_factory_options or {}),
82
82
  )
83
- self._host_validator = host_validator or OutboundHostValidator()
83
+ self._host_validator = host_validator or OutboundHostValidator(enabled=False)
84
84
 
85
85
  super().__init__(factory)
86
86
 
@@ -205,7 +205,7 @@ class HttpAdapterBase(ChannelServiceAdapter, ABC):
205
205
  or not activity_url
206
206
  or claim_url_host.casefold() != activity_url_host.casefold()
207
207
  ):
208
- if self._host_validator and self._host_validator.enabled:
208
+ if self._host_validator.enabled:
209
209
  logger.warning(
210
210
  "Service URL host mismatch: %s vs %s",
211
211
  claim_url_host,
@@ -2,7 +2,8 @@
2
2
  # Licensed under the MIT License.
3
3
 
4
4
  import json
5
- from typing import Callable
5
+ import logging
6
+ from typing import Any, Callable
6
7
 
7
8
  import aiohttp
8
9
 
@@ -13,27 +14,40 @@ from microsoft_agents.activity import (
13
14
  )
14
15
 
15
16
  from microsoft_agents.hosting.core.turn_context import TurnContext
16
- from microsoft_agents.hosting.core.outbound_host_validator import OutboundHostValidator
17
+ from microsoft_agents.hosting.core.security import (
18
+ OutboundHostValidator,
19
+ _SSRFError,
20
+ )
17
21
 
18
22
  from .input_file import InputFileDownloader, InputFile
19
23
  from ._utils import _parse_content_type, _basic_url_check
20
24
 
25
+ logger = logging.getLogger(__name__)
26
+
21
27
 
22
28
  class AttachmentDownloader(InputFileDownloader):
23
29
  """Downloads attachments from a given turn context."""
24
30
 
25
31
  def __init__(
26
32
  self,
27
- client_factory: Callable[[], aiohttp.ClientSession] | None = None,
28
33
  host_validator: OutboundHostValidator | None = None,
34
+ *,
35
+ client_session_kwargs: dict | None = None,
36
+ client_factory: Any = None,
29
37
  ):
30
38
  """Constructor for AttachmentDownloader.
31
39
 
32
- :param client_factory: A callable that returns an aiohttp.ClientSession instance.
33
40
  :param host_validator: An optional OutboundHostValidator instance.
41
+ :param client_session_kwargs: Optional keyword arguments for the aiohttp.ClientSession.
42
+ :param client_factory: (deprecated) A custom client factory, if any.
34
43
  """
35
44
 
36
- self._client_factory = client_factory or aiohttp.ClientSession
45
+ if client_factory is not None:
46
+ logger.warning(
47
+ "The 'client_factory' parameter is deprecated and will be ignored."
48
+ )
49
+
50
+ self._client_session_kwargs = client_session_kwargs or {}
37
51
  self._host_validator = host_validator
38
52
 
39
53
  async def download_files(self, context: TurnContext) -> list[InputFile]:
@@ -48,31 +62,36 @@ class AttachmentDownloader(InputFileDownloader):
48
62
  if not context.activity.attachments:
49
63
  return []
50
64
 
51
- files: list[InputFile] = []
52
- for attachment in context.activity.attachments:
53
- file = await self._download_file(attachment)
54
- if file:
55
- files.append(file)
65
+ client_factory: Callable[[], aiohttp.ClientSession]
66
+ if self._host_validator is not None:
67
+ host_validator = self._host_validator # to capture in lambda
68
+ client_factory = lambda: host_validator.client(self._client_session_kwargs)
69
+ else:
70
+ client_factory = lambda: aiohttp.ClientSession(
71
+ **self._client_session_kwargs
72
+ )
56
73
 
74
+ async with client_factory() as client:
75
+ files: list[InputFile] = []
76
+ for attachment in context.activity.attachments:
77
+ file = await self._download_file(client, attachment)
78
+ if file:
79
+ files.append(file)
57
80
  return files
58
81
 
59
- async def _download_file(self, attachment: Attachment) -> InputFile | None:
82
+ async def _download_file(
83
+ self, client: aiohttp.ClientSession, attachment: Attachment
84
+ ) -> InputFile | None:
60
85
  """Downloads a single file from the given attachment.
61
86
 
87
+ :param client: The aiohttp.ClientSession instance to use for downloading the file.
62
88
  :param attachment: The attachment to download.
63
89
  :return: An InputFile instance if the download is successful, None otherwise.
64
90
  """
65
91
  if attachment.content_url and _basic_url_check(attachment.content_url):
66
92
  remote_file_url = attachment.content_url
67
93
 
68
- if (
69
- self._host_validator
70
- and self._host_validator.enabled
71
- and not self._host_validator.is_allowed(remote_file_url)
72
- ):
73
- return None
74
-
75
- async with self._client_factory() as client:
94
+ try:
76
95
  async with client.get(remote_file_url) as response:
77
96
 
78
97
  if not (200 <= response.status < 300):
@@ -94,6 +113,11 @@ class AttachmentDownloader(InputFileDownloader):
94
113
  content_url=attachment.content_url,
95
114
  filename=attachment.name,
96
115
  )
116
+ except _SSRFError:
117
+ logger.warning(
118
+ "Outbound host validation failed for an attachment download URL."
119
+ )
120
+ return None
97
121
  else:
98
122
  content = bytes(json.dumps(attachment.content), "utf-8")
99
123
  return InputFile(
@@ -2,6 +2,9 @@
2
2
  # Licensed under the MIT License.
3
3
 
4
4
  import json
5
+ import logging
6
+ import warnings
7
+
5
8
  from typing import Callable, cast, Any
6
9
 
7
10
  import aiohttp
@@ -9,7 +12,6 @@ import aiohttp
9
12
  from microsoft_agents.activity import (
10
13
  Attachment,
11
14
  Channels,
12
- ChannelId,
13
15
  )
14
16
 
15
17
  from microsoft_agents.hosting.core.authorization import (
@@ -17,11 +19,16 @@ from microsoft_agents.hosting.core.authorization import (
17
19
  Connections,
18
20
  )
19
21
  from microsoft_agents.hosting.core.turn_context import TurnContext
20
- from microsoft_agents.hosting.core.outbound_host_validator import OutboundHostValidator
22
+ from microsoft_agents.hosting.core.security import (
23
+ OutboundHostValidator,
24
+ _SSRFError,
25
+ )
21
26
 
22
27
  from .input_file import InputFileDownloader, InputFile
23
28
  from ._utils import _parse_content_type, _basic_url_check
24
29
 
30
+ logger = logging.getLogger(__name__)
31
+
25
32
 
26
33
  class M365AttachmentDownloader(InputFileDownloader):
27
34
  """Downloads attachments from M365/Teams using the configured Token Provider (from Connections)."""
@@ -29,27 +36,35 @@ class M365AttachmentDownloader(InputFileDownloader):
29
36
  def __init__(
30
37
  self,
31
38
  connections: Connections,
32
- client_factory: Callable[[], aiohttp.ClientSession] | None = None,
33
39
  host_validator: OutboundHostValidator | None = None,
34
40
  *,
41
+ client_session_kwargs: dict[str, Any] | None = None,
35
42
  token_provider_name: str = "",
36
43
  use_anonymous: bool = False,
37
44
  scopes: list[str] | None = None,
45
+ client_factory: Any = None,
38
46
  ):
39
47
  """Constructor for M365AttachmentDownloader.
40
48
 
41
49
  :param connections: A Connections instance.
42
- :param client_factory: A callable that returns an aiohttp.ClientSession instance.
43
50
  :param host_validator: An optional OutboundHostValidator instance.
51
+ :param client_session_kwargs: Optional keyword arguments to pass to the aiohttp ClientSession constructor.
44
52
  :param token_provider_name: The name of the token provider.
45
53
  :param use_anonymous: Whether to use anonymous access.
46
54
  :param scopes: A list of scopes for the access token.
47
- :param connections: A Connections instance.
55
+ :param client_factory: (deprecated) A custom client factory, if any.
48
56
  """
49
57
 
58
+ if client_factory is not None:
59
+ warnings.warn(
60
+ "The 'client_factory' parameter is deprecated and will be ignored.",
61
+ DeprecationWarning,
62
+ stacklevel=2,
63
+ )
64
+
50
65
  self._connections = connections
51
- self._client_factory = client_factory or aiohttp.ClientSession
52
66
  self._host_validator = host_validator
67
+ self._client_session_kwargs = client_session_kwargs or {}
53
68
 
54
69
  self._token_provider_name = token_provider_name
55
70
  self._use_anonymous = use_anonymous
@@ -109,19 +124,32 @@ class M365AttachmentDownloader(InputFileDownloader):
109
124
  outgoing_audience_claim, self._scopes
110
125
  )
111
126
 
112
- files: list[InputFile] = []
113
- for att in attachments:
114
- file = await self._download_file(att, access_token)
115
- if file:
116
- files.append(file)
127
+ client_factory: Callable[[], aiohttp.ClientSession]
128
+ if self._host_validator is not None:
129
+ host_validator = self._host_validator # to
130
+ client_factory = lambda: host_validator.client(self._client_session_kwargs)
131
+ else:
132
+ client_factory = lambda: aiohttp.ClientSession(
133
+ **self._client_session_kwargs
134
+ )
117
135
 
136
+ async with client_factory() as client:
137
+ files: list[InputFile] = []
138
+ for att in attachments:
139
+ file = await self._download_file(client, att, access_token)
140
+ if file:
141
+ files.append(file)
118
142
  return files
119
143
 
120
144
  async def _download_file(
121
- self, attachment: Attachment, access_token: str
145
+ self,
146
+ client: aiohttp.ClientSession,
147
+ attachment: Attachment,
148
+ access_token: str,
122
149
  ) -> InputFile | None:
123
150
  """Download a single file from the given attachment.
124
151
 
152
+ :param client: The aiohttp.ClientSession instance to use for downloading the file.
125
153
  :param attachment: The Attachment instance.
126
154
  :param access_token: The access token for authentication.
127
155
  :return: An InputFile instance or None if the download fails.
@@ -136,16 +164,10 @@ class M365AttachmentDownloader(InputFileDownloader):
136
164
  download_url = attachment.content_url
137
165
 
138
166
  if download_url and _basic_url_check(download_url):
139
- if (
140
- self._host_validator is not None
141
- and self._host_validator.enabled
142
- and not self._host_validator.is_allowed(download_url)
143
- ):
144
- return None
145
-
146
- async with self._client_factory() as client:
167
+ try:
147
168
  async with client.get(
148
- download_url, headers={"Authorization": f"Bearer {access_token}"}
169
+ download_url,
170
+ headers={"Authorization": f"Bearer {access_token}"},
149
171
  ) as response:
150
172
  if not (200 <= response.status < 300):
151
173
  return None
@@ -165,6 +187,11 @@ class M365AttachmentDownloader(InputFileDownloader):
165
187
  content_url=attachment.content_url,
166
188
  filename=name,
167
189
  )
190
+ except _SSRFError:
191
+ logger.warning(
192
+ "Outbound host validation failed for an attachment download URL."
193
+ )
194
+ return None
168
195
  else:
169
196
  content = bytes(json.dumps(attachment.content), "utf-8")
170
197
  return InputFile(
@@ -6,6 +6,7 @@ from __future__ import annotations
6
6
  import uuid
7
7
  import asyncio
8
8
  import logging
9
+ from collections.abc import Mapping
9
10
  from typing import Optional, Callable, Literal, cast, TYPE_CHECKING
10
11
 
11
12
  from microsoft_agents.activity import (
@@ -499,6 +500,12 @@ class StreamingResponse:
499
500
  )
500
501
  if self._should_update_final_activity() and self._stream_id:
501
502
  activity.id = self._stream_id
503
+
504
+ if self._enable_feedback_loop and self._is_teams_channel():
505
+ self._add_feedback_loop_to_channel_data(activity)
506
+
507
+ self._add_generated_by_ai_metadata(activity)
508
+
502
509
  return activity
503
510
 
504
511
  def _create_stream_stopped_message(self, message: str) -> Activity:
@@ -514,6 +521,7 @@ class StreamingResponse:
514
521
  )
515
522
  ],
516
523
  )
524
+ self._add_generated_by_ai_metadata(activity)
517
525
  return activity
518
526
 
519
527
  def _create_stream_timed_out_message(
@@ -534,12 +542,15 @@ class StreamingResponse:
534
542
  stream_info.stream_id = self._stream_id
535
543
  entities.append(stream_info)
536
544
 
537
- return Activity(
545
+ activity = Activity(
538
546
  id=self._stream_id,
539
547
  type="message",
540
548
  text=text,
541
549
  entities=entities,
542
550
  )
551
+ if add_stream_final:
552
+ self._add_generated_by_ai_metadata(activity)
553
+ return activity
543
554
 
544
555
  def _create_stream_timed_out_streaming_update(self) -> Activity:
545
556
  text = (
@@ -615,23 +626,6 @@ class StreamingResponse:
615
626
  )
616
627
  )
617
628
 
618
- # Add in Powered by AI feature flags
619
- if self._ended:
620
- if self._enable_feedback_loop and self._feedback_loop_type:
621
- # Add feedback loop to streaminfo entity
622
- if streaminfo_entity:
623
- streaminfo_entity.feedback_loop = {"type": self._feedback_loop_type}
624
- else:
625
- # Add feedback loop enabled to streaminfo entity
626
- if streaminfo_entity:
627
- streaminfo_entity.feedback_loop_enabled = self._enable_feedback_loop
628
- # Add in Generated by AI
629
- if self._enable_generated_by_ai_label:
630
- curr_citations = CitationUtil.get_used_citations(
631
- self._message, self._citations
632
- )
633
- activity.add_ai_metadata(curr_citations, self._sensitivity_label)
634
-
635
629
  try:
636
630
  response = await self._context.send_activity(activity)
637
631
 
@@ -840,6 +834,38 @@ class StreamingResponse:
840
834
  channel_id = self._context.activity.channel_id
841
835
  return bool(channel_id) and channel_id.channel == Channels.ms_teams
842
836
 
837
+ def _add_feedback_loop_to_channel_data(self, activity: Activity) -> None:
838
+ channel_data = activity.channel_data
839
+ if channel_data is None:
840
+ serialized_channel_data = {}
841
+ elif isinstance(channel_data, Mapping):
842
+ serialized_channel_data = dict(channel_data)
843
+ elif callable(model_dump := getattr(channel_data, "model_dump", None)):
844
+ serialized_channel_data = model_dump(
845
+ mode="json",
846
+ by_alias=True,
847
+ exclude_none=True,
848
+ exclude_unset=True,
849
+ )
850
+ else:
851
+ logger.warning(
852
+ "Unable to add feedback loop to unsupported channel data type: %s",
853
+ type(channel_data).__name__,
854
+ )
855
+ return
856
+
857
+ serialized_channel_data["feedbackLoop"] = {
858
+ "type": self._feedback_loop_type or "default"
859
+ }
860
+ activity.channel_data = serialized_channel_data
861
+
862
+ def _add_generated_by_ai_metadata(self, activity: Activity) -> None:
863
+ if not self._enable_generated_by_ai_label:
864
+ return
865
+
866
+ curr_citations = CitationUtil.get_used_citations(self._message, self._citations)
867
+ activity.add_ai_metadata(curr_citations, self._sensitivity_label)
868
+
843
869
  def _should_update_final_activity(self) -> bool:
844
870
  if self._is_m365_copilot():
845
871
  return False
@@ -781,18 +781,17 @@ class ConnectorClient(ConnectorClientBase):
781
781
  if not endpoint.endswith("/"):
782
782
  endpoint += "/"
783
783
 
784
+ # Create session with the base URL
785
+ session = session or ClientSession(base_url=endpoint)
786
+
784
787
  # Configure headers with JSON acceptance
785
788
  headers = {
786
789
  "Accept": "application/json",
787
790
  "Content-Type": "application/json",
788
- "User-Agent": get_product_info(),
791
+ "User-Agent": session.headers.get("User-Agent", get_product_info()),
789
792
  }
793
+ session.headers.update(headers)
790
794
 
791
- # Create session with the base URL
792
- session = session or ClientSession(
793
- base_url=endpoint,
794
- headers=headers,
795
- )
796
795
  logger.debug(
797
796
  "ConnectorClient initialized with endpoint: %s and headers: %s",
798
797
  endpoint,
@@ -57,18 +57,16 @@ class UserTokenClient(UserTokenClientBase):
57
57
  if not endpoint.endswith("/"):
58
58
  endpoint += "/"
59
59
 
60
+ # Create session with the base URL
61
+ session = session or ClientSession(base_url=endpoint)
62
+
60
63
  # Configure headers with JSON acceptance
61
64
  headers = {
62
65
  "Accept": "application/json",
63
66
  "Content-Type": "application/json",
64
- "User-Agent": get_product_info(),
67
+ "User-Agent": session.headers.get("User-Agent", get_product_info()),
65
68
  }
66
-
67
- # Create session with the base URL
68
- session = session or ClientSession(
69
- base_url=endpoint,
70
- headers=headers,
71
- )
69
+ session.headers.update(headers)
72
70
  logger.debug(
73
71
  "Creating UserTokenClient with endpoint: %s and headers: %s",
74
72
  endpoint,
@@ -14,6 +14,7 @@ from ..attachments_base import AttachmentsBase
14
14
  from ..conversations_base import ConversationsBase
15
15
  from ..client._base_client import _BaseClient
16
16
  from .._utils import _handle_request_error
17
+ from ..get_product_info import get_product_info
17
18
 
18
19
  logger = logging.getLogger(__name__)
19
20
 
@@ -224,6 +225,13 @@ class MCSConnectorClient(ConnectorClientBase):
224
225
 
225
226
  self._endpoint = endpoint
226
227
  self._client = client or ClientSession()
228
+ headers = {
229
+ "Accept": "application/json",
230
+ "Content-Type": "application/json",
231
+ "User-Agent": self._client.headers.get("User-Agent", get_product_info()),
232
+ }
233
+ self._client.headers.update(headers)
234
+
227
235
  self._conversations = MCSConversations(self._client, self._endpoint)
228
236
  self._attachments = MCSAttachments()
229
237
 
@@ -0,0 +1,14 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from ._connector import _SSRFError, _SSRFConnector
5
+ from ._utils import _try_create_url, _normalize_host
6
+ from .outbound_host_validator import OutboundHostValidator
7
+
8
+ __all__ = [
9
+ "OutboundHostValidator",
10
+ "_SSRFError",
11
+ "_SSRFConnector",
12
+ "_try_create_url",
13
+ "_normalize_host",
14
+ ]
@@ -0,0 +1,58 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from collections.abc import Sequence
5
+ from typing import Protocol
6
+
7
+ from aiohttp import TCPConnector
8
+ from aiohttp.abc import ResolveResult
9
+ from aiohttp.tracing import Trace
10
+
11
+
12
+ class _ResolveResultValidator(Protocol):
13
+ """Protocol for validating resolved results to prevent SSRF attacks."""
14
+
15
+ def is_allowed(self, resolved: ResolveResult) -> bool:
16
+ """Check if the resolved result is valid to prevent SSRF attacks.
17
+
18
+ :param resolved: The resolved result to validate.
19
+ :return: True if the resolved result is valid, False otherwise.
20
+ """
21
+ ...
22
+
23
+
24
+ class _SSRFError(ValueError):
25
+ """Exception raised when an SSRF attack is detected."""
26
+
27
+
28
+ class _SSRFConnector(TCPConnector):
29
+ """TCPConnector subclass that validates resolved host results to prevent SSRF attacks."""
30
+
31
+ def __init__(
32
+ self, resolved_result_validator: _ResolveResultValidator, *args, **kwargs
33
+ ):
34
+ """Initialize the SSRFConnector with a resolved result validator.
35
+
36
+ :param resolved_result_validator: The validator used to check resolved host results.
37
+ """
38
+ super().__init__(*args, **kwargs)
39
+ self._resolved_result_validator = resolved_result_validator
40
+
41
+ async def _resolve_host(
42
+ self, host: str, port: int, traces: Sequence[Trace] | None = None
43
+ ) -> list[ResolveResult]:
44
+ """Resolve the host and validate the resolved results to prevent SSRF attacks.
45
+
46
+ :param host: The hostname to resolve.
47
+ :param port: The port number to resolve.
48
+ :param traces: Optional sequence of Trace objects for tracing the resolution process.
49
+ :return: A list of validated ResolveResult objects.
50
+ :raises _SSRFError: If any resolved result is invalid.
51
+ """
52
+
53
+ res = await super()._resolve_host(host, port, traces)
54
+
55
+ for r in res:
56
+ if not self._resolved_result_validator.is_allowed(r):
57
+ raise _SSRFError(f"Invalid resolved result: {r}")
58
+ return res
@@ -0,0 +1,31 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from typing import Callable, Awaitable
5
+
6
+ from aiohttp import ClientRequest, ClientHandlerType, ClientResponse
7
+
8
+ from ._connector import _SSRFError
9
+ from ._validator import _URLValidator
10
+
11
+
12
+ def _validator_middleware(
13
+ validator: _URLValidator,
14
+ ) -> Callable[[ClientRequest, ClientHandlerType], Awaitable[ClientResponse]]:
15
+ """Creates a middleware that validates outbound URLs using the given validator.
16
+
17
+ :param validator: The outbound host validator to use.
18
+ :return: A middleware function that validates outbound URLs.
19
+ """
20
+
21
+ async def _middleware(
22
+ req: ClientRequest, handler: ClientHandlerType
23
+ ) -> ClientResponse:
24
+ """Middleware that validates outbound URLs using the given host validator."""
25
+
26
+ if not validator.is_allowed(req.url):
27
+ raise _SSRFError(f"URL is not allowed by the outbound host validator.")
28
+
29
+ return await handler(req)
30
+
31
+ return _middleware