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.
Files changed (18) hide show
  1. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/PKG-INFO +84 -6
  2. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/README.md +80 -2
  3. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_agent.py +12 -2
  4. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_chat_client.py +106 -5
  5. agent_framework_foundry-1.14.0/agent_framework_foundry/_constants.py +10 -0
  6. agent_framework_foundry-1.14.0/agent_framework_foundry/_embedding_client.py +602 -0
  7. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_feature_usage.py +1 -0
  8. agent_framework_foundry-1.14.0/agent_framework_foundry/py.typed +0 -0
  9. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/pyproject.toml +4 -4
  10. agent_framework_foundry-1.13.0/agent_framework_foundry/_constants.py +0 -3
  11. agent_framework_foundry-1.13.0/agent_framework_foundry/_embedding_client.py +0 -407
  12. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/LICENSE +0 -0
  13. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/__init__.py +0 -0
  14. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_foundry_evals.py +0 -0
  15. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_memory_provider.py +0 -0
  16. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_oauth_helpers.py +0 -0
  17. {agent_framework_foundry-1.13.0 → agent_framework_foundry-1.14.0}/agent_framework_foundry/_to_prompt_agent.py +0 -0
  18. {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.13.0
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.17.0,<2
20
- Requires-Dist: agent-framework-openai>=1.14.2,<2
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.7.0
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.7.0`. Projects 2.5 and later require
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
- Generally available factories: `get_code_interpreter_tool`,
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.0`. Projects 2.5 and later require
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
- Generally available factories: `get_code_interpreter_tool`,
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,
@@ -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-exporter is not installed.
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
- "Install it with: pip install azure-monitor-opentelemetry"
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
- return super()._parse_chunk_from_openai(event, options, function_call_ids, seen_reasoning_delta_item_ids)
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-exporter is not installed.
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
- "Install it with: pip install azure-monitor-opentelemetry"
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
+ """