@@ -176,8 +176,9 @@ def _validate_chat_history(
176
176
error_message = create_error_message (
177
177
message = "Found AIMessages with tool_calls that do not have a corresponding ToolMessage. "
178
178
f"Here are the first few of those tool calls: { tool_calls_without_results [:3 ]} .\n \n "
179
- "Every tool call (LLM requesting to call a tool) in the message history MUST have a corresponding ToolMessage "
180
- "(result of a tool invocation to return to the LLM) - this is required by most LLM providers." ,
179
+ "Every tool call (LLM requesting to call a tool) in the message history "
180
+ "MUST have a corresponding ToolMessage (result of a tool invocation to return to the LLM) -"
181
+ " this is required by most LLM providers." ,
181
182
error_code = ErrorCode .INVALID_CHAT_HISTORY ,
182
183
)
183
184
raise ValueError (error_message )
@@ -216,7 +217,8 @@ def __init__(
216
217
if isinstance (model , Runnable ) and not isinstance (model , BaseChatModel ):
217
218
msg = (
218
219
"Expected `model` to be a BaseChatModel or a string, got {type(model)}."
219
- "The `model` parameter should not have pre-bound tools, simply pass the model and tools separately."
220
+ "The `model` parameter should not have pre-bound tools, "
221
+ "simply pass the model and tools separately."
220
222
)
221
223
raise ValueError (msg )
222
224
@@ -308,7 +310,8 @@ def _handle_structured_response_tool_calls(self, response: AIMessage) -> Command
308
310
Command with structured response update if found, None otherwise
309
311
310
312
Raises:
311
- MultipleStructuredOutputsError: If multiple structured responses are returned and error handling is disabled
313
+ MultipleStructuredOutputsError: If multiple structured responses are returned
314
+ and error handling is disabled
312
315
StructuredOutputParsingError: If parsing fails and error handling is disabled
313
316
"""
314
317
if not isinstance (self .response_format , ToolStrategy ) or not response .tool_calls :
@@ -452,7 +455,11 @@ def _apply_native_output_binding(self, model: LanguageModelLike) -> LanguageMode
452
455
return model .bind (** kwargs )
453
456
454
457
def _handle_structured_response_native (self , response : AIMessage ) -> Command | None :
455
- """If native output is configured and there are no tool calls, parse using ProviderStrategyBinding."""
458
+ """Handle structured output using the native output.
459
+
460
+ If native output is configured and there are no tool calls,
461
+ parse using ProviderStrategyBinding.
462
+ """
456
463
if self .native_output_binding is None :
457
464
return None
458
465
if response .tool_calls :
@@ -922,7 +929,8 @@ def create_agent( # noqa: D417
922
929
) -> CompiledStateGraph [StateT , ContextT ]:
923
930
"""Creates an agent graph that calls tools in a loop until a stopping condition is met.
924
931
925
- For more details on using `create_agent`, visit [Agents](https://langchain-ai.github.io/langgraph/agents/overview/) documentation.
932
+ For more details on using `create_agent`,
933
+ visit [Agents](https://langchain-ai.github.io/langgraph/agents/overview/) documentation.
926
934
927
935
Args:
928
936
model: The language model for the agent. Supports static and dynamic
@@ -969,25 +977,35 @@ def select_model(state: AgentState, runtime: Runtime[ModelContext]) -> ChatOpenA
969
977
must be a subset of those specified in the `tools` parameter.
970
978
971
979
tools: A list of tools or a ToolNode instance.
972
- If an empty list is provided, the agent will consist of a single LLM node without tool calling.
980
+ If an empty list is provided, the agent will consist of a single LLM node
981
+ without tool calling.
973
982
prompt: An optional prompt for the LLM. Can take a few different forms:
974
983
975
- - str: This is converted to a SystemMessage and added to the beginning of the list of messages in state["messages"].
976
- - SystemMessage: this is added to the beginning of the list of messages in state["messages"].
977
- - Callable: This function should take in full graph state and the output is then passed to the language model.
978
- - Runnable: This runnable should take in full graph state and the output is then passed to the language model.
984
+ - str: This is converted to a SystemMessage and added to the beginning
985
+ of the list of messages in state["messages"].
986
+ - SystemMessage: this is added to the beginning of the list of messages
987
+ in state["messages"].
988
+ - Callable: This function should take in full graph state and the output is then passed
989
+ to the language model.
990
+ - Runnable: This runnable should take in full graph state and the output is then passed
991
+ to the language model.
979
992
980
993
response_format: An optional UsingToolStrategy configuration for structured responses.
981
994
982
- If provided, the agent will handle structured output via tool calls during the normal conversation flow.
983
- When the model calls a structured output tool, the response will be captured and returned in the 'structured_response' state key.
995
+ If provided, the agent will handle structured output via tool calls
996
+ during the normal conversation flow.
997
+ When the model calls a structured output tool, the response will be captured
998
+ and returned in the 'structured_response' state key.
984
999
If not provided, `structured_response` will not be present in the output state.
985
1000
986
1001
The UsingToolStrategy should contain:
987
- - schemas: A sequence of ResponseSchema objects that define the structured output format
1002
+
1003
+ - schemas: A sequence of ResponseSchema objects that define
1004
+ the structured output format
988
1005
- tool_choice: Either "required" or "auto" to control when structured output is used
989
1006
990
1007
Each ResponseSchema contains:
1008
+
991
1009
- schema: A Pydantic model that defines the structure
992
1010
- name: Optional custom name for the tool (defaults to model name)
993
1011
- description: Optional custom description (defaults to model docstring)
@@ -997,11 +1015,15 @@ def select_model(state: AgentState, runtime: Runtime[ModelContext]) -> ChatOpenA
997
1015
`response_format` requires the model to support tool calling
998
1016
999
1017
!!! Note
1000
- Structured responses are handled directly in the model call node via tool calls, eliminating the need for separate structured response nodes.
1001
-
1002
- pre_model_hook: An optional node to add before the `agent` node (i.e., the node that calls the LLM).
1003
- Useful for managing long message histories (e.g., message trimming, summarization, etc.).
1004
- Pre-model hook must be a callable or a runnable that takes in current graph state and returns a state update in the form of
1018
+ Structured responses are handled directly in the model call node via tool calls,
1019
+ eliminating the need for separate structured response nodes.
1020
+
1021
+ pre_model_hook: An optional node to add before the `agent` node
1022
+ (i.e., the node that calls the LLM).
1023
+ Useful for managing long message histories
1024
+ (e.g., message trimming, summarization, etc.).
1025
+ Pre-model hook must be a callable or a runnable that takes in current
1026
+ graph state and returns a state update in the form of
1005
1027
```python
1006
1028
# At least one of `messages` or `llm_input_messages` MUST be provided
1007
1029
{
@@ -1016,21 +1038,26 @@ def select_model(state: AgentState, runtime: Runtime[ModelContext]) -> ChatOpenA
1016
1038
```
1017
1039
1018
1040
!!! Important
1019
- At least one of `messages` or `llm_input_messages` MUST be provided and will be used as an input to the `agent` node.
1041
+ At least one of `messages` or `llm_input_messages` MUST be provided
1042
+ and will be used as an input to the `agent` node.
1020
1043
The rest of the keys will be added to the graph state.
1021
1044
1022
1045
!!! Warning
1023
- If you are returning `messages` in the pre-model hook, you should OVERWRITE the `messages` key by doing the following:
1046
+ If you are returning `messages` in the pre-model hook,
1047
+ you should OVERWRITE the `messages` key by doing the following:
1024
1048
1025
1049
```python
1026
1050
{
1027
1051
"messages": [RemoveMessage(id=REMOVE_ALL_MESSAGES), *new_messages]
1028
1052
...
1029
1053
}
1030
1054
```
1031
- post_model_hook: An optional node to add after the `agent` node (i.e., the node that calls the LLM).
1032
- Useful for implementing human-in-the-loop, guardrails, validation, or other post-processing.
1033
- Post-model hook must be a callable or a runnable that takes in current graph state and returns a state update.
1055
+ post_model_hook: An optional node to add after the `agent` node
1056
+ (i.e., the node that calls the LLM).
1057
+ Useful for implementing human-in-the-loop, guardrails, validation,
1058
+ or other post-processing.
1059
+ Post-model hook must be a callable or a runnable that takes in
1060
+ current graph state and returns a state update.
1034
1061
1035
1062
!!! Note
1036
1063
Only available with `version="v2"`.
@@ -1039,12 +1066,14 @@ def select_model(state: AgentState, runtime: Runtime[ModelContext]) -> ChatOpenA
1039
1066
Defaults to `AgentState` that defines those two keys.
1040
1067
context_schema: An optional schema for runtime context.
1041
1068
checkpointer: An optional checkpoint saver object. This is used for persisting
1042
- the state of the graph (e.g., as chat memory) for a single thread (e.g., a single conversation).
1069
+ the state of the graph (e.g., as chat memory) for a single thread
1070
+ (e.g., a single conversation).
1043
1071
store: An optional store object. This is used for persisting data
1044
1072
across multiple threads (e.g., multiple conversations / users).
1045
1073
interrupt_before: An optional list of node names to interrupt before.
1046
1074
Should be one of the following: "agent", "tools".
1047
- This is useful if you want to add a user confirmation or other interrupt before taking an action.
1075
+ This is useful if you want to add a user confirmation or other interrupt
1076
+ before taking an action.
1048
1077
interrupt_after: An optional list of node names to interrupt after.
1049
1078
Should be one of the following: "agent", "tools".
1050
1079
This is useful if you want to return directly or run additional processing on an output.
@@ -1059,7 +1088,8 @@ def select_model(state: AgentState, runtime: Runtime[ModelContext]) -> ChatOpenA
1059
1088
node using the [Send](https://langchain-ai.github.io/langgraph/concepts/low_level/#send)
1060
1089
API.
1061
1090
name: An optional name for the CompiledStateGraph.
1062
- This name will be automatically used when adding ReAct agent graph to another graph as a subgraph node -
1091
+ This name will be automatically used when adding ReAct agent graph to
1092
+ another graph as a subgraph node -
1063
1093
particularly useful for building multi-agent systems.
1064
1094
1065
1095
!!! warning "`config_schema` Deprecated"
@@ -1071,9 +1101,11 @@ def select_model(state: AgentState, runtime: Runtime[ModelContext]) -> ChatOpenA
1071
1101
A compiled LangChain runnable that can be used for chat interactions.
1072
1102
1073
1103
The "agent" node calls the language model with the messages list (after applying the prompt).
1074
- If the resulting AIMessage contains `tool_calls`, the graph will then call the ["tools"][langgraph.prebuilt.tool_node.ToolNode].
1075
- The "tools" node executes the tools (1 tool per `tool_call`) and adds the responses to the messages list
1076
- as `ToolMessage` objects. The agent node then calls the language model again.
1104
+ If the resulting AIMessage contains `tool_calls`,
1105
+ the graph will then call the ["tools"][langgraph.prebuilt.tool_node.ToolNode].
1106
+ The "tools" node executes the tools (1 tool per `tool_call`)
1107
+ and adds the responses to the messages list as `ToolMessage` objects.
1108
+ The agent node then calls the language model again.
1077
1109
The process repeats until no more `tool_calls` are present in the response.
1078
1110
The agent then returns the full list of messages as a dictionary containing the key "messages".
1079
1111
@@ -1135,7 +1167,8 @@ def check_weather(location: str) -> str:
1135
1167
# Handle deprecated config_schema parameter
1136
1168
if (config_schema := deprecated_kwargs .pop ("config_schema" , MISSING )) is not MISSING :
1137
1169
warn (
1138
- "`config_schema` is deprecated and will be removed. Please use `context_schema` instead." ,
1170
+ "`config_schema` is deprecated and will be removed. "
1171
+ "Please use `context_schema` instead." ,
1139
1172
category = DeprecationWarning ,
1140
1173
stacklevel = 2 ,
1141
1174
)
0 commit comments