**Description:**
This PR adds the Python SDK types necessary for langgraph platform users
to inject their own custom encryption-at-rest functions. See [docs
PR](https://github.com/langchain-ai/docs/pull/1715) for more details.
note: this PR adds a starlette dev dependency so that custom encryption
can access BaseUser information.
**Issue:**
required for LSD-172
**Dependencies:**
- [depended upon by associated langgraph-api
changes](https://github.com/langchain-ai/langgraph-api/pull/1773)(this
PR must merge before that one)
- [docs PR](https://github.com/langchain-ai/docs/pull/1715)
**TODO:**
- [x] move docs to docs repo
- [x] bump package versions before merge
---------
Signed-off-by: Connor Braa <cwlbraa@langchain.dev>
Co-authored-by: Claude <noreply@anthropic.com>
This PR improves the consistency of interrupt streaming.
- when streaming with stream_mode values, the stream chunk now contains
the entire state alongside the interrupt:
```python
class State(TypedDict):
robot_input: str
# at this point in time robot_input is already set to "beep boop i am a robot"
app.stream(..., stream_mode="values")
# before
{"__interrupt__": (Interrupt(value="interrupt",))}}
# after
{"robot_input": "beep boop i am a robot", "__interrupt__": (Interrupt(value="interrupt"))}
```
- when streaming with stream_mode=["values", "updates"], interrupts are
surfaced in both an update stream chunk and the value stream chunk, when
previously we keep interrupt in values only if we request values mode
only
```python
class State(TypedDict):
robot_input: str
# at this point in time robot_input is already set to "beep boop i am a robot"
app.stream(..., stream_mode=["values", "updates"])
# before (interrupt would only emit on update chunk, there would be no values chunk)
("updates", {"__interrupt__": (Interrupt(value="interrupt",))}})
# after
("updates", {"__interrupt__": (Interrupt(value="interrupt",))}})
("values", {"robot_input": "beep boop i am a robot", "__interrupt__": (Interrupt(value="interrupt"))})
```
For housekeeping: this PR improves on this revert:
https://github.com/langchain-ai/langgraph/pull/6141
## overview
The main purpose of this is to respect tool signatures that request
injected args (like `ToolRuntime`) even when the explicitly specified
`args_schema` does not.
Ex in the following example, we should still inject `runtime` despite
its absence in `ArgsSchema`
```py
class ArgsSchema(BaseModel):
some_arg: int = Field(...)
@tool(args_schema=ArgsSchema)
def my_tool(some_arg: int, runtime: ToolRuntime): ...
```
This is accompanied by
https://github.com/langchain-ai/langchain/pull/34051 which has tests
that pass w/ this change. This tests injection w/ `create_agent` (more
end to end than tests added in
https://github.com/langchain-ai/langchain/pull/33999.
This unblocks the injection of `ToolRuntime` into MCP tools which is
exciting bc that exposes tool call id and state, which we previously
were unable to do.
## other benefits
* Cleaner code structure w/ more helpful docs about injected args.
* Nice perf boost, we're no longer inspecting the annotations of a
tool's schema 3 different times to detect store, state, and runtime
injections.
## additional notes
1. I could see a world where we want more of this logic to reside on the
tools themselves, but tools don't now about LG specific injection types
(like `ToolRuntime`, hence having this logic here for now).
2. We could separately add validation for the case where something is
specified in `args_schema` and not in the function signature (probably
at the tool level though).
**Description:** Bumping the checkpoint-postgres package to version
3.0.1 to release an update to migrations
(https://github.com/langchain-ai/langgraph/pull/6400).
**Issue:** N/A
**Dependencies:** N/A
**Twitter handle:** N/A
namespace decisions
```
langgraph.prebuilt
├── ToolRuntime # new
# all of the other stuff that was already there
langgraph.prebuilt.tool_node
├── ToolNode
├── ToolCallRequest # new
├── ToolRuntime # new
├── InjectedState
├── InjectedStore
├── ToolCallWrapper
├── AsyncToolCallWrapper
├── tools_condition
```
```
langchain.tools
├── ToolRuntime # now from langgraph.prebuilt
├── InjectedState # now from langgraph.prebuilt
├── InjectedStore # now from langgraph.prebuilt
├── ToolException
├── tool
├── BaseTool
├── InjectedToolArg
├── InjectedToolCallId
```
bumping core dependency for `langgraph-prebuilt` to `>1.0.0` so that we
can take advantage of internal utils that allow `ToolRuntime` injection.
We were previously bumping the version in lock step with prebuilt (prev
version was 0.3.67), so this pattern is in line with that.
Also updating snapshots accordingly:
* New mermaid syntax for a few graphs
* Removal of `examples` from `AIMessage`
In this PR:
- Bump `langgraph-checkpoint` to 3.0
- Bump `langgraph-checkpoint-sqlite` to 3.0; Update
`langgraph-checkpoint` deps to >=3,<4
- Bump `langgraph-checkpoint-postgres` to 3.0; Update
`langgraph-checkpoint` max to <4 (keep prior min since the deprecated
functionality wasn't explicitly used)
- Bump `langgraph` to 1.0.1; update `langgraph-checkpoint` max bound to
4
- Bump `prebuilt` to 1.0.1; update `langgraph-checkpoint` max bound to 4
* catching error thrown by asyncio
* using 2nd check for annotations given Pydantic 2.12 changes
* skipping tests for remote graph bc langgraph-api is dependent on
`jsonschema-rs`
* skipping tests w/ pydantic v1 models
```bash
hint: This usually indicates a problem with the package or the build environment.
help: `jsonschema-rs` (v0.29.1) was included because `langgraph:dev` (v1.0.0rc1) depends on `langgraph-cli[inmem]` which
depends on `langgraph-api` (v0.4.29) which depends on `jsonschema-rs`
```
not yet testing for free threaded python, that'll be much more involved!
ended up separating lint / testing deps during this process bc I was
getting a ton of not required deps while testing that were complicating
things :/
This PR updates the dependencies in all Python packages using `uv lock
--upgrade`.
This is an automated PR created by the UV Lock Upgrade workflow.
Co-authored-by: sydney-runkle <54324534+sydney-runkle@users.noreply.github.com>
This PR updates the dependencies in all Python packages using `uv lock
--upgrade`.
This is an automated PR created by the UV Lock Upgrade workflow.
Co-authored-by: sydney-runkle <54324534+sydney-runkle@users.noreply.github.com>
This PR updates the dependencies in all Python packages using `uv lock
--upgrade`.
This is an automated PR created by the UV Lock Upgrade workflow.
To make tests pass:
* linting fixes
* whitespace fixes in snapshots
---------
Co-authored-by: sydney-runkle <54324534+sydney-runkle@users.noreply.github.com>
Co-authored-by: Sydney Runkle <sydneymarierunkle@gmail.com>
### Description
Adds Redis as a supported cache backend for LangGraph node-level
caching, enabling distributed caching across multiple processes/servers.
This implementation follows the same patterns as existing InMemoryCache
and SqliteCache.
### Key changes
- New RedisCache class implementing the BaseCache interface
- Support for TTL-based expiration and batch operations
- Worker-specific cache prefixes for parallel test isolation
### Dependencies
- redis package (already included in dev dependencies)
### Test Plan
- Unit tests: Added Redis cache tests covering basic operations, TTL,
batch operations, and error handling
- Integration tests: Redis cache integrated into existing LangGraph test
suite, tested with all checkpointer combinations
Reproduces:
https://github.com/langchain-ai/langgraph/issues/5249#issuecomment-3156519635
Caused after this change:
https://github.com/langchain-ai/langgraph/pull/4843
Fix to allow emitting messages from subgraphs if the subgraphs
explicitly used a stream mode "messages".
```python
def node_in_parent(...):
# subgraph was called as a function.
# messages are explicitly requested.
for event in subgraph.stream(..., stream_mode="messages"):
# something is done with `event`
return ...
# subgraphs = False!
parent_graph.invoke(..., subgraphs=False)
```
The code above should continue to work correctly regardless of the value
of subgraphs as streaming messages was requested explicitly in the
parent node!
---------
Co-authored-by: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com>
`MessageGraph` is deprecated, to be removed in v2.
A `StateGraph` with a `messages` key should be used instead.
Alternatively, folks can use `Annotated[list[AnyMessage], add_messages]` as their state schema.
Reverts https://github.com/langchain-ai/langgraph/pull/5562
I anticipate that we want to do another pass at a refactor here in the
short term, but this makes it easier to adapt to new langchain core
message types for v0.4 support in the short term.
Fixes https://github.com/langchain-ai/langgraph/issues/5784
* Removes usage of `is_last_step`, no longer needed with
`remaining_steps`
* Make `remaining_steps` `NotRequired` so that json schema doesn't
suggest need for user input
* Move `PregelScratchpad` to shared utils file to prevent circular
import issue (it's used from `channels/managed` and other pregel files).
* Ensures that managed values wrapped in `NotRequired` or `Required` are
still recognized!