From bd5662abb1297ebd457ace2918c26e5d611271e9 Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 11 Feb 2025 12:38:07 -0600 Subject: [PATCH 1/9] Updated MSAL package (#2203) Co-authored-by: Tracy Boehrer --- libraries/botframework-connector/requirements.txt | 2 +- libraries/botframework-connector/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/botframework-connector/requirements.txt b/libraries/botframework-connector/requirements.txt index 5a6d8d4e9..515030672 100644 --- a/libraries/botframework-connector/requirements.txt +++ b/libraries/botframework-connector/requirements.txt @@ -3,4 +3,4 @@ botbuilder-schema==4.17.0 requests==2.32.0 PyJWT==2.4.0 cryptography==43.0.1 -msal>=1.29.0 +msal>=1.31.1 diff --git a/libraries/botframework-connector/setup.py b/libraries/botframework-connector/setup.py index 8a99b3e19..1bfc05d49 100644 --- a/libraries/botframework-connector/setup.py +++ b/libraries/botframework-connector/setup.py @@ -11,7 +11,7 @@ # "requests>=2.23.0,<2.26", "PyJWT>=2.4.0", "botbuilder-schema==4.17.0", - "msal>=1.29.0", + "msal>=1.31.1", ] root = os.path.abspath(os.path.dirname(__file__)) From e2015ebea8bbe000cb19f9c2c25c20b9575085e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20Su=C3=A1rez?= Date: Fri, 21 Mar 2025 12:24:45 -0600 Subject: [PATCH 2/9] MentionRemoved fix (#2216) --- .../botbuilder/core/turn_context.py | 6 ++- .../tests/test_turn_context.py | 42 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/libraries/botbuilder-core/botbuilder/core/turn_context.py b/libraries/botbuilder-core/botbuilder/core/turn_context.py index 852fd1f31..72e25726c 100644 --- a/libraries/botbuilder-core/botbuilder/core/turn_context.py +++ b/libraries/botbuilder-core/botbuilder/core/turn_context.py @@ -396,9 +396,13 @@ def remove_mention_text(activity: Activity, identifier: str) -> str: mentions = TurnContext.get_mentions(activity) for mention in mentions: if mention.additional_properties["mentioned"]["id"] == identifier: + replace_text = ( + mention.additional_properties.get("text") + or mention.additional_properties.get("mentioned")["name"] + ) mention_name_match = re.match( r"(.*?)<\/at>", - escape(mention.additional_properties["text"]), + escape(replace_text), re.IGNORECASE, ) if mention_name_match: diff --git a/libraries/botbuilder-core/tests/test_turn_context.py b/libraries/botbuilder-core/tests/test_turn_context.py index 473580ef0..7247caab9 100644 --- a/libraries/botbuilder-core/tests/test_turn_context.py +++ b/libraries/botbuilder-core/tests/test_turn_context.py @@ -350,6 +350,48 @@ def test_should_remove_at_mention_with_regex_characters(self): assert text == " test activity" assert activity.text == " test activity" + def test_should_remove_custom_mention_from_activity(self): + activity = Activity( + text="Hallo", + text_format="plain", + type="message", + timestamp="2025-03-11T14:16:47.0093935Z", + id="1741702606984", + channel_id="msteams", + service_url="https://smba.trafficmanager.net/emea/REDACTED/", + from_property=ChannelAccount( + id="29:1J-K4xVh-sLpdwQ-R5GkOZ_TB0W3ec_37p710aH8qe8bITA0zxdgIGc9l-MdDdkdE_jasSfNOeWXyyL1nsrHtBQ", + name="", + aad_object_id="REDACTED", + ), + conversation=ConversationAccount( + is_group=True, + conversation_type="groupChat", + tenant_id="REDACTED", + id="19:Ql86tXNM2lTBXNKJdqKdwIF9ltGZwpvluLvnJdA0tmg1@thread.v2", + ), + recipient=ChannelAccount( + id="28:c5d5fb56-a1a4-4467-a7a3-1b37905498a0", name="Azure AI Agent" + ), + entities=[ + Entity().deserialize( + Mention( + type="mention", + mentioned=ChannelAccount( + id="28:c5d5fb56-a1a4-4467-a7a3-1b37905498a0", + name="Custom Agent", + ), + ).serialize() + ) + ], + channel_data={"tenant": {"id": "REDACTED"}, "productContext": "COPILOT"}, + ) + + text = TurnContext.remove_mention_text(activity, activity.recipient.id) + + assert text == "Hallo" + assert activity.text == "Hallo" + async def test_should_send_a_trace_activity(self): context = TurnContext(SimpleAdapter(), ACTIVITY) called = False From ec22a895ddea708d4ebcb6497f9521f9de58f4ba Mon Sep 17 00:00:00 2001 From: Alex Recuenco <26118630+alexrecuenco@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:23:32 +0100 Subject: [PATCH 3/9] fix: Method name is emit_event, not emit (#2215) --- libraries/botbuilder-dialogs/botbuilder/dialogs/dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog.py index 43cfe3052..f07a8afa5 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/dialog.py @@ -125,7 +125,7 @@ async def on_dialog_event( # Bubble as needed if (not handled) and dialog_event.bubble and dialog_context.parent: - handled = await dialog_context.parent.emit( + handled = await dialog_context.parent.emit_event( dialog_event.name, dialog_event.value, True, False ) From 13ee2f25ec3b7470fc4f570d7624b59487a98d38 Mon Sep 17 00:00:00 2001 From: Alex Recuenco <26118630+alexrecuenco@users.noreply.github.com> Date: Tue, 25 Mar 2025 18:24:05 +0100 Subject: [PATCH 4/9] Typo on link (#2217) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit contributing goes to a 404 — file not found, https://github.com/microsoft/botbuilder-python/blob/main/contributing.md The correct link is https://github.com/microsoft/botbuilder-python/blob/main/Contributing.md Co-authored-by: tracyboehrer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92a7c1332..feace0e06 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ We use the [@msbotframework](https://twitter.com/msbotframework) account on twit The [Gitter Channel](https://gitter.im/Microsoft/BotBuilder) provides a place where the Community can get together and collaborate. ## Contributing and our code of conduct -We welcome contributions and suggestions. Please see our [contributing guidelines](./contributing.md) for more information. +We welcome contributions and suggestions. Please see our [contributing guidelines](./Contributing.md) for more information. This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). From ac28ca3d54a124cfc2c38765f64b9008e76801ab Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Wed, 28 May 2025 12:17:53 -0500 Subject: [PATCH 5/9] Teams SSO and OAuth fixes (#2226) * Fixed Teams SSO & OAuth * Formatting --------- Co-authored-by: Tracy Boehrer --- .../requirements.txt | 2 +- libraries/botbuilder-ai/setup.py | 2 +- .../botbuilder/core/__init__.py | 2 ++ .../botbuilder/core/activity_handler.py | 11 +++++-- .../core/teams/teams_activity_handler.py | 11 ++----- .../teams_sso_token_exchange_middleware.py | 19 ++++++++++-- .../dialogs/prompts/oauth_prompt.py | 8 +++++ .../integration/aiohttp/cloud_adapter.py | 6 +++- .../requirements.txt | 2 +- .../botbuilder-integration-aiohttp/setup.py | 2 +- .../setup.py | 2 +- .../botbuilder/schema/_models_py3.py | 3 ++ .../connector/token_api/models/__init__.py | 3 ++ .../connector/token_api/models/_models.py | 24 ++++++++++++++ .../connector/token_api/models/_models_py3.py | 31 ++++++++++++++++++- .../skills-buffered/child/requirements.txt | 2 +- .../skills-buffered/parent/requirements.txt | 2 +- 17 files changed, 110 insertions(+), 22 deletions(-) diff --git a/libraries/botbuilder-adapters-slack/requirements.txt b/libraries/botbuilder-adapters-slack/requirements.txt index 8dd02c6be..50f1af767 100644 --- a/libraries/botbuilder-adapters-slack/requirements.txt +++ b/libraries/botbuilder-adapters-slack/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.10.11 +aiohttp pyslack botbuilder-core==4.17.0 slackclient diff --git a/libraries/botbuilder-ai/setup.py b/libraries/botbuilder-ai/setup.py index 707369967..10bc3ee5c 100644 --- a/libraries/botbuilder-ai/setup.py +++ b/libraries/botbuilder-ai/setup.py @@ -8,7 +8,7 @@ "azure-cognitiveservices-language-luis==0.2.0", "botbuilder-schema==4.17.0", "botbuilder-core==4.17.0", - "aiohttp==3.10.11", + "aiohttp>=3.10,<4.0", ] TESTS_REQUIRES = ["aiounittest>=1.1.0"] diff --git a/libraries/botbuilder-core/botbuilder/core/__init__.py b/libraries/botbuilder-core/botbuilder/core/__init__.py index c5c038353..0769d9100 100644 --- a/libraries/botbuilder-core/botbuilder/core/__init__.py +++ b/libraries/botbuilder-core/botbuilder/core/__init__.py @@ -48,6 +48,7 @@ from .user_state import UserState from .register_class_middleware import RegisterClassMiddleware from .adapter_extensions import AdapterExtensions +from .serializer_helper import serializer_helper __all__ = [ "ActivityHandler", @@ -100,5 +101,6 @@ "TurnContext", "UserState", "UserTokenProvider", + "serializer_helper", "__version__", ] diff --git a/libraries/botbuilder-core/botbuilder/core/activity_handler.py b/libraries/botbuilder-core/botbuilder/core/activity_handler.py index 51aefb245..4dbf04f0b 100644 --- a/libraries/botbuilder-core/botbuilder/core/activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/activity_handler.py @@ -478,12 +478,19 @@ async def on_invoke_activity( # pylint: disable=unused-argument if ( turn_context.activity.name == SignInConstants.verify_state_operation_name - or turn_context.activity.name - == SignInConstants.token_exchange_operation_name ): await self.on_sign_in_invoke(turn_context) return self._create_invoke_response() + # This is for back-compat with previous versions of Python SDK. This method does not + # exist in the C# SDK, and is not used in the Python SDK. + if ( + turn_context.activity.name + == SignInConstants.token_exchange_operation_name + ): + await self.on_teams_signin_token_exchange(turn_context) + return self._create_invoke_response() + if turn_context.activity.name == "adaptiveCard/action": invoke_value = self._get_adaptive_card_invoke_value( turn_context.activity diff --git a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py index 9344e343e..2cc2e6fb6 100644 --- a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py @@ -56,13 +56,6 @@ async def on_invoke_activity(self, turn_context: TurnContext) -> InvokeResponse: ): return await self.on_teams_card_action_invoke(turn_context) - if ( - turn_context.activity.name - == SignInConstants.token_exchange_operation_name - ): - await self.on_teams_signin_token_exchange(turn_context) - return self._create_invoke_response() - if turn_context.activity.name == "fileConsent/invoke": return await self.on_teams_file_consent( turn_context, @@ -250,7 +243,9 @@ async def on_teams_signin_verify_state(self, turn_context: TurnContext): raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED) async def on_teams_signin_token_exchange(self, turn_context: TurnContext): - raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED) + # This is for back-compat with previous versions of Python SDK. This method does not + # exist in the C# SDK, and is not used in the Python SDK. + return await self.on_teams_signin_verify_state(turn_context) async def on_teams_file_consent( self, diff --git a/libraries/botbuilder-core/botbuilder/core/teams/teams_sso_token_exchange_middleware.py b/libraries/botbuilder-core/botbuilder/core/teams/teams_sso_token_exchange_middleware.py index 1dec1210a..5a6fa5de6 100644 --- a/libraries/botbuilder-core/botbuilder/core/teams/teams_sso_token_exchange_middleware.py +++ b/libraries/botbuilder-core/botbuilder/core/teams/teams_sso_token_exchange_middleware.py @@ -26,6 +26,7 @@ StoreItem, TurnContext, ) +from botframework.connector.auth.user_token_client import UserTokenClient class _TokenStoreItem(StoreItem): @@ -147,17 +148,29 @@ async def _exchanged_token(self, turn_context: TurnContext) -> bool: token_exchange_response: TokenResponse = None aux_dict = {} if turn_context.activity.value: - for prop in ["id", "connection_name", "token", "properties"]: + for prop in ["id", "connectionName", "token", "properties"]: aux_dict[prop] = turn_context.activity.value.get(prop) token_exchange_request = TokenExchangeInvokeRequest( id=aux_dict["id"], - connection_name=aux_dict["connection_name"], + connection_name=aux_dict["connectionName"], token=aux_dict["token"], properties=aux_dict["properties"], ) try: adapter = turn_context.adapter - if isinstance(turn_context.adapter, ExtendedUserTokenProvider): + + user_token_client: UserTokenClient = turn_context.turn_state.get( + UserTokenClient.__name__, None + ) + if user_token_client: + # If the adapter has UserTokenClient, use it to exchange the token. + token_exchange_response = await user_token_client.exchange_token( + turn_context.activity.from_property.id, + token_exchange_request.connection_name, + turn_context.activity.channel_id, + TokenExchangeRequest(token=token_exchange_request.token), + ) + elif isinstance(turn_context.adapter, ExtendedUserTokenProvider): token_exchange_response = await adapter.exchange_token( turn_context, self._oauth_connection_name, diff --git a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py index d31a0b56a..270d4f324 100644 --- a/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py +++ b/libraries/botbuilder-dialogs/botbuilder/dialogs/prompts/oauth_prompt.py @@ -341,6 +341,13 @@ async def _send_oauth_card( if sign_in_resource.token_exchange_resource else None ) + + json_token_ex_post = ( + sign_in_resource.token_post_resource.as_dict() + if sign_in_resource.token_post_resource + else None + ) + prompt.attachments.append( CardFactory.oauth_card( OAuthCard( @@ -355,6 +362,7 @@ async def _send_oauth_card( ) ], token_exchange_resource=json_token_ex_resource, + token_post_resource=json_token_ex_post, ) ) ) diff --git a/libraries/botbuilder-integration-aiohttp/botbuilder/integration/aiohttp/cloud_adapter.py b/libraries/botbuilder-integration-aiohttp/botbuilder/integration/aiohttp/cloud_adapter.py index 0f9131871..576c5125c 100644 --- a/libraries/botbuilder-integration-aiohttp/botbuilder/integration/aiohttp/cloud_adapter.py +++ b/libraries/botbuilder-integration-aiohttp/botbuilder/integration/aiohttp/cloud_adapter.py @@ -1,6 +1,8 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +import json + from typing import Awaitable, Callable, Optional from aiohttp.web import ( @@ -17,6 +19,7 @@ Bot, CloudAdapterBase, InvokeResponse, + serializer_helper, TurnContext, ) from botbuilder.core.streaming import ( @@ -102,7 +105,8 @@ async def process( # Write the response, serializing the InvokeResponse if invoke_response: return json_response( - data=invoke_response.body, status=invoke_response.status + data=serializer_helper(invoke_response.body), + status=invoke_response.status, ) return Response(status=201) else: diff --git a/libraries/botbuilder-integration-aiohttp/requirements.txt b/libraries/botbuilder-integration-aiohttp/requirements.txt index 4344965ca..d66ba0327 100644 --- a/libraries/botbuilder-integration-aiohttp/requirements.txt +++ b/libraries/botbuilder-integration-aiohttp/requirements.txt @@ -1,4 +1,4 @@ msrest== 0.7.* botframework-connector==4.17.0 botbuilder-schema==4.17.0 -aiohttp==3.10.11 +aiohttp==3.*.* diff --git a/libraries/botbuilder-integration-aiohttp/setup.py b/libraries/botbuilder-integration-aiohttp/setup.py index 635e26fc1..2624c9dc8 100644 --- a/libraries/botbuilder-integration-aiohttp/setup.py +++ b/libraries/botbuilder-integration-aiohttp/setup.py @@ -10,7 +10,7 @@ "botframework-connector==4.17.0", "botbuilder-core==4.17.0", "yarl>=1.8.1", - "aiohttp==3.10.11", + "aiohttp>=3.10,<4.0", ] root = os.path.abspath(os.path.dirname(__file__)) diff --git a/libraries/botbuilder-integration-applicationinsights-aiohttp/setup.py b/libraries/botbuilder-integration-applicationinsights-aiohttp/setup.py index 3ef0ca426..78c32e5eb 100644 --- a/libraries/botbuilder-integration-applicationinsights-aiohttp/setup.py +++ b/libraries/botbuilder-integration-applicationinsights-aiohttp/setup.py @@ -6,7 +6,7 @@ REQUIRES = [ "applicationinsights>=0.11.9", - "aiohttp==3.10.11", + "aiohttp>=3.10,<4.0", "botbuilder-schema==4.17.0", "botframework-connector==4.17.0", "botbuilder-core==4.17.0", diff --git a/libraries/botbuilder-schema/botbuilder/schema/_models_py3.py b/libraries/botbuilder-schema/botbuilder/schema/_models_py3.py index 1b6a631c6..e7dd1f789 100644 --- a/libraries/botbuilder-schema/botbuilder/schema/_models_py3.py +++ b/libraries/botbuilder-schema/botbuilder/schema/_models_py3.py @@ -1909,6 +1909,7 @@ class OAuthCard(Model): "connection_name": {"key": "connectionName", "type": "str"}, "buttons": {"key": "buttons", "type": "[CardAction]"}, "token_exchange_resource": {"key": "tokenExchangeResource", "type": "object"}, + "token_post_resource": {"key": "tokenPostResource", "type": "object"}, } def __init__( @@ -1918,6 +1919,7 @@ def __init__( connection_name: str = None, buttons=None, token_exchange_resource=None, + token_post_resource=None, **kwargs ) -> None: super(OAuthCard, self).__init__(**kwargs) @@ -1925,6 +1927,7 @@ def __init__( self.connection_name = connection_name self.buttons = buttons self.token_exchange_resource = token_exchange_resource + self.token_post_resource = token_post_resource class PagedMembersResult(Model): diff --git a/libraries/botframework-connector/botframework/connector/token_api/models/__init__.py b/libraries/botframework-connector/botframework/connector/token_api/models/__init__.py index f4593e21a..0f1f158da 100644 --- a/libraries/botframework-connector/botframework/connector/token_api/models/__init__.py +++ b/libraries/botframework-connector/botframework/connector/token_api/models/__init__.py @@ -13,6 +13,7 @@ from ._models_py3 import SignInUrlResponse from ._models_py3 import TokenExchangeRequest from ._models_py3 import TokenExchangeResource + from ._models_py3 import TokenPostResource from ._models_py3 import TokenResponse from ._models_py3 import TokenStatus except (SyntaxError, ImportError): @@ -23,6 +24,7 @@ from ._models import SignInUrlResponse from ._models import TokenExchangeRequest from ._models import TokenExchangeResource + from ._models import TokenPostResource from ._models import TokenResponse from ._models import TokenStatus @@ -35,6 +37,7 @@ "SignInUrlResponse", "TokenExchangeRequest", "TokenExchangeResource", + "TokenPostResource", "TokenResponse", "TokenStatus", ] diff --git a/libraries/botframework-connector/botframework/connector/token_api/models/_models.py b/libraries/botframework-connector/botframework/connector/token_api/models/_models.py index 5f69104cd..8b526324a 100644 --- a/libraries/botframework-connector/botframework/connector/token_api/models/_models.py +++ b/libraries/botframework-connector/botframework/connector/token_api/models/_models.py @@ -104,6 +104,9 @@ class SignInUrlResponse(Model): :param token_exchange_resource: :type token_exchange_resource: ~botframework.tokenapi.models.TokenExchangeResource + :param token_post_resource: + :type token_post_resource: + ~botframework.tokenapi.models.TokenPostResource """ _attribute_map = { @@ -112,12 +115,17 @@ class SignInUrlResponse(Model): "key": "tokenExchangeResource", "type": "TokenExchangeResource", }, + "token_post_resource": { + "key": "tokenPostResource", + "type": "TokenPostResource", + }, } def __init__(self, **kwargs): super(SignInUrlResponse, self).__init__(**kwargs) self.sign_in_link = kwargs.get("sign_in_link", None) self.token_exchange_resource = kwargs.get("token_exchange_resource", None) + self.token_exchange_resource = kwargs.get("token_post_resource", None) class TokenExchangeRequest(Model): @@ -164,6 +172,22 @@ def __init__(self, **kwargs): self.provider_id = kwargs.get("provider_id", None) +class TokenPostResource(Model): + """TokenPostResource. + + :param sas_url: + :type id: str + """ + + _attribute_map = { + "sas_url": {"key": "sasUrl", "type": "str"}, + } + + def __init__(self, **kwargs): + super(TokenPostResource, self).__init__(**kwargs) + self.sas_url = kwargs.get("sas_url", None) + + class TokenResponse(Model): """TokenResponse. diff --git a/libraries/botframework-connector/botframework/connector/token_api/models/_models_py3.py b/libraries/botframework-connector/botframework/connector/token_api/models/_models_py3.py index 60ab62c92..512e85356 100644 --- a/libraries/botframework-connector/botframework/connector/token_api/models/_models_py3.py +++ b/libraries/botframework-connector/botframework/connector/token_api/models/_models_py3.py @@ -106,6 +106,9 @@ class SignInUrlResponse(Model): :param token_exchange_resource: :type token_exchange_resource: ~botframework.tokenapi.models.TokenExchangeResource + :param token_post_resource: + :type token_post_resource: + ~botframework.tokenapi.models.TokenPostResource """ _attribute_map = { @@ -114,14 +117,24 @@ class SignInUrlResponse(Model): "key": "tokenExchangeResource", "type": "TokenExchangeResource", }, + "token_post_resource": { + "key": "tokenPostResource", + "type": "TokenPostResource", + }, } def __init__( - self, *, sign_in_link: str = None, token_exchange_resource=None, **kwargs + self, + *, + sign_in_link: str = None, + token_exchange_resource=None, + token_post_resource=None, + **kwargs ) -> None: super(SignInUrlResponse, self).__init__(**kwargs) self.sign_in_link = sign_in_link self.token_exchange_resource = token_exchange_resource + self.token_post_resource = token_post_resource class TokenExchangeRequest(Model): @@ -170,6 +183,22 @@ def __init__( self.provider_id = provider_id +class TokenPostResource(Model): + """TokenPostResource. + + :param sas_url: + :type id: str + """ + + _attribute_map = { + "sas_url": {"key": "sasUrl", "type": "str"}, + } + + def __init__(self, *, sas_url: str = None, **kwargs) -> None: + super(TokenPostResource, self).__init__(**kwargs) + self.sas_url = sas_url + + class TokenResponse(Model): """TokenResponse. diff --git a/tests/skills/skills-buffered/child/requirements.txt b/tests/skills/skills-buffered/child/requirements.txt index 20f8f8fe5..9e79c8115 100644 --- a/tests/skills/skills-buffered/child/requirements.txt +++ b/tests/skills/skills-buffered/child/requirements.txt @@ -1,2 +1,2 @@ botbuilder-core>=4.7.1 -aiohttp +aiohttp==3.*.* diff --git a/tests/skills/skills-buffered/parent/requirements.txt b/tests/skills/skills-buffered/parent/requirements.txt index 20f8f8fe5..9e79c8115 100644 --- a/tests/skills/skills-buffered/parent/requirements.txt +++ b/tests/skills/skills-buffered/parent/requirements.txt @@ -1,2 +1,2 @@ botbuilder-core>=4.7.1 -aiohttp +aiohttp==3.*.* From e535fac0c3cd1d0a33395c678d3a38a29cd6a7a4 Mon Sep 17 00:00:00 2001 From: Mark Jan van Kampen Date: Tue, 23 Dec 2025 20:08:24 +0100 Subject: [PATCH 6/9] chore: relaxes json pickle version constraint (#2240) --- libraries/botbuilder-azure/setup.py | 2 +- libraries/botbuilder-core/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/botbuilder-azure/setup.py b/libraries/botbuilder-azure/setup.py index 9c40b3ab5..7ff214d2e 100644 --- a/libraries/botbuilder-azure/setup.py +++ b/libraries/botbuilder-azure/setup.py @@ -10,7 +10,7 @@ "azure-storage-queue==12.4.0", "botbuilder-schema==4.17.0", "botframework-connector==4.17.0", - "jsonpickle>=1.2,<1.5", + "jsonpickle>=1.2,<4", ] TEST_REQUIRES = ["aiounittest==1.3.0"] diff --git a/libraries/botbuilder-core/setup.py b/libraries/botbuilder-core/setup.py index a4a0ed1af..24267bfb6 100644 --- a/libraries/botbuilder-core/setup.py +++ b/libraries/botbuilder-core/setup.py @@ -9,7 +9,7 @@ "botbuilder-schema==4.17.0", "botframework-connector==4.17.0", "botframework-streaming==4.17.0", - "jsonpickle>=1.2,<1.5", + "jsonpickle>=1.2,<4", ] root = os.path.abspath(os.path.dirname(__file__)) From df350e43f411e8b471f4bffc0df246d35c9440a6 Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 23 Dec 2025 13:53:28 -0600 Subject: [PATCH 7/9] README update (#2245) Co-authored-by: Tracy Boehrer --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index feace0e06..4e90050c0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,14 @@ # ![Bot Framework SDK v4 Python](./doc/media/FrameWorkPython.png) +# ARCHIVE NOTICE: + +> We are in the process of archiving the Bot Framework Python SDK repository on GitHub. This means that this project will no longer be updated or maintained. Customers using this tool will not be disrupted. However, the tool will no longer be supported through +> service tickets in the Azure portal and will not receive product updates. + +> To build agents with your choice of AI services, orchestration, and knowledge, consider using the [Microsoft 365 Agents SDK](https://github.com/microsoft/agents). The Agents SDK is GA and has support for C#, JavaScript or Python. You can learn more about the Agents SDK at aka.ms/agents. If you're looking for a SaaS-based agent platform, consider Microsoft Copilot Studio. If you have an existing bot built with the Bot Framework SDK, you can update your bot to the Agents SDK. You can review the core changes and updates at Bot Framework SDK to Agents SDK migration guidance [here](https://learn.microsoft.com/en-us/microsoft-365/agents-sdk/bf-migration-guidance). Support tickets for the Bot Framework SDK will no longer be serviced as of December 31, 2025. + +> We plan to archive this project no later than end of December of 2025. + This repository contains code for the Python version of the [Microsoft Bot Framework SDK](https://github.com/Microsoft/botframework-sdk), which is part of the Microsoft Bot Framework - a comprehensive framework for building enterprise-grade conversational AI experiences. This SDK enables developers to model conversation and build sophisticated bot applications using Python. SDKs for [JavaScript](https://github.com/Microsoft/botbuilder-js) and [.NET](https://github.com/Microsoft/botbuilder-dotnet) are also available. From 72fa3be2be2c5fdbb88a074ceb2c0f7e1fe21558 Mon Sep 17 00:00:00 2001 From: Hiroshi Yoshioka <40815708+hyoshioka0128@users.noreply.github.com> Date: Tue, 30 Dec 2025 01:53:36 +0900 Subject: [PATCH 8/9] Fix typo in docstring for O365 connector card action (#2244) https://github.com/microsoft/botbuilder-python/blob/main/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py #PingMSFTDocs --- .../botbuilder/core/teams/teams_activity_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py index 2cc2e6fb6..af45ba5b6 100644 --- a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py @@ -314,7 +314,7 @@ async def on_teams_o365_connector_card_action( # pylint: disable=unused-argumen self, turn_context: TurnContext, query: O365ConnectorCardActionQuery ): """ - Invoked when a O365 Connector Card Action activity is received from the connector. + Invoked when an O365 Connector Card Action activity is received from the connector. :param turn_context: A context object for this turn. :param query: The O365 connector card HttpPOST invoke query. From e07ec54ed9a863b69a7cfae5162629383924709d Mon Sep 17 00:00:00 2001 From: warnov Date: Mon, 29 Dec 2025 11:54:12 -0500 Subject: [PATCH 9/9] Update template-BotApp-with-rg.json (#2209) update remoteDebuggingVersion from VS2017 to VS2022 Co-authored-by: tracyboehrer --- .../deployUseExistResourceGroup/template-BotApp-with-rg.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generators/app/templates/echo/{{cookiecutter.bot_name}}/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json b/generators/app/templates/echo/{{cookiecutter.bot_name}}/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json index 23a23b1cc..71425ee9a 100644 --- a/generators/app/templates/echo/{{cookiecutter.bot_name}}/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json +++ b/generators/app/templates/echo/{{cookiecutter.bot_name}}/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json @@ -239,7 +239,7 @@ "linuxFxVersion": "PYTHON|3.9", "requestTracingEnabled": false, "remoteDebuggingEnabled": false, - "remoteDebuggingVersion": "VS2017", + "remoteDebuggingVersion": "VS2022", "httpLoggingEnabled": true, "logsDirectorySizeLimit": 35, "detailedErrorLoggingEnabled": false, @@ -275,4 +275,4 @@ } } ] -} \ No newline at end of file +}