diff --git a/libs/ai-endpoints/langchain_nvidia_ai_endpoints/chat_models.py b/libs/ai-endpoints/langchain_nvidia_ai_endpoints/chat_models.py index 1e13bff..28018dc 100644 --- a/libs/ai-endpoints/langchain_nvidia_ai_endpoints/chat_models.py +++ b/libs/ai-endpoints/langchain_nvidia_ai_endpoints/chat_models.py @@ -29,6 +29,7 @@ ) from langchain_core.exceptions import OutputParserException from langchain_core.language_models import BaseChatModel, LanguageModelInput +from langchain_core.language_models.chat_models import LangSmithParams from langchain_core.messages import ( AIMessage, AIMessageChunk, @@ -342,6 +343,28 @@ def _llm_type(self) -> str: """Return type of NVIDIA AI Foundation Model Interface.""" return "chat-nvidia-ai-playground" + def _get_ls_params( + self, + stop: Optional[List[str]] = None, + **kwargs: Any, + ) -> LangSmithParams: + """Get standard LangSmith parameters for tracing.""" + params = self._get_invocation_params(stop=stop, **kwargs) + return LangSmithParams( + ls_provider="NVIDIA", + # error: Incompatible types (expression has type "Optional[str]", + # TypedDict item "ls_model_name" has type "str") [typeddict-item] + ls_model_name=self.model or "UNKNOWN", + ls_model_type="chat", + ls_temperature=params.get("temperature", self.temperature), + ls_max_tokens=params.get("max_tokens", self.max_tokens), + # mypy error: Extra keys ("ls_top_p", "ls_seed") + # for TypedDict "LangSmithParams" [typeddict-item] + # ls_top_p=params.get("top_p", self.top_p), + # ls_seed=params.get("seed", self.seed), + ls_stop=params.get("stop", self.stop), + ) + def _generate( self, messages: List[BaseMessage], diff --git a/libs/ai-endpoints/poetry.lock b/libs/ai-endpoints/poetry.lock index 9eae9e8..a01a193 100644 --- a/libs/ai-endpoints/poetry.lock +++ b/libs/ai-endpoints/poetry.lock @@ -150,13 +150,13 @@ files = [ [[package]] name = "anyio" -version = "4.4.0" +version = "4.5.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, - {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, + {file = "anyio-4.5.0-py3-none-any.whl", hash = "sha256:fdeb095b7cc5a5563175eedd926ec4ae55413bb4be5770c424af0ba46ccb4a78"}, + {file = "anyio-4.5.0.tar.gz", hash = "sha256:c5a275fe5ca0afd788001f58fca1e69e29ce706d746e317d660e21f70c530ef9"}, ] [package.dependencies] @@ -166,9 +166,9 @@ sniffio = ">=1.1" typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] +doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +trio = ["trio (>=0.26.1)"] [[package]] name = "async-timeout" @@ -598,18 +598,40 @@ typing-extensions = ">=4.7" type = "git" url = "https://github.com/langchain-ai/langchain.git" reference = "HEAD" -resolved_reference = "84b831356c5e67ca2defdeb4c839d189a7c51a41" +resolved_reference = "eef18dec442eabb2c2532bd67cc2efa12a43d406" subdirectory = "libs/core" +[[package]] +name = "langchain-standard-tests" +version = "0.1.1" +description = "Standard tests for LangChain implementations" +optional = false +python-versions = ">=3.9,<4.0" +files = [] +develop = false + +[package.dependencies] +httpx = "^0.27.0" +langchain-core = "^0.3.0" +pytest = ">=7,<9" +syrupy = "^4" + +[package.source] +type = "git" +url = "https://github.com/langchain-ai/langchain.git" +reference = "HEAD" +resolved_reference = "eef18dec442eabb2c2532bd67cc2efa12a43d406" +subdirectory = "libs/standard-tests" + [[package]] name = "langsmith" -version = "0.1.122" +version = "0.1.123" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.122-py3-none-any.whl", hash = "sha256:9c9cde442d7321e8557f5c45c14b1b643b8aa28acc3f844d3a0021a9571aad7c"}, - {file = "langsmith-0.1.122.tar.gz", hash = "sha256:56dff727ca529fe8df300e6e4759dc920efe10ab8cd602b4d6b51e33599214e6"}, + {file = "langsmith-0.1.123-py3-none-any.whl", hash = "sha256:ee30c96e69038af92487c6229870b9ccc1fba43eb1b84fb4132a013af7212c6e"}, + {file = "langsmith-0.1.123.tar.gz", hash = "sha256:5d4ad7bb57351f0fc492debf2d7d0b96f2eed41b5545cd36f3043c5f4d42aa6b"}, ] [package.dependencies] @@ -1576,4 +1598,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = ">=3.9,<4.0" -content-hash = "fd55cec7f60515783c4b8f1cfcb696c8cd241979ac2f50323ba568a7ae2de039" +content-hash = "7a08e2786a8b70e328e92fbf014c8910fb64c0c55476c0dd050d61ffa636a4e5" diff --git a/libs/ai-endpoints/pyproject.toml b/libs/ai-endpoints/pyproject.toml index 73d0d0e..94e0bef 100644 --- a/libs/ai-endpoints/pyproject.toml +++ b/libs/ai-endpoints/pyproject.toml @@ -28,6 +28,7 @@ pytest-watcher = "^0.3.4" pytest-asyncio = "^0.21.1" langchain-core = { git = "https://github.com/langchain-ai/langchain.git", subdirectory = "libs/core" } requests-mock = "^1.11.0" +langchain-standard-tests = { git = "https://github.com/langchain-ai/langchain.git", subdirectory = "libs/standard-tests" } faker = "^24.4.0" [tool.poetry.group.codespell] diff --git a/libs/ai-endpoints/tests/integration_tests/test_standard.py b/libs/ai-endpoints/tests/integration_tests/test_standard.py new file mode 100644 index 0000000..983124c --- /dev/null +++ b/libs/ai-endpoints/tests/integration_tests/test_standard.py @@ -0,0 +1,23 @@ +"""Standard LangChain interface tests""" + +from typing import Type + +import pytest +from langchain_core.language_models import BaseChatModel +from langchain_standard_tests.integration_tests import ChatModelIntegrationTests + +from langchain_nvidia_ai_endpoints import ChatNVIDIA + + +class TestNVIDIAStandard(ChatModelIntegrationTests): + @property + def chat_model_class(self) -> Type[BaseChatModel]: + return ChatNVIDIA + + @property + def chat_model_params(self) -> dict: + return {"model": "meta/llama-3.1-8b-instruct"} + + @pytest.mark.xfail(reason="anthropic-style list content not supported") + def test_tool_message_histories_list_content(self, model: BaseChatModel) -> None: + return super().test_tool_message_histories_list_content(model) diff --git a/libs/ai-endpoints/tests/unit_tests/test_standard.py b/libs/ai-endpoints/tests/unit_tests/test_standard.py new file mode 100644 index 0000000..a08cae2 --- /dev/null +++ b/libs/ai-endpoints/tests/unit_tests/test_standard.py @@ -0,0 +1,18 @@ +"""Standard LangChain interface tests""" + +from typing import Type + +from langchain_core.language_models import BaseChatModel +from langchain_standard_tests.unit_tests import ChatModelUnitTests + +from langchain_nvidia_ai_endpoints import ChatNVIDIA + + +class TestNVIDIAStandard(ChatModelUnitTests): + @property + def chat_model_class(self) -> Type[BaseChatModel]: + return ChatNVIDIA + + @property + def chat_model_params(self) -> dict: + return {"model": "meta/llama-3.1-8b-instruct"}