prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Avoid sending typing activity when bot is invoked as skill
  We should port this once the C# PR is merged.
  See [parent](https://github.com/microsoft/botframework-sdk/issues/6049)
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py`
  Content:
  ```
  1 # Copyright (c) Microsoft Corporation. All rights reserved.
  2 # Licensed under the MIT License.
  3 import asyncio
  4 from typing import Awaitable, Callable
  5 
  6 from botbuilder.schema import Activity, ActivityTypes
  7 
  8 from .middleware_set import Middleware
  9 from .turn_context import TurnContext
  10 
  11 
  12 class Timer:
  13     clear_timer = False
  14 
  15     def set_timeout(self, func, span):
  16         async def some_fn():  # pylint: disable=function-redefined
  17             await asyncio.sleep(span)
  18             if not self.clear_timer:
  19                 await func()
  20 
  21         asyncio.ensure_future(some_fn())
  22 
  23     def set_clear_timer(self):
  24         self.clear_timer = True
  25 
  26 
  27 class ShowTypingMiddleware(Middleware):
  28     """
  29     When added, this middleware will send typing activities back to the user when a Message activity
  30     is received to let them know that the bot has received the message and is working on the response.
  31     You can specify a delay before the first typing activity is sent and then a frequency, which
  32     determines how often another typing activity is sent. Typing activities will continue to be sent
  33     until your bot sends another message back to the user.
  34     """
  35 
  36     def __init__(self, delay: float = 0.5, period: float = 2.0):
  37         """
  38         Initializes the middleware.
  39 
  40         :param delay: Delay in seconds for the first typing indicator to be sent.
  41         :param period: Delay in seconds for subsequent typing indicators.
  42         """
  43 
  44         if delay < 0:
  45             raise ValueError("Delay must be greater than or equal to zero")
  46 
  47         if period <= 0:
  48             raise ValueError("Repeat period must be greater than zero")
  49 
  50         self._delay = delay
  51         self._period = period
  52 
  53     async def on_turn(
  54         self, context: TurnContext, logic: Callable[[TurnContext], Awaitable]
  55     ):
  56         timer = Timer()
  57 
  58         def start_interval(context: TurnContext, delay, period):
  59             async def aux():
  60                 typing_activity = Activity(
  61                     type=ActivityTypes.typing, relates_to=context.activity.relates_to,
  62                 )
  63 
  64                 conversation_reference = TurnContext.get_conversation_reference(
  65                     context.activity
  66                 )
  67 
  68                 typing_activity = TurnContext.apply_conversation_reference(
  69                     typing_activity, conversation_reference
  70                 )
  71 
  72                 asyncio.ensure_future(
  73                     context.adapter.send_activities(context, [typing_activity])
  74                 )
  75 
  76                 # restart the timer, with the 'period' value for the delay
  77                 timer.set_timeout(aux, period)
  78 
  79             # first time through we use the 'delay' value for the timer.
  80             timer.set_timeout(aux, delay)
  81 
  82         def stop_interval():
  83             timer.set_clear_timer()
  84 
  85         # if it's a message, start sending typing activities until the
  86         # bot logic is done.
  87         if context.activity.type == ActivityTypes.message:
  88             start_interval(context, self._delay, self._period)
  89 
  90         # call the bot logic
  91         result = await logic()
  92 
  93         stop_interval()
  94 
  95         return result
  96
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py b/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py
  --- a/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py
  +++ b/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py
  @@ -4,7 +4,9 @@
   from typing import Awaitable, Callable
   
   from botbuilder.schema import Activity, ActivityTypes
  +from botframework.connector.auth import ClaimsIdentity, SkillValidation
   
  +from .bot_adapter import BotAdapter
   from .middleware_set import Middleware
   from .turn_context import TurnContext
   
  @@ -82,9 +84,12 @@
           def stop_interval():
               timer.set_clear_timer()
   
  -        # if it's a message, start sending typing activities until the
  -        # bot logic is done.
  -        if context.activity.type == ActivityTypes.message:
  +        # Start a timer to periodically send the typing activity
  +        # (bots running as skills should not send typing activity)
  +        if (
  +            context.activity.type == ActivityTypes.message
  +            and not ShowTypingMiddleware._is_skill_bot(context)
  +        ):
               start_interval(context, self._delay, self._period)
   
           # call the bot logic
  @@ -93,3 +98,10 @@
           stop_interval()
   
           return result
  +
  +    @staticmethod
  +    def _is_skill_bot(context: TurnContext) -> bool:
  +        claims_identity = context.turn_state.get(BotAdapter.BOT_IDENTITY_KEY)
  +        return isinstance(
  +            claims_identity, ClaimsIdentity
  +        ) and SkillValidation.is_skill_claim(claims_identity.claims)
  
verification_info: {"golden_diff": "diff --git a/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py b/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py\n--- a/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py\n+++ b/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py\n@@ -4,7 +4,9 @@\n from typing import Awaitable, Callable\r\n \r\n from botbuilder.schema import Activity, ActivityTypes\r\n+from botframework.connector.auth import ClaimsIdentity, SkillValidation\r\n \r\n+from .bot_adapter import BotAdapter\r\n from .middleware_set import Middleware\r\n from .turn_context import TurnContext\r\n \r\n@@ -82,9 +84,12 @@\n         def stop_interval():\r\n             timer.set_clear_timer()\r\n \r\n-        # if it's a message, start sending typing activities until the\r\n-        # bot logic is done.\r\n-        if context.activity.type == ActivityTypes.message:\r\n+        # Start a timer to periodically send the typing activity\r\n+        # (bots running as skills should not send typing activity)\r\n+        if (\r\n+            context.activity.type == ActivityTypes.message\r\n+            and not ShowTypingMiddleware._is_skill_bot(context)\r\n+        ):\r\n             start_interval(context, self._delay, self._period)\r\n \r\n         # call the bot logic\r\n@@ -93,3 +98,10 @@\n         stop_interval()\r\n \r\n         return result\r\n+\r\n+    @staticmethod\r\n+    def _is_skill_bot(context: TurnContext) -> bool:\r\n+        claims_identity = context.turn_state.get(BotAdapter.BOT_IDENTITY_KEY)\r\n+        return isinstance(\r\n+            claims_identity, ClaimsIdentity\r\n+        ) and SkillValidation.is_skill_claim(claims_identity.claims)\n", "issue": "Avoid sending typing activity when bot is invoked as skill\nWe should port this once the C# PR is merged.\r\nSee [parent](https://github.com/microsoft/botframework-sdk/issues/6049)\n", "before_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\r\n# Licensed under the MIT License.\r\nimport asyncio\r\nfrom typing import Awaitable, Callable\r\n\r\nfrom botbuilder.schema import Activity, ActivityTypes\r\n\r\nfrom .middleware_set import Middleware\r\nfrom .turn_context import TurnContext\r\n\r\n\r\nclass Timer:\r\n    clear_timer = False\r\n\r\n    def set_timeout(self, func, span):\r\n        async def some_fn():  # pylint: disable=function-redefined\r\n            await asyncio.sleep(span)\r\n            if not self.clear_timer:\r\n                await func()\r\n\r\n        asyncio.ensure_future(some_fn())\r\n\r\n    def set_clear_timer(self):\r\n        self.clear_timer = True\r\n\r\n\r\nclass ShowTypingMiddleware(Middleware):\r\n    \"\"\"\r\n    When added, this middleware will send typing activities back to the user when a Message activity\r\n    is received to let them know that the bot has received the message and is working on the response.\r\n    You can specify a delay before the first typing activity is sent and then a frequency, which\r\n    determines how often another typing activity is sent. Typing activities will continue to be sent\r\n    until your bot sends another message back to the user.\r\n    \"\"\"\r\n\r\n    def __init__(self, delay: float = 0.5, period: float = 2.0):\r\n        \"\"\"\r\n        Initializes the middleware.\r\n\r\n        :param delay: Delay in seconds for the first typing indicator to be sent.\r\n        :param period: Delay in seconds for subsequent typing indicators.\r\n        \"\"\"\r\n\r\n        if delay < 0:\r\n            raise ValueError(\"Delay must be greater than or equal to zero\")\r\n\r\n        if period <= 0:\r\n            raise ValueError(\"Repeat period must be greater than zero\")\r\n\r\n        self._delay = delay\r\n        self._period = period\r\n\r\n    async def on_turn(\r\n        self, context: TurnContext, logic: Callable[[TurnContext], Awaitable]\r\n    ):\r\n        timer = Timer()\r\n\r\n        def start_interval(context: TurnContext, delay, period):\r\n            async def aux():\r\n                typing_activity = Activity(\r\n                    type=ActivityTypes.typing, relates_to=context.activity.relates_to,\r\n                )\r\n\r\n                conversation_reference = TurnContext.get_conversation_reference(\r\n                    context.activity\r\n                )\r\n\r\n                typing_activity = TurnContext.apply_conversation_reference(\r\n                    typing_activity, conversation_reference\r\n                )\r\n\r\n                asyncio.ensure_future(\r\n                    context.adapter.send_activities(context, [typing_activity])\r\n                )\r\n\r\n                # restart the timer, with the 'period' value for the delay\r\n                timer.set_timeout(aux, period)\r\n\r\n            # first time through we use the 'delay' value for the timer.\r\n            timer.set_timeout(aux, delay)\r\n\r\n        def stop_interval():\r\n            timer.set_clear_timer()\r\n\r\n        # if it's a message, start sending typing activities until the\r\n        # bot logic is done.\r\n        if context.activity.type == ActivityTypes.message:\r\n            start_interval(context, self._delay, self._period)\r\n\r\n        # call the bot logic\r\n        result = await logic()\r\n\r\n        stop_interval()\r\n\r\n        return result\r\n", "path": "libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py"}], "after_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\r\n# Licensed under the MIT License.\r\nimport asyncio\r\nfrom typing import Awaitable, Callable\r\n\r\nfrom botbuilder.schema import Activity, ActivityTypes\r\nfrom botframework.connector.auth import ClaimsIdentity, SkillValidation\r\n\r\nfrom .bot_adapter import BotAdapter\r\nfrom .middleware_set import Middleware\r\nfrom .turn_context import TurnContext\r\n\r\n\r\nclass Timer:\r\n    clear_timer = False\r\n\r\n    def set_timeout(self, func, span):\r\n        async def some_fn():  # pylint: disable=function-redefined\r\n            await asyncio.sleep(span)\r\n            if not self.clear_timer:\r\n                await func()\r\n\r\n        asyncio.ensure_future(some_fn())\r\n\r\n    def set_clear_timer(self):\r\n        self.clear_timer = True\r\n\r\n\r\nclass ShowTypingMiddleware(Middleware):\r\n    \"\"\"\r\n    When added, this middleware will send typing activities back to the user when a Message activity\r\n    is received to let them know that the bot has received the message and is working on the response.\r\n    You can specify a delay before the first typing activity is sent and then a frequency, which\r\n    determines how often another typing activity is sent. Typing activities will continue to be sent\r\n    until your bot sends another message back to the user.\r\n    \"\"\"\r\n\r\n    def __init__(self, delay: float = 0.5, period: float = 2.0):\r\n        \"\"\"\r\n        Initializes the middleware.\r\n\r\n        :param delay: Delay in seconds for the first typing indicator to be sent.\r\n        :param period: Delay in seconds for subsequent typing indicators.\r\n        \"\"\"\r\n\r\n        if delay < 0:\r\n            raise ValueError(\"Delay must be greater than or equal to zero\")\r\n\r\n        if period <= 0:\r\n            raise ValueError(\"Repeat period must be greater than zero\")\r\n\r\n        self._delay = delay\r\n        self._period = period\r\n\r\n    async def on_turn(\r\n        self, context: TurnContext, logic: Callable[[TurnContext], Awaitable]\r\n    ):\r\n        timer = Timer()\r\n\r\n        def start_interval(context: TurnContext, delay, period):\r\n            async def aux():\r\n                typing_activity = Activity(\r\n                    type=ActivityTypes.typing, relates_to=context.activity.relates_to,\r\n                )\r\n\r\n                conversation_reference = TurnContext.get_conversation_reference(\r\n                    context.activity\r\n                )\r\n\r\n                typing_activity = TurnContext.apply_conversation_reference(\r\n                    typing_activity, conversation_reference\r\n                )\r\n\r\n                asyncio.ensure_future(\r\n                    context.adapter.send_activities(context, [typing_activity])\r\n                )\r\n\r\n                # restart the timer, with the 'period' value for the delay\r\n                timer.set_timeout(aux, period)\r\n\r\n            # first time through we use the 'delay' value for the timer.\r\n            timer.set_timeout(aux, delay)\r\n\r\n        def stop_interval():\r\n            timer.set_clear_timer()\r\n\r\n        # Start a timer to periodically send the typing activity\r\n        # (bots running as skills should not send typing activity)\r\n        if (\r\n            context.activity.type == ActivityTypes.message\r\n            and not ShowTypingMiddleware._is_skill_bot(context)\r\n        ):\r\n            start_interval(context, self._delay, self._period)\r\n\r\n        # call the bot logic\r\n        result = await logic()\r\n\r\n        stop_interval()\r\n\r\n        return result\r\n\r\n    @staticmethod\r\n    def _is_skill_bot(context: TurnContext) -> bool:\r\n        claims_identity = context.turn_state.get(BotAdapter.BOT_IDENTITY_KEY)\r\n        return isinstance(\r\n            claims_identity, ClaimsIdentity\r\n        ) and SkillValidation.is_skill_claim(claims_identity.claims)\r\n", "path": "libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py"}]}