Skip to content

ToolCallAdvisor uses hardcoded hasToolCalls() instead of ToolExecutionEligibilityPredicate for tool call detection #5877

@ArpanC6

Description

@ArpanC6

Problem

The ToolCallAdvisor is currently using a hardcoded check to detect tool calls:

isToolCall = chatResponse != null && chatResponse.hasToolCalls();

This approach works fine in some cases but it doesn't consider how certain models (like Anthropic or Bedrock) detect tool calls. For example models like Anthropic also check the "finish reason" (e.g., tool_use) along with tool calls to determine if a tool is being used. Because ToolCallAdvisor ignores this additional check it might miss important tool call detection when working with such models.

Fix

To solve this problem a ToolExecutionEligibilityPredicate has been added to ToolCallAdvisor. This predicate is used in the tool call detection process instead of the hardcoded hasToolCalls() check.

The new approach involves:

  1. Adding the ToolExecutionEligibilityPredicate to the ToolCallAdvisor which defaults to a basic predicate (DefaultToolExecutionEligibilityPredicate).

  2. Using this predicate in both the non streaming method (adviseCall) and the streaming method (handleToolCallRecursion).

  3. Allowing customization: A toolExecutionEligibilityPredicate() method has been added to the Builder class so users can inject their own custom predicates if needed.

Why?

This change ensures that ToolCallAdvisor behaves consistently with how different models (like AnthropicChatModel) detect tool calls. By using a customizable predicate the tool call detection process can now be aligned with the specific behavior of various models making it more accurate and flexible.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions