diff --git a/libs/langgraph/langgraph/_internal/_config.py b/libs/langgraph/langgraph/_internal/_config.py index 4e9c5aa92..d6fae9b06 100644 --- a/libs/langgraph/langgraph/_internal/_config.py +++ b/libs/langgraph/langgraph/_internal/_config.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections import ChainMap -from collections.abc import Mapping, Sequence +from collections.abc import Sequence from os import getenv from typing import Any, cast @@ -217,14 +217,16 @@ def get_callback_manager_for_config( callbacks.add_tags(all_tags) if metadata := config.get("metadata"): callbacks.add_metadata(metadata) - return callbacks + manager = callbacks else: # otherwise create a new manager - return CallbackManager.configure( + manager = CallbackManager.configure( inheritable_callbacks=config.get("callbacks"), inheritable_tags=all_tags, inheritable_metadata=config.get("metadata"), + langsmith_inheritable_metadata=_get_tracing_metadata_defaults(config), ) + return manager def get_async_callback_manager_for_config( @@ -255,14 +257,16 @@ def get_async_callback_manager_for_config( callbacks.add_tags(all_tags) if metadata := config.get("metadata"): callbacks.add_metadata(metadata) - return callbacks + manager = callbacks else: # otherwise create a new manager - return AsyncCallbackManager.configure( + manager = AsyncCallbackManager.configure( inheritable_callbacks=config.get("callbacks"), inheritable_tags=all_tags, inheritable_metadata=config.get("metadata"), + langsmith_inheritable_metadata=_get_tracing_metadata_defaults(config), ) + return manager def _is_not_empty(value: Any) -> bool: @@ -308,22 +312,54 @@ def ensure_config(*configs: RunnableConfig | None) -> RunnableConfig: for k, v in config.items(): if _is_not_empty(v) and k not in CONFIG_KEYS: empty[CONF][k] = v - _empty_metadata = empty["metadata"] - for key, value in empty[CONF].items(): - if _exclude_as_metadata(key, value, _empty_metadata): - continue - _empty_metadata[key] = value + + configurable = empty.get("configurable") + metadata = empty.get("metadata") + if configurable and metadata is not None: + for key in _PROPAGATE_TO_METADATA: + if key in metadata: + continue + value = configurable.get(key) + if value: + metadata[key] = value return empty _OMIT = ("key", "token", "secret", "password", "auth") -def _exclude_as_metadata(key: str, value: Any, metadata: Mapping[str, Any]) -> bool: +def _exclude_as_metadata(key: str, value: Any) -> bool: key_lower = key.casefold() return ( key.startswith("__") or not isinstance(value, (str, int, float, bool)) - or key in metadata or any(substr in key_lower for substr in _OMIT) ) + + +def _get_tracing_metadata_defaults( + config: RunnableConfig, +) -> dict[str, Any] | None: + """Get tracer-only metadata defaults from configurable values.""" + configurable = config.get("configurable") + if not configurable: + return None + metadata: dict[str, Any] = {} + for key, value in configurable.items(): + if _exclude_as_metadata(key, value): + continue + metadata[key] = value + return metadata or None + + +_PROPAGATE_TO_METADATA = frozenset( + ( + "thread_id", + "checkpoint_id", + "checkpoint_ns", + "task_id", + "run_id", + "assistant_id", + "graph_id", + ) +) diff --git a/libs/langgraph/langgraph/pregel/_messages.py b/libs/langgraph/langgraph/pregel/_messages.py index acab06098..6cda6b0a1 100644 --- a/libs/langgraph/langgraph/pregel/_messages.py +++ b/libs/langgraph/langgraph/pregel/_messages.py @@ -14,7 +14,7 @@ from langchain_core.messages import BaseMessage from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, LLMResult from pydantic import BaseModel -from langgraph._internal._constants import NS_SEP +from langgraph._internal._constants import NS_END, NS_SEP from langgraph.constants import TAG_HIDDEN, TAG_NOSTREAM from langgraph.pregel.protocol import StreamChunk from langgraph.types import Command @@ -132,15 +132,23 @@ class StreamMessagesHandler(BaseCallbackHandler, _StreamingCallbackHandler): **kwargs: Any, ) -> Any: if metadata and (not tags or (TAG_NOSTREAM not in tags)): - ns = tuple(cast(str, metadata["langgraph_checkpoint_ns"]).split(NS_SEP))[ - :-1 - ] + task_checkpoint_ns = cast(str, metadata["langgraph_checkpoint_ns"]) + checkpoint_ns = ( + f"{task_checkpoint_ns.rsplit(NS_END, 1)[0]}{NS_END}" + if NS_END in task_checkpoint_ns + else task_checkpoint_ns + ) + ns = tuple(task_checkpoint_ns.split(NS_SEP))[:-1] if not self.subgraphs and len(ns) > 0 and ns != self.parent_ns: return + stream_metadata = dict(metadata) + stream_metadata["langgraph_checkpoint_ns"] = checkpoint_ns + # Preserve backwards-compatible streamed checkpoint metadata shape. + stream_metadata["checkpoint_ns"] = checkpoint_ns if tags: if filtered_tags := [t for t in tags if not t.startswith("seq:step")]: - metadata["tags"] = filtered_tags - self.metadata[run_id] = (ns, metadata) + stream_metadata["tags"] = filtered_tags + self.metadata[run_id] = (ns, stream_metadata) def on_llm_new_token( self, diff --git a/libs/langgraph/pyproject.toml b/libs/langgraph/pyproject.toml index 6e4378c0c..e10d7da59 100644 --- a/libs/langgraph/pyproject.toml +++ b/libs/langgraph/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ 'Programming Language :: Python :: 3.13', ] dependencies = [ - "langchain-core>=0.1", + "langchain-core==1.3.0a2", "langgraph-checkpoint>=2.1.0,<5.0.0", "langgraph-sdk>=0.3.0,<0.4.0", "langgraph-prebuilt>=1.0.9,<1.1.0", diff --git a/libs/langgraph/tests/test_large_cases.py b/libs/langgraph/tests/test_large_cases.py index eedc191e1..bd2b780a0 100644 --- a/libs/langgraph/tests/test_large_cases.py +++ b/libs/langgraph/tests/test_large_cases.py @@ -1396,7 +1396,6 @@ def test_prebuilt_tool_chat(snapshot: SnapshotAssertion) -> None: "langgraph_path": (PULL, "agent"), "langgraph_checkpoint_ns": AnyStr("agent:"), "checkpoint_ns": AnyStr("agent:"), - "_type": "generic-fake-chat-model", "ls_provider": "fakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -1459,7 +1458,6 @@ def test_prebuilt_tool_chat(snapshot: SnapshotAssertion) -> None: "langgraph_path": (PULL, "agent"), "langgraph_checkpoint_ns": AnyStr("agent:"), "checkpoint_ns": AnyStr("agent:"), - "_type": "generic-fake-chat-model", "ls_provider": "fakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -1512,7 +1510,6 @@ def test_prebuilt_tool_chat(snapshot: SnapshotAssertion) -> None: "langgraph_path": (PULL, "agent"), "langgraph_checkpoint_ns": AnyStr("agent:"), "checkpoint_ns": AnyStr("agent:"), - "_type": "generic-fake-chat-model", "ls_provider": "fakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -6884,7 +6881,6 @@ def test_weather_subgraph( "langgraph_path": ("__pregel_pull", "router_node"), "langgraph_checkpoint_ns": AnyStr("router_node:"), "checkpoint_ns": AnyStr("router_node:"), - "_type": "fake-messages-list-chat-model", "ls_provider": "fakemessageslistchatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -6912,7 +6908,6 @@ def test_weather_subgraph( "langgraph_path": ("__pregel_pull", "model_node"), "langgraph_checkpoint_ns": AnyStr("weather_graph:"), "checkpoint_ns": AnyStr("weather_graph:"), - "_type": "fake-messages-list-chat-model", "ls_provider": "fakemessageslistchatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -6949,7 +6944,6 @@ def test_weather_subgraph( "langgraph_path": ("__pregel_pull", "router_node"), "langgraph_checkpoint_ns": AnyStr("router_node:"), "checkpoint_ns": AnyStr("router_node:"), - "_type": "fake-messages-list-chat-model", "ls_provider": "fakemessageslistchatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", diff --git a/libs/langgraph/tests/test_large_cases_async.py b/libs/langgraph/tests/test_large_cases_async.py index de35044f4..2455333ab 100644 --- a/libs/langgraph/tests/test_large_cases_async.py +++ b/libs/langgraph/tests/test_large_cases_async.py @@ -1147,7 +1147,6 @@ async def test_prebuilt_tool_chat() -> None: "langgraph_path": (PULL, "agent"), "langgraph_checkpoint_ns": AnyStr("agent:"), "checkpoint_ns": AnyStr("agent:"), - "_type": "generic-fake-chat-model", "ls_provider": "fakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -1210,7 +1209,6 @@ async def test_prebuilt_tool_chat() -> None: "langgraph_path": (PULL, "agent"), "langgraph_checkpoint_ns": AnyStr("agent:"), "checkpoint_ns": AnyStr("agent:"), - "_type": "generic-fake-chat-model", "ls_provider": "fakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -1263,7 +1261,6 @@ async def test_prebuilt_tool_chat() -> None: "langgraph_path": (PULL, "agent"), "langgraph_checkpoint_ns": AnyStr("agent:"), "checkpoint_ns": AnyStr("agent:"), - "_type": "generic-fake-chat-model", "ls_provider": "fakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -3981,7 +3978,6 @@ async def test_weather_subgraph( "langgraph_path": ("__pregel_pull", "router_node"), "langgraph_checkpoint_ns": AnyStr("router_node:"), "checkpoint_ns": AnyStr("router_node:"), - "_type": "fake-messages-list-chat-model", "ls_provider": "fakemessageslistchatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -4009,7 +4005,6 @@ async def test_weather_subgraph( "langgraph_path": ("__pregel_pull", "model_node"), "langgraph_checkpoint_ns": AnyStr("weather_graph:"), "checkpoint_ns": AnyStr("weather_graph:"), - "_type": "fake-messages-list-chat-model", "ls_provider": "fakemessageslistchatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -4046,7 +4041,6 @@ async def test_weather_subgraph( "langgraph_path": ("__pregel_pull", "router_node"), "langgraph_checkpoint_ns": AnyStr("router_node:"), "checkpoint_ns": AnyStr("router_node:"), - "_type": "fake-messages-list-chat-model", "ls_provider": "fakemessageslistchatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", diff --git a/libs/langgraph/tests/test_pregel.py b/libs/langgraph/tests/test_pregel.py index ad18f7843..f84f85c37 100644 --- a/libs/langgraph/tests/test_pregel.py +++ b/libs/langgraph/tests/test_pregel.py @@ -6893,7 +6893,6 @@ def test_tags_stream_mode_messages() -> None: "langgraph_path": ("__pregel_pull", "call_model"), "langgraph_checkpoint_ns": AnyStr("call_model:"), "checkpoint_ns": AnyStr("call_model:"), - "_type": "generic-fake-chat-model", "ls_provider": "genericfakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -6903,6 +6902,60 @@ def test_tags_stream_mode_messages() -> None: ] +def test_configurable_propagates_to_stream_metadata() -> None: + """Regression: thread_id, run_id, assistant_id, graph_id, + and langgraph_auth_user_id from configurable must appear + in stream_mode='messages' metadata.""" + + def my_node(state): + return {"messages": HumanMessage(content="hello")} + + graph = ( + StateGraph(MessagesState) + .add_node("my_node", my_node) + .add_edge(START, "my_node") + .compile() + ) + + config = { + "configurable": { + "thread_id": "th-123", + "checkpoint_id": "ckpt-1", + "checkpoint_ns": "ns-1", + "task_id": "task-1", + "run_id": "run-456", + "assistant_id": "asst-789", + "graph_id": "graph-0", + "model": "gpt-4o", + "user_id": "uid-1", + "cron_id": "cron-1", + "langgraph_auth_user_id": "user-1", + # these should NOT be propagated into metadata + "some_api_key": "secret", + "custom_setting": {"nested": True}, + }, + } + results = list(graph.stream({"messages": []}, config, stream_mode="messages")) + assert len(results) == 1 + _, metadata = results[0] + # propagated keys + assert metadata["thread_id"] == "th-123" + assert metadata["checkpoint_id"] == "ckpt-1" + assert metadata["checkpoint_ns"] == "ns-1" + assert metadata["task_id"] == "task-1" + assert metadata["run_id"] == "run-456" + assert metadata["assistant_id"] == "asst-789" + assert metadata["graph_id"] == "graph-0" + # These are only present in trace metadata by default as of langgraph 1.2 + # assert metadata["model"] == "gpt-4o" + # assert metadata["user_id"] == "uid-1" + # assert metadata["cron_id"] == "cron-1" + # assert metadata["langgraph_auth_user_id"] == "user-1" + # non-allowlisted keys must not appear + assert "some_api_key" not in metadata + assert "custom_setting" not in metadata + + def test_stream_mode_messages_command() -> None: from langchain_core.messages import HumanMessage diff --git a/libs/langgraph/tests/test_pregel_async.py b/libs/langgraph/tests/test_pregel_async.py index 5e4710a81..efb3bbfc1 100644 --- a/libs/langgraph/tests/test_pregel_async.py +++ b/libs/langgraph/tests/test_pregel_async.py @@ -20,6 +20,7 @@ from uuid import UUID import pytest from langchain_core.language_models import GenericFakeChatModel +from langchain_core.messages import HumanMessage from langchain_core.runnables import RunnableConfig, RunnableLambda, RunnablePassthrough from langchain_core.utils.aiter import aclosing from langgraph.cache.base import BaseCache @@ -7541,7 +7542,6 @@ async def test_tags_stream_mode_messages() -> None: "langgraph_path": ("__pregel_pull", "call_model"), "langgraph_checkpoint_ns": AnyStr("call_model:"), "checkpoint_ns": AnyStr("call_model:"), - "_type": "generic-fake-chat-model", "ls_provider": "genericfakechatmodel", "ls_model_type": "chat", "ls_integration": "langchain_chat_model", @@ -7551,6 +7551,67 @@ async def test_tags_stream_mode_messages() -> None: ] +async def test_configurable_propagates_to_stream_metadata() -> None: + """Regression: thread_id, run_id, assistant_id, graph_id, + and langgraph_auth_user_id from configurable must appear + in stream_mode='messages' metadata.""" + + def my_node(state): + return {"messages": HumanMessage(content="hello")} + + graph = ( + StateGraph(MessagesState) + .add_node("my_node", my_node) + .add_edge(START, "my_node") + .compile() + ) + + config = { + "configurable": { + "thread_id": "th-123", + "checkpoint_id": "ckpt-1", + "checkpoint_ns": "ns-1", + "task_id": "task-1", + "run_id": "run-456", + "assistant_id": "asst-789", + "graph_id": "graph-0", + "model": "gpt-4o", + "user_id": "uid-1", + "cron_id": "cron-1", + "langgraph_auth_user_id": "user-1", + # these should NOT be propagated into metadata + "some_api_key": "secret", + "custom_setting": {"nested": True}, + }, + } + results = [ + chunk + async for chunk in graph.astream( + {"messages": []}, config, stream_mode="messages" + ) + ] + assert len(results) == 1 + _, metadata = results[0] + # propagated keys + assert metadata["thread_id"] == "th-123" + assert metadata["checkpoint_id"] == "ckpt-1" + assert metadata["checkpoint_ns"] == "ns-1" + assert metadata["task_id"] == "task-1" + assert metadata["run_id"] == "run-456" + assert metadata["assistant_id"] == "asst-789" + assert metadata["graph_id"] == "graph-0" + + # These will only be traced as of langgraph 1.2 and not present by default in + # metadata + # assert metadata["model"] == "gpt-4o" + # assert metadata["user_id"] == "uid-1" + # assert metadata["cron_id"] == "cron-1" + # assert metadata["langgraph_auth_user_id"] == "user-1" + # non-allowlisted keys must not appear + assert "some_api_key" not in metadata + assert "custom_setting" not in metadata + + async def test_stream_mode_messages_command() -> None: from langchain_core.messages import HumanMessage diff --git a/libs/langgraph/tests/test_utils.py b/libs/langgraph/tests/test_utils.py index c8d2bbc71..c9e6168ff 100644 --- a/libs/langgraph/tests/test_utils.py +++ b/libs/langgraph/tests/test_utils.py @@ -11,13 +11,19 @@ from typing import ( TypeVar, Union, ) -from unittest.mock import patch +from unittest.mock import MagicMock, patch import langsmith import pytest +from langchain_core.runnables import RunnableConfig +from langchain_core.tracers import LangChainTracer from typing_extensions import NotRequired, Required, TypedDict -from langgraph._internal._config import _is_not_empty, ensure_config +from langgraph._internal._config import ( + _is_not_empty, + ensure_config, + get_callback_manager_for_config, +) from langgraph._internal._fields import ( _is_optional_type, get_enhanced_type_hints, @@ -298,7 +304,7 @@ def test_is_not_empty() -> None: assert not _is_not_empty({}) -def test_configurable_metadata(): +def test_configurable_metadata() -> None: config = { "configurable": { "a-key": "foo", @@ -309,11 +315,115 @@ def test_configurable_metadata(): "andme": 42, "nested": {"foo": "bar"}, "nooverride": -2, + "thread_id": "th-123", + "checkpoint_id": "ckpt-1", + "checkpoint_ns": "ns-1", + "task_id": "task-1", + "run_id": "run-456", + "assistant_id": "asst-789", + "graph_id": "graph-0", + "model": "gpt-4o", + "user_id": "uid-1", + "cron_id": "cron-1", + "langgraph_auth_user_id": "user-1", }, "metadata": {"nooverride": 18}, } - expected = {"includeme", "andme", "nooverride"} merged = ensure_config(config) metadata = merged["metadata"] - assert metadata.keys() == expected + assert set(metadata) == { + "nooverride", + "assistant_id", + "thread_id", + "checkpoint_id", + "run_id", + "graph_id", + "checkpoint_ns", + "task_id", + } assert metadata["nooverride"] == 18 + + +def test_callback_manager_copies_whitelisted_configurable_ids_to_metadata() -> None: + config = { + "configurable": { + "thread_id": "th-123", + "checkpoint_id": "ckpt-1", + "checkpoint_ns": "ns-1", + "task_id": "task-1", + "run_id": "run-456", + "assistant_id": "asst-789", + "graph_id": "graph-0", + "model": "gpt-4o", + "user_id": "uid-1", + "cron_id": "cron-1", + "langgraph_auth_user_id": "user-1", + }, + "metadata": { + "thread_id": "from-metadata", + "nooverride": 18, + }, + } + manager = ensure_config(config) + callback_manager = get_callback_manager_for_config(manager) + assert callback_manager.metadata == { + "thread_id": "from-metadata", + "nooverride": 18, + "checkpoint_id": "ckpt-1", + "checkpoint_ns": "ns-1", + "task_id": "task-1", + "run_id": "run-456", + "assistant_id": "asst-789", + "graph_id": "graph-0", + } + + +def test_callback_manager_copies_configurable_ids_to_tracing_metadata() -> None: + tracer = LangChainTracer(client=MagicMock()) + config: RunnableConfig = { + "configurable": { + "thread_id": "th-123", + "checkpoint_id": "ckpt-1", + "checkpoint_ns": "ns-1", + "task_id": "task-1", + "run_id": "run-456", + "assistant_id": "asst-789", + "graph_id": "graph-0", + "model": "gpt-4o", + "user_id": "uid-1", + "cron_id": "cron-1", + "langgraph_auth_user_id": "user-1", + "includeme": "hi", + "andme": 42, + "__dontinclude": "bar", + "some_api_key": "secret", + "custom_setting": {"nested": True}, + }, + "metadata": { + "thread_id": "from-metadata", + "user_id": "from-metadata-user", + "includeme": "from-metadata", + }, + "callbacks": [tracer], + } + + manager = ensure_config(config) + callback_manager = get_callback_manager_for_config(manager) + handlers = callback_manager.handlers + tracers = [handler for handler in handlers if isinstance(handler, LangChainTracer)] + assert len(tracers) == 1 + tracer = tracers[0] + assert tracer.tracing_metadata == { + "checkpoint_id": "ckpt-1", + "checkpoint_ns": "ns-1", + "task_id": "task-1", + "run_id": "run-456", + "assistant_id": "asst-789", + "graph_id": "graph-0", + "model": "gpt-4o", + "cron_id": "cron-1", + "andme": 42, + "includeme": "hi", + "thread_id": "th-123", + "user_id": "uid-1", + } diff --git a/libs/langgraph/uv.lock b/libs/langgraph/uv.lock index bfb933280..1629a8623 100644 --- a/libs/langgraph/uv.lock +++ b/libs/langgraph/uv.lock @@ -1348,7 +1348,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "1.2.22" +version = "1.3.0a2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -1360,9 +1360,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "uuid-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/a3/c4cd6827a1df46c821e7214b7f7b7a28b189e6c9b84ef15c6d629c5e3179/langchain_core-1.2.22.tar.gz", hash = "sha256:8d8f726d03d3652d403da915126626bb6250747e8ba406537d849e68b9f5d058", size = 842487, upload-time = "2026-03-24T18:48:44.9Z" } +sdist = { url = "https://files.pythonhosted.org/packages/af/bc/0bff31fcaff174d86031cc713471a3e85ed4ec8e5cd95ad0217f2aced20e/langchain_core-1.3.0a2.tar.gz", hash = "sha256:52d978c84552b74b9a3f16c1fced84f9e27cc96d7a67c601925ce6cbc4ea3cf9", size = 854580, upload-time = "2026-04-13T14:37:55.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/a6/2ffacf0f1a3788f250e75d0b52a24896c413be11be3a6d42bcdf46fbea48/langchain_core-1.2.22-py3-none-any.whl", hash = "sha256:7e30d586b75918e828833b9ec1efc25465723566845dd652c277baf751e9c04b", size = 506829, upload-time = "2026-03-24T18:48:43.286Z" }, + { url = "https://files.pythonhosted.org/packages/0e/14/03c09686602567059f26af29de0c44546a83af2f2aa29925e61040e43ea2/langchain_core-1.3.0a2-py3-none-any.whl", hash = "sha256:9e929a34f0b0c6c1255e395a1de34f8626893ceb4cdae550a22a0bd18c87be54", size = 510233, upload-time = "2026-04-13T14:37:54.277Z" }, ] [[package]] @@ -1439,7 +1439,7 @@ test = [ [package.metadata] requires-dist = [ - { name = "langchain-core", specifier = ">=0.1" }, + { name = "langchain-core", specifier = "==1.3.0a2" }, { name = "langgraph-checkpoint", editable = "../checkpoint" }, { name = "langgraph-prebuilt", editable = "../prebuilt" }, { name = "langgraph-sdk", editable = "../sdk-py" }, diff --git a/libs/prebuilt/uv.lock b/libs/prebuilt/uv.lock index f6ce058cc..309af5126 100644 --- a/libs/prebuilt/uv.lock +++ b/libs/prebuilt/uv.lock @@ -249,7 +249,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "1.2.25" +version = "1.3.0a2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -261,9 +261,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "uuid-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/2a/d65de24fc9b7989137253da8973f850f3e39b4ce3e0377bc8200d6b3c189/langchain_core-1.2.25.tar.gz", hash = "sha256:77e032b96509d0eb1f6875042fdf97b7e2334a815314700c6894d9d078909b9c", size = 842347, upload-time = "2026-04-02T22:39:11.528Z" } +sdist = { url = "https://files.pythonhosted.org/packages/af/bc/0bff31fcaff174d86031cc713471a3e85ed4ec8e5cd95ad0217f2aced20e/langchain_core-1.3.0a2.tar.gz", hash = "sha256:52d978c84552b74b9a3f16c1fced84f9e27cc96d7a67c601925ce6cbc4ea3cf9", size = 854580, upload-time = "2026-04-13T14:37:55.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/0e/7b31b0249f9b9b0fc7829d5b0ee484b8f8d43c78e376e9951e2ef3eac70c/langchain_core-1.2.25-py3-none-any.whl", hash = "sha256:0c05bf395aec6d2dfa14488fd006f7bcd0540e7e89287e04f92203532a82c828", size = 506866, upload-time = "2026-04-02T22:39:10.137Z" }, + { url = "https://files.pythonhosted.org/packages/0e/14/03c09686602567059f26af29de0c44546a83af2f2aa29925e61040e43ea2/langchain_core-1.3.0a2-py3-none-any.whl", hash = "sha256:9e929a34f0b0c6c1255e395a1de34f8626893ceb4cdae550a22a0bd18c87be54", size = 510233, upload-time = "2026-04-13T14:37:54.277Z" }, ] [[package]] @@ -281,7 +281,7 @@ dependencies = [ [package.metadata] requires-dist = [ - { name = "langchain-core", specifier = ">=0.1" }, + { name = "langchain-core", specifier = "==1.3.0a2" }, { name = "langgraph-checkpoint", editable = "../checkpoint" }, { name = "langgraph-prebuilt", editable = "." }, { name = "langgraph-sdk", editable = "../sdk-py" }, diff --git a/libs/sdk-py/uv.lock b/libs/sdk-py/uv.lock index bb29f8686..94016c161 100644 --- a/libs/sdk-py/uv.lock +++ b/libs/sdk-py/uv.lock @@ -262,7 +262,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "1.2.28" +version = "1.3.0a2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonpatch" }, @@ -274,9 +274,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "uuid-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/a4/317a1a3ac1df33a64adb3670bf88bbe3b3d5baa274db6863a979db472897/langchain_core-1.2.28.tar.gz", hash = "sha256:271a3d8bd618f795fdeba112b0753980457fc90537c46a0c11998516a74dc2cb", size = 846119, upload-time = "2026-04-08T18:19:34.867Z" } +sdist = { url = "https://files.pythonhosted.org/packages/af/bc/0bff31fcaff174d86031cc713471a3e85ed4ec8e5cd95ad0217f2aced20e/langchain_core-1.3.0a2.tar.gz", hash = "sha256:52d978c84552b74b9a3f16c1fced84f9e27cc96d7a67c601925ce6cbc4ea3cf9", size = 854580, upload-time = "2026-04-13T14:37:55.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/92/32f785f077c7e898da97064f113c73fbd9ad55d1e2169cf3a391b183dedb/langchain_core-1.2.28-py3-none-any.whl", hash = "sha256:80764232581eaf8057bcefa71dbf8adc1f6a28d257ebd8b95ba9b8b452e8c6ac", size = 508727, upload-time = "2026-04-08T18:19:32.823Z" }, + { url = "https://files.pythonhosted.org/packages/0e/14/03c09686602567059f26af29de0c44546a83af2f2aa29925e61040e43ea2/langchain_core-1.3.0a2-py3-none-any.whl", hash = "sha256:9e929a34f0b0c6c1255e395a1de34f8626893ceb4cdae550a22a0bd18c87be54", size = 510233, upload-time = "2026-04-13T14:37:54.277Z" }, ] [[package]] @@ -294,7 +294,7 @@ dependencies = [ [package.metadata] requires-dist = [ - { name = "langchain-core", specifier = ">=0.1" }, + { name = "langchain-core", specifier = "==1.3.0a2" }, { name = "langgraph-checkpoint", editable = "../checkpoint" }, { name = "langgraph-prebuilt", editable = "../prebuilt" }, { name = "langgraph-sdk", editable = "." },