diff --git a/libs/partners/openrouter/langchain_openrouter/chat_models.py b/libs/partners/openrouter/langchain_openrouter/chat_models.py index 0e591c6a0cb..c9526a3ca4e 100644 --- a/libs/partners/openrouter/langchain_openrouter/chat_models.py +++ b/libs/partners/openrouter/langchain_openrouter/chat_models.py @@ -837,6 +837,7 @@ class ChatOpenRouter(BaseChatModel): *, tool_choice: dict | str | bool | None = None, strict: bool | None = None, + parallel_tool_calls: bool | None = None, **kwargs: Any, ) -> Runnable[LanguageModelInput, AIMessage]: """Bind tool-like objects to this chat model. @@ -852,8 +853,13 @@ class ChatOpenRouter(BaseChatModel): If `None`, the `strict` argument will not be passed to the model. + parallel_tool_calls: Set to `False` to disable parallel tool use. + Defaults to `None` (no specification, which allows parallel + tool use). **kwargs: Any additional parameters. """ + if parallel_tool_calls is not None: + kwargs["parallel_tool_calls"] = parallel_tool_calls formatted_tools = [ convert_to_openai_tool(tool, strict=strict) for tool in tools ] diff --git a/libs/partners/openrouter/tests/unit_tests/test_chat_models.py b/libs/partners/openrouter/tests/unit_tests/test_chat_models.py index 4ba52979164..4d62e042374 100644 --- a/libs/partners/openrouter/tests/unit_tests/test_chat_models.py +++ b/libs/partners/openrouter/tests/unit_tests/test_chat_models.py @@ -1044,6 +1044,20 @@ class TestBindTools: tools = bound.kwargs["tools"] assert "strict" not in tools[0]["function"] + def test_bind_tools_parallel_tool_calls_forwarded(self) -> None: + """Test that parallel_tool_calls is forwarded to the request kwargs.""" + model = _make_model() + bound = model.bind_tools([GetWeather], parallel_tool_calls=False) + assert isinstance(bound, RunnableBinding) + assert bound.kwargs["parallel_tool_calls"] is False + + def test_bind_tools_parallel_tool_calls_none_omits_key(self) -> None: + """Test that parallel_tool_calls=None does not set the key in kwargs.""" + model = _make_model() + bound = model.bind_tools([GetWeather]) + assert isinstance(bound, RunnableBinding) + assert "parallel_tool_calls" not in bound.kwargs + # =========================================================================== # with_structured_output tests