**Description**: The Agent Server API now supports counting assistants
by name.
This is similar to adding the `name` parameter to the Assistants search
API: https://github.com/langchain-ai/langgraph/pull/6483
**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>
**Description:** There are times a user might want to create the client,
but conditionally set the API key. For example, consider a complex auth
situation where the system has user callers using jwts and system
callers using API keys. This allows explicitly disabling the
auto-loading behavior of API keys in the client today, so no key is set.
**Issue:** N/A
**Dependencies:** None
**Twitter handle:** N/A
Otherwise, you cannot use `context` with stateful runs, because the
server throws if you provide both configurable and context in a single
call (due to ambiguous parameters)
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).
Extract two common cases from the big switch statement of
`prepare_single_task` since it's a tad more composable.
All this does is shift/extract code to separate functions
`stream` and `astream` docstrings listed different available
`stream_mode` options.
Both methods support the same seven stream modes as defined in
`StreamMode`
Fixed for consistency
Hi all,
I found out that the sync and async code examples of the `task` function
in `libs/langgraph/langgraph/func/__init__.py` have a typo:
```
Example: Sync Task
```python
from langgraph.func import entrypoint, task
@task
def add_one(a: int) -> int:
return a + 1
@entrypoint()
def add_one(numbers: list[int]) -> list[int]:
futures = [add_one(n) for n in numbers]
results = [f.result() for f in futures]
return results
# Call the entrypoint
add_one.invoke([1, 2, 3]) # Returns [2, 3, 4]
```
```
Both task and entrypoint functions have the same name which gives an
error.
This is a small PR to fix this
Thank you for contributing to LangGraph! Follow these steps to mark your
pull request as ready for review. **If any of these steps are not
completed, your PR will not be considered for review.**
- [x] **PR title**: Follows the format: {TYPE}({SCOPE}): {DESCRIPTION}
- Examples:
- feat(core): add multi-tenant support
- fix(cli): resolve flag parsing error
- docs(openai): update API usage examples
- Allowed `{TYPE}` values:
- feat, fix, docs, style, refactor, perf, test, build, ci, chore,
revert, release
- Allowed `{SCOPE}` values (optional):
- langgraph, docs, cli, checkpoint, checkpoint-postgres,
checkpoint-sqlite, prebuilt, scheduler-kafka, sdk-py
- Once you've written the title, please delete this checklist item; do
not include it in the PR.
- **Description:** Azure Postgres SQL server has a limitation when doing
create extension vector is not exists, even though it manually created
before on a schema.
- **Issue:** Even though `CREATE EXTENSION vector` is executed manually
before, the permission issue arises. Putting it in an if else block
solves the issue and its not a breaking change.
```
Because vector isn't a trusted extension, only members of "azure_pg_admin" are allowed to use CREATE EXTENSION vector
HINT: to learn how to allow an extension or see the list of allowed extensions, please refer to https://go.microsoft.com/fwlink/?linkid=2301063
```
Co-authored-by: Josh Rogers <josh@langchain.dev>
## Issue
The `stream_mode` argument type includes `Sequence`, but it doesn't
correctly support non-list sequences. On the other hand, the
`print_mode` argument works as expected.
### Example
```python
from langgraph.pregel.main import Pregel
pregel = Pregel(nodes={}, channels=None, input_channels=[], output_channels=[], auto_validate=False)
stream_modes, *_ = pregel._defaults(
config={"recursion_limit": 1},
stream_mode=("values", "messages"),
print_mode=("values"),
output_keys=None,
interrupt_before=None,
interrupt_after=None,
durability=None,
)
print(stream_modes) # Expected `{'values', 'messages'}`, got `{('values', 'messages'), 'values'}`
```
## Summary
Replace f-string SQL formatting with parameterized queries to prevent
potential SQL injection in checkpoint migration code.
## Changes
Updated the migration version tracking INSERT statements in all
checkpoint saver classes to use parameterized queries instead of
f-string formatting:
- `PostgresSaver`
(libs/checkpoint-postgres/langgraph/checkpoint/postgres/__init__.py:100)
- `AsyncPostgresSaver`
(libs/checkpoint-postgres/langgraph/checkpoint/postgres/aio.py:104-106)
- `ShallowPostgresSaver`
(libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py:255)
- `AsyncShallowPostgresSaver`
(libs/checkpoint-postgres/langgraph/checkpoint/postgres/shallow.py:617-619)
**Before (vulnerable to SQL injection):**
```python
cur.execute(f"INSERT INTO checkpoint_migrations (v) VALUES ({v})")
```
**After (using parameterized query):**
```python
cur.execute("INSERT INTO checkpoint_migrations (v) VALUES (%s)", (v,))
```
## Risk Assessment
The practical risk is low since `v` is an integer loop variable
controlled by the codebase. However, using string formatting in SQL
queries is a well-known anti-pattern that can lead to SQL injection
vulnerabilities, especially if the code is later refactored or copied to
other contexts.
## Testing
- ✅ All 216 tests passing on PostgreSQL 15 and 16
- ✅ Linting and type checking passing
- ✅ No functional changes to behavior
Thank you for contributing to LangGraph! Follow these steps to mark your
pull request as ready for review. **If any of these steps are not
completed, your PR will not be considered for review.**
- [x] **PR title**: Follows the format: {TYPE}({SCOPE}): {DESCRIPTION}
- Examples:
- feat(core): add multi-tenant support
- fix(cli): resolve flag parsing error
- docs(openai): update API usage examples
- Allowed `{TYPE}` values:
- feat, fix, docs, style, refactor, perf, test, build, ci, chore,
revert, release
- Allowed `{SCOPE}` values (optional):
- langgraph, docs, cli, checkpoint, checkpoint-postgres,
checkpoint-sqlite, prebuilt, scheduler-kafka, sdk-py
- Once you've written the title, please delete this checklist item; do
not include it in the PR.
- [x] **PR message**: ***Delete this entire checklist*** and replace
with
- **Description:** a description of the change. Include a [closing
keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)
if applicable.
- **Issue:** the issue # it fixes, if applicable
- **Dependencies:** any dependencies required for this change
- **Twitter handle:** if your PR gets announced, and you'd like a
mention, we'll gladly shout you out!
- [x] **Add tests and docs**: If you're adding a new integration, you
must include:
1. A test for the integration, preferably unit tests that do not rely on
network access,
2. An example notebook showing its use. It lives in
`docs/docs/integrations` directory.
- [x] **Lint and test**: Run `make format`, `make lint` and `make test`
from the root of the package(s) you've modified. We will not consider a
PR unless these three are passing in CI. See [contribution
guidelines](https://github.com/langchain-ai/langgraph/blob/main/CONTRIBUTING.md)
for more.
Additional guidelines:
- Make sure optional dependencies are imported within a function.
- Please do not add dependencies to `pyproject.toml` files (even
optional ones) unless they are **required** for unit tests.
- Most PRs should not touch more than one package.
- Changes should be backwards compatible.
`REMOVE_ALL_MESSAGES` is a public constant used with `RemoveMessage` to
clear all messages from the state:
```python
from langchain_core.messages import RemoveMessage
from langgraph.graph.message import REMOVE_ALL_MESSAGES
# Clear all messages
[RemoveMessage(id=REMOVE_ALL_MESSAGES)]
```
However, it is not exported in __all__, causing:
Linting errors in IDEs (PyCharm)
no-member warnings from Pylint
Confusion for users
This PR:
Adds REMOVE_ALL_MESSAGES to __all__
Adds inline docstring with usage example
No runtime behavior changes — only improves IDE support and API clarity.
Thank you for contributing to LangGraph! Follow these steps to mark your
pull request as ready for review. **If any of these steps are not
completed, your PR will not be considered for review.**
---
Local verification:
```bash
# Before
from langgraph.graph.message import REMOVE_ALL_MESSAGES # Pylint: no-member
# After: no error
```
CI Note: This is a pure export/docs fix. `make lint` and `make test`
pass unchanged.
Thank you for contributing to LangGraph! Follow these steps to mark your
pull request as ready for review. **If any of these steps are not
completed, your PR will not be considered for review.**
## Description
- Fixed a bug in `libs/sdk-py/langgraph_sdk/auth/__init__.py` where the
error message for an already-set authentication handler did not properly
render the handler value.
- Updated the error string from a static `{self._authenticate_handler}`
to a correctly interpolated f-string.
```python
"Authentication handler already set as {self._authenticate_handler}."
```
```python
f"Authentication handler already set as {self._authenticate_handler}."
```
- Error messages now correctly display the actual handler instance,
improving debugging clarity.
- **Issue:** Fixes https://github.com/langchain-ai/langgraph/issues/6387
- **Dependencies:** -
- **Twitter handle:** -
- [x] **Add tests and docs**: If you're adding a new integration, you
must include:
1. A test for the integration, preferably unit tests that do not rely on
network access,
2. An example notebook showing its use. It lives in
`docs/docs/integrations` directory.
- [ ] **Lint and test**: Run `make format`, `make lint` and `make test`
from the root of the package(s) you've modified. We will not consider a
PR unless these three are passing in CI. See [contribution
guidelines](https://github.com/langchain-ai/langgraph/blob/main/CONTRIBUTING.md)
for more.
Additional guidelines:
- Make sure optional dependencies are imported within a function.
- Please do not add dependencies to `pyproject.toml` files (even
optional ones) unless they are **required** for unit tests.
- Most PRs should not touch more than one package.
- Changes should be backwards compatible.
In this PR:
- Add missing LICENSE files for checkpoint-sqlite and
checkpoint-postgres libraries.
Both libraries specify the MIT License in their pyproject.toml files,
but the actual LICENSE files were missing.
This update adds the corresponding LICENSE files to ensure proper
license documentation and compliance.
This is a very small PR to correct a typo in the docstring of the
`PregelLoop.tick()` method.
```python
def tick(self) -> bool:
"""Execute a single iteration of the Pregel loop.
Args:
input_keys: The key(s) to read input from.
Returns:
True if more iterations are needed.
"""
```
Corrected to :
```python
def tick(self) -> bool:
"""Execute a single iteration of the Pregel loop.
Returns:
True if more iterations are needed.
"""
```
The docstring was written in #2946 when the signature of tick was
```python
def tick(
self,
*,
input_keys: Union[str, Sequence[str]],
) -> bool:
```
but it was simplified to
```python
def tick(self) -> bool:
```
in #5080