Files
agent-framework/python/samples/04-hosting/foundry-hosted-agents
T
Tao Chen 72a6157c6a [BREAKING] Python: Enable instrumentation by default (#5865)
* Enable instrumentation by default

* Update samples

* Optimization when span is not recording

* Address Copilot comments

* Revert uv.lock

* Add warning

* Formatting

* Fix mypy

* Add disable_instrumentation() with sticky user-intent semantics

Add a public disable_instrumentation() entry point so users can explicitly opt
out of Agent Framework telemetry, with a sticky-disable flag that makes the
user's intent "leading" — no framework code path (foundry's
configure_azure_monitor, configure_otel_providers, enable_instrumentation,
enable_sensitive_telemetry, or direct OBSERVABILITY_SETTINGS.enable_*
writes) can re-enable instrumentation until the user explicitly clears the
disable with enable_instrumentation(force=True) /
enable_sensitive_telemetry(force=True).

Also addresses the two remaining unresolved review threads on the PR:
1. test_observability_settings_defaults_instrumentation_true pins the new
   "ENABLE_INSTRUMENTATION defaults to True when env unset" behavior.
2. test_enable_instrumentation_reads_env_sensitive_data restores coverage
   for the post-import load_dotenv() fallback path.

Implementation:
- ObservabilitySettings.enable_instrumentation / enable_sensitive_data become
  properties backed by _enable_*. While _user_disabled is True, the getters
  return False and the setters drop True writes (defense in depth so third-
  party writes can't subvert the disable).
- Public is_user_disabled read-only property lets integrations (e.g. foundry's
  configure_azure_monitor) cheaply check the disable state without poking at
  privates.
- enable_instrumentation() and enable_sensitive_telemetry() short-circuit with
  an info log when disabled; gain a force=True kwarg that clears the disable.
- configure_otel_providers() still creates providers / exporters / views so a
  later force-enable can use them, but logs an info message when called while
  disabled.
- Foundry's FoundryChatClient.configure_azure_monitor and
  FoundryAgent.configure_azure_monitor early-return when the user has
  disabled, so Azure Monitor's global providers aren't installed unnecessarily.

Tests: 11 new tests covering default-on, env re-read at call time, sticky
behavior against each re-enable surface (enable_instrumentation,
enable_sensitive_telemetry, configure_otel_providers, direct attribute
writes), force=True override, re-arming the disable, and the __all__ export.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: document disable_instrumentation() and force=True paths

Add a "Disabling instrumentation" section to the observability sample README
that walks through:

- The distinction between the ENABLE_INSTRUMENTATION env var (initial,
  non-sticky) and disable_instrumentation() (process-wide, sticky).
- Why the sticky semantics matter: framework integrations like
  FoundryChatClient.configure_azure_monitor() can call
  enable_instrumentation() as part of their setup, and the user's opt-out
  needs to win.
- All five surfaces guarded by the sticky disable (property reads, public
  enable functions, configure_otel_providers, direct attribute writes,
  is_user_disabled-aware integrations).
- The force=True escape hatch on both enable_instrumentation() and
  enable_sensitive_telemetry().
- How third-party integrations should consult OBSERVABILITY_SETTINGS.is_user_disabled.
- The limits of the disable (does not tear down existing providers /
  in-flight spans / third-party instrumentation, does not persist across
  processes).

Cross-links the new section from the ENABLE_INSTRUMENTATION row in the env
vars table.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: soften disable_instrumentation() overclaim about telemetry guarantees

Replace 'no telemetry will be emitted no matter what' (which is too strong,
since callers can still pass force=True or mutate private attributes) with
language framing the disable as a user-intent contract that library and
framework code is expected to honor: the framework actively short-circuits
the public enable paths, force=True and private-attribute writes are
acknowledged as out-of-contract escape hatches that integrations should
not use on the user's behalf.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: correct observability Dependencies section

- opentelemetry-sdk is no longer a hard dependency; it is lazily imported by
  create_resource(), create_metric_views(), and configure_otel_providers()
  with a clear ImportError when missing. Day-to-day instrumentation works
  with opentelemetry-api alone provided some other component configures the
  global OpenTelemetry providers (Azure Monitor, an APM agent, application
  bootstrap, etc.).
- opentelemetry-semantic-conventions-ai is no longer used anywhere in the
  source; remove it from the listed dependencies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs: replace stale observability migration guide with current PR's only relevant migration

The old guide documented the move away from setup_observability(otlp_endpoint=...)
which was an earlier-release API change unrelated to this PR and stale enough that
it's more confusing than helpful at this point. Replace it with a short note on the
single migration this PR introduces: callers of
enable_instrumentation(enable_sensitive_data=True) should switch to
enable_sensitive_telemetry(). Cross-link to the Disabling instrumentation section
for the rare 'force on without enabling sensitive data' use case where
enable_instrumentation() still applies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
72a6157c6a · 2026-05-20 11:52:08 +00:00
History
..

Foundry Hosted Agent Samples

This directory contains samples that demonstrate how to use hosted Agent Framework agents with different capabilities and configurations on Foundry using the Foundry Hosting Agent service. Each sample includes a README with instructions on how to set up, run, and interact with the agent.

Samples

Responses API

# Sample Description
1 Basic A minimal agent demonstrating basic request/response interaction and multi-turn conversations using previous_response_id.
2 Tools An agent with local tools (e.g., weather lookup), demonstrating how to register and invoke custom tool functions alongside the LLM.
3 MCP An agent connected to a remote MCP server (GitHub), demonstrating external MCP tool provider integration.
4 Foundry Toolbox An agent using Azure Foundry Toolbox, demonstrating toolbox provisioning and querying available tools at runtime.
5 Workflows An agent with a multi-step orchestrated workflow, demonstrating chaining prompts through an orchestrated flow.
6 Files An agent demonstrating how to work with files in a hosted agent session, including uploading files to a hosted agent session and having the agent read and manipulate those files at runtime.
7 Observability A sample demonstrating how to enable observability for the agent deployed to Foundry.
8 Azure AI Search RAG An agent with Retrieval Augmented Generation (RAG) capabilities backed by Azure AI Search, grounding answers in documents indexed in a pre-provisioned search index.
9 Foundry Skills An agent that uploads SKILL.md files to the Foundry Skills REST API and downloads them at startup, decoupling tone/policy guidelines from agent code.
10 Foundry Memory An agent with persistent semantic memory backed by an Azure AI Foundry Memory Store, using FoundryMemoryProvider to remember user facts across sessions.
11 Monty CodeAct An agent with a Monty-backed CodeAct context provider, exposing a single execute_code tool that runs Python in a pydantic-monty interpreter and invokes typed host tools (compute, fetch_data) from inside the sandbox. Uses the alpha agent-framework-monty package.
12 Using deployed agent A sample demonstrating how to invoke an agent that has already been deployed to Foundry, showing how to interact with a hosted agent in code.

Invocations API

# Sample Description
1 Basic A minimal agent demonstrating session state management via agent_session_id in URL params/response headers.
2 Break Glass An agent demonstrating a "break glass" scenario where customizations of the API behaviors are needed, allowing for more direct control over how requests and responses are handled by the hosting layer.

Running the Agent Host Locally

Using azd

Prerequisites

  1. Azure Developer CLI (azd)

    • Install azd and the AI agent extension: azd ext install azure.ai.agents
    • Authenticated: azd auth login
  2. Azure Subscription

Create a new project

No cloning required. Create a new folder, point azd at the manifest on GitHub.

mkdir hosted-agent-framework-agent && cd hosted-agent-framework-agent

# Initialize from the manifest
azd ai agent init -m https://github.com/microsoft/agent-framework/blob/main/python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/agent.manifest.yaml

Follow the instructions from azd ai agent init to complete the agent initialization. If you don't have an existing Foundry project and a model deployment, azd ai agent init will guide you through creating them.

Provision Azure Resources

This step is only needed if you don't have an existing Foundry project and model deployment.

Run the following command to provision the necessary Azure resources:

azd provision

This will create the following Azure resources:

  • A new resource group named rg-[project_name]-dev. In this guide, [project_name] will be hosted-agent-framework-agent.
  • Within the resource group, among other resources, the most important ones are:
    • A new Foundry instance
    • A new Foundry project, within which a new model deployment will be created
    • An Application Insights instance
    • A container registry, which will be used to store the container images for the hosted agent

Set Environment Variables

export FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="<your-model-deployment-name>"
# And any other environment variables required by the sample

Or in PowerShell:

$env:FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
$env:AZURE_AI_MODEL_DEPLOYMENT_NAME="<your-model-deployment-name>"
# And any other environment variables required by the sample

Note: The environment variables set above are only for the current session. You will need to set them again if you open a new terminal session. if you want to set the environment variables permanently in the azd environment, you can use azd env set <name> <value>.

Running the Agent Host

azd ai agent run

Right now, the agent host should be running on http://localhost:8088

Invoking the Agent

Open another terminal, navigate to the project directory, and run the following command to invoke the agent:

azd ai agent invoke --local "Hello!"

Or you can in another terminal, without navigating to the project directory, run the following command to invoke the agent:

curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hello!"}'

Or in PowerShell:

(Invoke-WebRequest -Uri http://localhost:8088/responses -Method POST -ContentType "application/json" -Body '{"input": "Hello!"}').Content

Using python

Prerequisites

  1. An existing Foundry project
  2. A deployed model in your Foundry project
  3. Azure CLI installed and authenticated
  4. Python 3.10 or later

Running the Agent Host with Python

Clone the repository containing the sample code:

git clone https://github.com/microsoft/agent-framework.git
cd agent-framework/python/samples/04-hosting/foundry-hosted-agents/responses

Environment setup

  1. Navigate to the sample directory you want to explore. Create and activate a virtual environment using uv (recommended):

    uv venv .venv
    
    # Windows (PowerShell)
    .venv\Scripts\Activate.ps1
    
    # Windows (Command Prompt)
    .venv\Scripts\activate.bat
    
    # macOS/Linux
    source .venv/bin/activate
    

    Note: python -m venv .venv also works, but can hang indefinitely on Windows with Microsoft Store Python due to a known ensurepip issue. Use uv venv .venv to avoid this.

  2. Install dependencies:

    uv pip install -r requirements.txt
    
  3. Create a .env file with your Foundry configuration following the env.example file in the sample.

  4. Make sure you are logged in with the Azure CLI:

    az login
    

Running the Agent Host

python main.py

Right now, the agent host should be running on http://localhost:8088

Invoking the Agent

On another terminal, run the following command to invoke the agent:

curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hello!"}'

Or in PowerShell:

(Invoke-WebRequest -Uri http://localhost:8088/responses -Method POST -ContentType "application/json" -Body '{"input": "Hello!"}').Content

Deploying the Agent to Foundry

Once you've tested locally, deploy to Microsoft Foundry.

With an Existing Foundry Project

If you already have a Foundry project and the necessary Azure resources provisioned, you can skip the setup steps and proceed directly to deploying the agent.

After running azd ai agent init -m <agent.manifest.yaml> and following the prompts to configure your agent, you will have a project ready for deployment.

Setting Up a New Foundry Project

Follow the steps in Using azd to set up the project and provision the necessary Azure resources for your Foundry deployment.

Deploying the Agent

Once the project is setup and resources are provisioned, you can deploy the agent to Foundry by running:

azd deploy

The Foundry hosting infrastructure will inject the following environment variables into your agent at runtime:

  • FOUNDRY_PROJECT_ENDPOINT: The endpoint URL for the Foundry project where the agent is deployed.
  • AZURE_AI_MODEL_DEPLOYMENT_NAME: The name of the model deployment in your Foundry project. This is configured during the agent initialization process with azd ai agent init.
  • APPLICATIONINSIGHTS_CONNECTION_STRING: The connection string for Application Insights to enable telemetry for your agent.

This will package your agent and deploy it to the Foundry environment, making it accessible through the Foundry project endpoint. Once it's deployed, you can also access the agent through the Foundry UI.

For the full deployment guide, see the official deployment guide.

Once deployed, learn more about how to manage deployed agents in the official management guide.