When searching for subgraphs do not attempt to search function non
locals for RunnableCallables as this captures unwanted reference to
surrounding variables.
- Previously the global resume value was passed to subgraphs without
being consumed
- This would result in two parallel subgraph calls being able to use the
same resume value
- Note this behavior can't be implemented over the wire, that will be
fixed in future PR
Closes#3398
- Was O(n^2) due to individual channels created for every conditional edge, including the default cond edge created for Command
- Now using a single channel per node for all conditional edge / command triggers, reducing to linear complexity
- Improves run time on sequential(200) from 1.8s to 0.14s
- Previously the global resume value was passed to subgraphs without being consumed
- This would result in two parallel subgraph calls being able to use the same resume value
- Note this behavior can't be implemented over the wire, that will be fixed in future PR
- Need to use a single operation to check if present and remove item
from list
- This doesn't fix the separate issue that parallel tasks claiming a
single interrupt value have somewhat undefined behavior (in the sense
that they will race to be the first to take it). That will be fixed in a
future PR
Closes#3875
- Need to use a single operation to check if present and remove item from list
- This doesn't fix the separate issue that parallel tasks claiming a single interrupt value have somewhat undefined behavior (in the sense that they will race to be the first to take it). That will be fixed in a future PR
- no dependency on any particular encryption lib (there is no py stdlib
encryption lib)
- works with any modern checkpointer, ie. those which use dumps_typed
and loads_typed methods to serialize data
- uses the default msg pack serializer, but also works with any custom
serializer
- backwards compatible with unencrypted data in same storage (will just
be read unencrypted)
- providing easy constructor to use AES encryption through pycriptodome
library, one single line of code to add it in
- other encryption libraries or algorithms (even assymetric ones) can be
used by implementing the two-method CipherProtocol interface
- cipher name (eg. aes) is stored with encrypted payload for forwards
compatibility
```py
import sqlite3
from langgraph.checkpoint.serde.encrypted import EncryptedSerializer
from langgraph.checkpoint.sqlite import SqliteSaver
# will read AES key from env var LANGGRAPH_AES_KEY
serde = EncryptedSerializer.from_pycryptodome_aes()
# works with any other checkpointer, including custom ones
checkpointer = SqliteSaver(sqlite3.connect('...'), serde=serde)
```