mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-30 03:39:38 +02:00
exciting!
relnotes preview:
# LangGraph 1.1.0 Release Notes
## Type-Safe Streaming & Invoke
LangGraph 1.1 introduces `version="v2"` — a new opt-in streaming format
that brings full type safety to `stream()`, `astream()`, `invoke()`, and
`ainvoke()`.
### What's changing
**v1 (default, unchanged):** `stream()` yields bare tuples like
`(stream_mode, data)` or just `data`. `invoke()` returns a plain `dict`.
Interrupts are mixed into the output dict under `"__interrupt__"`.
**v2 (opt-in):** `stream()` yields strongly-typed `StreamPart` dicts
with `type`, `ns`, `data`, and (for values) `interrupts` fields.
`invoke()` returns a `GraphOutput` object with `.value` and
`.interrupts` attributes. When your state schema is a Pydantic model or
dataclass, outputs are automatically coerced to the correct type.
### `invoke()` / `ainvoke()` with `version="v2"`
```python
from langgraph.types import GraphOutput
result = graph.invoke({"input": "hello"}, version="v2")
# result is a GraphOutput, not a dict
assert isinstance(result, GraphOutput)
result.value # your output — dict, Pydantic model, or dataclass
result.interrupts # tuple[Interrupt, ...], empty if none occurred
```
With a non-`"values"` stream mode, `invoke(..., stream_mode="updates",
version="v2")` returns `list[StreamPart]` instead of `list[tuple]`.
### `stream()` / `astream()` with `version="v2"`
```python
for part in graph.stream({"input": "hello"}, version="v2"):
if part["type"] == "values":
part["data"] # OutputT — full state
part["interrupts"] # tuple[Interrupt, ...]
elif part["type"] == "updates":
part["data"] # dict[str, Any]
elif part["type"] == "messages":
part["data"] # tuple[BaseMessage, dict]
elif part["type"] == "custom":
part["data"] # Any
elif part["type"] == "tasks":
part["data"] # TaskPayload | TaskResultPayload
elif part["type"] == "debug":
part["data"] # DebugPayload
```
Each stream mode has its own `TypedDict` — `ValuesStreamPart`,
`UpdatesStreamPart`, `MessagesStreamPart`, `CustomStreamPart`,
`CheckpointStreamPart`, `TasksStreamPart`, `DebugStreamPart` — all
importable from `langgraph.types`. The union type `StreamPart` is a
discriminated union on `part["type"]`, enabling full type narrowing in
editors and type checkers.
### Pydantic & dataclass output coercion
When your graph's state schema is a Pydantic model or dataclass,
`version="v2"` automatically coerces outputs to the declared type:
```python
from pydantic import BaseModel
class MyState(BaseModel):
answer: str
count: int
graph = StateGraph(MyState)
# ... build graph ...
compiled = graph.compile()
result = compiled.invoke({"answer": "", "count": 0}, version="v2")
assert isinstance(result.value, MyState) # not a dict!
```
### Backward compatibility
- **Default is still `version="v1"`** — existing code works without
changes.
- To make migration easier, `GraphOutput` supports old-style best-effort
access to graph values and interrupts. Dict-style access
(`result["key"]`, `"key" in result`, `result["__interrupt__"]`) still
works and delegates to `result.value` / `result.interrupts` under the
hood. However, this is **deprecated** and emits a
`LangGraphDeprecatedSinceV11` warning. It will be removed in v3.0 —
migrate to `result.value` and `result.interrupts` at your convenience.
```python
result = graph.invoke({"input": "hello"}, version="v2")
# Old style — still works, but deprecated
result["input"] # delegates to result.value["input"]
result["__interrupt__"] # delegates to result.interrupts
"input" in result # delegates to "input" in result.value
# New style — preferred
result.value["input"]
result.interrupts
```
## Migration Guide
1. **No action required** — `version="v1"` remains the default. All
existing code continues to work.
2. **Adopt v2 incrementally** — Add `version="v2"` to individual
`invoke()`/`stream()` calls to get typed outputs.
3. **Use typed imports** — Import `GraphOutput`, `StreamPart`, and
individual part types from `langgraph.types` for type-safe code.
129 lines
3.9 KiB
TOML
129 lines
3.9 KiB
TOML
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[project]
|
|
name = "langgraph"
|
|
version = "1.1.0"
|
|
description = "Building stateful, multi-actor applications with LLMs"
|
|
authors = []
|
|
requires-python = ">=3.10"
|
|
readme = "README.md"
|
|
license = "MIT"
|
|
license-files = ['LICENSE']
|
|
classifiers = [
|
|
'Development Status :: 5 - Production/Stable',
|
|
'Programming Language :: Python',
|
|
'Programming Language :: Python :: Implementation :: CPython',
|
|
'Programming Language :: Python :: Implementation :: PyPy',
|
|
'Programming Language :: Python :: 3',
|
|
'Programming Language :: Python :: 3 :: Only',
|
|
'Programming Language :: Python :: 3.10',
|
|
'Programming Language :: Python :: 3.11',
|
|
'Programming Language :: Python :: 3.12',
|
|
'Programming Language :: Python :: 3.13',
|
|
]
|
|
dependencies = [
|
|
"langchain-core>=0.1",
|
|
"langgraph-checkpoint>=2.1.0,<5.0.0",
|
|
"langgraph-sdk>=0.3.0,<0.4.0",
|
|
"langgraph-prebuilt>=1.0.8,<1.1.0",
|
|
"xxhash>=3.5.0",
|
|
"pydantic>=2.7.4",
|
|
]
|
|
|
|
|
|
[project.urls]
|
|
Homepage = "https://docs.langchain.com/oss/python/langgraph/overview"
|
|
Documentation = "https://reference.langchain.com/python/langgraph/"
|
|
Source = "https://github.com/langchain-ai/langgraph/tree/main/libs/langgraph"
|
|
Changelog = "https://github.com/langchain-ai/langgraph/releases"
|
|
Twitter = "https://x.com/LangChain"
|
|
Slack = "https://www.langchain.com/join-community"
|
|
Reddit = "https://www.reddit.com/r/LangChain/"
|
|
|
|
[dependency-groups]
|
|
test = [
|
|
"pytest",
|
|
"pytest-cov",
|
|
"pytest-dotenv",
|
|
"pytest-mock",
|
|
"syrupy",
|
|
"httpx",
|
|
"pytest-watcher",
|
|
"pytest-xdist[psutil]",
|
|
"pytest-repeat",
|
|
"langchain-core>=1.0.0",
|
|
"langgraph-prebuilt",
|
|
"langgraph-checkpoint",
|
|
"langgraph-checkpoint-sqlite",
|
|
"langgraph-checkpoint-postgres",
|
|
"langgraph-sdk",
|
|
"psycopg[binary]",
|
|
"uvloop==0.22.1",
|
|
"pyperf",
|
|
"py-spy",
|
|
"pycryptodome",
|
|
"langgraph-cli; python_version < '3.14'",
|
|
"langgraph-cli[inmem]; python_version < '3.14'",
|
|
"redis",
|
|
]
|
|
lint = [
|
|
"mypy",
|
|
"ruff",
|
|
"types-requests",
|
|
]
|
|
dev = [
|
|
{include-group = "test"},
|
|
{include-group = "lint"},
|
|
"jupyter",
|
|
]
|
|
|
|
|
|
[tool.uv.sources]
|
|
langgraph-prebuilt = { path = "../prebuilt", editable = true }
|
|
langgraph-checkpoint = { path = "../checkpoint", editable = true }
|
|
langgraph-checkpoint-sqlite = { path = "../checkpoint-sqlite", editable = true }
|
|
langgraph-checkpoint-postgres = { path = "../checkpoint-postgres", editable = true }
|
|
langgraph-sdk = { path = "../sdk-py", editable = true }
|
|
langgraph-cli = { path = "../cli", editable = true }
|
|
|
|
[tool.ruff]
|
|
lint.select = [ "E", "F", "I", "TID251", "UP" ]
|
|
lint.ignore = [ "E501" ]
|
|
line-length = 88
|
|
indent-width = 4
|
|
extend-include = ["*.ipynb"]
|
|
target-version = "py310"
|
|
|
|
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
|
"typing.TypedDict".msg = "Use typing_extensions.TypedDict instead."
|
|
|
|
[tool.mypy]
|
|
# https://mypy.readthedocs.io/en/stable/config_file.html
|
|
disallow_untyped_defs = "True"
|
|
explicit_package_bases = "True"
|
|
warn_no_return = "False"
|
|
warn_unused_ignores = "True"
|
|
warn_redundant_casts = "True"
|
|
allow_redefinition = "True"
|
|
disable_error_code = "typeddict-item, return-value, override, has-type"
|
|
|
|
[tool.coverage.run]
|
|
omit = ["tests/*"]
|
|
|
|
[tool.pytest-watcher]
|
|
now = true
|
|
delay = 0.1
|
|
patterns = ["*.py"]
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
packages = ["langgraph"]
|
|
|
|
[tool.pytest.ini_options]
|
|
addopts = "--full-trace --strict-markers --strict-config --durations=5 --snapshot-warn-unused"
|
|
|
|
[tool.codespell]
|
|
# Ignore words specific to the LangGraph library code
|
|
ignore-words-list = "infor,thead,stdio,nd,jupyter,lets,lite,uis,deque,langgraph,langchain,pydantic,typing,async,await,coroutine,iterable,iterables,serializable,deserializable,checkpointer,checkpointing,stateful,statefulness,prebuilt,prebuilt,supervisor,supervisory,swarm,swarming,multiactor,multiactors,subgraph,subgraphs,workflow,workflows,streaming,streamable,streamed,streamer,streamers,streaming,streamable,streamed,streamer,streamers"
|