Compare commits

...
Author SHA1 Message Date
Nuno Campos af666a87fb sqlite 1.0.2 2024-09-02 17:58:01 -07:00
Nuno Campos 6e9f54e5ae postgres 1.0.6 2024-09-02 17:57:55 -07:00
Nuno Campos dd4a15b569 Require latest version of langgraph-checkpoint 2024-09-02 17:57:33 -07:00
Nuno CamposandGitHub 1122e5cbbb Merge pull request #1579 from langchain-ai/nc/2sep/async-checkpoint-test-setup
test: Ensure that async checkpointers in tests are setup in same event loop as they are used in
2024-09-02 17:57:05 -07:00
Nuno CamposandGitHub 29311f054d Merge pull request #1580 from langchain-ai/nc/2sep/async-checkpointers-implement-async
checkpoint: Implement sync methods in async checkpointers
2024-09-02 17:51:52 -07:00
Nuno Campos 3b2a237deb Lint 2024-09-02 17:45:57 -07:00
Nuno Campos 0cc3799298 checkpoint: Implement sync methods in async checkpointers
- These are needed when subgraphs are invoked synchronously in nodes
2024-09-02 17:43:34 -07:00
Nuno Campos ddeb9d7314 Disable test in old versions of py 2024-09-02 17:42:37 -07:00
Nuno Campos d65d0ec665 test: Ensure that async checkpointers in tests are setup in same event loop as they are used in
- This more closely remembers the environment they're used in, so it's what we should be testing
- Remove unnecessary pytest-asyncio dependency, use anyio pytest plugin instead
- Convert remaining async tests using only memory checkpointer to use all existing ones
2024-09-02 17:24:54 -07:00
Nuno CamposandGitHub a937754132 lib 0.2.16 2024-09-01 12:15:20 -07:00
Reuben MandGitHub 8c698fc362 Return replan response in dict. Add Replan example (#1566) 2024-08-31 23:41:48 +00:00
gbaian10andGitHub 3a07fe2efb docs: fix agent_supervisor.ipynb (#1562)
fix #1561
2024-08-31 16:35:59 -07:00
Nuno CamposandGitHub 7d6a302858 Merge pull request #1514 from vermapratyush/patch-1
[docs]: Fix typo
2024-08-30 16:20:18 -07:00
Nuno CamposandGitHub d225ef074f Merge pull request #1487 from langchain-ai/isaac/fixcustomersupportbot
customer support bot doc nit
2024-08-30 16:14:50 -07:00
Nuno Campos eca419008c checkpoint 1.0.8 2024-08-30 16:10:57 -07:00
Nuno CamposandGitHub 76994f3c9a Merge pull request #1521 from langchain-ai/nc/28aug/pydantic-serialization
checkpoint: Avoid changes to pydantic models breaking deserialization while still relying on pydantic's type coercion
2024-08-30 15:56:43 -07:00
Nuno Campos ca4ebe1031 Update tests 2024-08-30 15:51:57 -07:00
Nuno CamposandGitHub 299179bc33 Merge pull request #1555 from langchain-ai/nc/30aug/detect-nested-graph-in-function-node
Detect subgraphs called inside function nodes
2024-08-30 15:19:40 -07:00
Nuno Campos 487fc8a8ca Detect subgraphs called inside function nodes 2024-08-30 15:13:56 -07:00
Vadym BardaandGitHub cf4de9a1a5 cli: remove jupyter from examples pyproject (#1554) 2024-08-30 21:45:35 +00:00
Nuno CamposandGitHub 921c366708 Merge pull request #1531 from langchain-ai/dependabot/pip/libs/langgraph/notebook-7.2.2
Bump notebook from 7.2.1 to 7.2.2 in /libs/langgraph
2024-08-30 14:34:45 -07:00
Nuno CamposandGitHub 243881ae90 Merge pull request #1532 from langchain-ai/dependabot/pip/libs/langgraph/jupyterlab-4.2.5
Bump jupyterlab from 4.2.2 to 4.2.5 in /libs/langgraph
2024-08-30 14:34:26 -07:00
Nuno Campos 770132dd79 sdk-py: Add values to get/list threads 2024-08-30 14:23:10 -07:00
Nuno Campos 3943637202 Bump them all 2024-08-30 14:18:35 -07:00
Nuno CamposandGitHub 13cf9b7ec5 Merge pull request #1552 from langchain-ai/nc/30aug/sort-pending-writes-on-fetch
postgres/sqlite: Sort pending writes when fetching from db
2024-08-30 14:12:54 -07:00
Nuno Campos e744db169a postgres/sqlite: Sort pending writes when fetching from db 2024-08-30 14:07:46 -07:00
Nuno CamposandGitHub 770c092b57 Merge pull request #1551 from langchain-ai/nc/30aug/rm-none-default-node-inputs
Remove None default for missing keys when generating input for each node
2024-08-30 14:06:51 -07:00
Nuno Campos c5c10a41e5 Remove None default for missing keys when generating input for each node 2024-08-30 13:59:36 -07:00
Nuno Campos af1f218e00 Try init, then construct 2024-08-30 13:35:33 -07:00
Nuno CamposandGitHub 35807068ef Merge pull request #1545 from langchain-ai/nc/29aug/input-metadata-from-writes
For input checkpoint use filtered input writes in checkpoint metadata
2024-08-30 13:30:54 -07:00
Nuno Campos 5db13dffbe checkpoint: Avoid changes to pydantic models breaking deserialization while still relying on pydantic's type coercion 2024-08-30 13:28:32 -07:00
Nuno Campos 6379cdc36d Fix tests 2024-08-30 13:25:35 -07:00
Nuno CamposandNuno Campos 8154ab784e For input checkpoint use filtered input writes in checkpoint metadata
- if we use the raw input we can end up saving keys that were actually ignored (because not one of the input keys), which is incosistent
2024-08-30 13:24:41 -07:00
Vadym BardaandGitHub c761b80970 docs: update subgraph how-to (#1520) 2024-08-30 14:41:29 -04:00
Nuno CamposandGitHub 36d1570c0f Merge pull request #1550 from langchain-ai/nc/30aug/replay-without-fork
Remove the need to fork a thread to replay a past state
2024-08-30 10:39:57 -07:00
Nuno CamposandGitHub 99a845128e Merge pull request #1522 from langchain-ai/nc/28aug/sdk-join-return-val
sdk-py: Update signature for runs.join
2024-08-30 10:36:15 -07:00
Nuno Campos 6036b4a7d4 Remove the need to fork a thread to replay a past state 2024-08-30 10:35:16 -07:00
Nuno Campos 33edc8e808 sdk-py: Update signature for runs.join 2024-08-30 10:31:33 -07:00
Nuno CamposandGitHub 15a204b2be Merge pull request #1539 from langchain-ai/nc/29aug/nested-update-state
Implement update_state for nested graphs
2024-08-30 10:30:40 -07:00
Nuno CamposandGitHub 24a7e6403f Merge pull request #1538 from langchain-ai/nc/29aug/nested-replay
Replay a nested checkpoint
2024-08-30 10:30:14 -07:00
Nuno Campos 9fd64cd37b Lint 2024-08-30 10:19:20 -07:00
Nuno Campos fcd0f094f9 Add test from harrison, always produce output when resuming graph 2024-08-30 10:10:51 -07:00
Vadym BardaandGitHub 30598cd913 docs: fix images in structured react agent (#1544) 2024-08-30 01:50:14 +00:00
Nuno Campos 44153e4a49 Update test 2024-08-29 16:52:50 -07:00
Nuno Campos 4133910670 Implement update_state for nested graphs 2024-08-29 16:41:47 -07:00
Nuno Campos 4fc4080597 Enable test for doubly nested interrupts 2024-08-29 15:49:43 -07:00
Nuno Campos 8865831104 Update async test 2024-08-29 15:42:29 -07:00
Nuno Campos a707eef6f7 Lint 2024-08-29 15:42:25 -07:00
Nuno Campos 090c759da0 Replay a nested checkpoint
- note this isn't very useful until update_state is added
2024-08-29 15:39:14 -07:00
Nuno CamposandGitHub 4ebaaba282 Merge pull request #1499 from langchain-ai/nc/27aug/print-output-skipped-tasks
Emit output for skipped tasks, with `cached` mark
2024-08-29 15:38:35 -07:00
Isaac FranciscoandGitHub 5343350a5c [docs]: conceptual guides for streaming from specific nodes/LLMs (#1537)
* x

* changes

* typo
2024-08-29 22:09:18 +00:00
Nuno CamposandGitHub 5dcb5976d9 Merge pull request #1536 from RafaelRViana/documentation-fix
[docs]: fix parameter "multitask_strategy" misspelled
2024-08-29 14:03:52 -07:00
Nuno Campos 791ab654cb Add cached mark 2024-08-29 13:57:37 -07:00
Nuno Campos c183f4f16a Emit output for skipped tasks 2024-08-29 13:56:55 -07:00
Rafael Viana 11e8728685 [docs]: fix parameter misspelled 2024-08-29 17:49:04 -03:00
Nuno CamposandGitHub b1f22d3d81 Merge pull request #1534 from langchain-ai/nc/29aug/stream-subgraphs
Stream output from subgraphs
2024-08-29 13:37:13 -07:00
Nuno Campos ddf67d9233 Add ns to subgraph stream events 2024-08-29 13:32:21 -07:00
Nuno Campos b479b88c7e Add name of subgraph to streaming output 2024-08-29 13:20:28 -07:00
Isaac FranciscoandGitHub dd52248ef2 [docs]: make react agent HIL guide a little better (#1526)
* ocd

* x

* spelling

* changes

* edits

* nits

* changes

* last nit
2024-08-29 19:02:59 +00:00
Nuno Campos 80e442e13d Stream output from subgraphs
- enabled by new argument stream(subgraphs=True)
- the same stream_mode requested for parent graph is applied to all subgraphs
2024-08-29 12:00:02 -07:00
Nuno CamposandGitHub a627a30f4c Merge pull request #1530 from langchain-ai/nc/29aug/get-state-subgraph
Enable passing subgraph checkpoint config to get_state/aget_state
2024-08-29 11:59:02 -07:00
Vadym BardaandGitHub 01f14d3166 docs: update how-to for streaming from final node (#1533) 2024-08-29 18:28:22 +00:00
dependabot[bot]andGitHub 209e4cef7b Bump jupyterlab from 4.2.2 to 4.2.5 in /libs/langgraph
Bumps [jupyterlab](https://github.com/jupyterlab/jupyterlab) from 4.2.2 to 4.2.5.
- [Release notes](https://github.com/jupyterlab/jupyterlab/releases)
- [Changelog](https://github.com/jupyterlab/jupyterlab/blob/@jupyterlab/lsp@4.2.5/CHANGELOG.md)
- [Commits](https://github.com/jupyterlab/jupyterlab/compare/@jupyterlab/lsp@4.2.2...@jupyterlab/lsp@4.2.5)

---
updated-dependencies:
- dependency-name: jupyterlab
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-29 18:10:05 +00:00
dependabot[bot]andGitHub 98789acacc Bump notebook from 7.2.1 to 7.2.2 in /libs/langgraph
Bumps [notebook](https://github.com/jupyter/notebook) from 7.2.1 to 7.2.2.
- [Release notes](https://github.com/jupyter/notebook/releases)
- [Changelog](https://github.com/jupyter/notebook/blob/@jupyter-notebook/tree@7.2.2/CHANGELOG.md)
- [Commits](https://github.com/jupyter/notebook/compare/@jupyter-notebook/tree@7.2.1...@jupyter-notebook/tree@7.2.2)

---
updated-dependencies:
- dependency-name: notebook
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-29 18:05:50 +00:00
Nuno Campos 9d68aac76f Enable passing subgraph checkpoint config to get_state/aget_state 2024-08-29 10:47:50 -07:00
Nuno CamposandGitHub e526674172 Merge pull request #1502 from langchain-ai/nc/27aug/subgraphs-cleanup
Nc/27aug/subgraphs cleanup
2024-08-29 10:17:04 -07:00
Nuno Campos ca8614f873 Implement get_state and get_state_history for nested graphs 2024-08-29 09:45:45 -07:00
ae8b1e164b docs: expand streaming conceptual guides (#1524)
* stash

* cr

* x

* spelling

* Update docs/docs/cloud/how-tos/stream_events.md

Co-authored-by: Vadym Barda <vadym@langchain.dev>

* Update docs/docs/cloud/how-tos/stream_updates.md

Co-authored-by: Vadym Barda <vadym@langchain.dev>

* Update docs/docs/cloud/how-tos/stream_values.md

Co-authored-by: Vadym Barda <vadym@langchain.dev>

* Update docs/docs/concepts/low_level.md

Co-authored-by: Vadym Barda <vadym@langchain.dev>

* final nits

* spelling

---------

Co-authored-by: isaac hershenson <ihershenson@hmc.edu>
Co-authored-by: Isaac Francisco <78627776+isahers1@users.noreply.github.com>
Co-authored-by: Vadym Barda <vadym@langchain.dev>
2024-08-29 15:03:08 +00:00
gbaian10andGitHub cd28799215 fix: ToolNode output isn't a str and contains non-ASCII characters (#1505) 2024-08-29 09:57:23 -04:00
Harrison ChaseandGitHub 883b39ba9f docs: better name for react agent w/ structured output how-to (#1527) 2024-08-29 13:50:01 +00:00
Niklas MartinandGitHub 337ccc058f [docs]: fix type hint for state (#1528) 2024-08-29 13:47:05 +00:00
Isaac FranciscoandGitHub 6111d37b99 [docs]: different structured output method (#1497)
* wip

* spelling

* consistent headers

* slight changes

* spelling

* more comments

* link

* changes

* diagrams

* format

* final nits

* x
2024-08-28 20:45:23 -07:00
Isaac FranciscoandGitHub 6962aa5acc ocd (#1525) 2024-08-29 01:50:55 +00:00
Vadym BardaandGitHub 4769122828 docs: fix map-reduce issue (#1523) 2024-08-28 20:40:06 +00:00
Nuno Campos c4010c03a6 Udpate async tests 2024-08-28 12:50:35 -07:00
Nuno Campos 03f6cf779d Fix test setup 2024-08-28 12:48:29 -07:00
Nuno Campos 112700810c Fix 2024-08-28 12:31:43 -07:00
Isaac FranciscoandGitHub 2645eb5a48 [docs]: remove agent executor (#1485) 2024-08-28 14:54:52 -04:00
Isaac FranciscoandGitHub ab71d29286 [docs]: update node config info (#1500)
* config changes

* vadym comments

* format

* spelling

* x
2024-08-28 11:54:44 -07:00
Isaac FranciscoandGitHub da38905db7 [docs]: fix llm compiler (#1517) 2024-08-28 13:36:36 -04:00
Vadym BardaandGitHub 7d3527db38 cli: release 0.1.52 (#1516) 2024-08-28 12:12:46 -04:00
David DuongandGitHub 36ed1a5d4b Merge pull request #1503 from langchain-ai/dqbd/cli-studio-js
feat(cli): add building support for JS
2024-08-28 18:08:32 +02:00
Vadym BardaandGitHub 7637a769dd docs: update reflection notebook (#1515)
* docs: update reflection notebook

* update more

* update more
2024-08-28 12:07:29 -04:00
Tat Dat Duong 3bbe09dac4 Fix missing comma 2024-08-28 17:56:26 +02:00
Pratyush VermaandGitHub 8e6019a6b8 Merge branch 'main' into patch-1 2024-08-28 15:46:39 +01:00
Pratyush VermaandGitHub 666fb3f31d Fix typo 2024-08-28 15:45:02 +01:00
Vadym BardaandGitHub 947f8c8c1d docs: fix astream in reflection notebook (#1512) 2024-08-28 14:32:09 +00:00
Isaac FranciscoandGitHub 84cb3ea151 [docs]: recursion limit info (#1501)
* draft

* vadym comments

* spelling

* final nits

* final nits
2024-08-27 21:06:09 -07:00
Tat Dat Duong f4dea9c5f7 feat(cli): add building support for JS 2024-08-28 02:07:21 +02:00
Nuno Campos a8a2a89602 Fix docstring 2024-08-27 16:59:20 -07:00
Nuno Campos e338a4ec98 Fix filtering on ns 2024-08-27 16:09:11 -07:00
Nuno Campos 499fe10ef2 Undo addition of Send.id 2024-08-27 13:34:50 -07:00
Isaac FranciscoandGitHub a8758661bc acesss tool calls directly (#1495) 2024-08-27 14:47:20 -04:00
Nuno CamposandGitHub 8912d50312 Merge pull request #1498 from langchain-ai/nc/27aug/store-sends-once
Avoid storing Sends twice in memory and postgres checkpointers
2024-08-27 11:24:27 -07:00
Nuno Campos 8d23929288 Remove print 2024-08-27 11:18:53 -07:00
Nuno Campos 9b6100bc4f Avoid storing Sends twice in memory and postgres checkpointers
- Sends are stored through put_writes, so we don't need to also store them inside checkpoint object
- On reading checkpoint, reconstruct pending_sends from the stored writes
2024-08-27 11:10:18 -07:00
Nuno CamposandGitHub 238b562e78 Merge pull request #1496 from langchain-ai/nc/27aug/update-ruff
Update ruff
2024-08-27 11:06:43 -07:00
Nuno Campos 7fcc0da4e3 Reformat 2024-08-27 11:00:25 -07:00
Nuno Campos d7eff6ab85 Remove abc 2024-08-27 10:52:26 -07:00
Nuno Campos 330c91f622 Update ruff 2024-08-27 10:50:39 -07:00
3dbf6f144e [docs]: structured output from tool calling agent (#1480)
* first draft

* vadym comments

* Update docs/mkdocs.yml

Co-authored-by: Vadym Barda <vadym@langchain.dev>

* vadym comments

* spellign

* more comments

* spelling

* final nits

---------

Co-authored-by: Vadym Barda <vadym@langchain.dev>
2024-08-27 10:26:28 -07:00
Nuno Campos 8c2fefcb28 sdk-py: Add values to Thread schema 2024-08-27 08:42:55 -07:00
Vadym BardaandGitHub c88d289a73 checkpoint-postgres: release 1.0.4 (#1493) 2024-08-27 11:34:26 -04:00
Vadym BardaandGitHub d12f5c6d8b checkpoint-postgres: allow passing pool (#1452)
* checkpoint-postgres: allow passing pool

* make psycopg_pool a non-dev dependency

* code review

* lockfile

* move methods

* relax requirements, remove binary

* add binary to dev dependencies

* update readme
2024-08-27 15:30:13 +00:00
9ff54e029e [docs]: conceptual guide for astream_events (#1482)
---------

Co-authored-by: Vadym Barda <vadym@langchain.dev>
2024-08-27 15:18:51 +00:00
Nuno CamposandGitHub 2a89c7a5b4 Merge pull request #1492 from langchain-ai/nc/27aug/all-value-channels-same-checkpoint-get
lib: For all value channels the return value of checkpoint() and get() are the same
2024-08-27 08:15:45 -07:00
Nuno Campos f2ec99b9a8 lib: For all value channels the return value of checkpoint() and get() are the same 2024-08-27 08:10:26 -07:00
Vadym BardaandGitHub eb387cc946 docs: update cloud time travel docs to pass checkpoint_id correctly (#1483) 2024-08-27 13:26:22 +00:00
Vadym BardaandGitHub 54b53f384d sdk-js: release 0.0.8 (#1490) 2024-08-27 09:11:57 -04:00
isaac hershenson 86c047eb31 changes 2024-08-26 18:05:17 -07:00
Nuno CamposandGitHub 65784d8174 Merge pull request #1108 from langchain-ai/vb/update-get-state
langgraph: update get_state to handle nested subgraph state
2024-08-26 17:58:41 -07:00
vbarda 507930e5b7 lint 2024-08-26 19:29:05 -04:00
vbarda 85e698e20b filter on checkpoint NS 2024-08-26 19:26:35 -04:00
vbarda bf4dc5d5f6 Merge branch 'main' into vb/update-get-state 2024-08-26 19:17:26 -04:00
Nuno CamposandGitHub ce0fad8ddb Merge pull request #1484 from langchain-ai/vb/add-checkpoint-id-js-sdk
sdk-js: add checkpoint_id arg to runs create/stream/wait payload
2024-08-26 15:36:03 -07:00
Nuno Campos 1315c0d743 sdk-py0.1.29 2024-08-26 15:27:53 -07:00
vbarda ada751d19b better comment 2024-08-26 18:25:43 -04:00
vbarda f310716921 sdk-js: add checkpoint_id arg to runs create/stream/wait payload 2024-08-26 17:16:06 -04:00
Nuno CamposandGitHub 568044171b Merge pull request #1479 from langchain-ai/nc/26aug/with-config
Override with_config to store config in Pregel instance
2024-08-26 13:22:30 -07:00
Nuno Campos 1d0f3577a7 Catch any type error when reviving saved values 2024-08-26 13:17:19 -07:00
Nuno Campos 3979bdb792 Type as self 2024-08-26 13:14:11 -07:00
Nuno CamposandGitHub d8d663ccd5 Merge pull request #1371 from langchain-ai/wfh/set_entry
Use START
2024-08-26 12:01:51 -07:00
Nuno Campos 25a72e77ef Override with_config to store config in Pregel instance
- This enables eg customizing callbacks/metadata in langgraph cloud deployments
2024-08-26 11:57:57 -07:00
Alexander KovriginandGitHub da806c466d Allow passing ToolNode as tools in create_react_agent (#1451) 2024-08-26 13:47:50 -04:00
Vadym BardaandGitHub 49c316578b langgraph: allow END end key in add_edge with list inputs (#1478) 2024-08-26 12:51:18 -04:00
Nuno CamposandGitHub 7039a54871 Merge pull request #1477 from langchain-ai/nc/26aug/update-docs-constraints
docs: Update langgraph-api/cloud version constraints
2024-08-26 08:34:55 -07:00
Nuno CamposandGitHub ef17e0351a Merge pull request #1457 from langchain-ai/dependabot/npm_and_yarn/libs/sdk-js/micromatch-4.0.8
Bump micromatch from 4.0.7 to 4.0.8 in /libs/sdk-js
2024-08-26 08:25:46 -07:00
Nuno Campos 0d9c0732d4 docs: Update langgraph-api/cloud version constraints 2024-08-26 08:25:24 -07:00
William FHandGitHub a2cfe694f1 Fix import (#1472) 2024-08-25 20:47:05 -07:00
Nuno CamposandGitHub 858c166cae Merge pull request #1463 from langchain-ai/nc/24aug/sdk-on-completion
sdk: Add on_completion param
2024-08-24 21:38:11 -07:00
Nuno Campos 03785c7d83 sdk: Add on_completion param 2024-08-24 21:34:35 -07:00
David DuongandGitHub 93cb2a7730 Merge pull request #1460 from langchain-ai/dqbd/js-api-key
feat(sdk-js): add apiKey property
2024-08-24 19:29:57 +02:00
Tat Dat Duong 4b48e71d2c Bump to 0.0.7 2024-08-24 19:24:39 +02:00
Tat Dat Duong b7744aff9b feat(sdk-js): add apiKey property 2024-08-24 19:24:13 +02:00
Nuno Campos 4a4dd16535 checkpoint 1.0.6 2024-08-23 18:25:56 -07:00
Nuno Campos ef790a57c6 Lint 2024-08-23 18:17:51 -07:00
Nuno Campos c49692d794 checkpoint 1.0.5 2024-08-23 18:15:48 -07:00
Nuno Campos 3cda14b069 lib 0.2.14 2024-08-23 18:15:31 -07:00
Nuno Campos 66a13b8865 Add test for runtime value replacement with pydantic model 2024-08-23 18:15:15 -07:00
Nuno Campos 58e139e7fd Lint 2024-08-23 18:15:04 -07:00
Nuno Campos a8d860273b Skip runtime value replacement when not needed 2024-08-23 18:14:59 -07:00
Nuno Campos 3ac4cdf3d4 Fix pydantic model deserialization 2024-08-23 18:14:40 -07:00
Nuno Campos 3a524e0e56 Fix attributeerror 2024-08-23 17:55:14 -07:00
Andrew NguonlyandGitHub 134f8faf8c Add section about authentication to API reference. (#1458) 2024-08-23 17:14:16 -07:00
vbarda 904a1a3471 extra paranoia 2024-08-23 18:09:10 -04:00
vbarda cb30f68642 remove more reused code 2024-08-23 18:01:35 -04:00
vbarda 15692acef9 refactor to remove nested DB calls 2024-08-23 17:56:28 -04:00
dependabot[bot]andGitHub 610257665f Bump micromatch from 4.0.7 to 4.0.8 in /libs/sdk-js
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.7 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/4.0.8/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.7...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-23 20:36:31 +00:00
Nuno Campos bc482431c3 lib0.2.13 2024-08-23 13:35:21 -07:00
155e0c66d5 docs: add how-to for dynamic interrupts (#1446)
---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-08-23 20:34:33 +00:00
Nuno CamposandGitHub ca63a06549 Merge pull request #1455 from langchain-ai/nc/23aug/some-magic-for-will
lib: Context values never stored in checkpoints
2024-08-23 13:17:50 -07:00
Nuno Campos e8c553c41e Lint 2024-08-23 13:12:46 -07:00
Nuno Campos beafddf7c8 Lint 2024-08-23 13:09:28 -07:00
1e6da19257 Update libs/langgraph/langgraph/managed/context.py
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-08-23 13:08:56 -07:00
Nuno Campos e0898409b9 Lint 2024-08-23 12:57:31 -07:00
Nuno Campos bc86757e73 lib: Context values never stored in checkpoints
- Convert Context to a ManagedValue
- Add shim for old Context constructor
- Add `runtime` flag for managed values, which, prior to serialization, replaces the value with a placeholder, and replaces it back with the actual value on resuming from checkpoint
2024-08-23 12:46:31 -07:00
vbarda 71442916e5 lint 2024-08-23 14:52:31 -04:00
vbarda 1f29925034 add max recursion depth 2024-08-23 14:44:42 -04:00
Vadym BardaandGitHub 4c4d7054ab Merge branch 'main' into vb/update-get-state 2024-08-23 14:27:40 -04:00
vbarda 1333d8b478 cleanup 2024-08-23 14:26:54 -04:00
vbarda 2bac0d0f41 re-trigger CI 2024-08-23 13:51:57 -04:00
David DuongandGitHub ed7b2c9e8a Merge pull request #1443 from langchain-ai:dqbd/js-sdk-end-event
fix(sdk-js): support sending end events
2024-08-23 16:48:02 +02:00
Nuno CamposandGitHub 0597aedaff Merge pull request #1448 from langchain-ai/nc/22aug/serde-exceptions
Don't try to serialize exceptions
2024-08-22 21:41:06 -07:00
Nuno Campos 82db383199 Don't try to serialize exceptions
- Store their string repr instead
2024-08-22 21:36:27 -07:00
William FHandGitHub dec7eb6f58 [Docs] Use injected RunnableConfig (#1444)
* Pass via type

* Format
2024-08-22 18:54:42 -07:00
vbarda 065055e587 small change 2024-08-22 20:37:48 -04:00
vbarda 4162be8119 optimize subgraph state lookups 2024-08-22 20:35:08 -04:00
Nuno Campos 6ece7124ed Fix param name in docstring 2024-08-22 17:21:01 -07:00
Nuno CamposandGitHub ffa9b8672a Merge pull request #1445 from langchain-ai/nc/22aug/sdk-on-disconnect
sdk: Add on_disconnect arg to create/wait streaming run
2024-08-22 17:06:24 -07:00
Nuno Campos 19b382335f sdk: Add on_disconnect arg to create/wait streaming run 2024-08-22 17:03:11 -07:00
Tat Dat Duong c72acc9145 Add missing status 2024-08-23 01:38:53 +02:00
Nuno CamposandGitHub c30aa1ca13 Merge pull request #1337 from langchain-ai/nc/13aug/sdk-py-join-stream
sdk-py: Add Runs.join_stream endpoint
2024-08-22 15:38:23 -07:00
Nuno Campos 15c3105748 cli0.1.51 2024-08-22 15:37:02 -07:00
Tat Dat Duong 0b7f451b40 Bump to 0.0.6 2024-08-23 00:18:28 +02:00
Tat Dat Duong 75dec9b924 fix(sdk-js): support sending end events 2024-08-23 00:18:06 +02:00
Vadym BardaandGitHub 8090ca67c5 checkpoint-postgres: pass row_factory in cursor (#1433) 2024-08-22 17:39:21 -04:00
vbarda 9f6e57d2a7 more code review 2024-08-22 17:37:46 -04:00
vbarda 72893d9abb code review 2024-08-22 17:33:17 -04:00
Nuno CamposandGitHub 7074604204 Try to improve async stack traces for exceptions in tasks (#1442)
* Try to improve async stack traces for exceptions in tasks

* Lint
2024-08-22 21:23:48 +00:00
Nuno CamposandGitHub 0720b931e8 Merge pull request #1441 from langchain-ai/nc/22aug/test-checkpointers
Test all checkpointers everywhere we test 1 of them
2024-08-22 14:14:49 -07:00
vbarda 4935cf52bf lint 2024-08-22 16:52:16 -04:00
Nuno Campos 45e3d1a3f1 Test all checkpointers everywhere we test 1 of them 2024-08-22 13:51:38 -07:00
vbarda acd8acf237 lint 2024-08-22 16:47:12 -04:00
Nuno Campos 3ec419a2f6 lib0.2.12 2024-08-22 12:45:27 -07:00
Nuno Campos 8a00a0026e checkpoint1.0.4 2024-08-22 12:45:20 -07:00
Nuno CamposandGitHub 7e32de9405 Remove current_tasks from checkpoint interface (#1440)
* Remove current_tasks from checkpoint interface

- Not used, now clear that it can be supported with put_writes(SCHEDULE)

* Add comment
2024-08-22 19:44:26 +00:00
Nuno CamposandGitHub 96af4c72ce Merge pull request #1439 from langchain-ai/nc/22aug/rm-unused-when-values
Remove unused when values for Interrupt
2024-08-22 12:38:28 -07:00
vbarda 6c7d9c35bc remove interrupts 2024-08-22 15:37:20 -04:00
vbarda 5654d8fc86 Merge branch 'main' into vb/update-get-state 2024-08-22 15:34:14 -04:00
Nuno Campos f93512e3b3 Remove unused when values for Interrupt 2024-08-22 12:33:25 -07:00
Nuno CamposandGitHub a261e1a497 Fix semantics of put_writes/list (#1436)
* Fix semantics of put_writes/list

- put_writes(error) should not prevent saving future successful if task is retried successfully
- put_writes(writes) should be a no-op if non-error writes already exist for that task (this prevents tasks executed more than once from modifying writes previously saved / acted on)
- checkpoints should not include channel default values (ie those without a version)
- list() should fetch and return writes for each checkpoint

* Lint

* Rm print

* Fix import

* Lint
2024-08-22 19:04:42 +00:00
38daba5259 Better error messages for invalid update in all channel types (#1437)
* langgraph: support multiple edges for Topic channel annotations

* remove support_multiple_edges

* Better error messages for invalid update in all channel types

---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-08-22 18:59:29 +00:00
Vadym BardaandGitHub 078f9f7275 docs: fix manage conversation history how-to (#1438) 2024-08-22 14:56:34 -04:00
gbaian10andGitHub 22f5367af7 langgraph: fix add_node input schema error (#1332) 2024-08-22 12:32:21 -04:00
Hassan MemonandGitHub 4e2b508ebb docs: remove extra line from generate function (#1392) 2024-08-22 12:27:23 -04:00
Vadym BardaandGitHub 7ec3c0e827 langgraph: release 0.2.11 (#1432) 2024-08-22 11:54:47 -04:00
Nuno CamposandGitHub 82408bacf1 Merge pull request #1431 from langchain-ai/vb/fix-get-state-bug
langgraph: check for empty checkpoint when creating snapshot tasks
2024-08-22 08:52:00 -07:00
vbarda 9a306ce931 langgraph: check for empty checkpoint when creating snapshot tasks 2024-08-22 11:47:36 -04:00
Harrison ChaseandGitHub a9a59dd4e4 fix notebook (#1422) 2024-08-22 09:29:23 -04:00
Nuno Campos a545a70afb lib0.2.10 2024-08-21 16:33:30 -07:00
Nuno CamposandGitHub 4521f9312d Merge pull request #1420 from langchain-ai/nc/21aug/debug-mode-interrupts-errors
Add interrupts and errors to debug stream mode
2024-08-21 16:31:58 -07:00
Nuno Campos d67419522d Remove error 2024-08-21 16:27:23 -07:00
Nuno Campos d85e267a83 Add interrupts and errors to debug stream mode
- move remaining output code from Pregel.stream to PregelLoop
2024-08-21 16:23:48 -07:00
Vadym BardaandGitHub 426125cf96 Merge branch 'main' into vb/update-get-state 2024-08-21 19:20:20 -04:00
Nuno CamposandGitHub 4827377191 Merge pull request #1419 from langchain-ai/nc/21aug/cli-redis
cli: Add redis container to `langgraph up`
2024-08-21 16:19:09 -07:00
vbarda 0b6088f913 remove futures.clear 2024-08-21 18:26:54 -04:00
vbarda 578ec48031 Merge branch 'main' into vb/update-get-state 2024-08-21 18:21:28 -04:00
vbarda e7bc74e918 remove refactors 2024-08-21 18:06:18 -04:00
vbarda 0a87b9fa1c update more tests 2024-08-21 17:49:51 -04:00
Nuno Campos 37848a5361 cli: Add redis container to langgraph up 2024-08-21 14:37:36 -07:00
Nuno Campos 9147d05cc4 lib0.2.9 2024-08-21 14:32:15 -07:00
Nuno CamposandGitHub 46171dd759 Merge pull request #1418 from langchain-ai/nc/21aug/fix-pending-interrupt-run
Fix pending run when interrupt exception is used
2024-08-21 14:29:59 -07:00
Nuno Campos 47ed3d97e9 Fix pending run when interrupt exception is used 2024-08-21 14:25:00 -07:00
Nuno CamposandGitHub 06c2481783 Merge pull request #1415 from langchain-ai/nc/21aug/loop-rm-pregel-arg
Remove graph arg to PregelLoop
2024-08-21 14:24:40 -07:00
Vadym BardaandGitHub 1907646bd4 sdk-py: release 0.1.28 (#1417) 2024-08-21 17:10:18 -04:00
Vadym BardaandGitHub 3a65f83ae1 sdk-py: allow passing custom headers (#1416) 2024-08-21 21:05:03 +00:00
Nuno CamposandGitHub 57811a6bfd Merge pull request #1414 from langchain-ai/nc/21aug/combine-managers
Combine channel and managed values manager
2024-08-21 13:49:15 -07:00
Nuno Campos 02697b5712 Remove graph arg to PregelLoop 2024-08-21 13:45:42 -07:00
Nuno Campos e76f4cc434 Combine channel and managed values manager 2024-08-21 13:30:18 -07:00
vbarda f51e7ea9a4 pass pending writes in checkpointers 2024-08-21 15:38:30 -04:00
Nuno Campos 14ec51601c lib0.2.8 2024-08-21 12:09:11 -07:00
Nuno CamposandGitHub 14976d4c56 Interrupts shouldn't be retried (#1413)
* Interrupts shouldn't be retried

* Add async test

* Lint
2024-08-21 12:08:58 -07:00
vbarda a94168af7f Merge branch 'main' into vb/update-get-state 2024-08-21 15:07:52 -04:00
Nuno Campos 2f41b2891b lib0.2.7 2024-08-21 11:33:54 -07:00
Nuno CamposandGitHub c857a77dd1 Merge pull request #1352 from langchain-ai/nc/14aug/scoped-value
Add SharedValue
2024-08-21 11:33:18 -07:00
Nuno Campos 5fb2c2c6f8 Lint 2024-08-21 11:27:04 -07:00
Nuno Campos 4250ff92b8 Fix 2024-08-21 11:25:37 -07:00
Nuno Campos 7fd4a9ed30 Lint 2024-08-21 10:48:52 -07:00
Nuno Campos 2106b5e4a6 Lint 2024-08-21 10:48:04 -07:00
Nuno Campos 1af0367b34 Add error message 2024-08-21 09:41:53 -07:00
Nuno Campos f037a2e9cb Update docstring 2024-08-21 09:39:58 -07:00
Nuno Campos aa1a6be160 Rename more 2024-08-21 09:36:21 -07:00
Nuno Campos c9e6ee6da7 Rename 2024-08-21 09:34:12 -07:00
Nuno Campos bd7b9cca21 WIP 2024-08-21 09:30:47 -07:00
Nuno Campos b228fc1a9b Add serde 2024-08-21 09:30:34 -07:00
Nuno Campos c3794f1fd3 Use batched async kv inside loop 2024-08-21 09:30:22 -07:00
Nuno Campos 4e1db854f6 Add async test 2024-08-21 09:30:22 -07:00
Nuno Campos 630d9c79ed Split out async batch to sep file 2024-08-21 09:30:22 -07:00
Nuno Campos 8f8f3849fc Lint 2024-08-21 09:30:22 -07:00
Nuno Campos 656f89e16a Lint 2024-08-21 09:30:22 -07:00
Nuno Campos 9b90a24d94 Lint 2024-08-21 09:30:22 -07:00
Nuno Campos 77d7deb033 Rename 2024-08-21 09:30:22 -07:00
Nuno Campos 7ca37afc74 Fix 2024-08-21 09:30:21 -07:00
Nuno Campos 2bc0e2df42 Fix 2024-08-21 09:30:21 -07:00
Nuno Campos 1dc09dc45f Remove warning on write to managed channel 2024-08-21 09:30:21 -07:00
Nuno Campos 1cc02825ea Add ScopedValue
- state shared between threads
2024-08-21 09:30:21 -07:00
Nuno Campos d1b7a787ee lib0.2.6 2024-08-21 09:22:27 -07:00
Nuno CamposandGitHub f8b053a286 Enable raising Interrupt from inside a node, add list of current interrupts to get_state (#1354)
* Enable raising Interrupt from inside a node, add list of current interrupts to get_state

* Lint

* Allow multiple interrupt values in exception

* Better typings

* Fix some tests

* Fix up

* Lint

* Add test

* Lint

* WIP stay=True

* Fix tests for get_state

* Remove ids

* Fix step count

* 999

* less fun

* Undo

* Update debug interface

* Remove ability to pass multiple values

* Undo
2024-08-21 16:19:15 +00:00
David DuongandGitHub ebf060675d feat(js-sdk): add config and parent_config to thread state schema (#1411)
* feat(js-sdk): add config and parent_config to thread state schema

* Bump to 0.0.5
2024-08-21 17:00:10 +02:00
Nuno Campos 3d33b575d6 0.2.5 2024-08-20 16:59:04 -07:00
Vadym BardaandGitHub 314488b5c5 ci: run full test suite on all changes (#1397) 2024-08-20 08:47:12 -04:00
Nuno CamposandGitHub 6e4dc26890 Merge pull request #1396 from langchain-ai/nc/19aug/fix-args
postgres: Fix args to put_writes
2024-08-19 15:57:44 -07:00
Nuno Campos 9cfb4b01c8 postgres: Fix args to put_writes 2024-08-19 15:54:49 -07:00
Nuno CamposandGitHub e7d2621a05 Merge pull request #1395 from langchain-ai/nc/19aug/put-writes-idempotent
checkpoint-*: In put_writes clear any previously saved writes for this task_id
2024-08-19 15:48:40 -07:00
Nuno Campos c0c534cbe3 Add pipeline arg 2024-08-19 15:44:22 -07:00
Nuno Campos 7aaeedd7ba checkpoint-*: In put_writes clear any previously saved writes for this task_id
- Previously implementations were clearing only tasks if the index matched a previously saved one, which isn't enough to guarantee idempotency
2024-08-19 15:40:04 -07:00
Nuno CamposandGitHub e15d56c2f2 Merge pull request #1390 from langchain-ai/nc/19aug/add-xray-test
Add xray test for issue #593
2024-08-19 12:09:51 -07:00
Nuno Campos 8a7c6b4fa7 Add xray test 2024-08-19 12:05:36 -07:00
Nuno CamposandGitHub 2e073473dc Merge pull request #1389 from langchain-ai/nc/19aug/fix-ready-signal
cli: Fix ready signal
2024-08-19 08:26:14 -07:00
Nuno Campos 31dcd15927 cli: Fix ready signal 2024-08-19 07:52:00 -07:00
William Fu-Hinthorn 1bd40b2ebf Do markdown 2024-08-16 15:45:56 -07:00
William Fu-Hinthorn b5429b6342 Use START 2024-08-16 15:43:24 -07:00
Nuno CamposandGitHub fc95028738 Merge pull request #1370 from langchain-ai/nc/16aug/checkpoint-errors
Checkpoint errors in pending_writes, expose under StateSnapshot.tasks
2024-08-16 13:15:40 -07:00
Nuno Campos e916cab08f Checkpoint errors in pending_writes, expose under StateSnapshot.tasks
- Save errors produced by tasks, under pending_writes
- Re-work logic to cancel other tasks when one fails, ready to change for interrupt exception
- Update serializer to handle exceptions
- Update get_state/get_state_history with new return value property "tasks" which contains a richer description of the next tasks, currently with id, name and error (if already ran and errored)
2024-08-16 13:11:27 -07:00
Vadym BardaandGitHub e4f1f90127 update pyproject in monorepo to reflect consistent min python version (#1369) 2024-08-16 15:41:56 +00:00
Nuno Campos a16a33806c lib0.2.4 2024-08-15 15:37:51 -07:00
Nuno CamposandGitHub 007f419bdc Merge pull request #1363 from Glavin001/patch-1
Include exception traceback in run_with_retry logging
2024-08-15 15:37:01 -07:00
Isaac FranciscoandGitHub 5bee9e92b5 [docs]: add studio desktop callout (#1361) 2024-08-15 22:35:04 +00:00
Nuno Campos 6a68581a9f Lint 2024-08-15 15:32:48 -07:00
Nuno Campos 78781b0a90 Use exc_info 2024-08-15 15:23:54 -07:00
Glavin WiechertandGitHub d15c5a46de Include exception traceback in run_with_retry logging 2024-08-15 18:29:05 -03:00
Isaac FranciscoandGitHub ce37fd3a04 [docs]: studio faqs (#1207)
* draft

* spelling

* rephrases

* vadym comments
2024-08-15 11:56:00 -07:00
Isaac FranciscoandGitHub 64636ee978 [docs]: add auth and small changes (#1356)
* wip

* m

* nit
2024-08-15 18:25:53 +00:00
Isaac FranciscoandGitHub 388a9643a5 [docs]: copying threads (#1350)
* wip

* wip

* wip

* vadym comments
2024-08-15 11:19:18 -07:00
Nuno CamposandGitHub c9f4b5aede Merge pull request #1360 from langchain-ai/nc/14auug/debug-checkpoint-full
Add missing attributes to checkpoint event in debug output
2024-08-15 10:26:27 -07:00
Nuno CamposandGitHub 855139d869 Merge pull request #1299 from langchain-ai/dependabot/pip/libs/langgraph/aiohttp-3.10.2
build(deps-dev): bump aiohttp from 3.9.5 to 3.10.2 in /libs/langgraph
2024-08-15 10:20:16 -07:00
Nuno Campos d07cbd34ce checkpoint1.0.3 2024-08-15 10:19:50 -07:00
Nuno Campos c701fef634 Lint 2024-08-15 09:40:53 -07:00
Nuno Campos 2c8fc3c9c6 Add missing attributes to checkpoint event in debug output 2024-08-15 09:30:29 -07:00
vbarda 45054df71a remove include_subgraph_state kwarg 2024-08-14 21:07:56 -04:00
Isaac FranciscoandGitHub 8ad797e261 fix (#1353) 2024-08-14 17:16:00 -07:00
Nuno CamposandGitHub 2dbfc8aca3 Merge pull request #1344 from langchain-ai/nc/14aug/ignore-serialized-values-missing-constructor
checkpoint: Ignore serialized values when constructor no longer available
2024-08-14 14:43:57 -07:00
vbarda 7fa97898aa correctly propagate all subgraph attributes 2024-08-14 16:15:08 -04:00
Isaac FranciscoandGitHub 3b2d5f02e1 [docs]: cloud how to for checking thread status (#1346)
* draft

* nit

* harrison comments

* spelling
2024-08-14 11:56:43 -07:00
Isaac FranciscoandGitHub 34fd833b04 [docs]: purge message graph (#1330)
* purge message graph

* docstrings

* use with dicts
2024-08-14 11:16:38 -07:00
vbarda 6531ec7669 remove inherit checkpointer 2024-08-14 14:14:06 -04:00
Nuno Campos 728b283063 checkpoint: Ignore serialized values when constructor no longer available 2024-08-14 10:59:14 -07:00
Isaac FranciscoandGitHub a3dd43b39b x (#1343) 2024-08-14 16:32:49 +00:00
Isaac FranciscoandGitHub 41a6eb7cf4 [docs]: add CURL commands to some how-tos (#1325) 2024-08-14 12:31:24 -04:00
vbarda 409b915a3f code review 2024-08-14 12:10:07 -04:00
Isaac FranciscoandGitHub c04133b1df [docs]: cloud hil review tool calls (#1334)
* hil review tool calls

* interrupt note
2024-08-14 08:03:15 -07:00
Hassan MemonandGitHub d1450a463e Improved description for chatbot node function (#1339)
Updated the documentation to describe the chatbot node function's return value in a more Pythonic and enthusiastic way. The description now emphasizes that the function returns a dictionary with the updated messages list neatly tucked under the messages key.
2024-08-14 14:12:37 +00:00
Hassan MemonandGitHub 8daeb56194 Fix typo in documentation: corrected 'they agent's' to 'their agent's' (#1338) 2024-08-14 10:08:26 -04:00
Nuno Campos 3b56cdf524 Add Runs.join_stream endpoint 2024-08-13 17:35:31 -07:00
vbarda d9618880a3 update logic for latest snapshot's subgraph snapshots 2024-08-13 20:13:13 -04:00
Nuno CamposandGitHub aa1b94166c Merge pull request #1329 from langchain-ai/nc/13aug/config-checkpoint-passthrough
Passthrough checkpoint in config even when current sub-graph didn't choose to use it
2024-08-13 16:49:12 -07:00
Isaac FranciscoandGitHub 307ae4cf66 link fixes (#1336) 2024-08-13 23:11:01 +00:00
Vadym BardaandGitHub 392891f5fc Merge branch 'main' into vb/update-get-state 2024-08-13 18:20:32 -04:00
vbarda 58887a5a3b checkpoints/interrupts for subgraphs triggered by sends 2024-08-13 18:15:57 -04:00
gbaian10andGitHub 0a25e865b9 docs: fix persistence_postgres.ipynb (#1328)
* docs: fix DB_URI port
* docs: remove unuse import
2024-08-13 16:06:13 -04:00
Nuno Campos a01c1c2bfa Passthrough checkpoint in config even when current sub-graph didn't choose to use it 2024-08-13 10:27:48 -07:00
vbarda 3295274711 fix empty snapshot 2024-08-13 10:23:53 -04:00
vbarda 0135c6f743 correct check for using parent checkpointer 2024-08-13 10:07:52 -04:00
Nuno CamposandGitHub e2a72bf511 Merge pull request #1311 from langchain-ai/nc/11aug/serde-more
checkpoint: Add support for serializing more python types
2024-08-12 17:54:07 -07:00
Vadym BardaandGitHub 519b3b9ce1 docs: add async python<=3.10 warning to streaming concepts (#1324)
* docs: add async python<=3.10 warning to streaming concepts
2024-08-13 00:48:20 +00:00
Vadym BardaandGitHub 0456f52195 Merge branch 'main' into vb/update-get-state 2024-08-12 20:30:56 -04:00
vbarda b5caf1ad3f Merge branch 'vb/update-get-state' of github.com:langchain-ai/langgraph into vb/update-get-state 2024-08-12 20:29:15 -04:00
vbarda f65d9b2b7d pass subgraph nodes/channels 2024-08-12 20:29:09 -04:00
Lenni JustenandGitHub 408676913c Remove extra bullet from index.md (#1149) 2024-08-12 17:21:32 -04:00
Vadym BardaandGitHub 21c842baf6 docs: update streaming example (#1321)
* docs: update streaming example
2024-08-12 21:11:07 +00:00
Vadym BardaandGitHub a03886b9e4 Merge branch 'main' into vb/update-get-state 2024-08-12 16:53:18 -04:00
Lance MartinandGitHub f7bda4c940 Minor clarifications on Memory in docs (#1301)
* Minor clarifications on Memory in docs

* Address comments
2024-08-12 13:42:57 -07:00
vbarda abe9b7c08e lint 2024-08-12 16:32:22 -04:00
vbarda 6d4cdc9456 opt-in 2024-08-12 16:29:15 -04:00
vbarda 5033044587 update checkpointer tests 2024-08-12 16:22:27 -04:00
vbarda 246dd0f8c0 Merge branch 'vb/update-get-state' of github.com:langchain-ai/langgraph into vb/update-get-state 2024-08-12 15:52:33 -04:00
vbarda fb05bdc2bf return all checkpoints from .list 2024-08-12 15:52:17 -04:00
vbarda 9948125745 add checkpointer=INHERIT_CHECKPOINTER 2024-08-12 14:27:50 -04:00
gbaian10andGitHub b8233ded23 docs: fix filter_messages error in manage-conversation-history.ipynb (#1315)
fix: #1314
2024-08-12 14:16:59 -04:00
Vadym BardaandGitHub 6a22b7c26f docs: update async connection pool example in postgres how-to (#1318) 2024-08-12 13:24:59 -04:00
vbarda 322cfc46d3 cleanup 2024-08-12 12:43:28 -04:00
vbarda c9d6a41d75 Merge branch 'main' into vb/update-get-state 2024-08-12 10:26:56 -04:00
Nuno Campos a64c0a2679 Add pathlib.Path and re.Pattern 2024-08-11 19:40:11 -07:00
Nuno Campos fdc5aece52 Add Decimal 2024-08-11 19:34:22 -07:00
Nuno Campos 685db62029 checkpoint: Add support for serializing more python types
- all ip interfaces
- deque,
- ZoneInfo
- date
- time
2024-08-11 19:27:29 -07:00
Nuno CamposandGitHub 4e643baaa6 Merge pull request #1309 from langchain-ai/nc/11aug/skip-context-get-state
Skip initializing Context channels when calling get_state/get_state_history
2024-08-11 10:56:54 -07:00
Nuno Campos 9634468260 Skip initializing Context channels when calling get_state/get_state_history 2024-08-11 10:47:19 -07:00
Isaac FranciscoandGitHub 00c1b6a2b0 callouts (#1269) 2024-08-09 16:43:03 -07:00
dependabot[bot]andGitHub b45273d112 build(deps-dev): bump aiohttp from 3.9.5 to 3.10.2 in /libs/langgraph
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.5 to 3.10.2.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.5...v3.10.2)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-09 18:26:13 +00:00
350adae672 hil concepts (#1298)
* hil concepts

* spelling

---------

Co-authored-by: isaac hershenson <ihershenson@hmc.edu>
2024-08-09 10:59:04 -07:00
Isaac FranciscoandGitHub bdb3832985 [docs]: changing setup docs (#1285)
* wip

* draft
2024-08-09 10:07:39 -07:00
Vadym BardaandGitHub 1fc8718352 docs: update how-to for mongodb (#1297)
* docs: update how-to for mongodb
2024-08-09 16:34:11 +00:00
Vadym BardaandGitHub d98eec6e91 checkpoint-postgres: vbump & add a note to readme (#1295) 2024-08-09 09:42:53 -04:00
Vadym BardaandGitHub 659586947d checkpoint-postgres: fix setup for AsyncPostgresSaver (#1294) 2024-08-09 13:39:30 +00:00
Vadym BardaandGitHub c303ef2a2b docs: update redis how-to (#1286) 2024-08-09 02:06:28 +00:00
ff92beb88a review tool calls (#1283)
* review tool calls

* spelling

* link

* link

---------

Co-authored-by: isaac hershenson <ihershenson@hmc.edu>
2024-08-08 18:02:02 -07:00
Jacob LeeandGitHub dce73fde66 Clarify send API docstring (#1280) 2024-08-08 12:59:23 -07:00
Vadym BardaandGitHub da6462e608 langgraph: release 0.2.3 (#1279) 2024-08-08 12:43:24 -04:00
Vadym BardaandGitHub 49bf8f6816 checkpoint-postgres: release 1.0.2 (#1278) 2024-08-08 12:42:06 -04:00
Vadym BardaandGitHub 71ce07d971 checkpoint: update docstrings for checkpoint libraries (#1277) 2024-08-08 16:26:16 +00:00
Vadym BardaandGitHub a16f86b5bd docs: update postgres persistence example (#1276) 2024-08-08 12:01:19 -04:00
Vadym BardaandGitHub 4dc27b98f1 langgraph, checkpoint-postgres: propagate new versions in update_state (#1270)
* langgraph, checkpoint-postgres: propagate new versions in update_state
2024-08-08 11:55:55 -04:00
Isaac FranciscoandGitHub be8476d981 added context (#1242) 2024-08-08 11:24:52 -04:00
Vadym BardaandGitHub cd92f19858 docs (examples): replace SqliteSaver with MemorySaver (#1271) 2024-08-08 10:30:43 -04:00
a2f4d57bf2 langgraph: more checkpointer tests (#1263)
* langgraph: more checkpointer tests

* more tests

* lint

* update tests

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-08-08 00:45:46 +00:00
Nuno CamposandGitHub f9fa35ed82 Merge pull request #1267 from langchain-ai/vb/update-empty-channels
checkpoint-postgres: set unset channel values to empty in blobs
2024-08-07 17:40:58 -07:00
Vadym BardaandGitHub 3b87a81c70 Merge branch 'main' into vb/update-empty-channels 2024-08-07 20:18:10 -04:00
Nuno CamposandGitHub 002b260e7a Various small changes (#1268) 2024-08-07 20:17:47 -04:00
vbarda 659c9881cf cleanup 2024-08-07 19:54:45 -04:00
vbarda b535d38393 test 2024-08-07 19:53:41 -04:00
vbarda d33807b5ea checkpoint-postgres: remove unset channel values from blobs 2024-08-07 17:31:07 -04:00
Nuno Campos 9650f0d41d postgres1.0.1 2024-08-07 12:15:40 -07:00
Nuno Campos 127b6dedee lib0.2.2 2024-08-07 12:14:34 -07:00
Nuno CamposandGitHub db5a6c569a Merge pull request #1265 from langchain-ai/nc/7aug/stream-nodes-wout-writes
Include in stream output all nodes ran, even if they returned no writes to state keys
2024-08-07 12:11:58 -07:00
Nuno CamposandGitHub b47ab6c30a Merge pull request #1264 from langchain-ai/nc/7aug/fix-tests
fix test setup for checkpointers
2024-08-07 12:08:22 -07:00
Nuno Campos 281c97b9e5 Include in stream output all nodes ran, even if they returned no writes to state keys
- This also includes these nodes in checkpoint.metadata.writes
2024-08-07 12:05:45 -07:00
Nuno Campos cb21a3547e Skip async postgres tests in 3.9 2024-08-07 12:04:11 -07:00
Nuno Campos 6028eb02c9 Lint 2024-08-07 11:49:46 -07:00
Nuno Campos 712d52ad3b fix test setup for checkpointers 2024-08-07 11:39:14 -07:00
Nuno CamposandGitHub 6078c408c3 Raise exception for reducers w wrong signature (#1261) 2024-08-07 17:48:07 +00:00
Nuno CamposandGitHub 9caeeaeeec Merge pull request #1258 from langchain-ai/nc/7aug/postgres-dont-sync-too-much
postgres: Avoid syncing pipeline unless actually needed
2024-08-07 09:43:52 -07:00
Nuno Campos 2bd9eb4298 postgres: Avoid syncing pipeline unless actually needed 2024-08-07 09:40:18 -07:00
Nuno CamposandGitHub 4c2542aac6 Merge pull request #1257 from langchain-ai/nc/7aug/postgres-migrations
postgres: Add migration tracking
2024-08-07 09:33:10 -07:00
vbarda 54da68cfe7 remove flag 2024-08-07 12:25:34 -04:00
vbarda 51b62ca0bd remove setup 2024-08-07 12:23:00 -04:00
Vadym BardaandGitHub ca4b65e1a6 checkpoint-postgres: use correct metadata serialization (#1255) 2024-08-07 12:13:44 -04:00
Nuno Campos 1e237bf33a postgres: Add migration tracking 2024-08-07 08:54:08 -07:00
Vadym BardaandGitHub fb8390e138 langgraph: release 0.2.1 (#1250) 2024-08-07 09:55:50 -04:00
Vadym BardaandGitHub 5cab47f751 checkpoint: move memory into a directory to fix namespace import issues (#1249) 2024-08-07 09:41:06 -04:00
Vadym BardaandGitHub 172b4af6ed langgraph: release 0.2.0 (#1246) 2024-08-06 23:25:18 -04:00
Vadym BardaandGitHub 186dfd3976 checkpoint-postgres: release 1.0.0 (#1245) 2024-08-06 22:53:29 -04:00
Vadym BardaandGitHub d9adebed84 checkpoint-sqlite: release 1.0.0 (#1244) 2024-08-06 22:43:35 -04:00
Vadym BardaandGitHub 2b860f04ce checkpoint: release 1.0.1 (#1243) 2024-08-06 22:38:13 -04:00
b37f78942d checkpoint-postgres: new library for postgres checkpointer implementation (#1236)
* checkpoint-postgres: new library for postgres checkpointer implementation

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-08-06 22:37:06 -04:00
Nuno CamposandGitHub 81e60893b6 Merge pull request #1240 from langchain-ai/nc/6aug/untracked-value
Add UntrackedValue to mark a state key as not checkpointable
2024-08-06 17:15:19 -07:00
Emil WåreusandGitHub 657cd30045 Update pass_private_state.ipynb (#1213)
Fix typo
2024-08-06 23:59:58 +00:00
Vadym BardaandGitHub 7cf2132df1 Merge branch 'main' into nc/6aug/untracked-value 2024-08-06 19:46:56 -04:00
vbarda b0b6c0ae7b lint + comment 2024-08-06 19:46:39 -04:00
Nuno Campos 5f9b0bc0ae Add UntrackedValue to mark a state key as not checkpointable 2024-08-06 15:41:52 -07:00
Nuno CamposandGitHub f7c09f5e9e Fix output schema affecting stream output (#1239)
* Fix output schema affecting stream output

* Remove file

* Remove file
2024-08-06 22:26:43 +00:00
Andrew NguonlyandGitHub 9c1aeb31dd Remove LangGraph Cloud waitlist from README (#1238)
* Remove waitlist from README.

* Remove waitlist from Cloud index page.

* Remove waitlist from README.
2024-08-06 13:32:55 -07:00
gbaian10andGitHub 43fb6012be fix: the execution error passed from ToolExecutor to create_react_agent (#1234) 2024-08-06 17:51:55 +00:00
Nuno CamposandGitHub 997a2afc79 Merge pull request #1233 from langchain-ai/nc/6aug/add-test-inherited-state-keys
Add test for inherited state keys
2024-08-06 09:30:59 -07:00
Nuno Campos f050f71584 Add test for inherited state keys 2024-08-06 09:20:33 -07:00
Nuno CamposandGitHub 3b63010673 Merge pull request #1232 from langchain-ai/dqbd/js-output-schema
feat(sdk-js): add output schema to match API, expose copy method for thread
2024-08-06 08:18:00 -07:00
Tat Dat Duong bb47a0d9b7 Reformat 2024-08-06 16:24:12 +02:00
Tat Dat Duong 475019731a Bump to 0.0.4 2024-08-06 15:34:28 +02:00
Tat Dat Duong 1e3a0aa88c Expose copy method for thread 2024-08-06 14:15:04 +02:00
Tat Dat Duong 3ba8500e90 feat(sdk-js): Add output schema typedef 2024-08-06 14:06:47 +02:00
Nuno CamposandGitHub 8850e8a373 Merge pull request #1228 from langchain-ai/vb/update-sqlite
checkpoint: stop using sqlite checkpointers as context managers, make memorysaver a context manager
2024-08-05 14:09:42 -07:00
vbarda 566e6c9b60 fix 2024-08-05 17:03:50 -04:00
vbarda 9aaa73cc55 undo comment 2024-08-05 16:55:19 -04:00
vbarda 55717c9bde update memory saver + tests 2024-08-05 16:53:33 -04:00
vbarda 64c30508d9 checkpoint-sqlite: stop using checkpointers as context managers, use contextmanager only in from_conn_string 2024-08-05 16:20:16 -04:00
ccurmeandGitHub a00ace21cb Merge pull request #1227 from langchain-ai/cc/fix_toolbar_title
docs: update title of doc in sidebar
2024-08-05 14:00:29 -04:00
Chester Curme e590a027db update title of doc in sidebar 2024-08-05 13:57:22 -04:00
ccurmeandGitHub 2976d4a3ba Merge pull request #1117 from langchain-ai/cc/many_tools_guide
docs: add how-to guide for handling many tools
2024-08-05 13:55:58 -04:00
Chester Curme 14d448b74d remove usage of upsert 2024-08-05 13:45:47 -04:00
Chester Curme ad31da06d1 update script + index + mkdocs 2024-08-05 13:34:30 -04:00
Chester Curme f124ce2f72 move file 2024-08-05 13:28:54 -04:00
Chester Curme 95f1032215 Merge branch 'main' into cc/many_tools_guide 2024-08-05 13:25:32 -04:00
Nuno CamposandGitHub c2c5b31f4b Merge pull request #1223 from langchain-ai/nc/5aug/test-update-state-custom-class
Add test for update_state when using custom state class
2024-08-05 09:00:34 -07:00
Nuno Campos e8c2fefb29 Add test for update_state when using custom state class 2024-08-05 08:54:16 -07:00
Nuno Campos 4f2f5f7cbc sdk0.1.27 2024-08-03 11:47:21 -07:00
Nuno CamposandGitHub 2ae1121994 sdk: Use an identifiable root path (#1216) 2024-08-03 18:46:36 +00:00
Nuno CamposandGitHub 3b5669a90b Merge pull request #1215 from langchain-ai/nc/3aug/sdk-asgi
sdk: Use ASGI transport when called inside langgraph-api
2024-08-03 11:20:26 -07:00
Nuno Campos 85454b6371 sdk: Use ASGI transport when called inside langgraph-api 2024-08-03 11:17:34 -07:00
Nuno CamposandGitHub 25a98fa888 Merge pull request #1210 from langchain-ai/vb/update-deps
checkpoint-sqlite: add checkpoint dependency
2024-08-02 17:14:54 -07:00
vbarda 2370db0f8c order 2024-08-02 19:08:16 -04:00
vbarda 1b353aed73 checkpoint-sqlite: add checkpoint dependency 2024-08-02 19:06:38 -04:00
Vadym BardaandGitHub 7b441e64e7 ci: update import pre-release check (#1209)
* ci: update import pre-release check

* fix
2024-08-02 18:58:04 -04:00
Vadym BardaandGitHub 351a29fcfb ci: handle initial library version in tags (#1208) 2024-08-02 18:44:25 -04:00
Vadym BardaandGitHub c149a99b44 checkpoint-sqlite: new library for sqlite checkpointer implementation (#1203)
* checkpoint-sqlite: new library for sqlite checkpointer implementation
2024-08-02 22:14:12 +00:00
Nuno CamposandGitHub 16a6450534 Merge pull request #1191 from langchain-ai/dqbd/js-sdk-types
feat(sdk-js): bump to 0.0.3, update types of updateState
2024-08-02 13:05:20 -07:00
Nuno CamposandGitHub 045f07c396 Merge pull request #1204 from langchain-ai/nc/2aug/graph-metadata-interrupt
Add interrupt info to graph repr
2024-08-02 13:05:11 -07:00
Nuno CamposandGitHub 373bcfe5cf Merge pull request #1206 from langchain-ai/nc/2aug/test-watch-all
Add make test_watch_all command
2024-08-02 13:04:39 -07:00
2742b2f884 aupdate_state now accepts null values (#1181)
* aupdate_state now accepts null values

---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-08-02 15:59:15 -04:00
Nuno Campos c30e80df67 Add missing 2024-08-02 12:59:11 -07:00
Nuno Campos 55044ba231 Add make test_watch_all command 2024-08-02 12:56:53 -07:00
Nuno Campos b1d0dbac77 Add interrupt info to graph repr 2024-08-02 12:20:56 -07:00
Nuno CamposandGitHub 742f17689e Merge pull request #1199 from langchain-ai/vb/bump-core
langgraph: bump core to 0.2.27
2024-08-02 12:07:23 -07:00
Vadym BardaandGitHub bbd5e692e1 checkpoint: release 1.0.0 (#1201) 2024-08-02 14:10:00 -04:00
Isaac FranciscoandGitHub c40df063d6 draft (#1200) 2024-08-02 11:06:52 -07:00
vbarda a0cd3ff7ad langgraph: bump core to 0.2.27 2024-08-02 13:56:26 -04:00
Nuno CamposandGitHub b2b31a323b Merge pull request #1197 from langchain-ai/nc/2aug/managed-rm-graph-arg
Remove graph arg from ManagedValue
2024-08-02 09:28:07 -07:00
Vadym BardaandGitHub 50eea98fc6 langgraph: remove deprecations and add new warnings (#1196)
* langgraph: remove deprecations and add new warnings
2024-08-02 12:18:34 -04:00
Nuno Campos a83718bec8 Remove graph arg from ManagedValue 2024-08-02 08:49:41 -07:00
Vadym BardaandGitHub 4d7a42a65e langgraph: remove FewShotExamples managed value (#1195) 2024-08-02 11:05:17 -04:00
Isaac FranciscoandGitHub 487157eafa typo fix (#1169) 2024-08-01 21:48:37 -04:00
4b2187c9a3 checkpoint: switch thread_ts -> checkpoint_id, add checkpoint_ns, change serializer protocol (#1185)
---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-08-02 01:08:19 +00:00
Tat Dat Duong a6e32e57e8 Bump to 0.0.3 2024-08-01 14:14:40 -07:00
Tat Dat Duong 51dbb9493c Improve types for updateState 2024-08-01 14:14:12 -07:00
Nuno CamposandGitHub 862afa27de Merge pull request #1189 from langchain-ai/nfcampos-patch-2
Update constraints
2024-08-01 10:13:18 -07:00
Nuno CamposandGitHub aa8cd8259d Update setup_pyproject.md 2024-08-01 10:08:42 -07:00
Nuno CamposandGitHub 000066d1a1 Update setup.md 2024-08-01 10:08:07 -07:00
Nuno CamposandGitHub cd2b6642ee Merge pull request #1188 from langchain-ai/nc/1aug/update-sdks
Nc/1aug/update sdks
2024-08-01 09:54:47 -07:00
Nuno Campos 15ded2c17b Mark all schemas as optional in js and py sdk typings 2024-08-01 09:43:46 -07:00
Nuno Campos e4905f438a Fix create entrypoints script 2024-08-01 09:43:30 -07:00
Nuno Campos eb762c4a77 Undo 2024-07-31 15:02:25 -07:00
Nuno Campos ea5eb73b9f Enable builds outside of master 2024-07-31 15:00:44 -07:00
ae74825ea7 langgraph checkpoint: new library for checkpoint interfaces (#1163)
---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-07-31 16:45:52 -04:00
Nuno CamposandGitHub 913a2d975b Merge pull request #1180 from langchain-ai/eugene/add_any_id_handling
langgraph[patch]: update unit tests to handle AnyStr() for pydantic 2 models
2024-07-31 12:30:54 -07:00
Eugene Yurtsev 5043aaf4fa UPdate 2024-07-31 14:33:20 -04:00
Vadym BardaandGitHub c3f6c58e13 docs: fix typo in retries (#1177) 2024-07-31 14:39:43 +00:00
Nuno Campos 298c93ca4a lib0.1.17 2024-07-30 18:27:48 -07:00
Nuno CamposandGitHub dd52472312 Merge pull request #1172 from langchain-ai/nc/30jul/update-no-values
Allow call to update_state without values
2024-07-30 18:27:00 -07:00
Nuno Campos 6475d81f29 Oops 2024-07-30 18:26:39 -07:00
Nuno Campos 51b4475fcc Allow call to update_state without values
- this means "fork without update" (eg to rerun a node)
2024-07-30 18:21:15 -07:00
Nuno Campos 3238fa0870 Add test for drawing lance example 2024-07-30 15:50:18 -07:00
Nuno CamposandGitHub fdaa5a3037 Merge pull request #1159 from akshseh/fix_visualization_example
fix: update the function for node colors
2024-07-30 10:04:05 -07:00
Akarsha SehwagandGitHub 12238c7b7e Merge branch 'main' into fix_visualization_example 2024-07-30 14:13:35 +02:00
Nuno Campos 3006084326 lib0.1.16 2024-07-29 12:46:33 -07:00
Nuno CamposandGitHub f448df4638 Merge pull request #1160 from langchain-ai/nc/29jul/fix-cond-after-multi-send
Fix issue when cond edge visited after multiple executions of Send
2024-07-29 12:46:00 -07:00
Nuno Campos 466cb8acb5 Fix issue when cond edge visited after multiple executions of Send
- cond edge will run for each execution of Send, so target channels need to support multiple publishes
2024-07-29 12:38:48 -07:00
Akarsha SehwagandGitHub 1a0ad5fdd0 fix: update the function for node colors
NodeColors does not exist anymore in Langchain_core -> updated to NodeStyles and changed the param names.
2024-07-29 17:23:48 +02:00
ea071935fe adding message info (#1150)
---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-07-26 20:24:19 +00:00
Nuno Campos 794a0fff03 lib0.1.15 2024-07-26 10:58:56 -07:00
Nuno CamposandGitHub 06ed6d7cab Merge pull request #1152 from langchain-ai/nc/26jul/pydantic-2-compat
lib: Improve compat with pydantic 2 models
2024-07-26 10:58:24 -07:00
Nuno Campos 6eacc6b7c8 lib: Improve compat with pydantic 2 models 2024-07-26 10:51:59 -07:00
Nuno CamposandGitHub f6ac881591 Merge pull request #1151 from langchain-ai/wfh/shrink
Shrink images
2024-07-26 10:50:56 -07:00
William Fu-Hinthorn f431b415fc Shrink images 2024-07-26 10:06:20 -07:00
Chester Curme 8d4b95afa8 add section 2024-07-26 11:22:01 -04:00
Lance MartinandGitHub 4b51c27461 Add llama3.1 tool calling (#1148) 2024-07-26 08:08:22 -07:00
Vadym BardaandGitHub 585c5c41ce docs: sync readmes (#1147) 2024-07-26 14:14:42 +00:00
BagaturandGitHub c64588a673 docs: rm discord from readme (#1145) 2024-07-26 08:19:54 -04:00
Vadym BardaandGitHub 75fa7395bd docs: add better state/reducers description in intro tutorial (#1140) 2024-07-25 22:01:18 +00:00
Isaac FranciscoandGitHub 66ad48e771 typo (#1139) 2024-07-25 21:36:28 +00:00
Isaac FranciscoandGitHub 41fd8020ee sdk-py: add docstrings (#1130) 2024-07-25 16:51:25 -04:00
Nuno CamposandGitHub 09a28ccef6 Merge pull request #1136 from langchain-ai/isaac/reducegifsizes
reduce video sizes
2024-07-25 11:57:21 -07:00
isaac hershenson c0431227d8 reduce videos 2024-07-25 11:53:29 -07:00
Nuno CamposandGitHub b5f861722d Merge branch 'main' into cc/many_tools_guide 2024-07-25 11:15:05 -07:00
Nuno CamposandGitHub 770e1601e5 Merge pull request #1135 from langchain-ai/nc/25jul/ci-large-size
Add CI check for large files added
2024-07-25 10:26:11 -07:00
Nuno Campos 045c2af663 Remove test image 2024-07-25 10:20:03 -07:00
Nuno Campos 23d3a7ac07 Improve output 2024-07-25 10:18:55 -07:00
Nuno Campos 67d00aca90 Fix 2024-07-25 10:16:56 -07:00
Nuno Campos e54989ca74 Add quotes 2024-07-25 10:05:25 -07:00
Nuno Campos 14372a4515 Try again 2024-07-25 10:04:05 -07:00
Nuno Campos 6e33bda433 Different flag? 2024-07-25 10:00:21 -07:00
Nuno Campos 77eb88eef2 Try again 2024-07-25 09:59:23 -07:00
Nuno Campos 7584f058c2 Add prints 2024-07-25 09:47:06 -07:00
Nuno Campos fba6e0504c Fix 2024-07-25 09:45:27 -07:00
Nuno Campos c17fe2d189 Support paths with spaces 2024-07-25 09:44:31 -07:00
Nuno Campos 4a58dcccf2 Add test large image 2024-07-25 09:36:02 -07:00
Nuno Campos ed2e1a736f Add CI check for large files added 2024-07-25 09:34:33 -07:00
Nuno CamposandGitHub a168615f2d Merge pull request #1126 from langchain-ai/vb/add-graph-factory-example 2024-07-24 18:35:36 -07:00
vbarda 190372e137 update 2024-07-24 21:22:19 -04:00
Isaac FranciscoandGitHub eba8303c98 display state management (#1127) 2024-07-24 16:57:17 -07:00
William FHandGitHub 2845d7ace5 Shrink Images (#1125) 2024-07-24 16:50:08 -07:00
vbarda 2ceac211e7 docs: add how to for graph factory + update cli 2024-07-24 18:14:34 -04:00
Vadym BardaandGitHub 8f6b3b636d docs: fix link in subgraphs how-to (#1124) 2024-07-24 16:59:46 -04:00
Vadym BardaandGitHub 56bf9c9047 Merge branch 'main' into vb/update-get-state 2024-07-24 14:03:10 -04:00
Nuno Campos ebe01c2639 lib0.1.14 2024-07-24 10:53:23 -07:00
Nuno CamposandGitHub 272219e410 Merge pull request #1121 from langchain-ai/nc/24jul/disable-nested-checkpoints-unless-interrupt 2024-07-24 10:52:29 -07:00
vbarda a7d48465da use .list for looking up prefix-matched checkpoints 2024-07-24 13:45:48 -04:00
Nuno Campos bb1324cdc3 Disable nested checkpoints unless interrupts set on subgraph 2024-07-24 10:45:39 -07:00
Nuno Campos 85af0603fa lib0.1.13 2024-07-24 09:49:23 -07:00
Chester Curme 590f810b53 add concluding text 2024-07-24 12:45:37 -04:00
Nuno CamposandGitHub e6e5911aae Merge pull request #1119 from langchain-ai/nc/24jul/avoid-crash-missing-node
Avoid crash when a node in pending sends is removed
2024-07-24 09:41:20 -07:00
Nuno CamposandGitHub 9fdbd0dd49 Merge pull request #1118 from langchain-ai/nc/24jul/fix-recursion-limit-thread
Fix recursion limit considering steps taken in previous runs on same thread
2024-07-24 09:35:12 -07:00
Nuno Campos 8a20c6f7e4 Avoid crash when a node in pending sends is removed 2024-07-24 09:29:38 -07:00
Nuno Campos 03f9b27e3b Fix 2024-07-24 09:26:49 -07:00
Nuno CamposandGitHub 19f6f7d5ca Merge pull request #1110 from langchain-ai/wfh/test_pending_writes_null
Test Null Pending Writes
2024-07-24 08:51:33 -07:00
Nuno Campos 745b96eb63 Fix recursion limit considering steps taken in previous runs on same thread 2024-07-24 08:50:32 -07:00
Chester Curme 7ea5da73c7 add guide 2024-07-24 11:49:05 -04:00
vbarda 6ae2c6c7b9 Merge branch 'main' into vb/update-get-state 2024-07-24 11:18:10 -04:00
b90d44d97d Add local tool calling agent example (#1109)
* Add local tool calling agent example

* Update copy_notebooks.py

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-07-24 07:39:53 -07:00
Vadym BardaandGitHub d99d3e05c7 langgraph: release 0.1.12 (#1116) 2024-07-24 10:38:07 -04:00
Vadym BardaandGitHub ca6aef4746 langgraph: bring back tool content stringify (#1114) 2024-07-24 10:36:32 -04:00
William Fu-Hinthorn f5b9e463e3 Merge branch 'main' into wfh/test_pending_writes_null 2024-07-23 21:28:51 -07:00
William FHandGitHub 82cbe25be8 Update typedoc build (#1087) 2024-07-23 21:27:40 -07:00
William Fu-Hinthorn 36505d9656 Add test 2024-07-23 21:15:53 -07:00
vbarda ae696d4f30 add sync history 2024-07-23 21:40:04 -04:00
vbarda b43ef6440f tests 2024-07-23 20:59:10 -04:00
vbarda e615aabf14 cleanup names + make subgraph state optional 2024-07-23 20:28:23 -04:00
Lance MartinandGitHub b72ea0ea1b Update MR docs (#1098) 2024-07-23 17:13:20 -07:00
vbarda 92ae8f4817 async methods 2024-07-23 19:51:44 -04:00
vbarda 2268802908 Merge branch 'main' into vb/update-get-state 2024-07-23 18:51:36 -04:00
vbarda 261cdf88a5 langgraph: update get_state to handle nested subgraph state 2024-07-23 18:35:49 -04:00
Vadym BardaandGitHub 603a137d33 langgraph: release 0.1.11 (#1107) 2024-07-23 18:06:07 -04:00
Nuno CamposandGitHub 4cdb38d337 Fix null pending writes (#1106) 2024-07-23 17:59:16 -04:00
Nuno Campos 03bf1e5414 Fix null pending writes 2024-07-23 14:55:07 -07:00
Nuno CamposandGitHub 4fa5c8bab0 Merge pull request #1089 from mihaic/patch-1
Fix StateGraph.add_edge end_key check
2024-07-23 13:52:33 -07:00
Nuno CamposandGitHub 9711f39995 Merge pull request #1090 from langchain-ai/harrison/private-state
Harrison/private state
2024-07-23 13:50:02 -07:00
Nuno CamposandGitHub 091bc003ae Merge pull request #1088 from langchain-ai/vb/update-return-type
langgraph: add proper type annotation for StateGraph.compile
2024-07-23 13:49:12 -07:00
Nuno CamposandGitHub 57c40026f8 Update pass_private_state.ipynb 2024-07-23 13:46:56 -07:00
Nuno CamposandGitHub bf61f6f869 Merge pull request #1102 from langchain-ai/an/23jul/docs-langgraph-cloud-constraints
docs: Add constraints info to LangGraph Cloud setup docs
2024-07-23 13:45:30 -07:00
Nuno Campos 6c299a1b5a Fix docs build 2024-07-23 13:42:57 -07:00
Nuno CamposandGitHub aeae796e60 Update setup_pyproject.md 2024-07-23 13:29:56 -07:00
Nuno CamposandGitHub 7ec37575de Update setup.md 2024-07-23 13:29:43 -07:00
Nuno CamposandGitHub 4fdd05532d Merge pull request #1100 from langchain-ai/harrison/migrations
migrations of graph
2024-07-23 13:26:18 -07:00
Nuno CamposandGitHub 43c793f7fe Update low_level.md 2024-07-23 13:24:46 -07:00
Lance MartinandGitHub 1765000263 Local RAG agent testing with Llama3.1 (#1104) 2024-07-23 13:05:51 -07:00
Vadym BardaandGitHub 3fdd4715f5 langgraph: release 0.1.10 (#1103) 2024-07-23 14:13:35 -04:00
Isaac FranciscoandGitHub 97cb44058a [docs]:open studio from local deployment (#1037)
* open studio from local deployment

* spelling

* harrison comments
2024-07-23 12:50:57 -04:00
Andrew Nguonly 73e0871345 Add constraints info to LangGraph Cloud setup docs. 2024-07-23 08:56:56 -07:00
Harrison Chase c8f046869b migrations of graph 2024-07-23 08:20:03 -07:00
Nuno CamposandGitHub bd4dccd9cb Merge pull request #1075 from langchain-ai/nc/19jul/nested-checkpoints 2024-07-22 18:41:56 -07:00
vbarda c268d695f0 spellcheck 2024-07-22 21:28:11 -04:00
vbarda 0891cc1864 comments / bring back sleep 2024-07-22 21:18:42 -04:00
Nuno Campos ee7cab664a Fix checkpoint put ordering issue 2024-07-22 17:52:09 -07:00
vbarda fd8f9e87dc update types 2024-07-22 20:48:21 -04:00
vbarda ed9c015d24 remove utils 2024-07-22 20:43:28 -04:00
vbarda cd4fae601c remove sleep 2024-07-22 20:26:12 -04:00
Nuno Campos aed313ebb5 Fix stack not being unwound when suppressing interrupt 2024-07-22 17:09:47 -07:00
Nuno Campos 2008df03fa Merge branch 'main' into nc/19jul/nested-checkpoints 2024-07-22 16:33:33 -07:00
Nuno Campos 3f860617a5 Update tests 2024-07-22 16:32:18 -07:00
Nuno Campos 98a962661b Instead of saving an additional interrupt checkpoint, make child graphs keep a single checkpoint for each parent checkpoint
- while the inner graph makes progress it overwrites the partial progress checkpoints, eventually keeping only one for each outer step
- implement parent_config in MemorySaver
- fix edge cases in PregelLoop
2024-07-22 16:32:15 -07:00
Harrison Chase 9483da1bdb cr 2024-07-22 16:31:14 -07:00
Harrison Chase 8d3da565c4 cr 2024-07-22 16:30:34 -07:00
Nuno Campos 42174ad9fb Add optional id arg to create_checkpoint 2024-07-22 16:30:19 -07:00
Nuno Campos 0c1ec8d5d2 Update sync bg executor to wait on all tasks on exit 2024-07-22 16:30:08 -07:00
Harrison Chase fdbb33ddad add private state 2024-07-22 16:26:31 -07:00
Mihai CapotăandGitHub 3f43e0d945 Fix StateGraph.add_edge end_key check
It looks like a typo to me: `END` should be `START`.

`END` should be accepted as `end_key` and it is accepted with the `super` call path.
2024-07-22 15:55:19 -07:00
vbarda d00503ecc4 langgraph: add proper type annotation for StateGraph.compile 2024-07-22 18:03:16 -04:00
trevor-cyiandGitHub ab80c113ac docs: Use bound model in convo history (#1082)
This fixes a small mistake in the manage-conversation-history notebook
where the model bound with tools was not used, instead, the original model
was used when invocations occur.
2024-07-22 16:27:42 -04:00
vbarda fbced023f3 add more tests 2024-07-22 16:23:54 -04:00
William FHandGitHub 91d6b964c4 Update js sdk links (#1086) 2024-07-22 13:08:48 -07:00
vbarda 6e57fa5f9a return future on self._put_checkpoint 2024-07-22 14:32:57 -04:00
vbarda 77f6ec5a2b update memory 2024-07-22 13:03:30 -04:00
vbarda f2a95ad67f fix broken interrupt tests 2024-07-22 12:18:12 -04:00
vbarda d635a22302 sort memory checkpoints monotonically decreasing 2024-07-22 12:14:33 -04:00
Nuno CamposandGitHub b1ffa52da6 Merge pull request #1064 from KYUUUW/patch-1
[docs]Fix runtime error README.md example
2024-07-22 08:42:34 -07:00
Nuno CamposandGitHub e2b959ee7e Merge pull request #1073 from langchain-ai/nc/19jul/binop-lambda-eq
Don't include lambdas in __eq__ for BinOp
2024-07-22 08:41:30 -07:00
Nuno Campos 84e404eb71 Lint 2024-07-22 08:24:53 -07:00
Nuno Campos a1a5fc01a9 cli0.1.50 2024-07-22 08:22:05 -07:00
Nuno CamposandGitHub 2616614470 Merge pull request #1080 from langchain-ai/nc/21jul/cli-stdout-overrun
cli: Fix crash when subprocess has a very long stdout/stderr line
2024-07-22 08:21:25 -07:00
Nuno CamposandGitHub 64fd304ea0 Merge pull request #1083 from langchain-ai/vb/update-sdk 2024-07-22 08:05:50 -07:00
vbarda f820ca8f7f sdk-py: add threads copy 2024-07-21 20:21:27 -04:00
Vadym BardaandGitHub 4bacbdd2bd docs: update create_react_agent to use state_modifier (#1081) 2024-07-21 17:07:50 -04:00
Nuno CamposandGitHub 34407d9de1 Update exec.py 2024-07-21 12:19:19 -07:00
Nuno Campos b81612c292 cli: Fix crash when subprocess has a very long stdout/stderr line 2024-07-21 12:16:37 -07:00
LEE KYU WONandGitHub b3e44bed22 Fix example error 2024-07-21 18:14:01 +09:00
LEE KYU WONandGitHub e8b05faff4 Merge branch 'main' into patch-1 2024-07-21 18:12:38 +09:00
BagaturandGitHub 610b6cc78c langgraph[patch]: InjectedState annotation (#1067)
Add annotated for injecting state vars into a Tool
2024-07-19 20:07:21 -07:00
William FHandGitHub 75f8a33c9e [Docs] Format notebooks (#1076) 2024-07-19 18:29:24 -07:00
Nuno CamposandGitHub afe3905958 Update loop.py 2024-07-19 18:15:54 -07:00
Nuno CamposandGitHub 375d9a45d9 Update loop.py 2024-07-19 18:15:47 -07:00
Nuno Campos f5390a4ee5 Port to new architecture 2024-07-19 18:04:55 -07:00
William FHandGitHub 29d7a812ae [Docs] Update checkpointer docstrings (#1074) 2024-07-19 17:52:47 -07:00
Nuno CamposandGitHub fb9d5b9304 Merge pull request #1059 from langchain-ai/nc/18jul/loop
Make Pregel loop runnable step-by-step
2024-07-19 17:16:48 -07:00
Nuno Campos b77ef7d162 Lint 2024-07-19 17:13:51 -07:00
Nuno Campos b0e0d269c5 Lint 2024-07-19 16:40:50 -07:00
Nuno Campos 1dbf7a3392 Move all checkpoint edits to apply_writes 2024-07-19 16:37:27 -07:00
Nuno Campos 27cd4e2221 Update core 2024-07-19 15:44:21 -07:00
Nuno Campos dc703857dd Run tests in parallel 2024-07-19 15:43:40 -07:00
Nuno CamposandGitHub 5df5eb6b09 Merge pull request #1072 from langchain-ai/isaac/retrynodeshowto
[docs]: add node retry docs
2024-07-19 15:00:03 -07:00
isaac hershenson eaa23ef4e5 added retrypolicy reference 2024-07-19 14:56:14 -07:00
Nuno Campos 4dc1195bcd Don't include lambdas in __eq__ for BinOp
When using forward refs, inline lambdas in Annotated are re-evaluated for every subclass, thus making the comparison fail
2024-07-19 14:46:01 -07:00
isaac hershenson 55c78bbf90 remove unneccesary imports 2024-07-19 13:13:02 -07:00
isaac hershenson 2a7ae83bf8 spelling 2024-07-19 13:07:26 -07:00
isaac hershenson d7dc16310f nuno comments 2024-07-19 13:05:28 -07:00
isaac hershenson afd940d9bd first draft 2024-07-19 12:38:55 -07:00
Nuno Campos ed5d114087 Fix 2024-07-19 12:19:43 -07:00
Nuno CamposandGitHub 9d14f4f2f1 docs: Add note on langgraph v langgraph cloud (#1071) 2024-07-19 10:40:02 -07:00
Nuno CamposandGitHub 29e860acca Update manager.py 2024-07-19 08:52:08 -07:00
Nuno CamposandGitHub b26be0c113 Merge pull request #1070 from langchain-ai/vb/update-assistants
sdk-py: add if_exists for assistants
2024-07-19 08:39:11 -07:00
Nuno CamposandGitHub ec2892098b Update client.py 2024-07-19 08:21:58 -07:00
vbarda c7133fd34b Merge branch 'main' into vb/update-assistants 2024-07-19 10:12:26 -04:00
Nuno Campos 7ed5f9e4bc Implement AsyncLoop 2024-07-18 17:28:44 -07:00
vbarda 8bd2d88be4 sdk-py: add if_exists for assistants 2024-07-18 19:59:12 -04:00
BagaturandGitHub 3a53843185 langgraph[patch]: refactor ToolNode (#1066) 2024-07-18 16:13:06 -07:00
Nuno Campos f974471f7d Lint 2024-07-18 15:52:20 -07:00
Nuno Campos 909bf4433f Lint 2024-07-18 15:51:37 -07:00
Nuno Campos 73b4b6ec5b Lint 2024-07-18 15:50:45 -07:00
Nuno Campos 06f83710c8 Lint 2024-07-18 15:49:58 -07:00
Nuno Campos b3ee728839 Pregel.stream passing all tests 2024-07-18 15:49:58 -07:00
Nuno Campos 60f7a7d593 Lint 2024-07-18 15:49:58 -07:00
Nuno Campos 56238036d7 WIP: Split out loop logic from Pregel class 2024-07-18 15:49:58 -07:00
LEE KYU WONandGitHub 3f35a0a44e Update wait-user-input.ipynb (#1065) 2024-07-18 18:48:22 -04:00
LEE KYU WONandGitHub 58af2c7d9f Fix error in example 2024-07-19 04:29:39 +09:00
Vadym BardaandGitHub 95a4a55849 docs: add how to for passing config to tools (#1063) 2024-07-18 13:33:56 -04:00
Nuno Campos 97281d708b lib 0.1.9 2024-07-18 10:28:24 -07:00
Nuno CamposandGitHub c39f4ce47a Merge pull request #1062 from langchain-ai/nc/18jul/node-retry-policy
Enable configuring retry policy for each node of StateGraph
2024-07-18 10:24:31 -07:00
Nuno Campos 833b1faba2 Enable configuring retry policy for each node of StateGraph 2024-07-18 10:18:29 -07:00
Nuno Campos 2ca816ca25 cli 0.1.49 2024-07-18 10:01:43 -07:00
Nuno CamposandGitHub 50861cdf1b Merge pull request #1036 from langchain-ai/nc/16jul/node-state
Add node state, customizable graph input and output schemas
2024-07-18 09:56:20 -07:00
Nuno Campos b5b0f8d7e3 Remove node output schemas 2024-07-18 09:46:06 -07:00
Nuno CamposandGitHub 87e80fe45a Merge pull request #1058 from langchain-ai/nc/18jul/cli-dockerfile
cli: Add dockerfile command to write dockerfile
2024-07-18 09:28:44 -07:00
Nuno Campos ffe9a6d5b8 cli: Add dockerfile command to write dockerfile 2024-07-18 09:04:14 -07:00
BagaturandGitHub 97ae473002 docs: pass in graph state to tool (#1056) 2024-07-18 07:34:19 -07:00
William FHandGitHub 246b7dafcf Add Docstrings (#1057) 2024-07-18 07:12:12 -07:00
William FHandGitHub 254926c4a8 Update template links (#1045) 2024-07-18 07:10:10 -07:00
Vadym BardaandGitHub 5fbc9555c3 docs: add how-to section on tool calling (#1051) 2024-07-18 09:36:15 -04:00
Vadym BardaandGitHub 83089c3a7f langgraph: add incorrect tool name handling to ToolNode (#1052) 2024-07-17 21:33:46 -04:00
Nuno CamposandGitHub c2e25e2ac2 Merge pull request #1049 from langchain-ai/nc/17jul/pregel-node-retry-policy
pregel: Support retry policy per node
2024-07-17 14:54:23 -07:00
Andrew NguonlyandGitHub e3ef9adac7 Add instructions to test locally before deploying to Cloud. (#1050) 2024-07-17 14:04:15 -07:00
Nuno Campos e4bfcffed4 pregel: Support retry policy per node
- to expose from StateGraph in future PR
2024-07-17 13:17:15 -07:00
Nuno CamposandGitHub a184c7f23a lib: Separate out executor logic from stream methods (#1048)
* lib: Separate out executor logic from stream methods

- first step towards splitting out tick and stream

* Lint

* Lint

* Lint

* Lint
2024-07-17 13:16:35 -07:00
clement.landGitHub a96f5f8f27 docs: fix typo in low_level.md (#1044) 2024-07-17 09:57:26 -04:00
Vadym BardaandGitHub 79dc1a64b3 langgraph: allow passing custom state & let message modifiers access state in create_react_agent (#1023) 2024-07-16 20:41:17 -04:00
Nuno Campos 7bc489f1f4 Add node state, customizable graph input and output schemas 2024-07-16 13:50:20 -07:00
924cd1f2d8 [docs]: minor changes for testing locally (#1029)
* small changes

* harrison comments

* Update docs/docs/cloud/deployment/test_locally.md

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-07-16 10:43:03 -07:00
William FHandGitHub 6fd1dc5697 Add note to docstring (#1035) 2024-07-16 08:43:49 -07:00
Arthur BermanandGitHub 09c5ebc94d Update low_level.md (#1016)
replace add_edge by add_conditional_edges
fix a mistake
2024-07-16 08:43:40 -07:00
Vadym BardaandGitHub ebeebcd095 sdk-js: release 0.0.2 (#1033) 2024-07-16 09:20:25 -04:00
Vadym BardaandGitHub 3713ba66a8 sdk-js: add thread_id and if_exists to ThreadsClient.create (#1032) 2024-07-16 09:18:22 -04:00
Jacob LeeandGitHub 449b42717c Add guide on handling tool calling errors (#1012)
* Fix example

CC @vbarda

* Progress on tool calling errors

* Update

* Rename

* Format

* Clean up outputs

* Revert

* Use stream instead of invoke for final example
2024-07-15 23:22:50 -07:00
BagaturandGitHub 2a1cdd31c5 langgraph[patch]: ToolNode support for tools outputting msg (#977)
ToolNode passes ToolCall to tools directly and outputs the generated ToolMessages directly
2024-07-15 16:40:37 -07:00
Nuno CamposandGitHub 5444563fdc Only render end node if there is an edge leading to it (#1022) 2024-07-15 11:26:05 -07:00
Vadym BardaandGitHub fad4de789f sdk-py: release 0.1.26 (#1026) 2024-07-15 13:44:41 -04:00
Vadym BardaandGitHub bf10f39b6b docs: update delete messages how-to for clarity (#1025) 2024-07-15 13:36:19 -04:00
Vadym BardaandGitHub ebf6316fa7 docs: fix collapsible code block affecting TOC in tutorial (#1024) 2024-07-15 13:16:28 -04:00
Vadym BardaandGitHub 647c5737f0 sdk-py: add if_exists to threads.create (#1009) 2024-07-15 12:15:43 -04:00
Vedanta SPandGitHub 9e7695085e Update langgraph_self_rag_local.ipynb (#1014)
replaced pprint with print
2024-07-14 16:32:07 -04:00
Nuno CamposandGitHub 8cf10fa460 Specific error when updating state as an unknown node (#1015) 2024-07-14 06:54:01 -07:00
Vadym BardaandGitHub 3ef65c37b3 docs: add note for langgraph cloud checkpointers (#1011) 2024-07-12 16:48:03 -04:00
Vadym BardaandGitHub 4b5152fde5 docs: small fix in postgres docs (#1010) 2024-07-12 16:27:58 -04:00
Jacob LeeandGitHub 07c3c5ff6f Hide output spacer column in docs (#1008) 2024-07-12 13:00:01 -07:00
Lance MartinandGitHub ada17d2ccb Improve visuals (#1005) 2024-07-12 12:55:32 -07:00
738f725aea Support multiple interruptions after resuming execution (#1004)
* Support multiple interruptions

* Add async test, Use a different fix

* Update comment

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-07-12 12:53:17 -07:00
Jacob LeeandGitHub 558a513a1a Remove Jupyter cell 'In[<number>]' display column from docs (#1007) 2024-07-12 12:47:07 -07:00
Vadym BardaandGitHub 5a55974f15 docs: update postgres checkpointer (#1001) 2024-07-12 13:40:55 -04:00
Vadym BardaandGitHub f84f9374d3 docs: bring back how-to on passing runtime values to tools (#1003) 2024-07-12 11:52:34 -04:00
Vadym BardaandGitHub f8c87afee1 docs: update streaming from within the tool to use dispatch_custom_event (#1000) 2024-07-11 21:31:55 -04:00
dedbdefd93 [Docs] Added Asynchronous implementation of MongoDB persistence (#983)
---------

Co-authored-by: Vadym Barda <vadim.barda@gmail.com>
Co-authored-by: Vadym Barda <vadym@langchain.dev>
2024-07-11 21:20:19 -04:00
Nuno Campos f13cf5dc2c Update snapshot tests after core release 2024-07-11 17:06:12 -07:00
Nuno Campos 1e2682616f lib0.1.8 2024-07-11 17:03:56 -07:00
Nuno CamposandGitHub 71d9d02d26 lib: Add metadata arg to add_node() (#990)
* lib: Add metadata arg to add_node()

- use metadata when drawing graph
- use metadata for tracing

* Update core

* Lock
2024-07-11 17:03:22 -07:00
Lance MartinandGitHub bd100fdfef Update controllability docs (#995)
* Update controllability docs

* Update controllability docs

* Update docs
2024-07-11 16:10:12 -07:00
Jacob LeeandGitHub 3f4a8e557e Remove broken edit button, view source button (#998)
* Fix edit button, remove view source button

* Update mkdocs.yml

* Update mkdocs.yml
2024-07-11 15:17:23 -07:00
Andrew NguonlyandGitHub e9f7cd3e52 docs: Add Cloud Concepts docs, update cloud deployment how-to guide (#996)
* Update Cloud deployment docs. Add Cloud Concepts docs.

* Update quick start. Update how-to for setting up repo.

* Delete unused image base_url.png.

* Fix spelling error. Fix broken anchor link.

* Fix broken links.
2024-07-11 14:33:25 -07:00
Vadym BardaandGitHub 39321ba042 docs: reduce number of cells in streaming how-tos (#997) 2024-07-11 17:19:58 -04:00
Vadym BardaandGitHub 85ec1934de langgraph: update stream_mode docstring for .stream() (#994)
* langgraph: update stream_mode docstring for .stream()

* add astream docstring

* fix import
2024-07-11 09:08:19 -07:00
Vadym BardaandGitHub 45dbf8c656 sdk-py: remove defaults from typedef (#989) 2024-07-10 18:08:05 -04:00
Nuno Campos 60763d4ddf lib 0.1.7 2024-07-10 14:44:07 -07:00
Vadym BardaandGitHub 8c4da2c41c sdk-py: add create_batch method (#988) 2024-07-10 17:37:56 -04:00
Nuno CamposandGitHub dfb2ac321f lib: Checkpoint pending writes whenever a node finishes (#976)
* lib: Checkpoint pending writes whenever a node finishes

- Whenever a node finishes, checkpoint pending writes

* Rename arg

* Add tests, resume from pending writes

* Add comment

* Add descriptive error

* Fix bug found by will

* Fix comments

* Lint

* Don't save pending write if executing only one node in step
2024-07-10 14:28:06 -07:00
Lance MartinandGitHub 4d2456be40 Update HIL update / edit state documentation (#966)
* Update user input example

* Update editing graph state

* Minor clarifications
2024-07-10 13:24:16 -07:00
Vadym BardaandGitHub 166aaa1bac docs: update another langsmith key ref (#986) 2024-07-10 12:33:34 -04:00
Vadym BardaandGitHub 7cad1658f6 docs: update key in local cloud quickstart (#985) 2024-07-10 12:18:10 -04:00
Vadym BardaandGitHub a3a9c6ceed docs: add how-to on how to stream tokens from within a tool (#984) 2024-07-10 12:16:18 -04:00
William FHandGitHub 4849501ccf Copy core context in RunnableCallable (#973) 2024-07-09 20:26:45 -07:00
Vadym BardaandGitHub a6dddd322a docs: add how-to for streaming tokens w/o langchain chat models (#972) 2024-07-09 21:56:18 -04:00
Isaac FranciscoandGitHub 17785375b8 [docs]: adding LangGraph up documentation (#975)
* first draft

* harrison comments
2024-07-09 18:22:11 -07:00
William FHandGitHub b632fd8c54 Add cleaned up csbot chatbot example (#971) 2024-07-09 14:06:05 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
f32daee7d5 chore(deps): bump certifi from 2024.6.2 to 2024.7.4 in /libs/langgraph (#969)
Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.6.2 to 2024.7.4.
- [Commits](https://github.com/certifi/python-certifi/compare/2024.06.02...2024.07.04)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 13:52:41 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
df52115de0 chore(deps-dev): bump certifi in /libs/cli/examples (#967)
Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.6.2 to 2024.7.4.
- [Commits](https://github.com/certifi/python-certifi/compare/2024.06.02...2024.07.04)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 12:54:47 -07:00
2eb7d14acd docs: add Redis Checkpointer example (#961)
---------

Co-authored-by: Vadym Barda <vadim.barda@gmail.com>
Co-authored-by: Vadym Barda <vadym@langchain.dev>
2024-07-09 14:32:01 -04:00
Lance MartinandGitHub 2842dae598 Minor edit to low-level docs to clarify Super Steps (#951) 2024-07-09 10:02:08 -07:00
Nuno Campos 2354066c6d Format 2024-07-09 09:40:29 -07:00
Nuno Campos 4b564f69a8 Fix tests 2024-07-09 09:35:50 -07:00
Vadym BardaandGitHub c283d7e2ba langgraph: release 0.1.6 (#965) 2024-07-09 12:34:11 -04:00
3675c5b89d [Docs] Added MongoDB persistence in how-tos (#960)
---------

Co-authored-by: Vadym Barda <vadim.barda@gmail.com>
Co-authored-by: Vadym Barda <vadym@langchain.dev>
2024-07-09 12:27:56 -04:00
a8644baf50 docs: add memory how-tos + update add_messages (#958)
---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-07-09 12:26:31 -04:00
Nuno CamposandGitHub cf75003cbe cli: Update pip install command 2024-07-09 12:31:08 +01:00
Andrew NguonlyandGitHub fab950acfb Update version of CLI to 0.1.48. (#957) 2024-07-08 18:20:23 -07:00
Andrew NguonlyandGitHub 7ed26e1396 Update LangGraph API documentation. (#956) 2024-07-08 17:52:21 -07:00
David DuongandGitHub 293bc2c11f feat(cli): add debugger host CLI flag to specify default base URL (#900) 2024-07-08 20:47:50 -04:00
Andrew NguonlyandGitHub bb6785bbef cli: set verbose flag for pull in langgraph build (#955)
* Set verbose flag for langgraph build.

* Update CLI README.
2024-07-08 17:46:21 -07:00
Henry KobinandGitHub 878567f6b0 spellcheck (#936) 2024-07-08 17:10:21 -04:00
William FHandGitHub 165e82eb33 [Docs] Replace Absolute External Links (#949) 2024-07-08 13:02:53 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
64a17599c1 chore(deps-dev): bump certifi from 2024.6.2 to 2024.7.4 (#950)
Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.6.2 to 2024.7.4.
- [Commits](https://github.com/certifi/python-certifi/compare/2024.06.02...2024.07.04)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 13:02:14 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
23f422e9d9 chore(deps): bump certifi from 2024.2.2 to 2024.7.4 in /libs/sdk-py (#934)
Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.2.2 to 2024.7.4.
- [Commits](https://github.com/certifi/python-certifi/compare/2024.02.02...2024.07.04)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-08 11:51:16 -07:00
Vadym BardaandGitHub d16b8b4e59 docs: fix more links (#948) 2024-07-08 12:32:05 -04:00
Vadym BardaandGitHub 9b4bb69001 docs: fix links in the cloud how-tos (#947) 2024-07-08 12:13:05 -04:00
Lance MartinandGitHub 5232ea2606 Improve and clean Breakpoints documentation (#923) 2024-07-03 19:38:42 -07:00
William FHandGitHub 56086512ca [Docs] Add State Context Key How-to (#920) 2024-07-03 12:28:40 -07:00
Vadym BardaandGitHub cd3a1cbf8f langgraph: add tool error handling (#910) 2024-07-03 15:12:50 -04:00
Vadym BardaandGitHub 6e8e532995 docs: update readme (#921) 2024-07-03 14:18:32 -04:00
Vadym BardaandGitHub 2093347f8a sdk-js: release 0.0.1 (#918) 2024-07-03 14:07:39 -04:00
William FHandGitHub f380e2301d [Docs] Update README example
Plus add CI check
2024-07-03 10:35:29 -07:00
Vadym BardaandGitHub 8b45146f13 docs: add langgraph logo (#916) 2024-07-03 13:15:15 -04:00
Andrew NguonlyandGitHub 5c42d26475 docs: Add CTA for LangGraph Cloud to README (#914)
* Update README.md

* Update README.
2024-07-03 08:20:17 -07:00
Vadym BardaandGitHub 6e7265a659 langgraph: add support for deleting messages (#651)
* (RFC) add support for deleting messages

* alternative design

* lint

* Revert "lint"

This reverts commit 88b59d2aef.

* Revert "alternative design"

This reverts commit 2ad6009160.

* switch to lc core removemessage

* lint

* add unittests
2024-07-03 06:43:53 +01:00
Vadym BardaandGitHub 5e8aa5d9f2 langgraph: update langchain-core & snapshot tests (#909) 2024-07-02 20:37:03 -04:00
Isaac FranciscoandGitHub d180c80c34 [docs] add JS examples for double texting and human in the loop for cloud (#885) 2024-07-02 11:42:46 -04:00
William FHandGitHub ab8f3174e1 [Docs] Img in map reduce (#904) 2024-07-02 06:34:09 -07:00
William FHandGitHub 320a87e1b9 [Docs] use END instead of set_finish_point (#903) 2024-07-01 21:56:10 -07:00
William FHandGitHub 727e63c01e [Docs] Update notebooks to use START (#902) 2024-07-01 21:36:34 -07:00
267f5e5234 docs: add js examples for streaming (#871)
---------

Co-authored-by: vbarda <vadym@langchain.dev>
2024-07-01 21:22:47 -04:00
William FHandGitHub 99e592b474 [Docs] More links to langgraph.json (#901) 2024-07-01 14:07:30 -07:00
2cbfc1cbeb docs: fixed variable error (#896)
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-07-01 14:53:39 -04:00
00514955fa fix: change 'action' to 'tools' in graph visualization (#895)
Co-authored-by: afsu <saf@zjuici.com>
2024-07-01 10:20:48 -07:00
William FHandGitHub d7a04663da [Docs] Improve create_react_agent docstring (#899)
- Cleanup parameter formatting
- Add diagrams
- Walk through example execution
2024-07-01 10:20:20 -07:00
Nuno Campos 94300877ee 0.1.5 2024-07-01 18:15:44 +01:00
Nuno Campos dfdb4d00ea Mark cancelled as seen 2024-07-01 18:12:37 +01:00
yoogleandGitHub 3506be18a4 fix: typo (#898) 2024-07-01 11:36:53 -04:00
Vadym BardaandGitHub 7a68cc63c4 ci: update permissions (#886) 2024-06-29 08:47:58 -04:00
Isaac FranciscoandGitHub 281e66ed2e sdk-js: added cron functionality to match langgraph-api (#863)
* testing

* first draft

* working

* first draft

* fmt

* vadym comments
2024-06-28 16:26:22 -07:00
Isaac FranciscoandGitHub 1fe13cb009 sdk-py: added Cron search functionality (#804)
* first draft

* minor fix

* second draft

* reformat

* rename

* remove f-string

* fmt

* fmt

* fmt

* fmt

* fmt

* typing

* fmt

* fmt

* fmt

* pagination

* fmt

* fmt

* schema

* fmt

* fmt
2024-06-28 16:23:15 -07:00
Nuno Campos 5b6c021d6a cli 0.1.47 2024-06-28 14:05:06 -07:00
Nuno CamposandGitHub ca4ad62762 cli: Update messaging for langsmith api key (#884)
* cli: Update messaging for langsmith api key

* Adjust
2024-06-28 14:04:43 -07:00
Vadym BardaandGitHub d9bfe22f00 ci: remove grep check for previous tag (#881) 2024-06-28 14:00:08 -04:00
Vadym BardaandGitHub b8e6483770 ci: display previous tag during release job (#880) 2024-06-28 13:33:17 -04:00
Vadym BardaandGitHub 7e54aba3e7 ci: attempt regex fix (#878) 2024-06-28 12:22:24 -04:00
Vadym BardaandGitHub 6929afda8a langgraph: release 0.1.4 (#877) 2024-06-28 12:04:15 -04:00
Nuno Campos c326ad019d Skip bad pending sends 2024-06-28 08:59:26 -07:00
Vadym BardaandGitHub 2bf4a72d9d langgraph: release 0.1.3 (#876) 2024-06-28 11:51:58 -04:00
Isaac FranciscoandGitHub b066b6ffa1 speed up gifs (#870) 2024-06-28 11:32:50 -04:00
Vadym BardaandGitHub 36f5e49693 docs: update HITL how-tos (#875) 2024-06-28 10:44:17 -04:00
William FHandGitHub 19087ed6d8 [Docs] spelling (#869) 2024-06-27 19:39:18 -07:00
Isaac FranciscoandGitHub 0a2a64a830 sdk-js: adding assistant_id param for assistant_search functionality (#865)
* first draft

* wrong text
2024-06-27 13:18:51 -07:00
William FHandGitHub bccea30c2a [Docstrings] Add reminder to close connection (#864)
In AsyncSqliteSaver, otherwise your program will "hang".

Recommend using async with AsyncSqliteSaver.from_conn_str(...).
2024-06-27 12:59:26 -07:00
Nuno CamposandGitHub 5fa2172066 Update self_hosted.md (#862) 2024-06-27 12:32:35 -07:00
Vadym BardaandGitHub 00259d6217 cli: release 0.1.46 (#861) 2024-06-27 15:02:44 -04:00
Vadym BardaandGitHub cd670d9d59 cli: fix asyncio runner bug for 3.10 (#860) 2024-06-27 15:01:47 -04:00
Vadym BardaandGitHub 294426de62 docs: expose conversation history how-to (#859) 2024-06-27 14:38:07 -04:00
Vadym BardaandGitHub 8932a1e59e docs: fix link in README (#858) 2024-06-27 11:27:14 -07:00
Vadym BardaandGitHub 2c8d4b4e62 docs: add contribution guidelines (#844) 2024-06-27 14:20:01 -04:00
William FHandGitHub 90335613e9 [Docs] Update form link (#857) 2024-06-27 11:07:26 -07:00
William FHandGitHub c917664f60 [SDK] Cleanup docstring(#841) 2024-06-27 10:23:37 -07:00
e0d341e966 docs: add missing install for langchain_community module in tutorials intro (#814)
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-06-27 10:04:05 -07:00
William FHandGitHub 1f1e681242 [Docs] Add pyproject how-to for langgraph cloud repo structuring (#856) 2024-06-27 10:03:23 -07:00
William FHandGitHub a9f20c2339 Beta (#855) 2024-06-27 09:19:47 -07:00
Nuno Campos 0db341e566 cli 0.1.45a1 2024-06-27 09:10:56 -07:00
Nuno CamposandGitHub 4768bdb0c8 cli: Add back up (#854)
* Revert "cli: Reduce to test and build commands (#838)"

This reverts commit 5697f07163.

* Undo

* Undo

* Undo

* Fix

* Fix

* Add license key admonition

* Quote env vars

* Test
2024-06-27 09:10:21 -07:00
Vadym BardaandGitHub 7973df6216 cli: release 0.1.45a1 (#852) 2024-06-27 11:08:58 -04:00
Vadym BardaandGitHub 655de27e07 ci: update regex (#851) 2024-06-27 11:08:19 -04:00
Vadym BardaandGitHub d5c7d8c5d9 ci: clean up release diff logic & formatting (#850) 2024-06-27 10:42:29 -04:00
Vadym BardaandGitHub 545abbe38a docs: remove extra line (#849) 2024-06-27 10:12:11 -04:00
Vadym BardaandGitHub a783abc684 docs: add a how-to for streaming from final node (#832) 2024-06-27 10:07:20 -04:00
Harrison ChaseandGitHub b0ed8fdd3b Harrison/final nits (#845)
* final nits

* cr

* cr

* cr
2024-06-26 21:56:31 -07:00
0bccc19a50 [docs]: restructuring (#834)
* restructuring

* spelling

* links

* restructuring

* edits

* Update docs/docs/cloud/concepts/index.md

* Update docs/docs/cloud/concepts/index.md

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-06-26 20:21:43 -07:00
Harrison ChaseandGitHub a6e25ba7c1 agent tutorial (#822)
* cr

* cr

* cr

* cr

* cr
2024-06-26 20:21:09 -07:00
4de8c5a7ce docs: add concepts faq (#840)
* docs: add concepts faq

* cr

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-06-26 20:14:44 -07:00
Vadym BardaandGitHub ebad91e2e1 docs: add postgres checkpointer example (#839) 2024-06-26 21:43:58 -04:00
Nuno Campos 1a58af81b3 lib 0.1.2 2024-06-26 16:25:34 -07:00
8e611b42aa Fix bug in add_conditional_edges when no path_map is provided (#809)
* Fix bug in add_conditional_edges when no path_map is provided

When an instance of a callable class is passed as the path arg to
add_conditional_edges but no path_map is provided, get_type_hints(path) is
called, which raises a TypeError (since get_type_hints only accepts a module,
class, method, or function).

This patch fixes the error by trying to get type hints from path.__call__ first,
which should work for instances of callable classes.

Tested: Added a test that raises TypeError without the fix in this patch but
passes with the fix.

* More defensive, additional test

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-06-26 16:24:59 -07:00
Andrew NguonlyandGitHub 6ae5958164 docs: Update self-hosted how-to page for LangGraph Cloud (#808)
* Update self-hosted how-to page.

* Update self-hosted LangGraph Cloud how-to page.

* Add step to publish Docker image.

* Add warning label to Docker compose section.

* Fix spelling error.

* Add update self-hosted docs.

* Update self-hosted page.
2024-06-26 16:12:20 -07:00
Nuno Campos 307c0cfe09 sdkpy 0.1.25 2024-06-26 15:31:57 -07:00
Nuno CamposandGitHub c6466da098 sdk: Filter assistants by graph_id (#843) 2024-06-26 15:23:08 -07:00
Nuno Campos 32e8a2dc50 sdk py 0.1.24 2024-06-26 14:45:12 -07:00
Nuno CamposandGitHub 8d103667c8 sdk: Add support to filter threads by status (#842) 2024-06-26 14:44:27 -07:00
Isaac FranciscoandGitHub 2657ebb57c expose webhook option to sdk (#812) 2024-06-26 12:13:14 -07:00
Isaac FranciscoandGitHub 33d099989b replace threadless with stateless (#821) 2024-06-26 12:12:29 -07:00
Nuno Campos 29a040dc21 cli 0.1.45a0 2024-06-26 11:55:03 -07:00
Nuno CamposandGitHub 5697f07163 cli: Reduce to test and build commands (#838)
* cli: Reduce to test and build commands

* Bump timeout

* Fix test?

* Fix

* Fix output
2024-06-26 11:53:44 -07:00
Andrew NguonlyandGitHub fb5f3c972a Update openapi.json spec to include POST /runs endpoint. (#837) 2024-06-26 11:29:58 -07:00
Vadym BardaandGitHub 86c556d01e cli: release 0.1.43 (#836) 2024-06-26 13:45:35 -04:00
Vadym BardaandGitHub b7580abf45 cli: update CAT -> RUN in the dockerfile (#816) 2024-06-26 13:43:34 -04:00
Vadym BardaandGitHub 72ac58d1c2 docs: update persistence in the how-tos (#833) 2024-06-26 13:43:23 -04:00
Vadym BardaandGitHub 000a5c5b83 docs: update graph state in readme (#835) 2024-06-26 13:43:14 -04:00
Isaac FranciscoandGitHub 6caea79fba webhook (#810) 2024-06-26 10:41:29 -07:00
Nuno Campos fae97d9fba cli0.1.42 2024-06-26 09:37:25 -07:00
Nuno CamposandGitHub d16ec4f436 cli: Make base image configurable in build command (#831)
* cli: Make base image configurable in build command

* Lint

* Fix
2024-06-26 09:36:09 -07:00
William FHandGitHub 66b728e83a [Docs] Cleanup links in nb (#828) 2024-06-26 00:20:20 -07:00
William FHandGitHub feca5e1970 [Docs] Restore Linkcheck (#824)
Plus:
1. Improve docstrings of add_node
2. Update crosslinking of sqlite and aiosqlite docstrings
3. Fix a bunch of links so we can turn on strict validation
2024-06-26 00:04:13 -07:00
Jacob LeeandGitHub c217e4a58d Update intro to same thread example, update conceptual docs to include checkpoint (#827) 2024-06-25 22:20:50 -07:00
Harrison ChaseandGitHub fcdf7a8ced add links from concepts guide (#825) 2024-06-25 22:07:06 -07:00
Jacob LeeandGitHub 720ea986d3 Fix misaligned code block (#823) 2024-06-25 21:25:01 -07:00
ab54ae2c23 Harrison/tutorial (#820)
* first draft edits (#818)

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>

* cr

* cr

---------

Co-authored-by: Isaac Francisco <78627776+isahers1@users.noreply.github.com>
2024-06-25 20:46:01 -07:00
Jacob LeeandGitHub a5650e1d88 Style nits in quickstart (#819)
* Style nits in quickstart

CC @andrewnguonly

* Missing quote

* Update quick_start.md
2024-06-25 19:44:19 -07:00
Jacob LeeandGitHub e49f3f5434 Fix typo (#817)
CC @andrewnguonly
2024-06-25 19:24:20 -07:00
William FHandGitHub f9c720f25a Rm git committers (#815) 2024-06-25 17:09:26 -07:00
David DuongandGitHub 5db7a2dc6a cli: release 0.1.42 (#813) 2024-06-26 00:35:28 +01:00
David DuongandGitHub ac34a4724f chore(cli): use different container port for debugger (#811)
* chore(cli): use different container port for debugger

* Fix test
2024-06-26 00:16:50 +01:00
Vadym BardaandGitHub c13e755c15 docs: add streaming from within a tool (#807) 2024-06-25 15:23:18 -04:00
Andrew NguonlyandGitHub 11bf3bde54 docs: Various updates to LangGraph Cloud docs (#805)
* Change LangGraph Deploy to LangGraph Cloud in CLI reference.

* Update main README to link to Cloud docs. Update How-to Guide link in Cloud index page.

* Create Environments Variable reference page.

* Add Authentication to Conceptual Guide.

* Update setup how-to to refer back to CompiledGraph variable name.

* Update how-to notebooks for double texting.

* Add warning about setting top-level variable for CompiledGraph.
2024-06-25 10:52:23 -07:00
Vadym BardaandGitHub 7490b2b38b docs: fix concepts page format/links (#806) 2024-06-25 13:36:45 -04:00
Vadym BardaandGitHub 97ccdd92b9 docs: add more streaming how-tos (#803) 2024-06-25 13:15:53 -04:00
Andrew NguonlyandGitHub 09b0af0630 docs: Add how-to page for LangGraph Studio (#802)
* Add how-to page for LangGraph Studio.

* Fix spelling error.

* Fix grammar typo.
2024-06-25 01:23:58 -07:00
Andrew NguonlyandGitHub 6a2a81be1c docs: Create how-to for setting up LangGraph app and how-to for deploying to LangGraph Cloud (#801)
* Create how-to for setting up LangGraph app and how-to for deploying to LangGraph Cloud.

* Fix spelling errors.
2024-06-25 00:16:44 -07:00
Andrew NguonlyandGitHub 4fb297471b Update API docs include link to Scalar API site. (#798) 2024-06-24 21:11:40 -07:00
Andrew NguonlyandGitHub 317664be63 Create notebooks for creating cron jobs and stateless runs. (#797) 2024-06-24 17:03:38 -07:00
Andrew NguonlyandGitHub 265f5012c1 docs: Breakup LangGraph Cloud human-in-the-loop notebook (#794)
* Breakup how-to pages for human-in-the-loop.

* Update indentation of Python code in notebooks.
2024-06-24 16:30:18 -07:00
Lance MartinandGitHub 93faaea7bd Update local CRAG ntbk (#795)
* Update local CRAG ntbk

* fmt
2024-06-24 16:24:20 -07:00
Andrew NguonlyandGitHub f867315c2d Add notebook for configuring multiple streaming modes. Update stream events notebook to show token-by-token streaming. (#792) 2024-06-24 15:26:59 -07:00
Vadym BardaandGitHub e80ddab3a5 cli: add analytics (#754) 2024-06-24 18:14:56 -04:00
Lance MartinandGitHub 5e8d4e584b Add CoLab link (#791) 2024-06-24 14:52:18 -07:00
Andrew NguonlyandGitHub ebc9cfb694 docs: Update LangGraph Cloud quickstart (#788)
* Update Cloud quick start.

* Fix spelling errors.
2024-06-24 13:43:18 -07:00
Andrew NguonlyandGitHub b3907b33b2 Add JS SDK how-to page. (#787) 2024-06-24 13:27:36 -07:00
Andrew NguonlyandGitHub 3e7d32cedb Update Cloud index page. (#786) 2024-06-24 13:12:50 -07:00
11cf3b0510 Add ReAct vs Custom agent tutorial (#765)
* Add agent tutorial ntbk

* Update and clean

* Update / finalize

* spelling

* fmt

* unused

* Wfh/craggycrag (#781)

* tmp

* rethought

* Update, finalize analysis

* Update figures

* Remove subdirs

* Fmt

---------

Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com>
2024-06-24 13:08:34 -07:00
Vadym BardaandGitHub 66ae1ff9b0 CI: run only on file changes (#784) 2024-06-24 14:44:55 -04:00
David DuongandGitHub 393a0e741c feat(js): add ability to specify custom fetch (#783)
* feat(js): add ability to specify custom fetch

* Bump to 0.0.1-rc.14

* Fix format
2024-06-24 13:21:58 +01:00
William FHandGitHub d9b4d021bd [Docs] Update docstrings (#780)
To add more color on the meaning of some arguments.
2024-06-23 17:38:26 -07:00
Andrew NguonlyandGitHub 20f84f2041 docs: Create JS/TS SDK reference page (#779)
* Create JS/TS SDK reference docs.

* Remove index.mts from typedoc entry point.
2024-06-23 17:24:30 -07:00
Harrison ChaseandGitHub 070b339b67 Harrison/human in the loop (#776)
* add human in the loop examples

* cr

* cr

* cr

* cr

* cr

* cr

* cr
2024-06-23 14:35:43 -07:00
Andrew NguonlyandGitHub f39a22098d docs: Add Python SDK reference page (#773)
* Add Python SDK client.

* Update dependencies for docs group.
2024-06-23 12:46:01 -07:00
73e39fcba9 docs: add an example comparing LangGraph & LangGraph API (#764)
* docs: add an example comparing LangGraph & LangGraph API

* stash

* add cloud docs

* cr

* cr

* cr

* cr

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-06-22 18:33:17 -07:00
Harrison ChaseandGitHub 06fe906719 minor changes to cloud docs (#769)
* stash

* add cloud docs
2024-06-22 18:15:00 -07:00
Harrison ChaseandGitHub 616c343034 update tutorials and how to guides for langgraph (#768)
* stash

* stash

* stash

* cr

* cr

* cr
2024-06-22 17:30:52 -07:00
Harrison ChaseandGitHub a5aef5c450 langgraph conceptual docs (#767)
* stash

* stash

* cr

* cr
2024-06-22 15:23:44 -07:00
53fd0321cb Fix typo in ReWOO notebook (#755)
Co-authored-by: Vadym Barda <vadym@langchain.dev>
2024-06-22 14:36:21 -07:00
William FHandGitHub a514ad41d4 Format docs (#752) 2024-06-22 14:35:41 -07:00
Nuno CamposandGitHub b4d815e32a Add example for context key (#762) 2024-06-21 18:15:56 -07:00
Nuno Campos cf2bda49a0 0.1.1 2024-06-21 18:15:39 -07:00
Nuno CamposandGitHub 99fa57666e Add support for using Context channel in StateGraph (#761)
* Add support for using Context channel in StateGraph

* Fix handling of asynccontextmanager funcs
2024-06-21 17:49:52 -07:00
Vadym BardaandGitHub 571f1bac27 docs: minor typos (#760) 2024-06-21 20:07:28 -04:00
Vadym BardaandGitHub 44510532ee docs: add link to api references for create_react_agent (#759) 2024-06-21 19:24:14 -04:00
Andrew NguonlyandGitHub 6abcbd5a74 docs: Update API Concepts page, add notebooks for streaming events and streaming debug (#756)
* Update API Concepts page. Add notebooks for streaming events and streaming debug events.

* Remove localhost URL from notebook example.
2024-06-21 15:38:14 -07:00
Vadym BardaandGitHub a29f354d9b docs: update home page (#753) 2024-06-21 17:17:32 -04:00
Vadym BardaandGitHub 19dd293c3f docs: disable TOC on index pages (#751) 2024-06-21 15:57:42 -04:00
Vadym BardaandGitHub c99b63b9d8 docs: update cloud how-tos (#747) 2024-06-21 14:04:25 -04:00
Vadym BardaandGitHub f8e7221cae cli: release 0.1.41 (#746) 2024-06-21 12:19:33 -04:00
Vadym BardaandGitHub 6699f53d53 cli: fix standalone docker compose version str (#745) 2024-06-21 12:17:06 -04:00
Andrew NguonlyandGitHub 11a5d39f52 Add waitlist form link. (#739) 2024-06-21 07:06:20 -07:00
Vadym BardaandGitHub f741fbf92e docs: run codespell on all notebooks (#736)
* run codespell on all notebooks

* fix codespell
2024-06-20 21:39:13 -04:00
Vadym BardaandGitHub cae502b8fe docs: small cleanup (#733) 2024-06-20 21:02:27 -04:00
Harrison ChaseandGitHub edfca48549 add intro (#735) 2024-06-20 16:04:44 -07:00
Andrew NguonlyandGitHub e4de6bc49a docs: Rename deploy directory to cloud (#732)
* Rename deploy to cloud.

* Fix link for streaming pages.
2024-06-20 14:44:51 -07:00
Vadym BardaandGitHub 3e1e3fbac9 libs: add py.typed (#729)
* libs: add py.typed

* update
2024-06-20 17:08:35 -04:00
William FHandGitHub 3786a89eaa Spelling (#730) 2024-06-20 14:02:38 -07:00
f27d8e16ad docs: Add initial LangGraph Cloud docs (#725)
* Create Deploy docs.

* Add LangGraph CLI docs.

* Update API concepts page.

* Create quick start page.

* first draft (#695)

* first draft

* fmt

* fmt

* Revert "fmt"

This reverts commit e599030ab5.

* Revert "fmt"

This reverts commit ec8fca977e.

* var change

* import lint

* changed locations

* second draft

* fmt

* Revert "fmt"

This reverts commit 68a1c5c872.

* double texting lint

* concepts (#704)

* concepts

* python sdk

* docs structure

* fmt

* fmt

* Small touch ups, rename Hosted LangGraph API to LangGraph Cloud. (#724)

* Fix small typos.

* Fix broken links in quick start page.

* Add LangGraph Cloud reference docs.

---------

Co-authored-by: Isaac Francisco <78627776+isahers1@users.noreply.github.com>
2024-06-20 13:38:54 -07:00
Vadym BardaandGitHub 4a38dd45dc cli: release 0.1.40 (#728) 2024-06-20 16:10:28 -04:00
Vadym BardaandGitHub de5beead0d cli: fix windows issues (#723) 2024-06-20 16:07:15 -04:00
Vadym BardaandGitHub 616de2467c update deprecation warnings (#718) 2024-06-20 15:35:23 -04:00
Vadym BardaandGitHub adaeff149a add CLI examples & integration tests (#711) 2024-06-20 09:33:20 -04:00
Vadym BardaandGitHub 51dbbc71b3 update release js (#717) 2024-06-19 20:43:34 -04:00
Vadym BardaandGitHub 5586b59811 update default directory in release-js (#716) 2024-06-19 20:39:27 -04:00
Vadym BardaandGitHub 562b6a2301 sdk-js: release new rc (#715) 2024-06-19 20:35:54 -04:00
Vadym BardaandGitHub 301987eecd add JS release workflow (#714) 2024-06-19 20:29:02 -04:00
Vadym BardaandGitHub cffece7480 langgraph: release 0.1.0 (#713) 2024-06-19 17:42:22 -04:00
Vadym BardaandGitHub 19ff4a142f add test command for sdk-py (#710) 2024-06-19 16:00:55 -04:00
Vadym BardaandGitHub 6a926b2034 sdk-py: release 0.1.23 (#709) 2024-06-19 15:52:16 -04:00
Vadym BardaandGitHub 63802db0ef update tagging (#708) 2024-06-19 15:47:45 -04:00
Vadym BardaandGitHub 8c7182bcd4 update refs in release workflow (#707) 2024-06-19 14:24:40 -04:00
Vadym BardaandGitHub 070e74c775 cli: release 0.1.39 (#706) 2024-06-19 14:20:25 -04:00
Vadym BardaandGitHub c1cf269a15 add release workflows (#705) 2024-06-19 14:15:55 -04:00
Nuno CamposandGitHub 755495af46 Merge pull request #703 from langchain-ai/nc/19jun/update-project-info
Update pypi info for each package
2024-06-19 08:21:30 -07:00
Nuno Campos 68164484eb Fix 2024-06-19 08:19:17 -07:00
Nuno Campos 5fe91c110d Update pypi info for each package 2024-06-19 08:15:58 -07:00
17f1a05b6b [Docs] Grammar and punctuation improvements in LangGraph introduction tutorial (#680)
* Fix backtick enclosure in section 2

* Remove unnecessary double new line in route_tools() docstring

* Fix typos for describing checkpointer memory in section 3

* Fix grammar mistake when describing checkpointing in section 3

* Replace is with are to describe plural

* Fix incomplete double underscore wrapping for markdown formatting in section 7

---------

Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-06-18 18:04:34 -07:00
Nuno CamposandGitHub 4578a653c7 Merge pull request #688 from langchain-ai/vb/move-langgraph-libs
libs: add separate langgraph cli, sdk-py, sdk-js libraries and move core langgraph
2024-06-18 17:42:26 -07:00
vbarda b35bb19b31 sync again 2024-06-18 20:38:40 -04:00
vbarda 8be35f3b59 Revert "pyproject warning"
This reverts commit 2c8806a974.
2024-06-18 20:27:33 -04:00
vbarda 2c8806a974 pyproject warning 2024-06-18 20:24:04 -04:00
vbarda e791f7ef5a sync changes 2024-06-18 20:19:55 -04:00
Lance MartinandGitHub 7d3e460585 Merge pull request #641 from langchain-ai/rlm/update-nomic-embd
Update Nomic embeddings
2024-06-18 10:58:36 -07:00
Lance Martin b3116ece60 fmt 2024-06-18 10:54:55 -07:00
Lance MartinandGitHub cad90b571c Merge branch 'main' into rlm/update-nomic-embd 2024-06-18 10:41:59 -07:00
vbarda 7e936c3078 remove js build files 2024-06-18 13:13:57 -04:00
vbarda 52395d2e1a spellcheck 2024-06-18 12:16:01 -04:00
vbarda 5b72a3f210 update authors 2024-06-18 12:14:29 -04:00
vbarda 2607d550fc remove old docs reqs 2024-06-18 12:13:20 -04:00
vbarda 47f777c0f2 remove dockerfile, update readmes 2024-06-18 12:07:37 -04:00
vbarda 2b0fcb26f9 bump deps 2024-06-18 11:30:17 -04:00
vbarda 12aa185c31 Merge branch 'main' into vb/move-langgraph-libs 2024-06-18 11:18:16 -04:00
vbarda 4cdb64884d merge latest libs 2024-06-18 11:17:48 -04:00
vbarda 06f764f33d add gitignore file 2024-06-18 11:00:15 -04:00
vbarda 79f0b4860d attempt to fix js 2024-06-18 10:56:45 -04:00
Nuno CamposandGitHub 25320a45ec Merge pull request #687 from langchain-ai/dependabot/pip/urllib3-2.2.2
Bump urllib3 from 2.2.1 to 2.2.2
2024-06-18 07:53:43 -07:00
vbarda 7d45e737fa clean up docs building 2024-06-18 10:46:43 -04:00
vbarda ede161a0d3 update deploy docs 2024-06-18 10:01:04 -04:00
vbarda 895f5f00ab update extract stopwords script 2024-06-18 09:57:28 -04:00
vbarda a15cab8430 add js lint step 2024-06-18 09:44:16 -04:00
vbarda 955def0408 update caching logic + add names 2024-06-18 09:38:23 -04:00
vbarda 633b444e01 make the lint steps more flexible 2024-06-18 09:29:50 -04:00
vbarda 312bd05b3a update lock 2024-06-17 21:44:31 -04:00
vbarda 91be831804 fix 2024-06-17 21:42:54 -04:00
vbarda 8174bc22fb and even more small fixes 2024-06-17 21:40:55 -04:00
vbarda c5ad863a04 even more small fixes 2024-06-17 21:38:02 -04:00
vbarda fd5da5ec5e more small fixes 2024-06-17 21:34:35 -04:00
vbarda b7a6716274 small fixes 2024-06-17 21:20:41 -04:00
vbarda d3ab444edf CI 2024-06-17 21:12:53 -04:00
vbarda 1a06d500d4 libs: add cli, sdk-py, sdk-js and move core langgraph 2024-06-17 20:37:25 -04:00
dependabot[bot]andGitHub e767ccf678 Bump urllib3 from 2.2.1 to 2.2.2
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-17 23:03:41 +00:00
Vadym BardaandGitHub 45e22f3f12 Merge pull request #662 from langchain-ai/vb/add-create-react-agent-nb
[docs]: add create_react_agent how-to notebook
2024-06-17 15:41:15 -04:00
vbarda fe464591f7 code review 2024-06-17 15:25:47 -04:00
Lance MartinandGitHub 8620cc3289 Add evals to SQL agent tutorial (#669) 2024-06-17 08:51:12 -07:00
Nuno CamposandGitHub 321a63b57c Merge pull request #677 from langchain-ai/nc/14jun/add-tests-checkpointer-errors
Add tests to ensure checkpointer errors are not swallowed
2024-06-14 13:39:30 -07:00
Nuno Campos e8dc9f0678 old py 2024-06-14 13:35:28 -07:00
Nuno Campos fe87c44da7 Add tests to ensure checkpointer errors are not swallowed 2024-06-14 13:32:21 -07:00
William FHandGitHub 336637437e [Docs] Update to use v2.0 links (#675) 2024-06-14 12:38:44 -07:00
Nuno Campos 74b01a59e8 0.0.69 2024-06-14 11:59:11 -07:00
Nuno CamposandGitHub b1a3e17b67 Merge pull request #673 from langchain-ai/nc/14jun/version-all-channel-changes
Version all channel changes
2024-06-14 11:58:28 -07:00
Nuno CamposandGitHub 66796db3c0 Merge pull request #668 from langchain-ai/nc/13jun/configurable-next-version
Allow checkpointer to customize assignment of channel versions
2024-06-14 11:58:20 -07:00
Nuno Campos 4ff56edc26 Update docstrings 2024-06-14 11:15:08 -07:00
Nuno Campos faebaac554 Add docstring 2024-06-14 11:14:28 -07:00
Nuno Campos 758d62fd22 Version all channel changes
- previously when channels were cleared via update([]) or consume() that would not bump the version
- that behavior is not compatible with checkpointers that store blobs separately, which join checkpoint and blobs using version
- now update() and consume() return bool to indicate if version should be bumped
- this also avoids bumping version when nothing changed
2024-06-14 11:10:11 -07:00
Nuno Campos 033c29f55a Support non-int versions, add tests for an example str version 2024-06-13 18:38:02 -07:00
Nuno Campos d98e90a13e Support float and str versions 2024-06-13 18:14:30 -07:00
Nuno Campos a8b14a4e04 Allow checkpointer to override logic that creates the next version for each channel 2024-06-13 17:49:18 -07:00
vbarda 0b703444a1 update script/yml 2024-06-13 19:53:04 -04:00
vbarda fabade8ff5 lint 2024-06-13 19:24:37 -04:00
vbarda cfbb6ba7ee code review 2024-06-13 19:21:56 -04:00
Nuno Campos 3f1e47d519 0.0.68 2024-06-13 16:18:18 -07:00
Nuno CamposandGitHub d9ab5b73cf Merge pull request #666 from langchain-ai/nc/13jun/update-core
Update core and add tests for cancellation of astream and astream_events v2
2024-06-13 16:17:50 -07:00
Nuno Campos 09c70d9eda py 3.9 2024-06-13 16:13:56 -07:00
Nuno Campos e88e246a73 Update core and add tests for cancellation of astream and astream_events v2 2024-06-13 16:12:01 -07:00
Lance MartinandGitHub c227cc0d94 Merge pull request #655 from langchain-ai/ankush/06-11/sql-agent
sql agent tutorial
2024-06-13 11:15:51 -07:00
William FHandGitHub f1158fcbbb [Docs] Update ToolNode docstring (#664)
To impart more clarity on what it expects and returns.
2024-06-13 10:13:15 -07:00
Nuno Campos 6db7f3b2b5 0.0.67 2024-06-13 09:29:03 -07:00
Nuno CamposandGitHub cc91110257 Merge pull request #663 from langchain-ai/nc/13jun/adjust-default-error-policy
Adjust default error policy
2024-06-13 09:24:43 -07:00
Nuno Campos b6cc30c6d4 Adjust default error policy
- Add information about the last exception to retry logging
- Add a few more exceptions to the list not retried by default
2024-06-13 09:23:01 -07:00
vbarda ca4ce87c00 nit 2024-06-13 11:10:47 -04:00
vbarda 4ecb8fa088 add docs mention 2024-06-13 11:09:57 -04:00
vbarda b010ce6544 add create_react_agent how-to notebook 2024-06-13 11:07:40 -04:00
Ankush Gola 3ae9ca9184 lint 2024-06-12 14:29:14 -07:00
Ankush Gola 8ca641cda6 nits 2024-06-12 13:39:59 -07:00
Ankush Gola cf1c0a7d2d add image 2024-06-12 13:37:01 -07:00
Ankush Gola e21a0d69fb uncomment chinook 2024-06-12 13:26:18 -07:00
Ankush Gola f96ff9386b update agent 2024-06-12 13:25:07 -07:00
William FHandGitHub fe11bb77ab Update Lockfile (#644)
Removes a security warning
2024-06-12 11:37:12 -07:00
Ankush Gola 9cdac632a7 sql agent tutorial 2024-06-12 10:27:42 -07:00
William FHandGitHub 35ee7ade6f [Docs] Add some missing installs (#649) 2024-06-11 22:22:31 -07:00
William FHandGitHub 2e56a8a953 [Doc] Fix image link (#646) 2024-06-11 18:18:24 -07:00
William FHandGitHub 4eab1739da [Docs] Add ruff linting to .ipynb files (#645) 2024-06-11 18:02:49 -07:00
Mal CurtisandGitHub 854bf2c295 Fix grammar in map-reduce.ipynb (#642) 2024-06-11 16:27:05 -07:00
Vadym BardaandGitHub 0da231231e Merge pull request #636 from langchain-ai/vb/improve-readme
improve README
2024-06-11 16:04:36 -04:00
vbarda 8d41c44e73 remove an extra pregel reference 2024-06-11 15:37:19 -04:00
vbarda 5d84d90706 one more cr 2024-06-11 15:15:00 -04:00
vbarda 42d952ea70 expand compilation 2024-06-11 14:53:45 -04:00
vbarda b9c783ec8a more code review 2024-06-11 14:42:18 -04:00
Lance Martin ca3ed1e322 Update local to ensure running locally 2024-06-11 11:18:40 -07:00
Lance Martin 6e9bdcd7c7 Update Nomic embeddings 2024-06-11 10:45:03 -07:00
William FHandGitHub 6f2316e2d4 Bug Report TEmplate (#638) 2024-06-11 10:03:21 -07:00
vbarda 70f9434886 remove contributing section 2024-06-11 09:44:30 -04:00
vbarda 8ebdbbde9c code review 2024-06-11 09:43:30 -04:00
vbarda c1fafd51f7 small nits 2024-06-10 14:05:10 -04:00
vbarda 0f3eadc784 update why langgraph section 2024-06-10 14:01:47 -04:00
vbarda 97ed6d19a8 remove duplicate feature 2024-06-10 13:36:55 -04:00
vbarda 6869d4594a more complex example 2024-06-10 13:34:42 -04:00
vbarda 46d5812b98 small nits 2024-06-10 11:37:57 -04:00
vbarda 8c922c4275 remove unncessary line 2024-06-10 11:33:54 -04:00
vbarda 00ecd0e8a5 improve README 2024-06-10 11:31:45 -04:00
Nuno Campos 6cc375dc6a 0.0.66 2024-06-09 18:45:15 -07:00
Nuno CamposandGitHub 2a2f91eb56 Merge pull request #246 from langchain-ai/wfh/tnt-llm
TNT-LLM
2024-06-09 18:39:23 -07:00
Nuno CamposandGitHub b0c448d3be Merge pull request #528 from langchain-ai/rlm/code-gen-mistral
Langgraph Code Generation Example
2024-06-09 18:38:37 -07:00
Nuno Campos 1c61ec507f Fix typo 2024-06-09 18:31:39 -07:00
Nuno CamposandGitHub 58d3645783 Merge pull request #625 from sushengloong/remove-obsolete-groups
Remove obsolete dependency groups from Dockerfile
2024-06-09 18:29:33 -07:00
Nuno CamposandGitHub b8f9b5c3a0 Merge pull request #631 from langchain-ai/nc/9jun/reducer-unwrap-special-types
In Binop channels unwrap types before trying to instantiate
2024-06-09 18:28:53 -07:00
Nuno Campos 2095edef7a One more 2024-06-09 18:27:14 -07:00
Nuno Campos fbd3b63837 Fix import 2024-06-09 18:26:44 -07:00
Nuno Campos 3b4fcf6ee6 In Binop channels unwrap types before trying to instantiate
- this makes List/Sequence annotations behave same as list
2024-06-09 16:33:23 -07:00
William FHandGitHub 5799d6ca1c Accept dead-ends (#626)
Previously, we validated that nodes explicitly route to END.
This feels a bit unnecessary, since graphs are expected to keep processing until no work is left to be done

Plus fix a small bug in validation.
2024-06-08 00:00:13 -07:00
Sheng-Loong Su 0a013237df Remove obsolete dependency groups from Dockerfile 2024-06-08 09:15:33 +08:00
Nuno CamposandGitHub eb8e77c8d5 Merge pull request #624 from langchain-ai/vb/conditional-edges-typing
allow path_map keys to be non-strings in add_conditional_edges
2024-06-07 16:09:38 -07:00
vbarda 91653cf2ab fix ci 2024-06-07 17:45:20 -04:00
vbarda 76e207b643 add unittest 2024-06-07 16:36:48 -04:00
vbarda 92e95c21ab use hashable 2024-06-07 15:19:06 -04:00
vbarda f688a8ad31 update path 2024-06-07 14:56:43 -04:00
vbarda 68774a2b0f allow path_map keys to be non-strings in add_conditional_edges 2024-06-07 14:27:58 -04:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ba4aa2a875 Bump tornado from 6.4 to 6.4.1 (#616)
Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4 to 6.4.1.
- [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst)
- [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.0...v6.4.1)

---
updated-dependencies:
- dependency-name: tornado
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-07 11:13:21 -07:00
William FHandGitHub 88f367135e [Docs] Customer-Support Part 1: Configuration Fix (#623) 2024-06-07 11:09:20 -07:00
Nuno Campos 500a1abfeb 0.0.65 2024-06-07 10:06:58 -07:00
Harrison ChaseandGitHub 7a164dab09 add how to guide for convo history (#622)
* add how to guide for convo history

* cr

* cr
2024-06-07 09:41:47 -07:00
Nuno CamposandGitHub 38a5ca1e20 Merge pull request #617 from langchain-ai/nc/6jun/potential-fix-for-update-state-on-triggered-barrier 2024-06-07 09:20:24 -07:00
Nuno Campos ec0aa273fd Fix for update_state mistakenly resetting barrier channels
- This introduces a new optional method BaseChannel.consume, which gets called when a channel triggers a node
- This is an alternative place to clean up channel state, in addition to the existing pattern of clearing state in the update() call for the next step
- Channels should implement consume() when they want to clean up state exactly if and only if the channel triggered a node
- Channels should clean up state in update() when they instead need to guarantee their value is available for a single step, irrespective of whether it was actually read
2024-06-06 17:53:14 -07:00
9729d3412a [Docs] Fix Spacing of name (#614)
Co-authored-by: Christoph Görn <goern@redhat.com>
2024-06-06 13:03:42 -07:00
Eugene YurtsevandGitHub 4a825f61a5 x (#613) 2024-06-06 12:21:56 -04:00
Eugene YurtsevandGitHub 85c0103ebb docs: another attempt to fix nav bar (#612) 2024-06-06 12:08:39 -04:00
Eugene YurtsevandGitHub d73642145d docs: fix navigation for passing run time values to tools 2024-06-06 11:52:13 -04:00
Eugene YurtsevandGitHub ca178cdcf0 docs: Add example that shows how to pass run time values to tools (#610)
Adds a notebook that shows how to bind run time values to tools (e.g., user ID) and make them inaccessible to the LLM!
2024-06-06 11:42:13 -04:00
William FHandGitHub 48f34b88d6 [Docs] Wording nit in docstring (#607) 2024-06-05 21:23:46 -07:00
Nuno Campos b8f39172a5 0.0.64 2024-06-05 17:20:22 -07:00
Nuno CamposandGitHub f9e99b12e9 Merge pull request #604 from langchain-ai/nc/5jun/checkpointer-list-filter
Expose filter arg in get_state_history
2024-06-05 17:18:52 -07:00
Nuno Campos 145e655c09 Fix 2024-06-05 17:17:21 -07:00
Nuno Campos d366bacf03 Expose filter arg in get_state_history
- Combine list and search methods in Checkpointer
2024-06-05 17:14:35 -07:00
Nuno Campos 052284f21d 0.0.63 2024-06-05 16:40:06 -07:00
Nuno Campos d2e98ae835 Fix spread 2024-06-05 16:38:01 -07:00
William FHandGitHub 644ea3a3d7 [Docs] Link (#603) 2024-06-05 09:56:05 -07:00
Nuno CamposandGitHub bdd12be343 Merge pull request #601 from langchain-ai/wfh/se_to_constants
Move START & END to constants.py
2024-06-05 08:57:50 -07:00
William FHandGitHub 10f92992b4 Fixup ToC in ref doc (#602) 2024-06-05 07:49:35 -07:00
William Fu-Hinthorn bcc6e51f87 Move START & END to constants.py 2024-06-05 07:42:39 -07:00
William FHandGitHub 03ba503569 Rm END check in STORM (#600) 2024-06-05 07:40:58 -07:00
William FHandGitHub 1511c3b3e1 [Docs] Ref docs for Send (#599) 2024-06-05 07:40:37 -07:00
William FHandGitHub eac9c600aa Nicer NotImplementedError in sqlite checkpointer (#598) 2024-06-05 06:35:21 -07:00
Nuno CamposandGitHub 683495aceb Merge pull request #586 from langchain-ai/nfcampos-patch-1
copy path_map when passed to add_conditional_edge
2024-06-04 19:54:30 -07:00
William FHandGitHub 953a76535b Update outputs (#595) 2024-06-04 17:34:20 -07:00
William FHandGitHub 30e99289c1 [Doc]Add ToolMessage (#594) 2024-06-04 17:31:30 -07:00
William FHandGitHub 67b565329f Update info seeking (#592) 2024-06-04 14:51:26 -07:00
William FHandGitHub 90958ab973 [Docs] Add explanation for error handling when branching (#591) 2024-06-04 13:22:28 -07:00
William FHandGitHub 5fd52a486e [Docs] Stream Anything (#590) 2024-06-04 10:30:34 -07:00
William FHandGitHub 52945478ef [Docs] Update stream_tokens to clarify how in older versions of python (#587) 2024-06-04 10:02:14 -07:00
William FHandGitHub 5a3fbfe82d [Docs] Fixup stream mode values (#589) 2024-06-04 10:02:00 -07:00
William FHandGitHub dacb018b32 Update quickstart (#588) 2024-06-04 10:01:51 -07:00
Nuno CamposandGitHub e1d98a00d0 Update graph.py 2024-06-04 08:24:03 -07:00
William FHandGitHub 220bdb7fc4 [Docs] Add map reduce to index (#582) 2024-06-03 22:01:52 -07:00
Nuno Campos 2b5d503906 Add sqlite test with emoji 2024-06-03 16:38:44 -07:00
Nuno Campos d418261996 0.0.62 2024-06-03 16:33:15 -07:00
Nuno CamposandGitHub cdc3c43e36 Merge pull request #580 from langchain-ai/nc/3jun/serde-handle-unicode-issues
serde: Handle unicode issues when encoding
2024-06-03 16:32:14 -07:00
Nuno Campos d22fe60d4c serde: Handle unicode issues when encoding
- any invalid utf-8 chars now removed on dumps
- fix serialization of Send
- remove serialization of NamedTuple, which doesn't work
- add test for custom serde passed to memory saver
- add test using Send and JsonPlus serde
2024-06-03 16:28:32 -07:00
ccurmeandGitHub 8d54b09371 examples: update HITL notebook (#543)
* update notebook

* update

* verify via ToolMessage

* update

* revert change to legacy notebook

* clean up
2024-06-03 15:43:59 -07:00
Harrison ChaseandGitHub 5b3b485a14 update notebook with branching (#578) 2024-06-03 12:58:42 -07:00
Lance MartinandGitHub 9c9d7d4061 Merge pull request #577 from langchain-ai/rlm/code-gen-check
Update name for base-case chain on code-assistant ntbk
2024-06-03 09:37:29 -07:00
Lance Martin 688717aa1a Fix ntbk 2024-06-03 08:22:48 -07:00
Nuno Campos e1e502acfd 0.0.61 2024-06-02 14:13:53 -07:00
Nuno Campos a5d413063e Fix missing attr 2024-06-02 14:11:17 -07:00
William FHandGitHub 0003c74657 [Docs] Update mkdocs (#568) 2024-06-01 04:38:51 -07:00
William FHandGitHub a870e87e7f [Docs] Update edit links (#567) 2024-06-01 04:28:35 -07:00
Joe MartyandGitHub 1b354ab2bf Update introduction.ipynb (#553)
Replace old references to an "action" node with a "tools" node (since that is the name of the note in the first section of the tutorial)
2024-06-01 04:03:17 -07:00
Nuno CamposandGitHub 515f724876 Merge pull request #566 from langchain-ai/harrison/map-reduce-docs
add map reduce docs
2024-05-31 16:50:36 -07:00
Harrison Chase 9eb514fb84 cr 2024-05-31 16:49:09 -07:00
Harrison Chase 4dae779a00 add map reduce docs 2024-05-31 15:42:48 -07:00
Nuno CamposandGitHub fd1faea0ce Merge pull request #565 from langchain-ai/nc/31may/send
Rename Packet to Send
2024-05-31 15:22:55 -07:00
Nuno Campos 8d038ac8ab Lint 2024-05-31 15:21:22 -07:00
Nuno Campos 823b4849a2 Fix serde 2024-05-31 15:20:16 -07:00
Nuno Campos a436e14fad Rename checkpoint var 2024-05-31 15:18:56 -07:00
Nuno Campos 5b5323b94f Rename Packet to Send 2024-05-31 15:17:22 -07:00
Nuno CamposandGitHub 5f3c61da98 Merge pull request #560 from langchain-ai/nc/30may/stream-updates-asap
For stream_mode=updates (the default) stream the output of each node as soon as that node finishes
2024-05-31 15:14:53 -07:00
Nuno Campos 30e456be91 One more test, handle negative timeout 2024-05-31 15:13:07 -07:00
Nuno Campos 1fa327cb28 Lint 2024-05-31 14:48:35 -07:00
Nuno Campos ef3332ff74 Remove nested output for packet tasks 2024-05-31 14:46:56 -07:00
Nuno Campos 5ae9db83c7 Update ids in tests 2024-05-31 13:58:35 -07:00
Nuno CamposandNuno Campos 81a5720dd0 Add missing metadata 2024-05-31 13:30:05 -07:00
Nuno Campos 0409d70d0c For stream_mode=updates (the default) stream the output of each node as soon as that node finishes
- currently output of all nodes is streamed only when all nodes in that step finish
- checkpoint/values stream chunks still yielded only at the end of the step, as they require applying all updates
2024-05-31 13:30:05 -07:00
Nuno CamposandGitHub 48f75699b0 Merge pull request #559 from langchain-ai/nc/30may/debug-checkpoint-metadata
Add metadata to debug/checkpoint stream events
2024-05-31 13:25:09 -07:00
Nuno CamposandGitHub 1462b5e6b0 Merge pull request #557 from langchain-ai/nc/30may/map-reduce
Implement map-reduce api for StateGraph/Pregel
2024-05-31 13:24:36 -07:00
Nuno Campos 9c513ee7e6 Lint 2024-05-31 13:23:04 -07:00
Nuno Campos 9fd459c7fc Update to use a single arg like other nodes 2024-05-31 13:19:29 -07:00
Nuno Campos 87de8df888 Add metadata to debug/checkpoint stream events
- reorganize checkpointing code to share code between input and step checkpoints
- do not emit debug/checkpoint events when there is no checkpointer attached
- emit debug/checkpoint event for input checkpoint as well
2024-05-30 17:39:28 -07:00
Nuno Campos ae9c5639f0 Lint 2024-05-30 17:01:21 -07:00
Nuno Campos 683fac83dc don't clear pending packets when just viewing 2024-05-30 17:00:35 -07:00
Nuno Campos dc9c7254e7 Passthrough additional keys from node to cond edge
- this can be used to eg inform what gets sent in packets, without needing to write them to state first
2024-05-30 16:59:08 -07:00
Nuno Campos b19c426a33 In state graph validate that all nodes either return None or write to one of the state keys 2024-05-30 16:41:14 -07:00
Nuno Campos fb9fdcd345 Lint 2024-05-30 16:09:29 -07:00
Nuno Campos 75f14cc06d Finish tests 2024-05-30 16:08:30 -07:00
Nuno Campos 7a1feb466b Implement map-reduce api for StateGraph/Pregel
- current Pregel primitive is pull-based, ie. nodes write to channels, and it's up to other nodes to subscribe to those channels to "pull" updates
- this adds a "push" primitive where a node can directly schedule a node (more than once if desired) for execution in the next step, with additional kwargs to be passed in. Nodes scheduled in this way get called with both the current state and any kwargs passed to Packet
2024-05-30 15:36:32 -07:00
Nuno Campos 7a2de5e369 WIP 2024-05-30 11:45:21 -07:00
Nuno Campos 02326d74bf WIP 2024-05-30 11:45:21 -07:00
Nuno Campos 423ab4fe8b 0.0.59 2024-05-30 11:28:37 -07:00
Nuno CamposandGitHub ff67b99b19 Merge pull request #556 from langchain-ai/nc/30may/rm-uuid6-dep
Bundle in uuid6 func due to install issues with uuid6 library
2024-05-30 11:20:02 -07:00
Nuno Campos d08182c2e0 Fix 2024-05-30 10:47:49 -07:00
Nuno Campos dd0c3102c8 Fix 2024-05-30 10:45:51 -07:00
Nuno Campos 2faf2ff9ec Bundle in uuid6 func due to install issues with uuid6 library 2024-05-30 10:42:44 -07:00
Nuno Campos 75a9c0a1ee 0.0.58 2024-05-30 08:45:37 -07:00
Nuno CamposandGitHub 306f5a75e5 Merge pull request #555 from langchain-ai/nc/30may/return-state-model
Support returning non-dict objects as state updates from nodes
2024-05-30 08:43:36 -07:00
Nuno Campos d713f849f4 Lint 2024-05-30 08:42:07 -07:00
Nuno Campos e4c32248aa Support returning non-dict objects as state updates from nodes 2024-05-30 08:38:40 -07:00
Nuno CamposandGitHub 978d7aa539 Merge pull request #554 from langchain-ai/nfcampos-patch-1
Update ci rules
2024-05-30 08:10:39 -07:00
Nuno Campos c820c75caa Update test.yml 2024-05-30 08:08:46 -07:00
Nuno Campos cd7c8d4bdd Update ci rules 2024-05-30 08:08:46 -07:00
Nuno Campos 86bc774b3d Lint 2024-05-30 08:08:21 -07:00
Nuno Campos 6e74415ec8 Add test for node decorated with traceable decorator 2024-05-30 08:04:48 -07:00
Nuno Campos 199b0b2d88 0.0.57 2024-05-29 18:23:29 -07:00
Nuno CamposandGitHub 27b98581a6 Merge pull request #550 from langchain-ai/nc/29may/allow-more-annotations
Use the last annotation as the reducer
2024-05-29 18:22:11 -07:00
Nuno Campos e47a7adb3c Fix 2024-05-29 16:53:58 -07:00
Nuno Campos c3f68a6d7e Use the last annotation as the reducer 2024-05-29 16:47:39 -07:00
Nuno Campos 4893a24756 0.0.56 2024-05-29 07:15:11 -07:00
Nuno Campos 1ce8a16e1c Change pydantic detection 2024-05-29 07:14:07 -07:00
Nuno CamposandGitHub 53e7fab49f Merge pull request #548 from langchain-ai/wfh/better_error
More Descriptive TypeError
2024-05-29 06:42:17 -07:00
William Fu-Hinthorn dfeff082bb nit: Better TypeError 2024-05-29 06:21:31 -07:00
William FHandGitHub 7fdc849fa8 [Docs] Add analytics (#546) 2024-05-29 05:07:33 -07:00
4c4839ca65 docs: specify that configurables are added to LangSmith as metadata (#534)
* docs: specify that configurables are added to LangSmith as metadata

* docs: add link to concepts in README

---------

Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-05-29 02:33:10 -07:00
William FHandGitHub 5c8fe206d3 [Conceptual docs] Fixup block (#545) 2024-05-29 02:16:02 -07:00
William FHandGitHub 7cc172e4d4 🪄 (#541) 2024-05-28 08:31:01 -07:00
Lance Martin c4279c7706 Clean 2024-05-28 07:26:12 -07:00
Lance MartinandGitHub 5e5acb2e3f Merge pull request #536 from langchain-ai/rlm/check-self-rag
Minor change to upgrade libs
2024-05-26 15:26:32 -07:00
Lance Martin 5435ff6f7f Minor change to upgrade libs 2024-05-26 15:14:04 -07:00
Lance Martin 765e35f24a Update code-gen ntbk 2024-05-26 15:09:30 -07:00
Lance Martin 149ebd0896 Testing code generation 2024-05-23 15:46:14 -07:00
Nuno Campos 9dd7f9d7f2 0.0.55 2024-05-22 13:19:16 -07:00
Nuno CamposandGitHub 070b7965ca Merge pull request #526 from langchain-ai/nc/22may/multi-stream-mode
Add support for requesting multiple stream modes in same stream/astream call
2024-05-22 13:17:54 -07:00
Nuno Campos 51186ba66f Sort 2024-05-22 12:30:07 -07:00
Nuno Campos 24d130d407 Add support for requesting multiple stream modes in same stream/astream call 2024-05-22 12:25:28 -07:00
Deepankar MahapatroandGitHub 3493e66490 fix: getpass module call (#523) 2024-05-22 11:24:36 -07:00
William FHandGitHub 76981dfb39 Explicitly use config (#524) 2024-05-22 11:23:45 -07:00
Nuno CamposandGitHub c32b2c0bb7 Merge pull request #519 from langchain-ai/nc/21may/extend-root-state
Add support and tests for using messagegraph checkpoints on a stategraph with 1 __root__ key other keys
2024-05-22 09:15:54 -07:00
Nuno Campos 8b946af20f Add support and tests for using messagegraph checkpoints on a stategraph with 1 __root__ key other keys 2024-05-21 14:01:23 -07:00
Nuno Campos a65aa73d79 0.0.54 2024-05-21 12:54:48 -07:00
Andrew NguonlyandGitHub 08b505e017 Merge configurable fields with previous checkpoint config before each run (#510)
* Merge configurable fields with previous checkpoint config.

* Update update_state() and aupdate_state() to merge configurable fields with previous checkpoint config.

* Update tests to verify that all checkpoint metadata contain the expected configurable field keys. This assertion is needed because a run can have an arbitrary number of steps based on the construction of the graph.
2024-05-21 11:03:25 -07:00
William FHandGitHub d3cce1e245 [Docs] tool_selection (#515) 2024-05-21 09:05:28 -07:00
Diego QuezadaandGitHub 6df54d70e4 fix multiple typos (#512) 2024-05-20 23:42:57 -07:00
Nuno Campos e3a5870b0a 0.0.53 2024-05-20 17:59:41 -07:00
Nuno CamposandGitHub d79017b653 Merge pull request #508 from langchain-ai/nc/20may/add-checkpoint-state-methods
Expose checkpoint timestamp in get/update/list state methods
2024-05-20 16:29:02 -07:00
Nuno Campos c13741f9da Lint 2024-05-20 16:26:10 -07:00
Nuno Campos de71709fdc Expose checkpoint timestamp in get/update/list state methods 2024-05-20 16:23:46 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8c89609187 --- (#507)
updated-dependencies:
- dependency-name: requests
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-20 14:45:17 -07:00
Nuno Campos 03bac7eeef 0.0.52 2024-05-20 14:40:46 -07:00
Nuno CamposandGitHub f20863ddbf Merge pull request #506 from langchain-ai/nc/20may/fix-stream-v2
Add compat with stream_events v2
2024-05-20 13:44:22 -07:00
Nuno Campos 54454c9d58 Bump 2024-05-20 13:42:02 -07:00
Nuno Campos fa4f50c952 Add compat with stream_events v2 2024-05-20 13:39:28 -07:00
William FHandGitHub 9754602a56 Fix typo (#505) 2024-05-20 12:51:57 -07:00
Nuno Campos d4b3364bba Raise error if cond edge returns None 2024-05-20 12:00:17 -07:00
William FHandGitHub a6363da62c [Docs] Rm Integration Tutorial (#503) 2024-05-20 10:35:07 -07:00
William FHandGitHub 89d9c291fe [Docs] Rm then from docs (#502) 2024-05-20 10:31:36 -07:00
William FHandGitHub c00dcaf891 Members (#500) 2024-05-20 10:11:58 -07:00
Nuno CamposandGitHub e33e4a64f9 Merge pull request #499 from langchain-ai/wfh/warn 2024-05-20 09:46:43 -07:00
William Fu-Hinthorn 70c5a22e4b Warn invalid state 2024-05-20 09:33:19 -07:00
Nuno Campos 02db4adeb7 0.0.51 2024-05-20 08:48:13 -07:00
Nuno CamposandGitHub 01340928f9 Merge pull request #489 from andrewnguonly/few-shot-filter
Add support for passing `Callable` metadata filter to `FewShotExamples` managed value
2024-05-20 08:47:08 -07:00
William FHandGitHub 4c2703ea3a [Docs] update node name (#498) 2024-05-20 08:44:30 -07:00
Andrew Nguonly f5454715df Merge main branch. 2024-05-17 19:32:14 -07:00
Andrew Nguonly 09bae3022d Add checkpoint config to checkpoint metadata? 2024-05-17 19:25:02 -07:00
Andrew Nguonly 18addb52aa Add support for passing Callable metadata filter to FewShotExamples managed value. 2024-05-17 18:41:57 -07:00
Nuno Campos d63b15dc47 0.0.50 2024-05-17 15:37:58 -07:00
Nuno CamposandGitHub 997bc8dc3a Merge pull request #488 from langchain-ai/nc/17may/lc-20
Nc/17may/lc 20
2024-05-17 14:48:17 -07:00
Nuno Campos 0416da05b6 Fix 2024-05-17 14:45:29 -07:00
Nuno Campos b7e2af6bd1 Update pyproject 2024-05-17 14:43:55 -07:00
Nuno Campos 695503a4d3 Update to langchain-core 0.2.0
- Use stream_events(version=v2) in tests
2024-05-17 14:38:51 -07:00
Nuno Campos 56c55e9521 Update core version range 2024-05-17 13:43:59 -07:00
Nuno CamposandGitHub fb8868b710 Merge pull request #487 from andrewnguonly/sqlite-wal 2024-05-17 11:41:42 -07:00
Andrew Nguonly daa921c120 Fix lint error. 2024-05-17 11:11:04 -07:00
Andrew Nguonly 0e77ad88ef Fix typo: LastValue --> EphemeralValue. 2024-05-17 10:44:40 -07:00
Andrew Nguonly 93897c6df8 Enable write ahead log mode in SqliteSaver and AsyncSqliteSaver. 2024-05-17 10:41:20 -07:00
William FHandGitHub c056ec9f54 [Docs] Capitalization Nits (#485) 2024-05-17 08:15:54 -07:00
Nuno CamposandGitHub 920978c4ab Merge pull request #484 from langchain-ai/nc/16may/retry-policy
Add retry_policy for graphs
2024-05-16 18:10:32 -07:00
Nuno Campos 53501f6aaf Lint 2024-05-16 16:00:19 -07:00
Nuno Campos a4e88e930f Disable retries by default 2024-05-16 15:59:45 -07:00
Nuno Campos 2414e0ab5e Add retry_policy for graphs
- default is to retry, fully configurable
- configuration options follow temporal https://docs.temporal.io/retry-policies#properties
2024-05-16 15:44:30 -07:00
Nuno CamposandGitHub f03930ad36 Merge pull request #454 from langchain-ai/nc/add-node-single-arg
Add single arg overload for add_node, which takes function/runnable's…
2024-05-16 10:59:23 -07:00
William FHandGitHub 347e546c84 Fixup some syntax issues in docstrings (#483) 2024-05-16 10:17:10 -07:00
William FHandGitHub 9da2c7fecc Update sqlite error for async (#481) 2024-05-16 09:51:07 -07:00
William FHandGitHub f4a2da9095 Update copy script (#478) 2024-05-16 07:21:46 -07:00
William FHandGitHub 9d0b5d6193 discuss (#475) 2024-05-16 00:14:23 -07:00
William FHandGitHub 0eab47f6ec retries (#471) 2024-05-15 23:05:06 -07:00
William FHandGitHub 9977501480 Cleanup spacing in docstring (#470) 2024-05-15 20:05:39 -07:00
William FHandGitHub 4209508556 Tool Validator Node (#468) 2024-05-15 20:02:38 -07:00
William FHandGitHub a308eb5f3b Rm __end__ in lats (#469) 2024-05-15 19:43:12 -07:00
William FHandGitHub 3cd20efcbc Export START (#467) 2024-05-15 18:08:06 -07:00
William FHandGitHub d8c3e70900 Accept raw functions (#466) 2024-05-15 17:03:51 -07:00
William FHandGitHub aef06f17ed Add pointers to create_react_agent in how-tos where appropriate (#464) 2024-05-15 13:50:12 -07:00
ZeelandandGitHub 9c0f9fdb31 Add graph for hierarchical agent teams (#458) 2024-05-15 10:55:31 -07:00
William FHandGitHub 4f8346df35 Handle Async Callable (#457) 2024-05-15 10:54:53 -07:00
William FHandGitHub 6774ac1db2 update footer (#456) 2024-05-14 18:55:34 -07:00
Nuno Campos 6f888b6206 Add single arg overload for add_node, which takes function/runnable's name as the node name 2024-05-14 17:51:25 -07:00
Nuno CamposandGitHub 835c411148 Merge pull request #453 from langchain-ai/nc/14may/checkpoint-id-uuid6
Use uuid6 as the id for checkpoints
2024-05-14 17:00:02 -07:00
Nuno Campos 52b2c755d7 Use uuid6 as the id for checkpoints
- this avoids conflicts if multiple processes creating checkpoints in same thread at same time
- uuid6 with a monotically increasing clock_seq is sortable by creation time at ms precision (plus clock_seq for ties, plus 48 bits of randomness for further ties)
2024-05-14 16:56:25 -07:00
William FHandGitHub 72cb4bac1b Migrate langchain deps (#452) 2024-05-14 16:48:21 -07:00
Nuno Campos 77db7bf825 0.0.49 2024-05-14 16:32:33 -07:00
Nuno CamposandGitHub 9a43234ae5 Merge pull request #451 from langchain-ai/nc/14may/small-fixes-ii
More small fixes following JS impl
2024-05-14 16:29:09 -07:00
Nuno Campos a909d90b08 More small fixes following JS impl 2024-05-14 15:36:38 -07:00
Nuno CamposandGitHub a694aaa2bb Merge pull request #444 from langchain-ai/an/10may/few-shot-clone
Add `FewShotExamples` managed value (redo)
2024-05-14 15:35:48 -07:00
Andrew Nguonly 3f325e7b0c Rename parameter for asearch() in BaseCheckpointSaver class. 2024-05-14 14:48:14 -07:00
Andrew Nguonly 306260185a Remove commented out line. 2024-05-14 14:46:07 -07:00
Andrew Nguonly 78e3a240f1 Update implementation for constructing WHERE clause for SqliteSaver so that parameter values are not hardcoded, but bound instead. 2024-05-14 14:44:59 -07:00
Nuno CamposandGitHub 46e173c189 Merge pull request #448 from langchain-ai/nc/14may/debug-output-include-task-idx-in-task-id
debug: Include task index in task id
2024-05-14 13:38:02 -07:00
Nuno Campos 273a836fc4 debug: Include task index in task id 2024-05-14 13:35:56 -07:00
Andrew Nguonly 6ce9a2860b Rename metadata_query to metadata_filter. 2024-05-14 12:45:16 -07:00
Andrew Nguonly 28e5d8f699 Update FewShotExamples class to support setting filter and limit params. 2024-05-14 12:41:55 -07:00
Andrew Nguonly 3f34b03ba1 Wow. Adding back extra blank line. 2024-05-14 11:38:46 -07:00
Andrew Nguonly 0093b773f0 Remove extra blank line. 2024-05-14 11:37:04 -07:00
Nuno CamposandGitHub d8af81312a Merge pull request #447 from langchain-ai/nc/14may/small-fixes
Fix memory checkpointer list/alist
2024-05-14 11:24:04 -07:00
Andrew Nguonly 44c6b414c3 Update implementation of MemorySaver.asearch() to not use custom next_item() iterator function. 2024-05-14 11:23:41 -07:00
Andrew Nguonly d6d33f9551 Fix bug with WHERE clause being incorrect when passing before param. 2024-05-14 10:38:26 -07:00
Nuno Campos 0c37a17172 Fix memory checkpointer list/alist
- add tests for memory checkpointer list and alist
- fix async step counting
2024-05-14 10:37:01 -07:00
Nuno CamposandGitHub 6b5b653c2f Merge pull request #442 from langchain-ai/nc/13may/small-fixes
Small fixes while migrating JS
2024-05-14 10:13:28 -07:00
William FHandGitHub 7092e230c0 Extraction with Retries (#426) 2024-05-13 23:58:40 -07:00
William FHandGitHub f146668735 Rename "action" to "tools" in tools_condition w/in docs (#445) 2024-05-13 23:41:33 -07:00
William FHandGitHub b933fcdef7 Pause linkcheck (#446) 2024-05-13 23:31:22 -07:00
Nuno CamposandGitHub 63586d86fc Update tool_condition to match default ToolNode name 2024-05-13 18:58:20 -07:00
Andrew Nguonly c80090465f Copy learning.ipynb. 2024-05-13 18:42:55 -07:00
Andrew Nguonly 065e0ff360 Remove unused imports. 2024-05-13 18:34:54 -07:00
William FHandGitHub f335105853 Update Refs to clean up syntax highlighting (#443) 2024-05-13 18:32:42 -07:00
Andrew Nguonly aae05407f4 Lint code. 2024-05-13 18:22:07 -07:00
Nuno Campos a885b1ca53 Small fixes while migrating JS 2024-05-13 17:28:06 -07:00
Andrew Nguonly 7a8cbe18f9 Implement asearch() in AsyncSqliteSaver. 2024-05-13 17:21:17 -07:00
Andrew Nguonly 9b1efe9698 Implement search() for SqliteSaver. 2024-05-13 16:59:59 -07:00
Andrew Nguonly dcb7278c56 Add search and asearch APIs to BaseCheckpointerSaver class. Implement search and asearch in MemorySaver. 2024-05-13 15:55:38 -07:00
William FHandGitHub 2c32a38c42 Use create_react_agent (#441) 2024-05-13 14:32:26 -07:00
William FHandGitHub 1100360ea6 Add comment about fetching from the frontend (#439) 2024-05-13 12:43:26 -07:00
William FHandGitHub 1f045761b6 Add meta merging in docs (#440) 2024-05-13 12:31:43 -07:00
Nuno CamposandGitHub 8c7502fe1b Merge pull request #430 from langchain-ai/harrison/expose-messages-state
add messages state
2024-05-10 17:09:37 -07:00
Harrison Chase c48d5a6160 add messages state 2024-05-10 16:53:22 -07:00
445a110917 Add managed values and IsLastStep (#330)
* Add managed values and IsLastStep

- managed values are read-only state keys whose values are managed by langgraph
- this PR implements one: IsLastValue, a boolean which is True in the last iteration, eg to allow you to return a nice "ran out of iterations" message to user

* Fix

* Fix some issues

* py39

* Break ref

* Fix types

* Fix

* Fix

* Update state.py

* Don't mutate dictionary while using it in for loop.

---------

Co-authored-by: Andrew Nguonly <andrewnguonly@gmail.com>
2024-05-10 13:44:20 -07:00
Nuno CamposandGitHub b33aed6f67 Merge pull request #427 from langchain-ai/nc/9may/checkpoint-metadata-writes
Add writes property in checkpoint metadata
2024-05-10 10:01:52 -07:00
Nuno Campos 227f409611 Add writes property in checkpoint metadata
- This adds a historic view of the actions taken by nodes inside a thread, supporting rendering a richer history of a thread (eg in debug ui)
2024-05-09 14:30:29 -07:00
William FHandGitHub 006e4df9a4 Add conceptual guide (#424) 2024-05-09 11:10:40 -07:00
Nuno Campos 5397d99b95 Fix pg connection str 2024-05-08 10:48:57 -07:00
Nuno CamposandGitHub cdde575c53 Merge pull request #423 from langchain-ai/nc/8may/test-update-empty-thread
Add tests for calling update on an empty thread
2024-05-08 10:45:23 -07:00
Nuno CamposandGitHub f883e8242e Merge pull request #422 from langchain-ai/wfh/irrelevant
Rm irrelevant comment
2024-05-08 10:44:49 -07:00
Nuno Campos a6c6b8211f Add tests for calling update on an empty thread
- this would eg be what you'd do in an api like openai assistants api
2024-05-08 10:43:31 -07:00
William Fu-Hinthorn ea5d068c7e Rm irrelevant comment 2024-05-08 10:41:35 -07:00
William FHandGitHub 3e5ea31cdc Add Spellcheck and import hogwarts (#419) 2024-05-08 10:25:11 -07:00
Nuno CamposandGitHub 7463c6fd44 Merge pull request #421 from langchain-ai/nfcampos-patch-1
Test in python 3.12
2024-05-08 08:53:27 -07:00
Nuno CamposandGitHub 1f374ebb52 Test in python 3.12 2024-05-08 08:13:54 -07:00
William FHandGitHub 991d35be08 Update How-to Guides (#417)
- reduce the number of API keys needed (Use simple tool)
- make everything "tool use" oriented rather than split across agent executor, function calling, tool use, etc.
- Reorg navbar and index
- Fixup some docstrings
- Add more links to ref docs
- Mix up models used
- Simplify a few examples
2024-05-07 23:09:17 -07:00
William FHandGitHub f49e8dbc98 Update Checkpoints Docstrings (#418) 2024-05-07 18:40:31 -07:00
Nuno Campos eef5f0e4b2 0.0.47 2024-05-07 18:02:24 -07:00
Nuno Campos 89629bf9a0 Add fix for calling update state on empty thread 2024-05-07 17:52:46 -07:00
Nuno CamposandGitHub 6d5ba331be Merge pull request #416 from langchain-ai/nfcampos-patch-1
Update README.md
2024-05-07 13:11:47 -07:00
Nuno CamposandGitHub b00a233174 Update README.md 2024-05-07 13:10:22 -07:00
Nuno Campos 86b4703f10 Remove checkpointer check 2024-05-07 12:29:24 -07:00
William FHandGitHub dbe10a8c99 Migrate Tool Executor to ReAct Agent (#409) 2024-05-07 12:23:04 -07:00
William FHandGitHub 1836367ae0 De-list Deprecated Tutorials (#407) 2024-05-07 09:47:26 -07:00
William FHandGitHub 5916e3e424 Note Taker (#415) 2024-05-07 09:37:40 -07:00
William FHandGitHub f7ae9beef9 Update README (#405) 2024-05-07 09:36:04 -07:00
Nuno Campos 5fcfaf8506 0.0.46 2024-05-07 08:44:28 -07:00
Nuno CamposandGitHub 65dcba2e2a Merge pull request #411 from langchain-ai/nc/7may/fix-recursion-issue
Fix recursion check
2024-05-07 08:33:27 -07:00
Nuno CamposandGitHub 9d56669ffa Merge pull request #412 from langchain-ai/nc/7may/errors-module
Export all exceptions from langgraph.errors
2024-05-07 08:33:17 -07:00
Nuno Campos 7038d222ee Re-export 2024-05-07 08:14:41 -07:00
Nuno Campos e892c95194 Export all exceptions from langgraph.errors 2024-05-07 08:07:26 -07:00
Nuno Campos f4a4b98946 Fix recursion check 2024-05-07 07:57:36 -07:00
William FHandGitHub a1e55855fb Update image in tutorial (#410) 2024-05-07 07:50:51 -07:00
William FHandGitHub baf84599df Update Ref Docs on Checkpointing (#406) 2024-05-06 23:03:17 -07:00
William FHandGitHub b492e67046 Format notebooks (#404) 2024-05-06 22:01:05 -07:00
William FHandGitHub 50a0ead50d Fixup Reflexion for Claude (#403) 2024-05-06 21:56:41 -07:00
William FHandGitHub 49ccfdb780 Improve Intro Tutorial (#402) 2024-05-06 17:41:12 -07:00
Nuno Campos bf1989cab7 0.0.45 2024-05-06 17:06:20 -07:00
Nuno Campos ef3a568dc1 Update core 2024-05-06 17:06:20 -07:00
Erick FriisandGitHub cd53094f2e update readme DAG wording 2024-05-06 16:23:13 -07:00
Nuno Campos 0502699136 Update docstrings 2024-05-06 15:14:02 -07:00
Nuno CamposandGitHub 5bee63c7d5 Merge pull request #387 from langchain-ai/nc/3may/checkpoint-metadata
Add metadata to checkpoints, checkpoint inputs before first step
2024-05-06 14:41:29 -07:00
Nuno CamposandGitHub d1b0be8620 Merge pull request #401 from langchain-ai/dependabot/pip/jinja2-3.1.4
Bump jinja2 from 3.1.3 to 3.1.4
2024-05-06 12:22:27 -07:00
Nuno CamposandGitHub 8027d21b4c Merge pull request #386 from langchain-ai/nc/3may/test-draw-cyclical-edge
Add (failing) test for drawing cyclic edge
2024-05-06 12:22:16 -07:00
Nuno Campos 52852cb226 Update langchain-core 2024-05-06 12:20:20 -07:00
Nuno Campos 48865daf02 Fix checkpoint lineage for updates/resumes 2024-05-06 11:53:20 -07:00
Nuno Campos 251bd9744d Fix lineage of maual state updates 2024-05-06 11:53:20 -07:00
Nuno Campos 48df2d1084 Add assert 2024-05-06 11:53:20 -07:00
Nuno Campos 611ecdb1cd Checkpoint inputs before starting the first step for easier error recovery
- this enables easier retrying, for any error just do .invoke(None, config) no matter which step the error happened on
2024-05-06 11:53:20 -07:00
Nuno Campos f160f82912 Add checkpoint metadata fields
- source: input, update or loop
- step: int
- make step counter continue from previous last step
2024-05-06 11:52:49 -07:00
Nuno Campos 3ff3def62b Remove option to only checkpoint at end of run
- Now that checkpoint at end of each step adds no latency there is not point to keep this
- This will make it easier to add future features
2024-05-06 11:52:49 -07:00
Nuno Campos f304908102 Add metadata to checkpoints
- not yet used in this PR
2024-05-06 11:52:49 -07:00
dependabot[bot]andGitHub 3f9faf1910 Bump jinja2 from 3.1.3 to 3.1.4
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-06 18:33:18 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d79b483a67 Bump tqdm from 4.66.2 to 4.66.3 (#385)
Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.66.2 to 4.66.3.
- [Release notes](https://github.com/tqdm/tqdm/releases)
- [Commits](https://github.com/tqdm/tqdm/compare/v4.66.2...v4.66.3)

---
updated-dependencies:
- dependency-name: tqdm
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 11:31:55 -07:00
Erick FriisandGitHub 97a6f8ecb8 Merge pull request #400 from langchain-ai/erick/pinecone-example
pinecone example
2024-05-06 10:37:56 -07:00
Erick Friis 79660451bb pinecone example 2024-05-06 10:33:51 -07:00
William FHandGitHub e0770d68b3 Update notebooks to use bind_tools (#394) 2024-05-04 01:30:52 -07:00
William FHandGitHub 21b8cbfd33 Deprecate Chat agent executor & Function Calling Executor in Docs (#392) 2024-05-04 00:17:54 -07:00
William FHandGitHub 119bbe6bae Fixup dup pip (#389) 2024-05-03 15:49:51 -07:00
William FHandGitHub b7ec64df8d [Notebooks Pt 1/N] Fixup some Tool Calling + Import formatting + prebuilt usage (#388) 2024-05-03 15:48:10 -07:00
Nuno Campos 04fe48f661 Add (failing) test for drawing cyclic edge
- fix waiting for new release of langchain-core
2024-05-03 15:17:20 -07:00
Nuno CamposandGitHub a307fc9fc4 Merge pull request #384 from langchain-ai/wfh/markdown_link_relaaaaax
Markdown Link Check only on changed files
2024-05-03 12:41:02 -07:00
William Fu-Hinthorn 5d5ee80b08 ok maybe ok onschedule 2024-05-03 12:37:45 -07:00
William Fu-Hinthorn c18ef9160d Relax link check 2024-05-03 12:36:19 -07:00
Nuno Campos 7b03ce021c 0.0.44 2024-05-03 12:33:25 -07:00
Nuno Campos 446543d973 Fix RunnableCallable wrapper when sync func with config arg is invoked async 2024-05-03 12:33:12 -07:00
Nuno Campos 33961eb2f0 0.0.43 2024-05-03 12:03:19 -07:00
Nuno CamposandGitHub 4b15a307f8 Merge pull request #382 from langchain-ai/nc/26apr/fix-aiosqlite
Use a lock to fix aiosqlite checkpointer running setup multiple times if called in parallel
2024-05-03 12:01:15 -07:00
Nuno Campos 574614eab9 Fix aiosqlite checkpointer running setup multiple times if called in parallel
Use a lock instead
2024-05-03 11:40:23 -07:00
William FHandGitHub b185efe365 Check if conn is alive (#381) 2024-05-03 11:38:18 -07:00
Nuno Campos d6091f5fa4 0.0.42 2024-05-03 11:06:42 -07:00
Nuno CamposandGitHub 01860d6a73 Merge pull request #380 from langchain-ai/nc/3may/state-graph-prefer-pydantic-io-schema
StateGraph: use state schema as input/output schema if already a pydantic model
2024-05-03 11:03:49 -07:00
Nuno Campos 0e30723684 Lint 2024-05-03 11:01:34 -07:00
Nuno CamposandGitHub 3ae17e9dd1 Merge pull request #379 from langchain-ai/nc/3may/checkpoint-end-of-step-costfree
Make end-of-step chckpointing costfree
2024-05-03 11:00:56 -07:00
Nuno CamposandGitHub 47d057557c Merge pull request #378 from langchain-ai/nc/3may/state-history-pagination
Implement cursor pagination for get_state_history (time travel endpoint)
2024-05-03 11:00:24 -07:00
Nuno Campos 2ab84d1562 StateGraph: use state schema as input/output schema if already a pydantic model 2024-05-03 10:59:00 -07:00
Nuno Campos 45149d2dc5 Make end-of-step chckpointing costfree
- instead of waiting for checkpoint put before proceeding, submit to executor / event loop and await all at the end
2024-05-03 10:54:32 -07:00
Nuno Campos 42d3215e34 Implement cursor pagination for get_state_history (time travel endpoint)
- interface in base checkpointer
- implement in sqlite, aiosqlite, memory
- implement in Pregel.get_state_history()
2024-05-03 10:34:11 -07:00
Nuno Campos d732385b7c 0.0.41 2024-05-03 10:09:04 -07:00
Nuno CamposandGitHub bdea491801 Merge pull request #377 from langchain-ai/nc/3may/config-schema
Optional 2nd arg to StateGraph with config schema
2024-05-03 10:08:05 -07:00
Nuno Campos 467f42d799 Optional 2nd arg to StateGraph with config schema 2024-05-03 10:05:14 -07:00
Nuno CamposandGitHub 740011efa6 Merge pull request #376 from langchain-ai/harrison/configuration-branch
add how-to notebook for configuration
2024-05-03 10:01:19 -07:00
Harrison Chase 301d71ec34 cr 2024-05-02 18:57:06 -07:00
William FHandGitHub 8a38226078 Customer Support Bot Tutorial (Flight Assistant) (#375) 2024-05-02 16:53:18 -07:00
Nuno CamposandGitHub 8ec1d2e3e9 Merge pull request #363 from langchain-ai/harrison/add-args
Harrison/add args
2024-05-02 15:49:21 -07:00
Nuno Campos 27efba27c0 Update tests 2024-05-02 09:31:22 -07:00
Nuno Campos d723a1e752 Add name to debug payload 2024-05-02 09:26:32 -07:00
Harrison Chase dea85d236c Merge branch 'master' into harrison/add-args 2024-05-01 08:26:00 -07:00
Harrison Chase 97f3d66c0e cr 2024-05-01 08:17:21 -07:00
Nuno Campos b2020c1972 0.0.40 2024-04-30 16:55:44 -07:00
Nuno CamposandGitHub 7d3133b239 Merge pull request #370 from langchain-ai/nc/30apr/stream-mode-debug
Implement stream_mode=debug
2024-04-30 16:54:37 -07:00
Nuno Campos 5e322a6550 Implement stream_mode=debug
- outputs 3 types of payloads
-- task: node about to be executed
-- task_result: result of node execution
-- checkpoint: state values at end of superstep
2024-04-30 16:15:38 -07:00
Nuno CamposandGitHub 49c95cefcf Merge pull request #369 from langchain-ai/nc/30apr/test-async-cancellation
Add tests for async cancellation
2024-04-30 14:37:56 -07:00
Nuno CamposandGitHub 14a256919d Merge pull request #368 from langchain-ai/dqbd/pregel-serializable
feat(pregel): mark graph as serializable
2024-04-30 13:58:02 -07:00
Nuno Campos 281e312d40 Add tests for async cancellation
- when outer invoke/stream is cancelled currently running nodes should be cancelled
- when multiple nodes run in parallel and one fails the others should be cancelled
2024-04-30 13:57:11 -07:00
Nuno CamposandGitHub d042f0d5fe Merge pull request #367 from langchain-ai/nc/30apr/interrupt-before-all
Implement interrupt_before=* and interrupt_after=*
2024-04-30 13:19:02 -07:00
Tat Dat Duong 2e3a690b34 feat(pregel): mark graph as serializable 2024-04-30 22:18:10 +02:00
Nuno Campos 280839b9df Try to avoid using deprecated method 2024-04-30 10:16:53 -07:00
Nuno CamposandGitHub c293d3d71d Merge pull request #366 from langchain-ai/nc/30apr/pregel-no-implicit-channels
Pregel: Remove implicit creation of channels referenced by nodes
2024-04-30 10:06:14 -07:00
Nuno Campos afa6a91934 Implement interrupt_before=* and interrupt_after=*
- This interrupts execution before/after all nodes
2024-04-30 10:05:53 -07:00
Nuno Campos 9a79eb54f9 Finish fixing tests 2024-04-30 09:23:41 -07:00
Nuno Campos 96870c0935 Pregel: Remove implicit creation of channels referenced by nodes
- channels must be declared in the constructor args
2024-04-30 09:04:19 -07:00
Nuno CamposandGitHub f6d332beb9 Merge pull request #362 from langchain-ai/nc/29apr/support-cond-edge-list-literal
For cond edges support specifying list of possible destinations as a list or typing annotation
2024-04-30 08:56:05 -07:00
Nuno CamposandGitHub 9505d8cc84 Merge pull request #365 from langchain-ai/nc/29apr/support-non-str-thread-ids
Nc/29apr/support non str thread ids
2024-04-30 08:54:14 -07:00
Nuno Campos 7554309abf Update tests 2024-04-29 17:46:42 -07:00
Nuno Campos ca2c93e0a1 Lint 2024-04-29 17:41:36 -07:00
Nuno Campos 516a74351d Support non str ids in sqlite checkpointers 2024-04-29 17:41:03 -07:00
Harrison Chase aa48a3be3d cr 2024-04-29 16:37:16 -07:00
Jose MayorgaandGitHub 75bb0e83cd Fixes #248, pattern validation failure (#277) 2024-04-29 15:27:23 -07:00
Aryan VermaandGitHub ee8fad5f7f Fix/call the correct variable authoring_graph during compilation (#292) 2024-04-29 15:27:03 -07:00
Trung PhanandGitHub a72d162a10 Fix typo in examples/human-in-the-loop.ipynb (#359) 2024-04-29 15:26:14 -07:00
Arno AngererandGitHub ede895cd9f Added required gpt4all dependency (#357)
For the GPT4AllEmbeddings to work (in the Indexing part) the `gpt4all` package is required. This PR adds it to the list of required dependencies at the top of the notebook
2024-04-29 15:25:52 -07:00
Harrison Chase a32fe442f0 cr 2024-04-29 14:59:31 -07:00
Harrison Chase d12c2bae6b add arguments to chat agent executor 2024-04-29 14:58:25 -07:00
BrantandGitHub 32ac2fdacb fix: examples plan-and-execute (#316) 2024-04-29 14:47:40 -07:00
Nuno Campos a3c867d688 Remove add_condition_nodes 2024-04-29 11:13:16 -07:00
Nuno Campos 3a59fb2247 Pass add_condition_node 2024-04-29 11:04:15 -07:00
Nuno Campos 4a28f19922 Remove labels if redundant 2024-04-29 10:44:45 -07:00
Nuno Campos a83fd19b29 For cond edges support specifying list of possible destinations as a list or typing annotation 2024-04-29 10:38:06 -07:00
Nuno CamposandGitHub 6519d72837 Merge pull request #353 from langchain-ai/nc/26apr/tracing-improv
Improve tracing output for function nodes
2024-04-29 09:02:38 -07:00
Nuno Campos fd9d30f144 Improve tracing output for function nodes
- remove double entry in tracing tree when using functions as nodes
2024-04-29 08:59:56 -07:00
Nuno Campos 0e3c37ba25 0.0.39 2024-04-25 11:35:14 -07:00
Nuno CamposandGitHub f15190e20f Merge pull request #339 from langchain-ai/nc/24apr/draw-xray
Improvements to get_graph(xray=)
2024-04-25 11:32:13 -07:00
Nuno Campos 61d0f60b8e Update 2024-04-25 11:30:23 -07:00
Nuno Campos 42b13ef576 Improvements to get_graph(xray=)
- Support xray: int, to control depth, eg xray=1 only exposes one level deep
- In mermaid draw a containing box around subgraphs created from xray
2024-04-25 11:27:13 -07:00
Nuno CamposandGitHub daf8bf2eef Merge pull request #317 from langchain-ai/nc/17apr/serde
Introduce json-based checkpoint serialization
2024-04-24 16:26:56 -07:00
Nuno Campos f975bd1c28 Fix 2024-04-24 16:23:31 -07:00
Nuno Campos 2e9e29243f Lint 2024-04-24 16:20:43 -07:00
Nuno Campos 4b8599b325 Fix 39 2024-04-24 16:19:32 -07:00
Nuno Campos a08eaf1a77 Fix 2024-04-24 16:18:02 -07:00
Nuno Campos 53378476ce Lock 2024-04-24 16:14:24 -07:00
Nuno Campos f9646b6a57 Use by default in sqlite adapters
- Support loading pickled checkpoints for backwards compat
- Update copy_checkpoint to coerce values to defaultdicts where needed
2024-04-24 16:08:41 -07:00
Nuno Campos e45c461d99 Fix 2024-04-24 15:42:43 -07:00
Nuno Campos d4982eb022 Fix 2024-04-24 15:40:48 -07:00
Nuno Campos 9bf90442e0 Undo 2024-04-24 15:40:48 -07:00
Nuno Campos 2824541102 Fix 2024-04-24 15:40:48 -07:00
Nuno Campos c6a199abc2 Skip py39 2024-04-24 15:40:48 -07:00
Nuno Campos 3ad0204a90 Add test 2024-04-24 15:40:48 -07:00
Nuno Campos 6125ea68f5 WIP 2024-04-24 15:40:48 -07:00
Nuno CamposandGitHub c447884ed0 Merge pull request #345 from langchain-ai/nc/24apr/fix-write-runnable-bug
Fix bug where saving a runnable or function in state object would misbehave
2024-04-24 15:36:53 -07:00
Nuno CamposandGitHub 35c5e1a697 Merge pull request #344 from langchain-ai/efriis-patch-1
Link docs in readme
2024-04-24 15:36:37 -07:00
Nuno CamposandGitHub 23f6658424 Merge pull request #343 from langchain-ai/nc/24apr/dbeug
Improve debug logging
2024-04-24 15:36:18 -07:00
Nuno CamposandGitHub 9c21f18eb6 Merge pull request #342 from langchain-ai/nc/24apr/branch-then
Add `then=` arg for add_conditional_edge and set_conditional_entry_point
2024-04-24 15:36:11 -07:00
Nuno Campos 3571a893f2 Fix bug where saving a runnable or function in state object would misbehave
- the function/runnable would be called when processing the state update
2024-04-24 15:35:02 -07:00
Nuno Campos c1feff2211 Rename for clarity 2024-04-24 15:04:47 -07:00
Erick FriisandGitHub a3b8d0694d Link docs in readme 2024-04-24 14:56:33 -07:00
Nuno Campos d3353427ae Improve debug logging 2024-04-24 14:55:12 -07:00
Nuno Campos 0e99cc5128 Lint 2024-04-24 14:52:45 -07:00
Nuno Campos 79bff13a47 Add then= arg for add_conditional_edge and set_conditional_entry_point
- This makes it easy to implement graphs where you want to decide among N possible nodes, and then visit another node after whichever one you chose
2024-04-24 14:06:07 -07:00
Nuno CamposandGitHub 1c0a138276 Merge pull request #340 from langchain-ai/nc/24apr/graph-validation
Improve graph validation
2024-04-24 12:32:40 -07:00
Nuno Campos 9ee5699f9a Fix 2024-04-24 11:22:53 -07:00
Nuno Campos 9f9c08bab9 Lint 2024-04-24 11:22:36 -07:00
Nuno Campos f2803372ec Improve graph validation
- Move all validation to compile() This allows adding edges before nodes
- Detect more cases of missing edges with shorthand branches
2024-04-24 11:19:40 -07:00
William FHandGitHub e01e1c6735 Add USACO example (#333)
Tutorial based on the paper: https://arxiv.org/abs/2404.10952v1 by Quan Shi, Michael Tang, Karthik Narasimhan, Shunyu Yao
2024-04-23 13:00:47 -07:00
Nuno CamposandGitHub 4707183814 Merge pull request #336 from langchain-ai/nc/22apr/fix-repeat-conditions
Fix issue when drawing graphs w repeat conditions
2024-04-22 09:56:30 -07:00
Nuno Campos 190d163005 Fix 2024-04-22 09:54:45 -07:00
Nuno Campos 85bdc8bdfa Fix issue when drawing graphs w repeat conditions 2024-04-22 09:53:14 -07:00
Nuno CamposandGitHub de9c0786f5 Merge pull request #328 from angeligareta/improve_visualization_notebook
Fix visualization notebook outputs
2024-04-22 08:38:19 -07:00
Angel Igareta 45a9a054d7 Fix visualization notebook outputs 2024-04-19 17:29:36 +02:00
Lance MartinandGitHub 37d2ae2aec Merge pull request #327 from langchain-ai/rlm/llama3
Local RAG agent w/ LLaMA3
2024-04-18 19:59:02 -07:00
Lance Martin 5abe98e8d9 RAG agent llama3 loca 2024-04-18 17:46:31 -07:00
Nuno CamposandGitHub 97dc410b08 Merge pull request #323 from angeligareta/improve_visualization_notebook
Enrich visualization notebook to showcase new capabilities
2024-04-18 10:20:55 -07:00
Nuno Campos 3edf7e4d73 Fix 2024-04-18 10:18:56 -07:00
Nuno CamposandGitHub e0618083d8 Merge pull request #325 from langchain-ai/dependabot/pip/aiohttp-3.9.4
Bump aiohttp from 3.9.3 to 3.9.4
2024-04-18 09:07:11 -07:00
William FHandGitHub fe03a60dff Fix bullet point (#324)
In tutorials index
2024-04-18 09:04:08 -07:00
Nuno Campos 38d990cf99 Merge branch 'main' into improve_visualization_notebook 2024-04-18 09:02:45 -07:00
dependabot[bot]andGitHub 0396436b02 Bump aiohttp from 3.9.3 to 3.9.4
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.3 to 3.9.4.
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.3...v3.9.4)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-18 16:01:24 +00:00
Nuno Campos 9e6fc78ac2 Make test deterministic 2024-04-18 08:40:56 -07:00
Angel Igareta 3fb6519886 Remove graph from repo 2024-04-18 16:04:36 +02:00
Angel Igareta d925736741 Snapshot updated for python 3.11 2024-04-18 13:19:51 +02:00
Angel Igareta 63125fe7a7 Snapshot updated 2024-04-18 13:01:24 +02:00
Angel Igareta c5ecd18312 Update langchain_core 2024-04-18 12:57:06 +02:00
Angel Igareta 99c2754156 Fix tests due to change of style for conditional edges. Migrate ascii to snapshot for system compatiblity 2024-04-18 12:53:43 +02:00
Angel Igareta 7f826abaa2 Fix linting 2024-04-18 12:20:31 +02:00
Angel Igareta f1eca30912 Update visualization notebook to showcase new capabilities for mermaid rendering (syntax and PNG), as well as removing conditional nodes 2024-04-18 12:19:45 +02:00
Angel Igareta 6570fd0ccb Fix get_graph method to define conditional edges 2024-04-18 12:19:07 +02:00
William FHandGitHub 49cced4f92 Tutorial (#315) 2024-04-18 01:15:21 -07:00
Yulong WangandGitHub 4244bab90e Fix typo in README.md (#322) 2024-04-18 01:07:02 -07:00
Nuno Campos 50cd5e27f2 0.0.38 2024-04-17 16:08:17 -07:00
Nuno CamposandGitHub 0d0bd8b430 Merge pull request #321 from andrewnguonly/default-state-value
Default state value (`StateGraph`) to `None` if channel is empty
2024-04-17 15:54:38 -07:00
Nuno CamposandGitHub f8465bfd5e Merge pull request #318 from langchain-ai/eugene/update_lock_file
Update lock file
2024-04-17 15:39:37 -07:00
Andrew Nguonly 084ab53252 Default state value to None if channel is empty. 2024-04-17 15:38:50 -07:00
Nuno CamposandGitHub 151a38d6e9 Merge pull request #320 from langchain-ai/nc/17apr/fix-stream-events
Fix astream_events modifying output format unexpectedly
2024-04-17 15:38:20 -07:00
Nuno Campos 64dd631668 Lint 2024-04-17 15:26:05 -07:00
Nuno Campos 322cea054c Fix astream_events modifying output format unexpectedly
- (unrelated) use run_id passed in
- if using a graph as node in another graph ensure stream_mode for inner call is always values
- ensure langchain-core doesn't auto promote streamed dicts to addable dicts, which results in unexpected output (only) when calling astream_events
2024-04-17 15:24:43 -07:00
Eugene Yurtsev 9e9f44a868 x 2024-04-17 13:36:22 -04:00
Nuno CamposandGitHub 8a39eb41cd Merge pull request #310 from angeligareta/add_condition_nodes_as_optional
Make condition nodes optional
2024-04-17 09:21:49 -07:00
Angel Igareta 4e8e51126d Fix formatting in graph 2024-04-17 18:03:22 +02:00
Ángel IgaretaandGitHub 35fe16b615 Merge branch 'main' into add_condition_nodes_as_optional 2024-04-17 17:53:51 +02:00
Nuno CamposandGitHub e35d349ef0 Merge pull request #314 from langchain-ai/nc/16apr/forward-ref
Resolve type annotation forward refs when parsing StateGraph schema type
2024-04-16 15:15:53 -07:00
Nuno Campos 012bbb961f Lint 2024-04-16 15:07:51 -07:00
Nuno Campos bdf0def798 Resolve type annotation forward refs when parsing StateGraph schema type 2024-04-16 15:05:04 -07:00
Nuno CamposandGitHub f91fb184a1 Merge pull request #308 from Undertone0809/zeeland/fix-typo
docs: fix wrongly written characters
2024-04-16 13:47:26 -07:00
Nuno CamposandGitHub 4327997b4d Merge pull request #300 from langchain-ai/dependabot/pip/idna-3.7
Bump idna from 3.6 to 3.7
2024-04-16 09:56:36 -07:00
William FHandGitHub 85f48da84e Docs Draft (#286) 2024-04-15 22:44:12 -07:00
Marco TrinelliandGitHub eb10fe599b fix: plan execute example response state (#303) 2024-04-15 22:43:11 -07:00
Angel Igareta 0f667cd9eb Add add_condition_nodes parameter to offer possibility of not including conditional nodes 2024-04-15 10:56:19 +02:00
zeeland e8d33210a7 docs: fix typo 2024-04-14 02:29:23 +08:00
Nuno CamposandGitHub 83df0ac844 Merge pull request #305 from langchain-ai/nc/12apr/configurable-serde
Make ser/de configurable in checkpointer classes
2024-04-12 12:50:44 -07:00
Nuno Campos f5a7c01e88 py39 2024-04-12 11:55:20 -07:00
Nuno Campos 74a40a895a Make ser/de configurable in checkpointer classes
- Remove pydantic usage from base checkpointer class
- Make serialization configurable for all existing checkpointer classes, you can eg use dill or json instead of pickle
2024-04-12 11:49:29 -07:00
Nuno Campos aa07d30e1f 0.0.37 2024-04-12 11:00:27 -07:00
Nuno CamposandGitHub d276510cb5 Merge pull request #304 from langchain-ai/nc/12apr/shorted-cond-edge-name
Shorten conditional edge names
2024-04-12 10:59:25 -07:00
Nuno Campos f3ae555b91 Shorten conditional edge names 2024-04-12 09:29:27 -07:00
dependabot[bot]andGitHub 2ff9d94bb6 Bump idna from 3.6 to 3.7
Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst)
- [Commits](https://github.com/kjd/idna/compare/v3.6...v3.7)

---
updated-dependencies:
- dependency-name: idna
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-12 00:05:35 +00:00
Nuno Campos dfec700da8 0.0.36 2024-04-11 17:04:19 -07:00
Nuno Campos 0015cb5f3a Fix non str values in cond edges 2024-04-11 11:52:20 -07:00
Nuno Campos ce6989daee 0.0.35 2024-04-11 11:51:53 -07:00
Nuno CamposandGitHub cd0bc870b3 Merge pull request #299 from langchain-ai/nc/11apr/stream-mode-values-all
In stream_mode=values yield all values, instead of only changed ones
2024-04-11 11:41:00 -07:00
Nuno Campos a8af7467b8 In stream_mode=values yield all values, instead of only changed ones 2024-04-11 11:12:10 -07:00
Nuno CamposandGitHub 9ffd6d9c78 Merge pull request #296 from langchain-ai/nc/10apr/tool-node
Add prebuilt ToolNode, Make prebuilt create_tool_calling_executor compatible with any tool calling model
2024-04-11 11:10:59 -07:00
Nuno Campos 92deae4196 Add anthropic notebook 2024-04-11 10:50:06 -07:00
Nuno CamposandGitHub 98ecc72de0 Merge pull request #298 from hmasdev/feature-handle-falsy-output
Pregel: Add support for falsy outputs in Pregel class
2024-04-11 08:46:34 -07:00
Nuno Campos 46e67cff87 Remove flag 2024-04-11 08:44:41 -07:00
hmasdev 236ecb1982 rename node name in tests 2024-04-11 20:34:45 +09:00
hmasdev 42de3304dc Add support for allow_falsy_output parameter in Pregel class 2024-04-11 19:46:01 +09:00
Nuno Campos c8d3f73d04 Lint 2024-04-10 18:55:12 -07:00
89a14160b0 Apply suggestions from code review
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-04-10 18:41:12 -07:00
Nuno Campos 7dafc09a5b Add prebuilt ToolNode 2024-04-10 18:15:19 -07:00
Nuno CamposandGitHub 1141370593 Merge pull request #295 from langchain-ai/nc/10apr/add-invoke-updates-mode
Support stream_mode=updates in invoke()
2024-04-10 17:52:20 -07:00
Nuno Campos 8788a6adfb Support stream_mode=updates in invoke() 2024-04-10 17:12:09 -07:00
Nuno Campos 8725839492 0.0.34 2024-04-10 16:18:30 -07:00
Nuno CamposandGitHub 8627e4e65c Merge pull request #294 from langchain-ai/nc/10apr/fix-null-output
Fix null output for node with conditional edge returning END
2024-04-10 16:17:51 -07:00
Nuno Campos 641def6fdb Fix null output for node with conditional edge returning END 2024-04-10 16:10:08 -07:00
Nuno Campos 71436be306 0.0.33 2024-04-10 16:09:07 -07:00
Nuno CamposandGitHub 8e941fb762 Merge pull request #290 from langchain-ai/eugene/postgres_example
Examples: Add persistence with langchain-postgres
2024-04-09 12:34:33 -07:00
Eugene Yurtsev a81ba40a86 x 2024-04-09 15:06:58 -04:00
Eugene Yurtsev 57feccfec9 x 2024-04-09 15:06:15 -04:00
Eugene Yurtsev 40a0f8c9ca x 2024-04-09 15:06:03 -04:00
Nuno CamposandGitHub 52621bb803 Merge pull request #288 from langchain-ai/nc/8apr/cond-edge-multiple-destinations
feat: Return multiple destinations from conditional edge
2024-04-08 17:38:17 -07:00
Nuno Campos fd6f44a7e4 feat: Return multiple destinations from conditional edge 2024-04-08 17:05:16 -07:00
ce687403d4 Fix single/double quotes in storm.ipynb (#225)
to avoid "unterminated string literal" error when run in Jupyter

Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2024-04-08 13:42:53 -07:00
Ronen AzachiandGitHub deabce5780 added packages to run multi-agent collaboration notebook (#282)
Added packages to be able to run the notebook
2024-04-08 13:41:58 -07:00
William FHandGitHub 2e9e3b0a6c Initial MKDocs (#285) 2024-04-08 13:40:21 -07:00
Lance MartinandGitHub a3c4d4bdd1 Merge pull request #273 from langchain-ai/rlm/claude3-code-gen
Clean code-gen ntbk
2024-04-07 17:21:15 -07:00
Lance Martin fdc34ef3b7 Fmt 2024-04-07 16:00:18 -07:00
Lance Martin 04668df9bc Add Claude3 evals 2024-04-07 15:55:37 -07:00
Lance MartinandGitHub ca1c936d72 Merge pull request #284 from langchain-ai/rlm/adaptive_rag_local
Update local adaptive RAG ntbk
2024-04-06 17:30:06 -07:00
Lance Martin 5f8add89c3 Clean / test 2024-04-06 13:31:48 -07:00
Lance Martin 520443d6cd Clean up code for Claude3 2024-04-06 13:20:39 -07:00
MisraaksandGitHub 217321127f Issue #274: Fix LLMCompiler Bugs (#275)
* Update LLMCompiler.ipynb

The code didn't actually handle when there's more than one dependency listed in an argument. The example of multi-step math used in the code doesn't work because the third step has more than one dependency in its args and the code only handles one:
```
User query: "What's ((3*(4+5)/0.5)+3245) + 8? What's 32/4.23? What's the sum of those two values?"
1. math(problem="((3*(4+5)/0.5)+3245) + 8")
2. math(problem="32/4.23")
3. math(problem="${1}+${2}")
4. join()<END_OFPLAN>
```
Step 3 fails, and does so silently too. It correctly parses strings that are "${1}", but not multi-argument strings like "${1}+${2}"

This fixes it to handle any number of dependencies listed in one arg. It uses the regex pattern already defined in output_parser.py.

* Fix looping function calls because no arg context

Task Fetching Unit, when it inserts the tool_messages, the function args don't get logged with function calls, this causes the replanner to loop and use the same function parameters and never corrects itself.

* Fix tool index count and range

In the planner prompt formatting, the 'num_tools' variable needs to have a +1 added to it because we're appending the join() function, without +1 it says there's one less available tools than there actually is because it only counts the passed in functions and not the join() function. And add +1 for listing otherwise it starts at a 0 offset.

* Fix unhandled empty iterator exception

Task fetching unit: When it calls the tools it doesn't handle when there's no tasks. next() is called and fails. This fixes it by wrapping in a try/except. On exception we set tasks to an empty list since next() failed, there's no tasks.
2024-04-05 10:37:11 -07:00
Nuno CamposandGitHub 70c1c996a4 Merge pull request #279 from langchain-ai/eugene/document_using_nuno_bot
Document Checkpoint
2024-04-04 15:02:48 -07:00
Nuno Campos f21cc3f282 0.0.32 2024-04-04 13:22:08 -07:00
Eugene Yurtsev 21ce575739 x 2024-04-04 15:01:03 -04:00
Eugene Yurtsev 75ce4474e5 x 2024-04-04 14:57:52 -04:00
Lance MartinandGitHub 657bd7d8c3 Merge pull request #271 from langchain-ai/rlm/cohere
Cohere adaptive RAG
2024-04-03 21:44:06 -07:00
Lance Martin c43de8637c Finalize 2024-04-03 21:39:56 -07:00
Lance Martin e779b4335b Finalize ntbk w/ GPT-4 2024-04-03 21:27:50 -07:00
Nuno CamposandGitHub 322763436b Merge pull request #276 from langchain-ai/nc/3apr/node-tracing-output
Ensure node tracing output is exactly what was returned from node
2024-04-03 17:39:04 -07:00
Lance Martin fe87c43375 Update notebook 2024-04-03 15:10:25 -07:00
Nuno Campos db3219f77c Ensure node tracing output is exactly what was returned from node 2024-04-03 13:13:04 -07:00
Lance Martin a984c65b6d Clean ntbk 2024-04-03 11:34:25 -07:00
Lance Martin 1257518789 Cohere adaptive RAG 2024-04-02 21:56:10 -07:00
Nuno CamposandGitHub e30d5f13bf Merge pull request #270 from langchain-ai/nc/2apr/update-rag-notebook
Update adaptive rag notebook to use invoke
2024-04-02 17:25:11 -07:00
Nuno Campos 05009d8068 Update adaptive rag notebook to use invoke 2024-04-02 16:53:56 -07:00
Nuno CamposandGitHub 1961482e2b Merge pull request #269 from langchain-ai/nc/2apr/add-langsmith-urls-time-travel
Add LangSmith run urls in time travel notebook
2024-04-02 16:14:17 -07:00
Nuno Campos f269db4d58 Add LangSmith run urls in time travel notebook 2024-04-02 16:11:48 -07:00
Nuno Campos d00d8913ca 0.0.31 2024-04-02 15:56:33 -07:00
Nuno CamposandGitHub 6fbb58c89f Merge pull request #267 from langchain-ai/nc/2apr/optimize-tracing-output
Optimize tracing output of Graph/StateGraph/MessageGraph
2024-04-02 15:32:24 -07:00
Nuno Campos 617591ad42 Update time travel notebook 2024-04-02 14:51:14 -07:00
Nuno Campos 2f8ae4fdb4 Simplify tool executor 2024-04-02 14:46:14 -07:00
Nuno Campos e3a9760bb2 Improve tracing output of state graph 2024-04-02 12:14:08 -07:00
Nuno Campos 2a299d070e Optimize tracing output of Graph/StateGraph/MessageGraph
- control selection of relevant runs (needs langsmith release)
- see output of conditional edge function
- fix issue with conditional entry point not getting full state values as input
2024-04-02 10:32:47 -07:00
Nuno CamposandGitHub 041ca2f784 Merge pull request #263 from langchain-ai/nc/1apr/rename-channel-invoke
Rename ChannelInvoke to PregelNode
2024-04-01 19:37:12 -07:00
Nuno Campos 8b8171724c Rename ChannelInvoke to PregelNode
- ChannelInvoke is a legacy name from when we had ChannelBatch
2024-04-01 19:34:13 -07:00
Nuno CamposandGitHub 8bdc66a867 Merge pull request #262 from langchain-ai/nc/1apr/message-graph-coerce
MessageGraph now accepts same shorthand message formats as langchain-core
2024-04-01 18:47:10 -07:00
Nuno Campos a184600915 MessageGraph now accepts same shorthand message formats as langchain-core 2024-04-01 18:44:06 -07:00
Nuno CamposandGitHub b1584a3980 Merge pull request #261 from langchain-ai/nc/1apr/test-state-custom-class
Add test and notebook for using pydantic base model as state object
2024-04-01 18:20:05 -07:00
Nuno Campos 694343c5b5 Update test 2024-04-01 18:03:52 -07:00
Nuno Campos cbd2024dec Add async test, add test for validation error 2024-04-01 17:56:18 -07:00
Nuno CamposandGitHub 2d042ed385 Merge pull request #260 from langchain-ai/nc/1apr/test-both-checkpoint-at
Add tests for both values of CheckpointAt
2024-04-01 17:51:38 -07:00
Nuno Campos 961ddd49ed Add test and notebook for using pydantic base model as state object 2024-04-01 17:40:55 -07:00
Nuno Campos f88ef74002 Add tests for both values of CheckpointAt
- fix bug when using at=END_OF_RUN together with interrupt_before
- fix bug when calling update_state after only node has run
- update some notebooks to new streaming format (ie. no __end__ node)
2024-04-01 17:17:39 -07:00
Nuno CamposandGitHub 1276547233 Merge pull request #258 from langchain-ai/nc/1apr/optimize-tracing-tree
Optimize tracing run tree
2024-04-01 16:16:54 -07:00
Nuno CamposandGitHub dec8a53070 Merge pull request #257 from langchain-ai/nc/1apr/add-test-waiting-edge-via-branch
Add test for waiting edge triggered via conditional edge
2024-04-01 16:16:25 -07:00
Nuno CamposandGitHub 1632c045b1 Merge pull request #256 from langchain-ai/nc/1apr/docstrings-multi-edges
Add some more docstrings around multi edges
2024-04-01 16:16:17 -07:00
Nuno CamposandGitHub a95d50c057 Merge pull request #254 from langchain-ai/nc/31mar/shorten-stack-traces
Remove some noisy frames from stack traces
2024-04-01 16:16:07 -07:00
Nuno CamposandGitHub 83b77824f0 Merge pull request #253 from langchain-ai/nc/31mar/rewrite-graph-compile
Rewrite Graph/StateGraph.compile()
2024-04-01 16:15:56 -07:00
Nuno CamposandGitHub 18112b4df8 Merge pull request #252 from langchain-ai/nc/31mar/channel-from-checkpoint-copy
Rename BaseChannel.empty() to BaseChannel.from_checkpoint()
2024-04-01 16:15:41 -07:00
Nuno Campos 008301cf02 Lint 2024-04-01 16:15:30 -07:00
Nuno CamposandGitHub 2d351e8752 Merge pull request #247 from langchain-ai/nc/30mar/state-graph-elim-end-node
Remove __end__ node from state graph
2024-04-01 16:14:49 -07:00
Nuno CamposandGitHub e15ba64e1b Merge pull request #245 from langchain-ai/nc/30mar/stream-mode
Add stream_mode=updates or values
2024-04-01 16:14:20 -07:00
Nuno CamposandGitHub 6de5a6de28 Merge pull request #244 from langchain-ai/nc/30mar/pending-writes-by-channel
Collect pending writes for each node separately
2024-04-01 16:13:32 -07:00
Nuno CamposandGitHub 90e39a6cc8 Merge pull request #243 from langchain-ai/nc/30mar/rm-mutate-in-stream
Remove private api to mutate values during call to stream()
2024-04-01 16:13:11 -07:00
Nuno Campos 2736d72989 Remove __start__ node from stream output 2024-04-01 16:05:12 -07:00
Nuno Campos 3e4c94289a Manage run_manager directly
- allows us to set run output different from streamed values: here the run output should always be final value of all channels
- removes 1-2 more frames from stack traces
2024-04-01 15:08:35 -07:00
Lance MartinandGitHub 379345a39c Merge pull request #259 from langchain-ai/rlm/clean-rag-ntbks
Clean and normalize all langgraph RAG ntbks
2024-04-01 14:59:37 -07:00
Lance Martin 736b307647 Clean, update all ntbks 2024-04-01 14:48:42 -07:00
Nuno Campos b6848c5fdf Optimize tracing run tree
- Do not run node if it's a passthrough
- Do not run writers that wouldn't affect any channels
- Combine consecutive writers when it doesn't change semantics
2024-04-01 13:43:23 -07:00
Lance Martin 3a9387e53f Update, clean, normalize langgraph RAG ntbks 2024-04-01 13:12:21 -07:00
Nuno Campos 3451e04b7d Add test for waiting edge triggered via conditional edge 2024-04-01 12:36:55 -07:00
Nuno Campos 2bf66b8834 Add some more docstrings around multi edges
- prompted by some github issues
2024-04-01 12:29:00 -07:00
William Fu-Hinthorn 2f22bb9f10 commentary 2024-04-01 00:32:55 -07:00
William Fu-Hinthorn 6bfb9ec666 Include classification steps 2024-04-01 00:28:55 -07:00
Nuno Campos 4e373b8af2 Remove noisy frames from stack traces
- The less frames in library code the less confused the user is
- This doesn't remove all library frames (not possible), but it's a start
2024-03-31 20:19:10 -07:00
Nuno Campos 03bef445c6 Lint 2024-03-31 20:16:50 -07:00
Nuno Campos a20bf12da9 Lint 2024-03-31 19:18:47 -07:00
Nuno Campos 02a25d890f Lint 2024-03-31 19:16:20 -07:00
Nuno Campos 7bc95d311c Lint 2024-03-31 19:15:18 -07:00
Nuno Campos 0d2bbe85c6 Fix default condition name 2024-03-31 18:56:38 -07:00
William Fu-Hinthorn ab0b6d3c0d Add img 2024-03-31 18:25:12 -07:00
Nuno Campos b668bf8eab Rewrite Graph/StateGraph.compile()
- Each iteration of the graph is one single iteration in Pregel (ie. no more "{node}:edges" nodes)
- .update_state() now acts exactly as one of the nodes in the graph (which can be chosen), which makes human-in-the-loop scenarios where you want to override the actions of a specific node a lot easier to build
- Graph/StateGraph.compile() now delegate adding nodes/edges/etc to dedicated methods that operate on the Pregel object, which is 90% of the way towards dynamic graphs where nodes and edges can be added during execution
2024-03-31 17:17:18 -07:00
Nuno Campos 4fd90f8ad6 Rename BaseChannel.empty() to BaseChannel.from_checkpoint()
- clearer name
- channels with complex data structures in checkpoint (eg a set or list) now copy the checkpointed data structures before creating the new channel
2024-03-31 09:25:08 -07:00
Nuno Campos 03b7d6fe0d Remove __end__ node from state graph
No longer necessary with stream output modes
2024-03-30 22:04:27 -07:00
William Fu-Hinthorn 62ac195d39 Run TNT-LLM 2024-03-30 21:53:15 -07:00
Nuno Campos 1ad017781d Add stream_mode=updates or values
- stream(stream_mode="values") yields thre current channel values whenever a channel is updated
- stream(stream_mode="updates") yields the update sent to each channel by each node
- this removes the __end__ value present at the end of each call to Graph/StateGraph/MessageGraph.stream(). To access the __end__ value either call .invoke() or stream(stream_mode="values")
2024-03-30 21:24:39 -07:00
Nuno Campos 885e5884c5 Collect pending writes for each node separately
- ensures that order of updates sent to channels is independent of timing differences when parallel executing multiple nodes
- enables future features
2024-03-30 20:02:17 -07:00
Nuno Campos 0baaf5cd96 Remove private api to mutate values during call to stream() 2024-03-30 19:41:50 -07:00
William Fu-Hinthorn f4ef67c5d3 Draft tnt llm 2024-03-30 16:29:27 -07:00
Mohamed A. FouadandGitHub 4182538b0a Update lats.ipynb (#227)
Fixes a typo.
2024-03-29 16:42:24 -07:00
Nuno CamposandGitHub 15908adcd0 Merge pull request #236 from langchain-ai/jacob/async_edges
Adds async conditional edge support
2024-03-28 15:42:34 -07:00
Lance MartinandGitHub 8f2356b590 Merge pull request #237 from langchain-ai/rlm/adaptive-rag
Add adaptive RAG
2024-03-28 12:07:56 -07:00
Lance Martin cb66b31286 Finalize ntbk 2024-03-28 12:03:52 -07:00
Lance Martin cf7f6243d7 Add set_conditional_entry_point 2024-03-26 16:59:24 -07:00
Lance Martin aefea04d31 Add adaptive RAG 2024-03-26 16:33:31 -07:00
Nuno Campos 5aa036639b Update 2024-03-26 15:42:16 -07:00
jacoblee93 e79453633d Simplify 2024-03-26 12:59:26 -07:00
jacoblee93 a6a9def91a Adds async conditional edge support 2024-03-26 12:46:15 -07:00
Nuno Campos 2b42407f05 0.0.30 2024-03-22 08:23:34 -07:00
Nuno CamposandGitHub 458d71e694 Merge pull request #226 from langchain-ai/nc/21mar/add-message-graph-test
Add one more test for message graph
2024-03-21 18:00:00 -07:00
Nuno CamposandGitHub 49d3943ffd Merge pull request #164 from langchain-ai/nc/29feb/waiting-edge
Add StateGraph.add_edge(string[], string)
2024-03-21 17:59:46 -07:00
Nuno Campos 62dfa48ce5 Lint 2024-03-21 17:58:23 -07:00
Nuno Campos db2ec5b2de Rename to add_edge(string[], string) 2024-03-21 17:56:35 -07:00
Nuno Campos e11153cf09 Fix graph repr 2024-03-21 16:53:59 -07:00
Nuno Campos 319d72952c Add one more test for message graph 2024-03-21 16:35:26 -07:00
Nuno Campos ccea395002 Fox 2024-03-21 16:06:23 -07:00
Nuno Campos 01c32c2464 Finish 2024-03-21 15:54:03 -07:00
Nuno Campos 6cb5062c1a Lol 2024-03-21 14:30:51 -07:00
Nuno Campos 158f84c826 WIP Waiting edge 2024-03-21 14:29:40 -07:00
Nuno CamposandGitHub ad5938f53e Merge pull request #224 from langchain-ai/nc/21mar/message-graph-coerce-to-msg
MessageGraph: convert message chunks to messages when added to graph
2024-03-21 14:10:43 -07:00
Nuno Campos 6cdb8925c8 MessageGraph: convert message chunks to messages when added to graph 2024-03-21 13:32:11 -07:00
Nuno CamposandGitHub 98ac7ef71a Merge pull request #221 from langchain-ai/wfh/simplify_readme
Simplify first example
2024-03-20 12:33:27 -07:00
Nuno Campos c8c94df261 0.0.29 2024-03-20 12:14:49 -07:00
Nuno CamposandGitHub 5d10c929b1 Merge pull request #220 from langchain-ai/nc/trach-checkpoint-parent
Track parent relationships for checkpoints
2024-03-20 12:12:20 -07:00
William Fu-Hinthorn a93c4fd186 Simplify first example 2024-03-20 12:11:24 -07:00
Nuno CamposandGitHub 4b9d09d22d Merge pull request #218 from langchain-ai/eyurtsev-patch-1
Update README.md
2024-03-20 12:09:01 -07:00
Nuno Campos 3bfac1f490 Track parent relationships for checkpoints
- This enables building "branching" views of checkpoint history
2024-03-20 12:08:22 -07:00
Eugene YurtsevandGitHub d3f0129d38 Update README.md 2024-03-19 22:16:20 -04:00
Jacob LeeandGitHub 35188d9ed5 Fix typo (#216) 2024-03-19 08:56:02 -07:00
Jacob LeeandGitHub 7dcc05f92f Small README tweaks (#215)
* Small README tweaks

* Update section

* Update
2024-03-19 08:49:06 -07:00
Jacob LeeandGitHub ea9fd7ada0 Fix broken link? (#214)
* Fix broken link?

* Fix
2024-03-18 22:12:29 -07:00
Jacob LeeandGitHub 575684e841 Update quickstart with simpler message graph examples (#213) 2024-03-18 21:34:12 -07:00
William FHandGitHub 00de78e2fd Add Branching Example (#212) 2024-03-18 10:51:35 -07:00
4a5206c93e add notebook for get update state (#180)
* add notebook for get update state

* cr

* Fix bad merge

* Update notebook

* Update

* Fix unbound local bug

* Fix duplicate history entries

* Update notebook with time travel section

* Update notebook

* cr

* cr

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
2024-03-15 14:35:01 -07:00
HowardChanandGitHub fa0f911340 Fix/Typos (#206) 2024-03-15 14:33:53 -07:00
Eugene YurtsevandGitHub 76b6394e7f x (#210) 2024-03-15 14:31:59 -07:00
Nuno CamposandGitHub 07a2815a5d Merge pull request #211 from langchain-ai/nc/15mar/message-graph-update
Support updating/replacing existing messages in messagegraph
2024-03-15 12:15:51 -07:00
Nuno Campos 7548f412fb Support updating existing messages in messagegraph 2024-03-15 12:13:58 -07:00
Nuno Campos ba5dbad75f Fix duplicate history entries 2024-03-15 08:33:35 -07:00
William FHandGitHub da7797431a Merge pull request #207 from langchain-ai/rlm/testing_storm
Minor updates to STORM ntbk
2024-03-14 12:29:30 -07:00
Lance Martin 453bbdc284 Minor updates to STORM ntbk 2024-03-14 10:50:58 -07:00
Nuno CamposandGitHub fa536f8368 Merge pull request #204 from langchain-ai/nc/13mar/get-state-history
Add history tracking to in-memory, sqlite and aiosqlite checkpointers
2024-03-13 17:46:06 -07:00
Nuno Campos d169db951a py3.9 2024-03-13 17:42:14 -07:00
Nuno Campos 53297db419 py3.9 2024-03-13 17:37:55 -07:00
Nuno Campos 4d9e8a2d5f Update error msg 2024-03-13 17:34:13 -07:00
Nuno Campos 0d13c6b159 Add history tracking to in-memory, sqlite and aiosqlite checkpointers
- Add Pregel.get_state_history and .aget_state_history methods to get history iterator
- Update checkpointer base class with new list and get_tuple methods
- Rewrite in-memory checkpointer class to track history
- Rewrite sqlite and aiosqlite checkpointers to track history
- Add new tests for history tracking
2024-03-13 17:22:39 -07:00
Nuno Campos 418267e4de 0.0.28 2024-03-13 11:39:29 -07:00
Nuno Campos c964b662b4 0.0.27 2024-03-13 11:39:10 -07:00
Nuno CamposandGitHub a4374a069b Merge pull request #202 from langchain-ai/nc/13mar/rm-subcribe-to-each
Remove subscribe_to_each() method in pregel api
2024-03-13 11:36:53 -07:00
Nuno Campos f5c3c7ac7d Remove subscribe_to_each() method in pregel api
- can be replaced by piping to batch method instead
2024-03-13 11:17:49 -07:00
Nuno CamposandGitHub 8b764f0a99 Merge pull request #200 from langchain-ai/nc/12mar/fix-human-in-loop-nb
Fix human in the loop notebook
2024-03-12 11:13:01 -07:00
Nuno Campos c90a6b14b9 Fix human in the loop notebook 2024-03-12 10:40:47 -07:00
William FHandGitHub b5b1c33ee6 Merge pull request #194 from langchain-ai/wfh/subgraph
Subgraph example
2024-03-07 19:12:38 -08:00
William FHandGitHub b3d64a4678 Merge pull request #155 from langchain-ai/wfh/typed
Make typed
2024-03-07 18:43:14 -08:00
William Fu-Hinthorn 5b7fa17955 Subgraph example 2024-03-07 17:58:23 -08:00
Harrison ChaseandGitHub 9be4cdd337 Update README.md 2024-03-07 09:27:45 -08:00
Harrison ChaseandGitHub 0b79646dbd Update README.md 2024-03-07 09:27:00 -08:00
Harrison ChaseandGitHub d0e974ce8b viz notebook (#182)
* cr

* cr
2024-03-07 09:19:26 -08:00
Nuno CamposandGitHub 069ff067a5 Merge pull request #193 from langchain-ai/wfh/aexec_tool_support
Add tools upport to agentexecutor
2024-03-07 09:01:39 -08:00
William Fu-Hinthorn 16970aca08 Add tools upport to agentexecutor 2024-03-07 08:51:05 -08:00
William FHandGitHub 4569be0e02 Add cloneable link in langgraph code assistant notebook
Add cloneable link in langgraph code assistant notebook
2024-03-06 17:34:03 -08:00
William Fu-Hinthorn 54e367a628 format 2024-03-06 17:33:07 -08:00
William Fu-Hinthorn 7e4abdf08a clear long outputs 2024-03-06 17:32:10 -08:00
William Fu-Hinthorn afca1e3e48 Add link for langgraph code assistnat 2024-03-06 17:30:58 -08:00
William FHandGitHub 9661514155 Add LangSmith chatbot evaluation example
Evaluation Simulation Benchmark
2024-03-06 17:10:55 -08:00
William Fu-Hinthorn 915bd9db16 fixup 2024-03-06 17:10:37 -08:00
William Fu-Hinthorn 073784b5e3 r 2024-03-06 17:08:20 -08:00
William Fu-Hinthorn c617e504d1 checkup 2024-03-06 17:06:38 -08:00
William Fu-Hinthorn 199af2c5b4 fixup 2024-03-06 16:59:34 -08:00
William Fu-Hinthorn 190337bd84 readme 2024-03-06 15:07:46 -08:00
William Fu-Hinthorn f9ae2e651f gs 2024-03-06 15:07:40 -08:00
William Fu-Hinthorn 918e795961 update notebook 2024-03-06 15:03:57 -08:00
William Fu-Hinthorn c08a9329aa Add notebook 2024-03-06 14:13:11 -08:00
William Fu-Hinthorn fc48546ebd examples 2024-03-06 13:07:33 -08:00
William Fu-Hinthorn ab032fec2f tmp 2024-03-06 12:33:06 -08:00
William FHandGitHub df66e37741 Merge pull request #185 from langchain-ai/wfh/license
Update pyproject license
2024-03-05 14:10:49 -08:00
William Fu-Hinthorn 83145ec2b0 MIT 2024-03-05 13:56:14 -08:00
Nuno CamposandGitHub 7cb61525bc Merge pull request #181 from langchain-ai/harrison/update-docs
update readme
2024-03-04 19:51:06 -08:00
Harrison Chase 1962800901 update readme 2024-03-04 19:47:54 -08:00
William FHandGitHub e68181dc01 Merge pull request #178 from langchain-ai/wfh/recurse
UCT on full nodes
2024-03-03 17:53:59 -08:00
William FHandGitHub 837a038ed2 Merge branch 'main' into wfh/recurse 2024-03-03 17:53:51 -08:00
William Fu-Hinthorn 699d89b3d9 noself 2024-03-03 17:52:12 -08:00
William Fu-Hinthorn 33d36c37b4 Recurse 2024-03-03 17:41:10 -08:00
William FHandGitHub 001fd058f3 Merge pull request #169 from kikoncuo/patch-1
Fixed rewoo.ipynb
2024-03-03 17:34:09 -08:00
Kenneth Gerald HamiltonandGitHub 013c80f0ee fix minor syntox issues (#157) 2024-03-03 15:56:34 -08:00
53d66a8a04 [bug] : Fix the score printing… (#174)
* bug[examples/rag/langgraph_agentic_rag.ipynb]: Fix the score printing when grader scores "no" and changing "msg" in rewrite node to list

* Update examples/rag/langgraph_agentic_rag.ipynb

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
2024-03-03 15:56:21 -08:00
Harrison ChaseandGitHub 0f605c6da4 Merge pull request #177 from langchain-ai/harrison/chain-of-table
add chain of table link
2024-03-03 15:50:23 -08:00
Harrison Chase aa2448b7ec add chain of table link 2024-03-03 15:41:04 -08:00
Nuno CamposandGitHub 8ad0c71cbe Merge pull request #165 from langchain-ai/nc/29feb/graph-xray
Implement xray mode for graph draw
2024-03-01 07:51:13 -08:00
Enrique Alcázar GarzásandGitHub cca9481692 Fixed rewoo.ipynb 2024-03-01 12:38:07 +01:00
William FHandGitHub 181433be7e Cleanup Link Check 2024-03-01 01:16:47 -08:00
William Fu-Hinthorn f546886447 x 2024-03-01 01:14:56 -08:00
William Fu-Hinthorn 3603f3e98c pip 2024-03-01 01:11:24 -08:00
William Fu-Hinthorn d5a22135ab link 2024-03-01 01:09:45 -08:00
William Fu-Hinthorn 80869554da uses 2024-03-01 01:05:50 -08:00
William FHandGitHub 60fe3954dd Merge pull request #167 from langchain-ai/wfh/storm_readme
Add STORM to readme
2024-03-01 00:47:57 -08:00
William Fu-Hinthorn d65375517a Add readme link 2024-03-01 00:47:17 -08:00
William FHandGitHub a77a1e764e STORM 2024-03-01 00:40:08 -08:00
William Fu-Hinthorn 048deb64b5 fixup 2024-03-01 00:38:05 -08:00
William Fu-Hinthorn afbe9360bb Add img 2024-03-01 00:34:51 -08:00
Nuno Campos a33acb6d8a Implement xray mode for graph draw 2024-02-29 19:07:58 -08:00
Nuno CamposandGitHub 19b8dbcc26 Merge pull request #163 from langchain-ai/nc/29feb/draw-cond-edge-end
Draw end edge for cond edge without mapping
2024-02-29 19:06:29 -08:00
Nuno Campos 359340dbc8 One more 2024-02-29 19:03:42 -08:00
Nuno Campos 971e15873e Fix core version mismatch in snapshot tests 2024-02-29 19:01:44 -08:00
William Fu-Hinthorn 2bd5e3606e render 2024-02-29 18:53:48 -08:00
Nuno Campos d75792f6e8 Fix 2024-02-29 18:48:21 -08:00
Nuno Campos 2a624274fd Draw end edge for cond edge without mapping 2024-02-29 18:26:28 -08:00
William Fu-Hinthorn 7644d09f21 Fixup language 2024-02-29 17:41:07 -08:00
William Fu-Hinthorn b721aad3e4 Update notebook 2024-02-29 17:06:58 -08:00
William Fu-Hinthorn 24954c24e0 Storm Draft 2024-02-29 16:28:40 -08:00
William Fu-Hinthorn e2070527d1 Make typed 2024-02-26 18:19:33 -08:00
Harrison ChaseandGitHub 13f08e9bff Merge pull request #87 from langchain-ai/harrsion/chatbots
Harrsion/chatbots
2024-02-26 11:34:50 -08:00
Harrison Chase 2d23fe6d9b cr 2024-02-26 11:32:55 -08:00
Nuno CamposandGitHub dcc39ca338 Merge pull request #154 from langchain-ai/nc/26feb/cached-create-model
Use faster/cached create_model in get_input_schema/get_output_schema
2024-02-26 10:14:03 -08:00
Nuno Campos c70376d0b7 Use faster/cached create_model in get_input_schema/get_output_schema 2024-02-26 10:10:52 -08:00
Nuno CamposandGitHub 45ec26dbe4 Merge pull request #153 from langchain-ai/nc/26feb/add-high-level-tools-nb
Add notebook showcasing create_tool_calling_executor
2024-02-26 09:01:28 -08:00
Nuno Campos dd19836be5 Add notebook showcasing create_tool_calling_executor 2024-02-26 08:25:04 -08:00
Nuno CamposandGitHub f716bbd1d1 Merge pull request #128 from langchain-ai/nc/20feb/state-api
Add get_state() and update_state() methods to get and update checkpoint in between runs, Add debug arg to Graph/StateGraph
2024-02-25 08:48:45 -08:00
Nuno Campos 515a512f7e Expose additional kwargs 2024-02-24 19:56:00 -08:00
Nuno Campos 28aee50a9f Lint 2024-02-24 19:52:43 -08:00
Nuno Campos 60097c5f1d Remove class 2024-02-24 19:47:06 -08:00
Nuno Campos 27cf03a444 Lint 2024-02-24 19:46:29 -08:00
Nuno Campos 5c2afc9418 Fix behaviour of interrupt_before
- checkpoints are now copied before being mutated
- compiled graph and compiled state graph no longer need to override get_state/update_state
- pregel class now natively supports interrupt before/after
2024-02-24 19:43:30 -08:00
Nuno Campos 82c704e57e Lint 2024-02-24 17:00:45 -08:00
Nuno CamposandNuno Campos 38cd934f38 Lint 2024-02-24 16:58:18 -08:00
Nuno CamposandNuno Campos fdb273b0f4 Add get_state() and update_state() methods to get and update checkpoint in between runs 2024-02-24 16:58:18 -08:00
Nuno CamposandGitHub 0a293d5b9e Merge pull request #147 from langchain-ai/nc/24feb/optimize-run-tree
Remove unnecessary runs from StateGraph/MessageGraph run tree
2024-02-24 16:55:57 -08:00
Nuno Campos d90478b50c Remove unnecessary runs from StateGraph/MessageGraph run tree 2024-02-24 16:53:09 -08:00
Lance MartinandGitHub 59908e6999 Merge pull request #146 from langchain-ai/rlm/scrub
Remove version used in video
2024-02-23 17:13:56 -08:00
Lance Martin 7c64f82425 Remove version used in video 2024-02-23 16:37:35 -08:00
Lance MartinandGitHub e312092366 Merge pull request #145 from langchain-ai/rlm/minor_cleanups
Minor cleanups on code-assistant and RAG examples
2024-02-23 16:35:54 -08:00
Lance Martin a0e4fea4ea Cleanup 2024-02-23 16:32:14 -08:00
Nuno Campos c4a77c4313 0.0.26 2024-02-22 15:24:26 -08:00
Nuno CamposandGitHub 0d2b4fe188 Merge pull request #139 from langchain-ai/nc/22feb/add-conditional-entry-point
Add support for conditional entry points in Graph, StateGraph, MessageGraph
2024-02-22 15:23:01 -08:00
Nuno Campos debd9a8d9c Add support for conditional entry points in Graph, StateGraph, MessageGraph 2024-02-22 15:19:03 -08:00
Lance MartinandGitHub 4f979d69bf Merge pull request #132 from langchain-ai/rlm/lcel-teacher
Add LCEL teacher cookbook
2024-02-22 14:31:28 -08:00
Lance Martin b013fa1082 Finalize metrics 2024-02-22 14:12:30 -08:00
Lance Martin 8feb891ed7 Add eval 2024-02-22 11:59:53 -08:00
Nuno Campos 1c252830bf 0.0.25 2024-02-22 08:40:06 -08:00
Lance Martin 2fd4926061 Add evals 2024-02-21 14:27:54 -08:00
William FHandGitHub 82bad94b8e Merge pull request #133 from langchain-ai/wfh/nits
Spelling
2024-02-21 09:33:18 -08:00
Lance Martin a902b3c19b Log each output key 2024-02-20 20:32:34 -08:00
William Fu-Hinthorn b768deb701 Spelling 2024-02-20 20:11:27 -08:00
Lance Martin a33bfdac2b Add LCEL teacher 2024-02-20 19:02:26 -08:00
William FHandGitHub ab5c2de786 Add LATS image
Add lats image
2024-02-20 17:55:11 -08:00
William FHandGitHub 6c06471524 Merge pull request #130 from langchain-ai/wfh/simple_reflection
Add Simple Reflection
2024-02-20 17:49:06 -08:00
William Fu-Hinthorn 18f4602900 Add lats image 2024-02-20 17:48:20 -08:00
Nuno CamposandGitHub c8411df833 Merge pull request #123 from langchain-ai/nc/19feb/get-graph
Implement get_input_schema(), get_output_schema(), get_graph() for StateGraph, MessageGraph
2024-02-20 17:20:26 -08:00
William Fu-Hinthorn 909cb3e3ad Reflection readme 2024-02-20 17:19:47 -08:00
Nuno Campos 7ca7c220be Update langchain-core 2024-02-20 17:18:45 -08:00
William Fu-Hinthorn 371b284447 Simple reflection 2024-02-20 17:17:42 -08:00
William FHandGitHub 1149690bac Merge pull request #129 from langchain-ai/wfh/lats
Wfh/lats
2024-02-20 15:51:28 -08:00
William Fu-Hinthorn 7e9620500c Update readme 2024-02-20 15:44:44 -08:00
William Fu-Hinthorn bebea9f1f7 still complicated 2024-02-20 15:42:06 -08:00
Nuno Campos c3cbececcf Update snapshots 2024-02-20 09:51:33 -08:00
Nuno Campos 69c570f3d0 Remove print 2024-02-20 08:55:57 -08:00
William Fu-Hinthorn 8b8e3e7638 Complicated version 2024-02-20 08:34:08 -08:00
William Fu-Hinthorn 9027246db3 update 2024-02-19 21:12:27 -08:00
William Fu-Hinthorn 2c208e3c50 tmp 2024-02-19 21:08:45 -08:00
Lance MartinandGitHub 40957c3fa0 Merge pull request #126 from langchain-ai/rlm/add_nomic_v1and1.5
Add Nomic v1, v1.5 to both local notebooks
2024-02-19 19:59:56 -08:00
Lance Martin 9de5b27996 Add Nomic v1, v1.5 2024-02-19 19:47:39 -08:00
Nuno Campos b27531e962 Lint 2024-02-19 13:19:49 -08:00
Nuno Campos 4f1980df7c Add missing input and output types for state graph 2024-02-19 13:14:24 -08:00
Nuno Campos 27464c0f46 Implement input_schema, output_schema, get_graph for Graph, StateGraph, MessageGraph 2024-02-19 13:07:34 -08:00
Nuno CamposandGitHub 50b1a455bd Merge pull request #41 from langchain-ai/nc/fan-out
StateGraph/MessageGraph: Add support for multiple incoming edges
2024-02-19 13:06:14 -08:00
William FHandGitHub b091c40165 Merge pull request #122 from langchain-ai/wfh/linkcheck
Linkcheck
2024-02-19 12:07:49 -08:00
William Fu-Hinthorn 39db6375a6 cleanup 2024-02-19 12:01:28 -08:00
William Fu-Hinthorn 602b8960be v4 2024-02-19 11:53:17 -08:00
William Fu-Hinthorn d34e9aca91 Add linkcheck 2024-02-19 11:49:30 -08:00
William FHandGitHub f3c940d22b Merge pull request #114 from langchain-ai/wfh/reflexion
Reflexion
2024-02-19 11:47:35 -08:00
William FHandGitHub ff4f99e2fe Merge branch 'main' into wfh/reflexion 2024-02-19 11:45:12 -08:00
William Fu-Hinthorn 13b5e578cf Update readme 2024-02-19 11:44:40 -08:00
William Fu-Hinthorn de255d2c57 add img 2024-02-19 11:39:43 -08:00
William Fu-Hinthorn 3c466a5bb6 Add reflexion 2024-02-19 11:39:24 -08:00
Nuno CamposandGitHub 5358d0ab49 Merge pull request #109 from MidasKylix/tool_call
Add prebuilt "tool calling executor"
2024-02-19 09:22:25 -08:00
Nuno Campos cadb852086 Undo change to readme 2024-02-19 09:20:39 -08:00
Nuno Campos e4bfa8603d Support multiple tool calls, Lint 2024-02-19 09:12:08 -08:00
Nuno CamposandGitHub 016d6a8dee Merge pull request #117 from Repkit/patch-1
fix base.ipynb to install langchainhub
2024-02-19 08:43:01 -08:00
Nuno CamposandGitHub de5cea49e5 Merge pull request #120 from kajarenc/patch-1
Typo fix
2024-02-19 08:42:36 -08:00
William Fu-Hinthorn 8fd64b6768 add gitignore 2024-02-19 08:41:18 -08:00
Nuno CamposandGitHub 957d21d8cf Merge pull request #116 from langchain-ai/eugene/add_version
Add __version__ to langgraph
2024-02-19 08:39:55 -08:00
Nuno CamposandGitHub c444ef0a2c Update base.ipynb 2024-02-19 08:39:21 -08:00
William FHandGitHub 2b6981ae18 Merge branch 'main' into wfh/reflexion 2024-02-19 08:22:11 -08:00
Karen JavadyanandGitHub a21380dd26 fix typo 2024-02-18 22:40:15 +04:00
midas8181919 6905242665 Merge branch 'main' into tool_call 2024-02-16 22:50:57 +00:00
RepkitandIonut-Andrei Baches ea26b42a7d fix base.ipynb to install langchainhub
this is requiered to load the prompt from hub
2024-02-16 22:28:15 +02:00
Lance MartinandGitHub 15ac624e62 Merge pull request #112 from langchain-ai/rlm/self_rag_local
Local self-RAG
2024-02-16 11:25:08 -08:00
Lance MartinandGitHub 66cf58ae7b Merge pull request #110 from langchain-ai/rlm/agentic_rag_update
Update Agentic RAG example
2024-02-16 08:56:04 -08:00
Eugene Yurtsev c0e075c081 x 2024-02-16 11:54:57 -05:00
William Fu-Hinthorn 41f93b9981 Reflexion 2024-02-16 08:41:16 -08:00
William FHandGitHub be5f83f808 Merge pull request #113 from langchain-ai/wfh/black_format
Format
2024-02-15 23:13:10 -08:00
William Fu-Hinthorn e9a7ad8b69 Format 2024-02-15 23:09:59 -08:00
Lance Martin 1253c9d05b Local self-RAG 2024-02-15 16:05:23 -08:00
Lance Martin 8b10dc7f3b Update agentic RAG 2024-02-14 16:23:35 -08:00
Lance Martin 3c5a21228c Update agentic RAG example 2024-02-14 15:26:17 -08:00
midas8181919 52df544dac fix 2024-02-13 22:58:38 +00:00
midas8181919 794cc71254 fixed 2024-02-13 22:42:37 +00:00
midas8181919 82ea95c3c0 Merge branch 'main' into tool_call 2024-02-13 22:35:09 +00:00
Lance MartinandGitHub c3942874eb Merge pull request #108 from langchain-ai/rlm/update_parser
Minor parser modifications in CRAG example
2024-02-13 11:37:55 -08:00
Lance Martin f399bb7512 Minor parser modifications in CRAG example 2024-02-13 11:35:12 -08:00
midas8181919 41ff4c8c43 fix some errors 2024-02-13 15:41:27 +00:00
William FHandGitHub f61dd21305 Merge pull request #107 from langchain-ai/wfh/rewoo_formatting
Formatting
2024-02-12 15:23:59 -08:00
William Fu-Hinthorn 3226278e22 conclusion 2024-02-12 15:18:48 -08:00
William Fu-Hinthorn 8823b78dc1 format 2024-02-12 15:15:37 -08:00
William Fu-Hinthorn 3ba3fdd855 Update plan-and-execute 2024-02-12 15:12:28 -08:00
William Fu-Hinthorn 925d015335 Update llmcompiler 2024-02-12 15:05:45 -08:00
William FHandGitHub f8e81831f0 Merge pull request #106 from langchain-ai/harrison/rewoo
Add ReWOO
2024-02-12 15:00:09 -08:00
William Fu-Hinthorn 2753768805 cite 2024-02-12 14:56:48 -08:00
William Fu-Hinthorn 92329b3ae8 reword 2024-02-12 14:55:30 -08:00
William Fu-Hinthorn 1307ce9cc7 Update readme 2024-02-12 14:53:41 -08:00
William Fu-Hinthorn ac131cc954 Add llmcompiler 2024-02-12 14:41:56 -08:00
William Fu-Hinthorn b208ccded0 Update conclusion 2024-02-12 14:40:16 -08:00
William Fu-Hinthorn 2f110d181b Add images + narration 2024-02-12 14:33:34 -08:00
William Fu-Hinthorn 0fc6c813f2 Merge branch 'main' into harrison/rewoo 2024-02-12 14:31:27 -08:00
Harrison Chase 899a76f82b add rewoo 2024-02-12 12:46:06 -08:00
Nuno Campos 0cc6ce3b50 Lint 2024-02-12 10:01:24 -08:00
Harrison ChaseandGitHub 6845bb926e Merge pull request #105 from langchain-ai/harrison/self-discover
add self discover notebook
2024-02-12 09:40:57 -08:00
Harrison Chase e97cd22a18 add self discover notebook 2024-02-11 21:14:07 -08:00
Lance MartinandGitHub 727be58c98 Merge pull request #97 from langchain-ai/rlm/crag_local_update
Updates to support running locally
2024-02-10 18:55:32 -08:00
midas8181919 7cdae56e7e test it 2024-02-11 02:19:29 +00:00
midas8181919 b4269f6453 finish test 2024-02-11 02:04:09 +00:00
midas8181919 88d4140174 Merge branch 'main' into tool_call 2024-02-10 23:25:32 +00:00
midas8181919 acaa4567e1 fix test 2024-02-10 23:25:17 +00:00
midas8181919 38ef3d5218 replace function_call with tool_call 2024-02-10 23:10:32 +00:00
Nuno CamposandGitHub 9657bbc38f Merge pull request #103 from langchain-ai/nc/10feb/warn-mutate-after-compile
Warn if graph is mutated after being compiled
2024-02-10 14:16:41 -08:00
Nuno Campos 29edaaead8 Warn if graph is mutated after being compiled 2024-02-10 13:39:46 -08:00
Nuno Campos 2535795f93 Comment 2024-02-10 13:17:26 -08:00
Nuno Campos 692d1ebe02 WIP 2024-02-10 12:02:50 -08:00
Nuno Campos 979b735256 Allow fan-in in stategraph 2024-02-10 12:01:52 -08:00
Nuno CamposandGitHub 634aee884c Merge pull request #102 from langchain-ai/nc/10feb/interrupt-after
Add interrupt_after arg to .compile()
2024-02-10 11:58:04 -08:00
Nuno Campos f1523f3e8d Add interrupt_after arg to .compile() 2024-02-10 11:39:38 -08:00
William FHandGitHub 107e96d245 Merge pull request #36 from langchain-ai/wfh/llm_compiler
LLMCompiler
2024-02-09 16:14:54 -08:00
William Fu-Hinthorn a319cbf521 rm file 2024-02-09 16:08:18 -08:00
William Fu-Hinthorn 61a854aabc format 2024-02-09 16:07:23 -08:00
William Fu-Hinthorn 13fb3dfa8b Merge remote-tracking branch 'origin/main' into wfh/llm_compiler 2024-02-09 16:07:01 -08:00
William FHandGitHub dfca91c775 Merge pull request #98 from langchain-ai/harrison/plan-and-execute
add plan-and-execute example
2024-02-09 16:06:37 -08:00
William Fu-Hinthorn c26a8675c3 rename 2024-02-09 16:05:51 -08:00
William Fu-Hinthorn ed3bf3c5ec del 2024-02-09 16:04:36 -08:00
William Fu-Hinthorn c7f3ecb9d9 Add LLM Compiler 2024-02-09 16:04:05 -08:00
Harrison Chase ce5144fccd add plan-and-execute example 2024-02-09 12:29:04 -08:00
Lance Martin bdd8a084cc Updates to support running locally 2024-02-08 14:42:13 -08:00
Nuno Campos c529016346 0.0.24 2024-02-08 10:30:05 -08:00
Nuno CamposandGitHub 27207e7105 Merge pull request #92 from langchain-ai/nc/7feb/hintl
Add human in the loop notebook
2024-02-08 08:44:58 -08:00
Harrison Chase 1af7615ff9 cr 2024-02-07 22:22:43 -08:00
Harrison ChaseandGitHub eb0bea2639 Merge pull request #88 from ldorigo/patch-1
Fix typing for _dict_getter
2024-02-07 22:09:02 -08:00
Harrison Chase f808aa2967 cr 2024-02-07 22:08:16 -08:00
William Fu-Hinthorn fc83419fe2 Merge branch 'main' into wfh/llm_compiler 2024-02-07 20:59:20 -08:00
Nuno Campos 37bad4e30a Add human in the loop notebook 2024-02-07 20:05:05 -08:00
Nuno CamposandGitHub 5612ded481 Merge pull request #91 from langchain-ai/nc/7feb/aiosqlite
Add AsyncSqliteSaver
2024-02-07 20:04:55 -08:00
Nuno Campos c4f87cdccd Close the connection 2024-02-07 20:02:36 -08:00
Nuno Campos f2c2f88413 Lock 2024-02-07 19:53:19 -08:00
Nuno Campos eafb70b9ab Move aiosqlite to test deps 2024-02-07 19:51:25 -08:00
Nuno Campos 387eb0cedd Lint 2024-02-07 19:50:28 -08:00
Nuno Campos 736649df66 Run failed tests first 2024-02-07 19:49:52 -08:00
Nuno Campos b0f0d6f3f7 Fix errors being swallowed 2024-02-07 19:49:35 -08:00
Nuno Campos f2ad930cd4 Add AsyncSqliteSaver 2024-02-07 19:31:24 -08:00
Lance MartinandGitHub 13c94af88a Merge pull request #90 from langchain-ai/rlm/crag_mistral
Add Mistral CRAG, update formatting / documentation
2024-02-07 16:49:16 -08:00
Lance Martin 09343a4013 Minor updates 2024-02-07 16:47:32 -08:00
Lance Martin addc79d29d Clean up docstrings 2024-02-07 16:07:33 -08:00
Lance Martin 385ec91b0e Mistral CRAG 2024-02-07 14:45:17 -08:00
Luca DorigoandGitHub e4a1bf2376 Fix typing for _dict_getter 2024-02-07 13:15:31 +01:00
Lance MartinandGitHub 03c30f4aa9 Merge pull request #85 from langchain-ai/rlm/agentic_rag
Add RAG examples
2024-02-06 16:55:42 -08:00
Harrison Chase b0b792f114 cr 2024-02-06 11:30:31 -08:00
Harrison Chase b64f34e85f add chatbot example 2024-02-06 09:57:00 -08:00
Eugene YurtsevandGitHub 19144ff291 README.md: Add absolute link to langgraph repo
This helps make sure that there's a clickable link from the langgraph page from langchain main python docs
2024-02-06 09:50:00 -05:00
William FHandGitHub 2db53da5f9 Merge pull request #86 from langchain-ai/wfh/update_annotation_script
Wfh/update annotation script
2024-02-06 06:43:28 -08:00
William Fu-Hinthorn 14bdfa3086 rerun 2024-02-06 06:40:35 -08:00
William Fu-Hinthorn 38eb16f131 Update notebook 2024-02-06 06:35:27 -08:00
William Fu-Hinthorn 200403f8ed Update annotation script 2024-02-06 06:18:31 -08:00
William FHandGitHub 84ac02d1f0 Merge pull request #77 from langchain-ai/wfh/web-voyager
Web Voyager
2024-02-05 16:39:43 -08:00
Harrison ChaseandGitHub 98f6b59a56 Merge pull request #84 from langchain-ai/harrison/persistence-in-readme
add persistence to readme
2024-02-05 09:44:15 -08:00
Lance Martin 05e8c7e369 Add RAG examples 2024-02-05 08:59:34 -08:00
Harrison Chase 66845a8d74 add persistence to readme 2024-02-05 08:57:29 -08:00
Nuno CamposandGitHub 5f6499678d Merge pull request #83 from langchain-ai/erick/readme-improvements
readme improvements
2024-02-05 08:57:14 -08:00
Erick Friis 847a00e1a5 readme improvements 2024-02-04 21:09:49 -08:00
Harrison ChaseandGitHub 62b49931d7 Merge pull request #82 from langchain-ai/harrison/add-persistence-nb
add more examples
2024-02-04 14:32:17 -08:00
Harrison Chase 4216b6b661 cr 2024-02-04 14:31:54 -08:00
Nuno Campos 58d421dc7d 0.0.23 2024-02-04 14:15:33 -08:00
Nuno CamposandGitHub 4f55d1cb62 Merge pull request #81 from langchain-ai/nc/resume-or-restart
Only execute tasks leftover from previous checkpoint when resuming with no new input
2024-02-04 14:15:02 -08:00
Nuno Campos afa9592f6a Only execute tasks leftover from previous checkpoint when resuming with no new input 2024-02-04 14:12:10 -08:00
Nuno Campos c7bfe63468 0.0.22 2024-02-04 13:25:55 -08:00
Nuno CamposandGitHub 297e485282 Merge pull request #80 from langchain-ai/harrison/add-persistence-nb
persistence
2024-02-04 12:37:39 -08:00
Harrison Chase 944263285b persistence 2024-02-04 12:35:45 -08:00
William Fu-Hinthorn f8497405fd Update 2024-02-02 18:56:22 -08:00
William Fu-Hinthorn 3b64ed576b Update notebook 2024-02-02 16:07:20 -08:00
Nuno CamposandGitHub 0a2604379d Merge pull request #79 from langchain-ai/nc/1feb/sqlite
Add SqliteSaver
2024-02-01 18:13:08 -08:00
Nuno Campos 083178d2a6 Add SqliteSaver 2024-02-01 18:12:52 -08:00
William Fu-Hinthorn 00a976ebb6 lint 2024-02-01 08:25:09 -08:00
William Fu-Hinthorn e87fb145fa Merge branch 'main' into wfh/web-voyager 2024-02-01 07:40:57 -08:00
William Fu-Hinthorn 5cbad73b90 Add Web Voyager 2024-02-01 07:40:53 -08:00
Nuno CamposandGitHub bbc8fb9d7c Merge pull request #76 from langchain-ai/erick/readme-link
chore: readme link
2024-01-31 17:01:30 -08:00
Erick Friis f24b7a4080 one more 2024-01-31 16:52:47 -08:00
Erick Friis c5dc3cd633 readme link 2024-01-31 16:50:54 -08:00
Nuno Campos 1f8a51595e 0.0.21 2024-01-31 10:10:22 -08:00
Nuno CamposandGitHub 948c7fe75b Merge pull request #75 from langchain-ai/nc/31jan/rm-double-channelwrite
Remove double channelwrite
2024-01-31 10:08:40 -08:00
Nuno Campos f9c893c739 Remove double channelwrite
- this removes one unnamed run from langsmith trace for each node, and ensures that output is streamed from each node to folks listening to that w stream_events
2024-01-31 10:04:41 -08:00
Harrison ChaseandGitHub 28b1587ffd Merge pull request #62 from langchain-ai/bagatur/optional_conditional_edge_mapping
patch: make conditional_edge_mapping optional
2024-01-30 17:21:38 -08:00
Harrison ChaseandGitHub b8e2fa4861 Merge pull request #72 from al1p/example_fix
Fix missing imports in the multi-agent-collaboration example
2024-01-30 17:20:24 -08:00
Nuno CamposandGitHub 9b2b7d325e Merge pull request #73 from langchain-ai/nc/update-deps
Update deps
2024-01-30 15:48:15 -08:00
Nuno Campos 0ca19a2ed4 Update deps 2024-01-30 15:44:41 -08:00
Harrison ChaseandGitHub 5bb7cadcb6 Merge pull request #65 from rudiheydra/fix-input-function
Update human-in-the-loop notebook with input function fix
2024-01-30 15:17:23 -08:00
Al1 2dd730b75d Fix missing imports in the multi-agent-collaboration example 2024-01-29 11:10:17 +02:00
BagaturandGitHub 9e59039232 infra: add ci 2024-01-27 14:05:16 -08:00
Bagatur 303e75c314 rm py3.8 2024-01-27 14:02:28 -08:00
Bagatur aed2844c20 fmt 2024-01-27 13:38:40 -08:00
Bagatur ac179f15cb test dep 2024-01-27 13:34:18 -08:00
Bagatur 21bcf33bc2 fix 2024-01-27 13:08:41 -08:00
Bagatur ad88ebf295 fix 2024-01-27 12:59:32 -08:00
Bagatur 9119dc18ef fix 2024-01-27 12:53:17 -08:00
Bagatur 85623274d1 infra: add ci 2024-01-27 12:49:55 -08:00
Bagatur 40e4b10689 fmt 2024-01-26 18:47:54 -08:00
Bagatur d99debe61c Merge branch 'main' into bagatur/optional_conditional_edge_mapping 2024-01-26 18:40:53 -08:00
Nuno CamposandGitHub 4969f7f62a Merge pull request #68 from langchain-ai/nc/26jan/cleanup-interrupt
On stream interrupt cleanup any (potentially) pending tasks
2024-01-26 18:37:58 -08:00
Nuno Campos 6f49703701 On stream interrupt cleanup any (potentially) pending tasks 2024-01-26 18:37:31 -08:00
Rudi Heydra 64140b42fc Update human-in-the-loop notebook with input function fix 2024-01-25 21:03:54 +11:00
Harrison ChaseandGitHub 18b4bdbf38 Merge pull request #63 from langchain-ai/harrison/notebook-for-streaming
update notebook for streaming
2024-01-24 08:22:47 -08:00
Harrison Chase fce68ce96c update notebook for streaming 2024-01-23 16:44:12 -08:00
Bagatur 9cbc67fecc undo 2024-01-23 16:38:26 -08:00
Bagatur 936b2637ce fmt 2024-01-23 16:38:11 -08:00
Nuno Campos d203e4ca15 0.0.19 2024-01-23 16:22:57 -08:00
Bagatur 333ad65cac patch: make conditional_edge_mapping optional 2024-01-23 13:29:23 -08:00
Nuno CamposandGitHub ec6c8bccc7 Merge pull request #61 from langchain-ai/bagatur/node_channel_collision_error
patch: Clarify node<>channel name collision error
2024-01-23 12:10:03 -08:00
Bagatur d5dc5239c1 patch: Clarify node<>channel name collision error 2024-01-23 12:04:36 -08:00
Nuno CamposandGitHub 10ee6f27ab Merge pull request #60 from langchain-ai/bagatur/tool_exec_config
patch: add config to ToolExecutor._execute
2024-01-23 11:48:09 -08:00
Bagatur 18b2519356 patch: add config to ToolExecutor._execute 2024-01-23 11:33:19 -08:00
Harrison ChaseandGitHub 1e3cca4015 Merge pull request #59 from langchain-ai/wfh/update-nb
Wfh/update nb
2024-01-23 09:16:47 -08:00
Harrison Chase 90665f2416 Merge branch 'master' into wfh/update-nb 2024-01-23 09:16:02 -08:00
Harrison Chase c8187a54d1 cr 2024-01-23 09:15:48 -08:00
Nuno Campos 14c840c1e8 0.0.17 2024-01-23 09:15:19 -08:00
Nuno CamposandGitHub 40d148a9a3 Merge pull request #58 from langchain-ai/nc/23jan/state-update-validation
Add clearer error message on invalid state updates
2024-01-23 09:14:17 -08:00
Nuno Campos 5967c94367 Add clearer error message on invalid state updates 2024-01-23 09:11:14 -08:00
William FHandGitHub b926abec45 Update hierarchical agents notebook
Update hierarchical agents notebook
2024-01-23 01:46:10 -08:00
William FHandGitHub 9382837448 Merge branch 'main' into wfh/update-nb 2024-01-23 01:45:52 -08:00
William FHandGitHub 06f0217e5c Update Notebooks
update notebooks
2024-01-23 01:45:39 -08:00
Harrison Chase 3c721585b0 Merge branch 'master' into wfh/update-nb 2024-01-22 14:49:46 -08:00
William Fu-Hinthorn 1b43491e58 reword 2024-01-22 14:35:42 -08:00
William Fu-Hinthorn 4c7c2cfe63 re-organize 2024-01-22 14:32:31 -08:00
Harrison Chase db6ff77fa3 update notebooks 2024-01-21 18:05:32 -08:00
William FHandGitHub c7b2cd975f Upload Multi-agent Diagram
Add image
2024-01-21 17:33:35 -08:00
William Fu-Hinthorn 9cd46aeeb7 Add image 2024-01-21 17:32:24 -08:00
Harrison ChaseandGitHub cf5b6fadd0 Merge pull request #51 from langchain-ai/harrison/agent-simulation
Harrison/agent simulation
2024-01-21 15:11:38 -08:00
Harrison Chase 01d35948fa cr 2024-01-21 11:13:13 -08:00
Nuno Campos 1deb70a351 0.0.16 2024-01-21 09:12:39 -08:00
Nuno Campos 150583bd40 py3.9 compat 2024-01-21 09:12:18 -08:00
Nuno CamposandGitHub bd6490443f Merge pull request #50 from langchain-ai/nc/20jan/root-state
Add support for single key state, eg just list of messages
2024-01-21 09:07:49 -08:00
Nuno Campos 60482b7adb export message graph 2024-01-21 09:07:24 -08:00
Harrison Chase f71943952e agent simulation clean up 2024-01-21 09:03:39 -08:00
Nuno Campos 07f0eca65f Add MessageGraph 2024-01-20 17:17:01 -08:00
Nuno Campos b328a46f73 Change chat executor back 2024-01-20 17:05:47 -08:00
William FHandGitHub cc764f8423 Add multi-agent examples
Multi-agent collaboration
2024-01-20 15:57:00 -08:00
William Fu-Hinthorn 84a610939c Update 2024-01-20 15:55:06 -08:00
William FHandGitHub 0a6d955583 Eval notebook updates
May get overwritten by Harrison's notebook, but updating until he's finalized that one
2024-01-20 15:54:23 -08:00
Nuno Campos ee66e11eae Add support for single key state, eg just list of messages 2024-01-20 15:04:35 -08:00
William Fu-Hinthorn d50e991378 updates 2024-01-20 14:20:24 -08:00
William Fu-Hinthorn 77459e82f7 push 2024-01-20 13:02:46 -08:00
William Fu-Hinthorn 580ec6b095 coder 2024-01-20 09:14:57 -08:00
William Fu-Hinthorn baead3d113 again 2024-01-20 08:45:46 -08:00
William Fu-Hinthorn 1381bd9f53 Move out to branch 2024-01-20 08:32:21 -08:00
William Fu-Hinthorn af4bdc6f43 Update flow 2024-01-19 18:07:13 -08:00
William Fu-Hinthorn 2308451640 mv directories 2024-01-19 18:00:55 -08:00
William Fu-Hinthorn 6dabca8b77 Update simulation 2024-01-19 17:34:12 -08:00
William Fu-Hinthorn 2e871982ee Update readme 2024-01-19 13:28:40 -08:00
William Fu-Hinthorn 3316c88d59 Merge branch 'main' into wfh/autogen 2024-01-19 13:20:50 -08:00
William FHandGitHub 6236fb086d Chat bot evaluation via simulation Example 2024-01-19 13:19:40 -08:00
William Fu-Hinthorn bd035e4112 title 2024-01-19 13:19:15 -08:00
William Fu-Hinthorn c69f91895c Update 2024-01-19 13:15:44 -08:00
William Fu-Hinthorn 6934d505e4 Updaet 2024-01-19 12:53:02 -08:00
William Fu-Hinthorn eff6620ff6 add images 2024-01-19 12:48:01 -08:00
David DuongandGitHub cb1e03ebaf Merge pull request #47 from langchain-ai/dqbd/readme-env-fix
Remove unnecessary env export
2024-01-19 16:29:08 +01:00
Tat Dat Duong 1fe08c395f Remove unnecessary env export 2024-01-19 16:27:51 +01:00
William Fu-Hinthorn 885d84e4ae Agent simulation 2024-01-18 18:17:56 -08:00
Nuno Campos b6292231d4 0.0.15 2024-01-18 16:23:35 -08:00
Nuno Campos ab2745b5ef 0.0.14 2024-01-18 16:23:27 -08:00
Nuno Campos f0fa577466 Make ppickleable 2024-01-18 16:23:21 -08:00
William Fu-Hinthorn 48e635b9f3 UPdate 2024-01-18 15:58:54 -08:00
William Fu-Hinthorn ef662ae849 note 2024-01-18 15:54:28 -08:00
William Fu-Hinthorn 4c883df123 Add hierarchical example 2024-01-18 15:51:42 -08:00
Nuno CamposandGitHub c80a0c77ac Merge pull request #44 from langchain-ai/nc/18jan/config-schema
Filter from config_schema properties provided by Pregel class
2024-01-18 11:10:59 -08:00
Nuno Campos 55493f5d45 Filter from config_schema properties provided by Pregel class 2024-01-18 11:10:39 -08:00
William Fu-Hinthorn d6c1c58f19 Add image 2024-01-18 08:34:50 -08:00
William Fu-Hinthorn 9aefcc20af update collab 2024-01-17 23:59:19 -08:00
William Fu-Hinthorn a6e3d8d29c Add collab 2024-01-17 22:26:28 -08:00
William Fu-Hinthorn 84a1915896 del image 2024-01-17 20:18:54 -08:00
William Fu-Hinthorn 215a1b2bfc Simple example 2024-01-17 19:24:09 -08:00
Nuno Campos 51983ea82a 0.0.13 2024-01-17 13:59:00 -08:00
Nuno Campos e245b1d2ff Lint 2024-01-17 13:55:26 -08:00
Nuno Campos aa2eb4606d Better error message on invalid use lf lastvalue channel 2024-01-17 13:51:17 -08:00
Nuno Campos c12c7583c8 Fix tags 2024-01-17 13:51:05 -08:00
William Fu-Hinthorn 85aa4fb4f7 Add img 2024-01-16 20:40:33 -08:00
Nuno CamposandGitHub 6c916e426a Merge pull request #40 from langchain-ai/harrison/fix-links
fix links
2024-01-16 17:13:05 -08:00
Harrison Chase c2ea16fd2e fix links 2024-01-16 17:10:23 -08:00
William Fu-Hinthorn 32df51a1ff Merge branch 'main' into wfh/llm_compiler 2024-01-16 17:09:23 -08:00
William Fu-Hinthorn 6174fd7813 update 2024-01-16 17:08:33 -08:00
Nuno Campos 29d5505139 0.0.12 2024-01-16 16:28:31 -08:00
Nuno CamposandGitHub dc75fa009a Merge pull request #39 from langchain-ai/nc/jan16/recursion-error
Add recursion check
2024-01-16 16:27:44 -08:00
Nuno Campos b535b5caa0 Add tests 2024-01-16 16:23:41 -08:00
Nuno Campos 8154114e11 Add recursion check 2024-01-16 16:13:03 -08:00
Nuno Campos c9000c9625 0.0.11 2024-01-16 14:45:40 -08:00
Nuno Campos 3d79c7552d Lint 2024-01-16 13:14:00 -08:00
Nuno CamposandGitHub 3e884d9737 Merge pull request #38 from langchain-ai/nc/state
Nc/state
2024-01-16 13:08:45 -08:00
efe83776e4 Update langgraph/prebuilt/tool_executor.py
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2024-01-16 12:30:53 -08:00
Nuno Campos 8ea24435fe Add more validation 2024-01-16 10:46:21 -08:00
William Fu-Hinthorn 66ae0ae813 oops add notebook 2024-01-16 09:03:27 -08:00
William Fu-Hinthorn cf3630c359 Add llm compiler example 2024-01-15 20:31:43 -08:00
Harrison Chase b5cbaad301 cr 2024-01-15 17:51:33 -08:00
Harrison Chase f124705d6e cr 2024-01-15 17:40:09 -08:00
William Fu-Hinthorn fadd42ddd1 Merge branch 'nc/state' into wfh/llm_compiler 2024-01-15 16:56:39 -08:00
William Fu-Hinthorn 56cecdb3cb Add LLMCompiler 2024-01-15 16:56:03 -08:00
Harrison Chase 8a37f67b3c Merge branch 'nc/state' of github.com:langchain-ai/permchain into nc/state 2024-01-15 16:35:51 -08:00
Harrison Chase 2dfe20d9c6 cr 2024-01-15 16:35:46 -08:00
Nuno Campos 412d49ccd3 Add async notebook 2024-01-15 16:16:41 -08:00
Harrison Chase 62c8689adf Merge branch 'nc/state' of github.com:langchain-ai/permchain into nc/state 2024-01-15 16:11:01 -08:00
Harrison Chase 7fb7c846e0 cr 2024-01-15 16:10:56 -08:00
Nuno Campos c5e66270af Add async for chat agent exec 2024-01-15 16:01:34 -08:00
Nuno Campos b2b5365814 Add async impls 2024-01-15 15:45:17 -08:00
Nuno Campos 3539fef0cc remove arg 2024-01-15 15:35:40 -08:00
Harrison Chase 47dfc5f8c8 cr 2024-01-15 15:35:19 -08:00
Harrison Chase 7bfeb1758a cr 2024-01-15 15:35:11 -08:00
Harrison Chase 1ffdd7b93d cr 2024-01-15 15:34:17 -08:00
Harrison Chase 177f503901 cr 2024-01-15 15:31:42 -08:00
Harrison Chase 95b333f474 stash 2024-01-15 15:30:35 -08:00
Nuno Campos 2e537320c3 Rename saver to checkpointer, expose in graph, state graph, prebuilt agent exec 2024-01-15 13:45:54 -08:00
Nuno Campos 23f84c9ac9 Fix tests to run in py 3.9 2024-01-15 13:18:32 -08:00
Harrison Chase db8d02c517 Merge branch 'nc/state' of github.com:langchain-ai/permchain into nc/state 2024-01-15 13:16:18 -08:00
Harrison Chase da5e6d7319 stash 2024-01-15 13:16:05 -08:00
Nuno Campos f6894fb5dd Add input_keys, rename output_keys, add interrupt 2024-01-15 09:14:30 -08:00
Nuno Campos 6383e24b08 Manually mark runs as hidden in langsmith 2024-01-15 08:35:52 -08:00
Harrison Chase ec219c4d49 cr 2024-01-14 15:36:05 -08:00
Nuno Campos e497d14db0 Fixes 2024-01-13 15:58:25 -08:00
Nuno Campos d68faa6d06 Update tracing name 2024-01-13 10:55:18 -08:00
Nuno Campos 3d58aff93e Add async test 2024-01-13 10:44:42 -08:00
Nuno Campos 3857713601 Lint 2024-01-12 17:57:04 -08:00
Nuno Campos 426a5c1b10 Implement StateGraph 2024-01-12 17:55:19 -08:00
Nuno Campos b1bf68fde4 0.0.10 2024-01-08 18:49:39 -08:00
Nuno CamposandGitHub 7ce316bb20 Merge pull request #32 from langchain-ai/nc/8jan/docs-streaming
Nc/8jan/docs streaming
2024-01-08 18:47:20 -08:00
Nuno Campos 1e076cac26 Move 2024-01-08 17:42:24 -08:00
Nuno Campos b6b61c6585 Add docs on streaming 2024-01-08 16:36:19 -08:00
Nuno Campos ad8b5064b3 Add validation 2024-01-08 16:06:11 -08:00
Nuno CamposandGitHub 270e4c0d05 Merge pull request #31 from langchain-ai/nc/jan8/graph-stream-outbox
Adjust stream output of Graph
2024-01-08 14:55:21 -08:00
Nuno Campos 8c65b30ca7 Adjust stream output of Graph
Now output of stream() are dicts where keys are node names and values are the output of that node on that step
2024-01-08 14:48:26 -08:00
Nuno CamposandGitHub 142ad35965 Merge pull request #30 from langchain-ai/nc/8jan
Nc/8jan
2024-01-08 08:31:32 -08:00
Nuno Campos 6a7d2c6ee4 Bump 2024-01-08 08:31:13 -08:00
Nuno Campos fea9acab06 Python 3.9 compat 2024-01-08 08:28:40 -08:00
Nuno Campos 1494e549f3 Add test dockerfile 2024-01-08 08:17:26 -08:00
Nuno Campos 513edb8f69 Use strenum 2024-01-08 07:58:21 -08:00
Nuno Campos 2ee200a5f1 Update dep 2024-01-08 07:57:43 -08:00
Harrison ChaseandGitHub 3456f94596 Merge pull request #28 from langchain-ai/harrison/update-readme
update readme and license
2024-01-07 22:12:20 -08:00
Harrison Chase cd7169fbe7 cr 2024-01-07 22:10:59 -08:00
Harrison Chase 7e15f3bb83 cr 2024-01-07 20:27:45 -08:00
Harrison Chase b1f5981283 cr 2024-01-07 20:23:16 -08:00
Harrison Chase 65c4afb8ea update readme and license 2024-01-07 20:20:41 -08:00
Nuno CamposandGitHub 8144f15995 Merge pull request #27 from langchain-ai/nc/stream-all-channels
.stream() defaults to yielding output from all channels
2024-01-07 19:55:24 -08:00
Nuno Campos 5799b80261 .stream() defaults to yielding output from all channels 2024-01-07 19:53:28 -08:00
Nuno CamposandGitHub 79f8acb602 Merge pull request #26 from langchain-ai/nc/7jan
Rename
2024-01-07 19:39:51 -08:00
Nuno Campos e441990f92 Rename 2024-01-07 19:39:10 -08:00
Nuno CamposandGitHub 4bdca9d253 Merge pull request #24 from langchain-ai/harrison/langgraph
start langgraph
2024-01-07 09:56:33 -08:00
Nuno Campos 6875401cc9 Lint 2024-01-07 09:55:43 -08:00
Nuno Campos 54bfdd8e42 Remove file 2024-01-07 09:50:39 -08:00
Nuno Campos 641190d84b Remove file 2024-01-06 14:56:19 -08:00
Nuno Campos 0da6d74320 Remove file 2024-01-06 14:55:29 -08:00
Nuno Campos cc2af50ce9 Lint 2024-01-06 14:53:22 -08:00
Nuno Campos d399074d05 Remove bogus example 2024-01-06 14:52:29 -08:00
Nuno Campos 1949379926 Add outputs to notebook 2024-01-06 14:44:25 -08:00
Nuno Campos 5f8f17cac3 Improve run names 2024-01-06 14:42:28 -08:00
Nuno Campos e0a6a6b9c0 Use better pytest watcher 2024-01-06 14:22:00 -08:00
Nuno Campos 49aad8f320 Stream output of each process when running with astream_log() 2024-01-06 14:21:48 -08:00
Nuno Campos 73e4f8953b Add tests for conditional edges 2024-01-06 13:51:00 -08:00
Nuno Campos 4ab9ff05ad Add graph async tests 2024-01-06 13:15:49 -08:00
Nuno Campos d293f5156d Add output kwarg 2024-01-06 13:13:32 -08:00
Nuno Campos de599be8a1 Rename chains to nodes 2024-01-06 12:43:15 -08:00
Nuno Campos 17cd659533 ... 2024-01-05 18:22:46 -08:00
Jake RachleffandNuno Campos 51a538c6fc update 2024-01-05 16:01:08 -08:00
Jake RachleffandNuno Campos b6e3cd9044 update graph to use more graph like syntax 2024-01-05 16:01:08 -08:00
Harrison ChaseandNuno Campos 0f6ea1fe4b cr 2024-01-05 16:01:08 -08:00
Harrison ChaseandNuno Campos 6a93a68fc3 start 2024-01-05 16:01:08 -08:00
Nuno CamposandGitHub 80147c02e9 Merge pull request #25 from langchain-ai/nc/3jan
nc/3jan
2024-01-04 16:25:24 -08:00
Nuno Campos c399dec257 In .step() expose only values of lastvalue channels 2024-01-03 18:07:50 -08:00
Nuno CamposandGitHub b14c2638ee Merge pull request #23 from langchain-ai/nc/checkpoint 2024-01-01 09:25:13 -08:00
Nuno Campos 58b9502872 Update to langchain core 2023-12-28 15:23:13 -08:00
Nuno Campos 476cc90ef7 Lint 2023-12-28 15:10:47 -08:00
Nuno Campos b8de895f6b Lint 2023-12-27 20:06:49 -08:00
Nuno Campos 82741a6dcc Implement .step() and .astep() 2023-12-27 19:57:54 -08:00
Nuno Campos d1572afd49 Update _atransform 2023-12-26 20:04:00 -08:00
Nuno Campos b1b68cde94 WIP 2023-12-26 19:05:21 -08:00
Nuno Campos 57881dee6d Update langchain 2023-12-26 17:57:12 -08:00
Nuno CamposandGitHub 6fb060add0 Merge pull request #22 from langchain-ai/nc/bump
0.0.8
2023-11-29 10:11:13 +00:00
Nuno Campos 0c77107dd1 0.0.8 2023-11-29 10:10:48 +00:00
Nuno CamposandGitHub 9a02f3e97f Merge pull request #21 from langchain-ai/nc/bump
0.0.7
2023-11-29 10:02:22 +00:00
Nuno Campos d03efe28cf 0.0.7 2023-11-29 10:01:33 +00:00
Nuno CamposandGitHub 88ecb87cb3 Merge pull request #20 from langchain-ai/nc/28nov
Update to new langchain release
2023-11-29 10:00:54 +00:00
Nuno Campos dd5b100f3c Update langchain 2023-11-29 09:59:47 +00:00
Nuno Campos 9a2ddb30d7 Add test 2023-11-28 14:06:51 +00:00
Nuno Campos 99b712ca5f Change .join() implementation to have non-subscribed channels as input arg 2023-11-28 11:26:46 +00:00
Nuno Campos 80477b27b8 Export checkpoint from init 2023-11-28 09:56:21 +00:00
Nuno Campos 877a1451cb Update to new langchain release 2023-11-28 09:21:16 +00:00
Nuno Campos db85dbe62d 0.0.6 2023-11-20 10:39:35 +00:00
Nuno Campos 2cf65ac6ba 0.0.5 2023-11-20 09:52:16 +00:00
Nuno CamposandGitHub e6ab8aa6d9 Merge pull request #18 from langchain-ai/nc/reserved-channels
Add concept of reserved channels (ie. channels updated by Pregel), Add a reserved channel for is_last_step
2023-11-15 16:35:31 +00:00
Nuno Campos eef4c015d6 Allow passing values directly to Channel.write_toi 2023-11-15 16:21:09 +00:00
Nuno Campos f04b2cff5d Lint 2023-11-15 15:30:45 +00:00
Nuno Campos b90a62a00d Add concept of reserved channels (ie. channels updated by Pregel), Add a reserved channel for is_last_step 2023-11-15 15:16:18 +00:00
Nuno CamposandGitHub 6518b472ed Merge pull request #16 from langchain-ai/nc/checkpoints
Nc/checkpoints
2023-11-15 12:27:11 +00:00
Nuno Campos 682e7d175d Add tests for checkpointing 2023-11-14 12:54:23 +00:00
Nuno Campos cec6ba4963 Change binop to init value if possible 2023-11-14 12:38:17 +00:00
Nuno Campos f96ebb3357 Implement checkpoints 2023-11-14 12:14:18 +00:00
Nuno Campos de4a5ed418 Update langchain, implement config_specs 2023-11-14 11:36:30 +00:00
Nuno Campos b266b73ab9 Make channel managers aware of checkpoints 2023-11-14 11:27:31 +00:00
Nuno Campos 56a38ee859 Change Channel.checkpoint() to return any python value, add checkpoint tests 2023-11-14 11:17:39 +00:00
Nuno Campos 4035beba76 to do 2023-11-13 15:14:25 +00:00
Nuno Campos 05c89338a8 Expose imperative channel write api 2023-11-09 20:43:20 +00:00
Nuno Campos 78e1b4d9d0 Better fix 2023-11-09 20:18:44 +00:00
Nuno Campos 15f1af7403 Fix piping bug 2023-11-09 20:14:39 +00:00
Nuno Campos 94f1ec07a0 Add example 2023-11-09 11:20:12 +00:00
Nuno Campos cb39c74898 Comment 2023-11-09 10:56:13 +00:00
Nuno Campos a784d69487 Compat with py 3.10 2023-11-07 23:33:54 +00:00
Nuno Campos 0c4d560281 Update todo 2023-11-05 10:24:46 +00:00
Nuno CamposandGitHub 215d16ec40 Update README.md 2023-11-05 08:44:05 +00:00
Nuno CamposandGitHub e8e57bb307 Update README.md 2023-11-05 00:32:10 +00:00
Nuno Campos 2cf92cdad7 Add missing channel creation 2023-11-04 17:58:19 +00:00
Nuno CamposandGitHub 6704b6d205 Merge pull request #15 from langchain-ai/nc/4nov/channel-topic
Create a Topic channel, Make LastValue the default channel if not specified, Add default input and output keys
2023-11-04 17:44:32 +00:00
Nuno Campos 7f76fbb699 Create a Topic channel, Make LastValue the default channel if not specified, Add default input and output keys
- Topic channel combines the features of Inbox, Archive, UniqueInbox, UniqueArchive, which have been removed.
2023-11-04 17:40:12 +00:00
Nuno Campos 124722c0c8 Rename Channel classes 2023-11-04 14:29:48 +00:00
Nuno Campos e66a5ff576 Update deps 2023-11-04 14:13:09 +00:00
Nuno CamposandGitHub 591b8e23f2 Merge pull request #14 from langchain-ai/hwchase17-license 2023-11-01 06:17:41 +00:00
Harrison ChaseandGitHub 63ef53c75b Update LICENSE 2023-10-31 17:24:39 -07:00
Nuno Campos 77b0515cc0 0.0.4 2023-10-23 23:05:18 +01:00
482 changed files with 133526 additions and 6922 deletions
+116
View File
@@ -0,0 +1,116 @@
name: "\U0001F41B Bug Report"
description: Report a bug in LangGraph. To report a security issue, please instead use the security option below. For questions, please use the GitHub Discussions.
labels: ["02 Bug Report"]
body:
- type: markdown
attributes:
value: >
Thank you for taking the time to file a bug report.
Use this to report bugs in LangChain.
If you're not certain that your issue is due to a bug in LangChain, please use [GitHub Discussions](https://github.com/langchain-ai/langchain/discussions)
to ask for help with your issue.
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
if there's another way to solve your problem:
[LangGraph documentation](https://langchain-ai.github.io/langgraph/).
[LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
[GitHub search](https://github.com/langchain-ai/langgraph),
[LangChain Github Discussions](https://github.com/langchain-ai/langgraph/discussions),
[LangChain Github Issues](https://github.com/langchain-ai/langgraph/issues),
[LangChain ChatBot](https://chat.langchain.com/)
- type: checkboxes
id: checks
attributes:
label: Checked other resources
description: Please confirm and check all the following options.
options:
- label: I added a very descriptive title to this issue.
required: true
- label: I searched the [LangGraph](https://langchain-ai.github.io/langgraph/)/LangChain documentation with the integrated search.
required: true
- label: I used the GitHub search to find a similar question and didn't find it.
required: true
- label: I am sure that this is a bug in LangGraph/LangChain rather than my code.
required: true
- label: I am sure this is better as an issue [rather than a GitHub discussion](https://github.com/langchain-ai/langgraph/discussions/new/choose), since this is a LangGraph bug and not a design question.
required: true
- type: textarea
id: reproduction
validations:
required: true
attributes:
label: Example Code
description: |
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
If a maintainer can copy it, run it, and see it right away, there's a much higher chance that you'll be able to get help.
**Important!**
* Reduce your code to the minimum required to reproduce the issue if possible. This makes it much easier for others to help you.
* Avoid screenshots when possible, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.
placeholder: |
from langgraph.graph import StateGraph
def bad_code(inputs) -> int:
raise NotImplementedError('For demo purpose')
chain = StateGraph(list)
chain.invoke('Hello!')
render: python
- type: textarea
id: error
validations:
required: false
attributes:
label: Error Message and Stack Trace (if applicable)
description: |
If you are reporting an error, please include the full error message and stack trace.
placeholder: |
Exception + full stack trace
render: shell
- type: textarea
id: description
attributes:
label: Description
description: |
What is the problem, question, or error?
Write a short description telling what you are doing, what you expect to happen, and what is currently happening.
placeholder: |
* I'm trying to use the `langgraph` library to do X.
* I expect to see Y.
* Instead, it does Z.
validations:
required: true
- type: textarea
id: system-info
attributes:
label: System Info
description: |
Please share your system info with us.
"pip freeze | grep langchain"
platform (windows / linux / mac)
python version
OR if you're on a recent version of langchain-core you can paste the output of:
python -m langchain_core.sys_info
placeholder: |
"pip freeze | grep langgraph"
platform
python version
Alternatively, if you're on a recent version of langchain-core you can paste the output of:
python -m langchain_core.sys_info
These will only surface LangChain packages, don't forget to include any other relevant
packages you're using (if you're not sure what's relevant, you can paste the entire output of `pip freeze`).
validations:
required: true
+15
View File
@@ -0,0 +1,15 @@
blank_issues_enabled: false
version: 2.1
contact_links:
- name: 🤔 Question or Problem
about: Ask a question or ask about a problem in GitHub Discussions.
url: https://github.com/langchain-ai/langgraph/discussions/categories/q-a
- name: Feature Request
url: https://github.com/langchain-ai/langgraph/discussions/categories/ideas
about: Suggest a feature or an idea
- name: Show and tell
about: Show what you built with LangChain
url: https://github.com/langchain-ai/langgraph/discussions/categories/show-and-tell
- name: Slack
url: https://www.langchain.com/join-community
about: General community discussions
+19
View File
@@ -0,0 +1,19 @@
name: Documentation
description: Report an issue related to the LangGraph documentation.
title: "DOC: <Please write a comprehensive title after the 'DOC: ' prefix>"
labels: [03 - Documentation]
body:
- type: textarea
attributes:
label: "Issue with current documentation:"
description: >
Please make sure to leave a reference to the document/code you're
referring to.
- type: textarea
attributes:
label: "Idea or request for content:"
description: >
Please describe as clearly as possible what topics you think are missing
from the current documentation.
+25
View File
@@ -0,0 +1,25 @@
name: 🔒 Privileged
description: You are a LangChain maintainer, or was asked directly by a maintainer to create an issue here. If not, check the other options.
body:
- type: markdown
attributes:
value: |
Thanks for your interest in LangChain! 🚀
If you are not a LangChain maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation in a [Question in GitHub Discussions](https://github.com/langchain-ai/langchain/discussions/categories/q-a) instead.
You are a LangChain maintainer if you maintain any of the packages inside of the LangChain repository
or are a regular contributor to LangChain with previous merged merged pull requests.
- type: checkboxes
id: privileged
attributes:
label: Privileged issue
description: Confirm that you are allowed to create an issue here.
options:
- label: I am a LangChain maintainer, or was asked directly by a LangChain maintainer to create an issue here.
required: true
- type: textarea
id: content
attributes:
label: Issue Content
description: Add the content of the issue here.
+88
View File
@@ -0,0 +1,88 @@
# An action for setting up poetry install with caching.
# Using a custom action since the default action does not
# take poetry install groups into account.
# Action code from:
# https://github.com/actions/setup-python/issues/505#issuecomment-1273013236
name: poetry-install-with-caching
description: Poetry install with support for caching of dependency groups.
inputs:
python-version:
description: Python version, supporting MAJOR.MINOR only
required: true
poetry-version:
description: Poetry version
required: true
cache-key:
description: Cache key to use for manual handling of caching
required: true
runs:
using: composite
steps:
- uses: actions/setup-python@v5
name: Setup python ${{ inputs.python-version }}
id: setup-python
with:
python-version: ${{ inputs.python-version }}
- uses: actions/cache@v3
id: cache-bin-poetry
name: Cache Poetry binary - Python ${{ inputs.python-version }}
env:
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "1"
with:
path: |
/opt/pipx/venvs/poetry
# This step caches the poetry installation, so make sure it's keyed on the poetry version as well.
key: bin-poetry-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-${{ inputs.poetry-version }}
- name: Refresh shell hashtable and fixup softlinks
if: steps.cache-bin-poetry.outputs.cache-hit == 'true'
shell: bash
env:
POETRY_VERSION: ${{ inputs.poetry-version }}
PYTHON_VERSION: ${{ inputs.python-version }}
run: |
set -eux
# Refresh the shell hashtable, to ensure correct `which` output.
hash -r
# `actions/cache@v3` doesn't always seem able to correctly unpack softlinks.
# Delete and recreate the softlinks pipx expects to have.
rm /opt/pipx/venvs/poetry/bin/python
cd /opt/pipx/venvs/poetry/bin
ln -s "$(which "python$PYTHON_VERSION")" python
chmod +x python
cd /opt/pipx_bin/
ln -s /opt/pipx/venvs/poetry/bin/poetry poetry
chmod +x poetry
# Ensure everything got set up correctly.
/opt/pipx/venvs/poetry/bin/python --version
/opt/pipx_bin/poetry --version
- name: Install poetry
if: steps.cache-bin-poetry.outputs.cache-hit != 'true'
shell: bash
env:
POETRY_VERSION: ${{ inputs.poetry-version }}
PYTHON_VERSION: ${{ inputs.python-version }}
# Install poetry using the python version installed by setup-python step.
run: pipx install "poetry==$POETRY_VERSION" --python '${{ steps.setup-python.outputs.python-path }}' --verbose
- name: Restore pip and poetry cached dependencies
uses: actions/cache@v3
env:
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "4"
with:
path: |
~/.cache/pip
~/.cache/pypoetry/virtualenvs
~/.cache/pypoetry/cache
~/.cache/pypoetry/artifacts
./.venv
key: py-deps-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-poetry-${{ inputs.poetry-version }}-${{ inputs.cache-key }}-${{ hashFiles('./poetry.lock') }}
+60
View File
@@ -0,0 +1,60 @@
name: CLI integration test
on:
workflow_call:
env:
POETRY_VERSION: "1.7.1"
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
name: "CLI integration test"
defaults:
run:
working-directory: libs/cli
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: Ana06/get-changed-files@v2.2.0
with:
filter: "libs/cli/**"
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
if: steps.changed-files.outputs.all
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
cache-key: integration-test-cli
- name: Setup env
if: steps.changed-files.outputs.all
working-directory: libs/cli/examples
run: cat .env.example > .env
- name: Install cli globally
if: steps.changed-files.outputs.all
run: pip install -e .
- name: Start service A
if: steps.changed-files.outputs.all
run: |
timeout 60 langgraph test -c examples/langgraph.json --verbose || (exit "$(($? == 124 ? 0 : $?))")
- name: Start 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
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
if: steps.changed-files.outputs.all
working-directory: libs/cli/examples/graphs_reqs_b
run: |
timeout 60 langgraph test --verbose || (exit "$(($? == 124 ? 0 : $?))")
+127
View File
@@ -0,0 +1,127 @@
name: lint
on:
workflow_call:
inputs:
working-directory:
required: true
type: string
description: "From which folder this pipeline executes"
env:
POETRY_VERSION: "1.7.1"
# This env var allows us to get inline annotations when ruff has complaints.
RUFF_OUTPUT_FORMAT: github
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
# Only lint on the min and max supported Python versions.
# It's extremely unlikely that there's a lint issue on any version in between
# that doesn't show up on the min or max versions.
#
# GitHub rate-limits how many jobs can be running at any one time.
# Starting new jobs is also relatively slow,
# so linting on fewer versions makes CI faster.
python-version:
- "3.9"
- "3.11"
name: "lint #${{ matrix.python-version }}"
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: Ana06/get-changed-files@v2.2.0
with:
filter: "${{ inputs.working-directory }}/**"
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
if: steps.changed-files.outputs.all
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: lint-with-extras
- name: Check Poetry File
if: steps.changed-files.outputs.all
shell: bash
working-directory: ${{ inputs.working-directory }}
run: poetry check
- name: Check lock file
if: steps.changed-files.outputs.all
shell: bash
working-directory: ${{ inputs.working-directory }}
run: poetry lock --check
- name: Install dependencies
if: steps.changed-files.outputs.all
# Also installs dev/lint/test/typing dependencies, to ensure we have
# type hints for as many of our libraries as possible.
# This helps catch errors that require dependencies to be spotted, for example:
# https://github.com/langchain-ai/langchain/pull/10249/files#diff-935185cd488d015f026dcd9e19616ff62863e8cde8c0bee70318d3ccbca98341
#
# If you change this configuration, make sure to change the `cache-key`
# in the `poetry_setup` action above to stop using the old cache.
# It doesn't matter how you change it, any change will cause a cache-bust.
working-directory: ${{ inputs.working-directory }}
run: poetry install --with dev
- name: Get .mypy_cache to speed up mypy
if: steps.changed-files.outputs.all
uses: actions/cache@v3
env:
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "2"
with:
path: |
${{ inputs.working-directory }}/.mypy_cache
key: mypy-lint-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/poetry.lock', inputs.working-directory)) }}
- name: Analysing package code with our lint
if: steps.changed-files.outputs.all
working-directory: ${{ inputs.working-directory }}
run: |
if make lint_package > /dev/null 2>&1; then
make lint_package
else
echo "lint_package command not found, using lint instead"
make lint
fi
- name: Install test dependencies
if: steps.changed-files.outputs.all
# Also installs dev/lint/test/typing dependencies, to ensure we have
# type hints for as many of our libraries as possible.
# This helps catch errors that require dependencies to be spotted, for example:
# https://github.com/langchain-ai/langchain/pull/10249/files#diff-935185cd488d015f026dcd9e19616ff62863e8cde8c0bee70318d3ccbca98341
#
# If you change this configuration, make sure to change the `cache-key`
# in the `poetry_setup` action above to stop using the old cache.
# It doesn't matter how you change it, any change will cause a cache-bust.
working-directory: ${{ inputs.working-directory }}
run: |
poetry install --with dev
- name: Get .mypy_cache_test to speed up mypy
if: steps.changed-files.outputs.all
uses: actions/cache@v3
env:
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "2"
with:
path: |
${{ inputs.working-directory }}/.mypy_cache_test
key: mypy-test-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/poetry.lock', inputs.working-directory)) }}
- name: Analysing tests with our lint
if: steps.changed-files.outputs.all
working-directory: ${{ inputs.working-directory }}
run: |
if make lint_tests > /dev/null 2>&1; then
make lint_tests
else
echo "lint_tests command not found, skipping step"
fi
+57
View File
@@ -0,0 +1,57 @@
name: test
on:
workflow_call:
inputs:
working-directory:
required: true
type: string
description: "From which folder this pipeline executes"
env:
POETRY_VERSION: "1.7.1"
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
name: "test #${{ matrix.python-version }}"
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: core
- name: Install dependencies
shell: bash
working-directory: ${{ inputs.working-directory }}
run: poetry install --with dev
- name: Run core tests
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
make test
- name: Ensure the tests did not create any additional files
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
set -eu
STATUS="$(git status)"
echo "$STATUS"
# grep will exit non-zero if the target message isn't found,
# and `set -e` above will cause the step to fail.
echo "$STATUS" | grep 'nothing to commit, working tree clean'
+95
View File
@@ -0,0 +1,95 @@
name: test-release
on:
workflow_call:
inputs:
working-directory:
required: true
type: string
description: "From which folder this pipeline executes"
env:
POETRY_VERSION: "1.7.1"
PYTHON_VERSION: "3.10"
jobs:
build:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
outputs:
pkg-name: ${{ steps.check-version.outputs.pkg-name }}
version: ${{ steps.check-version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
# We want to keep this build stage *separate* from the release stage,
# so that there's no sharing of permissions between them.
# The release stage has trusted publishing and GitHub repo contents write access,
# and we want to keep the scope of that access limited just to the release job.
# Otherwise, a malicious `build` step (e.g. via a compromised dependency)
# could get access to our GitHub or PyPI credentials.
#
# Per the trusted publishing GitHub Action:
# > It is strongly advised to separate jobs for building [...]
# > from the publish job.
# https://github.com/pypa/gh-action-pypi-publish#non-goals
- name: Build project for distribution
run: poetry build
working-directory: ${{ inputs.working-directory }}
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: test-dist
path: ${{ inputs.working-directory }}/dist/
- name: Check Version
id: check-version
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
echo pkg-name="$(poetry version | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
echo version="$(poetry version --short)" >> $GITHUB_OUTPUT
publish:
needs:
- build
runs-on: ubuntu-latest
permissions:
# This permission is used for trusted publishing:
# https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/
#
# Trusted publishing has to also be configured on PyPI for each package:
# https://docs.pypi.org/trusted-publishers/adding-a-publisher/
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: test-dist
path: ${{ inputs.working-directory }}/dist/
- name: Publish to test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
print-hash: true
repository-url: https://test.pypi.org/legacy/
# We overwrite any existing distributions with the same name and version.
# 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
+114
View File
@@ -0,0 +1,114 @@
---
name: CI
on:
push:
branches: [main]
pull_request:
# If another push to the same PR or branch happens while this workflow is still running,
# cancel the earlier run in favor of the next run.
#
# There's no point in testing an outdated version of the code. GitHub only allows
# a limited number of job runners to be active at the same time, so it's better to cancel
# pointless jobs early so that more useful jobs can run sooner.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
POETRY_VERSION: "1.7.1"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
lint:
name: cd ${{ matrix.working-directory }}
needs: [ build ]
strategy:
matrix:
working-directory: [
"libs/langgraph",
"libs/sdk-py",
"libs/cli",
"libs/checkpoint",
"libs/checkpoint-sqlite",
"libs/checkpoint-postgres"
]
uses: ./.github/workflows/_lint.yml
with:
working-directory: ${{ matrix.working-directory }}
secrets: inherit
test:
name: cd ${{ matrix.working-directory }}
needs: [ build ]
strategy:
matrix:
working-directory: [
"libs/langgraph",
"libs/cli",
"libs/checkpoint",
"libs/checkpoint-sqlite",
"libs/checkpoint-postgres"
]
uses: ./.github/workflows/_test.yml
with:
working-directory: ${{ matrix.working-directory }}
secrets: inherit
integration-test:
name: CLI integration test
needs: [ build ]
uses: ./.github/workflows/_integration_test.yml
secrets: inherit
lint-js:
runs-on: ubuntu-latest
needs: [ build ]
strategy:
matrix:
working-directory:
- "libs/sdk-js"
defaults:
run:
working-directory: ${{ matrix.working-directory }}
steps:
- uses: actions/checkout@v3
- name: Setup Node.js (LTS)
uses: actions/setup-node@v3
with:
node-version: "20"
cache: "yarn"
cache-dependency-path: ${{ matrix.working-directory }}/yarn.lock
- name: Install dependencies
run: yarn install
- name: Run lint
run: yarn lint
- name: Build
run: yarn build
ci_success:
name: "CI Success"
needs: [build, lint, lint-js, test, integration-test]
if: |
always()
runs-on: ubuntu-latest
env:
JOBS_JSON: ${{ toJSON(needs) }}
RESULTS_JSON: ${{ toJSON(needs.*.result) }}
EXIT_CODE: ${{!contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && '0' || '1'}}
steps:
- name: "CI Success"
run: |
echo $JOBS_JSON
echo $RESULTS_JSON
echo "Exiting with $EXIT_CODE"
exit $EXIT_CODE
+39
View File
@@ -0,0 +1,39 @@
---
name: CI / cd . / make spell_check
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
codespell:
name: (Check for spelling errors)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Dependencies
run: |
pip install toml codespell jupytext
- name: Extract Ignore Words List
run: |
# Use a Python script to extract the ignore words list from pyproject.toml
python .github/workflows/extract_ignored_words_list.py
id: extract_ignore_words
- name: Codespell
uses: codespell-project/actions-codespell@v2
with:
skip: '*.ambr,*.lock,*.ipynb'
ignore_words_list: ${{ steps.extract_ignore_words.outputs.ignore_words_list }}
# We do this to avoid spellchecking cell outputs
- name: Codespell Notebooks
run: make codespell
+68
View File
@@ -0,0 +1,68 @@
name: Deploy Docs
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
env:
POETRY_VERSION: "1.7.1"
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: "3.12"
poetry-version: ${{ env.POETRY_VERSION }}
cache-key: docs
- name: Install dependencies
run: |
poetry install --with docs
- name: Build site
run: make build-docs
env:
MKDOCS_GIT_COMMITTERS_APIKEY: ${{ secrets.MKDOCS_GIT_COMMITTERS_APIKEY }}
- name: Configure GitHub Pages
if: github.ref == 'refs/heads/main'
uses: actions/configure-pages@v4
- name: Upload Pages Artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: ./docs/site/
- name: Deploy to GitHub Pages
if: github.ref == 'refs/heads/main'
id: deployment
uses: actions/deploy-pages@v4
- name: Deploy Pull Request Preview
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v2
with:
name: pr-preview-${{ github.event.number }}
path: ./docs/site/
@@ -0,0 +1,10 @@
import toml
pyproject_toml = toml.load("libs/langgraph/pyproject.toml")
# Extract the ignore words list (adjust the key as per your TOML structure)
ignore_words_list = (
pyproject_toml.get("tool", {}).get("codespell", {}).get("ignore-words-list")
)
print(f"::set-output name=ignore_words_list::{ignore_words_list}") # noqa: T201
+87
View File
@@ -0,0 +1,87 @@
name: Check Docs & Links
on:
pull_request:
branches:
- main
push:
branches:
- main
schedule:
- cron: "0 5 * * *"
workflow_dispatch:
env:
POETRY_VERSION: "1.7.1"
jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check links in Markdown files
uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
folder-path: "examples/,docs/"
check-modified-files-only: ${{ github.event_name != 'schedule' }}
file-path: "./README.md"
config-file: "./.markdown-link-check.config.json"
notebook-link-check:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python 3.x + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: "3.11"
poetry-version: ${{ env.POETRY_VERSION }}
cache-key: core
- name: Install dependencies
run: |
python -m pip install --upgrade pip
poetry install --with docs
poetry run pip install -U pytest pytest-check-links langsmith langchain GitPython
- name: Check links in notebooks
env:
LANGCHAIN_API_KEY: test
run: |
if [ "${{ github.event_name }}" == "schedule" ] || [ "${{ github.event_name }}" == "workflow_dispatch" ] || ([ "${{ github.event_name }}" == "push" ] && [ "${{ github.ref }}" == "refs/heads/main" ]); then
echo "Running link check on all notebooks in examples directory..."
poetry run pytest -v --check-links-ignore "https://(api|web)\.smith\.langchain\.com/.*" --check-links-ignore "https://x.com/.*" --check-links examples
else
echo "Fetching changes from origin/main..."
git fetch origin main
echo "Checking for changed notebook files..."
CHANGED_FILES=$(git diff --name-only --diff-filter=d origin/main | grep '\.ipynb$' || true)
echo "Changed files: ${CHANGED_FILES}"
if [ -n "${CHANGED_FILES}" ]; then
echo "Running link check on changed notebook files..."
poetry run pytest -v --check-links-ignore "https://(api|web)\.smith\.langchain\.com/.*" --check-links-ignore "https://x.com/.*" --check-links ${CHANGED_FILES} || ([ $? = 5 ] && exit 0 || exit $?)
else
echo "No notebook files changed."
fi
fi
check-readmes-synced:
# This checks that the repo README.md is identical to the libs/langgraph/README.md
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Check README.md is in sync
run: |
if ! diff -q README.md libs/langgraph/README.md >/dev/null; then
echo "README.md is out of sync with libs/langgraph/README.md"
diff -C 3 README.md libs/langgraph/README.md
exit 1
fi
+315
View File
@@ -0,0 +1,315 @@
name: release
run-name: Release ${{ inputs.working-directory }} by @${{ github.actor }}
on:
workflow_dispatch:
inputs:
working-directory:
required: true
type: string
default: "libs/langgraph"
env:
PYTHON_VERSION: "3.11"
POETRY_VERSION: "1.7.1"
jobs:
build:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
outputs:
pkg-name: ${{ steps.check-version.outputs.pkg-name }}
short-pkg-name: ${{ steps.check-version.outputs.short-pkg-name }}
version: ${{ steps.check-version.outputs.version }}
tag: ${{ steps.check-version.outputs.tag }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
# We want to keep this build stage *separate* from the release stage,
# so that there's no sharing of permissions between them.
# The release stage has trusted publishing and GitHub repo contents write access,
# and we want to keep the scope of that access limited just to the release job.
# Otherwise, a malicious `build` step (e.g. via a compromised dependency)
# could get access to our GitHub or PyPI credentials.
#
# Per the trusted publishing GitHub Action:
# > It is strongly advised to separate jobs for building [...]
# > from the publish job.
# https://github.com/pypa/gh-action-pypi-publish#non-goals
- name: Build project for distribution
run: poetry build
working-directory: ${{ inputs.working-directory }}
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: dist
path: ${{ inputs.working-directory }}/dist/
- name: Check Version
id: check-version
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
PKG_NAME="$(poetry version | cut -d ' ' -f 1)"
VERSION="$(poetry version --short)"
SHORT_PKG_NAME="$(echo "$PKG_NAME" | sed -e 's/langgraph//g' -e 's/-//g')"
if [ -z $SHORT_PKG_NAME ]; then
TAG="$VERSION"
else
TAG="${SHORT_PKG_NAME}==${VERSION}"
fi
echo pkg-name="$PKG_NAME" >> $GITHUB_OUTPUT
echo short-pkg-name="$SHORT_PKG_NAME" >> $GITHUB_OUTPUT
echo version="$VERSION" >> $GITHUB_OUTPUT
echo tag="$TAG" >> $GITHUB_OUTPUT
release-notes:
needs:
- build
runs-on: ubuntu-latest
outputs:
release-body: ${{ steps.generate-release-body.outputs.release-body }}
steps:
- uses: actions/checkout@v4
with:
repository: langchain-ai/langgraph
path: langgraph
sparse-checkout: | # this only grabs files for relevant dir
${{ inputs.working-directory }}
ref: main # this scopes to just master branch
fetch-depth: 0 # this fetches entire commit history
- name: Check Tags
id: check-tags
shell: bash
working-directory: langgraph/${{ inputs.working-directory }}
env:
PKG_NAME: ${{ needs.build.outputs.pkg-name }}
SHORT_PKG_NAME: ${{ needs.build.outputs.short-pkg-name }}
VERSION: ${{ needs.build.outputs.version }}
TAG: ${{ needs.build.outputs.tag }}
run: |
if [ -z $SHORT_PKG_NAME ]; then
REGEX="^\\d+\\.\\d+\\.\\d+((a|b|rc)\\d+)?\$"
else
REGEX="^$SHORT_PKG_NAME==\\d+\\.\\d+\\.\\d+((a|b|rc)\\d+)?\$"
fi
echo $REGEX
PREV_TAG=$(git tag --sort=-creatordate | grep -P $REGEX | head -1 || echo "")
echo $PREV_TAG
if [ "$TAG" == "$PREV_TAG" ]; then
echo "No new version to release"
exit 1
fi
echo prev-tag="$PREV_TAG" >> $GITHUB_OUTPUT
- name: Generate release body
id: generate-release-body
working-directory: langgraph
env:
WORKING_DIR: ${{ inputs.working-directory }}
PKG_NAME: ${{ needs.build.outputs.pkg-name }}
TAG: ${{ needs.build.outputs.tag }}
PREV_TAG: ${{ steps.check-tags.outputs.prev-tag }}
run: |
{
echo 'release-body<<EOF'
if [ -z "$PREV_TAG" ]; then
echo "Initial release"
else
echo "Changes since $PREV_TAG"
echo
git log --format="%s" "$PREV_TAG"..HEAD -- $WORKING_DIR | awk '{print "* " $0}'
fi
echo EOF
} >> "$GITHUB_OUTPUT"
test-pypi-publish:
needs:
- build
- release-notes
permissions: write-all
uses: ./.github/workflows/_test_release.yml
with:
working-directory: ${{ inputs.working-directory }}
secrets: inherit
pre-release-checks:
needs:
- build
- release-notes
- test-pypi-publish
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# We explicitly *don't* set up caching here. This ensures our tests are
# maximally sensitive to catching breakage.
#
# For example, here's a way that caching can cause a falsely-passing test:
# - Make the langchain package manifest no longer list a dependency package
# as a requirement. This means it won't be installed by `pip install`,
# and attempting to use it would cause a crash.
# - That dependency used to be required, so it may have been cached.
# When restoring the venv packages from cache, that dependency gets included.
# - Tests pass, because the dependency is present even though it wasn't specified.
# - The package is published, and it breaks on the missing dependency when
# used in the real world.
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
- name: Import published package
shell: bash
working-directory: ${{ inputs.working-directory }}
env:
PKG_NAME: ${{ needs.build.outputs.pkg-name }}
VERSION: ${{ needs.build.outputs.version }}
# Here we use:
# - The default regular PyPI index as the *primary* index, meaning
# that it takes priority (https://pypi.org/simple)
# - The test PyPI index as an extra index, so that any dependencies that
# are not found on test PyPI can be resolved and installed anyway.
# (https://test.pypi.org/simple). This will include the PKG_NAME==VERSION
# package because VERSION will not have been uploaded to regular PyPI yet.
# - attempt install again after 5 seconds if it fails because there is
# sometimes a delay in availability on test pypi
run: |
poetry run pip install \
--extra-index-url https://test.pypi.org/simple/ \
"$PKG_NAME==$VERSION" || \
( \
sleep 5 && \
poetry run pip install \
--extra-index-url https://test.pypi.org/simple/ \
"$PKG_NAME==$VERSION" \
)
if [[ "$PKG_NAME" == *checkpoint* ]]; then
# since checkpoint packages are namespace packages, import them with . convention
# i.e. import langgraph.checkpoint or langgraph.checkpoint.sqlite
IMPORT_NAME="$(echo "$PKG_NAME" | sed s/-/./g)"
else
# Replace all dashes in the package name with underscores,
# since that's how Python imports packages with dashes in the name.
IMPORT_NAME="$(echo "$PKG_NAME" | sed s/-/_/g)"
fi
poetry run python -c "import $IMPORT_NAME; print(dir($IMPORT_NAME))"
- name: Import test dependencies
run: poetry install --with dev
working-directory: ${{ inputs.working-directory }}
# Overwrite the local version of the package with the test PyPI version.
- name: Import published package (again)
working-directory: ${{ inputs.working-directory }}
shell: bash
env:
PKG_NAME: ${{ needs.build.outputs.pkg-name }}
VERSION: ${{ needs.build.outputs.version }}
run: |
poetry run pip install \
--extra-index-url https://test.pypi.org/simple/ \
"$PKG_NAME==$VERSION"
- name: Run unit tests
run: make test
working-directory: ${{ inputs.working-directory }}
publish:
needs:
- build
- release-notes
- test-pypi-publish
- pre-release-checks
runs-on: ubuntu-latest
permissions:
# This permission is used for trusted publishing:
# https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/
#
# Trusted publishing has to also be configured on PyPI for each package:
# https://docs.pypi.org/trusted-publishers/adding-a-publisher/
id-token: write
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
- uses: actions/download-artifact@v4
with:
name: dist
path: ${{ inputs.working-directory }}/dist/
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ${{ inputs.working-directory }}/dist/
verbose: true
print-hash: true
mark-release:
needs:
- build
- release-notes
- test-pypi-publish
- pre-release-checks
- publish
runs-on: ubuntu-latest
permissions:
# This permission is needed by `ncipollo/release-action` to
# create the GitHub release.
contents: write
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@v4
- name: Set up Python + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: release
- uses: actions/download-artifact@v4
with:
name: dist
path: ${{ inputs.working-directory }}/dist/
- name: Create Tag
uses: ncipollo/release-action@v1
with:
artifacts: "dist/*"
token: ${{ secrets.GITHUB_TOKEN }}
generateReleaseNotes: false
tag: ${{needs.build.outputs.tag}}
body: ${{ needs.release-notes.outputs.release-body }}
commit: ${{ github.sha }}
+38
View File
@@ -0,0 +1,38 @@
name: JS Release
on:
workflow_dispatch:
jobs:
publish:
# Disallow publishing from branches that aren't `main`.
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
strategy:
matrix:
working-directory:
- "libs/sdk-js"
defaults:
run:
working-directory: ${{ matrix.working-directory }}
steps:
- uses: actions/checkout@v4
# JS Build
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: "20"
cache: "yarn"
cache-dependency-path: ${{ matrix.working-directory }}/yarn.lock
- name: Install dependencies
run: yarn install
- name: Build
run: yarn build
- name: Publish package to NPM
run: |
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
npm publish
+28
View File
@@ -0,0 +1,28 @@
name: Check File Size
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
jobs:
file-size-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v44
- name: Filter by size
run: |
large_added_files=$(find ${{ steps.changed-files.outputs.added_files }} -maxdepth 0 -size +1M)
if [ -n "$large_added_files" ]; then
echo "Large files added: $large_added_files"
echo "# Large files added:" >> $GITHUB_STEP_SUMMARY
echo "$large_added_files" >> $GITHUB_STEP_SUMMARY
exit 1
fi
+6
View File
@@ -171,3 +171,9 @@ docs/api_reference/*/
docs/docs_skeleton/build
docs/docs_skeleton/node_modules
docs/docs_skeleton/yarn.lock
# Any new jupyter notebooks
# not intended for the repo
Untitled*.ipynb
Chinook.db
+4
View File
@@ -0,0 +1,4 @@
{
"aliveStatusCodes": [200, 206, 402],
"ignorePatterns": ["*dcbadge.vercel.app*"]
}
+293
View File
@@ -0,0 +1,293 @@
# Contributing to LangGraph
Thank you for being interested in contributing to LangGraph!
## General guidelines
Here are some things to keep in mind for all types of contributions:
- Follow the ["fork and pull request"](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project) workflow.
- Fill out the checked-in pull request template when opening pull requests. Note related issues and tag relevant maintainers.
- Ensure your PR passes formatting, linting, and testing checks before requesting a review.
- If you would like comments or feedback, please open an issue or discussion and tag a maintainer.
- Backwards compatibility is key. Your changes must not be breaking, except in case of critical bug and security fixes.
- Look for duplicate PRs or issues that have already been opened before opening a new one.
- Keep scope as isolated as possible. As a general rule, your changes should not affect more than one package at a time.
### Bugfixes
For bug fixes, please open up an issue before proposing a fix to ensure the proposal properly addresses the underlying problem. In general, bug fixes should all have an accompanying unit test that fails before the fix.
### New features
For new features, please start a new [discussion](https://github.com/langchain-ai/langgraph/discussions), where the maintainers will help with scoping out the necessary changes.
## Contribute Documentation
Documentation is a vital part of LangGraph. We welcome both new documentation for new features and
community improvements to our current documentation. Please read the resources below before getting started:
- [Documentation style guide](#documentation-style-guide)
- [Documentation setup](#setup)
## Documentation Style Guide
As LangGraph continues to grow, the surface area of documentation required to cover it continues to grow too.
This page provides guidelines for anyone writing documentation for LangGraph, as well as some of our philosophies around organization and structure.
## Philosophy
LangGraph's documentation follows the [Diataxis framework](https://diataxis.fr).
Under this framework, all documentation falls under one of four categories: [Tutorials](#tutorials),
[How-to guides](#how-to-guides),
[References](#references), and [Explanations (aka conceptual guides)](#conceptual-guide).
### Tutorials
Tutorials are lessons that take the reader through a practical activity. Their purpose is to help the user
gain understanding of concepts and how they interact by showing one way to achieve some goal in a hands-on way.
They should **avoid** giving
multiple permutations of ways to achieve that goal in-depth. Choice is burdensome. Instead, they should guide a new user through a recommended path to accomplishing a concrete goal. While the end result of a tutorial does not necessarily need to
be completely production-ready, it should be useful and practically satisfy the the goal that you clearly stated in the tutorial's introduction.
To quote the Diataxis website:
> A tutorial serves the users *acquisition* of skills and knowledge - their study. Its purpose is not to help the user get something done, but to help them learn.
In LangGraph, these are often higher level guides that show off end-to-end use cases.
Some examples include:
- [Build a Customer Support Bot](https://langchain-ai.github.io/langgraph/tutorials/customer-support/customer-support/)
- [Build a SQL Agent](https://langchain-ai.github.io/langgraph/tutorials/sql-agent/)
Here are some high-level tips on writing a good tutorial:
- Focus on guiding the user to get something done, but keep in mind the end-goal is more to impart principles than to create a perfect production system.
- Be specific, not abstract and follow one path.
- No need to go deeply into alternative approaches, but its ok to reference them, ideally with a link to an appropriate how-to guide.
- Get "a point on the board" as soon as possible - something the user can run that outputs something.
- You can iterate and expand afterwards.
- Try to frequently checkpoint at given steps where the user can run code and see progress.
- Focus on results, not technical explanation.
- Crosslink heavily to appropriate conceptual/reference pages
- The first time you mention a LangGraph concept, use its full name (e.g. "human-in-the-loop"), and link to its conceptual/other documentation page.
- It's also helpful to add a prerequisite callout that links to any pages with necessary background information.
- End with a recap/next steps section summarizing what the tutorial covered and future reading, such as related how-to guides.
- Use phrases like "Next we can run X & Y. We will expect Z.". Then afterwards, use language like "Notice Z" that recalls our expectations and directs the reader's attention to the topic we are trying to teach.
- Do not shy away from repetition.
### How-to guides
A how-to guide, as the name implies, demonstrates how to do something discrete and specific.
It should assume that the user is already familiar with underlying concepts, and is trying to solve an immediate problem, but
should still give some background or list the scenarios where the information contained within can be relevant.
They can and should discuss alternatives if one approach may be better than another in certain cases.
To quote the Diataxis website:
> A how-to guide serves the work of the already-competent user, whom you can assume to know what they want to do, and to be able to follow your instructions correctly.
Some examples include:
- [How to add persistence to your graph](https://langchain-ai.github.io/langgraph/how-tos/persistence/)
- [How to view and update past graph state](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/time-travel/)
Here are some high-level tips on writing a good how-to guide:
- Clearly explain what you are guiding the user through at the start
- Assume higher intent than a tutorial and show what the user needs to do to get that task done
- Assume familiarity of concepts, but explain why suggested actions are helpful
- Crosslink heavily to conceptual/reference pages
- Discuss alternatives and responses to real-world tradeoffs that may arise when solving a problem
- Use lots of example code, ideally within complete code blocks that the reader can copy and run.
- End with a recap/next steps section summarizing what the tutorial covered and future reading, such as other related how-to guides
### Conceptual guides
LangGraph's conceptual guides fall under the **Explanation** quadrant of Diataxis. They should cover LangChain terms and concepts
in a more abstract way than how-to guides or tutorials, and should be geared towards curious users interested in
gaining a deeper understanding of the framework. Try to avoid excessively large code examples. The goal here is to
impart perspective to the user rather than to finish a practical project. These guides should cover **why** things work they way they do.
To quote the Diataxis website:
> The perspective of explanation is higher and wider than that of the other types. It does not take the users eye-level view, as in a how-to guide, or a close-up view of the machinery, like reference material. Its scope in each case is a topic - “an area of knowledge”, that somehow has to be bounded in a reasonable, meaningful way.
Some examples include:
- [What does it mean to be agentic?](https://langchain-ai.github.io/langgraph/concepts/high_level/)
- [Tool calling](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#tool-calling)
Here are some high-level tips on writing a good conceptual guide:
- Explain design decisions. Why does concept X exist and why was it designed this way?
- Use analogies and reference other concepts and alternatives
- Avoid blending in too much reference content
- You can and should reference content covered in other guides, but make sure to link to them
### References
References contain detailed, low-level information that describes exactly what functionality exists and how to use it.
In LangGraph, this is mainly our API reference pages, which are populated from docstrings within code.
References pages are generally not read end-to-end, but are consulted as necessary when a user needs to know
how to use something specific.
To quote the Diataxis website:
> The only purpose of a reference guide is to describe, as succinctly as possible, and in an orderly way. Whereas the content of tutorials and how-to guides are led by needs of the user, reference material is led by the product it describes.
Many of the reference pages in LangChain are automatically generated from code,
but here are some high-level tips on writing a good docstring:
- Be concise
- Discuss special cases and deviations from a user's expectations
- Go into detail on required inputs and outputs
- Light details on when one might use the feature are fine, but in-depth details belong in other sections.
Each category serves a distinct purpose and requires a specific approach to writing and structuring the content.
## General guidelines
Here are some other guidelines you should think about when writing and organizing documentation.
We generally do not merge new tutorials from outside contributors without an actue need.
We welcome updates as well as new integration docs, how-tos, and references.
### Avoid duplication
Multiple pages that cover the same material in depth are difficult to maintain and cause confusion. There should
be only one (very rarely two), canonical pages for a given concept or feature. Instead, you should link to other guides.
### Link to other sections
Because sections of the docs do not exist in a vacuum, it is important to link to other sections as often as possible
to allow a developer to learn more about an unfamiliar topic inline.
This includes linking to the API references as well as conceptual sections!
### Be concise
In general, take a less-is-more approach. If a section with a good explanation of a concept already exists, you should link to it rather than
re-explain it, unless the concept you are documenting presents some new wrinkle.
Be concise, including in code samples.
### General style
- Use active voice and present tense whenever possible
- Use examples and code snippets to illustrate concepts and usage
- Use appropriate header levels (`#`, `##`, `###`, etc.) to organize the content hierarchically
- Use fewer cells with more code to make copy/paste easier
- Use bullet points and numbered lists to break down information into easily digestible chunks
- Use tables (especially for **Reference** sections) and diagrams often to present information visually
- Include the table of contents for longer documentation pages to help readers navigate the content, but hide it for shorter pages
## Setup
LangChain documentation consists of two components:
1. Main Documentation: Hosted at [https://langchain-ai.github.io](https://langchain-ai.github.io/langgraph/),
this comprehensive resource serves as the primary user-facing documentation.
It covers a wide array of topics, including tutorials, use cases, integrations,
and more, offering extensive guidance on building with LangGraph.
The content for this documentation lives in the `/docs` directory of the monorepo.
2. In-code Documentation: This is documentation of the codebase itself, which is also
used to generate the externally facing [API Reference](https://langchain-ai.github.io/langgraph/reference/graphs/).
The content for the API reference is autogenerated by scanning the docstrings in the codebase. For this reason we ask that developers document their code well.
We appreciate all contributions to the documentation, whether it be fixing a typo,
adding a new tutorial or example and whether it be in the main documentation or the API Reference.
### 📜 Main Documentation
The content for the main documentation is located in the `/docs` directory of the monorepo.
The documentation is written using a combination of ipython notebooks (`.ipynb` files)
and markdown (`.md` files). The notebooks are converted to markdown
and then built using [MkDocs](https://www.mkdocs.org/).
Feel free to make contributions to the main documentation! 🥰
After modifying the documentation:
1. Run the linting and formatting commands (see below) to ensure that the documentation is well-formatted and free of errors.
2. Optionally build the documentation locally to verify that the changes look good.
3. Make a pull request with the changes.
### ⚒️ Linting and Building Documentation Locally
After writing up the documentation, you may want to lint and build the documentation
locally to ensure that it looks good and is free of errors.
If you're unable to build it locally that's okay as well, as you will be able to
see a preview of the documentation on the pull request page.
From the **monorepo root**, run the following command to install the dependencies:
```bash
poetry install --with docs --no-root
```
#### Building
The code that builds the documentation is located in the `/docs` directory of the monorepo.
Before building the documentation, it is always a good idea to clean the build directory:
```bash
make clean-docs
```
You can build and preview the documentation as outlined below:
```bash
make serve-docs
```
#### Linting
The documentation is linted from the **monorepo root**. To lint it, run the following from there:
```bash
make spellcheck
```
### In-code Documentation
The in-code documentation is autogenerated from docstrings.
For the API reference to be useful, the codebase must be well-documented. This means that all functions, classes, and methods should have a docstring that explains what they do, what the arguments are, and what the return value is. This is a good practice in general, but it is especially important for LangChain because the API reference is the primary resource for developers to understand how to use the codebase.
We generally follow the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) for docstrings.
Here is an example of a well-documented function:
```python
def my_function(arg1: int, arg2: str) -> float:
"""This is a short description of the function. (It should be a single sentence.)
This is a longer description of the function. It should explain what
the function does, what the arguments are, and what the return value is.
It should wrap at 88 characters.
Examples:
This is a section for examples of how to use the function.
.. code-block:: python
my_function(1, "hello")
Args:
arg1: This is a description of arg1. We do not need to specify the type since
it is already specified in the function signature.
arg2: This is a description of arg2.
Returns:
This is a description of the return value.
"""
return 3.14
```
+6 -6
View File
@@ -1,6 +1,6 @@
The MIT License
MIT License
Copyright (c) Harrison Chase
Copyright (c) 2024 LangChain, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+20 -66
View File
@@ -1,74 +1,28 @@
.PHONY: all clean docs_build docs_clean docs_linkcheck api_docs_build api_docs_clean api_docs_linkcheck format lint test tests test_watch integration_tests docker_tests help extended_tests
.PHONY: build-docs serve-docs serve-clean-docs clean-docs codespell build-typedoc
# Default target executed when no arguments are given to make.
all: help
build-typedoc:
cd libs/sdk-js && yarn install --include-dev && yarn typedoc
cd libs/sdk-js && yarn --silent concat-md --decrease-title-levels --ignore=js_ts_sdk_ref.md --start-title-level-at 2 docs > ../../docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md 2>/dev/null
# Add links to the monorepo
sed -e '1,10s|@langchain/langgraph-sdk|[@langchain/langgraph-sdk](https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-js)|g' docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md > temp_file && mv temp_file docs/docs/cloud/reference/sdk/js_ts_sdk_ref.md
######################
# TESTING AND COVERAGE
######################
# Run unit tests and generate a coverage report.
coverage:
poetry run pytest --cov \
--cov-config=.coveragerc \
--cov-report xml \
--cov-report term-missing:skip-covered
test:
poetry run pytest
build-docs: build-typedoc
poetry run python docs/_scripts/copy_notebooks.py
poetry run python -m mkdocs build --clean -f docs/mkdocs.yml --strict
test_watch:
poetry run ptw
serve-clean-docs: clean-docs
poetry run python docs/_scripts/copy_notebooks.py
poetry run python -m mkdocs serve -c -f docs/mkdocs.yml --strict -w ./libs/langgraph
######################
# LINTING AND FORMATTING
######################
serve-docs: build-typedoc
poetry run python docs/_scripts/copy_notebooks.py
poetry run python -m mkdocs serve -f docs/mkdocs.yml -w ./libs/langgraph --dirty
# Define a variable for Python and notebook files.
PYTHON_FILES=.
lint format: PYTHON_FILES=.
lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --diff-filter=d master | grep -E '\.py$$|\.ipynb$$')
clean-docs:
find ./docs/docs -name "*.ipynb" -type f -delete
rm -rf docs/site
lint lint_diff:
poetry run ruff .
poetry run black $(PYTHON_FILES) --check
poetry run mypy $(PYTHON_FILES)
format format_diff:
poetry run black $(PYTHON_FILES)
poetry run ruff --select I --fix $(PYTHON_FILES)
spell_check:
poetry run codespell --toml pyproject.toml
spell_fix:
poetry run codespell --toml pyproject.toml -w
######################
# HELP
######################
help:
@echo '===================='
@echo '-- DOCUMENTATION --'
@echo 'clean - run docs_clean and api_docs_clean'
@echo 'docs_build - build the documentation'
@echo 'docs_clean - clean the documentation build artifacts'
@echo 'docs_linkcheck - run linkchecker on the documentation'
@echo 'api_docs_build - build the API Reference documentation'
@echo 'api_docs_clean - clean the API Reference documentation build artifacts'
@echo 'api_docs_linkcheck - run linkchecker on the API Reference documentation'
@echo '-- LINTING --'
@echo 'format - run code formatters'
@echo 'lint - run linters'
@echo 'spell_check - run codespell on the project'
@echo 'spell_fix - run codespell on the project and fix the errors'
@echo '-- TESTS --'
@echo 'coverage - run unit tests and generate coverage report'
@echo 'test - run unit tests'
@echo 'tests - run unit tests (alias for "make test")'
@echo 'test TEST_FILE=<test_file> - run all tests in file'
@echo 'extended_tests - run only extended unit tests'
@echo 'test_watch - run unit tests in watch mode'
@echo 'integration_tests - run integration tests'
@echo 'docker_tests - run unit tests in docker'
codespell:
./docs/codespell_notebooks.sh .
+211 -79
View File
@@ -1,99 +1,231 @@
# `permchain`
# 🦜🕸️LangGraph
## Get started
![Version](https://img.shields.io/pypi/v/langgraph)
[![Downloads](https://static.pepy.tech/badge/langgraph/month)](https://pepy.tech/project/langgraph)
[![Open Issues](https://img.shields.io/github/issues-raw/langchain-ai/langgraph)](https://github.com/langchain-ai/langgraph/issues)
[![Docs](https://img.shields.io/badge/docs-latest-blue)](https://langchain-ai.github.io/langgraph/)
`pip install permchain`
⚡ Building language agents as graphs ⚡
> [!NOTE]
> Looking for the JS version? Click [here](https://github.com/langchain-ai/langgraphjs) ([JS docs](https://langchain-ai.github.io/langgraphjs/)).
## Overview
PermChain is an alpha-stage library for building stateful, multi-actor applications with LLMs. It extends the [LangChain Expression Language](https://python.langchain.com/docs/expression_language/) with the ability to coordinate multiple chains (or actors) across multiple steps of computation. It is inspired by [Pregel](https://research.google/pubs/pub37252/) and [Apache Beam](https://beam.apache.org/).
[LangGraph](https://langchain-ai.github.io/langgraph/) is a library for building stateful, multi-actor applications with LLMs, used to create agent and multi-agent workflows. Compared to other LLM frameworks, it offers these core benefits: cycles, controllability, and persistence. LangGraph allows you to define flows that involve cycles, essential for most agentic architectures, differentiating it from DAG-based solutions. As a very low-level framework, it provides fine-grained control over both the flow and state of your application, crucial for creating reliable agents. Additionally, LangGraph includes built-in persistence, enabling advanced human-in-the-loop and memory features.
Some of the use cases are:
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.
- Recursive/iterative LLM chains
- LLM chains with persistent state/memory
- LLM agents
- Multi-agent simulations
- ...and more!
### Key Features
## How it works
- **Cycles and Branching**: Implement loops and conditionals in your apps.
- **Persistence**: Automatically save state after each step in the graph. Pause and resume the graph execution at any point to support error recovery, human-in-the-loop workflows, time travel and more.
- **Human-in-the-Loop**: Interrupt graph execution to approve or edit next action planned by the agent.
- **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).
### Channels
Channels are used to communicate between chains. Each channel has a value type, an update type, and an update function which takes a sequence of updates and modifies the stored value. Channels can be used to send data from one chain to another, or to send data from a chain to itself in a future step. PermChain provides a number of built-in channels:
## Installation
- `LastValue`: stores the last value sent to the channel, useful for input values, and single-value outputs
- `Inbox`: stores an ephemeral sequence of values sent to the channel, useful for sending data from one chain to another
- `UniqueInbox`: same as Inbox, but deduplicates values sent to the channel
- `Archive`: stores a persistent sequence of values sent to the channel, useful for accumulating data over multiple steps
- `UniqueArchive`: same as Archive, but deduplicates values sent to the channel
- `BinaryOperatorAggregate`: stores a persistent value, updated by applying a binary operator to the current value and each update sent to the channel, useful for computing aggregates over multiple steps. eg. `total = BinaryOperatorAggregate(int, operator.add)`
- `Context`: exposes the value of a context manager, managing its lifecycle. Useful for accessing external resources that require setup and/or teardown. eg. `client = Context(httpx.Client)`
### Chains
Chains are LCEL Runnables which subscribe to one or more channels, and write to one or more channels. Any valid LCEL expression can be used as a chain. Chains can be combined into a Pregel application, which coordinates the execution of the chains across multiple steps.
### Pregel
Pregel combines multiple chains (or actors) into a single application. It coordinates the execution of the chains across multiple steps, following the Pregel/Bulk Synchronous Parallel model. Each step consists of three phases:
- **Plan**: Determine which chains to execute in this step, ie. the chains that subscribe to channels updated in the previous step (or, in the first step, chains that subscribe to input channels)
- **Execution**: Execute those chains in parallel, until all complete, or one fails, or a timeout is reached. Any channel updates are invisible to other chains until the next step.
- **Update**: Update the channels with the values written by the chains in this step.
Repeat until no chains are planned for execution, or a maximum number of steps is reached.
```shell
pip install -U langgraph
```
## Example
```python
from permchain import Channel, Pregel
from permchain.channels import LastValue
One of the central concepts of LangGraph is state. Each graph execution creates a state that is passed between nodes in the graph as they execute, and each node updates this internal state with its return value after it executes. The way that the graph updates its internal state is defined by either the type of graph chosen or a custom function.
grow_value = (
Channel.subscribe_to("value")
| (lambda x: x + x)
| Channel.write_to(value=lambda x: x if len(x) < 10 else None)
)
app = Pregel(
chains={"grow_value": grow_value},
channels={"value": LastValue(str)},
input="value",
output="value",
)
assert app.invoke("a") == "aaaaaaaa"
Let's take a look at a simple example of an agent that can use a search tool.
```shell
pip install langchain-anthropic
```
Check `examples` for more examples.
```shell
export ANTHROPIC_API_KEY=sk-...
```
## Near-term Roadmap
Optionally, we can set up [LangSmith](https://docs.smith.langchain.com/) for best-in-class observability.
- [x] Iterate on API
- [x] do we want api to receive output from multiple channels in invoke()
- [x] do we want api to send input to multiple channels in invoke()
- [x] Finish updating tests to new API
- [x] Implement input_schema and output_schema in Pregel
- [ ] More tests
- [x] Test different input and output types (str, str sequence)
- [x] Add tests for Stream, UniqueInbox
- [ ] Add tests for subscribe_to_each().join()
- [x] Add optional debug logging
- [ ] Implement checkpointing
- [ ] Save checkpoints at end of each step
- [ ] Load checkpoint at start of invocation
- [ ] API to specify storage backend and save key
- [ ] Add more examples
- [ ] human in the loop
- [ ] combine documents
- [ ] agent executor
- [ ] run over dataset
- [ ] Fault tolerance
- [ ] Retry individual processes in a step
- [ ] Retry entire step?
- [ ] Pregel.stream_log to contain additional keys specific to Pregel
- [ ] tasks: inputs of each chain in each step, keyed by {name}:{step}
- [ ] task_results: same as above but outputs
- [ ] channels: channel values at end of each step, keyed by {name}:{step}
```shell
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=lsv2_sk_...
```
```python
from typing import Annotated, Literal, TypedDict
from langchain_core.messages import HumanMessage
from langchain_anthropic import ChatAnthropic
from langchain_core.tools import tool
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import END, START, StateGraph, MessagesState
from langgraph.prebuilt import ToolNode
# Define the tools for the agent to use
@tool
def search(query: str):
"""Call to surf the web."""
# This is a placeholder, but don't tell the LLM that...
if "sf" in query.lower() or "san francisco" in query.lower():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
tools = [search]
tool_node = ToolNode(tools)
model = ChatAnthropic(model="claude-3-5-sonnet-20240620", temperature=0).bind_tools(tools)
# Define the function that determines whether to continue or not
def should_continue(state: MessagesState) -> Literal["tools", END]:
messages = state['messages']
last_message = messages[-1]
# If the LLM makes a tool call, then we route to the "tools" node
if last_message.tool_calls:
return "tools"
# Otherwise, we stop (reply to the user)
return END
# Define the function that calls the model
def call_model(state: MessagesState):
messages = state['messages']
response = model.invoke(messages)
# We return a list, because this will get added to the existing list
return {"messages": [response]}
# Define a new graph
workflow = StateGraph(MessagesState)
# Define the two nodes we will cycle between
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)
# Set the entrypoint as `agent`
# This means that this node is the first one called
workflow.add_edge(START, "agent")
# We now add a conditional edge
workflow.add_conditional_edges(
# First, we define the start node. We use `agent`.
# This means these are the edges taken after the `agent` node is called.
"agent",
# Next, we pass in the function that will determine which node is called next.
should_continue,
)
# We now add a normal edge from `tools` to `agent`.
# This means that after `tools` is called, `agent` node is called next.
workflow.add_edge("tools", 'agent')
# Initialize memory to persist state between graph runs
checkpointer = MemorySaver()
# Finally, we compile it!
# This compiles it into a LangChain Runnable,
# meaning you can use it as you would any other runnable.
# Note that we're (optionally) passing the memory when compiling the graph
app = workflow.compile(checkpointer=checkpointer)
# Use the Runnable
final_state = app.invoke(
{"messages": [HumanMessage(content="what is the weather in sf")]},
config={"configurable": {"thread_id": 42}}
)
final_state["messages"][-1].content
```
```
"Based on the search results, I can tell you that the current weather in San Francisco is:\n\nTemperature: 60 degrees Fahrenheit\nConditions: Foggy\n\nSan Francisco is known for its microclimates and frequent fog, especially during the summer months. The temperature of 60°F (about 15.5°C) is quite typical for the city, which tends to have mild temperatures year-round. The fog, often referred to as "Karl the Fog" by locals, is a characteristic feature of San Francisco\'s weather, particularly in the mornings and evenings.\n\nIs there anything else you\'d like to know about the weather in San Francisco or any other location?"
```
Now when we pass the same `"thread_id"`, the conversation context is retained via the saved state (i.e. stored list of messages)
```python
final_state = app.invoke(
{"messages": [HumanMessage(content="what about ny")]},
config={"configurable": {"thread_id": 42}}
)
final_state["messages"][-1].content
```
```
"Based on the search results, I can tell you that the current weather in New York City is:\n\nTemperature: 90 degrees Fahrenheit (approximately 32.2 degrees Celsius)\nConditions: Sunny\n\nThis weather is quite different from what we just saw in San Francisco. New York is experiencing much warmer temperatures right now. Here are a few points to note:\n\n1. The temperature of 90°F is quite hot, typical of summer weather in New York City.\n2. The sunny conditions suggest clear skies, which is great for outdoor activities but also means it might feel even hotter due to direct sunlight.\n3. This kind of weather in New York often comes with high humidity, which can make it feel even warmer than the actual temperature suggests.\n\nIt's interesting to see the stark contrast between San Francisco's mild, foggy weather and New York's hot, sunny conditions. This difference illustrates how varied weather can be across different parts of the United States, even on the same day.\n\nIs there anything else you'd like to know about the weather in New York or any other location?"
```
### Step-by-step Breakdown
1. <details>
<summary>Initialize the model and tools.</summary>
- we use `ChatAnthropic` as our LLM. **NOTE:** we need make sure the model knows that it has these tools available to call. We can do this by converting the LangChain tools into the format for OpenAI tool calling using the `.bind_tools()` method.
- we define the tools we want to use - a search tool in our case. It is really easy to create your own tools - see documentation here on how to do that [here](https://python.langchain.com/docs/modules/agents/tools/custom_tools).
</details>
2. <details>
<summary>Initialize graph with state.</summary>
- we initialize graph (`StateGraph`) by passing state schema (in our case `MessagesState`)
- `MessagesState` is a prebuilt state schema that has one attribute -- a list of LangChain `Message` objects, as well as logic for merging the updates from each node into the state
</details>
3. <details>
<summary>Define graph nodes.</summary>
There are two main nodes we need:
- The `agent` node: responsible for deciding what (if any) actions to take.
- The `tools` node that invokes tools: if the agent decides to take an action, this node will then execute that action.
</details>
4. <details>
<summary>Define entry point and graph edges.</summary>
First, we need to set the entry point for graph execution - `agent` node.
Then we define one normal and one conditional edge. Conditional edge means that the destination depends on the contents of the graph's state (`MessageState`). In our case, the destination is not known until the agent (LLM) decides.
- Conditional edge: after the agent is called, we should either:
- a. Run tools if the agent said to take an action, OR
- b. Finish (respond to the user) if the agent did not ask to run tools
- Normal edge: after the tools are invoked, the graph should always return to the agent to decide what to do next
</details>
5. <details>
<summary>Compile the graph.</summary>
- When we compile the graph, we turn it into a LangChain [Runnable](https://python.langchain.com/v0.2/docs/concepts/#runnable-interface), which automatically enables calling `.invoke()`, `.stream()` and `.batch()` with your inputs
- We can also optionally pass checkpointer object for persisting state between graph runs, and enabling memory, human-in-the-loop workflows, time travel and more. In our case we use `MemorySaver` - a simple in-memory checkpointer
</details>
6. <details>
<summary>Execute the graph.</summary>
1. LangGraph adds the input message to the internal state, then passes the state to the entrypoint node, `"agent"`.
2. The `"agent"` node executes, invoking the chat model.
3. The chat model returns an `AIMessage`. LangGraph adds this to the state.
4. Graph cycles the following steps until there are no more `tool_calls` on `AIMessage`:
- If `AIMessage` has `tool_calls`, `"tools"` node executes
- The `"agent"` node executes again and returns `AIMessage`
5. Execution progresses to the special `END` value and outputs the final state.
And as a result, we get a list of all our chat messages as output.
</details>
## Documentation
* [Tutorials](https://langchain-ai.github.io/langgraph/tutorials/): Learn to build with LangGraph through guided examples.
* [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/): 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.
## Contributing
For more information on how to contribute, see [here](https://github.com/langchain-ai/langgraph/blob/main/CONTRIBUTING.md).
+4
View File
@@ -0,0 +1,4 @@
*.ipynb
site/
docs/tutorials/**/*.png
docs/cloud/reference/sdk/js_ts_sdk_ref.md
+226
View File
@@ -0,0 +1,226 @@
import json
import os
import re
import shutil
from pathlib import Path
root_dir = Path(__file__).resolve().parents[2]
examples_dir = root_dir / "examples"
docs_dir = root_dir / "docs/docs"
how_tos_dir = docs_dir / "how-tos"
tutorials_dir = docs_dir / "tutorials"
cloud_how_tos_dir = docs_dir / "cloud/how-tos"
cloud_sdk_dir = docs_dir / "cloud"
_MANUAL = {
"how-tos": [
"state-context-key.ipynb",
"async.ipynb",
"stream-values.ipynb",
"stream-updates.ipynb",
"stream-multiple.ipynb",
"streaming-tokens.ipynb",
"streaming-tokens-without-langchain.ipynb",
"streaming-content.ipynb",
"streaming-events-from-within-tools.ipynb",
"streaming-events-from-within-tools-without-langchain.ipynb",
"streaming-from-final-node.ipynb",
"persistence.ipynb",
"input_output_schema.ipynb",
"pass_private_state.ipynb",
"memory/manage-conversation-history.ipynb",
"memory/delete-messages.ipynb",
"memory/add-summary-conversation-history.ipynb",
"persistence_postgres.ipynb",
"persistence_mongodb.ipynb",
"persistence_redis.ipynb",
"visualization.ipynb",
"state-model.ipynb",
"subgraph.ipynb",
"recursion-limit.ipynb",
"force-calling-a-tool-first.ipynb",
"pass-run-time-values-to-tools.ipynb",
"tool-calling.ipynb",
"tool-calling-errors.ipynb",
"pass-config-to-tools.ipynb",
"many-tools.ipynb",
"dynamic-returning-direct.ipynb",
"managing-agent-steps.ipynb",
"respond-in-format.ipynb",
"branching.ipynb",
"dynamically-returning-directly.ipynb",
"configuration.ipynb",
"map-reduce.ipynb",
"create-react-agent.ipynb",
"create-react-agent-system-prompt.ipynb",
"create-react-agent-memory.ipynb",
"create-react-agent-hitl.ipynb",
"human_in_the_loop/breakpoints.ipynb",
"human_in_the_loop/dynamic_breakpoints.ipynb",
"human_in_the_loop/time-travel.ipynb",
"human_in_the_loop/edit-graph-state.ipynb",
"human_in_the_loop/wait-user-input.ipynb",
"human_in_the_loop/review-tool-calls.ipynb",
"node-retries.ipynb",
"react_diagrams.png",
"react-agent-structured-output.ipynb",
],
"tutorials": [
"introduction.ipynb",
"customer-support/customer-support.ipynb",
"tutorials/tnt-llm/tnt-llm.ipynb",
"tutorials/sql-agent.ipynb",
],
}
_MANUAL_INVERSE = {v: docs_dir / k for k, vs in _MANUAL.items() for v in vs}
_HOW_TOS = {"agent_executor", "chat_agent_executor_with_function_calling", "docs"}
_HIDE = set(
str(examples_dir / f)
for f in [
"agent_executor/base.ipynb",
"agent_executor/force-calling-a-tool-first.ipynb",
"agent_executor/high-level.ipynb",
"agent_executor/human-in-the-loop.ipynb",
"agent_executor/managing-agent-steps.ipynb",
"chat_agent_executor_with_function_calling/anthropic.ipynb",
"chat_agent_executor_with_function_calling/base.ipynb",
"chat_agent_executor_with_function_calling/dynamically-returning-directly.ipynb",
"chat_agent_executor_with_function_calling/force-calling-a-tool-first.ipynb",
"chat_agent_executor_with_function_calling/high-level-tools.ipynb",
"chat_agent_executor_with_function_calling/high-level.ipynb",
"chat_agent_executor_with_function_calling/human-in-the-loop.ipynb",
"chat_agent_executor_with_function_calling/managing-agent-steps.ipynb",
"chat_agent_executor_with_function_calling/prebuilt-tool-node.ipynb",
"chat_agent_executor_with_function_calling/respond-in-format.ipynb",
"chatbots/customer-support.ipynb",
"rag/langgraph_rag_agent_llama3_local.ipynb",
"rag/langgraph_self_rag_pinecone_movies.ipynb",
"rag/langgraph_adaptive_rag_cohere.ipynb",
"dynamically-returning-directly.ipynb",
"force-calling-a-tool-first.ipynb",
"managing-agent-steps.ipynb",
"respond-in-format.ipynb",
"quickstart.ipynb",
"human-in-the-loop.ipynb",
"learning.ipynb",
"docs/quickstart.ipynb",
"tutorials/rag-agent-testing.ipynb",
"tutorials/rag-agent-testing-local.ipynb",
"tutorials/tool-calling-agent-local.ipynb",
"time-travel.ipynb",
"code_assistant/langgraph_code_assistant_mistral.ipynb",
]
)
def clean_notebooks():
roots = (how_tos_dir, tutorials_dir)
for dir_ in roots:
traversed = []
for root, dirs, files in os.walk(dir_):
for file in files:
if file.endswith(".ipynb"):
os.remove(os.path.join(root, file))
# Now delete the dir if it is empty now
if root not in roots:
traversed.append(root)
for root in reversed(traversed):
if not os.listdir(root):
os.rmdir(root)
def update_notebook_links(notebook_path):
with open(notebook_path, "r", encoding="utf-8") as f:
notebook = json.load(f)
for cell in notebook["cells"]:
if cell["cell_type"] == "markdown":
for i, source in enumerate(cell["source"]):
# Update relative notebook links
cell["source"][i] = re.sub(
r"\[([^\]]+)\]\(([^:)]+\.ipynb)\)",
lambda m: transform_link(m.group(1), m.group(2)),
source,
)
with open(notebook_path, "w", encoding="utf-8") as f:
json.dump(notebook, f, indent=2)
def transform_link(text, link):
dir_path, filename = os.path.split(link)
# Remove the .ipynb extension
filename_without_ext = os.path.splitext(filename)[0]
# If it's a local link (starts with ./)
if link.startswith("./"):
# Change to parent directory and remove ./ prefix
new_link = f"../{filename_without_ext}/"
elif dir_path:
# If there's a directory path, keep it and add one more level up
new_link = f"../{dir_path}/{filename_without_ext}/"
else:
# If it's just a filename, simply go one level up
new_link = f"../{filename_without_ext}/"
return f"[{text}]({new_link})"
def copy_notebooks():
# Nested ones are mostly tutorials rn
for root, dirs, files in os.walk(examples_dir):
if any(
path.startswith(".") or path.startswith("__") for path in root.split(os.sep)
):
continue
if any(path in _HOW_TOS for path in root.split(os.sep)):
dst_dir = how_tos_dir
elif "sdk" in root.split(os.sep):
dst_dir = cloud_sdk_dir
elif "cloud_examples" in root.split(os.sep):
dst_dir = cloud_how_tos_dir
else:
dst_dir = tutorials_dir
for file in files:
dst_dir_ = dst_dir
if file.endswith((".ipynb", ".png")):
src_path = os.path.join(root, file)
if src_path in _HIDE:
print("Hiding:", src_path)
continue
dst_path = os.path.join(
dst_dir, os.path.relpath(src_path, examples_dir)
)
for k in _MANUAL_INVERSE:
if src_path.endswith(k):
overridden_dir = _MANUAL_INVERSE[k]
dst_path = os.path.join(
overridden_dir, os.path.relpath(src_path, examples_dir)
)
print(f"Overriding: {src_path} to {dst_path}")
break
# Avoid double nesting.
dst_path = dst_path.replace("tutorials/tutorials", "tutorials").replace(
"how-tos/how-tos", "how-tos"
)
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
print(f"Copying: {src_path} to {dst_path}")
shutil.copy(src_path, dst_path)
# Convert all ./img/* to ../img/*
if file.endswith(".ipynb"):
with open(dst_path, "r") as f:
content = f.read()
content = content.replace("(./img/", "(../img/")
content = content.replace('src=\\"./img/', 'src=\\"../img/')
with open(dst_path, "w") as f:
f.write(content)
update_notebook_links(dst_path)
dst_dir = dst_dir_
if __name__ == "__main__":
clean_notebooks()
copy_notebooks()
+13
View File
@@ -0,0 +1,13 @@
ERROR_FOUND=0
for file in $(find $1 -name "*.ipynb"); do
OUTPUT=$(cat "$file" | jupytext --from ipynb --to py:percent | codespell -)
if [ -n "$OUTPUT" ]; then
echo "Errors found in $file"
echo "$OUTPUT"
ERROR_FOUND=1
fi
done
if [ "$ERROR_FOUND" -ne 0 ]; then
exit 1
fi
+203
View File
@@ -0,0 +1,203 @@
# API Concepts
This page describes the high-level concepts of the LangGraph Cloud API. The conceptual guide of LangGraph (Python library) is [here](../../concepts/index.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
An assistant is a configured instance of a [`CompiledGraph`][compiledgraph]. It abstracts the cognitive architecture of the graph and contains instance specific configuration and metadata. Multiple assistants can reference the same graph but can contain different configuration and metadata, which may differentiate the behavior of the assistants. An assistant (i.e. the graph) is invoked as part of a run.
The LangGraph Cloud API provides several endpoints for creating and managing assistants. See the [API reference](../reference/api/api_ref.html#tag/assistantscreate) for more details.
#### Configuring Assistants
You can save custom assistants from the same graph to set different default prompts, models, and other configurations without changing a line of code in your graph. This allows you the ability to quickly test out different configurations without having to rewrite your graph every time, and also give users the flexibility to select different configurations when using your LangGraph application. See <a href="https://langchain-ai.github.io/langgraph/cloud/how-tos/cloud_examples/configuration_cloud/">this</a> how-to for information on how to configure a deployed graph.
### 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#checkpointer).
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/cloud_examples/cron_jobs.ipynb) 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/cloud_examples/stateless_runs.ipynb) 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/cloud_examples/webhooks.ipynb) 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.
+28
View File
@@ -0,0 +1,28 @@
# 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)
Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

+78
View File
@@ -0,0 +1,78 @@
# How to Deploy to LangGraph Cloud
LangGraph Cloud is available within <a href="https://www.langchain.com/langsmith" target="_blank">LangSmith</a>. To deploy a LangGraph Cloud API, navigate to the <a href="https://smith.langchain.com/" target="_blank">LangSmith UI</a>.
## Prerequisites
1. LangGraph Cloud applications are deployed from GitHub repositories. Configure and upload a LangGraph Cloud application to a GitHub repository in order to deploy it to LangGraph Cloud.
1. [Verify that the LangGraph API runs locally](test_locally.md). If the API does not build and run successfully (i.e. `langgraph up`), deploying to LangGraph Cloud will fail as well.
## Create New Deployment
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 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`
1. Select `Import from GitHub` and follow the GitHub OAuth workflow to install and authorize LangChain's `hosted-langserve` GitHub app to access the selected repositories. After installation is complete, return to the `Create New Deployment` panel and select the GitHub repository to deploy from the dropdown menu.
1. Specify a name for the deployment.
1. Specify the full path to the [LangGraph API config file](../reference/cli.md#configuration-file) including the file name. For example, if the file `langgraph.json` is in the root of the repository, simply specify `langgraph.json`.
1. Specify the desired `git` reference (e.g. branch name). For example, different branches of the repository can be deployed.
1. Select the desired `Deployment Type`.
1. `Development` deployments are meant for non-production use cases and are provisioned with minimal resources.
1. `Production` deployments can serve up to 500 requests/second and are provisioned with highly available storage with automatic backups.
1. Specify `Environment Variables` and secrets. See the [Environment Variables reference](../reference/env_var.md) to configure additional variables for the deployment.
1. Sensitive values such as API keys (e.g. `OPENAI_API_KEY`) should be specified as secrets.
1. Additional non-secret environment variables can be specified as well.
1. A new LangSmith `Tracing Project` is automatically created with the same name as the deployment.
1. In the top-right corner, select `Submit`. After a few seconds, the `Deployment` view appears and the new deployment will be queued for provisioning.
## Create New Revision
When [creating a new deployment](#create-new-deployment), a new revision is created by default. Subsequent revisions can be created to deploy new code changes.
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. 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.
1. Specify the full path to the [LangGraph API config file](../reference/cli.md#configuration-file) including the file name. For example, if the file `langgraph.json` is in the root of the repository, simply specify `langgraph.json`.
1. Specify the desired `git` reference (e.g. branch name). For example, different branches of the repository can be deployed.
1. Specify `Environment Variables` and secrets. Existing secrets and environment variables are prepopulated. See the [Environment Variables reference](../reference/env_var.md) to configure additional variables for the revision.
1. Add new secrets or environment variables.
1. Remove existing secrets or environment variables.
1. Update the value of existing secrets or environment variables.
1. Select `Submit`. After a few seconds, the `New Revision` modal will close and the new revision will be queued for deployment.
## View Build and Deployment Logs
Build and deployment logs are available for each revision.
Starting from the `Deployment` 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.
1. Within the `Deploy` tab, adjust the date/time range picker as needed. By default, the date/time range picker is set to the `Last 15 minutes`.
## Interrupt Revision
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...
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.
1. A modal will appear. Review the confirmation message. Select `Interrupt revision`.
## Delete Deployment
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. 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`.
+146
View File
@@ -0,0 +1,146 @@
# Rebuild Graph at Runtime
You might need to rebuild your graph with a different configuration for a new run. For example, you might need to use a different graph state or graph structure depending on the config. This guide shows how you can do this.
!!! note "Note"
In most cases, customizing behavior based on the config should be handled by a single graph where each node can read a config and change its behavior based on it
## Prerequisites
Make sure to check out [this how-to guide](./setup.md) on setting up your app for deployment first.
## Define graphs
Let's say you have an app with a simple graph that calls an LLM and returns the response to the user. The app file directory looks like the following:
```
my-app/
|-- requirements.txt
|-- .env
|-- openai_agent.py # code for your graph
```
where the graph is defined in `openai_agent.py`.
### No rebuild
In the standard LangGraph API configuration, the server uses the compiled graph instance that's defined at the top level of `openai_agent.py`, which looks like the following:
```python
from langchain_openai import ChatOpenAI
from langgraph.graph import END, START, MessageGraph
model = ChatOpenAI(temperature=0)
graph_workflow = MessageGraph()
graph_workflow.add_node("agent", model)
graph_workflow.add_edge("agent", END)
graph_workflow.add_edge(START, "agent")
agent = graph_workflow.compile()
```
To make the server aware of your graph, you need to specify a path to the variable that contains the `CompiledStateGraph` instance in your LangGraph API configuration (`langgraph.json`), e.g.:
```
{
"dependencies": ["."],
"graphs": {
"openai_agent": "./openai_agent.py:agent",
},
"env": "./.env"
}
```
### Rebuild
To make your graph rebuild on each new run with custom configuration, you need to rewrite `openai_agent.py` to instead provide a _function_ that takes a config and returns a graph (or compiled graph) instance. Let's say we want to return our existing graph for user ID '1', and a tool-calling agent for other users. We can modify `openai_agent.py` as follows:
```python
from typing import Annotated, TypedDict
from langchain_openai import ChatOpenAI
from langgraph.graph import END, START, MessageGraph
from langgraph.graph.state import StateGraph
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode
from langchain_core.tools import tool
from langchain_core.messages import BaseMessage
from langchain_core.runnables import RunnableConfig
class State(TypedDict):
messages: Annotated[list[BaseMessage], add_messages]
model = ChatOpenAI(temperature=0)
def make_default_graph():
"""Make a simple LLM agent"""
graph_workflow = StateGraph(State)
def call_model(state):
return {"messages": [model.invoke(state["messages"])]}
graph_workflow.add_node("agent", call_model)
graph_workflow.add_edge("agent", END)
graph_workflow.add_edge(START, "agent")
agent = graph_workflow.compile()
return agent
def make_alternative_graph():
"""Make a tool-calling agent"""
@tool
def add(a: float, b: float):
"""Adds two numbers."""
return a + b
tool_node = ToolNode([add])
model_with_tools = model.bind_tools([add])
def call_model(state):
return {"messages": [model_with_tools.invoke(state["messages"])]}
def should_continue(state: State):
if state["messages"][-1].tool_calls:
return "tools"
else:
return END
graph_workflow = StateGraph(State)
graph_workflow.add_node("agent", call_model)
graph_workflow.add_node("tools", tool_node)
graph_workflow.add_edge("tools", "agent")
graph_workflow.add_edge(START, "agent")
graph_workflow.add_conditional_edges("agent", should_continue)
agent = graph_workflow.compile()
return agent
# this is the graph making function that will decide which graph to
# build based on the provided config
def make_graph(config: RunnableConfig):
user_id = config.get("configurable", {}).get("user_id")
# route to different graph state / structure based on the user ID
if user_id == "1":
return make_default_graph()
else:
return make_alternative_graph()
```
Finally, you need to specify the path to your graph-making function (`make_graph`) in `langgraph.json`:
```
{
"dependencies": ["."],
"graphs": {
"openai_agent": "./openai_agent.py:make_graph",
},
"env": "./.env"
}
```
See more info on LangGraph API configuration file [here](../reference/cli.md#configuration-file)
Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

+35
View File
@@ -0,0 +1,35 @@
# How to Self-Host LangGraph Cloud API
!!! warning "Enterprise License Required"
Self-hosting LangGraph Cloud API requires a license key. Please contact sales@langchain.dev for more details.
LangGraph Cloud APIs can be self-hosted with a valid LangGraph Cloud license key. Self-hosted deployments are built with Docker and deployed with Helm (on Kubernetes) or with Docker Compose. Ensure that the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/) is installed.
LangGraph Cloud license key should be passed to the service as an environment variable named LANGGRAPH_CLOUD_LICENSE_KEY.
## Build Docker Image
1. Follow the [How-to Guide](setup.md) for setting up a LangGraph application for deployment. Your LangGraph application will vary from the example in the How-to Guide. However, ensure that the [LangGraph API configuration file](../reference/cli.md#configuration-file) is created.
1. Install the [LangGraph CLI](../reference/cli.md#installation).
1. Run the following LangGraph CLI `build` command to build a Docker image. Specify the image tag (`-t`) and other desired [options](../reference/cli.md#build).
langgraph build -t tag_name
!!! info "Build Platform"
When building the Docker image, ensure that the image is built for the platform of the target Kubernetes cluster: `langgraph build -t tag_name --platform linux/amd64,linux/arm64`
## Self-Host on Kubernetes
This section is for self-hosting LangGraph Cloud API on Kubernetes via Helm. A Kubernetes cluster must be provisioned before proceeding with these steps. The public Helm chart for LangGraph Cloud is available [here](https://github.com/langchain-ai/helm/tree/main/charts/langgraph-cloud).
1. Publish the built Docker image to a repository that can be accessed by the target Kubernetes cluster.
1. Ensure that the [Helm client](https://github.com/helm/helm?tab=readme-ov-file#install) is installed.
1. Make note of all environment variables that are needed for the application. These values will need to be set in the Helm `values` YAML configuration.
1. Follow [these instructions](https://github.com/langchain-ai/helm/tree/main/charts/langgraph-cloud#readme) to configure the Helm chart and deploy to Kubernetes.
## Self-Host with Docker
!!! warning "Under Construction"
This section of the documentation is in progress.
Docker Compose can be used to deploy LangGraph Cloud to the compute infrastructure of your choice (e.g. VM).
+190
View File
@@ -0,0 +1,190 @@
# How to Set Up a LangGraph Application for Deployment
A LangGraph application must be configured with a [LangGraph API configuration file](../reference/cli.md#configuration-file) in order to be deployed to LangGraph Cloud (or to be self-hosted). This how-to guide discusses the basic steps to setup a LangGraph application for deployment using `requirements.txt` to specify project dependencies.
This walkthrough is based on [this repository](https://github.com/langchain-ai/langgraph-example), which you can play around with to learn more about how to setup your LangGraph application for deployment.
!!! tip "Setup with pyproject.toml"
If you prefer using poetry for dependency management, check out [this how-to guide](./setup_pyproject.md) on using `pyproject.toml` for LangGraph Cloud.
!!! tip "Setup with a Monorepo"
If you are interested in deploying a graph located inside a monorepo, take a look at [this](https://github.com/langchain-ai/langgraph-example-monorepo) repository for an example of how to do so.
The final repo structure will look something like this:
```bash
my-app/
├── my_agent # all project code lies within here
│ ├── utils # utilities for your graph
│ │ ├── __init__.py
│ │ ├── tools.py # tools for your graph
│ │ ├── nodes.py # node functions for you graph
│ │ └── state.py # state definition of your graph
│   ├── requirements.txt # package dependencies
│   ├── __init__.py
│   └── agent.py # code for constructing your graph
├── .env # environment variables
└── langgraph.json # configuration file for LangGraph
```
After each step, an example file directory is provided to demonstrate how code can be organized.
## Specify Dependencies
Dependencies can optionally be specified in one of the following files: `pyproject.toml`, `setup.py`, or `requirements.txt`. If none of these files is created, then dependencies can be specified later in the [LangGraph API configuration file](#create-langgraph-api-config).
The dependencies below will be included in the image, you can also use them in your code, as long as with a compatible version range:
```
langgraph>=0.2.7,<0.3.0
langgraph-checkpoint>=1.0.4
langchain-core>=0.2.27,<0.3.0
langsmith>=0.1.63
orjson>=3.9.7
httpx>=0.25.0
tenacity>=8.0.0
uvicorn>=0.26.0
sse-starlette>=2.1.0
uvloop>=0.18.0
httptools>=0.5.0
jsonschema-rs>=0.16.3
croniter>=1.0.1
structlog>=23.1.0
redis>=5.0.0,<6.0.0
```
Example `requirements.txt` file:
```
langgraph
langchain_anthropic
tavily-python
langchain_community
langchain_openai
```
Example file directory:
```bash
my-app/
├── my_agent # all project code lies within here
│   └── requirements.txt # package dependencies
```
## Specify Environment Variables
Environment variables can optionally be specified in a file (e.g. `.env`). See the [Environment Variables reference](../reference/env_var.md) to configure additional variables for a deployment.
Example `.env` file:
```
MY_ENV_VAR_1=foo
MY_ENV_VAR_2=bar
OPENAI_API_KEY=key
```
Example file directory:
```bash
my-app/
├── my_agent # all project code lies within here
│   └── requirements.txt # package dependencies
└── .env # environment variables
```
## Define Graphs
Implement your graphs! Graphs can be defined in a single file or multiple files. Make note of the variable names of each [CompiledGraph][compiledgraph] to be included in the LangGraph application. The variable names will be used later when creating the [LangGraph API configuration file](../reference/cli.md#configuration-file).
Example `agent.py` file, which shows how to import from other modules you define (code for the modules is not shown here, please see [this repo](https://github.com/langchain-ai/langgraph-example) to see their implementation):
```python
# my_agent/agent.py
from typing import TypedDict, Literal
from langgraph.graph import StateGraph, END, START
from my_agent.utils.nodes import call_model, should_continue, tool_node # import nodes
from my_agent.utils.state import AgentState # import state
# Define the config
class GraphConfig(TypedDict):
model_name: Literal["anthropic", "openai"]
workflow = StateGraph(AgentState, config_schema=GraphConfig)
workflow.add_node("agent", call_model)
workflow.add_node("action", tool_node)
workflow.add_edge(START, "agent")
workflow.add_conditional_edges(
"agent",
should_continue,
{
"continue": "action",
"end": END,
},
)
workflow.add_edge("action", "agent")
graph = workflow.compile()
```
!!! warning "Assign `CompiledGraph` to Variable"
The build process for LangGraph Cloud requires that the `CompiledGraph` object be assigned to a variable at the top-level of a Python module (alternatively, you can provide [a function that creates a graph](./graph_rebuild.md)).
Example file directory:
```bash
my-app/
├── my_agent # all project code lies within here
│ ├── utils # utilities for your graph
│ │ ├── __init__.py
│ │ ├── tools.py # tools for your graph
│ │ ├── nodes.py # node functions for you graph
│ │ └── state.py # state definition of your graph
│   ├── requirements.txt # package dependencies
│   ├── __init__.py
│   └── agent.py # code for constructing your graph
└── .env # environment variables
```
## Create LangGraph API Config
Create a [LangGraph API configuration file](../reference/cli.md#configuration-file) called `langgraph.json`. See the [LangGraph CLI reference](../reference/cli.md#configuration-file) for detailed explanations of each key in the JSON object of the configuration file.
Example `langgraph.json` file:
```json
{
"dependencies": ["./my_agent"],
"graphs": {
"agent": "./my_agent/agent.py:graph"
},
"env": ".env"
}
```
Note that the variable name of the `CompiledGraph` appears at the end of the value of each subkey in the top-level `graphs` key (i.e. `:<variable_name>`).
!!! warning "Configuration Location"
The LangGraph API configuration file must be placed in a directory that is at the same level or higher than the Python files that contain compiled graphs and associated dependencies.
Example file directory:
```bash
my-app/
├── my_agent # all project code lies within here
│ ├── utils # utilities for your graph
│ │ ├── __init__.py
│ │ ├── tools.py # tools for your graph
│ │ ├── nodes.py # node functions for you graph
│ │ └── state.py # state definition of your graph
│   ├── requirements.txt # package dependencies
│   ├── __init__.py
│   └── agent.py # code for constructing your graph
├── .env # environment variables
└── langgraph.json # configuration file for LangGraph
```
## Next
After you setup your project and place it in a github repo, it's time to [deploy your app](./cloud.md).
@@ -0,0 +1,198 @@
# How to Set Up a LangGraph Application for Deployment
A LangGraph application must be configured with a [LangGraph API configuration file](../reference/cli.md#configuration-file) in order to be deployed to LangGraph Cloud (or to be self-hosted). This how-to guide discusses the basic steps to setup a LangGraph application for deployment using `pyproject.toml` to define your package's dependencies.
This walkthrough is based on [this repository](https://github.com/langchain-ai/langgraph-example), which you can play around with to learn more about how to setup your LangGraph application for deployment.
!!! tip "Setup with requirements.txt"
If you prefer using `requirements.txt` for dependency management, check out [this how-to guide](./setup.md).
!!! tip "Setup with a Monorepo"
If you are interested in deploying a graph located inside a monorepo, take a look at [this](https://github.com/langchain-ai/langgraph-example-monorepo) repository for an example of how to do so.
The final repo structure will look something like this:
```bash
my-app/
├── my_agent # all project code lies within here
│ ├── utils # utilities for your graph
│ │ ├── __init__.py
│ │ ├── tools.py # tools for your graph
│ │ ├── nodes.py # node functions for you graph
│ │ └── state.py # state definition of your graph
│   ├── __init__.py
│   └── agent.py # code for constructing your graph
├── .env # environment variables
├── langgraph.json # configuration file for LangGraph
└── pyproject.toml # dependencies for your project
```
After each step, an example file directory is provided to demonstrate how code can be organized.
## Specify Dependencies
Dependencies can optionally be specified in one of the following files: `pyproject.toml`, `setup.py`, or `requirements.txt`. If none of these files is created, then dependencies can be specified later in the [LangGraph API configuration file](#create-langgraph-api-config).
The dependencies below will be included in the image, you can also use them in your code, as long as with a compatible version range:
```
langgraph>=0.2.7,<0.3.0
langgraph-checkpoint>=1.0.4
langchain-core>=0.2.27,<0.3.0
langsmith>=0.1.63
orjson>=3.9.7
httpx>=0.25.0
tenacity>=8.0.0
uvicorn>=0.26.0
sse-starlette>=2.1.0
uvloop>=0.18.0
httptools>=0.5.0
jsonschema-rs>=0.16.3
croniter>=1.0.1
structlog>=24.4.0
redis>=5.0.8,<6.0.0
```
Example `pyproject.toml` file:
```toml
[tool.poetry]
name = "my-agent"
version = "0.0.1"
description = "An excellent agent build for LangGraph cloud."
authors = ["Polly the parrot <1223+polly@users.noreply.github.com>"]
license = "MIT"
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.9.0,<3.13"
langgraph = "^0.2.0"
langchain-fireworks = "^0.1.3"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
```
Example file directory:
```bash
my-app/
└── pyproject.toml # Python packages required for your graph
```
## Specify Environment Variables
Environment variables can optionally be specified in a file (e.g. `.env`). See the [Environment Variables reference](../reference/env_var.md) to configure additional variables for a deployment.
Example `.env` file:
```
MY_ENV_VAR_1=foo
MY_ENV_VAR_2=bar
FIREWORKS_API_KEY=key
```
Example file directory:
```bash
my-app/
├── .env # file with environment variables
└── pyproject.toml
```
## Define Graphs
Implement your graphs! Graphs can be defined in a single file or multiple files. Make note of the variable names of each [CompiledGraph][compiledgraph] to be included in the LangGraph application. The variable names will be used later when creating the [LangGraph API configuration file](../reference/cli.md#configuration-file).
Example `agent.py` file, which shows how to import from other modules you define (code for the modules is not shown here, please see [this repo](https://github.com/langchain-ai/langgraph-example-pyproject) to see their implementation):
```python
# my_agent/agent.py
from typing import TypedDict, Literal
from langgraph.graph import StateGraph, END, START
from my_agent.utils.nodes import call_model, should_continue, tool_node # import nodes
from my_agent.utils.state import AgentState # import state
# Define the config
class GraphConfig(TypedDict):
model_name: Literal["anthropic", "openai"]
workflow = StateGraph(AgentState, config_schema=GraphConfig)
workflow.add_node("agent", call_model)
workflow.add_node("action", tool_node)
workflow.add_edge(START, "agent")
workflow.add_conditional_edges(
"agent",
should_continue,
{
"continue": "action",
"end": END,
},
)
workflow.add_edge("action", "agent")
graph = workflow.compile()
```
!!! warning "Assign `CompiledGraph` to Variable"
The build process for LangGraph Cloud requires that the `CompiledGraph` object be assigned to a variable at the top-level of a Python module.
Example file directory:
```bash
my-app/
├── my_agent # all project code lies within here
│ ├── utils # utilities for your graph
│ │ ├── __init__.py
│ │ ├── tools.py # tools for your graph
│ │ ├── nodes.py # node functions for you graph
│ │ └── state.py # state definition of your graph
│   ├── __init__.py
│   └── agent.py # code for constructing your graph
├── .env
└── pyproject.toml
```
## Create LangGraph API Config
Create a [LangGraph API configuration file](../reference/cli.md#configuration-file) called `langgraph.json`. See the [LangGraph CLI reference](../reference/cli.md#configuration-file) for detailed explanations of each key in the JSON object of the configuration file.
Example `langgraph.json` file:
```json
{
"dependencies": ["."],
"graphs": {
"agent": "./my_agent/agent.py:graph"
},
"env": ".env"
}
```
Note that the variable name of the `CompiledGraph` appears at the end of the value of each subkey in the top-level `graphs` key (i.e. `:<variable_name>`).
!!! warning "Configuration Location"
The LangGraph API configuration file must be placed in a directory that is at the same level or higher than the Python files that contain compiled graphs and associated dependencies.
Example file directory:
```bash
my-app/
├── my_agent # all project code lies within here
│ ├── utils # utilities for your graph
│ │ ├── __init__.py
│ │ ├── tools.py # tools for your graph
│ │ ├── nodes.py # node functions for you graph
│ │ └── state.py # state definition of your graph
│   ├── __init__.py
│   └── agent.py # code for constructing your graph
├── .env # environment variables
├── langgraph.json # configuration file for LangGraph
└── pyproject.toml # dependencies for your project
```
## Next
After you setup your project and place it in a github repo, it's time to [deploy your app](./cloud.md).
+182
View File
@@ -0,0 +1,182 @@
# How to test a LangGraph app locally
This guide assumes you have a LangGraph app correctly set up with a proper configuration file and a corresponding compiled graph, and that you have a proper LangChain API key.
Testing locally ensures that there are no errors or conflicts with Python dependencies and confirms that the configuration file is specified correctly.
## Setup
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:
```python
LANGCHAIN_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:
```shell
langgraph up
```
This will start up the LangGraph API server locally. If this runs successfully, you should see something like:
```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
```
### Interact with the server
We can now interact with the API server using the LangGraph SDK. First, we need to start our client, select our assistant (in this case a graph we called "agent", make sure to select the proper assistant you wish to test).
You can either initialize by passing authentication or by setting an environment variable.
#### Initialize with authentication
=== "Python"
```python
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>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
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 assistantId = "agent"
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
--header 'x-api-key: <LANGCHAIN_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
=== "Python"
```python
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()
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
// only set the apiUrl if you changed the default port when calling langgraph up
const client = new Client();
const assistantId = "agent"
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
Now we can invoke our graph to ensure it is working. Make sure to change the input to match the proper schema for your graph.
=== "Python"
```python
input = {"messages": [{"role": "human", "content": "what's the weather in sf"}]}
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id,
input=input,
stream_mode="updates",
):
print(f"Receiving new event of type: {chunk.event}...")
print(chunk.data)
print("\n\n")
```
=== "Javascript"
```js
const input = { "messages": [{ "role": "human", "content": "what's the weather in sf"}] }
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "updates",
}
);
for await (const chunk of streamResponse) {
console.log(`Receiving new event of type: ${chunk.event}...`);
console.log(chunk.data);
console.log("\n\n");
}
```
=== "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:/ {
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"
}
}
'
```
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.
+65
View File
@@ -0,0 +1,65 @@
# Studio FAQs
## Why is my project failing to start?
There are a few reasons that your project might fail to start, here are some of the most common ones.
### Docker issues
LangGraph Studio requires Docker Desktop version 4.24 or higher. Please make sure you have a version of Docker installed that satisfies that requirement and also make sure you have the Docker Desktop app up and running before trying to use LangGraph Studio. In addition, make sure you have docker-compose updated to version 2.22.0 or higher.
### Configuration or environment issues
Another reason your project might fail to start is because your configuration file is defined incorrectly, or you are missing required environment variables.
## How does interrupt work?
When you select the `Interrupts` dropdown and select a node to interrupt the graph will pause execution before and after (unless the node goes straight to `END`) that node has run. This means that you will be able to both edit the state before the node is ran and the state after the node has ran. This is intended to allow developers more fine-grained control over the behavior of a node and make it easier to observe how the node is behaving. You will not be able to edit the state after the node has ran if the node is the final node in the graph.
## How do I reload the app?
If you would like to reload the app, don't use Command+R as you might normally do. Instead, close and reopen the app for a full refresh.
## How does automatic rebuilding work?
One of the key features of LangGraph Studio is that it automatically rebuilds your image when you change the source code. This allows for a super fast development and testing cycle which makes it easy to iterate on your graph. There are two different ways that LangGraph rebuilds your image: either by editing the image or completely rebuilding it.
### Rebuilds from source code changes
If you modified the source code only (no configuration or dependency changes!) then the image does not require a full rebuild, and LangGraph Studio will only update the relevant parts. The UI status in the bottom left will switch from `Online` to `Stopping` temporarily while the image gets edited. The logs will be shown as this process is happening, and after the image has been edited the status will change back to `Online` and you will be able to run your graph with the modified code!
### Rebuilds from configuration or dependency changes
If you edit your graph configuration file (`langgraph.json`) or the dependencies (either `pyproject.toml` or `requirements.txt`) then the entire image will be rebuilt. This will cause the UI to switch away from the graph view and start showing the logs of the new image building process. This can take a minute or two, and once it is done your updated image will be ready to use!
## Why is my graph taking so long to startup?
The LangGraph Studio interacts with a local LangGraph API server. To stay aligned with ongoing updates, the LangGraph API requires regular rebuilding. As a result, you may occasionally experience slight delays when starting up your project.
## Why are extra edges showing up in my graph?
If you don't define your conditional edges carefully, you might notice extra edges appearing in your graph. This is because without proper definition, LangGraph Studio assumes the conditional edge could access all other nodes. In order for this to not be the case, you need to be explicit about how you define the nodes the conditional edge routes to. There are two ways you can do this:
### Solution 1: Include a path map
The first way to solve this is to add path maps to your conditional edges. A path map is just a dictionary that maps the possible outputs of your router function with the names of the nodes that each output corresponds to. The path map is passed as the third argument to the `add_conditional_edges` function like so:
```python
graph.add_conditional_edges("node_a", routing_function, {True: "node_b", False: "node_c"})
```
In this case, the routing function returns either True or False, which map to `node_b` and `node_c` respectively.
### Solution 2: Update the typing of the router
Instead of passing a path map, you can also be explicit about the typing of your routing function by specifying the nodes it can map to using the `Literal` python definition. Here is an example of how to define a routing function in that way:
```python
def routing_function(state: GraphState) -> Literal["node_b","node_c"]:
if state['some_condition'] == True:
return "node_a"
else:
return "node_b"
```
@@ -0,0 +1,200 @@
# Check the Status of your Threads
## Setup
To start, we can setup our client with whatever URL you are hosting your graph from:
### SDK initialization
First, we need to setup our client so that we can communicate with our hosted graph:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = agent;
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
## Find idle threads
We can use the following commands to find threads that are idle, which means that all runs executed on the thread have finished running:
=== "Python"
```python
print(await client.threads.search(status="idle",limit=1))
```
=== "Javascript"
```js
console.log(await client.threads.search({status: "idle",limit:1}));
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/search \
--header 'Content-Type: application/json' \
--data '{"status": "idle", "limit": 1}'
```
Output:
[{'thread_id': 'cacf79bb-4248-4d01-aabc-938dbd60ed2c',
'created_at': '2024-08-14T17:36:38.921660+00:00',
'updated_at': '2024-08-14T17:36:38.921660+00:00',
'metadata': {'graph_id': 'agent'},
'status': 'idle',
'config': {'configurable': {}}}]
## Find interrupted threads
We can use the following commands to find threads that have been interrupted in the middle of a run, which could either mean an error occurred before the run finished or a human-in-the-loop breakpoint was reached and the run is waiting to continue:
=== "Python"
```python
print(await client.threads.search(status="interrupted",limit=1))
```
=== "Javascript"
```js
console.log(await client.threads.search({status: "interrupted",limit:1}));
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/search \
--header 'Content-Type: application/json' \
--data '{"status": "interrupted", "limit": 1}'
```
Output:
[{'thread_id': '0d282b22-bbd5-4d95-9c61-04dcc2e302a5',
'created_at': '2024-08-14T17:41:50.235455+00:00',
'updated_at': '2024-08-14T17:41:50.235455+00:00',
'metadata': {'graph_id': 'agent'},
'status': 'interrupted',
'config': {'configurable': {}}}]
## Find busy threads
We can use the following commands to find threads that are busy, meaning they are currently handling the execution of a run:
=== "Python"
```python
print(await client.threads.search(status="busy",limit=1))
```
=== "Javascript"
```js
console.log(await client.threads.search({status: "busy",limit: 1}));
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/search \
--header 'Content-Type: application/json' \
--data '{"status": "busy", "limit": 1}'
```
Output:
[{'thread_id': '0d282b22-bbd5-4d95-9c61-04dcc2e302a5',
'created_at': '2024-08-14T17:41:50.235455+00:00',
'updated_at': '2024-08-14T17:41:50.235455+00:00',
'metadata': {'graph_id': 'agent'},
'status': 'busy',
'config': {'configurable': {}}}]
## Find specific threads
You may also want to check the status of specific threads, which you can do in a few ways:
### Find by ID
You can use the `get` function to find the status of a specific thread, as long as you have the ID saved
=== "Python"
```python
print((await client.threads.get(<THREAD_ID>))['status'])
```
=== "Javascript"
```js
console.log((await client.threads.get(<THREAD_ID>)).status);
```
=== "CURL"
```bash
curl --request GET \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID> \
--header 'Content-Type: application/json' | jq -r '.status'
```
Output:
'idle'
### Find by metadata
The search endpoint for threads also allows you to filter on metadata, which can be helpful if you use metadata to tag threads in order to keep them organized:
=== "Python"
```python
print((await client.threads.search(metadata={"foo":"bar"},limit=1))[0]['status'])
```
=== "Javascript"
```js
console.log((await client.threads.search({metadata: {"foo":"bar"},limit: 1}))[0].status);
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/search \
--header 'Content-Type: application/json' \
--data '{"metadata": {"foo":"bar"}, "limit": 1}' | jq -r '.[0].status'
```
Output:
'idle'
Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

+132
View File
@@ -0,0 +1,132 @@
# Copying Threads
You may wish to copy (i.e. "fork") an existing thread in order to keep the existing thread's history and create independent runs that do not affect the original thread. This guide shows how you can do that.
## 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).
### SDK initialization
First, we need to setup our client so that we can communicate with our hosted graph:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url="<DEPLOYMENT_URL>")
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl:"<DEPLOYMENT_URL>" });
const assistantId = agent;
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json' \
--data '{
"metadata": {}
}'
```
## Copying a thread
The code below assumes that a thread you'd like to copy already exists.
Copying a thread will create a new thread with the same history as the existing thread, and then allow you to continue executing runs.
### Create copy
=== "Python"
```python
copied_thread = await client.threads.copy(<THREAD_ID>)
```
=== "Javascript"
```js
let copiedThread = await client.threads.copy(<THREAD_ID>);
```
=== "CURL"
```bash
curl --request POST --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/copy \
--header 'Content-Type: application/json'
```
### Verify copy
We can verify that the history from the prior thread did indeed copy over correctly:
=== "Python"
```python
def remove_thread_id(d):
if 'metadata' in d and 'thread_id' in d['metadata']:
del d['metadata']['thread_id']
return d
original_thread_history = list(map(remove_thread_id,await client.threads.get_history(<THREAD_ID>)))
copied_thread_history = list(map(remove_thread_id,await client.threads.get_history(copied_thread['thread_id'])))
# Compare the two histories
assert original_thread_history == copied_thread_history
# if we made it here the assertion passed!
print("The histories are the same.")
```
=== "Javascript"
```js
function removeThreadId(d) {
if (d.metadata && d.metadata.thread_id) {
delete d.metadata.thread_id;
}
return d;
}
// Assuming `client.threads.getHistory(threadId)` is an async function that returns a list of dicts
async function compareThreadHistories(threadId, copiedThreadId) {
const originalThreadHistory = (await client.threads.getHistory(threadId)).map(removeThreadId);
const copiedThreadHistory = (await client.threads.getHistory(copiedThreadId)).map(removeThreadId);
// Compare the two histories
console.assert(JSON.stringify(originalThreadHistory) === JSON.stringify(copiedThreadHistory))
// if we made it here the assertion passed!
console.log("The histories are the same.");
}
// Example usage
compareThreadHistories(<THREAD_ID>, copiedThread.thread_id);
```
=== "CURL"
```bash
if diff <(
curl --request GET --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/history | jq -S 'map(del(.metadata.thread_id))'
) <(
curl --request GET --url <DEPLOYMENT_URL>/threads/<COPIED_THREAD_ID>/history | jq -S 'map(del(.metadata.thread_id))'
) >/dev/null; then
echo "The histories are the same."
else
echo "The histories are different."
fi
```
Output:
The histories are the same.
@@ -0,0 +1,183 @@
## 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).
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.
First, we will define a quick helper function for printing out JS model outputs (you can skip this if using Python):
```js
function prettyPrint(m) {
const padded = " " + m['type'] + " ";
const sepLen = Math.floor((80 - padded.length) / 2);
const sep = "=".repeat(sepLen);
const secondSep = sep + (padded.length % 2 ? "=" : "");
console.log(`${sep}${padded}${secondSep}`);
console.log("\n\n");
console.log(m.content);
}
```
Then, let's import our required packages and instantiate our client, assistant, and thread.
=== "Python"
```python
import asyncio
import httpx
from langchain_core.messages import convert_to_messages
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent";
const thread = await client.threads.create();
```
Now let's start two runs, with the second interrupting the first one with a multitask strategy of "enqueue":
=== "Python"
```python
first_run = await client.runs.create(
thread["thread_id"],
assistant_id,
input={"messages": [{"role": "human", "content": "what's the weather in sf?"}]},
)
second_run = await client.runs.create(
thread["thread_id"],
assistant_id,
input={"messages": [{"role": "human", "content": "what's the weather in nyc?"}]},
multitask_strategy="enqueue",
)
```
=== "Javascript"
```js
const firstRun = await client.runs.create(
thread["thread_id"],
assistantId,
input={"messages": [{"role": "human", "content": "what's the weather in sf?"}]},
)
const secondRun = await client.runs.create(
thread["thread_id"],
assistantId,
input={"messages": [{"role": "human", "content": "what's the weather in nyc?"}]},
multitask_strategy="enqueue",
)
```
Verify that the thread has data from both runs:
=== "Python"
```python
# wait until the second run completes
await client.runs.join(thread["thread_id"], second_run["run_id"])
state = await client.threads.get_state(thread["thread_id"])
for m in convert_to_messages(state["values"]["messages"]):
m.pretty_print()
```
=== "Javascript"
```js
await client.runs.join(thread["thread_id"], secondRun["run_id"]);
const state = await client.threads.getState(thread["thread_id"]);
for (const m of state["values"]["messages"]) {
prettyPrint(m);
}
```
Output:
================================ Human Message =================================
what's the weather in sf?
================================== Ai Message ==================================
[{'id': 'toolu_01Dez1sJre4oA2Y7NsKJV6VT', 'input': {'query': 'weather in san francisco'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_01Dez1sJre4oA2Y7NsKJV6VT)
Call ID: toolu_01Dez1sJre4oA2Y7NsKJV6VT
Args:
query: weather in san francisco
================================= Tool Message =================================
Name: tavily_search_results_json
[{"url": "https://www.accuweather.com/en/us/san-francisco/94103/weather-forecast/347629", "content": "Get the current and future weather conditions for San Francisco, CA, including temperature, precipitation, wind, air quality and more. See the hourly and 10-day outlook, radar maps, alerts and allergy information."}]
================================== Ai Message ==================================
According to AccuWeather, the current weather conditions in San Francisco are:
Temperature: 57°F (14°C)
Conditions: Mostly Sunny
Wind: WSW 10 mph
Humidity: 72%
The forecast for the next few days shows partly sunny skies with highs in the upper 50s to mid 60s F (14-18°C) and lows in the upper 40s to low 50s F (9-11°C). Typical mild, dry weather for San Francisco this time of year.
Some key details from the AccuWeather forecast:
Today: Mostly sunny, high of 62°F (17°C)
Tonight: Partly cloudy, low of 49°F (9°C)
Tomorrow: Partly sunny, high of 59°F (15°C)
Saturday: Mostly sunny, high of 64°F (18°C)
Sunday: Partly sunny, high of 61°F (16°C)
So in summary, expect seasonable spring weather in San Francisco over the next several days, with a mix of sun and clouds and temperatures ranging from the upper 40s at night to the low 60s during the days. Typical dry conditions with no rain in the forecast.
================================ Human Message =================================
what's the weather in nyc?
================================== Ai Message ==================================
[{'text': 'Here are the current weather conditions and forecast for New York City:', 'type': 'text'}, {'id': 'toolu_01FFft5Sx9oS6AdVJuRWWcGp', 'input': {'query': 'weather in new york city'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_01FFft5Sx9oS6AdVJuRWWcGp)
Call ID: toolu_01FFft5Sx9oS6AdVJuRWWcGp
Args:
query: weather in new york city
================================= Tool Message =================================
Name: tavily_search_results_json
[{"url": "https://www.weatherapi.com/", "content": "{'location': {'name': 'New York', 'region': 'New York', 'country': 'United States of America', 'lat': 40.71, 'lon': -74.01, 'tz_id': 'America/New_York', 'localtime_epoch': 1718734479, 'localtime': '2024-06-18 14:14'}, 'current': {'last_updated_epoch': 1718733600, 'last_updated': '2024-06-18 14:00', 'temp_c': 29.4, 'temp_f': 84.9, 'is_day': 1, 'condition': {'text': 'Sunny', 'icon': '//cdn.weatherapi.com/weather/64x64/day/113.png', 'code': 1000}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 158, 'wind_dir': 'SSE', 'pressure_mb': 1025.0, 'pressure_in': 30.26, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 63, 'cloud': 0, 'feelslike_c': 31.3, 'feelslike_f': 88.3, 'windchill_c': 28.3, 'windchill_f': 82.9, 'heatindex_c': 29.6, 'heatindex_f': 85.3, 'dewpoint_c': 18.4, 'dewpoint_f': 65.2, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 7.0, 'gust_mph': 16.5, 'gust_kph': 26.5}}"}]
================================== Ai Message ==================================
According to the weather data from WeatherAPI:
Current Conditions in New York City (as of 2:00 PM local time):
- Temperature: 85°F (29°C)
- Conditions: Sunny
- Wind: 2 mph (4 km/h) from the SSE
- Humidity: 63%
- Heat Index: 85°F (30°C)
The forecast shows sunny and warm conditions persisting over the next few days:
Today: Sunny, high of 85°F (29°C)
Tonight: Clear, low of 68°F (20°C)
Tomorrow: Sunny, high of 88°F (31°C)
Thursday: Mostly sunny, high of 90°F (32°C)
Friday: Partly cloudy, high of 87°F (31°C)
So New York City is experiencing beautiful sunny weather with seasonably warm temperatures in the mid-to-upper 80s Fahrenheit (around 30°C). Humidity is moderate in the 60% range. Overall, ideal late spring/early summer conditions for being outdoors in the city over the next several days.
@@ -0,0 +1,147 @@
# How to Add Breakpoints
When creating LangGraph agents, it is often nice to add a human-in-the-loop component.
This can be helpful when giving them access to tools.
Often in these situations you may want to manually approve an action before taking.
This can be in several ways, but the primary supported way is to add an "interrupt" before a node is executed.
This interrupts execution at that node.
You can then resume from that spot to continue.
## Setup
### Code for your graph
In this how-to we use a simple ReAct style hosted graph (you can see the full code for defining it [here](../../how-tos/human_in_the_loop/breakpoints.ipynb)). The important thing is that there are two nodes (one named `agent` that calls the LLM, and one named `action` that calls the tool), and a routing function from `agent` that determines whether to call `action` next or just end the graph run (the `action` node always calls the `agent` node after execution).
### SDK Initialization
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent"
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
## Adding a breakpoint
We now want to add a breakpoint in our graph run, which we will do before a tool is called.
We can do this by adding `interrupt_before=["action"]`, which tells us to interrupt before calling the action node.
We can do this either when compiling the graph or when kicking off a run.
Here we will do it when kicking of a run, if you would like to to do it at compile time you need to edit the python file where your graph is defined and add the `interrupt_before` parameter when you call `.compile`.
First let's access our hosted LangGraph instance through the SDK:
And, now let's compile it with a breakpoint before the tool node:
=== "Python"
```python
input = {"messages": [{"role": "human", "content": "what's the weather in sf"}]}
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id,
input=input,
stream_mode="updates",
interrupt_before=["action"],
):
print(f"Receiving new event of type: {chunk.event}...")
print(chunk.data)
print("\n\n")
```
=== "Javascript"
```js
const input = { "messages": [{ "role": "human", "content": "what's the weather in sf"}] }
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "updates",
interruptBefore: ["action"],
}
);
for await (const chunk of streamResponse) {
console.log(`Receiving new event of type: ${chunk.event}...`);
console.log(chunk.data);
console.log("\n\n");
}
```
=== "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\"}]},
\"interrupt_before\": [\"action\"],
\"stream_mode\": [
\"messages\"
]
}" | \
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:
Receiving new event of type: metadata...
{'run_id': '3b77ef83-687a-4840-8858-0371f91a92c3'}
Receiving new event of type: data...
{'agent': {'messages': [{'content': [{'id': 'toolu_01HwZqM1ptX6E15A5LAmyZTB', 'input': {'query': 'weather in san francisco'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-e5d17791-4d37-4ad2-815f-a0c4cba62585', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in san francisco'}, 'id': 'toolu_01HwZqM1ptX6E15A5LAmyZTB'}], 'invalid_tool_calls': []}]}}
Receiving new event of type: end...
None
@@ -0,0 +1,272 @@
# How to Edit State of a Deployed Graph
When creating LangGraph agents, it is often nice to add a human-in-the-loop component. This can be helpful when giving them access to tools. Often in these situations you may want to edit the graph state before continuing (for example, to edit what tool is being called, or how it is being called).
This can be in several ways, but the primary supported way is to add an "interrupt" before a node is executed. This interrupts execution at that node. You can then use update_state to update the state, and then resume from that spot to continue.
## 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.
### SDK initialization
First, we need to setup our client so that we can communicate with our hosted graph:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent";
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
## Editing state
### Initial invocation
Now let's invoke our graph, making sure to interrupt before the `action` node.
=== "Python"
```python
input = { 'messages':[{ "role":"user", "content":"search for weather in SF" }] }
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id,
input=input,
stream_mode="updates",
interrupt_before=["action"],
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const input = {"messages": [{ "role": "human", "content": "search for weather in SF"}] }
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "updates",
interruptBefore: ["action"],
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
=== "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\": \"search for weather in SF\"}]},
\"interrupt_before\": [\"action\"],
\"stream_mode\": [
\"updates\"
]
}" | \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
sub(/^event: /, "", $0)
event_type = $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
}
'
```
Output:
{'agent': {'messages': [{'content': [{'text': "Certainly! I'll search for the current weather in San Francisco for you using the search function. Here's how I'll do that:", 'type': 'text'}, {'id': 'toolu_01KEJMBFozSiZoS4mAcPZeqQ', 'input': {'query': 'current weather in San Francisco'}, 'name': 'search', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-6dbb0167-f8f6-4e2a-ab68-229b2d1fbb64', 'example': False, 'tool_calls': [{'name': 'search', 'args': {'query': 'current weather in San Francisco'}, 'id': 'toolu_01KEJMBFozSiZoS4mAcPZeqQ'}], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
### Edit the state
Now, let's assume we actually meant to search for the weather in Sidi Frej (another city with the initials SF). We can edit the state to properly reflect that:
=== "Python"
```python
# First, lets get the current state
current_state = await client.threads.get_state(thread['thread_id'])
# Let's now get the last message in the state
# This is the one with the tool calls that we want to update
last_message = current_state['values']['messages'][-1]
# Let's now update the args for that tool call
last_message['tool_calls'][0]['args'] = {'query': 'current weather in Sidi Frej'}
# Let's now call `update_state` to pass in this message in the `messages` key
# This will get treated as any other update to the state
# It will get passed to the reducer function for the `messages` key
# That reducer function will use the ID of the message to update it
# It's important that it has the right ID! Otherwise it would get appended
# as a new message
await client.threads.update_state(thread['thread_id'], {"messages": last_message})
```
=== "Javascript"
```js
// First, lets get the current state
const currentState = await client.threads.getState(thread['thread_id']);
// Let's now get the last message in the state
// This is the one with the tool calls that we want to update
let lastMessage = currentState['values']['messages'][-1];
// Let's now update the args for that tool call
lastMessage['tool_calls'][0]['args'] = {'query': 'current weather in Sidi Frej'};
// Let's now call `update_state` to pass in this message in the `messages` key
// This will get treated as any other update to the state
// It will get passed to the reducer function for the `messages` key
// That reducer function will use the ID of the message to update it
// It's important that it has the right ID! Otherwise it would get appended
// as a new message
await client.threads.updateState(thread['thread_id'], {values:{"messages": lastMessage}});
```
=== "CURL"
```bash
curl --request GET --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state | \
jq '.values.messages[-1] | (.tool_calls[0].args = {"query": "current weather in Sidi Frej"})' | \
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state \
--header 'Content-Type: application/json' \
--data @-
```
Output:
{'configurable': {'thread_id': '9c8f1a43-9dd8-4017-9271-2c53e57cf66a',
'checkpoint_ns': '',
'checkpoint_id': '1ef58e7e-3641-649f-8002-8b4305a64858'}}
### Resume invocation
Now we can resume our graph run but with the updated state:
=== "Python"
```python
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id,
input=None,
stream_mode="updates",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: null,
streamMode: "updates",
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": \"agent\",
\"stream_mode\": [
\"updates\"
]
}"| \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
sub(/^event: /, "", $0)
event_type = $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
}
'
```
Output:
{'action': {'messages': [{'content': '["I looked up: current weather in Sidi Frej. Result: It\'s sunny in San Francisco, but you better look out if you\'re a Gemini 😈."]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'search', 'id': '1161b8d1-bee4-4188-9be8-698aecb69f10', 'tool_call_id': 'toolu_01KEJMBFozSiZoS4mAcPZeqQ'}]}}
{'agent': {'messages': [{'content': [{'text': 'I apologize for the confusion in my search query. It seems the search function interpreted "SF" as "Sidi Frej" instead of "San Francisco" as we intended. Let me search again with the full city name to get the correct information:', 'type': 'text'}, {'id': 'toolu_0111rrwgfAcmurHZn55qjqTR', 'input': {'query': 'current weather in San Francisco'}, 'name': 'search', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-b8c25779-cfb4-46fc-a421-48553551242f', 'example': False, 'tool_calls': [{'name': 'search', 'args': {'query': 'current weather in San Francisco'}, 'id': 'toolu_0111rrwgfAcmurHZn55qjqTR'}], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
{'action': {'messages': [{'content': '["I looked up: current weather in San Francisco. Result: It\'s sunny in San Francisco, but you better look out if you\'re a Gemini 😈."]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'search', 'id': '6bc632ae-5ee6-4d01-9532-79c524a2d443', 'tool_call_id': 'toolu_0111rrwgfAcmurHZn55qjqTR'}]}}
{'agent': {'messages': [{'content': "Now, based on the search results, I can provide you with information about the current weather in San Francisco:\n\nThe weather in San Francisco is currently sunny. \n\nIt's worth noting that the search result included an unusual comment about Gemini, which doesn't seem directly related to the weather. This might be due to the search engine including some astrological information or a joke in its results. However, for the purpose of weather information, we can focus on the fact that it's sunny in San Francisco right now.\n\nIs there anything else you'd like to know about the weather in San Francisco or any other location?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-227a042b-dd97-476e-af32-76a3703af5d8', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
As you can see it now looks up the current weather in Sidi Frej (although our dummy search node still returns results for SF because we don't actually do a search in this example, we just return the same "It's sunny in San Francisco ..." result every time).
@@ -0,0 +1,575 @@
# Review Tool Calls
Human-in-the-loop (HIL) interactions are crucial for [agentic systems](https://langchain-ai.github.io/langgraph/concepts/agentic_concepts/#human-in-the-loop). A common pattern is to add some human in the loop step after certain tool calls. These tool calls often lead to either a function call or saving of some information. Examples include:
- A tool call to execute SQL, which will then be run by the tool
- A tool call to generate a summary, which will then be saved to the State of the graph
Note that using tool calls is common **whether actually calling tools or not**.
There are typically a few different interactions you may want to do here:
1. Approve the tool call and continue
2. Modify the tool call manually and then continue
3. Give natural language feedback, and then pass that back to the agent instead of continuing
We can implement this in LangGraph using a [breakpoint](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/breakpoints/): breakpoints allow us to interrupt graph execution before a specific step. At this breakpoint, we can manually update the graph state taking one of the three options above
## 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/review-tool-calls.ipynb#simple-usage) if you want to. Once this graph is hosted, we are ready to invoke it and wait for user input.
### SDK initialization
First, we need to setup our client so that we can communicate with our hosted graph:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent";
const thread = await client.threads.create();
```
## Example with no review
Let's look at an example when no review is required (because no tools are called)
=== "Python"
```python
input = { 'messages':[{ "role":"user", "content":"hi!" }] }
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id,
input=input,
stream_mode="updates",
interrupt_before=["action"],
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const input = {"messages": [{ "role": "human", "content": "hi!"}] }
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "updates",
interruptBefore: ["action"],
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
{'messages': [{'content': 'hi!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '39c51f14-2d5c-4690-883a-d940854b1845', 'example': False}]}
{'messages': [{'content': 'hi!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '39c51f14-2d5c-4690-883a-d940854b1845', 'example': False}, {'content': [{'text': "Hello! Welcome. How can I assist you today? Is there anything specific you'd like to know or any information you're looking for?", 'type': 'text', 'index': 0}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'end_turn', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-d65e07fb-43ff-4d98-ab6b-6316191b9c8b', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 355, 'output_tokens': 31, 'total_tokens': 386}}]}
If we check the state, we can see that it is finished
=== "Python"
```python
state = await client.threads.get_state(thread["thread_id"])
print(state['next'])
```
=== "Javascript"
```js
const state = await client.threads.getState(thread["thread_id"]);
console.log(state.next);
```
Output:
[]
## Example of approving tool
Let's now look at what it looks like to approve a tool call. Note that we don't need to pass an interrupt to our streaming calls because the graph (defined [here](../../how-tos/human_in_the_loop/review-tool-calls.ipynb#simple-usage)) was already compiled with an interrupt before the `human_review_node`.
=== "Python"
```python
input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]}
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=input,
stream_mode="values",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]}
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "values",
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '54e19d6e-89fa-44fb-b92c-12e7dd4ddf08', 'example': False}]}
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '54e19d6e-89fa-44fb-b92c-12e7dd4ddf08', 'example': False}, {'content': [{'text': "Certainly! I can help you check the weather in San Francisco. To get this information, I'll use the weather search function. Let me do that for you right away.", 'type': 'text', 'index': 0}, {'id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-45a6b6c3-ac69-42a4-8957-d982203d6392', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 90, 'total_tokens': 450}}]}
If we now check, we can see that it is waiting on human review:
=== "Python"
```python
state = await client.threads.get_state(thread["thread_id"])
print(state['next'])
```
=== "Javascript"
```js
const state = await client.threads.getState(thread["thread_id"]);
console.log(state.next);
```
Output:
['human_review_node']
To approve the tool call, we can just continue the thread with no edits. To do this, we just create a new run with no inputs.
=== "Python"
```python
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=None,
stream_mode="values",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: undefined,
streamMode: "values",
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '54e19d6e-89fa-44fb-b92c-12e7dd4ddf08', 'example': False}, {'content': [{'text': "Certainly! I can help you check the weather in San Francisco. To get this information, I'll use the weather search function. Let me do that for you right away.", 'type': 'text', 'index': 0}, {'id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-45a6b6c3-ac69-42a4-8957-d982203d6392', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 90, 'total_tokens': 450}}, {'content': 'Sunny!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '826cd0f2-9cc6-46f0-b7df-daa6a05d13d2', 'tool_call_id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'artifact': None, 'status': 'success'}]}
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '54e19d6e-89fa-44fb-b92c-12e7dd4ddf08', 'example': False}, {'content': [{'text': "Certainly! I can help you check the weather in San Francisco. To get this information, I'll use the weather search function. Let me do that for you right away.", 'type': 'text', 'index': 0}, {'id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-45a6b6c3-ac69-42a4-8957-d982203d6392', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 90, 'total_tokens': 450}}, {'content': 'Sunny!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '826cd0f2-9cc6-46f0-b7df-daa6a05d13d2', 'tool_call_id': 'toolu_015yrR3GMDXe6X8m2p9CsEDN', 'artifact': None, 'status': 'success'}, {'content': [{'text': "\n\nGreat news! The weather in San Francisco is sunny today. It's a beautiful day in the city by the bay. Is there anything else you'd like to know about the weather or any other information I can help you with?", 'type': 'text', 'index': 0}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'end_turn', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-5d5fd0f1-a939-447e-801a-9aaa812322d3', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 464, 'output_tokens': 50, 'total_tokens': 514}}]}
## Edit Tool Call
Let's now say we want to edit the tool call. E.g. change some of the parameters (or even the tool called!) but then execute that tool.
=== "Python"
```python
input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]}
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=input,
stream_mode="values",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]}
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "values",
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'cec11391-84da-464b-bd2a-bd4f0d93b9ee', 'example': False}]}
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'cec11391-84da-464b-bd2a-bd4f0d93b9ee', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01SunSpDurNfcnXppWLPrtjC', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-6326da9f-6061-4e12-8586-482e32ab4cab', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01SunSpDurNfcnXppWLPrtjC', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}}]}
To do this, we first need to update the state. We can do this by passing a message in with the **same** id of the message we want to overwrite. This will have the effect of **replacing** that old message. Note that this is only possible because of the **reducer** we are using that replaces messages with the same ID - read more about that [here](https://langchain-ai.github.io/langgraph/concepts/low_level/#working-with-messages-in-graph-state).
=== "Python"
```python
# To get the ID of the message we want to replace, we need to fetch the current state and find it there.
state = await client.threads.get_state(thread['thread_id'])
print("Current State:")
print(state['values'])
print("\nCurrent Tool Call ID:")
current_content = state['values']['messages'][-1]['content']
current_id = state['values']['messages'][-1]['id']
tool_call_id = state['values']['messages'][-1]['tool_calls'][0]['id']
print(tool_call_id)
# We now need to construct a replacement tool call.
# We will change the argument to be `San Francisco, USA`
# Note that we could change any number of arguments or tool names - it just has to be a valid one
new_message = {
"role": "assistant",
"content": current_content,
"tool_calls": [
{
"id": tool_call_id,
"name": "weather_search",
"args": {"city": "San Francisco, USA"}
}
],
# This is important - this needs to be the same as the message you replacing!
# Otherwise, it will show up as a separate message
"id": current_id
}
await client.threads.update_state(
# This is the config which represents this thread
thread['thread_id'],
# This is the updated value we want to push
{"messages": [new_message]},
# We push this update acting as our human_review_node
as_node="human_review_node"
)
print("\nResuming Execution")
# Let's now continue executing from here
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=None,
stream_mode="values",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const state = await client.threads.getState(thread.thread_id);
console.log("Current State:");
console.log(state.values);
console.log("\nCurrent Tool Call ID:");
const lastMessage = state.values.messages[state.values.messages.length - 1];
const currentContent = lastMessage.content;
const currentId = lastMessage.id;
const toolCallId = lastMessage.tool_calls[0].id;
console.log(toolCallId);
// Construct a replacement tool call
const newMessage = {
role: "assistant",
content: currentContent,
tool_calls: [
{
id: toolCallId,
name: "weather_search",
args: { city: "San Francisco, USA" }
}
],
// Ensure the ID is the same as the message you're replacing
id: currentId
};
await client.threads.updateState(
thread.thread_id, // Thread ID
{
values: { "messages": [newMessage] }, // Updated message
asNode: "human_review_node"
} // Acting as human_review_node
);
console.log("\nResuming Execution");
// Continue executing from here
const streamResponseResumed = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: undefined,
streamMode: "values",
interruptBefore: ["action"],
}
);
for await (const chunk of streamResponseResumed) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
Current State:
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '8713d1fa-9b26-4eab-b768-dafdaac70590', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-ede13f26-daf5-4d8f-817a-7611075bbcf1', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}}]}
Current Tool Call ID:
toolu_01VzagzsUGZsNMwW1wHkcw7h
Resuming Execution
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '8713d1fa-9b26-4eab-b768-dafdaac70590', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ede13f26-daf5-4d8f-817a-7611075bbcf1', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'Sunny!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '7fc7d463-66bf-4555-9929-6af483de169b', 'tool_call_id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'artifact': None, 'status': 'success'}]}
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '8713d1fa-9b26-4eab-b768-dafdaac70590', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ede13f26-daf5-4d8f-817a-7611075bbcf1', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'Sunny!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '7fc7d463-66bf-4555-9929-6af483de169b', 'tool_call_id': 'toolu_01VzagzsUGZsNMwW1wHkcw7h', 'artifact': None, 'status': 'success'}, {'content': [{'text': "\n\nBased on the search result, the weather in San Francisco is sunny! It's a beautiful day in the city by the bay. Is there anything else you'd like to know about the weather or any other information I can help you with?", 'type': 'text', 'index': 0}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'end_turn', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-d90ce97a-39f9-4330-985e-67c5f351a0c5', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 455, 'output_tokens': 52, 'total_tokens': 507}}]}
## Give feedback to a tool call
Sometimes, you may not want to execute a tool call, but you also may not want to ask the user to manually modify the tool call. In that case it may be better to get natural language feedback from the user. You can then insert these feedback as a mock **RESULT** of the tool call.
There are multiple ways to do this:
You could add a new message to the state (representing the "result" of a tool call)
You could add TWO new messages to the state - one representing an "error" from the tool call, other HumanMessage representing the feedback
Both are similar in that they involve adding messages to the state. The main difference lies in the logic AFTER the `human_node` and how it handles different types of messages.
For this example we will just add a single tool call representing the feedback. Let's see this in action!
=== "Python"
```python
input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]}
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=input,
stream_mode="values",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]}
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "values",
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c80f13d0-674d-4233-b6a0-3940509d3cf3', 'example': False}]}
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c80f13d0-674d-4233-b6a0-3940509d3cf3', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_016XyTdFA8NuPWeLyZPSzoM3', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-4911ac27-3d7c-4edf-a3ca-c2908e3922eb', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_016XyTdFA8NuPWeLyZPSzoM3', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}}]}
To do this, we first need to update the state. We can do this by passing a message in with the same **tool call id** of the tool call we want to respond to. Note that this is a **different*** ID from above
=== "Python"
```python
# To get the ID of the message we want to replace, we need to fetch the current state and find it there.
state = await client.threads.get_state(thread['thread_id'])
print("Current State:")
print(state['values'])
print("\nCurrent Tool Call ID:")
tool_call_id = state['values']['messages'][-1]['tool_calls'][0]['id']
print(tool_call_id)
# We now need to construct a replacement tool call.
# We will change the argument to be `San Francisco, USA`
# Note that we could change any number of arguments or tool names - it just has to be a valid one
new_message = {
"role": "tool",
# This is our natural language feedback
"content": "User requested changes: pass in the country as well",
"name": "weather_search",
"tool_call_id": tool_call_id
}
await client.threads.update_state(
# This is the config which represents this thread
thread['thread_id'],
# This is the updated value we want to push
{"messages": [new_message]},
# We push this update acting as our human_review_node
as_node="human_review_node"
)
print("\nResuming execution")
# Let's now continue executing from here
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=None,
stream_mode="values",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const state = await client.threads.getState(thread.thread_id);
console.log("Current State:");
console.log(state.values);
console.log("\nCurrent Tool Call ID:");
const lastMessage = state.values.messages[state.values.messages.length - 1];
const toolCallId = lastMessage.tool_calls[0].id;
console.log(toolCallId);
// Construct a replacement tool call
const newMessage = {
role: "tool",
content: "User requested changes: pass in the country as well",
name: "weather_search",
tool_call_id: toolCallId,
};
await client.threads.updateState(
thread.thread_id, // Thread ID
{
values: { "messages": [newMessage] }, // Updated message
asNode: "human_review_node"
} // Acting as human_review_node
);
console.log("\nResuming Execution");
// Continue executing from here
const streamResponseEdited = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: undefined,
streamMode: "values",
interruptBefore: ["action"],
}
);
for await (const chunk of streamResponseEdited) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
Current State:
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '3b2bbc38-d11b-49eb-80c0-c24a40dab5a8', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-c5a50900-abf5-4885-9cdb-da2bf0d892ac', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}}]}
Current Tool Call ID:
toolu_01NNw18j57GEGPZvsa9f1wvX
Resuming execution
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '3b2bbc38-d11b-49eb-80c0-c24a40dab5a8', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-c5a50900-abf5-4885-9cdb-da2bf0d892ac', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}}, {'content': 'User requested changes: pass in the country as well', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '787288be-213c-4fd3-8503-4a009bdb1b00', 'tool_call_id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'artifact': None, 'status': 'success'}, {'content': [{'text': '\n\nI apologize for the oversight. It seems the function requires additional information. Let me try again with a more specific request.', 'type': 'text', 'index': 0}, {'id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco, USA"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-5c355a56-cfe3-4046-b49f-f5b09fc397ef', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 461, 'output_tokens': 83, 'total_tokens': 544}}]}
We can see that we now get to another breakpoint - because it went back to the model and got an entirely new prediction of what to call. Let's now approve this one and continue
=== "Python"
```python
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=None,
stream_mode="values",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const streamResponseResumed = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: undefined,
streamMode: "values",
}
);
for await (const chunk of streamResponseResumed) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
Output:
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '3b2bbc38-d11b-49eb-80c0-c24a40dab5a8', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-c5a50900-abf5-4885-9cdb-da2bf0d892ac', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}}, {'content': 'User requested changes: pass in the country as well', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '787288be-213c-4fd3-8503-4a009bdb1b00', 'tool_call_id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'artifact': None, 'status': 'success'}, {'content': [{'text': '\n\nI apologize for the oversight. It seems the function requires additional information. Let me try again with a more specific request.', 'type': 'text', 'index': 0}, {'id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco, USA"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-5c355a56-cfe3-4046-b49f-f5b09fc397ef', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 461, 'output_tokens': 83, 'total_tokens': 544}}, {'content': 'Sunny!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '3b857482-bca2-4a73-a9ab-1f35a3e43e5f', 'tool_call_id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'artifact': None, 'status': 'success'}]}
{'messages': [{'content': "what's the weather in sf?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '3b2bbc38-d11b-49eb-80c0-c24a40dab5a8', 'example': False}, {'content': [{'text': 'To get the weather information for San Francisco, I can use the weather_search function. Let me do that for you.', 'type': 'text', 'index': 0}, {'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-c5a50900-abf5-4885-9cdb-da2bf0d892ac', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco'}, 'id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 360, 'output_tokens': 80, 'total_tokens': 440}}, {'content': 'User requested changes: pass in the country as well', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '787288be-213c-4fd3-8503-4a009bdb1b00', 'tool_call_id': 'toolu_01NNw18j57GEGPZvsa9f1wvX', 'artifact': None, 'status': 'success'}, {'content': [{'text': '\n\nI apologize for the oversight. It seems the function requires additional information. Let me try again with a more specific request.', 'type': 'text', 'index': 0}, {'id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'input': {}, 'name': 'weather_search', 'type': 'tool_use', 'index': 1, 'partial_json': '{"city": "San Francisco, USA"}'}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'tool_use', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-5c355a56-cfe3-4046-b49f-f5b09fc397ef', 'example': False, 'tool_calls': [{'name': 'weather_search', 'args': {'city': 'San Francisco, USA'}, 'id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'type': 'tool_call'}], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 461, 'output_tokens': 83, 'total_tokens': 544}}, {'content': 'Sunny!', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'weather_search', 'id': '3b857482-bca2-4a73-a9ab-1f35a3e43e5f', 'tool_call_id': 'toolu_01YAbLBoKozJyRQnB8LUMpXC', 'artifact': None, 'status': 'success'}, {'content': [{'text': "\n\nGreat news! The weather in San Francisco is sunny today. Is there anything else you'd like to know about the weather or any other information I can help you with?", 'type': 'text', 'index': 0}], 'additional_kwargs': {}, 'response_metadata': {'stop_reason': 'end_turn', 'stop_sequence': None}, 'type': 'ai', 'name': None, 'id': 'run-6a857bb1-f65b-4b86-93d6-c025e003c777', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': {'input_tokens': 557, 'output_tokens': 38, 'total_tokens': 595}}]}
@@ -0,0 +1,383 @@
# How to Replay and Branch from Prior States
With LangGraph Cloud you have the ability to return to any of your prior states and either re-run the graph to reproduce issues noticed during testing, or branch out in a different way from what was originally done in the prior states. In this guide we will show a quick example of how to rerun past states and how to branch off from previous states as well.
## 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/time-travel.ipynb#build-the-agent) if you want to. Once this graph is hosted, we are ready to invoke it and wait for user input.
### SDK initialization
First, we need to setup our client so that we can communicate with our hosted graph:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = agent;
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json' \
--data {}
```
## Replay a state
### Initial invocation
Before replaying a state - we need to create states to replay from! In order to do this, let's invoke our graph with a simple message:
=== "Python"
```python
input = {"messages": [{"role": "user", "content": "Please search the weather in SF"}]}
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id, # graph_id
input=input,
stream_mode="updates",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const input = { "messages": [{ "role": "human", "content": "Please search the weather in SF" }] }
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "updates",
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
=== "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\": \"Please search the weather in SF\"}]},
\"stream_mode\": [
\"updates\"
]
}" | \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
sub(/^event: /, "", $0)
event_type = $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
}
'
```
Output:
{'agent': {'messages': [{'content': [{'text': "Certainly! I'll use the search function to look up the current weather in San Francisco for you. Let me do that now.", 'type': 'text'}, {'id': 'toolu_011vroKUtWU7SBdrngpgpFMn', 'input': {'query': 'current weather in San Francisco'}, 'name': 'search', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ee639877-d97d-40f8-96dc-d0d1ae22d203', 'example': False, 'tool_calls': [{'name': 'search', 'args': {'query': 'current weather in San Francisco'}, 'id': 'toolu_011vroKUtWU7SBdrngpgpFMn'}], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
{'action': {'messages': [{'content': '["I looked up: current weather in San Francisco. Result: It\'s sunny in San Francisco, but you better look out if you\'re a Gemini 😈."]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'search', 'id': '7bad0e72-5ebe-4b08-9b8a-b99b0fe22fb7', 'tool_call_id': 'toolu_011vroKUtWU7SBdrngpgpFMn'}]}}
{'agent': {'messages': [{'content': "Based on the search results, I can provide you with information about the current weather in San Francisco:\n\nThe weather in San Francisco is currently sunny. This is great news for outdoor activities and enjoying the city's beautiful sights.\n\nIt's worth noting that the search result included an unusual comment about Geminis, which isn't typically part of a weather report. This might be due to the search engine including some astrological information or a joke in its results. However, for the purpose of answering your question about the weather, we can focus on the fact that it's sunny in San Francisco.\n\nIf you need any more specific information about the weather in San Francisco, such as temperature, wind speed, or forecast for the coming days, please let me know, and I'd be happy to search for that information for you.", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-dbac539a-33c8-4f0c-9e20-91f318371e7c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
Now let's get our list of states, and invoke from the third state (right before the tool get called):
=== "Python"
```python
states = await client.threads.get_history(thread['thread_id'])
# We can confirm that this state is correct by checking the 'next' attribute and seeing that it is the tool call node
state_to_replay = states[2]
print(state_to_replay['next'])
```
=== "Javascript"
```js
const states = await client.threads.getHistory(thread['thread_id']);
// We can confirm that this state is correct by checking the 'next' attribute and seeing that it is the tool call node
const stateToReplay = states[2];
console.log(stateToReplay['next']);
```
=== "CURL"
```bash
curl --request GET --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/history | jq -r '.[2].next'
```
Output:
['action']
To rerun from a state, we need first issue an empty update to the thread state. Then we need to pass in the resulting `checkpoint_id` as follows:
=== "Python"
```python
state_to_replay = states[2]
updated_config = await client.threads.update_state(
thread["thread_id"],
{"messages": []},
checkpoint_id=state_to_replay["checkpoint_id"]
)
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id, # graph_id
input=None,
stream_mode="updates",
checkpoint_id=updated_config["checkpoint_id"]
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const stateToReplay = states[2];
const config = await client.threads.updateState(thread["thread_id"], { values: {"messages": [] }, checkpointId: stateToReplay["checkpoint_id"] });
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: null,
streamMode: "updates",
checkpointId: config["checkpoint_id"]
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
=== "CURL"
```bash
curl --request GET --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/history | jq -c '
.[2] as $state_to_replay |
{
values: { messages: .[2].values.messages[-1] },
checkpoint_id: $state_to_replay.checkpoint_id
}' | \
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state \
--header 'Content-Type: application/json' \
--data @- | jq .checkpoint_id | \
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": \"agent\",
\"checkpoint_id\": \"$1\",
\"stream_mode\": [
\"updates\"
]
}" | \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
sub(/^event: /, "", $0)
event_type = $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
}
'
```
Output:
{'action': {'messages': [{'content': '["I looked up: current weather in San Francisco. Result: It\'s sunny in San Francisco, but you better look out if you\'re a Gemini 😈."]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'search', 'id': 'eba650e5-400e-4938-8508-f878dcbcc532', 'tool_call_id': 'toolu_011vroKUtWU7SBdrngpgpFMn'}]}}
{'agent': {'messages': [{'content': "Based on the search results, I can provide you with information about the current weather in San Francisco:\n\nThe weather in San Francisco is currently sunny. This is great news if you're planning any outdoor activities or simply want to enjoy a pleasant day in the city.\n\nIt's worth noting that the search result included an unusual comment about Geminis, which doesn't seem directly related to the weather. This appears to be a playful or humorous addition to the weather report, possibly from the source where this information was obtained.\n\nIs there anything else you'd like to know about the weather in San Francisco or any other information you need?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-bc6dca3f-a1e2-4f59-a69b-fe0515a348bb', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
As we can see, the graph restarted from the tool node with the same input as our original graph run.
## Branch off from previous state
Using LangGraph's checkpointing, you can do more than just replay past states. You can branch off previous locations to let the agent explore alternate trajectories or to let a user "version control" changes in a workflow.
Let's show how to do this to edit the state at a particular point in time. Let's update the state to change the input to the tool
=== "Python"
```python
# Let's now get the last message in the state
# This is the one with the tool calls that we want to update
last_message = state_to_replay['values']['messages'][-1]
# Let's now update the args for that tool call
last_message['tool_calls'][0]['args'] = {'query': 'current weather in SF'}
config = await client.threads.update_state(thread['thread_id'],{"messages":[last_message]},checkpoint_id=state_to_replay['checkpoint_id'])
```
=== "Javascript"
```js
// Let's now get the last message in the state
// This is the one with the tool calls that we want to update
let lastMessage = stateToReplay['values']['messages'][-1];
// Let's now update the args for that tool call
lastMessage['tool_calls'][0]['args'] = { 'query': 'current weather in SF' };
const config = await client.threads.updateState(thread['thread_id'], { values: { "messages": [lastMessage] }, checkpointId: stateToReplay['checkpoint_id'] });
```
=== "CURL"
```bash
curl -s --request GET --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/history | \
jq -c '
.[2] as $state_to_replay |
.[2].values.messages[-1].tool_calls[0].args.query = "current weather in SF" |
{
values: { messages: .[2].values.messages[-1] },
checkpoint_id: $state_to_replay.checkpoint_id
}' | \
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state \
--header 'Content-Type: application/json' \
--data @-
```
Now we can rerun our graph with this new config, starting from the `new_state`, which is a branch of our `state_to_replay`:
=== "Python"
```python
async for chunk in client.runs.stream(
thread["thread_id"],
assistant["assistant_id"], # graph_id
input=None,
stream_mode="updates",
checkpoint_id=config['checkpoint_id']
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const streamResponse = client.runs.stream(
thread["thread_id"],
assistant["assistant_id"],
{
input: null,
streamMode: "updates",
checkpointId: config['checkpoint_id'],
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
=== "CURL"
```bash
curl -s --request GET --url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state | \
jq -c '.checkpoint_id' | \
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": \"agent\",
\"checkpoint_id\": \"$1\",
\"stream_mode\": [
\"updates\"
]
}" | \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
sub(/^event: /, "", $0)
event_type = $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
}
'
```
Output:
{'action': {'messages': [{'content': '["I looked up: current weather in SF. Result: It\'s sunny in San Francisco, but you better look out if you\'re a Gemini 😈."]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'search', 'id': '2baf9941-4fda-4081-9f87-d76795d289f1', 'tool_call_id': 'toolu_011vroKUtWU7SBdrngpgpFMn'}]}}
{'agent': {'messages': [{'content': "Based on the search results, I can provide you with information about the current weather in San Francisco (SF):\n\nThe weather in San Francisco is currently sunny. This means it's a clear day with plenty of sunshine. \n\nIt's worth noting that the specific temperature wasn't provided in the search result, but sunny weather in San Francisco typically means comfortable temperatures. San Francisco is known for its mild climate, so even on sunny days, it's often not too hot.\n\nThe search result also included a playful reference to astrological signs, mentioning Gemini. However, this is likely just a joke or part of the search engine's presentation and not related to the actual weather conditions.\n\nIs there any specific information about the weather in San Francisco you'd like to know more about? I'd be happy to perform another search if you need details on temperature, wind conditions, or the forecast for the coming days.", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-a83de52d-ed18-4402-9384-75c462485743', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
As we can see, the search query changed from San Francisco to SF, just as we had hoped!
@@ -0,0 +1,264 @@
# How to Wait for User Input
One of the main human-in-the-loop interaction patterns is waiting for human input. A key use case involves asking the user clarifying questions. One way to accomplish this is simply go to the `END` node and exit the graph. Then, any user response comes back in as fresh invocation of the graph. This is basically just creating a chatbot architecture.
The issue with this is it is tough to resume back in a particular point in the graph. Often times the agent is halfway through some process, and just needs a bit of a user input. Although it is possible to design your graph in such a way where you have a `conditional_entry_point` to route user messages back to the right place, that is not super scalable (as it essentially involves having a routing function that can end up almost anywhere).
A separate way to do this is to have a node explicitly for getting user input. This is easy to implement in a notebook setting - you just put an `input()` call in the node. But that isn't exactly production ready.
Luckily, LangGraph makes it possible to do similar things in a production way. The basic idea is:
- Set up a node that represents human input. This can have specific incoming/outgoing edges (as you desire). There shouldn't actually be any logic inside this node.
- Add a breakpoint before the node. This will stop the graph before this node executes (which is good, because there's no real logic in it anyways)
- Use `.update_state` to update the state of the graph. Pass in whatever human response you get. The key here is to use the `as_node` parameter to apply this update **as if you were that node**. This will have the effect of making it so that when you resume execution next it resumes as if that node just acted, and not from the beginning.
## 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.
### SDK initialization
First, we need to setup our client so that we can communicate with our hosted graph:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent";
const thread = await client.threads.create();
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
## Waiting for user input
### Initial invocation
Now, let's invoke our graph by interrupting before `ask_human` node:
=== "Python"
```python
input = { 'messages':[{ "role":"user", "content":"Use the search tool to ask the user where they are, then look up the weather there" }] }
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id,
input=input,
stream_mode="updates",
interrupt_before=["ask_human"],
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const input = { "messages":[{ "role":"human", "content": "Use the search tool to ask the user where they are, then look up the weather there"}] }
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: input,
streamMode: "updates",
interruptBefore: ["ask_human"],
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
=== "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\": \"Use the search tool to ask the user where they are, then look up the weather there\"}]},
\"interrupt_before\": [\"ask_human\"],
\"stream_mode\": [
\"updates\"
]
}" | \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
sub(/^event: /, "", $0)
event_type = $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
}
'
```
Output:
{'agent': {'messages': [{'content': [{'text': "Certainly! I'll use the AskHuman function to ask the user about their location, and then I'll use the search function to look up the weather for that location. Let's start by asking the user where they are.", 'type': 'text'}, {'id': 'toolu_01RFahzYPvnPWTb2USk2RdKR', 'input': {'question': 'Where are you currently located?'}, 'name': 'AskHuman', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-a8422215-71d3-4093-afb4-9db141c94ddb', 'example': False, 'tool_calls': [{'name': 'AskHuman', 'args': {'question': 'Where are you currently located?'}, 'id': 'toolu_01RFahzYPvnPWTb2USk2RdKR'}], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
### Adding user input to state
We now want to update this thread with a response from the user. We then can kick off another run.
Because we are treating this as a tool call, we will need to update the state as if it is a response from a tool call. In order to do this, we will need to check the state to get the ID of the tool call.
=== "Python"
```python
state = await client.threads.get_state(thread['thread_id'])
tool_call_id = state['values']['messages'][-1]['tool_calls'][0]['id']
# We now create the tool call with the id and the response we want
tool_message = [{"tool_call_id": tool_call_id, "type": "tool", "content": "san francisco"}]
await client.threads.update_state(thread['thread_id'], {"messages": tool_message}, as_node="ask_human")
```
=== "Javascript"
```js
const state = await client.threads.getState(thread['thread_id']);
const toolCallId = state['values']['messages'][-1]['tool_calls'][0]['id'];
# We now create the tool call with the id and the response we want
const toolMessage = [{"tool_call_id": toolCallId, "type": "tool", "content": "san francisco"}];
await client.threads.updateState(thread['thread_id'], {values: {"messages": toolMessage}, asNode:"ask_human"})
```
=== "CURL"
```bash
curl --request GET \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state \
| jq -r '.values.messages[-1].tool_calls[0].id' \
| sh -c '
TOOL_CALL_ID="$1"
# Construct the JSON payload
JSON_PAYLOAD=$(printf "{\"messages\": [{\"tool_call_id\": \"%s\", \"type\": \"tool\", \"content\": \"san francisco\"}], \"as_node\": \"ask_human\"}" "$TOOL_CALL_ID")
# Send the updated state
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/state \
--header "Content-Type: application/json" \
--data "${JSON_PAYLOAD}"
' _
```
Output:
{'configurable': {'thread_id': 'a9f322ae-4ed1-41ec-942b-38cb3d342c3a',
'checkpoint_ns': '',
'checkpoint_id': '1ef58e97-a623-63dd-8002-39a9a9b20be3'}}
### Invoking after receiving human input
We can now tell the agent to continue. We can just pass in None as the input to the graph, since no additional input is needed:
=== "Python"
```python
async for chunk in client.runs.stream(
thread["thread_id"],
assistant_id,
input=None,
stream_mode="updates",
):
if chunk.data and chunk.event != "metadata":
print(chunk.data)
```
=== "Javascript"
```js
const streamResponse = client.runs.stream(
thread["thread_id"],
assistantId,
{
input: null,
streamMode: "updates",
}
);
for await (const chunk of streamResponse) {
if (chunk.data && chunk.event !== "metadata") {
console.log(chunk.data);
}
}
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads/<THREAD_ID>/runs/stream \
--header 'Content-Type: application/json' \
--data "{
\"assistant_id\": \"agent\",
\"stream_mode\": [
\"updates\"
]
}"| \
sed 's/\r$//' | \
awk '
/^event:/ {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
sub(/^event: /, "", $0)
event_type = $0
data_content = ""
}
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "" && event_type != "metadata") {
print data_content "\n"
}
}
'
```
Output:
{'agent': {'messages': [{'content': [{'text': "Thank you for letting me know that you're in San Francisco. Now, I'll use the search function to look up the weather in San Francisco.", 'type': 'text'}, {'id': 'toolu_01K57ofmgG2wyJ8tYJjbq5k7', 'input': {'query': 'current weather in San Francisco'}, 'name': 'search', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-241baed7-db5e-44ce-ac3c-56431705c22b', 'example': False, 'tool_calls': [{'name': 'search', 'args': {'query': 'current weather in San Francisco'}, 'id': 'toolu_01K57ofmgG2wyJ8tYJjbq5k7'}], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
{'action': {'messages': [{'content': '["I looked up: current weather in San Francisco. Result: It\'s sunny in San Francisco, but you better look out if you\'re a Gemini 😈."]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'search', 'id': '8b699b95-8546-4557-8e66-14ea71a15ed8', 'tool_call_id': 'toolu_01K57ofmgG2wyJ8tYJjbq5k7'}]}}
{'agent': {'messages': [{'content': "Based on the search results, I can provide you with information about the current weather in San Francisco:\n\nThe weather in San Francisco is currently sunny. It's a beautiful day in the city! \n\nHowever, I should note that the search result included an unusual comment about Gemini zodiac signs. This appears to be either a joke or potentially irrelevant information added by the search engine. For accurate and detailed weather information, you might want to check a reliable weather service or app for San Francisco.\n\nIs there anything else you'd like to know about the weather or San Francisco?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-b4d7309f-f849-46aa-b6ef-475bcabd2be9', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 721 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

+77
View File
@@ -0,0 +1,77 @@
---
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.
## Deployment
LangGraph Cloud gives you best in class observability, testing, and hosting services. Read more about them 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 test locally](../deployment/test_locally.md)
- [How to deploy to LangGraph cloud](../deployment/cloud.md)
- [How to self-host](../deployment/self_hosted.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](cloud_examples/background_run.ipynb)
- [How to run multiple agents in the same thread](cloud_examples/same-thread.ipynb)
- [How to create cron jobs](cloud_examples/cron_jobs.ipynb)
- [How to create stateless runs](cloud_examples/stateless_runs.ipynb)
## Other
Other guides that may prove helpful!
- [How to configure agents](cloud_examples/configuration_cloud.ipynb)
- [How to convert LangGraph calls to LangGraph cloud calls](cloud_examples/langgraph_to_langgraph_cloud.ipynb)
- [How to integrate webhooks](cloud_examples/webhooks.ipynb)
- [How to copy threads](./copy_threads.md)
- [How to check status of your threads](./check_thread_status.md)
@@ -0,0 +1,176 @@
## 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).
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.
First, we will define a quick helper function for printing out JS model outputs (you can skip this if using Python):
```js
function prettyPrint(m) {
const padded = " " + m['type'] + " ";
const sepLen = Math.floor((80 - padded.length) / 2);
const sep = "=".repeat(sepLen);
const secondSep = sep + (padded.length % 2 ? "=" : "");
console.log(`${sep}${padded}${secondSep}`);
console.log("\n\n");
console.log(m.content);
}
```
Now, let's import our required packages and instantiate our client, assistant, and thread.
=== "Python"
```python
import asyncio
from langchain_core.messages import convert_to_messages
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent";
const thread = await client.threads.create();
```
Now we can start our two runs and join the second on euntil it has completed:
=== "Python"
```python
# the first run will be interrupted
interrupted_run = await client.runs.create(
thread["thread_id"],
assistant_id,
input={"messages": [{"role": "human", "content": "what's the weather in sf?"}]},
)
await asyncio.sleep(2)
run = await client.runs.create(
thread["thread_id"],
assistant_id,
input={"messages": [{"role": "human", "content": "what's the weather in nyc?"}]},
multitask_strategy="interrupt",
)
# wait until the second run completes
await client.runs.join(thread["thread_id"], run["run_id"])
```
=== "Javascript"
```js
// the first run will be interrupted
let interruptedRun = await client.runs.create(
thread["thread_id"],
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"],
assistantId,
{
input: { messages: [{ role: "human", content: "what's the weather in nyc?" }] },
multitaskStrategy: "interrupt"
}
);
// wait until the second run completes
await client.runs.join(thread["thread_id"], run["run_id"]);
```
We can see that the thread has partial data from the first run + data from the second run
=== "Python"
```python
state = await client.threads.get_state(thread["thread_id"])
for m in convert_to_messages(state["values"]["messages"]):
m.pretty_print()
```
=== "Javascript"
```js
const state = await client.threads.getState(thread["thread_id"]);
for (const m of state['values']['messages']) {
prettyPrint(m);
}
```
Output:
================================ Human Message =================================
what's the weather in sf?
================================== Ai Message ==================================
[{'id': 'toolu_01MjNtVJwEcpujRGrf3x6Pih', 'input': {'query': 'weather in san francisco'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_01MjNtVJwEcpujRGrf3x6Pih)
Call ID: toolu_01MjNtVJwEcpujRGrf3x6Pih
Args:
query: weather in san francisco
================================= Tool Message =================================
Name: tavily_search_results_json
[{"url": "https://www.wunderground.com/hourly/us/ca/san-francisco/KCASANFR2002/date/2024-6-18", "content": "High 64F. Winds W at 10 to 20 mph. A few clouds from time to time. Low 49F. Winds W at 10 to 20 mph. Temp. San Francisco Weather Forecasts. Weather Underground provides local & long-range weather ..."}]
================================ Human Message =================================
what's the weather in nyc?
================================== Ai Message ==================================
[{'id': 'toolu_01KtE1m1ifPLQAx4fQLyZL9Q', 'input': {'query': 'weather in new york city'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_01KtE1m1ifPLQAx4fQLyZL9Q)
Call ID: toolu_01KtE1m1ifPLQAx4fQLyZL9Q
Args:
query: weather in new york city
================================= Tool Message =================================
Name: tavily_search_results_json
[{"url": "https://www.accuweather.com/en/us/new-york/10021/june-weather/349727", "content": "Get the monthly weather forecast for New York, NY, including daily high/low, historical averages, to help you plan ahead."}]
================================== Ai Message ==================================
The search results provide weather forecasts and information for New York City. Based on the top result from AccuWeather, here are some key details about the weather in NYC:
- This is a monthly weather forecast for New York City for the month of June.
- It includes daily high and low temperatures to help plan ahead.
- Historical averages for June in NYC are also provided as a reference point.
- More detailed daily or hourly forecasts with precipitation chances, humidity, wind, etc. can be found by visiting the AccuWeather page.
So in summary, the search provides a convenient overview of the expected weather conditions in New York City over the next month to give you an idea of what to prepare for if traveling or making plans there. Let me know if you need any other details!
Verify that the original, interrupted run was interrupted
=== "Python"
```python
print((await client.runs.get(thread["thread_id"], interrupted_run["run_id"]))["status"])
```
=== "Javascript"
```js
console.log((await client.runs.get(thread['thread_id'], interruptedRun["run_id"]))["status"])
```
Output:
'interrupted'
+15
View File
@@ -0,0 +1,15 @@
# Invoke Assistant
The LangGraph Studio lets you test different configurations and inputs to your graph. It also provides a nice visualization of your graph during execution so it is easy to see which nodes are being run and what the outputs of each individual node are.
1. The LangGraph Studio UI displays a visualization of the selected assistant.
1. In the top-left dropdown menu of the left-hand pane, select an assistant.
1. In the bottom of the left-hand pane, edit the `Input` and `Configure` the assistant.
1. Select `Submit` to invoke the selected assistant.
1. View output of the invocation in the right-hand pane.
The following video shows these exact steps being carried out:
<video controls allowfullscreen="true" poster="../img/studio_input_poster.png">
<source src="../img/studio_input.mp4" type="video/mp4">
</video>
@@ -0,0 +1,155 @@
## Reject
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide][double-texting].
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.
First, we will define a quick helper function for printing out JS model outputs (you can skip this if using Python):
```js
function prettyPrint(m) {
const padded = " " + m['type'] + " ";
const sepLen = Math.floor((80 - padded.length) / 2);
const sep = "=".repeat(sepLen);
const secondSep = sep + (padded.length % 2 ? "=" : "");
console.log(`${sep}${padded}${secondSep}`);
console.log("\n\n");
console.log(m.content);
}
```
Now, let's import our required packages and instantiate our client, assistant, and thread.
=== "Python"
```python
import httpx
from langchain_core.messages import convert_to_messages
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent";
const thread = await client.threads.create();
```
Now we can run a thread and try to run a second one with the "reject" option, which should fail since we have already started a run:
=== "Python"
```python
run = await client.runs.create(
thread["thread_id"],
assistant_id,
input={"messages": [{"role": "human", "content": "what's the weather in sf?"}]},
)
try:
await client.runs.create(
thread["thread_id"],
assistant_id,
input={
"messages": [{"role": "human", "content": "what's the weather in nyc?"}]
},
multitask_strategy="reject",
)
except httpx.HTTPStatusError as e:
print("Failed to start concurrent run", e)
```
=== "Javascript"
```js
const run = await client.runs.create(
thread["thread_id"],
assistantId,
input={"messages": [{"role": "human", "content": "what's the weather in sf?"}]},
);
try {
await client.runs.create(
thread["thread_id"],
assistantId,
{
input: {"messages": [{"role": "human", "content": "what's the weather in nyc?"}]},
multitask_strategy:"reject"
},
);
} catch (e) {
console.error("Failed to start concurrent run", e);
}
```
Failed to start concurrent run Client error '409 Conflict' for url 'http://localhost:8123/threads/f9e7088b-8028-4e5c-88d2-9cc9a2870e50/runs'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409
We can verify that the original thread finished executing:
=== "Python"
```python
# wait until the original run completes
await client.runs.join(thread["thread_id"], run["run_id"])
state = await client.threads.get_state(thread["thread_id"])
for m in convert_to_messages(state["values"]["messages"]):
m.pretty_print()
```
=== "Javascript"
```js
await client.runs.join(thread["thread_id"], run["run_id"]);
const state = await client.threads.getState(thread["thread_id"]);
for (const m of state["values"]["messages"]) {
prettyPrint(m);
}
```
Output:
================================ Human Message =================================
what's the weather in sf?
================================== Ai Message ==================================
[{'id': 'toolu_01CyewEifV2Kmi7EFKHbMDr1', 'input': {'query': 'weather in san francisco'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_01CyewEifV2Kmi7EFKHbMDr1)
Call ID: toolu_01CyewEifV2Kmi7EFKHbMDr1
Args:
query: weather in san francisco
================================= Tool Message =================================
Name: tavily_search_results_json
[{"url": "https://www.accuweather.com/en/us/san-francisco/94103/june-weather/347629", "content": "Get the monthly weather forecast for San Francisco, CA, including daily high/low, historical averages, to help you plan ahead."}]
================================== Ai Message ==================================
According to the search results from Tavily, the current weather in San Francisco is:
The average high temperature in San Francisco in June is around 65°F (18°C), with average lows around 54°F (12°C). June tends to be one of the cooler and foggier months in San Francisco due to the marine layer of fog that often blankets the city during the summer months.
Some key points about the typical June weather in San Francisco:
- Mild temperatures with highs in the 60s F and lows in the 50s F
- Foggy mornings that often burn off to sunny afternoons
- Little to no rainfall, as June falls in the dry season
- Breezy conditions, with winds off the Pacific Ocean
- Layers are recommended for changing weather conditions
So in summary, you can expect mild, foggy mornings giving way to sunny but cool afternoons in San Francisco this time of year. The marine layer keeps temperatures moderate compared to other parts of California in June.
@@ -0,0 +1,161 @@
## Rollback
This guide assumes knowledge of what double-texting is, which you can learn about in the [double-texting conceptual guide][double-texting].
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.
First, we will define a quick helper function for printing out JS model outputs (you can skip this if using Python):
```js
function prettyPrint(m) {
const padded = " " + m['type'] + " ";
const sepLen = Math.floor((80 - padded.length) / 2);
const sep = "=".repeat(sepLen);
const secondSep = sep + (padded.length % 2 ? "=" : "");
console.log(`${sep}${padded}${secondSep}`);
console.log("\n\n");
console.log(m.content);
}
```
Now, let's import our required packages and instantiate our client, assistant, and thread.
=== "Python"
```python
import asyncio
import httpx
from langchain_core.messages import convert_to_messages
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
assistant_id = "agent"
thread = await client.threads.create()
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
const assistantId = "agent";
const thread = await client.threads.create();
```
Now let's run a thread with the multitask parameter set to "rollback":
=== "Python"
```python
# the first run will be rolled back
rolled_back_run = await client.runs.create(
thread["thread_id"],
assistant_id,
input={"messages": [{"role": "human", "content": "what's the weather in sf?"}]},
)
await asyncio.sleep(2)
run = await client.runs.create(
thread["thread_id"],
assistant_id,
input={"messages": [{"role": "human", "content": "what's the weather in nyc?"}]},
multitask_strategy="rollback",
)
# wait until the second run completes
await client.runs.join(thread["thread_id"], run["run_id"])
```
=== "Javascript"
```js
// the first run will be interrupted
let rolledBackRun = await client.runs.create(
thread["thread_id"],
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"],
assistant_id,
{
input: { messages: [{ role: "human", content: "what's the weather in nyc?" }] },
multitaskStrategy: "rollback"
}
);
// wait until the second run completes
await client.runs.join(thread["thread_id"], run["run_id"]);
```
We can see that the thread has data only from the second run
=== "Python"
```python
state = await client.threads.get_state(thread["thread_id"])
for m in convert_to_messages(state["values"]["messages"]):
m.pretty_print()
```
=== "Javascript"
```js
const state = await client.threads.getState(thread["thread_id"]);
for (const m of state['values']['messages']) {
prettyPrint(m);
}
```
Output:
================================ Human Message =================================
what's the weather in nyc?
================================== Ai Message ==================================
[{'id': 'toolu_01JzPqefao1gxwajHQ3Yh3JD', 'input': {'query': 'weather in nyc'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}]
Tool Calls:
tavily_search_results_json (toolu_01JzPqefao1gxwajHQ3Yh3JD)
Call ID: toolu_01JzPqefao1gxwajHQ3Yh3JD
Args:
query: weather in nyc
================================= Tool Message =================================
Name: tavily_search_results_json
[{"url": "https://www.weatherapi.com/", "content": "{'location': {'name': 'New York', 'region': 'New York', 'country': 'United States of America', 'lat': 40.71, 'lon': -74.01, 'tz_id': 'America/New_York', 'localtime_epoch': 1718734479, 'localtime': '2024-06-18 14:14'}, 'current': {'last_updated_epoch': 1718733600, 'last_updated': '2024-06-18 14:00', 'temp_c': 29.4, 'temp_f': 84.9, 'is_day': 1, 'condition': {'text': 'Sunny', 'icon': '//cdn.weatherapi.com/weather/64x64/day/113.png', 'code': 1000}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 158, 'wind_dir': 'SSE', 'pressure_mb': 1025.0, 'pressure_in': 30.26, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 63, 'cloud': 0, 'feelslike_c': 31.3, 'feelslike_f': 88.3, 'windchill_c': 28.3, 'windchill_f': 82.9, 'heatindex_c': 29.6, 'heatindex_f': 85.3, 'dewpoint_c': 18.4, 'dewpoint_f': 65.2, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 7.0, 'gust_mph': 16.5, 'gust_kph': 26.5}}"}]
================================== Ai Message ==================================
The weather API results show that the current weather in New York City is sunny with a temperature of around 85°F (29°C). The wind is light at around 2-3 mph from the south-southeast. Overall it looks like a nice sunny summer day in NYC.
Verify that the original, rolled back run was deleted
=== "Python"
```python
try:
await client.runs.get(thread["thread_id"], rolled_back_run["run_id"])
except httpx.HTTPStatusError as _:
print("Original run was correctly deleted")
```
=== "Javascript"
```js
try {
await client.runs.get(thread["thread_id"], rolledBackRun["run_id"]);
} catch (e) {
console.log("Original run was correctly deleted");
}
```
Output:
Original run was correctly deleted
File diff suppressed because one or more lines are too long
+412
View File
@@ -0,0 +1,412 @@
# 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).
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
# create thread
thread = await client.threads.create()
print(thread)
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
// create thread
const thread = await client.threads.create();
console.log(thread)
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
Output:
{'thread_id': '3f4c64e0-f792-4a5e-aa07-a4404e06e0bd',
'created_at': '2024-06-24T22:16:29.301522+00:00',
'updated_at': '2024-06-24T22:16:29.301522+00:00',
'metadata': {},
'status': 'idle',
'config': {}}
Streaming events produces responses containing an `event` key (in addition to other keys such as `data`). See the LangChain [`Runnable.astream_events()` reference](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.base.Runnable.html#langchain_core.runnables.base.Runnable.astream_events) for all event types.
=== "Python"
```python
# create input
input = {
"messages": [
{
"role": "human",
"content": "What's the weather in SF?",
}
]
}
# stream events
async for chunk in client.runs.stream(
thread_id=thread["thread_id"],
assistant_id="agent",
input=input,
stream_mode="events",
):
print(f"Receiving new event of type: {chunk.event}...")
print(chunk.data)
print("\n\n")
```
=== "Javascript"
```js
// create input
const input = {
"messages": [
{
"role": "human",
"content": "What's the weather in SF?",
}
]
}
// stream events
const streamResponse = client.runs.stream(
thread["thread_id"],
"agent",
{
input,
streamMode: "events"
}
);
for await (const chunk of streamResponse) {
console.log(f"Receiving new event of type: {chunk.event}...")
console.log(chunk.data)
console.log("\n\n")
}
```
=== "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:/ {
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:
Receiving new event of type: metadata...
{'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8'}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {'input': {'messages': [{'role': 'human', 'content': "What's the weather in SF?"}]}}, 'name': 'LangGraph', 'tags': [], 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'parent_ids': []}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {}, 'name': 'agent', 'tags': ['graph:step:6'], 'run_id': '7bb08493-d507-4e28-b9e6-4a5eda9d04f0', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chat_model_start', 'data': {'input': {'messages': [[{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}]]}}, 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'run_id': 'cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'b', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': 'cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'e', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': 'cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'g', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': 'cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'i', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': 'cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'n', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': 'cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chat_model_end', 'data': {'output': {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, 'input': {'messages': [[{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}]]}}, 'run_id': 'cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {'input': {'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'name': 'should_continue', 'tags': ['seq:step:3'], 'run_id': 'c7fe4d2d-3fb8-4e53-946d-03de13527853', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': 'tool', 'input': {'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'run_id': 'c7fe4d2d-3fb8-4e53-946d-03de13527853', 'name': 'should_continue', 'tags': ['seq:step:3'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '7bb08493-d507-4e28-b9e6-4a5eda9d04f0']}
Receiving new event of type: events...
{'event': 'on_chain_stream', 'run_id': '7bb08493-d507-4e28-b9e6-4a5eda9d04f0', 'name': 'agent', 'tags': ['graph:step:6'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'data': {'chunk': {'messages': [{'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'messages': [{'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}, 'input': {'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': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}], 'sleep': None}}, 'run_id': '7bb08493-d507-4e28-b9e6-4a5eda9d04f0', 'name': 'agent', 'tags': ['graph:step:6'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 6, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {}, 'name': 'tool', 'tags': ['graph:step:7'], 'run_id': 'f044fd3d-7271-488f-b8aa-e01572ff9112', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 7, 'langgraph_node': 'tool', 'langgraph_triggers': ['branch:agent:should_continue:tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chain_stream', 'run_id': 'f044fd3d-7271-488f-b8aa-e01572ff9112', 'name': 'tool', 'tags': ['graph:step:7'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 7, 'langgraph_node': 'tool', 'langgraph_triggers': ['branch:agent:should_continue:tool'], 'langgraph_task_idx': 0}, 'data': {'chunk': {'messages': [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': None, 'tool_call_id': 'tool_call_id'}]}}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'messages': [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1c9a16d2-5f0a-4eba-a0d2-240484a4ce7e', 'tool_call_id': 'tool_call_id'}]}, 'input': {'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': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'sleep': None}}, 'run_id': 'f044fd3d-7271-488f-b8aa-e01572ff9112', 'name': 'tool', 'tags': ['graph:step:7'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 7, 'langgraph_node': 'tool', 'langgraph_triggers': ['branch:agent:should_continue:tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {}, 'name': 'agent', 'tags': ['graph:step:8'], 'run_id': '1f4f95d0-0ce1-4061-85d4-946446bbd3e5', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chat_model_start', 'data': {'input': {'messages': [[{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1c9a16d2-5f0a-4eba-a0d2-240484a4ce7e', 'tool_call_id': 'tool_call_id'}]]}}, 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'run_id': '028a68fb-6435-4b46-a156-c3326f73985c', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '1f4f95d0-0ce1-4061-85d4-946446bbd3e5']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'e', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '028a68fb-6435-4b46-a156-c3326f73985c', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '1f4f95d0-0ce1-4061-85d4-946446bbd3e5']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'n', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '028a68fb-6435-4b46-a156-c3326f73985c', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '1f4f95d0-0ce1-4061-85d4-946446bbd3e5']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'd', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '028a68fb-6435-4b46-a156-c3326f73985c', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '1f4f95d0-0ce1-4061-85d4-946446bbd3e5']}
Receiving new event of type: events...
{'event': 'on_chat_model_end', 'data': {'output': {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, 'input': {'messages': [[{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1c9a16d2-5f0a-4eba-a0d2-240484a4ce7e', 'tool_call_id': 'tool_call_id'}]]}}, 'run_id': '028a68fb-6435-4b46-a156-c3326f73985c', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '1f4f95d0-0ce1-4061-85d4-946446bbd3e5']}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {'input': {'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1c9a16d2-5f0a-4eba-a0d2-240484a4ce7e', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'name': 'should_continue', 'tags': ['seq:step:3'], 'run_id': 'f2b2dfaf-475d-422b-8bf5-02a31bcc7d1a', 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '1f4f95d0-0ce1-4061-85d4-946446bbd3e5']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': '__end__', 'input': {'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1c9a16d2-5f0a-4eba-a0d2-240484a4ce7e', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'run_id': 'f2b2dfaf-475d-422b-8bf5-02a31bcc7d1a', 'name': 'should_continue', 'tags': ['seq:step:3'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8', '1f4f95d0-0ce1-4061-85d4-946446bbd3e5']}
Receiving new event of type: events...
{'event': 'on_chain_stream', 'run_id': '1f4f95d0-0ce1-4061-85d4-946446bbd3e5', 'name': 'agent', 'tags': ['graph:step:8'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'data': {'chunk': {'messages': [{'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'messages': [{'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}, 'input': {'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': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1c9a16d2-5f0a-4eba-a0d2-240484a4ce7e', 'tool_call_id': 'tool_call_id'}], 'sleep': None}}, 'run_id': '1f4f95d0-0ce1-4061-85d4-946446bbd3e5', 'name': 'agent', 'tags': ['graph:step:8'], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 8, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef301a5-b867-67de-9e9e-a32e53c5b1f8']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'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': '51f2874d-f8c7-4040-8b3b-8f15429a56ae', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-5f556aa0-26ea-42e2-b9e4-7ece3a00974e', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1faf5dd0-ae97-4235-963f-5075083a027a', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-ae383611-6a42-475a-912a-09d5972e9e94', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'c67e08e6-e7af-4c4a-aa5e-50c8340ae341', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-cb1b98c1-c9e2-4a30-9d7a-38fa1f6224bd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '1c9a16d2-5f0a-4eba-a0d2-240484a4ce7e', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-028a68fb-6435-4b46-a156-c3326f73985c', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}, 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'name': 'LangGraph', 'tags': [], 'metadata': {'graph_id': 'agent', 'created_by': 'system', 'run_id': '1ef301a5-b867-67de-9e9e-a32e53c5b1f8', 'user_id': '', 'thread_id': '7196a3aa-763c-4a8d-bfda-12fbfe1cd727', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'parent_ids': []}
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="agent",
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"],
"agent",
{
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.
+484
View File
@@ -0,0 +1,484 @@
# 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.
E.g., the state should look something like:
=== "Python"
```python
from typing import TypedDict, Annotated
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)
First let's set up our client and thread:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
# create thread
thread = await client.threads.create()
print(thread)
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
// create thread
const thread = await client.threads.create();
console.log(thread)
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
Output:
{'thread_id': 'e1431c95-e241-4d1d-a252-27eceb1e5c86',
'created_at': '2024-06-21T15:48:59.808924+00:00',
'updated_at': '2024-06-21T15:48:59.808924+00:00',
'metadata': {},
'status': 'idle',
'config': {}}
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
```
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:
=== "Python"
```python
input = {"messages": [{"role": "user", "content": "what's the weather in sf"}]}
config = {"configurable": {"model_name": "openai"}}
async for event in client.runs.stream(
thread["thread_id"],
assistant_id="agent",
input=input,
config=config,
stream_mode="messages",
):
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)
```
=== "Javascript"
```js
const input = {
"messages": [
{
"role": "human",
"content": "What's the weather in sf",
}
]
}
const config = {"configurable": {"model_name": "openai"}}
const streamResponse = client.runs.stream(
thread["thread_id"],
"agent",
{
input,
config,
streamMode: "messages"
}
);
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));
}
}
```
=== "CURL"
```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
```
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
--------------------------------------------------
+486
View File
@@ -0,0 +1,486 @@
# How to configure multiple streaming modes at the same time
This guide covers how to configure multiple streaming modes at the same time.
First let's set up our client and thread:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
# create thread
thread = await client.threads.create()
print(thread)
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
// create thread
const thread = await client.threads.create();
console.log(thread)
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
Output:
{'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4',
'created_at': '2024-06-24T21:30:07.980789+00:00',
'updated_at': '2024-06-24T21:30:07.980789+00:00',
'metadata': {},
'status': 'idle',
'config': {}}
When configuring multiple streaming modes for a run, responses for each respective mode will be produced. In the following example, note that a `list` of modes (`messages`, `events`, `debug`) is passed to the `stream_mode` parameter and the response contains `events`, `debug`, `messages/complete`, `messages/metadata`, and `messages/partial` event types.
=== "Python"
```python
# create input
input = {
"messages": [
{
"role": "human",
"content": "What's the weather in SF?",
}
]
}
# stream events with multiple streaming modes
async for chunk in client.runs.stream(
thread_id=thread["thread_id"],
assistant_id="agent",
input=input,
stream_mode=["messages", "events", "debug"],
):
print(f"Receiving new event of type: {chunk.event}...")
print(chunk.data)
print("\n\n")
```
=== "Javascript"
```js
// create input
const input = {
"messages": [
{
"role": "human",
"content": "What's the weather in SF?",
}
]
}
// stream events with multiple streaming modes
const streamResponse = client.runs.stream(
thread["thread_id"],
"agent",
{
input,
streamMode: ["messages", "events", "debug"]
}
);
for await (const chunk of streamResponse) {
console.log(f"Receiving new event of type: {chunk.event}...")
console.log(chunk.data)
console.log("\n\n")
}
```
=== "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\": [
\"messages\",
\"events\",
\"debug\"
]
}" | \
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:
Receiving new event of type: metadata...
{'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {'input': {'messages': [{'role': 'human', 'content': "What's the weather in SF?"}]}}, 'name': 'LangGraph', 'tags': [], 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', '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'}, 'parent_ids': []}
Receiving new event of type: debug...
{'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.116009+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-bc7c-6daa-bfff-6b9027c1a50e', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'messages': []}, 'metadata': {'source': 'input', 'step': -1, 'writes': {'messages': [{'role': 'human', 'content': "What's the weather in SF?"}]}}}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.116009+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-bc7c-6daa-bfff-6b9027c1a50e', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'messages': []}, 'metadata': {'source': 'input', 'step': -1, 'writes': {'messages': [{'role': 'human', 'content': "What's the weather in SF?"}]}}}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'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', {'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}]}]}, 'parent_ids': []}
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}}}
Receiving new event of type: events...
{'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': ['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}}}]}, 'parent_ids': []}
Receiving new event of type: debug...
{'type': 'task', 'timestamp': '2024-06-24T21:34:06.118042+00:00', 'step': 1, 'payload': {'id': '212ed9c2-a454-50c5-a202-12066bbbe7b8', 'name': 'agent', 'input': {'some_bytes': None, 'some_byte_array': None, 'dict_with_bytes': None, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}], 'sleep': None}, 'triggers': ['start:agent']}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'task', 'timestamp': '2024-06-24T21:34:06.118042+00:00', 'step': 1, 'payload': {'id': '212ed9c2-a454-50c5-a202-12066bbbe7b8', 'name': 'agent', 'input': {'some_bytes': None, 'some_byte_array': None, 'dict_with_bytes': None, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}], 'sleep': None}, 'triggers': ['start:agent']}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {}, 'name': 'agent', 'tags': ['graph:step:1'], 'run_id': '72b74d24-5792-48da-a887-102100d6e2c0', '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: events...
{'event': 'on_chat_model_start', 'data': {'input': {'messages': [[{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}]]}}, 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'run_id': '2424dd6d-5cf5-4244-8d98-357640ce6e12', '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'b', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '2424dd6d-5cf5-4244-8d98-357640ce6e12', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: messages/metadata...
{'run-2424dd6d-5cf5-4244-8d98-357640ce6e12': {'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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}}}
Receiving new event of type: messages/partial...
[{'content': 'b', '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: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'e', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '2424dd6d-5cf5-4244-8d98-357640ce6e12', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: messages/partial...
[{'content': 'be', '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: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'g', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '2424dd6d-5cf5-4244-8d98-357640ce6e12', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: messages/partial...
[{'content': 'beg', '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: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'i', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '2424dd6d-5cf5-4244-8d98-357640ce6e12', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: messages/partial...
[{'content': 'begi', '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: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'n', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '2424dd6d-5cf5-4244-8d98-357640ce6e12', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: messages/partial...
[{'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: events...
{'event': 'on_chat_model_end', 'data': {'output': {'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}, 'input': {'messages': [[{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}]]}}, 'run_id': '2424dd6d-5cf5-4244-8d98-357640ce6e12', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {'input': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'name': 'should_continue', 'tags': ['seq:step:3'], 'run_id': '227afb0f-f909-4d54-a042-556ca6d98a69', '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': 'tool', 'input': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'run_id': '227afb0f-f909-4d54-a042-556ca6d98a69', 'name': 'should_continue', 'tags': ['seq:step:3'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', '72b74d24-5792-48da-a887-102100d6e2c0']}
Receiving new event of type: events...
{'event': 'on_chain_stream', 'run_id': '72b74d24-5792-48da-a887-102100d6e2c0', 'name': 'agent', 'tags': ['graph:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'data': {'chunk': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}, 'input': {'some_bytes': None, 'some_byte_array': None, 'dict_with_bytes': None, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}], 'sleep': None}}, 'run_id': '72b74d24-5792-48da-a887-102100d6e2c0', 'name': 'agent', 'tags': ['graph:step:1'], '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', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: debug...
{'type': 'task_result', 'timestamp': '2024-06-24T21:34:06.124350+00:00', 'step': 1, 'payload': {'id': '212ed9c2-a454-50c5-a202-12066bbbe7b8', 'name': 'agent', 'result': [['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}]]]}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'task_result', 'timestamp': '2024-06-24T21:34:06.124350+00:00', 'step': 1, 'payload': {'id': '212ed9c2-a454-50c5-a202-12066bbbe7b8', 'name': 'agent', 'result': [['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}]]]}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'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}]}]}, 'parent_ids': []}
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}]}}}}}
Receiving new event of type: events...
{'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': ['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}]}}}}}]}, 'parent_ids': []}
Receiving new event of type: debug...
{'type': 'task', 'timestamp': '2024-06-24T21:34:06.124572+00:00', 'step': 2, 'payload': {'id': '44139125-a1be-57c2-9cb2-19eb62bbaf2f', 'name': 'tool', 'input': {'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}], 'sleep': None}, 'triggers': ['branch:agent:should_continue:tool']}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'task', 'timestamp': '2024-06-24T21:34:06.124572+00:00', 'step': 2, 'payload': {'id': '44139125-a1be-57c2-9cb2-19eb62bbaf2f', 'name': 'tool', 'input': {'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}], 'sleep': None}, 'triggers': ['branch:agent:should_continue:tool']}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {}, 'name': 'tool', 'tags': ['graph:step:2'], 'run_id': '91575720-886e-485e-ae2d-d6817e5346bf', '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', 'langgraph_step': 2, 'langgraph_node': 'tool', 'langgraph_triggers': ['branch:agent:should_continue:tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: events...
{'event': 'on_chain_stream', 'run_id': '91575720-886e-485e-ae2d-d6817e5346bf', 'name': 'tool', 'tags': ['graph:step:2'], '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', 'langgraph_step': 2, 'langgraph_node': 'tool', 'langgraph_triggers': ['branch:agent:should_continue:tool'], 'langgraph_task_idx': 0}, 'data': {'chunk': {'messages': [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': None, 'tool_call_id': 'tool_call_id'}]}}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'messages': [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}]}, 'input': {'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}], 'sleep': None}}, 'run_id': '91575720-886e-485e-ae2d-d6817e5346bf', 'name': 'tool', 'tags': ['graph:step:2'], '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', 'langgraph_step': 2, 'langgraph_node': 'tool', 'langgraph_triggers': ['branch:agent:should_continue:tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: debug...
{'type': 'task_result', 'timestamp': '2024-06-24T21:34:06.126828+00:00', 'step': 2, 'payload': {'id': '44139125-a1be-57c2-9cb2-19eb62bbaf2f', 'name': 'tool', 'result': [['messages', [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}]]]}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'task_result', 'timestamp': '2024-06-24T21:34:06.126828+00:00', 'step': 2, 'payload': {'id': '44139125-a1be-57c2-9cb2-19eb62bbaf2f', 'name': 'tool', 'result': [['messages', [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}]]]}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'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'}]}]}, 'parent_ids': []}
Receiving new event of type: messages/complete...
[{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}]
Receiving new event of type: debug...
{'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.126966+00:00', 'step': 2, '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-bc97-6a06-8002-8e9ffc1ea75a', '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'}]}, 'metadata': {'source': 'loop', 'step': 2, 'writes': {'tool': {'messages': [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}]}}}}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.126966+00:00', 'step': 2, '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-bc97-6a06-8002-8e9ffc1ea75a', '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'}]}, 'metadata': {'source': 'loop', 'step': 2, 'writes': {'tool': {'messages': [{'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}]}}}}}]}, 'parent_ids': []}
Receiving new event of type: debug...
{'type': 'task', 'timestamp': '2024-06-24T21:34:06.127034+00:00', 'step': 3, 'payload': {'id': 'f1ccf371-63b3-5268-a837-7f360a93c4ec', 'name': 'agent', 'input': {'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'}], 'sleep': None}, 'triggers': ['tool']}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'task', 'timestamp': '2024-06-24T21:34:06.127034+00:00', 'step': 3, 'payload': {'id': 'f1ccf371-63b3-5268-a837-7f360a93c4ec', 'name': 'agent', 'input': {'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'}], 'sleep': None}, 'triggers': ['tool']}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {}, 'name': 'agent', 'tags': ['graph:step:3'], 'run_id': 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e', '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: events...
{'event': 'on_chat_model_start', 'data': {'input': {'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'}]]}}, 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], 'run_id': '0f2ef0a1-0fc7-445c-9df4-55e8bb284575', '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e']}
Receiving new event of type: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'e', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e']}
Receiving new event of type: messages/metadata...
{'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575': {'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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}}}
Receiving new event of type: messages/partial...
[{'content': 'e', '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: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'n', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e']}
Receiving new event of type: messages/partial...
[{'content': 'en', '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: events...
{'event': 'on_chat_model_stream', 'data': {'chunk': {'content': 'd', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'AIMessageChunk', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None, 'tool_call_chunks': []}}, 'run_id': '0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e']}
Receiving new event of type: messages/partial...
[{'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: events...
{'event': 'on_chat_model_end', 'data': {'output': {'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}, 'input': {'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'}]]}}, 'run_id': '0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'name': 'FakeListChatModel', 'tags': ['seq:step:1'], '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0, 'ls_model_type': 'chat'}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e']}
Receiving new event of type: events...
{'event': 'on_chain_start', 'data': {'input': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'name': 'should_continue', 'tags': ['seq:step:3'], 'run_id': '8af814e9-8136-4aab-acbc-dffc5bcafdfd', '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': '__end__', 'input': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'run_id': '8af814e9-8136-4aab-acbc-dffc5bcafdfd', 'name': 'should_continue', 'tags': ['seq:step:3'], '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25', 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e']}
Receiving new event of type: events...
{'event': 'on_chain_stream', 'run_id': 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e', 'name': 'agent', 'tags': ['graph:step:3'], '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'data': {'chunk': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'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}], 'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}}, 'input': {'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'}], 'sleep': None}}, 'run_id': 'b7d0900c-bfc2-43e4-b760-99bbc5bad84e', 'name': 'agent', 'tags': ['graph:step:3'], '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', 'langgraph_step': 3, 'langgraph_node': 'agent', 'langgraph_triggers': ['tool'], 'langgraph_task_idx': 0}, 'parent_ids': ['1ef32717-bc30-6cf2-8a26-33f63567bc25']}
Receiving new event of type: debug...
{'type': 'task_result', 'timestamp': '2024-06-24T21:34:06.133991+00:00', 'step': 3, 'payload': {'id': 'f1ccf371-63b3-5268-a837-7f360a93c4ec', 'name': 'agent', 'result': [['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}]]]}}
Receiving new event of type: events...
{'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': ['debug', {'type': 'task_result', 'timestamp': '2024-06-24T21:34:06.133991+00:00', 'step': 3, 'payload': {'id': 'f1ccf371-63b3-5268-a837-7f360a93c4ec', 'name': 'agent', 'result': [['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}]]]}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'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}]}}}}}
Receiving new event of type: events...
{'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': ['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}]}}}}}]}, 'parent_ids': []}
Receiving new event of type: events...
{'event': 'on_chain_end', 'data': {'output': {'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}]}}, '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'}, 'parent_ids': []}
Receiving new event of type: end...
None
+156
View File
@@ -0,0 +1,156 @@
# 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.```
First let's set up our client and thread:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
# create thread
thread = await client.threads.create()
print(thread)
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
// create thread
const thread = await client.threads.create();
console.log(thread)
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
Output:
{'thread_id': '979e3c89-a702-4882-87c2-7a59a250ce16',
'created_at': '2024-06-21T15:22:07.453100+00:00',
'updated_at': '2024-06-21T15:22:07.453100+00:00',
'metadata': {},
'status': 'idle',
'config': {}}
Now we can stream by updates, which outputs updates made to the state by each node after it has executed:
=== "Python"
```python
input = {
"messages": [
{
"role": "human",
"content": "what's the weather in la"
}
]
}
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=input,
stream_mode="updates",
):
print(f"Receiving new event of type: {chunk.event}...")
print(chunk.data)
print("\n\n")
```
=== "Javascript"
```js
const input = {
"messages": [
{
"role": "human",
"content": "What's the weather in la",
}
]
}
const streamResponse = client.runs.stream(
thread["thread_id"],
"agent",
{
input,
streamMode: "updates"
}
);
for await (const chunk of streamResponse) {
console.log(f"Receiving new event of type: {chunk.event}...")
console.log(chunk.data)
console.log("\n\n")
}
```
=== "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 la\"}]},
\"stream_mode\": [
\"updates\"
]
}" | \
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:
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': []}]}}
Receiving new event of type: end...
None
+255
View File
@@ -0,0 +1,255 @@
# 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.```
First let's set up our client and thread:
=== "Python"
```python
from langgraph_sdk import get_client
client = get_client(url=<DEPLOYMENT_URL>)
# create thread
thread = await client.threads.create()
print(thread)
```
=== "Javascript"
```js
import { Client } from "@langchain/langgraph-sdk";
const client = new Client({ apiUrl: <DEPLOYMENT_URL> });
// create thread
const thread = await client.threads.create();
console.log(thread)
```
=== "CURL"
```bash
curl --request POST \
--url <DEPLOYMENT_URL>/threads \
--header 'Content-Type: application/json'
```
Output:
{'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4',
'created_at': '2024-06-24T21:30:07.980789+00:00',
'updated_at': '2024-06-24T21:30:07.980789+00:00',
'metadata': {},
'status': 'idle',
'config': {}}
Now we can stream by values, which streams the full state of the graph after each node has finished executing:
=== "Python"
```python
input = {"messages": [{"role": "human", "content": "what's the weather in la"}]}
# stream values
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=input,
stream_mode="values"
):
print(f"Receiving new event of type: {chunk.event}...")
print(chunk.data)
print("\n\n")
```
=== "Javascript"
```js
const input = {"messages": [{"role": "human", "content": "what's the weather in la"}]}
const streamResponse = client.runs.stream(
thread["thread_id"],
"agent",
{
input,
streamMode: "values"
}
);
for await (const chunk of streamResponse) {
console.log(f"Receiving new event of type: {chunk.event}...")
console.log(chunk.data)
console.log("\n\n")
}
```
=== "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 la\"}]},
\"stream_mode\": [
\"values\"
]
}" | \
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:
Receiving new event of type: metadata...
{'run_id': 'f08791ce-0a3d-44e0-836c-ff62cd2e2786'}
Receiving new event of type: values...
{'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': []}]}
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': []}]}
Receiving new event of type: end...
None
If we want to just get the final result, we can use this endpoint and just keep track of the last value we received
=== "Python"
```python
final_answer = None
async for chunk in client.runs.stream(
thread["thread_id"],
"agent",
input=input,
stream_mode="values"
):
if chunk.event == "values":
final_answer = chunk.data
```
=== "Javascript"
```js
let finalAnswer;
const streamResponse = client.runs.stream(
thread["thread_id"],
"agent",
{
input,
streamMode: "values"
}
);
for await (const chunk of streamResponse) {
finalAnswer = chunk.data;
}
```
=== "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 la\"}]},
\"stream_mode\": [
\"values\"
]
}" | \
sed 's/\r$//' | \
awk '
/^data:/ {
sub(/^data: /, "", $0)
data_content = $0
}
END {
if (data_content != "") {
print data_content
}
}
'
```
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': []}]}
@@ -0,0 +1,16 @@
# Test Cloud Deployment
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. 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).
The following video shows these exact steps being carried out:
<video controls allowfullscreen="true" poster="../img/studio_usage_poster.png">
<source src="../img/studio_usage.mp4" type="video/mp4">
</video>
@@ -0,0 +1,28 @@
# LangGraph Studio With Local Deployment
!!! warning "Browser Compatibility"
Viewing the studio page of a local LangGraph deployment does not work in Safari. Use Chrome instead.
## Setup
Make sure you have setup your app correctly, by creating a compiled graph, a `.env` file with any environment variables, and a `langgraph.json` config file that points to your environment file and compiled graph. See [here](https://langchain-ai.github.io/langgraph/cloud/deployment/setup/) for more detailed instructions.
After you have your app setup, head into the directory with your `langgraph.json` file and call `langgraph up -c langgraph.json --watch` to start the API server in watch mode which means it will restart on code changes, which is ideal for local testing. If the API server start correctly you should see logs that look something like this:
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
Read this [reference](https://langchain-ai.github.io/langgraph/cloud/reference/cli/#up) to learn about all the options for starting the API server.
## Access Studio
Once you have successfully started the API server, you can access the studio by going to the following URL: `https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:8123` (see warning above if using Safari).
If everything is working correctly you should see the studio show up looking something like this (with your graph diagram on the left hand side):
![LangGraph Studio](./img/studio_screenshot.png)
## Use the Studio for Testing
To learn about how to use the studio for testing, read the [LangGraph Studio how-tos](https://langchain-ai.github.io/langgraph/cloud/how-tos/#langgraph-studio).
+23
View File
@@ -0,0 +1,23 @@
# Interacting with Threads in Studio
## View Thread
1. In the top of the right-hand pane, select the `New Thread` dropdown menu to view existing threads.
1. View the state of the thread (i.e. the output) in the right-hand pane.
1. To create a new thread, select `+ New Thread`.
The following video shows these exact steps being carried out:
<video controls="true" allowfullscreen="true" poster="../img/studio_threads_poster.png">
<source src="../img/studio_threads.mp4" type="video/mp4">
</video>
## Edit Thread State
The LangGraph Studio UI contains features for editing thread state. Explore these features in the right-hand pane. Select the `Edit` icon, modify the desired state, and then select `Fork` to invoke the assistant with the updated state.
The following video shows how to edit a thread in the studio:
<video controls allowfullscreen="true" poster="../img/studio_forks_poster.png">
<source src="../img/studio_forks.mp4" type="video/mp4">
</video>
Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 KiB

+44
View File
@@ -0,0 +1,44 @@
# 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.
+262
View File
@@ -0,0 +1,262 @@
# 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.
## 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/)
## Set up local files
1. Create a new application with the following 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
2. The `agent.py` file should contain Python 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, read more about it [here](..//concepts/agentic_concepts.md#react-agent).
```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)
```
3. The `requirements.txt` file should contain any dependencies for your graph(s). In this case we only require four packages for our graph to run:
langgraph
langchain_anthropic
tavily-python
langchain_community
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`.
```json
{
"dependencies": ["."],
"graphs": {
"agent": "./agent.py:graph"
},
"env": ".env"
}
```
Learn more about the LangGraph CLI configuration file [here](./reference/cli.md#configuration-file).
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:
```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.
## Test the graph build locally
### Using LangGraph Studio Desktop (recommended)
![LangGraph Studio Desktop](./img/graph_video_poster.png)
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
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.
### 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
```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.
```shell
langgraph up
```
This will start up the LangGraph API server locally. If this runs successfully, you should see something like:
```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:
```shell
curl --request POST \
--url http://localhost:8123/runs/stream \
--header 'Content-Type: application/json' \
--data '{
"assistant_id": "agent",
"input": {
"messages": [
{
"role": "user",
"content": "How are you?"
}
]
},
"metadata": {},
"config": {
"configurable": {}
},
"multitask_strategy": "reject",
"stream_mode": [
"values"
]
}'
```
If you get back a valid response, then all is functioning properly!
## Deploy to Cloud
### Push your code to GitHub
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)).
### Deploy from GitHub with LangGraph Cloud
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.
![Langsmith Workflow](./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:
![Deployment before being filled out](./deployment/img/deployment_page.png)
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)
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.
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.
### 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.
![Studio UI once being run](./deployment/img/graph_run.png)
## Use with the 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.
First, make sure you have the SDK installed by calling `pip install 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.
You also need to make sure you have set up your API key properly so you can authenticate with LangGraph Cloud.
```shell
export LANGSMITH_API_KEY=...
```
The first thing to do when using the SDK is to setup our client, access our assistant, and create a thread to execute a run on:
```python
from langgraph_sdk import get_client
# Replace this with the URL of your own deployed graph
URL = "https://chatbot-23a570f3210f52a7b167f09f6158e3b3-ffoprvkqsa-uc.a.run.app"
client = get_client(url=URL)
# Search all hosted graphs
assistants = await client.assistants.search()
# In this example we select the first assistant since we are only hosting a single graph
assistant = assistants[0]
# We create a thread for tracking the state of our run
thread = await client.threads.create()
```
We can then execute a run on the thread:
```python
input = {"messages":[{"role": "user", "content": "Hello! My name is Bagatur and I am 26 years old."}]}
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":
print(chunk.data)
```
{'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
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.
@@ -0,0 +1,19 @@
<!doctype html>
<html>
<head>
<title>LangGraph Cloud API Reference</title>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1" />
</head>
<body>
<script id="api-reference" data-url="./openapi.json"></script>
<script>
var configuration = {}
document.getElementById('api-reference').dataset.configuration =
JSON.stringify(configuration)
</script>
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
</body>
</html>
+22
View File
@@ -0,0 +1,22 @@
# API Reference
The LangGraph Cloud API reference is available with each deployment at the `/docs` URL path (e.g. `http://localhost:8124/docs`).
Click <a href="/langgraph/cloud/reference/api/api_ref.html" target="_blank">here</a> to view the API reference.
## Authentication
For deployments to LangGraph Cloud, authentication is required. Pass the `X-Api-Key` header with each request to the LangGraph Cloud API. The value of the header should be set to a valid LangSmith API key for the organization where the API is deployed.
Example `curl` command:
```shell
curl --request POST \
--url http://localhost:8124/assistants/search \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: LANGSMITH_API_KEY' \
--data '{
"metadata": {},
"limit": 10,
"offset": 0
}'
```
File diff suppressed because it is too large Load Diff
+127
View File
@@ -0,0 +1,127 @@
# 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.
## Installation
1. Ensure that Docker is installed (e.g. `docker --version`).
2. Install the `langgraph-cli` Python package (e.g. `pip 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. |
<div class="admonition tip">
<p class="admonition-title">Note</p>
<p>
The LangGraph CLI defaults to using the configuration file <strong>langgraph.json</strong> in the current directory.
</p>
</div>
Example:
```json
{
"dependencies": [
"langchain_openai",
"./your_package"
],
"graphs": {
"my_graph_id": "./your_package/your_file.py:variable"
},
"env": "./.env"
}
```
Example:
```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"
}
}
```
## Commands
The base command for the LangGraph CLI is `langgraph`.
**Usage**
```
langgraph [OPTIONS] COMMAND [ARGS]
```
### `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. |
### `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.
**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. |
### `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, ...)`
**Usage**
```
langgraph test [OPTIONS]
```
**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. |
+13
View File
@@ -0,0 +1,13 @@
# Environment Variables
The LangGraph Cloud API supports specific environment variables for configuring a deployment.
## `LANGGRAPH_AUTH_TYPE`
Type of authentication for the LangGraph Cloud API deployment. Valid values: `langsmith`, `noop`.
For deployments to LangGraph Cloud, this environment variable is set automatically. For local development or deployments where authentication is handled externally (e.g. self-hosted), set this environment variable to `noop`.
## `N_JOBS_PER_WORKER`
Number of jobs per worker for the LangGraph Cloud task queue. Defaults to `10`.
@@ -0,0 +1,79 @@
# 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
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
handler: python
Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

+4
View File
@@ -0,0 +1,4 @@
tags:
- concepts
- conceptual guide
- explanation
+118
View File
@@ -0,0 +1,118 @@
# Common Agentic Patterns
## Structured Output
It's pretty common to want LLMs inside nodes to return structured output when building agents. This is because that structured output can often be used to route to the next step (e.g. choose between two different edges) or update specific keys of the state.
Since LangGraph nodes can be arbitrary Python functions, you can do this however you want. If you want to use LangChain, [this how-to guide](https://python.langchain.com/v0.2/docs/how_to/structured_output/) is a starting point.
## Tool calling
It's extremely common to want agents to do tool calling. Tool calling refers to choosing from several available tools, and specifying which ones to call and what the inputs should be. This is extremely common in agents, as you often want to let the LLM decide which tools to call and then call those tools.
Since LangGraph nodes can be arbitrary Python functions, you can do this however you want. If you want to use LangChain, [this how-to guide](https://python.langchain.com/v0.2/docs/how_to/tool_calling/) is a starting point.
## Memory
Memory is a key concept to agentic applications. Memory is important because end users often expect the application they are interacting with remember previous interactions. The most simple example of this is chatbots - they clearly need to remember previous messages in a conversation.
LangGraph is perfectly suited to give you full control over the memory of your application. With user defined [`State`](./low_level.md#state) you can specify the exact schema of the memory you want to retain. With [checkpointers](./low_level.md#checkpointer) you can store checkpoints of previous interactions and resume from there in follow up interactions.
See [this guide](../how-tos/persistence.ipynb) for how to add memory to your graph.
## Human-in-the-loop
Agentic systems often require some human-in-the-loop (or "on-the-loop") interaction patterns. This is because agentic systems are still not super reliable, so having a human involved is required for any sensitive tasks/actions. These are all easily enabled in LangGraph, largely due to [checkpointers](./low_level.md#checkpointer). The reason a checkpointer is necessary is that a lot of these interaction patterns involve running a graph up until a certain point, waiting for some sort of human feedback, and then continuing. When you want to "continue" you will need to access the state of the graph previous to getting interrupted, and checkpointers are a built in, highly convenient way to do that.
There are a few common human-in-the-loop interaction patterns we see emerging.
### Approval
A basic one is to have the agent wait for approval before executing certain tools. This may be all tools, or just a subset of tools. This is generally recommend for more sensitive actions (like writing to a database). This can easily be done in LangGraph by setting a [breakpoint](./low_level.md#breakpoints) before specific nodes.
See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for how do this in LangGraph.
### Wait for input
A similar one is to have the agent wait for human input. This can be done by:
1. Create a node specifically for human input
2. Add a breakpoint before the node
3. Get user input
4. Update the state with that user input, acting as that node
5. Resume execution
See [this guide](../how-tos/human_in_the_loop/wait-user-input.ipynb) for how do this in LangGraph.
### Edit agent actions
This is a more advanced interaction pattern. In this interaction pattern the human can actually edit some of the agent's previous decisions. This can be done either during the flow (after a [breakpoint](./low_level.md#breakpoints), part of the [approval](#approval) flow) or after the fact (as part of [time-travel](#time-travel))
See [this guide](../how-tos/human_in_the_loop/edit-graph-state.ipynb) for how do this in LangGraph.
### Time travel
This is a pretty advanced interaction pattern. In this interaction pattern, the human can look back at the list of previous checkpoints, find one they like, optionally [edit it](#edit-agent-actions), and then resume execution from there.
See [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for how to do this in LangGraph.
## Review Tool Calls
This is a specific type of human-in-the-loop interaction but it's worth calling out because it is so common. A lot of agent decisions are made via tool calling, so having a clear UX for reviewing tool calls is handy.
A tool call consists of:
- The name of the tool to call
- Arguments to pass to the tool
Note that these tool calls can obviously be used for actually calling functions, but they can also be used for other purposes, like to route the agent in a specific direction.
You will want to review the tool call for both of these use cases.
When reviewing tool calls, there are few actions you may want to take.
1. Approve the tool call (and let the agent continue on its way)
2. Manually change the tool call, either the tool name or the tool arguments (and let the agent continue on its way after that)
3. Leave feedback on the tool call. This differs from (2) in that you are not changing the tool call directly, but rather leaving natural language feedback suggesting the LLM call it differently (or call a different tool). You could do this by either adding a `ToolMessage` and having the feedback be the result of the tool call, or by adding a `ToolMessage` (that simulates an error) and then a `HumanMessage` (with the feedback).
See [this guide](../how-tos/human_in_the_loop/review-tool-calls.ipynb) for how to do this in LangGraph.
## Map-Reduce
A common pattern in agents is to generate a list of objects, do some work on each of those objects, and then combine the results. This is very similar to the common [map-reduce](https://en.wikipedia.org/wiki/MapReduce) operation. This can be tricky for a few reasons. First, it can be tough to define a structured graph ahead of time because the length of the list of objects may be unknown. Second, in order to do this map-reduce you need multiple versions of the state to exist... but the graph shares a common shared state, so how can this be?
LangGraph supports this via the [Send](./low_level.md#send) api. This can be used to allow a conditional edge to Send multiple different states to multiple nodes. The state it sends can be different from the state of the core graph.
See a how-to guide for this [here](../how-tos/map-reduce.ipynb)
## Multi-agent
A term you may have heard is "multi-agent" architectures. What exactly does this mean?
Given that it is hard to even define an "agent", it's almost impossible to exactly define a "multi-agent" architecture. When most people talk about a multi-agent architecture, they typically mean a system where there are multiple different LLM-based systems. These LLM-based systems can be as simple as a prompt and an LLM call, or as complex as a [ReAct agent](#react-agent).
The big question in multi-agent systems is how they communicate. This involves both the schema of how they communicate, as well as the sequence in which they communicate. LangGraph is perfect for orchestrating these types of systems. It allows you to define multiple agents (each one is a node) an arbitrary state (to encapsulate the schema of how they communicate) as well as the edges (to control the sequence in which they communicate).
## Planning
One of the big things that agentic systems struggle with is long term planning. A common technique to overcome this is to have an explicit planning this. This generally involves calling an LLM to come up with a series of steps to execute. From there, the system then tries to execute the series of tasks (this could use a sub-agent to do so). Optionally, you can revisit the plan after each step and update it if needed.
## Reflection
Agents often struggle to produce reliable results. Therefore, it can be helpful to check whether the agent has completed a task correctly or not. If it has - then you can finish. If it hasn't - then you can take the feedback on why it's not correct and pass it back into another iteration of the agent.
This "reflection" step often uses an LLM, but doesn't have to. A good example of where using an LLM may not be necessary is in coding, when you can try to compile the generated code and use any errors as the feedback.
## ReAct Agent
One of the most common agent architectures is what is commonly called the ReAct agent architecture. In this architecture, an LLM is called repeatedly in a while-loop. At each step the agent decides which tools to call, and what the inputs to those tools should be. Those tools are then executed, and the outputs are fed back into the LLM as observations. The while-loop terminates when the agent decides it is not worth calling any more tools.
One of the few high level, pre-built agents we have in LangGraph - you can use it with [`create_react_agent`](../reference/prebuilt.md#create_react_agent)
This is named after and based on the [ReAct](https://arxiv.org/abs/2210.03629) paper. However, there are several differences between this paper and our implementation:
- First, we use [tool-calling](#tool-calling) to have LLMs call tools, whereas the paper used prompting + parsing of raw output. This is because tool calling did not exist when the paper was written, but is generally better and more reliable.
- Second, we use messages to prompt the LLM, whereas the paper used string formatting. This is because at the time of writing, LLMs didn't even expose a message-based interface, whereas now that's the only interface they expose.
- Third, the paper required all inputs to the tools to be a single string. This was largely due to LLMs not being super capable at the time, and only really being able to generate a single input. Our implementation allows for using tools that require multiple inputs.
- Forth, the paper only looks at calling a single tool at the time, largely due to limitations in LLMs performance at the time. Our implementation allows for calling multiple tools at a time.
- Finally, the paper asked the LLM to explicitly generate a "Thought" step before deciding which tools to call. This is the "Reasoning" part of "ReAct". Our implementation does not do this by default, largely because LLMs have gotten much better and that is not as necessary. Of course, if you wish to prompt it do so, you certainly can.
See [this guide](../how-tos/human_in_the_loop/time-travel.ipynb) for a full walkthrough of how to use the prebuilt ReAct agent.
+15
View File
@@ -0,0 +1,15 @@
# FAQ
Common questions and their answers!
## Do I need to use LangChain in order to use LangGraph?
No! LangGraph is a general-purpose framework - the nodes and edges are nothing more than Python functions. You can use LangChain, raw HTTP requests, or even other frameworks inside these nodes and edges.
## Does LangGraph work with LLMs that don't support tool calling?
Yes! You can use LangGraph with any LLMs. The main reason we use LLMs that support tool calling is that this is often the most convenient way to have the LLM make its decision about what to do. If your LLM does not support tool calling, you can still use it - you just need to write a bit of logic to convert the raw LLM string response to a decision about what to do.
## Does LangGraph work with OSS LLMs?
Yes! LangGraph is totally ambivalent to what LLMs are used under the hood. The main reason we use closed LLMs in most of the tutorials is that they seamlessly support tool calling, while OSS LLMs often don't. But tool calling is not necessary (see [this section](#does-langgraph-work-with-llms-that-dont-support-tool-calling)) so you can totally use LangGraph with OSS LLMs.
+55
View File
@@ -0,0 +1,55 @@
# LangGraph for Agentic Applications
## What does it mean to be agentic?
Other people may talk about a system being an "agent" - we prefer to talk about systems being "agentic". But what does this actually mean?
When we talk about systems being "agentic", we are talking about systems that use an LLM to decide the control flow of an application. There are different levels that an LLM can be used to decide the control flow, and this spectrum of "agentic" makes more sense to us than defining an arbitrary cutoff for what is or isn't an agent.
Examples of using an LLM to decide the control of an application:
- Using an LLM to route between two potential paths
- Using an LLM to decide which of many tools to call
- Using an LLM to decide whether the generated answer is sufficient or more work is need
The more times these types of decisions are made inside an application, the more agentic it is.
If these decisions are being made in a loop, then its even more agentic!
There are other concepts often associated with being agentic, but we would argue these are a by-product of the above definition:
- [Tool calling](agentic_concepts.md#tool-calling): this is often how LLMs make decisions
- Action taking: often times, the LLMs' outputs are used as the input to an action
- [Memory](agentic_concepts.md#memory): reliable systems need to have knowledge of things that occurred
- [Planning](agentic_concepts.md#planning): planning steps (either explicit or implicit) are useful for ensuring that the LLM, when making decisions, makes them in the highest fidelity way.
## Why LangGraph?
LangGraph has several core principles that we believe make it the most suitable framework for building agentic applications:
- [Controllability](../how-tos/index.md#controllability)
- [Human-in-the-Loop](../how-tos/index.md#human-in-the-loop)
- [Streaming First](../how-tos/index.md#streaming)
**Controllability**
LangGraph is extremely low level. This gives you a high degree of control over what the system you are building actually does. We believe this is important because it is still hard to get agentic systems to work reliably, and we've seen that the more control you exercise over them, the more likely it is that they will "work".
**Human-in-the-Loop**
LangGraph comes with a built-in persistence layer as a first-class concept. This enables several different human-in-the-loop interaction patterns. We believe that "Human-Agent Interaction" patterns will be the new "Human-Computer Interaction", and have built LangGraph with built in persistence to enable this.
**Streaming First**
LangGraph comes with first class support for streaming. Agentic applications often take a while to run, and so giving the user some idea of what is happening is important, and streaming is a great way to do that. LangGraph supports streaming of both events ([like a tool call being taken](../how-tos/stream-updates.ipynb)) as well as of [tokens that an LLM may emit](../how-tos/streaming-tokens.ipynb).
## Deployment
So you've built your LangGraph object - now what?
Now you need to deploy it.
There are many ways to deploy LangGraph objects, and the right solution depends on your needs and use case.
We'll highlight two ways here: using [LangGraph Cloud](../cloud/index.md) or rolling your own solution.
[LangGraph Cloud](../cloud/index.md) is an opinionated way to deploy LangGraph objects from the LangChain team. Please see the [LangGraph Cloud documentation](../cloud/index.md) for all the details about what it involves, to see if it is a good fit for you.
If it is not a good fit, you may want to roll your own deployment. In this case, we would recommend using [FastAPI](https://fastapi.tiangolo.com/) to stand up a server. You can then call this graph from inside the FastAPI server as you see fit.
+57
View File
@@ -0,0 +1,57 @@
# Conceptual Guides
In this guide we will explore the concepts behind build agentic and multi-agent systems with LangGraph. We assume you have already learned the basic covered in the [introduction tutorial](../tutorials/introduction.ipynb) and want to deepen your understanding of LangGraph's underlying design and inner workings.
There are three main parts to this concept guide. First, we'll discuss at a very high level what it means to be agentic. Next, we'll look at lower-level concepts in LangGraph that are core for understanding how to build your own agentic systems. Finally, we'll discuss common agentic patterns and how you can achieve those with LangGraph. These will be mostly conceptual guides - for more technical, hands-on guides see our [how-to guides](../how-tos/index.md)
LangGraph for Agentic Applications
- [What does it mean to be agentic?](high_level.md#what-does-it-mean-to-be-agentic)
- [Why LangGraph](high_level.md#why-langgraph)
- [Deployment](high_level.md#deployment)
Low Level Concepts
- [Graphs](low_level.md#graphs)
- [StateGraph](low_level.md#stategraph)
- [MessageGraph](low_level.md#messagegraph)
- [Compiling Your Graph](low_level.md#compiling-your-graph)
- [State](low_level.md#state)
- [Schema](low_level.md#schema)
- [Reducers](low_level.md#reducers)
- [MessageState](low_level.md#working-with-messages-in-graph-state)
- [Nodes](low_level.md#nodes)
- [`START` node](low_level.md#start-node)
- [`END` node](low_level.md#end-node)
- [Edges](low_level.md#edges)
- [Normal Edges](low_level.md#normal-edges)
- [Conditional Edges](low_level.md#conditional-edges)
- [Entry Point](low_level.md#entry-point)
- [Conditional Entry Point](low_level.md#conditional-entry-point)
- [Send](low_level.md#send)
- [Checkpointer](low_level.md#checkpointer)
- [Threads](low_level.md#threads)
- [Checkpointer states](low_level.md#checkpointer-state)
- [Get state](low_level.md#get-state)
- [Get state history](low_level.md#get-state-history)
- [Update state](low_level.md#update-state)
- [Configuration](low_level.md#configuration)
- [Visualization](low_level.md#visualization)
- [Streaming](low_level.md#streaming)
Common Agentic Patterns
- [Structured output](agentic_concepts.md#structured-output)
- [Tool calling](agentic_concepts.md#tool-calling)
- [Memory](agentic_concepts.md#memory)
- [Human in the loop](agentic_concepts.md#human-in-the-loop)
- [Approval](agentic_concepts.md#approval)
- [Wait for input](agentic_concepts.md#wait-for-input)
- [Edit agent actions](agentic_concepts.md#edit-agent-actions)
- [Time travel](agentic_concepts.md#time-travel)
- [Map-Reduce](agentic_concepts.md#map-reduce)
- [Multi-agent](agentic_concepts.md#multi-agent)
- [Planning](agentic_concepts.md#planning)
- [Reflection](agentic_concepts.md#reflection)
- [Off-the-shelf ReAct Agent](agentic_concepts.md#react-agent)
+638
View File
@@ -0,0 +1,638 @@
# Low Level Conceptual Guide
## Graphs
At its core, LangGraph models agent workflows as graphs. You define the behavior of your agents using three key components:
1. [`State`](#state): A shared data structure that represents the current snapshot of your application. It can be any Python type, but is typically a `TypedDict` or Pydantic `BaseModel`.
2. [`Nodes`](#nodes): Python functions that encode the logic of your agents. They receive the current `State` as input, perform some computation or side-effect, and return an updated `State`.
3. [`Edges`](#edges): Python functions that determine which `Node` to execute next based on the current `State`. They can be conditional branches or fixed transitions.
By composing `Nodes` and `Edges`, you can create complex, looping workflows that evolve the `State` over time. The real power, though, comes from how LangGraph manages that `State`. To emphasize: `Nodes` and `Edges` are nothing more than Python functions - they can contain an LLM or just good ol' Python code.
In short: _nodes do the work. edges tell what to do next_.
LangGraph's underlying graph algorithm uses [message passing](https://en.wikipedia.org/wiki/Message_passing) to define a general program. When a Node completes its operation, it sends messages along one or more edges to other node(s). These recipient nodes then execute their functions, pass the resulting messages to the next set of nodes, and the process continues. Inspired by Google's [Pregel](https://research.google/pubs/pregel-a-system-for-large-scale-graph-processing/) system, the program proceeds in discrete "super-steps."
A super-step can be considered a single iteration over the graph nodes. Nodes that run in parallel are part of the same super-step, while nodes that run sequentially belong to separate super-steps. At the start of graph execution, all nodes begin in an `inactive` state. A node becomes `active` when it receives a new message (state) on any of its incoming edges (or "channels"). The active node then runs its function and responds with updates. At the end of each super-step, nodes with no incoming messages vote to `halt` by marking themselves as `inactive`. The graph execution terminates when all nodes are `inactive` and no messages are in transit.
### StateGraph
The `StateGraph` class is the main graph class to uses. This is parameterized by a user defined `State` object.
### MessageGraph
The `MessageGraph` class is a special type of graph. The `State` of a `MessageGraph` is ONLY a list of messages. This class is rarely used except for chatbots, as most applications require the `State` to be more complex than a list of messages.
### Compiling your graph
To build your graph, you first define the [state](#state), you then add [nodes](#nodes) and [edges](#edges), and then you compile it. What exactly is compiling your graph and why is it needed?
Compiling is a pretty simple step. It provides a few basic checks on the structure of your graph (no orphaned nodes, etc). It is also where you can specify runtime args like [checkpointers](#checkpointer) and [breakpoints](#breakpoints). You compile your graph by just calling the `.compile` method:
```python
graph = graph_builder.compile(...)
```
You **MUST** compile your graph before you can use it.
## State
The first thing you do when you define a graph is define the `State` of the graph. The `State` consists of the [schema of the graph](#schema) as well as [`reducer` functions](#reducers) which specify how to apply updates to the state. The schema of the `State` will be the input schema to all `Nodes` and `Edges` in the graph, and can be either a `TypedDict` or a `Pydantic` model. All `Nodes` will emit updates to the `State` which are then applied using the specified `reducer` function.
### Schema
The main documented way to specify the schema of a graph is by using `TypedDict`. However, we also support [using a Pydantic BaseModel](../how-tos/state-model.ipynb) as your graph state to add **default values** and additional data validation.
By default, the graph will have the same input and output schemas. If you want to change this, you can also specify explicit input and output schemas directly. This is useful when you have a lot of keys, and some are explicitly for input and others for output. See the [notebook here](../how-tos/input_output_schema.ipynb) for how to use.
By default, all nodes in the graph will share the same state. This means that they will read and write to the same state channels. It is possible to have nodes write to private state channels inside the graph for internal node communication - see [this notebook](../how-tos/pass_private_state.ipynb) for how to do that.
### Reducers
Reducers are key to understanding how updates from nodes are applied to the `State`. Each key in the `State` has its own independent reducer function. If no reducer function is explicitly specified then it is assumed that all updates to that key should override it. There are a few different types of reducers, starting with the default type of reducer:
#### Default Reducer
These two examples show how to use the default reducer:
**Example A:**
```python
from typing import TypedDict
class State(TypedDict):
foo: int
bar: list[str]
```
In this example, no reducer functions are specified for any key. Let's assume the input to the graph is `{"foo": 1, "bar": ["hi"]}`. Let's then assume the first `Node` returns `{"foo": 2}`. This is treated as an update to the state. Notice that the `Node` does not need to return the whole `State` schema - just an update. After applying this update, the `State` would then be `{"foo": 2, "bar": ["hi"]}`. If the second node returns `{"bar": ["bye"]}` then the `State` would then be `{"foo": 2, "bar": ["bye"]}`
**Example B:**
```python
from typing import TypedDict, Annotated
from operator import add
class State(TypedDict):
foo: int
bar: Annotated[list[str], add]
```
In this example, we've used the `Annotated` type to specify a reducer function (`operator.add`) for the second key (`bar`). Note that the first key remains unchanged. Let's assume the input to the graph is `{"foo": 1, "bar": ["hi"]}`. Let's then assume the first `Node` returns `{"foo": 2}`. This is treated as an update to the state. Notice that the `Node` does not need to return the whole `State` schema - just an update. After applying this update, the `State` would then be `{"foo": 2, "bar": ["hi"]}`. If the second node returns `{"bar": ["bye"]}` then the `State` would then be `{"foo": 2, "bar": ["hi", "bye"]}`. Notice here that the `bar` key is updated by adding the two lists together.
#### Context Reducer
You can use `Context` channels to define shared resources (such as database connections) that are managed outside of your graph's nodes and excluded from checkpointing. The context manager provided to the Context channel is entered before the first step of the graph execution and exited after the last step, allowing you to set up and clean up resources for the duration of the graph invocation. Read this [how to](https://langchain-ai.github.io/langgraph/how-tos/state-context-key) to see an example of using the `Context` channel in your graph.
### Working with Messages in Graph State
#### Why use messages?
Most modern LLM providers have a chat model interface that accepts a list of messages as input. LangChain's [`ChatModel`](https://python.langchain.com/v0.2/docs/concepts/#chat-models) in particular accepts a list of `Message` objects as inputs. These messages come in a variety of forms such as `HumanMessage` (user input) or `AIMessage` (LLM response). To read more about what message objects are, please refer to [this](https://python.langchain.com/v0.2/docs/concepts/#messages) conceptual guide.
#### Using Messages in your Graph
In many cases, it is helpful to store prior conversation history as a list of messages in your graph state. To do so, we can add a key (channel) to the graph state that stores a list of `Message` objects and annotate it with a reducer function (see `messages` key in the example below). The reducer function is vital to telling the graph how to update the list of `Message` objects in the state with each state update (for example, when a node sends an update). If you don't specify a reducer, every state update will overwrite the list of messages with the most recently provided value. If you wanted to simply append messages to the existing list, you could use `operator.add` as a reducer.
However, you might also want to manually update messages in your graph state (e.g. human-in-the-loop). If you were to use `operator.add`, the manual state updates you send to the graph would be appended to the existing list of messages, instead of updating existing messages. To avoid that, you need a reducer that can keep track of message IDs and overwrite existing messages, if updated. To achieve this, you can use the prebuilt `add_messages` function. For brand new messages, it will simply append to existing list, but it will also handle the updates for existing messages correctly.
#### Serialization
In addition to keeping track of message IDs, the `add_messages` function will also try to deserialize messages into LangChain `Message` objects whenever a state update is received on the `messages` channel. See more information on LangChain serialization/deserialization [here](https://python.langchain.com/v0.2/docs/how_to/serialization/). This allows sending graph inputs / state updates in the following format:
```python
# this is supported
{"messages": [HumanMessage(content="message")]}
# and this is also supported
{"messages": [{"type": "human", "content": "message"}]}
```
Since the state updates are always deserialized into LangChain `Messages` when using `add_messages`, you should use dot notation to access message attributes, like `state["messages"][-1].content`. Below is an example of a graph that uses `add_messages` as it's reducer function.
```python
from langchain_core.messages import AnyMessage
from langgraph.graph.message import add_messages
from typing import Annotated, TypedDict
class GraphState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
```
#### MessagesState
Since having a list of messages in your state is so common, there exists a prebuilt state called `MessagesState` which makes it easy to use messages. `MessagesState` is defined with a single `messages` key which is a list of `AnyMessage` objects and uses the `add_messages` reducer. Typically, there is more state to track than just messages, so we see people subclass this state and add more fields, like:
```python
from langgraph.graph import MessagesState
class State(MessagesState):
documents: list[str]
```
## Nodes
In LangGraph, nodes are typically python functions (sync or `async`) where the **first** positional argument is the [state](#state), and (optionally), the **second** positional argument is a "config", containing optional [configurable parameters](#configuration) (such as a `thread_id`).
Similar to `NetworkX`, you add these nodes to a graph using the [add_node][langgraph.graph.StateGraph.add_node] method:
```python
from langchain_core.runnables import RunnableConfig
from langgraph.graph import StateGraph
builder = StateGraph(dict)
def my_node(state: dict, config: RunnableConfig):
print("In node: ", config["configurable"]["user_id"])
return {"results": f"Hello, {state['input']}!"}
# The second argument is optional
def my_other_node(state: dict):
return state
builder.add_node("my_node", my_node)
builder.add_node("other_node", my_other_node)
...
```
Behind the scenes, functions are converted to [RunnableLambda's](https://api.python.langchain.com/en/latest/runnables/langchain_core.runnables.base.RunnableLambda.html#langchain_core.runnables.base.RunnableLambda), which add batch and async support to your function, along with native tracing and debugging.
If you add a node to graph without specifying a name, it will be given a default name equivalent to the function name.
```python
builder.add_node(my_node)
# You can then create edges to/from this node by referencing it as `"my_node"`
```
### `START` Node
The `START` Node is a special node that represents the node sends user input to the graph. The main purpose for referencing this node is to determine which nodes should be called first.
```python
from langgraph.graph import START
graph.add_edge(START, "node_a")
```
### `END` Node
The `END` Node is a special node that represents a terminal node. This node is referenced when you want to denote which edges have no actions after they are done.
```
from langgraph.graph import END
graph.add_edge("node_a", END)
```
## Edges
Edges define how the logic is routed and how the graph decides to stop. This is a big part of how your agents work and how different nodes communicate with each other. There are a few key types of edges:
- Normal Edges: Go directly from one node to the next.
- Conditional Edges: Call a function to determine which node(s) to go to next.
- Entry Point: Which node to call first when user input arrives.
- Conditional Entry Point: Call a function to determine which node(s) to call first when user input arrives.
A node can have MULTIPLE outgoing edges. If a node has multiple out-going edges, **all** of those destination nodes will be executed in parallel as a part of the next superstep.
### Normal Edges
If you **always** want to go from node A to node B, you can use the [add_edge][langgraph.graph.StateGraph.add_edge] method directly.
```python
graph.add_edge("node_a", "node_b")
```
### Conditional Edges
If you want to **optionally** route to 1 or more edges (or optionally terminate), you can use the [add_conditional_edges][langgraph.graph.StateGraph.add_conditional_edges] method. This method accepts the name of a node and a "routing function" to call after that node is executed:
```python
graph.add_conditional_edges("node_a", routing_function)
```
Similar to nodes, the `routing_function` accept the current `state` of the graph and return a value.
By default, the return value `routing_function` is used as the name of the node (or a list of nodes) to send the state to next. All those nodes will be run in parallel as a part of the next superstep.
You can optionally provide a dictionary that maps the `routing_function`'s output to the name of the next node.
```python
graph.add_conditional_edges("node_a", routing_function, {True: "node_b", False: "node_c"})
```
### Entry Point
The entry point is the first node(s) that are run when the graph starts. You can use the [`add_edge`][langgraph.graph.StateGraph.add_edge] method from the virtual [`START`][start] node to the first node to execute to specify where to enter the graph.
```python
from langgraph.graph import START
graph.add_edge(START, "node_a")
```
### Conditional Entry Point
A conditional entry point lets you start at different nodes depending on custom logic. You can use [`add_conditional_edges`][langgraph.graph.StateGraph.add_conditional_edges] from the virtual [`START`][start] node to accomplish this.
```python
from langgraph.graph import START
graph.add_conditional_edges(START, routing_function)
```
You can optionally provide a dictionary that maps the `routing_function`'s output to the name of the next node.
```python
graph.add_conditional_edges(START, routing_function, {True: "node_b", False: "node_c"})
```
## `Send`
By default, `Nodes` and `Edges` are defined ahead of time and operate on the same shared state. However, there can be cases where the exact edges are not known ahead of time and/or you may want different versions of `State` to exist at the same time. A common of example of this is with `map-reduce` design patterns. In this design pattern, a first node may generate a list of objects, and you may want to apply some other node to all those objects. The number of objects may be unknown ahead of time (meaning the number of edges may not be known) and the input `State` to the downstream `Node` should be different (one for each generated object).
To support this design pattern, LangGraph supports returning [`Send`](../reference/graphs.md#send) objects from conditional edges. `Send` takes two arguments: first is the name of the node, and second is the state to pass to that node.
```python
def continue_to_jokes(state: OverallState):
return [Send("generate_joke", {"subject": s}) for s in state['subjects']]
graph.add_conditional_edges("node_a", continue_to_jokes)
```
## Checkpointer
LangGraph has a built-in persistence layer, implemented through [checkpointers][basecheckpointsaver]. When you use a checkpointer with a graph, you can interact with the state of that graph. When you use a checkpointer with a graph, you can interact with and manage the graph's state. The checkpointer saves a _checkpoint_ of the graph state at every super-step, enabling several powerful capabilities:
First, checkpointers facilitate [human-in-the-loop workflows](agentic_concepts.md#human-in-the-loop) workflows by allowing humans to inspect, interrupt, and approve steps.Checkpointers are needed for these workflows as the human has to be able to view the state of a graph at any point in time, and the graph has to be to resume execution after the human has made any updates to the state.
Second, it allows for ["memory"](agentic_concepts.md#memory) between interactions. You can use checkpointers to create threads and save the state of a thread after a graph executes. In the case of repeated human interactions (like conversations) any follow up messages can be sent to that checkpoint, which will retain its memory of previous ones.
See [this guide](../how-tos/persistence.ipynb) for how to add a checkpointer to your graph.
## Threads
Threads enable the checkpointing of multiple different runs, making them essential for multi-tenant chat applications and other scenarios where maintaining separate states is necessary. A thread is a unique ID assigned to a series of checkpoints saved by a checkpointer. When using a checkpointer, you must specify a `thread_id` or `thread_ts` when running the graph.
`thread_id` is simply the ID of a thread. This is always required
`thread_ts` can optionally be passed. This identifier refers to a specific checkpoint within a thread. This can be used to kick of a run of a graph from some point halfway through a thread.
You must pass these when invoking the graph as part of the configurable part of the config.
```python
config = {"configurable": {"thread_id": "a"}}
graph.invoke(inputs, config=config)
```
See [this guide](../how-tos/persistence.ipynb) for how to use threads.
## Checkpointer state
When interacting with the checkpointer state, you must specify a [thread identifier](#threads).Each checkpoint saved by the checkpointer has two properties:
- **values**: This is the value of the state at this point in time.
- **next**: This is a tuple of the nodes to execute next in the graph.
### Get state
You can get the state of a checkpointer by calling `graph.get_state(config)`. The config should contain `thread_id`, and the state will be fetched for that thread.
### Get state history
You can also call `graph.get_state_history(config)` to get a list of the history of the graph. The config should contain `thread_id`, and the state history will be fetched for that thread.
### Update state
You can also interact with the state directly and update it. This takes three different components:
- config
- values
- `as_node`
**config**
The config should contain `thread_id` specifying which thread to update.
**values**
These are the values that will be used to update the state. Note that this update is treated exactly as any update from a node is treated. This means that these values will be passed to the [reducer](#reducers) functions that are part of the state. So this does NOT automatically overwrite the state. Let's walk through an example.
Let's assume you have defined the state of your graph as:
```python
from typing import TypedDict, Annotated
from operator import add
class State(TypedDict):
foo: int
bar: Annotated[list[str], add]
```
Let's now assume the current state of the graph is
```
{"foo": 1, "bar": ["a"]}
```
If you update the state as below:
```
graph.update_state(config, {"foo": 2, "bar": ["b"]})
```
Then the new state of the graph will be:
```
{"foo": 2, "bar": ["a", "b"]}
```
The `foo` key is completely changed (because there is no reducer specified for that key, so it overwrites it). However, there is a reducer specified for the `bar` key, and so it appends `"b"` to the state of `bar`.
**`as_node`**
The final thing you specify when calling `update_state` is `as_node`. This update will be applied as if it came from node `as_node`. If `as_node` is not provided, it will be set to the last node that updated the state, if not ambiguous.
The reason this matters is that the next steps in the graph to execute depend on the last node to have given an update, so this can be used to control which node executes next.
## Graph Migrations
LangGraph can easily handle migrations of graph definitions (nodes, edges, and state) even when using a checkpointer to track state.
- For threads at the end of the graph (i.e. not interrupted) you can change the entire topology of the graph (i.e. all nodes and edges, remove, add, rename, etc)
- For threads currently interrupted, we support all topology changes other than renaming / removing nodes (as that thread could now be about to enter a node that no longer exists) -- if this is a blocker please reach out and we can prioritize a solution.
- For modifying state, we have full backwards and forwards compatibility for adding and removing keys
- State keys that are renamed lose their saved state in existing threads
- State keys whose types change in incompatible ways could currently cause issues in threads with state from before the change -- if this is a blocker please reach out and we can prioritize a solution.
## Configuration
When creating a graph, you can also mark that certain parts of the graph are configurable. This is commonly done to enable easily switching between models or system prompts. This allows you to create a single "cognitive architecture" (the graph) but have multiple different instance of it.
You can optionally specify a `config_schema` when creating a graph.
```python
class ConfigSchema(TypedDict):
llm: str
graph = StateGraph(State, config_schema=ConfigSchema)
```
You can then pass this configuration into the graph using the `configurable` config field.
```python
config = {"configurable": {"llm": "anthropic"}}
graph.invoke(inputs, config=config)
```
You can then access and use this configuration inside a node:
```python
def node_a(state, config):
llm_type = config.get("configurable", {}).get("llm", "openai")
llm = get_llm(llm_type)
...
```
See [this guide](../how-tos/configuration.ipynb) for a full breakdown on configuration.
### Recursion Limit
The recursion limit sets the maximum number of [super-steps](#graphs) the graph can execute during a single execution. Once the limit is reached, LangGraph will raise `GraphRecursionError`. By default this value is set to 25 steps. The recursion limit can be set on any graph at runtime, and is passed to `.invoke`/`.stream` via the config dictionary. Importantly, `recursion_limit` is a standalone `config` key and should not be passed inside the `configurable` key as all other user-defined configuration. See the example below:
```python
graph.invoke(inputs, config={"recursion_limit": 5, "configurable":{"llm": "anthropic"}})
```
Read [this how-to](https://langchain-ai.github.io/langgraph/how-tos/recursion-limit/) to learn more about how the recursion limit works.
## Breakpoints
It can often be useful to set breakpoints before or after certain nodes execute. This can be used to wait for human approval before continuing. These can be set when you ["compile" a graph](#compiling-your-graph). You can set breakpoints either _before_ a node executes (using `interrupt_before`) or after a node executes (using `interrupt_after`.)
You **MUST** use a [checkpoiner](#checkpointer) when using breakpoints. This is because your graph needs to be able to resume execution.
In order to resume execution, you can just invoke your graph with `None` as the input.
```python
# Initial run of graph
graph.invoke(inputs, config=config)
# Let's assume it hit a breakpoint somewhere, you can then resume by passing in None
graph.invoke(None, config=config)
```
See [this guide](../how-tos/human_in_the_loop/breakpoints.ipynb) for a full walkthrough of how to add breakpoints.
## Visualization
It's often nice to be able to visualize graphs, especially as they get more complex. LangGraph comes with several built-in ways to visualize graphs. See [this how-to guide](../how-tos/visualization.ipynb) for more info.
## Streaming
LangGraph is built with first class support for streaming. There are several different ways to stream back results
### `.stream` and `.astream`
`.stream` and `.astream` are sync and async methods for streaming back results.
There are several different modes you can specify when calling these methods (e.g. `graph.stream(..., mode="...")):
- [`"values"`](../how-tos/stream-values.ipynb): This streams the full value of the state after each step of the graph.
- [`"updates"`](../how-tos/stream-updates.ipynb): This streams the updates to the state after each step of the graph. If multiple updates are made in the same step (e.g. multiple nodes are run) then those updates are streamed separately.
- `"debug"`: This streams as much information as possible throughout the execution of the graph.
The below visualization shows the difference between the `values` and `updates` modes:
![values vs updates](../static/values_vs_updates.png)
### `.astream_events` (for streaming tokens of LLM calls)
In addition, you can use the [`astream_events`](../how-tos/streaming-events-from-within-tools.ipynb) method to stream back events that happen _inside_ nodes. This is useful for [streaming tokens of LLM calls](../how-tos/streaming-tokens.ipynb).
This is a standard method on all [LangChain objects](https://python.langchain.com/v0.2/docs/concepts/#runnable-interface). This means that as the graph is executed, certain events are emitted along the way and can be seen if you run the graph using `.astream_events`.
All events have (among other things) `event`, `name`, and `data` fields. What do these mean?
- `event`: This is the type of event that is being emitted. You can find a detailed table of all callback events and triggers [here](https://python.langchain.com/v0.2/docs/concepts/#callback-events).
- `name`: This is the name of event.
- `data`: This is the data associated with the event.
What types of things cause events to be emitted?
* each node (runnable) emits `on_chain_start` when it starts execution, `on_chain_stream` during the node execution and `on_chain_end` when the node finishes. Node events will have the node name in the event's `name` field
* the graph will emit `on_chain_start` in the beginning of the graph execution, `on_chain_stream` after each node execution and `on_chain_end` when the graph finishes. Graph events will have the `LangGraph` in the event's `name` field
* Any writes to state channels (i.e. anytime you update the value of one of your state keys) will emit `on_chain_start` and `on_chain_end` events
Additionally, any events that are created inside your nodes (LLM events, tool events, manually emitted events, etc.) will also be visible in the output of `.astream_events`.
To make this more concrete and to see what this looks like, let's see what events are returned when we run a simple graph:
```python
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START, END
model = ChatOpenAI(model="gpt-3.5-turbo")
def call_model(state: MessagesState):
response = model.invoke(state['messages'])
return {"messages": response}
workflow = StateGraph(MessagesState)
workflow.add_node(call_model)
workflow.add_edge(START, "call_model")
workflow.add_edge("call_model", END)
app = workflow.compile()
inputs = [{"role": "user", "content": "hi!"}]
async for event in app.astream_events({"messages": inputs}, version="v2"):
kind = event["event"]
print(f"{kind}: {event['name']}")
```
```shell
on_chain_start: LangGraph
on_chain_start: __start__
on_chain_end: __start__
on_chain_start: call_model
on_chat_model_start: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_stream: ChatOpenAI
on_chat_model_end: ChatOpenAI
on_chain_start: ChannelWrite<call_model,messages>
on_chain_end: ChannelWrite<call_model,messages>
on_chain_stream: call_model
on_chain_end: call_model
on_chain_stream: LangGraph
on_chain_end: LangGraph
```
We start with the overall graph start (`on_chain_start: LangGraph`). We then write to the `__start__` node (this is special node to handle input).
We then start the `call_model` node (`on_chain_start: call_model`). We then start the chat model invocation (`on_chat_model_start: ChatOpenAI`),
stream back token by token (`on_chat_model_stream: ChatOpenAI`) and then finish the chat model (`on_chat_model_end: ChatOpenAI`). From there,
we write the results back to the channel (`ChannelWrite<call_model,messages>`) and then finish the `call_model` node and then the graph as a whole.
This should hopefully give you a good sense of what events are emitted in a simple graph. But what data do these events contain?
Each type of event contains data in a different format. Let's look at what `on_chat_model_stream` events look like. This is an important type of event
since it is needed for streaming tokens from an LLM response.
These events look like:
```shell
{'event': 'on_chat_model_stream',
'name': 'ChatOpenAI',
'run_id': '3fdbf494-acce-402e-9b50-4eab46403859',
'tags': ['seq:step:1'],
'metadata': {'langgraph_step': 1,
'langgraph_node': 'call_model',
'langgraph_triggers': ['start:call_model'],
'langgraph_task_idx': 0,
'checkpoint_id': '1ef657a0-0f9d-61b8-bffe-0c39e4f9ad6c',
'checkpoint_ns': 'call_model',
'ls_provider': 'openai',
'ls_model_name': 'gpt-3.5-turbo',
'ls_model_type': 'chat',
'ls_temperature': 0.7},
'data': {'chunk': AIMessageChunk(content='Hello', id='run-3fdbf494-acce-402e-9b50-4eab46403859')},
'parent_ids': []}
```
We can see that we have the event type and name (which we knew from before).
We also have a bunch of stuff in metadata. Noticeably, `'langgraph_node': 'call_model',` is some really helpful information
which tells us which node this model was invoked inside of.
Finally, `data` is a really important field. This contains the actual data for this event! Which in this case
is an AIMessageChunk. This contains the `content` for the message, as well as an `id`.
This is the ID of the overall AIMessage (not just this chunk) and is super helpful - it helps
us track which chunks are part of the same message (so we can show them together in the UI).
This information contains all that is needed for creating a UI for streaming LLM tokens. You can see a
guide for that [here](../how-tos/streaming-tokens.ipynb).
!!! warning "ASYNC IN PYTHON<=3.10"
You may fail to see events being emitted from inside a node when using `.astream_events` in Python <= 3.10. If you're using a Langchain RunnableLambda, a RunnableGenerator, or Tool asynchronously inside your node, you will have to propagate callbacks to these objects manually. This is because LangChain cannot automatically propagate callbacks to child objects in this case. Please see examples [here](../how-tos/streaming-content.ipynb) and [here](../how-tos/streaming-events-from-within-tools.ipynb).
#### Only stream tokens from specific nodes/LLMs
There are certain cases where you have multiple nodes in your graph that make LLM calls, and you do not wish to stream the tokens from every single LLM call. For example, you may use one LLM as a planner for the next steps to take, and another LLM somewhere else in the graph that actually responds to the user. In that case, you most likely WON'T want to stream tokens from the planner LLM but WILL want to stream them from the respond to user LLM. Below we show two different ways of doing this, one by streaming from specific nodes only and the second by streaming from specific LLMs only.
First, let's define our graph:
```python
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START, END
model_1 = ChatOpenAI(model="gpt-3.5-turbo", name="model_1")
model_2 = ChatOpenAI(model="gpt-3.5-turbo", name="model_2")
def call_first_model(state: MessagesState):
response = model_1.invoke(state['messages'])
return {"messages": response}
def call_second_model(state: MessagesState):
response = model_2.invoke(state['messages'])
return {"messages": response}
workflow = StateGraph(MessagesState)
workflow.add_node(call_first_model)
workflow.add_node(call_second_model)
workflow.add_edge(START, "call_first_model")
workflow.add_edge("call_first_model", "call_second_model")
workflow.add_edge("call_second_model", END)
app = workflow.compile()
```
**Streaming from specific node**
In the case that we only want the output from a single node, we can use the event metadata to filter node names:
```python
inputs = [{"role": "user", "content": "hi!"}]
async for event in app.astream_events({"messages": inputs}, version="v2"):
# Get chat model tokens from a particular node
if event["event"] == "on_chat_model_stream" and event['metadata'].get('langgraph_node','') == "call_second_model":
print(event["data"]["chunk"].content, end="|", flush=True)
```
```shell
|Hello|!| How| can| I| help| you| today|?||
```
As we can see only the response from the second LLM was streamed (you can tell because we only received a single response, if we had streamed both we would have received two "Hello! How can I help you today?" messages).
**Streaming from specific LLM**
Sometimes you might want to stream from specific LLMs instead of specific nodes. This could be the case if you have multiple LLM calls inside a single node, and only want to stream the output of a specific one or if you use the same LLM in different nodes and want to stream it's output anytime it is called. We can do this by using the `name` parameter for LLMs and events:
```python
inputs = [{"role": "user", "content": "hi!"}]
async for event in app.astream_events({"messages": inputs}, version="v2"):
# Get chat model tokens from a particular LLM inside a particular node
if event["event"] == "on_chat_model_stream" and event['name'] == "model_2":
print(event["data"]["chunk"].content, end="|", flush=True)
```
```shell
|Hello|!| How| can| I| assist| you| today|?||
```
As expected, we only see a single LLM response since the response from `model_1` was not streamed.
+5
View File
@@ -0,0 +1,5 @@
tags:
- how-tos
- how-to
- howto
- how to
+92
View File
@@ -0,0 +1,92 @@
---
hide:
- toc
---
# How-to guides
Welcome to the LangGraph how-to guides! These guides provide practical, step-by-step instructions for accomplishing key tasks in LangGraph.
## Controllability
LangGraph is known for being a highly controllable agent framework.
These how-to guides show how to achieve that controllability.
- [How to create subgraphs](subgraph.ipynb)
- [How to create branches for parallel execution](branching.ipynb)
- [How to create map-reduce branches for parallel execution](map-reduce.ipynb)
- [How to control graph recursion limit](recursion-limit.ipynb)
## Persistence
LangGraph makes it easy to persist state across graph runs. The guide below shows how to add persistence to your graph.
- [How to add persistence ("memory") to your graph](persistence.ipynb)
- [How to manage conversation history](memory/manage-conversation-history.ipynb)
- [How to delete messages](memory/delete-messages.ipynb)
- [How to add summary conversation memory](memory/add-summary-conversation-history.ipynb)
- [How to use Postgres checkpointer for persistence](persistence_postgres.ipynb)
- [How to create a custom checkpointer using MongoDB](persistence_mongodb.ipynb)
- [How to create a custom checkpointer using Redis](persistence_redis.ipynb)
## Human in the Loop
One of LangGraph's main benefits is that it makes human-in-the-loop workflows easy.
These guides cover common examples of that.
- [How to add breakpoints](human_in_the_loop/breakpoints.ipynb)
- [How to add dynamic breakpoints](human_in_the_loop/dynamic_breakpoints.ipynb)
- [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb)
- [How to wait for user input](human_in_the_loop/wait-user-input.ipynb)
- [How to view and update past graph state](human_in_the_loop/time-travel.ipynb)
- [Review tool calls](human_in_the_loop/review-tool-calls.ipynb)
## Streaming
LangGraph is built to be streaming first.
These guides show how to use different streaming modes.
- [How to stream full state of your graph](stream-values.ipynb)
- [How to stream state updates of your graph](stream-updates.ipynb)
- [How to stream LLM tokens](streaming-tokens.ipynb)
- [How to stream LLM tokens without LangChain models](streaming-tokens-without-langchain.ipynb)
- [How to stream arbitrarily nested content](streaming-content.ipynb)
- [How to configure multiple streaming modes at the same time](stream-multiple.ipynb)
- [How to stream events from within a tool](streaming-events-from-within-tools.ipynb)
- [How to stream events from within a tool without LangChain models](streaming-events-from-within-tools-without-langchain.ipynb)
- [How to stream events from the final node](streaming-from-final-node.ipynb)
## Tool calling
- [How to call tools using ToolNode](tool-calling.ipynb)
- [How to handle tool calling errors](tool-calling-errors.ipynb)
- [How to pass graph state to tools](pass-run-time-values-to-tools.ipynb)
- [How to pass config to tools](pass-config-to-tools.ipynb)
- [How to handle large numbers of tools](many-tools.ipynb)
## State Management
- [Use Pydantic model as state](state-model.ipynb)
- [Use a context object in state](state-context-key.ipynb)
- [Have a separate input and output schema](input_output_schema.ipynb)
- [Pass private state between nodes inside the graph](pass_private_state.ipynb)
## Other
- [How to run graph asynchronously](async.ipynb)
- [How to visualize your graph](visualization.ipynb)
- [How to add runtime configuration to your graph](configuration.ipynb)
- [How to use a Pydantic model as your state](state-model.ipynb)
- [How to use a context object in state](state-context-key.ipynb)
- [How to add node retries](node-retries.ipynb)
- [How to force function calling agent to structure output](react-agent-structured-output.ipynb)
## Prebuilt ReAct Agent
These guides show how to use the prebuilt ReAct agent.
Please note that here will we use a **prebuilt agent**. One of the big benefits of LangGraph is that you can easily create your own agent architectures. So while it's fine to start here to build an agent quickly, we would strongly recommend learning how to build your own agent so that you can take full advantage of LangGraph.
- [How to create a ReAct agent](create-react-agent.ipynb)
- [How to add memory to a ReAct agent](create-react-agent-memory.ipynb)
- [How to add a custom system prompt to a ReAct agent](create-react-agent-system-prompt.ipynb)
- [How to add human-in-the-loop processes to a ReAct agent](create-react-agent-hitl.ipynb)
+7
View File
@@ -0,0 +1,7 @@
---
hide_comments: true
hide:
- navigation
---
{!README.md!}
+4
View File
@@ -0,0 +1,4 @@
tags:
- reference
- api
- api-reference
+54
View File
@@ -0,0 +1,54 @@
# Checkpoints
You can [compile][langgraph.graph.MessageGraph.compile] any LangGraph workflow with a [CheckPointer][basecheckpointsaver] to give your agent "memory" by persisting its state. This permits things like:
- Remembering things across multiple interactions
- Interrupting to wait for user input
- Resilience for long-running, error-prone agents
- Time travel retry and branch from a previous checkpoint
Key checkpointer interfaces and primitives are defined in [`langgraph_checkpoint`](https://github.com/langchain-ai/langgraph/tree/main/libs/checkpoint) library.
### Checkpoint
::: langgraph.checkpoint.base.Checkpoint
### CheckpointMetadata
::: langgraph.checkpoint.base.CheckpointMetadata
### BaseCheckpointSaver
::: langgraph.checkpoint.base.BaseCheckpointSaver
### SerializerProtocol
::: langgraph.checkpoint.base.SerializerProtocol
## Implementations
LangGraph also natively provides the following checkpoint implementations.
### MemorySaver
::: langgraph.checkpoint.memory.MemorySaver
### AsyncSqliteSaver
::: langgraph.checkpoint.sqlite.aio.AsyncSqliteSaver
### SqliteSaver
::: langgraph.checkpoint.sqlite.SqliteSaver
### AsyncPostgresSaver
::: langgraph.checkpoint.postgres.aio.AsyncPostgresSaver
### PostgresSaver
::: langgraph.checkpoint.postgres.PostgresSaver
handler: python
handler: python
+6
View File
@@ -0,0 +1,6 @@
# Errors
While you may not want to see them, informative errors help you design better workflows.
Below are the LangGraph-specific errors and what they mean.
::: langgraph.errors
+72
View File
@@ -0,0 +1,72 @@
# Graph Definitions
Graphs are the core abstraction of LangGraph. Each [StateGraph](#stategraph) implementation is used to create graph workflows. Once compiled, you can run the [CompiledGraph](#compiledgraph) to run the application.
## StateGraph
```python
from langgraph.graph import StateGraph
from typing_extensions import TypedDict
class MyState(TypedDict)
...
graph = StateGraph(MyState)
```
::: langgraph.graph.StateGraph
handler: python
## MessageGraph
::: langgraph.graph.message.MessageGraph
## CompiledGraph
::: langgraph.graph.graph.CompiledGraph
## StreamMode
::: langgraph.pregel.StreamMode
## Constants
The following constants and classes are used to help control graph execution.
## START
START is a string constant (`"__start__"`) that serves as a "virtual" node in the graph.
Adding an edge (or conditional edges) from `START` to node one or more nodes in your graph
will direct the graph to begin execution there.
```python
from langgraph.graph import START
...
builder.add_edge(START, "my_node")
# Or to add a conditional starting point
builder.add_conditional_edges(START, my_condition)
```
## END
END is a string constant (`"__end__"`) that serves as a "virtual" node in the graph. Adding
an edge (or conditional edges) from one or more nodes in your graph to the `END` "node" will
direct the graph to cease execution as soon as it reaches this point.
```python
from langgraph.graph import END
...
builder.add_edge("my_node", END) # Stop any time my_node completes
# Or to conditionally terminate
def my_condition(state):
if state["should_stop"]:
return END
return "my_node"
builder.add_conditional_edges("my_node", my_condition)
```
## Send
::: langgraph.constants.Send
## RetryPolicy
::: langgraph.pregel.types.RetryPolicy
+67
View File
@@ -0,0 +1,67 @@
# Prebuilt
## create_react_agent
```python
from langgraph.prebuilt import create_react_agent
```
::: langgraph.prebuilt.create_react_agent
## ToolNode
```python
from langgraph.prebuilt import ToolNode
```
::: langgraph.prebuilt.ToolNode
handler: python
## ToolExecutor
```python
from langgraph.prebuilt import ToolExecutor
```
::: langgraph.prebuilt.ToolExecutor
handler: python
## ToolInvocation
```python
from langgraph.prebuilt import ToolInvocation
```
::: langgraph.prebuilt.ToolInvocation
handler: python
heading_level: 4
## `tools_condition`
```python
from langgraph.prebuilt import tools_condition
```
::: langgraph.prebuilt.tools_condition
## ValidationNode
```python
from langgraph.prebuilt import ValidationNode
```
::: langgraph.prebuilt.ValidationNode
## InjectedState
```python
from langgraph.prebuilt import InjectedState
```
::: langgraph.prebuilt.InjectedState
handler: python

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