100 Commits
Author SHA1 Message Date
40ab009c62 feat: allow graph to graceful shutdown/drain by request (#7274)
## Summary

Adds cooperative drain support for Pregel runs so a graph can be asked
to stop at the next superstep boundary, persist its checkpoint, and
surface a resumable terminal exception.

- New `RunControl` (in `langgraph.runtime`) — a thread-safe handle whose
`request_drain(reason="shutdown")` sets a single flag.
- New `GraphDrained(GraphBubbleUp)` exception (in `langgraph.errors`)
raised when a run exits early due to drain. Carries the `reason` string.
- New `control: RunControl | None` kwarg on `invoke` / `ainvoke` /
`stream` / `astream` / `stream_v2` / `astream_v2`. Wired through to
`Runtime.control`, so nodes can read `runtime.control.drain_requested` /
`drain_reason` and even call `request_drain()` from inside a node.
- Stream transformers learn `"drained"` as a terminal `SubgraphStatus`.

The intended use is hooking SIGTERM (or any external supervisor signal)
to `control.request_drain("sigterm")` so an in-flight graph run can stop
cleanly and be resumed later from the saved checkpoint.

## Semantics: cooperative, between-superstep

`request_drain()` flips a flag. The Pregel loop checks it at the top of
each `tick()`, **after** the previous superstep's writes have been
applied and checkpointed. It never preempts work that is already
running.

| Scenario | Behavior |
|---|---|
| Node mid-execution (blocking I/O, sleeps, etc.) | Runs to completion.
Drain takes effect on the next superstep. |
| Node with a retry policy currently retrying | Retry loop runs to
exhaustion or success (drain is not checked between retries). Drain
takes effect on the next superstep. |
| Functional API: `@entrypoint` with pending `@task` futures |
Entrypoint and all dispatched tasks complete; drain takes effect after
the entrypoint returns. |
| Graph naturally finishes on the same tick where drain was requested
(no more tasks) | Treated as `done`; returns normally. **No
`GraphDrained` is raised.** The caller can inspect
`control.drain_requested` afterwards to distinguish a
drained-but-completed run from a normal one. |
| More tasks remain | Raises `GraphDrained(reason)`. The checkpoint of
the last completed superstep is saved (also under `durability="exit"`).
Resume with `invoke(None, config)` / `ainvoke(None, config)`. |
| Subgraph requests drain | `GraphDrained` bubbles up through the parent
loop and stops it at its own next superstep boundary; the parent's
checkpoint is saved and resumable. |

Drain does **not** cancel asyncio tasks or kill threads. Pair it with a
graceful timeout + `task.cancel()` (or process exit) if you need a hard
upper bound — see `test_drain_then_cancel_after_graceful_timeout` for
the recommended pattern.

## Usage

```python
from langgraph.runtime import RunControl
from langgraph.errors import GraphDrained

control = RunControl()

# In a signal handler, supervisor, etc.:
# control.request_drain("sigterm")

try:
    result = graph.invoke(input, config, control=control)
    if control.drain_requested:
        # finished naturally on the same tick where drain was requested
        ...
except GraphDrained as e:
    # checkpoint saved; resume later with the same config
    log.info("graph drained: %s", e.reason)
```

## Test plan

- [x] Sync + async drain stops the next superstep
(`test_run_control_request_drain_stops_future_steps[_async]`)
- [x] Drain on the terminal step finishes normally
(`test_drain_requested_in_terminal_step_finishes_normally[_async]`)
- [x] `durability=\"exit\"` persists a resumable checkpoint on drain
(`test_drain_with_exit_durability_persists_resume_checkpoint`)
- [x] Subgraph drain bubbles up and parent resumes correctly
(`test_drain_from_subgraph_can_resume_parent`)
- [x] External thread / task triggering drain mid-run
(`test_external_drain_concurrent_sync` / `_async`)
- [x] Drain + hard cancel after graceful timeout
(`test_drain_then_cancel_after_graceful_timeout`)
- [x] Functional API: in-flight `@task` futures still resolve after
`request_drain()`
(`test_request_drain_allows_inflight_[a]call_scheduling`)
- [x] `control` kwarg wired through `stream_v2`
(`test_stream_v2_accepts_control_for_drain`)
- [x] `Runtime.merge` preserves `control`
(`test_merge_runtime_preserves_run_control`)

---------

Co-authored-by: Quanzheng Long <long@langchain.dev>
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 15:23:31 -07:00
William FHGitHubWill Fu-HinthornSydney Runklecopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
4a5765dd23 release: alpha for timers (#7647)
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
Co-authored-by: Sydney Runkle <sydneymarierunkle@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-04-29 17:49:01 -04:00
a48a045596 chore: dynamic push-task timeouts (#7646)
You can Send(..., timeout=...) now. Much fun.


This would allow us to do something like adding support for an
annotation to let the LLM to pick a timeout for a given tool call, etc.

---------

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-29 12:37:19 -07:00
William FHGitHubWill Fu-HinthornClaude Opus 4.7copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
800071d0d4 chore: idle timeout (#7631)
## Summary

Adds per-node `timeout` support to async StateGraph/Pregel nodes and to
the functional API (`@task` / `@entrypoint`). A timeout caps how long a
single node attempt may run, either as a hard wall-clock budget
(`run_timeout`), or as an idle window that resets on observable progress
(`idle_timeout`), or both. When exceeded, LangGraph raises
`NodeTimeoutError`, clears writes from the failed attempt, and lets the
existing retry policy decide whether to retry.

## Public API

A single `timeout=` kwarg on `add_node`, `@task`, `@entrypoint`, and
`NodeBuilder.set_timeout`. Pass a number/`timedelta` for the simple case
(treated as a hard wall-clock cap), or a `TimeoutPolicy` (in
`langgraph.types`) for finer control:

```python
from datetime import timedelta
from langgraph.types import TimeoutPolicy

# simple: hard wall-clock cap on each attempt
builder.add_node("call_model", call_model, timeout=60)
builder.add_node("call_model", call_model, timeout=timedelta(minutes=2))

# full control
builder.add_node(
    "call_model",
    call_model,
    timeout=TimeoutPolicy(
        run_timeout=120,                # hard wall-clock cap in seconds, never refreshed
        idle_timeout=30,                # cap on time without observable progress, units in seconds
        refresh_on="auto",              # "auto" | "heartbeat"
    ),
)
```

- `run_timeout`: hard wall-clock cap on a single attempt; never
refreshed.
- `idle_timeout`: progress-resetting cap. Refreshed by writes, stream
output, yielded async stream chunks, child-task scheduling, runtime
stream-writer calls, and any LangChain callback event from descendants
of the node's run. `runtime.heartbeat()` is a manual signal for work
that doesn't naturally emit any of these.
- `refresh_on="heartbeat"` narrows the refresh source to explicit
`runtime.heartbeat()` only — useful when you want a strict idle
definition that isn't reset by chatty subordinates.

For long-running async work that doesn't naturally emit progress:

```python
async def call_model(state: State, runtime: Runtime) -> State:
    while still_working:
        ...
        runtime.heartbeat()
    return {"messages": [response]}
```

`NodeTimeoutError` subclasses `TimeoutError` and carries `node`,
`timeout`, `run_timeout`, `idle_timeout`, `elapsed`, and `kind` (`"run"`
or `"idle"`). If the node's `retry_policy` permits `TimeoutError` it'll
retry; the timer resets per attempt.

## Why async-only

Sync Python code cannot be safely cancelled in-process, so timeouts only
apply to async nodes/tasks. Sync nodes with a `timeout` are rejected at
compile time (covers direct nodes, wrapped runnables, sequences, and
`RunnableParallel` branches); `run_with_retry` rejects them at runtime
as a safety net.

## What gets cancelled and what doesn't

When a watchdog fires:

1. The attempt scope is closed under a lock so any in-flight
`CONFIG_KEY_SEND` / stream / child-task scheduling that races with the
timeout is dropped atomically.
2. Buffered `task.writes` are cleared so pre-timeout writes from the
failed attempt don't leak into the checkpoint after a retry succeeds.
3. The background `asyncio.Task` is cancelled; its eventual exception is
drained via a done-callback so asyncio doesn't log it.

Only the watchdog's own `TimeoutError` converts to `NodeTimeoutError`,
so user-raised `asyncio.TimeoutError`, built-in `TimeoutError`, and
`NodeTimeoutError` from a child node continue to propagate unchanged.

Child tasks already scheduled before the timeout fired still complete —
they aren't part of the cancelled task's structured cancellation
surface. This is intentional and tested.

## External-watchdog hook

WARNING: THIS API IS IN ALPHA AND SUBJECT TO CHANGE.

`CONFIG_KEY_TIMED_ATTEMPT_OBSERVER` is a per-config callback that
receives lifecycle events for each timed attempt:

- `start` — fired before the proc runs, with `task_id`, `task_name`,
`attempt`, `run_id`, `thread_id`, `checkpoint_ns`, `started_at`, and the
configured `run_timeout_secs` / `idle_timeout_secs` / `refresh_on`.
- `progress` — fired on each progress signal that resets the idle clock,
rate-limited to ~4 events per `idle_timeout` window so token-rate
callbacks don't flood the observer. Carries the same context plus
`progress_at`.
- `finish` — fired with `finished_at`, `status` (`"success"`/`"error"`),
`error_type`, `error_message`. `ParentCommand` and `GraphBubbleUp` are
treated as control flow, not errors.

This lets an orchestrating process listen to `start` + rolling
`progress` to compute its own kill deadline (`progress_at +
idle_timeout_secs`) and hard-kill a worker process if the in-process
cancellation deadlocks. Observer callbacks run in whatever thread fires
them, and any exception they raise is logged and swallowed.

## Implementation Notes

`runtime.heartbeat()` updates the progress timestamp without taking the
guarded write lock. This avoids lock overhead on high-frequency
callback/token paths and accepts a small timestamp race window, which is
negligible for expected coarse idle-timeout configurations.

## Testing

Covers timeout retry behavior, user-raised timeout propagation,
stale-write suppression, stream / callback / heartbeat progress resets,
sync-node rejection, `RunnableParallel` branch validation,
`StateGraph.add_node` behavior, lower-level Pregel behavior, observer
start/progress/finish events, and functional API compatibility.

---------

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-04-29 10:12:28 -07:00
William FHandGitHub d177a0db43 Revert "chore: node-level timeouts" (#7627)
Reverts langchain-ai/langgraph#7599

I am going to implement this as an `idle_timeout` instead. I think
that's a better default behavior.
2026-04-27 09:03:19 -07:00
aeff9549c2 chore: node-level timeouts (#7599)
This PR implements task/node-level timeouts. 

Since python has a terrible multi-processing model, we make two
concessions:
- we only support for async functions/nodes. Sync nodes with a timeout
raise an error at compile time
- we implement this with asyncio wait_for in the async path.
 
Each timed attempt is wrapped in _retry.py, and the timer is reset on
each node-level retry. When the deadline is exceeded LangGraph raises
NodeTimeoutError, clears buffered writes, and prevents any late writes
or child-task scheduling from leaking past the timeout via
_TimedAttemptScope.

The design also adds a timed-attempt observer hook
(CONFIG_KEY_TIMED_ATTEMPT_OBSERVER) that emits start/finish events with
identifiers and deadlines. This means that if you have an orchestrating
process starting a worker process, it can listen to start/end events and
hard-kill the process to enforce a timeout if there is a deadlock.

---------

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-24 18:27:22 -07:00
8657df80f3 chore: mixup cli formatting (#7585)
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-22 11:29:23 -07:00
f44b49b33d chore: dedup warnings (#7257)
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-17 10:13:03 -07:00
a0a95df2ac release(cli): 0.4.23 (#7542)
Release Note: Increase the max bound for langgraph-api

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-17 16:38:14 +00:00
25470ea435 release(checkpoint): 4.0.2 (#7518)
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-15 20:52:57 +00:00
4c67f84016 chore: allow passing some metadata only for tracing purposes (#7383)
Allows us to put some more information for tracing purposes (e.g.,
ls_integration) without dumping it into the streaming APIs (good for
performance)
Move some other metadata into tracing only since it's not needed in
streaming APIs

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2026-04-14 09:58:24 -04:00
1629794658 chore: update conformance lint (#7459)
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-08 18:22:18 -07:00
6242b99e06 chore(checkpoint-conformance): remove test_list_global_search, bump to 0.0.2 (#7444)
## Summary
- Remove `test_list_global_search` from the conformance test suite. This
test required cross-thread `alist(None, filter=...)` support that not
all checkpointer implementations provide.
- Remove the corresponding entry from `ALL_LIST_TESTS`.
- Bump `langgraph-checkpoint-conformance` version from 0.0.1 to 0.0.2.

## Test plan
- [x] Verify `test_list_global_search` function definition is fully
removed
- [x] Verify `test_list_global_search` is removed from `ALL_LIST_TESTS`
- [x] Verify version bumped to 0.0.2 in pyproject.toml

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 05:54:37 -07:00
890147681d chore(cli): add validate command (#7438)
add validate command

---------

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-07 18:29:24 -07:00
336ad1239b release(cli): lockfile (#7436)
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-07 17:19:17 -07:00
51f6cee1b1 chore: uv lock resolution (#7342)
## Summary

Adds native uv workspace/lockfile support to the LangGraph CLI's Docker
build pipeline. Instead of listing dependencies manually, users can
point at their existing `uv.lock` and the CLI will:

1. Discover workspace packages and their dependency graph
2. Export locked requirements via `uv export --package <name> --frozen`
3. Copy only the necessary workspace closure into the container
4. Install packages in dependency order with `--no-deps` for
reproducibility
5. Rewrite all import paths (graphs, auth, encryption, etc.) to
container paths

### New config field: `source`

Rather than using `pip` or `uv pip`, we add a new `uv_lock` installer.
The previous installers should still remain unchanged.

To avoid ambiguity, we discriminate by "source" field and **do not
permit** other arbitrary "dependencies". In this mode, we will treat the
provided root (defaults to the current directory) as the source of
truth.

This also would natively support uv workspaces, so you can specify the
target package within a larger workspace.

**Simple single-package project:**
```json
{
  "python_version": "3.11",
  "graphs": {
    "agent": "./agent.py:graph"
  },
  "source": {
    "kind": "uv"
  }
}
```

**Multi-package workspace with explicit package:**
```json
{
  "python_version": "3.11",
  "graphs": {
    "agent": "../../apps/agent/src/agent/graph.py:graph"
  },
  "source": {
    "kind": "uv",
    "root": "../..",
    "package": "agent"
  }
}
```

**Traditional pip deployment (unchanged):**
```json
{
  "python_version": "3.11",
  "dependencies": ["langgraph", "my-package"],
  "graphs": {
    "agent": "./agent.py:graph"
  }
}
```

Config validation enforces mutual exclusivity. you must use either
`dependencies` or `source`, not both.

---------

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-07 17:17:54 -07:00
7173379740 chore: bump langgraph version to 1.1.5 in CI and examples (#7435)
## Summary
- Bump `langgraph` version from `1.1.2` to `1.1.5` in the CI integration
test workflow version check
- Bump `langgraph` version from `1.1.2` to `1.1.5` in the prerelease
example `pyproject.toml` files

## Test plan
- [ ] CI integration tests pass with the updated version expectation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:20:56 -07:00
b2893bc778 chore: validate reconnect url (#7434)
Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
2026-04-07 13:30:49 -07:00
b8540449b4 feat(sdk-py): add langsmith_tracing param to runs.create/stream/wait (#7431)
## Summary
- Adds a `langsmith_tracing` parameter to `runs.create()`,
`runs.stream()`, and `runs.wait()` on both async and sync SDK clients
- Accepts a `LangSmithTracing` TypedDict with optional `project_name`
and `example_id` fields
- Maps to the server's existing `langsmith_tracer` payload key, enabling
users to route traces to specific LangSmith projects or associate with
dataset examples from the SDK

## Test plan
- [x] Unit tests verify payload serialization (langsmith_tracing →
langsmith_tracer mapping)
- [x] Unit tests verify key is excluded when param not provided
- [x] Unit tests verify partial configs (project_name only) work
- [x] API parity tests pass (async/sync client signatures match)
- [x] Full test suite passes (86 tests)
- [x] Lint + type check pass

Release Notes: Added `langsmith_tracing` parameter to `runs.create()`,
`runs.stream()`, and `runs.wait()` in the Python SDK, allowing users to
route traces to a specific LangSmith project or associate with a dataset
example.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Will Fu-Hinthorn <will@langchain.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:30:53 -07:00
William FHandGitHub 9f5f3fb35e Revert "chore: update configurable metadata" (#7393)
Reverts langchain-ai/langgraph#7367
2026-04-02 11:05:17 -07:00
William FHandGitHub a12e558020 chore: update configurable metadata (#7367) 2026-03-31 13:59:22 -07:00
William FHandGitHub 0f20c3fe04 fix(cli): persist deployment name to .env after prompt (#7323)
## Summary
- When `langgraph deploy` prompts for the deployment name interactively,
persist it as `LANGSMITH_DEPLOYMENT_NAME` in the `.env` file so
subsequent deploys pick it up automatically
- Extracted `_resolve_env_path()` helper from `_parse_env_from_config()`
to share env file path resolution logic
- Skips writing when env vars are configured as an inline dict in
`langgraph.json` (no file to write to)
- **CI fix**: CLI integration tests were using `pip install` but
`setup-uv` with caching enabled, so the post-step cache save failed on a
non-existent directory — switched to `uv pip install`

## Test plan
- [x] All 207 existing unit tests pass
- [ ] Manual: run `langgraph deploy` without `--name`, enter a name at
prompt, verify `.env` now contains `LANGSMITH_DEPLOYMENT_NAME=<name>`
- [ ] Manual: run `langgraph deploy` again, verify the name is picked up
from `.env` without re-prompting
- [x] CI integration test cache fix (broken on main since Feb 2026)
2026-03-29 07:50:57 -07:00
William FHandGitHub 54c92757f2 release(sdk-py): 0.3.12 (#7224)
Release Note: Impllemnets alpha support for server-side SWR w/ the cache
2026-03-18 15:13:58 -07:00
William FHandGitHub f393a5415e release(checkpoint-postgres): 3.0.5 (#7221) 2026-03-18 14:17:57 -07:00
William FHandGitHub 2e0fc1c49d fix: re-use connection (#7220) 2026-03-18 13:31:46 -07:00
William FHandGitHub 8f62374658 release(cli): 0.4.18 (#7186) 2026-03-15 16:53:39 -07:00
William FHandGitHub bec531980d chore: update error message (#7185) 2026-03-15 16:46:15 -07:00
60385e452f fix(checkpoint): don't add the task to the checkpoint batch if it was… (#7168)
Cleaning up CI for #6701 
```md
  I'm trying to help a customer with some issues related to their checkpointing in postgres. They have some timeouts and retries around the langgraph checkpoint queries and I suspect the queue may be filling up with cancelled tasks.
  
  This PR adds some eager checks to not execute an operation if the future was already cancelled.
  This is to prevent the queue executing tasks that might have already timed out, which would otherwise cause more tasks to timeout due to the longer execution delay.
  
  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.**
```

Co-authored-by: Conrad Ludgate <conradludgate@gmail.com>
2026-03-15 12:46:27 -07:00
William FHandGitHub acae5e23b0 chore(sdk-py): cron tz support (#7108) 2026-03-10 17:38:02 -07:00
William FHandGitHub 2638ff715a release(cli): 0.4.15 (#7095) 2026-03-09 18:13:45 -07:00
William FHandGitHub 6a19a5a7b2 chore: Add cache (#7092) 2026-03-09 16:44:36 -07:00
William FHandGitHub a3823395cf chore(cli): pass checkpointer config to CLI (#7003) 2026-03-02 21:12:22 +00:00
William FHandGitHub cdda595e6e release(langgraph) 1.0.10 (#6967) 2026-02-27 13:00:05 -08:00
William FHandGitHub 7895051c96 release(checkpoint): 0.4.1 (#6966)
Release langgraph-checkpoint.
2026-02-27 12:55:41 -08:00
William FHandGitHub 901ab6b3f8 chore: add serde events (#6954) 2026-02-26 17:20:42 -08:00
William FHandGitHub adb953ddd4 chore: update defaults (#6953) 2026-02-26 14:46:02 -08:00
William FHandGitHub 5ddfce1814 chore: support workflow dispatch on ci (#6952) 2026-02-26 14:45:02 -08:00
William FHandGitHub 1f31e0b9b6 chore: add wf dispatch to CI (#6951) 2026-02-26 14:22:43 -08:00
William FHandGitHub 1b37ece92f release: rc2 (#6949) 2026-02-26 13:20:13 -08:00
William FHandGitHub e2e90da5dc chore: improve subclass handling (#6948)
If subclass doesn't support the new parameter, we the current
implementation would create an error.
2026-02-26 13:08:00 -08:00
William FHandGitHub a04ec5d6f0 release: Candidate (#6947) 2026-02-26 12:09:34 -08:00
8087e6a42c docs(sdk-py): update auth docstrings to default-deny pattern (#6933)
## Summary
- Updated all auth docstring examples in `libs/sdk-py` to follow a
**default-closed** pattern
- Every example now first registers a global `@auth.on` handler that
**denies** all requests, then adds resource/action-specific handlers to
selectively **allow** access
- Fixed inconsistencies (e.g., `@auth.on` vs `@my_auth.on`, sync vs
async handlers) and made examples more realistic

## Test plan
- [x] `make format` passes
- [x] `make lint` passes
- [x] Changes are docstring-only — no runtime behavior affected

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:36:59 -08:00
William FHandGitHub 8fbdb14487 release(sdk-py): 0.3.9 (#6932) 2026-02-24 10:37:05 -08:00
b89ef60b91 feat(sdk-py): add extract parameter to threads.search() (#6880)
## Summary
- Adds `extract` parameter to `threads.search()` in both async and sync
clients
- Adds `extracted` field to the `Thread` TypedDict response type
- The `extract` parameter accepts a `dict[str, str]` mapping aliases to
JSONB paths (e.g., `{"last_msg": "values.messages[-1]"}`)
- Depends on server-side support in
https://github.com/langchain-ai/langgraph-api/pull/2609

## Test plan
- [ ] Verify types are correct via lint/format (already passing)
- [ ] Integration test against server with extract feature enabled

Release Notes: Add `extract` parameter to `threads.search()` for
extracting nested values from thread data during search.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:29:59 -08:00
ed293f16d6 fix(cli): update graph config schema to support description field (#6895)
## Summary
- The config processing code in `config.py` already handles graphs
defined as `{"path": "...", "description": "..."}` dicts, but the
`Config` TypedDict and JSON schema only declared `dict[str, str]`
- Added a `GraphDef` TypedDict with `path` and optional `description`
fields
- Updated `Config.graphs` to `dict[str, str | GraphDef]` and regenerated
the JSON schemas
- This makes the schema match the actual runtime behavior and fixes
IDE/schema validation for users who use the dict format

## Test plan
- [x] `make format` passes
- [x] `make lint` passes
- [x] `make test` passes (all 85 tests)
- [x] Schema regeneration produces consistent output

Release Notes: Update `langgraph.json` schema to support `{"path":
"...", "description": "..."}` format for graph definitions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 20:16:45 -08:00
William FHandGitHub b0f14649e0 chore: Update CLI schema (#6858) 2026-02-20 01:11:21 +00:00
William FHandGitHub e2efab8061 release(sdk-py): 0.3.8 (#6873)
Includes some updated docstrings.
2026-02-19 11:10:19 -08:00
9babffa054 feat(sdk-py): add stream_mode, stream_subgraphs, stream_resumable, durability to crons (#6876)
## Summary
- Adds `stream_mode`, `stream_subgraphs`, `stream_resumable`, and
`durability` parameters to cron `create`, `create_for_thread`, and
`update` methods in both async and sync clients
- Adds corresponding fields to the `CronUpdate` TypedDict in `schema.py`
- Adds `checkpoint_during` deprecation warnings to cron create methods
(consistent with the runs client pattern)

These fields were added to the OpenAPI spec in langgraph-api but were
not yet reflected in the Python SDK.

## Test plan
- [x] `make format` passes
- [x] `make lint` passes
- [x] `make test` passes (69/69, including sync/async API parity test)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 11:10:07 -08:00
5ac837d7cd feat(sdk-py): improve store auth type safety and docstrings (#6867)
## Summary
- Add `_StoreActionOn` class with action-specific decorator properties
(`.put`, `.get`, `.search`, `.delete`, `.list_namespaces`) to
`_StoreOn`, enabling `@auth.on.store.put` etc. which was documented but
not implemented
- Update docstring examples to show namespace-rewriting pattern as the
canonical store auth approach
- Fix `AuthContext.action` docstring: add missing `search` and `delete`
store actions
- Fix typo in `StoreSearch.query` docstring
- Add auth-handler-aware docstrings to all store TypedDicts

## Test plan
- [x] `make format && make lint` passes in `libs/sdk-py`
- [] Verify `@auth.on.store.put` decorator works at runtime

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 07:16:26 -08:00
William FHandGitHub 095da17833 chore: state_updated_at sort by (#6857) 2026-02-18 10:41:23 -08:00
William FHandGitHub 21a6f41e0a chore: add testpypi index (#6853) 2026-02-17 10:24:39 -08:00
William FHandGitHub 9b9de5bd16 chore: conformance testing (#6842)
Add some conformance tests for checkpointer implementations. Includes
additona methods that will be useful if you want to integarte in the
agent server.
2026-02-17 09:49:22 -08:00
df94475d3a fix(ci): skip server startup tests when LANGSMITH_API_KEY unavailable (#6844)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 06:12:35 -08:00
William FHandGitHub 7216504ce2 fix: dependabot (#6806) 2026-02-14 11:44:02 -08:00
William FHandGitHub fe4daa1c7c release(sdk-py): 0.3.6 (#6805) 2026-02-14 11:41:27 -08:00
William FHandGitHub eac6abb8ee chore: update to add prune method (#6804) 2026-02-14 10:02:07 -08:00
9f0ae94f27 chore: Re-organize client files. (#6787)
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.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:22:59 -05:00
f5e56e200d feat(cli): add keep_latest prune strategy to ThreadTTLConfig (#6784)
## Summary
- Add `"keep_latest"` to `ThreadTTLConfig.strategy` to match
langgraph-api support for pruning old checkpoints while retaining the
thread and its latest state
- Add `sweep_limit` to `ThreadTTLConfig` where the API actually reads it
(was previously a no-op on `CheckpointerConfig`)
- Regenerate `schema.json` / `schema.v0.json`

## Test plan
- [x] `make format && make lint` passes
- [x] `make test` passes (85/85)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:00:48 -08:00
William FHandGitHub f9870bc9ae chore: Drop support for bullseye builds (#6779)
It's EOL for debian.
2026-02-10 15:11:24 -08:00
William FHandGitHub a734f5e6ce chore: server runtime type (#6774)
Main jtbd here:
a) clarify who/how a graph is being accessed and make the factory aware
of the `context` where relevant (and make it obvious when it is
available)
b) make it more clear when you can bypass / defer resources with
expensive lifespans (like MCp connections)
c) make auth access more type-safe.

Gives us room to add other information, like:
- langsmith distributed tracing information



---- old
Can start doing things like this:

```
def my_graph(runtime: ServerRuntime):
     if runtime.ensure_user().permissions not in ("foo"):
         raise ValueError("bar")
```
etc.

Points of expected confusion:
- You won't have a stream_writer in this context.
- This won't be an accessible object within the graph, only the graph
factory.


For maintainers, related draft PR int he server
https://github.com/langchain-ai/langgraph/pull/6774
2026-02-10 08:53:52 -08:00
William FHandGitHub a7a27dd43a release(langgraph): 1.0.8 (#6757) 2026-02-06 07:27:08 -05:00
William FHandGitHub 50238be239 chore: shallow copy futures (#6755) 2026-02-05 19:14:42 -08:00
William FHandGitHub 86b65beb8f chore: Update ThreadTTLConfig (#6730)
Sync with underlying implementation.
2026-02-03 10:52:33 -08:00
193e128c20 chore: Omit lock when using connection pool (#6734)
Co-authored-by: Conrad Ludgate <conradludgate@gmail.com>
2026-01-31 00:30:34 +00:00
William FHandGitHub 2c6f99cbf0 release(cli): 0.4.12 (#6716)
Release Notes: Increase upper bound of `langgraph-ap` to `<0.8`

Closes https://github.com/langchain-ai/langgraph/issues/6706
2026-01-23 05:31:50 -08:00
William FHandGitHub 30355a7a5d fix: aiosqlite's breaking change (#6699)
`aiosqlite` changed it's Connection type to no longer subclass
`threading.Thread`. This removed the is_alive method, which is called
proactively in setup().

This PR handles this in a backwards compat way.
2026-01-18 16:35:50 -08:00
William FHandGitHub e820097701 chore: Better error messages (#6681) 2026-01-12 16:29:04 -08:00
William FHandGitHub 05e4efe712 release(cli): relax api bounds (#6606) 2025-12-17 06:10:37 -08:00
William FHandGitHub c80d93c78a fix(cli): Escape variable substitution in compose codegen (#6594) 2025-12-15 14:51:03 -08:00
William FHandGitHub 4d01e69b82 release(checkpoint-postgres): 3.0.1 (#6568) 2025-12-09 23:05:49 +00:00
William FHandGitHub e86b5f4da2 chore: pgqs (#6567)
Add more argument sanitization
2025-12-09 14:51:29 -08:00
William FHandGitHub 6c6978918e chore(cli): Pass through webhook configuration in dev server (#6557) 2025-12-09 07:05:15 -08:00
William FHandGitHub 2f1a16006a release(cli): 0.4.8 (#6556)
For webhook configuration support
2025-12-09 13:25:02 +00:00
William FHandGitHub 269d08f5d3 feat(cli): webhook configuration (#6555) 2025-12-09 13:17:22 +00:00
William FHandGitHub f211fadc2b release(sdk-py): Configure loopback client (#6536)
Will defer defaulting to deferred registration until a later date.
2025-12-05 11:56:40 -08:00
William FHandGitHub 024468c5dd chore: Bump lockfile (#6537) 2025-12-05 11:16:19 -08:00
William FHandGitHub 76203e2c20 chore: Sync langgraph.json schema (#6530) 2025-12-02 19:52:06 +00:00
b6cc022861 fix(checkpoint): InMemorySaver context managers should return self in… (#6529)
h/t to @lexi-k for openening. merged here to check/fix CI

Co-authored-by: lexi-k <69981673+lexi-k@users.noreply.github.com>
2025-12-02 11:47:41 -08:00
William FHandGitHub 55ed7d4b49 feat: Include pagination in assistants search response (#6526) 2025-12-01 20:18:26 -08:00
William FHandGitHub 2b78bf3bad fix: docstring for serializer protocol (#6525) 2025-12-01 18:14:12 +00:00
William FHandGitHub b945b1f21e release(langgraph): 1.0.4 (#6502)
This patch release includes a couple of small fixes and improvements,
such as:
- Include interrupt information in the values stream mode (no longer
rely solely on the updates stream mode):
https://github.com/langchain-ai/langgraph/pull/6475
- Omit thread_id from configurable to allow using context for stateful
runs via RemoteGraph:
https://github.com/langchain-ai/langgraph/pull/6497
2025-11-25 20:27:49 +00:00
William FHandGitHub 4cb108ccd9 release(sdk-py): 0.2.11 (#6501) 2025-11-25 19:17:40 +00:00
William FHandGitHub f8c1a323cc chore(sdk-py): Improve type-hinting of inputs (#6480) 2025-11-24 18:29:03 -08:00
William FHandGitHub b7e329cf0a chore: pop thread ID from configurable fields in remote graph (#6497)
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)
2025-11-24 16:09:08 -08:00
William FHandGitHub ed07d4a5d4 chore(sdk-py): Add more type checking. (#6479) 2025-11-20 17:40:23 -08:00
William FHandGitHub df8becd5cf refactor: separate prepare_push_* functions (#6450)
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
2025-11-14 16:13:03 -08:00
William FHandGitHub 092c9ecde6 chore: update ormsgpack minbound and add OPT_REPLACE_SURROGATES (#6395)
This lets the default `msgpack` serialization mode handle more cases
where user data contains invalid unicode.
2025-11-04 13:51:34 -08:00
William FHandGitHub 8336686e89 release(cli): 0.4.7 expand api bounds (#6390)
Fixes #6380
2025-11-03 23:47:05 +00:00
William FHandGitHub a10a66cbd1 chore: Update cli config schema (#6372) 2025-11-01 09:50:46 -07:00
William FHandGitHub fca3e4513c release: Checkpointers 3.0 (#6313)
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
2025-10-20 11:31:55 -07:00
c5744f583b chore: Restrict "json" type deserialization (#6269)
- Rm untyped loads/dumps
- Restrict to an allow list

---------

Co-authored-by: Sydney Runkle <sydneymarierunkle@gmail.com>
2025-10-20 10:18:36 -07:00
abb96c0e2f chore(cli): re-word schema arguments (#6243)
Clean up config docstrings

---------

Co-authored-by: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com>
2025-10-16 12:28:09 +00:00
cedecd8ed6 chore(docs): Update OpenAPI spec from LangGraph API v0.4.42 (#6287)
This PR updates the OpenAPI specification with changes detected from the
LangGraph API server.

**Changes detected as of LangGraph API version 0.4.42**

This update was automatically generated by the sync workflow in the
langgraph-api repository.

Co-authored-by: hinthornw <hinthornw@users.noreply.github.com>
2025-10-16 07:15:51 -04:00
William FHandGitHub a3ee814539 chore(langgraph): Log when no values event is emitted from RemoteGraph (#6140) 2025-09-12 14:05:07 -07:00
William FHandGitHub b65140a892 chore(cli): Add config schema (#6142)
So you can IDE LSP support / autocompletion
2025-09-12 12:16:07 -07:00
4af07942ed chore(ci): Run CI int tests in parallel (#5976)
Co-authored-by: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com>
2025-09-09 19:01:12 +00:00
William FHandGitHub 8f6ad0b25a chore(sdk-py): Cleanup docstring indentation (#6087) 2025-09-05 22:56:03 +00:00
William FHandGitHub f761116de7 chore(sdk-py): Clean up docstring for get_client (#6084)
Main thing here is to call out the ASGITransport behavior
2025-09-05 13:43:31 -07:00
William FHandGitHub 25ba4c3bda feat(sdk-py): Specify ttl on thread creation and update (#6075) 2025-09-03 18:48:57 -07:00
dfc1c59ebf chore(docs): Update OpenAPI spec from LangGraph API v0.4.11 (#6074)
This PR updates the OpenAPI specification with changes detected from the
LangGraph API server.

**Changes detected as of LangGraph API version 0.4.11**

This update was automatically generated by the sync workflow in the
langgraph-api repository.

Co-authored-by: hinthornw <hinthornw@users.noreply.github.com>
2025-09-03 18:37:39 -07:00