Compare commits

...
Author SHA1 Message Date
William FHandGitHub 1130c3accb [CLI] Add Store config to CLI (#2548) 2024-11-28 01:58:18 -08:00
William FHandGitHub ee8653d1c5 [SDK] Add SearchItem (#2567) 2024-11-27 22:50:52 -08:00
William FHandGitHub 12486d977a Update postgres-checkpoint min bounds (#2564) 2024-11-27 22:31:16 -08:00
William FHandGitHub c87f9ab6b1 Fix sentence fragment (#2566) 2024-11-27 22:31:03 -08:00
William FHandGitHub 855a3d21ff Update Checkpoint Version (#2565) 2024-11-27 20:50:11 -08:00
William FHandGitHub d767af421b feat: Add vector search (#2535)
- Initializing the store with an 'embedding config' -> this contains the
'dims' (used to create the table) and the encoder object (rn langchain
embeddings object, though that is ......)
- Call setup() -> creates the vector table.

Each document has 1 or more vectors associated with it for each json
path in the embedding config.

Would welcome critique and requests! 

Leaving the params as the defaults for pgvector but open to feedback if
you think it's important to be able to more transparently configure that
in setup()

```python
from typing import TypedDict, List, Dict, Any, Optional

from langchain_openai import OpenAIEmbeddings
from langgraph.graph import StateGraph
from langgraph.store.postgres import PostgresStore

emb_config = {
    "dims": 1536,  # OpenAI embedding dimensions
    "embed": OpenAIEmbeddings(model="text-embedding-3-small"),
    "distance_type": "cosine",
}
with PostgresStore.from_conn_string(
    "postgres://postgres:postgres@localhost:5441",
    embedding=emb_config,
) as store:
    store.setup()


# Define the state type for our graph
class State(TypedDict):
    query: str
    results: Optional[List[Dict[str, Any]]]


def put_stuff(state: State) -> State:
    docs = [
        ("doc1", {"text": "red apple in kitchen"}),
        ("doc2", {"text": "blue car in garage"}),
        ("doc3", {"text": "green apple on table"}),
    ]
    for key, value in docs:
        store.put(("docs",), key, value)


def search_stuff(state: State) -> State:
    """Search for documents using vector similarity."""
    results = store.search(("docs",), query=state["query"])

    return {"results": results}


builder = StateGraph(State)
builder.add_node(put_stuff)
builder.add_node(search_stuff)
builder.add_edge("__start__", "put_stuff")
builder.add_edge("put_stuff", "search_stuff")
# Compile
with PostgresStore.from_conn_string(
    "postgres://postgres:postgres@localhost:5441",
    embedding=emb_config,
) as store:
    chain = builder.compile(store=store)

    result = chain.invoke({"query": "sour apple"})

# Print results
for doc in result["results"]:
    print(doc.key)
    print(doc.value)
    print(doc.response_metadata)

```
2024-11-28 04:40:12 +00:00
Nuno CamposandGitHub 07ac016e60 Merge pull request #2562 from langchain-ai/nc/27nov/revert-sdk
Revert "sdk-py: Fix SSE parsing to split lines only \n \r \r\n per SSE spec"
2024-11-27 17:36:07 -08:00
Nuno Campos 4576a259dd sdk-py 0.1.39 2024-11-27 17:32:07 -08:00
Nuno Campos 53ec7c41b2 Revert "sdk-py: Fix SSE parsing to split lines only \n \r \r\n per SSE spec"
This reverts commit dc09b13400.
2024-11-27 17:31:21 -08:00
Nuno Campos 769f6a1925 Fix 2024-11-27 15:59:48 -08:00
William FHandGitHub 62a36befd5 Add in-mem vector search (#2547) 2024-11-27 14:53:24 -08:00
Andrew NguonlyandGitHub dfaff2511b docs: Update API docs and remove unused pages (#2561) 2024-11-27 14:39:12 -08:00
Nuno Campos 1d9a0d1e4e sdk-py 0.1.37 2024-11-27 14:17:15 -08:00
Nuno CamposandGitHub 35c7eb18ee Merge pull request #2560 from langchain-ai/nc/27nov/fix-sse-parser
sdk-py: Fix SSE parsing to split lines only \n \r \r\n per SSE spec
2024-11-27 14:16:43 -08:00
Nuno Campos dc09b13400 sdk-py: Fix SSE parsing to split lines only \n \r \r\n per SSE spec 2024-11-27 14:10:50 -08:00
Nuno CamposandGitHub b2d8acffc4 Merge pull request #2558 from langchain-ai/nc/27nov/exc-note
lib: Add exception note identify node/task
2024-11-27 12:57:03 -08:00
Nuno Campos 1031e54860 lib: Add exception note identify node/task 2024-11-27 12:44:31 -08:00
Jacob LeeandGitHub 7ac365ea84 fix(sdk-js): Avoid retrying 402s (#2554) 2024-11-27 19:33:23 +00:00
Vadym BardaandGitHub 5144b8f374 langgraph: allow create_react_agent to take empty tools (#2553) 2024-11-27 12:54:59 -05:00
Nuno CamposandGitHub 4b1b3cecb4 Merge pull request #2546 from langchain-ai/jacob/jsenv
fix(js): Adds fallback for fetching environment variables
2024-11-26 12:34:18 -08:00
jacoblee93 c6a953c02a Bump version 2024-11-26 12:31:00 -08:00
jacoblee93 16b955dee2 Adds fallback for fetching environment variables 2024-11-26 12:30:33 -08:00
Brace SproulandGitHub 877124f7df Merge pull request #2545 from langchain-ai/release
release(sdk-js): 0.0.27
2024-11-26 11:54:45 -08:00
bracesproul d3a4865c0e release(sdk-js): 0.0.27 2024-11-26 11:42:20 -08:00
Brace SproulandGitHub a3761ac522 Merge pull request #2543 from langchain-ai/brace/type-interrupts
fix(sdk-js): Add typing for interrupts on threads
2024-11-26 11:40:34 -08:00
bracesproul 376c58ff3b expose interupt type 2024-11-26 11:28:50 -08:00
bracesproul 58b99c899e cr 2024-11-26 11:28:19 -08:00
bracesproul 2ee279a977 fix(sdk-js): Add typing for interrupts on threads 2024-11-26 11:26:18 -08:00
William FHandGitHub f04ce5d1ee [CLI] Add python-dotenv for inmem group (#2540) 2024-11-26 07:56:57 -08:00
William FHandGitHub 8f649abd0a Release PG Checkpointer (#2536) 2024-11-26 01:44:45 +00:00
William FHandGitHub 1febec7c0d Dedup store batch operations (#2534) 2024-11-25 16:31:26 -08:00
Nuno CamposandGitHub a4eb4c6942 Merge pull request #2520 from langchain-ai/nc/22nov/parent-command
lib: Add Command(graph=Command.PARENT, ...)
2024-11-25 15:39:51 -08:00
Nuno Campos 8e1cd0e225 Add test 2024-11-25 14:11:20 -08:00
98935e1ffd fix: Fix race condition in PostgresSaver (#2494)
Signed-off-by: Tyler Ball <tyleraball@gmail.com>
Co-authored-by: Phoenix Logan <plogan@chanzuckerberg.com>
Co-authored-by: Tyler Ball <2481463+tyler-ball@users.noreply.github.com>
2024-11-25 20:19:52 +00:00
William FHandGitHub 328ef609af [CLI] Python path (#2531) 2024-11-25 11:59:49 -08:00
Talha MunirandGitHub 486d5412af docs: Fix grammatical mistake in introduction.ipynb (#2521) 2024-11-23 14:37:55 -05:00
Nuno Campos abc0c8c223 Fix 2024-11-22 16:35:20 -08:00
Nuno Campos 5bbb9dae57 Fix 2024-11-22 16:34:55 -08:00
Nuno Campos fed60e713c lib: Add Command(graph=Command.PARENT, ...)
- This makes the command bubble up out of the current graph and be handled by the calling graph (the immediate parent)
- This could be extended to support eg. ROOT graph, or some other level
2024-11-22 16:28:43 -08:00
Eugene YurtsevandGitHub 4f4e7a6981 docs: more fixes for python version (#2515) 2024-11-22 19:50:31 +00:00
3351d4f6c5 docs: fix typo (#2510)
`python-dotenv` not `python-dot-env`

Signed-off-by: Mingqi <mingqi.hu@intel.com>
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2024-11-22 14:17:59 -05:00
Eugene YurtsevandGitHub b4900341e4 docs: fix broken link (#2514)
We need to check later why CI didn't fail with original PR that broke
the link
2024-11-22 14:07:54 -05:00
Eugene YurtsevandGitHub 65f515e020 docs: add helm chart link (#2512) 2024-11-22 17:17:36 +00:00
Eugene YurtsevandGitHub 0d0665a6e3 docs: Add resource allocation (#2511) 2024-11-22 11:56:16 -05:00
Eugene YurtsevandGitHub 93b8525dc1 docs: fix link checker (#2508)
3rd attempt to fix localhost link
2024-11-21 21:59:43 -05:00
Eugene YurtsevandGitHub aeb6f784e1 docs: fix link checking? (#2506) 2024-11-21 21:21:30 -05:00
Nuno Campos 3eedeac0d4 Not red 2024-11-21 15:31:52 -08:00
Eugene YurtsevandGitHub b09e7b20b0 docs: do not check localhost links (#2505) 2024-11-21 23:28:24 +00:00
Eugene YurtsevandGitHub 26ce731eab docs: update README.md (#2474) 2024-11-21 22:48:12 +00:00
Eugene YurtsevandGitHub 55593446f8 docs: get started with langgraph platform (#2469) 2024-11-21 17:41:03 -05:00
William FHandGitHub 7082e2613e [CLI] Dotenv support (#2501) 2024-11-21 16:28:53 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>William FH
ceeb9636ee build(deps-dev): bump notebook from 7.0.7 to 7.2.2 in /libs/langgraph (#2411)
Bumps [notebook](https://github.com/jupyter/notebook) from 7.0.7 to
7.2.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jupyter/notebook/releases">notebook's
releases</a>.</em></p>
<blockquote>
<h2>v7.2.2</h2>
<h2>7.2.2</h2>
<p>(<a
href="https://github.com/jupyter/notebook/compare/@jupyter-notebook/application-extension@7.2.1...0426a897ad6b5708d73e6e49ea424076de2906a1">Full
Changelog</a>)</p>
<h3>Maintenance and upkeep improvements</h3>
<ul>
<li>Upgrade JupyterLab dependencies to v4.2.5 <a
href="https://redirect.github.com/jupyter/notebook/pull/7447">#7447</a>
(<a
href="https://github.com/krassowski"><code>@​krassowski</code></a>)</li>
</ul>
<h3>Contributors to this release</h3>
<p>(<a
href="https://github.com/jupyter/notebook/graphs/contributors?from=2024-06-07&amp;to=2024-08-27&amp;type=c">GitHub
contributors page for this release</a>)</p>
<p><a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Agithub-actions+updated%3A2024-06-07..2024-08-27&amp;type=Issues"><code>@​github-actions</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Akrassowski+updated%3A2024-06-07..2024-08-27&amp;type=Issues"><code>@​krassowski</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3ARRosio+updated%3A2024-06-07..2024-08-27&amp;type=Issues"><code>@​RRosio</code></a></p>
<h2>v7.2.1</h2>
<h2>7.2.1</h2>
<p>(<a
href="https://github.com/jupyter/notebook/compare/@jupyter-notebook/application-extension@7.2.0...e881745c98ea0a0ea585df78f1ca8950a0edeaa2">Full
Changelog</a>)</p>
<h3>Bugs fixed</h3>
<ul>
<li>Remove pseudoelement obstructing the cell collapser <a
href="https://redirect.github.com/jupyter/notebook/pull/7392">#7392</a>
(<a
href="https://github.com/krassowski"><code>@​krassowski</code></a>)</li>
</ul>
<h3>Contributors to this release</h3>
<p>(<a
href="https://github.com/jupyter/notebook/graphs/contributors?from=2024-05-16&amp;to=2024-06-07&amp;type=c">GitHub
contributors page for this release</a>)</p>
<p><a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Agithub-actions+updated%3A2024-05-16..2024-06-07&amp;type=Issues"><code>@​github-actions</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Ajtpio+updated%3A2024-05-16..2024-06-07&amp;type=Issues"><code>@​jtpio</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Ameeseeksmachine+updated%3A2024-05-16..2024-06-07&amp;type=Issues"><code>@​meeseeksmachine</code></a></p>
<h2>v7.2.0</h2>
<h2>7.2.0</h2>
<p>(<a
href="https://github.com/jupyter/notebook/compare/@jupyter-notebook/application-extension@7.1.2...31bf294e85175bbf39816a90dc8858dedaf73bde">Full
Changelog</a>)</p>
<h3>Enhancements made</h3>
<ul>
<li>Update to JupyterLab 4.2.0 <a
href="https://redirect.github.com/jupyter/notebook/pull/7357">#7357</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Update to JupyterLab 4.2.0rc0 <a
href="https://redirect.github.com/jupyter/notebook/pull/7333">#7333</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Add <code>@jupyterlab/theme-dark-high-contrast-extension</code> <a
href="https://redirect.github.com/jupyter/notebook/pull/7331">#7331</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Update to JupyterLab 4.2.0a2 <a
href="https://redirect.github.com/jupyter/notebook/pull/7307">#7307</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
</ul>
<h3>Bugs fixed</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jupyter/notebook/blob/@jupyter-notebook/tree@7.2.2/CHANGELOG.md">notebook's
changelog</a>.</em></p>
<blockquote>
<h2>7.2.2</h2>
<p>(<a
href="https://github.com/jupyter/notebook/compare/@jupyter-notebook/application-extension@7.2.1...0426a897ad6b5708d73e6e49ea424076de2906a1">Full
Changelog</a>)</p>
<h3>Maintenance and upkeep improvements</h3>
<ul>
<li>Upgrade JupyterLab dependencies to v4.2.5 <a
href="https://redirect.github.com/jupyter/notebook/pull/7447">#7447</a>
(<a
href="https://github.com/krassowski"><code>@​krassowski</code></a>)</li>
</ul>
<h3>Contributors to this release</h3>
<p>(<a
href="https://github.com/jupyter/notebook/graphs/contributors?from=2024-06-07&amp;to=2024-08-27&amp;type=c">GitHub
contributors page for this release</a>)</p>
<p><a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Agithub-actions+updated%3A2024-06-07..2024-08-27&amp;type=Issues"><code>@​github-actions</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Akrassowski+updated%3A2024-06-07..2024-08-27&amp;type=Issues"><code>@​krassowski</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3ARRosio+updated%3A2024-06-07..2024-08-27&amp;type=Issues"><code>@​RRosio</code></a></p>
<!-- raw HTML omitted -->
<h2>7.2.1</h2>
<p>(<a
href="https://github.com/jupyter/notebook/compare/@jupyter-notebook/application-extension@7.2.0...e881745c98ea0a0ea585df78f1ca8950a0edeaa2">Full
Changelog</a>)</p>
<h3>Bugs fixed</h3>
<ul>
<li>Remove pseudoelement obstructing the cell collapser <a
href="https://redirect.github.com/jupyter/notebook/pull/7392">#7392</a>
(<a
href="https://github.com/krassowski"><code>@​krassowski</code></a>)</li>
</ul>
<h3>Contributors to this release</h3>
<p>(<a
href="https://github.com/jupyter/notebook/graphs/contributors?from=2024-05-16&amp;to=2024-06-07&amp;type=c">GitHub
contributors page for this release</a>)</p>
<p><a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Agithub-actions+updated%3A2024-05-16..2024-06-07&amp;type=Issues"><code>@​github-actions</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Ajtpio+updated%3A2024-05-16..2024-06-07&amp;type=Issues"><code>@​jtpio</code></a>
| <a
href="https://github.com/search?q=repo%3Ajupyter%2Fnotebook+involves%3Ameeseeksmachine+updated%3A2024-05-16..2024-06-07&amp;type=Issues"><code>@​meeseeksmachine</code></a></p>
<h2>7.2.0</h2>
<p>(<a
href="https://github.com/jupyter/notebook/compare/@jupyter-notebook/application-extension@7.1.2...31bf294e85175bbf39816a90dc8858dedaf73bde">Full
Changelog</a>)</p>
<h3>Enhancements made</h3>
<ul>
<li>Update to JupyterLab 4.2.0 <a
href="https://redirect.github.com/jupyter/notebook/pull/7357">#7357</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Update to JupyterLab 4.2.0rc0 <a
href="https://redirect.github.com/jupyter/notebook/pull/7333">#7333</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Add <code>@jupyterlab/theme-dark-high-contrast-extension</code> <a
href="https://redirect.github.com/jupyter/notebook/pull/7331">#7331</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Update to JupyterLab 4.2.0a2 <a
href="https://redirect.github.com/jupyter/notebook/pull/7307">#7307</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
</ul>
<h3>Bugs fixed</h3>
<ul>
<li>Add the <code>@jupyterlab/notebook-extension:copy-output</code>
plugin <a
href="https://redirect.github.com/jupyter/notebook/pull/7353">#7353</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Fix CSS for <code>full</code> windowing mode <a
href="https://redirect.github.com/jupyter/notebook/pull/7337">#7337</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Force notebook windowing mode to <code>defer</code> <a
href="https://redirect.github.com/jupyter/notebook/pull/7335">#7335</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Fix scrollbar always showing up by default <a
href="https://redirect.github.com/jupyter/notebook/pull/7327">#7327</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
<li>Default to the <code>full</code> windowing mode <a
href="https://redirect.github.com/jupyter/notebook/pull/7321">#7321</a>
(<a href="https://github.com/jtpio"><code>@​jtpio</code></a>)</li>
</ul>
<h3>Maintenance and upkeep improvements</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jupyter/notebook/commit/d1d232b27c5441c4a040dd3ca491a7cf0fa6c528"><code>d1d232b</code></a>
Publish 7.2.2</li>
<li><a
href="https://github.com/jupyter/notebook/commit/0426a897ad6b5708d73e6e49ea424076de2906a1"><code>0426a89</code></a>
Upgrade JupyterLab dependencies to v4.2.5 (<a
href="https://redirect.github.com/jupyter/notebook/issues/7447">#7447</a>)</li>
<li><a
href="https://github.com/jupyter/notebook/commit/3542421de92c91892d8d8c40ebbd023215c39606"><code>3542421</code></a>
Publish 7.2.1</li>
<li><a
href="https://github.com/jupyter/notebook/commit/e881745c98ea0a0ea585df78f1ca8950a0edeaa2"><code>e881745</code></a>
Backport PR <a
href="https://redirect.github.com/jupyter/notebook/issues/7392">#7392</a>:
Remove pseudoelement obstructing the cell collapser (<a
href="https://redirect.github.com/jupyter/notebook/issues/7393">#7393</a>)</li>
<li><a
href="https://github.com/jupyter/notebook/commit/30587b826a0fe7055a02ea96d43e6305d8b5590b"><code>30587b8</code></a>
Publish 7.2.0</li>
<li><a
href="https://github.com/jupyter/notebook/commit/31bf294e85175bbf39816a90dc8858dedaf73bde"><code>31bf294</code></a>
Add user facing changelog for 7.2 (<a
href="https://redirect.github.com/jupyter/notebook/issues/7372">#7372</a>)</li>
<li><a
href="https://github.com/jupyter/notebook/commit/08fe5c5df12182178280bad5d2fbae02b3486146"><code>08fe5c5</code></a>
Update <code>@jupyterlab/galata</code> (<a
href="https://redirect.github.com/jupyter/notebook/issues/7361">#7361</a>)</li>
<li><a
href="https://github.com/jupyter/notebook/commit/7891117aa9f9cb95c8e301875f9bf74d9496a301"><code>7891117</code></a>
Update config.yml (<a
href="https://redirect.github.com/jupyter/notebook/issues/7363">#7363</a>)</li>
<li><a
href="https://github.com/jupyter/notebook/commit/a1e25b92bf10ef13a760353837114db9b498f242"><code>a1e25b9</code></a>
Publish 7.2.0rc1</li>
<li><a
href="https://github.com/jupyter/notebook/commit/f5d8aea3bdc3eea25213792f9d101738f2a1f627"><code>f5d8aea</code></a>
Default to the <code>full</code> windowing mode (<a
href="https://redirect.github.com/jupyter/notebook/issues/7321">#7321</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/jupyter/notebook/compare/@jupyter-notebook/tree@7.0.7...@jupyter-notebook/tree@7.2.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=notebook&package-manager=pip&previous-version=7.0.7&new-version=7.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-11-21 08:00:26 -08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>William FH
f7788abbb6 build(deps-dev): bump starlette from 0.38.6 to 0.40.0 (#2421)
Bumps [starlette](https://github.com/encode/starlette) from 0.38.6 to
0.40.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/encode/starlette/releases">starlette's
releases</a>.</em></p>
<blockquote>
<h2>Version 0.40.0</h2>
<p>This release fixes a Denial of service (DoS) via
<code>multipart/form-data</code> requests.</p>
<p>You can view the full security advisory:
<a
href="https://github.com/encode/starlette/security/advisories/GHSA-f96h-pmfr-66vw">GHSA-f96h-pmfr-66vw</a></p>
<h2>Fixed</h2>
<ul>
<li>Add <code>max_part_size</code> to <code>MultiPartParser</code> to
limit the size of parts in <code>multipart/form-data</code>
requests <a
href="https://github.com/encode/starlette/commit/fd038f3070c302bff17ef7d173dbb0b007617733">fd038f3</a>.</li>
</ul>
<h2>Version 0.39.2</h2>
<h2>Fixed</h2>
<ul>
<li>Allow use of <code>request.url_for</code> when only &quot;app&quot;
scope is available <a
href="https://redirect.github.com/encode/starlette/pull/2672">#2672</a>.</li>
<li>Fix internal type hints to support
<code>python-multipart==0.0.12</code> <a
href="https://redirect.github.com/encode/starlette/pull/2708">#2708</a>.</li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/encode/starlette/compare/0.39.1...0.39.2">https://github.com/encode/starlette/compare/0.39.1...0.39.2</a></p>
<h2>Version 0.39.1</h2>
<h2>Fixed</h2>
<ul>
<li>Avoid regex re-compilation in <code>responses.py</code> and
<code>schemas.py</code> <a
href="https://redirect.github.com/encode/starlette/pull/2700">#2700</a>.</li>
<li>Improve performance of <code>get_route_path</code> by removing
regular expression usage <a
href="https://redirect.github.com/encode/starlette/pull/2701">#2701</a>.</li>
<li>Consider <code>FileResponse.chunk_size</code> when handling multiple
ranges <a
href="https://redirect.github.com/encode/starlette/pull/2703">#2703</a>.</li>
<li>Use <code>token_hex</code> for generating multipart boundary strings
<a
href="https://redirect.github.com/encode/starlette/pull/2702">#2702</a>.</li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/encode/starlette/compare/0.39.0...0.39.1">https://github.com/encode/starlette/compare/0.39.0...0.39.1</a></p>
<h2>Version 0.39.0</h2>
<h2>Added</h2>
<ul>
<li>Add support for HTTP Range to <code>FileResponse</code> <a
href="https://redirect.github.com/encode/starlette/pull/2697">#2697</a></li>
</ul>
<hr />
<p><strong>Full Changelog</strong>: <a
href="https://github.com/encode/starlette/compare/0.38.6...0.39.0">https://github.com/encode/starlette/compare/0.38.6...0.39.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/encode/starlette/blob/master/docs/release-notes.md">starlette's
changelog</a>.</em></p>
<blockquote>
<h2>0.40.0 (October 15, 2024)</h2>
<p>This release fixes a Denial of service (DoS) via
<code>multipart/form-data</code> requests.</p>
<p>You can view the full security advisory:
<a
href="https://github.com/encode/starlette/security/advisories/GHSA-f96h-pmfr-66vw">GHSA-f96h-pmfr-66vw</a></p>
<h4>Fixed</h4>
<ul>
<li>Add <code>max_part_size</code> to <code>MultiPartParser</code> to
limit the size of parts in <code>multipart/form-data</code>
requests <a
href="https://github.com/encode/starlette/commit/fd038f3070c302bff17ef7d173dbb0b007617733">fd038f3</a>.</li>
</ul>
<h2>0.39.2 (September 29, 2024)</h2>
<h4>Fixed</h4>
<ul>
<li>Allow use of <code>request.url_for</code> when only &quot;app&quot;
scope is available <a
href="https://redirect.github.com/encode/starlette/pull/2672">#2672</a>.</li>
<li>Fix internal type hints to support
<code>python-multipart==0.0.12</code> <a
href="https://redirect.github.com/encode/starlette/pull/2708">#2708</a>.</li>
</ul>
<h2>0.39.1 (September 25, 2024)</h2>
<h4>Fixed</h4>
<ul>
<li>Avoid regex re-compilation in <code>responses.py</code> and
<code>schemas.py</code> <a
href="https://redirect.github.com/encode/starlette/pull/2700">#2700</a>.</li>
<li>Improve performance of <code>get_route_path</code> by removing
regular expression usage
<a
href="https://redirect.github.com/encode/starlette/pull/2701">#2701</a>.</li>
<li>Consider <code>FileResponse.chunk_size</code> when handling multiple
ranges <a
href="https://redirect.github.com/encode/starlette/pull/2703">#2703</a>.</li>
<li>Use <code>token_hex</code> for generating multipart boundary strings
<a
href="https://redirect.github.com/encode/starlette/pull/2702">#2702</a>.</li>
</ul>
<h2>0.39.0 (September 23, 2024)</h2>
<h4>Added</h4>
<ul>
<li>Add support for <a
href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests">HTTP
Range</a> to
<code>FileResponse</code> <a
href="https://redirect.github.com/encode/starlette/pull/2697">#2697</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/encode/starlette/commit/4ded4b7ac517bd301cee69f5c189b1cb48c069b6"><code>4ded4b7</code></a>
Version 0.40.0 (<a
href="https://redirect.github.com/encode/starlette/issues/2728">#2728</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/fd038f3070c302bff17ef7d173dbb0b007617733"><code>fd038f3</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/encode/starlette/commit/e11684013fe5ca084f5bd4e54830512a4dff9618"><code>e116840</code></a>
Bump the python-packages group with 6 updates (<a
href="https://redirect.github.com/encode/starlette/issues/2713">#2713</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/0b50b9c4abd992a39d6e32148cc6f577ac3b1c44"><code>0b50b9c</code></a>
Version 0.39.2 (<a
href="https://redirect.github.com/encode/starlette/issues/2710">#2710</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/fe46d99d92da17efe1827f96ad29d748aac870d2"><code>fe46d99</code></a>
Support <code>request.url_for</code> when only &quot;app&quot; scope is
avaialable (<a
href="https://redirect.github.com/encode/starlette/issues/2672">#2672</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/1a6018e08a994c78f5c169b8535408259af0f249"><code>1a6018e</code></a>
Support python-multipart 0.0.12 (<a
href="https://redirect.github.com/encode/starlette/issues/2708">#2708</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/fa7b382a66cd99e3dc18f3baa44dae5ec68be76b"><code>fa7b382</code></a>
Version 0.39.1 (<a
href="https://redirect.github.com/encode/starlette/issues/2706">#2706</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/075efd0c5c9f5e49a4416f3b4a24e24efab135f8"><code>075efd0</code></a>
generate boundary with token_hex (<a
href="https://redirect.github.com/encode/starlette/issues/2702">#2702</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/b8139f9fe3b1acb34ddbe38dc6472a60b621540e"><code>b8139f9</code></a>
Consider <code>FileResponse.chunk_size</code> when handling multiple
ranges (<a
href="https://redirect.github.com/encode/starlette/issues/2703">#2703</a>)</li>
<li><a
href="https://github.com/encode/starlette/commit/4fbf766b3eac4146b86175682cec88d266fd8470"><code>4fbf766</code></a>
test: add tests in <code>test_requests</code> (<a
href="https://redirect.github.com/encode/starlette/issues/2677">#2677</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/encode/starlette/compare/0.38.6...0.40.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=starlette&package-manager=pip&previous-version=0.38.6&new-version=0.40.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-11-21 07:58:30 -08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
9bd430142a build(deps-dev): bump aiohttp from 3.10.6 to 3.10.11 (#2454)
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.10.6 to
3.10.11.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/aio-libs/aiohttp/releases">aiohttp's
releases</a>.</em></p>
<blockquote>
<h2>3.10.11</h2>
<h2>Bug fixes</h2>
<ul>
<li>
<p>Authentication provided by a redirect now takes precedence over
provided <code>auth</code> when making requests with the client -- by
:user:<code>PLPeeters</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9436">#9436</a>.</p>
</li>
<li>
<p>Fixed :py:meth:<code>WebSocketResponse.close()
&lt;aiohttp.web.WebSocketResponse.close&gt;</code> to discard non-close
messages within its timeout window after sending close -- by
:user:<code>lenard-mosys</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9506">#9506</a>.</p>
</li>
<li>
<p>Fixed a deadlock that could occur while attempting to get a new
connection slot after a timeout -- by :user:<code>bdraco</code>.</p>
<p>The connector was not cancellation-safe.</p>
<p><em>Related issues and pull requests on GitHub:</em>
<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9670">#9670</a>,
<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9671">#9671</a>.</p>
</li>
<li>
<p>Fixed the WebSocket flow control calculation undercounting with
multi-byte data -- by :user:<code>bdraco</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9686">#9686</a>.</p>
</li>
<li>
<p>Fixed incorrect parsing of chunk extensions with the pure Python
parser -- by :user:<code>bdraco</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9851">#9851</a>.</p>
</li>
<li>
<p>Fixed system routes polluting the middleware cache -- by
:user:<code>bdraco</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em></p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst">aiohttp's
changelog</a>.</em></p>
<blockquote>
<h1>3.10.11 (2024-11-13)</h1>
<h2>Bug fixes</h2>
<ul>
<li>
<p>Authentication provided by a redirect now takes precedence over
provided <code>auth</code> when making requests with the client -- by
:user:<code>PLPeeters</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>9436</code>.</p>
</li>
<li>
<p>Fixed :py:meth:<code>WebSocketResponse.close()
&lt;aiohttp.web.WebSocketResponse.close&gt;</code> to discard non-close
messages within its timeout window after sending close -- by
:user:<code>lenard-mosys</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>9506</code>.</p>
</li>
<li>
<p>Fixed a deadlock that could occur while attempting to get a new
connection slot after a timeout -- by :user:<code>bdraco</code>.</p>
<p>The connector was not cancellation-safe.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>9670</code>, :issue:<code>9671</code>.</p>
</li>
<li>
<p>Fixed the WebSocket flow control calculation undercounting with
multi-byte data -- by :user:<code>bdraco</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>9686</code>.</p>
</li>
<li>
<p>Fixed incorrect parsing of chunk extensions with the pure Python
parser -- by :user:<code>bdraco</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>9851</code>.</p>
</li>
<li>
<p>Fixed system routes polluting the middleware cache -- by
:user:<code>bdraco</code>.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/3e09325e4839117df13fbac301f360edf8d3a0ee"><code>3e09325</code></a>
Remove 3.10.11rc0 from 3.10 changelog (<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9858">#9858</a>)</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/beb7b740533b81d75706e6615f07d92fcbf1c325"><code>beb7b74</code></a>
Release 3.10.11 (<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9857">#9857</a>)</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/259edc369075de63e6f3a4eaade058c62af0df71"><code>259edc3</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9851">#9851</a>/541d86d
backport][3.10] Fix incorrect parsing of chunk extensions w...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/bc15db61615079d1b6327ba42c682f758fa96936"><code>bc15db6</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9852">#9852</a>/249855a
backport][3.10] Fix system routes polluting the middleware ...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/158bf304bdd8047eec192540fa5bf7fe3862bffd"><code>158bf30</code></a>
Release 3.10.11rc0 (<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9848">#9848</a>)</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/e5917cd3480b01e7527b6524f9bec954325e1d5f"><code>e5917cd</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9844">#9844</a>/fabf3884
backport][3.10] Fix compressed get request benchmark paylo...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/68a1f42af90a5beae28c8617e0dfc15c3bd5153c"><code>68a1f42</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9840">#9840</a>/cc5fa316
backport][3.10] Add benchmark for sending compressed paylo...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/4f4b90fef082fbb37395c394d68ee0ab3fcbc7e6"><code>4f4b90f</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9835">#9835</a>/32ccfc9a
backport][3.10] Adjust client payload benchmarks to better...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/f3dd0f9fece79dc3cd9d00e2ffddd49c36598361"><code>f3dd0f9</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9832">#9832</a>/006f4070
backport][3.10] Increase allowed import time for Python 3....</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/f2aab2e40336848d6a53ea03dc6d072a38c5e7f9"><code>f2aab2e</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/9827">#9827</a>/14fcfd4c
backport][3.10] Adjust client GET read benchmarks to inclu...</li>
<li>Additional commits viewable in <a
href="https://github.com/aio-libs/aiohttp/compare/v3.10.6...v3.10.11">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aiohttp&package-manager=pip&previous-version=3.10.6&new-version=3.10.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 07:56:56 -08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
72dac006f4 build(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /libs/cli/js-examples (#2456)
Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from
7.0.3 to 7.0.6.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md">cross-spawn's
changelog</a>.</em></p>
<blockquote>
<h3><a
href="https://github.com/moxystudio/node-cross-spawn/compare/v7.0.5...v7.0.6">7.0.6</a>
(2024-11-18)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>update cross-spawn version to 7.0.5 in package-lock.json (<a
href="https://github.com/moxystudio/node-cross-spawn/commit/f700743918d901eff92960e15a8dd68f87bd4176">f700743</a>)</li>
</ul>
<h3><a
href="https://github.com/moxystudio/node-cross-spawn/compare/v7.0.4...v7.0.5">7.0.5</a>
(2024-11-07)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>fix escaping bug introduced by backtracking (<a
href="https://github.com/moxystudio/node-cross-spawn/commit/640d391fde65388548601d95abedccc12943374f">640d391</a>)</li>
</ul>
<h3><a
href="https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.4">7.0.4</a>
(2024-11-07)</h3>
<h3>Bug Fixes</h3>
<ul>
<li>disable regexp backtracking (<a
href="https://redirect.github.com/moxystudio/node-cross-spawn/issues/160">#160</a>)
(<a
href="https://github.com/moxystudio/node-cross-spawn/commit/5ff3a07d9add449021d806e45c4168203aa833ff">5ff3a07</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/77cd97f3ca7b62c904a63a698fc4a79bf41977d0"><code>77cd97f</code></a>
chore(release): 7.0.6</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/6717de49ff1e5de49622488dcb9c33fb25370c85"><code>6717de4</code></a>
chore: upgrade standard-version</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/f700743918d901eff92960e15a8dd68f87bd4176"><code>f700743</code></a>
fix: update cross-spawn version to 7.0.5 in package-lock.json</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/9a7e3b2165917367f74b8365faad9873b30d7263"><code>9a7e3b2</code></a>
chore: fix build status badge</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/085268352dcbcad8064c64c5efb25268b4023184"><code>0852683</code></a>
chore(release): 7.0.5</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/640d391fde65388548601d95abedccc12943374f"><code>640d391</code></a>
fix: fix escaping bug introduced by backtracking</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/bff0c87c8b627c4e6d04ec2449e733048bebb464"><code>bff0c87</code></a>
chore: remove codecov</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/a7c6abc6fee79641d45b452fe6217deaa1bd0973"><code>a7c6abc</code></a>
chore: replace travis with github workflows</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/9b9246e0969e86656d7ccd527716bc3c18842a19"><code>9b9246e</code></a>
chore(release): 7.0.4</li>
<li><a
href="https://github.com/moxystudio/node-cross-spawn/commit/5ff3a07d9add449021d806e45c4168203aa833ff"><code>5ff3a07</code></a>
fix: disable regexp backtracking (<a
href="https://redirect.github.com/moxystudio/node-cross-spawn/issues/160">#160</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cross-spawn&package-manager=npm_and_yarn&previous-version=7.0.3&new-version=7.0.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langgraph/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-21 07:56:33 -08:00
William FHandGitHub 54d848913f [CLI] Update Inmem Version (#2500) 2024-11-21 15:49:59 +00:00
Nuno CamposandGitHub 7021e81150 Merge pull request #2496 from langchain-ai/vb/fix-error-message
langgraph: fix error message on invalid update
2024-11-20 18:46:50 -08:00
vbarda b977045679 langgraph: fix error message on invalid update 2024-11-20 21:24:50 -05:00
William FHandGitHub a933776436 [CLI] Validate node version (#2489) 2024-11-20 17:24:34 -08:00
Nuno Campos 588373c2d5 0.2.53 2024-11-20 17:13:42 -08:00
Nuno CamposandGitHub 267962bece Merge pull request #2491 from langchain-ai/nc/20nov/stream-putnowait-loop
lib: For subgraphs / stream modes call stream.put as a callback in the original event loop
2024-11-20 17:11:56 -08:00
Nuno CamposandGitHub 4ae29b6e2a Merge pull request #2492 from langchain-ai/wfh/accept_313
[CLI] Accept 3.13 in build
2024-11-20 17:04:15 -08:00
William Fu-Hinthorn 3c0de26914 Accept 3.13 in build 2024-11-20 16:26:17 -08:00
Nuno Campos a570662773 Lint 2024-11-20 15:43:46 -08:00
Nuno Campos 9766068896 lib: For subgraphs / stream modes call stream.put as a callback in the original event loop
- This is asynchronous, so we shouldn't use for regular writes to the output stream (ie those from PregelLoop)
- For writes from subgraphs / nodes this is fine to use, as we make no guarantees about when those show up anyway
2024-11-20 15:39:30 -08:00
Vadym BardaandGitHub 7e8eef88ca docs: small fix for tutorial (#2487) 2024-11-20 14:36:42 -05:00
Eugene YurtsevandGitHub e3e63c70c9 docs: how-to guide language changes (#2462) 2024-11-19 14:54:08 -05:00
Brace SproulandGitHub 312f0982bc Merge pull request #2476 from langchain-ai/release
(sdk-js): Release 0.0.26
2024-11-19 11:38:11 -08:00
bracesproul 153245145e (sdk-js): Release 0.0.26 2024-11-19 11:32:22 -08:00
Brace SproulandGitHub c95abd88a1 Merge pull request #2117 from langchain-ai/brace/default-assign-api-key
fix(sdk-js): Pass api key in headers by default if in env
2024-11-19 11:26:01 -08:00
Brace SproulandGitHub a2b357bed5 Merge branch 'main' into brace/default-assign-api-key 2024-11-19 11:16:55 -08:00
Brace SproulandGitHub 7090d7e9a8 Merge pull request #2471 from langchain-ai/brace/drop-trailing-slash
fix(sdk-js): remove trailing slash from url
2024-11-19 09:31:59 -08:00
bracesproul b3fa43e4a6 fix(sdk-js): remove trailing slash from url 2024-11-19 09:23:47 -08:00
Vadym BardaandGitHub b1779cf348 docs: update autogen docs (#2470) 2024-11-19 11:57:26 -05:00
Harrison ChaseandGitHub 26d18d3ca5 add how to guides for autogen integration (#2466) 2024-11-19 08:44:17 -08:00
12052d7d26 CLI docs (#2464)
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-11-19 10:57:07 -05:00
Vadym BardaandGitHub e3a30a9b69 docs: fix prompt (#2467) 2024-11-19 09:42:20 -05:00
William FHandGitHub ff1370a9a5 Release CLI (#2465) 2024-11-19 08:41:18 +00:00
William FHandGitHub 679a7365da Add default ns in put_writes (#2404) 2024-11-18 22:55:12 -08:00
b2522ffe19 CLI Dev command (#2463)
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2024-11-19 05:12:03 +00:00
Eugene YurtsevandGitHub 4212a795a0 docs[minor]: Fix layout issues in available templates (#2452) 2024-11-18 22:53:19 -05:00
Eugene YurtsevandGitHub 517d67aa32 docs: Update to use LANGSMITH_API_KEY throughout (#2461) 2024-11-18 22:51:36 -05:00
Brace SproulandGitHub feaf14765a Merge pull request #2458 from langchain-ai/brace/expose-command-interface
fix(sdk-js): Expose Command interface
2024-11-18 18:54:19 -08:00
Vadym BardaandGitHub cc6063c729 docs: simplify multi-agent tutorials (#2443) 2024-11-19 02:31:12 +00:00
013397042e docs: grammar (#2449)
Co-authored-by: Ian Sullivan <ian@frame.ai>
2024-11-18 21:01:37 -05:00
Nuno Campos 9a775d9c9f 0.2.52 2024-11-18 17:17:40 -08:00
Nuno Campos 2c945ceb68 Copy configurable in ensure_config 2024-11-18 17:17:20 -08:00
Erick FriisandGitHub 39eabd0fb8 Merge pull request #2459 from langchain-ai/erick/docs-self-hosted-plan-links
docs: self-hosted plan links
2024-11-18 16:42:02 -08:00
Erick Friis e5cc2e2044 docs: self-hosted plan links 2024-11-18 16:35:19 -08:00
bracesproul f00c0515e7 add jsdoc 2024-11-18 16:32:32 -08:00
bracesproul d87c0d4d53 fix(sdk-js): Expose Command interface 2024-11-18 16:25:51 -08:00
Nuno Campos fb40a974c8 0.2.51 2024-11-18 16:03:04 -08:00
Nuno Campos d63bfc6879 Add missing property 2024-11-18 16:02:54 -08:00
Nuno CamposandGitHub 97dd30711a Merge pull request #2437 from langchain-ai/nc/16nov/speed-up-find-subgraph
lib: find_subgraph doesn't need to look in both func and afunc
2024-11-18 15:59:58 -08:00
Vadym BardaandGitHub 016a9c1936 checkpoint-postgres: release 2.0.3 (#2455) 2024-11-18 16:55:54 -05:00
Nuno CamposandGitHub a2d6837fba Merge pull request #2413 from langchain-ai/vb/fix-pipeline
checkpoint-postgres: handle cases when conn.pipeline is not supported
2024-11-18 10:39:56 -08:00
Andrew NguonlyandGitHub f5bb2a3b04 docs: Update LangGraph Server API docs (#2451) 2024-11-18 09:38:38 -08:00
vbarda f807b73092 use capabilities 2024-11-18 12:15:18 -05:00
Nuno CamposandGitHub 167405daf2 Merge pull request #2434 from langchain-ai/nc/15nov/update-state-copy-parent
lib: When copying checkpoint, make it a child of the parent
2024-11-18 08:34:34 -08:00
William FHandGitHub c6360e5408 [Checkpoint] 2.0.5 (#2450) 2024-11-18 08:19:17 -08:00
vbarda f0505155a2 cache 2024-11-18 11:12:21 -05:00
886df0fa86 checkpoint: Add option to use persistent dict for in-memory checkpointer (#2439)
- This should only be used in very specific circunstances, sqlite or
postgres adapters much more appropriate in most circunstances

---------

Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2024-11-18 16:04:05 +00:00
Kevin MarkhamandGitHub 3f1792d6ba docs: fix typo (#2406) 2024-11-18 09:11:57 -05:00
ZapironandGitHub 9208052a94 docs: Update link to LCEL Concept Guide (#2438)
Updated the link to the LCEL concept guide
2024-11-18 09:09:12 -05:00
Nuno Campos 7866bd2718 lib: find_subgraph doesn't need to look in both func and afunc
- if they both exist they're expected to share the same implementation, so looking in both is redundant
2024-11-16 16:57:32 -08:00
Nuno Campos 7c11325e23 Separate 2024-11-15 17:33:01 -08:00
Nuno Campos d99dc7d81b Fix missing writes 2024-11-15 17:23:00 -08:00
Nuno Campos 973ad76a58 Fix 2024-11-15 17:05:18 -08:00
Nuno Campos 36e49eb190 Add distinct source 2024-11-15 17:04:40 -08:00
Nuno Campos 66b9a7dee7 lib: When copying checkpoint, make it a child of the parent 2024-11-15 16:56:17 -08:00
Nuno Campos 5494855ffa 0.2.50 2024-11-15 15:43:37 -08:00
Nuno Campos 38d93a324c 0.2.49 2024-11-15 15:02:31 -08:00
Nuno CamposandGitHub 07c65321c1 Merge pull request #2432 from langchain-ai/nc/15nov/copy-checkpoint
lib: Restore prev behavior for update_state(None)
2024-11-15 15:00:18 -08:00
Nuno Campos 1dbdd7df2e Lint 2024-11-15 14:54:55 -08:00
Nuno Campos dab29ce094 lib: Restore prev behavior for update_state(None)
- update_state(None) copies checkpoint and keeps current (PUSH) tasks, eg for replay
- update_state(None, as_node=END) clears all tasks (PUSH or PULL)
2024-11-15 14:48:56 -08:00
Vadym BardaandGitHub 0388534b9f docs: update double texting how-tos (#2431) 2024-11-15 22:45:36 +00:00
Nuno CamposandGitHub 81077e7c3a Merge pull request #2429 from langchain-ai/nc/15nov/sdk-js-types
sdk-js: Update types for state.task
2024-11-15 11:54:59 -08:00
Nuno Campos 29a0042149 sdk-js: Update types for state.task 2024-11-15 11:54:00 -08:00
William FHandGitHub e9162e2516 Update CLI pyproject.toml (#2428) 2024-11-15 11:00:32 -08:00
Vadym BardaandGitHub 0f6c001c25 docs: update replay in persistence concepts (#2427) 2024-11-15 18:49:20 +00:00
Eugene YurtsevandGitHub 7f26325c87 cli: minor wording change in new command (#2422) 2024-11-15 03:13:53 +00:00
Nuno CamposandGitHub 3c4ce3f945 Merge pull request #2420 from langchain-ai/nc/14nov/js-sdk-command
Nc/14nov/js sdk command
2024-11-14 18:21:38 -08:00
Nuno Campos 84ef939bf4 sdk-js 0.0.24 2024-11-14 18:17:22 -08:00
Nuno Campos bdc22ea127 sdk-js: Accept command when creating run 2024-11-14 18:17:04 -08:00
Vadym BardaandGitHub 5abbb79e1b Merge branch 'main' into vb/fix-pipeline 2024-11-14 19:08:18 -05:00
vbarda 0a5220aa07 code review 2024-11-14 19:06:41 -05:00
Nuno CamposandGitHub 970e68edcc Merge pull request #2417 from langchain-ai/vb/fix-debug-async
langgraph: add debug to AsyncPregelLoop
2024-11-14 06:53:18 -08:00
vbarda da1a80e86d lint 2024-11-14 09:37:39 -05:00
vbarda c4b240e0c2 langgraph: add debug to AsyncPregelLoop 2024-11-14 09:36:33 -05:00
vbarda c2052d11c2 checkpoint-postgres: remove pipeline flag in cursor 2024-11-13 21:42:51 -05:00
Vadym BardaandGitHub dc0281b99c docs: update rollback in double-texting concepts (#2412) 2024-11-13 21:21:12 -05:00
Nuno Campos 3a860ad537 0.2.48 2024-11-13 17:45:04 -08:00
Nuno Campos 7051bccc30 checkpoint 2.0.4 2024-11-13 17:37:01 -08:00
Nuno Campos 199e41b228 sdk py 0.1.36 2024-11-13 17:07:07 -08:00
Nuno Campos 229a9e19a8 sdk-py: Add command arg for creating runs 2024-11-13 17:06:56 -08:00
Nuno Campos 3c3a1a1f35 0.2.47 2024-11-13 14:02:25 -08:00
Nuno CamposandGitHub f11127648e Merge pull request #2346 from langchain-ai/nc/4nov/send-eager
lib: Execute Sends in the superstep that originated them (feature-flagged)
2024-11-13 13:39:50 -08:00
Nuno CamposandGitHub 29f833b1a7 Merge pull request #2393 from langchain-ai/nc/11nov/command-resume
lib: Add interrupt() function
2024-11-13 13:34:19 -08:00
Nuno CamposandGitHub 7a3ea42743 Merge pull request #2410 from langchain-ai/nc/13nov/command-dataclass
Nc/13nov/command dataclass
2024-11-13 13:28:13 -08:00
Nuno Campos a94902db8a Lint 2024-11-13 13:17:02 -08:00
Nuno Campos 9fd152ef3a format 2024-11-13 13:14:03 -08:00
Nuno Campos 03bc9ba6e6 Make Command a dataclass 2024-11-13 13:11:28 -08:00
Nuno Campos 7fe6f88876 Add resumeable/ns properties to Interrupt 2024-11-13 12:51:55 -08:00
Nuno CamposandGitHub 1d88affd29 Merge pull request #2400 from langchain-ai/nc/12nov/command
Make Command accept generic arg for destinations
2024-11-13 10:03:27 -08:00
Eugene YurtsevandGitHub 6906e12edb cli: add ability to output docker compose file (#2379)
* Add ability to output docker compose file `langgraph dockerfile
Dockerfile --add-docker-compose`
* Add emoji in places
2024-11-13 12:42:58 -05:00
William FHandGitHub 7b4c29a20d [Checkpointers] MemorySaver: refrain from overwriting writes (#2399) 2024-11-13 00:20:38 +00:00
Nuno Campos 16bfa80b58 Make Command accept generic arg for destinations 2024-11-12 16:18:23 -08:00
Eugene YurtsevandGitHub cb10437c3f cli: Add default to interactive flow in new command (#2398) 2024-11-12 16:38:15 -05:00
Eugene YurtsevandGitHub 2bcf1c0a20 cli[minor]: Add langgraph new command (#2369)
Adds a "new" command to create langgraph application from a template.
2024-11-12 14:30:51 -05:00
Nuno Campos 00964b18f6 Undo 2024-11-11 18:12:25 -08:00
Nuno Campos 0d5c6201d3 Disable in py 3.10 or below for async 2024-11-11 18:09:58 -08:00
Nuno Campos 86d2847dab Use neg idx 2024-11-11 17:57:45 -08:00
Nuno Campos b3a4eaa967 Remove print 2024-11-11 17:56:10 -08:00
Nuno Campos 87fc519ce7 Remove print 2024-11-11 17:54:56 -08:00
Nuno Campos ef3a1ee997 Undo 2024-11-11 17:54:04 -08:00
Nuno Campos 311e16dffd Remove prints 2024-11-11 17:52:18 -08:00
Nuno Campos c83b8f6d04 Update 2024-11-11 17:49:58 -08:00
Nuno Campos 62d3a85b07 Add sync test 2024-11-11 17:46:54 -08:00
Nuno Campos 810ae0ef51 lib: Add interrupt() function
- This works similarly to the input() function from stdlib
- calling it in a node interrupts execution
- invoking the graph with Command(resume=...) will set ... as the return value of interrupt() so that the node can access the "answer" to the "question"
- This PR also starts the work to control the graph on invoke/stream with Command() input, to be continued in a future PR
2024-11-11 17:44:03 -08:00
Nuno Campos 2ff49d2200 Update 2024-11-11 15:43:20 -08:00
Nuno Campos d0567dc7be Add feature flag (default off) so we can merge this before releasing
- Add additional ci job to test with FF on
2024-11-11 15:38:48 -08:00
Nuno Campos ea64ac5c07 Update 2024-11-11 14:18:14 -08:00
Nuno Campos 090b53ccc1 Lint 2024-11-11 14:14:23 -08:00
Nuno Campos 0e872e7482 Lin t 2024-11-11 14:12:33 -08:00
Nuno Campos 3ad966e057 Update 2024-11-11 14:08:59 -08:00
Nuno CamposandGitHub a73f9affab Merge pull request #2391 from langchain-ai/nc/11nov/control-to-command
lib: Rename Control to GraphCommand
2024-11-11 14:06:17 -08:00
Nuno Campos 89a0859928 Execute Sends in same super step that triggered them
- Keep old code path for compatibility with existing checkpoints
- Keep a similar order of application of updates, in some cases there will be no visible change
- Update task path for Sends to contain the path of all the parent tasks (multiple parents when a Send task creates another Send)
- That lineage path is used to ensure order of application of updates respects their logical lineage (ie updates from parents always applied before their child tasks)
- Move Interrupt writes to use negative indexes, which allow replacing/shadowing (when task is re-run it may interrupt again, or succeed)
- Runner will now attempt to schedule new Send tasks as soon as the write is received (ie while the originating node is still running)
- Update kafka scheduler to support new Send behavior
2024-11-11 14:01:16 -08:00
Nuno Campos 75c502cd93 Lint 2024-11-11 13:59:18 -08:00
Nuno Campos 0cc45f7a35 Lint 2024-11-11 13:04:23 -08:00
Nuno Campos efb1dd6a10 lib: Rename Control to GraphCommand 2024-11-11 13:01:04 -08:00
Nuno CamposandGitHub 6edb213fe7 Merge pull request #2388 from langchain-ai/nc/11nov/update-none-clear-all-tasks
lib: update_state(values=None) should clear all tasks
2024-11-11 12:07:51 -08:00
Nuno Campos c0513076a2 Lint 2024-11-11 11:07:36 -08:00
Nuno Campos c043f148a6 lib: update_state(values=None) should clear all tasks 2024-11-11 10:48:34 -08:00
David DuongandGitHub 366b5e04c7 Merge pull request #2376 from langchain-ai/dqbd/js-0.0.23-lc_build
fix(sdk-js): move to `@langchain/scripts` for building, bump to 0.0.23
2024-11-11 15:33:53 +01:00
Tat Dat Duong 72239d2228 Bump to 0.0.23, use @langchain/scripts 0.1.4 2024-11-11 15:01:12 +01:00
Vadym BardaandGitHub b7f238975a docs: fix nav sidebar (#2382) 2024-11-10 16:32:14 -05:00
Tat Dat Duong a3c45141ee Make sure we actually build the CJS 2024-11-08 20:52:44 +01:00
Tat Dat Duong f7b899a54d fix(sdk-js): move to @langchain/scripts for building 2024-11-08 20:08:38 +01:00
Vadym BardaandGitHub 95477277a2 docs: improve breadcrumbs behavior (#2375) 2024-11-08 18:39:59 +00:00
Andrew NguonlyandGitHub 64b446f671 Update LangGraph server API docs (#2374) 2024-11-08 10:32:17 -08:00
David DuongandGitHub c2d2e44794 Merge pull request #2372 from langchain-ai/dqbd/0.0.22-sdk-js
feat(sdk-js): bump to 0.0.22
2024-11-08 16:17:45 +01:00
Eugene YurtsevandGitHub f60b9f3b43 cli: add --version option (#2373)
- add version option
- add unit test
2024-11-08 02:49:30 +00:00
Tat Dat Duong e3acfa3435 feat(sdk-js): bump to 0.0.22 2024-11-08 03:19:27 +01:00
Vadym BardaandGitHub 0f92c89529 docs: show nav menu for mobile (#2371) 2024-11-07 20:31:49 -05:00
Andrew NguonlyandGitHub 7cba75ec35 sdk-js: Add custom and messages-tuple stream modes (#2370) 2024-11-07 16:32:08 -08:00
Vadym BardaandGitHub 8408ba3a3e docs: add breadcrumbs (#2363) 2024-11-07 21:33:55 +00:00
Nuno CamposandGitHub c8c58b30d5 Merge pull request #2368 from langchain-ai/nc/7nov/control
lib: Rename args in Control object
2024-11-07 13:19:12 -08:00
Nuno Campos b4bed3329c lib: Rename args in Control object
- update_state -> state
- trigger -> goto
2024-11-07 13:12:19 -08:00
Eugene YurtsevandGitHub 4eec3aa69e docs: fix some typos (#2364) 2024-11-07 14:52:47 -05:00
Vadym BardaandGitHub 35e3276e34 langgraph: add add_sequence to StateGraph (#2352) 2024-11-07 13:16:34 -05:00
Nuno CamposandGitHub b346f4ead8 Merge pull request #2358 from langchain-ai/nc/6nov/kafka-missing-task-id
kafka: Add missing task id for TaskNotFound error
2024-11-06 16:48:25 -08:00
Vadym BardaandGitHub fef748e6cc docs: add another ignore url pattern to link check (#2357) 2024-11-07 00:43:22 +00:00
Nuno Campos 19cc95f7b6 kafka: Add missing task id for TaskNotFound error 2024-11-06 16:41:43 -08:00
Vadym BardaandGitHub eef65d94ac docs: fix numbered list in assistant versioning (#2356) 2024-11-06 22:17:01 +00:00
Nuno Campos 72d497e052 Move code 2024-11-06 09:02:06 -08:00
Nuno CamposandGitHub 32f58258aa Merge pull request #2355 from langchain-ai/nc/6nov/loop-match-writes
lib: Split out _match_writes util in PregelLoop
2024-11-06 08:55:10 -08:00
Nuno Campos 87d57b434a lib: Split out _match_writes util in PregelLoop 2024-11-06 08:48:30 -08:00
Nuno CamposandGitHub 4bbbb7d246 Merge pull request #2354 from langchain-ai/nc/6nov/cached-tasks-output-timing
lib: For cached tasks, emit output events after task events
2024-11-06 08:29:38 -08:00
Nuno Campos c1ce3c6b5f lib: For cached tasks, emit output events after task events 2024-11-06 08:22:54 -08:00
Nuno CamposandGitHub 511de6f5f6 Merge pull request #2353 from langchain-ai/dqbd/runnable-passthrough-test
fix(graph): invalid graph representation if RunnablePassthrough is used
2024-11-06 08:14:19 -08:00
Nuno Campos 4dc08cd724 Fix 2024-11-06 08:07:48 -08:00
Tat Dat Duong d7b9b3b01d fix(graph): invalid graph representation if RunnablePassthrough is used 2024-11-06 16:34:29 +01:00
Vadym BardaandGitHub a82ded65c6 docs: fix install/env cell for customer support tutorial (#2350) 2024-11-05 19:50:05 -05:00
Brace SproulandGitHub 1ca49fa568 Merge pull request #2348 from langchain-ai/brace/filter-status-js
feat(js-sdk): Add status field in search args
2024-11-05 16:40:23 -08:00
bracesproul 4eb3cd32fa cr 2024-11-05 16:04:52 -08:00
Brace SproulandGitHub 80d2a315aa Merge branch 'main' into brace/filter-status-js 2024-11-05 16:03:58 -08:00
bracesproul 82c9aa8485 feat(js-sdk): Add status field in search args 2024-11-05 16:03:24 -08:00
Nuno CamposandGitHub 8ecfafefbf Merge pull request #2347 from langchain-ai/nc/5nov/control-serializable
lib: Make Control object serializable
2024-11-05 15:34:13 -08:00
Nuno Campos 010564cbb3 lib: Make Control object serializable 2024-11-05 15:24:20 -08:00
Nuno Campos 18a3fa4a00 Ignore unknown tasks 2024-11-05 14:22:23 -08:00
Nuno Campos de8e487ff1 Add todo 2024-11-05 10:53:42 -08:00
Nuno CamposandGitHub e5ebdff4d8 Merge pull request #2342 from langchain-ai/nc/5nov/send-test-interrupt-before
Add two more test cases for Send + interrupt
2024-11-05 09:34:04 -08:00
Nuno Campos f283dac325 Add one more test for send-react-interrupt flow with replacing tool call 2024-11-05 09:27:02 -08:00
Nuno Campos 639501809c api: Add one more test case for send + interrupt before
- Testing same exact behavior as send + interrupt after
2024-11-05 09:15:46 -08:00
Nuno CamposandGitHub 36e6b89081 Merge pull request #2333 from langchain-ai/nc/apply-writes-order
lib: Enforce write application order in apply_writes
2024-11-05 09:07:23 -08:00
Nuno CamposandGitHub 90639e6cd7 Merge pull request #2332 from langchain-ai/nc/4nov/update-state-latest
lib: When updating state from latest, apply pending writes first
2024-11-04 16:59:51 -08:00
Nuno Campos dec0b7f439 Lint 2024-11-04 16:43:07 -08:00
Nuno Campos 04657408f8 lib: Enforce write application order in apply_writes
- Previously order was enforced in prepare_next_tasks, but that's not a good fit for future features
- This changes order between PULL and PUSH tasks, updates from PUSH tasks will now be applied after updates from PULL tasks
2024-11-04 16:39:04 -08:00
Nuno Campos 971d746061 Lint 2024-11-04 16:33:20 -08:00
Nuno Campos 9a2ba8c8cd lib: When updating state from latest, apply pending writes first
- This picks a default value for as_node which matches the node which last acted, even if the step didnt finish (due to an interrupt)
2024-11-04 16:20:21 -08:00
Nuno CamposandGitHub b50d41bbf3 Merge pull request #2331 from langchain-ai/nc/4nov/get-state-latest-next
lib: When getting latest state, alst make `next` reflect pending writes
2024-11-04 16:16:53 -08:00
Nuno Campos b71fd5092b lib: When getting latest state, alst make next reflect pending writes
- ie. tasks already executed should not show up in `next` list
2024-11-04 16:03:34 -08:00
Nuno CamposandGitHub f9b151b67f Merge pull request #2330 from langchain-ai/nc/4nov/test-react-send
lib: Add test for react architecture using Send + interrupt_before
2024-11-04 15:58:27 -08:00
William FHandGitHub 7ba9a66301 [Docs] Clarify checkpointer options (#2328) 2024-11-04 15:43:00 -08:00
Nuno CamposandGitHub 1b85764bf6 Merge pull request #2329 from langchain-ai/nc/4nov/get-state-apply-pending-writes
lib: In calls to get_state apply pending writes
2024-11-04 15:42:23 -08:00
Nuno CamposandGitHub 5e4c928948 Merge pull request #2327 from langchain-ai/nc/4nov/send-tests
lib: Add two more tests for Send
2024-11-04 15:42:08 -08:00
Nuno Campos ae282e3ae1 lib: Add test for react architecture using Send + interrupt_before
- Both for cond edge and edgeless graphs
2024-11-04 15:41:02 -08:00
Nuno Campos de3b654735 Add one more assertion 2024-11-04 15:14:29 -08:00
Nuno Campos d28734f287 Lint 2024-11-04 15:12:34 -08:00
Nuno Campos f9409022ed lib: In calls to get_state apply pending writes
- When calling get_state without a checkpoint id (ie to get the latest state) apply any pending writes for current checkpoint
2024-11-04 15:10:12 -08:00
Nuno Campos 8138c88b41 Add async versions 2024-11-04 11:56:31 -08:00
Nuno Campos 38332fd3c6 Lint 2024-11-04 11:55:14 -08:00
Nuno Campos 5606bef3dd lib: Add two more tests for Send 2024-11-04 11:52:39 -08:00
Vadym BardaandGitHub 895079bbdc langgraph: release 0.2.45 (#2326) 2024-11-04 14:34:07 -05:00
Nuno CamposandGitHub 6aaf80f2fd Merge pull request #2325 from langchain-ai/nc/4nov/unset-skip-done-tasks
lib: Unset skip_done_tasks after each tick of the loop
2024-11-04 11:30:08 -08:00
Vadym BardaandGitHub 2e656d9145 langgraph: add config metadata to pregel loop (#2323) 2024-11-04 19:26:34 +00:00
Nuno CamposandGitHub 1fb8e013f7 Merge pull request #2303 from langchain-ai/nc/1nov/test-send-order
Test order of update application after Send
2024-11-04 11:26:04 -08:00
Nuno CamposandGitHub f8fe2041d9 Merge pull request #2144 from langchain-ai/nc/19oct/graph-control
lib: Add support for graphs without edges
2024-11-04 11:25:40 -08:00
Nuno Campos 014f8485a6 lib: Unset skip_done_tasks after each tick of the loop 2024-11-04 11:23:53 -08:00
David DuongandGitHub 58d7eb9b17 Merge pull request #2322 from langchain-ai/dqbd/cli-prebuild-js
feat(cli): add JS prebuild script
2024-11-04 18:13:25 +01:00
Tat Dat Duong 44ff5f1a5a Update tests 2024-11-04 14:00:02 +01:00
David DuongandGitHub 46f25cf926 Merge pull request #2307 from langchain-ai/dqbd/cli-js-other-pkg-managers
feat(cli): add support for other JS package managers based off package lock
2024-11-04 13:59:28 +01:00
Tat Dat Duong e1467c27cb Remove newline 2024-11-04 13:52:40 +01:00
Tat Dat Duong 5deedfe548 Bump to 0.1.53 2024-11-04 13:51:46 +01:00
Tat Dat Duong 30937d0406 feat(cli): add JS prebuild script 2024-11-04 13:50:41 +01:00
David DuongandGitHub 6eb8130419 Merge pull request #2310 from langchain-ai/dqbd/sdk-js-types
feat(sdk-js): improve types for drawable graph, interrupts and metadata
2024-11-04 13:26:58 +01:00
Tat Dat Duong 8455771eb9 Bump to 0.0.21 2024-11-04 13:20:36 +01:00
Tat Dat Duong 39dcafcdea feat(sdk-js): improve types for drawable graph, interrupts and metadata 2024-11-02 02:48:47 +01:00
Tat Dat Duong 7854a19dac Update test 2024-11-02 02:05:42 +01:00
AllenandGitHub 18cea39090 fix(docs): function call in partial (#2297)
Docs use prompts with partial + function call, which would result in a
static datetime as opposed to a dynamic datetime being rendered on use.
2024-11-02 00:37:16 +00:00
Vadym BardaandGitHub 46ffa0e8d4 langgraph: release 0.2.44 (#2308) 2024-11-01 20:27:17 -04:00
Tat Dat Duong bf3098a075 feat(cli): add support for other JS package managers based off package lock 2024-11-02 00:44:08 +01:00
Andrew NguonlyandGitHub cdd7899564 RemoteGraph: If node name is not present, fallback to node id as the node name (#2304) 2024-11-01 15:21:39 -07:00
Vadym BardaandGitHub eeebd44a87 docs: add subgraph streaming example for remote graph (#2306) 2024-11-01 22:16:09 +00:00
Vadym BardaandGitHub 805f437534 docs: fix link in the tutorial (#2305) 2024-11-01 17:52:09 -04:00
Vadym BardaandGitHub 782b9a7903 langgraph: add message list validation to create_react_agent + a troubleshooting guide (#2182) 2024-11-01 17:40:53 -04:00
Andrew NguonlyandGitHub ecb584cbe0 sdk: Add action query param to cancel Run methods (#2284) 2024-11-01 13:32:49 -07:00
Nuno Campos 1e3953d1e0 Test order of update application after Send
- updates from inside Send tasks are applied in the order the Sends were created, if when you fan out, and have each task write results to a list with reducer, the final list is in the order you used when triggering
2024-11-01 13:23:10 -07:00
William FHandGitHub 509291fc1a Bump CLI (#2302) 2024-11-01 19:53:48 +00:00
Vadym BardaandGitHub dbb1958be5 docs: add more redirects & remove unused cloud pages (#2301) 2024-11-01 19:40:21 +00:00
Vadym BardaandGitHub d261d43b39 docs: update the docs for streaming messages (#2299) 2024-11-01 14:38:41 -04:00
Andrew NguonlyandGitHub 6986a50711 Update LangGraph Server API docs (#2300) 2024-11-01 11:38:12 -07:00
Nuno CamposandGitHub e9fe3e8bd9 Merge pull request #2298 from langchain-ai/dqbd/cli-debugger-rename
chore(cli): rename Debugger to LangGraph Studio
2024-11-01 11:11:07 -07:00
ccurmeandGitHub bdca2f590a Merge pull request #2294 from langchain-ai/cc/webhooks
docs: add some detail on webhooks
2024-11-01 14:01:42 -04:00
Tat Dat Duong f4801ae9ae chore(cli): rename Debugger to LangGraph Studio 2024-11-01 18:47:35 +01:00
Nuno CamposandGitHub 47ea264b46 Merge pull request #2296 from langchain-ai/vb/remap
langgraph: handle messages-tuple stream mode in RemoteGraph
2024-11-01 09:50:51 -07:00
vbarda 84e023e10b langgraph: handle messages-tuple stream mode in RemoteGraph 2024-11-01 12:43:59 -04:00
Chester Curme 52f0953786 add detail 2024-11-01 11:23:16 -04:00
Vadym BardaandGitHub d9743f684e docs: update annotation in tutorial (#2293) 2024-11-01 13:57:16 +00:00
Vadym BardaandGitHub 4aebb461e9 docs: update core in docs dependencies (#2291) 2024-11-01 09:51:34 -04:00
Vadym BardaandGitHub c2cc1e2e5e docs: remove token-by-token streaming from stream events (#2292) 2024-11-01 13:27:06 +00:00
William FHandGitHub 66cf2e6779 Add Tree of Thoughts (#1128) 2024-10-31 21:27:13 -07:00
Vadym BardaandGitHub 7bacb8c984 langgraph: release 0.2.43 (#2286) 2024-10-31 17:57:21 -04:00
BagaturandGitHub e2de59c6fb langgraph[patch]: bump core ^0.3.15 || ^ 0.2.43 (#2285) 2024-10-31 17:53:03 -04:00
Vadym BardaandGitHub c28dc26356 docs: fix typo (#2283) 2024-10-31 16:27:07 -04:00
Eugene YurtsevandGitHub ea012fb7dc docs: reorder reference (#2282) 2024-10-31 20:25:58 +00:00
Nuno Campos 18e71469e1 Lint 2024-10-31 12:57:00 -07:00
Eugene YurtsevandGitHub 4b1d30906e ci: update deploy docs workflow to check external links on langchain.com (#2280)
Reverts temporary change that was made yesterday to accommodate a link
that was only available on the staging version of langchain.com
2024-10-31 14:48:32 -04:00
Eugene YurtsevandGitHub 8b36013a03 Fix bad tab in how-to guide (#2278) 2024-10-31 14:48:21 -04:00
Vadym BardaandGitHub ed91572ceb docs: expose how-to on rebuilding graph at runtime (#2281) 2024-10-31 18:34:16 +00:00
Eugene YurtsevandGitHub 4150abf18c docs: update reference layout (#2279)
![image](https://github.com/user-attachments/assets/62f1588c-d08d-474c-b512-a558759e7627)
2024-10-31 18:23:27 +00:00
Vadym BardaandGitHub e132dfc955 docs: update FAQ (#2277)
Sync with https://www.langchain.com/langgraph
2024-10-31 13:43:08 -04:00
Nuno Campos 2624fc43dd Fix 2024-10-31 09:40:24 -07:00
Nuno Campos 0c5c2e6370 lib: Add support for graphs without edges
- Return Control(update_state=, trigger=, send=) from your nodes instead
- Annotate nodes with Control[Literal["destination"]] to see your graph connections drawn
2024-10-31 09:38:43 -07:00
Harrison ChaseandGitHub f7a93f99ef cp readme over (#2274) 2024-10-31 15:17:26 +00:00
Vadym BardaandGitHub 9f29bbfce8 docs: add flags to self-hosted (#2272) 2024-10-31 11:11:26 -04:00
Vadym BardaandGitHub 0075080827 docs: update quick start (#2273) 2024-10-31 11:11:07 -04:00
Harrison ChaseandGitHub 63318e5690 Harrison/update readme 1 (#2262) 2024-10-31 10:02:40 -05:00
Harrison ChaseandGitHub d0c12b1b7f Harrison/update language (#2271) 2024-10-31 10:01:22 -05:00
Vadym BardaandGitHub 194b4e0d9b langgraph: release 0.2.42 (#2270) 2024-10-31 10:32:13 -04:00
Nuno CamposandGitHub c6c7f400ae Merge pull request #2256 from langchain-ai/nc/30oct/fix-messages-subgraphs
Fix stream_mode=messages used together with subgraphs=True
2024-10-31 07:27:04 -07:00
Vadym BardaandGitHub c91e6bcc46 Merge branch 'main' into nc/30oct/fix-messages-subgraphs 2024-10-31 10:14:04 -04:00
vbarda ca69566d67 remove events 2024-10-31 10:13:24 -04:00
Jacob LeeandGitHub 0bedfa3628 docs: Fix typos (#2266) 2024-10-31 10:00:37 -04:00
Vadym BardaandGitHub fd82f037c6 docs: update remote graph how-to (#2269) 2024-10-31 09:58:11 -04:00
Vadym BardaandGitHub 2bacc42e01 docs: fix typo in remote graph how-to (#2268) 2024-10-31 09:29:10 -04:00
Eugene YurtsevandGitHub b527b785fd disable more link checking (#2265) 2024-10-31 04:10:10 +00:00
Eugene YurtsevandGitHub c3622cb0fe docs: disable link check for link that doesn't exist yet (#2263) 2024-10-31 03:51:44 +00:00
d0e59f406b docs: concepts for cloud and doc-reorg (#2196)
Update langgraph documentation

---------

Co-authored-by: Vadym Barda <vadym@langchain.dev>
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
Co-authored-by: Nuno Campos <nuno@langchain.dev>
Co-authored-by: Chester Curme <chester.curme@gmail.com>
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-10-30 23:34:02 -04:00
Nuno Campos 4cc6d789ed Fix stream_mode=messages used together with subgraphs=True 2024-10-30 19:35:28 -07:00
BagaturandGitHub d6d6ab9b73 langgraph[patch]: fix core dep specification (#2253) 2024-10-30 21:50:46 -04:00
Vadym BardaandGitHub e7816eb197 ci: turn off release attestations (#2252) 2024-10-30 21:28:34 -04:00
Vadym BardaandGitHub 4f8b69360c langgraph: release 0.2.41 (#2251) 2024-10-30 21:22:54 -04:00
Vadym BardaandGitHub 0718d0a660 langgraph: fix caller_ns in remote graph (#2250) 2024-10-31 01:20:36 +00:00
BagaturandGitHub 3641e65cac langgraph[patch]: fix annotations in inherited tool schemas (#2236)
fix #2220
2024-10-30 21:19:02 -04:00
Nuno CamposandGitHub b17141604d Merge pull request #2247 from langchain-ai/jacob/nit
fix: Fix typo in remote graph astream
2024-10-30 14:59:27 -07:00
Nuno Campos 5fece1cbfc langgraph 0.2.40 2024-10-30 14:58:27 -07:00
Nuno CamposandGitHub a85b7fca15 Merge pull request #2246 from langchain-ai/nc/30oct/node-callback
Add "node finished" callback
2024-10-30 14:57:51 -07:00
jacoblee93 af9a09b182 Fix typo in remote graph astream 2024-10-30 14:52:59 -07:00
Nuno Campos 75c8f99d3c Add "node finished" callback 2024-10-30 14:45:09 -07:00
Nuno CamposandGitHub 46892855c5 Merge pull request #2242 from langchain-ai/nc/30oct/remote-subgraphs
fix: RemoteGraph should propagate subgraphs streaming
2024-10-30 14:23:45 -07:00
Nuno Campos 59e8d59b7c Fix 2024-10-30 14:17:50 -07:00
Nuno Campos 5cb6ff79ca Prepend ns 2024-10-30 14:09:43 -07:00
Nuno Campos 9c41ce0b1c Lint 2024-10-30 14:07:27 -07:00
Nuno Campos 61abee4bd4 Lint 2024-10-30 13:59:31 -07:00
Nuno Campos 43d9567c5d fix: RemoteGraph should propagate subgraphs streaming 2024-10-30 13:47:27 -07:00
Nuno CamposandGitHub 3923979479 Merge pull request #2235 from langchain-ai/nc/30oct/remote-invoke
lib: Ensure RemoteGraph.invoke emits all subgraph events as expected
2024-10-30 13:26:56 -07:00
Nuno Campos 5312fbd7f4 Fix 2024-10-30 13:20:55 -07:00
David DuongandGitHub ae412bbede Merge pull request #2237 from langchain-ai/jacob/sdk
feat(sdk-js): Support if_not_exists in SDK runs
2024-10-30 19:16:22 +01:00
jacoblee93 69c8d21ba6 Support if_not_exists 2024-10-30 11:10:08 -07:00
Nuno Campos 2dfc4e3cc0 lib: Ensure RemoteGraph.invoke emits all subgraph events as expected
- Just delegate to stream
2024-10-30 10:40:14 -07:00
74c8589045 Add support for Docker arg passthrough in langgraph CLI (#2206)
Added a js-example to show it builds
Adapted integration tests after removing the test CLI command

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-10-29 22:33:40 -07:00
Vadym BardaandGitHub 4717632ce7 sdk-py: more docstring updates (#2225) 2024-10-30 01:22:29 +00:00
Andrew NguonlyandGitHub 726a85f26b Add docstring to RemoteGraph (#2217) 2024-10-29 15:31:21 -07:00
Vadym BardaandGitHub 8a0650a46b sdk-py: update docstrings (#2221) 2024-10-29 20:31:12 +00:00
Vadym BardaandGitHub e7dc43b7ca langgraph: validate sync/async clients initialized correctly in RemoteGraph (#2214) 2024-10-29 13:21:10 -04:00
Nuno Campos 90195af1d8 sdk-py 0.1.35 2024-10-28 15:22:05 -07:00
Nuno Campos da707343dc sdk-js 0.0.19 2024-10-28 15:21:57 -07:00
Nuno CamposandGitHub 1f5fc505c6 Merge pull request #2204 from langchain-ai/nc/28oct/sdk-wait-raise-error
sdk: By default raise errors in /wait endpoint
2024-10-28 14:46:14 -07:00
Nuno Campos 4c655f841e Lint 2024-10-28 14:40:25 -07:00
Nuno Campos be27c96f3c sdk: By default raise errors in /wait endpoint 2024-10-28 14:27:13 -07:00
eric-langchainandGitHub 5090e30f71 Merge pull request #2185 from langchain-ai/update-docs-for-homepage-redesign
home page redesign docs
2024-10-28 11:47:34 -05:00
Lance MartinandGitHub 688de89864 Fix link that is causing docs build to fail (#2194) 2024-10-25 23:34:08 +00:00
Lance MartinandGitHub 62444d4c63 Update memory concept doc (#2181)
Add content on [memory
types](https://blog.langchain.dev/memory-for-agents/).
2024-10-25 14:08:04 -07:00
Eugene YurtsevandGitHub 4a970cca8b docs: update main site layout (#2191)
* Remove land hand sidebar on most pages
* Cleans up some headings
* Adds error reference information to index (it was already on the
sidebar for the how-to page) -- should probably be its own tab?
* Adds an index page for the reference (so it's easier to link to a main
reference page), alternatively we can set up a redirect from index to
graph
2024-10-25 16:49:31 -04:00
Eugene YurtsevandGitHub 18b9135770 docs: update tutorials index page (#2190)
Minor formatting update -- since this section stands right now looks
quite bad
2024-10-25 18:08:21 +00:00
David DuongandGitHub d266ddb312 Merge pull request #2167 from langchain-ai/dqbd/sdk-js-timeout
feat(sdk-js): implement abort signal timeout, make default timeout for runs 5 minutes
2024-10-25 15:40:30 +02:00
Tat Dat Duong 7a348ac19c Don't enforce timeouts for run stream / block endpoints 2024-10-25 15:34:36 +02:00
Eric han 123d93539a some more spots 2024-10-24 17:14:02 -05:00
Eric han 785e7dab3a home page redesign docs 2024-10-24 17:04:20 -05:00
Vadym BardaandGitHub 582fb11dd4 checkpoint-sqlite: release 2.0.1 (#2184) 2024-10-24 17:08:25 -04:00
Vadym BardaandGitHub 39d9cdbef0 checkpoint-postgres: release 2.0.2 (#2183) 2024-10-24 17:06:36 -04:00
Vadym BardaandGitHub 6dacd1aabe langgraph: always raise NodeInterrupt in ToolNode if raised from a tool (#2175) 2024-10-24 18:21:18 +00:00
Vadym BardaandGitHub 91ad8b803b checkpoint-duckdb: release 2.0.1 (#2180) 2024-10-24 13:58:48 -04:00
Vadym BardaandGitHub a0e99f704f checkpoint: release 2.0.2 (#2179) 2024-10-24 13:52:02 -04:00
Vadym BardaandGitHub def3e06b4a move py.typed to submodules for namespace packages (#2177) 2024-10-24 13:43:43 -04:00
David DuongandGitHub a4fab2a867 Merge pull request #2178 from langchain-ai/dqbd/sdk-bump-24oct
feat(sdk): bump SDK to js@0.0.18 and py@0.1.34
2024-10-24 18:58:07 +02:00
Tat Dat Duong cf1c7f3673 feat(sdk): bump SDK to js@0.0.18 and py@0.1.34 2024-10-24 18:51:56 +02:00
Nuno CamposandGitHub 6c05b66c7c Merge pull request #2176 from langchain-ai/dqbd/error-thread-state
fix(sdk): add error thread state
2024-10-24 09:23:20 -07:00
Tat Dat Duong 5c44dcef81 fix(sdk): add error thread state 2024-10-24 18:16:21 +02:00
Nuno Campos 7fd6b1b4be Fix 2024-10-24 08:48:46 -07:00
Vadym BardaandGitHub 6202e0f1d9 docs: update branching how-to notebook (#2174) 2024-10-24 14:56:19 +00:00
Tat Dat Duong ccfeafa975 feat(sdk-js): implement abort signal timeout, make default timeout for runs 5 minutes 2024-10-24 09:38:42 +02:00
Nuno CamposandGitHub 83238f51d8 Merge pull request #2166 from langchain-ai/nc/23oct/remote-graph-interop
Interop of RemoteGraph w core lib
2024-10-23 20:36:38 -07:00
Nuno Campos 05f008cbfb Lint 2024-10-23 20:30:32 -07:00
Nuno Campos a8ae2a52a3 Lint 2024-10-23 20:27:18 -07:00
Nuno Campos aa245a8e71 Fix up 2024-10-23 20:22:04 -07:00
bdc75a22d5 langgraph: expand handle_tool_errors in ToolNode (#1667)
This change expands error-handling functionality of the `ToolNode` by
introducing more options for `handle_tool_errors`. Default behavior of
the `ToolNode` is unchanged -- all errors are handled and wrapped in a
`ToolMessage` to be sent back to LLM.

With this change, users have flexibility to only handle the exceptions
that they need to pass back to the LLM:

* they can specify exceptions to handle by passing a tuple of exceptions
in `handle_tool_errors`
* specify `handle_tool_errors=True/str/callable`
* when `handle_tool_errors` is a callable, the signature will be
inspected and exceptions from the signature will be handled

---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-10-24 00:58:05 +00:00
Nuno Campos 69227daff3 Lint 2024-10-23 17:01:58 -07:00
Nuno Campos dc8260bb72 Interop of RemoteGraph w core lib 2024-10-23 15:37:17 -07:00
Vadym BardaandGitHub 62a5ec509d checkpoint: add DuckDB store (#2154) 2024-10-23 22:20:10 +00:00
Vadym BardaandGitHub d32386f849 checkpoint: add DuckDB checkpointer (#2145) 2024-10-23 21:11:03 +00:00
Nuno CamposandGitHub 08a1ed38f1 Merge pull request #2092 from langchain-ai/an/11oct/remote-graph-interrupt
Update `stream()` and `astream()` methods in `RemoteGraph` to process `updates` event types
2024-10-23 13:48:43 -07:00
Nuno Campos 037a95ff60 Update tests 2024-10-23 13:43:48 -07:00
Nuno Campos e294720ec5 Lint 2024-10-23 13:29:59 -07:00
Nuno Campos f8a0b7a464 Use if_not_exists 2024-10-23 13:24:19 -07:00
Nuno Campos 1121806ba4 Add if_not_exists 2024-10-23 13:23:49 -07:00
Nuno Campos dca200d6c4 Finish 2024-10-23 13:23:42 -07:00
Vadym BardaandGitHub 6f236b5f2c docs: update multi-agent concept examples (#2151) 2024-10-23 13:40:24 -04:00
Vadym BardaandGitHub 916affa1b5 langgraph: add 'messages_key' param to ToolNode / tools_condition (#2049) 2024-10-22 17:32:05 -04:00
Nuno Campos 58cf0c6a6e chore: Switch s3 client utils from httpx client to curl client 2024-10-22 10:46:37 -07:00
gbaian10andGitHub 0042889c31 Support read type hints from the method in add_node (#2014)
Add function to read type hints from the `__call__` method to resolve issue #1950.
2024-10-22 17:11:59 +00:00
nikhildigdeandGitHub 2be012d8ed docs: fix typo in concept docs 2024-10-21 21:40:47 +00:00
Yuki OshimaandGitHub 780285ef91 Fix(docs): InMemoryStore example error (#2148) 2024-10-21 18:39:43 +00:00
Nuno CamposandGitHub 47c7b76aa1 Merge pull request #2152 from langchain-ai/nc/21oct/skip-docker-login-for-forks
ci: Skip docker login for PRs from forks
2024-10-21 10:09:54 -07:00
Nuno Campos 9931f61525 ci: Skip docker login for PRs from forks 2024-10-21 10:04:40 -07:00
Nuno CamposandGitHub 0d81ad92f0 Merge pull request #2143 from langchain-ai/nc/19oct/async-max-concurrency
lib: Add max_concurrency for async executions
2024-10-19 15:16:15 -07:00
Nuno Campos 7d3f2ca3ed Lint 2024-10-19 15:11:18 -07:00
Nuno Campos 42648c88dd lib: Add max_concurrency for async executions 2024-10-19 12:45:01 -07:00
Vadym BardaandGitHub 1aab758634 langgraph: release 0.2.39 (#2139) 2024-10-18 14:47:50 -04:00
Vadym BardaandGitHub b5fbc7a7b8 docs: temporarily disable some link checks (#2138) 2024-10-18 14:37:19 -04:00
b647dcb0f2 feat: Add LangGraph error pages (#2136)
Co-authored-by: Erick Friis <erick@langchain.dev>
Co-authored-by: vbarda <vadym@langchain.dev>
2024-10-18 18:20:22 +00:00
Nuno CamposandGitHub 4df5680732 Merge pull request #2132 from langchain-ai/nc/17oct/stream-messages-nostream-tag
For stream_mode=messages skip any nodes/llms with tag nostream
2024-10-17 15:57:09 -07:00
Nuno Campos 74a17a6d4c Update tests 2024-10-17 15:52:17 -07:00
Nuno Campos e2a3698250 For stream_mode=messages skip any nodes/llms with tag nostream 2024-10-17 15:28:14 -07:00
Vadym BardaandGitHub 4dfdb9a83e docs: update tags for store endpoints in API docs (#2127) 2024-10-16 16:34:54 +00:00
Vadym BardaandGitHub 583d8c9499 docs: update tutorial names/links (#2126) 2024-10-16 15:17:28 +00:00
vbarda 15bbede7bc update image in multi-agent concepts 2024-10-16 10:59:07 -04:00
Vadym BardaandGitHub 3ffdf4bb3f docs: update image in concepts (#2125) 2024-10-16 13:59:17 +00:00
Nuno CamposandGitHub 6578698414 Merge pull request #2124 from langchain-ai/dqbd/js-bump-0.0.17
feat(sdk-js): bump to 0.0.17
2024-10-16 06:21:22 -07:00
Tat Dat Duong 048ae6c17b feat(sdk-js): bump to 0.0.17 2024-10-16 15:19:39 +02:00
Nuno CamposandGitHub 0e2c2eb13a Merge pull request #2120 from langchain-ai/nc/15oct/executor-dict
fix: Avoid errors from executor modifying tasks dict during exit routine
2024-10-15 16:15:55 -07:00
Nuno Campos 515c4ffebe Fix 2024-10-15 16:11:08 -07:00
Nuno Campos eefe057a47 fix: Avoid errors from executor modifying tasks dict during exit routine
- This could happen if a task happened to finish while the exit routine is running
2024-10-15 15:13:46 -07:00
18f34c30d8 docs: update subgraph how-to (#2079)
Co-authored-by: vbarda <vadym@langchain.dev>
2024-10-15 17:30:34 -04:00
2670bcf330 docs: add concepts for subgraphs and multi-agent (#2069)
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-10-15 17:17:22 -04:00
bracesproul 433c382280 cr 2024-10-15 11:37:20 -07:00
bracesproul 7352ab14a2 cr 2024-10-15 11:36:37 -07:00
bracesproul 85a76912d3 fix(sdk-js): Pass api key in headers by default if in env 2024-10-15 11:33:40 -07:00
Nuno Campos f6fb2ef5ca langgraph 0.2.38 2024-10-15 11:04:22 -07:00
Vadym BardaandGitHub 2fb7e92879 docs: update recursion notebook to use RemainingSteps (#2114) 2024-10-15 12:05:46 -04:00
Nuno CamposandGitHub 46b2d08a8a Merge pull request #2115 from langchain-ai/nc/15oct/update-is-last-step
Return IsLastStep to previous definition
2024-10-15 08:41:30 -07:00
Nuno Campos 649b742e0a Update types for RemainingSteps, return IsLastStep to previous definition 2024-10-15 08:35:31 -07:00
Nuno CamposandGitHub fd4629e778 Merge pull request #2112 from langchain-ai/vb/fix-type
langgraph: fix type for RemainingSteps
2024-10-15 08:34:50 -07:00
vbarda d14f98f01b langgraph: fix type for RemainingSteps 2024-10-15 09:07:00 -04:00
Nuno Campos c0b56bf60d langgraph 0.2.37 2024-10-14 17:29:11 -07:00
Nuno CamposandGitHub e8b875906f Merge pull request #2105 from langchain-ai/nc/14oct/is-last-step-fix
Fix IsLastStep counter for runs with checkpointers
2024-10-14 17:21:31 -07:00
Nuno Campos d48faecd42 Fix 2024-10-14 17:16:32 -07:00
Nuno Campos 5e175e098b Update kafka 2024-10-14 17:10:10 -07:00
Nuno Campos bcf335651e Fix is_last_step 2024-10-14 17:05:16 -07:00
Nuno Campos 965849823a Fix 2024-10-14 17:03:53 -07:00
Nuno Campos 45e7101457 Backwards compat 2024-10-14 16:57:25 -07:00
Nuno Campos ecd75a8c4d Fix IsLastStep counter for runs with checkpointers
- Share step/stop logic with PregelLoop
- Add RemainingSteps value which contains the number of remaining steps
- Switch create_react_agent to use RemainingSteps, so that it behave correctly for return_direct tools
2024-10-14 16:54:16 -07:00
Nuno CamposandGitHub edec5c055e Merge pull request #2065 from langchain-ai/dqbd/debug-stream-checkpoint-map
fix(debug): send checkpoint_map as well
2024-10-14 15:50:39 -07:00
Nuno Campos ff310cc8d6 One more 2024-10-14 15:45:12 -07:00
Nuno Campos 233bd78ee4 Add checkpoint_map to parent_config 2024-10-14 15:44:18 -07:00
Nuno Campos b818bf2fba Fix up 2024-10-14 15:32:41 -07:00
Tat Dat DuongandNuno Campos c5ec568cfb Patch config before entering map_debug_checkpoint 2024-10-14 15:16:24 -07:00
Tat Dat DuongandNuno Campos 29548b2e27 fix(debug): add failing tests 2024-10-14 15:16:03 -07:00
Nuno Campos f2dc537696 langgraph 0.2.36 2024-10-14 12:28:43 -07:00
Nuno Campos 31d21c8d24 sdk-py 0.1.33 2024-10-14 12:28:22 -07:00
Nuno CamposandGitHub 4a03ed5915 Merge pull request #2091 from langchain-ai/nc/11oct/checkpoint-task-result
lib: Add result for each task in a checkpoint
2024-10-14 11:37:28 -07:00
Nuno Campos dc083c6563 Fix 2024-10-14 11:31:03 -07:00
Nuno Campos bfe005fef0 Lint 2024-10-14 10:30:59 -07:00
vbarda 5388b7c74f install dev sdk 2024-10-14 13:23:18 -04:00
vbarda 0d4617817d Merge branch 'nc/11oct/checkpoint-task-result' of github.com:langchain-ai/langgraph into nc/11oct/checkpoint-task-result 2024-10-14 13:20:25 -04:00
Nuno Campos 5046ec4f43 Lint 2024-10-14 10:16:14 -07:00
Nuno Campos c26bb9e156 lib: Add result for each task in a checkpoint
- Note this requires disabling the optimization that avoids saving writes for the last task in a step
2024-10-14 10:16:14 -07:00
Nuno CamposandGitHub 3982090c6d Merge pull request #2088 from langchain-ai/nc/11oct/stream-interrupt
lib: Add interrupts to stream_mode=updates
2024-10-14 10:15:53 -07:00
Nuno CamposandGitHub 6d3a2c59da Merge pull request #2102 from langchain-ai/vb/ci-update
ci: run core 0.2.x for a single python version
2024-10-14 10:15:38 -07:00
vbardaandNuno Campos 79444dee9c ci: run core 0.2.x for a single python version 2024-10-14 10:10:42 -07:00
Nuno CamposandGitHub 07f8f87780 Merge pull request #2103 from langchain-ai/nc/14oct/docker-ro-token
Add read-only token for pulling public images from dockerhub
2024-10-14 10:07:45 -07:00
Nuno Campos 99bde8774e Add read-only token for pulling public images from dockerhub 2024-10-14 09:56:24 -07:00
Nuno CamposandGitHub 5946f4ff2b Merge pull request #2100 from langchain-ai/vb/copy
langgraph: support copy without update in Pregel
2024-10-14 09:12:36 -07:00
vbarda b99734d157 langgraph: support copy without update in Pregel 2024-10-14 10:14:41 -04:00
Vadym BardaandGitHub d1c29fc8be docs: remove example with missing link (#2099) 2024-10-14 14:05:48 +00:00
Andrew Nguonly 19ccb0c6af Update astream_events() to process interrupt. 2024-10-11 19:06:52 -07:00
Andrew Nguonly a277b86fcb Fix unit test. 2024-10-11 18:53:45 -07:00
Andrew Nguonly 2f819a6a9b Update stream() and astream() to process 'updates' event types. 2024-10-11 18:40:40 -07:00
Nuno Campos dc47c7b357 lib: Add result for each task in a checkpoint
- Note this requires disabling the optimization that avoids saving writes for the last task in a step
2024-10-11 16:08:00 -07:00
Nuno Campos 561aa3080e Lint 2024-10-11 14:28:16 -07:00
Nuno Campos c6a450b857 lib: Add interrupts to stream_mode=updates 2024-10-11 14:28:16 -07:00
Nuno Campos 0557fb03a4 format 2024-10-11 14:28:08 -07:00
Nuno CamposandGitHub c9adf995c2 Merge pull request #2087 from langchain-ai/nc/11oct/o-flag
fix: Work w python's O flag
2024-10-11 12:03:21 -07:00
Nuno Campos fc20de5bba Fix 2024-10-11 11:39:19 -07:00
Nuno Campos 0822a287e3 fix: Work w python's O flag
- assert statements are skipped in that case, so we need to move calls to apply_writes to outside assert statements
2024-10-11 11:24:56 -07:00
Andrew NguonlyandGitHub 66741ba071 Rename RemotePregel to RemoteGraph (#2085) 2024-10-11 10:55:04 -07:00
Andrew NguonlyandGitHub e72c25873f Implement PregelProtocol and RemotePregel class (attempt 2) (#2078)
### Summary
Redo of [this PR](https://github.com/langchain-ai/langgraph/pull/2034)
(branched from clean branch).
2024-10-11 09:23:12 -07:00
Vadym BardaandGitHub 739336516d docs: remove empty cells for admonitions (#2082) 2024-10-11 13:36:24 +00:00
Nuno CamposandGitHub ae6c793bdf Merge pull request #2077 from langchain-ai/nc/10oct/313
Test w Python 3.13 in CI
2024-10-10 16:35:53 -07:00
Nuno Campos d8954963b4 Update snapshots 2024-10-10 16:27:43 -07:00
Nuno Campos ea38ba9e29 Update uvloop 2024-10-10 16:22:34 -07:00
Nuno Campos 76229ade66 Update psycopg 2024-10-10 16:17:19 -07:00
Nuno Campos 4aad36947e Upgrade pydantic 2024-10-10 16:13:05 -07:00
Nuno Campos cb7b667e6f Update psycopg 2024-10-10 16:09:24 -07:00
Nuno Campos 822ddb5f48 Test aux libs 2024-10-10 16:06:05 -07:00
Nuno Campos de355ee2d2 Update rpds-py 2024-10-10 16:05:43 -07:00
Nuno Campos 9ca270d62d Test w Python 3.13 in CI 2024-10-10 15:58:59 -07:00
David DuongandGitHub 28b5105913 Merge pull request #2070 from langchain-ai/dqbd/debug-self-referencing-checkpoint
fix(debug): self-referencing checkpoints when resuming streaming mid-thread
2024-10-10 12:44:45 +02:00
Tat Dat Duong be47752f0e Initialise to None 2024-10-10 11:15:54 +02:00
Isaac FranciscoandGitHub aa83f4a33e adding support for more notebooks in CI (#2060) 2024-10-10 01:48:13 +00:00
Tat Dat Duong 4d69331a52 Add async tests 2024-10-10 02:29:28 +02:00
Tat Dat Duong fb8c386958 fix(debug): address self-referencing 2024-10-10 02:21:32 +02:00
Tat Dat Duong ac8b51f1f2 fix(debug): add failing test for self-referencing 2024-10-10 02:21:17 +02:00
Vadym BardaandGitHub db0f508269 docs: add custom hooks for rendering jupyter notebooks (#2067) 2024-10-09 18:49:54 -04:00
Vadym BardaandGitHub fe110ae145 docs: fix intro in supervisor tutorial (#2068) 2024-10-09 20:59:49 +00:00
David DuongandGitHub fc276c5ac0 Merge pull request #2066 from langchain-ai/dqbd/checkpoint-sdk-js
fix(sdk-js): pass checkpoint when creating run
2024-10-09 20:50:54 +02:00
Tat Dat Duong 9360545659 Remove deprecated message 2024-10-09 20:41:18 +02:00
Tat Dat Duong 26e30ad6af Remove error warning 2024-10-09 20:40:24 +02:00
Tat Dat Duong 8df533b489 fix(sdk-js): allow passing checkpoint when creating a run 2024-10-09 20:34:19 +02:00
Vadym BardaandGitHub f9df0f4700 docs: update many tools how-to chart (#2059) 2024-10-09 13:46:59 +00:00
David DuongandGitHub 5d0afa3888 Merge pull request #2048 from langchain-ai/dqbd/debug-tasks-state
feat(debug): send tasks info
2024-10-09 14:38:26 +02:00
Tat Dat Duong a53a566730 Bump to 0.2.35 2024-10-09 14:33:14 +02:00
Andrew NguonlyandTat Dat Duong d2c359f7c9 docs: Update LangGraph API docs (#2056)
### Summary
Adding endpoints for `/subgraphs` and `/store`.
2024-10-09 14:33:14 +02:00
Andrew NguonlyandTat Dat Duong c4d251b05c sdk-py: Add Sequence[dict] type to values param type for update_state() (#2054)
### Summary
The LangGraph API supports a list of `dict` for the `values` field for
the `POST /threads/<thread_id>/state` endpoint.

Reference:
https://github.com/langchain-ai/langgraph-api/blob/main/api/openapi.json#L3005-L3021
2024-10-09 14:33:14 +02:00
Andrew NguonlyandTat Dat Duong 9a752e1563 sdk-py: Add "*" literal to interrupt_before and interrupt_after types (#2053)
### Summary
The LangGraph API supports the literal string `"*"` for
`interrupt_before` and `interrupt_after`.

Reference:
https://github.com/langchain-ai/langgraph-api/blob/main/api/openapi.json#L2425
2024-10-09 14:33:14 +02:00
Andrew NguonlyandTat Dat Duong 6d4a426059 sdk-py: Add custom stream mode to StreamMode type (#2051)
### Summary
The LangGraph API supports `custom` stream mode type.

Reference:
https://github.com/langchain-ai/langgraph/blob/main/docs/docs/cloud/reference/api/openapi.json#L2403
2024-10-09 14:33:14 +02:00
Andrew NguonlyandTat Dat Duong 598bb5a641 sdk-py: Update return type annotation for Thread.update_state() methods. (#2050)
### Summary
The response body of the endpoint `POST /threads/{thread_id}/state`
looks like this:
```
{
    "checkpoint": {
        "thread_id": "e2496803-ecd5-4e0c-a779-3226296181c2",
        "checkpoint_ns": "",
        "checkpoint_id": "1ef4a9b8-e6fb-67b1-8001-abd5184439d1",
        "checkpoint_map": {}
    }
}
```
2024-10-09 14:33:14 +02:00
Andrew NguonlyandGitHub 28ff7fd7ba docs: Update LangGraph API docs (#2056)
### Summary
Adding endpoints for `/subgraphs` and `/store`.
2024-10-08 16:44:01 -07:00
Tat Dat Duong 0628c6402f Fix typo 2024-10-09 01:00:36 +02:00
Tat Dat Duong db61d294a6 Code review 2024-10-09 01:00:06 +02:00
Andrew NguonlyandGitHub 7883ceae64 sdk-py: Add Sequence[dict] type to values param type for update_state() (#2054)
### Summary
The LangGraph API supports a list of `dict` for the `values` field for
the `POST /threads/<thread_id>/state` endpoint.

Reference:
https://github.com/langchain-ai/langgraph-api/blob/main/api/openapi.json#L3005-L3021
2024-10-08 13:49:27 -07:00
Andrew NguonlyandGitHub 6698e25a04 sdk-py: Add "*" literal to interrupt_before and interrupt_after types (#2053)
### Summary
The LangGraph API supports the literal string `"*"` for
`interrupt_before` and `interrupt_after`.

Reference:
https://github.com/langchain-ai/langgraph-api/blob/main/api/openapi.json#L2425
2024-10-08 13:29:11 -07:00
Andrew NguonlyandGitHub fd1a9e4da3 sdk-py: Add custom stream mode to StreamMode type (#2051)
### Summary
The LangGraph API supports `custom` stream mode type.

Reference:
https://github.com/langchain-ai/langgraph/blob/main/docs/docs/cloud/reference/api/openapi.json#L2403
2024-10-08 12:44:37 -07:00
Andrew NguonlyandGitHub 82c316b3f7 sdk-py: Update return type annotation for Thread.update_state() methods. (#2050)
### Summary
The response body of the endpoint `POST /threads/{thread_id}/state`
looks like this:
```
{
    "checkpoint": {
        "thread_id": "e2496803-ecd5-4e0c-a779-3226296181c2",
        "checkpoint_ns": "",
        "checkpoint_id": "1ef4a9b8-e6fb-67b1-8001-abd5184439d1",
        "checkpoint_map": {}
    }
}
```
2024-10-08 12:04:26 -07:00
Tat Dat Duong 7a282f82dc Tests? 2024-10-08 20:55:49 +02:00
Tat Dat Duong 45a12c938b Add more nested tests for nested subgraphs 2024-10-08 20:49:16 +02:00
Tat Dat Duong b51f5d6345 Fix optional types 2024-10-08 20:09:51 +02:00
Tat Dat Duong f9e900f39a Fix 3.9 2024-10-08 19:58:42 +02:00
Tat Dat Duong e564902753 Add async tests 2024-10-08 19:57:39 +02:00
Tat Dat Duong e3bee7d843 Add tests 2024-10-08 19:52:05 +02:00
Tat Dat Duong 4f61dd1aa6 Fix tests 2024-10-08 19:18:52 +02:00
Tat Dat Duong 7e9cf02922 Use casting instead 2024-10-08 17:08:08 +02:00
Tat Dat Duong 50b1a1e230 Cleanup, move instanceof checks to an util 2024-10-08 17:01:40 +02:00
Tat Dat Duong c1081af6bc Fix lint 2024-10-08 16:41:48 +02:00
Tat Dat Duong dfb265f296 feat(debug): send tasks info 2024-10-08 16:21:38 +02:00
William FHandGitHub 254b12a62d Use AsyncBatch for postgres store (#2020) 2024-10-08 06:58:26 +00:00
7c2a89dbc8 docs memory concept: Suggestion batch 1 (#2040)
Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2024-10-08 02:55:51 +00:00
Eugene YurtsevandGitHub 34b23fce06 docs: batch 2 Update memory.md (#2041) 2024-10-07 19:53:50 -07:00
Vadym BardaandGitHub 4633364e8e docs: small edits to memory concepts (#2039) 2024-10-07 18:31:48 -07:00
William FHandGitHub 23c1957812 Update glossary (#2038) 2024-10-08 01:03:11 +00:00
William FHandGitHub 90b8b4d745 Fixup Grammar (#2037) 2024-10-07 16:56:13 -07:00
William FHandGitHub 45957cc72a Docs Nits Pass 2 (#2036) 2024-10-07 16:48:22 -07:00
d5da547850 Shared state conceptual docs (#1958)
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2024-10-07 23:16:34 +00:00
Riya SinhaandGitHub 61798d09d2 checkpoint: set CheckpointNS ConfigurableFieldSpec model default to empty string (#2019) 2024-10-07 18:38:18 +00:00
Nuno CamposandGitHub 4685dc103a Merge pull request #2032 from langchain-ai/nc/7oct/kafka-loop-arg
scheduler-kafka: Pass loop arg to default async consumer and producer
2024-10-07 10:22:31 -07:00
Nuno Campos e5b4cd2701 scheduler-kafka: Pass loop arg to default async consumer and producer
- Some forks of aiokafka make this a required arg
2024-10-07 10:16:36 -07:00
David DuongandGitHub debfd85ff8 Merge pull request #2031 from langchain-ai/dqbd/js-0.0.16
feat(sdk-js): bump to 0.0.16
2024-10-07 18:15:46 +02:00
Tat Dat Duong 24f21a0ad8 feat(sdk-js): bump to 0.0.16 2024-10-07 18:10:32 +02:00
David DuongandGitHub b5138cd8f9 Merge pull request #2029 from langchain-ai/dqbd/js-get-history-checkpoint
feat(sdk-js): add `checkpoint` arg in `getHistory`
2024-10-07 17:52:27 +02:00
Tat Dat Duong 05f645b87c Make types more explicit 2024-10-07 17:47:36 +02:00
Tat Dat Duong 9ff5715961 feat(sdk-js): add checkpoint arg in getHistory 2024-10-07 17:24:29 +02:00
William FHandGitHub b42a31fdae Rm dup END (#2022) 2024-10-06 21:24:11 -07:00
William FHandGitHub 57727be9db Checkpoint 2.0.1 (#2018) 2024-10-06 14:10:48 -07:00
William FHandGitHub 05dbc1d498 Validate in async batched store (#2017) 2024-10-06 14:09:35 -07:00
b35fe5864d docs: update how-to for passing runtime values (#1984)
Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2024-10-05 01:23:55 +00:00
Andrew NguonlyandGitHub db3271ace5 docs: Update field descriptions for API spec (#2013) 2024-10-04 22:32:20 +00:00
bacf92c441 langgraph: add support for passing store via state_modifier (#1992)
Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2024-10-04 15:28:56 -07:00
Andrew NguonlyandGitHub c847f7df4e docs: Updates to API spec (#2012) 2024-10-04 22:12:13 +00:00
Vadym BardaandGitHub c2dc498b1c docs: clean up memory docs (#2000) 2024-10-04 16:58:22 -04:00
Andrew NguonlyandGitHub c2171f4a20 docs: Create API spec (#2009) 2024-10-04 20:40:01 +00:00
William FHandGitHub d8d4714a73 Update JS sdk version (#2008) 2024-10-04 11:04:10 -07:00
William FHandGitHub 018e9ac42e Check is string in store namespace validation (on put) (#2007) 2024-10-04 17:55:30 +00:00
Brace SproulandGitHub f9afd3c215 Merge pull request #1993 from langchain-ai/brace/after-seconds-js
fix(js): Add afterSeconds run arg
2024-10-03 11:18:02 -07:00
Eugene YurtsevandGitHub ac7903b3dc docs: how to guide batch 4 (#1991)
Updated the following guides:

docs/docs/how-tos/streaming-content.ipynb

docs/docs/how-tos/streaming-events-from-within-tools-without-langchain.ipynb
docs/docs/how-tos/streaming-events-from-within-tools.ipynb
docs/docs/how-tos/streaming-tokens-without-langchain.ipynb
2024-10-03 14:11:53 -04:00
Eugene YurtsevandGitHub 4a8510b690 docs: minor formatting change for how to docs 2024-10-03 13:47:59 -04:00
bracesproul 92e75aac17 cr 2024-10-03 09:40:37 -07:00
bracesproul 3e8be7fd79 fix(js): Add afterSeconds run arg 2024-10-03 09:40:10 -07:00
Vadym BardaandGitHub 99fd0eedbd docs: clean up and standardize more how-tos (#1959) 2024-10-03 13:40:34 +00:00
f55586ea23 [Docs] Drop memory doc (#1986)
---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-10-03 03:05:49 +00:00
Vadym BardaandGitHub 055b2ae74f ci: filter to added/modified for notebooks (#1987) 2024-10-03 02:27:57 +00:00
Isaac FranciscoandGitHub c39e08ec8e export checkpoint type from js-sdk (#1973) 2024-10-02 18:47:34 -07:00
William FHandGitHub c74aba8cc5 [Docs] Storage ref docs (#1985) 2024-10-02 16:53:39 -07:00
Eugene YurtsevandGitHub d683630094 docs: how-to fix some issues (#1983)
Fixes some issues introduced while updating how-to docs
2024-10-02 22:06:03 +00:00
Vadym BardaandGitHub 86edf631e3 langgraph: release 0.2.34 (#1982) 2024-10-02 17:42:14 -04:00
Vadym BardaandGitHub 93c22fbdde langgraph: add store to the prebuilt agent (#1981) 2024-10-02 21:38:15 +00:00
Eugene YurtsevandGitHub 7f95d7de42 docs: how to guide batch 2 (#1956)
Updates the following how to guides

docs/docs/how-tos/disable-streaming.ipynb
docs/docs/how-tos/input_output_schema.ipynb
docs/docs/how-tos/many-tools.ipynb
docs/docs/how-tos/map-reduce.ipynb
docs/docs/how-tos/node-retries.ipynb
docs/docs/how-tos/pass-config-to-tools.ipynb
docs/docs/how-tos/pass_private_state.ipynb
2024-10-02 17:29:21 -04:00
Eugene YurtsevandGitHub 1a4f375226 docs: how-to guides batch 3 (#1979)
Updates the following how to guides:

docs/docs/how-tos/persistence.ipynb
docs/docs/how-tos/persistence_mongodb.ipynb
docs/docs/how-tos/persistence_postgres.ipynb
docs/docs/how-tos/persistence_redis.ipynb
docs/docs/how-tos/react-agent-from-scratch.ipynb
docs/docs/how-tos/react-agent-structured-output.ipynb
docs/docs/how-tos/recursion-limit.ipynb
docs/docs/how-tos/return-when-recursion-limit-hits.ipynb
docs/docs/how-tos/run-id-langsmith.ipynb
docs/docs/how-tos/state-model.ipynb
2024-10-02 17:29:01 -04:00
William FHandGitHub 6c0da426c6 [PostGres Checkpointer] Run CI on PG15 as well (#1953) 2024-10-02 19:16:58 +00:00
William FHandGitHub 7ede237508 [Docs] Add SDK ref docs for the Store client (#1974) 2024-10-02 19:16:36 +00:00
Jacob LeeandGitHub fb382c20f7 fix: Fix for drawing subgraphs with multiple sinks (#1962)
* Fix for drawing subgraphs with multiple sinks

* Expand error message
2024-10-02 12:03:30 -07:00
Vadym BardaandGitHub 9821638965 docs: add InjectedStore to reference (#1976) 2024-10-02 18:54:25 +00:00
Vadym BardaandGitHub e48d9d3c38 docs: add a note for shared memory to persistence how-to (#1975) 2024-10-02 18:41:23 +00:00
Vadym BardaandGitHub 7ecc672e61 langgraph: release 0.2.33 (#1972) 2024-10-02 13:43:17 -04:00
Vadym BardaandGitHub 7efd3c726e langgraph: add support for store in ToolNode (#1968) 2024-10-02 17:39:25 +00:00
Eugene YurtsevandGitHub 74b36adb18 docs: update how-to guides batch 1 (#1918)
Add links to the following how-to guides:

docs/docs/how-tos/async.ipynb
docs/docs/how-tos/branching.ipynb
docs/docs/how-tos/configuration.ipynb
docs/docs/how-tos/create-react-agent-hitl.ipynb
docs/docs/how-tos/create-react-agent-memory.ipynb
docs/docs/how-tos/create-react-agent-system-prompt.ipynb
docs/docs/how-tos/create-react-agent.ipynb

Identified two missing concepts:
1) RunnableConfig in LangChain
2) Unclear where ReAct should link in langgraph
2024-10-02 15:09:11 +00:00
Eugene YurtsevandGitHub 2f7da90a38 docs: check for format violations with ruff (#1967) 2024-10-02 14:40:33 +00:00
William FHandGitHub a3cb9c1a94 Validate no empty namespace is added (#1961)
Also check the root label isn't "langgraph"
2024-10-01 18:43:45 -07:00
Vadym BardaandGitHub e0fd95b22a docs: update tutorial for long-term memory (#1955) 2024-10-01 17:56:43 -07:00
William FHandGitHub db87642a10 Revert "Validate not empty (#1957)" (#1960)
This reverts commit cf67acb699.
2024-10-01 17:44:08 -07:00
William FHandGitHub cf67acb699 Validate not empty (#1957) 2024-10-01 17:23:44 -07:00
Lance MartinandGitHub 36be928791 Fix link (#1954) 2024-10-01 20:47:30 +00:00
Brace SproulandGitHub 702b5949d9 fix(sdk-js): Release 0.0.14 2024-10-01 13:18:02 -07:00
Brace SproulandGitHub 267485f3e6 Merge branch 'main' into rc 2024-10-01 13:13:01 -07:00
bracesproul 79cded748d fix(sdk-js): Release 0.0.14 2024-10-01 12:45:57 -07:00
Brace SproulandGitHub c08dd2f71c Merge pull request #1949 from langchain-ai/brace/update-rc
fix: Update rc branch
2024-10-01 12:44:02 -07:00
bracesproul 7dbb5ce98f Merge branch 'main' of https://github.com/langchain-ai/langgraph into rc 2024-10-01 12:37:22 -07:00
Brace SproulandGitHub 813aadeb47 Merge pull request #1947 from langchain-ai/brace/fix-null-obj-err
fix(sdk-js): Fix null item error
2024-10-01 12:36:57 -07:00
bracesproul 38a3e11c9f cr 2024-10-01 11:32:07 -07:00
bracesproul 8486c9d413 fix(sdk-js): Fix null item error 2024-10-01 11:31:29 -07:00
Brace SproulandGitHub db4191b89e Merge pull request #1943 from langchain-ai/release
Release 0.0.14-rc.0
2024-10-01 10:48:36 -07:00
bracesproul 45bf27bafe Release 0.0.14-rc.0 2024-10-01 10:45:49 -07:00
409 changed files with 44599 additions and 13240 deletions
+115
View File
@@ -0,0 +1,115 @@
import asyncio
import json
import os
import pathlib
import sys
import langgraph_cli
import langgraph_cli.docker
import langgraph_cli.config
from langgraph_cli.exec import Runner, subp_exec
from langgraph_cli.progress import Progress
from langgraph_cli.constants import DEFAULT_PORT
def test(
config: pathlib.Path,
port: int,
tag: str,
verbose: bool,
):
with Runner() as runner, Progress(message="Pulling...") as set:
# check docker available
capabilities = langgraph_cli.docker.check_capabilities(runner)
# open config
config_json = langgraph_cli.config.validate_config_file(config)
set("Running...")
args = [
"run",
"--rm",
"-p",
f"{port}:8000",
]
if isinstance(config_json["env"], str):
args.extend(
[
"--env-file",
str(config.parent / config_json["env"]),
]
)
else:
for k, v in config_json["env"].items():
args.extend(
[
"-e",
f"{k}={v}",
]
)
if capabilities.healthcheck_start_interval:
args.extend(
[
"--health-interval",
"5s",
"--health-retries",
"1",
"--health-start-period",
"10s",
"--health-start-interval",
"1s",
]
)
else:
args.extend(
[
"--health-interval",
"5s",
"--health-retries",
"2",
]
)
_task = None
def on_stdout(line: str):
nonlocal _task
if "GET /ok" in line or "Uvicorn running on" in line:
set("")
sys.stdout.write(
f"""Ready!
- API: http://localhost:{port}
"""
)
sys.stdout.flush()
_task.cancel()
return True
return False
async def subp_exec_task(*args, **kwargs):
nonlocal _task
_task = asyncio.create_task(subp_exec(*args, **kwargs))
await _task
try:
runner.run(
subp_exec_task(
"docker",
*args,
tag,
verbose=verbose,
on_stdout=on_stdout,
)
)
except asyncio.CancelledError:
pass
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--tag", type=str)
parser.add_argument("-c", "--config", type=str, default="./langgraph.json")
parser.add_argument("-p", "--port", default=DEFAULT_PORT)
args = parser.parse_args()
test(pathlib.Path(args.config), args.port, args.tag, verbose=True)
+22 -8
View File
@@ -39,22 +39,36 @@ jobs:
- name: Install cli globally
if: steps.changed-files.outputs.all
run: pip install -e .
- name: Start service A
- name: Build and test service A
if: steps.changed-files.outputs.all
working-directory: libs/cli/examples
run: |
timeout 60 langgraph test -c examples/langgraph.json --verbose || (exit "$(($? == 124 ? 0 : $?))")
- name: Start service B
# The build-arg isn't used; just testing that we accept other args
langgraph build -t langgraph-test-a --base-image "langchain/langgraph-trial"
cp .env.example .envg
timeout 60 python ../../../.github/scripts/run_langgraph_cli_test.py -c langgraph.json -t langgraph-test-a
- name: Build and test service B
if: steps.changed-files.outputs.all
working-directory: libs/cli/examples/graphs
run: |
timeout 60 langgraph test --verbose || (exit "$(($? == 124 ? 0 : $?))")
- name: Start service C
langgraph build -t langgraph-test-b --base-image "langchain/langgraph-trial"
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-b
- name: Build and test service C
if: steps.changed-files.outputs.all
working-directory: libs/cli/examples/graphs_reqs_a
run: |
timeout 60 langgraph test --verbose || (exit "$(($? == 124 ? 0 : $?))")
- name: Start service D
langgraph build -t langgraph-test-c --base-image "langchain/langgraph-trial"
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-c
- name: Build and test service D
if: steps.changed-files.outputs.all
working-directory: libs/cli/examples/graphs_reqs_b
run: |
timeout 60 langgraph test --verbose || (exit "$(($? == 124 ? 0 : $?))")
langgraph build -t langgraph-test-d --base-image "langchain/langgraph-trial"
timeout 60 python ../../../../.github/scripts/run_langgraph_cli_test.py -t langgraph-test-d
- name: Build JS service
if: steps.changed-files.outputs.all
working-directory: libs/cli/js-examples
run: |
langgraph build -t langgraph-test-e
+7
View File
@@ -21,6 +21,7 @@ jobs:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
name: "test #${{ matrix.python-version }}"
steps:
@@ -32,6 +33,12 @@ jobs:
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: test-${{ inputs.working-directory }}
- name: Login to Docker Hub
uses: docker/login-action@v3
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_RO_TOKEN }}
- name: Install dependencies
shell: bash
+18 -2
View File
@@ -16,14 +16,22 @@ jobs:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
core-version:
- ">=0.2.39,<0.3.0"
- "latest"
ff-send-v2:
- "false"
include:
- python-version: "3.11"
core-version: ">=0.2.42,<0.3.0"
- python-version: "3.11"
core-version: "latest"
ff-send-v2: "true"
defaults:
run:
working-directory: libs/langgraph
name: "test #${{ matrix.python-version }} (langchain-core: ${{ matrix.core-version }})"
name: "test #${{ matrix.python-version }} (langchain-core: ${{ matrix.core-version }}, ff-send-v2: ${{ matrix.ff-send-v2 }})"
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
@@ -32,6 +40,12 @@ jobs:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
cache-key: test-langgraph
- name: Login to Docker Hub
uses: docker/login-action@v3
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_RO_TOKEN }}
- name: Install dependencies
shell: bash
@@ -43,6 +57,8 @@ jobs:
- name: Run tests
shell: bash
env:
LANGGRAPH_FF_SEND_V2: ${{ matrix.ff-send-v2 }}
run: |
make test
+2
View File
@@ -93,3 +93,5 @@ jobs:
# This is *only for CI use* and is *extremely dangerous* otherwise!
# https://github.com/pypa/gh-action-pypi-publish#tolerating-release-package-file-duplicates
skip-existing: true
# Temp workaround since attestations are on by default as of gh-action-pypi-publish v1.11.0
attestations: false
@@ -27,6 +27,12 @@ jobs:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
cache-key: test-scheduler-kafka
- name: Login to Docker Hub
uses: docker/login-action@v3
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_RO_TOKEN }}
- name: Install dependencies
shell: bash
+2
View File
@@ -31,6 +31,7 @@ jobs:
"libs/cli",
"libs/checkpoint",
"libs/checkpoint-sqlite",
"libs/checkpoint-duckdb",
"libs/checkpoint-postgres",
"libs/scheduler-kafka",
]
@@ -47,6 +48,7 @@ jobs:
"libs/cli",
"libs/checkpoint",
"libs/checkpoint-sqlite",
"libs/checkpoint-duckdb",
"libs/checkpoint-postgres"
]
uses: ./.github/workflows/_test.yml
+18 -4
View File
@@ -25,7 +25,7 @@ jobs:
get-changed-files:
runs-on: ubuntu-latest
outputs:
changed-files: ${{ steps.changed-files.outputs.all }}
changed-files: ${{ steps.changed-files.outputs.added_modified }}
steps:
- uses: actions/checkout@v4
- name: Get changed files
@@ -44,6 +44,8 @@ jobs:
deploy:
# needs: run-changed-notebooks
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.MKDOCS_GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
@@ -58,8 +60,14 @@ jobs:
- name: Install dependencies
run: |
poetry install --with docs
poetry run pip install -U pytest pytest-check-links langsmith langchain GitPython
poetry install --with test --no-root
poetry run pip install -U \
pytest \
pytest-check-links \
langsmith \
langchain \
GitPython \
"git+https://${GITHUB_TOKEN}@github.com/langchain-ai/mkdocs-material-insiders.git"
- name: Lint Docs
# This step lints the docs using the existing linting set up.
@@ -80,8 +88,13 @@ jobs:
--check-links-ignore "https://(api|web|docs)\.smith\.langchain\.com/.*" \
--check-links-ignore "https://x.com/.*" \
--check-links-ignore "https://github\.com/.*" \
--check-links-ignore "http://localhost:8123/.*" \
--check-links-ignore "/.*\.(ipynb|html)$" \
--check-links $(find docs/site -name "index.html" | grep -v 'storm/index.html')
--check-links-ignore "https://python\.langchain\.com/.*" \
--check-links-ignore "https://openai\.com/.*" \
--check-links-ignore "https://pepy\.tech/.*" \
--check-links $(find docs/site -name "index.html" | grep -v 'storm/index.html')
else
echo "Fetching changes from origin/main..."
git fetch origin main
@@ -92,6 +105,7 @@ jobs:
echo "Running link check on HTML files matching changed notebook files..."
poetry run pytest -v \
--check-links-ignore "https://(api|web|docs)\.smith\.langchain\.com/.*" \
--check-links-ignore "http://localhost:8123/.*" \
--check-links-ignore "https://x.com/.*" \
--check-links-ignore "https://github\.com/.*" \
--check-links-ignore "/.*\.(ipynb|html)$" \
+2
View File
@@ -270,6 +270,8 @@ jobs:
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
print-hash: true
# Temp workaround since attestations are on by default as of gh-action-pypi-publish v1.11.0
attestations: false
mark-release:
needs:
+1
View File
@@ -26,6 +26,7 @@ format-docs:
# Check the docs for linting violations
lint-docs:
poetry run ruff format --check docs/docs
poetry run ruff check docs/docs
codespell:
+13 -1
View File
@@ -16,6 +16,8 @@
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 Platform](https://langchain-ai.github.io/langgraph/concepts/langgraph_platform) is infrastructure for deploying LangGraph agents. It is a commercial solution for deploying agentic applications to production, built on the open-source LangGraph framework. The LangGraph Platform consists of several components that work together to support the development, deployment, debugging, and monitoring of LangGraph applications: [LangGraph Server](https://langchain-ai.github.io/langgraph/concepts/langgraph_server) (APIs), [LangGraph SDKs](https://langchain-ai.github.io/langgraph/concepts/sdk) (clients for the APIs), [LangGraph CLI](https://langchain-ai.github.io/langgraph/concepts/langgraph_cli) (command line tool for building the server), [LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio) (UI/debugger),
To learn more about LangGraph, check out our first LangChain Academy course, *Introduction to LangGraph*, available for free [here](https://academy.langchain.com/courses/intro-to-langgraph).
### Key Features
@@ -26,6 +28,16 @@ To learn more about LangGraph, check out our first LangChain Academy course, *In
- **Streaming Support**: Stream outputs as they are produced by each node (including token streaming).
- **Integration with LangChain**: LangGraph integrates seamlessly with [LangChain](https://github.com/langchain-ai/langchain/) and [LangSmith](https://docs.smith.langchain.com/) (but does not require them).
### LangGraph Platform
LangGraph Platform is a commercial solution for deploying agentic applications to production, built on the open-source LangGraph framework.
Here are some common issues that arise in complex deployments, which LangGraph Platform addresses:
- **Streaming support**: LangGraph Server provides [multiple streaming modes](https://langchain-ai.github.io/langgraph/concepts/streaming) optimized for various application needs
- **Background runs**: Runs agents asynchronously in the background
- **Support for long running agents**: Infrastructure that can handle long running processes
- **[Double texting](https://langchain-ai.github.io/langgraph/concepts/double_texting)**: Handle the case where you get two messages from the user before the agent can respond
- **Handle burstiness**: Task queue for ensuring requests are handled consistently without loss, even under heavy loads
## Installation
@@ -226,7 +238,7 @@ final_state["messages"][-1].content
* [How-to Guides](https://langchain-ai.github.io/langgraph/how-tos/): Accomplish specific things within LangGraph, from streaming, to adding memory & persistence, to common design patterns (branching, subgraphs, etc.), these are the place to go if you want to copy and run a specific code snippet.
* [Conceptual Guides](https://langchain-ai.github.io/langgraph/concepts/high_level/): In-depth explanations of the key concepts and principles behind LangGraph, such as nodes, edges, state and more.
* [API Reference](https://langchain-ai.github.io/langgraph/reference/graphs/): Review important classes and methods, simple examples of how to use the graph and checkpointing APIs, higher-level prebuilt components and more.
* [Cloud (beta)](https://langchain-ai.github.io/langgraph/cloud/): With one click, deploy LangGraph applications to LangGraph Cloud.
* [LangGraph Platform](https://langchain-ai.github.io/langgraph/concepts/#langgraph-platform): LangGraph Platform is a commercial solution for deploying agentic applications in production, built on the open-source LangGraph framework.
## Contributing
+1 -1
View File
@@ -24,7 +24,7 @@ export -f execute_notebook
# Check if custom notebook paths are provided
if [ $# -gt 0 ]; then
notebooks="$@"
notebooks=$(echo "$@" | tr ' ' '\n' | grep -vFf <(echo "$SKIP_NOTEBOOKS"))
else
# Find all notebooks and filter out those in the skip list
notebooks=$(find docs/docs/tutorials docs/docs/how-tos -name "*.ipynb" | grep -v ".ipynb_checkpoints" | grep -vFf <(echo "$SKIP_NOTEBOOKS"))
@@ -0,0 +1,246 @@
import importlib
import inspect
import logging
import os
import re
from typing import List, Literal, Optional
from typing_extensions import TypedDict
import nbformat
from nbconvert.preprocessors import Preprocessor
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Base URL for all class documentation
_LANGCHAIN_API_REFERENCE = "https://python.langchain.com/api_reference/"
_LANGGRAPH_API_REFERENCE = "https://langchain-ai.github.io/langgraph/reference/"
# (alias/re-exported modules, source module, class, docs namespace)
MANUAL_API_REFERENCES_LANGGRAPH = [
(
["langgraph.prebuilt"],
"langgraph.prebuilt.chat_agent_executor",
"create_react_agent",
"prebuilt",
),
(["langgraph.prebuilt"], "langgraph.prebuilt.tool_node", "ToolNode", "prebuilt"),
(
["langgraph.prebuilt"],
"langgraph.prebuilt.tool_node",
"tools_condition",
"prebuilt",
),
(
["langgraph.prebuilt"],
"langgraph.prebuilt.tool_node",
"InjectedState",
"prebuilt",
),
# Graph
(["langgraph.graph"], "langgraph.graph.message", "add_messages", "graphs"),
(["langgraph.graph"], "langgraph.graph.state", "StateGraph", "graphs"),
(["langgraph.graph"], "langgraph.graph.state", "CompiledStateGraph", "graphs"),
([], "langgraph.types", "StreamMode", "types"),
(["langgraph.graph"], "langgraph.constants", "START", "constants"),
(["langgraph.graph"], "langgraph.constants", "END", "constants"),
(["langgraph.constants"], "langgraph.types", "Send", "types"),
(["langgraph.constants"], "langgraph.types", "Interrupt", "types"),
([], "langgraph.types", "RetryPolicy", "types"),
([], "langgraph.checkpoint.base", "Checkpoint", "checkpoints"),
([], "langgraph.checkpoint.base", "CheckpointMetadata", "checkpoints"),
([], "langgraph.checkpoint.base", "BaseCheckpointSaver", "checkpoints"),
([], "langgraph.checkpoint.base", "SerializerProtocol", "checkpoints"),
([], "langgraph.checkpoint.serde.jsonplus", "JsonPlusSerializer", "checkpoints"),
([], "langgraph.checkpoint.memory", "MemorySaver", "checkpoints"),
([], "langgraph.checkpoint.sqlite.aio", "AsyncSqliteSaver", "checkpoints"),
([], "langgraph.checkpoint.sqlite", "SqliteSaver", "checkpoints"),
([], "langgraph.checkpoint.postgres.aio", "AsyncPostgresSaver", "checkpoints"),
([], "langgraph.checkpoint.postgres", "PostgresSaver", "checkpoints"),
]
WELL_KNOWN_LANGGRAPH_OBJECTS = {
(module_, class_): (source_module, namespace)
for (modules, source_module, class_, namespace) in MANUAL_API_REFERENCES_LANGGRAPH
for module_ in modules + [source_module]
}
def _make_regular_expression(pkg_prefix: str) -> re.Pattern:
if not pkg_prefix.isidentifier():
raise ValueError(f"Invalid package prefix: {pkg_prefix}")
return re.compile(
r"from\s+(" + pkg_prefix + "(?:_\w+)?(?:\.\w+)*?)\s+import\s+"
r"((?:\w+(?:,\s*)?)*" # Match zero or more words separated by a comma+optional ws
r"(?:\s*\(.*?\))?)", # Match optional parentheses block
re.DOTALL, # Match newlines as well
)
# Regular expression to match langchain import lines
_IMPORT_LANGCHAIN_RE = _make_regular_expression("langchain")
_IMPORT_LANGGRAPH_RE = _make_regular_expression("langgraph")
def _get_full_module_name(module_path, class_name) -> Optional[str]:
"""Get full module name using inspect"""
try:
module = importlib.import_module(module_path)
class_ = getattr(module, class_name)
module = inspect.getmodule(class_)
if module is None:
# For constants, inspect.getmodule() might return None
# In this case, we'll return the original module_path
return module_path
return module.__name__
except AttributeError as e:
logger.warning(f"Could not find module for {class_name}, {e}")
return None
except ImportError as e:
logger.warning(f"Failed to load for class {class_name}, {e}")
return None
def _get_doc_title(data: str, file_name: str) -> str:
try:
return re.findall(r"^#\s*(.*)", data, re.MULTILINE)[0]
except IndexError:
pass
# Parse the rst-style titles
try:
return re.findall(r"^(.*)\n=+\n", data, re.MULTILINE)[0]
except IndexError:
return file_name
class ImportInformation(TypedDict):
imported: str # imported class name
source: str # module path
docs: str # URL to the documentation
title: str # Title of the document
def _get_imports(
code: str, doc_title: str, package_ecosystem: Literal["langchain", "langgraph"]
) -> List[ImportInformation]:
"""Get imports from the given code block.
Args:
code: Python code block from which to extract imports
doc_title: Title of the document
package_ecosystem: "langchain" or "langgraph". The two live in different
repositories and have separate documentation sites.
Returns:
List of import information for the given code block
"""
imports = []
if package_ecosystem == "langchain":
pattern = _IMPORT_LANGCHAIN_RE
elif package_ecosystem == "langgraph":
pattern = _IMPORT_LANGGRAPH_RE
else:
raise ValueError(f"Invalid package ecosystem: {package_ecosystem}")
for import_match in pattern.finditer(code):
module = import_match.group(1)
if "pydantic_v1" in module:
continue
imports_str = (
import_match.group(2).replace("(\n", "").replace("\n)", "")
) # Handle newlines within parentheses
# remove any newline and spaces, then split by comma
imported_classes = [
imp.strip()
for imp in re.split(r",\s*", imports_str.replace("\n", ""))
if imp.strip()
]
for class_name in imported_classes:
module_path = _get_full_module_name(module, class_name)
if not module_path:
continue
if len(module_path.split(".")) < 2:
continue
if package_ecosystem == "langchain":
pkg = module_path.split(".")[0].replace("langchain_", "")
top_level_mod = module_path.split(".")[1]
url = (
_LANGCHAIN_API_REFERENCE
+ pkg
+ "/"
+ top_level_mod
+ "/"
+ module_path
+ "."
+ class_name
+ ".html"
)
elif package_ecosystem == "langgraph":
if (module, class_name) not in WELL_KNOWN_LANGGRAPH_OBJECTS:
# Likely not documented yet
continue
source_module, namespace = WELL_KNOWN_LANGGRAPH_OBJECTS[
(module, class_name)
]
url = (
_LANGGRAPH_API_REFERENCE
+ namespace
+ "/#"
+ source_module
+ "."
+ class_name
)
else:
raise ValueError(f"Invalid package ecosystem: {package_ecosystem}")
# Add the import information to our list
imports.append(
{
"imported": class_name,
"source": module,
"docs": url,
"title": doc_title,
}
)
return imports
class ImportPreprocessor(Preprocessor):
"""A preprocessor to replace imports in each Python code cell with links to their
documentation and append the import info in a comment."""
def preprocess(self, nb, resources):
self.all_imports = []
file_name = os.path.basename(resources.get("metadata", {}).get("name", ""))
_DOC_TITLE = _get_doc_title(nb.cells[0].source, file_name)
cells = []
for cell in nb.cells:
if cell.cell_type == "code":
cells.append(cell)
imports = _get_imports(
cell.source, _DOC_TITLE, "langchain"
) + _get_imports(cell.source, _DOC_TITLE, "langgraph")
if not imports:
continue
cells.append(
nbformat.v4.new_markdown_cell(
source=f"""
<div>
<b>API Reference:</b>
{' | '.join(f'<a href="{imp["docs"]}">{imp["imported"]}</a>' for imp in imports)}
</div>
"""
)
)
else:
cells.append(cell)
nb.cells = cells
return nb, resources
+126
View File
@@ -0,0 +1,126 @@
import os
import re
from pathlib import Path
import nbformat
from nbconvert.exporters import MarkdownExporter
from nbconvert.preprocessors import Preprocessor
from generate_api_reference_links import ImportPreprocessor
class EscapePreprocessor(Preprocessor):
def preprocess_cell(self, cell, resources, cell_index):
if cell.cell_type == "markdown":
# rewrite markdown links to html links (excluding image links)
cell.source = re.sub(
r"(?<!!)\[([^\]]*)\]\((?![^\)]*//)([^)]*)(?:\.ipynb)?\)",
r'<a href="\2">\1</a>',
cell.source,
)
# Fix image paths in <img> tags
cell.source = re.sub(
r'<img\s+src="\.?/img/([^"]+)"', r'<img src="../img/\1"', cell.source
)
elif cell.cell_type == "code":
# escape ``` in code
cell.source = cell.source.replace("```", r"\`\`\`")
# escape ``` in output
if "outputs" in cell:
filter_out = set()
for i, output in enumerate(cell["outputs"]):
if "text" in output:
if not output["text"].strip():
filter_out.add(i)
continue
value = output["text"].replace("```", r"\`\`\`")
# handle a funky case w/ references in text
value = re.sub(r"\[(\d+)\](?=\[(\d+)\])", r"[\1]\\", value)
output["text"] = value
elif "data" in output:
for key, value in output["data"].items():
if isinstance(value, str):
value = value.replace("```", r"\`\`\`")
# handle a funky case w/ references in text
output["data"][key] = re.sub(
r"\[(\d+)\](?=\[(\d+)\])", r"[\1]\\", value
)
cell["outputs"] = [
output
for i, output in enumerate(cell["outputs"])
if i not in filter_out
]
return cell, resources
class ExtractAttachmentsPreprocessor(Preprocessor):
"""
Extracts all of the outputs from the notebook file. The extracted
outputs are returned in the 'resources' dictionary.
"""
def preprocess_cell(self, cell, resources, cell_index):
"""
Apply a transformation on each cell,
Parameters
----------
cell : NotebookNode cell
Notebook cell being processed
resources : dictionary
Additional resources used in the conversion process. Allows
preprocessors to pass variables into the Jinja engine.
cell_index : int
Index of the cell being processed (see base.py)
"""
# Get files directory if it has been specified
# Make sure outputs key exists
if not isinstance(resources["outputs"], dict):
resources["outputs"] = {}
# Loop through all of the attachments in the cell
for name, attach in cell.get("attachments", {}).items():
for mime, data in attach.items():
if mime not in {
"image/png",
"image/jpeg",
"image/svg+xml",
"application/pdf",
}:
continue
# attachments are pre-rendered. Only replace markdown-formatted
# images with the following logic
attach_str = f"({name})"
if attach_str in cell.source:
data = f"(data:{mime};base64,{data})"
cell.source = cell.source.replace(attach_str, data)
return cell, resources
exporter = MarkdownExporter(
preprocessors=[
EscapePreprocessor,
ExtractAttachmentsPreprocessor,
ImportPreprocessor,
],
template_name="mdoutput",
extra_template_basedirs=[
os.path.join(os.path.dirname(__file__), "notebook_convert_templates")
],
)
def convert_notebook(
notebook_path: Path,
) -> Path:
with open(notebook_path) as f:
nb = nbformat.read(f, as_version=4)
body, _ = exporter.from_notebook_node(nb)
return body
@@ -0,0 +1,5 @@
{
"mimetypes": {
"text/markdown": true
}
}
@@ -0,0 +1,33 @@
{% extends 'markdown/index.md.j2' %}
{%- block traceback_line -%}
```output
{{ line.rstrip() | strip_ansi }}
```
{%- endblock traceback_line -%}
{%- block stream -%}
```output
{{ output.text.rstrip() }}
```
{%- endblock stream -%}
{%- block data_text scoped -%}
```output
{{ output.data['text/plain'].rstrip() }}
```
{%- endblock data_text -%}
{%- block data_html scoped -%}
```html
{{ output.data['text/html'] | safe }}
```
{%- endblock data_html -%}
{%- block data_jpg scoped -%}
![](data:image/jpg;base64,{{ output.data['image/jpeg'] }})
{%- endblock data_jpg -%}
{%- block data_png scoped -%}
![](data:image/png;base64,{{ output.data['image/png'] }})
{%- endblock data_png -%}
+40
View File
@@ -0,0 +1,40 @@
import logging
from typing import Any, Dict
from mkdocs.structure.pages import Page
from mkdocs.structure.files import Files, File
from notebook_convert import convert_notebook
logger = logging.getLogger(__name__)
logging.basicConfig()
logger.setLevel(logging.INFO)
class NotebookFile(File):
def is_documentation_page(self):
return True
def on_files(files: Files, **kwargs: Dict[str, Any]):
new_files = Files([])
for file in files:
if file.src_path.endswith(".ipynb"):
new_file = NotebookFile(
path=file.src_path,
src_dir=file.src_dir,
dest_dir=file.dest_dir,
use_directory_urls=file.use_directory_urls,
)
new_files.append(new_file)
else:
new_files.append(file)
return new_files
def on_page_markdown(markdown: str, page: Page, **kwargs: Dict[str, Any]):
if page.file.src_path.endswith(".ipynb"):
logger.info("Processing Jupyter notebook: %s", page.file.src_path)
body = convert_notebook(page.file.abs_src_path)
return body
return markdown
+11 -6
View File
@@ -36,11 +36,11 @@ NOTEBOOKS_NO_EXECUTION = [
"docs/docs/tutorials/rag/langgraph_self_rag_local.ipynb",
# this loads a massive dataset from gcp
"docs/docs/tutorials/usaco/usaco.ipynb",
# TODO: figure out why autogen notebook is not runnable (they are just hanging. possible due to code execution?)
"docs/docs/how-tos/autogen-integration.ipynb",
# TODO: need to update these notebooks to make sure they are runnable in CI
"docs/docs/tutorials/storm/storm.ipynb", # issues only when running with VCR
"docs/docs/tutorials/lats/lats.ipynb", # issues only when running with VCR
"docs/docs/tutorials/multi_agent/hierarchical_agent_teams.ipynb", # taking a very long time to run
"docs/docs/tutorials/customer-support/customer-support.ipynb", # user input - update
"docs/docs/tutorials/rag/langgraph_crag.ipynb", # flakiness from tavily
"docs/docs/tutorials/rag/langgraph_adaptive_rag.ipynb", # Cannot create a consistent method resolution error from VCR
"docs/docs/how-tos/map-reduce.ipynb" # flakiness from structured output, only when running with VCR
@@ -70,10 +70,13 @@ def is_comment(code: str) -> bool:
return code.strip().startswith("#")
def has_blocklisted_command(code: str) -> bool:
def has_blocklisted_command(code: str, metadata: dict) -> bool:
if 'hide_from_vcr' in metadata:
return True
code = code.strip()
for blocklisted_command in BLOCKLIST_COMMANDS:
if blocklisted_command in code:
for blocklisted_pattern in BLOCKLIST_COMMANDS:
if blocklisted_pattern in code:
return True
return False
@@ -108,7 +111,7 @@ def add_vcr_to_notebook(
if all(is_comment(line) or not line.strip() for line in lines):
continue
if has_blocklisted_command(cell.source):
if has_blocklisted_command(cell.source, cell.metadata):
continue
cell_id = cell.get("id", idx)
@@ -125,6 +128,8 @@ def add_vcr_to_notebook(
"import msgpack",
"import base64",
"import zlib",
"import os",
"os.environ.pop(\"LANGCHAIN_TRACING_V2\", None)",
"custom_vcr = vcr.VCR()",
"",
"def compress_data(data, compression_level=9):",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
eNqFVG1sU1UYLkIIGkA0GkkY7Fid8Qenve1tR9uQYO0Ax6gbW0GKEXJ27rnttfeLe07HPiTKwKAjkVxJGCrG6LqWlA26AGrAKYmQGPWHhhgsBELUGP/4C6KJBua5XcsgW2Z/NPee9+t5n+c5t7/QRSyqGPqcEUVnxEKY8Rdq9xcssjNLKNuX1whLG1KurbUjMZS1lHJDmjGTRrxeZCoepLO0ZZgK9mBD83b5vBqhFKUIzXUaUk/5hz63hrp3MCNDdOqOAJ/gD6wE7loSP3m5z20ZKuFP7iwllptHscGR6Mw5ekF5ErQTjWidxIoArQfoSCNAoeB5o9O9+xWnlSER1UnFKspKBIowCKmh64RBPx8mNPoFpyftoYxoTl7SyAJkEYBAmqimnFUBolShjG8CGFIzip4CzAAsTYADyAM283+g6LLBi3cX0gRJnLGDubRBmT02jYOTCGNiMkh0bEi8lz2a6lXMlUAisooYKWIHW4Vku5ghxIRIVbpIfrLKLiHTVBWMnLj3Vb7HSJUMyHpMMj1cdCBCTqXO7M+iNRzeth4umQ4Ejxjw+EvdkG+n6ConHaqIQ8qblfi5ewMmwhneB1btYOcni0/cm2NQeziOcGvHfS2RhdP2MLK0xsCpe8+trM4UjdiFWNv0cdXg1DjR4/N5wmP3NaY9OraHZaRSMnaX5LslRa6vCIVGKPhO1FhSiZ5iaXvIL4SOWYSa3Mpkb563ZFnan+OKkO+/KVTd90lrS03N665Hc01cHXt8naWsBEIAtGIGHP8AXyjiD0cEP1gfT4zEqmMSM4oxlrCQTmUuyNqa+AWczuoZIhVjM8pedk+tZfH5qqIpDFZvHhfLebVzAUEQys/MmmkRjbPmTMyJ4XD4f/pyZgizTzv7QZ8AhUBicstgYFsZzFQ5eX+rePIOHo7o6Vkyp/DUssGs2TPjEfzbilXQUJHsL/jzDsHXviqeifokRuM0bMbFYCiTNMPBM90Qq0ZWgox/wwisGKKb2WXQKRA50BiSRTEoiqIkBcOyLAeCZJUoyVK4kQx1Kcgu+jw+kDKMlEpOxtbBGMJpAjsqtrELTckXo/Hm2MhW2G50Gpy/BOI864ZO8h3E4na0i5XR/IJbJM/L26NJ+3QIS6tE7MeBkBwMiGEM177UXqoZ6K5Bcs7XofKt3MNtavGji3OW1B9Y4Kr85iYORlu+fm7JmxPfhga3N767Dp59IvrYlQMLBgbc6NDCIBM7dsmjw7e+aimuWL3otZvXfx1f/tfy3jqWHLx0NXmz+9LqNQmvcqb52q2bvXSC7V+snctvWltEzX8IzXXRtj9/emBZpC439NaKq0ut9Rebd245Jhx6fHPyw8Onik37R0uPLPvn8rUdx368nF5Td5AObLqx4f2ntv7ctOffw+fnzXfvHf0Nb93Yua9p7qJFDaW/zRsPhhbOG3/nOj7y3fwr50tvfDQwNG/j2dL4hdsfxILJy2/3PzS0/pcTnx5d+nr9hvr3Pm+4dRSzIw8fv724b3vqeHzLhYEvI7ueLd/5+MDtO8tcromJua7fPfHBjjku1385MZ/f
@@ -0,0 +1 @@
eNqFVHlsFFUcXiyIgTYg3gFkWO7j7c7sbrtsRcyy3KVsabdCMUJe37zdme7szHTe2x5UgpRLhEgmHiTGEAPbXdm00NoiIaAGFAE1QkgIbEgANQT/kIQQDFY5fLPd5QgNzh+Tmd/5/b7f915rqgEbRNbUAe2ySrEBEWU/xGxNGbg+jgndkIxhKmlioiJYFdodN+TMBIlSnZQ6nVCXHVClkqHpMnIgLeZsEJwxTAiMYJKo1cTmzPct9hhsWkW1KFaJvZQTeJdnOmfPBzHLWy12Q1Mw+7LHCTbszIs0hkSllqlRgpSTCRdr5lQYw2/Y17xtpWsiViw3UmBcxMANigHRVBVT4GIN+BIXb9UhzYTimBVXo8U5aGAOchJW9HBc4SAhMqEMPUehEpXVCEc1jkqYs0A4uGr25mQ1rLHkNSkJQ5GxtD0haYSaXY/NvQ8ihHUKsIo0kdUyOyKrZX06J+KwAilOIwtbllgzHcVYB1CRG3CyL8vshLquyAhafmcdm6M9RwCgzTp+3J22IAJGn0rNA/48DmdFM1uTyvEOt8fh6mwCbDpZVRjRQIEMUlLP+g897NAhirI6ICcBM9mXvPfhGI2YbeUQBaseKQkNJJlt0IiVeLofthtxlcoxbKYCFY+3yzkftHM7BMHh63qkMGlWkdkWhgrBXfdJvp+SZvt1A74E8MLePEsKViNUMncLvpIvDEx0Jl+8PslK0jhpTbCN4J9PpHKK2xUsy2/zom1EYg7bjvn1PEOezvEeLogoZ+mHE2aUunylzDK/PNQeyLUJ9buMrpABVRJmC5mbX34KSXE1isV0oN+1Z+wPxjJYf0WOyRTkThtblvVrJjw8z2cmPjHSwDHGmtUx4fb5fP9TlzGDqdljzQcEHvCeUN+UxZ4VGa6/zL4zm8OTtPAwROOfEPkATz6ae2J0/3h4z4p0DjSQRfMw+17FCxXRCEKLPdF6b039kmhZXXFj06Jo/f4mgBQtLgLK7i0MsoJoomaG87p8XkEQisPe8AyvKIphEYsC9kIXqnXBWgR3N8jQTAsOgYtoWkTB+wLzQAAiCYOqrGzM1JyaJf7yhYH25aBSq9UYfyHIeFY1FSersMHkaKazrdkBN3CSpVf6a8yeGUj0upHb40VY9Lh9CMxdVtmZF9B9gSSs2yF7P65jMjWY6diAyJitz9iyT4Fi+qMj/YUb771/+tiOev2r+OQWtw8c3DBqSGxKeOa4C4Fw28kFvzeg25d++jQJJkzakkoFh9Efnu86vnTYhbPXrg5effuj386du44O9M6+9c1rsz4uKu3Zc/pPe/Vaji6fcKp1WXndzqLRH4yYgraP/fdFuRceXJnmPwSHqm/Vx891nIbDS2q/u3uht6juJln57SevDr4+98tRZ6b5zhevH7Dr+tHLfwQH7py04PCO0tVlRy83nimcKL9wfjstGDnoVOcrl4OuW2PGDqwc9NzkUPX5q43vlu+Z6vmluzgz2z90Y0/wyNWZ/j3GItM+flMvHT5r6dlpvz696c4o6dmxqYhBhh1xv3ylcNydoqE7xxVu/QzO12+2LSbp5MCTF08IspR2v+S8NDq9MPPmjanbXh9xvGP/j3+3fH7zzHsF8BSIbL72T/vdbVvKujtOurtqL3WMXtS9tu3QX1duDLXZ7t0rsCWnrXtnyFM223+sv8iH
@@ -0,0 +1 @@
eNqFVG1oHEUYvlDQ+sMPqggGwfFoU5HM3e7d5i4XBY2XxLQ1HyZX8iGlndudvd3e7uy6O5fetUZqEm1sSdulCIKlBXO5K9eYJm3qB7Ui2B+KFhTqj6MqVBAs8YcW/KxtnL3cJSkJcVmW2Xm/nvd5n5mh/AC2bNUgVZMqodhCImU/tjOUt/DLKWzTkZyOqWJI2c6O7th4ylKLmxRKTbvB70em6kOEKpZhqqJPNHT/AO/XsW2jBLazcUPKFK/s8+oovZMaSUxsbwPguYBQC7wVJ7bz0j6vZWiYrbwpG1teZhUNhoRQd2uPgihQbaBnAEE6fsY7uMMNNySsuWZRQykJwyCsg7ZBCKYwwApwoQDn5rEzNsW669dnpACyMEBAwZoppzSAbFu1KUMPKNKSKkkAagCqYOCC8IHt7AtUIhsNC0u3uIvjOSPuHcwrGEmMtSNZxbCpM7OChzNIFLFJISaiIbHcznuJvapZCyQsa4jiguhiLRHtFJIYmxBp6gDOLUQ508g0NVVErt2/m/U1WSYE0oyJV5oLLmTI6CTU+aCxgsPfmWFjI4DzBQVfYDoNWbcq0RjxUEMMUs4s2S8sN5hITLI8sCwJJ7cQPLXcx7CdiTYkdnTfkRJZouJMIEsPCeeW71spQlUdO/lo58pyZeNSuaCP532RmTsS2xkiOhMy0mw8s0jyYkiBzTsIuRDk+KkKSxomCao44wE+cMrCtsnkjIdzLCVN2UNZNhH81ef5sgLf7dhWmeYPng3ZJjYd52KLpdYCTgAdIgWungBf3xCINHAB8HxbbDJaLhNbdRgzMQsRW2YDaa4MPy8qKZLEUiG66tiL3qW2LFZfU3WVwvLpY8Nyf52swHFcsWZNTwvrjDW3YjYYiUT+Jy9jBlNn1u0P8hzkhNhCl3VCfxGsFrlwhst4ci4ehmjjGp5LeCreYE3v1fFwgf5CGTRUJedjtt7J8W1Iifa0b+sVd0vp7e2tAdqeDCvy+TQUNSMlQcruMQxLgkhTpwjiclyuY28wGBLCKBQOcjyW5XBIkgUUiGBhfEBFToH38SBhGAkNn4m2wCgSFQy7S7Jx8k197Y1tW6KTvbDLiBuMvxhiPBOD4Fw3tpgcnUKpNDvgFs6x8K7GPme2XpTCQTHIx+vrOSEYEWFzT9d0RUCLAsm6t0PpvnyNydRiW5euPnZovaf0rHvh8FPJz559YGT+4Nv/PCQVM39t7al5/7TAPz56iOgjEzuaLyQ2jNzed3QL+PbT8P1y04PXvrn+0ZMPX50jF38+4c/fuvGr9f0vP8798Vt6//Dgn0K+te74PfcNzwbXF8b6dw1HNzv96St6q3MDv3ryNHfsJ/zi1MEDZ/dHoXbprvnQ7bHqwcu/v5N+dNO9jxw4fLbl3Ngr36G9ezqPfVL9xCnu6VERq7v+rd568s0Pa9Lt+txRsvnW6Bs3pbe+eL332pfnhzfePHIid/1uj2d+fp3n76+rL1dVeTz/AbjckGA=
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
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
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
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
@@ -0,0 +1 @@
eNrtV3lUFPcdX6XGYLTFaKImHuNq9RmZZWZvIJsIC4iRK4CLIGQzO/Pb3YHZmWFmFndBo2jUPNEkg1e94oWLUsUDQoxn43tNpEoN8chDo/FK1UKO5kV9pmr6m2VRiKZNWvvavmb+2J3f/L739fv8ZlWXAEGkObbbFpqVgECQElyIlbOqBVDsBaL0asADJDdHVWWkZ2Vv8Ap0yzNuSeLFmKgogqc1HA9YgtaQnCeqBI8i3YQUBd95BgTFVDk4yn+q27wytQeIIuECojoGmVKmJjmoi5XgQj0VsowWEckNEIaQoEKEBVNFhHBwXglJ4rh4QlBHImqBY4BC7hWBoJ5eAL94OAowyicXL6F6TiFi4RKH/6IkAMIDF06CEQH8IAEPD32TvIIiBNNgyjeOY0LmSH4+KNzpZYPuK7LuvscgZWqW8AQJXECyB233SQoNBURSoPkQmXo8kBABMKCEYCUkRIY4OQEhWHEqEGjWFXQzGFbIolFE8IQAZcPAi0FFvAADKkg0aF92kAYXHVZC76Ao9fTpSlhgkmgBUIof96iV8HRQc45CQEqQenrB9Go3ICio6o0qNydKcm3XBG4jSBLAWAKW5CioQd7qKqX5SIQCTiUzNdAjFgRjItcUAcCjBEOXgEA7l7yd4HmGJgllP6pQ5NgtoSSjiiX3b9comURhSbCSXJ8OjYibEJXhh5XGIrjGgGnw7T5UlAiaZWDloAwB7Qnwwf09nTd4giyCQtBQFcuBdubazjScKG9MJcj0rC4iCYF0yxsJwWPU13X+LnhZifYAudqacb+60OY9dToNjmuid3QRLPpZUt4YrL13ujADSfCjJAdlyOuw2o74MIB1SW55gy4a3yQAkYd9A2YHIJvkFWdVwVyAI4eqQ/2zPn1iRxLPqp6sSoB5kfclCXQkgumRdFJCtJhWD39iDMYYnQ4Zn5q9xRpSk/3ANOzIFmB1OmEqEjvSXk26vWwRoGqsD0z4PiXh0BvFfNiVKPDxnAjQkFXylsloZvvkQCck1LVXF8oJLoKlS4Nq5c1KMuGkoNn60DasekUkVI56RHmDHtPXhnY64lwD/cJQHEMx/F2l/klYVorhPCdIqAhIOJckv9wS6SF8Sk1ZdLhBZ8QwLBahWZLxUiDL60jgPFCnGIvwsEk5gtrtQ+FIAAztoWESgr+hmQfrBYfM2K77KSSuCLCivEmHtT/7O5MIQNGguHFXUFU0fPY+mKhDllahiTbpdnclE0EngzYYPeKu+/dDItZj4hZfBzFKU3LLSLiwO80GwkEB0okRmEFPkkYKByaKNBj1lMNpAqZt1iTUSpBugGYFq02uTshNi0udYK3JgrKtHFdEg8pT3cLsdtJpd3gs7qwsd7I9Tut3c/4Eqpix+302T7HJMVHjt483W3NL6bx0b2pqZlJpEYqbtGbMZNBF61BcAztSg6OiQ5eT4uK5Yq50kiAWltpsE6xGhjBqvWRqrp4tcUmi1pU22aF/IWViliduKk97MZNdk4I7s0mtOYUpSs4snkT7C+P8Pn18xiTMmcUlx02F+SQktyUqFoGVCGehaAn1Awr7AVW6AY/RdnRDLEIFq8Ci6Tr7YpFkeKils4w/FslSygnAfziYs2gJWNI4FrQshjHwltCUxZDny0gqTufIQp+Dwmzpk9w5NsppnoQLGd5MndvpS5TM7ngthidhnYKgNelRLBQHI6Y3B4vnnun/pFUNk9HO7Y2mB88imEeWE1na6QxkAQG2kFxDMpyXgmNcAAGY88y4XLneTFJmXK/XY+ZoDHMSOjQxJ3N7h7S7w6BKOQOCx3h5oP3g+X23j4ZVPKoKPmFM5mH2NBaxt3Xsa5Ypc4aWoK22nk0b42Zej1hbG1YesO0cPD/70BOFH391YEDp5MzBreMiYlcsP5P71pD31yYPdyLXVyXkTrhx+oZ1xbChJ0famo9m97g22/dL+1szDtzKOxd75Km5Z4dkfLjkWuKVnZXJc2xDInsLB5NO2B+R38l/9bdre7ywej3j9id+kb+nfMCRgihh3zZL8bbHyp90XP+AWLBDLDOiNf3fiNBxJVsXu9GjfS+cH/3+79wt2TOnTJl8Yf7LxlnxY+NPSFsLx4xW0Wi/9zYOXrjny2fffSO6eMyiaaPFoUOaP711ceWw1qZjjfbn113odyDt2+y3+4C3H7c+12/apg9MzgXlF8DhJrmy4caIMx8OCmO/3p2QmNrKnz1YtrCh7yfxe3s0hqP4nBnoxdiCfmXHS5uantR8FXflwid7DqRptb85sfTwc3v3vzKoYbj3pUH76kzn422bDn7Rb/YnDda0upJaduuvjg87Gb6kGSSGXzVlL2xTtyUQ05gRV8ZbklfsGtw6cUbJeHSC7Gtmy3wvz6qwBEYcE0eFvXJ97+jmPrmbbi2af2xsuSX3oLax15INm1Oa9ycdqvnFALP95vCk4eYBl5+HyfvuuzBVj6VXjywNU6keJtwLC3vYcC8S6SyD9TJMJxICHhzwsGSDiEwBdXaSYP4esqMVtKRWiOwuB+MizD6A55USeRPj81L8eHwK9PDHAkBCcHk90CpFm7os/y4Cy4frfPUPOZivnq5W4FhXt9Ttm4gST4L1I4VeyCsQtAgoBEfiaYaBguGgYGAXi8Pz2Xz2ewxTCRGiTS9LQQaahSAAj+4cSiU0XUJk/zGB+Blq/2tQ+6wq4mew/Z8H2wEyCGbklq//y7HMvwFl3HfRMJl+4kXjiX9w0dD/r140zOb/w4uGQfvQLxpGhz6aMBgNRi28WQAzjhkxSofpdQQOgJHAqR+8aDwEAGvGScz50wDssnsANoiDmBchih3Xux3FllOxf7m4tLs/X3BHrB1XEb82p77+j4VjIsfo2XMzokaObai4tHPe8tXne998SzUwZ4Vh4JQNpwLXrn5+pnbLd889e+7GB2v+uveZNZc+a9mP8nfybu8yLHrpvZVDcm9nFOSyeel/Ng+mnw5fUvrxNLzAWdHaUmiM6LPsUlnuicKYy9KK1Mt0Q0rdyhcn19WNdPY58Lhq5o3zn4+YW3n2yFM7G3t+9OajNupkdbpq1M4v+85Wp/WfvaJxef3gxQff/HbjqK82jexVfufRc3Nj55T9iRv4Xrh7Ya+8ft80YW3rksoLRvfquzojPJpZdeP1sMVtlqR3d6/qT58Ov55ovXz7tWFpzZYcz6WFC26Ff7r7XJVGvY6/Qs4Xih65/qbq1lDb8dsfn6qXV9oe+yyn177zhf563eWVqxqnGSr/MP9O96MDFkW1za/sv3pZxZCnKxoCX0c2VVawa+a9AorbLsdfa/z1oNUL2hI3j2nQZPc/feX1nNMNPQqOTVty1B2taxx+s2c7Cp15fNQ3+7urVH8Dq9r6oQ==
@@ -0,0 +1 @@
eNrtVnlwFFUaD2G5REIsBcQqoDPiwpL0pHuuzCRGyUEgIcmEXCaEMNvT/TrTSU93p49kJiEiuCiCizQrKsIWkgyTGMINMVyyGqIiN2ilIIAu4HLoLqyFQTn39WSCibhbbhX7x+7SVTPT733f+87f++Y3t74CiBLDc32aGE4GIkHKcCEtmVsvgnIFSPLv/G4gu3jKl2XPya1TROb4BJcsC1JsdDQhMHpeABzB6EneHV2BR5MuQo6G7wILAmZ8Tp7ynujzcrXODSSJKAGSLhYpqtaRPPTFyXChq4RHxkmI7AIIS8jQIcKBSgkhnLwiIyk8n0iIuihEJ/Is0NQVCYi6mmK44+YpwGpbJYKMmnhNiYNLHP5KsggIN1zQBCsBuCEDtwBzkxVRM4LpMW2P59lgOLJXCBinFS6Qvmbr7nssUq3jCHdAoQTIjkDsHlnToYBEiowQVNNNBjIiAhZUEJyMBNUQmhcRgpMqgchwJYE0A2WFR/SaCYEQoW1YeCngSBBhQUWZAV3LbtXAojtKmB00paup0coCm8SIgNLy+FFbK0+3Nu8sBaQMtWuKa+pdgKCgq9Mh4T4XL8nqut4tXE+QJIDVBBzJU9CHurakihGiEArQWm8aYU4cCFRFbSwDQEAJlqkA/q5T6gZCEFiGJDR5dKnEc03BNqNaLPeKG7VeohAUnKxuscMgElKjs7wQaxyC682YHt/gQSWZYDgWYgdlCRiPXwjId/QUCARZBo2gQRyr/q7D63rq8JK6OoMg7Tm9TBIi6VJXE6LbYtrcc19UOJlxA7U+Keted0Hhj+6MehzX2zb2Mix5OVJdHUDfe70OA1n0oiQPbairMD/J82UMUI9/63CQtMPpjnfl5LimOBIMXhfvTabKWYfXk+8uj3FO1Xsdk61JhVXMdLuSkZGdUlWG4jEGKxZjNtqMKK6HCetxVHIan0svEfhyvipPlEqr8vNTkywsYTEoZEahiasokSVDSWaB05SWPjXHnVApMAoW49Cn43QuabCms2VTssvzGG9pgtdjSszKw+gcfkpCZRwCo1MqGCrePN2TlVJu58lSj5PC8u15rufyKdqah4tZSrbRRXsmyVZXogHDU7Ae4RliTCgWjNCCmayY9qzrxgYLuBLZpdYZbXiDCCQBTg3woh+WTFakuT6IQ7D/k/rg9Ki1T/0RwsN8yRCT6q4UkYlCMBNiJ2XEgBlM8CvWbIk1mpDJGblNSUE3uT8LwY25IrybNIThpG7I15MuhSsDVGPSz4J9lwZ22EktfDiTUOAReAmgwajUpgI0u2tuoqnJm7tuFsqLJQTHVAXcqu9qQIZzkuG2BMXwzmsmoXPULal1sEDrgpJujDXCvGBFMRTDt2m3n4RXSgtc4EUZlQAJp7LsVY9HuQmPdp/ijbjZaIFFjkMYjmQVCuQozmTeDX1KcYgARxRPUNs9KByIgGXcDGxC4Ds48eFdwbUWtdyrIfNlgJPUBiPW9bzfU0UEmgctjbuGfDb47Px5pW5bBk3HFmPc3ltNAj0CqrO4pZZ75UETtZjU5OlWRhlKPT4WLhwmksZpK20iSIvNRtFGK4UbbSYLjZltZovNTK9PSkGTCNIF0JwA2tT65MLMhIzUpOYCtCdsUHtgwkM5x0scQ9P+HCDC1qiNJMsrFByNIvBDW9kJheoWK0lZcRN0TQMDRhNGdNJz2Ru6rd0FmU+bq4E/xzn+rnHe1ufEmIUDQwJPX/i5c4fN3sd1YOE7v46cH98xj41sris65ptS7Rrss5mUiMOfpdGJ5XlivzjzzcvzRjc/9nFs+J5FNF35xo2JAw//Zk/oZymbJqQZb3uurbjUtn7WD1e+n7f7C3bh7GvL6xeMPnnqUAf6amn/tSun/V39LmHatCeojOZ5S5P2FqzJHH4MtLS8XTx5SFbWAr//q6dee/IJeytjCnvzrHD6kRjfsKr5bZcnDozoPFD4nivnZELUh0c2Zr9zzTB5vv3ZQX0WpRf3ubirMwptbRgwrDClqNIdSfYPeXRZcipZdbazY+jfajKPvnXOsinOdKT90oDdTz9/3bLyWLzto/o5jshb0y1DwNK8+ln9v3939Mplg/rkDx8SMznz7dOVs1JGhPr2rQlF29e2Pt9vduTVrV8+dGbY43svFBacrIpoz934fbr85KmHwq6kXAifsf3OSOoctmanqdhTfEs48dKqnfKWzpI/J/rXdi7fs+rqgcWtTS/WFZ3t+/lyJfFiw3gbUZVQtG/mgenTLowpGpr5xqhP9hy9+l0bJSegqepqrrmm6rdpjUP88caH+/d9/9rOsUfC3nXfznzqwut/2l31kW7vlgNHlmbGrH9kk2EZPc3qcNh/bRwY9sHsQAP7hnSOao18A3bzfpKp0FP3m0xFIT1tcArL9lAh4GCCw5gL8B2NMjlIgv1XvInRuIhOU3IkmzgPYE1pSpZclpeUabHwU+DAAtN/Kb0ixBLFDaPSvOmqZ9zlNzPgeobunyU4Q1ej08hO77R0XUJEqyfBeZFSBZ4VCUYCFIIjiQzLQsMIxbPwNksRPYukJd0reccvSfEBRX1AUR9Q1P8tihpjNN5fimr+r6Wopv9DimrB7ztFNVNGinY6DcCJAYKkbARmMmBOJ4bRuAGLseD/QYpqxkiCsP57FHXJTynqtG6KOvzpojlU3KJvigaPvRYyaU7t+F8tmJEqj9d/ULwqLPROdcQPhWNHjKatm407xox8Qcz/68RlMxeOrD20O/7y2rI/nNrZ4hq6pvH6VzM/bu0833Gl5URDm+8d+rUUfeOApKSr4xd9+Ipl0NYvz01/Bl1z5mL51uJDeyYOvzX269pzZZ++2Sb+cUTezBU1GfaDyJpRNw+GhDzzl8oFj0eN/ixsQVu/kYsLKxsq2u0hE9SV4auXjVoYVjs85mhW+MPSpTHxc9vnRoVfiX6Rcz3mibi+7lFr/4tbX7g6MMc46vSq9odvqP2WVLw6PM214tqi0IJvZ457vmXl6xtGFdontV64NfLZmXXVl5y1Lx26OYwvFk62DzLnvOXclJVrrN4fcnt/5BN3ytY6ayPS0KsvEYam5nFxyo69v4+K9i12zX55xOdnBu84Ues6/wP38aeuY3W7Uhd+s67j/CpH4Yrr2w7XiHsPZi74olBoKBoRm45vO/b5iYLoDmUj0wy2ZR/HbwzoopY7Xnlz9fuhISH/APhftKQ=
@@ -1 +1 @@
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
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
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
@@ -0,0 +1 @@
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
@@ -1 +0,0 @@
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
@@ -1 +1 @@
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
@@ -1 +0,0 @@
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
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
eNqFVHtsFEUcLi2QWolGQAEhuJxFMXbvbvce7Z0xUA+EAqW1PVJbxDLsTm+X7u0uO7Ol11qTlkciNYGFiIomEHvclaOUK48QBGJFixoBK9jIGamgFCPYPwTFB9I62155hAb3j8nO/F7f7/t9Mw3RKqghUZFHtIgyhhrgMNkgoyGqwZU6RHhNJAixoPDhwoJif5OuiYnpAsYq8tpsQBWtQMaCpqgiZ+WUoK2KsQUhQiAAUXi5wocSn9ZagqC6HCuVUEYWL8XYWWcWZRlyIidLai2aIkHyZ9ER1CzEyikEiYzNo1UCwJSIqGCIkkEQzrTULTXDFR5KppmTgM5D2kG7aKTIMsQ0SwrY3azdzINCCMOg6Veq6BTQIAUoAUpqhS5RACERYYKewkCqFOUAhRUKC5AyQVipxWSlRLlCIcF1UQECnrC0ISwoCBtt9/S9B3AcVDENZU7hSS5jd6BGVLMoHlZIAMMYZ2IbINaIVUKo0kASq2BkMMqIA1WVRA6YdtsK0kdLkgAah1R4rzlmQqQJfTI2DuYO4bAVhsiYZMpudTitbLyaJt2JskSIpiVAIEXUAfvhOw0q4CpJHjopASMyGNx6p4+CjB35gCsovisl0DjB2AG0oNu5785zTZexGIRG1Fd4b7mk8XY5h5VhrJ62uxKjkMwZOyqAhGDbLZJvhcTIfB203U3bmdYhliQoB7BgNDEed7MGkUrkC1dHSEqso4YwmQg88Xk0qbgPChYMTbM7ZWx4NpmOcdQv6FmU3UEVcJgy9UMWr8vhdXqoufn+Fl+yjH/YYbT5NSCjCjKQOUPDj3KCLldCPuYbduwJy+22NFJfEoMippO3jQzL3Bphp91uTzx1X08NBglrZsWww+Px/E9ewgzExn6zP5qx03aHf7BLl7MsQQ0XOXhnk3giJh6CKPM+nrfxDHlT9/UeHo/TUxZLgqZF3jhC/svtTAmnqKzuy0H64nw0b25hkYt1hFwHqmlOUnSexuTdgvSAIKqxkaAYwPJ2JwNZxuF2uLPZHDbb6XKwHg8DuWwXzzZVicCIMVaGCihKQIJ7fC/SPsAJkC4ekI0RnV26KDc/z9fyMl2kLFcIf35AeJYVGUaKoUbkaMQGSpMLrsEICS/KLTX253BcBc9CJoeHIIfzuOk5JUXxIQHdEkjYfB0G3sd6IlONHHWM2P5EY3rKwJcmbcpVxuWOWdu/vmeB9b0ZIzO6umvSi9b4X2pNn3PqzX2TvJU2rmD+2J6Pms6lrnjk6QXXa7dtm4s+Ht/W0f1h79WTdczRm/921mWVn/rh2ys39iU+iT40+fcz7U3rTzZzUlyYOpnfciJvyuRfXdrxx3yRx0N9Va87sh8F2/Zs2bXqyz93TXdP9L/f0Xaz5u80vc/zXfT0j6OFzpalXpR2+HK8vplFOZ1G/cWRedfLaq6GU/efuayeLpvV/POo7ydtbD83ms0r2cm9s9zVv+yFZQ51bX3jzsK+h115Cz8b/yxsPt6xff7UpV8ERvu+5tZPmfbAX/XTmqccOnuxvH3rsRGbciZkjFt57Uh2Yl5P/fS91WmZvynxY4vyXu05O6EXzHhtYVlvV8aS9oqZ3c83bjzzpO+rn1xdE9Ol8xuvP7OwILWWboq/+83aC2+gzsAhdKrp2i+z+sZeynhu3SwPeuX8H0tWX/JKD27euawxa+WVA+l9Uyf2N2fVt721Fa3W/8nsHbV5TNfB1g1Z63ovR3J39+3Vb1youTkqJaW/Py0ls7Tk7YbUlJT/AFgF6ww=
@@ -0,0 +1 @@
eNqFVG1oHEUYTo0JDYq10j8WpcPRFsTM3e59hFwQJb3EKjVNTK42qbRhMvve7Ta7O5vduSTXWiSxFD8wZfOjFVGR5nIn17RJMLZCLFKtUGiLSqv1IPhDEQwitFb7wx/W2ctdk5IY98cyM+/X8z7vMzOc6wfb0Zi5ZkIzOdiEcrFx3OGcDX0pcPjhrAFcZUqmrbUjPpaytcIWlXPLaQgEiKX5iclVm1ka9VNmBPrlgAGOQ5LgZHqYki58f9BnkMFuznrBdHwNSJaC4VrkKzuJk5cP+mymg1j5Ug7YPmGlTCAxuXc0oBKONAcZaWQSA57xHdrrhTMFdM9MdZJSAIdwBDvMNIHjoCgg1QUlL4+TdjgYnl8XSyFiAyJIBd1KpHREHEdzuECPONF7NTOJOENcBeSB8KNd4o80M8EaFpZecQ9Ho65R8B3KqUAUwdvRjMoc7k4vY2KSUAoWx2BSpojs7qnkAc2qRQokdMIhTz20RardfC+AhYmu9UN2IcqdIpYlChHPHtgvOpsoUYJ52oLl5rwHGgtCTe6ebSzjCLSlxeBMJPlDYX9wahCLfjVTF9RjnQhIWaton11qsAjtFXlwSRRudiH49FIf5rjjLYS2dtyTkthUdceJbdSFP156bqdMrhng5mJty8uVjIvlQn5Z9ken70nspE3qjieI7sD0XZLvhuTFxENYqsOSfLrMkg5mkqvuWFAOf2SDYwlBw2tZkZKnnOGMmAhcvpgrafBE647yNH+seCTTJKbjnourqVokhVAr5chTlPg1REINEQltb4lPxEpl4isOYzpuE9NJiIE0l4efo2rK7AUlH1tx7AXfYlu2qK9rhsZx6f6JYXlbNxOWJKmwdVVPGwzBmlcxE4pGo/+TVzAD3J3x+sOyhKVQvNRleE8BrRS5cItLeLIeHoFo8yqei3jK3mhV7//AI+3Jl0BjTXE/E+tuSe6EoHWgOVq/bXd4G0vY27e92NXSEv5kEFOdpRTMxUsGuCiIQe4WEESVUDQSkaOJqBwJBykoSg/QHhqReuqjdYo81q8RNy/7ZZRkLKnDZOxZHCNUBdxRlI2ba+ra2djyfGyiE7ezHib4ixPBs8lMyHaALeTo5oulxQW3ISvC2xu73Jl6ShNKEIAqEbmeRutw8+72qbKA7gok470OxRdzSMjUFkcX5ja9tbai+FW+MHJl/5fSw4e7v7rc5R+5eqzp7OanN/wUax1qf3P97dHXLz55fXb4/p8HAg/hP8M3rqwLnR+Y+vWXuQ0n//40Pdnafurkdzffvn08ttf4q7ry3LqZzHMX3q+ppg8+YPn2XZv+4sOjj1d1zpwfH/kj9c/oDmXrlUsnXvHvu3RftaFseemHr+dZfP7MtU09N9dffWf6tydujf4+zOZrbh0fUh97132v6UhV33V146OfH/lmwGfWHOtYWz3fd3Xnjac2G+F9b1Sdmdt4IXPn28QHr4o27typrFgfmK2oXFNR8S83QI1c
@@ -0,0 +1 @@
eNqFVH9oG1Ucb90fDmR1DgTR4R5Bq2hfcpdLmqRs1Jqm1dW2oY2rrWh9uXvJXXP37nb30iXO/mE3HKJ03mAqxTFZ02SEbmtd58AfYGVDpYL7Y1IiTMU/RHAynMgQOuq7NGk7Wuv9cbz3vr8+38/3895oYRiblqKT2imFUGwikbKNZY8WTLw/jS16OK9hKutSLtrdG5tIm0rpUZlSw2ryeJChuBGhsqkbiugWdc0zzHs0bFkoia1cXJeypasHXRrKDFI9hYnlagI85/U1AFfViZ28eNBl6ipmK1fawqaLWUWdISHUOTogIwoUC2hZQJCGm10jLznhuoRVxyyqKC1hKEA/tHRCMIVeVoBr9HJOHitrUaw5fv16GiATAwRkrBqJtAqQZSkWZegBRWpKIUlAdUBlDBwQbvA8+wOFJPSm5aVT3MHxtB53jRRkjCTG2tGcrFvUnlnHwzkkitigEBNRl1hu+0zyVcVoABJOqIjiouhgLRNtF1MYGxCpyjDOL0fZ08gwVEVEjt0zxPqaqhACadbA681FBzJkdBJqX2yp4vBEs2xsBHBuwef2Tmcg61YhKiMeqohByhtl+6drDQYSUywPrEjCzi8Hn13ro1v2ZCcSu3vvSIlMUbYnkak1+s6vPTfThCoatgvh6PpyFeNqOcHN8+7QzB2JrSwR7ckEUi08s0LySkiRzVuAXCPk+LNVllRMklS2J7y897SJLYPJGR/Ks5Q0bY3m2ETwt18XKgo81d1RneaPNTtyrWw69ucxOd0AOAF0ixQ4emK/Jr/Q5OdAe2dsKlwpE9twGDMxExErwQYSqQ6/IMppksJSMbzh2Euu1bZMVl9VNIXCyu1jw3K2ds7HcVypflNPE2uMNadiTgiFQv+TlzGDqT3r9Ad5DnJCrNKlb6AENopcvsMVPHkHD0P0yCaeq3iq3mBT7//Aww0UK6ChItmfsfUgx++LdkXkwHBHsN3Xt5eIfDJMwpF9FzJQVPW0BCl7xzAsCyJD7RLgeMQn4qGgXwj4/VJc8kteMS7FuaAQ53FA8k4MK8gu8m4eJHU9qeJz4TYYRqKMYW9ZNnahtb+rpfPZ8NQLsEeP64y/GGI8E53gfC82mRztYrk0u+AmzrPwnpZ+ezYoignJi+PBkBAIiqFGGOnrma4KaEUgOed1KL+XrzOZmuzo0g+73tpaU/62PDfW0XHpqe2Hl/ae/qs1/tp32p6Ge0bbTz7zfuf4Ax/Qr+hRads/N45F5nrn+u4dalv4YmLh4ye6bjx8a7D7p2to6MDsNS1/5NYft+fv33mduzLu+v7Kjp1tbz65tXhi4JVDYc+2SOYqn3vj5vlFVx+qn58/tdvjnr+r7sL0fQ8t/r4YGPKd+Xsis7vjQaFuDz6RuPhR89zNXz+sD/t7oiizPXB80v4z9fhI/S/jP4cu//bO2GO33x47Ih3/5u6ZL98L1B273vzJy+/uYk0sLW2p6bu8sL+2tqbmX44/ioo=
@@ -1 +0,0 @@
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
@@ -1 +0,0 @@
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
-216
View File
@@ -1,216 +0,0 @@
# API Concepts
This page describes the high-level concepts of the LangGraph Cloud API. The conceptual guide of LangGraph (Python library) is [here](../../concepts/high_level.md).
## Data Models
The LangGraph Cloud API consists of a few core data models: [Assistants](#assistants), [Threads](#threads), [Runs](#runs), and [Cron Jobs](#cron-jobs).
### Assistants
When building agents, it is fairly common to make rapid changes that *do not* alter the graph logic. For example, simply changing prompts or the LLM selection can have significant impacts on the behavior of the agents. Assistants offer an easy way to make and save these types of changes to agent configuration. This can have at least two use-cases:
* Assistants give developers a quick and easy way to modify and version graph version for experimentation.
* Assistants can be modified via LangGraph Studio, offering a no-code way to configure agents (e.g., for business users).
#### Configuring Assistants
In practice, an assistant is just an *instance* of a graph with a specific configuration. Because of this, multiple assistants can reference the same graph but can contain different configurations, such as prompts, models, and other graph configuration options. The LangGraph Cloud API provides several endpoints for creating and managing assistants. See the [API reference](../reference/api/api_ref.html#tag/assistantscreate) and [this how-to](../how-tos/configuration_cloud.md) for more details on how to create assistants.
#### Versioning Assistants
![assistant versions](./assistant_version.png)
Once you've created an assistant, you can save and version it to track changes to the configuration over time. You can think about this at three levels:
1) The graph lays out the general agent application logic
2) The agent configuration options represent parameters that can be changed
3) Assistant versions save and track specific settings of the agent configuration options
For example, if you have an agent that helps for planning trips, you can create a new assistant *for each user* that passes specific user preferences (e.g., desired airline and car service). As each user interacts with their own assistant, assistant versions can be saved that track the specific desires of the user. Read [this how-to](../how-tos/assistant_versioning.md) to learn how you can use assistant versioning through both the [Studio](../how-tos/index.md/#langgraph-studio) and the SDK.
### Threads
A thread contains the accumulated state of a group of runs. If a run is executed on a thread, then the [state][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.
For more on threads and checkpoints, see this section of the [LangGraph conceptual guide](../../concepts/low_level.md#persistence).
The LangGraph Cloud API provides several endpoints for creating and managing threads and thread state. See the [API reference](../reference/api/api_ref.html#tag/threadscreate) for more details.
### Runs
A run is an invocation of an assistant. Each run may have its own input, configuration, and metadata, which may affect execution and output of the underlying graph. A run can optionally be executed on a thread.
The LangGraph Cloud API provides several endpoints for creating and managing runs. See the [API reference](../reference/api/api_ref.html#tag/runscreate) for more details.
### Cron Jobs
It's often useful to run graphs on some schedule. LangGraph Cloud supports cron jobs, which run on a user defined schedule. The user specifies a schedule, an assistant, and some input. After than, on the specified schedule LangGraph cloud will:
- Create a new thread with the specified assistant
- Send the specified input to that thread
Note that this sends the same input to the thread every time. See the [how-to guide](../how-tos/cron_jobs.md) for creating cron jobs.
The LangGraph Cloud API provides several endpoints for creating and managing cron jobs. See the [API reference](../reference/api/api_ref.html#tag/runscreate/POST/threads/{thread_id}/runs/crons) for more details.
## Features
The LangGraph Cloud API offers several features to support complex agent architectures.
### Streaming
Streaming is critical for making LLM applications feel responsive to end users. When creating a streaming run, the streaming mode determines what data is streamed back to the API client. The LangGraph Cloud API supports five streaming modes.
- `values`: Stream the full state of the graph after each [super-step](https://langchain-ai.github.io/langgraph/concepts/low_level/#graphs) is executed. See the [how-to guide](../how-tos/stream_values.md) for streaming values.
- `messages`: Stream complete messages (at the end of node execution) as well as tokens for any messages generated inside a node. This mode is primarily meant for powering chat applications. This is only an option if your graph contains a `messages` key. See the [how-to guide](../how-tos/stream_messages.md) for streaming messages.
- `updates`: Streams updates to the state of the graph after each node is executed. See the [how-to guide](../how-tos/stream_updates.md) for streaming updates.
- `events`: Stream all events (including the state of the graph) that occur during graph execution. See the [how-to guide](../how-tos/stream_events.md) for streaming events. This can be used to do token-by-token streaming for LLMs.
- `debug`: Stream debug events throughout graph execution. See the [how-to guide](../how-tos/stream_debug.md) for streaming debug events.
You can also specify multiple streaming modes at the same time. See the [how-to guide](../how-tos/stream_multiple.md) for configuring multiple streaming modes at the same time.
See the [API reference](../reference/api/api_ref.html#tag/runscreate/POST/threads/{thread_id}/runs/stream) for how to create streaming runs.
Streaming modes `values`, `updates`, and `debug` are very similar to modes available in the LangGraph library - for a deeper conceptual explanation of those, you can see the LangGraph library documentation [here](../../concepts/low_level.md#streaming).
Streaming mode `events` is the same as using `.astream_events` in the LangGraph library - for a deeper conceptual explanation of this, you can see the LangGraph library documentation [here](../../concepts/low_level.md#streaming).
#### `mode="messages"`
Streaming mode `messages` is a new streaming mode, currently only available in the API. What does this mode enable?
This mode is focused on streaming back messages. It currently assumes that you have a `messages` key in your graph that is a list of messages. Assuming we have a simple react agent deployed, what does this stream look like?
All events emitted have two attributes:
- `event`: This is the name of the event
- `data`: This is data associated with the event
Let's run it on a question that should trigger a tool call:
```python
thread = await client.threads.create()
input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]}
events = []
async for event in client.runs.stream(
thread["thread_id"],
assistant_id="agent", # This may need to change depending on the graph you deployed
input=input,
stream_mode="messages",
):
print(event.event)
```
```shell
metadata
messages/complete
messages/metadata
messages/partial
...
messages/partial
messages/complete
messages/complete
messages/metadata
messages/partial
...
messages/partial
messages/complete
end
```
We first get some `metadata` - this is metadata about the run.
```python
StreamPart(event='metadata', data={'run_id': '1ef657cf-ae55-6f65-97d4-f4ed1dbdabc6'})
```
We then get a `messages/complete` event - this a fully formed message getting emitted. In this case,
this was the just the input message we sent in.
```python
StreamPart(event='messages/complete', data=[{'content': 'hi!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '833c09a3-bb19-46c9-81d9-1e5954ec5f92', 'example': False}])
```
We then get a `messages/metadata` - this is just letting us know that a new message is starting.
```python
StreamPart(event='messages/metadata', data={'run-985c0f14-9f43-40d4-a505-4637fc58e333': {'metadata': {'created_by': 'system', 'run_id': '1ef657de-7594-66df-8eb2-31518e4a1ee2', 'graph_id': 'agent', 'thread_id': 'c178eab5-e293-423c-8e7d-1d113ffe7cd9', 'model_name': 'openai', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_provider': 'openai', 'ls_model_name': 'gpt-4o', 'ls_model_type': 'chat', 'ls_temperature': 0.0}}})
```
We then get a BUNCH of `messages/partial` events - these are the individual tokens from the LLM! In the case below, we can see the START of a tool call.
```python
StreamPart(event='messages/partial', data=[{'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs', 'function': {'arguments': '', 'name': 'tavily_search_results_json'}, 'type': 'function'}]}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-985c0f14-9f43-40d4-a505-4637fc58e333', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [{'name': 'tavily_search_results_json', 'args': '', 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs', 'error': None}], 'usage_metadata': None}])
```
After that, we get a `messages/complete` event - this is the AIMessage finishing. It's now a complete tool call:
```python
StreamPart(event='messages/complete', data=[{'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs', 'function': {'arguments': '{"query":"current weather in San Francisco"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}]}, 'response_metadata': {'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_157b3831f5'}, 'type': 'ai', 'name': None, 'id': 'run-985c0f14-9f43-40d4-a505-4637fc58e333', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'current weather in San Francisco'}, 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs'}], 'invalid_tool_calls': [], 'usage_metadata': None}])
```
After that, we get ANOTHER `messages/complete` event. This is a tool message - our agent has called a tool, gotten a response, and now inserting it into the state in the form of a tool message.
```python
StreamPart(event='messages/complete', data=[{'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'San Francisco\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 37.78, \'lon\': -122.42, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1724877689, \'localtime\': \'2024-08-28 13:41\'}, \'current\': {\'last_updated_epoch\': 1724877000, \'last_updated\': \'2024-08-28 13:30\', \'temp_c\': 23.3, \'temp_f\': 73.9, \'is_day\': 1, \'condition\': {\'text\': \'Partly cloudy\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/116.png\', \'code\': 1003}, \'wind_mph\': 15.0, \'wind_kph\': 24.1, \'wind_degree\': 310, \'wind_dir\': \'NW\', \'pressure_mb\': 1014.0, \'pressure_in\': 29.93, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 57, \'cloud\': 25, \'feelslike_c\': 25.0, \'feelslike_f\': 77.1, \'windchill_c\': 20.9, \'windchill_f\': 69.6, \'heatindex_c\': 23.3, \'heatindex_f\': 74.0, \'dewpoint_c\': 12.9, \'dewpoint_f\': 55.2, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 6.0, \'gust_mph\': 19.5, \'gust_kph\': 31.3}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': '0112eba5-7660-4375-9f24-c7a1d6777b97', 'tool_call_id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs'}])
```
After that, we see the agent doing another LLM call and streaming back a response. We then get an `end` event:
```python
StreamPart(event='end', data=None)
```
And that's it! This is more focused streaming mode specifically focused on streaming back messages. See this [how-to guide](../how-tos/stream_messages.md) for more information.
### Human-in-the-Loop
There are many occasions where the graph cannot run completely autonomously. For instance, the user might need to input some additional arguments to a function call, or select the next edge for the graph to continue on. In these instances, we need to insert some human in the loop interaction, which you can learn about in the [human in the loop how-tos](../how-tos/index.md#human-in-the-loop).
### Double Texting
Many times users might interact with your graph in unintended ways. For instance, a user may send one message and before the graph has finished running send a second message. To solve this issue of "double-texting" (i.e. prompting the graph a second time before the first run has finished), LangGraph has provided four different solutions, all of which are covered in the [Double Texting how-tos](../how-tos/index.md#double-texting). These options are:
- `reject`: This is the simplest option, this just rejects any follow up runs and does not allow double texting. See the [how-to guide](../how-tos/reject_concurrent.md) for configuring the reject double text option.
- `enqueue`: This is a relatively simple option which continues the first run until it completes the whole run, then sends the new input as a separate run. See the [how-to guide](../how-tos/enqueue_concurrent.md) for configuring the enqueue double text option.
- `interrupt`: This option interrupts the current execution but saves all the work done up until that point. It then inserts the user input and continues from there. If you enable this option, your graph should be able to handle weird edge cases that may arise. See the [how-to guide](../how-tos/interrupt_concurrent.md) for configuring the interrupt double text option.
- `rollback`: This option rolls back all work done up until that point. It then sends the user input in, basically as if it just followed the original run input. See the [how-to guide](../how-tos/rollback_concurrent.md) for configuring the rollback double text option.
### Stateless Runs
All runs use the built-in checkpointer to store checkpoints for runs. However, it can often be useful to just kick off a run without worrying about explicitly creating a thread and without wanting to keep those checkpointers around. Stateless runs allow you to do this by exposing an endpoint that:
- Takes in user input
- Under the hood, creates a thread
- Runs the agent but skips all checkpointing steps
- Cleans up the thread afterwards
Stateless runs are still retried as regular retries are per node, while everything still in memory, so doesn't use checkpoints.
The only difference is in stateless background runs, if the task worker dies halfway (not because the run itself failed, for some external reason) then the whole run will be retried like any background run, but
- whereas a stateful background run would retry from the last successful checkpoint
- a stateless background run would retry from the beginning
See the [how-to guide](../how-tos/stateless_runs.md) for creating stateless runs.
### Webhooks
For all types of runs, langgraph cloud supports completion webhooks. When you create the run you can pass a webhook URL to be called when the completes (successfully or not). This is especially useful for background runs and cron jobs, as the webhook can give you an indication the run has completed and you can perform further actions for your appilcation.
See this [how-to guide](../how-tos/webhooks.md) to learn about how to use webhooks with LangGraph Cloud.
## Deployment
The LangGraph Cloud offers several features to support secure and robost deployments.
### Authentication
LangGraph applications deployed to LangGraph Cloud are automatically configured with LangSmith authentication. In order to call the API, a valid <a href="https://docs.smith.langchain.com/how_to_guides/setup/create_account_api_key#api-keys" target="_blank">LangSmith API key</a> is required.
### Local Testing
Before deploying your app in production to LangGraph Cloud, you may wish to test out your graph locally in order to ensure that everything is running as expected. Luckily, LangGraph makes this easy for you through use of the LangGraph CLI. Read more in this [how-to guide](../deployment/test_locally.md) or look at the [CLI reference](../reference/cli.md) to learn more.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 KiB

-28
View File
@@ -1,28 +0,0 @@
# Cloud Concepts
This page describes the high-level concepts of the LangGraph Cloud deployment.
## Deployment
A deployment is an instance of a LangGraph API. A single deployment can have many [revisions](#revision). When a deployment is created, all of the necessary infrastructure (e.g. database, containers, secrets store) are automatically provisioned. See the [architecture diagram](#architecture) below for more details.
See the [how-to guide](../deployment/cloud.md#create-new-deployment) for creating a new deployment.
## Revision
A revision is an iteration of a [deployment](#deployment). When a new deployment is created, an initial revision is automatically created. To deploy new code changes or update environment variable configurations for a deployment, a new revision must be created. When a revision is created, a new container image is built automatically.
See the [how-to guide](../deployment/cloud.md#create-new-revision) for creating a new revision.
## Asynchronous Deployment
Infrastructure for [deployments](#deployment) and [revisions](#revision) are provisioned and deployed asynchronously. They are not deployed immediately after submission. Currently, deployment can take up to several minutes.
## Architecture
!!! warning "Subject to Change"
The LangGraph Cloud deployment architecture may change in the future.
A high-level diagram of a LangGraph Cloud deployment.
![diagram](langgraph_cloud_architecture.png)
+6 -6
View File
@@ -11,7 +11,7 @@ LangGraph Cloud is available within <a href="https://www.langchain.com/langsmith
Starting from the <a href="https://smith.langchain.com/" target="_blank">LangSmith UI</a>...
1. In the left-hand navigation panel, select `Deployments`. The `Deployments` view contains a list of existing LangGraph Cloud deployments.
1. In the left-hand navigation panel, select `LangGraph Cloud`. The `LangGraph Cloud` view contains a list of existing LangGraph Cloud deployments.
1. In the top-right corner, select `+ New Deployment` to create a new deployment.
1. In the `Create New Deployment` panel, fill out the required fields.
1. `Deployment details`
@@ -38,7 +38,7 @@ When [creating a new deployment](#create-new-deployment), a new revision is crea
Starting from the <a href="https://smith.langchain.com/" target="_blank">LangSmith UI</a>...
1. In the left-hand navigation panel, select `Deployments`. The `Deployments` view contains a list of existing LangGraph Cloud deployments.
1. In the left-hand navigation panel, select `LangGraph Cloud`. The `LangGraph Cloud` view contains a list of existing LangGraph Cloud deployments.
1. Select an existing deployment to create a new revision for.
1. In the `Deployment` view, in the top-right corner, select `+ New Revision`.
1. In the `New Revision` modal, fill out the required fields.
@@ -56,7 +56,7 @@ Starting from the <a href="https://smith.langchain.com/" target="_blank">LangSmi
Build and deployment logs are available for each revision.
Starting from the `Deployment` view...
Starting from the `LangGraph Cloud` view...
1. Select the desired revision from the `Revisions` table. A panel slides open from the right-hand side and the `Build` tab is selected by default, which displays build logs for the revision.
1. In the panel, select the `Deploy` tab to view deployment logs for the revision.
@@ -69,7 +69,7 @@ Interrupting a revision will stop deployment of the revision.
!!! warning "Undefined Behavior"
Interrupted revisions have undefined behavior. This is only useful if you need to deploy a new revision and you already have a revision "stuck" in progress. In the future, this feature may be removed.
Starting from the `Deployment` view...
Starting from the `LangGraph Cloud` view...
1. Select the menu icon (three dots) on the right-hand side of the row for the desired revision from the `Revisions` table.
1. Select `Interrupt` from the menu.
@@ -79,13 +79,13 @@ Starting from the `Deployment` view...
Starting from the <a href="https://smith.langchain.com/" target="_blank">LangSmith UI</a>...
1. In the left-hand navigation panel, select `Deployments`. The `Deployments` view contains a list of existing LangGraph Cloud deployments.
1. In the left-hand navigation panel, select `LangGraph Cloud`. The `LangGraph Cloud` view contains a list of existing LangGraph Cloud deployments.
1. Select the menu icon (three dots) on the right-hand side of the row for the desired deployment and select `Delete`.
1. A `Confirmation` modal will appear. Select `Delete`.
## Deployment Settings
Starting from the `Deployment` view...
Starting from the `LangGraph Cloud` view...
1. In the top-right corner, select the gear icon (`Deployment Settings`).
1. Update the `Git Branch` to the desired branch.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 453 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 KiB

+18 -12
View File
@@ -8,19 +8,25 @@ Testing locally ensures that there are no errors or conflicts with Python depend
Install the proper packages:
```shell
pip install langgraph-cli
```
Ensure you have an API key, which you can create from the LangSmith UI (Settings > API Keys). This is required to authenticate that you have LangGraph Cloud access. After you have saved the key to a safe place, place the following line in your `.env` file:
=== "pip"
```bash
pip install -U langgraph-cli
```
=== "Homebrew (macOS only)"
```bash
brew install langgraph-cli
```
Ensure you have an API key, which you can create from the [LangSmith UI](https://smith.langchain.com) (Settings > API Keys). This is required to authenticate that you have LangGraph Cloud access. After you have saved the key to a safe place, place the following line in your `.env` file:
```python
LANGCHAIN_API_KEY = *********
LANGSMITH_API_KEY = *********
```
## Start the API server
Once you have downloaded the CLI, you can run the following command to start the API server for local testing:
Once you have installed the CLI, you can run the following command to start the API server for local testing:
```shell
langgraph up
@@ -48,7 +54,7 @@ You can either initialize by passing authentication or by setting an environment
from langgraph_sdk import get_client
# only pass the url argument to get_client() if you changed the default port when calling langgraph up
client = get_client(url=<DEPLOYMENT_URL>,api_key=<LANGCHAIN_API_KEY>)
client = get_client(url=<DEPLOYMENT_URL>,api_key=<LANGSMITH_API_KEY>)
# Using the graph deployed with the name "agent"
assistant_id = "agent"
thread = await client.threads.create()
@@ -60,7 +66,7 @@ You can either initialize by passing authentication or by setting an environment
import { Client } from "@langchain/langgraph-sdk";
// only set the apiUrl if you changed the default port when calling langgraph up
const client = new Client({ apiUrl: <DEPLOYMENT_URL>, apiKey: <LANGCHAIN_API_KEY> });
const client = new Client({ apiUrl: <DEPLOYMENT_URL>, apiKey: <LANGSMITH_API_KEY> });
// Using the graph deployed with the name "agent"
const assistantId = "agent";
const thread = await client.threads.create();
@@ -72,13 +78,13 @@ You can either initialize by passing authentication or by setting an environment
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
--header 'x-api-key: <LANGCHAIN_API_KEY>'
--header 'x-api-key: <LANGSMITH_API_KEY>'
```
#### Initialize with environment variables
If you have a `LANGCHAIN_API_KEY` set in your environment, you do not need to explicitly pass authentication to the client
If you have a `LANGSMITH_API_KEY` set in your environment, you do not need to explicitly pass authentication to the client
=== "Python"
@@ -148,7 +154,7 @@ Now we can invoke our graph to ensure it is working. Make sure to change the inp
}
```
=== "CURL"
=== "CURL"
```bash
curl --request POST \
@@ -183,4 +189,4 @@ Now we can invoke our graph to ensure it is working. Make sure to change the inp
'
```
If your graph works correctly, you should see your graph output displayed in the console. Of course, there are many more ways you might need to test your graph, for a full list of commands you can send with the SDK, see the [Python](https://langchain-ai.github.io/langgraph/cloud/reference/sdk/python_sdk_ref/) and [JS/TS](https://langchain-ai.github.io/langgraph/cloud/reference/sdk/js_ts_sdk_ref/) references.
If your graph works correctly, you should see your graph output displayed in the console. Of course, there are many more ways you might need to test your graph, for a full list of commands you can send with the SDK, see the [Python](https://langchain-ai.github.io/langgraph/cloud/reference/sdk/python_sdk_ref/) and [JS/TS](https://langchain-ai.github.io/langgraph/cloud/reference/sdk/js_ts_sdk_ref/) references.
+13 -13
View File
@@ -1,6 +1,6 @@
# How to version assistants
In this how-to guide we will walk through how you can create and manage different assistant versions. If you haven't already, you can read [this](../concepts/api.md/#versioning-assistants) conceptual guide to gain a better understanding of what assistant versioning is. This how-to assumes you have a graph that is configurable, which means you have defined a config schema and passed it to your graph as follows:
In this how-to guide we will walk through how you can create and manage different assistant versions. If you haven't already, you can read [this](../../concepts/assistants.md#versioning-assistants) conceptual guide to gain a better understanding of what assistant versioning is. This how-to assumes you have a graph that is configurable, which means you have defined a config schema and passed it to your graph as follows:
=== "Python"
@@ -86,19 +86,19 @@ To create an assistant using the studio do the following steps:
1. Click on the "Create New Assistant" button:
![click create](./img/click_create_assistant.png)
![click create](./img/click_create_assistant.png)
2. Use the create assistant pane to enter info for the assistant you wish to create, and then click create:
1. Use the create assistant pane to enter info for the assistant you wish to create, and then click create:
![create](./img/create_assistant.png)
![create](./img/create_assistant.png)
3. See that your assistant was created and is displayed in the Studio
1. See that your assistant was created and is displayed in the Studio
![view create](./img/create_assistant_view.png)
![view create](./img/create_assistant_view.png)
4. Click on the edit button next to the selected assistant to manage your created assistant:
1. Click on the edit button next to the selected assistant to manage your created assistant:
![create edit](./img/edit_created_assistant.png)
![create edit](./img/edit_created_assistant.png)
## Create a new version for your assistant
@@ -131,15 +131,15 @@ Let's now say we wanted to add a system prompt to our assistant. We can do this
1. First, click on the edit button next to the `openai_assistant`. Then, add a system prompt and click "Save New Version":
![create new version](./img/create_new_version.png)
![create new version](./img/create_new_version.png)
2. Then you can see it is selected in the assistant dropdown:
1. Then you can see it is selected in the assistant dropdown:
![see version dropdown](./img/see_new_version.png)
![see version dropdown](./img/see_new_version.png)
3. And you can see all the version history in the edit pane for the assistant:
1. And you can see all the version history in the edit pane for the assistant:
![see versions](./img/see_version_history.png)
![see versions](./img/see_version_history.png)
## Point your assistant to a different version
+1 -1
View File
@@ -4,7 +4,7 @@ You may wish to copy (i.e. "fork") an existing thread in order to keep the exist
## Setup
This code assumes you already have a thread to copy. You can read about what a thread is [here](https://langchain-ai.github.io/langgraph/cloud/concepts/api/#threads) and learn how to stream a run on a thread in [these how-to guides](https://langchain-ai.github.io/langgraph/cloud/how-tos/#streaming).
This code assumes you already have a thread to copy. You can read about what a thread is [here](../../concepts/langgraph_server.md#threads) and learn how to stream a run on a thread in [these how-to guides](../../how-tos/index.md#streaming_1).
### SDK initialization
@@ -1,6 +1,6 @@
# Enqueue
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide](../concepts/api.md#double-texting).
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide](../../concepts/double_texting.md).
The guide covers the `enqueue` option for double texting, which adds the interruptions to a queue and executes them in the order they are received by the client. Below is a quick example of using the `enqueue` option.
@@ -6,7 +6,7 @@ This can be in several ways, but the primary supported way is to add an "interru
## Setup
We are not going to show the full code for the graph we are hosting, but you can see it [here](../../how-tos/human_in_the_loop/edit-graph-state.ipynb#build-the-agent) if you want to. Once this graph is hosted, we are ready to invoke it and wait for user input.
We are not going to show the full code for the graph we are hosting, but you can see it [here](../../how-tos/human_in_the_loop/edit-graph-state.ipynb#agent) if you want to. Once this graph is hosted, we are ready to invoke it and wait for user input.
### SDK initialization
@@ -14,7 +14,7 @@ Luckily, LangGraph makes it possible to do similar things in a production way. T
## Setup
We are not going to show the full code for the graph we are hosting, but you can see it [here](../../how-tos/human_in_the_loop/wait-user-input.ipynb#build-the-agent) if you want to. Once this graph is hosted, we are ready to invoke it and wait for user input.
We are not going to show the full code for the graph we are hosting, but you can see it [here](../../how-tos/human_in_the_loop/wait-user-input.ipynb#agent) if you want to. Once this graph is hosted, we are ready to invoke it and wait for user input.
### SDK initialization
-84
View File
@@ -1,84 +0,0 @@
---
hide:
- toc
---
# How-to Guides
Welcome to the LangGraph Cloud how-to guides! These guides provide practical, step-by-step instructions for accomplishing key tasks in LangGraph Cloud.
## Setup
LangGraph Cloud gives you best in class observability, testing, and hosting services. Learn how to setup your app for deployment to LangGraph Cloud in these how-to guides
- [How to set up app for deployment (requirements.txt)](../deployment/setup.md)
- [How to set up app for deployment (pyproject.toml)](../deployment/setup_pyproject.md)
- [How to set up app for deployment (JavaScript)](../deployment/setup_javascript.md)
- [How to customize Dockerfile](../deployment/custom_docker.md)
- [How to test locally](../deployment/test_locally.md)
## Deploy
Learn how to deploy your app to LangGraph Cloud in these how to guides:
- [How to deploy to LangGraph cloud](../deployment/cloud.md)
## Streaming
Streaming the results of your LLM application is vital for ensuring a good user experience, especially when your graph may call multiple models and take a long time to fully complete a run. Read about how to stream values from your graph in these how to guides:
- [How to stream values](./stream_values.md)
- [How to stream updates](./stream_updates.md)
- [How to stream messages](./stream_messages.md)
- [How to stream events](./stream_events.md)
- [How to stream in debug mode](./stream_debug.md)
- [How to stream multiple modes](./stream_multiple.md)
## Double-texting
Graph execution can take a while, and sometimes users may change their mind about the input they wanted to send before their original input has finished running. For example, a user might notice a typo in their original request and will edit the prompt and resend it. Deciding what to do in these cases is important for ensuring a smooth user experience and preventing your graphs from behaving in unexpected ways. The following how-to guides provide information on the various options LangGraph Cloud gives you for dealing with double-texting:
- [How to use the interrupt option](./interrupt_concurrent.md)
- [How to use the rollback option](./rollback_concurrent.md)
- [How to use the reject option](./reject_concurrent.md)
- [How to use the enqueue option](./enqueue_concurrent.md)
## Human-in-the-loop
When creating complex graphs, leaving every decision up to the LLM can be dangerous, especially when the decisions involve invoking certain tools or accessing specific documents. To remedy this, LangGraph allows you to insert human-in-the-loop behavior to ensure your graph does not have undesired outcomes. Read more about the different ways you can add human-in-the-loop capabilities to your LangGraph Cloud projects in these how-to guides:
- [How to add a breakpoint](./human_in_the_loop_breakpoint.md)
- [How to wait for user input](./human_in_the_loop_user_input.md)
- [How to edit graph state](./human_in_the_loop_edit_state.md)
- [How to replay and branch from prior states](./human_in_the_loop_time_travel.md)
- [How to review tool calls](./human_in_the_loop_review_tool_calls.md)
## LangGraph Studio
LangGraph Studio is a built-in UI for visualizing, testing, and debugging your agents.
- [How to enter LangGraph Studio](./test_deployment.md)
- [How to enter LangGraph Studio for local deployment](./test_local_deployment.md)
- [How to test your graph in LangGraph Studio](./invoke_studio.md)
- [Interact with threads in LangGraph Studio](./threads_studio.md)
## Different Types of Runs:
LangGraph Cloud supports multiple types of runs besides streaming runs.
- [How to run an agent in the background](./background_run.md)
- [How to run multiple agents in the same thread](./same-thread.md)
- [How to create cron jobs](./cron_jobs.md)
- [How to create stateless runs](./stateless_runs.md)
## Other
Other guides that may prove helpful!
- [How to configure agents](./configuration_cloud.md)
- [How to version assistants](./assistant_versioning.md)
- [How to convert LangGraph calls to LangGraph cloud calls](./langgraph_to_langgraph_cloud.ipynb)
- [How to integrate webhooks](./webhooks.md)
- [How to copy threads](./copy_threads.md)
- [How to check status of your threads](./check_thread_status.md)
@@ -1,6 +1,6 @@
# Interrupt
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide](../concepts/api.md#double-texting).
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide](../../concepts/double_texting.md).
The guide covers the `interrupt` option for double texting, which interrupts the prior run of the graph and starts a new one with the double-text. This option does not delete the first run, but rather keeps it in the database but sets its status to `interrupted`. Below is a quick example of using the `interrupt` option.
@@ -94,6 +94,7 @@ Now we can start our two runs and join the second on euntil it has completed:
assistant_id,
input={"messages": [{"role": "user", "content": "what's the weather in sf?"}]},
)
# sleep a bit to get partial outputs from the first run
await asyncio.sleep(2)
run = await client.runs.create(
thread["thread_id"],
@@ -114,6 +115,7 @@ Now we can start our two runs and join the second on euntil it has completed:
assistantId,
{ input: { messages: [{ role: "human", content: "what's the weather in sf?" }] } }
);
// sleep a bit to get partial outputs from the first run
await new Promise(resolve => setTimeout(resolve, 2000));
let run = await client.runs.create(
+1 -1
View File
@@ -1,6 +1,6 @@
# Reject
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide][double-texting].
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide](../../concepts/double_texting.md).
The guide covers the `reject` option for double texting, which rejects the new run of the graph by throwing an error and continues with the original run until completion. Below is a quick example of using the `reject` option.
@@ -1,6 +1,6 @@
# Rollback
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide][double-texting].
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide](../../concepts/double_texting.md).
The guide covers the `rollback` option for double texting, which interrupts the prior run of the graph and starts a new one with the double-text. This option is very similar to the `interrupt` option, but in this case the first run is completely deleted from the database and cannot be restarted. Below is a quick example of using the `rollback` option.
@@ -95,7 +95,6 @@ Now let's run a thread with the multitask parameter set to "rollback":
assistant_id,
input={"messages": [{"role": "user", "content": "what's the weather in sf?"}]},
)
await asyncio.sleep(2)
run = await client.runs.create(
thread["thread_id"],
assistant_id,
@@ -115,7 +114,6 @@ Now let's run a thread with the multitask parameter set to "rollback":
assistantId,
{ input: { messages: [{ role: "human", content: "what's the weather in sf?" }] } }
);
await new Promise(resolve => setTimeout(resolve, 2000));
let run = await client.runs.create(
thread["thread_id"],
@@ -139,7 +137,7 @@ Now let's run a thread with the multitask parameter set to "rollback":
--data "{
\"assistant_id\": \"agent\",
\"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"what\'s the weather in sf?\"}]},
}" && sleep 2 && curl --request POST \
}" && curl --request POST \
--url <DEPLOY<ENT_URL>>/threads/<THREAD_ID>/runs \
--header 'Content-Type: application/json' \
--data "{
+3
View File
@@ -1,5 +1,8 @@
# How to stream debug events
!!! info "Prerequisites"
* [Streaming](../../concepts/streaming.md)
This guide covers how to stream debug events from your graph (`stream_mode="debug"`). Streaming debug events produces responses containing `type` and `timestamp` keys. Debug events correspond to different steps in the graph's execution, and there are three different types of steps that will get streamed back to you:
- `checkpoint`: These events will get streamed anytime the graph saves its state, which occurs after every super-step. Read more about checkpoints [here](https://langchain-ai.github.io/langgraph/concepts/low_level/#checkpointer)
+5 -129
View File
@@ -1,6 +1,9 @@
# How to stream events
This guide covers how to stream events from your graph (`stream_mode="events"`). Depending on the use case and user experience of your LangGraph application, your application may process event types differently. Read more about events in this [conceptual guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#astream_events-for-streaming-tokens-of-llm-calls).
!!! info "Prerequisites"
* [Streaming](../../concepts/streaming.md#streaming-llm-tokens-and-events-astream_events)
This guide covers how to stream events from your graph (`stream_mode="events"`). Depending on the use case and user experience of your LangGraph application, your application may process event types differently.
## Setup
@@ -289,131 +292,4 @@ Output:
Receiving new event of type: end...
None
## Token-by-Token Streaming
Token-by-token streaming can be implemented with the `events` streaming mode. The `on_chat_model_stream` event type should be processed to stream LLM responses token-by-token.
=== "Python"
```python
llm_response = ""
# stream token-by-token
async for chunk in client.runs.stream(
thread_id=thread["thread_id"],
assistant_id=assistant_id,
input=input,
stream_mode="events",
):
if (
chunk.event == "events" and
chunk.data["event"] == "on_chat_model_stream" and
len(chunk.data["data"]["chunk"]["content"]) > 0 and
'text' in chunk.data["data"]["chunk"]["content"][0]
):
llm_response += chunk.data["data"]["chunk"]["content"][0]['text']
print(llm_response)
```
=== "Javascript"
```js
const llmResponse = "";
// stream events
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantID,
{
input,
streamMode: "events"
}
);
for await (const chunk of streamResponse) {
if (chunk.event === "events" && chunk.data.event === "on_chat_model_stream" && chunk.data.chunk.content.length > 0 && 'text' in chunk.data.chunk.content[0]) {
llmResponse += chunk.data.data.chunk.content[0].text;
console.log(llmResponse);
}
}
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": \"agent\",
\"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"What's the weather in sf\"}]},
\"stream_mode\": [
\"events\"
]
}" | sed 's/\r$//' | awk '
/^event:/ { event = $2 }
/^data:/ {
json_data = substr($0, index($0, $2))
if (event == "events") {
print json_data
}
}' | jq -r '
select(.event == "on_chat_model_stream") |
.data.chunk.content[] | .text // empty
' | awk '
BEGIN { llm_response="" }
$0 != "" && $0 != "null" {
llm_response = llm_response $0
print llm_response
}'
```
Output:
The
The search
The search results provide
The search results provide the current weather conditions
The search results provide the current weather conditions in San Francisco.
The search results provide the current weather conditions in San Francisco. According
The search results provide the current weather conditions in San Francisco. According to the data,
The search results provide the current weather conditions in San Francisco. According to the data, as
The search results provide the current weather conditions in San Francisco. According to the data, as of 3
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12,
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024,
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C).
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The win
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is bl
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 k
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph).
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70%
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles (10 km
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles (10 km).
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles (10 km). Overall
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles (10 km). Overall, it appears
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles (10 km). Overall, it appears to be a nice
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles (10 km). Overall, it appears to be a nice sunny day in San
The search results provide the current weather conditions in San Francisco. According to the data, as of 3:19 PM on August 12, 2024, the weather in San Francisco is sunny with a temperature of 60.8°F (16°C). The wind is blowing from the west-southwest at 13.4 mph (21.6 kph). The humidity is 70% and visibility is 6 miles (10 km). Overall, it appears to be a nice sunny day in San Francisco.
None
+226 -392
View File
@@ -1,43 +1,9 @@
# How to stream messages from your graph
This guide covers how to stream messages from your graph. In order to use this mode, the state of the graph you are interacting with MUST have a `messages` key that is a list of messages.
!!! info "Prerequisites"
* [Streaming](../../concepts/streaming.md)
E.g., the state should look something like:
=== "Python"
```python
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import add_messages
from langchain_core.messages import AnyMessage
class State(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
```
=== "Javascript"
```js
import { type BaseMessage } from "@langchain/core/messages";
import { Annotation, messagesStateReducer } from "@langchain/langgraph";
export const StateAnnotation = Annotation.Root({
messages: Annotation<BaseMessage[]>({
reducer: messagesStateReducer,
default: () => [],
}),
});
```
Alternatively, you can use an instance or subclass of `from langgraph.graph import MessagesState` (`MessagesState` is equivalent to the implementation above). Or in Javascript: `import { MessagesAnnotation } from "@langchain/langgraph";`.
With `stream_mode="messages"` two things will be streamed back:
- It outputs messages produced by any chat model called inside (unless tagged in a special way)
- It outputs messages returned from nodes (to allow for nodes to return `ToolMessages` and the like)
Read more about how the `messages` streaming mode works [here](https://langchain-ai.github.io/langgraph/cloud/concepts/api/#modemessages)
This guide covers how to stream messages from your graph. With `stream_mode="messages-tuple"`, messages (i.e. individual LLM tokens) from any chat model invocations inside your graph nodes will be streamed back.
## Setup
@@ -90,101 +56,9 @@ Output:
'values': None
}
Let's also define a helper function for better formatting of the tool calls in messages (for CURL we will define a helper script called `process_stream.sh`)
=== "Python"
```python
def format_tool_calls(tool_calls):
if tool_calls:
formatted_calls = []
for call in tool_calls:
formatted_calls.append(
f"Tool Call ID: {call['id']}, Function: {call['name']}, Arguments: {call['args']}"
)
return "\n".join(formatted_calls)
return "No tool calls"
```
=== "Javascript"
```js
function formatToolCalls(toolCalls) {
if (toolCalls && toolCalls.length > 0) {
const formattedCalls = toolCalls.map(call => {
return `Tool Call ID: ${call.id}, Function: ${call.name}, Arguments: ${call.args}`;
});
return formattedCalls.join("\n");
}
return "No tool calls";
}
```
=== "CURL"
```bash
# process_stream.sh
format_tool_calls() {
echo "$1" | jq -r 'map("Tool Call ID: \(.id), Function: \(.name), Arguments: \(.args)") | join("\n")'
}
process_data_item() {
local data_item="$1"
if echo "$data_item" | jq -e '.role == "user"' > /dev/null; then
echo "Human: $(echo "$data_item" | jq -r '.content')"
else
local tool_calls=$(echo "$data_item" | jq -r '.tool_calls // []')
local invalid_tool_calls=$(echo "$data_item" | jq -r '.invalid_tool_calls // []')
local content=$(echo "$data_item" | jq -r '.content // ""')
local response_metadata=$(echo "$data_item" | jq -r '.response_metadata // {}')
if [ -n "$content" ] && [ "$content" != "null" ]; then
echo "AI: $content"
fi
if [ "$tool_calls" != "[]" ]; then
echo "Tool Calls:"
format_tool_calls "$tool_calls"
fi
if [ "$invalid_tool_calls" != "[]" ]; then
echo "Invalid Tool Calls:"
format_tool_calls "$invalid_tool_calls"
fi
if [ "$response_metadata" != "{}" ]; then
local finish_reason=$(echo "$response_metadata" | jq -r '.finish_reason // "N/A"')
echo "Response Metadata: Finish Reason - $finish_reason"
fi
fi
}
while IFS=': ' read -r key value; do
case "$key" in
event)
event="$value"
;;
data)
if [ "$event" = "metadata" ]; then
run_id=$(echo "$value" | jq -r '.run_id')
echo "Metadata: Run ID - $run_id"
echo "------------------------------------------------"
elif [ "$event" = "messages/partial" ]; then
echo "$value" | jq -c '.[]' | while read -r data_item; do
process_data_item "$data_item"
done
echo "------------------------------------------------"
fi
;;
esac
done
```
## Stream graph in messages mode
Now we can stream by messages, which will return complete messages (at the end of node execution) as well as tokens for any messages generated inside a node:
Now we can stream LLM tokens for any messages generated inside a node in the form of tuples `(message, metadata)`. Metadata contains additional information that can be useful for filtering the streamed outputs to a specific node or LLM.
=== "Python"
@@ -192,41 +66,16 @@ Now we can stream by messages, which will return complete messages (at the end o
input = {"messages": [{"role": "user", "content": "what's the weather in sf"}]}
config = {"configurable": {"model_name": "openai"}}
async for event in client.runs.stream(
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id=assistant_id,
input=input,
config=config,
stream_mode="messages",
stream_mode="messages-tuple",
):
if event.event == "metadata":
print(f"Metadata: Run ID - {event.data['run_id']}")
print("-" * 50)
elif event.event == "messages/partial":
for data_item in event.data:
if "role" in data_item and data_item["role"] == "user":
print(f"Human: {data_item['content']}")
else:
tool_calls = data_item.get("tool_calls", [])
invalid_tool_calls = data_item.get("invalid_tool_calls", [])
content = data_item.get("content", "")
response_metadata = data_item.get("response_metadata", {})
if content:
print(f"AI: {content}")
if tool_calls:
print("Tool Calls:")
print(format_tool_calls(tool_calls))
if invalid_tool_calls:
print("Invalid Tool Calls:")
print(format_tool_calls(invalid_tool_calls))
if response_metadata:
finish_reason = response_metadata.get("finish_reason", "N/A")
print(f"Response Metadata: Finish Reason - {finish_reason}")
print("-" * 50)
print(f"Receiving new event of type: {chunk.event}...")
print(chunk.data)
print("\n\n")
```
=== "Javascript"
@@ -248,46 +97,13 @@ Now we can stream by messages, which will return complete messages (at the end o
{
input,
config,
streamMode: "messages"
streamMode: "messages-tuple"
}
);
for await (const event of streamResponse) {
if (event.event === "metadata") {
console.log(`Metadata: Run ID - ${event.data.run_id}`);
console.log("-".repeat(50));
} else if (event.event === "messages/partial") {
event.data.forEach(dataItem => {
if (dataItem.role && dataItem.role === "user") {
console.log(`Human: ${dataItem.content}`);
} else {
const toolCalls = dataItem.tool_calls || [];
const invalidToolCalls = dataItem.invalid_tool_calls || [];
const content = dataItem.content || "";
const responseMetadata = dataItem.response_metadata || {};
if (content) {
console.log(`AI: ${content}`);
}
if (toolCalls.length > 0) {
console.log("Tool Calls:");
console.log(formatToolCalls(toolCalls));
}
if (invalidToolCalls.length > 0) {
console.log("Invalid Tool Calls:");
console.log(formatToolCalls(invalidToolCalls));
}
if (responseMetadata) {
const finishReason = responseMetadata.finish_reason || "N/A";
console.log(`Response Metadata: Finish Reason - ${finishReason}`);
}
}
});
console.log("-".repeat(50));
}
for await (const chunk of streamResponse) {
console.log(`Receiving new event of type: ${chunk.event}...`);
console.log(chunk.data);
console.log("\n\n");
}
```
@@ -295,203 +111,221 @@ Now we can stream by messages, which will return complete messages (at the end o
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": \"agent\",
\"config\":{\"configurable\":{\"model_name\":\"openai\"}},
\"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"What's the weather in sf\"}]},
\"stream_mode\": [
\"messages\"
]
}" | sed 's/\r$//' | ./process_stream.sh
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": \"agent\",
\"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"what's the weather in la\"}]},
\"stream_mode\": [
\"messages-tuple\"
]
}" | \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "") {
print data_content "\n"
}
sub(/^event: /, "Receiving event of type: ", $0)
printf "%s...\n", $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "") {
print data_content "\n"
}
}
'
```
Output:
Metadata: Run ID - 1ef2fe5c-6a1d-6575-bc09-d7832711c17e
--------------------------------------------------
Invalid Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments:
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': ''}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current'}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather'}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in'}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San'}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San Francisco'}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San Francisco'}
--------------------------------------------------
Tool Calls:
Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San Francisco'}
Response Metadata: Finish Reason - tool_calls
--------------------------------------------------
--------------------------------------------------
AI: The
--------------------------------------------------
AI: The current
--------------------------------------------------
AI: The current weather
--------------------------------------------------
AI: The current weather in
--------------------------------------------------
AI: The current weather in San
--------------------------------------------------
AI: The current weather in San Francisco
--------------------------------------------------
AI: The current weather in San Francisco is
--------------------------------------------------
AI: The current weather in San Francisco is over
--------------------------------------------------
AI: The current weather in San Francisco is overcast
--------------------------------------------------
AI: The current weather in San Francisco is overcast with
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F).
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-s
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-south
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 k
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph).
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%,
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles).
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is 3
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is 3.
--------------------------------------------------
AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is 3.
Response Metadata: Finish Reason - stop
--------------------------------------------------
Receiving new event of type: metadata...
{"run_id": "1ef971e0-9a84-6154-9047-247b4ce89c4d", "attempt": 1}
...
Receiving new event of type: messages...
[
{
"type": "AIMessageChunk",
"tool_calls": [
{
"name": "tavily_search_results_json",
"args": {
"query": "weat"
},
"id": "toolu_0114XKXdNtHQEa3ozmY1uDdM",
"type": "tool_call"
}
],
...
},
{
"graph_id": "agent",
"langgraph_node": "agent",
...
}
]
Receiving new event of type: messages...
[
{
"type": "AIMessageChunk",
"tool_calls": [
{
"name": "tavily_search_results_json",
"args": {
"query": "her in san "
},
"id": "toolu_0114XKXdNtHQEa3ozmY1uDdM",
"type": "tool_call"
}
],
...
},
{
"graph_id": "agent",
"langgraph_node": "agent",
...
}
]
...
Receiving new event of type: messages...
[
{
"type": "AIMessageChunk",
"tool_calls": [
{
"name": "tavily_search_results_json",
"args": {
"query": "francisco"
},
"id": "toolu_0114XKXdNtHQEa3ozmY1uDdM",
"type": "tool_call"
}
],
...
},
{
"graph_id": "agent",
"langgraph_node": "agent",
...
}
]
...
Receiving new event of type: messages...
[
{
"content": "[{\"url\": \"https://www.weatherapi.com/\", \"content\": \"{'location': {'name': 'San Francisco', 'region': 'California', 'country': 'United States of America', 'lat': 37.775, 'lon': -122.4183, 'tz_id': 'America/Los_Angeles', 'localtime_epoch': 1730475777, 'localtime': '2024-11-01 08:42'}, 'current': {'last_updated_epoch': 1730475000, 'last_updated': '2024-11-01 08:30', 'temp_c': 11.1, 'temp_f': 52.0, 'is_day': 1, 'condition': {'text': 'Partly cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 192, 'wind_dir': 'SSW', 'pressure_mb': 1018.0, 'pressure_in': 30.07, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 89, 'cloud': 75, 'feelslike_c': 11.5, 'feelslike_f': 52.6, 'windchill_c': 10.0, 'windchill_f': 50.1, 'heatindex_c': 10.4, 'heatindex_f': 50.7, 'dewpoint_c': 9.1, 'dewpoint_f': 48.5, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 3.0, 'gust_mph': 6.7, 'gust_kph': 10.8}}\"}]",
"type": "tool",
"tool_call_id": "toolu_0114XKXdNtHQEa3ozmY1uDdM",
...
},
{
"graph_id": "agent",
"langgraph_node": "action",
...
}
]
...
Receiving new event of type: messages...
[
{
"content": [
{
"text": "\n\nThe search",
"type": "text",
"index": 0
}
],
"type": "AIMessageChunk",
...
},
{
"graph_id": "agent",
"langgraph_node": "agent",
...
}
]
Receiving new event of type: messages...
[
{
"content": [
{
"text": " results provide",
"type": "text",
"index": 0
}
],
"type": "AIMessageChunk",
...
},
{
"graph_id": "agent",
"langgraph_node": "agent",
...
}
]
Receiving new event of type: messages...
[
{
"content": [
{
"text": " the current weather conditions",
"type": "text",
"index": 0
}
],
"type": "AIMessageChunk",
...
},
{
"graph_id": "agent",
"langgraph_node": "agent",
...
}
]
Receiving new event of type: messages...
[
{
"content": [
{
"text": " in San Francisco.",
"type": "text",
"index": 0
}
],
"type": "AIMessageChunk",
...
},
{
"graph_id": "agent",
"langgraph_node": "agent",
...
}
]
...
+4 -16
View File
@@ -1,5 +1,8 @@
# How to configure multiple streaming modes at the same time
!!! info "Prerequisites"
* [Streaming](../../concepts/streaming.md)
This guide covers how to configure multiple streaming modes at the same time.
## Setup
@@ -175,11 +178,6 @@ Output:
Receiving new event of type: messages/complete...
[{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}]
Receiving new event of type: debug...
{'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.117924+00:00', 'step': 0, 'payload': {'config': {'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'callbacks': [None], 'recursion_limit': 25, 'configurable': {'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'thread_ts': '1ef32717-bc81-68c8-8000-4e18ae7d67a5', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}]}, 'metadata': {'source': 'loop', 'step': 0, 'writes': None}}}
@@ -305,11 +303,6 @@ Output:
Receiving new event of type: messages/complete...
[{'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]
Receiving new event of type: debug...
{'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.124510+00:00', 'step': 1, 'payload': {'config': {'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'callbacks': [None], 'recursion_limit': 25, 'configurable': {'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'thread_ts': '1ef32717-bc91-6a34-8001-26353c117c25', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}, 'metadata': {'source': 'loop', 'step': 1, 'writes': {'agent': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}}}}
@@ -469,12 +462,7 @@ Output:
{'event': 'on_chain_stream', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'name': 'LangGraph', 'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'data': {'chunk': ['values', {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}]}, 'parent_ids': []}
Receiving new event of type: messages/complete...
[{'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]
Receiving new event of type: debug...
{'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.134190+00:00', 'step': 3, 'payload': {'config': {'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'callbacks': [None], 'recursion_limit': 25, 'configurable': {'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'thread_ts': '1ef32717-bca9-6418-8003-8d0d0b06845c', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}, 'metadata': {'source': 'loop', 'step': 3, 'writes': {'agent': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}}}}
+68 -20
View File
@@ -1,6 +1,9 @@
# How to stream state updates of your graph
This guide covers how to use `stream_mode="updates"` for your graph, which will stream the updates to the graph state that are made after each node is executed. This differs from using `stream_mode="values"`: instead of streaming the entire value of the state at each superstep, it only streams the updates from each of the nodes that made an update to the state at that superstep. Read [this conceptual guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#stream-and-astream) to learn more.
!!! info "Prerequisites"
* [Streaming](../../concepts/streaming.md)
This guide covers how to use `stream_mode="updates"` for your graph, which will stream the updates to the graph state that are made after each node is executed. This differs from using `stream_mode="values"`: instead of streaming the entire value of the state at each superstep, it only streams the updates from each of the nodes that made an update to the state at that superstep.
## Setup
@@ -146,24 +149,69 @@ Now we can stream by updates, which outputs updates made to the state by each no
Output:
Receiving new event of type: metadata...
{'run_id': 'cfc96c16-ed9a-44bd-b5bb-c30e3c0725f0'}
Receiving new event of type: data...
{'agent': {'messages': [{'content': [{'id': 'toolu_0148tMmDK51iLQfG1yaNwRHM', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-1a9d32b0-7007-4a36-abde-8df812a0ed94', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_0148tMmDK51iLQfG1yaNwRHM'}], 'invalid_tool_calls': []}]}}
Receiving new event of type: data...
{'action': {'messages': [{'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716062239, \'localtime\': \'2024-05-18 12:57\'}, \'current\': {\'last_updated_epoch\': 1716061500, \'last_updated\': \'2024-05-18 12:45\', \'temp_c\': 18.9, \'temp_f\': 66.0, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 2.2, \'wind_kph\': 3.6, \'wind_degree\': 10, \'wind_dir\': \'N\', \'pressure_mb\': 1017.0, \'pressure_in\': 30.02, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 18.9, \'feelslike_f\': 66.0, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 6.0, \'gust_mph\': 7.5, \'gust_kph\': 12.0}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': 'a36e8cd1-0e96-4417-9c15-f10a945d2b42', 'tool_call_id': 'toolu_0148tMmDK51iLQfG1yaNwRHM'}]}}
Receiving new event of type: data...
{'agent': {'messages': [{'content': 'The weather in Los Angeles is currently overcast with a temperature of around 66°F (18.9°C). There are light winds from the north at around 2-3 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-d5c1c2f0-b12d-41ce-990b-f36570e7483d', 'example': False, 'tool_calls': [], 'invalid_tool_calls': []}]}}
{"run_id": "cfc96c16-ed9a-44bd-b5bb-c30e3c0725f0"}
Receiving new event of type: updates...
{
"agent": {
"messages": [
{
"type": "ai",
"tool_calls": [
{
"name": "tavily_search_results_json",
"args": {
"query": "weather in los angeles"
},
"id": "toolu_0148tMmDK51iLQfG1yaNwRHM"
}
],
...
}
]
}
}
Receiving new event of type: updates...
{
"action": {
"messages": [
{
"content": [
{
"url": "https://www.weatherapi.com/",
"content": "{\"location\": {\"name\": \"Los Angeles\", \"region\": \"California\", \"country\": \"United States of America\", \"lat\": 34.05, \"lon\": -118.24, \"tz_id\": \"America/Los_Angeles\", \"localtime_epoch\": 1716062239, \"localtime\": \"2024-05-18 12:57\"}, \"current\": {\"last_updated_epoch\": 1716061500, \"last_updated\": \"2024-05-18 12:45\", \"temp_c\": 18.9, \"temp_f\": 66.0, \"is_day\": 1, \"condition\": {\"text\": \"Overcast\", \"icon\": \"//cdn.weatherapi.com/weather/64x64/day/122.png\", \"code\": 1009}, \"wind_mph\": 2.2, \"wind_kph\": 3.6, \"wind_degree\": 10, \"wind_dir\": \"N\", \"pressure_mb\": 1017.0, \"pressure_in\": 30.02, \"precip_mm\": 0.0, \"precip_in\": 0.0, \"humidity\": 65, \"cloud\": 100, \"feelslike_c\": 18.9, \"feelslike_f\": 66.0, \"vis_km\": 16.0, \"vis_miles\": 9.0, \"uv\": 6.0, \"gust_mph\": 7.5, \"gust_kph\": 12.0}}"
}
],
"type": "tool",
"name": "tavily_search_results_json",
"tool_call_id": "toolu_0148tMmDK51iLQfG1yaNwRHM",
...
}
]
}
}
Receiving new event of type: updates...
{
"agent": {
"messages": [
{
"content": "The weather in Los Angeles is currently overcast with a temperature of around 66°F (18.9°C). There are light winds from the north at around 2-3 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.",
"type": "ai",
...
}
]
}
}
Receiving new event of type: end...
None
+127 -59
View File
@@ -1,6 +1,9 @@
# How to stream full state of your graph
This guide covers how to use `stream_mode="values"`, which streams the value of the state at each superstep. This differs from using `stream_mode="updates"`: instead of streaming just the updates to the state from each node, it streams the entire graph state at that superstep. Read [this conceptual guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#stream-and-astream) to learn more.
!!! info "Prerequisites"
* [Streaming](../../concepts/streaming.md)
This guide covers how to use `stream_mode="values"`, which streams the value of the state at each superstep. This differs from using `stream_mode="updates"`: instead of streaming just the updates to the state from each node, it streams the entire graph state at that superstep.
## Setup
@@ -133,30 +136,93 @@ Now we can stream by values, which streams the full state of the graph after eac
Output:
Receiving new event of type: metadata...
{'run_id': 'f08791ce-0a3d-44e0-836c-ff62cd2e2786'}
{"run_id": "f08791ce-0a3d-44e0-836c-ff62cd2e2786"}
Receiving new event of type: values...
{'messages': [{'role': 'human', 'content': 'what's the weather in la'}]}
{
"messages": [
{
"role": "human",
"content": "what's the weather in la"
}
]
}
Receiving new event of type: values...
{'messages': [{'content': 'what's the weather in la', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'faa15565-8823-4aa1-87af-e21b40526fae', 'example': False}, {'content': [{'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-3fe1db7a-6b8d-4d83-ba07-8657190ad811', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}], 'invalid_tool_calls': []}]}
{
"messages": [
{
"content": "what's the weather in la",
"type": "human",
...
},
{
"content": "",
"type": "ai",
"tool_calls": [
{
"name": "tavily_search_results_json",
"args": {
"query": "weather in los angeles"
},
"id": "toolu_01E5mSaZWm5rWJnCqmt63v4g"
}
],
...
}
]
}
...
Receiving new event of type: values...
{'messages': [{'content': 'what's the weather in la', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'faa15565-8823-4aa1-87af-e21b40526fae', 'example': False}, {'content': [{'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-3fe1db7a-6b8d-4d83-ba07-8657190ad811', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}], 'invalid_tool_calls': []}, {'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716310320, \'localtime\': \'2024-05-21 9:52\'}, \'current\': {\'last_updated_epoch\': 1716309900, \'last_updated\': \'2024-05-21 09:45\', \'temp_c\': 16.7, \'temp_f\': 62.1, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 8.1, \'wind_kph\': 13.0, \'wind_degree\': 250, \'wind_dir\': \'WSW\', \'pressure_mb\': 1015.0, \'pressure_in\': 29.97, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 16.7, \'feelslike_f\': 62.1, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 5.0, \'gust_mph\': 12.5, \'gust_kph\': 20.2}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': '0d5dab31-5ff8-4ae2-a560-bc4bcba7c9d7', 'tool_call_id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}]}
Receiving new event of type: values...
{'messages': [{'content': 'what's the weather in la', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'faa15565-8823-4aa1-87af-e21b40526fae', 'example': False}, {'content': [{'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-3fe1db7a-6b8d-4d83-ba07-8657190ad811', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}], 'invalid_tool_calls': []}, {'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716310320, \'localtime\': \'2024-05-21 9:52\'}, \'current\': {\'last_updated_epoch\': 1716309900, \'last_updated\': \'2024-05-21 09:45\', \'temp_c\': 16.7, \'temp_f\': 62.1, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 8.1, \'wind_kph\': 13.0, \'wind_degree\': 250, \'wind_dir\': \'WSW\', \'pressure_mb\': 1015.0, \'pressure_in\': 29.97, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 16.7, \'feelslike_f\': 62.1, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 5.0, \'gust_mph\': 12.5, \'gust_kph\': 20.2}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': '0d5dab31-5ff8-4ae2-a560-bc4bcba7c9d7', 'tool_call_id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}, {'content': 'Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-4d6d4c23-5aad-4042-b0d9-19407a9e08e3', 'example': False, 'tool_calls': [], 'invalid_tool_calls': []}]}
{
"messages": [
{
"content": "what's the weather in la",
"type": "human",
...
},
{
"content": "",
"type": "ai",
"tool_calls": [
{
"name": "tavily_search_results_json",
"args": {
"query": "weather in los angeles"
},
"id": "toolu_01E5mSaZWm5rWJnCqmt63v4g"
}
],
...
}
{
"content": [
{
"url": "https://www.weatherapi.com/",
"content": "{\"location\": {\"name\": \"Los Angeles\", \"region\": \"California\", \"country\": \"United States of America\", \"lat\": 34.05, \"lon\": -118.24, \"tz_id\": \"America/Los_Angeles\", \"localtime_epoch\": 1716310320, \"localtime\": \"2024-05-21 9:52\"}, \"current\": {\"last_updated_epoch\": 1716309900, \"last_updated\": \"2024-05-21 09:45\", \"temp_c\": 16.7, \"temp_f\": 62.1, \"is_day\": 1, \"condition\": {\"text\": \"Overcast\", \"icon\": \"//cdn.weatherapi.com/weather/64x64/day/122.png\", \"code\": 1009}, \"wind_mph\": 8.1, \"wind_kph\": 13.0, \"wind_degree\": 250, \"wind_dir\": \"WSW\", \"pressure_mb\": 1015.0, \"pressure_in\": 29.97, \"precip_mm\": 0.0, \"precip_in\": 0.0, \"humidity\": 65, \"cloud\": 100, \"feelslike_c\": 16.7, \"feelslike_f\": 62.1, \"vis_km\": 16.0, \"vis_miles\": 9.0, \"uv\": 5.0, \"gust_mph\": 12.5, \"gust_kph\": 20.2}}"
}
],
"type": "tool",
"name": "tavily_search_results_json",
"tool_call_id": "toolu_01E5mSaZWm5rWJnCqmt63v4g"
...
},
{
"content": "Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.",
"type": "ai",
...
}
]
}
Receiving new event of type: end...
None
@@ -228,40 +294,42 @@ If we want to just get the final result, we can use this endpoint and just keep
Output:
{'messages': [{'content': 'what's the weather in la',
'additional_kwargs': {},
'response_metadata': {},
'type': 'human',
'name': None,
'id': 'e78c2f94-d810-42fc-a399-11f6bb1b1092',
'example': False},
{'content': [{'id': 'toolu_01SBMoAGr4U9x3ibztm2UUom',
'input': {'query': 'weather in los angeles'},
'name': 'tavily_search_results_json',
'type': 'tool_use'}],
'additional_kwargs': {},
'response_metadata': {},
'type': 'ai',
'name': None,
'id': 'run-80767ab8-09fc-40ec-9e45-657ddef5e0b1',
'example': False,
'tool_calls': [{'name': 'tavily_search_results_json',
'args': {'query': 'weather in los angeles'},
'id': 'toolu_01SBMoAGr4U9x3ibztm2UUom'}],
'invalid_tool_calls': []},
{'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716310320, \'localtime\': \'2024-05-21 9:52\'}, \'current\': {\'last_updated_epoch\': 1716309900, \'last_updated\': \'2024-05-21 09:45\', \'temp_c\': 16.7, \'temp_f\': 62.1, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 8.1, \'wind_kph\': 13.0, \'wind_degree\': 250, \'wind_dir\': \'WSW\', \'pressure_mb\': 1015.0, \'pressure_in\': 29.97, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 16.7, \'feelslike_f\': 62.1, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 5.0, \'gust_mph\': 12.5, \'gust_kph\': 20.2}}"}]',
'additional_kwargs': {},
'response_metadata': {},
'type': 'tool',
'name': 'tavily_search_results_json',
'id': 'af25e94a-c119-48c3-bbd3-096e42f472ac',
'tool_call_id': 'toolu_01SBMoAGr4U9x3ibztm2UUom'},
{'content': 'Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.',
'additional_kwargs': {},
'response_metadata': {},
'type': 'ai',
'name': None,
'id': 'run-b90f0037-e56a-4f3b-ad92-00d10d079a9e',
'example': False,
'tool_calls': [],
'invalid_tool_calls': []}]}
{
"messages": [
{
"content": "what's the weather in la",
"type": "human",
...
},
{
"type": "ai",
"tool_calls": [
{
"name": "tavily_search_results_json",
"args": {
"query": "weather in los angeles"
},
"id": "toolu_01E5mSaZWm5rWJnCqmt63v4g"
}
],
...
}
{
"content": [
{
"url": "https://www.weatherapi.com/",
"content": "{\"location\": {\"name\": \"Los Angeles\", \"region\": \"California\", \"country\": \"United States of America\", \"lat\": 34.05, \"lon\": -118.24, \"tz_id\": \"America/Los_Angeles\", \"localtime_epoch\": 1716310320, \"localtime\": \"2024-05-21 9:52\"}, \"current\": {\"last_updated_epoch\": 1716309900, \"last_updated\": \"2024-05-21 09:45\", \"temp_c\": 16.7, \"temp_f\": 62.1, \"is_day\": 1, \"condition\": {\"text\": \"Overcast\", \"icon\": \"//cdn.weatherapi.com/weather/64x64/day/122.png\", \"code\": 1009}, \"wind_mph\": 8.1, \"wind_kph\": 13.0, \"wind_degree\": 250, \"wind_dir\": \"WSW\", \"pressure_mb\": 1015.0, \"pressure_in\": 29.97, \"precip_mm\": 0.0, \"precip_in\": 0.0, \"humidity\": 65, \"cloud\": 100, \"feelslike_c\": 16.7, \"feelslike_f\": 62.1, \"vis_km\": 16.0, \"vis_miles\": 9.0, \"uv\": 5.0, \"gust_mph\": 12.5, \"gust_kph\": 20.2}}"
}
],
"type": "tool",
"name": "tavily_search_results_json",
"tool_call_id": "toolu_01E5mSaZWm5rWJnCqmt63v4g"
...
},
{
"content": "Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.",
"type": "ai",
...
}
]
}
+1 -1
View File
@@ -4,7 +4,7 @@ The LangGraph Studio UI connects directly to LangGraph Cloud deployments.
Starting from the <a href="https://smith.langchain.com/" target="_blank">LangSmith UI</a>...
1. In the left-hand navigation panel, select `Deployments`. The `Deployments` view contains a list of existing LangGraph Cloud deployments.
1. In the left-hand navigation panel, select `LangGraph Cloud`. The `LangGraph Cloud` view contains a list of existing LangGraph Cloud deployments.
1. Select an existing deployment to test with LangGraph Studio.
1. In the top-right corner, select `Open LangGraph Studio`.
1. [Invoke an assistant](./invoke_studio.md) or [view an existing thread](./threads_studio.md).
+16 -5
View File
@@ -76,7 +76,9 @@ Output:
## Use graph with a webhook
Now we can invoke a run with a webhook:
To invoke a run with a webhook, we specify the `webhook` parameter with the desired endpoint when creating a run. Webhook requests are triggered by the end of a run.
For example, if we can receive requests at `https://my-server.app/my-webhook-endpoint`, we can pass this to `stream`:
=== "Python"
@@ -89,7 +91,7 @@ Now we can invoke a run with a webhook:
assistant_id=assistant_id,
input=input,
stream_mode="events",
webhook="your-webhook"
webhook="https://my-server.app/my-webhook-endpoint"
):
# Do something with the stream output
pass
@@ -107,7 +109,7 @@ Now we can invoke a run with a webhook:
assistantID,
{
input: input,
webhook: "your-webhook"
webhook: "https://my-server.app/my-webhook-endpoint"
}
);
for await (const chunk of streamResponse) {
@@ -124,8 +126,17 @@ Now we can invoke a run with a webhook:
--data '{
"assistant_id": <ASSISTANT_ID>,
"input" : {"messages":[{"role": "user", "content": "Hello!"}]},
"webhook": <YOUR_WEBHOOK_URL>
"webhook": "https://my-server.app/my-webhook-endpoint"
}'
```
And that's it! Now you can trigger your custom webhooks whenever you want in your LangGraph applications!
The schema for the payload sent to `my-webhook-endpoint` is that of a [run](../../concepts/langgraph_server.md/#runs). See [API Reference](https://langchain-ai.github.io/langgraph/cloud/reference/api/api_ref.html#model/run) for more detail. Note that the run input, configuration, etc. are included in the `kwargs` field.
### Signing webhook requests
To sign the webhook requests, we can specify a token parameter in the webhook URL, e.g.,
```
https://my-server.app/my-webhook-endpoint?token=...
```
The server should then extract the token from the request's parameters and validate it before processing the payload.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 KiB

-44
View File
@@ -1,44 +0,0 @@
# LangGraph Cloud (beta)
!!! tip
- LangGraph is an MIT-licensed open-source library, which we are committed to maintaining and growing for the community.
- LangGraph Cloud is an optional managed hosting service for LangGraph, which provides additional features geared towards production deployments.
- We are actively contributing improvements back to LangGraph informed by our work on LangGraph Cloud.
- You can always deploy LangGraph applications on your own infrastructure using the open-source LangGraph project.
!!! warning "Under Construction"
LangGraph Cloud documentation is under construction. Contents may change until general availability.
<video controls preload="auto" allowfullscreen="true" poster="how-tos/img/studio_forks_poster.png">
<source src="how-tos/img/studio_forks.mp4" type="video/mp4">
</video>
## Overview
LangGraph Cloud is a managed service for deploying and hosting LangGraph applications. Deploying applications with LangGraph Cloud shortens the time-to-market for developers. With one click, deploy a production-ready API with built-in persistence for your LangGraph application. LangGraph Cloud APIs are horizontally scalable and deployed with durable storage.
The LangGraph Cloud API exposes functionality of your LangGraph application through [Assistants](./concepts/api.md#assistants). An assistant abstracts the cognitive architecture of your graph. Invoke an assistant by calling the pre-built [API endpoints](./reference/api/api_ref.md).
LangGraph Cloud is seamlessly integrated with [LangSmith](https://www.langchain.com/langsmith) and is accessible from within the LangSmith UI.
LangGraph Cloud applications can be tested and debugged using the [LangGraph Studio Desktop](https://github.com/langchain-ai/langgraph-studio).
## Key Features
The LangGraph Cloud API supports key LangGraph features in addition to new functionality for enabling complex, agentic workflows.
- **Assistants and Threads**: Assistants abstract the cognitive architecture of graphs and threads track the state/history of graphs.
- **Streaming**: API support for [LangGraph streaming modes](../concepts/low_level.md#streaming) including setting multiple streaming modes at the same time.
- **Human-in-the-Loop**: API support for [LangGraph human-in-the-loop features](../concepts/agentic_concepts.md#human-in-the-loop).
- **Double Texting**: Configure how assistants respond when new input is received while processing a previous input. Interrupt, rollback, reject, or enqueue.
- **Background Runs/Cron Jobs**: A built-in task queue enables background runs and scheduled cron jobs.
- **Stateless Runs**: For simpler use cases, invoke an assistant without needing to create a thread.
## Documentation
- [Tutorials](./quick_start.md): Learn to build and deploy applications for LangGraph Cloud.
- [How-to Guides](./how-tos/index.md): Learn how to set up a LangGraph application for deployment and implement features of the LangGraph Cloud API such as streaming tokens, configuring double texting, and creating cron jobs. Go here if you want to copy and run a specific code snippet.
- [Conceptual Guides](./concepts/api.md): In-depth explanations of the core data models (e.g. assistants), key features of the LangGraph Cloud API (e.g. double texting), and the architecture of a LangGraph Cloud deployment.
- [Reference](./reference/api/api_ref.md): References for the LangGraph Cloud API, the corresponding Python and JS/TS SDKs, the LangGraph CLI, and deployment environment variables.
+266 -203
View File
@@ -1,155 +1,194 @@
# Quick Start
# LangGraph Cloud Quick Start
This quick start guide will cover how to build a simple agent that can look up things on the internet. We will then deploy it to LangGraph Cloud, use the LangGraph Studio to visualize and test it out, and use the LangGraph SDK to interact with it.
In this tutorial you will build and deploy a simple chatbot agent that can look things up on the internet. You will be using [LangGraph Cloud](../concepts/langgraph_cloud.md), [LangGraph Studio](../concepts/langgraph_studio.md) to visualize and test it out, and [LangGraph SDK](./reference/sdk/python_sdk_ref.md) to interact with the deployed agent.
If you want to learn how to build an agent like this from scratch, take a look at the [LangGraph Quick Start tutorial](../tutorials/introduction.ipynb).
## Set up requirements
This tutorial will use:
- Anthropic for the LLM - sign up and get an API key [here](https://console.anthropic.com/)
- Tavily for the search engine - sign up and get an API key [here](https://app.tavily.com/)
- LangSmith for hosting - sign up and get an API key [here](https://smith.langchain.com/)
- Anthropic for the LLM - sign up and get an API key [here](https://console.anthropic.com/).
- Tavily for the search engine - sign up and get an API key [here](https://app.tavily.com/).
- LangSmith for hosting - sign up and get an API key [here](https://smith.langchain.com/).
## Set up local files
## Create and configure your app
1. Create a new application with the following directory and files:
First, let's set create all of the necessary files for our LangGraph application.
=== "Python"
1. __Create application directory and files__
<my-app>/
|-- agent.py # code for your LangGraph agent
|-- requirements.txt # Python packages required for your graph
|-- langgraph.json # configuration file for LangGraph
|-- .env # environment files with API keys
Create a new application `my-app` with the following file structure:
=== "Javascript"
<my-app>/
|-- agent.ts # code for your LangGraph agent
|-- package.json # Javascript packages required for your graph
|-- langgraph.json # configuration file for LangGraph
|-- .env # environment files with API keys
2. The `agent.py`/`agent.ts` file should contain code for defining your graph. The following code is a simple example, the important thing is that at some point in your file you compile your graph and assign the compiled graph to a variable (in this case the `graph` variable). This example code uses `create_react_agent`, a prebuilt agent. You can read more about it [here](../concepts/agentic_concepts.md#react-implementation).
=== "Python"
```python
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.prebuilt import create_react_agent
model = ChatAnthropic(model="claude-3-5-sonnet-20240620")
tools = [TavilySearchResults(max_results=2)]
graph = create_react_agent(model, tools)
```shell
mkdir my-app
```
=== "Javascript"
=== "Python"
```ts
import { ChatAnthropic } from "@langchain/anthropic";
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
my-app/
|-- agent.py # code for your LangGraph agent
|-- requirements.txt # Python packages required for your graph
|-- langgraph.json # configuration file for LangGraph
|-- .env # environment files with API keys
const model = new ChatAnthropic({
model: "claude-3-5-sonnet-20240620",
});
=== "Javascript"
const tools = [
new TavilySearchResults({ maxResults: 3, }),
];
my-app/
|-- agent.ts # code for your LangGraph agent
|-- package.json # Javascript packages required for your graph
|-- langgraph.json # configuration file for LangGraph
|-- .env # environment files with API keys
export const graph = createReactAgent({ llm: model, tools });
```
3. The `requirements.txt`/`package.json` file should contain any dependencies for your graph(s). In this case we only require four packages for our graph to run:
1. __Define your graph__
=== "Python"
=== "Python"
The `agent.py` file should contain code with your graph.
```python
langgraph
langchain_anthropic
tavily-python
langchain_community
```
=== "Javascript"
The `agent.ts` file should contain code with your graph.
=== "Javascript"
The following code example is a simple chatbot agent (similar to the one in the [previous tutorial](../tutorials/introduction.ipynb)). Specifically, it uses [create_react_agent][langgraph.prebuilt.chat_agent_executor.create_react_agent], a prebuilt [ReAct](../concepts/agentic_concepts.md#react-implementation)-style agent.
```js
{
"name": "my-app",
"packageManager": "yarn@1.22.22",
"dependencies": {
"@langchain/community": "^0.2.31",
"@langchain/core": "^0.2.31",
"@langchain/langgraph": "0.2.0",
"@langchain/openai": "^0.2.8"
The `agent` file needs to have a variable with a [CompiledGraph][langgraph.graph.graph.CompiledGraph] (in this case the `graph` variable).
=== "Python"
```python
# agent.py
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.prebuilt import create_react_agent
model = ChatAnthropic(model="claude-3-5-sonnet-20240620")
tools = [TavilySearchResults(max_results=2)]
# compiled graph
graph = create_react_agent(model, tools)
```
=== "Javascript"
```ts
// agent.ts
import { ChatAnthropic } from "@langchain/anthropic";
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
const model = new ChatAnthropic({
model: "claude-3-5-sonnet-20240620",
});
const tools = [
new TavilySearchResults({ maxResults: 3, }),
];
// compiled graph
export const graph = createReactAgent({ llm: model, tools });
```
1. __Specify dependencies__
=== "Python"
You should add dependencies for your graph(s) to `requirements.txt`.
=== "Javascript"
You should add dependencies for your graph(s) to `package.json`.
In this case we only require four packages for our graph to run:
=== "Python"
```python
langgraph
langchain_anthropic
tavily-python
langchain_community
```
=== "Javascript"
```js
{
"name": "my-app",
"packageManager": "yarn@1.22.22",
"dependencies": {
"@langchain/community": "^0.3.11",
"@langchain/core": "^0.3.16",
"@langchain/langgraph": "0.2.18",
"@langchain/anthropic": "^0.3.7"
}
}
```
1. __Create LangGraph configuration file__
The [`langgraph.json`][langgraph.json] file is a configuration file that describes what graph(s) you are going to deploy. In this case we only have one graph: the compiled `graph` object from `agent.py` / `agent.ts`.
=== "Python"
```json
{
"dependencies": ["."],
"graphs": {
"agent": "./agent.py:graph"
},
"env": ".env"
}
}
```
```
4. The [`langgraph.json`][langgraph.json] file is a configuration file that describes what graph(s) you are going to host. In this case we only have one graph to host: the compiled `graph` object from `agent.py`/`agent.ts`.
=== "Javascript"
=== "Python"
```json
{
"node_version": "20",
"dockerfile_lines": [],
"dependencies": ["."],
"graphs": {
"agent": "./src/agent.ts:graph"
},
"env": ".env"
}
```
```json
{
"dependencies": ["."],
"graphs": {
"agent": "./agent.py:graph"
},
"env": ".env"
}
```
Learn more about the LangGraph CLI configuration file [here](./reference/cli.md#configuration-file).
=== "Javascript"
1. __Specify environment variables__
```json
{
"node_version": "20",
"dockerfile_lines": [],
"dependencies": ["."],
"graphs": {
"agent": "./src/agent.ts:graph"
},
"env": ".env"
}
```
The `.env` file should have any environment variables needed to run your graph. This will only be used for local testing, so if you are not testing locally you can skip this step.
Learn more about the LangGraph CLI configuration file [here](./reference/cli.md#configuration-file).
!!! warning
The `.env` file should NOT be included with the rest of source code in your Github repository. When creating a deployment using LangGraph Cloud, you will be able to specify the environment variables manually.
5. The `.env` file should have any environment variables needed to run your graph. This will only be used for local testing, so if you are not testing locally you can skip this step. NOTE: if you do add this, you should NOT check this into git. For this graph, we need two environment variables:
For this graph, we need two environment variables:
```shell
ANTHROPIC_API_KEY=...
TAVILY_API_KEY=...
```
Now that we have set everything up on our local file system, we are ready to host our graph.
!!! tip
Learn more about different application structure options [here](../how-tos/index.md#application-structure).
## Test the graph build locally
Now that we have set everything up on our local file system, we are ready to test our graph locally.
### Using LangGraph Studio Desktop (recommended)
## Test the app locally
![LangGraph Studio Desktop](./img/graph_video_poster.png)
To test the LangGraph app before deploying it using LangGraph Cloud, you can start the [LangGraph server](../concepts/langgraph_server.md) locally or use [LangGraph Studio](../concepts/langgraph_studio.md).
Testing your graph locally is easy with LangGraph Studio Desktop. LangGraph Studio offers a new way to develop LLM applications by providing a specialized agent IDE that enables visualization, interaction, and debugging of complex agentic applications
## Using local server
With visual graphs and the ability to edit state, you can better understand agent workflows and iterate faster. LangGraph Studio integrates with [LangSmith](https://smith.langchain.com) so you can collaborate with teammates to debug failure modes.
You can test your app by running [LangGraph server](../concepts/langgraph_server.md) locally. This is useful to make sure you have configured our [CLI configuration file][langgraph.json] correctly and can interact with your graph.
### Using the LangGraph CLI
Before deploying to the cloud, we probably want to test the building of our graph locally. This is useful to make sure we have configured our [CLI configuration file][langgraph.json] correctly and our graph runs.
In order to do this we can first install the LangGraph CLI
To run the server locally, you need to first install the LangGraph CLI:
```shell
pip install langgraph-cli
```
We can then test our API server locally. This requires access to LangGraph closed beta. In order to run the server locally, you will need to add your `LANGSMITH_API_KEY` to the .env file so we can validate you have access to LangGraph closed beta.
You can then test our API server locally. In order to run the server locally, you will need to add your `LANGSMITH_API_KEY` to the `.env` file.
```shell
langgraph up
@@ -160,10 +199,21 @@ This will start up the LangGraph API server locally. If this runs successfully,
```shell
Ready!
- API: http://localhost:8123
2024-06-26 19:20:41,056:INFO:uvicorn.access 127.0.0.1:44138 - "GET /ok HTTP/1.1" 200
```
You can now test this out! **Note: this local server is intended SOLELY for local testing purposes and is not performant enough for production applications, so please do not use it as such.** To test it out, you can go to another terminal window and run:
First, let's verify that the server is running correctly by calling `/ok` endpoint:
```shell
curl --request GET --url http://localhost:8123/ok
```
Output:
```
{"ok": "true"}
```
Now we're ready to test the app with the real inputs!
```shell
curl --request POST \
@@ -175,36 +225,57 @@ curl --request POST \
"messages": [
{
"role": "user",
"content": "How are you?"
"content": "What is the weather in NYC?"
}
]
},
"metadata": {},
"config": {
"configurable": {}
},
"multitask_strategy": "reject",
"stream_mode": [
"values"
]
"stream_mode": "updates"
}'
```
If you get back a valid response, then all is functioning properly!
Output:
## Deploy to Cloud
```
...
### Push your code to GitHub
data: {
"agent": {
"messages": [
{
"content": "The search results from Tavily provide the current weather conditions in New York City, including temperature, wind speed, precipitation, humidity, and cloud cover. According to the results, as of 3:00pm on October 30th, 2024, it is overcast in NYC with a temperature of around 66°F (19°C), light winds from the southwest around 8 mph (13 km/h), and 66% humidity.\n\nSo in summary, the current weather in NYC is overcast with mild temperatures in the mid 60sF and light winds, based on the search results. Let me know if you need any other details!",
"type": "ai",
...
}
]
}
}
```
Turn the `<my-app>` directory into a GitHub repo. You can use the GitHub CLI if you like, or just create a repo manually (if unfamiliar, instructions [here](https://docs.github.com/en/migrations/importing-source-code/using-the-command-line-to-import-source-code/adding-locally-hosted-code-to-github)).
You can see that our agent responds with the up-to-date search results!
### Deploy from GitHub with LangGraph Cloud
### Using LangGraph Studio Desktop
Once you have created your github repository with a Python file containing your compiled graph as well as a `langgraph.json` file containing the configuration for hosting your graph, you can head over to LangSmith and click on the 🚀 icon on the left navbar to create a new deployment. Then click the `+ New Deployment` button.
You can also test your app locally with [LangGraph Studio](../concepts/langgraph_studio.md). LangGraph Studio offers a new way to develop LLM applications by providing a specialized agent IDE that enables visualization, interaction, and debugging of complex agentic applications.
![Langsmith Workflow](./img/cloud_deployment.png)
With visual graphs and the ability to edit state, you can better understand agent workflows and iterate faster. LangGraph Studio integrates with LangSmith allowing you to collaborate with teammates to debug failure modes.
**_If you have not deployed to LangGraph Cloud before:_** there will be a button that shows up saying Import from GitHub. Youll need to follow that flow to connect LangGraph Cloud to GitHub.
LangGraph Studio is available as a [desktop app](https://studio.langchain.com/) for MacOS users. Once you have installed the app, you can select `my-app` directory, which will automatically start the server locally and load the graph in the UI.
To interact with your chatbot agent in LangGraph Studio, you can add a new message in the `Input` section and press `Submit`.
![LangGraph Studio Desktop](./deployment/img/quick_start_studio.png)
## Deploy to LangGraph Cloud
Once you've tested your graph locally and verified that it works as expected, you can deploy it to the LangGraph Cloud.
First, you'll need to turn the `my-app` directory into a GitHub repo and [push it to GitHub](https://docs.github.com/en/migrations/importing-source-code/using-the-command-line-to-import-source-code/adding-locally-hosted-code-to-github).
Once you have created your GitHub repository with a Python file containing your compiled graph as well as a `langgraph.json` with the configuration, you can head over to [LangSmith](https://smith.langchain.com/) and click on the graph icon (`LangGraph Cloud`) on the bottom of the left navbar. This will open the LangGraph deployments page. On this page, click the `+ New Deployment` button in the top right corner.
![Langsmith Workflow](./deployment/img/cloud_deployment.png)
**_If you have not deployed to LangGraph Cloud before:_** there will be a button that shows up saying `Import from GitHub`. Youll need to follow that flow to connect LangGraph Cloud to GitHub.
**_Once you have set up your GitHub connection:_** the new deployment page will look as follows:
@@ -213,53 +284,43 @@ Once you have created your github repository with a Python file containing your
To deploy your application, you should do the following:
1. Select your GitHub username or organization from the selector
2. Search for your repo to deploy in the search bar and select it
3. Choose any name
4. In the `LangGraph API config file` field, enter the path to your `langgraph.json` file (which in this case is just `langgraph.json`)
5. For Git Reference, you can select either the git branch for the code you want to deploy, or the exact commit SHA.
6. If your chain relies on environment variables, add those in. They will be propagated to the underlying server so your code can access them. In this case, we need `ANTHROPIC_API_KEY` and `TAVILY_API_KEY`.
Putting this all together, you should have something as follows for your deployment details:
![Deployment filled out](./deployment/img/deploy_filled_out.png)
1. Search for your repo to deploy in the search bar and select it
1. Choose a name for your deployment
1. In the `Git Branch` field, you can specify either the branch for the code you want to deploy, or the exact commit SHA.
1. In the `LangGraph API config file` field, enter the path to your `langgraph.json` file (which in this case is just `langgraph.json`)
1. If your application needs environment variables, add those in the `Environment Variables` section. They will be propagated to the underlying server so your code can access them. In this case, we will need `ANTHROPIC_API_KEY` and `TAVILY_API_KEY`.
Hit `Submit` and your application will start deploying!
## Inspect Traces + Monitor Service
### Deployments View
After your deployment is complete, your deployments page should look as follows:
![Deployed page](./deployment/img/deployed_page.png)
You can see that by default, you get access to the `Trace Count` monitoring chart and `Recent Traces` run view. These are powered by LangSmith.
## Interact with your deployment
You can click on `All Charts` to view all monitoring info for your server, or click on `See tracing project` to get more information on an individual trace.
### Using LangGraph Studio (Cloud)
### Access the Docs
You can access the docs by clicking on the API docs link, which should send you to a page that looks like this:
![API Docs page](./deployment/img/api_page.png)
You wont actually be able to test any of the API endpoints without authorizing first. To do so, grab your Langsmith API key and add it at the top where it says `API KEY (X-API-KEY)`. You should now be able to select any of the API endpoints, click `Test Request`, enter the parameters you would like to pass, and then click `Send` to view the results of the API call.
## Interact with your deployment via LangGraph Studio
If you click on your deployment you should see a blue button in the top right that says `LangGraph Studio`. Clicking on this button will take you to a page that looks like this:
![Studio UI before being run](./deployment/img/graph_visualization.png)
On this page you can test out your graph by passing in starting states and clicking `Start Run` (this should behave identically to calling `.invoke`). You will then be able to look into the execution thread for each run and explore the steps your graph is taking to produce its output.
On the deployment page for your application,, you should see a button in the top right corner that says `LangGraph Studio`. Clicking on this button will take you to the web version of LangGraph Studio. This is the same UI that you interacted with when [testing the app locally](#using-langgraph-studio-recommended), but instead of using a local LangGraph server, it uses the one from your LangGraph Cloud deployment.
![Studio UI once being run](./deployment/img/graph_run.png)
## Use with the SDK
### Using LangGraph SDK
Once you have tested that your hosted graph works as expected using LangGraph Studio, you can start using your hosted graph all over your organization by using the LangGraph SDK. Let's see how we can access our hosted graph and execute our run from a python file.
You can also interact with your deployed LangGraph application programmatically, using [LangGraph SDK](./reference/sdk/python_sdk_ref.md).
First, make sure you have the SDK installed by calling `pip install langgraph_sdk`.
First, make sure you have the SDK installed:
=== "Python"
```shell
pip install langgraph_sdk
```
=== "Javascript"
```shell
yarn add @langchain/langgraph-sdk
```
Before using, you need to get the URL of your LangGraph deployment. You can find this in the `Deployment` view. Click the URL to copy it to the clipboard.
@@ -278,8 +339,8 @@ The first thing to do when using the SDK is to setup our client, access our assi
client = get_client(url=<DEPLOYMENT_URL>)
# get default assistant
assistants = await client.assistants.search()
assistant = [a for a in assistants if not a["config"]][0]
assistants = await client.assistants.search(metadata={"created_by": "system"})
assistant = assistants[0]
# create thread
thread = await client.threads.create()
print(thread)
@@ -292,8 +353,8 @@ The first thing to do when using the SDK is to setup our client, access our assi
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
// get default assistant
const assistants = await client.assistants.search();
const assistant = assistants.find(a => !a.config);
const assistants = await client.assistants.search({ metadata: {"created_by": "system"} })
const assistant = assistants[0];
// create thread
const thread = await client.threads.create();
console.log(thread)
@@ -307,8 +368,9 @@ The first thing to do when using the SDK is to setup our client, access our assi
--header 'Content-Type: application/json' \
--data '{
"limit": 10,
"offset": 0
}' | jq -c 'map(select(.config == null or .config == {})) | .[0]' && \
"offset": 0,
"metadata": {"created_by": "system"}
}' &&
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json' \
@@ -320,32 +382,35 @@ We can then execute a run on the thread:
=== "Python"
```python
input = {"messages":[{"role": "user", "content": "Hello! My name is Bagatur and I am 26 years old."}]}
input = {
"messages": [{"role": "user", "content": "What is the weather in NYC?"}]
}
async for chunk in client.runs.stream(
thread['thread_id'],
assistant["assistant_id"],
input=input,
stream_mode="updates",
):
if chunk.data and chunk.event != "metadata":
thread["thread_id"],
assistant["assistant_id"],
input=input,
stream_mode="updates",
):
if chunk.data:
print(chunk.data)
```
=== "Javascript"
```js
const input = { "messages":[{ "role": "user", "content": "Hello! My name is Bagatur and I am 26 years old." }] };
const input = { "messages": [{ "role": "user", "content": "What is the weather in NYC?" }] };
const streamResponse = client.runs.stream(
thread["thread_id"],
assistant["assistant_id"],
{
input,
streamMode: "updates"
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata" ) {
if (chunk.data) {
console.log(chunk.data);
}
}
@@ -357,43 +422,41 @@ We can then execute a run on the thread:
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": <ASSISTANT_ID>,
\"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"Hello! My name is Bagatur and I am 26 years old.\"}]},
}" | sed 's/\r$//' | awk '
/^event:/ { event = $2 }
/^data:/ {
json_data = substr($0, index($0, $2))
if (event != "metadata") {
print json_data
}
--data '{
"assistant_id": <ASSISTANT_ID>,
"input": {
"messages": [
{
"role": "user",
"content": "What is the weather in NYC?"
}
]
},
"stream_mode": "updates"
}'
```
Output:
{'agent': {'messages': [{'content': "Hi Bagatur! It's nice to meet you. How can I assist you today?", 'additional_kwargs': {}, 'response_metadata': {'finish_reason': 'stop', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_9cb5d38cf7'}, 'type': 'ai', 'name': None, 'id': 'run-c89118b7-1b1e-42b9-a85d-c43fe99881cd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
```
...
## What's Next
data: {
"agent": {
"messages": [
{
"content": "The search results from Tavily provide the current weather conditions in New York City, including temperature, wind speed, precipitation, humidity, and cloud cover. According to the results, as of 3:00pm on October 30th, 2024, it is overcast in NYC with a temperature of around 66°F (19°C), light winds from the southwest around 8 mph (13 km/h), and 66% humidity.\n\nSo in summary, the current weather in NYC is overcast with mild temperatures in the mid 60sF and light winds, based on the search results. Let me know if you need any other details!",
"type": "ai",
...
}
]
}
}
```
## Next steps
Congratulations! If you've worked your way through this tutorial you are well on your way to becoming a LangGraph Cloud expert. Here are some other resources to check out to help you out on the path to expertise:
### LangGraph Cloud How-tos
If you want to learn more about streaming from hosted graphs, check out the Streaming [how-to guides](how-tos/index.md#streaming).
To learn more about double-texting and all the ways you can handle it in your application, read up on these [how-to guides](how-tos/index.md#double-texting).
To learn about how to include different human-in-the-loop behavior in your graph, take a look at [these how-tos](how-tos/index.md#human-in-the-loop).
### LangGraph Tutorials
Before hosting, you have to write a graph to host. Here are some tutorials to get you more comfortable with writing LangGraph graphs and give you inspiration for the types of graphs you want to host.
[This tutorial](../tutorials/customer-support/customer-support.ipynb) walks you through how to write a customer support bot using LangGraph.
If you are interested in writing a SQL agent, check out [this tutorial](../tutorials/sql-agent.ipynb).
Check out the [LangGraph tutorials](../tutorials/index.md) page to read about more exciting use cases.
* [LangGraph How-to guides](../how-tos/index.md)
* [LangGraph Tutorials](../tutorials/index.md)
File diff suppressed because it is too large Load Diff
+138 -62
View File
@@ -1,23 +1,38 @@
# LangGraph CLI
The LangGraph CLI includes commands to build and run a LangGraph Cloud API server locally in [Docker](https://www.docker.com/). For development and testing, use the CLI to deploy a local API server.
The LangGraph command line interface includes commands to build and run a LangGraph Cloud API server locally in [Docker](https://www.docker.com/). For development and testing, you can use the CLI to deploy a local API server as an alternative to the [Studio desktop app](../../concepts/langgraph_studio.md).
## Installation
1. Ensure that Docker is installed (e.g. `docker --version`).
2. Install the `langgraph-cli` Python package (e.g. `pip install langgraph-cli`).
2. Install the `langgraph-cli` package:
=== "pip"
```bash
pip install langgraph-cli
```
=== "Homebrew (MacOS only)"
```bash
brew install langgraph-cli
```
3. Run the command `langgraph --help` to confirm that the CLI is installed.
[](){#langgraph.json}
## Configuration File
The LangGraph CLI requires a JSON configuration file with the following keys:
| Key | Description |
| --- | ----------- |
| `dependencies` | **Required**. Array of dependencies for LangGraph Cloud API server. Dependencies can be one of the following: (1) `"."`, which will look for local Python packages, (2) `pyproject.toml`, `setup.py` or `requirements.txt` in the app directory `"./local_package"`, or (3) a package name. |
| `graphs` | **Required**. Mapping from graph ID to path where the compiled graph or a function that makes a graph is defined. Example: <ul><li>`./your_package/your_file.py:variable`, where `variable` is an instance of `langgraph.graph.state.CompiledStateGraph`</li><li>`./your_package/your_file.py:make_graph`, where `make_graph` is a function that takes a config dictionary (`langchain_core.runnables.RunnableConfig`) and creates an instance of `langgraph.graph.state.StateGraph` / `langgraph.graph.state.CompiledStateGraph`.</li></ul> |
| `env` | Path to `.env` file or a mapping from environment variable to its value. |
| `python_version` | `3.11` or `3.12`. Defaults to `3.11`. |
| `pip_config_file`| Path to `pip` config file. |
| `dockerfile_lines` | Array of additional lines to add to Dockerfile following the import from parent image. |
| Key | Description |
|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `dependencies` | **Required**. Array of dependencies for LangGraph Cloud API server. Dependencies can be one of the following: (1) `"."`, which will look for local Python packages, (2) `pyproject.toml`, `setup.py` or `requirements.txt` in the app directory `"./local_package"`, or (3) a package name. |
| `graphs` | **Required**. Mapping from graph ID to path where the compiled graph or a function that makes a graph is defined. Example: <ul><li>`./your_package/your_file.py:variable`, where `variable` is an instance of `langgraph.graph.state.CompiledStateGraph`</li><li>`./your_package/your_file.py:make_graph`, where `make_graph` is a function that takes a config dictionary (`langchain_core.runnables.RunnableConfig`) and creates an instance of `langgraph.graph.state.StateGraph` / `langgraph.graph.state.CompiledStateGraph`.</li></ul> |
| `env` | Path to `.env` file or a mapping from environment variable to its value. |
| `python_version` | `3.11` or `3.12`. Defaults to `3.11`. |
| `pip_config_file` | Path to `pip` config file. |
| `dockerfile_lines` | Array of additional lines to add to Dockerfile following the import from parent image. |
<div class="admonition tip">
<p class="admonition-title">Note</p>
@@ -27,101 +42,162 @@ The LangGraph CLI requires a JSON configuration file with the following keys:
</div>
Example:
```json
{
"dependencies": [
"langchain_openai",
"./your_package"
],
"graphs": {
"my_graph_id": "./your_package/your_file.py:variable"
},
"env": "./.env"
"dependencies": ["langchain_openai", "./your_package"],
"graphs": {
"my_graph_id": "./your_package/your_file.py:variable"
},
"env": "./.env"
}
```
Example:
Example with environment variables:
```json
{
"python_version": "3.11",
"dependencies": [
"langchain_openai",
"."
],
"graphs": {
"my_graph_id": "./your_package/your_file.py:make_graph"
},
"env": {
"OPENAI_API_KEY": "secret-key"
}
"python_version": "3.11",
"dependencies": ["langchain_openai", "."],
"graphs": {
"my_graph_id": "./your_package/your_file.py:make_graph"
},
"env": {
"OPENAI_API_KEY": "secret-key"
}
}
```
## Commands
The base command for the LangGraph CLI is `langgraph`.
**Usage**
```
langgraph [OPTIONS] COMMAND [ARGS]
```
### `dev`
Run LangGraph API server in development mode with hot reloading and debugging capabilities. This lightweight server requires no Docker installation and is suitable for development and testing. State is persisted to a local directory.
**Installation**
This command requires the "inmem" extra to be installed:
```bash
pip install -U "langgraph-cli[inmem]"
```
**Usage**
```
langgraph dev [OPTIONS]
```
**Options**
| Option | Default | Description |
|----------------------------|------------------|--------------------------------------------------------------------------------------------|
| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables |
| `--host TEXT` | `127.0.0.1` | Host to bind the server to |
| `--port INTEGER` | `2024` | Port to bind the server to |
| `--no-reload` | | Disable auto-reload |
| `--n-jobs-per-worker INTEGER` | | Number of jobs per worker. Default is 10 |
| `--no-browser` | | Disable automatic browser opening |
| `--debug-port INTEGER` | | Port for debugger to listen on |
| `--help` | | Display command documentation |
### `build`
Build LangGraph Cloud API server Docker image.
**Usage**
```
langgraph build [OPTIONS]
```
**Options**
| Option | Default | Description |
| ------ | ------- | ----------- |
| `--platform TEXT` | | Target platform(s) to build the Docker image for. Example: `langgraph build --platform linux/amd64,linux/arm64` |
| `-t, --tag TEXT` | | **Required**. Tag for the Docker image. Example: `langgraph build -t my-image` |
| `--pull / --no-pull` | `--pull` | Build with latest remote Docker image. Use `--no-pull` for running the LangGraph Cloud API server with locally built images. |
| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. |
| `--help` | | Display command documentation. |
| Option | Default | Description |
|----------------------|------------------|------------------------------------------------------------------------------------------------------------------------------|
| `--platform TEXT` | | Target platform(s) to build the Docker image for. Example: `langgraph build --platform linux/amd64,linux/arm64` |
| `-t, --tag TEXT` | | **Required**. Tag for the Docker image. Example: `langgraph build -t my-image` |
| `--pull / --no-pull` | `--pull` | Build with latest remote Docker image. Use `--no-pull` for running the LangGraph Cloud API server with locally built images. |
| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. |
| `--help` | | Display command documentation. |
### `up`
Start langgraph API server. For local testing, requires a LangSmith API key with access to LangGraph Cloud closed beta. Requires a license key for production use.
Start LangGraph API server. For local testing, requires a LangSmith API key with access to LangGraph Cloud closed beta. Requires a license key for production use.
**Usage**
```
langgraph up [OPTIONS]
```
**Options**
| Option | Default | Description |
| ------ | ------- | ----------- |
| `--wait` | | Wait for services to start before returning. Implies --detach |
| `--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. |
| `--debugger-port INTEGER` | | Pull the debugger image locally and serve the UI on specified port |
| `--verbose` | | Show more output from the server logs. |
| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. |
| `-d, --docker-compose FILE` | | Path to docker-compose.yml file with additional services to launch. |
| `-p, --port INTEGER` | `8123` | Port to expose. Example: `langgraph test --port 8000` |
| `--pull / --no-pull` | `pull` | Pull latest images. Use --no-pull for running the server with locally-built images. Example: `langgraph up --no-pull` |
| `--recreate / --no-recreate` | `no-recreate` | Recreate containers even if their configuration and image haven't changed |
| `--help` | | Display command documentation. |
| Option | Default | Description |
|------------------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------------|
| `--wait` | | Wait for services to start before returning. Implies --detach |
| `--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. |
| `--debugger-port INTEGER` | | Pull the debugger image locally and serve the UI on specified port |
| `--verbose` | | Show more output from the server logs. |
| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. |
| `-d, --docker-compose FILE` | | Path to docker-compose.yml file with additional services to launch. |
| `-p, --port INTEGER` | `8123` | Port to expose. Example: `langgraph up --port 8000` |
| `--pull / --no-pull` | `pull` | Pull latest images. Use `--no-pull` for running the server with locally-built images. Example: `langgraph up --no-pull` |
| `--recreate / --no-recreate` | `no-recreate` | Recreate containers even if their configuration and image haven't changed |
| `--help` | | Display command documentation. |
### `test`
Test your LangGraph in the cloud. The only function you can call from the SDK after testing your graph is `client.runs.stream(thread_id=None, ...)`
### `dockerfile`
Generate a Dockerfile for building a LangGraph Cloud API server Docker image.
**Usage**
```
langgraph test [OPTIONS]
langgraph dockerfile [OPTIONS] SAVE_PATH
```
**Options**
| Option | Default | Description |
| ------ | ------- | ----------- |
| `--verbose` | | Show more output from the server logs. |
| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. |
| `-p, --port INTEGER` | `8123` | Port to expose. Example: `langgraph test --port 8000` |
| `--pull / --no-pull` | `pull` | Pull latest images. Use --no-pull for running the server with locally-built images. Example: `langgraph up --no-pull` |
| `--help` | | Display command documentation. |
| Option | Default | Description |
|---------------------|------------------|-----------------------------------------------------------------------------------------------------------------|
| `-c, --config FILE` | `langgraph.json` | Path to the [configuration file](#configuration-file) declaring dependencies, graphs and environment variables. |
| `--help` | | Show this message and exit. |
Example:
```bash
langgraph dockerfile -c langgraph.json Dockerfile
```
This generates a Dockerfile that looks similar to:
```dockerfile
FROM langchain/langgraph-api:3.11
ADD ./pipconf.txt /pipconfig.txt
RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt langchain_community langchain_anthropic langchain_openai wikipedia scikit-learn
ADD ./graphs /deps/__outer_graphs/src
RUN set -ex && \
for line in '[project]' \
'name = "graphs"' \
'version = "0.1"' \
'[tool.setuptools.package-data]' \
'"*" = ["**/*"]'; do \
echo "$line" >> /deps/__outer_graphs/pyproject.toml; \
done
RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/*
ENV LANGSERVE_GRAPHS='{"agent": "/deps/__outer_graphs/src/agent.py:graph", "storm": "/deps/__outer_graphs/src/storm.py:graph"}'
@@ -1,79 +1,8 @@
# Python SDK Reference
The Python SDK provides four underlying clients (`AssistantsClient`, `ThreadsClient`, `RunsClient`, `CronClient`) that correspond to each of the core API models and one top-level client (`LangGraphClient`) to access them.
## get_client()
The `get_client()` function returns the top-level `LangGraphClient` client.
```python
from langgraph_sdk import get_client
# get top-level LangGraphClient
client = get_client(url="http://localhost:8123")
# example usage: client.<model>.<method_name>()
assistants = await client.assistants.get(assistant_id="some_uuid")
```
::: langgraph_sdk.client.get_client
::: langgraph_sdk.client
handler: python
## LangGraphClient
`LangGraphClient` is the top-level client for accessing `AssistantsClient`, `ThreadsClient`, `RunsClient`, and `CronClient`.
::: langgraph_sdk.client.LangGraphClient
handler: python
## AssistantsClient
Access the `AssistantsClient` via the `LangGraphClient.assistants` attribute.
```python
from langgraph_sdk import get_client
client = get_client(url="http://localhost:8123")
await client.assistants.<method_name>()
```
::: langgraph_sdk.client.AssistantsClient
handler: python
## ThreadsClient
Access the `ThreadsClient` via the `LangGraphClient.threads` attribute.
```python
from langgraph_sdk import get_client
client = get_client(url="http://localhost:8123")
await client.threads.<method_name>()
```
::: langgraph_sdk.client.ThreadsClient
handler: python
## RunsClient
Access the `RunsClient` via the `LangGraphClient.runs` attribute.
```python
from langgraph_sdk import get_client
client = get_client(url="http://localhost:8123")
await client.runs.<method_name>()
```
::: langgraph_sdk.client.RunsClient
handler: python
## CronClient
Access the `CronClient` via the `LangGraphClient.crons` attribute.
```python
from langgraph_sdk import get_client
client = get_client(url="http://localhost:8123")
await client.crons.<method_name>()
```
::: langgraph_sdk.client.CronClient
::: langgraph_sdk.schema
handler: python
+3 -3
View File
@@ -103,15 +103,15 @@ Parallel processing is vital for efficient multi-agent systems and complex tasks
For practical implementation, see our [map-reduce tutorial](../how-tos/map-reduce.ipynb).
### Sub-graphs
### Subgraphs
Sub-graphs are essential for managing complex agent architectures, particularly in multi-agent systems. They allow:
[Subgraphs](./low_level.md#subgraphs) are essential for managing complex agent architectures, particularly in [multi-agent systems](./multi_agent.md). They allow:
- Isolated state management for individual agents
- Hierarchical organization of agent teams
- Controlled communication between agents and the main system
Sub-graphs communicate with the parent graph through overlapping keys in the state schema. This enables flexible, modular agent design. For implementation details, refer to our [sub-graph tutorial](../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.ipynb).
### Reflection

Some files were not shown because too many files have changed in this diff Show More