microsoft-agents-hosting-core 1.7.0.dev7__tar.gz → 1.8.0__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.
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/PKG-INFO +11 -2
- microsoft_agents_hosting_core-1.8.0/VERSION.txt +1 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/_oauth/_oauth_flow.py +1 -1
- microsoft_agents_hosting_core-1.8.0/microsoft_agents/hosting/core/app/_utils.py +36 -0
- microsoft_agents_hosting_core-1.8.0/microsoft_agents/hosting/core/app/attachment_downloader.py +104 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/input_file.py +7 -7
- microsoft_agents_hosting_core-1.8.0/microsoft_agents/hosting/core/app/m365_attachment_downloader.py +175 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/claims_identity.py +17 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/channel_adapter.py +10 -2
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/channel_service_adapter.py +19 -15
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/attachments_base.py +4 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/client/connector_client.py +48 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/mcs/mcs_connector_client.py +8 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/turn_context.py +22 -19
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents_hosting_core.egg-info/PKG-INFO +11 -2
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents_hosting_core.egg-info/SOURCES.txt +3 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents_hosting_core.egg-info/requires.txt +1 -1
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/readme.md +9 -0
- microsoft_agents_hosting_core-1.7.0.dev7/VERSION.txt +0 -1
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/LICENSE +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/MANIFEST.in +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/_http_adapter_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/_oauth/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/_oauth/_flow_state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/_oauth/_flow_storage_client.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/_utils/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/_utils/_service_set.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/activity_handler.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/agent.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/_routes/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/_routes/_route.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/_routes/_route_list.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/_routes/route_rank.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/_type_defs.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/adaptive_card/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/adaptive_card/_type_defs.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/adaptive_card/adaptive_card.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/adaptive_card/factory.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/adaptive_card/models.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/agent_application.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/app_error.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/app_options.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/_handlers/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/_handlers/_authorization_handler.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/_handlers/_user_authorization.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/_handlers/connector_user_authorization.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/_sign_in_response.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/_sign_in_state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/auth_handler.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/authorization.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/telemetry/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/telemetry/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/oauth/telemetry/spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/conversation.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/conversation_builder.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/conversation_reference_builder.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/create_conversation_options.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/proactive.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/proactive_options.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/telemetry/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/telemetry/_utils.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/telemetry/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/proactive/telemetry/spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/query.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/state/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/state/conversation_state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/state/state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/state/temp_state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/state/turn_state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/streaming/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/streaming/citation.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/streaming/citation_util.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/streaming/streaming_response.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/telemetry/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/telemetry/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/telemetry/metrics.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/telemetry/spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/app/typing_indicator.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/_entra_issuers.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/_helpers.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/_log_config.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/access_token_provider_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/agent_auth_configuration.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/anonymous_token_provider.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/auth_types.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/authentication_constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/connection_manager.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/connection_settings_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/connections.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/jwt/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/jwt/_authorize_request.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/jwt/jwt_token_validator.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/telemetry/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/telemetry/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/telemetry/metrics.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/authorization/telemetry/spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/card_factory.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/channel_api_handler_protocol.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/channel_service_client_factory_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/agent_conversation_reference.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/channel_factory_protocol.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/channel_host_protocol.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/channel_info_protocol.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/channel_protocol.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/channels_configuration.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/configuration_channel_host.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/conversation_constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/conversation_id_factory.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/conversation_id_factory_options.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/conversation_id_factory_protocol.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/http_agent_channel.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/client/http_agent_channel_factory.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/_utils.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/agent_sign_in_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/client/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/client/_base_client.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/client/agent_sign_in.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/client/user_token.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/client/user_token_client.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/connector_client_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/conversations_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/get_product_info.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/mcs/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/teams/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/teams/teams_connector_client.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/telemetry/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/telemetry/_request_span_wrapper.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/telemetry/connector_spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/telemetry/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/telemetry/metrics.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/telemetry/user_token_client_spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/user_token_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/connector/user_token_client_base.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/errors/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/errors/error_resources.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/header_propagation/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/header_propagation/agentic_header_provider.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/header_propagation/header_propagation_context.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/header_propagation/header_value_provider.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/http/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/http/_channel_service_routes.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/http/_http_request_protocol.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/http/_http_response.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/message_factory.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/middleware_set.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/outbound_host_validator.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/py.typed +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/rest_channel_service_client_factory.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/state/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/state/agent_state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/state/state_property_accessor.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/state/user_state.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/_type_aliases.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/error_handling.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/memory_storage.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/storage.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/store_item.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/telemetry/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/telemetry/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/telemetry/metrics.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/telemetry/spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/transcript/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/transcript/transcript_file_store.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/transcript/transcript_info.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/transcript/transcript_logger.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/transcript/transcript_memory_store.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/storage/transcript/transcript_store.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/adapter/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/adapter/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/adapter/metrics.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/adapter/spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/attributes.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/core/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/core/_agents_telemetry.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/core/base_span_wrapper.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/core/resource.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/core/simple_span_wrapper.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/core/type_defs.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/turn_context/__init__.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/turn_context/constants.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/turn_context/spans.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents/hosting/core/telemetry/utils.py +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents_hosting_core.egg-info/dependency_links.txt +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/microsoft_agents_hosting_core.egg-info/top_level.txt +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/pyproject.toml +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/setup.cfg +0 -0
- {microsoft_agents_hosting_core-1.7.0.dev7 → microsoft_agents_hosting_core-1.8.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: microsoft-agents-hosting-core
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: Core library for Microsoft Agents
|
|
5
5
|
Author: Microsoft Corporation
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,7 +15,7 @@ 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.
|
|
18
|
+
Requires-Dist: microsoft-agents-activity==1.8.0
|
|
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
|
|
@@ -45,6 +45,15 @@ This library is part of the **Microsoft 365 Agents SDK for Python** - a comprehe
|
|
|
45
45
|
<th style="width:20%">Date</th>
|
|
46
46
|
<th style="width:60%">Release Notes</th>
|
|
47
47
|
</tr>
|
|
48
|
+
<tr>
|
|
49
|
+
<td>1.8.0</td>
|
|
50
|
+
<td>2026-10-01</td>
|
|
51
|
+
<td>
|
|
52
|
+
<a href="https://github.com/microsoft/Agents-for-python/blob/main/changelog.md#microsoft-365-agents-sdk-for-python---release-notes-v180">
|
|
53
|
+
1.8.0 Release Notes
|
|
54
|
+
</a>
|
|
55
|
+
</td>
|
|
56
|
+
</tr>
|
|
48
57
|
<tr>
|
|
49
58
|
<td>1.7.0</td>
|
|
50
59
|
<td>2026-09-17</td>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.8.0
|
|
@@ -208,7 +208,7 @@ class _OAuthFlow:
|
|
|
208
208
|
self, activity: Activity
|
|
209
209
|
) -> tuple[TokenResponse, _FlowErrorTag]:
|
|
210
210
|
"""Handles the continuation of the flow from a message activity."""
|
|
211
|
-
magic_code: str = activity.text
|
|
211
|
+
magic_code: str = activity.text or ""
|
|
212
212
|
if magic_code and magic_code.isdigit() and len(magic_code) == 6:
|
|
213
213
|
token_response: TokenResponse = await self.get_user_token(magic_code)
|
|
214
214
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
from email.message import Message
|
|
5
|
+
from urllib.parse import urlparse
|
|
6
|
+
|
|
7
|
+
_CONTENT_TYPE = "Content-Type"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _parse_content_type(content_type: str) -> tuple[str, dict[str, str]] | None:
|
|
11
|
+
"""Parses the given content type string into its main type and parameters.
|
|
12
|
+
|
|
13
|
+
:param content_type: The content type string to parse.
|
|
14
|
+
:return: A tuple containing the main content type and a dictionary of parameters,
|
|
15
|
+
or None if parsing fails.
|
|
16
|
+
"""
|
|
17
|
+
email = Message()
|
|
18
|
+
email[_CONTENT_TYPE] = content_type
|
|
19
|
+
params = email.get_params()
|
|
20
|
+
if params is None:
|
|
21
|
+
return None
|
|
22
|
+
# the first param is the mime-type
|
|
23
|
+
# the later ones are the attributes like "charset"
|
|
24
|
+
return params[0][0], dict(params[1:])
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _basic_url_check(url: str) -> bool:
|
|
28
|
+
"""Performs a basic check to see if the given string is a valid URL.
|
|
29
|
+
|
|
30
|
+
:param url: The URL string to check.
|
|
31
|
+
:return: True if the URL has a valid scheme and netloc, False otherwise.
|
|
32
|
+
"""
|
|
33
|
+
parsed = urlparse(url)
|
|
34
|
+
return parsed.scheme == "https" or (
|
|
35
|
+
parsed.scheme == "http" and parsed.hostname == "localhost"
|
|
36
|
+
)
|
microsoft_agents_hosting_core-1.8.0/microsoft_agents/hosting/core/app/attachment_downloader.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from typing import Callable
|
|
6
|
+
|
|
7
|
+
import aiohttp
|
|
8
|
+
|
|
9
|
+
from microsoft_agents.activity import (
|
|
10
|
+
Attachment,
|
|
11
|
+
Channels,
|
|
12
|
+
ChannelId,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from microsoft_agents.hosting.core.turn_context import TurnContext
|
|
16
|
+
from microsoft_agents.hosting.core.outbound_host_validator import OutboundHostValidator
|
|
17
|
+
|
|
18
|
+
from .input_file import InputFileDownloader, InputFile
|
|
19
|
+
from ._utils import _parse_content_type, _basic_url_check
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AttachmentDownloader(InputFileDownloader):
|
|
23
|
+
"""Downloads attachments from a given turn context."""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
client_factory: Callable[[], aiohttp.ClientSession] | None = None,
|
|
28
|
+
host_validator: OutboundHostValidator | None = None,
|
|
29
|
+
):
|
|
30
|
+
"""Constructor for AttachmentDownloader.
|
|
31
|
+
|
|
32
|
+
:param client_factory: A callable that returns an aiohttp.ClientSession instance.
|
|
33
|
+
:param host_validator: An optional OutboundHostValidator instance.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
self._client_factory = client_factory or aiohttp.ClientSession
|
|
37
|
+
self._host_validator = host_validator
|
|
38
|
+
|
|
39
|
+
async def download_files(self, context: TurnContext) -> list[InputFile]:
|
|
40
|
+
"""Downloads files for the given turn context.
|
|
41
|
+
|
|
42
|
+
:param context: The TurnContext instance for the current turn.
|
|
43
|
+
:return: A list of InputFile instances representing the downloaded files.
|
|
44
|
+
"""
|
|
45
|
+
if ChannelId.get_channel(context.activity.channel_id) == Channels.ms_teams:
|
|
46
|
+
return []
|
|
47
|
+
|
|
48
|
+
if not context.activity.attachments:
|
|
49
|
+
return []
|
|
50
|
+
|
|
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)
|
|
56
|
+
|
|
57
|
+
return files
|
|
58
|
+
|
|
59
|
+
async def _download_file(self, attachment: Attachment) -> InputFile | None:
|
|
60
|
+
"""Downloads a single file from the given attachment.
|
|
61
|
+
|
|
62
|
+
:param attachment: The attachment to download.
|
|
63
|
+
:return: An InputFile instance if the download is successful, None otherwise.
|
|
64
|
+
"""
|
|
65
|
+
if attachment.content_url and _basic_url_check(attachment.content_url):
|
|
66
|
+
remote_file_url = attachment.content_url
|
|
67
|
+
|
|
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:
|
|
76
|
+
async with client.get(remote_file_url) as response:
|
|
77
|
+
|
|
78
|
+
if not (200 <= response.status < 300):
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
content_type_val = response.headers.get("Content-Type", "")
|
|
82
|
+
result = _parse_content_type(content_type_val)
|
|
83
|
+
if result is None:
|
|
84
|
+
return None
|
|
85
|
+
content_type, _ = result
|
|
86
|
+
if content_type.startswith("image/"):
|
|
87
|
+
content_type = "image/png"
|
|
88
|
+
|
|
89
|
+
res = await response.read()
|
|
90
|
+
|
|
91
|
+
return InputFile(
|
|
92
|
+
content=res,
|
|
93
|
+
content_type=content_type,
|
|
94
|
+
content_url=attachment.content_url,
|
|
95
|
+
filename=attachment.name,
|
|
96
|
+
)
|
|
97
|
+
else:
|
|
98
|
+
content = bytes(json.dumps(attachment.content), "utf-8")
|
|
99
|
+
return InputFile(
|
|
100
|
+
content=content,
|
|
101
|
+
content_type=attachment.content_type,
|
|
102
|
+
content_url=attachment.content_url,
|
|
103
|
+
filename=attachment.name,
|
|
104
|
+
)
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Licensed under the MIT License.
|
|
4
|
-
"""
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
5
3
|
|
|
6
4
|
from __future__ import annotations
|
|
7
5
|
|
|
8
6
|
from abc import ABC, abstractmethod
|
|
9
7
|
from dataclasses import dataclass
|
|
10
|
-
from typing import Optional
|
|
11
8
|
|
|
12
9
|
from microsoft_agents.hosting.core import TurnContext
|
|
13
10
|
|
|
@@ -21,12 +18,15 @@ class InputFile:
|
|
|
21
18
|
:param content_type: The content type of the file.
|
|
22
19
|
:type content_type: str
|
|
23
20
|
:param content_url: Optional. URL to the content of the file.
|
|
24
|
-
:type content_url:
|
|
21
|
+
:type content_url: str | None
|
|
22
|
+
:param filename: Optional. The name of the file.
|
|
23
|
+
:type filename: str | None
|
|
25
24
|
"""
|
|
26
25
|
|
|
27
26
|
content: bytes
|
|
28
27
|
content_type: str
|
|
29
|
-
content_url:
|
|
28
|
+
content_url: str | None = None
|
|
29
|
+
filename: str | None = None
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class InputFileDownloader(ABC):
|
microsoft_agents_hosting_core-1.8.0/microsoft_agents/hosting/core/app/m365_attachment_downloader.py
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from typing import Callable, cast, Any
|
|
6
|
+
|
|
7
|
+
import aiohttp
|
|
8
|
+
|
|
9
|
+
from microsoft_agents.activity import (
|
|
10
|
+
Attachment,
|
|
11
|
+
Channels,
|
|
12
|
+
ChannelId,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from microsoft_agents.hosting.core.authorization import (
|
|
16
|
+
AccessTokenProviderBase,
|
|
17
|
+
Connections,
|
|
18
|
+
)
|
|
19
|
+
from microsoft_agents.hosting.core.turn_context import TurnContext
|
|
20
|
+
from microsoft_agents.hosting.core.outbound_host_validator import OutboundHostValidator
|
|
21
|
+
|
|
22
|
+
from .input_file import InputFileDownloader, InputFile
|
|
23
|
+
from ._utils import _parse_content_type, _basic_url_check
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class M365AttachmentDownloader(InputFileDownloader):
|
|
27
|
+
"""Downloads attachments from M365/Teams using the configured Token Provider (from Connections)."""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
connections: Connections,
|
|
32
|
+
client_factory: Callable[[], aiohttp.ClientSession] | None = None,
|
|
33
|
+
host_validator: OutboundHostValidator | None = None,
|
|
34
|
+
*,
|
|
35
|
+
token_provider_name: str = "",
|
|
36
|
+
use_anonymous: bool = False,
|
|
37
|
+
scopes: list[str] | None = None,
|
|
38
|
+
):
|
|
39
|
+
"""Constructor for M365AttachmentDownloader.
|
|
40
|
+
|
|
41
|
+
:param connections: A Connections instance.
|
|
42
|
+
:param client_factory: A callable that returns an aiohttp.ClientSession instance.
|
|
43
|
+
:param host_validator: An optional OutboundHostValidator instance.
|
|
44
|
+
:param token_provider_name: The name of the token provider.
|
|
45
|
+
:param use_anonymous: Whether to use anonymous access.
|
|
46
|
+
:param scopes: A list of scopes for the access token.
|
|
47
|
+
:param connections: A Connections instance.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
self._connections = connections
|
|
51
|
+
self._client_factory = client_factory or aiohttp.ClientSession
|
|
52
|
+
self._host_validator = host_validator
|
|
53
|
+
|
|
54
|
+
self._token_provider_name = token_provider_name
|
|
55
|
+
self._use_anonymous = use_anonymous
|
|
56
|
+
self._scopes = scopes or []
|
|
57
|
+
|
|
58
|
+
async def download_files(self, context: TurnContext) -> list[InputFile]:
|
|
59
|
+
"""Download files from the given context.
|
|
60
|
+
|
|
61
|
+
:param context: The TurnContext instance.
|
|
62
|
+
:return: A list of InputFile instances.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
if context.activity.channel_id not in (
|
|
66
|
+
Channels.ms_teams,
|
|
67
|
+
Channels.m365_copilot,
|
|
68
|
+
):
|
|
69
|
+
return []
|
|
70
|
+
|
|
71
|
+
attachments: list[Attachment]
|
|
72
|
+
if not context.activity.attachments:
|
|
73
|
+
return []
|
|
74
|
+
attachments = [
|
|
75
|
+
att
|
|
76
|
+
for att in context.activity.attachments
|
|
77
|
+
if not att.content_type.startswith("text/html")
|
|
78
|
+
]
|
|
79
|
+
if not attachments:
|
|
80
|
+
return []
|
|
81
|
+
|
|
82
|
+
access_token = ""
|
|
83
|
+
|
|
84
|
+
if not self._use_anonymous:
|
|
85
|
+
|
|
86
|
+
if not context.identity:
|
|
87
|
+
raise ValueError("No valid context identity found.")
|
|
88
|
+
|
|
89
|
+
outgoing_audience_claim = context.identity.get_outgoing_audience_claim()
|
|
90
|
+
if not outgoing_audience_claim:
|
|
91
|
+
raise ValueError("No valid outgoing App ID found.")
|
|
92
|
+
|
|
93
|
+
token_provider: AccessTokenProviderBase | None = None
|
|
94
|
+
if self._token_provider_name:
|
|
95
|
+
try:
|
|
96
|
+
token_provider = self._connections.get_connection(
|
|
97
|
+
self._token_provider_name
|
|
98
|
+
)
|
|
99
|
+
except ValueError:
|
|
100
|
+
pass
|
|
101
|
+
if not token_provider:
|
|
102
|
+
token_provider = self._connections.get_token_provider_from_activity(
|
|
103
|
+
context.identity, context.activity
|
|
104
|
+
)
|
|
105
|
+
if not token_provider:
|
|
106
|
+
raise RuntimeError("No valid token provider found.")
|
|
107
|
+
|
|
108
|
+
access_token = await token_provider.get_access_token(
|
|
109
|
+
outgoing_audience_claim, self._scopes
|
|
110
|
+
)
|
|
111
|
+
|
|
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)
|
|
117
|
+
|
|
118
|
+
return files
|
|
119
|
+
|
|
120
|
+
async def _download_file(
|
|
121
|
+
self, attachment: Attachment, access_token: str
|
|
122
|
+
) -> InputFile | None:
|
|
123
|
+
"""Download a single file from the given attachment.
|
|
124
|
+
|
|
125
|
+
:param attachment: The Attachment instance.
|
|
126
|
+
:param access_token: The access token for authentication.
|
|
127
|
+
:return: An InputFile instance or None if the download fails.
|
|
128
|
+
"""
|
|
129
|
+
name = attachment.name
|
|
130
|
+
|
|
131
|
+
download_url: str | None = None
|
|
132
|
+
if isinstance(attachment.content, dict):
|
|
133
|
+
content_dict = cast(dict[str, Any], attachment.content)
|
|
134
|
+
download_url = content_dict.get("downloadUrl", attachment.content_url)
|
|
135
|
+
else:
|
|
136
|
+
download_url = attachment.content_url
|
|
137
|
+
|
|
138
|
+
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:
|
|
147
|
+
async with client.get(
|
|
148
|
+
download_url, headers={"Authorization": f"Bearer {access_token}"}
|
|
149
|
+
) as response:
|
|
150
|
+
if not (200 <= response.status < 300):
|
|
151
|
+
return None
|
|
152
|
+
content = await response.read()
|
|
153
|
+
result = _parse_content_type(
|
|
154
|
+
response.headers.get("Content-Type", "")
|
|
155
|
+
)
|
|
156
|
+
if result is None:
|
|
157
|
+
return None
|
|
158
|
+
content_type, _ = result
|
|
159
|
+
if content_type.startswith("image/"):
|
|
160
|
+
content_type = "image/png"
|
|
161
|
+
|
|
162
|
+
return InputFile(
|
|
163
|
+
content=content,
|
|
164
|
+
content_type=content_type,
|
|
165
|
+
content_url=attachment.content_url,
|
|
166
|
+
filename=name,
|
|
167
|
+
)
|
|
168
|
+
else:
|
|
169
|
+
content = bytes(json.dumps(attachment.content), "utf-8")
|
|
170
|
+
return InputFile(
|
|
171
|
+
content=content,
|
|
172
|
+
content_type=attachment.content_type,
|
|
173
|
+
content_url=attachment.content_url,
|
|
174
|
+
filename=attachment.name,
|
|
175
|
+
)
|
|
@@ -79,6 +79,14 @@ class ClaimsIdentity:
|
|
|
79
79
|
|
|
80
80
|
return app_id
|
|
81
81
|
|
|
82
|
+
def get_outgoing_audience_claim(self) -> str | None:
|
|
83
|
+
"""Retrieves the audience for an outgoing token from the given incoming activity."""
|
|
84
|
+
if self.is_agent_claim():
|
|
85
|
+
return f"api://{self.get_outgoing_app_id()}"
|
|
86
|
+
if self.is_gov_botframework_claim():
|
|
87
|
+
return AuthenticationConstants.GOV_AGENTS_SDK_TOKEN_ISSUER
|
|
88
|
+
return AuthenticationConstants.AGENTS_SDK_SCOPE
|
|
89
|
+
|
|
82
90
|
def is_agent_claim(self) -> bool:
|
|
83
91
|
"""
|
|
84
92
|
Checks if the current claims represents an agent claim (not coming from ABS/SMBA).
|
|
@@ -116,6 +124,15 @@ class ClaimsIdentity:
|
|
|
116
124
|
else AuthenticationConstants.AGENTS_SDK_SCOPE
|
|
117
125
|
)
|
|
118
126
|
|
|
127
|
+
def is_gov_botframework_claim(self) -> bool:
|
|
128
|
+
"""Determines whether the specified incoming identity represents a government Bot Framework claim."""
|
|
129
|
+
aud = self.claims.get(AuthenticationConstants.AUDIENCE_CLAIM, None)
|
|
130
|
+
return (
|
|
131
|
+
aud.lower() == AuthenticationConstants.GOV_AGENTS_SDK_TOKEN_ISSUER.lower()
|
|
132
|
+
if aud
|
|
133
|
+
else False
|
|
134
|
+
)
|
|
135
|
+
|
|
119
136
|
def get_token_scope(self) -> list[str]:
|
|
120
137
|
"""
|
|
121
138
|
Gets the token scope from current claims.
|
|
@@ -114,7 +114,11 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
114
114
|
:rtype: typing.Any
|
|
115
115
|
"""
|
|
116
116
|
context = TurnContext(self, reference.get_continuation_activity())
|
|
117
|
-
|
|
117
|
+
try:
|
|
118
|
+
res = await self.run_pipeline(context, callback)
|
|
119
|
+
finally:
|
|
120
|
+
await context._aclose()
|
|
121
|
+
return res
|
|
118
122
|
|
|
119
123
|
async def continue_conversation_with_claims(
|
|
120
124
|
self,
|
|
@@ -220,7 +224,11 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
220
224
|
context.turn_state["ConversationParameters"] = conversation_parameters
|
|
221
225
|
|
|
222
226
|
# Process the activity through the middleware pipeline
|
|
223
|
-
|
|
227
|
+
try:
|
|
228
|
+
res = await self.run_pipeline(context, callback)
|
|
229
|
+
finally:
|
|
230
|
+
await context._aclose()
|
|
231
|
+
return res
|
|
224
232
|
|
|
225
233
|
async def run_pipeline(
|
|
226
234
|
self,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
from abc import ABC
|
|
7
|
+
from contextlib import AsyncExitStack
|
|
7
8
|
from http import HTTPStatus
|
|
8
9
|
from typing import Awaitable, Callable, Optional, cast
|
|
9
10
|
from uuid import uuid4
|
|
@@ -308,11 +309,12 @@ class ChannelServiceAdapter(ChannelAdapter, ABC):
|
|
|
308
309
|
user_token_client # for back-compat
|
|
309
310
|
)
|
|
310
311
|
|
|
311
|
-
# Run the pipeline
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
312
|
+
# Run the pipeline and release resources in reverse registration order.
|
|
313
|
+
async with AsyncExitStack() as cleanup:
|
|
314
|
+
cleanup.push_async_callback(context._aclose)
|
|
315
|
+
cleanup.push_async_callback(user_token_client.close)
|
|
316
|
+
cleanup.push_async_callback(connector_client.close)
|
|
317
|
+
await self.run_pipeline(context, callback)
|
|
316
318
|
|
|
317
319
|
async def process_proactive(
|
|
318
320
|
self,
|
|
@@ -356,11 +358,12 @@ class ChannelServiceAdapter(ChannelAdapter, ABC):
|
|
|
356
358
|
connector_client # for back-compat
|
|
357
359
|
)
|
|
358
360
|
|
|
359
|
-
# Run the pipeline
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
361
|
+
# Run the pipeline and release resources in reverse registration order.
|
|
362
|
+
async with AsyncExitStack() as cleanup:
|
|
363
|
+
cleanup.push_async_callback(context._aclose)
|
|
364
|
+
cleanup.push_async_callback(user_token_client.close)
|
|
365
|
+
cleanup.push_async_callback(connector_client.close)
|
|
366
|
+
await self.run_pipeline(context, callback)
|
|
364
367
|
|
|
365
368
|
def _resolve_if_connector_client_is_needed(self, activity: Activity) -> bool:
|
|
366
369
|
"""Determine if a connector client is needed based on the activity's delivery mode and service URL.
|
|
@@ -449,11 +452,12 @@ class ChannelServiceAdapter(ChannelAdapter, ABC):
|
|
|
449
452
|
connector_client # for back-compat
|
|
450
453
|
)
|
|
451
454
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
455
|
+
async with AsyncExitStack() as cleanup:
|
|
456
|
+
cleanup.push_async_callback(context._aclose)
|
|
457
|
+
cleanup.push_async_callback(user_token_client.close)
|
|
458
|
+
if connector_client:
|
|
459
|
+
cleanup.push_async_callback(connector_client.close)
|
|
460
|
+
await self.run_pipeline(context, callback)
|
|
457
461
|
|
|
458
462
|
# If there are any results they will have been left on the TurnContext.
|
|
459
463
|
return self._process_turn_results(context)
|
|
@@ -8,6 +8,7 @@ import re
|
|
|
8
8
|
from typing import Any, Optional
|
|
9
9
|
from aiohttp import ClientSession
|
|
10
10
|
from io import BytesIO
|
|
11
|
+
from urllib.parse import quote
|
|
11
12
|
|
|
12
13
|
from microsoft_agents.activity import (
|
|
13
14
|
Activity,
|
|
@@ -146,6 +147,37 @@ class AttachmentsOperations(AttachmentsBase, _BaseClient):
|
|
|
146
147
|
data = await response.read()
|
|
147
148
|
return BytesIO(data)
|
|
148
149
|
|
|
150
|
+
def get_attachment_uri(self, attachment_id: str, view_id: str = "original") -> str:
|
|
151
|
+
"""
|
|
152
|
+
Gets the URI of an attachment view.
|
|
153
|
+
|
|
154
|
+
:param attachment_id: The ID of the attachment.
|
|
155
|
+
:param view_id: The ID of the view, defaults to "original".
|
|
156
|
+
:return: The URI of the attachment view.
|
|
157
|
+
"""
|
|
158
|
+
if not attachment_id:
|
|
159
|
+
logger.error(
|
|
160
|
+
"AttachmentsOperations.get_attachment_uri(): attachmentId is required",
|
|
161
|
+
stack_info=True,
|
|
162
|
+
)
|
|
163
|
+
raise ValueError("attachmentId is required")
|
|
164
|
+
|
|
165
|
+
if not view_id:
|
|
166
|
+
logger.error(
|
|
167
|
+
"AttachmentsOperations.get_attachment_uri(): viewId is required",
|
|
168
|
+
stack_info=True,
|
|
169
|
+
)
|
|
170
|
+
raise ValueError("viewId is required")
|
|
171
|
+
|
|
172
|
+
base_url = str(self._client._base_url)
|
|
173
|
+
if not base_url.endswith("/"):
|
|
174
|
+
base_url += "/"
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
f"{base_url}v3/attachments/{quote(attachment_id, safe='')}"
|
|
178
|
+
f"/views/{quote(view_id, safe='')}"
|
|
179
|
+
)
|
|
180
|
+
|
|
149
181
|
|
|
150
182
|
class ConversationsOperations(ConversationsBase, _BaseClient):
|
|
151
183
|
|
|
@@ -276,8 +308,16 @@ class ConversationsOperations(ConversationsBase, _BaseClient):
|
|
|
276
308
|
body.type,
|
|
277
309
|
)
|
|
278
310
|
|
|
311
|
+
params = (
|
|
312
|
+
{"isTargetedActivity": "true"}
|
|
313
|
+
if ChannelId.get_channel(body.channel_id) == Channels.ms_teams
|
|
314
|
+
and body.is_targeted_activity()
|
|
315
|
+
else None
|
|
316
|
+
)
|
|
317
|
+
|
|
279
318
|
async with self._wrapped_client().post(
|
|
280
319
|
url,
|
|
320
|
+
params=params,
|
|
281
321
|
json=body.model_dump(
|
|
282
322
|
by_alias=True, exclude_unset=True, exclude_none=True, mode="json"
|
|
283
323
|
),
|
|
@@ -337,8 +377,16 @@ class ConversationsOperations(ConversationsBase, _BaseClient):
|
|
|
337
377
|
body.type,
|
|
338
378
|
)
|
|
339
379
|
|
|
380
|
+
params = (
|
|
381
|
+
{"isTargetedActivity": "true"}
|
|
382
|
+
if ChannelId.get_channel(body.channel_id) == Channels.ms_teams
|
|
383
|
+
and body.is_targeted_activity()
|
|
384
|
+
else None
|
|
385
|
+
)
|
|
386
|
+
|
|
340
387
|
async with self._wrapped_client().post(
|
|
341
388
|
url,
|
|
389
|
+
params=params,
|
|
342
390
|
json=body.model_dump(by_alias=True, exclude_unset=True, mode="json"),
|
|
343
391
|
) as response:
|
|
344
392
|
span.share(http_method="POST", status_code=response.status)
|
|
@@ -194,6 +194,14 @@ class MCSAttachments(AttachmentsBase):
|
|
|
194
194
|
"GetAttachment is not supported for Microsoft Copilot Studio Connector"
|
|
195
195
|
)
|
|
196
196
|
|
|
197
|
+
def get_attachment_uri(
|
|
198
|
+
self, attachment_id: str, view_id: str = "original", **kwargs
|
|
199
|
+
) -> str:
|
|
200
|
+
"""Not supported for MCS Connector."""
|
|
201
|
+
raise NotImplementedError(
|
|
202
|
+
"GetAttachmentUri is not supported for Microsoft Copilot Studio Connector"
|
|
203
|
+
)
|
|
204
|
+
|
|
197
205
|
|
|
198
206
|
class MCSConnectorClient(ConnectorClientBase):
|
|
199
207
|
"""
|