Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: internal doc nits #2946

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions libs/langgraph/langgraph/graph/graph.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import asyncio

Check notice on line 1 in libs/langgraph/langgraph/graph/graph.py

View workflow job for this annotation

GitHub Actions / benchmark

Benchmark results

......................................... fanout_to_subgraph_10x: Mean +- std dev: 62.3 ms +- 1.1 ms ......................................... fanout_to_subgraph_10x_sync: Mean +- std dev: 54.1 ms +- 0.8 ms ......................................... fanout_to_subgraph_10x_checkpoint: Mean +- std dev: 75.8 ms +- 1.1 ms ......................................... fanout_to_subgraph_10x_checkpoint_sync: Mean +- std dev: 97.1 ms +- 1.1 ms ......................................... fanout_to_subgraph_100x: Mean +- std dev: 640 ms +- 32 ms ......................................... fanout_to_subgraph_100x_sync: Mean +- std dev: 532 ms +- 16 ms ......................................... fanout_to_subgraph_100x_checkpoint: Mean +- std dev: 809 ms +- 26 ms ......................................... fanout_to_subgraph_100x_checkpoint_sync: Mean +- std dev: 984 ms +- 21 ms ......................................... react_agent_10x: Mean +- std dev: 31.1 ms +- 0.7 ms ......................................... react_agent_10x_sync: Mean +- std dev: 23.2 ms +- 0.5 ms ......................................... react_agent_10x_checkpoint: Mean +- std dev: 38.8 ms +- 0.9 ms ......................................... react_agent_10x_checkpoint_sync: Mean +- std dev: 37.2 ms +- 0.4 ms ......................................... react_agent_100x: Mean +- std dev: 346 ms +- 7 ms ......................................... react_agent_100x_sync: Mean +- std dev: 277 ms +- 4 ms ......................................... react_agent_100x_checkpoint: Mean +- std dev: 658 ms +- 10 ms ......................................... react_agent_100x_checkpoint_sync: Mean +- std dev: 637 ms +- 12 ms ......................................... wide_state_25x300: Mean +- std dev: 23.7 ms +- 0.5 ms ......................................... wide_state_25x300_sync: Mean +- std dev: 15.5 ms +- 0.2 ms ......................................... wide_state_25x300_checkpoint: Mean +- std dev: 253 ms +- 14 ms ......................................... wide_state_25x300_checkpoint_sync: Mean +- std dev: 248 ms +- 14 ms ......................................... wide_state_15x600: Mean +- std dev: 27.7 ms +- 0.6 ms ......................................... wide_state_15x600_sync: Mean +- std dev: 17.9 ms +- 0.2 ms ......................................... wide_state_15x600_checkpoint: Mean +- std dev: 434 ms +- 15 ms ......................................... wide_state_15x600_checkpoint_sync: Mean +- std dev: 431 ms +- 15 ms ......................................... wide_state_9x1200: Mean +- std dev: 27.7 ms +- 0.6 ms ......................................... wide_state_9x1200_sync: Mean +- std dev: 17.9 ms +- 0.2 ms ......................................... wide_state_9x1200_checkpoint: Mean +- std dev: 284 ms +- 15 ms ......................................... wide_state_9x1200_checkpoint_sync: Mean +- std dev: 279 ms +- 15 ms

Check notice on line 1 in libs/langgraph/langgraph/graph/graph.py

View workflow job for this annotation

GitHub Actions / benchmark

Comparison against main

+-----------------------------------------+---------+-----------------------+ | Benchmark | main | changes | +=========================================+=========+=======================+ | react_agent_10x | 30.8 ms | 31.1 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_25x300 | 23.4 ms | 23.7 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_15x600_sync | 17.8 ms | 17.9 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_9x1200_sync | 17.7 ms | 17.9 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_9x1200 | 27.4 ms | 27.7 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_15x600_checkpoint | 429 ms | 434 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | react_agent_100x | 342 ms | 346 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | react_agent_10x_checkpoint | 38.3 ms | 38.8 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_15x600_checkpoint_sync | 425 ms | 431 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_10x | 61.4 ms | 62.3 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_25x300_sync | 15.3 ms | 15.5 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | react_agent_10x_checkpoint_sync | 36.7 ms | 37.2 ms: 1.01x slower | +-----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_10x_sync | 53.3 ms | 54.1 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | react_agent_10x_sync | 22.9 ms | 23.2 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_25x300_checkpoint | 249 ms | 253 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_10x_checkpoint | 74.6 ms | 75.8 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_15x600 | 27.3 ms | 27.7 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_9x1200_checkpoint_sync | 275 ms | 279 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | wide_state_9x1200_checkpoint | 279 ms | 284 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_10x_checkpoint_sync | 95.1 ms | 97.1 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | react_agent_100x_sync | 271 ms | 277 ms: 1.02x slower | +-----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_100x_checkpoint_sync | 959 ms | 984 ms: 1.03x slower | +-----------------------------------------+---------+-----------------------+ | react_agent_100x_checkpoint_sync | 621 ms | 637 ms: 1.03x slower | +-----------------------------------------+---------+-----------------------+ | fanout_to_subgraph_100x_sync | 518 ms | 532 ms: 1.03x slower | +-----------------------------------------+---------+-----------------------+ | react_agent_100x_checkpoint | 634 ms | 658 ms: 1.04x slower | +---------------------------------------
import logging
from collections import defaultdict
from typing import (
Expand Down Expand Up @@ -257,7 +257,7 @@
selected by `path`.

Returns:
None
Self: The instance of the graph, allowing for method chaining.

Note: Without typehints on the `path` function's return value (e.g., `-> Literal["foo", "__end__"]:`)
or a path_map, the graph visualization assumes the edge could transition to any node in the graph.
Expand Down Expand Up @@ -308,7 +308,7 @@
key (str): The key of the node to set as the entry point.

Returns:
None
Self: The instance of the graph, allowing for method chaining.
"""
return self.add_edge(START, key)

Expand All @@ -334,7 +334,7 @@
selected by `path`.

Returns:
None
Self: The instance of the graph, allowing for method chaining.
"""
return self.add_conditional_edges(START, path, path_map, then)

Expand All @@ -347,7 +347,7 @@
key (str): The key of the node to set as the finish point.

Returns:
None
Self: The instance of the graph, allowing for method chaining.
"""
return self.add_edge(key, END)

Expand Down
13 changes: 6 additions & 7 deletions libs/langgraph/langgraph/graph/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ class StateGraph(Graph):
config_schema (Optional[Type[Any]]): The schema class that defines the configuration.
Use this to expose configurable parameters in your API.


Examples:
>>> from langchain_core.runnables import RunnableConfig
>>> from typing_extensions import Annotated, TypedDict
Expand Down Expand Up @@ -243,7 +242,7 @@ def add_node(
ValueError: If the key is already being used as a state key.

Returns:
StateGraph
Self: The instance of the state graph, allowing for method chaining.
"""
...

Expand All @@ -267,7 +266,7 @@ def add_node(
ValueError: If the key is already being used as a state key.

Returns:
StateGraph
Self: The instance of the state graph, allowing for method chaining.
"""
...

Expand All @@ -290,10 +289,10 @@ def add_node(
metadata (Optional[dict[str, Any]]): The metadata associated with the node. (default: None)
input (Optional[Type[Any]]): The input schema for the node. (default: the graph's input schema)
retry (Optional[RetryPolicy]): The policy for retrying the node. (default: None)

Raises:
ValueError: If the key is already being used as a state key.


Examples:
```pycon
>>> from langgraph.graph import START, StateGraph
Expand All @@ -320,7 +319,7 @@ def add_node(
```

Returns:
StateGraph
Self: The instance of the state graph, allowing for method chaining.
"""
if not isinstance(node, str):
action = node
Expand Down Expand Up @@ -410,7 +409,7 @@ def add_edge(self, start_key: Union[str, list[str]], end_key: str) -> Self:
ValueError: If the start key is 'END' or if the start key or end key is not present in the graph.

Returns:
StateGraph
Self: The instance of the state graph, allowing for method chaining.
"""
if isinstance(start_key, str):
return super().add_edge(start_key, end_key)
Expand Down Expand Up @@ -449,7 +448,7 @@ def add_sequence(
ValueError: if the sequence contains duplicate node names.

Returns:
StateGraph
Self: The instance of the state graph, allowing for method chaining.
"""
if len(nodes) < 1:
raise ValueError("Sequence requires at least one node.")
Expand Down
6 changes: 3 additions & 3 deletions libs/langgraph/langgraph/pregel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1652,10 +1652,10 @@ def get_waiter() -> concurrent.futures.Future[None]:
else:
get_waiter = None # type: ignore[assignment]
# Similarly to Bulk Synchronous Parallel / Pregel model
# computation proceeds in steps, while there are channel updates
# channel updates from step N are only visible in step N+1
# computation proceeds in steps, while there are channel updates.
# Channel updates from step N are only visible in step N+1
# channels are guaranteed to be immutable for the duration of the step,
# with channel updates applied only at the transition between steps
# with channel updates applied only at the transition between steps.
while loop.tick(input_keys=self.input_channels):
for _ in runner.tick(
loop.tasks.values(),
Expand Down
9 changes: 4 additions & 5 deletions libs/langgraph/langgraph/pregel/call.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Utility to convert a user provided function into a Runnable with a ChannelWrite."""
import sys
import types
from typing import Any, Callable, Optional
Expand All @@ -6,11 +7,9 @@
from langgraph.pregel.write import ChannelWrite, ChannelWriteEntry
from langgraph.utils.runnable import RunnableSeq, coerce_to_runnable

"""
Utilities borrowed from cloudpickle.
https://github.com/cloudpipe/cloudpickle/blob/6220b0ce83ffee5e47e06770a1ee38ca9e47c850/cloudpickle/cloudpickle.py#L265
"""

##
# Utilities borrowed from cloudpickle.
# https://github.com/cloudpipe/cloudpickle/blob/6220b0ce83ffee5e47e06770a1ee38ca9e47c850/cloudpickle/cloudpickle.py#L265

def _getattribute(obj: Any, name: str) -> Any:
for subpath in name.split("."):
Expand Down
7 changes: 5 additions & 2 deletions libs/langgraph/langgraph/pregel/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class BackgroundExecutor(ContextManager):
def __init__(self, config: RunnableConfig) -> None:
self.stack = ExitStack()
self.executor = self.stack.enter_context(get_executor_for_config(config))
# mapping of Future to (__cancel_on_exit__, __reraise_on_exit__) flags
self.tasks: dict[concurrent.futures.Future, tuple[bool, bool]] = {}

def submit( # type: ignore[valid-type]
Expand All @@ -68,10 +69,12 @@ def submit( # type: ignore[valid-type]
else:
task = self.executor.submit(fn, *args, **kwargs)
self.tasks[task] = (__cancel_on_exit__, __reraise_on_exit__)
# add a callback to remove the task from the tasks dict when it's done
task.add_done_callback(self.done)
return task

def done(self, task: concurrent.futures.Future) -> None:
"""Remove the task from the tasks dict when it's done."""
try:
task.result()
except GraphBubbleUp:
Expand Down Expand Up @@ -103,9 +106,9 @@ def __exit__(
concurrent.futures.wait(pending)
# shutdown the executor
self.stack.__exit__(exc_type, exc_value, traceback)
# re-raise the first exception that occurred in a task
# if there's already an exception being raised, don't raise another one
if exc_type is None:
# if there's already an exception being raised, don't raise another one
# re-raise the first exception that occurred in a task
for task, (_, reraise) in tasks.items():
if not reraise:
continue
Expand Down
8 changes: 7 additions & 1 deletion libs/langgraph/langgraph/pregel/loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,13 @@ def tick(
input_keys: Union[str, Sequence[str]],
) -> bool:
"""Execute a single iteration of the Pregel loop.
Returns True if more iterations are needed."""

Args:
input_keys: The key(s) to read input from.

Returns:
True if more iterations are needed.
"""
if self.status != "pending":
raise RuntimeError("Cannot tick when status is no longer 'pending'")

Expand Down
11 changes: 6 additions & 5 deletions libs/langgraph/langgraph/utils/runnable.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,21 +298,22 @@ def coerce_to_runnable(


class RunnableSeq(Runnable):
"""A simpler version of RunnableSequence."""
"""Sequence of Runnables, where the output of each is the input of the next.

RunnableSeq is a simpler version of RunnableSequence that is internal to
LangGraph.
"""

def __init__(
self,
*steps: RunnableLike,
name: Optional[str] = None,
) -> None:
"""Create a new RunnableSequence.
"""Create a new RunnableSeq.

Args:
steps: The steps to include in the sequence.
name: The name of the Runnable. Defaults to None.
first: The first Runnable in the sequence. Defaults to None.
middle: The middle Runnables in the sequence. Defaults to None.
last: The last Runnable in the sequence. Defaults to None.

Raises:
ValueError: If the sequence has less than 2 steps.
Expand Down
Loading