Skip to content

Python: fix(python): Filter unsupported kwargs in OllamaChatClient._inner_get_response#4404

Closed
LEDazzio01 wants to merge 3 commits intomicrosoft:mainfrom
LEDazzio01:fix/4402-ollama-filter-unsupported-kwargs
Closed

Python: fix(python): Filter unsupported kwargs in OllamaChatClient._inner_get_response#4404
LEDazzio01 wants to merge 3 commits intomicrosoft:mainfrom
LEDazzio01:fix/4402-ollama-filter-unsupported-kwargs

Conversation

@LEDazzio01
Copy link
Contributor

Summary

Fixes #4402

OllamaChatClient._inner_get_response() forwards **kwargs directly to ollama.AsyncClient.chat(). When used with HandoffBuilder, kwargs like allow_multiple_tool_calls=True leak through, causing a TypeError since the Ollama Python client doesn't accept this parameter.

Changes

_chat_client.py

  • Added _UNSUPPORTED_CHAT_KWARGS set containing kwargs that orchestration layers inject but Ollama doesn't support
  • Filter kwargs before passing to self.client.chat() in both streaming and non-streaming paths

test_ollama_chat_client.py

  • Added test_cmc_filters_unsupported_kwargs — verifies allow_multiple_tool_calls is stripped in non-streaming mode
  • Added test_cmc_streaming_filters_unsupported_kwargs — verifies the same for streaming mode

Motivation

When HandoffBuilder is used with OllamaChatClient, it injects allow_multiple_tool_calls=True as a kwarg. OllamaChatOptions already documents this as unsupported (allow_multiple_tool_calls: None), but the kwarg was still forwarded to the Ollama API.

The fix matches the existing pattern in _prepare_options() where tool_choice is excluded via exclude_keys.

…_response

Orchestration layers like HandoffBuilder inject kwargs such as
allow_multiple_tool_calls that ollama.AsyncClient.chat() does not
accept, causing a TypeError.

Filter these kwargs before forwarding to the Ollama API, matching
the behavior documented in OllamaChatOptions where these fields
are explicitly marked as unsupported.

Fixes microsoft#4402
Copilot AI review requested due to automatic review settings March 2, 2026 22:41
@github-actions github-actions bot changed the title fix(python): Filter unsupported kwargs in OllamaChatClient._inner_get_response Python: fix(python): Filter unsupported kwargs in OllamaChatClient._inner_get_response Mar 2, 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

Fixes a compatibility bug in the Python Ollama adapter where orchestration-injected parameters can be forwarded to ollama.AsyncClient.chat() and cause a TypeError.

Changes:

  • Add a small denylist of unsupported chat kwargs and filter them before calling AsyncClient.chat() (streaming and non-streaming).
  • Add regression tests ensuring allow_multiple_tool_calls is stripped when passed as a top-level kwarg.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
python/packages/ollama/agent_framework_ollama/_chat_client.py Introduces _UNSUPPORTED_CHAT_KWARGS and filters **kwargs before delegating to ollama.AsyncClient.chat().
python/packages/ollama/tests/test_ollama_chat_client.py Adds regression tests validating that unsupported kwargs are not forwarded in both streaming and non-streaming paths.

Comment on lines +361 to +365
# Filter out kwargs that are not supported by ollama.AsyncClient.chat().
# Orchestration layers (e.g. HandoffBuilder) may inject kwargs like
# allow_multiple_tool_calls that the Ollama Python client doesn't accept.
filtered_kwargs = {k: v for k, v in kwargs.items() if k not in _UNSUPPORTED_CHAT_KWARGS}

Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

filtered_kwargs prevents unsupported values coming in via **kwargs, but allow_multiple_tool_calls can also arrive via the options mapping (e.g., from Agent.default_options / handoff cloning). Since _prepare_options() currently forwards unknown option keys to ollama.AsyncClient.chat(), this can still raise TypeError even after this change. Consider also stripping allow_multiple_tool_calls (and any other unsupported keys) from options before _prepare_options() runs (e.g., add it to exclude_keys in _prepare_options, or validated_options.pop(...) in _inner_get_response).

Copilot uses AI. Check for mistakes.
Comment on lines +422 to +427
ollama_client = OllamaChatClient()
# Pass allow_multiple_tool_calls as a kwarg — this is what HandoffBuilder does
await ollama_client.get_response(
messages=chat_history,
allow_multiple_tool_calls=True,
)
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

These new tests verify filtering when allow_multiple_tool_calls is passed as a top-level kwarg, but they don’t cover the (common) case where the flag is present inside the options dict (e.g., via Agent.default_options / workflow cloning). Adding a regression assertion for get_response(..., options={"allow_multiple_tool_calls": ...}) (streaming and/or non-streaming) would better ensure the TypeError can’t reappear through the options path.

Copilot uses AI. Check for mistakes.
Address Copilot review feedback: allow_multiple_tool_calls can also
arrive via the options mapping (e.g. Agent.default_options, workflow
cloning), not just via **kwargs.

- Add allow_multiple_tool_calls to exclude_keys in _prepare_options()
- Add test_cmc_filters_unsupported_options regression test
Copy link
Contributor Author

@LEDazzio01 LEDazzio01 left a comment

Choose a reason for hiding this comment

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

Good catches! Pushed a follow-up commit (f9b01dc) addressing both:

  1. Options path — Added allow_multiple_tool_calls to exclude_keys in _prepare_options(), so it's stripped whether it arrives via **kwargs or the options dict (e.g. from Agent.default_options / workflow cloning).

  2. Options-path test — Added test_cmc_filters_unsupported_options which passes allow_multiple_tool_calls inside the options dict and asserts it doesn't reach ollama.AsyncClient.chat().

Both entry points are now covered.

@markwallace-microsoft
Copy link
Member

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
TOTAL22222275787% 
report-only-changed-files is enabled. No files were changed during this commit :)

Python Unit Test Overview

Tests Skipped Failures Errors Time
4720 247 💤 0 ❌ 0 🔥 1m 16s ⏱️

@@ -268,6 +268,13 @@ class OllamaChatOptions(ChatOptions[ResponseModelT], Generic[ResponseModelT], to
}
"""Maps ChatOptions keys to Ollama model option parameter names."""

# Kwargs that may be injected by orchestration layers (e.g. HandoffBuilder)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: We shouldn't mention downstream modules in the comment. We can just say this framework level key is not supported by the ollama client or it's handled separately.

Address TaoChenOSU nit: use generic 'framework-level kwargs' wording
instead of mentioning HandoffBuilder specifically.
Copy link
Contributor Author

@LEDazzio01 LEDazzio01 left a comment

Choose a reason for hiding this comment

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

Good point! Updated the comment in commit 3948f4d to use generic wording ("Framework-level kwargs that are not supported by ollama.AsyncClient.chat()") instead of referencing downstream modules.

# These are silently stripped in _inner_get_response so they never reach the
# Ollama API.
_UNSUPPORTED_CHAT_KWARGS: set[str] = {
"allow_multiple_tool_calls",
Copy link
Member

Choose a reason for hiding this comment

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

this is not a approach we want to take, since that parameter is already set to None in the OllamaChatOptions, people will get notified by their IDE if that is set, if that is being set by something like a workflow then we need to update that. The reason we don't want to hardcode filtering like this is because we want to not block future updates, let's say at some point Ollama does implement support for this parameter, then that will not be usable, because we filter it out, so we decided we would prefer to use the None above to notify the user beforehand that it is likely not right, and then we just let the API tell the user exactly what's wrong.

Copy link
Member

Choose a reason for hiding this comment

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

So reading more of the above, the real issue is that the HandoffBuilder set's parameters that are not universally applicable, which is what we would need to fix.

@moonbox3
Copy link
Contributor

moonbox3 commented Mar 3, 2026

Closing due this being a duplicate of #4403.

@moonbox3 moonbox3 closed this Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: OllamaChatClient passes unsupported kwargs (e.g. allow_multiple_tool_calls) to ollama.AsyncClient.chat(), causing TypeError

6 participants