microsoft-agents-hosting-core 0.5.0.dev11__py3-none-any.whl → 0.5.0.dev19__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.
@@ -93,7 +93,6 @@ class AgentApplication(Agent, Generic[StateT]):
93
93
  :param kwargs: Additional configuration parameters.
94
94
  :type kwargs: Any
95
95
  """
96
- self.typing = TypingIndicator()
97
96
  self._route_list = _RouteList[StateT]()
98
97
 
99
98
  configuration = kwargs
@@ -659,9 +658,12 @@ class AgentApplication(Agent, Generic[StateT]):
659
658
  await self._start_long_running_call(context, self._on_turn)
660
659
 
661
660
  async def _on_turn(self, context: TurnContext):
661
+ typing = None
662
662
  try:
663
663
  if context.activity.type != ActivityTypes.typing:
664
- await self._start_typing(context)
664
+ if self._options.start_typing_timer:
665
+ typing = TypingIndicator()
666
+ await typing.start(context)
665
667
 
666
668
  self._remove_mentions(context)
667
669
 
@@ -709,11 +711,8 @@ class AgentApplication(Agent, Generic[StateT]):
709
711
  )
710
712
  await self._on_error(context, err)
711
713
  finally:
712
- self.typing.stop()
713
-
714
- async def _start_typing(self, context: TurnContext):
715
- if self._options.start_typing_timer:
716
- await self.typing.start(context)
714
+ if typing:
715
+ await typing.stop()
717
716
 
718
717
  def _remove_mentions(self, context: TurnContext):
719
718
  if (
@@ -118,20 +118,20 @@ class AgenticUserAuthorization(_AuthorizationHandler):
118
118
  connection = self._connection_manager.get_token_provider(
119
119
  context.identity, "agentic"
120
120
  )
121
- upn = context.activity.get_agentic_user()
121
+ agentic_user_id = context.activity.get_agentic_user()
122
122
  agentic_instance_id = context.activity.get_agentic_instance_id()
123
- if not upn or not agentic_instance_id:
123
+ if not agentic_user_id or not agentic_instance_id:
124
124
  logger.error(
125
- "Unable to retrieve agentic user token: missing UPN or agentic instance ID. UPN: %s, Agentic Instance ID: %s",
126
- upn,
125
+ "Unable to retrieve agentic user token: missing agentic user Id or agentic instance Id. agentic_user_id: %s, Agentic Instance ID: %s",
126
+ agentic_user_id,
127
127
  agentic_instance_id,
128
128
  )
129
129
  raise ValueError(
130
- f"Unable to retrieve agentic user token: missing UPN or agentic instance ID. UPN: {upn}, Agentic Instance ID: {agentic_instance_id}"
130
+ f"Unable to retrieve agentic user token: missing agentic User Id or agentic instance Id. agentic_user_id: {agentic_user_id}, Agentic Instance ID: {agentic_instance_id}"
131
131
  )
132
132
 
133
133
  token = await connection.get_agentic_user_token(
134
- agentic_instance_id, upn, scopes
134
+ agentic_instance_id, agentic_user_id, scopes
135
135
  )
136
136
  return TokenResponse(token=token) if token else TokenResponse()
137
137
 
@@ -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
- _interval: int
24
- _timer: Optional[Timer] = None
25
-
26
- def __init__(self, interval=1000) -> None:
27
- self._interval = interval
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
- if self._timer is not None:
31
- return
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
- logger.debug(f"Starting typing indicator with interval: {self._interval} ms")
34
- func = self._on_timer(context)
35
- self._timer = Timer(self._interval, func)
36
- self._timer.start()
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._timer.cancel()
43
- self._timer = None
46
+ self._running = False
47
+ task = self._task
48
+ self._task = None
44
49
 
45
- def _on_timer(self, context: TurnContext):
46
- async def __call__():
50
+ # Cancel outside the lock to avoid blocking
51
+ if task and not task.done():
52
+ task.cancel()
47
53
  try:
48
- logger.debug("Sending typing activity")
49
- await context.send_activity(Activity(type=ActivityTypes.typing))
50
- except Exception as e:
51
- # TODO: Improve when adding logging
52
- logger.error(f"Error sending typing activity: {e}")
53
- self.stop()
54
-
55
- return __call__
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
@@ -43,6 +43,6 @@ class AccessTokenProviderBase(Protocol):
43
43
  raise NotImplementedError()
44
44
 
45
45
  async def get_agentic_user_token(
46
- self, agent_app_instance_id: str, upn: str, scopes: list[str]
46
+ self, agent_app_instance_id: str, agentic_user_id: str, scopes: list[str]
47
47
  ) -> Optional[str]:
48
48
  raise NotImplementedError()
@@ -33,6 +33,6 @@ class AnonymousTokenProvider(AccessTokenProviderBase):
33
33
  return "", ""
34
34
 
35
35
  async def get_agentic_user_token(
36
- self, agent_app_instance_id: str, upn: str, scopes: list[str]
36
+ self, agent_app_instance_id: str, agentic_user_id: str, scopes: list[str]
37
37
  ) -> Optional[str]:
38
38
  return ""
@@ -1,6 +1,7 @@
1
1
  # Copyright (c) Microsoft Corporation. All rights reserved.
2
2
  # Licensed under the MIT License.
3
3
 
4
+ import asyncio
4
5
  import logging
5
6
  import jwt
6
7
 
@@ -16,10 +17,10 @@ class JwtTokenValidator:
16
17
  def __init__(self, configuration: AgentAuthConfiguration):
17
18
  self.configuration = configuration
18
19
 
19
- def validate_token(self, token: str) -> ClaimsIdentity:
20
+ async def validate_token(self, token: str) -> ClaimsIdentity:
20
21
 
21
22
  logger.debug("Validating JWT token.")
22
- key = self._get_public_key_or_secret(token)
23
+ key = await self._get_public_key_or_secret(token)
23
24
  decoded_token = jwt.decode(
24
25
  token,
25
26
  key=key,
@@ -39,7 +40,7 @@ class JwtTokenValidator:
39
40
  logger.debug("Returning anonymous claims identity.")
40
41
  return ClaimsIdentity({}, False, authentication_type="Anonymous")
41
42
 
42
- def _get_public_key_or_secret(self, token: str) -> PyJWK:
43
+ async def _get_public_key_or_secret(self, token: str) -> PyJWK:
43
44
  header = get_unverified_header(token)
44
45
  unverified_payload: dict = decode(token, options={"verify_signature": False})
45
46
 
@@ -50,5 +51,6 @@ class JwtTokenValidator:
50
51
  )
51
52
  jwks_client = PyJWKClient(jwksUri)
52
53
 
53
- key = jwks_client.get_signing_key(header["kid"])
54
+ key = await asyncio.to_thread(jwks_client.get_signing_key, header["kid"])
55
+
54
56
  return key
@@ -1,16 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microsoft-agents-hosting-core
3
- Version: 0.5.0.dev11
3
+ Version: 0.5.0.dev19
4
4
  Summary: Core library for Microsoft Agents
5
5
  Author: Microsoft Corporation
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/microsoft/Agents
8
8
  Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Python :: 3.14
9
14
  Classifier: Operating System :: OS Independent
10
15
  Requires-Python: >=3.10
11
16
  Description-Content-Type: text/markdown
12
17
  License-File: LICENSE
13
- Requires-Dist: microsoft-agents-activity==0.5.0.dev11
18
+ Requires-Dist: microsoft-agents-activity==0.5.0.dev19
14
19
  Requires-Dist: pyjwt>=2.10.1
15
20
  Requires-Dist: isodate>=0.6.1
16
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=M1ex1XCb3RNijJOSaJMTLajR9GrXqx8nim8Bp1yKLDU,31600
19
+ microsoft_agents/hosting/core/app/agent_application.py,sha256=yYAVFkn4VWO5ZzrXdGFR4UheYMD5xP28HCxWPeJz8wA,31560
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=CxLtgDTr6a8ELqUujHMvAh_CYpm3mwhomH-tfTQGSe8,1558
24
+ microsoft_agents/hosting/core/app/typing_indicator.py,sha256=LwwuSJC2KXclO6GkSg0P80MUsf6ClQFzOyx3SSI9Yd0,2460
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
@@ -34,21 +34,21 @@ microsoft_agents/hosting/core/app/oauth/authorization.py,sha256=_sdCZcZ7iciwTZqX
34
34
  microsoft_agents/hosting/core/app/oauth/_handlers/__init__.py,sha256=ZQuXF-IZrJv_hOgt-sdRFAUyIpRXaYqYBuyEJWJRcfU,376
35
35
  microsoft_agents/hosting/core/app/oauth/_handlers/_authorization_handler.py,sha256=W36Y1m0zFaRmdt-cL3ZKoHxx95y0O7YJF9D0cXx_s24,4185
36
36
  microsoft_agents/hosting/core/app/oauth/_handlers/_user_authorization.py,sha256=o_pn5ZO7O-YvcC5NGlUgcCmVLD-f6KwQ5CRIsPp8zQE,10186
37
- microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py,sha256=7rGzYRLOzcy9vGAwnzjyImEaCy0G_bRUwufuXp3xiwk,7145
37
+ microsoft_agents/hosting/core/app/oauth/_handlers/agentic_user_authorization.py,sha256=4EgZxSMoymgap54xhoEQH0UIEBap-mMCiP6eFeanr3A,7253
38
38
  microsoft_agents/hosting/core/app/state/__init__.py,sha256=aL_8GB7_de8LUSEOgTJQFRx1kvgvJHHJVv7nWAoRPmU,331
39
39
  microsoft_agents/hosting/core/app/state/conversation_state.py,sha256=LfcSwvhaU0JeAahwg9YA9uz0kKHa9c6Y3XBAWqwuMg0,1593
40
40
  microsoft_agents/hosting/core/app/state/state.py,sha256=Q1GMGTdIGpu5Z4_6HPCfhJaD265oBlv6DMNNBCUyG3U,7372
41
41
  microsoft_agents/hosting/core/app/state/temp_state.py,sha256=Oh7K5-uYf50Z-lBXqttSMl2N1lRakktOmjLlIAKcEsM,3501
42
42
  microsoft_agents/hosting/core/app/state/turn_state.py,sha256=rEIRkwBsn3MPbrfKNjX8XqqbF-4THepMXU75KvDsBvM,9868
43
43
  microsoft_agents/hosting/core/authorization/__init__.py,sha256=pOTmTJFS5CMPEcHRadBTgrbWUP5lOIxsPMgTreFq7mw,634
44
- microsoft_agents/hosting/core/authorization/access_token_provider_base.py,sha256=AQROUB0U3C1vo4skM-bMOOLerqI0PrM2adKBBN7zJJo,1634
44
+ microsoft_agents/hosting/core/authorization/access_token_provider_base.py,sha256=Z0nGkfOUSIBvJSFjGGNQEd1-upqZVjT6eSXsqsFa2Cc,1646
45
45
  microsoft_agents/hosting/core/authorization/agent_auth_configuration.py,sha256=meLUO0Mwb9SBr01dLvYS9q3xuZyndCsb_gIx0r7__Sk,2944
46
- microsoft_agents/hosting/core/authorization/anonymous_token_provider.py,sha256=AzmwU7uqG6zX3Qw5_4Lenv18gHfLM55D6e_n2wGupy4,1064
46
+ microsoft_agents/hosting/core/authorization/anonymous_token_provider.py,sha256=44XKaSLJFZj4hCSAdWAtW1R31M5QCZVaFKJaxcwx5h4,1076
47
47
  microsoft_agents/hosting/core/authorization/auth_types.py,sha256=Fg_ywEItm3xL_DBUNzi0QsfDPVY5S3HlAiNw6I2SW64,374
48
48
  microsoft_agents/hosting/core/authorization/authentication_constants.py,sha256=ABEwosDCMYhubDiGrD8QULboTkACqDvNp_x_XBPt6dQ,4618
49
49
  microsoft_agents/hosting/core/authorization/claims_identity.py,sha256=ttnJpQx-2uAlwby_xRRmyHmyUPjzQjW86GO9FVzZK3Y,2501
50
50
  microsoft_agents/hosting/core/authorization/connections.py,sha256=f_NQpuJzhCBNZLk56SK4kvb_V_g2x2XMnFwWbYyDX_s,1247
51
- microsoft_agents/hosting/core/authorization/jwt_token_validator.py,sha256=LzVC4xfWieBDXqPH4kjM5ec2idEmkzo9-v3tTxywgdY,1966
51
+ microsoft_agents/hosting/core/authorization/jwt_token_validator.py,sha256=b440T7y1tM7gPUQZ27EA3SgNiaEupxz56E6773gL5Zo,2025
52
52
  microsoft_agents/hosting/core/client/__init__.py,sha256=HMWtSUXu1akaX6qtDx412Lr8vLi5SEslc-DYrvZAPWs,1299
53
53
  microsoft_agents/hosting/core/client/agent_conversation_reference.py,sha256=3Zf3IGbJVWv4pF6kA6vtWkpV3Ap3z6jVkimeEtFMvJI,288
54
54
  microsoft_agents/hosting/core/client/channel_factory_protocol.py,sha256=r270WJwySugnzY4AITT8oSRQHKqeqYAknkmD2eq_CqA,394
@@ -91,8 +91,8 @@ microsoft_agents/hosting/core/storage/transcript_info.py,sha256=5VN32j99tshChAff
91
91
  microsoft_agents/hosting/core/storage/transcript_logger.py,sha256=_atDk3CJ05fIVMhlWGNa91IiM9bGLmOhasFko8Lxjhk,8237
92
92
  microsoft_agents/hosting/core/storage/transcript_memory_store.py,sha256=v1Ud9LSs8m5c9_Fa8i49SuAjw80dX1hDciqbRduDEOE,6444
93
93
  microsoft_agents/hosting/core/storage/transcript_store.py,sha256=ka74o0WvI5GhMZcFqSxVdamBhGzZcDZe6VNkG-sMy74,1944
94
- microsoft_agents_hosting_core-0.5.0.dev11.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
95
- microsoft_agents_hosting_core-0.5.0.dev11.dist-info/METADATA,sha256=Rtru58Gme9kAIxyZrWPIGmCLWij8GWc7JQTPjiCyAOA,8597
96
- microsoft_agents_hosting_core-0.5.0.dev11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
- microsoft_agents_hosting_core-0.5.0.dev11.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
98
- microsoft_agents_hosting_core-0.5.0.dev11.dist-info/RECORD,,
94
+ microsoft_agents_hosting_core-0.5.0.dev19.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
95
+ microsoft_agents_hosting_core-0.5.0.dev19.dist-info/METADATA,sha256=_mlWjzKeQ8jxqQCVbwed1r6EB8xeB_yHIlcZjGY6kKo,8852
96
+ microsoft_agents_hosting_core-0.5.0.dev19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
+ microsoft_agents_hosting_core-0.5.0.dev19.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
98
+ microsoft_agents_hosting_core-0.5.0.dev19.dist-info/RECORD,,