diff --git a/libs/vertexai/langchain_google_vertexai/chat_models.py b/libs/vertexai/langchain_google_vertexai/chat_models.py index 2bad4326..1dc1398b 100644 --- a/libs/vertexai/langchain_google_vertexai/chat_models.py +++ b/libs/vertexai/langchain_google_vertexai/chat_models.py @@ -303,7 +303,11 @@ def _convert_to_parts(message: BaseMessage) -> List[Part]: if system_parts is not None: parts = system_parts + parts system_parts = None - vertex_messages.append(Content(role=role, parts=parts)) + if vertex_messages and vertex_messages[-1].role == "user": + prev_parts = list(vertex_messages[-1].parts) + vertex_messages[-1] = Content(role=role, parts=prev_parts + parts) + else: + vertex_messages.append(Content(role=role, parts=parts)) elif isinstance(message, AIMessage): prev_ai_message = message role = "model" diff --git a/libs/vertexai/tests/integration_tests/test_chat_models.py b/libs/vertexai/tests/integration_tests/test_chat_models.py index 33a43d11..2fffb601 100644 --- a/libs/vertexai/tests/integration_tests/test_chat_models.py +++ b/libs/vertexai/tests/integration_tests/test_chat_models.py @@ -856,3 +856,59 @@ def test_json_serializable() -> None: llm.prediction_client llm.async_prediction_client json.loads(llm.model_dump_json()) + + +@pytest.mark.release +def test_langgraph_example() -> None: + llm = ChatVertexAI( + model_name="gemini-1.5-pro-001", + max_output_tokens=8192, + temperature=0.2, + ) + + add_declaration = { + "name": "add", + "description": "Adds a and b.", + "parameters": { + "properties": { + "a": {"description": "first int", "type": "integer"}, + "b": {"description": "second int", "type": "integer"}, + }, + "required": ["a", "b"], + "type": "object", + }, + } + + multiply_declaration = { + "name": "multiply", + "description": "Multiply a and b.", + "parameters": { + "properties": { + "a": {"description": "first int", "type": "integer"}, + "b": {"description": "second int", "type": "integer"}, + }, + "required": ["a", "b"], + "type": "object", + }, + } + + messages = [ + SystemMessage( + content=( + "You are a helpful assistant tasked with performing " + "arithmetic on a set of inputs." + ) + ), + HumanMessage(content="Multiply 2 and 3"), + HumanMessage(content="No, actually multiply 3 and 3!"), + ] + step1 = llm.invoke( + messages, + tools=[{"function_declarations": [add_declaration, multiply_declaration]}], + ) + step2 = llm.invoke( + messages + + [step1, ToolMessage(content="9", tool_call_id=step1.tool_calls[0]["id"])], # type: ignore[attr-defined] + tools=[{"function_declarations": [add_declaration, multiply_declaration]}], + ) + assert isinstance(step2, AIMessage)