microsoft-agents-hosting-core 0.6.0.dev10__py3-none-any.whl → 0.6.0.dev15__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:
@@ -25,176 +25,147 @@ class ErrorResources:
25
25
  AdapterRequired = ErrorMessage(
26
26
  "start_agent_process: adapter can't be None",
27
27
  -63000,
28
- "hosting-configuration",
29
28
  )
30
29
 
31
30
  AgentApplicationRequired = ErrorMessage(
32
31
  "start_agent_process: agent_application can't be None",
33
32
  -63001,
34
- "hosting-configuration",
35
33
  )
36
34
 
37
35
  RequestRequired = ErrorMessage(
38
36
  "CloudAdapter.process: request can't be None",
39
37
  -63002,
40
- "hosting-configuration",
41
38
  )
42
39
 
43
40
  AgentRequired = ErrorMessage(
44
41
  "CloudAdapter.process: agent can't be None",
45
42
  -63003,
46
- "hosting-configuration",
47
43
  )
48
44
 
49
45
  StreamAlreadyEnded = ErrorMessage(
50
46
  "The stream has already ended.",
51
47
  -63004,
52
- "streaming",
53
48
  )
54
49
 
55
50
  TurnContextRequired = ErrorMessage(
56
51
  "TurnContext cannot be None.",
57
52
  -63005,
58
- "hosting-configuration",
59
53
  )
60
54
 
61
55
  ActivityRequired = ErrorMessage(
62
56
  "Activity cannot be None.",
63
57
  -63006,
64
- "hosting-configuration",
65
58
  )
66
59
 
67
60
  AppIdRequired = ErrorMessage(
68
61
  "AppId cannot be empty or None.",
69
62
  -63007,
70
- "hosting-configuration",
71
63
  )
72
64
 
73
65
  InvalidActivityType = ErrorMessage(
74
66
  "Invalid or missing activity type.",
75
67
  -63008,
76
- "hosting-configuration",
77
68
  )
78
69
 
79
70
  ConversationIdRequired = ErrorMessage(
80
71
  "Conversation ID cannot be empty or None.",
81
72
  -63009,
82
- "hosting-configuration",
83
73
  )
84
74
 
85
75
  AuthHeaderRequired = ErrorMessage(
86
76
  "Authorization header is required.",
87
77
  -63010,
88
- "hosting-configuration",
89
78
  )
90
79
 
91
80
  InvalidAuthHeader = ErrorMessage(
92
81
  "Invalid authorization header format.",
93
82
  -63011,
94
- "hosting-configuration",
95
83
  )
96
84
 
97
85
  ClaimsIdentityRequired = ErrorMessage(
98
86
  "ClaimsIdentity is required.",
99
87
  -63012,
100
- "hosting-configuration",
101
88
  )
102
89
 
103
90
  ChannelServiceRouteNotFound = ErrorMessage(
104
91
  "Channel service route not found for: {0}",
105
92
  -63013,
106
- "hosting-configuration",
107
93
  )
108
94
 
109
95
  TokenExchangeRequired = ErrorMessage(
110
96
  "Token exchange requires a token exchange resource.",
111
97
  -63014,
112
- "hosting-configuration",
113
98
  )
114
99
 
115
100
  MissingHttpClient = ErrorMessage(
116
101
  "HTTP client is required.",
117
102
  -63015,
118
- "hosting-configuration",
119
103
  )
120
104
 
121
105
  InvalidBotFrameworkActivity = ErrorMessage(
122
106
  "Invalid Bot Framework Activity format.",
123
107
  -63016,
124
- "hosting-configuration",
125
108
  )
126
109
 
127
110
  CredentialsRequired = ErrorMessage(
128
111
  "Credentials are required for authentication.",
129
112
  -63017,
130
- "hosting-configuration",
131
113
  )
132
114
 
133
115
  # General/Validation Errors (-66000 to -66999)
134
116
  InvalidConfiguration = ErrorMessage(
135
117
  "Invalid configuration: {0}",
136
118
  -66000,
137
- "configuration",
138
119
  )
139
120
 
140
121
  RequiredParameterMissing = ErrorMessage(
141
122
  "Required parameter missing: {0}",
142
123
  -66001,
143
- "configuration",
144
124
  )
145
125
 
146
126
  InvalidParameterValue = ErrorMessage(
147
127
  "Invalid parameter value for {0}: {1}",
148
128
  -66002,
149
- "configuration",
150
129
  )
151
130
 
152
131
  OperationNotSupported = ErrorMessage(
153
132
  "Operation not supported: {0}",
154
133
  -66003,
155
- "configuration",
156
134
  )
157
135
 
158
136
  ResourceNotFound = ErrorMessage(
159
137
  "Resource not found: {0}",
160
138
  -66004,
161
- "configuration",
162
139
  )
163
140
 
164
141
  UnexpectedError = ErrorMessage(
165
142
  "An unexpected error occurred: {0}",
166
143
  -66005,
167
- "configuration",
168
144
  )
169
145
 
170
146
  InvalidStateObject = ErrorMessage(
171
147
  "Invalid state object: {0}",
172
148
  -66006,
173
- "configuration",
174
149
  )
175
150
 
176
151
  SerializationError = ErrorMessage(
177
152
  "Serialization error: {0}",
178
153
  -66007,
179
- "configuration",
180
154
  )
181
155
 
182
156
  DeserializationError = ErrorMessage(
183
157
  "Deserialization error: {0}",
184
158
  -66008,
185
- "configuration",
186
159
  )
187
160
 
188
161
  TimeoutError = ErrorMessage(
189
162
  "Operation timed out: {0}",
190
163
  -66009,
191
- "configuration",
192
164
  )
193
165
 
194
166
  NetworkError = ErrorMessage(
195
167
  "Network error occurred: {0}",
196
168
  -66010,
197
- "configuration",
198
169
  )
199
170
 
200
171
  def __init__(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-hosting-core
3
- Version: 0.6.0.dev10
3
+ Version: 0.6.0.dev15
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.dev10
18
+ Requires-Dist: microsoft-agents-activity==0.6.0.dev15
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=CPpzP-wkU6z8yz-d_hC0YyRriBQAyVqXczXPkDf95oo,2350
81
- microsoft_agents/hosting/core/errors/error_resources.py,sha256=ar1YoU65eH1OJnE_n6J2YG23UjO-a0cuY4XSUzzK_kU,4761
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.dev10.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
98
- microsoft_agents_hosting_core-0.6.0.dev10.dist-info/METADATA,sha256=bE1qzB2ZWcgIf-dJojy8Y3e4nImcPJQH1mBW9xvwUl4,9244
99
- microsoft_agents_hosting_core-0.6.0.dev10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
100
- microsoft_agents_hosting_core-0.6.0.dev10.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
101
- microsoft_agents_hosting_core-0.6.0.dev10.dist-info/RECORD,,
96
+ microsoft_agents_hosting_core-0.6.0.dev15.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
97
+ microsoft_agents_hosting_core-0.6.0.dev15.dist-info/METADATA,sha256=MJNB3S9PYljd-tdAYTtLL7vp5ZXatkCIO_90fneXpIo,9244
98
+ microsoft_agents_hosting_core-0.6.0.dev15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
99
+ microsoft_agents_hosting_core-0.6.0.dev15.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
100
+ microsoft_agents_hosting_core-0.6.0.dev15.dist-info/RECORD,,
@@ -1,68 +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/#anchor
17
- """
18
-
19
- def __init__(
20
- self,
21
- message_template: str,
22
- error_code: int,
23
- help_url_anchor: str = "agentic-identity-with-the-m365-agents-sdk",
24
- ):
25
- """
26
- Initialize an ErrorMessage.
27
-
28
- :param message_template: The error message template (may include format placeholders)
29
- :type message_template: str
30
- :param error_code: The error code (should be negative)
31
- :type error_code: int
32
- :param help_url_anchor: The anchor for the help URL (defaults to agentic identity)
33
- :type help_url_anchor: str
34
- """
35
- self.message_template = message_template
36
- self.error_code = error_code
37
- self.help_url_anchor = help_url_anchor
38
- self.base_url = "https://aka.ms/M365AgentsErrorCodes"
39
-
40
- def format(self, *args, **kwargs) -> str:
41
- """
42
- Format the error message with the provided arguments.
43
-
44
- :param args: Positional arguments for string formatting
45
- :param kwargs: Keyword arguments for string formatting
46
- :return: Formatted error message with error code and help URL
47
- :rtype: str
48
- """
49
- # Format the main message
50
- if args or kwargs:
51
- message = self.message_template.format(*args, **kwargs)
52
- else:
53
- message = self.message_template
54
-
55
- # Append error code and help URL
56
- return (
57
- f"{message}\n\n"
58
- f"Error Code: {self.error_code}\n"
59
- f"Help URL: {self.base_url}/#{self.help_url_anchor}"
60
- )
61
-
62
- def __str__(self) -> str:
63
- """Return the formatted error message without any arguments."""
64
- return self.format()
65
-
66
- def __repr__(self) -> str:
67
- """Return a representation of the ErrorMessage."""
68
- return f"ErrorMessage(code={self.error_code}, message='{self.message_template[:50]}...')"