Python: Added internal kwargs filtering for Anthropic client (#3544)

* Added internal kwargs filtering for chat clients

* Small updates

* Reverted changes

* Small fix

* Fixed test
This commit is contained in:
Dmytro Struk
2026-02-05 15:34:26 -08:00
committed by GitHub
Unverified
parent 3dc59c83b5
commit 1f8e70d7ad
3 changed files with 38 additions and 2 deletions
@@ -455,7 +455,13 @@ class AnthropicClient(
# Add the structured outputs beta flag
run_options["betas"].add(STRUCTURED_OUTPUTS_BETA_FLAG)
run_options.update(kwargs)
# Filter out framework kwargs that should not be passed to the Anthropic API.
# This includes underscore-prefixed internal objects (like _function_middleware_pipeline)
# and framework kwargs like 'thread' and 'middleware'.
filtered_kwargs = {
k: v for k, v in kwargs.items() if not k.startswith("_") and k not in {"thread", "middleware"}
}
run_options.update(filtered_kwargs)
return run_options
def _prepare_betas(self, options: Mapping[str, Any]) -> set[str]:
@@ -479,6 +479,36 @@ async def test_prepare_options_with_top_p(mock_anthropic_client: MagicMock) -> N
assert run_options["top_p"] == 0.9
async def test_prepare_options_filters_internal_kwargs(mock_anthropic_client: MagicMock) -> None:
"""Test _prepare_options filters internal framework kwargs.
Internal kwargs like _function_middleware_pipeline, thread, and middleware
should be filtered out before being passed to the Anthropic API.
"""
chat_client = create_test_anthropic_client(mock_anthropic_client)
messages = [ChatMessage(role="user", text="Hello")]
chat_options: ChatOptions = {}
# Simulate internal kwargs that get passed through the middleware pipeline
internal_kwargs = {
"_function_middleware_pipeline": object(),
"_chat_middleware_pipeline": object(),
"_any_underscore_prefixed": object(),
"thread": object(),
"middleware": [object()],
}
run_options = chat_client._prepare_options(messages, chat_options, **internal_kwargs)
# Internal kwargs should be filtered out
assert "_function_middleware_pipeline" not in run_options
assert "_chat_middleware_pipeline" not in run_options
assert "_any_underscore_prefixed" not in run_options
assert "thread" not in run_options
assert "middleware" not in run_options
# Response Processing Tests
@@ -599,7 +599,7 @@ async def test_sub_workflow_checkpoint_restore_no_duplicate_requests() -> None:
# Get checkpoint
checkpoints = await storage.list_checkpoints(workflow1.id)
checkpoint_id = max(checkpoints, key=lambda cp: cp.timestamp).checkpoint_id
checkpoint_id = max(checkpoints, key=lambda cp: cp.iteration_count).checkpoint_id
# Step 2: Resume workflow from checkpoint
workflow2 = _build_checkpoint_test_workflow(storage)