microsoft-agents-hosting-core 0.4.0.dev16__py3-none-any.whl → 0.5.0__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.
- microsoft_agents/hosting/core/__init__.py +2 -1
- microsoft_agents/hosting/core/_oauth/__init__.py +3 -0
- microsoft_agents/hosting/core/_oauth/_flow_state.py +2 -2
- microsoft_agents/hosting/core/_oauth/_oauth_flow.py +26 -23
- microsoft_agents/hosting/core/activity_handler.py +20 -17
- microsoft_agents/hosting/core/app/__init__.py +2 -1
- microsoft_agents/hosting/core/app/_routes/__init__.py +13 -0
- microsoft_agents/hosting/core/app/_routes/_route.py +89 -0
- microsoft_agents/hosting/core/app/_routes/_route_list.py +32 -0
- microsoft_agents/hosting/core/app/_routes/route_rank.py +14 -0
- microsoft_agents/hosting/core/app/_type_defs.py +15 -0
- microsoft_agents/hosting/core/app/agent_application.py +116 -52
- microsoft_agents/hosting/core/app/input_file.py +15 -11
- microsoft_agents/hosting/core/app/oauth/__init__.py +4 -0
- microsoft_agents/hosting/core/app/oauth/_handlers/__init__.py +5 -0
- microsoft_agents/hosting/core/app/oauth/_handlers/_authorization_handler.py +9 -4
- microsoft_agents/hosting/core/app/oauth/_handlers/_user_authorization.py +6 -4
- microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py +14 -9
- microsoft_agents/hosting/core/app/oauth/_sign_in_response.py +4 -0
- microsoft_agents/hosting/core/app/oauth/_sign_in_state.py +5 -0
- microsoft_agents/hosting/core/app/oauth/auth_handler.py +4 -2
- microsoft_agents/hosting/core/app/oauth/authorization.py +43 -20
- microsoft_agents/hosting/core/app/state/state.py +50 -6
- microsoft_agents/hosting/core/app/typing_indicator.py +51 -27
- microsoft_agents/hosting/core/authorization/access_token_provider_base.py +4 -1
- microsoft_agents/hosting/core/authorization/agent_auth_configuration.py +3 -0
- microsoft_agents/hosting/core/authorization/anonymous_token_provider.py +4 -1
- microsoft_agents/hosting/core/authorization/auth_types.py +3 -0
- microsoft_agents/hosting/core/authorization/connections.py +3 -0
- microsoft_agents/hosting/core/authorization/jwt_token_validator.py +9 -4
- microsoft_agents/hosting/core/channel_adapter.py +9 -9
- microsoft_agents/hosting/core/channel_api_handler_protocol.py +3 -0
- microsoft_agents/hosting/core/channel_service_adapter.py +65 -10
- microsoft_agents/hosting/core/channel_service_client_factory_base.py +3 -0
- microsoft_agents/hosting/core/client/agent_conversation_reference.py +3 -0
- microsoft_agents/hosting/core/client/channel_factory_protocol.py +3 -0
- microsoft_agents/hosting/core/client/channel_host_protocol.py +3 -0
- microsoft_agents/hosting/core/client/channel_info_protocol.py +3 -0
- microsoft_agents/hosting/core/client/channel_protocol.py +3 -0
- microsoft_agents/hosting/core/client/channels_configuration.py +3 -0
- microsoft_agents/hosting/core/client/configuration_channel_host.py +3 -0
- microsoft_agents/hosting/core/client/conversation_constants.py +3 -0
- microsoft_agents/hosting/core/client/conversation_id_factory.py +3 -0
- microsoft_agents/hosting/core/client/conversation_id_factory_options.py +3 -0
- microsoft_agents/hosting/core/client/conversation_id_factory_protocol.py +3 -0
- microsoft_agents/hosting/core/client/http_agent_channel.py +3 -0
- microsoft_agents/hosting/core/client/http_agent_channel_factory.py +3 -0
- microsoft_agents/hosting/core/connector/client/connector_client.py +1 -4
- microsoft_agents/hosting/core/connector/client/user_token_client.py +40 -43
- microsoft_agents/hosting/core/connector/user_token_base.py +77 -1
- microsoft_agents/hosting/core/connector/user_token_client_base.py +3 -0
- microsoft_agents/hosting/core/rest_channel_service_client_factory.py +3 -0
- microsoft_agents/hosting/core/state/agent_state.py +16 -20
- microsoft_agents/hosting/core/storage/error_handling.py +3 -0
- microsoft_agents/hosting/core/storage/memory_storage.py +3 -0
- microsoft_agents/hosting/core/storage/storage.py +3 -0
- microsoft_agents/hosting/core/storage/store_item.py +3 -0
- microsoft_agents/hosting/core/storage/transcript_file_store.py +1 -5
- microsoft_agents/hosting/core/turn_context.py +2 -1
- microsoft_agents_hosting_core-0.5.0.dist-info/METADATA +191 -0
- {microsoft_agents_hosting_core-0.4.0.dev16.dist-info → microsoft_agents_hosting_core-0.5.0.dist-info}/RECORD +64 -59
- microsoft_agents_hosting_core-0.5.0.dist-info/licenses/LICENSE +21 -0
- microsoft_agents/hosting/core/app/route.py +0 -32
- microsoft_agents_hosting_core-0.4.0.dev16.dist-info/METADATA +0 -16
- {microsoft_agents_hosting_core-0.4.0.dev16.dist-info → microsoft_agents_hosting_core-0.5.0.dist-info}/WHEEL +0 -0
- {microsoft_agents_hosting_core-0.4.0.dev16.dist-info → microsoft_agents_hosting_core-0.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
Licensed under the MIT License.
|
|
4
|
+
"""
|
|
5
|
+
|
|
1
6
|
from datetime import datetime
|
|
2
7
|
import logging
|
|
3
8
|
from typing import TypeVar, Optional, Callable, Awaitable, Generic, cast
|
|
@@ -50,11 +55,11 @@ class Authorization:
|
|
|
50
55
|
only if auth_handlers is empty or None.
|
|
51
56
|
|
|
52
57
|
:param storage: The storage system to use for state management.
|
|
53
|
-
:type storage: Storage
|
|
58
|
+
:type storage: :class:`microsoft_agents.hosting.core.storage.Storage`
|
|
54
59
|
:param connection_manager: The connection manager for OAuth providers.
|
|
55
|
-
:type connection_manager: Connections
|
|
60
|
+
:type connection_manager: :class:`microsoft_agents.hosting.core.authorization.Connections`
|
|
56
61
|
:param auth_handlers: Configuration for OAuth providers.
|
|
57
|
-
:type auth_handlers: dict[str, AuthHandler],
|
|
62
|
+
:type auth_handlers: dict[str, :class:`microsoft_agents.hosting.core.app.oauth.auth_handler.AuthHandler`], Optional
|
|
58
63
|
:raises ValueError: When storage is None or no auth handlers provided.
|
|
59
64
|
"""
|
|
60
65
|
if not storage:
|
|
@@ -100,7 +105,7 @@ class Authorization:
|
|
|
100
105
|
it initializes an instance of each variant that is referenced.
|
|
101
106
|
|
|
102
107
|
:param auth_handlers: A dictionary of auth handler configurations.
|
|
103
|
-
:type auth_handlers: dict[str, AuthHandler]
|
|
108
|
+
:type auth_handlers: dict[str, :class:`microsoft_agents.hosting.core.app.oauth.auth_handler.AuthHandler`]
|
|
104
109
|
"""
|
|
105
110
|
for name, auth_handler in self._handler_settings.items():
|
|
106
111
|
auth_type = auth_handler.auth_type
|
|
@@ -121,26 +126,42 @@ class Authorization:
|
|
|
121
126
|
can be used to inspect or manipulate the state directly if needed.
|
|
122
127
|
|
|
123
128
|
:param context: The turn context for the current turn of conversation.
|
|
124
|
-
:type context: TurnContext
|
|
129
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
125
130
|
:return: A unique (across other values of channel_id and user_id) key for the sign-in state.
|
|
126
131
|
:rtype: str
|
|
127
132
|
"""
|
|
128
133
|
return f"auth:_SignInState:{context.activity.channel_id}:{context.activity.from_property.id}"
|
|
129
134
|
|
|
130
135
|
async def _load_sign_in_state(self, context: TurnContext) -> Optional[_SignInState]:
|
|
131
|
-
"""Load the sign-in state from storage for the given context.
|
|
136
|
+
"""Load the sign-in state from storage for the given context.
|
|
137
|
+
|
|
138
|
+
:param context: The turn context for the current turn of conversation.
|
|
139
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
140
|
+
:return: The sign-in state if found, None otherwise.
|
|
141
|
+
:rtype: Optional[:class:`microsoft_agents.hosting.core.app.oauth._sign_in_state._SignInState`]
|
|
142
|
+
"""
|
|
132
143
|
key = self._sign_in_state_key(context)
|
|
133
144
|
return (await self._storage.read([key], target_cls=_SignInState)).get(key)
|
|
134
145
|
|
|
135
146
|
async def _save_sign_in_state(
|
|
136
147
|
self, context: TurnContext, state: _SignInState
|
|
137
148
|
) -> None:
|
|
138
|
-
"""Save the sign-in state to storage for the given context.
|
|
149
|
+
"""Save the sign-in state to storage for the given context.
|
|
150
|
+
|
|
151
|
+
:param context: The turn context for the current turn of conversation.
|
|
152
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
153
|
+
:param state: The sign-in state to save.
|
|
154
|
+
:type state: :class:`microsoft_agents.hosting.core.app.oauth._sign_in_state._SignInState`
|
|
155
|
+
"""
|
|
139
156
|
key = self._sign_in_state_key(context)
|
|
140
157
|
await self._storage.write({key: state})
|
|
141
158
|
|
|
142
159
|
async def _delete_sign_in_state(self, context: TurnContext) -> None:
|
|
143
|
-
"""Delete the sign-in state from storage for the given context.
|
|
160
|
+
"""Delete the sign-in state from storage for the given context.
|
|
161
|
+
|
|
162
|
+
:param context: The turn context for the current turn of conversation.
|
|
163
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
164
|
+
"""
|
|
144
165
|
key = self._sign_in_state_key(context)
|
|
145
166
|
await self._storage.delete([key])
|
|
146
167
|
|
|
@@ -174,7 +195,7 @@ class Authorization:
|
|
|
174
195
|
:param handler_id: The ID of the auth handler to resolve.
|
|
175
196
|
:type handler_id: str
|
|
176
197
|
:return: The corresponding AuthorizationHandler instance.
|
|
177
|
-
:rtype:
|
|
198
|
+
:rtype: :class:`microsoft_agents.hosting.core.app.oauth._handlers._AuthorizationHandler`
|
|
178
199
|
:raises ValueError: If the handler ID is not recognized or not configured.
|
|
179
200
|
"""
|
|
180
201
|
if handler_id not in self._handlers:
|
|
@@ -195,13 +216,13 @@ class Authorization:
|
|
|
195
216
|
Storage is updated as needed with _SignInState data for caching purposes.
|
|
196
217
|
|
|
197
218
|
:param context: The turn context for the current turn of conversation.
|
|
198
|
-
:type context: TurnContext
|
|
219
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
199
220
|
:param state: The turn state for the current turn of conversation.
|
|
200
|
-
:type state: TurnState
|
|
221
|
+
:type state: :class:`microsoft_agents.hosting.core.app.state.turn_state.TurnState`
|
|
201
222
|
:param auth_handler_id: The ID of the auth handler to use for sign-in. If None, the first handler will be used.
|
|
202
223
|
:type auth_handler_id: str
|
|
203
224
|
:return: A _SignInResponse indicating the result of the sign-in attempt.
|
|
204
|
-
:rtype: _SignInResponse
|
|
225
|
+
:rtype: :class:`microsoft_agents.hosting.core.app.oauth._sign_in_response._SignInResponse`
|
|
205
226
|
"""
|
|
206
227
|
|
|
207
228
|
auth_handler_id = auth_handler_id or self._default_handler_id
|
|
@@ -245,7 +266,7 @@ class Authorization:
|
|
|
245
266
|
"""Attempts to sign out the user from a specified auth handler or the default handler.
|
|
246
267
|
|
|
247
268
|
:param context: The turn context for the current turn of conversation.
|
|
248
|
-
:type context: TurnContext
|
|
269
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
249
270
|
:param auth_handler_id: The ID of the auth handler to sign out from. If None, sign out from all handlers.
|
|
250
271
|
:type auth_handler_id: Optional[str]
|
|
251
272
|
:return: None
|
|
@@ -267,11 +288,11 @@ class Authorization:
|
|
|
267
288
|
from the cached _SignInState.
|
|
268
289
|
|
|
269
290
|
:param context: The context object for the current turn.
|
|
270
|
-
:type context: TurnContext
|
|
291
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
271
292
|
:param state: The turn state for the current turn.
|
|
272
|
-
:type state: TurnState
|
|
293
|
+
:type state: :class:`microsoft_agents.hosting.core.app.state.turn_state.TurnState`
|
|
273
294
|
:return: A tuple indicating whether the turn should be skipped and the continuation activity if applicable.
|
|
274
|
-
:rtype: tuple[bool, Optional[Activity]]
|
|
295
|
+
:rtype: tuple[bool, Optional[:class:`microsoft_agents.activity.Activity`]]
|
|
275
296
|
"""
|
|
276
297
|
sign_in_state = await self._load_sign_in_state(context)
|
|
277
298
|
|
|
@@ -301,11 +322,11 @@ class Authorization:
|
|
|
301
322
|
The token is taken from cache, so this does not initiate nor continue a sign-in flow.
|
|
302
323
|
|
|
303
324
|
:param context: The context object for the current turn.
|
|
304
|
-
:type context: TurnContext
|
|
325
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
305
326
|
:param auth_handler_id: The ID of the auth handler to get the token for.
|
|
306
327
|
:type auth_handler_id: str
|
|
307
328
|
:return: The token response from the OAuth provider.
|
|
308
|
-
:rtype: TokenResponse
|
|
329
|
+
:rtype: :class:`microsoft_agents.activity.TokenResponse`
|
|
309
330
|
"""
|
|
310
331
|
return await self.exchange_token(context, auth_handler_id=auth_handler_id)
|
|
311
332
|
|
|
@@ -319,7 +340,7 @@ class Authorization:
|
|
|
319
340
|
"""Exchanges or refreshes the token for a specific auth handler or the default handler.
|
|
320
341
|
|
|
321
342
|
:param context: The context object for the current turn.
|
|
322
|
-
:type context: TurnContext
|
|
343
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
323
344
|
:param scopes: The scopes to request during the token exchange or refresh. Defaults
|
|
324
345
|
to the list given in the AuthHandler configuration if None.
|
|
325
346
|
:type scopes: Optional[list[str]]
|
|
@@ -330,7 +351,7 @@ class Authorization:
|
|
|
330
351
|
the connection defined in the AuthHandler configuration will be used.
|
|
331
352
|
:type exchange_connection: Optional[str]
|
|
332
353
|
:return: The token response from the OAuth provider.
|
|
333
|
-
:rtype: TokenResponse
|
|
354
|
+
:rtype: :class:`microsoft_agents.activity.TokenResponse`
|
|
334
355
|
:raises ValueError: If the specified auth handler ID is not recognized or not configured.
|
|
335
356
|
"""
|
|
336
357
|
|
|
@@ -371,6 +392,7 @@ class Authorization:
|
|
|
371
392
|
Sets a handler to be called when sign-in is successfully completed.
|
|
372
393
|
|
|
373
394
|
:param handler: The handler function to call on successful sign-in.
|
|
395
|
+
:type handler: Callable[[:class:`microsoft_agents.hosting.core.turn_context.TurnContext`, :class:`microsoft_agents.hosting.core.app.state.turn_state.TurnState`, Optional[str]], Awaitable[None]]
|
|
374
396
|
"""
|
|
375
397
|
self._sign_in_success_handler = handler
|
|
376
398
|
|
|
@@ -382,5 +404,6 @@ class Authorization:
|
|
|
382
404
|
Sets a handler to be called when sign-in fails.
|
|
383
405
|
|
|
384
406
|
:param handler: The handler function to call on sign-in failure.
|
|
407
|
+
:type handler: Callable[[:class:`microsoft_agents.hosting.core.turn_context.TurnContext`, :class:`microsoft_agents.hosting.core.app.state.turn_state.TurnState`, Optional[str]], Awaitable[None]]
|
|
385
408
|
"""
|
|
386
409
|
self._sign_in_failure_handler = handler
|
|
@@ -97,9 +97,10 @@ class State(dict[str, StoreItem], ABC):
|
|
|
97
97
|
"""
|
|
98
98
|
Saves The State to Storage
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
:param _context: the turn context.
|
|
101
|
+
:type _context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
102
|
+
:param storage: storage to save to.
|
|
103
|
+
:type storage: Optional[:class:`microsoft_agents.hosting.core.storage.Storage`]
|
|
103
104
|
"""
|
|
104
105
|
|
|
105
106
|
if not storage or self.__key__ == "":
|
|
@@ -126,13 +127,24 @@ class State(dict[str, StoreItem], ABC):
|
|
|
126
127
|
"""
|
|
127
128
|
Loads The State from Storage
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
:param context: the turn context.
|
|
131
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
132
|
+
:param storage: storage to read from.
|
|
133
|
+
:type storage: Optional[:class:`microsoft_agents.hosting.core.storage.Storage`]
|
|
134
|
+
:return: The loaded state instance.
|
|
135
|
+
:rtype: :class:`microsoft_agents.hosting.core.app.state.state.State`
|
|
132
136
|
"""
|
|
133
137
|
return cls()
|
|
134
138
|
|
|
135
139
|
def create_property(self, name: str) -> _StatePropertyAccessor:
|
|
140
|
+
"""
|
|
141
|
+
Create a property accessor for the given name.
|
|
142
|
+
|
|
143
|
+
:param name: The name of the property.
|
|
144
|
+
:type name: str
|
|
145
|
+
:return: A state property accessor for the named property.
|
|
146
|
+
:rtype: :class:`microsoft_agents.hosting.core.state.state_property_accessor.StatePropertyAccessor`
|
|
147
|
+
"""
|
|
136
148
|
return StatePropertyAccessor(self, name)
|
|
137
149
|
|
|
138
150
|
def __setitem__(self, key: str, item: Any) -> None:
|
|
@@ -180,6 +192,14 @@ class StatePropertyAccessor(_StatePropertyAccessor):
|
|
|
180
192
|
_state: State
|
|
181
193
|
|
|
182
194
|
def __init__(self, state: State, name: str) -> None:
|
|
195
|
+
"""
|
|
196
|
+
Initialize the StatePropertyAccessor.
|
|
197
|
+
|
|
198
|
+
:param state: The state object to access properties from.
|
|
199
|
+
:type state: :class:`microsoft_agents.hosting.core.app.state.state.State`
|
|
200
|
+
:param name: The name of the property to access.
|
|
201
|
+
:type name: str
|
|
202
|
+
"""
|
|
183
203
|
self._name = name
|
|
184
204
|
self._state = state
|
|
185
205
|
|
|
@@ -190,6 +210,16 @@ class StatePropertyAccessor(_StatePropertyAccessor):
|
|
|
190
210
|
Union[Any, Callable[[], Optional[Any]]]
|
|
191
211
|
] = None,
|
|
192
212
|
) -> Optional[Any]:
|
|
213
|
+
"""
|
|
214
|
+
Get the property value from the state.
|
|
215
|
+
|
|
216
|
+
:param turn_context: The turn context.
|
|
217
|
+
:type turn_context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
218
|
+
:param default_value_or_factory: Default value or factory function to use if property doesn't exist.
|
|
219
|
+
:type default_value_or_factory: Optional[Union[Any, Callable[[], Optional[Any]]]]
|
|
220
|
+
:return: The property value or default value if not found.
|
|
221
|
+
:rtype: Optional[Any]
|
|
222
|
+
"""
|
|
193
223
|
value = self._state[self._name] if self._name in self._state else None
|
|
194
224
|
|
|
195
225
|
if value is None and default_value_or_factory is not None:
|
|
@@ -201,7 +231,21 @@ class StatePropertyAccessor(_StatePropertyAccessor):
|
|
|
201
231
|
return value
|
|
202
232
|
|
|
203
233
|
async def delete(self, turn_context: TurnContext) -> None:
|
|
234
|
+
"""
|
|
235
|
+
Delete the property from the state.
|
|
236
|
+
|
|
237
|
+
:param turn_context: The turn context.
|
|
238
|
+
:type turn_context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
239
|
+
"""
|
|
204
240
|
del self._state[self._name]
|
|
205
241
|
|
|
206
242
|
async def set(self, turn_context: TurnContext, value: Any) -> None:
|
|
243
|
+
"""
|
|
244
|
+
Set the property value in the state.
|
|
245
|
+
|
|
246
|
+
:param turn_context: The turn context.
|
|
247
|
+
:type turn_context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
248
|
+
:param value: The value to set for the property.
|
|
249
|
+
:type value: Any
|
|
250
|
+
"""
|
|
207
251
|
self._state[self._name] = value
|
|
@@ -4,9 +4,9 @@ Licensed under the MIT License.
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
|
+
import asyncio
|
|
7
8
|
import logging
|
|
8
9
|
|
|
9
|
-
from threading import Timer
|
|
10
10
|
from typing import Optional
|
|
11
11
|
|
|
12
12
|
from microsoft_agents.hosting.core import TurnContext
|
|
@@ -20,36 +20,60 @@ class TypingIndicator:
|
|
|
20
20
|
Encapsulates the logic for sending "typing" activity to the user.
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
self.
|
|
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()
|
|
28
28
|
|
|
29
29
|
async def start(self, context: TurnContext) -> None:
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
async with self._lock:
|
|
31
|
+
if self._running:
|
|
32
|
+
return
|
|
33
|
+
|
|
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))
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
await func()
|
|
40
|
+
async def stop(self) -> None:
|
|
41
|
+
async with self._lock:
|
|
42
|
+
if not self._running:
|
|
43
|
+
return
|
|
38
44
|
|
|
39
|
-
def stop(self) -> None:
|
|
40
|
-
if self._timer:
|
|
41
45
|
logger.debug("Stopping typing indicator")
|
|
42
|
-
self.
|
|
43
|
-
|
|
46
|
+
self._running = False
|
|
47
|
+
task = self._task
|
|
48
|
+
self._task = None
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
# Cancel outside the lock to avoid blocking
|
|
51
|
+
if task and not task.done():
|
|
52
|
+
task.cancel()
|
|
47
53
|
try:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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."""
|
|
60
|
+
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)
|
|
77
|
+
except asyncio.CancelledError:
|
|
78
|
+
logger.debug("Typing indicator loop cancelled")
|
|
79
|
+
raise
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
1
4
|
from typing import Protocol, Optional
|
|
2
5
|
from abc import abstractmethod
|
|
3
6
|
|
|
@@ -40,6 +43,6 @@ class AccessTokenProviderBase(Protocol):
|
|
|
40
43
|
raise NotImplementedError()
|
|
41
44
|
|
|
42
45
|
async def get_agentic_user_token(
|
|
43
|
-
self, agent_app_instance_id: str,
|
|
46
|
+
self, agent_app_instance_id: str, agentic_user_id: str, scopes: list[str]
|
|
44
47
|
) -> Optional[str]:
|
|
45
48
|
raise NotImplementedError()
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
1
4
|
from typing import Optional
|
|
2
5
|
|
|
3
6
|
from .access_token_provider_base import AccessTokenProviderBase
|
|
@@ -30,6 +33,6 @@ class AnonymousTokenProvider(AccessTokenProviderBase):
|
|
|
30
33
|
return "", ""
|
|
31
34
|
|
|
32
35
|
async def get_agentic_user_token(
|
|
33
|
-
self, agent_app_instance_id: str,
|
|
36
|
+
self, agent_app_instance_id: str, agentic_user_id: str, scopes: list[str]
|
|
34
37
|
) -> Optional[str]:
|
|
35
38
|
return ""
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import asyncio
|
|
1
5
|
import logging
|
|
2
6
|
import jwt
|
|
3
7
|
|
|
@@ -13,10 +17,10 @@ class JwtTokenValidator:
|
|
|
13
17
|
def __init__(self, configuration: AgentAuthConfiguration):
|
|
14
18
|
self.configuration = configuration
|
|
15
19
|
|
|
16
|
-
def validate_token(self, token: str) -> ClaimsIdentity:
|
|
20
|
+
async def validate_token(self, token: str) -> ClaimsIdentity:
|
|
17
21
|
|
|
18
22
|
logger.debug("Validating JWT token.")
|
|
19
|
-
key = self._get_public_key_or_secret(token)
|
|
23
|
+
key = await self._get_public_key_or_secret(token)
|
|
20
24
|
decoded_token = jwt.decode(
|
|
21
25
|
token,
|
|
22
26
|
key=key,
|
|
@@ -36,7 +40,7 @@ class JwtTokenValidator:
|
|
|
36
40
|
logger.debug("Returning anonymous claims identity.")
|
|
37
41
|
return ClaimsIdentity({}, False, authentication_type="Anonymous")
|
|
38
42
|
|
|
39
|
-
def _get_public_key_or_secret(self, token: str) -> PyJWK:
|
|
43
|
+
async def _get_public_key_or_secret(self, token: str) -> PyJWK:
|
|
40
44
|
header = get_unverified_header(token)
|
|
41
45
|
unverified_payload: dict = decode(token, options={"verify_signature": False})
|
|
42
46
|
|
|
@@ -47,5 +51,6 @@ class JwtTokenValidator:
|
|
|
47
51
|
)
|
|
48
52
|
jwks_client = PyJWKClient(jwksUri)
|
|
49
53
|
|
|
50
|
-
key = jwks_client.get_signing_key
|
|
54
|
+
key = await asyncio.to_thread(jwks_client.get_signing_key, header["kid"])
|
|
55
|
+
|
|
51
56
|
return key
|
|
@@ -40,7 +40,7 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
40
40
|
Sends a set of activities to the user. An array of responses from the server will be returned.
|
|
41
41
|
|
|
42
42
|
:param context: The context object for the turn.
|
|
43
|
-
:type context: :class:`TurnContext`
|
|
43
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
44
44
|
:param activities: The activities to send.
|
|
45
45
|
:type activities: list[Activity]
|
|
46
46
|
:return:
|
|
@@ -53,7 +53,7 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
53
53
|
Replaces an existing activity.
|
|
54
54
|
|
|
55
55
|
:param context: The context object for the turn.
|
|
56
|
-
:type context: :class:`TurnContext`
|
|
56
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
57
57
|
:param activity: New replacement activity.
|
|
58
58
|
:type activity: :class:`microsoft_agents.activity.Activity`
|
|
59
59
|
:return:
|
|
@@ -68,7 +68,7 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
68
68
|
Deletes an existing activity.
|
|
69
69
|
|
|
70
70
|
:param context: The context object for the turn.
|
|
71
|
-
:type context: :class:`TurnContext`
|
|
71
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
72
72
|
:param reference: Conversation reference for the activity to delete.
|
|
73
73
|
:type reference: :class:`microsoft_agents.activity.ConversationReference`
|
|
74
74
|
:return:
|
|
@@ -102,7 +102,7 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
102
102
|
:param reference: A reference to the conversation to continue.
|
|
103
103
|
:type reference: :class:`microsoft_agents.activity.ConversationReference`
|
|
104
104
|
:param callback: The method to call for the resulting agent turn.
|
|
105
|
-
:type callback: Callable[[TurnContext], Awaitable]
|
|
105
|
+
:type callback: Callable[[microsoft_agents.hosting.core.turn_context.TurnContext], Awaitable]
|
|
106
106
|
:param claims_identity: A :class:`microsoft_agents.hosting.core.ClaimsIdentity` for the conversation.
|
|
107
107
|
:type claims_identity: :class:`microsoft_agents.hosting.core.ClaimsIdentity`
|
|
108
108
|
:param audience:A value signifying the recipient of the proactive message.
|
|
@@ -124,11 +124,11 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
124
124
|
to the user.
|
|
125
125
|
|
|
126
126
|
:param claims_identity: A :class:`microsoft_agents.hosting.core.ClaimsIdentity` for the conversation.
|
|
127
|
-
:type claims_identity: :class:`microsoft_agents.hosting.core.ClaimsIdentity`
|
|
127
|
+
:type claims_identity: :class:`microsoft_agents.hosting.core.authorization.ClaimsIdentity`
|
|
128
128
|
:param continuation_activity: The activity to send.
|
|
129
129
|
:type continuation_activity: :class:`microsoft_agents.activity.Activity`
|
|
130
130
|
:param callback: The method to call for the resulting agent turn.
|
|
131
|
-
:type callback: Callable[[TurnContext], Awaitable]
|
|
131
|
+
:type callback: Callable[[microsoft_agents.hosting.core.turn_context.TurnContext], Awaitable]
|
|
132
132
|
:param audience: A value signifying the recipient of the proactive message.
|
|
133
133
|
:type audience: str
|
|
134
134
|
"""
|
|
@@ -155,9 +155,9 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
155
155
|
:param audience: A value signifying the recipient of the proactive message.
|
|
156
156
|
:type audience: str
|
|
157
157
|
:param conversation_parameters: The information to use to create the conversation
|
|
158
|
-
:type conversation_parameters: :class:`microsoft_agents.activity.
|
|
158
|
+
:type conversation_parameters: :class:`microsoft_agents.activity.ConversationParameters`
|
|
159
159
|
:param callback: The method to call for the resulting agent turn.
|
|
160
|
-
:type callback: Callable[[TurnContext], Awaitable]
|
|
160
|
+
:type callback: Callable[[microsoft_agents.hosting.core.turn_context.TurnContext], Awaitable]
|
|
161
161
|
|
|
162
162
|
:raises: Exception - Not implemented or when the implementation fails.
|
|
163
163
|
|
|
@@ -222,7 +222,7 @@ class ChannelAdapter(ABC, ChannelAdapterProtocol):
|
|
|
222
222
|
the end of the chain.
|
|
223
223
|
|
|
224
224
|
:param context: The context object for the turn.
|
|
225
|
-
:type context: :class:`TurnContext`
|
|
225
|
+
:type context: :class:`microsoft_agents.hosting.core.turn_context.TurnContext`
|
|
226
226
|
:param callback: A callback method to run at the end of the pipeline.
|
|
227
227
|
:type callback: Callable[[TurnContext], Awaitable]
|
|
228
228
|
:return:
|