diff --git a/libs/core/langchain_core/tools.py b/libs/core/langchain_core/tools.py index fcd93025bc7..2fa65902092 100644 --- a/libs/core/langchain_core/tools.py +++ b/libs/core/langchain_core/tools.py @@ -1664,6 +1664,10 @@ def _get_all_basemodel_annotations( if isinstance(cls, type): annotations: Dict[str, Type] = {} for name, param in inspect.signature(cls).parameters.items(): + # Exclude hidden init args added by pydantic Config. For example if + # BaseModel(extra="allow") then "extra_data" will part of init sig. + if (fields := getattr(cls, "__fields__", {})) and name not in fields: + continue annotations[name] = param.annotation orig_bases: Tuple = getattr(cls, "__orig_bases__", tuple()) # cls has subscript: cls = FooBar[int] diff --git a/libs/core/tests/unit_tests/test_tools.py b/libs/core/tests/unit_tests/test_tools.py index a222bc01500..0828066d99a 100644 --- a/libs/core/tests/unit_tests/test_tools.py +++ b/libs/core/tests/unit_tests/test_tools.py @@ -1751,11 +1751,11 @@ def test__get_all_basemodel_annotations_v2(use_v1_namespace: bool) -> None: if use_v1_namespace: - class ModelA(BaseModel, Generic[A]): + class ModelA(BaseModel, Generic[A], extra="allow"): a: A else: - class ModelA(BaseModelProper, Generic[A]): # type: ignore[no-redef] + class ModelA(BaseModelProper, Generic[A], extra="allow"): # type: ignore[no-redef] a: A class ModelB(ModelA[str]): @@ -1812,7 +1812,7 @@ def test__get_all_basemodel_annotations_v2(use_v1_namespace: bool) -> None: def test__get_all_basemodel_annotations_v1() -> None: A = TypeVar("A") - class ModelA(BaseModel, Generic[A]): + class ModelA(BaseModel, Generic[A], extra="allow"): a: A class ModelB(ModelA[str]): diff --git a/libs/standard-tests/langchain_standard_tests/integration_tests/chat_models.py b/libs/standard-tests/langchain_standard_tests/integration_tests/chat_models.py index 5c23376a917..32d7af5f5f7 100644 --- a/libs/standard-tests/langchain_standard_tests/integration_tests/chat_models.py +++ b/libs/standard-tests/langchain_standard_tests/integration_tests/chat_models.py @@ -285,10 +285,7 @@ class ChatModelIntegrationTests(ChatModelTests): assert isinstance(chunk, dict) # for mypy assert set(chunk.keys()) == {"setup", "punchline"} - def test_tool_message_histories_string_content( - self, - model: BaseChatModel, - ) -> None: + def test_tool_message_histories_string_content(self, model: BaseChatModel) -> None: """ Test that message histories are compatible with string tool contents (e.g. OpenAI).