Skip to content

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

@frdeange

Description

@frdeange

Description

When using OllamaChatClient with HandoffBuilder (from agent-framework-orchestrations), the orchestration layer injects additional keyword arguments — notably allow_multiple_tool_calls=True — into _inner_get_response(). These kwargs are passed through unfiltered via **kwargs to ollama.AsyncClient.chat(), which does not accept them, resulting in a TypeError.

What happened?

Running a HandoffBuilder workflow with OllamaChatClient raises:

TypeError: AsyncClient.chat() got an unexpected keyword argument 'allow_multiple_tool_calls'

What did you expect to happen?

OllamaChatClient._inner_get_response() should filter out kwargs that are not supported by ollama.AsyncClient.chat() before forwarding them, or the orchestration layer should not pass provider-specific kwargs to adapters that don't support them.

Steps to reproduce:

  1. Create agents using OllamaChatClient
  2. Build a workflow using HandoffBuilder with those agents
  3. Invoke the workflow — the handoff mechanism injects allow_multiple_tool_calls=True
  4. The call to ollama.AsyncClient.chat() fails with TypeError

Code Sample

Minimal reproduction:

import asyncio
from agent_framework.agents import Agent
from agent_framework_ollama import OllamaChatClient
from agent_framework_orchestrations.handoffs import HandoffBuilder, HandoffAgentUserRequest

async def main():
    client = OllamaChatClient(model_id="qwen2.5:3b")

    coordinator = Agent(
        name="Coordinator",
        instructions="Route incidents to IncidentAgent.",
        client=client,
    )
    incident_agent = Agent(
        name="IncidentAgent",
        instructions="Handle incidents.",
        client=client,
    )

    handoff = (
        HandoffBuilder()
        .with_client(client)
        .participants([coordinator, incident_agent])
        .build()
    )

    # This triggers the bug — HandoffBuilder passes allow_multiple_tool_calls=True
    # through to OllamaChatClient._inner_get_response(), which forwards it to
    # ollama.AsyncClient.chat()
    async for msg in handoff.invoke("Report an incident"):
        print(msg)

asyncio.run(main())

Error Messages / Stack Traces

TypeError: AsyncClient.chat() got an unexpected keyword argument 'allow_multiple_tool_calls'

The root cause is in _chat_client.py, method _inner_get_response(), lines ~360 and ~381:

# Streaming path (line ~360):
response_object = await self.client.chat(
    stream=True,
    **options_dict,
    **kwargs,          # <-- allow_multiple_tool_calls leaks through here
)

# Non-streaming path (line ~378):
response = await self.client.chat(
    stream=False,
    **options_dict,
    **kwargs,          # <-- same issue here
)

The **kwargs from the method signature is forwarded directly to ollama.AsyncClient.chat() without filtering out kwargs that the Ollama Python client doesn't support.

Workaround (Monkey Patch)

We found two functional workarounds. The most reliable one is monkey-patching ollama.AsyncClient.chat() directly to filter kwargs by inspecting its signature:

"""
Monkey-patch for agent_framework_ollama to strip unsupported kwargs.

The MAF Ollama adapter passes **kwargs directly to ollama.AsyncClient.chat(),
but HandoffBuilder injects kwargs like `allow_multiple_tool_calls` that the
Ollama Python client doesn't support, causing a TypeError.

This patch wraps ollama.AsyncClient.chat() itself to strip any kwargs not in
its explicit signature, so no matter how MAF calls it, invalid kwargs are
dropped.

Usage:
    import patch_ollama  # noqa: F401  — must import before using OllamaChatClient
"""

import functools
import inspect
from typing import Any


def _apply_patch() -> None:
    import ollama

    original_chat = ollama.AsyncClient.chat

    if getattr(original_chat, "_patched_for_kwargs", False):
        return  # Already patched

    # Get the valid parameter names from the original signature
    valid_params = set(inspect.signature(original_chat).parameters.keys())
    valid_params.discard("self")

    @functools.wraps(original_chat)
    async def _patched_chat(self, *args, **kwargs):
        filtered = {k: v for k, v in kwargs.items() if k in valid_params}
        dropped = set(kwargs.keys()) - set(filtered.keys())
        if dropped:
            pass  # silently drop unsupported kwargs
        return await original_chat(self, *args, **filtered)

    _patched_chat._patched_for_kwargs = True
    ollama.AsyncClient.chat = _patched_chat

_apply_patch()

Suggested proper fix

A cleaner fix would be inside OllamaChatClient._inner_get_response() itself — pop/discard any kwargs that aren't valid for ollama.AsyncClient.chat() before forwarding them. For example:

# In _inner_get_response, before calling self.client.chat():
kwargs.pop("allow_multiple_tool_calls", None)
# Or more generically, filter kwargs against ollama.AsyncClient.chat()'s signature

Package Versions

  • agent-framework-core: 1.0.0rc2
  • agent-framework: 1.0.0rc2
  • agent-framework-ollama: 1.0.0b260225
  • agent-framework-orchestrations: 1.0.0b260225
  • ollama (Python client): 0.6.1

Python Version

Python 3.13.9

Additional Context

  • Ollama server version: 0.15.6
  • Model tested: qwen2.5:3b
  • The issue affects both streaming and non-streaming code paths in _inner_get_response()
  • The allow_multiple_tool_calls kwarg is injected by the handoff orchestration layer and is meaningful for providers like OpenAI/Azure, but the Ollama adapter does not handle or strip it
  • We also attempted patching _inner_get_response directly, but the kwargs flow through closures (_stream() and _get_response()), making the ollama.AsyncClient.chat() monkey-patch more reliable

Metadata

Metadata

Labels

model clientsIssues related to the model client implementationspythonv1.0Features being tracked for the version 1.0 GA

Type

No type

Projects

Status

Community PR

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions