mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-11 12:17:53 +02:00
langgraph[change]: solidify public/private differentiations (#5252)
* public interfaces for channels * public interfaces for func * public interfaces for graph * pi for managed * first pass public interface for top level modules * first pass at private for utils -> _internal * private interface for pregel * scratchpad/stream protocol move * docs update * backwards compat for runnable * deprecation warning for send and interrupt * deprecation for pregel import
This commit is contained in:
@@ -282,8 +282,8 @@
|
||||
"from langgraph.graph import StateGraph\n",
|
||||
"\n",
|
||||
"from langchain_core.runnables import RunnableConfig\n",
|
||||
"from langgraph.constants import Send\n",
|
||||
"from langgraph.checkpoint.memory import MemorySaver\n",
|
||||
"from langgraph.types import Send\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def update_candidates(\n",
|
||||
|
||||
@@ -19,7 +19,7 @@ dependencies = [
|
||||
[project.optional-dependencies]
|
||||
inmem = [
|
||||
"langgraph-api>=0.2.67 ; python_version >= '3.11'",
|
||||
"langgraph-runtime-inmem>=0.3.0 ; python_version >= '3.11'",
|
||||
"langgraph-runtime-inmem>=0.3.4 ; python_version >= '3.11'",
|
||||
"python-dotenv>=0.8.0",
|
||||
]
|
||||
|
||||
|
||||
Generated
+4
-4
@@ -531,7 +531,7 @@ dev = [
|
||||
requires-dist = [
|
||||
{ name = "click", specifier = ">=8.1.7" },
|
||||
{ name = "langgraph-api", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.2.67" },
|
||||
{ name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.3.0" },
|
||||
{ name = "langgraph-runtime-inmem", marker = "python_full_version >= '3.11' and extra == 'inmem'", specifier = ">=0.3.4" },
|
||||
{ name = "langgraph-sdk", marker = "python_full_version >= '3.11'", specifier = ">=0.1.0" },
|
||||
{ name = "python-dotenv", marker = "extra == 'inmem'", specifier = ">=0.8.0" },
|
||||
]
|
||||
@@ -564,7 +564,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-runtime-inmem"
|
||||
version = "0.3.3"
|
||||
version = "0.3.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "blockbuster", marker = "python_full_version >= '3.11'" },
|
||||
@@ -574,9 +574,9 @@ dependencies = [
|
||||
{ name = "starlette", marker = "python_full_version >= '3.11'" },
|
||||
{ name = "structlog", marker = "python_full_version >= '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/c6/c6c515df38179517a187b11cc9506caac9bc7c25ab0adc1e21b463e338fd/langgraph_runtime_inmem-0.3.3.tar.gz", hash = "sha256:1b5bc8b05989f48c64c826d826e576a6e77f42349eca3382f38f8ed1d1f026e4", size = 77443, upload-time = "2025-06-24T19:50:36.235Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c1/17/7ff669ff44a53ab342903c2996fff75a77494af9fe56abcfbca64fe2342b/langgraph_runtime_inmem-0.3.4.tar.gz", hash = "sha256:eda7828f3ea07126e5265024b74a3fa9bf611633ad83ba3296ab9f51d89b7c0c", size = 77424, upload-time = "2025-07-01T14:45:07.465Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/36/87/1b47cf8a9a9ab8e6460203921e05f59e1e95dc0636e64a7429cd0e579a79/langgraph_runtime_inmem-0.3.3-py3-none-any.whl", hash = "sha256:ed485d520870a96a4a2e81188f2dbf993e7b96c5c65804bcdfdcb39df71be3ce", size = 29146, upload-time = "2025-06-24T19:50:35.083Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/0e/39c13ca7229a9425a0e5744a1d3817f80d38dd5ca7703494fb9cf836ba45/langgraph_runtime_inmem-0.3.4-py3-none-any.whl", hash = "sha256:dcb9ac68ac90b3fb1ddaf666d14a367ab70e69d5bb5589b77a72c318e29104ae", size = 29139, upload-time = "2025-07-01T14:45:06.472Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -3,8 +3,9 @@ from typing import Annotated
|
||||
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langgraph.constants import END, START, Send
|
||||
from langgraph.constants import END, START
|
||||
from langgraph.graph.state import StateGraph
|
||||
from langgraph.types import Send
|
||||
|
||||
|
||||
def fanout_to_subgraph() -> StateGraph:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Create a sequential no-op graph consisting of a few hundred nodes."""
|
||||
|
||||
from langgraph._internal._runnable import RunnableCallable
|
||||
from langgraph.graph import MessagesState, StateGraph
|
||||
from langgraph.utils.runnable import RunnableCallable
|
||||
|
||||
|
||||
def create_sequential(number_nodes: int) -> StateGraph:
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
"""Internal modules for LangGraph.
|
||||
|
||||
This module is not part of the public API, and thus stability is not guaranteed.
|
||||
"""
|
||||
-1
@@ -19,7 +19,6 @@ from langchain_core.runnables.config import (
|
||||
)
|
||||
|
||||
from langgraph.checkpoint.base import CheckpointMetadata
|
||||
from langgraph.config import get_config, get_store, get_stream_writer # noqa
|
||||
from langgraph.constants import (
|
||||
CONF,
|
||||
CONFIG_KEY_CHECKPOINT_ID,
|
||||
@@ -128,6 +128,3 @@ class SyncQueue:
|
||||
return len(self._queue)
|
||||
|
||||
__class_getitem__ = classmethod(types.GenericAlias)
|
||||
|
||||
|
||||
__all__ = ["AsyncQueue", "SyncQueue"]
|
||||
@@ -0,0 +1,29 @@
|
||||
def default_retry_on(exc: Exception) -> bool:
|
||||
import httpx
|
||||
import requests
|
||||
|
||||
if isinstance(exc, ConnectionError):
|
||||
return True
|
||||
if isinstance(exc, httpx.HTTPStatusError):
|
||||
return 500 <= exc.response.status_code < 600
|
||||
if isinstance(exc, requests.HTTPError):
|
||||
return 500 <= exc.response.status_code < 600 if exc.response else True
|
||||
if isinstance(
|
||||
exc,
|
||||
(
|
||||
ValueError,
|
||||
TypeError,
|
||||
ArithmeticError,
|
||||
ImportError,
|
||||
LookupError,
|
||||
NameError,
|
||||
SyntaxError,
|
||||
RuntimeError,
|
||||
ReferenceError,
|
||||
StopIteration,
|
||||
StopAsyncIteration,
|
||||
OSError,
|
||||
),
|
||||
):
|
||||
return False
|
||||
return True
|
||||
+6
-6
@@ -42,6 +42,12 @@ from langchain_core.runnables.utils import Input, Output
|
||||
from langchain_core.tracers.langchain import LangChainTracer
|
||||
from typing_extensions import TypeGuard
|
||||
|
||||
from langgraph._internal._config import (
|
||||
ensure_config,
|
||||
get_async_callback_manager_for_config,
|
||||
get_callback_manager_for_config,
|
||||
patch_config,
|
||||
)
|
||||
from langgraph.constants import (
|
||||
CONF,
|
||||
CONFIG_KEY_PREVIOUS,
|
||||
@@ -50,12 +56,6 @@ from langgraph.constants import (
|
||||
)
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import StreamWriter
|
||||
from langgraph.utils.config import (
|
||||
ensure_config,
|
||||
get_async_callback_manager_for_config,
|
||||
get_callback_manager_for_config,
|
||||
patch_config,
|
||||
)
|
||||
|
||||
try:
|
||||
from langchain_core.tracers._streaming import _StreamingCallbackHandler
|
||||
@@ -1,15 +1,27 @@
|
||||
from langgraph.channels.any_value import AnyValue
|
||||
from langgraph.channels.base import BaseChannel
|
||||
from langgraph.channels.binop import BinaryOperatorAggregate
|
||||
from langgraph.channels.ephemeral_value import EphemeralValue
|
||||
from langgraph.channels.last_value import LastValue
|
||||
from langgraph.channels.last_value import LastValue, LastValueAfterFinish
|
||||
from langgraph.channels.named_barrier_value import (
|
||||
NamedBarrierValue,
|
||||
NamedBarrierValueAfterFinish,
|
||||
)
|
||||
from langgraph.channels.topic import Topic
|
||||
from langgraph.channels.untracked_value import UntrackedValue
|
||||
|
||||
__all__ = [
|
||||
__all__ = (
|
||||
# base
|
||||
"BaseChannel",
|
||||
# value types
|
||||
"AnyValue",
|
||||
"LastValue",
|
||||
"Topic",
|
||||
"BinaryOperatorAggregate",
|
||||
"LastValueAfterFinish",
|
||||
"UntrackedValue",
|
||||
"EphemeralValue",
|
||||
"AnyValue",
|
||||
]
|
||||
"BinaryOperatorAggregate",
|
||||
"NamedBarrierValue",
|
||||
"NamedBarrierValueAfterFinish",
|
||||
# topics
|
||||
"Topic",
|
||||
)
|
||||
|
||||
@@ -7,6 +7,8 @@ from langgraph.channels.base import BaseChannel, Value
|
||||
from langgraph.constants import MISSING
|
||||
from langgraph.errors import EmptyChannelError
|
||||
|
||||
__all__ = ("AnyValue",)
|
||||
|
||||
|
||||
class AnyValue(Generic[Value], BaseChannel[Value, Value, Value]):
|
||||
"""Stores the last value received, assumes that if multiple values are
|
||||
|
||||
@@ -5,12 +5,14 @@ from typing import Any, Generic, TypeVar
|
||||
from typing_extensions import Self
|
||||
|
||||
from langgraph.constants import MISSING
|
||||
from langgraph.errors import EmptyChannelError, InvalidUpdateError
|
||||
from langgraph.errors import EmptyChannelError
|
||||
|
||||
Value = TypeVar("Value")
|
||||
Update = TypeVar("Update")
|
||||
C = TypeVar("C")
|
||||
|
||||
__all__ = ("BaseChannel",)
|
||||
|
||||
|
||||
class BaseChannel(Generic[Value, Update, C], ABC):
|
||||
"""Base class for all channels."""
|
||||
@@ -99,10 +101,3 @@ class BaseChannel(Generic[Value, Update, C], ABC):
|
||||
Returns True if the channel was updated, False otherwise.
|
||||
"""
|
||||
return False
|
||||
|
||||
|
||||
__all__ = [
|
||||
"BaseChannel",
|
||||
"EmptyChannelError",
|
||||
"InvalidUpdateError",
|
||||
]
|
||||
|
||||
@@ -8,6 +8,8 @@ from langgraph.channels.base import BaseChannel, Value
|
||||
from langgraph.constants import MISSING
|
||||
from langgraph.errors import EmptyChannelError
|
||||
|
||||
__all__ = ("BinaryOperatorAggregate",)
|
||||
|
||||
|
||||
# Adapted from typing_extensions
|
||||
def _strip_extras(t): # type: ignore[no-untyped-def]
|
||||
|
||||
@@ -7,6 +7,8 @@ from langgraph.channels.base import BaseChannel, Value
|
||||
from langgraph.constants import MISSING
|
||||
from langgraph.errors import EmptyChannelError, InvalidUpdateError
|
||||
|
||||
__all__ = ("EphemeralValue",)
|
||||
|
||||
|
||||
class EphemeralValue(Generic[Value], BaseChannel[Value, Value, Value]):
|
||||
"""Stores the value received in the step immediately preceding, clears after."""
|
||||
|
||||
@@ -12,6 +12,8 @@ from langgraph.errors import (
|
||||
create_error_message,
|
||||
)
|
||||
|
||||
__all__ = ("LastValue", "LastValueAfterFinish")
|
||||
|
||||
|
||||
class LastValue(Generic[Value], BaseChannel[Value, Value, Value]):
|
||||
"""Stores the last value received, can receive at most one value per step."""
|
||||
|
||||
@@ -7,6 +7,8 @@ from langgraph.channels.base import BaseChannel, Value
|
||||
from langgraph.constants import MISSING
|
||||
from langgraph.errors import EmptyChannelError, InvalidUpdateError
|
||||
|
||||
__all__ = ("NamedBarrierValue", "NamedBarrierValueAfterFinish")
|
||||
|
||||
|
||||
class NamedBarrierValue(Generic[Value], BaseChannel[Value, Value, set[Value]]):
|
||||
"""A channel that waits until all named values are received before making the value available."""
|
||||
|
||||
@@ -9,8 +9,10 @@ from langgraph.channels.base import BaseChannel, Value
|
||||
from langgraph.constants import MISSING
|
||||
from langgraph.errors import EmptyChannelError
|
||||
|
||||
__all__ = ("Topic",)
|
||||
|
||||
def flatten(values: Sequence[Value | list[Value]]) -> Iterator[Value]:
|
||||
|
||||
def _flatten(values: Sequence[Value | list[Value]]) -> Iterator[Value]:
|
||||
for value in values:
|
||||
if isinstance(value, list):
|
||||
yield from value
|
||||
@@ -77,7 +79,7 @@ class Topic(
|
||||
if not self.accumulate:
|
||||
updated = bool(self.values)
|
||||
self.values = list[Value]()
|
||||
if flat_values := tuple(flatten(values)):
|
||||
if flat_values := tuple(_flatten(values)):
|
||||
updated = True
|
||||
self.values.extend(flat_values)
|
||||
return updated
|
||||
|
||||
@@ -7,6 +7,8 @@ from langgraph.channels.base import BaseChannel, Value
|
||||
from langgraph.constants import MISSING
|
||||
from langgraph.errors import EmptyChannelError, InvalidUpdateError
|
||||
|
||||
__all__ = ("UntrackedValue",)
|
||||
|
||||
|
||||
class UntrackedValue(Generic[Value], BaseChannel[Value, Value, Value]):
|
||||
"""Stores the last value received, never checkpointed."""
|
||||
|
||||
@@ -1,23 +1,43 @@
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
from types import MappingProxyType
|
||||
from typing import Any, Literal, cast
|
||||
from warnings import warn
|
||||
|
||||
from langgraph.types import Interrupt, Send # noqa: F401
|
||||
from langgraph.warnings import LangGraphDeprecatedSinceV10
|
||||
|
||||
# Interrupt, Send re-exported for backwards compatibility
|
||||
__all__ = (
|
||||
"TAG_NOSTREAM",
|
||||
"TAG_HIDDEN",
|
||||
"START",
|
||||
"END",
|
||||
"SELF",
|
||||
"PREVIOUS",
|
||||
)
|
||||
|
||||
|
||||
def __getattr__(name: str) -> Any:
|
||||
if name in ["Send", "Interrupt"]:
|
||||
warn(
|
||||
f"Importing {name} from langgraph.constants is deprecated. "
|
||||
f"Please use 'from langgraph.types import {name}' instead.",
|
||||
LangGraphDeprecatedSinceV10,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
module = import_module("langgraph.types")
|
||||
return getattr(module, name)
|
||||
|
||||
raise AttributeError(f"module has no attribute '{name}'")
|
||||
|
||||
|
||||
# --- Empty read-only containers ---
|
||||
EMPTY_MAP: Mapping[str, Any] = MappingProxyType({})
|
||||
EMPTY_SEQ: tuple[str, ...] = tuple()
|
||||
MISSING = object()
|
||||
|
||||
# --- Public constants ---
|
||||
TAG_NOSTREAM = sys.intern("nostream")
|
||||
"""Tag to disable streaming for a chat model."""
|
||||
TAG_NOSTREAM_ALT = sys.intern("langsmith:nostream")
|
||||
"""Tag to disable streaming for a chat model. (Deprecated in favour of "nostream")"""
|
||||
TAG_HIDDEN = sys.intern("langsmith:hidden")
|
||||
"""Tag to hide a node/edge from certain tracing/streaming environments."""
|
||||
START = sys.intern("__start__")
|
||||
|
||||
@@ -2,10 +2,22 @@ from collections.abc import Sequence
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
# EmptyChannelError is re-exported from langgraph.channels.base
|
||||
from langgraph.checkpoint.base import EmptyChannelError # noqa: F401
|
||||
from langgraph.types import Command, Interrupt
|
||||
|
||||
# EmptyChannelError re-exported for backwards compatibility
|
||||
__all__ = (
|
||||
"EmptyChannelError",
|
||||
"ErrorCode",
|
||||
"GraphRecursionError",
|
||||
"InvalidUpdateError",
|
||||
"GraphBubbleUp",
|
||||
"GraphInterrupt",
|
||||
"NodeInterrupt",
|
||||
"ParentCommand",
|
||||
"EmptyInputError",
|
||||
"TaskNotFound",
|
||||
)
|
||||
|
||||
|
||||
class ErrorCode(Enum):
|
||||
|
||||
@@ -19,14 +19,14 @@ from typing import (
|
||||
|
||||
from typing_extensions import Unpack
|
||||
|
||||
from langgraph._typing import UNSET, DeprecatedKwargs
|
||||
from langgraph._internal._typing import UNSET, DeprecatedKwargs
|
||||
from langgraph.cache.base import BaseCache
|
||||
from langgraph.channels.ephemeral_value import EphemeralValue
|
||||
from langgraph.channels.last_value import LastValue
|
||||
from langgraph.checkpoint.base import BaseCheckpointSaver
|
||||
from langgraph.constants import CACHE_NS_WRITES, END, PREVIOUS, START
|
||||
from langgraph.pregel import Pregel
|
||||
from langgraph.pregel.call import (
|
||||
from langgraph.pregel._call import (
|
||||
P,
|
||||
SyncAsyncFuture,
|
||||
T,
|
||||
@@ -34,14 +34,16 @@ from langgraph.pregel.call import (
|
||||
get_runnable_for_entrypoint,
|
||||
identifier,
|
||||
)
|
||||
from langgraph.pregel.read import PregelNode
|
||||
from langgraph.pregel.write import ChannelWrite, ChannelWriteEntry
|
||||
from langgraph.pregel._read import PregelNode
|
||||
from langgraph.pregel._write import ChannelWrite, ChannelWriteEntry
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import _DC_KWARGS, CachePolicy, RetryPolicy, StreamMode
|
||||
from langgraph.warnings import LangGraphDeprecatedSinceV05
|
||||
|
||||
__all__ = ("task", "entrypoint")
|
||||
|
||||
class TaskFunction(Generic[P, T]):
|
||||
|
||||
class _TaskFunction(Generic[P, T]):
|
||||
def __init__(
|
||||
self,
|
||||
func: Callable[P, T],
|
||||
@@ -97,14 +99,14 @@ def task(
|
||||
**kwargs: Unpack[DeprecatedKwargs],
|
||||
) -> Callable[
|
||||
[Callable[P, Awaitable[T]] | Callable[P, T]],
|
||||
TaskFunction[P, T],
|
||||
_TaskFunction[P, T],
|
||||
]: ...
|
||||
|
||||
|
||||
@overload
|
||||
def task(
|
||||
__func_or_none__: Callable[P, Awaitable[T]] | Callable[P, T],
|
||||
) -> TaskFunction[P, T]: ...
|
||||
) -> _TaskFunction[P, T]: ...
|
||||
|
||||
|
||||
def task(
|
||||
@@ -115,8 +117,8 @@ def task(
|
||||
cache_policy: CachePolicy[Callable[P, str | bytes]] | None = None,
|
||||
**kwargs: Unpack[DeprecatedKwargs],
|
||||
) -> (
|
||||
Callable[[Callable[P, Awaitable[T]] | Callable[P, T]], TaskFunction[P, T]]
|
||||
| TaskFunction[P, T]
|
||||
Callable[[Callable[P, Awaitable[T]] | Callable[P, T]], _TaskFunction[P, T]]
|
||||
| _TaskFunction[P, T]
|
||||
):
|
||||
"""Define a LangGraph task using the `task` decorator.
|
||||
|
||||
@@ -195,7 +197,7 @@ def task(
|
||||
def decorator(
|
||||
func: Callable[P, Awaitable[T]] | Callable[P, T],
|
||||
) -> Callable[P, concurrent.futures.Future[T]] | Callable[P, asyncio.Future[T]]:
|
||||
return TaskFunction(
|
||||
return _TaskFunction(
|
||||
func, retry_policy=retry_policies, cache_policy=cache_policy, name=name
|
||||
)
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ from langgraph.constants import END, START
|
||||
from langgraph.graph.message import MessageGraph, MessagesState, add_messages
|
||||
from langgraph.graph.state import StateGraph
|
||||
|
||||
__all__ = [
|
||||
__all__ = (
|
||||
"END",
|
||||
"START",
|
||||
"StateGraph",
|
||||
"MessageGraph",
|
||||
"add_messages",
|
||||
"MessagesState",
|
||||
]
|
||||
"MessageGraph",
|
||||
)
|
||||
|
||||
+12
-12
@@ -26,15 +26,15 @@ from langchain_core.runnables import (
|
||||
RunnableLambda,
|
||||
)
|
||||
|
||||
from langgraph.constants import END, START
|
||||
from langgraph.errors import InvalidUpdateError
|
||||
from langgraph.pregel.write import PASSTHROUGH, ChannelWrite, ChannelWriteEntry
|
||||
from langgraph.types import Send
|
||||
from langgraph.utils.runnable import (
|
||||
from langgraph._internal._runnable import (
|
||||
RunnableCallable,
|
||||
)
|
||||
from langgraph.constants import END, START
|
||||
from langgraph.errors import InvalidUpdateError
|
||||
from langgraph.pregel._write import PASSTHROUGH, ChannelWrite, ChannelWriteEntry
|
||||
from langgraph.types import Send
|
||||
|
||||
Writer = Callable[
|
||||
_Writer = Callable[
|
||||
[Sequence[Union[str, Send]], bool],
|
||||
Sequence[Union[ChannelWriteEntry, Send]],
|
||||
]
|
||||
@@ -82,7 +82,7 @@ def _get_branch_path_input_schema(
|
||||
return input
|
||||
|
||||
|
||||
class Branch(NamedTuple):
|
||||
class BranchSpec(NamedTuple):
|
||||
path: Runnable[Any, Hashable | list[Hashable]]
|
||||
ends: dict[Hashable, str] | None
|
||||
input_schema: type[Any] | None = None
|
||||
@@ -93,7 +93,7 @@ class Branch(NamedTuple):
|
||||
path: Runnable[Any, Hashable | list[Hashable]],
|
||||
path_map: dict[Hashable, str] | list[str] | None,
|
||||
infer_schema: bool = False,
|
||||
) -> Branch:
|
||||
) -> BranchSpec:
|
||||
# coerce path_map to a dictionary
|
||||
path_map_: dict[Hashable, str] | None = None
|
||||
try:
|
||||
@@ -123,7 +123,7 @@ class Branch(NamedTuple):
|
||||
|
||||
def run(
|
||||
self,
|
||||
writer: Writer,
|
||||
writer: _Writer,
|
||||
reader: Callable[[RunnableConfig], Any] | None = None,
|
||||
) -> RunnableCallable:
|
||||
return ChannelWrite.register_writer(
|
||||
@@ -152,7 +152,7 @@ class Branch(NamedTuple):
|
||||
config: RunnableConfig,
|
||||
*,
|
||||
reader: Callable[[RunnableConfig], Any] | None,
|
||||
writer: Writer,
|
||||
writer: _Writer,
|
||||
) -> Runnable:
|
||||
if reader:
|
||||
value = reader(config)
|
||||
@@ -175,7 +175,7 @@ class Branch(NamedTuple):
|
||||
config: RunnableConfig,
|
||||
*,
|
||||
reader: Callable[[RunnableConfig], Any] | None,
|
||||
writer: Writer,
|
||||
writer: _Writer,
|
||||
) -> Runnable:
|
||||
if reader:
|
||||
value = reader(config)
|
||||
@@ -194,7 +194,7 @@ class Branch(NamedTuple):
|
||||
|
||||
def _finish(
|
||||
self,
|
||||
writer: Writer,
|
||||
writer: _Writer,
|
||||
input: Any,
|
||||
result: Any,
|
||||
config: RunnableConfig,
|
||||
@@ -0,0 +1,84 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import Any, NamedTuple, Protocol, Union
|
||||
|
||||
from langchain_core.runnables import Runnable, RunnableConfig
|
||||
from typing_extensions import TypeAlias
|
||||
|
||||
from langgraph.constants import EMPTY_SEQ
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import CachePolicy, RetryPolicy, StreamWriter
|
||||
from langgraph.typing import StateT_contra
|
||||
|
||||
|
||||
class _Node(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfig(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra, config: RunnableConfig) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithWriter(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra, *, writer: StreamWriter) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithStore(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra, *, store: BaseStore) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithWriterStore(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self, state: StateT_contra, *, writer: StreamWriter, store: BaseStore
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfigWriter(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self, state: StateT_contra, *, config: RunnableConfig, writer: StreamWriter
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfigStore(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self, state: StateT_contra, *, config: RunnableConfig, store: BaseStore
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfigWriterStore(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self,
|
||||
state: StateT_contra,
|
||||
*,
|
||||
config: RunnableConfig,
|
||||
writer: StreamWriter,
|
||||
store: BaseStore,
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
# TODO: we probably don't want to explicitly support the config / store signatures once
|
||||
# we move to adding a context arg. Maybe what we do is we add support for kwargs with param spec
|
||||
# this is purely for typing purposes though, so can easily change in the coming weeks.
|
||||
StateNode: TypeAlias = Union[
|
||||
_Node[StateT_contra],
|
||||
_NodeWithConfig[StateT_contra],
|
||||
_NodeWithWriter[StateT_contra],
|
||||
_NodeWithStore[StateT_contra],
|
||||
_NodeWithWriterStore[StateT_contra],
|
||||
_NodeWithConfigWriter[StateT_contra],
|
||||
_NodeWithConfigStore[StateT_contra],
|
||||
_NodeWithConfigWriterStore[StateT_contra],
|
||||
Runnable[StateT_contra, Any],
|
||||
]
|
||||
|
||||
|
||||
# TODO: use a dataclass generic on NodeInputType
|
||||
class StateNodeSpec(NamedTuple):
|
||||
runnable: StateNode
|
||||
metadata: dict[str, Any] | None
|
||||
input_schema: type[Any]
|
||||
retry_policy: RetryPolicy | Sequence[RetryPolicy] | None
|
||||
cache_policy: CachePolicy | None
|
||||
ends: tuple[str, ...] | dict[str, str] | None = EMPTY_SEQ
|
||||
defer: bool = False
|
||||
@@ -27,6 +27,12 @@ from typing_extensions import TypedDict
|
||||
from langgraph.constants import CONF, CONFIG_KEY_SEND
|
||||
from langgraph.graph.state import StateGraph
|
||||
|
||||
__all__ = (
|
||||
"add_messages",
|
||||
"MessagesState",
|
||||
"MessageGraph",
|
||||
)
|
||||
|
||||
Messages = Union[list[MessageLikeRepresentation], MessageLikeRepresentation]
|
||||
|
||||
REMOVE_ALL_MESSAGES = "__remove_all__"
|
||||
@@ -315,7 +321,7 @@ def push_message(
|
||||
|
||||
from langgraph.config import get_config
|
||||
from langgraph.constants import NS_SEP
|
||||
from langgraph.pregel.messages import StreamMessagesHandler
|
||||
from langgraph.pregel._messages import StreamMessagesHandler
|
||||
|
||||
config = get_config()
|
||||
message = next(x for x in convert_to_messages([message]))
|
||||
|
||||
@@ -14,8 +14,6 @@ from typing import (
|
||||
Callable,
|
||||
Generic,
|
||||
Literal,
|
||||
NamedTuple,
|
||||
Protocol,
|
||||
Union,
|
||||
cast,
|
||||
get_args,
|
||||
@@ -26,9 +24,16 @@ from typing import (
|
||||
|
||||
from langchain_core.runnables import Runnable, RunnableConfig
|
||||
from pydantic import BaseModel
|
||||
from typing_extensions import Self, TypeAlias, Unpack
|
||||
from typing_extensions import Self, Unpack
|
||||
|
||||
from langgraph._typing import UNSET, DeprecatedKwargs
|
||||
from langgraph._internal._fields import (
|
||||
get_cached_annotated_keys,
|
||||
get_field_default,
|
||||
get_update_as_tuples,
|
||||
)
|
||||
from langgraph._internal._pydantic import create_model
|
||||
from langgraph._internal._runnable import coerce_to_runnable
|
||||
from langgraph._internal._typing import UNSET, DeprecatedKwargs
|
||||
from langgraph.cache.base import BaseCache
|
||||
from langgraph.channels.base import BaseChannel
|
||||
from langgraph.channels.binop import BinaryOperatorAggregate
|
||||
@@ -56,14 +61,15 @@ from langgraph.errors import (
|
||||
ParentCommand,
|
||||
create_error_message,
|
||||
)
|
||||
from langgraph.graph.branch import Branch
|
||||
from langgraph.graph._branch import BranchSpec
|
||||
from langgraph.graph._node import StateNode, StateNodeSpec
|
||||
from langgraph.managed.base import (
|
||||
ManagedValueSpec,
|
||||
is_managed_value,
|
||||
)
|
||||
from langgraph.pregel import Pregel
|
||||
from langgraph.pregel.read import ChannelRead, PregelNode
|
||||
from langgraph.pregel.write import (
|
||||
from langgraph.pregel._read import ChannelRead, PregelNode
|
||||
from langgraph.pregel._write import (
|
||||
ChannelWrite,
|
||||
ChannelWriteEntry,
|
||||
ChannelWriteTupleEntry,
|
||||
@@ -76,20 +82,16 @@ from langgraph.types import (
|
||||
Command,
|
||||
RetryPolicy,
|
||||
Send,
|
||||
StreamWriter,
|
||||
)
|
||||
from langgraph.typing import InputT, OutputT, StateT, StateT_contra
|
||||
from langgraph.utils.fields import (
|
||||
get_cached_annotated_keys,
|
||||
get_field_default,
|
||||
get_update_as_tuples,
|
||||
)
|
||||
from langgraph.utils.pydantic import create_model
|
||||
from langgraph.utils.runnable import coerce_to_runnable
|
||||
from langgraph.typing import InputT, OutputT, StateT
|
||||
from langgraph.warnings import LangGraphDeprecatedSinceV05
|
||||
|
||||
__all__ = ("StateGraph", "CompiledStateGraph")
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_CHANNEL_BRANCH_TO = "branch:to:{}"
|
||||
|
||||
|
||||
def _warn_invalid_state_schema(schema: type[Any] | Any) -> None:
|
||||
if isinstance(schema, type):
|
||||
@@ -103,67 +105,6 @@ def _warn_invalid_state_schema(schema: type[Any] | Any) -> None:
|
||||
)
|
||||
|
||||
|
||||
class _StateNode(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfig(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra, config: RunnableConfig) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithWriter(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra, *, writer: StreamWriter) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithStore(Protocol[StateT_contra]):
|
||||
def __call__(self, state: StateT_contra, *, store: BaseStore) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithWriterStore(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self, state: StateT_contra, *, writer: StreamWriter, store: BaseStore
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfigWriter(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self, state: StateT_contra, *, config: RunnableConfig, writer: StreamWriter
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfigStore(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self, state: StateT_contra, *, config: RunnableConfig, store: BaseStore
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
class _NodeWithConfigWriterStore(Protocol[StateT_contra]):
|
||||
def __call__(
|
||||
self,
|
||||
state: StateT_contra,
|
||||
*,
|
||||
config: RunnableConfig,
|
||||
writer: StreamWriter,
|
||||
store: BaseStore,
|
||||
) -> Any: ...
|
||||
|
||||
|
||||
# TODO: we probably don't want to explicitly support the config / store signatures once
|
||||
# we move to adding a context arg. Maybe what we do is we add support for kwargs with param spec
|
||||
# this is purely for typing purposes though, so can easily change in the coming weeks.
|
||||
StateNode: TypeAlias = Union[
|
||||
_StateNode[StateT_contra],
|
||||
_NodeWithConfig[StateT_contra],
|
||||
_NodeWithWriter[StateT_contra],
|
||||
_NodeWithStore[StateT_contra],
|
||||
_NodeWithWriterStore[StateT_contra],
|
||||
_NodeWithConfigWriter[StateT_contra],
|
||||
_NodeWithConfigStore[StateT_contra],
|
||||
_NodeWithConfigWriterStore[StateT_contra],
|
||||
Runnable[StateT_contra, Any],
|
||||
]
|
||||
|
||||
|
||||
def _get_node_name(node: StateNode) -> str:
|
||||
try:
|
||||
return getattr(node, "__name__", node.__class__.__name__)
|
||||
@@ -171,20 +112,6 @@ def _get_node_name(node: StateNode) -> str:
|
||||
raise TypeError(f"Unsupported node type: {type(node)}")
|
||||
|
||||
|
||||
class StateNodeSpec(NamedTuple):
|
||||
# TODO: rename this callable, also move away from NamedTuple so that we can use
|
||||
# a generic StateNode, so maybe a dataclass
|
||||
runnable: StateNode
|
||||
metadata: dict[str, Any] | None
|
||||
# TODO: rename to input_schema, though we really just want to modify this structure to
|
||||
# be a dataclass
|
||||
input: type[Any]
|
||||
retry_policy: RetryPolicy | Sequence[RetryPolicy] | None
|
||||
cache_policy: CachePolicy | None
|
||||
ends: tuple[str, ...] | dict[str, str] | None = EMPTY_SEQ
|
||||
defer: bool = False
|
||||
|
||||
|
||||
class StateGraph(Generic[StateT, InputT, OutputT]):
|
||||
"""A graph whose nodes communicate by reading and writing to a shared state.
|
||||
The signature of each node is State -> Partial<State>.
|
||||
@@ -239,7 +166,7 @@ class StateGraph(Generic[StateT, InputT, OutputT]):
|
||||
|
||||
edges: set[tuple[str, str]]
|
||||
nodes: dict[str, StateNodeSpec]
|
||||
branches: defaultdict[str, dict[str, Branch]]
|
||||
branches: defaultdict[str, dict[str, BranchSpec]]
|
||||
channels: dict[str, BaseChannel]
|
||||
managed: dict[str, ManagedValueSpec]
|
||||
schemas: dict[type[Any], dict[str, BaseChannel | ManagedValueSpec]]
|
||||
@@ -538,7 +465,7 @@ class StateGraph(Generic[StateT, InputT, OutputT]):
|
||||
self.nodes[node] = StateNodeSpec(
|
||||
coerce_to_runnable(action, name=node, trace=False),
|
||||
metadata,
|
||||
input=input_schema or self.state_schema,
|
||||
input_schema=input_schema or self.state_schema,
|
||||
retry_policy=retry_policy,
|
||||
cache_policy=cache_policy,
|
||||
ends=ends,
|
||||
@@ -641,7 +568,7 @@ class StateGraph(Generic[StateT, InputT, OutputT]):
|
||||
f"Branch with name `{path.name}` already exists for node `{source}`"
|
||||
)
|
||||
# save it
|
||||
self.branches[source][name] = Branch.from_path(path, path_map, True)
|
||||
self.branches[source][name] = BranchSpec.from_path(path, path_map, True)
|
||||
if schema := self.branches[source][name].input_schema:
|
||||
self._add_schema(schema)
|
||||
return self
|
||||
@@ -994,7 +921,7 @@ class CompiledStateGraph(
|
||||
writers=[ChannelWrite(write_entries)],
|
||||
)
|
||||
elif node is not None:
|
||||
input_schema = node.input if node else self.builder._state_schema
|
||||
input_schema = node.input_schema if node else self.builder._state_schema
|
||||
input_channels = list(self.builder.schemas[input_schema])
|
||||
is_single_input = len(input_channels) == 1 and "__root__" in input_channels
|
||||
if input_schema in self.schema_to_mapper:
|
||||
@@ -1003,7 +930,7 @@ class CompiledStateGraph(
|
||||
mapper = _pick_mapper(input_channels, input_schema)
|
||||
self.schema_to_mapper[input_schema] = mapper
|
||||
|
||||
branch_channel = CHANNEL_BRANCH_TO.format(key)
|
||||
branch_channel = _CHANNEL_BRANCH_TO.format(key)
|
||||
self.channels[branch_channel] = (
|
||||
LastValueAfterFinish(Any)
|
||||
if node.defer
|
||||
@@ -1031,7 +958,7 @@ class CompiledStateGraph(
|
||||
if end != END:
|
||||
self.nodes[starts].writers.append(
|
||||
ChannelWrite(
|
||||
(ChannelWriteEntry(CHANNEL_BRANCH_TO.format(end), None),)
|
||||
(ChannelWriteEntry(_CHANNEL_BRANCH_TO.format(end), None),)
|
||||
)
|
||||
)
|
||||
elif end != END:
|
||||
@@ -1052,7 +979,7 @@ class CompiledStateGraph(
|
||||
)
|
||||
|
||||
def attach_branch(
|
||||
self, start: str, name: str, branch: Branch, *, with_reader: bool = True
|
||||
self, start: str, name: str, branch: BranchSpec, *, with_reader: bool = True
|
||||
) -> None:
|
||||
def get_writes(
|
||||
packets: Sequence[str | Send], static: bool = False
|
||||
@@ -1060,7 +987,7 @@ class CompiledStateGraph(
|
||||
writes = [
|
||||
(
|
||||
ChannelWriteEntry(
|
||||
p if p == END else CHANNEL_BRANCH_TO.format(p), None
|
||||
p if p == END else _CHANNEL_BRANCH_TO.format(p), None
|
||||
)
|
||||
if not isinstance(p, Send)
|
||||
else p
|
||||
@@ -1075,7 +1002,7 @@ class CompiledStateGraph(
|
||||
if with_reader:
|
||||
# get schema
|
||||
schema = branch.input_schema or (
|
||||
self.builder.nodes[start].input
|
||||
self.builder.nodes[start].input_schema
|
||||
if start in self.builder.nodes
|
||||
else self.builder.state_schema
|
||||
)
|
||||
@@ -1237,12 +1164,12 @@ def _control_branch(value: Any) -> Sequence[tuple[str, Any]]:
|
||||
if isinstance(command.goto, Send):
|
||||
rtn.append((TASKS, command.goto))
|
||||
elif isinstance(command.goto, str):
|
||||
rtn.append((CHANNEL_BRANCH_TO.format(command.goto), None))
|
||||
rtn.append((_CHANNEL_BRANCH_TO.format(command.goto), None))
|
||||
else:
|
||||
rtn.extend(
|
||||
(TASKS, go)
|
||||
if isinstance(go, Send)
|
||||
else (CHANNEL_BRANCH_TO.format(go), None)
|
||||
else (_CHANNEL_BRANCH_TO.format(go), None)
|
||||
for go in command.goto
|
||||
)
|
||||
return rtn
|
||||
@@ -1253,12 +1180,12 @@ def _control_static(
|
||||
) -> Sequence[tuple[str, Any, str | None]]:
|
||||
if isinstance(ends, dict):
|
||||
return [
|
||||
(k if k == END else CHANNEL_BRANCH_TO.format(k), None, label)
|
||||
(k if k == END else _CHANNEL_BRANCH_TO.format(k), None, label)
|
||||
for k, label in ends.items()
|
||||
]
|
||||
else:
|
||||
return [
|
||||
(e if e == END else CHANNEL_BRANCH_TO.format(e), None, None) for e in ends
|
||||
(e if e == END else _CHANNEL_BRANCH_TO.format(e), None, None) for e in ends
|
||||
]
|
||||
|
||||
|
||||
@@ -1415,6 +1342,3 @@ def _get_schema(
|
||||
if k in channels and isinstance(channels[k], BaseChannel)
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
CHANNEL_BRANCH_TO = "branch:to:{}"
|
||||
|
||||
@@ -6,8 +6,17 @@ from uuid import uuid4
|
||||
from langchain_core.messages import AnyMessage
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langgraph.config import get_config, get_stream_writer
|
||||
from langgraph.constants import CONF, CONFIG_KEY_SEND
|
||||
from langgraph.utils.config import get_config, get_stream_writer
|
||||
|
||||
__all__ = (
|
||||
"UIMessage",
|
||||
"RemoveUIMessage",
|
||||
"AnyUIMessage",
|
||||
"push_ui_message",
|
||||
"delete_ui_message",
|
||||
"ui_message_reducer",
|
||||
)
|
||||
|
||||
|
||||
class UIMessage(TypedDict):
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
from langgraph.managed.is_last_step import IsLastStep, RemainingSteps
|
||||
|
||||
__all__ = ["IsLastStep", "RemainingSteps"]
|
||||
__all__ = ("IsLastStep", "RemainingSteps")
|
||||
|
||||
@@ -8,11 +8,13 @@ from typing import (
|
||||
|
||||
from typing_extensions import TypeGuard
|
||||
|
||||
from langgraph.types import PregelScratchpad
|
||||
from langgraph.pregel._scratchpad import PregelScratchpad
|
||||
|
||||
V = TypeVar("V")
|
||||
U = TypeVar("U")
|
||||
|
||||
__all__ = ("ManagedValueSpec", "ManagedValueMapping")
|
||||
|
||||
|
||||
class ManagedValue(ABC, Generic[V]):
|
||||
@staticmethod
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
from typing import Annotated
|
||||
|
||||
from langgraph.managed.base import ManagedValue
|
||||
from langgraph.types import PregelScratchpad
|
||||
from langgraph.pregel._scratchpad import PregelScratchpad
|
||||
|
||||
__all__ = ("IsLastStep", "RemainingStepsManager")
|
||||
|
||||
|
||||
class IsLastStepManager(ManagedValue[bool]):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ from langchain_core.callbacks.manager import AsyncParentRunManager, ParentRunMan
|
||||
from langchain_core.runnables.config import RunnableConfig
|
||||
from xxhash import xxh3_128_hexdigest
|
||||
|
||||
from langgraph._internal._config import merge_configs, patch_config
|
||||
from langgraph.channels.base import BaseChannel
|
||||
from langgraph.channels.topic import Topic
|
||||
from langgraph.checkpoint.base import (
|
||||
@@ -64,24 +65,23 @@ from langgraph.constants import (
|
||||
RETURN,
|
||||
TAG_HIDDEN,
|
||||
TASKS,
|
||||
Send,
|
||||
)
|
||||
from langgraph.managed.base import ManagedValueMapping
|
||||
from langgraph.pregel.call import get_runnable_for_task, identifier
|
||||
from langgraph.pregel.io import read_channels
|
||||
from langgraph.pregel.log import logger
|
||||
from langgraph.pregel.read import INPUT_CACHE_KEY_TYPE, PregelNode
|
||||
from langgraph.pregel._call import get_runnable_for_task, identifier
|
||||
from langgraph.pregel._io import read_channels
|
||||
from langgraph.pregel._log import logger
|
||||
from langgraph.pregel._read import INPUT_CACHE_KEY_TYPE, PregelNode
|
||||
from langgraph.pregel._scratchpad import PregelScratchpad
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import (
|
||||
All,
|
||||
CacheKey,
|
||||
CachePolicy,
|
||||
PregelExecutableTask,
|
||||
PregelScratchpad,
|
||||
PregelTask,
|
||||
RetryPolicy,
|
||||
Send,
|
||||
)
|
||||
from langgraph.utils.config import merge_configs, patch_config
|
||||
|
||||
GetNextVersion = Callable[[Optional[V], None], V]
|
||||
SUPPORTS_EXC_NOTES = sys.version_info >= (3, 11)
|
||||
@@ -13,16 +13,16 @@ from typing import Any, Callable, Generic, TypeVar, cast
|
||||
from langchain_core.runnables import Runnable
|
||||
from typing_extensions import ParamSpec
|
||||
|
||||
from langgraph.constants import CONF, CONFIG_KEY_CALL, RETURN
|
||||
from langgraph.pregel.write import ChannelWrite, ChannelWriteEntry
|
||||
from langgraph.types import CachePolicy, RetryPolicy
|
||||
from langgraph.utils.config import get_config
|
||||
from langgraph.utils.runnable import (
|
||||
from langgraph._internal._runnable import (
|
||||
RunnableCallable,
|
||||
RunnableSeq,
|
||||
is_async_callable,
|
||||
run_in_executor,
|
||||
)
|
||||
from langgraph.config import get_config
|
||||
from langgraph.constants import CONF, CONFIG_KEY_CALL, RETURN
|
||||
from langgraph.pregel._write import ChannelWrite, ChannelWriteEntry
|
||||
from langgraph.types import CachePolicy, RetryPolicy
|
||||
|
||||
##
|
||||
# Utilities borrowed from cloudpickle.
|
||||
@@ -78,8 +78,8 @@ def _whichmodule(obj: Any, name: str) -> str | None:
|
||||
|
||||
def identifier(obj: Any, name: str | None = None) -> str | None:
|
||||
"""Return the module and name of an object."""
|
||||
from langgraph.pregel.read import PregelNode
|
||||
from langgraph.utils.runnable import RunnableCallable, RunnableSeq
|
||||
from langgraph._internal._runnable import RunnableCallable, RunnableSeq
|
||||
from langgraph.pregel._read import PregelNode
|
||||
|
||||
if isinstance(obj, PregelNode):
|
||||
obj = obj.bound
|
||||
@@ -11,16 +11,16 @@ from langgraph.channels.base import BaseChannel
|
||||
from langgraph.checkpoint.base import BaseCheckpointSaver
|
||||
from langgraph.constants import CONF, CONFIG_KEY_SEND, END, INPUT, START
|
||||
from langgraph.managed.base import ManagedValueSpec
|
||||
from langgraph.pregel.algo import (
|
||||
from langgraph.pregel._algo import (
|
||||
PregelTaskWrites,
|
||||
apply_writes,
|
||||
increment,
|
||||
prepare_next_tasks,
|
||||
)
|
||||
from langgraph.pregel.checkpoint import channels_from_checkpoint, empty_checkpoint
|
||||
from langgraph.pregel.io import map_input
|
||||
from langgraph.pregel.read import PregelNode
|
||||
from langgraph.pregel.write import ChannelWrite
|
||||
from langgraph.pregel._checkpoint import channels_from_checkpoint, empty_checkpoint
|
||||
from langgraph.pregel._io import map_input
|
||||
from langgraph.pregel._read import PregelNode
|
||||
from langgraph.pregel._write import ChannelWrite
|
||||
from langgraph.types import All, Checkpointer
|
||||
|
||||
|
||||
+1
-1
@@ -18,8 +18,8 @@ from langchain_core.runnables import RunnableConfig
|
||||
from langchain_core.runnables.config import get_executor_for_config
|
||||
from typing_extensions import ParamSpec
|
||||
|
||||
from langgraph._internal._future import CONTEXT_NOT_SUPPORTED, run_coroutine_threadsafe
|
||||
from langgraph.errors import GraphBubbleUp
|
||||
from langgraph.utils.future import CONTEXT_NOT_SUPPORTED, run_coroutine_threadsafe
|
||||
|
||||
P = ParamSpec("P")
|
||||
T = TypeVar("T")
|
||||
@@ -18,7 +18,7 @@ from langgraph.constants import (
|
||||
TASKS,
|
||||
)
|
||||
from langgraph.errors import InvalidUpdateError
|
||||
from langgraph.pregel.log import logger
|
||||
from langgraph.pregel._log import logger
|
||||
from langgraph.types import Command, PregelExecutableTask, Send
|
||||
|
||||
|
||||
+14
-15
@@ -27,6 +27,7 @@ from langchain_core.callbacks import AsyncParentRunManager, ParentRunManager
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
from typing_extensions import ParamSpec, Self
|
||||
|
||||
from langgraph._internal._config import patch_configurable
|
||||
from langgraph.cache.base import BaseCache
|
||||
from langgraph.channels.base import BaseChannel
|
||||
from langgraph.checkpoint.base import (
|
||||
@@ -69,7 +70,7 @@ from langgraph.managed.base import (
|
||||
ManagedValueMapping,
|
||||
ManagedValueSpec,
|
||||
)
|
||||
from langgraph.pregel.algo import (
|
||||
from langgraph.pregel._algo import (
|
||||
Call,
|
||||
GetNextVersion,
|
||||
PregelTaskWrites,
|
||||
@@ -81,44 +82,42 @@ from langgraph.pregel.algo import (
|
||||
should_interrupt,
|
||||
task_path_str,
|
||||
)
|
||||
from langgraph.pregel.checkpoint import (
|
||||
from langgraph.pregel._checkpoint import (
|
||||
channels_from_checkpoint,
|
||||
copy_checkpoint,
|
||||
create_checkpoint,
|
||||
empty_checkpoint,
|
||||
)
|
||||
from langgraph.pregel.debug import (
|
||||
map_debug_checkpoint,
|
||||
map_debug_task_results,
|
||||
map_debug_tasks,
|
||||
)
|
||||
from langgraph.pregel.executor import (
|
||||
from langgraph.pregel._executor import (
|
||||
AsyncBackgroundExecutor,
|
||||
BackgroundExecutor,
|
||||
Submit,
|
||||
)
|
||||
from langgraph.pregel.io import (
|
||||
from langgraph.pregel._io import (
|
||||
map_command,
|
||||
map_input,
|
||||
map_output_updates,
|
||||
map_output_values,
|
||||
read_channels,
|
||||
)
|
||||
from langgraph.pregel.read import PregelNode
|
||||
from langgraph.pregel.utils import get_new_channel_versions, is_xxh3_128_hexdigest
|
||||
from langgraph.pregel._read import PregelNode
|
||||
from langgraph.pregel._scratchpad import PregelScratchpad
|
||||
from langgraph.pregel._utils import get_new_channel_versions, is_xxh3_128_hexdigest
|
||||
from langgraph.pregel.debug import (
|
||||
map_debug_checkpoint,
|
||||
map_debug_task_results,
|
||||
map_debug_tasks,
|
||||
)
|
||||
from langgraph.pregel.protocol import StreamChunk, StreamProtocol
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import (
|
||||
All,
|
||||
CachePolicy,
|
||||
Command,
|
||||
PregelExecutableTask,
|
||||
PregelScratchpad,
|
||||
RetryPolicy,
|
||||
StreamChunk,
|
||||
StreamMode,
|
||||
StreamProtocol,
|
||||
)
|
||||
from langgraph.utils.config import patch_configurable
|
||||
|
||||
V = TypeVar("V")
|
||||
P = ParamSpec("P")
|
||||
+4
-5
@@ -13,8 +13,9 @@ from langchain_core.callbacks import BaseCallbackHandler
|
||||
from langchain_core.messages import BaseMessage
|
||||
from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, LLMResult
|
||||
|
||||
from langgraph.constants import NS_SEP, TAG_HIDDEN, TAG_NOSTREAM, TAG_NOSTREAM_ALT
|
||||
from langgraph.types import Command, StreamChunk
|
||||
from langgraph.constants import NS_SEP, TAG_HIDDEN, TAG_NOSTREAM
|
||||
from langgraph.pregel.protocol import StreamChunk
|
||||
from langgraph.types import Command
|
||||
|
||||
try:
|
||||
from langchain_core.tracers._streaming import _StreamingCallbackHandler
|
||||
@@ -94,9 +95,7 @@ class StreamMessagesHandler(BaseCallbackHandler, _StreamingCallbackHandler):
|
||||
metadata: dict[str, Any] | None = None,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
if metadata and (
|
||||
not tags or (TAG_NOSTREAM not in tags and TAG_NOSTREAM_ALT not in tags)
|
||||
):
|
||||
if metadata and (not tags or (TAG_NOSTREAM not in tags)):
|
||||
ns = tuple(cast(str, metadata["langgraph_checkpoint_ns"]).split(NS_SEP))[
|
||||
:-1
|
||||
]
|
||||
@@ -10,13 +10,13 @@ from typing import (
|
||||
|
||||
from langchain_core.runnables import Runnable, RunnableConfig
|
||||
|
||||
from langgraph._internal._config import merge_configs
|
||||
from langgraph._internal._runnable import RunnableCallable, RunnableSeq
|
||||
from langgraph.constants import CONF, CONFIG_KEY_READ
|
||||
from langgraph.pregel._utils import find_subgraph_pregel
|
||||
from langgraph.pregel._write import ChannelWrite
|
||||
from langgraph.pregel.protocol import PregelProtocol
|
||||
from langgraph.pregel.utils import find_subgraph_pregel
|
||||
from langgraph.pregel.write import ChannelWrite
|
||||
from langgraph.types import CachePolicy, RetryPolicy
|
||||
from langgraph.utils.config import merge_configs
|
||||
from langgraph.utils.runnable import RunnableCallable, RunnableSeq
|
||||
|
||||
READ_TYPE = Callable[[Union[str, Sequence[str]], bool], Union[Any, dict[str, Any]]]
|
||||
INPUT_CACHE_KEY_TYPE = tuple[Callable[..., Any], tuple[str, ...]]
|
||||
+1
-1
@@ -9,6 +9,7 @@ from collections.abc import Awaitable, Sequence
|
||||
from dataclasses import replace
|
||||
from typing import Any, Callable
|
||||
|
||||
from langgraph._internal._config import patch_configurable
|
||||
from langgraph.constants import (
|
||||
CONF,
|
||||
CONFIG_KEY_CHECKPOINT_NS,
|
||||
@@ -17,7 +18,6 @@ from langgraph.constants import (
|
||||
)
|
||||
from langgraph.errors import GraphBubbleUp, ParentCommand
|
||||
from langgraph.types import Command, PregelExecutableTask, RetryPolicy
|
||||
from langgraph.utils.config import patch_configurable
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
SUPPORTS_EXC_NOTES = sys.version_info >= (3, 11)
|
||||
+5
-5
@@ -19,6 +19,7 @@ from typing import (
|
||||
|
||||
from langchain_core.callbacks import Callbacks
|
||||
|
||||
from langgraph._internal._future import chain_future, run_coroutine_threadsafe
|
||||
from langgraph.constants import (
|
||||
CONF,
|
||||
CONFIG_KEY_CALL,
|
||||
@@ -32,16 +33,15 @@ from langgraph.constants import (
|
||||
TAG_HIDDEN,
|
||||
)
|
||||
from langgraph.errors import GraphBubbleUp, GraphInterrupt
|
||||
from langgraph.pregel.algo import Call
|
||||
from langgraph.pregel.executor import Submit
|
||||
from langgraph.pregel.retry import arun_with_retry, run_with_retry
|
||||
from langgraph.pregel._algo import Call
|
||||
from langgraph.pregel._executor import Submit
|
||||
from langgraph.pregel._retry import arun_with_retry, run_with_retry
|
||||
from langgraph.pregel._scratchpad import PregelScratchpad
|
||||
from langgraph.types import (
|
||||
CachePolicy,
|
||||
PregelExecutableTask,
|
||||
PregelScratchpad,
|
||||
RetryPolicy,
|
||||
)
|
||||
from langgraph.utils.future import chain_future, run_coroutine_threadsafe
|
||||
|
||||
F = TypeVar("F", concurrent.futures.Future, asyncio.Future)
|
||||
E = TypeVar("E", threading.Event, asyncio.Event)
|
||||
@@ -0,0 +1,18 @@
|
||||
import dataclasses
|
||||
from typing import Any, Callable
|
||||
|
||||
from langgraph.types import _DC_KWARGS
|
||||
|
||||
|
||||
@dataclasses.dataclass(**_DC_KWARGS)
|
||||
class PregelScratchpad:
|
||||
step: int
|
||||
stop: int
|
||||
# call
|
||||
call_counter: Callable[[], int]
|
||||
# interrupt
|
||||
interrupt_counter: Callable[[], int]
|
||||
get_null_resume: Callable[[bool], Any]
|
||||
resume: list[Any]
|
||||
# subgraph
|
||||
subgraph_counter: Callable[[], int]
|
||||
+2
-2
@@ -6,12 +6,12 @@ import re
|
||||
import textwrap
|
||||
from typing import Any, Callable
|
||||
|
||||
from langchain_core.runnables import RunnableLambda, RunnableSequence
|
||||
from langchain_core.runnables import Runnable, RunnableLambda, RunnableSequence
|
||||
from typing_extensions import override
|
||||
|
||||
from langgraph._internal._runnable import RunnableCallable, RunnableSeq
|
||||
from langgraph.checkpoint.base import ChannelVersions
|
||||
from langgraph.pregel.protocol import PregelProtocol
|
||||
from langgraph.utils.runnable import Runnable, RunnableCallable, RunnableSeq
|
||||
|
||||
|
||||
def get_new_channel_versions(
|
||||
+1
-1
@@ -6,7 +6,7 @@ from typing import Any
|
||||
from langgraph.channels.base import BaseChannel
|
||||
from langgraph.constants import RESERVED
|
||||
from langgraph.managed.base import ManagedValueMapping
|
||||
from langgraph.pregel.read import PregelNode
|
||||
from langgraph.pregel._read import PregelNode
|
||||
from langgraph.types import All
|
||||
|
||||
|
||||
+3
-2
@@ -13,9 +13,10 @@ from typing import (
|
||||
|
||||
from langchain_core.runnables import Runnable, RunnableConfig
|
||||
|
||||
from langgraph.constants import CONF, CONFIG_KEY_SEND, MISSING, TASKS, Send
|
||||
from langgraph._internal._runnable import RunnableCallable
|
||||
from langgraph.constants import CONF, CONFIG_KEY_SEND, MISSING, TASKS
|
||||
from langgraph.errors import InvalidUpdateError
|
||||
from langgraph.utils.runnable import RunnableCallable
|
||||
from langgraph.types import Send
|
||||
|
||||
TYPE_SEND = Callable[[Sequence[tuple[str, Any]]], None]
|
||||
R = TypeVar("R", bound=Runnable)
|
||||
@@ -5,8 +5,10 @@ from dataclasses import asdict
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langgraph._internal._config import patch_checkpoint_map
|
||||
from langgraph.channels.base import BaseChannel
|
||||
from langgraph.checkpoint.base import CheckpointMetadata, PendingWrite
|
||||
from langgraph.constants import (
|
||||
@@ -20,9 +22,10 @@ from langgraph.constants import (
|
||||
RETURN,
|
||||
TAG_HIDDEN,
|
||||
)
|
||||
from langgraph.pregel.io import read_channels
|
||||
from langgraph.pregel._io import read_channels
|
||||
from langgraph.types import PregelExecutableTask, PregelTask, StateSnapshot
|
||||
from langgraph.utils.config import RunnableConfig, patch_checkpoint_map
|
||||
|
||||
__all__ = ("TaskPayload", "TaskResultPayload", "CheckpointTask", "CheckpointPayload")
|
||||
|
||||
|
||||
class TaskPayload(TypedDict):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,17 +2,18 @@ from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import AsyncIterator, Iterator, Sequence
|
||||
from typing import Any, Generic
|
||||
from typing import Any, Callable, Generic, cast
|
||||
|
||||
from langchain_core.runnables import Runnable, RunnableConfig
|
||||
from langchain_core.runnables.graph import Graph as DrawableGraph
|
||||
from typing_extensions import Self
|
||||
|
||||
from langgraph.pregel.types import All, StateSnapshot, StateUpdate, StreamMode
|
||||
from langgraph.types import All, StateSnapshot, StateUpdate, StreamMode
|
||||
from langgraph.typing import InputT, OutputT, StateT
|
||||
|
||||
__all__ = ("PregelProtocol", "StreamProtocol")
|
||||
|
||||
|
||||
# TODO: remove Runnable inheritance here!
|
||||
class PregelProtocol(Runnable[InputT, Any], Generic[StateT, InputT, OutputT], ABC):
|
||||
@abstractmethod
|
||||
def with_config(
|
||||
@@ -138,3 +139,22 @@ class PregelProtocol(Runnable[InputT, Any], Generic[StateT, InputT, OutputT], AB
|
||||
interrupt_before: All | Sequence[str] | None = None,
|
||||
interrupt_after: All | Sequence[str] | None = None,
|
||||
) -> dict[str, Any] | Any: ...
|
||||
|
||||
|
||||
StreamChunk = tuple[tuple[str, ...], str, Any]
|
||||
|
||||
|
||||
class StreamProtocol:
|
||||
__slots__ = ("modes", "__call__")
|
||||
|
||||
modes: set[StreamMode]
|
||||
|
||||
__call__: Callable[[Self, StreamChunk], None]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
__call__: Callable[[StreamChunk], None],
|
||||
modes: set[StreamMode],
|
||||
) -> None:
|
||||
self.__call__ = cast(Callable[[Self, StreamChunk], None], __call__)
|
||||
self.modes = modes
|
||||
|
||||
@@ -29,6 +29,7 @@ from langgraph_sdk.schema import Command as CommandSDK
|
||||
from langgraph_sdk.schema import StreamMode as StreamModeSDK
|
||||
from typing_extensions import Self
|
||||
|
||||
from langgraph._internal._config import merge_configs
|
||||
from langgraph.checkpoint.base import CheckpointMetadata
|
||||
from langgraph.constants import (
|
||||
CONF,
|
||||
@@ -41,12 +42,19 @@ from langgraph.constants import (
|
||||
NS_SEP,
|
||||
)
|
||||
from langgraph.errors import GraphInterrupt
|
||||
from langgraph.pregel.protocol import PregelProtocol
|
||||
from langgraph.pregel.types import All, PregelTask, StateSnapshot, StreamMode
|
||||
from langgraph.types import Command, Interrupt, StreamProtocol
|
||||
from langgraph.utils.config import merge_configs
|
||||
from langgraph.pregel.protocol import PregelProtocol, StreamProtocol
|
||||
from langgraph.types import (
|
||||
All,
|
||||
Command,
|
||||
Interrupt,
|
||||
PregelTask,
|
||||
StateSnapshot,
|
||||
StreamMode,
|
||||
)
|
||||
|
||||
CONF_DROPLIST = frozenset(
|
||||
__all__ = ("RemoteGraph", "RemoteException")
|
||||
|
||||
_CONF_DROPLIST = frozenset(
|
||||
(
|
||||
CONFIG_KEY_CHECKPOINT_MAP,
|
||||
CONFIG_KEY_CHECKPOINT_ID,
|
||||
@@ -56,7 +64,7 @@ CONF_DROPLIST = frozenset(
|
||||
)
|
||||
|
||||
|
||||
def sanitize_config_value(v: Any) -> Any:
|
||||
def _sanitize_config_value(v: Any) -> Any:
|
||||
"""Recursively sanitize a config value to ensure it contains only primitives."""
|
||||
if isinstance(v, (str, int, float, bool)):
|
||||
return v
|
||||
@@ -64,14 +72,14 @@ def sanitize_config_value(v: Any) -> Any:
|
||||
sanitized_dict = {}
|
||||
for k, val in v.items():
|
||||
if isinstance(k, str):
|
||||
sanitized_value = sanitize_config_value(val)
|
||||
sanitized_value = _sanitize_config_value(val)
|
||||
if sanitized_value is not None:
|
||||
sanitized_dict[k] = sanitized_value
|
||||
return sanitized_dict
|
||||
elif isinstance(v, (list, tuple)):
|
||||
sanitized_list = []
|
||||
for item in v:
|
||||
sanitized_item = sanitize_config_value(item)
|
||||
sanitized_item = _sanitize_config_value(item)
|
||||
if sanitized_item is not None:
|
||||
sanitized_list.append(sanitized_item)
|
||||
return sanitized_list
|
||||
@@ -347,7 +355,7 @@ class RemoteGraph(PregelProtocol):
|
||||
for k, v in config["metadata"].items():
|
||||
if (
|
||||
isinstance(k, str)
|
||||
and (sanitized_value := sanitize_config_value(v)) is not None
|
||||
and (sanitized_value := _sanitize_config_value(v)) is not None
|
||||
):
|
||||
sanitized["metadata"][k] = sanitized_value
|
||||
|
||||
@@ -356,8 +364,8 @@ class RemoteGraph(PregelProtocol):
|
||||
for k, v in config["configurable"].items():
|
||||
if (
|
||||
isinstance(k, str)
|
||||
and k not in CONF_DROPLIST
|
||||
and (sanitized_value := sanitize_config_value(v)) is not None
|
||||
and k not in _CONF_DROPLIST
|
||||
and (sanitized_value := _sanitize_config_value(v)) is not None
|
||||
):
|
||||
sanitized["configurable"][k] = sanitized_value
|
||||
|
||||
|
||||
@@ -25,3 +25,14 @@ __all__ = [
|
||||
"StreamWriter",
|
||||
"default_retry_on",
|
||||
]
|
||||
|
||||
from warnings import warn
|
||||
|
||||
from langgraph.warnings import LangGraphDeprecatedSinceV10
|
||||
|
||||
warn(
|
||||
"Importing from langgraph.pregel.types is deprecated. "
|
||||
"Please use 'from langgraph.types import ...' instead.",
|
||||
LangGraphDeprecatedSinceV10,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@@ -18,12 +18,12 @@ from typing import (
|
||||
)
|
||||
|
||||
from langchain_core.runnables import Runnable, RunnableConfig
|
||||
from typing_extensions import Self
|
||||
from xxhash import xxh3_128_hexdigest
|
||||
|
||||
from langgraph._internal._cache import default_cache_key
|
||||
from langgraph._internal._fields import get_cached_annotated_keys, get_update_as_tuples
|
||||
from langgraph._internal._retry import default_retry_on
|
||||
from langgraph.checkpoint.base import BaseCheckpointSaver, CheckpointMetadata
|
||||
from langgraph.utils.cache import default_cache_key
|
||||
from langgraph.utils.fields import get_cached_annotated_keys, get_update_as_tuples
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langgraph.pregel.protocol import PregelProtocol
|
||||
@@ -37,6 +37,24 @@ except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
__all__ = (
|
||||
"All",
|
||||
"Checkpointer",
|
||||
"StreamMode",
|
||||
"StreamWriter",
|
||||
"RetryPolicy",
|
||||
"CachePolicy",
|
||||
"Interrupt",
|
||||
"StateUpdate",
|
||||
"PregelTask",
|
||||
"PregelExecutableTask",
|
||||
"StateSnapshot",
|
||||
"Send",
|
||||
"Command",
|
||||
"interrupt",
|
||||
)
|
||||
|
||||
|
||||
All = Literal["*"]
|
||||
"""Special value to indicate that graph should interrupt on all nodes."""
|
||||
|
||||
@@ -73,37 +91,6 @@ else:
|
||||
_DC_KWARGS = {"frozen": True}
|
||||
|
||||
|
||||
def default_retry_on(exc: Exception) -> bool:
|
||||
import httpx
|
||||
import requests
|
||||
|
||||
if isinstance(exc, ConnectionError):
|
||||
return True
|
||||
if isinstance(exc, httpx.HTTPStatusError):
|
||||
return 500 <= exc.response.status_code < 600
|
||||
if isinstance(exc, requests.HTTPError):
|
||||
return 500 <= exc.response.status_code < 600 if exc.response else True
|
||||
if isinstance(
|
||||
exc,
|
||||
(
|
||||
ValueError,
|
||||
TypeError,
|
||||
ArithmeticError,
|
||||
ImportError,
|
||||
LookupError,
|
||||
NameError,
|
||||
SyntaxError,
|
||||
RuntimeError,
|
||||
ReferenceError,
|
||||
StopIteration,
|
||||
StopAsyncIteration,
|
||||
OSError,
|
||||
),
|
||||
):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class RetryPolicy(NamedTuple):
|
||||
"""Configuration for retrying nodes.
|
||||
|
||||
@@ -364,39 +351,6 @@ class Command(Generic[N], ToolOutputMixin):
|
||||
PARENT: ClassVar[Literal["__parent__"]] = "__parent__"
|
||||
|
||||
|
||||
StreamChunk = tuple[tuple[str, ...], str, Any]
|
||||
|
||||
|
||||
class StreamProtocol:
|
||||
__slots__ = ("modes", "__call__")
|
||||
|
||||
modes: set[StreamMode]
|
||||
|
||||
__call__: Callable[[Self, StreamChunk], None]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
__call__: Callable[[StreamChunk], None],
|
||||
modes: set[StreamMode],
|
||||
) -> None:
|
||||
self.__call__ = cast(Callable[[Self, StreamChunk], None], __call__)
|
||||
self.modes = modes
|
||||
|
||||
|
||||
@dataclasses.dataclass(**_DC_KWARGS)
|
||||
class PregelScratchpad:
|
||||
step: int
|
||||
stop: int
|
||||
# call
|
||||
call_counter: Callable[[], int]
|
||||
# interrupt
|
||||
interrupt_counter: Callable[[], int]
|
||||
get_null_resume: Callable[[bool], Any]
|
||||
resume: list[Any]
|
||||
# subgraph
|
||||
subgraph_counter: Callable[[], int]
|
||||
|
||||
|
||||
def interrupt(value: Any) -> Any:
|
||||
"""Interrupt the graph with a resumable exception from within a node.
|
||||
|
||||
@@ -504,7 +458,7 @@ def interrupt(value: Any) -> Any:
|
||||
|
||||
conf = get_config()["configurable"]
|
||||
# track interrupt index
|
||||
scratchpad: PregelScratchpad = conf[CONFIG_KEY_SCRATCHPAD]
|
||||
scratchpad = conf[CONFIG_KEY_SCRATCHPAD]
|
||||
idx = scratchpad.interrupt_counter()
|
||||
# find previous resume values
|
||||
if scratchpad.resume:
|
||||
|
||||
@@ -4,7 +4,15 @@ from typing import Union
|
||||
|
||||
from typing_extensions import TypeVar
|
||||
|
||||
from langgraph._typing import StateLike
|
||||
from langgraph._internal._typing import StateLike
|
||||
|
||||
__all__ = (
|
||||
"StateT",
|
||||
"StateT_co",
|
||||
"StateT_contra",
|
||||
"InputT",
|
||||
"OutputT",
|
||||
)
|
||||
|
||||
StateT = TypeVar("StateT", bound=StateLike)
|
||||
"""Type variable used to represent the state in a graph."""
|
||||
@@ -19,12 +27,6 @@ InputT = TypeVar("InputT", bound=StateLike, default=StateT)
|
||||
Defaults to `StateT`.
|
||||
"""
|
||||
|
||||
ResolvedInputT = TypeVar("ResolvedInputT", bound=StateLike)
|
||||
"""Type variable used to represent the resolved input to a state graph.
|
||||
|
||||
No default.
|
||||
"""
|
||||
|
||||
|
||||
OutputT = TypeVar("OutputT", bound=Union[StateLike, None], default=StateT)
|
||||
"""Type variable used to represent the output of a state graph."""
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
from importlib import metadata
|
||||
|
||||
__all__ = ("__version__",)
|
||||
|
||||
try:
|
||||
__version__ = metadata.version(__package__)
|
||||
except metadata.PackageNotFoundError:
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = (
|
||||
"LangGraphDeprecationWarning",
|
||||
"LangGraphDeprecatedSinceV05",
|
||||
"LangGraphDeprecatedSinceV10",
|
||||
)
|
||||
|
||||
|
||||
class LangGraphDeprecationWarning(DeprecationWarning):
|
||||
"""A LangGraph specific deprecation warning.
|
||||
@@ -46,3 +52,10 @@ class LangGraphDeprecatedSinceV05(LangGraphDeprecationWarning):
|
||||
|
||||
def __init__(self, message: str, *args: object) -> None:
|
||||
super().__init__(message, *args, since=(0, 5), expected_removal=(2, 0))
|
||||
|
||||
|
||||
class LangGraphDeprecatedSinceV10(LangGraphDeprecationWarning):
|
||||
"""A specific `LangGraphDeprecationWarning` subclass defining functionality deprecated since LangGraph v1.0.0"""
|
||||
|
||||
def __init__(self, message: str, *args: object) -> None:
|
||||
super().__init__(message, *args, since=(1, 0), expected_removal=(2, 0))
|
||||
|
||||
@@ -1,105 +1,4 @@
|
||||
# serializer version: 1
|
||||
# name: test_conditional_graph[memory]
|
||||
'''
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "agent",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": [
|
||||
"langchain",
|
||||
"schema",
|
||||
"runnable",
|
||||
"RunnableAssign"
|
||||
],
|
||||
"name": "agent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tools",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "tools"
|
||||
},
|
||||
"metadata": {
|
||||
"parents": {},
|
||||
"version": 2,
|
||||
"variant": "b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "__start__"
|
||||
},
|
||||
{
|
||||
"id": "__end__"
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "__start__",
|
||||
"target": "agent"
|
||||
},
|
||||
{
|
||||
"source": "agent",
|
||||
"target": "__end__",
|
||||
"data": "exit",
|
||||
"conditional": true
|
||||
},
|
||||
{
|
||||
"source": "agent",
|
||||
"target": "tools",
|
||||
"data": "continue",
|
||||
"conditional": true
|
||||
},
|
||||
{
|
||||
"source": "tools",
|
||||
"target": "agent"
|
||||
}
|
||||
]
|
||||
}
|
||||
'''
|
||||
# ---
|
||||
# name: test_conditional_graph[memory].1
|
||||
'''
|
||||
graph TD;
|
||||
__start__ --> agent;
|
||||
agent -. exit .-> __end__;
|
||||
agent -. continue .-> tools;
|
||||
tools --> agent;
|
||||
|
||||
'''
|
||||
# ---
|
||||
# name: test_conditional_graph[memory].2
|
||||
'''
|
||||
---
|
||||
config:
|
||||
flowchart:
|
||||
curve: linear
|
||||
---
|
||||
graph TD;
|
||||
agent(agent)
|
||||
tools(tools<hr/><small><em>parents = {}
|
||||
version = 2
|
||||
variant = b</em></small>)
|
||||
__start__([<p>__start__</p>]):::first
|
||||
__end__([<p>__end__</p>]):::last
|
||||
__start__ --> agent;
|
||||
agent -. exit .-> __end__;
|
||||
agent -. continue .-> tools;
|
||||
tools --> agent;
|
||||
classDef default fill:#f2f0ff,line-height:1.2
|
||||
classDef first fill-opacity:0
|
||||
classDef last fill:#bfb6fc
|
||||
|
||||
'''
|
||||
# ---
|
||||
# name: test_conditional_state_graph[memory]
|
||||
'{"$defs": {"AgentAction": {"description": "Represents a request to execute an action by an agent.\\n\\nThe action consists of the name of the tool to execute and the input to pass\\nto the tool. The log is used to pass along extra information about the action.", "properties": {"tool": {"title": "Tool", "type": "string"}, "tool_input": {"anyOf": [{"type": "string"}, {"type": "object"}], "title": "Tool Input"}, "log": {"title": "Log", "type": "string"}, "type": {"const": "AgentAction", "default": "AgentAction", "enum": ["AgentAction"], "title": "Type", "type": "string"}}, "required": ["tool", "tool_input", "log"], "title": "AgentAction", "type": "object"}, "AgentFinish": {"description": "Final return value of an ActionAgent.\\n\\nAgents return an AgentFinish when they have reached a stopping condition.", "properties": {"return_values": {"title": "Return Values", "type": "object"}, "log": {"title": "Log", "type": "string"}, "type": {"const": "AgentFinish", "default": "AgentFinish", "enum": ["AgentFinish"], "title": "Type", "type": "string"}}, "required": ["return_values", "log"], "title": "AgentFinish", "type": "object"}}, "properties": {"input": {"default": null, "title": "Input", "type": "string"}, "agent_outcome": {"anyOf": [{"$ref": "#/$defs/AgentAction"}, {"$ref": "#/$defs/AgentFinish"}, {"type": "null"}], "default": null, "title": "Agent Outcome"}, "intermediate_steps": {"default": null, "items": {"maxItems": 2, "minItems": 2, "prefixItems": [{"$ref": "#/$defs/AgentAction"}, {"type": "string"}], "type": "array"}, "title": "Intermediate Steps", "type": "array"}}, "title": "LangGraphInput", "type": "object"}'
|
||||
# ---
|
||||
@@ -116,8 +15,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -142,8 +41,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "tools"
|
||||
@@ -204,8 +103,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -291,8 +190,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -304,8 +203,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "agent"
|
||||
|
||||
@@ -1,93 +1,4 @@
|
||||
# serializer version: 1
|
||||
# name: test_conditional_entrypoint_graph
|
||||
'{"title": "LangGraphInput"}'
|
||||
# ---
|
||||
# name: test_conditional_entrypoint_graph.1
|
||||
'{"title": "LangGraphOutput"}'
|
||||
# ---
|
||||
# name: test_conditional_entrypoint_graph.2
|
||||
'''
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "left",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "left"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "right",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "right"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "__start__",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "__end__"
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "__start__",
|
||||
"target": "left",
|
||||
"data": "go-left",
|
||||
"conditional": true
|
||||
},
|
||||
{
|
||||
"source": "__start__",
|
||||
"target": "right",
|
||||
"data": "go-right",
|
||||
"conditional": true
|
||||
},
|
||||
{
|
||||
"source": "left",
|
||||
"target": "__end__",
|
||||
"conditional": true
|
||||
},
|
||||
{
|
||||
"source": "right",
|
||||
"target": "__end__"
|
||||
}
|
||||
]
|
||||
}
|
||||
'''
|
||||
# ---
|
||||
# name: test_conditional_entrypoint_graph.3
|
||||
'''
|
||||
graph TD;
|
||||
__start__ -. go-left .-> left;
|
||||
__start__ -. go-right .-> right;
|
||||
left -.-> __end__;
|
||||
right --> __end__;
|
||||
|
||||
'''
|
||||
# ---
|
||||
# name: test_conditional_entrypoint_graph_state
|
||||
'{"properties": {"input": {"default": null, "title": "Input", "type": "string"}, "output": {"default": null, "title": "Output", "type": "string"}, "steps": {"default": null, "items": {"type": "string"}, "title": "Steps", "type": "array"}}, "title": "LangGraphInput", "type": "object"}'
|
||||
# ---
|
||||
@@ -104,8 +15,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -117,8 +28,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "left"
|
||||
@@ -130,8 +41,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "right"
|
||||
@@ -193,8 +104,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -206,8 +117,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "get_weather"
|
||||
@@ -249,8 +160,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -262,8 +173,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "A"
|
||||
@@ -275,8 +186,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "B"
|
||||
@@ -327,8 +238,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -340,8 +251,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "human"
|
||||
@@ -353,8 +264,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "agent"
|
||||
@@ -406,8 +317,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -461,8 +372,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "__start__"
|
||||
@@ -474,8 +385,8 @@
|
||||
"data": {
|
||||
"id": [
|
||||
"langgraph",
|
||||
"utils",
|
||||
"runnable",
|
||||
"_internal",
|
||||
"_runnable",
|
||||
"RunnableCallable"
|
||||
],
|
||||
"name": "worker_node"
|
||||
@@ -767,8 +678,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': '__start__',
|
||||
@@ -780,8 +691,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'tool_one',
|
||||
@@ -793,8 +704,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'tool_three',
|
||||
@@ -809,8 +720,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'tool_two:__start__',
|
||||
@@ -822,8 +733,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'tool_two:tool_two_slow',
|
||||
@@ -835,8 +746,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'tool_two:tool_two_fast',
|
||||
@@ -1020,8 +931,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': '__start__',
|
||||
@@ -1033,8 +944,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'ask_question',
|
||||
@@ -1046,8 +957,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'answer_question',
|
||||
@@ -1087,8 +998,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': '__start__',
|
||||
@@ -1100,8 +1011,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'generate_analysts',
|
||||
@@ -1126,8 +1037,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'generate_sections',
|
||||
@@ -1185,8 +1096,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': '__start__',
|
||||
@@ -1198,8 +1109,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'generate_analysts',
|
||||
@@ -1211,8 +1122,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'generate_sections',
|
||||
@@ -1227,8 +1138,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'conduct_interview:__start__',
|
||||
@@ -1240,8 +1151,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'conduct_interview:ask_question',
|
||||
@@ -1253,8 +1164,8 @@
|
||||
'data': dict({
|
||||
'id': list([
|
||||
'langgraph',
|
||||
'utils',
|
||||
'runnable',
|
||||
'_internal',
|
||||
'_runnable',
|
||||
'RunnableCallable',
|
||||
]),
|
||||
'name': 'conduct_interview:answer_question',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from langgraph.constants import PULL, PUSH
|
||||
from langgraph.pregel.algo import prepare_next_tasks, task_path_str
|
||||
from langgraph.pregel.checkpoint import channels_from_checkpoint, empty_checkpoint
|
||||
from langgraph.pregel._algo import prepare_next_tasks, task_path_str
|
||||
from langgraph.pregel._checkpoint import channels_from_checkpoint, empty_checkpoint
|
||||
|
||||
|
||||
def test_prepare_next_tasks() -> None:
|
||||
|
||||
@@ -7,11 +7,11 @@ from typing import Annotated, Literal, Optional, Union
|
||||
import pytest
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langgraph._internal._config import patch_configurable
|
||||
from langgraph.checkpoint.base import BaseCheckpointSaver, CheckpointTuple
|
||||
from langgraph.graph.state import StateGraph
|
||||
from langgraph.pregel.checkpoint import copy_checkpoint
|
||||
from langgraph.pregel._checkpoint import copy_checkpoint
|
||||
from langgraph.types import Command, Interrupt, PregelTask, StateSnapshot, interrupt
|
||||
from langgraph.utils.config import patch_configurable
|
||||
from tests.any_int import AnyInt
|
||||
from tests.any_str import AnyDict, AnyObject, AnyStr
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
from langchain_core.callbacks import AsyncCallbackManager
|
||||
|
||||
from langgraph.utils.config import get_async_callback_manager_for_config
|
||||
from langgraph._internal._config import get_async_callback_manager_for_config
|
||||
|
||||
pytestmark = pytest.mark.anyio
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing_extensions import TypedDict
|
||||
from langgraph.func import entrypoint, task
|
||||
from langgraph.graph import StateGraph
|
||||
from langgraph.types import RetryPolicy
|
||||
from langgraph.warnings import LangGraphDeprecatedSinceV05
|
||||
from langgraph.warnings import LangGraphDeprecatedSinceV05, LangGraphDeprecatedSinceV10
|
||||
|
||||
|
||||
class PlainState(TypedDict): ...
|
||||
@@ -66,3 +66,25 @@ def test_add_node_input_schema() -> None:
|
||||
match="`input` is deprecated and will be removed. Please use `input_schema` instead.",
|
||||
):
|
||||
builder.add_node("test_node", lambda state: state, input=PlainState) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def test_constants_deprecation() -> None:
|
||||
with pytest.warns(
|
||||
LangGraphDeprecatedSinceV10,
|
||||
match="Importing Send from langgraph.constants is deprecated. Please use 'from langgraph.types import Send' instead.",
|
||||
):
|
||||
from langgraph.constants import Send # noqa: F401
|
||||
|
||||
with pytest.warns(
|
||||
LangGraphDeprecatedSinceV10,
|
||||
match="Importing Interrupt from langgraph.constants is deprecated. Please use 'from langgraph.types import Interrupt' instead.",
|
||||
):
|
||||
from langgraph.constants import Interrupt # noqa: F401
|
||||
|
||||
|
||||
def test_pregel_deprecation() -> None:
|
||||
with pytest.warns(
|
||||
LangGraphDeprecatedSinceV10,
|
||||
match="Importing from langgraph.pregel.types is deprecated. Please use 'from langgraph.types import ...' instead.",
|
||||
):
|
||||
from langgraph.pregel.types import StateSnapshot # noqa: F401
|
||||
|
||||
@@ -43,27 +43,26 @@ from langgraph.checkpoint.base import (
|
||||
from langgraph.checkpoint.memory import InMemorySaver
|
||||
from langgraph.config import get_stream_writer
|
||||
from langgraph.constants import CONFIG_KEY_NODE_FINISHED, ERROR, PULL, START
|
||||
from langgraph.errors import InvalidUpdateError, ParentCommand
|
||||
from langgraph.errors import GraphRecursionError, InvalidUpdateError, ParentCommand
|
||||
from langgraph.func import entrypoint, task
|
||||
from langgraph.graph import END, StateGraph
|
||||
from langgraph.graph.message import MessageGraph, MessagesState, add_messages
|
||||
from langgraph.prebuilt.tool_node import ToolNode
|
||||
from langgraph.pregel import (
|
||||
GraphRecursionError,
|
||||
NodeBuilder,
|
||||
Pregel,
|
||||
StateSnapshot,
|
||||
)
|
||||
from langgraph.pregel.loop import SyncPregelLoop
|
||||
from langgraph.pregel.retry import RetryPolicy
|
||||
from langgraph.pregel.runner import PregelRunner
|
||||
from langgraph.pregel._loop import SyncPregelLoop
|
||||
from langgraph.pregel._runner import PregelRunner
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import (
|
||||
CachePolicy,
|
||||
Command,
|
||||
Interrupt,
|
||||
PregelTask,
|
||||
RetryPolicy,
|
||||
Send,
|
||||
StateSnapshot,
|
||||
StateUpdate,
|
||||
StreamWriter,
|
||||
interrupt,
|
||||
|
||||
@@ -42,22 +42,28 @@ from langgraph.checkpoint.base import (
|
||||
from langgraph.checkpoint.memory import InMemorySaver
|
||||
from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer
|
||||
from langgraph.constants import CONFIG_KEY_NODE_FINISHED, ERROR, PULL, START
|
||||
from langgraph.errors import InvalidUpdateError, NodeInterrupt, ParentCommand
|
||||
from langgraph.errors import (
|
||||
GraphRecursionError,
|
||||
InvalidUpdateError,
|
||||
NodeInterrupt,
|
||||
ParentCommand,
|
||||
)
|
||||
from langgraph.func import entrypoint, task
|
||||
from langgraph.graph import END, StateGraph
|
||||
from langgraph.graph.message import MessagesState, add_messages
|
||||
from langgraph.prebuilt.tool_node import ToolNode
|
||||
from langgraph.pregel import GraphRecursionError, NodeBuilder, Pregel, StateSnapshot
|
||||
from langgraph.pregel.loop import AsyncPregelLoop
|
||||
from langgraph.pregel.retry import RetryPolicy
|
||||
from langgraph.pregel.runner import PregelRunner
|
||||
from langgraph.pregel import NodeBuilder, Pregel
|
||||
from langgraph.pregel._loop import AsyncPregelLoop
|
||||
from langgraph.pregel._runner import PregelRunner
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import (
|
||||
CachePolicy,
|
||||
Command,
|
||||
Interrupt,
|
||||
PregelTask,
|
||||
RetryPolicy,
|
||||
Send,
|
||||
StateSnapshot,
|
||||
StateUpdate,
|
||||
StreamWriter,
|
||||
interrupt,
|
||||
@@ -8381,7 +8387,7 @@ async def test_draw_invalid():
|
||||
"id": "__start__",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": ["langgraph", "utils", "runnable", "RunnableCallable"],
|
||||
"id": ["langgraph", "_internal", "_runnable", "RunnableCallable"],
|
||||
"name": "__start__",
|
||||
},
|
||||
},
|
||||
@@ -8389,7 +8395,7 @@ async def test_draw_invalid():
|
||||
"id": "agent",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": ["langgraph", "utils", "runnable", "RunnableCallable"],
|
||||
"id": ["langgraph", "_internal", "_runnable", "RunnableCallable"],
|
||||
"name": "agent",
|
||||
},
|
||||
},
|
||||
@@ -8397,7 +8403,7 @@ async def test_draw_invalid():
|
||||
"id": "tool",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": ["langgraph", "utils", "runnable", "RunnableCallable"],
|
||||
"id": ["langgraph", "_internal", "_runnable", "RunnableCallable"],
|
||||
"name": "tool",
|
||||
},
|
||||
},
|
||||
@@ -8405,7 +8411,7 @@ async def test_draw_invalid():
|
||||
"id": "nothing",
|
||||
"type": "runnable",
|
||||
"data": {
|
||||
"id": ["langgraph", "utils", "runnable", "RunnableCallable"],
|
||||
"id": ["langgraph", "_internal", "_runnable", "RunnableCallable"],
|
||||
"name": "nothing",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -21,9 +21,9 @@ from pydantic import (
|
||||
model_validator,
|
||||
)
|
||||
|
||||
from langgraph._internal._pydantic import is_supported_by_pydantic
|
||||
from langgraph.constants import END, START
|
||||
from langgraph.graph.state import StateGraph
|
||||
from langgraph.utils.pydantic import is_supported_by_pydantic
|
||||
|
||||
|
||||
def test_is_supported_by_pydantic() -> None:
|
||||
|
||||
@@ -15,8 +15,7 @@ from langgraph.errors import GraphInterrupt
|
||||
from langgraph.graph import StateGraph, add_messages
|
||||
from langgraph.pregel import Pregel
|
||||
from langgraph.pregel.remote import RemoteGraph
|
||||
from langgraph.pregel.types import StateSnapshot
|
||||
from langgraph.types import Interrupt
|
||||
from langgraph.types import Interrupt, StateSnapshot
|
||||
from tests.conftest import NO_DOCKER
|
||||
from tests.example_app.example_graph import app
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import pytest
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langgraph.graph import START, StateGraph
|
||||
from langgraph.pregel.retry import _should_retry_on
|
||||
from langgraph.pregel._retry import _should_retry_on
|
||||
from langgraph.types import RetryPolicy
|
||||
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ from typing import Any, Optional
|
||||
|
||||
import pytest
|
||||
|
||||
from langgraph._internal._runnable import RunnableCallable
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import StreamWriter
|
||||
from langgraph.utils.runnable import RunnableCallable
|
||||
|
||||
pytestmark = pytest.mark.anyio
|
||||
|
||||
@@ -85,7 +85,7 @@ def test_runnable_callable_injectable_arguments() -> None:
|
||||
"""
|
||||
|
||||
# Test Optional[BaseStore] annotation.
|
||||
def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP007
|
||||
def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP045
|
||||
"""Test function that accepts an optional store parameter."""
|
||||
assert store is None
|
||||
return "success"
|
||||
@@ -159,7 +159,7 @@ async def test_runnable_callable_injectable_arguments_async() -> None:
|
||||
"""
|
||||
|
||||
# Test Optional[BaseStore] annotation.
|
||||
def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP007
|
||||
def func_optional_store(inputs: Any, store: Optional[BaseStore]) -> str: # noqa: UP045
|
||||
"""Test function that accepts an optional store parameter."""
|
||||
assert store is None
|
||||
return "success"
|
||||
|
||||
@@ -17,18 +17,18 @@ import langsmith
|
||||
import pytest
|
||||
from typing_extensions import NotRequired, Required, TypedDict
|
||||
|
||||
from langgraph.graph import END, StateGraph
|
||||
from langgraph.graph.state import CompiledStateGraph
|
||||
from langgraph.utils.config import _is_not_empty
|
||||
from langgraph.utils.fields import (
|
||||
from langgraph._internal._config import _is_not_empty
|
||||
from langgraph._internal._fields import (
|
||||
_is_optional_type,
|
||||
get_enhanced_type_hints,
|
||||
get_field_default,
|
||||
)
|
||||
from langgraph.utils.runnable import (
|
||||
from langgraph._internal._runnable import (
|
||||
is_async_callable,
|
||||
is_async_generator,
|
||||
)
|
||||
from langgraph.graph import END, StateGraph
|
||||
from langgraph.graph.state import CompiledStateGraph
|
||||
|
||||
pytestmark = pytest.mark.anyio
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# import for backwards compatibility
|
||||
from langgraph._internal._runnable import RunnableCallable, RunnableSeq # noqa: F401
|
||||
Generated
+414
-395
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,7 @@ from langchain_core.tools import BaseTool
|
||||
from pydantic import BaseModel
|
||||
from typing_extensions import Annotated, TypedDict
|
||||
|
||||
from langgraph._internal._runnable import RunnableCallable, RunnableLike
|
||||
from langgraph.errors import ErrorCode, create_error_message
|
||||
from langgraph.graph import END, StateGraph
|
||||
from langgraph.graph.message import add_messages
|
||||
@@ -42,7 +43,6 @@ from langgraph.managed import IsLastStep, RemainingSteps
|
||||
from langgraph.prebuilt.tool_node import ToolNode
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import Checkpointer, Send
|
||||
from langgraph.utils.runnable import RunnableCallable, RunnableLike
|
||||
|
||||
StructuredResponse = Union[dict, BaseModel]
|
||||
StructuredResponseSchema = Union[dict, type[BaseModel]]
|
||||
|
||||
@@ -37,10 +37,10 @@ from langchain_core.tools.base import (
|
||||
from pydantic import BaseModel
|
||||
from typing_extensions import Annotated, get_args, get_origin
|
||||
|
||||
from langgraph._internal._runnable import RunnableCallable
|
||||
from langgraph.errors import GraphBubbleUp
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.types import Command, Send
|
||||
from langgraph.utils.runnable import RunnableCallable
|
||||
|
||||
INVALID_TOOL_NAME_ERROR_TEMPLATE = (
|
||||
"Error: {requested_tool} is not a valid tool, try one of [{available_tools}]."
|
||||
|
||||
@@ -34,7 +34,7 @@ from pydantic import BaseModel, ValidationError
|
||||
from pydantic.v1 import BaseModel as BaseModelV1
|
||||
from pydantic.v1 import ValidationError as ValidationErrorV1
|
||||
|
||||
from langgraph.utils.runnable import RunnableCallable
|
||||
from langgraph._internal._runnable import RunnableCallable
|
||||
|
||||
|
||||
def _default_format_error(
|
||||
|
||||
@@ -15,7 +15,7 @@ from langgraph.checkpoint.base import (
|
||||
SerializerProtocol,
|
||||
)
|
||||
from langgraph.checkpoint.memory import InMemorySaver, PersistentDict
|
||||
from langgraph.pregel.checkpoint import copy_checkpoint
|
||||
from langgraph.pregel._checkpoint import copy_checkpoint
|
||||
|
||||
|
||||
class NoopSerializer(SerializerProtocol):
|
||||
|
||||
@@ -29,6 +29,7 @@ from pydantic.v1 import BaseModel as BaseModelV1
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from langgraph.checkpoint.base import BaseCheckpointSaver
|
||||
from langgraph.config import get_stream_writer
|
||||
from langgraph.graph import START, MessagesState, StateGraph, add_messages
|
||||
from langgraph.graph.message import REMOVE_ALL_MESSAGES
|
||||
from langgraph.prebuilt import (
|
||||
@@ -53,7 +54,6 @@ from langgraph.prebuilt.tool_node import (
|
||||
from langgraph.store.base import BaseStore
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
from langgraph.types import Command, Interrupt, interrupt
|
||||
from langgraph.utils.config import get_stream_writer
|
||||
from tests.any_str import AnyStr
|
||||
from tests.messages import _AnyIdHumanMessage, _AnyIdToolMessage
|
||||
from tests.model import FakeToolCallingModel
|
||||
|
||||
Reference in New Issue
Block a user