agent-framework-foundry 1.13.0__tar.gz → 1.14.0__tar.gz
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.
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/PKG-INFO +84 -6
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/README.md +80 -2
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_agent.py +12 -2
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_chat_client.py +106 -5
- agent_framework_foundry-1.14.0/agent_framework_foundry/_constants.py +10 -0
- agent_framework_foundry-1.14.0/agent_framework_foundry/_embedding_client.py +602 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_feature_usage.py +1 -0
- agent_framework_foundry-1.14.0/agent_framework_foundry/py.typed +0 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/pyproject.toml +4 -4
- agent_framework_foundry-1.13.0/agent_framework_foundry/_constants.py +0 -3
- agent_framework_foundry-1.13.0/agent_framework_foundry/_embedding_client.py +0 -407
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/LICENSE +0 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/__init__.py +0 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_foundry_evals.py +0 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_memory_provider.py +0 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_oauth_helpers.py +0 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_to_prompt_agent.py +0 -0
- {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-framework-foundry
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.14.0
|
|
4
4
|
Summary: Microsoft Foundry integrations for Microsoft Agent Framework.
|
|
5
5
|
Author-email: Microsoft <af-support@microsoft.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -16,11 +16,11 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.14
|
|
17
17
|
Classifier: Typing :: Typed
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: agent-framework-core>=1.
|
|
20
|
-
Requires-Dist: agent-framework-openai>=1.
|
|
19
|
+
Requires-Dist: agent-framework-core>=1.20.0,<2
|
|
20
|
+
Requires-Dist: agent-framework-openai>=1.15.0,<2
|
|
21
21
|
Requires-Dist: aiohttp>=3.9,<4
|
|
22
22
|
Requires-Dist: azure-ai-inference>=1.0.0b9,<1.0.0b10
|
|
23
|
-
Requires-Dist: azure-ai-projects>=2.2.0,<2.
|
|
23
|
+
Requires-Dist: azure-ai-projects>=2.2.0,<2.8.0
|
|
24
24
|
Requires-Dist: httpx>=0.28,<1
|
|
25
25
|
Project-URL: homepage, https://aka.ms/agent-framework
|
|
26
26
|
Project-URL: issues, https://github.com/microsoft/agent-framework/issues
|
|
@@ -33,10 +33,56 @@ This package contains the Microsoft Foundry integrations for Microsoft Agent Fra
|
|
|
33
33
|
|
|
34
34
|
## SDK compatibility
|
|
35
35
|
|
|
36
|
-
This package supports `azure-ai-projects>=2.2.0,<2.
|
|
36
|
+
This package supports `azure-ai-projects>=2.2.0,<2.8.0`. Projects 2.5 and later require
|
|
37
37
|
`openai>=3.0.0`, so `agent-framework-foundry` requires `agent-framework-openai>=1.14.2`,
|
|
38
38
|
which supports both OpenAI 2.x and 3.x.
|
|
39
39
|
|
|
40
|
+
## Tracing an existing Foundry agent
|
|
41
|
+
|
|
42
|
+
Install Azure Monitor to connect client and service traces:
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
pip install --upgrade agent-framework-foundry "azure-monitor-opentelemetry>=1.8.10,<2"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
With Application Insights connected to your project, call
|
|
49
|
+
`await agent.configure_azure_monitor()` before invoking a `FoundryAgent`.
|
|
50
|
+
See [the tracing sample](../../samples/02-agents/observability/foundry_agent_tracing.py)
|
|
51
|
+
for streaming and non-streaming examples.
|
|
52
|
+
|
|
53
|
+
## Embeddings
|
|
54
|
+
|
|
55
|
+
`FoundryEmbeddingClient` supports OpenAI text embedding deployments exposed through a Microsoft Foundry project.
|
|
56
|
+
Pass an existing `AIProjectClient`, or provide the project endpoint and an async Azure credential:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import os
|
|
60
|
+
|
|
61
|
+
from agent_framework.foundry import FoundryEmbeddingClient
|
|
62
|
+
from azure.identity.aio import AzureCliCredential
|
|
63
|
+
|
|
64
|
+
async with AzureCliCredential() as credential:
|
|
65
|
+
async with FoundryEmbeddingClient(
|
|
66
|
+
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
|
67
|
+
model=os.environ["FOUNDRY_EMBEDDING_MODEL"],
|
|
68
|
+
credential=credential,
|
|
69
|
+
) as client:
|
|
70
|
+
result = await client.get_embeddings(["Hello, world!"])
|
|
71
|
+
print(result[0].dimensions)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Set `FOUNDRY_PROJECT_ENDPOINT` to the project endpoint and `FOUNDRY_EMBEDDING_MODEL` to the embedding deployment
|
|
75
|
+
name. When an `AIProjectClient` is already available, pass it as `project_client` and omit the endpoint and
|
|
76
|
+
credential.
|
|
77
|
+
|
|
78
|
+
The client uses the project for authentication and converts a
|
|
79
|
+
`https://<resource>.services.ai.azure.com/api/projects/<project>` endpoint to the documented resource-scoped
|
|
80
|
+
`https://<resource>.openai.azure.com/openai/v1/` model route. The existing `FOUNDRY_MODELS_ENDPOINT` and
|
|
81
|
+
`FOUNDRY_MODELS_API_KEY` configuration remains available for Foundry Models inference endpoints. A Models endpoint is
|
|
82
|
+
required for image embedding models. If both project and Models endpoints are configured only through environment
|
|
83
|
+
variables, the Models endpoint is retained for backward compatibility; pass `project_endpoint` explicitly to select
|
|
84
|
+
the project OpenAI deployment.
|
|
85
|
+
|
|
40
86
|
## Evaluations
|
|
41
87
|
|
|
42
88
|
`FoundryEvals` implements the provider-neutral `Evaluator` protocol with
|
|
@@ -134,10 +180,42 @@ agent = Agent(
|
|
|
134
180
|
)
|
|
135
181
|
```
|
|
136
182
|
|
|
137
|
-
|
|
183
|
+
Non-preview factories: `get_computer_tool`, `get_code_interpreter_tool`,
|
|
138
184
|
`get_file_search_tool`, `get_web_search_tool`,
|
|
139
185
|
`get_image_generation_tool`, `get_mcp_tool`.
|
|
140
186
|
|
|
187
|
+
`get_computer_tool()` returns the Foundry SDK's `ComputerTool` (available in
|
|
188
|
+
`azure-ai-projects>=2.3.0`). The package still supports 2.2.x for other tools:
|
|
189
|
+
only calling this factory on an older SDK raises `ImportError` with upgrade guidance.
|
|
190
|
+
`get_computer_use_tool(...)` remains available for the separate preview API.
|
|
191
|
+
The OpenAI Responses client also exposes `OpenAIChatClient.get_computer_tool()`.
|
|
192
|
+
The new `ComputerSafetyCheck` type and `Content.from_computer_tool_call` /
|
|
193
|
+
`Content.from_computer_tool_result` constructors are experimental Agent Framework APIs,
|
|
194
|
+
even though Foundry's `ComputerTool` is a non-preview SDK model.
|
|
195
|
+
|
|
196
|
+
Computer calls arrive as `Content` with `type="computer_tool_call"`, a
|
|
197
|
+
provider item `id`, a distinct `call_id`, ordered `actions`, and optional
|
|
198
|
+
`pending_safety_checks`. Unanswered calls require application input: inspect
|
|
199
|
+
`AgentResponse.user_input_requests` (or `ChatResponse.messages[*].contents`),
|
|
200
|
+
show the actions and warnings to the user, and execute actions only after
|
|
201
|
+
approval. To continue, return `Content.from_computer_tool_result(call_id=...,
|
|
202
|
+
screenshot=Content.from_data(image_bytes, "image/png"))` in a tool message;
|
|
203
|
+
`Content.from_uri(...)` and `Content.from_hosted_file(...)` also work for
|
|
204
|
+
screenshots. Shared `Content` allows a result without a screenshot for other
|
|
205
|
+
providers, but OpenAI and Foundry Responses require one. If checks were pending,
|
|
206
|
+
explicitly pass *only* those the
|
|
207
|
+
application has confirmed as `acknowledged_safety_checks=[{"id": "..."}]`.
|
|
208
|
+
The framework never acknowledges warnings on your behalf. Calls and results
|
|
209
|
+
can be persisted as `Content.to_dict()` and restored with `Content.from_dict()`.
|
|
210
|
+
A call already paired with a completed screenshot result stays in the transcript
|
|
211
|
+
for audit (`informational_only=True`), but does not appear in
|
|
212
|
+
`AgentResponse.user_input_requests`. When a workflow pauses on a computer call
|
|
213
|
+
alongside locally executable functions, it sends their completed results with
|
|
214
|
+
the screenshot in the original call order after the application responds. If
|
|
215
|
+
any computer request in a workflow batch is cancelled, the remaining requests
|
|
216
|
+
in that agent's batch are cancelled too; the terminal output retains already
|
|
217
|
+
resolved results, and the next turn starts with a fresh agent session.
|
|
218
|
+
|
|
141
219
|
> **Choosing a web grounding tool.** `get_web_search_tool` is the recommended
|
|
142
220
|
> default — it requires no separate Bing resource and works with Azure OpenAI
|
|
143
221
|
> models out of the box. Reach for `get_bing_grounding_tool` (experimental,
|
|
@@ -4,10 +4,56 @@ This package contains the Microsoft Foundry integrations for Microsoft Agent Fra
|
|
|
4
4
|
|
|
5
5
|
## SDK compatibility
|
|
6
6
|
|
|
7
|
-
This package supports `azure-ai-projects>=2.2.0,<2.
|
|
7
|
+
This package supports `azure-ai-projects>=2.2.0,<2.8.0`. Projects 2.5 and later require
|
|
8
8
|
`openai>=3.0.0`, so `agent-framework-foundry` requires `agent-framework-openai>=1.14.2`,
|
|
9
9
|
which supports both OpenAI 2.x and 3.x.
|
|
10
10
|
|
|
11
|
+
## Tracing an existing Foundry agent
|
|
12
|
+
|
|
13
|
+
Install Azure Monitor to connect client and service traces:
|
|
14
|
+
|
|
15
|
+
```shell
|
|
16
|
+
pip install --upgrade agent-framework-foundry "azure-monitor-opentelemetry>=1.8.10,<2"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
With Application Insights connected to your project, call
|
|
20
|
+
`await agent.configure_azure_monitor()` before invoking a `FoundryAgent`.
|
|
21
|
+
See [the tracing sample](../../samples/02-agents/observability/foundry_agent_tracing.py)
|
|
22
|
+
for streaming and non-streaming examples.
|
|
23
|
+
|
|
24
|
+
## Embeddings
|
|
25
|
+
|
|
26
|
+
`FoundryEmbeddingClient` supports OpenAI text embedding deployments exposed through a Microsoft Foundry project.
|
|
27
|
+
Pass an existing `AIProjectClient`, or provide the project endpoint and an async Azure credential:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import os
|
|
31
|
+
|
|
32
|
+
from agent_framework.foundry import FoundryEmbeddingClient
|
|
33
|
+
from azure.identity.aio import AzureCliCredential
|
|
34
|
+
|
|
35
|
+
async with AzureCliCredential() as credential:
|
|
36
|
+
async with FoundryEmbeddingClient(
|
|
37
|
+
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
|
38
|
+
model=os.environ["FOUNDRY_EMBEDDING_MODEL"],
|
|
39
|
+
credential=credential,
|
|
40
|
+
) as client:
|
|
41
|
+
result = await client.get_embeddings(["Hello, world!"])
|
|
42
|
+
print(result[0].dimensions)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Set `FOUNDRY_PROJECT_ENDPOINT` to the project endpoint and `FOUNDRY_EMBEDDING_MODEL` to the embedding deployment
|
|
46
|
+
name. When an `AIProjectClient` is already available, pass it as `project_client` and omit the endpoint and
|
|
47
|
+
credential.
|
|
48
|
+
|
|
49
|
+
The client uses the project for authentication and converts a
|
|
50
|
+
`https://<resource>.services.ai.azure.com/api/projects/<project>` endpoint to the documented resource-scoped
|
|
51
|
+
`https://<resource>.openai.azure.com/openai/v1/` model route. The existing `FOUNDRY_MODELS_ENDPOINT` and
|
|
52
|
+
`FOUNDRY_MODELS_API_KEY` configuration remains available for Foundry Models inference endpoints. A Models endpoint is
|
|
53
|
+
required for image embedding models. If both project and Models endpoints are configured only through environment
|
|
54
|
+
variables, the Models endpoint is retained for backward compatibility; pass `project_endpoint` explicitly to select
|
|
55
|
+
the project OpenAI deployment.
|
|
56
|
+
|
|
11
57
|
## Evaluations
|
|
12
58
|
|
|
13
59
|
`FoundryEvals` implements the provider-neutral `Evaluator` protocol with
|
|
@@ -105,10 +151,42 @@ agent = Agent(
|
|
|
105
151
|
)
|
|
106
152
|
```
|
|
107
153
|
|
|
108
|
-
|
|
154
|
+
Non-preview factories: `get_computer_tool`, `get_code_interpreter_tool`,
|
|
109
155
|
`get_file_search_tool`, `get_web_search_tool`,
|
|
110
156
|
`get_image_generation_tool`, `get_mcp_tool`.
|
|
111
157
|
|
|
158
|
+
`get_computer_tool()` returns the Foundry SDK's `ComputerTool` (available in
|
|
159
|
+
`azure-ai-projects>=2.3.0`). The package still supports 2.2.x for other tools:
|
|
160
|
+
only calling this factory on an older SDK raises `ImportError` with upgrade guidance.
|
|
161
|
+
`get_computer_use_tool(...)` remains available for the separate preview API.
|
|
162
|
+
The OpenAI Responses client also exposes `OpenAIChatClient.get_computer_tool()`.
|
|
163
|
+
The new `ComputerSafetyCheck` type and `Content.from_computer_tool_call` /
|
|
164
|
+
`Content.from_computer_tool_result` constructors are experimental Agent Framework APIs,
|
|
165
|
+
even though Foundry's `ComputerTool` is a non-preview SDK model.
|
|
166
|
+
|
|
167
|
+
Computer calls arrive as `Content` with `type="computer_tool_call"`, a
|
|
168
|
+
provider item `id`, a distinct `call_id`, ordered `actions`, and optional
|
|
169
|
+
`pending_safety_checks`. Unanswered calls require application input: inspect
|
|
170
|
+
`AgentResponse.user_input_requests` (or `ChatResponse.messages[*].contents`),
|
|
171
|
+
show the actions and warnings to the user, and execute actions only after
|
|
172
|
+
approval. To continue, return `Content.from_computer_tool_result(call_id=...,
|
|
173
|
+
screenshot=Content.from_data(image_bytes, "image/png"))` in a tool message;
|
|
174
|
+
`Content.from_uri(...)` and `Content.from_hosted_file(...)` also work for
|
|
175
|
+
screenshots. Shared `Content` allows a result without a screenshot for other
|
|
176
|
+
providers, but OpenAI and Foundry Responses require one. If checks were pending,
|
|
177
|
+
explicitly pass *only* those the
|
|
178
|
+
application has confirmed as `acknowledged_safety_checks=[{"id": "..."}]`.
|
|
179
|
+
The framework never acknowledges warnings on your behalf. Calls and results
|
|
180
|
+
can be persisted as `Content.to_dict()` and restored with `Content.from_dict()`.
|
|
181
|
+
A call already paired with a completed screenshot result stays in the transcript
|
|
182
|
+
for audit (`informational_only=True`), but does not appear in
|
|
183
|
+
`AgentResponse.user_input_requests`. When a workflow pauses on a computer call
|
|
184
|
+
alongside locally executable functions, it sends their completed results with
|
|
185
|
+
the screenshot in the original call order after the application responds. If
|
|
186
|
+
any computer request in a workflow batch is cancelled, the remaining requests
|
|
187
|
+
in that agent's batch are cancelled too; the terminal output retains already
|
|
188
|
+
resolved results, and the next turn starts with a fresh agent session.
|
|
189
|
+
|
|
112
190
|
> **Choosing a web grounding tool.** `get_web_search_tool` is the recommended
|
|
113
191
|
> default — it requires no separate Bing resource and works with Azure OpenAI
|
|
114
192
|
> models out of the box. Reach for `get_bing_grounding_tool` (experimental,
|
{agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_agent.py
RENAMED
|
@@ -658,6 +658,14 @@ class RawFoundryAgent(
|
|
|
658
658
|
"""
|
|
659
659
|
|
|
660
660
|
service_session_state_keys: ClassVar[frozenset[str]] = frozenset({FOUNDRY_HOSTED_AGENT_SESSION_ID_KEY})
|
|
661
|
+
"""Session-state keys this agent owns, which untrusted input must never supply.
|
|
662
|
+
|
|
663
|
+
Holds the Foundry hosted-agent session ID. Despite the attribute name, that value is not a conversation or
|
|
664
|
+
an ``AgentSession.service_session_id``: it identifies the hosted agent's *runtime session*, a VM-isolated
|
|
665
|
+
sandbox with a persistent filesystem. Hosts such as AG-UI read this to reject client-supplied values, since
|
|
666
|
+
honouring one would run the server's own credentialed call inside another session's sandbox. Hosts are
|
|
667
|
+
expected to reserve this key independently as well, because a wrapper agent may not forward this attribute.
|
|
668
|
+
"""
|
|
661
669
|
|
|
662
670
|
def __init__(
|
|
663
671
|
self,
|
|
@@ -848,6 +856,8 @@ class RawFoundryAgent(
|
|
|
848
856
|
|
|
849
857
|
This method configures Azure Monitor for telemetry collection using the
|
|
850
858
|
connection string from the Foundry project client (accessed via the internal client).
|
|
859
|
+
Use azure-monitor-opentelemetry>=1.8.10,<2 for HTTPX/HTTPX2
|
|
860
|
+
auto-instrumentation that connects client and service traces.
|
|
851
861
|
|
|
852
862
|
Args:
|
|
853
863
|
enable_sensitive_data: Enable sensitive data logging (prompts, responses).
|
|
@@ -855,7 +865,7 @@ class RawFoundryAgent(
|
|
|
855
865
|
**kwargs: Additional arguments passed to configure_azure_monitor().
|
|
856
866
|
|
|
857
867
|
Raises:
|
|
858
|
-
ImportError: If azure-monitor-opentelemetry
|
|
868
|
+
ImportError: If azure-monitor-opentelemetry is not installed.
|
|
859
869
|
"""
|
|
860
870
|
from agent_framework.observability import (
|
|
861
871
|
OBSERVABILITY_SETTINGS,
|
|
@@ -892,7 +902,7 @@ class RawFoundryAgent(
|
|
|
892
902
|
except ImportError as exc:
|
|
893
903
|
raise ImportError(
|
|
894
904
|
"azure-monitor-opentelemetry is required for Azure Monitor integration. "
|
|
895
|
-
|
|
905
|
+
'Install it with: pip install "azure-monitor-opentelemetry>=1.8.10,<2"'
|
|
896
906
|
) from exc
|
|
897
907
|
|
|
898
908
|
if "resource" not in kwargs:
|
|
@@ -5,10 +5,11 @@ from __future__ import annotations
|
|
|
5
5
|
import logging
|
|
6
6
|
import sys
|
|
7
7
|
from collections.abc import Awaitable, Callable, Mapping, Sequence
|
|
8
|
-
from typing import TYPE_CHECKING, Any, ClassVar, Generic, Literal
|
|
8
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Generic, Literal, cast
|
|
9
9
|
|
|
10
10
|
from agent_framework import (
|
|
11
11
|
ChatMiddlewareLayer,
|
|
12
|
+
ChatResponse,
|
|
12
13
|
ChatResponseUpdate,
|
|
13
14
|
Content,
|
|
14
15
|
FunctionInvocationConfiguration,
|
|
@@ -84,6 +85,16 @@ logger: logging.Logger = logging.getLogger("agent_framework.foundry")
|
|
|
84
85
|
|
|
85
86
|
AzureTokenProvider = Callable[[], str | Awaitable[str]]
|
|
86
87
|
AzureCredentialTypes = TokenCredential | AsyncTokenCredential
|
|
88
|
+
_FOUNDRY_REASONING_REPLAY_ITEM_KEY = "__foundry_reasoning_replay_item__"
|
|
89
|
+
_FOUNDRY_REASONING_REPLAY_FIELDS = frozenset({
|
|
90
|
+
"type",
|
|
91
|
+
"id",
|
|
92
|
+
"response_id",
|
|
93
|
+
"status",
|
|
94
|
+
"summary",
|
|
95
|
+
"content",
|
|
96
|
+
"encrypted_content",
|
|
97
|
+
})
|
|
87
98
|
|
|
88
99
|
|
|
89
100
|
class FoundrySettings(TypedDict, total=False):
|
|
@@ -270,6 +281,73 @@ class RawFoundryChatClient(
|
|
|
270
281
|
run_options.pop("include")
|
|
271
282
|
return run_options
|
|
272
283
|
|
|
284
|
+
@override
|
|
285
|
+
def _prepare_provider_reasoning_item_for_openai(
|
|
286
|
+
self,
|
|
287
|
+
reasoning_id: str,
|
|
288
|
+
contents: Sequence[Content],
|
|
289
|
+
) -> dict[str, Any] | None:
|
|
290
|
+
for content in reversed(contents):
|
|
291
|
+
raw_item = content.additional_properties.get(_FOUNDRY_REASONING_REPLAY_ITEM_KEY)
|
|
292
|
+
if isinstance(raw_item, Mapping):
|
|
293
|
+
payload = self._prepare_foundry_reasoning_replay_item(raw_item)
|
|
294
|
+
if payload is not None and payload["id"] == reasoning_id:
|
|
295
|
+
return payload
|
|
296
|
+
return None
|
|
297
|
+
|
|
298
|
+
@classmethod
|
|
299
|
+
def _prepare_foundry_reasoning_replay_item(cls, item: Any) -> dict[str, Any] | None:
|
|
300
|
+
payload = cls._serialize_provider_payload(item)
|
|
301
|
+
if not isinstance(payload, Mapping):
|
|
302
|
+
return None
|
|
303
|
+
typed_payload = cast("Mapping[str, Any]", payload)
|
|
304
|
+
if typed_payload.get("type") != "reasoning":
|
|
305
|
+
return None
|
|
306
|
+
reasoning_id = typed_payload.get("id")
|
|
307
|
+
if not isinstance(reasoning_id, str) or not reasoning_id:
|
|
308
|
+
return None
|
|
309
|
+
response_id = typed_payload.get("response_id")
|
|
310
|
+
if not isinstance(response_id, str) or not response_id:
|
|
311
|
+
return None
|
|
312
|
+
if not isinstance(typed_payload.get("summary"), list) or not isinstance(typed_payload.get("content"), list):
|
|
313
|
+
return None
|
|
314
|
+
return {key: typed_payload[key] for key in _FOUNDRY_REASONING_REPLAY_FIELDS if key in typed_payload}
|
|
315
|
+
|
|
316
|
+
@classmethod
|
|
317
|
+
def _attach_foundry_reasoning_replay_item(cls, contents: list[Content], item: Any) -> None:
|
|
318
|
+
payload = cls._prepare_foundry_reasoning_replay_item(item)
|
|
319
|
+
if payload is None:
|
|
320
|
+
return
|
|
321
|
+
|
|
322
|
+
reasoning_id = cast(str, payload["id"])
|
|
323
|
+
for content in reversed(contents):
|
|
324
|
+
if content.type == "text_reasoning" and content.id == reasoning_id:
|
|
325
|
+
content.additional_properties[_FOUNDRY_REASONING_REPLAY_ITEM_KEY] = payload
|
|
326
|
+
return
|
|
327
|
+
|
|
328
|
+
contents.append(
|
|
329
|
+
Content.from_text_reasoning(
|
|
330
|
+
id=reasoning_id,
|
|
331
|
+
text="",
|
|
332
|
+
raw_representation=item,
|
|
333
|
+
additional_properties={_FOUNDRY_REASONING_REPLAY_ITEM_KEY: payload},
|
|
334
|
+
)
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
@override
|
|
338
|
+
def _parse_response_from_openai(
|
|
339
|
+
self,
|
|
340
|
+
response: Any,
|
|
341
|
+
options: dict[str, Any],
|
|
342
|
+
) -> ChatResponse:
|
|
343
|
+
chat_response = super()._parse_response_from_openai(response, options)
|
|
344
|
+
if chat_response.messages:
|
|
345
|
+
for item in getattr(response, "output", ()):
|
|
346
|
+
if getattr(item, "type", None) != "reasoning":
|
|
347
|
+
continue
|
|
348
|
+
self._attach_foundry_reasoning_replay_item(chat_response.messages[0].contents, item)
|
|
349
|
+
return chat_response
|
|
350
|
+
|
|
273
351
|
@override
|
|
274
352
|
def _check_model_presence(self, options: dict[str, Any]) -> None:
|
|
275
353
|
if not options.get("model"):
|
|
@@ -297,7 +375,10 @@ class RawFoundryChatClient(
|
|
|
297
375
|
update = try_parse_oauth_consent_event(event, self.model)
|
|
298
376
|
if update is not None:
|
|
299
377
|
return update
|
|
300
|
-
|
|
378
|
+
update = super()._parse_chunk_from_openai(event, options, function_call_ids, seen_reasoning_delta_item_ids)
|
|
379
|
+
if event.type == "response.output_item.done" and getattr(event.item, "type", None) == "reasoning":
|
|
380
|
+
self._attach_foundry_reasoning_replay_item(update.contents, event.item)
|
|
381
|
+
return update
|
|
301
382
|
|
|
302
383
|
async def configure_azure_monitor(
|
|
303
384
|
self,
|
|
@@ -308,6 +389,8 @@ class RawFoundryChatClient(
|
|
|
308
389
|
|
|
309
390
|
This method configures Azure Monitor for telemetry collection using the
|
|
310
391
|
connection string from the Foundry project client.
|
|
392
|
+
Use azure-monitor-opentelemetry>=1.8.10,<2 for HTTPX/HTTPX2
|
|
393
|
+
auto-instrumentation that connects client and service traces.
|
|
311
394
|
|
|
312
395
|
Args:
|
|
313
396
|
enable_sensitive_data: Enable sensitive data logging (prompts, responses).
|
|
@@ -319,7 +402,7 @@ class RawFoundryChatClient(
|
|
|
319
402
|
- resource (Resource): Custom OpenTelemetry resource
|
|
320
403
|
|
|
321
404
|
Raises:
|
|
322
|
-
ImportError: If azure-monitor-opentelemetry
|
|
405
|
+
ImportError: If azure-monitor-opentelemetry is not installed.
|
|
323
406
|
"""
|
|
324
407
|
from agent_framework.observability import (
|
|
325
408
|
OBSERVABILITY_SETTINGS,
|
|
@@ -352,7 +435,7 @@ class RawFoundryChatClient(
|
|
|
352
435
|
except ImportError as exc:
|
|
353
436
|
raise ImportError(
|
|
354
437
|
"azure-monitor-opentelemetry is required for Azure Monitor integration. "
|
|
355
|
-
|
|
438
|
+
'Install it with: pip install "azure-monitor-opentelemetry>=1.8.10,<2"'
|
|
356
439
|
) from exc
|
|
357
440
|
|
|
358
441
|
if "resource" not in kwargs:
|
|
@@ -672,6 +755,7 @@ class RawFoundryChatClient(
|
|
|
672
755
|
description: A description of what the MCP server provides.
|
|
673
756
|
approval_mode: Tool approval mode ("always_require", "never_require", or dict).
|
|
674
757
|
allowed_tools: List of allowed tool names from this MCP server.
|
|
758
|
+
None omits the filter; an empty list is sent unchanged.
|
|
675
759
|
headers: HTTP headers to include in requests to the MCP server.
|
|
676
760
|
project_connection_id: Foundry connection ID for managed MCP connections.
|
|
677
761
|
**kwargs: Additional arguments passed to the SDK MCPTool constructor.
|
|
@@ -697,7 +781,7 @@ class RawFoundryChatClient(
|
|
|
697
781
|
mcp["project_connection_id"] = project_connection_id
|
|
698
782
|
elif headers:
|
|
699
783
|
mcp["headers"] = headers
|
|
700
|
-
if allowed_tools:
|
|
784
|
+
if allowed_tools is not None:
|
|
701
785
|
mcp["allowed_tools"] = allowed_tools
|
|
702
786
|
if approval_mode:
|
|
703
787
|
if isinstance(approval_mode, str):
|
|
@@ -840,6 +924,23 @@ class RawFoundryChatClient(
|
|
|
840
924
|
params["update_delay"] = update_delay
|
|
841
925
|
return MemorySearchPreviewTool(**params)
|
|
842
926
|
|
|
927
|
+
@staticmethod
|
|
928
|
+
def get_computer_tool() -> Any:
|
|
929
|
+
"""Create a non-preview Foundry computer tool (requires azure-ai-projects >= 2.3.0).
|
|
930
|
+
|
|
931
|
+
Older supported SDK releases can still import this client; calling this
|
|
932
|
+
factory on those releases raises ``ImportError`` with upgrade guidance.
|
|
933
|
+
"""
|
|
934
|
+
try:
|
|
935
|
+
from azure.ai.projects.models import ComputerTool
|
|
936
|
+
except ImportError as exc:
|
|
937
|
+
raise ImportError(
|
|
938
|
+
"FoundryChatClient.get_computer_tool() requires ComputerTool from azure-ai-projects>=2.3.0. "
|
|
939
|
+
"Upgrade azure-ai-projects to >=2.3.0 to use this tool."
|
|
940
|
+
) from exc
|
|
941
|
+
|
|
942
|
+
return ComputerTool()
|
|
943
|
+
|
|
843
944
|
@staticmethod
|
|
844
945
|
@experimental(feature_id=ExperimentalFeature.FOUNDRY_PREVIEW_TOOLS)
|
|
845
946
|
def get_computer_use_tool(
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
FOUNDRY_HOSTED_AGENT_SESSION_ID_KEY = "foundry_hosted_agent_session_id"
|
|
4
|
+
"""``AgentSession.state`` key holding the Foundry hosted-agent session ID.
|
|
5
|
+
|
|
6
|
+
This is the hosted agent's runtime session, a VM-isolated sandbox with a persistent filesystem, sent as
|
|
7
|
+
``extra_body["agent_session_id"]``. It is distinct from ``AgentSession.service_session_id``, which continues the
|
|
8
|
+
model-side response or conversation chain. The value is server-owned; see
|
|
9
|
+
``RawFoundryAgent.service_session_state_keys``.
|
|
10
|
+
"""
|