Skip to content

Python: Clarify Foundry agent tool ownership - #8852

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 3 commits into
mainfrom
i922r502-tool-policy
Oct 6, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 3 commits into
mainfrom
i922r502-tool-policy

Conversation

@rogerbarreto

@rogerbarreto Roger Barreto (rogerbarreto) commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Motivation & Context

FoundryAgent connects to a preconfigured PromptAgent or HostedAgent whose tool declarations and tool-selection behavior are owned by Microsoft Foundry. Per-request tool controls cannot be propagated alongside an agent reference, but this boundary was not explicit when callers supplied local function implementations.

Description & Review Guide

  • What are the major changes? Document that FoundryAgent.tools supplies matching local Python implementations only, warn when caller-supplied tool_choice restrictions or allow_multiple_tool_calls values are ignored, silently omit the framework's unrestricted tool_choice="auto" default, and cover stable and preview agent paths with regression tests.
  • What is the impact of these changes? Callers receive visible guidance instead of silently assuming per-request tool controls affect a preconfigured remote agent. Ordinary runs no longer warn for the framework-generated default. FoundryChatClient remains the supported path when tool selection must vary per request.
  • What do you want reviewers to focus on? The distinction between remote Foundry tool ownership and client-side function implementations, and whether the warning provides sufficient guidance without changing existing runtime behavior.

Related Issue

N/A. This maintenance change is not linked to a public issue.

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.

Some provider protocols cannot represent every tool-selection constraint.
Revalidate fresh calls at the local dispatch boundary while preserving
correlated results, execution budgets, and approval resumes.

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Approval-resume tests remain permissive and do not verify separation from fresh-call policy filtering.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Enforces tool_choice restrictions at Python’s local function-dispatch boundary.

Changes:

  • Rejects disallowed fresh function calls with correlated errors.
  • Excludes rejected calls from execution-budget accounting.
  • Adds streaming, non-streaming, approval-resume tests and specification mapping.
File Description
python/​packages/​core/​agent_framework/​_tools.py Filters fresh calls before dispatch.
python/​packages/​core/​tests/​core/​test_function_invocation_logic.py Adds policy and budget regressions.
docs/​specs/​004-python-function-calling-loop.md Documents tool-selection behavior.

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

Comment thread python/packages/core/tests/core/test_function_invocation_logic.py Outdated
@github-code-quality

github-code-quality Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Python

Python / code-coverage/python

The overall line coverage in commit d405fd2 in the i922r502-tool-policy branch is 92%. Line coverage data for the main branch is not yet available.

Show a line coverage summary of the most covered files.
File main i922r502-tool-policy d405fd2 +/-
packages/core/a...ework/_tools.py — 96% —
packages/core/a...work/_skills.py — 96% —
packages/core/a...ework/_types.py — 95% —
packages/openai..._chat_client.py — 94% —
packages/core/a.../_compaction.py — 94% —
packages/core/a...ork/_vectors.py — 93% —
packages/core/a...amework/_mcp.py — 92% —
packages/ag-ui/...i/_agent_run.py — 90% —
packages/core/a...ork/security.py — 90% —
packages/foundr...g/_responses.py — 88% —

Updated October 06, 2026 10:03 UTC

@github-actions github-actions Bot 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.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): c040c47161d6
Model: gpt-5.6-sol-fast

Overview

The PR adds a shared pre-dispatch filter that blocks fresh model calls excluded by tool_choice, preserves call/result ordering, and excludes synthetic rejections from the execution budget. The new streaming and non-streaming tests cover the immediate mixed-call and budget cases, while existing approval binding keeps recorded approval resumes separate. Two required-mode transitions still discard active restrictions and can allow a later model turn to execute a forbidden registered tool.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (2 high) across 1 file. Details are attached to the affected lines below.

Affected areas: python/packages/core/agent_framework/_tools.py

Comment thread python/packages/core/agent_framework/_tools.py Outdated
Comment thread python/packages/core/agent_framework/_tools.py Outdated
Comment thread python/packages/core/agent_framework/_tools.py Outdated
Preconfigured Foundry agents own tool selection server-side, so per-request tool controls cannot be propagated with an agent reference. Warn when callers provide ignored controls and document the boundary.

Remove the generic core dispatch enforcement because it could not govern server-side tools and changed behavior for every provider.

Copilot-Session: c2489530-5c17-4230-af9a-3b4448b5da1a
@rogerbarreto Roger Barreto (rogerbarreto) changed the title Python: Enforce tool selection before dispatch Python: Clarify Foundry agent tool ownership Oct 5, 2026
@rogerbarreto

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot 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.

MAF Automated Review — Iteration 2

Result: Findings reported
Scope: 1 net-new commit(s): b208f7b795ca
Model: gpt-5.6-sol

Overview

The PR clearly documents that preconfigured Foundry agents own remote tool declarations and selection, strips unsupported controls on both stable and preview paths, and preserves local approval and middleware authorization boundaries. The new warning logic is not aligned with the framework's option lifecycle, however: it reports the framework-generated tool_choice default as caller input while missing the public allow_multiple_tool_calls option entirely. Those two defects make the guidance noisy for ordinary runs and absent for one supported caller-facing control.

Reviewed the supplied incremental change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (2 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: python/packages/foundry/agent_framework_foundry/_agent.py

Comment thread python/packages/foundry/agent_framework_foundry/_agent.py Outdated
Comment thread python/packages/foundry/agent_framework_foundry/_agent.py Outdated
Ignore the framework-generated unrestricted auto default and detect the public allow_multiple_tool_calls option before Foundry translates it for the provider.

Copilot-Session: c2489530-5c17-4230-af9a-3b4448b5da1a
Merged via the queue into main with commit b306dde Oct 6, 2026
50 checks passed
@eavanvalkenburg
Eduard van Valkenburg (eavanvalkenburg) deleted the i922r502-tool-policy branch October 6, 2026 13:14

This branch was previously deployed

1 inactive deployment
github-app-auth — d405fd2e Deployed Oct 6, 2026 by rogerbarreto via add_label #24508
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants