mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-27 01:52:25 +02:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b79f779cb1 |
@@ -32,7 +32,7 @@ jobs:
|
||||
run:
|
||||
working-directory: libs/cli
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: Ana06/get-changed-files@v2.3.0
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
- "3.12"
|
||||
name: "lint #${{ matrix.python-version }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: Ana06/get-changed-files@v2.3.0
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
name: "test #${{ matrix.python-version }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
working-directory: libs/langgraph
|
||||
name: "test #${{ matrix.python-version }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
version: ${{ steps.check-version.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python $${ env.PYTHON_VERSION }}
|
||||
uses: astral-sh/setup-uv@v7
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- uses: actions/download-artifact@v6
|
||||
with:
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
run:
|
||||
working-directory: libs/langgraph
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- run: SHA=$(git rev-parse HEAD) && echo "SHA=$SHA" >> $GITHUB_ENV
|
||||
- name: Set up Python 3.11
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
run:
|
||||
working-directory: libs/langgraph
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- id: files
|
||||
name: Get changed files
|
||||
uses: Ana06/get-changed-files@v2.3.0
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
python: ${{ steps.filter.outputs.python }}
|
||||
deps: ${{ steps.filter.outputs.deps }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
with:
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
name: "Check SDK methods matching"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
python-version:
|
||||
- "3.11"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.MKDOCS_GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
tag: ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python
|
||||
uses: astral-sh/setup-uv@v7
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
outputs:
|
||||
release-body: ${{ steps.generate-release-body.outputs.release-body }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: langchain-ai/langgraph
|
||||
path: langgraph
|
||||
@@ -157,7 +157,7 @@ jobs:
|
||||
- test-pypi-publish
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
# We explicitly *don't* set up caching here. This ensures our tests are
|
||||
# maximally sensitive to catching breakage.
|
||||
@@ -260,7 +260,7 @@ jobs:
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python
|
||||
uses: astral-sh/setup-uv@v7
|
||||
@@ -301,7 +301,7 @@ jobs:
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Python
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- "latest"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python + Poetry
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
@@ -4698,11 +4698,6 @@
|
||||
"title": "Graph Id",
|
||||
"description": "The ID of the graph to filter by. The graph ID is normally set in your langgraph.json configuration."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name",
|
||||
"description": "Name of the assistant to filter by. The filtering logic will match (case insensitive) assistants where 'name' is a substring of the assistant name."
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"title": "Limit",
|
||||
|
||||
@@ -60,28 +60,23 @@ class Checkpoint(TypedDict):
|
||||
"""State snapshot at a given point in time."""
|
||||
|
||||
v: int
|
||||
"""The version of the checkpoint format. Currently `1`."""
|
||||
"""The version of the checkpoint format. Currently 1."""
|
||||
id: str
|
||||
"""The ID of the checkpoint.
|
||||
|
||||
This is both unique and monotonically increasing, so can be used for sorting
|
||||
checkpoints from first to last."""
|
||||
"""The ID of the checkpoint. This is both unique and monotonically
|
||||
increasing, so can be used for sorting checkpoints from first to last."""
|
||||
ts: str
|
||||
"""The timestamp of the checkpoint in ISO 8601 format."""
|
||||
channel_values: dict[str, Any]
|
||||
"""The values of the channels at the time of the checkpoint.
|
||||
|
||||
Mapping from channel name to deserialized channel snapshot value.
|
||||
"""
|
||||
channel_versions: ChannelVersions
|
||||
"""The versions of the channels at the time of the checkpoint.
|
||||
|
||||
The keys are channel names and the values are monotonically increasing
|
||||
version strings for each channel.
|
||||
"""
|
||||
versions_seen: dict[str, ChannelVersions]
|
||||
"""Map from node ID to map from channel name to version seen.
|
||||
|
||||
This keeps track of the versions of the channels that each node has seen.
|
||||
Used to determine which nodes to execute next.
|
||||
"""
|
||||
@@ -357,9 +352,8 @@ class BaseCheckpointSaver(Generic[V]):
|
||||
def get_next_version(self, current: V | None, channel: None) -> V:
|
||||
"""Generate the next version ID for a channel.
|
||||
|
||||
Default is to use integer versions, incrementing by `1`.
|
||||
|
||||
If you override, you can use `str`/`int`/`float` versions, as long as they are monotonically increasing.
|
||||
Default is to use integer versions, incrementing by `1`. If you override, you can use `str`/`int`/`float`
|
||||
versions, as long as they are monotonically increasing.
|
||||
|
||||
Args:
|
||||
current: The current version identifier (`int`, `float`, or `str`).
|
||||
|
||||
@@ -33,7 +33,7 @@ class InMemorySaver(
|
||||
):
|
||||
"""An in-memory checkpoint saver.
|
||||
|
||||
This checkpoint saver stores checkpoints in memory using a `defaultdict`.
|
||||
This checkpoint saver stores checkpoints in memory using a defaultdict.
|
||||
|
||||
Note:
|
||||
Only use `InMemorySaver` for debugging or testing purposes.
|
||||
@@ -44,23 +44,22 @@ class InMemorySaver(
|
||||
Args:
|
||||
serde: The serializer to use for serializing and deserializing checkpoints.
|
||||
|
||||
Example:
|
||||
```python
|
||||
import asyncio
|
||||
Examples:
|
||||
|
||||
from langgraph.checkpoint.memory import InMemorySaver
|
||||
from langgraph.graph import StateGraph
|
||||
import asyncio
|
||||
|
||||
builder = StateGraph(int)
|
||||
builder.add_node("add_one", lambda x: x + 1)
|
||||
builder.set_entry_point("add_one")
|
||||
builder.set_finish_point("add_one")
|
||||
from langgraph.checkpoint.memory import InMemorySaver
|
||||
from langgraph.graph import StateGraph
|
||||
|
||||
memory = InMemorySaver()
|
||||
graph = builder.compile(checkpointer=memory)
|
||||
coro = graph.ainvoke(1, {"configurable": {"thread_id": "thread-1"}})
|
||||
asyncio.run(coro) # Output: 2
|
||||
```
|
||||
builder = StateGraph(int)
|
||||
builder.add_node("add_one", lambda x: x + 1)
|
||||
builder.set_entry_point("add_one")
|
||||
builder.set_finish_point("add_one")
|
||||
|
||||
memory = InMemorySaver()
|
||||
graph = builder.compile(checkpointer=memory)
|
||||
coro = graph.ainvoke(1, {"configurable": {"thread_id": "thread-1"}})
|
||||
asyncio.run(coro) # Output: 2
|
||||
"""
|
||||
|
||||
# thread ID -> checkpoint NS -> checkpoint ID -> checkpoint mapping
|
||||
|
||||
@@ -52,13 +52,12 @@ def maybe_add_typed_methods(
|
||||
|
||||
class CipherProtocol(Protocol):
|
||||
"""Protocol for encryption and decryption of data.
|
||||
|
||||
- `encrypt`: Encrypt plaintext.
|
||||
- `decrypt`: Decrypt ciphertext.
|
||||
"""
|
||||
|
||||
def encrypt(self, plaintext: bytes) -> tuple[str, bytes]:
|
||||
"""Encrypt plaintext. Returns a tuple `(cipher name, ciphertext)`."""
|
||||
"""Encrypt plaintext. Returns a tuple (cipher name, ciphertext)."""
|
||||
...
|
||||
|
||||
def decrypt(self, ciphername: str, ciphertext: bytes) -> bytes:
|
||||
|
||||
@@ -41,12 +41,10 @@ logger = logging.getLogger(__name__)
|
||||
class JsonPlusSerializer(SerializerProtocol):
|
||||
"""Serializer that uses ormsgpack, with optional fallbacks.
|
||||
|
||||
!!! warning
|
||||
|
||||
Security note: This serializer is intended for use within the `BaseCheckpointSaver`
|
||||
class and called within the Pregel loop. It should not be used on untrusted
|
||||
python objects. If an attacker can write directly to your checkpoint database,
|
||||
they may be able to trigger code execution when data is deserialized.
|
||||
Security note: this serializer is intended for use within the BaseCheckpointSaver
|
||||
class and called within the Pregel loop. It should not be used on untrusted
|
||||
python objects. If an attacker can write directly to your checkpoint database,
|
||||
they may be able to trigger code execution when data is deserialized.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
|
||||
@@ -39,19 +39,14 @@ class BaseChannel(Generic[Value, Update, Checkpoint], ABC):
|
||||
|
||||
def copy(self) -> Self:
|
||||
"""Return a copy of the channel.
|
||||
|
||||
By default, delegates to `checkpoint()` and `from_checkpoint()`.
|
||||
|
||||
Subclasses can override this method with a more efficient implementation.
|
||||
"""
|
||||
Subclasses can override this method with a more efficient implementation."""
|
||||
return self.from_checkpoint(self.checkpoint())
|
||||
|
||||
def checkpoint(self) -> Checkpoint | Any:
|
||||
"""Return a serializable representation of the channel's current state.
|
||||
|
||||
Raises `EmptyChannelError` if the channel is empty (never updated yet),
|
||||
or doesn't support checkpoints.
|
||||
"""
|
||||
or doesn't support checkpoints."""
|
||||
try:
|
||||
return self.get()
|
||||
except EmptyChannelError:
|
||||
@@ -60,9 +55,7 @@ class BaseChannel(Generic[Value, Update, Checkpoint], ABC):
|
||||
@abstractmethod
|
||||
def from_checkpoint(self, checkpoint: Checkpoint | Any) -> Self:
|
||||
"""Return a new identical channel, optionally initialized from a checkpoint.
|
||||
|
||||
If the checkpoint contains complex data structures, they should be copied.
|
||||
"""
|
||||
If the checkpoint contains complex data structures, they should be copied."""
|
||||
|
||||
# read methods
|
||||
|
||||
@@ -74,7 +67,6 @@ class BaseChannel(Generic[Value, Update, Checkpoint], ABC):
|
||||
|
||||
def is_available(self) -> bool:
|
||||
"""Return `True` if the channel is available (not empty), `False` otherwise.
|
||||
|
||||
Subclasses should override this method to provide a more efficient
|
||||
implementation than calling `get()` and catching `EmptyChannelError`.
|
||||
"""
|
||||
@@ -91,29 +83,21 @@ class BaseChannel(Generic[Value, Update, Checkpoint], ABC):
|
||||
"""Update the channel's value with the given sequence of updates.
|
||||
The order of the updates in the sequence is arbitrary.
|
||||
This method is called by Pregel for all channels at the end of each step.
|
||||
|
||||
If there are no updates, it is called with an empty sequence.
|
||||
|
||||
Raises `InvalidUpdateError` if the sequence of updates is invalid.
|
||||
|
||||
Returns `True` if the channel was updated, `False` otherwise."""
|
||||
|
||||
def consume(self) -> bool:
|
||||
"""Notify the channel that a subscribed task ran.
|
||||
|
||||
By default, no-op.
|
||||
|
||||
A channel can use this method to modify its state, preventing the value from being consumed again.
|
||||
"""Notify the channel that a subscribed task ran. By default, no-op.
|
||||
A channel can use this method to modify its state, preventing the value
|
||||
from being consumed again.
|
||||
|
||||
Returns `True` if the channel was updated, `False` otherwise.
|
||||
"""
|
||||
return False
|
||||
|
||||
def finish(self) -> bool:
|
||||
"""Notify the channel that the Pregel run is finishing.
|
||||
|
||||
By default, no-op.
|
||||
|
||||
"""Notify the channel that the Pregel run is finishing. By default, no-op.
|
||||
A channel can use this method to modify its state, preventing finish.
|
||||
|
||||
Returns `True` if the channel was updated, `False` otherwise.
|
||||
|
||||
@@ -32,8 +32,8 @@ def get_config() -> RunnableConfig:
|
||||
def get_store() -> BaseStore:
|
||||
"""Access LangGraph store from inside a graph node or entrypoint task at runtime.
|
||||
|
||||
Can be called from inside any [`StateGraph`][langgraph.graph.StateGraph] node or
|
||||
functional API [`task`][langgraph.func.task], as long as the `StateGraph` or the [`entrypoint`][langgraph.func.entrypoint]
|
||||
Can be called from inside any [StateGraph][langgraph.graph.StateGraph] node or
|
||||
functional API [task][langgraph.func.task], as long as the StateGraph or the [entrypoint][langgraph.func.entrypoint]
|
||||
was initialized with a store, e.g.:
|
||||
|
||||
```python
|
||||
@@ -53,10 +53,10 @@ def get_store() -> BaseStore:
|
||||
!!! warning "Async with Python < 3.11"
|
||||
|
||||
If you are using Python < 3.11 and are running LangGraph asynchronously,
|
||||
`get_store()` won't work since it uses [`contextvar`](https://docs.python.org/3/library/contextvars.html) propagation (only available in [Python >= 3.11](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)).
|
||||
`get_store()` won't work since it uses [contextvar](https://docs.python.org/3/library/contextvars.html) propagation (only available in [Python >= 3.11](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)).
|
||||
|
||||
|
||||
Example: Using with `StateGraph`
|
||||
Example: Using with StateGraph
|
||||
```python
|
||||
from typing_extensions import TypedDict
|
||||
from langgraph.graph import StateGraph, START
|
||||
@@ -124,17 +124,17 @@ def get_store() -> BaseStore:
|
||||
|
||||
|
||||
def get_stream_writer() -> StreamWriter:
|
||||
"""Access LangGraph [`StreamWriter`][langgraph.types.StreamWriter] from inside a graph node or entrypoint task at runtime.
|
||||
"""Access LangGraph [StreamWriter][langgraph.types.StreamWriter] from inside a graph node or entrypoint task at runtime.
|
||||
|
||||
Can be called from inside any [`StateGraph`][langgraph.graph.StateGraph] node or
|
||||
functional API [`task`][langgraph.func.task].
|
||||
Can be called from inside any [StateGraph][langgraph.graph.StateGraph] node or
|
||||
functional API [task][langgraph.func.task].
|
||||
|
||||
!!! warning "Async with Python < 3.11"
|
||||
|
||||
If you are using Python < 3.11 and are running LangGraph asynchronously,
|
||||
`get_stream_writer()` won't work since it uses [`contextvar`](https://docs.python.org/3/library/contextvars.html) propagation (only available in [Python >= 3.11](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)).
|
||||
`get_stream_writer()` won't work since it uses [contextvar](https://docs.python.org/3/library/contextvars.html) propagation (only available in [Python >= 3.11](https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task)).
|
||||
|
||||
Example: Using with `StateGraph`
|
||||
Example: Using with StateGraph
|
||||
```python
|
||||
from typing_extensions import TypedDict
|
||||
from langgraph.graph import StateGraph, START
|
||||
|
||||
@@ -357,7 +357,7 @@ class entrypoint(Generic[ContextT]):
|
||||
my_workflow.invoke("hello", config)
|
||||
```
|
||||
|
||||
Example: Using `entrypoint.final` to save a value
|
||||
Example: Using entrypoint.final to save a value
|
||||
The `entrypoint.final` object allows you to return a value while saving
|
||||
a different value to the checkpoint. This value will be accessible
|
||||
in the next invocation of the entrypoint via the `previous` parameter, as
|
||||
|
||||
@@ -88,8 +88,8 @@ def add_messages(
|
||||
If a message in `right` has the same ID as a message in `left`, the
|
||||
message from `right` will replace the message from `left`.
|
||||
|
||||
Example: Basic usage
|
||||
```python
|
||||
Example:
|
||||
```python title="Basic usage"
|
||||
from langchain_core.messages import AIMessage, HumanMessage
|
||||
|
||||
msgs1 = [HumanMessage(content="Hello", id="1")]
|
||||
@@ -98,16 +98,14 @@ def add_messages(
|
||||
# [HumanMessage(content='Hello', id='1'), AIMessage(content='Hi there!', id='2')]
|
||||
```
|
||||
|
||||
Example: Overwrite existing message
|
||||
```python
|
||||
```python title="Overwrite existing message"
|
||||
msgs1 = [HumanMessage(content="Hello", id="1")]
|
||||
msgs2 = [HumanMessage(content="Hello again", id="1")]
|
||||
add_messages(msgs1, msgs2)
|
||||
# [HumanMessage(content='Hello again', id='1')]
|
||||
```
|
||||
|
||||
Example: Use in a StateGraph
|
||||
```python
|
||||
```python title="Use in a StateGraph"
|
||||
from typing import Annotated
|
||||
from typing_extensions import TypedDict
|
||||
from langgraph.graph import StateGraph
|
||||
@@ -126,8 +124,7 @@ def add_messages(
|
||||
# {'messages': [AIMessage(content='Hello', id=...)]}
|
||||
```
|
||||
|
||||
Example: Use OpenAI message format
|
||||
```python
|
||||
```python title="Use OpenAI message format"
|
||||
from typing import Annotated
|
||||
from typing_extensions import TypedDict
|
||||
from langgraph.graph import StateGraph, add_messages
|
||||
|
||||
@@ -127,7 +127,6 @@ class StateGraph(Generic[StateT, ContextT, InputT, OutputT]):
|
||||
Args:
|
||||
state_schema: The schema class that defines the state.
|
||||
context_schema: The schema class that defines the runtime context.
|
||||
|
||||
Use this to expose immutable context data to your nodes, like `user_id`, `db_conn`, etc.
|
||||
input_schema: The schema class that defines the input to the graph.
|
||||
output_schema: The schema class that defines the output from the graph.
|
||||
@@ -372,23 +371,18 @@ class StateGraph(Generic[StateT, ContextT, InputT, OutputT]):
|
||||
|
||||
Args:
|
||||
node: The function or runnable this node will run.
|
||||
|
||||
If a string is provided, it will be used as the node name, and action will be used as the function or runnable.
|
||||
action: The action associated with the node.
|
||||
Will be used as the node function or runnable if `node` is a string (node name).
|
||||
defer: Whether to defer the execution of the node until the run is about to end.
|
||||
metadata: The metadata associated with the node.
|
||||
input_schema: The input schema for the node. (Default: the graph's state schema)
|
||||
input_schema: The input schema for the node. (default: the graph's state schema)
|
||||
retry_policy: The retry policy for the node.
|
||||
|
||||
If a sequence is provided, the first matching policy will be applied.
|
||||
cache_policy: The cache policy for the node.
|
||||
destinations: Destinations that indicate where a node can route to.
|
||||
|
||||
Useful for edgeless graphs with nodes that return `Command` objects.
|
||||
|
||||
This is useful for edgeless graphs with nodes that return `Command` objects.
|
||||
If a `dict` is provided, the keys will be used as the target node names and the values will be used as the labels for the edges.
|
||||
|
||||
If a `tuple` is provided, the values will be used as the target node names.
|
||||
|
||||
!!! note
|
||||
@@ -637,14 +631,11 @@ class StateGraph(Generic[StateT, ContextT, InputT, OutputT]):
|
||||
Args:
|
||||
source: The starting node. This conditional edge will run when
|
||||
exiting this node.
|
||||
path: The callable that determines the next node or nodes.
|
||||
|
||||
If not specifying `path_map` it should return one or more nodes.
|
||||
|
||||
If it returns `'END'`, the graph will stop execution.
|
||||
path_map: Optional mapping of paths to node names.
|
||||
|
||||
If omitted the paths returned by `path` should be node names.
|
||||
path: The callable that determines the next
|
||||
node or nodes. If not specifying `path_map` it should return one or
|
||||
more nodes. If it returns `'END'`, the graph will stop execution.
|
||||
path_map: Optional mapping of paths to node
|
||||
names. If omitted the paths returned by `path` should be node names.
|
||||
|
||||
Returns:
|
||||
Self: The instance of the graph, allowing for method chaining.
|
||||
@@ -685,9 +676,7 @@ class StateGraph(Generic[StateT, ContextT, InputT, OutputT]):
|
||||
|
||||
Args:
|
||||
nodes: A sequence of `StateNode` (callables that accept a `state` arg) or `(name, StateNode)` tuples.
|
||||
|
||||
If no names are provided, the name will be inferred from the node object (e.g. a `Runnable` or a `Callable` name).
|
||||
|
||||
Each node will be executed in the order provided.
|
||||
|
||||
Raises:
|
||||
@@ -744,14 +733,11 @@ class StateGraph(Generic[StateT, ContextT, InputT, OutputT]):
|
||||
"""Sets a conditional entry point in the graph.
|
||||
|
||||
Args:
|
||||
path: The callable that determines the next node or nodes.
|
||||
|
||||
If not specifying `path_map` it should return one or more nodes.
|
||||
|
||||
If it returns END, the graph will stop execution.
|
||||
path_map: Optional mapping of paths to node names.
|
||||
|
||||
If omitted the paths returned by `path` should be node names.
|
||||
path: The callable that determines the next
|
||||
node or nodes. If not specifying `path_map` it should return one or
|
||||
more nodes. If it returns END, the graph will stop execution.
|
||||
path_map: Optional mapping of paths to node
|
||||
names. If omitted the paths returned by `path` should be node names.
|
||||
|
||||
Returns:
|
||||
Self: The instance of the graph, allowing for method chaining.
|
||||
@@ -838,12 +824,9 @@ class StateGraph(Generic[StateT, ContextT, InputT, OutputT]):
|
||||
|
||||
Args:
|
||||
checkpointer: A checkpoint saver object or flag.
|
||||
|
||||
If provided, this `Checkpointer` serves as a fully versioned "short-term memory" for the graph,
|
||||
allowing it to be paused, resumed, and replayed from any point.
|
||||
|
||||
If `None`, it may inherit the parent graph's checkpointer when used as a subgraph.
|
||||
|
||||
If `False`, it will not use or inherit any checkpointer.
|
||||
interrupt_before: An optional list of node names to interrupt before.
|
||||
interrupt_after: An optional list of node names to interrupt after.
|
||||
|
||||
@@ -210,10 +210,8 @@ class NodeBuilder:
|
||||
*channels: str,
|
||||
read: bool = True,
|
||||
) -> Self:
|
||||
"""Add channels to subscribe to.
|
||||
|
||||
Node will be invoked when any of these channels are updated, with a dict of the
|
||||
channel values as input.
|
||||
"""Add channels to subscribe to. Node will be invoked when any of these
|
||||
channels are updated, with a dict of the channel values as input.
|
||||
|
||||
Args:
|
||||
channels: Channel name(s) to subscribe to
|
||||
@@ -272,8 +270,8 @@ class NodeBuilder:
|
||||
"""Add channel writes.
|
||||
|
||||
Args:
|
||||
*channels: Channel names to write to.
|
||||
**kwargs: Channel name and value mappings.
|
||||
*channels: Channel names to write to
|
||||
**kwargs: Channel name and value mappings
|
||||
|
||||
Returns:
|
||||
Self for chaining
|
||||
@@ -377,12 +375,12 @@ class Pregel(
|
||||
### Advanced channels: Context and BinaryOperatorAggregate
|
||||
|
||||
- `Context`: exposes the value of a context manager, managing its lifecycle.
|
||||
Useful for accessing external resources that require setup and/or teardown. e.g.
|
||||
`client = Context(httpx.Client)`
|
||||
Useful for accessing external resources that require setup and/or teardown. eg.
|
||||
`client = Context(httpx.Client)`
|
||||
- `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. e.g.
|
||||
`total = BinaryOperatorAggregate(int, operator.add)`
|
||||
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)`
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -497,7 +495,7 @@ class Pregel(
|
||||
{"c": ["foofoo", "foofoofoofoo"]}
|
||||
```
|
||||
|
||||
Example: Using a `BinaryOperatorAggregate` channel
|
||||
Example: Using a BinaryOperatorAggregate channel
|
||||
```python
|
||||
from langgraph.channels import EphemeralValue, BinaryOperatorAggregate
|
||||
from langgraph.pregel import Pregel, NodeBuilder
|
||||
@@ -543,9 +541,8 @@ class Pregel(
|
||||
|
||||
Example: Introducing a cycle
|
||||
This example demonstrates how to introduce a cycle in the graph, by having
|
||||
a chain write to a channel it subscribes to.
|
||||
|
||||
Execution will continue until a `None` value is written to the channel.
|
||||
a chain write to a channel it subscribes to. Execution will continue
|
||||
until a None value is written to the channel.
|
||||
|
||||
```python
|
||||
from langgraph.channels import EphemeralValue
|
||||
@@ -1429,8 +1426,7 @@ class Pregel(
|
||||
Args:
|
||||
config: The config to apply the updates to.
|
||||
supersteps: A list of supersteps, each including a list of updates to apply sequentially to a graph state.
|
||||
|
||||
Each update is a tuple of the form `(values, as_node, task_id)` where `task_id` is optional.
|
||||
Each update is a tuple of the form `(values, as_node, task_id)` where `task_id` is optional.
|
||||
|
||||
Raises:
|
||||
ValueError: If no checkpointer is set or no updates are provided.
|
||||
@@ -1873,8 +1869,7 @@ class Pregel(
|
||||
Args:
|
||||
config: The config to apply the updates to.
|
||||
supersteps: A list of supersteps, each including a list of updates to apply sequentially to a graph state.
|
||||
|
||||
Each update is a tuple of the form `(values, as_node, task_id)` where `task_id` is optional.
|
||||
Each update is a tuple of the form `(values, as_node, task_id)` where `task_id` is optional.
|
||||
|
||||
Raises:
|
||||
ValueError: If no checkpointer is set or no updates are provided.
|
||||
@@ -2425,7 +2420,6 @@ class Pregel(
|
||||
context: The static context to use for the run.
|
||||
!!! version-added "Added in version 0.6.0"
|
||||
stream_mode: The mode to stream output, defaults to `self.stream_mode`.
|
||||
|
||||
Options are:
|
||||
|
||||
- `"values"`: Emit all values in the state after each step, including interrupts.
|
||||
@@ -2434,7 +2428,7 @@ class Pregel(
|
||||
If multiple updates are made in the same step (e.g. multiple nodes are run) then those updates are emitted separately.
|
||||
- `"custom"`: Emit custom data from inside nodes or tasks using `StreamWriter`.
|
||||
- `"messages"`: Emit LLM messages token-by-token together with metadata for any LLM invocations inside nodes or tasks.
|
||||
- Will be emitted as 2-tuples `(LLM token, metadata)`.
|
||||
Will be emitted as 2-tuples `(LLM token, metadata)`.
|
||||
- `"checkpoints"`: Emit an event when a checkpoint is created, in the same format as returned by `get_state()`.
|
||||
- `"tasks"`: Emit events when tasks start and finish, including their results and errors.
|
||||
- `"debug"`: Emit debug events with as much information as possible for each step.
|
||||
@@ -2443,21 +2437,17 @@ class Pregel(
|
||||
The streamed outputs will be tuples of `(mode, data)`.
|
||||
|
||||
See [LangGraph streaming guide](https://docs.langchain.com/oss/python/langgraph/streaming) for more details.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes.
|
||||
|
||||
Does not affect the output of the graph in any way.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes. Does not affect the output of the graph in any way.
|
||||
output_keys: The keys to stream, defaults to all non-context channels.
|
||||
interrupt_before: Nodes to interrupt before, defaults to all nodes in the graph.
|
||||
interrupt_after: Nodes to interrupt after, defaults to all nodes in the graph.
|
||||
durability: The durability mode for the graph execution, defaults to `"async"`.
|
||||
|
||||
Options are:
|
||||
|
||||
- `"sync"`: Changes are persisted synchronously before the next step starts.
|
||||
- `"async"`: Changes are persisted asynchronously while the next step executes.
|
||||
- `"exit"`: Changes are persisted only when the graph exits.
|
||||
subgraphs: Whether to stream events from inside subgraphs, defaults to `False`.
|
||||
|
||||
subgraphs: Whether to stream events from inside subgraphs, defaults to False.
|
||||
If `True`, the events will be emitted as tuples `(namespace, data)`,
|
||||
or `(namespace, mode, data)` if `stream_mode` is a list,
|
||||
where `namespace` is a tuple with the path to the node where a subgraph is invoked,
|
||||
@@ -2699,7 +2689,6 @@ class Pregel(
|
||||
context: The static context to use for the run.
|
||||
!!! version-added "Added in version 0.6.0"
|
||||
stream_mode: The mode to stream output, defaults to `self.stream_mode`.
|
||||
|
||||
Options are:
|
||||
|
||||
- `"values"`: Emit all values in the state after each step, including interrupts.
|
||||
@@ -2708,7 +2697,7 @@ class Pregel(
|
||||
If multiple updates are made in the same step (e.g. multiple nodes are run) then those updates are emitted separately.
|
||||
- `"custom"`: Emit custom data from inside nodes or tasks using `StreamWriter`.
|
||||
- `"messages"`: Emit LLM messages token-by-token together with metadata for any LLM invocations inside nodes or tasks.
|
||||
- Will be emitted as 2-tuples `(LLM token, metadata)`.
|
||||
Will be emitted as 2-tuples `(LLM token, metadata)`.
|
||||
- `"checkpoints"`: Emit an event when a checkpoint is created, in the same format as returned by `get_state()`.
|
||||
- `"tasks"`: Emit events when tasks start and finish, including their results and errors.
|
||||
- `"debug"`: Emit debug events with as much information as possible for each step.
|
||||
@@ -2717,21 +2706,17 @@ class Pregel(
|
||||
The streamed outputs will be tuples of `(mode, data)`.
|
||||
|
||||
See [LangGraph streaming guide](https://docs.langchain.com/oss/python/langgraph/streaming) for more details.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes.
|
||||
|
||||
Does not affect the output of the graph in any way.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes. Does not affect the output of the graph in any way.
|
||||
output_keys: The keys to stream, defaults to all non-context channels.
|
||||
interrupt_before: Nodes to interrupt before, defaults to all nodes in the graph.
|
||||
interrupt_after: Nodes to interrupt after, defaults to all nodes in the graph.
|
||||
durability: The durability mode for the graph execution, defaults to `"async"`.
|
||||
|
||||
Options are:
|
||||
|
||||
- `"sync"`: Changes are persisted synchronously before the next step starts.
|
||||
- `"async"`: Changes are persisted asynchronously while the next step executes.
|
||||
- `"exit"`: Changes are persisted only when the graph exits.
|
||||
subgraphs: Whether to stream events from inside subgraphs, defaults to `False`.
|
||||
|
||||
subgraphs: Whether to stream events from inside subgraphs, defaults to False.
|
||||
If `True`, the events will be emitted as tuples `(namespace, data)`,
|
||||
or `(namespace, mode, data)` if `stream_mode` is a list,
|
||||
where `namespace` is a tuple with the path to the node where a subgraph is invoked,
|
||||
@@ -3040,14 +3025,11 @@ class Pregel(
|
||||
context: The static context to use for the run.
|
||||
!!! version-added "Added in version 0.6.0"
|
||||
stream_mode: The stream mode for the graph run.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes.
|
||||
|
||||
Does not affect the output of the graph in any way.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes. Does not affect the output of the graph in any way.
|
||||
output_keys: The output keys to retrieve from the graph run.
|
||||
interrupt_before: The nodes to interrupt the graph run before.
|
||||
interrupt_after: The nodes to interrupt the graph run after.
|
||||
durability: The durability mode for the graph execution, defaults to `"async"`.
|
||||
|
||||
Options are:
|
||||
|
||||
- `"sync"`: Changes are persisted synchronously before the next step starts.
|
||||
@@ -3130,14 +3112,11 @@ class Pregel(
|
||||
context: The static context to use for the run.
|
||||
!!! version-added "Added in version 0.6.0"
|
||||
stream_mode: The stream mode for the graph run.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes.
|
||||
|
||||
Does not affect the output of the graph in any way.
|
||||
print_mode: Accepts the same values as `stream_mode`, but only prints the output to the console, for debugging purposes. Does not affect the output of the graph in any way.
|
||||
output_keys: The output keys to retrieve from the graph run.
|
||||
interrupt_before: The nodes to interrupt the graph run before.
|
||||
interrupt_after: The nodes to interrupt the graph run after.
|
||||
durability: The durability mode for the graph execution, defaults to `"async"`.
|
||||
|
||||
Options are:
|
||||
|
||||
- `"sync"`: Changes are persisted synchronously before the next step starts.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from langgraph_sdk.auth import Auth
|
||||
from langgraph_sdk.client import get_client, get_sync_client
|
||||
|
||||
__version__ = "0.2.10"
|
||||
__version__ = "0.2.9"
|
||||
|
||||
__all__ = ["Auth", "get_client", "get_sync_client"]
|
||||
|
||||
@@ -1033,7 +1033,6 @@ class AssistantsClient:
|
||||
*,
|
||||
metadata: Json = None,
|
||||
graph_id: str | None = None,
|
||||
name: str | None = None,
|
||||
limit: int = 10,
|
||||
offset: int = 0,
|
||||
sort_by: AssistantSortBy | None = None,
|
||||
@@ -1048,8 +1047,6 @@ class AssistantsClient:
|
||||
metadata: Metadata to filter by. Exact match filter for each KV pair.
|
||||
graph_id: The ID of the graph to filter by.
|
||||
The graph ID is normally set in your langgraph.json configuration.
|
||||
name: The name of the assistant to filter by.
|
||||
The filtering logic will match assistants where 'name' is a substring (case insensitive) of the assistant name.
|
||||
limit: The maximum number of results to return.
|
||||
offset: The number of results to skip.
|
||||
sort_by: The field to sort by.
|
||||
@@ -1080,8 +1077,6 @@ class AssistantsClient:
|
||||
payload["metadata"] = metadata
|
||||
if graph_id:
|
||||
payload["graph_id"] = graph_id
|
||||
if name:
|
||||
payload["name"] = name
|
||||
if sort_by:
|
||||
payload["sort_by"] = sort_by
|
||||
if sort_order:
|
||||
@@ -4294,7 +4289,6 @@ class SyncAssistantsClient:
|
||||
*,
|
||||
metadata: Json = None,
|
||||
graph_id: str | None = None,
|
||||
name: str | None = None,
|
||||
limit: int = 10,
|
||||
offset: int = 0,
|
||||
sort_by: AssistantSortBy | None = None,
|
||||
@@ -4309,8 +4303,6 @@ class SyncAssistantsClient:
|
||||
metadata: Metadata to filter by. Exact match filter for each KV pair.
|
||||
graph_id: The ID of the graph to filter by.
|
||||
The graph ID is normally set in your langgraph.json configuration.
|
||||
name: The name of the assistant to filter by.
|
||||
The filtering logic will match assistants where 'name' is a substring (case insensitive) of the assistant name.
|
||||
limit: The maximum number of results to return.
|
||||
offset: The number of results to skip.
|
||||
headers: Optional custom headers to include with the request.
|
||||
@@ -4338,8 +4330,6 @@ class SyncAssistantsClient:
|
||||
payload["metadata"] = metadata
|
||||
if graph_id:
|
||||
payload["graph_id"] = graph_id
|
||||
if name:
|
||||
payload["name"] = name
|
||||
if sort_by:
|
||||
payload["sort_by"] = sort_by
|
||||
if sort_order:
|
||||
|
||||
@@ -413,7 +413,6 @@ CronSelectField = Literal[
|
||||
"next_run_date",
|
||||
"metadata",
|
||||
"now",
|
||||
"on_run_completed",
|
||||
]
|
||||
|
||||
PrimitiveData = str | int | float | bool | None
|
||||
|
||||
Reference in New Issue
Block a user