diff --git a/libs/langgraph/langgraph/_internal/_runnable.py b/libs/langgraph/langgraph/_internal/_runnable.py index 0c110b96f..fa11d55ae 100644 --- a/libs/langgraph/langgraph/_internal/_runnable.py +++ b/libs/langgraph/langgraph/_internal/_runnable.py @@ -142,6 +142,9 @@ ANY_TYPE = object() ASYNCIO_ACCEPTS_CONTEXT = sys.version_info >= (3, 11) +# Cache for inspect.signature results, keyed by function object +_SIGNATURE_CACHE: dict[Callable, inspect.Signature] = {} + # List of keyword arguments that can be injected into nodes / tasks / tools at runtime. # A named argument may appear multiple times if it appears with distinct types. KWARGS_CONFIG_KEYS: tuple[tuple[str, tuple[Any, ...], str, Any], ...] = ( @@ -315,7 +318,16 @@ class RunnableCallable(Runnable): raise ValueError("At least one of func or afunc must be provided.") self.func_accepts: dict[str, tuple[str, Any]] = {} - params = inspect.signature(cast(Callable, func or afunc)).parameters + target = cast(Callable, func or afunc) + try: + sig = _SIGNATURE_CACHE[target] + except (KeyError, TypeError): + sig = inspect.signature(target) + try: + _SIGNATURE_CACHE[target] = sig + except TypeError: + pass # unhashable function, skip caching + params = sig.parameters for kw, typ, runtime_key, default in KWARGS_CONFIG_KEYS: p = params.get(kw) diff --git a/libs/langgraph/langgraph/pregel/_loop.py b/libs/langgraph/langgraph/pregel/_loop.py index d1082d2d5..6e6ac5469 100644 --- a/libs/langgraph/langgraph/pregel/_loop.py +++ b/libs/langgraph/langgraph/pregel/_loop.py @@ -198,6 +198,7 @@ class PregelLoop: _migrate_checkpoint: Callable[[Checkpoint], None] | None submit: Submit channels: Mapping[str, BaseChannel] + _has_untracked_channels: bool # Futures from `checkpointer.put_writes` calls that produced delta-channel # writes. `_checkpointer_put_after_previous` drains this list (swap to a # local `futs` then reset to `[]` and wait/gather) before putting the