mirror of
https://github.com/hwchase17/langchain.git
synced 2026-04-03 19:04:23 +00:00
committed by
GitHub
parent
4d9842da67
commit
fe2f105ce7
@@ -1652,7 +1652,7 @@ class ChatAnthropic(BaseChatModel):
|
||||
# _get_llm_for_structured_output_when_thinking_is_enabled.
|
||||
if (
|
||||
self.thinking is not None
|
||||
and self.thinking.get("type") == "enabled"
|
||||
and self.thinking.get("type") in ("enabled", "adaptive")
|
||||
and "tool_choice" in kwargs
|
||||
and kwargs["tool_choice"].get("type") in ("any", "tool")
|
||||
):
|
||||
@@ -1781,7 +1781,10 @@ class ChatAnthropic(BaseChatModel):
|
||||
# The result of convert_to_anthropic_tool for 'method=function_calling' will
|
||||
# always be an AnthropicTool
|
||||
tool_name = formatted_tool["name"]
|
||||
if self.thinking is not None and self.thinking.get("type") == "enabled":
|
||||
if self.thinking is not None and self.thinking.get("type") in (
|
||||
"enabled",
|
||||
"adaptive",
|
||||
):
|
||||
llm = self._get_llm_for_structured_output_when_thinking_is_enabled(
|
||||
schema,
|
||||
formatted_tool,
|
||||
@@ -1993,7 +1996,7 @@ def _tools_in_params(params: dict) -> bool:
|
||||
|
||||
|
||||
def _thinking_in_params(params: dict) -> bool:
|
||||
return params.get("thinking", {}).get("type") == "enabled"
|
||||
return params.get("thinking", {}).get("type") in ("enabled", "adaptive")
|
||||
|
||||
|
||||
def _documents_in_params(params: dict) -> bool:
|
||||
|
||||
@@ -29,6 +29,7 @@ from langchain_anthropic.chat_models import (
|
||||
_format_messages,
|
||||
_is_builtin_tool,
|
||||
_merge_messages,
|
||||
_thinking_in_params,
|
||||
convert_to_anthropic_tool,
|
||||
)
|
||||
|
||||
@@ -2675,6 +2676,57 @@ def test_bind_tools_drops_forced_tool_choice_when_thinking_enabled() -> None:
|
||||
assert len(w) == 1
|
||||
|
||||
|
||||
def test_bind_tools_drops_forced_tool_choice_when_adaptive_thinking() -> None:
|
||||
"""Adaptive thinking has the same forced tool_choice restriction as enabled."""
|
||||
chat_model = ChatAnthropic(
|
||||
model=MODEL_NAME,
|
||||
anthropic_api_key="secret-api-key",
|
||||
thinking={"type": "adaptive"},
|
||||
)
|
||||
|
||||
# tool_choice="any" should be dropped with warning
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
result = chat_model.bind_tools([GetWeather], tool_choice="any")
|
||||
assert "tool_choice" not in cast("RunnableBinding", result).kwargs
|
||||
assert len(w) == 1
|
||||
assert "thinking is enabled" in str(w[0].message)
|
||||
|
||||
# tool_choice="auto" should NOT be dropped (auto is allowed)
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
result = chat_model.bind_tools([GetWeather], tool_choice="auto")
|
||||
assert cast("RunnableBinding", result).kwargs["tool_choice"] == {"type": "auto"}
|
||||
assert len(w) == 0
|
||||
|
||||
# tool_choice=specific tool name should be dropped with warning
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
result = chat_model.bind_tools([GetWeather], tool_choice="GetWeather")
|
||||
assert "tool_choice" not in cast("RunnableBinding", result).kwargs
|
||||
assert len(w) == 1
|
||||
|
||||
# tool_choice=dict with type "tool" should be dropped with warning
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
result = chat_model.bind_tools(
|
||||
[GetWeather],
|
||||
tool_choice={"type": "tool", "name": "GetWeather"},
|
||||
)
|
||||
assert "tool_choice" not in cast("RunnableBinding", result).kwargs
|
||||
assert len(w) == 1
|
||||
|
||||
# tool_choice=dict with type "any" should also be dropped
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
result = chat_model.bind_tools(
|
||||
[GetWeather],
|
||||
tool_choice={"type": "any"},
|
||||
)
|
||||
assert "tool_choice" not in cast("RunnableBinding", result).kwargs
|
||||
assert len(w) == 1
|
||||
|
||||
|
||||
def test_bind_tools_keeps_forced_tool_choice_when_thinking_disabled() -> None:
|
||||
"""When thinking is not enabled, forced tool_choice should pass through."""
|
||||
chat_model = ChatAnthropic(
|
||||
@@ -2703,3 +2755,12 @@ def test_bind_tools_keeps_forced_tool_choice_when_thinking_disabled() -> None:
|
||||
)
|
||||
result = chat_model_disabled.bind_tools([GetWeather], tool_choice="any")
|
||||
assert cast("RunnableBinding", result).kwargs["tool_choice"] == {"type": "any"}
|
||||
|
||||
|
||||
def test_thinking_in_params_recognizes_adaptive() -> None:
|
||||
"""_thinking_in_params should recognize both enabled and adaptive types."""
|
||||
assert _thinking_in_params({"thinking": {"type": "enabled", "budget_tokens": 5000}})
|
||||
assert _thinking_in_params({"thinking": {"type": "adaptive"}})
|
||||
assert not _thinking_in_params({"thinking": {"type": "disabled"}})
|
||||
assert not _thinking_in_params({"thinking": {}})
|
||||
assert not _thinking_in_params({})
|
||||
|
||||
Reference in New Issue
Block a user