Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion python/packages/bedrock/tests/test_bedrock_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ def test_prepare_options_tool_choice_required_includes_any() -> None:
assert request["toolConfig"]["toolChoice"] == {"any": {}}



def test_prepare_options_tool_choice_auto_without_tools_omits_tool_config() -> None:
"""When tool_choice='auto' but no tools are provided, toolConfig must be omitted.
Expand Down
1 change: 0 additions & 1 deletion python/packages/core/agent_framework/_feature_stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class ExperimentalFeature(str, Enum):
FUNCTIONAL_WORKFLOWS = "FUNCTIONAL_WORKFLOWS"
HARNESS = "HARNESS"
SKILLS = "SKILLS"
TOOLBOXES = "TOOLBOXES"


class ReleaseCandidateFeature(str, Enum):
Expand Down
4 changes: 0 additions & 4 deletions python/packages/core/agent_framework/foundry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
"FoundryEmbeddingOptions": ("agent_framework_foundry", "agent-framework-foundry"),
"FoundryEmbeddingSettings": ("agent_framework_foundry", "agent-framework-foundry"),
"FoundryEvals": ("agent_framework_foundry", "agent-framework-foundry"),
"FoundryHostedToolType": ("agent_framework_foundry", "agent-framework-foundry"),
"FoundryMemoryProvider": ("agent_framework_foundry", "agent-framework-foundry"),
"FoundryLocalChatOptions": ("agent_framework_foundry_local", "agent-framework-foundry-local"),
"FoundryLocalClient": ("agent_framework_foundry_local", "agent-framework-foundry-local"),
Expand All @@ -42,9 +41,6 @@
"RawFoundryEmbeddingClient": ("agent_framework_foundry", "agent-framework-foundry"),
"evaluate_foundry_target": ("agent_framework_foundry", "agent-framework-foundry"),
"evaluate_traces": ("agent_framework_foundry", "agent-framework-foundry"),
"get_toolbox_tool_name": ("agent_framework_foundry", "agent-framework-foundry"),
"get_toolbox_tool_type": ("agent_framework_foundry", "agent-framework-foundry"),
"select_toolbox_tools": ("agent_framework_foundry", "agent-framework-foundry"),
}


Expand Down
8 changes: 0 additions & 8 deletions python/packages/core/agent_framework/foundry/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,13 @@ from agent_framework_foundry import (
FoundryEmbeddingOptions,
FoundryEmbeddingSettings,
FoundryEvals,
FoundryHostedToolType,
FoundryMemoryProvider,
RawFoundryAgent,
RawFoundryAgentChatClient,
RawFoundryChatClient,
RawFoundryEmbeddingClient,
evaluate_foundry_target,
evaluate_traces,
get_toolbox_tool_name,
get_toolbox_tool_type,
select_toolbox_tools,
)
from agent_framework_foundry_local import (
FoundryLocalChatOptions,
Expand All @@ -51,7 +47,6 @@ __all__ = [
"FoundryEmbeddingOptions",
"FoundryEmbeddingSettings",
"FoundryEvals",
"FoundryHostedToolType",
"FoundryLocalChatOptions",
"FoundryLocalClient",
"FoundryLocalSettings",
Expand All @@ -63,7 +58,4 @@ __all__ = [
"RawFoundryEmbeddingClient",
"evaluate_foundry_target",
"evaluate_traces",
"get_toolbox_tool_name",
"get_toolbox_tool_type",
"select_toolbox_tools",
]
27 changes: 1 addition & 26 deletions python/packages/foundry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,7 @@ For hosted `FoundryAgent`, the toolbox must already be attached to the agent in

### Using toolboxes with `FoundryChatClient`

There are two patterns for wiring a toolbox into a `FoundryChatClient`-backed agent.

**1. Fetch, optionally filter, and pass the tools directly**

Load the toolbox from the Microsoft Foundry project, optionally select a subset of its tools, and hand them to an `Agent` alongside any other tools you own:

```python
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, select_toolbox_tools

client = FoundryChatClient(...)
toolbox = await client.get_toolbox("my-toolbox", version="3")

# Pass the whole toolbox:
agent = Agent(client=client, tools=toolbox)

# Or filter to a subset first:
selected = select_toolbox_tools(toolbox, include_types=["code_interpreter", "mcp"])
agent = Agent(client=client, tools=selected)
```

See [`foundry_chat_client_with_toolbox.py`](../../samples/02-agents/providers/foundry/foundry_chat_client_with_toolbox.py) for a full example, including combining multiple toolboxes.

**2. Connect to the toolbox's MCP endpoint with `MCPStreamableHTTPTool`**

Each toolbox is reachable as an MCP server. Instead of fetching and fanning out its individual tool definitions, you can point a MAF `MCPStreamableHTTPTool` at the toolbox's MCP endpoint — the agent then discovers and calls its tools over MCP at runtime:
Each toolbox is reachable as an MCP server. Connect to the toolbox's MCP endpoint with `MCPStreamableHTTPTool` — the agent then discovers and calls its tools over MCP at runtime:

```python
from agent_framework import Agent, MCPStreamableHTTPTool
Expand Down
5 changes: 0 additions & 5 deletions python/packages/foundry/agent_framework_foundry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
evaluate_traces,
)
from ._memory_provider import FoundryMemoryProvider
from ._tools import FoundryHostedToolType, get_toolbox_tool_name, get_toolbox_tool_type, select_toolbox_tools

try:
__version__ = importlib.metadata.version(__name__)
Expand All @@ -32,7 +31,6 @@
"FoundryEmbeddingOptions",
"FoundryEmbeddingSettings",
"FoundryEvals",
"FoundryHostedToolType",
"FoundryMemoryProvider",
"RawFoundryAgent",
"RawFoundryAgentChatClient",
Expand All @@ -41,7 +39,4 @@
"__version__",
"evaluate_foundry_target",
"evaluate_traces",
"get_toolbox_tool_name",
"get_toolbox_tool_type",
"select_toolbox_tools",
]
6 changes: 0 additions & 6 deletions python/packages/foundry/agent_framework_foundry/_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,6 @@ def _prepare_tools_for_openai(
self,
tools: ToolTypes | Callable[..., Any] | Sequence[ToolTypes | Callable[..., Any]] | None,
) -> list[Any]:
"""Prepare tools for Foundry agent Responses API calls.

Mirrors ``RawFoundryChatClient`` sanitization so toolbox-fetched MCP
tools with extra read-model fields continue to work through the agent
surface.
"""
response_tools = super()._prepare_tools_for_openai(tools)
return [_sanitize_foundry_response_tool(tool_item) for tool_item in response_tools]

Expand Down
42 changes: 1 addition & 41 deletions python/packages/foundry/agent_framework_foundry/_chat_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
load_settings,
)
from agent_framework._compaction import CompactionStrategy, TokenizerProtocol
from agent_framework._feature_stage import ExperimentalFeature, experimental
from agent_framework._telemetry import get_user_agent
from agent_framework.observability import ChatTelemetryLayer
from agent_framework_openai._chat_client import OpenAIChatOptions, RawOpenAIChatClient
Expand All @@ -36,7 +35,7 @@

from agent_framework_foundry._oauth_helpers import try_parse_oauth_consent_event

from ._tools import _sanitize_foundry_response_tool, fetch_toolbox # pyright: ignore[reportPrivateUsage]
from ._tools import _sanitize_foundry_response_tool # pyright: ignore[reportPrivateUsage]

if sys.version_info >= (3, 13):
from typing import TypeVar # type: ignore # pragma: no cover
Expand All @@ -53,7 +52,6 @@

if TYPE_CHECKING:
from agent_framework import ChatAndFunctionMiddlewareTypes, ToolTypes
from azure.ai.projects.models import ToolboxVersionObject

logger: logging.Logger = logging.getLogger("agent_framework.foundry")

Expand Down Expand Up @@ -234,13 +232,6 @@ def _prepare_tools_for_openai(
self,
tools: ToolTypes | Callable[..., Any] | Sequence[ToolTypes | Callable[..., Any]] | None,
) -> list[Any]:
"""Prepare tools for Foundry Responses API calls.

Foundry toolbox reads can surface MCP tool objects with extra fields
(for example ``name``) that are accepted by the toolbox API but rejected
by the Responses API. Sanitize those hosted-tool payloads before sending
them downstream.
"""
response_tools = super()._prepare_tools_for_openai(tools)
return [_sanitize_foundry_response_tool(tool_item) for tool_item in response_tools]

Expand Down Expand Up @@ -510,37 +501,6 @@ def get_mcp_tool(

# endregion

# region Toolbox methods (instance methods — these hit the network)

@experimental(feature_id=ExperimentalFeature.TOOLBOXES)
async def get_toolbox(
self,
name: str,
*,
version: str | None = None,
) -> ToolboxVersionObject:
"""Fetch a Foundry toolbox by name.

If ``version`` is omitted, resolves the toolbox's current default version
(two requests). If ``version`` is specified, fetches that version directly
(single request).

Args:
name: The name of the toolbox.

Keyword Args:
version: Optional immutable version identifier to pin to.

Returns:
A ``ToolboxVersionObject``. Pass its ``tools`` attribute to
``Agent(tools=toolbox.tools)``.

Raises:
azure.core.exceptions.ResourceNotFoundError: If the toolbox or
the requested version does not exist.
"""
return await fetch_toolbox(self.project_client, name, version)


class FoundryChatClient( # type: ignore[misc]
FunctionInvocationLayer[FoundryChatOptionsT],
Expand Down
Loading
Loading