Skip to content

Python: FoundryAgent does not forward default_headers to underlying client — isolation headers not sent to agent endpoint #6027

@monuminu

Description

@monuminu

Bug Report

Description

FoundryAgent (and RawFoundryAgent) do not accept or forward a default_headers parameter to the underlying RawFoundryAgentChatClient / _FoundryAgentChatClient. This means custom HTTP headers (e.g. Foundry isolation headers) set on the AIProjectClient via HeadersPolicy are not propagated to the OpenAI client that makes the actual /responses API call to the agent endpoint.

Related Issue

This is related to #5416 — the isolation key header requirement was introduced with Header-based isolation mode, but FoundryAgent has no way to pass those headers through to the Responses API call for Azure AI Foundry Hosted Agents

Steps to Reproduce

  1. Create a Hosted Agent in Foundry with Header isolation mode enabled (isolation_key_source.kind: "Header")
    1. Create a FoundryAgent with a project_client that has HeadersPolicy(base_headers={"x-ms-user-isolation-key": "..."})
    1. Call agent.run(...) with a session
from agent_framework.foundry import FoundryAgent
from azure.ai.projects.aio import AIProjectClient
from azure.core.pipeline.policies import HeadersPolicy

isolation_headers = {
    "x-ms-user-isolation-key": "my-user-id",
    "x-ms-chat-isolation-key": "my-conversation-id",
}

project_client = AIProjectClient(
    endpoint=FOUNDRY_PROJECT_ENDPOINT,
    credential=credential,
    headers_policy=HeadersPolicy(base_headers=isolation_headers),
)

agent = FoundryAgent(
    project_client=project_client,
    agent_name="my-hosted-agent",
    allow_preview=True,
)

session = agent.get_session(session_id)
result = await agent.run("Hello", session=session)  # 400 Bad Request

Expected Behavior

The isolation headers should be forwarded to the Responses API endpoint.

Actual Behavior

HTTP/1.1 400 Bad Request
{
  "error": {
    "code": "bad_request",
    "message": "Agent endpoint requires user isolation key header 'x-ms-user-isolation-key' but it was not present in the request."
  }
}

Root Cause

In RawFoundryAgent.__init__, the client is created without default_headers:

client_kwargs: dict[str, Any] = {
    "project_endpoint": project_endpoint,
    "agent_name": agent_name,
    "agent_version": agent_version,
    "credential": credential,
    "project_client": project_client,
    "allow_preview": allow_preview,
    "env_file_path": env_file_path,
    "env_file_encoding": env_file_encoding,
}
client = actual_client_type(**client_kwargs)

The underlying RawFoundryAgentChatClient.__init__ does accept default_headers and forwards it to both project_client.get_openai_client(default_headers=...) and the parent RawOpenAIChatClient. But RawFoundryAgent / FoundryAgent never thread it through.

Suggested Fix

Add default_headers as an optional parameter to RawFoundryAgent.__init__ and FoundryAgent.__init__, and include it in client_kwargs:

# In RawFoundryAgent.__init__:
client_kwargs: dict[str, Any] = {
    ...
    "default_headers": default_headers,  # Add this
}

Workaround

Use client_type to create a subclass that injects headers:

from agent_framework_foundry._agent import _FoundryAgentChatClient

def _make_header_injecting_client(headers):
    class _Client(_FoundryAgentChatClient):
        def __init__(self, **kwargs):
            merged = dict(headers)
            if kwargs.get("default_headers"):
                merged.update(kwargs["default_headers"])
            kwargs["default_headers"] = merged
            super().__init__(**kwargs)
    return _Client

agent = FoundryAgent(
    project_client=project_client,
    agent_name="my-hosted-agent",
    allow_preview=True,
    client_type=_make_header_injecting_client(isolation_headers),
)

Environment

  • agent-framework version: 1.6.0
    • agent-framework-foundry version: 1.6.0
      • Python: 3.12
        • OS: macOS

Metadata

Metadata

Labels

agentsIssues related to single agentsbugSomething isn't workingpythonreproduced

Type

No fields configured for Bug.

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions