mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-05 09:17:47 +02:00
* Enable raising Interrupt from inside a node, add list of current interrupts to get_state * Lint * Allow multiple interrupt values in exception * Better typings * Fix some tests * Fix up * Lint * Add test * Lint * WIP stay=True * Fix tests for get_state * Remove ids * Fix step count * 999 * less fun * Undo * Update debug interface * Remove ability to pass multiple values * Undo
105 lines
3.2 KiB
Python
105 lines
3.2 KiB
Python
from dataclasses import dataclass
|
|
from typing import Any, Literal
|
|
|
|
INPUT = "__input__"
|
|
CONFIG_KEY_SEND = "__pregel_send"
|
|
CONFIG_KEY_READ = "__pregel_read"
|
|
CONFIG_KEY_CHECKPOINTER = "__pregel_checkpointer"
|
|
CONFIG_KEY_RESUMING = "__pregel_resuming"
|
|
CONFIG_KEY_TASK_ID = "__pregel_task_id"
|
|
INTERRUPT = "__interrupt__"
|
|
ERROR = "__error__"
|
|
TASKS = "__pregel_tasks"
|
|
RESERVED = {
|
|
INTERRUPT,
|
|
ERROR,
|
|
TASKS,
|
|
CONFIG_KEY_SEND,
|
|
CONFIG_KEY_READ,
|
|
CONFIG_KEY_CHECKPOINTER,
|
|
CONFIG_KEY_RESUMING,
|
|
CONFIG_KEY_TASK_ID,
|
|
INPUT,
|
|
}
|
|
TAG_HIDDEN = "langsmith:hidden"
|
|
|
|
START = "__start__"
|
|
END = "__end__"
|
|
|
|
CHECKPOINT_NAMESPACE_SEPARATOR = "|"
|
|
|
|
|
|
class Send:
|
|
"""A message or packet to send to a specific node in the graph.
|
|
|
|
The `Send` class is used within a `StateGraph`'s conditional edges to
|
|
dynamically invoke a node with a custom state at the next step.
|
|
|
|
Importantly, the sent state can differ from the core graph's state,
|
|
allowing for flexible and dynamic workflow management.
|
|
|
|
One such example is a "map-reduce" workflow where your graph invokes
|
|
the same node multiple times in parallel with different states,
|
|
before aggregating the results back into the main graph's state.
|
|
|
|
Attributes:
|
|
node (str): The name of the target node to send the message to.
|
|
arg (Any): The state or message to send to the target node.
|
|
|
|
Examples:
|
|
>>> from typing import Annotated
|
|
>>> import operator
|
|
>>> class OverallState(TypedDict):
|
|
... subjects: list[str]
|
|
... jokes: Annotated[list[str], operator.add]
|
|
...
|
|
>>> from langgraph.constants import Send
|
|
>>> from langgraph.graph import END, START
|
|
>>> def continue_to_jokes(state: OverallState):
|
|
... return [Send("generate_joke", {"subject": s}) for s in state['subjects']]
|
|
...
|
|
>>> from langgraph.graph import StateGraph
|
|
>>> builder = StateGraph(OverallState)
|
|
>>> builder.add_node("generate_joke", lambda state: {"jokes": [f"Joke about {state['subject']}"]})
|
|
>>> builder.add_conditional_edges(START, continue_to_jokes)
|
|
>>> builder.add_edge("generate_joke", END)
|
|
>>> graph = builder.compile()
|
|
>>>
|
|
>>> # Invoking with two subjects results in a generated joke for each
|
|
>>> graph.invoke({"subjects": ["cats", "dogs"]})
|
|
{'subjects': ['cats', 'dogs'], 'jokes': ['Joke about cats', 'Joke about dogs']}
|
|
"""
|
|
|
|
node: str
|
|
arg: Any
|
|
|
|
def __init__(self, /, node: str, arg: Any) -> None:
|
|
"""
|
|
Initialize a new instance of the Send class.
|
|
|
|
Args:
|
|
node (str): The name of the target node to send the message to.
|
|
arg (Any): The state or message to send to the target node.
|
|
"""
|
|
self.node = node
|
|
self.arg = arg
|
|
|
|
def __hash__(self) -> int:
|
|
return hash((self.node, self.arg))
|
|
|
|
def __repr__(self) -> str:
|
|
return f"Send(node={self.node!r}, arg={self.arg!r})"
|
|
|
|
def __eq__(self, value: object) -> bool:
|
|
return (
|
|
isinstance(value, Send)
|
|
and self.node == value.node
|
|
and self.arg == value.arg
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class Interrupt:
|
|
when: Literal["before", "during", "after"]
|
|
value: Any = None
|