mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-06 17:57:49 +02:00
chore(prebuilt): critical renaming (#5971)
* `create_react_agent` -> `create_agent` * `agent` node -> `model` node
This commit is contained in:
@@ -10,7 +10,7 @@ from langchain_core.outputs import ChatGeneration, ChatResult
|
||||
from langchain_core.tools import StructuredTool
|
||||
|
||||
from langgraph.checkpoint.base import BaseCheckpointSaver
|
||||
from langgraph.prebuilt.chat_agent_executor import create_react_agent
|
||||
from langgraph.prebuilt.chat_agent_executor import create_agent
|
||||
from langgraph.pregel import Pregel
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ def react_agent(n_tools: int, checkpointer: Optional[BaseCheckpointSaver]) -> Pr
|
||||
]
|
||||
)
|
||||
|
||||
return create_react_agent(model, [tool], checkpointer=checkpointer)
|
||||
return create_agent(model, [tool], checkpointer=checkpointer)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -21,7 +21,7 @@ from langgraph.checkpoint.memory import InMemorySaver
|
||||
from langgraph.constants import END, START
|
||||
from langgraph.graph import StateGraph
|
||||
from langgraph.graph.message import MessagesState, add_messages
|
||||
from langgraph.prebuilt.chat_agent_executor import create_react_agent
|
||||
from langgraph.prebuilt.chat_agent_executor import create_agent
|
||||
from langgraph.prebuilt.tool_node import ToolNode
|
||||
from langgraph.pregel import NodeBuilder, Pregel
|
||||
from langgraph.types import (
|
||||
@@ -1301,7 +1301,7 @@ def test_prebuilt_tool_chat(snapshot: SnapshotAssertion) -> None:
|
||||
]
|
||||
)
|
||||
|
||||
app = create_react_agent(model, tools)
|
||||
app = create_agent(model, tools)
|
||||
|
||||
assert json.dumps(app.get_input_jsonschema()) == snapshot
|
||||
assert json.dumps(app.get_output_jsonschema()) == snapshot
|
||||
|
||||
@@ -23,7 +23,7 @@ from langgraph.checkpoint.base import BaseCheckpointSaver
|
||||
from langgraph.constants import END, START
|
||||
from langgraph.graph.message import add_messages
|
||||
from langgraph.graph.state import StateGraph
|
||||
from langgraph.prebuilt.chat_agent_executor import create_react_agent
|
||||
from langgraph.prebuilt.chat_agent_executor import create_agent
|
||||
from langgraph.prebuilt.tool_node import ToolNode
|
||||
from langgraph.pregel import NodeBuilder, Pregel
|
||||
from langgraph.types import PregelTask, Send, StateSnapshot, StreamWriter
|
||||
@@ -1059,7 +1059,7 @@ async def test_prebuilt_tool_chat() -> None:
|
||||
|
||||
tools = [search_api]
|
||||
|
||||
app = create_react_agent(model, tools)
|
||||
app = create_agent(model, tools)
|
||||
|
||||
assert await app.ainvoke(
|
||||
{"messages": [HumanMessage(content="what is weather in sf")]}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""langgraph.prebuilt exposes a higher-level API for creating and executing agents and tools."""
|
||||
|
||||
from langgraph.prebuilt.chat_agent_executor import create_react_agent
|
||||
from langgraph.prebuilt.chat_agent_executor import create_agent
|
||||
from langgraph.prebuilt.tool_node import (
|
||||
InjectedState,
|
||||
InjectedStore,
|
||||
@@ -10,7 +10,7 @@ from langgraph.prebuilt.tool_node import (
|
||||
from langgraph.prebuilt.tool_validator import ValidationNode
|
||||
|
||||
__all__ = [
|
||||
"create_react_agent",
|
||||
"create_agent",
|
||||
"ToolNode",
|
||||
"tools_condition",
|
||||
"ValidationNode",
|
||||
|
||||
@@ -680,7 +680,7 @@ class _AgentBuilder(Generic[StructuredResponseT]):
|
||||
|
||||
def _get_entry_point(self) -> str:
|
||||
"""Get the workflow entry point."""
|
||||
return "pre_model_hook" if self.pre_model_hook else "agent"
|
||||
return "pre_model_hook" if self.pre_model_hook else "model"
|
||||
|
||||
def _get_model_paths(self) -> list[str]:
|
||||
"""Get possible edge destinations from model node."""
|
||||
@@ -714,7 +714,7 @@ class _AgentBuilder(Generic[StructuredResponseT]):
|
||||
|
||||
# Add nodes
|
||||
workflow.add_node(
|
||||
"agent", self.create_model_node(), input_schema=self._get_input_schema()
|
||||
"model", self.create_model_node(), input_schema=self._get_input_schema()
|
||||
)
|
||||
|
||||
if self._tool_calling_enabled:
|
||||
@@ -728,10 +728,10 @@ class _AgentBuilder(Generic[StructuredResponseT]):
|
||||
|
||||
# Add edges
|
||||
if self.pre_model_hook:
|
||||
workflow.add_edge("pre_model_hook", "agent")
|
||||
workflow.add_edge("pre_model_hook", "model")
|
||||
|
||||
if self.post_model_hook:
|
||||
workflow.add_edge("agent", "post_model_hook")
|
||||
workflow.add_edge("model", "post_model_hook")
|
||||
post_hook_paths = self._get_post_model_hook_paths()
|
||||
if len(post_hook_paths) == 1:
|
||||
# No need for a conditional edge if there's only one path
|
||||
@@ -746,10 +746,10 @@ class _AgentBuilder(Generic[StructuredResponseT]):
|
||||
model_paths = self._get_model_paths()
|
||||
if len(model_paths) == 1:
|
||||
# No need for a conditional edge if there's only one path
|
||||
workflow.add_edge("agent", model_paths[0])
|
||||
workflow.add_edge("model", model_paths[0])
|
||||
else:
|
||||
workflow.add_conditional_edges(
|
||||
"agent",
|
||||
"model",
|
||||
self.create_model_router(),
|
||||
path_map=model_paths,
|
||||
)
|
||||
@@ -771,7 +771,7 @@ class _AgentBuilder(Generic[StructuredResponseT]):
|
||||
return workflow
|
||||
|
||||
|
||||
def create_react_agent(
|
||||
def create_agent(
|
||||
model: Union[
|
||||
str,
|
||||
BaseChatModel,
|
||||
@@ -796,7 +796,7 @@ def create_react_agent(
|
||||
) -> CompiledStateGraph:
|
||||
"""Creates an agent graph that calls tools in a loop until a stopping condition is met.
|
||||
|
||||
For more details on using `create_react_agent`, visit [Agents](https://langchain-ai.github.io/langgraph/agents/overview/) documentation.
|
||||
For more details on using `create_agent`, visit [Agents](https://langchain-ai.github.io/langgraph/agents/overview/) documentation.
|
||||
|
||||
Args:
|
||||
model: The language model for the agent. Supports static and dynamic
|
||||
@@ -911,10 +911,10 @@ def create_react_agent(
|
||||
store: An optional store object. This is used for persisting data
|
||||
across multiple threads (e.g., multiple conversations / users).
|
||||
interrupt_before: An optional list of node names to interrupt before.
|
||||
Should be one of the following: "agent", "tools".
|
||||
Should be one of the following: "model", "tools".
|
||||
This is useful if you want to add a user confirmation or other interrupt before taking an action.
|
||||
interrupt_after: An optional list of node names to interrupt after.
|
||||
Should be one of the following: "agent", "tools".
|
||||
Should be one of the following: "model", "tools".
|
||||
This is useful if you want to return directly or run additional processing on an output.
|
||||
debug: A flag indicating whether to enable debug mode.
|
||||
name: An optional name for the CompiledStateGraph.
|
||||
@@ -924,7 +924,7 @@ def create_react_agent(
|
||||
Returns:
|
||||
A CompiledStateGraph that can be used for chat interactions.
|
||||
|
||||
The "agent" node calls the language model with the messages list (after applying the prompt).
|
||||
The "model" node calls the language model with the messages list (after applying the prompt).
|
||||
If the resulting AIMessage contains `tool_calls`, the graph will then call the ["tools"][langgraph.prebuilt.tool_node.ToolNode].
|
||||
The "tools" node executes the tools (1 tool per `tool_call`) and adds the responses to the messages list
|
||||
as `ToolMessage` objects. The agent node then calls the language model again.
|
||||
@@ -947,13 +947,13 @@ def create_react_agent(
|
||||
|
||||
Example:
|
||||
```python
|
||||
from langgraph.prebuilt import create_react_agent
|
||||
from langgraph.prebuilt import create_agent
|
||||
|
||||
def check_weather(location: str) -> str:
|
||||
'''Return the weather forecast for the specified location.'''
|
||||
return f"It's always sunny in {location}"
|
||||
|
||||
graph = create_react_agent(
|
||||
graph = create_agent(
|
||||
"anthropic:claude-3-7-sonnet-latest",
|
||||
tools=[check_weather],
|
||||
prompt="You are a helpful assistant",
|
||||
@@ -1005,12 +1005,8 @@ def create_react_agent(
|
||||
)
|
||||
|
||||
|
||||
# Keep for backwards compatibility
|
||||
create_tool_calling_executor = create_react_agent
|
||||
|
||||
__all__ = [
|
||||
"create_react_agent",
|
||||
"create_tool_calling_executor",
|
||||
"create_agent",
|
||||
"AgentState",
|
||||
"AgentStatePydantic",
|
||||
"AgentStateWithStructuredResponse",
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
# name: test_react_agent_graph_structure[None-None-tools0]
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> agent;
|
||||
agent --> __end__;
|
||||
__start__ --> model;
|
||||
model --> __end__;
|
||||
|
||||
'''
|
||||
# ---
|
||||
# name: test_react_agent_graph_structure[None-None-tools1]
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> agent;
|
||||
agent -.-> __end__;
|
||||
agent -.-> tools;
|
||||
tools --> agent;
|
||||
__start__ --> model;
|
||||
model -.-> __end__;
|
||||
model -.-> tools;
|
||||
tools --> model;
|
||||
|
||||
'''
|
||||
# ---
|
||||
@@ -21,8 +21,8 @@
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> pre_model_hook;
|
||||
pre_model_hook --> agent;
|
||||
agent --> __end__;
|
||||
pre_model_hook --> model;
|
||||
model --> __end__;
|
||||
|
||||
'''
|
||||
# ---
|
||||
@@ -30,9 +30,9 @@
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> pre_model_hook;
|
||||
agent -.-> __end__;
|
||||
agent -.-> tools;
|
||||
pre_model_hook --> agent;
|
||||
model -.-> __end__;
|
||||
model -.-> tools;
|
||||
pre_model_hook --> model;
|
||||
tools --> pre_model_hook;
|
||||
|
||||
'''
|
||||
@@ -40,8 +40,8 @@
|
||||
# name: test_react_agent_graph_structure[post_model_hook-None-tools0]
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> agent;
|
||||
agent --> post_model_hook;
|
||||
__start__ --> model;
|
||||
model --> post_model_hook;
|
||||
post_model_hook --> __end__;
|
||||
|
||||
'''
|
||||
@@ -49,12 +49,12 @@
|
||||
# name: test_react_agent_graph_structure[post_model_hook-None-tools1]
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> agent;
|
||||
agent --> post_model_hook;
|
||||
__start__ --> model;
|
||||
model --> post_model_hook;
|
||||
post_model_hook -.-> __end__;
|
||||
post_model_hook -.-> agent;
|
||||
post_model_hook -.-> model;
|
||||
post_model_hook -.-> tools;
|
||||
tools --> agent;
|
||||
tools --> model;
|
||||
|
||||
'''
|
||||
# ---
|
||||
@@ -62,8 +62,8 @@
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> pre_model_hook;
|
||||
agent --> post_model_hook;
|
||||
pre_model_hook --> agent;
|
||||
model --> post_model_hook;
|
||||
pre_model_hook --> model;
|
||||
post_model_hook --> __end__;
|
||||
|
||||
'''
|
||||
@@ -72,11 +72,11 @@
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> pre_model_hook;
|
||||
agent --> post_model_hook;
|
||||
model --> post_model_hook;
|
||||
post_model_hook -.-> __end__;
|
||||
post_model_hook -.-> pre_model_hook;
|
||||
post_model_hook -.-> tools;
|
||||
pre_model_hook --> agent;
|
||||
pre_model_hook --> model;
|
||||
tools --> pre_model_hook;
|
||||
|
||||
'''
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -4,7 +4,7 @@ import pytest
|
||||
from pydantic import BaseModel
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from langgraph.prebuilt import create_react_agent
|
||||
from langgraph.prebuilt import create_agent
|
||||
from tests.model import FakeToolCallingModel
|
||||
|
||||
model = FakeToolCallingModel()
|
||||
@@ -40,7 +40,7 @@ def test_react_agent_graph_structure(
|
||||
pre_model_hook: Union[Callable, None],
|
||||
post_model_hook: Union[Callable, None],
|
||||
) -> None:
|
||||
agent = create_react_agent(
|
||||
agent = create_agent(
|
||||
model,
|
||||
tools=tools,
|
||||
pre_model_hook=pre_model_hook,
|
||||
|
||||
Reference in New Issue
Block a user