diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
index 077dd1b67..6bd541d6e 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -1,29 +1,29 @@
name: "\U0001F41B Bug Report"
-description: Report a bug in LangGraph. To report a security issue, please instead use the security option below. For questions, please use the GitHub Discussions.
+description: Report a bug in LangGraph. To report a security issue, please instead use the security option below. For questions, please use the LangChain Forum at forum.langchain.com.
labels: [pending,bug]
body:
- type: markdown
attributes:
- value: >
+ value: |
Thank you for taking the time to file a bug report.
- Use this to report BUGS in LangGraph. For usage questions, feature requests and general design questions, please use [GitHub Discussions](https://github.com/langchain-ai/langgraph/discussions).
+ Use this to report BUGS in LangGraph. For usage questions, feature requests and general design questions, please use the [LangChain Forum](https://forum.langchain.com/).
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
if there's another way to solve your problem:
- [LangGraph Github Discussions](https://github.com/langchain-ai/langgraph/discussions),
- [LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
- [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
- [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
- [GitHub search](https://github.com/langchain-ai/langgraph),
+ * [LangChain Forum](https://forum.langchain.com/),
+ * [LangGraph Github Issues](https://github.com/langchain-ai/langgraph/issues),
+ * [LangGraph how-to guides](https://langchain-ai.github.io/langgraph/how-tos/).
+ * [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
+ * [GitHub search](https://github.com/langchain-ai/langgraph),
- type: checkboxes
id: checks
attributes:
label: Checked other resources
description: Before submitting this issue, please confirm that you have completed all the steps below by checking each option. These steps help ensure your issue is well-defined, relevant, and actionable.
options:
- - label: This is a bug, not a usage question. For questions, please use GitHub Discussions.
+ - label: This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
required: true
- label: I added a clear and detailed title that summarizes the issue.
required: true
@@ -38,7 +38,7 @@ body:
attributes:
label: Example Code
description: |
- Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
+ Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case. Replace this code with your own!
placeholder: |
from langgraph.graph import StateGraph
@@ -78,7 +78,7 @@ body:
attributes:
label: System Info
description: |
- python -m langchain_core.sys_info
+ Run on your machine: `python -m langchain_core.sys_info`
placeholder: |
python -m langchain_core.sys_info
validations:
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index c2d2f70e0..8ab0b8d23 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,15 +1,6 @@
-blank_issues_enabled: true
+blank_issues_enabled: false
version: 2.1
contact_links:
- - name: 🤔 Question or Problem
- about: Ask a question or ask about a problem in GitHub Discussions.
- url: https://github.com/langchain-ai/langgraph/discussions/categories/q-a
- - name: Feature Request
- url: https://github.com/langchain-ai/langgraph/discussions/categories/ideas
- about: Suggest a feature or an idea
- - name: Show and tell
- about: Show what you built with LangChain
- url: https://github.com/langchain-ai/langgraph/discussions/categories/show-and-tell
- name: LangChain Forum
url: https://forum.langchain.com/
- about: General community discussions and support
+ about: General community discussions, support, and feature requests
diff --git a/.github/ISSUE_TEMPLATE/privileged.yml b/.github/ISSUE_TEMPLATE/privileged.yml
index 692a5bde6..f258be6ee 100644
--- a/.github/ISSUE_TEMPLATE/privileged.yml
+++ b/.github/ISSUE_TEMPLATE/privileged.yml
@@ -1,22 +1,22 @@
name: đź”’ Privileged
-description: You are a LangChain maintainer, or was asked directly by a maintainer to create an issue here. If not, check the other options.
+description: You are a LangGraph maintainer, or was asked directly by a maintainer to create an issue here. If not, check the other options.
body:
- type: markdown
attributes:
value: |
- Thanks for your interest in LangChain! 🚀
-
- If you are not a LangChain maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation in a [Question in GitHub Discussions](https://github.com/langchain-ai/langchain/discussions/categories/q-a) instead.
-
- You are a LangChain maintainer if you maintain any of the packages inside of the LangChain repository
- or are a regular contributor to LangChain with previous merged merged pull requests.
+ Thanks for your interest in LangGraph! 🚀
+
+ If you are not a LangGraph maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation on the [LangChain Forum](https://forum.langchain.com/) instead.
+
+ You are a LangGraph maintainer if you maintain any of the packages inside of the LangGraph repository
+ or are a regular contributor to LangGraph with previous merged merged pull requests.
- type: checkboxes
id: privileged
attributes:
label: Privileged issue
description: Confirm that you are allowed to create an issue here.
options:
- - label: I am a LangChain maintainer, or was asked directly by a LangChain maintainer to create an issue here.
+ - label: I am a LangGraph maintainer, or was asked directly by a LangGraph maintainer to create an issue here.
required: true
- type: textarea
id: content
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..2a6380594
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,31 @@
+Thank you for contributing to LangGraph! Follow these steps to mark your pull request as ready for review. **If any of these steps are not completed, your PR will not be considered for review.**
+
+- [ ] **PR title**: Follows the format: {TYPE}({SCOPE}): {DESCRIPTION}
+ - Examples:
+ - feat(core): add multi-tenant support
+ - fix(cli): resolve flag parsing error
+ - docs(openai): update API usage examples
+ - Allowed `{TYPE}` values:
+ - feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, release
+ - Allowed `{SCOPE}` values (optional):
+ - langgraph, docs, cli, checkpoint, checkpoint-postgres, checkpoint-sqlite, prebuilt, scheduler-kafka, sdk-py
+ - Once you've written the title, please delete this checklist item; do not include it in the PR.
+
+- [ ] **PR message**: ***Delete this entire checklist*** and replace with
+ - **Description:** a description of the change. Include a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) if applicable.
+ - **Issue:** the issue # it fixes, if applicable
+ - **Dependencies:** any dependencies required for this change
+ - **Twitter handle:** if your PR gets announced, and you'd like a mention, we'll gladly shout you out!
+
+- [ ] **Add tests and docs**: If you're adding a new integration, you must include:
+ 1. A test for the integration, preferably unit tests that do not rely on network access,
+ 2. An example notebook showing its use. It lives in `docs/docs/integrations` directory.
+
+- [ ] **Lint and test**: Run `make format`, `make lint` and `make test` from the root of the package(s) you've modified. We will not consider a PR unless these three are passing in CI. See [contribution guidelines](https://github.com/langchain-ai/langgraph/blob/main/CONTRIBUTING.md) for more.
+
+Additional guidelines:
+
+- Make sure optional dependencies are imported within a function.
+- Please do not add dependencies to `pyproject.toml` files (even optional ones) unless they are **required** for unit tests.
+- Most PRs should not touch more than one package.
+- Changes should be backwards compatible.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index fcf1bd801..84770db13 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,11 +1,18 @@
-# Please see the documentation for all configuration options:
-# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
-# and
-# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
-
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
+
+ - package-ecosystem: "pip"
+ directories:
+ - "libs/checkpoint"
+ - "libs/checkpoint-postgres"
+ - "libs/checkpoint-sqlite"
+ - "libs/cli"
+ - "libs/langgraph"
+ - "libs/prebuilt"
+ - "libs/sdk-py"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/_integration_test.yml b/.github/workflows/_integration_test.yml
index e6452c637..5857609ec 100644
--- a/.github/workflows/_integration_test.yml
+++ b/.github/workflows/_integration_test.yml
@@ -3,6 +3,9 @@ name: CLI integration test
on:
workflow_call:
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
diff --git a/.github/workflows/_lint.yml b/.github/workflows/_lint.yml
index 585c232df..68c9a78f3 100644
--- a/.github/workflows/_lint.yml
+++ b/.github/workflows/_lint.yml
@@ -8,6 +8,9 @@ on:
type: string
description: "From which folder this pipeline executes"
+permissions:
+ contents: read
+
env:
# This env var allows us to get inline annotations when ruff has complaints.
RUFF_OUTPUT_FORMAT: github
diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml
index c572e96cb..6fb763003 100644
--- a/.github/workflows/_test.yml
+++ b/.github/workflows/_test.yml
@@ -8,6 +8,9 @@ on:
type: string
description: "From which folder this pipeline executes"
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
diff --git a/.github/workflows/_test_langgraph.yml b/.github/workflows/_test_langgraph.yml
index 0a8b515ea..df09511e7 100644
--- a/.github/workflows/_test_langgraph.yml
+++ b/.github/workflows/_test_langgraph.yml
@@ -3,6 +3,9 @@ name: test
on:
workflow_call:
+permissions:
+ contents: read
+
jobs:
build:
runs-on: ubuntu-latest
diff --git a/.github/workflows/_test_release.yml b/.github/workflows/_test_release.yml
index ea0c352aa..2a2324c6f 100644
--- a/.github/workflows/_test_release.yml
+++ b/.github/workflows/_test_release.yml
@@ -11,6 +11,9 @@ on:
env:
PYTHON_VERSION: "3.10"
+permissions:
+ contents: read
+
jobs:
build:
if: github.ref == 'refs/heads/main'
diff --git a/.github/workflows/baseline.yml b/.github/workflows/baseline.yml
index a89bf8b3f..9b2c7cd71 100644
--- a/.github/workflows/baseline.yml
+++ b/.github/workflows/baseline.yml
@@ -7,6 +7,9 @@ on:
paths:
- "libs/**"
+permissions:
+ contents: read
+
jobs:
benchmark:
runs-on: ubuntu-latest
diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml
index e3eba31ac..f5484badb 100644
--- a/.github/workflows/bench.yml
+++ b/.github/workflows/bench.yml
@@ -5,6 +5,9 @@ on:
paths:
- "libs/**"
+permissions:
+ contents: read
+
jobs:
benchmark:
runs-on: ubuntu-latest
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ece56b460..050daa704 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -6,6 +6,9 @@ on:
branches: [main]
pull_request:
+permissions:
+ contents: read
+
# If another push to the same PR or branch happens while this workflow is still running,
# cancel the earlier run in favor of the next run.
#
@@ -21,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
python: ${{ steps.filter.outputs.python }}
- sdk-js: ${{ steps.filter.outputs.sdk-js }}
+ deps: ${{ steps.filter.outputs.deps }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
@@ -36,8 +39,9 @@ jobs:
- 'libs/checkpoint-sqlite/**'
- 'libs/checkpoint-postgres/**'
- 'libs/prebuilt/**'
- sdk-js:
- - 'libs/sdk-js/**'
+ deps:
+ - '**/pyproject.toml'
+ - '**/uv.lock'
lint:
needs: changes
@@ -55,7 +59,7 @@ jobs:
"libs/prebuilt",
]
- if: needs.changes.outputs.python == 'true'
+ if: needs.changes.outputs.python == 'true' || needs.changes.outputs.deps == 'true'
uses: ./.github/workflows/_lint.yml
with:
working-directory: ${{ matrix.working-directory }}
@@ -74,7 +78,7 @@ jobs:
"libs/checkpoint-postgres",
"libs/prebuilt",
]
- if: needs.changes.outputs.python == 'true'
+ if: needs.changes.outputs.python == 'true' || needs.changes.outputs.deps == 'true'
uses: ./.github/workflows/_test.yml
with:
working-directory: ${{ matrix.working-directory }}
@@ -83,7 +87,7 @@ jobs:
# NOTE: we're testing langgraph separately because it requires a different matrix
test-langgraph:
needs: changes
- if: needs.changes.outputs.python == 'true'
+ if: needs.changes.outputs.python == 'true' || needs.changes.outputs.deps == 'true'
name: "cd libs/langgraph"
uses: ./.github/workflows/_test_langgraph.yml
secrets: inherit
@@ -140,73 +144,21 @@ jobs:
integration-test:
needs: changes
- if: needs.changes.outputs.python == 'true'
+ if: needs.changes.outputs.python == 'true' || needs.changes.outputs.deps == 'true'
name: CLI integration test
uses: ./.github/workflows/_integration_test.yml
secrets: inherit
- lint-js:
- needs: changes
- if: needs.changes.outputs.sdk-js == 'true'
- runs-on: ubuntu-latest
- strategy:
- matrix:
- working-directory:
- - "libs/sdk-js"
- defaults:
- run:
- working-directory: ${{ matrix.working-directory }}
- steps:
- - uses: actions/checkout@v4
- - name: Setup Node.js (LTS)
- uses: actions/setup-node@v4
- with:
- node-version: "20"
- cache: "yarn"
- cache-dependency-path: ${{ matrix.working-directory }}/yarn.lock
- - name: Install dependencies
- run: yarn install
- - name: Run lint
- run: yarn lint
- - name: Build
- run: yarn build
-
- test-js:
- needs: changes
- if: needs.changes.outputs.sdk-js == 'true'
- runs-on: ubuntu-latest
- strategy:
- matrix:
- working-directory:
- - "libs/sdk-js"
- defaults:
- run:
- working-directory: ${{ matrix.working-directory }}
- steps:
- - uses: actions/checkout@v4
- - name: Setup Node.js (LTS)
- uses: actions/setup-node@v4
- with:
- node-version: "20"
- cache: "yarn"
- cache-dependency-path: ${{ matrix.working-directory }}/yarn.lock
- - name: Install dependencies
- run: yarn install
- - name: Run tests
- run: yarn test
-
ci_success:
name: "CI Success"
needs:
[
lint,
- lint-js,
test,
test-langgraph,
check-sdk-methods,
check-schema,
integration-test,
- test-js,
]
if: |
always()
diff --git a/.github/workflows/codespell-ignore-words.txt b/.github/workflows/codespell-ignore-words.txt
new file mode 100644
index 000000000..07165207b
--- /dev/null
+++ b/.github/workflows/codespell-ignore-words.txt
@@ -0,0 +1,11 @@
+LangChain
+LangGraph
+LangSmith
+thead
+stdio
+nd
+jupyter
+lets
+lite
+uis
+deque
\ No newline at end of file
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
index c5baf4d42..c00bb42ae 100644
--- a/.github/workflows/codespell.yml
+++ b/.github/workflows/codespell.yml
@@ -34,10 +34,16 @@
id: extract_ignore_words
- name: Codespell
- uses: codespell-project/actions-codespell@v2
+ uses: codespell-project/actions-codespell@v2.0
with:
- skip: '*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.md'
+ skip: '*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.css.map,*.js.map'
ignore_words_list: ${{ steps.extract_ignore_words.outputs.ignore_words_list }}
# We do this to avoid spellchecking cell outputs
- name: Codespell Notebooks
- run: make codespell
\ No newline at end of file
+ run: make codespell
+
+ - name: Codespell LangGraph Library
+ run: |
+ # Change to root directory to check the main LangGraph library
+ cd ..
+ codespell --skip="*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.css.map,*.js.map,*.pyc,__pycache__/*" --ignore-words-list="${{ steps.extract_ignore_words.outputs.ignore_words_list }}" libs/langgraph/langgraph/
\ No newline at end of file
diff --git a/.github/workflows/link_check.yml b/.github/workflows/link_check.yml
index 05897c215..65e041e7b 100644
--- a/.github/workflows/link_check.yml
+++ b/.github/workflows/link_check.yml
@@ -11,6 +11,9 @@ on:
- cron: "0 5 * * *"
workflow_dispatch:
+permissions:
+ contents: read
+
jobs:
markdown-link-check:
runs-on: ubuntu-latest
diff --git a/.github/workflows/pr_lint.yml b/.github/workflows/pr_lint.yml
new file mode 100644
index 000000000..50749b528
--- /dev/null
+++ b/.github/workflows/pr_lint.yml
@@ -0,0 +1,44 @@
+name: PR Title Lint
+
+permissions:
+ pull-requests: read
+
+on:
+ pull_request:
+ types: [opened, edited, synchronize]
+
+jobs:
+ lint-pr-title:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Validate PR Title
+ uses: amannn/action-semantic-pull-request@v5
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ types: |
+ feat
+ fix
+ docs
+ style
+ refactor
+ perf
+ test
+ build
+ ci
+ chore
+ revert
+ release
+ scopes: |
+ checkpoint
+ checkpoint-postgres
+ checkpoint-sqlite
+ cli
+ langgraph
+ prebuilt
+ scheduler-kafka
+ sdk-py
+ docs
+ requireScope: false
+ ignoreLabels: |
+ ignore-lint-pr-title
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e91f25804..78461653c 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -8,6 +8,9 @@ on:
type: string
default: "libs/langgraph"
+permissions:
+ contents: read
+
env:
PYTHON_VERSION: "3.11"
diff --git a/.github/workflows/release_js.yml b/.github/workflows/release_js.yml
deleted file mode 100644
index 70617d6f1..000000000
--- a/.github/workflows/release_js.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: JS Release
-
-on:
- workflow_dispatch:
-
-jobs:
- publish:
- # Disallow publishing from branches that aren't `main`.
- if: github.ref == 'refs/heads/main'
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- working-directory:
- - "libs/sdk-js"
-
- defaults:
- run:
- working-directory: ${{ matrix.working-directory }}
-
- steps:
- - uses: actions/checkout@v4
- # JS Build
- - name: Use Node.js
- uses: actions/setup-node@v4
- with:
- node-version: "20"
- cache: "yarn"
- cache-dependency-path: ${{ matrix.working-directory }}/yarn.lock
-
- - name: Install dependencies
- run: yarn install
- - name: Build
- run: yarn build
- - name: Publish package to NPM
- run: |
- echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
- npm publish
\ No newline at end of file
diff --git a/.github/workflows/run_notebooks.yml b/.github/workflows/run_notebooks.yml
index da49980cd..975df0191 100644
--- a/.github/workflows/run_notebooks.yml
+++ b/.github/workflows/run_notebooks.yml
@@ -11,6 +11,9 @@ on:
schedule:
- cron: "0 13 * * *"
+permissions:
+ contents: read
+
defaults:
run:
working-directory: docs
diff --git a/.github/workflows/uv_lock_ugprade.yml b/.github/workflows/uv_lock_ugprade.yml
new file mode 100644
index 000000000..75d74890c
--- /dev/null
+++ b/.github/workflows/uv_lock_ugprade.yml
@@ -0,0 +1,45 @@
+name: UV Lock Upgrade
+
+on:
+ schedule:
+ # run at midnight every Sunday
+ - cron: '0 0 * * 0'
+ # allow manual triggering
+ workflow_dispatch:
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ upgrade-dependencies:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up uv
+ uses: astral-sh/setup-uv@v6
+ with:
+ # use minimum supported Python version
+ python-version: "3.9"
+ enable-cache: true
+ cache-suffix: "uv-lock-upgrade"
+
+ - name: Run uv lock --upgrade in all Python packages
+ run: make lock-upgrade
+
+ - name: Create Pull Request
+ uses: peter-evans/create-pull-request@v7
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ commit-message: "chore[deps]: upgrade dependencies with `uv lock --upgrade`"
+ title: "chore[deps]: upgrade dependencies with `uv lock --upgrade`"
+ body: |
+ This PR updates the dependencies in all Python packages using `uv lock --upgrade`.
+
+ This is an automated PR created by the UV Lock Upgrade workflow.
+ branch: deps/uv-lock-upgrade
+ delete-branch: true
+ labels: |
+ dependencies
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a4e9a3eca..253b123d5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,7 +9,7 @@ Here are some things to keep in mind for all types of contributions:
- Follow the ["fork and pull request"](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project) workflow.
- Fill out the checked-in pull request template when opening pull requests. Note related issues and tag relevant maintainers.
- Ensure your PR passes formatting, linting, and testing checks before requesting a review.
- - If you would like comments or feedback, please open an issue or discussion and tag a maintainer.
+ - If you would like comments or feedback, please tag a maintainer.
- Backwards compatibility is key. Your changes must not be breaking, except in case of critical bug and security fixes.
- Look for duplicate PRs or issues that have already been opened before opening a new one.
- Keep scope as isolated as possible. As a general rule, your changes should not affect more than one package at a time.
@@ -20,7 +20,7 @@ For bug fixes, please open up an issue before proposing a fix to ensure the prop
### New features
-For new features, please start a new [discussion](https://github.com/langchain-ai/langgraph/discussions), where the maintainers will help with scoping out the necessary changes.
+For new features, please start a new [discussion](https://forum.langchain.com/), where the maintainers will help with scoping out the necessary changes.
## Contribute Documentation
@@ -60,7 +60,7 @@ In LangGraph, these are often higher level guides that show off end-to-end use c
Some examples include:
- [Build a Customer Support Bot](https://langchain-ai.github.io/langgraph/tutorials/customer-support/customer-support/)
-- [Build a SQL Agent](https://langchain-ai.github.io/langgraph/tutorials/sql-agent/)
+- [Build a SQL Agent](https://langchain-ai.github.io/langgraph/tutorials/sql/sql-agent/)
Here are some high-level tips on writing a good tutorial:
@@ -111,7 +111,6 @@ in a more abstract way than how-to guides or tutorials, and should be geared tow
gaining a deeper understanding of the framework. Try to avoid excessively large code examples. The goal here is to
impart perspective to the user rather than to finish a practical project. These guides should cover **why** things work the way they do.
-
To quote the Diataxis website:
> The perspective of explanation is higher and wider than that of the other types. It does not take the user’s eye-level view, as in a how-to guide, or a close-up view of the machinery, like reference material. Its scope in each case is a topic - “an area of knowledge”, that somehow has to be bounded in a reasonable, meaningful way.
@@ -187,9 +186,9 @@ Be concise, including in code samples.
## Setup
-LangChain documentation consists of two components:
+LangGraph documentation consists of two components:
-1. Main Documentation: Hosted at [https://langchain-ai.github.io](https://langchain-ai.github.io/langgraph/),
+1. Main Documentation: Hosted at [https://langchain-ai.github.io/langgraph/](https://langchain-ai.github.io/langgraph/),
this comprehensive resource serves as the primary user-facing documentation.
It covers a wide array of topics, including tutorials, use cases, integrations,
and more, offering extensive guidance on building with LangGraph.
@@ -250,17 +249,17 @@ make serve-docs
#### Linting
-The documentation is linted from the **monorepo root**. To lint it, run the following from there:
+To spell check the docs, run the following from the `docs` directory:
```bash
-make spellcheck
+codespell --skip="*.ambr,*.lock,*.ipynb,*.yaml,*.zlib,*.css.map,*.js.map" --ignore-words-list="infor,thead,stdio,nd,jupyter,lets,lite,uis,deque" .
```
### ️In-code Documentation
The in-code documentation is autogenerated from docstrings.
-For the API reference to be useful, the codebase must be well-documented. This means that all functions, classes, and methods should have a docstring that explains what they do, what the arguments are, and what the return value is. This is a good practice in general, but it is especially important for LangChain because the API reference is the primary resource for developers to understand how to use the codebase.
+For the API reference to be useful, the codebase must be well-documented. This means that all functions, classes, and methods should have a docstring that explains what they do, what the arguments are, and what the return value is. This is a good practice in general, but it is especially important for LangGraph because the API reference is the primary resource for developers to understand how to use the codebase.
We generally follow the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) for docstrings.
@@ -291,4 +290,4 @@ def my_function(arg1: int, arg2: str) -> float:
This is a description of the return value.
"""
return 3.14
-```
\ No newline at end of file
+```
diff --git a/Makefile b/Makefile
index aa4eb9945..477e03123 100644
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,16 @@ lock:
fi; \
done
+# Lock all projects and upgrade dependencies
+.PHONY: lock-upgrade
+lock-upgrade:
+ @for dir in $(LIBS_DIRS); do \
+ if [ -f $$dir/Makefile ]; then \
+ echo "Running lock-upgrade in $$dir"; \
+ (cd $$dir && uv lock --upgrade); \
+ fi; \
+ done
+
# Test all projects
.PHONY: test
test:
diff --git a/README.md b/README.md
index ec9967659..47cc4d052 100644
--- a/README.md
+++ b/README.md
@@ -73,11 +73,12 @@ While LangGraph can be used standalone, it also integrates seamlessly with any L
- [Guides](https://langchain-ai.github.io/langgraph/how-tos/): Quick, actionable code snippets for topics such as streaming, adding memory & persistence, and design patterns (e.g. branching, subgraphs, etc.).
- [Reference](https://langchain-ai.github.io/langgraph/reference/graphs/): Detailed reference on core classes, methods, how to use the graph and checkpointing APIs, and higher-level prebuilt components.
-- [Examples](https://langchain-ai.github.io/langgraph/tutorials/overview/): Guided examples on getting started with LangGraph.
+- [Examples](https://langchain-ai.github.io/langgraph/examples/): Guided examples on getting started with LangGraph.
+- [LangChain Forum](https://forum.langchain.com/): Connect with the community and share all of your technical questions, ideas, and feedback.
- [LangChain Academy](https://academy.langchain.com/courses/intro-to-langgraph): Learn the basics of LangGraph in our free, structured course.
- [Templates](https://langchain-ai.github.io/langgraph/concepts/template_applications/): Pre-built reference apps for common agentic workflows (e.g. ReAct agent, memory, retrieval etc.) that can be cloned and adapted.
- [Case studies](https://www.langchain.com/built-with-langgraph): Hear how industry leaders use LangGraph to ship AI applications at scale.
## Acknowledgements
-LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
+LangGraph is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/). The public interface draws inspiration from [NetworkX](https://networkx.org/documentation/latest/). LangGraph is built by LangChain Inc, the creators of LangChain, but can be used without LangChain.
\ No newline at end of file
diff --git a/docs/.gitignore b/docs/.gitignore
index f4d716881..540583df2 100644
--- a/docs/.gitignore
+++ b/docs/.gitignore
@@ -1,4 +1,3 @@
site/
-docs/cloud/reference/sdk/js_ts_sdk_ref.md
.vercel
diff --git a/docs/Makefile b/docs/Makefile
index 5696fbc6f..95d256241 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,10 +1,4 @@
-.PHONY: lint-docs format-docs build-docs serve-docs serve-clean-docs clean-docs codespell build-typedoc llms-text build-prebuilt tests
-
-build-typedoc:
- cd ../libs/sdk-js && yarn install --include-dev && yarn typedoc
- cd ../libs/sdk-js && yarn --silent concat-md --decrease-title-levels --ignore=js_ts_sdk_ref.md --start-title-level-at 2 docs > ../../docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md 2>/dev/null
- # Add links to the monorepo
- sed -e '1,10s|@langchain/langgraph-sdk|[@langchain/langgraph-sdk](https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-js)|g' docs/cloud/reference/sdk/js_ts_sdk_ref.md > temp_file && mv temp_file docs/cloud/reference/sdk/js_ts_sdk_ref.md
+.PHONY: lint-docs format-docs build-docs serve-docs serve-clean-docs clean-docs codespell llms-text build-prebuilt tests
build-prebuilt:
# Use to create an update to date prebuilt page.
@@ -21,7 +15,7 @@ build-prebuilt:
fi
uv run python -m _scripts.third_party_page.create_third_party_page stats.yml docs/agents/prebuilt.md --language python
-build-docs: build-typedoc build-prebuilt
+build-docs: build-prebuilt
uv run python -m mkdocs build --clean -f mkdocs.yml --strict
llms-text:
@@ -45,7 +39,7 @@ vercel-build-docs: install-vercel-deps
serve-clean-docs: clean-docs
uv run python -m mkdocs serve -c -f mkdocs.yml --strict -w ../libs/langgraph
-serve-docs: build-typedoc
+serve-docs:
uv run python -m mkdocs serve -f mkdocs.yml -w ../libs/langgraph -w ../libs/checkpoint -w ../libs/sdk-py --dirty
clean-docs:
diff --git a/docs/_scripts/generate_llms_text.py b/docs/_scripts/generate_llms_text.py
index ff981834e..a262549c9 100644
--- a/docs/_scripts/generate_llms_text.py
+++ b/docs/_scripts/generate_llms_text.py
@@ -14,10 +14,7 @@ from mkdocs.structure.pages import Page
from pydantic import BaseModel, Field
from yaml import SafeLoader
-from _scripts.notebook_hooks import (
- _on_page_markdown_with_config,
- _apply_conditional_rendering,
-)
+from _scripts.notebook_hooks import _on_page_markdown_with_config
HERE = os.path.dirname(os.path.abspath(__file__))
# Get source directory (parent of HERE / docs)
diff --git a/docs/_scripts/notebook_hooks.py b/docs/_scripts/notebook_hooks.py
index 34dceb064..81882d397 100644
--- a/docs/_scripts/notebook_hooks.py
+++ b/docs/_scripts/notebook_hooks.py
@@ -3,6 +3,7 @@
Lifecycle events: https://www.mkdocs.org/dev-guide/plugins/#events
"""
+import json
import logging
import os
import posixpath
@@ -15,8 +16,8 @@ from mkdocs.structure.files import Files, File
from mkdocs.structure.pages import Page
from _scripts.generate_api_reference_links import update_markdown_with_imports
-from _scripts.notebook_convert import convert_notebook
from _scripts.link_map import JS_LINK_MAP
+from _scripts.notebook_convert import convert_notebook
logger = logging.getLogger(__name__)
logging.basicConfig()
@@ -34,20 +35,20 @@ REDIRECT_MAP = {
"how-tos/streaming-from-final-node.ipynb": "how-tos/streaming-specific-nodes.ipynb",
"how-tos/streaming-events-from-within-tools-without-langchain.ipynb": "how-tos/streaming-events-from-within-tools.ipynb#example-without-langchain",
# graph-api
- "how-tos/state-reducers.ipynb": "how-tos/graph-api#define-and-update-state",
- "how-tos/sequence.ipynb": "how-tos/graph-api#create-a-sequence-of-steps",
- "how-tos/branching.ipynb": "how-tos/graph-api#create-branches",
- "how-tos/recursion-limit.ipynb": "how-tos/graph-api#create-and-control-loops",
- "how-tos/visualization.ipynb": "how-tos/graph-api#visualize-your-graph",
- "how-tos/input_output_schema.ipynb": "how-tos/graph-api#define-input-and-output-schemas",
- "how-tos/pass_private_state.ipynb": "how-tos/graph-api#pass-private-state-between-nodes",
- "how-tos/state-model.ipynb": "how-tos/graph-api#use-pydantic-models-for-graph-state",
- "how-tos/map-reduce.ipynb": "how-tos/graph-api/#map-reduce-and-the-send-api",
- "how-tos/command.ipynb": "how-tos/graph-api/#combine-control-flow-and-state-updates-with-command",
- "how-tos/configuration.ipynb": "how-tos/graph-api/#add-runtime-configuration",
- "how-tos/node-retries.ipynb": "how-tos/graph-api/#add-retry-policies",
- "how-tos/return-when-recursion-limit-hits.ipynb": "how-tos/graph-api/#impose-a-recursion-limit",
- "how-tos/async.ipynb": "how-tos/graph-api/#async",
+ "how-tos/state-reducers.ipynb": "how-tos/graph-api.md#define-and-update-state",
+ "how-tos/sequence.ipynb": "how-tos/graph-api.md#create-a-sequence-of-steps",
+ "how-tos/branching.ipynb": "how-tos/graph-api.md#create-branches",
+ "how-tos/recursion-limit.ipynb": "how-tos/graph-api.md#create-and-control-loops",
+ "how-tos/visualization.ipynb": "how-tos/graph-api.md#visualize-your-graph",
+ "how-tos/input_output_schema.ipynb": "how-tos/graph-api.md#define-input-and-output-schemas",
+ "how-tos/pass_private_state.ipynb": "how-tos/graph-api.md#pass-private-state-between-nodes",
+ "how-tos/state-model.ipynb": "how-tos/graph-api.md#use-pydantic-models-for-graph-state",
+ "how-tos/map-reduce.ipynb": "how-tos/graph-api.md#map-reduce-and-the-send-api",
+ "how-tos/command.ipynb": "how-tos/graph-api.md#combine-control-flow-and-state-updates-with-command",
+ "how-tos/configuration.ipynb": "how-tos/graph-api.md#add-runtime-configuration",
+ "how-tos/node-retries.ipynb": "how-tos/graph-api.md#add-retry-policies",
+ "how-tos/return-when-recursion-limit-hits.ipynb": "how-tos/graph-api.md#impose-a-recursion-limit",
+ "how-tos/async.ipynb": "how-tos/graph-api.md#async",
# memory how-tos
"how-tos/memory/manage-conversation-history.ipynb": "how-tos/memory/add-memory.md",
"how-tos/memory/delete-messages.ipynb": "how-tos/memory/add-memory.md#delete-messages",
@@ -55,8 +56,8 @@ REDIRECT_MAP = {
"how-tos/memory.ipynb": "how-tos/memory/add-memory.md",
"agents/memory.ipynb": "how-tos/memory/add-memory.md",
# subgraph how-tos
- "how-tos/subgraph-transform-state.ipynb": "how-tos/subgraph.ipynb#different-state-schemas",
- "how-tos/subgraphs-manage-state.ipynb": "how-tos/subgraph.ipynb#add-persistence",
+ "how-tos/subgraph-transform-state.ipynb": "how-tos/subgraph.md#different-state-schemas",
+ "how-tos/subgraphs-manage-state.ipynb": "how-tos/subgraph.md#add-persistence",
# persistence how-tos
"how-tos/persistence_postgres.ipynb": "how-tos/memory/add-memory.md#use-in-production",
"how-tos/persistence_mongodb.ipynb": "how-tos/memory/add-memory.md#use-in-production",
@@ -72,10 +73,11 @@ REDIRECT_MAP = {
"how-tos/pass-config-to-tools.ipynb": "how-tos/tool-calling.ipynb#access-config",
"how-tos/pass-run-time-values-to-tools.ipynb": "how-tos/tool-calling.ipynb#read-state",
"how-tos/update-state-from-tools.ipynb": "how-tos/tool-calling.ipynb#update-state",
+ "agents/tools.md": "how-tos/tool-calling.md",
# multi-agent how-tos
- "how-tos/agent-handoffs.ipynb": "how-tos/multi_agent.ipynb#handoffs",
- "how-tos/multi-agent-network.ipynb": "how-tos/multi_agent.ipynb#use-in-a-multi-agent-system",
- "how-tos/multi-agent-multi-turn-convo.ipynb": "how-tos/multi_agent.ipynb#multi-turn-conversation",
+ "how-tos/agent-handoffs.ipynb": "how-tos/multi_agent.md#handoffs",
+ "how-tos/multi-agent-network.ipynb": "how-tos/multi_agent.md#use-in-a-multi-agent-system",
+ "how-tos/multi-agent-multi-turn-convo.ipynb": "how-tos/multi_agent.md#multi-turn-conversation",
# cloud redirects
"cloud/index.md": "index.md",
"cloud/how-tos/index.md": "concepts/langgraph_platform",
@@ -99,10 +101,6 @@ REDIRECT_MAP = {
"how-tos/create-react-agent-memory.ipynb": "agents/memory.md",
"how-tos/create-react-agent-system-prompt.ipynb": "agents/context.md#prompts",
"how-tos/create-react-agent-structured-output.ipynb": "agents/agents.md#structured-output",
- # Time-travel
- "how-tos/human_in_the_loop/edit-graph-state.ipynb": "how-tos/human_in_the_loop/time-travel.md",
- # breakpoints
- "how-tos/human_in_the_loop/dynamic_breakpoints.ipynb": "how-tos/human_in_the_loop/breakpoints.md",
# misc
"prebuilt.md": "agents/prebuilt.md",
"reference/prebuilt.md": "reference/agents.md",
@@ -124,6 +122,11 @@ REDIRECT_MAP = {
"how-tos/review-tool-calls-functional.ipynb": "how-tos/use-functional-api.md",
"how-tos/create-react-agent-hitl.ipynb": "how-tos/human_in_the_loop/add-human-in-the-loop.md",
"agents/human-in-the-loop.md": "how-tos/human_in_the_loop/add-human-in-the-loop.md",
+ "how-tos/human_in_the_loop/dynamic_breakpoints.ipynb": "how-tos/human_in_the_loop/breakpoints.md",
+ "concepts/breakpoints.md": "concepts/human_in_the_loop.md",
+ "how-tos/human_in_the_loop/breakpoints.md": "how-tos/human_in_the_loop/add-human-in-the-loop.md",
+ "cloud/how-tos/human_in_the_loop_breakpoint.md": "cloud/how-tos/add-human-in-the-loop.md",
+ "how-tos/human_in_the_loop/edit-graph-state.ipynb": "how-tos/human_in_the_loop/time-travel.md",
}
@@ -355,12 +358,16 @@ def _on_page_markdown_with_config(
def on_page_markdown(markdown: str, page: Page, **kwargs: Dict[str, Any]):
- return _on_page_markdown_with_config(
- markdown,
- page,
- add_api_references=True,
- **kwargs,
+ finalized_markdown = (
+ _on_page_markdown_with_config(
+ markdown,
+ page,
+ add_api_references=True,
+ **kwargs,
+ )
)
+ page.meta["original_markdown"] = finalized_markdown
+ return finalized_markdown
# redirects
@@ -430,20 +437,51 @@ height="0" width="0" style="display:none;visibility:hidden">
else:
return html # fallback if no
found
+def _inject_markdown_into_html(html: str, page: Page) -> str:
+ """Inject the original markdown content into the HTML page as JSON."""
+ original_markdown = page.meta.get("original_markdown", "")
+ if not original_markdown:
+ return html
+ markdown_data = {
+ "markdown": original_markdown,
+ "title": page.title or "Page Content",
+ "url": page.url or "",
+ }
-def on_post_page(output: str, page: Page, config: MkDocsConfig) -> str:
+ # Properly escape the JSON for HTML
+ json_content = json.dumps(markdown_data, ensure_ascii=False)
+
+ json_content = (
+ json_content.replace("", "\\u003c/")
+ .replace("'
+ )
+
+ # Insert before if it exists, otherwise before .
Args:
- output: The HTML output of the page.
+ html: The HTML output of the page.
page: The page instance.
config: The MkDocs configuration object.
Returns:
modified HTML output with GTM code injected.
"""
- return _inject_gtm(output)
-
+ html = _inject_markdown_into_html(html, page)
+ return _inject_gtm(html)
# Create HTML files for redirects after site dir has been built
def on_post_build(config):
diff --git a/docs/docs/additional-resources/index.md b/docs/docs/additional-resources/index.md
new file mode 100644
index 000000000..33e52e805
--- /dev/null
+++ b/docs/docs/additional-resources/index.md
@@ -0,0 +1,11 @@
+# Additional resources
+
+This section contains additional resources for LangGraph.
+
+- [Community agents](../agents/prebuilt.md): A collection of prebuilt libraries that you can use in your LangGraph applications.
+- [LangGraph Academy](https://academy.langchain.com/courses/intro-to-langgraph): A collection of courses that teach you how to use LangGraph.
+- [Case studies](../adopters.md): A collection of case studies that show how LangGraph is used in production.
+- [FAQ](../concepts/faq.md): A collection of frequently asked questions about LangGraph.
+- [llms.txt](../llms-txt-overview.md): A list of documentation files in the `llms.txt` format that allow LLMs and agents to access our documentation.
+- [LangChain Forum](https://forum.langchain.com/): A place to ask questions and get help from other LangGraph users.
+- [Troubleshooting](../troubleshooting/errors/index.md): A collection of troubleshooting guides for common issues.
\ No newline at end of file
diff --git a/docs/docs/adopters.md b/docs/docs/adopters.md
index 91142d44f..d2b8a278b 100644
--- a/docs/docs/adopters.md
+++ b/docs/docs/adopters.md
@@ -8,24 +8,41 @@ This list of companies using LangGraph and their success stories is compiled fro
| [AirTop](https://www.airtop.ai/) | Software & Technology (GenAI Native) | Browser automation for AI agents | [Case study, 2024](https://blog.langchain.dev/customers-airtop/) |
| [AppFolio](https://www.appfolio.com/) | Real Estate | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-appfolio/) |
| [Athena Intelligence](https://www.athenaintel.com/) | Software & Technology (GenAI Native) | Research & summarization | [Case study, 2024](https://blog.langchain.dev/customers-athena-intelligence/) |
+| [BlackRock](https://www.blackrock.com/) | Financial Services | Copilot for domain-specific task | [Interrupt talk, 2025](https://youtu.be/oyqeCHFM5U4?feature=shared) |
| [Captide](https://www.captide.co/) | Software & Technology (GenAI Native) | Data extraction | [Case study, 2025](https://blog.langchain.dev/how-captide-is-redefining-equity-research-with-agentic-workflows-built-on-langgraph-and-langsmith/) |
-| [Cisco Outshift](https://outshift.cisco.com/) | Software & Technology | DevOps | [Blog post, 2025](https://outshift.cisco.com/blog/build-react-agent-application-for-devops-tasks-using-rest-apis) |
+| [Cisco CX](https://www.cisco.com/site/us/en/services/modern-data-center/index.html?CCID=cc005911&DTID=eivtotr001480&OID=srwsas032775) | Software & Technology | Customer support | [Interrupt Talk, 2025](https://youtu.be/gPhyPRtIMn0?feature=shared) |
+| [Cisco Outshift](https://outshift.cisco.com/) | Software & Technology | DevOps | [Video story, 2025](https://www.youtube.com/watch?v=htcb-vGR_x0); [Case study, 2025](https://blog.langchain.com/cisco-outshift/); [Blog post, 2025](https://outshift.cisco.com/blog/build-react-agent-application-for-devops-tasks-using-rest-apis) |
+| [Cisco TAC](https://www.cisco.com/c/en/us/support/index.html) | Software & Technology | Customer support | [Video story, 2025](https://youtu.be/EAj0HBDGqaE?feature=shared) |
+| [City of Hope](https://www.cityofhope.org/) | Non-profit | Copilot for domain-specific task | [Video story, 2025](https://youtu.be/9ABwtK2gIZU?feature=shared) |
| [C.H. Robinson](https://www.chrobinson.com/en-us/) | Logistics | Automation | [Case study, 2025](https://blog.langchain.dev/customers-chrobinson/) |
+| [Definely](https://www.definely.com/) | Legal | Copilot for domain-specific task | [Case study, 2025](https://blog.langchain.com/customers-definely/) |
+| [Docent Pro](https://docentpro.com/) | Travel | GenAI embedded product experiences | [Case study, 2025](https://blog.langchain.com/customers-docentpro/) |
| [Elastic](https://www.elastic.co/) | Software & Technology | Copilot for domain-specific task | [Blog post, 2025](https://www.elastic.co/blog/elastic-security-generative-ai-features) |
+| [Exa](https://exa.ai/) | Software & Technology (GenAI Native) | Search | [Case study, 2025](https://blog.langchain.com/exa/) |
| [GitLab](https://about.gitlab.com/) | Software & Technology | Code generation | [Duo workflow docs](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/duo_workflow/) |
+| [Harmonic](https://harmonic.ai/) | Software & Technology | Search | [Case study, 2025](https://blog.langchain.com/customers-harmonic/) |
| [Inconvo](https://inconvo.ai/?ref=blog.langchain.dev) | Software & Technology | Code generation | [Case study, 2025](https://blog.langchain.dev/customers-inconvo/) |
| [Infor](https://infor.com/) | Software & Technology | GenAI embedded product experiences; customer support; copilot | [Case study, 2025](https://blog.langchain.dev/customers-infor/) |
+| [J.P. Morgan](https://www.jpmorganchase.com/) | Financial Services | Copilot for domain-specific task | [Interrupt talk, 2025](https://youtu.be/yMalr0jiOAc?feature=shared) |
| [Klarna](https://www.klarna.com/) | Fintech | Copilot for domain-specific task | [Case study, 2025](https://blog.langchain.dev/customers-klarna/) |
| [Komodo Health](https://www.komodohealth.com/) | Healthcare | Copilot for domain-specific task | [Blog post](https://www.komodohealth.com/perspectives/new-gen-ai-assistant-empowers-the-enterprise/) |
-| [LinkedIn](https://www.linkedin.com/) | Social Media | Code generation; Search & discovery | [Blog post, 2025](https://www.linkedin.com/blog/engineering/ai/practical-text-to-sql-for-data-analytics); [Blog post, 2024](https://www.linkedin.com/blog/engineering/generative-ai/behind-the-platform-the-journey-to-create-the-linkedin-genai-application-tech-stack) |
+| [LinkedIn](https://www.linkedin.com/) | Social Media | Code generation; Search & discovery | [Interrupt talk, 2025](https://youtu.be/NmblVxyBhi8?feature=shared); [Blog post, 2025](https://www.linkedin.com/blog/engineering/ai/practical-text-to-sql-for-data-analytics); [Blog post, 2024](https://www.linkedin.com/blog/engineering/generative-ai/behind-the-platform-the-journey-to-create-the-linkedin-genai-application-tech-stack) |
| [Minimal](https://gominimal.ai/) | E-commerce | Customer support | [Case study, 2025](https://blog.langchain.dev/how-minimal-built-a-multi-agent-customer-support-system-with-langgraph-langsmith/) |
+| [Modern Treasury](https://www.moderntreasury.com/) | Fintech | GenAI embedded product experiences | [Video story, 2025](https://youtu.be/AwAiffXqaCU?feature=shared) |
+| [Monday](https://monday.com/) | Software & Technology | GenAI embedded product experiences | [Interrupt talk, 2025](https://blog.langchain.dev/how-minimal-built-a-multi-agent-customer-support-system-with-langgraph-langsmith/) |
+| [Morningstar](https://www.morningstar.com/) | Financial Services | Research & summarization | [Video story, 2025](https://youtu.be/6LidoFXCJPs?feature=shared) |
| [OpenRecovery](https://www.openrecovery.com/) | Healthcare | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-openrecovery/) |
+| [Pigment](https://www.pigment.com/) | Fintech | GenAI embedded product experiences | [Video story, 2025](https://youtu.be/5JVSO2KYOmE?feature=shared) |
+| [Prosper](https://www.prosper.com/) | Fintech | Customer support | [Video story, 2025](https://youtu.be/9RFNOYtkwsc?feature=shared) |
| [Qodo](https://www.qodo.ai/) | Software & Technology (GenAI Native) | Code generation | [Blog post, 2025](https://www.qodo.ai/blog/why-we-chose-langgraph-to-build-our-coding-agent/) |
-| [Rakuten](https://www.rakuten.com/) | E-commerce / Fintech | Copilot for domain-specific task | [Blog post, 2025](https://rakuten.today/blog/from-ai-hype-to-real-world-tools-rakuten-teams-up-with-langchain.html) |
+| [Rakuten](https://www.rakuten.com/) | E-commerce / Fintech | Copilot for domain-specific task | [Video story, 2025](https://youtu.be/gD1LIjCkuA8?feature=shared); [Blog post, 2025](https://rakuten.today/blog/from-ai-hype-to-real-world-tools-rakuten-teams-up-with-langchain.html) |
| [Replit](https://replit.com/) | Software & Technology | Code generation | [Blog post, 2024](https://blog.langchain.dev/customers-replit/); [Breakout agent story, 2024](https://www.langchain.com/breakoutagents/replit); [Fireside chat video, 2024](https://www.youtube.com/watch?v=ViykMqljjxU) |
| [Rexera](https://www.rexera.com/) | Real Estate (GenAI Native) | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-rexera/) |
+| [Abu Dhabi Government](https://www.tamm.abudhabi/) | Government | Search | [Case study, 2025](https://blog.langchain.com/customers-abu-dhabi-government/) |
| [Tradestack](https://www.tradestack.uk/) | Software & Technology (GenAI Native) | Copilot for domain-specific task | [Case study, 2024](https://blog.langchain.dev/customers-tradestack/) |
-| [Uber](https://www.uber.com/) | Transportation | Developer productivity; Code generation | [Presentation, 2024](https://dpe.org/sessions/ty-smith-adam-huda/this-year-in-ubers-ai-driven-developer-productivity-revolution/); [Video, 2024](https://www.youtube.com/watch?v=8rkA5vWUE4Y) |
-| [Unify](https://www.unifygtm.com/) | Software & Technology (GenAI Native) | Copilot for domain-specific task | [Blog post, 2024](https://blog.langchain.dev/unify-launches-agents-for-account-qualification-using-langgraph-and-langsmith/) |
-| [Vizient](https://www.vizientinc.com/) | Healthcare | Copilot for domain-specific task | [Case study, 2025](https://blog.langchain.dev/p/3d2cd58c-13a5-4df9-bd84-7d54ed0ed82c/) |
+| [Uber](https://www.uber.com/) | Transportation | Developer productivity; Code generation | [Interrupt talk, 2025](https://youtu.be/Bugs0dVcNI8?feature=shared); [Presentation, 2024](https://dpe.org/sessions/ty-smith-adam-huda/this-year-in-ubers-ai-driven-developer-productivity-revolution/); [Video, 2024](https://www.youtube.com/watch?v=8rkA5vWUE4Y) |
+| [Unify](https://www.unifygtm.com/) | Software & Technology (GenAI Native) | Copilot for domain-specific task | [Interrupt talk, 2025](https://youtu.be/pKk-LfhujwI?feature=shared); [Blog post, 2024](https://blog.langchain.dev/unify-launches-agents-for-account-qualification-using-langgraph-and-langsmith/) |
+| [Vizient](https://www.vizientinc.com/) | Healthcare | Copilot for domain-specific task | [Video story, 2025](https://www.youtube.com/watch?v=vrjJ6NuyTWA); [Case study, 2025](https://blog.langchain.dev/p/3d2cd58c-13a5-4df9-bd84-7d54ed0ed82c/) |
| [Vodafone](https://www.vodafone.com/) | Telecommunications | Code generation; internal search | [Case study, 2025](https://blog.langchain.dev/customers-vodafone/) |
+| [WebToon](https://www.webtoons.com/en/) | Media & Entertainment | Data extraction | [Case study, 2025](https://blog.langchain.com/customers-webtoon/) |
+| [11x](https://www.11x.ai/) | Software & Technology (GenAI Native) | Research & outreach | [Interrupt talk, 2025](https://youtu.be/fegwPmaAPQk?feature=shared) |
diff --git a/docs/docs/agents/agents.md b/docs/docs/agents/agents.md
index b00184266..04ee419ce 100644
--- a/docs/docs/agents/agents.md
+++ b/docs/docs/agents/agents.md
@@ -52,7 +52,7 @@ agent.invoke(
)
```
-1. Define a tool for the agent to use. Tools can be defined as vanilla Python functions. For more advanced tool usage and customization, check the [tools](./tools.md) page.
+1. Define a tool for the agent to use. Tools can be defined as vanilla Python functions. For more advanced tool usage and customization, check the [tools](../how-tos/tool-calling.md) page.
2. Provide a language model for the agent to use. To learn more about configuring language models for the agents, check the [models](./models.md) page.
3. Provide a list of tools for the model to use.
4. Provide a system prompt (instructions) to the language model used by the agent.
diff --git a/docs/docs/agents/evals.md b/docs/docs/agents/evals.md
index 74fdb5a63..ead956dd5 100644
--- a/docs/docs/agents/evals.md
+++ b/docs/docs/agents/evals.md
@@ -15,7 +15,7 @@ To evaluate your agent's performance you can use `LangSmith` [evaluations](https
def evaluator(*, outputs: dict, reference_outputs: dict):
# compare agent outputs against reference outputs
output_messages = outputs["messages"]
- reference_messages = reference["messages"]
+ reference_messages = reference_outputs["messages"]
score = compare_messages(output_messages, reference_messages)
return {"key": "evaluator_score", "score": score}
```
diff --git a/docs/docs/agents/mcp.md b/docs/docs/agents/mcp.md
index 9b654ffa5..e204ac3bc 100644
--- a/docs/docs/agents/mcp.md
+++ b/docs/docs/agents/mcp.md
@@ -9,21 +9,12 @@ hide:
# Use MCP
-[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that standardizes how applications provide tools and context to language models. LangGraph agents can use tools defined on MCP servers through the `langchain-mcp-adapters` library.
-
-
-
-Install the `langchain-mcp-adapters` library to use MCP tools in LangGraph:
-
-```bash
-pip install langchain-mcp-adapters
-```
+The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide tools and context to language models. LangGraph agents can use tools defined on MCP servers through the `langchain-mcp-adapters` library.
## Use MCP tools
The `langchain-mcp-adapters` package enables agents to use tools defined across one or more MCP servers.
-
=== "In an agent"
```python title="Agent using tools defined on MCP servers"
@@ -64,14 +55,16 @@ The `langchain-mcp-adapters` package enables agents to use tools defined across
=== "In a workflow"
- ```python
+ ```python title="Workflow using MCP tools with ToolNode"
from langchain_mcp_adapters.client import MultiServerMCPClient
- from langgraph.graph import StateGraph, MessagesState, START
- from langgraph.prebuilt import ToolNode, tools_condition
-
from langchain.chat_models import init_chat_model
- model = init_chat_model("openai:gpt-4.1")
+ from langgraph.graph import StateGraph, MessagesState, START, END
+ from langgraph.prebuilt import ToolNode
+ # Initialize the model
+ model = init_chat_model("anthropic:claude-3-5-sonnet-latest")
+
+ # Set up MCP client
client = MultiServerMCPClient(
{
"math": {
@@ -89,22 +82,47 @@ The `langchain-mcp-adapters` package enables agents to use tools defined across
)
tools = await client.get_tools()
- def call_model(state: MessagesState):
- response = model.bind_tools(tools).invoke(state["messages"])
- return {"messages": response}
+ # Bind tools to model
+ model_with_tools = model.bind_tools(tools)
+ # Create ToolNode
+ tool_node = ToolNode(tools)
+
+ def should_continue(state: MessagesState):
+ messages = state["messages"]
+ last_message = messages[-1]
+ if last_message.tool_calls:
+ return "tools"
+ return END
+
+ # Define call_model function
+ async def call_model(state: MessagesState):
+ messages = state["messages"]
+ response = await model_with_tools.ainvoke(messages)
+ return {"messages": [response]}
+
+ # Build the graph
builder = StateGraph(MessagesState)
- builder.add_node(call_model)
- builder.add_node(ToolNode(tools))
+ builder.add_node("call_model", call_model)
+ builder.add_node("tools", tool_node)
+
builder.add_edge(START, "call_model")
builder.add_conditional_edges(
"call_model",
- tools_condition,
+ should_continue,
)
builder.add_edge("tools", "call_model")
+
+ # Compile the graph
graph = builder.compile()
- math_response = await graph.ainvoke({"messages": "what's (3 + 5) x 12?"})
- weather_response = await graph.ainvoke({"messages": "what is the weather in nyc?"})
+
+ # Test the graph
+ math_response = await graph.ainvoke(
+ {"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]}
+ )
+ weather_response = await graph.ainvoke(
+ {"messages": [{"role": "user", "content": "what is the weather in nyc?"}]}
+ )
```
@@ -157,4 +175,4 @@ if __name__ == "__main__":
- [MCP documentation](https://modelcontextprotocol.io/introduction)
- [MCP Transport documentation](https://modelcontextprotocol.io/docs/concepts/transports)
-- [langchain_mcp_adapters](https://github.com/langchain-ai/langchain-mcp-adapters)
\ No newline at end of file
+- [langchain_mcp_adapters](https://github.com/langchain-ai/langchain-mcp-adapters)
diff --git a/docs/docs/agents/models.md b/docs/docs/agents/models.md
index 6b8af56a7..46db9c41d 100644
--- a/docs/docs/agents/models.md
+++ b/docs/docs/agents/models.md
@@ -7,7 +7,7 @@ LangGraph provides built-in support for [LLMs (language models)](https://python.
Use [`init_chat_model`](https://python.langchain.com/docs/how_to/chat_models_universal_init/) to initialize models:
-{!snippets/chat_model_tabs.md!}
+{% include-markdown "../../snippets/chat_model_tabs.md" %}
### Instantiate a model directly
diff --git a/docs/docs/agents/overview.md b/docs/docs/agents/overview.md
index 35426cc1d..96fef74b3 100644
--- a/docs/docs/agents/overview.md
+++ b/docs/docs/agents/overview.md
@@ -30,7 +30,7 @@ LangGraph includes several capabilities essential for building robust, productio
- [**Memory integration**](../how-tos/memory/add-memory.md): Native support for *short-term* (session-based) and *long-term* (persistent across sessions) memory, enabling stateful behaviors in chatbots and assistants.
- [**Human-in-the-loop control**](../concepts/human_in_the_loop.md): Execution can pause *indefinitely* to await human feedback—unlike websocket-based solutions limited to real-time interaction. This enables asynchronous approval, correction, or intervention at any point in the workflow.
- [**Streaming support**](../how-tos/streaming.md): Real-time streaming of agent state, model tokens, tool outputs, or combined streams.
-- [**Deployment tooling**](./deployment.md): Includes infrastructure-free deployment tools. [**LangGraph Platform**](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) supports testing, debugging, and deployment.
+- [**Deployment tooling**](../tutorials/langgraph-platform/local-server.md): Includes infrastructure-free deployment tools. [**LangGraph Platform**](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) supports testing, debugging, and deployment.
- **[Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/)**: A visual IDE for inspecting and debugging workflows.
- Supports multiple [**deployment options**](https://langchain-ai.github.io/langgraph/concepts/deployment_options.md) for production.
@@ -60,7 +60,7 @@ Use the following tool to visualize the graph generated by
and to view an outline of the corresponding code.
It allows you to explore the infrastructure of the agent as defined by the presence of:
-* [`tools`](../agents/tools.md): A list of tools (functions, APIs, or other callable objects) that the agent can use to perform tasks.
+* [`tools`](../how-tos/tool-calling.md): A list of tools (functions, APIs, or other callable objects) that the agent can use to perform tasks.
* [`pre_model_hook`](../how-tos/create-react-agent-manage-message-history.ipynb): A function that is called before the model is invoked. It can be used to condense messages or perform other preprocessing tasks.
* `post_model_hook`: A function that is called after the model is invoked. It can be used to implement guardrails, human-in-the-loop flows, or other postprocessing tasks.
* [`response_format`](../agents/agents.md#6-configure-structured-output): A data structure used to constrain the type of the final output, e.g., a `pydantic` `BaseModel`.
diff --git a/docs/docs/agents/tools.md b/docs/docs/agents/tools.md
deleted file mode 100644
index e9f45effb..000000000
--- a/docs/docs/agents/tools.md
+++ /dev/null
@@ -1,310 +0,0 @@
----
-search:
- boost: 2
-tags:
- - agent
-hide:
- - tags
----
-
-# Tools
-
-[Tools](https://python.langchain.com/docs/concepts/tools/) are a way to encapsulate a function and its input schema in a way that can be passed to a chat model that supports tool calling. This allows the model to request the execution of this function with specific inputs.
-
-You can either [define your own tools](#define-simple-tools) or use [prebuilt integrations](#prebuilt-tools) that LangChain provides.
-
-## Define simple tools
-
-You can pass a vanilla function to `create_react_agent` to use as a tool:
-
-```python
-from langgraph.prebuilt import create_react_agent
-
-def multiply(a: int, b: int) -> int:
- """Multiply two numbers."""
- return a * b
-
-create_react_agent(
- model="anthropic:claude-3-7-sonnet",
- tools=[multiply]
-)
-```
-
-`create_react_agent` automatically converts vanilla functions to [LangChain tools](https://python.langchain.com/docs/concepts/tools/#tool-interface).
-
-## Customize tools
-
-For more control over tool behavior, use the `@tool` decorator:
-
-```python
-# highlight-next-line
-from langchain_core.tools import tool
-
-# highlight-next-line
-@tool("multiply_tool", parse_docstring=True)
-def multiply(a: int, b: int) -> int:
- """Multiply two numbers.
-
- Args:
- a: First operand
- b: Second operand
- """
- return a * b
-```
-
-You can also define a custom input schema using Pydantic:
-
-```python
-from pydantic import BaseModel, Field
-
-class MultiplyInputSchema(BaseModel):
- """Multiply two numbers"""
- a: int = Field(description="First operand")
- b: int = Field(description="Second operand")
-
-# highlight-next-line
-@tool("multiply_tool", args_schema=MultiplyInputSchema)
-def multiply(a: int, b: int) -> int:
- return a * b
-```
-
-For additional customization, refer to the [custom tools guide](https://python.langchain.com/docs/how_to/custom_tools/).
-
-## Hide arguments from the model
-
-Some tools require runtime-only arguments (e.g., user ID or session context) that should not be controllable by the model.
-
-You can put these arguments in the `state` or `config` of the agent, and access
-this information inside the tool:
-
-```python
-from langgraph.prebuilt import InjectedState
-from langgraph.prebuilt.chat_agent_executor import AgentState
-from langchain_core.runnables import RunnableConfig
-
-def my_tool(
- # This will be populated by an LLM
- tool_arg: str,
- # access information that's dynamically updated inside the agent
- # highlight-next-line
- state: Annotated[AgentState, InjectedState],
- # access static data that is passed at agent invocation
- # highlight-next-line
- config: RunnableConfig,
-) -> str:
- """My tool."""
- do_something_with_state(state["messages"])
- do_something_with_config(config)
- ...
-```
-
-## Disable parallel tool calling
-
-Some model providers support executing multiple tools in parallel, but
-allow users to disable this feature.
-
-For supported providers, you can disable parallel tool calling by setting `parallel_tool_calls=False` via the `model.bind_tools()` method:
-
-```python
-from langchain.chat_models import init_chat_model
-
-def add(a: int, b: int) -> int:
- """Add two numbers"""
- return a + b
-
-def multiply(a: int, b: int) -> int:
- """Multiply two numbers."""
- return a * b
-
-model = init_chat_model("anthropic:claude-3-5-sonnet-latest", temperature=0)
-tools = [add, multiply]
-agent = create_react_agent(
- # disable parallel tool calls
- # highlight-next-line
- model=model.bind_tools(tools, parallel_tool_calls=False),
- tools=tools
-)
-
-agent.invoke(
- {"messages": [{"role": "user", "content": "what's 3 + 5 and 4 * 7?"}]}
-)
-```
-
-## Return tool results directly
-
-Use `return_direct=True` to return tool results immediately and stop the agent loop:
-
-```python
-from langchain_core.tools import tool
-
-# highlight-next-line
-@tool(return_direct=True)
-def add(a: int, b: int) -> int:
- """Add two numbers"""
- return a + b
-
-agent = create_react_agent(
- model="anthropic:claude-3-7-sonnet-latest",
- tools=[add]
-)
-
-agent.invoke(
- {"messages": [{"role": "user", "content": "what's 3 + 5?"}]}
-)
-```
-
-## Force tool use
-
-To force the agent to use specific tools, you can set the `tool_choice` option in `model.bind_tools()`:
-
-```python
-from langchain_core.tools import tool
-
-# highlight-next-line
-@tool(return_direct=True)
-def greet(user_name: str) -> int:
- """Greet user."""
- return f"Hello {user_name}!"
-
-tools = [greet]
-
-agent = create_react_agent(
- # highlight-next-line
- model=model.bind_tools(tools, tool_choice={"type": "tool", "name": "greet"}),
- tools=tools
-)
-
-agent.invoke(
- {"messages": [{"role": "user", "content": "Hi, I am Bob"}]}
-)
-```
-
-!!! Warning "Avoid infinite loops"
-
- Forcing tool usage without stopping conditions can create infinite loops. Use one of the following safeguards:
-
- - Mark the tool with [`return_direct=True`](#return-tool-results-directly) to end the loop after execution.
- - Set [`recursion_limit`](../concepts/low_level.md#recursion-limit) to restrict the number of execution steps.
-
-## Handle tool errors
-
-By default, the agent will catch all exceptions raised during tool calls and will pass those as tool messages to the LLM. To control how the errors are handled, you can use the prebuilt [`ToolNode`][langgraph.prebuilt.tool_node.ToolNode] — the node that executes tools inside `create_react_agent` — via its `handle_tool_errors` parameter:
-
-=== "Enable error handling (default)"
-
- ```python
- from langgraph.prebuilt import create_react_agent
-
- def multiply(a: int, b: int) -> int:
- """Multiply two numbers."""
- if a == 42:
- raise ValueError("The ultimate error")
- return a * b
-
- # Run with error handling (default)
- agent = create_react_agent(
- model="anthropic:claude-3-7-sonnet-latest",
- tools=[multiply]
- )
- agent.invoke(
- {"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
- )
- ```
-
-=== "Disable error handling"
-
- ```python
- from langgraph.prebuilt import create_react_agent, ToolNode
-
- def multiply(a: int, b: int) -> int:
- """Multiply two numbers."""
- if a == 42:
- raise ValueError("The ultimate error")
- return a * b
-
- # highlight-next-line
- tool_node = ToolNode(
- [multiply],
- # highlight-next-line
- handle_tool_errors=False # (1)!
- )
- agent_no_error_handling = create_react_agent(
- model="anthropic:claude-3-7-sonnet-latest",
- tools=tool_node
- )
- agent_no_error_handling.invoke(
- {"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
- )
- ```
-
- 1. This disables error handling (enabled by default). See all available strategies in the [API reference][langgraph.prebuilt.tool_node.ToolNode].
-
-=== "Custom error handling"
-
- ```python
- from langgraph.prebuilt import create_react_agent, ToolNode
-
- def multiply(a: int, b: int) -> int:
- """Multiply two numbers."""
- if a == 42:
- raise ValueError("The ultimate error")
- return a * b
-
- # highlight-next-line
- tool_node = ToolNode(
- [multiply],
- # highlight-next-line
- handle_tool_errors=(
- "Can't use 42 as a first operand, you must switch operands!" # (1)!
- )
- )
- agent_custom_error_handling = create_react_agent(
- model="anthropic:claude-3-7-sonnet-latest",
- tools=tool_node
- )
- agent_custom_error_handling.invoke(
- {"messages": [{"role": "user", "content": "what's 42 x 7?"}]}
- )
- ```
-
- 1. This provides a custom message to send to the LLM in case of an exception. See all available strategies in the [API reference][langgraph.prebuilt.tool_node.ToolNode].
-
-See [API reference][langgraph.prebuilt.tool_node.ToolNode] for more information on different tool error handling options.
-
-## Working with memory
-
-LangGraph allows access to short-term and long-term memory from tools. See [Memory](../how-tos/memory/add-memory.md) guide for more information on:
-
-* how to [read](../how-tos/memory/add-memory.md#read-short-term) from and [write](../how-tos/memory/add-memory.md#write-short-term) to **short-term** memory
-* how to [read](../how-tos/memory/add-memory.md#read-long-term) from and [write](../how-tos/memory/add-memory.md#write-long-term) to **long-term** memory
-
-## Prebuilt tools
-
-You can use prebuilt tools from model providers by passing a dictionary with tool specs to the `tools` parameter of `create_react_agent`. For example, to use the `web_search_preview` tool from OpenAI:
-
-```python
-from langgraph.prebuilt import create_react_agent
-
-agent = create_react_agent(
- model="openai:gpt-4o-mini",
- tools=[{"type": "web_search_preview"}]
-)
-response = agent.invoke(
- {"messages": ["What was a positive news story from today?"]}
-)
-```
-
-Additionally, LangChain supports a wide range of prebuilt tool integrations for interacting with APIs, databases, file systems, web data, and more. These tools extend the functionality of agents and enable rapid development.
-
-You can browse the full list of available integrations in the [LangChain integrations directory](https://python.langchain.com/docs/integrations/tools/).
-
-Some commonly used tool categories include:
-
-- **Search**: Bing, SerpAPI, Tavily
-- **Code interpreters**: Python REPL, Node.js REPL
-- **Databases**: SQL, MongoDB, Redis
-- **Web data**: Web scraping and browsing
-- **APIs**: OpenWeatherMap, NewsAPI, and others
-
-These integrations can be configured and added to your agents using the same `tools` parameter shown in the examples above.
-
diff --git a/docs/docs/agents/ui.md b/docs/docs/agents/ui.md
index 64b321f60..41735d652 100644
--- a/docs/docs/agents/ui.md
+++ b/docs/docs/agents/ui.md
@@ -13,7 +13,7 @@ You can use a prebuilt chat UI for interacting with any LangGraph agent through
## Run agent in UI
-First, set up LangGraph API server [locally](./deployment.md#launch-langgraph-server-locally) or deploy your agent on [LangGraph Platform](https://langchain-ai.github.io/langgraph/cloud/quick_start/).
+First, set up LangGraph API server [locally](../tutorials/langgraph-platform/local-server.md) or deploy your agent on [LangGraph Platform](https://langchain-ai.github.io/langgraph/cloud/quick_start/).
Then, navigate to [Agent Chat UI](https://agentchat.vercel.app), or clone the repository and [run the dev server locally](https://github.com/langchain-ai/agent-chat-ui?tab=readme-ov-file#setup):
@@ -25,7 +25,7 @@ Then, navigate to [Agent Chat UI](https://agentchat.vercel.app), or clone the re
## Add human-in-the-loop
-Agent Chat UI has full support for [human-in-the-loop](../concepts/human_in_the_loop.md) workflows. To try it out, replace the agent code in `src/agent/graph.py` (from the [deployment](./deployment.md) guide) with this [agent implementation](../how-tos/human_in_the_loop/add-human-in-the-loop.md#add-interrupts-to-any-tool):
+Agent Chat UI has full support for [human-in-the-loop](../concepts/human_in_the_loop.md) workflows. To try it out, replace the agent code in `src/agent/graph.py` (from the [deployment](../tutorials/langgraph-platform/local-server.md) guide) with this [agent implementation](../how-tos/human_in_the_loop/add-human-in-the-loop.md#add-interrupts-to-any-tool):
diff --git a/docs/docs/cloud/concepts/data_storage_and_privacy.md b/docs/docs/cloud/concepts/data_storage_and_privacy.md
new file mode 100644
index 000000000..c9ca1f59d
--- /dev/null
+++ b/docs/docs/cloud/concepts/data_storage_and_privacy.md
@@ -0,0 +1,54 @@
+# Data Storage and Privacy
+
+This document describes how data is processed in the LangGraph CLI and the LangGraph Server for both the in-memory server (`langgraph dev`) and the local Docker server (`langgraph up`). It also describes what data is tracked when interacting with the hosted LangGraph Studio frontend.
+
+## CLI
+
+LangGraph **CLI** is the command-line interface for building and running LangGraph applications; see the [CLI guide](../../concepts/langgraph_cli.md) to learn more.
+
+By default, calls to most CLI commands log a single analytics event upon invocation. This helps us better prioritize improvements to the CLI experience. Each telemetry event contains the calling process's OS, OS version, Python version, the CLI version, the command name (`dev`, `up`, `run`, etc.), and booleans representing whether a flag was passed to the command. You can see the full analytics logic [here](https://github.com/langchain-ai/langgraph/blob/main/libs/cli/langgraph_cli/analytics.py).
+
+You can disable all CLI telemetry by setting `LANGGRAPH_CLI_NO_ANALYTICS=1`.
+
+## LangGraph Server (in-memory & docker)
+
+The [LangGraph Server](../../concepts/langgraph_server.md) provides a durable execution runtime that relies on persisting checkpoints of your application state, long-term memories, thread metadata, assistants, and similar resources to the local file system or a database. Unless you have deliberately customized the storage location, this information is either written to local disk (for `langgraph dev`) or a PostgreSQL database (for `langgraph up` and in all deployments).
+
+### LangSmith Tracing
+
+When running the LangGraph server (either in-memory or in Docker), LangSmith tracing may be enabled to facilitate faster debugging and offer observability of graph state and LLM prompts in production. You can always disable tracing by setting `LANGSMITH_TRACING=false` in your server's runtime environment.
+
+### In-memory development server (`langgraph dev`)
+
+`langgraph dev` runs an [in-memory development server](../../tutorials/langgraph-platform/local-server.md) as a single Python process, designed for quick development and testing. It saves all checkpointing and memory data to disk within a `.langgraph_api` directory in the current working directory. Apart from the telemetry data described in the [CLI](#cli) section, no data leaves the machine unless you have enabled tracing or your graph code explicitly contacts an external service.
+
+### Standalone Container (`langgraph up`)
+
+`langgraph up` builds your local package into a Docker image and runs the server as a [standalone container](../../concepts/deployment_options.md#standalone-container) consisting of three containers: the API server, a PostgreSQL container, and a Redis container. All persistent data (checkpoints, assistants, etc.) are stored in the PostgreSQL database. Redis is used as a pubsub connection for real-time streaming of events. You can encrypt all checkpoints before saving to the database by setting a valid `LANGGRAPH_AES_KEY` environment variable. You can also specify [TTLs](../../how-tos/ttl/configure_ttl.md) for checkpoints and cross-thread memories in `langgraph.json` to control how long data is stored. All persisted threads, memories, and other data can be deleted via the relevant API endpoints.
+
+Additional API calls are made to confirm that the server has a valid license and to track the number of executed runs and tasks. Periodically, the API server validates the provided license key (or API key).
+
+If you've disabled [tracing](#langsmith-tracing), no user data is persisted externally unless your graph code explicitly contacts an external service.
+
+## Studio
+
+[LangGraph Studio](../../concepts/langgraph_studio.md) is a graphical interface for interacting with your LangGraph server. It does not persist any private data (the data you send to your server is not sent to LangSmith). Though the studio interface is served at [smith.langchain.com](https://smith.langchain.com), it is run in your browser and connects directly to your local LangGraph server so that no data needs to be sent to LangSmith.
+
+If you are logged in, LangSmith does collect some usage analytics to help improve studio's user experience. This includes:
+
+- Page visits and navigation patterns
+- User actions (button clicks)
+- Browser type and version
+- Screen resolution and viewport size
+
+Importantly, no application data or code (or other sensitive configuration details) are collected. All of that is stored in the persistence layer of your LangGraph server. When using Studio anonymously, no account creation is required and usage analytics are not collected.
+
+## Quick reference
+
+In summary, you can opt-out of server-side telemetry by turning off CLI analytics and disabling tracing.
+
+| Variable | Purpose | Default |
+| ------------------------------ | ------------------------- | -------------------------------- |
+| `LANGGRAPH_CLI_NO_ANALYTICS=1` | Disable CLI analytics | Analytics enabled |
+| `LANGSMITH_API_KEY` | Enable LangSmith tracing | Tracing disabled |
+| `LANGSMITH_TRACING=false` | Disable LangSmith tracing | Depends on environment |
diff --git a/docs/docs/cloud/concepts/threads.md b/docs/docs/cloud/concepts/threads.md
deleted file mode 100644
index ffd48faa8..000000000
--- a/docs/docs/cloud/concepts/threads.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Threads
-
-A thread contains the accumulated state of a sequence of [runs](../../concepts/assistants.md#execution). When a run is executed, the [state](../../concepts/low_level.md#state) of the underlying graph of the assistant will be persisted to the thread.
-
-A thread's current and historical state can be retrieved. To persist state, a thread must be created prior to executing a run.
-
-The state of a thread at a particular point in time is called a [checkpoint](../../concepts/persistence.md#checkpoints). Checkpoints are persisted and can be used to restore the state of a thread at a later time.
-
-## Learn more
-
-* For more on threads and checkpoints, see this section of the [LangGraph conceptual guide](../../concepts/persistence.md).
-* The LangGraph Platform API provides several endpoints for creating and managing threads and thread state. See the [API reference](../../cloud/reference/api/api_ref.html#tag/threads) for more details.
diff --git a/docs/docs/cloud/deployment/egress.md b/docs/docs/cloud/deployment/egress.md
new file mode 100644
index 000000000..40e149402
--- /dev/null
+++ b/docs/docs/cloud/deployment/egress.md
@@ -0,0 +1,119 @@
+# Egress for Subscription Metrics and Operational Metadata
+
+> **Important: Self Hosted Only**
+> This section only applies to customers who are not running in offline mode and assumes you are using a self-hosted LangGraph Platform instance.
+> This does not apply to SaaS or Hybrid deployments.
+
+Self-Hosted LangGraph Platform instances store all information locally and will never send sensitive information outside of your network. We currently only track platform usage for billing purposes according to the entitlements in your order. In order to better remotely support our customers, we do require egress to `https://beacon.langchain.com`.
+
+In the future, we will be introducing support diagnostics to help us ensure that the LangGraph Platform is running at an optimal level within your environment.
+
+> **Warning**
+> **This will require egress to `https://beacon.langchain.com` from your network.**
+> **If using an API key, you will also need to allow egress to `https://api.smith.langchain.com` or `https://eu.api.smith.langchain.com` for API key verification.**
+
+Generally, data that we send to Beacon can be categorized as follows:
+
+- **Subscription Metrics**
+ - Subscription metrics are used to determine level of access and utilization of LangSmith. This includes, but are not limited to:
+ - Nodes Executed
+ - Runs Executed
+ - License Key Verification
+- **Operational Metadata**
+ - This metadata will contain and collect the above subscription metrics to assist with remote support, allowing the LangChain team to diagnose and troubleshoot performance issues more effectively and proactively.
+
+## Example Payloads
+
+In an effort to maximize transparency, we provide sample payloads here:
+
+### License Verification (If using an Enterprise License)
+
+**Endpoint:**
+
+`POST beacon.langchain.com/v1/beacon/verify`
+
+**Request:**
+
+```json
+{
+ "license": ""
+}
+```
+
+**Response:**
+
+```json
+{
+ "token": "Valid JWT" // Short-lived JWT token to avoid repeated license checks
+}
+```
+
+### Api Key Verification (If using a LangSmith API Key)
+
+**Endpoint:**
+`POST api.smith.langchain.com/auth`
+
+**Request:**
+
+```json
+"Headers": {
+ X-Api-Key:
+}
+```
+
+**Response:**
+
+```json
+{
+ "org_config": {
+ "org_id": "3a1c2b6f-4430-4b92-8a5b-79b8b567bbc1",
+ ... // Additional organization details
+ }
+}
+```
+
+### Usage Reporting
+
+**Endpoint:**
+
+`POST beacon.langchain.com/v1/metadata/submit`
+
+**Request:**
+
+```json
+{
+ "license": "",
+ "from_timestamp": "2025-01-06T09:00:00Z",
+ "to_timestamp": "2025-01-06T10:00:00Z",
+ "tags": {
+ "langgraph.python.version": "0.1.0",
+ "langgraph_api.version": "0.2.0",
+ "langgraph.platform.revision": "abc123",
+ "langgraph.platform.variant": "standard",
+ "langgraph.platform.host": "host-1",
+ "langgraph.platform.tenant_id": "3a1c2b6f-4430-4b92-8a5b-79b8b567bbc1",
+ "langgraph.platform.project_id": "c5b5f53a-4716-4326-8967-d4f7f7799735",
+ "langgraph.platform.plan": "enterprise",
+ "user_app.uses_indexing": "true",
+ "user_app.uses_custom_app": "false",
+ "user_app.uses_custom_auth": "true",
+ "user_app.uses_thread_ttl": "true",
+ "user_app.uses_store_ttl": "false"
+ },
+ "measures": {
+ "langgraph.platform.runs": 150,
+ "langgraph.platform.nodes": 450
+ },
+ "logs": []
+}
+```
+
+**Response:**
+
+```json
+"204 No Content"
+```
+
+## Our Commitment
+
+LangChain will not store any sensitive information in the Subscription Metrics or Operational Metadata. Any data collected will not be shared with a third party. If you have any concerns about the data being sent, please reach out to your account team.
diff --git a/docs/docs/cloud/deployment/self_hosted_control_plane.md b/docs/docs/cloud/deployment/self_hosted_control_plane.md
index 0a8575080..14905ac79 100644
--- a/docs/docs/cloud/deployment/self_hosted_control_plane.md
+++ b/docs/docs/cloud/deployment/self_hosted_control_plane.md
@@ -23,6 +23,8 @@ Before deploying, review the [conceptual guide for the Self-Hosted Control Plane
kubectl get storageclass
+1. Egress to `https://beacon.langchain.com` from your network. This is required for license verification and usage reporting if not running in air-gapped mode. See the [Egress documentation](../../cloud/deployment/egress.md) for more details.
+
## Setup
1. As part of configuring your Self-Hosted LangSmith instance, you enable the `langgraphPlatform` option. This will provision a few key resources.
diff --git a/docs/docs/cloud/deployment/self_hosted_data_plane.md b/docs/docs/cloud/deployment/self_hosted_data_plane.md
index bcb07028c..f6d4dcf65 100644
--- a/docs/docs/cloud/deployment/self_hosted_data_plane.md
+++ b/docs/docs/cloud/deployment/self_hosted_data_plane.md
@@ -35,7 +35,6 @@ Before deploying, review the [conceptual guide for the Self-Hosted Data Plane](.
1. Configure your `langgraph-dataplane-values.yaml` file.
config:
- langgraphPlatformLicenseKey: "" # Your LangGraph Platform license key
langsmithApiKey: "" # API Key of your Workspace
langsmithWorkspaceId: "" # Workspace ID
hostBackendUrl: "https://api.host.langchain.com" # Only override this if on EU
diff --git a/docs/docs/cloud/deployment/standalone_container.md b/docs/docs/cloud/deployment/standalone_container.md
index 4e0015bbc..ac5fa1527 100644
--- a/docs/docs/cloud/deployment/standalone_container.md
+++ b/docs/docs/cloud/deployment/standalone_container.md
@@ -24,6 +24,7 @@ Before deploying, review the [conceptual guide for the Standalone Container](../
1. `LANGSMITH_API_KEY`: (if using [Lite](../../concepts/langgraph_server.md#server-versions)) LangSmith API key. This will be used to authenticate ONCE at server start up.
1. `LANGGRAPH_CLOUD_LICENSE_KEY`: (if using [Enterprise](../../concepts/langgraph_data_plane.md#licensing)) LangGraph Platform license key. This will be used to authenticate ONCE at server start up.
1. `LANGSMITH_ENDPOINT`: To send traces to a [self-hosted LangSmith](https://docs.smith.langchain.com/self_hosting) instance, set `LANGSMITH_ENDPOINT` to the hostname of the self-hosted LangSmith instance.
+1. Egress to `https://beacon.langchain.com` from your network. This is required for license verification and usage reporting if not running in air-gapped mode. See the [Egress documentation](../../cloud/deployment/egress.md) for more details.
## Kubernetes (Helm)
diff --git a/docs/docs/cloud/how-tos/add-human-in-the-loop.md b/docs/docs/cloud/how-tos/add-human-in-the-loop.md
index ecdd2004c..1df6c0c4e 100644
--- a/docs/docs/cloud/how-tos/add-human-in-the-loop.md
+++ b/docs/docs/cloud/how-tos/add-human-in-the-loop.md
@@ -2,7 +2,7 @@
To review, edit, and approve tool calls in an agent or workflow, use LangGraph's [human-in-the-loop](../../concepts/human_in_the_loop.md) features.
-## LangGraph API invoke & resume
+## Dynamic interrupts
=== "Python"
@@ -305,6 +305,185 @@ To review, edit, and approve tool calls in an agent or workflow, use LangGraph's
}"
```
+## Static interrupts
+
+Static interrupts (also known as static breakpoints) are triggered either before or after a node executes.
+
+!!! warning
+
+ Static interrupts are **not** recommended for human-in-the-loop workflows. They are best used for debugging and testing.
+
+You can set static interrupts by specifying `interrupt_before` and `interrupt_after` at compile time:
+
+```python
+# highlight-next-line
+graph = graph_builder.compile( # (1)!
+ # highlight-next-line
+ interrupt_before=["node_a"], # (2)!
+ # highlight-next-line
+ interrupt_after=["node_b", "node_c"], # (3)!
+)
+```
+
+1. The breakpoints are set during `compile` time.
+2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
+3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
+
+Alternatively, you can set static interrupts at run time:
+
+=== "Python"
+
+ ```python
+ # highlight-next-line
+ await client.runs.wait( # (1)!
+ thread_id,
+ assistant_id,
+ inputs=inputs,
+ # highlight-next-line
+ interrupt_before=["node_a"], # (2)!
+ # highlight-next-line
+ interrupt_after=["node_b", "node_c"] # (3)!
+ )
+ ```
+
+ 1. `client.runs.wait` is called with the `interrupt_before` and `interrupt_after` parameters. This is a run-time configuration and can be changed for every invocation.
+ 2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
+ 3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
+
+=== "JavaScript"
+
+ ```js
+ // highlight-next-line
+ await client.runs.wait( // (1)!
+ threadID,
+ assistantID,
+ {
+ input: input,
+ // highlight-next-line
+ interruptBefore: ["node_a"], // (2)!
+ // highlight-next-line
+ interruptAfter: ["node_b", "node_c"] // (3)!
+ }
+ )
+ ```
+
+ 1. `client.runs.wait` is called with the `interruptBefore` and `interruptAfter` parameters. This is a run-time configuration and can be changed for every invocation.
+ 2. `interruptBefore` specifies the nodes where execution should pause before the node is executed.
+ 3. `interruptAfter` specifies the nodes where execution should pause after the node is executed.
+
+=== "cURL"
+
+ ```bash
+ curl --request POST \
+ --url /threads//runs/wait \
+ --header 'Content-Type: application/json' \
+ --data "{
+ \"assistant_id\": \"agent\",
+ \"interrupt_before\": [\"node_a\"],
+ \"interrupt_after\": [\"node_b\", \"node_c\"],
+ \"input\":
+ }"
+ ```
+
+The following example shows how to add static interrupts:
+
+=== "Python"
+
+ ```python
+ from langgraph_sdk import get_client
+ client = get_client(url=)
+
+ # Using the graph deployed with the name "agent"
+ assistant_id = "agent"
+
+ # create a thread
+ thread = await client.threads.create()
+ thread_id = thread["thread_id"]
+
+ # Run the graph until the breakpoint
+ result = await client.runs.wait(
+ thread_id,
+ assistant_id,
+ input=inputs # (1)!
+ )
+
+ # Resume the graph
+ await client.runs.wait(
+ thread_id,
+ assistant_id,
+ input=None # (2)!
+ )
+ ```
+
+ 1. The graph is run until the first breakpoint is hit.
+ 2. The graph is resumed by passing in `None` for the input. This will run the graph until the next breakpoint is hit.
+
+=== "JavaScript"
+
+ ```js
+ import { Client } from "@langchain/langgraph-sdk";
+ const client = new Client({ apiUrl: });
+
+ // Using the graph deployed with the name "agent"
+ const assistantID = "agent";
+
+ // create a thread
+ const thread = await client.threads.create();
+ const threadID = thread["thread_id"];
+
+ // Run the graph until the breakpoint
+ const result = await client.runs.wait(
+ threadID,
+ assistantID,
+ { input: input } // (1)!
+ );
+
+ // Resume the graph
+ await client.runs.wait(
+ threadID,
+ assistantID,
+ { input: null } // (2)!
+ );
+ ```
+
+ 1. The graph is run until the first breakpoint is hit.
+ 2. The graph is resumed by passing in `null` for the input. This will run the graph until the next breakpoint is hit.
+
+=== "cURL"
+
+ Create a thread:
+
+ ```bash
+ curl --request POST \
+ --url /threads \
+ --header 'Content-Type: application/json' \
+ --data '{}'
+ ```
+
+ Run the graph until the breakpoint:
+
+ ```bash
+ curl --request POST \
+ --url /threads//runs/wait \
+ --header 'Content-Type: application/json' \
+ --data "{
+ \"assistant_id\": \"agent\",
+ \"input\":
+ }"
+ ```
+
+ Resume the graph:
+
+ ```bash
+ curl --request POST \
+ --url /threads//runs/wait \
+ --header 'Content-Type: application/json' \
+ --data "{
+ \"assistant_id\": \"agent\"
+ }"
+ ```
+
+
## Learn more
- [Human-in-the-loop conceptual guide](../../concepts/human_in_the_loop.md): learn more about LangGraph human-in-the-loop features.
diff --git a/docs/docs/cloud/how-tos/human_in_the_loop_breakpoint.md b/docs/docs/cloud/how-tos/human_in_the_loop_breakpoint.md
deleted file mode 100644
index f52c96954..000000000
--- a/docs/docs/cloud/how-tos/human_in_the_loop_breakpoint.md
+++ /dev/null
@@ -1,185 +0,0 @@
-# Set breakpoints using Server API
-
-[Breakpoints](../../concepts/breakpoints.md) pause graph execution at defined points and let you step through each stage. They use LangGraph's [**persistence layer**](../../concepts/persistence.md), which saves the graph state after each step.
-
-With breakpoints, you can inspect the graph's state and node inputs at any point. Execution pauses indefinitely until you resume, as the checkpointer preserves the state.
-
-!!! tip
-
- For conceptual information on breakpoints, see [Breakpoints](../../concepts/breakpoints.md).
-
-## Set 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"
-
- ```python
- # highlight-next-line
- graph = graph_builder.compile( # (1)!
- # highlight-next-line
- interrupt_before=["node_a"], # (2)!
- # highlight-next-line
- interrupt_after=["node_b", "node_c"], # (3)!
- )
- ```
-
- 1. The breakpoints are set during `compile` time.
- 2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
- 3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
-
-=== "Run time"
-
- === "Python"
-
- ```python
- # highlight-next-line
- await client.runs.wait( # (1)!
- thread_id,
- assistant_id,
- inputs=inputs,
- # highlight-next-line
- interrupt_before=["node_a"], # (2)!
- # highlight-next-line
- interrupt_after=["node_b", "node_c"] # (3)!
- )
- ```
-
- 1. `client.runs.wait` is called with the `interrupt_before` and `interrupt_after` parameters. This is a run-time configuration and can be changed for every invocation.
- 2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
- 3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
-
- === "JavaScript"
-
- ```js
- // highlight-next-line
- await client.runs.wait( // (1)!
- threadID,
- assistantID,
- {
- input: input,
- // highlight-next-line
- interruptBefore: ["node_a"], // (2)!
- // highlight-next-line
- interruptAfter: ["node_b", "node_c"] // (3)!
- }
- )
- ```
-
- 1. `client.runs.wait` is called with the `interruptBefore` and `interruptAfter` parameters. This is a run-time configuration and can be changed for every invocation.
- 2. `interruptBefore` specifies the nodes where execution should pause before the node is executed.
- 3. `interruptAfter` specifies the nodes where execution should pause after the node is executed.
-
- === "cURL"
-
- ```bash
- curl --request POST \
- --url /threads//runs/wait \
- --header 'Content-Type: application/json' \
- --data "{
- \"assistant_id\": \"agent\",
- \"interrupt_before\": [\"node_a\"],
- \"interrupt_after\": [\"node_b\", \"node_c\"],
- \"input\":
- }"
- ```
-
-## Example
-
-This example shows how to add **static** breakpoints. See [Use breakpoints](../../how-tos/human_in_the_loop/breakpoints.md) for more options on adding breakpoints.
-
-=== "Python"
-
- ```python
- from langgraph_sdk import get_client
- client = get_client(url=)
-
- # Using the graph deployed with the name "agent"
- assistant_id = "agent"
-
- # create a thread
- thread = await client.threads.create()
- thread_id = thread["thread_id"]
-
- # Run the graph until the breakpoint
- result = await client.runs.wait(
- thread_id,
- assistant_id,
- input=inputs # (1)!
- )
-
- # Resume the graph
- await client.runs.wait(
- thread_id,
- assistant_id,
- input=None # (2)!
- )
- ```
-
- 1. The graph is run until the first breakpoint is hit.
- 2. The graph is resumed by passing in `None` for the input. This will run the graph until the next breakpoint is hit.
-
-=== "JavaScript"
-
- ```js
- import { Client } from "@langchain/langgraph-sdk";
- const client = new Client({ apiUrl: });
-
- // Using the graph deployed with the name "agent"
- const assistantID = "agent";
-
- // create a thread
- const thread = await client.threads.create();
- const threadID = thread["thread_id"];
-
- // Run the graph until the breakpoint
- const result = await client.runs.wait(
- threadID,
- assistantID,
- { input: input } // (1)!
- );
-
- // Resume the graph
- await client.runs.wait(
- threadID,
- assistantID,
- { input: null } // (2)!
- );
- ```
-
- 1. The graph is run until the first breakpoint is hit.
- 2. The graph is resumed by passing in `null` for the input. This will run the graph until the next breakpoint is hit.
-
-=== "cURL"
-
- Create a thread:
-
- ```bash
- curl --request POST \
- --url /threads \
- --header 'Content-Type: application/json' \
- --data '{}'
- ```
-
- Run the graph until the breakpoint:
-
- ```bash
- curl --request POST \
- --url /threads//runs/wait \
- --header 'Content-Type: application/json' \
- --data "{
- \"assistant_id\": \"agent\",
- \"input\":
- }"
- ```
-
- Resume the graph:
-
- ```bash
- curl --request POST \
- --url /threads//runs/wait \
- --header 'Content-Type: application/json' \
- --data "{
- \"assistant_id\": \"agent\"
- }"
- ```
\ No newline at end of file
diff --git a/docs/docs/cloud/how-tos/invoke_studio.md b/docs/docs/cloud/how-tos/invoke_studio.md
index 0548373e1..d01b8eeb3 100644
--- a/docs/docs/cloud/how-tos/invoke_studio.md
+++ b/docs/docs/cloud/how-tos/invoke_studio.md
@@ -29,7 +29,7 @@ Click the dropdown next to "Submit" and click the toggle to enable/disable strea
To run your graph with breakpoints, click the "Interrupt" button. Select a node and whether to pause before and/or after that node has executed. Click "Continue" in the thread log to resume execution.
-For more information on breakpoints see [here](../../concepts/breakpoints.md).
+For more information on breakpoints see [here](../../concepts/human_in_the_loop.md).
### Submit run
diff --git a/docs/docs/cloud/how-tos/use_stream_react.md b/docs/docs/cloud/how-tos/use_stream_react.md
index 29703761e..3ddcbe5b4 100644
--- a/docs/docs/cloud/how-tos/use_stream_react.md
+++ b/docs/docs/cloud/how-tos/use_stream_react.md
@@ -1,4 +1,4 @@
-How to integrate LangGraph into your React application# How to integrate LangGraph into your React application
+# How to integrate LangGraph into your React application
!!! info "Prerequisites"
diff --git a/docs/docs/cloud/how-tos/webhooks.md b/docs/docs/cloud/how-tos/webhooks.md
index 59509c774..12e7a62b2 100644
--- a/docs/docs/cloud/how-tos/webhooks.md
+++ b/docs/docs/cloud/how-tos/webhooks.md
@@ -140,6 +140,22 @@ https://my-server.app/my-webhook-endpoint?token=YOUR_SECRET_TOKEN
Your server should extract and validate this token before processing requests.
+## Disable webhooks
+
+As of `langgraph-api>=0.2.78`, developers can disable webhooks in the `langgraph.json` file:
+
+```json
+{
+ "http": {
+ "disable_webhooks": true
+ }
+}
+```
+
+This feature is primarily intended for self-hosted deployments, where platform administrators or developers may prefer to disable webhooks to simplify their security posture—especially if they are not configuring firewall rules or other network controls. Disabling webhooks helps prevent untrusted payloads from being sent to internal endpoints.
+
+For full configuration details, refer to the [configuration file reference](https://langchain-ai.github.io/langgraph/cloud/reference/cli/?h=disable_webhooks#configuration-file).
+
## Test webhooks
You can test your webhook using online services like:
diff --git a/docs/docs/cloud/quick_start.md b/docs/docs/cloud/quick_start.md
index 2823b891d..41ad577e1 100644
--- a/docs/docs/cloud/quick_start.md
+++ b/docs/docs/cloud/quick_start.md
@@ -154,8 +154,9 @@ You can now test the API:
```bash
curl -s --request POST \
- --url \
+ --url /runs/stream \
--header 'Content-Type: application/json' \
+ --header "X-Api-Key: \
--data "{
\"assistant_id\": \"agent\",
\"input\": {
diff --git a/docs/docs/cloud/reference/api/api_ref.md b/docs/docs/cloud/reference/api/api_ref.md
index 13b30acf2..c2d6a10a7 100644
--- a/docs/docs/cloud/reference/api/api_ref.md
+++ b/docs/docs/cloud/reference/api/api_ref.md
@@ -1,12 +1,12 @@
-# API Reference
+# LangGraph Server API Reference
-The LangGraph Platform API reference is available with each deployment at the `/docs` URL path (e.g. `http://localhost:8124/docs`).
+The LangGraph Server API reference is available within each deployment at the `/docs` endpoint (e.g. `http://localhost:8124/docs`).
Click here to view the API reference.
## Authentication
-For deployments to LangGraph Platform, authentication is required. Pass the `X-Api-Key` header with each request to the LangGraph Platform API. The value of the header should be set to a valid LangSmith API key for the organization where the API is deployed.
+For deployments to LangGraph Platform, authentication is required. Pass the `X-Api-Key` header with each request to the LangGraph Server. The value of the header should be set to a valid LangSmith API key for the organization where the LangGraph Server is deployed.
Example `curl` command:
```shell
@@ -18,5 +18,5 @@ curl --request POST \
"metadata": {},
"limit": 10,
"offset": 0
-}'
+}'
```
diff --git a/docs/docs/cloud/reference/api/api_ref_control_plane.md b/docs/docs/cloud/reference/api/api_ref_control_plane.md
new file mode 100644
index 000000000..b6f3827ae
--- /dev/null
+++ b/docs/docs/cloud/reference/api/api_ref_control_plane.md
@@ -0,0 +1,247 @@
+# LangGraph Control Plane API Reference
+
+The LangGraph Control Plane API is used to programmatically create and manage LangGraph Server deployments. For example, the APIs can be orchestrated to create custom CI/CD workflows.
+
+Click here to view the API reference.
+
+## Host
+
+LangGraph Control Plane hosts for Cloud SaaS data regions:
+
+| US | EU |
+|----|----|
+| `https://api.host.langchain.com` | `https://eu.api.host.langchain.com` |
+
+**Note**: Self-hosted deployments of LangGraph Platform will have a custom host for the LangGraph Control Plane.
+
+## Authentication
+
+To authenticate with the LangGraph Control Plane API, set the `X-Api-Key` header to a valid LangSmith API key.
+
+Example `curl` command:
+```shell
+curl --request GET \
+ --url http://localhost:8124/v2/deployments \
+ --header 'X-Api-Key: LANGSMITH_API_KEY'
+```
+
+## Versioning
+
+Each endpoint path is prefixed with a version (e.g. `v1`, `v2`).
+
+## Quick Start
+
+1. Call `POST /v2/deployments` to create a new Deployment. The response body contains the Deployment ID (`id`) and the ID of the latest (and first) revision (`latest_revision_id`).
+1. Call `GET /v2/deployments/{deployment_id}` to retrieve the Deployment. Set `deployment_id` in the URL to the value of Deployment ID (`id`).
+1. Poll for revision `status` until `status` is `DEPLOYED` by calling `GET /v2/deployments/{deployment_id}/revisions/{latest_revision_id}`.
+1. Call `PATCH /v2/deployments/{deployment_id}` to update the deployment.
+
+## Example Code
+Below is example Python code that demonstrates how to orchestrate the LangGraph Control Plane APIs to create a deployment, update the deployment, and delete the deployment.
+```python
+import os
+import time
+
+import requests
+from dotenv import load_dotenv
+
+
+load_dotenv()
+
+# required environment variables
+CONTROL_PLANE_HOST = os.getenv("CONTROL_PLANE_HOST")
+LANGSMITH_API_KEY = os.getenv("LANGSMITH_API_KEY")
+INTEGRATION_ID = os.getenv("INTEGRATION_ID")
+MAX_WAIT_TIME = 1800 # 30 mins
+
+
+def get_headers() -> dict:
+ """Return common headers for requests to LangGraph Control Plane API."""
+ return {
+ "X-Api-Key": LANGSMITH_API_KEY,
+ }
+
+
+def create_deployment() -> str:
+ """Create deployment. Return deployment ID."""
+ headers = get_headers()
+ headers["Content-Type"] = "application/json"
+
+ deployment_name = "my_deployment"
+
+ request_body = {
+ "name": deployment_name,
+ "source": "github",
+ "source_config": {
+ "integration_id": INTEGRATION_ID,
+ "repo_url": "https://github.com/langchain-ai/langgraph-example",
+ "deployment_type": "dev",
+ "build_on_push": False,
+ "custom_url": None,
+ "resource_spec": None,
+ },
+ "source_revision_config": {
+ "repo_ref": "main",
+ "langgraph_config_path": "langgraph.json",
+ "image_uri": None,
+ },
+ "secrets": [
+ {
+ "name": "OPENAI_API_KEY",
+ "value": "test_openai_api_key",
+ },
+ {
+ "name": "ANTHROPIC_API_KEY",
+ "value": "test_anthropic_api_key",
+ },
+ {
+ "name": "TAVILY_API_KEY",
+ "value": "test_tavily_api_key",
+ },
+ ],
+ }
+
+ response = requests.post(
+ url=f"{CONTROL_PLANE_HOST}/v2/deployments",
+ headers=headers,
+ json=request_body,
+ )
+
+ if response.status_code != 201:
+ raise Exception(f"Failed to create deployment: {response.text}")
+
+ deployment_id = response.json()["id"]
+ print(f"Created deployment {deployment_name} ({deployment_id})")
+ return deployment_id
+
+
+def get_deployment(deployment_id: str) -> dict:
+ """Get deployment."""
+ response = requests.get(
+ url=f"{CONTROL_PLANE_HOST}/v2/deployments/{deployment_id}",
+ headers=get_headers(),
+ )
+
+ if response.status_code != 200:
+ raise Exception(f"Failed to get deployment ID {deployment_id}: {response.text}")
+
+ return response.json()
+
+
+def list_revisions(deployment_id: str) -> list[dict]:
+ """List revisions.
+
+ Return list is sorted by created_at in descending order (latest first).
+ """
+ response = requests.get(
+ url=f"{CONTROL_PLANE_HOST}/v2/deployments/{deployment_id}/revisions",
+ headers=get_headers(),
+ )
+
+ if response.status_code != 200:
+ raise Exception(
+ f"Failed to list revisions for deployment ID {deployment_id}: {response.text}"
+ )
+
+ return response.json()
+
+
+def get_revision(
+ deployment_id: str,
+ revision_id: str,
+) -> dict:
+ """Get revision."""
+ response = requests.get(
+ url=f"{CONTROL_PLANE_HOST}/v2/deployments/{deployment_id}/revisions/{revision_id}",
+ headers=get_headers(),
+ )
+
+ if response.status_code != 200:
+ raise Exception(f"Failed to get revision ID {revision_id}: {response.text}")
+
+ return response.json()
+
+
+def patch_deployment(deployment_id: str) -> None:
+ """Patch deployment."""
+ headers = get_headers()
+ headers["Content-Type"] = "application/json"
+
+ response = requests.patch(
+ url=f"{CONTROL_PLANE_HOST}/v2/deployments/{deployment_id}",
+ headers=headers,
+ json={
+ "source_config": {
+ "build_on_push": True,
+ },
+ "source_revision_config": {
+ "repo_ref": "main",
+ "langgraph_config_path": "langgraph.json",
+ },
+ },
+ )
+
+ if response.status_code != 200:
+ raise Exception(f"Failed to patch deployment: {response.text}")
+
+ print(f"Patched deployment ID {deployment_id}")
+
+
+def wait_for_deployment(deployment_id: str, revision_id: str) -> None:
+ """Wait for revision status to be DEPLOYED."""
+ start_time = time.time()
+ revision, status = None, None
+ while time.time() - start_time < MAX_WAIT_TIME:
+ revision = get_revision(deployment_id, revision_id)
+ status = revision["status"]
+ if status == "DEPLOYED":
+ break
+ elif "FAILED" in status:
+ raise Exception(f"Revision ID {revision_id} failed: {revision}")
+
+ print(f"Waiting for revision ID {revision_id} to be DEPLOYED...")
+ time.sleep(60)
+
+ if status != "DEPLOYED":
+ raise Exception(
+ f"Timeout waiting for revision ID {revision_id} to be DEPLOYED: {revision}"
+ )
+
+
+def delete_deployment(deployment_id: str) -> None:
+ """Delete deployment."""
+ response = requests.delete(
+ url=f"{CONTROL_PLANE_HOST}/v2/deployments/{deployment_id}",
+ headers=get_headers(),
+ )
+
+ if response.status_code != 204:
+ raise Exception(
+ f"Failed to delete deployment ID {deployment_id}: {response.text}"
+ )
+
+ print(f"Deployment ID {deployment_id} deleted")
+
+
+if __name__ == "__main__":
+ # create deployment and get the latest revision
+ deployment_id = create_deployment()
+ revisions = list_revisions(deployment_id)
+ latest_revision = revisions["resources"][0]
+ latest_revision_id = latest_revision["id"]
+
+ # wait for latest revision to be DEPLOYED
+ wait_for_deployment(deployment_id, latest_revision_id)
+
+ # patch the deployment and get the latest revision
+ patch_deployment(deployment_id)
+ revisions = list_revisions(deployment_id)
+ latest_revision = revisions["resources"][0]
+ latest_revision_id = latest_revision["id"]
+
+ # wait for latest revision to be DEPLOYED
+ wait_for_deployment(deployment_id, latest_revision_id)
+
+ # delete the deployment
+ delete_deployment(deployment_id)
+```
\ No newline at end of file
diff --git a/docs/docs/cloud/reference/api/openapi.json b/docs/docs/cloud/reference/api/openapi.json
index 782619368..8a3b7f5fc 100644
--- a/docs/docs/cloud/reference/api/openapi.json
+++ b/docs/docs/cloud/reference/api/openapi.json
@@ -1,6 +1,9 @@
{
"openapi": "3.1.0",
- "info": { "title": "LangGraph Platform", "version": "0.1.0" },
+ "info": {
+ "title": "LangGraph Platform",
+ "version": "0.1.0"
+ },
"tags": [
{
"name": "Assistants",
@@ -30,14 +33,18 @@
"paths": {
"/assistants": {
"post": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Create Assistant",
"description": "Create an assistant.\n\nAn initial version of the assistant will be created and the assistant is set to that version. To change versions, use the `POST /assistants/{assistant_id}/latest` endpoint.",
"operationId": "create_assistant_assistants_post",
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/AssistantCreate" }
+ "schema": {
+ "$ref": "#/components/schemas/AssistantCreate"
+ }
}
},
"required": true
@@ -47,7 +54,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Assistant" }
+ "schema": {
+ "$ref": "#/components/schemas/Assistant"
+ }
}
}
},
@@ -55,7 +64,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -63,7 +74,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -71,7 +84,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -80,7 +95,9 @@
},
"/assistants/search": {
"post": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Search Assistants",
"description": "Search for assistants.\n\nThis endpoint also functions as the endpoint to list all assistants.",
"operationId": "search_assistants_assistants_search_post",
@@ -100,7 +117,9 @@
"content": {
"application/json": {
"schema": {
- "items": { "$ref": "#/components/schemas/Assistant" },
+ "items": {
+ "$ref": "#/components/schemas/Assistant"
+ },
"type": "array",
"title": "Response Search Assistants Assistants Search Post"
}
@@ -111,7 +130,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -119,7 +140,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -128,7 +151,9 @@
},
"/assistants/{assistant_id}": {
"get": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Get Assistant",
"description": "Get an assistant by ID.",
"operationId": "get_assistant_assistants__assistant_id__get",
@@ -151,7 +176,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Assistant" }
+ "schema": {
+ "$ref": "#/components/schemas/Assistant"
+ }
}
}
},
@@ -159,14 +186,18 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"delete": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Delete Assistant",
"description": "Delete an assistant by ID.\n\nAll versions of the assistant will be deleted as well.",
"operationId": "delete_assistant_assistants__assistant_id__delete",
@@ -187,13 +218,19 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -201,14 +238,18 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"patch": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Patch Assistant",
"description": "Update an assistant.",
"operationId": "patch_assistant_assistants__assistant_id__patch",
@@ -229,7 +270,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/AssistantPatch" }
+ "schema": {
+ "$ref": "#/components/schemas/AssistantPatch"
+ }
}
},
"required": true
@@ -239,7 +282,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Assistant" }
+ "schema": {
+ "$ref": "#/components/schemas/Assistant"
+ }
}
}
},
@@ -247,7 +292,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -255,7 +302,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -264,7 +313,9 @@
},
"/assistants/{assistant_id}/graph": {
"get": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Get Assistant Graph",
"description": "Get an assistant by ID.",
"operationId": "get_assistant_graph_assistants__assistant_id__graph_get",
@@ -294,7 +345,14 @@
"description": "Include graph representation of subgraphs. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included.",
"required": false,
"schema": {
- "oneOf": [{ "type": "boolean" }, { "type": "integer" }],
+ "oneOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "integer"
+ }
+ ],
"title": "Xray",
"default": false,
"description": "Include graph representation of subgraphs. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included."
@@ -310,7 +368,9 @@
"application/json": {
"schema": {
"additionalProperties": {
- "items": { "type": "object" },
+ "items": {
+ "type": "object"
+ },
"type": "array"
},
"type": "object",
@@ -323,7 +383,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -331,7 +393,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -340,7 +404,9 @@
},
"/assistants/{assistant_id}/subgraphs": {
"get": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Get Assistant Subgraphs",
"description": "Get an assistant's subgraphs.",
"operationId": "get_assistant_subgraphs_assistants__assistant_id__subgraphs_get",
@@ -373,7 +439,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Subgraphs" }
+ "schema": {
+ "$ref": "#/components/schemas/Subgraphs"
+ }
}
}
},
@@ -381,7 +449,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -389,7 +459,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -398,7 +470,9 @@
},
"/assistants/{assistant_id}/subgraphs/{namespace}": {
"get": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Get Assistant Subgraphs by Namespace",
"description": "Get an assistant's subgraphs filtered by namespace.",
"operationId": "get_assistant_subgraphs_assistants__assistant_id__subgraphs__namespace__get",
@@ -417,7 +491,10 @@
{
"description": "Namespace of the subgraph to filter by.",
"required": true,
- "schema": { "type": "string", "title": "Namespace" },
+ "schema": {
+ "type": "string",
+ "title": "Namespace"
+ },
"name": "namespace",
"in": "path"
},
@@ -438,7 +515,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Subgraphs" }
+ "schema": {
+ "$ref": "#/components/schemas/Subgraphs"
+ }
}
}
},
@@ -446,7 +525,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -455,7 +536,9 @@
},
"/assistants/{assistant_id}/schemas": {
"get": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Get Assistant Schemas",
"description": "Get an assistant by ID.",
"operationId": "get_assistant_schemas_assistants__assistant_id__schemas_get",
@@ -478,7 +561,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/GraphSchema" }
+ "schema": {
+ "$ref": "#/components/schemas/GraphSchema"
+ }
}
}
},
@@ -486,7 +571,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -494,7 +581,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -503,7 +592,9 @@
},
"/assistants/{assistant_id}/versions": {
"post": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Get Assistant Versions",
"description": "Get all versions of an assistant.",
"operationId": "get_assistant_versions_assistants__assistant_id__versions_get",
@@ -527,7 +618,9 @@
"content": {
"application/json": {
"schema": {
- "items": { "$ref": "#/components/schemas/Assistant" },
+ "items": {
+ "$ref": "#/components/schemas/Assistant"
+ },
"type": "array",
"title": "Response Search Assistants Assistants Search Post"
}
@@ -538,7 +631,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -547,7 +642,9 @@
},
"/assistants/{assistant_id}/latest": {
"post": {
- "tags": ["Assistants"],
+ "tags": [
+ "Assistants"
+ ],
"summary": "Set Latest Assistant Version",
"description": "Set the latest version for an assistant.",
"operationId": "set_latest_assistant_version_assistants__assistant_id__versions_post",
@@ -581,7 +678,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Assistant" }
+ "schema": {
+ "$ref": "#/components/schemas/Assistant"
+ }
}
}
},
@@ -589,7 +688,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -597,7 +698,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -606,14 +709,18 @@
},
"/threads": {
"post": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Create Thread",
"description": "Create a thread.",
"operationId": "create_thread_threads_post",
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ThreadCreate" }
+ "schema": {
+ "$ref": "#/components/schemas/ThreadCreate"
+ }
}
},
"required": true
@@ -623,7 +730,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Thread" }
+ "schema": {
+ "$ref": "#/components/schemas/Thread"
+ }
}
}
},
@@ -631,7 +740,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -639,7 +750,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -648,7 +761,9 @@
},
"/threads/search": {
"post": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Search Threads",
"description": "Search for threads.\n\nThis endpoint also functions as the endpoint to list all threads.",
"operationId": "search_threads_threads_search_post",
@@ -668,7 +783,9 @@
"content": {
"application/json": {
"schema": {
- "items": { "$ref": "#/components/schemas/Thread" },
+ "items": {
+ "$ref": "#/components/schemas/Thread"
+ },
"type": "array",
"title": "Response Search Threads Threads Search Post"
}
@@ -679,7 +796,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -688,7 +807,9 @@
},
"/threads/{thread_id}/state": {
"get": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Get Thread State",
"description": "Get state for a thread.\n\nThe latest state of the thread (i.e. latest checkpoint) is returned.",
"operationId": "get_latest_thread_state_threads__thread_id__state_get",
@@ -722,7 +843,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ThreadState" }
+ "schema": {
+ "$ref": "#/components/schemas/ThreadState"
+ }
}
}
},
@@ -730,14 +853,18 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"post": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Update Thread State",
"description": "Add state to a thread.",
"operationId": "update_thread_state_threads__thread_id__state_post",
@@ -758,7 +885,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ThreadStateUpdate" }
+ "schema": {
+ "$ref": "#/components/schemas/ThreadStateUpdate"
+ }
}
},
"required": true
@@ -778,7 +907,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -787,7 +918,9 @@
},
"/threads/{thread_id}/state/{checkpoint_id}": {
"get": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Get Thread State At Checkpoint",
"description": "Get state for a thread at a specific checkpoint.",
"operationId": "get_thread_state_at_checkpoint_threads__thread_id__state__checkpoint_id__get",
@@ -833,7 +966,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ThreadState" }
+ "schema": {
+ "$ref": "#/components/schemas/ThreadState"
+ }
}
}
},
@@ -841,7 +976,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -850,7 +987,9 @@
},
"/threads/{thread_id}/state/checkpoint": {
"post": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Get Thread State At Checkpoint",
"description": "Get state for a thread at a specific checkpoint.",
"operationId": "post_thread_state_at_checkpoint_threads__thread_id__state__checkpoint_id__get",
@@ -893,7 +1032,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ThreadState" }
+ "schema": {
+ "$ref": "#/components/schemas/ThreadState"
+ }
}
}
},
@@ -901,7 +1042,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -910,7 +1053,9 @@
},
"/threads/{thread_id}/history": {
"get": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Get Thread History",
"description": "Get all past states for a thread.",
"operationId": "get_thread_history_threads__thread_id__history_get",
@@ -929,13 +1074,20 @@
},
{
"required": false,
- "schema": { "type": "integer", "title": "Limit", "default": 10 },
+ "schema": {
+ "type": "integer",
+ "title": "Limit",
+ "default": 10
+ },
"name": "limit",
"in": "query"
},
{
"required": false,
- "schema": { "type": "string", "title": "Before" },
+ "schema": {
+ "type": "string",
+ "title": "Before"
+ },
"name": "before",
"in": "query"
}
@@ -959,14 +1111,18 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"post": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Get Thread History Post",
"description": "Get all past states for a thread.",
"operationId": "get_thread_history_post_threads__thread_id__history_post",
@@ -987,7 +1143,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ThreadStateSearch" }
+ "schema": {
+ "$ref": "#/components/schemas/ThreadStateSearch"
+ }
}
},
"required": true
@@ -1011,7 +1169,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1020,7 +1180,9 @@
},
"/threads/{thread_id}/copy": {
"post": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Copy Thread",
"description": "Create a new thread with a copy of the state and checkpoints from an existing thread.",
"operationId": "copy_thread_post_threads__thread_id__copy_post",
@@ -1043,7 +1205,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Thread" }
+ "schema": {
+ "$ref": "#/components/schemas/Thread"
+ }
}
}
},
@@ -1051,7 +1215,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1059,7 +1225,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1068,7 +1236,9 @@
},
"/threads/{thread_id}": {
"get": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Get Thread",
"description": "Get a thread by ID.",
"operationId": "get_thread_threads__thread_id__get",
@@ -1091,7 +1261,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Thread" }
+ "schema": {
+ "$ref": "#/components/schemas/Thread"
+ }
}
}
},
@@ -1099,7 +1271,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1107,14 +1281,18 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"delete": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Delete Thread",
"description": "Delete a thread by ID.",
"operationId": "delete_thread_threads__thread_id__delete",
@@ -1135,13 +1313,19 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1149,14 +1333,18 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"patch": {
- "tags": ["Threads"],
+ "tags": [
+ "Threads"
+ ],
"summary": "Patch Thread",
"description": "Update a thread.",
"operationId": "patch_thread_threads__thread_id__patch",
@@ -1177,7 +1365,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ThreadPatch" }
+ "schema": {
+ "$ref": "#/components/schemas/ThreadPatch"
+ }
}
},
"required": true
@@ -1187,7 +1377,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Thread" }
+ "schema": {
+ "$ref": "#/components/schemas/Thread"
+ }
}
}
},
@@ -1195,7 +1387,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1203,7 +1397,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1212,7 +1408,9 @@
},
"/threads/{thread_id}/runs": {
"get": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "List Runs",
"description": "List runs for a thread.",
"operationId": "list_runs_http_threads__thread_id__runs_get",
@@ -1231,13 +1429,21 @@
},
{
"required": false,
- "schema": { "type": "integer", "title": "Limit", "default": 10 },
+ "schema": {
+ "type": "integer",
+ "title": "Limit",
+ "default": 10
+ },
"name": "limit",
"in": "query"
},
{
"required": false,
- "schema": { "type": "integer", "title": "Offset", "default": 0 },
+ "schema": {
+ "type": "integer",
+ "title": "Offset",
+ "default": 0
+ },
"name": "offset",
"in": "query"
},
@@ -1245,7 +1451,13 @@
"required": false,
"schema": {
"type": "string",
- "enum": ["pending", "error", "success", "timeout", "interrupted"]
+ "enum": [
+ "pending",
+ "error",
+ "success",
+ "timeout",
+ "interrupted"
+ ]
},
"name": "status",
"in": "query"
@@ -1257,7 +1469,9 @@
"content": {
"application/json": {
"schema": {
- "items": { "$ref": "#/components/schemas/Run" },
+ "items": {
+ "$ref": "#/components/schemas/Run"
+ },
"type": "array"
}
}
@@ -1267,7 +1481,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1275,14 +1491,18 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"post": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Create Background Run",
"description": "Create a run in existing thread, return the run ID immediately. Don't wait for the final run output.",
"operationId": "create_run_threads__thread_id__runs_post",
@@ -1303,7 +1523,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/RunCreateStateful" }
+ "schema": {
+ "$ref": "#/components/schemas/RunCreateStateful"
+ }
}
},
"required": true
@@ -1313,7 +1535,17 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Run" }
+ "schema": {
+ "$ref": "#/components/schemas/Run"
+ }
+ }
+ },
+ "headers": {
+ "Content-Location": {
+ "description": "The URL of the run that was created. Can be used to later join the stream.",
+ "schema": {
+ "type": "string"
+ }
}
}
},
@@ -1321,7 +1553,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1329,7 +1563,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1337,7 +1573,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1346,7 +1584,9 @@
},
"/threads/{thread_id}/runs/crons": {
"post": {
- "tags": ["Crons (Plus tier)"],
+ "tags": [
+ "Crons (Plus tier)"
+ ],
"summary": "Create Thread Cron",
"description": "Create a cron to schedule runs on a thread.",
"operationId": "create_thread_cron_threads__thread_id__runs_crons_post",
@@ -1367,7 +1607,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/CronCreate" }
+ "schema": {
+ "$ref": "#/components/schemas/CronCreate"
+ }
}
},
"required": true
@@ -1377,7 +1619,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Cron" }
+ "schema": {
+ "$ref": "#/components/schemas/Cron"
+ }
}
}
},
@@ -1385,7 +1629,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1393,7 +1639,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1402,7 +1650,9 @@
},
"/threads/{thread_id}/runs/stream": {
"post": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Create Run, Stream Output",
"description": "Create a run in existing thread. Stream the output.",
"operationId": "stream_run_threads__thread_id__runs_stream_post",
@@ -1423,7 +1673,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/RunCreateStateful" }
+ "schema": {
+ "$ref": "#/components/schemas/RunCreateStateful"
+ }
}
},
"required": true
@@ -1438,13 +1690,23 @@
"description": "The server will send a stream of events in SSE format.\n\n**Example event**:\n\nid: 1\n\nevent: message\n\ndata: {}"
}
}
+ },
+ "headers": {
+ "Content-Location": {
+ "description": "The URL of the run that was created. Can be used to later join the stream.",
+ "schema": {
+ "type": "string"
+ }
+ }
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1452,7 +1714,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1460,7 +1724,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1469,7 +1735,9 @@
},
"/threads/{thread_id}/runs/wait": {
"post": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Create Run, Wait for Output",
"description": "Create a run in existing thread. Wait for the final output and then return it.",
"operationId": "wait_run_threads__thread_id__runs_wait_post",
@@ -1490,7 +1758,9 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/RunCreateStateful" }
+ "schema": {
+ "$ref": "#/components/schemas/RunCreateStateful"
+ }
}
},
"required": true
@@ -1498,13 +1768,27 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ },
+ "headers": {
+ "Content-Location": {
+ "description": "The URL of the run that was created. Can be used to later join the stream.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1512,7 +1796,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1520,7 +1806,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1529,7 +1817,9 @@
},
"/threads/{thread_id}/runs/{run_id}": {
"get": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Get Run",
"description": "Get a run by ID.",
"operationId": "get_run_http_threads__thread_id__runs__run_id__get",
@@ -1564,7 +1854,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Run" }
+ "schema": {
+ "$ref": "#/components/schemas/Run"
+ }
}
}
},
@@ -1572,7 +1864,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1580,14 +1874,18 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"delete": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Delete Run",
"description": "Delete a run by ID.",
"operationId": "delete_run_threads__thread_id__runs__run_id__delete",
@@ -1620,13 +1918,19 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1634,7 +1938,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1643,7 +1949,9 @@
},
"/threads/{thread_id}/runs/{run_id}/join": {
"get": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Join Run",
"description": "Wait for a run to finish.",
"operationId": "join_run_http_threads__thread_id__runs__run_id__join_get",
@@ -1687,13 +1995,19 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1701,7 +2015,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1710,9 +2026,11 @@
},
"/threads/{thread_id}/runs/{run_id}/stream": {
"get": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Join Run Stream",
- "description": "Join a run stream. This endpoint streams output in real-time from a run similar to the /threads/__THREAD_ID__/runs/stream endpoint. Only output produced after this endpoint is called will be streamed.",
+ "description": "Join a run stream. This endpoint streams output in real-time from a run similar to the /threads/__THREAD_ID__/runs/stream endpoint. If the run has been created with `stream_resumable=true`, the stream can be resumed from the last seen event ID.",
"operationId": "stream_run_http_threads__thread_id__runs__run_id__join_get",
"parameters": [
{
@@ -1738,6 +2056,37 @@
},
"name": "run_id",
"in": "path"
+ },
+ {
+ "required": false,
+ "schema": {
+ "type": "string",
+ "title": "Last Event ID",
+ "description": "The ID of the last event received. Set to -1 if you want to stream all events. Requires `stream_resumable=true` to be set when creating the run."
+ },
+ "name": "Last-Event-ID",
+ "in": "header"
+ },
+ {
+ "required": false,
+ "schema": {
+ "type": "string",
+ "title": "Stream Mode",
+ "description": "The mode to stream the run in. If not provided, the default mode will be used."
+ },
+ "name": "stream_mode",
+ "in": "query"
+ },
+ {
+ "required": false,
+ "schema": {
+ "type": "boolean",
+ "title": "Cancel On Disconnect",
+ "description": "If true, the run will be cancelled if the client disconnects.",
+ "default": false
+ },
+ "name": "cancel_on_disconnect",
+ "in": "query"
}
],
"responses": {
@@ -1756,7 +2105,9 @@
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1764,7 +2115,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1773,7 +2126,9 @@
},
"/threads/{thread_id}/runs/{run_id}/cancel": {
"post": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Cancel Run",
"operationId": "cancel_run_http_threads__thread_id__runs__run_id__cancel_post",
"parameters": [
@@ -1816,7 +2171,10 @@
"required": false,
"schema": {
"type": "string",
- "enum": ["interrupt", "rollback"],
+ "enum": [
+ "interrupt",
+ "rollback"
+ ],
"title": "Action",
"default": "interrupt"
},
@@ -1827,13 +2185,19 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1841,7 +2205,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1850,58 +2216,20 @@
},
"/runs/crons": {
"post": {
- "tags": ["Crons (Plus tier)"],
+ "tags": [
+ "Crons (Plus tier)"
+ ],
"summary": "Create Cron",
"description": "Create a cron to schedule runs on new threads.",
"operationId": "create_cron_runs_crons_post",
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/CronCreate" }
- }
- },
- "required": true
- },
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": { "$ref": "#/components/schemas/Cron" }
+ "schema": {
+ "$ref": "#/components/schemas/CronCreate"
}
}
},
- "404": {
- "description": "Not Found",
- "content": {
- "application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
- }
- }
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
- }
- }
- }
- }
- }
- },
- "/runs/crons/search": {
- "post": {
- "tags": ["Crons (Plus tier)"],
- "summary": "Search Crons",
- "description": "Search all active crons",
- "operationId": "search_crons_runs_crons_post",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": { "$ref": "#/components/schemas/CronSearch" }
- }
- },
"required": true
},
"responses": {
@@ -1910,7 +2238,61 @@
"content": {
"application/json": {
"schema": {
- "items": { "$ref": "#/components/schemas/Cron" },
+ "$ref": "#/components/schemas/Cron"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not Found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/runs/crons/search": {
+ "post": {
+ "tags": [
+ "Crons (Plus tier)"
+ ],
+ "summary": "Search Crons",
+ "description": "Search all active crons",
+ "operationId": "search_crons_runs_crons_post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CronSearch"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "items": {
+ "$ref": "#/components/schemas/Cron"
+ },
"type": "array",
"title": "Response Search Crons Search Post"
}
@@ -1921,7 +2303,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1930,7 +2314,9 @@
},
"/runs/stream": {
"post": {
- "tags": ["Stateless Runs"],
+ "tags": [
+ "Stateless Runs"
+ ],
"summary": "Create Run, Stream Output",
"description": "Create a run in a new thread, stream the output.",
"operationId": "stream_run_stateless_runs_stream_post",
@@ -1954,13 +2340,23 @@
"description": "The server will send a stream of events in SSE format.\n\n**Example event**:\n\nid: 1\n\nevent: message\n\ndata: {}"
}
}
+ },
+ "headers": {
+ "Content-Location": {
+ "description": "The URL of the run that was created. Can be used to later join the stream.",
+ "schema": {
+ "type": "string"
+ }
+ }
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1968,7 +2364,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -1976,7 +2374,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -1985,7 +2385,9 @@
},
"/runs/cancel": {
"post": {
- "tags": ["Thread Runs"],
+ "tags": [
+ "Thread Runs"
+ ],
"summary": "Cancel Runs",
"description": "Cancel one or more runs. Can cancel runs by thread ID and run IDs, or by status filter.",
"operationId": "cancel_runs_post",
@@ -1995,7 +2397,10 @@
"required": false,
"schema": {
"type": "string",
- "enum": ["interrupt", "rollback"],
+ "enum": [
+ "interrupt",
+ "rollback"
+ ],
"title": "Action",
"default": "interrupt"
},
@@ -2006,18 +2411,24 @@
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/RunsCancel" }
+ "schema": {
+ "$ref": "#/components/schemas/RunsCancel"
+ }
}
},
"required": true
},
"responses": {
- "204": { "description": "Success - Runs cancelled" },
+ "204": {
+ "description": "Success - Runs cancelled"
+ },
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2025,7 +2436,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2034,7 +2447,9 @@
},
"/runs/wait": {
"post": {
- "tags": ["Stateless Runs"],
+ "tags": [
+ "Stateless Runs"
+ ],
"summary": "Create Run, Wait for Output",
"description": "Create a run in a new thread. Wait for the final output and then return it.",
"operationId": "wait_run_stateless_runs_wait_post",
@@ -2051,13 +2466,27 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ },
+ "headers": {
+ "Content-Location": {
+ "description": "The URL of the run that was created. Can be used to later join the stream.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2065,7 +2494,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2073,7 +2504,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2082,7 +2515,9 @@
},
"/runs": {
"post": {
- "tags": ["Stateless Runs"],
+ "tags": [
+ "Stateless Runs"
+ ],
"summary": "Create Background Run",
"description": "Create a run in a new thread, return the run ID immediately. Don't wait for the final run output.",
"operationId": "run_stateless_runs_post",
@@ -2099,13 +2534,27 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ },
+ "headers": {
+ "Content-Location": {
+ "description": "The URL of the run that was created. Can be used to later join the stream.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2113,7 +2562,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2121,7 +2572,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2130,14 +2583,18 @@
},
"/runs/batch": {
"post": {
- "tags": ["Stateless Runs"],
+ "tags": [
+ "Stateless Runs"
+ ],
"summary": "Create Run Batch",
"description": "Create a batch of runs in new threads, return immediately.",
"operationId": "run_batch_stateless_runs_post",
"requestBody": {
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/RunBatchCreate" }
+ "schema": {
+ "$ref": "#/components/schemas/RunBatchCreate"
+ }
}
},
"required": true
@@ -2145,13 +2602,19 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2159,7 +2622,9 @@
"description": "Conflict",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2167,7 +2632,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2176,7 +2643,9 @@
},
"/runs/crons/{cron_id}": {
"delete": {
- "tags": ["Crons (Plus tier)"],
+ "tags": [
+ "Crons (Plus tier)"
+ ],
"summary": "Delete Cron",
"description": "Delete a cron by ID.",
"operationId": "delete_cron_runs_crons__cron_id__delete",
@@ -2195,13 +2664,19 @@
"responses": {
"200": {
"description": "Success",
- "content": { "application/json": { "schema": {} } }
+ "content": {
+ "application/json": {
+ "schema": {}
+ }
+ }
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2209,7 +2684,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2218,31 +2695,41 @@
},
"/store/items": {
"put": {
- "tags": ["Store"],
+ "tags": [
+ "Store"
+ ],
"summary": "Store or update an item.",
"operationId": "put_item",
"requestBody": {
"required": true,
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/StorePutRequest" }
+ "schema": {
+ "$ref": "#/components/schemas/StorePutRequest"
+ }
}
}
},
"responses": {
- "204": { "description": "Success" },
+ "204": {
+ "description": "Success"
+ },
"422": {
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"delete": {
- "tags": ["Store"],
+ "tags": [
+ "Store"
+ ],
"summary": "Delete an item.",
"operationId": "delete_item",
"requestBody": {
@@ -2256,19 +2743,25 @@
}
},
"responses": {
- "204": { "description": "Success" },
+ "204": {
+ "description": "Success"
+ },
"422": {
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
}
},
"get": {
- "tags": ["Store"],
+ "tags": [
+ "Store"
+ ],
"summary": "Retrieve a single item.",
"operationId": "get_item",
"parameters": [
@@ -2276,13 +2769,20 @@
"name": "key",
"in": "query",
"required": true,
- "schema": { "type": "string" }
+ "schema": {
+ "type": "string"
+ }
},
{
"name": "namespace",
"in": "query",
"required": false,
- "schema": { "type": "array", "items": { "type": "string" } }
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
}
],
"responses": {
@@ -2290,7 +2790,9 @@
"description": "Success",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Item" }
+ "schema": {
+ "$ref": "#/components/schemas/Item"
+ }
}
}
},
@@ -2298,7 +2800,9 @@
"description": "Bad Request",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
},
@@ -2306,7 +2810,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2315,7 +2821,9 @@
},
"/store/items/search": {
"post": {
- "tags": ["Store"],
+ "tags": [
+ "Store"
+ ],
"summary": "Search for items within a namespace prefix.",
"operationId": "search_items",
"requestBody": {
@@ -2343,7 +2851,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2352,7 +2862,9 @@
},
"/store/namespaces": {
"post": {
- "tags": ["Store"],
+ "tags": [
+ "Store"
+ ],
"summary": "List namespaces with optional match conditions.",
"operationId": "list_namespaces",
"requestBody": {
@@ -2380,7 +2892,9 @@
"description": "Validation Error",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
@@ -2399,7 +2913,9 @@
"required": true,
"schema": {
"type": "string",
- "enum": ["application/json, text/event-stream"]
+ "enum": [
+ "application/json, text/event-stream"
+ ]
},
"description": "Accept header must include both 'application/json' and 'text/event-stream' media types."
}
@@ -2408,7 +2924,9 @@
"required": true,
"content": {
"application/json": {
- "schema": { "type": "object" },
+ "schema": {
+ "type": "object"
+ },
"description": "A JSON-RPC 2.0 request, notification, or response object.",
"example": {
"jsonrpc": "2.0",
@@ -2430,7 +2948,11 @@
"200": {
"description": "Successful JSON-RPC response.",
"content": {
- "application/json": { "schema": { "type": "object" } }
+ "application/json": {
+ "schema": {
+ "type": "object"
+ }
+ }
}
},
"202": {
@@ -2439,12 +2961,16 @@
"400": {
"description": "Bad request: invalid JSON or message format, or unacceptable Accept header."
},
- "405": { "description": "HTTP method not allowed." },
+ "405": {
+ "description": "HTTP method not allowed."
+ },
"500": {
"description": "Internal server error or unexpected failure."
}
},
- "tags": ["MCP"]
+ "tags": [
+ "MCP"
+ ]
},
"get": {
"operationId": "get_mcp",
@@ -2455,14 +2981,20 @@
"description": "GET method not allowed; streaming not supported."
}
},
- "tags": ["MCP"]
+ "tags": [
+ "MCP"
+ ]
},
"delete": {
"operationId": "delete_mcp",
"summary": "Terminate Session",
"description": "Implemented according to the Streamable HTTP Transport specification.\nTerminate an MCP session. The server implementation is stateless, so this is a no-op.\n\n",
- "responses": { "404": {} },
- "tags": ["MCP"]
+ "responses": {
+ "404": {}
+ },
+ "tags": [
+ "MCP"
+ ]
}
}
},
@@ -2484,7 +3016,9 @@
"config": {
"properties": {
"tags": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Tags"
},
@@ -2492,7 +3026,10 @@
"type": "integer",
"title": "Recursion Limit"
},
- "configurable": { "type": "object", "title": "Configurable" }
+ "configurable": {
+ "type": "object",
+ "title": "Configurable"
+ }
},
"type": "object",
"title": "Config",
@@ -2526,7 +3063,10 @@
"description": "The name of the assistant"
},
"description": {
- "type": ["string", "null"],
+ "type": [
+ "string",
+ "null"
+ ],
"title": "Assistant Description",
"description": "The description of the assistant"
}
@@ -2567,7 +3107,10 @@
},
"if_exists": {
"type": "string",
- "enum": ["raise", "do_nothing"],
+ "enum": [
+ "raise",
+ "do_nothing"
+ ],
"title": "If Exists",
"description": "How to handle duplicate creation. Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing assistant).",
"default": "raise"
@@ -2578,13 +3121,18 @@
"description": "The name of the assistant. Defaults to 'Untitled'."
},
"description": {
- "type": ["string", "null"],
+ "type": [
+ "string",
+ "null"
+ ],
"title": "Description",
"description": "The description of the assistant. Defaults to null."
}
},
"type": "object",
- "required": ["graph_id"],
+ "required": [
+ "graph_id"
+ ],
"title": "AssistantCreate",
"description": "Payload for creating an assistant."
},
@@ -2601,7 +3149,8 @@
"description": "Configuration to use for the graph. Useful when graph is configurable and you want to update the assistant's configuration."
},
"metadata": {
- "type": "object", "title": "Metadata",
+ "type": "object",
+ "title": "Metadata",
"description": "Metadata to merge with existing assistant metadata."
},
"name": {
@@ -2634,12 +3183,20 @@
"Config": {
"properties": {
"tags": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Tags"
},
- "recursion_limit": { "type": "integer", "title": "Recursion Limit" },
- "configurable": { "type": "object", "title": "Configurable" }
+ "recursion_limit": {
+ "type": "integer",
+ "title": "Recursion Limit"
+ },
+ "configurable": {
+ "type": "object",
+ "title": "Configurable"
+ }
},
"type": "object",
"title": "Config"
@@ -2713,7 +3270,6 @@
"title": "End Time",
"description": "The end date to stop running the cron."
},
-
"assistant_id": {
"anyOf": [
{
@@ -2721,14 +3277,24 @@
"format": "uuid",
"title": "Assistant Id"
},
- { "type": "string", "title": "Graph Id" }
+ {
+ "type": "string",
+ "title": "Graph Id"
+ }
],
"description": "The assistant ID or graph name to run. If using graph name, will default to the assistant automatically created from that graph by the server."
},
"input": {
"anyOf": [
- { "items": { "type": "object" }, "type": "array" },
- { "type": "object" }
+ {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ {
+ "type": "object"
+ }
],
"title": "Input",
"description": "The input to the graph."
@@ -2741,7 +3307,9 @@
"config": {
"properties": {
"tags": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Tags"
},
@@ -2749,7 +3317,10 @@
"type": "integer",
"title": "Recursion Limit"
},
- "configurable": { "type": "object", "title": "Configurable" }
+ "configurable": {
+ "type": "object",
+ "title": "Configurable"
+ }
},
"type": "object",
"title": "Config",
@@ -2765,30 +3336,58 @@
},
"interrupt_before": {
"anyOf": [
- { "type": "string", "enum": ["*"] },
- { "items": { "type": "string" }, "type": "array" }
+ {
+ "type": "string",
+ "enum": [
+ "*"
+ ]
+ },
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
],
"title": "Interrupt Before",
"description": "Nodes to interrupt immediately before they get executed."
},
"interrupt_after": {
"anyOf": [
- { "type": "string", "enum": ["*"] },
- { "items": { "type": "string" }, "type": "array" }
+ {
+ "type": "string",
+ "enum": [
+ "*"
+ ]
+ },
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
],
"title": "Interrupt After",
"description": "Nodes to interrupt immediately after they get executed."
},
"multitask_strategy": {
"type": "string",
- "enum": ["reject", "rollback", "interrupt", "enqueue"],
+ "enum": [
+ "reject",
+ "rollback",
+ "interrupt",
+ "enqueue"
+ ],
"title": "Multitask Strategy",
"description": "Multitask strategy to use. Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.",
"default": "reject"
}
},
"type": "object",
- "required": ["assistant_id", "schedule"],
+ "required": [
+ "assistant_id",
+ "schedule"
+ ],
"title": "CronCreate",
"description": "Payload for creating a cron job."
},
@@ -2823,15 +3422,17 @@
},
"sort_by": {
"type": "string",
- "enum": ["cron_id", "assistant_id", "thread_id", "next_run_date", "end_time", "created_at", "updated_at"],
"title": "Sort By",
- "description": "The field to sort by."
+ "description": "The field to sort by.",
+ "default": "created_at",
+ "enum": ["cron_id", "assistant_id", "thread_id", "next_run_date", "end_time", "created_at", "updated_at"]
},
"sort_order": {
"type": "string",
- "enum": ["asc", "desc"],
"title": "Sort Order",
- "description": "The order to sort by."
+ "description": "The order to sort by.",
+ "default": "desc",
+ "enum": ["asc", "desc"]
}
},
"type": "object",
@@ -2868,7 +3469,11 @@
}
},
"type": "object",
- "required": ["graph_id", "state_schema", "config_schema"],
+ "required": [
+ "graph_id",
+ "state_schema",
+ "config_schema"
+ ],
"title": "GraphSchema",
"description": "Defines the structure and properties of a graph."
},
@@ -2947,19 +3552,34 @@
},
"status": {
"type": "string",
- "enum": ["pending", "error", "success", "timeout", "interrupted"],
+ "enum": [
+ "pending",
+ "running",
+ "error",
+ "success",
+ "timeout",
+ "interrupted"
+ ],
"title": "Status",
- "description": "The status of the run. One of 'pending', 'error', 'success', 'timeout', 'interrupted'."
+ "description": "The status of the run. One of 'pending', 'running', 'error', 'success', 'timeout', 'interrupted'."
},
"metadata": {
"type": "object",
"title": "Metadata",
"description": "The run metadata."
},
- "kwargs": { "type": "object", "title": "Kwargs" },
+ "kwargs": {
+ "type": "object",
+ "title": "Kwargs"
+ },
"multitask_strategy": {
"type": "string",
- "enum": ["reject", "rollback", "interrupt", "enqueue"],
+ "enum": [
+ "reject",
+ "rollback",
+ "interrupt",
+ "enqueue"
+ ],
"title": "Multitask Strategy",
"description": "Strategy to handle concurrent runs on the same thread."
}
@@ -2989,12 +3609,22 @@
"description": "The node to send the message to."
},
"input": {
- "type": ["object", "array", "number", "string", "boolean", "null"],
+ "type": [
+ "object",
+ "array",
+ "number",
+ "string",
+ "boolean",
+ "null"
+ ],
"title": "Message",
"description": "The message to send."
}
},
- "required": ["node", "input"]
+ "required": [
+ "node",
+ "input"
+ ]
},
"Command": {
"type": "object",
@@ -3002,25 +3632,49 @@
"description": "The command to run.",
"properties": {
"update": {
- "type": ["object", "array", "null"],
+ "type": [
+ "object",
+ "array",
+ "null"
+ ],
"title": "Update",
"description": "An update to the state."
},
"resume": {
- "type": ["object", "array", "number", "string", "boolean", "null"],
+ "type": [
+ "object",
+ "array",
+ "number",
+ "string",
+ "boolean",
+ "null"
+ ],
"title": "Resume",
"description": "A value to pass to an interrupted node."
},
"goto": {
"anyOf": [
- { "$ref": "#/components/schemas/Send" },
+ {
+ "$ref": "#/components/schemas/Send"
+ },
{
"type": "array",
- "items": { "$ref": "#/components/schemas/Send" }
+ "items": {
+ "$ref": "#/components/schemas/Send"
+ }
},
- { "type": "string" },
- { "type": "array", "items": { "type": "string" } },
- { "type": "null" }
+ {
+ "type": "string"
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "type": "null"
+ }
],
"title": "Goto",
"description": "Name of the node(s) to navigate to next or node(s) to be executed with a provided input."
@@ -3036,7 +3690,10 @@
"format": "uuid",
"title": "Assistant Id"
},
- { "type": "string", "title": "Graph Id" }
+ {
+ "type": "string",
+ "title": "Graph Id"
+ }
],
"description": "The assistant ID or graph name to run. If using graph name, will default to first assistant created from that graph."
},
@@ -3048,20 +3705,36 @@
},
"input": {
"anyOf": [
- { "type": "object" },
- { "type": "array" },
- { "type": "string" },
- { "type": "number" },
- { "type": "boolean" },
- { "type": "null" }
+ {
+ "type": "object"
+ },
+ {
+ "type": "array"
+ },
+ {
+ "type": "string"
+ },
+ {
+ "type": "number"
+ },
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
],
"title": "Input",
"description": "The input to the graph."
},
"command": {
"anyOf": [
- { "$ref": "#/components/schemas/Command" },
- { "type": "null" }
+ {
+ "$ref": "#/components/schemas/Command"
+ },
+ {
+ "type": "null"
+ }
],
"title": "Input",
"description": "The input to the graph."
@@ -3074,7 +3747,9 @@
"config": {
"properties": {
"tags": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Tags"
},
@@ -3082,7 +3757,10 @@
"type": "integer",
"title": "Recursion Limit"
},
- "configurable": { "type": "object", "title": "Configurable" }
+ "configurable": {
+ "type": "object",
+ "title": "Configurable"
+ }
},
"type": "object",
"title": "Config",
@@ -3098,16 +3776,36 @@
},
"interrupt_before": {
"anyOf": [
- { "type": "string", "enum": ["*"] },
- { "items": { "type": "string" }, "type": "array" }
+ {
+ "type": "string",
+ "enum": [
+ "*"
+ ]
+ },
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
],
"title": "Interrupt Before",
"description": "Nodes to interrupt immediately before they get executed."
},
"interrupt_after": {
"anyOf": [
- { "type": "string", "enum": ["*"] },
- { "items": { "type": "string" }, "type": "array" }
+ {
+ "type": "string",
+ "enum": [
+ "*"
+ ]
+ },
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
],
"title": "Interrupt After",
"description": "Nodes to interrupt immediately after they get executed."
@@ -3144,7 +3842,9 @@
],
"title": "Stream Mode",
"description": "The stream mode(s) to use.",
- "default": ["values"]
+ "default": [
+ "values"
+ ]
},
"stream_subgraphs": {
"type": "boolean",
@@ -3152,35 +3852,54 @@
"description": "Whether to stream output from subgraphs.",
"default": false
},
+ "stream_resumable": {
+ "type": "boolean",
+ "title": "Stream Resumable",
+ "description": "Whether to persist the stream chunks in order to resume the stream later.",
+ "default": false
+ },
"on_disconnect": {
"type": "string",
- "enum": ["cancel", "continue"],
+ "enum": [
+ "cancel",
+ "continue"
+ ],
"title": "On Disconnect",
"description": "The disconnect mode to use. Must be one of 'cancel' or 'continue'.",
"default": "cancel"
},
"feedback_keys": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Feedback Keys",
"description": "Feedback keys to assign to run."
},
"multitask_strategy": {
"type": "string",
- "enum": ["reject", "rollback", "interrupt", "enqueue"],
+ "enum": [
+ "reject",
+ "rollback",
+ "interrupt",
+ "enqueue"
+ ],
"title": "Multitask Strategy",
"description": "Multitask strategy to use. Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.",
"default": "reject"
},
"if_not_exists": {
"type": "string",
- "enum": ["create", "reject"],
+ "enum": [
+ "create",
+ "reject"
+ ],
"title": "If Not Exists",
"description": "How to handle missing thread. Must be either 'reject' (raise error if missing), or 'create' (create new thread).",
"default": "reject"
},
"after_seconds": {
- "type": "integer",
+ "type": "number",
"title": "After Seconds",
"description": "The number of seconds to wait before starting the run. Use to schedule future runs."
},
@@ -3192,13 +3911,17 @@
}
},
"type": "object",
- "required": ["assistant_id"],
+ "required": [
+ "assistant_id"
+ ],
"title": "RunCreateStateful",
"description": "Payload for creating a run."
},
"RunBatchCreate": {
"type": "array",
- "items": { "$ref": "#/components/schemas/RunCreateStateless" },
+ "items": {
+ "$ref": "#/components/schemas/RunCreateStateless"
+ },
"minItems": 1,
"title": "RunBatchCreate",
"description": "Payload for creating a batch of runs."
@@ -3212,26 +3935,45 @@
"format": "uuid",
"title": "Assistant Id"
},
- { "type": "string", "title": "Graph Id" }
+ {
+ "type": "string",
+ "title": "Graph Id"
+ }
],
"description": "The assistant ID or graph name to run. If using graph name, will default to first assistant created from that graph."
},
"input": {
"anyOf": [
- { "type": "object" },
- { "type": "array" },
- { "type": "string" },
- { "type": "number" },
- { "type": "boolean" },
- { "type": "null" }
+ {
+ "type": "object"
+ },
+ {
+ "type": "array"
+ },
+ {
+ "type": "string"
+ },
+ {
+ "type": "number"
+ },
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "null"
+ }
],
"title": "Input",
"description": "The input to the graph."
},
"command": {
"anyOf": [
- { "$ref": "#/components/schemas/Command" },
- { "type": "null" }
+ {
+ "$ref": "#/components/schemas/Command"
+ },
+ {
+ "type": "null"
+ }
],
"title": "Input",
"description": "The input to the graph."
@@ -3244,7 +3986,9 @@
"config": {
"properties": {
"tags": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Tags"
},
@@ -3252,7 +3996,10 @@
"type": "integer",
"title": "Recursion Limit"
},
- "configurable": { "type": "object", "title": "Configurable" }
+ "configurable": {
+ "type": "object",
+ "title": "Configurable"
+ }
},
"type": "object",
"title": "Config",
@@ -3268,16 +4015,36 @@
},
"interrupt_before": {
"anyOf": [
- { "type": "string", "enum": ["*"] },
- { "items": { "type": "string" }, "type": "array" }
+ {
+ "type": "string",
+ "enum": [
+ "*"
+ ]
+ },
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
],
"title": "Interrupt Before",
"description": "Nodes to interrupt immediately before they get executed."
},
"interrupt_after": {
"anyOf": [
- { "type": "string", "enum": ["*"] },
- { "items": { "type": "string" }, "type": "array" }
+ {
+ "type": "string",
+ "enum": [
+ "*"
+ ]
+ },
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
],
"title": "Interrupt After",
"description": "Nodes to interrupt immediately after they get executed."
@@ -3314,10 +4081,14 @@
],
"title": "Stream Mode",
"description": "The stream mode(s) to use.",
- "default": ["values"]
+ "default": [
+ "values"
+ ]
},
"feedback_keys": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Feedback Keys",
"description": "Feedback keys to assign to run."
@@ -3328,22 +4099,34 @@
"description": "Whether to stream output from subgraphs.",
"default": false
},
+ "stream_resumable": {
+ "type": "boolean",
+ "title": "Stream Resumable",
+ "description": "Whether to persist the stream chunks in order to resume the stream later.",
+ "default": false
+ },
"on_completion": {
"type": "string",
- "enum": ["delete", "keep"],
+ "enum": [
+ "delete",
+ "keep"
+ ],
"title": "On Completion",
"description": "Whether to delete or keep the thread created for a stateless run. Must be one of 'delete' or 'keep'.",
"default": "delete"
},
"on_disconnect": {
"type": "string",
- "enum": ["cancel", "continue"],
+ "enum": [
+ "cancel",
+ "continue"
+ ],
"title": "On Disconnect",
"description": "The disconnect mode to use. Must be one of 'cancel' or 'continue'.",
"default": "cancel"
},
"after_seconds": {
- "type": "integer",
+ "type": "number",
"title": "After Seconds",
"description": "The number of seconds to wait before starting the run. Use to schedule future runs."
},
@@ -3355,7 +4138,9 @@
}
},
"type": "object",
- "required": ["assistant_id"],
+ "required": [
+ "assistant_id"
+ ],
"title": "RunCreateStateless",
"description": "Payload for creating a run."
},
@@ -3400,7 +4185,10 @@
},
"sort_order": {
"type": "string",
- "enum": ["asc", "desc"],
+ "enum": [
+ "asc",
+ "desc"
+ ],
"title": "Sort Order",
"description": "The order to sort by."
}
@@ -3450,7 +4238,12 @@
},
"status": {
"type": "string",
- "enum": ["idle", "busy", "interrupted", "error"],
+ "enum": [
+ "idle",
+ "busy",
+ "interrupted",
+ "error"
+ ],
"title": "Status",
"description": "Thread status to filter on."
},
@@ -3471,13 +4264,21 @@
},
"sort_by": {
"type": "string",
- "enum": ["thread_id", "status", "created_at", "updated_at"],
+ "enum": [
+ "thread_id",
+ "status",
+ "created_at",
+ "updated_at"
+ ],
"title": "Sort By",
"description": "Sort by field."
},
"sort_order": {
"type": "string",
- "enum": ["asc", "desc"],
+ "enum": [
+ "asc",
+ "desc"
+ ],
"title": "Sort Order",
"description": "Sort order."
}
@@ -3513,7 +4314,12 @@
},
"status": {
"type": "string",
- "enum": ["idle", "busy", "interrupted", "error"],
+ "enum": [
+ "idle",
+ "busy",
+ "interrupted",
+ "error"
+ ],
"title": "Status",
"description": "The status of the thread."
},
@@ -3548,7 +4354,10 @@
},
"if_exists": {
"type": "string",
- "enum": ["raise", "do_nothing"],
+ "enum": [
+ "raise",
+ "do_nothing"
+ ],
"title": "If Exists",
"description": "How to handle duplicate creation. Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing thread).",
"default": "raise"
@@ -3560,7 +4369,9 @@
"properties": {
"strategy": {
"type": "string",
- "enum": ["delete"],
+ "enum": [
+ "delete"
+ ],
"description": "The TTL strategy. 'delete' removes the entire thread.",
"default": "delete"
},
@@ -3582,7 +4393,9 @@
}
}
},
- "required": ["updates"]
+ "required": [
+ "updates"
+ ]
}
}
},
@@ -3615,7 +4428,9 @@
"description": "Include subgraph states."
}
},
- "required": ["checkpoint"],
+ "required": [
+ "checkpoint"
+ ],
"type": "object",
"title": "ThreadStateCheckpointRequest",
"description": "Payload for getting the state of a thread at a checkpoint."
@@ -3624,13 +4439,22 @@
"properties": {
"values": {
"anyOf": [
- { "items": { "type": "object" }, "type": "array" },
- { "type": "object" }
+ {
+ "items": {
+ "type": "object"
+ },
+ "type": "array"
+ },
+ {
+ "type": "object"
+ }
],
"title": "Values"
},
"next": {
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"type": "array",
"title": "Next"
},
@@ -3638,17 +4462,34 @@
"items": {
"type": "object",
"properties": {
- "id": { "type": "string", "title": "Task Id" },
- "name": { "type": "string", "title": "Node Name" },
- "error": { "type": "string", "title": "Error" },
- "interrupts": { "type": "array", "items": {} },
+ "id": {
+ "type": "string",
+ "title": "Task Id"
+ },
+ "name": {
+ "type": "string",
+ "title": "Node Name"
+ },
+ "error": {
+ "type": "string",
+ "title": "Error"
+ },
+ "interrupts": {
+ "type": "array",
+ "items": {}
+ },
"checkpoint": {
"$ref": "#/components/schemas/CheckpointConfig",
"title": "Checkpoint"
},
- "state": { "$ref": "#/components/schemas/ThreadState" }
+ "state": {
+ "$ref": "#/components/schemas/ThreadState"
+ }
},
- "required": ["id", "name"]
+ "required": [
+ "id",
+ "name"
+ ]
},
"type": "array",
"title": "Tasks"
@@ -3657,15 +4498,27 @@
"$ref": "#/components/schemas/CheckpointConfig",
"title": "Checkpoint"
},
- "metadata": { "type": "object", "title": "Metadata" },
- "created_at": { "type": "string", "title": "Created At" },
+ "metadata": {
+ "type": "object",
+ "title": "Metadata"
+ },
+ "created_at": {
+ "type": "string",
+ "title": "Created At"
+ },
"parent_checkpoint": {
"type": "object",
"title": "Parent Checkpoint"
}
},
"type": "object",
- "required": ["values", "next", "checkpoint", "metadata", "created_at"],
+ "required": [
+ "values",
+ "next",
+ "checkpoint",
+ "metadata",
+ "created_at"
+ ],
"title": "ThreadState"
},
"ThreadStateSearch": {
@@ -3701,9 +4554,16 @@
"properties": {
"values": {
"anyOf": [
- { "items": { "type": "object" }, "type": "array" },
- { "type": "object" },
- { "type": "null" }
+ {
+ "items": {},
+ "type": "array"
+ },
+ {
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
],
"title": "Values",
"description": "The values to update the state with."
@@ -3727,15 +4587,28 @@
"properties": {
"values": {
"anyOf": [
- { "type": "array", "items": { "type": "object" } },
- { "type": "object" },
- { "type": "null" }
+ {
+ "type": "array",
+ "items": {
+ "type": "object"
+ }
+ },
+ {
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
]
},
"command": {
"anyOf": [
- { "$ref": "#/components/schemas/Command" },
- { "type": "null" }
+ {
+ "$ref": "#/components/schemas/Command"
+ },
+ {
+ "type": "null"
+ }
],
"description": "The command associated with the update."
},
@@ -3744,12 +4617,17 @@
"description": "Update the state as if this node had just executed."
}
},
- "required": ["as_node"],
+ "required": [
+ "as_node"
+ ],
"type": "object"
},
"ThreadStateUpdateResponse": {
"properties": {
- "checkpoint": { "type": "object", "title": "Checkpoint" }
+ "checkpoint": {
+ "type": "object",
+ "title": "Checkpoint"
+ }
},
"type": "object",
"title": "ThreadStateUpdateResponse",
@@ -3780,11 +4658,17 @@
},
"StorePutRequest": {
"type": "object",
- "required": ["namespace", "key", "value"],
+ "required": [
+ "namespace",
+ "key",
+ "value"
+ ],
"properties": {
"namespace": {
"type": "array",
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"title": "Namespace",
"description": "A list of strings representing the namespace path."
},
@@ -3804,11 +4688,15 @@
},
"StoreDeleteRequest": {
"type": "object",
- "required": ["key"],
+ "required": [
+ "key"
+ ],
"properties": {
"namespace": {
"type": "array",
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"title": "Namespace",
"description": "A list of strings representing the namespace path."
},
@@ -3825,25 +4713,25 @@
"type": "object",
"properties": {
"namespace_prefix": {
- "type": ["array", "null"],
- "items": { "type": "string" },
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
"title": "Namespace Prefix",
"description": "List of strings representing the namespace prefix."
},
"filter": {
- "type": ["object", "null"],
+ "type": [
+ "object",
+ "null"
+ ],
"additionalProperties": true,
"title": "Filter",
"description": "Optional dictionary of key-value pairs to filter results."
},
- "query": {
- "type": [
- "string",
- "null"
- ],
- "title": "Query",
- "description": "Query string for semantic/vector search."
- },
"limit": {
"type": "integer",
"default": 10,
@@ -3855,6 +4743,14 @@
"default": 0,
"title": "Offset",
"description": "Number of items to skip before returning results (default is 0)."
+ },
+ "query": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "title": "Query",
+ "description": "Query string for semantic/vector search."
}
},
"title": "StoreSearchRequest",
@@ -3865,13 +4761,17 @@
"properties": {
"prefix": {
"type": "array",
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"title": "Prefix",
"description": "Optional list of strings representing the prefix to filter namespaces."
},
"suffix": {
"type": "array",
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"title": "Suffix",
"description": "Optional list of strings representing the suffix to filter namespaces."
},
@@ -3896,11 +4796,19 @@
},
"Item": {
"type": "object",
- "required": ["namespace", "key", "value", "created_at", "updated_at"],
+ "required": [
+ "namespace",
+ "key",
+ "value",
+ "created_at",
+ "updated_at"
+ ],
"properties": {
"namespace": {
"type": "array",
- "items": { "type": "string" },
+ "items": {
+ "type": "string"
+ },
"description": "The namespace of the item. A namespace is analogous to a document's directory."
},
"key": {
@@ -3931,7 +4839,11 @@
"properties": {
"status": {
"type": "string",
- "enum": ["pending", "running", "all"],
+ "enum": [
+ "pending",
+ "running",
+ "all"
+ ],
"title": "Status",
"description": "Filter runs by status to cancel. Must be one of 'pending', 'running', or 'all'."
},
@@ -3943,29 +4855,50 @@
},
"run_ids": {
"type": "array",
- "items": { "type": "string", "format": "uuid" },
+ "items": {
+ "type": "string",
+ "format": "uuid"
+ },
"title": "Run Ids",
"description": "List of run IDs to cancel."
}
},
"oneOf": [
- { "required": ["status"] },
- { "required": ["thread_id", "run_ids"] }
+ {
+ "required": [
+ "status"
+ ]
+ },
+ {
+ "required": [
+ "thread_id",
+ "run_ids"
+ ]
+ }
]
},
"SearchItemsResponse": {
"type": "object",
- "required": ["items"],
+ "required": [
+ "items"
+ ],
"properties": {
"items": {
"type": "array",
- "items": { "$ref": "#/components/schemas/Item" }
+ "items": {
+ "$ref": "#/components/schemas/Item"
+ }
}
}
},
"ListNamespaceResponse": {
"type": "array",
- "items": { "type": "array", "items": { "type": "string" } }
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
},
"ErrorResponse": {
"type": "string",
@@ -3978,7 +4911,9 @@
"description": "Successful retrieval of an item.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/Item" }
+ "schema": {
+ "$ref": "#/components/schemas/Item"
+ }
}
}
},
@@ -3994,7 +4929,9 @@
"description": "Successful search operation.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/SearchItemsResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/SearchItemsResponse"
+ }
}
}
},
@@ -4002,7 +4939,9 @@
"description": "Successful retrieval of namespaces.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ListNamespaceResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ListNamespaceResponse"
+ }
}
}
},
@@ -4010,7 +4949,9 @@
"description": "An error occurred.",
"content": {
"application/json": {
- "schema": { "$ref": "#/components/schemas/ErrorResponse" }
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
}
}
}
diff --git a/docs/docs/cloud/reference/cli.md b/docs/docs/cloud/reference/cli.md
index 84e5f3f66..b2a45bf61 100644
--- a/docs/docs/cloud/reference/cli.md
+++ b/docs/docs/cloud/reference/cli.md
@@ -51,9 +51,10 @@ The LangGraph CLI requires a JSON configuration file that follows this [schema](
| `node_version` | Specify `node_version: 20` to use LangGraph.js. |
| `pip_config_file` | Path to `pip` config file. |
| `pip_installer` | _(Added in v0.3)_ Optional. Python package installer selector. It can be set to `"auto"`, `"pip"`, or `"uv"`. From version 0.3 onward the default strategy is to run `uv pip`, which typically delivers faster builds while remaining a drop-in replacement. In the uncommon situation where `uv` cannot handle your dependency graph or the structure of your `pyproject.toml`, specify `"pip"` here to revert to the earlier behaviour. |
+ | `keep_pkg_tools` | _(Added in v0.3.4)_ Optional. Control whether to retain Python packaging tools (`pip`, `setuptools`, `wheel`) in the final image. Accepted values:
true : Keep all three tools (skip uninstall).
false / omitted : Uninstall all three tools (default behaviour).
list[str] : Names of tools to retain. Each value must be one of "pip", "setuptools", "wheel".
. By default, all three tools are uninstalled. |
| `dockerfile_lines` | Array of additional lines to add to Dockerfile following the import from parent image. |
| `checkpointer` | Configuration for the checkpointer. Contains a `ttl` field which is an object with the following keys:
`strategy`: How to handle expired checkpoints (e.g., `"delete"`).
`sweep_interval_minutes`: How often to check for expired checkpoints (integer).
`default_ttl`: Default time-to-live for checkpoints in **minutes** (integer). Defines how long checkpoints are kept before the specified strategy is applied.
|
- | `http` | HTTP server configuration with the following fields:
`app`: Path to custom Starlette/FastAPI app (e.g., `"./src/agent/webapp.py:app"`). See [custom routes guide](../../how-tos/http/custom_routes.md).
`disable_meta`: Disable `/ok`, `/info`, `/metrics`, and `/docs` routes
`disable_runs`: Disable `/runs` routes
`disable_store`: Disable `/store` routes
`disable_threads`: Disable `/threads` routes
`disable_ui`: Disable `/ui` routes
`disable_webhooks`: Disable webhooks calls on run completion in all routes
`mount_prefix`: Prefix for mounted routes (e.g., "/my-deployment/api")
|
=== "JS"
@@ -408,6 +409,8 @@ The LangGraph CLI requires a JSON configuration file that follows this [schema](
| Option | Default | Description |
| ---------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `--wait` | | Wait for services to start before returning. Implies --detach |
+ | `--base-image TEXT` | `langchain/langgraph-api` | Base image to use for the LangGraph API server. Pin to specific versions using version tags. |
+ | `--image TEXT` | | Docker image to use for the langgraph-api service. If specified, skips building and uses this image directly. |
| `--postgres-uri TEXT` | Local database | Postgres URI to use for the database. |
| `--watch` | | Restart on file changes |
| `--debugger-base-url TEXT` | `http://127.0.0.1:[PORT]` | URL used by the debugger to access LangGraph API. |
@@ -435,6 +438,8 @@ The LangGraph CLI requires a JSON configuration file that follows this [schema](
| Option | Default | Description |
| ---------------------------------------------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `--wait` | | Wait for services to start before returning. Implies --detach |
+ | `--base-image TEXT` | `langchain/langgraph-api` | Base image to use for the LangGraph API server. Pin to specific versions using version tags. |
+ | `--image TEXT` | | Docker image to use for the langgraph-api service. If specified, skips building and uses this image directly. |
| `--postgres-uri TEXT` | Local database | Postgres URI to use for the database. |
| `--watch` | | Restart on file changes |
| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. |
diff --git a/docs/docs/cloud/reference/env_var.md b/docs/docs/cloud/reference/env_var.md
index 563cec2a1..e24270c13 100644
--- a/docs/docs/cloud/reference/env_var.md
+++ b/docs/docs/cloud/reference/env_var.md
@@ -10,6 +10,10 @@ This environment variable should be set to `True` if the implementation of a gra
Defaults to `False`.
+## `BG_JOB_SHUTDOWN_GRACE_PERIOD_SECS`
+
+Specifies, in seconds, how long the server will wait for background jobs to finish after the queue receives a shutdown signal. After this period, the server will force termination. Defaults to `180` seconds. Set this to ensure jobs have enough time to complete cleanly during shutdown. Added in `langgraph-api==0.2.16`.
+
## `BG_JOB_TIMEOUT_SECS`
The timeout of a background run can be increased. However, the infrastructure for a Cloud SaaS deployment enforces a 1 hour timeout limit for API requests. This means the connection between client and server will timeout after 1 hour. This is not configurable.
@@ -18,16 +22,15 @@ A background run can execute for longer than 1 hour, but a client must reconnect
Defaults to `3600`.
-## `BG_JOB_SHUTDOWN_GRACE_PERIOD_SECS`
-
-Specifies, in seconds, how long the server will wait for background jobs to finish after the queue receives a shutdown signal. After this period, the server will force termination. Defaults to `3600` seconds. Set this to ensure jobs have enough time to complete cleanly during shutdown. Added in `langgraph-api==0.2.16`.
-
## `DD_API_KEY`
Specify `DD_API_KEY` (your [Datadog API Key](https://docs.datadoghq.com/account_management/api-app-keys/)) to automatically enable Datadog tracing for the deployment. Specify other [`DD_*` environment variables](https://ddtrace.readthedocs.io/en/stable/configuration.html) to configure the tracing instrumentation.
If `DD_API_KEY` is specified, the application process is wrapped in the [`ddtrace-run` command](https://ddtrace.readthedocs.io/en/stable/installation_quickstart.html). Other `DD_*` environment variables (e.g. `DD_SITE`, `DD_ENV`, `DD_SERVICE`, `DD_TRACE_ENABLED`) are typically needed to properly configure the tracing instrumentation. See [`DD_*` environment variables](https://ddtrace.readthedocs.io/en/stable/configuration.html) for more details.
+!!! note
+ Enabling `DD_API_KEY` (and thus `ddtrace-run`) can override or interfere with other auto-instrumentation solutions (such as OpenTelemetry) that you may have instrumented into your application code.
+
## `LANGCHAIN_TRACING_SAMPLING_RATE`
Sampling rate for traces sent to LangSmith. Valid values: Any float between `0` and `1`.
@@ -40,6 +43,14 @@ Type of authentication for the LangGraph Server deployment. Valid values: `langs
For deployments to LangGraph Platform, this environment variable is set automatically. For local development or deployments where authentication is handled externally (e.g. self-hosted), set this environment variable to `noop`.
+## `LANGGRAPH_POSTGRES_POOL_MAX_SIZE`
+
+Beginning with langgraph-api version `0.2.12`, the maximum size of the Postgres connection pool (per replica) can be controlled using the `LANGGRAPH_POSTGRES_POOL_MAX_SIZE` environment variable. By setting this variable, you can determine the upper bound on the number of simultaneous connections the server will establish with the Postgres database.
+
+For example, if a deployment is scaled up to 10 replicas and `LANGGRAPH_POSTGRES_POOL_MAX_SIZE` is configured to `150`, then up to `1500` connections to Postgres can be established. This is particularly useful for deployments where database resources are limited (or more available) or where you need to tune connection behavior for performance or scaling reasons.
+
+Defaults to `150` connections.
+
## `LANGSMITH_RUNS_ENDPOINTS`
For deployments with [self-hosted LangSmith](https://docs.smith.langchain.com/self_hosting) only.
@@ -54,6 +65,10 @@ Set `LANGSMITH_TRACING` to `false` to disable tracing to LangSmith.
Defaults to `true`.
+## `LOG_COLOR`
+
+This is mainly relevant in the context of using the dev server via the `langgraph dev` command. Set `LOG_COLOR` to `true` to enable ANSI-colored console output when using the default console renderer. Disabling color output by setting this variable to `false` produces monochrome logs. Defaults to `true`.
+
## `LOG_LEVEL`
Configure [log level](https://docs.python.org/3/library/logging.html#logging-levels). Defaults to `INFO`.
@@ -62,9 +77,14 @@ Configure [log level](https://docs.python.org/3/library/logging.html#logging-lev
Set `LOG_JSON` to `true` to render all log messages as JSON objects using the configured `JSONRenderer`. This produces structured logs that can be easily parsed or ingested by log management systems. Defaults to `false`.
-## `LOG_COLOR`
+## `MOUNT_PREFIX`
-This is mainly relevant in the context of using the dev server via the `langgraph dev` command. Set `LOG_COLOR` to `true` to enable ANSI-colored console output when using the default console renderer. Disabling color output by setting this variable to `false` produces monochrome logs. Defaults to `true`.
+!!! info "Only Allowed in Self-Hosted Deployments"
+ The `MOUNT_PREFIX` environment variable is only allowed in Self-Hosted Deployment models, LangGraph Platform SaaS will not allow this environment variable.
+
+Set `MOUNT_PREFIX` to serve the LangGraph Server under a specific path prefix. This is useful for deployments where the server is behind a reverse proxy or load balancer that requires a specific path prefix.
+
+For example, if the server is to be served under `https://example.com/langgraph`, set `MOUNT_PREFIX` to `/langgraph`.
## `N_JOBS_PER_WORKER`
@@ -94,16 +114,14 @@ Database Connectivity:
- The custom Postgres instance must be accessible by the LangGraph Server. The user is responsible for ensuring connectivity.
-## `LANGGRAPH_POSTGRES_POOL_MAX_SIZE`
+## `REDIS_CLUSTER`
-Beginning with langgraph-api version `0.2.12`, the maximum size of the Postgres connection pool can be controlled using the `LANGGRAPH_POSTGRES_POOL_MAX_SIZE` environment variable. By setting this variable, you can determine the upper bound on the number of simultaneous connections the server will establish with the Postgres database. This is particularly useful for deployments where database resources are limited (or more available) or where you need to tune connection behavior for performance or scaling reasons. If not specified, the pool size defaults to 150 connections.
+!!! info "Only Allowed in Self-Hosted Deployments"
+ Redis Cluster mode is only available in Self-Hosted Deployment models, LangGraph Platform SaaS will provision a redis instance for you by default.
-## `REDIS_URI_CUSTOM`
+Set `REDIS_CLUSTER` to `True` to enable Redis Cluster mode. When enabled, the system will connect to Redis using cluster mode. This is useful when connecting to a Redis Cluster deployment.
-!!! info "Only for Self-Hosted Data Plane and Self-Hosted Control Plane"
- Custom Redis instances are only available for [Self-Hosted Data Plane](../../concepts/langgraph_self_hosted_data_plane.md) and [Self-Hosted Control Plane](../../concepts/langgraph_self_hosted_control_plane.md) deployments.
-
-Specify `REDIS_URI_CUSTOM` to use a custom Redis instance. The value of `REDIS_URI_CUSTOM` must be a valid [Redis connection URI](https://redis-py.readthedocs.io/en/stable/connections.html#redis.Redis.from_url).
+Defaults to `False`.
## `REDIS_KEY_PREFIX`
@@ -114,20 +132,19 @@ Specify a prefix for Redis keys. This allows multiple LangGraph Server instances
Defaults to `''`.
-## `REDIS_CLUSTER`
+## `REDIS_URI_CUSTOM`
-!!! info "Only Allowed in Self-Hosted Deployments"
- Redis Cluster mode is only available in Self-Hosted Deployment models, LangGraph Platform SaaS will provision a redis instance for you by default.
+!!! info "Only for Self-Hosted Data Plane and Self-Hosted Control Plane"
+ Custom Redis instances are only available for [Self-Hosted Data Plane](../../concepts/langgraph_self_hosted_data_plane.md) and [Self-Hosted Control Plane](../../concepts/langgraph_self_hosted_control_plane.md) deployments.
-Set `REDIS_CLUSTER` to `True` to enable Redis Cluster mode. When enabled, the system will connect to Redis using cluster mode. This is useful when connecting to a Redis Cluster deployment.
+Specify `REDIS_URI_CUSTOM` to use a custom Redis instance. The value of `REDIS_URI_CUSTOM` must be a valid [Redis connection URI](https://redis-py.readthedocs.io/en/stable/connections.html#redis.Redis.from_url).
-Defaults to `False`.
+## `RESUMABLE_STREAM_TTL_SECONDS`
-## `MOUNT_PREFIX`
+Time-to-live in seconds for resumable stream data in Redis.
-!!! info "Only Allowed in Self-Hosted Deployments"
- The `MOUNT_PREFIX` environment variable is only allowed in Self-Hosted Deployment models, LangGraph Platform SaaS will not allow this environment variable.
+When a run is created and the output is streamed, the stream can be configured to be resumable (e.g. `stream_resumable=True`). If a stream is resumable, output from the stream is temporarily stored in Redis. The TTL for this data can be configured by setting `RESUMABLE_STREAM_TTL_SECONDS`.
-Set `MOUNT_PREFIX` to serve the LangGraph Server under a specific path prefix. This is useful for deployments where the server is behind a reverse proxy or load balancer that requires a specific path prefix.
+See the [Python](https://langchain-ai.github.io/langgraph/cloud/reference/sdk/python_sdk_ref/#langgraph_sdk.client.RunsClient.stream) and [JS/TS](https://langchain-ai.github.io/langgraphjs/reference/classes/sdk_client.RunsClient.html#stream) SDKs for more details on how to implement resumable streams.
-For example, if the server is to be served under `https://example.com/langgraph`, set `MOUNT_PREFIX` to `/langgraph`.
+Defaults to `120` seconds.
diff --git a/docs/docs/cloud/reference/langgraph_server_changelog.md b/docs/docs/cloud/reference/langgraph_server_changelog.md
new file mode 100644
index 000000000..66e1702af
--- /dev/null
+++ b/docs/docs/cloud/reference/langgraph_server_changelog.md
@@ -0,0 +1,184 @@
+# LangGraph Server Changelog
+
+[LangGraph Server](../../concepts/langgraph_server.md) is an API platform for creating and managing agent-based applications. It provides built-in persistence, a task queue, and supports deploying, configuring, and running assistants (agentic workflows) at scale. This changelog documents all notable updates, features, and fixes to LangGraph Server releases.
+
+---
+
+## v0.2.96 (2025-07-17)
+- Added a fallback mechanism for configurable header patterns to handle exclude/include settings more effectively.
+
+## v0.2.95 (2025-07-17)
+- Avoided setting the future if it is already done to prevent redundant operations.
+- Resolved compatibility errors in CI by switching from `typing.TypedDict` to `typing_extensions.TypedDict` for Python versions below 3.12.
+
+## v0.2.94 (2025-07-16)
+- Improved performance by omitting pending sends for langgraph versions 0.5 and above.
+- Improved server startup logs to provide clearer warnings when the DD_API_KEY environment variable is set.
+
+## v0.2.93 (2025-07-16)
+- Removed the GIN index for run metadata to improve performance.
+
+## v0.2.92 (2025-07-16)
+- Enabled copying functionality for blobs and checkpoints, improving data management flexibility.
+
+## v0.2.91 (2025-07-16)
+- Reduced writes to the `checkpoint_blobs` table by inlining small values (null, numeric, str, etc.). This means we don't need to store extra values for channels that haven't been updated.
+
+## v0.2.90 (2025-07-16)
+- Improve checkpoint writes via node-local background queueing.
+
+
+## v0.2.89 (2025-07-15)
+- Decoupled checkpoint writing from thread/run state by removing foreign keys and updated logger to prevent timeout-related failures.
+
+## v0.2.88 (2025-07-14)
+- Removed the foreign key constraint for `thread` in the `run` table to simplify database schema.
+
+## v0.2.87 (2025-07-14)
+- Added more detailed logs for Redis worker signaling to improve debugging.
+
+## v0.2.86 (2025-07-11)
+- Honored tool descriptions in the `/mcp` endpoint to align with expected functionality.
+
+## v0.2.85 (2025-07-10)
+- Added support for the `on_disconnect` field to `runs/wait` and included disconnect logs for better debugging.
+
+## v0.2.84 (2025-07-09)
+- Removed unnecessary status updates to streamline thread handling and updated version to 0.2.84.
+
+## v0.2.83 (2025-07-09)
+- Reduced the default time-to-live for resumable streams to 2 minutes.
+- Enhanced data submission logic to send data to both Beacon and LangSmith instance based on license configuration.
+- Enabled submission of self-hosted data to a Langsmith instance when the endpoint is configured.
+
+## v0.2.82 (2025-07-03)
+- Addressed a race condition in background runs by implementing a lock using join, ensuring reliable execution across CTEs.
+
+## v0.2.81 (2025-07-03)
+- Optimized run streams by reducing initial wait time to improve responsiveness for older or non-existent runs.
+
+## v0.2.80 (2025-07-03)
+- Corrected parameter passing in the `logger.ainfo()` API call to resolve a TypeError.
+
+## v0.2.79 (2025-07-02)
+- Fixed a JsonDecodeError in checkpointing with remote graph by correcting JSON serialization to handle trailing slashes properly.
+- Introduced a configuration flag to disable webhooks globally across all routes.
+
+## v0.2.78 (2025-07-02)
+- Added timeout retries to webhook calls to improve reliability.
+- Added HTTP request metrics, including a request count and latency histogram, for enhanced monitoring capabilities.
+
+## v0.2.77 (2025-07-02)
+- Added HTTP metrics to improve performance monitoring.
+- Changed the Redis cache delimiter to reduce conflicts with subgraph message names and updated caching behavior.
+
+## v0.2.76 (2025-07-01)
+- Updated Redis cache delimiter to prevent conflicts with subgraph messages.
+
+## v0.2.74 (2025-06-30)
+- Scheduled webhooks in an isolated loop to ensure thread-safe operations and prevent errors with PYTHONASYNCIODEBUG=1.
+
+## v0.2.73 (2025-06-27)
+- Fixed an infinite frame loop issue and removed the dict_parser due to structlog's unexpected behavior.
+- Throw a 409 error on deadlock occurrence during run cancellations to handle lock conflicts gracefully.
+
+## v0.2.72 (2025-06-27)
+- Ensured compatibility with future langgraph versions.
+- Implemented a 409 response status to handle deadlock issues during cancellation.
+
+## v0.2.71 (2025-06-26)
+- Improved logging for better clarity and detail regarding log types.
+
+## v0.2.70 (2025-06-26)
+- Improved error handling to better distinguish and log TimeoutErrors caused by users from internal run timeouts.
+
+## v0.2.69 (2025-06-26)
+- Added sorting and pagination to the crons API and updated schema definitions for improved accuracy.
+
+## v0.2.66 (2025-06-26)
+- Fixed a 404 error when creating multiple runs with the same thread_id using `on_not_exist="create"`.
+
+## v0.2.65 (2025-06-25)
+- Ensured that only fields from `assistant_versions` are returned when necessary.
+- Ensured consistent data types for in-memory and PostgreSQL users, improving internal authentication handling.
+
+## v0.2.64 (2025-06-24)
+- Added descriptions to version entries for better clarity.
+
+## v0.2.62 (2025-06-23)
+- Improved user handling for custom authentication in the JS Studio.
+- Added Prometheus-format run statistics to the metrics endpoint for better monitoring.
+- Added run statistics in Prometheus format to the metrics endpoint.
+
+## v0.2.61 (2025-06-20)
+- Set a maximum idle time for Redis connections to prevent unnecessary open connections.
+
+## v0.2.60 (2025-06-20)
+- Enhanced error logging to include traceback details for dictionary operations.
+- Added a `/metrics` endpoint to expose queue worker metrics for monitoring.
+
+## v0.2.57 (2025-06-18)
+- Removed CancelledError from retriable exceptions to allow local interrupts while maintaining retriability for workers.
+- Introduced middleware to gracefully shut down the server after completing in-flight requests upon receiving a SIGINT.
+- Reduced metadata stored in checkpoint to only include necessary information.
+- Improved error handling in join runs to return error details when present.
+
+## v0.2.56 (2025-06-17)
+- Improved application stability by adding a handler for SIGTERM signals.
+
+## v0.2.55 (2025-06-17)
+- Improved the handling of cancellations in the queue entrypoint.
+- Improved cancellation handling in the queue entry point.
+
+## v0.2.54 (2025-06-16)
+- Enhanced error message for LuaLock timeout during license validation.
+- Fixed the $contains filter in custom auth by requiring an explicit ::text cast and updated tests accordingly.
+- Ensured project and tenant IDs are formatted as UUIDs for consistency.
+
+## v0.2.53 (2025-06-13)
+- Resolved a timing issue to ensure the queue starts only after the graph is registered.
+- Improved performance by setting thread and run status in a single query and enhanced error handling during checkpoint writes.
+- Reduced the default background grace period to 3 minutes.
+
+## v0.2.52 (2025-06-12)
+- Now logging expected graphs when one is omitted to improve traceability.
+- Implemented a time-to-live (TTL) feature for resumable streams.
+- Improved query efficiency and consistency by adding a unique index and optimizing row locking.
+
+## v0.2.51 (2025-06-12)
+- Handled `CancelledError` by marking tasks as ready to retry, improving error management in worker processes.
+- Added LG API version and request ID to metadata and logs for better tracking.
+- Added LG API version and request ID to metadata and logs to improve traceability.
+- Improved database performance by creating indexes concurrently.
+- Ensured postgres write is committed only after the Redis running marker is set to prevent race conditions.
+- Enhanced query efficiency and reliability by adding a unique index on thread_id/running, optimizing row locks, and ensuring deterministic run selection.
+- Resolved a race condition by ensuring Postgres updates only occur after the Redis running marker is set.
+
+## v0.2.46 (2025-06-07)
+- Introduced a new connection for each operation while preserving transaction characteristics in Threads state `update()` and `bulk()` commands.
+
+## v0.2.45 (2025-06-05)
+- Enhanced streaming feature by incorporating tracing contexts.
+- Removed an unnecessary query from the Crons.search function.
+- Resolved connection reuse issue when scheduling next run for multiple cron jobs.
+- Removed an unnecessary query in the Crons.search function to improve efficiency.
+- Resolved an issue with scheduling the next cron run by improving connection reuse.
+
+## v0.2.44 (2025-06-04)
+- Enhanced the worker logic to exit the pipeline before continuing when the Redis message limit is reached.
+- Introduced a ceiling for Redis message size with an option to skip messages larger than 128 MB for improved performance.
+- Ensured the pipeline always closes properly to prevent resource leaks.
+
+## v0.2.43 (2025-06-04)
+- Improved performance by omitting logs in metadata calls and ensuring output schema compliance in value streaming.
+- Ensured the connection is properly closed after use.
+- Aligned output format to strictly adhere to the specified schema.
+- Stopped sending internal logs in metadata requests to improve privacy.
+
+## v0.2.42 (2025-06-04)
+- Added timestamps to track the start and end of a request's run.
+- Added tracer information to the configuration settings.
+- Added support for streaming with tracing contexts.
+
+## v0.2.41 (2025-06-03)
+- Added locking mechanism to prevent errors in pipelined executions.
diff --git a/docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md b/docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md
new file mode 100644
index 000000000..e90a54cad
--- /dev/null
+++ b/docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md
@@ -0,0 +1,3403 @@
+
+
+
+**[@langchain/langgraph-sdk](https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-js)**
+
+***
+
+## [@langchain/langgraph-sdk](https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-js)
+
+### Classes
+
+- [AssistantsClient](#classesassistantsclientmd)
+- [Client](#classesclientmd)
+- [CronsClient](#classescronsclientmd)
+- [RunsClient](#classesrunsclientmd)
+- [StoreClient](#classesstoreclientmd)
+- [ThreadsClient](#classesthreadsclientmd)
+
+### Interfaces
+
+- [ClientConfig](#interfacesclientconfigmd)
+
+### Functions
+
+- [getApiKey](#functionsgetapikeymd)
+
+
+
+
+**@langchain/langgraph-sdk**
+
+***
+
+## @langchain/langgraph-sdk/auth
+
+### Classes
+
+- [Auth](#authclassesauthmd)
+- [HTTPException](#authclasseshttpexceptionmd)
+
+### Interfaces
+
+- [AuthEventValueMap](#authinterfacesautheventvaluemapmd)
+
+### Type Aliases
+
+- [AuthFilters](#authtype-aliasesauthfiltersmd)
+
+
+
+
+[**@langchain/langgraph-sdk**](#authreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#authreadmemd) / Auth
+
+## Class: Auth\
+
+Defined in: [src/auth/index.ts:11](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/index.ts#L11)
+
+### Type Parameters
+
+• **TExtra** = \{\}
+
+• **TAuthReturn** *extends* `BaseAuthReturn` = `BaseAuthReturn`
+
+• **TUser** *extends* `BaseUser` = `ToUserLike`\<`TAuthReturn`\>
+
+### Constructors
+
+#### new Auth()
+
+> **new Auth**\<`TExtra`, `TAuthReturn`, `TUser`\>(): [`Auth`](#authclassesauthmd)\<`TExtra`, `TAuthReturn`, `TUser`\>
+
+##### Returns
+
+[`Auth`](#authclassesauthmd)\<`TExtra`, `TAuthReturn`, `TUser`\>
+
+### Methods
+
+#### authenticate()
+
+> **authenticate**\<`T`\>(`cb`): [`Auth`](#authclassesauthmd)\<`TExtra`, `T`\>
+
+Defined in: [src/auth/index.ts:25](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/index.ts#L25)
+
+##### Type Parameters
+
+• **T** *extends* `BaseAuthReturn`
+
+##### Parameters
+
+###### cb
+
+`AuthenticateCallback`\<`T`\>
+
+##### Returns
+
+[`Auth`](#authclassesauthmd)\<`TExtra`, `T`\>
+
+***
+
+#### on()
+
+> **on**\<`T`\>(`event`, `callback`): `this`
+
+Defined in: [src/auth/index.ts:32](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/index.ts#L32)
+
+##### Type Parameters
+
+• **T** *extends* `CallbackEvent`
+
+##### Parameters
+
+###### event
+
+`T`
+
+###### callback
+
+`OnCallback`\<`T`, `TUser`\>
+
+##### Returns
+
+`this`
+
+
+
+
+[**@langchain/langgraph-sdk**](#authreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#authreadmemd) / HTTPException
+
+## Class: HTTPException
+
+Defined in: [src/auth/error.ts:66](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/error.ts#L66)
+
+### Extends
+
+- `Error`
+
+### Constructors
+
+#### new HTTPException()
+
+> **new HTTPException**(`status`, `options`?): [`HTTPException`](#authclasseshttpexceptionmd)
+
+Defined in: [src/auth/error.ts:70](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/error.ts#L70)
+
+##### Parameters
+
+###### status
+
+`number`
+
+###### options?
+
+####### cause?
+
+`unknown`
+
+####### headers?
+
+`HeadersInit`
+
+####### message?
+
+`string`
+
+##### Returns
+
+[`HTTPException`](#authclasseshttpexceptionmd)
+
+##### Overrides
+
+`Error.constructor`
+
+### Properties
+
+#### cause?
+
+> `optional` **cause**: `unknown`
+
+Defined in: node\_modules/typescript/lib/lib.es2022.error.d.ts:24
+
+##### Inherited from
+
+`Error.cause`
+
+***
+
+#### headers
+
+> **headers**: `HeadersInit`
+
+Defined in: [src/auth/error.ts:68](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/error.ts#L68)
+
+***
+
+#### message
+
+> **message**: `string`
+
+Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1077
+
+##### Inherited from
+
+`Error.message`
+
+***
+
+#### name
+
+> **name**: `string`
+
+Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1076
+
+##### Inherited from
+
+`Error.name`
+
+***
+
+#### stack?
+
+> `optional` **stack**: `string`
+
+Defined in: node\_modules/typescript/lib/lib.es5.d.ts:1078
+
+##### Inherited from
+
+`Error.stack`
+
+***
+
+#### status
+
+> **status**: `number`
+
+Defined in: [src/auth/error.ts:67](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/error.ts#L67)
+
+***
+
+#### prepareStackTrace()?
+
+> `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any`
+
+Defined in: node\_modules/@types/node/globals.d.ts:28
+
+Optional override for formatting stack traces
+
+##### Parameters
+
+###### err
+
+`Error`
+
+###### stackTraces
+
+`CallSite`[]
+
+##### Returns
+
+`any`
+
+##### See
+
+https://v8.dev/docs/stack-trace-api#customizing-stack-traces
+
+##### Inherited from
+
+`Error.prepareStackTrace`
+
+***
+
+#### stackTraceLimit
+
+> `static` **stackTraceLimit**: `number`
+
+Defined in: node\_modules/@types/node/globals.d.ts:30
+
+##### Inherited from
+
+`Error.stackTraceLimit`
+
+### Methods
+
+#### captureStackTrace()
+
+> `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void`
+
+Defined in: node\_modules/@types/node/globals.d.ts:21
+
+Create .stack property on a target object
+
+##### Parameters
+
+###### targetObject
+
+`object`
+
+###### constructorOpt?
+
+`Function`
+
+##### Returns
+
+`void`
+
+##### Inherited from
+
+`Error.captureStackTrace`
+
+
+
+
+[**@langchain/langgraph-sdk**](#authreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#authreadmemd) / AuthEventValueMap
+
+## Interface: AuthEventValueMap
+
+Defined in: [src/auth/types.ts:218](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L218)
+
+### Properties
+
+#### assistants:create
+
+> **assistants:create**: `object`
+
+Defined in: [src/auth/types.ts:226](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L226)
+
+##### assistant\_id?
+
+> `optional` **assistant\_id**: `Maybe`\<`string`\>
+
+##### config?
+
+> `optional` **config**: `Maybe`\<`AssistantConfig`\>
+
+##### graph\_id
+
+> **graph\_id**: `string`
+
+##### if\_exists?
+
+> `optional` **if\_exists**: `Maybe`\<`"raise"` \| `"do_nothing"`\>
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### name?
+
+> `optional` **name**: `Maybe`\<`string`\>
+
+***
+
+#### assistants:delete
+
+> **assistants:delete**: `object`
+
+Defined in: [src/auth/types.ts:229](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L229)
+
+##### assistant\_id
+
+> **assistant\_id**: `string`
+
+***
+
+#### assistants:read
+
+> **assistants:read**: `object`
+
+Defined in: [src/auth/types.ts:227](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L227)
+
+##### assistant\_id
+
+> **assistant\_id**: `string`
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+***
+
+#### assistants:search
+
+> **assistants:search**: `object`
+
+Defined in: [src/auth/types.ts:230](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L230)
+
+##### graph\_id?
+
+> `optional` **graph\_id**: `Maybe`\<`string`\>
+
+##### limit?
+
+> `optional` **limit**: `Maybe`\<`number`\>
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### offset?
+
+> `optional` **offset**: `Maybe`\<`number`\>
+
+***
+
+#### assistants:update
+
+> **assistants:update**: `object`
+
+Defined in: [src/auth/types.ts:228](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L228)
+
+##### assistant\_id
+
+> **assistant\_id**: `string`
+
+##### config?
+
+> `optional` **config**: `Maybe`\<`AssistantConfig`\>
+
+##### graph\_id?
+
+> `optional` **graph\_id**: `Maybe`\<`string`\>
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### name?
+
+> `optional` **name**: `Maybe`\<`string`\>
+
+##### version?
+
+> `optional` **version**: `Maybe`\<`number`\>
+
+***
+
+#### crons:create
+
+> **crons:create**: `object`
+
+Defined in: [src/auth/types.ts:232](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L232)
+
+##### cron\_id?
+
+> `optional` **cron\_id**: `Maybe`\<`string`\>
+
+##### end\_time?
+
+> `optional` **end\_time**: `Maybe`\<`string`\>
+
+##### payload?
+
+> `optional` **payload**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### schedule
+
+> **schedule**: `string`
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+##### user\_id?
+
+> `optional` **user\_id**: `Maybe`\<`string`\>
+
+***
+
+#### crons:delete
+
+> **crons:delete**: `object`
+
+Defined in: [src/auth/types.ts:235](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L235)
+
+##### cron\_id
+
+> **cron\_id**: `string`
+
+***
+
+#### crons:read
+
+> **crons:read**: `object`
+
+Defined in: [src/auth/types.ts:233](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L233)
+
+##### cron\_id
+
+> **cron\_id**: `string`
+
+***
+
+#### crons:search
+
+> **crons:search**: `object`
+
+Defined in: [src/auth/types.ts:236](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L236)
+
+##### assistant\_id?
+
+> `optional` **assistant\_id**: `Maybe`\<`string`\>
+
+##### limit?
+
+> `optional` **limit**: `Maybe`\<`number`\>
+
+##### offset?
+
+> `optional` **offset**: `Maybe`\<`number`\>
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+***
+
+#### crons:update
+
+> **crons:update**: `object`
+
+Defined in: [src/auth/types.ts:234](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L234)
+
+##### cron\_id
+
+> **cron\_id**: `string`
+
+##### payload?
+
+> `optional` **payload**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### schedule?
+
+> `optional` **schedule**: `Maybe`\<`string`\>
+
+***
+
+#### store:delete
+
+> **store:delete**: `object`
+
+Defined in: [src/auth/types.ts:242](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L242)
+
+##### key
+
+> **key**: `string`
+
+##### namespace?
+
+> `optional` **namespace**: `Maybe`\<`string`[]\>
+
+***
+
+#### store:get
+
+> **store:get**: `object`
+
+Defined in: [src/auth/types.ts:239](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L239)
+
+##### key
+
+> **key**: `string`
+
+##### namespace
+
+> **namespace**: `Maybe`\<`string`[]\>
+
+***
+
+#### store:list\_namespaces
+
+> **store:list\_namespaces**: `object`
+
+Defined in: [src/auth/types.ts:241](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L241)
+
+##### limit?
+
+> `optional` **limit**: `Maybe`\<`number`\>
+
+##### max\_depth?
+
+> `optional` **max\_depth**: `Maybe`\<`number`\>
+
+##### namespace?
+
+> `optional` **namespace**: `Maybe`\<`string`[]\>
+
+##### offset?
+
+> `optional` **offset**: `Maybe`\<`number`\>
+
+##### suffix?
+
+> `optional` **suffix**: `Maybe`\<`string`[]\>
+
+***
+
+#### store:put
+
+> **store:put**: `object`
+
+Defined in: [src/auth/types.ts:238](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L238)
+
+##### key
+
+> **key**: `string`
+
+##### namespace
+
+> **namespace**: `string`[]
+
+##### value
+
+> **value**: `Record`\<`string`, `unknown`\>
+
+***
+
+#### store:search
+
+> **store:search**: `object`
+
+Defined in: [src/auth/types.ts:240](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L240)
+
+##### filter?
+
+> `optional` **filter**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### limit?
+
+> `optional` **limit**: `Maybe`\<`number`\>
+
+##### namespace?
+
+> `optional` **namespace**: `Maybe`\<`string`[]\>
+
+##### offset?
+
+> `optional` **offset**: `Maybe`\<`number`\>
+
+##### query?
+
+> `optional` **query**: `Maybe`\<`string`\>
+
+***
+
+#### threads:create
+
+> **threads:create**: `object`
+
+Defined in: [src/auth/types.ts:219](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L219)
+
+##### if\_exists?
+
+> `optional` **if\_exists**: `Maybe`\<`"raise"` \| `"do_nothing"`\>
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+***
+
+#### threads:create\_run
+
+> **threads:create\_run**: `object`
+
+Defined in: [src/auth/types.ts:224](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L224)
+
+##### after\_seconds?
+
+> `optional` **after\_seconds**: `Maybe`\<`number`\>
+
+##### assistant\_id
+
+> **assistant\_id**: `string`
+
+##### if\_not\_exists?
+
+> `optional` **if\_not\_exists**: `Maybe`\<`"reject"` \| `"create"`\>
+
+##### kwargs
+
+> **kwargs**: `Record`\<`string`, `unknown`\>
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### multitask\_strategy?
+
+> `optional` **multitask\_strategy**: `Maybe`\<`"reject"` \| `"interrupt"` \| `"rollback"` \| `"enqueue"`\>
+
+##### prevent\_insert\_if\_inflight?
+
+> `optional` **prevent\_insert\_if\_inflight**: `Maybe`\<`boolean`\>
+
+##### run\_id
+
+> **run\_id**: `string`
+
+##### status
+
+> **status**: `Maybe`\<`"pending"` \| `"running"` \| `"error"` \| `"success"` \| `"timeout"` \| `"interrupted"`\>
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+***
+
+#### threads:delete
+
+> **threads:delete**: `object`
+
+Defined in: [src/auth/types.ts:222](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L222)
+
+##### run\_id?
+
+> `optional` **run\_id**: `Maybe`\<`string`\>
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+***
+
+#### threads:read
+
+> **threads:read**: `object`
+
+Defined in: [src/auth/types.ts:220](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L220)
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+***
+
+#### threads:search
+
+> **threads:search**: `object`
+
+Defined in: [src/auth/types.ts:223](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L223)
+
+##### limit?
+
+> `optional` **limit**: `Maybe`\<`number`\>
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### offset?
+
+> `optional` **offset**: `Maybe`\<`number`\>
+
+##### status?
+
+> `optional` **status**: `Maybe`\<`"error"` \| `"interrupted"` \| `"idle"` \| `"busy"` \| `string` & `object`\>
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+##### values?
+
+> `optional` **values**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+***
+
+#### threads:update
+
+> **threads:update**: `object`
+
+Defined in: [src/auth/types.ts:221](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L221)
+
+##### action?
+
+> `optional` **action**: `Maybe`\<`"interrupt"` \| `"rollback"`\>
+
+##### metadata?
+
+> `optional` **metadata**: `Maybe`\<`Record`\<`string`, `unknown`\>\>
+
+##### thread\_id?
+
+> `optional` **thread\_id**: `Maybe`\<`string`\>
+
+
+
+
+[**@langchain/langgraph-sdk**](#authreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#authreadmemd) / AuthFilters
+
+## Type Alias: AuthFilters\
+
+> **AuthFilters**\<`TKey`\>: \{ \[key in TKey\]: string \| \{ \[op in "$contains" \| "$eq"\]?: string \} \}
+
+Defined in: [src/auth/types.ts:367](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/auth/types.ts#L367)
+
+### Type Parameters
+
+• **TKey** *extends* `string` \| `number` \| `symbol`
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / AssistantsClient
+
+## Class: AssistantsClient
+
+Defined in: [client.ts:294](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L294)
+
+### Extends
+
+- `BaseClient`
+
+### Constructors
+
+#### new AssistantsClient()
+
+> **new AssistantsClient**(`config`?): [`AssistantsClient`](#classesassistantsclientmd)
+
+Defined in: [client.ts:88](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L88)
+
+##### Parameters
+
+###### config?
+
+[`ClientConfig`](#interfacesclientconfigmd)
+
+##### Returns
+
+[`AssistantsClient`](#classesassistantsclientmd)
+
+##### Inherited from
+
+`BaseClient.constructor`
+
+### Methods
+
+#### create()
+
+> **create**(`payload`): `Promise`\<`Assistant`\>
+
+Defined in: [client.ts:359](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L359)
+
+Create a new assistant.
+
+##### Parameters
+
+###### payload
+
+Payload for creating an assistant.
+
+####### assistantId?
+
+`string`
+
+####### config?
+
+`Config`
+
+####### description?
+
+`string`
+
+####### graphId
+
+`string`
+
+####### ifExists?
+
+`OnConflictBehavior`
+
+####### metadata?
+
+`Metadata`
+
+####### name?
+
+`string`
+
+##### Returns
+
+`Promise`\<`Assistant`\>
+
+The created assistant.
+
+***
+
+#### delete()
+
+> **delete**(`assistantId`): `Promise`\<`void`\>
+
+Defined in: [client.ts:415](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L415)
+
+Delete an assistant.
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+ID of the assistant.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+***
+
+#### get()
+
+> **get**(`assistantId`): `Promise`\<`Assistant`\>
+
+Defined in: [client.ts:301](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L301)
+
+Get an assistant by ID.
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+The ID of the assistant.
+
+##### Returns
+
+`Promise`\<`Assistant`\>
+
+Assistant
+
+***
+
+#### getGraph()
+
+> **getGraph**(`assistantId`, `options`?): `Promise`\<`AssistantGraph`\>
+
+Defined in: [client.ts:311](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L311)
+
+Get the JSON representation of the graph assigned to a runnable
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+The ID of the assistant.
+
+###### options?
+
+####### xray?
+
+`number` \| `boolean`
+
+Whether to include subgraphs in the serialized graph representation. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included.
+
+##### Returns
+
+`Promise`\<`AssistantGraph`\>
+
+Serialized graph
+
+***
+
+#### getSchemas()
+
+> **getSchemas**(`assistantId`): `Promise`\<`GraphSchema`\>
+
+Defined in: [client.ts:325](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L325)
+
+Get the state and config schema of the graph assigned to a runnable
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+The ID of the assistant.
+
+##### Returns
+
+`Promise`\<`GraphSchema`\>
+
+Graph schema
+
+***
+
+#### getSubgraphs()
+
+> **getSubgraphs**(`assistantId`, `options`?): `Promise`\<`Subgraphs`\>
+
+Defined in: [client.ts:336](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L336)
+
+Get the schemas of an assistant by ID.
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+The ID of the assistant to get the schema of.
+
+###### options?
+
+Additional options for getting subgraphs, such as namespace or recursion extraction.
+
+####### namespace?
+
+`string`
+
+####### recurse?
+
+`boolean`
+
+##### Returns
+
+`Promise`\<`Subgraphs`\>
+
+The subgraphs of the assistant.
+
+***
+
+#### getVersions()
+
+> **getVersions**(`assistantId`, `payload`?): `Promise`\<`AssistantVersion`[]\>
+
+Defined in: [client.ts:453](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L453)
+
+List all versions of an assistant.
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+ID of the assistant.
+
+###### payload?
+
+####### limit?
+
+`number`
+
+####### metadata?
+
+`Metadata`
+
+####### offset?
+
+`number`
+
+##### Returns
+
+`Promise`\<`AssistantVersion`[]\>
+
+List of assistant versions.
+
+***
+
+#### search()
+
+> **search**(`query`?): `Promise`\<`Assistant`[]\>
+
+Defined in: [client.ts:426](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L426)
+
+List assistants.
+
+##### Parameters
+
+###### query?
+
+Query options.
+
+####### graphId?
+
+`string`
+
+####### limit?
+
+`number`
+
+####### metadata?
+
+`Metadata`
+
+####### offset?
+
+`number`
+
+####### sortBy?
+
+`AssistantSortBy`
+
+####### sortOrder?
+
+`SortOrder`
+
+##### Returns
+
+`Promise`\<`Assistant`[]\>
+
+List of assistants.
+
+***
+
+#### setLatest()
+
+> **setLatest**(`assistantId`, `version`): `Promise`\<`Assistant`\>
+
+Defined in: [client.ts:481](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L481)
+
+Change the version of an assistant.
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+ID of the assistant.
+
+###### version
+
+`number`
+
+The version to change to.
+
+##### Returns
+
+`Promise`\<`Assistant`\>
+
+The updated assistant.
+
+***
+
+#### update()
+
+> **update**(`assistantId`, `payload`): `Promise`\<`Assistant`\>
+
+Defined in: [client.ts:388](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L388)
+
+Update an assistant.
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+ID of the assistant.
+
+###### payload
+
+Payload for updating the assistant.
+
+####### config?
+
+`Config`
+
+####### description?
+
+`string`
+
+####### graphId?
+
+`string`
+
+####### metadata?
+
+`Metadata`
+
+####### name?
+
+`string`
+
+##### Returns
+
+`Promise`\<`Assistant`\>
+
+The updated assistant.
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / Client
+
+## Class: Client\
+
+Defined in: [client.ts:1448](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1448)
+
+### Type Parameters
+
+• **TStateType** = `DefaultValues`
+
+• **TUpdateType** = `TStateType`
+
+• **TCustomEventType** = `unknown`
+
+### Constructors
+
+#### new Client()
+
+> **new Client**\<`TStateType`, `TUpdateType`, `TCustomEventType`\>(`config`?): [`Client`](#classesclientmd)\<`TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+Defined in: [client.ts:1484](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1484)
+
+##### Parameters
+
+###### config?
+
+[`ClientConfig`](#interfacesclientconfigmd)
+
+##### Returns
+
+[`Client`](#classesclientmd)\<`TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+### Properties
+
+#### ~ui
+
+> **~ui**: `UiClient`
+
+Defined in: [client.ts:1482](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1482)
+
+**`Internal`**
+
+The client for interacting with the UI.
+ Used by LoadExternalComponent and the API might change in the future.
+
+***
+
+#### assistants
+
+> **assistants**: [`AssistantsClient`](#classesassistantsclientmd)
+
+Defined in: [client.ts:1456](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1456)
+
+The client for interacting with assistants.
+
+***
+
+#### crons
+
+> **crons**: [`CronsClient`](#classescronsclientmd)
+
+Defined in: [client.ts:1471](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1471)
+
+The client for interacting with cron runs.
+
+***
+
+#### runs
+
+> **runs**: [`RunsClient`](#classesrunsclientmd)\<`TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+Defined in: [client.ts:1466](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1466)
+
+The client for interacting with runs.
+
+***
+
+#### store
+
+> **store**: [`StoreClient`](#classesstoreclientmd)
+
+Defined in: [client.ts:1476](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1476)
+
+The client for interacting with the KV store.
+
+***
+
+#### threads
+
+> **threads**: [`ThreadsClient`](#classesthreadsclientmd)\<`TStateType`, `TUpdateType`\>
+
+Defined in: [client.ts:1461](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1461)
+
+The client for interacting with threads.
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / CronsClient
+
+## Class: CronsClient
+
+Defined in: [client.ts:197](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L197)
+
+### Extends
+
+- `BaseClient`
+
+### Constructors
+
+#### new CronsClient()
+
+> **new CronsClient**(`config`?): [`CronsClient`](#classescronsclientmd)
+
+Defined in: [client.ts:88](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L88)
+
+##### Parameters
+
+###### config?
+
+[`ClientConfig`](#interfacesclientconfigmd)
+
+##### Returns
+
+[`CronsClient`](#classescronsclientmd)
+
+##### Inherited from
+
+`BaseClient.constructor`
+
+### Methods
+
+#### create()
+
+> **create**(`assistantId`, `payload`?): `Promise`\<`CronCreateResponse`\>
+
+Defined in: [client.ts:238](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L238)
+
+##### Parameters
+
+###### assistantId
+
+`string`
+
+Assistant ID to use for this cron job.
+
+###### payload?
+
+`CronsCreatePayload`
+
+Payload for creating a cron job.
+
+##### Returns
+
+`Promise`\<`CronCreateResponse`\>
+
+***
+
+#### createForThread()
+
+> **createForThread**(`threadId`, `assistantId`, `payload`?): `Promise`\<`CronCreateForThreadResponse`\>
+
+Defined in: [client.ts:205](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L205)
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### assistantId
+
+`string`
+
+Assistant ID to use for this cron job.
+
+###### payload?
+
+`CronsCreatePayload`
+
+Payload for creating a cron job.
+
+##### Returns
+
+`Promise`\<`CronCreateForThreadResponse`\>
+
+The created background run.
+
+***
+
+#### delete()
+
+> **delete**(`cronId`): `Promise`\<`void`\>
+
+Defined in: [client.ts:265](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L265)
+
+##### Parameters
+
+###### cronId
+
+`string`
+
+Cron ID of Cron job to delete.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+***
+
+#### search()
+
+> **search**(`query`?): `Promise`\<`Cron`[]\>
+
+Defined in: [client.ts:276](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L276)
+
+##### Parameters
+
+###### query?
+
+Query options.
+
+####### assistantId?
+
+`string`
+
+####### limit?
+
+`number`
+
+####### offset?
+
+`number`
+
+####### threadId?
+
+`string`
+
+##### Returns
+
+`Promise`\<`Cron`[]\>
+
+List of crons.
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / RunsClient
+
+## Class: RunsClient\
+
+Defined in: [client.ts:776](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L776)
+
+### Extends
+
+- `BaseClient`
+
+### Type Parameters
+
+• **TStateType** = `DefaultValues`
+
+• **TUpdateType** = `TStateType`
+
+• **TCustomEventType** = `unknown`
+
+### Constructors
+
+#### new RunsClient()
+
+> **new RunsClient**\<`TStateType`, `TUpdateType`, `TCustomEventType`\>(`config`?): [`RunsClient`](#classesrunsclientmd)\<`TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+Defined in: [client.ts:88](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L88)
+
+##### Parameters
+
+###### config?
+
+[`ClientConfig`](#interfacesclientconfigmd)
+
+##### Returns
+
+[`RunsClient`](#classesrunsclientmd)\<`TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+##### Inherited from
+
+`BaseClient.constructor`
+
+### Methods
+
+#### cancel()
+
+> **cancel**(`threadId`, `runId`, `wait`, `action`): `Promise`\<`void`\>
+
+Defined in: [client.ts:1063](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1063)
+
+Cancel a run.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### runId
+
+`string`
+
+The ID of the run.
+
+###### wait
+
+`boolean` = `false`
+
+Whether to block when canceling
+
+###### action
+
+`CancelAction` = `"interrupt"`
+
+Action to take when cancelling the run. Possible values are `interrupt` or `rollback`. Default is `interrupt`.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+***
+
+#### create()
+
+> **create**(`threadId`, `assistantId`, `payload`?): `Promise`\<`Run`\>
+
+Defined in: [client.ts:885](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L885)
+
+Create a run.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### assistantId
+
+`string`
+
+Assistant ID to use for this run.
+
+###### payload?
+
+`RunsCreatePayload`
+
+Payload for creating a run.
+
+##### Returns
+
+`Promise`\<`Run`\>
+
+The created run.
+
+***
+
+#### createBatch()
+
+> **createBatch**(`payloads`): `Promise`\<`Run`[]\>
+
+Defined in: [client.ts:921](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L921)
+
+Create a batch of stateless background runs.
+
+##### Parameters
+
+###### payloads
+
+`RunsCreatePayload` & `object`[]
+
+An array of payloads for creating runs.
+
+##### Returns
+
+`Promise`\<`Run`[]\>
+
+An array of created runs.
+
+***
+
+#### delete()
+
+> **delete**(`threadId`, `runId`): `Promise`\<`void`\>
+
+Defined in: [client.ts:1157](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1157)
+
+Delete a run.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### runId
+
+`string`
+
+The ID of the run.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+***
+
+#### get()
+
+> **get**(`threadId`, `runId`): `Promise`\<`Run`\>
+
+Defined in: [client.ts:1050](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1050)
+
+Get a run by ID.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### runId
+
+`string`
+
+The ID of the run.
+
+##### Returns
+
+`Promise`\<`Run`\>
+
+The run.
+
+***
+
+#### join()
+
+> **join**(`threadId`, `runId`, `options`?): `Promise`\<`void`\>
+
+Defined in: [client.ts:1085](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1085)
+
+Block until a run is done.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### runId
+
+`string`
+
+The ID of the run.
+
+###### options?
+
+####### signal?
+
+`AbortSignal`
+
+##### Returns
+
+`Promise`\<`void`\>
+
+***
+
+#### joinStream()
+
+> **joinStream**(`threadId`, `runId`, `options`?): `AsyncGenerator`\<\{ `data`: `any`; `event`: `StreamEvent`; \}\>
+
+Defined in: [client.ts:1111](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1111)
+
+Stream output from a run in real-time, until the run is done.
+Output is not buffered, so any output produced before this call will
+not be received here.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### runId
+
+`string`
+
+The ID of the run.
+
+###### options?
+
+Additional options for controlling the stream behavior:
+ - signal: An AbortSignal that can be used to cancel the stream request
+ - cancelOnDisconnect: When true, automatically cancels the run if the client disconnects from the stream
+ - streamMode: Controls what types of events to receive from the stream (can be a single mode or array of modes)
+ Must be a subset of the stream modes passed when creating the run. Background runs default to having the union of all
+ stream modes enabled.
+
+`AbortSignal` | \{ `cancelOnDisconnect`: `boolean`; `signal`: `AbortSignal`; `streamMode`: `StreamMode` \| `StreamMode`[]; \}
+
+##### Returns
+
+`AsyncGenerator`\<\{ `data`: `any`; `event`: `StreamEvent`; \}\>
+
+An async generator yielding stream parts.
+
+***
+
+#### list()
+
+> **list**(`threadId`, `options`?): `Promise`\<`Run`[]\>
+
+Defined in: [client.ts:1013](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1013)
+
+List all runs for a thread.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### options?
+
+Filtering and pagination options.
+
+####### limit?
+
+`number`
+
+Maximum number of runs to return.
+Defaults to 10
+
+####### offset?
+
+`number`
+
+Offset to start from.
+Defaults to 0.
+
+####### status?
+
+`RunStatus`
+
+Status of the run to filter by.
+
+##### Returns
+
+`Promise`\<`Run`[]\>
+
+List of runs.
+
+***
+
+#### stream()
+
+Create a run and stream the results.
+
+##### Param
+
+The ID of the thread.
+
+##### Param
+
+Assistant ID to use for this run.
+
+##### Param
+
+Payload for creating a run.
+
+##### Call Signature
+
+> **stream**\<`TStreamMode`, `TSubgraphs`\>(`threadId`, `assistantId`, `payload`?): `TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+Defined in: [client.ts:781](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L781)
+
+###### Type Parameters
+
+• **TStreamMode** *extends* `StreamMode` \| `StreamMode`[] = `StreamMode`
+
+• **TSubgraphs** *extends* `boolean` = `false`
+
+###### Parameters
+
+####### threadId
+
+`null`
+
+####### assistantId
+
+`string`
+
+####### payload?
+
+`Omit`\<`RunsStreamPayload`\<`TStreamMode`, `TSubgraphs`\>, `"multitaskStrategy"` \| `"onCompletion"`\>
+
+###### Returns
+
+`TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+##### Call Signature
+
+> **stream**\<`TStreamMode`, `TSubgraphs`\>(`threadId`, `assistantId`, `payload`?): `TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+Defined in: [client.ts:799](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L799)
+
+###### Type Parameters
+
+• **TStreamMode** *extends* `StreamMode` \| `StreamMode`[] = `StreamMode`
+
+• **TSubgraphs** *extends* `boolean` = `false`
+
+###### Parameters
+
+####### threadId
+
+`string`
+
+####### assistantId
+
+`string`
+
+####### payload?
+
+`RunsStreamPayload`\<`TStreamMode`, `TSubgraphs`\>
+
+###### Returns
+
+`TypedAsyncGenerator`\<`TStreamMode`, `TSubgraphs`, `TStateType`, `TUpdateType`, `TCustomEventType`\>
+
+***
+
+#### wait()
+
+Create a run and wait for it to complete.
+
+##### Param
+
+The ID of the thread.
+
+##### Param
+
+Assistant ID to use for this run.
+
+##### Param
+
+Payload for creating a run.
+
+##### Call Signature
+
+> **wait**(`threadId`, `assistantId`, `payload`?): `Promise`\<`DefaultValues`\>
+
+Defined in: [client.ts:938](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L938)
+
+###### Parameters
+
+####### threadId
+
+`null`
+
+####### assistantId
+
+`string`
+
+####### payload?
+
+`Omit`\<`RunsWaitPayload`, `"multitaskStrategy"` \| `"onCompletion"`\>
+
+###### Returns
+
+`Promise`\<`DefaultValues`\>
+
+##### Call Signature
+
+> **wait**(`threadId`, `assistantId`, `payload`?): `Promise`\<`DefaultValues`\>
+
+Defined in: [client.ts:944](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L944)
+
+###### Parameters
+
+####### threadId
+
+`string`
+
+####### assistantId
+
+`string`
+
+####### payload?
+
+`RunsWaitPayload`
+
+###### Returns
+
+`Promise`\<`DefaultValues`\>
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / StoreClient
+
+## Class: StoreClient
+
+Defined in: [client.ts:1175](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1175)
+
+### Extends
+
+- `BaseClient`
+
+### Constructors
+
+#### new StoreClient()
+
+> **new StoreClient**(`config`?): [`StoreClient`](#classesstoreclientmd)
+
+Defined in: [client.ts:88](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L88)
+
+##### Parameters
+
+###### config?
+
+[`ClientConfig`](#interfacesclientconfigmd)
+
+##### Returns
+
+[`StoreClient`](#classesstoreclientmd)
+
+##### Inherited from
+
+`BaseClient.constructor`
+
+### Methods
+
+#### deleteItem()
+
+> **deleteItem**(`namespace`, `key`): `Promise`\<`void`\>
+
+Defined in: [client.ts:1296](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1296)
+
+Delete an item.
+
+##### Parameters
+
+###### namespace
+
+`string`[]
+
+A list of strings representing the namespace path.
+
+###### key
+
+`string`
+
+The unique identifier for the item.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+Promise
+
+***
+
+#### getItem()
+
+> **getItem**(`namespace`, `key`, `options`?): `Promise`\<`null` \| `Item`\>
+
+Defined in: [client.ts:1252](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1252)
+
+Retrieve a single item.
+
+##### Parameters
+
+###### namespace
+
+`string`[]
+
+A list of strings representing the namespace path.
+
+###### key
+
+`string`
+
+The unique identifier for the item.
+
+###### options?
+
+####### refreshTtl?
+
+`null` \| `boolean`
+
+Whether to refresh the TTL on this read operation. If null, uses the store's default behavior.
+
+##### Returns
+
+`Promise`\<`null` \| `Item`\>
+
+Promise
+
+##### Example
+
+```typescript
+const item = await client.store.getItem(
+ ["documents", "user123"],
+ "item456",
+ { refreshTtl: true }
+);
+console.log(item);
+// {
+// namespace: ["documents", "user123"],
+// key: "item456",
+// value: { title: "My Document", content: "Hello World" },
+// createdAt: "2024-07-30T12:00:00Z",
+// updatedAt: "2024-07-30T12:00:00Z"
+// }
+```
+
+***
+
+#### listNamespaces()
+
+> **listNamespaces**(`options`?): `Promise`\<`ListNamespaceResponse`\>
+
+Defined in: [client.ts:1392](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1392)
+
+List namespaces with optional match conditions.
+
+##### Parameters
+
+###### options?
+
+####### limit?
+
+`number`
+
+Maximum number of namespaces to return (default is 100).
+
+####### maxDepth?
+
+`number`
+
+Optional integer specifying the maximum depth of namespaces to return.
+
+####### offset?
+
+`number`
+
+Number of namespaces to skip before returning results (default is 0).
+
+####### prefix?
+
+`string`[]
+
+Optional list of strings representing the prefix to filter namespaces.
+
+####### suffix?
+
+`string`[]
+
+Optional list of strings representing the suffix to filter namespaces.
+
+##### Returns
+
+`Promise`\<`ListNamespaceResponse`\>
+
+Promise
+
+***
+
+#### putItem()
+
+> **putItem**(`namespace`, `key`, `value`, `options`?): `Promise`\<`void`\>
+
+Defined in: [client.ts:1196](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1196)
+
+Store or update an item.
+
+##### Parameters
+
+###### namespace
+
+`string`[]
+
+A list of strings representing the namespace path.
+
+###### key
+
+`string`
+
+The unique identifier for the item within the namespace.
+
+###### value
+
+`Record`\<`string`, `any`\>
+
+A dictionary containing the item's data.
+
+###### options?
+
+####### index?
+
+`null` \| `false` \| `string`[]
+
+Controls search indexing - null (use defaults), false (disable), or list of field paths to index.
+
+####### ttl?
+
+`null` \| `number`
+
+Optional time-to-live in minutes for the item, or null for no expiration.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+Promise
+
+##### Example
+
+```typescript
+await client.store.putItem(
+ ["documents", "user123"],
+ "item456",
+ { title: "My Document", content: "Hello World" },
+ { ttl: 60 } // expires in 60 minutes
+);
+```
+
+***
+
+#### searchItems()
+
+> **searchItems**(`namespacePrefix`, `options`?): `Promise`\<`SearchItemsResponse`\>
+
+Defined in: [client.ts:1347](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L1347)
+
+Search for items within a namespace prefix.
+
+##### Parameters
+
+###### namespacePrefix
+
+`string`[]
+
+List of strings representing the namespace prefix.
+
+###### options?
+
+####### filter?
+
+`Record`\<`string`, `any`\>
+
+Optional dictionary of key-value pairs to filter results.
+
+####### limit?
+
+`number`
+
+Maximum number of items to return (default is 10).
+
+####### offset?
+
+`number`
+
+Number of items to skip before returning results (default is 0).
+
+####### query?
+
+`string`
+
+Optional search query.
+
+####### refreshTtl?
+
+`null` \| `boolean`
+
+Whether to refresh the TTL on items returned by this search. If null, uses the store's default behavior.
+
+##### Returns
+
+`Promise`\<`SearchItemsResponse`\>
+
+Promise
+
+##### Example
+
+```typescript
+const results = await client.store.searchItems(
+ ["documents"],
+ {
+ filter: { author: "John Doe" },
+ limit: 5,
+ refreshTtl: true
+ }
+);
+console.log(results);
+// {
+// items: [
+// {
+// namespace: ["documents", "user123"],
+// key: "item789",
+// value: { title: "Another Document", author: "John Doe" },
+// createdAt: "2024-07-30T12:00:00Z",
+// updatedAt: "2024-07-30T12:00:00Z"
+// },
+// // ... additional items ...
+// ]
+// }
+```
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / ThreadsClient
+
+## Class: ThreadsClient\
+
+Defined in: [client.ts:489](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L489)
+
+### Extends
+
+- `BaseClient`
+
+### Type Parameters
+
+• **TStateType** = `DefaultValues`
+
+• **TUpdateType** = `TStateType`
+
+### Constructors
+
+#### new ThreadsClient()
+
+> **new ThreadsClient**\<`TStateType`, `TUpdateType`\>(`config`?): [`ThreadsClient`](#classesthreadsclientmd)\<`TStateType`, `TUpdateType`\>
+
+Defined in: [client.ts:88](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L88)
+
+##### Parameters
+
+###### config?
+
+[`ClientConfig`](#interfacesclientconfigmd)
+
+##### Returns
+
+[`ThreadsClient`](#classesthreadsclientmd)\<`TStateType`, `TUpdateType`\>
+
+##### Inherited from
+
+`BaseClient.constructor`
+
+### Methods
+
+#### copy()
+
+> **copy**(`threadId`): `Promise`\<`Thread`\<`TStateType`\>\>
+
+Defined in: [client.ts:566](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L566)
+
+Copy an existing thread
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+ID of the thread to be copied
+
+##### Returns
+
+`Promise`\<`Thread`\<`TStateType`\>\>
+
+Newly copied thread
+
+***
+
+#### create()
+
+> **create**(`payload`?): `Promise`\<`Thread`\<`TStateType`\>\>
+
+Defined in: [client.ts:511](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L511)
+
+Create a new thread.
+
+##### Parameters
+
+###### payload?
+
+Payload for creating a thread.
+
+####### graphId?
+
+`string`
+
+Graph ID to associate with the thread.
+
+####### ifExists?
+
+`OnConflictBehavior`
+
+How to handle duplicate creation.
+
+**Default**
+
+```ts
+"raise"
+```
+
+####### metadata?
+
+`Metadata`
+
+Metadata for the thread.
+
+####### supersteps?
+
+`object`[]
+
+Apply a list of supersteps when creating a thread, each containing a sequence of updates.
+
+Used for copying a thread between deployments.
+
+####### threadId?
+
+`string`
+
+ID of the thread to create.
+
+If not provided, a random UUID will be generated.
+
+##### Returns
+
+`Promise`\<`Thread`\<`TStateType`\>\>
+
+The created thread.
+
+***
+
+#### delete()
+
+> **delete**(`threadId`): `Promise`\<`void`\>
+
+Defined in: [client.ts:599](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L599)
+
+Delete a thread.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+ID of the thread.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+***
+
+#### get()
+
+> **get**\<`ValuesType`\>(`threadId`): `Promise`\<`Thread`\<`ValuesType`\>\>
+
+Defined in: [client.ts:499](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L499)
+
+Get a thread by ID.
+
+##### Type Parameters
+
+• **ValuesType** = `TStateType`
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+ID of the thread.
+
+##### Returns
+
+`Promise`\<`Thread`\<`ValuesType`\>\>
+
+The thread.
+
+***
+
+#### getHistory()
+
+> **getHistory**\<`ValuesType`\>(`threadId`, `options`?): `Promise`\<`ThreadState`\<`ValuesType`\>[]\>
+
+Defined in: [client.ts:752](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L752)
+
+Get all past states for a thread.
+
+##### Type Parameters
+
+• **ValuesType** = `TStateType`
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+ID of the thread.
+
+###### options?
+
+Additional options.
+
+####### before?
+
+`Config`
+
+####### checkpoint?
+
+`Partial`\<`Omit`\<`Checkpoint`, `"thread_id"`\>\>
+
+####### limit?
+
+`number`
+
+####### metadata?
+
+`Metadata`
+
+##### Returns
+
+`Promise`\<`ThreadState`\<`ValuesType`\>[]\>
+
+List of thread states.
+
+***
+
+#### getState()
+
+> **getState**\<`ValuesType`\>(`threadId`, `checkpoint`?, `options`?): `Promise`\<`ThreadState`\<`ValuesType`\>\>
+
+Defined in: [client.ts:659](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L659)
+
+Get state for a thread.
+
+##### Type Parameters
+
+• **ValuesType** = `TStateType`
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+ID of the thread.
+
+###### checkpoint?
+
+`string` | `Checkpoint`
+
+###### options?
+
+####### subgraphs?
+
+`boolean`
+
+##### Returns
+
+`Promise`\<`ThreadState`\<`ValuesType`\>\>
+
+Thread state.
+
+***
+
+#### patchState()
+
+> **patchState**(`threadIdOrConfig`, `metadata`): `Promise`\<`void`\>
+
+Defined in: [client.ts:722](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L722)
+
+Patch the metadata of a thread.
+
+##### Parameters
+
+###### threadIdOrConfig
+
+Thread ID or config to patch the state of.
+
+`string` | `Config`
+
+###### metadata
+
+`Metadata`
+
+Metadata to patch the state with.
+
+##### Returns
+
+`Promise`\<`void`\>
+
+***
+
+#### search()
+
+> **search**\<`ValuesType`\>(`query`?): `Promise`\<`Thread`\<`ValuesType`\>[]\>
+
+Defined in: [client.ts:611](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L611)
+
+List threads
+
+##### Type Parameters
+
+• **ValuesType** = `TStateType`
+
+##### Parameters
+
+###### query?
+
+Query options
+
+####### limit?
+
+`number`
+
+Maximum number of threads to return.
+Defaults to 10
+
+####### metadata?
+
+`Metadata`
+
+Metadata to filter threads by.
+
+####### offset?
+
+`number`
+
+Offset to start from.
+
+####### sortBy?
+
+`ThreadSortBy`
+
+Sort by.
+
+####### sortOrder?
+
+`SortOrder`
+
+Sort order.
+Must be one of 'asc' or 'desc'.
+
+####### status?
+
+`ThreadStatus`
+
+Thread status to filter on.
+Must be one of 'idle', 'busy', 'interrupted' or 'error'.
+
+##### Returns
+
+`Promise`\<`Thread`\<`ValuesType`\>[]\>
+
+List of threads
+
+***
+
+#### update()
+
+> **update**(`threadId`, `payload`?): `Promise`\<`Thread`\<`DefaultValues`\>\>
+
+Defined in: [client.ts:579](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L579)
+
+Update a thread.
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+ID of the thread.
+
+###### payload?
+
+Payload for updating the thread.
+
+####### metadata?
+
+`Metadata`
+
+Metadata for the thread.
+
+##### Returns
+
+`Promise`\<`Thread`\<`DefaultValues`\>\>
+
+The updated thread.
+
+***
+
+#### updateState()
+
+> **updateState**\<`ValuesType`\>(`threadId`, `options`): `Promise`\<`Pick`\<`Config`, `"configurable"`\>\>
+
+Defined in: [client.ts:693](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L693)
+
+Add state to a thread.
+
+##### Type Parameters
+
+• **ValuesType** = `TUpdateType`
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+The ID of the thread.
+
+###### options
+
+####### asNode?
+
+`string`
+
+####### checkpoint?
+
+`Checkpoint`
+
+####### checkpointId?
+
+`string`
+
+####### values
+
+`ValuesType`
+
+##### Returns
+
+`Promise`\<`Pick`\<`Config`, `"configurable"`\>\>
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / getApiKey
+
+## Function: getApiKey()
+
+> **getApiKey**(`apiKey`?): `undefined` \| `string`
+
+Defined in: [client.ts:53](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L53)
+
+Get the API key from the environment.
+Precedence:
+ 1. explicit argument
+ 2. LANGGRAPH_API_KEY
+ 3. LANGSMITH_API_KEY
+ 4. LANGCHAIN_API_KEY
+
+### Parameters
+
+#### apiKey?
+
+`string`
+
+Optional API key provided as an argument
+
+### Returns
+
+`undefined` \| `string`
+
+The API key if found, otherwise undefined
+
+
+
+
+[**@langchain/langgraph-sdk**](#readmemd)
+
+***
+
+[@langchain/langgraph-sdk](#readmemd) / ClientConfig
+
+## Interface: ClientConfig
+
+Defined in: [client.ts:71](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L71)
+
+### Properties
+
+#### apiKey?
+
+> `optional` **apiKey**: `string`
+
+Defined in: [client.ts:73](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L73)
+
+***
+
+#### apiUrl?
+
+> `optional` **apiUrl**: `string`
+
+Defined in: [client.ts:72](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L72)
+
+***
+
+#### callerOptions?
+
+> `optional` **callerOptions**: `AsyncCallerParams`
+
+Defined in: [client.ts:74](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L74)
+
+***
+
+#### defaultHeaders?
+
+> `optional` **defaultHeaders**: `Record`\<`string`, `undefined` \| `null` \| `string`\>
+
+Defined in: [client.ts:76](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L76)
+
+***
+
+#### timeoutMs?
+
+> `optional` **timeoutMs**: `number`
+
+Defined in: [client.ts:75](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/client.ts#L75)
+
+
+
+
+**@langchain/langgraph-sdk**
+
+***
+
+## @langchain/langgraph-sdk/react
+
+### Interfaces
+
+- [UseStream](#reactinterfacesusestreammd)
+- [UseStreamOptions](#reactinterfacesusestreamoptionsmd)
+
+### Type Aliases
+
+- [MessageMetadata](#reacttype-aliasesmessagemetadatamd)
+
+### Functions
+
+- [useStream](#reactfunctionsusestreammd)
+
+
+
+
+[**@langchain/langgraph-sdk**](#reactreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#reactreadmemd) / useStream
+
+## Function: useStream()
+
+> **useStream**\<`StateType`, `Bag`\>(`options`): [`UseStream`](#reactinterfacesusestreammd)\<`StateType`, `Bag`\>
+
+Defined in: [react/stream.tsx:618](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L618)
+
+### Type Parameters
+
+• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\>
+
+• **Bag** *extends* `object` = `BagTemplate`
+
+### Parameters
+
+#### options
+
+[`UseStreamOptions`](#reactinterfacesusestreamoptionsmd)\<`StateType`, `Bag`\>
+
+### Returns
+
+[`UseStream`](#reactinterfacesusestreammd)\<`StateType`, `Bag`\>
+
+
+
+
+[**@langchain/langgraph-sdk**](#reactreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#reactreadmemd) / UseStream
+
+## Interface: UseStream\
+
+Defined in: [react/stream.tsx:507](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L507)
+
+### Type Parameters
+
+• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\>
+
+• **Bag** *extends* `BagTemplate` = `BagTemplate`
+
+### Properties
+
+#### assistantId
+
+> **assistantId**: `string`
+
+Defined in: [react/stream.tsx:592](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L592)
+
+The ID of the assistant to use.
+
+***
+
+#### branch
+
+> **branch**: `string`
+
+Defined in: [react/stream.tsx:542](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L542)
+
+The current branch of the thread.
+
+***
+
+#### client
+
+> **client**: `Client`
+
+Defined in: [react/stream.tsx:587](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L587)
+
+LangGraph SDK client used to send request and receive responses.
+
+***
+
+#### error
+
+> **error**: `unknown`
+
+Defined in: [react/stream.tsx:519](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L519)
+
+Last seen error from the thread or during streaming.
+
+***
+
+#### experimental\_branchTree
+
+> **experimental\_branchTree**: `Sequence`\<`StateType`\>
+
+Defined in: [react/stream.tsx:558](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L558)
+
+**`Experimental`**
+
+Tree of all branches for the thread.
+
+***
+
+#### getMessagesMetadata()
+
+> **getMessagesMetadata**: (`message`, `index`?) => `undefined` \| [`MessageMetadata`](#reacttype-aliasesmessagemetadatamd)\<`StateType`\>
+
+Defined in: [react/stream.tsx:579](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L579)
+
+Get the metadata for a message, such as first thread state the message
+was seen in and branch information.
+
+##### Parameters
+
+###### message
+
+`Message`
+
+The message to get the metadata for.
+
+###### index?
+
+`number`
+
+The index of the message in the thread.
+
+##### Returns
+
+`undefined` \| [`MessageMetadata`](#reacttype-aliasesmessagemetadatamd)\<`StateType`\>
+
+The metadata for the message.
+
+***
+
+#### history
+
+> **history**: `ThreadState`\<`StateType`\>[]
+
+Defined in: [react/stream.tsx:552](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L552)
+
+Flattened history of thread states of a thread.
+
+***
+
+#### interrupt
+
+> **interrupt**: `undefined` \| `Interrupt`\<`GetInterruptType`\<`Bag`\>\>
+
+Defined in: [react/stream.tsx:563](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L563)
+
+Get the interrupt value for the stream if interrupted.
+
+***
+
+#### isLoading
+
+> **isLoading**: `boolean`
+
+Defined in: [react/stream.tsx:524](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L524)
+
+Whether the stream is currently running.
+
+***
+
+#### messages
+
+> **messages**: `Message`[]
+
+Defined in: [react/stream.tsx:569](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L569)
+
+Messages inferred from the thread.
+Will automatically update with incoming message chunks.
+
+***
+
+#### setBranch()
+
+> **setBranch**: (`branch`) => `void`
+
+Defined in: [react/stream.tsx:547](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L547)
+
+Set the branch of the thread.
+
+##### Parameters
+
+###### branch
+
+`string`
+
+##### Returns
+
+`void`
+
+***
+
+#### stop()
+
+> **stop**: () => `void`
+
+Defined in: [react/stream.tsx:529](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L529)
+
+Stops the stream.
+
+##### Returns
+
+`void`
+
+***
+
+#### submit()
+
+> **submit**: (`values`, `options`?) => `void`
+
+Defined in: [react/stream.tsx:534](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L534)
+
+Create and stream a run to the thread.
+
+##### Parameters
+
+###### values
+
+`undefined` | `null` | `GetUpdateType`\<`Bag`, `StateType`\>
+
+###### options?
+
+`SubmitOptions`\<`StateType`, `GetConfigurableType`\<`Bag`\>\>
+
+##### Returns
+
+`void`
+
+***
+
+#### values
+
+> **values**: `StateType`
+
+Defined in: [react/stream.tsx:514](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L514)
+
+The current values of the thread.
+
+
+
+
+[**@langchain/langgraph-sdk**](#reactreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#reactreadmemd) / UseStreamOptions
+
+## Interface: UseStreamOptions\
+
+Defined in: [react/stream.tsx:408](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L408)
+
+### Type Parameters
+
+• **StateType** *extends* `Record`\<`string`, `unknown`\> = `Record`\<`string`, `unknown`\>
+
+• **Bag** *extends* `BagTemplate` = `BagTemplate`
+
+### Properties
+
+#### apiKey?
+
+> `optional` **apiKey**: `string`
+
+Defined in: [react/stream.tsx:430](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L430)
+
+The API key to use.
+
+***
+
+#### apiUrl?
+
+> `optional` **apiUrl**: `string`
+
+Defined in: [react/stream.tsx:425](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L425)
+
+The URL of the API to use.
+
+***
+
+#### assistantId
+
+> **assistantId**: `string`
+
+Defined in: [react/stream.tsx:415](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L415)
+
+The ID of the assistant to use.
+
+***
+
+#### callerOptions?
+
+> `optional` **callerOptions**: `AsyncCallerParams`
+
+Defined in: [react/stream.tsx:435](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L435)
+
+Custom call options, such as custom fetch implementation.
+
+***
+
+#### client?
+
+> `optional` **client**: `Client`\<`DefaultValues`, `DefaultValues`, `unknown`\>
+
+Defined in: [react/stream.tsx:420](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L420)
+
+Client used to send requests.
+
+***
+
+#### defaultHeaders?
+
+> `optional` **defaultHeaders**: `Record`\<`string`, `undefined` \| `null` \| `string`\>
+
+Defined in: [react/stream.tsx:440](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L440)
+
+Default headers to send with requests.
+
+***
+
+#### messagesKey?
+
+> `optional` **messagesKey**: `string`
+
+Defined in: [react/stream.tsx:448](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L448)
+
+Specify the key within the state that contains messages.
+Defaults to "messages".
+
+##### Default
+
+```ts
+"messages"
+```
+
+***
+
+#### onCustomEvent()?
+
+> `optional` **onCustomEvent**: (`data`, `options`) => `void`
+
+Defined in: [react/stream.tsx:470](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L470)
+
+Callback that is called when a custom event is received.
+
+##### Parameters
+
+###### data
+
+`GetCustomEventType`\<`Bag`\>
+
+###### options
+
+####### mutate
+
+(`update`) => `void`
+
+##### Returns
+
+`void`
+
+***
+
+#### onDebugEvent()?
+
+> `optional` **onDebugEvent**: (`data`) => `void`
+
+Defined in: [react/stream.tsx:494](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L494)
+
+**`Internal`**
+
+Callback that is called when a debug event is received.
+ This API is experimental and subject to change.
+
+##### Parameters
+
+###### data
+
+`unknown`
+
+##### Returns
+
+`void`
+
+***
+
+#### onError()?
+
+> `optional` **onError**: (`error`) => `void`
+
+Defined in: [react/stream.tsx:453](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L453)
+
+Callback that is called when an error occurs.
+
+##### Parameters
+
+###### error
+
+`unknown`
+
+##### Returns
+
+`void`
+
+***
+
+#### onFinish()?
+
+> `optional` **onFinish**: (`state`) => `void`
+
+Defined in: [react/stream.tsx:458](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L458)
+
+Callback that is called when the stream is finished.
+
+##### Parameters
+
+###### state
+
+`ThreadState`\<`StateType`\>
+
+##### Returns
+
+`void`
+
+***
+
+#### onLangChainEvent()?
+
+> `optional` **onLangChainEvent**: (`data`) => `void`
+
+Defined in: [react/stream.tsx:488](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L488)
+
+Callback that is called when a LangChain event is received.
+
+##### Parameters
+
+###### data
+
+####### data
+
+`unknown`
+
+####### event
+
+`string` & `object` \| `"on_tool_start"` \| `"on_tool_stream"` \| `"on_tool_end"` \| `"on_chat_model_start"` \| `"on_chat_model_stream"` \| `"on_chat_model_end"` \| `"on_llm_start"` \| `"on_llm_stream"` \| `"on_llm_end"` \| `"on_chain_start"` \| `"on_chain_stream"` \| `"on_chain_end"` \| `"on_retriever_start"` \| `"on_retriever_stream"` \| `"on_retriever_end"` \| `"on_prompt_start"` \| `"on_prompt_stream"` \| `"on_prompt_end"`
+
+####### metadata
+
+`Record`\<`string`, `unknown`\>
+
+####### name
+
+`string`
+
+####### parent_ids
+
+`string`[]
+
+####### run_id
+
+`string`
+
+####### tags
+
+`string`[]
+
+##### Returns
+
+`void`
+
+##### See
+
+https://langchain-ai.github.io/langgraph/cloud/how-tos/stream_events/#stream-graph-in-events-mode for more details.
+
+***
+
+#### onMetadataEvent()?
+
+> `optional` **onMetadataEvent**: (`data`) => `void`
+
+Defined in: [react/stream.tsx:482](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L482)
+
+Callback that is called when a metadata event is received.
+
+##### Parameters
+
+###### data
+
+####### run_id
+
+`string`
+
+####### thread_id
+
+`string`
+
+##### Returns
+
+`void`
+
+***
+
+#### onThreadId()?
+
+> `optional` **onThreadId**: (`threadId`) => `void`
+
+Defined in: [react/stream.tsx:504](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L504)
+
+Callback that is called when the thread ID is updated (ie when a new thread is created).
+
+##### Parameters
+
+###### threadId
+
+`string`
+
+##### Returns
+
+`void`
+
+***
+
+#### onUpdateEvent()?
+
+> `optional` **onUpdateEvent**: (`data`) => `void`
+
+Defined in: [react/stream.tsx:463](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L463)
+
+Callback that is called when an update event is received.
+
+##### Parameters
+
+###### data
+
+##### Returns
+
+`void`
+
+***
+
+#### threadId?
+
+> `optional` **threadId**: `null` \| `string`
+
+Defined in: [react/stream.tsx:499](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L499)
+
+The ID of the thread to fetch history and current values from.
+
+
+
+
+[**@langchain/langgraph-sdk**](#reactreadmemd)
+
+***
+
+[@langchain/langgraph-sdk](#reactreadmemd) / MessageMetadata
+
+## Type Alias: MessageMetadata\
+
+> **MessageMetadata**\<`StateType`\>: `object`
+
+Defined in: [react/stream.tsx:169](https://github.com/langchain-ai/langgraph/blob/d4f644877db6264bd46d0b00fc4c37f174e502d5/libs/sdk-js/src/react/stream.tsx#L169)
+
+### Type Parameters
+
+• **StateType** *extends* `Record`\<`string`, `unknown`\>
+
+### Type declaration
+
+#### branch
+
+> **branch**: `string` \| `undefined`
+
+The branch of the message.
+
+#### branchOptions
+
+> **branchOptions**: `string`[] \| `undefined`
+
+The list of branches this message is part of.
+This is useful for displaying branching controls.
+
+#### firstSeenState
+
+> **firstSeenState**: `ThreadState`\<`StateType`\> \| `undefined`
+
+The first thread state the message was seen in.
+
+#### messageId
+
+> **messageId**: `string`
+
+The ID of the message used.
diff --git a/docs/docs/concepts/agentic_concepts.md b/docs/docs/concepts/agentic_concepts.md
index 5c18fce31..0dce56cd9 100644
--- a/docs/docs/concepts/agentic_concepts.md
+++ b/docs/docs/concepts/agentic_concepts.md
@@ -97,7 +97,7 @@ Parallel processing is vital for efficient multi-agent systems and complex tasks
- Implementation of map-reduce-like operations
- Efficient handling of independent subtasks
-For practical implementation, see our [map-reduce tutorial](../how-tos/graph-api.ipynb#map-reduce-and-the-send-api)
+For practical implementation, see our [map-reduce tutorial](../how-tos/graph-api.md#map-reduce-and-the-send-api)
### Subgraphs
@@ -107,7 +107,7 @@ For practical implementation, see our [map-reduce tutorial](../how-tos/graph-api
- Hierarchical organization of agent teams
- Controlled communication between agents and the main system
-Subgraphs communicate with the parent graph through overlapping keys in the state schema. This enables flexible, modular agent design. For implementation details, refer to our [subgraph how-to guide](../how-tos/subgraph.ipynb).
+Subgraphs communicate with the parent graph through overlapping keys in the state schema. This enables flexible, modular agent design. For implementation details, refer to our [subgraph how-to guide](../how-tos/subgraph.md).
### Reflection
diff --git a/docs/docs/concepts/auth.md b/docs/docs/concepts/auth.md
index 7788ce37f..204764ed3 100644
--- a/docs/docs/concepts/auth.md
+++ b/docs/docs/concepts/auth.md
@@ -143,6 +143,54 @@ The returned user information is available:
In many of our tutorials, we will just show the "authorization" parameter to be concise, but you can opt to accept more information as needed
to implement your custom authentication scheme.
+### Agent authentication
+
+Custom authentication permits delegated access. The values you return in `@auth.authenticate` are added to the run context, giving agents user-scoped credentials lets them access resources on the user’s behalf.
+
+```mermaid
+sequenceDiagram
+ %% Actors
+ participant ClientApp as Client
+ participant AuthProv as Auth Provider
+ participant LangGraph as LangGraph Backend
+ participant SecretStore as Secret Store
+ participant ExternalService as External Service
+
+ %% Platform login / AuthN
+ ClientApp ->> AuthProv: 1. Login (username / password)
+ AuthProv -->> ClientApp: 2. Return token
+ ClientApp ->> LangGraph: 3. Request with token
+
+ Note over LangGraph: 4. Validate token (@auth.authenticate)
+ LangGraph -->> AuthProv: 5. Fetch user info
+ AuthProv -->> LangGraph: 6. Confirm validity
+
+ %% Fetch user tokens from secret store
+ LangGraph ->> SecretStore: 6a. Fetch user tokens
+ SecretStore -->> LangGraph: 6b. Return tokens
+
+ Note over LangGraph: 7. Apply access control (@auth.on.*)
+
+ %% External Service round-trip
+ LangGraph ->> ExternalService: 8. Call external service (with header)
+ Note over ExternalService: 9. External service validates header and executes action
+ ExternalService -->> LangGraph: 10. Service response
+
+ %% Return to caller
+ LangGraph -->> ClientApp: 11. Return resources
+```
+
+After authentication, the platform creates a special configuration object that is passed to your graph and all nodes via the configurable context.
+This object contains information about the current user, including any custom fields you return from your [`@auth.authenticate`](../cloud/reference/sdk/python_sdk_ref.md#langgraph_sdk.auth.Auth.authenticate) handler.
+
+To enable an agent to act on behalf of the user, use [custom authentication middleware](../how-tos/auth/custom_auth.md). This will allow the agent to interact with external systems like MCP servers, external databases, and even other agents on behalf of the user.
+
+For more information, see the [Use custom auth](../how-tos/auth/custom_auth.md#enable-agent-authentication) guide.
+
+### Agent authentication with MCP
+
+For information on how to authenticate an agent to an MCP server, see the [MCP conceptual guide](../concepts/mcp.md).
+
## Authorization
After authentication, LangGraph calls your [`@auth.on`](../cloud/reference/sdk/python_sdk_ref.md#langgraph_sdk.auth.Auth.on) handlers to control access to specific resources (e.g., threads, assistants, crons). These handlers can:
diff --git a/docs/docs/concepts/breakpoints.md b/docs/docs/concepts/breakpoints.md
deleted file mode 100644
index ecd580271..000000000
--- a/docs/docs/concepts/breakpoints.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-search:
- boost: 2
----
-
-# Breakpoints
-
-[Breakpoints](../how-tos/human_in_the_loop/breakpoints.md) pause graph execution at defined points and let you step through each stage. They use LangGraph's [**persistence layer**](./persistence.md), which saves the graph state after each step.
-
-With breakpoints, you can inspect the graph's state and node inputs at any point. Execution pauses **indefinitely** until you resume, as the checkpointer preserves the state.
-
-
-{: style="max-height:400px"}
-An example graph consisting of 3 sequential steps with a breakpoint before step_3.
-
-!!! tip
-
- For information on how to use breakpoints, see [Set breakpoints](../how-tos/human_in_the_loop/breakpoints.md) and [Set breakpoints using Server API](../cloud/how-tos/human_in_the_loop_breakpoint.md).
\ No newline at end of file
diff --git a/docs/docs/concepts/deployment_options.md b/docs/docs/concepts/deployment_options.md
index 247a392f8..da3ee2d9d 100644
--- a/docs/docs/concepts/deployment_options.md
+++ b/docs/docs/concepts/deployment_options.md
@@ -10,7 +10,7 @@ search:
There are two free options for deploying LangGraph applications via the LangGraph Server:
1. [Local](../tutorials/langgraph-platform/local-server.md): Deploy for local testing and development.
-1. [Standalone Container (Lite)](../concepts/langgraph_standalone_container.md): A limited version of Standalone Container for deployments unlikely to see more that 1 million node executions per year and that do not need crons and other enterprise features. Standalone Container (Lite) deployment option is free with a LangSmith API key.
+1. [Standalone Container (Lite)](../concepts/langgraph_standalone_container.md): A limited version of Standalone Container for deployments unlikely to see more than 1 million node executions per year and that do not need crons and other enterprise features. Standalone Container (Lite) deployment option is free with a LangSmith API key.
## Production deployment
diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md
index b11e5c2ae..eabe5fe85 100644
--- a/docs/docs/concepts/human_in_the_loop.md
+++ b/docs/docs/concepts/human_in_the_loop.md
@@ -23,9 +23,18 @@ To review, edit, and approve tool calls in an agent or workflow, [use LangGraph'
## Key capabilities
-* **Persistent execution state**: LangGraph allows you to pause execution **indefinitely** — for minutes, hours, or even days—until human input is received. This is possible because LangGraph checkpoints the graph state after each step, which allows the system to persist execution context and later resume the workflow, continuing from where it left off. This supports asynchronous human review or input without time constraints.
+* **Persistent execution state**: Interrupts use LangGraph's [persistence](../../concepts/persistence.md) layer, which saves the graph state, to indefinitely pause graph execution until you resume. This is possible because LangGraph checkpoints the graph state after each step, which allows the system to persist execution context and later resume the workflow, continuing from where it left off. This supports asynchronous human review or input without time constraints.
-* **Flexible integration points**: HIL logic can be introduced at any point in the workflow. This allows targeted human involvement, such as approving API calls, correcting outputs, or guiding conversations.
+ There are two ways to pause a graph:
+
+ - [Dynamic interrupts](../how-tos/human_in_the_loop/add-human-in-the-loop.md#pause-using-interrupt): Use `interrupt` to pause a graph from inside a specific node, based on the current state of the graph.
+ - [Static interrupts](../how-tos/human_in_the_loop/add-human-in-the-loop.md#debug-with-interrupts): Use `interrupt_before` and `interrupt_after` to pause the graph at defined points, either before or after a node executes.
+
+
+ {: style="max-height:400px"}
+ An example graph consisting of 3 sequential steps with a breakpoint before step_3.
+
+* **Flexible integration points**: Human-in-the-loop logic can be introduced at any point in the workflow. This allows targeted human involvement, such as approving API calls, correcting outputs, or guiding conversations.
## Patterns
diff --git a/docs/docs/concepts/img/human_in_the_loop/static-interrupt.png b/docs/docs/concepts/img/human_in_the_loop/static-interrupt.png
new file mode 100644
index 000000000..d095dd2d7
Binary files /dev/null and b/docs/docs/concepts/img/human_in_the_loop/static-interrupt.png differ
diff --git a/docs/docs/concepts/langgraph_control_plane.md b/docs/docs/concepts/langgraph_control_plane.md
index 2e3ecc84d..006a57df9 100644
--- a/docs/docs/concepts/langgraph_control_plane.md
+++ b/docs/docs/concepts/langgraph_control_plane.md
@@ -26,7 +26,7 @@ The Control Plane UI is embedded in [LangSmith](https://docs.smith.langchain.com
## Control Plane API
-This section describes data model of the control plane API. The API is used to create, update, and delete deployments. However, they are not publicly accessible.
+This section describes the data model of the control plane API. The API is used to create, update, and delete deployments. See the [control plane API reference](../cloud/reference/api/api_ref_control_plane.md) for more details.
### Deployment
@@ -34,11 +34,7 @@ A deployment is an instance of a LangGraph Server. A single deployment can have
### Revision
-A revision is an iteration of a deployment. When a new deployment is created, an initial revision is automatically created. To deploy code changes or update environment variables for a deployment, a new revision must be created.
-
-### Environment Variable
-
-Environment variables are set for a deployment. All environment variables are stored as secrets (i.e. saved in a secrets store).
+A revision is an iteration of a deployment. When a new deployment is created, an initial revision is automatically created. To deploy code changes or update secrets for a deployment, a new revision must be created.
## Control Plane Features
@@ -50,21 +46,40 @@ For simplicity, the control plane offers two deployment types with different res
| **Deployment Type** | **CPU/Memory** | **Scaling** | **Database** |
|---------------------|-----------------|---------------------|----------------------------------------------------------------------------------|
-| Development | 1 CPU, 1 GB RAM | Up to 1 container | 10 GB disk, no backups |
-| Production | 2 CPU, 2 GB RAM | Up to 10 containers | Autoscaling disk, automatic backups, highly available (multi-zone configuration) |
+| Development | 1 CPU, 1 GB RAM | Up to 1 replica | 10 GB disk, no backups |
+| Production | 2 CPU, 2 GB RAM | Up to 10 replicas | Autoscaling disk, automatic backups, highly available (multi-zone configuration) |
-CPU and memory resources are per container.
+CPU and memory resources are per replica.
!!! warning "Immutable Deployment Type"
Once a deployment is created, the deployment type cannot be changed.
-!!! info "Resource Customization"
- For `Production` type deployments, resources can be manually increased on a case-by-case basis depending on use case and capacity constraints. Contact support@langchain.dev to request an increase in resources.
+!!! info "Self-Hosted Deployment"
+ Resources for [Self-Hosted Data Plane](../concepts/langgraph_self_hosted_data_plane.md) and [Self-Hosted Control Plane](../concepts/langgraph_self_hosted_control_plane.md) deployments can be fully customized. Deployment types are only applicable for [Cloud SaaS](../concepts/langgraph_cloud.md) deployments.
- For `Development` types deployments, database disk size can be manually increased on a case-by-case basis depending on use case and capacity constraints. For most use cases, [TTLs](../how-tos/ttl/configure_ttl.md) should be configured to manage disk usage. Contact support@langchain.dev to request an increase in resources.
+#### Production
- Resources for [Self-Hosted Data Plane](../concepts/langgraph_self_hosted_data_plane.md) and [Self-Hosted Control Plane](../concepts/langgraph_self_hosted_control_plane.md) deployments can be fully customized.
+`Production` type deployments are suitable for "production" workloads. For example, select `Production` for customer-facing applications in the critical path.
+
+Resources for `Production` type deployments can be manually increased on a case-by-case basis depending on use case and capacity constraints. Contact support@langchain.dev to request an increase in resources.
+
+#### Development
+
+`Development` type deployments are suitable development and testing. For example, select `Development` for internal testing environments. `Development` type deployments are not suitable for "production" workloads.
+
+!!! danger "Preemptible Compute Infrastructure"
+ `Development` type deployments (API server, queue server, and database) are provisioned on preemptible compute infrastructure. This means the compute infrastructure **may be terminated at any time without notice**. This may result in intermittent...
+
+ - Redis connection timeouts/errors
+ - Postgres connection timeouts/errors
+ - Failed or retrying background runs
+
+ This behavior is expected. Preemptible compute infrastructure **significantly reduces the cost to provision a `Development` type deployment**. By design, LangGraph Server is fault-tolerant. The implementation will automatically attempt to recover from Redis/Postgres connection errors and retry failed background runs.
+
+ `Production` type deployments are provisioned on durable compute infrastructure, not preemptible compute infrastructure.
+
+Database disk size for `Development` type deployments can be manually increased on a case-by-case basis depending on use case and capacity constraints. For most use cases, [TTLs](../how-tos/ttl/configure_ttl.md) should be configured to manage disk usage. Contact support@langchain.dev to request an increase in resources.
### Database Provisioning
@@ -97,6 +112,8 @@ After a deployment is ready, the control plane monitors the deployment and recor
- Number of container restarts.
- Number of replicas (this will increase with [autoscaling](../concepts/langgraph_data_plane.md#autoscaling)).
- [Postgres](../concepts/langgraph_data_plane.md#postgres) CPU, memory usage, and disk usage.
+- [LangGraph Server queue](../concepts/langgraph_server.md#persistence-and-task-queue) pending/active run count.
+- [LangGraph Server API](../concepts/langgraph_server.md) success response count, error response count, and latency.
These metrics are displayed as charts in the Control Plane UI.
diff --git a/docs/docs/concepts/langgraph_data_plane.md b/docs/docs/concepts/langgraph_data_plane.md
index 0b52b8b6f..5d7473cb6 100644
--- a/docs/docs/concepts/langgraph_data_plane.md
+++ b/docs/docs/concepts/langgraph_data_plane.md
@@ -50,6 +50,15 @@ Runs in a LangGraph Server may be retried for specific failures (currently only
This section describes various features of the data plane.
+### Data Region
+
+!!! info "Only for Cloud SaaS"
+ Data regions are only applicable for [Cloud SaaS](../concepts/langgraph_cloud.md) deployments.
+
+Deployments can be created in 2 data regions: US and EU
+
+The data region for a deployment is implied by the data region of the LangSmith organization where the deployment is created. Deployments and the underlying database for the deployments cannot be migrated between data regions.
+
### Autoscaling
[`Production` type](../concepts/langgraph_control_plane.md#deployment-types) deployments automatically scale up to 10 containers. Scaling is based on 3 metrics:
diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md
index f277b742e..d47cc2116 100644
--- a/docs/docs/concepts/low_level.md
+++ b/docs/docs/concepts/low_level.md
@@ -45,9 +45,9 @@ The first thing you do when you define a graph is define the `State` of the grap
### Schema
-The main documented way to specify the schema of a graph is by using `TypedDict`. However, we also support [using a Pydantic BaseModel](../how-tos/graph-api.ipynb#use-pydantic-models-for-graph-state) as your graph state to add **default values** and additional data validation.
+The main documented way to specify the schema of a graph is by using a [`TypedDict`](https://docs.python.org/3/library/typing.html#typing.TypedDict). If you want to provide default values in your state, use a [`dataclass`](https://docs.python.org/3/library/dataclasses.html). We also support using a Pydantic [BaseModel](../how-tos/graph-api.md#use-pydantic-models-for-graph-state) as your graph state if you want recursive data validation (though note that pydantic is less performant than a `TypedDict` or `dataclass`).
-By default, the graph will have the same input and output schemas. If you want to change this, you can also specify explicit input and output schemas directly. This is useful when you have a lot of keys, and some are explicitly for input and others for output. See the [guide here](../how-tos/graph-api.ipynb#define-input-and-output-schemas) for how to use.
+By default, the graph will have the same input and output schemas. If you want to change this, you can also specify explicit input and output schemas directly. This is useful when you have a lot of keys, and some are explicitly for input and others for output. See the [guide here](../how-tos/graph-api.md#define-input-and-output-schemas) for how to use.
#### Multiple schemas
@@ -56,9 +56,9 @@ Typically, all graph nodes communicate with a single schema. This means that the
- Internal nodes can pass information that is not required in the graph's input / output.
- We may also want to use different input / output schemas for the graph. The output might, for example, only contain a single relevant output key.
-It is possible to have nodes write to private state channels inside the graph for internal node communication. We can simply define a private schema, `PrivateState`. See [this guide](../how-tos/graph-api.ipynb#pass-private-state-between-nodes) for more detail.
+It is possible to have nodes write to private state channels inside the graph for internal node communication. We can simply define a private schema, `PrivateState`. See [this guide](../how-tos/graph-api.md#pass-private-state-between-nodes) for more detail.
-It is also possible to define explicit input and output schemas for a graph. In these cases, we define an "internal" schema that contains _all_ keys relevant to graph operations. But, we also define `input` and `output` schemas that are sub-sets of the "internal" schema to constrain the input and output of the graph. See [this guide](../how-tos/graph-api.ipynb#define-input-and-output-schemas) for more detail.
+It is also possible to define explicit input and output schemas for a graph. In these cases, we define an "internal" schema that contains _all_ keys relevant to graph operations. But, we also define `input` and `output` schemas that are sub-sets of the "internal" schema to constrain the input and output of the graph. See [this guide](../how-tos/graph-api.md#define-input-and-output-schemas) for more detail.
Let's look at an example:
@@ -298,7 +298,7 @@ print(graph.invoke({"x": 5}, stream_mode='updates')) # (2)!
[{'expensive_node': {'result': 10}, '__metadata__': {'cached': True}}]
```
-1. First run takes the full second to run (due to mocked expensive computation).
+1. First run takes two seconds to run (due to mocked expensive computation).
2. Second run utilizes cache and returns quickly.
## Edges
@@ -406,7 +406,7 @@ def my_node(state: State) -> Command[Literal["my_other_node"]]:
When returning `Command` in your node functions, you must add return type annotations with the list of node names the node is routing to, e.g. `Command[Literal["my_other_node"]]`. This is necessary for the graph rendering and tells LangGraph that `my_node` can navigate to `my_other_node`.
-Check out this [how-to guide](../how-tos/graph-api.ipynb#combine-control-flow-and-state-updates-with-command) for an end-to-end example of how to use `Command`.
+Check out this [how-to guide](../how-tos/graph-api.md#combine-control-flow-and-state-updates-with-command) for an end-to-end example of how to use `Command`.
### When should I use Command instead of conditional edges?
@@ -433,17 +433,17 @@ def my_node(state: State) -> Command[Literal["other_subgraph"]]:
!!! important "State updates with `Command.PARENT`"
- When you send updates from a subgraph node to a parent graph node for a key that's shared by both parent and subgraph [state schemas](#schema), you **must** define a [reducer](#reducers) for the key you're updating in the parent graph state. See this [example](../how-tos/graph-api.ipynb#navigate-to-a-node-in-a-parent-graph).
+ When you send updates from a subgraph node to a parent graph node for a key that's shared by both parent and subgraph [state schemas](#schema), you **must** define a [reducer](#reducers) for the key you're updating in the parent graph state. See this [example](../how-tos/graph-api.md#navigate-to-a-node-in-a-parent-graph).
This is particularly useful when implementing [multi-agent handoffs](./multi_agent.md#handoffs).
-Check out [this guide](../how-tos/graph-api.ipynb#navigate-to-a-node-in-a-parent-graph) for detail.
+Check out [this guide](../how-tos/graph-api.md#navigate-to-a-node-in-a-parent-graph) for detail.
### Using inside tools
A common use case is updating graph state from inside a tool. For example, in a customer support application you might want to look up customer information based on their account number or ID in the beginning of the conversation.
-Refer to [this guide](../how-tos/graph-api.ipynb#use-inside-tools) for detail.
+Refer to [this guide](../how-tos/graph-api.md#use-inside-tools) for detail.
### Human-in-the-loop
@@ -489,7 +489,7 @@ def node_a(state, config):
...
```
-See [this guide](../how-tos/graph-api.ipynb#add-runtime-configuration) for a full breakdown on configuration.
+See [this guide](../how-tos/graph-api.md#add-runtime-configuration) for a full breakdown on configuration.
### Recursion Limit
@@ -503,4 +503,4 @@ Read [this how-to](https://langchain-ai.github.io/langgraph/how-tos/recursion-li
## Visualization
-It's often nice to be able to visualize graphs, especially as they get more complex. LangGraph comes with several built-in ways to visualize graphs. See [this how-to guide](../how-tos/graph-api.ipynb#visualize-your-graph) for more info.
+It's often nice to be able to visualize graphs, especially as they get more complex. LangGraph comes with several built-in ways to visualize graphs. See [this how-to guide](../how-tos/graph-api.md#visualize-your-graph) for more info.
diff --git a/docs/docs/concepts/mcp.md b/docs/docs/concepts/mcp.md
new file mode 100644
index 000000000..4b05d008e
--- /dev/null
+++ b/docs/docs/concepts/mcp.md
@@ -0,0 +1,57 @@
+# MCP
+
+[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that standardizes how applications provide tools and context to language models. LangGraph agents can use tools defined on MCP servers through the `langchain-mcp-adapters` library.
+
+
+
+Install the `langchain-mcp-adapters` library to use MCP tools in LangGraph:
+
+```bash
+pip install langchain-mcp-adapters
+```
+
+## Authenticate to an MCP server
+
+You can set up [custom authentication middleware](../how-tos/auth/custom_auth.md) to authenticate a user with an MCP server to get access to user-scoped tools within your LangGraph Platform deployment.
+
+!!! note
+ Custom authentication is a LangGraph Platform feature.
+
+An example architecture for this flow:
+
+```mermaid
+sequenceDiagram
+ %% Actors
+ participant ClientApp as Client
+ participant AuthProv as Auth Provider
+ participant LangGraph as LangGraph Backend
+ participant SecretStore as Secret Store
+ participant MCPServer as MCP Server
+
+ %% Platform login / AuthN
+ ClientApp ->> AuthProv: 1. Login (username / password)
+ AuthProv -->> ClientApp: 2. Return token
+ ClientApp ->> LangGraph: 3. Request with token
+
+ Note over LangGraph: 4. Validate token (@auth.authenticate)
+ LangGraph -->> AuthProv: 5. Fetch user info
+ AuthProv -->> LangGraph: 6. Confirm validity
+
+ %% Fetch user tokens from secret store
+ LangGraph ->> SecretStore: 6a. Fetch user tokens
+ SecretStore -->> LangGraph: 6b. Return tokens
+
+ Note over LangGraph: 7. Apply access control (@auth.on.*)
+
+ %% MCP round-trip
+ Note over LangGraph: 8. Build MCP client with user token
+ LangGraph ->> MCPServer: 9. Call MCP tool (with header)
+ Note over MCPServer: 10. MCP validates header and runs tool
+ MCPServer -->> LangGraph: 11. Tool response
+
+ %% Return to caller
+ LangGraph -->> ClientApp: 12. Return resources / tool output
+```
+
+For more information, see [MCP endpoint in LangGraph Server](../concepts/server-mcp.md#use-user-scoped-mcp-tools-in-your-deployment).
+
diff --git a/docs/docs/concepts/multi_agent.md b/docs/docs/concepts/multi_agent.md
index 0cd4e7f61..5d3e30a29 100644
--- a/docs/docs/concepts/multi_agent.md
+++ b/docs/docs/concepts/multi_agent.md
@@ -26,7 +26,7 @@ The primary benefits of using multi-agent systems are:
There are several ways to connect agents in a multi-agent system:
- **Network**: each agent can communicate with [every other agent](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/multi-agent-collaboration/). Any agent can decide which other agent to call next.
-- **Supervisor**: each agent communicates with a single [supervisor](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/agent_supervisor/) agent. Supervisor agent makes decisions on which agent should be called next.
+- **Supervisor**: each agent communicates with a single [supervisor](../tutorials/multi_agent/agent_supervisor.md) agent. Supervisor agent makes decisions on which agent should be called next.
- **Supervisor (tool-calling)**: this is a special case of supervisor architecture. Individual agents can be represented as tools. In this case, a supervisor agent uses a tool-calling LLM to decide which of the agent tools to call, as well as the arguments to pass to those agents.
- **Hierarchical**: you can define a multi-agent system with [a supervisor of supervisors](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/hierarchical_agent_teams/). This is a generalization of the supervisor architecture and allows for more complex control flows.
- **Custom multi-agent workflow**: each agent communicates with only a subset of agents. Parts of the flow are deterministic, and only some agents can decide which other agents to call next.
@@ -166,7 +166,7 @@ network = builder.compile()
### Supervisor
-In this architecture, we define agents as nodes and add a supervisor node (LLM) that decides which agent nodes should be called next. We use [`Command`](./low_level.md#command) to route execution to the appropriate agent node based on supervisor's decision. This architecture also lends itself well to running multiple agents in parallel or using [map-reduce](../how-tos/graph-api.ipynb#map-reduce-and-the-send-api) pattern.
+In this architecture, we define agents as nodes and add a supervisor node (LLM) that decides which agent nodes should be called next. We use [`Command`](./low_level.md#command) to route execution to the appropriate agent node based on supervisor's decision. This architecture also lends itself well to running multiple agents in parallel or using [map-reduce](../how-tos/graph-api.md#map-reduce-and-the-send-api) pattern.
```python
from typing import Literal
@@ -211,7 +211,7 @@ builder.add_edge(START, "supervisor")
supervisor = builder.compile()
```
-Check out this [tutorial](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/agent_supervisor/) for an example of supervisor multi-agent architecture.
+Check out this [tutorial](../tutorials/multi_agent/agent_supervisor.md) for an example of supervisor multi-agent architecture.
### Supervisor (tool-calling)
@@ -414,5 +414,5 @@ There are two high-level approaches to achieve that:
An agent might need to have a different state schema from the rest of the agents. For example, a search agent might only need to keep track of queries and retrieved documents. There are two ways to achieve this in LangGraph:
-- Define [subgraph](./subgraphs.md) agents with a separate state schema. If there are no shared state keys (channels) between the subgraph and the parent graph, it’s important to [add input / output transformations](../how-tos/subgraph.ipynb#different-state-schemas) so that the parent graph knows how to communicate with the subgraphs.
-- Define agent node functions with a [private input state schema](../how-tos/graph-api.ipynb/#pass-private-state-between-nodes) that is distinct from the overall graph state schema. This allows passing information that is only needed for executing that particular agent.
+- Define [subgraph](./subgraphs.md) agents with a separate state schema. If there are no shared state keys (channels) between the subgraph and the parent graph, it’s important to [add input / output transformations](../how-tos/subgraph.md#different-state-schemas) so that the parent graph knows how to communicate with the subgraphs.
+- Define agent node functions with a [private input state schema](../how-tos/graph-api.md/#pass-private-state-between-nodes) that is distinct from the overall graph state schema. This allows passing information that is only needed for executing that particular agent.
diff --git a/docs/docs/concepts/persistence.md b/docs/docs/concepts/persistence.md
index 7c612cf60..185db6b62 100644
--- a/docs/docs/concepts/persistence.md
+++ b/docs/docs/concepts/persistence.md
@@ -5,7 +5,7 @@ search:
# Persistence
-LangGraph has a built-in persistence layer, implemented through checkpointers. When you compile graph with a checkpointer, the checkpointer saves a `checkpoint` of the graph state at every super-step. Those checkpoints are saved to a `thread`, which can be accessed after graph execution. Because `threads` allow access to graph's state after execution, several powerful capabilities including human-in-the-loop, memory, time travel, and fault-tolerance are all possible. Below, we'll discuss each of these concepts in more detail.
+LangGraph has a built-in persistence layer, implemented through checkpointers. When you compile a graph with a checkpointer, the checkpointer saves a `checkpoint` of the graph state at every super-step. Those checkpoints are saved to a `thread`, which can be accessed after graph execution. Because `threads` allow access to graph's state after execution, several powerful capabilities including human-in-the-loop, memory, time travel, and fault-tolerance are all possible. Below, we'll discuss each of these concepts in more detail.

@@ -33,7 +33,7 @@ The state of a thread at a particular point in time is called a checkpoint. Chec
- `metadata`: Metadata associated with this checkpoint.
- `values`: Values of the state channels at this point in time.
- `next` A tuple of the node names to execute next in the graph.
-- `tasks`: A tuple of `PregelTask` objects that contain information about next tasks to be executed. If the step was previously attempted, it will include error information. If a graph was interrupted [dynamically](../how-tos/human_in_the_loop/breakpoints.md#dynamic-breakpoints) from within a node, tasks will contain additional data associated with interrupts.
+- `tasks`: A tuple of `PregelTask` objects that contain information about next tasks to be executed. If the step was previously attempted, it will include error information. If a graph was interrupted [dynamically](../how-tos/human_in_the_loop/add-human-in-the-loop.md#pause-using-interrupt) from within a node, tasks will contain additional data associated with interrupts.
Checkpoints are persisted and can be used to restore the state of a thread at a later time.
@@ -78,7 +78,7 @@ After we run the graph, we expect to see exactly 4 checkpoints:
* checkpoint with the outputs of `node_a` `{'foo': 'a', 'bar': ['a']}` and `node_b` as the next node to be executed
* checkpoint with the outputs of `node_b` `{'foo': 'b', 'bar': ['a', 'b']}` and no next nodes to be executed
-Note that we `bar` channel values contain outputs from both nodes as we have a reducer for `bar` channel.
+Note that the `bar` channel values contain outputs from both nodes as we have a reducer for `bar` channel.
### Get state
@@ -525,7 +525,7 @@ When running on LangGraph Platform, encryption is automatically enabled whenever
### Human-in-the-loop
-First, checkpointers facilitate [human-in-the-loop workflows](agentic_concepts.md#human-in-the-loop) workflows by allowing humans to inspect, interrupt, and approve graph steps. Checkpointers are needed for these workflows as the human has to be able to view the state of a graph at any point in time, and the graph has to be to resume execution after the human has made any updates to the state. See [these how-to guides](../how-tos/human_in_the_loop/breakpoints.md) for concrete examples.
+First, checkpointers facilitate [human-in-the-loop workflows](agentic_concepts.md#human-in-the-loop) workflows by allowing humans to inspect, interrupt, and approve graph steps. Checkpointers are needed for these workflows as the human has to be able to view the state of a graph at any point in time, and the graph has to be to resume execution after the human has made any updates to the state. See [the how-to guides](../how-tos/human_in_the_loop/add-human-in-the-loop.md) for examples.
### Memory
diff --git a/docs/docs/concepts/server-mcp.md b/docs/docs/concepts/server-mcp.md
index 7f144e87f..b66eaada3 100644
--- a/docs/docs/concepts/server-mcp.md
+++ b/docs/docs/concepts/server-mcp.md
@@ -8,8 +8,7 @@ hide:
# MCP endpoint in LangGraph Server
-The **Model Context Protocol (MCP)** is an open protocol for describing tools and data sources in a model-agnostic format, enabling LLMs to discover
-and use them via a structured API.
+The [Model Context Protocol (MCP)](./mcp.md) is an open protocol for describing tools and data sources in a model-agnostic format, enabling LLMs to discover and use them via a structured API.
[LangGraph Server](./langgraph_server.md) implements MCP using the [Streamable HTTP transport](https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/transports/#streamable-http). This allows LangGraph **agents** to be exposed as **MCP tools**, making them usable with any MCP-compliant client supporting Streamable HTTP.
@@ -28,79 +27,6 @@ Install them with:
pip install "langgraph-api>=0.2.3" "langgraph-sdk>=0.1.61"
```
-## Exposing an agent as MCP tool
-
-
-When deployed, your agent will appear as a tool in the MCP endpoint
-with this configuration:
-
-- **Tool name**: The agent's name.
-- **Tool description**: The agent's description.
-- **Tool input schema**: The agent's input schema.
-
-### Setting name and description
-
-You can set the name and description of your agent in `langgraph.json`:
-
-```json
-{
- "graphs": {
- "my_agent": {
- "path": "./my_agent/agent.py:graph",
- "description": "A description of what the agent does"
- }
- },
- "env": ".env"
-}
-```
-
-After deployment, you can update the name and description using the LangGraph SDK.
-
-### Schema
-
-Define clear, minimal input and output schemas to avoid exposing unnecessary internal complexity to the LLM.
-
-The default [MessagesState](./low_level.md#messagesstate) uses `AnyMessage`, which supports many message types but is too general for direct LLM exposure.
-
-Instead, define **custom agents or workflows** that use explicitly typed input and output structures.
-
-For example, a workflow answering documentation questions might look like this:
-
-```python
-from langgraph.graph import StateGraph, START, END
-from typing_extensions import TypedDict
-
-# Define input schema
-class InputState(TypedDict):
- question: str
-
-# Define output schema
-class OutputState(TypedDict):
- answer: str
-
-# Combine input and output
-class OverallState(InputState, OutputState):
- pass
-
-# Define the processing node
-def answer_node(state: InputState):
- # Replace with actual logic and do something useful
- return {"answer": "bye", "question": state["question"]}
-
-# Build the graph with explicit schemas
-builder = StateGraph(OverallState, input_schema=InputState, output_schema=OutputState)
-builder.add_node(answer_node)
-builder.add_edge(START, "answer_node")
-builder.add_edge("answer_node", END)
-graph = builder.compile()
-
-# Run the graph
-print(graph.invoke({"question": "hi"}))
-```
-
-For more details, see the [low-level concepts guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#state).
-
-
## Usage overview
To enable MCP:
@@ -201,6 +127,114 @@ Use an MCP-compliant client to connect to the LangGraph server. The following ex
asyncio.run(main())
```
+## Expose an agent as MCP tool
+
+When deployed, your agent will appear as a tool in the MCP endpoint
+with this configuration:
+
+- **Tool name**: The agent's name.
+- **Tool description**: The agent's description.
+- **Tool input schema**: The agent's input schema.
+
+### Setting name and description
+
+You can set the name and description of your agent in `langgraph.json`:
+
+```json
+{
+ "graphs": {
+ "my_agent": {
+ "path": "./my_agent/agent.py:graph",
+ "description": "A description of what the agent does"
+ }
+ },
+ "env": ".env"
+}
+```
+
+After deployment, you can update the name and description using the LangGraph SDK.
+
+### Schema
+
+Define clear, minimal input and output schemas to avoid exposing unnecessary internal complexity to the LLM.
+
+The default [MessagesState](./low_level.md#messagesstate) uses `AnyMessage`, which supports many message types but is too general for direct LLM exposure.
+
+Instead, define **custom agents or workflows** that use explicitly typed input and output structures.
+
+For example, a workflow answering documentation questions might look like this:
+
+```python
+from langgraph.graph import StateGraph, START, END
+from typing_extensions import TypedDict
+
+# Define input schema
+class InputState(TypedDict):
+ question: str
+
+# Define output schema
+class OutputState(TypedDict):
+ answer: str
+
+# Combine input and output
+class OverallState(InputState, OutputState):
+ pass
+
+# Define the processing node
+def answer_node(state: InputState):
+ # Replace with actual logic and do something useful
+ return {"answer": "bye", "question": state["question"]}
+
+# Build the graph with explicit schemas
+builder = StateGraph(OverallState, input_schema=InputState, output_schema=OutputState)
+builder.add_node(answer_node)
+builder.add_edge(START, "answer_node")
+builder.add_edge("answer_node", END)
+graph = builder.compile()
+
+# Run the graph
+print(graph.invoke({"question": "hi"}))
+```
+
+For more details, see the [low-level concepts guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#state).
+
+## Use user-scoped MCP tools in your deployment
+
+!!! tip "Prerequisites"
+
+ You have added your own [custom auth middleware](https://langchain-ai.github.io/langgraph/how-tos/auth/custom_auth/) that populates the `langgraph_auth_user` object, making it accessible through configurable context for every node in your graph.
+
+To make user-scoped tools available to your LangGraph Platform deployment, start with implementing a snippet like the following:
+
+```python
+from langchain_mcp_adapters.client import MultiServerMCPClient
+
+def mcp_tools_node(state, config):
+ user = config["configurable"].get("langgraph_auth_user")
+ # e.g., user["github_token"], user["email"], etc.
+
+ client = MultiServerMCPClient({
+ "github": {
+ "transport": "streamable_http", # (1)
+ "url": "https://my-github-mcp-server/mcp", # (2)
+ "headers": {
+ "Authorization": f"Bearer {user['github_token']}"
+ }
+ }
+ })
+ tools = await client.get_tools() # (3)
+
+ # Your tool-calling logic here
+
+ tool_messages = ...
+ return {"messages": tool_messages}
+```
+
+1. MCP only supports adding headers to requests made to `streamable_http` and `sse` `transport` servers.
+2. Your MCP server URL.
+3. Get available tools from your MCP server.
+
+_This can also be done by [rebuilding your graph at runtime](https://langchain-ai.github.io/langgraph/cloud/deployment/graph_rebuild/) to have a different configuration for a new run_
## Session behavior
@@ -210,7 +244,7 @@ The current LangGraph MCP implementation does not support sessions. Each `/mcp`
The `/mcp` endpoint uses the same authentication as the rest of the LangGraph API. Refer to the [authentication guide](./auth.md) for setup details.
-## Disabling MCP
+## Disable MCP
To disable the MCP endpoint, set `disable_mcp` to `true` in your `langgraph.json` configuration file:
@@ -222,4 +256,4 @@ To disable the MCP endpoint, set `disable_mcp` to `true` in your `langgraph.json
}
```
-This will prevent the server from exposing the `/mcp` endpoint.
\ No newline at end of file
+This will prevent the server from exposing the `/mcp` endpoint.
diff --git a/docs/docs/concepts/subgraphs.md b/docs/docs/concepts/subgraphs.md
index 6a4aefb23..218bf8cac 100644
--- a/docs/docs/concepts/subgraphs.md
+++ b/docs/docs/concepts/subgraphs.md
@@ -12,7 +12,7 @@ Some reasons for using subgraphs are:
The main question when adding subgraphs is how the parent graph and subgraph communicate, i.e. how they pass the [state](./low_level.md#state) between each other during the graph execution. There are two scenarios:
-* parent and subgraph have **shared state keys** in their state [schemas](./low_level.md#state). In this case, you can [include the subgraph as a node in the parent graph](../how-tos/subgraph.ipynb#shared-state-schemas)
+* parent and subgraph have **shared state keys** in their state [schemas](./low_level.md#state). In this case, you can [include the subgraph as a node in the parent graph](../how-tos/subgraph.md#shared-state-schemas)
```python
from langgraph.graph import StateGraph, MessagesState, START
@@ -40,7 +40,7 @@ The main question when adding subgraphs is how the parent graph and subgraph com
graph.invoke({"messages": [{"role": "user", "content": "hi!"}]})
```
-* parent graph and subgraph have **different schemas** (no shared state keys in their state [schemas](./low_level.md#state)). In this case, you have to [call the subgraph from inside a node in the parent graph](../how-tos/subgraph.ipynb#different-state-schemas): this is useful when the parent graph and the subgraph have different state schemas and you need to transform state before or after calling the subgraph
+* parent graph and subgraph have **different schemas** (no shared state keys in their state [schemas](./low_level.md#state)). In this case, you have to [call the subgraph from inside a node in the parent graph](../how-tos/subgraph.md#different-state-schemas): this is useful when the parent graph and the subgraph have different state schemas and you need to transform state before or after calling the subgraph
```python
from typing_extensions import TypedDict, Annotated
diff --git a/docs/docs/concepts/template_applications.md b/docs/docs/concepts/template_applications.md
index 76ebff698..8da3229b9 100644
--- a/docs/docs/concepts/template_applications.md
+++ b/docs/docs/concepts/template_applications.md
@@ -64,7 +64,7 @@ To create a new app from a template, use the `langgraph new` command.
=== "JS"
```bash
- npx @langchain/langgraph-cli new
+ npm create langgraph@latest
```
## Next Steps
diff --git a/docs/docs/concepts/tracing.md b/docs/docs/concepts/tracing.md
new file mode 100644
index 000000000..a9aa954c3
--- /dev/null
+++ b/docs/docs/concepts/tracing.md
@@ -0,0 +1,17 @@
+# Tracing
+
+Traces are a series of steps that your application takes to go from input to output. Each of these individual steps is represented by a run. You can use [LangSmith](https://smith.langchain.com/) to visualize these execution steps. To use it, [enable tracing for your application](../how-tos/enable-tracing.md). This enables you to do the following:
+
+- [Debug a locally running application](../cloud/how-tos/clone_traces_studio.md).
+- [Evaluate the application performance](../agents/evals.md).
+- [Monitor the application](https://docs.smith.langchain.com/observability/how_to_guides/dashboards).
+
+To get started, sign up for a free account at [LangSmith](https://smith.langchain.com/).
+
+## Learn more
+
+- [Graph runs in LangSmith](../how-tos/run-id-langsmith.md)
+- [LangSmith Observability quickstart](https://docs.smith.langchain.com/observability)
+- [Trace with LangGraph](https://docs.smith.langchain.com/observability/how_to_guides/trace_with_langgraph)
+- [Tracing conceptual guide](https://docs.smith.langchain.com/observability/concepts#traces)
+
diff --git a/docs/docs/examples/index.md b/docs/docs/examples/index.md
new file mode 100644
index 000000000..aadfb0f2c
--- /dev/null
+++ b/docs/docs/examples/index.md
@@ -0,0 +1,23 @@
+# Examples
+
+The pages in this section provide end-to-end examples for the following topics:
+
+## General
+
+- [Template Applications](../concepts/template_applications.md): Create a LangGraph application from a template.
+- [Agentic RAG](../tutorials/rag/langgraph_agentic_rag.md): Build a retrieval agent that can decide when to use a retriever tool.
+- [Agent Supervisor](../tutorials/multi_agent/agent_supervisor.md): Build a supervisor agent that can manage a team of agents.
+- [SQL agent](../tutorials/sql/sql-agent.md): Build a SQL agent that can execute SQL queries and return the results.
+- [Prebuilt chat UI](../agents/ui.md): Use a prebuilt chat UI to interact with any LangGraph agent.
+- [Graph runs in LangSmith](../how-tos/run-id-langsmith.md): Use LangSmith to track and analyze graph runs.
+
+## LangGraph Platform
+
+- [Set up custom authentication](../tutorials/auth/getting_started.md): Set up custom authentication for your LangGraph application.
+- [Make conversations private](../tutorials/auth/resource_auth.md): Make conversations private by using resource-based authentication.
+- [Connect an authentication provider](../tutorials/auth/add_auth_server.md): Connect an authentication provider to your LangGraph application.
+- [Rebuild graph at runtime](../cloud/deployment/graph_rebuild.md): Rebuild a graph at runtime.
+- [Use RemoteGraph](../how-tos/use-remote-graph.md): Use RemoteGraph to deploy your LangGraph application to a remote server.
+- [Deploy CrewAI, AutoGen, and other frameworks](../how-tos/autogen-integration.md): Deploy CrewAI, AutoGen, and other frameworks with LangGraph.
+- [Integrate LangGraph into a React app](../cloud/how-tos/use_stream_react.md)
+- [Implement Generative User Interfaces with LangGraph](../cloud/how-tos/generative_ui_react.md)
\ No newline at end of file
diff --git a/docs/docs/guides/index.md b/docs/docs/guides/index.md
new file mode 100644
index 000000000..d8a29643f
--- /dev/null
+++ b/docs/docs/guides/index.md
@@ -0,0 +1,45 @@
+# Guides
+
+The pages in this section provide a conceptual overview and how-tos for the following topics:
+
+## Agent development
+
+- [Overview](../agents/overview.md): Use prebuilt components to build an agent.
+- [Run an agent](../agents/run_agents.md): Run an agent by providing input, interpreting output, enabling streaming, and controlling execution limits.
+
+## LangGraph APIs
+
+- [Graph API](../concepts/low_level.md): Use the Graph API to define workflows using a graph paradigm.
+- [Functional API](../concepts/functional_api.md): Use Functional API to build workflows using a functional paradigm without thinking about the graph structure.
+- [Runtime](../concepts/pregel.md): Pregel implements LangGraph's runtime, managing the execution of LangGraph applications.
+
+## Core capabilities
+
+These capabilities are available in both LangGraph OSS and the LangGraph Platform.
+
+- [Streaming](../concepts/streaming.md): Stream outputs from a LangGraph graph.
+- [Persistence](../concepts/persistence.md): Persist the state of a LangGraph graph.
+- [Durable execution](../concepts/durable_execution.md): Save progress at key points in the graph execution.
+- [Memory](../concepts/memory.md): Remember information about previous interactions.
+- [Context](../agents/context.md): Pass outside data to a LangGraph graph to provide context for the graph execution.
+- [Models](../agents/models.md): Integrate various LLMs into your LangGraph application.
+- [Tools](../concepts/tools.md): Interface directly with external systems.
+- [Human-in-the-loop](../concepts/human_in_the_loop.md): Pause a graph and wait for human input at any point in a workflow.
+- [Time travel](../concepts/time-travel.md): Travel back in time to a specific point in the execution of a LangGraph graph.
+- [Subgraphs](../concepts/subgraphs.md): Build modular graphs.
+- [Multi-agent](../concepts/multi_agent.md): Break down a complex workflow into multiple agents.
+- [MCP](../concepts/mcp.md): Use MCP servers in a LangGraph graph.
+- [Evaluation](../agents/evals.md): Use LangSmith to evaluate your graph's performance.
+
+## Platform-only capabilities
+
+These capabilities are only available in [LangGraph Platform](../concepts/langgraph_platform.md).
+
+- [Authentication and access control](../concepts/auth.md): Authenticate and authorize users to access a LangGraph graph.
+- [Assistants](../concepts/assistants.md): Build assistants that can be used to interact with a LangGraph graph.
+- [Double-texting](../concepts/double_texting.md): Handle double-texting (consecutive messages before a first response is returned) in a LangGraph graph.
+- [Webhooks](../cloud/concepts/webhooks.md): Send webhooks to a LangGraph graph.
+- [Cron jobs](../cloud/concepts/cron_jobs.md): Schedule jobs to run at a specific time.
+- [Server customization](../how-tos/http/custom_lifespan.md): Customize the server that runs a LangGraph graph.
+- [Data management](../cloud/concepts/data_storage_and_privacy.md): Manage data in a LangGraph graph.
+- [Deployment](../concepts/deployment_options.md): Deploy a LangGraph graph to a server.
diff --git a/docs/docs/how-tos/assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png b/docs/docs/how-tos/assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png
new file mode 100644
index 000000000..9bd66e565
Binary files /dev/null and b/docs/docs/how-tos/assets/410e0089-2ab8-46bb-a61a-827187fd46b3.png differ
diff --git a/docs/docs/how-tos/assets/autogen-output.png b/docs/docs/how-tos/assets/autogen-output.png
new file mode 100644
index 000000000..02106782e
Binary files /dev/null and b/docs/docs/how-tos/assets/autogen-output.png differ
diff --git a/docs/docs/how-tos/assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png b/docs/docs/how-tos/assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png
new file mode 100644
index 000000000..ce95409d6
Binary files /dev/null and b/docs/docs/how-tos/assets/d38d1f2b-0f4c-4707-b531-a3c749de987f.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_1.png b/docs/docs/how-tos/assets/graph_api_image_1.png
new file mode 100644
index 000000000..c1ac60da9
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_1.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_10.png b/docs/docs/how-tos/assets/graph_api_image_10.png
new file mode 100644
index 000000000..18ea05fa8
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_10.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_2.png b/docs/docs/how-tos/assets/graph_api_image_2.png
new file mode 100644
index 000000000..4f890a3dd
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_2.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_3.png b/docs/docs/how-tos/assets/graph_api_image_3.png
new file mode 100644
index 000000000..61520b53e
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_3.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_4.png b/docs/docs/how-tos/assets/graph_api_image_4.png
new file mode 100644
index 000000000..09bb71be2
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_4.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_5.png b/docs/docs/how-tos/assets/graph_api_image_5.png
new file mode 100644
index 000000000..c1ebb138c
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_5.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_6.png b/docs/docs/how-tos/assets/graph_api_image_6.png
new file mode 100644
index 000000000..3d60cbfb9
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_6.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_7.png b/docs/docs/how-tos/assets/graph_api_image_7.png
new file mode 100644
index 000000000..d607bdc4a
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_7.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_8.png b/docs/docs/how-tos/assets/graph_api_image_8.png
new file mode 100644
index 000000000..67049fb59
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_8.png differ
diff --git a/docs/docs/how-tos/assets/graph_api_image_9.png b/docs/docs/how-tos/assets/graph_api_image_9.png
new file mode 100644
index 000000000..2eb23cc16
Binary files /dev/null and b/docs/docs/how-tos/assets/graph_api_image_9.png differ
diff --git a/docs/docs/how-tos/auth/custom_auth.md b/docs/docs/how-tos/auth/custom_auth.md
index 64f95e1ef..2b1dd035c 100644
--- a/docs/docs/how-tos/auth/custom_auth.md
+++ b/docs/docs/how-tos/auth/custom_auth.md
@@ -1,138 +1,176 @@
# Add custom authentication
-!!! tip "Prerequisites"
-
- This guide assumes familiarity with the following concepts:
-
- * [**Authentication & Access Control**](../../concepts/auth.md)
- * [**LangGraph Platform**](../../concepts/langgraph_platform.md)
-
- For a more guided walkthrough, see [**setting up custom authentication**](../../tutorials/auth/getting_started.md) tutorial.
-
-???+ note "Support by deployment type"
-
- Custom auth is supported for all deployments in the **managed LangGraph Platform**, as well as **Enterprise** self-hosted plans. It is not supported for **Lite** self-hosted plans.
-
This guide shows how to add custom authentication to your LangGraph Platform application. This guide applies to both LangGraph Platform and self-hosted deployments. It does not apply to isolated usage of the LangGraph open source library in your own custom server.
-## 1. Implement authentication
+!!! note
+
+ Custom auth is supported for all **managed LangGraph Platform** deployments, as well as **Enterprise** self-hosted plans. It is not supported for **Lite** self-hosted plans.
+
+## Add custom authentication to your deployment
+
+To leverage custom authentication and access user-level metadata in your deployments, set up custom authentication to automatically populate the `config["configurable"]["langgraph_auth_user"]` object through a custom authentication handler. You can then access this object in your graph with the `langgraph_auth_user` key to [allow an agent to perform authenticated actions on behalf of the user](#enable-agent-authentication).
+
+1. Implement authentication:
+
+ !!! note
+
+ Without a custom `@auth.authenticate` handler, LangGraph sees only the API-key owner (usually the developer), so requests aren’t scoped to individual end-users. To propagate custom tokens, you must implement your own handler.
+
+ ```python
+ from langgraph_sdk import Auth
+ import requests
+
+ auth = Auth()
+
+ def is_valid_key(api_key: str) -> bool:
+ is_valid = # your API key validation logic
+ return is_valid
+
+ @auth.authenticate # (1)!
+ async def authenticate(headers: dict) -> Auth.types.MinimalUserDict:
+ api_key = headers.get("x-api-key")
+ if not api_key or not is_valid_key(api_key):
+ raise Auth.exceptions.HTTPException(status_code=401, detail="Invalid API key")
+
+ # Fetch user-specific tokens from your secret store
+ user_tokens = await fetch_user_tokens(api_key)
+
+ return { # (2)!
+ "identity": api_key, # fetch user ID from LangSmith
+ "github_token" : user_tokens.github_token
+ "jira_token" : user_tokens.jira_token
+ # ... custom fields/secrets here
+ }
+ ```
+
+ 1. This handler receives the request (headers, etc.), validates the user, and returns a dictionary with at least an identity field.
+ 2. You can add any custom fields you want (e.g., OAuth tokens, roles, org IDs, etc.).
+
+2. In your `langgraph.json`, add the path to your auth file:
+
+ ```json hl_lines="7-9"
+ {
+ "dependencies": ["."],
+ "graphs": {
+ "agent": "./agent.py:graph"
+ },
+ "env": ".env",
+ "auth": {
+ "path": "./auth.py:my_auth"
+ }
+ }
+ ```
+
+3. Once you've set up authentication in your server, requests must include the required authorization information based on your chosen scheme. Assuming you are using JWT token authentication, you could access your deployments using any of the following methods:
+
+ === "Python Client"
+
+ ```python
+ from langgraph_sdk import get_client
+
+ my_token = "your-token" # In practice, you would generate a signed token with your auth provider
+ client = get_client(
+ url="http://localhost:2024",
+ headers={"Authorization": f"Bearer {my_token}"}
+ )
+ threads = await client.threads.search()
+ ```
+
+ === "Python RemoteGraph"
+
+ ```python
+ from langgraph.pregel.remote import RemoteGraph
+
+ my_token = "your-token" # In practice, you would generate a signed token with your auth provider
+ remote_graph = RemoteGraph(
+ "agent",
+ url="http://localhost:2024",
+ headers={"Authorization": f"Bearer {my_token}"}
+ )
+ threads = await remote_graph.ainvoke(...)
+ ```
+
+ === "JavaScript Client"
+
+ ```javascript
+ import { Client } from "@langchain/langgraph-sdk";
+
+ const my_token = "your-token"; // In practice, you would generate a signed token with your auth provider
+ const client = new Client({
+ apiUrl: "http://localhost:2024",
+ defaultHeaders: { Authorization: `Bearer ${my_token}` },
+ });
+ const threads = await client.threads.search();
+ ```
+
+ === "JavaScript RemoteGraph"
+
+ ```javascript
+ import { RemoteGraph } from "@langchain/langgraph/remote";
+
+ const my_token = "your-token"; // In practice, you would generate a signed token with your auth provider
+ const remoteGraph = new RemoteGraph({
+ graphId: "agent",
+ url: "http://localhost:2024",
+ headers: { Authorization: `Bearer ${my_token}` },
+ });
+ const threads = await remoteGraph.invoke(...);
+ ```
+
+ === "CURL"
+
+ ```bash
+ curl -H "Authorization: Bearer ${your-token}" http://localhost:2024/threads
+ ```
+
+## Enable agent authentication
+
+After [authentication](#add-custom-authentication-to-your-deployment), the platform creates a special configuration object (`config`) that is passed to LangGraph Platform deployment. This object contains information about the current user, including any custom fields you return from your `@auth.authenticate` handler.
+
+To allow an agent to perform authenticated actions on behalf of the user, access this object in your graph with the `langgraph_auth_user` key:
```python
-from langgraph_sdk import Auth
+def my_node(state, config):
+ user_config = config["configurable"].get("langgraph_auth_user")
+ # token was resolved during the @auth.authenticate function
+ token = user_config.get("github_token","")
+ ...
+```
-my_auth = Auth()
+!!! note
+ Fetch user credentials from a secure secret store. Storing secrets in graph state is not recommended.
-@my_auth.authenticate
-async def authenticate(authorization: str) -> str:
- token = authorization.split(" ", 1)[-1] # "Bearer "
- try:
- # Verify token with your auth provider
- user_id = await verify_token(token)
- return user_id
- except Exception:
- raise Auth.exceptions.HTTPException(
- status_code=401,
- detail="Invalid token"
- )
+### Authorizing a Studio user
-# Add authorization rules to actually control access to resources
-@my_auth.on
+By default, if you add custom authorization on your resources, this will also apply to interactions made from the Studio. If you want, you can handle logged-in Studio users differently by checking [is_studio_user()](../../reference/functions/sdk_auth.isStudioUser.html).
+
+!!! note
+ `is_studio_user` was added in version 0.1.73 of the langgraph-sdk. If you're on an older version, you can still check whether `isinstance(ctx.user, StudioUser)`.
+
+```python
+from langgraph_sdk.auth import is_studio_user, Auth
+auth = Auth()
+
+# ... Setup authenticate, etc.
+
+@auth.on
async def add_owner(
ctx: Auth.types.AuthContext,
- value: dict,
-):
- """Add owner to resource metadata and filter by owner."""
+ value: dict # The payload being sent to this access method
+) -> dict: # Returns a filter dict that restricts access to resources
+ if is_studio_user(ctx.user):
+ return {}
+
filters = {"owner": ctx.user.identity}
metadata = value.setdefault("metadata", {})
metadata.update(filters)
return filters
-
-# Assumes you organize information in store like (user_id, resource_type, resource_id)
-@my_auth.on.store()
-async def authorize_store(ctx: Auth.types.AuthContext, value: dict):
- namespace: tuple = value["namespace"]
- assert namespace[0] == ctx.user.identity, "Not authorized"
-
```
-## 2. Update configuration
+Only use this if you want to permit developer access to a graph deployed on the managed LangGraph Platform SaaS.
-In your `langgraph.json`, add the path to your auth file:
+## Learn more
-```json hl_lines="7-9"
-{
- "dependencies": ["."],
- "graphs": {
- "agent": "./agent.py:graph"
- },
- "env": ".env",
- "auth": {
- "path": "./auth.py:my_auth"
- }
-}
-```
-
-## 3. Connect from the client
-
-Once you've set up authentication in your server, requests must include the required authorization information based on your chosen scheme.
-Assuming you are using JWT token authentication, you could access your deployments using any of the following methods:
-
-=== "Python Client"
-
- ```python
- from langgraph_sdk import get_client
-
- my_token = "your-token" # In practice, you would generate a signed token with your auth provider
- client = get_client(
- url="http://localhost:2024",
- headers={"Authorization": f"Bearer {my_token}"}
- )
- threads = await client.threads.search()
- ```
-
-=== "Python RemoteGraph"
-
- ```python
- from langgraph.pregel.remote import RemoteGraph
-
- my_token = "your-token" # In practice, you would generate a signed token with your auth provider
- remote_graph = RemoteGraph(
- "agent",
- url="http://localhost:2024",
- headers={"Authorization": f"Bearer {my_token}"}
- )
- threads = await remote_graph.ainvoke(...)
- ```
-
-=== "JavaScript Client"
-
- ```javascript
- import { Client } from "@langchain/langgraph-sdk";
-
- const my_token = "your-token"; // In practice, you would generate a signed token with your auth provider
- const client = new Client({
- apiUrl: "http://localhost:2024",
- defaultHeaders: { Authorization: `Bearer ${my_token}` },
- });
- const threads = await client.threads.search();
- ```
-
-=== "JavaScript RemoteGraph"
-
- ```javascript
- import { RemoteGraph } from "@langchain/langgraph/remote";
-
- const my_token = "your-token"; // In practice, you would generate a signed token with your auth provider
- const remoteGraph = new RemoteGraph({
- graphId: "agent",
- url: "http://localhost:2024",
- headers: { Authorization: `Bearer ${my_token}` },
- });
- const threads = await remoteGraph.invoke(...);
- ```
-
-=== "CURL"
-
- ```bash
- curl -H "Authorization: Bearer ${your-token}" http://localhost:2024/threads
- ```
+- [Authentication & Access Control](../../concepts/auth.md)
+- [LangGraph Platform](../../concepts/langgraph_platform.md)
+- [Setting up custom authentication tutorial](../../tutorials/auth/getting_started.md)
diff --git a/docs/docs/how-tos/autogen-integration.ipynb b/docs/docs/how-tos/autogen-integration.ipynb
deleted file mode 100644
index 5e58a260c..000000000
--- a/docs/docs/how-tos/autogen-integration.ipynb
+++ /dev/null
@@ -1,406 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "100c0c81-6a9f-4ba1-b1a8-42aae82b7172",
- "metadata": {},
- "source": [
- "# How to integrate LangGraph with AutoGen, CrewAI, and other frameworks\n",
- "\n",
- "LangGraph is a framework for building agentic and multi-agent applications. LangGraph can be easily integrated with other agent frameworks. \n",
- "\n",
- "The primary reasons you might want to integrate LangGraph with other agent frameworks:\n",
- "\n",
- "- create [multi-agent systems](../../concepts/multi_agent) where individual agents are built with different frameworks\n",
- "- leverage LangGraph to add features like [persistence](../../concepts/persistence), [streaming](../../concepts/streaming), [short and long-term memory](../../concepts/memory) and more\n",
- "\n",
- "The simplest way to integrate agents from other frameworks is by calling those agents inside a LangGraph [node](../../concepts/low_level/#nodes):\n",
- "\n",
- "```python\n",
- "from langgraph.graph import StateGraph, MessagesState, START\n",
- "\n",
- "autogen_agent = autogen.AssistantAgent(name=\"assistant\", ...)\n",
- "user_proxy = autogen.UserProxyAgent(name=\"user_proxy\", ...)\n",
- "\n",
- "def call_autogen_agent(state: MessagesState):\n",
- " response = user_proxy.initiate_chat(\n",
- " autogen_agent,\n",
- " message=state[\"messages\"][-1],\n",
- " ...\n",
- " )\n",
- " ...\n",
- "\n",
- "graph = (\n",
- " StateGraph(MessagesState)\n",
- " .add_node(call_autogen_agent)\n",
- " .add_edge(START, \"call_autogen_agent\")\n",
- " .compile()\n",
- ")\n",
- "\n",
- "graph.invoke({\n",
- " \"messages\": [\n",
- " {\n",
- " \"role\": \"user\",\n",
- " \"content\": \"Find numbers between 10 and 30 in fibonacci sequence\",\n",
- " }\n",
- " ]\n",
- "})\n",
- "```\n",
- "\n",
- "In this guide we show how to build a LangGraph chatbot that integrates with AutoGen, but you can follow the same approach with other frameworks."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "b189ceb2-132b-4c7b-81b4-c7b8b062f833",
- "metadata": {},
- "source": [
- "## Setup"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "62417d3a-94f9-4a52-9962-12639d714966",
- "metadata": {},
- "outputs": [],
- "source": [
- "%pip install autogen langgraph"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "d46da41d-0a71-4654-aec8-9e6ad8765236",
- "metadata": {},
- "outputs": [
- {
- "name": "stdin",
- "output_type": "stream",
- "text": [
- "OPENAI_API_KEY: ········\n"
- ]
- }
- ],
- "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": "1926bbc3-6b06-41e0-9604-860a2bbf8fa3",
- "metadata": {},
- "source": [
- "## Define AutoGen agent\n",
- "\n",
- "Here we define our AutoGen agent. Adapted from official tutorial [here](https://github.com/microsoft/autogen/blob/0.2/notebook/agentchat_web_info.ipynb)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "524de117-ff09-4b26-bfe8-a9f85a46ffd5",
- "metadata": {},
- "outputs": [],
- "source": [
- "import autogen\n",
- "import os\n",
- "\n",
- "config_list = [{\"model\": \"gpt-4o\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]\n",
- "\n",
- "llm_config = {\n",
- " \"timeout\": 600,\n",
- " \"cache_seed\": 42,\n",
- " \"config_list\": config_list,\n",
- " \"temperature\": 0,\n",
- "}\n",
- "\n",
- "autogen_agent = autogen.AssistantAgent(\n",
- " name=\"assistant\",\n",
- " llm_config=llm_config,\n",
- ")\n",
- "\n",
- "user_proxy = autogen.UserProxyAgent(\n",
- " name=\"user_proxy\",\n",
- " human_input_mode=\"NEVER\",\n",
- " max_consecutive_auto_reply=10,\n",
- " is_termination_msg=lambda x: x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n",
- " code_execution_config={\n",
- " \"work_dir\": \"web\",\n",
- " \"use_docker\": False,\n",
- " }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n",
- " llm_config=llm_config,\n",
- " system_message=\"Reply TERMINATE if the task has been solved at full satisfaction. Otherwise, reply CONTINUE, or the reason why the task is not solved yet.\",\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8aa858e2-4acb-4f75-be20-b9ccbbcb5073",
- "metadata": {},
- "source": [
- "---"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "dcc478f5-4a35-43f8-bf59-9cb71289cd00",
- "metadata": {},
- "source": [
- "## Create the graph\n",
- "\n",
- "We will now create a LangGraph chatbot graph that calls AutoGen agent."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "d129e4e1-3766-429a-b806-cde3d8bc0469",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langchain_core.messages import convert_to_openai_messages\n",
- "from langgraph.graph import StateGraph, MessagesState, START\n",
- "from langgraph.checkpoint.memory import MemorySaver\n",
- "\n",
- "\n",
- "def call_autogen_agent(state: MessagesState):\n",
- " # convert to openai-style messages\n",
- " messages = convert_to_openai_messages(state[\"messages\"])\n",
- " response = user_proxy.initiate_chat(\n",
- " autogen_agent,\n",
- " message=messages[-1],\n",
- " # pass previous message history as context\n",
- " carryover=messages[:-1],\n",
- " )\n",
- " # get the final response from the agent\n",
- " content = response.chat_history[-1][\"content\"]\n",
- " return {\"messages\": {\"role\": \"assistant\", \"content\": content}}\n",
- "\n",
- "\n",
- "# add short-term memory for storing conversation history\n",
- "checkpointer = MemorySaver()\n",
- "\n",
- "builder = StateGraph(MessagesState)\n",
- "builder.add_node(call_autogen_agent)\n",
- "builder.add_edge(START, \"call_autogen_agent\")\n",
- "graph = builder.compile(checkpointer=checkpointer)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "c761fc05-e8b6-4905-a793-eb7522d20060",
- "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": "23d629c3-1d6b-40af-adf6-915e15657566",
- "metadata": {},
- "source": [
- "## Run the graph\n",
- "\n",
- "We can now run the graph."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "a279b667-0f5d-4008-8d43-c806a3f379c4",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001B[33muser_proxy\u001B[0m (to assistant):\n",
- "\n",
- "Find numbers between 10 and 30 in fibonacci sequence\n",
- "\n",
- "--------------------------------------------------------------------------------\n",
- "\u001B[33massistant\u001B[0m (to user_proxy):\n",
- "\n",
- "To find numbers between 10 and 30 in the Fibonacci sequence, we can generate the Fibonacci sequence and check which numbers fall within this range. Here's a plan:\n",
- "\n",
- "1. Generate Fibonacci numbers starting from 0.\n",
- "2. Continue generating until the numbers exceed 30.\n",
- "3. Collect and print the numbers that are between 10 and 30.\n",
- "\n",
- "Let's implement this in Python:\n",
- "\n",
- "```python\n",
- "# filename: fibonacci_range.py\n",
- "\n",
- "def fibonacci_sequence():\n",
- " a, b = 0, 1\n",
- " while a <= 30:\n",
- " if 10 <= a <= 30:\n",
- " print(a)\n",
- " a, b = b, a + b\n",
- "\n",
- "fibonacci_sequence()\n",
- "```\n",
- "\n",
- "This script will print the Fibonacci numbers between 10 and 30. Please execute the code to see the result.\n",
- "\n",
- "--------------------------------------------------------------------------------\n",
- "\u001B[31m\n",
- ">>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...\u001B[0m\n",
- "\u001B[33muser_proxy\u001B[0m (to assistant):\n",
- "\n",
- "exitcode: 0 (execution succeeded)\n",
- "Code output: \n",
- "13\n",
- "21\n",
- "\n",
- "\n",
- "--------------------------------------------------------------------------------\n",
- "\u001B[33massistant\u001B[0m (to user_proxy):\n",
- "\n",
- "The Fibonacci numbers between 10 and 30 are 13 and 21. \n",
- "\n",
- "These numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1. \n",
- "\n",
- "The sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\n",
- "\n",
- "As you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30.\n",
- "\n",
- "TERMINATE\n",
- "\n",
- "--------------------------------------------------------------------------------\n",
- "{'call_autogen_agent': {'messages': {'role': 'assistant', 'content': 'The Fibonacci numbers between 10 and 30 are 13 and 21. \\n\\nThese numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1. \\n\\nThe sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\\n\\nAs you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30.\\n\\nTERMINATE'}}}\n"
- ]
- }
- ],
- "source": [
- "# pass the thread ID to persist agent outputs for future interactions\n",
- "# highlight-next-line\n",
- "config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
- "\n",
- "for chunk in graph.stream(\n",
- " {\n",
- " \"messages\": [\n",
- " {\n",
- " \"role\": \"user\",\n",
- " \"content\": \"Find numbers between 10 and 30 in fibonacci sequence\",\n",
- " }\n",
- " ]\n",
- " },\n",
- " # highlight-next-line\n",
- " config,\n",
- "):\n",
- " print(chunk)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "c6cd57b4-d4ee-49f6-be12-318613849669",
- "metadata": {},
- "source": [
- "Since we're leveraging LangGraph's [persistence](https://langchain-ai.github.io/langgraph/concepts/persistence/) features we can now continue the conversation using the same thread ID -- LangGraph will automatically pass previous history to the AutoGen agent:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "e68811a7-962e-4fe3-9f45-9b99ebbe04e7",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "\u001B[33muser_proxy\u001B[0m (to assistant):\n",
- "\n",
- "Multiply the last number by 3\n",
- "Context: \n",
- "Find numbers between 10 and 30 in fibonacci sequence\n",
- "The Fibonacci numbers between 10 and 30 are 13 and 21. \n",
- "\n",
- "These numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1. \n",
- "\n",
- "The sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\n",
- "\n",
- "As you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30.\n",
- "\n",
- "TERMINATE\n",
- "\n",
- "--------------------------------------------------------------------------------\n",
- "\u001B[33massistant\u001B[0m (to user_proxy):\n",
- "\n",
- "The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives:\n",
- "\n",
- "21 * 3 = 63\n",
- "\n",
- "TERMINATE\n",
- "\n",
- "--------------------------------------------------------------------------------\n",
- "{'call_autogen_agent': {'messages': {'role': 'assistant', 'content': 'The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives:\\n\\n21 * 3 = 63\\n\\nTERMINATE'}}}\n"
- ]
- }
- ],
- "source": [
- "for chunk in graph.stream(\n",
- " {\n",
- " \"messages\": [\n",
- " {\n",
- " \"role\": \"user\",\n",
- " \"content\": \"Multiply the last number by 3\",\n",
- " }\n",
- " ]\n",
- " },\n",
- " # highlight-next-line\n",
- " config,\n",
- "):\n",
- " print(chunk)"
- ]
- }
- ],
- "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.12.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/docs/how-tos/autogen-integration.md b/docs/docs/how-tos/autogen-integration.md
new file mode 100644
index 000000000..efbcf3d30
--- /dev/null
+++ b/docs/docs/how-tos/autogen-integration.md
@@ -0,0 +1,321 @@
+# How to integrate LangGraph with AutoGen, CrewAI, and other frameworks
+
+This guide shows how to integrate AutoGen agents with LangGraph to leverage features like persistence, streaming, and memory, and then deploy the integrated solution to LangGraph Platform for scalable production use. In this guide we show how to build a LangGraph chatbot that integrates with AutoGen, but you can follow the same approach with other frameworks.
+
+Integrating AutoGen with LangGraph provides several benefits:
+
+- Enhanced features: Add [persistence](../concepts/persistence.md), [streaming](../concepts/streaming.md), [short and long-term memory](../concepts/memory.md) and more to your AutoGen agents.
+- Multi-agent systems: Build [multi-agent systems](../concepts/multi_agent.md) where individual agents are built with different frameworks.
+- Production deployment: Deploy your integrated solution to [LangGraph Platform](../concepts/langgraph_platform.md) for scalable production use.
+
+## Prerequisites
+
+- Python 3.9+
+- Autogen: `pip install autogen`
+- LangGraph: `pip install langgraph`
+- OpenAI API key
+
+## Setup
+
+Set your your environment:
+
+```python
+import getpass
+import os
+
+
+def _set_env(var: str):
+ if not os.environ.get(var):
+ os.environ[var] = getpass.getpass(f"{var}: ")
+
+
+_set_env("OPENAI_API_KEY")
+```
+
+## 1. Define AutoGen agent
+
+Create an AutoGen agent that can execute code. This example is adapted from AutoGen's [official tutorials](https://github.com/microsoft/autogen/blob/0.2/notebook/agentchat_web_info.ipynb):
+
+```python
+import autogen
+import os
+
+config_list = [{"model": "gpt-4o", "api_key": os.environ["OPENAI_API_KEY"]}]
+
+llm_config = {
+ "timeout": 600,
+ "cache_seed": 42,
+ "config_list": config_list,
+ "temperature": 0,
+}
+
+autogen_agent = autogen.AssistantAgent(
+ name="assistant",
+ llm_config=llm_config,
+)
+
+user_proxy = autogen.UserProxyAgent(
+ name="user_proxy",
+ human_input_mode="NEVER",
+ max_consecutive_auto_reply=10,
+ is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
+ code_execution_config={
+ "work_dir": "web",
+ "use_docker": False,
+ }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.
+ llm_config=llm_config,
+ system_message="Reply TERMINATE if the task has been solved at full satisfaction. Otherwise, reply CONTINUE, or the reason why the task is not solved yet.",
+)
+```
+
+## 2. Create the graph
+
+We will now create a LangGraph chatbot graph that calls AutoGen agent.
+
+```python
+from langchain_core.messages import convert_to_openai_messages
+from langgraph.graph import StateGraph, MessagesState, START
+from langgraph.checkpoint.memory import MemorySaver
+
+def call_autogen_agent(state: MessagesState):
+ # Convert LangGraph messages to OpenAI format for AutoGen
+ messages = convert_to_openai_messages(state["messages"])
+
+ # Get the last user message
+ last_message = messages[-1]
+
+ # Pass previous message history as context (excluding the last message)
+ carryover = messages[:-1] if len(messages) > 1 else []
+
+ # Initiate chat with AutoGen
+ response = user_proxy.initiate_chat(
+ autogen_agent,
+ message=last_message,
+ carryover=carryover
+ )
+
+ # Extract the final response from the agent
+ final_content = response.chat_history[-1]["content"]
+
+ # Return the response in LangGraph format
+ return {"messages": {"role": "assistant", "content": final_content}}
+
+# Create the graph with memory for persistence
+checkpointer = MemorySaver()
+
+# Build the graph
+builder = StateGraph(MessagesState)
+builder.add_node("autogen", call_autogen_agent)
+builder.add_edge(START, "autogen")
+
+# Compile with checkpointer for persistence
+graph = builder.compile(checkpointer=checkpointer)
+```
+
+```python
+from IPython.display import display, Image
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+## 3. Test the graph locally
+
+Before deploying to LangGraph Platform, you can test the graph locally:
+
+```python
+# pass the thread ID to persist agent outputs for future interactions
+# highlight-next-line
+config = {"configurable": {"thread_id": "1"}}
+
+for chunk in graph.stream(
+ {
+ "messages": [
+ {
+ "role": "user",
+ "content": "Find numbers between 10 and 30 in fibonacci sequence",
+ }
+ ]
+ },
+ # highlight-next-line
+ config,
+):
+ print(chunk)
+```
+
+**Output:**
+```
+user_proxy (to assistant):
+
+Find numbers between 10 and 30 in fibonacci sequence
+
+--------------------------------------------------------------------------------
+assistant (to user_proxy):
+
+To find numbers between 10 and 30 in the Fibonacci sequence, we can generate the Fibonacci sequence and check which numbers fall within this range. Here's a plan:
+
+1. Generate Fibonacci numbers starting from 0.
+2. Continue generating until the numbers exceed 30.
+3. Collect and print the numbers that are between 10 and 30.
+
+...
+```
+
+Since we're leveraging LangGraph's [persistence](https://langchain-ai.github.io/langgraph/concepts/persistence/) features we can now continue the conversation using the same thread ID -- LangGraph will automatically pass previous history to the AutoGen agent:
+
+```python
+for chunk in graph.stream(
+ {
+ "messages": [
+ {
+ "role": "user",
+ "content": "Multiply the last number by 3",
+ }
+ ]
+ },
+ # highlight-next-line
+ config,
+):
+ print(chunk)
+```
+
+**Output:**
+```
+user_proxy (to assistant):
+
+Multiply the last number by 3
+Context:
+Find numbers between 10 and 30 in fibonacci sequence
+The Fibonacci numbers between 10 and 30 are 13 and 21.
+
+These numbers are part of the Fibonacci sequence, which is generated by adding the two preceding numbers to get the next number, starting from 0 and 1.
+
+The sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
+
+As you can see, 13 and 21 are the only numbers in this sequence that fall between 10 and 30.
+
+TERMINATE
+
+--------------------------------------------------------------------------------
+assistant (to user_proxy):
+
+The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives:
+
+21 * 3 = 63
+
+TERMINATE
+
+--------------------------------------------------------------------------------
+{'call_autogen_agent': {'messages': {'role': 'assistant', 'content': 'The last number in the Fibonacci sequence between 10 and 30 is 21. Multiplying 21 by 3 gives:\n\n21 * 3 = 63\n\nTERMINATE'}}}
+```
+
+## 4. Prepare for deployment
+
+To deploy to LangGraph Platform, create a file structure like the following:
+
+```
+my-autogen-agent/
+├── agent.py # Your main agent code
+├── requirements.txt # Python dependencies
+└── langgraph.json # LangGraph configuration
+```
+
+=== "agent.py"
+
+ ```python
+ import os
+ import autogen
+ from langchain_core.messages import convert_to_openai_messages
+ from langgraph.graph import StateGraph, MessagesState, START
+ from langgraph.checkpoint.memory import MemorySaver
+
+ # AutoGen configuration
+ config_list = [{"model": "gpt-4o", "api_key": os.environ["OPENAI_API_KEY"]}]
+
+ llm_config = {
+ "timeout": 600,
+ "cache_seed": 42,
+ "config_list": config_list,
+ "temperature": 0,
+ }
+
+ # Create AutoGen agents
+ autogen_agent = autogen.AssistantAgent(
+ name="assistant",
+ llm_config=llm_config,
+ )
+
+ user_proxy = autogen.UserProxyAgent(
+ name="user_proxy",
+ human_input_mode="NEVER",
+ max_consecutive_auto_reply=10,
+ is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
+ code_execution_config={
+ "work_dir": "/tmp/autogen_work",
+ "use_docker": False,
+ },
+ llm_config=llm_config,
+ system_message="Reply TERMINATE if the task has been solved at full satisfaction.",
+ )
+
+ def call_autogen_agent(state: MessagesState):
+ """Node function that calls the AutoGen agent"""
+ messages = convert_to_openai_messages(state["messages"])
+ last_message = messages[-1]
+ carryover = messages[:-1] if len(messages) > 1 else []
+
+ response = user_proxy.initiate_chat(
+ autogen_agent,
+ message=last_message,
+ carryover=carryover
+ )
+
+ final_content = response.chat_history[-1]["content"]
+ return {"messages": {"role": "assistant", "content": final_content}}
+
+ # Create and compile the graph
+ def create_graph():
+ checkpointer = MemorySaver()
+ builder = StateGraph(MessagesState)
+ builder.add_node("autogen", call_autogen_agent)
+ builder.add_edge(START, "autogen")
+ return builder.compile(checkpointer=checkpointer)
+
+ # Export the graph for LangGraph Platform
+ graph = create_graph()
+ ```
+
+=== "requirements.txt"
+
+ ```
+ langgraph>=0.1.0
+ pyautogen>=0.2.0
+ langchain-core>=0.1.0
+ langchain-openai>=0.0.5
+ ```
+
+=== "langgraph.json"
+
+ ```json
+ {
+ "dependencies": ["."],
+ "graphs": {
+ "autogen_agent": "./agent.py:graph"
+ },
+ "env": ".env"
+ }
+ ```
+
+
+## 5. Deploy to LangGraph Platform
+
+Deploy the graph with the LangGraph Platform CLI:
+
+```
+pip install -U langgraph-cli
+```
+
+```
+langgraph deploy --config langgraph.json
+```
diff --git a/docs/docs/how-tos/autogen-langgraph-platform.ipynb b/docs/docs/how-tos/autogen-langgraph-platform.ipynb
deleted file mode 100644
index 29bd24ba5..000000000
--- a/docs/docs/how-tos/autogen-langgraph-platform.ipynb
+++ /dev/null
@@ -1,171 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "8381b6e0-29a6-48c5-b451-5d2549351249",
- "metadata": {},
- "source": [
- "# How to use LangGraph Platform to deploy CrewAI, AutoGen, and other frameworks\n",
- "\n",
- "[LangGraph Platform](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/) provides infrastructure for deploying agents. This integrates seamlessly with LangGraph, but can also work with other frameworks. The way to make this work is to wrap the agent in a single LangGraph node, and have that be the entire graph.\n",
- "\n",
- "Doing so will allow you to deploy to LangGraph Platform, and allows you to get a lot of the [benefits](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform/). You get horizontally scalable infrastructure, a task queue to handle bursty operations, a persistence layer to power short term memory, and long term memory support.\n",
- "\n",
- "In this guide we show how to do this with an AutoGen agent, but this method should work for agents defined in other frameworks like CrewAI, LlamaIndex, and others as well."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "1113cb16-b538-448c-924c-85731ce96ebd",
- "metadata": {},
- "source": [
- "## Setup"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "f05993fa-9d03-4f45-bc13-0a8d87260d86",
- "metadata": {
- "scrolled": true
- },
- "outputs": [],
- "source": [
- "%pip install autogen langgraph"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "f4e0ca12-1714-4776-a30a-9527e519799b",
- "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": "1926bbc3-6b06-41e0-9604-860a2bbf8fa3",
- "metadata": {},
- "source": [
- "## Define autogen agent\n",
- "\n",
- "Here we define our AutoGen agent. From https://github.com/microsoft/autogen/blob/0.2/notebook/agentchat_web_info.ipynb"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "d4a14dc7-d565-4207-8788-525f85b9fb27",
- "metadata": {},
- "outputs": [],
- "source": [
- "import autogen\n",
- "import os\n",
- "\n",
- "config_list = [{\"model\": \"gpt-4o\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]\n",
- "\n",
- "llm_config = {\n",
- " \"timeout\": 600,\n",
- " \"cache_seed\": 42,\n",
- " \"config_list\": config_list,\n",
- " \"temperature\": 0,\n",
- "}\n",
- "\n",
- "autogen_agent = autogen.AssistantAgent(\n",
- " name=\"assistant\",\n",
- " llm_config=llm_config,\n",
- ")\n",
- "\n",
- "user_proxy = autogen.UserProxyAgent(\n",
- " name=\"user_proxy\",\n",
- " human_input_mode=\"NEVER\",\n",
- " max_consecutive_auto_reply=10,\n",
- " is_termination_msg=lambda x: x.get(\"content\", \"\").rstrip().endswith(\"TERMINATE\"),\n",
- " code_execution_config={\n",
- " \"work_dir\": \"web\",\n",
- " \"use_docker\": False,\n",
- " }, # Please set use_docker=True if docker is available to run the generated code. Using docker is safer than running the generated code directly.\n",
- " llm_config=llm_config,\n",
- " system_message=\"Reply TERMINATE if the task has been solved at full satisfaction. Otherwise, reply CONTINUE, or the reason why the task is not solved yet.\",\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "b1170836-f23e-4e4c-ab83-ce791cd7fbd2",
- "metadata": {},
- "source": [
- "## Wrap in LangGraph\n",
- "\n",
- "We now wrap the AutoGen agent in a single LangGraph node, and make that the entire graph.\n",
- "The main thing this involves is defining an Input and Output schema for the node, which you would need to do if deploying this manually, so it's no extra work"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "7b417c16-ff4e-4d5c-a9a9-0aaeeef6ede5",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph import StateGraph, MessagesState\n",
- "\n",
- "\n",
- "def call_autogen_agent(state: MessagesState):\n",
- " last_message = state[\"messages\"][-1]\n",
- " response = user_proxy.initiate_chat(autogen_agent, message=last_message.content)\n",
- " # get the final response from the agent\n",
- " content = response.chat_history[-1][\"content\"]\n",
- " return {\"messages\": {\"role\": \"assistant\", \"content\": content}}\n",
- "\n",
- "\n",
- "graph = StateGraph(MessagesState)\n",
- "graph.add_node(call_autogen_agent)\n",
- "graph.set_entry_point(\"call_autogen_agent\")\n",
- "graph = graph.compile()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f6a18377-ac29-478f-a76a-b213f1a3c85d",
- "metadata": {},
- "source": [
- "## Deploy with LangGraph Platform\n",
- "\n",
- "You can now deploy this as you normally would with LangGraph Platform. See [these instructions](https://langchain-ai.github.io/langgraph/concepts/deployment_options/) for more details."
- ]
- }
- ],
- "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.12.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/docs/how-tos/enable-tracing.md b/docs/docs/how-tos/enable-tracing.md
new file mode 100644
index 000000000..d1273b6d3
--- /dev/null
+++ b/docs/docs/how-tos/enable-tracing.md
@@ -0,0 +1,16 @@
+# Enable tracing for your application
+
+To enable [tracing](../concepts/tracing.md) for your application, set the following environment variables:
+
+```python
+export LANGSMITH_TRACING=true
+export LANGSMITH_API_KEY=
+```
+
+For more information, see [Trace with LangGraph](https://docs.smith.langchain.com/observability/how_to_guides/trace_with_langgraph).
+
+## Learn more
+
+- [Graph runs in LangSmith](../how-tos/run-id-langsmith.md)
+- [LangSmith Observability quickstart](https://docs.smith.langchain.com/observability)
+- [Tracing conceptual guide](https://docs.smith.langchain.com/observability/concepts#traces)
\ No newline at end of file
diff --git a/docs/docs/how-tos/graph-api.ipynb b/docs/docs/how-tos/graph-api.ipynb
deleted file mode 100644
index 9d890beae..000000000
--- a/docs/docs/how-tos/graph-api.ipynb
+++ /dev/null
@@ -1,3438 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "9c19faa1-795c-451e-95e4-7aa40a19aa20",
- "metadata": {},
- "source": [
- "# How to use the graph API\n",
- "\n",
- "This guide demonstrates the basics of LangGraph's Graph API. It walks through [state](#define-and-update-state), as well as composing common graph structures such as [sequences](#create-a-sequence-of-steps), [branches](#create-branches), and [loops](#create-and-control-loops). It also covers LangGraph's control features, including the [Send API](#map-reduce-and-the-send-api) for map-reduce workflows and the [Command API](#combine-control-flow-and-state-updates-with-command) for combining state updates with \"hops\" across nodes."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f6fcda61-9c21-43de-af0d-0d9efb063c40",
- "metadata": {},
- "source": [
- "## Setup\n",
- "\n",
- "Install `langgraph`:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "f031bc56-26f5-4ece-b27e-3c87b3b34f0a",
- "metadata": {},
- "outputs": [],
- "source": [
- "%pip install -qU langgraph"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "55c22136-74cc-495a-94ab-82ccac247cef",
- "metadata": {},
- "source": [
- "
\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 aps built with LangGraph — read more about how to get started in the docs. \n",
- "
\n",
- "
"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "b462f26d-8795-4dc2-9420-722d3e21656c",
- "metadata": {},
- "source": [
- "## Define and update state\n",
- "\n",
- "Here we show how to define and update [state](../../concepts/low_level/#state) in LangGraph. We will demonstrate:\n",
- "\n",
- "1. How to use state to define a graph's [schema](../../concepts/low_level/#schema)\n",
- "2. How to use [reducers](../../concepts/low_level/#reducers) to control how state updates are processed."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ca7ac66a-a3ae-43c6-bb9d-7ee2bd0030f0",
- "metadata": {},
- "source": [
- "### Define state\n",
- "\n",
- "[State](../../concepts/low_level/#state) in LangGraph can be a `TypedDict`, `Pydantic` model, or dataclass. Below we will use `TypedDict`. See [this section](#use-pydantic-models-for-graph-state) for detail on using Pydantic.\n",
- "\n",
- "By default, graphs will have the same input and output schema, and the state determines that schema. See [this section](#define-input-and-output-schemas) for how to define distinct input and output schemas.\n",
- "\n",
- "Let's consider a simple example using [messages](../../concepts/low_level/#messagesstate). This represents a versatile formulation of state for many LLM applications. See our [concepts page](../../concepts/low_level/#working-with-messages-in-graph-state) for more detail."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "e7c3b392-50fb-4af3-bf2d-7b769f47efc6",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langchain_core.messages import AnyMessage\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " messages: list[AnyMessage]\n",
- " extra_field: int"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "c3555791-9dc9-4593-923e-9aa599d4c547",
- "metadata": {},
- "source": [
- "This state tracks a list of [message](https://python.langchain.com/docs/concepts/messages/) objects, as well as an extra integer field.\n",
- "\n",
- "### Update state\n",
- "\n",
- "Let's build an example graph with a single node. Our [node](../../concepts/low_level/#nodes) is just a Python function that reads our graph's state and makes updates to it. The first argument to this function will always be the state:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "f5db493b-c977-4f15-a06f-27b460cd7e4c",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langchain_core.messages import AIMessage\n",
- "\n",
- "\n",
- "def node(state: State):\n",
- " messages = state[\"messages\"]\n",
- " new_message = AIMessage(\"Hello!\")\n",
- "\n",
- " return {\"messages\": messages + [new_message], \"extra_field\": 10}"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "9f6cef5d-2635-45bc-a415-b422bb571685",
- "metadata": {},
- "source": [
- "This node simply appends a message to our message list, and populates an extra field.\n",
- "\n",
- "!!! important\n",
- "\n",
- " Nodes should return updates to the state directly, instead of mutating the state.\n",
- "\n",
- "Let's next define a simple graph containing this node. We use [StateGraph](../../concepts/low_level/#stategraph) to define a graph that operates on this state. We then use [add_node](../../concepts/low_level/#nodes) populate our graph."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "92402ca2-9e46-4ad9-8378-83f98f597c00",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph import StateGraph\n",
- "\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(node)\n",
- "builder.set_entry_point(\"node\")\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f765d37d-3793-4ac9-90e5-fe28c6142202",
- "metadata": {},
- "source": [
- "LangGraph provides built-in utilities for visualizing your graph. Let's inspect our graph. See [this section](#visualize-your-graph) for detail on visualization."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "263470d0-a9fa-48bc-86b1-c5a28b242aec",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ca3cd1a1-38b1-4cbb-9301-5aec62659e70",
- "metadata": {},
- "source": [
- "In this case, our graph just executes a single node. Let's proceed with a simple invocation:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "7d932703-932f-48cb-842c-c372f82510f9",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'messages': [HumanMessage(content='Hi', additional_kwargs={}, response_metadata={}),\n",
- " AIMessage(content='Hello!', additional_kwargs={}, response_metadata={})],\n",
- " 'extra_field': 10}"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "from langchain_core.messages import HumanMessage\n",
- "\n",
- "result = graph.invoke({\"messages\": [HumanMessage(\"Hi\")]})\n",
- "result"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e5918e84-49ac-4ab1-80bb-863a2e5461e2",
- "metadata": {},
- "source": [
- "Note that:\n",
- "\n",
- "- We kicked off invocation by updating a single key of the state.\n",
- "- We receive the entire state in the invocation result.\n",
- "\n",
- "For convenience, we frequently inspect the content of [message objects](https://python.langchain.com/docs/concepts/messages/) via pretty-print:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "5009dbb2-77c3-47de-9d9d-3fc6e5b649b9",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "================================\u001b[1m Human Message \u001b[0m=================================\n",
- "\n",
- "Hi\n",
- "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
- "\n",
- "Hello!\n"
- ]
- }
- ],
- "source": [
- "for message in result[\"messages\"]:\n",
- " message.pretty_print()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "4c4da6ff-a677-41bf-b51e-f2826fc51926",
- "metadata": {},
- "source": [
- "### Process state updates with reducers\n",
- "\n",
- "Each key in the state can have its own independent [reducer](../../concepts/low_level/#reducers) function, which controls how updates from nodes are applied. If no reducer function is explicitly specified then it is assumed that all updates to the key should override it.\n",
- "\n",
- "For `TypedDict` state schemas, we can define reducers by annotating the corresponding field of the state with a reducer function.\n",
- "\n",
- "In the earlier example, our node updated the `\"messages\"` key in the state by appending a message to it. Below, we add a reducer to this key, such that updates are automatically appended:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "35db8bfc-8747-423f-858a-b4f069d6199f",
- "metadata": {},
- "outputs": [],
- "source": [
- "from typing_extensions import Annotated\n",
- "\n",
- "\n",
- "def add(left, right):\n",
- " \"\"\"Can also import `add` from the `operator` built-in.\"\"\"\n",
- " return left + right\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " # highlight-next-line\n",
- " messages: Annotated[list[AnyMessage], add]\n",
- " extra_field: int"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "4979a906-fff3-48de-9215-8a12b9bc4acf",
- "metadata": {},
- "source": [
- "Now our node can be simplified:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "f24f8d3f-973f-468e-8895-8c4cf01951dd",
- "metadata": {},
- "outputs": [],
- "source": [
- "def node(state: State):\n",
- " new_message = AIMessage(\"Hello!\")\n",
- " # highlight-next-line\n",
- " return {\"messages\": [new_message], \"extra_field\": 10}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "6ef429ed-a0fa-4c00-a88c-bb61df59f578",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "================================\u001b[1m Human Message \u001b[0m=================================\n",
- "\n",
- "Hi\n",
- "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
- "\n",
- "Hello!\n"
- ]
- }
- ],
- "source": [
- "from langgraph.graph import START\n",
- "\n",
- "\n",
- "graph = StateGraph(State).add_node(node).add_edge(START, \"node\").compile()\n",
- "\n",
- "result = graph.invoke({\"messages\": [HumanMessage(\"Hi\")]})\n",
- "\n",
- "for message in result[\"messages\"]:\n",
- " message.pretty_print()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "7827723b-64aa-4d8b-b17a-5a3bcd8206f7",
- "metadata": {},
- "source": [
- "#### MessagesState\n",
- "\n",
- "In practice, there are additional considerations for updating lists of messages:\n",
- "\n",
- "- We may wish to update an existing message in the state.\n",
- "- We may want to accept short-hands for [message formats](../../concepts/low_level/#using-messages-in-your-graph), such as [OpenAI format](https://python.langchain.com/docs/concepts/messages/#openai-format).\n",
- "\n",
- "LangGraph includes a built-in reducer `add_messages` that handles these considerations:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "89880b92-5d00-421f-83c3-46382c1d1c17",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph.message import add_messages\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " # highlight-next-line\n",
- " messages: Annotated[list[AnyMessage], add_messages]\n",
- " extra_field: int\n",
- "\n",
- "\n",
- "def node(state: State):\n",
- " new_message = AIMessage(\"Hello!\")\n",
- " return {\"messages\": [new_message], \"extra_field\": 10}\n",
- "\n",
- "\n",
- "graph = StateGraph(State).add_node(node).set_entry_point(\"node\").compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "51aeb731-e7f0-4d28-a096-436ef7fe004a",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "================================\u001b[1m Human Message \u001b[0m=================================\n",
- "\n",
- "Hi\n",
- "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
- "\n",
- "Hello!\n"
- ]
- }
- ],
- "source": [
- "# highlight-next-line\n",
- "input_message = {\"role\": \"user\", \"content\": \"Hi\"}\n",
- "\n",
- "result = graph.invoke({\"messages\": [input_message]})\n",
- "\n",
- "for message in result[\"messages\"]:\n",
- " message.pretty_print()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "17583dde-2520-464c-a962-eae511d0928e",
- "metadata": {},
- "source": [
- "This is a versatile representation of state for applications involving [chat models](https://python.langchain.com/docs/concepts/chat_models/). LangGraph includes a pre-built `MessagesState` for convenience, so that we can have:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "id": "05956122-5ba0-4b4c-8b66-6362982227f2",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph import MessagesState\n",
- "\n",
- "\n",
- "class State(MessagesState):\n",
- " extra_field: int"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f262985e-e973-4a27-9c9e-dbb3a06a35b7",
- "metadata": {},
- "source": [
- "### Define input and output schemas\n",
- "\n",
- "By default, `StateGraph` operates with a single schema, and all nodes are expected to communicate using that schema. However, it's also possible to define distinct input and output schemas for a graph.\n",
- "\n",
- "When distinct schemas are specified, an internal schema will still be used for communication between nodes. The input schema ensures that the provided input matches the expected structure, while the output schema filters the internal data to return only the relevant information according to the defined output schema.\n",
- "\n",
- "Below, we'll see how to define distinct input and output schema."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "6ec0eb77-874e-443e-8c73-93125b515106",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'answer': 'bye'}\n"
- ]
- }
- ],
- "source": [
- "from langgraph.graph import StateGraph, START, END\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "\n",
- "# Define the schema for the input\n",
- "class InputState(TypedDict):\n",
- " question: str\n",
- "\n",
- "\n",
- "# Define the schema for the output\n",
- "class OutputState(TypedDict):\n",
- " answer: str\n",
- "\n",
- "\n",
- "# Define the overall schema, combining both input and output\n",
- "class OverallState(InputState, OutputState):\n",
- " pass\n",
- "\n",
- "\n",
- "# Define the node that processes the input and generates an answer\n",
- "def answer_node(state: InputState):\n",
- " # Example answer and an extra key\n",
- " return {\"answer\": \"bye\", \"question\": state[\"question\"]}\n",
- "\n",
- "\n",
- "# Build the graph with input and output schemas specified\n",
- "builder = StateGraph(OverallState, input_schema=InputState, output_schema=OutputState)\n",
- "builder.add_node(answer_node) # Add the answer node\n",
- "builder.add_edge(START, \"answer_node\") # Define the starting edge\n",
- "builder.add_edge(\"answer_node\", END) # Define the ending edge\n",
- "graph = builder.compile() # Compile the graph\n",
- "\n",
- "# Invoke the graph with an input and print the result\n",
- "print(graph.invoke({\"question\": \"hi\"}))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6a68836f-98e1-4684-a8a6-c1473c73460c",
- "metadata": {},
- "source": [
- "Notice that the output of invoke only includes the output schema."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "47ed5db3-bda5-49e1-bf75-23e08c9a3af0",
- "metadata": {},
- "source": [
- "### Pass private state between nodes\n",
- "\n",
- "In some cases, you may want nodes to exchange information that is crucial for intermediate logic but doesn’t need to be part of the main schema of the graph. This private data is not relevant to the overall input/output of the graph and should only be shared between certain nodes.\n",
- "\n",
- "Below, we'll create an example sequential graph consisting of three nodes (node_1, node_2 and node_3), where private data is passed between the first two steps (node_1 and node_2), while the third step (node_3) only has access to the public overall state."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "ce5b944d-4597-4af9-a7b5-15a00325f3e0",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Entered node `node_1`:\n",
- "\tInput: {'a': 'set at start'}.\n",
- "\tReturned: {'private_data': 'set by node_1'}\n",
- "Entered node `node_2`:\n",
- "\tInput: {'private_data': 'set by node_1'}.\n",
- "\tReturned: {'a': 'set by node_2'}\n",
- "Entered node `node_3`:\n",
- "\tInput: {'a': 'set by node_2'}.\n",
- "\tReturned: {'a': 'set by node_3'}\n",
- "\n",
- "Output of graph invocation: {'a': 'set by node_3'}\n"
- ]
- }
- ],
- "source": [
- "from langgraph.graph import StateGraph, START, END\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "\n",
- "# The overall state of the graph (this is the public state shared across nodes)\n",
- "class OverallState(TypedDict):\n",
- " a: str\n",
- "\n",
- "\n",
- "# Output from node_1 contains private data that is not part of the overall state\n",
- "class Node1Output(TypedDict):\n",
- " private_data: str\n",
- "\n",
- "\n",
- "# The private data is only shared between node_1 and node_2\n",
- "def node_1(state: OverallState) -> Node1Output:\n",
- " output = {\"private_data\": \"set by node_1\"}\n",
- " print(f\"Entered node `node_1`:\\n\\tInput: {state}.\\n\\tReturned: {output}\")\n",
- " return output\n",
- "\n",
- "\n",
- "# Node 2 input only requests the private data available after node_1\n",
- "class Node2Input(TypedDict):\n",
- " private_data: str\n",
- "\n",
- "\n",
- "def node_2(state: Node2Input) -> OverallState:\n",
- " output = {\"a\": \"set by node_2\"}\n",
- " print(f\"Entered node `node_2`:\\n\\tInput: {state}.\\n\\tReturned: {output}\")\n",
- " return output\n",
- "\n",
- "\n",
- "# Node 3 only has access to the overall state (no access to private data from node_1)\n",
- "def node_3(state: OverallState) -> OverallState:\n",
- " output = {\"a\": \"set by node_3\"}\n",
- " print(f\"Entered node `node_3`:\\n\\tInput: {state}.\\n\\tReturned: {output}\")\n",
- " return output\n",
- "\n",
- "\n",
- "# Connect nodes in a sequence\n",
- "# node_2 accepts private data from node_1, whereas\n",
- "# node_3 does not see the private data.\n",
- "builder = StateGraph(OverallState).add_sequence([node_1, node_2, node_3])\n",
- "builder.add_edge(START, \"node_1\")\n",
- "graph = builder.compile()\n",
- "\n",
- "# Invoke the graph with the initial state\n",
- "response = graph.invoke(\n",
- " {\n",
- " \"a\": \"set at start\",\n",
- " }\n",
- ")\n",
- "\n",
- "print()\n",
- "print(f\"Output of graph invocation: {response}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "51466c8d-8ce4-4b3d-be4e-18fdbeda5f53",
- "metadata": {},
- "source": [
- "### Use Pydantic models for graph state\n",
- "\n",
- "A [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.StateGraph) accepts a `state_schema` argument on initialization that specifies the \"shape\" of the state that the nodes in the graph can access and update.\n",
- "\n",
- "In our examples, we typically use a python-native `TypedDict` for `state_schema`, but `state_schema` can be any [type](https://docs.python.org/3/library/stdtypes.html#type-objects).\n",
- "\n",
- "Here, we'll see how a [Pydantic BaseModel](https://docs.pydantic.dev/latest/api/base_model/). can be used for `state_schema` to add run time validation on **inputs**.\n",
- "\n",
- "\n",
- "
\n",
- "
Known Limitations
\n",
- "
\n",
- "
\n",
- "
\n",
- " Currently, the output of the graph will NOT be an instance of a pydantic model.\n",
- "
\n",
- "
\n",
- " Run-time validation only occurs on inputs into nodes, not on the outputs.\n",
- "
\n",
- "
\n",
- " The validation error trace from pydantic does not show which node the error arises in.\n",
- "
\n",
- "
\n",
- " \n",
- "
"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "efc46b36-425c-49c3-9f9e-d9785c70b034",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'a': 'goodbye'}"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "from langgraph.graph import StateGraph, START, END\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from pydantic import BaseModel\n",
- "\n",
- "\n",
- "# The overall state of the graph (this is the public state shared across nodes)\n",
- "class OverallState(BaseModel):\n",
- " a: str\n",
- "\n",
- "\n",
- "def node(state: OverallState):\n",
- " return {\"a\": \"goodbye\"}\n",
- "\n",
- "\n",
- "# Build the state graph\n",
- "builder = StateGraph(OverallState)\n",
- "builder.add_node(node) # node_1 is the first node\n",
- "builder.add_edge(START, \"node\") # Start the graph with node_1\n",
- "builder.add_edge(\"node\", END) # End the graph after node_1\n",
- "graph = builder.compile()\n",
- "\n",
- "# Test the graph with a valid input\n",
- "graph.invoke({\"a\": \"hello\"})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "25b594c2-8198-4f76-9606-ea47151ff9d1",
- "metadata": {},
- "source": [
- "Invoke the graph with an **invalid** input"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "05d7d43b-0b71-4e25-af6f-61d1560a46cb",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "An exception was raised because `a` is an integer rather than a string.\n",
- "1 validation error for OverallState\n",
- "a\n",
- " Input should be a valid string [type=string_type, input_value=123, input_type=int]\n",
- " For further information visit https://errors.pydantic.dev/2.9/v/string_type\n"
- ]
- }
- ],
- "source": [
- "try:\n",
- " graph.invoke({\"a\": 123}) # Should be a string\n",
- "except Exception as e:\n",
- " print(\"An exception was raised because `a` is an integer rather than a string.\")\n",
- " print(e)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "572ee9f1-45d2-428e-9b70-e7befaf2da80",
- "metadata": {},
- "source": [
- "See below for additional features of Pydantic model state:\n",
- "\n",
- "\n",
- "Serialization Behavior\n",
- "\n",
- "When using Pydantic models as state schemas, it's important to understand how serialization works, especially when:\n",
- "
\n",
- "
Passing Pydantic objects as inputs
\n",
- "
Receiving outputs from the graph
\n",
- "
Working with nested Pydantic models
\n",
- "
\n",
- "Let's see these behaviors in action.\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "0e919cdc",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph import StateGraph, START, END\n",
- "from pydantic import BaseModel\n",
- "\n",
- "\n",
- "class NestedModel(BaseModel):\n",
- " value: str\n",
- "\n",
- "\n",
- "class ComplexState(BaseModel):\n",
- " text: str\n",
- " count: int\n",
- " nested: NestedModel\n",
- "\n",
- "\n",
- "def process_node(state: ComplexState):\n",
- " # Node receives a validated Pydantic object\n",
- " print(f\"Input state type: {type(state)}\")\n",
- " print(f\"Nested type: {type(state.nested)}\")\n",
- "\n",
- " # Return a dictionary update\n",
- " return {\"text\": state.text + \" processed\", \"count\": state.count + 1}\n",
- "\n",
- "\n",
- "# Build the graph\n",
- "builder = StateGraph(ComplexState)\n",
- "builder.add_node(\"process\", process_node)\n",
- "builder.add_edge(START, \"process\")\n",
- "builder.add_edge(\"process\", END)\n",
- "graph = builder.compile()\n",
- "\n",
- "# Create a Pydantic instance for input\n",
- "input_state = ComplexState(text=\"hello\", count=0, nested=NestedModel(value=\"test\"))\n",
- "print(f\"Input object type: {type(input_state)}\")\n",
- "\n",
- "# Invoke graph with a Pydantic instance\n",
- "result = graph.invoke(input_state)\n",
- "print(f\"Output type: {type(result)}\")\n",
- "print(f\"Output content: {result}\")\n",
- "\n",
- "# Convert back to Pydantic model if needed\n",
- "output_model = ComplexState(**result)\n",
- "print(f\"Converted back to Pydantic: {type(output_model)}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f13f28ce",
- "metadata": {},
- "source": [
- "\n",
- "\n",
- "Runtime Type Coercion\n",
- "\n",
- "Pydantic performs runtime type coercion for certain data types. This can be helpful but also lead to unexpected behavior if you're not aware of it.\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "faf59316",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph import StateGraph, START, END\n",
- "from pydantic import BaseModel\n",
- "\n",
- "\n",
- "class CoercionExample(BaseModel):\n",
- " # Pydantic will coerce string numbers to integers\n",
- " number: int\n",
- " # Pydantic will parse string booleans to bool\n",
- " flag: bool\n",
- "\n",
- "\n",
- "def inspect_node(state: CoercionExample):\n",
- " print(f\"number: {state.number} (type: {type(state.number)})\")\n",
- " print(f\"flag: {state.flag} (type: {type(state.flag)})\")\n",
- " return {}\n",
- "\n",
- "\n",
- "builder = StateGraph(CoercionExample)\n",
- "builder.add_node(\"inspect\", inspect_node)\n",
- "builder.add_edge(START, \"inspect\")\n",
- "builder.add_edge(\"inspect\", END)\n",
- "graph = builder.compile()\n",
- "\n",
- "# Demonstrate coercion with string inputs that will be converted\n",
- "result = graph.invoke({\"number\": \"42\", \"flag\": \"true\"})\n",
- "\n",
- "# This would fail with a validation error\n",
- "try:\n",
- " graph.invoke({\"number\": \"not-a-number\", \"flag\": \"true\"})\n",
- "except Exception as e:\n",
- " print(f\"\\nExpected validation error: {e}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "2844475b",
- "metadata": {},
- "source": [
- "\n",
- "\n",
- "Working with Message Models\n",
- "\n",
- "When working with LangChain message types in your state schema, there are important considerations for serialization. You should use AnyMessage (rather than BaseMessage) for proper serialization/deserialization when using message objects over the wire.\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bd0734b0",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph import StateGraph, START, END\n",
- "from pydantic import BaseModel\n",
- "from langchain_core.messages import HumanMessage, AIMessage, AnyMessage\n",
- "from typing import List\n",
- "\n",
- "\n",
- "class ChatState(BaseModel):\n",
- " messages: List[AnyMessage]\n",
- " context: str\n",
- "\n",
- "\n",
- "def add_message(state: ChatState):\n",
- " return {\"messages\": state.messages + [AIMessage(content=\"Hello there!\")]}\n",
- "\n",
- "\n",
- "builder = StateGraph(ChatState)\n",
- "builder.add_node(\"add_message\", add_message)\n",
- "builder.add_edge(START, \"add_message\")\n",
- "builder.add_edge(\"add_message\", END)\n",
- "graph = builder.compile()\n",
- "\n",
- "# Create input with a message\n",
- "initial_state = ChatState(\n",
- " messages=[HumanMessage(content=\"Hi\")], context=\"Customer support chat\"\n",
- ")\n",
- "\n",
- "result = graph.invoke(initial_state)\n",
- "print(f\"Output: {result}\")\n",
- "\n",
- "# Convert back to Pydantic model to see message types\n",
- "output_model = ChatState(**result)\n",
- "for i, msg in enumerate(output_model.messages):\n",
- " print(f\"Message {i}: {type(msg).__name__} - {msg.content}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "c2e52e1f-c07a-4ebf-b28e-c370c8f50550",
- "metadata": {},
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6e6a0a39-9a4c-47ae-a238-1a3a847eea5b",
- "metadata": {},
- "source": [
- "## Add runtime configuration\n",
- "\n",
- "Sometimes you want to be able to configure your graph when calling it. For example, you might want to be able to specify what LLM or system prompt to use at runtime, *without polluting the graph state with these parameters*.\n",
- "\n",
- "To add runtime configuration:\n",
- "\n",
- "1. Specify a schema for your configuration\n",
- "2. Add the configuration to the function signature for nodes or conditional edges\n",
- "3. Pass the configuration into the graph.\n",
- "\n",
- "See below for a simple example:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "id": "97fc508b-1011-402e-8769-573ac3acb53a",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'my_state_value': 1}\n",
- "{'my_state_value': 2}\n"
- ]
- }
- ],
- "source": [
- "from langchain_core.runnables import RunnableConfig\n",
- "from langgraph.graph import END, StateGraph, START\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "\n",
- "# 1. Specify config schema\n",
- "class ConfigSchema(TypedDict):\n",
- " my_runtime_value: str\n",
- "\n",
- "\n",
- "# 2. Define a graph that accesses the config in a node\n",
- "class State(TypedDict):\n",
- " my_state_value: str\n",
- "\n",
- "\n",
- "# highlight-next-line\n",
- "def node(state: State, config: RunnableConfig):\n",
- " # highlight-next-line\n",
- " if config[\"configurable\"][\"my_runtime_value\"] == \"a\":\n",
- " return {\"my_state_value\": 1}\n",
- " # highlight-next-line\n",
- " elif config[\"configurable\"][\"my_runtime_value\"] == \"b\":\n",
- " return {\"my_state_value\": 2}\n",
- " else:\n",
- " raise ValueError(\"Unknown values.\")\n",
- "\n",
- "\n",
- "# highlight-next-line\n",
- "builder = StateGraph(State, config_schema=ConfigSchema)\n",
- "builder.add_node(node)\n",
- "builder.add_edge(START, \"node\")\n",
- "builder.add_edge(\"node\", END)\n",
- "\n",
- "graph = builder.compile()\n",
- "\n",
- "# 3. Pass in configuration at runtime:\n",
- "# highlight-next-line\n",
- "print(graph.invoke({}, {\"configurable\": {\"my_runtime_value\": \"a\"}}))\n",
- "# highlight-next-line\n",
- "print(graph.invoke({}, {\"configurable\": {\"my_runtime_value\": \"b\"}}))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f080f50b-cec1-4dba-81e0-63cf40c990ee",
- "metadata": {},
- "source": [
- "Extended example: specifying LLM at runtime\n",
- "\n",
- "Below we demonstrate a practical example in which we configure what LLM to use at runtime. We will use both OpenAI and Anthropic models.\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ff4c1453-8cff-4679-9574-8602c530144e",
- "metadata": {},
- "outputs": [],
- "source": [
- "%%capture --no-stderr\n",
- "%pip install -U langgraph \"langchain[anthropic,openai]\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "c031a059-7279-4e75-9164-58325d76242f",
- "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(\"ANTHROPIC_API_KEY\")\n",
- "_set_env(\"OPENAI_API_KEY\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "75ebea6f-e75f-42d4-9d32-68b37150bdde",
- "metadata": {},
- "source": [
- "Build the graph:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "a6033c2a-3b56-46f5-9c3f-79310e31e545",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "claude-3-5-haiku-20241022\n",
- "gpt-4.1-mini-2025-04-14\n"
- ]
- }
- ],
- "source": [
- "from langchain.chat_models import init_chat_model\n",
- "from langchain_core.runnables import RunnableConfig\n",
- "from langgraph.graph import MessagesState\n",
- "from langgraph.graph import END, StateGraph, START\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "\n",
- "class ConfigSchema(TypedDict):\n",
- " model: str\n",
- "\n",
- "\n",
- "MODELS = {\n",
- " \"anthropic\": init_chat_model(\"anthropic:claude-3-5-haiku-latest\"),\n",
- " \"openai\": init_chat_model(\"openai:gpt-4.1-mini\"),\n",
- "}\n",
- "\n",
- "\n",
- "def call_model(state: MessagesState, config: RunnableConfig):\n",
- " model = config[\"configurable\"].get(\"model\", \"anthropic\")\n",
- " model = MODELS[model]\n",
- " response = model.invoke(state[\"messages\"])\n",
- " return {\"messages\": [response]}\n",
- "\n",
- "\n",
- "builder = StateGraph(MessagesState, config_schema=ConfigSchema)\n",
- "builder.add_node(\"model\", call_model)\n",
- "builder.add_edge(START, \"model\")\n",
- "builder.add_edge(\"model\", END)\n",
- "\n",
- "graph = builder.compile()\n",
- "\n",
- "# Usage\n",
- "input_message = {\"role\": \"user\", \"content\": \"hi\"}\n",
- "# With no configuration, uses default (Anthropic)\n",
- "response_1 = graph.invoke({\"messages\": [input_message]})[\"messages\"][-1]\n",
- "# Or, can set OpenAI\n",
- "config = {\"configurable\": {\"model\": \"openai\"}}\n",
- "response_2 = graph.invoke({\"messages\": [input_message]}, config=config)[\"messages\"][-1]\n",
- "\n",
- "print(response_1.response_metadata[\"model_name\"])\n",
- "print(response_2.response_metadata[\"model_name\"])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bd1ac2bc-9e3e-42c4-a68f-238c841e58d1",
- "metadata": {},
- "source": [
- "\n",
- "\n",
- "Extended example: specifying model and system message at runtime\n",
- "\n",
- "Below we demonstrate a practical example in which we configure two parameters: the LLM and system message to use at runtime.\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "367bcedd-047c-4150-a059-0a7630ab2663",
- "metadata": {},
- "outputs": [],
- "source": [
- "%%capture --no-stderr\n",
- "%pip install -U langgraph \"langchain[anthropic,openai]\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "e5d0dd7d-9564-4a5f-aa2e-2f7be20e1647",
- "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(\"ANTHROPIC_API_KEY\")\n",
- "_set_env(\"OPENAI_API_KEY\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "04924627-9326-438b-aa52-91cea76f4477",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "================================\u001b[1m Human Message \u001b[0m=================================\n",
- "\n",
- "hi\n",
- "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
- "\n",
- "Ciao! Come posso aiutarti oggi?\n"
- ]
- }
- ],
- "source": [
- "from typing import Optional\n",
- "\n",
- "from langchain.chat_models import init_chat_model\n",
- "from langchain_core.messages import SystemMessage\n",
- "from langchain_core.runnables import RunnableConfig\n",
- "from langgraph.graph import END, MessagesState, StateGraph, START\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "\n",
- "class ConfigSchema(TypedDict):\n",
- " model: Optional[str]\n",
- " system_message: Optional[str]\n",
- "\n",
- "\n",
- "MODELS = {\n",
- " \"anthropic\": init_chat_model(\"anthropic:claude-3-5-haiku-latest\"),\n",
- " \"openai\": init_chat_model(\"openai:gpt-4.1-mini\"),\n",
- "}\n",
- "\n",
- "\n",
- "def call_model(state: MessagesState, config: RunnableConfig):\n",
- " model = config[\"configurable\"].get(\"model\", \"anthropic\")\n",
- " model = MODELS[model]\n",
- " messages = state[\"messages\"]\n",
- " if system_message := config[\"configurable\"].get(\"system_message\"):\n",
- " messages = [SystemMessage(system_message)] + messages\n",
- " response = model.invoke(messages)\n",
- " return {\"messages\": [response]}\n",
- "\n",
- "\n",
- "builder = StateGraph(MessagesState, config_schema=ConfigSchema)\n",
- "builder.add_node(\"model\", call_model)\n",
- "builder.add_edge(START, \"model\")\n",
- "builder.add_edge(\"model\", END)\n",
- "\n",
- "graph = builder.compile()\n",
- "\n",
- "# Usage\n",
- "input_message = {\"role\": \"user\", \"content\": \"hi\"}\n",
- "config = {\"configurable\": {\"model\": \"openai\", \"system_message\": \"Respond in Italian.\"}}\n",
- "response = graph.invoke({\"messages\": [input_message]}, config)\n",
- "for message in response[\"messages\"]:\n",
- " message.pretty_print()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "03eac38a-fca6-4baf-9ccf-94bf16321235",
- "metadata": {},
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "94715e3d-e98b-4be0-ae5f-1169cb795ce5",
- "metadata": {},
- "source": [
- "## Add retry policies\n",
- "\n",
- "There are many use cases where you may wish for your node to have a custom retry policy, for example if you are calling an API, querying a database, or calling an LLM, etc. LangGraph lets you add retry policies to nodes.\n",
- "\n",
- "To configure a retry policy, pass the `retry_policy` parameter to the [add_node](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph.add_node). The `retry_policy` parameter takes in a `RetryPolicy` named tuple object. Below we instantiate a `RetryPolicy` object with the default parameters and associate it with a node:\n",
- "\n",
- "```python\n",
- "from langgraph.pregel import RetryPolicy\n",
- "\n",
- "builder.add_node(\n",
- " \"node_name\",\n",
- " node_function,\n",
- " retry_policy=RetryPolicy(),\n",
- ")\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "af144b8f-761a-4456-a356-ce0812e92577",
- "metadata": {},
- "source": [
- "By default, the `retry_on` parameter uses the `default_retry_on` function, which retries on any exception except for the following:\n",
- "\n",
- "* `ValueError`\n",
- "* `TypeError`\n",
- "* `ArithmeticError`\n",
- "* `ImportError`\n",
- "* `LookupError`\n",
- "* `NameError`\n",
- "* `SyntaxError`\n",
- "* `RuntimeError`\n",
- "* `ReferenceError`\n",
- "* `StopIteration`\n",
- "* `StopAsyncIteration`\n",
- "* `OSError`\n",
- "\n",
- "In addition, for exceptions from popular http request libraries such as `requests` and `httpx` it only retries on 5xx status codes.\n",
- "\n",
- "Extended example: customizing retry policies\n",
- "\n",
- "Consider an example in which we are reading from a SQL database. Below we pass two different retry policies to nodes:\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ad92598c-b688-42fa-aae0-9de36273d584",
- "metadata": {},
- "outputs": [],
- "source": [
- "import sqlite3\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langchain.chat_models import init_chat_model\n",
- "\n",
- "from langgraph.graph import END, MessagesState, StateGraph, START\n",
- "from langgraph.pregel import RetryPolicy\n",
- "from langchain_community.utilities import SQLDatabase\n",
- "from langchain_core.messages import AIMessage\n",
- "\n",
- "db = SQLDatabase.from_uri(\"sqlite:///:memory:\")\n",
- "\n",
- "model = init_chat_model(\"anthropic:claude-3-5-haiku-latest\")\n",
- "\n",
- "\n",
- "def query_database(state: MessagesState):\n",
- " query_result = db.run(\"SELECT * FROM Artist LIMIT 10;\")\n",
- " return {\"messages\": [AIMessage(content=query_result)]}\n",
- "\n",
- "\n",
- "def call_model(state: MessagesState):\n",
- " response = model.invoke(state[\"messages\"])\n",
- " return {\"messages\": [response]}\n",
- "\n",
- "\n",
- "# Define a new graph\n",
- "builder = StateGraph(MessagesState)\n",
- "builder.add_node(\n",
- " \"query_database\",\n",
- " query_database,\n",
- " retry_policy=RetryPolicy(retry_on=sqlite3.OperationalError),\n",
- ")\n",
- "builder.add_node(\"model\", call_model, retry_policy=RetryPolicy(max_attempts=5))\n",
- "builder.add_edge(START, \"model\")\n",
- "builder.add_edge(\"model\", \"query_database\")\n",
- "builder.add_edge(\"query_database\", END)\n",
- "\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "068f806a",
- "metadata": {},
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6d99d63c",
- "metadata": {},
- "source": [
- "## Add node caching\n",
- "\n",
- "Node caching is useful in cases where you want to avoid repeating operations, like when doing something expensive (either in terms of time or cost). LangGraph lets you add individualized caching policies to nodes in a graph.\n",
- "\n",
- "To configure a cache policy, pass the `cache_policy` parameter to the [add_node](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph.add_node) function. In the following example, a [`CachePolicy`](https://langchain-ai.github.io/langgraph/reference/types/?h=cachepolicy#langgraph.types.CachePolicy) object is instantiated with a time to live of 120 seconds and the default `key_func` generator. Then it is associated with a node:\n",
- "\n",
- "```python\n",
- "from langgraph.types import CachePolicy\n",
- "\n",
- "builder.add_node(\n",
- " \"node_name\",\n",
- " node_function,\n",
- " cache_policy=CachePolicy(ttl=120),\n",
- ")\n",
- "```\n",
- "\n",
- "Then, to enable node-level caching for a graph, set the `cache` argument when compiling the graph. The example below uses `InMemoryCache` to set up a graph with in-memory cache, but `SqliteCache` is also available.\n",
- "\n",
- "```python\n",
- "from langgraph.cache.memory import InMemoryCache\n",
- "\n",
- "\n",
- "graph = builder.compile(cache=InMemoryCache())\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e1a0213e-282f-4fad-b048-5f7465edfccb",
- "metadata": {},
- "source": [
- "## Create a sequence of steps\n",
- "\n",
- "!!! info \"Prerequisites\"\n",
- " This guide assumes familiarity with the above section on [state](#define-and-update-state).\n",
- "\n",
- "Here we demonstrate how to construct a simple sequence of steps. We will show:\n",
- "\n",
- "1. How to build a sequential graph\n",
- "2. Built-in short-hand for constructing similar graphs.\n",
- "\n",
- "\n",
- "To add a sequence of nodes, we use the `.add_node` and `.add_edge` methods of our [graph](../../concepts/low_level/#stategraph):\n",
- "```python\n",
- "from langgraph.graph import START, StateGraph\n",
- "\n",
- "builder = StateGraph(State)\n",
- "\n",
- "# Add nodes\n",
- "builder.add_node(step_1)\n",
- "builder.add_node(step_2)\n",
- "builder.add_node(step_3)\n",
- "\n",
- "# Add edges\n",
- "builder.add_edge(START, \"step_1\")\n",
- "builder.add_edge(\"step_1\", \"step_2\")\n",
- "builder.add_edge(\"step_2\", \"step_3\")\n",
- "```\n",
- "\n",
- "We can also use the built-in shorthand `.add_sequence`:\n",
- "```python\n",
- "builder = StateGraph(State).add_sequence([step_1, step_2, step_3])\n",
- "builder.add_edge(START, \"step_1\")\n",
- "```\n",
- "\n",
- "\n",
- "\n",
- "Why split application steps into a sequence with LangGraph?\n",
- "\n",
- "LangGraph makes it easy to add an underlying persistence layer to your application.\n",
- "This allows state to be checkpointed in between the execution of nodes, so your LangGraph nodes govern:\n",
- "\n",
- "
\n",
- "
How state updates are [checkpointed](../../concepts/persistence/)
\n",
- "
How interruptions are resumed in [human-in-the-loop](../../concepts/human_in_the_loop/) workflows
\n",
- "
How we can \"rewind\" and branch-off executions using LangGraph's [time travel](../../concepts/time-travel/) features
\n",
- "
\n",
- "\n",
- "They also determine how execution steps are [streamed](../../concepts/streaming/), and how your application is visualized\n",
- "and debugged using [LangGraph Studio](../../concepts/langgraph_studio/).\n",
- "\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "518cb5d1-c60f-44d7-b348-e03b6e487098",
- "metadata": {},
- "source": [
- "Let's demonstrate an end-to-end example. We will create a sequence of three steps:\n",
- "\n",
- "1. Populate a value in a key of the state\n",
- "2. Update the same value\n",
- "3. Populate a different value\n",
- "\n",
- "Let's first define our [state](../../concepts/low_level/#state). This governs the [schema of the graph](../../concepts/low_level/#schema), and can also specify how to apply updates. See [this section](#process-state-updates-with-reducers) for more detail.\n",
- "\n",
- "In our case, we will just keep track of two values:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "aa1b04c6-2653-4ad4-a720-facc1f2906a7",
- "metadata": {},
- "outputs": [],
- "source": [
- "from typing_extensions import TypedDict\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " value_1: str\n",
- " value_2: int"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6d4a8554-bc19-4bbe-a8c2-20adcfca8273",
- "metadata": {},
- "source": [
- "Our [nodes](../../concepts/low_level/#nodes) are just Python functions that read our graph's state and make updates to it. The first argument to this function will always be the state:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "c7db921a-dbfb-4039-a93b-8b2264143a3f",
- "metadata": {},
- "outputs": [],
- "source": [
- "def step_1(state: State):\n",
- " return {\"value_1\": \"a\"}\n",
- "\n",
- "\n",
- "def step_2(state: State):\n",
- " current_value_1 = state[\"value_1\"]\n",
- " return {\"value_1\": f\"{current_value_1} b\"}\n",
- "\n",
- "\n",
- "def step_3(state: State):\n",
- " return {\"value_2\": 10}"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "2b454eb0-19c1-418e-a912-dc44c0c045e2",
- "metadata": {},
- "source": [
- "!!! note\n",
- "\n",
- " Note that when issuing updates to the state, each node can just specify the value of the key it wishes to update.\n",
- "\n",
- "By default, this will **overwrite** the value of the corresponding key. You can also use [reducers](../../concepts/low_level/#reducers) to control how updates are processed— for example, you can append successive updates to a key instead. See [this section](#process-state-updates-with-reducers) for more detail.\n",
- "\n",
- "Finally, we define the graph. We use [StateGraph](../../concepts/low_level/#stategraph) to define a graph that operates on this state.\n",
- "\n",
- "We will then use [add_node](../../concepts/low_level/#messagesstate) and [add_edge](../../concepts/low_level/#edges) to populate our graph and define its control flow."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "b02bdbcf-2bbb-4f08-b177-1a45b2a8bc6d",
- "metadata": {},
- "outputs": [],
- "source": [
- "from langgraph.graph import START, StateGraph\n",
- "\n",
- "builder = StateGraph(State)\n",
- "\n",
- "# Add nodes\n",
- "builder.add_node(step_1)\n",
- "builder.add_node(step_2)\n",
- "builder.add_node(step_3)\n",
- "\n",
- "# Add edges\n",
- "builder.add_edge(START, \"step_1\")\n",
- "builder.add_edge(\"step_1\", \"step_2\")\n",
- "builder.add_edge(\"step_2\", \"step_3\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "79a696b2-ef9b-4f8d-ae83-ea674a16bab0",
- "metadata": {},
- "source": [
- "!!! tip \"Specifying custom names\"\n",
- "\n",
- " You can specify custom names for nodes using `.add_node`:\n",
- "\n",
- " ```python\n",
- " builder.add_node(\"my_node\", step_1)\n",
- " ```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "7452c5ea-cf1b-47a5-8da0-32479c142dce",
- "metadata": {},
- "source": [
- "Note that:\n",
- "\n",
- "- `.add_edge` takes the names of nodes, which for functions defaults to `node.__name__`.\n",
- "- We must specify the entry point of the graph. For this we add an edge with the [START node](../../concepts/low_level/#start-node).\n",
- "- The graph halts when there are no more nodes to execute.\n",
- "\n",
- "We next [compile](../../concepts/low_level/#compiling-your-graph) our graph. This provides a few basic checks on the structure of the graph (e.g., identifying orphaned nodes). If we were adding persistence to our application via a [checkpointer](../../concepts/persistence/), it would also be passed in here."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "7aa2828c-0903-4775-b4ea-d62647f3bf0a",
- "metadata": {},
- "outputs": [],
- "source": [
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "4c85772e-788c-49df-9327-11cb92f02c6a",
- "metadata": {},
- "source": [
- "LangGraph provides built-in utilities for visualizing your graph. Let's inspect our sequence. See [this guide](../../how-tos/visualization) for detail on visualization."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "4162bc81-cbfd-49e3-b79f-8a97b9f417c2",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGsAAAFNCAIAAACIXwbEAAAAAXNSR0IArs4c6QAAG5NJREFUeJztnXlcE2fewJ/cdwIkEO5L5VZUPKiiUsWqVFG88MCq27p16/bSd3uyvde61lbbravdqtuttR61WhfXqrUeFdFWqlZAKXJ4QMIRQsh9zeT9I36oH801MxnykM73L53M8cuXJzPPPNeP5nA4AAUB6IEOoN9DGSQKZZAolEGiUAaJQhkkCpPg8Tq1rafLZtQhRi1itzlQtB/UjRhMwGTS+WIGX8QMjWTxhYQk0PDVB7uUlsarhuZqA5tPAw4aX8Tgixk8ARNF+oFBJoum19qNWsSos1tMKItNTx4sGJgtFEtZOM6G2aBeY68sVzkACJGxkgYLImK5OK4KFcpmU1O1obvdKgxljpkuY3Ox3dmwGbx4XF1T2TNmhiw1R4Q9VNipruipPKzKfVSaPS7E96MwGDy0pXXgMGFmrgRvhP2Dn0+ou9qsj5RG+ri/ryV2+1+bh00MDXp9AICcgrCENMGhLa2+HuDwgW1lTSqF2Zc9g4YbV3R7Ntz2ZU/vv+JDW1qHTQyNT+X74e/br7j+o7a1yVSwUO55Ny8Gq75T84SMzIeC/8frkqoTap7Ay9f3dB/Ua+zV53p+t/oAACMKwk7t6/S8jyeDleWqMTNk/o6qn/HQdGllucrDDm4NdiktDgCCst6HiZxJoSqFxWywu9vBrcHGq4YQGZ63HHzU1NRYLJZAHe4ZgZjZVGN096lbg83VhqTBApJiuo/y8vJly5aZTKaAHO6V5MHCpmq9u09dG9SqbRw+vc/eeXEXH2dFgrzS5yQpS6DvtrtrdnJjsMtGUhferVu3Vq5cmZeXV1hYuHbtWhRFy8vL161bBwAoKCgYMWJEeXk5AKC9vf31118vKCjIzc0tKSk5evSo83CNRjNixIidO3eWlZXl5eWtWLHC5eF+x25z9KhsLj9y3TRm1CF8EYOMUN5+++2bN2+uWbPGYDBUVVXR6fSxY8eWlpZ+8cUXmzZtEgqF8fHxAAC73V5bWzt37tyQkJCTJ0+WlZXFxcVlZmY6T7J9+/Z58+Zt3bqVwWDI5fIHD/c7fDHDqEVCI1x85MagFuGLSTGoUCjS0tKKi4sBAKWlpQCAsLCw2NhYAEBWVlZIyN1GkZiYmK+++opGowEAZs6cWVBQcPr06V6DgwcPXrVqVe85Hzzc7wjETIPW9ePY7ZOExSalA6CwsPDChQvr169Xq9We96yvr1+9evXUqVOLi4sRBOnq6ur9aNSoUWTE5gE2l+7u5c21Jq6Arut2WwMiwqpVq1avXn38+PGioqJ9+/a52+3ixYtLly61Wq2vv/76+vXrJRIJiqK9n/J4PDJi80CPysYXuf69ut7KFzGNOlIM0mi0RYsWzZw5c+3atevXr09JSRk6dKjzo3v/yNu2bYuNjd20aROTyfRRGanDVzw8GFyXQWEog8Mj5VfsrHkIBIKVK1cCAOrq6noFdXb+9gaq0WhSUlKc+qxWq9FovLcM3seDh/sdgYQhCnX9fuG6DIbJOZ0tVk2nNSSc7d9QXnzxRaFQmJubW1FRAQBIT08HAGRnZzMYjA0bNhQVFVksljlz5jjrJYcOHZJIJLt27dJqtY2Nje5K2YOH+zfm1gYTagfu+k8Yb7zxhssPdN12Q489KsnPd5yWlpaKioqjR4+aTKann346Pz8fACAWi+Vy+XfffXf27FmtVjt9+vTs7OympqY9e/ZUVVVNnjy5pKTk2LFjaWlpUqn0888/z8vLy8jI6D3ng4f7N+ZfzmjkidzIRNfvF27bBxVNpus/aid5a1/8PfC/7cq8mTKJm1YCt53N0cm8n46q79Qb41Jct05rtdqioiKXH8XGxra0tDy4fcKECW+++abPkePkiSeeaGhoeHB7enr69evXH9yelZX18ccfuzvb9Z+0HB7dnT4vbdQdd8yn9nWWrIlz+SmKom1tba5PSnN9Wh6PFxoa6u5y/qKzs9Nmc/EG5i4qNpstk7ltBt3+1+aFL8S5q8p4b+X/4WBnfAo/MbOPGmlgo/ZCj1GLjHwkzMM+Xqos44vDzxzo1Ha5fqkObhSNprqLOs/6gC+9nRYzsvWFBn/0IPYnTAbbJy81+rKnT/3FVgvyycsN+h4b4cD6Bx0t5u2vNdntqC87+zrqw6RHdq+/PeUxeczAIO84bvhFV3W8e8FffG0lwzby6NTeDm23bewMmSyGgzdCeGltNJ0v75IncMYVh/t+FObRb7frjOfKVfFpfHkcNylLwGDSsIcKF1Yz2lSjb7tpViutD82QRiView3DOQKz8aq+/pKuucaQmiNicegCMVMgYXD5jP4whBUw6DSjzm7Q2g1aRN9ja6k3JWcJU0YIE9LwVNpwGuzldp2xu8Nq0NoNPQiKOuxWfypEEKS6urq3+ctfcPh0Z7OzQMyQRrEJ3tmJGiQVvV4/ffr006dPBzoQT1Bj+YlCGSQK7AadTbAwA7tBl+1RUAG7QfK6gP0F7AY1Gk2gQ/AC7Aajo6MDHYIXYDeoUCgCHYIXYDc4ePDgQIfgBdgNVldXBzoEL8BuEH5gN+ihFw0SYDeoUnmaiQADsBsMD8fQXBwQYDdI6ogsvwC7QfiB3eDAgQMDHYIXYDfocgwRVMBuEH5gN3jvSEs4gd3gtWvXAh2CF2A3CD+wG6TaZohCtc0EP7AbpHo7iUL1dgY/sBuk+ouJQvUXE2XQoEGBDsELsBu8ceNGoEPwAuwG4Qd2g5GRvq5FGShgN+hu8iM8wG4wKysr0CF4AXaDNTU1gQ7BC7AbpMogUagySJS4ONcz7OEBxhk5K1asUCgUTCYTRVGVSiWTyeh0us1mO3LkSKBDcwGMZXDx4sVarba1tVWpVNpsNqVS2draymCQspIacWA0mJ+ff9/rsMPhgLbDBEaDAIAlS5bw+b9NGIyKilqwYEFAI3ILpAYffvjhpKSk3nt0dnb2kCFDAh2UayA1CABYvny5s3lVJpNBWwChNpifn5+cnOzsMob2Jog/T5PFhKhaLRYzuTWhWY88aeneW5i/vKnGQOqFeAK6NJrN5uB53OOpDx79XHn7uil6AL9fZGXyBcSOtt82DxommrTA1WK1HsFm0GZB93/Ukp0fFpcixHol+Km/1HOnTj9zZbRzBV0fwWZwz4Y7uY+GS6P7fXYrdzTX6m5f009/Isr3QzA8SeovaSMTeUGsDwCQlClismh36t2uwv8gGAx23LFyBJC+WvkRFpfRpbD6vj8GgxYTIpb6eVlWCAmVc4xuFu92CQaDVrMjaB6+HkBsDpsNw9eEt0bdX6AMEoUySBTKIFEog0ShDBKFMkgUyiBRKINEoQwShTJIlAAYbGtTKttIXwvKbre/+tfVdb+SPjW0rw22KloWlRb9SvIX0+l1r5Y9X1n5A6lXcYKzpwk3iN1O9kidS5cvvvfeW52qDlKv0guJBs1m86aP1jkLwpAhw/781P85gGPp8rkAgDffeulNAKZMmf7SC28499y2ffP3J49arZa42IT585dMfPgRAMD+r7/c/M8PZs9ecObMCb1el5E++Mknn01N8TLT7uDBvaNHj01KGrjpw3XkfbteSDT45e5/Hzt2ePmylVKp7Njxwzwej8fjv/rKO39bW7Z82cphQ0eEhoY5M8W8WvZ8W5ti8aLlISFhV65Uvf3OK2azqXDaTOd5bFbr229u6FR1fPafT1aveXLbp3uiIj0tSvjcsy9JpbLvvuujgV4kGlS2KXg83qKFy5hM5qOFs5wbUwalAQDi4xMHD767TvcPZ09erb68e1e5TBYOACiYNNVkMn59YHevwZVPPsfn89MBSE3JKH1s1sGDe5/60/MeriuV9ulSXSQaLJg07fvvj7740tOrnlqTnOx22ZgLFyrsdvui0t9SPiEIIhC46E2VyyPj4xOv18E1qpVEg6NHjXl37YdbP9n0+IoFjxbOeu7Zl5wZ/O6ju7tLKpV9sGHrvRsZrvYEAIhEYp1OS1rIeCD3WTx61JiRI3K/PrD7n1s2yuVRS0off3AfkUis0XTL5VEcjveMHarOjrj4RHKCxQmJ9UGr1QoAoNPp8+YulsnCb9yoAwBwOFwAQJfqt/XIhg8fhSDIf8v3925xl0/8ypWfWxUtmRlwDYMjsQweOLjnXOWZyQWFXV2dKlVnamoGACAiQh4dFbNv/xdcHk+r7ZldvGByQWH54QNbP/lQ2aZIGZTW0FBfce7UZzv2c7l3u/Y3blqbkzNaoWj5+sDusDBp8awS8mLGAYkGo6NjbVbrlq0bBQLh7NkLSuYvcSaNKytbu/69Nz/evCEiIvLh/EciI6Pe+/vmT7f94+TJY4cPH4iNjS+aMffeO6bdbt/6yYdWqyU7O+dPTz4nEMCV+g3DuJlvP2uLTRUmZvTdmCNnjfp/5T/cOyKYbOp+6jFqrRPm+LpyZF+/1fmFZ557ornZxZpwY8ZMePlF0rNa3ke/NPha2bs2u4skhDxuX+fWht3g3DmL5s5Z9OB259sLJFAtrEShDBKFMkgUyiBRKINEoQwShTJIFMogUSiDRKEMEgWDQWEIk07v99mKvUJn0PhCDNNmMBgUiBkdt123HgcT7TeNYhnL9/0xGIxL5em7XbSIBBlGnT0uBUMbDwaD4THcmEHcioPtuALrH3z/pWLIOAlfhKHJCvP84ppzPTeuGBIyhbJoLpsbJA8isxHpUphrz2vGzZIlZWLrRcAzQ1vRZLp2QavvQTQdGGbw4cHhsFitvvSCEkQUygqLZA3NDwmNwDxxEMY1j3qhspD/LqAMEgV2gzCvk+IEdoNUdg2iUNnWiEJlWyMKlZ+EKFR+EqJQ90GiUPfB4Ad2g6mpqYEOwQuwG/z1118DHYIXYDcIP7Ab7B2PDi2wGzSbzYEOwQuwG5RIJIEOwQuwG+zp6Ql0CF6A3SD8wG4wNjY20CF4AXaDLS0tgQ7BC7AbhB/YDVJZJ4lCZZ0MfmA3SPV2EoXq7Qx+YDdI9ZMQheonIUpoaGigQ/AC7Aa7u7sDHYIXYDcIP7AbpEZ9EIUa9UGUjIyMQIfgBdgNXrtG+lK0BIHdIFUGiUKVQaJkZmYGOgQvwDgjZ9WqVWq1msViIQjS2NiYnJzMZDIRBNm1a1egQ3MBjKtGTZgw4f3330cQxPnf+vp6ZxrtQMflGhh/xfPnz4+Li7tv46hRowIUjhdgNAgAKC0tvXdColgsXrhwYUAjcgukBmfNmhUTE9P730GDBo0fPz6gEbkFUoMAgIULFzqLoUQiKS0tDXQ4boHXYHFxsbMYDhgwYNy4cYEOxy34n8VmA2qzon4N5n5K5izbvn17yZxlum4MqUhxwOHT2RychQlPffDid+raSi2Hz7AYEXxXhQ2HAzBZIHtCyJC8EKzHYjZ45N/KkAhOUpZIGIJhSRH40alttZXdPCE9bya2xAjYDB7ZoZTF8dJHYf5D9RcunVABmmPCbAzrvGL48TfX6nlCZhDrAwAML5CZ9Gj7LQyDtzEYbL9lYXGDPws5g0HrbLH4vj+WHNomNCyK9IVLAk54HNdAUhZygw5B7JC+3vsRm8VhNmKopcFbo+4vUAaJQhkkCmWQKJRBolAGiUIZJAplkCiUQaJQBolCGSRKAHrc29qUDuDwnEEXNwaDYcvWjRXnTtts1vj4pCWLHx8zhtxOvmDLQv6vTz868f23Ux6Z/odlfwIOR9lra6qrr5B0LSfBloX8sSUrCiZNcyZHHj9+0vwFhRXnTvfmSiaDYMtCLpXKejNA83h8AIDNRu6Sz0GYhbyXny5WAgByho8m7zsGZxZyJyiK7t79WVxcQm5uHnnfMZizkH9z6KuGxvq172xkMMjt2wnOLOQdHe3bd2weO3bCQw+RPlwkOLOQf/TxehRFn171F7yBYyAIs5CfPnPi3Lkzjy1ZIZdH+u/buCXYspDr9fqPN29gMplms+nznducGwsKpkVHxXg4igjBloX8s/980tWlAgD06gMApKdnkWeQykJ+P1QWcioLuQ9QWch9hcpC/ruAMkgUyiBRKINEoQwShTJIFMogUSiDRKEMEoUySBRsObQZzOA3zmLRuXwMXxPDrlwBQ9X6O8hCfsckDMXQXIDBYGQCx2YOksmcHkARVB6PISkKBoPxaQIH6rhyWo0rsP7BhcMdoREsWTSGqVuYZ8ee3t+BOkDyYLE0CvbsNb6Doo4upeXa+e6oJG7ORGyrbuKZoV1zrqfmvNZqRs0Gcn/UDgBQFGHQSZ8OyWDSJDJW9njJoGEirMfiX/PI4QBWM7mrBBgMhpKSksOHD5N6FQAAh0sHNJzH4m+jptEAh0du5caG0GyIkeyrEATq4PoFsBukVvQmCrWiN1Go3BBEoXJDECUrKyvQIXgBdoM1NT6NWA0gsBuksk4Shco6GfzAbpCqzRCFqs0EP7AbTEz0PvchsMBu8ObNm4EOwQuwG4Qf2A2GhMC+YCTsBjUaTaBD8ALsBul06CMMdABeQFFyO7OIA7tB+IHdIJV1kihU1sngB3aDVG8nUajezuAHdoNUCytRqBbW4Ad2gyIR5iGRfQzsBnU6XaBD8ALsBqknCVGoJwlRYmNjAx2CF2A32NLSEugQvAC7wXuzd8IJ7AZbW1sDHYIXYDdIjcAkCvwjMGHM475jx46tW7eiKIqiKJ1OdzgcNBoNRdFLly4FOjQXwFgG58+fHx8f39vVSaPRHA4HtE2tMBoUCoWFhYX3ruHL5XKhTQINo0EAwNy5cxMSEnr/GxsbW1RU5PGIgAGpQbFYPHXqVOevWCAQLF68ONARuQVSgwCAefPmOQcPwlwAoTYoEommTZvG4/EWLFgQ6Fg8QWJtRnnT1FRt7LhjMekQkwFhsmgmrHPiHcButzFZmJN1C0OYVhPKEzJ4QmZkImfAEEF4DFlZb/1v0GpGfzzaff3HHhafJQoXsHlMJpvB5DCZbHrfVT0dALEhditisyAWg1XfaUQRJCNXMubRML9fys8GzxzounZBE5kqE8l4TDZE6aJtZru206i83jVyinT0VH+OxfGbwbZbthO72zkiXngy1KNO2+rVqNU6449RIol/ngH+Mdh4VX9ynyp5dDSDCVG5c4fVaGs43zr3uZiIWD8s+OIHg8qb5uO7VAnDo4hH05fcuqQoekIeKmcTPA/RkqxoNh3b2dnv9AEAEoZH7/+oVa/BkLLdJYQM2qzoN5sViSNIyTzXBySPjtm17jbBkxD6FR/4p4IbKuGH9OPlo3raDVymaUqpHPcZ8JfB5lq9Qevo1/oAABK5QNFoUbVacJ8Bv8GzB7vCB/i/gtr3yJJDT3+twn04zlWjbtUZmDwWV4jnQabuVgLgCAsl5e7pcDhOVez8seqQVqeShydOHL9sSObDng8RyfjddzRdSos0Cs+bH84y2PiLgSPEk8pCpW55d2Pxndbr+K7rCw1NVVnpE6YVrKTTGZ/veamu/rzXQ9hCbnOtAd/lcBpsrjWKwvHkrUERcvN20mi0FY99OGPqM+PHLHx8yUYAwKWrR70eJQ7nN1zBaRDPr7i7wyoIYbF5Xo61Ws0HDq+/VncWAJCUMHRm4WoAHOs/KgEA7Nz7ys69YMSwRxfMfs2557cntly+esxms4TLEvLzFg8dPBkA8EPl7v9+uykvt+Rq7fcmsy4hNuvRKU/HxXjK2+mU6PwHjytiMtkMuvfvyA/hau7QrFaUzcZcpPAYNOkQq9l7OTr5w3+qLv9vyqQ/ioWyqitH2Gweh8NfNO+tL796bcrEPw5MzhEK7ubt3LFrTXe3cuL4pUJhWGPTz1/sK7NYTaNz7raq2u3WpQv/3qPtPH7y0607nlrz512+3EM1Pe2VP32NokjuyGJfvpRRZzfrELa0TwwatHZf2l3UGgWbzZs4bimDwRw94m4SztioVABARHhiUsLdvJ3V104137zyyppvJOJwAMDwIVMsVmPF+b29BmdMfYbD4QMA4mLS122aU3Hhq6Jpz3q9+rsb5yCIrXj6XxLifOqzZ3MZBq1dLMXcFonHoNWEsgXen8LDh0y9fPXYp58/O7Pw+Si5277K67+eQ1D72g9+KykoivC4LjKShYZERsgSb7fU+hLk0gXrfv7lyKEjH0jEEVnp3tNo8yQcox7Poqh4DDJYNKvRRaKp+0hLeejx0o3lxz56/+PFo3Nmzp7xAoPh4nI6fZdYJFu5fPO9G+lubl48nthk8p63EwCQkZaXnjr2H/964uDh93wxaNJaOa7+bF7BY5AvZiJWn17I01IeShk4+uz5PeVHPwwNiSzI/4OLs/HEekN3aEgUi+W9Otaj7YgIT/C6mxMajRYfm1FxocZk0vF4XsZj2y0IX4zHBp7ajEDMsNu8T/u12e/m7ZwwdpFYFN6i/BUAwGJxAQBa3W95OwcOGImiSOVPX/dusVhdr7ze0Pxzl7olIc7LuGCTWd/775bWOiaTzWZ7r7pazXaBGE/jJh7r0iiOqceKog463dMCuhXn99bWnc3JntqjU2l1nXHR6QCAEIlcGhpz5tyXbBbPYOoZl1uSkz3tx6pvDh/7R7dGGROVqmi7UX3t9AvP7GWz775x7//vupQBo7rUrWfP7xEJpXmj53u4aJe6ddOWpcOzp4aGRDXe/PnmnatjR89zefe4F4vRxuExODw8BhlvvPEGjsPa71jMJprntzqdXt3YfOny1aPtnc0jh8+YMnEFnU6n0WgJcVl1Ny5crj7erVFmpU8QCCRDsiaZTLpfak5cvXbKbDaMypmRlDCUTqffulPza8MFeXjihapvmm9fGZA0fNG8t0IkER4uSqcxjCZt9bWTdTcqAaBNGr90cv7jXpca0Cj0MYnMxAxPGUHdgbN1q65Ke+mMITrD05chjrNG/beyU87aDHncvqycOC8sdhCeq+BsWUgdLqo8rHaOS8N3BiJs3vakst3FnM/MtPEL57yO9WxWs53JdODTh98gjU4bkidpuq6OGCjFdwYilM5/B0FcVKd8eWI8SGejemQB/nUiCbVR/+vlpuTcWKj6hbFi0lq6mlSlL8fjPgOhfpLJSyJUTfjbJmGg66Z66lL8TfxEDSZlCJMzuZ2N/TVjifJ6x4iJYkzZSB6EaG/nqEfCYhIZbTe6CJ6n71Fe70wfwU8bKSZ4Hj+MfBgzPSw8ArTf6E8/Z0Vt+6AhnKHj/bDQsN/GzVw+rWmoNovkEq6I6CgAUjF0mzWt3SMnSVKG+2fmsj/HbimaTN/v6WSwWeEDwlhc6LJzm/XWzkY1i+WYvDhcGum34YT+Hz9Y/7Pu6jmdXmMXSAXiCD5bwApIrduJA3WYdBZdh9GgNkqkrJxJEnyvbh4gawxr+y3zjV8MikZzx20Ti0tnc5kcARPxoUXHL7D4TJPGYjUhdhsqjeYmZfIHDBEQfOa6oy/mNBl1dqMWsZgQgDsZEkacGZD4EiZPQHptH8ZZYf0LeMfy9xcog0ShDBKFMkgUyiBRKINE+X82OL629pwN6gAAAABJRU5ErkJggg==",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "9406b427-c28c-4cd0-9f01-e5bc1f089f4c",
- "metadata": {},
- "source": [
- "Let's proceed with a simple invocation:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "3f7012ae-4f8f-4dd3-9f99-ebd179ff5fe9",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'value_1': 'a b', 'value_2': 10}"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "graph.invoke({\"value_1\": \"c\"})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "648421de-e43a-4242-8e62-afd84bc91b7e",
- "metadata": {},
- "source": [
- "Note that:\n",
- "\n",
- "- We kicked off invocation by providing a value for a single state key. We must always provide a value for at least one key.\n",
- "- The value we passed in was overwritten by the first node.\n",
- "- The second node updated the value.\n",
- "- The third node populated a different value."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "1acdf7f1-d2f8-4863-a7f3-d5de4cc0ef28",
- "metadata": {},
- "source": [
- "!!! tip \"Built-in shorthand\"\n",
- "\n",
- " `langgraph>=0.2.46` includes a built-in short-hand `add_sequence` for adding node sequences. You can compile the same graph as follows:\n",
- "\n",
- " ```python\n",
- " # highlight-next-line\n",
- " builder = StateGraph(State).add_sequence([step_1, step_2, step_3])\n",
- " builder.add_edge(START, \"step_1\")\n",
- " \n",
- " graph = builder.compile()\n",
- " \n",
- " graph.invoke({\"value_1\": \"c\"}) \n",
- " ```"
- ]
- },
- {
- "attachments": {
- "51f122de-b2ce-4c21-a5a7-c3be70c28a91.png": {
- "image/png": "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LyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj41NDI8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+OTA0PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6VXNlckNvbW1lbnQ+U2NyZWVuc2hvdDwvZXhpZjpVc2VyQ29tbWVudD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+ClCweXwAAAAcaURPVAAAAAIAAAAAAAABDwAAACgAAAEPAAABDwAARV8dcCWfAABAAElEQVR4AezdB3wURfvA8UcgdAgdqaElNAEVFBSk96agf1REFJSiooAFRXxtiAooShHEBkhRULEjRTpIB0MTCC0JJEBooZcA/5mJt97mLqSQS+4uv30/8XZnd2dnvjcvnzyZ2ZmbrqlN2BBAAAEEEEAAAQQQQAABBDK9wE0EiJm+DQCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIIAAAggggAACCCCAgBEgQKQhIIAAAggggAACCCCAAAIIGAECRBoCAggggAACCCCAAAIIIICAESBApCEggAACCCCAAAIIIIAAAggYAQJEGgICCCCAAAIIIIAAAggggIARIECkISCAAAIIIIAAAggggAACCBgBAkQaAgIIIICARwXOnDkjW7ZssT2jWrVqEhgYaEvjAAEEEEAAAQQyXoAAMeO/A0qAAAII+LVA+/btXQJEXeHy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Ujl++pycOH1eTkSfl7PnzsvFC+cl5qL5MZ8XL56TwsUjpFSZslK2TBkpXz5C8uUQyZczixTKncV82llyggACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAApaKqg4AAAVzSURBVAgggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuCxAgugxOcQgggAACCCCAAAIIIICAVwUIEL36ZqgXAggggAACCCCAAAIIIOCyAAGiy+AUhwACCCCAAAIIIIAAAgh4VYAA0atvhnohgAACCCCAAAIIIIAAAi4LECC6DE5xCCCAAAIIIIAAAggggIBXBQgQvfpmqBcCCCCAAAIIIIAAAggg4LIAAaLL4BSHAAIIIIAAAggggAACCHhVgADRq2+GeiGAAAIIIIAAAggggAACLgsQILoMTnEIIIAAAggggAACCCCAgFcFCBC9+maoFwIIIIAAAggggAACCCDgsgABosvgFIcAAggggAACCCCAAAIIeFWAANGrb4Z6IYAAAggggAACCCCAAAIuC/w/OsDdHSiHP+MAAAAASUVORK5CYII="
- }
- },
- "cell_type": "markdown",
- "id": "710dc4f0-1c88-4386-9e9d-fec3de6bb774",
- "metadata": {},
- "source": [
- "## Create branches\n",
- "\n",
- "Parallel execution of nodes is essential to speed up overall graph operation. LangGraph offers native support for parallel execution of nodes, which can significantly enhance the performance of graph-based workflows. This parallelization is achieved through fan-out and fan-in mechanisms, utilizing both standard edges and [conditional_edges](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.MessageGraph.add_conditional_edges). Below are some examples showing how to add create branching dataflows that work for you. \n",
- "\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "d6c05fc4-ecd8-483f-a9fd-b1a055f922d9",
- "metadata": {},
- "source": [
- "### Run graph nodes in parallel\n",
- "\n",
- "In this example, we fan out from `Node A` to `B and C` and then fan in to `D`. With our state, [we specify the reducer add operation](https://langchain-ai.github.io/langgraph/concepts/low_level/#reducers). This will combine or accumulate values for the specific key in the State, rather than simply overwriting the existing value. For lists, this means concatenating the new list with the existing list. See the above section on [state reducers](#process-state-updates-with-reducers) for more detail on updating state with reducers."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "09372b8b-edea-4b9d-9ec3-3d93ce1ba819",
- "metadata": {},
- "outputs": [],
- "source": [
- "import operator\n",
- "from typing import Annotated, Any\n",
- "\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.graph import StateGraph, START, END\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " # The operator.add reducer fn makes this append-only\n",
- " aggregate: Annotated[list, operator.add]\n",
- "\n",
- "\n",
- "def a(state: State):\n",
- " print(f'Adding \"A\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"A\"]}\n",
- "\n",
- "\n",
- "def b(state: State):\n",
- " print(f'Adding \"B\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"B\"]}\n",
- "\n",
- "\n",
- "def c(state: State):\n",
- " print(f'Adding \"C\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"C\"]}\n",
- "\n",
- "\n",
- "def d(state: State):\n",
- " print(f'Adding \"D\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"D\"]}\n",
- "\n",
- "\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(a)\n",
- "builder.add_node(b)\n",
- "builder.add_node(c)\n",
- "builder.add_node(d)\n",
- "builder.add_edge(START, \"a\")\n",
- "builder.add_edge(\"a\", \"b\")\n",
- "builder.add_edge(\"a\", \"c\")\n",
- "builder.add_edge(\"b\", \"d\")\n",
- "builder.add_edge(\"c\", \"d\")\n",
- "builder.add_edge(\"d\", END)\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "66f52a20",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "74dd577b-0474-44c4-b4bc-9113090e3121",
- "metadata": {},
- "source": [
- "With the reducer, you can see that the values added in each node are accumulated."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "81646784-5e7d-4096-980d-9fdfafd6e7a3",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Adding \"A\" to []\n",
- "Adding \"B\" to ['A']\n",
- "Adding \"C\" to ['A']\n",
- "Adding \"D\" to ['A', 'B', 'C']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "{'aggregate': ['A', 'B', 'C', 'D']}"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "graph.invoke({\"aggregate\": []}, {\"configurable\": {\"thread_id\": \"foo\"}})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ea5495cf-9564-40c6-bc2d-0b2a8f72a5df",
- "metadata": {},
- "source": [
- "!!! note\n",
- "\n",
- " In the above example, nodes `\"b\"` and `\"c\"` are executed concurrently in the same [superstep](../../concepts/low_level/#graphs). Because they are in the same step, node `\"d\"` executes after both `\"b\"` and `\"c\"` are finished.\n",
- "\n",
- " Importantly, updates from a parallel superstep may not be ordered consistently. If you need a consistent, predetermined ordering of updates from a parallel superstep, you should write the outputs to a separate field in the state together with a value with which to order them."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "c392b3d2",
- "metadata": {},
- "source": [
- "Exception handling?\n",
- "
LangGraph executes nodes within \"supersteps\", meaning that while parallel branches are executed in parallel, the entire superstep is transactional. If any of these branches raises an exception, none of the updates are applied to the state (the entire superstep errors).
\n",
- "
Importantly, when using a checkpointer, results from successful nodes within a superstep are saved, and don't repeat when resumed.
\n",
- " If you have error-prone (perhaps want to handle flakey API calls), LangGraph provides two ways to address this: \n",
- " \n",
- "
You can write regular python code within your node to catch and handle exceptions.
\n",
- "
You can set a retry_policy to direct the graph to retry nodes that raise certain types of exceptions. Only failing branches are retried, so you needn't worry about performing redundant work.
\n",
- "\n",
- "Together, these let you perform parallel execution and fully control exception handling.\n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "48731230",
- "metadata": {},
- "source": [
- "### Defer node execution\n",
- "\n",
- "Deferring node execution is useful when you want to delay the execution of a node until all other pending tasks are completed. This is particularly relevant when branches have different lengths, which is common in workflows like map-reduce flows.\n",
- "\n",
- "The above example showed how to fan-out and fan-in when each path was only one step. But what if one branch had more than one step? Let's add a node `\"b_2\"` in the `\"b\"` branch:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "id": "3890af2f-fb14-4569-b48d-a91db2d3f026",
- "metadata": {},
- "outputs": [],
- "source": [
- "import operator\n",
- "from typing import Annotated, Any\n",
- "\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.graph import StateGraph, START, END\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " # The operator.add reducer fn makes this append-only\n",
- " aggregate: Annotated[list, operator.add]\n",
- "\n",
- "\n",
- "def a(state: State):\n",
- " print(f'Adding \"A\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"A\"]}\n",
- "\n",
- "\n",
- "def b(state: State):\n",
- " print(f'Adding \"B\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"B\"]}\n",
- "\n",
- "\n",
- "def b_2(state: State):\n",
- " print(f'Adding \"B_2\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"B_2\"]}\n",
- "\n",
- "\n",
- "def c(state: State):\n",
- " print(f'Adding \"C\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"C\"]}\n",
- "\n",
- "\n",
- "def d(state: State):\n",
- " print(f'Adding \"D\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"D\"]}\n",
- "\n",
- "\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(a)\n",
- "builder.add_node(b)\n",
- "builder.add_node(b_2)\n",
- "builder.add_node(c)\n",
- "# highlight-next-line\n",
- "builder.add_node(d, defer=True)\n",
- "builder.add_edge(START, \"a\")\n",
- "builder.add_edge(\"a\", \"b\")\n",
- "builder.add_edge(\"a\", \"c\")\n",
- "builder.add_edge(\"b\", \"b_2\")\n",
- "builder.add_edge(\"b_2\", \"d\")\n",
- "builder.add_edge(\"c\", \"d\")\n",
- "builder.add_edge(\"d\", END)\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "1a3508e6-bcaf-448e-bdc8-bf5701589d42",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "b510379a-b82a-4658-973e-df56caf5cd01",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Adding \"A\" to []\n",
- "Adding \"B\" to ['A']\n",
- "Adding \"C\" to ['A']\n",
- "Adding \"B_2\" to ['A', 'B', 'C']\n",
- "Adding \"D\" to ['A', 'B', 'C', 'B_2']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "{'aggregate': ['A', 'B', 'C', 'B_2', 'D']}"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "graph.invoke({\"aggregate\": []})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "70e67ced",
- "metadata": {},
- "source": [
- "In the above example, nodes `\"b\"` and `\"c\"` are executed concurrently in the same superstep. We set `defer=True` on node `d` so it will not execute until all pending tasks are finished. In this case, this means that `\"d\"` waits to execute until the entire `\"b\"` branch is finished."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "1a940eec-f36f-4236-9cc8-8d5dfd5cc860",
- "metadata": {},
- "source": [
- "### Conditional branching\n",
- "\n",
- "If your fan-out should vary at runtime based on the state, you can use [add_conditional_edges](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.StateGraph.add_conditional_edges) to select one or more paths using the graph state. See example below, where node `a` generates a state update that determines the following node."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "8b270199-f07d-4831-9674-f18715fa26de",
- "metadata": {},
- "outputs": [],
- "source": [
- "import operator\n",
- "from typing import Annotated, Literal, Sequence\n",
- "\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.graph import StateGraph, START, END\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " aggregate: Annotated[list, operator.add]\n",
- " # Add a key to the state. We will set this key to determine\n",
- " # how we branch.\n",
- " which: str\n",
- "\n",
- "\n",
- "def a(state: State):\n",
- " print(f'Adding \"A\" to {state[\"aggregate\"]}')\n",
- " # highlight-next-line\n",
- " return {\"aggregate\": [\"A\"], \"which\": \"c\"}\n",
- "\n",
- "\n",
- "def b(state: State):\n",
- " print(f'Adding \"B\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"B\"]}\n",
- "\n",
- "\n",
- "def c(state: State):\n",
- " print(f'Adding \"C\" to {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"C\"]}\n",
- "\n",
- "\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(a)\n",
- "builder.add_node(b)\n",
- "builder.add_node(c)\n",
- "builder.add_edge(START, \"a\")\n",
- "builder.add_edge(\"b\", END)\n",
- "builder.add_edge(\"c\", END)\n",
- "\n",
- "\n",
- "def conditional_edge(state: State) -> Literal[\"b\", \"c\"]:\n",
- " # Fill in arbitrary logic here that uses the state\n",
- " # to determine the next node\n",
- " return state[\"which\"]\n",
- "\n",
- "\n",
- "# highlight-next-line\n",
- "builder.add_conditional_edges(\"a\", conditional_edge)\n",
- "\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "43999312-0198-49e4-86a9-4f71e343ed64",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "id": "c6e92bf6-5ee8-4a5a-8693-a0e028b73e3b",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Adding \"A\" to []\n",
- "Adding \"C\" to ['A']\n",
- "{'aggregate': ['A', 'C'], 'which': 'c'}\n"
- ]
- }
- ],
- "source": [
- "result = graph.invoke({\"aggregate\": []})\n",
- "print(result)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "b1c54e61-393d-4359-88e2-6117a6022ce3",
- "metadata": {},
- "source": [
- "!!! tip\n",
- "\n",
- " Your conditional edges can route to multiple destination nodes. For example:\n",
- "\n",
- " ```python\n",
- " def route_bc_or_cd(state: State) -> Sequence[str]:\n",
- " if state[\"which\"] == \"cd\":\n",
- " return [\"c\", \"d\"]\n",
- " return [\"b\", \"c\"]\n",
- " ```"
- ]
- },
- {
- "attachments": {
- "f0038a5c-08d9-4eff-a1cb-d1ee4dde4fe5.png": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAABXIAAAExCAYAAADRMVpJAAABXWlDQ1BJQ0MgUHJvZmlsZQAAKJF1kD1Lw3AQxp9oS0EDFnUQ6hDoJFQpbcRBCtZaXyBDaC21gkOa1lboy98kIm7i4hcQv4BQ3B3q4ODkLAgKguDqLARBS7x/o6ZVvON4fjzcHccBA6LGWM0HoN6wjMzKorRR2JQCL/BTBillTTdZUlUVasG39od9D4Hr3TTfpa2ehd4ux+ZCN+JTdjd89Le/L4ZKZVMn/aCSdWZYgBAlVvctxvmQeNygo4hPOFdcPudcdPmq27OeSRHfEgf1qlYifiaOFHv8Sg/Xa3v61w38erHcyGVJJ6gmsYQ0FEoJOcQhI4ZZ5JH+Z0buzqTQBMMBDOyggiosmk6Sw1BDmXgNDeiYQYQ4hijfyX/9+4eed0yayBMseJ5SAC6awGjL88JbwMg8cL3MNEP7+axg+8zteMzl4TbgP3WcV9oXmAI6D47z3nacTgsYfKRZ+xN5zGEwOHUGjgAAAFZlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA5KGAAcAAAASAAAARKACAAQAAAABAAAFcqADAAQAAAABAAABMQAAAABBU0NJSQAAAFNjcmVlbnNob3S9u+miAAAB12lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zMDU8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MTM5NDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlVzZXJDb21tZW50PlNjcmVlbnNob3Q8L2V4aWY6VXNlckNvbW1lbnQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgqn9EX7AABAAElEQVR4AeydB4BVxfnFz/beCyxLWXqXJihYwB4xdqNGjcYaY0xMYokaW9QY/zExRZMYE02MGrvYS1CkSJPey9J3l+299//55vGWB1IWWHB3OQO77+0tc2d+d+69M+d+831+zUxQEgEREAEREAEREAEREAEREAEREAEREAEREAEREAERaLcE/NttyVQwERABERABERABERABERABERABERABERABERABERABR0BCrhqCCIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQEKu2oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAItHMCEnLb+QlS8URABERABERABERABERABERABERABERABERABERAQq7agAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAi0cwISctv5CVLxREAEREAEREAEREAEREAEREAEREAEREAEREAEREBCrtqACIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQEKu2oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAItHMCEnLb+QlS8URABERABERABERABERABERABERABERABERABERAQq7agAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAi0cwISctv5CVLxREAEREAEREAEREAEREAEREAEREAEREAEREAEREBCrtqACIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQEKu2oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAItHMCEnLb+QlS8URABERABERABERABERABERABERABERABERABERAQq7agAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAi0cwISctv5CVLxREAEREAEREAEREAEREAEREAEREAEREAEREAEREBCrtqACIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQEKu2oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAItHMCEnLb+QlS8URABERABERABERABERABERABERABERABERABERAQq7agAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAi0cwISctv5CVLxREAEREAEREAEREAEREAEREAEREAEREAEREAEREBCrtqACIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQEKu2oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAItHMCEnLb+QlS8URABERABERABERABERABERABERABERABERABERAQq7agAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAi0cwISctv5CVLxREAEREAEREAEREAEREAEREAEREAEREAEREAEREBCrtqACIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQEKu2oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAItHMCEnLb+QlS8URABERABERABERABERABERABERABERABERABERAQq7agAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAi0cwISctv5CVLxREAEREAEREAEREAEREAEREAEREAEREAEREAEREBCrtqACIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAREQAREQAREQAREQAREQAREQAREQAREQEKu2oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAItHMCEnLb+QlS8URABERABERABERABERABERABERABERABERABERAQq7agAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAi0cwISctv5CVLxREAEREAEREAEREAEREAEREAEREAEREAEREAEREBCrtqACIiACIiACIiACIiACIiACIiACIiACIiACIiACLRzAhJy2/kJUvFEQAREQAQOH4H60lKULFqA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iIAIiEDHJCAht2OeN5VaBERABNoPAYq5jbQu3fz0H1G1KR3D//ws/IJswkdrLFbbTzUOa0nIyKyXze1EU00N+QQxIFrQfl0zHNYyKXMREAEREAEREAEREAEREAEREIEORUBCboc6XSqsCIiACLRfAs1NTQxO1kCB0gKYKYmACIiACIiACIhAxyOwOacSm7IrMXZgPKLD5Ymw451BlVgEREAEOjcBzXvt3OdXtRMBERCBI0bAz99fIu4Ro60DiYAIiIAIiIAItDWB+oYm/OXtdXjw74vdZyODliqJgAiIgAiIQHsiICG3PZ0NlUUEREAEREAEREAEREAEREAEROAbIWBCbnpGORobGcw1qwIScr+R06CDioAIiIAI7IOAhNx9wNEqERABERABERABERABERABERCBzk/AbG9NuC0uqYV9r6OoqyQCIiACIiAC7Y2AhNz2dkZUHhEQAREQAREQAREQAREQAREQgSNLgOrt1rxqirkeAbemttFilCqJgAiIgAiIQLsiICG3XZ0OFUYEREAEREAEREAEREAEREAEROBIE2imHe6MFfnOGteOXVldTyFXSu6RPg86ngiIgAiIwL4JSMjdNx+tFQEREAEREAEREAEREAEREAER6OwEqNl+tbqgRbwNCPSHn19nr7TqJwIiIAIi0NEISMjtaGdM5RUBERABERABERABERABERABEWhzArl5VS3uFCLDguDHf0oiIAIiIAIi0J4IBLanwqgsIiACIiACIiACIiACIiACIiACRzcB82hgrg48Mirl1COgp5oThaqaBgfejhcbSSH3CBz36D7Tqr0IiIAIiMCBEpCQe6DEtL0IiIAIiIAIiIAIiIAIiIAIiECbEzABt7a+EQs2lGBrbiWC6d6gb0oEhvaMRkhQwF6FVa/w2+LglgKsWdMeqBDb2OAJdGYV6xoXCn//tlNyD7aMB7tfm58cZSgCIiACItAuCEjIbRenQYUQAREQAREQAREQAREQAREQgaObwLrMctz796XIzqvYBURMdAiuO6cfzhyXgtiIoF3WNVHpXLy+GG/NysTaraVmyothfWJx1tgUTBiasFcxtoaCcRN127DgnQJxU7NHyPWjAty/RzT8dyjBJqbmldQghNvGhB+4pW5VbSP97xbikwXZWLK+CMFB/hjUKwbfP6s3BqftPM4uFeMf9RSWV20pw9tf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"
- }
- },
- "cell_type": "markdown",
- "id": "931a0f15-b8d2-4ff6-8772-fd99f708a099",
- "metadata": {},
- "source": [
- "### Map-reduce and the `Send` API\n",
- "\n",
- "By default, `Nodes` and `Edges` are defined ahead of time and operate on the same shared state. However, there can be cases where the exact edges are not known ahead of time and/or you may want different versions of state to exist at the same time. A common example of this is with map-reduce design patterns. In this design pattern, a first node may generate a list of objects, and you may want to apply some other node to all those objects. The number of objects may be unknown ahead of time (meaning the number of edges may not be known) and the input state to the downstream `Node` should be different (one for each generated object).\n",
- "\n",
- "To support this design pattern, LangGraph supports returning [Send](/langgraph/reference/types/#langgraph.types.Send) objects from conditional edges. `Send` takes two arguments: first is the name of the node, and second is the state to pass to that node.\n",
- "\n",
- "```python\n",
- "def continue_to_jokes(state: OverallState):\n",
- " return [Send(\"generate_joke\", {\"subject\": s}) for s in state['subjects']]\n",
- "\n",
- "graph.add_conditional_edges(\"node_a\", continue_to_jokes)\n",
- "```\n",
- "\n",
- "Below we implement a simple example, where we simulate using LLMs to (1) generate a list of subjects (the length of which is unknown ahead of time), (2) generate jokes in parallel, and (3) select a \"best\" joke. Importantly, the input state to the fan-out nodes is different than the graph's overall state.\n",
- "\n",
- ""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "8b971a9c-337a-4899-bcf7-080193832935",
- "metadata": {},
- "outputs": [],
- "source": [
- "import operator\n",
- "from typing import Annotated\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.types import Send\n",
- "from langgraph.graph import END, StateGraph, START\n",
- "\n",
- "\n",
- "# This will be the overall state of the main graph.\n",
- "# It will contain a topic (which we expect the user to provide)\n",
- "# and then will generate a list of subjects, and then a joke for\n",
- "# each subject\n",
- "class OverallState(TypedDict):\n",
- " topic: str\n",
- " subjects: list\n",
- " # Notice here we use the operator.add\n",
- " # This is because we want combine all the jokes we generate\n",
- " # from individual nodes back into one list - this is essentially\n",
- " # the \"reduce\" part\n",
- " jokes: Annotated[list, operator.add]\n",
- " best_selected_joke: str\n",
- "\n",
- "\n",
- "# This will be the state of the node that we will \"map\" all\n",
- "# subjects to in order to generate a joke\n",
- "class JokeState(TypedDict):\n",
- " subject: str\n",
- "\n",
- "\n",
- "# This is the function we will use to generate the subjects of the jokes.\n",
- "# In general the length of the list generated by this node could vary each run.\n",
- "def generate_topics(state: OverallState):\n",
- " # Simulate a LLM.\n",
- " return {\"subjects\": [\"lions\", \"elephants\", \"penguins\"]}\n",
- "\n",
- "\n",
- "# Here we generate a joke, given a subject\n",
- "def generate_joke(state: JokeState):\n",
- " # Simulate a LLM.\n",
- " joke_map = {\n",
- " \"lions\": \"Why don't lions like fast food? Because they can't catch it!\",\n",
- " \"elephants\": \"Why don't elephants use computers? They're afraid of the mouse!\",\n",
- " \"penguins\": (\n",
- " \"Why don’t penguins like talking to strangers at parties? \"\n",
- " \"Because they find it hard to break the ice.\"\n",
- " ),\n",
- " }\n",
- " return {\"jokes\": [joke_map[state[\"subject\"]]]}\n",
- "\n",
- "\n",
- "# Here we define the logic to map out over the generated subjects\n",
- "# We will use this as an edge in the graph\n",
- "def continue_to_jokes(state: OverallState):\n",
- " # We will return a list of `Send` objects\n",
- " # Each `Send` object consists of the name of a node in the graph\n",
- " # as well as the state to send to that node\n",
- " return [Send(\"generate_joke\", {\"subject\": s}) for s in state[\"subjects\"]]\n",
- "\n",
- "\n",
- "# Here we will judge the best joke\n",
- "def best_joke(state: OverallState):\n",
- " return {\"best_selected_joke\": \"penguins\"}\n",
- "\n",
- "\n",
- "# Construct the graph: here we put everything together to construct our graph\n",
- "builder = StateGraph(OverallState)\n",
- "builder.add_node(\"generate_topics\", generate_topics)\n",
- "builder.add_node(\"generate_joke\", generate_joke)\n",
- "builder.add_node(\"best_joke\", best_joke)\n",
- "builder.add_edge(START, \"generate_topics\")\n",
- "builder.add_conditional_edges(\"generate_topics\", continue_to_jokes, [\"generate_joke\"])\n",
- "builder.add_edge(\"generate_joke\", \"best_joke\")\n",
- "builder.add_edge(\"best_joke\", END)\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "2760846f-a297-455c-a07c-155743f5e55f",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAAAKAAAAGwCAIAAAChDPlVAAAQAElEQVR4nOydB1wUx9vH5zp3R+8dRRBUEHsBY40FY4nYWxKxxBKjEUM0amzYUNTYUYwmNoyJiZpoYkRjYouxoaJUadL7cXcc13gfWP8XXkUChivMzvfDR3dnZvd29zfzPM/Mzu6yq6qqEAFf2IiANURgzCECYw4RGHOIwJhDBMYcgxO4KKdSUqaSlitlUrVcpkYGDwMuIpchMGULTFimVhwzKw4yJBgG0g/OSpY+eyxJfSSxczOSSVUCE7apJZvBYCDDh1Ell1VJRUppuYrFZohLlS19hK3aC22cjZABoH+Bc9NlN84VmllzrOx5LX2FhtYCGkthdmXqY0lpvlypqPIfYa3309GzwFe/L8jPkPkPt3by4CO8SI4V3zhb6NXFpHugFdIfehO4QqI6EZ4xYIKtWxshwpf4v0WPb4jGLHBGekI/AkP09M3atImhrkIz/MP4nNSKs5HZsza46yWk0IPAEIacjMiYvtYd0QaJSHkkLH12eCukc5hI54BlnrzUDdEJoSl75FzH77Y/RzpH1y045kRe256mDi1wC6kaQsIdUUm+osdQncZcOm3Bzx6JYfiCnuoCXl1Mkx+IS/LlSIfoVOAb54r8h+uzz6B34PThIiAdojuBE++KWvkZW9hyEY1x9zXm8Zm5aRVIV+hQ4PtiezeDGL3TL5b23JSHEqQrdCQwhHJpcVIYpEU6JCUlZdiwYajxfPvtt6tWrULaAS4CjGUiXaEjgdPiJD7+pki3PH36FL0Rb7xhQwAnBQPvxbmVSCfoaCAJugccnrYqU25u7vbt2+/evSuRSBwdHSdNmhQUFBQZGXngwAHI7dKly6JFiyDxyZMnu3btSkhIqKysdHd3nzdvXvfu3VFNQx8/fvzWrVt37tzJ5/ONjIzu3bsH6T/99NOxY8e8vLxQU8NgorJCpaU9D2kfHQksFamE5iykHVavXi2Xy0FjMzOzW7dubdy4EWR+//33y8vLr1y5AiKBbCDq/PnzfX199+zZw+FwTp8+HRISAv/a2trCKuxk//79U6dObdu2rb29/ezZs11dXUNDQ01MTJAWgHEPGNtCOkFHAkvKlbYu2qqwycnJ0ATbtWsHy2PGjPH29nZwcICGyOPxYPjX3Nwc0pVKJbRpa2tranXOnDnR0dGxsbEDBw6khoihoY8YMYLaIZvN5nK5VEltACPwkjK8BGYyGXAzHGmH3r17Hz58GNprQEBAx44dfXx8Xi0DmikUivDw8MTERChJjd+VlZVpCkDjRrqCw2UodOSCdSUw14ipPaO0dOlSDw+P8+fPgzUWCoXQiKGBgqK1y2RkZIDh7dq169q1a21sbNRq9dChQ2sXMDY2RrpCVKy0sNXRRAAdCSw0ZUlEKqQdQMuJNRQVFf3888/gZS0sLKZMmVK7zMWLF1Uq1bp168Buo5q4DOkPqUipswkOOuomQcdAS3c1xGLxhQsXwMXCspWV1XvvvQfGFrzyS8UgCqO8MrUKzb3+3Wr1HgybyzSx0JVzRDrB1Vvw+LoIaQEIkTZt2hQWFgb9n6ysrF9++QV6sZ07d4YsiIELCwvv37+fk5MDjrm0tPTs2bOQcurUqbi4OGjl4I+hfry6T9gwoQbYBDU14KoyE6R2rjoa1GNpb8imNmwOMz1eYmrJgT/UpEC4CwHw5cuXIc6CwDgpKQmM89ixYyELOjzXrl07ceIEdJNGjx5dUVFx5MgRKAObrFixAiw2KA1xVvv27U+ePPnOO+84O7+YWAPdLTD10ImCkM3FxQU1KYl3yyEiadlOR4N6ursf/PhGmUyq6vK2JaI3v5/Kd/cVunrrSGDd3Wzw8Te7F1NaWaGtUKtZkJsuK3heqTN1kY5ndEAjhtPrN862ztyrV6+uXLmyziywmbX7rLUZNWrUggULkHZYuHDhgwcPUCMPCUbW+vTpU2fW6V3Puw+x0uUcYV1P2fn5YHbvUTYmdXliiITBTda5FYxRUAOKrwLpEB4j7SCVSsFVo0YeErj8l3rhFM8TpUmx4n5j667fWkLXAsskqiPr02euo9GUSooKserYxvQZYbo+cV3PqjQSsoZOczi1PRPRjOOb0ieGuiKdo5+J78V5lTEn8scubOIeiGECceXxjRkTl7ga8bV1P60e9DAvGrC04/kPsz7w+bOyIp1OMdQ9uWkVX69JH7PQWS/qIv0+fAbdYmjHRkKm/3BrvlA/5689SvLk188VwnkNmGiH9If+Hx99ckt041xh+95m9i34rl4C1MypUlc9eyzJz5ClPJIEDLfW8TS0VzGUB8DjbpYlPxBnp8p8e5mhKrglzjIx5zDZzeABcHByMplKKlLBPXyVsurxTZG7j9Cjo3HrjlqZDdJYDEVgCqVcnR4vFRUpJGUquUxdIWniYS+4KwydZlvbpuyJMpnVI+0CU5bQjG1uw2nR1rCehjUsgbVNeHi4m5vb+PHjEW0gb9nBHCIw5hCBMYcIjDlEYMwhAmMOERhziMCYQwTGHCIw5hCBMYcIjDlEYMwhAmMOERhziMCYQwTGHCIw5hCBMYcIjDlEYMwhAmMOERhz6CWwQCDgcun1RnJ6CSyVSuVyzJ9nfAliojGHCIw5RGDMIQJjDhEYc4jAmEMExhwiMOYQgTGHCIw5RGDMIQJjDhEYc4jAmEMExhxavAhtxIgR1GmKRCIWiyUUvngZ3blz5xDu0KIFW1tbx8bGUh+hRDUyq9Xqt99+G9EA/bwvWsdMmTLFwsKidoqVlVVwcDCiAbQQuH///i1atNCsgrn28/Pz9vZGNIAWAgOTJk0yNX3xjXlovtOnT0f0gC4CQyN2d6/+4gk03/bt27dp0wbRA7oIDIwbN04gEDg4ONDE+1L8exStqFQX5cil4mb/SToPxwAf9wG2trZGardnjyWoOQP9AWNztqU991+/q/4v/eA/ThckPxALzdh8YzIkYkBwjZjFeZWoCnl3NenU36KekvUJfOFQjoWDUbue9W1P0C+3fs43MWf1GGr1ugKvFfi3Y3nmdjzvruaIYNjcvlBgZs3u8nbd7bDuICsvUyarUBN1mwXdAm2ePRS/7ru9dQtcnCNnc2gUYDd3qhCjOK/uZ67qVlEiUppb0+spvGaNtSOvvKjuFlx3bKxWIZWSRp/bae7IK9Svi6VI5wdziMCYQwTGHCIw5hCBMYcIjDlEYMwhAmMOERhziMCYQwTGHHLLSOusXBUasngO0hOYC7xq9We//Pqfnk/54cdvN4avQv+BYcOCxoyehPQE5iY6MfFpjx690H8A9oD+G1279ED6o+4pO7d/LZbLkF9fS9RgCgsLIratu3//b2NjE6iwEon4jz8vf33oO8hSKpVHjx28fOViXl6OjY3d2DGTR44YA+np6akfBI/dGrHv+9MnHj16wGQy+/UdOG9uCIvFgtzS0pI9+7bFxt4tKyt1d/ecOeOjjh26oJom9c2RA4sXLd+yNWzQwHfmzF5YUlK8N3L7vXu3y8tFsP+gd8cHBU2Akv0GdKGOzdjY+NyZ32Eh5vKvp04dTc9I5fMF/fsNnjF9npGRUT0ntXDRrNjYe9Ty/shjnh5ecJwHDu4C1RkMRhtvn5kz57fxbge5p747duTowRXL1+/eEwGnaW5m8cH7Hw4ePAzVmGixuDxiy15YLioq3LN36+2/bzAYzM6dus2Z/YmtrR2k/3z+x+++P56Tk8XjGfm17/TRvMVUegO5djrP3Vfg1cXk1awmM9FwuZOS4teuidi0YWfsw3sgJwhGZe2L/PLkt0cmT5x2MOokqLtr9xY4H0hnsavtB1yRiePfP/NDzPJl60A8qBaQqFarP1syPy7u4WehqyL3HvX2artk6cfPniVDFofDkckqTv8QDVkjR46FlPAta57EPVyxbH3U/hOTJn6we+/Wa9d/h/Rvo8/Dv/M/+vTokTPVV+Ha72HrlnXu3P3A/hOhn678488YqJH1n1TYmq2tPb379xv04+lL7i09MjPTF4fOtbG23b3z8K4dh/gCweJP5+Tn51WfC4sNdRpqT8TmvWd+uDxo0DubNq/OyEirvTeo6HAW2dnPV6/aHLYmAuRcumwBnOnDh/e3RISNDpoI12fD+i/LRKWr1y5BTUTTCFxcXHT79o0pk6eDOWrVynP55+tEZaVUllgsPnP21PhxU6E6Ozu5QNsdPGjY8ROHNdv26f12u3btYQFqtKODU0LCE1i+c/evxKT4xSHLO3Xs6ubWEmq0nZ0DiApZ0HRkMhkYiR7dA6A8pECjDw/f7efXycXFbWjgSI9Wre/cuQXppqZmqOYd0WY1C8ejD0MZsARwGLDtzBnzL126QMnzOqDpQy3kcLlmZuZgV86c/Q6a/tIla+Ac4W/Z0jDQ7NeLP1GFQaqpU2ZYWVlzuVy4FGAbYi7/Untv9x/cSU5J/HTxF3BS7dt3DAlZ7uLsBpYvNS2Fx+MNGTzcydG5bRuflSs2whmhJqJpfHBWViaYep92ftSqUCiEhgKWEJZTUhLhKnTp/I8f8vPrDC1YKpVSq63cPTVZYN7BmsHC06ePoaV28OtMpYMxaO/bMTk5QVOybVtfzTLfiA/iPXhwB4w5XGUw1E5OLi8dIaSDXQWzqUmhdv7sWVLDjWFi0lNo0Gz2i4sGVQeqFJygpoCn54sH2uDgnRxd4LL8v80Tn4L27u4eLwp7eK1auQkWwPVArf144QyonXDdHOwdLS2tUBPRNAKX1bRXMFmaFKr1oOp3cFc/Q/BJyIeax3Mpr19cUkStcnm82ruicmErhUIxONBfk65SqWqftlBoTC1A7Qld8hHkQit3dWkB7Wz5F3VUf2j0UObw15Hgv2unFxUXogYDR2VlaV07RSAQUidIUdujG/H55TWVVQPUPCMj/qu7dXVtAQb/xMmv9x/YWb51XZs2PnAu0JRRU9A0AlMiVcpkmhQ4GWqBUmLZ52Hgw2pvYmtjl1/wWvMIW0FlPxB5vHaixqnXBto6+OYvtx0Ao0ellJWWQCN4qRhcemh5QaMmvDP03drp5haNCCThqMDR1k6B1dqSV1RU8PkvJATh7e0c/t9vmVtAItRgTV3XUOPXwqAKQhB38NCez5cthACiSb4+0DQ+mDKJ8Qlx1KpEIrl79y9qGQJgsFcQ6EI9pf6gcYNLq//ovb3byeVyOGHNVlwuz9ra9tWSlfJKVMtgQFyWk5tdu2tALUPlAPsJ8a1mhw4OTuBfTU1M0b+h2ZtX67YJiU/BtFCr0EAhjPKuiaIpIOanFsABQZaLS4va+/Hw8AJ78+TJI2o1Le3Zh7OnpKamQB2Fw0bVkRqrQ4fOwdPmgEWEsAY1BU0ksKMzOKdjx76CA4UT27DpC4v/mVOIU6CnD7YR4ursnCwINCAQ/dehAwi4wEWt37DiwYO7INilmF9mfTgJgrVXS0JIBXUF4i/ogfx959aOneEQ6GU+T4cqxasBQvqk5AS4shPGvwchOsR3EAxDCuz84wXToS7WfyQmxibgb/b12gAAEABJREFU+6E8XHQI2isrZRC0wx7AbEBMDm0aYkaqJMgDoQA0QcjdvmMjpAwYMOSlkwIHvDliLRwnFIMYHmonePG/bt9YtmLR1T9isrKfww+dPh0NTd/Ozh41BU020AGdHDh08LXWVjaTJweD4YqPf9Gg587+BC7T/gM7QAPwo/49e08Pnlf/3uBibdq4E3q3K1eHQqfI3t5x6tQZ0MV6tSTYPejzREXtuvjbz61bt4G+U0Fh/tqwpYsWzz508NuJEz6IPvn1zZt/Hj3yY++3+n++dO2J6MOHDu8DYXx8/LZFRGpeyPI6Ro2asGHjF1AVoG/TrWvPzZt274/aOWPWRDhCX58OsAc4AE3hWTPm79y1+VlqMnSl1q7eAvW+9q7AMq8P275z9+ZVq0NZTBYEmxCHg+OYMjlYqVTs27e9sKiAOrCNG3a8asbfjCYb6IAoRqFUgJDU6qKQ2WA2qSiRDpz+4SR06GN+u430QT0DHU3WgiEugMA45JNlFhaWN2/9CaZ4w7rtiKBvmtJEwyDcipWLwUs5OjovCV31HweBdcbwkX1fl7UkdHVAQB/UnGkyE918gSDudVkW5pb1D1YbCLow0c2XVzvNOEEExhwiMOYQgTGHCIw5RGDMIQJjDhEYc4jAmEMExpy6BTYSsNQqNSI0E3jGLA6v7tuLdd/wN7Nm56RVIEIzITNebOXAqzOrboGdPQXyimb//mCaUF6isLDlmllz6sytW2AWm9F9iOXFb7IQweC5Ep391rvWr8ut73XCWSkVv36T26GPpbkdT2BCwjEDgsFAomKFqEh+81zBe8vdTK04ry1Z/wvBxaXKe5dLctNk0nIcLLZSoWAwmdSzT80avjGbw2U4tjLqHmhZ/+wtWnz5TEN4eLibm9v48eMRbaCX4R06dKixsTGiE/RqwTSEXq9wuHDhwu3b+pnZqi/oJfCjR49SU1MRnSA+GHOID8Yc4oMxh/hgzCE+GHOID8Yc4oMxh/hgzCE+GHOID8Yc4oMxh/hgzCE+GHOID8Yc4oMxh/hgzCE+GHOID8Yc4oMxh14mOjMzU/MyYJpAL4H9/f2JDyZgBfHBmEP6wZhD+sGYQ3ww5hAfjDnEB2MO8cGYQ3ww5hAfjDnEB2MO8cGYQ3ww5hAfjDnEB2MOLUz0hAkTmEwmnCnc7WfVUFVDdHQ0wh1aBFmgZWJi4kspHTp0QDSAFiZ67NixPN7/e52yQCCYNm0aogG0EHjMmDEuLi61U7y9vXv1ah4fR/2P0CXIAo25XC61bGJiEhwcjOgBjQSmGjF4X2i+PXv2RPSARt0k8MTQiE1NTadMmYJow5tH0aIiBYPJQM2Hgf1GfH/yvK2tbfu23ctLlKj5AD1ZU8s3VKrR/eCc1Ip7l0tT4ySO7nzQGBG0j6UDLytJ6uEn7D7UytSS06htGydw+lPpzZ+LAt61M7Pm1P8meULTolSoS/Pll0/mBM1zsrDlNnzDRggM6v71S1FgsAsi6I9TW1PHLHBueDtuRJB170rJgMk4f+6+WdBvvMOt88UNL99QgctLFKX5Ci6v2X+vpLljYcdLflDe8PINFbi0QOHsKUAEfcNiM1y9hKUF8gaWb2jwXaWu/oYSIhgAxXnyhke45HtmmEMExhwiMOYQgTGHCIw5RGDMIQJjDhEYc4jAmEMExhwiMObQ69GVJmHlqtCQxXPqL/PsWXK/AV0ePXqA9A3tWvAPP36bkPhkSegq9KYMGxakbD4vvKSdwImJT9F/o2uXHqj5oEWBlUrlnr1bL8X8olIpe781IMC/z4qVi09/d9HCwhKyjh47ePnKxby8HBsbu7FjJo8cMYbaatTogVMnT8/Lz7185deKCqmvb8fFi5ZbWVlTO6xzq9TUlOAZ49et3bo/aiffiL93zzcqleqbIwdiYn4pKMw3NTWDn/5w1gI+n79w0azY2Huwya+//rQ/8pinh1diUnxU1K6ExKdKpaJTx27z5obY2zvUf15gosXi8ogte2E5Pz9v775td+/+VSGrcHFxmzj+/YEDh766ydFjXx0/cWjb1v1erduUlpbs2bctNvZuWVmpu7vnzBkfdezQBWkNLfrg774/fu6n07Nmzt+7+xtra5t9+7+s/j1m9S/ui/zy5LdHJk+cdjDqJOi0a/eWn8//SG3FZrNPnPy6RQv3E8fOfRX1bVJS/JGjUVTW67bicKonKH39zf7x46Z+uvgL6qePnzgcHDz34IHo0E9XXr9xNeqr3ZAetmZra0/v/v0G/Xj6kntLj7y83EUhHzKYzG0RkRFb9onKy0I+nSOXN/ReukKh+PSzeZnP09euiTh08Nveb/Vfv/GL69evvlTs96uX4Ni+WLER1FWr1Z8tmR8X9/Cz0FWRe496e7VdsvRjcNhIa2ixBf968adeAX2HvTMKlqcHz33y5FFWViYsi8XiM2dPTZ40bfDgYbDq7OQCKoIe7wx9l9rQzbVl4JARsGBra9etq39CwpN/2arm7neHDl2orYC3BwR27dLT3d2juqSza7++g/66fR2WjY2NWWw2h8s1MzOH1bPnvoM758uXrTMxNoHVz5esnTh5+NU/Yga+HdiQE/zrr+sZGWmUJYDVD97/8O692z/8eDIgoI+mzNOnjzduWvnJwqU9ugfA6p27f4HN2Bqxj2q1H81bDCmnf4heHLIcaQdtteCqqqrnzzN82vlpUnr16kctpKQkgrHt0vkfT+bn1zk7+7lUKqVWwXBpskxMTEXlooZs1batryYL9ANF5370wbgJQ4PGDDr30/flNTt5Cbj63l7tKHUBOzt7Bwen5OQE1DCSkuN5PJ5Hq9aalNat2ySn/POcam5ezrIVi8aNnTI0cKTmF8HedPDrTK2CPWvv27Hhv/gGaKsFV1RUgB58wT/TuMAXUgtSqQT+/QRs4//mnVBTd4tLigQ15V961JPxb1tRq0LhP29X2blr82+Xzn+yYGk7Hz8el3ci+mvw6K8epEQiTkpOGDTkn+eUwOoWFReihiGWiI2M+LVnzwgFQuo4Kb7csRHqX1HRPzuEXPiJwYH+mhQIFywtrZDW0JbAlF+UyWSaFE0bopRY9nkYeMHam9ja2NWzw3q2yi/Iq50Cl+z8hTNTp8zQxDsg5Ov26evbIeSTZbUT+fyGzi00FhpDGAj1TKOxRCqpXc/AU3Tq1A2Csp493wJvRf0il8s9EHm89n6ouERLaFFg8KDxCXGalGvXrlALYIEht6Sk2LVPCyoFAku4RprHO+uk4VtBIAMaawyGRCK5cfOP2hdRM9e/TRsfCBQcHZ0hsqNSMjPTqYi9IXi1bgsRGfhUiJ6olCdxD72922kKDOg/BCrQkMHDt0SEtfH2gT1DLmwCh9eyZSuqTG5ujrm5BdIaWqw7fXq/ffXqJejVZGU/P/x1JPRYqHSIdGCsAFIgKzsn6/6DO4tD524MX1X/3hq+FdQDiHpAOfjdlJSkz5cv7N49AOwHBETgNcDjgs8Dywy9lOHDRkMT3BS+ClYhYvjmSNS06ePi4+NQw+jWzd/NrWVERNjT+Dj4rQNRu+ITnkB4/1IxiKQEfEH45tVQsTp36gbHtn7DigcP7ubkZkMfctaHkyB4RFpDi1H0tA9ml5QUbd6yhsczGjBgyJRJwdCLgBgWsubO/gQu9P4DO8A/gQfy79l7evC8f91hw7eCzhL8bvD0cfb2jsHT5kDriXscO2fee1EHokeNmrBh4xcfL5i+etXmbl17bo2I3L9/B6yyWKwWLVqFrd1aO1irH2j34Rt3QV8/9LN54IzAd6xdvaVTx64vFRMKhUuXrFnwyczTP5wcHTRh08adeyO3r1wdKpNVwOFNnTrj1TrRhDT02aSMeOndmNK3pzTi0RVoLjAgoLE/0D6gPwAdUNTMWfHFYtBmc/hupCd+2Jk+crajmXWDHk/Sook+dvzQpCkjoJsP5uva9d9B3cGDhqHmDATAYMzBwltZ26BmghZNNAxKyOWV+yK3FxcXQawLIxLvTZ2JmgNLly18/LiOG0EQHEH3z9HBKWjUBNRM0KKJbr6Aj5cr6h6wFAiEZv+Lz/VFo0w0ueFfBw3vKRk+RGDMIQJjDhEYc4jAmEMExhwiMOYQgTGHCIw5RGDMaajADCYysSS1wSCwtOch1ND3Ezb0bpKlHTfjqQQR9I1Crn6eKDGzbujrKhsqsNCMbe3MqxCTV2XpmeLcSs+OJg0v34j7wV0HWlw6mo0IeuXy8eyAEY2Yhdm41wnnZ8h++SY3YKSdqTXXSEDeW6k7JCJlWUHllejcqctchWaNeGV0o18IXpIvv/NbcdoTqakVp6ygmb0QXF2lro4Xm9ubrm2ceaX58pa+woDh1hxe4ybhvPmXz2QSNaO5PV385Zdfurq6jho1CjUrqtRVRsI3tJdv3vMxEjbDh8eZCgZLyePT6LF30rXFHCIw5hCBMYcIjDlEYMwhAmMOERhziMCYQwTGHCIw5hCBMYcIjDlEYMwhAmMOERhziMCYQwTGHCIw5hCBMYcIjDlEYMwhAmMOvQQ2Nzfn8/mITtDrw1ilpaUVFRWIThATjTlEYMwhAmMOERhziMCYQwTGHCIw5hCBMYcIjDlEYMwhAmMOERhziMCYQwTGHCIw5hCBMefN33TXjBg1alRGRgaDwVCr1UwmkzplLy+v48ePI9yhxYyOwYMHUx8Kp74DDkoLhcKpU6ciGkALgSdMmODi4lI7pWXLloGBgYgG0EJgc3PzIUOGsFgv3ucpEAjGjx+P6AFdJt0FBQW5urpSy9B8hw4diugBXQSmGjGbzaZV80W0mjY7evRoZ2dnNzc3+jRfpJtu0uPrZSkPJWp1VcHzSqRXlCoVhNAspp6rtYUdly9ktelh0srXGGkZrQv829E8njHb1sXIysGIyWpm79LXEgq5uihblhYndnQ36tjXHGkT7Qr888EcC3sj314WiFAXN8/lG5uz/Ic14isqjUWLxirhjsjYgkPUrYeew23LihQ5qVp8mkaLAqfHVzT8A120hW/MyUpungKrlFXgdxGhXiA6kYrVSGto8W5SSa6cBjcy/itqVZWkVIufnyK3CzGHCIw5RGDMIQJjDhEYc4jAmEMExhwiMOYQgTGHCIw5RGDMIQJjjgHNyXr2LLnfgC6PHj1AOqSBP7pyVWjI4jmoGYLzpLt3g97Oyc2uv4y1je3CBUscHZ0RpmBrovPycsvKSv+1mKmJ6cgRYxC+GJzAxSVFS5ctfPDgDpfLCxwyYtbM+dQDRYlJ8VFRuxISnyqVik4du82bG2Jv7wDpSqXyQNSu36/+VlJSbG5u0af327DJ47jYRSGzIXfS5BEBAX3C1kS87ufARE+fOWHH9ihf3w6wCrb6wMFdiYlPGQxGG2+fmTPnt/Fu99ImRUWF8+Z/4OvT4fOla6FYzOVfT506mp6RyucL+vcbPGP6PCMjA5rmYHAmOurg7q5den65PWrsmMknvz1y9tz3qKY5Lgr5kCNHCqUAAAyySURBVMFkbouIjNiyT1ReFvLpHLlcDlnHTxy++NvPi0NWHPrq1KKFn1/5/eLhryPh6n+xYgPkRu47uvSzNQ386czM9MWhc22sbXfvPLxrxyG+QLD40zn5+Xm1y8hksuVfhDg6OId+uhLUvXbt97B1yzp37n5g/wlI+ePPmIht65AhYXACB/j3CRo1vrWn95TJwW3b+l6KuQCJZ899B1dz+bJ17u4e3l5tP1+yNicn6+ofMZCVmprs3tKja5ceTo7OPXr02rpl35DBw2ueYBBCromJqVAobOBPnzn7HbTCpUvWtGrlCX/LloaBefj14k+aAlVVVRs2flFZKVuzeguHw4GU49GH/fw6zZzxkbOTS4/uATNnzL906cJLdUK/GJzA7X07apbbtW2fkZEGC0+fPvb2amdibEKl29nZOzg4JScnwLJ/z9737v+9Zu3S369eEpWLXF1buLi4oTciMekpVCyoHNSqQCCAXaWkJGoK7D+wE4z/xvU7jI2rJ6yr1Wow5l0699AU6ODXGVWb/SRkMBicDxYK/5nsz+fzZbLqGYcSiTgpOWHQkJ6aLIVCUVRcCAsDBw6Fxnrm7CloWyqVCgwARMUWFpao8UilEitL69opsGdIpJbjE+IexN7lcrnQgqkUMNfwi+ARvjlyoPZW1IEZCAYncIXsnzmkUqkUbCaqUR2CoJBPltUuSWUBEEbBX0VFxa2/ru3eE7E5Yu36sG2o8cCvQE2qnQKrGsk5HO7WiMht29avW798185D0NAhmIJ/g0ZNeGfou7W3Mn+j6qUlDM5EP378z5hDQuITN7eWsNCmjU9WVib0VsECU3/gkq2sqi89hDlUZxeae7++A+Fapz5L1uyhUc9teLVuC1E62AZqtVxcDg7C+39RdCt3T6/WbSByTkt/Bq0W1bwvwNPTOy8vR3NU4DhYbDZ0vZDBYHAC/3ntyuUrF3NzcyDkgU7L4EHDIHH4sNEVFdJN4avAUD9/nvHNkahp08fFx8dB1venT4ADjo29l52Tdf/BHfDEfh2qHSF1lW/dupaW9qyBPz1y5Fgwv+Fb1kA4Dd0nCI+hTVMHoAFUnDXz4xPRX1ODXxPGv/fHn5chkodN4NjWb1jx8YLpEokEGQwGZKKVKiX8Cx1c0Cx882ojI/7kSdOGBo6EROjygnncv38HXD4Wi9WiRauwtVshxoYs6A7t2bt15erQanNqZd2je68Z0z+C9Nat23Tr5r933zboMm2N2NeQA4A4fPOm3fujds6YNRF+BTaEXhn0rV8qNurdcbdu/QlaQteo91v9oU2fiD586PA+qA0+Pn6wScPjdh2gxYfPjm/M6BVkb2Fn0E+vJCcnzvxw0s4vD4I2SB+kPxFnxpcHTnNA2oHWd5NgTOrGzT9gwcraBmEK/gKDs/x8+cI6s6Cfw2SyRgwf7WDviDAFf4EhAj9+7Nzrco2FxhCQI3zBX2DoqmqGwGgImdGBOURgzCECYw4RGHOIwJhDBMYcIjDmEIExR4sCm1hwmEzy7sJ/gcVi8AQspDW0eD+YyUJlRXp++6jhU1IgNxJoUwWkNRzceZIyJSLUi7xCZePCQ1pDiwJ36m/5+HqJREQ0fi2Z8eKSvErPDlocKtfu22blMvXxTen+I+0cWgoQoRZw2VNiy1Mflr87z1GrkYrW3xetUlVdjs5PvFfu7mssEamQXqlSV78VkqHvF4KzOYznSVIff9O+Y2yRltHRh7FA5sLnlUqFnt9dGR0dbWdn169fP6RXuHymjZMW/W5tdNQPhs6AnZv+H8lScQs4pgInDz6iDWSgA3OIwJhDBMYcIjDmEIExhwiMOURgzCECYw4RGHOIwJhDBMYcIjDmEIExhwiMOURgzCECYw4RGHOIwJhDBMYcIjDmEIExhwiMOfQS2MTEhMs16FcrNjk4f1bnVcrLy6kvPdAHYqIxhwiMOURgzCECYw4RGHOIwJhDBMYcIjDmEIExhwiMOURgzCECYw4RGHOIwJhDBMYcIjDm6OhNd/olMDAwPz8f1bwhUvOdM0dHx3PnziHcocWMjr59+8K/IC2TyWTUwGKxxo0bh2gALQSeNGmSs7Nz7RQXFxciMD6AnAEBARpnBM135MiRPJ6OXgeqX+gy6W7ChAmaRuzk5DR27FhED+gisKura48ePVBN8w0KCuLz6fLCWRpNm504caJzDWPGjEG0wRC7SfJKddoTSVG2XFymkoiUanWVqonmMufm5nC4XCtLK9QU8E1YalWV0JRlbM62deG1bCdEhodhCRx3syzuVnlRdqWlszF0Zdg8FpsL/7GQQX5+CQ5KIVcp4a8S/hQlWRInT4GPv4lWP7LRWAxF4Kd/l18/U2juZGJkamRs2VwdpChfKhNVVJbLegdZu3kbxHdI9C+wWo3OROZKxVW2HpYcIxyGTitElQUpJdaO7MD37Rj6tj16Frg4t/JEeKZ7dye+KW7PhIkKJEWpJe8tc2Wx9SmyPgWWipXHNz5v1dOZgeknDisliqxHuVOXuXC4Wvw6Yf3oTeDyEkV0xHPPAFeENWqVOuFqxpzNrZCe0Fs/+PjGTPduTgh3mCymWyf7E5szkZ7QTwv+7XievEogtKTL9+7KckR2DuoegU3T/24UemjBWSkVuekK+qgLmDmYPvyjTFquh+906kHgP38otGphgWiGjYflnz8WIZ2ja4EzEyRVLLbAXP+fuasTiaR08YrusY9jUFNj4WhSlKuE0BLpFl0LnPxQyuXT4kbsqzA57LQ4CdItuhY49bHExIam3xIWWgmSYqVIt+h0aLA4T25qzeMKOEg7PM+OP//bHvhXpVR4tuo6IvATSwsHSL9x+/tfY/YHT4k4c35rfkGaQGA2oM+07p1HUFvdvH065o/DYkmJs4P3kIGzkdYwsRbk5pdBzxj6TkhX6LQFi0uVlVI10g4lpbn7vprLZDDnBO+ZHbxbKhVFHv5Ioay+0chismUy8aWrX703YcPaZTGdOww9fW5TaVn1PMtnafe/P7epfbsBi+YeHdB32rkLO5A2EZcodPyVbJ0KLBUpWVobtLv592nEYEweu9bBzsPFqe3EMauKS7IexV2mclVqZb+33jM3g9F/RrdOw1UqZXZuEqTffXDBxNjqnUEf2dq4tWnt36fXJKRN4G6KFGOBZRI1i6ctp5CR+djVqS2f/+JerIW5vaWFU1ZOoqaAo50ntSDgm1YfjKwc/s0rSHN28maxXlQ7V+d2SJtwhWwd94Z16oPh3plaoS0TXSGTZOcmfLaqlyZFpVKIygs1qxzO/4veqSG8ykqJqck/A0xcjnZvRSsr1Sy2ThuVTgUWmLJUCm0ZKCMjYUvXDmNGLqmdyOX+S8TO5fLBPWtWK2qatfZQVqrgIiAdotPaJDRjK+XaMlBuLj6FxZlWls62Ni2oPzAZpibW9W9lY+WanZesVr+wK0kpt5E2kVcohaY6bVQ6FdjClovU2jLRPbqMqqyURp9ek5WdUFCY8duVg1t2TczMiqt/q45+g8Xi4rMXtufkJT+Mu3Ln/nmkNcB6Cc04fGN8WzCcG5fPlJbKkBaALu/s4D3l4qLdUbO+3PdBQtKtaZO3uLn41r+Vl0f3EYELH8bFbN/7wdXrx8aOXIr+556bHFG+1NZF1xNXdH278M6l4uQnKntPS0Q/nj/K8w80dfc1RjpE10OVnh1MqhS6HnA3BKqfXEVqHauLdP8AuJk1x9KWVfxcZOlsWmeBMlHB5p0T6swy4hnLKsV1ZtnZtJw/Kwo1HcvXDXhdllqlZLLquG4uTm0+/GDX67bKSyr27qKHmfF6mNEhk6oOr0737utWZy6MMZWJ8uvMUigqX+rLamCxOGamNqjpKC7Jfl2WXFHJresw2Gzu64J26B09u501a31LpHP0M2XnbkxJRqrawskc0YPCZ0Ude/Fb+enhiQf9TLrrPMCCXSUX5en65qheKEorsXdh6UVdpMdZlcNnOpTnlZUX6vr+qI4pTCs14il7jdDDdDsKPT/Z8PXadHNnczN7XceWugHUNRaqhrxni/SH/p9N+ikqV67iWLpi5Y9VSnVRerG9E6v3KGukVwzi6cL7V0pv/FRo39rSytUMNX/yk4uLMkUDxtu27qz/50gN5fFRlbLq6unCvExFFWKZ2ApMrJvZvK0qdZWoQFpeIFUrFK07CnsEGspQnWE9AC4WKVMeSBLvi6Xl0B+uYnPZLC50cVmG+bY2Npslr5C/eABcobJz43t1ErbuaMziGNCLMQz0TXcKubqsUCEVqSRlSoW8Sq02SIE5DDaXAbf/4M/CjsPQ+7PAdUGLVxnSGfIyUswhAmMOERhziMCYQwTGHCIw5vwfAAAA//+6DtzUAAAABklEQVQDAFiqIpwyPw3aAAAAAElFTkSuQmCC",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "cd91131a-b640-4604-9b48-b6cb5207be31",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'generate_topics': {'subjects': ['lions', 'elephants', 'penguins']}}\n",
- "{'generate_joke': {'jokes': [\"Why don't lions like fast food? Because they can't catch it!\"]}}\n",
- "{'generate_joke': {'jokes': [\"Why don't elephants use computers? They're afraid of the mouse!\"]}}\n",
- "{'generate_joke': {'jokes': ['Why don’t penguins like talking to strangers at parties? Because they find it hard to break the ice.']}}\n",
- "{'best_joke': {'best_selected_joke': 'penguins'}}\n"
- ]
- }
- ],
- "source": [
- "# Call the graph: here we call it to generate a list of jokes\n",
- "for step in graph.stream({\"topic\": \"animals\"}):\n",
- " print(step)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "4c505843-5449-4e9b-8ad4-27b88a987cc4",
- "metadata": {},
- "source": [
- "## Create and control loops\n",
- "\n",
- "When creating a graph with a loop, we require a mechanism for terminating execution. This is most commonly done by adding a [conditional edge](../../concepts/low_level/#conditional-edges) that routes to the [END](../../concepts/low_level/#end-node) node once we reach some termination condition.\n",
- "\n",
- "You can also set the graph recursion limit when invoking or streaming the graph. The recursion limit sets the number of [supersteps](../../concepts/low_level/#graphs) that the graph is allowed to execute before it raises an error. Read more about the concept of recursion limits [here](../../concepts/low_level/#recursion-limit). \n",
- "\n",
- "Let's consider a simple graph with a loop to better understand how these mechanisms work.\n",
- "\n",
- "!!! tip\n",
- "\n",
- " To return the last value of your state instead of receiving a recursion limit error, see the [next section](#impose-a-recursion-limit).\n",
- "\n",
- "When creating a loop, you can include a conditional edge that specifies a termination condition:\n",
- "```python\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(a)\n",
- "builder.add_node(b)\n",
- "\n",
- "def route(state: State) -> Literal[\"b\", END]:\n",
- " if termination_condition(state):\n",
- " return END\n",
- " else:\n",
- " return \"b\"\n",
- "\n",
- "builder.add_edge(START, \"a\")\n",
- "builder.add_conditional_edges(\"a\", route)\n",
- "builder.add_edge(\"b\", \"a\")\n",
- "graph = builder.compile()\n",
- "```\n",
- "\n",
- "To control the recursion limit, specify `\"recursion_limit\"` in the config. This will raise a `GraphRecursionError`, which you can catch and handle:\n",
- "```python\n",
- "from langgraph.errors import GraphRecursionError\n",
- "\n",
- "try:\n",
- " graph.invoke(inputs, {\"recursion_limit\": 3})\n",
- "except GraphRecursionError:\n",
- " print(\"Recursion Error\")\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "2de7cdff-3811-4d19-b93b-7b8dfbbdb4f1",
- "metadata": {},
- "source": [
- "Let's define a graph with a simple loop. Note that we use a conditional edge to implement a termination condition."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "f087c028-b115-42a0-a85d-f53d96223720",
- "metadata": {},
- "outputs": [],
- "source": [
- "import operator\n",
- "from typing import Annotated, Literal\n",
- "\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.graph import StateGraph, START, END\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " # The operator.add reducer fn makes this append-only\n",
- " aggregate: Annotated[list, operator.add]\n",
- "\n",
- "\n",
- "def a(state: State):\n",
- " print(f'Node A sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"A\"]}\n",
- "\n",
- "\n",
- "def b(state: State):\n",
- " print(f'Node B sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"B\"]}\n",
- "\n",
- "\n",
- "# Define nodes\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(a)\n",
- "builder.add_node(b)\n",
- "\n",
- "\n",
- "# Define edges\n",
- "def route(state: State) -> Literal[\"b\", END]:\n",
- " if len(state[\"aggregate\"]) < 7:\n",
- " return \"b\"\n",
- " else:\n",
- " return END\n",
- "\n",
- "\n",
- "builder.add_edge(START, \"a\")\n",
- "builder.add_conditional_edges(\"a\", route)\n",
- "builder.add_edge(\"b\", \"a\")\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "c468e5b2-a1dd-4fac-84a9-9eb212a09752",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "255d288a-6e17-4f34-babe-0c6cf1e09a6f",
- "metadata": {},
- "source": [
- "This architecture is similar to a [ReAct agent](../../agents/overview) in which node `\"a\"` is a tool-calling model, and node `\"b\"` represents the tools.\n",
- "\n",
- "In our `route` conditional edge, we specify that we should end after the `\"aggregate\"` list in the state passes a threshold length.\n",
- "\n",
- "Invoking the graph, we see that we alternate between nodes `\"a\"` and `\"b\"` before terminating once we reach the termination condition."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "83c759be-9bb7-4f96-8b79-028fe1ebb45f",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Node A sees []\n",
- "Node B sees ['A']\n",
- "Node A sees ['A', 'B']\n",
- "Node B sees ['A', 'B', 'A']\n",
- "Node A sees ['A', 'B', 'A', 'B']\n",
- "Node B sees ['A', 'B', 'A', 'B', 'A']\n",
- "Node A sees ['A', 'B', 'A', 'B', 'A', 'B']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "{'aggregate': ['A', 'B', 'A', 'B', 'A', 'B', 'A']}"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "graph.invoke({\"aggregate\": []})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8c596264-9a36-4c52-ba7d-9fa5dcb3467d",
- "metadata": {},
- "source": [
- "### Impose a recursion limit\n",
- "\n",
- "In some applications, we may not have a guarantee that we will reach a given termination condition. In these cases, we can set the graph's [recursion limit](../../concepts/low_level/#recursion-limit). This will raise a `GraphRecursionError` after a given number of [supersteps](../../concepts/low_level/#graphs). We can then catch and handle this exception:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "f7526e3c-357c-4eba-b101-751418523672",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Node A sees []\n",
- "Node B sees ['A']\n",
- "Node A sees ['A', 'B']\n",
- "Node B sees ['A', 'B', 'A']\n",
- "Recursion Error\n"
- ]
- }
- ],
- "source": [
- "from langgraph.errors import GraphRecursionError\n",
- "\n",
- "try:\n",
- " graph.invoke({\"aggregate\": []}, {\"recursion_limit\": 4})\n",
- "except GraphRecursionError:\n",
- " print(\"Recursion Error\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "0793b71a-fd92-4284-8d58-cc10f49872f6",
- "metadata": {},
- "source": [
- "Note that this time we terminate after the fourth step. The default recursion limit is 25.\n",
- "\n",
- "Extended example: return state on hitting recursion limit\n",
- "\n",
- "Instead of raising GraphRecursionError, we can introduce a new key to the state that keeps track of the number of steps remaining until reaching the recursion limit. We can then use this key to determine if we should end the run.\n",
- "\n",
- "LangGraph implements a special RemainingSteps annotation. Under the hood, it creates a ManagedValue channel -- a state channel that will exist for the duration of our graph run and no longer.\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "7fe57f1a-ab55-45ed-b229-8f29fc3da05b",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Node A sees []\n",
- "Node B sees ['A']\n",
- "Node A sees ['A', 'B']\n",
- "{'aggregate': ['A', 'B', 'A']}\n"
- ]
- }
- ],
- "source": [
- "import operator\n",
- "from typing import Annotated, Literal\n",
- "\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.graph import StateGraph, START, END\n",
- "\n",
- "# highlight-next-line\n",
- "from langgraph.managed.is_last_step import RemainingSteps\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " # The operator.add reducer fn makes this append-only\n",
- " aggregate: Annotated[list, operator.add]\n",
- " # highlight-next-line\n",
- " remaining_steps: RemainingSteps\n",
- "\n",
- "\n",
- "def a(state: State):\n",
- " print(f'Node A sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"A\"]}\n",
- "\n",
- "\n",
- "def b(state: State):\n",
- " print(f'Node B sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"B\"]}\n",
- "\n",
- "\n",
- "# Define nodes\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(a)\n",
- "builder.add_node(b)\n",
- "\n",
- "\n",
- "# Define edges\n",
- "def route(state: State) -> Literal[\"b\", END]:\n",
- " # highlight-next-line\n",
- " if state[\"remaining_steps\"] <= 2:\n",
- " return END\n",
- " else:\n",
- " return \"b\"\n",
- "\n",
- "\n",
- "builder.add_edge(START, \"a\")\n",
- "builder.add_conditional_edges(\"a\", route)\n",
- "builder.add_edge(\"b\", \"a\")\n",
- "graph = builder.compile()\n",
- "\n",
- "# Test it out\n",
- "result = graph.invoke({\"aggregate\": []}, {\"recursion_limit\": 4})\n",
- "print(result)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6c9e1818-079a-41bb-aed0-2bf993ca943f",
- "metadata": {},
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "308d93f4-6e78-411d-82de-78eac230e44d",
- "metadata": {},
- "source": [
- "Extended example: loops with branches\n",
- "\n",
- "To better understand how the recursion limit works, let's consider a more complex example. Below we implement a loop, but one step fans out into two nodes:\n",
- " "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "258d8613-8572-407a-941a-2ac50b8f1c3e",
- "metadata": {},
- "outputs": [],
- "source": [
- "import operator\n",
- "from typing import Annotated, Literal\n",
- "\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.graph import StateGraph, START, END\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " aggregate: Annotated[list, operator.add]\n",
- "\n",
- "\n",
- "def a(state: State):\n",
- " print(f'Node A sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"A\"]}\n",
- "\n",
- "\n",
- "def b(state: State):\n",
- " print(f'Node B sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"B\"]}\n",
- "\n",
- "\n",
- "def c(state: State):\n",
- " print(f'Node C sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"C\"]}\n",
- "\n",
- "\n",
- "def d(state: State):\n",
- " print(f'Node D sees {state[\"aggregate\"]}')\n",
- " return {\"aggregate\": [\"D\"]}\n",
- "\n",
- "\n",
- "# Define nodes\n",
- "builder = StateGraph(State)\n",
- "builder.add_node(a)\n",
- "builder.add_node(b)\n",
- "builder.add_node(c)\n",
- "builder.add_node(d)\n",
- "\n",
- "\n",
- "# Define edges\n",
- "def route(state: State) -> Literal[\"b\", END]:\n",
- " if len(state[\"aggregate\"]) < 7:\n",
- " return \"b\"\n",
- " else:\n",
- " return END\n",
- "\n",
- "\n",
- "builder.add_edge(START, \"a\")\n",
- "builder.add_conditional_edges(\"a\", route)\n",
- "builder.add_edge(\"b\", \"c\")\n",
- "builder.add_edge(\"b\", \"d\")\n",
- "builder.add_edge([\"c\", \"d\"], \"a\")\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "bdb2a545-3f1f-408b-8aa3-3702d37eedf8",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "\n",
- "display(Image(graph.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a1d4cc42-590c-4de9-9e51-0bb8a79db86f",
- "metadata": {},
- "source": [
- "This graph looks complex, but can be conceptualized as loop of [supersteps](../../concepts/low_level/#graphs):\n",
- "\n",
- "1. Node A\n",
- "2. Node B\n",
- "3. Nodes C and D\n",
- "4. Node A\n",
- "5. ...\n",
- "\n",
- "We have a loop of four supersteps, where nodes C and D are executed concurrently.\n",
- "\n",
- "Invoking the graph as before, we see that we complete two full \"laps\" before hitting the termination condition:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "d5c692d0-9a69-4743-bd47-e462adab8700",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Node A sees []\n",
- "Node B sees ['A']\n",
- "Node D sees ['A', 'B']\n",
- "Node C sees ['A', 'B']\n",
- "Node A sees ['A', 'B', 'C', 'D']\n",
- "Node B sees ['A', 'B', 'C', 'D', 'A']\n",
- "Node D sees ['A', 'B', 'C', 'D', 'A', 'B']\n",
- "Node C sees ['A', 'B', 'C', 'D', 'A', 'B']\n",
- "Node A sees ['A', 'B', 'C', 'D', 'A', 'B', 'C', 'D']\n"
- ]
- }
- ],
- "source": [
- "result = graph.invoke({\"aggregate\": []})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "42cb9253-93a9-4a33-b4fb-a235aa41d655",
- "metadata": {},
- "source": [
- "However, if we set the recursion limit to four, we only complete one lap because each lap is four supersteps:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "d0ff64b3-eb78-48a4-aab5-bb78499f92df",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Node A sees []\n",
- "Node B sees ['A']\n",
- "Node C sees ['A', 'B']\n",
- "Node D sees ['A', 'B']\n",
- "Node A sees ['A', 'B', 'C', 'D']\n",
- "Recursion Error\n"
- ]
- }
- ],
- "source": [
- "from langgraph.errors import GraphRecursionError\n",
- "\n",
- "try:\n",
- " result = graph.invoke({\"aggregate\": []}, {\"recursion_limit\": 4})\n",
- "except GraphRecursionError:\n",
- " print(\"Recursion Error\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "13579366-69fb-4aa4-9d95-a9865c1d5799",
- "metadata": {},
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "5a2d23ae-ea3f-478b-8db6-791cd29cfb6c",
- "metadata": {},
- "source": [
- "## Async\n",
- "\n",
- "Using the [async](https://docs.python.org/3/library/asyncio.html) programming paradigm can produce significant performance improvements when running [IO-bound](https://en.wikipedia.org/wiki/I/O_bound) code concurrently (e.g., making concurrent API requests to a chat model provider).\n",
- "\n",
- "To convert a `sync` implementation of the graph to an `async` implementation, you will need to:\n",
- "\n",
- "1. Update `nodes` use `async def` instead of `def`.\n",
- "2. Update the code inside to use `await` appropriately.\n",
- "3. Invoke the graph with `.ainvoke` or `.astream` as desired.\n",
- "\n",
- "Because many LangChain objects implement the [Runnable Protocol](https://python.langchain.com/docs/expression_language/interface/) which has `async` variants of all the `sync` methods it's typically fairly quick to upgrade a `sync` graph to an `async` graph.\n",
- "\n",
- "See example below. To demonstrate async invocations of underlying LLMs, we will include a chat model:\n",
- "\n",
- "{!snippets/chat_model_tabs.md!}\n",
- "\n",
- "```python\n",
- "from langchain.chat_models import init_chat_model\n",
- "from langgraph.graph import MessagesState, StateGraph\n",
- "\n",
- "\n",
- "# highlight-next-line\n",
- "async def node(state: MessagesState): # (1)!\n",
- " # highlight-next-line\n",
- " new_message = await llm.ainvoke(state[\"messages\"]) # (2)!\n",
- " return {\"messages\": [new_message]}\n",
- "\n",
- "\n",
- "builder = StateGraph(MessagesState).add_node(node).set_entry_point(\"node\")\n",
- "graph = builder.compile()\n",
- "\n",
- "input_message = {\"role\": \"user\", \"content\": \"Hello\"}\n",
- "# highlight-next-line\n",
- "result = await graph.ainvoke({\"messages\": [input_message]}) # (3)!\n",
- "```\n",
- "\n",
- "1. Declare nodes to be async functions.\n",
- "2. Use async invocations when available within the node.\n",
- "3. Use async invocations on the graph object itself.\n",
- "\n",
- "!!! tip \"Async streaming\"\n",
- " See the [streaming guide](../../how-tos/streaming) for examples of streaming with async."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "d33ecddc-6818-41a3-9d0d-b1b1cbcd286d",
- "metadata": {},
- "source": [
- "## Combine control flow and state updates with `Command`"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "7c0a8d03-80b4-47fd-9b17-e26aa9b081f3",
- "metadata": {},
- "source": [
- "It can be useful to combine control flow (edges) and state updates (nodes). For example, you might want to BOTH perform state updates AND decide which node to go to next in the SAME node. LangGraph provides a way to do so by returning a [Command](/langgraph/reference/types/#langgraph.types.Command) object from node functions:\n",
- "\n",
- "```python\n",
- "def my_node(state: State) -> Command[Literal[\"my_other_node\"]]:\n",
- " return Command(\n",
- " # state update\n",
- " update={\"foo\": \"bar\"},\n",
- " # control flow\n",
- " goto=\"my_other_node\"\n",
- " )\n",
- "```\n",
- "\n",
- "We show an end-to-end example below. Let's create a simple graph with 3 nodes: A, B and C. We will first execute node A, and then decide whether to go to Node B or Node C next based on the output of node A."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "4539b81b-09e9-4660-ac55-1b1775e13892",
- "metadata": {},
- "outputs": [],
- "source": [
- "import random\n",
- "from typing_extensions import TypedDict, Literal\n",
- "\n",
- "from langgraph.graph import StateGraph, START\n",
- "from langgraph.types import Command\n",
- "\n",
- "\n",
- "# Define graph state\n",
- "class State(TypedDict):\n",
- " foo: str\n",
- "\n",
- "\n",
- "# Define the nodes\n",
- "\n",
- "\n",
- "def node_a(state: State) -> Command[Literal[\"node_b\", \"node_c\"]]:\n",
- " print(\"Called A\")\n",
- " value = random.choice([\"a\", \"b\"])\n",
- " # this is a replacement for a conditional edge function\n",
- " if value == \"a\":\n",
- " goto = \"node_b\"\n",
- " else:\n",
- " goto = \"node_c\"\n",
- "\n",
- " # note how Command allows you to BOTH update the graph state AND route to the next node\n",
- " return Command(\n",
- " # this is the state update\n",
- " update={\"foo\": value},\n",
- " # this is a replacement for an edge\n",
- " goto=goto,\n",
- " )\n",
- "\n",
- "\n",
- "def node_b(state: State):\n",
- " print(\"Called B\")\n",
- " return {\"foo\": state[\"foo\"] + \"b\"}\n",
- "\n",
- "\n",
- "def node_c(state: State):\n",
- " print(\"Called C\")\n",
- " return {\"foo\": state[\"foo\"] + \"c\"}"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "badc25eb-4876-482e-bb10-d763023cdaad",
- "metadata": {},
- "source": [
- "We can now create the `StateGraph` with the above nodes. Notice that the graph doesn't have [conditional edges](../../concepts/low_level#conditional-edges) for routing! This is because control flow is defined with `Command` inside `node_a`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "d6711650-4380-4551-a007-2805f49ab2d8",
- "metadata": {},
- "outputs": [],
- "source": [
- "builder = StateGraph(State)\n",
- "builder.add_edge(START, \"node_a\")\n",
- "builder.add_node(node_a)\n",
- "builder.add_node(node_b)\n",
- "builder.add_node(node_c)\n",
- "# NOTE: there are no edges between nodes A, B and C!\n",
- "\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "0ab344c5-d634-4d7d-b3b4-edf4fa875311",
- "metadata": {},
- "source": [
- "!!! important\n",
- "\n",
- " You might have noticed that we used `Command` as a return type annotation, e.g. `Command[Literal[\"node_b\", \"node_c\"]]`. This is necessary for the graph rendering and tells LangGraph that `node_a` can navigate to `node_b` and `node_c`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "eeb810e5-8822-4c09-8d53-c55cd0f5d42e",
- "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": "58fb6c32-e6fb-4c94-8182-e351ed52a45d",
- "metadata": {},
- "source": [
- "If we run the graph multiple times, we'd see it take different paths (A -> B or A -> C) based on the random choice in node A."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "d88a5d9b-ee08-4ed4-9c65-6e868210bfac",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Called A\n",
- "Called C\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "{'foo': 'bc'}"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "graph.invoke({\"foo\": \"\"})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "68986cc4-97ec-43a1-b95d-5273d7ffc25a",
- "metadata": {},
- "source": [
- "### Navigate to a node in a parent graph\n",
- "\n",
- "If you are using [subgraphs](../../concepts/subgraphs), you might want to navigate from a node within a subgraph to a different subgraph (i.e. a different node in the parent graph). To do so, you can specify `graph=Command.PARENT` in `Command`:\n",
- "\n",
- "```python\n",
- "def my_node(state: State) -> Command[Literal[\"my_other_node\"]]:\n",
- " return Command(\n",
- " update={\"foo\": \"bar\"},\n",
- " goto=\"other_subgraph\", # where `other_subgraph` is a node in the parent graph\n",
- " graph=Command.PARENT\n",
- " )\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "02ccddf2-978c-41bf-b2eb-2d0c4b3f5d81",
- "metadata": {},
- "source": [
- "Let's demonstrate this using the above example. We'll do so by changing `node_a` in the above example into a single-node graph that we'll add as a subgraph to our parent graph.\n",
- "\n",
- "!!! important \"State updates with `Command.PARENT`\"\n",
- "\n",
- " When you send updates from a subgraph node to a parent graph node for a key that's shared by both parent and subgraph [state schemas](../../concepts/low_level#schema), you **must** define a [reducer](../../concepts/low_level#reducers) for the key you're updating in the parent graph state. See the example below."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "91351541-67af-4c73-9437-426599dcf81e",
- "metadata": {},
- "outputs": [],
- "source": [
- "import operator\n",
- "from typing_extensions import Annotated\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " # NOTE: we define a reducer here\n",
- " # highlight-next-line\n",
- " foo: Annotated[str, operator.add]\n",
- "\n",
- "\n",
- "def node_a(state: State):\n",
- " print(\"Called A\")\n",
- " value = random.choice([\"a\", \"b\"])\n",
- " # this is a replacement for a conditional edge function\n",
- " if value == \"a\":\n",
- " goto = \"node_b\"\n",
- " else:\n",
- " goto = \"node_c\"\n",
- "\n",
- " # note how Command allows you to BOTH update the graph state AND route to the next node\n",
- " return Command(\n",
- " update={\"foo\": value},\n",
- " goto=goto,\n",
- " # this tells LangGraph to navigate to node_b or node_c in the parent graph\n",
- " # NOTE: this will navigate to the closest parent graph relative to the subgraph\n",
- " # highlight-next-line\n",
- " graph=Command.PARENT,\n",
- " )\n",
- "\n",
- "\n",
- "subgraph = StateGraph(State).add_node(node_a).add_edge(START, \"node_a\").compile()\n",
- "\n",
- "\n",
- "def node_b(state: State):\n",
- " print(\"Called B\")\n",
- " # NOTE: since we've defined a reducer, we don't need to manually append\n",
- " # new characters to existing 'foo' value. instead, reducer will append these\n",
- " # automatically (via operator.add)\n",
- " # highlight-next-line\n",
- " return {\"foo\": \"b\"}\n",
- "\n",
- "\n",
- "def node_c(state: State):\n",
- " print(\"Called C\")\n",
- " # highlight-next-line\n",
- " return {\"foo\": \"c\"}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "beb61d02-c868-4c2b-b83f-1dfd280f1c8e",
- "metadata": {},
- "outputs": [],
- "source": [
- "builder = StateGraph(State)\n",
- "builder.add_edge(START, \"subgraph\")\n",
- "builder.add_node(\"subgraph\", subgraph)\n",
- "builder.add_node(node_b)\n",
- "builder.add_node(node_c)\n",
- "\n",
- "graph = builder.compile()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "3f07b704-1fe2-48a3-ad40-c9bc7698cb1c",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Called A\n",
- "Called C\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "{'foo': 'bc'}"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "graph.invoke({\"foo\": \"\"})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bcd31ceb-f96f-4325-878d-ae1dea8cde8a",
- "metadata": {},
- "source": [
- "### Use inside tools\n",
- "\n",
- "A common use case is updating graph state from inside a tool. For example, in a customer support application you might want to look up customer information based on their account number or ID in the beginning of the conversation. To update the graph state from the tool, you can return `Command(update={\"my_custom_key\": \"foo\", \"messages\": [...]})` from the tool:\n",
- "\n",
- "```python\n",
- "@tool\n",
- "def lookup_user_info(tool_call_id: Annotated[str, InjectedToolCallId], config: RunnableConfig):\n",
- " \"\"\"Use this to look up user information to better assist them with their questions.\"\"\"\n",
- " user_info = get_user_info(config.get(\"configurable\", {}).get(\"user_id\"))\n",
- " return Command(\n",
- " update={\n",
- " # update the state keys\n",
- " \"user_info\": user_info,\n",
- " # update the message history\n",
- " \"messages\": [ToolMessage(\"Successfully looked up user information\", tool_call_id=tool_call_id)]\n",
- " }\n",
- " )\n",
- "```\n",
- "\n",
- "!!! important\n",
- " You MUST include `messages` (or any state key used for the message history) in `Command.update` when returning `Command` from a tool and the list of messages in `messages` MUST contain a `ToolMessage`. This is necessary for the resulting message history to be valid (LLM providers require AI messages with tool calls to be followed by the tool result messages).\n",
- "\n",
- "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 the node."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8bcd1a3d-7c50-4f58-be4e-1ed654aa33be",
- "metadata": {},
- "source": [
- "## Visualize your graph\n",
- "\n",
- "Here we demonstrate how to visualize the graphs you create."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e130cf70-a30e-47d7-8fd5-464f1a92e374",
- "metadata": {},
- "source": [
- "You can visualize any arbitrary [Graph](https://langchain-ai.github.io/langgraph/reference/graphs/), including [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs/#langgraph.graph.state.StateGraph). Let's have some fun by drawing fractals :)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "6d604311",
- "metadata": {},
- "outputs": [],
- "source": [
- "import random\n",
- "from typing import Annotated, Literal\n",
- "\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "from langgraph.graph import StateGraph, START, END\n",
- "from langgraph.graph.message import add_messages\n",
- "\n",
- "\n",
- "class State(TypedDict):\n",
- " messages: Annotated[list, add_messages]\n",
- "\n",
- "\n",
- "class MyNode:\n",
- " def __init__(self, name: str):\n",
- " self.name = name\n",
- "\n",
- " def __call__(self, state: State):\n",
- " return {\"messages\": [(\"assistant\", f\"Called node {self.name}\")]}\n",
- "\n",
- "\n",
- "def route(state) -> Literal[\"entry_node\", \"__end__\"]:\n",
- " if len(state[\"messages\"]) > 10:\n",
- " return \"__end__\"\n",
- " return \"entry_node\"\n",
- "\n",
- "\n",
- "def add_fractal_nodes(builder, current_node, level, max_level):\n",
- " if level > max_level:\n",
- " return\n",
- "\n",
- " # Number of nodes to create at this level\n",
- " num_nodes = random.randint(1, 3) # Adjust randomness as needed\n",
- " for i in range(num_nodes):\n",
- " nm = [\"A\", \"B\", \"C\"][i]\n",
- " node_name = f\"node_{current_node}_{nm}\"\n",
- " builder.add_node(node_name, MyNode(node_name))\n",
- " builder.add_edge(current_node, node_name)\n",
- "\n",
- " # Recursively add more nodes\n",
- " r = random.random()\n",
- " if r > 0.2 and level + 1 < max_level:\n",
- " add_fractal_nodes(builder, node_name, level + 1, max_level)\n",
- " elif r > 0.05:\n",
- " builder.add_conditional_edges(node_name, route, node_name)\n",
- " else:\n",
- " # End\n",
- " builder.add_edge(node_name, \"__end__\")\n",
- "\n",
- "\n",
- "def build_fractal_graph(max_level: int):\n",
- " builder = StateGraph(State)\n",
- " entry_point = \"entry_node\"\n",
- " builder.add_node(entry_point, MyNode(entry_point))\n",
- " builder.add_edge(START, entry_point)\n",
- "\n",
- " add_fractal_nodes(builder, entry_point, 1, max_level)\n",
- "\n",
- " # Optional: set a finish point if required\n",
- " builder.add_edge(entry_point, END) # or any specific node\n",
- "\n",
- " return builder.compile()\n",
- "\n",
- "\n",
- "app = build_fractal_graph(3)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "edcd9ad2",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-18T12:18:30.629307Z",
- "start_time": "2024-04-18T12:18:30.609323Z"
- }
- },
- "source": [
- "### Mermaid\n",
- "\n",
- "We can also convert a graph class into Mermaid syntax."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "66007b2d",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-19T11:25:38.733126Z",
- "start_time": "2024-04-19T11:25:38.726838Z"
- }
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "%%{init: {'flowchart': {'curve': 'linear'}}}%%\n",
- "graph TD;\n",
- "\t__start__([
]):::last\n",
- "\t__start__ --> entry_node;\n",
- "\tentry_node --> __end__;\n",
- "\tentry_node --> node_entry_node_A;\n",
- "\tentry_node --> node_entry_node_B;\n",
- "\tnode_entry_node_B --> node_node_entry_node_B_A;\n",
- "\tnode_entry_node_B --> node_node_entry_node_B_B;\n",
- "\tnode_entry_node_B --> node_node_entry_node_B_C;\n",
- "\tnode_entry_node_A -.-> entry_node;\n",
- "\tnode_entry_node_A -.-> __end__;\n",
- "\tnode_node_entry_node_B_A -.-> entry_node;\n",
- "\tnode_node_entry_node_B_A -.-> __end__;\n",
- "\tnode_node_entry_node_B_B -.-> entry_node;\n",
- "\tnode_node_entry_node_B_B -.-> __end__;\n",
- "\tnode_node_entry_node_B_C -.-> entry_node;\n",
- "\tnode_node_entry_node_B_C -.-> __end__;\n",
- "\tclassDef default fill:#f2f0ff,line-height:1.2\n",
- "\tclassDef first fill-opacity:0\n",
- "\tclassDef last fill:#bfb6fc\n",
- "\n"
- ]
- }
- ],
- "source": [
- "print(app.get_graph().draw_mermaid())"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8f77ad75",
- "metadata": {},
- "source": [
- "### PNG\n",
- "\n",
- "If preferred, we could render the Graph into a `.png`. Here we could use three options:\n",
- "\n",
- "- Using Mermaid.ink API (does not require additional packages)\n",
- "- Using Mermaid + Pyppeteer (requires `pip install pyppeteer`)\n",
- "- Using graphviz (which requires `pip install graphviz`)\n",
- "\n",
- "\n",
- "**Using Mermaid.Ink**\n",
- "\n",
- "By default, `draw_mermaid_png()` uses Mermaid.Ink's API to generate the diagram."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "967f116d",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/jpeg": "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IgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiIC17waINTV+xJ/958l3/8Aa/nWwlr3g1v5Jq/fb+s+S7tv879CDYSIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiIC15wZG1TWHUH/3oyXcP/nLYa15wZ28k1ht7UZLw2/tkGw0REBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEUzmdU3GZGbH4alDcs1w3yma1M6KGEkAhm4a4ufykO2AAAI3I3G+O8+6w/0DB+9zfVrqp6NXVF+yPWYWy3RRHn3WH+gYP3ub6tPPusP9Awfvc31a1utecawWW6KI8+6w/0DB+9zfVp591h/oGD97m+rTda841gs+3GHXd3hhwz1BqvH4N+pLGJr+VOxsc/YOlja4dq4P5XbcrOd/cd+Xbx3XmD4G3wvbXGbX+X0tR0LJSq2rd3OXMm7JB7abJHbtZyCFvOS8tbvuO8nw2XpafLasswyQzYzAyxSNLHxvsyua5pGxBBi6grU3wfeA1r4OsOpWafp4id2avutOkntS80MI37KAHs+rWczuvjum615xrBZ6TRRHn3WH+gYP3ub6tPPusP9Awfvc31abrXnGsFluiiPPusP9Awfvc31aefdYf6Bg/e5vq03WvONYLLdFEefdYf6Bg/e5vq1+2ai1VBvJPicXZjb1MVW69sjht+LzxhpPqBIHXqQm615xrBZaIupicpWzeOgvVHl9eZvM0uaWuHgQQeoIIIIPUEELtrkmJpm0oIiKAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIggNPnfNasJ7/Ox6/8A+vAs4sHp/wD6a1Z+lj/w8Kzi+vicY9I+kLPEREXmgi6NzOY/H5HH0LN2CC9kHPZUrSSASTljC9/I3vdytBJ27gu8gIiICIiAi6uVylbCYu5kbsvY06cL7E8vKXckbGlzjsASdgD0A3X4weap6kwuPy+Om8ox9+vHarTcrm9pE9ocx2zgCNwQdiAfWoO6iIqOtwxO+mJ/oyuSAAHcBenVYpLhh/Vix+lsn/x06rVy9J+PX6z9WquMiIi5mRERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEX5kkbExz3uDGNG5c47ABRuZ408P9PTdjktbafp2CdhXlycIlcfUGc3MT9ACC0Ra6dx60vO0nG19Q5vpuHYzTt6aI/8AfdiIh+t4UXmvhb4bHWvJIsDYbcPyYchl8bXkd+aFtl8//wBpBdaf/wCmtWfpY/8ADwrOKF4Salm1hjc5mJ6Xm6W1lHuNbeQ8m0UQHWSON3UAHqwd/TcbE3S+vicY9I+kLPF5d1bPr7ihxk1/hcNYsw0tMGpVqQU9VS4V0RmrNl7d7I6svb8znOA5zygR7cu+5PfxWB1dq7izR0prLVuXp2a2haVu/HprJy1IZr3ldiN07XMDXAkAEgcodsA4ENaBtjW/A3RHEXMsy2ewgs5JsPkzrVe1PWfLDvv2chie3tGdT6L9x1PRZ6lofCY7Uoz9aiIcsMdHiRO2R+wqxvc9kYZvyjZznHfbfrtvsufZm/ajyphq1ji5N8G/I6jzOY85XoMtVsW8fk56UkjoYJAJAYnt5Xu5PSc3YuG4O46LZun9PXdccfuJ1bI6o1FFh8JLifIcXQy09aFj31Gve48jgSCQN278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1J98f3FpEez2Dxe3drfEhLOsXw+WCHT+auOrW2VC2Ku1na83fKwyPaHRt8Xb/mBVEiCctaky7BeFbSeQmdXtMgiMlmqxtqM/KmYRKSGN9Tw158GnvXNrJ6m5rramAov7O1HHXdayZibNAflynlheWub12Zseb1tVEiCdnk1ZIbIhr4aANusEDpJ5Zeer+O54DG8svqaC5vrKS09VymcMy2IrDy9r4j5tlkIpj5UTvv4++n/OD0R+QVRIgnZMHnp+231M6EHINsR+T0YgWVh/1Y8/Nzb+MnR3q2XEmlL0/bCTVWZIfkBdYGCtH2UY/wCqtLYQTF6+bmkP5fgqNEE7LoitY7cT5TNSCW+3IANyc0XI4d0TTG5p7L1x9WnxBXE3D/CWRYE8Fmy2e83JPbPenkAnb8ktDnnkaPyG7M/1VRognpeHel7BtGfT2Ms+U3W5Gbt6jJOe035Mx5gfTHg7vHgsjHp7FRPsPZjKbH2JhYmc2uwGSUd0junV30nqsgiDgADuGy5REBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERBhtaaVqa70dndNZB80VDM0J8dYfXcGytjmjdG4sJBAds47EgjfwK0Fjvgd8KeBWkMnnMHp039QY6tJPUy2WlNieKYDeORoOzGua7YhzWgghellitVYUak0zlcUXBnltWWuHn8UuaQD+ondeuDNNOJTNfC8XWOLzXBC2tBHEwbMjaGNH0AbBftfKrJJJCBMwxWGExzRHvjkaS17T9IcCP1LCag1Rdwl1kFbS+YzbHRh5sY81hG07kcp7WZjt+m/QbdR179v6jVVFMXliVAoHizxJm0HHhqdGFs2Vy9h8MDpa09iOFrGF75HRwNdI/YAANaB1duSACV3PjAym39QNTfm5qH2pY7O4C1xOioXW1MtonOYS15Rj712OvMd3MLXgsjleHMc0kOBLT3bFc+JXNVExhcfSf1427hJt41aobhJ98RWfkY8xQx0FuxRt0qltll/Ju1kzRIxzDuD8sDoeu+yyd/i9mdGs1hU1DUo5HJ4aGnNTOMa+GO2bT3RxRlr3PLCJG7E7kbHfbpsqDIcO8xn8HQqZvUzchcq5mrlRZZj2ws5YZGPELWB/QHlPpFziC4942C+WquD9XV+S1RYuZCWOLN0KlRrIY+V9aSvI+RkrX79TzOadth8nvO65tjpEReme39Mp9e+3/AFxNYIapHHvD/dQ7EPsnTdt0fmlkrWNHlFfma7tCSdunpDbf1BbmWsaeidRac1LDq7L5qfWV2njpMdHQx2NhqySNklicXgumDdxybncgEd222xzrdfZRx2OgdSt6E7l1D1d3/Ol7YM9XeK4ntm+f0uLFFKUNbZK7dggk0TqGlHK8MdYsOpdnECflO5bLnbD6AT9Cq3ODWlziAANyT4LrpqirgjRvwg/gza8494dmQ0jSwt9uBlkp9hKeyyMgftYIbI70DGDO7ZhIIJceu422p/7P7hbrnRnArVOGzT8porIzZx7q0NvGtbNBtFBzzM7VpbI14HKDsWgscQSe70NwUwz8ZooWpWlkuUsPv8p/IcGsjP642MP61fL+cdPmmrpWJNPC/wD9/d6TxTmR0peyPnhp1Vmasd9sLYWVhWZ5Bybcxhd2JcTJt6XaF+2/o8iZLRFfLeeG2MpmhFk2wtfHWyc1fsBHtt2DonNdEXbekWkF3j06KjRcCJzJcP8ACZjzyLsFm0zLiEW4pL05jcItuQMZz8sfd15A3mPV26/WR4d6XzDswchp7GZAZnsPOLblRkzbfY7dj2jXAh3JsC3fuI3CoUQY52ncS+e7M7GU3TXTG61Ia7OacsGzC87ekWgADffbwWQAAJ2AG/U/SuUQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREGsOJHDCfJW5M1gmB9143s0C4NFggdHsJ2DX+B3IDum5BG51BcvRYyya2QLsbaHfBeaYX/qDttx9I3C9XL5z1orUZjmiZMw/iyNDh/4FfoOifxfE6PRGHiU7URw7bT917J4vKfneiP8Artf/ABW/xXHnej/ptf8AxW/xXp/7msR81Uvd2fwT7msR81Uvd2fwX0fx3D/xzr/pLQ8wed6P+m1/8Vv8U870f9Nr/wCK3+K9P/c1iPmql7uz+Cfc1iPmql7uz+CfjuH/AI51/wBFoeYPO9H/AE2v/it/innej/ptf/Fb/Fen/uaxHzVS93Z/BPuaxHzVS93Z/BPx3D/xzr/otDy/55omRsbLUUsrzs2KJ3O9x9Qa3cn9QWwtDcLruoLEdzOVJMfiWEObUnHLNa+h7e9jPWDs49xAHfuirj6tEEVq0NcHv7KMN/3LsLj6T/Gq8SmaMGnZv33vP6cLHZHBwAGgADYDuAXKIvzQIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiIP/Z",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "from IPython.display import Image, display\n",
- "from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles\n",
- "\n",
- "display(Image(app.get_graph().draw_mermaid_png()))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "b9e767fc",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-18T12:18:30.873950Z",
- "start_time": "2024-04-18T12:18:30.871750Z"
- }
- },
- "source": [
- "**Using Mermaid + Pyppeteer**"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "d403e1e7",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-19T11:25:44.798703Z",
- "start_time": "2024-04-19T11:25:44.793438Z"
- }
- },
- "outputs": [],
- "source": [
- "%%capture --no-stderr\n",
- "%pip install --quiet pyppeteer\n",
- "%pip install --quiet nest_asyncio"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "058546ee",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-19T11:25:47.412695Z",
- "start_time": "2024-04-19T11:25:45.405158Z"
- }
- },
- "outputs": [
- {
- "data": {
- "image/png": "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AAAAJpWJUwAAwEHt2zUw+nHjDG8hflVPT0++8IW/O2C9tbUt5557YXbs2J5HH30k3d37kiSXXnplqqurR89bsuS4XHDBpdm1a0ceffSRMde44IJLD7ju3Lnzxxy3t8/JZZe9Kffcc9eY9cbGpixbdnx27hyZCvWrPve5/5WPf/xPDutz/OY37xj9eNGipTn99Feno2NLfvrTH+f6629MfX19Zs5sG817//33jnn+2Wefd0BZ7MQTTzmse5dRY0ttsqk3e5/32gMAAAAAYOL5rgcAAHBQfb1DSZLaegNrx/OLX6wYLUXt9/GP/0kuvfSNo8c9PT25/fYv5J/+6dM5//xfG3PueeddlPPOuygbNz6T97//raPrS5celz/8wz87rAzvfOfNo8WpD3/4Y7nkkjfmmGNmjj6+efOz+Yu/+OMsX/6T0bV77/123vKWd+bUU1912J/r7/7u7+Xqq68fPV6z5qm0t89JkixYsGg07zve8cYxW/197GN/lLa2WYd9n7KrrRt5re1/7QEAAAAAMDkUpwAAgIPq/2V5o6ZWcWo8u3fvOmDt4ovfMOa4oaEhN974m3nTm64bU2iaKMuWHZ+PfeyTOeusc0eLTM83f/7C/NEf/WXe+95rxxSaVq1aedjFqf/0n/4gb3rTm8esHXfciS8vOOPaX1LsV5wCAAAAAJhUvvMBAAAc1P6pN3UmTo1rzpx5B6z94hc/H/fc9vbZqa2tnZQcr3/9VeOWpvZraGjI2972njFr423hN57jjjsxV1xxzcvKx+GrrR/ZytHEKQAAAACAyeU7HwAAwEH19/1yq766SsFJpqalS487YO2P/uijWbHi4QLSjLVz54488cRjeeCB+7J27dNZvHjpmMcPtzh13XW/kerq6smIyDj2b9W3/7UHAAAAAMDksFUfAABwUJXKSGFquOAcU1Vz84zcfPPv5B/+4W9H13bs6MpHP/rbueKKa3L99Tce0S3tHn74gXzxi/+YVatWprt730HP3bz58IpTS5YcOxHROEy/fMll2IsOAAAAAGBSKU4BAAAHtX/S1GC/FscLeetbb8zTT6/K97//nTHrd9/99dx999dz3nkX5eabPzSpBapVq1bm7/7uf2bFip8e9nMGBwcP67x58xa81Fi8BM9NeTMkGgAAAABgMvkqLAAAcFC19bYNO5S6urr83u/9t9x002+N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DgAAAAAAAABA76NVHwAAAIBeUVS0QTfccHnA0FQgL7/8rG644XLV1m7qcu2zzz6km266xi801dGiRR/rgQfu7NbzH6gVK/4dMDTV5txzLzUqZbX57LOPujxvXd1WU2hKkk444bT92+Q+euWVv+ruu//LLzTVUVHRBs2Y8Qs1NDQEXbNu3Wpdd91FAUNTHXm9bt1887WaPfsF+Xy+oOv27Nmjp5/+n4Chqf21bVud7rrr5oChqUA++2yerrrqPK1c+W2P7QEAAAAAAAAAEBpUnAIAAAAQcjt31uvuu/9LXq/bNG+12pWfP1oWS4y8XrfWrPnO9HhFRZmefPJ+3XffUwoLCwt6/u++W2oaH3bYWGVlOVVZ6TJVA5Kk5cu/0YYNa02VnYYOTdRPfrK3fds33ywxrZ8w4WhZLDGmueHDR3RxxXurLrVJSEjU+PFHS5IWL16gww4bq7y8kWppaTZVP1q06GNdd93vZLFYgp63Y9BowoSjZbMld7mfnuD1uk2fw/T0LB1++Hht3bpZ3377lWltY2ODPv74PV144RV+59m82aubb77Wbz4ry6lx446SxWJRQcGPWr16henx11//X2VlOXX88acG3N/99//R7/Mn7f06Gz36CEnSmjXf+bVj7MwTT9znd20xMbEaPfoIJSQMU339DhUUrDWds7GxQffcc5teffWfGjo0oeMpAQAAAAAAAAD9BMEpAAAAACE3a9ZzfqGpGTNu05lnnq9BgwYZc9u21em55x7V4sULjLnvvluqzz6bp9NPP7vL57nggst16aVXa8iQocbcqlXLdffdtxjt5iTp3Xff0J13/qcqUWpquu6662FJ0iWXnG4Kwdx22z1KTBy2D1drNmXKuZox4w9Gy8HrrvudsZeRI8coK8upiooySXsDN//+97900klnBD3f4sWfmMannDJ1v/e2v8aOnajf//5OpaVlGHObNlXrvvtuV1HRBmNu9uwXdN55lyoiwvyj5+uv/6/fOW+88Vadc87FprnS0iLdcceNps/Hyy8/o2OOOcGvheOyZV/7haYSEhJ1992PatSow405n8+n1157Xm+++XKX1/nll4v8znnOORfrqqt+bWr32NzcrHfeeU2zZj1nzDU2NuiFF57ULbfc1eXzAAAAAAAAAAD6Bq36AAAAAITU2rWr9MEHfzfNPfXULJ199kWm0JQkDR2a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379qGHV1dZo7d67mzp0rr9drzFssFk2bNk2XXXYZbfyAQ1Rtba2ee+45I1xVX1+vCy+8ULfffrtp3RNPPKHZs2cbY7vdrvvvv1/jxo3r7S0DPaKpqUlut9sIWG3ZskU///nPTWvWrFmj6dOnm+YuueQS3Xrrraa5++67T++//74kKS4uTna7XY888oiysrJM69avXy+bzSar1RqCKwIAAAAAdIbgFABgwNu9e7epelTbv5WVlWppaQl6XHx8vF/1qJycHKWkpAzYKkjbt283wlEbNmxQQUGBysvL1draGnC9xWLR8OHDTa328vLyTH/JC+DAtLb4tPKLzfp2oVe7mwL/twjg0JNgjdSE45OUP3aIYuIOvMpcc3OzFi1apDlz5uiHH34wPTZp0iRdeumlOu644wbsayBgIPB6vWppaVFysrnl50033aQvv/zSNPf2228rNzfXNDdt2jRZrVZlZ2fL4XAoPz9fP/3pT0O+byBUtmzZIrfbrc2bN6umpkY5OTkaP368aU37tn9tFixYYApI7dixQyeddJIxttvtOvHEE3XbbbeZjnO73WpoaFBKSgo/MwMAAABADyI4BQAYMNraUZSVlamkpMQISVVVVamzb4eJiYnKyckxhaOcTueA/0vQmpoaUxWpgoIC1dTUBF0/ZMgQo3pU283hcCg8PLwXdw0MXL+dcZMifamKDx+ulj2RptZbnfH5fEYQov39uLg45efnh2y/OHBbt2412swkJSUpOzu7j3eEUBocP0hDk6I0NClKw+xRSs8ZHLLnKigo0BtvvKFPP/3UVIUzIyNDF110kc477zwNHhy65wfQvzQ2Npra/pWWlv5/9u48Lup6+x/4i0U2kU1AcB3WGTZFBMR9QyX1uqQVopZL3TYzu9atzG5a3ntb7GplV7uZ4m5qRaWlaLngQkKKMOwgg4DADCAgwoAIvz/88vn5ccByYT4sr+fjMQ+d9+eM94A3kJnXnIN//vOforVkV69exfjx40WP8/DwwO7du0Vnly5dQnJysrD2jytBqSPIz88XVgNqNBrMnTtXdD0rKwvh4eGis7CwMKxevVp09t///hebN28GAFhYWMDR0RFvv/02BgwYIKrLyMiAtbW1TsiRiIiIiIiImsfgFBERdTharVY0OaopJFVQUHDXgJSDg4MoGOXq6go3NzdYWVnpsfu2p76+HtnZ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4OnpKTpLT0/HsmXLUFRUJJw98sgjeO+990R1O3bswLp164Q1gzKZDHPnzoVCodBL70REREQPisEpIhLJz8+HUqlEYmIikpKSWgzrGBsbw8PDA35+fujfvz9X7j2g6upqJCYmCpOklEolysvLdeoMDQ3h6uoqCqe5urrC0NBQgq6JiKi2thZbt27F1q1b0adPH+zevRsGBgZSt0VERG1QSUkJtmzZgu+++w51dXUAbq3RnDdvHmbNmgUzMzOJOyQiIildunQJubm56NKlC4YPHy669uGHH2Lv3r3CfVNTU7z11luYNGmSvtskok4qNTUVly9fRvfu3REYGCi69v7772P//v2is40bN+rUrVixAqampnB0dISjoyNkMhkGDhzY6r0TERER/REGp4g6sbq6OqSkpCAxMRGJiYm4ePEirl692mytg4MD/Pz8hJu3tzdMTEz03HHH0NjYCJVKJYTTEhMTkZOTg+a+HNvZ2cHPzw++vr7Cr3xBhYiobYiOjsbatWuh0WgAAGZmZoiMjOTUKSIiuqvS0lJs374d+/fvh1arBXBreu+cOXPw+OOPo2vXrhJ3SEREbc2ePXsQHR2NtLQ0IXzbXChh/fr16NKlC7y9vdG/f39YW1tL0S4RdTLp6elIT0+HRqOBWq2GRqPB8uXLYW9vL9Rcv34do0aNEj0uMDAQGzduFJ0lJSUhLy8Pffv2hbu7O58LJyIiIr1gcIqoEykpKcHFixeFkFRaWlqz06RMTEygUCiEkJSvry/3kz+AqqoqKJVKISSVlJSEqqoqnTpjY2MoFAohJOXn54eePXtK0DEREf0ZixYtwsWLFwEAU6ZMwZIlS7gqldqcL774AgAwduxYrnQhamMqKiqwfft27N27F9XV1QCAbt26ITw8HHPmzOHacyIialZaWhpSU1MxceJEWFhYiK6NHDlS+J4CAD179sQPP/yg7xaJiHRcvXoVn332GXJycpCTk4Oqqio8+uijWL58uahuzZo12LNnj3DfwcEBq1atQnBwsL5bJiIiok6EwSmiDurmzZvIzMwUTZMqLCxsttbe3h4DBgxA//79MWDAACgUChgbG+u5444jJydHCEglJSXh0qVLzU6TcnJyEk3xUigU6NKliwQdExHR/VCpVFi5ciVeffVV+Pr6St0OkQ6tViuseVm1ahUmT54scUdE1Jyqqirs3LkTu3fvFt5g0bVrV0RERDBARUREf9q1a9ewatUqxMfHC99PPD09sWvXLlFdUlISjh49iqCgIAQGBnKaCxFJoqSkBPX19Tpv2F66dClOnTolOouMjNR53uXRRx+FpaUl+vXrB5lMBrlcrrPmlIiIiOjPYnCKqIPQarVISkpCQkICEhISkJiYiJqaGp06Q0NDeHp6on///kJQytnZWYKOO4ba2loolUrRJK9r167p1JmYmMDLywt+fn7o378//P39OZWEiKidqK6uxpYtW7Bw4UKYm5tL3Q7Rn8bgFFH7cv36dXz99dfYtWsXysvLAdyaQDVv3jyEh4frTBUhIiJqiVKpRHx8PLp06YI5c+aIrm3atEm0GisgIACvvPIKvLy89N0mEZEOrVaLS5cuQaVS4fLly8jJycHy5ctFq0erq6sxcuRI0eOaC4qmp6cjMzMTrq6ucHFx4XM6RERE1CKOlCFqpyoqKnD+/HkhKJWWloabN2/q1HXr1k0UkvL19eU7yR5ASUmJKJyWnp7e7Oe9R48eQkiqf//+nOJFRNROHTp0COvWrUNJSQnMzc2xcOFCqVsiIqIOqmvXrli4cCEiIiKwe/dubN++HZWVlfjvf/+LXbt24cknn8Tjjz/On+eIiOgP+fr6tjgVt6KiQnT//PnzzU5AP3DgAIYNGwZbW9tW6ZGIqDlmZmbw9vaGt7d3izWGhoZ49913oVKpkJOTA5VKBU9PT526Y8eOYdOmTcJ9R0dHfPzxxwyKEhERkQ6+ik/UTuTn5yMhIQEXLlxAQkICcnNzm62TyWSioJSLi4ueO+04GhsbkZ2dLQSlWlp3aGRkBE9PTwwYMAADBgyAv78/HBwcJOiYiIgelpKSErz55pu4cOGCcKZUKiXsiIiIOgszMzMsWLAAjz32GHbv3o2dO3eivLwcn376KXbs2IEFCxZg5syZMDExkbpVIiJqh5YtW4bFixcjNTUVSUlJSE1Nhbu7u6gmMTERK1euBADI5XIEBQVh6tSpcHV1laJlIiIRMzMzTJo06Q/ramtrYW5uLmzmUKvVzW6BGDt2LPr27QuZTCas/RsyZMhD75uIiIjaLq7qI2qDGhoakJGRIQR2EhISUFJSolNnbGwMhUIBf39/+Pv7IyAgAFZWVhJ03DHU1dUJ6w6bVu9VVVXp1HXr1g1+fn5CUIpTvIiIOp66ujrMmDEDxcXFcHV1xeLFi3XGwBMREenDtWvXsGPHDuzevRvV1dUAAAcHByxatAjTp0/nZFsiInroDhw4IASnmrz77rs6QYX8/Hz07t1bn60REd2z4uJiYTJVeHi46FpeXh5mzJghOvP29sa2bdtEZ1lZWVCpVPD19YWTk1Or90xERET6xeAUURtw8+ZNpKSk4PfffxfW7zU9IX47c3Nz+Pn5YeDAgfD390f//v1hamoqQccdw/Xr14UJXufPn0dKSgrq6+t16nr27ClMkhowYADc3NxgYGAgQcdERKRPp06dwtWrV/GXv/xF6laIiIhQUVGBbdu24euvv4ZWqwVw62eVF154ARMnTuTPKERE9FBVV1fj3LlzOHv2LGJjY7F582Z0795duF5fX4/Ro0fDwsICwcHBCA4OxpAhQziFnYjalfz8fGzatAkqlQoqlQpVVVWYNGkS3n33XVHdV199hQ0bNgAAunfvDh8fHzz77LOQy+VStE1EREQPGYNTRBKor6+HUqnE+fPnhaBU0xPft7O1tRWmSQ0cOBByuRxGRkYSdNwxVFRUCOG0CxcuICMjA3d+CTQ0NISnp6cQkho4cCDs7e0l6piIiFpbcXExtm3bhsrKSrz33ntSt0NERPSHysvLsWXLFuzfvx+1tbUAbq1ReumllxASEiJxd0RE1FlcvHgRixYtEp15eXlh+/btEnVERPTgSkpKUF9frzNVasWKFTh06JDoLDIyEr6+vqKz1157TVj55+LiAldXV26rICIiagcYnCLSgxs3biAxMRHnz5/H77//jqSkJOEJ7tvZ29tj0KBBCAgIwKBBgyCTySTotuNQqVRISEhAYmIiLl68iNzcXJ2apqBUYGAgAgMDERAQAAsLCwm6JSIifcrLy8OWLVvw008/CdMGd+zYAYVCIXFnREREf45Go8HGjRvx448/oqGhAQAQEBCAZcuW8Z3vRESkFwkJCTh37hx+++03XLx4EfPnz8fixYtFNd9//z3UajUGDx6M/v37S9QpEdGD0Wq1UKlUyMnJEdb+vffee6KNILm5uZg5c6bocWFhYVi9erW+2yUiIqJ7xOAUUSuor69HcnIy4uLiEB8fj8TERNTV1enU9ejRQwhJBQQEoG/fvhJ023E0Te9KTExEQkICqqqqmq2Ty+UICAhAUFAQAgICYGlpqedOiYhIap988onwTmgTExOE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y5cvV3BwsObNm6e0tDQ5OzurY8eOWrp0qT7++GN17NiRoikHVatWLbVr106StGjRIh05csRwIgBAUTp8+LD+/e9/W4umJCk7O9tgIgAAgBtTp04dSdLvv/9uOAkAAI4lLS1NY8aM0Z49e/Too48qKirKdCQAwF/k10Hmvffe0759+/TCCy+ob9+++v777w0kAwD8GStOlXBZWVkKCwvTwoULlZiYaB3v1KmTRo4cqZo1axpMh+KUmJiohx56SBcvXpSfn5+WLl0qT09P07EAADfphx9+UKNGjfJcGdq3b19JUo8ePdSzZ0/atAIAALs0b948LViwQBUrVlR4eLjpOAAAOJStW7fqpZdeksVikYuLi5599ln169fPdCwAwFXs2bNHy5cv17fffmsdmzdvnlq2bGkwFQCUbq6mAyB/OTk52rhxo+bNm6fjx49bx4OCgjRq1CjVrVvXYDqYULVqVT3//POaPn26YmNjNWnSJM2ePdt0LADADTh16pRWr16tr776SqdPn9bYsWP1z3/+0+aYDz74QFWrVjWUEICjmDdvniSpQ4cOqlevnuE0AEqj3At+LBaL4SQAADieDh06yM/PT88++6wSEhIUHR1tOhIA4BoCAgIUEBCgw4cP64033tDly5cpmgIAw1hxqgT69ttv9cEHH9i0Y2vRooXGjh2rxo0bG0yGkuC1117Tl19+KUnq3r27pk6dajgRAOB67Ny5UyNHjrQZa9Omjd5//31DiQA4KovFoqCgIEnStGnT1K1bN8OJAJRGoaGhmjFjhiQpMjLScBoAABxTamqqlixZkud8AwCg5EtJScnTbeDgwYO69dZb83QpAAAUDVacKkGioqL01ltv6eDBg9axxo0b66mnnlKbNm0MJkNJMmnSJMXFxSkyMlJr166Vt7e3xo4dazoWAKCAWrRoIQ8PD126dEn33nuvevbsqbvvvtt0LAAAgCLx5xbzFotF7u7uBtMAAOCYvLy8KJoCADv116IpSZo4caLOnTunESNG6NFHHzWQCgBKF2fTASBFR0dr5MiRGjJkiLVoqnbt2po5c6aWLl1K0RTyeOedd9SgQQNJ0ieffELLPgAoYY4cOaKFCxeqX79++vXXX232lS1bVq+//rq+/vprzZw5U0FBQXJxcTGUFAAAoGi5ublZb1+8eNFgEgAASpecnByNHz+eFR8BwM78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DvYhqYCAALy9vQ3UitQ8q1evBqBhw4b27UBERKqLzp07a3BKRERqvUaNGjFkyBD76rGZmZlXrNx88OBBioqKKCwsZN++fezbt4/FixdjsVho3749PXr0ICAggMDAwHLbTu/ll19m+/btbNy4kVWrVpXLzxQRkdrp0qVLvPnmmwC88847hISEGC4SEfltGpwSERERkWuy2WwcOXLEPiSVmJhIWlraVec5OTnRuXNn+1OwAQEBuLi4GCgWqflsNht169Zl1KhRODg4mM4RESkTX19foqKiOHLkCIWFhdqmV0REBPDw8KB///70798fAKvVyvfff2//Pfz777/HarXaf0c/cuQIy5YtA6BFixYEBAQQEBBAjx49aN68eZn/+19//TXbt28HYOjQoeX3xkREpFbKycmxf12vXj2DJSIi1093qEREREQE+Peg1O7du+3b712+fPmq81xcXOjatSsBAQF0796drl27UrduXQPFIrXPyy+/TG5uLkVFRaZTRETKzM/PD4CioiL2799P9+7dDReJiIhUPS4uLgQHBxMcHAyU/Lt58OBBEhMT2bNnD0lJSfbf1VNSUkhJSWHNmjUANG7c+IqHmtq1a/er/62MjAxee+01ANq2bcvDDz9cge9MRERqg+zsbPvXbm5uBktERK6fBqdERMrgnnvuITU11X7DX0SkOrPZbBw7doyEhAQSEhJITEwkIyPjqvPc3d3tW+716NEDPz8/6tSpY6BYRABcXV1NJ4iI3JDOnTvj5OREQUEBcXFxGpwSERG5DnXq1MHf3x9/f38eeugh++/ye/bssQ9SpaamAnDhwgU2btzIxo0bAfDy8rIPUQUEBNChQwcsFov9Z1+8eBEPDw8yMzOZNWuWVoMUEZGb9ssVpzQ4JSLVhcVms9lMR1yP0NBQCgoKmDJlCpGRkaZzRERERKql48ePk5CQwO7du9m9ezfp6elXnePt7W1/QrVHjx5X3VgVERERuVGTJk1ix44d+Pv78/HHH5vOERERqRFOnz5tX5EqMTGRM2fOXPO80gejAgMDCQgIoFOnTtSpU4edO3fSq1evSq4WEZGaKDk52T7AO27cOFxcXAwXiYj8Nj0+ICIiIlKDnT9/nri4OOLj49m1axdpaWlXnePl5UVAQABBQUEEBQX95lL+IlL5fv75Zxo2bGg6Q0TkpvXu3ZsdO3awf/9+cnNztYqeiIhIOWjZsiUtW7bk7rvvBiAtLY2EhAT7ilRHjx4FICsri9jYWGJjY4GS1Wy7detGYGAgzs7O+Pv7a9UpERG5KW3atOGxxx4znSEiUia6AhYRERGpQTIyMuxDUrt27SIlJeWqc9zd3QkMDLQPSrVv314rSolUYUlJSUyYMIGIiAiefvppPDw8TCeJiNyw0NBQ+9c7duzgtttuM1gjIiJSM3l7ezN48GAGDx4MlAxMJSQkkJiYyO7du/nxxx8pLi4mNzeXuLg44uLiAHB2dqZr164EBQURGBioQSoRERERqRV0xSsiIiJSjVmtVvbs2cOuXbuIj4/n8OHDV53j7OxM9+7dCQ4OpmfPnnTq1AkHBwcDtSJyIxYvXgzA9u3bmTFjhuEaEZGb06ZNG5o0acL58+f55ptvNDglIiJSCdzd3RkwYAADBgxg+vTpPPDAA3h5eZGUlERCQgL79+8HIC8vj/j4eOLj44GS+wmlK1KVbvEnIiIiIlLTaHBKRKQMVqxYQWpqKn5+foSFhZnOEZFayGazcfjwYfsToUlJSRQWFl5xjoODA35+fvTs2ZOePXvStWtX6tata6hYRG7G3r172bZtGwBjxowxXCMiUj5uv/12lixZwubNm5k+fTrOzs6mk0RERGqFf/7zn0RFRREVFcXcuXN54okngJKHsr7//nuSkpJISkri+++/Jycnh7y8PPuK1gCOjo74+fnRo0cPunfvTo8ePXB3dzf5lkREREREbpoGp0REyuDLL7/k8OHDjBw5UoNTIlJp0tPT2b59Ozt27GDnzp2kpaVddU67du3sg1KBgYG4ubkZKBWR8rZgwQKg5Anx++67z3CNiEj5GDp0KEuWLCE/P5/o6Gjuuusu00kiIiI13sGDB5k7dy4AnTp1YuDAgfbXXFxcCA4OJjg4+Irz9+7dS1JSErt27SIzM5PCwkL27dvHvn377Cvjtm/fnuDgYPr27UuvXr0q902JiEiVM3v2bLZv307v3r2ZPn266RwRkeuiwSkRERGRKmj//v3ExsYSGxvLoUOHrnq9fv369OrViz59+tCnTx+8vb0NVIpIRRs/fjznz59n8ODB1KtXz3SOiEi56NChA23btuXEiROsX79eg1MiIiIVLC0tjSeffBIoeSijdIDq1/j6+uLr68sDDzyAzWbjxx9/JC4ujp07d5KUlER+fj4AR48e5ejRo3z++ee4urrSs2dPevfuTVhYGI0bN67Q9yUiIlXPpUuXuHDhAufOnTOdIiJy3TQ4JSIiIlIFWK1W4uLi+Pbbb4mNjb1qVSmLxULnzp0JCQmhd+/e+Pv74+DgYKhWRCpLSEgIK1euJDs723SKiEi5GjZsGG+//TY7d+7kzJkzNG/e3HSSiIhIjeXt7c348eN58803mTNnDs2aNSvT91ssFjp27EjHjh0ZN24ceXl5JCYmEhcXR3x8PIcPHwYgNzeXmJgYYmJiePXVV7nlllvsK1kFBgZqWz8RkVogMzMTAA8PD8MlIiLXT4NTIiIiIoZcuHCBLVu2EBsbS1xc3FWvu7u7M2DAAEJCQujTpw/169c3UCkiVYG23xSRmmbEiBG899575OXl8Y9//INp06aZThIREanRxo4dS0REBJ6enjf9s5ydnQkJCSEkJASAjIwM9uzZw+7du0lISODo0aMAHDt2jGPHjrF06VIsFgudOnUiODiYoKAgevTogaur6023iIhI1XL58mVAg1MiUr1ocEpEpAymT59OdnY2jRo1Mp0iItVUSkoKmzZtYvPmzdfcgq9t27aEhYXRr18/unbtqlWlREREpEby8PBg+PDhLFu2jFWrVvG///u/urEuIiJSwcpjaOq//dyBAwcycOBAANLT00lISGD37t3Ex8eTnJyMzWbj4MGDHDx4kE8++QSALl262AepunXrhrOzc4X0iYhI5SldcUoPAYtIdWKx2Ww20xHXIzQ0lIKCAqZMmUJkZKTpHBEREZHrdurUKTZu3MjmzZvtT12WcnR0JCAggLCwMAYMGFDm5fJFpOZZv349Xl5e9O7d23SKiEiFOnPmDCNGjMBms/HYY4/x6KOPmk4SERGpMebPn8+4ceOqxPZ4aWlp7Nq1i4SEBBISEkhJSbnqHCcnJ7p160bPnj3p2bMnvr6+1KlTx0CtiIjcDKvVyvnz53F2dqZp06amc0RErosGp0REREQqwJEjR9i8eTObN2/mxIkTV7xWOhDRr18/evfuTb169QxVikhVk5aWxvDhw8nNzWXChAk8/vjjppNERCrU9OnTiYqKol69eqxZswYvLy/TSSIiItXec889x6ZNm2jTpg2LFy+uclt/nz9/nvj4ePv/Lly4cNU57u7uBAYG2gep2rZta6BURERERGoDbdUnIiIiUk4OHTpEdHQ0W7Zs4dSpU1e85uXlxW233cbtt99OYGCgtuATkWt64403yM3NBaBfv36Ga0REKt4TTzzB5s2bycnJ4a233mLGjBmmk0RERKqtvLw8nn32WWJjY4GSB9Kr2tAUQJMmTYiIiCAiIgIoWal7165dxMfHk5CQQEZGBllZWcTExBATEwOAj4+PfYiqV69eNGrUyORbEBEREZEaRINTIiIiIjchLS2NNWvWsG7dOpKTk694zcvLi4EDBxIeHk5QUJCWmBeRX7Vz506ioqIAuPfee/Hz8zNcJCJS8Zo2bcq4ceP44IMPWLduHaNHj6Zz586ms0RERKqlv/71r/ahqTFjxvD0008bLro+rVq1olWrVowaNQqbzcbhw4eJj49n165dJCYmYrVaSU1NZf369axfvx6ANm3a0KtXL0JCQggKCsLV1dXwuxARERGR6kpb9YmIlMHYsWM5fPgwI0eO5PnnnzedIyKGFBYWEhMTw9q1a9m+fTvFxcX217y8vBgwYADh4eEEBwdrWEpErtumTZt4+eWXqVevHsuWLcPd3d10kohIpcjPz2fkyJGcP3+e9u3b8+mnn+oaSkRE5AZkZGQwfvx4+vbty5QpU0znlIvCwkK+//57+4pU+/fvp7Cw8IpzHB0d8ff3JyQkhJCQEHx9fXUtISJiQEZGBhcvXqRx48Z4eHiYzhERuW4anBIRKQMNTonUbsePH2flypVs2LCB9PR0+3FHR0f69etHREQEffr00c05EblhaWlpnDt3TqtNiUits3XrVqZOnQrAM888w/3332+4SEREpHrKzMys0R9W5+bmkpCQwM6dO4mLi7tq9W8Ad3d3goOD7StStWjRwkCpiEjts2nTJp577jkAoqOj8fLyMlwkInJ9tFWfiIiIyK8oLCxky5YtLF26lH379l3xWufOnYmIiODOO+/UyjAiUi68vb3x9vY2nSEiUukGDBhAcHAw8fHxvP322/Tu3ZuWLVuazhIREanSsrKyrrofUZOHpgBcXV0JCwsjLCwMgIsXL7Jjxw527tzJzp07SU9PJysri2+++YZvvvkGgObNmxMaGkpoaCg9e/bUtn4iIhUkLS3N/rWnp6fBEhGRstHglIiIiMg1ZGRksGLFCr744gsuXrxoP96oUSOGDh3KiBEj9GGeiIiISDmaOXMmkZGRZGRk8NRTT7FkyRJcXFxMZ4mIiFRJsbGx/N///R/z58+nS5cupnOMadSoEXfffTd33303NpuNH3/8kbi4OHbu3ElSUhL5+fmcOXOG5cuXs3z5chwdHenatat9kKpjx45YLBbTb0NEpEa4dOkSAD4+Pvq7VUSqFQ1OiYiUga+vL25ubrRu3dp0iohUkOPHj7NkyRKioqLIz8+3Hw8KCuKBBx6gX79+ODg4GCwUkZrkk08+ISwsjLZt21dsP9kAACAASURBVJpOERExrnHjxrz++us8/vjjJCcn88ILLzBnzhzTWSIiIlXOihUrePXVVwF46qmnWLdunYaNAYvFQseOHenYsSPjxo0jLy+P3bt3ExcXx44dOzhx4gSFhYXs2bOHPXv2MH/+fLy8vAgJCSE0NJTevXvToEED029DRKTaKl1xSqupi0h1Y7HZbDbTEdcjNDSUgoICpkyZQmRkpOkcERERqWGOHj3KO++8Q2xsrP2Yi4sLd911F5GRkbRp08ZgnYjURLGxsUyePBmAhQsXEhQUZLhIRKRqeO+99/j73/8OwNNPP82YMWMMF4mIiFQdn332GW+88QYAjo6OzJ49m/DwcMNV1UNqaiqxsbH2FakuX7581TmdOnWiT58+9OnTB39/fz08JyJSBlFRUcTFxeHj48MTTzxhOkdE5LppcEpERERqteTkZBYsWMDmzZvtxzw8PHjggQeIjIykfv36ButEpKY6d+4cY8eOJSMjg44dO/Lpp5+aThIRqTJsNhuPP/44u3fvpk6dOvz973+na9euprNERESqhPnz57No0SIaNmzIG2+8QefOnU0nVUvFxcX88MMP7Nixgx07dvDDDz9QXFx8xTmenp6EhobSp08fevfujaenp6FaEREREalIGpwSERGRWikrK4t3332X5cuX22+MNWzYkDFjxnDffffh6upquFBEaiqr1cr48eM5evQozs7OfPbZZ9oGWETkP6SnpxMZGcnFixfx9PTko48+0t+VIiIi/7Jw4UJGjx5Nw4YNTafUGFlZWezYsYPvvvuO7du327ebKmWxWOjcuTN9+vShb9++dOrUCYvFYqhWRERERMqTBqdERESk1lm7di1vv/02ly5dAqBp06Y89NBDjBw5krp16xquE5GarqCggFmzZrF+/XpmzJhBRESE6SQRkSrp2LFjPPLII2RlZeHj48MHH3xAixYtTGeJiIhIDWez2Th06BDfffcd33333TVXo/L29qZv376EhYUREhKiB/BEREREqjENTomIlMGKFStITU3Fz8+PsLAw0zkiUkZHjhzh1VdfZd++fQC4uLjwyCOP8NBDD+Ho6Gi4TkRqm/j4eIKDg01niIhUaT/88AN/+MMfyMvLo0mTJnz88cc0atTIdJaIiEiliI6OJioqijlz5uDg4GA6p9bKzMy8YjWq9PT0K153dHQkKCiIvn37MmDAAJo2bWqoVERERERuhAanRETKYOzYsRw+fJiRI0fy/PPPm84RkTL49NNPefvttykqKgIgPDycqVOn4uPjY7hMRERERH7N7t27+eMf/0hhYSGtWrXigw8+wNvb23SWiIhIhcnNzeVvf/sby5YtA+DRRx/lscceM1wlULIa1Q8//MC2bdvYtm0bP/7441Xn3HLLLfTv35/+/fvj5+enLf1EpFY4e/Ys8+bNo1GjRowfP15DpCJSrWhpBREREanRcnNzef755/n2228BaNmyJS+++CLdu3c3XCYitUlGRgaenp6mM0REqqXAwEDmzp3L008/zalTp/j973/PwoULadasmek0ERGRcnfo0CGmTp3KuXPnAAgKCuL+++83XCWlLBYL/v7++Pv7M3HiRFJTU9m6dSuxsbHEx8eTl5fHsWPHOHbsGB999BE+Pj6EhYXRv39/evXqhZOTk+m3ICJSIc6cOUNMTAwADzzwgOEaEZGy0dquIiIiUmOdOnWKMWPG2Iemhg4dyrJlyzQ0JSKV6vLlyzz88MM8++yz5OXlmc4REamWwsLCeOGFF4CSG/IPPfQQBw4cMFwlIiJS/ho1akRWVhYAEyZMYOHChXh5eRmukv/Gx8eHUaNG8dZbb7F582b++te/cvfdd9OgQQMAUlNTWblyJZMnT2bgwIFMnTqVdevWkZGRYbhcRKR8Xbhwwf61VpsSkepGK06JiIhIjXT27FnGjRvH5cuXqVOnDk8//bSe0BQRIyZPnszJkyc5efIkQ4cOpX///qaTRESqpWHDhmGxWJg5cybp6ek8+uijzJkzhz59+phOExERKTcNGzZk1qxZODo6EhoaajpHysDFxcW+RZ/NZuP7778nJiaGmJgYkpOTsVqtbN26la1bt2KxWOjevTsDBgxg4MCB/M///I/pfBGRm1I6OFWvXj1cXFwM14iIlI0Gp0REyuCee+4hNTUVPz8/0yki8isyMzOZOHEily9fxmKx8MorrzBo0CDTWSJSyxQVFTFlyhT27t0LwMSJEzU0JSJykyIiIvD09OTPf/4zeXl5TJ48menTpzN8+HDTaSIiIjfku+++u2oIOCwszFCNlBeLxULXrl3p2rUrkyZN4syZM3zzzTfExMSwd+9eiouLSUxMJDExkTfffJNbb72VgQMHMnDgQG699VbT+SIiZXbx4kUAGjdubLhERKTsLDabzWY64nqEhoZSUFDAlClTiIyMNJ0jIiIiVdjEiROJj48H4LnnnuPee+81XCQitdGZM2cYO3YsWVlZREREMGPGDNNJIiI1RlJSEpMnT7ZvZTR+/HieeOIJw1UiIiLX7+jRo8yYMYNDhw4xf/58evXqZTpJKklGRgYxMTFs2bKF2NjYq15v1qwZ4eHhDBo0CH9/fwOFIiI35uzZs+Tk5HDLLbeYThERKRMNTomIiEiNkpSUxIQJEwB49NFHeeyxxwwXiUhtduzYMd58803eeustHB214K+ISHk6evQoEydO5NKlSwCEhITw6quvUr9+fcNlIiIiv+6f//wnc+fOtf85PDyc1157zWCRmJKTk8N3333HN998Q2xsLDk5OVe8XjpENXjwYHx9fQ1VioiIiNRsGpwSERGRGmXKlCnExMTg4eHB119/rUEFERERkRrsp59+4n//939JSUkBSj5cnDdvHh07djRcJiIicm3JycmMGjUKAFdXV5588klGjx5tuEqqitjYWL755huio6PJzs6+4rUmTZowZMgQwsPDNUQlIiIiUo40OCUiIiI1St++fbFarYwdO5annnrKdI6I1DJZWVm4u7ubzhARqVWysrKYPn26fasbJycnZs6cyeDBgw2XiYiIXNubb77Jrl27mDt3Li1atDCdI1VQYWEhO3fuZNOmTWzdutW+PXGpli1bMmTIEIYOHUrLli0NVYqIiIjUDBqcEhEpg9mzZ3Pq1Cn69evHgw8+aDpHRP5DYWEhISEhAEybNs3+BKeISGXYunUrs2fPZuHChbRv3950johIrfPRRx+xYMECSm913X333fz5z3/GxcXFcJmIiNRmGRkZeHp6XnHMarXq3ye5boWFhezYsYOvv/6ab7/99qqVqPz8/Ljzzju544478Pb2NlQpIrVZTk4OKSkpNG7cGC8vL9M5IiJl5mA6QESkOjl48CB79uzh5MmTplNE5Bq0LZ+ImBIbG8vUqVNJT0/XanciIoY8/PDDvPvuu/aV/9asWcP999/PwYMHDZeJiEhtlJOTw5w5c7jrrrs4f/78Fa9paErKwtHRkbCwMGbNmkV0dDTz5s3jjjvuwNXVFYADBw7w17/+lSFDhvDHP/6RdevWkZOTY7haRGqTH374gTFjxhAeHk5ycrLpHBGRMtPglIiIiNQofn5+AMTHxxsuEZHaIj4+nqlTpwLg6urKnDlzDBeJiNRewcHBLF26lG7dugFw5swZfv/737N48WKqyaLrIiJSA0RFRTFixAiWLVuG1WplwYIFppOkhnBycmLAgAG8/PLLREdH88orr9C3b1/q1KlDcXExO3fuZMaMGYSHhzNt2jS2bt1KQUGB6WwRqeHOnDlj/7pp06YGS0REbowGp0RERKRG6dChA1CyZdbFixcN14hIbbBs2TIKCwtxcXHh3XffxdfX13SSiEit1rRpU/7+978zceJE6tSpQ2FhIX/729/4wx/+wNmzZ03niYhIDRcbG8v06dNJS0sDYNSoUfYHLUTKk7OzM4MHD+att97i66+/5tlnn6VLly4A5OfnEx0dzdSpU7njjjt4/fXXOXDggOFiEampfvrpJwAaNGigVRVFpFrS4JSIiIjUKPfccw8ARUVFLFq0yHCNiNQGs2bNonfv3rz77rv2m9QiImKWg4MDjzzyCB9//DHNmjUDIDExkfvvv59Vq1YZrhMRkZqsd+/etG/fniZNmrBo0SKmTZtm30ZWpKJ4enoyevRoFi1axOrVq3n88cdp1aoVAJmZmXzxxRf87ne/Y/To0XzyySf2wT4RkfJQOjhV+ruXiEh1Y7FVk3XKQ0NDKSgoYMqUKURGRprOERERkSrstddeY/ny5QC8/vrrDBo0yHCRiIiIiJiSk5PDG2+8ccXAVGhoKC+++CI+Pj4Gy0REpCZIT0/Hy8vrimOHDh2iRYsWGpgS4/bv38+6devYuHEjly9fth93cHAgJCSEiIgIBgwYQN26dQ1Wikh1t2zZMqKiomjZsiUzZ840nSMiUmYanBIREZEax2q18uCDD5KcnIyjoyMLFy6ke/fuprNEpIbYuXMnvXr1Mp0hIiJltH37dmbOnMnPP/8MgIeHB9OmTWPw4MGGy0REpDpKTk7mtddeIz09nc8//xyLxWI6SeS/KigoICYmhnXr1rF9+3aKi4vtr7m7uzN48GCGDRumVZRFRESkVtLglIiIiNRIycnJPPzww2RmZuLq6sqiRYto37696SwRqcaKioqYOXMm69ev1+8lIiLV1OXLl3nppZf45ptv7Mf69OnDiy++iLe3t8EyERGpLpKTk1m0aBFfffWV/dicOXO47bbbDFaJXL/09HTWrVvHunXrOHr06BWvtWnThuHDhzNs2LCrVlITERERqak0OCUiIiI11pEjR5gwYQLZ2dm4uroyZ84cQkNDTWeJSDWUlZXF1KlTSUhIAMDf35+PP/7YcJWIiNyojRs38tprr9m3rKlfvz5TpkwhIiLCcJmIiFR1f/3rX/n8888BaNCgAZMmTWLYsGFacUqqpUOHDrFu3TqioqJIT0+3H69Tpw5hYWGMGDGC0NBQ6tSpY7BSREREpGJpcEpEpAwOHjxIdnY2jRo1onXr1qZzROQ6HDp0iD/96U/2LVkmT57Mgw8+aLhKRKqbxx9/3D40dfvtt/Pqq68aLhIRkZv1888/M3PmTLZv324/FhgYyEsvvUSTJk0MlomISFWWnp7OsGHDGDFiBI8//jhubm6mk0RuWmFhITExMaxatYq4uDh++dGhj48PERERjBgxghYtWhisFBEREakYGpwSESmDsWPHcvjwYUaOHMnzzz9vOkdErtOlS5d45plnSEpKAuC2227jpZdewsXFxXCZiFQX33//PRMmTOD2229n1qxZeppcRKQGiYqKYu7cuWRkZADg6urKE088wX333ae/70VEarGcnBw++eQThg8fTrNmza54LTMzEw8PD0NlIhXrwoULrF69mtWrV3Pu3LkrXgsICGD48OEMGjRI99VEBIDo6Gg2b95Mq1atmDhxoukcEZEb4mA6QERERKSiNWjQgA8++IDbb78dgC1btjBu3DiSk5MNl4lIddGlSxfef/99Zs+erQ/RRURqmCFDhrB8+XIGDhwIQG5uLnPnzuWRRx7h1KlThutERKSyWa1WPvnkE4YNG8YHH3xwzS26NTQlNVnjxo159NFHWbduHW+//TaDBg2yv7Znzx5efPFF+0NF+/fvN1gqIlVBQkICmzZtYsuWLaZTRERumAanREREpNZ45ZVXGDFiBADHjh3jwQcfZNu2bYarRKQqunz58lXHunXrZqBEREQqQ4MGDZg7dy6vvfYaXl5eAOzbt4/77ruPDz74gMLCQsOFIiJSGVJSUoiIiODtt9+2r0R46NAhw1Ui5vTu3ZvXX3+dzZs38/TTT9OuXTugZNB89erVjB8/nsjISL744guys7MN14qICaUPJ7dq1cpwiYjIjdPglIiIiNQaFouF6dOn8/jjjwMlT5E+9dRTvPvuu4bLRKSqKCoq4rXXXiMyMpL09HTTOSIiUsnCw8NZvnw54eHhABQWFrJw4ULGjh3LwYMHDdeJiEhFa968Oe7u7gC0bduW119/ncWLFxuuEjHP09OTMWPGsGzZMhYtWsTw4cNxdXUF4MiRI7z++uvccccdzJgxg3379hmuFZHKVLpKb8uWLQ2XiIjcuDozZsyYYTrienz44YcUFxfTu3dvunTpYjpHRGoxX19fgoKCaN26tekUEblBAQEBdOnShW3btpGfn09iYiJ79uyhf//+ODs7m84TEUPS09N56qmn2Lx5M1lZWeTl5dGnTx/TWSIiUslcXFwIDw+na9euJCQkkJ2dzaVLl1i9ejXZ2dl0794dR0dH05kiIlIO0tLS7MMfUPLAVbNmzejTpw/PP/+8fXUdEfm3Jk2a0L9/f8aMGcP//M//8PPPP3Px4kUKCwv58ccfWb16NdHR0RQVFdGmTRvq1q1rOllEKkh+fj5vv/02ABEREfj6+houEhG5MRabzWYzHXE9QkNDKSgoYMqUKURGRprOERERkRrg7Nmz/OlPf+L48eMANG3alDfeeIMOHToYLhORynb27FkmTJjA+fPnARg9ejTPPvus4SoRETEtNzeXt99+m+XLl1N6C61p06bMmjWLHj16GK4TEZEbUVRUxMaNG1m8eDHOzs588sknppNEqr3jx4/zxRdfsGHDBrKysuzH69aty6BBgxg5ciQBAQEGC0WkoqSkpPDDDz/g6+ur7fpEpNrS4JSIiIjUalarlZkzZ7Jp0yYAnJycmD59OnfddZfhMhGpTEVFRUycOJF9+/bxl7/8RX8HiIjIFQ4cOMALL7xAcnKy/diIESN46qmncHNzM1gmIiJl8dVXX7FgwQLOnTtnP/bhhx/SrVs3g1UiNYfVaiU6Opovv/zyqi372rRpw4gRIxg2bBienp6GCkVERESupq36REREpFZzdHQkPDwcd3d3du3aRWFhIVu3buXSpUuEhITg4OBgOlFEKoGDgwMDBw5kwIAB2p5PRESu0qhRI+655x4cHBzYu3cvxcXFHDp0iLVr19K2bVs9WS0iUk1ER0ezbds2AHx9fZk7dy5du3Y1XCVSczg6OtKhQweGDx/O4MGDcXBw4NSpU+Tl5ZGenk5cXByfffYZx48fx8PDg+bNm5tOFhEREdGKUyIiIiKlEhMTeeaZZ0hPTwfA39+fefPm4ePjY7hMRMpbRkaGnnAVEZEbcurUKV544QX2799vPxYeHs60adPw8vIyWCYiIr906dIlGjRocMWx9PR0nnzySSZMmEC/fv0MlYnULgUFBfZVqBITE694rUWLFowYMYIRI0boOkpERESM0eCUiEgZrFixgtTUVPz8/AgLCzOdIyIVIDU1lcmTJ3Po0CEAvLy8ePPNN7XipUgNsnfvXqZMmcJjjz3G6NGjTeeIiEg1ZLPZ+OKLL3jnnXfIyckBwNPTk6efflrbvYqIGLZ7927+8Y9/sGvXLjZs2KAHJkSqkNOnT7NixQrWrVtnf3ARSlaq6t+/PyNHjqRXr15YLBaDlSJyvZKTk2nTpo3pDBGRm6at+kREyuDll1/m66+/pl69enoqTaSGqlevHsOGDSM9PZ2DBw9itVr56quvcHd3x9/f33SeiNykBQsWMGPGDKxWK3v37uW+++7DycnJdJaIiFQzFouFzp07M3ToUI4dO8aZM2fIy8tj69at7N69m549e+Lu7m46U0SkVomPj+fZZ5/l448/5tSpUxQVFeHh4UH37t1Np4nIv3h6ehISEsKYMWNo164dmZmZ/PTTTxQXF3PixAnWr1/PV199RU5ODm3atMHV1dV0soj8ivDwcBYvXkyLFi1o37696RwRkRvmYDpAREREpKpxcnLiueeeY+bMmTg5OVFYWMi8efN47rnnyM/PN50nIjfowQcf5MMPPwTg1ltv5dNPP6VevXqGq0REpDpr0qQJ8+fP55VXXrFvB7V7925GjRrFP//5T6rJQu8iIjXCxYsX7atHu7m58dBDD2kVQJEqytHRkcGDB7NgwQLWrl3LuHHj8Pb2BuCnn35iwYIF3HnnnUyZMoXY2FiKi4sNF4vIfzpx4gQAeXl5uLm5Ga4REbk5GpwSERER+S/uuusuFi9eTOPGjQHYtGkT48aN4+zZs4bLRORGPPDAAwAMHz6cxYsX07x5c8NFIiJSUwwePJgVK1YQEREBQG5uLnPnzuX3v/89p06dMlwnIlLzZGVlXXVs6NChdOrUiaeeeooNGzbwpz/9iUaNGhmoE5GyaNasGZMmTWL9+vW8/vrrhISEYLFYKCoqIiYmhsmTJzNs2DDef/99Lly4YDpXRP7l2LFj9q+12pSIVHcanBIRERH5FR06dOCzzz4jKCgIgCNHjhAZGcmOHTsMl4lIWUVERDB//nz+8pe/ULduXdM5IiJSw3h4eDBjxgwWLlxI06ZNAdi/fz/3338/H330EUVFRYYLRUSqv5SUFObOncudd95JVFTUVa8vWbKEsWPHamVZkWrI0dGRQYMG8c4777B27VoeeeQRfHx8ADh//jzvv/8+ERERTJ48mZiYGF1biRh29OhRAFxcXOy//4iIVFcWWzVZMzw0NJSCggKmTJlCZGSk6RwRERGpZYqLi5k/fz6LFy8GwGKx8NhjjzFhwoQy/ZygoCASEhIqIlFEfuGLL77A19cXf39/0ykiIlILWa1W3nvvPT799FP71jK33HILL730Eh07djRcJyJS/Rw/fpx33nmHb7/91n6sW7du9q24RaRmKioqYtu2baxatYrvvvvuim2QfXx8GD58OCNHjtTQhogBGzZsYOXKlTg5OTF//nzTOSIiN0WDUyIiIiJlsGXLFl544QWsVisAffv2Zfbs2bi7u//m95auWuXk5KQVq0QqyE8//cT06dPZt28fLVu2ZOnSpTg7O5vOEhGRWurw4cO88MIL9m0sHBwcePDBB3n88cdvaPVDDeGLSG118uRJ7r33XqBkhb8777yTkSNHamsgkVrkwoULrFq1itWrV3P+/Hn7cYvFQq9evbjnnnvo168fjo6OBitFRESkOqozY8aMGaYjrseHH35IcXExvXv3pkuXLqZzREREpJZq27Ytt912Gzt37iQjI4NTp06xadMmQkND8fLy+q/fFxQUZH8qrri4mIKCAnr27FlZ2SK1wubNm3nyySdJSUkBoEmTJvTr14/69esbLhMRkdrKx8eHe+65B1dXV/bu3UthYSF79+4lKioKf39/mjRpct0/q3QI//3338fb2xs/P7+KyhYRMSouLg53d3dcXFzsx7y8vCgqKuLee+9l1qxZ9OnTB29vb4OVIlLZ3NzcCAwMJDIyks6dO5Obm0tKSgrFxcWkpKSwadMmvvzySzIyMmjZsqXuBYiIiMh104pTIiIiIjcgNzeX5557jtjYWKBk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Wrvh5FwyhnTmRK7hmuvnaDpARKQ6+fTTT00n1Chp5/MBcPN0sm99IyIiIlJVOdRxoElLN84mZ5N2Ps90jlSAtAv//v+1eTs3gyUiIiIiv635LfU5kpRBUYGNrPQC6jfQ/bWa5tK/fu9o0d7dcImIiIjIb7M4WGjaxo3Thy9Xq/unWnFKRESMycoseZrf3VM3dURERKR6qO9V8vxRdmah4RKpCKXXp6BrVBEREan63Dz+/Wx89i+uY6TmyPrX7x31dG0qIiIi1YS7Z+n90+pzfarBKRERMcaaXQSAs2sdwyUiIiIi16duvZJf/HOyigyXSEUovT4FcK6nRbpFRESkaqvn/u9hmpxsXZ/WRNacYgBc6+n+qYiIyP9n787Doqr+P4C/URQGFwbFBdlBFMXEfd9x18wtK5fU0qTUXHL7luWeS2mWmZpL5ZZbpua+b6louIUKoqAoYgiCKIsywO8PfozcubMBs13m/XqenriHO3c+cmfOvefczzmHpKFMudx71HQJ3Z8ycYqIiMwmJyf3/yV4NSIiIiKJKFHSBgCQk51j5kjIGPLuT2Fj1jCIiIiI9GKTr08tWzrPpUhf+ZscNrxBJSIiIon4/9uW7GzzhlEQHD5JRFQAt27dQmpqKipVqgRPT09zh0NERERERERERERERERERESFxDk+iIgKYO7cuQgODsbGjRvNHQoREREREREREREREREREREVAROniIiIiIiIiIiIiIiIiIiIiIjI6jBxioiIiIiIiIiIiIiIiIiIiIiIrA4Tp4iIiIiIiIiIiIiIiIiIiIiIyOrYmjsAIiIp6du3LxISElC7dm1zh0JERERERERERERERERERERFwMQpIqIC6Nevn7lDICIiIiIiIiIiIiIiIiIiIgPgUn1ERERERERERERERERERERERGR1mDhFRERERERERERERERERERERERWh4lTRERERERERERERERERERERERkdWzNHQARkZTMnTsXMTExaNOmDQYPHmzucIiIiIiIiIiIiIiIiIiIiKiQmDhFRFQAt27dQkREBDw9Pc0dChERERERERERERERERERERUBl+ojIiIiIiIiIiIiIiIiIiIiIiKrw8QpIiIiIiIiIiIiIiIiIiIiIiKyOkycIiIiIiIiIiIiIiIiIiIiIiIiq2Nr7gCIiKRk+vTpSE1NRaVKlcwdChERERERERERERERERERERUBE6eIiAqgVq1a5g6BiIiIiIiIiIiIiIiIiIiIDIBL9RERERERERERERERERERERERkdVh4hQREREREREREREREREREREREVkdJk4REREREREREREREREREREREZHVsTV3AEREUjJ37lzExMSgTZs2GDx4sLnDISIiIiIiIiIiIiIiIiIiokJi4hQRUQHcunULERER8PT0NHcoREREREREREREREREREREVARcqo+IiIiIiIiIiIiIiIiIiIiIiKwOE6eIiIiIiIiIiIiIiIiIiIiIiMjqMHGKiIiIiIiIiIiIiIiIiIiIiIisjq25AyAikpJNmzaZOwQiIiIiIiIiIiIiIiIiIiIyAM44RUREREREREREREREREREREREVoeJU0REREREREREREREREREREREZHWYOEVERERERERERERERERERERERFbH1twBEBFJya1bt5CamopKlSrB09PT3OEQERERERERERERERERERFRIXHGKSKiApg7dy6Cg4OxceNGc4dCRERERERERERERERERERERcDEKSIiIiIiIiIiIiIiIiIiIiIisjpMnCIiIiIiIiIiIiIiIiIiIiIiIqvDxCkiIiIiIiIiIiIiIiIiIiIiIrI6tuYOgIhISvr27YuEhATUrl3b3KEQERERERERERERERERERFRETBxioioAPr162fuEIiIiIiIiIiIiIiIiIiIiMgAmDhFRERkZWbOnISUlGQAQMmStpgzZyns7e3NHBXl2bRpDUJDLyi3g4M/Q40atcwYEVHxEBJyFlu3/qrc7tz5TXTt+pYZIyoahUKBly8zkJGRAYUiEwqFAtnZWShZ0hYVK1aCnZ2duUPUKisrC6GhF1Ctmjvc3DzMHQ4RmVlxq6OLG54fIuMpTu3znJwcvHz5Ei9fZiAz8xUyMzOhUGQiOzsbMpkDKlashJIlS5o7TGRlZeHVq1d4+TIDr169hEKhQFaWAjk5OShfXg653MncIRKRmcXHP8aCBdOV297efhg7dqoZIyJVxen6SWRJituzifz3fJmZmcjKykJWlgIymQOcnCrC1tayU2UePXqIhIR4PH2agOzsLDg6OkEurwC53AmOjk4WH7/U8K9JRERkZa5evYT09DTldlaWwozRkKp79+7ixo1ryu3k5KdmjIao+Hjy5LHguxUQEGjG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c4dFRMWYZBKn7OzsAHDGKSIyryVLlpg7BCIiKgZmz+b1hIiIiIgsx8CBH2LgwA/NHQYRERERERo0aIoGDZqaOwwisiIlzB2AvjjjFBERERERERERERERERERERERGQoTp4iIiIiIiIiIiIiIiIiIiIiIyOpIJnEqb6m+9PR0M0dCRERERERERERERERERERERERSZ2vuAPQlk8kAAKmpqWaOhIisWUxMDOLj41GmTBnUqlXL3OEQERERERERERERERERERFRIUkmcapMmTIAgLS0NDNHQkTWbOvWrdi6dSt8fHywbds2c4dDREREREREREREREREREREhSSZpfqYOEVElqB06dIAgMzMTDNHQkREREREREREREREREREREUhmcQpBwcH5c/p6elmjISIrBkTp4iIiIiIiIiIiIiIiIiIiIoHySROlS1bVvlzamqqGSMhImuWlzj16tUrM0dCRERERERERERERERERERERWFr7gD0Vb58eeXPKSkpcHZ2NmM0RGStGjVqhJEjR8Le3t7coRAREREREREREREREREREVERSCZxqkKFCsqfExIS4OPjY8ZoiMhaBQYGIjAw0NxhEBERERERERERERERERERURFJZqm+/DNMPX361IyREBERERERERERERERERERERGR1Ekmcaps2bKwtc2dICshIcHM0RARERERERERERERERERERERkZRJJnEKeD3rVGJiopkjISIiIiIiIiIiIiIiIiIiIiIiKZNk4hSX6iMic4mLi8OCBQvw2Wef4fHjx+YOh4iIiIiIiIiIiIiIiIiIiApJUolTFSpUAMAZp4jIfJ4+fYodO3bg1KlTSE5ONnc4REREREREREREREREREREVEiSSpyqWLEiACZOEZH5lClTRvlzamqqGSMhIiIiIiIiIiIiIiIiIiKiopBk4lRcXJyZIyEia5U/cSotLc2MkRAREREREREREREREREREVFRSCpxqmrVqgCAFy9e4NmzZ2aOhoiskYODg/JnzjhFREREREREREREREREREQkXbbmDqAgPDw8lD8/fPgQjo6OZoyGiP6PvTuPrqo82z9+hYRAJgiQSQYzAgHCaBgUEApRVKJSRKUOVBGLUxUp/gSHNq0T+mrFVl5wZBBb8aWCGgQlzKCAAYIkJDGQQUjICAmZTubfH+hpt6GtIMmTk3w/a53l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xXQMAAAAAAAAAAAAwK6srMx0BABocZxjYmJiTIdoau7u7vLy8tKXX36poqIi2Ww2XX755aZjAWiF7r33Xr3xxhs6c+aMfdodAKD5bdu2TZ9//rlOnDih8PBw03EAAADQhr344ot64403VFJSoqFDh5qOAwAAgDZs6dKlevLJJ1VdXa1hw4aZjgMALUKbmDglSbfeeqvGjBkjSXr//fe1d+9ew4kAtEYDBw6UJO3cuZPpdgBg0LZt2/TWW29p3bp1pqMAAACgjfvqq6+UnJysrKws01EAAADQhhUVFWn16tUqLi7W8ePHTccBgBajzTROSdKf/vQndevWTZL05JNPqri42HAiAK3NxIkTJUlVVVXatGmT4TQAAAAAAMCknJwcnThxQpIUGRlpOA0AAADaqoaGBj355JOqqqqSi4uLHnzwQdORAKDFaFONU506ddILL7wgSSouLtYTTzyhhoYGw6kAtCYDBgxQz549JUlbtmwxnAYAAAAAAJj0w7WBdu3a6corrzScBgAAAG3V4cOHFR8fL0m699575efnZzgRALQcbapxSpKGDRumO++8U5K0b98+rVy50nAiAK3NPffco2eeeUYvv/yy6SgAAAAAAMAgFxcXde7cWcOHD1enTp1MxwEAAEAbNWjQIC1ZskSXX3657r77btNxAKBFcWpogyOXamtr9etf/1qpqalq166d/vKXv2jUqFGmYwEAAAAAAABohQoKCuTr62s6BgAAAAAA+JE22TglSdnZ2br11ltls9nUsWNHLVu2TL179zYdCwAAAAAAAAAAAAAAAEAzaHNb9f2gR48eWrhwoZycnGSz2fTQQw8pLy/PdCwAAAAAAAAAAAAAAC7YkSNHNGvWLJWWlpqOAgAtXpttnJKkMWPGaMGCBZKkoqIiPfjggyorKzOcCkBrkpCQoMWLF5uOAQAAAAAAmtGOHTtMRwAAAEAbFRsbqxkzZighIUFz5841HQcAWrw23TglSVOnTtXMmTMlSZmZmZo7d65qa2sNpwLQGqxfv16zZs3SsmXLlJycbDoOAAAAAABoBtu3b9fcuXN11113KTc313QcAAAAtCEPP/ywYmJiJEne3t767W9/azgRALR8bb5xSpIeeOABRUdHS5IOHDhg/8cEAH6O8ePHq2PHjpKk5cuXG04DAG1LTEyMIiMjddddd5mOAgAAgDaksrJS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XJxqa2u1ceNGbdy4UWFhYZo8ebImT57MFCqglXFxcdH8+fPVv39//elPf1Jtba327NlD4xQAAAAAwCEUFRWpW7dullppaan9eVBQkKKiolRXV9fc0QAAANqU3NxcdejQQV26dLHUY2JiFBcXZ6ldf/31lsapjh076oYbbpC3t7eCg4MVEhKikJCQRr8Hk6UAAC0ZE6dakVOnTmnNmjX66KOPVFhYaK87OTlp5MiRmjx5sn7xi1+oY8eOBlMCuNiOHj2q559/XosWLVKnTp1MxwGAFoGJUwAAAC3P9u3btWnTJu3YsUPXXnutFixYYDn+xRdf6Pjx45o4caKCgoIMpQQAAGjdCgoKtHjxYqWnpysjI0OVlZV69NFHdfvtt1vWvfnmm3rzzTfl6uqq0NBQ9erVS7/61a80cOBAQ8kBAGgaNE61QrW1tfryyy+1fv167dixQzU1NfZjbm5umjhxoqKjo3XZZZfJycnJYFIATc1ms9EsCaBNWrFihXbv3q2QkBDNnz/fdBwAAIA27cyZM7ruuutks9nstUsuuUSffvqpwVQAAACtT0pKig4cOKDMzExlZWUpPT1db731lqUp/fTp07rqqqss75syZYqeeuopS62wsFC1tbUKCAholuwAAJhC41QrV1ZWps8//1yxsbE6fPiw5Zi/v7+uvfZaXX/99QoMDDSUEEBTWbx4sTZs2KCYmBhFRkaajgMAAAAAaOXKy8u1d+9e9e/fv9EXbNOnT9fRo0fl6empyMhIjRgxQrfccouhpAAAAI7JZrPp2LFjOn78uPz9/TV06FDL8ZdfflkffPCBpbZo0SKNGTPGUluwYIF69uyp4OBg+4ObsAEAbRWNU21Idna2Pv30U61fv14nT560HAsLC1NUVJSuvvpqXXrppYYSArhYsrOzdeONN9pfX3PNNZo3b568vb0NpgIAAAAAtDa5ubn65JNP9NVXX9lv2ps/f76mTZtmWbd371517NhRgwcPNhETAADAYaSlpal3796W2r59+/SHP/xBBQUF9toNN9yg3//+95Z1H3zwgV5++WV16NBBQUFBCgoK0m233aYBAwY0S3YAABwRjVNtUENDgw4ePKj169crLi5O5eXlluPBwcGaOHGioqKiFBYWZiglgJ/ryy+/1DPPPGP/QWrs2LF69dVXDacCAAAAALQm33zzjWbOnGmpRUVF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AAAAms6HH36ojRs36ptvvrHXhg8fbpmK3bdvX/n5+alPnz6KiIhQREQEW9UAAACdOXNGBQUF6tatW6MtfJ988knt379fhYWF9lp8fLxlTUVFhdasWWOp5eXlNfp9RowYoW7dutkbovz8/NShQ4dG637c6A0AANBW0EUCh+Ph4WG5q6G6ulpJSUk6ePCgDhw4oG+++UYVFRUqKyvT7t27tXv3bkmSq6urwsPDNXDgQPvD39/f5KkArYKvr68eeughPfTQQ8rNzW10fNu2bZo3b56uuuoq3XjjjRo1apSBlAAAAABw/mw2m44dO6asrCz17NlTgwYNshzPzMy0NE1J0rfffmtpnJKkzz77rMmzAgCAliMnJ0dVVVUKDg621P/xj39o5cqVKigosE/JjomJUXR0tGVdUVGRpWlKOrudno+Pj/21n5+frrzySsu2eT+eSiVJd91118U6LQAAgFaJxik4PFdXV/tUqZkzZ6q+vl7ffvutfWu/hIQEnTp1StXV1frmm28sFzR9fHw0aNAgeyNVv379znmnBYCfJiAgoFHtk08+kSRt2rRJmzZtkp+fn55//nkNGTKkueMBaEOCg4M1bNgwhYSEmI4CAAAc0K5du/Tss89avrCcMmVKo8apyy+/XBUVFQoKClJISIgCAwPPua0NAABwbGVlZSovL1dFRYXKy8sVGBjYaML+jBkzlJOTo+LiYknSwIEDtWzZMssam82m7OxsS62oqKjR7zd8+HD5+fnJz8/PPiXK09PTsqZz587685//fDFODwAAoE1zamhoaDAdAmhq6enpSkpKUlJSkhISEnT06NF/uzY8PFzh4eHq37+/+vfvf847NAD8dMePH9fatWsVGxurU6dOSZI2bNggX19fw8kAAAAAtEU2m03p6enKyMhQRkaGsrKy9D//8z+WNd98841mzpxpqU2aNEnPPfdcc0YFAABNrKSkRAUFBSosLFReXp68vLw0YcIEy5q33npLb7zxhqX26quvauzYsZbaddddp/z8fPvrgIAAxcbGWtbs2bNHa9eula+vr/0xcOBA9erV6yKfGQAAAH4qGqfQJtlsNiUmJioxMVGHDx/W4cOH7Q0dP+bq6qq+fftqwIAB9maqwMBAOTk5NXNqwPFt3bpVqampuu+++yz13Nxcvffee5o4caKGDRtmKB0AAACAtuDpp5/Whg0b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",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "import nest_asyncio\n",
- "\n",
- "nest_asyncio.apply() # Required for Jupyter Notebook to run async functions\n",
- "\n",
- "display(\n",
- " Image(\n",
- " app.get_graph().draw_mermaid_png(\n",
- " curve_style=CurveStyle.LINEAR,\n",
- " node_colors=NodeStyles(first=\"#ffdfba\", last=\"#baffc9\", default=\"#fad7de\"),\n",
- " wrap_label_n_words=9,\n",
- " output_file_path=None,\n",
- " draw_method=MermaidDrawMethod.PYPPETEER,\n",
- " background_color=\"white\",\n",
- " padding=10,\n",
- " )\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "d821b2f6",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-18T12:18:30.629629Z",
- "start_time": "2024-04-18T12:18:30.620092Z"
- }
- },
- "source": [
- "**Using Graphviz**"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "d4234400-75cd-4b13-aeff-828f7fb68ab1",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-19T11:25:42.057704Z",
- "start_time": "2024-04-19T11:25:42.019017Z"
- }
- },
- "outputs": [],
- "source": [
- "%%capture --no-stderr\n",
- "%pip install pygraphviz"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "ee026342-f560-4ce0-ab43-1718bd19a366",
- "metadata": {
- "ExecuteTime": {
- "end_time": "2024-04-19T11:25:42.631675Z",
- "start_time": "2024-04-19T11:25:42.452377Z"
- }
- },
- "outputs": [
- {
- "data": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAABqIAAAKACAYAAAD3vGlMAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOzdeXSU5eH28WuSmew7IQGSkA0IISBiQGQRUERFUKoWwQqotFoUKhXbuqCtrbVqq1aLWF+XqlVcwKW/itQFURDCIiEIgSRAEkIWEggZsi8zmXn/GEmIiAIyebJ8P+fMmWdmnuV6hqNwcuW+b5PT6XQKAAAAAAAAAAAAOLusHkYnAAAAAAAAAAAAQNdEEQUAAAAAAAAAAAC3oIgCAAAAAAAAAACAW5iNDgAAAL5ffX29amtrVVVVperqatntdtXV1amxsbFlH7vdrurq6jbH+fr6ysfHp+W1p6engoKCJEkhISHy9/eXv7+/AgMD2+dGAAAAAAAA0O1QRAEA0I6qq6t14MABFRcX6/DhwyovL295lJWV6dDhcpWXH1Ztba1qqmtUVVUph8Ph9lyBgUHy8/dTQECAwsPD1bNnT/UMD1d4eLgiIyMVftx2TEyMIiMj3Z4JAAAAAAAAnZ/J6XQ6jQ4BAEBXUV9frz179ignJ0d5eXkqLCxUwYED2r9/v4oKi1RZebRlX7PZouCwMAWFhikwNExBPcIVGOJ67ePvL1//APkFBMnb11fevr7yCwySr5+/PM1mmS1e8vbzazmXSSb5fzPa6ZiGulrZ7faW13Zbkxrr6uR0OlVbXaXGujo1NtSrvrZGddXVamyoV0NdraqtFaqyVqjGWqGqiiOqPFKuSusRNTY0tJzL28dHMTEx6hsTo9jYWPXt21dxcXFKSkpSUlKSwsLC3PgtAwAAAAAAoJOwUkQBAHAGqqqqtH37du3cuVPZ2dnKydmj7JxsFRUWyul0ytNsVs/efRTeq4969Il2PX/zOiI6RqE9IxUQHGL0bZyWxvo6WQ8fUvnBYpUfLNbh4iKVl5boSGmJKkoPqrSwoKWsCusRrqSkJA1KHqgBAwYoJSVFw4YNU58+fQy+CwAAAAAAALQjiigAAH7IkSNHlJ6erm3btikjI0Pp27YpLzdXTqdTQSGh6hOf+M2jn/rEJSgqPlG9YuNltliMjt6unE6nyg8WqyQ/VyX781Sct08l+bk6uD9Ph0qKJEk9IyJ03rDzlJp6noYNG6bU1FTFx8cbnBwAAAAAAABuQhEFAMC3lZSUaMOGDVq/fr3WrV+vHdu3y+FwqEdEpOJTzlFMvwGKThygxMHnKDpxgEwmk9GRO7y6mmoV5GQpb9cO5e7aoZLcvdqfkyWbrUkRkb10/ojhGjt2rMaMGaORI0fK0s1KPAAAAAAAgC6KIgoAgIqKCn3yySdatWqVPluzRiXFxbJYvNRvyFAlnTdCycNHasA55ykorIfRUbuUxoZ65e3aqez0LcretkXZ275STVWlgoKCNXbsWE2efLkmT56sxMREo6MCAAAAAADgzFBEAQC6p4yMDP3vf//Thx+u0ubNmySTSYNSz9eQURcqOXWk+g05V14+PkbH7FacDocO7M3R7q2btGtLmnZsWKfammr1HzBAU6dM0eTJkzV+/Hh5eXkZHRUAAAAAAACnhiIKANB9ZGVl6e2339Ybb76pvXv2KCSshwadP1qpEy7RiIsvk39QkNERcRxHc7Pys3dp6+efKuOL1dq3a4eCgoJ11VVXavr06Zo8ebLMZrPRMQEAAAAAAHByFFEAgK7t0KFDevXVV/X6smXa8fXXCu/VW6Muv1JjrpimfkPOZX2nTuRQcaE2fvSB1q/8j/KyMtW7Tx/NnDFDc+fO1eDBg42OBwAAAAAAgBNRRAEAuqYtW7ZoyTPPaPny5fLx9dMFl07R2Kk/0aDhF8jk4WF0PPxIxXn79OWH/9GGle+rpCBf48eP169+9StNmzaNUVIAAAAAAAAdB0UUAKDrcDgceuedd/T440/oq6+2KGHQYF3+s5t14dSrWe+pi3I6ndqRtk7/W/ay0r9Yrd59+uhXCxZo/vz5CggIMDoeAAAAAABAd0cRBQDoGlauXKnF99+vzJ07dcGlU3TF7J8rOfV8o2OhHZUVFujjN/+t1ctfl5+vrxYvvk/z5s2Tt7e30dEAAAAAAAC6K4ooAEDntmnTJi1adJc2bdqokZdcrhl3/FZ9+w80OhYMVGWt0H9eWKqP3nhZ4eHhevjPf9acOXNYDwwAAAAAAKD9UUQBADqn+vp6PfDAA3rqqac0+PzR+tmie9VvyLlGx0IHUnGoTO/+8yl9svx1Tbx4ol544XnFxsYaHQsAAAAAAKA7oYgCAHQ+aWlpmnPjTSo7dEg33v0HXXTNDEa74KT2fr1Nzy5epIrSg/rb3/6qefPmGR0JAAAAAACgu7B6GJ0AAIDT8eqrr2rCRRcpNDpWf//gc1187UxKKHyv/kPP01/f+0SX3XCz5i9YoFtvvVV2u93oWAAAAAAAAN0CRRQAoFNwOp168MEHdfPNN+vSGbN1z7OvKCyyl9Gx2l1ddZVeefRBbf3i0y5xnfZi8fLSz+68R4v/32t64823dPnlk1VZWWl0LAAAAAAAgC6PIgoA0Cncddddevgvf9FtDz2uuYsfksmj+/0VtvurTZp/2Rh98Mrzara5b0RPe13HCOeOnaAH//2Otmdm6rLLLlddXZ3RkQAAAAAAALq07vdTPABAp/Pcc8/p6aef1q8e/Ycm/vR6o+MYJj8rU1UVRyTJrdMRttd1jJIwaIgefPUd5ezdq9lz5hgdBwAAAAAAoEszGx0AAIDvk5OTozsXLdK1t/1aY6dMMzqOW9TXVCvto5UqKyxQfW2NgnuEK2nYcA0eOaalCNq5ab327shoOSZz8wbV1VRp+EWXKiA4RJLU3GzX1jWfKj97l6qtFfLx81N0Yn+NvGSy/AKDWo7dtSVNh0uK5OMfoBEXTdKa995W+cESnTtmvOx22w9epyvoE5egRU8/rwdvuk4vvviifvGLXxgdCQAAAAAAoEsyOZ1Op9EhAAA4malTr1RWXr4efed/8vTser8/sfurTXpswVzVVB494bMxV1ylRU8+J0l65LYbtfXzE9drevz9TxWfnCJHc7Pu+9k07f162wn79I6N1/0vLFOvvnGSpL/+6ufa/On/FBHdV4NHjtaad9+SJMX0S1JkTN/vvU5X88pjf1Taf99Vbu4+BQcHGx0HAAAAAACgq7EyNR8AoMPKysrSqlUfaubCu7tkCSVJT/9ugWoqjyoyJlbXzluom+/9owaPHCNJ2rDqv1r333clSZHRfRUWEdlyXERUjOIGDpK3j48k6YNXn28poc4bP1FTb7xFiSnnSJIOFuTrzaf/esK1DxcXas27b8nb10+enmaNu+qaH7xOVzP9tjtV39igV1991egoAAAAAAAAXVLX/KkeAKBLWL58ucJ79dZ54y42OopbHC0/pPKDJZKkQcMv0HXzF8lsseiy62/U8meeUO+4BCUMGiJJmrv4IUXGxOpff/m9JOnme/+o8y+5vOVcfgFBuvjamfL189fcxQ9Jkhrr63TzqCFqbKjXwf15J1zf6XQq5fzReuCFZaqvq5WHp6cCgoK/9zpdjX9QkEZdNlVvvvW27rjjDqPjAAAAAAAAdDkUUQCADmvTps1KHn6BTB5dcwBvcI+eCggOUU3lUX3+/tva8tn/lDJilM4ZPU6TZsxSRFTMKZ9r0nU3aNJ1N0iSjh45rD3bt2nXlrSWz+vrar/zuJ/84nZZvL1l8fb+cTfTiQ0eOUbP3v+e7Ha7zGb+aQQAAAAAAHA28dMWAECHdbD0oBLOH2t0DLcxmUya//CTenzhrWputqu2qkpbPvtYWz77WC8+tFhDx4zXrX94pGVtp+/T3GzXf15Yqk2frFJ+Vqa+vQSkyWT6zuP6xCWcjVvp1MJ7R8nW1KQjR44oMjLyhw8AAAAAAADAKeuav2IOAOgSvLy81GyzGx3Drc6/5HI9t2aLrltwl/qfM0wenp4tn329Ya0emz/3lM7z+MJb9cZTjylv904lDx+pm+55UE/8Z3VLiXWyUWU+fn4/+h46O1tToyTJuxuPCgMAAAAAAHAXRkQBADqs+Ph45eXvMzqG2zidTh0pPaiS/FxdfM0MzVhwl+qqq7R9/Rd69a8PqfxgsQ7szdbR8kMKCY+QjhvV5HA6WraPlB7UltUfSZIumHSFfrvkxZbP6qqrJEkmffeIKLPF68Q3T3Kdrqoob59CQ8MUHBxsdBQAAAAAAIAuhxFRAIAO6+KLLtKurzaqvrbG6ChusWX1R/rlRcP1x7kztPS+RWpqaJBfYJBGXHyZQntGSJIs3t4KDAmVJJktlpZjC/dkq/TAftXXVKui7GDL+/W1NS3T8n385quqslZ88371d2bw+I6RUie7Tle17YvVGj9h/EmnLwQAAAAAAMCZo4gCAHRY1113neR0avXyZUZHcYvzJ16mlPNHS5J2blqvOecP1F0/uUSzhg/Q3h0ZkqQrb7xVnmZXMRQVn9hy7FtLHtf8S0drz44MxSYNUliEa22jr9PW6baJI3XbxJF6/o/3ytPTNfi52mqVo7n5lHKd7DpdUcGeLO3Y+KVuvukmo6MAAAAAAAB0SRRRAIAOKzQ0VL9euFDvPve0rIfLjI5z1pk8PLT4+dd05U23ytc/QLamJu3P3i27zaag0DDdePfv9bNf392yf8qIUbpg0hUtr80Wi+pra+Tl46PfLnlRvWPjJUmHS4pUZa3Q7N/crzm/e0CS1NhQr52bN5xSrpNdp6txOhx6+S+/17Bh52nq1KlGxwEAAAAAAOiSTM5j8/cAANAB1dTU6Nxh58k/PFL3v7isZXRQV9Nst+lIWamqrRUKjeil0J4RJ50q7mj5IVVZKxQVn9jm+3A6HDpUXChbU5Oi4hNl+o5p907Hya7TVax49u9697mntTEtTampqUbHAQAAAAAA6IqsFFEAgA4vIyNDF44bp/MvmazbH35SHp6eRkdCJ/f5+29r6X2L9Mwzz+j22283Og4AAAAAAEBXZTUbnQAAgB8ybNgwvfvOO/rJ1VerpqpSdz7xrLx9/drl2iX5uXp84a2ntG9x/j7ZbTbFDkg+pf0X/u0ZxSad2r5G60rfw3vPL9Ebf39U999/PyUUAAAAAACAm1FEAQA6hcsuu0yfr1mjq66apt/PvkZ3P/uqwiIi3X5dm61JpYUFp7Sv3WaTpFPe39bUeMa52ltX+B6a7Ta98Kf7tObdt7RkyRLNnz+/Xa4LAAAAAADQnTE1HwCgU8nLy9PkK6aotKxMN9/3J4276lqjI6ETyNu9U8/ed6cOFR7QW2+9qalTpxodCQAAAAAAoDuw/rhVzAEAaGcJCQnalr5VN86epSX3LNSjt92oirJSo2Ohg7I1NmrZk4/onuumKCayp77+ejslFAAAAAAAQDtiRBQAoNNKS0vTzXN/rgOFBzT5hpv1k1sWKCAo2OhY6ACcDoc2fvKh3nzyEVnLD+kPv/+9fvvb38rDg9/BAQAAAAAAaEdWiigAQKdWX1+vpUuX6tFHH1Ojzaar5s7TlDm/kI+fv9HRYACnw6G0j1Zq+TOPq7SwQD+fO1cPPPCAoqKijI4GAAAAAADQHVFEAQC6hpqaGi1dulR/+csjanY4NPqKaZp64y2KTuxvdDS0g7qaam1Y9X9a9dpLKsrdq2uuvVZ/efhh9e/Pnz8AAAAAAICBKKIAAF3LkSNH9MILL2jps/9USXGRUsdP1GU/u0lDR4+Th6en0fFwlhXsydLHb7yqdR+8Kw+ZdOONc7RgwQIlJycbHQ0AAAAAAAAUUQCArsrhcGjNmjV66qmntGrVKgWGhGrkpCs0ftpPNfC8ETKZTEZHxBkqP1iizZ+u0qaPV2p3+hYlJCbq1ltu0S233KKwsDCj4wEAAAAAAKAVRRQAoOvbu3ev3nzzTS17403tyclW776xGnX5VRp+8aXqP+RcRkp1AgcL8rVt7Wfa+NEHys7YqtCwMM247jpdf/31Gjt2LMUiAAAAAABAx0QRBQDoXjIyMvTGG29o+YoVOlBQoKDQMA0dO17njZuoc8dOUFAoI2o6AltjozK3pClj3RplrFujkoJ8BQUF66qrrtT111+vSZMmyWKxGB0TAAAAAAAA348iCgDQfe3evVurVq3SqlWrtH7DBjXb7UpIHqyk1POV/M0jJDzC6JjdQkNdrfZs36asbVuUvXWz9nydrob6eg055xxdMXmyJk+erDFjxshsNhsdFQAAAAAAAKeOIgoAAEmqrq7WZ599ps8//1zrvvxSO3fsUHNzs6LiEpQ0bIT6n3ueEgYNUeyAZFm8vY2O26k5HQ6V7M9Tflam9u3crpxtW5S7O1PNdrvi4uM17sILNX78eF122WWKiooyOi4AAAAAAADOHEUUAADfpbq6WmlpaVq/fr3WrftS27ZtU01NtTzNZvVN7K/Y5MGKTx6suIGDFJ3Yn5FTJ1FXU62S/FwV5GQpPytT+7MylZ+9Sw11dTJbLBo0aJDGXXihxo4dqwsvvFB9+vQxOjIAAAAAAADOHoooAABOhcPh0L59+5SRkaGMjAxt25ahbRkZOlJ+WJLkHxikqPgE9Y7vp6iEfuoTl6BefeMV3ruPAkNCDU7vXo0N9TpcXKTDJUUqztunkvxcHdyfq+K8fTpyqEyS5OfvryFDzlHqecM0bJjrMXjwYHkzugwAAAAAAKAro4gCAODHKC0tVXZ2tnJycpSTk6OsrGxl52Sr8MABNTc3S5J8fH0VERWjHr16K6xXH4X36qMevfooKKyHgkLDFBgappDwnvILCDT4btpqamhQlfWIKo+Uq/JIuaqsFTpafljlB4tVfrBYFaUlOnywRFXWipZjekZEKHlgsgYOTNKAAQOUnJyspKQkxcXFydPT08C7AQAAAAAAgAEoogAAcIfGxkbl5+ersLBQRUVFKigo0IEDB1RYWKQDhQdUXFSs2tqaNsdYLF4KDgtTUFgP+QYEyNvXTz5+AfINCJCPr5+8fH3lHxgsL29vefn4tB7n5SUvH9/vzNFst6uhrrbN6/raWjXU1aqxoV4NtbWqq6lSY329mhrqVV9drSprhSqtR9RQV9fmXN4+PoqIiFBMTF/Fx8UqJiZG0dHR6tu3r2JjY9W3b1+FhIScxW8RAAAAAAAAnRxFFAAARmloaFB5ebkOHz6ssrIylZeXtzyqqqpUW1ur6upqHT1aqdq6OtXW1qiyslI1NTWy2+wt56mrr1NTY+N3XsPDw0NBQcEtr00mk4JDguXn5yd/f38FBQYqJCSk5XVwcLB69Oihnj17Kjw8XOHh4erZs6ciIiIUGNixRmwBAAAAAACgw6OIAgCgK7nvvvv00Ucfadu2bUZHAQAAAAAAAKweRicAAAAAAAAAAABA10QRBQAAAAAAAAAAALegiAIAAAAAAAAAAIBbUEQBAAAAAAAAAADALSiiAAAAAAAAAAAA4BYUUQAAAAAAAAAAAHALiigAAAAAAAAAAAC4BUUUAAAAAAAAAAAA3IIiCgAAAAAAAAAAAG5BEQUAAAAAAAAAAAC3oIgCAAAAAAAAAACAW1BEAQAAAAAAAAAAwC0oogAAAAAAAAAAAOAWFFEAAAAAAAAAAABwC4ooAAAAAAAAAAAAuAVFFAAAAAAAAAAAANyCIgoAAAAAAAAAAABuQREFAAAAAAAAAAAAt6CIAgAAAAAAAAAAgFtQRAEAAAAAAAAAAMAtKKIAAAAAAAAAAADgFhRRAAAAAAAAAAAAcAuKKAAAAAAAAAAAALgFRRQAAAAAAAAAAADcgiIKAAAAAAAAAAAAbkERBQAAAAAAAAAAALegiAIAAAAAAAAAAIBbUEQBAAAAAAAAAADALSiiAAAAAAAAAAAA4BYUUQAAAAAAAAAAAHALiigAAAAAAAAAAAC4BUUUAAAAAAAAAAAA3IIiCgAAAAAAAAAAAG5BEQUAAAAAAAAAAAC3oIgCAAAAAAAAAACAW1BEAQAAAAAAAAAAwC0oogAAAAAAAAAAAOAWFFEAAAAAAAAAAABwC4ooAAAAAAAAAAAAuAVFFAAAAAAAAAAAANyCIgoAAAAAAAAAAABuQREFAAAAAAAAAAAAt6CIAgAAAAAAAAAAgFtQRAEAAAAAAAAAAMAtKKIAAAAAAAAAAADgFhRRAAAAAAAAAAAAcAuKKAAAAAAAAAAAALgFRRQAAAAAAAAAAADcgiIKAAAAAAAAAAAAbkERBQAAAAAAAAAAALegiAIAAAAAAAAAAIBbUEQBAAAAAAAAAADALSiiAAAAAAAAAAAA4BYUUQAAAAAAAAAAAHALiigAAAAAAAAAAAC4BUUUAAAAAAAAAAAA3IIiCgAAAAAAAAAAAG5BEQUAAAAAAAAAAAC3oIgCAAAAAAAAAACAW1BEAQAAAAAAAAAAwC0oogAAAAAAAAAAAOAWFFEAAAAAAAAAAABwC4ooAAAAAAAAAAAAuAVFFAAAAAAAAAAAANyCIgoAAAAAAAAAAABuQREFAAAAAAAAAAAAt6CIAgAAAAAAAAAAgFtQRAEAAAAAAAAAAMAtKKIAAAAAAAAAAADgFhRRAAAAAAAAAAAAcAuKKAAAAAAAAAAAALgFRRQAAAAAAAAAAADcgiIKAAAAAAAAAAAAbkERBQAAAAAAAAAAALegiAIAAAAAAAAAAIBbUEQBAAAAAAAAAADALSiiAAAAAAAAAAAA4BYUUQAAAAAAAAAAAHALiigAADqpjz/+WCaTqc3jkUceUUZGxgnv33nnnUbHBQAAAAAAQDdkcjqdTqNDAACA02e32xURESGr1fqD+27evFnnn39+O6QCAAAAAAAAWlgZEQUAQCdlNpt1ww03yGKxfO9+MTExGjFiRDulAgAAAAAAAFpRRAEA0Ildf/31stlsJ/3cYrHopptukslkasdUAAAAAAAAgAtT8wEA0Ik5nU717dtXRUVFJ90nMzNTKSkp7ZgKAAAAAAAAkMTUfAAAdG4mk0mzZs066fR8KSkplFAAAAAAAAAwDEUUAACd3Mmm57NYLLrxxhsNSAQAAAAAAAC4MDUfAABdwMCBA5WTk9PmPZPJpLy8PMXFxRkTCgAAAAAAAN0dU/MBANAVzJ49u830fB4eHho5ciQlFAAAAAAAAAxFEQUAQBcwa9Ys2e32ltceHh6aM2eOgYkAAAAAAAAApuYDAKDLGD58uLZt2yan0ylPT0+VlJQoIiLC6FgAAAAAAADovpiaDwCArmLOnDny9PSUp6enJk6cSAkFAAAAAAAAw1FEAQDQRcycOVMOh0PNzc2aPXu20XEAAAAAAAAApuYDAKArufjii5WWlqbDhw8rMDDQ6DgAAAAAAADo3qxmoxMAAICzZ/bs2YqIiKCEAgAAAAAAQIdAEQUAQAdWWVmpxsZG1dTUqLa2Vk1NTS2fffu1JPn6+qp///5avXp1m/dNJpNCQkJOeO3j4yNfX18FBwfLw4MZewEAAAAAAHB2MTUfAABuVFNTo6KiIh0+fFhWq1UVFRWqqKho2XY9H5LVWq7Kyko1NTXp6NEqNTQ0qb6+6YcvcBaZzZ4KDPSVv7+fvL29FBISouDgUIWG9lRYWA+FhYUpLCxMoaGhLds9e/ZUZGSkevbs2a5ZAQAAAAAA0ClYKaIAADhDpaWlys/PV35+vkpKSlRcXKzS0lIVF+errKxUxcVlqq1taHOMv7+nQkM9FRZmUliYQ6GhdoWFORUWJgUFSd7eUnCw5OMj+fq63vPycj37+bk+P8bb2/Xe8SwW16Ouru37NptUU9P6urlZqqqS6uulhgapslJqapKqq6XaWte21ep6v6JCslrNqqjwVEWFVFHRrMpKe5vze3mZFRnZQ9HR0YqI6KPo6L6KjIxUdHS0YmNjFR8fr5iYGJnNDMYGAAAAAADoRiiiAAA4mebmZuXn52v37t3Kzc39pnTKVV5ejvLzC1tGLFksHoqMNCs6WoqMtCs62qHISH3zWoqKkiIipLCwtkVSZ+ZwuAqqQ4ek0lKppMT1XFx87Nmi0lIPFRXZVV/fLMk14iomppcSEvopPr6/4uPjlZCQoIEDB2rgwIHy8fEx+K4AAAAAAABwllFEAQDgcDi0b98+ZWZmKjs7W5mZO5WdvUNZWfvU0OAqm3r39lJ8vBQf3/TNc+sjOlpioM/JlZVJ+fnffpiVn++pwkKbbDaHPD09FB8fpZSUc5WcnKKUlBQlJycrJSWFggoAAAAAAKDzoogCAHQ/JSUlSk9P/+axUWlpG1VRUS1J6t3bopSUZg0a5FBKijRokDR0qBQYaHDoLspulw4ckHbtknbvlnbtMmn3bi9lZdlVV9css9lTAwbEKzV1lFJTU1sevr6+RkcHAAAAAADAD6OIAgB0bbW1tdq4caPWrl2r9eu/0LZt21RVVSeLxUNDhpiVmtqk4cOl1FQpOfnENZdgDLtdys2VMjKkrVul9HSLtm1zqqrKLovFU0OGJGvUqPEaN26cxo8fr8jISKMjAwAAAAAA4EQUUQCArqWmpkbr16/X2rVrtW7dZ/rqq22y2ZqVmOitceOaNGKEU8OHS+ec03XWa+ouHA5p715XMbV1q7R+vUUZGXY1Nzs1cGCcxo+/TOPGjdOECRPUp08fo+MCAAAAAACAIgoA0BXs379fn3zyiT744H19+ulnamy0KSHBojFjbBo7Vrr0UikuzuiUcIfaWmnjRmn9emnDBi99+aVdjY0ODRrUX1deeY2mTp2q0aNHy8PDw+ioAAAAAAAA3RFFFACgc9q8ebPee+89rVz5vnbv3qvgYLMuvdShKVMcuuwyqVcvoxPCCLW10rp10gcfSKtWWVRQYFNkZKimTJmmadOu1uWXXy4vLy+jYwIAAAAAAHQXFFEAgM4jLy9Py5Yt0+uv/0t79uxX//5euvLKJk2ZIl14oWSxGJ0QHc2OHdKHH0orV1q0aZNdISGBmjHjBs2aNUujRo2SyWQyOiIAAAAAAEBXRhEFAOjYGhoatGzZMr388gtKS9uiiAizrr/eplmzpNRUo9OhMykqkt54Q3rtNYsyM21KTIzWrFk/1y9/+XcuxXsAACAASURBVEv17t3b6HgAAAAAAABdEUUUAKBjKisr07PPPqt//vMfqqqq0rXXSrNmOTRpkmQ2G50Ond3XX0uvvSa9/rpFVqtT11//M9155yINHTrU6GgAAAAAAABdCUUUAKBjyc3N1cMP/1lvvLFMQUHSbbfZdPvtUmSk0cnQFTU2SsuWSU89ZdbOnXZdfPGFuu++P2jixIlGRwMAAAAAAOgKrB5GJwAAQJKOHj2q3/zmNxo0aKDS0pZpyRKbDhyw6Y9/pISC+3h7S3PnSl9/bdcnn0hm80ZdcskluvLKK5SVlWV0PAAAAAAAgE6PIgoAYCiHw6FnnnlG/frF6dVX/6G//92uzEybbrlF8vExOh26C5NJmjRJ+vhju1avlgoLV+uccwZr/vzbZbVajY4HAAAAAADQaTE1HwDAMAcPHtTs2dfryy+/1MKFDi1eLAUHG50K7vLFF5LVKlks0tSpRqf5fg6H9Mor0v33W2SxhOuNN1ZozJgxRscCAAAAAADobFgjCgBgjM8++0yzZ8+Ut3el3nzTpgsuMDqRe1RWSn/8o3TxxR2/fHG3ESOkrVulwECpqsroNKemslK65RZPvf++U4sXP6AHHnhAnp6eRscCAAAAAADoLFgjCgDQ/pYsWaJJkyZp4sQK7djRdUuodeuk/v2lv/9dstmMToMzERwsvf12sx5/3KFHH31IM2b8VE1NTUbHAgAAAAAA6DQoogAA7eqZZ57RwoV36NFHnXrtNYcCA41O5D4ZGdLhw65tk8nYLDhzJpO0cKH06acOffrpSs2cOV0Oh8PoWAAAAAAAAJ2C2egAAIDuY/Xq1fr1rxfqL3+Rfvc7o9O0tWOHaw2j/fulgQOlceNcz8fbvFnKzpbMZumGG1z7fvKJlJMjpaRI11wjhYS49l2zRtqypfXYzz93TfN25ZVSWJjrWgUFrmnqrrxSevllqbBQuvRS17R15eWu4376U8nfv/U89fXS8uWu7T59pEmTTu8+T+cejtfc7CrW1q2TysqkwYNd0w1GRZ38Ol98IR09Ko0a5brH73Mq37/RLrxQWrXKrksu+VCLFy/WI488YnQkAAAAAACADo81ogAA7aK6ulopKQM0atRhvf12s9FxWjgc0u9/Lz3yiGv7GLNZeugh6e67W0czzZ8vPfus5OsrLVsmzZol1dW1HhMbK332mZSYKF11lfTBBydeLyNDOvdcV+Hz/vtSfLx00UXSv/7l+jwlxbWW1GOPuV6/8YZ0/fWtx7/7rquckqSHH5buu+/07vd07uGYfftcGYuK2p4rIED661+l225rfc/plH7zG+nJJ9vuO2WK6zw5OW3XiDqd77+jeOkl6Ze/9ND69Rt0QVedVxIAAAAAAODsYI0oAED7WLp0qaqqyrV0accpoSRXAfTww64SpEcP6ZZbpOhoyW6X7r1XWrHixGMaGlxl0ODB0h13SHFxrvcLCloLpPh414ilY+LipKFDXQXQ8fbvd2Xw928dpXTzza2fHxv9dMyxPCaTq0Q6U6dyD5KUn+8a+XSshBo1SrriCsnPT6qpkW6/XXrllbZ5j5VQJpNrJNTo0dKHH7pKqG87k+/faD//uTR+vIcWL77b6CgAAAAAAAAdHkUUAKBdvPDCUt1yi13h4UYnadXUJC1e7NoOCXGVMM8/7ypf+vZ1vf/gg65RPsdzOl0jnjZvlp5+Wvr009bPduxwPT/9dNvpB//+d2n7dikp6cRzTZjgmorv4EFp3jzXPqNGuT7/6KPW0UMNDa5CR5LGj2/NeCZO5R4k6f77XVMGStJTT0lpaa4M6emSl5fr/UWLJKvVtf2nP7Ueu2qV9N//Shs2SC+8cGKGM/3+O4J777VrzZp12rdvn9FRAAAAAAAAOjSKKACA2+3fv195eUW66iqjk7SVmysdOuTanjjRVfQcOeJay+mKK1zvZ2VJpaUnHnv77a3b/fqppWA7cuT0c/zud5KPj+scoaGu946NimpocJU5kquUqqlxbc+Zc/rX+bZTuYfPP3c9e3u7RgIdM3Cga7o+yVVCffWVZLO1jnrq0cO13tUxc+dKwcFtr/9jvn+jTZggBQWZtWbNGqOjAAAAAAAAdGgUUQAAtyv6Zl6349cd6gj27m3dfvddVxFz7PHcc62fFRefeGzPnm1f+/m5npvPYObB/v1PfG/GjNZzHpue7513Wq91bJ2oH+OH7iE/3zVKS3IVLwEBbfefOrV1e9cu18ipY8eOHy95HPevDA8P15R7x/sx37/RzGYpLs5TBw4cMDoKAAAAAABAh2Y2OgAAoOvz+mYON5vN4CDfYrG0bp97rjR8+Hfv5+Nz4nve3m1fe/yIX+34dsEjSUFB0rXXSq+9Jn38sWvk0AcfuD77yU+kwMAzv94xP3QPvXq5viOb7bvLoGPrRkmukVxBQa2vv/1nbbdL3+5sfsz33xE0Nkre3/4SAQAAAAAA0AZFFADA7RITE+XhYdLXXzsVG2t0mlYJCa3bgYFt1zHatctVEPXtK5lMJx77Xe993z4Ox8n3O7bW0rfdfLOriGpqkubPb10r6mxMy/ftfN/F19dVEH31lZSZKeXltf3Ojk0ZKElDhrhGMgUHu6bWS0933fOxcmvjRqm6uu35f8z3b7Tqaik/36b+3zWcDQAAAAAAAC2Ymg8A4HY9evTQBRcM1xtvdKy/dpKSpPPOc22vXy+9/bZrarmCAmnMGCkuzlXENDWd2fmPL5gyM6V9+1rLpON5en738RMmuDJIrdPy9e4tXXLJmeU5Exdf3Lo9f75rOr3ycunPf3at3yS5puE79j1efbXruaREWrDAdb/H9v82d3//7uT68/DQpEmTjI4CAAAAAADQoXWsnwgCALqsO+64S++849T27UYnaevxx11rIzmd0syZrunoEhJco3rMZun5508+YumHJCW1bv/hD661oDZvPvXjTSbpppvavnfDDScvrtzhoYda16P66CNpwADX2lIPPOB6r0cP6cUXW0ct/fnPrVP0/fOfUliYFBEhrVnz3WuEufP7d5e6Ounhhy2aNWuWevToYXQcAAAAAACADo0iCgDQLqZPn64xY0ZpzhyLamqMTtPqoouktDQpNdVVfJSXu4qPSZOkZcukkSPP/Nzjx0vXXNP62svrxOnpfsiNN7admm727DPPcyYsFumtt6S775YGDmx939vbtYbVrl1Sv36t70dFucq2YcNcr5ubXaO4/vtfaeLEE8/vzu/fXRYtMunIEW899NDDRkcBAAAAAADo8ExOp9NpdAgAQPewf/9+jRyZqhEjKvXee80dbqRLQ4Nr6rl+/VzrI50tpaWugiUpyVXsnI7sbCklxbXe0tChMnxEWXm5dOiQa2SU+QdWmiwrcxVvxxdV38dd3//Z9Le/SffcY9Ly5St07bXXGh0HAAAAAACgo7MyIgoA0G7i4uL0f//3ob780kfTppm/c70kI/n4SEOGnP0SpFcvafDgUy+h7HZXKZORId1+u6uEkqS5c89urjMRHi4NGvTDJZQkRUaeegklue/7PxucTulPf3KNDHviiSdPqYSqrKzUxo0b2yEdAAAAAABAx8WIKABAu9u6daumTr1MAQHVevttm1JTjU7UseTnu9ZJOl7v3lJubtuSJidHmj791M/7+uvSOeecnYzdSXm5dNNNnvr4Y6eWLFmqefPmnbCP3W7Xjh07tHnzZm3ZskVffvml8vLylJqaqq+++sqA1AAAAAAAAB2C9RR+nxkAgLNr+PDh+vrr3Zo163qNHr1Wjz3m0B13SB6M05XkWmfJZHKNwpFc5dGrr544UqipScrLO/XzNjaevYzdxdq10qxZZnl6Rmjdunc0atQoSVJBQYE2bdqkLVu2KC0tTRkZGWpsbJTZbJbJZJLNZpPJZFLCtxtFAAAAAACAboYiCgDQrux2u4qLi7V//37dcMMcmc3e+s1vPtFrr3nqiSdsmjDB6ITG8/JyrStVWuqaCq9Pn+/eb8gQqaamfbN1F0VF0kMPeejFF526/PJL9Itf3Ko1a9bo4Ycf1saNG1VRUSGTySRvb281NDS0HGe321u2vby8FB8fb0R8AAAAAACADoMiCgBwVh1fNBUUFCg/P1/79+9veRQVFbX8sN7Hx0fx8fGaMWOmjhw5pIsuWq2rrzbrscfs6t/f4BsxWESE64H2VVkpPfKI9PTTHoqJ6asnn/y1li1bpmuuuUaSZDKZdGxWY6fT2aaE+rbm5mbFxcW1R2wAAAAAAIAOiyIKAHDarFar8vLyvvNx4MCBlqLJy8tL0dHRSkhI0IABAzR+/Hj16dNHCQkJSkhIUFxcnDyOm49v9erVuuuuOzRwYLauuMKke+5xaMwYo+4S3UlpqfTcc9KSJRY5nT568MHF+vWvfy1vb2/dcccd+vDDD/XAAw9o+/bt8vDwkMPh+MFz2u12ZWZmqqamRgEBAe1wFwAAAAAAAB2PyXns13oBAPhGeXm5cnNzW8ql3NzcNiOabDabJNeIpri4OMXFxSk2NrZl+9jr3r17n/a1m5ubtXz5cj355F+1det2jR5t0aJFNv3kJ5Kn59m+U3R3W7dKTz7poXfekSIiemjBgkWaN2+empqalJmZqezsbGVmZrY8rFbraZ0/JCREBQUFCgoKOuk+6enpiomJUQRD4AAAAAAAQNdjpYgCgG7IZrPpwIEDLSXT8YVTXl6eqqqqJEkWi0WxsbFKSEhQfHz8CYXTmRRNpyM9PV1PP/2k3nzzLfXs6anp022aPl0aO9atl0UXV1IirVghrVjhrQ0bGpWUlKhzzx2uwMBA7dq1S7t371ZlZaUk138Dnp6e3zsF38lGSJlMJtXV1cnHx+ekx9psNvn5+clut2vGjBl66623fvwNAgAAAAAAdBwUUQDQVTU0NKikpKTNtHnHfsh+/PR5Pj4+LdPlDRo0SCkpKS1T5/Xt21dms/GzuObl5enf//63li17Wfv2HdDgwV6aNatJM2dKsbFGp0NnUFkp/d//Sa+/btaaNc0KCvLX9OnXa/bsORo6dKgeffRRPfHEE2psbDyt85pMJiUkJCg3N1dms7nlvytJ6tGjh8rLy7/3eKfT2VIK+/n5aeTIkSfdd8WKFXrmmWeUkJCge++9VwMGDDitrAAAAAAAAAagiAKAzsrpdKqwsPCko5qOHDkiyTVaIzo6WomJiUpISGh5PrYdFhZm8J2cnvT0dP373//WW2+9pkOHrEpIMGvqVLuuvFKaMEHqAL0ZOoi8PGn1aumDDyz65JNmSR669NJJmj59pn7605/Kz8+vzf7FxcV68MEH9dJLL8lsNrdMQflDsrKylJ+frwceeEDp6ekthVRqaqq2bt161u5nw4YNWrZsmfLz8/XUU08pKSnppPt+8sknCgoKUr9+/RQeHn7WMgAAAAAAAJwmiigA6OisVusJI5ry8vKUk5OjmpoaSZK3t7eioqJaCqbjH8nJySf8wL0raGpq0tq1a7Vy5UqtXPm+8vIKFR5u0RVXNOvSSx2aMEGKijI6JdpTdbW0fr302WfSypUW5eTYFBoaoMsvn6Irr5ymyy+/XKGhoT94nvT0dC1cuFAbNmw46bR7x3h7eys8PFwBAQG65pprdOGFF7YUUjNnztSbb755Nm/xlPXr10+5ubkaNmyYtm3bZkgGAAAAAAAAUUQBQMdQVlamvXv3tnns27dPe/fuVW1trSQpICBA/fv3V79+/dS/f/+WR2Jionr16mXwHRhv9+7dWrlypT788D/auHGLbLZmJSZ6ady4Jo0fL40bJ8XHG50SZ1NFhat4WrtWWrfOSxkZNjU3OzVoUD9NmXK1pkyZojFjxpzx9JKrV6/W/PnztW/fvpOWUUOHDtX999+vHTt2KCIiQgsWLJAkffTRRzpy5IhuuOGGln2rq6tlMpkUEBBwRnlOR3Nzsw4cOKCamhoNGTLkpPulpaVp4cKF6tevn+644w6NGjXK7dkAAAAAAEC3QhEFAO3l+JFNx49wyszMVGVlpSTJy8tL0dHR37leU1xcnDw8PAy+i86hrq5OGzdu1Nq1a7V27Wpt2ZKuhoYmRUd76fzz7UpNdSg1VRo+XOrRw+i0OBX19dL27VJ6urR1q7R1q5eyslxT56WkDND48ZM0btw4jRs3TpGRkWftujabTS+//LLuvvtu1dTUtFkDymw2a86cOXrppZdO6VxLlizRwoULlZCQoBUrVmjYsGFnLeeZ2r17t/71r39p7969WrRokcaPH3/Sfbds2SJPT08lJSW1S5kGAAAAAAC6BIooADibKisrtWfPnhNGN+3du1dWq1WSayqvhIQEDRgw4IQRTtHR0TKZTAbfRddRX1+vt99+W88884zS09M1d+5cWa0V2rp1kwoLSyVJcXHeGj7crtTUZg0aJKWkSHFxkqensdm7s9JSadcuKStLysiQtm61aPduu+x2p0JC/JWamqrU1As0evRojR07Vj3aoU20Wq166KGHtGTJEplMJtlsNnl5eenRRx/VnXfeeUrnKCsr08aNG7Vz507NmzdPPXv2POm+27dvV1xcnEJCQs7WLfxo48aN05dffqnQ0FBVVFQYHQcAAAAAAHQOFFEAcCasVmub9ZqObefn58vpdMpisSgmJqbNWk3HRjjFxsbKk5bDrXJzc/XCCy/opZdeUlVVlaZNm6Zbb71VEydObCn6Dh06pPT0dG3dulXp6V9p+/atKig4KEny8fHQwIEWJSc3KSXFqeRkacAA19R+/v5G3lnXYbNJBw5IubmtpdPu3Rbt3u2U1eoadRQWFqihQ89VaupIDR8+XKmpqUpMTDS0rN23b59++9vf6j//+Y8k6dNPP9Ull1xyVq/hdDoVEhKiqqoqTZ8+XcuXLz+r5z9TNptN+fn5Ki0t1bhx4066X1FRkRYtWqQBAwZo2rRpGjFiRDumBAAAAAAAHQxFFACcTGNjo/bs2aPs7Gzl5OQoKyurZfvYuk3h4eEaOHCgBg4cqKSkJCUnJyspKUlxcXFnvC4NzozD4dCaNWv0/PPP67333lNkZKRmz56tBQsWKDo6+pTOUV1draysLO3evVtZWVnatWuHsrJ2av/+Ejkcrr8uIyIsSkgwKT6+SfHxUkKCq6CKipKioymqjmlqksrKpMJCaf9+KT9fysuT8vMtysszqajItZ6TJEVEhColJUUDBw5RSkqKkpOTlZKSclan2DvbNm/erLvuukvvvvuuW3IWFhZqx44dslgsuvTSS0+6X35+vvLz8zV06NB2GRl2Kvbs2aN77rlHOTk5uvPOO/WLX/zipPtWVlbK39+f/18CAAAAANB1UUQBwLG1m749wiknJ0fNzc2SpN69e7es13RsZFNKSop69+5tcHocOnRIL7/8sp577jkVFBRo4sSJuvXWW3X11VeftR9u19fXKzc3V/n5+crLy/vmeZ/y8/coL++A6uoaW/b19/dUdLRZkZEORUXZ1KuXq6SKiJDCwqTQUNfzsUdn+vm71SpVVLR9HD7smkqvpEQqLTWruNhTZWUOHT5saznOYvFU3769FR/fTwkJAxQfH68PP/xQ27dv1/z583XvvfcqODjYwDs7M06n0/CpNJ988kndddddkqS0tDSNGjXK0Dyna9asWVqxYoX69eunjIwMeXl5GR0JAAAAAACcXRRRALqPkpKSE6bS27Vrlw4edE3H5u3trcTExBMKp+TkZPn5+RmcHt+2ZcsW/eMf/9CKFSsUEBCgm2++WfPmzVO/fv3aPUtZWZmKi4t18OBBlZaWqri4+Jv3ClVWVqyioiKVlx9VQ0PTCccGBZkVFuapsDApJMQhLy+nAgPt8vOTvL2lkBDJy0sKCHA9LJbWY0ND257LbJYCA13b9fVSQ0Pbz2tqXFPiSZLTKR09KjU2SnV1UnW1axRTZaVUX++phgYPVVZ66OhRqaLCoYoKm779LwZPTw/17BmiyMgIRUXFKjKyj6KjoxUREaGoqChFRkYqOjpaUVFRJ0xHWVNTo6VLl+qxxx6T3W7X7bff3mkLKaMdPHhQO3fu1JgxY+T/PUPyXnnlFUVFRWno0KGKiIhox4Qnt2vXLmVkZKiwsFD33nvvSfez2WxatmxZy/+TAwIC2jElAAAAAAD4ESiiAHQtdrtd+/btU2Zmpnbt2qVdu3YpOztbe/bsUWOja9RKVFRUm6n0jm3HxMQYnB4/pKmpSe+8847+8Y9/aPPmzRo2bJh+9atfaebMmfL19TU63v9n777jqi77P46/kY0IuMUcoUjKEAERFdDUg3anaP1QMy1zJW7KBag4UBEcOVC7UUtD0xQrB25yHoYoAjJUENyDJXsezjm/P7rlvhuSFnAx3s/Hw0fq+cL3VbeD+/s513X9paKiIqSnpyM8PBwRERGIiYlB9+7d0aFDB7x48QK5ubkoKytDXl4eioryUVpajOzsLJSWlqKoqAj5+YUoL//1/KTycjny84vf6P7a2hrQ0vrvihMDAz1oamqicePG0NXVg6amFvT1m0NbWxtaWlowMDCAvr4+mjVrhqZNm6JZs2Zo3rx5xY+rYmiUn5+P7du3w9fXF6qqqpg1axbmzp0LPT29f/y56b+USiWMjIzw4MEDvPfeezh16pTopDeSmpoKMzMzlJSUYOHChfDz8xOdRERERERERESvh4MoIqqbFAoF7t27VzFwio+PrzjXp6ysDKqqqujUqRMsLCwqznB6OXDiA+665+X2e9u2bcOTJ0/w/vvvw83NDRKJRHTaX3r06BEiIiIQEREBqVSKmJgYlJX9ujJqwoQJ2L17d5XcJz4+HhEREXBxcQEAqKur16lVIy8HUmvWrIG6ujrmz5+P2bNnczViFcvIyEBeXh46d+78ymuio6Nx48YN9OjRA927d4f6/y7DE+jln/uampqVnvv23XffISYmBqamphg3bhx/DRERERERERGJxUEUEdV+L7fU+9/t9GJiYlBYWAjgv+c3vdxKz9TUFFZWVpVuUUV1w40bNxAQEIC9e/dCU1MT48ePx9y5c9GxY0fRaX+qsLAQUVFRiIiIQHh4OMLCwpCeng4VFRVoamqi5D975TVq1AhWVlYIDQ2FpqZmldx70qRJKCsrw759+6rk84mSlZUFf39/bNy4EZqampg3bx7mzJlTJ1a81Rfbt2/HggULUFRUhBs3bsDKykp00hvZtm0bAgMDkZSUhGfPnkFLS0t0EhEREREREVFDxkEUEdUe2dnZvxk2RUVF4ebNm8jPzwcANG3aFKamprCxsakYOPXo0aNOrfqgvyaXy3Hy5Els2bIFISEh6NGjB6ZPn45PPvmkVq5sOHXqFI4fP47Lly/j9u3bkMvl0NDQgFwuh1wu/8P1qqqqaNasGWJiYtC2bdsqaUhPT0e7du1gYGCA9PT0KvmcomVmZmL9+vXw9/eHrq4u5s6dCzc3Nw4VaohcLkdSUhKMjY0rXRG1ZcsWvP3227CxscFbb71Vg4X/XGFhIYyNjWFubo5PPvkEn332megkIiIiIiIiovqIgygiqnm/HzglJibi5s2bFQ/QXw6c/neVk6WlJVq2bCm4nKpTdnY2AgICsHXrVqSlpeGDDz7A7Nmz0a9fP9FplQoODoazs/NrX6+uro4rV67Azs6uyhqWLVuGlStXQqlU4tatW+jatWuVfW7RMjIysGHDBmzZsgUtWrTAvHnzMG3atCpbSUZ/n0wmg6mpKVJSUuDi4oKgoCDRSW+koKAAO3fuRFxcHOzt7TF58uRXXltUVARtbW2oqKjUYCERERERERFRvcBBFBFVn7KyMsTHxyM2NhaxsbG4efMm4uLikJmZCQBo3rw5zM3NYWpqCgsLC5iamsLc3BzNmzcXXE41KSUlBZs2bcKePXugpqaGqVOnYubMmejQoYPotNc2fPhwnD59GjKZ7C+v3bVrV6UPvN9UcXExDA0NkZubCzU1NWzevBkzZsyoss9fWzx+/Bjr1q3Djh070Lp1ayxatAiTJk2Cmpqa6LQGLzc3F/n5+ZWe2xQWFobY2FhYWVnBysqqzg0S586di127dsHc3BxHjx7lGyOIiIiIiIiIXh8HUURUNTIzMxETE1MxdIqJicHt27chk8mgra0Nc3Nz9OjRA2ZmZjAzM4O5uTnatGkjOpsEioqKwubNm3HgwAG0b98erq6ucHV1hYGBgei0N/bo0SO88847KC4ufuU1qqqqmDNnDr766qsqvXdAQABmzJgBhUIBVVVVjBgxAj/++GOV3qM2efToEdavX4+AgAAYGhrC09OTA6k6YMuWLfDy8kJeXh7u3LkDExMT0UlvJCEhAaGhoYiPj8fGjRuhqqr6ymsTExPRpUuXSrc0JCIiIiIiImpAOIgiojf39OlTREVFVXxLTEzEvXv3oFQqf3OO08uznCwsLKChoSE6m2oBhUKBEydOwNfXF2FhYbCxscGcOXMwduzYOj9IWLduHTw8PKBQKP7wmrq6Ouzt7XHu3Lkq/fdUKpUwMTFBSkoKXv51rqenh+zsbDRq1KjK7lMbPXjwAD4+Pvj222/RoUMHuLu7Y/LkyZUOCEgspVKJ1NRUGBkZVfrr08fHB126dIGtrS3efvvtmgusApmZmWjZsiU0NDQwf/58rF69WnQSERERERERkWgcRBHRq5WVlSE5Ofk3Q6eYmBgUFhZCVVUVHTt2/M3QqWfPnjA0NBSdTbVQQUEB9u/fjw0bNuDu3bt4//334ebmBolEIjqtypSXl8PS0hJJSUkoLy+v+Hk1NTW0adMG0dHRaNGiRZXe81XnU0VHR6NHjx5Veq/a6v79+1izZg2+/fZbmJiYwN3dHZ988km9H8TVV4WFhbC1tUVSUhI++eQT7NmzR3TSG5HL5YiPj0d8fDzat29f6Rl3KSkpkMvlMDY25q9XIiIiIiIiqs84iCKiXz19+hSJiYlISEioGDrdvn0bCoUCTZo0gYmJyW+GTtbW1tDRFt6oXQAAIABJREFU0RGdTbXcs2fPEBAQgC1btkAmk2Hs2LGYO3cu3nnnHdFp1SI0NBSOjo4Vq5NUVFSgpaWFyMhImJubV/n9+vXrh/Dw8N8MvtTV1bFmzRrMmzevyu9Xm92+fRs+Pj7Yv38/unXrhqVLl2LkyJFQUVERnUZ/Q1FREQoKCtCqVatXXvPLL78gISEB1tbWsLW1rXPnTrm6umLHjh1o0qQJ7t69W+m/KxEREREREVEdxkEUUUNTXl6OW7duITo6uuJMp5iYGLx48QIA8Pbbb8PS0hKWlpbo0aMHLC0tYWRkxIe59Eaio6OxceNG/PDDD2jevDlcXV0xZ84cNGvWTHRatZs0aRL27dsHmUwGFRUV/PzzzxgxYkSV3+fmzZvo0aMHfv/XeKNGjTB48GCcOnWqyu9ZFyQmJsLX1xfff/89zMzM4OXlxYFUPfXVV1/Bx8cHWVlZePz4Md566y3RSW+kuLgYcXFxuHnzJqZMmVLptdevX4e5uTm0tLRqqI6IiIiIiIioynAQRVTfvTzPKTQ0FFKptGJrPXV1dXTp0qXiHCdTU1P07t0bLVu2FJ1MdZRCocD58+exefNmBAcHo0ePHpg+fTrGjx9fbx6eFhUVYc+ePZg2bdort9LKysqCsbExcnJy4O3tDS8vr2ppGTduHIKCgiCTyf7wmra2NnJzc6Gurl4t964L4uPj4e3tjcOHD6N79+5YvHgxRo0aJTqLqsHDhw/RoUOHV76uVCqxYcMGWFpawtraGs2bN6/Bun/u/v37MDIygpqaGry8vLB06VLRSURERERERERvgoMoovpCqVQiJSUF169fr/h248YN5OfnQ0NDA927d0fPnj0rvpmZmUFNTU10NtUDpaWlOHjwIHx9fXH79m0MGjQIc+bMwbBhw+rVKpSLFy9i/PjxyM3NRVhYGMzMzF557e7duxEcHIzDhw9Xy3+Dp0+fomPHjr/Zku/3wsLC0KdPnyq/d10TFxeHlStX4vDhw+jduzc8PT3/9Fwtqr/S0tJga2uLR48eYebMmdi6davopDeiUCiQnJyM6OhoGBkZwc7O7pXXPnz4EI0bN65zwzYiIiIiIiKq1ziIIqqrXq50evktIiICmZmZUFNTg4mJScVZTjY2NujZs2e9WZFCtUd6ejq2b9+Obdu2IT8/H6NHj4aHhwdMTU1Fp1WLpKQkrF+/HitXrkTr1q0rvVapVKKkpATa2trV0uLp6YkNGzb86WooANDQ0ICXlxeWLFlSLfevi65evYpVq1YhODgY9vb2WLFiBQYNGiQ6i2pQRkYGZDIZ2rZt+8prQkNDkZmZCWtra7Rv374G66rGuHHjsH//fnTs2BGJiYk8y5GIiIiIiIhqAw6iiOqC3w+drl27hrS0NABAp06dYG9vXzF0sra25oMnqlZJSUnYtm0bdu7ciSZNmmDixIlwc3ODoaGh6LQGoaioCIaGhsjLy3vlNSoqKnB0dMSlS5dqsKxuCA8Ph4+PT8VAauXKlRgwYIDoLKol3NzcsHXrViiVSrx48QIGBgaik95IWloabty4geTkZMyZM+eV1ykUCpSVlfFNKkRERERERFQTOIgiqm1ycnIQHx9fMXSSSqW4d+8eAMDQ0PA3K50cHBzQtGlTwcXUUEilUvj5+eHEiRMwNjbGzJkzMXXq1Gpb9UN/btu2bZg1axbU1NSgqqoKpVIJmUyG3/91rq6ujtzcXP7v8wqhoaFYunQpzp8/D4lEgtWrV6NXr16is6gWyMvLQ2JiInr37v3Ka8rLy3Hs2DHY2NigY8eONVhXNRISEmBlZQVLS0t4eHjAxcVFdBIRERERERHVXxxEEYmUm5uLyMjI35zr9PDhQwCAkZERbG1t0bNnz4rBk76+vuBiamgUCgWOHTsGPz8/REREoH///nB3d8d7771Xr85/eunp06eVbttVG8TFxeHu3bt4/vw5MjMzkZGRgX379kFXVxdaWlrIyspCbm4u5HI5QkJCuP3cX5BKpfDy8sLFixchkUjg4+MDW1tb0VlUy926dQsWFhaQy+VYsmQJVq5cKTrpjeTk5ODkyZOIjIzEsGHDIJFIRCcRERERERFR/cVBFFFNSk1NhVQqRVRUFEJDQxEdHQ2FQvGHlU52dnZo1aqV6FxqwGQyGQ4cOAA/Pz/cunULQ4cOhaenJ/r27Ss6rVrcunULX3zxBeLj45GamgpNTU3RSW9k48aNsLS0xMCBAyt+LjMzExoaGtDT0xNYVneEhIRg8eLFiIyMhEQigZ+fH6ytrUVnUS1WUFCA6OhotG7dGiYmJq+8LikpCbq6urV+yP0qrq6uyMzMRN++fTFv3jzROURERERERFT3cBBFVF0yMzMRERGBq1evIjw8HJGRkcjPz0fjxo3Rs2dP9OnTB71794adnR3atGkjOpcIAFBYWIhdu3bhq6++wrNnzzBmzBi4u7vDzMxMdFq1mj9/Ps6fP4/NmzfD0dFRdA4JFBISAk9PT0RFRWHo0KHw9vaGlZWV6Cyqw4YNG4YTJ06gQ4cOSElJgZqamuikN/L111/jzJkzKCoqwtmzZ0XnEBERERERUd3DQRRRVSgvL0dsbCwiIiIqhk/JyclQUVGBiYlJxcCpT58+MDc3r3MPoaj+y8zMxNatW7F161aUlJRg8uTJmDdvHjp06CA6rUYUFxdDU1MTjRo1Ep1CtURISAjc3d0RExMDFxcXeHt7o2vXrqKzqA7Kzc3FjRs3cP/+fUycOPGV18lkMmRnZ9fZFdGJiYn45ptv0KdPHwwcOBDNmjUTnURERERERES1AwdRRH9HQUEBYmJiEBoaCqlUiitXriA3NxdNmjRB9+7d4eDgAHt7e/Tp0wctWrQQnUv0Sg8fPsSGDRvwzTffQE1NDdOmTcOCBQvQvHlz0WlEwimVSgQHB2Pp0qW4efMmXFxcsGrVqkq3YSP6u8LDw9G3b1906NABa9euxUcffSQ66Y1cvHgRX375JeLi4vDTTz9h+PDhopOIiIiIiIioduAgiuh1PHjwAFKpFGFhYZBKpYiPj4dCoYCJiQn69u0LBwcH9OnTB127duWKCqoT7t69C39/fwQEBKBp06ZwdXXFl19+CX19fdFp1aa8vJyrEelvUSgU+PHHH7F06VIkJSXBxcUFPj4+MDY2Fp1G9UhBQQHCwsIQFRWFwYMHw8bG5pXXKhSKWvv1RkFBAdTV1Ss9ay8qKgpdunThGXZEREREREQNAwdRRL8nl8tx+/btitVOUqkU9+7dg5qaGiwtLWFvbw8bGxsMGDAA7du3F51L9EZu3LiBTZs2Yf/+/TAyMsKsWbMwbdq0Sh8Y1nVRUVFYsGAB7O3tsXLlStE5VIe9HEgtWbIE9+7dw5gxY7Bs2TJ07txZdBo1MIMHD0ZaWhr69++PLVu2iM55IwqFAs2aNUNBQQHGjBmDffv2iU4iIiIiIiKi6sVBFFFJSQkiIyNx6dIlXLlyBREREcjPz4eBgQHs7e0rVjzZ2tpCW1tbdC7R3yKVSuHn54fg4GBYW1vDzc0N48aNg6qqqui0alVSUoKOHTuiU6dO2LBhA/r27Ss6ieqBlwOpRYsW4cGDB5g4cSK8vLzQrl070WnUQBw/fhxXrlxBcXEx/P39Ree8sefPnyM8PByqqqrcwo+IiIiIiKj+4yCKGp7CwkKEhYXhypUruHTpEiIjI1FSUoL27dujf//+Fec7mZqa1tptb4heh0KhwIkTJ+Dt7Y3r16/D3t4e7u7ucHZ2Fp1Wo1JTU2FkZAQVFRXRKVTPyGQyHDhwAN7e3nj06BEmTJiAZcuWoW3btqLTiAAAly9fxvLly2Fra4vJkyfXufPNAgICcPr0afTr1w+TJk2q19vHEhERERER1WPZfMpO9V5BQQFCQkKwfPlyODk5oXnz5hg8eDB27dqF1q1bY/PmzYiPj8fDhw+xd+9euLq6wtzcnEMoqrNKS0sRGBiIbt264YMPPkCbNm0QGRkJqVTa4IZQANCpU6d6PYQ6evQot7YSRF1dHePHj8etW7fg7++PEydOoFOnTnB1dcWzZ89E5xFBV1cXb7/9Nk6ePIm0tDTROW+sTZs2UCqV8PPzq9d/jhMREREREdV3XBFF9c6LFy9w+fJlXLp0CZcvX0ZsbCwUCgW6deuG/v37o1+/fujXrx/fsU71Tk5ODrZt24YtW7YgPz8fEyZMwPz589GpUyfRaVSNxo0bh8LCQhw5ckR0SoNXVlaGPXv2YMWKFcjNzcXkyZOxaNEitG7dWnQa0V/y8PBA8+bNK7YlrkvKy8sRERGBXr16QUNDQ3QOERERERER/Ra35qO6r6ioCGFhYQgJCYFUKsXVq1ehUCjQtWtXODg4QCKR4N1330XLli1FpxJVi8zMTGzduhWbN2+GXC7HxIkT4e7u3iCGrREREVi0aBF27tyJzp07i84RYvDgwejYsSN27twpOoX+o7S0FN999x2WL1+OvLw8zJo1CwsXLkSzZs1EpxG90ujRoyGVSmFhYYEzZ86Iznkj169fh62tLXR0dLBx40ZMnTpVdBIRERERERH9FwdRVPeUlpYiIiIC58+fx/nz53H16lXIZDKYmZlh4MCBGDhwIN59910YGBiITiWqVs+fP8f69esREBAALS0tfPnll5g1axb09PREp9WIU6dO4f3334dEIsH27dvRpUsX0UlCPH36FAqFAu3atROdQr9TWFiIXbt2Yc2aNSgsLMTMmTPh4eHBv5+oVissLETjxo1f+XpCQgLu3LmDXr161ao/d1JTU3Hx4kXY2NjA0tJSdA4RERERERH9FwdRVPvJ5XLExMRAKpUiNDQUZ86cQV5eHgwNDStWPP3rX/9C+/btRacS1Yi0tDRs3LgR/v7+0NXVxfTp0zF37twGM4B6qby8HJcvX8bAgQNFpxBVqqCgANu2bcPatWshk8kwY8YMeHp6Ql9fX3Qa0RvbtGkT5s+fD7lcjqioKFhbW4tOeiPLli2Dvr4+Bg8eDHNzc9E5REREREREDQEHUVQ7JScn4+zZszh37hwuXryI3NxctGnTpmLF08CBA2FkZCQ6k6hGPXjwAF999RV27NgBfX19fPnll5gzZw60tbVFpxHRa3g5kPL19YWqqipmzZrVIIfIVPfl5+cjKioK9vb2UFdXf+V1t2/fhrGxMdTU1GqwrnKTJk3CsWPHYGxsjIiICNE5REREREREDQEHUVQ75Obm4vz58zh79izOnDmDe/fuQU9PDwMGDMCgQYMwcOBAmJmZic4kEuLevXvw9fXF7t270bZtW3z55ZdwdXWFlpaW6DQi+hvy8/Oxfft2rFmzBurq6pg/fz5mz54NHR0d0WlEVSY/Px9NmzaFlpYW5syZAx8fH9FJFRQKBdLT09GmTRvRKURERERERA0BB1EkhkKhQHR0NEJCQhASEoLLly+jvLwcVlZWkEgkkEgk6NevHzQ0NESnEgmTkJAAPz8/HDhwAB06dIC7uzsmTZpUq95ZXl3KysoQEBCAxMREfP3116JziKpFVlYW/P39sXHjRmhqamLevHlc5Uj1hlwuR0JCAiIjI9G2bVu8//77opPeyPr163HkyBFIJBK4ubmhadOmopOIiIiIiIjqKg6iqOY8f/4cV65cwfHjx3HixAm8ePECrVu3Rr9+/SCRSODs7AxDQ0PRmUTCxcXFYd26ddi/fz+6du2KhQsXYuzYsQ1iAPXSBx98gDNnzmDGjBlYt24dGjVqJDqJqNpkZmZi/fr1Fee+zZ07F25ublz1SA3G/Pnzcfr0afTp0wcbNmyoFdtVXrhwAd9//z0uX76M6OhoNG7cWHQSERERERFRXcVBFFWf8vJySKVSnDx5EidOnEBiYiJ0dHTQr18/DB48GEOGDIGpqanoTKJaIyYmBj4+Pjh8+DAsLCwwb948jBs3DqqqqqLTalxsbCyaNWuG9u3bi04hqjEZGRnYsGEDtmzZghYtWmDevHmYNm0aNDU1RacRVavLly8jODgYN2/exMmTJ+vUmw8UCgXkcnmlZ2URERERERE1cBxEUdXKyMjAqVOncOLECZw9exY5OTl45513MGzYMLz33ntwcHDgO7yJfic0NBS+vr4IDg5Gjx49sGjRIowcORIqKiqi04hIgPT0dHz11VfYvHkzWrVqhcWLFzeYbTmJKpOZmYkFCxagd+/eGDx4MIyMjEQnQSqVYujQoRg0aBDc3d1hZ2cnOomIiIiIiKi2ya47bzekWuvlOTZOTk5o27YtJk+ejCdPnsDDwwOJiYm4ffs21q9fD4lEwiEU0f+QSqVwdnaGg4MDsrOzcezYMURHR2PUqFEcQtFr2bRpE4YMGSI6g6pYq1at4Ovri6SkJHzwwQeYM2cOunTpgh07dqC8vFx0HpEwWVlZuH//PubPn49jx46JzgEAdOnSBT4+PpDJZCgrKxOdQ0REREREVCtxRRS9saKiIoSFheH48eP4+eef8ejRI7Rq1QpDhgyBs7MzhgwZUiv29ieqrUJCQrB06VKEh4fD3t4e7u7ucHZ2Fp1VYxITE+Hl5YVZs2ZhwIABonPqtC+++ALXrl1DaGio6BSqRg8ePICPjw++/fZbtG/fHh4eHpg8eXKD3LaTCADkcjnKysqgra39ymsuXboEPT09WFhY1JrVhCUlJXxTFhERERERNURcEUWvJysrC4GBgRg9enTF0Ck0NBRjx47FlStX8Pz5cwQGBmLUqFEcQhH9CaVSiePHj6NXr15wcnJC48aNER4eXrEqqqFITk5G9+7dkZyczIfoVaBVq1awtbUVnUHVrGPHjggICEBycjKcnJwwc+ZMWFhYIDAwEHK5XHQeUY1TVVWtdAgFAJ6enrC2toaJiUkNVVWuuLgYbdq0gUQiwaFDh0TnEBERERER1SiuiKJXSklJwZEjR3DkyBGEhYVBS0sLgwcPxogRIzB06FC0bNlSdCJRradUKvHjjz/C29sb8fHx+OCDD7BkyRJYW1uLThPml19+wYABA+rUYfREtcm9e/fg6+uLb775Bl27dsWyZct4rhzR7ygUCiQkJODp06eVbmFaVlYGFRUVqKurV2tPSUkJfv75Zxw/fhx2dnZwc3Or1vsRERERERHVItkcRNFvJCQkICgoCMHBwYiKikLTpk0hkUgwbNgwfPjhh2jSpInoRKI6QalU4siRI1i+fDni4+MxcuRIeHl5wdzcXHQaEdUTiYmJ8PX1xf79+2FqagovLy8OpIjeUFBQECZMmABbW1usW7eOq0yJiIiIiIiqHrfma+jkcjmkUik8PDxgYmICc3Nz7N69GzY2Njh27BjS0tJw6NAhjB8/nkMootcUEhKCXr16wcXFBR06dMD169dx8OBBDqGIqEqZmpoiMDAQsbGx6Nq1Kz766CNYWVkhKChIdBpRnWFvbw9/f3907twZ+vr6onMAAMOGDcPHH3+MI0eOiE4hIiIiIiKqElwR1QApFAqEhYUhKCgIBw8eRFpaGkxNTeHs7Ixhw4bB3t6e76Ym+htCQkKwaNEiXLt2DRKJBH5+fg1qC76ysjLs2bMHQUFBOHPmDLfeI6phcXFxWLlyJQ4fPgw7OzssWrSoQZ1BR1Tdpk2bBiMjIwwYMAC9evWqtvt8/fXXOHz4MLS0tHDixIlquw8REREREVEN4dZ8DYVcLsfly5dx6NAh/PTTT0hPT4e1tTU++ugjuLi4oHPnzqITieqskJAQLF68GJGRkZBIJFizZg169uwpOqvGTZ8+HYGBgZgxYwa8vb3/8iB5IqoesbGxWL16NYKCgtC3b194e3tj0KBBorOI6rTy8nKMHTsWoaGhcHR0xA8//FDt95TL5VBVVa32+xAREREREVUzDqLqs/9d+RQUFIRnz57B1NQUo0aNwscff4x33nlHdCJRnSaVSrFkyRJcunQJEokEPj4+DfpsicePH0NdXR2tW7cWnUJEACIiIrB69WoEBwfD3t4eK1euxIABA0RnEdV5RUVF0NHReeXrd+7cQWlpKczMzKp1kLRnzx4UFxdj1KhRaNGiRbXdh4iIiIiI6B/iGVH1UUJCAjw8PNChQwc4OjoiJCQEU6dOxa1bt5CQkIDly5dzCEX0D0ilUgwYMACOjo5QV1fH1atXce7cuQY9hAKAdu3acQhFVIv07t0bx48fh1QqhZaWFgYOHAgHBwdcunRJdBpRnVbZEAoAtm7dCktLSzRr1gzPnj2rto5bt25hwYIF6NatG+RyebXdh4iIiIiI6J/iiqh6IiEhAfv27cP333+PR48eoVu3bhg9ejRGjx4NU1NT0XlE9YJUKsWyZctw/vx52NvbY/Xq1ejfv7/orBojl8uhVCqhpqYmOoUAPH/+HKmpqejbt6/oFKojpFIpli5digsXLnAVJ1E1ksvlSEhIQGRkJCZPnlytZ68WFhYiPj4ednZ21XYPIiIiIiKif4grouqytLQ0bNq0CTY2NjA3N8f+/fvx6aef4ubNm0hMTMTy5cs5hCKqAqGhoZBIJHB0dERpaSkuXLgAqVTaYIZQCoUCQUFBMDMzw65du0Tn0H8cO3YMQ4cOFZ1BdYiDgwPOnz+PK1euoKysDL169YKTkxOioqJEpxHVK6qqqujevTumTJlS6RDq8ePHeOuttzBmzBiEhIT8rXs1btz4L4dQWVlZKCsr+1ufn4iIiIiIqCpwEFXHlJSU4Pjx4xg9ejTat2+PZcuWwczMDMeOHUNqaipWr14NCwsL0ZlE9UJYWBicnZ3h4OCAkpIS/PLLL5BKpXj33XdFp9Wo58+fY+LEibCzs4OTk5PoHPqPjIwMtGzZUnQG1UEvt+c7d+4ccnNzYWtrC2dnZ0RHR4tOI2pQNDU1MWvWLBQUFCAtLa3a7uPh4QFDQ0O4urqioKCg2u5DRERERET0Ktyarw5QKBQICwvD3r178cMPP6CwsBADBgzAp59+ChcXFzRu3Fh0IlG9Eh4eDh8fHwQHB8Pe3h4rVqzAoEGDRGcJ9eLFCzRr1kx0Bv2PyMhI3L17F2PHjhWdQnVcSEgIPDw8EB0djffffx+rVq2CpaWl6Cwi+h8//vgjtLS0YG9vDwMDgzf62IcPH+LgwYO4cuUKjh49Wq1bBRIREREREf2JbA6iarGUlBR888032LdvHx49egQbGxt8+umn+Pjjj9GqVSvReUT1TkREBFavXo3g4GD07dsXHh4ecHZ2Fp1FRFTtlEolgoODsWzZMsTGxsLFxQWrVq2CiYmJ6DQiAjBs2DCcPHkSHTt2xL1790TnEBERERERvQmeEVXblJaW4uDBg5BIJOjSpQsCAwPxySefICEhAdevX4ebmxuHUERVLDIyEu+//z769OmD7OxsnDt3DqGhoQ1qCPXgwQPRCUQkkIqKCpydnXH9+nUcOXIESUlJ6NatG0aPHo3k5GTReUQNXnBwMNLT03H48OFKrysvL8fffZ9hREQELl269Lc/noiIiIiI6FU4iKolkpKS4OHhgfbt22Ps2LFQUVHBwYMHcf/+ffj4+MDU1FR0IlG9k5iYiNGjR6N3797Izs7GsWPHIJVKIZFIRKfVmIsXL8Le3h42NjYoLi4WnUNEgjVq1AjOzs64ceMGfvjhB8TGxsLMzAzjx49HSkqK6DyiBq1FixawsbGp9Jr9+/ejZcuWGDFiBBISEt7o8+/btw/vvvsujI2NeZYUERERERFVKQ6iBCotLUVQUBCcnJzQtWtX7Nu3D5MmTUJqairOnTuHUaNGQU1NTXQmUb2TkpKCTz/9FBYWFkhOTsbx48cRHh7eoFZAvXTp0iXo6Ojg5MmT0NbWFp1DRLVEo0aNMGrUKNy6dQvff/89IiIi0K1bN4wfP57bghHVYg4ODliyZAnU1NSgo6PzRh+7detW3Lx5E19++SV0dXWrqZCIiIiIiBoinhElQFxcHHbu3Im9e/eisLAQw4cPx+effw4nJyc0asTZIFF1ycjIwIYNG7Bp0yYYGhrC09MTkydPhqqqqug0YRQKBf/cIaK/JJPJcODAAXh7e+PRo0eYMGECli1bhrZt24pOI6K/aenSpbCysoKjoyNatGghOoeIiIiIiOqvbA6iaohCocCJEyewZcsWhISEwNjYGFOmTMGECRPQunVr0XlE9dqLFy+wdu1abNmyBc2bN4eXlxcmTZrEFYdERG9IJpNh9+7dWLlyJdLT0zFhwgQsX74choaGotOI6A3k5eWhf//+uHnzJsaPH4/du3e/9seePHkS6urqkEgkUFFRqcZKIiIiIiKqJziIqm4vXrzAzp07sX37djx+/BjDhg3D7NmzMWjQIP4fN6JqVlhYiK1bt8LX1xeqqqpYsGAB5syZ02C2oFMqlQgODoatrS3atGkjOoeI6pGysjLs2bMHK1asQE5ODqZMmQJPT0/+WUNUx+Tk5KCgoADt2rV75TUymQzq6uoVP540aRJ2794NCwsLREdHN+iV5URERERE9FqyuR9TNblz5w7c3NzQoUMH+Pj44L333kNCQgKOHj3Kdw8SVbOysjLs2LEDxsbGWLVqFVxdXZGSkgJ3d/cGM4RKSUmBjY0NRowYgRMnTojOoSqWmJiIKVOm8DB5EkZDQwNTp07FvXv3sHHjRgQFBcHY2Bhubm5IT08XnUdEr8nAwKDSIRQAfP755+jSpQsmT56MsrIyfPvtt4iPj8fChQs5hCIiIiIiotfCFVFVSKFQ4Pz589i8eTNOnDiBzp07Y8qUKXB1dYWBgYHoPKJ6T6FQ4Mcff4S7uzuePHmCCRMmYOXKlWjVqpXotBpXUlKCWbNmYfbs2bC0tBSdQ1Xsp59+wsiRI1FaWvqbd6kTiVJYWIhdu3bB19cXBQUFmDlzJtzd3dG0aVPRaUT0D4WGhuL06dO4c+cODh06JDqHiIiIiIjqHm7NVxUKCgqwc+dO+Pv748GDBxgyZAjc3NwwePBgrnwiqgFKpRKHDx/GkiVLcO/ePUxH7iEyAAAgAElEQVScOBHLli1D27ZtRacRVYuAgAB4enrixYsXolOIfuPllqhr166FTCbDjBkz4OHhwTfkEDUAT58+xbFjx9C/f39069YNV69ehbm5ORo3biw6jYiIiIiIxOIg6p948eIF/P394e/vj5KSEkyaNAmzZs2CiYmJ6DSiBiMkJATu7u6IiYmBi4sLfHx8YGxsLDqLqNrl5eVBT09PdAbRnyooKMC2bdvg5+cHFRUVzJ49G3PnzuWvWaJ67PTp0xg1ahQKCgqwd+9euLu7o7i4GO7u7nB3dxedR0RERERE4nAQ9Xekp6dj+/bt2LRpE5RKJSZMmMADuolqWFhYGBYvXoyLFy9CIpFg3bp16NGjh+isGlFWVobAwECkpqbCx8dHdA4R0Svl5+dj+/btWLNmDdTV1TF//nzMnj0bOjo6otOIqBqUl5cjKioKXbp0gUKhwI4dO6Crq4s5c+aITiMiIiIiInE4iHoT9+/fx8aNG7Fz5040adIE06dPxxdffMHtZohqUHx8PLy9vREUFAR7e3usWbMGjo6OorNq1HvvvYcLFy5gypQp2LZtm+gcIqK/lJWVBX9/f2zcuBGampqYN28e5syZA21tbdFpRCRA9+7d0alTJ4wcORKffPKJ6BwiIiIiIqpeHES9jvj4eKxduxYHDhxAu3bt8MUXX2Dq1Kl8eEJUg27fvg0fHx98//336NmzJ1avXg2JRCI6S4jIyEgYGhqiffv2olOIiN5IZmYm1q9fD39/f+jq6mLu3Llwc3ODlpaW6DQiqiFyuRzbt2/HhQsX0LlzZ6xbt050EhERERERVS8OoioTHx8PLy8vHD16FGZmZvDw8MBHH30ENTU10WlEDcbjx4+xdOlSBAYGolu3bli1ahVGjBghOouIiP6BjIwMbNiwAVu2bEGLFi0wb948TJs2DZqamqLTiKgGPX36FBMmTMCCBQvg5OT0h9eTkpKgqqqKzp07C6gjIiIiIqIqkt1IdEFtdO/ePYwfPx6Wlpa4f/8+jhw5gps3b2LcuHEcQhHVkNzcXHh6esLExAQXL17Enj17EBsb2yCGUMXFxaITiIiqVcuWLeHr64v79+9j7Nix8PDwgImJCXbs2IHy8nLReURUQ/Lz8wEAgwcPxqFDh/7w+urVq2FsbIy3334beXl5NZ1HRERERERVhCui/sfL7WI2bdoEQ0NDeHp6YvLkyVBVVRWdRtRgyGQy7N69G15eXigvL8fChQsbzLZNmZmZ2Lp1K/z9/XHmzBn07NlTdBIRUY149OgR1q9fj4CAgIqvwSZNmsQ3ABE1ENeuXUP37t3/sCqyrKwMkZGRiIqKgpubm6A6IiIiIiL6h7g1H/DrO/G2b98OHx8fNGnSBAsWLOD2MEQ1TKlU4vDhw1i0aBEePnyIadOmYcWKFTAwMBCdVmPOnj2LcePGYc6cOZg1axaaNm0qOomIqEY9fPgQq1evxrfffov27dvDw8ODbwoior+UmpqKr776CgMGDMDAgQP5NRQRERERUe3SsLfmKyoqgp+fHzp27Ii1a9di0aJFSE5OhpubG4dQRDUoPDwcjo6OGDNmDKysrHD79m1s3ry5QQ2hgF+3pXnw4AG8vLz4AIVeKSkpCRoaGoiPjxedQlTlOnTogICAACQnJ8PJyQkzZ86EhYUFAgMDIZfLRecRUS2VkZGByMhIfPTRRzh9+rToHCIiIiIi+p0GOYhSKpXYt28funTpglWrVmHWrFm4d+8e3N3doa2tLTqPqMG4ffs2Ro8ejb59+0JbWxvXr1/HoUOHYGRkJDpNGB0dHdEJVMulpaVBJpOhefPmolOIqs3bb7+NgIAAJCUlwdHREZMmTYKlpSWCgoLAxfxEDc+ECRPg6uqKZ8+e/enrdnZ2iIyMRFZW1l+eJ8pz6IiIiIiIal6DG0TFxMSgX79++Oyzz+Ds7IzU1FR4e3tDT09PdBpRg/H06VO4urrCwsICiYmJOH78OM6dOwcrKyvRadXq4sWLCA8PF51BdZyuri5GjBjBQRQ1CEZGRggICEBcXBysra3x8ccfcyBF1AA5ODjgxIkT+PDDDyu9Tl9fv9I39SiVSnTu3BmOjo7497//XdWZRERERET0Cg1mEJWTkwM3Nzf07NkTJSUlCAsLw7///W+0bNlSdBpRg1FYWAg/Pz907doVJ0+exLZt2xAbG4thw4aJTqtWxcXF6Nu3LwYMGIBDhw6JzqE6zsrKCkeOHIGGhoboFKIa061bNwQGBiI2NhZdu3bFRx99hB49eiAoKEh0GhHVgClTpiA5ORmBgYH/6PMoFAr4+vrCxMQEz58/r6I6IiIiIiL6KyrKev52UqVSib1792LBggWQy+Xw8vLC7Nmz0ahRg5nBEQknk8mwe/duLFu2DKWlpXB3d4ebmxu0tLREp9WYVatWQSKRoHfv3qJTiIjqvLi4OKxcuRKHDx+GnZ0dFi1aBGdnZ9FZRFSPJCcnQ1dXF4aGhqJTiIiIiIjquux6PY2JiopC3759MXnyZIwZMwYpKSlwc3PjEIqoBh0/fhxmZmaYPXs2hg8fjjt37sDd3b1BDaEAYMmSJRxCERFVEQsLCxw6dAgxMTFo3749hg8fDnt7e/zyyy+i04ionvDy8kLbtm1hYWGB4uJi0TlERERERHVavZzI5OfnY/r06bC1tYWOjg5iYmKwefNm6Ovri04jajCuXr2Kfv36YcSIEejRowdu3bqFgIAAbodJRERVpnv37jh06BDCw8PRrFkzSCQSODg44MKFC6LTiKiGXbt2rUq3QP7mm29w6tQpfPLJJ9DW1q6yz0tERERE1BDVu0HUhQsXYGlpicOHD2P//v345ZdfYGZmJjqLqMG4c+cORo8ejT59+kBDQwPXr1/HoUOH0KlTJ9Fp1SIzMxPLly9Hr169IJfLRecQETVIvXv3xvHjxxEaGgotLS0MHDgQDg4OuHTpkug0IqohISEhGDNmDIYMGYLCwsJ//PkaN26M9957D+7u7pVed//+fWzduhW3b9/+x/ckIiIiIqqv6s0gqri4GB4eHpBIJOjWrRtiY2MxZswY0VlEDUZGRgamT58Oc3Nz3L59GydOnEBISAisra1Fp1WrRYsWYfv27RgxYgRkMpnoHCKiBq1v374ICQnBlStXoKGhgXfffRdOTk64du2a6DQiqmaenp4IDQ2FhYUFGjduXGP3jY+Px5IlS9CtWzf89NNPNXZfIiIiIqK6REWpVCpFR/xT4eHhmDBhAtLT0+Hn54epU6eKTiJqMGQyGfz9/bFy5Uo0btwYK1euxGeffdZgzmLLzMyEjo4OdHR0RKcQEdHvSKVSLFmyBJcuXYJEIoGvry9sbGxEZxFRPVNeXo5r167B1NSU28ETEREREf1Rdp1+UlxSUgIPDw84OjqiU6dOiIuL4xCKqAaFhITAysoKnp6eGD9+PG7duoWJEyc2mCEUALRo0YJDKKoxSqUSe/fuxZMnT0SnENUJDg4OuHjxIs6dO4fc3FzY2trC2dkZ0dHRotOIqB5RU1NDnz59Kh1CKZVKjBgxAqtXr0ZcXFwN1hERERERiVdnnxZHR0fDysoK//73v7Fr1y6cOnUK7dq1E51F1CAkJSXB2dkZTk5OMDIywu3bt7F582Y0adJEdFqVkslkOHDgAIqKikSnEAEAsrOzK4a+RPT6JBIJIiMjcfbsWTx79gw2NjZwdnZGbGys6DQiaiDy8/PRrFkzbN++HTt27BCdQ0RERERUo+rkIOrrr79G37590bZtW8TFxWHChAmik4gahJycHHh4eMDCwgKPHz/GxYsXcfz4cRgZGYlOq3JhYWEwNjbG+PHjceXKFdE5RACA9PR0AECrVq0ElxDVTRKJBNeuXcPRo0fx5MkTWFtbY/To0bhz547oNCKqAT/99BOCg4OF3FtPTw+7d+/GkydP4OfnJ6SBiIiIiEiUOjWIys/Px9ixYzFz5ky4ubnh7NmzaN++vegsonpPoVAgMDAQ77zzDnbt2oW1a9fi+vXr6N+/v+i0amNsbIyRI0fi7t27GDJkiOgcIgBA27ZtcfToUXTu3Fl0ClGdpaKiAmdnZ0RFReHIkSNISkqCqakpRo8ejeTkZNF5RFSNLly4gOHDh8PT01Nox19t6zxhwgR8+OGHCAgIqKEiIiIiIqLqpaJUKpWiI17HnTt3MGLECOTk5OD777/HoEGDRCcR1WlyuRyqqqp/ed2FCxfwxRdf4NatW5g+fTq8vb15CDMREdUbCoUCP/74I7y8vJCamooxY8Zg2bJlHPgS1VN79uxBRkYGFixYIDrllb777jv8/PPPyMrK4sp8IiIiIqoPsuvEIOrUqVMYO3Ysunbtip9++gmGhoaik4jqtPDwcPj5+eHIkSOvvObRo0dYvHgx9u7dC4lEgk2bNsHMzKwGK6tfaWkpNDU1RWcQEVEt8HIgtXjxYty/fx9jxozB8uXL0alTJ9FpRER/qqysDBoaGqIziIiIiIj+Snat35pv3bp1cHZ2xogRI3Dx4kUOoYj+ocePH2P48OE4evQofv755z+8XlhYiOXLl8PExARXr15FcHAwzp07V2+GUDKZDPv27YOVlRW8vb1F5xARUS3RqFEjjBo1CgkJCdi1axfCwsLQrVs3uLq64smTJ6/9eUpLS6uxkojov7Zt24a33noLkydPxuPHj0XnEBERERG9Uq0dRMnlckyfPh2enp5Yt24d9uzZw5ULRP9QcXExhg8fjtzcXKioqGDmzJkoLCwEACiVSgQGBsLY2BhbtmzB8uXLERcXh6FDhwqurlrl5eVYuHAhTE1NMWrUKNE5RERUy6irq2P8+PG4desWdu7ciZCQEHTq1Amurq549uxZpR977do1ODk5VfzdSkRUnf71r39hxowZuHv3LnR1dUXnEBERERG9Uq3cmq+oqAhjxozBuXPnEBgYyIfFRFXk448/xuHDh1FeXg4AUFNTw9y5czFy5Ei4ubnh6tWrGDduHNavX49WrVoJrq0+xcXF0NbWFp1BRER1QFlZGfbs2QNvb29kZ2djypQp8PT0RJs2bf5w7eDBg3Hu3Dm8++67OHXqFLS0tAQUE9E/oVAo0KhRrX2/5t+iUCjw7NkzvPXWW6JTiIiIiKhhqn1b87148QIDBw5EeHg4Lly4wCEUURXx8/PDwYMHK4ZQwK+rg9atWwc7Ozvo6OggNjYWgYGB9XoIBYBDKCIiem0aGhqYOnUqUlNTsXHjRgQFBcHY2Bhubm5IS0uruC48PBznzp0DAEilUnz44YeQyWSisonobzh58iTs7e1/83u7Prhx4wbatWsHKysrHD9+XHQOERERETVAtWoQlZGRgUGDBuH58+cIDQ1F7969RScR1QtnzpzBokWL8GcLIFVUVNClSxecO3cO5ubmAuqqjkKhwNGjR7F+/XrRKUREVM+8HEjdvXsXq1evxqFDh2BsbAwPDw9kZ2dj0aJFUFNTA/DrGz3OnTuHUaNG/eYNIERUu5mYmCArKwuOjo4oKCgQnVNlzM3NcerUKTg4OMDAwEB0DhERERE1QLVma7709HRIJBLk5+fjl19+QadOnUQnEdULd+7cQc+ePVFUVASFQvGn16ioqGD37t347LPPariuar3//vs4ffo0hg8fjp9//hkqKiqik4iq1P/93/9h6tSpeO+990SnEDV4BQUF2LJlCzZs2ICysrI/fWitqqqKjz76CHv37q13W30R1VdpaWk4duwYPv/8c9EpQjx+/Bjt2rUTnUFERERE9Ut2rRhEZWRkoH///pDL5fjll1/4hS9RFcnLy0PPnj1x//79SrcHUlFRgZ6eHu7evYsWLVrUYGHVunLlClq3bg0TExPRKURVTqlUQkNDA3v37sWYMWNE5xDRf+Tl5cHCwgJPnjyBXC7/w+uqqqr49NNP8e233/INEkRUq5WVlaFly5Zo2rQpZsyYgYULF4pOIiIiIqL6QfwZUXl5efjXv/6FsrIyXLhwgUMooioil8vh4uLyl0Mo4NcH3Lm5uVi8eHEN1VUPR0dHDqGo3srPz4e+vn6dHhYT1UfXrl3Dw4cP/3QIBfz693FgYCC++OKLGi4jInozampqOHv2LD799FNu4UdEREREVUpN5M2Li4sxfPhwPHv2DFKpFG3bthWZQ1SvuLu748KFC698MKaiogJVVVWUl5dDVVUVXbt2haamJkpLS6GpqVnDtX8tPz8fZ8+ehYuLi+gUIiH09PSQmZkpOoOIfsfLywtqamqVngWlUCiwdetWGBgYYMWKFTVYR0T0+ho1agQ7OzvY2dn95bXPnz9Hy5YtoaqqWgNlRERERFTXCduaT6lUYvTo0Th//jwuXboEc3NzERlE9VJgYOAfzntSV1evWBnVpk0b9OvXD71794adnR2sra2hpaUlIvW17NixAwsXLoRMJkNKSgratGkjOomIiAhnz57FkCFD3uhjfH194e7uXk1FREQ1w8nJCTdu3MDQoUPx3XffcetRIiIiIqpMtrAVUStWrMDRo0dx5swZDqGIqtDVq1d/c7iyjo4ObG1t4eDggF69esHOzg6tW7cWWPjmjI2N4enpic8//xzNmjUTnUNERAQA+O67736zGkpNTQ2qqqqQyWRQKBR/+jEeHh7Q0dHB7NmzazKViKpAbGwszMzMoKYmdGORWmHbtm0IDg7GkydPOIQiIiIior8kZEXUTz/9hJEjR2L79u2YNm1aTd+e6I2Vl5cjPz8fAFBUVITS0lIAvx7oW1hYWOnH5uTk4E1+m+np6VW6xYWmpiZ0dHQA/HoAup6eHgBAS0sLeXl5mDhxIjp06AA7Ozv06tUL3bp1Q6NGwo+DIyIiqpfKy8vx6NEjpKamIjU1FSkpKUhNTUVycjJSUlIqvn5QUVGBhoYGysrKAAA7d+7E5MmTq72tLnz9oq2t/dr3IRIlPz8fRkZGcHFxQUBAgOicOiM3NxcaGhr8fU5ERETUsGXX+CDqzp076NmzJz777DNs3bq1Jm9N9VBeXh5yc3ORm5uLoqIi5OXlVTxoyc7ORmlpacXPl5SUoKCgAAUFBSgtLUVubiaKi4tQUlL8uwc1xSgt/fUhUW5uIRQKIbtX/iN6ejpQVW30nwc9ugD++6BHVVUNenr60NFpAi0tHRgYGFS8pq+vD01NTejq6kJXVxeamprQ19eHjo5OxetNmzaFvr5+lQ63Hj16hHbt2vHdlEREVO+8ePHiD0OqxMREPH78GHPmzIGjoyO/fvmPuvb1CzU8R44cgYuLC06fPg0nJyfROXXCihUrsHbtWgwZMgRbt27ludBEREREDVPNDqJKS0vRp08fqKqqIjQ0FBoaGjV1a6ql5HI5MjMzkZWVVfHPrKysiuFSTk7Of76fjdzcF8jJefGfn89DTk5hpe/UbdpUHZqaKtDRUYGeHqCpqUSTJko0biyHhoYCTZsCmpqAjg6gogIYGPz6cS9/DgCaNAHU1IBGjQB9/T++/ut9Kv931NH59WNe778HkJdX+TX5+cDL89BlMqCg4NfvFxYC/3mTNXJyAKXyz19/+XMFBUBpKZCbq47iYhWUlKggNxcoLVWioECJggI5ZLI/31YIAJo00YaBgR709fWgr28Aff1m0NdvBgMDA+jr68PAwKDi+y1btkSLFi3QokULNG/evOI8qoSEBCxbtgxHjhzByZMnMXjw4Nf7D0VERCQQv375/X+PhvX1CzVskZGR6NWrl+iMOuP58+c4duwYTp06hQMHDvD3EREREVHDVLODqFmzZuG7775DVFQUTExMauq2VIMUCgXS0tLw/PlzPH36FBkZGcjMzERGRgYyMjKQlZWBzMznyMrKRGbmC2Rl/fGphb6+GvT1G0FfXwUGBkro68v/8+3Xhy0v//ny+y9/rK0N6Om92YMTqpxCAeTmAsXFQFHRr9/Pzv71ny+/5eT8749VkJOjhtzcRsjJAXJyFMjNLYdc/ts/ZnR1tdGihQEaN26CJ0/SYGHRHVZWVmjVqhVatmyJVq1aoXXr1njrrbf+n707D4uq7N8AfrODiKAgCu4YoICYoqKCZpktpuaSmruWS+7WT7PcXn3DiqzcUnPfkjSzXlPrNU1fDRRQRJFdRXFh30GWgZnz++OEOIoKCDzMzP25rnPNcObMmfvMiDzzfM95HjRt2pRFayIiqlFsv2iXmm6/2Nrawtq6CWxsmsDa2ho2NjZsvxA9J5VKBT09PY6QQERERKSdaq8QdfToUQwaNAh79+7FmDFjauMlqZolJiYiMTERCQkJD26TkpJw794dJCXdxb1795CSkomSEuWD59SrZwAbGwM0bqyHxo2VsLYugY0NYGMDWFsDtrZQ+9nGRj6Dl7RLejqQllZ2W7qkppbe10d6uiHS0vSQmqpEVlaJ2vMbN7ZCkyaN0bx5azRpYo/mzZurdfQ0a9YM9vb2MDIyEnSERDUvOTkZDRo04BwLRJXE9gtVFdsvRLXn1KlTGDduHAYNGoS5c+eiXbt2oiMRERERUfWpnULUnTt30KlTJwwdOhRbtmyp6ZejKsrMzHwwh0HpkpBwG4mJtxETE4e8vMIH25qa6sPe3hB2dhLs7YthZwfY20PttlmzsuFiiCpDoZA7eBITgYSER28NkJhohIQEFVJSitXOVm7Y0AIODm3g4OAMBwcHODg4wM7ODvb29nB2dkb9+vUFHhXR8+nQoQOGDBmCf//736KjENUpbL9QXcH2C1HV3b59G7t27cLhw4exYcMGdO/eXXQkIiIiIqo+NV+IKikpQZ8+fZCVlYXg4GDUe3hweqpVCoUCN27cQExMDGJjY3Ht2jVcvx6N+PibuHs3GcXF8lmcxsb6aNHCCK1aSWjVSoFWrYA2bYBWrco6aMzNBR8MEeQOn+Rk4O5d4PZtID6+9FYfN28aIj5eiby8sjPc7ewaoXXrVmjd2hlOTs5wdnaGo6MjnJyc0KBBA4FHQvRsTZo0wZIlSzB79mzRUYhqFdsvpG3YfiEiIiIiIh1T84WoRYsWYfXq1QgKCoK7u3tNvhT9486dO4iNjX2wxMREITY2Crdu3YVSqYKeHtCihSkcHVV44QW5o6Z0ad1a7qzR1xd9FETVIz1d7uApXW7dAm7e1EdMjAHi4kpQXCz/F9i0aSM4OzvCyckdTk5OcHJygrOzM9q2bQtDjrdEdcDChQsxZMgQniFMWovtF6IybL8QlS83Nxevvvoq+vfvj5EjR3IIPyIiIiLNULOFqPPnz8Pb2xvff/89pkyZUlMvo7MUCgWuXbuGkJAQhISEIDLyCq5cuYzU1GwAgJWVIdq21YeDgwIODoCLC+DqCjg7AxzhgwgoKZHPQI6LK1siIowQGamPW7cUUKkkGBkZwNGxDVxdO8HFxQUeHh7o0qUL7OzsRMcnItJIbL8QPR+2X+oePz8/SJLEuZBrQXJyMlasWIEjR45gzpw5WLBggehIRERERPRsNVeIKioqgoeHB5o2bYoTJ05AT0+vJl5GZyQnJyMoKAihoaG4ejUMV65cRFzcHahUEiwsDOHmZgh390J07Ai4uQHt28sTZxNR1dy/D8TGAuHhwNWrwJUrhggL00NSUjEA+QzkDh3c8eKLXeHu7o5u3brByclJcGoiorqF7Rei2sX2ixjz58/H9u3bERMTA1tbW9FxdIIkSVAoFDAxMREdhYiIiIiereYKUUuXLsXq1asRFhYGBweHmngJraVQKBAaGoqgoCAEBp5HYODfuHnzHvT19eDgYISOHUvg7q5Chw5Ax47y/Aes8xHVjtRU4MoVICxM7uAJCzNGREQJiopUsLZuAE/PHvD07Inu3bvD09MTlpaWoiMTEdUKtl+I6i62X2rW/fv34e7uDl9fX7zzzjui49A/li1bho4dO+LNN9/kXNVEREREYtVMIerq1avw8PDAt99+i1mzZlX37rVOTk4OTp8+jTNnziAoyB+XLl1BYaECjRoZoXt3wNOz+J9bgN8JieoehQIIDQWCgoDAQD0EBhri5s1i6OvroV07B3Tv3hve3r3w6quvokWLFqLjEhFVC7ZfiDQb2y/Vq6ioiFfn1CEKhQJvvPEGzp49i0GDBuGXX34RHYmIiIhIl1V/IUqpVKJHjx4wMDBAQEAA9Dlr9GNKSkoQHByMEydO4MSJ3xEUFAKVSoUOHYzQs6fiQaeNkxPPFCbSVMnJQGCgvJw/b4jgYAkFBUq0a+eAfv3eQr9+/dCnTx9YWFiIjkpEVCFsvxBpP7ZfSNukpKQgKyuLQ1ASERERiVX9hahVq1Zh6dKluHTpElxcXKpz1xotJSUFv/zyC44f/x2nT59CdvZ9tGxpjH79itGvn4S+fTknApE2KygA/P2BkyeBEyeMcOVKCQwM9NG9exe89toADB06lP9nElGdw/YLkW5j+4V0QWBgINq0aYMmTZqIjkJERESkraq3EHX9+nV07NgRixYtwuLFi6trtxorIyMDv/zyCw4c2IfTp8/CzEwPffsC/fop0a+ffMYwEemm1FTgr7+AEyf0cPy4Ee7dU8DNzQkjR47DyJEj4ejoKDoiEekotl+I6EnYfiFt5O7ujsjISLz99ts4dOiQ6DhERERE2qh6C1EDBw5EfHw8QkJCYGRkVF271Sj5+fn4+eefceCAH06cOAlDQ6B/f2DkSCUGDADMzEQnJKK6RqUCzp0DDhwAfv7ZEElJJejc2RUjR47HmDFj0KxZM9ERSbCDBw+ifv36ePPNN0VHIS3F9gsRVRbbL6QtCgoK8McffyAjIwOTJ08WHYeIiIhIG1VfIerUqVPo27cv/vzzT/Tr1686dqlRYmNjsXHjRuzevR0FBfl47TU9jBypxKBBAIdQJ6KKUiqBM2eAAwf0cOiQIbKzVRg0aABmzJiNvn37io5HgrzyyitwdnbGpk2bREchLcP2S9X8739AZiZgZAQMGCA6DVWX2vxcIyKA2NjH1xsYACYmQLqTXfsAACAASURBVNOmgLu75sy3xvYL6YKioiKYmJiIjkFERESkiaqnEKVSqdC1a1c0a9YMv/32W3UE0xhXr17FqlVfws9vP5o21cfkySWYORNo3Fh0Ms3QtStw8aLc2ZWTIzrN88nOBlasAF55hZ1SIj/XV14BTp+W7zdqBNy7B5ia1m6G6qJQAIcPA1u2GOHkyWJ07OiKjz76GGPGjIGBgYHoeFSL3NzcMGzYMKxYsUJ0FNISbL88H7ZftFNtfq6ffAL4+j59m7ZtgXXr5KsTNQnbL7Lc3FxERESge/fuoqNQNZk0aRIuXLiAoUOHYsmSJTA2NhYdiYiIiEhTZOpXx1527NiBsLAwfPHFF9WxO41w9+5djB07Gh07dkRY2EH8+KMKt2+XYPlyduLoorNnAUdHYPVqoLhYdBrddeOGfDZzqYwM4OefhcV5bsbGwPDhwIkTxbhwAWjTJhoTJ05Ajx5dcP78edHxqBYdOnQIU6dOFR2DtADbL/Qwtl/qths3gGHDgEuXRCepHLZfZF9++SWGDRsGhUIhOgpVk6lTp6Jv374ICAhgEYqIiIiokp67EJWXl4dly5Zh+vTpcHV1rY5MdZokSdi0aRPatXPE+fM/4+BBCaGhxRg+HNCvlrIeaaLQUHnyZkBzhlDRRjt2AI9e47lli5gs1a1LF+DXX5UIDQUsLMLh5eWFqVMn4/79+6KjUS1wdnbmXBv0XNh+ofKw/VI3bNkiDwmYkSF/HuHhwNCh8mOFhYCfn9h8z0OX2y8zZsxAWloa/DT5AyQ1PXr0wNq1a/HXX3+JjkJERESkcQyfdwe+vr4oKCjAsmXLqiNPnXb//n2MHTsKR44cxaJFEhYvlsdw13RBQUB0NGBoCIwZA9y6Bfz5JxATA7i6yl+Erawef55SKXdgnD0LJCcDbm7ysC5P6isNCpKvVsnKAnr0AAYOfHqusDB5+1u3gHbtgN695dvnVZH9VuY9OXUKCA4ue+7p0/IwNwMHykPD/e9/QHy8PMzLwIHAzp3AnTvAa6/Jw76kpcnPe+cdwNy8bD8FBcBPP8n37e2Byk69pmufq1IJ7Nol32/eHGjTBvj7b3mJigLat3/+16gLOnYE/vqrBAcPAtOn78bZs6dx+PDvcHZ2Fh2NiOootl/UaerfObZftPNzBeT37+FjsrEBVq4EfvlF/jk+vnpeRyRdbL80a9YMP/30E3r16iU6CtWyo0eP4urVqxgxYgTatm0rOg4RERFR3SA9hzt37kj16tWTVq1a9Ty70QjZ2dlSjx5dJRsbI+nMGUiSpD3LjBmQAEhmZpB++QVSvXryz6VLq1aQrl9Xf861a5CaN1ffDoBUvz6kjRvVt1WpIH300ePbvvUWJGdn+b6FRdn2SiWkxYsh6eurb29oCOmLL+T9VeU4K7PfyrwnAwc+fmwApNBQ+fEhQ+Sf27SB9N57ZY+7ukJauLDsZz8/9bw//1z22MqV/FyftRw5UrbPhQsh7dhR9vO8eeJ/z2piuXsXUvfuhlLjxlZSaGioRET0KLZfNP/vHNsv2vm5Pvwe7tv3+ONbtpQ9vmWL+N+36lzYfiFt991330k2NjaSvr6+lJycLDoOERERUV2Qged59syZM6VWrVpJhYWF1RWoTlKpVNKwYYMlOzsjKTpa/Je36l5Kv/Dr6clfsrt1gzRnDqTWrcu+AE+ZUrZ9XBykFi3KHuvRA1L//uodBTt3lm2/f3/Zej09ueOjZ0/1L/MPf+HfurVsvbW1/NoPdy4cOFC146zMfivznsyZA8nevmx969aQOnbEg38rpR05enryrbm53Hnx+efyNqXPGzxYPe/IkWXPi4/n5/qs5e23y/YVHg4pJ6cse6NGkAoKxP+u1cSSlwepb18DqWVLOyktLU0iIirF9ot2/J1j+0U7P9eHC1G9e0OaOBHShAmQxo6F5O1d9thrr0HKzRX/+1bdC9svpO2Ki4ulwMBA0TGIiIiI6oqqF6KSk5MlMzMzaf369dUZqE46fPiwpK+vJ509K/5LW00spV/4H+1MuHatbL2nZ9n60aPL1q9ZU7Y+KgqSsbG8vmFDSBkZ8noXl7Lt//ij/C/2pV/4i4og2drK66ys5C+pkgSpuBhSy5by+vbtK3/2aWX3W9n3ZM2asvW//qr+2qUdOQCkPn3kgkhqatn706OH/JipKaTsbHldQYF8Fm/pc/i5Pn1JTJQ7xwBInTqVrR87tizL3r3if9dqaklPh9SihZE0Y8Z0iYioFNsvmv93ju0X7fxcJUm9EPWkpX59SBER4n/Xamph+4V0XVpampSQkCA6BhEREVFtyKjy9NSrV6+GhYUF3n///aruQmNs2rQeAwfqQxeG954xo+z+Cy/IY9QDQHp62frTp+VbExPg4Y+/XTvg5Zfl+5mZwIULQHGxPKY/AFhby/MKlHrvPcDSUv31b9wAUlLk+337yhM0p6fLcxb07y+vj4oCkpIqd1zPs9+KvCcV9fHHgKmpvI+GDeV1kybJt4WFwG+/yff/+18gL0++P3585V/nUdr6uZbavRsoKZHvP/x+TZhQdn/z5qrtWxM0agR88kkxdu7cjoKCAtFxiKiOYPtF8//Osf1Sdl+bPtdHOTsDvXrJi6en/LOBgfxeengA69Y93/7rKrZfSNdt27YNzZs3R58+fXDjxg3RcYiIiIhqVJUKUTk5Ofj+++8xb948mJmZVXemOics7DJeflkpOkataNxY/ed69eRb5T+Hf/MmkJgo3+/TB6hfX337AQPK7kdEyJNalz73pZcA/Yf+xenrA82bqz//2rWy+4cOyR0Opcv335c9du9epQ7rufb7rPekMhwdH183cmTZPksn9/7557LXeuedyr/Oo7T1cy21fXvZ/WPHgBEj5OXhffv7A5GRVdu/JujbFygoUODaw282Eek0tl80/+8c2y/qP2vL5/qoZcuAs2flJTAQiI4GQkMBW1u5+LVwYVmBT9uw/UK6bM6cOTh48CCaNWuGJk2aiI5DREREVKMMq/Kk7777DiqVCtOnT6/uPHWSiYkxCgtFp6gdJibqP+s/Uqps2hQwMpLPKC3vS/fdu2X3GzYEGjQo+7m4WH3bkhLg9m31dUZGZfdffBHo0qX8nKam5a9/kufZ77Pek8p4tIMEkN+jYcOAvXuB48flM2+PHJEfGzwYsLCo+uuV0tbPFQDOnFHvKDp58snbbtkCrFlT+dfQBKX/R5lW5U2kOm358uW4d+8etm7dKjoKaRi2X8po6t85tl/Uf9aWz7UiOnQA3noL2LlT/hv/++/ySTbahu0X0mVmZmYYOnQohg4dKjoKERERUY2rdCGqsLAQ69evx8yZM2FlZVUTmeqc7t174ddff8HChcXP3ljD6ek9/XEzM/mL+IULQHg4EBcHODiUPV46NAsgf4G2sZGHOcnOBkJCAJWqrBPh/HkgN1d9/w/vy8ICeLjfNSJC7ghp2fLZOR/1PPutyGs9vI1K9eTtjI3LXz9pktyRo1AAM2cCOTny+uoY1ubRfOXR1M8VUL8aysOj/I6vM2cASQL27AG+/LJmOoxE++UXwNa2IRwefrNJK0RFRUFZlUsYSOex/VJGU//Osf3y9Mc19XOtqKtXy+5r6yAUutR+uXHjBoKDgzFq1CjRUUjDBAcH4/PPP8fo0aMxcOBAnRiVhoiIiLRPpc+N3L59O7KzszF37tyayFMnffTRfFy4UKLW4a3LXnml7P7MmfLVKGlpgI+PPE4+IA930rmzfH/IEPk2IQGYNUvupCjd/lHOzmXP8/cHDhyQh1CJjwe8vIDWreUOB4Wicplrar+lHu6gCQ8Hrl8v64x5mIFB+c/v00fOAJQNa2NnB7z6atXyVIUmfq5ZWWXvl6WlvO/Tpx9fHp4j4uDByr2GJoiKAr791hDz5i2AoWGVLnSlOsza2hrt2rUTHYM0ENsv6jTx7xzbL8+miZ/ro06eBDZtkpcNG4Cvv5bni7p4UX7c2Bjw9n6+16iLdK398r///Q/vvfcesrOzRUchDSNJEgoLCzF69GgEBQWJjkNERERUNVIlubm5SZMnT67s0zTekiVLJFNTA+m33yBJknYtM2ZAAuQlKkr9sdat5fVt2pStUyggvfNO2XMeXaytIV27Vrb93buQGjQoe9zAAJKeHiRDQ0ht28rrLCzKtj91ClK9emXb29hA0teX7xsaQgoMrNpxVma/lX1PTp16/H3480/5sSFDytZlZT053/Ll6s+fP5+f67OWDRvK9vf++0/e7ocfyrbz9hb/O1edy40bkBwcjCQvL09JoVBIREQPY/ulbJ0m/p2r7H7ZftGcz3XhwidnfnTZtUv871t1L7rYfsnIyJCMjY2lPXv2iI5CGio5OVlSKpWiYxARERFVRUalrogKDAxEeHg4pkyZUpmnaYUVK1ZgwoT3MXSoPlavlof50lVGRsD+/fLEyQ+fpG9iIs8VEBEBvPBC2fpmzYCgIKBTJ/lnpVI+W/a33+QJih/18svAuXPyMGuGhvJZqsbGQL9+wL59gKdn1XLX1H4B+Uzbh4f2NjZ+fHiXZ5kwQX1ol3Hjqp6nKjTxc922rez+096vYcOA0pFE/f2ByMjKv1ZddPo04O1thEaNXPDrr0dg9PBkFkREYPvlYZr4d64m9wuw/QKI+1yfxNBQHoavcWNg+HDg6FH5PdYmutp+adiwIf73v/9hhDZO9kW1wtbWFvpPmfCvsLAQYWFhtZiIiIiIqOL0JKniXRJTpkxBUFCQTjdufH19sXTpYvTpo4cNG0rg6Cg6kXhpafIE1U5O8pfnp0lOljs4Hu4QeJrCQnmIlRdeqN6x8Wtqv0lJ8vvh7Kw+wXVFREcDrq7yfAUdOwKXL1dfrqrQxM9VV+TkAP/6F7BunR6GDh2MHTt2w6I6ZoUnIq3F9svjNPHvHNsvz6aJn6uuYPuFqGYdOXIEgwYNgqurKzZu3IjevXuLjkRERERUKrPChai8vDzY29vDx8cHc+bMqelgdVpwcDDef388YmOvYc4cFT7+WD5rkaiySkrkJSoK+L//k88QBYC1awEd/zWjcigUwK5dwLJlRigpqYevv16DiRMnio5FRBqC7ReqLmy/UGWw/UJUOyRJwrlz5/Djjz9izpw5cHJyEh2JiIiIqFTFC1Hbtm3DrFmzcPfuXdjY2NR0sDqvpKQEW7ZswfLlS5Cfn4OpU5X48EOgRQvRyXRDTIw8XElF/fAD4O5ec3mq6uZNwMFBfZ2dHXDjhvqZttpyvM+iK8dZWffvAzt3AqtWGSEpScK0aR9g+fIVaNSokehoRKRh2H4RS1v+zrH9ok5XjrOy2H4hIiIiIqJ/ZD5jwIoy27dvx7Bhw1iE+oehoSFmzJiBiRMnYvPmzfj66y+wbl0aBg3Sx/TpSvTtCzxl+GZ6TgoFEBdX8e2Limouy/No1kyeV6G0HOzuDuze/fhwL9pyvM+iK8dZUZGRwObNwO7dhlAo9DF58lQsWPAxWrDHmIiqiO0XsbTl7xzbL+p05Tgriu0XorotJSUFM2fOxKhRo9C/f3+YmpqKjkREREQ6oEJXREVHR6N9+/Y4efIk+pY3iy9BoVDg8OHD2LJlA/766ywaNTJA//4lGD9envj44UmciR6WkiLPzWBjA9jbi05DosXHA//5D3DwoAkCAorQrFkTTJ78AWbNmsUTAYio2rH9QlXF9gs9jO0XIs0RGRmJ2bNn48yZM9iwYQOmTZsmOhIRERFpv4oNzffFF19gzZo1SExMhD5Pk32mmJgYHDhwAAcO/IDIyGto0cIEI0YUYeRIoEsXduoQkbr4eODgQeDAAUNcvFgCW9uGGDbsXYwYMQK9e/fm/7s67O7du8jJyYGLi4voKKQD2H4hospg+4VIsyUkJMDCwgIWFhaioxAREZH2q1ghqmfPnmjfvj22b99eG6G0SkREBA4ePIj9+/cgJuYmGjc2Qp8+JXj1VQlvvsk5GYh0UX4+cO4ccPIkcPKkCS5dKoKVlQUGDHgbw4ePwBtvvAEjIyPRMakOWL58OX766SdERkaKjkI6hu0XInoU2y/VR6FQIDw8HJ07dxYdheip7t27h2bNmomOQURERJrv2YWolJQU2Nvb4+eff8bgwYNrK5hWunz5Mv773//i5Mnj8PcPQFFRMdzczNCvXwH69QN69wbMzUWnJKLqplQCFy/KHTcnThjh/HkliosldOzYHv36vYV+/fqhT58+7Lyhx8ycORPh4eE4c+aM6Cikw9h+IdJNbL/UnP3792PcuHFIT09HgwYNRMchKld4eDjc3d3Rq1cvLFu2jNM0EBER0fN4diFqx44dmDVrFlJTU2HOXoZqU1BQgICAAJw8eRInTx7DpUsR0NcHnJ0N4eFRDG9vwMsLcHHhUDhEmiY7G7hwAfD3B0JCjBAQAGRmFqNJk0bo3fsVvPpqP7z11ls8u5Ce6cSJE8jKysLw4cNFRyECwPYLkTZj+6X2pKSkoGnTpjh27BjefPNN0XGIylVSUoLjx4/jhx9+wIQJE/DGG2+IjkRERESa69mFqCFDhqCkpARHjhyprVA6KSkpCWfOnEFgYCCCgvxx6dIVFBUVw9raGN27S/D0LEaPHoCHB9Cwoei0RFSqsBAICwOCgoDAQD0EBhohLk4BPT09tGvXBt2790b37j3g7e3NeX6ISOuw/UKkmdh+EW/NmjV466234OjoKDoKEREREVFNe3ohqqioCDY2Nvjmm28wderU2gym80pKShATE4OAgAD4+/+NkJBziIq6CUmSYGdnBFdXFVxclPDwAFxdATc3wMREdGoi7ZaQAERGAhERQEiIHiIjTRAerkBRkQoNGtRDhw7u8PZ+CV5eXujZsyesra1FRyYiqlVsvxDVPWy/EFFNUiqV+Oqrr/DOO++wsEpERERP8vRC1F9//YVXX30Vd+7cQfPmzWszGJUjKSkJV65cwZUrVxAWFoawsBBER19DcbESJiYGcHU1grt7EdzcJLRvDzg6Am3aAIaGopMTaZaEBCAmBrh2Dbh6Fbh61RBhYUBmZgkAoE0bO7i7e6BDhxfh7u6OF198ES+88AL0OA4VEdFj2H4hqh1svxCRCNeuXUOfPn2QkJCAb775Bh999JHoSERERFT3PL0Q5ePjg23btuHWrVu1mIkqQ6FQIDIyElevXkVYWBiuXAlBeHgYEhPTAQBGRvpo08YIzs7FcHJSwclJ7uBxcgI4vDvpsqwsIDZW7qyJiQFiY/Vw7ZoxYmNLkJenBAA0aFAPLi7t0LFjV7i7u8Pd3R0dOnSApaWl4PRERJqN7ReiqmH7hYjqIqVSib/++gtt2rThVVFERERUnqcXogYOHAhzc3Ps37+/NkNRNcjJycG1a9cQGxuL2NhYxMRE49q1CMTG3kBOTj4AoH59A7Rta4hWrYrRurUKrVpBbWncWPBBED2HvDwgPh64dUu+lRc9xMcb4cYNCampxQAAY2NDtG3bEs7ObnB0dIaTkxOcnJzg7OyMJk2aiD0IIiIdw/YL6Tq2X4iIiIiISAs9uRAlSRKaNGmCTz/9FB9++GFtB6MalJSUhJiYGFy7dg1xcXGIj49HfPwN3LwZh8TENJT+k6hXzwCtWxuhdesStGxZglat5LOQ7ewAe3v5lhOPkwgFBcC9e0BSUtmt3GGjj/h4A8THS0hPL3mwfaNGFmjVqjlatXoBrVo5oG3btnB0dISTkxNatWoFAwMDcQdDREQVwvYLabrKtl/MzU1haGgIO7tmcHJyhqenJzp37sz2CxFppJycHHh6emLIkCGYOHEinJycREciIiKi2vPkQtT169fh6OiIc+fOoUePHrUdjARRKBS4ffv2P5078nLr1i3cunUNt2/fQmJiGoqKih9sb2qqD3t7I9jZSbC3L/7nVu7ksbMDmjYFrK0BGxvA2FjggVGdJ0lAWlrZ8mhHTUKCERIT9ZGQoER2dlknjb6+Hpo0aYQWLVr8U2hqjVatWqF169Zo3Vq+b2FhIfDIiIioprH9QqLUZPvl9OnT8PPzQ0hICK5fvw4AaN68Obp06fJg8fDwgI2NjajDJyKqsPT0dHzzzTfYt28fZs2ahQULFoiORERERLXnyYWovXv3YsqUKcjKyoKpqWltB6M6LC0tDUlJSbh3757abULCPSQm3kZCwj0kJaWjsFCh9rwGDQxha2sAGxsJNjZK2NgoYW0N2NrKw+jY2MidPtbWgKWlvJiZCTpIei4lJUB2trykp5d1zpTeT00FUlP1kJZmhLQ0PaSlqZCeXgKVquy/IwMDfTRp0gh2dk1hZ9cS9vbNYWdnBzs7O9jb2z+4tbW1hSFntCctdOHCBezfvx/ffPON6ChEWoHtF3qWutx+ycnJQVhYGEJCQh4sUVFRkCQJdnZ28PDweLD06NGDxSkiqrNUKhWKi4thYmIiOgoRERHVnicXombPno3g4GAEBQXVdijSEunp6UhJSUF6ejrS0tKQlpaGlJSUB/fT01OQlpb0z7os5OUVPLYPY2N9WFoawNJSH5aWQMOGKlhalsDSUnrQ2VO61K8PWFgAJiZAgwaAubl838oKMDVlp9CzlJQAubny3ARFRXInTEEBUFgoT4xdWFjWOZOdLa/LygKysw2Rna2P7Gw9ZGdLyM5W4v595WP7NzExgo2NFaytG6Fx46awtbWHtbU1bGxsHiy2trZq9znkDOmyDRs2YMWKFUhJSREdhUinsP2iWXS5/ZKdnY2rV6+qFaciIyMB4LHiVM+ePWFtbV0ruaji7ty5g/Hjx2Pbtm1o27at6DhEdUZMTAycnZ1FxyAiIqLqk/nE0/CioqLg7u5em2FIy1hbW1fqC29hYSHS0tKQkZGB7OzscpfMzExkZ2cjISEdUVGZyM7OQnZ2DrKz88rtCHqUpaUhTEz0UL++/j+dPhIaNJBrsebmShgbqwCUzR1hZCR3EMmPlw3P8+jcEhYWwNNOarW0BPT1n/0eZGcDKtWTH8/KkoeAKZWXBxQXy+uysuR1RUVAvjyfO3Jz5Q4a+XEjAEBBgR4KC/WQmQkUFUnIz5eQk1MCpbLcmvQDJiZGsLSsD0tLC1haWsLKqhGsrBqjeXNLuLpawtKy/KX03wGHxyOqnNTUVDRu3Fh0DCKdU1Ptlxs3buDs2SuwtW0ESVKy/VLF9ktGBqBQsP0CAJaWlvD29oa3t/eDdVlZWQgPD0dAQAD8/f2xZcsWJCYmAlAvTnl7e6NHjx4wNzcXFZ8g/39z9uxZhIWFsRBF9I/4+Hi0b98erq6uWLFiBYYOHSo6EhEREVWDJ14R1aZNG0ybNg2ffPJJbWciqrK8vDwUFhYiJycH9+/fR1FREbKyslBQUIDCwkJkZWWhsLAQ+fn5yMnJQWFhIfLy8gDIQ54olUqoVCpkZ6cBAAoLC1BQIPeK5ObmoqSk5J/Hcx+8ptxJklcrx2dubgpj47Ieo3r1zGBiIvcuWVlZQU9PD0ZGxqhf3+Kfxy1gYmKm9ripqSnMzMxgaWkJU1NTmJubw8LCAqamprCwsIC5uTlMTU1haWkJMzMzmJqaoiFndSeqdYWFhcjNzWUxikiDqVQq/Oc//4Gvry+Cg4PRp08ffPXVV+jatavadmy/VLz9EhAQgOzsbEyaNAlNmzZl+6UCEhIS1K6aunDhApKTk2FgYABnZ2e1K6c6d+6MevXqiY6sUzp37ozp06djypQpoqMQ1Rnnzp3Dnj178Prrr2PIkCGi4xAREdHzK39ovuLiYpiZmcHPzw8jRowQEYxI4x06dAgjR45EampqhZ9T2nFCREREmkuhUGD//v348ssvER0djbfeeguLFi1Cjx49REerMKVSiZycnAptW5vtl/Pnz2PMmDHIz8/Hrl278MYbb9TK62qbR4tTQUFBSE1NhaGhIZycnNSKUx4eHjDjGJFERERERFR15Reirl+/DkdHR1y8eBEeHh4ighFpvP/7v//DqVOnEBoaKjoKERER1YK8vDxs374d33zzDZKSkvDuu+/ik08+gYuLi+hoWiU7OxvTp0/H/v37MXv2bKxatQrGpeMPUpU9Wpw6f/480tPTyy1Ode3aFSYmJqIjE5EOkyQJ69evx5AhQ9CiRQvRcYiIiOjpyi9EHT9+HG+88QYyMjI4pAVRFcXFxSEpKQk9e/YUHYWIiIhqUFpaGr777jusX78eRUVFeP/99zF//nx2jNWwPXv2YObMmXB2doafnx+cnJxER9I6jxanAgICkJmZCSMjIzg6OqoVp7p168aCIBHVmlu3bqFLly7IzMyEr68v5s+fLzoSERERPVn5hahNmzZh0aJFyMzMFBGKiIiIiKjOi4+Px7fffott27ahXr16mDlzJmbPng1ra2vR0XTGzZs3MWbMGFy+fBlffPEF5s6dKzqSVlMqlYiOjlYrToWGhiI/P/9Bccrb2xteXl7w8PBA+/btoa+vLzo2EWkphUKBY8eOoW3btnB3dxcdh4iIiJ6s/ELUp59+iuPHj+PSpUsiQhERERER1Vnh4eH46quvsH//ftjZ2eGjjz7C5MmTYW5uLjqaTiopKYGPjw8+++wzDB48GFu3bkWjRo1Ex9IZ5RWnLl26hIKCAtSvXx8dO3ZUu3KKxSkiIiIiIp1TfiFq+vTpiImJwalTp0SEIiIiIiKqc/z9/eHr6/vg7OtZs2bhgw8+4Fw5dcTp06cxbtw46OvrY+/evXjppZdER9JZJSUliImJUStOhYSEoLCwEBYWFnB3d1crTrm4uEBPT090bCLSQoWFhRg+fDiGDx+Od955B/Xq1RMdiYiISBdlGpa3Njc3FxYWFrUdhoiIiIioziktQB09ehSdO3fGrl27MGbMGBgYGIiORg95+eWXER4ejg8++AAvv/wyZs+ejVWrVnHeIgEMDQ3h6uoKV1dXjB8/HgBQXFyM2NhYtcLU999/D4VCAUtLS7i5ubE4RUTVLjMzEyYmJpgyZQritOpSGQAAIABJREFU4uKwfPly0ZGIiIh0UrlXRL399tto0KAB9u7dKyITERGRTjtz5gwGDRqEmzdvcngpIkFUKhWOHTuGFStWICQkBF5eXli4cCEGDhwoOhpVwJ49ezBjxgy4uLhg3759cHR0FB2JyvFwcSogIAD+/v6IiYmBUqmElZUVXF1dHxSmvL294eDgIDpyjbhz5w4kSULLli1FRyHSWmlpadDT0+M8jkRERGKUPzTfyy+/jPbt22Pjxo0iQhEREem0n376CaNHj0ZRURGvuCCqZUVFRThw4AB8fHxw48YN9O/fH//617/QpUsX0dGokqKjozF69Ghcv34dX3/9NaZOnSo6ElVAXl4eLl++rHblVHR0NFQqFezs7NSumurWrRuaNGkiOvJz69+/P2xtbbFr1y7RUYh0mkql4hx2RERENYND8xFVNzZeieh5NWrUCG+//TaLUES1KCcnBzt37oSvry8yMjIwYsQIHD16FE5OTqKjURW1a9cOQUFBWLlyJaZPn44TJ05gy5YtaNiwoeho9BT169eHt7c3vL29H6zLzc3FlStXHhSmDh48iH//+9+QJOmx4pSnpydsbW0FHkHl2dvb4/bt26JjEOm05ORkdO7cGSNHjsS0adPg7OwsOhIREZFWKfeKKGdnZ4wbNw5LliwRkYlIoy1ZsgQXLlzA8ePHRUchIiKiZ0hOTsamTZuwdu1aKJVKTJo0CQsXLoS9vb3oaFSN/vrrL4wfPx6GhobYu3cvevfuLToSPaecnByEhYWpXTkVFRVVbnGqR48esLGxER35iY4fP47k5OQH82kRUe3LyMjAhg0bsHv3bixYsADTpk0THYmIiEiblD80n5OTEyZMmIDFixeLCEWk0V5//XU0adIEe/bsER2FiIiInuDGjRtYt24dtmzZAktLS3zwwQeYN28erKysREejGpKamorJkyfj2LFjmD9/Pj777DMYGRmJjkXVKCsrC+Hh4WrFqcjISAB4rDjl5eXFeRiJ6DGSJEGpVMLQsNwBhIiIiKhqyh+az9TUFEVFRbUdhkgrtG3bFl5eXqJjEBERUTkuX76Mb7/9Fn5+fmjVqhW+/PJLTJ06FWZmZqKjUQ1r3LgxDh8+jD179mD69Ok4ffo09u3bhxdeeEF0NKomVlZWjw3rl5iYiIsXLz4oTG3evBlJSUkAyopT3t7e8PLyQqdOnWBubi4qPhHVAXp6es8sQt25cwctWrSopURERETaodwrojw9PfHSSy/hq6++EpGJiIiIiKha+fv7w9fXF0ePHsWLL76IDz/8EGPGjOFcbDoqKioKo0ePRlxcHL777juMGzdOdCSqRQkJCWpXTQUHByMlJQUGBgZwdnZWu3LKw8ODhWoieuDKlSvo1KkT+vTpg3/961946aWXREciIiLSBE++IqqwsLC2wxARERERVRuVSoVjx45h5cqVCAoKgpeXF3777TcMGDAAenp6ouORQO3bt8f58+exfPlyTJw4EUeOHMGWLVs4NKOOsLe3h729PQYOHPhg3aPFKR8fH6SlpcHQ0BBOTk5qhakuXbrA1NRU4BEQkSiurq747bffsHPnTvabERERVUK5V0S9/vrraNWqFbZs2SIiExERERFRlSkUCuzfvx9ffPEFYmNj0b9/fyxZsgSenp6io1EddOLECUyYMAHGxsb44Ycf1IZ1I932aHHq3LlzyMjIKLc41bVrV5iYmIiOTERERERUF2WWW4h6++23YWlpiT179ogIRURERERUabm5udixYwdWrVqF1NRUjBw5EosWLUK7du1ER6M6LjU1Fe+99x7++9//YvHixVi6dCmHbaRylRanAgIC4O/vj8uXL+P+/fswMjKCo6OjWnGqW7duMDY2Fh2ZiARQKpU4deoU+vbtC319fdFxiIiIRCu/EDV27Fjk5ubi8OHDIkIRERHprPz8fBw/fhyvvPIKLC0tRcch0gipqanYsGED1q1bh+LiYrz33ntYsGABmjdvLjoaaRBJkrB161Z8+OGHcHd3x759++Dg4CA6FtVxSqUS0dHRaldOhYaGIj8/H+bm5njxxRfVilPt27dnpzSRDvD390evXr3QsmVLbN68GW+88YboSERERCKVX4j65JNP8Oeff+LSpUsiQhEREemsiIgIuLm5ISIiAi4uLqLjENVpt27dwurVq7Ft2zaYm5tjxowZmDNnDho1aiQ6GmmwiIgIjB49Grdu3cLGjRsxZswY0ZFIw5SUlCAmJkatOBUSEoLCwkJYWFjA3d1drTjVqlUr+Pj4YPLkyXjhhRdExyeiahITE4Pt27djwoQJcHV1FR2HiIhIpPILURs2bMDy5cuRmpoqIhQREZHOOn36NF555RWkpKSgcePGouMQ1UlhYWH4+uuv8eOPP6J58+aYN28epkyZgnr16omORlqisLAQCxcuxPr16zF27Fhs3LgR9evXFx2LNFh5xamLFy+iqKgIFhYWyM3NxaBBgzBs2DB4eHjAxcUFenp6omMTEREREVWH8gtRv/32G95++23cv3+fX+iJKujvv/9GfHw8xo4dKzoKEWmwpKQk/PXXX3j33Xc5PwnRI/z9/eHr64tjx47Bzc0N8+fPx+jRo2FoaCg6Gmmp48ePY+LEiTA1NcW+ffvQs2dP0ZFIixQXFyM2NhYXLlzApEmT0K5dO8TFxUGhUMDS0hJubm5qV07xigoi7ZOdnY1Dhw5hxIgRPOGBiIi0WfmFqNDQUHTu3BkxMTFwcnISEYxI43zwwQeIiorCmTNnREchIiLSGpIk4ejRo/jyyy9x7tw5eHl5YeHChRgwYACvFqBakZKSgkmTJuHPP//E4sWLsXTpUp4oQNUuLi4Otra2MDY2xtWrV+Hv7//gyqno6GioVCpYWVnB1dUV3t7e8PLyQpcuXWBnZyc6OhE9hxMnTmDgwIEwNjbGwYMH8frrr4uOREREVBPKL0SlpaWhcePGOHnyJPr27SsiGJHG6d27N9zc3LBx40bRUYiIiDRecXExfvzxR/j6+iIqKgpvvfUWPv30U16RQkJIkoR169Zh4cKF6NmzJ/bs2YPmzZuLjkU6Ii8vD5cvX1Yb1q+0OGVnZ6d21VS3bt3QpEkT0ZGJqBLS09Pxww8/YNSoUbC1tRUdh4iIqCaUX4iSJAn169fHunXr8P7774sIRqRxbt68CT09PbRu3Vp0FCIiIo11//59bNu2Dd9++y0SExPx7rvvYuHChRySiuqE8PBwjB49Grdv38amTZswatQo0ZFIR+Xk5CAsLEytOBUVFQVJkh4rTnXv3p3zThIRERGRSOUXogDA09MTnp6eWLduXW2HIiIiIiIdk5aWhu+++w7fffcd8vLyMGHCBCxevBgtW7YUHY1ITUFBAT755BOsW7cO48aNw8aNGzmvB9UJ2dnZuHr1qlpxKjIyEgAeK0717NkT1tbWghMTUUXdunULP/zwAyZNmoRmzZqJjkNERFRZTy5EzZgxA2FhYfD396/tUERERESkI5KSkvD9999j9erVAICJEyfi008/RdOmTQUnI3q6//znP5g8eTJsbGzg5+eHzp07i45E9JisrCyEh4cjJCQEAQEB8Pf3R2JiIoDHi1Pe3t5o2LCh4MREVJ4//vgD48ePR2ZmJk6ePIk+ffqIjkRERFQZTy5Ebdu2DXPnzkVOTg4n4yUiIiKianX9+nWsX78emzdvRsOGDTFt2jR8+OGHsLS0FB2NqMKSk5MxceJEnDx5EosXL8ayZcugr68vOhbRUyUkJKhdNXXhwgUkJycDABwcHODl5fWgONW5c2fUq1dPcGIiAgCFQoHDhw9j0KBBMDExER2HiIioMp5ciLp06RI8PDwQEREBFxeX2g5GRERERFro0qVLWLNmDfz8/NC6dWvMnj0b06ZNg6mpqehoRFUiSRLWrVuHjz/+GN7e3tizZw+HTSKN82hxKigoCKmpqTAwMICzs7PalVMeHh4wMzMTHZmIiIiINMeTC1EKhQINGjTAtm3bMHbs2NoORkREpHOUSiWGDBmCpUuXomvXrqLjEFUrf39/+Pr64ujRo+jUqRPmzZuHMWPG8Mp70hoXL17EmDFjkJGRgW3btuHtt98WHYnouTxanDp//jzS09NhaGgIJycntcJUly5deEIBUR0QHBz8YOhYBwcH0XGIiIhKZT5x3AhjY2O4ubkhJCSkNgMRERHprLS0NBw5cgT5+fmioxBVC5VKhSNHjqBbt27o1asXMjMz8dtvv+HSpUsYP348i1CkVbp06YLLly9j9OjRGDx4MMaPH4/79++LjkUaws3NDT///LPoGGrs7e0xcOBALF++HEeOHEFaWhru3buHX375BcOHD0dmZiZWrFiBXr16oUGDBnB1dcX48eOxdu1a+Pv7Q6FQiD4EIp1z9+5d7N69G46OjggLCxMdh4iI6AHDpz3o7e2N06dP11YWIiIinZaZmQkTExPY2NiIjkL0XIqKinDgwAGsXLkS169fR//+/REcHMwr/UjrmZmZYe3atXjppZcwZcoUdOnSBX5+fujUqZPoaFTHxcbGoqioSHSMZ7K3t39QoCoVFxcHf3//B1dOHTp0CPn5+TAyMoKjoyM8PDzg7e0NLy8vtGvXjichENWgoUOHYtCgQTh58iTc3d1FxyEiInrgiUPzAcDvv/+OAQMG4N69e7Czs6vNXEQa4/bt2+jatStOnjyJDh06iI5DREQkTG5uLnbs2IGvvvoKaWlpGDlyJBYvXgxnZ2fR0Yhq3Z07dzBu3DgEBgZixYoVWLBgAfT1nzggBem4rl27YuXKlXjttddER3luSqUS0dHRasP6Xbp0CQUFBahfvz46duyoNqxf+/bt+btBREREpN2ePEcUAOTn56NRo0bYvHkzJkyYUJvBiDTGmTNn0KdPHyQmJqJp06ai4xAREdW6lJQUbNy4EWvXroVSqcSkSZPw8ccfo1mzZqKjEQklSRLWrVuHjz/+GL1798bu3bthb28vOhZRrSspKUFMTIxacSokJASFhYWwsLCAu7u7WnHKxcUFenp6omMTaa3Dhw/j7NmzmDJlCtq1ayc6DhERab+nF6IA4NVXX4WtrS38/PxqKxSRRvn777+xdOlSnD59ml+WiIhIp8TFxWHt2rXYunUrLCwsMH36dMydOxcNGzYUHY2oTrlw4QJGjx6N7OxsbN++XW1YMyJdVVxcjNjYWLXC1MWLF1FUVIQGDRqgQ4cOLE4R1RA/Pz8sWrQId+7cwZ07d3iSBBER1bRnF6JWrVqFr776CsnJybxcnoiIiIhw5coVfPPNN/jxxx/RokULzJ07F1OnToWZmZnoaER1Vm5uLubPn4+tW7diypQpWL16NerVqyc6FlGd8mhxKiAgAJcvX4ZSqYSVlRVcXV3VilOurq6iIxNpLJVKhYsXL6Jbt26ioxARkfZ7diHq6tWrcHd35wTTRERERDrO398fvr6+OHbsGNzd3fHRRx9h9OjRMDQ0FB2NSGP8/PPPmDp1Kuzs7ODn54eOHTuKjkRUp+Xl5eHy5ctqV05FR0dDpVLBzs5OrTDVtWtXDpdOREREVPc8uxAlSRIcHBwwYsQI+Pr61lYwIiIiIqoDVCoVjh07hs8//xyBgYHw8vLCwoULMWDAAA6RRFRFt2/fxtixY3HhwgV8+eWXmDNnDn+fiCohNzcXV65cUStORUVFQZKkx4pTnp6esLW1FR2ZSCN9//33uHbtGqZOnQpnZ2fRcYiISHM9uxAFAIsXL8bu3bsRHx8PAwOD2ghGRERERAIpFArs378fX375JWJiYtC/f38sXrwY3bt3Fx2NSCsolUp8/fXXWLp0KV5++WXs2rULdnZ2omMRaaycnByEhYVVqDjVo0cP2NjYiI5MVOdt27YNK1euRFpaGpKTkzmkLBERVVXFClFRUVFwcXHBqVOn8PLLL9dGMCIiIp2TmZkJKysrnhVPQuXl5WH79u34+uuvkZKSgpEjR+LTTz9F+/btRUcj0krBwcEYPXo0cnNzsWPHDrz11luiIxFpjezsbFy9elWtOBUZGQkAjxWnvLy80KhRI8GJieoelUqFyMhIuLm5iY5CRESaq2KFKADw8PBAp06dsG3btpoORUREpJNsbGzw2WefYfr06aKjkA5KTU3Fhg0bsH79eigUCrz33nuYP38+WrRoIToakdbLycnBzJkzsW/fPkyZMgVr1qyBmZmZ6FhUSxISEpCcnIxOnTqJjqITMjMzERISAn9/f4SEhODixYtISkoCoF6c8vb2Ro8ePWBubi44MREREZHGq3gh6ttvv8WKFSuQlJTEL0VERETVTKlUwtjYGAcOHMA777wjOg7pkFu3bmH16tXYtm0b6tWrh5kzZ2LOnDk8K5xIgIMHD2Lq1Klo1qwZ/Pz84O7uLjoS1YINGzbg3//+N5KTk0VH0VkJCQlqV00FBwcjJSUFBgYGcHZ2VrtyqnPnzhyejOgRPj4+UCgUmDJlCk9iIiKi8mTqV3TLUaNG4f79+zh69GhNBiLSKPHx8fydIKJqUVRUhKlTp6Jdu3aio5COuHr1KsaPHw9HR0ccPnwYn3/+OeLj47F8+XIWoYgEGT58OC5fvoyGDRvC09MTa9euRQXPGyQNlpWVBSsrK9ExdJq9vT0GDhyI5cuX48iRI0hOTsa9e/fw66+/Yvjw4cjMzISPjw969eoFS0tLuLq6Yvz48Vi7di38/f1RWFgo+hCIhDI0NMTWrVvRq1cv/t0iIqJyVfiKKADo378/FAoFTp48WZOZiDTGpk2bsGTJEqSnp4uOQkREVCH+/v7w9fXFsWPH4OrqigULFmDUqFEwMjISHY2I/lFSUgIfHx/4+Pjg1Vdfxa5du9C0aVPRsaiGBAcHIzIyEhMnThQdhZ7h0Sunzp8/j/T0dBgaGsLJyUntyqmuXbvCxMREdGSiWlNcXIzr169zXlEiIipPxYfmA4D//ve/ePPNN3H58mV07NixJoMRaYTly5fj4MGDiIiIEB2FiIjoiSRJwtGjR+Hr64uAgAB4eXlh4cKFGDBgAPT09ETHI6InCAwMxJgxY3D//n3s3LkTb775puhIRPSIh4tTAQEBOH/+PO7fvw8jIyM4OjqqFae6desGY2Nj0ZGJiIiIalvlClGSJMHNzQ3du3fH9u3bazIYkUYIDw/HnTt32ClARER1kkqlwqFDh7BixQpEREQ8KEANHDhQdDQiqqDs7GzMmDEDP/74I2bPno1Vq1axI5uoDlMqlYiOjla7cio0NBT5+fkwNjZGhw4d4OXl9aA41b59e+jrV3jWBCKNNm/ePNjb22PixImwtbUVHYeIiGpP5QpRALB582bMnTsX8fHxaNKkSU0FIyIiIqIqKioqwoEDB/DZZ58hLi4O/fv3x/Lly+Hh4SE6GhFV0Z49ezBz5ky0bt0aP/74I9zc3ERHIqIKKikpQUxMjFpx6tKlSygoKED9+vXRsWNHtSunWJwibfV///d/2LFjB1xcXBAQECA6DhER1Z7KF6IKCgrQsmVLzJ49G8uWLaupYERERERUSTk5Odi5cyd8fX2RkZGBESNGYOnSpXB0dBQdjYiqwa1btzBmzBiEhobiiy++wNy5c0VHIqIqKq84dfHiRRQVFaFBgwbo0KGDWnHKxcWFw+mSVsjPz8e9e/fYPiUi0i2VL0QBwOLFi7Fjxw7cunWLk28SERERCZaUlITvv/8ea9asgSRJmDhxIj755BPY2dmJjkZE1aykpAQ+Pj7w8fHBoEGDsHXrVlhbW4uORUTVoLi4GLGxsWrFqQsXLkChUMDS0hJubm5qxSlXV1fRkYmIiIgqomqFqHv37qFt27b49ttvMWPGjJoIRkRERETPcOPGDaxbtw5btmyBpaUlPvjgA8ybNw9WVlaioxFRDTt9+jTGjx+PkpIS7Nq1C6+//rroSERUA0qLUwEBAfD390dISAiio6OhUqlgZWUFV1dXeHh4wNvbG97e3jwJhbTCrFmz8NJLL2Hw4MEwMjISHYeIiJ5f1QpRADB37lwcPHgQ169fR7169ao7GBERkU7x8/NDmzZt0KNHD9FRSAOEhoZi9erV8PPzQ+vWrTF79mxMmzYNpqamoqMRUS3Kzs7GBx98gAMHDmD27NlYtWoVjI2NRcciohqWl5eHy5cvq105VVqcsrOzU7tqqlu3bpzfmzRKfn4+3n33Xfz+++8YP348duzYIToSERE9v6oXolJTU9G2bVssXboUCxYsqO5gREREOqV9+/YYNWoU51+kp/L394evry+OHj2KF198ER9++CHGjBkDAwMD0dGISKA9e/Zg5syZaNeuHfz8/DjvhgYJCQnBrl27sHr1ahgaGoqOQxosNzcXV65cUStORUVFQZKkx4pT3bt3R+PGjUVHJnqq+Ph4FBYWwtnZWXQUIiJ6flUvRAHAokWLsGXLFsTFxaFBgwbVGYyIiEinWFtbw8fHB9OnTxcdheoYlUqFY8eOwcfHB8HBwfDy8sLChQsxcOBA0dGIqA6JiYnB6NGjERUVhS+++AJz584VHYkqYOvWrZg/fz6ys7NFRyEtlJ2djatXr1aoONWzZ0/ON0dEREQ1JVP/eZ798ccfQ5IkrF69uroCEWmMqKgoDBs2DOnp6aKjEJEW+OOPPzB48GDRMagOUSgU2LNnD1xcXDB48GDY2toiMDAQ/v7+LEIR0WOcnZ0RGBiIjz/+GB999BHeeecdZGRkiI5Fz3Dv3j3Y29uLjkFaytLSEt7e3pg7dy727NmDiIgIZGRk4O+//8bChQvRsGFD7N27F4MGDYKNjQ3s7e0xcOBALF++HEeOHEFmZqboQyB6IqVSifnz5yM0NFR0FCIiqoDnuiIKAFauXImvvvoKcXFxPHuGdMqJEyfw2muvISsrC5aWlqLjEBGRlsjNzcWOHTuwatUqpKamYuTIkVi0aBHatWsnOhr9P3v3HR9FnT5w/LMtvRICpFASeqihiJgQQFROBA77iQ3xlDsLcFhiO/Wnp4KHCiKo2AvKWU/BgnAqEBQkoYckCIkYSAjpfZPs7vz+mGw2SwJSkkyy+7xfr++L3dnZmWd2wjzfmWeKEB3E//73P26++WYMBgPvvfceCQkJWockTsJqtVJaWkqnTp20DkW4sZycHKerprZv305eXh4AYWFhxMfHExcXx8iRIxkxYoQ8J1y0C7/99htTpkwhLS2NxYsXc88992gdkhBCiJM7t1vzgfqQzL59+3L55ZezYsWKlgpMiHZvzZo1zJgxg9raWnk2hxBCiHN2/PhxVqxYwYsvvkhdXR2zZ8/m/vvvJyIiQuvQhBAdUEFBAbfeeitr167lrrvuYvHixZhMJq3DEkJ0ECcWp3755ReOHz+OwWCgf//+Trf1GzlyJN7e3lqHLNyQoij8+OOP9OrVi6ioKK3DEUIIcXLnXogCeO+995g1axY///wz5513XksEJoQQQgjhFrKysliyZAmvvfYafn5+3HHHHcybN4/g4GCtQxNCuIB3332XO+64g0GDBrFq1Sr69OmjdUhCiA7qxOLU1q1bKSgowGg00q9fP6fC1KhRo/Dy8tI6ZCGEEEK0Dy1TiFIUhQsvvJCKigq2bduGXn9Oj54SQgghhHB5e/bsYfHixXz44YdERkYyf/58brvtNrndjRCixaWlpXH99ddz8OBBFi9ezO233651SEIIF3Ficeqnn36iqKgIk8lE3759nYpTo0ePxtPTU+uQhZspLS1l5cqV3HLLLXTu3FnrcIQQwl21TCEKIDU1ldjYWF5++WVuvfXWlpikEEIIIYTLSUpKYtGiRXz11VcMGTKEe+65h5kzZ2I0GrUOTQjhwmpqanjsscf497//zZVXXsmrr74qV14KIVpFTk4OW7ZsISkpiZSUFHbt2kVlZWWT4lR8fDzDhw+XW92LVrVp0yamT59OTU0Nn3zyCZdddpnWIQkhhDtquUIUwLx581i1ahXp6elyloEQQgghRD2bzcZXX33FM888w88//0xcXByJiYlMnToVnU6ndXhCCDeyYcMGbr75ZkwmE++99x7jxo3TOiQhhIuzWq2kp6c7XTm1Y8cOqqur8fPzY9iwYU5XTg0cOFDutCNaVGVlJR988AGXX365HK8UQghttGwhqrS0lAEDBjBjxgxefvnllpqsEEIIIUSHVFdXx4cffsiiRYtIS0vjsssu48EHH+SCCy7QOjQhhBvLz89n9uzZfPvtt9xzzz08+eSTmEwmrcMSQrgRi8VCRkaGU3EqJSUFs9mMv78/Q4cOdSpOxcTEyMk7QgghRMfVsoUogFWrVnHTTTexYcMGJk6c2JKTFkIIIVzSP/7xDwICAvi///s/rUMRLaSiooI33niD5557jmPHjvGXv/yFBx54gJiYGK1DE0IIQH3O72uvvcY//vEPhgwZwqpVq+jdu7fWYbkVs9mMl5eX1mEI0W40V5xKTk6mpqaGgIAAhgwZIsUp0Wp+//13UlJSmDZtmtwyWwghWl7LF6IArrrqKlJSUti9ezcBAQEtPXkhhBDCpSQkJDBs2DCWLVumdSjiHBUUFPDSSy/x0ksvYTabufXWW7nnnnvo0aOH1qEJIUSz9u/fz8yZM8nKymL58uXccMMNWofkNmbMmEFgYCDvvPOO1qEI0W7V1dVx4MABp+LU9u3bqa2tJTAwkMGDBzsVpwYNGqR1yKKDeuONN7j99tsJDw9n3bp1cgKZEEK0rNYpROXn5zNkyBCmT5/OypUrW3ryQrQLtbW1eHh4aB2GEMIFTJs2jYkTJ7JgwQKtQxFn6fDhwzz//PO88cYbeHt7c+edd3L33XcTEhKidWhCCPGHzGYziYmJLFu2jKuuuoqVK1cSFBSkdVgub/DgwVx++eU8+eSTWociRIdSWVnJzp07nYpT6enp2Gw2goODGTlyJHFxcYwcOZLRo0fTrVs3rUMWHURmZiZvv/02jzzyiBzvEUKzHvJBAAAgAElEQVSIltU6hSiAL774gssvv5y1a9cyZcqU1piFEJqaOXMmZrOZzz77TOtQhBBCaGTfvn08++yzrF69mpCQEObMmcOCBQvkinAhRIf03XffMWvWLDw9PXn//feJi4vTOiSXNm/ePC699FL+9Kc/aR2KEB1eeXk5u3fvbrY4FRYW5nTV1JgxY+jSpYvWIQshhBDupPUKUaAeqN+4cSN79+6lU6dOrTUbITRx9dVXo9Pp+Oijj7QORQghRBtLSUlh6dKlrFq1iujoaO666y7+9re/4enpqXVoQghxTo4fP87s2bNZt24dDz/8MP/85z8xGAxahyWEEGesrKyMPXv2OBWn0tLSUBSlSXHq/PPPJzQ0VOuQRQdw8OBBbDYb/fr10zoUIYToSFq3EFVYWMiQIUOYOHEiq1ataq3ZCKGJJUuWoNPpmDdvntahCCGEaCNJSUksWrSItWvXMmLECObNm8f1118vB2mFEC5FURRefPFFEhMTGTFiBKtWrSIqKkrrsIQQ4pyVlpayd+9ep+LU/v37AZoUpy644AK5zbJo4u6772bFihVccsklrF69msDAQK1DEkKIjqB1C1EA33zzDVOnTuXVV1/lr3/9a2vOSgghhBCixdlsNr766iueeOIJkpOTiYuLIzExkWnTpmkdmhBCtKrU1FSuu+46fv/9d15++WWuu+46rUMSQogWV1JSwr59+9iyZQtJSUmkpKSQm5sLNC1OxcfHExwcrHHEQks2m401a9bwzTff8Morr2gdjhBCdBStX4gCeOihh3jhhRf46aefiI2Nbe3ZCSGEEEKcs5qaGv7zn//wr3/9i0OHDjFlyhQeffRRRo8erXVoQgjRZsxmM4mJiSxbtowbbriBFStW4Ofnp3VYQgjRqnJycpyumtq+fTt5eXkYDAb69+/vVJwaMWIEPj4+WocshBBCtGdtU4iyWq1MnjyZw4cPk5ycLJetCiGEEKLdKisr46233uLZZ5+lsLCQa665hkceeUTuAy+EcGv//e9/ue222/D392fVqlWMHTtW65CEEKJNnVic2rZtG/n5+RiNRvr16+dUnBo5ciTe3t5ahyw0lJubS5cuXeQW3kIIoWqbQhRAXl4esbGxxMfH89FHH7XFLIUQQgghTlteXh4vv/wyS5cuxWq1csstt5CYmEh4eLjWoQkhRLuQl5fHLbfcwvr163n44Yd59NFH0ev1WoclhBCaObE49fPPP1NYWNhscWr06NF4enpqHbJoIwkJCWRnZ3PnnXdy7733ah2OEEJore0KUQA//PADF198MUuXLuXOO+9sq9kKIYQQ7daRI0dQFIXu3btrHYrbyszMZOnSpaxcuZKAgAD+/ve/M3/+fIKCgrQOTQgh2h1FUXjxxRe5//77iYuL47333iMiIkLrsIQQot04sTi1ZcsWiouLMZlM9O3b16k4dd555+Hh4aF1yKIV/Prrr6xYsYK8vDw++OADrcMRQgittW0hCuCJJ57g6aef5ocffpDbOQghhHB7c+bM4eDBg/zvf//TOhS3s2vXLp5//nk++OADevbsydy5c7n99tvlNipCCHEaUlJSmDlzJsePH+eVV17h2muv1TqkDmPr1q1s3bqV+fPnax2KEKINWK1W0tPTnYpTO3fupKqqqqE4FR8fT1xcHCNHjmTgwIFytakQQghX0/aFKJvNxowZM/jll1/Ytm0bPXv2bMvZCyGEEO3KFVdcgYeHB6tXr9Y6FLeRlJTEokWLWLt2LcOGDWPBggXMnDkTo9GodWhCCNGhVFdX88ADD/Diiy9y44038vLLL+Pr66t1WO3e/fffz3fffceuXbu0DkUIoZHmilM7duyguroaPz8/hg0b5nTllBSnXJfFYpH9ECGEO2j7QhRARUUFcXFxWCwWfvrpJwIDA9s6BCHOWUpKCgUFBUyePFnrUIQQHdjq1avx9PTk8ssv1zoUl2az2fjqq6946qmn2LZtG3FxcSQmJjJ16lR0Op3W4QkhRIf2+eefc9tttxEaGsoHH3xAbGys1iG1axdeeCHR0dG8/vrrWocihGhHLBYLGRkZTsWplJQUzGYz/v7+DB061Kk4FRMTI/3YDs5mszFkyBBGjRrF3LlzGTlypNYhCSFEa9GmEAVw+PBhxowZw4gRI1izZg0Gg0GLMIQ4a3feeSepqan8+OOPWocihBDiJGpra1m9ejXPPPMMBw4cYMqUKTz88MOcf/75WocmhBAuJTs7m5tuuoktW7bw0EMP8eijj8rZ+ydRVFREVVUVkZGRWocihGjn6urqOHDggFNhavv27dTW1hIYGMjgwYOlONWBWSwW3n77bV566SXGjBnDq6++qnVIQgjRWrQrRAH89NNPXHjhhcybN49FixZpFYYQZ2XBggX8/PPP/Pzzz1qHIoQQ4gQVFRW88cYbLF68mOPHj3Pttdfy4IMPMnDgQK1DE0IIl6UoCi+++CL3338/48aN49133yU8PFzrsIQQwqU0Lk5t2bKFpKQkMjIysFqtBAUFMWjQoIbCVHx8PNHR0VqHLE5DdXW1PKtWCOHKtC1EAbz33nvcfPPNvPnmm8yaNUvLUIQ4I3v27KGsrIz4+HitQxFCCFEvPz+f5cuXs2zZMmpra5k9ezb33XefnHUuhBBtKDk5mZkzZ1JSUsLrr7/O9OnTtQ5JCCFcWkVFBbt27XK6cio9PR2bzUZYWJjTVVOjR4+mW7duWocshBDCvWhfiAJ46KGHeO6551izZg2XXHKJ1uEIIYQQooP57bffeOGFF3j99dfx9fXljjvuYO7cuXTq1Enr0IQQwi2Vl5dz7733snLlSm688UZeeeUVfHx8tA5LCCHcRnl5Obt373YqTqWlpaEoSpPi1JgxY+jSpYvWIYuTqKysZNq0adx4441cd911eHl5aR2SEEKcqfZRiFIUhVtvvZX//Oc/rF+/ngsuuEDrkIQQQgjRAezdu5d///vffPjhh0RGRjJ//nxuu+02OdgphBDtxKeffsrtt99O165d+eCDDxg+fLjWIQkhhNsqKytjz549p1WcGjt2LJ07d9Y6ZAHk5uZy77338sknn/D444/z4IMPah2SEEKcqfZRiAKwWq1cffXVbNq0ic2bN8szHIQQQghxUklJSSxatIivvvqKwYMHc++99zJz5kyMRqPWoQkhhDjB77//zo033sgvv/zC448/zn333Yder9c6LCGEEEBJSQn79u1zKk7t378foElxKi4uTu44oKFjx47h6elJcHCw1qEIIcSZaj+FKFAfzHfJJZeQlZXFli1b6Nmzp9YhCSGEEKKdUBSFtWvXsnDhQn766Sfi4uJITExk6tSp6HQ6rcMTQghxClarlcWLF/PPf/6TCRMm8M477xAWFqZ1WEIIIZqRm5tLcnJyQ2EqOTmZY8eOAY7iVHx8PHFxccTGxuLr66txxEIIIdq59lWIAigtLWX8+PFUVVWRlJQk96gVQgjhsr7//ntSUlK47777tA6lXaurq+PDDz/k2WefZf/+/Vx22WU88MADxMXFaR2aEEKIM/TLL79w/fXXU1payptvvsnUqVObHc9qtfLxxx/zl7/8pY0jbD0lJSX4+/tjMBi0DkUIIc5YTk6O01VTv/zyC8ePH8dgMNC/f3+nK6dGjhyJt7e31iG7naNHj7J8+XLuvPNOIiIitA5HCCEaa3+FKFA3nHFxcYSFhfHdd9/h7++vdUhCCCFEi3vkkUdYs2YNu3fv1jqUdqmyspLXX3+d559/niNHjnDllVfy2GOPMWjQIK1DE0IIcQ7Kysq46667eP/997ntttt44YUXmjzb78knn+Txxx/nxx9/ZNy4cRpF2rJuu+02fv/9d9atW6d1KEII0SJOLE5t3bqVgoICjEYj/fr1cypMjRo1Ci8vL61Ddmk//PAD119/PQUFBXz77bdceOGFWockhBB27bMQBZCRkcH48ePp27cv33zzDX5+flqHJIQQQrSoOXPmcOjQITZs2KB1KK2uoqLitHN5WVkZb731FgsXLqS4uJhrrrmGRx99lD59+rRylEIIIdrSxx9/zJw5cwgPD+eDDz5g6NChAPz888/Ex8ejKArh4eGkpqYSGBiocbTnLiYmhhkzZvD0009rHYoQQrSaE4tTP/30E0VFRc0Wp0aPHo2np6fWIbuU2tpaPvnkE6644gop/Akh2pP2W4gCtRg1ceJEoqOj+fbbb6UYJdoVm83Gn//8Z+6//36XOUtTCNG2SktLqaqqcvlnZCxdupTvv/+eL7744pTjHTt2jFdeeYUlS5agKAqzZs3igQcecPnfRwgh3Nnhw4e54YYbSE5OZuHChcyePZuhQ4dy5MgRLBYLJpOJa665hvfff1/rUM+JoigkJiYyffp04uPjtQ5HCCHalL04tWXLFpKSkti1axeVlZWYTCb69u3rVJw677zz8PDw0DpkIYQQLat9F6IA0tPTmThxIn369JEro0S7ExgYyHPPPcdf//pXrUMRQoh2afHixdx3333odDr27dtHTExMk3EOHjzIsmXLWLlyJUFBQcyZM4d//OMfLnH2uxBCiD9msVh44oknePrpp+nWrRvHjx+nrq7OaZwPP/zQpZ4XJYQQ7sxqtZKenu505dTOnTupqqrC19eX4cOHOxWnBg4ciF6v1zpsl3Ho0CGqq6sZPHiw1qEIIdxH+y9EgaMY1bdvX77++mspRol2IyYmhr///e/cfffdWocihBDtzrPPPktiYiIAJpOJv/zlL7z77rsNn+/YsYMlS5bwwQcf0KtXL+6++27mzJkjt5AQQgg39cQTT/DYY481Ga7T6fD19SU1NZUePXpoEJkQQojWZrFYyMjIcCpOpaSkYDab8ff3Z+jQoVKcaiH3338/ixcvZtKkSaxevZqQkBCtQxJCuL6OUYgC2LNnD5MmTSImJoavv/4aX19frUMSQgghxEksWrSIBx54wGmYwWDg0KFDZGdns2jRItauXUtsbCzz58/n+uuvx2AwaBStEEIIrWVlZTFkyBCqqqpobhfVZDJx3nnnsWnTJjnwKIQQbqK54lRycjI1NTUEBAQwZMgQp+JUTEwMOp1O67DbPUVRWLduHZ999hmv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5BNcvHgR0dHReOqppzB9+nS4ubkJHe+OKC0thbe3t9AxiIiI6BYYDAacOXMGiYmJcHFxwfPPPy90JCKyAnq9Hrm5ufD29oajo2Or44YPH47y8nIMGDAAH3/8sRkTEhEREVEHUCEWOgFRR+Tp6Ym//e1vuHDhAk6ePIl7770XL730Evz8/DB16lTs378fHbnHe+LECchkMmzatEnoKERERHSLxo4di1WrVqGoqEjoKERkBb744gs4Ojqia9euSElJaXPsgQMHcPr0aTahiIiIiOiGeEUU0R2iUCiwdetWrF+/vvGmun/5y1/wl7/8pcMtfaPX67Fo0SIsX74cJ06cQExMjNCRiIiI6CZyc3MRFBQEkUgkdBQislAGgwFr1qxBZmYmgoKCsHDhwlbHZmRk4OjRo+jWrRt69erF++MSERER0R/FpfmI2kNaWho2b96MDRs2QKlUYvz48Zg5cyYefPBB2NjYCB3vlqWmpvL+V0RERAJSKBRISEjADz/8gEcffRTjxo0TOhIRWSiNRoPs7GyEhoZCIpG0Oq5nz55wdnbGgw8+iNdff92MCYmIiIiok+LSfETtISoqCkuXLkV+fj6++OILVFRUYPz48ejatSv+8Y9/ICcnR+iIt4RNKKI7LzExEatWrRI6BhF1EEVFRZg9ezYKCws71GQWIjKv9957D46OjoiIiMDly5fbHHv+/HkcPXqUTSgiIiIiMhteEUVkJunp6di4cSM2btyIa9euYdiwYXj66acxYcIESKVSoeMRkZksXrwYiYmJSE1NFToKEXUQSqWSS2IRdUJKpRLr1q2DXC7HgAED8OSTT7Y69vTp08jIyEB4eDh69uwJOzs78wUlIiIiImobr4giMpeIiAgsXboUV69exZYtWwAAjz76KLp27YpXX331pjMXiYiIyHqcP38eixYtQnR0NPLz89scyyYUkfWpra3FxYsX2xxjY2ODDz74ABcuXEBdXV2bY/v27Ytp06YhJiaGTSgiIiIisji8IopIQHl5efjyyy+xdu1a5OTkICYmBjNnzsTMmTPh6ekpdLw2ffvtt7j33nsRHBwsdBSiDqW2thYajQaurq5CRyEiAf3vf//De++9hzFjxuDll19mPSXqRObNm4f169cDAFQqFRwcHARORERERETUrirYiCKyAHq9HklJSdi0aRN27twJvV6P+Ph4zJw5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IiIiItLgaWk+EZG64HQ62bFjB6tWrSIpKYlvvvkGX19frr/+ehITE7n55puJjo42OqbUk61bt3LNNdeccd5qtfL0008zY8YMA1LJxcrNzWXChAls3LiRJ554glmzZhkdSS7QnDlz+O677zCZTCxatKjWcXa7na1btxIVFUX79u0xmUz1mFJERERERETkkqRClIhIXSovLycuLo4hQ4YQFRXF1q1bSUpKori4mMjISBITE2v2lvL19TU6rtShyMhIcnJyzjj/448/0rlzZwMSycWqrKzk/vvvZ/DgwQwePJjg4GCjI8kp3G43ubm5ZGZm0qNHD1q3bl3r2D/84Q8UFBQQGxvLzJkz6zGliIiIiIiISKOnQpSISF0qKSnhpZdeYsGCBUyaNImnn34ah8PBxo0b+eqrr1i2bBnp6ekEBgZy4403MmLECIYPH06HDh2Mji5eNnPmTP7617/WLM9nMpno2bMn27dvNziZnI3b7Wb79u3ExMSoSHyJWrhwIXfddRcAixYt4tZbbzU4kYiIiIiIiMhlSYUoEZH64HK5qKioICAg4Ixr+fn5rFixgi+//JIVK1ZQWlpa0y2VmJjI8OHDCQwMNCC1eNPu3btPW47RYrEwe/ZsHnnkEQNTydksXryYBx54gPz8fFauXEliYqLRkeQUjz/+OBkZGYSHh/PGG2/UOi4/P5/MzEw6d+5MSEhIPSYUERERERERkVOoECUi0lAUFhYSFBTEhg0bWL58OStWrCA9PR1/f38GDBjA0KFDGTZsGF27djU6qlyg7t27k56ejtvtxmQykZubS7t27YyOJf8jPT2dpKQkhg0bRs+ePbUPUD1wOBzs27ePrKws+vfvf9ai/c9uu+02bDYb/fr148EHH6zHlCIiIiIiIiJyAVSIEhFpCH766SfCw8OJj4/n8ccfZ+TIkYDnX/SvX7+epKQkli5dytGjRwkNDWXw4MGMGjWKxMREWrRoYXB6OVezZ89m+vTpuFwubrjhBtauXWt0pMtOQUEBKSkpDBs2zOgocornnnuOGTNmALBlyxb69OljcCIRERERERER8RIVokREGoKqqipWrFjBhx9+yMiRI7nzzjvPGON0OtmxYwerVq1i1apVrFu3DpfLRa9evWqW8Rs4cCAWi8WAGci5yM3NpWPHjrjdbubNm8ekSZOMjnRZeeCBB3j77bcJCAigoKAAf39/oyM1asePH2fatGlkZWXRr18/nn766VrHHjhwgIKCAqKiomjevHk9phQRERERERGROqZClIjIpaqoqIhVq1axYsUKVqxYQV5eHq1bt2bw4MEMHTqUxMRELfvWAPXr14+tW7eSn5+vbrZ69vXXX1NeXk5CQgJNmjQxOs4lq6KigszMTLKyshg9enSt41wuF4MHD6Zjx44MHTqUsWPH1mNKEREREREREWkgVIgSEbnUzJw5k4EDB9K/f398fHxqzu/cubOmKLVx40YqKyuJjo4+rVuqadOmBiYXgLfeeovly5ezZMkSo6M0CAUFBYSEhFzUMxwOB5s2baKqqoohQ4Z4KZnUZvLkycybNw/w7G3XunVrgxOJiIiIiIiISAOmQpSIyKWkqKiIhIQEdu7cyf3338/cuXPPOu7EiRNs2rSpZhm/7du3YzKZTlvG74YbbsDX17eeZ9D4lZeXY7fbsdvtNefsdjsOhwOA0tJSUlJSGDhwYM31UzujfH19CQoKavRFw8rKSmbMmMFXX31FWlraBT/H5XLRoUMH8vLyGDNmDP/+97+9mPLycejQIWbOnElmZibjxo1j8uTJtY7du3cvFRUVREVFaXlDEREREREREfk1KkSJiFyK9u7di9vtpkuXLuc0/siRI6xZs6amMJWdnU1AQAB9+/atKUz17t0bs9nslXwul8trzzJSUVEReXl5HD58mPz8fAoLC8nPz/ccFxzm2NEjlJWVUlZWRklJGaX2cpxOl9e+v1nTJgQFNiEoMJDAoEBatGxNcEgYwcHBtGnThtDQ0Jrjtm3bEhYWhslk8tr315X09HTGjh1LRkYGbrebAwcO0KFDhwt+3tKlS4mOjiYyMtKLKRuH0tJSMjMzyc/PZ/jw4bWOKygoYPz48URFRTFmzBgGDx5cjylFREREREREpBFTIUpEpLHasmULXbt2PWtnTXZ2Nhs3bmTTpk18+eWX5OXlERwczMCBA0lMTGTIkCFERERc0PdmZWVx1113MX/+fLp27XqRs6hbTqeT7Oxsdu3aRU5OjueVncW+nL3s259LaVl5zVirxUxIcwshTU2ENq0mJMhJiyYQ5A+BftA8AIL8PMdB/p7jn/nbwM969gzVTiirOPn5RBXYKzznisuh7ITns70SjtqhsMxMod3C4RIT+ceqKa901tzra7PSMbwtEZ2uIKJTFBEREXTq1IkuXboQHR1tePeK2+1m3rx5PPzwwzidTqqrq7FYLMydO5dJkyadMT4rK4vly5dz3XXXERcXZ0DiS9/QoUNJTk4mKCiIkpKSS6JQKSIiIiIiIiKNigpRIiKNkdvtpn379hQVFXHffffx5ptv/uL47Ozsmm6p5cuXU1ZWRmRkZE231I033kjLli3P6bvfffddJk2ahM1m49lnn2XKlCmn7WVllP3797Nt2zZ27dpFWtoP7M7Yya7dmVRWeZbMC21pI6I1RLSqolMwRARDp2Bo3xJCmkGrQIMnUIvjlXC4GH4qhpxCyCmAfUdgX5GVnEITB484qHa6MZtNdOrYjpjYXnSLiaVbt2707NmTmJiYevnzyc/PZ8KECaxcuRKX62TXmI+PD6NGjWLx4sWnjd++fTtXXXUVTZs25e9//zsTJ06s84yXirS0NF544QUyMzOZPn06o0aNqnVseno6VquViIgIbDZbPaYUEREREREREQFUiBIRabyOHTtGUlISTqeTe++995zvq66uJjU1taYwtW7dOpxOJ717964pTF1//fX4+flRWVmJ1Wo9bRm+8ePH8+mnn1JdXY3ZbKZXr168//77dOvWrS6meValpaXs3LmTbdu2sWnjetavW0t+4VEAwlpaiWnnpFtbFzHtoVs76NXR08nUGFU74UARpB+EjEOQfshExk82dh2sprzCSZMAP3r17EFcH0/XUVxcHN26dfNq58znn3/OfffdR3l5ec1eWacKCAiguLgYq/Vk25jL5WLDhg307dv3tPON2ZEjR8jMzKS8vJyEhIRax6WmpjJ9+nSioqK46667uPrqq+sxpYiIiIiIiIjIeVEhSkTkcpednU3z5s1r7Xiy2+189913NYWplJQU/Pz86NevH6GhoezYsYOPP/6YmJgYAEJCQigsLKy532Kx4Ha7efTRR5k1a1addGWUlJSwfv16vv76a9Z8vYIf0vfgdrvpFGrjmk4O+kS6ueYKuCoCmvh6/esvSdVOSD8EW7NgcxZs3Wcj/YCne6p92xASEoeSkHAjCQkJF7x/U1lZGVOmTOGdd97BbDaf1gn1v9atW0f//v0vdDqNQteuXdmzZw+xsbH88MMPRscREREREREREfEGFaJERC53Y8aMISkpiX79+pGcnPyrhaLc3NyaotSSJUsoL/fsoxQbG8uYMWOYNWvW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4MTxEh64sZo/DoXQ5kYnk4tR4YB/roc5X1k5cMTNw398hBkzZtCsWTOjo4mIiIiIiIiISP3SHlEiImK8srIyXn/9dV59+SWOHSvm7hvcTB3h4sowo5PJ+Th2HOaugleTLRSXw90TJvD443/iiiuuMDqaiIiIiIiIiIgYQ4UoERFpOKqqqvj444/52/Oz2LUni7hIHyYPcjKuLwT6GZ1Ozsblhm9+hPc3mflgkwkfqy/33DuJxx57TEvwiYiIiIiIiIiIClEiItLwuFwuli9fzvx33yEpKQlfK9x+jYs7r3dxw5Xgox0ODZdxCD79DhZstLK/wEH8tVdz78TJ3HHHHQQFBRkdT0REREREREREGgYVokREpGE7cuQIH3zwAQvmz2PHznRaNbUyqlc1t1ztZkh38LcZnfDy4HLD5kxY8j0s2W7jx0NVhLVpzZ1338u9995LdHS00RFFRERERERERKThUSFKREQuHZmZmSxevJglny/iuy3f42czk9ANEro5SYiBHh3AZDI6ZeORWwSrM2B1uonkNAuHjzmIigznljG3c8sttxAfH4/ZrPY0ERERERERERGplQpRIiJyaTp8+DBffPEFyckrWLvma4qOltC6mZVB0U4GdnUR3xliO4DVx+ikl47MfNiSBet2wZrdVvbmOfDztRJ/3bUkDhnOzTffTGxsrNExRURERERERETk0qFClIiIXPpcLhepqamsWbOG1V+vZP36dZTZT+Dv60OvCDPXdHLQJxKujoSoNtpjCuDQMUjJga3ZsDXHhy1ZJo6WVWO1+HB1XG8SEoeSkJBAfHw8/v7+RscVEREREREREZFLkwpRIiLS+LhcLnbv3s2WLVvYunUrW77bSOrOdBzVTnytZqLbW4kOqyK2vZtu7SCmPXRsDTaL0cm9y+32FJx250H6Qcg4BGmHrGQcclNsr8ZkMtH5inD6XNuPa665lj59+tC7d2/8/PyMji4iIiIiIiIiIo2DClEiInJ5qKys5IcffiA9PZ2MjAzS03aSkf4D+w7k4Xa7MZtNtG1pJSLYTadWDiKCISIY2reE0GYQ0hSCmzasbqqjdsgvgcIyOHgU9hX+91VkYd8RHw4UOqh0uABo3bIZsbGxRMf0oHv37kRHR9OrVy+aN29u8CxERERERERERKQRUyFKREQub3a7nT179pCTk8O+ffs8r5wscrL3sm//QcpPVNaMNZtNBDezEtzURGgzFy38HTQLgEBfCPSDIH9oHgBBfmDx8exPFXhKc5G/DfysnmOnC0pPnLxW6YDyKs/xseNgr/C8yio840rKwV7lw+ESC4dL3BSWVFP13yITgNXiQ/t2oUREdCIisjMRERF06tSJiIgIunbtSnBwcF3+GEVERERERERERM5GhSgREZFfcuzYMQ4fPkxhYSGHDx8mPz+/5ri4uJiS4iLsZaWUlZVSVlZGSUkZpfZynE7Xrz+8Fs2aNiEosAmBTZoQ1DSIZs1a0KxFKwIDgwgJCSEsLIzg4GDatGlDaGgowcHBhISEYDY3oHYtERERERERERERFaJERETqTkVFBSdOnGx7stvtOByOms8tWrSoObZYL2SkjgAAAF9JREFULAQFBdVrPhERERERERERkTqmQpSIiIiIiIiIiIiIiIjUiWNaw0dERERERERERERERETqhApRIiIiIiIiIiIiIiIiUicswDajQ4iIiIiIiIiIiIiIiEijU/r/ARN5/xGPrsbJAAAAAElFTkSuQmCC",
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "try:\n",
- " display(Image(app.get_graph().draw_png()))\n",
- "except ImportError:\n",
- " print(\n",
- " \"You likely need to install dependencies for pygraphviz, see more here https://github.com/pygraphviz/pygraphviz/blob/main/INSTALL.txt\"\n",
- " )"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": ".venv",
- "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.9.6"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/docs/how-tos/graph-api.md b/docs/docs/how-tos/graph-api.md
new file mode 100644
index 000000000..64bdf389b
--- /dev/null
+++ b/docs/docs/how-tos/graph-api.md
@@ -0,0 +1,1879 @@
+# How to use the graph API
+
+This guide demonstrates the basics of LangGraph's Graph API. It walks through [state](#define-and-update-state), as well as composing common graph structures such as [sequences](#create-a-sequence-of-steps), [branches](#create-branches), and [loops](#create-and-control-loops). It also covers LangGraph's control features, including the [Send API](#map-reduce-and-the-send-api) for map-reduce workflows and the [Command API](#combine-control-flow-and-state-updates-with-command) for combining state updates with "hops" across nodes.
+
+## Setup
+
+Install `langgraph`:
+
+```bash
+pip install -U langgraph
+```
+
+!!! tip "Set up LangSmith for better debugging"
+ Sign up for [LangSmith](https://smith.langchain.com) 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 in the [docs](https://docs.smith.langchain.com).
+
+## Define and update state
+
+Here we show how to define and update [state](../concepts/low_level.md#state) in LangGraph. We will demonstrate:
+
+1. How to use state to define a graph's [schema](../concepts/low_level.md#schema)
+2. How to use [reducers](../concepts/low_level.md#reducers) to control how state updates are processed.
+
+### Define state
+
+[State](../concepts/low_level.md#state) in LangGraph can be a `TypedDict`, `Pydantic` model, or dataclass. Below we will use `TypedDict`. See [this section](#use-pydantic-models-for-graph-state) for detail on using Pydantic.
+
+By default, graphs will have the same input and output schema, and the state determines that schema. See [this section](#define-input-and-output-schemas) for how to define distinct input and output schemas.
+
+Let's consider a simple example using [messages](../concepts/low_level.md#messagesstate). This represents a versatile formulation of state for many LLM applications. See our [concepts page](../concepts/low_level.md#working-with-messages-in-graph-state) for more detail.
+
+```python
+from langchain_core.messages import AnyMessage
+from typing_extensions import TypedDict
+
+class State(TypedDict):
+ messages: list[AnyMessage]
+ extra_field: int
+```
+
+This state tracks a list of [message](https://python.langchain.com/docs/concepts/messages/) objects, as well as an extra integer field.
+
+### Update state
+
+Let's build an example graph with a single node. Our [node](../concepts/low_level.md#nodes) is just a Python function that reads our graph's state and makes updates to it. The first argument to this function will always be the state:
+
+```python
+from langchain_core.messages import AIMessage
+
+def node(state: State):
+ messages = state["messages"]
+ new_message = AIMessage("Hello!")
+ return {"messages": messages + [new_message], "extra_field": 10}
+```
+
+This node simply appends a message to our message list, and populates an extra field.
+
+!!! important
+ Nodes should return updates to the state directly, instead of mutating the state.
+
+Let's next define a simple graph containing this node. We use [StateGraph](../concepts/low_level.md#stategraph) to define a graph that operates on this state. We then use [add_node](../concepts/low_level.md#nodes) populate our graph.
+
+```python
+from langgraph.graph import StateGraph
+
+builder = StateGraph(State)
+builder.add_node(node)
+builder.set_entry_point("node")
+graph = builder.compile()
+```
+
+LangGraph provides built-in utilities for visualizing your graph. Let's inspect our graph. See [this section](#visualize-your-graph) for detail on visualization.
+
+```python
+from IPython.display import Image, display
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+In this case, our graph just executes a single node. Let's proceed with a simple invocation:
+
+```python
+from langchain_core.messages import HumanMessage
+
+result = graph.invoke({"messages": [HumanMessage("Hi")]})
+result
+```
+```
+{'messages': [HumanMessage(content='Hi'), AIMessage(content='Hello!')], 'extra_field': 10}
+```
+
+Note that:
+
+- We kicked off invocation by updating a single key of the state.
+- We receive the entire state in the invocation result.
+
+For convenience, we frequently inspect the content of [message objects](https://python.langchain.com/docs/concepts/messages/) via pretty-print:
+
+```python
+for message in result["messages"]:
+ message.pretty_print()
+```
+```
+================================ Human Message ================================
+
+Hi
+================================== Ai Message ==================================
+
+Hello!
+```
+
+### Process state updates with reducers
+
+Each key in the state can have its own independent [reducer](../concepts/low_level.md#reducers) function, which controls how updates from nodes are applied. If no reducer function is explicitly specified then it is assumed that all updates to the key should override it.
+
+For `TypedDict` state schemas, we can define reducers by annotating the corresponding field of the state with a reducer function.
+
+In the earlier example, our node updated the `"messages"` key in the state by appending a message to it. Below, we add a reducer to this key, such that updates are automatically appended:
+
+```python
+from typing_extensions import Annotated
+
+def add(left, right):
+ """Can also import `add` from the `operator` built-in."""
+ return left + right
+
+class State(TypedDict):
+ # highlight-next-line
+ messages: Annotated[list[AnyMessage], add]
+ extra_field: int
+```
+
+Now our node can be simplified:
+
+```python
+def node(state: State):
+ new_message = AIMessage("Hello!")
+ # highlight-next-line
+ return {"messages": [new_message], "extra_field": 10}
+```
+```python
+from langgraph.graph import START
+
+graph = StateGraph(State).add_node(node).add_edge(START, "node").compile()
+
+result = graph.invoke({"messages": [HumanMessage("Hi")]})
+
+for message in result["messages"]:
+ message.pretty_print()
+```
+```
+================================ Human Message ================================
+
+Hi
+================================== Ai Message ==================================
+
+Hello!
+```
+
+#### MessagesState
+
+In practice, there are additional considerations for updating lists of messages:
+
+- We may wish to update an existing message in the state.
+- We may want to accept short-hands for [message formats](../concepts/low_level.md#using-messages-in-your-graph), such as [OpenAI format](https://python.langchain.com/docs/concepts/messages/#openai-format).
+
+LangGraph includes a built-in reducer `add_messages` that handles these considerations:
+
+```python
+from langgraph.graph.message import add_messages
+
+class State(TypedDict):
+ # highlight-next-line
+ messages: Annotated[list[AnyMessage], add_messages]
+ extra_field: int
+
+def node(state: State):
+ new_message = AIMessage("Hello!")
+ return {"messages": [new_message], "extra_field": 10}
+
+graph = StateGraph(State).add_node(node).set_entry_point("node").compile()
+```
+
+```python
+# highlight-next-line
+input_message = {"role": "user", "content": "Hi"}
+
+result = graph.invoke({"messages": [input_message]})
+
+for message in result["messages"]:
+ message.pretty_print()
+```
+```
+================================ Human Message ================================
+
+Hi
+================================== Ai Message ==================================
+
+Hello!
+```
+
+This is a versatile representation of state for applications involving [chat models](https://python.langchain.com/docs/concepts/chat_models/). LangGraph includes a pre-built `MessagesState` for convenience, so that we can have:
+
+```python
+from langgraph.graph import MessagesState
+
+class State(MessagesState):
+ extra_field: int
+```
+
+### Define input and output schemas
+
+By default, `StateGraph` operates with a single schema, and all nodes are expected to communicate using that schema. However, it's also possible to define distinct input and output schemas for a graph.
+
+When distinct schemas are specified, an internal schema will still be used for communication between nodes. The input schema ensures that the provided input matches the expected structure, while the output schema filters the internal data to return only the relevant information according to the defined output schema.
+
+Below, we'll see how to define distinct input and output schema.
+
+```python
+from langgraph.graph import StateGraph, START, END
+from typing_extensions import TypedDict
+
+# Define the schema for the input
+class InputState(TypedDict):
+ question: str
+
+# Define the schema for the output
+class OutputState(TypedDict):
+ answer: str
+
+# Define the overall schema, combining both input and output
+class OverallState(InputState, OutputState):
+ pass
+
+# Define the node that processes the input and generates an answer
+def answer_node(state: InputState):
+ # Example answer and an extra key
+ return {"answer": "bye", "question": state["question"]}
+
+# Build the graph with input and output schemas specified
+builder = StateGraph(OverallState, input_schema=InputState, output_schema=OutputState)
+builder.add_node(answer_node) # Add the answer node
+builder.add_edge(START, "answer_node") # Define the starting edge
+builder.add_edge("answer_node", END) # Define the ending edge
+graph = builder.compile() # Compile the graph
+
+# Invoke the graph with an input and print the result
+print(graph.invoke({"question": "hi"}))
+```
+```
+{'answer': 'bye'}
+```
+
+Notice that the output of invoke only includes the output schema.
+
+### Pass private state between nodes
+
+In some cases, you may want nodes to exchange information that is crucial for intermediate logic but doesn't need to be part of the main schema of the graph. This private data is not relevant to the overall input/output of the graph and should only be shared between certain nodes.
+
+Below, we'll create an example sequential graph consisting of three nodes (node_1, node_2 and node_3), where private data is passed between the first two steps (node_1 and node_2), while the third step (node_3) only has access to the public overall state.
+
+```python
+from langgraph.graph import StateGraph, START, END
+from typing_extensions import TypedDict
+
+# The overall state of the graph (this is the public state shared across nodes)
+class OverallState(TypedDict):
+ a: str
+
+# Output from node_1 contains private data that is not part of the overall state
+class Node1Output(TypedDict):
+ private_data: str
+
+# The private data is only shared between node_1 and node_2
+def node_1(state: OverallState) -> Node1Output:
+ output = {"private_data": "set by node_1"}
+ print(f"Entered node `node_1`:\n\tInput: {state}.\n\tReturned: {output}")
+ return output
+
+# Node 2 input only requests the private data available after node_1
+class Node2Input(TypedDict):
+ private_data: str
+
+def node_2(state: Node2Input) -> OverallState:
+ output = {"a": "set by node_2"}
+ print(f"Entered node `node_2`:\n\tInput: {state}.\n\tReturned: {output}")
+ return output
+
+# Node 3 only has access to the overall state (no access to private data from node_1)
+def node_3(state: OverallState) -> OverallState:
+ output = {"a": "set by node_3"}
+ print(f"Entered node `node_3`:\n\tInput: {state}.\n\tReturned: {output}")
+ return output
+
+# Connect nodes in a sequence
+# node_2 accepts private data from node_1, whereas
+# node_3 does not see the private data.
+builder = StateGraph(OverallState).add_sequence([node_1, node_2, node_3])
+builder.add_edge(START, "node_1")
+graph = builder.compile()
+
+# Invoke the graph with the initial state
+response = graph.invoke(
+ {
+ "a": "set at start",
+ }
+)
+
+print()
+print(f"Output of graph invocation: {response}")
+```
+```
+Entered node `node_1`:
+ Input: {'a': 'set at start'}.
+ Returned: {'private_data': 'set by node_1'}
+Entered node `node_2`:
+ Input: {'private_data': 'set by node_1'}.
+ Returned: {'a': 'set by node_2'}
+Entered node `node_3`:
+ Input: {'a': 'set by node_2'}.
+ Returned: {'a': 'set by node_3'}
+
+Output of graph invocation: {'a': 'set by node_3'}
+```
+
+### Use Pydantic models for graph state
+
+A [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs.md#langgraph.graph.StateGraph) accepts a `state_schema` argument on initialization that specifies the "shape" of the state that the nodes in the graph can access and update.
+
+In our examples, we typically use a python-native `TypedDict` or [`dataclass`](https://docs.python.org/3/library/dataclasses.html) for `state_schema`, but `state_schema` can be any [type](https://docs.python.org/3/library/stdtypes.html#type-objects).
+
+Here, we'll see how a [Pydantic BaseModel](https://docs.pydantic.dev/latest/api/base_model/) can be used for `state_schema` to add run-time validation on **inputs**.
+
+!!! note "Known Limitations"
+ - Currently, the output of the graph will **NOT** be an instance of a pydantic model.
+ - Run-time validation only occurs on inputs into nodes, not on the outputs.
+ - The validation error trace from pydantic does not show which node the error arises in.
+ - Pydantic's recursive validation can be slow. For performance-sensitive applications, you may want to consider using a `dataclass` instead.
+
+```python
+from langgraph.graph import StateGraph, START, END
+from typing_extensions import TypedDict
+from pydantic import BaseModel
+
+# The overall state of the graph (this is the public state shared across nodes)
+class OverallState(BaseModel):
+ a: str
+
+def node(state: OverallState):
+ return {"a": "goodbye"}
+
+# Build the state graph
+builder = StateGraph(OverallState)
+builder.add_node(node) # node_1 is the first node
+builder.add_edge(START, "node") # Start the graph with node_1
+builder.add_edge("node", END) # End the graph after node_1
+graph = builder.compile()
+
+# Test the graph with a valid input
+graph.invoke({"a": "hello"})
+```
+
+Invoke the graph with an **invalid** input
+
+```python
+try:
+ graph.invoke({"a": 123}) # Should be a string
+except Exception as e:
+ print("An exception was raised because `a` is an integer rather than a string.")
+ print(e)
+```
+```
+An exception was raised because `a` is an integer rather than a string.
+1 validation error for OverallState
+a
+ Input should be a valid string [type=string_type, input_value=123, input_type=int]
+ For further information visit https://errors.pydantic.dev/2.9/v/string_type
+```
+
+See below for additional features of Pydantic model state:
+
+??? example "Serialization Behavior"
+
+ When using Pydantic models as state schemas, it's important to understand how serialization works, especially when:
+ - Passing Pydantic objects as inputs
+ - Receiving outputs from the graph
+ - Working with nested Pydantic models
+
+ Let's see these behaviors in action.
+
+ ```python
+ from langgraph.graph import StateGraph, START, END
+ from pydantic import BaseModel
+
+ class NestedModel(BaseModel):
+ value: str
+
+ class ComplexState(BaseModel):
+ text: str
+ count: int
+ nested: NestedModel
+
+ def process_node(state: ComplexState):
+ # Node receives a validated Pydantic object
+ print(f"Input state type: {type(state)}")
+ print(f"Nested type: {type(state.nested)}")
+ # Return a dictionary update
+ return {"text": state.text + " processed", "count": state.count + 1}
+
+ # Build the graph
+ builder = StateGraph(ComplexState)
+ builder.add_node("process", process_node)
+ builder.add_edge(START, "process")
+ builder.add_edge("process", END)
+ graph = builder.compile()
+
+ # Create a Pydantic instance for input
+ input_state = ComplexState(text="hello", count=0, nested=NestedModel(value="test"))
+ print(f"Input object type: {type(input_state)}")
+
+ # Invoke graph with a Pydantic instance
+ result = graph.invoke(input_state)
+ print(f"Output type: {type(result)}")
+ print(f"Output content: {result}")
+
+ # Convert back to Pydantic model if needed
+ output_model = ComplexState(**result)
+ print(f"Converted back to Pydantic: {type(output_model)}")
+ ```
+
+??? example "Runtime Type Coercion"
+
+ Pydantic performs runtime type coercion for certain data types. This can be helpful but also lead to unexpected behavior if you're not aware of it.
+
+ ```python
+ from langgraph.graph import StateGraph, START, END
+ from pydantic import BaseModel
+
+ class CoercionExample(BaseModel):
+ # Pydantic will coerce string numbers to integers
+ number: int
+ # Pydantic will parse string booleans to bool
+ flag: bool
+
+ def inspect_node(state: CoercionExample):
+ print(f"number: {state.number} (type: {type(state.number)})")
+ print(f"flag: {state.flag} (type: {type(state.flag)})")
+ return {}
+
+ builder = StateGraph(CoercionExample)
+ builder.add_node("inspect", inspect_node)
+ builder.add_edge(START, "inspect")
+ builder.add_edge("inspect", END)
+ graph = builder.compile()
+
+ # Demonstrate coercion with string inputs that will be converted
+ result = graph.invoke({"number": "42", "flag": "true"})
+
+ # This would fail with a validation error
+ try:
+ graph.invoke({"number": "not-a-number", "flag": "true"})
+ except Exception as e:
+ print(f"\nExpected validation error: {e}")
+ ```
+
+??? example "Working with Message Models"
+
+ When working with LangChain message types in your state schema, there are important considerations for serialization. You should use `AnyMessage` (rather than `BaseMessage`) for proper serialization/deserialization when using message objects over the wire.
+
+ ```python
+ from langgraph.graph import StateGraph, START, END
+ from pydantic import BaseModel
+ from langchain_core.messages import HumanMessage, AIMessage, AnyMessage
+ from typing import List
+
+ class ChatState(BaseModel):
+ messages: List[AnyMessage]
+ context: str
+
+ def add_message(state: ChatState):
+ return {"messages": state.messages + [AIMessage(content="Hello there!")]}
+
+ builder = StateGraph(ChatState)
+ builder.add_node("add_message", add_message)
+ builder.add_edge(START, "add_message")
+ builder.add_edge("add_message", END)
+ graph = builder.compile()
+
+ # Create input with a message
+ initial_state = ChatState(
+ messages=[HumanMessage(content="Hi")], context="Customer support chat"
+ )
+
+ result = graph.invoke(initial_state)
+ print(f"Output: {result}")
+
+ # Convert back to Pydantic model to see message types
+ output_model = ChatState(**result)
+ for i, msg in enumerate(output_model.messages):
+ print(f"Message {i}: {type(msg).__name__} - {msg.content}")
+ ```
+
+## Add runtime configuration
+
+Sometimes you want to be able to configure your graph when calling it. For example, you might want to be able to specify what LLM or system prompt to use at runtime, *without polluting the graph state with these parameters*.
+
+To add runtime configuration:
+
+1. Specify a schema for your configuration
+2. Add the configuration to the function signature for nodes or conditional edges
+3. Pass the configuration into the graph.
+
+See below for a simple example:
+
+```python
+from langchain_core.runnables import RunnableConfig
+from langgraph.graph import END, StateGraph, START
+from typing_extensions import TypedDict
+
+# 1. Specify config schema
+class ConfigSchema(TypedDict):
+ my_runtime_value: str
+
+# 2. Define a graph that accesses the config in a node
+class State(TypedDict):
+ my_state_value: str
+
+# highlight-next-line
+def node(state: State, config: RunnableConfig):
+ # highlight-next-line
+ if config["configurable"]["my_runtime_value"] == "a":
+ return {"my_state_value": 1}
+ # highlight-next-line
+ elif config["configurable"]["my_runtime_value"] == "b":
+ return {"my_state_value": 2}
+ else:
+ raise ValueError("Unknown values.")
+
+# highlight-next-line
+builder = StateGraph(State, config_schema=ConfigSchema)
+builder.add_node(node)
+builder.add_edge(START, "node")
+builder.add_edge("node", END)
+
+graph = builder.compile()
+
+# 3. Pass in configuration at runtime:
+# highlight-next-line
+print(graph.invoke({}, {"configurable": {"my_runtime_value": "a"}}))
+# highlight-next-line
+print(graph.invoke({}, {"configurable": {"my_runtime_value": "b"}}))
+```
+```
+{'my_state_value': 1}
+{'my_state_value': 2}
+```
+
+??? example "Extended example: specifying LLM at runtime"
+ Below we demonstrate a practical example in which we configure what LLM to use at runtime. We will use both OpenAI and Anthropic models.
+
+ ```python
+ from langchain.chat_models import init_chat_model
+ from langchain_core.runnables import RunnableConfig
+ from langgraph.graph import MessagesState
+ from langgraph.graph import END, StateGraph, START
+ from typing_extensions import TypedDict
+
+ class ConfigSchema(TypedDict):
+ model: str
+
+ MODELS = {
+ "anthropic": init_chat_model("anthropic:claude-3-5-haiku-latest"),
+ "openai": init_chat_model("openai:gpt-4.1-mini"),
+ }
+
+ def call_model(state: MessagesState, config: RunnableConfig):
+ model = config["configurable"].get("model", "anthropic")
+ model = MODELS[model]
+ response = model.invoke(state["messages"])
+ return {"messages": [response]}
+
+ builder = StateGraph(MessagesState, config_schema=ConfigSchema)
+ builder.add_node("model", call_model)
+ builder.add_edge(START, "model")
+ builder.add_edge("model", END)
+
+ graph = builder.compile()
+
+ # Usage
+ input_message = {"role": "user", "content": "hi"}
+ # With no configuration, uses default (Anthropic)
+ response_1 = graph.invoke({"messages": [input_message]})["messages"][-1]
+ # Or, can set OpenAI
+ config = {"configurable": {"model": "openai"}}
+ response_2 = graph.invoke({"messages": [input_message]}, config=config)["messages"][-1]
+
+ print(response_1.response_metadata["model_name"])
+ print(response_2.response_metadata["model_name"])
+ ```
+ ```
+ claude-3-5-haiku-20241022
+ gpt-4.1-mini-2025-04-14
+ ```
+
+??? example "Extended example: specifying model and system message at runtime"
+ Below we demonstrate a practical example in which we configure two parameters: the LLM and system message to use at runtime.
+
+ ```python
+ from typing import Optional
+ from langchain.chat_models import init_chat_model
+ from langchain_core.messages import SystemMessage
+ from langchain_core.runnables import RunnableConfig
+ from langgraph.graph import END, MessagesState, StateGraph, START
+ from typing_extensions import TypedDict
+
+ class ConfigSchema(TypedDict):
+ model: Optional[str]
+ system_message: Optional[str]
+
+ MODELS = {
+ "anthropic": init_chat_model("anthropic:claude-3-5-haiku-latest"),
+ "openai": init_chat_model("openai:gpt-4.1-mini"),
+ }
+
+ def call_model(state: MessagesState, config: RunnableConfig):
+ model = config["configurable"].get("model", "anthropic")
+ model = MODELS[model]
+ messages = state["messages"]
+ if system_message := config["configurable"].get("system_message"):
+ messages = [SystemMessage(system_message)] + messages
+ response = model.invoke(messages)
+ return {"messages": [response]}
+
+ builder = StateGraph(MessagesState, config_schema=ConfigSchema)
+ builder.add_node("model", call_model)
+ builder.add_edge(START, "model")
+ builder.add_edge("model", END)
+
+ graph = builder.compile()
+
+ # Usage
+ input_message = {"role": "user", "content": "hi"}
+ config = {"configurable": {"model": "openai", "system_message": "Respond in Italian."}}
+ response = graph.invoke({"messages": [input_message]}, config)
+ for message in response["messages"]:
+ message.pretty_print()
+ ```
+ ```
+ ================================ Human Message ================================
+
+ hi
+ ================================== Ai Message ==================================
+
+ Ciao! Come posso aiutarti oggi?
+ ```
+
+## Add retry policies
+
+There are many use cases where you may wish for your node to have a custom retry policy, for example if you are calling an API, querying a database, or calling an LLM, etc. LangGraph lets you add retry policies to nodes.
+
+To configure a retry policy, pass the `retry_policy` parameter to the [add_node](../reference/graphs.md#langgraph.graph.state.StateGraph.add_node). The `retry_policy` parameter takes in a `RetryPolicy` named tuple object. Below we instantiate a `RetryPolicy` object with the default parameters and associate it with a node:
+
+```python
+from langgraph.pregel import RetryPolicy
+
+builder.add_node(
+ "node_name",
+ node_function,
+ retry_policy=RetryPolicy(),
+)
+```
+
+By default, the `retry_on` parameter uses the `default_retry_on` function, which retries on any exception except for the following:
+
+* `ValueError`
+* `TypeError`
+* `ArithmeticError`
+* `ImportError`
+* `LookupError`
+* `NameError`
+* `SyntaxError`
+* `RuntimeError`
+* `ReferenceError`
+* `StopIteration`
+* `StopAsyncIteration`
+* `OSError`
+
+In addition, for exceptions from popular http request libraries such as `requests` and `httpx` it only retries on 5xx status codes.
+
+??? example "Extended example: customizing retry policies"
+ Consider an example in which we are reading from a SQL database. Below we pass two different retry policies to nodes:
+
+ ```python
+ import sqlite3
+ from typing_extensions import TypedDict
+ from langchain.chat_models import init_chat_model
+ from langgraph.graph import END, MessagesState, StateGraph, START
+ from langgraph.pregel import RetryPolicy
+ from langchain_community.utilities import SQLDatabase
+ from langchain_core.messages import AIMessage
+
+ db = SQLDatabase.from_uri("sqlite:///:memory:")
+ model = init_chat_model("anthropic:claude-3-5-haiku-latest")
+
+ def query_database(state: MessagesState):
+ query_result = db.run("SELECT * FROM Artist LIMIT 10;")
+ return {"messages": [AIMessage(content=query_result)]}
+
+ def call_model(state: MessagesState):
+ response = model.invoke(state["messages"])
+ return {"messages": [response]}
+
+ # Define a new graph
+ builder = StateGraph(MessagesState)
+ builder.add_node(
+ "query_database",
+ query_database,
+ retry_policy=RetryPolicy(retry_on=sqlite3.OperationalError),
+ )
+ builder.add_node("model", call_model, retry_policy=RetryPolicy(max_attempts=5))
+ builder.add_edge(START, "model")
+ builder.add_edge("model", "query_database")
+ builder.add_edge("query_database", END)
+ graph = builder.compile()
+ ```
+
+## Add node caching
+
+Node caching is useful in cases where you want to avoid repeating operations, like when doing something expensive (either in terms of time or cost). LangGraph lets you add individualized caching policies to nodes in a graph.
+
+To configure a cache policy, pass the `cache_policy` parameter to the [add_node](https://langchain-ai.github.io/langgraph/reference/graphs.md#langgraph.graph.state.StateGraph.add_node) function. In the following example, a [`CachePolicy`](https://langchain-ai.github.io/langgraph/reference/types/?h=cachepolicy#langgraph.types.CachePolicy) object is instantiated with a time to live of 120 seconds and the default `key_func` generator. Then it is associated with a node:
+
+```python
+from langgraph.types import CachePolicy
+
+builder.add_node(
+ "node_name",
+ node_function,
+ cache_policy=CachePolicy(ttl=120),
+)
+```
+
+Then, to enable node-level caching for a graph, set the `cache` argument when compiling the graph. The example below uses `InMemoryCache` to set up a graph with in-memory cache, but `SqliteCache` is also available.
+
+```python
+from langgraph.cache.memory import InMemoryCache
+
+graph = builder.compile(cache=InMemoryCache())
+```
+
+## Create a sequence of steps
+
+!!! info "Prerequisites"
+ This guide assumes familiarity with the above section on [state](#define-and-update-state).
+
+Here we demonstrate how to construct a simple sequence of steps. We will show:
+
+1. How to build a sequential graph
+2. Built-in short-hand for constructing similar graphs.
+
+To add a sequence of nodes, we use the `.add_node` and `.add_edge` methods of our [graph](../concepts/low_level.md#stategraph):
+
+```python
+from langgraph.graph import START, StateGraph
+
+builder = StateGraph(State)
+
+# Add nodes
+builder.add_node(step_1)
+builder.add_node(step_2)
+builder.add_node(step_3)
+
+# Add edges
+builder.add_edge(START, "step_1")
+builder.add_edge("step_1", "step_2")
+builder.add_edge("step_2", "step_3")
+```
+
+We can also use the built-in shorthand `.add_sequence`:
+
+```python
+builder = StateGraph(State).add_sequence([step_1, step_2, step_3])
+builder.add_edge(START, "step_1")
+```
+
+??? info "Why split application steps into a sequence with LangGraph?"
+ LangGraph makes it easy to add an underlying persistence layer to your application.
+ This allows state to be checkpointed in between the execution of nodes, so your LangGraph nodes govern:
+
+ - How state updates are [checkpointed](../concepts/persistence.md)
+ - How interruptions are resumed in [human-in-the-loop](../concepts/human_in_the_loop.md) workflows
+ - How we can "rewind" and branch-off executions using LangGraph's [time travel](../concepts/time-travel.md) features
+
+ They also determine how execution steps are [streamed](../concepts/streaming.md), and how your application is visualized
+ and debugged using [LangGraph Studio](../concepts/langgraph_studio.md).
+
+Let's demonstrate an end-to-end example. We will create a sequence of three steps:
+
+1. Populate a value in a key of the state
+2. Update the same value
+3. Populate a different value
+
+Let's first define our [state](../concepts/low_level.md#state). This governs the [schema of the graph](../concepts/low_level.md#schema), and can also specify how to apply updates. See [this section](#process-state-updates-with-reducers) for more detail.
+
+In our case, we will just keep track of two values:
+
+```python
+from typing_extensions import TypedDict
+
+class State(TypedDict):
+ value_1: str
+ value_2: int
+```
+
+Our [nodes](../concepts/low_level.md#nodes) are just Python functions that read our graph's state and make updates to it. The first argument to this function will always be the state:
+
+```python
+def step_1(state: State):
+ return {"value_1": "a"}
+
+def step_2(state: State):
+ current_value_1 = state["value_1"]
+ return {"value_1": f"{current_value_1} b"}
+
+def step_3(state: State):
+ return {"value_2": 10}
+```
+
+!!! note
+ Note that when issuing updates to the state, each node can just specify the value of the key it wishes to update.
+
+ By default, this will **overwrite** the value of the corresponding key. You can also use [reducers](../concepts/low_level.md#reducers) to control how updates are processed— for example, you can append successive updates to a key instead. See [this section](#process-state-updates-with-reducers) for more detail.
+
+Finally, we define the graph. We use [StateGraph](../concepts/low_level.md#stategraph) to define a graph that operates on this state.
+
+We will then use [add_node](../concepts/low_level.md#messagesstate) and [add_edge](../concepts/low_level.md#edges) to populate our graph and define its control flow.
+
+```python
+from langgraph.graph import START, StateGraph
+
+builder = StateGraph(State)
+
+# Add nodes
+builder.add_node(step_1)
+builder.add_node(step_2)
+builder.add_node(step_3)
+
+# Add edges
+builder.add_edge(START, "step_1")
+builder.add_edge("step_1", "step_2")
+builder.add_edge("step_2", "step_3")
+```
+
+!!! tip "Specifying custom names"
+ You can specify custom names for nodes using `.add_node`:
+
+ ```python
+ builder.add_node("my_node", step_1)
+ ```
+
+Note that:
+
+- `.add_edge` takes the names of nodes, which for functions defaults to `node.__name__`.
+- We must specify the entry point of the graph. For this we add an edge with the [START node](../concepts/low_level.md#start-node).
+- The graph halts when there are no more nodes to execute.
+
+We next [compile](../concepts/low_level.md#compiling-your-graph) our graph. This provides a few basic checks on the structure of the graph (e.g., identifying orphaned nodes). If we were adding persistence to our application via a [checkpointer](../concepts/persistence.md), it would also be passed in here.
+
+```python
+graph = builder.compile()
+```
+
+LangGraph provides built-in utilities for visualizing your graph. Let's inspect our sequence. See [this guide](#visualize-your-graph) for detail on visualization.
+
+```python
+from IPython.display import Image, display
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+Let's proceed with a simple invocation:
+
+```python
+graph.invoke({"value_1": "c"})
+```
+```
+{'value_1': 'a b', 'value_2': 10}
+```
+
+Note that:
+
+- We kicked off invocation by providing a value for a single state key. We must always provide a value for at least one key.
+- The value we passed in was overwritten by the first node.
+- The second node updated the value.
+- The third node populated a different value.
+
+!!! tip "Built-in shorthand"
+ `langgraph>=0.2.46` includes a built-in short-hand `add_sequence` for adding node sequences. You can compile the same graph as follows:
+
+ ```python
+ # highlight-next-line
+ builder = StateGraph(State).add_sequence([step_1, step_2, step_3])
+ builder.add_edge(START, "step_1")
+
+ graph = builder.compile()
+
+ graph.invoke({"value_1": "c"})
+ ```
+
+## Create branches
+
+Parallel execution of nodes is essential to speed up overall graph operation. LangGraph offers native support for parallel execution of nodes, which can significantly enhance the performance of graph-based workflows. This parallelization is achieved through fan-out and fan-in mechanisms, utilizing both standard edges and [conditional_edges](https://langchain-ai.github.io/langgraph/reference/graphs.md#langgraph.graph.MessageGraph.add_conditional_edges). Below are some examples showing how to add create branching dataflows that work for you.
+
+### Run graph nodes in parallel
+
+In this example, we fan out from `Node A` to `B and C` and then fan in to `D`. With our state, [we specify the reducer add operation](https://langchain-ai.github.io/langgraph/concepts/low_level.md#reducers). This will combine or accumulate values for the specific key in the State, rather than simply overwriting the existing value. For lists, this means concatenating the new list with the existing list. See the above section on [state reducers](#process-state-updates-with-reducers) for more detail on updating state with reducers.
+
+```python
+import operator
+from typing import Annotated, Any
+from typing_extensions import TypedDict
+from langgraph.graph import StateGraph, START, END
+
+class State(TypedDict):
+ # The operator.add reducer fn makes this append-only
+ aggregate: Annotated[list, operator.add]
+
+def a(state: State):
+ print(f'Adding "A" to {state["aggregate"]}')
+ return {"aggregate": ["A"]}
+
+def b(state: State):
+ print(f'Adding "B" to {state["aggregate"]}')
+ return {"aggregate": ["B"]}
+
+def c(state: State):
+ print(f'Adding "C" to {state["aggregate"]}')
+ return {"aggregate": ["C"]}
+
+def d(state: State):
+ print(f'Adding "D" to {state["aggregate"]}')
+ return {"aggregate": ["D"]}
+
+builder = StateGraph(State)
+builder.add_node(a)
+builder.add_node(b)
+builder.add_node(c)
+builder.add_node(d)
+builder.add_edge(START, "a")
+builder.add_edge("a", "b")
+builder.add_edge("a", "c")
+builder.add_edge("b", "d")
+builder.add_edge("c", "d")
+builder.add_edge("d", END)
+graph = builder.compile()
+```
+
+```python
+from IPython.display import Image, display
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+With the reducer, you can see that the values added in each node are accumulated.
+
+```python
+graph.invoke({"aggregate": []}, {"configurable": {"thread_id": "foo"}})
+```
+```
+Adding "A" to []
+Adding "B" to ['A']
+Adding "C" to ['A']
+Adding "D" to ['A', 'B', 'C']
+```
+
+!!! note
+ In the above example, nodes `"b"` and `"c"` are executed concurrently in the same [superstep](../concepts/low_level.md#graphs). Because they are in the same step, node `"d"` executes after both `"b"` and `"c"` are finished.
+
+ Importantly, updates from a parallel superstep may not be ordered consistently. If you need a consistent, predetermined ordering of updates from a parallel superstep, you should write the outputs to a separate field in the state together with a value with which to order them.
+
+??? note "Exception handling?"
+ LangGraph executes nodes within [supersteps](../concepts/low_level.md#graphs), meaning that while parallel branches are executed in parallel, the entire superstep is **transactional**. If any of these branches raises an exception, **none** of the updates are applied to the state (the entire superstep errors).
+
+ Importantly, when using a [checkpointer](../concepts/persistence.md), results from successful nodes within a superstep are saved, and don't repeat when resumed.
+
+ If you have error-prone (perhaps want to handle flakey API calls), LangGraph provides two ways to address this:
+
+ 1. You can write regular python code within your node to catch and handle exceptions.
+ 2. You can set a **[retry_policy](../reference/types.md#langgraph.types.RetryPolicy)** to direct the graph to retry nodes that raise certain types of exceptions. Only failing branches are retried, so you needn't worry about performing redundant work.
+
+ Together, these let you perform parallel execution and fully control exception handling.
+
+### Defer node execution
+
+Deferring node execution is useful when you want to delay the execution of a node until all other pending tasks are completed. This is particularly relevant when branches have different lengths, which is common in workflows like map-reduce flows.
+
+The above example showed how to fan-out and fan-in when each path was only one step. But what if one branch had more than one step? Let's add a node `"b_2"` in the `"b"` branch:
+
+```python
+import operator
+from typing import Annotated, Any
+from typing_extensions import TypedDict
+from langgraph.graph import StateGraph, START, END
+
+class State(TypedDict):
+ # The operator.add reducer fn makes this append-only
+ aggregate: Annotated[list, operator.add]
+
+def a(state: State):
+ print(f'Adding "A" to {state["aggregate"]}')
+ return {"aggregate": ["A"]}
+
+def b(state: State):
+ print(f'Adding "B" to {state["aggregate"]}')
+ return {"aggregate": ["B"]}
+
+def b_2(state: State):
+ print(f'Adding "B_2" to {state["aggregate"]}')
+ return {"aggregate": ["B_2"]}
+
+def c(state: State):
+ print(f'Adding "C" to {state["aggregate"]}')
+ return {"aggregate": ["C"]}
+
+def d(state: State):
+ print(f'Adding "D" to {state["aggregate"]}')
+ return {"aggregate": ["D"]}
+
+builder = StateGraph(State)
+builder.add_node(a)
+builder.add_node(b)
+builder.add_node(b_2)
+builder.add_node(c)
+# highlight-next-line
+builder.add_node(d, defer=True)
+builder.add_edge(START, "a")
+builder.add_edge("a", "b")
+builder.add_edge("a", "c")
+builder.add_edge("b", "b_2")
+builder.add_edge("b_2", "d")
+builder.add_edge("c", "d")
+builder.add_edge("d", END)
+graph = builder.compile()
+```
+
+```python
+from IPython.display import Image, display
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+```python
+graph.invoke({"aggregate": []})
+```
+```
+Adding "A" to []
+Adding "B" to ['A']
+Adding "C" to ['A']
+Adding "B_2" to ['A', 'B', 'C']
+Adding "D" to ['A', 'B', 'C', 'B_2']
+```
+
+In the above example, nodes `"b"` and `"c"` are executed concurrently in the same superstep. We set `defer=True` on node `d` so it will not execute until all pending tasks are finished. In this case, this means that `"d"` waits to execute until the entire `"b"` branch is finished.
+
+### Conditional branching
+
+If your fan-out should vary at runtime based on the state, you can use [add_conditional_edges](https://langchain-ai.github.io/langgraph/reference/graphs.md#langgraph.graph.StateGraph.add_conditional_edges) to select one or more paths using the graph state. See example below, where node `a` generates a state update that determines the following node.
+
+```python
+import operator
+from typing import Annotated, Literal, Sequence
+from typing_extensions import TypedDict
+from langgraph.graph import StateGraph, START, END
+
+class State(TypedDict):
+ aggregate: Annotated[list, operator.add]
+ # Add a key to the state. We will set this key to determine
+ # how we branch.
+ which: str
+
+def a(state: State):
+ print(f'Adding "A" to {state["aggregate"]}')
+ # highlight-next-line
+ return {"aggregate": ["A"], "which": "c"}
+
+def b(state: State):
+ print(f'Adding "B" to {state["aggregate"]}')
+ return {"aggregate": ["B"]}
+
+def c(state: State):
+ print(f'Adding "C" to {state["aggregate"]}')
+ return {"aggregate": ["C"]}
+
+builder = StateGraph(State)
+builder.add_node(a)
+builder.add_node(b)
+builder.add_node(c)
+builder.add_edge(START, "a")
+builder.add_edge("b", END)
+builder.add_edge("c", END)
+
+def conditional_edge(state: State) -> Literal["b", "c"]:
+ # Fill in arbitrary logic here that uses the state
+ # to determine the next node
+ return state["which"]
+
+# highlight-next-line
+builder.add_conditional_edges("a", conditional_edge)
+
+graph = builder.compile()
+```
+
+```python
+from IPython.display import Image, display
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+```python
+result = graph.invoke({"aggregate": []})
+print(result)
+```
+```
+Adding "A" to []
+Adding "C" to ['A']
+{'aggregate': ['A', 'C'], 'which': 'c'}
+```
+
+!!! tip
+ Your conditional edges can route to multiple destination nodes. For example:
+
+ ```python
+ def route_bc_or_cd(state: State) -> Sequence[str]:
+ if state["which"] == "cd":
+ return ["c", "d"]
+ return ["b", "c"]
+ ```
+
+## Map-Reduce and the Send API
+
+LangGraph supports map-reduce and other advanced branching patterns using the Send API. Here is an example of how to use it:
+
+```python
+from langgraph.graph import StateGraph, START, END
+from langgraph.types import Send
+from typing_extensions import TypedDict
+
+class OverallState(TypedDict):
+ topic: str
+ subjects: list[str]
+ jokes: list[str]
+ best_selected_joke: str
+
+def generate_topics(state: OverallState):
+ return {"subjects": ["lions", "elephants", "penguins"]}
+
+def generate_joke(state: OverallState):
+ joke_map = {
+ "lions": "Why don't lions like fast food? Because they can't catch it!",
+ "elephants": "Why don't elephants use computers? They're afraid of the mouse!",
+ "penguins": "Why don't penguins like talking to strangers at parties? Because they find it hard to break the ice."
+ }
+ return {"jokes": [joke_map[state["subject"]]]}
+
+def continue_to_jokes(state: OverallState):
+ return [Send("generate_joke", {"subject": s}) for s in state["subjects"]]
+
+def best_joke(state: OverallState):
+ return {"best_selected_joke": "penguins"}
+
+builder = StateGraph(OverallState)
+builder.add_node("generate_topics", generate_topics)
+builder.add_node("generate_joke", generate_joke)
+builder.add_node("best_joke", best_joke)
+builder.add_edge(START, "generate_topics")
+builder.add_conditional_edges("generate_topics", continue_to_jokes, ["generate_joke"])
+builder.add_edge("generate_joke", "best_joke")
+builder.add_edge("best_joke", END)
+builder.add_edge("generate_topics", END)
+graph = builder.compile()
+```
+
+```python
+from IPython.display import Image, display
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+```python
+# Call the graph: here we call it to generate a list of jokes
+for step in graph.stream({"topic": "animals"}):
+ print(step)
+```
+```
+{'generate_topics': {'subjects': ['lions', 'elephants', 'penguins']}}
+{'generate_joke': {'jokes': ["Why don't lions like fast food? Because they can't catch it!"]}}
+{'generate_joke': {'jokes': ["Why don't elephants use computers? They're afraid of the mouse!"]}}
+{'generate_joke': {'jokes': ['Why don't penguins like talking to strangers at parties? Because they find it hard to break the ice.']}}
+{'best_joke': {'best_selected_joke': 'penguins'}}
+```
+
+## Create and control loops
+
+When creating a graph with a loop, we require a mechanism for terminating execution. This is most commonly done by adding a [conditional edge](../concepts/low_level.md#conditional-edges) that routes to the [END](../concepts/low_level.md#end-node) node once we reach some termination condition.
+
+You can also set the graph recursion limit when invoking or streaming the graph. The recursion limit sets the number of [supersteps](../concepts/low_level.md#graphs) that the graph is allowed to execute before it raises an error. Read more about the concept of recursion limits [here](../concepts/low_level.md#recursion-limit).
+
+Let's consider a simple graph with a loop to better understand how these mechanisms work.
+
+!!! tip
+ To return the last value of your state instead of receiving a recursion limit error, see the [next section](#impose-a-recursion-limit).
+
+When creating a loop, you can include a conditional edge that specifies a termination condition:
+
+```python
+builder = StateGraph(State)
+builder.add_node(a)
+builder.add_node(b)
+
+def route(state: State) -> Literal["b", END]:
+ if termination_condition(state):
+ return END
+ else:
+ return "b"
+
+builder.add_edge(START, "a")
+builder.add_conditional_edges("a", route)
+builder.add_edge("b", "a")
+graph = builder.compile()
+```
+
+To control the recursion limit, specify `"recursion_limit"` in the config. This will raise a `GraphRecursionError`, which you can catch and handle:
+
+```python
+from langgraph.errors import GraphRecursionError
+
+try:
+ graph.invoke(inputs, {"recursion_limit": 3})
+except GraphRecursionError:
+ print("Recursion Error")
+```
+
+Let's define a graph with a simple loop. Note that we use a conditional edge to implement a termination condition.
+
+```python
+import operator
+from typing import Annotated, Literal
+from typing_extensions import TypedDict
+from langgraph.graph import StateGraph, START, END
+
+class State(TypedDict):
+ # The operator.add reducer fn makes this append-only
+ aggregate: Annotated[list, operator.add]
+
+def a(state: State):
+ print(f'Node A sees {state["aggregate"]}')
+ return {"aggregate": ["A"]}
+
+def b(state: State):
+ print(f'Node B sees {state["aggregate"]}')
+ return {"aggregate": ["B"]}
+
+# Define nodes
+builder = StateGraph(State)
+builder.add_node(a)
+builder.add_node(b)
+
+# Define edges
+def route(state: State) -> Literal["b", END]:
+ if len(state["aggregate"]) < 7:
+ return "b"
+ else:
+ return END
+
+builder.add_edge(START, "a")
+builder.add_conditional_edges("a", route)
+builder.add_edge("b", "a")
+graph = builder.compile()
+```
+
+```python
+from IPython.display import Image, display
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+This architecture is similar to a [ReAct agent](../agents/overview.md) in which node `"a"` is a tool-calling model, and node `"b"` represents the tools.
+
+In our `route` conditional edge, we specify that we should end after the `"aggregate"` list in the state passes a threshold length.
+
+Invoking the graph, we see that we alternate between nodes `"a"` and `"b"` before terminating once we reach the termination condition.
+
+```python
+graph.invoke({"aggregate": []})
+```
+```
+Node A sees []
+Node B sees ['A']
+Node A sees ['A', 'B']
+Node B sees ['A', 'B', 'A']
+Node A sees ['A', 'B', 'A', 'B']
+Node B sees ['A', 'B', 'A', 'B', 'A']
+Node A sees ['A', 'B', 'A', 'B', 'A', 'B']
+```
+
+### Impose a recursion limit
+
+In some applications, we may not have a guarantee that we will reach a given termination condition. In these cases, we can set the graph's [recursion limit](../concepts/low_level.md#recursion-limit). This will raise a `GraphRecursionError` after a given number of [supersteps](../concepts/low_level.md#graphs). We can then catch and handle this exception:
+
+```python
+from langgraph.errors import GraphRecursionError
+
+try:
+ graph.invoke({"aggregate": []}, {"recursion_limit": 4})
+except GraphRecursionError:
+ print("Recursion Error")
+```
+```
+Node A sees []
+Node B sees ['A']
+Node C sees ['A', 'B']
+Node D sees ['A', 'B']
+Node A sees ['A', 'B', 'C', 'D']
+Recursion Error
+```
+
+??? example "Extended example: return state on hitting recursion limit"
+
+ Instead of raising `GraphRecursionError`, we can introduce a new key to the state that keeps track of the number of steps remaining until reaching the recursion limit. We can then use this key to determine if we should end the run.
+
+ LangGraph implements a special `RemainingSteps` annotation. Under the hood, it creates a `ManagedValue` channel -- a state channel that will exist for the duration of our graph run and no longer.
+
+ ```python
+ import operator
+ from typing import Annotated, Literal
+ from typing_extensions import TypedDict
+ from langgraph.graph import StateGraph, START, END
+ from langgraph.managed.is_last_step import RemainingSteps
+
+ class State(TypedDict):
+ aggregate: Annotated[list, operator.add]
+ remaining_steps: RemainingSteps
+
+ def a(state: State):
+ print(f'Node A sees {state["aggregate"]}')
+ return {"aggregate": ["A"]}
+
+ def b(state: State):
+ print(f'Node B sees {state["aggregate"]}')
+ return {"aggregate": ["B"]}
+
+ # Define nodes
+ builder = StateGraph(State)
+ builder.add_node(a)
+ builder.add_node(b)
+
+ # Define edges
+ def route(state: State) -> Literal["b", END]:
+ if state["remaining_steps"] <= 2:
+ return END
+ else:
+ return "b"
+
+ builder.add_edge(START, "a")
+ builder.add_conditional_edges("a", route)
+ builder.add_edge("b", "a")
+ graph = builder.compile()
+
+ # Test it out
+ result = graph.invoke({"aggregate": []}, {"recursion_limit": 4})
+ print(result)
+ ```
+ ```
+ Node A sees []
+ Node B sees ['A']
+ Node A sees ['A', 'B']
+ {'aggregate': ['A', 'B', 'A']}
+ ```
+
+??? example "Extended example: loops with branches"
+
+ To better understand how the recursion limit works, let's consider a more complex example. Below we implement a loop, but one step fans out into two nodes:
+
+ ```python
+ import operator
+ from typing import Annotated, Literal
+ from typing_extensions import TypedDict
+ from langgraph.graph import StateGraph, START, END
+
+ class State(TypedDict):
+ aggregate: Annotated[list, operator.add]
+
+ def a(state: State):
+ print(f'Node A sees {state["aggregate"]}')
+ return {"aggregate": ["A"]}
+
+ def b(state: State):
+ print(f'Node B sees {state["aggregate"]}')
+ return {"aggregate": ["B"]}
+
+ def c(state: State):
+ print(f'Node C sees {state["aggregate"]}')
+ return {"aggregate": ["C"]}
+
+ def d(state: State):
+ print(f'Node D sees {state["aggregate"]}')
+ return {"aggregate": ["D"]}
+
+ # Define nodes
+ builder = StateGraph(State)
+ builder.add_node(a)
+ builder.add_node(b)
+ builder.add_node(c)
+ builder.add_node(d)
+
+ # Define edges
+ def route(state: State) -> Literal["b", END]:
+ if len(state["aggregate"]) < 7:
+ return "b"
+ else:
+ return END
+
+ builder.add_edge(START, "a")
+ builder.add_conditional_edges("a", route)
+ builder.add_edge("b", "c")
+ builder.add_edge("b", "d")
+ builder.add_edge(["c", "d"], "a")
+ graph = builder.compile()
+ ```
+
+ ```python
+ from IPython.display import Image, display
+
+ display(Image(graph.get_graph().draw_mermaid_png()))
+ ```
+
+ 
+
+ This graph looks complex, but can be conceptualized as loop of [supersteps](../concepts/low_level.md#graphs):
+
+ 1. Node A
+ 2. Node B
+ 3. Nodes C and D
+ 4. Node A
+ 5. ...
+
+ We have a loop of four supersteps, where nodes C and D are executed concurrently.
+
+ Invoking the graph as before, we see that we complete two full "laps" before hitting the termination condition:
+
+ ```python
+ result = graph.invoke({"aggregate": []})
+ ```
+ ```
+ Node A sees []
+ Node B sees ['A']
+ Node D sees ['A', 'B']
+ Node C sees ['A', 'B']
+ Node A sees ['A', 'B', 'C', 'D']
+ Node B sees ['A', 'B', 'C', 'D', 'A']
+ Node D sees ['A', 'B', 'C', 'D', 'A', 'B']
+ Node C sees ['A', 'B', 'C', 'D', 'A', 'B']
+ Node A sees ['A', 'B', 'C', 'D', 'A', 'B', 'C', 'D']
+ ```
+
+ However, if we set the recursion limit to four, we only complete one lap because each lap is four supersteps:
+
+ ```python
+ from langgraph.errors import GraphRecursionError
+
+ try:
+ result = graph.invoke({"aggregate": []}, {"recursion_limit": 4})
+ except GraphRecursionError:
+ print("Recursion Error")
+ ```
+ ```
+ Node A sees []
+ Node B sees ['A']
+ Node C sees ['A', 'B']
+ Node D sees ['A', 'B']
+ Node A sees ['A', 'B', 'C', 'D']
+ Recursion Error
+ ```
+
+## Async
+
+Using the [async](https://docs.python.org/3/library/asyncio.html) programming paradigm can produce significant performance improvements when running [IO-bound](https://en.wikipedia.org/wiki/I/O_bound) code concurrently (e.g., making concurrent API requests to a chat model provider).
+
+To convert a `sync` implementation of the graph to an `async` implementation, you will need to:
+
+1. Update `nodes` use `async def` instead of `def`.
+2. Update the code inside to use `await` appropriately.
+3. Invoke the graph with `.ainvoke` or `.astream` as desired.
+
+Because many LangChain objects implement the [Runnable Protocol](https://python.langchain.com/docs/expression_language/interface/) which has `async` variants of all the `sync` methods it's typically fairly quick to upgrade a `sync` graph to an `async` graph.
+
+See example below. To demonstrate async invocations of underlying LLMs, we will include a chat model:
+
+{% include-markdown "../../snippets/chat_model_tabs.md" %}
+
+```python
+from langchain.chat_models import init_chat_model
+from langgraph.graph import MessagesState, StateGraph
+
+# highlight-next-line
+async def node(state: MessagesState): # (1)!
+ # highlight-next-line
+ new_message = await llm.ainvoke(state["messages"]) # (2)!
+ return {"messages": [new_message]}
+
+builder = StateGraph(MessagesState).add_node(node).set_entry_point("node")
+graph = builder.compile()
+
+input_message = {"role": "user", "content": "Hello"}
+# highlight-next-line
+result = await graph.ainvoke({"messages": [input_message]}) # (3)!
+```
+
+1. Declare nodes to be async functions.
+2. Use async invocations when available within the node.
+3. Use async invocations on the graph object itself.
+
+!!! tip "Async streaming"
+ See the [streaming guide](./streaming.md) for examples of streaming with async.
+
+## Combine control flow and state updates with `Command`
+
+It can be useful to combine control flow (edges) and state updates (nodes). For example, you might want to BOTH perform state updates AND decide which node to go to next in the SAME node. LangGraph provides a way to do so by returning a [Command](../reference/types.md#langgraph.types.Command) object from node functions:
+
+```python
+def my_node(state: State) -> Command[Literal["my_other_node"]]:
+ return Command(
+ # state update
+ update={"foo": "bar"},
+ # control flow
+ goto="my_other_node"
+ )
+```
+
+We show an end-to-end example below. Let's create a simple graph with 3 nodes: A, B and C. We will first execute node A, and then decide whether to go to Node B or Node C next based on the output of node A.
+
+```python
+import random
+from typing_extensions import TypedDict, Literal
+from langgraph.graph import StateGraph, START
+from langgraph.types import Command
+
+# Define graph state
+class State(TypedDict):
+ foo: str
+
+# Define the nodes
+
+def node_a(state: State) -> Command[Literal["node_b", "node_c"]]:
+ print("Called A")
+ value = random.choice(["a", "b"])
+ # this is a replacement for a conditional edge function
+ if value == "a":
+ goto = "node_b"
+ else:
+ goto = "node_c"
+
+ # note how Command allows you to BOTH update the graph state AND route to the next node
+ return Command(
+ # this is the state update
+ update={"foo": value},
+ # this is a replacement for an edge
+ goto=goto,
+ )
+
+def node_b(state: State):
+ print("Called B")
+ return {"foo": state["foo"] + "b"}
+
+def node_c(state: State):
+ print("Called C")
+ return {"foo": state["foo"] + "c"}
+```
+
+We can now create the `StateGraph` with the above nodes. Notice that the graph doesn't have [conditional edges](../concepts/low_level.md#conditional-edges) for routing! This is because control flow is defined with `Command` inside `node_a`.
+
+```python
+builder = StateGraph(State)
+builder.add_edge(START, "node_a")
+builder.add_node(node_a)
+builder.add_node(node_b)
+builder.add_node(node_c)
+# NOTE: there are no edges between nodes A, B and C!
+
+graph = builder.compile()
+```
+
+!!! important
+ You might have noticed that we used `Command` as a return type annotation, e.g. `Command[Literal["node_b", "node_c"]]`. This is necessary for the graph rendering and tells LangGraph that `node_a` can navigate to `node_b` and `node_c`.
+
+```python
+from IPython.display import display, Image
+
+display(Image(graph.get_graph().draw_mermaid_png()))
+```
+
+
+
+If we run the graph multiple times, we'd see it take different paths (A -> B or A -> C) based on the random choice in node A.
+
+```python
+graph.invoke({"foo": ""})
+```
+```
+Called A
+Called C
+```
+
+### Navigate to a node in a parent graph
+
+If you are using [subgraphs](../concepts/subgraphs.md), you might want to navigate from a node within a subgraph to a different subgraph (i.e. a different node in the parent graph). To do so, you can specify `graph=Command.PARENT` in `Command`:
+
+```python
+def my_node(state: State) -> Command[Literal["my_other_node"]]:
+ return Command(
+ update={"foo": "bar"},
+ goto="other_subgraph", # where `other_subgraph` is a node in the parent graph
+ graph=Command.PARENT
+ )
+```
+
+Let's demonstrate this using the above example. We'll do so by changing `node_a` in the above example into a single-node graph that we'll add as a subgraph to our parent graph.
+
+!!! important "State updates with `Command.PARENT`"
+ When you send updates from a subgraph node to a parent graph node for a key that's shared by both parent and subgraph [state schemas](../concepts/low_level.md#schema), you **must** define a [reducer](../concepts/low_level.md#reducers) for the key you're updating in the parent graph state. See the example below.
+
+```python
+import operator
+from typing_extensions import Annotated
+
+class State(TypedDict):
+ # NOTE: we define a reducer here
+ # highlight-next-line
+ foo: Annotated[str, operator.add]
+
+def node_a(state: State):
+ print("Called A")
+ value = random.choice(["a", "b"])
+ # this is a replacement for a conditional edge function
+ if value == "a":
+ goto = "node_b"
+ else:
+ goto = "node_c"
+
+ # note how Command allows you to BOTH update the graph state AND route to the next node
+ return Command(
+ update={"foo": value},
+ goto=goto,
+ # this tells LangGraph to navigate to node_b or node_c in the parent graph
+ # NOTE: this will navigate to the closest parent graph relative to the subgraph
+ # highlight-next-line
+ graph=Command.PARENT,
+ )
+
+subgraph = StateGraph(State).add_node(node_a).add_edge(START, "node_a").compile()
+
+def node_b(state: State):
+ print("Called B")
+ # NOTE: since we've defined a reducer, we don't need to manually append
+ # new characters to existing 'foo' value. instead, reducer will append these
+ # automatically (via operator.add)
+ # highlight-next-line
+ return {"foo": "b"}
+
+def node_c(state: State):
+ print("Called C")
+ # highlight-next-line
+ return {"foo": "c"}
+
+builder = StateGraph(State)
+builder.add_edge(START, "subgraph")
+builder.add_node("subgraph", subgraph)
+builder.add_node(node_b)
+builder.add_node(node_c)
+
+graph = builder.compile()
+```
+
+```python
+graph.invoke({"foo": ""})
+```
+```
+Called A
+Called C
+```
+
+### Use inside tools
+
+A common use case is updating graph state from inside a tool. For example, in a customer support application you might want to look up customer information based on their account number or ID in the beginning of the conversation. To update the graph state from the tool, you can return `Command(update={"my_custom_key": "foo", "messages": [...]})` from the tool:
+
+```python
+@tool
+def lookup_user_info(tool_call_id: Annotated[str, InjectedToolCallId], config: RunnableConfig):
+ """Use this to look up user information to better assist them with their questions."""
+ user_info = get_user_info(config.get("configurable", {}).get("user_id"))
+ return Command(
+ update={
+ # update the state keys
+ "user_info": user_info,
+ # update the message history
+ "messages": [ToolMessage("Successfully looked up user information", tool_call_id=tool_call_id)]
+ }
+ )
+```
+
+!!! important
+ You MUST include `messages` (or any state key used for the message history) in `Command.update` when returning `Command` from a tool and the list of messages in `messages` MUST contain a `ToolMessage`. This is necessary for the resulting message history to be valid (LLM providers require AI messages with tool calls to be followed by the tool result messages).
+
+If you are using tools that update state via `Command`, we recommend using prebuilt [`ToolNode`](../reference/agents.md#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 the node.
+
+## Visualize your graph
+
+Here we demonstrate how to visualize the graphs you create.
+
+You can visualize any arbitrary [Graph](https://langchain-ai.github.io/langgraph/reference/graphs/), including [StateGraph](https://langchain-ai.github.io/langgraph/reference/graphs.md#langgraph.graph.state.StateGraph). Let's have some fun by drawing fractals :).
+
+```python
+import random
+from typing import Annotated, Literal
+from typing_extensions import TypedDict
+from langgraph.graph import StateGraph, START, END
+from langgraph.graph.message import add_messages
+
+class State(TypedDict):
+ messages: Annotated[list, add_messages]
+
+class MyNode:
+ def __init__(self, name: str):
+ self.name = name
+ def __call__(self, state: State):
+ return {"messages": [("assistant", f"Called node {self.name}")]}
+
+def route(state) -> Literal["entry_node", "__end__"]:
+ if len(state["messages"]) > 10:
+ return "__end__"
+ return "entry_node"
+
+def add_fractal_nodes(builder, current_node, level, max_level):
+ if level > max_level:
+ return
+ # Number of nodes to create at this level
+ num_nodes = random.randint(1, 3) # Adjust randomness as needed
+ for i in range(num_nodes):
+ nm = ["A", "B", "C"][i]
+ node_name = f"node_{current_node}_{nm}"
+ builder.add_node(node_name, MyNode(node_name))
+ builder.add_edge(current_node, node_name)
+ # Recursively add more nodes
+ r = random.random()
+ if r > 0.2 and level + 1 < max_level:
+ add_fractal_nodes(builder, node_name, level + 1, max_level)
+ elif r > 0.05:
+ builder.add_conditional_edges(node_name, route, node_name)
+ else:
+ # End
+ builder.add_edge(node_name, "__end__")
+
+def build_fractal_graph(max_level: int):
+ builder = StateGraph(State)
+ entry_point = "entry_node"
+ builder.add_node(entry_point, MyNode(entry_point))
+ builder.add_edge(START, entry_point)
+ add_fractal_nodes(builder, entry_point, 1, max_level)
+ # Optional: set a finish point if required
+ builder.add_edge(entry_point, END) # or any specific node
+ return builder.compile()
+
+app = build_fractal_graph(3)
+```
+
+### Mermaid
+
+We can also convert a graph class into Mermaid syntax.
+
+```python
+print(app.get_graph().draw_mermaid())
+```
+```
+%%{init: {'flowchart': {'curve': 'linear'}}}%%
+graph TD;
+ __start__([
]):::last
+ __start__ --> entry_node;
+ entry_node --> __end__;
+ entry_node --> node_entry_node_A;
+ entry_node --> node_entry_node_B;
+ node_entry_node_B --> node_node_entry_node_B_A;
+ node_entry_node_B --> node_node_entry_node_B_B;
+ node_entry_node_B --> node_node_entry_node_B_C;
+ node_entry_node_A -.-> entry_node;
+ node_entry_node_A -.-> __end__;
+ node_node_entry_node_B_A -.-> entry_node;
+ node_node_entry_node_B_A -.-> __end__;
+ node_node_entry_node_B_B -.-> entry_node;
+ node_node_entry_node_B_B -.-> __end__;
+ node_node_entry_node_B_C -.-> entry_node;
+ node_node_entry_node_B_C -.-> __end__;
+ classDef default fill:#f2f0ff,line-height:1.2
+ classDef first fill-opacity:0
+ classDef last fill:#bfb6fc
+```
+
+### PNG
+
+If preferred, we could render the Graph into a `.png`. Here we could use three options:
+
+- Using Mermaid.ink API (does not require additional packages)
+- Using Mermaid + Pyppeteer (requires `pip install pyppeteer`)
+- Using graphviz (which requires `pip install graphviz`)
+
+**Using Mermaid.Ink**
+
+By default, `draw_mermaid_png()` uses Mermaid.Ink's API to generate the diagram.
+
+```python
+from IPython.display import Image, display
+from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles
+
+display(Image(app.get_graph().draw_mermaid_png()))
+```
+
+
+
+**Using Mermaid + Pyppeteer**
+
+```python
+import nest_asyncio
+
+nest_asyncio.apply() # Required for Jupyter Notebook to run async functions
+
+display(
+ Image(
+ app.get_graph().draw_mermaid_png(
+ curve_style=CurveStyle.LINEAR,
+ node_colors=NodeStyles(first="#ffdfba", last="#baffc9", default="#fad7de"),
+ wrap_label_n_words=9,
+ output_file_path=None,
+ draw_method=MermaidDrawMethod.PYPPETEER,
+ background_color="white",
+ padding=10,
+ )
+ )
+)
+```
+
+**Using Graphviz**
+
+```python
+try:
+ display(Image(app.get_graph().draw_png()))
+except ImportError:
+ print(
+ "You likely need to install dependencies for pygraphviz, see more here https://github.com/pygraphviz/pygraphviz/blob/main/INSTALL.txt"
+ )
+```
diff --git a/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md b/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md
index 01166b008..31c3d2b27 100644
--- a/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md
+++ b/docs/docs/how-tos/human_in_the_loop/add-human-in-the-loop.md
@@ -11,11 +11,19 @@ hide:
# Enable human intervention
-To review, edit, and approve tool calls in an agent or workflow, use LangGraph's [human-in-the-loop](../../concepts/human_in_the_loop.md) features.
+To review, edit, and approve tool calls in an agent or workflow, use interrupts to pause a graph and wait for human input. Interrupts use LangGraph's [persistence](../../concepts/persistence.md) layer, which saves the graph state, to indefinitely pause graph execution until you resume.
+
+!!! info
+
+ For more information about human-in-the-loop workflows, see the [Human-in-the-Loop](../../concepts/human_in_the_loop.md) conceptual guide.
## Pause using `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. It's useful for tasks like approvals, edits, or gathering additional context.
+[Dynamic interrupts](../../concepts/human_in_the_loop.md#key-capabilities) (also known as dynamic breakpoints) are triggered based on the current state of the graph. You can set dynamic interrupts by calling [`interrupt` function][langgraph.types.interrupt] in the appropriate place. The graph will pause, which allows for human intervention, and then resumes the graph with their input. It's useful for tasks like approvals, edits, or gathering additional context.
+
+!!! note
+
+ As of v1.0, `interrupt` is the recommended way to pause a graph. `NodeInterrupt` is deprecated and will be removed in v2.0.
To use `interrupt` in your graph, you need to:
@@ -138,15 +146,10 @@ print(graph.invoke(Command(resume="Edited text"), config=config)) # (7)!
!!! warning
- Interrupts are both powerful and ergonomic. However, while they may resemble Python's input() function in terms of developer experience, it's important to note that they do not automatically resume execution from the interruption point. Instead, they rerun the entire node where the interrupt was used. For this reason, interrupts are typically best placed at the start of a node or in a dedicated node.
-
+ Interrupts resemble Python's input() function in terms of developer experience, but they do not automatically resume execution from the interruption point. Instead, they rerun the entire node where the interrupt was used. For this reason, interrupts are typically best placed at the start of a node or in a dedicated node.
## Resume using the `Command` primitive
-!!! 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.
-
When the `interrupt` function is used within a graph, execution pauses at that point and awaits user input.
To resume execution, use the [`Command`][langgraph.types.Command] primitive, which can be supplied via the `invoke`, `ainvoke`, `stream`, or `astream` methods. The graph resumes execution from the beginning of the node where `interrupt(...)` was initially called. This time, the `interrupt` function will return the value provided in `Command(resume=value)` rather than pausing again. All code from the beginning of the node to the `interrupt` will be re-executed.
@@ -712,6 +715,162 @@ def human_node(state: State):
print(final_result) # Should include the valid age
```
+## Debug with interrupts
+
+To debug and test a graph, use [static interrupts](../../concepts/human_in_the_loop.md#key-capabilities) (also known as static breakpoints) to step through the graph execution one node at a time or to pause the graph execution at specific nodes. Static interrupts are triggered at defined points either before or after a node executes. You can set static interrupts by specifying `interrupt_before` and `interrupt_after` at compile time or run time.
+
+!!! warning
+
+ Static interrupts are **not** recommended for human-in-the-loop workflows. Use [dynamic interrupts](#pause-using-interrupt) instead.
+
+=== "Compile time"
+
+ ```python
+ # highlight-next-line
+ graph = graph_builder.compile( # (1)!
+ # highlight-next-line
+ interrupt_before=["node_a"], # (2)!
+ # highlight-next-line
+ interrupt_after=["node_b", "node_c"], # (3)!
+ checkpointer=checkpointer, # (4)!
+ )
+
+ config = {
+ "configurable": {
+ "thread_id": "some_thread"
+ }
+ }
+
+ # Run the graph until the breakpoint
+ graph.invoke(inputs, config=thread_config) # (5)!
+
+ # Resume the graph
+ graph.invoke(None, config=thread_config) # (6)!
+ ```
+
+ 1. The breakpoints are set during `compile` time.
+ 2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
+ 3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
+ 4. A checkpointer is required to enable breakpoints.
+ 5. The graph is run until the first breakpoint is hit.
+ 6. The graph is resumed by passing in `None` for the input. This will run the graph until the next breakpoint is hit.
+
+=== "Run time"
+
+ ```python
+ # highlight-next-line
+ graph.invoke( # (1)!
+ inputs,
+ # highlight-next-line
+ interrupt_before=["node_a"], # (2)!
+ # highlight-next-line
+ interrupt_after=["node_b", "node_c"] # (3)!
+ config={
+ "configurable": {"thread_id": "some_thread"}
+ },
+ )
+
+ config = {
+ "configurable": {
+ "thread_id": "some_thread"
+ }
+ }
+
+ # Run the graph until the breakpoint
+ graph.invoke(inputs, config=config) # (4)!
+
+ # Resume the graph
+ graph.invoke(None, config=config) # (5)!
+ ```
+
+ 1. `graph.invoke` is called with the `interrupt_before` and `interrupt_after` parameters. This is a run-time configuration and can be changed for every invocation.
+ 2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
+ 3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
+ 4. The graph is run until the first breakpoint is hit.
+ 5. The graph is resumed by passing in `None` for the input. This will run the graph until the next breakpoint is hit.
+
+ !!! 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.
+
+??? example "Setting static breakpoints"
+
+ ```python
+ from IPython.display import Image, display
+ from typing_extensions import TypedDict
+
+ from langgraph.checkpoint.memory import InMemorySaver
+ from langgraph.graph import StateGraph, START, END
+
+
+ class State(TypedDict):
+ input: str
+
+
+ def step_1(state):
+ print("---Step 1---")
+ pass
+
+
+ def step_2(state):
+ print("---Step 2---")
+ pass
+
+
+ def step_3(state):
+ print("---Step 3---")
+ pass
+
+
+ builder = StateGraph(State)
+ builder.add_node("step_1", step_1)
+ builder.add_node("step_2", step_2)
+ builder.add_node("step_3", step_3)
+ builder.add_edge(START, "step_1")
+ builder.add_edge("step_1", "step_2")
+ builder.add_edge("step_2", "step_3")
+ builder.add_edge("step_3", END)
+
+ # Set up a checkpointer
+ checkpointer = InMemorySaver() # (1)!
+
+ graph = builder.compile(
+ checkpointer=checkpointer, # (2)!
+ interrupt_before=["step_3"] # (3)!
+ )
+
+ # View
+ display(Image(graph.get_graph().draw_mermaid_png()))
+
+
+ # Input
+ initial_input = {"input": "hello world"}
+
+ # Thread
+ thread = {"configurable": {"thread_id": "1"}}
+
+ # Run the graph until the first interruption
+ for event in graph.stream(initial_input, thread, stream_mode="values"):
+ print(event)
+
+ # This will run until the breakpoint
+ # You can get the state of the graph at this point
+ print(graph.get_state(config))
+
+ # You can continue the graph execution by passing in `None` for the input
+ for event in graph.stream(None, thread, stream_mode="values"):
+ print(event)
+ ```
+
+### Use static interrupts in LangGraph Studio
+
+You can use [LangGraph Studio](../../concepts/langgraph_studio.md) to debug your graph. You can set static breakpoints in the UI and then run the graph. You can also use the UI to inspect the graph state at any point in the execution.
+
+{: style="max-height:400px"}
+
+LangGraph Studio is free with [locally deployed applications](../../tutorials/langgraph-platform/local-server.md) using `langgraph dev`.
+
## Considerations
When using human-in-the-loop, there are some considerations to keep in mind.
@@ -953,4 +1112,3 @@ To avoid issues, refrain from dynamically changing the node's structure between
Name: N/A. Age: John
{'human_node': {'age': 'John', 'name': 'N/A'}}
```
-
diff --git a/docs/docs/how-tos/human_in_the_loop/breakpoints.md b/docs/docs/how-tos/human_in_the_loop/breakpoints.md
deleted file mode 100644
index 16c8fb552..000000000
--- a/docs/docs/how-tos/human_in_the_loop/breakpoints.md
+++ /dev/null
@@ -1,342 +0,0 @@
-# Set breakpoints
-
-There are two places where you can set 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. We call these [**dynamic breakpoints**](#dynamic-breakpoints).
-
-To use breakpoints, you will need to:
-
-1. [**Specify a checkpointer**](../../concepts/persistence.md#checkpoints) to save the graph state after each step.
-2. **Set breakpoints** to specify where execution should pause.
-3. **Run the graph** with a [**thread ID**](../../concepts/persistence.md#threads) to pause execution at the breakpoint.
-4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` passing a `None` as the argument for the inputs.
-
-!!! tip
-
- For a conceptual overview of breakpoints, see [Breakpoints](../../concepts/breakpoints.md).
-
-## 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.
-
-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.
-
-=== "Compile time"
-
- ```python
- # highlight-next-line
- graph = graph_builder.compile( # (1)!
- # highlight-next-line
- interrupt_before=["node_a"], # (2)!
- # highlight-next-line
- interrupt_after=["node_b", "node_c"], # (3)!
- checkpointer=checkpointer, # (4)!
- )
-
- config = {
- "configurable": {
- "thread_id": "some_thread"
- }
- }
-
- # Run the graph until the breakpoint
- graph.invoke(inputs, config=thread_config) # (5)!
-
- # Resume the graph
- graph.invoke(None, config=thread_config) # (6)!
- ```
-
- 1. The breakpoints are set during `compile` time.
- 2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
- 3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
- 4. A checkpointer is required to enable breakpoints.
- 5. The graph is run until the first breakpoint is hit.
- 6. The graph is resumed by passing in `None` for the input. This will run the graph until the next breakpoint is hit.
-
-=== "Run time"
-
- ```python
- # highlight-next-line
- graph.invoke( # (1)!
- inputs,
- # highlight-next-line
- interrupt_before=["node_a"], # (2)!
- # highlight-next-line
- interrupt_after=["node_b", "node_c"] # (3)!
- config={
- "configurable": {"thread_id": "some_thread"}
- },
- )
-
- config = {
- "configurable": {
- "thread_id": "some_thread"
- }
- }
-
- # Run the graph until the breakpoint
- graph.invoke(inputs, config=config) # (4)!
-
- # Resume the graph
- graph.invoke(None, config=config) # (5)!
- ```
-
- 1. `graph.invoke` is called with the `interrupt_before` and `interrupt_after` parameters. This is a run-time configuration and can be changed for every invocation.
- 2. `interrupt_before` specifies the nodes where execution should pause before the node is executed.
- 3. `interrupt_after` specifies the nodes where execution should pause after the node is executed.
- 4. The graph is run until the first breakpoint is hit.
- 5. The graph is resumed by passing in `None` for the input. This will run the graph until the next breakpoint is hit.
-
- !!! 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.
-
-??? example "Setting static breakpoints"
-
- ```python
- from IPython.display import Image, display
- from typing_extensions import TypedDict
-
- from langgraph.checkpoint.memory import InMemorySaver
- from langgraph.graph import StateGraph, START, END
-
-
- class State(TypedDict):
- input: str
-
-
- def step_1(state):
- print("---Step 1---")
- pass
-
-
- def step_2(state):
- print("---Step 2---")
- pass
-
-
- def step_3(state):
- print("---Step 3---")
- pass
-
-
- builder = StateGraph(State)
- builder.add_node("step_1", step_1)
- builder.add_node("step_2", step_2)
- builder.add_node("step_3", step_3)
- builder.add_edge(START, "step_1")
- builder.add_edge("step_1", "step_2")
- builder.add_edge("step_2", "step_3")
- builder.add_edge("step_3", END)
-
- # Set up a checkpointer
- checkpointer = InMemorySaver() # (1)!
-
- graph = builder.compile(
- checkpointer=checkpointer, # (2)!
- interrupt_before=["step_3"] # (3)!
- )
-
- # View
- display(Image(graph.get_graph().draw_mermaid_png()))
-
-
- # Input
- initial_input = {"input": "hello world"}
-
- # Thread
- thread = {"configurable": {"thread_id": "1"}}
-
- # Run the graph until the first interruption
- for event in graph.stream(initial_input, thread, stream_mode="values"):
- print(event)
-
- # This will run until the breakpoint
- # You can get the state of the graph at this point
- print(graph.get_state(config))
-
- # You can continue the graph execution by passing in `None` for the input
- for event in graph.stream(None, thread, stream_mode="values"):
- print(event)
- ```
-
-## Dynamic breakpoints
-
-Use dynamic breakpoints if you need to interrupt the graph from inside a given node based on a condition.
-
-```python
-from langgraph.errors import NodeInterrupt
-
-def step_2(state: State) -> State:
- # highlight-next-line
- if len(state["input"]) > 5:
- # highlight-next-line
- raise NodeInterrupt( # (1)!
- f"Received input that is longer than 5 characters: {state['foo']}"
- )
- return state
-```
-
-1. raise NodeInterrupt exception based on a some condition. In this example, we create a dynamic breakpoint if the length of the attribute `input` is longer than 5 characters.
-
-Using dynamic breakpoints
-
-```python
-from typing_extensions import TypedDict
-from IPython.display import Image, display
-
-from langgraph.graph import StateGraph, START, END
-from langgraph.checkpoint.memory import MemorySaver
-from langgraph.errors import NodeInterrupt
-
-
-class State(TypedDict):
- input: str
-
-
-def step_1(state: State) -> State:
- print("---Step 1---")
- return state
-
-
-def step_2(state: State) -> State:
- # Let's optionally raise a NodeInterrupt
- # if the length of the input is longer than 5 characters
- if len(state["input"]) > 5:
- raise NodeInterrupt(
- f"Received input that is longer than 5 characters: {state['input']}"
- )
- print("---Step 2---")
- return state
-
-
-def step_3(state: State) -> State:
- print("---Step 3---")
- return state
-
-
-builder = StateGraph(State)
-builder.add_node("step_1", step_1)
-builder.add_node("step_2", step_2)
-builder.add_node("step_3", step_3)
-builder.add_edge(START, "step_1")
-builder.add_edge("step_1", "step_2")
-builder.add_edge("step_2", "step_3")
-builder.add_edge("step_3", END)
-
-# Set up memory
-memory = MemorySaver()
-
-# Compile the graph with memory
-graph = builder.compile(checkpointer=memory)
-
-# View
-display(Image(graph.get_graph().draw_mermaid_png()))
-```
-
-First, let's run the graph with an input that <= 5 characters long. This should safely ignore the interrupt condition we defined and return the original input at the end of the graph execution.
-
-```python
-initial_input = {"input": "hello"}
-thread_config = {"configurable": {"thread_id": "1"}}
-
-for event in graph.stream(initial_input, thread_config, stream_mode="values"):
- print(event)
-```
-
-If we inspect the graph at this point, we can see that there are no more tasks left to run and that the graph indeed finished execution.
-
-```python
-state = graph.get_state(thread_config)
-print(state.next)
-print(state.tasks)
-```
-
-Now, let's run the graph with an input that's longer than 5 characters. This should trigger the dynamic interrupt we defined via raising a `NodeInterrupt` error inside the `step_2` node.
-
-```python
-initial_input = {"input": "hello world"}
-thread_config = {"configurable": {"thread_id": "2"}}
-
-# Run the graph until the first interruption
-for event in graph.stream(initial_input, thread_config, stream_mode="values"):
- print(event)
-```
-
-We can see that the graph now stopped while executing `step_2`. If we inspect the graph state at this point, we can see the information on what node is set to execute next (`step_2`), as well as what node raised the interrupt (also `step_2`), and additional information about the interrupt.
-
-```python
-state = graph.get_state(thread_config)
-print(state.next)
-print(state.tasks)
-```
-
-If we try to resume the graph from the breakpoint, we will simply interrupt again as our inputs & graph state haven't changed.
-
-```python
-# NOTE: to resume the graph from a dynamic interrupt we use the same syntax as with regular interrupts -- we pass None as the input
-for event in graph.stream(None, thread_config, stream_mode="values"):
- print(event)
-```
-
-```python
-state = graph.get_state(thread_config)
-print(state.next)
-print(state.tasks)
-```
-
-
-
-## Use with subgraphs
-
-To add breakpoints to subgraph either:
-
-* Define [static breakpoints](#static-breakpoints) by specifying them when **compiling** the subgraph.
-* Define [dynamic breakpoints](#dynamic-breakpoints).
-
-Add breakpoints to subgraphs
-
-```python
-from typing_extensions import TypedDict
-
-from langgraph.graph import START, StateGraph
-from langgraph.checkpoint.memory import InMemorySaver
-from langgraph.types import interrupt
-
-
-class State(TypedDict):
- foo: str
-
-
-def subgraph_node_1(state: State):
- return {"foo": state["foo"]}
-
-
-subgraph_builder = StateGraph(State)
-subgraph_builder.add_node(subgraph_node_1)
-subgraph_builder.add_edge(START, "subgraph_node_1")
-
-subgraph = subgraph_builder.compile(interrupt_before=["subgraph_node_1"])
-
-builder = StateGraph(State)
-builder.add_node("node_1", subgraph) # directly include subgraph as a node
-builder.add_edge(START, "node_1")
-
-checkpointer = InMemorySaver()
-graph = builder.compile(checkpointer=checkpointer)
-
-config = {"configurable": {"thread_id": "1"}}
-
-graph.invoke({"foo": ""}, config)
-
-# Fetch state including subgraph state.
-print(graph.get_state(config, subgraphs=True).tasks[0].state)
-
-# resume the subgraph
-graph.invoke(None, config)
-```
-
-
\ No newline at end of file
diff --git a/docs/docs/how-tos/human_in_the_loop/time-travel.md b/docs/docs/how-tos/human_in_the_loop/time-travel.md
index 4b1a78182..84ded8410 100644
--- a/docs/docs/how-tos/human_in_the_loop/time-travel.md
+++ b/docs/docs/how-tos/human_in_the_loop/time-travel.md
@@ -4,7 +4,7 @@ To use [time-travel](../../concepts/time-travel.md) in LangGraph:
1. [Run the graph](#1-run-the-graph) with initial inputs using [`invoke`][langgraph.graph.state.CompiledStateGraph.invoke] or [`stream`][langgraph.graph.state.CompiledStateGraph.stream] methods.
2. [Identify a checkpoint in an existing thread](#2-identify-a-checkpoint): Use the [`get_state_history()`][langgraph.graph.state.CompiledStateGraph.get_state_history] method to retrieve the execution history for a specific `thread_id` and locate the desired `checkpoint_id`.
- Alternatively, set a [breakpoint](../../concepts/breakpoints.md) before the node(s) where you want execution to pause. You can then find the most recent checkpoint recorded up to that breakpoint.
+ Alternatively, set an [interrupt](../../how-tos/human_in_the_loop/add-human-in-the-loop.md) before the node(s) where you want execution to pause. You can then find the most recent checkpoint recorded up to that interrupt.
3. [Update the graph state (optional)](#3-update-the-state-optional): Use the [`update_state`][langgraph.graph.state.CompiledStateGraph.update_state] method to modify the graph's state at the checkpoint and resume execution from alternative state.
4. [Resume execution from the checkpoint](#4-resume-execution-from-the-checkpoint): Use the `invoke` or `stream` methods with an input of `None` and a configuration containing the appropriate `thread_id` and `checkpoint_id`.
diff --git a/docs/docs/how-tos/memory/add-memory.md b/docs/docs/how-tos/memory/add-memory.md
index 4aaf8ec69..408c260aa 100644
--- a/docs/docs/how-tos/memory/add-memory.md
+++ b/docs/docs/how-tos/memory/add-memory.md
@@ -1351,7 +1351,7 @@ The problem with trimming or removing messages, as shown above, is that you may
```python
from langchain_anthropic import ChatAnthropic
- from langmem.short_term import SummarizationNode
+ from langmem.short_term import SummarizationNode, RunningSummary
from langchain_core.messages.utils import count_tokens_approximately
from langgraph.prebuilt import create_react_agent
from langgraph.prebuilt.chat_agent_executor import AgentState
@@ -1372,7 +1372,7 @@ The problem with trimming or removing messages, as shown above, is that you may
# NOTE: we're adding this key to keep track of previous summary information
# to make sure we're not summarizing on every LLM call
# highlight-next-line
- context: dict[str, Any] # (2)!
+ context: dict[str, RunningSummary] # (2)!
checkpointer = InMemorySaver() # (3)!
@@ -1447,18 +1447,18 @@ The problem with trimming or removing messages, as shown above, is that you may
from langgraph.graph import StateGraph, START, MessagesState
from langgraph.checkpoint.memory import InMemorySaver
# highlight-next-line
- from langmem.short_term import SummarizationNode
+ from langmem.short_term import SummarizationNode, RunningSummary
model = init_chat_model("anthropic:claude-3-7-sonnet-latest")
summarization_model = model.bind(max_tokens=128)
class State(MessagesState):
# highlight-next-line
- context: dict[str, Any] # (1)!
+ context: dict[str, RunningSummary] # (1)!
class LLMInputState(TypedDict): # (2)!
summarized_messages: list[AnyMessage]
- context: dict[str, Any]
+ context: dict[str, RunningSummary]
# highlight-next-line
summarization_node = SummarizationNode(
diff --git a/docs/docs/how-tos/memory/semantic-search.ipynb b/docs/docs/how-tos/memory/semantic-search.ipynb
index 890363ef4..c952ac6ea 100644
--- a/docs/docs/how-tos/memory/semantic-search.ipynb
+++ b/docs/docs/how-tos/memory/semantic-search.ipynb
@@ -125,7 +125,7 @@
"memories = store.search((\"user_123\", \"memories\"), query=\"I like food?\", limit=5)\n",
"\n",
"for memory in memories:\n",
- " print(f'Memory: {memory.value[\"text\"]} (similarity: {memory.score})')"
+ " print(f\"Memory: {memory.value['text']} (similarity: {memory.score})\")"
]
},
{
diff --git a/docs/docs/how-tos/multi_agent.ipynb b/docs/docs/how-tos/multi_agent.ipynb
deleted file mode 100644
index 6ee5777de..000000000
--- a/docs/docs/how-tos/multi_agent.ipynb
+++ /dev/null
@@ -1,657 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "34d3d54e-9a2b-481e-bccd-74aca7a53f9a",
- "metadata": {},
- "source": [
- "# Build multi-agent systems"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "id": "3f0b4f70-f14e-4026-82c0-874786789ee8",
- "metadata": {},
- "source": [
- "A single agent might struggle if it needs to specialize in multiple domains or manage many tools. To tackle this, you can break your agent into smaller, independent agents and composing them into a [multi-agent system](../../concepts/multi_agent).\n",
- "\n",
- "In multi-agent systems, agents need to communicate between each other. They do so via [handoffs](#handoffs) — a primitive that describes which agent to hand control to and the payload to send to that agent.\n",
- "\n",
- "This guide covers the following:\n",
- "\n",
- "* implementing [handoffs](#handoffs) between agents\n",
- "* using handoffs and the prebuilt [agent](../../agents/agents) to [build a custom multi-agent system](#build-a-multi-agent-system)\n",
- "\n",
- "To get started with building multi-agent systems, check out LangGraph [prebuilt implementations](#prebuilt-implementations) of two of the most popular multi-agent architectures — [supervisor](../../agents/multi-agent#supervisor) and [swarm](../../agents/multi-agent#swarm)."
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "id": "7d43e110-16fc-4899-97f1-015d5b804b87",
- "metadata": {},
- "source": [
- "## Handoffs\n",
- "\n",
- "To set up communication between the agents in a multi-agent system you can use [**handoffs**](../../concepts/multi_agent#handoffs) — a pattern where one agent *hands off* control to another. Handoffs allow you to specify:\n",
- "\n",
- "- **destination**: target agent to navigate to (e.g., name of the LangGraph node to go to)\n",
- "- **payload**: information to pass to that agent (e.g., state update)\n",
- "\n",
- "### Create handoffs\n",
- "\n",
- "To implement handoffs, you can return [`Command`](../command) objects from your agent nodes or tools:\n",
- "\n",
- "```python\n",
- "from typing import Annotated\n",
- "from langchain_core.tools import tool, InjectedToolCallId\n",
- "from langgraph.prebuilt import create_react_agent, InjectedState\n",
- "from langgraph.graph import StateGraph, START, MessagesState\n",
- "from langgraph.types import Command\n",
- "\n",
- "def create_handoff_tool(*, agent_name: str, description: str | None = None):\n",
- " name = f\"transfer_to_{agent_name}\"\n",
- " description = description or f\"Transfer to {agent_name}\"\n",
- "\n",
- " @tool(name, description=description)\n",
- " def handoff_tool(\n",
- " # highlight-next-line\n",
- " state: Annotated[MessagesState, InjectedState], # (1)!\n",
- " # highlight-next-line\n",
- " tool_call_id: Annotated[str, InjectedToolCallId],\n",
- " ) -> Command:\n",
- " tool_message = {\n",
- " \"role\": \"tool\",\n",
- " \"content\": f\"Successfully transferred to {agent_name}\",\n",
- " \"name\": name,\n",
- " \"tool_call_id\": tool_call_id,\n",
- " }\n",
- " return Command( # (2)!\n",
- " # highlight-next-line\n",
- " goto=agent_name, # (3)!\n",
- " # highlight-next-line\n",
- " update={\"messages\": state[\"messages\"] + [tool_message]}, # (4)!\n",
- " # highlight-next-line\n",
- " graph=Command.PARENT, # (5)!\n",
- " )\n",
- " return handoff_tool\n",
- "```\n",
- "\n",
- "1. Access the [state](../../concepts/low_level#state) of the agent that is calling the handoff tool using the [InjectedState][langgraph.prebuilt.InjectedState] annotation. See [this guide](../tool-calling/#read-state) for more information.\n",
- "2. The `Command` primitive allows specifying a state update and a node transition as a single operation, making it useful for implementing handoffs.\n",
- "3. Name of the agent or node to hand off to.\n",
- "4. Take the agent's messages and **add** them to the parent's **state** as part of the handoff. The next agent will see the parent state.\n",
- "5. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph.\n",
- "\n",
- "!!! tip\n",
- "\n",
- " If you want to use tools that return `Command`, you can either use prebuilt [`create_react_agent`][langgraph.prebuilt.chat_agent_executor.create_react_agent] / [`ToolNode`][langgraph.prebuilt.tool_node.ToolNode] components, or implement your own tool-executing node that collects `Command` objects returned by the tools and returns a list of them, e.g.:\n",
- " \n",
- " ```python\n",
- " def call_tools(state):\n",
- " ...\n",
- " commands = [tools_by_name[tool_call[\"name\"]].invoke(tool_call) for tool_call in tool_calls]\n",
- " return commands\n",
- " ```\n",
- "\n",
- "!!! Important\n",
- "\n",
- " This handoff implementation assumes that:\n",
- " \n",
- " - each agent receives overall message history (across all agents) in the multi-agent system as its input. If you want more control over agent inputs, see [this section](#control-agent-inputs)\n",
- " - each agent outputs its internal messages history to the overall message history of the multi-agent system. If you want more control over **how agent outputs are added**, wrap the agent in a separate node function:\n",
- "\n",
- " ```python\n",
- " def call_hotel_assistant(state):\n",
- " # return agent's final response,\n",
- " # excluding inner monologue\n",
- " response = hotel_assistant.invoke(state)\n",
- " # highlight-next-line\n",
- " return {\"messages\": response[\"messages\"][-1]}\n",
- " ```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "3956f12d-285a-4799-a0a5-db13def58a15",
- "metadata": {},
- "source": [
- "### Control agent inputs\n",
- "\n",
- "You can use the [`Send()`][langgraph.types.Send] primitive to directly send data to the worker agents during the handoff. For example, you can request that the calling agent populate a task description for the next agent:\n",
- "\n",
- "```python\n",
- "\n",
- "from typing import Annotated\n",
- "from langchain_core.tools import tool, InjectedToolCallId\n",
- "from langgraph.prebuilt import InjectedState\n",
- "from langgraph.graph import StateGraph, START, MessagesState\n",
- "# highlight-next-line\n",
- "from langgraph.types import Command, Send\n",
- "\n",
- "def create_task_description_handoff_tool(\n",
- " *, agent_name: str, description: str | None = None\n",
- "):\n",
- " name = f\"transfer_to_{agent_name}\"\n",
- " description = description or f\"Ask {agent_name} for help.\"\n",
- "\n",
- " @tool(name, description=description)\n",
- " def handoff_tool(\n",
- " # this is populated by the calling agent\n",
- " task_description: Annotated[\n",
- " str,\n",
- " \"Description of what the next agent should do, including all of the relevant context.\",\n",
- " ],\n",
- " # these parameters are ignored by the LLM\n",
- " state: Annotated[MessagesState, InjectedState],\n",
- " ) -> Command:\n",
- " task_description_message = {\"role\": \"user\", \"content\": task_description}\n",
- " agent_input = {**state, \"messages\": [task_description_message]}\n",
- " return Command(\n",
- " # highlight-next-line\n",
- " goto=[Send(agent_name, agent_input)],\n",
- " graph=Command.PARENT,\n",
- " )\n",
- "\n",
- " return handoff_tool\n",
- "```\n",
- "\n",
- "See the multi-agent [supervisor](../tutorials/agent_supervisor.ipynb#4-create-delegation-tasks) tutorial for a full example of using [`Send()`][langgraph.types.Send] in handoffs."
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "id": "21511f57-7bf3-4223-9a17-ce9fc84c40ab",
- "metadata": {},
- "source": [
- "## Build a multi-agent system\n",
- "\n",
- "You can use handoffs in any agents built with LangGraph. We recommend using the prebuilt [agent](../../agents/overview) or [`ToolNode`](../tool-calling#use-prebuilt-toolnode), as they natively support handoffs tools returning `Command`. Below is an example of how you can implement a multi-agent system for booking travel using handoffs:\n",
- "\n",
- "```python\n",
- "from langgraph.prebuilt import create_react_agent\n",
- "from langgraph.graph import StateGraph, START, MessagesState\n",
- "\n",
- "def create_handoff_tool(*, agent_name: str, description: str | None = None):\n",
- " # same implementation as above\n",
- " ...\n",
- " return Command(...)\n",
- "\n",
- "# Handoffs\n",
- "transfer_to_hotel_assistant = create_handoff_tool(agent_name=\"hotel_assistant\")\n",
- "transfer_to_flight_assistant = create_handoff_tool(agent_name=\"flight_assistant\")\n",
- "\n",
- "# Define agents\n",
- "flight_assistant = create_react_agent(\n",
- " model=\"anthropic:claude-3-5-sonnet-latest\",\n",
- " # highlight-next-line\n",
- " tools=[..., transfer_to_hotel_assistant],\n",
- " # highlight-next-line\n",
- " name=\"flight_assistant\"\n",
- ")\n",
- "hotel_assistant = create_react_agent(\n",
- " model=\"anthropic:claude-3-5-sonnet-latest\",\n",
- " # highlight-next-line\n",
- " tools=[..., transfer_to_flight_assistant],\n",
- " # highlight-next-line\n",
- " name=\"hotel_assistant\"\n",
- ")\n",
- "\n",
- "# Define multi-agent graph\n",
- "multi_agent_graph = (\n",
- " StateGraph(MessagesState)\n",
- " # highlight-next-line\n",
- " .add_node(flight_assistant)\n",
- " # highlight-next-line\n",
- " .add_node(hotel_assistant)\n",
- " .add_edge(START, \"flight_assistant\")\n",
- " .compile()\n",
- ")\n",
- "```\n",
- "\n",
- "??? example \"Full example: Multi-agent system for booking travel\"\n",
- "\n",
- " ```python\n",
- " from typing import Annotated\n",
- " from langchain_core.messages import convert_to_messages\n",
- " from langchain_core.tools import tool, InjectedToolCallId\n",
- " from langgraph.prebuilt import create_react_agent, InjectedState\n",
- " from langgraph.graph import StateGraph, START, MessagesState\n",
- " from langgraph.types import Command\n",
- " \n",
- " # We'll use `pretty_print_messages` helper to render the streamed agent outputs nicely\n",
- " \n",
- " def pretty_print_message(message, indent=False):\n",
- " pretty_message = message.pretty_repr(html=True)\n",
- " if not indent:\n",
- " print(pretty_message)\n",
- " return\n",
- " \n",
- " indented = \"\\n\".join(\"\\t\" + c for c in pretty_message.split(\"\\n\"))\n",
- " print(indented)\n",
- " \n",
- " \n",
- " def pretty_print_messages(update, last_message=False):\n",
- " is_subgraph = False\n",
- " if isinstance(update, tuple):\n",
- " ns, update = update\n",
- " # skip parent graph updates in the printouts\n",
- " if len(ns) == 0:\n",
- " return\n",
- " \n",
- " graph_id = ns[-1].split(\":\")[0]\n",
- " print(f\"Update from subgraph {graph_id}:\")\n",
- " print(\"\\n\")\n",
- " is_subgraph = True\n",
- " \n",
- " for node_name, node_update in update.items():\n",
- " update_label = f\"Update from node {node_name}:\"\n",
- " if is_subgraph:\n",
- " update_label = \"\\t\" + update_label\n",
- " \n",
- " print(update_label)\n",
- " print(\"\\n\")\n",
- " \n",
- " messages = convert_to_messages(node_update[\"messages\"])\n",
- " if last_message:\n",
- " messages = messages[-1:]\n",
- " \n",
- " for m in messages:\n",
- " pretty_print_message(m, indent=is_subgraph)\n",
- " print(\"\\n\")\n",
- "\n",
- "\n",
- " def create_handoff_tool(*, agent_name: str, description: str | None = None):\n",
- " name = f\"transfer_to_{agent_name}\"\n",
- " description = description or f\"Transfer to {agent_name}\"\n",
- " \n",
- " @tool(name, description=description)\n",
- " def handoff_tool(\n",
- " # highlight-next-line\n",
- " state: Annotated[MessagesState, InjectedState], # (1)!\n",
- " # highlight-next-line\n",
- " tool_call_id: Annotated[str, InjectedToolCallId],\n",
- " ) -> Command:\n",
- " tool_message = {\n",
- " \"role\": \"tool\",\n",
- " \"content\": f\"Successfully transferred to {agent_name}\",\n",
- " \"name\": name,\n",
- " \"tool_call_id\": tool_call_id,\n",
- " }\n",
- " return Command( # (2)!\n",
- " # highlight-next-line\n",
- " goto=agent_name, # (3)!\n",
- " # highlight-next-line\n",
- " update={\"messages\": state[\"messages\"] + [tool_message]}, # (4)!\n",
- " # highlight-next-line\n",
- " graph=Command.PARENT, # (5)!\n",
- " )\n",
- " return handoff_tool\n",
- " \n",
- " # Handoffs\n",
- " transfer_to_hotel_assistant = create_handoff_tool(\n",
- " agent_name=\"hotel_assistant\",\n",
- " description=\"Transfer user to the hotel-booking assistant.\",\n",
- " )\n",
- " transfer_to_flight_assistant = create_handoff_tool(\n",
- " agent_name=\"flight_assistant\",\n",
- " description=\"Transfer user to the flight-booking assistant.\",\n",
- " )\n",
- " \n",
- " # Simple agent tools\n",
- " def book_hotel(hotel_name: str):\n",
- " \"\"\"Book a hotel\"\"\"\n",
- " return f\"Successfully booked a stay at {hotel_name}.\"\n",
- " \n",
- " def book_flight(from_airport: str, to_airport: str):\n",
- " \"\"\"Book a flight\"\"\"\n",
- " return f\"Successfully booked a flight from {from_airport} to {to_airport}.\"\n",
- " \n",
- " # Define agents\n",
- " flight_assistant = create_react_agent(\n",
- " model=\"anthropic:claude-3-5-sonnet-latest\",\n",
- " # highlight-next-line\n",
- " tools=[book_flight, transfer_to_hotel_assistant],\n",
- " prompt=\"You are a flight booking assistant\",\n",
- " # highlight-next-line\n",
- " name=\"flight_assistant\"\n",
- " )\n",
- " hotel_assistant = create_react_agent(\n",
- " model=\"anthropic:claude-3-5-sonnet-latest\",\n",
- " # highlight-next-line\n",
- " tools=[book_hotel, transfer_to_flight_assistant],\n",
- " prompt=\"You are a hotel booking assistant\",\n",
- " # highlight-next-line\n",
- " name=\"hotel_assistant\"\n",
- " )\n",
- " \n",
- " # Define multi-agent graph\n",
- " multi_agent_graph = (\n",
- " StateGraph(MessagesState)\n",
- " .add_node(flight_assistant)\n",
- " .add_node(hotel_assistant)\n",
- " .add_edge(START, \"flight_assistant\")\n",
- " .compile()\n",
- " )\n",
- " \n",
- " # Run the multi-agent graph\n",
- " for chunk in multi_agent_graph.stream(\n",
- " {\n",
- " \"messages\": [\n",
- " {\n",
- " \"role\": \"user\",\n",
- " \"content\": \"book a flight from BOS to JFK and a stay at McKittrick Hotel\"\n",
- " }\n",
- " ]\n",
- " },\n",
- " # highlight-next-line\n",
- " subgraphs=True\n",
- " ):\n",
- " pretty_print_messages(chunk)\n",
- " ```\n",
- "\n",
- " 1. Access agent's state\n",
- " 2. The `Command` primitive allows specifying a state update and a node transition as a single operation, making it useful for implementing handoffs.\n",
- " 3. Name of the agent or node to hand off to.\n",
- " 4. Take the agent's messages and **add** them to the parent's **state** as part of the handoff. The next agent will see the parent state.\n",
- " 5. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e8314da4-9971-429b-9e70-58b40795de74",
- "metadata": {},
- "source": [
- "## Multi-turn conversation\n",
- "\n",
- "Users might want to engage in a *multi-turn conversation* with one or more agents. To build a system that can handle this, you can create a node that uses an [`interrupt`][langgraph.types.interrupt] to collect user input and routes back to the **active** agent.\n",
- "\n",
- "The agents can then 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](#handoffs)\n",
- "\n",
- "```python\n",
- "def human(state) -> 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",
- "\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",
- "\n",
- "??? example \"Full example: multi-agent system for travel recommendations\"\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 2 agents:\n",
- " \n",
- " * travel_advisor: can help with travel destination recommendations. Can ask hotel_advisor for help.\n",
- " * hotel_advisor: can help with hotel recommendations. Can ask travel_advisor for help.\n",
- "\n",
- " ```python\n",
- " from langchain_anthropic import ChatAnthropic\n",
- " from langgraph.graph import MessagesState, StateGraph, START\n",
- " from langgraph.prebuilt import create_react_agent, InjectedState\n",
- " from langgraph.types import Command, interrupt\n",
- " from langgraph.checkpoint.memory import MemorySaver\n",
- " \n",
- " \n",
- " model = ChatAnthropic(model=\"claude-3-5-sonnet-latest\")\n",
- "\n",
- " class MultiAgentState(MessagesState):\n",
- " last_active_agent: str\n",
- " \n",
- " \n",
- " # Define travel advisor tools and ReAct agent\n",
- " travel_advisor_tools = [\n",
- " get_travel_recommendations,\n",
- " make_handoff_tool(agent_name=\"hotel_advisor\"),\n",
- " ]\n",
- " travel_advisor = create_react_agent(\n",
- " model,\n",
- " travel_advisor_tools,\n",
- " prompt=(\n",
- " \"You are a general travel expert that can recommend travel destinations (e.g. countries, cities, etc). \"\n",
- " \"If you need hotel recommendations, ask 'hotel_advisor' for help. \"\n",
- " \"You MUST include human-readable response before transferring to another agent.\"\n",
- " ),\n",
- " )\n",
- " \n",
- " \n",
- " def call_travel_advisor(\n",
- " state: MultiAgentState,\n",
- " ) -> Command[Literal[\"hotel_advisor\", \"human\"]]:\n",
- " # You can also add additional logic like changing the input to the agent / output from the agent, etc.\n",
- " # NOTE: we're invoking the ReAct agent with the full history of messages in the state\n",
- " response = travel_advisor.invoke(state)\n",
- " update = {**response, \"last_active_agent\": \"travel_advisor\"}\n",
- " return Command(update=update, goto=\"human\")\n",
- " \n",
- " \n",
- " # Define hotel advisor tools and ReAct agent\n",
- " hotel_advisor_tools = [\n",
- " get_hotel_recommendations,\n",
- " make_handoff_tool(agent_name=\"travel_advisor\"),\n",
- " ]\n",
- " hotel_advisor = create_react_agent(\n",
- " model,\n",
- " hotel_advisor_tools,\n",
- " prompt=(\n",
- " \"You are a hotel expert that can provide hotel recommendations for a given destination. \"\n",
- " \"If you need help picking travel destinations, ask 'travel_advisor' for help.\"\n",
- " \"You MUST include human-readable response before transferring to another agent.\"\n",
- " ),\n",
- " )\n",
- " \n",
- " \n",
- " def call_hotel_advisor(\n",
- " state: MultiAgentState,\n",
- " ) -> Command[Literal[\"travel_advisor\", \"human\"]]:\n",
- " response = hotel_advisor.invoke(state)\n",
- " update = {**response, \"last_active_agent\": \"hotel_advisor\"}\n",
- " return Command(update=update, goto=\"human\")\n",
- " \n",
- " \n",
- " def human_node(\n",
- " state: MultiAgentState, config\n",
- " ) -> Command[Literal[\"hotel_advisor\", \"travel_advisor\", \"human\"]]:\n",
- " \"\"\"A node for collecting user input.\"\"\"\n",
- " \n",
- " user_input = interrupt(value=\"Ready for user input.\")\n",
- " active_agent = state[\"last_active_agent\"]\n",
- " \n",
- " return Command(\n",
- " update={\n",
- " \"messages\": [\n",
- " {\n",
- " \"role\": \"human\",\n",
- " \"content\": user_input,\n",
- " }\n",
- " ]\n",
- " },\n",
- " goto=active_agent,\n",
- " )\n",
- " \n",
- " \n",
- " builder = StateGraph(MultiAgentState)\n",
- " builder.add_node(\"travel_advisor\", call_travel_advisor)\n",
- " builder.add_node(\"hotel_advisor\", call_hotel_advisor)\n",
- " \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",
- " # 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)\n",
- " ```\n",
- " \n",
- " Let's test a multi turn conversation with this application.\n",
- "\n",
- " ```python\n",
- " import uuid\n",
- " \n",
- " thread_config = {\"configurable\": {\"thread_id\": str(uuid.uuid4())}}\n",
- " \n",
- " inputs = [\n",
- " # 1st round of conversation,\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(\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(\n",
- " resume=\"i like the first one. could you recommend something to do near the hotel?\"\n",
- " ),\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 isinstance(last_message, dict) or last_message.type != \"ai\":\n",
- " continue\n",
- " print(f\"{node_id}: {last_message.content}\")\n",
- " ```\n",
- " \n",
- " ```\n",
- " --- Conversation Turn 1 ---\n",
- " \n",
- " User: {'messages': [{'role': 'user', 'content': 'i wanna go somewhere warm in the caribbean'}]}\n",
- " \n",
- " travel_advisor: Based on the recommendations, Aruba would be an excellent choice for your Caribbean getaway! Aruba is known as \"One Happy Island\" and offers:\n",
- " - Year-round warm weather with consistent temperatures around 82°F (28°C)\n",
- " - Beautiful white sand beaches like Eagle Beach and Palm Beach\n",
- " - Clear turquoise waters perfect for swimming and snorkeling\n",
- " - Minimal rainfall and location outside the hurricane belt\n",
- " - A blend of Caribbean and Dutch culture\n",
- " - Great dining options and nightlife\n",
- " - Various water sports and activities\n",
- " \n",
- " Would you like me to get some specific hotel recommendations in Aruba for your stay? I can transfer you to our hotel advisor who can help with accommodations.\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",
- " hotel_advisor: Based on the recommendations, I can suggest two excellent options:\n",
- " \n",
- " 1. The Ritz-Carlton, Aruba - Located in Palm Beach\n",
- " - This luxury resort is situated in the vibrant Palm Beach area\n",
- " - Known for its exceptional service and amenities\n",
- " - Perfect if you want to be close to dining, shopping, and entertainment\n",
- " - Features multiple restaurants, a casino, and a world-class spa\n",
- " - Located on a pristine stretch of Palm Beach\n",
- " \n",
- " 2. Bucuti & Tara Beach Resort - Located in Eagle Beach\n",
- " - An adults-only boutique resort on Eagle Beach\n",
- " - Known for being more intimate and peaceful\n",
- " - Award-winning for its sustainability practices\n",
- " - Perfect for a romantic getaway or peaceful vacation\n",
- " - Located on one of the most beautiful beaches in the Caribbean\n",
- " \n",
- " Would you like more specific information about either of these properties or their locations?\n",
- " \n",
- " --- Conversation Turn 3 ---\n",
- " \n",
- " User: Command(resume='i like the first one. could you recommend something to do near the hotel?')\n",
- " \n",
- " travel_advisor: Near the Ritz-Carlton in Palm Beach, here are some highly recommended activities:\n",
- " \n",
- " 1. Visit the Palm Beach Plaza Mall - Just a short walk from the hotel, featuring shopping, dining, and entertainment\n",
- " 2. Try your luck at the Stellaris Casino - It's right in the Ritz-Carlton\n",
- " 3. Take a sunset sailing cruise - Many depart from the nearby pier\n",
- " 4. Visit the California Lighthouse - A scenic landmark just north of Palm Beach\n",
- " 5. Enjoy water sports at Palm Beach:\n",
- " - Jet skiing\n",
- " - Parasailing\n",
- " - Snorkeling\n",
- " - Stand-up paddleboarding\n",
- " \n",
- " Would you like more specific information about any of these activities or would you like to know about other options in the area?\n",
- " ```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "04d18c63-a0eb-45ac-86dc-0cc5bd683973",
- "metadata": {},
- "source": [
- "## Prebuilt implementations"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e0e4ce57-f8de-4f37-836e-c1e1a02dd7b7",
- "metadata": {},
- "source": [
- "LangGraph comes with prebuilt implementations of two of the most popular multi-agent architectures:\n",
- "\n",
- "- [supervisor](../../agents/multi-agent#supervisor) — individual agents are coordinated by a central supervisor agent. The supervisor controls all communication flow and task delegation, making decisions about which agent to invoke based on the current context and task requirements. You can use [`langgraph-supervisor`](https://github.com/langchain-ai/langgraph-supervisor-py) library to create a supervisor multi-agent systems.\n",
- "- [swarm](../../agents/multi-agent#supervisor) — agents dynamically hand off control to one another based on their specializations. The system remembers which agent was last active, ensuring that on subsequent interactions, the conversation resumes with that agent. You can use [`langgraph-swarm`](https://github.com/langchain-ai/langgraph-swarm-py) library to create a swarm multi-agent systems."
- ]
- }
- ],
- "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.12.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/docs/how-tos/multi_agent.md b/docs/docs/how-tos/multi_agent.md
new file mode 100644
index 000000000..fdd781d4f
--- /dev/null
+++ b/docs/docs/how-tos/multi_agent.md
@@ -0,0 +1,580 @@
+# Build multi-agent systems
+
+A single agent might struggle if it needs to specialize in multiple domains or manage many tools. To tackle this, you can break your agent into smaller, independent agents and composing them into a [multi-agent system](../concepts/multi_agent.md).
+
+In multi-agent systems, agents need to communicate between each other. They do so via [handoffs](#handoffs) — a primitive that describes which agent to hand control to and the payload to send to that agent.
+
+This guide covers the following:
+
+* implementing [handoffs](#handoffs) between agents
+* using handoffs and the prebuilt [agent](../agents/agents.md) to [build a custom multi-agent system](#build-a-multi-agent-system)
+
+To get started with building multi-agent systems, check out LangGraph [prebuilt implementations](#prebuilt-implementations) of two of the most popular multi-agent architectures — [supervisor](../agents/multi-agent.md#supervisor) and [swarm](../agents/multi-agent.md#swarm).
+
+## Handoffs
+
+To set up communication between the agents in a multi-agent system you can use [**handoffs**](../concepts/multi_agent.md#handoffs) — a pattern where one agent *hands off* control to another. Handoffs allow you to specify:
+
+- **destination**: target agent to navigate to (e.g., name of the LangGraph node to go to)
+- **payload**: information to pass to that agent (e.g., state update)
+
+### Create handoffs
+
+To implement handoffs, you can return `Command` objects from your agent nodes or tools:
+
+```python
+from typing import Annotated
+from langchain_core.tools import tool, InjectedToolCallId
+from langgraph.prebuilt import create_react_agent, InjectedState
+from langgraph.graph import StateGraph, START, MessagesState
+from langgraph.types import Command
+
+def create_handoff_tool(*, agent_name: str, description: str | None = None):
+ name = f"transfer_to_{agent_name}"
+ description = description or f"Transfer to {agent_name}"
+
+ @tool(name, description=description)
+ def handoff_tool(
+ # highlight-next-line
+ state: Annotated[MessagesState, InjectedState], # (1)!
+ # highlight-next-line
+ tool_call_id: Annotated[str, InjectedToolCallId],
+ ) -> Command:
+ tool_message = {
+ "role": "tool",
+ "content": f"Successfully transferred to {agent_name}",
+ "name": name,
+ "tool_call_id": tool_call_id,
+ }
+ return Command( # (2)!
+ # highlight-next-line
+ goto=agent_name, # (3)!
+ # highlight-next-line
+ update={"messages": state["messages"] + [tool_message]}, # (4)!
+ # highlight-next-line
+ graph=Command.PARENT, # (5)!
+ )
+ return handoff_tool
+```
+
+1. Access the [state](../concepts/low_level.md#state) of the agent that is calling the handoff tool using the [InjectedState][langgraph.prebuilt.InjectedState] annotation.
+2. The `Command` primitive allows specifying a state update and a node transition as a single operation, making it useful for implementing handoffs.
+3. Name of the agent or node to hand off to.
+4. Take the agent's messages and **add** them to the parent's **state** as part of the handoff. The next agent will see the parent state.
+5. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph.
+
+!!! tip
+
+ If you want to use tools that return `Command`, you can either use prebuilt [`create_react_agent`][langgraph.prebuilt.chat_agent_executor.create_react_agent] / [`ToolNode`][langgraph.prebuilt.tool_node.ToolNode] components, or implement your own tool-executing node that collects `Command` objects returned by the tools and returns a list of them, e.g.:
+
+ ```python
+ def call_tools(state):
+ ...
+ commands = [tools_by_name[tool_call["name"]].invoke(tool_call) for tool_call in tool_calls]
+ return commands
+ ```
+
+!!! Important
+
+ This handoff implementation assumes that:
+
+ - each agent receives overall message history (across all agents) in the multi-agent system as its input. If you want more control over agent inputs, see [this section](#control-agent-inputs)
+ - each agent outputs its internal messages history to the overall message history of the multi-agent system. If you want more control over **how agent outputs are added**, wrap the agent in a separate node function:
+
+ ```python
+ def call_hotel_assistant(state):
+ # return agent's final response,
+ # excluding inner monologue
+ response = hotel_assistant.invoke(state)
+ # highlight-next-line
+ return {"messages": response["messages"][-1]}
+ ```
+
+### Control agent inputs
+
+You can use the [`Send()`][langgraph.types.Send] primitive to directly send data to the worker agents during the handoff. For example, you can request that the calling agent populate a task description for the next agent:
+
+```python
+
+from typing import Annotated
+from langchain_core.tools import tool, InjectedToolCallId
+from langgraph.prebuilt import InjectedState
+from langgraph.graph import StateGraph, START, MessagesState
+# highlight-next-line
+from langgraph.types import Command, Send
+
+def create_task_description_handoff_tool(
+ *, agent_name: str, description: str | None = None
+):
+ name = f"transfer_to_{agent_name}"
+ description = description or f"Ask {agent_name} for help."
+
+ @tool(name, description=description)
+ def handoff_tool(
+ # this is populated by the calling agent
+ task_description: Annotated[
+ str,
+ "Description of what the next agent should do, including all of the relevant context.",
+ ],
+ # these parameters are ignored by the LLM
+ state: Annotated[MessagesState, InjectedState],
+ ) -> Command:
+ task_description_message = {"role": "user", "content": task_description}
+ agent_input = {**state, "messages": [task_description_message]}
+ return Command(
+ # highlight-next-line
+ goto=[Send(agent_name, agent_input)],
+ graph=Command.PARENT,
+ )
+
+ return handoff_tool
+```
+
+See the multi-agent [supervisor](../tutorials/multi_agent/agent_supervisor.md#4-create-delegation-tasks) example for a full example of using [`Send()`][langgraph.types.Send] in handoffs.
+
+## Build a multi-agent system
+
+You can use handoffs in any agents built with LangGraph. We recommend using the prebuilt [agent](../agents/overview.md) or [`ToolNode`](./tool-calling.md#toolnode), as they natively support handoffs tools returning `Command`. Below is an example of how you can implement a multi-agent system for booking travel using handoffs:
+
+```python
+from langgraph.prebuilt import create_react_agent
+from langgraph.graph import StateGraph, START, MessagesState
+
+def create_handoff_tool(*, agent_name: str, description: str | None = None):
+ # same implementation as above
+ ...
+ return Command(...)
+
+# Handoffs
+transfer_to_hotel_assistant = create_handoff_tool(agent_name="hotel_assistant")
+transfer_to_flight_assistant = create_handoff_tool(agent_name="flight_assistant")
+
+# Define agents
+flight_assistant = create_react_agent(
+ model="anthropic:claude-3-5-sonnet-latest",
+ # highlight-next-line
+ tools=[..., transfer_to_hotel_assistant],
+ # highlight-next-line
+ name="flight_assistant"
+)
+hotel_assistant = create_react_agent(
+ model="anthropic:claude-3-5-sonnet-latest",
+ # highlight-next-line
+ tools=[..., transfer_to_flight_assistant],
+ # highlight-next-line
+ name="hotel_assistant"
+)
+
+# Define multi-agent graph
+multi_agent_graph = (
+ StateGraph(MessagesState)
+ # highlight-next-line
+ .add_node(flight_assistant)
+ # highlight-next-line
+ .add_node(hotel_assistant)
+ .add_edge(START, "flight_assistant")
+ .compile()
+)
+```
+
+??? example "Full example: Multi-agent system for booking travel"
+
+ ```python
+ from typing import Annotated
+ from langchain_core.messages import convert_to_messages
+ from langchain_core.tools import tool, InjectedToolCallId
+ from langgraph.prebuilt import create_react_agent, InjectedState
+ from langgraph.graph import StateGraph, START, MessagesState
+ from langgraph.types import Command
+
+ # We'll use `pretty_print_messages` helper to render the streamed agent outputs nicely
+
+ def pretty_print_message(message, indent=False):
+ pretty_message = message.pretty_repr(html=True)
+ if not indent:
+ print(pretty_message)
+ return
+
+ indented = "\n".join("\t" + c for c in pretty_message.split("\n"))
+ print(indented)
+
+
+ def pretty_print_messages(update, last_message=False):
+ is_subgraph = False
+ if isinstance(update, tuple):
+ ns, update = update
+ # skip parent graph updates in the printouts
+ if len(ns) == 0:
+ return
+
+ graph_id = ns[-1].split(":")[0]
+ print(f"Update from subgraph {graph_id}:")
+ print("\n")
+ is_subgraph = True
+
+ for node_name, node_update in update.items():
+ update_label = f"Update from node {node_name}:"
+ if is_subgraph:
+ update_label = "\t" + update_label
+
+ print(update_label)
+ print("\n")
+
+ messages = convert_to_messages(node_update["messages"])
+ if last_message:
+ messages = messages[-1:]
+
+ for m in messages:
+ pretty_print_message(m, indent=is_subgraph)
+ print("\n")
+
+
+ def create_handoff_tool(*, agent_name: str, description: str | None = None):
+ name = f"transfer_to_{agent_name}"
+ description = description or f"Transfer to {agent_name}"
+
+ @tool(name, description=description)
+ def handoff_tool(
+ # highlight-next-line
+ state: Annotated[MessagesState, InjectedState], # (1)!
+ # highlight-next-line
+ tool_call_id: Annotated[str, InjectedToolCallId],
+ ) -> Command:
+ tool_message = {
+ "role": "tool",
+ "content": f"Successfully transferred to {agent_name}",
+ "name": name,
+ "tool_call_id": tool_call_id,
+ }
+ return Command( # (2)!
+ # highlight-next-line
+ goto=agent_name, # (3)!
+ # highlight-next-line
+ update={"messages": state["messages"] + [tool_message]}, # (4)!
+ # highlight-next-line
+ graph=Command.PARENT, # (5)!
+ )
+ return handoff_tool
+
+ # Handoffs
+ transfer_to_hotel_assistant = create_handoff_tool(
+ agent_name="hotel_assistant",
+ description="Transfer user to the hotel-booking assistant.",
+ )
+ transfer_to_flight_assistant = create_handoff_tool(
+ agent_name="flight_assistant",
+ description="Transfer user to the flight-booking assistant.",
+ )
+
+ # Simple agent tools
+ def book_hotel(hotel_name: str):
+ """Book a hotel"""
+ return f"Successfully booked a stay at {hotel_name}."
+
+ def book_flight(from_airport: str, to_airport: str):
+ """Book a flight"""
+ return f"Successfully booked a flight from {from_airport} to {to_airport}."
+
+ # Define agents
+ flight_assistant = create_react_agent(
+ model="anthropic:claude-3-5-sonnet-latest",
+ # highlight-next-line
+ tools=[book_flight, transfer_to_hotel_assistant],
+ prompt="You are a flight booking assistant",
+ # highlight-next-line
+ name="flight_assistant"
+ )
+ hotel_assistant = create_react_agent(
+ model="anthropic:claude-3-5-sonnet-latest",
+ # highlight-next-line
+ tools=[book_hotel, transfer_to_flight_assistant],
+ prompt="You are a hotel booking assistant",
+ # highlight-next-line
+ name="hotel_assistant"
+ )
+
+ # Define multi-agent graph
+ multi_agent_graph = (
+ StateGraph(MessagesState)
+ .add_node(flight_assistant)
+ .add_node(hotel_assistant)
+ .add_edge(START, "flight_assistant")
+ .compile()
+ )
+
+ # Run the multi-agent graph
+ for chunk in multi_agent_graph.stream(
+ {
+ "messages": [
+ {
+ "role": "user",
+ "content": "book a flight from BOS to JFK and a stay at McKittrick Hotel"
+ }
+ ]
+ },
+ # highlight-next-line
+ subgraphs=True
+ ):
+ pretty_print_messages(chunk)
+ ```
+
+ 1. Access agent's state
+ 2. The `Command` primitive allows specifying a state update and a node transition as a single operation, making it useful for implementing handoffs.
+ 3. Name of the agent or node to hand off to.
+ 4. Take the agent's messages and **add** them to the parent's **state** as part of the handoff. The next agent will see the parent state.
+ 5. Indicate to LangGraph that we need to navigate to agent node in a **parent** multi-agent graph.
+
+## Multi-turn conversation
+
+Users might want to engage in a *multi-turn conversation* with one or more agents. To build a system that can handle this, you can create a node that uses an [`interrupt`][langgraph.types.interrupt] to collect user input and routes back to the **active** agent.
+
+The agents can then be implemented as nodes in a graph that executes agent steps and determines the next action:
+
+1. **Wait for user input** to continue the conversation, or
+2. **Route to another agent** (or back to itself, such as in a loop) via a [handoff](#handoffs)
+
+```python
+def human(state) -> Command[Literal["agent", "another_agent"]]:
+ """A node for collecting user input."""
+ user_input = interrupt(value="Ready for user input.")
+
+ # Determine the active agent.
+ active_agent = ...
+
+ ...
+ return Command(
+ update={
+ "messages": [{
+ "role": "human",
+ "content": user_input,
+ }]
+ },
+ goto=active_agent
+ )
+
+def agent(state) -> Command[Literal["agent", "another_agent", "human"]]:
+ # The condition for routing/halting can be anything, e.g. LLM tool call / structured output, etc.
+ goto = get_next_agent(...) # 'agent' / 'another_agent'
+ if goto:
+ return Command(goto=goto, update={"my_state_key": "my_state_value"})
+ else:
+ return Command(goto="human") # Go to human node
+```
+
+??? example "Full example: multi-agent system for travel recommendations"
+
+ In this example, we will build a team of travel assistant agents that can communicate with each other via handoffs.
+
+ We will create 2 agents:
+
+ * travel_advisor: can help with travel destination recommendations. Can ask hotel_advisor for help.
+ * hotel_advisor: can help with hotel recommendations. Can ask travel_advisor for help.
+
+ ```python
+ from langchain_anthropic import ChatAnthropic
+ from langgraph.graph import MessagesState, StateGraph, START
+ from langgraph.prebuilt import create_react_agent, InjectedState
+ from langgraph.types import Command, interrupt
+ from langgraph.checkpoint.memory import MemorySaver
+
+
+ model = ChatAnthropic(model="claude-3-5-sonnet-latest")
+
+ class MultiAgentState(MessagesState):
+ last_active_agent: str
+
+
+ # Define travel advisor tools and ReAct agent
+ travel_advisor_tools = [
+ get_travel_recommendations,
+ make_handoff_tool(agent_name="hotel_advisor"),
+ ]
+ travel_advisor = create_react_agent(
+ model,
+ travel_advisor_tools,
+ prompt=(
+ "You are a general travel expert that can recommend travel destinations (e.g. countries, cities, etc). "
+ "If you need hotel recommendations, ask 'hotel_advisor' for help. "
+ "You MUST include human-readable response before transferring to another agent."
+ ),
+ )
+
+
+ def call_travel_advisor(
+ state: MultiAgentState,
+ ) -> Command[Literal["hotel_advisor", "human"]]:
+ # You can also add additional logic like changing the input to the agent / output from the agent, etc.
+ # NOTE: we're invoking the ReAct agent with the full history of messages in the state
+ response = travel_advisor.invoke(state)
+ update = {**response, "last_active_agent": "travel_advisor"}
+ return Command(update=update, goto="human")
+
+
+ # Define hotel advisor tools and ReAct agent
+ hotel_advisor_tools = [
+ get_hotel_recommendations,
+ make_handoff_tool(agent_name="travel_advisor"),
+ ]
+ hotel_advisor = create_react_agent(
+ model,
+ hotel_advisor_tools,
+ prompt=(
+ "You are a hotel expert that can provide hotel recommendations for a given destination. "
+ "If you need help picking travel destinations, ask 'travel_advisor' for help."
+ "You MUST include human-readable response before transferring to another agent."
+ ),
+ )
+
+
+ def call_hotel_advisor(
+ state: MultiAgentState,
+ ) -> Command[Literal["travel_advisor", "human"]]:
+ response = hotel_advisor.invoke(state)
+ update = {**response, "last_active_agent": "hotel_advisor"}
+ return Command(update=update, goto="human")
+
+
+ def human_node(
+ state: MultiAgentState, config
+ ) -> Command[Literal["hotel_advisor", "travel_advisor", "human"]]:
+ """A node for collecting user input."""
+
+ user_input = interrupt(value="Ready for user input.")
+ active_agent = state["last_active_agent"]
+
+ return Command(
+ update={
+ "messages": [
+ {
+ "role": "human",
+ "content": user_input,
+ }
+ ]
+ },
+ goto=active_agent,
+ )
+
+
+ builder = StateGraph(MultiAgentState)
+ builder.add_node("travel_advisor", call_travel_advisor)
+ builder.add_node("hotel_advisor", call_hotel_advisor)
+
+ # This adds a node to collect human input, which will route
+ # back to the active agent.
+ builder.add_node("human", human_node)
+
+ # We'll always start with a general travel advisor.
+ builder.add_edge(START, "travel_advisor")
+
+
+ checkpointer = MemorySaver()
+ graph = builder.compile(checkpointer=checkpointer)
+ ```
+
+ Let's test a multi turn conversation with this application.
+
+ ```python
+ import uuid
+
+ thread_config = {"configurable": {"thread_id": str(uuid.uuid4())}}
+
+ inputs = [
+ # 1st round of conversation,
+ {
+ "messages": [
+ {"role": "user", "content": "i wanna go somewhere warm in the caribbean"}
+ ]
+ },
+ # Since we're using `interrupt`, we'll need to resume using the Command primitive.
+ # 2nd round of conversation,
+ Command(
+ resume="could you recommend a nice hotel in one of the areas and tell me which area it is."
+ ),
+ # 3rd round of conversation,
+ Command(
+ resume="i like the first one. could you recommend something to do near the hotel?"
+ ),
+ ]
+
+ for idx, user_input in enumerate(inputs):
+ print()
+ print(f"--- Conversation Turn {idx + 1} ---")
+ print()
+ print(f"User: {user_input}")
+ print()
+ for update in graph.stream(
+ user_input,
+ config=thread_config,
+ stream_mode="updates",
+ ):
+ for node_id, value in update.items():
+ if isinstance(value, dict) and value.get("messages", []):
+ last_message = value["messages"][-1]
+ if isinstance(last_message, dict) or last_message.type != "ai":
+ continue
+ print(f"{node_id}: {last_message.content}")
+ ```
+
+ ```
+ --- Conversation Turn 1 ---
+
+ User: {'messages': [{'role': 'user', 'content': 'i wanna go somewhere warm in the caribbean'}]}
+
+ travel_advisor: Based on the recommendations, Aruba would be an excellent choice for your Caribbean getaway! Aruba is known as "One Happy Island" and offers:
+ - Year-round warm weather with consistent temperatures around 82°F (28°C)
+ - Beautiful white sand beaches like Eagle Beach and Palm Beach
+ - Clear turquoise waters perfect for swimming and snorkeling
+ - Minimal rainfall and location outside the hurricane belt
+ - A blend of Caribbean and Dutch culture
+ - Great dining options and nightlife
+ - Various water sports and activities
+
+ Would you like me to get some specific hotel recommendations in Aruba for your stay? I can transfer you to our hotel advisor who can help with accommodations.
+
+ --- Conversation Turn 2 ---
+
+ User: Command(resume='could you recommend a nice hotel in one of the areas and tell me which area it is.')
+
+ hotel_advisor: Based on the recommendations, I can suggest two excellent options:
+
+ 1. The Ritz-Carlton, Aruba - Located in Palm Beach
+ - This luxury resort is situated in the vibrant Palm Beach area
+ - Known for its exceptional service and amenities
+ - Perfect if you want to be close to dining, shopping, and entertainment
+ - Features multiple restaurants, a casino, and a world-class spa
+ - Located on a pristine stretch of Palm Beach
+
+ 2. Bucuti & Tara Beach Resort - Located in Eagle Beach
+ - An adults-only boutique resort on Eagle Beach
+ - Known for being more intimate and peaceful
+ - Award-winning for its sustainability practices
+ - Perfect for a romantic getaway or peaceful vacation
+ - Located on one of the most beautiful beaches in the Caribbean
+
+ Would you like more specific information about either of these properties or their locations?
+
+ --- Conversation Turn 3 ---
+
+ User: Command(resume='i like the first one. could you recommend something to do near the hotel?')
+
+ travel_advisor: Near the Ritz-Carlton in Palm Beach, here are some highly recommended activities:
+
+ 1. Visit the Palm Beach Plaza Mall - Just a short walk from the hotel, featuring shopping, dining, and entertainment
+ 2. Try your luck at the Stellaris Casino - It's right in the Ritz-Carlton
+ 3. Take a sunset sailing cruise - Many depart from the nearby pier
+ 4. Visit the California Lighthouse - A scenic landmark just north of Palm Beach
+ 5. Enjoy water sports at Palm Beach:
+ - Jet skiing
+ - Parasailing
+ - Snorkeling
+ - Stand-up paddleboarding
+
+ Would you like more specific information about any of these activities or would you like to know about other options in the area?
+ ```
+
+## Prebuilt implementations
+
+LangGraph comes with prebuilt implementations of two of the most popular multi-agent architectures:
+
+- [supervisor](../agents/multi-agent.md#supervisor) — individual agents are coordinated by a central supervisor agent. The supervisor controls all communication flow and task delegation, making decisions about which agent to invoke based on the current context and task requirements. You can use [`langgraph-supervisor`](https://github.com/langchain-ai/langgraph-supervisor-py) library to create a supervisor multi-agent systems.
+- [swarm](../agents/multi-agent.md#supervisor) — agents dynamically hand off control to one another based on their specializations. The system remembers which agent was last active, ensuring that on subsequent interactions, the conversation resumes with that agent. You can use [`langgraph-swarm`](https://github.com/langchain-ai/langgraph-swarm-py) library to create a swarm multi-agent systems.
\ No newline at end of file
diff --git a/docs/docs/how-tos/run-id-langsmith.ipynb b/docs/docs/how-tos/run-id-langsmith.ipynb
deleted file mode 100644
index 550c8ae64..000000000
--- a/docs/docs/how-tos/run-id-langsmith.ipynb
+++ /dev/null
@@ -1,274 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# How to pass custom run ID or set tags and metadata for graph runs in LangSmith\n",
- "\n",
- "
\n",
- "
Prerequisites
\n",
- "
\n",
- " This guide assumes familiarity with the following:\n",
- "
\n",
- "\n",
- "Debugging graph runs can sometimes be difficult to do in an IDE or terminal. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read the [LangSmith documentation](https://docs.smith.langchain.com) for more information on how to get started.\n",
- "\n",
- "To make it easier to identify and analyzed traces generated during graph invocation, you can set additional configuration at run time (see [RunnableConfig](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.config.RunnableConfig.html#langchain_core.runnables.config.RunnableConfig)):\n",
- "\n",
- "| **Field** | **Type** | **Description** |\n",
- "|-------------|---------------------|--------------------------------------------------------------------------------------------------------------------|\n",
- "| run_name | `str` | Name for the tracer run for this call. Defaults to the name of the class. |\n",
- "| run_id | `UUID` | Unique identifier for the tracer run for this call. If not provided, a new UUID will be generated. |\n",
- "| tags | `List[str]` | Tags for this call and any sub-calls (e.g., a Chain calling an LLM). You can use these to filter calls. |\n",
- "| metadata | `Dict[str, Any]` | Metadata for this call and any sub-calls (e.g., a Chain calling an LLM). Keys should be strings, values should be JSON-serializable. |\n",
- "\n",
- "LangGraph graphs implement the [LangChain Runnable Interface](https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.base.Runnable.html) and accept a second argument (`RunnableConfig`) in methods like `invoke`, `ainvoke`, `stream` etc.\n",
- "\n",
- "The LangSmith platform will allow you to search and filter traces based on `run_name`, `run_id`, `tags` and `metadata`.\n",
- "\n",
- "\n",
- "## TLDR\n",
- "\n",
- "```python\n",
- "import uuid\n",
- "# Generate a random UUID -- it must be a UUID\n",
- "config = {\"run_id\": uuid.uuid4()}, \"tags\": [\"my_tag1\"], \"metadata\": {\"a\": 5}}\n",
- "# Works with all standard Runnable methods \n",
- "# like invoke, batch, ainvoke, astream_events etc\n",
- "graph.stream(inputs, config, stream_mode=\"values\")\n",
- "```\n",
- "\n",
- "The rest of the how to guide will show a full agent.\n",
- "\n",
- "## Setup\n",
- "\n",
- "First, let's install the required packages and set our API keys"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {},
- "outputs": [],
- "source": [
- "%%capture --no-stderr\n",
- "%pip install --quiet -U langgraph langchain_openai"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "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\")\n",
- "_set_env(\"LANGSMITH_API_KEY\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "
\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",
- "metadata": {},
- "source": [
- "## Define the graph\n",
- "\n",
- "For this example we will use the [prebuilt ReAct agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [],
- "source": [
- "from langchain_openai import ChatOpenAI\n",
- "from typing import Literal\n",
- "from langgraph.prebuilt import create_react_agent\n",
- "from langchain_core.tools import tool\n",
- "\n",
- "# First we initialize the model we want to use.\n",
- "model = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n",
- "\n",
- "\n",
- "# For this tutorial we will use custom tool that returns pre-defined values for weather in two cities (NYC & SF)\n",
- "@tool\n",
- "def get_weather(city: Literal[\"nyc\", \"sf\"]):\n",
- " \"\"\"Use this to get weather information.\"\"\"\n",
- " if city == \"nyc\":\n",
- " return \"It might be cloudy in nyc\"\n",
- " elif city == \"sf\":\n",
- " return \"It's always sunny in sf\"\n",
- " else:\n",
- " raise AssertionError(\"Unknown city\")\n",
- "\n",
- "\n",
- "tools = [get_weather]\n",
- "\n",
- "\n",
- "# Define the graph\n",
- "graph = create_react_agent(model, tools=tools)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Run your graph\n",
- "\n",
- "Now that we've defined our graph let's run it once and view the trace in LangSmith. In order for our trace to be easily accessible in LangSmith, we will pass in a custom `run_id` in the config.\n",
- "\n",
- "This assumes that you have set your `LANGSMITH_API_KEY` environment variable.\n",
- "\n",
- "Note that you can also configure what project to trace to by setting the `LANGCHAIN_PROJECT` environment variable, by default runs will be traced to the `default` project."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "================================\u001b[1m Human Message \u001b[0m=================================\n",
- "\n",
- "what is the weather in sf\n",
- "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
- "Tool Calls:\n",
- " get_weather (call_9ZudXyMAdlUjptq9oMGtQo8o)\n",
- " Call ID: call_9ZudXyMAdlUjptq9oMGtQo8o\n",
- " Args:\n",
- " city: sf\n",
- "=================================\u001b[1m Tool Message \u001b[0m=================================\n",
- "Name: get_weather\n",
- "\n",
- "It's always sunny in sf\n",
- "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
- "\n",
- "The weather in San Francisco is currently sunny.\n"
- ]
- }
- ],
- "source": [
- "import uuid\n",
- "\n",
- "\n",
- "def print_stream(stream):\n",
- " for s in stream:\n",
- " message = s[\"messages\"][-1]\n",
- " if isinstance(message, tuple):\n",
- " print(message)\n",
- " else:\n",
- " message.pretty_print()\n",
- "\n",
- "\n",
- "inputs = {\"messages\": [(\"user\", \"what is the weather in sf\")]}\n",
- "\n",
- "config = {\"run_name\": \"agent_007\", \"tags\": [\"cats are awesome\"]}\n",
- "\n",
- "print_stream(graph.stream(inputs, config, stream_mode=\"values\"))"
- ]
- },
- {
- "attachments": {
- "d38d1f2b-0f4c-4707-b531-a3c749de987f.png": {
- "image/png": "iVBORw0KGgoAAAANSUhEUgAABUAAAAHACAIAAADsm1WnAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4XuydB5RURdqGnUTOOUgSBcmgIgiiEiQpiAQRUBFB17y6uuuuYf81u66rrhkUsyhKjiKIBMlBSSIqURBEchjCpP/pqba4dqK7p3ume+btM4fT1K34VN3b96svVEL58pXO0EcEREAEREAEREAEREAEREAEREAERCC2CSTGdvfUOxEQAREQAREQAREQAREQAREQAREQARcBCfBaByIgAiIgAiIgAiIgAiIgAiIgAiIQBwQkwMfBJKmLIiACIiACIiACIiACIiACIiACIiABXmtABERABERABERABERABERABERABOKAgAT4OJgkdVEEREAEREAEREAEREAEREAEREAEJMBrDYiACIiACIiACIiACIiACIiACIhAHBCQAB8Hk6QuioAIiIAIiIAIiIAIiIAIiIAIiIAEeK0BERABERABERABERABERABERABEYgDAhLg42CS1EUREAEREAEREAEREAEREAEREAERkACvNSACIiACIiACIiACIiACIiACIiACcUBAAnwcTJK6KAIiIAIiIAIiIAIiIAIiIAIiIAIS4LUGREAEREAEREAEREAEREAEREAERCAOCEiAj4NJUhdFQAREQAREQAREQAREQAREQAREQAK81oAIiIAIiIAIiIAIiIAIiIAIiIAIxAEBCfBxMEnqogiIgAiIgAiIgAiIgAiIgAiIgAhIgNcaEAEREAEREAEREAEREAEREAEREIE4ICABPg4mSV0UAREQAREQAREQAREQAREQAREQAQnwWgMiIAIiIAIiIAIiIAIiIAIiIAIiEAcEJMDHwSSpiyIgAiIgAiIgAiIgAiIgAiIgAiIgAV5rQAREQAREQAREQAREQAREQAREQATigIAE+DiYJHVRBERABERABERABERABERABERABCTAaw2IgAiIgAiIgAiIgAiIgAiIgAiIQBwQkAAfB5OkLoqACIiACIiACIiACIiACIiACIiABHitAREQAREQAREQAREQAREQAREQARGIAwIS4ONgktRFERABERABERABERABERABERABEZAArzUgAiIgAiIgAiIgAiIgAiIgAiIgAnFAQAJ8HEySuigCIiACIiACIiACIiACIiACIiACEuC1BkRABERABERABERABERABERABEQgDghIgI+DSVIXRUAEREAEREAEREAEREAEREAERCCpWLHioiACIiAC+ZJAuXJle/XqVaFC+S1btubLAWpQIiACIiACIiACIiACBYpAcrRH+9hj/ype3PceQVZWVmrqsd9++239+vULFy5KTU2NdmcKYP2NGjW66aYbwxv4Aw/8Iz093ZTt3r1bx44d+D5v3vyJEyeFV2G8l+ratcvll3diFF9//fX48RPjfTim/xUrVvz73/9mx7Jo0eIxY8YGP7SmTZsOHny9zT9hwsT5878OvnhUcyK9z537VdWqVWnlf/976fHHn4xqc/mj8pIlS7LIu3XrWqdO7UqVKiUkJOzevXvz5i2ffz5jxowvDh8+nD+GqVGIgAiIgAiIgAiIQJwSiLoAf+211/IafVo6x44dGzXq4yeeeEoviKdlFVKGWrVqDh58Q0hFbOYHH3zYCvAXXHC+qef48RMFVoA/77zzDASw5BsBvkyZMs4V0qVL5/HjJ2RkZAS5Zm6//da+ffvYzD/++GPsCPBt2rQx0jvd69u3rwT4wHOalJQ0ZMiN//jHA6VLl3bmhGGzZs169brq4MGDTz/973feeTf45RG4RV0VAREQAREQAREQAREIlUCs+MAXLVp06NCb5s2bc955LUIdg/KLgAhEikCVKlU6deoYZG2lSpW68sorgsyc+9nWrFlz/Phx0+7SpUs9OvD888/NmDGdv4svbpv7fYu1FpOTk99++61nnnnKKb2fdH3SbFe5RIa33hqBqB/Z/lOhmQv+ZVFFtnLVJgIiIAIiIAIiIAL5iUDUNfAhwapR48xRoz5s377Tzp07QyqozP4ILF26rH//Ad5XGzdu/MgjD5l0nxm4lJZ26t3duwal5FcC1103CGPpYEbXp0/vIkWKBJMzT/Js3brtyiuvGjCg/86du0aMeNOjD/Xr1z///PNILFeuXJ50L6Ya/c9/nr3iiu6mS8uXr3jjjeHz5s3bt28/KZUrV77sskvvuOP2hg0b8N8ePa5EjP/rXx+IYP8x1DdzQZ0pKbH1qxTBYaoqERABERABERABEcg5gVx9VcJ9+tln/2M7jW981apVOnbsyItjYqLbFqBChQr/+98L11xzbc7HphogsGfPni+/nO2NwtrGc8lnBu8iSsnfBLZv34G3S7FixXCBxvkZz+fTjve66waaPOvWfdeoUcPT5s/9DN9mf3K/3fhqkUAG118/yPT5lVdeffTRxwlQYofw66+/jh796dix47BZGDjQtRt4442D3333PSY9voap3oqACIiACIiACIhAPiCQqyb0e/fuW7x4if1Dbvzww1FDhgzt2fNqa+kK0w4d2terd04+gKshiEAcEcCx2SjesaYeMOD0O2hI7LhGM8D167//+eef42ik6qoHgb59e5uUVatW/etfjzmld5uTLb+//OX+LVu2kILCvHfvq4VRBERABERABERABEQg9wnkqgbe3/AWL178/PMvPPjgP2wGAp7/8MOP5r+FCqU0bNjIXuIN8sCBA95VIfPbI/H279+/deupU6Nq1qxRrlx5U2Tv3j0//7zdfK9duzax2TCgRU39448/4THrXa13CgalzZs3q1ixQtGixWho+/btK1asLIDW5rzEt2jRHCmucOEi6OjQc1qw3tDOOecccxjBhg0bCFhIhjp16gC/WrVqx48fGz7c07yZDIUKFSIgwtln12Va4bxu3ToERZ+ihXdz9I310LBhw/Lly3O6AR4Za9eu47wD75w+U+rWrcsUU5aQij/99BMWxUG2a2o7++yzMTYmujsOxJBZsmQp0b98NhRTiZguE57w6qt70StU6y+99HLgUQ8a5Fa/T5w4sWXLlkGOpUSJEsx7rVq1ChcuzI3MtAZW5BJBjTuOyrnRuE/5Et7C27x5s5kFmi5b1hVWk9Vr+sxcb9vm3oDYuHGjvziarKgmTZqwKphWOsOq8PkgMnXSSbO7wbaIfbBgJW7WJKH+pk6dFiSxXMhGr0wrU6ZMDdAcMvwHH3xkdPUege68S/Fk4AgMQiQeOXJk06bNK1eucLrT2/zkSWHlJZ9yqm/evDlbvSYDGwpmEVqepMPTXxQ9bj0WGHk8fiYIrc9NTTprgJVgKucRxBrA5is19eiGDT+sXPmNv2q9R6cUERABERABERABEcgrAjEhwDP4yZOnOgV45D1LhKhas2bNsP+96aZhkyZN9ub1+uuvmjfm7NqmoNi3ef72t79ee21/89+PPhr15z/fi7M9Pp8ewbq++279ww8/gp2/d+UmhXhdf/nLPbzE8zbpzHP06NFPP/3sueeeR1rzVzafpXfq1Omppx4/66yz7Lh4z547d959992P47H3YF955SXj49qpU5dNmza98MJ/8aQ1fhMI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dBs/fqIzZKnHdLCKLrusI442zl8Bnhg8fnksOI+i9NdD0lnMPXv2Qp/v8ZOxdes2jnhkru3ZeAEq0SUREAEREAEREAERyCsCCeXLV8qrtsNrF/0MZwURPurAgYObN2/OTZWd6TCaH2z1y5Urh54WE1PcXwljHt5YVCowAdTpKNXLlCmdmnqMPRQc3YMxVMZUu02bizCsxdmVUgsXLmKaAjfkcZWyxF1HnX7o0OEffvjB21o4QG2sT8pSQ8mSJdhTQOzBFN+aAQcoWEAucVoEfGrWrFm4cCFuYUyauYvzduwYBWCYXbp0KUQ7TL79TRYqZdwxWBUIeOzZIY46w7Dn7RAi2zrm6MwRDzqsyk+cOI5SHQMWIomG9LAlOgC4KlWqiJzMDchdwM0YTD8x2q9b9yz+xUcGodpnEe4yDqKnewcPHmL92AB4PjOTiJ0FLjl8wbzi0kvdwTXQ5LNTzE8J88htTqSGkAbory2li4AIiIAIiIAIiEBUCcSfAB9VHKpcBERABEQgnxHwKcDnszFqOCIgAiIgAiIgAgWEQKyY0BcQ3BqmCIiACIiACIiACIiACIiACIiACIRHQAJ8eNxUSgREQAREQAREQAREQAREQAREQARylYAE+FzFrcZEQAREQAREQAREQAREQAREQAREIDwCEuDD46ZSIiACIiACIiACIiACIiACIiACIpCrBCTA5ypuNSYCIiACIiACIiACIiACIiACIiAC4RFQFPrwuKmUCIiACIhAfBAoUaJE7dq16StH0OvUz/iYM/VSBERABERABETADwEJ8H7AKFkEREAEREAEREAEREAEREAEREAEYomATOhjaTbUFxEQAREQAREQAREQAREQAREQARHwQ0ACvB8wShYBERABERABERABERABERABERCBWCIgAT6WZkN9EQEREAEREAEREAEREAEREAEREAE/BCTA+wGjZBEQAREQAREQAREQAREQAREQARGIJQIS4GNpNtQXERABERABERABERABERABERABEfBDQAK8HzBKFgEREAEREAEREAEREAEREAEREIFYIiABPpZmQ30RAREQAREQAREQAREQAREQAREQAT8EJMD7AaNkERABERABERABERABERABERABEYglAhLgY2k21BcREAEREAEREAEREAEREAEREAER8ENAArwfMEoWAREQAREQAREQAREQAREQAREQgVgiIAE+lmZDfREBERABERABERABERABERABERABPwQkwPsBo2QREAEREAEREAEREAEREAEREAERiCUCEuBjaTbUFxEQAREQAREQAREQAREQAREQARHwQ0ACvB8wShYBERABERABERABERABERABERCBWCIgAT6WZkN9EQEREAEREAEREAEREAEREAEREAE/BCTA+wGjZBEQAREQAREQAREQAREQAREQARGIJQIS4GNpNtQXERABERABERABERABERABERABEfBDQAK8HzBKFgEREAEREAEREAEREAEREAEREIFYIiABPpZmQ30RAREQAREQAREQAREQAREQAREQAT8EJMD7AaNkERABERABERABERABERABERABEYglAhLgY2k21BcREAEREAEREAEREAEREAEREAER8ENAArwfMEoWAREQAREQAREQAREQAREQAREQgVgiIAE+lmZDfREBERABERABERABERABERABERABPwQkwPsBo2QREAEREAEREAEREAEREAEREAERiCUCydHrzOq166JXeezX3LRxo9jvpHooAiIgAiIgAiIgAiIgAiIgAiIQLwSkgY+XmVI/RUAEREAEREAEREAEREAEREAECjQBCfAFevo1eBEQAREQAREQAREQAREQAREQgXghIAE+XmZK/RQBERABERABERABERABERABESjQBBLq1ZerdoFeARq8CIiACIiACIiACIiACIiACIhAXBCQBj4upkmdFAEREAEREAEREAEREAEREAERKOgEEsqXr1TQGWj8IiACIiACIiACIiACIiACIiACIhDzBKSBj/kpUgdFQAREQAREQAREQAREQAREQARE4IwzJMBrFYiACIiACIiACIiACIiACIiACIhAHBCQAB8Hk6QuioAIiIAIiIAIiIAIiIAIiIAIiIAEeK0BERABERABERABERABERABERABEYgDAhLg42CS1EUREAEREAEREAEREAEREAEREAERkACvNSACIiACIiACIiACIiACIiACIiACcUBAAnwcTJK6KAIiIAIiIAIiIAIiIAIiIAIiIAIS4LUGREAEREAEREAEREAEREAEREAERCAOCEiAj4NJUhdFQAREQAREQAREQAREQAREQAREQAK81oAIiIAIiIAIiIAIiIAIiIAIiIAIxAEBCfBxMEnqogiIgAiIgAiIgAiIgAiIgAiIgAhIgNcaEAEREAEREAEREAEREAEREAEREIE4ICABPg4mSV0UAREQAREQAREQAREQAREQAREQAQnwWgMiIAIiIAIiIAIiIAIiIAIiIAIiEAcEJMDHwSSpiyIgAiIgAiIgAiIgAiIgAiIgAiIgAV5rQAREQAREQAREQAREQAREQAREQATigIAE+DiYJHVRBERABERABERABERABERABERABCTAaw2IgAiIgAiIgAiIgAiIgAiIgAiIQBwQkAAfB5OkLoqACIiACIiACIiACIiACIiACIiABHitAREQAREQAREQAREQAREQAREQARGIAwIS4ONgktRFERABERABERABERABERABERABEZAArzUgAiIgAiIgAiIgAiIgAiIgAiIgAnFAQAJ8HEySuigCIiACIiACIiACIiACIiACIiACEuC1BkRABERABERABERABERABERABEQgDghIgI+DSVIXRUAEREAEREAEREAEREAEREAEREACvNaACIiACIiACIiACIiACIiACIiACMQBAQnwcTBJ6qIIiIAIiIAIiIAIiIAIiIAIiIAISIDXGhABERABERABERABERABERABERCBOCAgAT4OJkldFAEREAEREAEREAEREAEREAEREAEJ8FoDIiACIiACIiACIiACIiACIiACIhAHBCTAx8EkqYsiIAIiIAIiIAIiIAIiIAIiIAIiIAFea0AEREAEREAEREAEREAEREAEREAE4oCABPg4mCR1UQREQAREQAREQAREQAREQAREQAQkwGsNiIAIiIAIiIAIiIAIiIAIiIAIiEAcEEjO/T4mFEpJKl48qWhRviQmJ5+RkJD7fVCLYRLIyspMT886mZZx7FjG0aN8CbOeUIolJSUXKlQoOSWZT0L2J5TSyisCeUYgK/uTzict/eTJkxkZ6bnQFd0vuQBZTYiACIhAHhLIkx+XPByvmhYBEfAgkFC+fKVcg5JYpEhy2TLJJYrnWotqKKoE0o8cTd9/IPP48Si1gsRetFgxpPco1a9qRSA3CSDDH0tNRZyPUqO6X6IEVtWKgAiIQCwTiPaPSyyPXX0TgYJJIPcE+JTy5VLKlYVyVkZG5omTWSdPZqZnnJGZkZWZVTDRx+OoExITzkhMSkxJSkgplFikcEKiywUjbd/+tL37Ij6cYsWKFy1W1LVgsrIyXErMjMzs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H54feyOQPAKa2U4rOHg8xRs2rM/NJWJPnjNHSRFAAAEEEEAAAQQQ2CmQgQMCCKSIwLZtW/WTIpWlmggggAACCCCAAAIIVD6BiM0MX/loqBECCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQgAA+IA1vIIAAAggggAACCCCAAAIIIJA4AgTwiXMuKAkCCCCAAAIIIIAAAggggAACAQUI4APS8AYCCCCAAAIIIIAAAggggAACiSNAAJ8454KSIIAAAggggAACCCCAAAIIIBBQIKN6jeoB3+QNBBBAAAEEEEAAAQQQQAABBBBIDAFa4BPjPFAKBBBAAAEEEEAAAQQQQAABBIIKZGzdsjVoAt5EAAEEEEAAAQQQQAABBBBAAIH4C9AC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RfFP9+7dunb9z0EHHVi3bt3c3LzVq1drwPDzz7/w008/2XfxucbqlGnsjxIYGb+ZWxutLwi/Z1Dz2w0YcKa+HRo1aqjyqMxffvnlCy9MXbBgQfBszbvlLViNGjUGDx7YrVvXvfbaq7jY89tvv02f/vYLL7yQn1/6te5zXH1tDR48yPr+WrNmrQbzv/TSVJUzlBIqjU7o5MmT9CER2tVXX+PIv8njj4/Wxi1bNg8adJbPBynIvvpqEF2XLie1bNlSD5U2btyo0zF9+vSZM98N8j1+xBGdevfWt/+h+vbXQVevXvPjjz9qGvn33//AXrDywup2vUePbv3799cJ1dfxqlUrZ8/+QAPQ/v7770BK5Sq/7jH0QVJWvXr1rl+/3siRI/7zn//stlt9fVMfccRRgQ5htgf6BJq/7q+//vqmm27x+8F4/vnnrdbE4IewvxvKR/rGG69v166d9rLuW8aMecz8TWnj5ZdfoRkfQz8iKQMJEMAHkonidsXwF110ib7niOGjqFyZst41elfN0luVblLUHU5dvevGnVYylj59v3TXm7tkVrS0OKPdzn46Ga70pml+nhSoIBHuvF/x2tSuXfu+++459thj7Fnstdfe+tHGc845Z8SIkc4bWcWr9957lxWgal/loxvrE0447oorrs7JyTZfQtWqVXGWrH//vjfddKP5QzbvanI4ffXqpYGRl19+pc/stbqrNrnpy6xlyxaTJk3Ul7TZUffNh+58de/+n/POG7F9+3azfd9991GfdvuhrS/FKlWynUUKskV35+bd9957z+89kEr72Wefd+58tJLpOYg9gA9nX79FEvKQIQPNWy+88JLuVPwmYyMCySugOSXMX2ugcEh/BSZBjRresNZ6Kdh78MH7dBmxtugioxmh9HPGGX2uvPKa//3vfz4saja//vprFYxZ2zVYplWrlvoZNGjQvffeP2nScz676BKkR4ebN286+uijnnji8exsP9eT3r1P0e24ot9rrvmvlpn0ycH5T8U2J5/cRds7dGj34Ycf2xPss88+7dt7b+v10qQbPgG84paTTjpRcaBWmfIbvV955RXnn3+ulaGutJrdunv3rrfccuvLL7/qUxIda/Toh8388OYtrZWtf+pHS2M8+OBD9ieGga6xkvHJ1vlPdSPyewaV8rzzhl122aU+3w6aOE2vCRMm3H33fc7cfLaU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"
- }
- },
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## View the trace in LangSmith\n",
- "\n",
- "Now that we've ran our graph, let's head over to LangSmith and view our trace. First click into the project that you traced to (in our case the default project). You should see a run with the custom run name \"agent_007\".\n",
- "\n",
- ""
- ]
- },
- {
- "attachments": {
- "410e0089-2ab8-46bb-a61a-827187fd46b3.png": {
- "image/png": "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Vy63y6ty5ao33XSrOrR06aIFC76zm61MmbI33zyCQ8eOHV67drXKQ+WkHz9+TAREu9A8SZw8eYKWDj/66OM333zLqjae0EOH3jRnzixkL5abn376Hw899LAbLY4ZM7pZs2YUnDfvex8JiAMGDLjvvnud9G3Xrt2TJ389efJkUUo5oeQPh66++mqkQ3rCm0n37t0XLFjgD72SPggBISAE/JmAP9og7tz5l0JWt25DR+zq1WugDxl/W+WvVy+nhp07dziqStK9RQCJrX37Dqq2sWPtSIfqEBq4Rx99TP2+7rrrypYt460O5HM9uGa//PKLkyZNRG+az00bm6tevcbChT/wveuuuwqwG/7c9Nat25KTk+kh/27b9oc/dzUg+iZTLiBOk3TSHwjExZWPiIhwqSeseVaqVNmlIj7K7I8axCNH/k5IuFSiRPE6deoS9J9dMm0HbxQKq1atHhUVzZKxbba6deupRC102uaRFG8R2LZt26FDf1evXu299z54//33nVSL7u2nnxb169eXPF27dmUl2knmAj/0zDPPrFjxi+5GdHR0hQrlMaa87bYRKEHxtnnhhef/9a9nC6qfUVERjRo1onV6VVB98PN2Dx06iDFDp07t16xZz28/763/d0+mnP+fI+mhPxBgOfSxx55OSIj/+OP3Tpw4YaZLPF9Gj34cAXH69K/Xr19jpojv8vijBpEFu927dzLmyMioKlWq2Q4+NDQE2ZH0PXt28S/2iHXq5AiCVpnr1q1PSlpa6t69e2zrkRSvE+jatVuNGrWcS4eq0RUrctxTGjZ0qCf2evfcq/DcufM42ejP3r17f/11DbaV118/SFmz4Zddo0ZN9yqXUvlD4MCB/VOnTuff/GlOWhECQkAInDhx7MyZMyVKxDz00D8qVKiYJxCkw1GjHkM6TElJ9oeblT8KiEDctStnldnu8nGNGrXDwsLJtmHDWqVftJutXLkKpUqVJhvSYUZGep7nJt8yIODyybfm/LOhM2fOqo6VKROoS8zoQceNG6dGMWSIxWpWPkJACNglEB4eFhrqjwtWdnsriULAKwRSU1PRHZ49e7Z48eKjRz+BTOKkWlZNH3roicqVq6SkpHz66YcnTx53kjl/DvnpFWsUEPFBsWKhLQtRNOJ9UqVKdbsCYr16FvUhH12bLVPWpq+6qluLFm0IgYGseerUyd9+27Bq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FNFRXJb0UHGDCWMXSYAESIAEbCagRQERgwoPf/X27Vus6CVNlpR6RJtnmRVYTwCXHy5CXIq4IHFZWl8RS5IACZAACZCA+xDQrn7u5YsXwJggQYIkH3zw5jWO8OjoGPcBy566PQF4pcDuUKwsQzoUF6Tbj4oDIAESIAESIAELCGhXQETn8UqOjooODArESzpBwoQRb9++0x2RMTFRMZQVLZhdZokrAeyVgmjYiHeIiDbwWYbiEDVgZZm6w7iSZH4SIAESIAG3JqBpARFk8WKOiHgbGBSElT7IiPjPrXGz8+5FAD7LkA1pd+hes8bekgAJkAAJ2E5A6wIiRojX84vnz+EoABnRz98PB/Q6QrVj+/hZAwkYEsA2ejhwySEaNiPa8NogARIgARLwWgJuICCKuUHwudevI+PpnJt5kAAJkAAJkAAJkAAJOJCARr2YHThiVk0CJEACJEACJEACJKBKgAKiKh6eJAESIAESIAESIAHvI0AB0fvmnCMmARIgARIgARIgAVUCFBBV8fAkCZAACZAACZAACXgfAQqI3jfnHDEJkAAJkAAJkAAJqBKggKiKhydJgARIgARIgARIwPsIUED0vjnniEmABEiABEiABEhAlQAFRFU8PEkCJEACJEACJEAC3keAAqL3zTlHTAIkQAIkQAIkQAKqBCggquLhSRIgARIgARIgARLwPgIUEL1vzjliEiABEiABEiABElAlQAFRFQ9PkgAJkAAJkAAJkID3EaCA6H1zzhGTAAmQAAmQAAmQgCoBCoiqeHiSBEiABEiABEiABLyPAAVE75tzjpgESIAESIAESIAEVAlQQFTFw5MkQAIkQAIkQAIk4H0EKCB635xzxCRAAiRAAiRAAiSgSoACoioeniQBEiABEiABEiAB7yNAAdH75pwjJgESIAESIAESIAFVAhQQVfHwJAmQAAmQAAmQAAl4HwEKiN435xwxCZAACZAACZAACagSoICoiocnSYAESIAESIAESMD7CFBA9L4554hJgARIgARIgARIQJUABURVPDxJAiRAAiRAAiRAAt5HgAKi9805R0wCJEACJEACJEACqgQoIKri4UkSIAESIAESIAES8D4CFBC9b845YhIgARIgARIgARJQJUABURUPT5IACZAACZAACZCA9xGggOh9c84RkwAJkAAJkAAJkIAqAQqIqnh4kgRIgARIgARIgAS8jwAFRO+bc46YBEiABEiABEiABFQJUEBUxcOTJEACJEACJEACJOB9BCgget+cc8QkQAIkQAIkQAIkoEqAAqIqHp4kARIgARIgARIgAe8jQAHR++acIyYBEiABEiABEiABVQJ+qme1dfKTT8pky5YNfQoLe7Rt2zb1zhUpUvjDDz9Enn379t26dVs9s+LZgICAChXKFylSJEOG9AkSJHz27NmVK1f2799/+fIVxfxMJAESIAESIAESsIRAzpw5SpUqhZwxMTErVqyMjIxUKYW3cMWKFeUZIiPfPXgQdvfu3cuXL0dHR8szIMUKYcDCIlmzZitbtoxo9NCh369f/0uxA+6b6DYCYvz48SdMGJ8mTRqwjoh4V6JEiSdPnqpwr1Wr1ldfdUCGjh07xVVA9Pf379Dhy86dOydLllTWxOBjx46NHPnDqVOnZaeYQAIkQAIkQAIkYJ5Ar1696tatI/Ldv39/585dKmXy5s07cuQIlQx37tyFlDlt2rSIiAijbFYIA5YUgcy6fPmSdOnSobldu3YvX75CpXtuesptlpihPhTSIUAHBPjXrfuZg4inTJly9epVAwcOkKTDqKio169fS80VL14cGTp2/MpBHWC1JEACJEACJODBBBInTly1ahVpgI0aNbRxsOnTp+vdu+fataslOcHGCtWLp0iRYsmSRUI6PHLkcJcuIeoaUPXaNHvWbQTEhg11F9Dt2/9AgYcftl9PilPywQcfrFy5/OOPC+IshMIZM2bWqFEzZ87cefN++NFHBTp0+Oq3337HKV9f38GDv+ncuZNiJUwkARIgARIgARIwRaB27VoJEybE2bVr1+HfKlWqJE0qX69TKL18+cpSpcpI/336aYVGjZpMmDDp8ePHyJ2UEl8rAAAgAElEQVQ/f/5JkyZivVGhpP2SIN0uWrQgW7bsqPLcuXPt2nV4+/at/arXUE2O5WivgQYFBdWoUR217dmzG7pc/ChU6OMcOXLYq36pnjFjRolqsSoNJeWPP466ePGSsGx4+fLljh07v/ii+ejRY2AzgSL9+/eDNtHufWCFJEACJEACJODBBITG5+rVawsWLMAwYfEvLTerjzo8/BUsDqXj5s0bx48fnzhxYvXqNW/c+BtlS5cuVb26Tlpw0JEgQYK5c3+GJIr6r137s3XrNq9evXJQWy6v1j0ExOrVq0FGBCyYKezcuVNQs7sSsWzZT2rWrInKnz591qhRY1y7itMzbdr0sWPH4RT0iMOHf+fj46OYzVWJfn5+WIJ3VetslwRIgARIgARUCMB6r2TJEsiAt/np02fCwsLwW4iMKqXUTz148GDo0OEiT8OGDdQzW30WL/3Q0CklS+p8a7Ce2aJFy8ePn1hdm/YLuoeAKC4dfDpghRdym/hQaNCggX2FM3iliAkbNmwYbGZVJm/mzFkXLlxABjhKwzjSMGefPn22bduC/7BarVjDokULcXbGjGmKZ6G77tKl8/r16y5evHD9+p+nTp2YP39uvXqfQeyT54cNh2irYMGCcKzp1Knj3r27rly5dPXqFaEHhVuPyJAlS1Z5cZFSsWIFkad7966m8jCdBEiABEiABOxCoH79+uLdjUU5LMft2KFzTylatIjKe8qSdg8cOBAeHo6cH330kSX545oHfR4zZnS1alVREEJt8+Yt7927Z6qSzJkzDx36v127duJ1fO3alUOHDk6cOEG+5NiuXTvx/q1bt66pqmDvuHXrZmSbNWumqTwOSncDATF16tRCCNu9e49wUNq6dTtwwCgVymR7ccEcQIOI2uAMJawiVGqGOSpkRJGhXr16hjnxbZRPf/j5+SrWkDt3LpzNkSOn/CzEzd27d8I/Bgvo0JjCkAK9gm//5MmT1qxZnTFjBqMiyZIlE2198EGSefPmfvPNIFhF4BNHynb+/HmRoUGD+vLmREqzZs1EnqNHT5jKw3QSIAESIAESsAsBofF5+PDhqVOnUOH27bFB62xcFcR7+eHDB6gwdepUdumnUSVDhgxu3LgREp8/f96yZSuhqFJsCC9ciIbt27dDKB8s6OHA6xuJq1at/OmnccL4UhQ8cuSIeP+2atVcsSokQsaAbIBsFy/+YSqPg9LdQECE/kwIPUIuBIgtW7YIHI0bN7YXl9KlS4tvGkRYFCaG6jVjsVvYpZYp8x8NonoplbOwacDVIzywzp49O2nSlKFDh/3882xozlEKfjPwmTJlxtu2bdtPPy2L/sBAc/HixatXrxEfUpB03717h+ING/5HipW6gQorVaqEP2HJcfToEZXu8RQJkAAJkAAJ2EigQIECEJtQyfbt24V9/6FDhyByIQVLwzauCgYFJUI94vVnYz9FcUkYwMoegt8hEd6rbdu2h3OCqfqbN/8CykLIhRgdVKRjx479/vsRCMHz5s0bFIGIOX78OGmYf+gPpJcoURI6L8U6GzbU6XfQk19+WaWYwXGJbiAgiq8KzMru3Tr3FBxnzpy9efMmftSsWV3YJtoOKHfu3KISSPSW1Aa71PPndavM+DIQF6UlpUzlwQryuHFjEiVKhG+ggQMH1q1bb/z48fPnzx8xYmTZsuVEVPCsWbP17/+1Yg1Ya963b3/p0p+0b//l4MHf9unTFza8yAnHLuHTA9U9In/Ky9apU1sYLK5c+YslYrG8BqaQAAmQAAmQgIUEJAPBjRs3iSIIbLx1q06JmClTRshJFtYjz4blu1SpdLrDW7duyc9al4IgdygI5d+AAf1FDZ06dT5xwuRqG4bw7bdDkPPRo0cNGjRE5JPQ0GmzZ8/p339AxYqV/vzzT5yqrT+k/qxcqRP7IDJi5V3eyezZs8OEDOmHDv0Gq0d5BoemaF1AzJs3DzSrQACNneFnwbp1G5AIyUx4N9vOKG3atKIS6L0trE2Y1iJz2rS68N22HNCSimHCG2vZsv/E24ResHv3niLWd9Omn6dIkVzeEHTdiAeOK1J+6pdffhGJiqvM4l7Fh86qVWvkZZlCAiRAAiRAAvYiAFUIXnaoDStjR4/qItaJY/369eJHo0bW+5fACl9U8uuvv9qrw9HRMcWKFRszZoyk84MuRqXyHj16QGkFbUunTiHwvzHMCes1CJdC4gwJiXV4QIZ169ZCRMYPuFXIa5Z8d6CDlJ91dIrWBUSJzoYNOolQOtat0wVPwtGokc4mwPYjUSKdlzSOhw8VxCzF+iUBEZo/xQyWJ4rviRcvXsyc+bO8FCwvoU1EOrR9n3xSVp5hxYpfhPpafmrv3n1C5K1Tp66Rp0vmzJlw6aPI/v0HhMZRXpwpJEACJEACJGAXAp9++mlwcDCqgvrQcGe8338/LBxDpfiIcWoOMlm/fv1at26NUljcEzq5ONVgKjO0P7NmzTAMDNKsWVNTmfGGrVatGs5CiDx27Kg8G1xs4UqBdLjRwLlCZMCecDBYxG/4J4j9gaWCerWizjwMS/BYkZdX6OgUTQuI8NIQXxugA0HHkAVUtQhQiZQyZUqLaOY2khJyPSpJmDDAwqoQD0nktD2EuvDCgSmGfJsg0cTBgwfFD/ivyLsnFtzl6UhB39asWYsfUD2WK1fOMI+kU3S+ZYNiV5lIAiRAAiTgwQQkBaGRxgfC4oYNGzFwxPFAVDsVAvD8GG1wIFLH4sWLTpw42q1biFDyDR48xI76jlGjfoREC1P+efPmCSusoUOHwtxLsYcFCuQXG7Dt2bNXMQMSDx48JE6J/TjEb6h4xA+jhb5ixYpjzRqngMslsbgVgqeYGpjz0yH8iZVfGCjIJad169bD3BVCJJgiNqGN3XvxQmckiwNb7V25ctWS2oS5A3K+fPnCkvym8iRPnky4NdWoUQPaZsVsyZLFBs2BX7M8Q1SU8iblIufKlSuF7h22rpIdJ06JaxFBH+2okJf3jSkkQAIkQAIkgKW2qlV1MWKg0TBafkUiXCq/+qoDfmBVcP36/ywYGqEzpcPDElzfvl9v32639WXRLoTX3r37QOWJ9yz8VKCtnDx5IiIlCwdQw76lTRvrZTJs2FCh+ZNPeuHChUSi4at8//79UKDCRfWzz+piew5JtyrJ05IEKa/QoSmaFhCl9eXPP2+aNWtmIxCpUsVqaHE92S4g3rih83rBkSlTpnjxdPvpmT2EaA/rAdgWmM2skiFFCp3KXRzS1WMqv6nwiqbyIx3R3k+dOo2acXPiFhVh3/Gn2ClIbwBhvLu5Sm08RQIkQAIkQAJxJSAtHyNG4MqVy0wVL1++HJZfRfgOxTyG0QffvYuErde9e3ehtNu4cTOCJSsWsSXxm2++Ef402EQNa33wFoDyr3fvXmPGjDWqNjj4vfomTq9yLGBioQ+O0tCIIXgf/FFQM3aXATH8uHTpMgKb2DIEq8tqV0AMDAyEk7I0MBG7XHGc8JmHm4+NBM+c0S1Y48CmkJZYg0K6woH88FGXlqcVu2c28fVrXWxPcUyZMlU9/59/Ku/vol4Kriq4XqGnrFmzxqpVq5FZUmW76tNEvcM8SwIkQAIk4EkEDPdKUXmhY8hQv82apWCOj1Nz584bNmy407AcOXJYchuFJqV79x6bNm3EmxTC3N69+41iw0l+tH/99dfmzVvVOwmtjWEGBBJBnUiBq4oQECtXriz0QVgDVK/KcWe1KyDqt9eLdf7AJCkikC6yxo0b2iggnjp1EpaOmA98vsCMAAuvUosIMbhw4QKsZSNkzJdfdhCGCPXrx8Y937tXZ3MqHQbBYpS34AsIiLVclIo8fBiGUrCf2Lp167hxuk387H5AY/+//32Ly7pOnToQEDEW4RaD/WBEECa7t8gKSYAESIAESEAQQJC/UqViQ9iYeqFnyJBJ7AeBCMemBEQn85wzZ55hi/Ay+eGHUdhiF+/QiRPH16hRU0RwFHkkref8+QvFHtOW9xYy5fHjJ4oVK4rALIMGfYP1688+q4PiWKJcu1bZ8Mzyyq3OqV0BUfraaNiw0YkTJxVHiAXTkyePQ+6pW/ez778fKbcJUCylmIiy8NX48sv2cD0ZMmTI11/3k7IdOHBw8uTQXr16VK5cKSSky9Sp03ARd+z4FTJAdwjB37BCyR4xadJkCENo1BZEXlgcGiWiaVx28GCCTzEuO0PfLsWuWpH48uXLbdu247MMGnL0IV++vDC1RD1UH1oBk0VIgARIgATiREDaXg8rs3iHmiqL3SKwH12ePLnh5yv2szWV01XpkPwqVCiHDSYQdvHHH0d27dpd6gnWgvH6xku8ZMnicRUQUcmqVb9AQEySJAkk6SNHjpYvXx6JcHB24XbPGvVihv+H2PgO8f9MSYdgB3M6RCrHD7joYk9hG6+YGTNmCguGJk0a4z/D2iZNmiS0vn379kFUasRJF9rN5ctX/PPPHcOcUAeKP8uUUdgGsF69OlI4JcNSW7Zsxp8Ydc2aNRVHAaMHeG+JAPSKGcwmCjU1zBqgIhW7SUJhjk2fzRZkBhIgARIgARKwhYCk8dm4UeetbOqA76k4ZeO2e6bqt0v611/3F1GHsSInNt8T1cIaUgR3xOowxEfFturWrYOhSR6uhnk2bNiEDUGQAhkDqhwRPs+1ShyNCojQdYnt9dQvJqCUtK+2X0/QDw8fPkJM2LhxY/v27QtxSvyJzwIYHyADejV79s9iy22ENUf8TKOL4PDh2NXwbt26CS2dlAE2iwMGDFS8aGD1KGTTESOGQ5VolAduU3C2Fzt/Fy9eQrEGs4m//fa7iLZdpQqu3srID28vw5V0szUwAwmQAAmQAAnElQA2ks2VKydKnTx56uZNtW1ONm3aJKJGQwYwCtwb10Ydlx/SYd++sWuMw4cPg8+N1NbcuXPxG6uakydPlnuUQsUzevSo8eN/2rt3t3wTOCi8xI4ylSvjJV0J9cC1GQ7OjhuI2Zo1KiBKu/EYRUuSjwdBnoUCtlKlyiIEkTyP5SnLli2XTB969Oj2228HIbFha0W4dOBDIXHi9wGxIVp16NBBLmDhBoCeGS3C5GLz5o3w24e6uGLFigMHDti0acOzZ0/Onz8v7w/8oEeM+AHpcH1fv37t119/DQU7FqNRyWeffbZhw3oRPxOL3YrhN+UVylNg5ijcUzAQca+60PRV3j2mkAAJkAAJeCQBgxe6mvoQY8crdd8+XcxjRB/EYpdmaezZs2fhwoXoHvR8kyZNlGRZqF2EVguLxZs3b0Ls7hw5ciRNmhTqIQgDa9asFnrBGTNmKG4YvWKFbh812LC1atUKP/DKttEF1kaAWrRBhP2BkIdgmaeyJbYYOQz4MA2giVjnsERctGiRjURGjvwBmrYhQ76BMSL0wGKe5HXu2rVLsW+Qw3r16rVy5Qp8PcBlfciQwVJZ6Ah79Og1bNgweW1IWbJkKS6jfv2+xuJ19+5d8Z9RNuxAjW18FMtamLh69SpYUoo1boikUsROC4szGwmQAAmQAAnEiQCW3cSGF1iIg4LQbFkERMQaK7JhVRCOoWbzuyoDdDqlSpXGil+RIoXxah4/frzoSb9+AzDkWrVqYa+y779XeN1jwXDqVOXIzTA9hIYVBUVVdtwSxjpKWtQgGmyvF2uOoD62tWvtbLWAL4Py5SvCnV7aTE90AMKf5JoOBbipbcUhONauXXfLli1SfEFsZwJVaJ069SDkqYwF0RxbtmwFVyajPFjaRgSmJk2a2misCsH38OEjonJ8mjjCG0ZldDxFAiRAAiTgbQTKlftUWFthPz2x76s6gZ07d8KrEnkQuFe+Sqte1plnsbUJ5ELxlsc+LmLfWnQAdoQhId2woYt8hzPIBjjVv/8AUy9fyBjQ44hRHDt27O+/rztzRPK2fIKDY8NNy8+ZSHkfyCVlqlTI8ygs1i3DRH73ToYsnz59emgT4c0OjSYuXKwCb9u2BUHPYR9Qo0YtuauyNGCUQmh1aOz++ed2nDysobmEozEUiq9ehd++feuKZTu7WAJ66tQpsKvFFJYrV0F++VpSA/OQAAmQAAmQAAmYJYB4yTlyZENQ52fPnkF+sGQPwJYtW44c+T1q7tevv1GMFLPNWZEhWB/PJOzhQ1HWRxed732EPgqIViCNh/iLy5YthhoZFpCtW7d5LzJbU5nzymCby+PHj+JihR7x88+bOa9htkQCJEACJEACJGCOwOrVCHZTDAZpRYuWULRTNFdB3M6rC4hatEGM2/hckRtxPkuUKOXv74/GISZiBdkVvYhzmy1aNId0iGLLlpnc5ijOlbIACZAACZAACSgRKFy48Lp1a5TOMC1elizZjCggnp1Yql6/fpMkHd648X6h+dix440bN3EaOwqIVqI2Mk+0shanFIP/FCw/KlWq2KdPbzSIwI2bN29xSstshARIgARIgARIQI0AAuU8efIE/i7YnQX54LmMaHpqBZx1jgKis0i7qB24hP/663apcdjGYuvxOBlEuqjjbJYESIAESIAEPJwAdl5BbDv4NkjjnD595rVrf2ph2BQQtTALDuwDdgSSaoc/zaBBg/fu1UWZ4kECJEACJEACDiVw6tQp+UKqQ1t0u8qxrCxJh9DdTJs2Y8KECYajcCFACohudznFrcObN2++ffs2grbfuXMHuwDBMz9u5ZmbBEiABEiABEjAMQT+/POvjh07JUuWDJ7OR48etTGYnX37SC9m+/JkbSRAAiRAAiRAAiTgBgTUvZi1GCjbDaCyiyRAAiRAAiRAAiTguQQoIHru3HJkJEACJEACJEACJGAVAQqIVmFjIRIgARIgARIgARLwXAIUED13bjkyEiABEiABEiABErCKAAVEq7CxEAmQAAmQAAmQAAl4LgEKiJ47txwZCZAACZAACZAACVhFgAKiVdhYiARIgARIgARIgAQ8lwAFRM+dW46MBEiABEiABEiABKwiQAHRKmwsRAIkQAIkQAIkQAKeS4ACoufOLUdGAiRAAiRAAiRAAlYRoIBoFTYWIgESIAESIAESIAHPJUAB0XPnliMjARIgARIgARIgAasIUEC0ChsLkQAJkAAJkAAJkIDnEqCA6Llzy5GRAAmQAAmQAAmQgFUEKCBahY2FSIAESIAESIAESMBzCVBA9Ny55chIgARIgARIgARIwCoCFBCtwsZCJEACJEACJEACJOC5BCggeu7ccmQkQAIkQAIkQAIkYBUBCohWYWMhEiABEiABEiABEvBcAhQQPXduOTISIAESIAESIAESsIoABUSrsLEQCZAACZAACZAACXguAT93GZqvr19AQICfvx8OH/3hLj1nP0mABEiABEiABEhAhUCM/ojE8S4yIiIiKipSJbNzTrmBgAiJMDAoCNKhc4iwFRIgARIgARIgARJwJgGh+YKogyMoURBkxNfh4RAXndkHo7a0LiAGBSUKDApEpyFZR7x9+053RMbERMXEuBAamyYBEiABEiABEiABuxHAsqiPj6+/v5+/v39AggRCUnwdDinx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vNxYE1H8uF1jDyYYmZOaDx/cVzk526sWMc1WBERABOrU8QTwmdfGjRsXLFhIpptgj9qrxhgjTiByL00yGksjGnW4cGFkbsCdJ9cg72r8iEfO0pCJFZOpJ3IQaqUiIAIRRAA5OG/evD17solKrgZHJ5f7nYtEgQhENKLJiUjuj/vvfyBS1WG5P07qUAREQAREQASqDIF//vPFKjPXSp9ohApEOH9W9Kp04BpQBERABERABERABMKdQMnhWuE+U81PBERABERABERABESgUghIIFYKZg0iAiIgAiIgAiIgAlWHgARi1blXmqkIiIAIiIAIiIAIVAoBCcRKwaxBREAEREAEREAERKDqEJBArDr3SjMVAREQAREQAREQgUohIIFYKZg1iAiIgAiIgAiIgAhUHQISiFXnXmmmIiACIiACIiACIlApBCQQKwWzBhEBERABERABERCBqkMg7ATi+fPnoRcVVXUQaqYiIAIiIAIiIAIiUGEEjCgyAqnCBvHuOGwFYrT3TPW3CIiACIiACIiACEQegagojyiKdIFYWFgIhdjYyD0DMPKefK1YBERABERABETAJwEjioxA8lmpvC+EnQWx8IwRiLHlvVL1JwIiIAIiIAIiIAJVj0BsrEcUGYFUabMPO4FYUFDA4uPi42vWlB9ipT0GGkgEREAEREAERCAcCSCHEEXMzAikSpti2AnEs2cLQRAVFZWYmFRpFDSQCIiACIiACIiACIQhAeQQoghphECqzOmFnUBk8Xm5ufw3ITExLi6uMlloLBEQAREQAREQAREIHwIIIeQQ8zHSqDInFo4CETfMvNw8KNRKSYmOVrRKZT4PGksEREAEREAERCAsCCCBEEJMBVFUyREqDBqOApFp5eaeys/Px6Zap24d2RHD4jnVJERABERABERABCqLAOIHCYQQQg4hiipr2JJxwtc+dzInh2nGx8en1K59Oo9X7rlznhzaeomACIiACIiACIhAdSVAVAp+h2ZnGXVo5FDlLzZ8BSIsgHLu7LnEpEQwxSckFOTnn/G8Cs+fP1t03opeIiACIiACIiACIlDlCXBWCtmwyXdIRhtiljEcsiR2li+J7dDQDGuByBRBU1CQn5iUhK0Vjci7yj8FWoAIiIAIiIAIiIAI+CZAzDLasPL9Du0zCneByFwBXtW3OQAAIABJREFUlHPiBK6aaMSY2Bhe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iIAIiIAIiIAIhCEBI96MkHOdXpkEYkFBPp3GxcfXrCk/RFe8KhQBERABERABERCB8CKAbEO8MScj5FwnVyaBePbsWbqOiopKTExy7V2FIiACIiACIiACIiACYUUA2YZ4Q8Ih5HxNrEwCkU5zT+Xy34TExLi4OF9jqFwEREAEREAEREAERCAcCCDYkG3MxEg4X1MKQSBetJtcWFhoBqiVkhIdrWgVX5xVLgIiIAIiIAIiIAKXmABSDcHGJBBvSLiLZ3ORwItOSkoOdrJeiQ/PnCmIjvG84hPisVX6MVcGO5Dqi4AIiIAIiIAIiIAIlAsBbIe169Rmczk/P//UyRwSFVrdFkm7MgtExyyjCvJPF2tEAlaios6eLSxKoa2XCIiACIiACIiACIjAJSZAVAoGweRatYw6zDlx3EsOVpBA9Cw7/3R+VI2o2LjYmNjYhITE6OhoJlEkEyUVL/FjoeFFQAREQAREQAQijQCar2bNaKyGiYmJybVSTF4bdpZP5uQ45aBLSf36jYJH5no0i6cwJiY2KTkpvih2Wi8REAEREAEREAEREIFwIMC2cpHf4RmnFmR6zsKokAQiXfnUiFzDBTI+Pi42Li4mBjsie87KkhgOz4bmIAIiIAIiIAIiECkEEGqcpMdZKWfIZ5NfgPsfK3cKQV+F5Rx3zMDYEZlEbm5hjVxPBpyil3aZL5DQ/xcBERABERABERCByiDgbZ4Lyl4XskAs8jD0Fn5FMTA+yt1QeLd3q6MyERABERABERABERABXwS8haBrPVfbITV9lYcsED19+jANerQjlx3y0TnhgJbkbKYSERABERABERABERCBQAhcMBz6El3u5SEkyi6ZjG/nQmNKNLI0kMmrjgiIgAiIgAiIgAiIQHkSQBr6V4e+hVyNslgQPWswToduqykWpEUzK2UrOQBbo9sIKhMBERABERABERCBiCQQgEOhu2nQouW/h7IKRI9EdHE69LpXXlP01ov+pxiR912LFgEREAEREAEREIGgCJSiCO19FUkvf/XLLhA9AwTsdGjm5m9CQZFQZREQAREQAREQAREQgcAJ+N90tvopkw+ibTZFQlTCL/D7o5oiIAIiIAIiIAIiULkEAlSHTKpcLIhmcUYjBhi/XLk8NJoIiIAIiIAIiIAIRDCBwKWhgVSOAtF0KJkYwU+fli4CIiACIiACIhBmBIKVhmb65S4QTbclMtH8rTjlMHtaNB0REAEREAEREIFqS+Bir79QXAArSCAa4iUTMlEs1fY+aGEiIAIiIAIiIAIiEEYEQhGF9ulXqEC0D1TWiYYRc01FBERABERABERABKo1gfKKYq7WkLQ4ERABERABERABEYgkAhKIkXS3tVYREAEREAEREAERCICABGIAkFRFBERABERABERABCKJgARiJN1trVUEREAEREAEREAEAiAggRgAJFURAREQAREQAREQgUgi8P8DjezhV1S5aa0AAAAASUVORK5CYII="
- }
- },
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "In addition, you will be able to filter traces after the fact using the tags or metadata provided. For example,\n",
- "\n",
- "\n"
- ]
- }
- ],
- "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": 4
-}
diff --git a/docs/docs/how-tos/run-id-langsmith.md b/docs/docs/how-tos/run-id-langsmith.md
new file mode 100644
index 000000000..0cd87e864
--- /dev/null
+++ b/docs/docs/how-tos/run-id-langsmith.md
@@ -0,0 +1,155 @@
+# How to pass custom run ID or set tags and metadata for graph runs in LangSmith
+
+!!! tip "Prerequisites"
+ This guide assumes familiarity with the following:
+
+ - [LangSmith Documentation](https://docs.smith.langchain.com)
+ - [LangSmith Platform](https://smith.langchain.com)
+ - [RunnableConfig](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.config.RunnableConfig.html#langchain_core.runnables.config.RunnableConfig)
+ - [Add metadata and tags to traces](https://docs.smith.langchain.com/how_to_guides/tracing/trace_with_langchain#add-metadata-and-tags-to-traces)
+ - [Customize run name](https://docs.smith.langchain.com/how_to_guides/tracing/trace_with_langchain#customize-run-name)
+
+Debugging graph runs can sometimes be difficult to do in an IDE or terminal. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read the [LangSmith documentation](https://docs.smith.langchain.com) for more information on how to get started.
+
+To make it easier to identify and analyzed traces generated during graph invocation, you can set additional configuration at run time (see [RunnableConfig](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.config.RunnableConfig.html#langchain_core.runnables.config.RunnableConfig)):
+
+| **Field** | **Type** | **Description** |
+|-------------|---------------------|--------------------------------------------------------------------------------------------------------------------|
+| run_name | `str` | Name for the tracer run for this call. Defaults to the name of the class. |
+| run_id | `UUID` | Unique identifier for the tracer run for this call. If not provided, a new UUID will be generated. |
+| tags | `List[str]` | Tags for this call and any sub-calls (e.g., a Chain calling an LLM). You can use these to filter calls. |
+| metadata | `Dict[str, Any]` | Metadata for this call and any sub-calls (e.g., a Chain calling an LLM). Keys should be strings, values should be JSON-serializable. |
+
+LangGraph graphs implement the [LangChain Runnable Interface](https://python.langchain.com/api_reference/core/runnables/langchain_core.runnables.base.Runnable.html) and accept a second argument (`RunnableConfig`) in methods like `invoke`, `ainvoke`, `stream` etc.
+
+The LangSmith platform will allow you to search and filter traces based on `run_name`, `run_id`, `tags` and `metadata`.
+
+## TLDR
+
+```python
+import uuid
+# Generate a random UUID -- it must be a UUID
+config = {"run_id": uuid.uuid4()}, "tags": ["my_tag1"], "metadata": {"a": 5}}
+# Works with all standard Runnable methods
+# like invoke, batch, ainvoke, astream_events etc
+graph.stream(inputs, config, stream_mode="values")
+```
+
+The rest of the how to guide will show a full agent.
+
+## Setup
+
+First, let's install the required packages and set our API keys
+
+```python
+%%capture --no-stderr
+%pip install --quiet -U langgraph langchain_openai
+```
+
+```python
+import getpass
+import os
+
+
+def _set_env(var: str):
+ if not os.environ.get(var):
+ os.environ[var] = getpass.getpass(f"{var}: ")
+
+
+_set_env("OPENAI_API_KEY")
+_set_env("LANGSMITH_API_KEY")
+```
+
+!!! tip
+ Sign up for LangSmith to quickly spot issues and improve the performance of your LangGraph projects. [LangSmith](https://docs.smith.langchain.com) lets you use trace data to debug, test, and monitor your LLM apps built with LangGraph — read more about how to get started [here](https://docs.smith.langchain.com).
+
+## Define the graph
+
+For this example we will use the [prebuilt ReAct agent](https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/).
+
+```python
+from langchain_openai import ChatOpenAI
+from typing import Literal
+from langgraph.prebuilt import create_react_agent
+from langchain_core.tools import tool
+
+# First we initialize the model we want to use.
+model = ChatOpenAI(model="gpt-4o", temperature=0)
+
+
+# For this tutorial we will use custom tool that returns pre-defined values for weather in two cities (NYC & SF)
+@tool
+def get_weather(city: Literal["nyc", "sf"]):
+ """Use this to get weather information."""
+ if city == "nyc":
+ return "It might be cloudy in nyc"
+ elif city == "sf":
+ return "It's always sunny in sf"
+ else:
+ raise AssertionError("Unknown city")
+
+
+tools = [get_weather]
+
+
+# Define the graph
+graph = create_react_agent(model, tools=tools)
+```
+
+## Run your graph
+
+Now that we've defined our graph let's run it once and view the trace in LangSmith. In order for our trace to be easily accessible in LangSmith, we will pass in a custom `run_id` in the config.
+
+This assumes that you have set your `LANGSMITH_API_KEY` environment variable.
+
+Note that you can also configure what project to trace to by setting the `LANGCHAIN_PROJECT` environment variable, by default runs will be traced to the `default` project.
+
+```python
+import uuid
+
+
+def print_stream(stream):
+ for s in stream:
+ message = s["messages"][-1]
+ if isinstance(message, tuple):
+ print(message)
+ else:
+ message.pretty_print()
+
+
+inputs = {"messages": [("user", "what is the weather in sf")]}
+
+config = {"run_name": "agent_007", "tags": ["cats are awesome"]}
+
+print_stream(graph.stream(inputs, config, stream_mode="values"))
+```
+
+**Output:**
+```
+================================ Human Message ==================================
+
+what is the weather in sf
+================================== Ai Message ===================================
+Tool Calls:
+ get_weather (call_9ZudXyMAdlUjptq9oMGtQo8o)
+ Call ID: call_9ZudXyMAdlUjptq9oMGtQo8o
+ Args:
+ city: sf
+================================= Tool Message ==================================
+Name: get_weather
+
+It's always sunny in sf
+================================== Ai Message ===================================
+
+The weather in San Francisco is currently sunny.
+```
+
+## View the trace in LangSmith
+
+Now that we've ran our graph, let's head over to LangSmith and view our trace. First click into the project that you traced to (in our case the default project). You should see a run with the custom run name "agent_007".
+
+
+
+In addition, you will be able to filter traces after the fact using the tags or metadata provided. For example,
+
+
\ No newline at end of file
diff --git a/docs/docs/how-tos/subgraph.ipynb b/docs/docs/how-tos/subgraph.ipynb
deleted file mode 100644
index a16d99216..000000000
--- a/docs/docs/how-tos/subgraph.ipynb
+++ /dev/null
@@ -1,559 +0,0 @@
-{
- "cells": [
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Use subgraphs\n",
- "\n",
- "This guide explains the mechanics of using [subgraphs](../../concepts/subgraphs). A common application of subgraphs is to build [multi-agent](../../concepts/multi_agent) systems.\n",
- "\n",
- "When adding subgraphs, you need to define how the parent graph and the subgraph communicate:\n",
- "\n",
- "* [Shared state schemas](#shared-state-schemas) — parent and subgraph have **shared state keys** in their state [schemas](../../concepts/low_level#state)\n",
- "* [Different state schemas](#different-state-schemas) — **no shared state keys** in parent and subgraph [schemas](../../concepts/low_level#state)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Setup"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "%%capture --no-stderr\n",
- "%pip install -U langgraph"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "
\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",
- "
"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Shared state schemas\n",
- "\n",
- "A common case is for the parent graph and subgraph to communicate over a shared state key (channel) in the [schema](../../concepts/low_level#state). For example, in [multi-agent](../../concepts/multi_agent) systems, the agents often communicate over a shared [messages](https://langchain-ai.github.io/langgraph/concepts/low_level/#why-use-messages) key.\n",
- "\n",
- "If your subgraph shares state keys with the parent graph, you can follow these steps to add it to your graph:\n",
- "\n",
- "1. Define the subgraph workflow (`subgraph_builder` in the example below) and compile it\n",
- "2. Pass compiled subgraph to the `.add_node` method when defining the parent graph workflow\n",
- "\n",
- "```python\n",
- "from typing_extensions import TypedDict\n",
- "from langgraph.graph.state import StateGraph, START\n",
- "\n",
- "class State(TypedDict):\n",
- " foo: str\n",
- "\n",
- "# Subgraph\n",
- "\n",
- "def subgraph_node_1(state: State):\n",
- " return {\"foo\": \"hi! \" + state[\"foo\"]}\n",
- "\n",
- "subgraph_builder = StateGraph(State)\n",
- "subgraph_builder.add_node(subgraph_node_1)\n",
- "subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
- "# highlight-next-line\n",
- "subgraph = subgraph_builder.compile()\n",
- "\n",
- "# Parent graph\n",
- "\n",
- "builder = StateGraph(State)\n",
- "# highlight-next-line\n",
- "builder.add_node(\"node_1\", subgraph)\n",
- "builder.add_edge(START, \"node_1\")\n",
- "graph = builder.compile()\n",
- "```\n",
- "\n",
- "??? example \"Full example: shared state schemas\"\n",
- "\n",
- " ```python\n",
- " from typing_extensions import TypedDict\n",
- " from langgraph.graph.state import StateGraph, START\n",
- "\n",
- " # Define subgraph\n",
- " class SubgraphState(TypedDict):\n",
- " foo: str # (1)! \n",
- " bar: str # (2)!\n",
- " \n",
- " def subgraph_node_1(state: SubgraphState):\n",
- " return {\"bar\": \"bar\"}\n",
- " \n",
- " def subgraph_node_2(state: SubgraphState):\n",
- " # note that this node is using a state key ('bar') that is only available in the subgraph\n",
- " # and is sending update on the shared state key ('foo')\n",
- " return {\"foo\": state[\"foo\"] + state[\"bar\"]}\n",
- " \n",
- " subgraph_builder = StateGraph(SubgraphState)\n",
- " subgraph_builder.add_node(subgraph_node_1)\n",
- " subgraph_builder.add_node(subgraph_node_2)\n",
- " subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
- " subgraph_builder.add_edge(\"subgraph_node_1\", \"subgraph_node_2\")\n",
- " subgraph = subgraph_builder.compile()\n",
- " \n",
- " # Define parent graph\n",
- " class ParentState(TypedDict):\n",
- " foo: str\n",
- " \n",
- " def node_1(state: ParentState):\n",
- " return {\"foo\": \"hi! \" + state[\"foo\"]}\n",
- " \n",
- " builder = StateGraph(ParentState)\n",
- " builder.add_node(\"node_1\", node_1)\n",
- " # highlight-next-line\n",
- " builder.add_node(\"node_2\", subgraph)\n",
- " builder.add_edge(START, \"node_1\")\n",
- " builder.add_edge(\"node_1\", \"node_2\")\n",
- " graph = builder.compile()\n",
- " \n",
- " for chunk in graph.stream({\"foo\": \"foo\"}):\n",
- " print(chunk)\n",
- " ```\n",
- "\n",
- " 1. This key is shared with the parent graph state\n",
- " 2. This key is private to the `SubgraphState` and is not visible to the parent graph\n",
- " \n",
- " ```\n",
- " {'node_1': {'foo': 'hi! foo'}}\n",
- " {'node_2': {'foo': 'hi! foobar'}}\n",
- " ```\n",
- "\n",
- " ```"
- ]
- },
- {
- "attachments": {},
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Different state schemas\n",
- "\n",
- "For more complex systems you might want to define subgraphs that have a **completely different schema** from the parent graph (no shared keys). For example, you might want to keep a private message history for each of the agents in a [multi-agent](../concepts/multi_agent.md) system.\n",
- "\n",
- "If that's the case for your application, you need to define a node **function that invokes the subgraph**. This function needs to transform the input (parent) state to the subgraph state before invoking the subgraph, and transform the results back to the parent state before returning the state update from the node.\n",
- "\n",
- "```python\n",
- "from typing_extensions import TypedDict\n",
- "from langgraph.graph.state import StateGraph, START\n",
- "\n",
- "class SubgraphState(TypedDict):\n",
- " bar: str\n",
- "\n",
- "# Subgraph\n",
- "\n",
- "def subgraph_node_1(state: SubgraphState):\n",
- " return {\"bar\": \"hi! \" + state[\"bar\"]}\n",
- "\n",
- "subgraph_builder = StateGraph(SubgraphState)\n",
- "subgraph_builder.add_node(subgraph_node_1)\n",
- "subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
- "# highlight-next-line\n",
- "subgraph = subgraph_builder.compile()\n",
- "\n",
- "# Parent graph\n",
- "\n",
- "class State(TypedDict):\n",
- " foo: str\n",
- "\n",
- "def call_subgraph(state: State):\n",
- " # highlight-next-line\n",
- " subgraph_output = subgraph.invoke({\"bar\": state[\"foo\"]}) # (1)!\n",
- " # highlight-next-line\n",
- " return {\"foo\": subgraph_output[\"bar\"]} # (2)!\n",
- "\n",
- "builder = StateGraph(State)\n",
- "# highlight-next-line\n",
- "builder.add_node(\"node_1\", call_subgraph)\n",
- "builder.add_edge(START, \"node_1\")\n",
- "graph = builder.compile()\n",
- "```\n",
- "\n",
- "1. Transform the state to the subgraph state\n",
- "2. Transform response back to the parent state\n",
- "\n",
- "??? example \"Full example: different state schemas\"\n",
- "\n",
- " ```python\n",
- " from typing_extensions import TypedDict\n",
- " from langgraph.graph.state import StateGraph, START\n",
- "\n",
- " # Define subgraph\n",
- " class SubgraphState(TypedDict):\n",
- " # note that none of these keys are shared with the parent graph state\n",
- " bar: str\n",
- " baz: str\n",
- " \n",
- " def subgraph_node_1(state: SubgraphState):\n",
- " return {\"baz\": \"baz\"}\n",
- " \n",
- " def subgraph_node_2(state: SubgraphState):\n",
- " return {\"bar\": state[\"bar\"] + state[\"baz\"]}\n",
- " \n",
- " subgraph_builder = StateGraph(SubgraphState)\n",
- " subgraph_builder.add_node(subgraph_node_1)\n",
- " subgraph_builder.add_node(subgraph_node_2)\n",
- " subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
- " subgraph_builder.add_edge(\"subgraph_node_1\", \"subgraph_node_2\")\n",
- " subgraph = subgraph_builder.compile()\n",
- " \n",
- " # Define parent graph\n",
- " class ParentState(TypedDict):\n",
- " foo: str\n",
- " \n",
- " def node_1(state: ParentState):\n",
- " return {\"foo\": \"hi! \" + state[\"foo\"]}\n",
- " \n",
- " def node_2(state: ParentState):\n",
- " # highlight-next-line\n",
- " response = subgraph.invoke({\"bar\": state[\"foo\"]}) # (1)!\n",
- " # highlight-next-line\n",
- " return {\"foo\": response[\"bar\"]} # (2)!\n",
- " \n",
- " \n",
- " builder = StateGraph(ParentState)\n",
- " builder.add_node(\"node_1\", node_1)\n",
- " # highlight-next-line\n",
- " builder.add_node(\"node_2\", node_2)\n",
- " builder.add_edge(START, \"node_1\")\n",
- " builder.add_edge(\"node_1\", \"node_2\")\n",
- " graph = builder.compile()\n",
- " \n",
- " for chunk in graph.stream({\"foo\": \"foo\"}, subgraphs=True):\n",
- " print(chunk)\n",
- " ```\n",
- "\n",
- " 1. Transform the state to the subgraph state\n",
- " 2. Transform response back to the parent state\n",
- "\n",
- " ```\n",
- " ((), {'node_1': {'foo': 'hi! foo'}})\n",
- " (('node_2:9c36dd0f-151a-cb42-cbad-fa2f851f9ab7',), {'subgraph_node_1': {'baz': 'baz'}})\n",
- " (('node_2:9c36dd0f-151a-cb42-cbad-fa2f851f9ab7',), {'subgraph_node_2': {'bar': 'hi! foobaz'}})\n",
- " ((), {'node_2': {'foo': 'hi! foobaz'}})\n",
- " ```\n",
- "\n",
- "??? example \"Full example: different state schemas (two levels of subgraphs)\"\n",
- "\n",
- " This is an example with two levels of subgraphs: parent -> child -> grandchild.\n",
- "\n",
- " ```python\n",
- " # Grandchild graph\n",
- " from typing_extensions import TypedDict\n",
- " from langgraph.graph.state import StateGraph, START, END\n",
- " \n",
- " class GrandChildState(TypedDict):\n",
- " my_grandchild_key: str\n",
- " \n",
- " def grandchild_1(state: GrandChildState) -> GrandChildState:\n",
- " # NOTE: child or parent keys will not be accessible here\n",
- " return {\"my_grandchild_key\": state[\"my_grandchild_key\"] + \", how are you\"}\n",
- " \n",
- " \n",
- " grandchild = StateGraph(GrandChildState)\n",
- " grandchild.add_node(\"grandchild_1\", grandchild_1)\n",
- " \n",
- " grandchild.add_edge(START, \"grandchild_1\")\n",
- " grandchild.add_edge(\"grandchild_1\", END)\n",
- " \n",
- " grandchild_graph = grandchild.compile()\n",
- " \n",
- " # Child graph\n",
- " class ChildState(TypedDict):\n",
- " my_child_key: str\n",
- " \n",
- " def call_grandchild_graph(state: ChildState) -> ChildState:\n",
- " # NOTE: parent or grandchild keys won't be accessible here\n",
- " grandchild_graph_input = {\"my_grandchild_key\": state[\"my_child_key\"]} # (1)!\n",
- " # highlight-next-line\n",
- " grandchild_graph_output = grandchild_graph.invoke(grandchild_graph_input)\n",
- " return {\"my_child_key\": grandchild_graph_output[\"my_grandchild_key\"] + \" today?\"} # (2)!\n",
- " \n",
- " child = StateGraph(ChildState)\n",
- " # highlight-next-line\n",
- " child.add_node(\"child_1\", call_grandchild_graph) # (3)!\n",
- " child.add_edge(START, \"child_1\")\n",
- " child.add_edge(\"child_1\", END)\n",
- " child_graph = child.compile()\n",
- " \n",
- " # Parent graph\n",
- " class ParentState(TypedDict):\n",
- " my_key: str\n",
- " \n",
- " def parent_1(state: ParentState) -> ParentState:\n",
- " # NOTE: child or grandchild keys won't be accessible here\n",
- " return {\"my_key\": \"hi \" + state[\"my_key\"]}\n",
- " \n",
- " def parent_2(state: ParentState) -> ParentState:\n",
- " return {\"my_key\": state[\"my_key\"] + \" bye!\"}\n",
- " \n",
- " def call_child_graph(state: ParentState) -> ParentState:\n",
- " child_graph_input = {\"my_child_key\": state[\"my_key\"]} # (4)!\n",
- " # highlight-next-line\n",
- " child_graph_output = child_graph.invoke(child_graph_input)\n",
- " return {\"my_key\": child_graph_output[\"my_child_key\"]} # (5)!\n",
- " \n",
- " parent = StateGraph(ParentState)\n",
- " parent.add_node(\"parent_1\", parent_1)\n",
- " # highlight-next-line\n",
- " parent.add_node(\"child\", call_child_graph) # (6)!\n",
- " parent.add_node(\"parent_2\", parent_2)\n",
- " \n",
- " parent.add_edge(START, \"parent_1\")\n",
- " parent.add_edge(\"parent_1\", \"child\")\n",
- " parent.add_edge(\"child\", \"parent_2\")\n",
- " parent.add_edge(\"parent_2\", END)\n",
- " \n",
- " parent_graph = parent.compile()\n",
- " \n",
- " for chunk in parent_graph.stream({\"my_key\": \"Bob\"}, subgraphs=True):\n",
- " print(chunk)\n",
- " ```\n",
- "\n",
- " 1. We're transforming the state from the child state channels (`my_child_key`) to the child state channels (`my_grandchild_key`)\n",
- " 2. We're transforming the state from the grandchild state channels (`my_grandchild_key`) back to the child state channels (`my_child_key`)\n",
- " 3. We're passing a function here instead of just compiled graph (`grandchild_graph`)\n",
- " 4. We're transforming the state from the parent state channels (`my_key`) to the child state channels (`my_child_key`)\n",
- " 5. We're transforming the state from the child state channels (`my_child_key`) back to the parent state channels (`my_key`)\n",
- " 6. We're passing a function here instead of just a compiled graph (`child_graph`)\n",
- "\n",
- " ```\n",
- " ((), {'parent_1': {'my_key': 'hi Bob'}})\n",
- " (('child:2e26e9ce-602f-862c-aa66-1ea5a4655e3b', 'child_1:781bb3b1-3971-84ce-810b-acf819a03f9c'), {'grandchild_1': {'my_grandchild_key': 'hi Bob, how are you'}})\n",
- " (('child:2e26e9ce-602f-862c-aa66-1ea5a4655e3b',), {'child_1': {'my_child_key': 'hi Bob, how are you today?'}})\n",
- " ((), {'child': {'my_key': 'hi Bob, how are you today?'}})\n",
- " ((), {'parent_2': {'my_key': 'hi Bob, how are you today? bye!'}})\n",
- " ```"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Add persistence \n",
- "\n",
- "You only need to **provide the checkpointer when compiling the parent graph**. LangGraph will automatically propagate the checkpointer to the child subgraphs.\n",
- "\n",
- "```python\n",
- "from langgraph.graph import START, StateGraph\n",
- "from langgraph.checkpoint.memory import InMemorySaver\n",
- "from typing_extensions import TypedDict\n",
- "\n",
- "class State(TypedDict):\n",
- " foo: str\n",
- "\n",
- "# Subgraph\n",
- "\n",
- "def subgraph_node_1(state: State):\n",
- " return {\"foo\": state[\"foo\"] + \"bar\"}\n",
- "\n",
- "subgraph_builder = StateGraph(State)\n",
- "subgraph_builder.add_node(subgraph_node_1)\n",
- "subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
- "# highlight-next-line\n",
- "subgraph = subgraph_builder.compile()\n",
- "\n",
- "# Parent graph\n",
- "\n",
- "builder = StateGraph(State)\n",
- "# highlight-next-line\n",
- "builder.add_node(\"node_1\", subgraph)\n",
- "builder.add_edge(START, \"node_1\")\n",
- "\n",
- "checkpointer = InMemorySaver()\n",
- "# highlight-next-line\n",
- "graph = builder.compile(checkpointer=checkpointer)\n",
- "``` \n",
- "\n",
- "If you want the subgraph to **have its own memory**, you can compile it `with checkpointer=True`. This is useful in [multi-agent](../../concepts/multi_agent) systems, if you want agents to keep track of their internal message histories:\n",
- "\n",
- "```python\n",
- "subgraph_builder = StateGraph(...)\n",
- "# highlight-next-line\n",
- "subgraph = subgraph_builder.compile(checkpointer=True)\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## View subgraph state\n",
- "\n",
- "When you enable [persistence](../persistence), you can [inspect the graph state](../persistence#manage-checkpoints) (checkpoint) via `graph.get_state(config)`. To view the subgraph state, you can use `graph.get_state(config, subgraphs=True)`.\n",
- "\n",
- "!!! important \"Available **only** when interrupted\"\n",
- "\n",
- " Subgraph state can only be viewed **when the subgraph is interrupted**. Once you resume the graph, you won't be able to access the subgraph state.\n",
- "\n",
- "??? example \"View interrupted subgraph state\"\n",
- "\n",
- " ```python\n",
- " from langgraph.graph import START, StateGraph\n",
- " from langgraph.checkpoint.memory import InMemorySaver\n",
- " from langgraph.types import interrupt, Command\n",
- " from typing_extensions import TypedDict\n",
- " \n",
- " class State(TypedDict):\n",
- " foo: str\n",
- " \n",
- " # Subgraph\n",
- " \n",
- " def subgraph_node_1(state: State):\n",
- " # highlight-next-line\n",
- " value = interrupt(\"Provide value:\")\n",
- " return {\"foo\": state[\"foo\"] + value}\n",
- " \n",
- " subgraph_builder = StateGraph(State)\n",
- " subgraph_builder.add_node(subgraph_node_1)\n",
- " subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
- " \n",
- " subgraph = subgraph_builder.compile()\n",
- " \n",
- " # Parent graph\n",
- " \n",
- " builder = StateGraph(State)\n",
- " # highlight-next-line\n",
- " builder.add_node(\"node_1\", subgraph)\n",
- " builder.add_edge(START, \"node_1\")\n",
- " \n",
- " checkpointer = InMemorySaver()\n",
- " # highlight-next-line\n",
- " graph = builder.compile(checkpointer=checkpointer)\n",
- " \n",
- " config = {\"configurable\": {\"thread_id\": \"1\"}}\n",
- " \n",
- " graph.invoke({\"foo\": \"\"}, config)\n",
- " parent_state = graph.get_state(config)\n",
- " # highlight-next-line\n",
- " subgraph_state = graph.get_state(config, subgraphs=True).tasks[0].state # (1)!\n",
- " \n",
- " # resume the subgraph\n",
- " graph.invoke(Command(resume=\"bar\"), config)\n",
- " ```\n",
- " \n",
- " 1. This will be available only when the subgraph is interrupted. Once you resume the graph, you won't be able to access the subgraph state."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Stream subgraph outputs\n",
- "\n",
- "To include outputs from [subgraphs](../concepts/low_level.md#subgraphs) in the streamed outputs, you can set `subgraphs=True` in the `.stream()` method of the parent graph. This will stream outputs from both the parent graph and any subgraphs.\n",
- "\n",
- "```python\n",
- "for chunk in graph.stream(\n",
- " {\"foo\": \"foo\"},\n",
- " # highlight-next-line\n",
- " subgraphs=True, # (1)!\n",
- " stream_mode=\"updates\",\n",
- "):\n",
- " print(chunk)\n",
- "```\n",
- "\n",
- "1. Set `subgraphs=True` to stream outputs from subgraphs.\n",
- "\n",
- "??? example \"Stream from subgraphs\"\n",
- "\n",
- " ```python\n",
- " from typing_extensions import TypedDict\n",
- " from langgraph.graph.state import StateGraph, START\n",
- "\n",
- " # Define subgraph\n",
- " class SubgraphState(TypedDict):\n",
- " foo: str\n",
- " bar: str\n",
- " \n",
- " def subgraph_node_1(state: SubgraphState):\n",
- " return {\"bar\": \"bar\"}\n",
- " \n",
- " def subgraph_node_2(state: SubgraphState):\n",
- " # note that this node is using a state key ('bar') that is only available in the subgraph\n",
- " # and is sending update on the shared state key ('foo')\n",
- " return {\"foo\": state[\"foo\"] + state[\"bar\"]}\n",
- " \n",
- " subgraph_builder = StateGraph(SubgraphState)\n",
- " subgraph_builder.add_node(subgraph_node_1)\n",
- " subgraph_builder.add_node(subgraph_node_2)\n",
- " subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
- " subgraph_builder.add_edge(\"subgraph_node_1\", \"subgraph_node_2\")\n",
- " subgraph = subgraph_builder.compile()\n",
- " \n",
- " # Define parent graph\n",
- " class ParentState(TypedDict):\n",
- " foo: str\n",
- " \n",
- " def node_1(state: ParentState):\n",
- " return {\"foo\": \"hi! \" + state[\"foo\"]}\n",
- " \n",
- " builder = StateGraph(ParentState)\n",
- " builder.add_node(\"node_1\", node_1)\n",
- " # highlight-next-line\n",
- " builder.add_node(\"node_2\", subgraph)\n",
- " builder.add_edge(START, \"node_1\")\n",
- " builder.add_edge(\"node_1\", \"node_2\")\n",
- " graph = builder.compile()\n",
- "\n",
- " for chunk in graph.stream(\n",
- " {\"foo\": \"foo\"},\n",
- " stream_mode=\"updates\",\n",
- " # highlight-next-line\n",
- " subgraphs=True, # (1)!\n",
- " ):\n",
- " print(chunk)\n",
- " ```\n",
- " \n",
- " 1. Set `subgraphs=True` to stream outputs from subgraphs.\n",
- "\n",
- " ```\n",
- " ((), {'node_1': {'foo': 'hi! foo'}})\n",
- " (('node_2:e58e5673-a661-ebb0-70d4-e298a7fc28b7',), {'subgraph_node_1': {'bar': 'bar'}})\n",
- " (('node_2:e58e5673-a661-ebb0-70d4-e298a7fc28b7',), {'subgraph_node_2': {'foo': 'hi! foobar'}})\n",
- " ((), {'node_2': {'foo': 'hi! foobar'}})\n",
- " ```"
- ]
- }
- ],
- "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.12.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/docs/how-tos/subgraph.md b/docs/docs/how-tos/subgraph.md
new file mode 100644
index 000000000..9ad820f73
--- /dev/null
+++ b/docs/docs/how-tos/subgraph.md
@@ -0,0 +1,453 @@
+# Use subgraphs
+
+This guide explains the mechanics of using [subgraphs](../concepts/subgraphs.md). A common application of subgraphs is to build [multi-agent](../concepts/multi_agent.md) systems.
+
+When adding subgraphs, you need to define how the parent graph and the subgraph communicate:
+
+* [Shared state schemas](#shared-state-schemas) — parent and subgraph have **shared state keys** in their state [schemas](../concepts/low_level.md#state)
+* [Different state schemas](#different-state-schemas) — **no shared state keys** in parent and subgraph [schemas](../concepts/low_level.md#state)
+
+## Setup
+
+```bash
+pip install -U langgraph
+```
+
+!!! tip "Set up LangSmith for LangGraph development"
+ Sign up for [LangSmith](https://smith.langchain.com) 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](https://docs.smith.langchain.com).
+
+## Shared state schemas
+
+A common case is for the parent graph and subgraph to communicate over a shared state key (channel) in the [schema](../concepts/low_level.md#state). For example, in [multi-agent](../concepts/multi_agent.md) systems, the agents often communicate over a shared [messages](https://langchain-ai.github.io/langgraph/concepts/low_level.md#why-use-messages) key.
+
+If your subgraph shares state keys with the parent graph, you can follow these steps to add it to your graph:
+
+1. Define the subgraph workflow (`subgraph_builder` in the example below) and compile it
+2. Pass compiled subgraph to the `.add_node` method when defining the parent graph workflow
+
+```python
+from typing_extensions import TypedDict
+from langgraph.graph.state import StateGraph, START
+
+class State(TypedDict):
+ foo: str
+
+# Subgraph
+
+def subgraph_node_1(state: State):
+ return {"foo": "hi! " + state["foo"]}
+
+subgraph_builder = StateGraph(State)
+subgraph_builder.add_node(subgraph_node_1)
+subgraph_builder.add_edge(START, "subgraph_node_1")
+subgraph = subgraph_builder.compile()
+
+# Parent graph
+
+builder = StateGraph(State)
+builder.add_node("node_1", subgraph)
+builder.add_edge(START, "node_1")
+graph = builder.compile()
+```
+
+??? example "Full example: shared state schemas"
+
+ ```python
+ from typing_extensions import TypedDict
+ from langgraph.graph.state import StateGraph, START
+
+ # Define subgraph
+ class SubgraphState(TypedDict):
+ foo: str # (1)!
+ bar: str # (2)!
+
+ def subgraph_node_1(state: SubgraphState):
+ return {"bar": "bar"}
+
+ def subgraph_node_2(state: SubgraphState):
+ # note that this node is using a state key ('bar') that is only available in the subgraph
+ # and is sending update on the shared state key ('foo')
+ return {"foo": state["foo"] + state["bar"]}
+
+ subgraph_builder = StateGraph(SubgraphState)
+ subgraph_builder.add_node(subgraph_node_1)
+ subgraph_builder.add_node(subgraph_node_2)
+ subgraph_builder.add_edge(START, "subgraph_node_1")
+ subgraph_builder.add_edge("subgraph_node_1", "subgraph_node_2")
+ subgraph = subgraph_builder.compile()
+
+ # Define parent graph
+ class ParentState(TypedDict):
+ foo: str
+
+ def node_1(state: ParentState):
+ return {"foo": "hi! " + state["foo"]}
+
+ builder = StateGraph(ParentState)
+ builder.add_node("node_1", node_1)
+ builder.add_node("node_2", subgraph)
+ builder.add_edge(START, "node_1")
+ builder.add_edge("node_1", "node_2")
+ graph = builder.compile()
+
+ for chunk in graph.stream({"foo": "foo"}):
+ print(chunk)
+ ```
+
+ 1. This key is shared with the parent graph state
+ 2. This key is private to the `SubgraphState` and is not visible to the parent graph
+
+ ```
+ {'node_1': {'foo': 'hi! foo'}}
+ {'node_2': {'foo': 'hi! foobar'}}
+ ```
+
+## Different state schemas
+
+For more complex systems you might want to define subgraphs that have a **completely different schema** from the parent graph (no shared keys). For example, you might want to keep a private message history for each of the agents in a [multi-agent](../concepts/multi_agent.md) system.
+
+If that's the case for your application, you need to define a node **function that invokes the subgraph**. This function needs to transform the input (parent) state to the subgraph state before invoking the subgraph, and transform the results back to the parent state before returning the state update from the node.
+
+```python
+from typing_extensions import TypedDict
+from langgraph.graph.state import StateGraph, START
+
+class SubgraphState(TypedDict):
+ bar: str
+
+# Subgraph
+
+def subgraph_node_1(state: SubgraphState):
+ return {"bar": "hi! " + state["bar"]}
+
+subgraph_builder = StateGraph(SubgraphState)
+subgraph_builder.add_node(subgraph_node_1)
+subgraph_builder.add_edge(START, "subgraph_node_1")
+subgraph = subgraph_builder.compile()
+
+# Parent graph
+
+class State(TypedDict):
+ foo: str
+
+def call_subgraph(state: State):
+ subgraph_output = subgraph.invoke({"bar": state["foo"]}) # (1)!
+ return {"foo": subgraph_output["bar"]} # (2)!
+
+builder = StateGraph(State)
+builder.add_node("node_1", call_subgraph)
+builder.add_edge(START, "node_1")
+graph = builder.compile()
+```
+
+1. Transform the state to the subgraph state
+2. Transform response back to the parent state
+
+??? example "Full example: different state schemas"
+
+ ```python
+ from typing_extensions import TypedDict
+ from langgraph.graph.state import StateGraph, START
+
+ # Define subgraph
+ class SubgraphState(TypedDict):
+ # note that none of these keys are shared with the parent graph state
+ bar: str
+ baz: str
+
+ def subgraph_node_1(state: SubgraphState):
+ return {"baz": "baz"}
+
+ def subgraph_node_2(state: SubgraphState):
+ return {"bar": state["bar"] + state["baz"]}
+
+ subgraph_builder = StateGraph(SubgraphState)
+ subgraph_builder.add_node(subgraph_node_1)
+ subgraph_builder.add_node(subgraph_node_2)
+ subgraph_builder.add_edge(START, "subgraph_node_1")
+ subgraph_builder.add_edge("subgraph_node_1", "subgraph_node_2")
+ subgraph = subgraph_builder.compile()
+
+ # Define parent graph
+ class ParentState(TypedDict):
+ foo: str
+
+ def node_1(state: ParentState):
+ return {"foo": "hi! " + state["foo"]}
+
+ def node_2(state: ParentState):
+ response = subgraph.invoke({"bar": state["foo"]}) # (1)!
+ return {"foo": response["bar"]} # (2)!
+
+
+ builder = StateGraph(ParentState)
+ builder.add_node("node_1", node_1)
+ builder.add_node("node_2", node_2)
+ builder.add_edge(START, "node_1")
+ builder.add_edge("node_1", "node_2")
+ graph = builder.compile()
+
+ for chunk in graph.stream({"foo": "foo"}, subgraphs=True):
+ print(chunk)
+ ```
+
+ 1. Transform the state to the subgraph state
+ 2. Transform response back to the parent state
+
+ ```
+ ((), {'node_1': {'foo': 'hi! foo'}})
+ (('node_2:9c36dd0f-151a-cb42-cbad-fa2f851f9ab7',), {'grandchild_1': {'my_grandchild_key': 'hi Bob, how are you'}})
+ (('node_2:9c36dd0f-151a-cb42-cbad-fa2f851f9ab7',), {'grandchild_2': {'bar': 'hi! foobaz'}})
+ ((), {'node_2': {'foo': 'hi! foobaz'}})
+ ```
+
+??? example "Full example: different state schemas (two levels of subgraphs)"
+
+ This is an example with two levels of subgraphs: parent -> child -> grandchild.
+
+ ```python
+ # Grandchild graph
+ from typing_extensions import TypedDict
+ from langgraph.graph.state import StateGraph, START, END
+
+ class GrandChildState(TypedDict):
+ my_grandchild_key: str
+
+ def grandchild_1(state: GrandChildState) -> GrandChildState:
+ # NOTE: child or parent keys will not be accessible here
+ return {"my_grandchild_key": state["my_grandchild_key"] + ", how are you"}
+
+
+ grandchild = StateGraph(GrandChildState)
+ grandchild.add_node("grandchild_1", grandchild_1)
+
+ grandchild.add_edge(START, "grandchild_1")
+ grandchild.add_edge("grandchild_1", END)
+
+ grandchild_graph = grandchild.compile()
+
+ # Child graph
+ class ChildState(TypedDict):
+ my_child_key: str
+
+ def call_grandchild_graph(state: ChildState) -> ChildState:
+ # NOTE: parent or grandchild keys won't be accessible here
+ grandchild_graph_input = {"my_grandchild_key": state["my_child_key"]} # (1)!
+ grandchild_graph_output = grandchild_graph.invoke(grandchild_graph_input)
+ return {"my_child_key": grandchild_graph_output["my_grandchild_key"] + " today?"} # (2)!
+
+ child = StateGraph(ChildState)
+ child.add_node("child_1", call_grandchild_graph) # (3)!
+ child.add_edge(START, "child_1")
+ child.add_edge("child_1", END)
+ child_graph = child.compile()
+
+ # Parent graph
+ class ParentState(TypedDict):
+ my_key: str
+
+ def parent_1(state: ParentState) -> ParentState:
+ # NOTE: child or grandchild keys won't be accessible here
+ return {"my_key": "hi " + state["my_key"]}
+
+ def parent_2(state: ParentState) -> ParentState:
+ return {"my_key": state["my_key"] + " bye!"}
+
+ def call_child_graph(state: ParentState) -> ParentState:
+ child_graph_input = {"my_child_key": state["my_key"]} # (4)!
+ child_graph_output = child_graph.invoke(child_graph_input)
+ return {"my_key": child_graph_output["my_child_key"]} # (5)!
+
+ parent = StateGraph(ParentState)
+ parent.add_node("parent_1", parent_1)
+ parent.add_node("child", call_child_graph) # (6)!
+ parent.add_node("parent_2", parent_2)
+
+ parent.add_edge(START, "parent_1")
+ parent.add_edge("parent_1", "child")
+ parent.add_edge("child", "parent_2")
+ parent.add_edge("parent_2", END)
+
+ parent_graph = parent.compile()
+
+ for chunk in parent_graph.stream({"my_key": "Bob"}, subgraphs=True):
+ print(chunk)
+ ```
+
+ 1. We're transforming the state from the child state channels (`my_child_key`) to the child state channels (`my_grandchild_key`)
+ 2. We're transforming the state from the grandchild state channels (`my_grandchild_key`) back to the child state channels (`my_child_key`)
+ 3. We're passing a function here instead of just compiled graph (`grandchild_graph`)
+ 4. We're transforming the state from the parent state channels (`my_key`) to the child state channels (`my_child_key`)
+ 5. We're transforming the state from the child state channels (`my_child_key`) back to the parent state channels (`my_key`)
+ 6. We're passing a function here instead of just a compiled graph (`child_graph`)
+
+ ```
+ ((), {'parent_1': {'my_key': 'hi Bob'}})
+ (('child:2e26e9ce-602f-862c-aa66-1ea5a4655e3b', 'child_1:781bb3b1-3971-84ce-810b-acf819a03f9c'), {'grandchild_1': {'my_grandchild_key': 'hi Bob, how are you'}})
+ (('child:2e26e9ce-602f-862c-aa66-1ea5a4655e3b',), {'child_1': {'my_child_key': 'hi Bob, how are you today?'}})
+ ((), {'child': {'my_key': 'hi Bob, how are you today?'}})
+ ((), {'parent_2': {'my_key': 'hi Bob, how are you today? bye!'}})
+ ```
+
+## Add persistence
+
+You only need to **provide the checkpointer when compiling the parent graph**. LangGraph will automatically propagate the checkpointer to the child subgraphs.
+
+```python
+from langgraph.graph import START, StateGraph
+from langgraph.checkpoint.memory import InMemorySaver
+from typing_extensions import TypedDict
+
+class State(TypedDict):
+ foo: str
+
+# Subgraph
+
+def subgraph_node_1(state: State):
+ return {"foo": state["foo"] + "bar"}
+
+subgraph_builder = StateGraph(State)
+subgraph_builder.add_node(subgraph_node_1)
+subgraph_builder.add_edge(START, "subgraph_node_1")
+subgraph = subgraph_builder.compile()
+
+# Parent graph
+
+builder = StateGraph(State)
+builder.add_node("node_1", subgraph)
+builder.add_edge(START, "node_1")
+
+checkpointer = InMemorySaver()
+graph = builder.compile(checkpointer=checkpointer)
+```
+
+If you want the subgraph to **have its own memory**, you can compile it `with checkpointer=True`. This is useful in [multi-agent](../concepts/multi_agent.md) systems, if you want agents to keep track of their internal message histories:
+
+```python
+subgraph_builder = StateGraph(...)
+subgraph = subgraph_builder.compile(checkpointer=True)
+```
+
+## View subgraph state
+
+When you enable [persistence](../concepts/persistence.md), you can [inspect the graph state](../concepts/persistence.md#checkpoints) (checkpoint) via `graph.get_state(config)`. To view the subgraph state, you can use `graph.get_state(config, subgraphs=True)`.
+
+!!! important "Available **only** when interrupted"
+
+ Subgraph state can only be viewed **when the subgraph is interrupted**. Once you resume the graph, you won't be able to access the subgraph state.
+
+??? example "View interrupted subgraph state"
+
+ ```python
+ from langgraph.graph import START, StateGraph
+ from langgraph.checkpoint.memory import InMemorySaver
+ from langgraph.types import interrupt, Command
+ from typing_extensions import TypedDict
+
+ class State(TypedDict):
+ foo: str
+
+ # Subgraph
+
+ def subgraph_node_1(state: State):
+ value = interrupt("Provide value:")
+ return {"foo": state["foo"] + value}
+
+ subgraph_builder = StateGraph(State)
+ subgraph_builder.add_node(subgraph_node_1)
+ subgraph_builder.add_edge(START, "subgraph_node_1")
+
+ subgraph = subgraph_builder.compile()
+
+ # Parent graph
+
+ builder = StateGraph(State)
+ builder.add_node("node_1", subgraph)
+ builder.add_edge(START, "node_1")
+
+ checkpointer = InMemorySaver()
+ graph = builder.compile(checkpointer=checkpointer)
+
+ config = {"configurable": {"thread_id": "1"}}
+
+ graph.invoke({"foo": ""}, config)
+ parent_state = graph.get_state(config)
+ subgraph_state = graph.get_state(config, subgraphs=True).tasks[0].state # (1)!
+
+ # resume the subgraph
+ graph.invoke(Command(resume="bar"), config)
+ ```
+
+ 1. This will be available only when the subgraph is interrupted. Once you resume the graph, you won't be able to access the subgraph state.
+
+## Stream subgraph outputs
+
+To include outputs from subgraphs in the streamed outputs, you can set `subgraphs=True` in the `.stream()` method of the parent graph. This will stream outputs from both the parent graph and any subgraphs.
+
+```python
+for chunk in graph.stream(
+ {"foo": "foo"},
+ subgraphs=True, # (1)!
+ stream_mode="updates",
+):
+ print(chunk)
+```
+
+1. Set `subgraphs=True` to stream outputs from subgraphs.
+
+??? example "Stream from subgraphs"
+
+ ```python
+ from typing_extensions import TypedDict
+ from langgraph.graph.state import StateGraph, START
+
+ # Define subgraph
+ class SubgraphState(TypedDict):
+ foo: str
+ bar: str
+
+ def subgraph_node_1(state: SubgraphState):
+ return {"bar": "bar"}
+
+ def subgraph_node_2(state: SubgraphState):
+ # note that this node is using a state key ('bar') that is only available in the subgraph
+ # and is sending update on the shared state key ('foo')
+ return {"foo": state["foo"] + state["bar"]}
+
+ subgraph_builder = StateGraph(SubgraphState)
+ subgraph_builder.add_node(subgraph_node_1)
+ subgraph_builder.add_node(subgraph_node_2)
+ subgraph_builder.add_edge(START, "subgraph_node_1")
+ subgraph_builder.add_edge("subgraph_node_1", "subgraph_node_2")
+ subgraph = subgraph_builder.compile()
+
+ # Define parent graph
+ class ParentState(TypedDict):
+ foo: str
+
+ def node_1(state: ParentState):
+ return {"foo": "hi! " + state["foo"]}
+
+ builder = StateGraph(ParentState)
+ builder.add_node("node_1", node_1)
+ builder.add_node("node_2", subgraph)
+ builder.add_edge(START, "node_1")
+ builder.add_edge("node_1", "node_2")
+ graph = builder.compile()
+
+ for chunk in graph.stream(
+ {"foo": "foo"},
+ stream_mode="updates",
+ subgraphs=True, # (1)!
+ ):
+ print(chunk)
+ ```
+
+ 1. Set `subgraphs=True` to stream outputs from subgraphs.
+
+ ```
+ ((), {'node_1': {'foo': 'hi! foo'}})
+ (('node_2:e58e5673-a661-ebb0-70d4-e298a7fc28b7',), {'subgraph_node_1': {'bar': 'bar'}})
+ (('node_2:e58e5673-a661-ebb0-70d4-e298a7fc28b7',), {'subgraph_node_2': {'foo': 'hi! foobar'}})
+ ((), {'node_2': {'foo': 'hi! foobar'}})
+
\ No newline at end of file
diff --git a/docs/docs/how-tos/tool-calling.md b/docs/docs/how-tos/tool-calling.md
index a2e711ba3..9968b0036 100644
--- a/docs/docs/how-tos/tool-calling.md
+++ b/docs/docs/how-tos/tool-calling.md
@@ -344,6 +344,8 @@ tool_node.invoke({"messages": [...]})
## Tool customization
+For more control over tool behavior, use the `@tool` decorator.
+
### Parameter descriptions
Auto-generate descriptions from docstrings:
diff --git a/docs/docs/index.md b/docs/docs/index.md
index 60ec1b509..db036367a 100644
--- a/docs/docs/index.md
+++ b/docs/docs/index.md
@@ -28,4 +28,4 @@ title: LangGraph
}
-{!../README.md!}
\ No newline at end of file
+{% include-markdown "../../README.md" %}
\ No newline at end of file
diff --git a/docs/docs/snippets/chat_model_tabs.md b/docs/docs/snippets/chat_model_tabs.md
new file mode 100644
index 000000000..e984e1821
--- /dev/null
+++ b/docs/docs/snippets/chat_model_tabs.md
@@ -0,0 +1,87 @@
+=== "OpenAI"
+
+ ```shell
+ pip install -U "langchain[openai]"
+ ```
+ ```python
+ import os
+ from langchain.chat_models import init_chat_model
+
+ os.environ["OPENAI_API_KEY"] = "sk-..."
+
+ llm = init_chat_model("openai:gpt-4.1")
+ ```
+
+ 👉 Read the [OpenAI integration docs](https://python.langchain.com/docs/integrations/chat/openai/)
+
+=== "Anthropic"
+
+ ```shell
+ pip install -U "langchain[anthropic]"
+ ```
+ ```python
+ import os
+ from langchain.chat_models import init_chat_model
+
+ os.environ["ANTHROPIC_API_KEY"] = "sk-..."
+
+ llm = init_chat_model("anthropic:claude-3-5-sonnet-latest")
+ ```
+
+ 👉 Read the [Anthropic integration docs](https://python.langchain.com/docs/integrations/chat/anthropic/)
+
+=== "Azure"
+
+ ```shell
+ pip install -U "langchain[openai]"
+ ```
+ ```python
+ import os
+ from langchain.chat_models import init_chat_model
+
+ os.environ["AZURE_OPENAI_API_KEY"] = "..."
+ os.environ["AZURE_OPENAI_ENDPOINT"] = "..."
+ os.environ["OPENAI_API_VERSION"] = "2025-03-01-preview"
+
+ llm = init_chat_model(
+ "azure_openai:gpt-4.1",
+ azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
+ )
+ ```
+
+ 👉 Read the [Azure integration docs](https://python.langchain.com/docs/integrations/chat/azure_chat_openai/)
+
+=== "Google Gemini"
+
+ ```shell
+ pip install -U "langchain[google-genai]"
+ ```
+ ```python
+ import os
+ from langchain.chat_models import init_chat_model
+
+ os.environ["GOOGLE_API_KEY"] = "..."
+
+ llm = init_chat_model("google_genai:gemini-2.0-flash")
+ ```
+
+ 👉 Read the [Google GenAI integration docs](https://python.langchain.com/docs/integrations/chat/google_generative_ai/)
+
+=== "AWS Bedrock"
+
+ ```shell
+ pip install -U "langchain[aws]"
+ ```
+ ```python
+ from langchain.chat_models import init_chat_model
+
+ # Follow the steps here to configure your credentials:
+ # https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started.html
+
+ llm = init_chat_model(
+ "anthropic.claude-3-5-sonnet-20240620-v1:0",
+ model_provider="bedrock_converse",
+ )
+ ```
+
+ 👉 Read the [AWS Bedrock integration docs](https://python.langchain.com/docs/integrations/chat/bedrock/)
diff --git a/docs/docs/stylesheets/navigation_title_ovverides.css b/docs/docs/stylesheets/navigation_title_ovverides.css
deleted file mode 100644
index 4e7c937d7..000000000
--- a/docs/docs/stylesheets/navigation_title_ovverides.css
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is used to override the navigation title for the LangGraph documentation.
- * It is used to change the title of the first and second items in the navigation menu.
- * The first item is the Guides page, and the second item is the Reference page.
- */
-
-.md-nav--primary > .md-nav__list > .md-nav__item:nth-child(1) > .md-nav__link .md-ellipsis {
- visibility: hidden !important;
- position: relative;
-}
-
-.md-nav--primary > .md-nav__list > .md-nav__item:nth-child(1) > .md-nav__link .md-ellipsis::after {
- content: "Home";
- visibility: visible;
- position: absolute;
- left: 0;
-}
-
-.md-nav--primary > .md-nav__list > .md-nav__item:nth-child(2) > .md-nav__link .md-ellipsis {
- visibility: hidden !important;
- position: relative;
-}
-
-.md-nav--primary > .md-nav__list > .md-nav__item:nth-child(2) > .md-nav__link .md-ellipsis::after {
- content: "Home";
- visibility: visible;
- position: absolute;
- left: 0;
-}
\ No newline at end of file
diff --git a/docs/docs/troubleshooting/studio.md b/docs/docs/troubleshooting/studio.md
index b06f325de..3fcbdea7f 100644
--- a/docs/docs/troubleshooting/studio.md
+++ b/docs/docs/troubleshooting/studio.md
@@ -17,7 +17,7 @@ Safari blocks plain-HTTP traffic on localhost. When running Studio with `langgra
```shell
# Requires @langchain/langgraph-cli>=0.0.26
- npx @langchain/langgraph-cli dev
+ npx @langchain/langgraph-cli dev --tunnel
```
The command outputs a URL in this format:
@@ -55,7 +55,7 @@ Disable Brave Shields for LangSmith using the Brave icon in the URL bar.
```shell
# Requires @langchain/langgraph-cli>=0.0.26
- npx @langchain/langgraph-cli dev
+ npx @langchain/langgraph-cli dev --tunnel
```
The command outputs a URL in this format:
diff --git a/docs/docs/tutorials/get-started/1-build-basic-chatbot.md b/docs/docs/tutorials/get-started/1-build-basic-chatbot.md
index 9235fa65f..b32e42861 100644
--- a/docs/docs/tutorials/get-started/1-build-basic-chatbot.md
+++ b/docs/docs/tutorials/get-started/1-build-basic-chatbot.md
@@ -63,7 +63,7 @@ Next, add a "`chatbot`" node. **Nodes** represent units of work and are typicall
Let's first select a chat model:
-{!snippets/chat_model_tabs.md!}
+{% include-markdown "../../../snippets/chat_model_tabs.md" %}