microsoft-agents-hosting-core 0.7.0__py3-none-any.whl → 0.7.0.dev0__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.
Files changed (25) hide show
  1. microsoft_agents/hosting/core/__init__.py +1 -24
  2. microsoft_agents/hosting/core/app/agent_application.py +24 -12
  3. microsoft_agents/hosting/core/app/oauth/_sign_in_state.py +15 -7
  4. microsoft_agents/hosting/core/authorization/claims_identity.py +0 -14
  5. microsoft_agents/hosting/core/channel_service_adapter.py +14 -28
  6. microsoft_agents/hosting/core/connector/client/connector_client.py +1 -0
  7. microsoft_agents/hosting/core/connector/client/user_token_client.py +1 -0
  8. microsoft_agents/hosting/core/rest_channel_service_client_factory.py +2 -2
  9. microsoft_agents/hosting/core/storage/memory_storage.py +1 -0
  10. microsoft_agents/hosting/core/storage/storage.py +1 -0
  11. microsoft_agents/hosting/core/storage/transcript_logger.py +1 -0
  12. {microsoft_agents_hosting_core-0.7.0.dist-info → microsoft_agents_hosting_core-0.7.0.dev0.dist-info}/METADATA +3 -21
  13. {microsoft_agents_hosting_core-0.7.0.dist-info → microsoft_agents_hosting_core-0.7.0.dev0.dist-info}/RECORD +16 -25
  14. microsoft_agents/hosting/core/app/streaming/__init__.py +0 -14
  15. microsoft_agents/hosting/core/app/streaming/citation.py +0 -22
  16. microsoft_agents/hosting/core/app/streaming/citation_util.py +0 -85
  17. microsoft_agents/hosting/core/app/streaming/streaming_response.py +0 -411
  18. microsoft_agents/hosting/core/http/__init__.py +0 -17
  19. microsoft_agents/hosting/core/http/_channel_service_routes.py +0 -202
  20. microsoft_agents/hosting/core/http/_http_adapter_base.py +0 -136
  21. microsoft_agents/hosting/core/http/_http_request_protocol.py +0 -36
  22. microsoft_agents/hosting/core/http/_http_response.py +0 -56
  23. {microsoft_agents_hosting_core-0.7.0.dist-info → microsoft_agents_hosting_core-0.7.0.dev0.dist-info}/WHEEL +0 -0
  24. {microsoft_agents_hosting_core-0.7.0.dist-info → microsoft_agents_hosting_core-0.7.0.dev0.dist-info}/licenses/LICENSE +0 -0
  25. {microsoft_agents_hosting_core-0.7.0.dist-info → microsoft_agents_hosting_core-0.7.0.dev0.dist-info}/top_level.txt +0 -0
@@ -1,136 +0,0 @@
1
- # Copyright (c) Microsoft Corporation. All rights reserved.
2
- # Licensed under the MIT License.
3
-
4
- """Base HTTP adapter with shared processing logic."""
5
-
6
- from abc import ABC
7
- from traceback import format_exc
8
-
9
- from microsoft_agents.activity import Activity, DeliveryModes
10
- from microsoft_agents.hosting.core.authorization import ClaimsIdentity, Connections
11
- from microsoft_agents.hosting.core import (
12
- Agent,
13
- ChannelServiceAdapter,
14
- ChannelServiceClientFactoryBase,
15
- MessageFactory,
16
- RestChannelServiceClientFactory,
17
- TurnContext,
18
- )
19
-
20
- from ._http_request_protocol import HttpRequestProtocol
21
- from ._http_response import HttpResponse, HttpResponseFactory
22
-
23
-
24
- class HttpAdapterBase(ChannelServiceAdapter, ABC):
25
- """Base adapter for HTTP-based agent hosting with shared processing logic.
26
-
27
- This class contains all the common logic for processing HTTP requests
28
- and can be subclassed by framework-specific adapters (aiohttp, FastAPI, etc).
29
- """
30
-
31
- def __init__(
32
- self,
33
- *,
34
- connection_manager: Connections = None,
35
- channel_service_client_factory: ChannelServiceClientFactoryBase = None,
36
- ):
37
- """Initialize the HTTP adapter.
38
-
39
- Args:
40
- connection_manager: Optional connection manager for OAuth.
41
- channel_service_client_factory: Factory for creating channel service clients.
42
- """
43
-
44
- async def on_turn_error(context: TurnContext, error: Exception):
45
- error_message = f"Exception caught : {error}"
46
- print(format_exc())
47
-
48
- await context.send_activity(MessageFactory.text(error_message))
49
-
50
- # Send a trace activity
51
- await context.send_trace_activity(
52
- "OnTurnError Trace",
53
- error_message,
54
- "https://www.botframework.com/schemas/error",
55
- "TurnError",
56
- )
57
-
58
- self.on_turn_error = on_turn_error
59
-
60
- channel_service_client_factory = (
61
- channel_service_client_factory
62
- or RestChannelServiceClientFactory(connection_manager)
63
- )
64
-
65
- super().__init__(channel_service_client_factory)
66
-
67
- async def process_request(
68
- self, request: HttpRequestProtocol, agent: Agent
69
- ) -> HttpResponse:
70
- """Process an incoming HTTP request.
71
-
72
- Args:
73
- request: The HTTP request to process.
74
- agent: The agent to handle the request.
75
-
76
- Returns:
77
- HttpResponse with the result.
78
-
79
- Raises:
80
- TypeError: If request or agent is None.
81
- """
82
- if not request:
83
- raise TypeError("HttpAdapterBase.process_request: request can't be None")
84
- if not agent:
85
- raise TypeError("HttpAdapterBase.process_request: agent can't be None")
86
-
87
- if request.method != "POST":
88
- return HttpResponseFactory.method_not_allowed()
89
-
90
- # Deserialize the incoming Activity
91
- content_type = request.headers.get("Content-Type", "")
92
- if "application/json" not in content_type:
93
- return HttpResponseFactory.unsupported_media_type()
94
-
95
- try:
96
- body = await request.json()
97
- except Exception:
98
- return HttpResponseFactory.bad_request("Invalid JSON")
99
-
100
- activity: Activity = Activity.model_validate(body)
101
-
102
- # Get claims identity (default to anonymous if not set by middleware)
103
- claims_identity: ClaimsIdentity = (
104
- request.get_claims_identity() or ClaimsIdentity({}, False)
105
- )
106
-
107
- # Validate required activity fields
108
- if (
109
- not activity.type
110
- or not activity.conversation
111
- or not activity.conversation.id
112
- ):
113
- return HttpResponseFactory.bad_request(
114
- "Activity must have type and conversation.id"
115
- )
116
-
117
- try:
118
- # Process the inbound activity with the agent
119
- invoke_response = await self.process_activity(
120
- claims_identity, activity, agent.on_turn
121
- )
122
-
123
- # Check if we need to return a synchronous response
124
- if (
125
- activity.type == "invoke"
126
- or activity.delivery_mode == DeliveryModes.expect_replies
127
- ):
128
- # Invoke and ExpectReplies cannot be performed async
129
- return HttpResponseFactory.json(
130
- invoke_response.body, invoke_response.status
131
- )
132
-
133
- return HttpResponseFactory.accepted()
134
-
135
- except PermissionError:
136
- return HttpResponseFactory.unauthorized()
@@ -1,36 +0,0 @@
1
- # Copyright (c) Microsoft Corporation. All rights reserved.
2
- # Licensed under the MIT License.
3
-
4
- """Protocol for abstracting HTTP request objects across frameworks."""
5
-
6
- from typing import Protocol, Dict, Any, Optional
7
-
8
-
9
- class HttpRequestProtocol(Protocol):
10
- """Protocol for HTTP requests that adapters must implement.
11
-
12
- This protocol defines the interface that framework-specific request
13
- adapters must implement to work with the shared HTTP adapter logic.
14
- """
15
-
16
- @property
17
- def method(self) -> str:
18
- """HTTP method (GET, POST, etc.)."""
19
- ...
20
-
21
- @property
22
- def headers(self) -> Dict[str, str]:
23
- """Request headers."""
24
- ...
25
-
26
- async def json(self) -> Dict[str, Any]:
27
- """Parse request body as JSON."""
28
- ...
29
-
30
- def get_claims_identity(self) -> Optional[Any]:
31
- """Get claims identity attached by auth middleware."""
32
- ...
33
-
34
- def get_path_param(self, name: str) -> str:
35
- """Get path parameter by name."""
36
- ...
@@ -1,56 +0,0 @@
1
- # Copyright (c) Microsoft Corporation. All rights reserved.
2
- # Licensed under the MIT License.
3
-
4
- """HTTP response abstraction."""
5
-
6
- from typing import Any, Optional, Dict
7
- from dataclasses import dataclass
8
-
9
-
10
- @dataclass
11
- class HttpResponse:
12
- """Framework-agnostic HTTP response."""
13
-
14
- status_code: int
15
- body: Optional[Any] = None
16
- headers: Optional[Dict[str, str]] = None
17
- content_type: Optional[str] = "application/json"
18
-
19
-
20
- class HttpResponseFactory:
21
- """Factory for creating HTTP responses."""
22
-
23
- @staticmethod
24
- def ok(body: Any = None) -> HttpResponse:
25
- """Create 200 OK response."""
26
- return HttpResponse(status_code=200, body=body)
27
-
28
- @staticmethod
29
- def accepted() -> HttpResponse:
30
- """Create 202 Accepted response."""
31
- return HttpResponse(status_code=202)
32
-
33
- @staticmethod
34
- def json(body: Any, status_code: int = 200) -> HttpResponse:
35
- """Create JSON response."""
36
- return HttpResponse(status_code=status_code, body=body)
37
-
38
- @staticmethod
39
- def bad_request(message: str = "Bad Request") -> HttpResponse:
40
- """Create 400 Bad Request response."""
41
- return HttpResponse(status_code=400, body={"error": message})
42
-
43
- @staticmethod
44
- def unauthorized(message: str = "Unauthorized") -> HttpResponse:
45
- """Create 401 Unauthorized response."""
46
- return HttpResponse(status_code=401, body={"error": message})
47
-
48
- @staticmethod
49
- def method_not_allowed(message: str = "Method Not Allowed") -> HttpResponse:
50
- """Create 405 Method Not Allowed response."""
51
- return HttpResponse(status_code=405, body={"error": message})
52
-
53
- @staticmethod
54
- def unsupported_media_type(message: str = "Unsupported Media Type") -> HttpResponse:
55
- """Create 415 Unsupported Media Type response."""
56
- return HttpResponse(status_code=415, body={"error": message})