Skip to content

Python: [BREAKING] Remove deprecated kwargs compatibility paths#4858

Open
eavanvalkenburg wants to merge 4 commits intomicrosoft:mainfrom
eavanvalkenburg:remove_kwargs
Open

Python: [BREAKING] Remove deprecated kwargs compatibility paths#4858
eavanvalkenburg wants to merge 4 commits intomicrosoft:mainfrom
eavanvalkenburg:remove_kwargs

Conversation

@eavanvalkenburg
Copy link
Member

Motivation and Context

PR #4581 introduced explicit runtime buckets such as additional_properties, client_kwargs, and function_invocation_kwargs, but it intentionally left deprecated kwargs-based compatibility paths in place.

This change removes those deprecated paths before more code depends on them again. It is a breaking change because callers that still rely on legacy constructor kwargs, direct runtime run(**kwargs) / get_response(**kwargs) compatibility, or tool invoke(**kwargs) runtime injection now need to move to the explicit APIs.

Workflow run(..., custom_data=...) behavior remains intentionally unchanged in this branch and is tracked separately in #4850.

Description

This PR removes the remaining deprecated kwargs compatibility shims from the Python core stack.

  • Remove deprecated constructor kwargs merging from BaseAgent and BaseChatClient, leaving additional_properties as the explicit metadata bucket.
  • Remove deprecated runtime kwargs fan-out from agent and chat execution paths so runtime data flows through options, client_kwargs, and function_invocation_kwargs.
  • Remove legacy runtime kwargs injection into tool **kwargs; tool runtime context must now flow through FunctionInvocationContext.
  • Update middleware, telemetry, MCP, and workflow-internal callers to use the explicit signatures.
  • Update focused core tests to match the explicit APIs and delete the legacy kwargs propagation coverage file.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Remove the deprecated kwargs compatibility shims across core agents, clients, tools, middleware, and telemetry.

Keep workflow kwargs behavior intact in this branch and follow up separately in microsoft#4850.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 23, 2026 15:13
@github-actions github-actions bot changed the title [BREAKING] Remove deprecated kwargs compatibility paths Python: [BREAKING] Remove deprecated kwargs compatibility paths Mar 23, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Removes deprecated **kwargs compatibility shims across the Python core agent/chat/tool stack, enforcing explicit runtime buckets (options, client_kwargs, function_invocation_kwargs) and FunctionInvocationContext for tool runtime context.

Changes:

  • Remove legacy constructor/runtime **kwargs fan-out paths in agents, chat clients, middleware, tools, and telemetry layers.
  • Enforce explicit tool runtime context via FunctionInvocationContext (reject unexpected runtime kwargs in FunctionTool.invoke()).
  • Update and simplify tests to reflect the explicit APIs; delete legacy kwargs propagation coverage.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
python/packages/core/tests/core/test_tools.py Updates tool invocation tests to assert runtime kwargs are rejected and ctx-based flow is required.
python/packages/core/tests/core/test_middleware_with_chat.py Updates chat middleware tests to use context.options and explicit options={...} calls.
python/packages/core/tests/core/test_middleware_with_agent.py Updates agent/function middleware tests to use function_invocation_kwargs and options.
python/packages/core/tests/core/test_kwargs_propagation_to_ai_function.py Removes legacy coverage for kwargs propagation into tool **kwargs.
python/packages/core/tests/core/test_function_invocation_logic.py Updates function-invocation tests to pass tools/tool_choice via options and session via client_kwargs.
python/packages/core/tests/core/test_clients.py Changes BaseChatClient constructor test to expect TypeError for direct legacy kwargs.
python/packages/core/tests/core/test_agents.py Changes Agent constructor test to expect TypeError for direct legacy kwargs; updates option plumbing expectations.
python/packages/core/agent_framework/observability.py Updates telemetry layers to accept/forward explicit client_kwargs and function_invocation_kwargs (no **kwargs).
python/packages/core/agent_framework/_workflows/_agent_executor.py Adds typing casts for new run signatures while continuing to pass workflow run kwargs into agent execution.
python/packages/core/agent_framework/_tools.py Removes legacy runtime kwargs injection; enforces ctx-based runtime flow; tightens invoke() kwarg handling.
python/packages/core/agent_framework/_middleware.py Updates middleware layers/signatures for explicit runtime buckets; adds run-level tools plumbing.
python/packages/core/agent_framework/_mcp.py Updates MCP callback to pass model settings via options dict instead of direct kwargs.
python/packages/core/agent_framework/_clients.py Removes legacy constructor kwargs merge; updates get_response signatures to explicit runtime buckets.
python/packages/core/agent_framework/_agents.py Removes run(**kwargs) and constructor kwargs merge; adds explicit additional_properties and middleware plumbing.
Comments suppressed due to low confidence (2)

python/packages/core/agent_framework/_workflows/_agent_executor.py:362

  • AgentExecutor still forwards **run_kwargs into agent.run(). After this PR removes run(**kwargs) compatibility, any workflow-level kwargs stored under WORKFLOW_RUN_KWARGS_KEY (e.g., custom_data / arbitrary values intended for tool context) will now raise TypeError at runtime. Since _prepare_agent_run_args already merges these values into options["additional_function_arguments"], run_kwargs should be filtered down to only explicit agent.run parameters (or cleared) before spreading into run().
        run_kwargs, options = self._prepare_agent_run_args(ctx.get_state(WORKFLOW_RUN_KWARGS_KEY, {}))

        run_agent = cast(Callable[..., Awaitable[AgentResponse[Any]]], self._agent.run)
        response = await run_agent(
            self._cache,
            stream=False,
            session=self._session,
            options=options,
            **run_kwargs,
        )

python/packages/core/agent_framework/_workflows/_agent_executor.py:394

  • Same issue in the streaming path: spreading **run_kwargs into agent.run(stream=True, ...) will now fail for workflow-provided arbitrary kwargs after removal of run(**kwargs) compatibility. Filter/clear run_kwargs (keeping only explicit agent.run parameters) and rely on options["additional_function_arguments"] / function_invocation_kwargs for propagating workflow runtime data.
        run_agent_stream = cast(Callable[..., ResponseStream[AgentResponseUpdate, AgentResponse[Any]]], self._agent.run)
        stream = run_agent_stream(
            self._cache,
            stream=True,
            session=self._session,
            options=options,
            **run_kwargs,
        )

Copy link
Member Author

@eavanvalkenburg eavanvalkenburg left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 83%

✗ Correctness

This PR removes deprecated **kwargs patterns across the agent framework, replacing them with explicit function_invocation_kwargs and client_kwargs parameters. The changes are internally consistent and tests are properly updated. One concrete bug: in ChatMiddlewareLayer.get_response(), context_kwargs is copied from effective_client_kwargs before middleware is popped, so a middleware key in client_kwargs would leak into context.kwargs and eventually downstream client_kwargs / _inner_get_response(). The old code popped middleware before constructing context kwargs. Additionally, removing the VAR_KEYWORD continue in _discover_injected_parameters introduces a theoretical edge case where **ctx without annotation on a tool with explicit input_model could be misidentified as a context parameter.

✓ Security Reliability

This PR removes deprecated **kwargs pass-through patterns across the agent/client/tool APIs, replacing them with explicit named parameters (function_invocation_kwargs, client_kwargs, tool_call_id). This is a positive security change: it eliminates an injection vector where arbitrary keyword arguments could leak into tool invocations, client calls, or middleware contexts. The main concerns are: (1) the _mcp.py sampling callback uses chat_client: Any cast to bypass type checking, which silently hides signature mismatches and could cause runtime errors; (2) exception messages in _tools.py include user-controlled parameter names which is a minor info-leak concern but acceptable for developer-facing errors; (3) the _agent_executor.py introduces cast(Callable[...], self._agent.run) which bypasses type safety unnecessarily. No blocking security issues found.

✓ Test Coverage

This PR removes deprecated **kwargs patterns, replacing them with explicit parameters (function_invocation_kwargs, client_kwargs, tool_call_id). Test updates are mostly consistent with the code changes—deprecation-warning tests are replaced with TypeError-rejection tests, and middleware tests are updated to use the new explicit parameter style. However, the complete deletion of test_kwargs_propagation_to_ai_function.py removes the only end-to-end integration test verifying clean separation of function_invocation_kwargs vs client_kwargs through the full Agent → Client → Tool pipeline. Additionally, the MCP sampling_callback calling-convention change (positional kwargs to options dict) has no test verifying the new argument format, and the new AgentContext.tools attribute has no middleware-level test coverage.

✗ Design Approach

The PR cleanly removes the deprecated **kwargs forwarding paths throughout the agent/client/tool stack and replaces them with explicit function_invocation_kwargs / client_kwargs / options parameters. The intent and scope are correct. There is one concrete regression introduced by the refactoring: in ChatMiddlewareLayer.get_response, context_kwargs is now constructed from effective_client_kwargs before middleware is popped from that dict. In the old code the ChatContext.kwargs dict was built after the pop ({**effective_client_kwargs, **kwargs} where effective_client_kwargs already had middleware removed). In the new code any middleware key present in client_kwargs survives into context_kwargs, then gets forwarded by _middleware_handler as part of client_kwargs to the next layer, where downstream code pops and re-applies it — resulting in double middleware application. A secondary concern is the _mcp.py fix using chat_client: Any = self.client / response: Any = ... to silence a type-checker complaint; cast(SupportsChatGetResponse[Any], self.client) would constrain the escape to the minimum necessary. Finally, AgentContext.kwargs is kept as a public field but is now always {} because kwargs=kwargs is no longer passed at construction; existing middleware that reads context.kwargs to observe runtime parameters will silently see an empty dict with no deprecation warning.


Automated review by eavanvalkenburg's agents

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@markwallace-microsoft markwallace-microsoft added the lab Agent Framework Lab label Mar 23, 2026
@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Mar 23, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/azure-ai/agent_framework_azure_ai
   _agent_provider.py116199%270
   _project_provider.py124595%157, 213, 312, 352, 385
packages/claude/agent_framework_claude
   _agent.py2792889%328–329, 333, 345, 353–355, 357–358, 388–390, 409, 413, 415, 419, 428, 474, 477, 498, 503–504, 571, 658, 684–687
packages/core/agent_framework
   _agents.py3544786%456, 460, 515, 915, 951, 967, 1063–1067, 1121, 1149, 1274, 1290, 1292, 1305, 1311, 1347, 1349, 1358–1363, 1368, 1370, 1376–1377, 1384, 1386–1387, 1395–1396, 1399–1401, 1411–1416, 1420, 1425, 1427
   _clients.py138794%325, 377, 533–536, 645
   _mcp.py5287386%96–97, 107–112, 123, 128, 171, 180, 192–193, 244, 253, 316, 324, 383, 496, 531, 544, 546–549, 568–569, 582–585, 587–588, 592, 649, 684, 686, 690–691, 693–694, 751, 766, 784, 829, 961, 974–979, 1003, 1062–1063, 1069–1071, 1090, 1115–1116, 1120–1124, 1141–1145, 1292
   _middleware.py3661695%61, 64, 69, 798, 814, 816, 818, 951, 954, 981, 983, 1114, 1118, 1300, 1304, 1372
   _tools.py9308590%190–191, 364, 366, 379, 404–406, 414, 432, 446, 453, 460, 477, 479, 486, 494, 533, 577, 581, 613–615, 617, 623, 668–670, 672, 695, 721, 763–765, 769, 791, 903–909, 945, 957, 959, 961, 964–967, 988, 992, 996, 1010–1012, 1353, 1375, 1462–1468, 1597, 1601, 1647, 1796, 1816, 1818, 1874, 1937, 2109–2110, 2130, 2186–2187, 2242, 2315–2316, 2378, 2383, 2390
   observability.py7363095%389–390, 417, 419–421, 424–426, 431–432, 438–439, 445–446, 736, 936–937, 1099, 1340–1341, 1611–1615, 1804, 2002, 2220, 2222
packages/core/agent_framework/_workflows
   _agent_executor.py2061990%109, 133, 174, 200–201, 256–257, 259–260, 296–298, 300, 310–311, 412–413, 478, 497
packages/core/agent_framework/openai
   _chat_client.py3382792%212, 293–294, 298, 423, 506–513, 515–518, 528, 606, 608, 625, 646, 674, 687, 711, 731, 847
packages/foundry_local/agent_framework_foundry_local
   _foundry_local_client.py48589%196, 200–203
TOTAL27281322388% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
5344 20 💤 0 ❌ 0 🔥 1m 25s ⏱️

eavanvalkenburg and others added 2 commits March 23, 2026 16:54
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lab Agent Framework Lab python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants