Repository: microsoft/botbuilder-python (python)

Issue:
[Bug] on_turn_error: unhandled error: 'text'
### [Github issues](https://github.com/Microsoft/botbuilder-python) should be used for bugs and feature requests. Use [Stack Overflow](https://stackoverflow.com/questions/tagged/botframework) for general "how-to" questions. 

## Version
latest

## Describe the bug
Using botbuilder-python and teams-ai SDK to build a Teams bot with AI response. When sideloading the bot in the M365 Copilot, on_turn_error will occur if trying to conversation with the bot.
Linked issue: https://github.com/microsoft/teams-ai/issues/2326

## To Reproduce
https://github.com/user-attachments/assets/f4192af5-4fc0-4c03-a8e7-ba79c19c14ff

```bash
[on_turn_error] unhandled error: 'text'
Traceback (most recent call last):
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\botbuilder\core\bot_adapter.py", line 174, in run_pipeline
    return await self._middleware.receive_activity_with_status(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\botbuilder\core\middleware_set.py", line 69, in receive_activity_with_status
    return await self.receive_activity_internal(context, callback)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\botbuilder\core\middleware_set.py", line 79, in receive_activity_internal
    return await callback(context)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\teams\app.py", line 745, in on_turn
    await self._start_long_running_call(context, self._on_turn)
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\teams\app.py", line 903, in _start_long_running_call
    return await func(context)
           ^^^^^^^^^^^^^^^^^^^
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\teams\app.py", line 751, in _on_turn
    self._remove_mentions(context)
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\teams\app.py", line 786, in _remove_mentions
    context.activity.text = context.remove_recipient_mention(context.activity)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\botbuilder\core\turn_context.py", line 392, in remove_recipient_mention
    return TurnContext.remove_mention_text(activity, activity.recipient.id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\frankqian\TeamsApps\test11\.venv\Lib\site-packages\botbuilder\core\turn_context.py", line 401, in remove_mention_text
    escape(mention.additional_properties["text"]),
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
KeyError: 'text'
```
## Expected behavior
Give a clear and concise description of what you expected to happen.

## Screenshots
If applicable, add screenshots to help explain your problem.

## Additional context
Add any other context about the problem here.


Pull request:
MentionRemoved fix
Fixes #2210 
This pull request includes changes to the `remove_mention_text` method in `turn_context.py` and adds a new test case in `test_turn_context.py` to ensure the method works correctly with custom mentions.

Improvements to `remove_mention_text` method:

* [`libraries/botbuilder-core/botbuilder/core/turn_context.py`](diffhunk://#diff-e80e0302ba9095fcef94e0004e727e78057cffb08bce12ef4339f05ed6d43e5cR399-R405): Modified the `remove_mention_text` method to handle cases where the mention text is not directly available by using either the `text` or `name` property from `additional_properties`.

Additions to test cases:

* [`libraries/botbuilder-core/tests/test_turn_context.py`](diffhunk://#diff-0aebc3cd5165e7e1ee742045c212d5a38e59a19a6fe57e9726e0d5964f01d530R353-R394): Added a new test case `test_should_remove_custom_mention_from_activity` to verify that the `remove_mention_text` method correctly removes custom mentions from the activity text.

Patch:
diff --git a/libraries/botbuilder-core/botbuilder/core/turn_context.py b/libraries/botbuilder-core/botbuilder/core/turn_context.py
index 852fd1f3..72e25726 100644
--- a/libraries/botbuilder-core/botbuilder/core/turn_context.py
+++ b/libraries/botbuilder-core/botbuilder/core/turn_context.py
@@ -396,9 +396,13 @@ class TurnContext:
         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(.*)>(.*?)<\/at>",
-                    escape(mention.additional_properties["text"]),
+                    escape(replace_text),
                     re.IGNORECASE,
                 )
                 if mention_name_match:


Test patch:
diff --git a/libraries/botbuilder-core/tests/test_turn_context.py b/libraries/botbuilder-core/tests/test_turn_context.py
index 473580ef..7247caab 100644
--- a/libraries/botbuilder-core/tests/test_turn_context.py
+++ b/libraries/botbuilder-core/tests/test_turn_context.py
@@ -350,6 +350,48 @@ class TestBotContext(aiounittest.AsyncTestCase):
         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