Skip to content

Python: Handoff workflow + Ollama: allow_multiple_tool_calls passed to AsyncClient.chat() #7054

Description

@danielpcampagna

Description

When using HandoffBuilder with OllamaChatClient, the workflow crashes because the handoff orchestrator injects allow_multiple_tool_calls=False into agent default options, and OllamaChatClient._prepare_options() passes it through to ollama.AsyncClient.chat(), which doesn't accept that keyword.

Error

agent_framework.exceptions.ChatClientException: ("Ollama streaming chat request failed : AsyncClient.chat() got an unexpected keyword argument 'allow_multiple_tool_calls'", TypeError("AsyncClient.chat() got an unexpected keyword argument 'allow_multiple_tool_calls'"))

Root Cause

Two locations contribute to this bug:

1. agent_framework_orchestrations/_handoff.py (orchestrations layer)

HandoffAgentExecutor._clone_chat_agent() unconditionally sets allow_multiple_tool_calls=False at line 286, assuming all clients support this option:

cloned_options["allow_multiple_tool_calls"] = False

2. agent_framework_ollama/_chat_client.py (Ollama connector)

OllamaChatOptions documents this option as "Not supported. Not configurable in Ollama." (lines 216-217), and _prepare_options() skips None values (line 409). However, False is a non-None boolean, so allow_multiple_tool_calls=False passes through to AsyncClient.chat().

The similar unsupported option tool_choice is correctly excluded:

exclude_keys = {"instructions", "tool_choice"}

Suggested Fixes

Fix A (Ollama connector — defense-in-depth)

Add "allow_multiple_tool_calls" to the exclude_keys set in _prepare_options(), the same way tool_choice is excluded. Also consider excluding all keys typed as None in OllamaChatOptions (user, store, logit_bias, metadata).

Fix B (Orchestrations layer — client-aware)

HandoffAgentExecutor._clone_chat_agent() should check whether the underlying client supports allow_multiple_tool_calls before injecting it.

Fix C (Runtime — middleware workaround)

from agent_framework import ChatMiddlewareLayer, ChatMiddlewareContext

class OllamaOptionsFilter(ChatMiddlewareLayer):
    _UNSUPPORTED = frozenset({"allow_multiple_tool_calls"})
    async def send(self, ctx: ChatMiddlewareContext) -> None:
        for key in self._UNSUPPORTED:
            ctx.options.pop(key, None)
        await super().send(ctx)

client = OllamaChatClient(middleware=[OllamaOptionsFilter()])

Environment

  • agent-framework-ollama v1.0.0b260630
  • agent-framework-orchestrations v1.0.0
  • ollama Python client v0.5.3
  • Python 3.12

Metadata

Metadata

Assignees

Labels

orchestrationUsage: [Issues, PRs], Target: multi-agent orchestration (high-level patterns)pythonUsage: [Issues, PRs], Target: PythonreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflow

Type

Fields

No fields configured for Bug.

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions