-
release(langgraph): 1.1 (#7102)
发布于
2026-03-10 12:41:30 +00:00 | 438 次提交 在此版本后已推送到 mainexciting!
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 tostream(),astream(),invoke(), and
ainvoke().What's changing
v1 (default, unchanged):
stream()yields bare tuples like
(stream_mode, data)or justdata.invoke()returns a plaindict.
Interrupts are mixed into the output dict under"__interrupt__".v2 (opt-in):
stream()yields strongly-typedStreamPartdicts
withtype,ns,data, and (for values)interruptsfields.
invoke()returns aGraphOutputobject with.valueand
.interruptsattributes. When your state schema is a Pydantic model or
dataclass, outputs are automatically coerced to the correct type.invoke()/ainvoke()withversion="v2"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 occurredWith a non-
"values"stream mode,invoke(..., stream_mode="updates", version="v2")returnslist[StreamPart]instead oflist[tuple].stream()/astream()withversion="v2"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"] # DebugPayloadEach stream mode has its own
TypedDict—ValuesStreamPart,
UpdatesStreamPart,MessagesStreamPart,CustomStreamPart,
CheckpointStreamPart,TasksStreamPart,DebugStreamPart— all
importable fromlanggraph.types. The union typeStreamPartis a
discriminated union onpart["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: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,
GraphOutputsupports old-style best-effort
access to graph values and interrupts. Dict-style access
(result["key"],"key" in result,result["__interrupt__"]) still
works and delegates toresult.value/result.interruptsunder the
hood. However, this is deprecated and emits a
LangGraphDeprecatedSinceV11warning. It will be removed in v3.0 —
migrate toresult.valueandresult.interruptsat your convenience.
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.interruptsMigration Guide
- No action required —
version="v1"remains the default. All
existing code continues to work. - Adopt v2 incrementally — Add
version="v2"to individual
invoke()/stream()calls to get typed outputs. - Use typed imports — Import
GraphOutput,StreamPart, and
individual part types fromlanggraph.typesfor type-safe code.
下载附件
- Default is still