Skip to main content

Agent Framework Foundry

This package contains the Microsoft Foundry integrations for Microsoft Agent Framework, including Foundry chat clients, preconfigured Foundry agents, Foundry embedding clients, and Foundry memory providers.

Concurrent reuse

A FoundryChatClient instance can be shared by concurrent asynchronous calls on the same event loop. Streaming, non-streaming, and mixed calls are supported. Keep mutable run state isolated by creating a separate Agent and AgentSession for each concurrent run and by passing separate messages and options.

This guarantee does not extend to user-supplied middleware, tools, or callbacks unless those implementations are also safe for concurrent use. Do not share one client across OS threads or event loops, and do not mutate its configuration while calls are active.

Toolboxes

A toolbox is a named, versioned bundle of hosted tool configurations — code interpreter, file search, image generation, MCP, web search, and so on — stored inside a Microsoft Foundry project. Toolboxes let you manage tool configuration once and reuse it across agents.

Authoring a toolbox

Toolboxes can be authored two ways:

  • Foundry portal — create and version toolboxes through the UI without touching code.
  • Programmatically — use the azure-ai-projects SDK to create, update, and version toolboxes from Python.

Toolbox authoring APIs (ToolboxVersionObject, ToolboxObject, project_client.beta.toolboxes.*) require azure-ai-projects>=2.1.0. Earlier versions can only consume toolboxes that already exist.

Using toolboxes with FoundryAgent

For hosted FoundryAgent, the toolbox must already be attached to the agent in the Microsoft Foundry project. Once attached, the agent invokes its toolbox tools transparently — no client-side wiring required — and you interact with the agent the same way you would with any other tool-equipped Foundry agent.

Using toolboxes with FoundryChatClient

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:

from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.foundry import FoundryChatClient

async with Agent(
    client=FoundryChatClient(...),
    instructions="You are a helpful assistant. Use the toolbox tools when useful.",
    tools=MCPStreamableHTTPTool(
        name="my_toolbox",
        description="Tools served by my Foundry toolbox",
        url="https://<your-toolbox-mcp-endpoint>",
    ),
) as agent:
    result = await agent.run("What tools are available?")
    print(result.text)

Hosted tool factories

FoundryChatClient exposes static factory methods that return Foundry SDK tool configurations ready to pass to an Agent's tools=[...] argument. These factories don't require a FoundryChatClient instance — you can call them statically and reuse the same tool configuration across agents.

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient

agent = Agent(
    client=FoundryChatClient(...),
    instructions="...",
    tools=[
        FoundryChatClient.get_web_search_tool(),
        FoundryChatClient.get_code_interpreter_tool(),
    ],
)

Generally available factories: get_code_interpreter_tool, get_file_search_tool, get_web_search_tool, get_image_generation_tool, get_mcp_tool.

Choosing a web grounding tool. get_web_search_tool is the recommended default — it requires no separate Bing resource and works with Azure OpenAI models out of the box. Reach for get_bing_grounding_tool (experimental, see below) when you need finer Bing parameters (count, freshness, market, set_lang), are grounding non-OpenAI Foundry models, or are migrating from Grounding with Bing Search on the classic platform — it requires a Grounding with Bing Search Azure resource that you manage. get_bing_custom_search_tool (also experimental) is for grounding restricted to a curated list of domains via a Bing Custom Search instance. See the web grounding overview for the full comparison.

Experimental — ExperimentalFeature.FOUNDRY_TOOLS. The following factories wrap GA Foundry tool SDK classes but are new wrappers in agent-framework-foundry and may change before the wrappers themselves reach GA. Calls emit an ExperimentalWarning the first time the FOUNDRY_TOOLS feature is exercised in a process (then deduplicated).

Factory Foundry SDK tool
get_azure_ai_search_tool(index_connection_id, index_name, ...) AzureAISearchTool
get_bing_grounding_tool(connection_id, ...) BingGroundingTool

Experimental — ExperimentalFeature.FOUNDRY_PREVIEW_TOOLS. The following factories wrap preview Foundry tool SDK types — the underlying Foundry capability itself is in preview and may change or be removed before reaching GA. Calls emit a separate ExperimentalWarning the first time the FOUNDRY_PREVIEW_TOOLS feature is exercised in a process (then deduplicated). Use FOUNDRY_TOOLS for "wrapper is new" and FOUNDRY_PREVIEW_TOOLS for "underlying Foundry feature is preview".

Factory Foundry SDK tool
get_sharepoint_tool(connection_id) SharepointPreviewTool
get_fabric_tool(connection_id) MicrosoftFabricPreviewTool
get_memory_search_tool(memory_store_name, scope, ...) MemorySearchPreviewTool
get_computer_use_tool(environment, display_width, display_height) ComputerUsePreviewTool
get_browser_automation_tool(connection_id) BrowserAutomationPreviewTool
get_bing_custom_search_tool(connection_id, instance_name, ...) BingCustomSearchPreviewTool
get_a2a_tool(base_url=..., project_connection_id=..., ...) A2APreviewTool

Creating Foundry conversation sessions

FoundryAgent.create_conversation() creates a server-side Foundry project conversation and returns an AgentSession that can be passed to agent.run(...) without reaching into the raw OpenAI client.

from agent_framework.foundry import FOUNDRY_HOSTED_AGENT_SESSION_ID_KEY, FoundryAgent

agent = FoundryAgent(
    project_endpoint=project_endpoint,
    agent_name="travel-agent",
    credential=credential,
)

session = await agent.create_conversation()
response = await agent.run("Help me plan a trip to Seattle.", session=session)

For HostedAgents, start with a normal AgentSession. When no hosted-agent session ID is supplied, the service creates one and the agent stores it in session.state[FOUNDRY_HOSTED_AGENT_SESSION_ID_KEY]. The response conversation ID or response ID remains separate in session.service_session_id and is used as the next request's continuation handle.

Publishing an agent as a Foundry prompt agent

Experimental — ExperimentalFeature.TO_PROMPT_AGENT. to_prompt_agent is a preview API and may change before reaching GA. The warning fires the first time the TO_PROMPT_AGENT feature is exercised in a process and is then deduplicated.

to_prompt_agent(agent) converts an Agent whose chat client is a FoundryChatClient into a Foundry PromptAgentDefinition that can be published with AIProjectClient.agents.create_version(...). The model is read from default_options["model"] first and falls back to the bound FoundryChatClient.model (matching Agent.__init__'s resolution order), so the same agent definition you run locally can be published as a hosted prompt agent without restating the model deployment name.

Every generation parameter that has an Agent Framework equivalent is sourced from agent.default_options and translated into the matching Foundry shape by _prepare_prompt_agent_options (a module-private helper in agent_framework_foundry._to_prompt_agent that reuses the chat client's own request-path helpers):

default_options key PromptAgentDefinition field
temperature temperature
top_p top_p
tool_choice (dropped when no tools) tool_choice (str / ToolChoiceFunction / ToolChoiceAllowed)
reasoning (dict or Reasoning) reasoning
response_format (dict or BaseModel) text.format
verbosity text.verbosity
text merged into text

This keeps the Agent as the single source of truth for everything it can already express. Only Foundry-specific fields with no Agent Framework equivalent are accepted as keyword arguments on to_prompt_agent:

  • structured_inputs — dict[str, StructuredInputDefinition]
  • rai_config — RaiConfig
import asyncio
import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, to_prompt_agent
from azure.ai.projects.aio import AIProjectClient
from azure.identity.aio import AzureCliCredential


async def main() -> None:
    credential = AzureCliCredential()
    project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]

    agent = Agent(
        client=FoundryChatClient(
            project_endpoint=project_endpoint,
            model="gpt-4o",
            credential=credential,
        ),
        name="travel-agent",
        description="Helps Contoso employees book travel.",
        instructions="You are a helpful travel assistant.",
        tools=[
            FoundryChatClient.get_web_search_tool(),
            FoundryChatClient.get_code_interpreter_tool(),
        ],
        # Generation parameters set on the Agent flow through automatically.
        default_options={
            "temperature": 0.3,
            "top_p": 0.95,
            "reasoning": {"effort": "medium"},
        },
    )

    definition = to_prompt_agent(agent)

    project_client = AIProjectClient(endpoint=project_endpoint, credential=credential)
    created = await project_client.agents.create_version(
        agent_name=agent.name,
        definition=definition,
        description=agent.description,
    )
    print(f"Published {created.name} v{created.version}")


asyncio.run(main())

Behaviour:

  • agent.client must be a FoundryChatClient (or subclass) — otherwise the converter raises TypeError.

  • The bound client must have a model set — otherwise the converter raises ValueError.

  • Foundry SDK tool instances returned by FoundryChatClient.get_*_tool() are passed through unchanged.

  • AF FunctionTool instances (and @tool-decorated callables) are emitted as Foundry FunctionTool declarations — the prompt agent receives the schema only, not the Python implementation. To execute the function when invoking the deployed prompt agent, connect with FoundryAgent and pass the same callable via tools=:

    from agent_framework.foundry import FoundryAgent
    
    deployed = FoundryAgent(
        project_endpoint=project_endpoint,
        agent_name="travel-agent",
        credential=credential,
        tools=[book_hotel],  # same @tool-decorated callable used at publish time
    )
    result = await deployed.run("Book me a hotel in Seattle for 3 nights.")
    

    FoundryAgent runs the function locally when the prompt agent calls it, so the declaration on the server and the implementation on the client stay in sync via the shared @tool definition.

  • Local Agent Framework MCP tools cannot be published as prompt-agent tools — the converter raises ValueError and points at FoundryChatClient.get_mcp_tool(...) for hosted MCP servers.

See the runnable example under samples/02-agents/providers/foundry/:

  • foundry_prompt_agents.py — publish with to_prompt_agent, then connect back with FoundryAgent and execute the same local @tool callable that the deployed prompt agent invokes by name.

Release files for agent-framework-foundry 1.12.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-framework-foundry 1.12.0
File Size Uploaded
agent_framework_foundry-1.12.0.tar.gz 51.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-framework-foundry 1.12.0
File Interpreter ABI Platform
agent_framework_foundry-1.12.0-py3-none-any.whl Python 3 none any Details

Total release size: 105.0 kB

Release files / agent_framework_foundry-1.12.0.tar.gz

Download URL agent_framework_foundry-1.12.0.tar.gz
Size 51.2 kB
Tags Source
SHA-256 checksum
How to use checksums
6361fb0ead699ddc907c95c4ecac7176d688f14a3d60f00e8dfdf06904336356
BLAKE2b-256 checksum
How to use checksums
14a12a1a8b7d50d0ab6de9c7170b1f90a9d91f664a40f833913b2d2164dba91e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / agent_framework_foundry-1.12.0-py3-none-any.whl

Download URL agent_framework_foundry-1.12.0-py3-none-any.whl
Size 53.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f48362cd01962a526ec8f88f67608fbac13d1c728400c6c6ec8a5bc9b1f42c94
BLAKE2b-256 checksum
How to use checksums
bc6bb066715e5ccc2d906920b1859160c54703aacc213f2f01c5e8e121d8555a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page