-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
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:
- Create agents using
OllamaChatClient - Build a workflow using
HandoffBuilderwith those agents - Invoke the workflow — the handoff mechanism injects
allow_multiple_tool_calls=True - The call to
ollama.AsyncClient.chat()fails withTypeError
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 signaturePackage 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_callskwarg 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_responsedirectly, but the kwargs flow through closures (_stream()and_get_response()), making theollama.AsyncClient.chat()monkey-patch more reliable
Metadata
Metadata
Assignees
Labels
Type
Projects
Status