Python: [BREAKING] Remove deprecated kwargs compatibility paths#4858
Python: [BREAKING] Remove deprecated kwargs compatibility paths#4858eavanvalkenburg wants to merge 5 commits intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
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
**kwargsfan-out paths in agents, chat clients, middleware, tools, and telemetry layers. - Enforce explicit tool runtime context via
FunctionInvocationContext(reject unexpected runtime kwargs inFunctionTool.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_kwargsinto agent.run(). After this PR removesrun(**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_kwargsinto agent.run(stream=True, ...) will now fail for workflow-provided arbitrary kwargs after removal ofrun(**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,
)
eavanvalkenburg
left a comment
There was a problem hiding this comment.
Automated Code Review
Reviewers: 4 | Confidence: 83%
✗ Correctness
This PR removes deprecated
**kwargspatterns across the agent framework, replacing them with explicitfunction_invocation_kwargsandclient_kwargsparameters. The changes are internally consistent and tests are properly updated. One concrete bug: inChatMiddlewareLayer.get_response(),context_kwargsis copied fromeffective_client_kwargsbeforemiddlewareis popped, so amiddlewarekey inclient_kwargswould leak intocontext.kwargsand eventually downstreamclient_kwargs/_inner_get_response(). The old code popped middleware before constructing context kwargs. Additionally, removing theVAR_KEYWORDcontinuein_discover_injected_parametersintroduces a theoretical edge case where**ctxwithout annotation on a tool with explicitinput_modelcould be misidentified as a context parameter.
✓ Security Reliability
This PR removes deprecated
**kwargspass-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.pysampling callback useschat_client: Anycast to bypass type checking, which silently hides signature mismatches and could cause runtime errors; (2) exception messages in_tools.pyinclude user-controlled parameter names which is a minor info-leak concern but acceptable for developer-facing errors; (3) the_agent_executor.pyintroducescast(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
**kwargsforwarding paths throughout the agent/client/tool stack and replaces them with explicitfunction_invocation_kwargs/client_kwargs/optionsparameters. The intent and scope are correct. There is one concrete regression introduced by the refactoring: inChatMiddlewareLayer.get_response,context_kwargsis now constructed fromeffective_client_kwargsbeforemiddlewareis popped from that dict. In the old code theChatContext.kwargsdict was built after the pop ({**effective_client_kwargs, **kwargs}whereeffective_client_kwargsalready hadmiddlewareremoved). In the new code anymiddlewarekey present inclient_kwargssurvives intocontext_kwargs, then gets forwarded by_middleware_handleras part ofclient_kwargsto the next layer, where downstream code pops and re-applies it — resulting in double middleware application. A secondary concern is the_mcp.pyfix usingchat_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.kwargsis kept as a public field but is now always{}becausekwargs=kwargsis no longer passed at construction; existing middleware that readscontext.kwargsto observe runtime parameters will silently see an empty dict with no deprecation warning.
Automated review by eavanvalkenburg's agents
3917863 to
9752caa
Compare
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>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the stale _get_current_conversation_id override from the Azure AI client after the OpenAI base helper was deleted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
be21d0a to
a6a08df
Compare
Motivation and Context
PR #4581 introduced explicit runtime buckets such as
additional_properties,client_kwargs, andfunction_invocation_kwargs, but it intentionally left deprecatedkwargs-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 toolinvoke(**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.
BaseAgentandBaseChatClient, leavingadditional_propertiesas the explicit metadata bucket.options,client_kwargs, andfunction_invocation_kwargs.**kwargs; tool runtime context must now flow throughFunctionInvocationContext.Contribution Checklist