microsoft-agents-hosting-fastapi 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.
- microsoft_agents/hosting/fastapi/__init__.py +1 -3
- microsoft_agents/hosting/fastapi/channel_service_route_table.py +120 -63
- microsoft_agents/hosting/fastapi/cloud_adapter.py +87 -68
- microsoft_agents/hosting/fastapi/jwt_authorization_middleware.py +1 -0
- {microsoft_agents_hosting_fastapi-0.7.0.dist-info → microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info}/METADATA +2 -29
- {microsoft_agents_hosting_fastapi-0.7.0.dist-info → microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info}/RECORD +9 -9
- {microsoft_agents_hosting_fastapi-0.7.0.dist-info → microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info}/WHEEL +0 -0
- {microsoft_agents_hosting_fastapi-0.7.0.dist-info → microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info}/licenses/LICENSE +0 -0
- {microsoft_agents_hosting_fastapi-0.7.0.dist-info → microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info}/top_level.txt +0 -0
|
@@ -5,9 +5,7 @@ from .cloud_adapter import CloudAdapter
|
|
|
5
5
|
from .jwt_authorization_middleware import (
|
|
6
6
|
JwtAuthorizationMiddleware,
|
|
7
7
|
)
|
|
8
|
-
|
|
9
|
-
# Import streaming utilities from core for backward compatibility
|
|
10
|
-
from microsoft_agents.hosting.core.app.streaming import (
|
|
8
|
+
from .app.streaming import (
|
|
11
9
|
Citation,
|
|
12
10
|
CitationUtil,
|
|
13
11
|
StreamingResponse,
|
|
@@ -1,58 +1,64 @@
|
|
|
1
1
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
2
|
# Licensed under the MIT License.
|
|
3
|
+
import json
|
|
4
|
+
from typing import List, Union, Type
|
|
3
5
|
|
|
4
|
-
from fastapi import APIRouter, Request, Response
|
|
6
|
+
from fastapi import APIRouter, Request, Response, HTTPException, Depends
|
|
5
7
|
from fastapi.responses import JSONResponse
|
|
6
8
|
|
|
9
|
+
from microsoft_agents.activity import (
|
|
10
|
+
AgentsModel,
|
|
11
|
+
Activity,
|
|
12
|
+
AttachmentData,
|
|
13
|
+
ConversationParameters,
|
|
14
|
+
Transcript,
|
|
15
|
+
)
|
|
7
16
|
from microsoft_agents.hosting.core import ChannelApiHandlerProtocol
|
|
8
|
-
from microsoft_agents.hosting.core.http import ChannelServiceRoutes
|
|
9
17
|
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
|
|
19
|
+
async def deserialize_from_body(
|
|
20
|
+
request: Request, target_model: Type[AgentsModel]
|
|
21
|
+
) -> AgentsModel:
|
|
22
|
+
content_type = request.headers.get("Content-Type", "")
|
|
23
|
+
if "application/json" in content_type:
|
|
24
|
+
body = await request.json()
|
|
25
|
+
else:
|
|
26
|
+
raise HTTPException(status_code=415, detail="Unsupported Media Type")
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
self._request = request
|
|
28
|
+
return target_model.model_validate(body)
|
|
16
29
|
|
|
17
|
-
@property
|
|
18
|
-
def method(self) -> str:
|
|
19
|
-
return self._request.method
|
|
20
30
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
def get_serialized_response(
|
|
32
|
+
model_or_list: Union[AgentsModel, List[AgentsModel]],
|
|
33
|
+
) -> JSONResponse:
|
|
34
|
+
if isinstance(model_or_list, AgentsModel):
|
|
35
|
+
json_obj = model_or_list.model_dump(
|
|
36
|
+
mode="json", exclude_unset=True, by_alias=True
|
|
37
|
+
)
|
|
38
|
+
else:
|
|
39
|
+
json_obj = [
|
|
40
|
+
model.model_dump(mode="json", exclude_unset=True, by_alias=True)
|
|
41
|
+
for model in model_or_list
|
|
42
|
+
]
|
|
30
43
|
|
|
31
|
-
|
|
32
|
-
return self._request.path_params.get(name, "")
|
|
44
|
+
return JSONResponse(content=json_obj)
|
|
33
45
|
|
|
34
46
|
|
|
35
47
|
def channel_service_route_table(
|
|
36
48
|
handler: ChannelApiHandlerProtocol, base_url: str = ""
|
|
37
49
|
) -> APIRouter:
|
|
38
|
-
"""Create FastAPI router for Channel Service API.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
handler: The handler that implements the Channel API protocol.
|
|
42
|
-
base_url: Optional base URL prefix for all routes.
|
|
43
|
-
|
|
44
|
-
Returns:
|
|
45
|
-
APIRouter with all channel service routes.
|
|
46
|
-
"""
|
|
47
50
|
router = APIRouter()
|
|
48
|
-
service_routes = ChannelServiceRoutes(handler, base_url)
|
|
49
51
|
|
|
50
52
|
@router.post(base_url + "/v3/conversations/{conversation_id}/activities")
|
|
51
53
|
async def send_to_conversation(conversation_id: str, request: Request):
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
activity = await deserialize_from_body(request, Activity)
|
|
55
|
+
result = await handler.on_send_to_conversation(
|
|
56
|
+
getattr(request.state, "claims_identity", None),
|
|
57
|
+
conversation_id,
|
|
58
|
+
activity,
|
|
54
59
|
)
|
|
55
|
-
|
|
60
|
+
|
|
61
|
+
return get_serialized_response(result)
|
|
56
62
|
|
|
57
63
|
@router.post(
|
|
58
64
|
base_url + "/v3/conversations/{conversation_id}/activities/{activity_id}"
|
|
@@ -60,21 +66,40 @@ def channel_service_route_table(
|
|
|
60
66
|
async def reply_to_activity(
|
|
61
67
|
conversation_id: str, activity_id: str, request: Request
|
|
62
68
|
):
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
activity = await deserialize_from_body(request, Activity)
|
|
70
|
+
result = await handler.on_reply_to_activity(
|
|
71
|
+
getattr(request.state, "claims_identity", None),
|
|
72
|
+
conversation_id,
|
|
73
|
+
activity_id,
|
|
74
|
+
activity,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
return get_serialized_response(result)
|
|
65
78
|
|
|
66
79
|
@router.put(
|
|
67
80
|
base_url + "/v3/conversations/{conversation_id}/activities/{activity_id}"
|
|
68
81
|
)
|
|
69
82
|
async def update_activity(conversation_id: str, activity_id: str, request: Request):
|
|
70
|
-
|
|
71
|
-
|
|
83
|
+
activity = await deserialize_from_body(request, Activity)
|
|
84
|
+
result = await handler.on_update_activity(
|
|
85
|
+
getattr(request.state, "claims_identity", None),
|
|
86
|
+
conversation_id,
|
|
87
|
+
activity_id,
|
|
88
|
+
activity,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
return get_serialized_response(result)
|
|
72
92
|
|
|
73
93
|
@router.delete(
|
|
74
94
|
base_url + "/v3/conversations/{conversation_id}/activities/{activity_id}"
|
|
75
95
|
)
|
|
76
96
|
async def delete_activity(conversation_id: str, activity_id: str, request: Request):
|
|
77
|
-
await
|
|
97
|
+
await handler.on_delete_activity(
|
|
98
|
+
getattr(request.state, "claims_identity", None),
|
|
99
|
+
conversation_id,
|
|
100
|
+
activity_id,
|
|
101
|
+
)
|
|
102
|
+
|
|
78
103
|
return Response(status_code=200)
|
|
79
104
|
|
|
80
105
|
@router.get(
|
|
@@ -84,65 +109,97 @@ def channel_service_route_table(
|
|
|
84
109
|
async def get_activity_members(
|
|
85
110
|
conversation_id: str, activity_id: str, request: Request
|
|
86
111
|
):
|
|
87
|
-
result = await
|
|
88
|
-
|
|
112
|
+
result = await handler.on_get_activity_members(
|
|
113
|
+
getattr(request.state, "claims_identity", None),
|
|
114
|
+
conversation_id,
|
|
115
|
+
activity_id,
|
|
89
116
|
)
|
|
90
|
-
|
|
117
|
+
|
|
118
|
+
return get_serialized_response(result)
|
|
91
119
|
|
|
92
120
|
@router.post(base_url + "/")
|
|
93
121
|
async def create_conversation(request: Request):
|
|
94
|
-
|
|
95
|
-
|
|
122
|
+
conversation_parameters = await deserialize_from_body(
|
|
123
|
+
request, ConversationParameters
|
|
124
|
+
)
|
|
125
|
+
result = await handler.on_create_conversation(
|
|
126
|
+
getattr(request.state, "claims_identity", None), conversation_parameters
|
|
96
127
|
)
|
|
97
|
-
|
|
128
|
+
|
|
129
|
+
return get_serialized_response(result)
|
|
98
130
|
|
|
99
131
|
@router.get(base_url + "/")
|
|
100
132
|
async def get_conversation(request: Request):
|
|
101
|
-
|
|
102
|
-
|
|
133
|
+
# TODO: continuation token? conversation_id?
|
|
134
|
+
result = await handler.on_get_conversations(
|
|
135
|
+
getattr(request.state, "claims_identity", None), None
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
return get_serialized_response(result)
|
|
103
139
|
|
|
104
140
|
@router.get(base_url + "/v3/conversations/{conversation_id}/members")
|
|
105
141
|
async def get_conversation_members(conversation_id: str, request: Request):
|
|
106
|
-
result = await
|
|
107
|
-
|
|
142
|
+
result = await handler.on_get_conversation_members(
|
|
143
|
+
getattr(request.state, "claims_identity", None),
|
|
144
|
+
conversation_id,
|
|
108
145
|
)
|
|
109
|
-
|
|
146
|
+
|
|
147
|
+
return get_serialized_response(result)
|
|
110
148
|
|
|
111
149
|
@router.get(base_url + "/v3/conversations/{conversation_id}/members/{member_id}")
|
|
112
150
|
async def get_conversation_member(
|
|
113
151
|
conversation_id: str, member_id: str, request: Request
|
|
114
152
|
):
|
|
115
|
-
result = await
|
|
116
|
-
|
|
153
|
+
result = await handler.on_get_conversation_member(
|
|
154
|
+
getattr(request.state, "claims_identity", None),
|
|
155
|
+
member_id,
|
|
156
|
+
conversation_id,
|
|
117
157
|
)
|
|
118
|
-
|
|
158
|
+
|
|
159
|
+
return get_serialized_response(result)
|
|
119
160
|
|
|
120
161
|
@router.get(base_url + "/v3/conversations/{conversation_id}/pagedmembers")
|
|
121
162
|
async def get_conversation_paged_members(conversation_id: str, request: Request):
|
|
122
|
-
|
|
123
|
-
|
|
163
|
+
# TODO: continuation token? page size?
|
|
164
|
+
result = await handler.on_get_conversation_paged_members(
|
|
165
|
+
getattr(request.state, "claims_identity", None),
|
|
166
|
+
conversation_id,
|
|
124
167
|
)
|
|
125
|
-
|
|
168
|
+
|
|
169
|
+
return get_serialized_response(result)
|
|
126
170
|
|
|
127
171
|
@router.delete(base_url + "/v3/conversations/{conversation_id}/members/{member_id}")
|
|
128
172
|
async def delete_conversation_member(
|
|
129
173
|
conversation_id: str, member_id: str, request: Request
|
|
130
174
|
):
|
|
131
|
-
result = await
|
|
132
|
-
|
|
175
|
+
result = await handler.on_delete_conversation_member(
|
|
176
|
+
getattr(request.state, "claims_identity", None),
|
|
177
|
+
conversation_id,
|
|
178
|
+
member_id,
|
|
133
179
|
)
|
|
134
|
-
|
|
180
|
+
|
|
181
|
+
return get_serialized_response(result)
|
|
135
182
|
|
|
136
183
|
@router.post(base_url + "/v3/conversations/{conversation_id}/activities/history")
|
|
137
184
|
async def send_conversation_history(conversation_id: str, request: Request):
|
|
138
|
-
|
|
139
|
-
|
|
185
|
+
transcript = await deserialize_from_body(request, Transcript)
|
|
186
|
+
result = await handler.on_send_conversation_history(
|
|
187
|
+
getattr(request.state, "claims_identity", None),
|
|
188
|
+
conversation_id,
|
|
189
|
+
transcript,
|
|
140
190
|
)
|
|
141
|
-
|
|
191
|
+
|
|
192
|
+
return get_serialized_response(result)
|
|
142
193
|
|
|
143
194
|
@router.post(base_url + "/v3/conversations/{conversation_id}/attachments")
|
|
144
195
|
async def upload_attachment(conversation_id: str, request: Request):
|
|
145
|
-
|
|
146
|
-
|
|
196
|
+
attachment_data = await deserialize_from_body(request, AttachmentData)
|
|
197
|
+
result = await handler.on_upload_attachment(
|
|
198
|
+
getattr(request.state, "claims_identity", None),
|
|
199
|
+
conversation_id,
|
|
200
|
+
attachment_data,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
return get_serialized_response(result)
|
|
147
204
|
|
|
148
205
|
return router
|
|
@@ -1,48 +1,32 @@
|
|
|
1
1
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
2
|
# Licensed under the MIT License.
|
|
3
|
+
from traceback import format_exc
|
|
3
4
|
from typing import Optional
|
|
4
5
|
|
|
5
|
-
from fastapi import Request, Response
|
|
6
|
+
from fastapi import Request, Response, HTTPException
|
|
6
7
|
from fastapi.responses import JSONResponse
|
|
7
|
-
|
|
8
|
-
from microsoft_agents.hosting.core import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
from microsoft_agents.hosting.core import error_resources
|
|
9
|
+
from microsoft_agents.hosting.core.authorization import (
|
|
10
|
+
ClaimsIdentity,
|
|
11
|
+
Connections,
|
|
12
|
+
)
|
|
13
|
+
from microsoft_agents.activity import (
|
|
14
|
+
Activity,
|
|
15
|
+
DeliveryModes,
|
|
16
|
+
)
|
|
17
|
+
from microsoft_agents.hosting.core import (
|
|
18
|
+
Agent,
|
|
19
|
+
ChannelServiceAdapter,
|
|
20
|
+
ChannelServiceClientFactoryBase,
|
|
21
|
+
MessageFactory,
|
|
22
|
+
RestChannelServiceClientFactory,
|
|
23
|
+
TurnContext,
|
|
13
24
|
)
|
|
14
|
-
from microsoft_agents.hosting.core import ChannelServiceClientFactoryBase
|
|
15
25
|
|
|
16
26
|
from .agent_http_adapter import AgentHttpAdapter
|
|
17
27
|
|
|
18
28
|
|
|
19
|
-
class
|
|
20
|
-
"""Adapter to make FastAPI Request compatible with HttpRequestProtocol."""
|
|
21
|
-
|
|
22
|
-
def __init__(self, request: Request):
|
|
23
|
-
self._request = request
|
|
24
|
-
|
|
25
|
-
@property
|
|
26
|
-
def method(self) -> str:
|
|
27
|
-
return self._request.method
|
|
28
|
-
|
|
29
|
-
@property
|
|
30
|
-
def headers(self):
|
|
31
|
-
return self._request.headers
|
|
32
|
-
|
|
33
|
-
async def json(self):
|
|
34
|
-
return await self._request.json()
|
|
35
|
-
|
|
36
|
-
def get_claims_identity(self):
|
|
37
|
-
return getattr(self._request.state, "claims_identity", None)
|
|
38
|
-
|
|
39
|
-
def get_path_param(self, name: str) -> str:
|
|
40
|
-
return self._request.path_params.get(name, "")
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class CloudAdapter(HttpAdapterBase, AgentHttpAdapter):
|
|
44
|
-
"""CloudAdapter for FastAPI web framework."""
|
|
45
|
-
|
|
29
|
+
class CloudAdapter(ChannelServiceAdapter, AgentHttpAdapter):
|
|
46
30
|
def __init__(
|
|
47
31
|
self,
|
|
48
32
|
*,
|
|
@@ -52,43 +36,78 @@ class CloudAdapter(HttpAdapterBase, AgentHttpAdapter):
|
|
|
52
36
|
"""
|
|
53
37
|
Initializes a new instance of the CloudAdapter class.
|
|
54
38
|
|
|
55
|
-
:param connection_manager: Optional connection manager for OAuth.
|
|
56
39
|
:param channel_service_client_factory: The factory to use to create the channel service client.
|
|
57
40
|
"""
|
|
58
|
-
super().__init__(
|
|
59
|
-
connection_manager=connection_manager,
|
|
60
|
-
channel_service_client_factory=channel_service_client_factory,
|
|
61
|
-
)
|
|
62
41
|
|
|
63
|
-
|
|
64
|
-
|
|
42
|
+
async def on_turn_error(context: TurnContext, error: Exception):
|
|
43
|
+
error_message = f"Exception caught : {error}"
|
|
44
|
+
print(format_exc())
|
|
65
45
|
|
|
66
|
-
|
|
67
|
-
request: The FastAPI request.
|
|
68
|
-
agent: The agent to handle the request.
|
|
46
|
+
await context.send_activity(MessageFactory.text(error_message))
|
|
69
47
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# Process using base implementation
|
|
77
|
-
http_response: HttpResponse = await self.process_request(adapted_request, agent)
|
|
78
|
-
|
|
79
|
-
# Convert HttpResponse to FastAPI Response
|
|
80
|
-
return self._to_fastapi_response(http_response)
|
|
81
|
-
|
|
82
|
-
@staticmethod
|
|
83
|
-
def _to_fastapi_response(http_response: HttpResponse) -> Response:
|
|
84
|
-
"""Convert HttpResponse to FastAPI Response."""
|
|
85
|
-
if http_response.body is not None:
|
|
86
|
-
return JSONResponse(
|
|
87
|
-
content=http_response.body,
|
|
88
|
-
status_code=http_response.status_code,
|
|
89
|
-
headers=http_response.headers,
|
|
48
|
+
# Send a trace activity
|
|
49
|
+
await context.send_trace_activity(
|
|
50
|
+
"OnTurnError Trace",
|
|
51
|
+
error_message,
|
|
52
|
+
"https://www.botframework.com/schemas/error",
|
|
53
|
+
"TurnError",
|
|
90
54
|
)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
55
|
+
|
|
56
|
+
self.on_turn_error = on_turn_error
|
|
57
|
+
|
|
58
|
+
channel_service_client_factory = (
|
|
59
|
+
channel_service_client_factory
|
|
60
|
+
or RestChannelServiceClientFactory(connection_manager)
|
|
94
61
|
)
|
|
62
|
+
|
|
63
|
+
super().__init__(channel_service_client_factory)
|
|
64
|
+
|
|
65
|
+
async def process(self, request: Request, agent: Agent) -> Optional[Response]:
|
|
66
|
+
if not request:
|
|
67
|
+
raise TypeError(str(error_resources.RequestRequired))
|
|
68
|
+
if not agent:
|
|
69
|
+
raise TypeError(str(error_resources.AgentRequired))
|
|
70
|
+
|
|
71
|
+
if request.method == "POST":
|
|
72
|
+
# Deserialize the incoming Activity
|
|
73
|
+
content_type = request.headers.get("Content-Type", "")
|
|
74
|
+
if "application/json" in content_type:
|
|
75
|
+
body = await request.json()
|
|
76
|
+
else:
|
|
77
|
+
raise HTTPException(status_code=415, detail="Unsupported Media Type")
|
|
78
|
+
|
|
79
|
+
activity: Activity = Activity.model_validate(body)
|
|
80
|
+
|
|
81
|
+
# default to anonymous identity with no claims
|
|
82
|
+
claims_identity: ClaimsIdentity = getattr(
|
|
83
|
+
request.state, "claims_identity", ClaimsIdentity({}, False)
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# A POST request must contain an Activity
|
|
87
|
+
if (
|
|
88
|
+
not activity.type
|
|
89
|
+
or not activity.conversation
|
|
90
|
+
or not activity.conversation.id
|
|
91
|
+
):
|
|
92
|
+
raise HTTPException(status_code=400, detail="Bad Request")
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
# Process the inbound activity with the agent
|
|
96
|
+
invoke_response = await self.process_activity(
|
|
97
|
+
claims_identity, activity, agent.on_turn
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if (
|
|
101
|
+
activity.type == "invoke"
|
|
102
|
+
or activity.delivery_mode == DeliveryModes.expect_replies
|
|
103
|
+
):
|
|
104
|
+
# Invoke and ExpectReplies cannot be performed async, the response must be written before the calling thread is released.
|
|
105
|
+
return JSONResponse(
|
|
106
|
+
content=invoke_response.body, status_code=invoke_response.status
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return Response(status_code=202)
|
|
110
|
+
except PermissionError:
|
|
111
|
+
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
112
|
+
else:
|
|
113
|
+
raise HTTPException(status_code=405, detail="Method Not Allowed")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: microsoft-agents-hosting-fastapi
|
|
3
|
-
Version: 0.7.0
|
|
3
|
+
Version: 0.7.0.dev0
|
|
4
4
|
Summary: Integration library for Microsoft Agents with FastAPI
|
|
5
5
|
Author: Microsoft Corporation
|
|
6
6
|
License-Expression: MIT
|
|
@@ -10,7 +10,7 @@ Classifier: Operating System :: OS Independent
|
|
|
10
10
|
Requires-Python: >=3.10
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
|
-
Requires-Dist: microsoft-agents-hosting-core==0.7.0
|
|
13
|
+
Requires-Dist: microsoft-agents-hosting-core==0.7.0.dev0
|
|
14
14
|
Requires-Dist: fastapi>=0.104.0
|
|
15
15
|
Dynamic: license-file
|
|
16
16
|
Dynamic: requires-dist
|
|
@@ -19,33 +19,6 @@ Dynamic: requires-dist
|
|
|
19
19
|
|
|
20
20
|
This library provides FastAPI integration for Microsoft Agents, enabling you to build conversational agents using the FastAPI web framework.
|
|
21
21
|
|
|
22
|
-
## Release Notes
|
|
23
|
-
<table style="width:100%">
|
|
24
|
-
<tr>
|
|
25
|
-
<th style="width:20%">Version</th>
|
|
26
|
-
<th style="width:20%">Date</th>
|
|
27
|
-
<th style="width:60%">Release Notes</th>
|
|
28
|
-
</tr>
|
|
29
|
-
<tr>
|
|
30
|
-
<td>0.6.1</td>
|
|
31
|
-
<td>2025-12-01</td>
|
|
32
|
-
<td>
|
|
33
|
-
<a href="https://github.com/microsoft/Agents-for-python/blob/main/changelog.md#microsoft-365-agents-sdk-for-python---release-notes-v061">
|
|
34
|
-
0.6.1 Release Notes
|
|
35
|
-
</a>
|
|
36
|
-
</td>
|
|
37
|
-
</tr>
|
|
38
|
-
<tr>
|
|
39
|
-
<td>0.6.0</td>
|
|
40
|
-
<td>2025-11-18</td>
|
|
41
|
-
<td>
|
|
42
|
-
<a href="https://github.com/microsoft/Agents-for-python/blob/main/changelog.md#microsoft-365-agents-sdk-for-python---release-notes-v060">
|
|
43
|
-
0.6.0 Release Notes
|
|
44
|
-
</a>
|
|
45
|
-
</td>
|
|
46
|
-
</tr>
|
|
47
|
-
</table>
|
|
48
|
-
|
|
49
22
|
## Features
|
|
50
23
|
|
|
51
24
|
- FastAPI integration for Microsoft Agents
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
microsoft_agents/hosting/fastapi/__init__.py,sha256=
|
|
1
|
+
microsoft_agents/hosting/fastapi/__init__.py,sha256=9IuCCWHY4FEPGAzv9uEyob0irIbMqAomjjiYKs95NPA,592
|
|
2
2
|
microsoft_agents/hosting/fastapi/_start_agent_process.py,sha256=u4aTpiPYzhcOPD1nJjVD1stRFGmsysAE3QS8vOV_37c,946
|
|
3
3
|
microsoft_agents/hosting/fastapi/agent_http_adapter.py,sha256=40fi8bPXzXMGMAdeK1NDT34RSbKP--jLzBvRJ159-BQ,427
|
|
4
|
-
microsoft_agents/hosting/fastapi/channel_service_route_table.py,sha256=
|
|
5
|
-
microsoft_agents/hosting/fastapi/cloud_adapter.py,sha256=
|
|
6
|
-
microsoft_agents/hosting/fastapi/jwt_authorization_middleware.py,sha256=
|
|
4
|
+
microsoft_agents/hosting/fastapi/channel_service_route_table.py,sha256=NHt5958_SpcT1O6tTSPuTtZX0R196IAcDUr5gWuTYZ4,7113
|
|
5
|
+
microsoft_agents/hosting/fastapi/cloud_adapter.py,sha256=wg9wFjRvEvM1scD8lqBASXhcoGlsssB8cxfKMROp-Co,4028
|
|
6
|
+
microsoft_agents/hosting/fastapi/jwt_authorization_middleware.py,sha256=YMLqoXrUcC5klaLiKT4uP_dF7Tz1KbsVJjL2PvWgkLQ,2600
|
|
7
7
|
microsoft_agents/hosting/fastapi/app/__init__.py,sha256=TioskqZet16twXOsI3X2snyLzmuyeKNtN2dySD1Xw7s,253
|
|
8
8
|
microsoft_agents/hosting/fastapi/app/streaming/__init__.py,sha256=G_VGmQ0m6TkHZsHjRV5HitaCOt2EBEjENIoBYabJMqM,292
|
|
9
9
|
microsoft_agents/hosting/fastapi/app/streaming/citation.py,sha256=ZGaMUOWxxoMplwRrkFsjnK7Z12V6rT5odE7qZCu-mP8,498
|
|
10
10
|
microsoft_agents/hosting/fastapi/app/streaming/citation_util.py,sha256=c95c3Y3genmFc0vSXppPaD1-ShFohAV1UABZnyJS_BQ,2478
|
|
11
11
|
microsoft_agents/hosting/fastapi/app/streaming/streaming_response.py,sha256=c5jytVvOIV3f1zKWxpFFxvCS6nR_8mi7bhv5pYusIGw,13325
|
|
12
|
-
microsoft_agents_hosting_fastapi-0.7.0.dist-info/licenses/LICENSE,sha256=oDrK6gJRdwYynx5l4UtyDa2nX_D1WWkvionBYrCebek,1073
|
|
13
|
-
microsoft_agents_hosting_fastapi-0.7.0.dist-info/METADATA,sha256=
|
|
14
|
-
microsoft_agents_hosting_fastapi-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
-
microsoft_agents_hosting_fastapi-0.7.0.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
|
|
16
|
-
microsoft_agents_hosting_fastapi-0.7.0.dist-info/RECORD,,
|
|
12
|
+
microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info/licenses/LICENSE,sha256=oDrK6gJRdwYynx5l4UtyDa2nX_D1WWkvionBYrCebek,1073
|
|
13
|
+
microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info/METADATA,sha256=_vpvIr9V7X1XwKTp27MybUG1PTM7rBOjY47xexKxHbY,1431
|
|
14
|
+
microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
+
microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info/top_level.txt,sha256=lWKcT4v6fTA_NgsuHdNvuMjSrkiBMXohn64ApY7Xi8A,17
|
|
16
|
+
microsoft_agents_hosting_fastapi-0.7.0.dev0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|