diff --git a/libs/community/langchain_community/chat_models/hunyuan.py b/libs/community/langchain_community/chat_models/hunyuan.py index bcf6a0750a444..c16dc7d114173 100644 --- a/libs/community/langchain_community/chat_models/hunyuan.py +++ b/libs/community/langchain_community/chat_models/hunyuan.py @@ -16,6 +16,7 @@ ChatMessageChunk, HumanMessage, HumanMessageChunk, + SystemMessage, ) from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult from langchain_core.pydantic_v1 import Field, SecretStr, root_validator @@ -33,6 +34,8 @@ def _convert_message_to_dict(message: BaseMessage) -> dict: message_dict: Dict[str, Any] if isinstance(message, ChatMessage): message_dict = {"Role": message.role, "Content": message.content} + elif isinstance(message, SystemMessage): + message_dict = {"Role": "system", "Content": message.content} elif isinstance(message, HumanMessage): message_dict = {"Role": "user", "Content": message.content} elif isinstance(message, AIMessage): @@ -45,7 +48,9 @@ def _convert_message_to_dict(message: BaseMessage) -> dict: def _convert_dict_to_message(_dict: Mapping[str, Any]) -> BaseMessage: role = _dict["Role"] - if role == "user": + if role == "system": + return SystemMessage(content=_dict.get("Content", "") or "") + elif role == "user": return HumanMessage(content=_dict["Content"]) elif role == "assistant": return AIMessage(content=_dict.get("Content", "") or "") @@ -73,6 +78,7 @@ def _create_chat_result(response: Mapping[str, Any]) -> ChatResult: generations = [] for choice in response["Choices"]: message = _convert_dict_to_message(choice["Message"]) + message.id = response.get("Id", "") generations.append(ChatGeneration(message=message)) token_usage = response["Usage"] @@ -115,7 +121,7 @@ def lc_serializable(self) -> bool: model: str = "hunyuan-lite" """What Model to use. Optional model: - - hunyuan-lite、 + - hunyuan-lite - hunyuan-standard - hunyuan-standard-256K - hunyuan-pro @@ -233,6 +239,7 @@ def _stream( chunk = _convert_delta_to_message_chunk( choice["Delta"], default_chunk_class ) + chunk.id = response.get("Id", "") default_chunk_class = chunk.__class__ cg_chunk = ChatGenerationChunk(message=chunk) if run_manager: diff --git a/libs/community/tests/integration_tests/chat_models/test_hunyuan.py b/libs/community/tests/integration_tests/chat_models/test_hunyuan.py index 91e9e184a7a6c..8c3aaaafeeb0c 100644 --- a/libs/community/tests/integration_tests/chat_models/test_hunyuan.py +++ b/libs/community/tests/integration_tests/chat_models/test_hunyuan.py @@ -1,5 +1,15 @@ +import uuid +from operator import itemgetter +from typing import Any + import pytest +from langchain.prompts.chat import ( + ChatPromptTemplate, + HumanMessagePromptTemplate, + SystemMessagePromptTemplate, +) from langchain_core.messages import AIMessage, HumanMessage +from langchain_core.runnables.base import RunnableSerializable from langchain_community.chat_models.hunyuan import ChatHunyuan @@ -11,6 +21,8 @@ def test_chat_hunyuan() -> None: response = chat.invoke([message]) assert isinstance(response, AIMessage) assert isinstance(response.content, str) + assert response.id is not None, "request_id is empty" + assert uuid.UUID(response.id), "Invalid UUID" @pytest.mark.requires("tencentcloud-sdk-python") @@ -20,6 +32,8 @@ def test_chat_hunyuan_with_temperature() -> None: response = chat.invoke([message]) assert isinstance(response, AIMessage) assert isinstance(response.content, str) + assert response.id is not None, "request_id is empty" + assert uuid.UUID(response.id), "Invalid UUID" @pytest.mark.requires("tencentcloud-sdk-python") @@ -29,6 +43,8 @@ def test_chat_hunyuan_with_model_name() -> None: response = chat.invoke([message]) assert isinstance(response, AIMessage) assert isinstance(response.content, str) + assert response.id is not None, "request_id is empty" + assert uuid.UUID(response.id), "Invalid UUID" @pytest.mark.requires("tencentcloud-sdk-python") @@ -38,6 +54,27 @@ def test_chat_hunyuan_with_stream() -> None: response = chat.invoke([message]) assert isinstance(response, AIMessage) assert isinstance(response.content, str) + assert response.id is not None, "request_id is empty" + assert uuid.UUID(response.id), "Invalid UUID" + + +@pytest.mark.requires("tencentcloud-sdk-python") +def test_chat_hunyuan_with_prompt_template() -> None: + system_prompt = SystemMessagePromptTemplate.from_template( + "You are a helpful assistant! Your name is {name}." + ) + user_prompt = HumanMessagePromptTemplate.from_template("Question: {query}") + chat_prompt = ChatPromptTemplate.from_messages([system_prompt, user_prompt]) + chat: RunnableSerializable[Any, Any] = ( + {"query": itemgetter("query"), "name": itemgetter("name")} + | chat_prompt + | ChatHunyuan() + ) + response = chat.invoke({"query": "Hello", "name": "Tom"}) + assert isinstance(response, AIMessage) + assert isinstance(response.content, str) + assert response.id is not None, "request_id is empty" + assert uuid.UUID(response.id), "Invalid UUID" def test_extra_kwargs() -> None: diff --git a/libs/community/tests/unit_tests/chat_models/test_hunyuan.py b/libs/community/tests/unit_tests/chat_models/test_hunyuan.py index e3f13b2d725b8..303631a5cd301 100644 --- a/libs/community/tests/unit_tests/chat_models/test_hunyuan.py +++ b/libs/community/tests/unit_tests/chat_models/test_hunyuan.py @@ -32,9 +32,9 @@ def test__convert_message_to_dict_ai() -> None: def test__convert_message_to_dict_system() -> None: message = SystemMessage(content="foo") - with pytest.raises(TypeError) as e: - _convert_message_to_dict(message) - assert "Got unknown type" in str(e) + result = _convert_message_to_dict(message) + expected_output = {"Role": "system", "Content": "foo"} + assert result == expected_output def test__convert_message_to_dict_function() -> None: @@ -58,10 +58,17 @@ def test__convert_dict_to_message_ai() -> None: assert result == expected_output -def test__convert_dict_to_message_other_role() -> None: +def test__convert_dict_to_message_system() -> None: message_dict = {"Role": "system", "Content": "foo"} result = _convert_dict_to_message(message_dict) - expected_output = ChatMessage(role="system", content="foo") + expected_output = SystemMessage(content="foo") + assert result == expected_output + + +def test__convert_dict_to_message_other_role() -> None: + message_dict = {"Role": "other", "Content": "foo"} + result = _convert_dict_to_message(message_dict) + expected_output = ChatMessage(role="other", content="foo") assert result == expected_output