microsoft-agents-hosting-core 0.6.0.dev11__py3-none-any.whl → 0.6.0.dev16__py3-none-any.whl

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.
@@ -683,8 +683,8 @@ class AgentApplication(Agent, Generic[StateT]):
683
683
  try:
684
684
  if context.activity.type != ActivityTypes.typing:
685
685
  if self._options.start_typing_timer:
686
- typing = TypingIndicator()
687
- await typing.start(context)
686
+ typing = TypingIndicator(context)
687
+ typing.start()
688
688
 
689
689
  self._remove_mentions(context)
690
690
 
@@ -733,7 +733,7 @@ class AgentApplication(Agent, Generic[StateT]):
733
733
  await self._on_error(context, err)
734
734
  finally:
735
735
  if typing:
736
- await typing.stop()
736
+ typing.stop()
737
737
 
738
738
  def _remove_mentions(self, context: TurnContext):
739
739
  if (
@@ -4,9 +4,9 @@ Licensed under the MIT License.
4
4
  """
5
5
 
6
6
  from __future__ import annotations
7
+
7
8
  import asyncio
8
9
  import logging
9
-
10
10
  from typing import Optional
11
11
 
12
12
  from microsoft_agents.hosting.core import TurnContext
@@ -18,61 +18,64 @@ logger = logging.getLogger(__name__)
18
18
  class TypingIndicator:
19
19
  """
20
20
  Encapsulates the logic for sending "typing" activity to the user.
21
+
22
+ Scoped to a single turn of conversation with the user.
21
23
  """
22
24
 
23
- def __init__(self, intervalSeconds=1) -> None:
24
- self._intervalSeconds = intervalSeconds
25
- self._task: Optional[asyncio.Task] = None
26
- self._running: bool = False
27
- self._lock = asyncio.Lock()
25
+ def __init__(self, context: TurnContext, interval_seconds: float = 10.0) -> None:
26
+ """Initializes a new instance of the TypingIndicator class.
28
27
 
29
- async def start(self, context: TurnContext) -> None:
30
- async with self._lock:
31
- if self._running:
32
- return
28
+ :param context: The turn context.
29
+ :param interval_seconds: The interval in seconds between typing indicators.
30
+ """
31
+ if interval_seconds <= 0:
32
+ raise ValueError("interval_seconds must be greater than 0")
33
+ self._context: TurnContext = context
34
+ self._interval: float = interval_seconds
35
+ self._task: Optional[asyncio.Task[None]] = None
33
36
 
34
- logger.debug(
35
- f"Starting typing indicator with interval: {self._intervalSeconds} seconds"
36
- )
37
- self._running = True
38
- self._task = asyncio.create_task(self._typing_loop(context))
39
-
40
- async def stop(self) -> None:
41
- async with self._lock:
42
- if not self._running:
43
- return
44
-
45
- logger.debug("Stopping typing indicator")
46
- self._running = False
47
- task = self._task
48
- self._task = None
49
-
50
- # Cancel outside the lock to avoid blocking
51
- if task and not task.done():
52
- task.cancel()
53
- try:
54
- await task
55
- except asyncio.CancelledError:
56
- pass
57
-
58
- async def _typing_loop(self, context: TurnContext):
59
- """Continuously send typing indicators at the specified interval."""
37
+ async def _run(self) -> None:
38
+ """Sends typing indicators at regular intervals."""
39
+
40
+ running_task = self._task
60
41
  try:
61
- while True:
62
- # Check running status under lock
63
- async with self._lock:
64
- if not self._running:
65
- break
66
-
67
- try:
68
- logger.debug("Sending typing activity")
69
- await context.send_activity(Activity(type=ActivityTypes.typing))
70
- except Exception as e:
71
- logger.error(f"Error sending typing activity: {e}")
72
- async with self._lock:
73
- self._running = False
74
- break
75
-
76
- await asyncio.sleep(self._intervalSeconds)
42
+ while running_task is self._task:
43
+ await self._context.send_activity(Activity(type=ActivityTypes.typing))
44
+ await asyncio.sleep(self._interval)
77
45
  except asyncio.CancelledError:
78
- logger.debug("Typing indicator loop cancelled")
46
+ # Task was cancelled, exit gracefully
47
+ pass
48
+
49
+ def start(self) -> None:
50
+ """Starts sending typing indicators."""
51
+
52
+ if self._task is not None:
53
+ logger.warning(
54
+ "Typing indicator is already running for conversation %s",
55
+ self._context.activity.conversation.id,
56
+ )
57
+ return
58
+
59
+ logger.debug(
60
+ "Starting typing indicator with interval: %s seconds in conversation %s",
61
+ self._interval,
62
+ self._context.activity.conversation.id,
63
+ )
64
+ self._task = asyncio.create_task(self._run())
65
+
66
+ def stop(self) -> None:
67
+ """Stops sending typing indicators."""
68
+
69
+ if self._task is None:
70
+ logger.warning(
71
+ "Typing indicator is not running for conversation %s",
72
+ self._context.activity.conversation.id,
73
+ )
74
+ return
75
+
76
+ logger.debug(
77
+ "Stopping typing indicator for conversation %s",
78
+ self._context.activity.conversation.id,
79
+ )
80
+ self._task.cancel()
81
+ self._task = None
@@ -8,7 +8,8 @@ This module provides centralized error messages with error codes and help URLs
8
8
  following the pattern established in the C# SDK.
9
9
  """
10
10
 
11
- from .error_message import ErrorMessage
11
+ from microsoft_agents.activity.errors import ErrorMessage
12
+
12
13
  from .error_resources import ErrorResources
13
14
 
14
15
  # Singleton instance
@@ -9,7 +9,7 @@ Error codes are in the range -63000 to -63999 for hosting errors.
9
9
  General/validation errors are in the range -66000 to -66999.
10
10
  """
11
11
 
12
- from .error_message import ErrorMessage
12
+ from microsoft_agents.activity.errors import ErrorMessage
13
13
 
14
14
 
15
15
  class ErrorResources:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-hosting-core
3
- Version: 0.6.0.dev11
3
+ Version: 0.6.0.dev16
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==0.6.0.dev11
18
+ Requires-Dist: microsoft-agents-activity==0.6.0.dev16
19
19
  Requires-Dist: pyjwt>=2.10.1
20
20
  Requires-Dist: isodate>=0.6.1
21
21
  Requires-Dist: azure-core>=1.30.0
@@ -16,12 +16,12 @@ microsoft_agents/hosting/core/_oauth/_flow_storage_client.py,sha256=1MLD8m_qw0jS
16
16
  microsoft_agents/hosting/core/_oauth/_oauth_flow.py,sha256=vgg_sQLYr83YA0F7aQ1K5j8vEATw7ZS151ODkpCGYAM,12211
17
17
  microsoft_agents/hosting/core/app/__init__.py,sha256=GZQdog7BBMA8uD9iaRMNeRJf12rJZB3bAKFAD8Y8dVo,1228
18
18
  microsoft_agents/hosting/core/app/_type_defs.py,sha256=b5VZFWnQ5ONUZMtFxw7Q-mbbxIUSJ7RXcCXjqdHwSQw,438
19
- microsoft_agents/hosting/core/app/agent_application.py,sha256=HEOYRgpT9iN_YRu8MbV--O8yoOiz3CquB9ZGjQ1_fX0,33996
19
+ microsoft_agents/hosting/core/app/agent_application.py,sha256=iqcsLM4k_BWY0KKI1Ia-W11geuIHF8TP3mRc3D1eVF0,33984
20
20
  microsoft_agents/hosting/core/app/app_error.py,sha256=JgYBgv2EKe9Q2TFi5FeG_RneulBEa5SyBpWSF-duBzE,301
21
21
  microsoft_agents/hosting/core/app/app_options.py,sha256=P3XTFFuQCnEcHixfdmr5RPG-Wli4c1VSmCMRKVBBLsw,2792
22
22
  microsoft_agents/hosting/core/app/input_file.py,sha256=AEzVAnAPO1V7MWDI_uoZfcYY8Oog3XgvEpAeO-tATeY,1546
23
23
  microsoft_agents/hosting/core/app/query.py,sha256=lToDWFG7exUyPC5zxvna89013fDPKrUGOI8jyWFoUYk,328
24
- microsoft_agents/hosting/core/app/typing_indicator.py,sha256=L4zEqDHeu_0JmpDQwaB-j84TFLYzUAH0-tFUEfOxD0g,2442
24
+ microsoft_agents/hosting/core/app/typing_indicator.py,sha256=2T9pmy0raz0Y84HMZ4taGL0q8iIEUxhQ2rQhQg9sV2I,2558
25
25
  microsoft_agents/hosting/core/app/_routes/__init__.py,sha256=faz05Hk5Z1IGIXUwXljohym0lzE8nW3CbTpXlE-VcB0,300
26
26
  microsoft_agents/hosting/core/app/_routes/_route.py,sha256=gs5XVi74H1wzDShpZd9ZXVDrREjricFYVPz10XrK06c,2669
27
27
  microsoft_agents/hosting/core/app/_routes/_route_list.py,sha256=fe1-wmFaJJqYkWFcbNhJ9OMH954TneQR0-uoxyKQVlU,874
@@ -76,9 +76,8 @@ microsoft_agents/hosting/core/connector/client/connector_client.py,sha256=9oF_x_
76
76
  microsoft_agents/hosting/core/connector/client/user_token_client.py,sha256=qxYxvdUcvYinCzaR4YiIucEEAb8TjYYtPsmXKZRbxv4,10536
77
77
  microsoft_agents/hosting/core/connector/teams/__init__.py,sha256=3ZMPGYyZ15EwvfQzfJJQy1J58oIt4InSxibl3BN6R54,100
78
78
  microsoft_agents/hosting/core/connector/teams/teams_connector_client.py,sha256=XGQDTYHrA_I9n9JlxGST5eesjsFhz2dnSaMSuyoFnKU,12676
79
- microsoft_agents/hosting/core/errors/__init__.py,sha256=2BiNgN84UxPl1Q1kZuQ_a36S7sIwvHE4H6MTmgp6cCk,481
80
- microsoft_agents/hosting/core/errors/error_message.py,sha256=UTEsUaIoISZjDjGgr-bwQqKmqA8AN1jE-cjN9U8921Y,2102
81
- microsoft_agents/hosting/core/errors/error_resources.py,sha256=41b2DM3aS_89MN6NHO3l6uqxjhBudgfU1uFQAteEpIQ,3904
79
+ microsoft_agents/hosting/core/errors/__init__.py,sha256=kcfwDGDaopWfLyvYsNXM6j4cYt2oGKysjCRDezcVY0A,500
80
+ microsoft_agents/hosting/core/errors/error_resources.py,sha256=_nyvPQaX3gpi9kziajVdzGWCzMa6JcTntK__zQJlGMo,3922
82
81
  microsoft_agents/hosting/core/state/__init__.py,sha256=yckKi1wg_86ng-DL9Q3R49QiWKvNjPkVNk6HClWgVrY,208
83
82
  microsoft_agents/hosting/core/state/agent_state.py,sha256=uboptWaC3VrSGTnXIzaO38XUqOT-ITW6EhJxuGMtKWs,13724
84
83
  microsoft_agents/hosting/core/state/state_property_accessor.py,sha256=kpiNnzkZ6el-oRITRbRkk1Faa_CPFxpJQdvSGxIJP70,1392
@@ -94,8 +93,8 @@ microsoft_agents/hosting/core/storage/transcript_info.py,sha256=5VN32j99tshChAff
94
93
  microsoft_agents/hosting/core/storage/transcript_logger.py,sha256=_atDk3CJ05fIVMhlWGNa91IiM9bGLmOhasFko8Lxjhk,8237
95
94
  microsoft_agents/hosting/core/storage/transcript_memory_store.py,sha256=v1Ud9LSs8m5c9_Fa8i49SuAjw80dX1hDciqbRduDEOE,6444
96
95
  microsoft_agents/hosting/core/storage/transcript_store.py,sha256=ka74o0WvI5GhMZcFqSxVdamBhGzZcDZe6VNkG-sMy74,1944
97
- microsoft_agents_hosting_core-0.6.0.dev11.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
98
- microsoft_agents_hosting_core-0.6.0.dev11.dist-info/METADATA,sha256=yd85NaZ-vgi3his-UEveuHuCad0QFQZQDKXWN9yliMk,9244
99
- microsoft_agents_hosting_core-0.6.0.dev11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
100
- microsoft_agents_hosting_core-0.6.0.dev11.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
101
- microsoft_agents_hosting_core-0.6.0.dev11.dist-info/RECORD,,
96
+ microsoft_agents_hosting_core-0.6.0.dev16.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
97
+ microsoft_agents_hosting_core-0.6.0.dev16.dist-info/METADATA,sha256=ncM6FbZU1KZIuVrVNUfQ4818ID5lnEmZDDoUD-8Fcyo,9244
98
+ microsoft_agents_hosting_core-0.6.0.dev16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
99
+ microsoft_agents_hosting_core-0.6.0.dev16.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
100
+ microsoft_agents_hosting_core-0.6.0.dev16.dist-info/RECORD,,
@@ -1,64 +0,0 @@
1
- # Copyright (c) Microsoft Corporation. All rights reserved.
2
- # Licensed under the MIT License.
3
-
4
- """
5
- ErrorMessage class for formatting error messages with error codes and help URLs.
6
- """
7
-
8
-
9
- class ErrorMessage:
10
- """
11
- Represents a formatted error message with error code and help URL.
12
-
13
- This class formats error messages according to the Microsoft Agents SDK pattern:
14
- - Original error message
15
- - Error Code: [negative number]
16
- - Help URL: https://aka.ms/M365AgentsErrorCodes/#[error_code]
17
- """
18
-
19
- def __init__(
20
- self,
21
- message_template: str,
22
- error_code: int,
23
- ):
24
- """
25
- Initialize an ErrorMessage.
26
-
27
- :param message_template: The error message template (may include format placeholders)
28
- :type message_template: str
29
- :param error_code: The error code (should be negative)
30
- :type error_code: int
31
- """
32
- self.message_template = message_template
33
- self.error_code = error_code
34
- self.base_url = "https://aka.ms/M365AgentsErrorCodes"
35
-
36
- def format(self, *args, **kwargs) -> str:
37
- """
38
- Format the error message with the provided arguments.
39
-
40
- :param args: Positional arguments for string formatting
41
- :param kwargs: Keyword arguments for string formatting
42
- :return: Formatted error message with error code and help URL
43
- :rtype: str
44
- """
45
- # Format the main message
46
- if args or kwargs:
47
- message = self.message_template.format(*args, **kwargs)
48
- else:
49
- message = self.message_template
50
-
51
- # Append error code and help URL
52
- return (
53
- f"{message}\n\n"
54
- f"Error Code: {self.error_code}\n"
55
- f"Help URL: {self.base_url}/#{self.error_code}"
56
- )
57
-
58
- def __str__(self) -> str:
59
- """Return the formatted error message without any arguments."""
60
- return self.format()
61
-
62
- def __repr__(self) -> str:
63
- """Return a representation of the ErrorMessage."""
64
- return f"ErrorMessage(code={self.error_code}, message='{self.message_template[:50]}...')"