mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-17 23:27:56 +02:00
chore(prebuilt): critical renaming (#5971)
* `create_react_agent` -> `create_agent` * `agent` node -> `model` node
This commit is contained in:
@@ -28,7 +28,7 @@ from langgraph.graph import START, MessagesState, StateGraph
|
||||
from langgraph.graph.message import REMOVE_ALL_MESSAGES
|
||||
from langgraph.prebuilt import (
|
||||
ToolNode,
|
||||
create_react_agent,
|
||||
create_agent,
|
||||
)
|
||||
from langgraph.prebuilt.chat_agent_executor import (
|
||||
AgentState,
|
||||
@@ -56,7 +56,7 @@ pytestmark = pytest.mark.anyio
|
||||
def test_no_prompt(sync_checkpointer: BaseCheckpointSaver) -> None:
|
||||
model = FakeToolCallingModel()
|
||||
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[],
|
||||
checkpointer=sync_checkpointer,
|
||||
@@ -86,7 +86,7 @@ def test_no_prompt(sync_checkpointer: BaseCheckpointSaver) -> None:
|
||||
async def test_no_prompt_async(async_checkpointer: BaseCheckpointSaver) -> None:
|
||||
model = FakeToolCallingModel()
|
||||
|
||||
agent = create_react_agent(model, [], checkpointer=async_checkpointer)
|
||||
agent = create_agent(model, [], checkpointer=async_checkpointer)
|
||||
inputs = [HumanMessage("hi?")]
|
||||
thread = {"configurable": {"thread_id": "123"}}
|
||||
response = await agent.ainvoke({"messages": inputs}, thread, debug=True)
|
||||
@@ -111,7 +111,7 @@ async def test_no_prompt_async(async_checkpointer: BaseCheckpointSaver) -> None:
|
||||
|
||||
def test_system_message_prompt():
|
||||
prompt = SystemMessage(content="Foo")
|
||||
agent = create_react_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
agent = create_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
inputs = [HumanMessage("hi?")]
|
||||
response = agent.invoke({"messages": inputs})
|
||||
expected_response = {
|
||||
@@ -122,7 +122,7 @@ def test_system_message_prompt():
|
||||
|
||||
def test_string_prompt():
|
||||
prompt = "Foo"
|
||||
agent = create_react_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
agent = create_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
inputs = [HumanMessage("hi?")]
|
||||
response = agent.invoke({"messages": inputs})
|
||||
expected_response = {
|
||||
@@ -136,7 +136,7 @@ def test_callable_prompt():
|
||||
modified_message = f"Bar {state['messages'][-1].content}"
|
||||
return [HumanMessage(content=modified_message)]
|
||||
|
||||
agent = create_react_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
agent = create_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
inputs = [HumanMessage("hi?")]
|
||||
response = agent.invoke({"messages": inputs})
|
||||
expected_response = {"messages": inputs + [AIMessage(content="Bar hi?", id="0")]}
|
||||
@@ -148,7 +148,7 @@ async def test_callable_prompt_async():
|
||||
modified_message = f"Bar {state['messages'][-1].content}"
|
||||
return [HumanMessage(content=modified_message)]
|
||||
|
||||
agent = create_react_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
agent = create_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
inputs = [HumanMessage("hi?")]
|
||||
response = await agent.ainvoke({"messages": inputs})
|
||||
expected_response = {"messages": inputs + [AIMessage(content="Bar hi?", id="0")]}
|
||||
@@ -160,7 +160,7 @@ def test_runnable_prompt():
|
||||
lambda state: [HumanMessage(content=f"Baz {state['messages'][-1].content}")]
|
||||
)
|
||||
|
||||
agent = create_react_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
agent = create_agent(FakeToolCallingModel(), [], prompt=prompt)
|
||||
inputs = [HumanMessage("hi?")]
|
||||
response = agent.invoke({"messages": inputs})
|
||||
expected_response = {"messages": inputs + [AIMessage(content="Baz hi?", id="0")]}
|
||||
@@ -187,7 +187,7 @@ def test_prompt_with_store():
|
||||
model = FakeToolCallingModel()
|
||||
|
||||
# test state modifier that uses store works
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[add],
|
||||
prompt=prompt,
|
||||
@@ -199,7 +199,7 @@ def test_prompt_with_store():
|
||||
assert response["messages"][-1].content == "User name is Alice-hi"
|
||||
|
||||
# test state modifier that doesn't use store works
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[add],
|
||||
prompt=prompt_no_store,
|
||||
@@ -237,16 +237,14 @@ async def test_prompt_with_store_async():
|
||||
model = FakeToolCallingModel()
|
||||
|
||||
# test state modifier that uses store works
|
||||
agent = create_react_agent(model, [add], prompt=prompt, store=in_memory_store)
|
||||
agent = create_agent(model, [add], prompt=prompt, store=in_memory_store)
|
||||
response = await agent.ainvoke(
|
||||
{"messages": [("user", "hi")]}, {"configurable": {"user_id": "1"}}
|
||||
)
|
||||
assert response["messages"][-1].content == "User name is Alice-hi"
|
||||
|
||||
# test state modifier that doesn't use store works
|
||||
agent = create_react_agent(
|
||||
model, [add], prompt=prompt_no_store, store=in_memory_store
|
||||
)
|
||||
agent = create_agent(model, [add], prompt=prompt_no_store, store=in_memory_store)
|
||||
response = await agent.ainvoke(
|
||||
{"messages": [("user", "hi")]}, {"configurable": {"user_id": "2"}}
|
||||
)
|
||||
@@ -287,7 +285,7 @@ def test_model_with_tools(tool_style: str, include_builtin: bool) -> None:
|
||||
)
|
||||
# check valid agent constructor
|
||||
with pytest.raises(ValueError):
|
||||
create_react_agent(
|
||||
create_agent(
|
||||
model.bind_tools(tools),
|
||||
tools,
|
||||
)
|
||||
@@ -436,7 +434,7 @@ def test_react_agent_with_structured_response() -> None:
|
||||
model = FakeToolCallingModel[WeatherResponse](
|
||||
tool_calls=tool_calls, structured_response=expected_structured_response
|
||||
)
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[get_weather],
|
||||
response_format=WeatherResponse,
|
||||
@@ -513,7 +511,7 @@ def test_react_agent_update_state(
|
||||
|
||||
tool_calls = [[{"args": {}, "id": "1", "name": "get_user_name"}]]
|
||||
model = FakeToolCallingModel(tool_calls=tool_calls)
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[get_user_name],
|
||||
state_schema=state_schema,
|
||||
@@ -564,7 +562,7 @@ def test_react_agent_parallel_tool_calls(
|
||||
[],
|
||||
]
|
||||
model = FakeToolCallingModel(tool_calls=tool_calls)
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[human_assistance, get_weather],
|
||||
checkpointer=sync_checkpointer,
|
||||
@@ -647,7 +645,7 @@ def test_create_react_agent_inject_vars(state_schema: StateSchemaType) -> None:
|
||||
"type": "tool_call",
|
||||
}
|
||||
model = FakeToolCallingModel(tool_calls=[[tool_call], []])
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
ToolNode([tool1], handle_tool_errors=False),
|
||||
state_schema=state_schema,
|
||||
@@ -687,7 +685,7 @@ async def test_return_direct() -> None:
|
||||
tool_calls=first_tool_call,
|
||||
)
|
||||
model = FakeToolCallingModel(tool_calls=[first_tool_call, []])
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[tool_return_direct, tool_normal],
|
||||
)
|
||||
@@ -714,7 +712,7 @@ async def test_return_direct() -> None:
|
||||
),
|
||||
]
|
||||
model = FakeToolCallingModel(tool_calls=[second_tool_call, []])
|
||||
agent = create_react_agent(model, [tool_return_direct, tool_normal])
|
||||
agent = create_agent(model, [tool_return_direct, tool_normal])
|
||||
result = agent.invoke(
|
||||
{"messages": [HumanMessage(content="Test normal", id="hum1")]}
|
||||
)
|
||||
@@ -743,7 +741,7 @@ async def test_return_direct() -> None:
|
||||
),
|
||||
]
|
||||
model = FakeToolCallingModel(tool_calls=[both_tool_calls, []])
|
||||
agent = create_react_agent(model, [tool_return_direct, tool_normal])
|
||||
agent = create_agent(model, [tool_return_direct, tool_normal])
|
||||
result = agent.invoke({"messages": [HumanMessage(content="Test both", id="hum2")]})
|
||||
assert result["messages"] == [
|
||||
HumanMessage(content="Test both", id="hum2"),
|
||||
@@ -780,8 +778,8 @@ def test__get_state_args() -> None:
|
||||
|
||||
def test_inspect_react() -> None:
|
||||
model = FakeToolCallingModel(tool_calls=[])
|
||||
agent = create_react_agent(model, [])
|
||||
inspect.getclosurevars(agent.nodes["agent"].bound.func)
|
||||
agent = create_agent(model, [])
|
||||
inspect.getclosurevars(agent.nodes["model"].bound.func)
|
||||
|
||||
|
||||
def test_react_with_subgraph_tools(
|
||||
@@ -837,7 +835,7 @@ def test_react_with_subgraph_tools(
|
||||
]
|
||||
)
|
||||
tool_node = ToolNode([addition, multiplication], handle_tool_errors=False)
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
tool_node,
|
||||
checkpointer=sync_checkpointer,
|
||||
@@ -887,7 +885,7 @@ def test_react_agent_subgraph_streaming_sync() -> None:
|
||||
]
|
||||
)
|
||||
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
tools=[get_weather],
|
||||
prompt="You are a helpful travel assistant.",
|
||||
@@ -976,7 +974,7 @@ async def test_react_agent_subgraph_streaming() -> None:
|
||||
]
|
||||
)
|
||||
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
tools=[get_weather],
|
||||
prompt="You are a helpful travel assistant.",
|
||||
@@ -1074,7 +1072,7 @@ def test_tool_node_node_interrupt(
|
||||
]
|
||||
)
|
||||
config = {"configurable": {"thread_id": "1"}}
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[tool_interrupt, tool_normal],
|
||||
checkpointer=sync_checkpointer,
|
||||
@@ -1126,7 +1124,7 @@ def test_dynamic_model_basic() -> None:
|
||||
else:
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
agent = create_react_agent(dynamic_model, [])
|
||||
agent = create_agent(dynamic_model, [])
|
||||
|
||||
result = agent.invoke({"messages": [HumanMessage("hello")]})
|
||||
assert len(result["messages"]) == 2
|
||||
@@ -1164,7 +1162,7 @@ def test_dynamic_model_with_tools() -> None:
|
||||
tool_calls=[[{"args": {"x": 1}, "id": "1", "name": "basic_tool"}], []]
|
||||
)
|
||||
|
||||
agent = create_react_agent(dynamic_model, [basic_tool, advanced_tool])
|
||||
agent = create_agent(dynamic_model, [basic_tool, advanced_tool])
|
||||
|
||||
# Test basic tool usage
|
||||
result = agent.invoke({"messages": [HumanMessage("basic request")]})
|
||||
@@ -1197,7 +1195,7 @@ def test_dynamic_model_with_context() -> None:
|
||||
else:
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
agent = create_react_agent(dynamic_model, [], context_schema=Context)
|
||||
agent = create_agent(dynamic_model, [], context_schema=Context)
|
||||
|
||||
# Test with basic user
|
||||
result = agent.invoke(
|
||||
@@ -1227,7 +1225,7 @@ def test_dynamic_model_with_state_schema() -> None:
|
||||
else:
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
agent = create_react_agent(dynamic_model, [], state_schema=CustomDynamicState)
|
||||
agent = create_agent(dynamic_model, [], state_schema=CustomDynamicState)
|
||||
|
||||
result = agent.invoke(
|
||||
{"messages": [HumanMessage("hello")], "model_preference": "advanced"}
|
||||
@@ -1243,7 +1241,7 @@ def test_dynamic_model_with_prompt() -> None:
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
# Test with string prompt
|
||||
agent = create_react_agent(dynamic_model, [], prompt="system_msg")
|
||||
agent = create_agent(dynamic_model, [], prompt="system_msg")
|
||||
result = agent.invoke({"messages": [HumanMessage("human_msg")]})
|
||||
assert result["messages"][-1].content == "system_msg-human_msg"
|
||||
|
||||
@@ -1252,7 +1250,7 @@ def test_dynamic_model_with_prompt() -> None:
|
||||
"""Generate a dynamic system message based on state."""
|
||||
return [{"role": "system", "content": "system_msg"}] + list(state["messages"])
|
||||
|
||||
agent = create_react_agent(dynamic_model, [], prompt=dynamic_prompt)
|
||||
agent = create_agent(dynamic_model, [], prompt=dynamic_prompt)
|
||||
result = agent.invoke({"messages": [HumanMessage("human_msg")]})
|
||||
assert result["messages"][-1].content == "system_msg-human_msg"
|
||||
|
||||
@@ -1263,7 +1261,7 @@ async def test_dynamic_model_async() -> None:
|
||||
def dynamic_model(state: AgentState, runtime: Runtime) -> BaseChatModel:
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
agent = create_react_agent(dynamic_model, [])
|
||||
agent = create_agent(dynamic_model, [])
|
||||
|
||||
result = await agent.ainvoke({"messages": [HumanMessage("hello async")]})
|
||||
assert len(result["messages"]) == 2
|
||||
@@ -1291,7 +1289,7 @@ def test_dynamic_model_with_structured_response() -> None:
|
||||
],
|
||||
)
|
||||
|
||||
agent = create_react_agent(dynamic_model, [], response_format=TestResponse)
|
||||
agent = create_agent(dynamic_model, [], response_format=TestResponse)
|
||||
|
||||
result = agent.invoke({"messages": [HumanMessage("hello")]})
|
||||
assert "structured_response" in result
|
||||
@@ -1315,7 +1313,7 @@ def test_dynamic_model_with_checkpointer(sync_checkpointer):
|
||||
index=call_count,
|
||||
)
|
||||
|
||||
agent = create_react_agent(dynamic_model, [], checkpointer=sync_checkpointer)
|
||||
agent = create_agent(dynamic_model, [], checkpointer=sync_checkpointer)
|
||||
config = {"configurable": {"thread_id": "test_dynamic"}}
|
||||
|
||||
# First call
|
||||
@@ -1354,7 +1352,7 @@ def test_dynamic_model_state_dependent_tools() -> None:
|
||||
tool_calls=[[{"args": {"x": 1}, "id": "1", "name": "tool_a"}], []]
|
||||
)
|
||||
|
||||
agent = create_react_agent(dynamic_model, [tool_a, tool_b])
|
||||
agent = create_agent(dynamic_model, [tool_a, tool_b])
|
||||
|
||||
# Ask to use tool B
|
||||
result = agent.invoke({"messages": [HumanMessage("use_b please")]})
|
||||
@@ -1377,7 +1375,7 @@ def test_dynamic_model_error_handling() -> None:
|
||||
raise ValueError("Dynamic model failed")
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
agent = create_react_agent(failing_dynamic_model, [])
|
||||
agent = create_agent(failing_dynamic_model, [])
|
||||
|
||||
# Normal operation should work
|
||||
result = agent.invoke({"messages": [HumanMessage("hello")]})
|
||||
@@ -1392,13 +1390,13 @@ def test_dynamic_model_vs_static_model_behavior():
|
||||
"""Test that dynamic and static models produce equivalent results when configured the same."""
|
||||
# Static model
|
||||
static_model = FakeToolCallingModel(tool_calls=[])
|
||||
static_agent = create_react_agent(static_model, [])
|
||||
static_agent = create_agent(static_model, [])
|
||||
|
||||
# Dynamic model returning the same model
|
||||
def dynamic_model(state, runtime: Runtime):
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
dynamic_agent = create_react_agent(dynamic_model, [])
|
||||
dynamic_agent = create_agent(dynamic_model, [])
|
||||
|
||||
input_msg = {"messages": [HumanMessage("test message")]}
|
||||
|
||||
@@ -1423,7 +1421,7 @@ def test_dynamic_model_receives_correct_state():
|
||||
received_states.append(state)
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
agent = create_react_agent(dynamic_model, [], state_schema=CustomAgentState)
|
||||
agent = create_agent(dynamic_model, [], state_schema=CustomAgentState)
|
||||
|
||||
# Test with initial state
|
||||
input_state = {"messages": [HumanMessage("hello")], "custom_field": "test_value"}
|
||||
@@ -1454,7 +1452,7 @@ async def test_dynamic_model_receives_correct_state_async():
|
||||
received_states.append(state)
|
||||
return FakeToolCallingModel(tool_calls=[])
|
||||
|
||||
agent = create_react_agent(dynamic_model, [], state_schema=CustomAgentStateAsync)
|
||||
agent = create_agent(dynamic_model, [], state_schema=CustomAgentStateAsync)
|
||||
|
||||
# Test with initial state
|
||||
input_state = {
|
||||
@@ -1483,7 +1481,7 @@ def test_pre_model_hook() -> None:
|
||||
def pre_model_hook(state: AgentState):
|
||||
return {"llm_input_messages": [HumanMessage("Hello!")]}
|
||||
|
||||
agent = create_react_agent(model, [], pre_model_hook=pre_model_hook)
|
||||
agent = create_agent(model, [], pre_model_hook=pre_model_hook)
|
||||
assert "pre_model_hook" in agent.nodes
|
||||
result = agent.invoke({"messages": [HumanMessage("hi?")]})
|
||||
assert result == {
|
||||
@@ -1499,7 +1497,7 @@ def test_pre_model_hook() -> None:
|
||||
"messages": [RemoveMessage(id=REMOVE_ALL_MESSAGES), HumanMessage("Hello!")]
|
||||
}
|
||||
|
||||
agent = create_react_agent(model, [], pre_model_hook=pre_model_hook)
|
||||
agent = create_agent(model, [], pre_model_hook=pre_model_hook)
|
||||
result = agent.invoke({"messages": [HumanMessage("hi?")]})
|
||||
assert result == {
|
||||
"messages": [
|
||||
@@ -1518,7 +1516,7 @@ def test_post_model_hook() -> None:
|
||||
def post_model_hook(state: FlagState) -> dict[str, bool]:
|
||||
return {"flag": True}
|
||||
|
||||
pmh_agent = create_react_agent(
|
||||
pmh_agent = create_agent(
|
||||
model, [], post_model_hook=post_model_hook, state_schema=FlagState
|
||||
)
|
||||
|
||||
@@ -1530,7 +1528,7 @@ def test_post_model_hook() -> None:
|
||||
events = list(pmh_agent.stream({"messages": [HumanMessage("hi?")], "flag": False}))
|
||||
assert events == [
|
||||
{
|
||||
"agent": {
|
||||
"model": {
|
||||
"messages": [
|
||||
AIMessage(
|
||||
content="hi?",
|
||||
@@ -1568,7 +1566,7 @@ def test_post_model_hook_with_structured_output() -> None:
|
||||
return {"flag": True}
|
||||
|
||||
model = FakeToolCallingModel(tool_calls=tool_calls)
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[get_weather],
|
||||
response_format=WeatherResponse,
|
||||
@@ -1586,7 +1584,7 @@ def test_post_model_hook_with_structured_output() -> None:
|
||||
|
||||
# Reset the state of the model
|
||||
model = FakeToolCallingModel(tool_calls=tool_calls)
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[get_weather],
|
||||
response_format=WeatherResponse,
|
||||
@@ -1599,7 +1597,7 @@ def test_post_model_hook_with_structured_output() -> None:
|
||||
)
|
||||
assert events == [
|
||||
{
|
||||
"agent": {
|
||||
"model": {
|
||||
"messages": [
|
||||
AIMessage(
|
||||
content="What's the weather?",
|
||||
@@ -1631,7 +1629,7 @@ def test_post_model_hook_with_structured_output() -> None:
|
||||
}
|
||||
},
|
||||
{
|
||||
"agent": {
|
||||
"model": {
|
||||
"messages": [
|
||||
AIMessage(
|
||||
content="What's the weather?-What's the weather?-The weather is sunny and 75°F.",
|
||||
@@ -1703,7 +1701,7 @@ def test_create_react_agent_inject_vars_with_post_model_hook(
|
||||
return {"foo": 2}
|
||||
|
||||
model = FakeToolCallingModel(tool_calls=[[tool_call], []])
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
ToolNode([tool1], handle_tool_errors=False),
|
||||
state_schema=state_schema,
|
||||
@@ -1738,7 +1736,7 @@ def test_response_format_using_tool_choice() -> None:
|
||||
|
||||
expected_structured_response = WeatherResponse(temperature=75)
|
||||
model = FakeToolCallingModel(tool_calls=tool_calls)
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
[get_weather],
|
||||
response_format=WeatherResponse,
|
||||
|
||||
Reference in New Issue
Block a user