Skip to content

Python: Add Foundry-Features header to toolbox requests - #7696

Open
Willow Lopez (Oxygen56) wants to merge 2 commits into
microsoft:mainfrom
Oxygen56:fix/7689-foundry-features-header
Open

Python: Add Foundry-Features header to toolbox requests#7696
Willow Lopez (Oxygen56) wants to merge 2 commits into
microsoft:mainfrom
Oxygen56:fix/7689-foundry-features-header

Conversation

@Oxygen56

@Oxygen56Willow Lopez (Oxygen56) commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Motivation & Context

Python FoundryToolbox requests currently omit the mandatory Foundry-Features: Toolboxes=V1Preview header and ignore FOUNDRY_AGENT_TOOLSET_FEATURES. This can prevent platform-provided feature flags from reaching the toolbox service and leaves Python behavior inconsistent with .NET.

Description & Review Guide

  • What are the major changes? Build the toolbox features header when authentication is configured, always include the mandatory preview flag, merge platform-provided values, and avoid duplicating the mandatory flag. Add focused coverage for default, blank, merged, and pre-existing mandatory values across asynchronous and synchronous authentication flows.
  • What is the impact of these changes? Every Python FoundryToolbox request now carries the expected feature header without changing the public API.
  • What do you want reviewers to focus on? The feature-value merge behavior and parity with the .NET toolbox handler.

Related Issue

Fixes#7689

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for sending a mandatory Foundry toolbox preview feature flag via a Foundry-Features request header, optionally merged with platform-provided feature flags from an environment variable.

Changes:

  • Add _build_toolbox_features_header() to merge Toolboxes=V1Preview with FOUNDRY_AGENT_TOOLSET_FEATURES.
  • Update _ToolboxAuth to inject the Foundry-Features header on every request.
  • Add async auth-flow tests covering header composition behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

FileDescription
python/packages/foundry_hosting/agent_framework_foundry_hosting/_toolbox.pyBuilds and injects the mandatory preview feature header into toolbox requests.
python/packages/foundry_hosting/tests/test_toolbox.pyAdds parameterized tests validating Foundry-Features header behavior in async auth flow.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +116 to +122
self._features_header = _build_toolbox_features_header(os.environ.get("FOUNDRY_AGENT_TOOLSET_FEATURES"))

def _apply_headers(self, request: httpx.Request, token: AccessToken) -> None:
request.headers["Authorization"] = f"Bearer {token.token}"
for key, value in get_request_context().platform_headers().items():
request.headers[key] = value
request.headers["Foundry-Features"] = self._features_header
def __init__(self, credential: AzureCredentialTypes, scope: str) -> None:
self._credential = credential
self._scope = scope
self._features_header = _build_toolbox_features_header(os.environ.get("FOUNDRY_AGENT_TOOLSET_FEATURES"))
Comment on lines 118 to +122
def _apply_headers(self, request: httpx.Request, token: AccessToken) -> None:
request.headers["Authorization"] = f"Bearer {token.token}"
for key, value in get_request_context().platform_headers().items():
request.headers[key] = value
request.headers["Foundry-Features"] = self._features_header
# Environment variable used to inject platform-provided toolbox feature flags.
_TOOLSET_FEATURES_ENV_VAR = "FOUNDRY_AGENT_TOOLSET_FEATURES"
# Mandatory preview feature flag for Foundry toolbox requests.
_MANDATORY_TOOLBOX_FEATURE = "Toolboxes=V1Preview"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the preview flag is obsolete. Where did you see it's still required?

@github-actions

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/foundry_hosting/agent_framework_foundry_hosting
_toolbox.py121397%374, 378, 382
TOTAL46789435790%

Python Unit Test Overview

TestsSkippedFailuresErrorsTime
945736 💤0 ❌0 🔥2m 32s ⏱️

self._credential = credential
self._scope = scope
# Feature flags are startup configuration, matching the .NET toolbox service.
self._features_header = _build_toolbox_features_header(os.environ.get(_TOOLSET_FEATURES_ENV_VAR))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we capture this value once in FoundryToolbox.__init__ and pass it into each _ToolboxAuth instance? Currently _ToolboxAuth.__init__ reads FOUNDRY_AGENT_TOOLSET_FEATURES, and reconnecting after close() creates a new _ToolboxAuth. Consequently, the same FoundryToolbox instance can silently change feature flags across connections. Holding the merged value on FoundryToolbox would preserve the stated startup-configuration semantics and match the .NET service's lifetime behavior.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pythonUsage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: Python: FoundryToolbox does not send the Foundry-Features header or honor FOUNDRY_AGENT_TOOLSET_FEATURES

4 participants

@Oxygen56@TaoChenOSU@moonbox3