From 41ff4c8c437c9f2f9ed351459eb739de02edb110 Mon Sep 17 00:00:00 2001 From: midas8181919 Date: Tue, 13 Feb 2024 15:41:27 +0000 Subject: [PATCH] fix some errors --- README.md | 8 +-- langgraph/prebuilt/chat_agent_executor.py | 14 ++--- tests/test_pregel.py | 63 ++++++++++----------- tests/test_pregel_async.py | 67 ++++++++++++----------- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 96f70c7db..7be0bb11f 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,7 @@ def should_continue(state): messages = state['messages'] last_message = messages[-1] # If there is no function call, then we finish - if "function_call" not in last_message.additional_kwargs: + if "tool_calls" not in last_message.additional_kwargs: return "end" # Otherwise if there is, we continue else: @@ -171,10 +171,10 @@ def call_tool(state): # Based on the continue condition # we know the last message involves a function call last_message = messages[-1] - # We construct an ToolInvocation from the function_call + # We construct an ToolInvocation from the tool_calls action = ToolInvocation( - tool=last_message.additional_kwargs["function_call"]["name"], - tool_input=json.loads(last_message.additional_kwargs["function_call"]["arguments"]), + tool=last_message.additional_kwargs["tool_calls"][0]["function"]["name"], + tool_input=json.loads(last_message.additional_kwargs["tool_calls"][0]["function"]["arguments"]), ) # We call the tool_executor and get back a response response = tool_executor.invoke(action) diff --git a/langgraph/prebuilt/chat_agent_executor.py b/langgraph/prebuilt/chat_agent_executor.py index 83e48a392..c99d56e65 100644 --- a/langgraph/prebuilt/chat_agent_executor.py +++ b/langgraph/prebuilt/chat_agent_executor.py @@ -3,7 +3,7 @@ import operator from typing import Annotated, Sequence, TypedDict from langchain_core.agents import AgentAction -from langchain_core.messages import BaseMessage, FunctionMessage +from langchain_core.messages import BaseMessage, FunctionMessage, ToolMessage from langchain_core.runnables import RunnableLambda from langchain_core.utils.function_calling import convert_to_openai_function, convert_to_openai_tool @@ -139,7 +139,7 @@ def create_tool_calling_executor(model, tools): messages = state["messages"] last_message = messages[-1] # If there is no function call, then we finish - if "tool_call" not in last_message.additional_kwargs: + if "tool_calls" not in last_message.additional_kwargs: return "end" # Otherwise if there is, we continue else: @@ -170,7 +170,7 @@ def create_tool_calling_executor(model, tools): tool_input=json.loads( last_message.additional_kwargs["tool_calls"][0]["function"]["arguments"] ), - log="", + log=last_message.additional_kwargs["tool_calls"][0]["id"], ) def call_tool(state): @@ -178,18 +178,18 @@ def create_tool_calling_executor(model, tools): # We call the tool_executor and get back a response response = tool_executor.invoke(action) # We use the response to create a FunctionMessage - function_message = FunctionMessage(content=str(response), name=action.tool) + tool_message = ToolMessage(content=str(response), tool_call_id=action.log) # We return a list, because this will get added to the existing list - return {"messages": [function_message]} + return {"messages": [tool_message]} async def acall_tool(state): action = _get_action(state) # We call the tool_executor and get back a response response = await tool_executor.ainvoke(action) # We use the response to create a FunctionMessage - function_message = FunctionMessage(content=str(response), name=action.tool) + tool_message = ToolMessage(content=str(response), tool_call_id=action.log) # We return a list, because this will get added to the existing list - return {"messages": [function_message]} + return {"messages": [tool_message]} # We create the AgentState that we will pass around # This simply involves a list of messages diff --git a/tests/test_pregel.py b/tests/test_pregel.py index 6f0e3aad8..447e99e12 100644 --- a/tests/test_pregel.py +++ b/tests/test_pregel.py @@ -26,7 +26,6 @@ from langgraph.prebuilt.tool_executor import ToolExecutor from langgraph.pregel import Channel, GraphRecursionError, Pregel from langgraph.pregel.reserved import ReservedChannels - def test_invoke_single_process_in_out(mocker: MockerFixture) -> None: add_one = mocker.Mock(side_effect=lambda x: x + 1) chain = Channel.subscribe_to("input") | add_one | Channel.write_to("output") @@ -1065,7 +1064,7 @@ def test_conditional_graph_state() -> None: def test_prebuilt_tool_chat() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool - from langchain_core.messages import AIMessage, FunctionMessage, HumanMessage + from langchain_core.messages import AIMessage, HumanMessage, ToolMessage class FakeFuntionChatModel(FakeMessagesListChatModel): def bind_functions(self, functions: list): @@ -1112,7 +1111,7 @@ def test_prebuilt_tool_chat() -> None: ), tools, ) - + assert app.invoke( {"messages": [HumanMessage(content="what is weather in sf")]} ) == { @@ -1126,12 +1125,12 @@ def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1140,12 +1139,12 @@ def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] } @@ -1164,7 +1163,7 @@ def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, @@ -1175,7 +1174,7 @@ def test_prebuilt_tool_chat() -> None: { "action": { "messages": [ - FunctionMessage(content="result for query", name="search_api") + ToolMessage(content="result for query", tool_call_id="tool_call123") ] } }, @@ -1190,7 +1189,7 @@ def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, @@ -1201,7 +1200,7 @@ def test_prebuilt_tool_chat() -> None: { "action": { "messages": [ - FunctionMessage(content="result for another", name="search_api") + ToolMessage(content="result for another", tool_call_id="tool_call234") ] } }, @@ -1218,12 +1217,12 @@ def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1232,12 +1231,12 @@ def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] } @@ -1248,7 +1247,7 @@ def test_tool_message_graph() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool from langchain_core.agents import AgentAction - from langchain_core.messages import AIMessage, FunctionMessage, HumanMessage + from langchain_core.messages import AIMessage, ToolMessage, HumanMessage class FakeFuntionChatModel(FakeMessagesListChatModel): def bind_functions(self, functions: list): @@ -1315,12 +1314,12 @@ def test_tool_message_graph() -> None: tool_input=json.loads( last_message.additional_kwargs["tool_calls"][0]["function"]["arguments"] ), - log="", + log=last_message.additional_kwargs["tool_calls"][0]["id"], ) # We call the tool_executor and get back a response response = tool_executor.invoke(action) - # We use the response to create a FunctionMessage - return FunctionMessage(content=str(response), name=action.tool) + # We use the response to create a ToolMessage + return ToolMessage(content=str(response), tool_call_id=action.log) # Define a new graph workflow = MessageGraph() @@ -1373,12 +1372,12 @@ def test_tool_message_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1387,12 +1386,12 @@ def test_tool_message_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] @@ -1406,13 +1405,13 @@ def test_tool_message_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ) }, - {"action": FunctionMessage(content="result for query", name="search_api")}, + {"action": ToolMessage(content="result for query", tool_call_id="tool_call123")}, { "agent": AIMessage( content="", @@ -1422,13 +1421,13 @@ def test_tool_message_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ) }, - {"action": FunctionMessage(content="result for another", name="search_api")}, + {"action": ToolMessage(content="result for another", tool_call_id="tool_call234")}, {"agent": AIMessage(content="answer")}, { "__end__": [ @@ -1441,12 +1440,12 @@ def test_tool_message_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1455,18 +1454,17 @@ def test_tool_message_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] }, ] -@deprecated("*") def test_prebuilt_chat() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool @@ -1611,7 +1609,6 @@ def test_prebuilt_chat() -> None: }, ] -@deprecated("*") def test_message_graph() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool diff --git a/tests/test_pregel_async.py b/tests/test_pregel_async.py index 24fa679b8..a51c36a94 100644 --- a/tests/test_pregel_async.py +++ b/tests/test_pregel_async.py @@ -1115,7 +1115,7 @@ async def test_conditional_graph_state() -> None: async def test_prebuilt_tool_chat() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool - from langchain_core.messages import AIMessage, FunctionMessage, HumanMessage + from langchain_core.messages import AIMessage, ToolMessage, HumanMessage class FakeFuntionChatModel(FakeMessagesListChatModel): def bind_functions(self, functions: list): @@ -1128,7 +1128,7 @@ async def test_prebuilt_tool_chat() -> None: tools = [search_api] - app = create_function_calling_executor( + app = create_tool_calling_executor( FakeFuntionChatModel( responses=[ AIMessage( @@ -1163,6 +1163,9 @@ async def test_prebuilt_tool_chat() -> None: tools, ) + res = await app.ainvoke( + {"messages": [HumanMessage(content="what is weather in sf")]} + ) assert await app.ainvoke( {"messages": [HumanMessage(content="what is weather in sf")]} ) == { @@ -1176,12 +1179,12 @@ async def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1190,12 +1193,12 @@ async def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] } @@ -1217,7 +1220,7 @@ async def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, @@ -1228,7 +1231,7 @@ async def test_prebuilt_tool_chat() -> None: { "action": { "messages": [ - FunctionMessage(content="result for query", name="search_api") + ToolMessage(content="result for query", tool_call_id="tool_call123") ] } }, @@ -1243,7 +1246,7 @@ async def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, @@ -1254,7 +1257,7 @@ async def test_prebuilt_tool_chat() -> None: { "action": { "messages": [ - FunctionMessage(content="result for another", name="search_api") + ToolMessage(content="result for another", tool_call_id="tool_call234") ] } }, @@ -1271,12 +1274,12 @@ async def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1285,12 +1288,12 @@ async def test_prebuilt_tool_chat() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] } @@ -1302,7 +1305,7 @@ async def test_message_tool_graph() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool from langchain_core.agents import AgentAction - from langchain_core.messages import AIMessage, FunctionMessage, HumanMessage + from langchain_core.messages import AIMessage, ToolMessage, HumanMessage class FakeFuntionChatModel(FakeMessagesListChatModel): def bind_functions(self, functions: list): @@ -1365,16 +1368,16 @@ async def test_message_tool_graph() -> None: last_message = messages[-1] # We construct an AgentAction from the function_call action = AgentAction( - tool=last_message.additional_kwargs["tool_calls"][0]["fcuntion"]["name"], + tool=last_message.additional_kwargs["tool_calls"][0]["function"]["name"], tool_input=json.loads( last_message.additional_kwargs["tool_calls"][0]["function"]["arguments"] ), - log="", + log=last_message.additional_kwargs["tool_calls"][0]["id"], ) # We call the tool_executor and get back a response response = await tool_executor.ainvoke(action) # We use the response to create a FunctionMessage - return FunctionMessage(content=str(response), name=action.tool) + return ToolMessage(content=str(response), tool_call_id=action.log) # Define a new graph workflow = MessageGraph() @@ -1427,12 +1430,12 @@ async def test_message_tool_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1441,12 +1444,12 @@ async def test_message_tool_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] @@ -1462,13 +1465,13 @@ async def test_message_tool_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ) }, - {"action": FunctionMessage(content="result for query", name="search_api")}, + {"action": ToolMessage(content="result for query", tool_call_id="tool_call123")}, { "agent": AIMessage( content="", @@ -1478,13 +1481,13 @@ async def test_message_tool_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ) }, - {"action": FunctionMessage(content="result for another", name="search_api")}, + {"action": ToolMessage(content="result for another", tool_call_id="tool_call234")}, {"agent": AIMessage(content="answer")}, { "__end__": [ @@ -1497,12 +1500,12 @@ async def test_message_tool_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "query", + "arguments": "\"query\"", } }] }, ), - FunctionMessage(content="result for query", name="search_api"), + ToolMessage(content="result for query", tool_call_id="tool_call123"), AIMessage( content="", additional_kwargs={ @@ -1511,18 +1514,18 @@ async def test_message_tool_graph() -> None: "type": "function", "function":{ "name": "search_api", - "arguments": "another", + "arguments": "\"another\"", } }] }, ), - FunctionMessage(content="result for another", name="search_api"), + ToolMessage(content="result for another", tool_call_id="tool_call234"), AIMessage(content="answer"), ] }, ] -@deprecated("*") + async def test_prebuilt_chat() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool @@ -1670,7 +1673,7 @@ async def test_prebuilt_chat() -> None: }, ] -@deprecated("*") + async def test_message_graph() -> None: from langchain.chat_models.fake import FakeMessagesListChatModel from langchain_community.tools import tool