From eb09909c22c7654811ddb4fb654afb33d05a4f70 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 17:21:31 -0500 Subject: [PATCH 01/72] x --- docs/docs/reference/types.md | 1 + libs/langgraph/langgraph/types.py | 35 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/docs/docs/reference/types.md b/docs/docs/reference/types.md index 347a87d6e..06a6ac2a5 100644 --- a/docs/docs/reference/types.md +++ b/docs/docs/reference/types.md @@ -13,3 +13,4 @@ - PregelExecutableTask - StateSnapshot - Send + - interrupt diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index 7bf9148c5..8a614f458 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -301,6 +301,41 @@ class LoopProtocol: def interrupt(value: Any) -> Any: + """Interrupt the graph with a resumable exception from within a node. + + The interrupt function is used for supporting human-in-the-loop workflows. + + It can be thought of as an equivalent to the python's built-in `input` function. + + In a given node, the first invocation of this function raises a `GraphInterrupt` + exception. The `value` argument is passed to the exception and can be used to + communicate information to the client executing the graph. + + The client can choose to resume the graph from the same node provide a value to + resume with. + + + The client will use the `Command` primitive to + resume graph execution. + + graph.astream(Command(resume="answer 1", update={"my_key": "foofoo"}), config, stream_mode="updates") + + + The first invocation of this function raises a `GraphInterrupt` exception + + The first occurrence of this function in a node raises a `GraphInterrupt` + exception with the given value. + + A client executing the graph will receive the value and can choose to + resume the graph from the same node with a value. + + Args: + value: The value to interrupt the graph with. + + Returns: + On a first call, raises a `GraphInterrupt` exception with the given value. + On subsequent calls from the same node, returns the value to resume with. + """ from langgraph.constants import ( CONFIG_KEY_CHECKPOINT_NS, CONFIG_KEY_RESUME_VALUE, From 6dc70b703d90239074c709d3c8d3b479047bab65 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 17:21:47 -0500 Subject: [PATCH 02/72] x --- .../how-tos/human_in_the_loop/interrupt.ipynb | 487 ++++++++++++++++++ 1 file changed, 487 insertions(+) create mode 100644 docs/docs/how-tos/human_in_the_loop/interrupt.ipynb diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb new file mode 100644 index 000000000..06d448511 --- /dev/null +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -0,0 +1,487 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0ff51c4b-5d5c-4b6e-8478-0ea489adb689", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# How to use `interrupt` for human-in-the-loop workflows\n", + "\n", + "To use an `interrupt` you must pass a checkpointer.\n", + "\n", + "1. Used with checkpointers\n", + "1. Used together with `Command` to resume.\n", + "2. Interrupt information is available when streaming. If using invoke with human in the loop need to inspect next\n", + "3. Cannot be used twice in a node.\n", + "\n", + "An interrupt can be used within a node like this:\n", + "\n", + "```python\n", + "async def some_node(state: State):\n", + " ...\n", + " # Any value that we want to surface as part of the interrupt\n", + " value = {\"foo\": \"bar\"} \n", + " answer = interrupt(value)\n", + " ...\n", + "```\n", + "\n", + "Graph execution willbe interrupted when the code reaches\n", + "the `interrup` function. It can be resumed by passing `Command`.\n", + "\n", + "```python\n", + "graph.invoke(Command(resume=some_value)))\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "17ecd33b-7879-47a8-9ad3-0b4ce1fdc0c9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Setup\n", + "\n", + "First we need to install the packages required" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "cbc003a6-b45f-4526-bcf1-963d951797ae", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "%%capture --no-stderr\n", + "%pip install --quiet -U langgraph" + ] + }, + { + "cell_type": "markdown", + "id": "7091bfdc-2754-4b3c-83b9-20cfb1d2be66", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "
\n", + "

Set up LangSmith for LangGraph development

\n", + "

\n", + " Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started here. \n", + "

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "8aa9eb6a-d54f-40e9-a618-0ad7290d15dc", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Interrupt and resume\n", + "\n", + "Here is a minimal example that shows how to `interrupt` and `resume` a graph consisting of one node." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ce902820-2739-402f-a784-867a44a3997c", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 1 # of times\n", + "{'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:d82f393c-4bba-241b-22aa-0cd65a88fd8b'], when='during'),)}\n" + ] + } + ], + "source": [ + "import uuid\n", + "import operator\n", + "from typing import TypedDict, Annotated, Optional\n", + "\n", + "from langgraph.graph import StateGraph\n", + "from langgraph.constants import START, INTERRUPT\n", + "from langgraph.types import interrupt, Command\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "\n", + "class State(TypedDict):\n", + " \"\"\"The graph state.\"\"\"\n", + " foo: str\n", + " human_value: Optional[str]\n", + " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", + " \n", + "counter = 0\n", + "\n", + "def node(state: State):\n", + " global counter\n", + " counter +=1 \n", + " print(f'> Entered the node: {counter} # of times')\n", + " answer = interrupt(\n", + " # This value will be sent to the client\n", + " # as part of the interrupt inforamtion.\n", + " 'what is your age?'\n", + " )\n", + " print(f'> Received an input from the interrupt: {answer}')\n", + " return {\"human_value\": answer}\n", + "\n", + "builder = StateGraph(State)\n", + "builder.add_node(\"node\", node)\n", + "builder.add_edge(START, \"node\")\n", + "\n", + "# A checkpointer must be enabled for interrupts to work!\n", + "graph = builder.compile(checkpointer=MemorySaver())\n", + "\n", + "config = {\n", + " \"thread_id\": uuid.uuid4(),\n", + "}\n", + "\n", + "for chunk in graph.stream({\"foo\": \"abc\"}, config):\n", + " print(chunk)" + ] + }, + { + "cell_type": "markdown", + "id": "8df4319f-f7e8-40dc-8943-91fa3fad31a0", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "Let's resume graph execution from the given node:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "c2ea37d8-4b92-442d-85e1-212e20123907", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 2 # of times\n", + "> Received an input from the interrupt: some input from a human!!!\n", + "{'node': {'human_value': 'some input from a human!!!'}}\n" + ] + } + ], + "source": [ + "command = Command(resume=\"some input from a human!!!\")\n", + "\n", + "for chunk in graph.stream(Command(resume=\"some input from a human!!!\"), config):\n", + " print(chunk)" + ] + }, + { + "cell_type": "markdown", + "id": "0036a06d-c875-461b-917d-1cd48c233e7d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "!!! important \"Graph execution resumes at the start of a **node**\"\n", + "\n", + " Graph execution resumes from the **node** where the interrupt was raised rather than from the line where the `interrupt` was raised.\n", + "\n", + " As a result, you should see `> Entered the node: 2 # of times`." + ] + }, + { + "cell_type": "markdown", + "id": "9b40603f-5d01-41d7-afc7-2ead455a6803", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Validation of input with resume" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "id": "30b5821e-8bb8-4076-b477-60f39ea65445", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 1 # of times\n", + "{'__interrupt__': (Interrupt(value='What is your age?', resumable=True, ns=['node:a1c64b81-7957-8c3c-7728-e73cb81837d5'], when='during'),)}\n" + ] + } + ], + "source": [ + "import uuid\n", + "import operator\n", + "from typing import TypedDict, Annotated, Optional, Literal\n", + "\n", + "from langgraph.graph import StateGraph\n", + "from langgraph.graph.state import GraphCommand\n", + "from langgraph.constants import START, INTERRUPT\n", + "from langgraph.types import interrupt, Command\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "\n", + "\n", + "class State(TypedDict):\n", + " \"\"\"The graph state.\"\"\"\n", + " foo: str\n", + " human_value: Optional[str]\n", + " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", + " \n", + "\n", + "counter = 0\n", + "\n", + "def node(state: State) -> GraphCommand[Literal['node']]:\n", + " global counter\n", + " counter +=1 \n", + " print(f'> Entered the node: {counter} # of times')\n", + "\n", + " answer = interrupt(\n", + " \"What is your age?\"\n", + " )\n", + "\n", + " if not isinstance(answer, int) or answer < 0:\n", + " return GraphCommand(goto=\"node\")\n", + "\n", + " return GraphCommand(update={\"human_value\": answer})\n", + " \n", + "\n", + "builder = StateGraph(State)\n", + "builder.add_node(\"node\", node)\n", + "builder.add_edge(START, \"node\")\n", + "\n", + "# A checkpointer must be enabled for interrupts to work!\n", + "graph = builder.compile(checkpointer=MemorySaver())\n", + "\n", + "config = {\n", + " \"thread_id\": uuid.uuid4(),\n", + "}\n", + "\n", + "for chunk in graph.stream({\"foo\": \"abc\"}, config):\n", + " print(chunk)" + ] + }, + { + "cell_type": "markdown", + "id": "0d95194e-e9f2-4abf-83dc-c29b5f1f6f2d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "Let's resume with a bad input" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "id": "a79e330d-f849-44ea-af37-221efcffe1a3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 2 # of times\n", + "{'node': None}\n", + "> Entered the node: 3 # of times\n", + "{'__interrupt__': (Interrupt(value='What is your age?', resumable=True, ns=['node:995027b2-c8ad-8951-74ff-d9b86fca74bb'], when='during'),)}\n" + ] + } + ], + "source": [ + "bad_input = -20 # Negative number!\n", + "for chunk in graph.stream(Command(resume=bad_input), config):\n", + " print(chunk)" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "id": "c9d01c77-7a9c-43aa-bbfa-c969b1d3e3f2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "ok_input = 5\n", + "for chunk in graph.stream(Command(resume=ok_input), config):\n", + " print(chunk)" + ] + }, + { + "cell_type": "markdown", + "id": "c7181eea-a0a8-43df-8ce6-b2172ea6cb21", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Usage with invoke / ainvoke\n", + "\n", + "If you're not using `stream` or `astream`, you will need to explicitly access the state of the graph to get information about the interrupt." + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "id": "c9ae2c5f-c81d-4188-9f7e-f3f90e675e12", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 1 # of times\n" + ] + } + ], + "source": [ + "import uuid\n", + "import operator\n", + "from typing import TypedDict, Annotated, Optional\n", + "\n", + "from langgraph.graph import StateGraph\n", + "from langgraph.constants import START, INTERRUPT\n", + "from langgraph.types import interrupt, Command\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "\n", + "class State(TypedDict):\n", + " \"\"\"The graph state.\"\"\"\n", + " foo: str\n", + " human_value: Optional[str]\n", + " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", + " \n", + "counter = 0\n", + "\n", + "def node(state: State):\n", + " global counter\n", + " counter +=1 \n", + " print(f'> Entered the node: {counter} # of times')\n", + " answer = interrupt(\n", + " # This value will be sent to the client\n", + " # as part of the interrupt inforamtion.\n", + " 'what is your age?'\n", + " )\n", + " print(f'> Received an input from the interrupt: {answer}')\n", + " return {\"human_value\": answer}\n", + "\n", + "builder = StateGraph(State)\n", + "builder.add_node(\"node\", node)\n", + "builder.add_edge(START, \"node\")\n", + "\n", + "# A checkpointer must be enabled for interrupts to work!\n", + "graph = builder.compile(checkpointer=MemorySaver())\n", + "\n", + "config = {\n", + " \"thread_id\": uuid.uuid4(),\n", + "}\n", + "\n", + "for event in graph.invoke({\"foo\": \"abc\"}, config):\n", + " print" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c75bfc1032239848a1f4c7390a47d1903c67b5ad Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 17:22:09 -0500 Subject: [PATCH 03/72] x --- docs/docs/how-tos/human_in_the_loop/interrupt.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index 06d448511..fc8fd0966 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -109,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "id": "ce902820-2739-402f-a784-867a44a3997c", "metadata": { "editable": true, @@ -124,7 +124,7 @@ "output_type": "stream", "text": [ "> Entered the node: 1 # of times\n", - "{'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:d82f393c-4bba-241b-22aa-0cd65a88fd8b'], when='during'),)}\n" + "{'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:ec36fcc8-2135-a0e6-4681-fc0138772022'], when='during'),)}\n" ] } ], From 9f93e48a6742888d40291756f5144285f087bab4 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 22:19:32 -0500 Subject: [PATCH 04/72] x --- .../how-tos/human_in_the_loop/interrupt.ipynb | 218 ++++++++++++++---- 1 file changed, 168 insertions(+), 50 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index fc8fd0966..043e60c6b 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -11,32 +11,33 @@ "tags": [] }, "source": [ - "# How to use `interrupt` for human-in-the-loop workflows\n", + "# How to use interrupt for human-in-the-loop workflows\n", "\n", - "To use an `interrupt` you must pass a checkpointer.\n", + "An `interrupt` is a convenient way to support human-in-the-loop workflows.\n", "\n", - "1. Used with checkpointers\n", - "1. Used together with `Command` to resume.\n", - "2. Interrupt information is available when streaming. If using invoke with human in the loop need to inspect next\n", - "3. Cannot be used twice in a node.\n", + "To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state.\n", "\n", - "An interrupt can be used within a node like this:\n", + "An `interrupt` can be used within a node to pause execution and wait for input, as shown in this example:\n", "\n", "```python\n", "async def some_node(state: State):\n", " ...\n", - " # Any value that we want to surface as part of the interrupt\n", - " value = {\"foo\": \"bar\"} \n", + " # Surface any value as part of the interrupt\n", + " value = {\"question\": \"how old are you?\"} \n", " answer = interrupt(value)\n", " ...\n", "```\n", "\n", - "Graph execution willbe interrupted when the code reaches\n", - "the `interrup` function. It can be resumed by passing `Command`.\n", + "Graph execution will pause when the interrupt function is called. To resume execution, pass a `Command` with the desired resume value:\n", "\n", "```python\n", - "graph.invoke(Command(resume=some_value)))\n", - "```" + "for chunk in graph.stream(Command(resume=some_value), config={\"configurable\": {\"thread_id\": ...}}):\n", + " ...\n", + "```\n", + "\n", + "Remember that graph execution always restarts at the beginning of the node. Be cautious of side effects, such as API calls that mutate data, as these may inadvertently be triggered multiple times.\n", + "\n", + "When a node contains multiple interrupt calls, LangGraph maintains a list of resume values provided during graph execution. When resuming, execution always starts at the beginning of the node, and for each interrupt encountered, LangGraph checks whether a corresponding value exists in the list. Matching is strictly index-based, making the order of interrupt calls within the node critical. Users should avoid logic that dynamically removes, adds, or reorders interrupt calls between executions, as this can lead to mismatched indices. Such patterns often involve unconventional state mutations, such as altering state via `Command(resume=..., update=SOME_STATE_MUTATION)` or relying on global variables to modify the node's structure." ] }, { @@ -52,12 +53,12 @@ "source": [ "## Setup\n", "\n", - "First we need to install the packages required" + "First we need to install the required packages:" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 14, "id": "cbc003a6-b45f-4526-bcf1-963d951797ae", "metadata": { "editable": true, @@ -102,14 +103,14 @@ "tags": [] }, "source": [ - "## Interrupt and resume\n", + "## Basic usage of interrupt and Command\n", "\n", - "Here is a minimal example that shows how to `interrupt` and `resume` a graph consisting of one node." + "Here is an exmaple that shows how to use `interrupt` to interrupt the execution of a graph, and then resume the execution using the `Command` primitive." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "id": "ce902820-2739-402f-a784-867a44a3997c", "metadata": { "editable": true, @@ -124,7 +125,7 @@ "output_type": "stream", "text": [ "> Entered the node: 1 # of times\n", - "{'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:ec36fcc8-2135-a0e6-4681-fc0138772022'], when='during'),)}\n" + "{'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:62e598fa-8653-9d6d-2046-a70203020e37'], when='during'),)}\n" ] } ], @@ -163,10 +164,13 @@ "builder.add_edge(START, \"node\")\n", "\n", "# A checkpointer must be enabled for interrupts to work!\n", - "graph = builder.compile(checkpointer=MemorySaver())\n", + "checkpointer = MemorySaver()\n", + "graph = builder.compile(checkpointer=checkpointer)\n", "\n", "config = {\n", - " \"thread_id\": uuid.uuid4(),\n", + " \"configurable\": {\n", + " \"thread_id\": uuid.uuid4(),\n", + " }\n", "}\n", "\n", "for chunk in graph.stream({\"foo\": \"abc\"}, config):\n", @@ -189,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "id": "c2ea37d8-4b92-442d-85e1-212e20123907", "metadata": { "editable": true, @@ -227,11 +231,13 @@ "tags": [] }, "source": [ - "!!! important \"Graph execution resumes at the start of a **node**\"\n", + "!!! important \"Graph execution resumes at the start of a node\"\n", "\n", - " Graph execution resumes from the **node** where the interrupt was raised rather than from the line where the `interrupt` was raised.\n", + " Graph execution resumes from the start of the **node** where the interrupt was raised rather than from the line where the `interrupt` was raised.\n", "\n", - " As a result, you should see `> Entered the node: 2 # of times`." + " As a result, you should see that the node was entered 2 times rather than once!\n", + "\n", + " Exercise care if your code has side-effects like making mutable API calls between consecutive interrupts!" ] }, { @@ -245,12 +251,14 @@ "tags": [] }, "source": [ - "## Validation of input with resume" + "## Using multiple interrupts calls within a single node\n", + "\n", + "In some situations, you may need to use interrupt more than once within a single node. A common use case is performing runtime validation on the value supplied through `Command(resume=value)`." ] }, { "cell_type": "code", - "execution_count": 127, + "execution_count": 12, "id": "30b5821e-8bb8-4076-b477-60f39ea65445", "metadata": { "editable": true, @@ -265,7 +273,7 @@ "output_type": "stream", "text": [ "> Entered the node: 1 # of times\n", - "{'__interrupt__': (Interrupt(value='What is your age?', resumable=True, ns=['node:a1c64b81-7957-8c3c-7728-e73cb81837d5'], when='during'),)}\n" + "{'__interrupt__': (Interrupt(value='What is your age?', resumable=True, ns=['node:ed4d470f-5753-d7f3-eec6-4435f5f93f72'], when='during'),)}\n" ] } ], @@ -275,8 +283,7 @@ "from typing import TypedDict, Annotated, Optional, Literal\n", "\n", "from langgraph.graph import StateGraph\n", - "from langgraph.graph.state import GraphCommand\n", - "from langgraph.constants import START, INTERRUPT\n", + "from langgraph.constants import START\n", "from langgraph.types import interrupt, Command\n", "from langgraph.checkpoint.memory import MemorySaver\n", "\n", @@ -290,19 +297,30 @@ "\n", "counter = 0\n", "\n", - "def node(state: State) -> GraphCommand[Literal['node']]:\n", + "def node(state: State):\n", " global counter\n", " counter +=1 \n", " print(f'> Entered the node: {counter} # of times')\n", "\n", - " answer = interrupt(\n", - " \"What is your age?\"\n", - " )\n", + " answer = None\n", + " question = \"What is your age?\"\n", "\n", - " if not isinstance(answer, int) or answer < 0:\n", - " return GraphCommand(goto=\"node\")\n", + " while answer is None:\n", + " answer = interrupt(\n", + " question\n", + " )\n", + "\n", + " if not isinstance(answer, int) or answer < 0:\n", + " question = f\"'{answer} is not a valid age. What is your age?\"\n", + " answer = None\n", + " continue\n", + " else:\n", + " break\n", + "\n", + " return {\n", + " \"human_value\": f\"The human is {answer} years old.\"\n", + " }\n", "\n", - " return GraphCommand(update={\"human_value\": answer})\n", " \n", "\n", "builder = StateGraph(State)\n", @@ -310,10 +328,13 @@ "builder.add_edge(START, \"node\")\n", "\n", "# A checkpointer must be enabled for interrupts to work!\n", - "graph = builder.compile(checkpointer=MemorySaver())\n", + "checkpointer = MemorySaver()\n", + "graph = builder.compile(checkpointer=checkpointer)\n", "\n", "config = {\n", - " \"thread_id\": uuid.uuid4(),\n", + " \"configurable\": {\n", + " \"thread_id\": uuid.uuid4(),\n", + " }\n", "}\n", "\n", "for chunk in graph.stream({\"foo\": \"abc\"}, config):\n", @@ -336,7 +357,7 @@ }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 13, "id": "a79e330d-f849-44ea-af37-221efcffe1a3", "metadata": { "editable": true, @@ -351,9 +372,7 @@ "output_type": "stream", "text": [ "> Entered the node: 2 # of times\n", - "{'node': None}\n", - "> Entered the node: 3 # of times\n", - "{'__interrupt__': (Interrupt(value='What is your age?', resumable=True, ns=['node:995027b2-c8ad-8951-74ff-d9b86fca74bb'], when='during'),)}\n" + "{'__interrupt__': (Interrupt(value=\"'-20 is not a valid age. What is your age?\", resumable=True, ns=['node:ed4d470f-5753-d7f3-eec6-4435f5f93f72'], when='during'),)}\n" ] } ], @@ -365,7 +384,28 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 14, + "id": "170b0cde-d94b-4aca-bfea-70f9927f4288", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 3 # of times\n", + "{'__interrupt__': (Interrupt(value=\"'{'foo': 'bar'} is not a valid age. What is your age?\", resumable=True, ns=['node:ed4d470f-5753-d7f3-eec6-4435f5f93f72'], when='during'),)}\n" + ] + } + ], + "source": [ + "bad_input = {\"foo\": \"bar\"} # Not a number!\n", + "for chunk in graph.stream(Command(resume=bad_input), config):\n", + " print(chunk)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, "id": "c9d01c77-7a9c-43aa-bbfa-c969b1d3e3f2", "metadata": { "editable": true, @@ -374,9 +414,18 @@ }, "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 4 # of times\n", + "{'node': {'human_value': 'The human is 25 years old.'}}\n" + ] + } + ], "source": [ - "ok_input = 5\n", + "ok_input = 25\n", "for chunk in graph.stream(Command(resume=ok_input), config):\n", " print(chunk)" ] @@ -394,12 +443,12 @@ "source": [ "## Usage with invoke / ainvoke\n", "\n", - "If you're not using `stream` or `astream`, you will need to explicitly access the state of the graph to get information about the interrupt." + "If you're using `invoke` and/or `ainvoke`, you will need to explicitly access the state of the graph using `graph.get_state(config)` to determine if there was an interrupt and if so what value it was associated with." ] }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 21, "id": "c9ae2c5f-c81d-4188-9f7e-f3f90e675e12", "metadata": { "editable": true, @@ -452,15 +501,84 @@ "builder.add_edge(START, \"node\")\n", "\n", "# A checkpointer must be enabled for interrupts to work!\n", - "graph = builder.compile(checkpointer=MemorySaver())\n", + "checkpointer = MemorySaver()\n", + "graph = builder.compile(checkpointer=checkpointer)\n", "\n", "config = {\n", - " \"thread_id\": uuid.uuid4(),\n", + " \"configurable\": {\n", + " \"thread_id\": uuid.uuid4(),\n", + " }\n", "}\n", "\n", "for event in graph.invoke({\"foo\": \"abc\"}, config):\n", " print" ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "f15b73f1-259b-4045-b633-2686873ef1f6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('node',)\n", + "\n", + "PregelTask(id='57efb8b4-1170-b872-647e-60de07598d61', name='node', path=('__pregel_pull', 'node'), error=None, interrupts=(Interrupt(value='what is your age?', resumable=True, ns=['node:57efb8b4-1170-b872-647e-60de07598d61'], when='during'),), state=None, result=None)\n", + "\n", + "(Interrupt(value='what is your age?', resumable=True, ns=['node:57efb8b4-1170-b872-647e-60de07598d61'], when='during'),)\n" + ] + } + ], + "source": [ + "state = graph.get_state(config)\n", + "\n", + "print(state.next)\n", + "print()\n", + "print(state.tasks[0])\n", + "print()\n", + "print(state.tasks[0].interrupts)" + ] + }, + { + "cell_type": "markdown", + "id": "113a746b-c9b7-4efa-ad6c-516f85b9cf5f", + "metadata": {}, + "source": [ + "Let's resume now:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "69a46d8f-ebe6-4ee0-84c9-30ce81d576c9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> Entered the node: 2 # of times\n", + "> Received an input from the interrupt: 25\n" + ] + }, + { + "data": { + "text/plain": [ + "{'foo': 'abc', 'human_value': 25}" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ok_input = 25\n", + "graph.invoke(Command(resume=ok_input), config)" + ] } ], "metadata": { From 291379dfb907ee071b097f428c586765e64b3eaa Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 22:32:11 -0500 Subject: [PATCH 05/72] x --- .../how-tos/human_in_the_loop/interrupt.ipynb | 2 +- libs/langgraph/langgraph/types.py | 57 ++++++++++++------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index 043e60c6b..892be2c65 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -37,7 +37,7 @@ "\n", "Remember that graph execution always restarts at the beginning of the node. Be cautious of side effects, such as API calls that mutate data, as these may inadvertently be triggered multiple times.\n", "\n", - "When a node contains multiple interrupt calls, LangGraph maintains a list of resume values provided during graph execution. When resuming, execution always starts at the beginning of the node, and for each interrupt encountered, LangGraph checks whether a corresponding value exists in the list. Matching is strictly index-based, making the order of interrupt calls within the node critical. Users should avoid logic that dynamically removes, adds, or reorders interrupt calls between executions, as this can lead to mismatched indices. Such patterns often involve unconventional state mutations, such as altering state via `Command(resume=..., update=SOME_STATE_MUTATION)` or relying on global variables to modify the node's structure." + "When a node contains multiple interrupt calls, LangGraph maintains a list of resume values scoped to the specific task executing the node. When resuming, execution always starts at the beginning of the node, and for each interrupt encountered, LangGraph checks whether a corresponding value exists in the task's list. Matching is strictly index-based, making the order of interrupt calls within the node critical. Users should avoid logic that dynamically removes, adds, or reorders interrupt calls between executions, as this can lead to mismatched indices. Such patterns often involve unconventional state mutations, such as altering state via `Command(resume=..., update=SOME_STATE_MUTATION)` or relying on global variables to modify the node's structure." ] }, { diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index 456196e44..3e3c729ba 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -330,38 +330,55 @@ class PregelScratchpad(TypedDict, total=False): def interrupt(value: Any) -> Any: """Interrupt the graph with a resumable exception from within a node. - The interrupt function is used for supporting human-in-the-loop workflows. - - It can be thought of as an equivalent to the python's built-in `input` function. + The `interrupt` function enables human-in-the-loop workflows by pausing graph + execution and surfacing a value to the client. This value can communicate context + or request input required to resume execution. In a given node, the first invocation of this function raises a `GraphInterrupt` - exception. The `value` argument is passed to the exception and can be used to - communicate information to the client executing the graph. + exception, halting execution. The provided `value` is included with the exception + and sent to the client executing the graph. - The client can choose to resume the graph from the same node provide a value to - resume with. + A client resuming the graph must use the `Command` primitive to specify a value + for the interrupt and continue execution. The graph resumes from the start of + the node, **re-executing** all logic. + If a node contains multiple `interrupt` calls, LangGraph matches resume values + to interrupts based on their order in the node. This list of resume values + is scoped to the specific task executing the node and is not shared across tasks. - The client will use the `Command` primitive to - resume graph execution. + To use an `interrupt`, you must enable a checkpointer, as the feature relies + on persisting the graph state. - graph.astream(Command(resume="answer 1", update={"my_key": "foofoo"}), config, stream_mode="updates") + Examples: + ```python + async def some_node(state: State): + # Surface a value as part of the interrupt + question = {"question": "how old are you?"} + answer = interrupt(question) + # Continue execution with the provided answer + ``` - The first invocation of this function raises a `GraphInterrupt` exception - - The first occurrence of this function in a node raises a `GraphInterrupt` - exception with the given value. - - A client executing the graph will receive the value and can choose to - resume the graph from the same node with a value. + A client resuming the graph: + ```python + for chunk in graph.astream( + Command(resume="25"), + config, + stream_mode="updates" + ): + print(chunk) + ``` Args: - value: The value to interrupt the graph with. + value: The value to surface to the client when the graph is interrupted. Returns: - On a first call, raises a `GraphInterrupt` exception with the given value. - On subsequent calls from the same node, returns the value to resume with. + On subsequent invocations within the same node (same task to be precise), + returns the value provided during the first invocation + + Raises: + GraphInterrupt: On the first invocation within the node, halts execution + and surfaces the provided value to the client. """ from langgraph.constants import ( CONFIG_KEY_CHECKPOINT_NS, From 3d3647cd85f70bad62a39591388a10be84f29ae4 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 22:36:43 -0500 Subject: [PATCH 06/72] x --- docs/docs/how-tos/human_in_the_loop/interrupt.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index 892be2c65..4f7ecdd25 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -105,7 +105,7 @@ "source": [ "## Basic usage of interrupt and Command\n", "\n", - "Here is an exmaple that shows how to use `interrupt` to interrupt the execution of a graph, and then resume the execution using the `Command` primitive." + "Here is an example that shows how to use `interrupt` to interrupt the execution of a graph, and then resume the execution using the `Command` primitive." ] }, { @@ -153,7 +153,7 @@ " print(f'> Entered the node: {counter} # of times')\n", " answer = interrupt(\n", " # This value will be sent to the client\n", - " # as part of the interrupt inforamtion.\n", + " # as part of the interrupt information.\n", " 'what is your age?'\n", " )\n", " print(f'> Received an input from the interrupt: {answer}')\n", @@ -490,7 +490,7 @@ " print(f'> Entered the node: {counter} # of times')\n", " answer = interrupt(\n", " # This value will be sent to the client\n", - " # as part of the interrupt inforamtion.\n", + " # as part of the interrupt information.\n", " 'what is your age?'\n", " )\n", " print(f'> Received an input from the interrupt: {answer}')\n", From e80098e297d951221c3fe79cddcaf92747d9104b Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 22:38:55 -0500 Subject: [PATCH 07/72] x --- .../how-tos/human_in_the_loop/interrupt.ipynb | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index 4f7ecdd25..f063a07fc 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -139,26 +139,31 @@ "from langgraph.types import interrupt, Command\n", "from langgraph.checkpoint.memory import MemorySaver\n", "\n", + "\n", "class State(TypedDict):\n", " \"\"\"The graph state.\"\"\"\n", + "\n", " foo: str\n", " human_value: Optional[str]\n", " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", - " \n", + "\n", + "\n", "counter = 0\n", "\n", + "\n", "def node(state: State):\n", " global counter\n", - " counter +=1 \n", - " print(f'> Entered the node: {counter} # of times')\n", + " counter += 1\n", + " print(f\"> Entered the node: {counter} # of times\")\n", " answer = interrupt(\n", " # This value will be sent to the client\n", " # as part of the interrupt information.\n", - " 'what is your age?'\n", + " \"what is your age?\"\n", " )\n", - " print(f'> Received an input from the interrupt: {answer}')\n", + " print(f\"> Received an input from the interrupt: {answer}\")\n", " return {\"human_value\": answer}\n", "\n", + "\n", "builder = StateGraph(State)\n", "builder.add_node(\"node\", node)\n", "builder.add_edge(START, \"node\")\n", @@ -290,25 +295,25 @@ "\n", "class State(TypedDict):\n", " \"\"\"The graph state.\"\"\"\n", + "\n", " foo: str\n", " human_value: Optional[str]\n", " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", - " \n", + "\n", "\n", "counter = 0\n", "\n", + "\n", "def node(state: State):\n", " global counter\n", - " counter +=1 \n", - " print(f'> Entered the node: {counter} # of times')\n", + " counter += 1\n", + " print(f\"> Entered the node: {counter} # of times\")\n", "\n", " answer = None\n", " question = \"What is your age?\"\n", "\n", " while answer is None:\n", - " answer = interrupt(\n", - " question\n", - " )\n", + " answer = interrupt(question)\n", "\n", " if not isinstance(answer, int) or answer < 0:\n", " question = f\"'{answer} is not a valid age. What is your age?\"\n", @@ -317,11 +322,8 @@ " else:\n", " break\n", "\n", - " return {\n", - " \"human_value\": f\"The human is {answer} years old.\"\n", - " }\n", + " return {\"human_value\": f\"The human is {answer} years old.\"}\n", "\n", - " \n", "\n", "builder = StateGraph(State)\n", "builder.add_node(\"node\", node)\n", @@ -377,7 +379,7 @@ } ], "source": [ - "bad_input = -20 # Negative number!\n", + "bad_input = -20 # Negative number!\n", "for chunk in graph.stream(Command(resume=bad_input), config):\n", " print(chunk)" ] @@ -398,7 +400,7 @@ } ], "source": [ - "bad_input = {\"foo\": \"bar\"} # Not a number!\n", + "bad_input = {\"foo\": \"bar\"} # Not a number!\n", "for chunk in graph.stream(Command(resume=bad_input), config):\n", " print(chunk)" ] @@ -476,26 +478,31 @@ "from langgraph.types import interrupt, Command\n", "from langgraph.checkpoint.memory import MemorySaver\n", "\n", + "\n", "class State(TypedDict):\n", " \"\"\"The graph state.\"\"\"\n", + "\n", " foo: str\n", " human_value: Optional[str]\n", " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", - " \n", + "\n", + "\n", "counter = 0\n", "\n", + "\n", "def node(state: State):\n", " global counter\n", - " counter +=1 \n", - " print(f'> Entered the node: {counter} # of times')\n", + " counter += 1\n", + " print(f\"> Entered the node: {counter} # of times\")\n", " answer = interrupt(\n", " # This value will be sent to the client\n", " # as part of the interrupt information.\n", - " 'what is your age?'\n", + " \"what is your age?\"\n", " )\n", - " print(f'> Received an input from the interrupt: {answer}')\n", + " print(f\"> Received an input from the interrupt: {answer}\")\n", " return {\"human_value\": answer}\n", "\n", + "\n", "builder = StateGraph(State)\n", "builder.add_node(\"node\", node)\n", "builder.add_edge(START, \"node\")\n", From 0a49f3003b7e772047b9c195100deec991dc4a3c Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 4 Dec 2024 22:57:48 -0500 Subject: [PATCH 08/72] x --- libs/langgraph/langgraph/types.py | 85 +++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index 3e3c729ba..26d27acab 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -338,9 +338,9 @@ def interrupt(value: Any) -> Any: exception, halting execution. The provided `value` is included with the exception and sent to the client executing the graph. - A client resuming the graph must use the `Command` primitive to specify a value - for the interrupt and continue execution. The graph resumes from the start of - the node, **re-executing** all logic. + A client resuming the graph must use the [`Command`][langgraph.types.Command] + primitive to specify a value for the interrupt and continue execution. + The graph resumes from the start of the node, **re-executing** all logic. If a node contains multiple `interrupt` calls, LangGraph matches resume values to interrupts based on their order in the node. This list of resume values @@ -349,25 +349,70 @@ def interrupt(value: Any) -> Any: To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state. - Examples: + Example: Basic interrupt and resume - ```python - async def some_node(state: State): - # Surface a value as part of the interrupt - question = {"question": "how old are you?"} - answer = interrupt(question) - # Continue execution with the provided answer - ``` + ```python + import uuid + from typing import TypedDict, Optional + + from langgraph.checkpoint.memory import MemorySaver + from langgraph.constants import START + from langgraph.graph import StateGraph + from langgraph.types import interrupt + + + class State(TypedDict): + \"\"\"The graph state.\"\"\" + + foo: str + human_value: Optional[str] + \"\"\"Human value will be updated using an interrupt.\"\"\" + + + def node(state: State): + answer = interrupt( + # This value will be sent to the client + # as part of the interrupt information. + \"what is your age?\" + ) + print(f\"> Received an input from the interrupt: {answer}\") + return {\"human_value\": answer} + + + builder = StateGraph(State) + builder.add_node(\"node\", node) + builder.add_edge(START, \"node\") + + # A checkpointer must be enabled for interrupts to work! + checkpointer = MemorySaver() + graph = builder.compile(checkpointer=checkpointer) + + config = { + \"configurable\": { + \"thread_id\": uuid.uuid4(), + } + } + + for chunk in graph.stream({\"foo\": \"abc\"}, config): + print(chunk) + ``` + + ```pycon + {'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:62e598fa-8653-9d6d-2046-a70203020e37'], when='during'),)} + ``` + + ```python + command = Command(resume=\"some input from a human!!!\") + + for chunk in graph.stream(Command(resume=\"some input from a human!!!\"), config): + print(chunk) + ``` + + ```pycon + Received an input from the interrupt: some input from a human!!! + {'node': {'human_value': 'some input from a human!!!'}} + ``` - A client resuming the graph: - ```python - for chunk in graph.astream( - Command(resume="25"), - config, - stream_mode="updates" - ): - print(chunk) - ``` Args: value: The value to surface to the client when the graph is interrupted. From 4fd261765a7dff2b73718321ca68e159ae221549 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 5 Dec 2024 15:46:26 -0500 Subject: [PATCH 09/72] x --- docs/docs/concepts/human_in_the_loop.md | 15 ++-- docs/docs/concepts/low_level.md | 91 ++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 20 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 45ce792d4..77a8114dd 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -1,20 +1,17 @@ # Human-in-the-loop -Human-in-the-loop (or "on-the-loop") enhances agent capabilities through several common user interaction patterns. +Human-in-the-loop (or "on-the-loop") workflows enhance agent capabilities through several common user interaction patterns. Common interaction patterns include: -(1) `Approval` - We can interrupt our agent, surface the current state to a user, and allow the user to accept an action. - -(2) `Editing` - We can interrupt our agent, surface the current state to a user, and allow the user to edit the agent state. - -(3) `Input` - We can explicitly create a graph node to collect human input and pass that input directly to the agent state. +1. **Approval**: Pause the agent, present its current state to the user, and allow the user to approve or reject a proposed action. +2. **Editing**: Pause the agent, present its current state to the user, and allow the user to make modifications to the agent's state. +3. **Input**: Introduce a dedicated graph node to explicitly collect user input, which is then integrated into the agent's state. Use-cases for these interaction patterns include: -(1) `Reviewing tool calls` - We can interrupt an agent to review and edit the results of tool calls. - -(2) `Time Travel` - We can manually re-play and / or fork past actions of an agent. +1. `Reviewing tool calls` - We can interrupt an agent to review and edit the results of tool calls. +2. `Time travel` - We can manually re-play and / or fork past actions of an agent. ## Persistence diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index 1d059568b..266ced5be 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -451,25 +451,54 @@ Read [this how-to](https://langchain-ai.github.io/langgraph/how-tos/recursion-li ## Breakpoints -It can often be useful to set breakpoints before or after certain nodes execute. This can be used to wait for human approval before continuing. These can be set when you ["compile" a graph](#compiling-your-graph). You can set breakpoints either _before_ a node executes (using `interrupt_before`) or after a node executes (using `interrupt_after`.) +Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. -You **MUST** use a [checkpointer](./persistence.md) when using breakpoints. This is because your graph needs to be able to resume execution. +You **MUST** use a [checkpointer](./persistence.md) when using breakpoints as breakpoints require the ability to save the state of the graph at the time of pausing. -In order to resume execution, you can just invoke your graph with `None` as the input. +There are two types of breakpoints: + +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. + +### Static Breakpoints + +To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). ```python -# Initial run of graph -graph.invoke(inputs, config=config) - -# Let's assume it hit a breakpoint somewhere, you can then resume by passing in None -graph.invoke(None, config=config) +graph = graph_builder.compile( + interrupt_before=["node_a"], + interrupt_after=["node_b", "node_c"], + checkpointer=..., # Required +) ``` -See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. +When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. -### Dynamic Breakpoints +### Dynamic Breakpoints -It may be helpful to **dynamically** interrupt the graph from inside a given node based on some condition. In `LangGraph` you can do so by using `NodeInterrupt` -- a special exception that can be raised from inside a node. +There are two ways to interrupt the graph dynamically: + +1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. +2. `NodeInterrupt` exception: An older, less flexible method for interrupting. + +#### `interrupt` + +```python +from langgraph.types import interrupt + +def node(state: State): + ... + client_value = interrupt( + # This value will be sent to the client. + # It can be any JSON serializable value. + {"key": "value"} + ) + ... +``` + +#### `NodeInterrupt` + +Throw a `NodeInterrupt` exception to interrupt the graph. ```python def my_node(state: State) -> State: @@ -479,6 +508,46 @@ def my_node(state: State) -> State: return state ``` +### Resuming + +When a breakpoint is hit, graph execution will pause. + +=== "Command" + + Resume execution using the new `Command` primitive. + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + graph.invoke( + Command( + # Use `resume` to pass a value to the `interrupt`. + resume=resume, + # For other kinds of breakpoints, use `update` to update the state. + update=update, + ), + config=config + ) + ``` + +=== "Without the Command Primitive" + + Resume execution without the `Command` primitive (older versions of LangGraph). + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + + graph.update_state(update, config=config) + graph.invoke(None, config=config) + ``` + +See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. + ## Subgraphs A subgraph is a [graph](#graphs) that is used as a [node](#nodes) in another graph. This is nothing more than the age-old concept of encapsulation, applied to LangGraph. Some reasons for using subgraphs are: From 62ff2eb32dc0b3d5fe4ddc6a11586d9004351376 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 5 Dec 2024 17:16:34 -0500 Subject: [PATCH 10/72] x --- docs/docs/concepts/human_in_the_loop.md | 134 +++++++++++++++++++++--- docs/docs/concepts/low_level.md | 93 +--------------- libs/langgraph/langgraph/types.py | 96 +++++++++-------- 3 files changed, 172 insertions(+), 151 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 77a8114dd..32cf7582b 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -1,25 +1,51 @@ # Human-in-the-loop -Human-in-the-loop (or "on-the-loop") workflows enhance agent capabilities through several common user interaction patterns. +**Human-in-the-loop** (or "on-the-loop") workflows enhance agent capabilities by incorporating human interactions at key points. Common interaction patterns include: -Common interaction patterns include: - -1. **Approval**: Pause the agent, present its current state to the user, and allow the user to approve or reject a proposed action. -2. **Editing**: Pause the agent, present its current state to the user, and allow the user to make modifications to the agent's state. -3. **Input**: Introduce a dedicated graph node to explicitly collect user input, which is then integrated into the agent's state. +1. ✅ **Approval**: Pause the agent, present its current state to the user, and allow the user to approve or reject a proposed action. +2. 📝 **Editing**: Pause the agent, present its current state to the user, and allow the user to make modifications to the agent's state. +3. 💬 **Input**: Introduce a dedicated graph node to explicitly collect user input, which is then integrated into the agent's state. Use-cases for these interaction patterns include: -1. `Reviewing tool calls` - We can interrupt an agent to review and edit the results of tool calls. -2. `Time travel` - We can manually re-play and / or fork past actions of an agent. +1. [**Reviewing tool calls**](#reviewing-tool-calls): Pause the agent to review and edit the results of tool executions. +2. [**Time travel**](#time-travel): Replay or fork the agent's past actions for further exploration. ## Persistence -All of these interaction patterns are enabled by LangGraph's built-in [persistence](./persistence.md) layer, which will write a checkpoint of the graph state at each step. Persistence allows the graph to stop so that a human can review and / or edit the current state of the graph and then resume with the human's input. +Human-in-the-loop patterns are enabled by LangGraph's built-in [persistence](./persistence.md) layer, which writes a checkpoint of the graph state at each step. +Persistence allows pausing graph execution so that a human can review and / or edit the current state of the graph and then resume with the human's input. -### Breakpoints +## Breakpoints + +Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. This functionality is enabled by LangGraph's built-in [checkpointer](./persistence.md#checkpointer), which writes a checkpoint of the graph state at each step. + +There are two types of breakpoints: + +1. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. +2. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause the graph from **inside** a node often based on some condition. + +!!! important "Checkpointer Required" + + You must compile your graph with a checkpointer to use breakpoints. + +### Static Breakpoints + +Use static breakpoints if you want to **ALWAYS** pause the graph either **before** or **after** one or more nodes execute. + +To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). + +```python +# Compile our graph with a checkpointer and a breakpoint before "node_a" and after "node_b" and "node_c" +graph = graph_builder.compile( + interrupt_before=["node_a"], + interrupt_after=["node_b", "node_c"], + checkpointer=checkpointer, # Required +) +``` + +When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. -Adding a [breakpoint](./low_level.md#breakpoints) a specific location in the graph flow is one way to enable human-in-the-loop. In this case, the developer knows *where* in the workflow human input is needed and simply places a breakpoint prior to or following that particular graph node. Here, we compile our graph with a checkpointer and a breakpoint at the node we want to interrupt before, `step_for_human_in_the_loop`. We then perform one of the above interaction patterns, which will create a new checkpoint if a human edits the graph state. The new checkpoint is saved to the `thread` and we can resume the graph execution from there by passing in `None` as the input. @@ -41,6 +67,15 @@ for event in graph.stream(None, thread_config, stream_mode="values"): ### Dynamic Breakpoints +Alternatively, you may want to raise a breakpoint from inside a node, potentially based on some condition that is not known until runtime. This is called a dynamic breakpoint. + +This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. + +There are two ways to interrupt the graph dynamically: + +1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. +2. `NodeInterrupt` exception: An older, less flexible method for interrupting. + Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. ```python @@ -50,7 +85,7 @@ def my_node(state: State) -> State: return state ``` -Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. +Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. ```python # Attempt to continue the graph execution with no change to state after we hit the dynamic breakpoint @@ -78,6 +113,81 @@ for event in graph.stream(None, thread_config, stream_mode="values"): See [our guide](../how-tos/human_in_the_loop/dynamic_breakpoints.ipynb) for a detailed how-to on doing this! +### Dynamic Breakpoints + +There are two ways to interrupt the graph dynamically: + +1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. +2. `NodeInterrupt` exception: An older, less flexible method for interrupting. + +#### `interrupt` + +```python +from langgraph.types import interrupt + +def node(state: State): + ... + client_value = interrupt( + # This value will be sent to the client. + # It can be any JSON serializable value. + {"key": "value"} + ) + ... +``` + +#### `NodeInterrupt` + +Throw a `NodeInterrupt` exception to interrupt the graph. + +```python +def my_node(state: State) -> State: + if len(state['input']) > 5: + raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") + + return state +``` + +### Resuming + +When a breakpoint is hit, graph execution will pause. + +=== "Command" + + Resume execution using the new `Command` primitive. + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + graph.invoke( + Command( + # Use `resume` to pass a value to the `interrupt`. + resume=resume, + # For other kinds of breakpoints, use `update` to update the state. + update=update, + ), + config=config + ) + ``` + +=== "Without the Command Primitive" + + Resume execution without the `Command` primitive (older versions of LangGraph). + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + + graph.update_state(update, config=config) + graph.invoke(None, config=config) + ``` + +See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. + + ## Interaction Patterns ### Approval diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index 266ced5be..6080c7d58 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -453,100 +453,13 @@ Read [this how-to](https://langchain-ai.github.io/langgraph/how-tos/recursion-li Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. -You **MUST** use a [checkpointer](./persistence.md) when using breakpoints as breakpoints require the ability to save the state of the graph at the time of pausing. - There are two types of breakpoints: -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. -### Static Breakpoints +Please see the [Human-in-the-Loop guide](../human_in_the_loop) for conceptual information about breakpoints. -To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). - -```python -graph = graph_builder.compile( - interrupt_before=["node_a"], - interrupt_after=["node_b", "node_c"], - checkpointer=..., # Required -) -``` - -When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. - -### Dynamic Breakpoints - -There are two ways to interrupt the graph dynamically: - -1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. -2. `NodeInterrupt` exception: An older, less flexible method for interrupting. - -#### `interrupt` - -```python -from langgraph.types import interrupt - -def node(state: State): - ... - client_value = interrupt( - # This value will be sent to the client. - # It can be any JSON serializable value. - {"key": "value"} - ) - ... -``` - -#### `NodeInterrupt` - -Throw a `NodeInterrupt` exception to interrupt the graph. - -```python -def my_node(state: State) -> State: - if len(state['input']) > 5: - raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") - - return state -``` - -### Resuming - -When a breakpoint is hit, graph execution will pause. - -=== "Command" - - Resume execution using the new `Command` primitive. - - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - graph.invoke( - Command( - # Use `resume` to pass a value to the `interrupt`. - resume=resume, - # For other kinds of breakpoints, use `update` to update the state. - update=update, - ), - config=config - ) - ``` - -=== "Without the Command Primitive" - - Resume execution without the `Command` primitive (older versions of LangGraph). - - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - - graph.update_state(update, config=config) - graph.invoke(None, config=config) - ``` - -See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. ## Subgraphs diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index 26d27acab..8853a501d 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -349,77 +349,75 @@ def interrupt(value: Any) -> Any: To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state. - Example: Basic interrupt and resume + Example: + ```python + import uuid + from typing import TypedDict, Optional - ```python - import uuid - from typing import TypedDict, Optional - - from langgraph.checkpoint.memory import MemorySaver - from langgraph.constants import START - from langgraph.graph import StateGraph - from langgraph.types import interrupt + from langgraph.checkpoint.memory import MemorySaver + from langgraph.constants import START + from langgraph.graph import StateGraph + from langgraph.types import interrupt - class State(TypedDict): - \"\"\"The graph state.\"\"\" + class State(TypedDict): + \"\"\"The graph state.\"\"\" - foo: str - human_value: Optional[str] - \"\"\"Human value will be updated using an interrupt.\"\"\" + foo: str + human_value: Optional[str] + \"\"\"Human value will be updated using an interrupt.\"\"\" - def node(state: State): - answer = interrupt( - # This value will be sent to the client - # as part of the interrupt information. - \"what is your age?\" - ) - print(f\"> Received an input from the interrupt: {answer}\") - return {\"human_value\": answer} + def node(state: State): + answer = interrupt( + # This value will be sent to the client + # as part of the interrupt information. + \"what is your age?\" + ) + print(f\"> Received an input from the interrupt: {answer}\") + return {\"human_value\": answer} - builder = StateGraph(State) - builder.add_node(\"node\", node) - builder.add_edge(START, \"node\") + builder = StateGraph(State) + builder.add_node(\"node\", node) + builder.add_edge(START, \"node\") - # A checkpointer must be enabled for interrupts to work! - checkpointer = MemorySaver() - graph = builder.compile(checkpointer=checkpointer) + # A checkpointer must be enabled for interrupts to work! + checkpointer = MemorySaver() + graph = builder.compile(checkpointer=checkpointer) - config = { - \"configurable\": { - \"thread_id\": uuid.uuid4(), + config = { + \"configurable\": { + \"thread_id\": uuid.uuid4(), + } } - } - for chunk in graph.stream({\"foo\": \"abc\"}, config): - print(chunk) - ``` + for chunk in graph.stream({\"foo\": \"abc\"}, config): + print(chunk) + ``` - ```pycon - {'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:62e598fa-8653-9d6d-2046-a70203020e37'], when='during'),)} - ``` + ```pycon + {'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:62e598fa-8653-9d6d-2046-a70203020e37'], when='during'),)} + ``` - ```python - command = Command(resume=\"some input from a human!!!\") + ```python + command = Command(resume=\"some input from a human!!!\") - for chunk in graph.stream(Command(resume=\"some input from a human!!!\"), config): - print(chunk) - ``` + for chunk in graph.stream(Command(resume=\"some input from a human!!!\"), config): + print(chunk) + ``` - ```pycon - Received an input from the interrupt: some input from a human!!! - {'node': {'human_value': 'some input from a human!!!'}} - ``` + ```pycon + Received an input from the interrupt: some input from a human!!! + {'node': {'human_value': 'some input from a human!!!'}} + ``` Args: value: The value to surface to the client when the graph is interrupted. Returns: - On subsequent invocations within the same node (same task to be precise), - returns the value provided during the first invocation + Any: On subsequent invocations within the same node (same task to be precise), returns the value provided during the first invocation Raises: GraphInterrupt: On the first invocation within the node, halts execution From 01b1080b6e3b1f26696f040a7b30e0a45f21dfe5 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 5 Dec 2024 17:26:55 -0500 Subject: [PATCH 11/72] x --- docs/docs/concepts/human_in_the_loop.md | 12 ++++++++---- docs/docs/concepts/low_level.md | 3 +-- libs/langgraph/langgraph/types.py | 1 - 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 32cf7582b..cffa910a6 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -18,17 +18,21 @@ Persistence allows pausing graph execution so that a human can review and / or e ## Breakpoints -Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. This functionality is enabled by LangGraph's built-in [checkpointer](./persistence.md#checkpointer), which writes a checkpoint of the graph state at each step. +Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. This functionality is enabled by LangGraph's built-in [checkpointer](./persistence.md), which writes a checkpoint of the graph state at each step. -There are two types of breakpoints: +You have a few options for setting breakpoints: -1. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. -2. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause the graph from **inside** a node often based on some condition. +1. [**Using the `interrupt` function**](./#interrupts): Pause the graph **inside** a node. +2. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. +3. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause the graph from **inside** typically based on a condition. !!! important "Checkpointer Required" You must compile your graph with a checkpointer to use breakpoints. + +### `Interrupt` function + ### Static Breakpoints Use static breakpoints if you want to **ALWAYS** pause the graph either **before** or **after** one or more nodes execute. diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index 6080c7d58..b05867cd6 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -458,8 +458,7 @@ There are two types of breakpoints: 1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). 2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. -Please see the [Human-in-the-Loop guide](../human_in_the_loop) for conceptual information about breakpoints. - +Please see the [Human-in-the-Loop guide](../human_in_the_loop) for information about breakpoints. ## Subgraphs diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index 8853a501d..0b0bf83a0 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -412,7 +412,6 @@ def interrupt(value: Any) -> Any: {'node': {'human_value': 'some input from a human!!!'}} ``` - Args: value: The value to surface to the client when the graph is interrupted. From 6230c4683086c1ae3a794da4f190ebdbf7c0f82a Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 5 Dec 2024 21:27:18 -0500 Subject: [PATCH 12/72] x --- docs/docs/concepts/human_in_the_loop.md | 92 ++++++++++++++++++------- 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index cffa910a6..90bd4ab83 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -1,5 +1,12 @@ # Human-in-the-loop +!!! tip "This guide uses the new `interrupt` function." + + As of LangGraph 0.2.57, the recommended way to set breakpoints is using `interrupt` function as it significantly + simpifies **human-in-the-loop** patterns. + + If you're looking for the previous version of this conceptual guide, which uses static breakpoints and `NodeInterrupt` exception, it is available [here](./low_level.md#breakpoints). + **Human-in-the-loop** (or "on-the-loop") workflows enhance agent capabilities by incorporating human interactions at key points. Common interaction patterns include: 1. ✅ **Approval**: Pause the agent, present its current state to the user, and allow the user to approve or reject a proposed action. @@ -13,25 +20,63 @@ Use-cases for these interaction patterns include: ## Persistence -Human-in-the-loop patterns are enabled by LangGraph's built-in [persistence](./persistence.md) layer, which writes a checkpoint of the graph state at each step. -Persistence allows pausing graph execution so that a human can review and / or edit the current state of the graph and then resume with the human's input. +**Human-in-the-loop** patterns are enabled by LangGraph's built-in [persistence](./persistence.md) layer, which writes a checkpoint of the graph state at each step, allowing for resumption of execution. You **must compile** your graph with a checkpointer to use breakpoints. -## Breakpoints +## Breakpoints -Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. This functionality is enabled by LangGraph's built-in [checkpointer](./persistence.md), which writes a checkpoint of the graph state at each step. +Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. -You have a few options for setting breakpoints: +1. [**Interrupt function**](#interrupt-function): Pause the graph from **inside** a node. This is the recommended way to set breakpoints for human-in-the-loop workflows. +1. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. +2. [**Using the `interrupt` function**](#interrupt-function): Pause the graph from **inside** a node. -1. [**Using the `interrupt` function**](./#interrupts): Pause the graph **inside** a node. -2. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. -3. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause the graph from **inside** typically based on a condition. - -!!! important "Checkpointer Required" +## Interrupt - You must compile your graph with a checkpointer to use breakpoints. +An `interrupt` is a particularly convenient way to support human-in-the-loop workflows. To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state. An `interrupt` can be used within a node to pause execution and wait for input, as shown in this example: + +You can think of an `interrupt` as similar to how the `input` function works, but with the difference +that graph execution always **resumes** from the **beginning** of the node where the `interrupt` was called. This means that you have to: + +1. Be cautious of side effects, such as API calls that mutate data, as these may inadvertently be triggered multiple times. +2. Be aware that the node will be re-run with the same graph state, so you may need to update the state to avoid the same `interrupt` being triggered again. + +```python +from langgraph.types import interrupt + +def node(state: State): + answer = interrupt( + # This value will be sent to the client. + { + "question": "What is your age?", + "options": ["18-24", "25-34", "35-44", "45-54", "55-64", "65+"], + } + ) + print(f"> Received an input from the interrupt: {answer}") + return {"human_value": answer} +``` -### `Interrupt` function + + + +Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. + +The recommended way to set breakpoints is to use the `interrupt` function. This function allows you to pause the graph from **inside** a node, and surface a value to the client as part of the interrupt information. + +You have a few options for setting breakpoints, but the recommended approach for newer versions of LangGraph is to use the `interrupt` function. + +1. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. +2. [**Using the `interrupt` function**](#interrupt-function): Pause the graph from **inside** a node. + +### Using the `interrupt` function + + +```python +# A checkpointer must be enabled for interrupts to work! +checkpointer = MemorySaver() +graph = builder.compile(checkpointer=checkpointer) +``` + ### Static Breakpoints @@ -311,9 +356,8 @@ For example, many agents use [tool calling](https://python.langchain.com/docs/ho Tool calling presents a challenge because the agent must get two things right: -(1) The name of the tool to call - -(2) The arguments to pass to the tool +1. The name of the tool to call +2. The arguments to pass to the tool Even if the tool call is correct, we may also want to apply discretion: @@ -322,7 +366,7 @@ Even if the tool call is correct, we may also want to apply discretion: With these points in mind, we can combine the above ideas to create a human-in-the-loop review of a tool call. ```python -# Compile our graph with a checkpointer and a breakpoint before the step to to review the tool call from the LLM +# Compile our graph with a checkpointer and a breakpoint before the step to review the tool call from the LLM graph = builder.compile(checkpointer=checkpointer, interrupt_before=["human_review"]) # Run the graph up to the breakpoint @@ -405,25 +449,21 @@ See see [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a detai ![](./img/human_in_the_loop/forking.png) -Sometimes we want to fork past actions of an agent, and explore different paths through the graph. +Forking allows us to revisit an agent's past actions and explore alternative paths through the graph. -`Editing`, as discussed above, is *exactly* how we do this for the *current* state of the graph! +The **Editing** pattern, as described earlier, enables modifications to the *current* state of the graph. But what if you want to fork from a *past* state? -But, what if we want to fork *past* states of the graph? - -For example, let's say we want to edit a particular checkpoint, `xxx`. - -We pass this `checkpoint_id` when we update the state of the graph. +For instance, suppose you want to edit a specific checkpoint, such as `xyz`. You can achieve this by providing the relevant `checkpoint_id` when updating the graph's state. ```python -config = {"configurable": {"thread_id": "1", "checkpoint_id": "xxx"}} +config = {"configurable": {"thread_id": "1", "checkpoint_id": "xyz"}} graph.update_state(config, {"state": "updated state"}, ) ``` -This creates a new forked checkpoint, `xxx-fork`, which we can then run the graph from. +This creates a new forked checkpoint, `xyz-fork`, which we can then run the graph from. ```python -config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xxx-fork'}} +config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xyz-fork'}} for event in graph.stream(None, config, stream_mode="values"): print(event) ``` From 750b97349e98db884bab2d557cc485c264dfe8aa Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 5 Dec 2024 21:32:10 -0500 Subject: [PATCH 13/72] x --- docs/docs/concepts/human_in_the_loop.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 90bd4ab83..efeb860e3 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -350,20 +350,15 @@ See [this guide](../how-tos/human_in_the_loop/wait-user-input.ipynb) for a detai ### Reviewing Tool Calls -Some user interaction patterns combine the above ideas. +Some user interaction patterns combine the concepts outlined above. -For example, many agents use [tool calling](https://python.langchain.com/docs/how_to/tool_calling/) to make decisions. +For example, many agents rely on [tool calling](https://python.langchain.com/docs/how_to/tool_calling/) to make decisions. Tool calling introduces unique challenges because the agent must get multiple aspects right: -Tool calling presents a challenge because the agent must get two things right: +1. **Selecting the correct tool**: The agent must choose the appropriate tool to call. +2. **Providing accurate arguments**: The agent must pass the correct parameters to the tool. +3. **Ensuring discretion**: Even if the tool call is technically correct, it might involve sensitive operations that require human approval. -1. The name of the tool to call -2. The arguments to pass to the tool - -Even if the tool call is correct, we may also want to apply discretion: - -(3) The tool call may be a sensitive operation that we want to approve - -With these points in mind, we can combine the above ideas to create a human-in-the-loop review of a tool call. +By addressing these challenges, we can integrate **human-in-the-loop** processes to review and approve tool calls effectively. ```python # Compile our graph with a checkpointer and a breakpoint before the step to review the tool call from the LLM @@ -385,7 +380,7 @@ for event in graph.stream(None, thread, stream_mode="values"): print(event) ``` -See [this guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a detailed how-to on doing this! +See [the how to review tool calls guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a details. ### Time Travel From 5e13460604d47ab48dacafba03f1d43a3b573384 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 5 Dec 2024 23:31:54 -0500 Subject: [PATCH 14/72] x --- docs/docs/concepts/human_in_the_loop.md | 242 ++++++------------------ 1 file changed, 60 insertions(+), 182 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index efeb860e3..77c70ca1b 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -2,10 +2,11 @@ !!! tip "This guide uses the new `interrupt` function." - As of LangGraph 0.2.57, the recommended way to set breakpoints is using `interrupt` function as it significantly + As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [interrupt](../reference/types.md#langgraph.types.interrupt) function as it significantly simpifies **human-in-the-loop** patterns. - If you're looking for the previous version of this conceptual guide, which uses static breakpoints and `NodeInterrupt` exception, it is available [here](./low_level.md#breakpoints). + If you're looking for the previous version of this conceptual guide, which relied on static breakpoints and and `NodeInterrupt` exception, it is available [here](v0-human-in-the-loop.md). + **Human-in-the-loop** (or "on-the-loop") workflows enhance agent capabilities by incorporating human interactions at key points. Common interaction patterns include: @@ -20,222 +21,99 @@ Use-cases for these interaction patterns include: ## Persistence -**Human-in-the-loop** patterns are enabled by LangGraph's built-in [persistence](./persistence.md) layer, which writes a checkpoint of the graph state at each step, allowing for resumption of execution. You **must compile** your graph with a checkpointer to use breakpoints. +The [persistence](./persistence.md) layer in LangGraph writes a **checkpoint** of the graph state at each step, enabling the graph to **pause** and **resume** execution. This functionality is essential for supporting **human-in-the-loop** workflows. -## Breakpoints +## Breakpoints -Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. - -1. [**Interrupt function**](#interrupt-function): Pause the graph from **inside** a node. This is the recommended way to set breakpoints for human-in-the-loop workflows. -1. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. -2. [**Using the `interrupt` function**](#interrupt-function): Pause the graph from **inside** a node. - -## Interrupt - -An `interrupt` is a particularly convenient way to support human-in-the-loop workflows. To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state. An `interrupt` can be used within a node to pause execution and wait for input, as shown in this example: - -You can think of an `interrupt` as similar to how the `input` function works, but with the difference -that graph execution always **resumes** from the **beginning** of the node where the `interrupt` was called. This means that you have to: - -1. Be cautious of side effects, such as API calls that mutate data, as these may inadvertently be triggered multiple times. -2. Be aware that the node will be re-run with the same graph state, so you may need to update the state to avoid the same `interrupt` being triggered again. +The recommended method to set breakpoints in LangGraph is using the [interrupt](../reference/types.md/#langgraph.types.interrupt) function. The `interrupt` function pauses execution **from inside a node** and surfaces interrupt information to the client. To use the `interrupt` function, the graph must be compiled with a [checkpointer](./persistence.md) to maintain state persistence. ```python from langgraph.types import interrupt def node(state: State): + ... + # Pause the graph and wait for user input. answer = interrupt( - # This value will be sent to the client. { "question": "What is your age?", - "options": ["18-24", "25-34", "35-44", "45-54", "55-64", "65+"], } ) - print(f"> Received an input from the interrupt: {answer}") - return {"human_value": answer} + # Answer is the value provided by the client via `Command(resume=answer)` + print(f"Value received from interrupt: {answer}") + # Do something with the answer. + ... + +graph_builder.add_node("node", node) + +# The checkpointer is required for the `interrupt` function to work. +graph = graph_builder.compile(checkpointer=checkpointer) ``` +??? warning "Graph execution resumes from the beginning of the node not the exact point of the `interrupt`" + Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`, unlike a traditional breakpoint or Python's `input()` function. Keep the following considerations in mind when using the `interrupt` function: + 1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. + 2. **Multiple interrupts**: Using multiple `interrupt` calls in a node is useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. - -Breakpoints allow **pausing** graph execution to allow for human review before **resuming** execution. - -The recommended way to set breakpoints is to use the `interrupt` function. This function allows you to pause the graph from **inside** a node, and surface a value to the client as part of the interrupt information. - -You have a few options for setting breakpoints, but the recommended approach for newer versions of LangGraph is to use the `interrupt` function. - -1. [**Static breakpoints**](#static-breakpoints): Pause the graph **before** or **after** a node executes. -2. [**Using the `interrupt` function**](#interrupt-function): Pause the graph from **inside** a node. - -### Using the `interrupt` function - +Now, we can run the graph and observe that it pauses at the `interrupt` function: ```python -# A checkpointer must be enabled for interrupts to work! -checkpointer = MemorySaver() -graph = builder.compile(checkpointer=checkpointer) -``` - - -### Static Breakpoints - -Use static breakpoints if you want to **ALWAYS** pause the graph either **before** or **after** one or more nodes execute. - -To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). - -```python -# Compile our graph with a checkpointer and a breakpoint before "node_a" and after "node_b" and "node_c" -graph = graph_builder.compile( - interrupt_before=["node_a"], - interrupt_after=["node_b", "node_c"], - checkpointer=checkpointer, # Required -) -``` - -When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. - - -Here, we compile our graph with a checkpointer and a breakpoint at the node we want to interrupt before, `step_for_human_in_the_loop`. We then perform one of the above interaction patterns, which will create a new checkpoint if a human edits the graph state. The new checkpoint is saved to the `thread` and we can resume the graph execution from there by passing in `None` as the input. - -```python -# Compile our graph with a checkpointer and a breakpoint before "step_for_human_in_the_loop" -graph = builder.compile(checkpointer=checkpointer, interrupt_before=["step_for_human_in_the_loop"]) - # Run the graph up to the breakpoint -thread_config = {"configurable": {"thread_id": "1"}} +thread_config = {"configurable": {"thread_id": "some_id"}} for event in graph.stream(inputs, thread_config, stream_mode="values"): print(event) - -# Perform some action that requires human in the loop - -# Continue the graph execution from the current checkpoint -for event in graph.stream(None, thread_config, stream_mode="values"): - print(event) ``` -### Dynamic Breakpoints - -Alternatively, you may want to raise a breakpoint from inside a node, potentially based on some condition that is not known until runtime. This is called a dynamic breakpoint. - -This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. - -There are two ways to interrupt the graph dynamically: - -1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. -2. `NodeInterrupt` exception: An older, less flexible method for interrupting. - -Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. - -```python -def my_node(state: State) -> State: - if len(state['input']) > 5: - raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") - return state -``` - -Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. - -```python -# Attempt to continue the graph execution with no change to state after we hit the dynamic breakpoint -for event in graph.stream(None, thread_config, stream_mode="values"): - print(event) -``` - -The graph will *interrupt* again because this node will be *re-run* with the same graph state. We need to change the graph state such that the condition that triggers the dynamic breakpoint is no longer met. So, we can simply edit the graph state to an input that meets the condition of our dynamic breakpoint (< 5 characters) and re-run the node. - -```python -# Update the state to pass the dynamic breakpoint -graph.update_state(config=thread_config, values={"input": "foo"}) -for event in graph.stream(None, thread_config, stream_mode="values"): - print(event) -``` - -Alternatively, what if we want to keep our current input and skip the node (`my_node`) that performs the check? To do this, we can simply perform the graph update with `as_node="my_node"` and pass in `None` for the values. This will make no update the graph state, but run the update as `my_node`, effectively skipping the node and bypassing the dynamic breakpoint. - -```python -# This update will skip the node `my_node` altogether -graph.update_state(config=thread_config, values=None, as_node="my_node") -for event in graph.stream(None, thread_config, stream_mode="values"): - print(event) -``` - -See [our guide](../how-tos/human_in_the_loop/dynamic_breakpoints.ipynb) for a detailed how-to on doing this! - -### Dynamic Breakpoints - -There are two ways to interrupt the graph dynamically: - -1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. -2. `NodeInterrupt` exception: An older, less flexible method for interrupting. - -#### `interrupt` - -```python -from langgraph.types import interrupt - -def node(state: State): - ... - client_value = interrupt( - # This value will be sent to the client. - # It can be any JSON serializable value. - {"key": "value"} +```pycon +{'__interrupt__': ( + Interrupt( + value={'question': 'what is your age?'}, + resumable=True, + ns=['node:5df255f7-d683-1a99-b7c8-00dd534aed8e'], + when='during' + ), ) - ... +} ``` -#### `NodeInterrupt` +??? note "Using other types of breakpoints" -Throw a `NodeInterrupt` exception to interrupt the graph. + The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. + + See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. + + +## Resuming + +After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: + +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. +2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. +3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. + +Here’s how resumption works in practice: ```python -def my_node(state: State) -> State: - if len(state['input']) > 5: - raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") - - return state +# Resume graph execution with the user's input. +graph.invoke(Command(resume={"age": "25"}), thread_config) ``` -### Resuming +By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. -When a breakpoint is hit, graph execution will pause. +### Usage with invoke/ainvoke -=== "Command" - Resume execution using the new `Command` primitive. - - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - graph.invoke( - Command( - # Use `resume` to pass a value to the `interrupt`. - resume=resume, - # For other kinds of breakpoints, use `update` to update the state. - update=update, - ), - config=config - ) - ``` - -=== "Without the Command Primitive" - - Resume execution without the `Command` primitive (older versions of LangGraph). - - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - - graph.update_state(update, config=config) - graph.invoke(None, config=config) - ``` - -See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. +The `invoke` and `ainvoke` methods differ from `stream` and `astream` in how they handle interrupts. While these methods pause execution at the `interrupt` function, they do not return interrupt information directly. To retrieve this information, you need to access the graph state using the `get_state` method. +```python +# Run the graph up to the breakpoint +result = graph.invoke(inputs, thread_config) +# Get the graph state to get interrupt information. +state = graph.get_state(thread_config) +# Resume the graph with the user's input. +graph.invoke(Command(resume={"age": "25"}), thread_config) +``` ## Interaction Patterns From e16312da3f0d76a80b490a82855e06171c9f65ce Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 6 Dec 2024 16:52:33 -0500 Subject: [PATCH 15/72] x --- docs/docs/concepts/human_in_the_loop.md | 78 ++++++++++++++++--------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 77c70ca1b..1029cb704 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -5,27 +5,33 @@ As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [interrupt](../reference/types.md#langgraph.types.interrupt) function as it significantly simpifies **human-in-the-loop** patterns. - If you're looking for the previous version of this conceptual guide, which relied on static breakpoints and and `NodeInterrupt` exception, it is available [here](v0-human-in-the-loop.md). + If you're looking for the previous version of this conceptual guide, which relied on static breakpoints and `NodeInterrupt` exception, it is available [here](v0-human-in-the-loop.md). +A **human-in-the-loop** (or "on-the-loop") workflow integrates human input into automated processes, allowing for decisions, validation, or corrections at key stages. This is especially useful in **LLM-based applications**, where the underlying model may generate occasional inaccuracies. In low-error-tolerance scenarios like compliance, decision-making, or content generation, human involvement ensures reliability by enabling review, correction, or override of model outputs. -**Human-in-the-loop** (or "on-the-loop") workflows enhance agent capabilities by incorporating human interactions at key points. Common interaction patterns include: +## Use cases -1. ✅ **Approval**: Pause the agent, present its current state to the user, and allow the user to approve or reject a proposed action. -2. 📝 **Editing**: Pause the agent, present its current state to the user, and allow the user to make modifications to the agent's state. -3. 💬 **Input**: Introduce a dedicated graph node to explicitly collect user input, which is then integrated into the agent's state. +Key use cases for **human-in-the-loop** workflows in LLM-based applications include: -Use-cases for these interaction patterns include: +1. **🛠️ [Reviewing tool calls](#reviewing-tool-calls)**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. +2. **✅ Validating LLM outputs**: Ensure accuracy by reviewing, editing, or approving the LLM's generated outputs. +3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details, improving decision-making and accuracy. +4. **🔍 Debugging**: Investigate and correct errors in the LLM's decision-making process. This is mostly developer facing. -1. [**Reviewing tool calls**](#reviewing-tool-calls): Pause the agent to review and edit the results of tool executions. -2. [**Time travel**](#time-travel): Replay or fork the agent's past actions for further exploration. +## Interrupt & Resume -## Persistence +**Human-in-the-loop** works in the following manner: -The [persistence](./persistence.md) layer in LangGraph writes a **checkpoint** of the graph state at each step, enabling the graph to **pause** and **resume** execution. This functionality is essential for supporting **human-in-the-loop** workflows. +1. [**Persistence**](./persistence.md): the graph state is saved after each graph step, enabling **pausing** and **resuming** execution. +2. [**Interrupting execution**](#interrupting-execution): the [`interrupt`](../reference/types.md#langgraph.types.interrupt) function is used to **pause** the graph at specific points for user input. +3. [**Running the graph**](#run): the graph is executed until it reaches the **breakpoint**. +4. [**Resuming execution**](#resuming-execution): the [`Command`](../reference/types.md#langgraph.types.Command) primitive allows **resuming** execution based on user input. -## Breakpoints +> **Note:** While there are other ways to set breakpoints (e.g., static breakpoints or dynamic exceptions) and resume execution (e.g., by relying on state updates `graph.update_state`), this guide focuses on the `interrupt` function and `Command` primitive as the recommended methods. -The recommended method to set breakpoints in LangGraph is using the [interrupt](../reference/types.md/#langgraph.types.interrupt) function. The `interrupt` function pauses execution **from inside a node** and surfaces interrupt information to the client. To use the `interrupt` function, the graph must be compiled with a [checkpointer](./persistence.md) to maintain state persistence. +### Interrupt + +Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing you to collect user input, validate the graph state, or make decisions before resuming execution. The graph must be compiled with a [checkpointer](./persistence.md) to maintain state persistence. ```python from langgraph.types import interrupt @@ -38,7 +44,7 @@ def node(state: State): "question": "What is your age?", } ) - # Answer is the value provided by the client via `Command(resume=answer)` + # Answer will be assigned a value when the graph resumes (see below). print(f"Value received from interrupt: {answer}") # Do something with the answer. ... @@ -56,7 +62,9 @@ graph = graph_builder.compile(checkpointer=checkpointer) 1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. 2. **Multiple interrupts**: Using multiple `interrupt` calls in a node is useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. -Now, we can run the graph and observe that it pauses at the `interrupt` function: +### Run + +**Run the graph** and observe the `interrupt` function in action: ```python # Run the graph up to the breakpoint @@ -77,14 +85,34 @@ for event in graph.stream(inputs, thread_config, stream_mode="values"): } ``` -??? note "Using other types of breakpoints" +??? note "Using with `invoke` and `ainvoke`" - The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. + `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the `get_state` method to retrieve the graph state after calling `invoke` or `ainvoke`. - See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. + ```python + # Run the graph up to the breakpoint + result = graph.invoke(inputs, thread_config) + # Get the graph state to get interrupt information. + state = graph.get_state(thread_config) + # Resume the graph with the user's input. + graph.invoke(Command(resume={"age": "25"}), thread_config) + ``` +### Resume -## Resuming +Once you have collected user input, you can **resume** the graph execution using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: + +```python +graph.invoke(Command(resume={"age": "25"}), thread_config) +``` + +You should see the following output printed by to the `print` function in the `node` function: + +```pycon +Value received from interrupt: {'age': '25'} +``` + +## Options for resuming execution After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: @@ -101,19 +129,13 @@ graph.invoke(Command(resume={"age": "25"}), thread_config) By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. -### Usage with invoke/ainvoke +??? note "Using other types of breakpoints" -The `invoke` and `ainvoke` methods differ from `stream` and `astream` in how they handle interrupts. While these methods pause execution at the `interrupt` function, they do not return interrupt information directly. To retrieve this information, you need to access the graph state using the `get_state` method. + The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. + + See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. -```python -# Run the graph up to the breakpoint -result = graph.invoke(inputs, thread_config) -# Get the graph state to get interrupt information. -state = graph.get_state(thread_config) -# Resume the graph with the user's input. -graph.invoke(Command(resume={"age": "25"}), thread_config) -``` ## Interaction Patterns From a19d06e18c322ce63205d631490cfe4c232ca316 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 6 Dec 2024 17:00:18 -0500 Subject: [PATCH 16/72] x --- docs/docs/concepts/human_in_the_loop.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 1029cb704..6d5bac05c 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -14,24 +14,24 @@ A **human-in-the-loop** (or "on-the-loop") workflow integrates human input into Key use cases for **human-in-the-loop** workflows in LLM-based applications include: 1. **🛠️ [Reviewing tool calls](#reviewing-tool-calls)**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. -2. **✅ Validating LLM outputs**: Ensure accuracy by reviewing, editing, or approving the LLM's generated outputs. -3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details, improving decision-making and accuracy. -4. **🔍 Debugging**: Investigate and correct errors in the LLM's decision-making process. This is mostly developer facing. - +2. **✅ Validating LLM outputs**: Ensure accuracy by reviewing, editing, or approving content generated by the LLM. +3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details. +4. **🔍 Debugging**: Investigate and correct errors in the LLM's decision-making process. + ## Interrupt & Resume **Human-in-the-loop** works in the following manner: 1. [**Persistence**](./persistence.md): the graph state is saved after each graph step, enabling **pausing** and **resuming** execution. -2. [**Interrupting execution**](#interrupting-execution): the [`interrupt`](../reference/types.md#langgraph.types.interrupt) function is used to **pause** the graph at specific points for user input. +2. [**Interrupting execution**](#interrupting-execution): the [`interrupt`](../reference/types.md#langgraph.types.interrupt) function is used to **pause** the graph at specific points for **human input**. 3. [**Running the graph**](#run): the graph is executed until it reaches the **breakpoint**. -4. [**Resuming execution**](#resuming-execution): the [`Command`](../reference/types.md#langgraph.types.Command) primitive allows **resuming** execution based on user input. +4. [**Resuming execution**](#resuming-execution): the [`Command`](../reference/types.md#langgraph.types.Command) primitive allows **resuming** execution based on **human input**. > **Note:** While there are other ways to set breakpoints (e.g., static breakpoints or dynamic exceptions) and resume execution (e.g., by relying on state updates `graph.update_state`), this guide focuses on the `interrupt` function and `Command` primitive as the recommended methods. ### Interrupt -Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing you to collect user input, validate the graph state, or make decisions before resuming execution. The graph must be compiled with a [checkpointer](./persistence.md) to maintain state persistence. +Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing you to collect user input, validate the graph state, or make decisions before resuming execution. The graph must be compiled with a [checkpointer](./persistence.md) so graph execution can be paused and resumed. ```python from langgraph.types import interrupt @@ -87,7 +87,7 @@ for event in graph.stream(inputs, thread_config, stream_mode="values"): ??? note "Using with `invoke` and `ainvoke`" - `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the `get_state` method to retrieve the graph state after calling `invoke` or `ainvoke`. + `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. ```python # Run the graph up to the breakpoint @@ -112,6 +112,10 @@ You should see the following output printed by to the `print` function in the `n Value received from interrupt: {'age': '25'} ``` +## Resuming Execution + +Execution is always resumed from the **beginning** of the **graph node** where the `interrupt` was used. + ## Options for resuming execution After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: From 0d580bdac758e4ee0cd105474fe8855a461536ee Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 6 Dec 2024 22:31:11 -0500 Subject: [PATCH 17/72] x --- docs/docs/concepts/persistence.md | 2 +- docs/docs/concepts/time-travel.md | 72 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 docs/docs/concepts/time-travel.md diff --git a/docs/docs/concepts/persistence.md b/docs/docs/concepts/persistence.md index 0ec126316..dccf6a36f 100644 --- a/docs/docs/concepts/persistence.md +++ b/docs/docs/concepts/persistence.md @@ -471,7 +471,7 @@ Second, checkpointers allow for ["memory"](agentic_concepts.md#memory) between i ### Time Travel -Third, checkpointers allow for ["time travel"](../how-tos/human_in_the_loop/time-travel.ipynb), allowing users to replay prior graph executions to review and / or debug specific graph steps. In addition, checkpointers make it possible to fork the graph state at arbitrary checkpoints to explore alternative trajectories. +Third, checkpointers allow for ["time travel"](time-travel.md), allowing users to replay prior graph executions to review and / or debug specific graph steps. In addition, checkpointers make it possible to fork the graph state at arbitrary checkpoints to explore alternative trajectories. ### Fault-tolerance diff --git a/docs/docs/concepts/time-travel.md b/docs/docs/concepts/time-travel.md new file mode 100644 index 000000000..5592aba3f --- /dev/null +++ b/docs/docs/concepts/time-travel.md @@ -0,0 +1,72 @@ +# Time Travel ⏱️ + +!!! note "Prerequisites" + + This guide assumes that you are familiar with LangGraph's checkpoints and states. If not, please review the [persistence](./persistence.md) concept first. + + +When working with non-deterministic systems that make model-based decisions (e.g., agents powered by LLMs), it can be useful to examine their decision-making process in detail: + +1. 🤔 **Understand Reasoning**: Analyze the steps that led to a successful result. +2. 🐞 **Debug Mistakes**: Identify where and why errors occurred. +3. 🔍 **Explore Alternatives**: Test different paths to uncover better solutions. + +We call these debugging techniques **Time Travel**, composed of two key actions: [**Replaying**](#replaying) 🔁 and [**Forking**](#forking) 🔀 . + +## Replaying + +![](./img/human_in_the_loop/replay.png) + +Replaying allows us to revisit and reproduce an agent's past actions. This can be done either from the current state (or checkpoint) of the graph or from a specific checkpoint. + +To replay from the current state, simply pass `None` as the input along with a `thread`: + +```python +thread = {"configurable": {"thread_id": "1"}} +for event in graph.stream(None, thread, stream_mode="values"): + print(event) +``` + +To replay actions from a specific checkpoint, start by retrieving all checkpoints for the thread: + +```python +all_checkpoints = [] +for state in graph.get_state_history(thread): + all_checkpoints.append(state) +``` + +Each checkpoint has a unique ID. After identifying the desired checkpoint, for instance, `xyz`, include its ID in the configuration: + +```python +config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xyz'}} +for event in graph.stream(None, config, stream_mode="values"): + print(event) +``` + +The graph efficiently replays previously executed nodes instead of re-executing them, leveraging its awareness of prior checkpoint executions. + +## Forking + +![](./img/human_in_the_loop/forking.png) + +Forking allows you to revisit an agent's past actions and explore alternative paths within the graph. + +To edit a specific checkpoint, such as `xyz`, provide its `checkpoint_id` when updating the graph's state: + +```python +config = {"configurable": {"thread_id": "1", "checkpoint_id": "xyz"}} +graph.update_state(config, {"state": "updated state"}, ) +``` + +This creates a new forked checkpoint, xyz-fork, from which you can continue running the graph: + +```python +config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xyz-fork'}} +for event in graph.stream(None, config, stream_mode="values"): + print(event) +``` + +## Additional Resources 📚 + +- [**Conceptual Guide: Persistence**](https://langchain-ai.github.io/langgraph/concepts/persistence/#replay): Read the persistence guide for more context on replaying. +- [**How to View and Update Past Graph State**](../how-tos/human_in_the_loop/time-travel.ipynb): Step-by-step instructions for working with graph state that demonstrate the **replay** and **fork** actions. From cc4718c5cb42b22b9b07fd3bc929a9375b054fe7 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 6 Dec 2024 22:31:18 -0500 Subject: [PATCH 18/72] x --- docs/docs/concepts/human_in_the_loop.md | 132 ++++++------------------ 1 file changed, 32 insertions(+), 100 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 6d5bac05c..f306aaffe 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -9,18 +9,24 @@ A **human-in-the-loop** (or "on-the-loop") workflow integrates human input into automated processes, allowing for decisions, validation, or corrections at key stages. This is especially useful in **LLM-based applications**, where the underlying model may generate occasional inaccuracies. In low-error-tolerance scenarios like compliance, decision-making, or content generation, human involvement ensures reliability by enabling review, correction, or override of model outputs. +## Interaction Patterns + +1. **Approval**/**Rejection**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. +2. **Editing**: Pause the graph to review and edit the agent's state. This is useful for correcting mistakes or updating the agent's state. +3. **Input**: Explicitly request human input at a particular step in the graph. This is useful for collecting additional information or context to inform the agent's decision-making process. + ## Use cases Key use cases for **human-in-the-loop** workflows in LLM-based applications include: 1. **🛠️ [Reviewing tool calls](#reviewing-tool-calls)**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. -2. **✅ Validating LLM outputs**: Ensure accuracy by reviewing, editing, or approving content generated by the LLM. +2. **✅ Validating LLM outputs**: Humans can review, edit, or approve content generated by the LLM. 3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details. 4. **🔍 Debugging**: Investigate and correct errors in the LLM's decision-making process. ## Interrupt & Resume -**Human-in-the-loop** works in the following manner: +**Human-in-the-loop** workflow consists of four key steps: 1. [**Persistence**](./persistence.md): the graph state is saved after each graph step, enabling **pausing** and **resuming** execution. 2. [**Interrupting execution**](#interrupting-execution): the [`interrupt`](../reference/types.md#langgraph.types.interrupt) function is used to **pause** the graph at specific points for **human input**. @@ -57,10 +63,6 @@ graph = graph_builder.compile(checkpointer=checkpointer) ??? warning "Graph execution resumes from the beginning of the node not the exact point of the `interrupt`" - Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`, unlike a traditional breakpoint or Python's `input()` function. Keep the following considerations in mind when using the `interrupt` function: - - 1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. - 2. **Multiple interrupts**: Using multiple `interrupt` calls in a node is useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. ### Run @@ -112,37 +114,14 @@ You should see the following output printed by to the `print` function in the `n Value received from interrupt: {'age': '25'} ``` -## Resuming Execution - -Execution is always resumed from the **beginning** of the **graph node** where the `interrupt` was used. - -## Options for resuming execution - -After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: - -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. -2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. -3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. - -Here’s how resumption works in practice: - -```python -# Resume graph execution with the user's input. -graph.invoke(Command(resume={"age": "25"}), thread_config) -``` - -By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. - - -??? note "Using other types of breakpoints" - - The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. - - See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. - - ## Interaction Patterns +1. **Approval**/**Rejection**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected. + +2. **Editing**: Pause the graph to review and edit the agent's state. This is useful for correcting mistakes or updating the agent's state. + + + ### Approval ![](./img/human_in_the_loop/approval.png) @@ -286,87 +265,40 @@ for event in graph.stream(None, thread, stream_mode="values"): See [the how to review tool calls guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a details. -### Time Travel -When working with agents, we often want closely examine their decision making process: +## Advanced -(1) Even when they arrive a desired final result, the reasoning that led to that result is often important to examine. +### How does an `interrupt` work? -(2) When agents make mistakes, it is often valuable to understand why. +Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`. -(3) In either of the above cases, it is useful to manually explore alternative decision making paths. +Please note that this is **unlike** a traditional breakpoint or Python's `input()` function. As a result, you should structure your graph nodes to handle the `interrupt` and `resume` logic effectively. -Collectively, we call these debugging concepts `time-travel` and they are composed of `replaying` and `forking`. +Keep the following considerations in mind when using the `interrupt` function: -#### Replaying +1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. +2. **Multiple interrupts**: Using multiple `interrupt` calls in a node can be very useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. -![](./img/human_in_the_loop/replay.png) -Sometimes we want to simply replay past actions of an agent. - -Above, we showed the case of executing an agent from the current state (or checkpoint) of the graph. +### Options for resuming execution -We by simply passing in `None` for the input with a `thread`. +After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: -``` -thread = {"configurable": {"thread_id": "1"}} -for event in graph.stream(None, thread, stream_mode="values"): - print(event) -``` - -Now, we can modify this to replay past actions from a *specific* checkpoint by passing in the checkpoint ID. - -To get a specific checkpoint ID, we can easily get all of the checkpoints in the thread and filter to the one we want. +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. +2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. +3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. ```python -all_checkpoints = [] -for state in app.get_state_history(thread): - all_checkpoints.append(state) +# Resume graph execution with the user's input. +graph.invoke(Command(resume={"age": "25"}), thread_config) ``` -Each checkpoint has a unique ID, which we can use to replay from a specific checkpoint. +By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. -Assume from reviewing the checkpoints that we want to replay from one, `xxx`. +??? note "Using other types of breakpoints" -We just pass in the checkpoint ID when we run the graph. + The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. -```python -config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xxx'}} -for event in graph.stream(None, config, stream_mode="values"): - print(event) -``` - -Importantly, the graph knows which checkpoints have been previously executed. + See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. -So, it will re-play any previously executed nodes rather than re-executing them. -See [this additional conceptual guide](https://langchain-ai.github.io/langgraph/concepts/persistence/#replay) for related context on replaying. - -See see [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a detailed how-to on doing time-travel! - -#### Forking - -![](./img/human_in_the_loop/forking.png) - -Forking allows us to revisit an agent's past actions and explore alternative paths through the graph. - -The **Editing** pattern, as described earlier, enables modifications to the *current* state of the graph. But what if you want to fork from a *past* state? - -For instance, suppose you want to edit a specific checkpoint, such as `xyz`. You can achieve this by providing the relevant `checkpoint_id` when updating the graph's state. - -```python -config = {"configurable": {"thread_id": "1", "checkpoint_id": "xyz"}} -graph.update_state(config, {"state": "updated state"}, ) -``` - -This creates a new forked checkpoint, `xyz-fork`, which we can then run the graph from. - -```python -config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xyz-fork'}} -for event in graph.stream(None, config, stream_mode="values"): - print(event) -``` - -See [this additional conceptual guide](https://langchain-ai.github.io/langgraph/concepts/persistence/#update-state) for related context on forking. - -See see [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a detailed how-to on doing time-travel! From 1dda28f8fbee05054329a1465afced865281b70c Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 6 Dec 2024 22:31:28 -0500 Subject: [PATCH 19/72] x --- docs/docs/concepts/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/concepts/index.md b/docs/docs/concepts/index.md index 6c057c672..47c93c1be 100644 --- a/docs/docs/concepts/index.md +++ b/docs/docs/concepts/index.md @@ -25,6 +25,7 @@ The conceptual guide does not cover step-by-step instructions or specific implem - [Common Agentic Patterns](agentic_concepts.md): An agent uses an LLM to pick its own control flow to solve more complex problems! Agents are a key building block in many LLM applications. This guide explains the different types of agent architectures and how they can be used to control the flow of an application. - [Multi-Agent Systems](multi_agent.md): Complex LLM applications can often be broken down into multiple agents, each responsible for a different part of the application. This guide explains common patterns for building multi-agent systems. - [Human-in-the-Loop](human_in_the_loop.md): Explains different ways of integrating human feedback into a LangGraph application. +- [Time Travel](time-travel.md): Time travel allows you to replay past actions in your LangGraph application to explore alternative paths and debug issues. - [Persistence](persistence.md): LangGraph has a built-in persistence layer, implemented through checkpointers. This persistence layer helps to support powerful capabilities like human-in-the-loop, memory, time travel, and fault-tolerance. - [Memory](memory.md): Memory in AI applications refers to the ability to process, store, and effectively recall information from past interactions. With memory, your agents can learn from feedback and adapt to users' preferences. - [Streaming](streaming.md): Streaming is crucial for enhancing the responsiveness of applications built on LLMs. By displaying output progressively, even before a complete response is ready, streaming significantly improves user experience (UX), particularly when dealing with the latency of LLMs. From b4f7e06a1dda547f6934448f58a69416eb38ccd5 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 6 Dec 2024 22:42:41 -0500 Subject: [PATCH 20/72] x --- docs/docs/concepts/human_in_the_loop.md | 130 ++++++++---------------- docs/docs/concepts/time-travel.md | 2 +- 2 files changed, 42 insertions(+), 90 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index f306aaffe..c49d0aae0 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -121,113 +121,65 @@ Value received from interrupt: {'age': '25'} 2. **Editing**: Pause the graph to review and edit the agent's state. This is useful for correcting mistakes or updating the agent's state. - -### Approval - -![](./img/human_in_the_loop/approval.png) - -Sometimes we want to approve certain steps in our agent's execution. - -We can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to the step that we want to approve. - -This is generally recommend for sensitive actions (e.g., using external APIs or writing to a database). - -With persistence, we can surface the current agent state as well as the next step to a user for review and approval. - -If approved, the graph resumes execution from the last saved checkpoint, which is saved to the `thread`: +### Approval/Rejection ```python -# Compile our graph with a checkpointer and a breakpoint before the step to approve -graph = builder.compile(checkpointer=checkpointer, interrupt_before=["node_2"]) - -# Run the graph up to the breakpoint -for event in graph.stream(inputs, thread, stream_mode="values"): - print(event) +def node(state): + ... + # Pause the graph and wait for user input. + approval = interrupt( + { + "question": "Do you approve this action?", + # Surface the current state or any other relevant information. + "state": state, + } + ) -# ... Get human approval ... - -# If approved, continue the graph execution from the last saved checkpoint -for event in graph.stream(None, thread, stream_mode="values"): - print(event) + if not isinstance(approval, bool): + raise ValueError("Approval must be a boolean value.") + + if approval: + # Perform the action. + ... + else: + # Skip the action. + ... ``` -See [our guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a detailed how-to on doing this! - ### Editing -![](./img/human_in_the_loop/edit_graph_state.png) - -Sometimes we want to review and edit the agent's state. - -As with approval, we can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to the step we want to check. - -We can surface the current state to a user and allow the user to edit the agent state. - -This can, for example, be used to correct the agent if it made a mistake (e.g., see the section on tool calling below). - -We can edit the graph state by forking the current checkpoint, which is saved to the `thread`. - -We can then proceed with the graph from our forked checkpoint as done before. - ```python -# Compile our graph with a checkpointer and a breakpoint before the step to review -graph = builder.compile(checkpointer=checkpointer, interrupt_before=["node_2"]) - -# Run the graph up to the breakpoint -for event in graph.stream(inputs, thread, stream_mode="values"): - print(event) +def node(state): + ... + # Pause the graph and wait for user input. + user_input = interrupt( + { + "question": "Please provide additional information:", + # Surface the current state or any other relevant information. + "state": state, + } + ) + return { + # some state update based on user input + } -# Review the state, decide to edit it, and create a forked checkpoint with the new state -graph.update_state(thread, {"state": "new state"}) - -# Continue the graph execution from the forked checkpoint -for event in graph.stream(None, thread, stream_mode="values"): - print(event) ``` -See [this guide](../how-tos/human_in_the_loop/edit-graph-state.ipynb) for a detailed how-to on doing this! - ### Input -![](./img/human_in_the_loop/wait_for_input.png) - -Sometimes we want to explicitly get human input at a particular step in the graph. - -We can create a graph node designated for this (e.g., `human_input` in our example diagram). - -As with approval and editing, we can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to this node. - -We can then perform a state update that includes the human input, just as we did with editing state. - -But, we add one thing: - -We can use `as_node=human_input` with the state update to specify that the state update *should be treated as a node*. - -The is subtle, but important: - -With editing, the user makes a decision about whether or not to edit the graph state. - -With input, we explicitly define a node in our graph for collecting human input! - -The state update with the human input then runs *as this node*. - ```python -# Compile our graph with a checkpointer and a breakpoint before the step to to collect human input -graph = builder.compile(checkpointer=checkpointer, interrupt_before=["human_input"]) -# Run the graph up to the breakpoint -for event in graph.stream(inputs, thread, stream_mode="values"): - print(event) +def node(state): + ... + # Pause the graph and wait for user input. + human_message = interrupt() + return { + "messages": [human_message] + } -# Update the state with the user input as if it was the human_input node -graph.update_state(thread, {"user_input": user_input}, as_node="human_input") - -# Continue the graph execution from the checkpoint created by the human_input node -for event in graph.stream(None, thread, stream_mode="values"): - print(event) ``` -See [this guide](../how-tos/human_in_the_loop/wait-user-input.ipynb) for a detailed how-to on doing this! +### ## Use-cases diff --git a/docs/docs/concepts/time-travel.md b/docs/docs/concepts/time-travel.md index 5592aba3f..bb7fd334b 100644 --- a/docs/docs/concepts/time-travel.md +++ b/docs/docs/concepts/time-travel.md @@ -55,7 +55,7 @@ To edit a specific checkpoint, such as `xyz`, provide its `checkpoint_id` when u ```python config = {"configurable": {"thread_id": "1", "checkpoint_id": "xyz"}} -graph.update_state(config, {"state": "updated state"}, ) +graph.update_state(config, {"state": "updated state"}) ``` This creates a new forked checkpoint, xyz-fork, from which you can continue running the graph: From d0bf7837bd52f9f1b1887c33629a67b83fa2d44d Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 11:25:21 -0500 Subject: [PATCH 21/72] x --- docs/docs/concepts/breakpoints.md | 139 ++++++++++++++++++++++++ docs/docs/concepts/human_in_the_loop.md | 40 +------ docs/docs/concepts/index.md | 1 + 3 files changed, 141 insertions(+), 39 deletions(-) create mode 100644 docs/docs/concepts/breakpoints.md diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md new file mode 100644 index 000000000..25c25cbdc --- /dev/null +++ b/docs/docs/concepts/breakpoints.md @@ -0,0 +1,139 @@ +## Breakpoints + +Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. + +There are two types of breakpoints: + +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. + +Please see the [Human-in-the-Loop guide](../human_in_the_loop) for information about breakpoints. + +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. + +### Static Breakpoints + +To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). + +```python +graph = graph_builder.compile( + interrupt_before=["node_a"], + interrupt_after=["node_b", "node_c"], + checkpointer=..., # Required +) +``` + +When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. + +### Dynamic Breakpoints + +There are two ways to interrupt the graph dynamically: + +1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. +2. `NodeInterrupt` exception: An older, less flexible method for interrupting. + +#### `interrupt` + +```python +from langgraph.types import interrupt + +def node(state: State): + ... + client_value = interrupt( + # This value will be sent to the client. + # It can be any JSON serializable value. + {"key": "value"} + ) + ... +``` + +#### `NodeInterrupt` + +Throw a `NodeInterrupt` exception to interrupt the graph. + +```python +def my_node(state: State) -> State: + if len(state['input']) > 5: + raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") + + return state +``` + +### Resuming +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. + +When a breakpoint is hit, graph execution will pause. +Please see the [Human-in-the-Loop guide](../human_in_the_loop) for conceptual information about breakpoints. + +=== "Command" + + Resume execution using the new `Command` primitive. + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + graph.invoke( + Command( + # Use `resume` to pass a value to the `interrupt`. + resume=resume, + # For other kinds of breakpoints, use `update` to update the state. + update=update, + ), + config=config + ) + ``` + +=== "Without the Command Primitive" + + Resume execution without the `Command` primitive (older versions of LangGraph). + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + + graph.update_state(update, config=config) + graph.invoke(None, config=config) + ``` + +See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. + +### How does an `interrupt` work? + +Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`. + +Please note that this is **unlike** a traditional breakpoint or Python's `input()` function. As a result, you should structure your graph nodes to handle the `interrupt` and `resume` logic effectively. + +Keep the following considerations in mind when using the `interrupt` function: + +1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. +2. **Multiple interrupts**: Using multiple `interrupt` calls in a node can be very useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. + + +### Options for resuming execution + +After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: + +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. +2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. +3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. + +```python +# Resume graph execution with the user's input. +graph.invoke(Command(resume={"age": "25"}), thread_config) +``` + +By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. + +??? note "Using other types of breakpoints" + + The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. + + See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. + + diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index c49d0aae0..4dffc336a 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -215,42 +215,4 @@ for event in graph.stream(None, thread, stream_mode="values"): print(event) ``` -See [the how to review tool calls guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a details. - - -## Advanced - -### How does an `interrupt` work? - -Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`. - -Please note that this is **unlike** a traditional breakpoint or Python's `input()` function. As a result, you should structure your graph nodes to handle the `interrupt` and `resume` logic effectively. - -Keep the following considerations in mind when using the `interrupt` function: - -1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. -2. **Multiple interrupts**: Using multiple `interrupt` calls in a node can be very useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. - - -### Options for resuming execution - -After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: - -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. -2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. -3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. - -```python -# Resume graph execution with the user's input. -graph.invoke(Command(resume={"age": "25"}), thread_config) -``` - -By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. - -??? note "Using other types of breakpoints" - - The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. - - See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. - - +See [the how to review tool calls guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a details. \ No newline at end of file diff --git a/docs/docs/concepts/index.md b/docs/docs/concepts/index.md index 47c93c1be..f0bf563bf 100644 --- a/docs/docs/concepts/index.md +++ b/docs/docs/concepts/index.md @@ -24,6 +24,7 @@ The conceptual guide does not cover step-by-step instructions or specific implem - [LangGraph Glossary](low_level.md): LangGraph workflows are designed as graphs, with nodes representing different components and edges representing the flow of information between them. This guide provides an overview of the key concepts associated with LangGraph graph primitives. - [Common Agentic Patterns](agentic_concepts.md): An agent uses an LLM to pick its own control flow to solve more complex problems! Agents are a key building block in many LLM applications. This guide explains the different types of agent architectures and how they can be used to control the flow of an application. - [Multi-Agent Systems](multi_agent.md): Complex LLM applications can often be broken down into multiple agents, each responsible for a different part of the application. This guide explains common patterns for building multi-agent systems. +- [Breakpoints](breakpoints.md): Breakpoints allow pausing the execution of a graph at specific points. Breakpoints are crucial for human-in-the-loop workflows, allowing human review before continuing. - [Human-in-the-Loop](human_in_the_loop.md): Explains different ways of integrating human feedback into a LangGraph application. - [Time Travel](time-travel.md): Time travel allows you to replay past actions in your LangGraph application to explore alternative paths and debug issues. - [Persistence](persistence.md): LangGraph has a built-in persistence layer, implemented through checkpointers. This persistence layer helps to support powerful capabilities like human-in-the-loop, memory, time travel, and fault-tolerance. From c279421cbf6caa2bf38e6a995645cb7261e0f544 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 14:46:06 -0500 Subject: [PATCH 22/72] x --- docs/docs/concepts/breakpoints.md | 186 ++++++++++++++++++++++-------- docs/docs/concepts/low_level.md | 106 +++++++++++++++++ 2 files changed, 244 insertions(+), 48 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index 25c25cbdc..2003df4cc 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -1,20 +1,28 @@ -## Breakpoints +# Breakpoints -Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. +Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. They rely on the graph's [**persistence layer**](./persistence.md), which saves the state after each graph step, to enable pausing and resuming execution. + +## Overview + +To use breakpoints, you will generally need to: + +1. [**Use a checkpointer**](persistence.md): Compile the graph with a checkpointer, so the graph state is saved after each graph step. +1. [**Set breakpoints**](#setting-breakpoints): Pause execution at selected points in the graph. +2. Run the graph until a breakpoint is hit. +3. [**Resume execution**](#resuming): Continue execution from the breakpoint. + +## Types of Breakpoints There are two types of breakpoints: -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. +1. [**Static breakpoints**](#static-breakpoints): Pause execution **before** or **after** a node by specifying `interrupt_before` and `interrupt_after` during [graph compilation](#compiling-your-graph). +2. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause execution from **inside** a node using the `interrupt` function or by raising a `NodeInterrupt` exception. -Please see the [Human-in-the-Loop guide](../human_in_the_loop) for information about breakpoints. +## Static Breakpoints -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. +Static breakpoints are triggered either **before** or **after** a node executes. To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph) or at run time when invoking the graph. -### Static Breakpoints - -To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). +#### Setting at Compilation time ```python graph = graph_builder.compile( @@ -24,16 +32,31 @@ graph = graph_builder.compile( ) ``` -When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. +#### Setting at Runtime -### Dynamic Breakpoints +```python +graph.invoke( + inputs, + config={"configurable": {"thread_id": "some_thread"}}, + interrupt_before=["node_a"], + interrupt_after=["node_b", "node_c"] +) +``` -There are two ways to interrupt the graph dynamically: +!!! note + + You cannot set static breakpoints at runtime for sub-graphs. + If you have a sub-graph, you must set the breakpoints at compilation time. + +## Dynamic Breakpoints + +You may want to raise a breakpoint from inside a node, potentially based on some condition that is not known until runtime. We +refer to these as **dynamic breakpoints**. 1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. 2. `NodeInterrupt` exception: An older, less flexible method for interrupting. -#### `interrupt` +### `interrupt` ```python from langgraph.types import interrupt @@ -48,7 +71,55 @@ def node(state: State): ... ``` -#### `NodeInterrupt` +### `NodeInterrupt` + + +This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. + +There are two ways to interrupt the graph dynamically: + +1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. +2. `NodeInterrupt` exception: An older, less flexible method for interrupting. + +Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. + +```python +def my_node(state: State) -> State: + if len(state['input']) > 5: + raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") + return state +``` + +Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. +Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. + +```python +# Attempt to continue the graph execution with no change to state after we hit the dynamic breakpoint +for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) +``` + +The graph will *interrupt* again because this node will be *re-run* with the same graph state. We need to change the graph state such that the condition that triggers the dynamic breakpoint is no longer met. So, we can simply edit the graph state to an input that meets the condition of our dynamic breakpoint (< 5 characters) and re-run the node. + +```python +# Update the state to pass the dynamic breakpoint +graph.update_state(config=thread_config, values={"input": "foo"}) +for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) +``` + + +## Updating with as_node + +Alternatively, what if we want to keep our current input and skip the node (`my_node`) that performs the check? To do this, we can simply perform the graph update with `as_node="my_node"` and pass in `None` for the values. This will make no update the graph state, but run the update as `my_node`, effectively skipping the node and bypassing the dynamic breakpoint. + +```python +# This update will skip the node `my_node` altogether +graph.update_state(config=thread_config, values=None, as_node="my_node") +for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) +``` + Throw a `NodeInterrupt` exception to interrupt the graph. @@ -60,48 +131,58 @@ def my_node(state: State) -> State: return state ``` -### Resuming -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. +!!! note "Use `interrupt` instead of `NodeInterrupt` if on recent LangGraph." -When a breakpoint is hit, graph execution will pause. -Please see the [Human-in-the-Loop guide](../human_in_the_loop) for conceptual information about breakpoints. + The `NodeInterrupt` exception is an older method for interrupting the graph. We recommend using the `interrupt` function instead as it allows passing a `resume` value to the client. This allows addin -=== "Command" + The `interrupt` function allows resuming using a `Command` primitive, which provides more flexibility than the `NodeInterrupt` exception. - Resume execution using the new `Command` primitive. +## Resuming - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - graph.invoke( - Command( - # Use `resume` to pass a value to the `interrupt`. - resume=resume, - # For other kinds of breakpoints, use `update` to update the state. - update=update, - ), - config=config - ) - ``` +When you run a graph with breakpoints, execution will pause at the breakpoint. To resume execution, you can: -=== "Without the Command Primitive" +1. [**Use the `Command` primitive**](#using-the-command-primitive): Pass a value to the `interrupt` or update the graph state. +2. [**Without the Command Primitive**](#without-the-command-primitive): Update the graph state and resume + +### Using the `Command` Primitive + +The new [Command](../reference/types.md#langgraph.types.Command) primitive provides a flexible way to resume execution after an `interrupt`. + +```python +graph.invoke(inputs, config=config) # This will pause at the breakpoint + +# Do something (e.g., get human input) +graph.invoke( + Command( + # Use `resume` to pass a value to the `interrupt`. + resume=resume, + ), + config=config +) +``` + +### Without the Command Primitive + +Before the command primitive was introduced, the way to resume execution was to: + +1. (optional) Update the graph state based on user input (e.g., to incorporate human feedback). +2. Resume `graph.invoke(None, config=config)` using a `None` and the same `config` as the original invocation (which contains the thread ID). + +```python +graph.invoke(inputs, config=config) # This will pause at the breakpoint +... +# Do something (e.g., get human input) +... + +graph.update_state(update, config=config) +graph.invoke(None, config=config) +``` + +## Comparison of methods - Resume execution without the `Command` primitive (older versions of LangGraph). - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - graph.update_state(update, config=config) - graph.invoke(None, config=config) - ``` -See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. ### How does an `interrupt` work? @@ -137,3 +218,12 @@ By leveraging `Command`, you can resume graph execution, handle user inputs, and See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. +## Best practices + +We currently recommend the `interrupt` function for setting breakpoints and resuming execution. +This function is more flexible and easier to use than the older methods of setting breakpoints using static breakpoints and the `NodeInterrupt` exception. + +## Additional Resources 📚 + +- [**Conceptual Guide: Persistence**](https://langchain-ai.github.io/langgraph/concepts/persistence/#replay): Read the persistence guide for more context on replaying. +- [**How to View and Update Past Graph State**](../how-tos/human_in_the_loop/time-travel.ipynb): Step-by-step instructions for working with graph state that demonstrate the **replay** and **fork** actions. \ No newline at end of file diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index b05867cd6..bf0ac4235 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -453,6 +453,17 @@ Read [this how-to](https://langchain-ai.github.io/langgraph/how-tos/recursion-li Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. +You **MUST** use a [checkpointer](./persistence.md) when using breakpoints as breakpoints require the ability to save the state of the graph at the time of pausing. + +There are two types of breakpoints: + +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. + +## Breakpoints + +Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. + There are two types of breakpoints: 1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). @@ -460,6 +471,101 @@ There are two types of breakpoints: Please see the [Human-in-the-Loop guide](../human_in_the_loop) for information about breakpoints. +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. + +### Static Breakpoints + +To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). + +```python +graph = graph_builder.compile( + interrupt_before=["node_a"], + interrupt_after=["node_b", "node_c"], + checkpointer=..., # Required +) +``` + +When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. + +### Dynamic Breakpoints + +There are two ways to interrupt the graph dynamically: + +1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. +2. `NodeInterrupt` exception: An older, less flexible method for interrupting. + +#### `interrupt` + +```python +from langgraph.types import interrupt + +def node(state: State): + ... + client_value = interrupt( + # This value will be sent to the client. + # It can be any JSON serializable value. + {"key": "value"} + ) + ... +``` + +#### `NodeInterrupt` + +Throw a `NodeInterrupt` exception to interrupt the graph. + +```python +def my_node(state: State) -> State: + if len(state['input']) > 5: + raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") + + return state +``` + +### Resuming +1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). +2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. + +When a breakpoint is hit, graph execution will pause. +Please see the [Human-in-the-Loop guide](../human_in_the_loop) for conceptual information about breakpoints. + +=== "Command" + + Resume execution using the new `Command` primitive. + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + graph.invoke( + Command( + # Use `resume` to pass a value to the `interrupt`. + resume=resume, + # For other kinds of breakpoints, use `update` to update the state. + update=update, + ), + config=config + ) + ``` + +=== "Without the Command Primitive" + + Resume execution without the `Command` primitive (older versions of LangGraph). + + ```python + graph.invoke(inputs, config=config) # This will pause at the breakpoint + ... + # Do something (e.g., get human input) + ... + + graph.update_state(update, config=config) + graph.invoke(None, config=config) + ``` + +See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. + + ## Subgraphs A subgraph is a [graph](#graphs) that is used as a [node](#nodes) in another graph. This is nothing more than the age-old concept of encapsulation, applied to LangGraph. Some reasons for using subgraphs are: From 723bcfeaa27d8d8133b92af48fc4e4363662a972 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 15:27:00 -0500 Subject: [PATCH 23/72] x --- docs/docs/concepts/breakpoints.md | 143 ++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 46 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index 2003df4cc..f0f62d451 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -1,85 +1,137 @@ # Breakpoints -Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. They rely on the graph's [**persistence layer**](./persistence.md), which saves the state after each graph step, to enable pausing and resuming execution. +Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints depend +on LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. To use breakpoints, you will need to: -## Overview - -To use breakpoints, you will generally need to: - -1. [**Use a checkpointer**](persistence.md): Compile the graph with a checkpointer, so the graph state is saved after each graph step. -1. [**Set breakpoints**](#setting-breakpoints): Pause execution at selected points in the graph. -2. Run the graph until a breakpoint is hit. -3. [**Resume execution**](#resuming): Continue execution from the breakpoint. +1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. +2. [**Set breakpoints**](#setting-breakpoints) to specify where execution should pause. +3. Run the graph with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. +4. [**Resume execution**](#resuming) from the paused state. ## Types of Breakpoints -There are two types of breakpoints: +There are three ways to add breakpoints to your graph: -1. [**Static breakpoints**](#static-breakpoints): Pause execution **before** or **after** a node by specifying `interrupt_before` and `interrupt_after` during [graph compilation](#compiling-your-graph). -2. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause execution from **inside** a node using the `interrupt` function or by raising a `NodeInterrupt` exception. +1. [**Static breakpoints**](#static-breakpoints): Pause execution **before** or **after** a node by specifying `interrupt_before` and `interrupt_after` during [graph compilation](#compiling-your-graph). +2. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause execution **inside** a node based on a condition that is not known until runtime. These consist of `interrupt` and `NodeInterrupt`. ## Static Breakpoints -Static breakpoints are triggered either **before** or **after** a node executes. To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph) or at run time when invoking the graph. +Static breakpoints are triggered either **before** or **after** a node executes. You can set static breakpoints at: -#### Setting at Compilation time +1. **"compile" time** via the `compile` method. +2. **run time** via the `invoke`/`stream` method. -```python -graph = graph_builder.compile( - interrupt_before=["node_a"], - interrupt_after=["node_b", "node_c"], - checkpointer=..., # Required -) -``` +=== "Compile time" -#### Setting at Runtime + ```python + graph = graph_builder.compile( + interrupt_before=["node_a"], + interrupt_after=["node_b", "node_c"], + checkpointer=..., # Specify a checkpointer + ) -```python -graph.invoke( - inputs, - config={"configurable": {"thread_id": "some_thread"}}, - interrupt_before=["node_a"], - interrupt_after=["node_b", "node_c"] -) -``` + thread_config = { + "configurable": { + "thread_id": "some_thread" + } + } -!!! note + # Run the graph until the breakpoint + graph.invoke(inputs, config=thread_config) - You cannot set static breakpoints at runtime for sub-graphs. - If you have a sub-graph, you must set the breakpoints at compilation time. + # Optionally update the graph state based on user input + graph.update_state(update, config=thread_config) + + # Resume the graph + graph.invoke(None, config=thread_config) + ``` + +=== "Run time" + + ```python + graph.invoke( + inputs, + config={"configurable": {"thread_id": "some_thread"}}, + interrupt_before=["node_a"], + interrupt_after=["node_b", "node_c"] + ) + + thread_config = { + "configurable": { + "thread_id": "some_thread" + } + } + + # Run the graph until the breakpoint + graph.invoke(inputs, config=thread_config) + + # Optionally update the graph state based on user input + graph.update_state(update, config=thread_config) + + # Resume the graph + graph.invoke(None, config=thread_config) + ``` + + !!! note + + You cannot set static breakpoints at runtime for **sub-graphs**. + If you have a sub-graph, you must set the breakpoints at compilation time. ## Dynamic Breakpoints -You may want to raise a breakpoint from inside a node, potentially based on some condition that is not known until runtime. We -refer to these as **dynamic breakpoints**. +You may want to raise a breakpoint from inside a node, potentially based on some condition that is not known until runtime. We refer to these as **dynamic breakpoints**. 1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. 2. `NodeInterrupt` exception: An older, less flexible method for interrupting. -### `interrupt` +## `interrupt` function ```python from langgraph.types import interrupt -def node(state: State): +def human_approval(state: State): ... - client_value = interrupt( + answer = interrupt( # This value will be sent to the client. # It can be any JSON serializable value. - {"key": "value"} + { + "question": "OK to proceed?", + # Surface some context to the client. + "llm_output": state["llm_output"] + } ) + + if answer['approved']: + # Proceed with the action + ... + else: + # Do something else ... + + +# Add the node to the graph +graph_builder.add_node("human_approval", human_approval) +# Compile the graph with a checkpointer +graph = graph_builder.compile(checkpointer=checkpointer) + +# Run the graph until the breakpoint +thread_config = { + "configurable": { + "thread_id": "some_thread" + } +} +graph.invoke(inputs, config=thread_config) + +# Resume the graph with the user's input +graph.invoke(Command(resume={"approved": True}), config=thread_config) ``` ### `NodeInterrupt` +`NodeInterrupts` are an older method for interrupting the graph. We recommend using the `interrupt` function instead. -This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. - -There are two ways to interrupt the graph dynamically: - -1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. -2. `NodeInterrupt` exception: An older, less flexible method for interrupting. +A `NodeInterrupt` is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. @@ -90,7 +142,6 @@ def my_node(state: State) -> State: return state ``` -Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. ```python From acac19b95b9a55cf615b2e2fa98f7f32e8e2cd21 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 16:49:51 -0500 Subject: [PATCH 24/72] x --- docs/docs/concepts/breakpoints.md | 313 ++++++++++-------------- docs/docs/concepts/human_in_the_loop.md | 1 - 2 files changed, 135 insertions(+), 179 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index f0f62d451..afb77dad5 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -1,26 +1,85 @@ # Breakpoints -Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints depend -on LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. To use breakpoints, you will need to: +Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. + +## Requirements + +To use breakpoints, you will need to: 1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. 2. [**Set breakpoints**](#setting-breakpoints) to specify where execution should pause. 3. Run the graph with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. 4. [**Resume execution**](#resuming) from the paused state. -## Types of Breakpoints +## Setting breakpoints -There are three ways to add breakpoints to your graph: +There are two places where you can set breakpoints: -1. [**Static breakpoints**](#static-breakpoints): Pause execution **before** or **after** a node by specifying `interrupt_before` and `interrupt_after` during [graph compilation](#compiling-your-graph). -2. [**Dynamic breakpoints**](#dynamic-breakpoints): Pause execution **inside** a node based on a condition that is not known until runtime. These consist of `interrupt` and `NodeInterrupt`. +1. **Inside** a node using the [`interrupt` function](#the-interrupt-function) (or the older [`NodeInterrupt` exception](#nodeinterrupt-exception)). +2. **Before** or **after** a node executes by setting breakpoints at **compile time** or **run time**. We call these [**static breakpoints**](#static-breakpoints). + +The **recommended** way to set breakpoints is using the [`interrupt` function](#the-interrupt-function). This method is easier to use and more flexible than the older methods. -## Static Breakpoints +### The `interrupt` function -Static breakpoints are triggered either **before** or **after** a node executes. You can set static breakpoints at: +Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing the developer to collect user input, validate the graph state, or make decisions before resuming execution. -1. **"compile" time** via the `compile` method. -2. **run time** via the `invoke`/`stream` method. +```python +from langgraph.types import interrupt + +def human_approval(state: State): + ... + answer = interrupt( + # Interrupt information to surface to the client. + # Can be any JSON serializable value. + { + "question": "Can we proceed?", + "llm_output": state["llm_output"] + } + ) + + if answer['approved']: + # Proceed with the action + ... + else: + # Do something else + ... + + +# Add the node to the graph +graph_builder.add_node("human_approval", human_approval) +# Compile the graph with a checkpointer +graph = graph_builder.compile(checkpointer=checkpointer) + +# Run the graph until the breakpoint +thread_config = {"configurable": {"thread_id": "some_id"}} +for event in graph.stream(inputs, thread_config, stream_mode="values"): + print(event) +``` + +```pycon +{'__interrupt__': ( + Interrupt( + value={'question': 'Can we proceed?', "llm_output": "..."}, + resumable=True, + ns=['node:5df255f7-d683-1a99-b7c8-00dd534aed8e'], + when='during' + ), + ) +} +``` + +Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: + +```python +# Resume the graph with the user's input +for event in graph.stream(Command(resume={"approved": True}), config=thread_config): + print(event) +``` + +### Static breakpoints + +Static breakpoints are triggered either **before** or **after** a node executes. You can set static breakpoints by specifying `interrupt_before` and `interrupt_after` at **"compile" time** or **run time**. === "Compile time" @@ -78,164 +137,83 @@ Static breakpoints are triggered either **before** or **after** a node executes. You cannot set static breakpoints at runtime for **sub-graphs**. If you have a sub-graph, you must set the breakpoints at compilation time. -## Dynamic Breakpoints +Static breakpoints can be especially useful for debugging if you want to step through the graph execution one +node at a time or if you want to pause the graph execution at specific nodes. -You may want to raise a breakpoint from inside a node, potentially based on some condition that is not known until runtime. We refer to these as **dynamic breakpoints**. +### `NodeInterrupt` exception -1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. -2. `NodeInterrupt` exception: An older, less flexible method for interrupting. +We recommend that you [**use the `interrupt` function instead**](#the-interrupt-function) of the `NodeInterrupt` exception. The `interrupt` function is easier to use and more flexible. -## `interrupt` function +??? node "`NodeInterrupt` exception" + + The developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. + + ```python + def my_node(state: State) -> State: + if len(state['input']) > 5: + raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") + + return state + ``` + + + Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. + + ```python + # Attempt to continue the graph execution with no change to state after we hit the dynamic breakpoint + for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) + ``` + + The graph will *interrupt* again because this node will be *re-run* with the same graph state. We need to change the graph state such that the condition that triggers the dynamic breakpoint is no longer met. So, we can simply edit the graph state to an input that meets the condition of our dynamic breakpoint (< 5 characters) and re-run the node. + + ```python + # Update the state to pass the dynamic breakpoint + graph.update_state(config=thread_config, values={"input": "foo"}) + for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) + ``` + + Alternatively, what if we want to keep our current input and skip the node (`my_node`) that performs the check? To do this, we can simply perform the graph update with `as_node="my_node"` and pass in `None` for the values. This will make no update the graph state, but run the update as `my_node`, effectively skipping the node and bypassing the dynamic breakpoint. + + ```python + # This update will skip the node `my_node` altogether + graph.update_state(config=thread_config, values=None, as_node="my_node") + for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) + ``` + +## The `Command` primitive + +Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive currently supports two ways of **resuming** graph execution after an `interrupt`: + +1. **Pass a `resume` value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. +2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. ```python -from langgraph.types import interrupt - -def human_approval(state: State): - ... - answer = interrupt( - # This value will be sent to the client. - # It can be any JSON serializable value. - { - "question": "OK to proceed?", - # Surface some context to the client. - "llm_output": state["llm_output"] - } - ) - - if answer['approved']: - # Proceed with the action - ... - else: - # Do something else - ... - - -# Add the node to the graph -graph_builder.add_node("human_approval", human_approval) -# Compile the graph with a checkpointer -graph = graph_builder.compile(checkpointer=checkpointer) - -# Run the graph until the breakpoint -thread_config = { - "configurable": { - "thread_id": "some_thread" - } -} -graph.invoke(inputs, config=thread_config) - -# Resume the graph with the user's input -graph.invoke(Command(resume={"approved": True}), config=thread_config) +# Resume graph execution with the user's input. +graph.invoke(Command(resume={"age": "25"}), thread_config) ``` -### `NodeInterrupt` +By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. -`NodeInterrupts` are an older method for interrupting the graph. We recommend using the `interrupt` function instead. +## Using with `invoke` and `ainvoke` -A `NodeInterrupt` is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. - -Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. +If you use `stream` or `ainvoke` to run the graph, you will not receive the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. ```python -def my_node(state: State) -> State: - if len(state['input']) > 5: - raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") - return state -``` - -Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. +`invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. ```python -# Attempt to continue the graph execution with no change to state after we hit the dynamic breakpoint -for event in graph.stream(None, thread_config, stream_mode="values"): - print(event) +# Run the graph up to the breakpoint +result = graph.invoke(inputs, thread_config) +# Get the graph state to get interrupt information. +state = graph.get_state(thread_config) +# Resume the graph with the user's input. +graph.invoke(Command(resume={"age": "25"}), thread_config) ``` -The graph will *interrupt* again because this node will be *re-run* with the same graph state. We need to change the graph state such that the condition that triggers the dynamic breakpoint is no longer met. So, we can simply edit the graph state to an input that meets the condition of our dynamic breakpoint (< 5 characters) and re-run the node. - -```python -# Update the state to pass the dynamic breakpoint -graph.update_state(config=thread_config, values={"input": "foo"}) -for event in graph.stream(None, thread_config, stream_mode="values"): - print(event) -``` - - -## Updating with as_node - -Alternatively, what if we want to keep our current input and skip the node (`my_node`) that performs the check? To do this, we can simply perform the graph update with `as_node="my_node"` and pass in `None` for the values. This will make no update the graph state, but run the update as `my_node`, effectively skipping the node and bypassing the dynamic breakpoint. - -```python -# This update will skip the node `my_node` altogether -graph.update_state(config=thread_config, values=None, as_node="my_node") -for event in graph.stream(None, thread_config, stream_mode="values"): - print(event) -``` - - -Throw a `NodeInterrupt` exception to interrupt the graph. - -```python -def my_node(state: State) -> State: - if len(state['input']) > 5: - raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") - - return state -``` - -!!! note "Use `interrupt` instead of `NodeInterrupt` if on recent LangGraph." - - The `NodeInterrupt` exception is an older method for interrupting the graph. We recommend using the `interrupt` function instead as it allows passing a `resume` value to the client. This allows addin - - The `interrupt` function allows resuming using a `Command` primitive, which provides more flexibility than the `NodeInterrupt` exception. - -## Resuming - -When you run a graph with breakpoints, execution will pause at the breakpoint. To resume execution, you can: - -1. [**Use the `Command` primitive**](#using-the-command-primitive): Pass a value to the `interrupt` or update the graph state. -2. [**Without the Command Primitive**](#without-the-command-primitive): Update the graph state and resume - -### Using the `Command` Primitive - -The new [Command](../reference/types.md#langgraph.types.Command) primitive provides a flexible way to resume execution after an `interrupt`. - -```python -graph.invoke(inputs, config=config) # This will pause at the breakpoint - -# Do something (e.g., get human input) -graph.invoke( - Command( - # Use `resume` to pass a value to the `interrupt`. - resume=resume, - ), - config=config -) -``` - -### Without the Command Primitive - -Before the command primitive was introduced, the way to resume execution was to: - -1. (optional) Update the graph state based on user input (e.g., to incorporate human feedback). -2. Resume `graph.invoke(None, config=config)` using a `None` and the same `config` as the original invocation (which contains the thread ID). - -```python -graph.invoke(inputs, config=config) # This will pause at the breakpoint -... -# Do something (e.g., get human input) -... - -graph.update_state(update, config=config) -graph.invoke(None, config=config) -``` - -## Comparison of methods - - - - - -### How does an `interrupt` work? +## How does resuming from a breakpoint work? Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`. @@ -246,33 +224,12 @@ Keep the following considerations in mind when using the `interrupt` function: 1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. 2. **Multiple interrupts**: Using multiple `interrupt` calls in a node can be very useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. - -### Options for resuming execution - -After an `interrupt`, graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: - -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. -2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. -3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. - -```python -# Resume graph execution with the user's input. -graph.invoke(Command(resume={"age": "25"}), thread_config) -``` - -By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. - -??? note "Using other types of breakpoints" - - The `interrupt` function was introduced to address difficulties with the older methods that necessitated updating the graph state when resuming execution. You can read more about these methods in the [low-level guide](./low_level.md#breakpoints). A [previous version of this guide](v0-human-in-the-loop.md) covers the older method of setting breakpoints using **static breakpoints** and the `NodeInterrupt` exception. - - See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. - - ## Best practices -We currently recommend the `interrupt` function for setting breakpoints and resuming execution. -This function is more flexible and easier to use than the older methods of setting breakpoints using static breakpoints and the `NodeInterrupt` exception. +We recommend the `interrupt` function for setting breakpoints and using `Command(resume=value)` to resume execution. + +This approach allows you to collect user input without having to immediately modify the graph state or add any special +attributes to the graph state to represent the user input. ## Additional Resources 📚 diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 4dffc336a..71e5ed804 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -63,7 +63,6 @@ graph = graph_builder.compile(checkpointer=checkpointer) ??? warning "Graph execution resumes from the beginning of the node not the exact point of the `interrupt`" - ### Run **Run the graph** and observe the `interrupt` function in action: From 09e9117674eae864500afa54862d6de8ae8b065c Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 17:24:59 -0500 Subject: [PATCH 25/72] x --- docs/docs/concepts/breakpoints.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index afb77dad5..d24dfc710 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -185,10 +185,13 @@ We recommend that you [**use the `interrupt` function instead**](#the-interrupt- ## The `Command` primitive -Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive currently supports two ways of **resuming** graph execution after an `interrupt`: +Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive which can be passed through the `invoke`, `ainvoke`, `stream` or `astream` methods. -1. **Pass a `resume` value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. +The `Command` primitive provides several options to control and modify the graph's state during resumption: + +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. 2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. +3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. ```python # Resume graph execution with the user's input. @@ -199,9 +202,8 @@ By leveraging `Command`, you can resume graph execution, handle user inputs, and ## Using with `invoke` and `ainvoke` -If you use `stream` or `ainvoke` to run the graph, you will not receive the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. +When you use `stream` or `astream` to run the graph, you will receive an `interrupt` event that let you know that a breakpoint has been hit. -```python `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. ```python @@ -209,10 +211,28 @@ If you use `stream` or `ainvoke` to run the graph, you will not receive the inte result = graph.invoke(inputs, thread_config) # Get the graph state to get interrupt information. state = graph.get_state(thread_config) +# Print the state values +print(state.values) +# Print the pending tasks +print(state.tasks) # Resume the graph with the user's input. graph.invoke(Command(resume={"age": "25"}), thread_config) ``` +```pycon +{'foo': 'bar'} # State values +( + PregelTask( + id='5d8ffc92-8011-0c9b-8b59-9d3545b7e553', + name='node_foo', + path=('__pregel_pull', 'node_foo'), + error=None, + interrupts=(Interrupt(value='value_in_interrupt', resumable=True, ns=['node_foo:5d8ffc92-8011-0c9b-8b59-9d3545b7e553'], when='during'),), state=None, + result=None + ), +) # Pending tasks. interrupts +``` + ## How does resuming from a breakpoint work? Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`. From 60ab76c3e972c83ae73018c63e1cc6ff5e5e76f3 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 18:12:17 -0500 Subject: [PATCH 26/72] x --- docs/docs/concepts/breakpoints.md | 39 ++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index d24dfc710..4d90199c9 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -202,7 +202,7 @@ By leveraging `Command`, you can resume graph execution, handle user inputs, and ## Using with `invoke` and `ainvoke` -When you use `stream` or `astream` to run the graph, you will receive an `interrupt` event that let you know that a breakpoint has been hit. +When you use `stream` or `astream` to run the graph, you will receive an `Interrupt` event that let you know that a breakpoint has been hit. `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. @@ -235,21 +235,44 @@ graph.invoke(Command(resume={"age": "25"}), thread_config) ## How does resuming from a breakpoint work? -Execution always resumes from the **beginning** of the **graph node**, not the exact point of the `interrupt`. +> Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered. -Please note that this is **unlike** a traditional breakpoint or Python's `input()` function. As a result, you should structure your graph nodes to handle the `interrupt` and `resume` logic effectively. +A critical aspect of using breakpoints is understanding how resuming from a breakpoint works. When you resume execution after a breakpoint, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. + +**All** code from the beginning of the node to the **breakpoint** will be re-executed. + +```python +counter = 0 +def node(state: State): + # All the code from the beginning of the node to the breakpoint will be re-executed + # when the graph resumes. + global counter + counter += 1 + print(f"> Entered the node: {counter} # of times") + # Pause the graph and wait for user input. + answer = interrupt() + print("The value of counter is:", counter) + ... +``` + +Upon **resuming** the graph, the counter will be incremented a second time, resulting in the following output: + +```pycon +> Entered the node: 2 # of times +The value of counter is: 2 +``` Keep the following considerations in mind when using the `interrupt` function: 1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. -2. **Multiple interrupts**: Using multiple `interrupt` calls in a node can be very useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. +2. **Multiple interrupts**: Using multiple `interrupt` calls in a node can be very useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. As a result, we recommend that you structure your code in a way that avoids providing both a `resume` and a state `update` value (e.g., `Command(resume=resume, update=update)`) at the same time. +3. **Subgraphs**: If you're invoking a subgraph [as a function](low_level.md#as-a-function), the **parent** graph will be re-run from the **beginning of the node** where the subgraph was invoked. ## Best practices -We recommend the `interrupt` function for setting breakpoints and using `Command(resume=value)` to resume execution. - -This approach allows you to collect user input without having to immediately modify the graph state or add any special -attributes to the graph state to represent the user input. +* Use the `interrupt` function to set breakpoints and collect user input. +* Use `Command` to resume execution and control the graph state. +* Consider putting all side effects (e.g., API calls) after the `interrupt` to prevent duplication. See [How does resuming from a breakpoint work?](#how-does-resuming-from-a-breakpoint-work) ## Additional Resources 📚 From a879de51f1e6c94e3dd2b368d0da8456c89826b4 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 18:13:39 -0500 Subject: [PATCH 27/72] x --- docs/docs/concepts/human_in_the_loop.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 71e5ed804..5513929d5 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -2,8 +2,7 @@ !!! tip "This guide uses the new `interrupt` function." - As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [interrupt](../reference/types.md#langgraph.types.interrupt) function as it significantly - simpifies **human-in-the-loop** patterns. + As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [interrupt](../reference/types.md#langgraph.types.interrupt) function as it significantly simpifies **human-in-the-loop** patterns. Please see the [Breakpoints](breakpoints.md) guide for more information. If you're looking for the previous version of this conceptual guide, which relied on static breakpoints and `NodeInterrupt` exception, it is available [here](v0-human-in-the-loop.md). From b98a1337a5854cc36c1f6c03773ec5b2d80de2ba Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 22:50:16 -0500 Subject: [PATCH 28/72] x --- docs/docs/concepts/breakpoints.md | 5 +- docs/docs/concepts/human_in_the_loop.md | 276 ++++++++++-------------- 2 files changed, 115 insertions(+), 166 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index 4d90199c9..112898137 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -43,7 +43,7 @@ def human_approval(state: State): ... else: # Do something else - ... + ... # Add the node to the graph @@ -276,5 +276,6 @@ Keep the following considerations in mind when using the `interrupt` function: ## Additional Resources 📚 -- [**Conceptual Guide: Persistence**](https://langchain-ai.github.io/langgraph/concepts/persistence/#replay): Read the persistence guide for more context on replaying. +- [**Conceptual Guide: Persistence**](persistence.md): Read the persistence guide for more context about persistence. +- [**Conceptual Guide: Human-in-the-loop**](human_in_the_loop.md): Read the human-in-the-loop guide for more context on integrating human feedback into LangGraph applications using breakpoints. - [**How to View and Update Past Graph State**](../how-tos/human_in_the_loop/time-travel.ipynb): Step-by-step instructions for working with graph state that demonstrate the **replay** and **fork** actions. \ No newline at end of file diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 5513929d5..9b5f93a54 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -8,209 +8,157 @@ A **human-in-the-loop** (or "on-the-loop") workflow integrates human input into automated processes, allowing for decisions, validation, or corrections at key stages. This is especially useful in **LLM-based applications**, where the underlying model may generate occasional inaccuracies. In low-error-tolerance scenarios like compliance, decision-making, or content generation, human involvement ensures reliability by enabling review, correction, or override of model outputs. -## Interaction Patterns -1. **Approval**/**Rejection**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. -2. **Editing**: Pause the graph to review and edit the agent's state. This is useful for correcting mistakes or updating the agent's state. -3. **Input**: Explicitly request human input at a particular step in the graph. This is useful for collecting additional information or context to inform the agent's decision-making process. - ## Use cases Key use cases for **human-in-the-loop** workflows in LLM-based applications include: -1. **🛠️ [Reviewing tool calls](#reviewing-tool-calls)**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. +1. **🛠️ [Reviewing tool calls](#review-and-edit)**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. 2. **✅ Validating LLM outputs**: Humans can review, edit, or approve content generated by the LLM. -3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details. -4. **🔍 Debugging**: Investigate and correct errors in the LLM's decision-making process. - -## Interrupt & Resume +3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details or to support multi-turn conversations. -**Human-in-the-loop** workflow consists of four key steps: +## Design Patterns -1. [**Persistence**](./persistence.md): the graph state is saved after each graph step, enabling **pausing** and **resuming** execution. -2. [**Interrupting execution**](#interrupting-execution): the [`interrupt`](../reference/types.md#langgraph.types.interrupt) function is used to **pause** the graph at specific points for **human input**. -3. [**Running the graph**](#run): the graph is executed until it reaches the **breakpoint**. -4. [**Resuming execution**](#resuming-execution): the [`Command`](../reference/types.md#langgraph.types.Command) primitive allows **resuming** execution based on **human input**. +1. **Approval**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. +2. **Editing**: Pause the graph to review and edit the agent's state. This is useful for correcting mistakes or updating the agent's state. +3. **Input**: Explicitly request human input at a particular step in the graph. This is useful for collecting additional information or context to inform the agent's decision-making process or for supporting **multi-turn conversations**. -> **Note:** While there are other ways to set breakpoints (e.g., static breakpoints or dynamic exceptions) and resume execution (e.g., by relying on state updates `graph.update_state`), this guide focuses on the `interrupt` function and `Command` primitive as the recommended methods. -### Interrupt +### Approval -Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing you to collect user input, validate the graph state, or make decisions before resuming execution. The graph must be compiled with a [checkpointer](./persistence.md) so graph execution can be paused and resumed. +
+![image](img/human_in_the_loop/approve-or-reject.png){: style="max-height:400px"} +
Depending on the human's approval or rejection, the graph can proceed with the action or take an alternative path.
+
+ +Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. ```python from langgraph.types import interrupt -def node(state: State): +def human_approval(state: State): ... - # Pause the graph and wait for user input. - answer = interrupt( + is_approved = interrupt( { - "question": "What is your age?", + "question": "Is this correct?", + # Surface the output that should be + # reviewed and approved by the human. + "llm_output": state["llm_output"] } ) - # Answer will be assigned a value when the graph resumes (see below). - print(f"Value received from interrupt: {answer}") - # Do something with the answer. - ... -graph_builder.add_node("node", node) - -# The checkpointer is required for the `interrupt` function to work. -graph = graph_builder.compile(checkpointer=checkpointer) -``` - -??? warning "Graph execution resumes from the beginning of the node not the exact point of the `interrupt`" - -### Run - -**Run the graph** and observe the `interrupt` function in action: - -```python -# Run the graph up to the breakpoint -thread_config = {"configurable": {"thread_id": "some_id"}} -for event in graph.stream(inputs, thread_config, stream_mode="values"): - print(event) -``` - -```pycon -{'__interrupt__': ( - Interrupt( - value={'question': 'what is your age?'}, - resumable=True, - ns=['node:5df255f7-d683-1a99-b7c8-00dd534aed8e'], - when='during' - ), - ) -} -``` - -??? note "Using with `invoke` and `ainvoke`" - - `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. - - ```python - # Run the graph up to the breakpoint - result = graph.invoke(inputs, thread_config) - # Get the graph state to get interrupt information. - state = graph.get_state(thread_config) - # Resume the graph with the user's input. - graph.invoke(Command(resume={"age": "25"}), thread_config) - ``` - -### Resume - -Once you have collected user input, you can **resume** the graph execution using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: - -```python -graph.invoke(Command(resume={"age": "25"}), thread_config) -``` - -You should see the following output printed by to the `print` function in the `node` function: - -```pycon -Value received from interrupt: {'age': '25'} -``` - -## Interaction Patterns - -1. **Approval**/**Rejection**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected. - -2. **Editing**: Pause the graph to review and edit the agent's state. This is useful for correcting mistakes or updating the agent's state. - - -### Approval/Rejection - -```python -def node(state): - ... - # Pause the graph and wait for user input. - approval = interrupt( - { - "question": "Do you approve this action?", - # Surface the current state or any other relevant information. - "state": state, - } - ) - - if not isinstance(approval, bool): - raise ValueError("Approval must be a boolean value.") - - if approval: - # Perform the action. + if is_approved: + # Proceed with the action ... else: - # Skip the action. + # Do something else ... + +# Add the node to the graph in an appropriate location +# and connect it to the relevant nodes. +graph_builder.add_node("human_approval", human_approval) +graph = graph_builder.compile(checkpointer=checkpointer) + +... + +# After running the graph and hitting the breakpoint, the graph will pause. +# Resume it with either an approval or rejection. +thread_config = {"configurable": {"thread_id": "some_id"}} +graph.invoke(Command(resume=True), config=thread_config) ``` -### Editing + +### Edit + +
+![image](img/human_in_the_loop/tool-call-review.png){: style="max-height:400px"} +
A human can review and edit the output from the LLM before proceeding. This is particularly +critical in applications where the tool calls requested by the LLM may be sensitive or require human oversight. +
+
+ ```python -def node(state): +from langgraph.types import interrupt + +def human_editing(state: State): ... - # Pause the graph and wait for user input. - user_input = interrupt( + result = interrupt( + # Interrupt information to surface to the client. + # Can be any JSON serializable value. { - "question": "Please provide additional information:", - # Surface the current state or any other relevant information. - "state": state, + "task": "Review the output from the LLM and make any necessary edits.", + "llm_output": state["llm_output"] } ) + + # Update the state with the edited text return { - # some state update based on user input + "llm_output": result["edited_text"] } - + +# Add the node to the graph in an appropriate location +# and connect it to the relevant nodes. +graph_builder.add_node("human_editing", human_editing) +graph = graph_builder.compile(checkpointer=checkpointer) + +... + +# After running the graph and hitting the breakpoint, the graph will pause. +# Resume it with the edited text. +thread_config = {"configurable": {"thread_id": "some_id"}} +graph.invoke( + Command(resume={"edited_text": "The edited text"}), + config=thread_config +) ``` -### Input +### Multi-turn conversation (Input) + +
+![image](img/human_in_the_loop/multi-turn-conversation.png){: style="max-height:400px"} +
A multi-turn conversation architecture where an agent and human node cycle back and forth until the agent decides to hand off the conversation to another agent or another part of the system. +
+
+ +A **multi-turn conversation** involves multiple back-and-forth interactions between an agent and a human, which can allow the agent to gather additional information from the human in a conversational manner. + +This design pattern is useful in an LLM application consisting of [multiple agents](./multi_agent.md). One or more agents may need to carry out multi-turn conversations with a human, where the human provides input or feedback at different stages of the conversation. For simplicity, the agent implementation below is illustrated as a single node, but in reality +it may be part of a larger graph consisting of multiple nodes and include a conditional edge. ```python +from langgraph.types import interrupt -def node(state): +def human_input(state: State): + human_message = interrupt("human_input") + return { + "messages": [ + { + "role": "human", + "content": human_message + } + ] + } + +def agent(state: State): + # Agent logic ... - # Pause the graph and wait for user input. - human_message = interrupt() - return { - "messages": [human_message] - } - + +graph_builder.add_node("human_input", human_input) +graph_builder.add_edge("human_input", "agent") +graph = graph_builder.compile(checkpointer=checkpointer) + + +# After running the graph and hitting the breakpoint, the graph will pause. +# Resume it with the human's input. +graph.invoke( + Command(resume="hello!"), + config=thread_config +) ``` -### +## Additional Resources 📚 -## Use-cases - -### Reviewing Tool Calls - -Some user interaction patterns combine the concepts outlined above. - -For example, many agents rely on [tool calling](https://python.langchain.com/docs/how_to/tool_calling/) to make decisions. Tool calling introduces unique challenges because the agent must get multiple aspects right: - -1. **Selecting the correct tool**: The agent must choose the appropriate tool to call. -2. **Providing accurate arguments**: The agent must pass the correct parameters to the tool. -3. **Ensuring discretion**: Even if the tool call is technically correct, it might involve sensitive operations that require human approval. - -By addressing these challenges, we can integrate **human-in-the-loop** processes to review and approve tool calls effectively. - -```python -# Compile our graph with a checkpointer and a breakpoint before the step to review the tool call from the LLM -graph = builder.compile(checkpointer=checkpointer, interrupt_before=["human_review"]) - -# Run the graph up to the breakpoint -for event in graph.stream(inputs, thread, stream_mode="values"): - print(event) - -# Review the tool call and update it, if needed, as the human_review node -graph.update_state(thread, {"tool_call": "updated tool call"}, as_node="human_review") - -# Otherwise, approve the tool call and proceed with the graph execution with no edits - -# Continue the graph execution from either: -# (1) the forked checkpoint created by human_review or -# (2) the checkpoint saved when the tool call was originally made (no edits in human_review) -for event in graph.stream(None, thread, stream_mode="values"): - print(event) -``` - -See [the how to review tool calls guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a details. \ No newline at end of file +- [**Conceptual Guide: Persistence**](persistence.md#replay): Read the persistence guide for more context on replaying. +- [**Conceptual Guide: Breakpoints**](breakpoints.md): Read the breakpoints guide for more context on breakpoints. +- [**How to Guides: Human-in-the-loop**](../how-tos/index.md#human-in-the-loop): Learn how to implement human-in-the-loop workflows in LangGraph. From 73fb725f0cf6f44c9f99e609e64ce254d8189d5b Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 22:50:33 -0500 Subject: [PATCH 29/72] add pngs --- .../img/human_in_the_loop/approve-or-reject.png | Bin 0 -> 94081 bytes .../multi-turn-conversation.png | Bin 0 -> 41799 bytes .../img/human_in_the_loop/tool-call-review.png | Bin 0 -> 55595 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/docs/concepts/img/human_in_the_loop/approve-or-reject.png create mode 100644 docs/docs/concepts/img/human_in_the_loop/multi-turn-conversation.png create mode 100644 docs/docs/concepts/img/human_in_the_loop/tool-call-review.png diff --git a/docs/docs/concepts/img/human_in_the_loop/approve-or-reject.png b/docs/docs/concepts/img/human_in_the_loop/approve-or-reject.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba06b1a40a907531940c524fe499d8756e626d3 GIT binary patch literal 94081 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 O|5O#PC{)N;(aR_)!$GM;1l%uxKWIS{ zedY2Kfd0Ar@p~_ujJ;KYP3vOKYvSP&VkwRJ;B_BmeKeCZfsT)l?;8sWA;|w;8OY*d z-6qTpj?$o{0{?w+fud=9eiiox|L?1-ADptu3O@B*;(u@X`bSKBfrHdv@qb6d((!@)@0q0fM!>0TkkSwTcT1qV&+PwB1hJ(;YBa#bS~<#oO}{QT3ZLvzCME zDN(3-_5E_>ID?$u>ObtZAQI^Qo1CVPN4iN0p4BI8IB@5+=y1a@4`EYpq3YIdpBFEu z0lrHW#MCUAD}5e6c$~IWVl;{U$>l|VfaSDB(-bgG(0)aa<~$zAVSgwV>~@A|PurZo zh}mRy?F>>l6K!U#_(k10NV}ss$OpoAz-OH4Y%vaPal}3GpSz7r_YQ6MSMo0S6Jx-g9oA_4d=JxnG1`sH{k%sO^kEN1{_ z8?!4(f?2<^*Q(F+*TRbIfqMrJM{C@q;sA;Xl1tKSm@FQjl9#uc1LWdoiDJLdO4UA` zJUIc(h}SCSPd?`deSuKZG_R(G;lKt#R`0H6zaqR>SqhfoigN-vu+bG&wo)#^_At5p zu>|^Fw5bLua{c&sc|8%5xa6BC&yO5!h)A}S2?BnfaF4AAWY3R1z8dbBi?nUc4bfxo zc7+Pu=cJS50`LD)i2bjBHkm?jUSfUwVTAkn#daeOV%0*gU$l@Lt0^A8B0^<%)rYW4 z4_7F67*c9o{++aUxnU@dp~dBmajQVpTObG|W;w;M30@O4uKSts6Vfy#_g zD_DF3&{eum8w#SxE>7sm(W0pOZcf3bvl4b$G%LlqJCX%u;`ye~An^UscqGr=mk8+> z@H9l=X+JL8GhDIa>_Jq&S5Q^ro?w=R{ab=9;p2xC2POT34`}~#8nvh-s45X*ki>%S zS~!AQN7<*iOO|3rv^VYjO>9z9c?S!)04F zD_K?)1FVG`@S`5ErM%?G-N{Xe;;ju~-*w7^reC@dA^Eg@2f!<&NkzYj3y^@zuJcB) zsx|13&6S5nN_fdBP4NUdmTI8GLUqlIDUoQTV-}!U@!IY|M?+>#XZlNzUz^=eh0#4F zbq}Sbip94Bs;@{Q(4B-sP>}AIk%2pm2`|w14}>zVQM}|V zvs_TwiUm=ZvjkPwo{Nc-IxP>&eFXAFu{;w2!uvy>m++41P3M-e3=)PD?fYA$UZTpSNe@O%z}z!sgn z337J~Sr<#@^^|cAl8J(XXEBcK+hCJgJOg3=~I&CquTy3OpV*H}hm2X9&u>E|gG(}`F z>uinRVg|T)*LOhfoO^Xl-_0nho|fr6T{hWyLRoY zbr(Z$k)jruN|pZL6f``}pWE390IK5zsG{P-D+3n_17X$mwWw!@S*`+;{dASV(Q=V; z6V1?4tbn#Qp0n<1%-KO?%If9VX+Totn7^3&H}R@1mPu9^^KigT7ZgNvw=jXY1#!If z@(dm)GnQ(!!QuceXcW6$2RlK>fgjBkv^3_IwDV{X{zssX?3r$ev05r#B>3;&z{eBh z7-k$0K~F#%kMAwlVm!@b<-74Z%(3L5{<3;bo=`pxQpa@TYwwBqJ#;rr% zlGQ060Uu55F*x%Wns^rvAo6`XBYKpo?;yo!8%}-ttL_%B?rC&$D}U^_uGyme#%E*! zb%s=88|&?X?wQHc;AJ-Ivt*8AHoC9lHbnwBKL&7q`W1}{#EiuD`keDt>&3g~r&HN9 z%3QdLeM4O)RW^U)c=s4XPYrTkEoT2HTS6?W5Jur}%Fw6JmIVTvlc<#-s56Nz?<+YM z%~|%Tt2H&dQ2DmX83qy*Q+C&EIWu5J6@CGl9V(2)N0@`VSyP?|rxJie;{@nW&tQT) zEd#d^TNNo4@rswJGzsc2QY#6rEx1T@^Qt{o6BZT2*_|(vw|-qT$KzS$`OWl;Tm*=R z;y`L72LV&$>zn9d-r7W;yPX>)I#Xr^#zLc{1rf&-SobwFGVEVtskfk~XPaQ7Y0!z0 zVZy}pcCC8y*R3;b>T0r21nVRGU5TJ3@6Ib2y6Ly5RsZ+KQd$fV?2<}9g z81V*?Lnz|K#BaaGDE{aQc2Mo_2!W0R{2Ey@OMNO%7C4Pi_pE!PK5gpQFpo^*Vfv%j zqe~gPCRWeMz%T=2#ovguGJeK(C{L~iGiuI?oW|=$mT<(f6c1h}29WOI&>xx^=o?y2 zy8!sS|urh@kIgkBTV@bCtU4CGVv;aB+b(KuKqL z`6I_+V6;8(`~^?MwgvMISnVYi=nLte*-t^_*ySijv%bUlbvlmig|($Q7|CYn z#lBq2GS>VpL%%W1>EUqfwuRe#2moBle~9=ke<0tTuMC~5TG#FS2GSD;s?{#75V zDD!vS+mjM18MbQ3gC~t z+#FaiNiT`tA$0Ya;SbLB*wWjfX_2*A7D&G$qZhY6ALu@MLHGufS?+|i7{w9c%ayk5 zCv=x(MgbqL9izNa!1oiuRNcyW>$kLVYiiyp7p)}mK~zmpTkBn7{4+yzP<^;b6@bid zeb3kOR9|aEiWd&}b5%gvRwBvX5?=(AwOMrac;Qoe{3EZ;@#K+YK#$|mVf6c^5IArg z6$Nwae!)mvJ#)gg9FPzJDi-zWOdi3RJe^QeU7WGKd2U0d2u)O^R2z+xB1A!BvUvOJ z&OWw(8V7>*uOMu6b>;FtTExXb!N%(7-WaMHur;Z zg*a>8Mkwy_GZlEf?n?N6HY`8ItUf$+i~%wrx`P6orWVMDLtzlrpFa{w^)wDv;8>-c zFzd(i8;IL_^tzz|ya*NFw|Pgx=jZl*6*@jP(mw`(U~#f|f-7_Z!uUlm=7f-+Z=(fc zS1Bvk-IRokGh{Ei&Lg1EbCju7Ve%~6!9L*o=Drde0mT+W06;GGZbOQEZpjHcT${cgu>S9^Zo=Ur|`CQP~N;k}b4Un<|qzSOl~f z`Ol_g)K`8AKNb{q)Fucc7q4G+YNfC;gdeuk;)G@TEjm{=VGD7b?TsadCJcZze+RT{8}$dMDk+2gO3ETm z+d!8QV>U6Cd}j!{ST401q3zW?`siA#a-0QV-(5jeHAS%DVMJ|7ZD2{sAd%xU>lRu{(vIR>U0;$>|R67uE!2*Xihh0APJTR zt&jpdiPJ$=npRp@E?nu=*t;G=o9V-F_=6_Ae_?B3l2|^s8e!Gxr6wK{U!Hiq^u0V`ztTM%n1vJg4Q!l(00zZowpmnJ0TQGVcJ{8lNONCwZCzw~8yB5Pro zWID6-tLrll=tkw!7~$H~Sn!`lJu|iLE*=Si8^D@b_=BVc5WrP+*Fz^Bq*cA-|lcfPiknEgKYoJ$#opqiLIQ`^mu^EDKs8^!d{J>1oTcU5!u$pHTyn z#Ia%?QYE~~G#+89HSnZ81<|Od*g9PM#&|5Olj}9|-!}+te~<)Hkn&Go@C?u7t@8D- z)*Wknz0>^bNT_N+9JK?YO79?Hos>Yu^OMue1|&?RH6y4FT-}_FVdQUc?NGqB;AGg8 z>JdPi%UY&h7vO)t><@;xWZc(|{kc812PZGj4h}(%L33;TzJa!({Ia;G&R~EtNepn9 zb{xk@72R)*2@s^VeZ%A(g6q2Z3A6A5k{;^@*Q2A`QeK1AwX7<9S4%l7f5lv%xXTjx!GysGW^NQ_2tL zXatM#bywnk{7|;4qeBGZ0M?8*)-+M3(9ZPqX0@H2t&4+$>tNxJaic52J-+VSqZuQc zh40Xp&ZiFhwjA(40wMr70I-DKuX8e+Yf%J7K1KF>g2eAlZysEJJK_ocX^I@o-NNQx zQ+p(X{Ihk5Fv5MJ2IuQ!P0kmP7AZyHY)R>yXiIN}NLM4l*pQ6y#q3`Kr0$)~t?+(> zixWBl3SZ1@2!|pbC(!exbIEZWmK&v40gAQy=oFHmP@pln-DvjKhgYRQ!tF}od~t}S8hy|95C8}!nI$Hj@a zS^#c3mL4?0|Dnw&+TwWR_(2zXNu|?LCo|9(?C@VHekm#zlQDFEG=4-79H!y*?hx09 zjg1W!s|DKg!$pjA+U(WLYktoRgFys%*=OSQJ1Ga)+N@QXO@JGP!6_dnFQ-yZsbLBU^?$Y9mE-yNqi7=XUM zy;dNM5hL4S=s7X zo^Htc_k~71310=nXil}AElL%cpK7`0*6Y*FcSIs;UE;Qmk9Q9=YSq!?t<=2?{}CFi zQ)5feoBgpKifqsLZ3efSeUXh0uc>MyF*G{u#d#v^yN~mNnCg#$>p;UD-xhNe`3a&c zQuvnJNu1wJ-t&aPIDOPPUVF)iQ8Ls46zJL}aL;*W<+9J0J3BkbSFhMW=W6rl9K?kk z$+f9@g@@M&_h1igkKnG^Zhilf)3*nDu(W5T@mB^*2XtkDOorifzQkZUYpI0S=~Sry z$hSmJ(R7&8^>*CKPMhWL{BCoLWg5(DdJIqL)M^zhF=jR)Hq`6=dsU_3=ankILL`Gm z(od$hy+12AqZRF5lJzdNfa&_FHf^wo0b2+t35XQvl52?1P!iy=g>}#4%f0}kbm8h z)E)KGMXx64u&S|o&=-OEXtYAJ>g_mDREe>No6`}%?ydDZKMGG+n73!`@+CAf`p04| zgLbD67|>0Vy)g%Ykjzy(qx*SoW&s6ovewO{d)elL*unjm(pnWhP*D4l{bJHN+~DF@DNm-qNyw_h>S!YfY?VZ;Fc|E@3-#;^h{V znr+#0%p|?qvKpn4^6Y)HV|FcNF!`*}1qw-xiaq3~G{tunH6-4=>shX!6v&_Gn?O-0V z`MzxL#F02S4@wNLYMef3s;j>?JQ1wAS+z7x#4|F(?p_M!ta@LL?7?lE^2IhchTyl^ z!&}N)v0+)*XH-rO4&0Zv+z-YX#R@2bCYRZg-I0Y<2P5JGU8}6D`zH@-MxdA9tV-*5 zy*EO_!?S8}_4NFlYq?NyxKv94i$3i=He79TijOTT9T29T(Z$;Xk}((+ueMsdTP<$6cZ6DlYv9xdo>gq zO%P&|R@cbC(m0?u8!n_Kx2d{_Z~QRsuez6k(~f!dQs24t(|EX4D~*Ra$0#W|_D!)y zZA8JD=aD5DU)PM`by4&p&vME+8a84l-d6@Dm8wZv=PX{o)_5ovRrgo>9meXKwa;dd z|42a$bf(siuGvogpZFvm_oprKD8y~ynDklm=g;@{Tne(^$$>e_h6LSWk{J7@_@uPn0q2AS-bHaj>Hs`XPH$i@v<?XvAo! z(rmRZ%!(LB7kfgBw)U+ZnJ&T7mqW==Y8M?P$GW6)g76lHi}nO4n@hNu)tg$Pf52A zxl{@7ZrdNp6K7L;{dFP#=KckgCu3PZVM^O4K0LwvE45mx%ce?v)=~_iuAZY-0i&g6 zX`ud>CrDAfeF*uMY9F(s74>|0&(ho5w_Uo&f5dO8Rt#a0Tx6x_S)HU#j#xk~gM?j1kMkvRQ^!So2VC+Z=dZC-Z9uXF3 zbloRrdSOFtGD<>b+i^0|NsOO&R`% zS6O5lDl|w08QA+zBvYxEd!lTkki&HD;#M4A=ZkdB*J?*LASch52qC`-XXCks@z&;6xhVbBZbO+=nJR1iR_%l+ z9E)AMn&zU=htBLr3ZvrMxdRw{+A4~Pv2y?Xv%6E6e{pnE{TAO*tB zH4R}5Z#TOGV2RRI6*O~&VOVTd7pdxVQ4DKH>5o>*wb;>U%rlkdVHRpMP?Y@j8$&iF zLzTR-D)l<~_#QXGQg3=(?VmJdY=`WBzyAFb=Ue+VHY({_I)z4K+FY_9T&?q&*U`iC z)PT#N+Jr6t+0|cy6V$CdOtk9t{Tr*9dlmuY)C#W#go&WpzX0T8dI_h7^Uod$VTt_fIthce(%5 zHKADCt=Ezye~=h%k1t;Gc}dw>9g}J?b#=f%@NQeGK0-G_hp4 z0SE}l<0;TTr!q2<@uNu*?0malX<>rhPajQMMYDf>v~$ood?AB&p2A8_FMA$g3#&^# zy>UOQUvPY2)wEDW)pk0W?~B4^r-=%AlMqk=mrSAx8p}YC3zUfM*ZuB2>0agSG&CPZ z!`+545HN8V5*LxQ=fBsBfsPw>MNNM6Q6x4NO?i;=N>*uRquuonj2fNK7}eu#nsus4 znzt|5K_e*sS?=3;R!h`Vjh&vfYBS#vgZ7rtvBq1YPuly$Fgi`tc|F%5+XDrghC)WO z2Z-@UQmUS;9=y%;0_AXi^U!eu8nuiz21%id^KHcpM4`~Qprk3OdTk8?AsMq`Ezru^ z{&9$|Q+ukr#85NF{U636Wd|EfL+%Ziz-v~jBfQSr`m6N+T5sc|({caKQf^SgRc*OI zSF1fl6?WQKS1`oCJyVFw#9{*f+WPB13#uL`u*); z<3ADre~HEq{wrU`CO{P}Tokr>yil1fA_SwdvjY|qV0s#4#bc?>fGpx ztIB0SbL_VGMzbV=u)djY-Tix$u(tQCsd$N()tZ2;?t9g~OMn3tCQU@zm>zy?6=`&3 z=R1zi+nt5aZ?ca3%10DrvkDE5ASqpRjT$*I-MB11ujN%o_-D?HO%y*gv|9_-6-9Zs z>)q-i^1Q!0Qa;U3!gK=-y=CN0DE?Lb+*(p7HEJ78O&qxTTL5 zf%jqjQWbLB{3+i3&x_P*YWQN_7I+-C`ZX`ukx4;SA)E2;3NsDu%Z*8_N*M4z*}mA< z&~;}4W8k|NA`bU67P>$jRjCv%HJy^isd7TH#ex~`s+VoSK1Yh*&eBKNvFL;vFp^dI zP*CF`y8m9iMxt5s6ac-~Vb~+eOGT!Rytq_ek5VrAcGjIV1Oq zqn#=Bm`%phL|DS2PhPd0$QLB{=1p5Zk@0xrjZ+)aqtL9E#%fHIv!k)NDV+N!zKBY? zakA^7@o%BGQ|?(~`XgD9riNdU4y~aV<=$4qC`rgWG+xbg$Qqr2Ojbi*y~a39W&N0A zhgw8qEnbDrG7XJ7lk0BITgLK9=9J>EJxUEbJ;UW3lK+16FQ;x38^Y5RXHXb_*$#5( znqHq|!prz~4MQTzPWHl>N7=&+b$Igo6xY{YBhqO0dYPr4g@&2m>_uW}h(>}XntMi4 zv8g>REW63b5Z@QMw5l~pamO7@$Nicx?LwoYx@(J|LpLRdcH{TXS-Fo@-BF}f{~3$W zbW79PRo|_CJLPCp+xVs5qubK13zO`6kqn)4n2M#-9G*yHwtxDSKMX=?`kt8d;LPJL zooUO#g`FMVVi6YtHB913TDNo9Qk~J@-tJ}gA&`c<24kSI-P1Y)XlofMQCfIBjjOD> z+TzYdsMI~lfbAqx$_+?*2HB%^mB`kX-Czp*)!ii!k%IVB&lU(rtf9}K7Ag7dx?~QU zeT?7rQb6smfVYOlwNRzi?-U{FXa>&Et8wlN{oBJS3?#X36UHB0Re=KA+3Bd2Si|g$ zoMhY33BLy0Js#%Kd*R^Vgrf22Wz~YnnYUPh`QsT}8dBj20LqfDoWQ8Pf5C)STPklbRV=tEOnU%HCN8llGcc+*?SCz2R- z@@P=P>N20b8tj#VbmDn*Z`Z~)tiO@wNsha;S6^bAxKMeGGq0Mw3agei%30mK@K`pu=MCAMes7xp zw&4%vCnggv!8$Vd}xDlNKZ8f zK|o#C!lhoLNxHoqLt9H&%54aM3=EAkT%w+luZaHA@M?5$UK8boP!Q+k*`7?{ z>l6phu+tsNk(1xLm0q2E%}LguFv>FeH>`L2K|8mpS89-XVwOyx5o5FNhVZ&69Qvuqf4q6x39E6s6JmyOwzFzm!JV zSo*KRG2kckF&gZ*qK@JHpbaKh|o*-PPq+vcBq8;Xt?7-QdX~ZmoV- zgm|yayt#cKPv;7*OL*2*JfJQf8eTo#sZ`Z9-g)(X=8dJWv`JW#8ly$Fv`3Kl2e<(7 zQrYI&NA;Ir{nuT=ls#q`6f)vJA!)X5pH*-5aO!v%^jlQV#M|%Tx=t;Jy0ya~!4Zv> zhHGJCvGF*DOKmlV!Xw>7S!FDoTWC1sE?l)%x;~?pFBz=Ce~?h*@jM|q*r zRvYZATBH9>Nph6-%1os$`x>v$&+6>?H$Sn7e|I{HCDvq7yMcLaqEbawS*z+2rEC<9 z8ak>+rl+YfxJW{G75RwjH}(h$_2v+H+rk#kI?bqoBaH!$djz{#BFN%K%bkTAO60iL znE0AO%tV-q<><)_Rb@Yh@FQTV+g8f5&z-F7$$wmg%ykN?egM(nn#s+$Hy|`5TnO^| z$r70AD;lh16-b`b^{MvZ?zBSA14T~qL4>tL*EjGovL^e3@hCRy8yQrfX>=UO~CO56KUuyRBO7i_n-JXKYH}ytNQ&G8eo6tkuJW>wd#HYp< zP8?_S&@z)jI<$C2^e&a2=O}d{&ZrA@1DR;Ht8Ii{cLr^R-+j`;q`#%b&W&g_7FvGn zkt})~?ZNOdHs6a@bTXO}KfW*X$sJHvOQ<{(H@`Wu_UiTy?6^sjR`A2Kay0NOL6CB=sAi8Y>N`oz3zUY>W8O&&NIs`CZ{2h! z=?=sWC#(Ep!zRX!_sxV+CvIXg9{i&<6i-WfJ-4#5GCtLb7wtbnw8&ZX9o+kI3+nZ~ z)j;HI_F2+E$P!IU+8XbPr+Aa8-rvolW6wQ3u+-c*ule_@RJrsIdpR~6-}98>DhBU!A!?M zgB2ShCEYZjni85uw+)NH>sFye`P8n3w3$$o<~XPo`2n2(>DLqawYuPBe!43TF3>Lp z`JSmy3lu3t73<9f4k^nWRryB4@1>;=6XQWtGFi2%a> zu|P9*R>LiN`Y3Wsq@%QTJXkMTO^sEJy$l9tA#7v{#m278lAVPFntyw8X^pDM` zJUhzUrd+p_V{3(GTTUe%^MSld1ov4t4+K- z`P!(AR6kN+Dpv&ErJTGj&Id{~8ZYeiiI$$#$nqLZyMbK#!xS|({wr}2O2#S>Nn|M6qbt8lChO>U(id|f8ur7V^Ym-DjYZEQpwC|niVU!`iyj#%Q0m_RX z0gwoeKFuYn)LV)&enMi_Rwg*7?Bc{1paq|@DU&V5rl7@(oeHqpHIQmegD(qa#ugtwq@@zUC)Li>1#Ms;~T2Y&`l;xXPgw<(Z z(=7l-ecO9k5@1E}MeK8+p8*UVmkt->z;#i~tBWYkMJX=`tdt87)04|9IfcVce8|A* zE5)JMPGO22>F;mdz{!85`V}owuKBo>E#u6Et4?ZHXu>}N{ZnA}JwkXJ7R4`AOT6r{ zUdI6ynFc;eCeUp{$9YfU_d#)a-_OW_1ClQZ0K!WBMEY7e zo{EFg!+c`zXgE5jzYJVr1WY>$*5bGh>jd09(DwyRQj-TM6&gF$RhYZYxhFsxk(@R= zLgUI=tHn~rk0DXFyb5svLv|_(04jYAW9WKJL1-u?tfpwG(1CpXvY_k(DnX1k&lA*Pb&%WMGab~PxA&e>j9ch_6{WDj`g4_68J~1IYOh%Vt*ir-s zz!Bc&WA#%Mf&WlIN*fD{0cm1hUYcA7xS zV@~KAPND`9uS;VOEiK#3HV=%qd7O@dTcGjWla9o~4ChSZrv~n<#{=Cg##miXHxItS z_DaAAz>3U$0ZoM@4ayLrWadNpAw={=dU*C34&IRn9e-UZ5S89!Nz<_~m4wlD*hk6Gz7jEs}0zgXJ)u zR!KF|{Bu;WI`fIm6Oh}y&LkXND%Y+bJII8>ZJD4T`-B#K5;-W$D7^!2I*}C>hDuS; zQj*l<0wi*Tg=p3WLTq0CUhGJ?P3Ib=sKXeyjeW7VN1)(r*-K$Mn23~2XUZk$9Yx&J z5H)7uq?>r3s7s@7I&=|}lk%^ZJxJ;utC#5sy$stsJ8^V6ToBnn9)*<{R)x_eBgoC@ zKHv)Gk_4O52jpNHmRQerjG#UjsWFxhLTDOtmUmzl`<17Lq^Wc;=AW=F=Yw$*61_&7 zOj#=k2#CMKU8$SLOSOeIl_}+A2ggKBwjVWqFThON50vwI#X|krNfGoRi>C`f6DS(1 zjWoi(Tm5V`Ta-{>qD8T#1T-dO`(X1Y(N|Q|JXFn@LOJ&4490F&*GqlR=c7XM7jes; z-HPX8#e7gMHOov@7pseHaOd9}A?0Q+)RdkY7bK1}OVfQr3|=Uc7{J4<$5KW_J#G&b z#QPqFLJuV;1?T~{;rwaon4@^TD4>exTN%GP1cil#)7P+2wE@E? z0cO!zrg}e*E(flbQk@Me1XCn~hPUf+R!5RBk}Fp4x67$hTV0AlySbA#y10{`TbMBR zWkJ&c*vsFcpAJ!fMD)WZQMyekuu-+`YpNCUME6@*iuJ@@DO<|%A`hyEJudQZ{sSXI zy69kr$&X;ybathUhRU8&8r@-VRB3&1Xn9Oz^1}Q?LHyS|G7lyr$*jelWKra&FAx#*6^ynD9r9mV7R-ME7UTp18j~GlG+fY$ zjE-AAk^GlXTYoz(cLvyQv0p9*04&t1WnIAZ+wd0M@cH)WYP%0EA%U5^37EwD^SE87 zp7yK;`^8jj-LYN}G3__|MS$FS{7IEVcF?KKhWoncvj;t&xmYro`2TyZsp0kWWI6?O z6bzlEo^~e6(eAyy1hVq?U`Z0cUFg?#hi?^YtvMg5e+eJUVtpF`PxjN}{WsNfw)Znk z=lgT1pe#0%v4C>omM*13LSx}3Y>d1Ax@GXT=p$`_?aTa0xZ+cIMh4^yC!^ngg91f@ zX&|8Ot1zP{SZyha1stFWyJ=1!$l?^aKlsKx^TX4wfKuK9eml>FxH%LfeMrESLG~cG$gbYcO%rw#F>gPm0@Y}FBJsgiLU^7Hy+pw z=rilt0zcpAj44q$yNL<=Z3_<%U*|F2`U6q_G1(4s=M#J4hu}eyp@z{q&?Ebyj8X<{LOeFjGu%OpgaW>58UXWC%QP)6s)Cctqz4WqP^=8Mum4J>(XibgEo~8H zBVd^NV&viz1FSP(!E2P8LpYWVQ~R89Vp`x!-CGa6mxGT0eyVo)9rQ^OaPpIEpH?=J ztt8^}{^}Nq%Z?a=M9`q23!owDi$4-UJ8v(k)|WY8W3oeVSx!`Id8r;D7HNKQsq*^; z_zhI;KbngCsi`5O*8W@{JNpDtz2kAIK+0wDbgSuk1p$@q5^3d+AXtM3n>~>(Hf&1l zLMi%+zJ(WfwQGB`p&;O;iKY5S@8Ls?iUS2UGc8kVU8-~Yf1fUGi@GIAf9)Xzp$2?u z4XAKS6`$W+soKuNhEGVDyT%LvEvf!FLvGn3U0X?i{~m~*!iIHQ`dhUupmTMZczM9G+2kiUujh{@Xw5RK$uOF92HThgqiTsV41leu zOXqjM1Mu{r?ChR_mN7rzTOP`mU`*a#$LvPQgQKIe-4Qg3WwVpO)?%++p4Es;Spt8 zUJ+No`$y5PapBt z(pDq^|2JmS(aDdk!>K$*$3uCQfzeHI0M7@2vKinaiBv#8r+^^@njM8Ax-uR2>FyOX zoK6=!kiW2k0O#0BTx&Y)-{I6stasm5Tw?%cjojpZfU{4a9$l1bF0yH4fgn=JbgV~9 zrPV+K3>iv7y_RZBoT+uo%9l**fZd?a-9E@U)Yyp9z52dphlAVdWI7$3JkhA>vjNGG z;vNV%j6VQ2rDWLcy?O6(Yg0KOHGKbjAp5aXP-{j=$+ii@J}R`EEh>j0U1b>9ZP*)Byyt@+UU-PO0}xp=@S2AR}FnANK}B-Za&` z9`}dG&T00~wg=;xl#2PG$A7%rj6m7I&lo}@R1Q_xRZO8s7w$(lI^koourWG#83i;h zXHNxBC+*%}pB^_p-pv@MPnT+^fFU5aa2JudKnB3WI?i8os7~VIp*BuZ=UUQLkO(-N zKn}#JZ+p7PxE8(;jn8fSa&H|lAqC9w>Ma-k&CDn{z1r}#M?J8`^v#KNLstJ6s%);k zQp`y}1tT`Jye~v`XFUNbe9+!_H2ADNxrkc+@ydo=`1)92#I zLaN!A=@Wnf(%&CV3xAY(l6VH>+_La31QCDwEk0eBL^QGsioo-aCPvCP$nCr{y&d;Q znEK-V@r%*?ml?R>d>|X!GqasFS5xYvY0ED>9=ab4(O2yzG zpvRwkkXg<8q!Q40oc6u?0UnJuYYcYV!i6SI=kH{ZtMBMGyzO~|aT$m8oO_DT27Oae z0F+pPRDPVG!MOEE&QS(9iv%FCgqeLD!OoZS*6~C}YMyZSGI2FwwGa2TI5JfFX4Ml1VCC@peAcReEjt}fpgNo0_fgBYR!t!}2kmUn zYnab+VNy<)a~_z4kG(JYf&Wee;vDltMX-a^b4#v#&X1P4a_weqGp7UnLpy*mWLcur zQqZA?IIB%aOigB!m+;(Xhk_6O)#tlx0O)Fgusgl4L|;>A@26I|Qmhc|wF~PJ5qfj2 zvT#ZxdnLv6Gaj?|34kcA`6lIFgW|{Ou&=+`WC#1J#?8CS7ep0DklW^dohLGGrGtes zk_tj0gw28Xn?+W$kl#S{`>bkj|M$`XsZjubzjKhDUCilOYm~uiiNW`=dZ|0fzU~U9 z=kr$opKXob{{{Xp>c4@3gPTe6YjQqI=S!ecDbatr-ou#~eZ6!E#_I~v>J-p!yC$#) zpsR;!mE6|{my8>n9-2X)yCYQ}!wPvF?sJEcj3y!KCV2H+M=Oo=fQg%Y&04l`mZ#?L z-@^ecN82ciHR11Xf!|Cf;l%5J&EP9O3?x~P)URPRzCa20^RahLHf!Q4e^*>jy5gXD z7;&jETzCR&a^~+P42J)P%}}T7)25JL+Ou7|&;^C`Z5ESQmdCWi^U1Li16W_Qsg&nH zgegh}1Y=Rye+Sy?c!a{`a$eR{SPtZ9seE27C*2J3SM>u#kH!a$91oi{-G%kxY9bM^ zQJY))vZ~I6gladZEw*2P#ycZdx?BT~Yv;O_c|v0~ey+m6*X!p?pe4ctU7%8`n#yLK z&gE~6M!G2gAZHN+CvuX&`y;Wznok(2hmv?%Eo+9|4auY4Pr}6}k_s{RZh)@lWSgfD z+OUdmOfmut0QxT1nrr#E&6!e=+@p_XL`71dT4MthVh6yQ8+zkJ*qm@@6=�%y5zCFVcP^wk3|@fu2IZ6eOur=R%?Wp? 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 z%0A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 z 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 eoS~mPKGbh}Ai~D$Iqf|I5O})!xvX Date: Mon, 9 Dec 2024 22:51:06 -0500 Subject: [PATCH 30/72] x --- docs/docs/concepts/v0-human-in-the-loop.md | 322 +++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 docs/docs/concepts/v0-human-in-the-loop.md diff --git a/docs/docs/concepts/v0-human-in-the-loop.md b/docs/docs/concepts/v0-human-in-the-loop.md new file mode 100644 index 000000000..45ce792d4 --- /dev/null +++ b/docs/docs/concepts/v0-human-in-the-loop.md @@ -0,0 +1,322 @@ +# Human-in-the-loop + +Human-in-the-loop (or "on-the-loop") enhances agent capabilities through several common user interaction patterns. + +Common interaction patterns include: + +(1) `Approval` - We can interrupt our agent, surface the current state to a user, and allow the user to accept an action. + +(2) `Editing` - We can interrupt our agent, surface the current state to a user, and allow the user to edit the agent state. + +(3) `Input` - We can explicitly create a graph node to collect human input and pass that input directly to the agent state. + +Use-cases for these interaction patterns include: + +(1) `Reviewing tool calls` - We can interrupt an agent to review and edit the results of tool calls. + +(2) `Time Travel` - We can manually re-play and / or fork past actions of an agent. + +## Persistence + +All of these interaction patterns are enabled by LangGraph's built-in [persistence](./persistence.md) layer, which will write a checkpoint of the graph state at each step. Persistence allows the graph to stop so that a human can review and / or edit the current state of the graph and then resume with the human's input. + +### Breakpoints + +Adding a [breakpoint](./low_level.md#breakpoints) a specific location in the graph flow is one way to enable human-in-the-loop. In this case, the developer knows *where* in the workflow human input is needed and simply places a breakpoint prior to or following that particular graph node. + +Here, we compile our graph with a checkpointer and a breakpoint at the node we want to interrupt before, `step_for_human_in_the_loop`. We then perform one of the above interaction patterns, which will create a new checkpoint if a human edits the graph state. The new checkpoint is saved to the `thread` and we can resume the graph execution from there by passing in `None` as the input. + +```python +# Compile our graph with a checkpointer and a breakpoint before "step_for_human_in_the_loop" +graph = builder.compile(checkpointer=checkpointer, interrupt_before=["step_for_human_in_the_loop"]) + +# Run the graph up to the breakpoint +thread_config = {"configurable": {"thread_id": "1"}} +for event in graph.stream(inputs, thread_config, stream_mode="values"): + print(event) + +# Perform some action that requires human in the loop + +# Continue the graph execution from the current checkpoint +for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) +``` + +### Dynamic Breakpoints + +Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. + +```python +def my_node(state: State) -> State: + if len(state['input']) > 5: + raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") + return state +``` + +Let's assume we run the graph with an input that triggers the dynamic breakpoint and then attempt to resume the graph execution simply by passing in `None` for the input. + +```python +# Attempt to continue the graph execution with no change to state after we hit the dynamic breakpoint +for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) +``` + +The graph will *interrupt* again because this node will be *re-run* with the same graph state. We need to change the graph state such that the condition that triggers the dynamic breakpoint is no longer met. So, we can simply edit the graph state to an input that meets the condition of our dynamic breakpoint (< 5 characters) and re-run the node. + +```python +# Update the state to pass the dynamic breakpoint +graph.update_state(config=thread_config, values={"input": "foo"}) +for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) +``` + +Alternatively, what if we want to keep our current input and skip the node (`my_node`) that performs the check? To do this, we can simply perform the graph update with `as_node="my_node"` and pass in `None` for the values. This will make no update the graph state, but run the update as `my_node`, effectively skipping the node and bypassing the dynamic breakpoint. + +```python +# This update will skip the node `my_node` altogether +graph.update_state(config=thread_config, values=None, as_node="my_node") +for event in graph.stream(None, thread_config, stream_mode="values"): + print(event) +``` + +See [our guide](../how-tos/human_in_the_loop/dynamic_breakpoints.ipynb) for a detailed how-to on doing this! + +## Interaction Patterns + +### Approval + +![](./img/human_in_the_loop/approval.png) + +Sometimes we want to approve certain steps in our agent's execution. + +We can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to the step that we want to approve. + +This is generally recommend for sensitive actions (e.g., using external APIs or writing to a database). + +With persistence, we can surface the current agent state as well as the next step to a user for review and approval. + +If approved, the graph resumes execution from the last saved checkpoint, which is saved to the `thread`: + +```python +# Compile our graph with a checkpointer and a breakpoint before the step to approve +graph = builder.compile(checkpointer=checkpointer, interrupt_before=["node_2"]) + +# Run the graph up to the breakpoint +for event in graph.stream(inputs, thread, stream_mode="values"): + print(event) + +# ... Get human approval ... + +# If approved, continue the graph execution from the last saved checkpoint +for event in graph.stream(None, thread, stream_mode="values"): + print(event) +``` + +See [our guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a detailed how-to on doing this! + +### Editing + +![](./img/human_in_the_loop/edit_graph_state.png) + +Sometimes we want to review and edit the agent's state. + +As with approval, we can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to the step we want to check. + +We can surface the current state to a user and allow the user to edit the agent state. + +This can, for example, be used to correct the agent if it made a mistake (e.g., see the section on tool calling below). + +We can edit the graph state by forking the current checkpoint, which is saved to the `thread`. + +We can then proceed with the graph from our forked checkpoint as done before. + +```python +# Compile our graph with a checkpointer and a breakpoint before the step to review +graph = builder.compile(checkpointer=checkpointer, interrupt_before=["node_2"]) + +# Run the graph up to the breakpoint +for event in graph.stream(inputs, thread, stream_mode="values"): + print(event) + +# Review the state, decide to edit it, and create a forked checkpoint with the new state +graph.update_state(thread, {"state": "new state"}) + +# Continue the graph execution from the forked checkpoint +for event in graph.stream(None, thread, stream_mode="values"): + print(event) +``` + +See [this guide](../how-tos/human_in_the_loop/edit-graph-state.ipynb) for a detailed how-to on doing this! + +### Input + +![](./img/human_in_the_loop/wait_for_input.png) + +Sometimes we want to explicitly get human input at a particular step in the graph. + +We can create a graph node designated for this (e.g., `human_input` in our example diagram). + +As with approval and editing, we can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to this node. + +We can then perform a state update that includes the human input, just as we did with editing state. + +But, we add one thing: + +We can use `as_node=human_input` with the state update to specify that the state update *should be treated as a node*. + +The is subtle, but important: + +With editing, the user makes a decision about whether or not to edit the graph state. + +With input, we explicitly define a node in our graph for collecting human input! + +The state update with the human input then runs *as this node*. + +```python +# Compile our graph with a checkpointer and a breakpoint before the step to to collect human input +graph = builder.compile(checkpointer=checkpointer, interrupt_before=["human_input"]) + +# Run the graph up to the breakpoint +for event in graph.stream(inputs, thread, stream_mode="values"): + print(event) + +# Update the state with the user input as if it was the human_input node +graph.update_state(thread, {"user_input": user_input}, as_node="human_input") + +# Continue the graph execution from the checkpoint created by the human_input node +for event in graph.stream(None, thread, stream_mode="values"): + print(event) +``` + +See [this guide](../how-tos/human_in_the_loop/wait-user-input.ipynb) for a detailed how-to on doing this! + +## Use-cases + +### Reviewing Tool Calls + +Some user interaction patterns combine the above ideas. + +For example, many agents use [tool calling](https://python.langchain.com/docs/how_to/tool_calling/) to make decisions. + +Tool calling presents a challenge because the agent must get two things right: + +(1) The name of the tool to call + +(2) The arguments to pass to the tool + +Even if the tool call is correct, we may also want to apply discretion: + +(3) The tool call may be a sensitive operation that we want to approve + +With these points in mind, we can combine the above ideas to create a human-in-the-loop review of a tool call. + +```python +# Compile our graph with a checkpointer and a breakpoint before the step to to review the tool call from the LLM +graph = builder.compile(checkpointer=checkpointer, interrupt_before=["human_review"]) + +# Run the graph up to the breakpoint +for event in graph.stream(inputs, thread, stream_mode="values"): + print(event) + +# Review the tool call and update it, if needed, as the human_review node +graph.update_state(thread, {"tool_call": "updated tool call"}, as_node="human_review") + +# Otherwise, approve the tool call and proceed with the graph execution with no edits + +# Continue the graph execution from either: +# (1) the forked checkpoint created by human_review or +# (2) the checkpoint saved when the tool call was originally made (no edits in human_review) +for event in graph.stream(None, thread, stream_mode="values"): + print(event) +``` + +See [this guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a detailed how-to on doing this! + +### Time Travel + +When working with agents, we often want closely examine their decision making process: + +(1) Even when they arrive a desired final result, the reasoning that led to that result is often important to examine. + +(2) When agents make mistakes, it is often valuable to understand why. + +(3) In either of the above cases, it is useful to manually explore alternative decision making paths. + +Collectively, we call these debugging concepts `time-travel` and they are composed of `replaying` and `forking`. + +#### Replaying + +![](./img/human_in_the_loop/replay.png) + +Sometimes we want to simply replay past actions of an agent. + +Above, we showed the case of executing an agent from the current state (or checkpoint) of the graph. + +We by simply passing in `None` for the input with a `thread`. + +``` +thread = {"configurable": {"thread_id": "1"}} +for event in graph.stream(None, thread, stream_mode="values"): + print(event) +``` + +Now, we can modify this to replay past actions from a *specific* checkpoint by passing in the checkpoint ID. + +To get a specific checkpoint ID, we can easily get all of the checkpoints in the thread and filter to the one we want. + +```python +all_checkpoints = [] +for state in app.get_state_history(thread): + all_checkpoints.append(state) +``` + +Each checkpoint has a unique ID, which we can use to replay from a specific checkpoint. + +Assume from reviewing the checkpoints that we want to replay from one, `xxx`. + +We just pass in the checkpoint ID when we run the graph. + +```python +config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xxx'}} +for event in graph.stream(None, config, stream_mode="values"): + print(event) +``` + +Importantly, the graph knows which checkpoints have been previously executed. + +So, it will re-play any previously executed nodes rather than re-executing them. + +See [this additional conceptual guide](https://langchain-ai.github.io/langgraph/concepts/persistence/#replay) for related context on replaying. + +See see [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a detailed how-to on doing time-travel! + +#### Forking + +![](./img/human_in_the_loop/forking.png) + +Sometimes we want to fork past actions of an agent, and explore different paths through the graph. + +`Editing`, as discussed above, is *exactly* how we do this for the *current* state of the graph! + +But, what if we want to fork *past* states of the graph? + +For example, let's say we want to edit a particular checkpoint, `xxx`. + +We pass this `checkpoint_id` when we update the state of the graph. + +```python +config = {"configurable": {"thread_id": "1", "checkpoint_id": "xxx"}} +graph.update_state(config, {"state": "updated state"}, ) +``` + +This creates a new forked checkpoint, `xxx-fork`, which we can then run the graph from. + +```python +config = {'configurable': {'thread_id': '1', 'checkpoint_id': 'xxx-fork'}} +for event in graph.stream(None, config, stream_mode="values"): + print(event) +``` + +See [this additional conceptual guide](https://langchain-ai.github.io/langgraph/concepts/persistence/#update-state) for related context on forking. + +See see [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a detailed how-to on doing time-travel! From 5bfb9af5fe40879cd1474c6d83193f32b3c15b17 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 22:53:35 -0500 Subject: [PATCH 31/72] x --- docs/docs/concepts/human_in_the_loop.md | 69 ++++++++++++++----------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 9b5f93a54..493d8f149 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -78,40 +78,47 @@ critical in applications where the tool calls requested by the LLM may be sensit -```python -from langgraph.types import interrupt +=== "Review tool calls" -def human_editing(state: State): - ... - result = interrupt( - # Interrupt information to surface to the client. - # Can be any JSON serializable value. - { - "task": "Review the output from the LLM and make any necessary edits.", - "llm_output": state["llm_output"] + TODO: Create an example for tool call review. + + +=== "Review text output from the LLM and make any necessary edits." + + ```python + from langgraph.types import interrupt + + def human_editing(state: State): + ... + result = interrupt( + # Interrupt information to surface to the client. + # Can be any JSON serializable value. + { + "task": "Review the output from the LLM and make any necessary edits.", + "llm_output": state["llm_output"] + } + ) + + # Update the state with the edited text + return { + "llm_output": result["edited_text"] } + + # Add the node to the graph in an appropriate location + # and connect it to the relevant nodes. + graph_builder.add_node("human_editing", human_editing) + graph = graph_builder.compile(checkpointer=checkpointer) + + ... + + # After running the graph and hitting the breakpoint, the graph will pause. + # Resume it with the edited text. + thread_config = {"configurable": {"thread_id": "some_id"}} + graph.invoke( + Command(resume={"edited_text": "The edited text"}), + config=thread_config ) - - # Update the state with the edited text - return { - "llm_output": result["edited_text"] - } - -# Add the node to the graph in an appropriate location -# and connect it to the relevant nodes. -graph_builder.add_node("human_editing", human_editing) -graph = graph_builder.compile(checkpointer=checkpointer) - -... - -# After running the graph and hitting the breakpoint, the graph will pause. -# Resume it with the edited text. -thread_config = {"configurable": {"thread_id": "some_id"}} -graph.invoke( - Command(resume={"edited_text": "The edited text"}), - config=thread_config -) -``` + ``` ### Multi-turn conversation (Input) From 01cdb60b5d3bd1f74cd9f5add50ad67c25ae9c85 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 9 Dec 2024 23:14:19 -0500 Subject: [PATCH 32/72] x --- .../human_in_the_loop/breakpoints.ipynb | 10 +++++++- .../dynamic_breakpoints.ipynb | 23 +++++++++++-------- .../human_in_the_loop/edit-graph-state.ipynb | 8 ++++++- .../how-tos/human_in_the_loop/interrupt.ipynb | 10 +++++++- .../human_in_the_loop/review-tool-calls.ipynb | 11 ++++++++- .../human_in_the_loop/time-travel.ipynb | 10 +++++++- .../human_in_the_loop/wait-user-input.ipynb | 21 +++++++++-------- 7 files changed, 69 insertions(+), 24 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb b/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb index a52f3b216..a74a8ceb4 100644 --- a/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb @@ -12,6 +12,14 @@ "source": [ "# How to add breakpoints\n", "\n", + "!!! tip \"Prerequisits\"\n", + "\n", + " This guide assumes familiarity with the following concepts:\n", + "\n", + " * [Breakpoints](../../../concepts/breakpoints)\n", + " * [LangGraph Glossary](../../../concepts/low_level)\n", + " \n", + "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). [Breakpoints](https://langchain-ai.github.io/langgraph/concepts/low_level/#breakpoints) are a common HIL interaction pattern, allowing the graph to stop at specific steps and seek human approval before proceeding (e.g., for sensitive actions). \n", "\n", "Breakpoints are built on top of LangGraph [checkpoints](https://langchain-ai.github.io/langgraph/concepts/low_level/#checkpointer), which save the graph's state after each node execution. Checkpoints are saved in [threads](https://langchain-ai.github.io/langgraph/concepts/low_level/#threads) that preserve graph state and can be accessed after a graph has finished execution. This allows for graph execution to pause at specific points, await human approval, and then resume execution from the last checkpoint.\n", @@ -467,7 +475,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb index e1e06cd49..9de44a77c 100644 --- a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb @@ -1,18 +1,21 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", - "id": "ee54cde3-7e4d-43f4-b921-e7141ea0f19e", - "metadata": {}, - "source": [ - "# How to add dynamic breakpoints" - ] - }, - { - "cell_type": "markdown", - "id": "607849c6-4b8c-4e06-ad9c-758bb5a08e86", + "id": "b7d5f6a5-9e59-43e4-a4b6-8ada6dace691", "metadata": {}, "source": [ + "# How to add dynamic breakpoints\n", + "\n", + "!!! tip \"Prerequisits\"\n", + "\n", + " This guide assumes familiarity with the following concepts:\n", + "\n", + " * [Breakpoints](../../../concepts/breakpoints)\n", + " * [LangGraph Glossary](../../../concepts/low_level)\n", + " \n", + "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). [Breakpoints](https://langchain-ai.github.io/langgraph/concepts/low_level/#breakpoints) are a common HIL interaction pattern, allowing the graph to stop at specific steps and seek human approval before proceeding (e.g., for sensitive actions).\n", "\n", "In LangGraph you can add breakpoints before / after a node is executed. But oftentimes it may be helpful to **dynamically** interrupt the graph from inside a given node based on some condition. When doing so, it may also be helpful to include information about **why** that interrupt was raised.\n", @@ -430,7 +433,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb b/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb index 4d7685cfa..a398b1bf6 100644 --- a/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb @@ -12,6 +12,12 @@ "source": [ "# How to edit graph state\n", "\n", + "!!! tip \"Prerequisits\"\n", + "\n", + " * [Human-in-the-loop](../../../concepts/human_in_the_loop)\n", + " * [Breakpoints](../../../concepts/breakpoints)\n", + " * [LangGraph Glossary](../../../concepts/low_level)\n", + "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). Manually updating the graph state a common HIL interaction pattern, allowing the human to edit actions (e.g., what tool is being called or how it is being called).\n", "\n", "We can implement this in LangGraph using a [breakpoint](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/breakpoints/): breakpoints allow us to interrupt graph execution before a specific step. At this breakpoint, we can manually update the graph state and then resume from that spot to continue. \n", @@ -554,7 +560,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index f063a07fc..92c94e4a6 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -11,7 +11,15 @@ "tags": [] }, "source": [ - "# How to use interrupt for human-in-the-loop workflows\n", + "# How to use add breakpoints using interrupt?\n", + "\n", + "!!! tip \"Prerequisits\"\n", + "\n", + " This guide assumes familiarity with the following concepts:\n", + "\n", + " * [Breakpoints](../../../concepts/breakpoints)\n", + " * [LangGraph Glossary](../../../concepts/low_level)\n", + " \n", "\n", "An `interrupt` is a convenient way to support human-in-the-loop workflows.\n", "\n", diff --git a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb index 773511099..bdffd2733 100644 --- a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb @@ -8,6 +8,15 @@ "source": [ "# How to Review Tool Calls\n", "\n", + "!!! tip \"Prerequisits\"\n", + "\n", + " This guide assumes familiarity with the following concepts:\n", + "\n", + " * [Tool calling])(https://python.langchain.com/docs/concepts/tool_calling/)\n", + " * [Human-in-the-loop](../../../concepts/human_in_the_loop)\n", + " * [Breakpoints](../../../concepts/breakpoints\n", + " * [LangGraph Glossary](../../../concepts/low_level) \n", + "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). A common pattern is to add some human in the loop step after certain tool calls. These tool calls often lead to either a function call or saving of some information. Examples include:\n", "\n", "- A tool call to execute SQL, which will then be run by the tool\n", @@ -674,7 +683,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb b/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb index 5565b95ca..d37a73bc1 100644 --- a/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb @@ -7,6 +7,14 @@ "source": [ "# How to view and update past graph state\n", "\n", + "!!! tip \"Prerequisits\"\n", + "\n", + " This guide assumes familiarity with the following concepts:\n", + " \n", + " * [Breakpoints](../../../concepts/breakpoints)\n", + " * [LangGraph Glossary](../../../concepts/low_level)\n", + "\n", + "\n", "Once you start [checkpointing](../../persistence) your graphs, you can easily **get** or **update** the state of the agent at any point in time. This permits a few things:\n", "\n", "1. You can surface a state during an interrupt to a user to let them accept an action.\n", @@ -589,7 +597,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.9" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index 7d6d378b9..ca665342f 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -1,22 +1,25 @@ { "cells": [ { - "attachments": { - "f6c5e4f7-4e60-4085-95ad-6edeaeb902e0.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAACGUAAAT7CAYAAAA9nJ+qAAAAAXNSR0IArs4c6QAAIABJREFUeF7snQmcTeX/x7+zMINhZjDGTiJ+iRAtRCKJUpYihCRLkUQphWQtUckWIhJKdiEhe8rWgrTbl7HNGMMwY2b+r8/DOf9zz5x777kzd2bu5fN9vbzi3uc8y/s599xpvp/n8w1IS0tLEwYJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkIBXCQRQlOFVnuyMBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABBQBijJ4I5AACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAFhCgKCMLoLJLEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEqAog/cACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACWQBAYoysgAquyQBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABijJ4D5AACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAFhCgKCMLoLJLEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEqAog/cACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACWQBAYoysgAquyQBEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABEiABijJ4D5AACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZAACZBAFhCgKCMLoLJLEiABEiABEiABEiABEsgMgYsrV0pqQoLkvu02yVWhggTmy5eZ7nhtThFISZHYCRPk4vLlEly6tET27i0h1arl1Gw4LgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQQA4QoCgjB6BzSBIgARIgARIgARIgARJwReDoQw9JyrlzehOIMnLffrsu0shTt64ERUYSoo8TSFi0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faJh2tWrqmyJy0hLE0lN/X+hRkqKXD11SoIiI3Uhg/n6qzExStBgFC5YjpGSkiEXidS4OCUycRvX+9dKqJTevl2tN+3yZfXHVh9uB7nW4Ozw4ZKwaJEqJQMhB8qYQDTCIAESIAESIAESIAESIAESIAESIAESIAESIAESuPEIUJRx4+0pV0QCJEACJEACJEACJEACJJBBApooo8yOHRkSgdgdNiU2VoIKFMjSMezOhe1IgARIgARIgARIgARIgARIgARIgARIgARIgASyjgBFGVnHlj2TAAmQAAmQAAmQAAmQAAn4GYETHTpI0r59Umr9eqduI362JE6XBEiABEiABEiABEiABEiABEiABEiABEiABEggBwlQlJGD8Dk0CZAACZAACZAACZAACZCAbxE43a+fXFq/XorPn8+SIr61NZwNCZAACZAACZAACZAACZAACZAACZAACZAACfglAYoy/HLbOGkSIAESIAESIAESIAESIIGsIBD78ccSP3OmRLz0koR37pwVQ7BPEiABEiABEiABEiABEiABEiABEiABEiABEiCBm4gARRk30WZzqSRAAiRAAiRAAiRAAiRAAq4JXPnlFzn53HMSFB0tJVeuFAkIIDISIAESIAESIAESIAESIAESIAESIAESIAESIAESyDABijIyjI4XkgAJkAAJkAAJkAAJkAAJ3HAEUlLkaOPGknLunJTevl0CgoNvuCVyQSRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAtlHgKKM7GPNkUiABEiABEiABEiABEiABPyAQPLBg5Jy+rSE1qrlB7PlFEmABEiABEiABEiABEiABEiABEiABEiABEiABHyZAEUZvrw7nBsJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkIDfEqAow2+3jhMnARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARLwZQIUZfjy7nBuJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACJEACfkuAogy/3TpOnARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIgARIwJcJUJThy7vDuZEACZAACZAACZAACZAACZAACZAACZAACZCAnxJISUmR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sOErxRnJlph/7tc+9JDdMnq0bbH55jbmiSfyz4AjIFBmArNuvdVm33VXUGrcUCYT99/fFn/33Ypjtt7a1ho5ssy1prhyElg6Zcr/BBqvv262bFla8U179LCmEmhsv7013mSTclYtkbJmz1hiQw/+1pYtW27dt2tl2/evjDBZbmPxlpFI16dlKkHsc889Z59++mnq+/XWWy8QZuy0004INJLvgnpbAqKMutv1iDLqbt/SssohgCijcvqCmkAAAhCAAAQqjQCijErrEeoDAQhAAAIQqEACN954o7388sv28ccfp9Vuyy23tL333tsOPfRQa9asWQXWvHRVWrp0qfXaZhubPG2a/WXoUNu5R4/SZV7CnN7+9FM75JJLghxfe+01W6eOu/gvITqyqkEC0//0J5v7j38ENajacUdrd/PNGWvz0xFH2C/jxgW/N+ne3dr/5S81WHOKLjeBJePH24I33kh9/PKbdOtmVf36WbOddrJGFebNKC6r15+abQ9cPzlIvv+x69hanZrGPbRs6WZO/cX+dtsKYZTs2tEb2uprNCxb+fWpoFdffTUQZ+gzefKKcSFDoFGfRkF524ooo7y8y1kaooxy0qas+koAUUZ97XnaDQEIQAACEMhNIHFRxpIlS+znn38OXG42btw4d42KTLFo0SKbM2dOUF7TppU3eVVk8zgcAhCAAAQgUKMEJMp46aWXqgk01lhjDTvooINswIABtsUWW9RoHZMq/J133rGDDz7YVm/WzP5z771JFVOSfHccNMjGT5liEtPsv//+JcmTTCCQNIEpgwcHC+2yZjvvbG2vu65akZNPOMEWvv9+8L08Iqz9178mXS3yr2ACuQQaEmboU7XTTtagefMKbkl61a7743j76t8LrE37JnbQCetWbL0fvu07mzH1l6B+p9/Y2bp2r6rYutaFis2dOzclzpBAQ2LR0EKBhkKc1DcvZnWhbyutDdOmTbPbb789Va3NN988EGFjtZ/ARx99ZE899VSqIQMHDrTu3bvX/obRAghUEAG9g8+bNy+oUYsWLewPf/hDBdWOqkAAAhCAAAQgUJMESi7K0ETB888/Hzzkf/DBBzZ9+vSgfccff7xdcMEFibd17NixQQx1WfPmza1r166211572R577GGdO3dOvHwKgAAEIAABCNQXAhJoyHvGM888Y5999lmq2QpvonAncq9d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AQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEECUwRiAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACCRBAlJEAVLKEAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACiDIYAxCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQCABAogyEoBKlhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQABRBmMAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIJEAAUUYCUMkSAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIIMpgDEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAIEECCDKSAAqWUIAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAFEGYwBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgkAABRBkJQCVLCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQggCiDMQABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQSIIAoIwGoZAkBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQQZTAGIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAQAIEEGUkAJUsIQABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAKIMxgAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhBIgACijASgkiUEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhBAlMEYgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAgkQQJSRAFSyhAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAogyGAMQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAgAQKIMhKASpYQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAUQZjAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCCRAAFFGAlDJEgIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCCDKYAxAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIACBBAggykgAKllCAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABRBmMAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIJAAAUQZCUAlSwhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIIAogzEAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEEiCAKCMBqGQJAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEEGUwBiAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgEACBBBlJACVLCEAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgACiDMYABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQSIAAoowEoJIlBCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQQJTBGIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIJEECUkQBUsoQABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAKIMhgDEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAIAECiDISgEqWEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAFEGYwACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQgkQABRRgJQyRICEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQggymAMQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAgQQIIMpIACpZQgACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAUQZjAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCCQAAFEGQlAJUsIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCCAKIMxAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABBIggCgjAahkCQEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABBBlMAYgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIBAAgQQZSQAlSwhAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAAogzGAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEEiAAKKMBKCSJQQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEECUwRiAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACCRBAlJEAVLKEAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACiDIYAxCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQCABAogyEoBKlhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQABRBmMAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIJEAAUUYCUMkSAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIIMpgDEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAAB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QHM9AUIZrncmaa3o999/l3r16pm7EKIx1vmxWmMLqF+aq1+eJ20LFizQFTOyovG/tVmh7pg5Z8yYIWPHjk1z8P/H3ntAy1Fc299FFGCQAIskBAITbUwSUQhEzjkHmZwt+JNMkMhBCASIbEBIZIGNyTnnZILIGZskEWXyIxr41q+/V/1q6nacqZ47c+8+a2nBnamusKu6uqfOPvuIlFEN9qq1vREQKaO950+9FwJCQAgIASEgBISAEBACQkAICAEhIASEgBAIjACyzPPNN19cK9Gl999/f+FWRowYYc4///y4/Lhx4+JocZEyCsPYtIL33Xef2XnnneP25EhoGvSlGxIpozRknXqBSBmdCr8a7+YIDBkyxNxyyy01KJx55plmk0026RRk9KztFNgraVSkjEpgVaXdAAGRMrrBJGuIQkAICAEhIASEgBAQAkJACAgBISAEhIAQEALlEOjfv7/5z3/+E1/07rvvFq4Ap/51110Xl0cufIEFFoj+FimjMIxNK+g7ivbee29z2GGHNa19NVQcAZEyimPVCiVFymiFWVAfuisCjz76qNluu+3i4f/mN78xzzzzjJl22mk7BRI9azsF9koa/frrrw3/XIO8PGzYsPgjEVwrgV6VtjkCImW0+QSq+0JACAgBISAEhIAQEAJCQAgIASEgBISAEBAC4RHYfPPNzdNPPx1X/Oqrr5rpppuuUEPbbruteeyxx+KyL774ounZs2f0t0gZhSBsaiE5ipoKd0ONiZTREHxNv1ikjKZDrgaFQIzAr7/+ap588klz0003mV69epltttnGzD333J2GkJ61nQZ9Uxq+8847zR577BG3JVJGU2BXI22GgEgZbTZh6q4QEAJCQAgIASEgBISAEBACQkAICAEhIASEQPUI7L///ub666+PG3r44YcLOzNWXXVVg/PYmquyIVJG9XNXtgU5isoi1nnlRcroPOzraVmkjHpQ0zVCoGsioGdt15xXOyqRMrr2/Gp0YRAQKSMMjqpFCAgBISAEhIAQEAJCQAgIASEgBISAEBACQqALITBy5Ehz7rnnxiO64YYbzJJLLllohP369YvLkbaE9CXWskgZ//M//2M++eQTM/XUU5s55pjDTD755IXaSyr03XffmYkTJ5revXubGWecse567IU///xzlM7lyy+/NH369DHIoLeS/fjjj+aLL74wX331VYQbUcGok0w11VS53azaUfTpp58aIpZnnnlmM+WUU+b2J6/AL7/8YiZNmmSYk5lmmslMM800eZdkfv/TTz/F644+TjHFFHXX99///tdMmDDB9OjRw8w+++xmsskmq7uujz76KJrPOeecM15vImUUhzPkXBRvtbZkFimj3j2Fe4k1y33OWm1kjdU7rrLXhd6Py7bvlgc7MGsX7Oj7t99+G6dKmG222RoZvqlyLljT7Ftg3Ldv37r2e+5b9j2etfw/zzH+dVbKER/sVn7WghnPW54ZIfBiHj/++GPDmOeaa65C7xNZi5P6eD5y/80yyywNvUdVuY7rvcFCkDK0v9eiH2JPqXc+dV01CIiUUQ2uqlUICAEhIASEgBAQAkJACAgBISAEhIAQEAJCoI0RuPzyy80RRxwRj2DMmDFmzTXXjP5++eWXzV577RV/96c//cnsueee0d84j37/+9/H36222mrm4osvjv9OImVAJjj55JPN888/X4PYSiutZI488kiz0EILFUKSFCvnnXeeIV2Kq9Tx29/+1iy66KJm9913NyuuuGJqXZAutt56a/PDDz9EZQ477DCzyiqrmDPPPNNccMEFNddBGmHc4BCCaFBogP9biEN75uCOO+4wt956a81Yk+rZcccdzXHHHRd/dcYZZ5hrr702/hsyDGO3BuEEzNIMee7tt98+9Xv6d/XVV0d9IwUO9VtbfPHFzQorrGD23XffTIdM0lysscYa5pxzzjFjx46tqfOPf/yjGThwoEEqPM0R9cgjj5ihQ4fG/Rg3blw0b6eccoq57rrrasay/PLLm/XXXz8aYxGH92effWbOOussM378+Jo1DI7cCxtvvHG0VoqQjJ566ilz4YUXRri5cwJu5KqfddZZDUo01tZee20zevToMsun08pCptlkk03M559/HvWB/eSoo46K/h8yFimTrJFmYMiQIdGfrJ911lkn/m6RRRYx559/fuI4Qs5FCKCSSBmnn356Q3vKa6+9Zph311hrOOuXXnpp079//2iNQApKM5yjG264Yc19dM0110R1ZNnOO+9s3nrrrbjI8ccfH+2RSdbofhwC/6Q6/vCHP9SMmzLs50sssYRZaqmlomeE+wyrqh9+vextf//736OP2X8hQj7zzDPmpJNOilJwWGOuBwwYYHbZZZdo3ytijc4FKclwpvvGs2W33XaL9iqe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3nln5PROM1KeQIIgZUdXMZy6kyZNiiL8IFdMP/30kTTyTDPNFA+R6EEi+ojyc/9bhskYEi/6SVQiaweFCSIEiRScbbbZzCyzzGKmmGKKkM11Sl3My/vvvx+Ns2fPnpGsd48ePTqlL92p0Swp0y+++CJKY0QULASZsvPBnLJmmVPW7bzzzmtIhYTZNV02ktadm+5wX3SntaixCgEhIASEgBAQAkJACAgBISAEshCompSBQhMptQio4kyO4IbOslDO57zf/J9++qmZeeaZ49/q9Y4XzKiL87UiSsD1tlPvdZxPcDbx3XffRQphnDu1qvoWZ5acx4TAkjXNuH/66adI3ayec02uR7m03uv9OaMvqKShDjDXXHPlKrW514e6L+pdR/Vcx57CP86d+Zc3B1npSxrBzu87wYso0nHWN/vsswe5HyBZoMLN3sl9xplfljWTlGH9AdwTzEMjvg7qIHKc/3I234rGHlLv/i4H6v/N6DfffBOdbeN/4Xy82RZ6LqokZVSxpzSyjkPPVei5cPvXDntKI3hWiV0j/dK11SDQkqQMhvrJJ59EqUzS8kGSW7lMful64bvsssuiyPckIzfnfvvt15I/puodr64TAkKgFgHll9WKEAJCQAgIASEgBISAEBACQkAIdE8EUOXcddddDQfp2MEHH2w22mij6P/vvffe6NzKGgeqAwcOjP5E6ZKy1nbYYQez++6714BIANCrr76aCeyAAQPMyJEjU8ucccYZkey3NRx4ODet4fizxP+kSujD9ttvX/PVv/71r1h9lS/WXnvtSC0SJdYLLrigpizKpKTe3GuvvXIdqY2uIAgnfnrX9957r6baueeeO7UZVCcZh29Jv/k5CwRbH8v11lvPkK60qOOJVDSkFEZ9162LfnKmiRotSsCdZay/sWPHRuuQgBPfCJjbYostzIorrpjYReaeoC1rDzzwQGJQFGV22mmn+D4iLQ/pll077bTTDGe9vi266KIGhVSc7RdddFG0Dl0FY7AcOnSoYW5cQ1kYh7pvO+64Y6Qoy3ycfPLJ5u9//3tNEdbJCSecYH7/+9+nTgv7Abgx3ueff76mP1wHXvvvv38U5JZmjzzySNRva+PGjYsUgbnf/bNw6mStIO3vW1X3RZVrEuzPO++8CDtSFviK1ARAohyLknZS6sAkUsbKK69cGrukMX722WfmrLPOMuPHj69Jmc1eyjywdln3WWkH3XpZt5dccolhvlGtdvcByhHgxT225ZZbJu7VZUkZrCnaskaq60GDBsV/0z4KvQRxYYcddlikTH7OOedEa9qdC9SAeaYdcMABhXwfELrOPffcqH32PGtg179//2j9FsEuxLPRts3z+4033oj+5FnG/l3P/u7vdeDoYsVzNoukCL6LL754JbcV+wb3CiQYjPQfKDBj+Nc233zzuN1tttnGDBkyJPqb/q+zzjrxd4sssog5//zzo7/99xu346jIQyxEQfq4444z7nMYHHjf2WeffTq8E/jtpYFB/+hnmoWci7feesvsvPPONU2Vea/gwrTnnq00xJ4Sah2HXoAh5yKpb6H2lJDjbsV1HHJ8qqs5CLQsKcMO/9FHHzXXX3+9ue2222oedvwQdB8cVcHls5R4uPBiyAvTwgsvXFWzqlcICIEWQUCkjBaZCHVDCAgBISAEhIAQEAJCQAgIASHQZAQ4sF999dXjVnEk77vvvtHfOJ9cwsSxxx4bJE3itQAAIABJREFUOZ4xHPGu05nUlYMHD67pvR+NmTS0VVZZxVx66aWpo4YMcfvtt9eNCsQRnCeuJZEy+B4l2TSDYHDVVVcVctzV29msoKkideLopY+++b/5mUef/OFew7kgTuGslL0c2lOP7/BP6ueIESOi1MTNVKXA0UEqWdZwEcNhjPNtuummqym+0kor1TjkIDElKdU+88wzNelZt9tuO8O4XYO0hLPPN5tqloA51kCa4Wx1iU9paZchmpBClzNlPyWtWzfpnUmh7RsOu//3//5fjdM5qU8QlnDuL7vssold9okFEE4OP/zwTNVonIcuEYyKq7oviqyLsmVQiOWMn7nyiRhJdeHExpntk6187CDAcK8lpeK29SZh57eJD4L93SdO+OXYS1hDKLVkGcQE9tisdWavZ1/hnrTEPvt5WVIG5Ae3/zjO3b3K398hZfAZz6w0g5xB2vYsxXKID3/+859zx0q6dbDLIguGeDbasbj7O8Qd2q9nf0/bT4reA9dcc41ZZpllihYvXc4dJym17bPn6aefriFlQIxhLrF33nnHgIk1N6U5RKI0nEgTDpGP+U4zcEZZ3rWvv/7asJbyjH0wS7U+5Fwwjkb9i2nPPcYZak8JtY7zsC/7fci58NsOuaeUHVdW+VZcxyHHp7qag0DLkzIsDLCQYfchUYcUG5t4UWZ6I1CSLoJ/yHbxwoC0WFE2bCPt6lohIARaAwGRMlpjHtQLISAEhIAQEAJCQAgIASEgBIRAsxHwD18hXeBsxw455JAap7vr9MOReMopp8TdJQreVxsI4XhqBimD1Kk4HfLMJazkla3n+6qcz/5vfpzpWc5d+p5G8OA7HM84/t1I8bzxohrgKz3kXVPv95yvEmyGSkEZg5iBM9W1ZpAyaA+CBH3OMsgbOCAtcSTNWYSjH6WAYcOGZdaXRIgi1QFOzCKEAlt5Wvptn1iAExPVizzDee4SPaq6L/L6Uc/3KJBYh3DR69l/CNR0U/742BXdo3zs3D4Q7Y6KSlFD4QIlnLRUKxCMfHWkInWjUDD//PPHRcuQMlifKL24BuHC7WMS6S6LcGfrwify2GOPJaY0If05e2JRg2TDWk9SQaGOEM9G2xd3f2fObKqNrL4m7e9VOp+L4pZVzsWM+wHiBAYJCtKSNfe7p556Kgo6tgbZ7KCDDor+zCJlQCCDbJRHXvJV7lvRmV0lKSPknhJqHYdYa24dVd0XofeUkONuxXUccnyqqzkItA0pozlwqBUhIASEQC0CImVoRQgBISAEhIAQEAJCQAgIASEgBLovAu5vQhwfpFLAkATHCWzNdeIiHe4qXDz44IMd0lT885//jCJVXbMpFZLqTJoB0qR89NFH8VekoHCdnjh6kdtPMyJqZ5999pqvfaed/ZLgKNI+kG7j448/jhz0fgQ4qQiyUjY0soroF/L/1lB7IMrbGmQK92+/LRydSVG6/m9+rsPBT10LLbRQlDYDx7fvuCQSGfx8w4FMumPXKMfa6dWrV4Td5ZdfXqMwgZMSZ+zUU0/dCESFrk1y4jNenHM4Lb/88kvz8MMPRyl4fMMJ7ab1CEnKcNcyWNx0001x80ikX3HFFYY5RsadlCasB59YARlqww03jK7jemT9MST5baogxrrqqquaW265JSI3MG4clcyvTxigT7Rpzb+v+XyrrbaK6iGA7+23347UDlyjflKz+OYTC+z3kEaI3J5tttnMK6+8YsaMGVNzKW25qgZV3ReFFlOJQuwNScQj9ifmk7VPVDmpL3zSy/HHHx+lRLCWhh2R/qSXmnXWWaO0KCgUuXX52Nn6IColKaegIsTawFgLV199dc2I2QMhK/lGm9wbvtOafQCHP/2DtHXPPfd0KOM+Y6i3DCmDPQmyoDUUjPyUQGn7O+sclRCcrLTJvQ4ZyjXUxFH18c0nKPI9zx4ITN9++22UjsdPj5SkHmXrDfFstHUl7e98BwGHvYz9/corr+yQSszf32+++Wbz888/x0OH7IDT3RoEnDQVCPYG1leV+7tL0LTqQvSNNFx+2i6r7MC8uGoX7npGJczOGemnRo0aFY/V7sd8wJqBCMQ9hAKOS2gkNRpELGsQFnk+Qoxxjfco997KU8oIORc87yyBxfaJde6Og79dUpjbdwLGeffzLfSeEmodd+hogx+EnAu3K6H3lAaHWXN5K67jkONTXc1BQKSM5uCsVoSAEGhTBETKaNOJU7eFgBAQAkJACAgBISAEhIAQEAIBEFhjjTVi8gHOh2uvvTaq1f+tiGMdZzaG9LbrxPejldO6hVKrq6iRl77Er4foYzc/OuSALKJCUj+SnHb0A4e161RCxRYno+v0xMlTRJ48wLREKro4c63RLu2XNX8eiQgnJQxOcddwCkOusYa0+y677FJTBgcfzkg3Jz3477nnnjWquzilcIa59Z188slmm222Kdv9UuWTlB5wEuO488cLAQZFCTu/SQ7okKQMdyCsNdeZh5NxmmmmiYgWffv2jYvibKTv1sDaJ8TwHfeEq0JBfdzLo0ePron894lWbgoTCBe+8w1ywIABA2rmAKIVqh6uQ95XP+CCJGIBa4x15Sob+Pc019JGWrqbUPdFqYWVUxhyDJi46jGQAFCIgTjg2ueff25w+lqHMCQc5tXde5KwS1Lq8dPmpGHHnn7ggQfG3YCIAXHKXWt86c8FewVqA37KHtJa+amBku4fnPyMzTqk2U8h9UDasFaGlOGvX0hE4Oda0v7OvQCJ0CfUsSdZEiJ18IzDge2uTz/FF+X8ufjxxx8jtQZ3fwY7SDhpzm5/SdX7bPT3d+595tsll+FAhzzlrs+k/d3tk5/uHvySnPMh76OsuiAuuQQuUj/06NEjwh0CiWtWvYc+s0aspaVYee6552rInWDIuvTHzHySmsoapJyslFO2nK/mkUfK8HEIPRe+Ugt70QwzzFBqKkPvKVWt41KDKlA4xFw0a08pMJxSRVptHZfqvAo3HQGRMpoOuRoUAkKgnRAQKaOdZkt9FQJCQAgIASEgBISAEBACQkAIhEUApxYRzZglXuBUX2SRRaLPcGhZxQwOk5FkJ1rbpodwyRp5PavX8WTrrYqU4Ssk2Pb8dATNTMMRyvns/+b3o/LtWO++++5IKcQakdbHHXdczZT6TmAID0RhJznQfSc/jujhw4fnLZGGvvdVMnCukZIgLT00agPMMQ7KhRdeuEPbzSJl0DAEirXXXrumD0TUo1RhzU0h5Bb0SRl8x1yRoto1HOJuipYLLrgginDHWNs4nKxlpeuBzHHAAQfEZamXPcE1n1jAXDz55JOJSjMuMYw6IAK4jnu33lD3RUMLzbs4KUVAmtIMlxK9jjMZUpDFPwu7rNQaXG9VUtKw8wlXWWlOSNvgRvUnpafx9xQIH/vtt18ipBAz2HNQ0UF1wE+HUpSUAWGJ611L6lsSKcNPM2Hr+OGHHyLSjEu8u/HGG80SSywRN+On6kJtxz4v3b5AtnGv4zuIL4MGDSq01Op9NvpzkUbcgkQJmdJa0v7udjSE87nQwAsWgpDBOrJmVX7su4j7nsL6XW655YxPumE/9ZWzqM8nZfAZz8IjjzyypneQW+abb774MzdVStYwWs2ZHYKUUfWeEmodF1xehYuFuC+atacUHlTBgq22jgt2W8U6CQGRMjoJeDUrBIRAeyBA5IX9AdKzZ09Djj2ZEBACQkAICIFmI4B8MYesaUYklx/NlVQ2rx6edRxe5VmSpLV7TbPrCTWuvHpC4Ay+4CMTAkJACAiB9kDAT1mAlLfrZCSq0zrTbZqS/v37x5HyKCdcfPHFhQZbr+PJVl4FKQOH5/jx4xP77zv50wgNhQZfslAo57PvtEtKNUPXfMcyBAGIAq7h3HSdr3nR025kOwSOq666qiQK5YpDIhk7dmx8UZpjp2itzSJlQFggip3Ib9e4X4YOHRp/tO6665rBgwd36L5Pyki7JyHeuGmHDjrooFjJAazc+UFJJO197vvvv49S31jDkU8qDNd8UgZKEn6aAVveTU3AZ2kkKb4LdV8UXQNFyvkO76IR9Gl1+9iRQsQl07jXoUjjKjQkYYdChU1XkKe4A4nJTeHhqwugkML+b421C4mG/9ZjRUgZ7PusL5c8kbaefFKGm+oiqX+kGYGcZM0lKvGZn2YgKy2JT2hJS4eS1I96n43+/k7KkXnnnbdDE0X2d/eiEM7netZD2jV+KhLShEActeNn/7KkMqvawv7G+rUGUZBUK74lkTJ8co69BmILKWswUuEUIRq2mjM7BCkj5J4CllWt45BrkLpC3BfN2lNCj73V1nHo8am+sAiIlBEWT9UmBISAEBACQkAICIGWQWDChAmGf/VaUp5sty4c2HfddVdm9RxWIgea5YQmGsk9EEiqcK655ooiprKIBxxkJpEFXEc7P2iRRM6q59hjjzUXXXRR7rioJwsj/6AjrcKkyD+3LFFieSQIyqflNbZ1kes2b74oixQ3EZFpVnRcSZK5bp0DBw4stD7z6ikyX7SbltPb9qloPXn9KTpfefPuS98nzQf3Vd46LDIu7gfqySLkcH9xX6SRgyxhhbWTVQ/OoLx1SLQg93tWPaH2De6tvPuryD5WZD8Eo7XWWitzPyy6b+ftz8wTfUqzvOvrfW7oOiHQFRHwI+Rx3jzyyCOG5yqGw9FG8I8bNy56N3CjRZMiStNwqtfxZOurgpThpmzx+020Owfo1nD6E2HcDAvlfPadHa+//npNSgs7ln//+99m1VVXjYeWRMrwlRZ41vtqDC42vLvh5MWyyC+h8PSjd5PSb5Rpq1mkjI033ticddZZZbpWU9YnZZRxBtuK/Pc71DCybPvtt4+d5Kh5nHLKKTXFfWIBZB43hYZb2E9BYB2uSe2Hui/qBjvhQn8PzVKOKNKujx34uMokZbAj5dD8888fX4IyhK8A4NbHHu0Sr3g/hgBhzVfLWXbZZQ3vrPWaT8pAfeD88883r732mnnhhRcixRc37YZtxyol+O36pAzGC5kszXxHo5/Ww78v0lQ3qN9PlzFkyJCa50cWRvU+G/39HdySUqYU2d/d/oVwPte7JpKu89cdKiQQjGx6IIihzB2ptQg25Pc85CL7/ElTOKGtpPQlqCilpVAqO65Wc2Y3SsoIvaeAZ1XruOxc5ZUPcV80a0/JG0vZ71ttHZftv8o3FwGRMpqLt1oTAkJACAgBISAEhEClCOAYILdyljOuaAfynMbk8c5Sb7Dt5Dmxi9aTRzogGqOI5fWHSMWJEyfmVpVXjy+Xm1ZhXj1F+5OHT6uRMoqOKw+foiSRPFJG0XrySCuhxlW0nrx5L1pPHs5F13PWwTj3AAeEX3/9de79lVdP0fs9r56i+09ePaFIRkT5Ftm/8+araH9wKlJXEaWd3ElTASHQRRHw1Q/Im060NaoQRBnjnJhnnnmi0Y8YMcKQamCZZZaJ0SijHlGv48k2VgUpI4l8YNvriqQMlFCSrIjTjpQWjThg09oOdWu5Ci7U+fDDD0cpeeq1ZpEyUIpwFTHK9tcnZeCgRC2jjPnYlbk2SZnDJxZkEZranZThKyT4RIYyWFI2JHbvvPOOQbmjXjviiCNigh51+Klrkgg5ZdrySRlFrs36De+TMrL2d9qCgOiqz/B7kjFb8+8LyhNMkWSQifbee+/4qw022MCce+65RYZk6n02Fk1JXWR/dzsawvlcaOAFC3F2wW8+a5wHQQ7dcMMNo4/uvffeKF0JxHhSmkAghGTIuDGICH/9618TW/NJGXlqMgW7HBdrNWd2o6SM0HsKQFW1jsvOVV75EPdFs/aUvLGU/b7V1nHZ/qt8cxEQKaO5eKs1ISAEhIAQEAJCQAhUikDRKP0incjK9cv1RZz8c845Z5R3tx6FC7ePXE8EVFY9aZHzfroIcsNnKXcQWUQO3izjeqRys+oh4h2STBZxhb75+bH9dpsVOW/bLRJBX0RZIC8NSl4kP/0JlQaFukKMq0g9efOF8451XGTe89aPrSdrHeLgp55G13PefcG46Qf3aaPKOLaeRhU3GHOecgeOAdQ7sogi7GOjRo1qijJOkX2VceWRMoqScagrj4BX5HmhMkKgKyPA/sf7lbWbbropUvgidYeNgraH+DiPcXist956cXkiVgcNGlQIonodT7ZykTJuLYSzWyiks6MRUkZeGoHSA0u4wHd23HPPPYYI6XqtKCnjySefjN6brW233XYRgSnNUO864YQT4q9JEYSCWL3mkzKyovnT2miElJHk8AxJLHD73IpKGf59wdyzBuq1kNg16kBlnaKKYo3fo4zXmnWA1zvWsqSMPJJFWVLG008/bUizZO1Pf/pTTUoK/77gN3SfPn0Sh+unsYGIjOpHEav32Rhyf3f7GcL5XGTcRcv46gwQZ5gH0vdgb7zxRvRbBrwtqcIluJP+BvJUkvmkjFVWWaUmzVPRPqaVazVndmeTMvw9BdyqWseNzp1/fYj7oll7Suixt9o6Dj0+1RcWAZEywuKp2oSAEBACQkAICAEh0KkI4DjAyYgDGscmuUTrMZ/IUE8dukYICAEhIATKI+CmXEq62qaKyas5jTz15ZdfxmockGkgrmQRafLa0fdCoKsj4DvtkGAfM2ZMpDJgncvIgZNjHYcYn7kpPNJy2CfhVq/jydYlUkbnkjKINCYa2docc8xhZp111kK3COlLUHCo0nCosm6t1aMY4favKCnDd8aWJWXkqYLlYeaTMh588MFY3SbvWvu9j93iiy9e9FKz+uqr16S84MKQxAK3I61IykANYeTIkXE3G1U+CYndf//735p0U3SyzNyy96OOZM0nMTSqKlCWlEE/sshWZUkZ/r0L4WTfffeNxwthgzFb4zm4xBJLJN4bEBRdlY0999zTDBs2rNB9VO+zsSpndgjnc6GBlyjkOrNRJOHdnucRzyF+E7j3zUsvvRSRM6yRXglVlyTzSRl56pMluhwVbTVndqOkjNB7ChhVtY7LzlVe+RD3RbP2lLyxlP2+1dZx2f6rfHMRECmjuXirNSEgBISAEBACQkAICAEhIASEgBAQAm2BAM4dFAE4gBVxoy2mTJ2sAIFvv/3W/P73v49rxkF82mmnmQ8//NDYCP4zzzwzikL93e9+F0WmupHSb775ppl66qkL9axex5Ot3JeaR52A/paxMk67zkxf8t1335mFF144HhqkhvHjx5cZalQ2pLPDd2AeeuihcaRy6Y5VcAEqS5CKrDXqHPdJGaydKaecskPPUZU58sgj48/LkjIaTXfhkzLqSdtCehGUtayRpmKppZaqe5ZCEgvcToS6L+oeWMKFftoKnME333yzmXzyyetqJjR2kCrYp629+uqrZrrppqurb5988klN+ioqeeaZZ0zv3r3rqs8nZeBg57kzxRRTGPa86aefPlKhoZw1gjPAaLLJJuvQZpn9nYsvueSSiLxrzb8XfRWUrHvV33+SFAHSQKr32Rhyf3f7xvOe5761RoljdS0O76JNNtnEPPvss9GnrAnuL57RVtnCVf2y7/a2iiyFVJ+U0WhKHn+sjTqzQ8+FTwqoh8QXck8Br6rWcYh1F/q+aNaeEnrsrbaOQ49P9YVFQKSMsHiqNiEgBISAEBACQkAIVIYAh4FIovKjPy/1QWWdUMVCQAgIASHQbRCw6VQ4DOTAVsSMbjP1GqiHgHsgTpomHE8YaRbWWmutSCWDiGnsoIMOikgbmI1QLQpovY4nW//bb78dOWCsQSa54447ijYflSvjtOtMUgZ99WWun3/+eTPjjDOWGm9IZ8frr78erQdrOE3Bv6haRqmO11HYJ0dQRT0OJ9s0qRnA3BqkoLnmmqtDz3xSRDuSMq644orIGW6N+wySRhIJpcjUhCYWuG2GuC+KjKFoGUgO66yzTk1xHNo4keux0NgNGTLE3HLLLXFXfDWIMn389ddfO6iwbLvttoYI8nrMJ2Uk7elXXnmlGTp0aCF8/f09T8nDv8fBfsCAAXFblpBoP1h66aXNtdde22GojGOZZZapIY9AEHOfV1n41PtsDLm/u/0jPaub7qOM6kc966DINSiYkF4NW3nllQ0ELVJH7bbbbhEp7oMPPojn7rDDDqtZk1lpZ1qdlBF6LnjHg3Rn7aKLLorUjspYyD2Fdqtax2XGVKRsiLlo1p5SZDxlyjRKygiBXZn+qmznIiBSRufir9aFgBAQAkJACAgBIVAIAZcxHloyslAHVEgICAEhIAS6HQLHHnus4TASg5CBA5aDQZkQ6G4IuHLWqAPYFBB33XWXWWihhYzrtMDJRMoSrGzu9XodT3Y+fvzxR7PAAgvUTA8pNeh/UWsnUsbWW28dybJbI20MJOYyFtLZgWz5BhtsYHBCW2M+IEP06dOnTLcqKfvuu++aQYMG1dSNUxYnyPzzz1+6Td95hVPQVYmhQj+dA5+1IynDdWhaoDbddFNz4okn1qWqEJpY4E5eiPui9GLIuID7AlKGq0bxm9/8xpxzzjlmtdVWK91UaOx8hRs6xD5CyhoUKcoa5B1IPK7x2S677FKaxFOElJG070AI4znkk2n9/Z0+Qhxz1aBsv/10WHzOs26mmWaKh+Y77PnCV8v45ZdfDO+TqG5YY/4hAvTq1asQvPU+G0Pu725HXdUJ+3k9CjyFBl+wkJs6gvl87733IhLM8OHDo7X8888/R2pemPuewt///ve/U9d6q5MyQs/FWWedFRNrwQYsIbsUVTzjmtB7SlXruODSKlwsxFw0a08pPKiCBRslZYTArmBXVawFEBApowUmQV0QAkJACAgBISAEhEAaAkjHE6lsD5z5UQiLWtHKWjNCQAgIASHQDAR8YobUmpqButpoNQT22GOP6JDdt9dee81MO+205vPPPzdLLLFEh+933XVXg2S7bzjtXbl5+z1KF65Te/HFF0+8ns+nmmqqRJhwfrqkAAohZY7zc7bZZoskzb/88kuDzD7m55FvJ1IGDvELLrigBodll102cvqjUkIKgq+//joa60cffWSYD9+xEtrZ8eKLL0bEDN+YA6Jt6VePHj0Mjsr//Oc/hjmnT0TTN8NwhJ9yyikdmtppp50MBI155503cs4RZc26njhxYoSdTZngXnjuueeakSNH1tTFOKwqAlL6Z5xxRoe2aGf77bePFAWYL9oBB2soz0BksbbPPvuYVVddNf4bNZQsEsk777xjJk2aFJcnTYKV9edDMGAerKHuwb2RZ0T2+/czzmXW1ZJLLhk5q0knAXakN8LRudhii5mBAwd2qDo0scBtIMR9kYdF2e+J2Oce8A31xxVXXNHMN998MXbcs+A3YcIEs80228SOZHttFdgl7fFzzz13pDJA3/jtzV7/zTffRM5u1itpDpKUYb744guzwgordNjjWfcbb7xxVN8ss8xifvjhh6gM9xf3GWvIJ6kUIWWASxK+KNQcc8wxNZAnkTJYwyg9cY+RZoV96aGHHjLHH398zbV77723QWHBtyTsaJv0PiiHkKoGAqNr1EN9voV+Nobe321/2V+S0hftv//+ZtFFF43mF7LMZ599Fq1lyBCs8yotSQmJ9saNGxe3nfR+AHHwnnvuibsGufOFF16I/37jjTdqlFggdEDAs8bzgrWbZRBC3D3YLXvDDTeYyy+/PP6IZ4OvosMzE1yTLPRc3HvvvRGByjWeF6Sm45nFPk9aO+4TyHo813luFrkv6t1TqlrHoddjqLkIuaeEHGM7reOQ41Zd4REQKSM8pqpRCAgBISAEhIAQEALBEFh33XXNK6+8EtUnQkYwWFWREBACQkAIlECA1FnWUSzFjBLAqWiXQQDn1JgxY2rGQyTy+PHj48/8Q3O+4LoddtihAw6+JHxZoHDApTmRk6Lt0ur3x0C5diJl4PDC0ZVEcEkac1KqjiqcHSNGjDDnn39+4WnFYXf//fcXLt9IQRzBOOYgDJQx1pVLZOBanFIox+Thz3q3svp+m6R8wWHrOvny+gXpBUJImiUpFWTVCYlh8ODBec1GTtbNNtusJmVL3kWQXSA3+lYFscC2EeK+yBtXPd+T7oHggjJ29tlnG9aPa1VgBzFiueWWK9O16B7nt3qSkf4AJZkyhpoBqgauFSVlcA3ECghNrt12221mkUUWiT9KImUU7eNTTz2VmIoJp/2aa65ZtBrDc4dUR5DmfAv9bKxif7d99tMsZAHQDKXTJHUG+uQqePhpNfgeYtTo0aPj7kMiWX755QvPJ6Qee16VdpG/jgtX/r8F856RIecCIhFkMFeFK6u/kNWTCGch95Qq13HZucgrH2IuQu4pef0t8307reMy41LZ5iMgUkbzMVeLQkAICAEhIASEgBAohIAbndyMH/KFOqVCQkAICAEh0C0RcB29HA6SykSqTd1yKXTLQV944YWGaHvXyNnuRvMTNU2qBteIrCeq1LfQjie//qOPPrpGKj5r0nCKTzPNNHGRdiJl0GmisFFSKGJXXnllB9WCKpwdOO9xHOPszyMs2H6D+5RTTllkGA2XIZoV5y+O46JG2aTI8Kuuuioxet7WiwMWYl9amop2ImUwJlQMcTr5JK00HP19wpargljg9qHR+6LouihTjgh89lJfXSWrjkMPPTSKUHetKuxQWGHvtOmn8sY2dOhQs9dee6UWIy3IsGHDIvJSEYPg5Kc9KUPKSEqxg6oSsvo2DYu/v6+xxhoGByjqH2mG0x2nfZbSw2OPPRbtw3ljJciElFo2jUbVz8Yq9nfb5++//z5Smnr++edzp3fppZc21157bW65RgrQD5/ARH3us2XUqFHR/uWar4DSjqSM0HMBZhtuuGGh5zfqKGkErFB7SpXruJE1l3RtqLkItaeEHF/VpIxQ2IUcs+qqBgGRMqrBVbUKASEgBISAEBACQqAhBNyoZA4vONSRCQEhIASEgBDoTATIE26l6IkKIzpMJgS6AwJJDk5fGv6QQw6JyEqu3XfffZFUvW+keODAuV6BstlwAAAgAElEQVTLUsqwddL2eeedF8naZxkRy64Ev++023TTTRNTUFAnUdlEZ1vD2br11lvXO6y6r3vzzTcN+xPO1CwSBM4oXxbddXZkRfySXoCUBNaycLFlcFDSJpHKWcoUtEsZCAzNNNYg/SPlShZu9A9HahLBiP5C2kMFwXfsEm2NagiS70ny7lwLKYOxkyaiqOUpZUCgwvlf1IoqZbj1kWaBNQcRK8sRjaw/8vy++cSCrHsH5z+EImuoqqQ5td12GrkvimJXTzkclaTQefzxx3Od+Dg7cXq6VjV2KLeQFiktlYbtC6oD7PtZRrqTs846y9x999256jTcL/4zBGWbBRdcMG4iz7mflFKIe2GttdaK6kgi3R133HHRfLCu/LXMPc/9Meecc+ZONWQv6iIVhr+foLJD6pYDDzwwSt+UZqGfjVXu74yBNFS33nqrgeyQtccz/qLKC7lApxRIUmbwFSYg6Pj308knnxwpQ1hDaScvHYnbhSJKGf46LjvGPKWMKuaCNETcu+zfWXs8a/akk07KHFKje0rV67jsfOSVD3VfhNhT8vpa5vt2XMdlxqeyzUNApIzmYa2WhIAQEAJCQAgIASFQCAHy5yKFSiTWDDPMEBEy+vbtW+haFRICQkAICAEhUCUCOFztwfKjjz6q51OVYKtuIRAAge+++8689dZb0XvlZJNNZpDmRjZ+5plnNn369DFTTTVVgFZaowryfeN0xKmEUwDFCsbaq1evaKw4jzrL6Avv+J9++mnksESdhPd8+kWO+s42MHv33XcN6wXscJyCXZn+4bjC4c4am3XWWc3cc88dD4u6WWtTTz11zX+bpQ5SJb7ffvtthN2XX35pUINgbplTHNlJKRqq7EtS3a18X3AvQObBAfrTTz9F6w78Zp99djPLLLOYySefvNlw1bT3+eefR3PLHHNfTDvttKZ379517Z3sAYwVRyP1MU7G28y9OE8JCfIZZB7u3X79+sUKG2UngX2OsTJ/EBO7g7IaDluIEShNsAfyvGW9kGqMtWzVSspiqfLlEQg9Fzy7mVfuYbtPTT/99KWej3YUIfeU8sg0/4pQc6E9RXtK81dvdS2KlFEdtqpZCAgBISAEhIAQEAJ1IUBOTpuflmiZMjk962pQFwkBISAEhIAQKIgAjt3dd9/dELWFzLdMCAgBISAEhIAQEAJCoPURyCNltP4I1EMhIASEgBAQAu2NgEgZ7T1/6r0QEAJCQAgIASHQRRG48847o6g+ETK66ARrWEJACAgBISAEhIAQEAJCQAgIASEgBJqEgEgZTQJazQgBISAEhIAQSEFApAwtDSEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAh0UQREyuiiE6thCQEhIASEQNsgIFJG20yVOioEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAiBcgiIlFEOL5UWAkJACAgBIRAaAZEyQiOq+oSAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASHQIgiIlNEiE6FuCAEhIASEQLdFQKSMbjv1GrgQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBIdDVERApo6vPsMYnBISAEBACrY6ASBmtPkPqnxAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIATqRGDSpEnm/PPPj69ebLHFzEYbbVRnbbpMCAgBISAEhIAQKIuASBllEVN5ISAEhIAQEAJCQAgIASEgBISAEBACQiBC4KuvvjJ33XWXWWuttUzPnj2FihAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAh4BIGVoSQkAICAEhIASEgBBoAQTGjh0bObUOOOAAs/zyy7dAj9QFISAEhIAQEAL5CGy99dbmiSeeMFtssYU57bTT8i9QCSEgBISAEBACQkAICAEhIASEgBAQAkJACHQzBETK6GYTruEKASEgBISAEBACrYnAoosuGkUb77///hExQyYEhIAQEAJCoB0Q2H333SNSYd++fc2jjz7aDl1WH4WAEBACQkAICAEhIASEgBAQAkJACAgBIdBUBETKaCrcakwICAEhIASEgBAQAskI9OvXL/pCpAytECEgBISAEGgnBE4//XRzxhlnRF1+991326nr6qsQEAJCQAgIASEgBISAEBACQkAICAEhIASagoBIGU2BWY0IASEgBISAEBACQiAdgVdeecWsu+66UYHRo0ebtddeW3AJASEgBISAEGgLBO68806zxx57RH39+9//rhRcbTFr6qQQEAJCQAgIASEgBISAEBACQkAICAEh0EwERMpoJtpqSwgIASEgBISAEBACCQg88cQTZuutt5ZDS6tDCAgBISAE2g4Bl1h46qmnmi233LLtxqAOCwEhIASEgBAQAkJACAgBISAEhIAQEAJCoEoERMqoEl3VLQSEgBAQAkJACAiBAgi40u8vvvii6dmzZ4GrVEQICAEhIASEQGsgoBRcrTEP6oUQEAJCQAgIASEgBISAEBACQkAICAEh0JoIiJTRmvOiXgkBISAEhIAQEALdCAGXlPHuu+92o5FrqEJACAgBIdAVEBApoyvMosYgBISAEBACQkAICAEhIASEgBAQAkJACFSFgEgZVSGreoWAEBACQkAICAEhUBABkTIKAqViQkAICAEh0JIIrLDCCmbixIlmrbXWMhdeeGFL9lGdEgJCQAj8f+zdCZydZX0v8P+smclkJjtbAgFckIS0boUoLlQtAa3X2hLjVmuhcN1qScFq1QqJXayC0GulFgptXWpDaN2qCHZxQ1N79UqBUEEgkAlbIJCZLJPMcu7nec55h5OQZZLMSWbmfN/7mc7MOe/7vM/zfd5M+7nnx/9PgAABAgQIECBAgAABAodLQCjjcMm7LwECBAgQIECgIiCU4VEgQIAAgfEssHTp0li9enUsWrQoVq5cOZ6XYu4ECBAgQIAAAQIECBAgQIAAgVEXEMoYdVIDEiBAgAABAgT2T0AoY/+8DvnZQ0MRpVJE8b365+K1hoaI4quxsfzzrt/Taw4CBAhMQAGhjAm4qZZEgAABAgQIECBAgAABAgQIjJqAUMaoURqIAAECBAgQIHBgAqtWrYqLL744X3z//fcf2CAT9Kru7u5IX+lYs2ZNzJ8/f7crnTt3bqSv4SMFJwYGIvr7y1+7+3lw8Kmgxd4CF6Npu7ugxq6vNTdHVH319PXFmnvuiWhqKr+evqdrRnD09PRkt+JIfl1dXfm/ZncQIEBgtASWL18e1113nf89NlqgxiFAgAABAgQIECBAgAABAgQmlIBQxoTaToshQIAAAQIExqNA+uA8VctIH5QvXrx4PC5hVOecPG644YZIYZXqQMFo3qSroyPmH3/8aA454rF6tmyJNWvXjvj8WpyYghkvetGL4iMf+cjOYZZa3MyYBAhMeAEVnyb8FlsgAQIECBAgQIAAAQIECBAgcBACQhkHgedSAgQIECBAgACB0RW46aabctWQFMzY3TFn9uw4dvbs/Na6DRti/YYNozuBcTpa5+TJsWA3IZPVVVUy9rS08847L4czHAQIEDhQgfS3+4ILLsiXr1y5UjWeA4V0HQECBAgQIECAAAECBAgQIDAhBYQyJuS2WhQBAgQIECBAYPwJrFi+PK6tlL9Ps09BgyVnnBGLFiyIFy1YEKm6xUiOVIUiVaPY17HpACtWpAobU0c4l33NYU/vpzWP1pE8fnjHHbH67rvjh7feGr2bNz9t6CVLlsRll102Wrc0DgECdSawevXqWLp0aV61UEadbb7lEiBAgAABAgQIECBAgAABAvsUEMrYJ5ETCBAgQIAAAQIEai1wxZ//eVx51VX5NimMcd5rXpO/RhrEqPX8JtL4ax5/PFZ973ux6qtfjd7e3uGlXXjhhbFs2bKJtFRrIUDgEAmk6kYLFy7Md0uVd1IFHgcBAgQIECBAgAABAgQIECBAgEBZQCjDk0CAAAECBAgQIHBYBdZ873tx9lvfmudw8vHHx/WXXiqMcSh2ZNq0WPXDH8byT3xiOJxx4403xvz58w/F3d2DAIEJJjBv3ry8IgGvCbaxlkOAAAECBAgQIECAAAECBAgctIBQxkETGoAAAQIECBAgQOBABXoefjiXvE8tNs4544y45O1vF8g4UMwDvK5nxox4w3veE3feeWcsWrQotx5wECBAYH8FTjnllBzwOuecc+Lyyy/f38udT4AAAQIECBAgQIAAAQIECBCYsAJCGRN2ay2MAAECBAgQIDD2BS56xzvihhtvjDmzZ8c3P/EJgYzDtGXdra1x+utel++eQhkpnOEgQIDA/gikgN3q1auFMvYHzbkECBAgQIAAAQIECBAgQIBAXQgIZdTFNlskAQIECBAgQGDsCXQ/8ECc/tKX5old9u53x5Izzhh7k6yXGbW0xNI//dNY/aMfxZlnnhnXXHNNvazcOgkQGCWBFMhYtWpVnHfeedogjZKpYQgQIECAAAECBAgQIECAAIGJISCUMTH20SoIECBAgACBcS5wxRVX5P/COJV8nzt37jhfzcimf9F73xs3fOUr0Tl5cvzgqqtUyRgZW83Ouva7340Vn/pUHv/++++v2X0MTIAAAQIECBAgQIAAAQIECBAgQIAAgXoSEMqop922VgIECBAgQGDMCsybNy/P7cILL4xly5aN2XmO5sROf9GLovvBB2PR/Pmxcvny0RzaWAcgsPquu2Lphz6Ur7zxxhv9l+4HYOgSAgQIECBAgAABAgQIECBAgAABAgQI7CoglOGZIECAAAECBAiMAYF6DGUMr3nJklj2hjeMgV2o7yn0bNkSC9/+9oywcuXKWLRoUX2DWD0BAgQIECBAgAABAgQIECBAgAABAgRGQUAoYxQQDUGAAAECBAgQOFiBegtlrFmzJs4+++zMdvX73heLTz31YAldPwoC85YsyaMIZYwCpiEIECBAgAABAgQIECBAgAABAgQIECAQEUIZHgMCBAgQIECAwBgQWLp0aaxevTpXJ0gfiE/0o6enJxYuXJiXufLSS2PRggUTfcnjYn1CGeNim0ySAAECBAgQIECAAAECBAgQIECAAIFxJCCUMY42y1QJECBAgACBiStQb6GMtJNFdRChjLHzXJ/1vvfFnWvXqpQxdrbETAgQIECAAAECBAgQIECAAAECBAgQGOcCQhnjfANNnwABAgQIEJgYAvUcyrh/1aqJsYkTYBVLL7kkVq9ZI5QxAfbSEggQIECAAAECBAgQIECAAAECBAgQGBsCQhljYx/MggABAgQIEKhzAaGMOn8AxsjyhTLGyEaY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AgQIECAwPgXqPZSRdu2iiy6KG264IW9gV1dXXLNiRSyaM2d8bugYn3WqjnHdN74R137965F+Lo5UoSVVanEQIEBgfwVuuummuPjii3Owa9myZft7ufMJECBAgAABAgQIECBAgAABAhNaQChjQm+vxREgQIAAAQLjQaC6UsRtt92WQwn1eKxatSqWL18evb29efnzTzoplrzkJXHmC16gpckoPBBr1q6NG7797dyqpDqMkYY++eST4/rrr6/bZ28UeA1BoK4FUguuFDAU7qrrx8DiCRAgQIAAAQIECBAgQIAAgT0ICGV4NAgQIECAAAECh1mgOpRx//33H+bZHN7b9/T0xLXXXpu/inBGmtH8E0+MBccdF4sWLCgHNBoa9jjR1XfccUgWkeYx94gjDsm9DugmpVKkFiXJ44d33JF/3t1x5plnxuWXXy6QcUDILiJAIAkIZXgOCBAgQIAAAQIECBAgQIAAAQJ7FhDK8HQQIECAAAECBA6zgPYlT9+A7u7uSGGVVBK/OpxxmLdqQt1+zpw5uc3AkiVLJtS6LIYAgUMvIJRx6M3dkQABAgQIECBAgAABAgQIEBg/AkIZ42evzJQAAQIECBCYoALVoYyrr746Fi9ePEFXemDLSsGMNWvW5K9USWPdunWxfv36AxusRlfNmT07jt21gkelmscd990XvVu21OjO+zdsai0wf/783GLAc7Z/ds4mQGDPAkIZng4CBAgQIECAAAECBAgQIECAwJ4FhDI8HQQIECBAgACBMSAwb968PIsLL7wwVy9w1J9ACucc6JFCFg4CBAgcLoGzzz47B+dSO6RrrrnmcE3DfQkQIECAAAECBAgQIECAAAECY1JAKGNMbotJESBAgAABAvUm8OIXvzhXf/CBVr3tvPUSIEBg/AsIFo7/PbQCAgQIECBAgAABAgQIECBAoHYCQhm1szUyAQIECBAgQGDEAueff37cfPPNMXfu3LjllltGfJ0TCRAgQIDA4RRIbaUWLlyYp6Da0+HcCfcmQIAAAQIECBAgQIAAAQIExqqAUMZY3RnzIkCAAAECBOpK4Iorrogrr7wyr/m2226Lrq6uulq/xRIgQIDA+BRIrZeWLl2aJ79y5crQTml87qNZEyBAgAABAgQIECBAgAABArUTEMqona2RCRAgQIAAAQIjFvCh1oipnEiAAAECY0hg1apVcfHFF+cZ3XjjjTF//vwxNDtTIUCAAAECBAgQIECAAAECBAgcfgGhjMO/B2ZAgAABAgQIEMgCqVpGOpYtW0aEAAECBAiMC4Frr702VqxYEZ2dnXH77bePizmbJAECBAgQIECAAAECBAgQIEDgUAoIZRxKbfciQIAAAQIECBAgQIAAAQITSKCnpydStYy5c+fG4sWLJ9DKLIUAAQIECBAgQIAAAQIECBAgMDoCQhmj42gUAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgMBOAkIZHggCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAQA0EhDJqgGpIAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgIBQhmeAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFADAaGMGqAakgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAglOEZIECAAAECBAiMQYGenp5YsWJFnHbaabFkyZIxOENTIkCAAAECBAgQIECAAAECBAgQIECAAAECBPYlIJSxLyHvEyBAgAABAgQOg8AVV1wRV155Zb7zypUrY9GiRYdhFm5JgAABAgSeLrBq1ar41re+FZdddll0dXUhIkCAAAECBAgQIECAAAECBAgQ2IuAUIbHgwABAgQIECAwBgW6u7vjrLPOit7e3vyB14033hhz584dgzM1JQIECBCoJ4GbbropLrjggrzkj3zkI3HeeefV0/KtlQABAgQIECBAgJCdI34AACAASURBVAABAgQIECCw3wJCGftN5gICBAgQIECAwKERSP8l8sUXX5xvNn/+/BzMcBAgQIAAgcMlkAKDZ599dqQWW52dnfHNb35TYPBwbYb7EiBAgAABAgQIECBAgAABAuNGQChj3GyViRIgQIAAAQL1KLB8+fK47rrr8tJTMCO1MlEqvh6fBGsmQIDA4RVIQYylS5fGmjVr8kSuvvrqWLx48eGdlLsTIECAAAECBAgQIECAAAECBMaBgFDGONgkUyRAgAABAgTqWyC1MbnzzjszQgpmXHPNNf7L5Pp+JKyeAAECh1Rg10DGhRdeGMuWLTukc3AzAgQIECBAgAABAgQIECBAgMB4FRDKGK87Z94ECBAgQIBAXQlcdNFFccMNN+Q1p0oZqZXJ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jQSEMmoEa1gCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgvgWEMup7/62eAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQqJGAUEaNYA1LgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQI1LeAUEZ977/VEyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAjUSEMqoEaxhCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgfoWEMqo7/23egIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKBGAkIZNYI1LAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIFDfAkIZ9b3/Vk+AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUSEAoo0awhiVAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTqW0Aoo7733+oJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBGgkIZdQI1rAECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAfQsIZdT3/ls9AQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUCMBoYwawRqWAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQqG8BoYz63n+rJ0CAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBGokIJRRI1jDEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAvUtIJRR3/tv9QQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgECNBIQyagRrWAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKC+BYQy6nv/rZ4AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBCokYBQRo1gDUuAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAjUt4BQRn3vv9UTIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECNRIQyqgRrGEJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB+hYQyqjv/bd6AgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoEYCQhk1gjUsAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUN8CQhn1vf9WT4AAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNRIQCijRrCGJUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBOpbQCijvvff6gkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIEaCQhl1AjWsAQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEB9Cwhl1Pf+Wz0BAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBQIwGhjBrBGpYAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBCobwGhjPref6snQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEaiQglFEjWMMSIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAEC9S0glFHf+2/1BAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAQI0EhDJqBGtYAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAoL4FhDLqe/+tngABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEKiRgFBGjWANS4AAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECNS3gFBGfe+/1RMgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQI1EhDKqBGsYQkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIH6FhDKqO/9t3oCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgRgJCGTWCNSwBAgQIECBAgMDIBLZuHoqhwVJMmdo0sgucRYAAAQIECBAgQIAAAQIECBAgQIAAAQIExomAUMY42SjTJECAAAECE1GgVIr48X/0xrOf2x5dM5on4hJruqbt24ZiS89gzDiyJQYHSvnnSe2N+Wu8HA8/sCNWnHd/tLQ2xOVffkY0tzSMl6mbJwECBAgQIECAAAECBAgQIECAAAECBAgQ2KeAUMY+iZxAgAABAgQIHKjAfWv64u7/3hov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AQJZ4INvvDdS9ZKXvGZqvPWiI6kQIECAAAECBAgQIECAAAECBAgQIECAAAECBykglHGQgC4nQIAAAQIECEwUgSsv7o7/+cnWaO9ojE9+9ZnR0DBRVmYdBAgQIECAAAECBAgQIECAAAECBAgQIEDg8AgIZRwed3clQIAAAQIECIw5ge985cn44l88muf1zo8eE794+pQxN0cTIkCAAAECBAgQIECAAAECBAgQIECAAAEC40lAKGM87Za5EiBAgAABAgRqKLB502Bc/Pp78h1e+IrO+J0PH13DuxmaAAECBAgQIECAAAECBAgQIECAAAECBAhMfAGhjIm/x1ZIgAABAgQIEBixwKc/uD5uW70lXvKaqfHWi44c8XVOJECAAAECBAgQIECAAAECBAgQIECAAAECBJ4uIJThqSBAgAABAgQIEBgWGBosxd23bYtn/cLkaGwEQ4AAAQIECBAgQIAAAQIECBAgQIAAAQIECByMgFDGwei5lgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECCwBwGhDI8GAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKAGAkIZNUA1JAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAKMMzQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBCogYBQRg1QDUmAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQEMrwDBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEaiAglFEDVEMSIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBIQyPAMECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgRoICGXUANWQBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAGhDM8AAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKAGAkIZNUA1JAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAKMMzQIAAAQIECBAYYwKlUikaGhoifR/tI43rIECAAAECBAgQIECAAAECBAgQIECAAAECBA6NgFDGoXF2FwIECBAgQIDAiAT2K5CRMhu7Zix2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IIAAAghkrAChjMyqlPH999/bOeecE3W/16lTx+bOnVtg3wPnnXeezZ8/P3L8b775xipWrFhg6+HACCCAAAIIIIAAAkVDgFBG0bhOrBIBBBBAAAEEEEAAAQQQQAABBBBAAIGMFiCUkVmhDN3sl156qX322WeR+/6OO+6w6667rsC+D/yhDAU0qlSpUmDr4cAIIIAAAggggAACRUOAUEbRuE6sEgEEEEAAAQQQQAABBBBAAAEEEEAAgYwWIJSReaGM9evX28svv2z/+9//rFWrVk7ljNKlSxfY9wGhjAKj58AIIIAAAggggECRFiCUUaQvH4tHAAEEEEAAAQQQQAABBBBAAAEEEEAgMwQIZWReKKOw3dmEMgrbFWE9CCCAAAIIIIBA0RAglFE0rhOrRAABBBBAAAEEEEAAAQQQQAABBBAoZAJbtmyxX375xcqWLWt16tSxkiVL5nqFu3fvtuXLl1u5cuWsdu3aVqJEiVzPVRR23Lt3r61atcq2bdtmNWrUsKysrKTnnCiUEea10JpWrFjhrGvfffcNhXPt2rWmP1WrVnX+JKv28P7771vHjh0jx7722mutf//0hDJ27doVuY+rVatmpUqVyvU579ixw1TdokKFCrbPPvvkep507bhnzx7nOmzYsMHq1q1rlSpVSulQhDJS4mJjBBBAAAEEEEAAgT8FCGVwKyCAAAIIIIAAAggggAACCCCAAAIIIBBH4PHHH7dJkyY5r1avXt2mTZtmH330kT344IP29ddfR+11yimn2N13322HHHJIIM9169bZY489Zl988UXUXHpQ3LRpU7vwwgvt73//e8ywx6uvvmoPP/xw5DjPPvusNWzY0Pn7sGHDnHW647XXXos8IH/yySftX//6V+S1oUOH2gknnBBovXnd6JtvvrFx48aZ/jt//vwc01188cV22WWX2cknnxzzULFCGb/99lso10JrGj16tM2bN88WLVoUOb6u+RFHHGHdunWLu65Yi9WDf82ne0StNxQa8Y4TTzzRLrnkErvooousTJkyOaZIJZShgItaeygQ4Y7//Oc/UYGSDz/80O64447I67oHFAzRPTR16tSo47do0cIUPlAoJEg46Oeff7YRI0Y49/HChQsjcymodOSRR9pVV12V1E4+bdq0SXqL3XjjjXb55Zcn3E72HTp0iHj069fPTj/9dHv00UftqaeeitpXa9T32HXXXZcjKPPDDz9Y586do7b/6aefov5+wAEHJFzLu+++m6eQS1IQNkAAAQQQQAABBBAoEgKEMorEZWKRCCCAAAIIIIAAAggggAACCCCAAAIFIeAPAijsoAfpiYaCHOeff37CbRTsuPnmm51P7Scaeniv4ES9evWiNnvhhRdMD5vd8dJLL0XCFXrI/MEHH0Ree+ONN+ywww5z/t67d2+bMmVK5LXZs2dbkyZN0kqryhMjR460J554ItBx2rVrZ4MHD7aKFStGbe+/Fvfee6/dddddCefUcS+44IK42yjQMHHiRBs4cGDStV199dWOuapAxBu///67/fvf/3bW5Q9ixNqnefPmpvvF/3A/lVDGkiVL7LTTTotMr1DPggULog734osvWt++fSNfU4hHxt4QhX99Co088MADVr58+bjnO2vWLOvZs2fSc1WY4tZbb41bIWTTpk12+OGHJ70Gd955p3Xv3j3hdj/++KOdeeaZkW10zb788kubOXNm3P2OPvpo0/eU99oqqBMkKJJoMQr45KXySFIQNkAAAQQQQAABBBAoEgKEMorEZWKRCCCAAAIIIIAAAggggAACCCCAAAIFIeAPAuhh79tvv51wKXooPmfOnLjtG/Tp+U6dOgU+nYMPPthmzJgR9UDbP4cqYLRt29aZU5UOVq5cGZlf1QHch8tXXHGFffzxx5HXvv3224Qhg8CLjLOh2rLo4b6/qkiyeRXMUBjFO/zXolGjRlFVLWLNmexaqFKEQhFBh66bwgzxhoIiY8eODTqds53OQ8EZbyAglVDG9OnTnUoP7lBAQ0ET7/CHMnSvaL9k469//WvcMI3/uMnmat++fVR1F+/26QxlBPme1Vpuu+02JyjlDkIZya4oryOAAAIIIIAAAggEFSCUEVSK7RBAAAEEEEAAAQQQQAABBBBAAAEEMk7AHwRwAVq3bm2qYqEH6W+99VaOT+GrIoX29Q+FFBSQ8FcouOmmm5yH8xpz5841Vb7wDgUUFFRwh/+BscIAajexffv2HO1T+vfvb9dee62z6xlnnBEJMqg1h1pOpHMoHKCWLt6hoITalChssmHDBqeqh87ZPxREURsXd8S7FrJTCxZdCwVmRo0aFTWVKjT06NEjx/xqu9GyZcuor6tihSqN1KpVyzZv3mxqA+Jf2zvvvBO5Vt6d1abk3HPPzXEctaFRC5SyZcs6rW/USsRfReOee+5x2ny4I5VQhipVqDqH10n3n3f4QxnuawrwKKhTs2ZN++WXX+yZZ55xqkp4h+7vxo0bR31N97HuJX87D9k1a9bMVqxYYTqmvxKMKmvEau+jCiMKpsjcOz777LOo74XcVMpw59P9fuWVVzpVSXSuqtzivw66hpUrV3Z20b2pa+0dQ4YMiQo86e/xKqfsu+++TtsUBgIIIIAAAggggAAChDK4BxBAAAEEEEAAAQQQQAABBBBAAAEEEIgjECsIMGLECLv44ouj9lCbB1WrcEerVq1iVkx4+eWXnTYO7lAQQ60k6tevHzWfwgWdO3eOfE0PlP/73/9GWiGsW7fO1HLBHb169XLaSKhdgh6We4celN93333Olxo0aBB5SaEStWxI11izZo3TVsP74FvHlJ9CD94xb94869ChQ2RbfwhF28a6FpMmTXIqg3jH6NGjTQ/Lk10LVUaYPHlyZDtVjxg2bJgpNOIOtTfR17zVNBSyeOyxx6KOqe1UEcQbaKhTp45pLd7rpJ3Wr1/vBD/mz5/vzNG1a1enLYpCG+4IGspQcODII4+MWstrr73mhEC8I1Yo45prrjGFHEqWLBnZVK1munTpElVNJVaFC7nffvvtUcfQfXzqqadGvqZqLX/729+iqpkozDRmzJjAt5zCJrqv3ZHbUIauwYQJE6xq1aqRuVatWuW0OfHen6+//nrCNirnnXde5LppIl3DKlWqBD4fNkQAAQQQQAABBBDITAFCGZl53TlrBBBAAAEEEEAAAQQQQAABBBBAAIEAAv4gQKzWEJpGFQGOOeaYyIwKW/g/Za8XVQ3hvffei2ynUMDxxx8fcyV9+vSJqhKglih169Z1tlVlgYYNG0b2c4MX3rYmxx13nKnSgEILeoiuKgSHHXZYZB9V1lCFjXQNf5UMhR3UOkUVBGINVSnQegYOHGiHHnpojk3810IhCm8Qxt1BoYejjjoq4bVQpYeDDjooso3WpioW3of27ou7du1yHt67VSFUaUHVPbwjVquLWIERdx+FKRQ2UBDFbS3jnS9oKEMhheeeey6yq9amfUuUKBG1Pn8oQ+f76aefRqpCeDdW0EDhA+9YvHhxVHjD3wZHAQ9/RRTtH6tVj6wqVqwY6LYLK5QxdepUO/bYY3McU61oxo0bF/m6QjSxqp24GxDKCHTZ2AgBBBBAAAEEEEDAJ0Aog1sCAQQQQAABBBBAAAEEEEAAAQQQQACBOAL+IMDDDz9sqhwQa6htg/dT90uXLs2xmQISqiCgcfjhh5s+mR9vKMCgh9/umDJliv3lL3+J/N3bisStQOANQqiFhao8uG1KlixZ4lSucMddd91l3bp1S9u19z/wVjWI66+/PtfH81+LWNU03MmTXQu111DVDndoXVpfvKHqHsOHD4+8/OOPP1rp0qUjf585c6Z179498vd44Z2gJ58slKHKHGq/IQPviHd/+kMZqvSic4o3FBRReMIdn3/+udWoUSPyd+99rC/Onj3bmjRpkmO6PXv22EknnRTV8iNWO5R46wgjlJGoTY8/OORvI+NfF6GMoHcw2yGAAAIIIIAAAgh4BQhlcD8ggAACCCCAAAIIIIAAAggggAACCCAQR8AfBPjXv/5lJ598csytkwUBVHGhcePGkX3VUiFWdQF3g2XLllmPHj0i2ysUoBYZ7vBW3dBc06ZNMz1Ufvrpp53Axw033OD80fj222+dVguXXXZZZP+xY8ea2qyka/irgigY0LJly1wfzn8tnn/+eeeBf6yR7Fp88sknUeEaVXpIVCFh1qxZUVU5VClDVSnc4W+ZohY13muX6kn7QxmqqOG2PPnqq69MVVPcyh3u3E2bNnVCPqVKlcpxOH8oQ5YK7cQbak2iSh/u8Lb12Llzpx188MFRu6ptTqzjaiOFVRRaccczzzxjp59+eiCSMEIZqhijtkGxhr8Ni4JEnTp1irs2QhmBLhsbIYAAAggggAACCPgECGVwSyCAAAIIIIAAAggggAACCCCAAAIIIBBHwB8EeOONN6JagHh3SxYE8FeqSBXdX9lClR1eeOEFZ5o6derY3LlzrWvXrvbmm2/ahRde6DwMd9tQ6GsLFy6MqlQxY8YM04P8dA21c1FbF3f4gwypHjfMa6G2MbfddluqS4hs/8orr0S1SPG3mvEHaFI9kD+UkWx/VYNQ8ODAAw+Muak/lJEsfPDII4/Yo48+GplLQZ9zzjnH+bsqwJx66qmR19x7L94a1Y7mn//8Z+Tl+++/36688spkp+S8HkYow60iE+uAhDICXQY2QgABBBBAAAEEEMijAKGMPAKyOwIIIIAAAggggAACCCCAAAIIIIBA8RUIMwiQ11DGvffeax07doxgP/bYY057EnfoYfkpp5ziVFBQpYarr77ajjzySOflCRMmmCpvDBgwILL9ggULrFKlSmm7eP5QhoIh/goLqRw8zGuR11CGKj8ceuihkeUr4KE53fHAAw/Y3/72t1ROL2rbVEMZydpupBrKUGuUhx56KLKmkSNH2gUXXOD8ffHixVGVLpKFMvxtbJKt1QtBKCPXtxA7IoAAAggggAACCBQiAUIZhehisBQEEEAAAQQQQAABBBBAAAEEEEAAgcIlEGYQYPfu3XbQQQdFnWDz5s0Dn7DWcvbZZ0e29wcLvvzyS1MbEw0FNlQtw63eoQfjq1atslGjRjmvq7LCF198EfjYudlQ7TZUHcMdCoaceeaZuZnK2SfMa/H5559HtYJROMXbWibZIp988kmrW7duZDN/iOG6666zO+64I9k0cV9PNZShViqzZ8+28uXLx5wz1VCGP0jx0ksv2QknnODMvW3btqhAir6mwFGJEiViHlstdNT+xB3jx4+3s846K5ANoYxATGyEAAIIIIAAAgggUMgFCGUU8gvE8hBAAAEEEEAAAQQQQAABBBBAAAEECk4gzCCAzkKhCrURccc333xjFStWzNUJfvjhh1FtIJ599tlIJY1p06Y5AY127drZp59+ap07d7ZNmzbZlClTnGO1aNHC1LohnUNVOZ555pnIIfIaVAjzWqitiip5uEMVRp577rlcc6itzfXXXx/Z//DDD7f//Oc/VrJkyVzN6Q9lKMxyySWXWNmyZW2//fZzAjby9A5VR+nRo0fM46UayujWrZvNmjUrMpe/9UwqrWnOOOMMW7RoUWQuf5WRRECFLZRx6aWX2meffRZZ8nvvvWcNGzbM1TVmJwQQQAABBBBAAIHMESCUkTnXmjNFAAEEEEAAAQQQQAABBBBAAAEEEEhRIMwggA5944032muvvRZZhdpe3HzzzSmu6o/NFe7wVs7QQ/lHHnnEeU1VM6pVq+ZUa3j++eeddhM7d+60jz/+2HldrTXUYiOdY+LEiXb33XdHHSIvD7HDvhZuFRF3gao8cvzxx+eKROGaNm3aRO376KOP2kUXXZSr+fyhjGuvvdb69+8fNZfum1dffTWQrz+UoQBJv379Yq5t/fr1dtRRR0W9pntNgRB3uGEf9+8Kg+j+8w8FGBRk8I758+dblSpVArkUtlBGr169bOrUqZG1p1L1I9AJsxECCCCAAAIIIIBAsRQglFEsLysnhQACCCCAAAIIIIAAAggggAACCCAQhkDYQQBVCejevXvU0tQqQq0+SpUqldKSN27caEcccURkH1V7UEUDteJYsGCB8/WxY8favffea2pvUbp06UjFAj3g14P+dI6lS5faqaeeGnUIVZBQWCGVViHuBGFfC3+LDh3H26YjFRu1plEow1sFRdfh8ccfz1XLliChjJ9//tlatmwZtUyFb7zVSdwX/aEM3Q9qKZKVlZXjNIcMGWKjR4+OfF0VV1R5xTvc+8r9ms715ZdftqZNm0Y2U2WWq6++OqqyRKoVWgpbKENtgYYNGxY5R52vgjHewEoq9w3bIoAAAggggAACCGSGAKGMzLjOnCUCCCCAAAIIIIAAAggggAACCCCAQC4Ewg4CaAkKZSic4R16SH7NNdfYQQcd5Dwor1Chgm3evNl++uknW7x4sVNtYP/9989xBg0aNMjxteOOO855QK4xe/ZsZ17/GDNmjP7KkUUAACAASURBVLVu3ToXIqntolDCww8/nGMnPaxXQOPAAw90wijbtm0zVWhYsWKF05rjzjvvzBFSCftayFehEbUy8Y4TTzzRaftSv359J+CiFiQbNmwwhUx0PVTdpESJEjnOSW1itJ9/yPnkk092rm3lypWdc1VgYeXKlbZ8+XK7/PLLrVGjRlG7BQllaIdYvk899VSOqh3+UIb2Pfjgg53KLQpdqHKFzk3tbfxtXCZMmJAjWKJzOOmkk6LsZHXTTTc55ylTVUpRBRHvUJWJY489Nupre/bscSq7xBoKg6gtjzs6duyYo/pIuXLlosJJP/74Y9R65a/7PdZQC5/bb7898pKCOp06dYp7k7/11lvWpUuXqNfr1KljN9xwg9PGpGrVqrZ161bn/BWaOeuss5x7nIEAAggggAACCCCQ2QKEMjL7+nP2CCCAAAIIIIAAAggggAACCCCAAAIJBMIOAuhQCh2ccMIJKbk/+eST1rZt2xz7qH2JtzqDNmjfvn0kCPHdd99Zq1atcuw3Y8aMqKoGKS0mhY137NjhBAQWLVqUwl5mc+fONT3s9o50XIu3337bOnfunNLa1JKjZs2aMffp06ePU20jlTFy5Ei74IILonYJGsrYvn2705pGAQ93VK9ePVIxxf1arFBGkDWqEsT06dNjhlBeeOGFuC1QYs2te3XcuHE5XtqyZYuplUxuhwIt77zzTmT3dIYyfv/9dydEo/szyBg6dGjMoE6QfdkGAQQQQAABBBBAoPgIEMooPteSM0EAAQQQQAABBBBAAAEEEEAAAQQQCFkgHUEALXHJkiU2cOBAe/fddwOt+I477rDrrrsux7YKFChY4B39+vWz66+/3vmSKhoceuihOfabP3++Ux0hP8avv/5q9913n6lKQtARq6JCuq7FRx99ZHfddVfg4IiqN6i6RKyxc+dOp2XMQw89FPRUrW/fvk6lBe8IGsrQPrFa4uj66z5whz+UoXY5/ooY/gUrkKEKE6riEmsooKBWKbqPk40LL7zQuQdi3XNFKZSh81To4/zzzzetO9no2bOn9erVK9lmvI4AAggggAACCCBQzAUIZRTzC8zpIYAAAggggAACCCCAAAIIIIAAAgjkXsAfBNAn8v2tJtzZW7RoEalYoFYOCxYsSHrgWbNmmdpNqM1Dooe8ajPhbbPgTqwwgbe9g77ub1/hXZdeD7q2pItPcYOPP/7YHn30UZs3b17Cc9X6Ro0a5VSA8I50Xotdu3aZ2nQoDOJvueE/zVjtPPzbKHSjti1z5szJ0R7Fv60e2uvhvXf4W6Eke7ivkMUHH3wQNYe3ooc/lKE2HapOoQosWqP33pO/2uX079/faaOTbCjgc88998SsHqEWKWrXo+ot8YaqqTRp0iTZYeK+nqxSxsUXX2wjRoyIuf8rr7xiuq/coTBNhw4dkq7lt99+s8cee8wU0PG3v/HufMUVV9iQIUOSzscGCCCAAAIIIIAAAsVbgFBG8b6+nB0CCCCAAAIIIIAAAggggAACCCCAQBERWL9+vS1dutS2bt1qe/fudR6I16hRw+rWrWtlypQpImcRbJnr1q1zzlWVPHSu5cqVs4oVKzrnWrVq1WCTpGkrrWf16tW2fPlyU+WLEiVKONdCa1PbkpIlS6Z0ZAUefvrpJ9ODfIU/dK7ly5e32rVr52q+lA7+58axQhmdOnVyXt2zZ4/TAkcVTRo3buysKzdDbsuWLXPa82RlZTnhJZ1rcR+6T9Q+Zvfu3ZHrW7ly5UJxLxd3e84PAQQQQAABBBAoKgKEMorKlWKdCCCAAAIIIIAAAggggAACCCCAAAIIIIBALgQShTJyMR27IIAAAggggAACCCCAQAoChDJSwGJTBBBAAAEEEEAAAQQQyJvAhg0bnE//auhTp7n9JGbeVlH899ane/VpVZyL/7XmDBFAAAEEEAgiQCgjiBLbIIAAAggggAACCCCQHgFCGelxZVYEEEAAAQQQQAABBBCIIeDvaa+y5YzwBdQj3tsbHufwjZkRAQQQQACBoiRAKKMoXS3WigACCCCAAAIIIFDcBAhlFLcryvkggAACCCCAAAIIIBCCgHqKd+nSJc8z3XLLLXb22WdH5iEskGfSQBPgHIiJjRBAAAEEEMgYAUIZGXOpOVEEEEAAAQQQQACBQihAKKMQXhSWhAACCCCAAAIIIIBAQQusXLnSVNUir2Po0KHWrl27yDSEBfIqGmx/nIM5sRUCCCCAAAKZIkAoI1OuNOeJAAIIIIAAAgggUBgFCGUUxqvCmhBAAAEEEEAAAQQQKGABQhkFfAHyeHhCGXkEZHcEEEAAAQSKmQChjGJ2QTkdBBBAAAEEEEAAgSIlQCijSF0uFosAAggggAACCCCAQP4IrFu3zvr27RvzYBs3brS5c+dGXmvUqJE1btw45rY9evSwww8/PPIaYYH8uX44548zR0EAAQQQQKCoCHz55Zf2+uuvR5Z7/vnnW/PmzYvK8lknAggggAACCCCAAAJFWoBQRpG+fCweAQQQQAABBBBAAIH8F/jmm2+sTZs2kQPfeeed1r1790ALISwQiCnPG+GcZ0ImQAABBBBAAAEEEEAAAQQQQAABBBBAIBQBQhmhMDIJAggggAACCCCAAAKZI5CuUMZvv/1ma9assWrVqln16tVDA92zZ4+tWrXKdu3aZfXr17fSpUunPLf23759e8r7//77785xS5YsaaVKlbISJUqkfOxEO2zYsMHUaqZGjRrOH3cQygiVmckQQAABBBBAAAEEEEAAAQQQQAABBBDItQChjFzTsSMCCCCAAAIIIIAAApkpEHYoY+LEiTZixAhbu3ZtBLRSpUp27rnn2l133WX77rtvTOgrrrjCli9fnuO1Tp062TXXXOPM9+CDD9qkSZOitjnuuOPs3nvvtaZNm8a9gLt377Zx48bZu+++a19//bVt2bIlsq32O/nkk61nz55WuXLlhDfBt99+a61bt47aRudWq1Yt0zqOOeYYO+OMM6x27dqBbyaFMIYNG2affPKJ/fTTT5H9FGTp06ePyYVQRmBONkQAAQQQQAABBBBAAAEEEEAAAQQQQCCtAoQy0srL5AgggAACCCCAAAIIFD+BMEMZgwYNsoEDB8ZFUtDgxRdftCZNmuTYpkGDBjH3u/jii23o0KFOi5WFCxfGnXvq1Kl27LHH5nhdQYdbbrnF1Hs90ahTp4499thjdvzxx8fd7P3337eOHTsmvQl69+5t3bp1swoVKiTcVmvq2rVrVIDFv4MCJw888EBUkGTp0qVJ18AGCCCAAAIIIIAAAggggAACCCCAAAIIIBC+AKGM8E2ZEQEEEEAAAQQQQACBYi0QZihDwQZVfkg0TjzxRHvhhRdybBIvlNG8eXPr0KGD9e/fP+G8p59+uj3zzDNR26h9ymmnnRYVaEh2MefMmWN169aNudnkyZPttttuSzaF83q7du2cMEm8sWjRIqeqRrKhIItarXirexDKSKbG6wgggAACCCCAAAIIIIAAAggggAACCKRHgFBGelyZFQEEEEAAAQQQQACBYisQZihDSGrn0a9fPzvkkENs165dpnYmM2fOjPJTC5IWLVpEfe3VV1+1vXv3Ol978sknTety51N44bXXXnOqWFx22WXWqFEjZ86xY8dGzTF37lxTMMQdAwYMyBHUaN++vTNPyZIlbfHixTZy5MioOTS/2onEGv/73//s448/tp07dzrnprDE6tWrnbYjn332WY5dRo0aZeedd17MuWTkD6fcdNNN1rJlS8dh3rx59tBDD8Xcl1BGsf125MQQQAABBBBAAAEEEEAAAQQQQAABBAq5AKGMQn6BWB4CCCCAAAIIIIAAAoVNIMxQhqo6TJ8+3WrVqhV1mldddZW99957ka+pxUmXLl3iUnTu3NnefvvtyOsKehx33HE2ZswYK1++fOTrl156aVQYwtvCRIELVc/wDrVOUejBO5YsWWKXXHJJVAuRt956yxo3bpzSpfrll1/skUceiQpaKDzyzjvv5JhH1UT8oRQFUdq2bRu17fLly61Vq1Y5Kn0Qykjp0rAxAggggAACCCCAAAIIIIAAAggggAACoQkQygiNkokQQAABBBBAAAEEEMgMgTBDGffcc48pgOEfs2fPtmuuuSby5U6dOtngwYPjAvtDGdrw888/txo1akTtoyoX3hYhTz31lLVp08bZZvTo0TZkyJDI9mo7cvPNN8c8psIcvXr1irymeS+44IKUb4A9e/bY5Zdfbp9++mlk32+//dYqVKgQNdezzz5rd911V+Rrp5xyij333HMxj6dKI3fffXfUa4QyUr407IAA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IECAAAECsxA4+OCDy/nnn1/22X338s5DD51FTV7alIBQxuiSQhmj243jldVQxl+eunXZattl41iNOisCQhmaAwECBAgQIECAAAECBAgQILCYBYQyFvPRtW8ECBAgQIAAgUUqcPLJJ5dTTjmlHL5qVVm9776LdC8X1m4JZYx+vNqhjFWHbF02f4QAwOiSzbzyOxfdVC447/pWZUecNFW223l5MxWrpavAWWedVY466qjW3y+44IIyNTVFiwABAgQIECBAgAABAgQIECCwaASEMhbNobQjBAgQIECAAIGlI9CevkQoY3KO+cEnnFDO/8Y3yoknnlhWrVo1ORu2ALbkpNVXlcsuvr084/mPKI/9zRULYIsX9yZ+6exry6UXr2vt5Emf3bYs32i9xb3DE7B37aBdNuXKK6+cgC2yCQQIECBAgAABAgQIECBAgACB5gSEMpqzVBMBAgQIECBAgMAcCey2225l7dq15ZgDDigH/d7vzdFaraaXwE4HHFDW/fzn5Zxzzik77LADrCEEPvehG0t+Hr/Lg8tuez50iFdadBwCH/vby8u6m+4sGz5ovXLyP2w7jlWosyZwySWXlH333bc1Qsa5557LhwABAgQIECBAgAABAgQIECCwqASEMhbV4bQzBAgQIECAwFIUOP/888uKFSvKypUrl8zub7311q19FcqYjEO+9vrry26vfGVrYzzlPvwx+fY/31red8w1ZdmG65UDXyMEMLxgc6+45orbytkfXtuqcNc9V5T9X/uI5ipXEwECBAgQIECAAAECBAgQIECAwJIUEMpYkofdThMgQIAAAQKLReDCCy8smcoj5bvf/W4rnLEUSjuUsc/uu5d3HnroUtjlid7H0z//+XL8Bz9YVu6wQznznHMmelsndeNe/8LLy0+vu9MUJvN8gBLISDAj5S0ff2TZ7BHrz/MWWT0BAgQIECBAgAABAgQIECBAgMBCFxDKWOhH0PYTIECAAAECS1qgGso488wzl8xoGXvttVf5wQ9+UKYe/vBywbvfvaTbwCTs/N6veU255IoryuEvfGFZ/fa3T8ImLbht+OKnbipn/d31ZZPN1i9/fNDWZdkG6y24fVjoG/ydi24qF5x3fWs3jJKx0I+m7SdAgAABAgQIECBAgAABAgQITI6AUMbkHAtbQoAAAQIECBAYWmCphjIOPvjgkmlbUk489NCyavfdh7bzgmYELvz+98t+b3xjq7Jz3v/+ssNeezVT8RKs5c0HX1nW/tcd5RFbLSvP+sMtysabGqVhrppBNZAx9ehl5YiTtyrLNxKMmSt/6yFAgAABAgQIECBAgAABAgQILGYBoYzFfHTtGwECBAgQILDoBZZqKOO8884rhxxySOv4Tv3ar5UL3vWuRX+sJ3UHDz7hhHL+N75RNl6+vHwvQZmttprUTZ347brx2jvLO1evbU1jssHy9cpvP2Ozsu2Omxg1Y4xH7vJLby3fuejm6SlLBDLGiK1qAgQIECBAgAABAgQIECBAgMASFRDKWKIH3m4TIECAAAECi0NgqYYycvSe8pSnlKuvvrp1IFf93u+VEw84YHEc1AW0F5myJFOXpBz4nOeUY088sZQHPWgB7cHkbeptt95dTlp9VWvEjJSEM7bbaZOyxTYblkc+ZqPJ2+AFuEXXXHl7ufw/bi0JZNxy852tPXjgBuuV5x+0WfndP37wAtwjm0yAAAECBAgQIECAAAECBAgQIDDJAkIZk3x0bBsBAgQIECBAoI/AUg5lnHXWWeWoo46aFjrxL/+yrHrCE0q5+27tZg4E1v38561Axtrrr2+t7ZzTTy87POtZc7Dmxb+KBDO+9KmbyhfX3FRu//nM9rzFNsvLlltv2JrapNv0JtdccVtnpPuVst56pdxvvVLuvOPucv1P7ijlfqXcr/JT/Xf+d8r//KfyPyq/n/5jZZWpr74F+cU9rf/7n/9Xyj2tf8z8/a9ts6xssOF69y5b+cm/89Zu/fyq8nN3KZs9fFlZtsH9ezaMG679RUkYIzZ3/OJ/TTfeZP3yhKdtWp5/yCamK1n8by17SIAAAQIECBAgQIAAAQIECBCYFwGhjHlht1ICBAgQIECAQDMCSzmUEcGTTz65nHLKKdOYB730peWY/fcv5ac/bQZYLR0FEsg46j3vKef967+2/r7HLruU0z70oVI23JBYgwIJZ/zLeT8rl3379nLxBbc2WPPSripBjEc+dqPyyMc8qDx+t+Vly99Y2h6TsPfnn39+WbFiRVm5cuUkbI5tIECAAAECBAgQIECAAAECBAg0KiCU0SinyggQIECAAAECcyuw1EMZ0T7yyCPLmjVrpuHTqbf6wAPLyi22KOX22+f2gCyBtWVkjINPOKFk6pKUjZcvL+d+5jNl6rGPXQJ7P3+7mIDG2h/+olx28e2l/b/nb2sW3pof8vD1y6//xr2jjGy6+fqtETs237KUB6y/8PZlsW3xJZdcUvbee+/Wbl1wwQVlampqse2i/SFAgAABAgQIECBAgAABAgSWuIBQxhJvAHafAAECBAgQWNgCQhn3Hr/TTz+9HH/88TMO5spddimr9tij7LHTTmVF5mdQZiWQMMaar3ylnP75z5eMlJGy8YMeVD75939fdthll1nV7cUECCxdgepUVEIZS7cd2HMCBAgQIECAAAECBAgQILCYBYQyFvPRtW8ECBAgQIDAohdYt25d2WmnnVr7efjhh5fVq1cv+n3utoNr165tTWdSHTWjveyKjTcuOzzqUaXcdddwPu0wRzXU0el/j/L3Pq9Zd8stJU+Qz0VZmTZ0zz33/nQoa//7v0tCGdWyz3OfW1a/7nWeap+LA2QdBBaxQHUaqiuvvHIR76ldI0CAAAECBAgQIECAAAECBJaqgFDGUj3y9psAAQIECBBYNAJbb711a1+WeiijfUATzsiT1xlFJD9KcwLbP+YxZdenPKUc9Kd/KozRHKuaCCxpAaGMJX347TwBAgQIECBAgAABAgQIEFgSAkIZS+Iw20kCBAgQIEBgMQs87nGPK7fccks58MADy7HHHruYd3WkfUtIIz/dylVXXdXz7yOttM+Ldt1115Gr3WGHHcqKFStGfn37hRmFIyOtDFpWrlw56KKWI0CAwMACQhkDU1mQAAECBAgQIECAAAECBAgQWKACQhkL9MDZbAIECBAgQIBAW2C//fZrjQiRTvMzzzwTDAECBAgQWDACxx13XDnjjDNa22v6kgVz2GwoAQIECBAgQIAAAQIECBAgMISAUMYQWBYlQIAAAQIECEyiwMEHH1zOP//8khEUzjnnnEncRNtEgAABAgQ6CggWahgECBAgQIAAAQIECBAgQIDAYhcQyljsR9j+ESBAgAABAotewNDvi/4Q20ECBAgsWoHddtutNYXUHnvsUU477bRFu592jAABAgQIECBAgAABAgQIEFi6AkIZS/fY23MCBAgQIEBgkQicd9555ZBDDmntTaYvyTQmCgECBAgQWAgCW2+9dWszDz/88LJ69eqFsMm2kQABAgQIECBAgAABAgQIECAwlIBQxlBcFiZAgAABAgQITJ7AJZdcUvbee+/WhgllTN7xsUUECBAg0Fmg+vl16qmnlj333BMVAQIECBAgQIAAAQIECBAgQGDRCQhlLLpDaocIECBAgACBpSiw1157lXXr1pVPfvKTZWpqaikS2GcCBAgQWIAC++23X7nqqqvKueeeW1asWLEA98AmEyBAgAABAgQIECBAgAABAgR6CwhlaCEECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgTEICGWMAVWVBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAGhDG2AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIDAGAaGMMaCqkgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAglKENECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTGICCUMQZUVRIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEhDK0AQIECBAgQIDAIhS45JJLytTUVFmxYsUi3Du7RIAAAQILVWDdunUln1ErV65cqLtguwkQIECAAAECBAgQIECAAAECQwkIZQzFZWECBAgQIECAwOQLnHfeeeWQQw4pO+ywQznzzDMFMyb/kNlCAgQILBmB/fbbr1x44YXlwAMPLMcee+yS2W87SoAAAQIECBAgQIAAAQIECCxdAaGMpXvs7TkBAgQIECCwSAXOOuusctRRR7X2bs899yynnnrqIt1Tu0WAAAECC0ng5JNPLqecckqrILXZAAAgAElEQVRrk4855phy0EEHLaTNt60ECBAgQIAAAQIECBAgQIAAgZEEhDJGYvMiAgQIECBAgMBkCxx55JFlzZo1rY08/PDDy+rVqyd7g20dAQIECCxqgYyOkVEyUrbffvty7rnnLur9tXMECBAgQIAAAQIECBAgQIAAgbaAUIa2QIAAAQIECBBYhALr1q0r++67b/nBD37Q2rsTTzyxrFq1ahHuqV0iQIAAgUkXuOSSS1qBjHw2bbzxxq1AxtTU1KRvtu0jQIAAAQIECBAgQIAAAQIECDQiIJTRCKNKCBAgQIAAAQKTJ5BOsAQzbrnlltbGJZSRcIZCgAABAgTmSqAayMg6M6VWptZSCBAgQIAAAQIECBAgQIAAAQJLRUAoY6kcaftJgAABAgQILEmBejBj5cqV5bTTTisrVqxYkh52mgABAgTmTuC8884rRx11VGuEjBSjNs2dvTURIECAAAECBAgQIECAAAECkyMglDE5x8KWECBAgAABAgTGIlCfyuSYY44pBx100FjWpVICBAgQIBCBtWvXlr333lsgQ3MgQIAAAQIECBAgQIAAAQIElryAUMaSbwIACBAgQIAAgaUicNxxx5WzzjqrnHvuuWVqamqp7Lb9JECAAIF5Ethrr71a4Yx3vvOdpiyZp2NgtQQIECBAgAABAgQIECBAgMD8CwhlzP8xsAUECBAgQIAAAQIECBAgQGDRCbSnLTFl1qI7tHaIAAECBAgQIECAAAECBAgQGEJAKGMILIsSIECAAAECBBa7wOmnn16OP/74ssMOO5R0ou26666tXV65cuX0ruf3+btCgAABAotXIIGKbmGKCy+8cHpakj322GPxItgzAgQIECBAgAABAgQIECBAgEADAkIZDSCqggABAgQIECCwWAT222+/ks62QcoxxxxTDjrooK6LnnfeeeWoo46a7rjrtGA6/A488MCyevXqrvVke04++eSem7TJJpu06qmGR+ovSAfjGWec0XfXUkevejIU//nnn99xvzItTHtqmHawpdcKL7nkkr4+AjB9D5kFCMybQM4rOScM8j7tdm5tnwdy7kjAodeoElk255+U/O+f/exn99n3Qc6HCeCdcsopPc8/g6Kec845A+3/oPVZjgABAgQIECBAgAABAgQIECCw2ASEMhbbEbU/BAgQIECAAIFZCKRz8ayzzmp19l111VXlBz/4Qdfa9tlnn/LOd76z69/bo27025wtt9yyfP3rX++62HHHHTdQmCKdmaeddlrXehLsSCdkv7L99tuXc889t+tiRx55ZFmzZk2/alqdq722Z1Cffs6D7tfhhx/eM/wySIgmncYJ4+y5555d9z9tJ8esX0mIplc96cBOiKZTp3O77kE6n6ud2L22KcerV8d63huDHPccr3Ywp9P6eoV6qssPUk9T2zOX9QzinPdpzj+9SnxWrVo1dDusBiMGac85HyZc1q/0e58Oeh7L++LYY4/turqDDz54OpTRz6fX+XnQevrt98Ybb9w6X/Zq8/3q8HcCBAgQIECAAAECBAgQIECAwGIXEMpY7EfY/hEgQIAAAQIEZimQJ8HTsd0u6STP79Kh3uuJ7iyTDs38t1fJFCm9RqbIuhM86FdPRtvoV88RRxzRM2iS7ewXXmgqTDFoPf3CHYOGRGJz5plndj0Ug3Ya9+t8HjQk0m97Bh21pV89g+5XP+em6hn0ePXbnkE71Setnn7Ha9D3RRrylVde2bU9D9oO+4Ugmjrug9Zz4okn9gybxCf7dsstt5QEyBJMqpeclzOKUb8Rf3J+7lUStEiIqFNJgCnr7rWOWX70eDkBAgQIECBAgAABAgQIECBAYNEICGUsmkNpRwgQIECAAAECBOZbIB2Y+Umn6CDTGfSbviT7028alIRVMspFt87TtklGFeg3gkO/TtrUlTBOr33LPqXjuN/29AvRDDJtTban34gJsUmH+NVXX921eWS0loxO0GvkjkHqyagBqafXCA4xzvakU71X6Tc90KDhhUHqaXfyd9ue7FeOV6/pigbZrzinnl4+aTfx6RfCStik1/Z0aoed3pf93hf9wmWpc8cdd+z7Po1tt/d7v/f4fJ/XrJ8AAQIECBAgQIAAAQIECBAgQGB2AkIZs/PzagIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIBARwGhDA2DAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIDAGAaGMMaCqkgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAglKENECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTGICCUMQZUVRIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEhDK0AQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAGASEMsaAqkoCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAgFCGNkCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQGIOAUMYYUFVJgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEBDK0AYIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAmMQEMoYA6oqCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJCGdoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQGAMAkIZY0BVJQECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAKEMbIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAiMQUAoYwyoqiRAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQICGVoAwQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBMQgIZYwBVZUECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAaEMbYAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMAYBoYwxoKqSAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQICCUoQ0QIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBMYgIJQxBlRVEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgSEMrQBAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgMAYBIQyxoCqSgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQICAUIY2QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAYg4BQxhhQVUmAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQEMrQBggQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECYxAQyhgDqioJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAkIZ2gABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAYAwCQhljQFUlAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEAoQxsgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECIxBQChjDKiqJECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgIZWgDBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIExCAhljAFVlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABoQxtgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAwBgGhjDGgqpIAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgIJShDRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIExiAglDEGVFUSIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBIQytAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAwBgEhDLGgKpKAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgIBQhjZAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEBiDgFDGGFBVSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAQytAGCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJjEBDKGAOqKgkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECQhnaAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBgDAJCGWNAVSUBAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAQChDGyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIjEFAKGMMqKokQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECAhlaAMECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgTEICGWMAVWVBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAGhDG2AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIDAGAaGMMaCqkgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAglKENECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTGICCUMQZUVRIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEhDK0AQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAGASEMsaAqkoCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAgFCGNkCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQGIOAUMYYUFVJgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEBDK0AYIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAmMQEMoYA6oqCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJCGdoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQGAMAkIZY0BVJQECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAKEMbIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAiMQUAoYwyoqiRAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQICGVoAwQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBMQgIZYwBVZUECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAaEMbYAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMAYBoYwxoKqSAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQICCUoQ0QIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBMYgIJQxBlRVEiBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgSEMrQBAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgMAYBIQyxoCqSgIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQICAUIY2QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAYg4BQxhhQVUmAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQEMrQBggQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECYxAQyhgDqioJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAkIZ2gABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAYAwCQhljQFUlAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQEAoQxsgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECIxBQChjDKiqJECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgIZWgDBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIExCAhljAFVlQQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABoQxtgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAwBgGhjDGgqpIAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgIJShDRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIExiAglDEGVFUSIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBIQytAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAwBgEhDLGgKpKAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgIBQhjZAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEBiDgFDGGFBVSYAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAQytAGCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJjEBDKGAOqKgkQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECQhnaAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBgDAJCGWNAVSUBAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAQChDGyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIjEFAKGMMqKokQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECAhlaAMECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgTEICGWMAVWVBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAGhDG2AAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIDAGAaGMMaCqkgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAglKENECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgTGICCUMQZUVRIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEhDK0AQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAGASEMsaAqkoCBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAgFCGNkCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQGIOAUMYYUFVJgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEBDK0AYIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAmMQEMoYA6oqCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJCGdoAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQGAMAkIZY0BVJQECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBAKEMbIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAiMQUAoYwyoqiRAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQICGVoAwQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBMQgIZYwBVZUECBAgQIAAAQIECBCYb4GrfnhHuf3nd3fdjNtv/VXJMpNclm+0XpnadoNZbeKGD1qvbLXtslnV4cUECBAgQIAAAQIECBAgQIAAAQIERhUQyhhVzusIECBAgAABAgQIECAwTwK/uquUn/+slLvuLOWGn9xZLv3WreXKy24v11x5R/npdXfO01YtzNUmtPHwrTYo692/lMfsvGHZ/knLy9Sjl5UEQhQCBAgQIECAAAECBAgQIECAAAECsxUQypitoNcTIECAAAECBAgQIEBgjgTW3VjKTdeVct2P7y6XXvyzcunF68oN1072aBdzRNP4anZ88kbld563ovzmbhs1XrcKCRAgQIAAAQIECBAgQIAAAQIElo6AUMbSOdb2lAABAgQIECBAgACBBSxw4zWl/Nd37i7fveim8p2Lbip3/OLeqUkeuGy9suU2y8sW22xYNn/4srLFNst77uUtN99Z8jNJZeNN1y/5mY9yzRW3tSxvuO6Okv99zZW3z9iM7XZeXvY/+uFls0fMz/bNh4l1EiBAgAABAgQIECBAgAABAgQINCcglNGcpZoIECBAgAABAgQIECAwFoEbri7li2vWla+f99/TYYyNN1m/PGn3zcojH7NRWbaBqTaagk9A4/JLby2Xfvtn0wGNTGXy5o8/ypQmTSGrhwABAgQIECBAgAABAgQIECCwhASEMpbQwbarBAgQIECAAAECBAgsPIE7bi/lfX91bfnBv69rbXxGxnjy7puVx+/y4IW3Mwtsiy//j1vLl86+tvzyjrvLzk/dqLzi+C0W2B7YXAIECBAgQIAAAQIECBAgQIAAgfkWEMqY7yNg/QQIECBAgAABAgQIEOgh8N43XFsu/vq9gYyMjrHXfluUzR+xjNkcCdxw7R3l7A9d1Qpm7H/0I8que62YozVbDQECBAgQIECAAAECBAgQIECAwGIQEMpYDEfRPhAgQIAAAQIECBAgsCgFvv3Pt5b3HXNNa98yQsbz999KIGMejvQF511fvnPRTWWzR6xf3vLxR87DFlglAQIECBAgQIAAAQIECBAgQIDAQhUQylioR852EyBAgAABAgQIECCw6AVet9/l5abr72zt5/NfOlW22Gb5ot/nSdzBW26+s3z0XZe3Ns1oGZN4hGwTAQIECBAgQIAAAQIECBAgQGByBYQyJvfY2DICBAgQIECAAAECBJawQHWUjC223rA1SoYyfwKffP+V5cbr7ijP/OMHl30Pfej8bYg1EyBAgAABAgQIECBAgAABAgQILCgBoYwFdbhsLAECBAgQIECAAAECS0Xgk393ffnSp25q7e6f/Pkjy8abrr9Udn0i9/NLZ19bLr14XdnuNzcsR5wsIDORB8lGESBAgAABAgQIECBAgAABAgQmUEAoYwIPik0iQIAAAQIECBAgQIDASauvKpddfHvZeJP1y58c9kgg8yzwnYtuKhecd31rK973pe3meWusngABAgQIECBAgAABAgQIECBAYKEICGUslCNlOwkQIECAAAECBAgQWFICr3jmZa39ffwuDy677Wm6jPk++NdccVs5+8NrW5shlDHfR8P6CRAgQIAAAQIECBAgQIAAAQILR0AoY+EcK1tKgAABAgQIECBAgMASEmiHMvbad4vyyMdutIT2fDJ39Y5f3F3OOOGHrY0TypjMY2SrCBAgQIAAAQIECBAgQIAAAQKTKCCUMYlHxTYRIECAAAECBAgQILDkBdqhjOe/dKpssc3yJe8xCQDvPf7e0UuOOGmqbLezYzIJx8Q2ECBAgAABAgQIECBAgAABAgQmXUAoY9KPkO0bSeCee+4p69atKw94wAPKgx70oJHqGOZFv/rVr8pNN91UNthgg7LRRp5iHMbOsgQIECBAgAABAp0F2qGMP/nzR5aNN10f0wQIfPRdl5dbbr5TKGMCjoVNILCQBW6//fZy8803T+/CQx/60Nb9C4VAXeD6668vd911V+vXuef04Ac/GBKBiRFI20wbbZdly5aVhzzkIROzfU1tSPbzmmuuKVdccUVZu3Zt2XDDDctmm23W+tlqq63KihUrmlqVehoU+NnPflZuu+22Vo33u9/9yiMe8YgGa1/cVS2l65T0If385z+fPqD5nM3n7VIs//Zv/1a+/e1vl7322qtsueWWS5HAPhPoKZDPlHy2tEs+/4ftfxbK0MgWhUAujr/+9a+Xc845p3z5y18uP/nJT1r7tf3225dzzz137PuYQMbOO+88vZ5HPepRZc8992x9gFV/P/YNsQICBAgQIECAAIFFI2CkjMk7lO2RMk767LZl+UbrTd4G2iICBBaEwNFHH13OPPPM6W39x3/8x7LjjjsuiG23kXMncNVVV5WnPvWp0yvMfaZTTz117jbAmgj0EfjRj35UnvGMZyzaNpr7vW95y1vKWWed1VXizW9+c3nJS16irUygwMqVK6f7CLJ5V1555QRu5WRu0lK6Tvnrv/7r8u53v3v6QJxxxhnld3/3dyfzwIxxq1avXl0+/elPT6/hb//2b8vznve8Ma5R1QQWnkC+v+X82C7HH3982X///YfaEaGMobgsPIkC3//+91tvhO9973v32bynPOUp5ROf+MTYNzsjc2yzzTYd15MvzXlzSuOO/TDM+QqkR+ec3AoJECBAgMCSEhDKmKzDnREyMlJGyvu+tN1kbZytIUBgLAI33HBDOfDAA2dd95//+dUrrhEAACAASURBVJ+XZz3rWdP15N9nn3329L+FMmZNvCgr+K//+q/yzGc+c3rfhDIW5WFe0Du1mEMZX/jCF0rO1dUn6DsdrNNPP33G+X1BH9AJ2fi77767XH311dNbs8kmm4w0GskOO+ww4/gJZQx+gJfSdYpQRmmFlxJiqpbf/M3fLJ/97GcHbzQNL3ndddeVX/7yl61aMwrTwx72sIbXoLr5EGjq/D4f2551CmXMl7z1TozA5z//+fLKV76y6/asWrWqnHjiiXOyvU972tPKj3/8447ryhA2SVVP6pMvmX4lN5sy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EEAAAQQQQAABBBDIE4Gnx6+y/0z+ztb9tDFPepyf3WzZrp71On0L67w/lUjy8wzSawQQQAABBBBAAAEEEEAAAQQQQKD6CBDKqD7ngp4ggAACCCCAAAIIIIAAAkkFVDVj9vPf2+znfoiZ0iTpigkWaNW+1OqX1ajMJmLW3bTp9786f25y/vf7n/6vJ/s8uJ7v71Zi+t/vzf3/7hf+/99L9GcNM/257Iv19vPa+EEWVRxp1rLUWneob126lVnHXUutZu3IONgQAgjkucC6dets9erV3lE0bdrUatWqledHlZvub9iwwb755htvZw0bNrTNNtssNztnLwgggECRCPz222+2YsUK72hLS0utcePGRXL0HCYCCCCAAAL5IUAoIz/OE71EAAEEEEAAAQQQQAABBEIFVi371fSfWr2ymta6QylSCCCAAAIRCgwePNgmTpzobfGZZ56xTp06RbiHwt3UlClT7KKLLvIO8Oqrr7Z+/foV7gFzZAgggEAVCHz66afWrVs3b889evSwcePGVUFP2CUCCCCAAAIIxBMglMG1gQACCCCAAAIIIIAAAggggAACCCCAQByBv/zlLzZ16lTv02IJZag6yJo1a5zjLikpsVatWqV9jTz66KN2+eWXe+sVcihj1KhR9sILLzjHWl5ebvfdd1/CiirDhg2zefPmOcu3b9/ebr311rR9WSE3AjqvOr+ZtNtuu8222WabTFYtuHWieKYUHEpEB0QoIyJINoMAAggggEAWBQhlZBGXTSOAAAIIIIAAAggggAACCCCAAAII5LdAsYYybrjhBhszZox38h555BHbd9990zqZxRTK+Otf/2oycttHH31k9evXj+t10kkn2axZs5zPNaXLhx9+mJYtC+dOIHgdp7PnYglxpWISxTMllf0U4zKEMorxrHPMCCCAAAL5JkAoI9/OGP1FAAEEEEAAAQQQQAABBBBAAAEEEMiZAKGM36nHjx9vXbt2TcudUAahjLQumGq6MKGMaE5MMJSRyTMlmp4U3lYIZRTeOeWIEEAAAQQKT4BQRuGdU44IAQQQQAABBBBAAAEEEEAAAQQQQCAiAUIZv0NmMoBKKINQRkS3YZVu5tVXX7UHH3ywQh/c6WrcD7p37x6zTO3ate2aa66xxo0bV2n/q8vOCWVk70wQysieLVtGAAEEEEAgKgFCGVFJsh0EEEAAAQQQQAABBBBAAAEEEEAAgYITIJTx+ykllJH40mb6koK79ZMeUJs2bbxlFMi45557kq5TzAsQysje2SeUkT1btowAAggggEBUAoQyopJkOwgggAACCCCAAAIIIIAAAggggAACBSeQKJSxevVqW7FihTVr1swaNWpUUMcexQBqokoZv/76qy1fvtx++eUXa926tamqQKbtt99+s6VLl1ppaak1b97cSkpKMt1UxuvlYyhD50DXr8xq1KjhHfuGDRts8eLFznXdsGHDuCZabuPGjc66NWvWzNgu2YrufaaKE1tssUWyxXP2eTZCGVHeF4JYu3atrVmzxjHZcsstc2YTtqMonim5PICffvrJvvnmG6tTp45ttdVWMfdIuv344YcfnHNRXl5udevWTXf1mOWXLVtm2l7Lli1ts802cz6rbCjj+++/d54F2ma9evUq1T9WRgABBBBAAIFwAUIZXBkIIIAAAggggAACCCCAAAIIIIAAAgjEEQgLZSxZssSuv/56+/zzz721NGi322672QUXXGCdOnWqsLXnn3/emcrAbUceeaRdfvnlSd379+9vH330kbfcbbfdZrvvvnvS9dJdoG/fvqbjctuqVatMg5Ju02C4OwAYtu1Ro0ZZ586dYz4KC2UcdNBBduONN9q0adNilt1hhx1s0KBBFpwCIt5xfPvtt3bHHXfYu+++a/PmzfMWUx+1rd69e5uOyR82SNckneWjDmXMmDHDrrzySq8Lug5OOeWU0C5dd9119uyzz3qfTZ48OWYA/v3333euS7f985//tNGjR9vUqVOdL+na1bV49NFH280332wPP/yw6fyr7bvvvqZrLmxAX1N6DB06NKZP8u/QoYPtsccezvVw6KGHpjTIe+aZZ9onn3zibKtHjx7Odh944AFn325f9Jm2f8QRRzifa4C7KlumoYzXXnvNrrjiCq/rEyZMcMItmd4XuvcmTpzobE/36ZNPPmnvvPOOKQQxZ86cmHtjn332sTPOOMP222+/UDoNzB9zzDHeZ126dLFbb701dNlnnnnGeQ66TdfrIYcc4v09G8+UqM93mN3rr79uI0aMiHmuaL8HHHCADRs2zDp27JhSN2R/33332dy5c+3rr7/21tl2221tl112sYEDB5r/Gkq00bfeesupxPL222/H3A+6x4YMGeIEqLp16+ZtQvfQuHHjEvbzueees0mT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AggggAACRScwd+5cGz16tH3xxRf20UcfxT3+iRMn2t577110PhwwAghkJkAoIzM31kIAAQQQQAABBHIpQCgjl9rsCwEEEEAAAQQQQAABBBBAAAEEEECgKAVefPFF07Qk8ZoqZNx+++126KGHFqUPB40AApkJEMrIzI21EEAAAQQQQACBXAoQysilNvtCAAEEEEAAAQQQQAABBBBAAAEEEChKgdmzZ9uJJ54Yeux9+/a1/v37W5s2bYrShoNGAIHMBQhlZG7HmggggAACCCCAQK4ECGXkSpr9IIAAAggggAACCCCAAAIIIIAAAggUrcD8+fPt3HPPtVatWlnLli2dAMb2229v++yzj5WVlRWtCweOAAKVE5gyZYrp+eK2AQMGWHl5eeU2ytoIIIAAAggggAACkQoQyoiUk40hgAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAK/CxDK4EpAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQSyIEAoIwuobBIBBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEECCUwTWAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAghkQYBQRhZQ2SQCCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIEAog2sAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBDIggChjCygskkEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQIBQBtcAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCQBQFCGVlAZZMIIIAAAggggAACCCCAAAIIIIAAAggggAACCCCAAAIIIIAAAggggMD/A+fuCGi+euw/AAAAAElFTkSuQmCC" - } - }, + "attachments": {}, "cell_type": "markdown", "id": "51466c8d-8ce4-4b3d-be4e-18fdbeda5f53", "metadata": {}, "source": [ "# How to wait for user input\n", "\n", + "!!! tip \"Prerequisits\"\n", + "\n", + " This guide assumes familiarity with the following concepts:\n", + "\n", + " * [Human-in-the-loop](../../../concepts/human_in_the_loop)\n", + " * [Breakpoints](../../../concepts/breakpoints)\n", + " * [LangGraph Glossary](../../../concepts/low_level)\n", + " \n", + "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). Waiting for human input is a common HIL interaction pattern, allowing the agent to ask the user clarifying questions and await input before proceeding. \n", "\n", - "We can implement this in LangGraph using a [breakpoint](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/breakpoints/): breakpoints allow us to stop graph execution at a specific step. At this breakpoint, we can wait for human input. Once we have input from the user, we can add it to the graph state and proceed.\n", - "\n", - "![wait_for_input.png](attachment:f6c5e4f7-4e60-4085-95ad-6edeaeb902e0.png)" + "We can implement this in LangGraph using a [breakpoint](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/breakpoints/): breakpoints allow us to stop graph execution at a specific step. At this breakpoint, we can wait for human input. Once we have input from the user, we can add it to the graph state and proceed." ] }, { @@ -642,7 +645,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.8" + "version": "3.11.4" } }, "nbformat": 4, From 61f362f16e3088da2d191a28b2814caad0102cd8 Mon Sep 17 00:00:00 2001 From: vbarda Date: Tue, 10 Dec 2024 14:07:08 -0500 Subject: [PATCH 33/72] update dynamic breakpoints --- .../how-tos/human_in_the_loop/dynamic_breakpoints.ipynb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb index 9de44a77c..6f0704017 100644 --- a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb @@ -6,7 +6,11 @@ "id": "b7d5f6a5-9e59-43e4-a4b6-8ada6dace691", "metadata": {}, "source": [ - "# How to add dynamic breakpoints\n", + "# How to add dynamic breakpoints with `NodeInterrupt`\n", + "\n", + "!!! note\n", + "\n", + " Current recommended way to add dynamic breakpoints is using [`interrupt()`][langgraph.types.interrupt] API. See this [how-to guide](../interrupt) to learn more.\n", "\n", "!!! tip \"Prerequisits\"\n", "\n", @@ -22,6 +26,7 @@ "\n", "This guide shows how you can dynamically interrupt the graph using `NodeInterrupt` -- a special exception that can be raised from inside a node. Let's see it in action!\n", "\n", + "\n", "## Setup\n", "\n", "First, let's install the required packages" @@ -433,7 +438,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.12.3" } }, "nbformat": 4, From e14a6cf98bac03e42699ffe8f73ef17fadca5140 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 17:06:08 -0500 Subject: [PATCH 34/72] Add multi turn conversation input --- docs/docs/how-tos/index.md | 3 + .../multi-agent-multi-turn-convo.ipynb | 377 ++++++++++++++++++ 2 files changed, 380 insertions(+) create mode 100644 docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index d93488d94..0f01fb73b 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -94,7 +94,10 @@ These how-to guides show common patterns for tool calling with LangGraph: ### Multi-agent +[Multi-agent systems](../concepts/multi_agent.md) are useful to break down complex LLM applications into multiple agents, each responsible for a different part of the application. These how-to guides show how to implement multi-agent systems in LangGraph: + - [How to build a multi-agent network](multi-agent-network.ipynb) +- [How to add multi-turn conversation in a multi-agent application](multi-agent-multi-turn-convo.ipynb) See the [multi-agent tutorials](../tutorials/index.md#multi-agent-systems) for implementations of other multi-agent architectures. diff --git a/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb new file mode 100644 index 000000000..98cc4ba64 --- /dev/null +++ b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb @@ -0,0 +1,377 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "a2b182eb-1e31-43c8-85b1-706508dfa370", + "metadata": {}, + "source": [ + "# How to add multi-turn conversation in a multi-agent application\n", + "\n", + "!!! info \"Prerequisites\"\n", + " This guide assumes familiarity with the following:\n", + "\n", + " - [Node](../../concepts/low_level/#nodes)\n", + " - [Command](../../concepts/low_level/#command)\n", + " - [Multi-agent systems](../../concepts/multi_agent)\n", + " - [Human-in-the-loop](../../concepts/human_in_the_loop)\n", + "\n", + "\n", + "In this how-to guide, we’ll build an application that allows an end-user to engage in a *multi-turn conversation* with one or more agents. We'll create a node that uses an [`interrupt`](../../reference/types/#langgraph.types.interrupt) to collect user input and routes back to the **active** agent.\n", + "\n", + "The agents will be implemented as nodes in a graph that executes agent steps and determines the next action: \n", + "\n", + "1. **Wait for user input** to continue the conversation, or \n", + "2. **Route to another agent** (or back to itself, such as in a loop) via a [**handoff**](../../concepts/multi_agent/#handoffs).\n", + "\n", + "```python\n", + "def human(state: MessagesState) -> Command[Literal[\"agent\", \"another_agent\"]]:\n", + " \"\"\"A node for collecting user input.\"\"\"\n", + " user_input = interrupt(value=\"Ready for user input.\")\n", + "\n", + " # Determine the active agent.\n", + " active_agent = ...\n", + "\n", + " ...\n", + " return Command(\n", + " update={\n", + " \"messages\": [{\n", + " \"role\": \"human\",\n", + " \"content\": user_input,\n", + " }]\n", + " },\n", + " goto=active_agent,\n", + "\n", + "def agent(state) -> Command[Literal[\"agent\", \"another_agent\", \"human\"]]:\n", + " # The condition for routing/halting can be anything, e.g. LLM tool call / structured output, etc.\n", + " goto = get_next_agent(...) # 'agent' / 'another_agent'\n", + " if goto:\n", + " return Command(goto=goto, update={\"my_state_key\": \"my_state_value\"})\n", + " else:\n", + " return Command(goto=\"human\") # Go to human node\n", + " )\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "faaa4444-cd06-4813-b9ca-c9700fe12cb7", + "metadata": {}, + "source": [ + "## Setup\n", + "\n", + "First, let's install the required packages" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "05038da0-31df-4066-a1a4-c4ccb5db4d3a", + "metadata": {}, + "outputs": [], + "source": [ + "%%capture --no-stderr\n", + "%pip install -U langgraph langchain-openai" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "id": "0bcff5d4-130e-426d-9285-40d0f72c7cd3", + "metadata": {}, + "outputs": [], + "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", + "id": "c3ec6e48-85dc-4905-ba50-985e5d4788e6", + "metadata": {}, + "source": [ + "" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "6696b398-559d-4250-bb76-ebb7c97ce5f3", + "metadata": {}, + "source": [ + "## Travel Recommendations Example\n", + "\n", + "In this example, we will build a team of travel assistant agents that can communicate with each other via handoffs.\n", + "\n", + "We will create 3 agents:\n", + "\n", + "* `travel_advisor`: can help with general travel destination recommendations. Can ask `sightseeing_advisor` and `hotel_advisor` for help.\n", + "* `sightseeing_advisor`: can help with sightseeing recommendations. Can ask `travel_advisor` and `hotel_advisor` for help.\n", + "* `hotel_advisor`: can help with hotel recommendations. Can ask `sightseeing_advisor` and `hotel_advisor` for help.\n", + "\n", + "This is a fully-connected network - every agent can talk to any other agent. \n", + "\n", + "To implement the handoffs between the agents we'll be using LLMs with structured output. Each agent's LLM will return an output with both its text response (`response`) as well as which agent to route to next (`goto`). If the agent has enough information to respond to the user, the `goto` will be set to `human` to route back and collect information from a human.\n", + "\n", + "Now, let's define our agent nodes and graph!" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "id": "aa4bdbff-9461-46cc-aee9-8a22d3c3d9ec", + "metadata": {}, + "outputs": [], + "source": [ + "from typing_extensions import TypedDict, Literal\n", + "\n", + "from langchain_openai import ChatOpenAI\n", + "from langchain_core.messages import HumanMessage\n", + "from langgraph.graph import MessagesState, StateGraph, START, END\n", + "from langgraph.types import Command, interrupt\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "from langgraph.prebuilt import create_react_agent\n", + "\n", + "model = ChatOpenAI(model=\"gpt-4o\")\n", + "\n", + "\n", + "def make_agent_node(*, name: str, destinations: list[str], system_prompt: str):\n", + " def agent_node(state: MessagesState) -> Command[Literal[*destinations, \"human\"]]:\n", + " # define schema for the structured output:\n", + " # - model's text response (`response`)\n", + " # - name of the node to go to next (or 'finish')\n", + " class Response(TypedDict):\n", + " response: str\n", + " goto: Literal[*destinations, \"finish\"]\n", + "\n", + " messages = [{\"role\": \"system\", \"content\": system_prompt}] + state[\"messages\"]\n", + " response = model.with_structured_output(Response).invoke(messages)\n", + " goto = response[\"goto\"]\n", + " if goto == \"finish\":\n", + " # When the agent is done, we should go to the \n", + " goto = \"human\"\n", + "\n", + " # Handoff to another agent or halt\n", + " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": name}\n", + " return Command(goto=goto, update={\"messages\": [ai_msg]})\n", + " return agent_node\n", + "\n", + "\n", + "travel_advisor = make_agent_node(\n", + " name=\"travel_advisor\",\n", + " destinations=[\"sightseeing_advisor\", \"hotel_advisor\", \"human\"],\n", + " system_prompt=(\n", + " \"You are a general travel expert that can recommend travel destinations (e.g. countries, cities, etc). \"\n", + " \"If you need specific sightseeing recommendations, ask 'sightseeing_advisor' for help. \"\n", + " \"If you need hotel recommendations, ask 'hotel_advisor' for help. \"\n", + " \"If you have enough information to respond to the user, return 'finish'. \"\n", + " \"Never mention other agents by name.\"\n", + " ),\n", + ")\n", + "sightseeing_advisor = make_agent_node(\n", + " name=\"sightseeing_advisor\",\n", + " destinations=[\"travel_advisor\", \"hotel_advisor\", \"human\"],\n", + " system_prompt=(\n", + " \"You are a travel expert that can provide specific sightseeing recommendations for a given destination. \"\n", + " \"If you need general travel help, go to 'travel_advisor' for help. \"\n", + " \"If you need hotel recommendations, go to 'hotel_advisor' for help. \"\n", + " \"If you have enough information to respond to the user, return 'finish'. \"\n", + " \"Never mention other agents by name.\"\n", + " ),\n", + ")\n", + "hotel_advisor = make_agent_node(\n", + " name=\"hotel_advisor\",\n", + " destinations=[\"travel_advisor\", \"sightseeing_advisor\", \"human\"],\n", + " system_prompt=(\n", + " \"You are a travel expert that can provide hotel recommendations for a given destination. \"\n", + " \"If you need general travel help, ask 'travel_advisor' for help. \"\n", + " \"If you need specific sightseeing recommendations, ask 'sightseeing_advisor' for help. \"\n", + " \"If you have enough information to respond to the user, return 'finish'. \"\n", + " \"Never mention other agents by name.\"\n", + " ),\n", + ")\n", + "\n", + "def human_node(state: MessagesState) -> Command[Literal[\"hotel_advisor\", \"sightseeing_advisor\", \"travel_advisor\", \"human\"]]:\n", + " \"\"\"A node for collecting user input.\"\"\"\n", + " user_input = interrupt(value=\"Ready for user input.\")\n", + "\n", + " active_agent = None\n", + "\n", + " # This will look up the active agent.\n", + " for message in state['messages'][::-1]:\n", + " if message.name:\n", + " active_agent = message.name\n", + " break\n", + " else:\n", + " raise AssertionError(f'Could not determine the active agent.')\n", + " \n", + " return Command(\n", + " update={\n", + " \"messages\": [{\n", + " \"role\": \"human\",\n", + " \"content\": user_input,\n", + " }]\n", + " },\n", + " goto=active_agent,\n", + " )\n", + " \n", + "\n", + "builder = StateGraph(MessagesState)\n", + "builder.add_node(\"travel_advisor\", travel_advisor)\n", + "builder.add_node(\"sightseeing_advisor\", sightseeing_advisor)\n", + "builder.add_node(\"hotel_advisor\", hotel_advisor)\n", + "\n", + "# This adds a node to collet human input, which will route \n", + "# back to the active agent.\n", + "builder.add_node(\"human\", human_node)\n", + "\n", + "# We'll always start with a general travel advisor.\n", + "builder.add_edge(START, \"travel_advisor\")\n", + "\n", + "\n", + "checkpointer = MemorySaver()\n", + "graph = builder.compile(checkpointer=checkpointer)" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "id": "d77921f6-599d-443f-8b15-56b1adafd3a8", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from IPython.display import display, Image\n", + "\n", + "display(Image(graph.get_graph().draw_mermaid_png()))" + ] + }, + { + "cell_type": "markdown", + "id": "af856e1b-41fc-4041-8cbf-3818a60088e0", + "metadata": {}, + "source": [ + "### Test multi-turn conversation\n", + "\n", + "Let's test a multi turn conversation with this application." + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "id": "161e0cf1-d13a-4026-8f89-bdab67d1ad4d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- Conversation Turn 1 ---\n", + "\n", + "User: {'messages': [{'role': 'user', 'content': 'i wanna go somewhere warm in the caribbean'}]}\n", + "\n", + "travel_advisor: The Caribbean is full of warm and beautiful destinations. Some popular options include Jamaica, the Bahamas, the Dominican Republic, and Aruba. Each of these places offers stunning beaches, vibrant culture, and plenty of activities to enjoy. Would you like recommendations on sightseeing or accommodations in any specific location?\n", + "\n", + "--- Conversation Turn 2 ---\n", + "\n", + "User: Command(resume='could you recommend a nice hotel in one of the areas and tell me which area it is.')\n", + "\n", + "travel_advisor: I'll get a hotel recommendation for you.\n", + "hotel_advisor: I recommend the \"Half Moon Resort\" located in Montego Bay, Jamaica. It's a luxurious resort known for its beautiful private beaches, excellent service, and a variety of amenities including golf, spas, and fine dining. Montego Bay is a vibrant area offering plenty of activities, from snorkeling and diving to exploring local culture and nightlife.\n", + "\n", + "--- Conversation Turn 3 ---\n", + "\n", + "User: Command(resume='could you recommend something to do near the hotel?')\n", + "\n", + "hotel_advisor: I recommend visiting the Rose Hall Great House, a historic plantation house located near Montego Bay. It's known for its intriguing history and beautiful architecture, offering guided tours that include tales of the White Witch of Rose Hall. Additionally, you could explore Dunn's River Falls, a stunning natural waterfall that you can climb, located a bit further but well worth the trip. For a more relaxing day, you might enjoy a catamaran cruise along the coast, which often includes snorkeling stops and beautiful sunset views.\n" + ] + } + ], + "source": [ + "import uuid\n", + "\n", + "thread_config = {\n", + " \"configurable\": {\n", + " \"thread_id\": uuid.uuid4()\n", + " }\n", + "}\n", + "\n", + "inputs = [\n", + " # 1st round of conversation,\n", + " {\"messages\": [{\n", + " \"role\": \"user\", \n", + " \"content\": \"i wanna go somewhere warm in the caribbean\"\n", + " }]},\n", + " # Since we're using `interrupt`, we'll need to resume using the Command primitive.\n", + " # 2nd round of conversation,\n", + " Command(resume=\"could you recommend a nice hotel in one of the areas and tell me which area it is.\"),\n", + " # 3rd round of conversation,\n", + " Command(resume=\"could you recommend something to do near the hotel?\"),\n", + "]\n", + "\n", + "for idx, user_input in enumerate(inputs):\n", + " print()\n", + " print(f'--- Conversation Turn {idx + 1} ---')\n", + " print()\n", + " print(f\"User: {user_input}\")\n", + " print()\n", + " for update in graph.stream(\n", + " user_input,\n", + " config=thread_config,\n", + " stream_mode='updates',\n", + " ):\n", + " for node_id, value in update.items():\n", + " if isinstance(value, dict) and value.get('messages', []):\n", + " last_message = value['messages'][-1]\n", + " if last_message['role'] != \"ai\":\n", + " continue\n", + " print(f\"{last_message['name']}: {last_message['content']}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 81436ceef88a9e3d2458dd596cfbd475ffdcca64 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 17:22:22 -0500 Subject: [PATCH 35/72] x --- docs/docs/how-tos/human_in_the_loop/interrupt.ipynb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index 92c94e4a6..a4877deaf 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -11,17 +11,18 @@ "tags": [] }, "source": [ - "# How to use add breakpoints using interrupt?\n", + "# How to use interrupt for human-in-the-loop?\n", "\n", "!!! tip \"Prerequisits\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", "\n", " * [Breakpoints](../../../concepts/breakpoints)\n", - " * [LangGraph Glossary](../../../concepts/low_level)\n", + " * [Interrupt](../../../concepts/low_level#interrupt)\n", + " * [Command](../../../concepts/low_level#command)\n", " \n", "\n", - "An `interrupt` is a convenient way to support human-in-the-loop workflows.\n", + "An [interrupt]( is a convenient way to support human-in-the-loop workflows.\n", "\n", "To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state.\n", "\n", From 79aa88812de8e75860b522cb43fc12c4f58f342c Mon Sep 17 00:00:00 2001 From: Vadym Barda Date: Tue, 10 Dec 2024 17:38:48 -0500 Subject: [PATCH 36/72] docs: update reivew tool calls how-to (#2700) --- .../human_in_the_loop/review-tool-calls.ipynb | 423 +++++++++++------- 1 file changed, 251 insertions(+), 172 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb index bdffd2733..c1653f0e1 100644 --- a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb @@ -12,12 +12,11 @@ "\n", " This guide assumes familiarity with the following concepts:\n", "\n", - " * [Tool calling])(https://python.langchain.com/docs/concepts/tool_calling/)\n", + " * [Tool calling](https://python.langchain.com/docs/concepts/tool_calling/)\n", " * [Human-in-the-loop](../../../concepts/human_in_the_loop)\n", - " * [Breakpoints](../../../concepts/breakpoints\n", " * [LangGraph Glossary](../../../concepts/low_level) \n", "\n", - "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). A common pattern is to add some human in the loop step after certain tool calls. These tool calls often lead to either a function call or saving of some information. Examples include:\n", + "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](../../../concepts/human-in-the-loop). A common pattern is to add some human in the loop step after certain tool calls. These tool calls often lead to either a function call or saving of some information. Examples include:\n", "\n", "- A tool call to execute SQL, which will then be run by the tool\n", "- A tool call to generate a summary, which will then be saved to the State of the graph\n", @@ -28,9 +27,42 @@ "\n", "1. Approve the tool call and continue\n", "2. Modify the tool call manually and then continue\n", - "3. Give natural language feedback, and then pass that back to the agent instead of continuing\n", + "3. Give natural language feedback, and then pass that back to the agent\n", "\n", - "We can implement this in LangGraph using a [breakpoint](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/breakpoints/): breakpoints allow us to interrupt graph execution before a specific step. At this breakpoint, we can manually update the graph state taking one of the three options above" + "\n", + "We can implement these in LangGraph using a [`interrupt()`][langgraph.types.interrupt]. `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input:\n", + "\n", + "\n", + "```python\n", + "def human_review_node(state) -> Command[Literal[\"call_llm\", \"run_tool\"]]:\n", + " # this is the value we'll be providing via Command(resume=)\n", + " human_review = interrupt(\n", + " {\n", + " \"question\": \"Is this correct?\",\n", + " # Surface tool calls for review\n", + " \"tool_call\": tool_call\n", + " }\n", + " )\n", + " \n", + " review_action, review_data = human_review\n", + " \n", + " # Approve the tool call and continue\n", + " if review_data == \"approve\":\n", + " return Command(goto=\"run_tool\")\n", + " \n", + " # Modify the tool call manually and then continue\n", + " elif review_action == \"update\":\n", + " ...\n", + " updated_msg = get_updated_msg(review_data)\n", + " return Command(goto=\"run_tool\", update={\"messages\": [updated_message]})\n", + "\n", + " # Give natural language feedback, and then pass that back to the agent\n", + " elif review_action == \"feedback\":\n", + " ...\n", + " feedback_msg = get_feedback_msg(review_data)\n", + " return Command(goto=\"call_llm\", update={\"messages\": [feedback_msg]})\n", + "\n", + "```" ] }, { @@ -67,7 +99,15 @@ "execution_count": 2, "id": "c903a1cf-2977-4e2d-ad7d-8b3946821d89", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ANTHROPIC_API_KEY: ········\n" + ] + } + ], "source": [ "import getpass\n", "import os\n", @@ -111,13 +151,13 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "id": "85e452f8-f33a-4ead-bb4d-7386cdba8edc", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "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", + "image/png": "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", "text/plain": [ "" ] @@ -130,6 +170,7 @@ "from typing_extensions import TypedDict, Literal\n", "from langgraph.graph import StateGraph, START, END, MessagesState\n", "from langgraph.checkpoint.memory import MemorySaver\n", + "from langgraph.types import Command, interrupt\n", "from langchain_anthropic import ChatAnthropic\n", "from langchain_core.tools import tool\n", "from langchain_core.messages import AIMessage\n", @@ -145,7 +186,7 @@ " return \"Sunny!\"\n", "\n", "\n", - "model = ChatAnthropic(model_name=\"claude-3-5-sonnet-20240620\").bind_tools(\n", + "model = ChatAnthropic(model_name=\"claude-3-5-sonnet-latest\").bind_tools(\n", " [weather_search]\n", ")\n", "\n", @@ -158,8 +199,58 @@ " return {\"messages\": [model.invoke(state[\"messages\"])]}\n", "\n", "\n", - "def human_review_node(state):\n", - " pass\n", + "def human_review_node(state) -> Command[Literal[\"call_llm\", \"run_tool\"]]:\n", + " last_message = state[\"messages\"][-1]\n", + " tool_call = last_message.tool_calls[-1]\n", + "\n", + " # this is the value we'll be providing via Command(resume=)\n", + " human_review = interrupt(\n", + " {\n", + " \"question\": \"Is this correct?\",\n", + " # Surface tool calls for review\n", + " \"tool_call\": tool_call\n", + " }\n", + " )\n", + " \n", + " review_action = human_review[\"action\"]\n", + " review_data = human_review.get(\"data\")\n", + "\n", + " # if approved, call the tool\n", + " if review_action == \"continue\":\n", + " return Command(goto=\"run_tool\")\n", + " \n", + " # update the AI message AND call tools\n", + " elif review_action == \"update\":\n", + " updated_message = {\n", + " \"role\": \"ai\",\n", + " \"content\": last_message.content,\n", + " \"tool_calls\": [\n", + " {\n", + " \"id\": tool_call[\"id\"],\n", + " \"name\": tool_call[\"name\"],\n", + " # This the update provided by the human\n", + " \"args\": review_data,\n", + " }\n", + " ],\n", + " # This is important - this needs to be the same as the message you replacing!\n", + " # Otherwise, it will show up as a separate message\n", + " \"id\": last_message.id,\n", + " }\n", + " return Command(goto=\"run_tool\", update={\"messages\": [updated_message]})\n", + "\n", + " # provide feedback to LLM\n", + " elif review_action == \"feedback\":\n", + " # NOTE: we're adding feedback message as a ToolMessage\n", + " # to preserve the correct order in the message history\n", + " # (AI messages with tool calls need to be followed by tool call messages)\n", + " tool_message = {\n", + " \"role\": \"tool\",\n", + " # This is our natural language feedback\n", + " \"content\": review_data,\n", + " \"name\": tool_call[\"name\"],\n", + " \"tool_call_id\": tool_call[\"id\"],\n", + " }\n", + " return Command(goto=\"call_llm\", update={\"messages\": [tool_message]})\n", "\n", "\n", "def run_tool(state):\n", @@ -187,27 +278,19 @@ " return \"human_review_node\"\n", "\n", "\n", - "def route_after_human(state) -> Literal[\"run_tool\", \"call_llm\"]:\n", - " if isinstance(state[\"messages\"][-1], AIMessage):\n", - " return \"run_tool\"\n", - " else:\n", - " return \"call_llm\"\n", - "\n", - "\n", "builder = StateGraph(State)\n", "builder.add_node(call_llm)\n", "builder.add_node(run_tool)\n", "builder.add_node(human_review_node)\n", "builder.add_edge(START, \"call_llm\")\n", "builder.add_conditional_edges(\"call_llm\", route_after_llm)\n", - "builder.add_conditional_edges(\"human_review_node\", route_after_human)\n", "builder.add_edge(\"run_tool\", \"call_llm\")\n", "\n", "# Set up memory\n", "memory = MemorySaver()\n", "\n", "# Add\n", - "graph = builder.compile(checkpointer=memory, interrupt_before=[\"human_review_node\"])\n", + "graph = builder.compile(checkpointer=memory)\n", "\n", "# View\n", "display(Image(graph.get_graph().draw_mermaid_png()))" @@ -225,7 +308,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "id": "1b3aa6fc-c7fb-4819-8d7f-ba6057cc4edf", "metadata": {}, "outputs": [ @@ -233,8 +316,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'messages': [HumanMessage(content='hi!', id='393fa21d-4bfb-445b-8faa-78e22b92e346')]}\n", - "{'messages': [HumanMessage(content='hi!', id='393fa21d-4bfb-445b-8faa-78e22b92e346'), AIMessage(content=\"Hello! Welcome to our conversation. How can I assist you today? Is there anything specific you'd like to know or discuss?\", response_metadata={'id': 'msg_017S671xYvZm1mi9EcsKvPzF', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 355, 'output_tokens': 29}}, id='run-8ec507a1-5caf-47d6-89eb-1a2e8f38423c-0', usage_metadata={'input_tokens': 355, 'output_tokens': 29, 'total_tokens': 384})]}\n" + "{'call_llm': {'messages': [AIMessage(content=\"Hello! I'm here to help you. I can assist you with checking the weather in different cities using the weather search tool. Would you like to know the weather for a specific city? Just let me know which city you're interested in!\", additional_kwargs={}, response_metadata={'id': 'msg_01XHvA3ZWpsq4PdyiruWFLBs', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 374, 'output_tokens': 52}}, id='run-c3ff5fea-0135-4d66-8ec1-f8ed6a88356b-0', usage_metadata={'input_tokens': 374, 'output_tokens': 52, 'total_tokens': 426, 'input_token_details': {}})]}}\n", + "\n", + "\n" ] } ], @@ -246,8 +330,9 @@ "thread = {\"configurable\": {\"thread_id\": \"1\"}}\n", "\n", "# Run the graph until the first interruption\n", - "for event in graph.stream(initial_input, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(initial_input, thread, stream_mode=\"updates\"):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { @@ -258,26 +343,6 @@ "If we check the state, we can see that it is finished" ] }, - { - "cell_type": "code", - "execution_count": 3, - "id": "213323cc-0320-4313-ab11-19042e28b495", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Pending Executions!\n", - "()\n" - ] - } - ], - "source": [ - "print(\"Pending Executions!\")\n", - "print(graph.get_state(thread).next)" - ] - }, { "cell_type": "markdown", "id": "5c1985f7-54f1-420f-a2b6-5e6154909966", @@ -290,7 +355,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "2561a38f-edb5-4b44-b2d7-6a7b70d2e6b7", "metadata": {}, "outputs": [ @@ -298,8 +363,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='8bda37cc-4bd3-4a14-bca5-b992934e710b')]}\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='8bda37cc-4bd3-4a14-bca5-b992934e710b'), AIMessage(content=[{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text'}, {'id': 'toolu_01MW3ETLpq4b8s6VaAMgDBZP', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_019FjC1prjVv8BuQX7DmF65F', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 80}}, id='run-1b580410-173c-4fe0-a149-22e8f516b259-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01MW3ETLpq4b8s6VaAMgDBZP', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440})]}\n" + "{'call_llm': {'messages': [AIMessage(content=[{'text': \"I'll help you check the weather in San Francisco.\", 'type': 'text'}, {'id': 'toolu_01Kn67GmQAA3BEF1cfYdNW3c', 'input': {'city': 'sf'}, 'name': 'weather_search', 'type': 'tool_use'}], additional_kwargs={}, response_metadata={'id': 'msg_013eJXUAEA2ANvYLkDUQFRPo', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 379, 'output_tokens': 65}}, id='run-e8174b94-f681-4688-967f-a32295412f91-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'sf'}, 'id': 'toolu_01Kn67GmQAA3BEF1cfYdNW3c', 'type': 'tool_call'}], usage_metadata={'input_tokens': 379, 'output_tokens': 65, 'total_tokens': 444, 'input_token_details': {}})]}}\n", + "\n", + "\n", + "{'__interrupt__': (Interrupt(value={'question': 'Is this correct?', 'tool_call': {'name': 'weather_search', 'args': {'city': 'sf'}, 'id': 'toolu_01Kn67GmQAA3BEF1cfYdNW3c', 'type': 'tool_call'}}, resumable=True, ns=['human_review_node:be252162-5b29-0a98-1ed2-c807c1fc64c6'], when='during'),)}\n", + "\n", + "\n" ] } ], @@ -311,8 +380,9 @@ "thread = {\"configurable\": {\"thread_id\": \"2\"}}\n", "\n", "# Run the graph until the first interruption\n", - "for event in graph.stream(initial_input, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(initial_input, thread, stream_mode=\"updates\"):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { @@ -325,7 +395,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "33d68f0f-d435-4dd1-8013-6a59186dc9f5", "metadata": {}, "outputs": [ @@ -348,12 +418,12 @@ "id": "14c99fdd-4204-4c2d-b1af-02f38ab6ad57", "metadata": {}, "source": [ - "To approve the tool call, we can just continue the thread with no edits. To do this, we just create a new run with no inputs." + "To approve the tool call, we can just continue the thread with no edits. To do so, we need to let `human_review_node` know what value to use for the `human_review` variable we defined inside the node. We can provide this value by invoking the graph with a `Command(resume=)` input. Since we're approving the tool call, we'll provide `resume` value of `{\"action\": \"continue\"}` to navigate to `run_tool` node:" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "f9a0d5d4-52ff-49e0-a6f4-41f9a0e844d8", "metadata": {}, "outputs": [ @@ -361,17 +431,30 @@ "name": "stdout", "output_type": "stream", "text": [ + "{'human_review_node': None}\n", + "\n", + "\n", "----\n", - "Searching for: San Francisco\n", + "Searching for: sf\n", "----\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='8bda37cc-4bd3-4a14-bca5-b992934e710b'), AIMessage(content=[{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text'}, {'id': 'toolu_01MW3ETLpq4b8s6VaAMgDBZP', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_019FjC1prjVv8BuQX7DmF65F', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 80}}, id='run-1b580410-173c-4fe0-a149-22e8f516b259-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01MW3ETLpq4b8s6VaAMgDBZP', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}), ToolMessage(content='Sunny!', name='weather_search', id='835b0fe3-8aa0-45d5-ac29-03bbe57cc767', tool_call_id='toolu_01MW3ETLpq4b8s6VaAMgDBZP')]}\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='8bda37cc-4bd3-4a14-bca5-b992934e710b'), AIMessage(content=[{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text'}, {'id': 'toolu_01MW3ETLpq4b8s6VaAMgDBZP', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_019FjC1prjVv8BuQX7DmF65F', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 80}}, id='run-1b580410-173c-4fe0-a149-22e8f516b259-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01MW3ETLpq4b8s6VaAMgDBZP', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}), ToolMessage(content='Sunny!', name='weather_search', id='835b0fe3-8aa0-45d5-ac29-03bbe57cc767', tool_call_id='toolu_01MW3ETLpq4b8s6VaAMgDBZP'), AIMessage(content=\"Based on the search results, the weather in San Francisco is sunny! It's a beautiful day in the city. Is there anything else you'd like to know about the weather or any other information I can help you with?\", response_metadata={'id': 'msg_01UY2d6RCzvwagwMb1J5etek', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 453, 'output_tokens': 49}}, id='run-7137f52c-abe6-4dc1-b536-92dd1d9187b0-0', usage_metadata={'input_tokens': 453, 'output_tokens': 49, 'total_tokens': 502})]}\n" + "{'run_tool': {'messages': [{'role': 'tool', 'name': 'weather_search', 'content': 'Sunny!', 'tool_call_id': 'toolu_01Kn67GmQAA3BEF1cfYdNW3c'}]}}\n", + "\n", + "\n", + "{'call_llm': {'messages': [AIMessage(content=\"According to the search, it's sunny in San Francisco today!\", additional_kwargs={}, response_metadata={'id': 'msg_01FJTbC8oK5fkD73rUBmAtUx', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 457, 'output_tokens': 17}}, id='run-c21af72d-3cc5-4b74-bb7c-fbeb8f88bd6d-0', usage_metadata={'input_tokens': 457, 'output_tokens': 17, 'total_tokens': 474, 'input_token_details': {}})]}}\n", + "\n", + "\n" ] } ], "source": [ - "for event in graph.stream(None, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(\n", + " # provide value \n", + " Command(resume={\"action\": \"continue\"}), \n", + " thread,\n", + " stream_mode=\"updates\"\n", + "):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { @@ -386,7 +469,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "ec77831c-e6b8-4903-9146-e098a4b2fda1", "metadata": {}, "outputs": [ @@ -394,8 +477,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='0c488edd-7b9c-4416-ba02-8a2d7e9f2597')]}\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='0c488edd-7b9c-4416-ba02-8a2d7e9f2597'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get this information, I'll use the weather search tool. Let me fetch that for you.\", 'type': 'text'}, {'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_01Mv7iqdtPgZEX2LiBBqWDuY', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 88}}, id='run-52a09799-efb5-4fff-82c3-884e20119ad3-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 88, 'total_tokens': 448})]}\n" + "{'call_llm': {'messages': [AIMessage(content=[{'text': \"I'll help you check the weather in San Francisco.\", 'type': 'text'}, {'id': 'toolu_013eUXow3jwM6eekcDJdrjDa', 'input': {'city': 'sf'}, 'name': 'weather_search', 'type': 'tool_use'}], additional_kwargs={}, response_metadata={'id': 'msg_013ruFpCRNZKX3cDeBAH8rEb', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 379, 'output_tokens': 65}}, id='run-13df3982-ce6d-4fe2-9e5c-ea6ce30a63e4-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'sf'}, 'id': 'toolu_013eUXow3jwM6eekcDJdrjDa', 'type': 'tool_call'}], usage_metadata={'input_tokens': 379, 'output_tokens': 65, 'total_tokens': 444, 'input_token_details': {}})]}}\n", + "\n", + "\n", + "{'__interrupt__': (Interrupt(value={'question': 'Is this correct?', 'tool_call': {'name': 'weather_search', 'args': {'city': 'sf'}, 'id': 'toolu_013eUXow3jwM6eekcDJdrjDa', 'type': 'tool_call'}}, resumable=True, ns=['human_review_node:da717c23-60a0-2a1a-45de-cac5cff308bb'], when='during'),)}\n", + "\n", + "\n" ] } ], @@ -404,16 +491,17 @@ "initial_input = {\"messages\": [{\"role\": \"user\", \"content\": \"what's the weather in sf?\"}]}\n", "\n", "# Thread\n", - "thread = {\"configurable\": {\"thread_id\": \"5\"}}\n", + "thread = {\"configurable\": {\"thread_id\": \"3\"}}\n", "\n", "# Run the graph until the first interruption\n", - "for event in graph.stream(initial_input, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(initial_input, thread, stream_mode=\"updates\"):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "edcffbd7-829b-4d0c-88bf-cd531bc0e6b2", "metadata": {}, "outputs": [ @@ -436,72 +524,46 @@ "id": "87358aca-9b8f-48c7-98d4-3d755f6b0104", "metadata": {}, "source": [ - "To do this, we first need to update the state. We can do this by passing a message in with the **same** id of the message we want to overwrite. This will have the effect of **replacing** that old message. Note that this is only possible because of the **reducer** we are using that replaces messages with the same ID - read more about that [here](https://langchain-ai.github.io/langgraph/concepts/low_level/#working-with-messages-in-graph-state)" + "To do this, we will use `Command` with a different resume value of `{\"action\": \"update\", \"data\": }`. This will do the following:\n", + "\n", + "* combine existing tool call with user-provided tool call arguments and update the existing AI message with the new tool call\n", + "* navigate to `run_tool` node with the updated AI message and continue execution" ] }, { "cell_type": "code", - "execution_count": 9, - "id": "df4a9900-d953-4465-b8af-bd2858cb63ea", + "execution_count": 10, + "id": "b2f73998-baae-4c00-8a90-f4153e924941", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Current State:\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='0c488edd-7b9c-4416-ba02-8a2d7e9f2597'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get this information, I'll use the weather search tool. Let me fetch that for you.\", 'type': 'text'}, {'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_01Mv7iqdtPgZEX2LiBBqWDuY', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 88}}, id='run-52a09799-efb5-4fff-82c3-884e20119ad3-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 88, 'total_tokens': 448})]}\n", + "{'human_review_node': {'messages': [{'role': 'ai', 'content': [{'text': \"I'll help you check the weather in San Francisco.\", 'type': 'text'}, {'id': 'toolu_013eUXow3jwM6eekcDJdrjDa', 'input': {'city': 'sf'}, 'name': 'weather_search', 'type': 'tool_use'}], 'tool_calls': [{'id': 'toolu_013eUXow3jwM6eekcDJdrjDa', 'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}}], 'id': 'run-13df3982-ce6d-4fe2-9e5c-ea6ce30a63e4-0'}]}}\n", + "\n", "\n", - "Current Tool Call ID:\n", - "toolu_01CpbVmprQnjxpQzx8MzE1g8\n", "----\n", "Searching for: San Francisco, USA\n", "----\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='0c488edd-7b9c-4416-ba02-8a2d7e9f2597'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get this information, I'll use the weather search tool. Let me fetch that for you.\", 'type': 'text'}, {'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], id='run-52a09799-efb5-4fff-82c3-884e20119ad3-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'type': 'tool_call'}]), ToolMessage(content='Sunny!', name='weather_search', id='ff968b9f-9b87-4893-9f32-dfb88dbe0536', tool_call_id='toolu_01CpbVmprQnjxpQzx8MzE1g8')]}\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='0c488edd-7b9c-4416-ba02-8a2d7e9f2597'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get this information, I'll use the weather search tool. Let me fetch that for you.\", 'type': 'text'}, {'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], id='run-52a09799-efb5-4fff-82c3-884e20119ad3-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01CpbVmprQnjxpQzx8MzE1g8', 'type': 'tool_call'}]), ToolMessage(content='Sunny!', name='weather_search', id='ff968b9f-9b87-4893-9f32-dfb88dbe0536', tool_call_id='toolu_01CpbVmprQnjxpQzx8MzE1g8'), AIMessage(content=\"Great news! The weather in San Francisco is currently sunny. It's a beautiful day in the city by the bay. Is there anything else you'd like to know about the weather or any other information I can help you with?\", response_metadata={'id': 'msg_01PhwUeRWkSJB6kzHZS361XZ', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 464, 'output_tokens': 50}}, id='run-5aebcf37-626e-4675-b225-476bc99bdbb8-0', usage_metadata={'input_tokens': 464, 'output_tokens': 50, 'total_tokens': 514})]}\n" + "{'run_tool': {'messages': [{'role': 'tool', 'name': 'weather_search', 'content': 'Sunny!', 'tool_call_id': 'toolu_013eUXow3jwM6eekcDJdrjDa'}]}}\n", + "\n", + "\n", + "{'call_llm': {'messages': [AIMessage(content=\"According to the search, it's sunny in San Francisco right now!\", additional_kwargs={}, response_metadata={'id': 'msg_01QssVtxXPqr8NWjYjTaiHqN', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 460, 'output_tokens': 18}}, id='run-8ab865c8-cc9e-4300-8e1d-9eb673e8445c-0', usage_metadata={'input_tokens': 460, 'output_tokens': 18, 'total_tokens': 478, 'input_token_details': {}})]}}\n", + "\n", + "\n" ] } ], "source": [ - "# To get the ID of the message we want to replace, we need to fetch the current state and find it there.\n", - "state = graph.get_state(thread)\n", - "print(\"Current State:\")\n", - "print(state.values)\n", - "print(\"\\nCurrent Tool Call ID:\")\n", - "current_content = state.values[\"messages\"][-1].content\n", - "current_id = state.values[\"messages\"][-1].id\n", - "tool_call_id = state.values[\"messages\"][-1].tool_calls[0][\"id\"]\n", - "print(tool_call_id)\n", - "\n", - "# We now need to construct a replacement tool call.\n", - "# We will change the argument to be `San Francisco, USA`\n", - "# Note that we could change any number of arguments or tool names - it just has to be a valid one\n", - "new_message = {\n", - " \"role\": \"assistant\",\n", - " \"content\": current_content,\n", - " \"tool_calls\": [\n", - " {\n", - " \"id\": tool_call_id,\n", - " \"name\": \"weather_search\",\n", - " \"args\": {\"city\": \"San Francisco, USA\"},\n", - " }\n", - " ],\n", - " # This is important - this needs to be the same as the message you replacing!\n", - " # Otherwise, it will show up as a separate message\n", - " \"id\": current_id,\n", - "}\n", - "graph.update_state(\n", - " # This is the config which represents this thread\n", - " thread,\n", - " # This is the updated value we want to push\n", - " {\"messages\": [new_message]},\n", - " # We push this update acting as our human_review_node\n", - " as_node=\"human_review_node\",\n", - ")\n", - "\n", "# Let's now continue executing from here\n", - "for event in graph.stream(None, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(\n", + " Command(resume={\"action\": \"update\", \"data\": {\"city\": \"San Francisco, USA\"}}), \n", + " thread, \n", + " stream_mode=\"updates\"\n", + "):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { @@ -511,21 +573,21 @@ "source": [ "## Give feedback to a tool call\n", "\n", - "Sometimes, you may not want to execute a tool call, but you also may not want to ask the user to manually modify the tool call. In that case it may be better to get natural language feedback from the user. You can then insert these feedback as a mock **RESULT** of the tool call.\n", + "Sometimes, you may not want to execute a tool call, but you also may not want to ask the user to manually modify the tool call. In that case it may be better to get natural language feedback from the user. You can then insert this feedback as a mock **RESULT** of the tool call.\n", "\n", "There are multiple ways to do this:\n", "\n", "1. You could add a new message to the state (representing the \"result\" of a tool call)\n", "2. You could add TWO new messages to the state - one representing an \"error\" from the tool call, other HumanMessage representing the feedback\n", "\n", - "Both are similar in that they involve adding messages to the state. The main difference lies in the logic AFTER the `human_node` and how it handles different types of messages.\n", + "Both are similar in that they involve adding messages to the state. The main difference lies in the logic AFTER the `human_review_node` and how it handles different types of messages.\n", "\n", - "For this example we will just add a single tool call representing the feedback. Let's see this in action!" + "For this example we will just add a single tool call representing the feedback (see `human_review_node` implementation). Let's see this in action!" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "d57d5131-7912-4216-aa87-b7272507fa51", "metadata": {}, "outputs": [ @@ -533,8 +595,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='601c4c75-f506-4d91-896d-5e382123de24')]}\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='601c4c75-f506-4d91-896d-5e382123de24'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get the most accurate and up-to-date information, I'll use the weather search tool. Let me fetch that for you right away.\", 'type': 'text'}, {'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_013nHyPYxNXFSoXeS6q4oWua', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 98}}, id='run-0537e15e-86a4-4c6f-8dfb-6e4c160812c4-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 98, 'total_tokens': 458})]}\n" + "{'call_llm': {'messages': [AIMessage(content=[{'text': \"I'll help you check the weather in San Francisco.\", 'type': 'text'}, {'id': 'toolu_01QxXNTCasnNLQCGAiVoNUBe', 'input': {'city': 'sf'}, 'name': 'weather_search', 'type': 'tool_use'}], additional_kwargs={}, response_metadata={'id': 'msg_01DjwkVxgfqT2K329rGkycx6', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 379, 'output_tokens': 65}}, id='run-c57bee36-9f5f-4d2e-85df-758b56d3cc05-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'sf'}, 'id': 'toolu_01QxXNTCasnNLQCGAiVoNUBe', 'type': 'tool_call'}], usage_metadata={'input_tokens': 379, 'output_tokens': 65, 'total_tokens': 444, 'input_token_details': {}})]}}\n", + "\n", + "\n", + "{'__interrupt__': (Interrupt(value={'question': 'Is this correct?', 'tool_call': {'name': 'weather_search', 'args': {'city': 'sf'}, 'id': 'toolu_01QxXNTCasnNLQCGAiVoNUBe', 'type': 'tool_call'}}, resumable=True, ns=['human_review_node:47a3f541-b630-5f8a-32d7-5a44826d99da'], when='during'),)}\n", + "\n", + "\n" ] } ], @@ -543,16 +609,17 @@ "initial_input = {\"messages\": [{\"role\": \"user\", \"content\": \"what's the weather in sf?\"}]}\n", "\n", "# Thread\n", - "thread = {\"configurable\": {\"thread_id\": \"6\"}}\n", + "thread = {\"configurable\": {\"thread_id\": \"4\"}}\n", "\n", "# Run the graph until the first interruption\n", - "for event in graph.stream(initial_input, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(initial_input, thread, stream_mode=\"updates\"):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "e33ad664-0307-43c5-b85a-1e02eebceb5c", "metadata": {}, "outputs": [ @@ -575,12 +642,15 @@ "id": "483d9455-8625-4c6a-9b98-f731403b2ed3", "metadata": {}, "source": [ - "To do this, we first need to update the state. We can do this by passing a message in with the same **tool call id** of the tool call we want to respond to. Note that this is a **different** ID from above." + "To do this, we will use `Command` with a different resume value of `{\"action\": \"feedback\", \"data\": }`. This will do the following:\n", + "\n", + "* create a new tool message that combines existing tool call from LLM with the with user-provided feedback as content\n", + "* navigate to `call_llm` node with the updated tool message and continue execution" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "3f05f8b6-6128-4de5-8884-862fc93f1227", "metadata": {}, "outputs": [ @@ -588,46 +658,28 @@ "name": "stdout", "output_type": "stream", "text": [ - "Current State:\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='601c4c75-f506-4d91-896d-5e382123de24'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get the most accurate and up-to-date information, I'll use the weather search tool. Let me fetch that for you right away.\", 'type': 'text'}, {'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_013nHyPYxNXFSoXeS6q4oWua', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 98}}, id='run-0537e15e-86a4-4c6f-8dfb-6e4c160812c4-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 98, 'total_tokens': 458})]}\n", + "{'human_review_node': {'messages': [{'role': 'tool', 'content': 'User requested changes: use format for location', 'name': 'weather_search', 'tool_call_id': 'toolu_01QxXNTCasnNLQCGAiVoNUBe'}]}}\n", "\n", - "Current Tool Call ID:\n", - "toolu_014UTKh5uqfc885Fj4RRqGdg\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='601c4c75-f506-4d91-896d-5e382123de24'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get the most accurate and up-to-date information, I'll use the weather search tool. Let me fetch that for you right away.\", 'type': 'text'}, {'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_013nHyPYxNXFSoXeS6q4oWua', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 98}}, id='run-0537e15e-86a4-4c6f-8dfb-6e4c160812c4-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 98, 'total_tokens': 458}), ToolMessage(content='User requested changes: pass in the country as well', name='weather_search', id='e20ceddc-a0d3-469d-b31e-512f3042a07e', tool_call_id='toolu_014UTKh5uqfc885Fj4RRqGdg'), AIMessage(content=[{'text': \"I apologize for the oversight. It seems that the weather search function requires more specific information. Let's try again with a more detailed search, including the country. Since San Francisco is commonly associated with the one in California, USA, I'll use that. Here's the updated search:\", 'type': 'text'}, {'id': 'toolu_01AaipBbWDLjHnPcoApx8wRq', 'input': {'city': 'San Francisco, USA'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_018rErqC2cLe2VVhebdJf81e', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 480, 'output_tokens': 116}}, id='run-fcba65ed-400a-4783-9ecd-e22051682399-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01AaipBbWDLjHnPcoApx8wRq', 'type': 'tool_call'}], usage_metadata={'input_tokens': 480, 'output_tokens': 116, 'total_tokens': 596})]}\n" + "\n", + "{'call_llm': {'messages': [AIMessage(content=[{'text': 'Let me try again with the full city name.', 'type': 'text'}, {'id': 'toolu_01WBGTKBWusaPNZYJi5LKmeQ', 'input': {'city': 'San Francisco, USA'}, 'name': 'weather_search', 'type': 'tool_use'}], additional_kwargs={}, response_metadata={'id': 'msg_0141KCdx6KhJmWXyYwAYGvmj', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 468, 'output_tokens': 68}}, id='run-60c8267a-52c7-4b6e-87ca-16aa3bd6266b-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01WBGTKBWusaPNZYJi5LKmeQ', 'type': 'tool_call'}], usage_metadata={'input_tokens': 468, 'output_tokens': 68, 'total_tokens': 536, 'input_token_details': {}})]}}\n", + "\n", + "\n", + "{'__interrupt__': (Interrupt(value={'question': 'Is this correct?', 'tool_call': {'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01WBGTKBWusaPNZYJi5LKmeQ', 'type': 'tool_call'}}, resumable=True, ns=['human_review_node:621fc4a9-bbf1-9a99-f50b-3bf91675234e'], when='during'),)}\n", + "\n", + "\n" ] } ], "source": [ - "# To get the ID of the message we want to replace, we need to fetch the current state and find it there.\n", - "state = graph.get_state(thread)\n", - "print(\"Current State:\")\n", - "print(state.values)\n", - "print(\"\\nCurrent Tool Call ID:\")\n", - "tool_call_id = state.values[\"messages\"][-1].tool_calls[0][\"id\"]\n", - "print(tool_call_id)\n", - "\n", - "# We now need to construct a replacement tool call.\n", - "# We will change the argument to be `San Francisco, USA`\n", - "# Note that we could change any number of arguments or tool names - it just has to be a valid one\n", - "new_message = {\n", - " \"role\": \"tool\",\n", - " # This is our natural language feedback\n", - " \"content\": \"User requested changes: pass in the country as well\",\n", - " \"name\": \"weather_search\",\n", - " \"tool_call_id\": tool_call_id,\n", - "}\n", - "graph.update_state(\n", - " # This is the config which represents this thread\n", - " thread,\n", - " # This is the updated value we want to push\n", - " {\"messages\": [new_message]},\n", - " # We push this update acting as our human_review_node\n", - " as_node=\"human_review_node\",\n", - ")\n", - "\n", "# Let's now continue executing from here\n", - "for event in graph.stream(None, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(\n", + " # provide our natural language feedback!\n", + " Command(resume={\"action\": \"feedback\", \"data\": \"User requested changes: use format for location\"}), \n", + " thread, \n", + " stream_mode=\"updates\"\n", + "):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { @@ -635,13 +687,13 @@ "id": "2d2e79ab-7cdb-42ce-b2ca-2932f8782c90", "metadata": {}, "source": [ - "We can see that we now get to another breakpoint - because it went back to the model and got an entirely new prediction of what to call. Let's now approve this one and continue." + "We can see that we now get to another interrupt - because it went back to the model and got an entirely new prediction of what to call. Let's now approve this one and continue." ] }, { "cell_type": "code", - "execution_count": 13, - "id": "a30d40ad-611d-4ec3-84be-869ea05acb89", + "execution_count": 14, + "id": "ca558915-f4d9-4ff2-95b7-cdaf0c6db485", "metadata": {}, "outputs": [ { @@ -649,21 +701,48 @@ "output_type": "stream", "text": [ "Pending Executions!\n", - "('human_review_node',)\n", - "----\n", - "Searching for: San Francisco, USA\n", - "----\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='601c4c75-f506-4d91-896d-5e382123de24'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get the most accurate and up-to-date information, I'll use the weather search tool. Let me fetch that for you right away.\", 'type': 'text'}, {'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_013nHyPYxNXFSoXeS6q4oWua', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 98}}, id='run-0537e15e-86a4-4c6f-8dfb-6e4c160812c4-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 98, 'total_tokens': 458}), ToolMessage(content='User requested changes: pass in the country as well', name='weather_search', id='e20ceddc-a0d3-469d-b31e-512f3042a07e', tool_call_id='toolu_014UTKh5uqfc885Fj4RRqGdg'), AIMessage(content=[{'text': \"I apologize for the oversight. It seems that the weather search function requires more specific information. Let's try again with a more detailed search, including the country. Since San Francisco is commonly associated with the one in California, USA, I'll use that. Here's the updated search:\", 'type': 'text'}, {'id': 'toolu_01AaipBbWDLjHnPcoApx8wRq', 'input': {'city': 'San Francisco, USA'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_018rErqC2cLe2VVhebdJf81e', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 480, 'output_tokens': 116}}, id='run-fcba65ed-400a-4783-9ecd-e22051682399-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01AaipBbWDLjHnPcoApx8wRq', 'type': 'tool_call'}], usage_metadata={'input_tokens': 480, 'output_tokens': 116, 'total_tokens': 596}), ToolMessage(content='Sunny!', name='weather_search', id='3f3ee262-70f5-422c-8e3f-6a9af758514d', tool_call_id='toolu_01AaipBbWDLjHnPcoApx8wRq')]}\n", - "{'messages': [HumanMessage(content=\"what's the weather in sf?\", id='601c4c75-f506-4d91-896d-5e382123de24'), AIMessage(content=[{'text': \"Certainly! I can help you check the weather in San Francisco. To get the most accurate and up-to-date information, I'll use the weather search tool. Let me fetch that for you right away.\", 'type': 'text'}, {'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'input': {'city': 'San Francisco'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_013nHyPYxNXFSoXeS6q4oWua', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 360, 'output_tokens': 98}}, id='run-0537e15e-86a4-4c6f-8dfb-6e4c160812c4-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_014UTKh5uqfc885Fj4RRqGdg', 'type': 'tool_call'}], usage_metadata={'input_tokens': 360, 'output_tokens': 98, 'total_tokens': 458}), ToolMessage(content='User requested changes: pass in the country as well', name='weather_search', id='e20ceddc-a0d3-469d-b31e-512f3042a07e', tool_call_id='toolu_014UTKh5uqfc885Fj4RRqGdg'), AIMessage(content=[{'text': \"I apologize for the oversight. It seems that the weather search function requires more specific information. Let's try again with a more detailed search, including the country. Since San Francisco is commonly associated with the one in California, USA, I'll use that. Here's the updated search:\", 'type': 'text'}, {'id': 'toolu_01AaipBbWDLjHnPcoApx8wRq', 'input': {'city': 'San Francisco, USA'}, 'name': 'weather_search', 'type': 'tool_use'}], response_metadata={'id': 'msg_018rErqC2cLe2VVhebdJf81e', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 480, 'output_tokens': 116}}, id='run-fcba65ed-400a-4783-9ecd-e22051682399-0', tool_calls=[{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01AaipBbWDLjHnPcoApx8wRq', 'type': 'tool_call'}], usage_metadata={'input_tokens': 480, 'output_tokens': 116, 'total_tokens': 596}), ToolMessage(content='Sunny!', name='weather_search', id='3f3ee262-70f5-422c-8e3f-6a9af758514d', tool_call_id='toolu_01AaipBbWDLjHnPcoApx8wRq'), AIMessage(content=\"Great news! The weather in San Francisco, USA is currently sunny. \\n\\nHere's a summary of the weather information:\\n- Location: San Francisco, USA\\n- Current conditions: Sunny\\n\\nIt's a beautiful day in San Francisco! The sunny weather is perfect for outdoor activities or simply enjoying the city. Remember to wear sunscreen and stay hydrated if you plan to spend time outside. \\n\\nIs there anything else you'd like to know about the weather in San Francisco or any other location?\", response_metadata={'id': 'msg_017Pnjyte2ZXAREgUvEqbUVt', 'model': 'claude-3-5-sonnet-20240620', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 609, 'output_tokens': 107}}, id='run-30c0d0ef-09a3-40ad-b410-80019b284983-0', usage_metadata={'input_tokens': 609, 'output_tokens': 107, 'total_tokens': 716})]}\n" + "('human_review_node',)\n" ] } ], "source": [ "print(\"Pending Executions!\")\n", - "print(graph.get_state(thread).next)\n", - "\n", - "for event in graph.stream(None, thread, stream_mode=\"values\"):\n", - " print(event)" + "print(graph.get_state(thread).next)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a30d40ad-611d-4ec3-84be-869ea05acb89", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'human_review_node': None}\n", + "\n", + "\n", + "----\n", + "Searching for: San Francisco, USA\n", + "----\n", + "{'run_tool': {'messages': [{'role': 'tool', 'name': 'weather_search', 'content': 'Sunny!', 'tool_call_id': 'toolu_01WBGTKBWusaPNZYJi5LKmeQ'}]}}\n", + "\n", + "\n", + "{'call_llm': {'messages': [AIMessage(content='The weather in San Francisco is sunny!', additional_kwargs={}, response_metadata={'id': 'msg_01JrfZd8SYyH51Q8rhZuaC3W', 'model': 'claude-3-5-sonnet-20241022', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 549, 'output_tokens': 12}}, id='run-09a198b2-79fa-484d-9d9d-f12432978488-0', usage_metadata={'input_tokens': 549, 'output_tokens': 12, 'total_tokens': 561, 'input_token_details': {}})]}}\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for event in graph.stream(\n", + " Command(resume={\"action\": \"continue\"}), \n", + " thread, \n", + " stream_mode=\"updates\"\n", + "):\n", + " print(event)\n", + " print(\"\\n\")" ] } ], @@ -683,7 +762,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.12.3" } }, "nbformat": 4, From baa88f3c97b8fbb4bbc2cb2aacd9c728426730f3 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 17:56:48 -0500 Subject: [PATCH 37/72] x --- docs/docs/how-tos/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index 0f01fb73b..d2900ed9d 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -48,8 +48,8 @@ LangGraph makes it easy to manage conversation [memory](../concepts/memory.md) i [Human-in-the-loop](../concepts/human_in_the_loop.md) functionality allows you to involve humans in the decision-making process of your graph. These how-to guides show how to implement human-in-the-loop workflows in your graph. -- [How to add breakpoints](human_in_the_loop/breakpoints.ipynb) -- [How to add dynamic breakpoints](human_in_the_loop/dynamic_breakpoints.ipynb) +- [How to add static breakpoints](human_in_the_loop/breakpoints.ipynb): Use for graph execution step by step. For **human-in-the-loop** workflows, use the new [`interrupt` function](../concepts/human_in_the_loop.md) instead. +- [How to add dynamic breakpoints with `NodeInterrupt` (not recommended)](human_in_the_loop/dynamic_breakpoints.ipynb): This guide shows how to add dynamic breakpoints to your graph using `NodeInterrupt`. Use the new [`interrupt` function](../concepts/human_in_the_loop.md) instead. - [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb) - [How to wait for user input](human_in_the_loop/wait-user-input.ipynb) - [How to view and update past graph state](human_in_the_loop/time-travel.ipynb) From 3a611fb20dffea47552ccf88f74fd6a1868e64bd Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 18:09:07 -0500 Subject: [PATCH 38/72] update dynamic breakpoints --- .../docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb | 5 ++--- docs/docs/how-tos/index.md | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb index 6f0704017..28a974ba0 100644 --- a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb @@ -10,7 +10,7 @@ "\n", "!!! note\n", "\n", - " Current recommended way to add dynamic breakpoints is using [`interrupt()`][langgraph.types.interrupt] API. See this [how-to guide](../interrupt) to learn more.\n", + " For **human-in-the-loop** workflows use the new [`interrupt()`](../../../reference/types/#langgraph.types.interrupt) function for **human-in-the-loop** workflows. Please review the [Human-in-the-loop conceptual guide](../../../concepts/human_in_the_loop) for more information about design patterns with `interrupt`.\n", "\n", "!!! tip \"Prerequisits\"\n", "\n", @@ -18,7 +18,6 @@ "\n", " * [Breakpoints](../../../concepts/breakpoints)\n", " * [LangGraph Glossary](../../../concepts/low_level)\n", - " \n", "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). [Breakpoints](https://langchain-ai.github.io/langgraph/concepts/low_level/#breakpoints) are a common HIL interaction pattern, allowing the graph to stop at specific steps and seek human approval before proceeding (e.g., for sensitive actions).\n", "\n", @@ -438,7 +437,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index d2900ed9d..507962772 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -48,12 +48,12 @@ LangGraph makes it easy to manage conversation [memory](../concepts/memory.md) i [Human-in-the-loop](../concepts/human_in_the_loop.md) functionality allows you to involve humans in the decision-making process of your graph. These how-to guides show how to implement human-in-the-loop workflows in your graph. -- [How to add static breakpoints](human_in_the_loop/breakpoints.ipynb): Use for graph execution step by step. For **human-in-the-loop** workflows, use the new [`interrupt` function](../concepts/human_in_the_loop.md) instead. -- [How to add dynamic breakpoints with `NodeInterrupt` (not recommended)](human_in_the_loop/dynamic_breakpoints.ipynb): This guide shows how to add dynamic breakpoints to your graph using `NodeInterrupt`. Use the new [`interrupt` function](../concepts/human_in_the_loop.md) instead. - [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb) - [How to wait for user input](human_in_the_loop/wait-user-input.ipynb) - [How to view and update past graph state](human_in_the_loop/time-travel.ipynb) - [How to review tool calls](human_in_the_loop/review-tool-calls.ipynb) +- [How to add static breakpoints](human_in_the_loop/breakpoints.ipynb): Use for debugging purposes. For [**human-in-the-loop**](../concepts/human_in_the_loop.md) workflows, we recommend the [`interrupt()`](../../../reference/types/#langgraph.types.interrupt) function instead. +- [How to add dynamic breakpoints with `NodeInterrupt`](human_in_the_loop/dynamic_breakpoints.ipynb): **Not recommended**: Use the [`interrupt` function](../concepts/human_in_the_loop.md) instead. ### Streaming From 47dcb2d105275fa944ddd1e7b4056a5b30a1f0c8 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 18:10:14 -0500 Subject: [PATCH 39/72] x --- docs/docs/how-tos/human_in_the_loop/interrupt.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index a4877deaf..51cb2a165 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -22,7 +22,7 @@ " * [Command](../../../concepts/low_level#command)\n", " \n", "\n", - "An [interrupt]( is a convenient way to support human-in-the-loop workflows.\n", + "An `interrupt` is a convenient way to support human-in-the-loop workflows.\n", "\n", "To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state.\n", "\n", From 686ee31b751c7c0aefcfa07af5904cf745e6f9c3 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 18:10:55 -0500 Subject: [PATCH 40/72] x --- docs/docs/how-tos/human_in_the_loop/interrupt.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb index 51cb2a165..805f01b65 100644 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb @@ -13,7 +13,7 @@ "source": [ "# How to use interrupt for human-in-the-loop?\n", "\n", - "!!! tip \"Prerequisits\"\n", + "!!! tip \"Prerequisites\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", "\n", From f52a8728ff7a48cdd3e1236278435666b38314f4 Mon Sep 17 00:00:00 2001 From: vbarda Date: Tue, 10 Dec 2024 18:19:33 -0500 Subject: [PATCH 41/72] docs: update wait for user input how-to --- .../human_in_the_loop/wait-user-input.ipynb | 255 +++++++----------- 1 file changed, 101 insertions(+), 154 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index ca665342f..c94686136 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -19,7 +19,7 @@ "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). Waiting for human input is a common HIL interaction pattern, allowing the agent to ask the user clarifying questions and await input before proceeding. \n", "\n", - "We can implement this in LangGraph using a [breakpoint](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/breakpoints/): breakpoints allow us to stop graph execution at a specific step. At this breakpoint, we can wait for human input. Once we have input from the user, we can add it to the graph state and proceed." + "We can implement this in LangGraph using a [`interrupt()`][langgraph.types.interrupt]: `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input." ] }, { @@ -40,7 +40,7 @@ "outputs": [], "source": [ "%%capture --no-stderr\n", - "%pip install --quiet -U langgraph langchain_anthropic langchain_openai" + "%pip install --quiet -U langgraph langchain_anthropic" ] }, { @@ -53,10 +53,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "c903a1cf-2977-4e2d-ad7d-8b3946821d89", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ANTHROPIC_API_KEY: ········\n" + ] + } + ], "source": [ "import getpass\n", "import os\n", @@ -67,7 +75,6 @@ " os.environ[var] = getpass.getpass(f\"{var}: \")\n", "\n", "\n", - "_set_env(\"OPENAI_API_KEY\")\n", "_set_env(\"ANTHROPIC_API_KEY\")" ] }, @@ -93,25 +100,22 @@ "\n", "Let's look at very basic usage of this. One intuitive approach is simply to create a node, `human_feedback`, that will get user feedback. This allows us to place our feedback gathering at a specific, chosen point in our graph.\n", " \n", - "1) We specify the [breakpoint](https://langchain-ai.github.io/langgraph/concepts/low_level/#breakpoints) using `interrupt_before` our `human_feedback` node.\n", + "1) We call `interrupt()` inside our `human_feedback` node.\n", "\n", "2) We set up a [checkpointer](https://langchain-ai.github.io/langgraph/concepts/low_level/#checkpointer) to save the state of the graph up until this node.\n", "\n", - "3) We use `.update_state` to update the state of the graph with the human response we get.\n", - "\n", - "* We [use the `as_node` parameter](https://langchain-ai.github.io/langgraph/concepts/low_level/#update-state) to apply this state update as the specified node, `human_feedback`.\n", - "* The graph will then resume execution as if the `human_feedback` node just acted." + "3) We use `Command(resume=...)` to provide the requested value to the human feedback node and resume execution." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "58eae42d-be32-48da-8d0a-ab64471657d9", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "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KGvD91xaQS0loBb0OGoOoJCy7sPIY6bse8eiiY2KKOrubGMYNGtAuNSAAB0BaFiVHmNNPUHJ7tY7lCWjkW2m1zUjmu14lxkqJd4aeIAe2uzEMPtGBY/BZLFSdo2yB8skcHKvk3XSSOled55Ljq97j08NdBoNAsrabiZUXZPyk1nvTF/WkUoouyflJrPemL+tItn7K/L7wseK7oiLykEREBERAREQEREBVLaj6kf3jb/nsCtqjcjsrchs1RQOldAZN1zJWjUxva4PY7Tx6OaDp49FvwK4oxaK6tUTE+qxolHIoZ1bkdIBHNi9RWSt4OloKqn5J3sjlJGOAPkIX57rX7zMuvWqL69ehmf2j5o6lk2ihO61+8zLr1qi+vTutfvMy69aovr0zP7R80dVsm0VTuOb19qulqt1Vil1irLpK+Gkj5ekPKPZG6Rw1E2g0Yxx46dGnSpHutfvMy69aovr0zP7R80dSybRQnda/eZl161RfXp3Wv3mZdetUX16Zn9o+aOpZNqLsn5Saz3pi/rSL0i6348OZtzHsuqqPT/hOpnF7HVwV1Xd7kyOGuqo2QMponl7YImFxALtBq8l5LiBoPBaNd3edjXbDoqvMaYtomJ8eBqWREReUxEREBERAREQEREBERAREQEREGf56NdpOzLhrpcK3xa6feE/sHT/AIf6HQFnuft12l7LzoTpca06ga6feE/T5FoSAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgzzaAR3zNl2p490a3Thr/h9R/BaGs+z4O75WzDQvA7o1u9ujhp2hP0+x/rotBQEREBERAREQEREBERARFC3jNsex+qFNc75brfUkb3I1NUxj9PLuk66LOmiqubUxeVtdNIqt30sO86bR12P0p30sO86bR12P0rb2fG3J5SubOxaUVW76WHedNo67H6U76WHedNo67H6U7Pjbk8pM2di0oqt30sO86bR12P0p30sO86bR12P0p2fG3J5SZs7FpRVbvpYd502jrsfpTvpYd502jrsfpTs+NuTykzZ2M92j7VMIpNqOz+KozCwQzW651zKuOS5wNdTOFFOwiQF43DvHd0Pj4dK2Ogr6a60NNW0VTFWUdTG2aCop3h8csbgC17XDg5pBBBHAgr+bnZadjtYtonZKY3esbvVsFhyiZovlTBUxllDJHpykr9DoA9g4ani8HyhfetkzrA8ds1Barfkdnp6Chp46WnhbWx6MjY0Na0cfEAAnZ8bcnlJmzsXZFVu+lh3nTaOux+lO+lh3nTaOux+lOz425PKTNnYtKKrd9LDvOm0ddj9Kd9LDvOm0ddj9KdnxtyeUmbOxaUVW76WHedNo67H6U76WHedNo67H6U7Pjbk8pM2di0oqt30sO86bR12P0r2Q7TMRqJAyPJrQ9x0AArY/GdB4/KQP2p2fG3J5Slp2LKiIudHFeqx1vs9dVMAL4IJJWg+VrSR/kqjiVJHTWCikA3p6mJk88zuL5pHNBc9xPEkk/s6OgKz5V6mLx7jm+QVXsa9Tlq9yRfIC9DA0YU+a+CSREWaCIiAiIgIiICIiAiIgIiICIiAvD2NkYWvaHNI0LXDUFeUQcmzt4ghvlsjJFJbLiaamj04RRughmDG/wC60ykAdAAAAAACtyp2z78Z5n78M+Y0iuK5sp72fh6xCzrReVepi8e45vkFV7GvU5avckXyArDlXqYvHuOb5BVexr1OWr3JF8gLfg9zPn9jwSS+YbBtyybA3bSrrc7BWZBiNozGqp6u7zXVvKUNOTC0MggcHF7I97eLd5gG8d3Xjp9PLCL/ALCL/ddk+1vF4qy2tr8uvVXcaGR8sgijjl5HdEpDNQ4cm7UNDhxHEqVX8EXF21/dq9qcPcn1DsY/e7Z/23eom1X5n3P8Lc/vdGvsKpO7Im/XOftfH8EZdahmMUOTzcveW07GRVDZCYQTE4ueOT8E6AO1OpZoN7zmWybOHX/aU/FqqwG25zSRsnkuz52zUMzKTtYljGMIka5jWHi5u6dTo4cD1YPsWveM3OsqKqqt8jJsJtuNtEMjyRU07Zg951YPuZ5Vuh6eB1aPHNNx+8E7IKuyu84THccRfZLPmlLLU2Su7osnlcWQ8tuTRBgEe9GHOaQ9/RodDwHox3sjZavaxb8Gv1ht9orbk+eKlNFkFPcJ45Io3SbtTAwB0O8xjiDq4ajTXVfmybD77b7TsSpJa+ijkwmjmprjLTyv1e59ufSh0GrOOj3g+Fu8Br08FWMG7HvNsXq9msUvNGKgwuufI6ai5cVN0ZJDJDJPI4s0ZLpJvlnhhzifDaBxnvCfsvZKXS4UFlvlXhJocTuN9OPm5i6skmjn7afTMk5HkxrEZGgElwcCT4JABO7LCKbYRf4djNmxF1ZbTcqLKW3ySUSyciYBdnVm6Dua7/JuA00A3uGunFXV+3fFY3uaYMm1adDpiV2I/iKZZRNtYzW05Zkl07ITaBW5OZ7XiOE08UjBR36VtPHEYZJRLLTMiaJ3SM8Ih7iI90NG9+EvbhfZiWjKcmx+hqKK00lvyCcU9BLR5JS1tbE9zS6Ptqkj8KHeDdDo5+64gO01Vxt+yp1/vu1OvuMzDj+d0FJTQxxiSOpjiFG6GTlGPYNxx3+A4nygHgubZbhG0LFqe049kRxK4Y5bKXtPulRxztr6yNrNyIujLQyJ2gBcQ5+vHTTVTSKbbuzXx+43agljprS7G6+vjoIKmPIqZ9z8OTkmTPt48NsZcQfwi8NO8WDQhR+3nbrk152a55PhuP1cFgtNT3NflsN2FLM2ojnYyUwRBu89jXasL99uvhaAgK57KNmGfbL4bTijZcVueF2uZzILlOyYXR1Lq5zInRhvJ77dQ3lN/Qhv4OqquVbAtoxwjMsBx6vxibEb1XzV9HUXKSojrKTlqgVEkJayNzHND97dfrroeIKx96w9sW1vM8OzjbDV0+M1mY45ZbtDLOe67Y5KKnFBTvkbTQPBD9PCeWhzAS7hqSVadp3ZGvwWx2nIbdZbbdsYuFtZc4q+uyGC3Szsc3f5OnhkaXSybm67d1brvgA6qNvmynaVBfNpLMdrsYgtGaVQe+rrnVDqqgj7Uip3ubG1u5I7wHENLmgEDUnXQcNz7G++2e6VcGMyWCstNbjFJjDKvIGyyVVqigjfGXU7WN3Xh4eHOaXR+E0HUhX3hcbtt1qLjdbFaMGxp+WXa52eK/uZUVraCClopDpE6SUted951AY1pPguJ0A1VKyjbVX4DthqKm/QVkE1Rh1AaTEYa0TcvdJq6eNkMWngOkdo1pkA/BbqeDV32HY5n+Az4pfMbqsdqL7SYzSYzeLfcpZ20lQymJMU8MrIy9rxq7VrmaEO011Gp/eUdjjU7Uc2nv8Amvcl9TLicVnjqbZygloa9tTJN2xTh48EN3oy1xdvatIIAJ1e9I3G0T1tTaqSW40sVDXyRNdUUsM/LMikI8JjZN1u8AdRvbo18gXWoPCIb/T4laocpkop8higbHWzW9zjBLIOBkbvNaRvaBxGnAkgagamcWwcOz78Z5n78M+Y0iuKp2z78Z5n78M+Y0iuK58q7z4R9IWUXlXqYvHuOb5BVexr1OWr3JF8gKw5V6mLx7jm+QVXsa9Tlq9yRfIC34Pcz5/Y8Eki9FdSmtoainE0lOZo3RiaF269mo03mnxEdIKjubEHry5del+krMyiYRQ/NiD15cuvS/STmxB68uXXpfpKXnYJhFD82IPXly69L9JObEHry5del+kl52CYRQ/NiD15cuvS/STmxB68uXXpfpJedgmEUPzYg9eXLr0v0k5sQevLl16X6SXnYJhFD82IPXly69L9JObEHry5del+kl52CYRQ/NiD15cuvS/STmxB68uXXpfpJedgmEUPzYg9eXLr0v0k5sQevLl16X6SXnYJhFz0NCy3wmJkk0oJ3t6eV0jv4uJK6FRw7Pvxnmfvwz5jSK4qnbPvxnmfvwz5jSK4rnyrvPhH0hZReVepi8e45vkFV7GvU5avckXyArDlXqYvHuOb5BVexr1OWr3JF8gLfg9zPn9jwSSIiyQRVPavmr9nGzbJMnjpX1klroZKlsUbWuJIHAlrnsDgOkgOBIBDdXEA1K+9kFRYd3Rp7tYb1WT2Ono5L3WW2mi7VozOwEO8OYOIBPFrQ54HHQjisZmIGsoswotsVQdoec2u4WSe34ri8ETqm/ySQclHJyBqJTJ92393knQlu7GTxdvbvDWPn7JuwUNuulbX2HIbdFR2nu3AyppoRLXUpkbG10TBKXNc5z2AMlEbjr0cDozoGvos8uu2NlnrbFb58RyJ13vb6kUNtjZSmZ7IGMe6Rx5fcjaQ9oG+5pBOjg0kLzLtts0Fhu91koLk2O23yHHnwCOMyzVckkEQEekmjmh9QGkkjix+gOg1XgaEizCDsgLRNd4KZ9ivsFtmvkuOsvUkEPaZrWTPh3OEpk3XSMLQ/c3dSASDqB17Idpd12ktyCprMbqrPbqS6VNHQVcskDmVMcMphf8AgTPdviSOXU7obpu7pdxKXgaIiq8+1LC6XIBYpsvsMV8MzaYWyS5wtqTK4gNj5Iu3t4kgBump1Cr+2/OLrhVuxVtljqZ7hdcho6HtejijkmnhG9NPGwSaNBdFDI3eJbu72u83TUW8DSEWXw9kJYquhohSWm9Vd/qq2pt7cbjgiFeyan0M4fvSCJrWBzCXmTcIezRx3gq3ku2u45n3vaDC6W8UTMqnqpJ7hBFROqaSnpt5swY2eQx74l5MF2j27hcW75LQpnQN0RZtatudluN5tVFFb7u613OuktdBkckMQoayqjbIXMYQ/lOPJSAPMYY4t8Fx1GvJbeyIslxxGDJu4d9prPWysprZJNBCZLnO+R0bIqeJspeXOLSQXBrd3wt7QEhnQNURVbANoFLtApLrJDbq601VrrnW6torhyRlhmbHHIRrFJIxw3ZWHVrj0kHQghWlUcOz78Z5n78M+Y0iuKp2z78Z5n78M+Y0iuK58q7z4R9IWUXlXqYvHuOb5BVexr1OWr3JF8gKw5V6mLx7jm+QVXsa9Tlq9yRfIC34Pcz5/Y8HXXVElJRVE8VNLWyxRueymgLBJKQNQxpe5rQT0DecBqeJA4qo8/77/wCWuUdZtX21XVFUZrldvuW2DGa/F63HrziNLUmCSWuuHaU8cjI6iJ74Q2Cqe7WRjXN1I0AJPEgNPov2xHu/bs0pZr1uuyi+Ud0qJe1dTHT04pW9qgb/ABDm0xG/4uVJ3Tpx1FFLbRlNVsOmuVLtLtNdf2z47mrpppKdlFuVdJNJBFCXCflC17WtibutMY08ZIC4rZ2PcdJhclgknx+iM90oK6qnx/HGW1tVFTVEc3JSMbK7VzzGQX66AOOjPEtjRM2BWKnCe29pdvy2Ss3hQ2motkFEYvwTNNFJJLv73SRAxum75ePiWfd4a501dTmXK2S47SZTNlnc6O0k1M8jpZJxC+bljvBsj2lpbGDowAg8CNoRLQMC2ObIshuOHYRV5fdRHRUk/OJmOtthpp4q+Z8k+lVK6RxeY5J3ndDI/CA3td1aNsjwC47M8XNhq73De6OCaV9HI2hNPKxj5HyESnlHiR+886vAZr+aruiREQKvPs5tVRkAvL6u/CrEzZ+TjyG4Mpt5pBA7XE4i3eHFm5unjqDqVF7R9nl3y+/4tebPf6ay1mPyVE8LKu3Gsiklli5EOc0SxnwY3zAAHpeDro0h18RW0DBLt2KFBWutVcLjbrre4JK2a4VOT2SO509fLVPjfLIYN+MRuaYmBha7wWjdIcCVbbZiNdJtspbn3OFFj2O46600UgYyOOWeeWKSUwxtPgsYyCJuugGriBroVpyKZsDGca7H2uslrsNpqcrFZaMYjn5v07LdyT6eV8UkUc1Q/lTy742SvDd0RglxJBOhHXlHY90GQ7KsLw1tVSHmqaR9JLcbc2spZ3QwOgPLU7nAPa5kj9RvggkEO1C1tEzYEHhOLw4bjFDaYYLdAIGnebaaBtFTbxJJLIWlwYOPRqT5SVOIio4dn34zzP34Z8xpFcVTtn34zzP34Z8xpFcVz5V3nwj6Qso7I4X1GPXSKNpdI+lla1o8ZLCAq1i72yY1aXNOrXUkJB8o3ArsqnVbPm8vI+2Xu5WOF7i80tGIHwhx4ktbLE/d1PHRpA1JOnFZ4OJTFM0VTbxPCzpRcHMC4eed7+Iovs6cwLh553v4ii+zrffD349ehbi70XBzAuHnne/iKL7OnMC4eed7+Iovs6Xw9+PXoW4u9FwcwLh553v4ii+zpzAuHnne/iKL7Ol8Pfj16FuLvRcHMC4eed7+Iovs6cwLh553v4ii+zpfD349ehbi70VHyi1Xuy5fhtqgy+6Pp7zV1EFQ6SCi32NjpZZWln3Acd5gB1B4a+2rTzAuHnne/iKL7Ol8Pfj16FuLvRcHMC4eed7+Iovs6cwLh553v4ii+zpfD349ehbi70XBzAuHnne/iKL7OnMC4eed7+Iovs6Xw9+PXoW4u9FwcwLh553v4ii+zpzAuHnne/iKL7Ol8Pfj16FuLvRcHMC4eed7+Iovs6/TMBrNSJcuvUzD0t5OkZrx8rYAR+w+NS+Hvx69C3F52fsIrstlB1ZLdwWnQ+KkpmH/AOTXD9it65LVaqWyW+GiooRBTRAhrdS4kkklxJ1LnEkkuJJJJJJJK61xY1cYlc1Rq6aCdIiItKCIiAiIgIiICIiDP89c4bSdmIAJBuFbrproPvCfp4/5rQFnm0DTvl7LtSde6NbpoNf8Pn/gtDQEREBERAREQEREBERAREQEREBERAREQEREGebQDptL2XDVo1uNb0jUn+z5+jyLQ1n2fAnaVsx0BOlwrddGA6feE/j8Xt/s8a0FAREQEREBERAREQEREBERAREQERc1xuNPaaGesq5RDTQML3vIJ0A8gHEnyAcT0BWImZtA6UVLdl2R1AEtJjdI2F3Fra+5uhl08W81kMgB9jeOi8c6Mt83LP8AzqX7KursuLw+anqtl1RUrnRlvm5Z/wCdS/ZU50Zb5uWf+dS/ZVeyYvD5qepZ827f+zYw/Zttvx+yXnHcoZW4tXTy1XJUlO5tRHNSSRxvgJnBcCZWnwg06a+PgvriwXYX+xW65tpamhFbTR1IpaxgbNDvtDtyQAkBw10IBI1B4lfNO2PseJ9s21XCs3ulhs8M+Pv++aQXOR7bjG078UbyaYboa/Uk6O1BI4dK3DnRlvm5Z/51L9lTsmLw+anqWXVFSudGW+bln/nUv2VOdGW+bln/AJ1L9lTsmLw+anqWXVFShlGWa8cctGn+7epCfmqnsfyFt8ZPHJTyUNfTECopJSCWa67rmuHBzHaHRw8hBAcCBrrwMTDjOnVwmJ+klkuiIudBERAREQEREBERAVT2nuLcROmmjq+gaQRrqDWQgj+BVsVS2o+pH942/wCewLpyXv8AD84+rKnXDqREXUxEX5kkZE3ee5rG6gauOg1J0A/iv0gIiICLivF6t+O22e4XWvprZQQDelqqyZsUUY101c9xAHEjpK/Njv8AbMmtsVxs9xpLtb5deTq6Gds0T9OB0e0kH+Kg71GWM6bSK0DgDaYSfZ0mk0/hqf4lSai7J+Ums96Yv60iz/ZX5feFjxXdEReUgiIgIiICIiAiIgKpbUfUj+8bf89gVtVS2o+pH942/wCewLpyXv8AD84+rKnXDqVO2wVmV2/Zpf6jCKdlTlMcAdRROY15J3m75a1xDXPDN8taToXAA9KuKicqx/nVj9Xa+6VwtBqA0CttU/I1MJDg4Fj9DoeGnEEEEgjiumdTF8u5/eK3PdkuNOptod0uVdT53aqWolqrPT0VdRSmohAhngMWgkieeUHggO1aCHN6bjtLzzOLTntk2dY9WX641lPY+7FxvNqoLbLXVAMxhYNyofFAxurXFxa0niwAN4lXFvY4Y5JiF8slZc73cKu818N0qr9U1be6HbUO5yMrXtYGtMfJMDQGaaDiDqV771sDt97bYquTKMmpsls8UtPDk1LVxR3CaGR+++KU8lyb2a6aNMfDdGmh1J12kZxBmG1a53TZrjd5uNThlyu9dd6erqhQ0clRV00EIkp5jHrNHFIR0hriNdeBGgWi7F8uv9xvWdYnklfHerhi1yipmXdlO2A1cM1PHPHvsZ4IkaHlrt0AHQcAq9n2xO73nJ9llNbb1kDLfYnXI1uQtuMZuERlg0Y4ukB395+rdAxwA4aAaKx2XBLrshtRo8ItEGUz3Gqlrrtcskvr6erqJ3BoEjntppQ8kDTQBgaGjQHU6WLxI0K82mjvdulpa6gprnAS14pqyNr43PaQ5hIcCODgCDpwIB8SxPsXoTbr1tQoLhb4sfyQX5lZX2Ci0NHRMlp4+RdA8cJBIxm+526w728C0acbvPaMt2hWitteSUwwmPWOWnuOK5DJNVB7Xa6avpYwG8BqCHA9BC79m+yq1bNG3aakq7jd7rd521Fxu93qOXqqp7W7jN5wDWgNaNGta0ADxK65iRc1F2T8pNZ70xf1pFKKLsn5Saz3pi/rSLb+yvy+8LHiu6Ii8pBERAREQEREBERAVS2o+pH942/57AraorJ7JzisdTQNm7Xlfuvim3d4MkY4PY4jUagOa0kajUajUdK34FUUYtFVWqJj6rGiXCihX3i8Uv3Opxa5Pmbwc6jkglid7LXGRpI8m81p4cQF+ecFx80758Gn+uXoeznbHOOpaU4ig+cFx80758Gn+uTnBcfNO+fBp/rk9nO2OcdS0pxFVK/Pn2y422gqcbvUVXcpHxUkRjhJlcyN0jgNJeGjWuPHyLv5wXHzTvnwaf65PZztjnHUtKcRQfOC4+ad8+DT/XJzguPmnfPg0/1yeznbHOOpaU4ouyflJrPemL+tIucZBcjwGJ3vXxeDTj/9lM4tZqttyrLzcYRS1NTEynipN8PMMTHOd4RBIL3F5J3eAAaNTpqca/06Ks6Y0xtjbC2ssyIi8piIiICIiAiIgIiICIiAiIgIiIM9z/d75ey/Xp7o1unt9oT+x6FoSz3PwTtK2YaN3tLjW6nj4P3hPx/6+VaEgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiIM82gFvfL2Xa9PdGt3eHj7nz+z6VoazzaA3e2l7Lj4XC41p4DUfi+fp8i0NAREQEREBERAREQEREBERAREQEREBEUNVZnj9DI6Opvtsp5GnQtlrI2kH2iVlTRVXopi5rTKKv98HFvOWz9fi+knfBxbzls/X4vpLZ7DF3Z5StpV3PxrtL2X+DvaXGt48fB+8J+P/AF8q0JfzI7L7sbLbmnZL4/csWudt7i5hOO6lVBUxuioJmkcvLIQdGhzPDBJ8J28Av6DY3kOE4njtrsdsyC0QW22UsVFTRd0IjuRRsDGN13vE1oCewxd2eUlpXFFX++Di3nLZ+vxfSX6bn+MPcA3I7Q4nxCuiP/MnscXdnlJaU8i9VNVQ1kLZqeVk8LuLZI3BzT7RC9q06taCIiAiIgIiICIiAiIgKOyG/wBJjFoqLlXOc2CEa7rBq97jwa1o8bidAB7KkVi+3G7OqsjtNnDvuFLTmvkZ+c97jHGf2BsvwvYXdkWTdqx6cKdXj5LCqZXlFzzeeQ3KZ8VvcTydrifpC1vi5TT/ALx3l3uHkAULHQUsLd2OmhY3yNYAF70X0fDopwaYow4tEMZmZertWD9DH8EJ2rB+hj+CF7Vn9121We1VNa51uu9RaKCc01ZfKelDqKnka7deHO3t4hp4Oc1pAIOp4FK8SnD01TZF77Vg/Qx/BCdqwfoY/ghUC9bb7TZKy/RPtF6qqexStjuVbTUzHQU7TGyQSEl4Lm7r+IaC4bpJaBoT2ZTtXoLFcnWuit90v9xFIKyVlnpxMKaJ2u4+QlwA3tDo0auOnALDtGHp97ULn2rB+hj+CENHA4aGCMjyFgVU2P3+vynZfjN3uk/bVwrKGOaebcazfeRxOjQAP2BXBbKK8+mKo8R4tnK2Gs7btE8lqqtQTJSEND9PE9v4Lx7Dgf8AJbps52gtzGlkpqtjKa80rQZ4owRHK08BLHqSd0ngWkktPA6gtc7DF2WC6vsOUWa5Ru3eTqo4JeJ8KKVwY8Hy9Id7bQvN/EMjoyrCmbe9Gqfsyib6JfTSIi+dgiIgIiICIiAiIgLDttdDJTZzQVrteRrLdyDT4g6GRziPbInHt6HyLcVXc7w+HNLE6jc8Q1UTxPSVBGvJSgEAkeNpBLSPI49B0K9H8PyiMmyimurVqn4rD54nnjpYJJppGQwxtL3ySODWtaBqSSegAeNVdu1vBnuDW5njznE6AC6wEk/DVur6WotVxltlxgNJXxjwoH9D2/nsP99h8Th7R0IIHN2lT/oIvgBfQ5maoiqiYtz+7DUrPfdwXz1x3+awfTWV2HZF3Cutbbq/ZrZ8tpam5SVMORSy04Pa8speRK14MhewOcBugh2gGoW9dpU/6CL4AXuWmvA9rMTiTq4dbjI7jgV6lsW2OlhoByl/bILWwSxgT60DIh/e0Z4bSPC06NejivRb8ey3Bsmudbb8dF/pL7baKKbk62KCSiqIITEWu3zo5hGh1bqQdeB1WxopOTU3iYmYmP8AeHGRmGzfIrLs02e41jmU320WK+UNBFHUUNZcoGSRnT/18R7I4Kx993BfPTHv5rB9NWh9NDK7efEx7vK5oJX57RpvW8XwAs6aK6KYppmLRw/1HJY8jtOT0r6qzXSiu1Mx5jdNQ1DJmNeACWktJAOhB09kKVo6F91u9poI2lz6mugZoPE0PD3n9jGuP7FyvfT0EYJLIWucGgAabzjwAA8ZPQAOJWubKNn1RbpxkF3gNPWujdHSUj/woI3abz3+R7tBw6Wt1B4ucBoyzKaclwZrrnT4cZ/7Wzp2tQREXzYEREBERAREQEREBERBGX7GrVlFIKa60EFfC07zRMzUsPlaelp9kaFVCXYXjDz9yNyp2/msuErgPhElaEi6cLKsfBi2HXMRwlbyznvD4565u3XnJ3h8c9c3brzloyLf+YZX/LPMvLOe8Pjnrm7decneHxz1zduvOWjIn5hlf8s8y8s57w+Oeubt15y8t2EY4Dxnurh5DXP/ANFoqJ+YZX/LPMvKt45s6x7Fajtm325ravTTtqd7ppgNNDo95JHtAgKyIi468SvFqzsSZmeOlNYiItYIiICIiD//2Q==", + "image/png": "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", "text/plain": [ "" ] @@ -123,6 +127,7 @@ "source": [ "from typing_extensions import TypedDict\n", "from langgraph.graph import StateGraph, START, END\n", + "from langgraph.types import Command, interrupt\n", "from langgraph.checkpoint.memory import MemorySaver\n", "from IPython.display import Image, display\n", "\n", @@ -139,7 +144,8 @@ "\n", "def human_feedback(state):\n", " print(\"---human_feedback---\")\n", - " pass\n", + " feedback = interrupt(\"Please provide feedback:\")\n", + " return {\"user_feedback\": feedback}\n", "\n", "\n", "def step_3(state):\n", @@ -160,7 +166,7 @@ "memory = MemorySaver()\n", "\n", "# Add\n", - "graph = builder.compile(checkpointer=memory, interrupt_before=[\"human_feedback\"])\n", + "graph = builder.compile(checkpointer=memory)\n", "\n", "# View\n", "display(Image(graph.get_graph().draw_mermaid_png()))" @@ -176,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "eb8e7d47-e7c9-4217-b72c-08394a2c4d3e", "metadata": {}, "outputs": [ @@ -184,8 +190,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'input': 'hello world'}\n", - "---Step 1---\n" + "---Step 1---\n", + "{'step_1': None}\n", + "\n", + "\n", + "---human_feedback---\n", + "{'__interrupt__': (Interrupt(value='Please provide feedback:', resumable=True, ns=['human_feedback:e9a51d27-22ed-8c01-3f17-0ed33209b554'], when='during'),)}\n", + "\n", + "\n" ] } ], @@ -197,8 +209,9 @@ "thread = {\"configurable\": {\"thread_id\": \"1\"}}\n", "\n", "# Run the graph until the first interruption\n", - "for event in graph.stream(initial_input, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(initial_input, thread, stream_mode=\"updates\"):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { @@ -211,58 +224,7 @@ }, { "cell_type": "code", - "execution_count": 7, - "id": "2165a1bc-1c5b-411f-9e9c-a2b9627e5d56", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "--State after update--\n", - "StateSnapshot(values={'input': 'hello world', 'user_feedback': 'go to step 3!'}, next=('step_3',), config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1ef7830e-b807-6142-8002-1b511e4caf96'}}, metadata={'source': 'update', 'step': 2, 'writes': {'human_feedback': {'user_feedback': 'go to step 3!'}}, 'parents': {}}, created_at='2024-09-21T15:48:17.660131+00:00', parent_config={'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1ef7830e-36d1-6f1e-8001-4d4c913ae8a8'}}, tasks=(PregelTask(id='6b5486bf-eb6c-0e27-4784-cad2a69b86a2', name='step_3', path=('__pregel_pull', 'step_3'), error=None, interrupts=(), state=None),))\n" - ] - }, - { - "data": { - "text/plain": [ - "('step_3',)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Get user input\n", - "try:\n", - " user_input = input(\"Tell me how you want to update the state: \")\n", - "except:\n", - " user_input = \"go to step 3!\"\n", - "\n", - "# We now update the state as if we are the human_feedback node\n", - "graph.update_state(thread, {\"user_feedback\": user_input}, as_node=\"human_feedback\")\n", - "\n", - "# We can check the state\n", - "print(\"--State after update--\")\n", - "print(graph.get_state(thread))\n", - "\n", - "# We can check the next node, showing that it is node 3 (which follows human_feedback)\n", - "graph.get_state(thread).next" - ] - }, - { - "cell_type": "markdown", - "id": "ccc4a84a-02f2-4b79-a5a5-22173645526d", - "metadata": {}, - "source": [ - "We can proceed after our breakpoint - " - ] - }, - { - "cell_type": "code", - "execution_count": 64, + "execution_count": 5, "id": "3cca588f-e8d8-416b-aba7-0f3ae5e51598", "metadata": {}, "outputs": [ @@ -270,14 +232,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "---Step 3---\n" + "---human_feedback---\n", + "{'human_feedback': {'user_feedback': 'go to step 3!'}}\n", + "\n", + "\n", + "---Step 3---\n", + "{'step_3': None}\n", + "\n", + "\n" ] } ], "source": [ "# Continue the graph execution\n", - "for event in graph.stream(None, thread, stream_mode=\"values\"):\n", - " print(event)" + "for event in graph.stream(Command(resume=\"go to step 3!\"), thread, stream_mode=\"updates\"):\n", + " print(event)\n", + " print(\"\\n\")" ] }, { @@ -290,7 +260,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 6, "id": "2b83e5ca-8497-43ca-bff7-7203e654c4d3", "metadata": {}, "outputs": [ @@ -300,7 +270,7 @@ "{'input': 'hello world', 'user_feedback': 'go to step 3!'}" ] }, - "execution_count": 66, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -320,7 +290,7 @@ " \n", "To show this, we will build a relatively simple ReAct-style agent that does tool calling. \n", "\n", - "We will use OpenAI and / or Anthropic's models and a fake tool (just for demo purposes)." + "We will use Anthropic's models and a fake tool (just for demo purposes)." ] }, { @@ -338,13 +308,13 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 7, "id": "f5319e01", "metadata": {}, "outputs": [ { "data": { - "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAE7AccDASIAAhEBAxEB/8QAHQABAAIDAQEBAQAAAAAAAAAAAAUGAwQHCAECCf/EAFoQAAEEAQIDAgcICg8FBgcAAAEAAgMEBQYRBxIhEzEUFRYiQVaUCDJRVGGT0dQXIyRCU1V0ddLTJTM1NjdxcoGRkpWhsrO0GFJzguEJQ2JkscEnKDREhKOk/8QAGwEBAAMBAQEBAAAAAAAAAAAAAAECBAUDBgf/xAA2EQEAAQICBggEBQUBAAAAAAAAAQIDESEEEjFRkdETFDNBYXGhsQVSksEVI0JigSJTsuHwMv/aAAwDAQACEQMRAD8A/qmiIgIiICIiAiIgIiICIiAiIgIirtu9d1DenoYud1GnXcY7eSa0F5ft+1QAgtLh988ghp80Bzubs70UTX5JhN2rteizns2Iq7P96V4aP71o+VWE/HFD2pn0rUq6B0/XeZH4uC7ZOxdavN8ImcR6S9+5+H0+lbnkthfxRQ9mZ9C9cLMd8zw/2ZPnlVhPxxQ9qZ9KeVWE/HFD2pn0r75LYX8UUPZmfQnkthfxRQ9mZ9Cfk+PonJ88qsJ+OKHtTPpTyqwn44oe1M+lffJbC/iih7Mz6E8lsL+KKHszPoT8nx9DJ88qsJ+OKHtTPpTyqwn44oe1M+lffJbC/iih7Mz6E8lsL+KKHszPoT8nx9DJuVL9W+0uq2YbLR3mJ4cB/QthV+3oDTlyQTHD1ILLTu21Vj7Cdv8AJkj5Xj+YrDDZu6UsQ18hZlyWKmeI4r8wb2td56NZMWgAtJ2DX7b77B25PMWpRV2c57p+3/QjDcsyIizoEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREENrHLy4HS2Uv1w02YYHdgHe9MpGzAfk5i3dbWCxEOBxFTHwblkDA0vPe93e5xPpLiSSfSSVF8Ra0lnROW7FjpJYYvCWsaN3PMbhJygeknk2H8an688dqCOeJ4kikaHscO4gjcFaJysxhvn2jD3lbuZEVV1NxX0RorIjH6h1jgMDfMYlFXJ5SCtKWEkB3K9wOxIPXb0FRJ90JwsG2/EvR437v2eq/rFnVfriTxix3DfL4PDuw2a1Fm8y2eSpjMHWZNMYoQ0yyHnexoa3nZ99uSegKqNzjtnIePuJ0bBo3MWsLd0/Hk3SxwQMnhkknjZ2knaTtLYo2uLXtDS/m32DgFE8abmN40YKi7Q2EqcSbNEz9hndL6mrVbeCtljeyeyUSAgO3JcA7uYN2PB6INK8SNI8QNB6us4ZmuMiNIt07nnUrsNZ8VvtYpXWR2pYHsLmvBDevcQ30ILnqDj5jtKaviw2X0xqfH4+W/DjGajmx7RjDPKQ2Nvac/Pyuc5rQ/k5dztuvzU4+UsvrTUOmMPpTUuZvYC54HkJ6leAV4nGFsrHdpJM0ODg7lAHnAg7tAIceDcReBmuNQX9UzTaBZqfUh1NHmMdqu1l4By46K1HNFTrRvdzRPEbOzLSGMJ5nF536994Q6Oy+l9WcUruTp+C183qTw+g/tGP7aDwOtHzbNJLfPjeNnbHpvtsQUEf7mjjDm+MugY8vnNN3cLa7Sb7reyFlSyBYmYGwhs0j92Nja13OG+d3cw6rrq4LwUyN/gToh2mOIVWhpXC4q3bZT1RfzFWOnke1tSzRtY1zw9j+R53a8D3h23V7Hug+FrgSOJWkCANztnqvT/9iC/rWyWOr5fH2aNuMTVbMbopYz980jYhVvTnFzQuscm3G4DWmns5kXNL21MblYLEpaO8hjHk7D0nZWzuUxMxOMCC0PkZ8npmq+3J21yB8tOxIPv5YZHQvd/O6Mn+dTyrPDphdpdlrZwbftWr8fM3lPZzWJJI+n8h7VZl7X4iLtURvlM7REReCBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBVSjPHoTlx1siHBcxFG315KzfwEp7mAHcMcdm7bMOzg3nta/MkbJo3Me0PY4FrmuG4IPeCF6UV6uNM5xKYljkqV7Dg+SGKU7dHOaD0X48W1PisHzY+hQJ4fY6A/sbZyGFZ0+04+29kI27uWI7saP5LR/cF+fIif1pz3z8X6pempanZXxjliYRvWWGvFXBEUbIwepDGgbrIqt5ET+tOe+fi/VJ5ET+tOe+fi/VJ0dv5/SU4RvWlFyu1jsrFxWxunm6pzPi6xhbV95M0XadrHPXY3Y9n73llfv079uqtfkRP60575+L9UnR2/n9JMI3rNLDHO3lljbI3ffZ4BCw+LafxWD5sfQq/wCRE/rTnvn4v1SeRE/rTnvn4v1SdHb+f0kwjescVKvA/mjgijd/vNYAVW8nebrMT4fGSiXHu3iyGQif5rWdQ6GNw75D3Eg+YNyfO2B/Z4f0bLv2RvZTLM337G5df2R/lRs5WuHyOBCsdevFUgjggiZDDG0NZHG0Na0DuAA7gkTRbzpnGfT/AH6fyZQ+xRMhjZHGxscbAGtY0bBoHcAF+0RZ1RERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBz28R/tAYQbnm8mL+w9G3hdP5f8A2/69CXPr2/8AtAYTu28mL/oG/wD9XT/n/wDb+5dBQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREHPLw/+YLCHmG/kvf8AN26n7rproa55f2/2g8H1O/kvf6bf+bp+ldDQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERARVG9q3J3Lc8WCoVbEFeR0Mlu9O6NrpGkhzWNaxxcGkbFxIG4IG+xWt481h8RwftU36ta40a5MYzhH8wnBd0VI8eaw+I4P2qb9WnjzWHxHB+1Tfq1PVa98cYMHjbUHu98tivdEx4qbhVYdqSgyxpoYyPMtcZZ5bEJa5r/B9+UmIbdOocD6F/QBeacp7n6bLe6Gx3F2ahhvHVSn2HgnbymKScDlZYcTHvztYS0fxNPeOvX/AB5rD4jg/apv1adVr3xxgwXdFSPHmsPiOD9qm/Vp481h8RwftU36tOq1744wYLuip0Gr8rjJI3Z2hThove2N1ujYfJ2LnHlaXscwbM3IBcCdt9yA0FwuK8Llqq3/AOjAREXkgREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREHO9BHfTURPebFkn5T28isKr2gf3sQ/8ez/nyKwrs3u1q85TO2REReKBERARaMmcx8WagxD7sDcpPA+1HTMg7V8THNa6QN7+UF7QT3buC3kFc4jnl0BqJw7xQmI/jDCujLnHEn+D7Uf5vn/wFdHVNI7Kjzq9qVu4REXPVEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBzvQP72If8Aj2f8+RWFV7QP72If+PZ/z5FYV2b3a1ecpnbLyHxD1lqGHVN/W+lLmpGYbFasq4a1PkdQEUpneFx1rEEOOEZa6Pdzm9o5zXhwLhuAtXXOZ1DqLV+rcaNRarg4gV9V1auJ07jbFiGhJiDJARI8RbM5HQmZ75S4Oa4bbjuPfM57nDh1qPI5K9kNOCefIzG1Ya25YZGZztvOyNsgZHN0/bWBr+/zupXNdf8AuddX6i1zmclgLGI00zIXGWY87RzWVhuVyAwOeabZPBpZCG7bnlB6bg+nHMShXZncUeL+puId3T96ajPhM5aw2MMeqpcfDR7ANEb5aTak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", + "image/png": "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", "text/plain": [ "" ] @@ -378,10 +348,8 @@ "\n", "# Set up the model\n", "from langchain_anthropic import ChatAnthropic\n", - "from langchain_openai import ChatOpenAI\n", "\n", - "model = ChatAnthropic(model=\"claude-3-5-sonnet-20240620\")\n", - "model = ChatOpenAI(model=\"gpt-4o\")\n", + "model = ChatAnthropic(model=\"claude-3-5-sonnet-latest\")\n", "\n", "from pydantic import BaseModel\n", "\n", @@ -407,7 +375,7 @@ " last_message = messages[-1]\n", " # If there is no function call, then we finish\n", " if not last_message.tool_calls:\n", - " return \"end\"\n", + " return END\n", " # If tool call is asking Human, we return that node\n", " # You could also add logic here to let some system know that there's something that requires Human input\n", " # For example, send a slack message, etc\n", @@ -415,7 +383,7 @@ " return \"ask_human\"\n", " # Otherwise if there is, we continue\n", " else:\n", - " return \"continue\"\n", + " return \"action\"\n", "\n", "\n", "# Define the function that calls the model\n", @@ -428,7 +396,12 @@ "\n", "# We define a fake node to ask the human\n", "def ask_human(state):\n", - " pass\n", + " tool_call_id = state[\"messages\"][-1].tool_calls[0][\"id\"]\n", + " location = interrupt(\"Please provide your location:\")\n", + " tool_message = [\n", + " {\"tool_call_id\": tool_call_id, \"type\": \"tool\", \"content\": location}\n", + " ]\n", + " return {\"messages\": tool_message}\n", "\n", "\n", "# Build the graph\n", @@ -453,21 +426,7 @@ " # 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", - " # We may ask the human\n", - " \"ask_human\": \"ask_human\",\n", - " # Otherwise we finish.\n", - " \"end\": END,\n", - " },\n", + " should_continue\n", ")\n", "\n", "# We now add a normal edge from `tools` to `agent`.\n", @@ -486,7 +445,7 @@ "# This compiles it into a LangChain Runnable,\n", "# meaning you can use it as you would any other runnable\n", "# We add a breakpoint BEFORE the `ask_human` node so it never executes\n", - "app = workflow.compile(checkpointer=memory, interrupt_before=[\"ask_human\"])\n", + "app = workflow.compile(checkpointer=memory)\n", "\n", "display(Image(app.get_graph().draw_mermaid_png()))" ] @@ -505,7 +464,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 8, "id": "cfd140f0-a5a6-4697-8115-322242f197b5", "metadata": {}, "outputs": [ @@ -517,11 +476,13 @@ "\n", "Use the search tool to ask the user where they are, then look up the weather there\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "[{'text': \"I'll help you with that. Let me first ask the user about their location.\", 'type': 'text'}, {'id': 'toolu_01KNvb7RCVu8yKYUuQQSKN1x', 'input': {'question': 'Where are you located?'}, 'name': 'AskHuman', 'type': 'tool_use'}]\n", "Tool Calls:\n", - " AskHuman (call_LDo62KBPQKZWxPI5IHxPBF0w)\n", - " Call ID: call_LDo62KBPQKZWxPI5IHxPBF0w\n", + " AskHuman (toolu_01KNvb7RCVu8yKYUuQQSKN1x)\n", + " Call ID: toolu_01KNvb7RCVu8yKYUuQQSKN1x\n", " Args:\n", - " question: Can you tell me where you are located?\n" + " question: Where are you located?\n" ] } ], @@ -529,63 +490,32 @@ "from langchain_core.messages import HumanMessage\n", "\n", "config = {\"configurable\": {\"thread_id\": \"2\"}}\n", - "input_message = HumanMessage(\n", - " content=\"Use the search tool to ask the user where they are, then look up the weather there\"\n", - ")\n", - "for event in app.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n", + "for event in app.stream(\n", + " {\"messages\": [(\"user\", \"Use the search tool to ask the user where they are, then look up the weather there\")]},\n", + " config,\n", + " stream_mode=\"values\"\n", + "):\n", " event[\"messages\"][-1].pretty_print()" ] }, - { - "cell_type": "markdown", - "id": "cc168c90-a374-4280-a9a6-8bc232dbb006", - "metadata": {}, - "source": [ - "We now want to update this thread with a response from the user. We then can kick off another run. \n", - "\n", - "Because we are treating this as a tool call, we will need to update the state as if it is a response from a tool call. In order to do this, we will need to check the state to get the ID of the tool call." - ] - }, { "cell_type": "code", - "execution_count": 50, - "id": "63598092-d565-4170-9773-e092d345f8c1", + "execution_count": 9, + "id": "924a30ea-94c0-468e-90fe-47eb9c08584d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "('agent',)" + "('ask_human',)" ] }, - "execution_count": 50, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "tool_call_id = app.get_state(config).values[\"messages\"][-1].tool_calls[0][\"id\"]\n", - "\n", - "# We now create the tool call with the id and the response we want\n", - "tool_message = [\n", - " {\"tool_call_id\": tool_call_id, \"type\": \"tool\", \"content\": \"san francisco\"}\n", - "]\n", - "\n", - "# # This is equivalent to the below, either one works\n", - "# from langchain_core.messages import ToolMessage\n", - "# tool_message = [ToolMessage(tool_call_id=tool_call_id, content=\"san francisco\")]\n", - "\n", - "# We now update the state\n", - "# Notice that we are also specifying `as_node=\"ask_human\"`\n", - "# This will apply this update as this node,\n", - "# which will make it so that afterwards it continues as normal\n", - "app.update_state(config, {\"messages\": tool_message}, as_node=\"ask_human\")\n", - "\n", - "# We can check the state\n", - "# We can see that the state currently has the `agent` node next\n", - "# This is based on how we define our graph,\n", - "# where after the `ask_human` node goes (which we just triggered)\n", - "# there is an edge to the `agent` node\n", "app.get_state(config).next" ] }, @@ -594,12 +524,12 @@ "id": "6a30c9fb-2a40-45cc-87ba-406c11c9f0cf", "metadata": {}, "source": [ - "We can now tell the agent to continue. We can just pass in `None` as the input to the graph, since no additional input is needed" + "You can see that our graph got interrupted inside the `ask_human` node, which is now waiting for a `location` to be provided. We can provide this value by invoking the graph with a `Command(resume=\"\")` input:" ] }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 10, "id": "a9f599b5-1a55-406b-a76b-f52b3ca06975", "metadata": {}, "outputs": [ @@ -608,23 +538,40 @@ "output_type": "stream", "text": [ "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "[{'text': \"I'll help you with that. Let me first ask the user about their location.\", 'type': 'text'}, {'id': 'toolu_01KNvb7RCVu8yKYUuQQSKN1x', 'input': {'question': 'Where are you located?'}, 'name': 'AskHuman', 'type': 'tool_use'}]\n", "Tool Calls:\n", - " search (call_LJlkCFfHvAS2taKHTaMmORE5)\n", - " Call ID: call_LJlkCFfHvAS2taKHTaMmORE5\n", + " AskHuman (toolu_01KNvb7RCVu8yKYUuQQSKN1x)\n", + " Call ID: toolu_01KNvb7RCVu8yKYUuQQSKN1x\n", " Args:\n", - " query: current weather in San Francisco\n", + " question: Where are you located?\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "\n", + "san francisco\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "[{'text': \"Now I'll search for the weather in San Francisco.\", 'type': 'text'}, {'id': 'toolu_01Y5C4rU9WcxBqFLYSMGjV1F', 'input': {'query': 'current weather in san francisco'}, 'name': 'search', 'type': 'tool_use'}]\n", + "Tool Calls:\n", + " search (toolu_01Y5C4rU9WcxBqFLYSMGjV1F)\n", + " Call ID: toolu_01Y5C4rU9WcxBqFLYSMGjV1F\n", + " Args:\n", + " query: current weather in san francisco\n", "=================================\u001b[1m Tool Message \u001b[0m=================================\n", "Name: search\n", "\n", - "[\"I looked up: current weather in San Francisco. Result: It's sunny in San Francisco, but you better look out if you're a Gemini \\ud83d\\ude08.\"]\n", + "I looked up: current weather in san francisco. Result: It's sunny in San Francisco, but you better look out if you're a Gemini 😈.\n", "==================================\u001b[1m Ai Message \u001b[0m==================================\n", "\n", - "The current weather in San Francisco is sunny. Enjoy the good weather! 🌞\n" + "Based on the search results, it's currently sunny in San Francisco. Note that this is the current weather at the time of our conversation, and conditions can change throughout the day.\n" ] } ], "source": [ - "for event in app.stream(None, config, stream_mode=\"values\"):\n", + "for event in app.stream(\n", + " Command(resume=\"san francisco\"), \n", + " config, \n", + " stream_mode=\"values\"\n", + "):\n", " event[\"messages\"][-1].pretty_print()" ] } @@ -645,7 +592,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.4" + "version": "3.12.3" } }, "nbformat": 4, From 04b76f55a0dd5af20baeda0d6ffdaedd653405ff Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 18:23:51 -0500 Subject: [PATCH 42/72] x --- docs/docs/concepts/low_level.md | 107 ++++---------------------------- 1 file changed, 12 insertions(+), 95 deletions(-) diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index 051be9e6a..2b99e55d6 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -444,120 +444,37 @@ Read [this how-to](https://langchain-ai.github.io/langgraph/how-tos/recursion-li ## Breakpoints -Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. +Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. You **MUST** use a [checkpointer](./persistence.md) when using breakpoints as breakpoints require the ability to save the state of the graph at the time of pausing. -There are two types of breakpoints: +There are two places where you can set breakpoints: -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. +1. **Inside** a node using the [`interrupt` function](#the-interrupt-function) (or the older [`NodeInterrupt` exception](#nodeinterrupt-exception)). +2. **Before** or **after** a node executes by setting breakpoints at **compile time** or **run time**. We call these [**static breakpoints**](#static-breakpoints). -## Breakpoints +Read more about breakpoints in the [Breakpoints conceptual guide](./breakpoints.md). -Breakpoints enable **human-in-the-loop** workflows by **pausing** graph execution to allow for human review before continuing. +## `interrupt` -There are two types of breakpoints: - -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. - -Please see the [Human-in-the-Loop guide](../human_in_the_loop) for information about breakpoints. - -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. - -### Static Breakpoints - -To set static breakpoints, specify the `interrupt_before` and/or `interrupt_after` key when [compiling your graph](#compiling-your-graph). - -```python -graph = graph_builder.compile( - interrupt_before=["node_a"], - interrupt_after=["node_b", "node_c"], - checkpointer=..., # Required -) -``` - -When using sub-graphs, specify the `interrupt_before` and `interrupt_after` values when compiling the subgraph. - -### Dynamic Breakpoints - -There are two ways to interrupt the graph dynamically: - -1. `interrupt` **function (recommended)**: Interrupts the graph within a node and surfaces a value to the client as part of the interrupt information. -2. `NodeInterrupt` exception: An older, less flexible method for interrupting. - -#### `interrupt` +Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing the developer to collect user input, validate the graph state, or make decisions before resuming execution. ```python from langgraph.types import interrupt -def node(state: State): +def human_approval_node(state: State): ... - client_value = interrupt( + answer = interrupt( # This value will be sent to the client. # It can be any JSON serializable value. - {"key": "value"} + {"question": "is it ok to continue?"}, ) ... ``` -#### `NodeInterrupt` - -Throw a `NodeInterrupt` exception to interrupt the graph. - -```python -def my_node(state: State) -> State: - if len(state['input']) > 5: - raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") - - return state -``` - -### Resuming -1. **Static breakpoints**: Pause the graph **before** or **after** a node executes. This is achieved by specifying the `interrupt_before` and `interrupt_after` keys when [compiling your graph](#compiling-your-graph). -2. **Dynamic breakpoints**: Pause the graph from **inside** a node. This is achieved by using the `interrupt` function or raising a `NodeInterrupt` exception. - -When a breakpoint is hit, graph execution will pause. -Please see the [Human-in-the-Loop guide](../human_in_the_loop) for conceptual information about breakpoints. - -=== "Command" - - Resume execution using the new `Command` primitive. - - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - graph.invoke( - Command( - # Use `resume` to pass a value to the `interrupt`. - resume=resume, - # For other kinds of breakpoints, use `update` to update the state. - update=update, - ), - config=config - ) - ``` - -=== "Without the Command Primitive" - - Resume execution without the `Command` primitive (older versions of LangGraph). - - ```python - graph.invoke(inputs, config=config) # This will pause at the breakpoint - ... - # Do something (e.g., get human input) - ... - - graph.update_state(update, config=config) - graph.invoke(None, config=config) - ``` - -See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints. +Resuming the graph is done by passing a [`Command`](#command) object to the graph with the `resume` key set to the value returned by the `interrupt` function. +Read more about how the `interrupt` is used for **human-in-the-loop** workflows in the [Human-in-the-loop conceptual guide](./human_in_the_loop.md). ## Subgraphs From 04f6a6ccd1c8515fdd565e700517e548f52f8c72 Mon Sep 17 00:00:00 2001 From: vbarda Date: Tue, 10 Dec 2024 21:13:38 -0500 Subject: [PATCH 43/72] update --- docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index c94686136..364fb7250 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -19,7 +19,7 @@ "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). Waiting for human input is a common HIL interaction pattern, allowing the agent to ask the user clarifying questions and await input before proceeding. \n", "\n", - "We can implement this in LangGraph using a [`interrupt()`][langgraph.types.interrupt]: `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input." + "We can implement this in LangGraph using [`interrupt()`][langgraph.types.interrupt]: `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input." ] }, { @@ -58,7 +58,7 @@ "metadata": {}, "outputs": [ { - "name": "stdin", + "name": "stdout", "output_type": "stream", "text": [ "ANTHROPIC_API_KEY: ········\n" From 5a0ae2157cd65b84b3cdfcb94053c24a446bc766 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 21:22:00 -0500 Subject: [PATCH 44/72] update resume link --- docs/docs/concepts/breakpoints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index 112898137..e8617a50b 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -9,7 +9,7 @@ To use breakpoints, you will need to: 1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. 2. [**Set breakpoints**](#setting-breakpoints) to specify where execution should pause. 3. Run the graph with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. -4. [**Resume execution**](#resuming) from the paused state. +4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` (see [**The `Command` primitive**](#the-command-primitive)). ## Setting breakpoints From 45d1033092928aa56c9103ed0af459358dc3bca2 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 21:32:31 -0500 Subject: [PATCH 45/72] x --- docs/docs/concepts/breakpoints.md | 32 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index e8617a50b..f3111d9f8 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -1,6 +1,6 @@ # Breakpoints -Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. +Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. ## Requirements @@ -8,7 +8,7 @@ To use breakpoints, you will need to: 1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. 2. [**Set breakpoints**](#setting-breakpoints) to specify where execution should pause. -3. Run the graph with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. +3. **Run the graph** with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. 4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` (see [**The `Command` primitive**](#the-command-primitive)). ## Setting breakpoints @@ -185,20 +185,28 @@ We recommend that you [**use the `interrupt` function instead**](#the-interrupt- ## The `Command` primitive +When using the `interrupt` function, the graph will pause at the breakpoint and wait for user input. + Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive which can be passed through the `invoke`, `ainvoke`, `stream` or `astream` methods. The `Command` primitive provides several options to control and modify the graph's state during resumption: -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. THe `resume` value is only used when using `interrupt` as a breakpoint. + + ```python + # Resume graph execution with the user's input. + graph.invoke(Command(resume={"age": "25"}), thread_config) + ``` + 2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. -3. **Navigate to another node**: Direct the graph to continue execution at a different node using `Command(goto="node_name")`. -```python -# Resume graph execution with the user's input. -graph.invoke(Command(resume={"age": "25"}), thread_config) -``` + ```python + # Update the graph state and resume. + # You must provide a `resume` value if using an `interrupt`. + graph.invoke(Command(update={"foo": "bar"}, resume="Let's go!!!"), thread_config) + ``` -By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state or flow. +By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state. ## Using with `invoke` and `ainvoke` @@ -235,7 +243,7 @@ graph.invoke(Command(resume={"age": "25"}), thread_config) ## How does resuming from a breakpoint work? -> Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered. +> Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered or where the `input()` function was called. A critical aspect of using breakpoints is understanding how resuming from a breakpoint works. When you resume execution after a breakpoint, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. @@ -270,8 +278,8 @@ Keep the following considerations in mind when using the `interrupt` function: ## Best practices -* Use the `interrupt` function to set breakpoints and collect user input. -* Use `Command` to resume execution and control the graph state. +* Use the [`interrupt`](#the-interrupt-function) function to set breakpoints and collect user input. +* Use [`Command`](#the-command-primitive) to resume execution and control the graph state. * Consider putting all side effects (e.g., API calls) after the `interrupt` to prevent duplication. See [How does resuming from a breakpoint work?](#how-does-resuming-from-a-breakpoint-work) ## Additional Resources 📚 From 327bb369d7d356afac5f32ed7bb2a070f17c165a Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 21:38:20 -0500 Subject: [PATCH 46/72] x --- docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb | 2 +- docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb | 3 ++- docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb | 2 +- docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb | 4 ++-- docs/docs/how-tos/human_in_the_loop/time-travel.ipynb | 2 +- docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb | 4 ++-- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb b/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb index a74a8ceb4..7d52f25c9 100644 --- a/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/breakpoints.ipynb @@ -12,7 +12,7 @@ "source": [ "# How to add breakpoints\n", "\n", - "!!! tip \"Prerequisits\"\n", + "!!! tip \"Prerequisites\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", "\n", diff --git a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb index 28a974ba0..28893dda7 100644 --- a/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/dynamic_breakpoints.ipynb @@ -12,12 +12,13 @@ "\n", " For **human-in-the-loop** workflows use the new [`interrupt()`](../../../reference/types/#langgraph.types.interrupt) function for **human-in-the-loop** workflows. Please review the [Human-in-the-loop conceptual guide](../../../concepts/human_in_the_loop) for more information about design patterns with `interrupt`.\n", "\n", - "!!! tip \"Prerequisits\"\n", + "!!! tip \"Prerequisites\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", "\n", " * [Breakpoints](../../../concepts/breakpoints)\n", " * [LangGraph Glossary](../../../concepts/low_level)\n", + " \n", "\n", "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). [Breakpoints](https://langchain-ai.github.io/langgraph/concepts/low_level/#breakpoints) are a common HIL interaction pattern, allowing the graph to stop at specific steps and seek human approval before proceeding (e.g., for sensitive actions).\n", "\n", diff --git a/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb b/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb index a398b1bf6..35b5f6c41 100644 --- a/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/edit-graph-state.ipynb @@ -12,7 +12,7 @@ "source": [ "# How to edit graph state\n", "\n", - "!!! tip \"Prerequisits\"\n", + "!!! tip \"Prerequisites\"\n", "\n", " * [Human-in-the-loop](../../../concepts/human_in_the_loop)\n", " * [Breakpoints](../../../concepts/breakpoints)\n", diff --git a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb index c1653f0e1..18db683ef 100644 --- a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb @@ -8,7 +8,7 @@ "source": [ "# How to Review Tool Calls\n", "\n", - "!!! tip \"Prerequisits\"\n", + "!!! tip \"Prerequisites\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", "\n", @@ -762,7 +762,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb b/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb index d37a73bc1..40ff56c86 100644 --- a/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb @@ -7,7 +7,7 @@ "source": [ "# How to view and update past graph state\n", "\n", - "!!! tip \"Prerequisits\"\n", + "!!! tip \"Prerequisites\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", " \n", diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index 364fb7250..119f8eeda 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -8,7 +8,7 @@ "source": [ "# How to wait for user input\n", "\n", - "!!! tip \"Prerequisits\"\n", + "!!! tip \"Prerequisites\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", "\n", @@ -592,7 +592,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.3" + "version": "3.11.4" } }, "nbformat": 4, From 0cb530e588c4db4aa51a330d6c56c848ef623625 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 21:53:19 -0500 Subject: [PATCH 47/72] x --- .../human_in_the_loop/wait-user-input.ipynb | 24 +++++++++---------- docs/docs/how-tos/index.md | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index 119f8eeda..f0f80e20e 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -6,7 +6,7 @@ "id": "51466c8d-8ce4-4b3d-be4e-18fdbeda5f53", "metadata": {}, "source": [ - "# How to wait for user input\n", + "# How to wait for user input using `interrupt`\n", "\n", "!!! tip \"Prerequisites\"\n", "\n", @@ -17,7 +17,7 @@ " * [LangGraph Glossary](../../../concepts/low_level)\n", " \n", "\n", - "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). Waiting for human input is a common HIL interaction pattern, allowing the agent to ask the user clarifying questions and await input before proceeding. \n", + "**Human-in-the-loop (HIL)** interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). Waiting for human input is a common HIL interaction pattern, allowing the agent to ask the user clarifying questions and await input before proceeding. \n", "\n", "We can implement this in LangGraph using [`interrupt()`][langgraph.types.interrupt]: `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input." ] @@ -98,13 +98,13 @@ "source": [ "## Simple Usage\n", "\n", - "Let's look at very basic usage of this. One intuitive approach is simply to create a node, `human_feedback`, that will get user feedback. This allows us to place our feedback gathering at a specific, chosen point in our graph.\n", - " \n", - "1) We call `interrupt()` inside our `human_feedback` node.\n", + "Let's explore a basic example of using human feedback. A straightforward approach is to create a node, **`human_feedback`**, designed specifically to collect user input. This allows us to gather feedback at a specific, chosen point in our graph.\n", "\n", - "2) We set up a [checkpointer](https://langchain-ai.github.io/langgraph/concepts/low_level/#checkpointer) to save the state of the graph up until this node.\n", + "Steps:\n", "\n", - "3) We use `Command(resume=...)` to provide the requested value to the human feedback node and resume execution." + "1. **Call `interrupt()`** inside the **`human_feedback`** node. \n", + "2. **Set up a [checkpointer](https://langchain-ai.github.io/langgraph/concepts/low_level/#checkpointer)** to save the graph's state up to this node. \n", + "3. **Use `Command(resume=...)`** to provide the requested value to the **`human_feedback`** node and resume execution." ] }, { @@ -281,21 +281,19 @@ }, { "cell_type": "markdown", - "id": "e36f89e5", + "id": "b22b9598-7ce4-4d16-b932-bba2bc2803ec", "metadata": {}, "source": [ "## Agent\n", "\n", - "In the context of agents, waiting for user feedback is useful to ask clarifying questions.\n", - " \n", - "To show this, we will build a relatively simple ReAct-style agent that does tool calling. \n", + "In the context of [agents](../../../concepts/agentic_concepts), waiting for user feedback is especially useful for asking clarifying questions. To illustrate this, we’ll create a simple [ReAct-style agent](../../../concepts/agentic_concepts#react-implementation) capable of [tool calling](https://python.langchain.com/docs/concepts/tool_calling/). \n", "\n", - "We will use Anthropic's models and a fake tool (just for demo purposes)." + "For this example, we’ll use Anthropic's chat model along with a **mock tool** (purely for demonstration purposes)." ] }, { "cell_type": "markdown", - "id": "b3b8b7e5", + "id": "01789855-b769-426d-a329-3cdb29684df8", "metadata": {}, "source": [ "
    \n", diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index 507962772..06e5caf23 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -49,7 +49,7 @@ LangGraph makes it easy to manage conversation [memory](../concepts/memory.md) i you to involve humans in the decision-making process of your graph. These how-to guides show how to implement human-in-the-loop workflows in your graph. - [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb) -- [How to wait for user input](human_in_the_loop/wait-user-input.ipynb) +- [How to wait for user input using `interrupt`](human_in_the_loop/wait-user-input.ipynb) - [How to view and update past graph state](human_in_the_loop/time-travel.ipynb) - [How to review tool calls](human_in_the_loop/review-tool-calls.ipynb) - [How to add static breakpoints](human_in_the_loop/breakpoints.ipynb): Use for debugging purposes. For [**human-in-the-loop**](../concepts/human_in_the_loop.md) workflows, we recommend the [`interrupt()`](../../../reference/types/#langgraph.types.interrupt) function instead. From 31dd6c65a90db9c7c6f4f5bb89a4c69df869396e Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 22:20:55 -0500 Subject: [PATCH 48/72] x --- .../human_in_the_loop/time-travel.ipynb | 3 ++- docs/docs/how-tos/index.md | 20 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb b/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb index 40ff56c86..7e363b12d 100644 --- a/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/time-travel.ipynb @@ -10,7 +10,8 @@ "!!! tip \"Prerequisites\"\n", "\n", " This guide assumes familiarity with the following concepts:\n", - " \n", + "\n", + " * [Time Travel](../../../concepts/time-travel)\n", " * [Breakpoints](../../../concepts/breakpoints)\n", " * [LangGraph Glossary](../../../concepts/low_level)\n", "\n", diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index 06e5caf23..b28b7f025 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -48,13 +48,25 @@ LangGraph makes it easy to manage conversation [memory](../concepts/memory.md) i [Human-in-the-loop](../concepts/human_in_the_loop.md) functionality allows you to involve humans in the decision-making process of your graph. These how-to guides show how to implement human-in-the-loop workflows in your graph. -- [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb) -- [How to wait for user input using `interrupt`](human_in_the_loop/wait-user-input.ipynb) -- [How to view and update past graph state](human_in_the_loop/time-travel.ipynb) -- [How to review tool calls](human_in_the_loop/review-tool-calls.ipynb) + +Key workflows: + +- [How to wait for user input](human_in_the_loop/wait-user-input.ipynb): A basic example that shows how to implement a human-in-the-loop workflow in your graph using the `interrupt` function. +- [How to review tool calls](human_in_the_loop/review-tool-calls.ipynb): Incorporate human-in-the-loop for reviewing/editing/accepting tool call requests before they executed using the `interrupt` function. + + +Other methods: + - [How to add static breakpoints](human_in_the_loop/breakpoints.ipynb): Use for debugging purposes. For [**human-in-the-loop**](../concepts/human_in_the_loop.md) workflows, we recommend the [`interrupt()`](../../../reference/types/#langgraph.types.interrupt) function instead. +- [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb): Edit graph state using `graph.update_state` method. Use this if implementing a **human-in-the-loop** workflow via **static breakpoints**. - [How to add dynamic breakpoints with `NodeInterrupt`](human_in_the_loop/dynamic_breakpoints.ipynb): **Not recommended**: Use the [`interrupt` function](../concepts/human_in_the_loop.md) instead. +### Time Travel + +[Time travel](../concepts/time-travel.md) allows you to replay past actions in your LangGraph application to explore alternative paths and debug issues. These how-to guides show how to use time travel in your graph. + +- [How to view and update past graph state](human_in_the_loop/time-travel.ipynb) + ### Streaming [Streaming](../concepts/streaming.md) is crucial for enhancing the responsiveness of applications built on LLMs. By displaying output progressively, even before a complete response is ready, streaming significantly improves user experience (UX), particularly when dealing with the latency of LLMs. From 789c732866fa432690ecdecfa68bcce877743748 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 22:52:17 -0500 Subject: [PATCH 49/72] x --- docs/docs/concepts/human_in_the_loop.md | 184 ++++++++++++++---------- 1 file changed, 109 insertions(+), 75 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 493d8f149..7b5896d3b 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -13,10 +13,37 @@ A **human-in-the-loop** (or "on-the-loop") workflow integrates human input into Key use cases for **human-in-the-loop** workflows in LLM-based applications include: -1. **🛠️ [Reviewing tool calls](#review-and-edit)**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. +1. **🛠️ Reviewing tool calls**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. 2. **✅ Validating LLM outputs**: Humans can review, edit, or approve content generated by the LLM. 3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details or to support multi-turn conversations. +## `interrupt` + +The [`interrupt` function][langgraph.types.interrupt] in LangGraph enables human-in-the-loop workflows by pausing the graph at a specific node, presenting information to a human, and resuming the graph with their input. This function is useful for tasks like approvals, edits, or collecting additional input. The [`interrupt` function][langgraph.types.interrupt] is used in conjunction with the [`Command`](../reference/types.md#langgraph.types.Command) object to resume the graph with a value provided by the human. + +```python +from langgraph.types import interrupt + +def human_node(state: State): + value = interrupt( + # Any JSON serializable value to surface to the human. + # For example, a question or a piece of text or a set of keys in the state + some_data + ) + ... + # Update the state with the human's input or route the graph based on the input. + ... + +# Run the graph and hit the breakpoint +thread_config = {"configurable": {"thread_id": "some_id"}} +graph.invoke(some_input, config=thread_config) + +# Resume the graph with the human's input +graph.invoke(Command(resume=value_from_human), config=thread_config) +``` + +Please read the [Breakpoints](breakpoints.md) guide for more information on using the `interrupt` function. + ## Design Patterns 1. **Approval**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. @@ -24,103 +51,103 @@ Key use cases for **human-in-the-loop** workflows in LLM-based applications incl 3. **Input**: Explicitly request human input at a particular step in the graph. This is useful for collecting additional information or context to inform the agent's decision-making process or for supporting **multi-turn conversations**. -### Approval +=== "Approval" -
    -![image](img/human_in_the_loop/approve-or-reject.png){: style="max-height:400px"} -
    Depending on the human's approval or rejection, the graph can proceed with the action or take an alternative path.
    -
    +
    + ![image](img/human_in_the_loop/approve-or-reject.png){: style="max-height:400px"} +
    Depending on the human's approval or rejection, the graph can proceed with the action or take an alternative path.
    +
    -Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. - -```python -from langgraph.types import interrupt - -def human_approval(state: State): - ... - is_approved = interrupt( - { - "question": "Is this correct?", - # Surface the output that should be - # reviewed and approved by the human. - "llm_output": state["llm_output"] - } - ) - - if is_approved: - # Proceed with the action - ... - else: - # Do something else - ... - -# Add the node to the graph in an appropriate location -# and connect it to the relevant nodes. -graph_builder.add_node("human_approval", human_approval) -graph = graph_builder.compile(checkpointer=checkpointer) - -... - -# After running the graph and hitting the breakpoint, the graph will pause. -# Resume it with either an approval or rejection. -thread_config = {"configurable": {"thread_id": "some_id"}} -graph.invoke(Command(resume=True), config=thread_config) -``` - - -### Edit - -
    -![image](img/human_in_the_loop/tool-call-review.png){: style="max-height:400px"} -
    A human can review and edit the output from the LLM before proceeding. This is particularly -critical in applications where the tool calls requested by the LLM may be sensitive or require human oversight. -
    -
    - - -=== "Review tool calls" - - TODO: Create an example for tool call review. - - -=== "Review text output from the LLM and make any necessary edits." + Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. ```python from langgraph.types import interrupt - def human_editing(state: State): + def human_approval(state: State): ... - result = interrupt( - # Interrupt information to surface to the client. - # Can be any JSON serializable value. + is_approved = interrupt( { - "task": "Review the output from the LLM and make any necessary edits.", + "question": "Is this correct?", + # Surface the output that should be + # reviewed and approved by the human. "llm_output": state["llm_output"] } ) - # Update the state with the edited text - return { - "llm_output": result["edited_text"] - } + if is_approved: + # Proceed with the action + ... + else: + # Do something else + ... # Add the node to the graph in an appropriate location # and connect it to the relevant nodes. - graph_builder.add_node("human_editing", human_editing) + graph_builder.add_node("human_approval", human_approval) graph = graph_builder.compile(checkpointer=checkpointer) ... # After running the graph and hitting the breakpoint, the graph will pause. - # Resume it with the edited text. + # Resume it with either an approval or rejection. thread_config = {"configurable": {"thread_id": "some_id"}} - graph.invoke( - Command(resume={"edited_text": "The edited text"}), - config=thread_config - ) + graph.invoke(Command(resume=True), config=thread_config) ``` -### Multi-turn conversation (Input) + +=== "Review & Edit" + +
    + ![image](img/human_in_the_loop/tool-call-review.png){: style="max-height:400px"} +
    A human can review and edit the output from the LLM before proceeding. This is particularly + critical in applications where the tool calls requested by the LLM may be sensitive or require human oversight. +
    +
    + + + === "Review tool calls" + + TODO: Create an example for tool call review. + + + === "Review text output from the LLM and make any necessary edits." + + ```python + from langgraph.types import interrupt + + def human_editing(state: State): + ... + result = interrupt( + # Interrupt information to surface to the client. + # Can be any JSON serializable value. + { + "task": "Review the output from the LLM and make any necessary edits.", + "llm_output": state["llm_output"] + } + ) + + # Update the state with the edited text + return { + "llm_output": result["edited_text"] + } + + # Add the node to the graph in an appropriate location + # and connect it to the relevant nodes. + graph_builder.add_node("human_editing", human_editing) + graph = graph_builder.compile(checkpointer=checkpointer) + + ... + + # After running the graph and hitting the breakpoint, the graph will pause. + # Resume it with the edited text. + thread_config = {"configurable": {"thread_id": "some_id"}} + graph.invoke( + Command(resume={"edited_text": "The edited text"}), + config=thread_config + ) + ``` + +### Multi-turn conversation
    ![image](img/human_in_the_loop/multi-turn-conversation.png){: style="max-height:400px"} @@ -164,6 +191,13 @@ graph.invoke( ) ``` +## Best practices + +* Use the [`interrupt`](breakpoints.md#the-interrupt-function) function to set breakpoints and collect user input. +* Use [`Command`](breakpoints.md#the-command-primitive) to resume execution and control the graph state. +* Consider putting all side effects (e.g., API calls) after the `interrupt` to prevent duplication. +* Understand [how resuming from a breakpoint works](breakpoints.md#how-does-resuming-from-a-breakpoint-work) to avoid common gotchas. + ## Additional Resources 📚 - [**Conceptual Guide: Persistence**](persistence.md#replay): Read the persistence guide for more context on replaying. From a4d49b4e77ad9ecde4a28ff8e82314516c21bd68 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 23:23:58 -0500 Subject: [PATCH 50/72] x --- docs/docs/concepts/human_in_the_loop.md | 185 ++++++++++++++---------- 1 file changed, 107 insertions(+), 78 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 7b5896d3b..ac02d57c2 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -46,106 +46,136 @@ Please read the [Breakpoints](breakpoints.md) guide for more information on usin ## Design Patterns -1. **Approval**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. -2. **Editing**: Pause the graph to review and edit the agent's state. This is useful for correcting mistakes or updating the agent's state. +There are typically three different things that you might want to do when you interrupt a graph: + +1. **Approval/Rejection**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. This pattern often involve **routing** the graph based on the human's input. +2. **Editing**: Pause the graph to review and edit the graph state. This is useful for correcting mistakes or updating the state with additional information. This pattern often involves **updating** the state with the human's input. 3. **Input**: Explicitly request human input at a particular step in the graph. This is useful for collecting additional information or context to inform the agent's decision-making process or for supporting **multi-turn conversations**. -=== "Approval" +### Approve or Reject -
    - ![image](img/human_in_the_loop/approve-or-reject.png){: style="max-height:400px"} -
    Depending on the human's approval or rejection, the graph can proceed with the action or take an alternative path.
    -
    +
    +![image](img/human_in_the_loop/approve-or-reject.png){: style="max-height:400px"} +
    Depending on the human's approval or rejection, the graph can proceed with the action or take an alternative path.
    +
    - Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. +Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. - ```python - from langgraph.types import interrupt +```python - def human_approval(state: State): - ... - is_approved = interrupt( - { - "question": "Is this correct?", - # Surface the output that should be - # reviewed and approved by the human. - "llm_output": state["llm_output"] - } - ) +from typing import Literal +from langgraph.types import interrupt, Command - if is_approved: - # Proceed with the action - ... - else: - # Do something else - ... +def human_approval(state: State) -> Command[Literal["some_node", "another_node"]]: + is_approved = interrupt( + { + "question": "Is this correct?", + # Surface the output that should be + # reviewed and approved by the human. + "llm_output": state["llm_output"] + } + ) - # Add the node to the graph in an appropriate location - # and connect it to the relevant nodes. - graph_builder.add_node("human_approval", human_approval) - graph = graph_builder.compile(checkpointer=checkpointer) + if is_approved: + return Command(goto="some_node") + else: + return Command(goto="another_node") +# Add the node to the graph in an appropriate location +# and connect it to the relevant nodes. +graph_builder.add_node("human_approval", human_approval) +graph = graph_builder.compile(checkpointer=checkpointer) + +# After running the graph and hitting the breakpoint, the graph will pause. +# Resume it with either an approval or rejection. +thread_config = {"configurable": {"thread_id": "some_id"}} +graph.invoke(Command(resume=True), config=thread_config) +``` + +### Review & Edit State + +
    +![image](img/human_in_the_loop/edit-graph-state-simple.png){: style="max-height:400px"} +
    A human can review and edit the state of the graph. This is useful for correcting mistakes or updating the state with additional information. +
    +
    + +```python +from langgraph.types import interrupt + +def human_editing(state: State): ... + result = interrupt( + # Interrupt information to surface to the client. + # Can be any JSON serializable value. + { + "task": "Review the output from the LLM and make any necessary edits.", + "llm_generated_summary": state["llm_generated_summary"] + } + ) - # After running the graph and hitting the breakpoint, the graph will pause. - # Resume it with either an approval or rejection. - thread_config = {"configurable": {"thread_id": "some_id"}} - graph.invoke(Command(resume=True), config=thread_config) - ``` + # Update the state with the edited text + return { + "llm_generated_summary": result["edited_text"] + } +# Add the node to the graph in an appropriate location +# and connect it to the relevant nodes. +graph_builder.add_node("human_editing", human_editing) +graph = graph_builder.compile(checkpointer=checkpointer) -=== "Review & Edit" +... -
    - ![image](img/human_in_the_loop/tool-call-review.png){: style="max-height:400px"} -
    A human can review and edit the output from the LLM before proceeding. This is particularly - critical in applications where the tool calls requested by the LLM may be sensitive or require human oversight. -
    -
    +# After running the graph and hitting the breakpoint, the graph will pause. +# Resume it with the edited text. +thread_config = {"configurable": {"thread_id": "some_id"}} +graph.invoke( + Command(resume={"edited_text": "The edited text"}), + config=thread_config +) +``` +### Review Tool Call - === "Review tool calls" +
    +![image](img/human_in_the_loop/tool-call-review.png){: style="max-height:400px"} +
    A human can review and edit the output from the LLM before proceeding. This is particularly +critical in applications where the tool calls requested by the LLM may be sensitive or require human oversight. +
    +
    - TODO: Create an example for tool call review. +```python +def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: + # This is the value we'll be providing via Command(resume=) + human_review = interrupt( + { + "question": "Is this correct?", + # Surface tool calls for review + "tool_call": tool_call + } + ) + review_action, review_data = human_review - === "Review text output from the LLM and make any necessary edits." - - ```python - from langgraph.types import interrupt - - def human_editing(state: State): - ... - result = interrupt( - # Interrupt information to surface to the client. - # Can be any JSON serializable value. - { - "task": "Review the output from the LLM and make any necessary edits.", - "llm_output": state["llm_output"] - } - ) - - # Update the state with the edited text - return { - "llm_output": result["edited_text"] - } - - # Add the node to the graph in an appropriate location - # and connect it to the relevant nodes. - graph_builder.add_node("human_editing", human_editing) - graph = graph_builder.compile(checkpointer=checkpointer) + # Approve the tool call and continue + if review_data == "approve": + return Command(goto="run_tool") + # Modify the tool call manually and then continue + elif review_action == "update": ... + updated_msg = get_updated_msg(review_data) + # Remember that modify an existing message you will need + # pass the message with a matching ID. + return Command(goto="run_tool", update={"messages": [updated_message]}) - # After running the graph and hitting the breakpoint, the graph will pause. - # Resume it with the edited text. - thread_config = {"configurable": {"thread_id": "some_id"}} - graph.invoke( - Command(resume={"edited_text": "The edited text"}), - config=thread_config - ) - ``` + # Give natural language feedback, and then pass that back to the agent + elif review_action == "feedback": + ... + feedback_msg = get_feedback_msg(review_data) + return Command(goto="call_llm", update={"messages": [feedback_msg]}) +``` ### Multi-turn conversation @@ -182,7 +212,6 @@ graph_builder.add_node("human_input", human_input) graph_builder.add_edge("human_input", "agent") graph = graph_builder.compile(checkpointer=checkpointer) - # After running the graph and hitting the breakpoint, the graph will pause. # Resume it with the human's input. graph.invoke( From 6153c777fb2bd795ef07b8b54ad2b5a60920dbc3 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Tue, 10 Dec 2024 23:24:26 -0500 Subject: [PATCH 51/72] x --- .../edit-graph-state-simple.png | Bin 0 -> 40187 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/docs/concepts/img/human_in_the_loop/edit-graph-state-simple.png diff --git a/docs/docs/concepts/img/human_in_the_loop/edit-graph-state-simple.png b/docs/docs/concepts/img/human_in_the_loop/edit-graph-state-simple.png new file mode 100644 index 0000000000000000000000000000000000000000..4c4d4fac49e9f67a0f4683f331c7208eb56cea03 GIT binary patch literal 40187 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 Date: Tue, 10 Dec 2024 23:54:15 -0500 Subject: [PATCH 52/72] x --- docs/docs/concepts/human_in_the_loop.md | 107 +++++++++++++----- .../human_in_the_loop/review-tool-calls.ipynb | 33 +++--- .../human_in_the_loop/wait-user-input.ipynb | 27 +++-- .../multi-agent-multi-turn-convo.ipynb | 59 +++++----- 4 files changed, 142 insertions(+), 84 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index ac02d57c2..74b6906c8 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -13,7 +13,7 @@ A **human-in-the-loop** (or "on-the-loop") workflow integrates human input into Key use cases for **human-in-the-loop** workflows in LLM-based applications include: -1. **🛠️ Reviewing tool calls**: Humans can review, edit, or approve tool calls requested by the LLM before tool execution. +1. [**🛠️ Reviewing tool calls**](#review-tool-calls): Humans can review, edit, or approve tool calls requested by the LLM before tool execution. 2. **✅ Validating LLM outputs**: Humans can review, edit, or approve content generated by the LLM. 3. **💡 Providing context**: Enable the LLM to explicitly request human input for clarification or additional details or to support multi-turn conversations. @@ -46,12 +46,13 @@ Please read the [Breakpoints](breakpoints.md) guide for more information on usin ## Design Patterns -There are typically three different things that you might want to do when you interrupt a graph: +There are typically three different **actions** that you can do with a human-in-the-loop workflow: -1. **Approval/Rejection**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. This pattern often involve **routing** the graph based on the human's input. -2. **Editing**: Pause the graph to review and edit the graph state. This is useful for correcting mistakes or updating the state with additional information. This pattern often involves **updating** the state with the human's input. -3. **Input**: Explicitly request human input at a particular step in the graph. This is useful for collecting additional information or context to inform the agent's decision-making process or for supporting **multi-turn conversations**. +1. **Approve or Reject**: Pause the graph before a critical step, such as an API call, to review and approve the action. If the action is rejected, you can prevent the graph from executing the step, and potentially take an alternative action. This pattern often involve **routing** the graph based on the human's input. +2. **Edit Graph State**: Pause the graph to review and edit the graph state. This is useful for correcting mistakes or updating the state with additional information. This pattern often involves **updating** the state with the human's input. +3. **Get Input**: Explicitly request human input at a particular step in the graph. This is useful for collecting additional information or context to inform the agent's decision-making process or for supporting **multi-turn conversations**. +Below we show different design patterns that can be implemented using these **actions**. ### Approve or Reject @@ -93,6 +94,8 @@ thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(Command(resume=True), config=thread_config) ``` +See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. + ### Review & Edit State
    @@ -136,7 +139,9 @@ graph.invoke( ) ``` -### Review Tool Call +See [How to wait for user input using interrupt](../../how-tos/human_in_the_loop/wait-user-input) for a more detailed example. + +### Review Tool Calls
    ![image](img/human_in_the_loop/tool-call-review.png){: style="max-height:400px"} @@ -177,6 +182,8 @@ def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: return Command(goto="call_llm", update={"messages": [feedback_msg]}) ``` +See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. + ### Multi-turn conversation
    @@ -190,35 +197,72 @@ A **multi-turn conversation** involves multiple back-and-forth interactions betw This design pattern is useful in an LLM application consisting of [multiple agents](./multi_agent.md). One or more agents may need to carry out multi-turn conversations with a human, where the human provides input or feedback at different stages of the conversation. For simplicity, the agent implementation below is illustrated as a single node, but in reality it may be part of a larger graph consisting of multiple nodes and include a conditional edge. -```python -from langgraph.types import interrupt +=== "One human node per agent" -def human_input(state: State): - human_message = interrupt("human_input") - return { - "messages": [ - { - "role": "human", - "content": human_message - } - ] - } + In this pattern, each agent has its own human node for collecting user input. + This can be achieved by either naming the human nodes with unique names (e.g., "human for agent 1", "human for agent 2") or by + using subgraphs where a subgraph contains a human node and an agent node. -def agent(state: State): - # Agent logic - ... + ```python + from langgraph.types import interrupt -graph_builder.add_node("human_input", human_input) -graph_builder.add_edge("human_input", "agent") -graph = graph_builder.compile(checkpointer=checkpointer) + def human_input(state: State): + human_message = interrupt("human_input") + return { + "messages": [ + { + "role": "human", + "content": human_message + } + ] + } -# After running the graph and hitting the breakpoint, the graph will pause. -# Resume it with the human's input. -graph.invoke( - Command(resume="hello!"), - config=thread_config -) -``` + def agent(state: State): + # Agent logic + ... + + graph_builder.add_node("human_input", human_input) + graph_builder.add_edge("human_input", "agent") + graph = graph_builder.compile(checkpointer=checkpointer) + + # After running the graph and hitting the breakpoint, the graph will pause. + # Resume it with the human's input. + graph.invoke( + Command(resume="hello!"), + config=thread_config + ) + ``` + + +=== "Single human node shared across multiple agents" + + In this pattern, a single human node is used to collect user input for multiple agents. The active agent is determined from the state, so after human input is collected, the graph can route to the correct agent. + + ```python + from langgraph.types import interrupt + + def human_node(state: MessagesState) -> Command[Literal["agent_1", "agent_2", ...]]: + """A node for collecting user input.""" + user_input = interrupt(value="Ready for user input.") + + # Determine the **active agent** from the state, so + # we can route to the correct agent after collecting input. + # For example, add a field to the state or use the last active agent. + # or fill in `name` attribute of AI messages generated by the agents. + active_agent = ... + + return Command( + update={ + "messages": [{ + "role": "human", + "content": user_input, + }] + }, + goto=active_agent, + ) + ``` + +See [how to implement multi-turn conversations](../how-tos/multi-agent-multi-turn-convo.ipynb) for a more detailed example. ## Best practices @@ -232,3 +276,4 @@ graph.invoke( - [**Conceptual Guide: Persistence**](persistence.md#replay): Read the persistence guide for more context on replaying. - [**Conceptual Guide: Breakpoints**](breakpoints.md): Read the breakpoints guide for more context on breakpoints. - [**How to Guides: Human-in-the-loop**](../how-tos/index.md#human-in-the-loop): Learn how to implement human-in-the-loop workflows in LangGraph. +- [**How to implement multi-turn conversations**](../how-tos/multi-agent-multi-turn-convo.ipynb): Learn how to implement multi-turn conversations in LangGraph. diff --git a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb index 18db683ef..1c36ca285 100644 --- a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb @@ -208,17 +208,17 @@ " {\n", " \"question\": \"Is this correct?\",\n", " # Surface tool calls for review\n", - " \"tool_call\": tool_call\n", + " \"tool_call\": tool_call,\n", " }\n", " )\n", - " \n", + "\n", " review_action = human_review[\"action\"]\n", " review_data = human_review.get(\"data\")\n", "\n", " # if approved, call the tool\n", " if review_action == \"continue\":\n", " return Command(goto=\"run_tool\")\n", - " \n", + "\n", " # update the AI message AND call tools\n", " elif review_action == \"update\":\n", " updated_message = {\n", @@ -448,10 +448,10 @@ ], "source": [ "for event in graph.stream(\n", - " # provide value \n", - " Command(resume={\"action\": \"continue\"}), \n", + " # provide value\n", + " Command(resume={\"action\": \"continue\"}),\n", " thread,\n", - " stream_mode=\"updates\"\n", + " stream_mode=\"updates\",\n", "):\n", " print(event)\n", " print(\"\\n\")" @@ -558,9 +558,9 @@ "source": [ "# Let's now continue executing from here\n", "for event in graph.stream(\n", - " Command(resume={\"action\": \"update\", \"data\": {\"city\": \"San Francisco, USA\"}}), \n", - " thread, \n", - " stream_mode=\"updates\"\n", + " Command(resume={\"action\": \"update\", \"data\": {\"city\": \"San Francisco, USA\"}}),\n", + " thread,\n", + " stream_mode=\"updates\",\n", "):\n", " print(event)\n", " print(\"\\n\")" @@ -674,9 +674,14 @@ "# Let's now continue executing from here\n", "for event in graph.stream(\n", " # provide our natural language feedback!\n", - " Command(resume={\"action\": \"feedback\", \"data\": \"User requested changes: use format for location\"}), \n", - " thread, \n", - " stream_mode=\"updates\"\n", + " Command(\n", + " resume={\n", + " \"action\": \"feedback\",\n", + " \"data\": \"User requested changes: use format for location\",\n", + " }\n", + " ),\n", + " thread,\n", + " stream_mode=\"updates\",\n", "):\n", " print(event)\n", " print(\"\\n\")" @@ -737,9 +742,7 @@ ], "source": [ "for event in graph.stream(\n", - " Command(resume={\"action\": \"continue\"}), \n", - " thread, \n", - " stream_mode=\"updates\"\n", + " Command(resume={\"action\": \"continue\"}), thread, stream_mode=\"updates\"\n", "):\n", " print(event)\n", " print(\"\\n\")" diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index f0f80e20e..6142030cd 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -245,7 +245,9 @@ ], "source": [ "# Continue the graph execution\n", - "for event in graph.stream(Command(resume=\"go to step 3!\"), thread, stream_mode=\"updates\"):\n", + "for event in graph.stream(\n", + " Command(resume=\"go to step 3!\"), thread, stream_mode=\"updates\"\n", + "):\n", " print(event)\n", " print(\"\\n\")" ] @@ -396,9 +398,7 @@ "def ask_human(state):\n", " tool_call_id = state[\"messages\"][-1].tool_calls[0][\"id\"]\n", " location = interrupt(\"Please provide your location:\")\n", - " tool_message = [\n", - " {\"tool_call_id\": tool_call_id, \"type\": \"tool\", \"content\": location}\n", - " ]\n", + " tool_message = [{\"tool_call_id\": tool_call_id, \"type\": \"tool\", \"content\": location}]\n", " return {\"messages\": tool_message}\n", "\n", "\n", @@ -424,7 +424,7 @@ " # 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", + " should_continue,\n", ")\n", "\n", "# We now add a normal edge from `tools` to `agent`.\n", @@ -489,9 +489,16 @@ "\n", "config = {\"configurable\": {\"thread_id\": \"2\"}}\n", "for event in app.stream(\n", - " {\"messages\": [(\"user\", \"Use the search tool to ask the user where they are, then look up the weather there\")]},\n", + " {\n", + " \"messages\": [\n", + " (\n", + " \"user\",\n", + " \"Use the search tool to ask the user where they are, then look up the weather there\",\n", + " )\n", + " ]\n", + " },\n", " config,\n", - " stream_mode=\"values\"\n", + " stream_mode=\"values\",\n", "):\n", " event[\"messages\"][-1].pretty_print()" ] @@ -565,11 +572,7 @@ } ], "source": [ - "for event in app.stream(\n", - " Command(resume=\"san francisco\"), \n", - " config, \n", - " stream_mode=\"values\"\n", - "):\n", + "for event in app.stream(Command(resume=\"san francisco\"), config, stream_mode=\"values\"):\n", " event[\"messages\"][-1].pretty_print()" ] } diff --git a/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb index 98cc4ba64..2e6db94d4 100644 --- a/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb +++ b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb @@ -161,12 +161,13 @@ " response = model.with_structured_output(Response).invoke(messages)\n", " goto = response[\"goto\"]\n", " if goto == \"finish\":\n", - " # When the agent is done, we should go to the \n", + " # When the agent is done, we should go to the\n", " goto = \"human\"\n", "\n", " # Handoff to another agent or halt\n", " ai_msg = {\"role\": \"ai\", \"content\": response[\"response\"], \"name\": name}\n", " return Command(goto=goto, update={\"messages\": [ai_msg]})\n", + "\n", " return agent_node\n", "\n", "\n", @@ -204,37 +205,44 @@ " ),\n", ")\n", "\n", - "def human_node(state: MessagesState) -> Command[Literal[\"hotel_advisor\", \"sightseeing_advisor\", \"travel_advisor\", \"human\"]]:\n", + "\n", + "def human_node(\n", + " state: MessagesState,\n", + ") -> Command[\n", + " Literal[\"hotel_advisor\", \"sightseeing_advisor\", \"travel_advisor\", \"human\"]\n", + "]:\n", " \"\"\"A node for collecting user input.\"\"\"\n", " user_input = interrupt(value=\"Ready for user input.\")\n", "\n", " active_agent = None\n", "\n", " # This will look up the active agent.\n", - " for message in state['messages'][::-1]:\n", + " for message in state[\"messages\"][::-1]:\n", " if message.name:\n", " active_agent = message.name\n", " break\n", " else:\n", - " raise AssertionError(f'Could not determine the active agent.')\n", - " \n", + " raise AssertionError(\"Could not determine the active agent.\")\n", + "\n", " return Command(\n", " update={\n", - " \"messages\": [{\n", - " \"role\": \"human\",\n", - " \"content\": user_input,\n", - " }]\n", + " \"messages\": [\n", + " {\n", + " \"role\": \"human\",\n", + " \"content\": user_input,\n", + " }\n", + " ]\n", " },\n", " goto=active_agent,\n", " )\n", - " \n", + "\n", "\n", "builder = StateGraph(MessagesState)\n", "builder.add_node(\"travel_advisor\", travel_advisor)\n", "builder.add_node(\"sightseeing_advisor\", sightseeing_advisor)\n", "builder.add_node(\"hotel_advisor\", hotel_advisor)\n", "\n", - "# This adds a node to collet human input, which will route \n", + "# This adds a node to collet human input, which will route\n", "# back to the active agent.\n", "builder.add_node(\"human\", human_node)\n", "\n", @@ -314,40 +322,39 @@ "source": [ "import uuid\n", "\n", - "thread_config = {\n", - " \"configurable\": {\n", - " \"thread_id\": uuid.uuid4()\n", - " }\n", - "}\n", + "thread_config = {\"configurable\": {\"thread_id\": uuid.uuid4()}}\n", "\n", "inputs = [\n", " # 1st round of conversation,\n", - " {\"messages\": [{\n", - " \"role\": \"user\", \n", - " \"content\": \"i wanna go somewhere warm in the caribbean\"\n", - " }]},\n", + " {\n", + " \"messages\": [\n", + " {\"role\": \"user\", \"content\": \"i wanna go somewhere warm in the caribbean\"}\n", + " ]\n", + " },\n", " # Since we're using `interrupt`, we'll need to resume using the Command primitive.\n", " # 2nd round of conversation,\n", - " Command(resume=\"could you recommend a nice hotel in one of the areas and tell me which area it is.\"),\n", + " Command(\n", + " resume=\"could you recommend a nice hotel in one of the areas and tell me which area it is.\"\n", + " ),\n", " # 3rd round of conversation,\n", " Command(resume=\"could you recommend something to do near the hotel?\"),\n", "]\n", "\n", "for idx, user_input in enumerate(inputs):\n", " print()\n", - " print(f'--- Conversation Turn {idx + 1} ---')\n", + " print(f\"--- Conversation Turn {idx + 1} ---\")\n", " print()\n", " print(f\"User: {user_input}\")\n", " print()\n", " for update in graph.stream(\n", " user_input,\n", " config=thread_config,\n", - " stream_mode='updates',\n", + " stream_mode=\"updates\",\n", " ):\n", " for node_id, value in update.items():\n", - " if isinstance(value, dict) and value.get('messages', []):\n", - " last_message = value['messages'][-1]\n", - " if last_message['role'] != \"ai\":\n", + " if isinstance(value, dict) and value.get(\"messages\", []):\n", + " last_message = value[\"messages\"][-1]\n", + " if last_message[\"role\"] != \"ai\":\n", " continue\n", " print(f\"{last_message['name']}: {last_message['content']}\")" ] From 7144f7db41594a34f41dee171efa669f2d07d6fc Mon Sep 17 00:00:00 2001 From: vbarda Date: Wed, 11 Dec 2024 09:21:16 -0500 Subject: [PATCH 53/72] typos --- docs/docs/concepts/breakpoints.md | 2 +- docs/docs/concepts/human_in_the_loop.md | 8 ++++---- .../how-tos/human_in_the_loop/review-tool-calls.ipynb | 4 ++-- docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb | 6 ++---- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index f3111d9f8..df510efc0 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -191,7 +191,7 @@ Graph execution can be resumed using the [Command](../reference/types.md#langgra The `Command` primitive provides several options to control and modify the graph's state during resumption: -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. THe `resume` value is only used when using `interrupt` as a breakpoint. +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. The `resume` value is only used when using `interrupt` as a breakpoint. ```python # Resume graph execution with the user's input. diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 74b6906c8..fd895bece 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -2,7 +2,7 @@ !!! tip "This guide uses the new `interrupt` function." - As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [interrupt](../reference/types.md#langgraph.types.interrupt) function as it significantly simpifies **human-in-the-loop** patterns. Please see the [Breakpoints](breakpoints.md) guide for more information. + As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [interrupt](../reference/types.md#langgraph.types.interrupt) function as it significantly simplifies **human-in-the-loop** patterns. Please see the [Breakpoints](breakpoints.md) guide for more information. If you're looking for the previous version of this conceptual guide, which relied on static breakpoints and `NodeInterrupt` exception, it is available [here](v0-human-in-the-loop.md). @@ -164,15 +164,15 @@ def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: review_action, review_data = human_review # Approve the tool call and continue - if review_data == "approve": + if review_action == "continue": return Command(goto="run_tool") # Modify the tool call manually and then continue elif review_action == "update": ... updated_msg = get_updated_msg(review_data) - # Remember that modify an existing message you will need - # pass the message with a matching ID. + # Remember that to modify an existing message you will need + # to pass the message with a matching ID. return Command(goto="run_tool", update={"messages": [updated_message]}) # Give natural language feedback, and then pass that back to the agent diff --git a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb index 1c36ca285..d87ee13e5 100644 --- a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb @@ -47,7 +47,7 @@ " review_action, review_data = human_review\n", " \n", " # Approve the tool call and continue\n", - " if review_data == \"approve\":\n", + " if review_action == \"continue\":\n", " return Command(goto=\"run_tool\")\n", " \n", " # Modify the tool call manually and then continue\n", @@ -101,7 +101,7 @@ "metadata": {}, "outputs": [ { - "name": "stdin", + "name": "stdout", "output_type": "stream", "text": [ "ANTHROPIC_API_KEY: ········\n" diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index 6142030cd..5805447bc 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -177,7 +177,7 @@ "id": "ce0fe2bc-86fc-465f-956c-729805d50404", "metadata": {}, "source": [ - "Run until our breakpoint at `human_feedback` - " + "Run until our breakpoint at `human_feedback`:" ] }, { @@ -219,7 +219,7 @@ "id": "28a7d545-ab19-4800-985b-62837d060809", "metadata": {}, "source": [ - "Now, we can just manually update our graph state with with the user input - " + "Now, we can manually update our graph state with the user input:" ] }, { @@ -485,8 +485,6 @@ } ], "source": [ - "from langchain_core.messages import HumanMessage\n", - "\n", "config = {\"configurable\": {\"thread_id\": \"2\"}}\n", "for event in app.stream(\n", " {\n", From a03900be7a63de1faca4b7c67cf7b0019cfafc0f Mon Sep 17 00:00:00 2001 From: vbarda Date: Wed, 11 Dec 2024 09:56:20 -0500 Subject: [PATCH 54/72] minor fix --- docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb | 2 +- docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb index d87ee13e5..d647483ba 100644 --- a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb @@ -30,7 +30,7 @@ "3. Give natural language feedback, and then pass that back to the agent\n", "\n", "\n", - "We can implement these in LangGraph using a [`interrupt()`][langgraph.types.interrupt]. `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input:\n", + "We can implement these in LangGraph using the [`interrupt()`][langgraph.types.interrupt] function. `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input:\n", "\n", "\n", "```python\n", diff --git a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb index 5805447bc..e13c17b41 100644 --- a/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/wait-user-input.ipynb @@ -19,7 +19,7 @@ "\n", "**Human-in-the-loop (HIL)** interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). Waiting for human input is a common HIL interaction pattern, allowing the agent to ask the user clarifying questions and await input before proceeding. \n", "\n", - "We can implement this in LangGraph using [`interrupt()`][langgraph.types.interrupt]: `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input." + "We can implement this in LangGraph using the [`interrupt()`][langgraph.types.interrupt] function. `interrupt` allows us to stop graph execution to collect input from a user and continue execution with collected input." ] }, { From f6c44ec1548559bcd0d006c1d6de340358dfce3f Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 10:58:10 -0500 Subject: [PATCH 55/72] x --- docs/docs/concepts/breakpoints.md | 4 +- docs/docs/concepts/human_in_the_loop.md | 184 +++++++++++++++++++++++- 2 files changed, 185 insertions(+), 3 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index df510efc0..8608e51eb 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -243,7 +243,9 @@ graph.invoke(Command(resume={"age": "25"}), thread_config) ## How does resuming from a breakpoint work? -> Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered or where the `input()` function was called. +!!! warning + + Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered or where the `input()` function was called. A critical aspect of using breakpoints is understanding how resuming from a breakpoint works. When you resume execution after a breakpoint, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index fd895bece..f04d5e6d1 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -197,7 +197,7 @@ A **multi-turn conversation** involves multiple back-and-forth interactions betw This design pattern is useful in an LLM application consisting of [multiple agents](./multi_agent.md). One or more agents may need to carry out multi-turn conversations with a human, where the human provides input or feedback at different stages of the conversation. For simplicity, the agent implementation below is illustrated as a single node, but in reality it may be part of a larger graph consisting of multiple nodes and include a conditional edge. -=== "One human node per agent" +=== "Using a human node per agent" In this pattern, each agent has its own human node for collecting user input. This can be achieved by either naming the human nodes with unique names (e.g., "human for agent 1", "human for agent 2") or by @@ -234,7 +234,7 @@ it may be part of a larger graph consisting of multiple nodes and include a cond ``` -=== "Single human node shared across multiple agents" +=== "Sharing human node across multiple agents" In this pattern, a single human node is used to collect user input for multiple agents. The active agent is determined from the state, so after human input is collected, the graph can route to the correct agent. @@ -264,6 +264,186 @@ it may be part of a larger graph consisting of multiple nodes and include a cond See [how to implement multi-turn conversations](../how-tos/multi-agent-multi-turn-convo.ipynb) for a more detailed example. +### Validating human input + +If you need to validate the input provided by the human within the graph itself (rather than on the client side), you can achieve this by using multiple interrupt calls within a single node. + +```python +from langgraph.types import interrupt + +def human_node(state: State): + """Human node with validation.""" + question = "What is your age?" + + while True: + answer = interrupt(question) + + # Validate answer, if the answer isn't valid ask for input again. + if not isinstance(answer, int) or answer < 0: + question = f"'{answer} is not a valid age. What is your age?" + answer = None + continue + else: + # If the answer is valid, we can proceed. + break + + print(f"The human in the loop is {answer} years old.") + return { + "age": answer + } +``` + +## Gotchyas + +!!! warning + + Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered or where the `input()` function was called. + +A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. + +**All** code from the beginning of the node to the **breakpoint** will be re-executed. + +### Side-effects + +Place code with side effects, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node is resumed. + +=== "Side effects before interrupt (BAD)" + + This code will re-execute the API call another time when the node is resumed from + the `interrupt`. + + This can be problematic if the API call is not idempotent or is just expensive. + + ```python + from langgraph.types import interrupt + + def human_node(state: State): + """Human node with validation.""" + api_call(...) # This code will be re-executed when the node is resumed. + answer = interrupt(question) + ``` + +=== "Side effects after interrupt (OK)" + + ```python + from langgraph.types import interrupt + + def human_node(state: State): + """Human node with validation.""" + + answer = interrupt(question) + + api_call(answer) # OK as it's after the interrupt + ``` + +=== "Side effects in a separate node (OK)" + + ```python + from langgraph.types import interrupt + + def human_node(state: State): + """Human node with validation.""" + + answer = interrupt(question) + + return { + "answer": answer + } + + def api_call_node(state: State): + api_call(...) # OK as it's in a separate node + ``` + +### Subgraphs called as functions + + +**Subgraphs**: If you're invoking a subgraph [as a function](low_level.md#as-a-function), the **parent** graph will be re-run from the **beginning of the node** where the subgraph was invoked. + +```python +def some_node(state: State): + some_code() # <-- This code will be re-executed when the subgraph is resumed. + # Using a subgraph as a function. + # The subgraph has an `interrupt` call + subgraph_result = subgraph.invoke(some_input) + ... +``` + + +### Using multiple interrupts + +Using multiple interrupts within a **single** node can be helpful for patterns like [validating human input](#validating-human-input). However, using multiple interrupts in the same node can lead to unexpected behavior if not handled carefully. + +When a node contains multiple interrupt calls, LangGraph keeps a list of resume values specific to the task executing the node. Whenever execution resumes, it starts at the beginning of the node. For each interrupt encountered, LangGraph checks if a matching value exists in the task's resume list. Matching is **strictly index-based**, so the order of interrupt calls within the node is critical. + +To avoid issues, refrain from dynamically changing the node's structure between executions. This includes adding, removing, or reordering interrupt calls, as such changes can result in mismatched indices. These problems often arise from unconventional patterns, such as mutating state via `Command(resume=..., update=SOME_STATE_MUTATION)` or relying on global variables to modify the node’s structure dynamically. + +??? "Example of incorrect code" + + ```python + import uuid + from typing import TypedDict, Optional + + from langgraph.graph import StateGraph + from langgraph.constants import START + from langgraph.types import interrupt, Command + from langgraph.checkpoint.memory import MemorySaver + + + class State(TypedDict): + """The graph state.""" + + age: Optional[str] + name: Optional[str] + + + def human_node(state: State): + if not state.get('name'): + name = interrupt("what is your name?") + else: + name = "N/A" + + if not state.get('age'): + age = interrupt("what is your age?") + else: + age = "N/A" + + print(f"Name: {name}. Age: {age}") + + return { + "age": age, + "name": name, + } + + + builder = StateGraph(State) + builder.add_node("human_node", human_node) + builder.add_edge(START, "human_node") + + # A checkpointer must be enabled for interrupts to work! + checkpointer = MemorySaver() + graph = builder.compile(checkpointer=checkpointer) + + config = { + "configurable": { + "thread_id": uuid.uuid4(), + } + } + + for chunk in graph.stream({"age": None, "name": None}, config): + print(chunk) + + for chunk in graph.stream(Command(resume="John", update={"name": "foo"}), config): + print(chunk) + ``` + + ```pycon + {'__interrupt__': (Interrupt(value='what is your name?', resumable=True, ns=['human_node:3a007ef9-c30d-c357-1ec1-86a1a70d8fba'], when='during'),)} + Name: N/A. Age: John + {'human_node': {'age': 'John', 'name': 'N/A'}} + ``` + + + ## Best practices * Use the [`interrupt`](breakpoints.md#the-interrupt-function) function to set breakpoints and collect user input. From 82fa597e842a6eb25b59510cefcfd30fa67320c7 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 10:58:58 -0500 Subject: [PATCH 56/72] x --- .../how-tos/human_in_the_loop/interrupt.ipynb | 621 ------------------ 1 file changed, 621 deletions(-) delete mode 100644 docs/docs/how-tos/human_in_the_loop/interrupt.ipynb diff --git a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb b/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb deleted file mode 100644 index 805f01b65..000000000 --- a/docs/docs/how-tos/human_in_the_loop/interrupt.ipynb +++ /dev/null @@ -1,621 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0ff51c4b-5d5c-4b6e-8478-0ea489adb689", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "# How to use interrupt for human-in-the-loop?\n", - "\n", - "!!! tip \"Prerequisites\"\n", - "\n", - " This guide assumes familiarity with the following concepts:\n", - "\n", - " * [Breakpoints](../../../concepts/breakpoints)\n", - " * [Interrupt](../../../concepts/low_level#interrupt)\n", - " * [Command](../../../concepts/low_level#command)\n", - " \n", - "\n", - "An `interrupt` is a convenient way to support human-in-the-loop workflows.\n", - "\n", - "To use an `interrupt`, you must enable a checkpointer, as the feature relies on persisting the graph state.\n", - "\n", - "An `interrupt` can be used within a node to pause execution and wait for input, as shown in this example:\n", - "\n", - "```python\n", - "async def some_node(state: State):\n", - " ...\n", - " # Surface any value as part of the interrupt\n", - " value = {\"question\": \"how old are you?\"} \n", - " answer = interrupt(value)\n", - " ...\n", - "```\n", - "\n", - "Graph execution will pause when the interrupt function is called. To resume execution, pass a `Command` with the desired resume value:\n", - "\n", - "```python\n", - "for chunk in graph.stream(Command(resume=some_value), config={\"configurable\": {\"thread_id\": ...}}):\n", - " ...\n", - "```\n", - "\n", - "Remember that graph execution always restarts at the beginning of the node. Be cautious of side effects, such as API calls that mutate data, as these may inadvertently be triggered multiple times.\n", - "\n", - "When a node contains multiple interrupt calls, LangGraph maintains a list of resume values scoped to the specific task executing the node. When resuming, execution always starts at the beginning of the node, and for each interrupt encountered, LangGraph checks whether a corresponding value exists in the task's list. Matching is strictly index-based, making the order of interrupt calls within the node critical. Users should avoid logic that dynamically removes, adds, or reorders interrupt calls between executions, as this can lead to mismatched indices. Such patterns often involve unconventional state mutations, such as altering state via `Command(resume=..., update=SOME_STATE_MUTATION)` or relying on global variables to modify the node's structure." - ] - }, - { - "cell_type": "markdown", - "id": "17ecd33b-7879-47a8-9ad3-0b4ce1fdc0c9", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "## Setup\n", - "\n", - "First we need to install the required packages:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "cbc003a6-b45f-4526-bcf1-963d951797ae", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "%%capture --no-stderr\n", - "%pip install --quiet -U langgraph" - ] - }, - { - "cell_type": "markdown", - "id": "7091bfdc-2754-4b3c-83b9-20cfb1d2be66", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "
    \n", - "

    Set up LangSmith for LangGraph development

    \n", - "

    \n", - " Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started here. \n", - "

    \n", - "
    " - ] - }, - { - "cell_type": "markdown", - "id": "8aa9eb6a-d54f-40e9-a618-0ad7290d15dc", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "## Basic usage of interrupt and Command\n", - "\n", - "Here is an example that shows how to use `interrupt` to interrupt the execution of a graph, and then resume the execution using the `Command` primitive." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "ce902820-2739-402f-a784-867a44a3997c", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 1 # of times\n", - "{'__interrupt__': (Interrupt(value='what is your age?', resumable=True, ns=['node:62e598fa-8653-9d6d-2046-a70203020e37'], when='during'),)}\n" - ] - } - ], - "source": [ - "import uuid\n", - "import operator\n", - "from typing import TypedDict, Annotated, Optional\n", - "\n", - "from langgraph.graph import StateGraph\n", - "from langgraph.constants import START, INTERRUPT\n", - "from langgraph.types import interrupt, Command\n", - "from langgraph.checkpoint.memory import MemorySaver\n", - "\n", - "\n", - "class State(TypedDict):\n", - " \"\"\"The graph state.\"\"\"\n", - "\n", - " foo: str\n", - " human_value: Optional[str]\n", - " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", - "\n", - "\n", - "counter = 0\n", - "\n", - "\n", - "def node(state: State):\n", - " global counter\n", - " counter += 1\n", - " print(f\"> Entered the node: {counter} # of times\")\n", - " answer = interrupt(\n", - " # This value will be sent to the client\n", - " # as part of the interrupt information.\n", - " \"what is your age?\"\n", - " )\n", - " print(f\"> Received an input from the interrupt: {answer}\")\n", - " return {\"human_value\": answer}\n", - "\n", - "\n", - "builder = StateGraph(State)\n", - "builder.add_node(\"node\", node)\n", - "builder.add_edge(START, \"node\")\n", - "\n", - "# A checkpointer must be enabled for interrupts to work!\n", - "checkpointer = MemorySaver()\n", - "graph = builder.compile(checkpointer=checkpointer)\n", - "\n", - "config = {\n", - " \"configurable\": {\n", - " \"thread_id\": uuid.uuid4(),\n", - " }\n", - "}\n", - "\n", - "for chunk in graph.stream({\"foo\": \"abc\"}, config):\n", - " print(chunk)" - ] - }, - { - "cell_type": "markdown", - "id": "8df4319f-f7e8-40dc-8943-91fa3fad31a0", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "Let's resume graph execution from the given node:" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "c2ea37d8-4b92-442d-85e1-212e20123907", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 2 # of times\n", - "> Received an input from the interrupt: some input from a human!!!\n", - "{'node': {'human_value': 'some input from a human!!!'}}\n" - ] - } - ], - "source": [ - "command = Command(resume=\"some input from a human!!!\")\n", - "\n", - "for chunk in graph.stream(Command(resume=\"some input from a human!!!\"), config):\n", - " print(chunk)" - ] - }, - { - "cell_type": "markdown", - "id": "0036a06d-c875-461b-917d-1cd48c233e7d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "!!! important \"Graph execution resumes at the start of a node\"\n", - "\n", - " Graph execution resumes from the start of the **node** where the interrupt was raised rather than from the line where the `interrupt` was raised.\n", - "\n", - " As a result, you should see that the node was entered 2 times rather than once!\n", - "\n", - " Exercise care if your code has side-effects like making mutable API calls between consecutive interrupts!" - ] - }, - { - "cell_type": "markdown", - "id": "9b40603f-5d01-41d7-afc7-2ead455a6803", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "## Using multiple interrupts calls within a single node\n", - "\n", - "In some situations, you may need to use interrupt more than once within a single node. A common use case is performing runtime validation on the value supplied through `Command(resume=value)`." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "30b5821e-8bb8-4076-b477-60f39ea65445", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 1 # of times\n", - "{'__interrupt__': (Interrupt(value='What is your age?', resumable=True, ns=['node:ed4d470f-5753-d7f3-eec6-4435f5f93f72'], when='during'),)}\n" - ] - } - ], - "source": [ - "import uuid\n", - "import operator\n", - "from typing import TypedDict, Annotated, Optional, Literal\n", - "\n", - "from langgraph.graph import StateGraph\n", - "from langgraph.constants import START\n", - "from langgraph.types import interrupt, Command\n", - "from langgraph.checkpoint.memory import MemorySaver\n", - "\n", - "\n", - "class State(TypedDict):\n", - " \"\"\"The graph state.\"\"\"\n", - "\n", - " foo: str\n", - " human_value: Optional[str]\n", - " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", - "\n", - "\n", - "counter = 0\n", - "\n", - "\n", - "def node(state: State):\n", - " global counter\n", - " counter += 1\n", - " print(f\"> Entered the node: {counter} # of times\")\n", - "\n", - " answer = None\n", - " question = \"What is your age?\"\n", - "\n", - " while answer is None:\n", - " answer = interrupt(question)\n", - "\n", - " if not isinstance(answer, int) or answer < 0:\n", - " question = f\"'{answer} is not a valid age. What is your age?\"\n", - " answer = None\n", - " continue\n", - " else:\n", - " break\n", - "\n", - " return {\"human_value\": f\"The human is {answer} years old.\"}\n", - "\n", - "\n", - "builder = StateGraph(State)\n", - "builder.add_node(\"node\", node)\n", - "builder.add_edge(START, \"node\")\n", - "\n", - "# A checkpointer must be enabled for interrupts to work!\n", - "checkpointer = MemorySaver()\n", - "graph = builder.compile(checkpointer=checkpointer)\n", - "\n", - "config = {\n", - " \"configurable\": {\n", - " \"thread_id\": uuid.uuid4(),\n", - " }\n", - "}\n", - "\n", - "for chunk in graph.stream({\"foo\": \"abc\"}, config):\n", - " print(chunk)" - ] - }, - { - "cell_type": "markdown", - "id": "0d95194e-e9f2-4abf-83dc-c29b5f1f6f2d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "Let's resume with a bad input" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "a79e330d-f849-44ea-af37-221efcffe1a3", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 2 # of times\n", - "{'__interrupt__': (Interrupt(value=\"'-20 is not a valid age. What is your age?\", resumable=True, ns=['node:ed4d470f-5753-d7f3-eec6-4435f5f93f72'], when='during'),)}\n" - ] - } - ], - "source": [ - "bad_input = -20 # Negative number!\n", - "for chunk in graph.stream(Command(resume=bad_input), config):\n", - " print(chunk)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "170b0cde-d94b-4aca-bfea-70f9927f4288", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 3 # of times\n", - "{'__interrupt__': (Interrupt(value=\"'{'foo': 'bar'} is not a valid age. What is your age?\", resumable=True, ns=['node:ed4d470f-5753-d7f3-eec6-4435f5f93f72'], when='during'),)}\n" - ] - } - ], - "source": [ - "bad_input = {\"foo\": \"bar\"} # Not a number!\n", - "for chunk in graph.stream(Command(resume=bad_input), config):\n", - " print(chunk)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "c9d01c77-7a9c-43aa-bbfa-c969b1d3e3f2", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 4 # of times\n", - "{'node': {'human_value': 'The human is 25 years old.'}}\n" - ] - } - ], - "source": [ - "ok_input = 25\n", - "for chunk in graph.stream(Command(resume=ok_input), config):\n", - " print(chunk)" - ] - }, - { - "cell_type": "markdown", - "id": "c7181eea-a0a8-43df-8ce6-b2172ea6cb21", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "## Usage with invoke / ainvoke\n", - "\n", - "If you're using `invoke` and/or `ainvoke`, you will need to explicitly access the state of the graph using `graph.get_state(config)` to determine if there was an interrupt and if so what value it was associated with." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "c9ae2c5f-c81d-4188-9f7e-f3f90e675e12", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 1 # of times\n" - ] - } - ], - "source": [ - "import uuid\n", - "import operator\n", - "from typing import TypedDict, Annotated, Optional\n", - "\n", - "from langgraph.graph import StateGraph\n", - "from langgraph.constants import START, INTERRUPT\n", - "from langgraph.types import interrupt, Command\n", - "from langgraph.checkpoint.memory import MemorySaver\n", - "\n", - "\n", - "class State(TypedDict):\n", - " \"\"\"The graph state.\"\"\"\n", - "\n", - " foo: str\n", - " human_value: Optional[str]\n", - " \"\"\"Human value will be updated using an interrupt.\"\"\"\n", - "\n", - "\n", - "counter = 0\n", - "\n", - "\n", - "def node(state: State):\n", - " global counter\n", - " counter += 1\n", - " print(f\"> Entered the node: {counter} # of times\")\n", - " answer = interrupt(\n", - " # This value will be sent to the client\n", - " # as part of the interrupt information.\n", - " \"what is your age?\"\n", - " )\n", - " print(f\"> Received an input from the interrupt: {answer}\")\n", - " return {\"human_value\": answer}\n", - "\n", - "\n", - "builder = StateGraph(State)\n", - "builder.add_node(\"node\", node)\n", - "builder.add_edge(START, \"node\")\n", - "\n", - "# A checkpointer must be enabled for interrupts to work!\n", - "checkpointer = MemorySaver()\n", - "graph = builder.compile(checkpointer=checkpointer)\n", - "\n", - "config = {\n", - " \"configurable\": {\n", - " \"thread_id\": uuid.uuid4(),\n", - " }\n", - "}\n", - "\n", - "for event in graph.invoke({\"foo\": \"abc\"}, config):\n", - " print" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "f15b73f1-259b-4045-b633-2686873ef1f6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('node',)\n", - "\n", - "PregelTask(id='57efb8b4-1170-b872-647e-60de07598d61', name='node', path=('__pregel_pull', 'node'), error=None, interrupts=(Interrupt(value='what is your age?', resumable=True, ns=['node:57efb8b4-1170-b872-647e-60de07598d61'], when='during'),), state=None, result=None)\n", - "\n", - "(Interrupt(value='what is your age?', resumable=True, ns=['node:57efb8b4-1170-b872-647e-60de07598d61'], when='during'),)\n" - ] - } - ], - "source": [ - "state = graph.get_state(config)\n", - "\n", - "print(state.next)\n", - "print()\n", - "print(state.tasks[0])\n", - "print()\n", - "print(state.tasks[0].interrupts)" - ] - }, - { - "cell_type": "markdown", - "id": "113a746b-c9b7-4efa-ad6c-516f85b9cf5f", - "metadata": {}, - "source": [ - "Let's resume now:" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "69a46d8f-ebe6-4ee0-84c9-30ce81d576c9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "> Entered the node: 2 # of times\n", - "> Received an input from the interrupt: 25\n" - ] - }, - { - "data": { - "text/plain": [ - "{'foo': 'abc', 'human_value': 25}" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ok_input = 25\n", - "graph.invoke(Command(resume=ok_input), config)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.11.4" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 6b80fa67187c5679e21701216459207b1da4388c Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 11:02:28 -0500 Subject: [PATCH 57/72] x --- docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb index 2e6db94d4..411eb4216 100644 --- a/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb +++ b/docs/docs/how-tos/multi-agent-multi-turn-convo.ipynb @@ -242,7 +242,7 @@ "builder.add_node(\"sightseeing_advisor\", sightseeing_advisor)\n", "builder.add_node(\"hotel_advisor\", hotel_advisor)\n", "\n", - "# This adds a node to collet human input, which will route\n", + "# This adds a node to collect human input, which will route\n", "# back to the active agent.\n", "builder.add_node(\"human\", human_node)\n", "\n", From fbb11a6d2e5f95ba06617e55b27926ff9598007e Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 11:08:24 -0500 Subject: [PATCH 58/72] x --- docs/docs/concepts/low_level.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index 2b99e55d6..7905590b6 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -377,6 +377,10 @@ def lookup_user_info(tool_call_id: Annotated[str, InjectedToolCallId], config: R If you are using tools that update state via `Command`, we recommend using prebuilt [`ToolNode`][langgraph.prebuilt.tool_node.ToolNode] which automatically handles tools returning `Command` objects and propagates them to the graph state. If you're writing a custom node that calls tools, you would need to manually propagate `Command` objects returned by the tools as the update from node. +### Human-in-the-loop + +`Command` is an important part of human-in-the-loop workflows: when using `interrupt()` to collect user input, `Command` is then used to supply the input and resume execution via `Command(resume="User input")`. Check out [this conceptual guide](./human_in_the_loop.md) for more information. + ## Persistence LangGraph provides built-in persistence for your agent's state using [checkpointers][langgraph.checkpoint.base.BaseCheckpointSaver]. Checkpointers save snapshots of the graph state at every superstep, allowing resumption at any time. This enables features like human-in-the-loop interactions, memory management, and fault-tolerance. You can even directly manipulate a graph's state after its execution using the @@ -515,7 +519,7 @@ The simplest way to create subgraph nodes is by using a [compiled subgraph](#com If you pass extra keys to the subgraph node (i.e., in addition to the shared keys), they will be ignored by the subgraph node. Similarly, if you return extra keys from the subgraph, they will be ignored by the parent graph. ```python -from langgraph.graph import START, StateGraph +from langgraph.graph import StateGraph from typing import TypedDict class State(TypedDict): From 6907d1b775e96aa7efa804dd5d1bf99c59388ab9 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 11:32:33 -0500 Subject: [PATCH 59/72] x --- docs/docs/concepts/breakpoints.md | 169 +----------------------- docs/docs/concepts/human_in_the_loop.md | 111 ++++++++++++++-- docs/docs/concepts/index.md | 2 +- docs/docs/concepts/low_level.md | 19 +-- 4 files changed, 113 insertions(+), 188 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index 8608e51eb..6e5235751 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -1,6 +1,6 @@ # Breakpoints -Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. +Breakpoints pause graph execution at specific points and enable stepping through execution step by step. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. Breakpoints can also be used to enable [**human-in-the-loop**](./human_in_the_loop.md) workflows, though we recommend using the [`interrupt` function](#the-interrupt-function) for this purpose. ## Requirements @@ -15,68 +15,9 @@ To use breakpoints, you will need to: There are two places where you can set breakpoints: -1. **Inside** a node using the [`interrupt` function](#the-interrupt-function) (or the older [`NodeInterrupt` exception](#nodeinterrupt-exception)). -2. **Before** or **after** a node executes by setting breakpoints at **compile time** or **run time**. We call these [**static breakpoints**](#static-breakpoints). +1. **Before** or **after** a node executes by setting breakpoints at **compile time** or **run time**. We call these [**static breakpoints**](#static-breakpoints). +2. **Inside** a node using the [`NodeInterrupt` exception](#nodeinterrupt-exception). -The **recommended** way to set breakpoints is using the [`interrupt` function](#the-interrupt-function). This method is easier to use and more flexible than the older methods. - -### The `interrupt` function - -Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing the developer to collect user input, validate the graph state, or make decisions before resuming execution. - -```python -from langgraph.types import interrupt - -def human_approval(state: State): - ... - answer = interrupt( - # Interrupt information to surface to the client. - # Can be any JSON serializable value. - { - "question": "Can we proceed?", - "llm_output": state["llm_output"] - } - ) - - if answer['approved']: - # Proceed with the action - ... - else: - # Do something else - ... - - -# Add the node to the graph -graph_builder.add_node("human_approval", human_approval) -# Compile the graph with a checkpointer -graph = graph_builder.compile(checkpointer=checkpointer) - -# Run the graph until the breakpoint -thread_config = {"configurable": {"thread_id": "some_id"}} -for event in graph.stream(inputs, thread_config, stream_mode="values"): - print(event) -``` - -```pycon -{'__interrupt__': ( - Interrupt( - value={'question': 'Can we proceed?', "llm_output": "..."}, - resumable=True, - ns=['node:5df255f7-d683-1a99-b7c8-00dd534aed8e'], - when='during' - ), - ) -} -``` - -Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive. The `Command` primitive provides several options to control and modify the graph's state during resumption: - -```python -# Resume the graph with the user's input -for event in graph.stream(Command(resume={"approved": True}), config=thread_config): - print(event) -``` - ### Static breakpoints Static breakpoints are triggered either **before** or **after** a node executes. You can set static breakpoints by specifying `interrupt_before` and `interrupt_after` at **"compile" time** or **run time**. @@ -142,7 +83,8 @@ node at a time or if you want to pause the graph execution at specific nodes. ### `NodeInterrupt` exception -We recommend that you [**use the `interrupt` function instead**](#the-interrupt-function) of the `NodeInterrupt` exception. The `interrupt` function is easier to use and more flexible. +We recommend that you [**use the `interrupt` function instead**](#the-interrupt-function) of the `NodeInterrupt` exception if you're trying to implement +[human-in-the-loop](./human_in_the_loop.md) workflows. The `interrupt` function is easier to use and more flexible. ??? node "`NodeInterrupt` exception" @@ -183,107 +125,6 @@ We recommend that you [**use the `interrupt` function instead**](#the-interrupt- print(event) ``` -## The `Command` primitive - -When using the `interrupt` function, the graph will pause at the breakpoint and wait for user input. - -Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive which can be passed through the `invoke`, `ainvoke`, `stream` or `astream` methods. - -The `Command` primitive provides several options to control and modify the graph's state during resumption: - -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. The `resume` value is only used when using `interrupt` as a breakpoint. - - ```python - # Resume graph execution with the user's input. - graph.invoke(Command(resume={"age": "25"}), thread_config) - ``` - -2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. - - ```python - # Update the graph state and resume. - # You must provide a `resume` value if using an `interrupt`. - graph.invoke(Command(update={"foo": "bar"}, resume="Let's go!!!"), thread_config) - ``` - -By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state. - -## Using with `invoke` and `ainvoke` - -When you use `stream` or `astream` to run the graph, you will receive an `Interrupt` event that let you know that a breakpoint has been hit. - -`invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. - -```python -# Run the graph up to the breakpoint -result = graph.invoke(inputs, thread_config) -# Get the graph state to get interrupt information. -state = graph.get_state(thread_config) -# Print the state values -print(state.values) -# Print the pending tasks -print(state.tasks) -# Resume the graph with the user's input. -graph.invoke(Command(resume={"age": "25"}), thread_config) -``` - -```pycon -{'foo': 'bar'} # State values -( - PregelTask( - id='5d8ffc92-8011-0c9b-8b59-9d3545b7e553', - name='node_foo', - path=('__pregel_pull', 'node_foo'), - error=None, - interrupts=(Interrupt(value='value_in_interrupt', resumable=True, ns=['node_foo:5d8ffc92-8011-0c9b-8b59-9d3545b7e553'], when='during'),), state=None, - result=None - ), -) # Pending tasks. interrupts -``` - -## How does resuming from a breakpoint work? - -!!! warning - - Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered or where the `input()` function was called. - -A critical aspect of using breakpoints is understanding how resuming from a breakpoint works. When you resume execution after a breakpoint, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. - -**All** code from the beginning of the node to the **breakpoint** will be re-executed. - -```python -counter = 0 -def node(state: State): - # All the code from the beginning of the node to the breakpoint will be re-executed - # when the graph resumes. - global counter - counter += 1 - print(f"> Entered the node: {counter} # of times") - # Pause the graph and wait for user input. - answer = interrupt() - print("The value of counter is:", counter) - ... -``` - -Upon **resuming** the graph, the counter will be incremented a second time, resulting in the following output: - -```pycon -> Entered the node: 2 # of times -The value of counter is: 2 -``` - -Keep the following considerations in mind when using the `interrupt` function: - -1. **Side effects**: Place side-effecting code, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node resumes. -2. **Multiple interrupts**: Using multiple `interrupt` calls in a node can be very useful (e.g., for run-time validation), but the order and number of calls must remain consistent to prevent mismatched resume values. As a result, we recommend that you structure your code in a way that avoids providing both a `resume` and a state `update` value (e.g., `Command(resume=resume, update=update)`) at the same time. -3. **Subgraphs**: If you're invoking a subgraph [as a function](low_level.md#as-a-function), the **parent** graph will be re-run from the **beginning of the node** where the subgraph was invoked. - -## Best practices - -* Use the [`interrupt`](#the-interrupt-function) function to set breakpoints and collect user input. -* Use [`Command`](#the-command-primitive) to resume execution and control the graph state. -* Consider putting all side effects (e.g., API calls) after the `interrupt` to prevent duplication. See [How does resuming from a breakpoint work?](#how-does-resuming-from-a-breakpoint-work) - ## Additional Resources 📚 - [**Conceptual Guide: Persistence**](persistence.md): Read the persistence guide for more context about persistence. diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index f04d5e6d1..47c37dd37 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -34,6 +34,10 @@ def human_node(state: State): # Update the state with the human's input or route the graph based on the input. ... +graph = graph_builder.compile( + checkpointer=checkpointer # Required for `interrupt` to work +) + # Run the graph and hit the breakpoint thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(some_input, config=thread_config) @@ -42,7 +46,14 @@ graph.invoke(some_input, config=thread_config) graph.invoke(Command(resume=value_from_human), config=thread_config) ``` -Please read the [Breakpoints](breakpoints.md) guide for more information on using the `interrupt` function. +## Requirements + +To use `interrupt` in your graph, you need to: + +1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. +2. **Call `interrupt()`** in the appropriate place. See the [Design Patterns](#design-patterns) section for examples. +3. **Run the graph** with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. +4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` (see [**The `Command` primitive**](#the-command-primitive)). ## Design Patterns @@ -293,6 +304,95 @@ def human_node(state: State): } ``` +## The `Command` primitive + +When using the `interrupt` function, the graph will pause at the breakpoint and wait for user input. + +Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive which can be passed through the `invoke`, `ainvoke`, `stream` or `astream` methods. + +The `Command` primitive provides several options to control and modify the graph's state during resumption: + +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. The `resume` value is only used when using `interrupt` as a breakpoint. + + ```python + # Resume graph execution with the user's input. + graph.invoke(Command(resume={"age": "25"}), thread_config) + ``` + +2. **Update the graph state**: Modify the graph state using `Command(update=update)`. Note that resumption starts from the beginning of the node where the `interrupt` was used. Execution resumes from the beginning of the node where the `interrupt` was used, but with the updated state. + + ```python + # Update the graph state and resume. + # You must provide a `resume` value if using an `interrupt`. + graph.invoke(Command(update={"foo": "bar"}, resume="Let's go!!!"), thread_config) + ``` + +By leveraging `Command`, you can resume graph execution, handle user inputs, and dynamically adjust the graph's state. + +## Using with `invoke` and `ainvoke` + +When you use `stream` or `astream` to run the graph, you will receive an `Interrupt` event that let you know that a breakpoint has been hit. + +`invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. + +```python +# Run the graph up to the breakpoint +result = graph.invoke(inputs, thread_config) +# Get the graph state to get interrupt information. +state = graph.get_state(thread_config) +# Print the state values +print(state.values) +# Print the pending tasks +print(state.tasks) +# Resume the graph with the user's input. +graph.invoke(Command(resume={"age": "25"}), thread_config) +``` + +```pycon +{'foo': 'bar'} # State values +( + PregelTask( + id='5d8ffc92-8011-0c9b-8b59-9d3545b7e553', + name='node_foo', + path=('__pregel_pull', 'node_foo'), + error=None, + interrupts=(Interrupt(value='value_in_interrupt', resumable=True, ns=['node_foo:5d8ffc92-8011-0c9b-8b59-9d3545b7e553'], when='during'),), state=None, + result=None + ), +) # Pending tasks. interrupts +``` + +## How does resuming from a breakpoint work? + +!!! warning + + Resuming from an `interrupt` is **different** from Python's `input()` function, where execution resumes from the exact point where the `input()` function was called. + +A critical aspect of using breakpoints is understanding how resuming from a breakpoint works. When you resume execution after a breakpoint, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. + +**All** code from the beginning of the node to the **breakpoint** will be re-executed. + +```python +counter = 0 +def node(state: State): + # All the code from the beginning of the node to the breakpoint will be re-executed + # when the graph resumes. + global counter + counter += 1 + print(f"> Entered the node: {counter} # of times") + # Pause the graph and wait for user input. + answer = interrupt() + print("The value of counter is:", counter) + ... +``` + +Upon **resuming** the graph, the counter will be incremented a second time, resulting in the following output: + +```pycon +> Entered the node: 2 # of times +The value of counter is: 2 +``` + ## Gotchyas !!! warning @@ -442,15 +542,6 @@ To avoid issues, refrain from dynamically changing the node's structure between {'human_node': {'age': 'John', 'name': 'N/A'}} ``` - - -## Best practices - -* Use the [`interrupt`](breakpoints.md#the-interrupt-function) function to set breakpoints and collect user input. -* Use [`Command`](breakpoints.md#the-command-primitive) to resume execution and control the graph state. -* Consider putting all side effects (e.g., API calls) after the `interrupt` to prevent duplication. -* Understand [how resuming from a breakpoint works](breakpoints.md#how-does-resuming-from-a-breakpoint-work) to avoid common gotchas. - ## Additional Resources 📚 - [**Conceptual Guide: Persistence**](persistence.md#replay): Read the persistence guide for more context on replaying. diff --git a/docs/docs/concepts/index.md b/docs/docs/concepts/index.md index f0bf563bf..4d8e5f06f 100644 --- a/docs/docs/concepts/index.md +++ b/docs/docs/concepts/index.md @@ -24,7 +24,7 @@ The conceptual guide does not cover step-by-step instructions or specific implem - [LangGraph Glossary](low_level.md): LangGraph workflows are designed as graphs, with nodes representing different components and edges representing the flow of information between them. This guide provides an overview of the key concepts associated with LangGraph graph primitives. - [Common Agentic Patterns](agentic_concepts.md): An agent uses an LLM to pick its own control flow to solve more complex problems! Agents are a key building block in many LLM applications. This guide explains the different types of agent architectures and how they can be used to control the flow of an application. - [Multi-Agent Systems](multi_agent.md): Complex LLM applications can often be broken down into multiple agents, each responsible for a different part of the application. This guide explains common patterns for building multi-agent systems. -- [Breakpoints](breakpoints.md): Breakpoints allow pausing the execution of a graph at specific points. Breakpoints are crucial for human-in-the-loop workflows, allowing human review before continuing. +- [Breakpoints](breakpoints.md): Breakpoints allow pausing the execution of a graph at specific points. Breakpoints allow stepping through graph execution for debugging purposes. - [Human-in-the-Loop](human_in_the_loop.md): Explains different ways of integrating human feedback into a LangGraph application. - [Time Travel](time-travel.md): Time travel allows you to replay past actions in your LangGraph application to explore alternative paths and debug issues. - [Persistence](persistence.md): LangGraph has a built-in persistence layer, implemented through checkpointers. This persistence layer helps to support powerful capabilities like human-in-the-loop, memory, time travel, and fault-tolerance. diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index 7905590b6..a2a36534b 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -446,19 +446,6 @@ graph.invoke(inputs, config={"recursion_limit": 5, "configurable":{"llm": "anthr Read [this how-to](https://langchain-ai.github.io/langgraph/how-tos/recursion-limit/) to learn more about how the recursion limit works. -## Breakpoints - -Breakpoints pause graph execution at specific points, enabling [**human-in-the-loop**](./human_in_the_loop.md) workflows and debugging. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. - -You **MUST** use a [checkpointer](./persistence.md) when using breakpoints as breakpoints require the ability to save the state of the graph at the time of pausing. - -There are two places where you can set breakpoints: - -1. **Inside** a node using the [`interrupt` function](#the-interrupt-function) (or the older [`NodeInterrupt` exception](#nodeinterrupt-exception)). -2. **Before** or **after** a node executes by setting breakpoints at **compile time** or **run time**. We call these [**static breakpoints**](#static-breakpoints). - -Read more about breakpoints in the [Breakpoints conceptual guide](./breakpoints.md). - ## `interrupt` Use the [interrupt](../reference/types.md/#langgraph.types.interrupt) function to **pause** the graph at specific points to collect user input. The `interrupt` function surfaces interrupt information to the client, allowing the developer to collect user input, validate the graph state, or make decisions before resuming execution. @@ -480,6 +467,12 @@ Resuming the graph is done by passing a [`Command`](#command) object to the grap Read more about how the `interrupt` is used for **human-in-the-loop** workflows in the [Human-in-the-loop conceptual guide](./human_in_the_loop.md). +## Breakpoints + +Breakpoints pause graph execution at specific points and enable stepping through execution step by step. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. Breakpoints can also be used to enable [**human-in-the-loop**](./human_in_the_loop.md) workflows, though we recommend using the [`interrupt` function](#interrupt-function) for this purpose. + +Read more about breakpoints in the [Breakpoints conceptual guide](./breakpoints.md). + ## Subgraphs A subgraph is a [graph](#graphs) that is used as a [node](#nodes) in another graph. This is nothing more than the age-old concept of encapsulation, applied to LangGraph. Some reasons for using subgraphs are: From d9c0a5d827ade21b0d676903f2dc4b24311cc625 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 11:40:09 -0500 Subject: [PATCH 60/72] x --- docs/docs/concepts/human_in_the_loop.md | 35 ++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 47c37dd37..d2ad6fa49 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -38,7 +38,7 @@ graph = graph_builder.compile( checkpointer=checkpointer # Required for `interrupt` to work ) -# Run the graph and hit the breakpoint +# Run the graph until the interrupt thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(some_input, config=thread_config) @@ -52,7 +52,7 @@ To use `interrupt` in your graph, you need to: 1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. 2. **Call `interrupt()`** in the appropriate place. See the [Design Patterns](#design-patterns) section for examples. -3. **Run the graph** with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. +3. **Run the graph** with a [**thread ID**](./persistence.md#threads) until the `interrupt` is hit. 4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` (see [**The `Command` primitive**](#the-command-primitive)). ## Design Patterns @@ -99,7 +99,7 @@ def human_approval(state: State) -> Command[Literal["some_node", "another_node"] graph_builder.add_node("human_approval", human_approval) graph = graph_builder.compile(checkpointer=checkpointer) -# After running the graph and hitting the breakpoint, the graph will pause. +# After running the graph and hitting the interrupt, the graph will pause. # Resume it with either an approval or rejection. thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(Command(resume=True), config=thread_config) @@ -141,7 +141,7 @@ graph = graph_builder.compile(checkpointer=checkpointer) ... -# After running the graph and hitting the breakpoint, the graph will pause. +# After running the graph and hitting the interrupt, the graph will pause. # Resume it with the edited text. thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke( @@ -236,7 +236,7 @@ it may be part of a larger graph consisting of multiple nodes and include a cond graph_builder.add_edge("human_input", "agent") graph = graph_builder.compile(checkpointer=checkpointer) - # After running the graph and hitting the breakpoint, the graph will pause. + # After running the graph and hitting the interrupt, the graph will pause. # Resume it with the human's input. graph.invoke( Command(resume="hello!"), @@ -306,13 +306,13 @@ def human_node(state: State): ## The `Command` primitive -When using the `interrupt` function, the graph will pause at the breakpoint and wait for user input. +When using the `interrupt` function, the graph will pause at the interrupt and wait for user input. Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive which can be passed through the `invoke`, `ainvoke`, `stream` or `astream` methods. The `Command` primitive provides several options to control and modify the graph's state during resumption: -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. The `resume` value is only used when using `interrupt` as a breakpoint. +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. ```python # Resume graph execution with the user's input. @@ -331,12 +331,12 @@ By leveraging `Command`, you can resume graph execution, handle user inputs, and ## Using with `invoke` and `ainvoke` -When you use `stream` or `astream` to run the graph, you will receive an `Interrupt` event that let you know that a breakpoint has been hit. +When you use `stream` or `astream` to run the graph, you will receive an `Interrupt` event that let you know the `interrupt` was triggered. `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. ```python -# Run the graph up to the breakpoint +# Run the graph up to the interrupt result = graph.invoke(inputs, thread_config) # Get the graph state to get interrupt information. state = graph.get_state(thread_config) @@ -362,20 +362,20 @@ graph.invoke(Command(resume={"age": "25"}), thread_config) ) # Pending tasks. interrupts ``` -## How does resuming from a breakpoint work? +## How does resuming from an interrupt work? !!! warning Resuming from an `interrupt` is **different** from Python's `input()` function, where execution resumes from the exact point where the `input()` function was called. -A critical aspect of using breakpoints is understanding how resuming from a breakpoint works. When you resume execution after a breakpoint, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. +A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution after an `interrupt`, graph execution starts from the **beginning** of the **graph node** where the last `interrupt` was triggered. -**All** code from the beginning of the node to the **breakpoint** will be re-executed. +**All** code from the beginning of the node to the `interrupt` will be re-executed. ```python counter = 0 def node(state: State): - # All the code from the beginning of the node to the breakpoint will be re-executed + # All the code from the beginning of the node to the interrupt will be re-executed # when the graph resumes. global counter counter += 1 @@ -393,15 +393,15 @@ Upon **resuming** the graph, the counter will be incremented a second time, resu The value of counter is: 2 ``` -## Gotchyas +## Common Pitfalls !!! warning - Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered or where the `input()` function was called. + Resuming from a interrupt is **different** from using Python's `input()` function, where execution resumes from the exact point where `input()` was called. -A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. +A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution, the graph execution starts from the **beginning** of the **graph node** where the `interrupt` was triggered. -**All** code from the beginning of the node to the **breakpoint** will be re-executed. +**All** code from the beginning of the node to the `interrupt` will be re-executed. ### Side-effects @@ -545,6 +545,5 @@ To avoid issues, refrain from dynamically changing the node's structure between ## Additional Resources 📚 - [**Conceptual Guide: Persistence**](persistence.md#replay): Read the persistence guide for more context on replaying. -- [**Conceptual Guide: Breakpoints**](breakpoints.md): Read the breakpoints guide for more context on breakpoints. - [**How to Guides: Human-in-the-loop**](../how-tos/index.md#human-in-the-loop): Learn how to implement human-in-the-loop workflows in LangGraph. - [**How to implement multi-turn conversations**](../how-tos/multi-agent-multi-turn-convo.ipynb): Learn how to implement multi-turn conversations in LangGraph. From 7f48428d16fac75f9417c29fab685494c76fef0c Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 11:41:00 -0500 Subject: [PATCH 61/72] x --- docs/docs/concepts/human_in_the_loop.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index d2ad6fa49..7f7576501 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -395,14 +395,6 @@ The value of counter is: 2 ## Common Pitfalls -!!! warning - - Resuming from a interrupt is **different** from using Python's `input()` function, where execution resumes from the exact point where `input()` was called. - -A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution, the graph execution starts from the **beginning** of the **graph node** where the `interrupt` was triggered. - -**All** code from the beginning of the node to the `interrupt` will be re-executed. - ### Side-effects Place code with side effects, such as API calls, **after** the `interrupt` to avoid duplication, as these are re-triggered every time the node is resumed. From 0ad470162ca78a1715722fa00541168d990b9fdd Mon Sep 17 00:00:00 2001 From: vbarda Date: Wed, 11 Dec 2024 11:54:19 -0500 Subject: [PATCH 62/72] fix links --- docs/docs/concepts/breakpoints.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md index 6e5235751..c38431071 100644 --- a/docs/docs/concepts/breakpoints.md +++ b/docs/docs/concepts/breakpoints.md @@ -1,6 +1,6 @@ # Breakpoints -Breakpoints pause graph execution at specific points and enable stepping through execution step by step. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. Breakpoints can also be used to enable [**human-in-the-loop**](./human_in_the_loop.md) workflows, though we recommend using the [`interrupt` function](#the-interrupt-function) for this purpose. +Breakpoints pause graph execution at specific points and enable stepping through execution step by step. Breakpoints are powered by LangGraph's [**persistence layer**](./persistence.md), which saves the state after each graph step. Breakpoints can also be used to enable [**human-in-the-loop**](./human_in_the_loop.md) workflows, though we recommend using the [`interrupt` function](./human_in_the_loop.md#interrupt) for this purpose. ## Requirements @@ -9,7 +9,7 @@ To use breakpoints, you will need to: 1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. 2. [**Set breakpoints**](#setting-breakpoints) to specify where execution should pause. 3. **Run the graph** with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. -4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` (see [**The `Command` primitive**](#the-command-primitive)). +4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` (see [**The `Command` primitive**](./human_in_the_loop.md#the-command-primitive)). ## Setting breakpoints From 54a5e45d217a7fcffca0fee01236f9a1051bb6a0 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 12:37:54 -0500 Subject: [PATCH 63/72] x --- docs/docs/concepts/human_in_the_loop.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 7f7576501..2f246a8da 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -105,7 +105,7 @@ thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(Command(resume=True), config=thread_config) ``` -See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. +See [how to review tool calls](../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. ### Review & Edit State @@ -150,7 +150,7 @@ graph.invoke( ) ``` -See [How to wait for user input using interrupt](../../how-tos/human_in_the_loop/wait-user-input) for a more detailed example. +See [How to wait for user input using interrupt](../how-tos/human_in_the_loop/wait-user-input) for a more detailed example. ### Review Tool Calls @@ -193,7 +193,7 @@ def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: return Command(goto="call_llm", update={"messages": [feedback_msg]}) ``` -See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. +See [how to review tool calls](../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. ### Multi-turn conversation From 11ce54d7e4c97190b8131df7da8584b787578dd5 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 12:39:53 -0500 Subject: [PATCH 64/72] x --- docs/docs/concepts/human_in_the_loop.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 2f246a8da..8a5a77453 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -2,7 +2,7 @@ !!! tip "This guide uses the new `interrupt` function." - As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [interrupt](../reference/types.md#langgraph.types.interrupt) function as it significantly simplifies **human-in-the-loop** patterns. Please see the [Breakpoints](breakpoints.md) guide for more information. + As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [`interrupt` function][langgraph.types.interrupt] as it simplifies **human-in-the-loop** patterns. Please see the [Breakpoints](breakpoints.md) guide for more information. If you're looking for the previous version of this conceptual guide, which relied on static breakpoints and `NodeInterrupt` exception, it is available [here](v0-human-in-the-loop.md). @@ -105,7 +105,7 @@ thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(Command(resume=True), config=thread_config) ``` -See [how to review tool calls](../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. +See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a more detailed example. ### Review & Edit State @@ -150,7 +150,7 @@ graph.invoke( ) ``` -See [How to wait for user input using interrupt](../how-tos/human_in_the_loop/wait-user-input) for a more detailed example. +See [How to wait for user input using interrupt](../../how-tos/human_in_the_loop/wait-user-input) for a more detailed example. ### Review Tool Calls @@ -193,7 +193,7 @@ def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: return Command(goto="call_llm", update={"messages": [feedback_msg]}) ``` -See [how to review tool calls](../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. +See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. ### Multi-turn conversation From 3db266bb93c879415d8df007bd304db5a3c3c253 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 12:41:03 -0500 Subject: [PATCH 65/72] x --- docs/docs/concepts/human_in_the_loop.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 8a5a77453..15413b3c8 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -105,8 +105,6 @@ thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(Command(resume=True), config=thread_config) ``` -See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a more detailed example. - ### Review & Edit State
    @@ -150,8 +148,6 @@ graph.invoke( ) ``` -See [How to wait for user input using interrupt](../../how-tos/human_in_the_loop/wait-user-input) for a more detailed example. - ### Review Tool Calls
    @@ -193,8 +189,6 @@ def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: return Command(goto="call_llm", update={"messages": [feedback_msg]}) ``` -See [how to review tool calls](../../how-tos/human_in_the_loop/review-tool-calls) for a more detailed example. - ### Multi-turn conversation
    @@ -273,8 +267,6 @@ it may be part of a larger graph consisting of multiple nodes and include a cond ) ``` -See [how to implement multi-turn conversations](../how-tos/multi-agent-multi-turn-convo.ipynb) for a more detailed example. - ### Validating human input If you need to validate the input provided by the human within the graph itself (rather than on the client side), you can achieve this by using multiple interrupt calls within a single node. From 32702dea0871555ff5f884715e2461c04a29c141 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 12:42:54 -0500 Subject: [PATCH 66/72] x --- docs/docs/concepts/human_in_the_loop.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 15413b3c8..2d5ffd7f9 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -105,6 +105,8 @@ thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(Command(resume=True), config=thread_config) ``` +See [how to review tool calls](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a more detailed example. + ### Review & Edit State
    @@ -148,6 +150,8 @@ graph.invoke( ) ``` +See [How to wait for user input using interrupt](../how-tos/human_in_the_loop/wait-user-input.ipynb) for a more detailed example. + ### Review Tool Calls
    @@ -189,6 +193,8 @@ def human_review_node(state) -> Command[Literal["call_llm", "run_tool"]]: return Command(goto="call_llm", update={"messages": [feedback_msg]}) ``` +See [how to review tool calls](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for a more detailed example. + ### Multi-turn conversation
    @@ -267,6 +273,8 @@ it may be part of a larger graph consisting of multiple nodes and include a cond ) ``` +See [how to implement multi-turn conversations](../how-tos/multi-agent-multi-turn-convo.ipynb) for a more detailed example. + ### Validating human input If you need to validate the input provided by the human within the graph itself (rather than on the client side), you can achieve this by using multiple interrupt calls within a single node. From 630195a108eded0c30cd7e551e43288bf4a2d4c0 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 12:50:32 -0500 Subject: [PATCH 67/72] fix one more link --- docs/docs/how-tos/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index b28b7f025..24083d328 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -57,7 +57,7 @@ Key workflows: Other methods: -- [How to add static breakpoints](human_in_the_loop/breakpoints.ipynb): Use for debugging purposes. For [**human-in-the-loop**](../concepts/human_in_the_loop.md) workflows, we recommend the [`interrupt()`](../../../reference/types/#langgraph.types.interrupt) function instead. +- [How to add static breakpoints](human_in_the_loop/breakpoints.ipynb): Use for debugging purposes. For [**human-in-the-loop**](../concepts/human_in_the_loop.md) workflows, we recommend the [`interrupt` function][langgraph.types.interrupt] instead. - [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb): Edit graph state using `graph.update_state` method. Use this if implementing a **human-in-the-loop** workflow via **static breakpoints**. - [How to add dynamic breakpoints with `NodeInterrupt`](human_in_the_loop/dynamic_breakpoints.ipynb): **Not recommended**: Use the [`interrupt` function](../concepts/human_in_the_loop.md) instead. From 25d45127446c80d04deaf8066b143d353acb5532 Mon Sep 17 00:00:00 2001 From: vbarda Date: Wed, 11 Dec 2024 12:58:26 -0500 Subject: [PATCH 68/72] update cassettes --- ...turn-convo_161e0cf1-d13a-4026-8f89-bdab67d1ad4d.msgpack.zlib | 1 + ...nt-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib | 1 + ...nt-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib | 1 + ...tool-calls_1b3aa6fc-c7fb-4819-8d7f-ba6057cc4edf.msgpack.zlib | 2 +- ...tool-calls_2561a38f-edb5-4b44-b2d7-6a7b70d2e6b7.msgpack.zlib | 2 +- ...tool-calls_3f05f8b6-6128-4de5-8884-862fc93f1227.msgpack.zlib | 2 +- ...tool-calls_85e452f8-f33a-4ead-bb4d-7386cdba8edc.msgpack.zlib | 1 - ...tool-calls_a30d40ad-611d-4ec3-84be-869ea05acb89.msgpack.zlib | 2 +- ...tool-calls_b2f73998-baae-4c00-8a90-f4153e924941.msgpack.zlib | 1 + ...tool-calls_d57d5131-7912-4216-aa87-b7272507fa51.msgpack.zlib | 2 +- ...tool-calls_df4a9900-d953-4465-b8af-bd2858cb63ea.msgpack.zlib | 1 - ...tool-calls_ec77831c-e6b8-4903-9146-e098a4b2fda1.msgpack.zlib | 2 +- ...tool-calls_f9a0d5d4-52ff-49e0-a6f4-41f9a0e844d8.msgpack.zlib | 2 +- ...user-input_58eae42d-be32-48da-8d0a-ab64471657d9.msgpack.zlib | 1 - ...user-input_a9f599b5-1a55-406b-a76b-f52b3ca06975.msgpack.zlib | 2 +- ...user-input_cfd140f0-a5a6-4697-8115-322242f197b5.msgpack.zlib | 2 +- docs/cassettes/wait-user-input_f5319e01.msgpack.zlib | 1 - 17 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 docs/cassettes/multi-agent-multi-turn-convo_161e0cf1-d13a-4026-8f89-bdab67d1ad4d.msgpack.zlib create mode 100644 docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib create mode 100644 docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib delete mode 100644 docs/cassettes/review-tool-calls_85e452f8-f33a-4ead-bb4d-7386cdba8edc.msgpack.zlib create mode 100644 docs/cassettes/review-tool-calls_b2f73998-baae-4c00-8a90-f4153e924941.msgpack.zlib delete mode 100644 docs/cassettes/review-tool-calls_df4a9900-d953-4465-b8af-bd2858cb63ea.msgpack.zlib delete mode 100644 docs/cassettes/wait-user-input_58eae42d-be32-48da-8d0a-ab64471657d9.msgpack.zlib delete mode 100644 docs/cassettes/wait-user-input_f5319e01.msgpack.zlib diff --git a/docs/cassettes/multi-agent-multi-turn-convo_161e0cf1-d13a-4026-8f89-bdab67d1ad4d.msgpack.zlib b/docs/cassettes/multi-agent-multi-turn-convo_161e0cf1-d13a-4026-8f89-bdab67d1ad4d.msgpack.zlib new file mode 100644 index 000000000..25b20565b --- /dev/null +++ b/docs/cassettes/multi-agent-multi-turn-convo_161e0cf1-d13a-4026-8f89-bdab67d1ad4d.msgpack.zlib @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib b/docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib new file mode 100644 index 000000000..8c7f584d7 --- /dev/null +++ b/docs/cassettes/multi-agent-network_26a0d4df-ff99-40f0-92a8-0b3f2c591040.msgpack.zlib @@ -0,0 +1 @@ +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Y+iT51iVvbT37TUVc1lBXfqLkXU6fOH+85oXOU4P2OQt2bXk67vO4F4Wib14avyNUP3T+ke8P3v7P1qmz1xo23Bc1d9b2G+6Zkvduk/mHB2tCFaEX/3R+84YHYpWG+tqyl95eN7BqdmHhmdOt3Ldnv5669tzmEx3s+dumDfYvxyjv8co1ZateHfj0x88a34luu/OJL8p+sFR//UXjkn1PDb7l+vt7B7fTRPzKpB+ToqMaP/+5stPxzYzj5IYlz1esvMM74fzpaVF3fMCuenmyP++zte2PPcOuex0f609yjc8+4rr3nXbKd8n25dOH0zqoP5469d0LJ757+KmHF9UMlk8aPFxYvnrg1tmb9zfa/nG8oaX3+Bs1oW+/ejr008zJj/g86WemrFxf01V+IOo6++kqOf78bwuX3XRocG7fLRcX233NGeumdcTcFd0xdx15H9GRaCn9/dnopctufOX9oij15txXks/1Jn0fN2Xl8q+mVF/31oGkyXOK84botrvoN4mKmpRfxQ1suvP6twueLHtn74xFxXuetVutezJXVX18MPrI2aWf3Hgi63j8K/uNMXvH7Uh67jbLsjn+1eN2r64qSLdRzx/lyi/8ZeKy9KN9qYcU/m3nF+1bN6+cOy52N9XxRI69/b0FJ9tbb78u9qEjpe0J888UPXNk9+v8Xyfnln7o+GlF26k9ju/zc9IOzPTIf+YPbst871yVq3vqB3U909L23HOmbd6bKRPGT0ztWp99bvHN4ZefcRR3XlDuf2PRS7snTji0um3fhntbjq15+VhRimXOmvU77k5dsaB5f5un6ctThw5MubC5n3ksOwO9cXytwz5r54726thWebV1zqHWvKdaOsa1nd35yfILN0OxD7YOlJdxPYxjhfvix/UPFH6Udml/itrcm9wZ212/bfaF1075voxZd/HYrl9fTG4mA457nc4zh4/W772pM7Q99tHxfGgo7uc842/uTpxk2zB50okVdxNlMU9aO2KbXz25LfTgBHHitPdP/+2DLbOemNr6u5rDzy/b8u6+G/O+fffnsqPVH4Y+Hzp2afmScV1xG7KFh9DGT998/LC3+Wvnpa3eAVNDS9aHr2UGHFy546uMhoGFpUscW44WbLr/ubZZVHD9j7doVRIT5f/Xvhb2hqiofwOhx+ms \ No newline at end of file diff --git a/docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib b/docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib new file mode 100644 index 000000000..798718a46 --- /dev/null +++ b/docs/cassettes/multi-agent-network_68a547d4-0a15-43bd-aeed-c9ba1dfe388f.msgpack.zlib @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_1b3aa6fc-c7fb-4819-8d7f-ba6057cc4edf.msgpack.zlib b/docs/cassettes/review-tool-calls_1b3aa6fc-c7fb-4819-8d7f-ba6057cc4edf.msgpack.zlib index 58facdc65..23ed0cf9b 100644 --- a/docs/cassettes/review-tool-calls_1b3aa6fc-c7fb-4819-8d7f-ba6057cc4edf.msgpack.zlib +++ b/docs/cassettes/review-tool-calls_1b3aa6fc-c7fb-4819-8d7f-ba6057cc4edf.msgpack.zlib @@ -1 +1 @@ -eNqFVGtsFFUUboMISjBCTBRj0mFFg7F3d2ZnH2yJlWYLtJTa2l0tYJtyO3N3Z+js3GHmbmm7qQkVyo9SzNBgUBOidrtrl9p2IwqhEBLERMLDWvBRFYIRX8SoGPxj0uCd7W5b0qbOrzv3fOec75zv3NORbEa6IWM1f0BWCdKhQOiPYXYkdbQzigyyJxFBRMJivLoqEOyN6vL4UxIhmlHkcEBNtkOVSDrWZMEu4IijmXNEkGHAMDLijVhs/Tb/yZgtAlsaCG5CqmErYjjW6SpkbDkUvXklZtOxgujJFjWQbqNWAVMqKrGuJHmlrb3e8sAiUqwbQYFREQEeuIGBVRUR4KQxWY+TtVwJxko2qgojmai7ECQS0hsMBHVBskAiMgRd1qxKLUAgY2BCWGcokMniLaCsalHSYAgSikCKjNk0WivSiZxhHrMJMmnNHEirlsllEF1Ww7b2dupsNVDWkWixmURadeSQuHEHEghF1rcnJQRFqsLrcQkbxEzP6usQFASkEYBUAYs0vvlBuE3WChkRhRRIUEqw+pARzkw1IaQBqMjNKDHpZQ5DTVNkAVp2xw7as4Fsf4HFZbY5ZckAqDoqMY+X5Hg4qlvpGKgMa+dddudwCzAIlFWF6ggUSCkltIx9ZKZBg0ITjQOyI2YmJp0HZ2KwYfZVQqEqcE9ISxCzD+oRj+vDmfd6VCVyBJlJf/XsdFnjdDreznF2X/qewEarKph9IagYKD3V5CmXFJ0lHrAewHKDuS4pSA0Tyex1+rj3dWRo9Hmg1xI0JIkaHXGqCLr4WTI70O9VVeTUvJ63PF5K1TFPB6VoIeP0MAGkMdasMhxfxHuKOC+zsTI44M+mCc4pRjqoQ9UIUUHW58RPClJUbUJiyj+n7OO26bJ0ml+RIzIB2ddMxbJ+zbiLZdnxp+dF6nToZdXKGOd9Pt//xKWdQcQ8ZtUHWB9weoKTVbpd28aZuTwnV0KWT8LiQxmtmgc5zSeHZuZFz82H825LZUkDWTRP0XMDy3mN6M5qrtKPImhTzWaurE1zV2qej1qAoOCoCAjdiwhkBqKFmONMiOeh14s4H4Is7250Ix/rXOP1Ch6ODzkbvaHeZhmaKc7OMWGMwwoa8m8AfkjXCAhkxsZMlm59oaSy3D+wBdTgRkz7F4S0zypWUSKAdDqOZiqTmj5wHSWoe03JVvPYGsHHQ5fbzQuiV3C53GB9bc1wboCmBiRubYfM/t2dmFxIn+Y/UtC1OC/zLdhcVVnxybqHJ579se7UqoOJxL66tr/GbGXLSkrjA2/LI6G1PaFQf/rOmYpUR3LRnz27zo5u745dG+w6fye96ei+5JcT12Jrvxgqb+v3FCy6ONp5YMOj/ScB7Dx9ztRSJZfSsDMmr27sLj55tbr40tG6vW8WOrr+/vjwoYWhX/d2fzP86nMThx5vP3B7ydUT7zz204NHnmkbv7K08Obi61zhD+El95dvHzsBH6pY+N2LVTdahutvAGljsdJRUP/10nOjyw+vu6Df99u7D9zqufXE53hFqvz4H+f72a/Kvh8A/+w/0zG2clns7FuB/SsSF27/u2f3iNjU88aW9JGXX+o8+PvztZcv/4Jp+XfvLsi7eeXn1bX5eXn/Af6Nxeo= \ No newline at end of file +eNqNVWtsFFUU3lJrDNGE+AjBUBjWUrBltjO726dBWrdQEaG1XQRKsNy9c6cz7ezc4c6d0qX2BxVNDCYyaQLB2GrodhfWAi3gIyIKUUwxSpQfkEJsNESJqFExiMTEemcftNjy2F937vnOOd853zl3u+JtiJgq1rMGVJ0iAiBlH6bdFSdok4VMui0WRlTBUrSutiHYZxF1ZL5CqWFWFBUBQ/UAnSoEGyr0QBwuahOLwsg0QTMyoyEsRc5nzetwh0F7E8WtSDfdFZwoeP2LOHcGxW7Wd7gJ1hA7uS0TETezQsyo6NS5UtR57s4NjgeWkObcQA1YEuJ9fDFvYl1HlNcAZUQdR4qxlo6pg3Ay5mYEqIJIk4kAgYoDkpAJiWo4dTqAhqSBkzHhGJBL4x2gqhsWbTKhgsKAITvcBqsUEaomeXe4oUojyQONGMlcJiWq3uzu7GTOTvtUgiSHTQrpVJFB4lALgpQhN3TGFQQkpsHrUQWb1B6a1NWDAEJkUB7pEEssvr2/eYtqLOIkJDuVJ6DThaRsdqIVIYMHmtqGYikvexAYhqZC4NiLWljHBtLd5R0uk80JRwSeaaNT+/2qDI+iuggbAp0TPD6/xzvYzpsUqLrGVGTdZ5RiRtJ+dKLBALCVxeHTA2bHUs4HJmKwafevBLC24aaQjiB2PyDhEv/hiffE0qkaRnY8UDc5Xdo4ns7nEUVP+dBNgc2IDu1+GWgmGrrR5BsuCa/g9fFCCS+IBzJd0pDeTBW7z1tWvpcg02DLgV6KsZDUMruiTBH05XA8Pc57aldk1Bx1zYxWM3XsY2uQtIgTRa4aQY7F93NiWYUgVAilXM3K4EAgnSY4pRhDQQJ0U2aCLM2IH4eKpbciKRGYUvYR93hZhOXX1LBK+fQuM7GcTzvqFwRhJP+2SMKGXtWdjFFfeXn5HeKyziBqH3Hq40UvL4rBdJXFjVPnSe4Wn3oW0qxiDivGq+CO+HFuGZ/8u/C5BcPSxpEFU3lji06i2F+WzFZ4Z/w4xbTPgrvxuTVFbir3/7UvlSjvNsiJjUuhuduib8knkVaeVyX7I3ZuEsRqEoF1z5Cwz2pcE/CWlDRWrd60OdLXpgI7IXpErhnjZg0dDCzjA4A9qXxDcoXsePW6VVUrlwcG1vL1OITZLAUBmzkd6yjWgAhbTTsBNWxJ7LEjKMbc66vW2UfKZKG0WPaHvGUhvyCX+Pmla+oHM8t0Y1mizkuZ/CfaGks9ziezlszdfp8r+csO7qha8WnljJfHvqCeY3lnYo8/5em9Z/vMnJ+X5mml3fIpOf/bnnd3nhnz7Ju+5dH2P0evfdfzTfHa72dcuxq63v7311f1wtoLh2bVP9R74dw/u7LlvXE7f+ZJ5a9ts+79o3tjiD73QKFc9nRgTuGR0egrV1Z/fLpP6P7x5J6Fu7bvOX7//sEHC5/Hl5r2nrn08Ce90+cOd+w+IT9ZWbO1MqfiymNv5n21Mfus8OKuVdNn97RtfOLQsYuLlRojry83R5lfefH8zmlDXdblhaPH81fFKmcg7tdY3exTH54debUUHz/6b+P5w7NP/JL305IBKAhvvH06H09rH1rW83vuC6O+1wpg7nA1GNjxwb7inM/fqokG3O9te2TBb75nz/Hv+CrmdJ8tWLzpsxZrvbxw+VjLD1fI9Wku19hYtmsuvKwlslyu/wBhhTld \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_2561a38f-edb5-4b44-b2d7-6a7b70d2e6b7.msgpack.zlib b/docs/cassettes/review-tool-calls_2561a38f-edb5-4b44-b2d7-6a7b70d2e6b7.msgpack.zlib index 7b712fabd..5eee7c03b 100644 --- a/docs/cassettes/review-tool-calls_2561a38f-edb5-4b44-b2d7-6a7b70d2e6b7.msgpack.zlib +++ b/docs/cassettes/review-tool-calls_2561a38f-edb5-4b44-b2d7-6a7b70d2e6b7.msgpack.zlib @@ -1 +1 @@ -eNqFVH9sE1Uc3yAhokAMKIsa9Wwci8Br73rXsm7gaMo0yoCxFoGROV7vXnfHrne3u9exOTYFB3+wCF5080f8A7auJc0cDCZMQIIimSQa0GRggSgIgsoQTRQE+eG7roURFuw/ffe+n++vz+f7vmvitUg3JFXJ7pIUjHTIY/JhmGviOqqJIAM3x8IIi6oQLV3gD3REdCmZK2KsGQUOB9QkO1SwqKuaxNt5NeyoZRxhZBiwChnRoCrUH8/2NNjCsK4Sq9VIMWwFFEM7uemULYMiN8sabLoqI3KyRQyk24iVV0kpCrauVooQ5xkUFhG1EkHyp1OSQhmhIltjhRVHFZBs4XgZRgQEWOAChqooCAMnyUS7nbQVEKuqnM6lwHAqVzpapYGgzosWSEAGr0ua1b8F8KcMVEjVh2e3gJKiRXClwYsoDAmywaYRBpCOpVQ/DTZewvWpA67XUrkMrEtKla2xkThbtEo6EqxqhpBWHxmkGlyBeEyQFY1xEUGBaLMxKqoGNnvuYXsr5HmkYYAUXhVIfPPjqtckbToloJAMMUrwFg8pOc1ENUIagLJUi2JDXuY2qGmyxEPL7lhBOOtKsw6sWu41JyxxANFMweYub6YOR2k9GQ6Fou0sZ3duqwMGhpIiE3WBDElJMS1l3zPcoEG+msQB6cEzY0PO3cMxqmF2zoP8Av9dIS1BzE6oh93cjuH3ekTBUhiZcV/pvenSxjvpWDvD2D09dwU26hXe7AxB2UA9t0m+7ZIgs8QC2g1opjvDkoyUKiyaHSzDbtGRoZFHg96MkZA4YqyJEkXQ11/F02PevmBuRs0fsiZG5xB1zM8CYmQ65XRTfqRR1qxSDFvAuguYfOrFeYEuXzpNYEQxegI6VIwQEaQ4I36cFyNKNRISvhFlT9rutKWT/LIUljBIv3EilvVpRjmappNT7ovUydBLipUxyno8nv+JS5hB2Oy1+gO0BzjdgaEuXVx5khrJc2hRpOuJWfWQip69D/JOPRk0dV/0yPUw+eWJdNFAEsy95FxJM8XekiVqOSNqnLsUR1yIWxxaOYP9pA7wshoRACbbEoHUQNRhM0mxbuRyu0Nuxhn0uIKs2xOig1w+63HS7AzOIzg7aiVoJhg7Q1WpapWMtvpeAD5I1gjwp8bGjM9ZOt877yVf1xJQpgZVwl8AEp4VVUExP9LJOJqJVGrywHUUI+5l3qVmbz7vYSHnCs7gWZrnOBcoXly2LTNAtwckam2H1FZeHRtaSAezpadbHshK/UYHFlZUP+Edd31a4tVr2905ea5f97W+4aNWT86Lxpr5HXn/2pPvdO8p/+nAydcdF7jepomPS6G/avZ3e1sajw8MJBdN+vHazd8RO7NvVVHX2RNnyo6Kpf2rX87pPFvbPKajeVTfu7ujGx4df/m70tktz/edPDK46jJqa/4A79wyOWdAX7jZ6+j6cv3lY6d9Aanyl/7lf65v373hwD9jlf2F69q+yOoQ/gBXFx9pO/XWRzsf2cwvKVy3CA/uOYsmXBlVWHbk6HN4b+v3hRebx59cNSFbb5/UZMtpfGjqxHPa3Adnfd7WO7t4U81vy6f19B2ucd6aMnlsZP7PE/rPtM48NpA82Hd137Ki+I3coutvf3PxcP+Fi01rxyT/Xnvl2K6mK0B+anv7rE2X8JyWvBOnuFmPlUz1PXko97T/PP/Mt5dKBseC8w+PO3emYfB0xaev1OfOFw+/1+o9dK2o9mrkw5uE01u3Rme931SZfyM7K+s/SQ38Dw== \ No newline at end of file +eNqNVWtMFFcUXsqPAvaZNMU/1snGIhFnd4ZdHos/WrOgqKWou5TiI+Qyc5cZmL13OnMHXRGTLrSNMT4mTWo0tkll2TULym6xKUb7MMZaE/80VRPaVElbbcSY2KcGo/TOPgALovtnZ+75zjnfOd85d8KxDqjpMkY5AzIiUAMCoS+6GY5p8B0D6qQnGoREwmJkbb3P32to8sirEiGqXuV0AlV2AEQkDauy4BBw0NnBO4NQ10Er1CMtWAz9mFPRaQ+Crc0Et0Ok26sYnit1L2XsWRQ92dhp17AC6ZPd0KFmp1YBUyqIWEdbJEAW6wyRILMFAvqnMTJi9MBr9q7NVhwsQsXCCQowRMi62DJWxwhBwiqAUPpWOIKxksmEQDCVKROrWYdAEyQLJEJd0GTVqt4C+FIGJoC16bktoIxUgzTrggSDgCI77SqtH2pETlXTaRdkEko9kJCayqUTTUat9q4u6mw1VdagaLFJI60qskjc0gYFQpGbu2ISBCJVZm9EwjoxkzN6PQgEAaqEhUjAIo1vHm3dJqtLGREGrMrjgtWFlJhmvB1ClQWK3AGjaS8zAVRVkQVg2Z1ttGMDmZ6zFpeZ5rglDUsVQ8T8YnmWh3NtiI4GYjiHy+0oTWxldQJkpFBtafcppaiasp+cblCB0E7jsJmxM6Np52PTMVg3++qAUO97KKQliNkHtGC5e2j6uWYgIgehGfOunZkuY5xK53LwvMOTfCiwHkKC2RcAig6Tk02edImXcqUulitnOf5YtksKRK1EMntdPH9Eg7pKVwZ2R2lIYujhCFUEXvgulhnyw/VrsmpesRVGqqk65peNUFzK8DxTDQWGxnczfGUVx1VxHmZlnX/Am0njn1WMpF8DSA9QQWqy4scEyUDtUIx7Z5V9xD5VlkbzK3JQJmxmw6lY1qsZcXMcN1I0J1KjQy8jK2PE5fF4HhOXdgYS87hVH8uXsjzvz1RZsWH2PKndYtOXRYZV1GJFeS15LH6KW9an6Al8HsHQs2Fk8Wze2CAzKPZVprKVPB4/RTHjs/hJfB5NkZnN/X/tSydaNAdyeuPSaGZO9CP5xDPKs7JonqLPzRy/oqaNhGo7gt4mt9fHA1zrW+krFXs7ZGDGeQfPtGLcqsBB7wrWC+iVyvpSK2TGqpveXF63yjvwNrset2A6S35AZw5hBKM+qNHVNOOCgg2RXnYajFL39cubzOOVAa6iLFBW7m5xu7hAuZutaVyfyC7T5LJErJsy9X16N5q+nM/mLFm4K8+W+uX699XVn+GeeX9i9W/z9r9kLPhJQpu+PZefPPNCXsO6sR2JCzfGqgfi41fXFeRVNu24deePc3nB/II9mwpvtEx80lDivvfzry/f++r6Z6fO3ny29rb3g+S8A8Zu5tMt5QUHT8DB8909vSXfh58SjGK+qai/Z8GL44vWDPXXHITM6co/a1+5ePNu7j9b9/zrKR7+OvGWW1rGDzNvdF9ntnf/kvs5ThSyOz8uSt4qO/DR7pM9qx4cPjRUMzo8ur3hgtd0XK6vOHHad+m50INNFSFj5fO/F+57fXx+19Xb4XV3ojvRWPjpsrB831YwHJa3ffjNFaNm78EF9xdWFM6vzznPFBdcXp3319DFu++VnFrG8EeuFe0fDU/0H2384e98m21iItd2aeO1i7tybLb/APjLO6s= \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_3f05f8b6-6128-4de5-8884-862fc93f1227.msgpack.zlib b/docs/cassettes/review-tool-calls_3f05f8b6-6128-4de5-8884-862fc93f1227.msgpack.zlib index 36f20eb2d..1a98b9223 100644 --- a/docs/cassettes/review-tool-calls_3f05f8b6-6128-4de5-8884-862fc93f1227.msgpack.zlib +++ b/docs/cassettes/review-tool-calls_3f05f8b6-6128-4de5-8884-862fc93f1227.msgpack.zlib @@ -1 +1 @@ -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 \ No newline at end of file +eNqNVmtsFFUUboUf8jASokiMwrhCm0hnd2e77bYNEer2QSG1S3cLfYib25m73Wln507n3m27QFUKYrRRnCAhwYA8trtks0ArCNEiapBKkdCoGFMS0IivUJTGGBKNBu/M7vZdYP/MzL3nfOc75zvnZDuiLVDFIpLT46JMoAp4Qj+w1hFVYXMQYrItEoDEj4Swq8LtORRUxcGlfkIUXGCxAEU0A5n4VaSIvJlHAUsLZwlAjEEDxOF6JISuPDC8yRQAbV6CmqCMTQUMZ7XZsxhTyoqe1G0yqUiC9M0UxFA10VseUSoy0Y9a/YBkYob4IdMKAX2ojCgz2LfC1J7FjHoCjEVMKJnx7hSbwDYDqCxTkhg/lBQmhIIM74d800RUN5CZEhXIvIh5ZNaRSEgx4A0QI+DICUKSl/LVrWQQMM6SUF4Mgcr79RtRVoJ69E0mXiQh3WZcDB3SJAopvKDXyq2r8bmVYHkzBrmrMb+xtrJVqM3LMbVvGJfu5ELVTaCmQhyUJlTDVEXdmKSuUKBFADLVoIChcMxynWEWw6OgTNTQs4wPqQFA9AcjIR7oXWFUJJm3975o6+lhL1RVpFJrH5AwpJls0BsACVDSEXgJBAXIZrM5LEayDAkrAUL5pYIlW2T6GgsQ86qoGAT1AhsXBu8x8o6I4cVU+gAwNFFo40KViEYbjkg0WkhMVFFuMLXrKulVE1WoJ12XsNwwpj9QfSPkaYfQ5KJ+CAQ6UjvCfoSJ1jNpSI4BnocKYaHMI4Hia0caNopKFiNAn555jNerYEyhFmuCUGGBJLbASMJL6waKIokJPSyNtGLxpL6szmXydUxvFZaOmky0U4UpHhZXiM60zFjN2XazrbuNpbMjyhIdSlp9SimiGPe9Yy8UwDdRHDa5L7RIwvnoWBuEta5ywFe4x0HqgmhdQA3k2o+PPVdpq4kBqEWdrsnhkpej4bLNHGfO7xkHjEMyr3UZfdUzUuQRl5jNastmrbmslTuaqpIE5Qbi1w45cmyH6YwodNfBrREKSYK4I0wVgRfPR5Pb6WDFmpSa19IeCxdRdbSP10Mhi+E4pgjyDMW3M1xegdVawDmY0nJP3JkM45lSjB4PnXzso4IUp8SP8v6g3ASFmHNK2QdNo2mpNL4kBkTCJkeYiqV/amG71WodzLirpUqbXpT1iOHs/Pz8e+DSykCindDzYzkby3GeZJa5tVPHMWaLTWz5JKuIzoryeuae9qPcUj4Z9+EzDUNH7WDmVN4oSCZR7Mozoi27t/0oxaRP5v34TE+Rmcp9QvkSgZbcxXJs4RLWzF2tp+UTSyrPioJ2mr7Tjb6qrai6Wqla1ebylQrVtpCzem2j23GoRQRajDNzTANCDRI85ixhnYCuVNZtjJAWLap5vrC8zBmvZitRPaK95AG052Qkw4gbqnQ0tRgvoaBAl50KI9S9srBGO5HnszpyfHlCjuCrt/py7Wzx+sru1DCNDEtY35TGH4stkcRyPpduX9z5YJrxm+FxfbX685Vz/921dKDOP1RDvp994+yB1yqXF2nvn+w50tI6lLHmVtZ/rWLx5ejbZb6MnbM+evyRhY0X8soW9V/bPnDx1nEnWNQSGdy+e8GS4eZP4ZzXyVbms96X0u1rS+Ps1pnXG28WFn475OLJ/L0lP8WL3/o67+qS5j0d2y7UlHy5f19k8dq+s895OzuaBODqXjFbzplz9bdLb/RcX6d01g/LKy0v7nXsefTin+v7Pjwz98QTpzJq/3H19d8OZPVxA5bWzd/d2Nj78N/n3pwxa927rzoO/rKgvexw+wfC7zfnLbw8s+qLUpfLv+zo6ZNVpbt2/njmPNj33tJ5vQf+Otw/eOf20CvDT+8/Mu+dh9otT8V3uL85tbn/jyfZLVeEX+e/8MMn1S25A15anjt3ZqR1Xvr55d3paWn/A/LD19Y= \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_85e452f8-f33a-4ead-bb4d-7386cdba8edc.msgpack.zlib b/docs/cassettes/review-tool-calls_85e452f8-f33a-4ead-bb4d-7386cdba8edc.msgpack.zlib deleted file mode 100644 index 378edbb99..000000000 --- a/docs/cassettes/review-tool-calls_85e452f8-f33a-4ead-bb4d-7386cdba8edc.msgpack.zlib +++ /dev/null @@ -1 +0,0 @@ -eNqVewVAlMve9yISioCIgtKNSjdLI8LSnUsJu/QWLA2CgghKg4CkhIDS3Snd3d2NdCjxrefce86573vue+83+zyzv2dm/jmx838YfDKdLRzQNkgEVo4NwtHCwQziiHlAh/tkOljYO1mgHd9kwC0crZHQNJCsdpqTg83kjVNrR0cUWoSLC27hADezgXLaIOy4bOBWXIpaukJmegIo6HOklYUbFG4OAvIZ8FpbQxAaCDWbZ0KKvKo8EAQYpuiOtFLkdUWZw3WtITZQoKU+N0xRA4WAwOVczGSe6Wg+RyvJ6AItIXyaGFpNS303a3N1eWk2fR6gOxQk5waVA1qqywBd1GHcKDVbpCAYDnOD8GkoyeipWpuDXC0xt6MS6C9YA6kIQeg66fNpOpvzuiD/glEyVjAkVI/H2hwGdAPrg1FgfailORxoB9ay/vtybVckxEaYTV1e1dFAzxWtbusKM9cWsNTnhTlBQbpuGN4uUBlpoAJIEQaGY2i1XZzBetxsGH3dzfXk0ObP+X/JxLTXdQJj7FCSQwtDngv88fxXu8xBcu5QaaTiX+1WkOF2VLd5ZvtLtj6vK9pcG+MrfUUejJ7c5rxA9N/W/8UvmHonZW1+KwxPmDkc41v3v683k9fF2CdgCYHr8prp6fLp8wo4g0E6Qv/eX9KOyjbcbAryf+qi5oJU/Dd8rJS1+P9OT7SBvqq7JkgXrgDSxPhPjsdcXsMK078YvyFtwbaKcBUQGK4M+jV2dBzNQLooMK81t5qtrJOKFVLRgNfVGsKnKgvWM7D6x5j4nVaGxxkCkrM109cUULOV/h9yftH8KcMADrZRhYNtZazExSXNrWSQMKSDOL2LtY2jxWdzJNStIdPawgyKmTJvsnTQFg4c0lYWCMfwMpQbZo4gOP4xZ9BcvJx8mCtfGgKxQDlyyCIgSKgNwio818rdBsVOB7WwhJk5WmT8Xh2e9pTraZYMEoGw+G3yhWfZWVigOMxgNs4WXxws0CjMfLTwzUA7mjk6oX0+Y1hZdLdnwi3QaDMri1Q1pX9qFPr5OYZpeK22tRM7Ha8gnZYFio6Xm5efjodPhE9QhEeQDqSinStjBrG24MBIc3RAwsLz4WauHBg24ryCQsL83NwZWhYOmAUhPAsCQzpBMVo6WKSpyiqHT4h5MKCdMOqi0aaW/1gkGES42RkcLFBIB0dTRySDCAPEkgNhAWNgZ8AwNcUwZRAR5OYX5uZ+mYbxUni6sKCwAPCzrpmDW3i5moONlQ2Cne5/OCjvl14Yh3IoWyCsHK3D03kEefj482XkOH5XW+s3H4SnySto5yqboR05VDBkljYW0PBaPQsoxmqBf7GaV1iET+iX1Tn/5KvthrIIz7KBY7TjskVZWOX+QwFNM4SVBTo83dzN0QL9VfM3ozi0keETOx4MFggoColZHNEMIoYeDE4OMIypvy+BRlxGXGacGJs5/3QXJwQJN+L63S1GXM78kmhxbSUFsL2SNeiZnpKBMMjZ3EXnmYWtOUgArqer7aJjD1d2Bulqw6xcZO2lDXRc4XwId4QcWEcB4gaVlxYGu0krCj4DKyIQenJ88nCEjiVQXg1orm6lqeKoBrVQtTVHwdCa2vYu2pZqaAclBUVpOM8zfgeIgzAYCXbm15Bm5nuOuRheGrMzWDkgnVD/V0dVS//Wxf8cHhzSMBjSheP3zgpP+XeDNAPTP5rSBuElwhAgnxm/AD/UghfKz8fPxyGrp/nbrHmNGb0OmP5tkcS9Hr+eB9xVlFOQA2BhAQBYmA/gehFrXEFGxlRdU01OQVn294p2ACbd5AYA4BhdNEHP6PQNwHR4879T/EpmEDQK8O8TptXJ6O9thzgA///pFtQCDcF872FuJgeMcAzL+xh83+p3/PgXNv8di/3CLo4oRwxW/4UdtDVlMBiKwY+t/oLN/4IhKIdf7YMwWAwOc4L8qTfgjgVCRwvzjY+5qQBogCYABHj2y/7fmyBTAQDhYwAAO+zPMvNYAKDcDwB4OPlnGVMyAED8BgAo6/uz7E+foMwczH4ruom5b1haAgAHmQAAoQEAQNoPANw2/Kcj/o1udL/pBgIgMR8rAAxggSlRACAAEAAnBvECuAE8AMHrKYAMAPvGjV8XJt3EXDj4ODg3b+LcxsPDxb9z+84dgtsEBIRE9+4SEpEQERDcJbtLQnr/wYMHd4jJH5Ldf3jv/oP7v5hgYWNobuLcwsG5dZ+QgPD+/3e6bgCQ4GO9xbLFxmIA3CDBwibBum4GUGNMwv51Yf3R7zi4eDdvYONj3cJUm94FYN3EuoGNhX8H/zYOHuGvsXcDYwIuCd49eoyaZAw80rof8Ml5BTW0zRwjB4aGGXXsnaKKSgaZBJ5pQl6HR6QU8ws5FC7cYuYz9/m295CFVea5rJwe2tkvNa0RI4ASC5P+RTwA6zcBeJhKQRKMvBs3cG/dwMH5RwusGyTYGvfoeaTDB26S3ufTNLNPaYwoxHnAYP6akVdmYc/n2/Uk4A7GIkw7EoAk4OprKsMNBjqG/zPjtIt9+nGPMFtdF6/dMozvckWqyiOuVcFAtbtimgnBEx92l7Vi3hPRHebGQA0S3k9w4VjByvNWMcbLtBWurQBrKiqgM5JI2PNYe00up71z8lr97rtE5j8+vwZk9sDheZ9uF3wKeew+JFGyl33rbNE/l2/LtI7AzPu++rHlS4X5MvJ9WWJdq+FPA4cnxmp9/31jAUmxp9+8hFO2lH8MfcthXXpPU9KX63XG4XehITMSe8zqM27acl/c4JOmN6hvfNhVx0/y52/8jEdyG50lBmsG+mgPU11RV/0VcjFN2L8TcVJSSQwddExJB/lTwrC7kFSicWbXAHg86TnR0rLSi97zENIOAXb57GFeclT5QqtFhlP72r4tdHq0pHNeaHuFECtVpZyuBLcaMvAZBmN7X8Xy7uZzfWmSuyQkWP8pe+BhPB1XBxjLp3/bcr6Q2oFFV1waxtN70+kmf0XoBxwznRA6orYHcvtzxSnhuZYqb3/ylRC6XbzOZ7p4leeJ/64l4zwHrm8z7E+rebs0FSYwDzEPESSMa31dgL0M4HJ46uwSVCM5OGGz75aLzih8JPLz1lfTrjEf61Nr1CokCX/6rtxSu7QRn9DY44qcNeP9eupUAT9jLjJsdVvYdImqKriCApY4knWS+DHqos9yvuYuRa8Vdajs7jWgk9zP+6JrANPZWZepXa5bit/J7QY69/qwidI7m3T2F46vkoaj5r9bJL1MpPos6mZGyV/pm0DdvoyX5TPju6Trwrj9dgR8T4U1IoYwOFt6b9muCNCunOpwbonOXOWpLrYzaP+2M3n1Are5c/HsPKQ8z3ojKOTj8A8How+HOq3LaOGTJs2jwtI+NCPKI+GWHdXqYWlNY62QuvbRbulAjVu7VWoDIShgeDzBmLJSpGzBt3Zo1PObAvX9ECIPAqtVqvhP5PCaLYZBI8LRo1JaogM3cUBHqQSBemCcv/54t7R4UA4SNvCIHmf6MvJ5bljr1bP+hlGeFtwO8iLFOvfo3EhV6x2lKBF3WDCb4M+4ajbBEROUQff5pAkVGH8FL81f6Mk668vQGqXOfVO/cULp2IaZb6alz0oOJJoYYILTZ3GnSka8BvgBEc5rK86z6mnCsk01rcTSdkGCJgVt+t22d1a+3AqPQOLE84o8EXvmmYsSpQ44uHvbf360xBvf1SyTv/4+YwvqypPj9llWjENspw9VvnkvqAMvhApAGBS2h7+DpxogxK+Nte2zYG/muqgaxn7zxu7VyDhpXdNV5LLkeIZjOWmJc2W5gLFQNre7zzD7joXvg4i3XeM9Dato/UWp6deVZ+oKtjBJ7wLdDf63yieHjU+uASPKg9T3fVfsmowvlU6VLeVShj7WJFtbOY+8b6O7UkBLM/4on3CC5je9bwNXv4huBLP20GM7UPQrXAMAqSU0IkZy7xuHCghgsoosnYOCExdpH+HnLsbBFXyex6ixverI9oCqdYb/vGphsqOpr4Q/InULKS3z+aipwmsQYyXBAZL0OB7h+vF2rw1aoDMZn4gouXgIKUEg+idi0QZ1PcG74jcbYPisbacqV1oGkswUgzW1x4sefVG9L5jypz5sLT/tAg+TTOSyuUHfWuIVLs3THdHrJSY/bRp8q8YVaPnzRCdffCC0vQPoC2oH0DKs1dGwVGUM7VzFjTzZPdGi/clEKyeRvvueRapXf3x86mI02CfnjEQyHfg9M3A7suHd5ZO+l2Km0EQT2tBJJTk7xaflr0l/aCX9cK3r0OERns6dZd2E3YnL5Jm98OKiRhAZpO6IKixXTADr8ZYn8U/WJaNWDkVqJGlLooMmU497wGyUzoW8xjUJO3gW4D0Gb0X0nBr5BOsfLP/RdJToZPgsRxKj2HLn8Ya//PjiK6zqBArKoZWnNfzP530XVF13VvlaTuw6JWghUA/jsKQruw+7jO1TnoXeRoZvabdsVO48njLFX4OWiGt197ixO23BWZLey3WJF3gahtj5xlN594aiCGZ2Vad9410OJseWwA/7R1+NYpaedvLNpbxatue2ASzPnxtZ/3fd+o+M/aca2U8Pu9eVq9/JyO1Xp8rad9Yu6pBbEnAcq0kPb6Sx/Ui1SyBBP1b9pSCoa+1qNsm4Zp3//nOp589v/n9nOEkb/eJ1Ah2rNuIL386qnWjfdjgdeC+ZlzAn2czU1jn1adW7omoFr+KZ164BbWfJ/QP/eUX/18y1dic4vZc+13o6whlAdyCrKFIPjL7RSk4Jqs3funNOcI9XIX7VNThHLFdCo3I69DFBW31c06KwJDh+ewxdtIgs8eYuMx7QFD3PkWD0Pf5a1/MXxOHW9pC9bMWq3JDcwfaBgfsRqvZ4s4MLOvGZkDmHa/zAx5lqirp8zrzuwQJX8bfR8hP5akJaQg7t9k1y9W9qpEVmfalsXS+62PxfEPgair6zYUR0H1NGHX/3FvBvRnmVCk3k+Cp60FoMUrkPe2pnytxxOA8Ain7oYbUA68GnlJsmvvewNHl3XgPWHJ3BhyHcBkdFT0F/0Gb+iSzyhZdwYhy1Q67siAPmL22Rxap/oi4T+1YCzvUsbQFLxfQK+t6BbBPKe4IPdwYTB3mKhF+N1uZBlNzejd+Vn3vhPM1mO9/clE0E17DDD6gI+++6mDTbyDAdzUQdkM5z0/uoM1qDon42yW5V6xoQvdLlN6u1RUCp7u6Ilbn/CoDn0NLvXXDfJ3RorvlhX1zLj9fyXHL1uxHOAQEFPk/9VDk2RMfFaMzv5EuICoULJ3jO9DzeycVr7+37UOx81t8OTMD2NOXSqK1VSX6f6/3uhxWZgE1xxPbbD6/L0JKvPpyyI950Uw/USc43OnevSiC5ZM3TnKminp5s1Zfki8GjhbZBfEZCeJBhRwlHmqPn2nrHE1OqwuctWW88/asYwRS9x2u15Reb+TskuST2RyGboQZndqiAwOT2gAD8gFf/KbvNqPdzqMez0/tgOn1YLv80M+78wzVgpdJhweXDj2+twzRJV3StnqNcwwQTsbUsfMTuy+rxvGM+CgYEnkVkJWED584T7ken+7h8q4VeyZoEA/k/PyfmEL+u6HC4kBi60B0WWVJfRs60VXN4VfNyPhwVGKjs9Ss1XMRtWaYkQlg6sX7RDiGz5dAKXSwn3C1qTbOMGC3drRMu5Uz5HjQKgSPW3yLWSN7qODdQp7lRSppjEaCaPWhLcPE0qXYl1Xhzd0cVmmHFQmheBYrV9tWxtW2wEc28/Iu5jxdsY5mXIdPig+dGCKVHmT124x3VtqTxZTSbSWxxBuT8/hG8YxUP44uJLg374WMDifKNRyk0g1TEW8uLfI0XtVNhpqZZhHXY1qIVYnUUxuLkHrzlPzcsq1mjXoHnvCZ5x3wJyrdqPGsVzhQvyt8vvi4VcrA1Znyg6uLM05OZK75jefUY7TdPJTXlAJibJ9AglW8t/V5xAiaWdM1OrL9QGl4+QthePbHm4N6RSWh5sdo/OBdXR8nIrDqpq6ITZI/GR43Lu5f4OI9HDEqPZKPKbyGfQMRjWweqvzoI5x2twEdD5JOrb2HHhryq7eE4JDJfw42Yhb+b61Pai1G07nKN1/c0+CrBRsv5NLLn6+dt2w42C88X4sskva1hqsuYWM1RSw7UK4LN/KUwjvXNZCcc8qUo1igvR5hywLRdBFz21PnE7u1HEb4EfP3dIYTDTger1yeTLD+TezYi+lQsZFR6LEIE4d9L8UUztMYnd2hZbbpNq2vcTNyMlDzhZeOEuZtDZA923L7DrwEi2T+f2z03mK05LbsGJOpcpgqkPhkUzRK3wkyycvyAqjsB//cAfU8kDvcrRvi5x8SHvdxgeUveD8kB9d2dlTpnxCk82CkPMVyCzT3Burn4dIZq1oO7k1TmlXBcGV3Uoctsl2zcwY3nKtupa3a+tQMXjEpyTQh4g0zGQXlKHlrkrRt09wkbOP99gGY+f+hB92x+nBC/I5J9RiSycvxVbMfK+oKtmh29w22dZL8T5ujm18FQGGXtcuRALrXCAbHI2xhwmzmweiCo3TL9voEX9k3xD2QU1wBUq9oTmEWzE2M8SiSxHHBifvSWklDcUKBw79TJNjiF+rwxbu4F0aKQ6uUyaq5VrFc0sWNrRJkudypQe+WR+2PLtvm0iBrjLqjA6GqI1qiqM40uDHcH0bzr/mn1y45N2pbJEPjrOUGMA/f051vZYsvSJH5+PTyF1fDuhe6d09UDWvLUsmVYhxKtZbMASz0/j4icdp4+U2zDvYffTgVe94rj8cUJictT6zV/ND1XfryPpz48WCFBtnIQK/Y59YMAbXgI76loC12STKdYdeQyIHLZMNXR9n2R/kuzzPoAnk8Cgcc3wtQ1dIcpEDX6JwssPY3Gwe8po9iftYm/gt0JjtqZmCKqvkcck/GTmPOn1SVhx48RyXKTUu0WLQFZDZvDEDvo5GPVPyr+RAab1wDHl9qH7PGyt+Zg14CUSklw5snGX+DI1fqPr6sGgu8L/UfcPHdZkuQygrtdBCoMxYxroswio5rsu9u6qZrGso2w8FIAeb1/Csk/BY2o8XaUqCee9P2gjDzO8kb8BZnuhmYlWSQl/nWoSlR0L++DNU+QTzIcOJoWsXnJvg5HPMo3gKnZnTNCoMsrN9FiMd87v2EbGVf0utpfAx6bElak53L/MLwVMKLWtcIuWEJST9EGUKvyqGS2vwORRieW9dgZqUnpGX5Wth6S/c7jNpIPryQt6ssMJ3E0+Dfbg/smLppL/CMEQryCUzcFPk4wA8hrBHpXEN3WnKLVyQDqPqkKxBpakDo837+h8oRNAZuhOCpBN9ssH9C+SnaL6YJSTX19kmonjrgK/ay54gD4/qG9YfV33bQZvqIS6iE+yI6F/UR4uQMwwbOHWjGwMPPA7cn2qaW7dVa8vRqYCvasOpZUrFD+wMiEajePY3mjgNJpLp8yvVD4HXuHbpByREvbXAQIcUpJTJUX6YKQXsGqFXsFE6S+a9+UIyfb75JPGtnevNWXzn/pj+atZ63+cLLit/+9X4TuytwdgcV4UEKRdP6VufrhhVTI1JyAbbBTmrj9oKBz/p1l+4NqS9pXNAmtzQFspfzi+DNyhkOGPeB0SyWn7WVLXhEgbX/YQLFcU5oU8r1YogKLQ7r8Yz3og5SQmjuUgo8/UoxeSYng7D6/KdsY3zswVELY/ab1IXDi7gokaa12lxACbvVZE654BbiZ2O/ypSbvc/q7SpPAWcuOyfc22epvsPl3gpPrP9wDYDuHWN2dmR2o2yWIyhSKLrtFvfhV95wqM8KNS8/OndaHbi3yYs2hxMPnO3k59uv0jMJwyDqvnF5QZUOP6Fp4LzowYa2DMeG0orI5YlGB+ebzM6Po3K9MbrGfglum00mhLUPh++D3mjLpRKVUiXJTfNZN7ugkKzRgktP/hH09F6t1RqV5Gu5GHdtTUl+YcFj0eRDY2hxOOuz82Qd04OKKFzWdOx7+z8EiZT1BYGPyZc3Cwkn0hIFvZfxmxI1DOp4KAO3de7g8s8YfsaZ9tH/kLUxuTnZpSHl8Z2QJyW1kLqJWSO/xlHva1g16QXPiFpTrcjDyDsONvOsH4zhrhiMX5TFnTSs0d+mRWVAMDg1wkXURJplgMJGeHsFf/oFbmOygg9GoqdioLvn5o/3R2B782T4Djd1pQ9wmzYV5dKr1ulCxEVqB2LjDA7gEIAcOhLzfD+nQ7lb3OSZQn0k385GHjYYpUAVLgAQawqTPnm1ow/zv/JzyMsoLaafmiohaNdgskhiidmqO2J0sm8e7p8DbbEAvigY2OITVpH7dCLbnuHj3zaowr2FTkLtGl4t3tKxxJSLnIvdeidukDBT5bJUfmD7a/D93faZvXt1iffEATTG2OabVVTdFxFzkoioMyQUOGPntwzosxdI+0jiAG6tfdpXbr6wQ0+ckd1QWzpsBmzhsMt/OuHhjcUICbyIKsKztXTkmUnoRzdHbImf12NE9bY+7Vqg1c3M82HpCm2sHHmaIQ8Oj/dnrj8GG7VLTOz2FcJ9S669j72tdY2+ScPMKp1nb6fcLArD6AWJd4z6i1JmFHwN1ObRSTGq72IOjOXh5plQZkWyiCuJD54b9aNKi8H/YINsV2THybSnXtFb06VA2aUacDVEPhEIIHbqMJesiISNpF+fSF9g6Vkz4/ltJS8S0tRUPbL7g4VTvwiK/jwfXw4PabvrFS1lOpHXJhs8yb5slX5zdhLhicfMSLePHMX/5BToUuw3AWRNPPGSFaLvZZp3HmbnqnKnyQ+Ed7olqvlD+2nh5G0IaNtxdj0p9CiGPkBntYPd9rfz7d5+3071LCW+hlAG3vi4AEL3CWjX5F+9Lm8TRE9+1bX8U7VYcGJu+7Xx29hNoPi7mluECc/Mia2M9fFaQtWvXPArGLMSHXZXxthxfnVKFIMY91p4SLAOf/HppnMz/yY6EIk1Za+Rj71IZ1G/bNa60apcwKadnLkI/QXqiCb1y866SEYGR9PuFq4zamFyPB/Ew+01l/tTc3Q6/8HGcmgGDd58T06LiReF9bG/Cd5Wh2ea9x3WTWgFVIK1WArp2pflVhYbtwQ63Txq7Z0owop56Ue+YbgoGTBT6WLm1bGjSqz83sheybsAYX1hoEeQ1R/xEdLtc5YGeYAYXm13GgE5tKb9L+sNPRqFbanAV6g051jHGH2Nclq17areMH3XYyOqeDA/MfjB/6SCZK/5HU9We4Pmke9a9SopPy8syQo7SSLfCL212vqbVPm7+sewNdoYhb+5FyjmANf6W/1AxxJX1TRxfRP+qf0lpA/AzTPrgwfMFr7qh8wQnDiBu+hCQQyX468Rs6zwcVILLwOAGozxsba223JZaYSJ+rVMxp/Q2wXGhVUvB8piTStai5jjnVBnx0pAQrziq1jM5sj4SZSS2tcp1Ll6BDJ0vSxubeGkQ0zrQISjt//nU8AV0r3T6QLGnL6iNhKyXFuuM9B/qRP64+T73TyM8bK2/K/JIVNKOJsZTNooxDSREf9BB/mnElBbIXePdcftVyfb47K0FlqDlktTsP4mSJuNEB4PU8kDHmb95k9+KOd1+hXekYE+WI7My1SAtn1K/TbwvfJfQGiv505NNz2BARRgWQ37YEk1wKr2dE5mIW6ZbCAvoBbBmOs8lZKEC4myzn1gwZzbSay3mKu6Rbic+diBSTSoI7r5b1B7IWGvdhV2jD0GXWa969AlO906j71H0j/1TdAx1YKnziGeSkbMePSnv06g1dHZrmxhZZc86LRfbo6W7bgquZhO9nPH/ycC8wUXO6PbxkFpjUGCSG9XD9gkE71rFOYDyWMLkE0Mh59O9raZ4PVKarzbBqQzsdH/sjn0qvwQg0gf9r9xEp2KrIfUD3gPpolNXoZmBl/ShC7oCxsOfg6U/nwBfX0gYt/J740o2sl4DlK8Cz+sHTxSb/wj+3rUp3ptdoMl8Ca8uCpb5kF330/nYiF12eWt3ERluMpZ6+bhIG6adWLOnRpkaXk9gJMj48zZx98t1B0c2o7xd9xMG2ED1gt0rumuAmfFtvwbRotn5aL8IF/IJS7IcUuHgys8hLIVrP3ue/vANFLAf3xbfUgbU4TNFJV9w2DBedqZ9zmozVRsMI7LZ/taxFjtjyh9izenxblNBcmL5AMdqxOSEj5Yv/vh2vs0nj4/5cbI/Xrs/pCjIHMntYHpuCP37uJ4mW8es1kTxhD6k+V5J4b5i/2ptZie+OL6JkWglRy7vI/b8hJFy2zTohxjhoifLwfERCkwCuZSRlVPoFRO7mLcmp3lezu1XY08/Jjb/aJvUc5gMCOz585U9DlILmKZhA9goKiQN+yDwQWjXjdhBf8PuB5fwVdjznPfVX5nYhylUaibs+7w0yoDJYxi/S367wq9y/Re/4wf4is7TdC/k6DTQlxxU2kqR1n2jCv6ICZKOwAy9Z3RujiepbwADZF97jmiPi0g7rph/XgPAA3dlN/M9HoXG9vzw0yvpq+3W62G4lMoRyZ5thayivVJ0dvi+ox8cyterc4HwKj+Zvi1niumWaOsF2tomiC8EuedjObSyqcvzoDYDDXQnCgXKnfPMohkIfGknKlNWlo8oSxDkQ134DXuMkoELkrdKmst58uo/F+vw6n2GFj38HML4BBUQjTDykNumohChSVGoPeb9+GkCe3zP90meR1PPNDDT7KdvtfjsBL1SyY6oRJKJl4nWxcw14EOKgFURhCtjawuW/hJ/OyRp4NzkZDmvnLN91XXl3fTeN8h+Oyl/dGU3jUrCbvVzWyLsfVw4eVL/WXYVsrE6zr8eZVTO8RpZ7HRi5EgEgXDY2PmWhQGnG7A6Z87fjKbPy3nzNfVyz7+oDIb3QOKc5XyXo6WpND5mFdvIm9FPNVwFE1EbjnWVeasXv3CtTCz9WhxnxZcmx6Ux1BQ0Q+F0UDgess3ca0X/odAHiD1JIT2D2QaYi2SNhp+o84lb6UHyF+xHDoWp2CvLGgP6miJ9XNOmRYSUKPEs6Fwec3CI0+DPONujX1eGMNkGqzhn6NZxZuiBFDLTYmIvi1kFPYyn+wW3Az21iss33R9TTBONlvOdHkRvrV+wkzm+nOGg4cLfmHqAprdL/SDWDHyNoiuPqkmDB/ZuXqVYD3g6d1od/uDNsAIl4Erqa0bM0kw5KBczBtKTPlwN4knlhTA3+Et2FK6IkzUUVrraRDTING5HZT9INJTq/2iB46zCH+nd05t/QSMoZ0y/tlXWEL5880gXXGM/eMohYyIsQBeh95a/I503B7G8LYTOBgwcRAAOs0nhqVGZtZFk+ajDJ/mHYJUKjkehFhl1W0XB0W6r7xtf57zn7Eku3aXEq92ZaAgum2hlJNmuBNqRFxa84J6g2mgBdyxZz5eqeEbCPlLQ/DioYyG945fpfJZnF0AnmprU9pM2d/ZEELyQBGEmtBvqsLQ0TaspbGLMlxgmxmpMn/7c1i1IuS0l4QRf6CH0xhmrNtAdVG+k9pKfy2zejbZxoWzfHcglKQm+kO4Z/pn33iv3GSljG6ulse/Xz6juvq6YIbQt7zkvdfvkyLk+Pc43obNB8V3rjcUTpCh1mXaQaRGEMk0Y0mRNOWHYs1bQ3V5gW6tEqEEF4Cfvc9YlGljpBeC2VZfZj+NG5F0wz8sIG9KUkhjBi2OKGXkap3YU/UPObEMSKTpYEo7m0vwbsoRNALaXpIELvVpYSCyk9saMGP+uYrTG4CnOuBDkFJpr5kE18aiC2R8lT8e6SepOOiEdMvaImuuma8V8dnS9N7H5kcHDbWndS+t47ndF3GSKHeacaCgRzRrCuE8NE6iqLjpFJwydsxMJnOasOj0Z2huM8OrpecEZNsH64ay2c0BiyonYzmWru8o1qnF7jlxYnCipe6Z1oVQU0eJUXhAcHqaLtqD7eF5jvtvYZ7kG73o3jl2wn9+QIxe2dJNKKmtN79viHksaz4Mlz8SEbYg5aZGgj9HuapBsAU4zP+C2V0ohO0t9kdbjTUTPxABuWYSver3qZKfLSEg0EKdJJ1KQqK81qD4y3kWgoeLVGIBqK0fMaXCou30KN33VwxckGNlZgvC6ZweTfKIdL4bf19OY0BsO77buMB7h7AU9iVZtlnLoqexUY7m4jJefMgdWIct1LJEFTrZqUIsLo6pi5vcD6NUS58iSH24JXQ533uvW0Y3pc+txsGjcdQlSmqi0ezVn0dVcB7Tk5Xcq45PeqET3m9lzRjImIlRK4jUV7GL1x4VseNvHp8cSAwEzafEOlU5cNwUG0vMdMxI7X7wYmBw8DozemSV1eYllk2wI1SitTUiZBdqgY7t6XeZe1Dt43hud1O0tbbNWArur8GVtCkQ0JnhuJwUtZtuRy0Egb4LRD7/JVMrTbRf/eGOMhB6/JP9cQkZ4AOGNi3jJFdppWvjlmEq4ognql0wz+mJNiW16LAJw4IT2556zXADds5827Hed0QgK7h8tn+Tpr90Ja2NyEAFSdn8Dz1O1wVYTEwQZO4tqTG8KZPjUv+qxsSlZlWHgH7lDZEcd79iTyxRlUOJMFxVe2RBiVR7VDQiu8UOIOBMcF2gzdJ7Sek4ReHxZWkKzxTrvd8PtmYRenkzvlqqcvnvQ1cTlMSYpCvW2i3LiNHnkMVt5PsX40yhbP7HFpPCgOnr4uYnt7z9QXyabAoV7eCwVBcwiuSKtQI3GjYXfnOdsmMQpvKSodtMy2pxAn4LjkvQiiYRIDeos5c8tGK/6l+d+kn/1PbNSbMtUjYPTuEf3tJCR7gxke7H5/QDWvxSvEkC2oOpBQt/z2pZnuB4verMjJ+i3N7pRekHcNoEXYpVc7rBTY4ONTcY7QH3oW/mJSdB03kxyR087lRs0uFaNy7TQMUN31UVp4cCAyq7gnODDQqEV1bmojK5eAXCfHAYMVOCYM6ublapTXYyOpzIeoxDVXiusiFl27AmZxW2jPGcPboqnSo7sbq3BAwgeXrCpn6yP1D/4dkk1V/cp0rEm7d1FOVRfrVwu9yyPfH318viH8EC29JbW7YU9XGXJtkRJlg03EOk54ktREC01VlThWiHLB+jrGUcoX4Fnnpk1GrS8eg3wmgwWjTp4YFaq67o9Gvt6v4egafwkKbkk5A3tGy7Rz45GiEDBlow5BHPS8nPj5yQkuC6NoWTU1n18AqqgCxPqa4CbdaDY/Ll1vIlAcoixBvpl76USg+Q1IFtGmjyrdttSwkpo84HJkMQpjyl/4PGNgr/ZE9RS0ay+9KKYjpDdqDastukzLY0mGhUCTX7b1Su2L9uRMBdL/jKHS3e2qjSWfrkcG62Fn3Lx0Hcplssk5jSyMUACGHG84e3GBbz1Rv3qjvR+d0y+0s+O+WZaqg73o/qamIQ33x57/0G+Z04cAq11N51V6n1mdl/S964nmnlr8OrAlQevjdeklus78xo993vaP9iK/VNSxGHYR1niP9gm/SHJrV2Zwf8Ptmp/SKpZZiGROfsnW9Y/JJk4kP7FgA9+FMopeNAOlg/Iev6DKpC33bsnpEAiv38z+LMWXR64t3XuGmqQuH1hYLiRum+l35WB6tdKow9ljUCnvpf7RPFwEitC4yB4cmAPuCMu9fSooI5fhfHstSYr6QQo0C6Nli3d1XuT74I8+8ySUPjyKSaupjhjf2LfOh7bOXMyjdliRqguR7hHqGmqRbkxcPVPmzOc92I30zDOjADFBMqHS0EcdrTyZ9LM1rbOXCsQ6Be22ghkAbpyWsm3yiE4xpScMqsEfAgkTiN54TaOBnpcGJRKpHWrF7/KxXnPDfkuIUwXX7sd3szvkRFTPl3tfMwK73gKuuXC3JL4YlPvsFKMWcyZmNYtap9MRW8irotqrXNNKDuuV71/Dl25SU5uU7PeIrIKp23uY7YDozUgx5b3MkwfQKoKT+JM70yHWHFPhzK+Yvwiof5Z137bgaqGdNDXwTlnN7PvDJRL7cydnaAsYpdYTEKXJ/Z0pMhmRpqIxeZWC/QzO4TKE3xCtEx2cUOmgvF8OvOF0rtMLpWvpli5/KZHA2Af+WvAFCyXY2plGick3FdN/lv27dxrgOdoYtlL/YDAg+NfM+Mbod8s3Svvs4y+c24OEitPTKChukh+DXCcuAYw4KTSBf5NjKDvpFcb1Na9evkse9JqdpVtNdwr2SSEGC1RT4hQYGAY+hXLd/J6ohBJfVtLH9rACFJlSUrt2yNTzPFkHKJmHV1PiJELdBPpOa7TR84LoM3vULHxnSdfMpo3lLOd5LjoQfe5J+iN8/gM0ZTGP4scxnhm0tzxDrF3faWYrBRxewO5Roy8WzZwDeG5kgmFaMoQhBaPZrad+Pj73VUOQRorksO7bWHts6d3B6XEhSKyW9m9ZHRWUB8Kzj3gzUW3HB6xtNx3si2y9rCMIW8fi3hUyGGn5M89DXNRaqhn6C5Zo7GfDKX+nB8M/NSmPcLXiPvkNDVvTG1SL9rhoLV7TSAIyrnKRHgeZ9hNtHUyR1PIs9wrGE0qFFO3XZvDLrAhc4tPzYSsiy3OlA3MSDVd08uxHyc9DlPc42/W7zWdIBComgROmipZ8JHzGQTqd+lvyLrChgQM6Ysp30QW1ibzhBEDrWJap0vzhgVochvXtz1dSnEhtK8zmXxYxjsmQ2osn926Q+QGqLas2Kn/eHF7lkmJIXjoRzxxtn1P+4uDEjQ/1WKjHa1FZLORWFrsm+C2xqr2CoO2d7yjj4g+Z0fkmwrEd+p9W2XNJ3jccZ9UZUKKagzt78wNvOh7QTQxJRyWPg9fL6pRK2K8FV9uEMVdWa5drzhyoXPO4CPsYC/Vv/ZRJp3Ymi5ET3F8fKcteEQK1Rdk4OaoSyz6ZWP1wO3SSKVGLi4bh251dPmev5TM5M1nQMbVl7EylWXrs5YlJckI66JJk3ZlOUtPDmUJbPGPndD5auE23be4StrDiQWqHd2RPEGo8Ja0Vg4xf3MXpFBdGy23hq3+PmqpqGxDlHOaoFhdltye91ys1j+YLnxZtAUdSxk3SLQMczbBjQ4IlKp0tfjuvrYGC91xyEv/y3KkrLqYr39u3GXLwCWACWINkFSOR5HaKV/obFBthy0wYn7i8RP/S39+5J5An4TFVy7ywiKebg+Z8YVCu7fzoa/yxuTastMgWoGq33/oHHSnrAoFdBmytH2oQGAdIkQQX2e+L9Iu7fD9uNc2O/o921XAIecAPCT3xLYihgq6u91tyqQ2hTB9HTKFqBaFxz3RsglWMJgu2khIRh28levAOyls9n7/c1oiZqBKhUdHYKrz5FO1CF9l0ml9gHdoSd+6Eq2HiQHn3Q2xVreJ7I9v61kZY5kGZcQKQXwT5Wyfg/PvuFESBr4Wv1Hn4i+5Pmo6Ur+YuND3QyDmGIkJCo7cRnQ0JIpJTyPldGL5TSj0NvHqknb7CkAR4tnXAKIBciheTMs+7iznHHFMVmDXXqjCGnXQy241/orJnkywfo4S6RSAEn96VYy8PLPSnrFrL8r9O5H3QE59tneLaNOnIzuuzbl9Xau0kSzLJJ5N6y6J/M98VeAoI9WwyjfN80/lGPM1dyVavj4ajjxT3UAsOXim/Rgrrr14dvEyw/uZ/s/JutN/Ku2L9YXKmcKOq/LMDn51UOyJP2EEuqqfSHtMKE5ke7vozkonOSxmt21pU6IaW5CawJT9TeLpVsWho+4OQebyiMg3P+eSuBKoxRaSRu5tteu4l15tWmaCwDUAt6v61rcZtfjYVPegxpFptIr9TsQzsYvCwrb8+FbGha21iaO66JTPPCopoRBfl7VoG2L+4nYpnO8uCYmvDn87BUpjqnqhRIB3G7VnO5jlBK+tTxhlmBxcD6ijwqygbt9Ie5CmiY1z2uADwprwZyLXAPP+UbfGxmqBnETJW1lcSf4vz5UMrgFO1tYMx/974dSl1vkO4TkE1qtnncSeVr4//2z6hTzNd7ovv8kwQj6gpLM0ccRNWU56ZNO6exVxt1+2ilQD9vyT4JBB8M/QE+czISOiscrWpASh4d11osVeru9Z6+/1LRz2DCb0luEGnXVA3qqM6MzS+1HSKAtLKYYv8mGh90eDYnxAMZmJ6E0aHKMugx6ozab8piXS1jYuhJJ0qdra/MH8+4fZdTxsysE3eHdfrNJYIVe38hiiX4dBX4ZGOYhpOhcnnlG9Ga2OGjPv3Djb6WbyS0k4tnR8NbZqZ1hB/5OkYvxYK39BeZZonyHIIK+PPseqWMjllHP1k42uyECIiTdtMUxFQvf7Acete/18tUrfqvWoUzIbLNkWOTZ4T0bIH8ej5Nt0BdrZYYVh80MDjTMiu/hsQi0obz2bGbfMwrNEqd71Vo2uFY5N5RCSIWnb2WdbJqtvBS355Ud5pmCHBVPO2zsxAwGRyneiQ29YDY0dGU/TpG3D59PrOSYctGUjI19OPGKONe48+wlUilscI2ySaV9hTB1wYonNzPrCmz5RdPd5x82U8emo97wILMpHdOEhjF/3FabanacJ0zUMpQKaN9pLdsmUvXh7ek7cQjyjJr63j4X3x/QwJs0TH7iVnQka6EadCHWFttpsy6UNr0n6DpVa+j5SrMVSP4loPvtk7nISugO9E60+iA1YY/Jxzy28X0KctDhvAvKrYRzRhwOVCD72QQuNV9rAzfMprQb74+vNo6v3SDinezwSsF820n+uNOGtYagmvGSMGAKOc8eKi7+Pud1m1BYfpgSWJrqii+Yd8zV+IyyKfEzfkMtDKoeLbKq7PbwwmoJQLFO067Zkrlgta4aUOOaVCsQLmuw5c0YrSHMQAhwc516+QRJdhh4Ju+U6PPqCSzRNOlGOuGX6OrhS3lQsL7zHafblbIPJHh6dWE1yxdtcm3v9+AElBH95qbdpVMN7Wos+LAOdVGo37z49Do2aLktlOFT/23eJpiEoiFKCDBh3+ROddNKe6F6VHp9dTEyVk6D90oqdgy6jzVXhQ8nREoFPqBusRIQbhlzB+5L0enUIqK8V/4RHzl0v45XNkvskkyHk40MT8mk2jqHZbOCBNeY3OODB77A4q7uriZObqDAvkvYHE9o7qMvE6rmgHmgBqrZlN1teal0mVBM8Ye7NuZbXQ4dQmMranTfXut/zQKU8B1acTk78ivySr+eSkLaa9Q/E6bFwtjQXMcnnwrCwd+MakOFWn5J2Cv0LrKMNET8nC5ppr/AE1G8kIdetLyfE/kBc/kuhXrJpQg6ctACuH1bxPygkndX+QEq/mIdb90wH+jcQXMWuXr0NnYn8A0WceQmfLoMxonOsZ7gi+2w8Ec+MvT3omQNkZuyoTT7m05/pUxsl1j/RkgCYHvUJHfF7bcc07bfVMwzEV/6tNcx7F/bf20ssd2Wb5nGuAcqH3jKg3Y6/QE9JKo8DjkfV4agzLO8hsbn+gZ9Frn8gU+I2motAOcSy0Z8Ck/63aPTegF+VQ1NNbiTryx1ReIXgyni+obC36IUSOFMIgb2bOlsj1tQLXPQLRcZ0jmHv3c0VeCodmk0ILmgzKWEnabmjQgihwG1M/vVnLyPhig/W1lpCNW2lh8eC4u0BVex/d8LldmyrUcmZyYPN+AcUa7Mvb7FpQ4haRpmpPzC+DJlqPyE8ebpaPEv/+qtAXuBgSl4E5ybwZzXtg4Ihdh48x4N4Xl00SKVZjXE60WftVVNjJkp/W0ej1FYgLfvuFJIkmBB5Bqge+J+HCvRKmGe3h3Ig+drtarot79FKcjSdPExa4iFWrAdKSs4S8NallNvfsvtVL1i+xpXGex479O48buiUTX3ysO9b6ZBQC3MD3qvLxEGVwFcTZff/i/N1NKR91NbQOBvK+xoltQfiDQK52A4KElIPCPyOV/oMu7fi7T+u9AHDl8a/s7uOu/l5b4XVGVxJi4LdS11tQy8fr7AMlspHKut5pA0LSs1EO9O2bB/SwNtg7q8aIKeapDRv/7dXgQ6uZwcVP++veu7LihJQ/Riqu0VBnFjE7c9/keyTWv0Tckv0RU9pKhu5gWZwVWHH45jY+JJeip5kscbt6aRnHuIJ1HRBaqnErRXiKT30PYwo6em79TrO1AzcGfEoMo8+xWIYzbEsKaHCpyecRKiVNSRbB2oZLdeLojta2aOoMhKjPW97vtji6eJi1CFLF0lLYlcW7qPVeTk1MFUZjJOJUmPzfdYZOALuFmJrMa/JSbqlzxSiP001VhLc9JoanzFva/L/OAqVPVluYlai7dSq2BXc9bwsQyIHkTRTTsxm7veq9qdbOyW/kz12FsHtZIPhctdAW5hJdBy4QhDYPzs8AMNiRK3b3MMPnz9ynCLj3h2NqREGLczPJi+yJ+ZlOn4kFK/b3+hE75g3HLrAA2YK8TL2nruJpXyPylshnyw1SwNTjKSE1LrqM4Y8jKNo5Sf0BeNJASgBd9FmqBLH1adlQpQGUY9HrZjUi1++OlfYVBD9FeoqMEVN/7tDXWzn4uSKSweCmM0YAZs7/nwka/AyrIF7t6l4cn3acJlq2+UZSGPAdbbyS0EbK1QzUFKj1t9eK5kSp0i8e3o3Wpoy4BS+2Rtf3oklyCRNaqgNgRuXapU7krHpw/WKhtX8k0BCsam8ezdfBbezT1MHzKGkoo1i2VWoeuxN6VUJ+gV2PoAsWdr7T8JWK26IJb+SPvAR0pC4A07hM33XDc7qcGA5/oKoHHvERgWIIHMOmWU5WrU2I7RhtQxfTC5IzdcbfqQYbTPSZcYEjc7pIYAtLgtmt7YeBx9EjIr7LfV0rpY2+BwAjdapXdrgpE11tG25DpVVu0NF4LdpHDoeFqseq9uJnf0u9kHvqE7KXXBbWN8ryUt7y2KHj95PboXsLLV3U0XKrAsmBKNh3CWiJcRzH+QoZAJPp8wBq+i4oXs7GtlC+467jHD/qu524jMdtkI5XBYmG7k+YMDPzglHWcW9NN0fQP9LAa4ZrW/BhuurtEfD9U6G2xV1pjpio11ZT/X8KMoHuiU3vnptJt23nQNxY34Z0n9mORuZcmUlWcRoa+ffFkCmffQe0rwcEXs8Uhdidg1QUTrV/p1DF+eXryZ/IXPVyH5J1XQVF7P7dcLesy7LLdpYQ7PmTzKdieBRckqvWqNRTjGbot1eggc5p89ZVMqX0YEPVyPHPkQfRAhOC5eIqMm1BNTl8UjaKCkOBraCyliA31EQilvoBGeAJ7N65pIExUXE2GBUnl12YX0xGkUIjVryNm7aEe95/fmuCxKImpqOHHDS8NaZMWymFk+ZAnQvL+WadzCUPv64sTPJ2Dlu10rNlLkMUdAZej1W1cC/inY6Qog3tbZtzOQYos5oHSwB/XJTAQtEeC8/i98u2FCl2bi8v7HSvBT7YApAALw1u0XOvrO8A5M3Zvp0kqCuN+NttBVDBtkixPFjRezWtW+vsCCb7lNWPRY68FeEusT2l2Tjfli4Igf1WI4IMxVGleE5reQr/mIyjNd9YNx5SyyHkqd6e7TEUZf/Px9UPjgtBo3XZl1Gcg3dR+ntCcMs2bsEAoWaZixtaAvsDLtIOCBS9qcewh0jaWGkx7fpzu3G5xp2dLa9ypWUbAkNyb4kd5Klt8lSEb1IpeanzqZYu+dm5Gbc1X/j1mF+8gfL5GuAwcNPPYLXgN68z2PZVyLimBBzmoGh69d7kn3PoIAbpwKvwvqNnKc/0ZnI4weG9FrRqjEq0ZofW3PNEAvYdvAZsi+8Ij/gT5zpxGd94TyN8C3UdQ2aUhtcKbF8XzrkHObjtrhjQJU4Qs4WiB1nhDW+TTXofBD6tPjpVcUVk+9hMPEUvVGF+IpEQWEZ/hlXSLd48RZ74iVamH7mrcFCCYX35lCQIGn5x/axGm/RrtqrWtcsaaq7z9vNglOCQgTfluZSAwBuAJNmE5H/4rjzb9kTEd9LqLk3/9Q1QKQqUiPur08m+WfrR+fRmWjGJcHkEZ0K3yYOYEaxLzaN18w6UtW2BbidmrUhbe2h2otT9+QAWc6Nwslse775UpaYpCI048Cgo/jB0RUtKYfBtp4P8M5gC7SHsVqQ/94hKdEUTHAdz/i7wSVe6LB7uZItJZ+BxYwoxztbEGkco1sc+bOrfrIIKbt3lCRjXfXhUraztyECul/Kk0IFEhqm2jUtJZm6xTO+de1x1xQWIdqEyU5CsfajRa1IqhZLZreLaCjtZun2FU/etBDasJDXuZOxH29F7ZdC45SMK4IqU7bZrcWa7DvletYpVLdezJOVduzjvakQm7UZUIgOG8+11Tdo72DyaQ4jf3teWc0Jr5nK78FpvENOdKAvWjHl9milaeNkox3nKyPa2KDoHfZcZ2NNfIkTJWF9RMXepJXmXvwtJZX1HFxJyTev+iBVh25r2gXMcc3F4jWFQx5K0pEp09RVJENoBhbB9/VF8cRhXUYLotZWufPTOxDw3R8FjfTEjqTRXWe6wmi+qAZiBw+ZClEhpEVCSNXotOIwhRBeLm0m3aB+Fa5nYGHptn7HVEEHFS2j0ayc3E1jQ0qwUsJOAADLttcaFkPuOGS9JXJncOzx3NsrkdmEbpHufhWalaLSA70ggSYXoQ+FDT56LOjxy9Ae8Nsj93ztxWJcX/uYoo9bAy0QZmylQNnQRrKYG6fbJwJ5VM03boCR9vGo08C4udBT/iu+BwmhMlXigt11qjtPNcARLZkGcRVQlY/A3DcUB2KJgaF8ckvwsWyQXU7M3Qr/RqoQqBT6wefh8akIXRuYlpJpBCkj3kfJMFGkEA+NRebyy5BJVIsPhTd97IAzanz3SK88M1fwiamaF6JVhpGGBliOsqdqbA5zYXbSmyeKadMYeFCIaDcnCivYeni+MTEJOvF3m+BBuVhPVB1+H951pvtqWx5Mr3fcts9Em2DtNXG74C/zyziH5uCTvv4UISEJeYjPf/lfN7dV/3VtWP3aZBh3SVUnwWM5Ir/8+ljpXNT6MzsnIdM2zR04o5d/K2UIvJm+bznOWURNqP6TmdHONeDEJJesuSlTDqJtCJM778n92qzudXe5lrTX27l+ivUNkOv54aeZ/JMuY6M1KkisjSqD754/83oS+mfp1YQYfYc7a8LVjneZah46hKe7JJNE+kwm4kgNeDl5DYAl/clHD9j2cBWsFZB88QeJGr6Dybs1yWrTncjshKUgNMeTFtMx2uYwL/uUn1C2iQUipQGxtVO7y6ITkAxz1trXB0HGCXIilCQGUae0tDY8wTvhQRD9UxhwEhhYtj4IEJsKHqI21jDWIgsVZuAQMhkgcc0J+C+Xm/87k7ye+H9yVd86 \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_a30d40ad-611d-4ec3-84be-869ea05acb89.msgpack.zlib b/docs/cassettes/review-tool-calls_a30d40ad-611d-4ec3-84be-869ea05acb89.msgpack.zlib index 84baadf0f..62fed2095 100644 --- a/docs/cassettes/review-tool-calls_a30d40ad-611d-4ec3-84be-869ea05acb89.msgpack.zlib +++ b/docs/cassettes/review-tool-calls_a30d40ad-611d-4ec3-84be-869ea05acb89.msgpack.zlib @@ -1 +1 @@ -eNq9VmtsFFUUbnkFTNWIiAYNXBeVxOxs99XdbjWUpuXRtLWF3dpCqfXuzN2daWfnTmfubndpACmSyEuYQNBIACPbrS4V2lCiBJrYIBHRqKBBCsgfotFQI1ZiNCh4Z7rbN8Ufxv7Yzt57zrnf+b7vntmWtghSVAFLme2CRJACWUK/qFpLm4Iaw0glryZCiPCYi1eUe30Hw4rQ+zRPiKzmZWdDWbBAifAKlgXWwuJQdsSWHUKqCoNIjfsxF7s05VazKQSjdQQ3IEk15QGb1e40A1M6iq7UNJsULCL6ZAqrSDHRXRZTKBLRl5p4SBaogPAINCFI/ylAkIAayDetNYOhTKiqgkoomJHptDZBUaOQD4MgIqMKBbASgnrDgD4BL5TAEgVKrKCy2AyKAUsXKKbhSXUqggrLg0BYMpiygFJaNYQAh2kYJEahGA5bdCAkJhvoDAwG3sEVjMU6WlqPkmDIWBt5gr4jSHJYB99sYgUS02NGQNRLmgQuXS9cZ7VVljVWVcNSObrKxXkLF3uXR5uUYK5pbe0ItsbyXDMKmoLUsDiKTFMlTQMpWyAOsDyUqIR5QKbs66roNLE4LBElBqBKGRNFg4VUr3X/CqreklqHFAUrNDoARRWNQn9vrYsBlLGIg8IaZOihA8OGz4M8sYBiAlSEQgOuSgtpNCbQvgHkOEFfgeJwhwwKbXQXhLTfJoHwAIIQVhBQZcQKAYEFlB0l9n+obwaV3oJxLLDM6S5Z0VAZfbHMX+nxSP6KityqopX/kQW8YUmKPTmBqnc5fXxVa/VJgDkk6hVYEYY5xDiYHEbFkoQIY6ezwuqyW9PHpabF3RnjkMoqgqzLZYBNXdWUA1Lxg9TWqSyPQtBgWKYzDClEMCbSIOFDjKhEEaSgaa1Od8ooets1A5G1w9TG/nrEUr1pe208ghx13Y44j1WidY6Zl0cgyyKZMEhiMUfra+8H1wiyGXAoIEKCkqzOg+FOLdmAkMxAUYigxECW1gFlWRRYw53Z9ZSz9pRQjI5l7HZS15yhU1ci2gcFaRzZFTE63iVgtTicFntHlKFXS5BEOp8Zkd5vLSEb+yeGb8iQbaB1mNSrQ0sMJB8eHoNVrbUMsuXeESV1QbRWqIRczqPD1xU6NYQQ0toKK8Yel9ocOs5hsdksns4RhdWYxGqthrM6B0keTElSLzkYq4ux2g6nWRKRFCS8FrfZ3TnvUrfL9L2HNiZoTRJWW+JUEvT5mbbUm+qd8pK0nFczZsaLqDxat48Pm4HdBbxIBrpZgc2R53Dl2d1gaZmvvTB1jm9cNTp99CKrAarI4rT6bSwflhoQlywcV/de01BfCj1fFEICYVLzmKqlf9XiTqvV2vvMhJEKdb0g6SfGHR6P5x51KTOIaF16f4zVw9hdvoEuc5yresF4mQPv+hSehI6HInpqgsghPOloMGH0+Hjs7lXJFGhG4LST9JnOoyJXpLRy2VKnw70cFvChameo0JYbORZlWBGHOYbQHzyIMRwRJVovcPtRAOY6IQcd9MPucLg5l8vvsXs8VjfichwHIwLUkjaLDQQxDoroSOESphDSOcJ4DdtobUUrXygoKy5sr2ZWYD+m/Pkg5VnCEkp4kUL9qCWNo+kNV1CCpq8oWKl15bIeB3R6cvych2WdzhxmcdWKjrSBBg0S18eD8cNqQ2JgIp3OLJu3dXqG8TfZt7Og/NqirE13tvza+gZ5ZFJtkaV50aw10zLP11ce33w5a98l1Lf8teTtpt3TH2ju//q3W/vNB6xd1dd6Itf7+yPHa650fyfWJRes716/uj58+dZzs388pX0ya++51zs/ijc6z5jf3JU7O/rVnvkXLhadZb488sPW4+9Nv3Xy2UPX+5sq/Ru2bzmae2F9eX7rFwfmL9w+Z97MXRtl/OiNK7abpVcbW8CNokmfFZ2f0jCrZQPSMlfXzFnXczY4bcrjiT64d36Xc9vupqyyG5muU3G39+KSfY8tm/ZLS98rB21ZbwWZjzuC8qZu/sGuc30P/6FuTmiT/l7YcOinRXN9L0+9fwZ5Ygf70M2eE/nR21VvH5/77eZPfR1L9kR+9sxYl70t315yqrqENvB894cL4U7292PX95/ueMks3fdN353Y93/+NTUj486dyRmXAr7ansyMjH8AFOQpEQ== \ No newline at end of file +eNq9Vm1sU1UYHkERjT+IoBgT8dBMlmBv17tuo60ErNsQ5srHOmAfWZqze0/by27Pudxz7kqZmIASJQTwqvzRxMTRtaZOYI74EZUIzkQNkIhEHUEk8YeKZhiDiUHIPPe23We38cPYP+095/143ud53/d2T6YL6VQheE6fghnSocT4AzX3ZHS03UCUPZ+OIxYjcmrjhlDTEUNXhh6NMaZRf3k51BQXxCymE02RXBKJl3eJ5XFEKYwimuogcvLiHdu7HXG4I8xIJ8LU4Qeiu6LSCRwFK37S1u3QiYr4L4dBke7gtxLhUDCzjhIxyMooYDEEEgjyLx0oGNDIascuJxjzhJQqlHEwE915bIZ22IHWlakqiCFVA0liACmGpM7JUUMQgzU6xJJCJeKyIrGkZoe3g9gJR08IUcMcr2WFYdw+y4cKUwR1KWbdKFgzrOzdDklhSctmQg4rpEORC/GMsFvc0hIJaUZwO4XV9VTa2dqYkFu9VY5d7RPKnUpU2yRoOqKGOokNx2buBvK6IpmTADHXwA94OLDSQugEEjEw05OrQIToccisL6ASCVpdYTOSrzt8W7Ct8mgY6TrRuXUEqhRNqmR24RoQA3EEOCiuF0cEo5BrlVBYzNZP493Hq8rB9f8PojnB5lCgiHL12xKhRCIQqFvPNsWgXL/FCNQGyX+kXMjAOLl0BgGmyV5cgHZrAomMVCuCpEJDRoJHqBIowRgxQYWMN0ghWX5Gp+dLRlTSFc3uEAuqfWE3zrj5GiU2TPnsxaHNb047pth7YJTuMT4o0xUcdeyyyLbaVtGRVXRbzrJ9nNakYxuSuNq8uEwMQZnvtEOpGKHM7J+ypY5BSUIaExCWiMzjm+9EdyqaE8goYlWelSwW7DVoZjsR0gSoKl0onfMyj0NNU5XcQJRv44z15WUSLCxTr7OW4gLfdZiZ7wcKOMo3JvlSxcDt8lS6Ko7vEPgMKFjlW5GzzyGlNfv+o/EXGpQ6eRwhv7DNdM756HgbQs3eIJQ2hCaEtAQxe6Eer64cGH+u81lX4sjM1Gycmi5/OZbO4xJFl69/QmCaxJLZa/dV/yjJoy7ZCneFR3BXC27xaIElFeEoi5kpUfSseIv3usbfNui5NI/JDLonxSVBZ77I5N8PPRueLsh5uWRxqpbLY36yFclOIIqgFkmAJ6gEotfvdvtFH3gq2NRXk8/TVFSN/iY+xjTCFakrqJ+RYgbuRHK2pqjuQ46xunSeX1XiChPyS5SrZT2aqUq32z20bEZLnXe9gq2MKY/P55slLmcGMfOEVZ8gVgii2JSv0ttaPI89XELuPZtHlbZQcVzLZ7Ufw1bwWXYbPtMg9LUOlRXzJgabArHXa2d7bHb7MYh5n7Lb8ZkeIijmPom+XKLSGSzHE5ezBjNaT4snm1deUGTzY/6br/S1rZ01HXVBX210S0VzfUsi4ZM7twaPdCnQzIouEUQJiaroWM0aoQbynSqE7BEyM7Ut6wPBdTV9zUIj6SC8l5og7zlMMEqHkM5n08xKKjFkvu10lObujYEW84Q34l5RFfF5fV7J445UVwp1WxuPF4ZpdFhS1qq0/9rtTue28+Cvj+yfX2J/5jYcPFv/2ROL9obRyt/uLv1m3lfqXpcTn7jyZOm9X1Y93HBt8NLjF+/7c/jlnitXP0086/V03HVo4Hqw5Ydr108P//39tfdeyNz6Z2l8ydVji5t/MVJVdY43y5oblObAgn09u+9/4OcLX5cc6pr/4ZGO0IW9pZHzpw/jtsPnTvUE+wbvGfGPHFje/u2N4MqDZRU/Lrpe+8o+9Y25r99a9MGB88sWfr42cvIyTA4sCEqeTS8N/gGGHzq78KfvFtw4Myicokvm7X+mezhau2Sg+rVVL9558ujT+1/9a/Xbl969yWsaGZlbcrPx3O8Pzikp+RdvMzCt \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_b2f73998-baae-4c00-8a90-f4153e924941.msgpack.zlib b/docs/cassettes/review-tool-calls_b2f73998-baae-4c00-8a90-f4153e924941.msgpack.zlib new file mode 100644 index 000000000..9498dc2b0 --- /dev/null +++ b/docs/cassettes/review-tool-calls_b2f73998-baae-4c00-8a90-f4153e924941.msgpack.zlib @@ -0,0 +1 @@ +eNqNVmtsFFUULqJREoMJz0R+MKxAUXd2Z7ZL220atfQFpS3QWdJCUza3M3d3hs7eO8y903ZtmkjFQJRIJkRjYsBAt7u6KX2EGjTlYYQYmsgf/khVIMbE+EMTjSQkRsA7s7t9F+if7t5zzne+c75zTrYv3QlNomG0ZFBDFJpApuwLsfvSJjxkQUKPpOKQqlhJ7t4lhfstU5vcpFJqkDK/HxiaDyCqmtjQZJ+M4/5O0R+HhIAYJMl2rCR+fOZijycOuiMUd0BEPGWcKASCXs6T92IvrT0eE+uQffJYBJoeZpUxo4Ko89SlAlpIOKpCrgsC9s/kNMSR6JueXi83HQkI0QhlZGaHM2wKu12gHYW6zqlQN7gEtjhZhXLHXFQJIK7GBEjWiIx9DhJNGC68C+ImnHrBWI8wvo4XAnH3LQcVIRCYsupYNGRYTvYej6zRhOMzK4eX2ytVOLgeTcmDWhFBrEkYAYV2ldS2N9cXt6jbVKlREls8vW2zap7frdY5/ExILH1OSzyShVBig1tdrobIU2V3WJIINE1sMu8o0AlkhNocMbECdQdB1oGlQL6I38oTjBCkvA4om6F8spzci/dLgUQ2NcMZQZeqa+Ci2Jwp1VRjI4TJGAdufw02hNCkmjtSU+2e7gehpoZinl6n2c5kayZ0im7NerbN0Bq3H4QyU5sVl1YhUNh6nEiqmFB7dN7ADwNZhgblIZKxwvDtc7G3NcPLKTDqVJ6RnS64G2VnOiA0eKBrnTCVjbJHgGHomgwcu/8g69hgTibe4TLfnHEU59naIGpfqMjz8O9OsP1EnOArCvoCI9082wMN6WzBWPcZpZTh2sdnGgwgdzAcPrf7diobPDTTBxN7oAHIu6RZkI4g9gAw48XB8zPfTQtRLQ7tdOXu+elyxul0RT5R9IVGZwGTBJLtAXeuRqeaPBWSCQiBIl4o5gVxKN8lHaIYVe3+EkH4nI26we4WfDfFIKlF+pJMEfj99XTu0pzdtTOv5p2Ctckqpo59qRkqXk4UuSoocww/yImlZYJQJga52obwYGUuTXhBMUbDbItJlAlSnRc/LasW6oBKpnJB2Sc902WZLL+uxTXK584sE8v5aieDgiBMbn6sp8mGXkNOxmRRKBR6Ai7rDKT2mFMfLwZ4UQznqizav3Aed7f47MXOsUo5rBiv157oP80tH7P5KWIWYRjcP1m4UDS26DyKA6Vuttef7D9NMRdT+DQxi1PkFgqf075soo2P8ZzZuKw391jvRflkcsrzmmJfZJ/ZRa9orK1Vw1rXwdD+urpY4yEFVVcF6vs7NWBnRJ/IxTCO6XC4soavBOyk8pK7Qna6al9jRcOOysEWvgm3YzZLYcBmDmEEUxI02WraGVnHlsKOnQlTLLypYp89VhoVSrZGS9rF0kBIiBYH+ermppH8Mk0tS9K5lO6PhMOp7HG+9mD9By8UuH9L60/cqLv61qr3IrB8XcnK7e2rT8GKtUOrzqyzhQbfxK2JU2X3P/zy48vjY1u+Kvvr1PrS548sWX7+eNvt8uHiw90H7pZ0PPz59tDdzy43//OKl14ZkN6v+m/7yPVXT7+zdtnZ06vXkJe3fHvmxOUXw217f/hoY/Rm5txP1dIF3vvvtbpBY/jolT0Dw9ID7/Kd/uAn12oKA9veuH9yYuOmTMvKe03HV/12aZl+oPzTo398/dLNwpNXS7/4ZWz8m79vbAvGx+sPrLh6uPv3MeW74Q339hzr6ft1RX916K75/LN31vwZjB97Dh2SWpNnH+0jXeUPWZ2PHi0t2Hyrd2LrkoKC/wFNFp9z \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_d57d5131-7912-4216-aa87-b7272507fa51.msgpack.zlib b/docs/cassettes/review-tool-calls_d57d5131-7912-4216-aa87-b7272507fa51.msgpack.zlib index 27999e5d4..5e6db5f2f 100644 --- a/docs/cassettes/review-tool-calls_d57d5131-7912-4216-aa87-b7272507fa51.msgpack.zlib +++ b/docs/cassettes/review-tool-calls_d57d5131-7912-4216-aa87-b7272507fa51.msgpack.zlib @@ -1 +1 @@ -eNqFVG1sE2Uc3zIgCkpgvsT4Ei+Vt+muvd5dO27KyxyIG47Vrgjbsoxnd0/bW693xz1Px7oxlAkSgmy7kAlEvjBKq10Zm4Ia5mC+RYNGgWDMWJzDD/hBjTHxFRPnc107RliwH67P3f/3f/v9/s+/PdEEDSRram5KVjE0gIjJCzLbEwbcGoEI74qHIQ5qUsxTWeU7FjHkkcVBjHVU7HAAXbYDFQcNTZdFu6iFHU1ORxgiBAIQxRo0KXolV2i1hUFzPdZCUEW2YsrJsHwhZcuiyJfaVpuhKZCcbBEEDRuxihopRcXWp21BgJciCgchtQ0C8mdQskoh/ypbW50VR5OgYuFEBUQkSHO0i0aaqkJMsyQT42YZKyDWNCWTSwXhdK5MtHoEgSEGLZAEkWjIutW/BahKGyi/ZkzPbgFlVY/geiQGYRgQZKtNJwxAA8vpflptooyj6QOO6ulcCBuyGrC1tRFni1bZgJJVzSTS6iOL1BoaoYgJsq4tEYRAItp0xoIawubALWyfBKIIdUxDVdQkEt88EWiR9UJKgn4FYJgULR7ScprJEIQ6DRS5CcYnvcx+oOuKLALL7mgknKUyrNNWLbeak5Y4NNFMxea7Jdk6HJ4oGQ6VYuwcb2f7m2mEgawqRF1aAaSkuJ62D0436EAMkTh0ZvDM+KRz33SMhszjFUCsrLoppCWIeRwYYTf/9vTvRkTFchiaiVLPrekyxhvpOLvTaRcGbgqMoqpoHvcDBcGBKZKnXJJkljiacdOMsy/LkgLVAA6axzgn94YBkU4uDXw5TkLiCGqPEUXgF58lMmPeU7k+q+ZYTn5sDVHHHPIFI4UU66aqoE5Zs0o5uWLOXUwO6yp8qdJMGt+MYgz4DKAiPxFkbVb8hBiMqCEoJUtnlH3EdqMtg+RX5LCM6cwdJ2JZr2aMZxhmZMltkQYZelm1MsY4QRD+Jy5hBmLzlNUfzQg06/ZNdunia0aomTwnF0WmnrhVD6lo0W2QN+rJoqnbomeuh+VrkpmiaVky3yfnesbpYbdW8Bwb4BrcoQh+IVDd6G0WN59upkVFi0g0JtsS0umBaMbmCMUWLRcFAfg5F3SxbsHPuIrIE7gEQXLzTAN/rEkGZtJpd1IBTQso8GTpM3QpIGuErkqPjZlYU72hpKKsNLWZ9moNGuHPBwjPqqbCeBU0yDiayXRqcsENGCfu3pJq8xTJygF+OVvUwEoiz7votZu8/dkBmhqQmLUd0lt5Z3xyIX2SW/bovjty0r88X9e35R+tXrC7Hh7+Mbz3zf3Q0T33UsvzPb577/zcf2XWgcP8k+sfWj9Wl79wtBfsOIv81+6C8+c0nvuq5/WfjbPF9nkTdcqZwX+WVHg7Nt3PP/vNOLN7bHRF+yuv9R7dMuQY2px/wYM67ntA775b2OA/8PfH3MLzizq+H12297EL44dmlQ1vPzKxZnZl3so5eY7UH8vK5/rWnfJu6S2/srW2tuDw5Y7a7hpv54nFm1o+rVlRECib3XnQc+3iO32ewdVqTqJxf0+jT3iiIPXq04/sKfjt+ov3XHt83o73tO3nu/YUnom2rVS+++mMMLQ0er3/uaKEOFj/0py3fh+ua53Pu0qGj3zQfWnnzt79R39Z5Wq+uiR0sSUe+mHg6q8Luh5uP+rZ+OCHfzWhfzd+uetc11OHqvPlcerg6bWX/1xFOJuYyMtpTe3r/jo3J+c/5ePcUw== \ No newline at end of file +eNqNVWtsFFUU3qUaCWiMBIEETScbBITO7sx26UubAltAIKWvRVqk1Lszd7vTnb13mHu3D2o1FAKJGO1QowbBhLLdxbVCK6gJlMSioImiNBTI+qMYEsVXCD5iIIB4Zx+02Afsn5255zvnfOd859xpizZAnSgYWbsVRKEOJMpeiNEW1eGmECR0WyQIqR/L4bLSSs/+kK7En/JTqpEChwNoih0g6texpkh2CQcdDaIjCAkBdZCEvVhu/t6a22ILgqZaigMQEVsBJwpOVxZnS6PYyQstNh2rkD3ZQgTqNmaVMKOCqHnU6Ad0HuGoH3KNELA/nVMQR3xFttYaMw6WoWriJBWEZMhn84t4ghGClFcBZfTNcBRjNZUJgWAiUypWLYFAl/wmSIZE0hXNrN4EVCYMnA/rI3ObQAVpIVpLJD8MAoZssWmsfqhTJVFNi01SaHPigTZriVyE6gqqs7W2MmezqYoOZZNNEmlWkUZibz2UKEPWtEb9EMhMmTfCfkyo0Tuq14eAJEGN8hBJWGbxjQ/rNitaFidDn1l5TDK7kBDTiAUg1HigKg0wkvQyeoCmqYoETLujnnWsO9Vz3uQy2hwzpeGZYogany5J83CUNbPRQJxgz3bZnT1NPKFAQSrTlnWfUYpoCfuxkQYNSAEWh0+NnRFJOh8cicHE6CoBUmnlXSFNQYwuoAdzXIdHnushRJUgNKLustHpUsbhdNl2UbTn994VmDQjyejyAZXA3jtNvuMScwrObF7I4QXxYLpLKkR11G/szxbFAzokGlsZuDXCQtIQaQszReA3X0VTQ95Zujqt5pBlZriYqWMcXwflLE4UuWIocSy+ixPzCgShQMzhVpR4ut2pNJ4xxej16AARHxNkWVr8qOQPoQCUY+4xZY/bhsvSWX5VCSqUT204E8t8NcIuQRDicydE6mzoFWRmDGfn5+ffIy7rDKTGEbM+XnTyouhJVelaP3aexG7xycsixSpismK8FtwTP8wt7TP3PnzGYZizPj5vLG8coqModuUlsi28N36YYspn3v34jE+RG8v9f+1LJpozAXJk45JobkL0uHxiKeV5RTb62HOtIK71lHufR95NMqivJt7AqtxV+VR+bn+DAoyYaBe5OozrVHjIvZx3A3al8pWJFTKixdVrlpSsdHdX8RXYi9kseQCbOYQRjFRCna2mEZNUHJLZZafDCHOvWFJtHMnzCbmLfHlOKHmh4Mtx8cvWVfSkl+nOsoTNmzLxfdoSSV7OJ6185s7JlsQvw1NWUvq58PCthYZjQ8VgSO3Zc/0J70Pb22ctXfvm0UDVTzTUKcb+bRyc1LY3q+jG8cuXZ6jWKZ/0fXt24Pdfzm/ceBrdnPR2oLXIcfHrzeVbtmkHei8u9R1f3n6m6ULG7rh+ZvriE+dn/rx4y6aCGe+81rHyxHuT3bu64vH5p53tLz77YNjy68e3Hn/k2sDZHZ0/XPkiv3zfByf7V4AFrtmPLZjeMrjvxPKqaatLLh0dkLNmvzJl782OP4d+NG5k7PC0Zv5F/75ZYf/tWo9UuPfw9Q2FV3aeO/nAnPahf/oy/9hTnhv5LvD+61bP1FPbM+bnfbTtYEvHZ/0XmrfuLnzymUczTtUUOye/2kmmXbqae+7lhZf7cfuswWsvze3/8mrmu2uOXZlqsdy+nWHhnrb2vWW1WP4Da5ZAYQ== \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_df4a9900-d953-4465-b8af-bd2858cb63ea.msgpack.zlib b/docs/cassettes/review-tool-calls_df4a9900-d953-4465-b8af-bd2858cb63ea.msgpack.zlib deleted file mode 100644 index 1fc1b90cd..000000000 --- a/docs/cassettes/review-tool-calls_df4a9900-d953-4465-b8af-bd2858cb63ea.msgpack.zlib +++ /dev/null @@ -1 +0,0 @@ -eNqNVX1sE2UY3xgkOiAQVFSUcDYogrvu2l63dcboKGwO2IdrHYxl1Ld3b9tj17vj3ve6DkLCV4JR+Tid8vGHICutlAqbbqAyTAbRQSCIxIhDlIQ/FELUEUKIRjPfu7X7Fu0/vXvf5+P3/H7P89ymRASqSJCl7JQgYagCDpMXpG9KqHCNBhHeEg9DHJL5WHWVx9uqqULv0yGMFVScnw8UwQokHFJlReCsnBzOj9jywxAhEIQo5pf55is5U9ZZwiDqw3IjlJClmLIxdjaPsmSsyEn9Oosqi5A8WTQEVQu55WQCRcLGUVMI4HmIwiFINUFA/lRKkCgUeNGyPo8a8gQICQgTMCPdSWwMo2Ygr0wFIR4VKCCrYWAUTJEnygMkqlQFEicgTs6jyimOHBBMw518CAKVC1EBTTKZslLLSNQwpAIQk2NM4I6J2yxrVgMXblZMsCYkE/7giSyLPpLJsJJA2DwbmdC4ESRFM2pZZ+EE3GzYjEL8qqfEiGsR+ExQzcfY6rx8nX+h2x6pq8OFfjfkAjjkbLKsbxjB4Fju60fhUyHSxFEEWzyaJDU/ZVaXrsH3v7IbKJEPqqqsEusAEBEkgBqM1pB5KBoROBFoPKQdtJNGsiRBTNtJ8zAFdiaTLt0+/84YDxGnCoqhhAk2rR3RZJikg9T6EBeCYWAyrJCmhioWzBYdJHyIEYRVQQpa1ht0G5MiqNAou37AsmGY2rJ/NeSI3qS8RAgCnozbjlhIRlhvHzNARwHHQQXTUOJknsTXPwquFZQ8iocBEWCY5AwezL7Tk40QKjQQhQiMD3jpbUBRRIEzGy9/NeEslRaKNrCMvU4amtNkDCWsHy/J4MivbibzLlGM1cFa7W1RmsyVIIlkYGkREEhxxbw/MfxCAVwjiUOnd4keH3A+MtxGRvrBCsBVeUaENATRDwI1XMB+Mvxc1SQshKGecFePTZe+HErnsNpsVlf7iMCoWeL0g2ZntQ+SPOiSJL3koJkCmrEdybAkQimIQ3prYRHzIWl2hexBuDlOQmINbYoRReD5M4n05jpQtTSj5k9ZM2KLiDr6SW9Iy6PsBZQHKpTRq5TNUewoKLY7qLIKb8qdTuMdV4x2L5ljFCCCLM6In+BCmtQI+aR7XNl7LUNlqSS/KIQFTKfXNhHLeNVjLMMwvc/c11IlTS9IRsaYw+Vy/UdcwgzEeodRH824aHuBd6BKJ7uylxrPc2D3p/HEDTwE0dz7WA7hyVhT97UeH4/dsTKZBk0LvN5Fnsk6WuYvjIZKK/2SVBtdGaldoYJFTtvazijNibLG05h8ACFtNkQU670Uy7N8EWPjgJ9leSfJUcAGGMj7eQY4bX4H1xoRgJ60WW1UUJaDIjzqLqXdgKwR2mO2jZ5YVFdZUlHuTq2ga2S/TPjzAsKzJEsw7oEqaUc9aaYmA67COHGvKanTO4o4lwOwhUU8LHJwLOukFy+vacs00GCDxIztYH5oN8YHFtKX2ZVz3nwgy/zleKu7l+S8MuWvd3cvza8/1El/+mhJd01f7cXNL5dfi/9Y5nvnz7eDDUv6G449e2P+aT7w2M9b2rtn3TvWsE1atWpX07mqfZ7vnaee3P71nZ6K7tyTzytH/Y4r9trdzrsT9yxGM3py711RTs1yH7jU1xcpmr33jbZpPa23efaJHW2n9l/P2373h5uF3/5x+Livcts0/uqG3Oi515a5Onb2LlEPW6/qZ+svTJ/03ty+lvKFHfunT029jpe39W3M7t57KHq1ZeJU7eQXx7femJ06MXmVp2nq5FtrAtTNrm0fT6r86qLwOLvz+vbuRyIHyvZ3zuy/XIJ+n/D3/I5vuubtWNC24aUJdMI9Z2LPjV9feP/ac+zl0wsce3K/O3Mp1cV379t6uww8+FZnS8uCvF2dtx4qdT3s++y3FVNuncW1H8zsP1fR88udQkJcf39O1ucX2Mbz2VlZ/wBwZ4U6 \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_ec77831c-e6b8-4903-9146-e098a4b2fda1.msgpack.zlib b/docs/cassettes/review-tool-calls_ec77831c-e6b8-4903-9146-e098a4b2fda1.msgpack.zlib index ec2404cb5..be2bd2dfa 100644 --- a/docs/cassettes/review-tool-calls_ec77831c-e6b8-4903-9146-e098a4b2fda1.msgpack.zlib +++ b/docs/cassettes/review-tool-calls_ec77831c-e6b8-4903-9146-e098a4b2fda1.msgpack.zlib @@ -1 +1 @@ -eNqFVH9sE1Uc3wAJI4iIERIj8XJBMIbX3rXXbl2WYB0/5MfG2MoGDKxv7157x673jrvXsTJnYCPEaCacJhIlKmFdi80GmwPUoAlRjBOVfwTcBiqJJEYMKAgGMAHfdS2MsGD/6bv3/Xx/fT7f921LN2HTUole2K3qFJsQUfZh2W1pE2+MY4tuS8UwVYicrFpRE+qMm+rQ0wqlhlXqdkNDdUGdKiYxVORCJOZuEt0xbFkwiq1kA5ETw4WBFj4Gm8OUNGLd4ks5UfBI8zg+j2I39S28STTMTnzcwibPrIiwUnTqXG1SIJ1rcVTB3CYM2Z/JqTpnRebzreudOETGmoNDGozLGHiBD1hE1zEFHpZJ8HsEJyAlRMvl0mEsmysXLWxhaCLFAcnYQqZqOP07gJqsgYsQc3R2B6jqRpyGLaTgGGTIFt5gDGCTqtl+Wnik0kT2QBNGNpdFTVWP8q2tzNmhVTWx7FQzgnT6yCNJwwaMKEOub00rGMpMmx1JhVjU7ruP7QMQIWxQgHVEZBbf7oluVo15nIwjGqQ4gxwesnLamUaMDQA1tQmnRrzsXmgYmoqgY3dvYJx151gHTi33mzOOOIBpplP742C+DndVgg2Hzgkur+Ty9DYDi0JV15i6QIOspJSRtR8ZbTAgamRxQG7w7NSI8/7RGGLZXRUQrai5J6QjiN0FzZhf6h99b8Z1qsawnS6vuj9dzng3ndcliq5A3z2BrYSO7K4I1Czcd4fkOy4ZNkteIPiBIO7Ps6RhPUoVu9MreveZ2DLYo8HtKRaSxq22JFMEfzeQzo353hXL8mr+XDA9uYCpY38eUuLzOI+fq8EG58wqJ3pLvf5Sj8gtrgh1l+fShMYUoy9kQt2KMEEW5sVPIyWuN2I5Uz6m7EP83bZMll9TYyoFuTfOxHI+7aQkCMLQnAciTTb0qu5kTHoDgcD/xGXMYGofdPoDQgB4/KGRLn3S2iFuLM+RRZGrJ+XUwyqa/QDk3XryaO6B6LHr8YhrM7migSrbn7FzWBAXBxRj4/NysGmtZxXCDcFYpeVbZB5qBkgjcRlQti0xyA5EM7WHOKm4ISJjiP2S6JMhFLEPBfwlCEYETwAKyN/ZpEI7I7pELkpIVMMHyheBcsjWCKjJjo2dXrCmMlixpLx7NagmDYTxF4KMZ53oOFWDTTaOdiabmj1wE6eYe3VwjX2wBAW8UCoWJFTsRZLkAwvrqnvzA3RnQJLOdshu5a2pkYX0VeGyp16fVJD9jZftM0u/fG7a9jB+54+KJdX12A0mtbWd5CfavT8tf3dQPvz9ieHTOzft6ngVvPiwdf1W4FrVzD174rvLKmu/3TH3/Znuq9dvrtLf+vXWJ+EL9TuPpmdtf5ZWkmmz6eGiwovrLq5+rH3b6RmDW8b9oIRfkjoidv+CgZVPpOsul3UE2/qOvTDlQs/tx3HZxJelybW12s6H6p6Zuu/TLypPhob3n1pXP73r4rH+ORt/VD2HvLWvtUCp6M+/njw+68KJ0N6r8riSRx8Z2LtwJb97qdF144NL39wsmnKFCI27zx7pvdTcee7fssqPVtk9ZObv0bcvX9u8NXV+Q1NBUfLM0fVvTFOGExNPtX94Y8Jk14wtsHnXucFLV6Ye6qdDieUlZ1tmt+8ZKO6YMP+V4LX5xwNnwJvjfe99Pb37t78HKzxTfmGs3b49vuD65PZ/zhcWFPwHw7bk8g== \ No newline at end of file +eNqNVWtsFFUUbkWNPARSmyBRcRyFRunszuxul26L0nYLSklt2a4WWpt6O3O3O+3snWHu3aUPaqQSEy1IJxKNhQSl211YSh+xiUQ0aIjEGIzwB1NMKqmGoAExEiTKj/XOPtpiX+yfvTPnO+d853zn3OmMhqCOZRVl9suIQB2IhD5gozOqwx1BiMmeSAASvyqFKyuqvL1BXR5d7SdEwwVWK9BkC0DEr6uaLFpENWANCdYAxBg0QhxuUKXWS5nr2tkAaKknajNEmC1gBN7myGXYNIq+qW1ndVWB9MQGMdRZahVVSgUR89VOPyA5mCF+yOyEgP7pjIwY7NvAdtSZcVQJKiZOVEBQgpydy+OwihAknAIIpW+GI6qqpDIhEEhkSsWqxxDoot8ESRCLuqyZ1ZuAqoSB8an61NwmUEZakNRj0Q8DgCLbWY3WD3UiJ6ppZ0WZtCYOpFVL5MJEl1Ej29FBnc2myjqUTDZJpFlFGqk2NEGRUGRdR9QPgUSV2R/2q5gYw9N6PQhEEWqEg0hUJRrfONHYJmu5jAR9ZuUx0exCQkwj1gyhxgFFDsFI0ssYApqmyCIw7dYm2rH+VM85k8t0c8yUhqOKIWJ8VpzmYa1spaOBGN5id1hsQy0cJkBGCtWWdp9SimgJ+6mpBg2IzTQOlxo7I5J0HpiKUbHRVw7Eiqq7QpqCGH1ADzgdn059rwcRkQPQiLorp6dLGSfT2S2CYHEN3xUYtyLR6PMBBcPhiSZPuMRsvM3O8U6OFwbSXVIgaiR+o9cuCEd1iDW6MvCtCA1JgrgzTBWB576Npob8SMWWtJpjGSvCpVQd48tqKOUygsCUQpGh8R2MkF/A8wWCnXmx3NvvTqXxzijGsFcHCPuoIBvT4kdFfxA1QynmnlH2UXayLJ3mV+SATLjUhlOxzEcj7OB5fnTNnEidDr2MzIxhu8vlmicu7QwkxohZHyfYOEHwpqoUambOk9gtLnlZpFhFTFaU13Pz4ie5pX3W3IPPLAztNaM5M3mrQTKNYl9+Itva+fGTFFM+OffiMztFZib3/7UvmeiZOZBTG5dEM3OiZ+UTSynPyZLxBT3X88JWZ1mz0+aR2lBbiTvf0xTSBM9Wf29IBkZMsAhMo6o2KnDQvYlzA3qlclWJFTKipdtfLi7f7O7fxnnUBpXOkhfQmUMqgpEqqNPVNGKiogYletnpMELdPcXbjZF8H78uz+cUgYvP431OB7ex2jOUXqaJZQmbN2Xi+7Q7krycv8nknux6KCPxW+DtLt9ypmj52/HvbCusj232/DS+6vire8ZXv76YBadWHjz/Per5qO9sd9zyTtktx7nCmy/cvOB+5c3OnqWth3JvrHqXnF4YDew7fPv4wLHYNfhw1slm7VoJ21HUfb6tcFHPUfbie8Ul1xePfPzVticW7fVdWM/eeFw/cPa38qzosy/xY0LBg7cuxUtWbth0Jzt7fd32tWUj+67uWh4pxdmvHcnvvZJVu9VlyDkXT4Qi7C+DoHvFgdvOZQ5Lfl3elaf2vx/8MfzA4Q/337nuG15bDf8+tLqw+zJ5/t83Lrs+QeWuz+seedS7LDK+NPt84ZIzB+9v+PlXrumvP+InjxW1LLq6pFP/umYhaPvg99M7XHeeLrgvr3as7M/d8aauf/hdmRkZ8fiCjNAPy1Z10fN/12s1SQ== \ No newline at end of file diff --git a/docs/cassettes/review-tool-calls_f9a0d5d4-52ff-49e0-a6f4-41f9a0e844d8.msgpack.zlib b/docs/cassettes/review-tool-calls_f9a0d5d4-52ff-49e0-a6f4-41f9a0e844d8.msgpack.zlib index 052a69dfb..9df5c981f 100644 --- a/docs/cassettes/review-tool-calls_f9a0d5d4-52ff-49e0-a6f4-41f9a0e844d8.msgpack.zlib +++ b/docs/cassettes/review-tool-calls_f9a0d5d4-52ff-49e0-a6f4-41f9a0e844d8.msgpack.zlib @@ -1 +1 @@ -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 \ No newline at end of file +eNqNVt1vFFUUL5AYjSaCSjTGxGGgbYKd3Zl2u3RrGty0RUFKobsCbQOb25k7O5fO3jude2fpWvpQRB80gmPUKDExge0ubgptFQUiJpDIxwNEVBSKHyQ8kPgHiAmJ4J3Z3X7z0Zfu3nPO7/zO+Z1zsrvzaWhTRPCCEYQZtIHK+Bfq7s7bsM+BlO3JpSAziJbd2B6LH3RsNFFpMGbRxmAQWCgAMDNsYiE1oJJUMK0EU5BSkIQ020O0zLWFIwNiCvQnGOmFmIqNgiLXhmoEsezFX7oHRJuYkH8SHQptkVtVwqlg5j3tNACrpgIzoLATAv7PFhAWqL5aHKwRpiIBpYgyTmZmOMdmsN8HWlttmoIBTUvIEEdQDaj2zkaNASyssQFWEVVJwENiGcuH90H8hJMvhJgJztfzwiDlv5WgEhQCWzU8C8KW42UfEFXEMp4P1T0cEWllECchK+GOaESFfTrKRCJbk0ZEfw2v6+8SB7fNqHFud7pn8bEhdcxZLRBjDsaZZX41Jc6Jh8rusaQJaNvE5t46MCnkhLZ54hENmh6CagJHg1KdVC9RgjFkkgkYn5lyspK89+6PBqlqI8sbOZ+qbxB0Yk+XZrKRCcplSwG/nxYfOmgz5I/QZHun+kGZjXBSHPSa7U0ysqFXdHfRc9s0bUnPDqhydXlxeQMCja/DvqxBKHPH5wz4KFBVaDEJYpVoHN89nHwTWTWCBnWv8oLqdcHfILfQC6ElAROlYa4Y5Y4ByzKRCjx7cAfv2EhJJsnjMtdc8BSX+Jpg5h6LlnkEN2b4PmJBDtSFArVj/RKfe4RNvlC8+5xSzvLt3003WEDt5ThSadfdXDH4yHQfQt3hNqC2x2ZAeoK4w8BOhUNfT3+3HcxQCrr55o1z05WMU+nqAooSiIzPAKYZrLrD/lyNTzZ5MqRQK9fWSXJYkpUj5S6ZECeZ4R4MN4QO8VG3+J2Cb+U4JHPo7ixXBF44ny9dlgPtr5fV/Kvi2WwLV8f9fgvUagRFEVqgKnD8kKA0NMpyoyILr7bFR5pLaeLzijEe55eB6lyQ1rL4edVwcC/UCs3zyj4hTpVl8/wmSiEmlc4qF8v76mZDsixPVN3X0+ZDj7CXMVsXiUQegMs7A5l71KtPUmolRYkXq5QjXfPn8XdLKl7oEqucx4rzWvlA/ylu5Ziqh4iZn6Eid01UzxdNHDaH4nCDn+2lB/tPUSzFVD9MzL0pCvOFz2pfMdGK+3hOb1zRW7iv9z35FErKS0hzT/LP/KJvskOd0VV96zo6N7e2bGjr60LpekM/mEbALSgBRUgSkjThaPMaqRnwkyrF/BVy8y2dG6Jta5tHtkodpIfwWYoDPnOYYJiLQZuvpltQTeJo/NjZMMfDO6Kd7tEGXV5Vr4frG2CoTtbDIal1S8dYeZkmlyXrXUr/R8FQrnicf7j54nuPVvh/i9bvvbhjzyuL9yTOXIbB5Yc6l9z85IWFYOKX7QuXnZfDehjvu9a0eMn1puMrPoid3rL68ruXTt+oGuz+KOl+mW6/8mPsbtXFyrdvn/hsg3wJZptaxSPVz13ouzr09GMH9i595NjVnyoeX3388qY7n1450aL/fHJlQe2ML31il1a5+eq//5D43wOj18/ceOPJD9f2bP/q1MSZvlu1L9+K7roQSuPMqVtAeP5cuqraBdE/vtmvnx1dFqrsaR/7/J3Twp+J35cOncsePhvsGWr67f3o+ttffPzrt//xgu7eXVQxsvzOU88sqKj4H6D2kjg= \ No newline at end of file diff --git a/docs/cassettes/wait-user-input_58eae42d-be32-48da-8d0a-ab64471657d9.msgpack.zlib b/docs/cassettes/wait-user-input_58eae42d-be32-48da-8d0a-ab64471657d9.msgpack.zlib deleted file mode 100644 index 86f79ac54..000000000 --- a/docs/cassettes/wait-user-input_58eae42d-be32-48da-8d0a-ab64471657d9.msgpack.zlib +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/docs/cassettes/wait-user-input_a9f599b5-1a55-406b-a76b-f52b3ca06975.msgpack.zlib b/docs/cassettes/wait-user-input_a9f599b5-1a55-406b-a76b-f52b3ca06975.msgpack.zlib index c37cbe052..2b47d6fad 100644 --- a/docs/cassettes/wait-user-input_a9f599b5-1a55-406b-a76b-f52b3ca06975.msgpack.zlib +++ b/docs/cassettes/wait-user-input_a9f599b5-1a55-406b-a76b-f52b3ca06975.msgpack.zlib @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/docs/cassettes/wait-user-input_cfd140f0-a5a6-4697-8115-322242f197b5.msgpack.zlib b/docs/cassettes/wait-user-input_cfd140f0-a5a6-4697-8115-322242f197b5.msgpack.zlib index b94794151..dd2777e25 100644 --- a/docs/cassettes/wait-user-input_cfd140f0-a5a6-4697-8115-322242f197b5.msgpack.zlib +++ b/docs/cassettes/wait-user-input_cfd140f0-a5a6-4697-8115-322242f197b5.msgpack.zlib @@ -1 +1 @@ -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 \ No newline at end of file +eNqNVQtsFFUUbUWNYsCCpNAEcNxgAdvZX7efLUhcln60lNZ2SSlam9eZt7vDzs4Mb94USq2fWhTFgIP4CZFI6HZXN+VTgUAUiISIECpKwE/VIoSEECHFxMjHEPC92Vla7ALdbHbevHvuu+fdc+/d9lgzRKogS+ndgoQhAhwmL6reHkNwqQZV3BENQxyU+Uh1Va2vU0NC35NBjBW12GYDimAFEg4iWRE4KyeHbc0OWxiqKghANdIk8y2/3jep1RIGyxuxHIKSailmHHanK5exJFFk54VWC5JFSFYWTYXIQqycTKhImG4tVCGDg5BRIUBckMGyLJIfBqghY5t6MMuCEBmoFgYgmEtXEiPKcojRFAO1DALyQHSNoKWtgRKQeSjSAJwINB6yeWw+q8qSBDErAkzuTXnQaCZFCYQNigke1MhDlUOCQtNFDV4gGsxUDfnNoE1WihMkRcONKheEYUCArRaF5AsiLBi3b7WQLKMWY4VblEQMjAQpYGlrI95UBQFBnrIwoZR+Eio3LYEcNqCDHD1qqFwLAykFS4+ZtyC1M4AxJKa2kRFVzXNGxjWBTkm3oS0WhIAnpbc2EpRVrPcMK6ZtgOOgglkocTJPYuhbAisEJZfhoZ8qFOeoWka16vEQhAoLRKEZRhNe+nagKKLAAWq3LSHKdptFxVIuw81xWkksKUkJ67s9SR626hZS+xJjt+a5rM7ty1kVA0ESSfGSKiGUooph/2qoQQFciJzDmn2lRxPOW4diZFXvqgRcVe1tR9LK0rsAChe4dgzdR5qEhTDUY97q4eFM42C4PKvDYXX33Haw2iJxepcfiCrsuZXkWy5xp92Zx9oLWLtjazJLIpQCOKh35ucVfIagqpCZAN+IkiOxprZHiCKw93DM7OLNVRVJNU+lTYzMI+ro++ogn8s4HMw8yDHkfBfjKCzOJ183U1bp6/aaYXwpxejxISCpfiJISVL8GBfUpBDk496UsvdZBq+FSHxRCAuYNUcYEYu+6hGX3W7vy74rEpHiFyQaMZLndrvvcS7JDMT6Tno/1uFkHQ6fecuixanjGD3GJqahySpKWRFeT90TP8gt6ZM9Ap87MHQv7pueylvW8DCKXUVGtJx74wcpmj7TR+JzZ4pMKvf/pS8RaNpdkEMTl0Azd0XfkU/cVJ4VeH0vWTfaHSXlBc+r80ufC5R4Khe6lWbPEm9haVlnswD0uMPqYAKyHBDhNm8p6wVktLK1RgvpsXn1CzyVz3q7F7E1cpNMaskHSM1JsgSjtRCR1tTjnChrPBl2CEaJe42nXt9Z5LcX5nNO3u8vLHI5ORdbUlezPdlMt5olQiel8Qf8ejQxoL9JL3t89UNpxmfU/OqGioPPZFzP+Xb/VTQz/NhvK2w11dUZ4yKZOeO3HjnXue/3rr6nwzOvXULjeqqO9g5c7B3I+nPyBJcvevbIlzOEXa0L1rw1fuK1C5t/2Xv85UfGXz3Z9PFcS4Ol/PwnD3dkx9/eBd/7Yc/kMTMOv3vZXboUT9F3ZLo3rIkd4WdvbO/orS89umnOsVcrstZ65kx4YG3doVWjK3MWHFt9aUPOgQ/O6cvnZo55Z/PAqpXRfadHr5x+seNU8ffpP220W0+8OGtW+0s3ZhUFaqqeuKKIX8+ZUjVw9qOrez6XnK982r+luW9vfWbj1GmL+u/vX3f50f3HC86LF7JOZo2dOnPSa+3ayimj+89kaMqh65n/3qi9ryd0Ymz+mPcnpr/54JkDnd9lrP/nUPlfB+t+vPZzNtxdVrFp3bQPT89uRH/X/3GTZOzmzVFpV77YtX5nelraf/0LlPM= \ No newline at end of file diff --git a/docs/cassettes/wait-user-input_f5319e01.msgpack.zlib b/docs/cassettes/wait-user-input_f5319e01.msgpack.zlib deleted file mode 100644 index a6565ab72..000000000 --- a/docs/cassettes/wait-user-input_f5319e01.msgpack.zlib +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file From 3ffed8d38d7611523a40319de00dad6d1b72ccf8 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 13:08:57 -0500 Subject: [PATCH 69/72] x --- docs/docs/concepts/human_in_the_loop.md | 2 +- docs/docs/concepts/v0-human-in-the-loop.md | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 2d5ffd7f9..3b7a146dd 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -2,7 +2,7 @@ !!! tip "This guide uses the new `interrupt` function." - As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [`interrupt` function][langgraph.types.interrupt] as it simplifies **human-in-the-loop** patterns. Please see the [Breakpoints](breakpoints.md) guide for more information. + As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [`interrupt` function][langgraph.types.interrupt] as it simplifies **human-in-the-loop** patterns. If you're looking for the previous version of this conceptual guide, which relied on static breakpoints and `NodeInterrupt` exception, it is available [here](v0-human-in-the-loop.md). diff --git a/docs/docs/concepts/v0-human-in-the-loop.md b/docs/docs/concepts/v0-human-in-the-loop.md index 45ce792d4..de34eefb6 100644 --- a/docs/docs/concepts/v0-human-in-the-loop.md +++ b/docs/docs/concepts/v0-human-in-the-loop.md @@ -1,5 +1,12 @@ # Human-in-the-loop +!!! note "Use the `interrupt` function instead." + + As of LangGraph 0.2.57, the recommended way to set breakpoints is using the [`interrupt` function][langgraph.types.interrupt] as it simplifies **human-in-the-loop** patterns. + + Please see the revised [human-in-the-loop guide](./human_in_the_loop.md) for the latest version that uses the `interrupt` function. + + Human-in-the-loop (or "on-the-loop") enhances agent capabilities through several common user interaction patterns. Common interaction patterns include: @@ -44,7 +51,7 @@ for event in graph.stream(None, thread_config, stream_mode="values"): ### Dynamic Breakpoints -Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./low_level.md#dynamic-breakpoints) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. +Alternatively, the developer can define some *condition* that must be met for a breakpoint to be triggered. This concept of [dynamic breakpoints](./breakpoints.md) is useful when the developer wants to halt the graph under *a particular condition*. This uses a `NodeInterrupt`, which is a special type of exception that can be raised from within a node based upon some condition. As an example, we can define a dynamic breakpoint that triggers when the `input` is longer than 5 characters. ```python def my_node(state: State) -> State: @@ -89,7 +96,7 @@ See [our guide](../how-tos/human_in_the_loop/dynamic_breakpoints.ipynb) for a de Sometimes we want to approve certain steps in our agent's execution. -We can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to the step that we want to approve. +We can interrupt our agent at a [breakpoint](./breakpoints.md) prior to the step that we want to approve. This is generally recommend for sensitive actions (e.g., using external APIs or writing to a database). @@ -120,7 +127,7 @@ See [our guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a detailed h Sometimes we want to review and edit the agent's state. -As with approval, we can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to the step we want to check. +As with approval, we can interrupt our agent at a [breakpoint](./breakpoints) prior to the step we want to check. We can surface the current state to a user and allow the user to edit the agent state. @@ -156,7 +163,7 @@ Sometimes we want to explicitly get human input at a particular step in the grap We can create a graph node designated for this (e.g., `human_input` in our example diagram). -As with approval and editing, we can interrupt our agent at a [breakpoint](./low_level.md#breakpoints) prior to this node. +As with approval and editing, we can interrupt our agent at a [breakpoint](./breakpoints) prior to this node. We can then perform a state update that includes the human input, just as we did with editing state. @@ -319,4 +326,4 @@ for event in graph.stream(None, config, stream_mode="values"): See [this additional conceptual guide](https://langchain-ai.github.io/langgraph/concepts/persistence/#update-state) for related context on forking. -See see [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a detailed how-to on doing time-travel! +See [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a detailed how-to on doing time-travel! From d24ce62c3f3bc438958890123ea1490f59cd125f Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 13:10:42 -0500 Subject: [PATCH 70/72] x --- docs/docs/concepts/v0-human-in-the-loop.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/concepts/v0-human-in-the-loop.md b/docs/docs/concepts/v0-human-in-the-loop.md index de34eefb6..ad2f19aa4 100644 --- a/docs/docs/concepts/v0-human-in-the-loop.md +++ b/docs/docs/concepts/v0-human-in-the-loop.md @@ -29,7 +29,7 @@ All of these interaction patterns are enabled by LangGraph's built-in [persisten ### Breakpoints -Adding a [breakpoint](./low_level.md#breakpoints) a specific location in the graph flow is one way to enable human-in-the-loop. In this case, the developer knows *where* in the workflow human input is needed and simply places a breakpoint prior to or following that particular graph node. +Adding a [breakpoint](./breakpoints.md) a specific location in the graph flow is one way to enable human-in-the-loop. In this case, the developer knows *where* in the workflow human input is needed and simply places a breakpoint prior to or following that particular graph node. Here, we compile our graph with a checkpointer and a breakpoint at the node we want to interrupt before, `step_for_human_in_the_loop`. We then perform one of the above interaction patterns, which will create a new checkpoint if a human edits the graph state. The new checkpoint is saved to the `thread` and we can resume the graph execution from there by passing in `None` as the input. @@ -127,7 +127,7 @@ See [our guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a detailed h Sometimes we want to review and edit the agent's state. -As with approval, we can interrupt our agent at a [breakpoint](./breakpoints) prior to the step we want to check. +As with approval, we can interrupt our agent at a [breakpoint](./breakpoints.md) prior to the step we want to check. We can surface the current state to a user and allow the user to edit the agent state. @@ -163,7 +163,7 @@ Sometimes we want to explicitly get human input at a particular step in the grap We can create a graph node designated for this (e.g., `human_input` in our example diagram). -As with approval and editing, we can interrupt our agent at a [breakpoint](./breakpoints) prior to this node. +As with approval and editing, we can interrupt our agent at a [breakpoint](./breakpoints.md) prior to this node. We can then perform a state update that includes the human input, just as we did with editing state. From fdf19a5be9ef927187d2b1d01f39f76f7e6f905e Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 13:12:29 -0500 Subject: [PATCH 71/72] x --- libs/langgraph/langgraph/types.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/langgraph/langgraph/types.py b/libs/langgraph/langgraph/types.py index db15422cc..850f8ff41 100644 --- a/libs/langgraph/langgraph/types.py +++ b/libs/langgraph/langgraph/types.py @@ -438,8 +438,7 @@ def interrupt(value: Any) -> Any: Any: On subsequent invocations within the same node (same task to be precise), returns the value provided during the first invocation Raises: - GraphInterrupt: On the first invocation within the node, halts execution - and surfaces the provided value to the client. + GraphInterrupt: On the first invocation within the node, halts execution and surfaces the provided value to the client. """ from langgraph.constants import ( CONFIG_KEY_CHECKPOINT_NS, From 189358cb9135633b1bf03d15e5ffbe8e8f559c9a Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 13:22:17 -0500 Subject: [PATCH 72/72] one more link fix --- docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb index d647483ba..c080c4afa 100644 --- a/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb +++ b/docs/docs/how-tos/human_in_the_loop/review-tool-calls.ipynb @@ -16,7 +16,7 @@ " * [Human-in-the-loop](../../../concepts/human_in_the_loop)\n", " * [LangGraph Glossary](../../../concepts/low_level) \n", "\n", - "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](../../../concepts/human-in-the-loop). A common pattern is to add some human in the loop step after certain tool calls. These tool calls often lead to either a function call or saving of some information. Examples include:\n", + "Human-in-the-loop (HIL) interactions are crucial for [agentic systems](../../../concepts/agentic_concepts). A common pattern is to add some human in the loop step after certain tool calls. These tool calls often lead to either a function call or saving of some information. Examples include:\n", "\n", "- A tool call to execute SQL, which will then be run by the tool\n", "- A tool call to generate a summary, which will then be saved to the State of the graph\n",
    \n", + "

    Set up LangSmith for LangGraph development

    \n", + "

    \n", + " Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. LangSmith lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started here. \n", + "

    \n", + "