mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-13 13:17:52 +02:00
docs: subgraphs manage state (#1543)
This commit is contained in:
@@ -30,6 +30,7 @@ _MANUAL = {
|
||||
"input_output_schema.ipynb",
|
||||
"pass_private_state.ipynb",
|
||||
"memory/manage-conversation-history.ipynb",
|
||||
"subgraphs-manage-state.ipynb",
|
||||
"memory/delete-messages.ipynb",
|
||||
"memory/add-summary-conversation-history.ipynb",
|
||||
"persistence_postgres.ipynb",
|
||||
|
||||
@@ -12,7 +12,6 @@ Welcome to the LangGraph how-to guides! These guides provide practical, step-by-
|
||||
LangGraph is known for being a highly controllable agent framework.
|
||||
These how-to guides show how to achieve that controllability.
|
||||
|
||||
- [How to create subgraphs](subgraph.ipynb)
|
||||
- [How to create branches for parallel execution](branching.ipynb)
|
||||
- [How to create map-reduce branches for parallel execution](map-reduce.ipynb)
|
||||
- [How to control graph recursion limit](recursion-limit.ipynb)
|
||||
@@ -64,6 +63,11 @@ These guides show how to use different streaming modes.
|
||||
- [How to pass config to tools](pass-config-to-tools.ipynb)
|
||||
- [How to handle large numbers of tools](many-tools.ipynb)
|
||||
|
||||
## Subgraphs
|
||||
|
||||
- [How to create subgraphs](subgraph.ipynb)
|
||||
- [How to manage state in subgraphs](subgraphs-manage-state.ipynb)
|
||||
|
||||
## State Management
|
||||
|
||||
- [Use Pydantic model as state](state-model.ipynb)
|
||||
|
||||
+3
-1
@@ -126,7 +126,6 @@ nav:
|
||||
- "How-to Guides":
|
||||
- "how-tos/index.md"
|
||||
- Controllability:
|
||||
- Create subgraphs: how-tos/subgraph.ipynb
|
||||
- Create branches for parallel execution: how-tos/branching.ipynb
|
||||
- Create map-reduce branches for parallel execution: how-tos/map-reduce.ipynb
|
||||
- Control graph recursion limit: how-tos/recursion-limit.ipynb
|
||||
@@ -161,6 +160,9 @@ nav:
|
||||
- Pass graph state to tools: how-tos/pass-run-time-values-to-tools.ipynb
|
||||
- Pass config to tools: how-tos/pass-config-to-tools.ipynb
|
||||
- Handle many tools: how-tos/many-tools.ipynb
|
||||
- Subgraphs:
|
||||
- Create subgraphs: how-tos/subgraph.ipynb
|
||||
- Manage state in subgraphs: how-tos/subgraphs-manage-state.ipynb
|
||||
- State Management:
|
||||
- Use Pydantic model as state: how-tos/state-model.ipynb
|
||||
- Use a context object in state: how-tos/state-context-key.ipynb
|
||||
|
||||
File diff suppressed because one or more lines are too long
+236
-34
@@ -46,7 +46,10 @@
|
||||
"id": "af4ce0ba-7596-4e5f-8bf8-0b0bd6e62833",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["%%capture --no-stderr\n%pip install --quiet -U langgraph langchain_openai"]
|
||||
"source": [
|
||||
"%%capture --no-stderr\n",
|
||||
"%pip install --quiet -U langgraph langchain_openai"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -62,7 +65,18 @@
|
||||
"id": "c903a1cf-2977-4e2d-ad7d-8b3946821d89",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["import getpass\nimport os\n\n\ndef _set_env(var: str):\n if not os.environ.get(var):\n os.environ[var] = getpass.getpass(f\"{var}: \")\n\n\n_set_env(\"ANTHROPIC_API_KEY\")"]
|
||||
"source": [
|
||||
"import getpass\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _set_env(var: str):\n",
|
||||
" if not os.environ.get(var):\n",
|
||||
" os.environ[var] = getpass.getpass(f\"{var}: \")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"_set_env(\"OPENAI_API_KEY\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -78,7 +92,10 @@
|
||||
"id": "95e25aec-7c9f-4a63-b143-225d0e9a79c3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n_set_env(\"LANGCHAIN_API_KEY\")"]
|
||||
"source": [
|
||||
"os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
|
||||
"_set_env(\"LANGCHAIN_API_KEY\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -96,7 +113,22 @@
|
||||
"id": "f5319e01",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from typing import Annotated\n\nfrom typing_extensions import TypedDict\n\nfrom langgraph.graph.message import add_messages\n\n# `add_messages`` essentially does this\n# (with more robust handling)\n# def add_messages(left: list, right: list):\n# return left + right\n\n\nclass State(TypedDict):\n messages: Annotated[list, add_messages]"]
|
||||
"source": [
|
||||
"from typing import Annotated\n",
|
||||
"\n",
|
||||
"from typing_extensions import TypedDict\n",
|
||||
"\n",
|
||||
"from langgraph.graph.message import add_messages\n",
|
||||
"\n",
|
||||
"# `add_messages`` essentially does this\n",
|
||||
"# (with more robust handling)\n",
|
||||
"# def add_messages(left: list, right: list):\n",
|
||||
"# return left + right\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class State(TypedDict):\n",
|
||||
" messages: Annotated[list, add_messages]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -116,7 +148,19 @@
|
||||
"id": "d7ef57dd-5d6e-4ad3-9377-a92201c1310e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from langchain_core.tools import tool\n\n\n@tool\ndef search(query: str):\n \"\"\"Call to surf the web.\"\"\"\n # This is a placeholder for the actual implementation\n return [\"The weather is cloudy with a chance of meatballs.\"]\n\n\ntools = [search]"]
|
||||
"source": [
|
||||
"from langchain_core.tools import tool\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"@tool\n",
|
||||
"def search(query: str):\n",
|
||||
" \"\"\"Call to surf the web.\"\"\"\n",
|
||||
" # This is a placeholder for the actual implementation\n",
|
||||
" return [\"The weather is cloudy with a chance of meatballs.\"]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"tools = [search]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -133,7 +177,11 @@
|
||||
"id": "5cf3331e-ccb3-41c8-aeb9-a840a94d41e7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from langgraph.prebuilt import ToolNode\n\ntool_node = ToolNode(tools)"]
|
||||
"source": [
|
||||
"from langgraph.prebuilt import ToolNode\n",
|
||||
"\n",
|
||||
"tool_node = ToolNode(tools)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -157,7 +205,11 @@
|
||||
"id": "892b54b9-75f0-4804-9ed0-88b5e5532989",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from langchain_openai import ChatOpenAI\n\nmodel = ChatOpenAI(temperature=0)"]
|
||||
"source": [
|
||||
"from langchain_openai import ChatOpenAI\n",
|
||||
"\n",
|
||||
"model = ChatOpenAI(temperature=0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -175,7 +227,9 @@
|
||||
"id": "cd3cbae5-d92c-4559-a4aa-44721b80d107",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["model = model.bind_tools(tools)"]
|
||||
"source": [
|
||||
"model = model.bind_tools(tools)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -210,7 +264,20 @@
|
||||
"id": "3b541bb9-900c-40d0-964d-7b5dfee30667",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from typing import Literal\n\n\n# Define the function that determines whether to continue or not\ndef should_continue(state: State) -> Literal[\"continue\", \"end\"]:\n last_message = state[\"messages\"][-1]\n # If there is no function call, then we finish\n if not last_message.tool_calls:\n return \"end\"\n # Otherwise if there is, we continue\n else:\n return \"continue\""]
|
||||
"source": [
|
||||
"from typing import Literal\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Define the function that determines whether to continue or not\n",
|
||||
"def should_continue(state: State) -> Literal[\"continue\", \"end\"]:\n",
|
||||
" last_message = state[\"messages\"][-1]\n",
|
||||
" # If there is no function call, then we finish\n",
|
||||
" if not last_message.tool_calls:\n",
|
||||
" return \"end\"\n",
|
||||
" # Otherwise if there is, we continue\n",
|
||||
" else:\n",
|
||||
" return \"continue\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -228,7 +295,50 @@
|
||||
"id": "812b4e70-4956-4415-8880-db48b3dcbad2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from langgraph.graph import END, StateGraph, START\n\n# Define a new graph\nworkflow = StateGraph(State)\n\n\n# Define the two nodes we will cycle between\ndef call_model(state: State) -> State:\n return {\"messages\": model.invoke(state[\"messages\"])}\n\n\nworkflow.add_node(\"agent\", call_model)\nworkflow.add_node(\"action\", tool_node)\n\n# Set the entrypoint as `agent`\n# This means that this node is the first one called\nworkflow.add_edge(START, \"agent\")\n\n# We now add a conditional edge\nworkflow.add_conditional_edges(\n # First, we define the start node. We use `agent`.\n # This means these are the edges taken after the `agent` node is called.\n \"agent\",\n # Next, we pass in the function that will determine which node is called next.\n should_continue,\n # Finally we pass in a mapping.\n # The keys are strings, and the values are other nodes.\n # END is a special node marking that the graph should finish.\n # What will happen is we will call `should_continue`, and then the output of that\n # will be matched against the keys in this mapping.\n # Based on which one it matches, that node will then be called.\n {\n # If `tools`, then we call the tool node.\n \"continue\": \"action\",\n # Otherwise we finish.\n \"end\": END,\n },\n)\n\n# We now add a normal edge from `tools` to `agent`.\n# This means that after `tools` is called, `agent` node is called next.\nworkflow.add_edge(\"action\", \"agent\")"]
|
||||
"source": [
|
||||
"from langgraph.graph import END, StateGraph, START\n",
|
||||
"\n",
|
||||
"# Define a new graph\n",
|
||||
"workflow = StateGraph(State)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Define the two nodes we will cycle between\n",
|
||||
"def call_model(state: State) -> State:\n",
|
||||
" return {\"messages\": model.invoke(state[\"messages\"])}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"workflow.add_node(\"agent\", call_model)\n",
|
||||
"workflow.add_node(\"action\", tool_node)\n",
|
||||
"\n",
|
||||
"# Set the entrypoint as `agent`\n",
|
||||
"# This means that this node is the first one called\n",
|
||||
"workflow.add_edge(START, \"agent\")\n",
|
||||
"\n",
|
||||
"# We now add a conditional edge\n",
|
||||
"workflow.add_conditional_edges(\n",
|
||||
" # First, we define the start node. We use `agent`.\n",
|
||||
" # This means these are the edges taken after the `agent` node is called.\n",
|
||||
" \"agent\",\n",
|
||||
" # Next, we pass in the function that will determine which node is called next.\n",
|
||||
" should_continue,\n",
|
||||
" # Finally we pass in a mapping.\n",
|
||||
" # The keys are strings, and the values are other nodes.\n",
|
||||
" # END is a special node marking that the graph should finish.\n",
|
||||
" # What will happen is we will call `should_continue`, and then the output of that\n",
|
||||
" # will be matched against the keys in this mapping.\n",
|
||||
" # Based on which one it matches, that node will then be called.\n",
|
||||
" {\n",
|
||||
" # If `tools`, then we call the tool node.\n",
|
||||
" \"continue\": \"action\",\n",
|
||||
" # Otherwise we finish.\n",
|
||||
" \"end\": END,\n",
|
||||
" },\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# We now add a normal edge from `tools` to `agent`.\n",
|
||||
"# This means that after `tools` is called, `agent` node is called next.\n",
|
||||
"workflow.add_edge(\"action\", \"agent\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -246,7 +356,11 @@
|
||||
"id": "6845ed6a-d155-4105-9160-28849877248b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from langgraph.checkpoint.memory import MemorySaver\n\nmemory = MemorySaver()"]
|
||||
"source": [
|
||||
"from langgraph.checkpoint.memory import MemorySaver\n",
|
||||
"\n",
|
||||
"memory = MemorySaver()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -254,7 +368,12 @@
|
||||
"id": "79d29875-8aa8-434c-9f20-1c58346a6249",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["# Finally, we compile it!\n# This compiles it into a LangChain Runnable,\n# meaning you can use it as you would any other runnable\napp = workflow.compile(checkpointer=memory)"]
|
||||
"source": [
|
||||
"# Finally, we compile it!\n",
|
||||
"# This compiles it into a LangChain Runnable,\n",
|
||||
"# meaning you can use it as you would any other runnable\n",
|
||||
"app = workflow.compile(checkpointer=memory)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -281,7 +400,15 @@
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": ["from IPython.display import Image, display\n\ntry:\n display(Image(app.get_graph().draw_mermaid_png()))\nexcept Exception:\n # This requires some extra dependencies and is optional\n pass"]
|
||||
"source": [
|
||||
"from IPython.display import Image, display\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" display(Image(app.get_graph().draw_mermaid_png()))\n",
|
||||
"except Exception:\n",
|
||||
" # This requires some extra dependencies and is optional\n",
|
||||
" pass"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -312,7 +439,14 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": ["from langchain_core.messages import HumanMessage\n\nconfig = {\"configurable\": {\"thread_id\": \"2\"}}\ninput_message = HumanMessage(content=\"hi! I'm bob\")\nfor event in app.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n event[\"messages\"][-1].pretty_print()"]
|
||||
"source": [
|
||||
"from langchain_core.messages import HumanMessage\n",
|
||||
"\n",
|
||||
"config = {\"configurable\": {\"thread_id\": \"2\"}}\n",
|
||||
"input_message = HumanMessage(content=\"hi! I'm bob\")\n",
|
||||
"for event in app.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n",
|
||||
" event[\"messages\"][-1].pretty_print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -350,7 +484,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["app.get_state(config).values"]
|
||||
"source": [
|
||||
"app.get_state(config).values"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -379,7 +515,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["app.get_state(config).next"]
|
||||
"source": [
|
||||
"app.get_state(config).next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -426,7 +564,12 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": ["config = {\"configurable\": {\"thread_id\": \"2\"}}\ninput_message = HumanMessage(content=\"what is the weather in sf currently\")\nfor event in app.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n event[\"messages\"][-1].pretty_print()"]
|
||||
"source": [
|
||||
"config = {\"configurable\": {\"thread_id\": \"2\"}}\n",
|
||||
"input_message = HumanMessage(content=\"what is the weather in sf currently\")\n",
|
||||
"for event in app.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n",
|
||||
" event[\"messages\"][-1].pretty_print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -466,7 +609,9 @@
|
||||
"id": "5a68afc0-606f-4294-a872-b2b563be0d69",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["app_w_interrupt = workflow.compile(checkpointer=memory, interrupt_before=[\"action\"])"]
|
||||
"source": [
|
||||
"app_w_interrupt = workflow.compile(checkpointer=memory, interrupt_before=[\"action\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -490,7 +635,14 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": ["config = {\"configurable\": {\"thread_id\": \"4\"}}\ninput_message = HumanMessage(content=\"what is the weather in sf currently\")\nfor event in app_w_interrupt.stream(\n {\"messages\": [input_message]}, config, stream_mode=\"values\"\n):\n event[\"messages\"][-1].pretty_print()"]
|
||||
"source": [
|
||||
"config = {\"configurable\": {\"thread_id\": \"4\"}}\n",
|
||||
"input_message = HumanMessage(content=\"what is the weather in sf currently\")\n",
|
||||
"for event in app_w_interrupt.stream(\n",
|
||||
" {\"messages\": [input_message]}, config, stream_mode=\"values\"\n",
|
||||
"):\n",
|
||||
" event[\"messages\"][-1].pretty_print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -526,7 +678,10 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["current_values = app_w_interrupt.get_state(config)\ncurrent_values.next"]
|
||||
"source": [
|
||||
"current_values = app_w_interrupt.get_state(config)\n",
|
||||
"current_values.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -555,7 +710,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["current_values.values[\"messages\"][-1].tool_calls"]
|
||||
"source": [
|
||||
"current_values.values[\"messages\"][-1].tool_calls"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -571,7 +728,11 @@
|
||||
"id": "060e2e33-1f6a-40ef-850e-161b308986fb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\n \"query\"\n] = \"weather in San Francisco today\""]
|
||||
"source": [
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\n",
|
||||
" \"query\"\n",
|
||||
"] = \"weather in San Francisco today\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -591,7 +752,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["app_w_interrupt.update_state(config, current_values.values)"]
|
||||
"source": [
|
||||
"app_w_interrupt.update_state(config, current_values.values)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -629,7 +792,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["app_w_interrupt.get_state(config).values"]
|
||||
"source": [
|
||||
"app_w_interrupt.get_state(config).values"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -648,7 +813,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["app_w_interrupt.get_state(config).next"]
|
||||
"source": [
|
||||
"app_w_interrupt.get_state(config).next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -679,7 +846,11 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": ["for event in app_w_interrupt.stream(None, config):\n for v in event.values():\n print(v)"]
|
||||
"source": [
|
||||
"for event in app_w_interrupt.stream(None, config):\n",
|
||||
" for v in event.values():\n",
|
||||
" print(v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -726,7 +897,13 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": ["for state in app_w_interrupt.get_state_history(config):\n print(state)\n print(\"--\")\n if len(state.values[\"messages\"]) == 2:\n to_replay = state"]
|
||||
"source": [
|
||||
"for state in app_w_interrupt.get_state_history(config):\n",
|
||||
" print(state)\n",
|
||||
" print(\"--\")\n",
|
||||
" if len(state.values[\"messages\"]) == 2:\n",
|
||||
" to_replay = state"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -754,7 +931,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["to_replay.values"]
|
||||
"source": [
|
||||
"to_replay.values"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -773,7 +952,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["to_replay.next"]
|
||||
"source": [
|
||||
"to_replay.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -806,7 +987,11 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": ["for event in app_w_interrupt.stream(None, to_replay.config):\n for v in event.values():\n print(v)"]
|
||||
"source": [
|
||||
"for event in app_w_interrupt.stream(None, to_replay.config):\n",
|
||||
" for v in event.values():\n",
|
||||
" print(v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -834,7 +1019,18 @@
|
||||
"id": "b084f141-5800-487b-b115-d2e58421b963",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["from langchain_core.messages import AIMessage\n\nbranch_config = app_w_interrupt.update_state(\n to_replay.config,\n {\n \"messages\": [\n AIMessage(content=\"All done here!\", id=to_replay.values[\"messages\"][-1].id)\n ]\n },\n)"]
|
||||
"source": [
|
||||
"from langchain_core.messages import AIMessage\n",
|
||||
"\n",
|
||||
"branch_config = app_w_interrupt.update_state(\n",
|
||||
" to_replay.config,\n",
|
||||
" {\n",
|
||||
" \"messages\": [\n",
|
||||
" AIMessage(content=\"All done here!\", id=to_replay.values[\"messages\"][-1].id)\n",
|
||||
" ]\n",
|
||||
" },\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -842,7 +1038,9 @@
|
||||
"id": "1a7cfcd4-289e-419e-8b49-dfaef4f88641",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": ["branch_state = app_w_interrupt.get_state(branch_config)"]
|
||||
"source": [
|
||||
"branch_state = app_w_interrupt.get_state(branch_config)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -862,7 +1060,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["branch_state.values"]
|
||||
"source": [
|
||||
"branch_state.values"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -881,7 +1081,9 @@
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": ["branch_state.next"]
|
||||
"source": [
|
||||
"branch_state.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
|
||||
Reference in New Issue
Block a user