Skip to content

Python: [Feature]: Publish which arguments an invocation's variable expansion rewrote - #8506

Open
pratik wayase (PratikWayase) wants to merge 1 commit into
microsoft:mainfrom
PratikWayase:feature/expand-args-rewrite
Open

pratik wayase (PratikWayase) wants to merge 1 commit into
microsoft:mainfrom
PratikWayase:feature/expand-args-rewrite

Conversation

@PratikWayase

Copy link
Copy Markdown
Contributor

Motivation & Context

LabelTrackingFunctionMiddleware expands [var_xxx] references into a tool's arguments before the body runs. From 1.18, PolicyEnforcementFunctionMiddleware refuses forwarding that content unless the destination tool opts in (accepts_untrusted=True).

However, a tool that opts in has no supported way to ask which of its arguments the expansion rewrote. The tool body just sees ordinary strings. This creates a security gap: if a tool needs to refuse a bad file name and names it in the error message, it might accidentally echo hidden, untrusted content back into the conversation.

This PR provides a supported, public API for tools to identify exactly which argument positions were produced by the framework, allowing them to render safe indices (e.g., files[0]) instead of quoting the hidden text.

Description & Review Guide

  • What are the major changes?

    • Added a new public function rewritten_arguments(context=None) to agent_framework.security.
    • Introduced a new _current_context ContextVar in security.py to securely propagate the FunctionInvocationContext to rewritten_arguments(), supporting both explicit context passing and implicit asyncio.to_thread usage.
    • Updated LabelTrackingFunctionMiddleware._resolve_value and _resolve_string to track the exact paths of expanded variables.
    • Added logic in _expand_variable_references_in_context to map these paths to a dict[str, set[int]] stored in context.metadata.
  • What is the impact of these changes?

    • Tools can now safely construct error messages without risking hidden content exfiltration.
    • The API contract returns specific indices for lists (e.g., {"files": {0, 2}}) and -1 for scalar or dictionary arguments (e.g., {"text": {-1}}).
    • No existing behavior is broken; this strictly adds new metadata tracking.
  • What do you want reviewers to focus on?

    • The path tracking logic in _resolve_value and how current_path tuples are constructed.
    • The translation logic in _expand_variable_references_in_context that converts path[1] into the integer index for lists, or falls back to -1 for non-lists.
    • The asyncio.to_thread test to ensure the ContextVar correctly copies to worker threads.

Related Issue

Closes #8342

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.

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.

🟡 Changes recommended

Integer-keyed dictionaries are incorrectly reported as list positions rather than non-list arguments.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds a public security API for identifying arguments rewritten by variable expansion.

Changes:

  • Tracks rewritten argument paths in security middleware.
  • Exposes rewrite indices through rewritten_arguments().
  • Adds coverage for lists, scalars, dictionaries, and threaded execution.
File summaries
File Description
python/packages/core/agent_framework/security.py Implements tracking, context propagation, and the public accessor.
python/packages/core/tests/test_security.py Tests rewrite reporting across supported scenarios.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

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

Comment on lines +1634 to +1635
if len(path) > 1 and isinstance(path[1], int):
rewritten_args[arg_name].add(path[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Feature]: Publish which arguments an invocation's variable expansion rewrote

2 participants