mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-01 07:13:00 +00:00
dont tool search if there is only one tool
This commit is contained in:
@@ -471,19 +471,20 @@ class AnthropicCompletion(BaseLLM):
|
|||||||
if tools and self.supports_tools:
|
if tools and self.supports_tools:
|
||||||
converted_tools = self._convert_tools_for_interference(tools)
|
converted_tools = self._convert_tools_for_interference(tools)
|
||||||
|
|
||||||
# When tool_search is enabled, inject the tool search tool and
|
# When tool_search is enabled and there are 2+ regular tools,
|
||||||
# mark all regular tools with defer_loading=True
|
# inject the search tool and mark regular tools with defer_loading.
|
||||||
if self.tool_search is not None:
|
# With only 1 tool there's nothing to search — skip tool search
|
||||||
converted_tools = self._apply_tool_search(converted_tools)
|
# entirely so the normal forced tool_choice optimisation still works.
|
||||||
|
|
||||||
params["tools"] = converted_tools
|
|
||||||
|
|
||||||
# Count only regular tools (not tool search tools) for tool_choice
|
|
||||||
regular_tools = [
|
regular_tools = [
|
||||||
t
|
t
|
||||||
for t in converted_tools
|
for t in converted_tools
|
||||||
if t.get("type", "") not in TOOL_SEARCH_TOOL_TYPES
|
if t.get("type", "") not in TOOL_SEARCH_TOOL_TYPES
|
||||||
]
|
]
|
||||||
|
if self.tool_search is not None and len(regular_tools) >= 2:
|
||||||
|
converted_tools = self._apply_tool_search(converted_tools)
|
||||||
|
|
||||||
|
params["tools"] = converted_tools
|
||||||
|
|
||||||
if available_functions and len(regular_tools) == 1:
|
if available_functions and len(regular_tools) == 1:
|
||||||
tool_name = regular_tools[0].get("name")
|
tool_name = regular_tools[0].get("name")
|
||||||
if tool_name and tool_name in available_functions:
|
if tool_name and tool_name in available_functions:
|
||||||
|
|||||||
@@ -1189,8 +1189,20 @@ def test_tool_search_regex_config():
|
|||||||
{
|
{
|
||||||
"type": "function",
|
"type": "function",
|
||||||
"function": {
|
"function": {
|
||||||
"name": "test_tool",
|
"name": "tool_a",
|
||||||
"description": "A test tool",
|
"description": "First tool",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {"q": {"type": "string"}},
|
||||||
|
"required": ["q"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "tool_b",
|
||||||
|
"description": "Second tool",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {"q": {"type": "string"}},
|
"properties": {"q": {"type": "string"}},
|
||||||
@@ -1315,8 +1327,9 @@ def test_tool_search_passthrough_preserves_tool_search_type():
|
|||||||
assert "input_schema" in converted[1]
|
assert "input_schema" in converted[1]
|
||||||
|
|
||||||
|
|
||||||
def test_tool_search_tool_choice_excludes_search_tool():
|
def test_tool_search_single_tool_skips_search_and_forces_choice():
|
||||||
"""When tool_search is enabled with a single regular tool, tool_choice should still work."""
|
"""With only 1 tool, tool_search is skipped (nothing to search) and the
|
||||||
|
normal forced tool_choice optimisation still applies."""
|
||||||
llm = LLM(model="anthropic/claude-sonnet-4-5", tool_search=True)
|
llm = LLM(model="anthropic/claude-sonnet-4-5", tool_search=True)
|
||||||
|
|
||||||
crewai_tools = [
|
crewai_tools = [
|
||||||
@@ -1344,10 +1357,18 @@ def test_tool_search_tool_choice_excludes_search_tool():
|
|||||||
available_functions={"test_tool": lambda q: "result"},
|
available_functions={"test_tool": lambda q: "result"},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Should have tool_choice forcing the single regular tool
|
# Single tool — tool_search skipped, tool_choice forced as normal
|
||||||
assert "tool_choice" in params
|
assert "tool_choice" in params
|
||||||
assert params["tool_choice"]["name"] == "test_tool"
|
assert params["tool_choice"]["name"] == "test_tool"
|
||||||
|
|
||||||
|
# No tool search tool should be injected
|
||||||
|
tool_types = [t.get("type", "") for t in params["tools"]]
|
||||||
|
for ts_type in ("tool_search_tool_bm25_20251119", "tool_search_tool_regex_20251119"):
|
||||||
|
assert ts_type not in tool_types
|
||||||
|
|
||||||
|
# No defer_loading on the single tool
|
||||||
|
assert "defer_loading" not in params["tools"][0]
|
||||||
|
|
||||||
|
|
||||||
def test_tool_search_via_llm_class():
|
def test_tool_search_via_llm_class():
|
||||||
"""Verify tool_search param passes through LLM class correctly."""
|
"""Verify tool_search param passes through LLM class correctly."""
|
||||||
|
|||||||
Reference in New Issue
Block a user