Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-langchain-core for
openSUSE:Factory checked in at 2026-10-31 23:10:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-langchain-core (Old)
and /work/SRC/openSUSE:Factory/.python-langchain-core.new.1255 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-langchain-core"
Sat Oct 31 23:10:45 2026 rev:24 rq:1394130 version:1.7.3
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-langchain-core/python-langchain-core.changes
2026-10-29 22:22:36.812417300 +0100
+++
/work/SRC/openSUSE:Factory/.python-langchain-core.new.1255/python-langchain-core.changes
2026-10-31 23:13:40.821154565 +0100
@@ -1,0 +2,16 @@
+Sat Oct 31 13:45:51 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 1.7.3:
+ * New notification metadata API: add_notification_metadata
+ and get_notification_metadata
+ * Fix merge_content mutating the first message: traced output
+ no longer repeats text following a reasoning block or other
+ list content when the stream passes a later step
+ * Require python-certifi >= 2026.10.19 to exclude bundles
+ affected by compromised emSign CA keys
+ (GHSA-6q48-6c7w-9gw2); temporary direct requirement until
+ the minimum httpx enforces the same floor
+ * requires-python stays >= 3.10
+ * Spec-cleaner modernization: %files %python_files
+
+-------------------------------------------------------------------
Old:
----
langchain_core-1.7.1.tar.gz
New:
----
langchain_core-1.7.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-langchain-core.spec ++++++
--- /var/tmp/diff_new_pack.CWwDPW/_old 2026-10-31 23:13:41.503183280 +0100
+++ /var/tmp/diff_new_pack.CWwDPW/_new 2026-10-31 23:13:41.504183322 +0100
@@ -17,7 +17,7 @@
Name: python-langchain-core
-Version: 1.7.1
+Version: 1.7.3
Release: 0
Summary: Building applications with LLMs through composability
License: MIT
@@ -30,6 +30,7 @@
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-PyYAML >= 5.3
+Requires: python-certifi >= 2026.10.19
Requires: python-httpx >= 0.23.0
Requires: python-jsonpatch >= 1.33
Requires: python-langchain-protocol >= 0.0.20
@@ -43,6 +44,7 @@
# SECTION test requirements
BuildRequires: %{python_module PyYAML >= 5.3}
BuildRequires: %{python_module blockbuster}
+BuildRequires: %{python_module certifi >= 2026.10.19}
BuildRequires: %{python_module freezegun}
BuildRequires: %{python_module httpx >= 0.23.0}
BuildRequires: %{python_module jsonpatch >= 1.33}
@@ -100,7 +102,7 @@
# and already fails on slower OBS i586 workers (same fail on devel 1.5.6).
%pytest tests/unit_tests --ignore
tests/unit_tests/indexing/test_in_memory_indexer.py --ignore
tests/unit_tests/language_models/test_compat_bridge.py --ignore
tests/unit_tests/stores/test_in_memory.py --ignore
tests/unit_tests/vectorstores/test_in_memory.py --ignore
tests/unit_tests/test_ssrf_policy_transport.py --deselect
tests/unit_tests/runnables/test_graph.py::test_graph_single_runnable --deselect
tests/unit_tests/runnables/test_graph.py::test_graph_sequence --deselect
tests/unit_tests/runnables/test_graph.py::test_graph_sequence_map --deselect
tests/unit_tests/test_ssrf_protection.py::TestValidateSafeUrl::test_valid_public_https_url
--deselect
tests/unit_tests/test_ssrf_protection.py::TestValidateSafeUrl::test_valid_public_http_url
--deselect
tests/unit_tests/test_ssrf_protection.py::TestValidateSafeUrl::test_https_only_mode
--deselect
tests/unit_tests/test_ssrf_protection.py::TestIsSafeUrl::test_safe_url_returns_true
--deselect tests/unit_tests/test_ssrf_protection.py::TestSSR
FProtectedUrlType::test_valid_url_accepted --deselect
tests/unit_tests/test_ssrf_protection.py::TestRealWorldURLs::test_slack_webhook
--deselect
tests/unit_tests/test_ssrf_protection.py::TestRealWorldURLs::test_discord_webhook
--deselect
tests/unit_tests/test_ssrf_protection.py::TestRealWorldURLs::test_webhook_site
--deselect
tests/unit_tests/test_ssrf_protection.py::TestRealWorldURLs::test_ngrok_url
--deselect
tests/unit_tests/language_models/chat_models/test_benchmark.py::test_benchmark_model
-%files %{python_files}
+%files %python_files
%doc README.md
%license LICENSE
%{python_sitelib}/langchain_core
++++++ langchain_core-1.7.1.tar.gz -> langchain_core-1.7.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.7.1/PKG-INFO
new/langchain_core-1.7.3/PKG-INFO
--- old/langchain_core-1.7.1/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.5
Name: langchain-core
-Version: 1.7.1
+Version: 1.7.3
Summary: Building applications with LLMs through composability
Project-URL: Homepage, https://docs.langchain.com/
Project-URL: Documentation,
https://reference.langchain.com/python/langchain_core/
@@ -24,6 +24,7 @@
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: <4.0.0,>=3.10.0
+Requires-Dist: certifi>=2026.10.19
Requires-Dist: httpx>=0.23.0
Requires-Dist: jsonpatch>=1.33.0
Requires-Dist: langchain-protocol>=0.0.20
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.7.1/langchain_core/messages/__init__.py
new/langchain_core-1.7.3/langchain_core/messages/__init__.py
--- old/langchain_core-1.7.1/langchain_core/messages/__init__.py
2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/langchain_core/messages/__init__.py
2020-02-02 01:00:00.000000000 +0100
@@ -48,6 +48,11 @@
from langchain_core.messages.function import FunctionMessage,
FunctionMessageChunk
from langchain_core.messages.human import HumanMessage, HumanMessageChunk
from langchain_core.messages.modifier import RemoveMessage
+ from langchain_core.messages.notification import (
+ NotificationMetadata,
+ add_notification_metadata,
+ get_notification_metadata,
+ )
from langchain_core.messages.system import SystemMessage,
SystemMessageChunk
from langchain_core.messages.tool import (
ToolCall,
@@ -95,6 +100,7 @@
"MessageLikeRepresentation",
"NonStandardAnnotation",
"NonStandardContentBlock",
+ "NotificationMetadata",
"OutputTokenDetails",
"PlainTextContentBlock",
"ReasoningContentBlock",
@@ -112,6 +118,7 @@
"UsageMetadata",
"VideoContentBlock",
"_message_from_dict",
+ "add_notification_metadata",
"convert_to_messages",
"convert_to_openai_data_block",
"convert_to_openai_image_block",
@@ -119,6 +126,7 @@
"ensure_id",
"filter_messages",
"get_buffer_string",
+ "get_notification_metadata",
"is_data_content_block",
"merge_content",
"merge_message_runs",
@@ -149,6 +157,9 @@
"FunctionMessageChunk": "function",
"HumanMessage": "human",
"HumanMessageChunk": "human",
+ "NotificationMetadata": "notification",
+ "add_notification_metadata": "notification",
+ "get_notification_metadata": "notification",
"NonStandardAnnotation": "content",
"NonStandardContentBlock": "content",
"OutputTokenDetails": "ai",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.7.1/langchain_core/messages/base.py
new/langchain_core-1.7.3/langchain_core/messages/base.py
--- old/langchain_core-1.7.1/langchain_core/messages/base.py 2020-02-02
01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/langchain_core/messages/base.py 2020-02-02
01:00:00.000000000 +0100
@@ -379,6 +379,9 @@
"""
merged: str | list[str | dict[Any, Any]]
merged = "" if first_content is None else first_content
+ if isinstance(merged, list):
+ # The branches below append to it, which would change the first
message.
+ merged = merged.copy()
for content in contents:
# If current is a string
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.7.1/langchain_core/messages/notification.py
new/langchain_core-1.7.3/langchain_core/messages/notification.py
--- old/langchain_core-1.7.1/langchain_core/messages/notification.py
1970-01-01 01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/langchain_core/messages/notification.py
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,92 @@
+"""Metadata for messages the agent harness adds to a conversation."""
+
+from typing import Any
+
+from typing_extensions import NotRequired, TypedDict
+
+from langchain_core.messages.base import BaseMessage
+from langchain_core.messages.human import HumanMessage
+
+
+class NotificationMetadata(TypedDict):
+ """Which feature added a message, and that feature's fields.
+
+ !!! version-added "Added in `langchain-core` 1.7.2"
+ """
+
+ source: str
+ """The feature that added the message, e.g. `'async_subagent'`."""
+
+ data: NotRequired[dict[str, Any]]
+ """The feature's fields, documented by that feature."""
+
+
+def add_notification_metadata(
+ message: HumanMessage, *, source: str, data: dict[str, Any] | None = None
+) -> HumanMessage:
+ """Return a copy of `message` marked as added by the agent harness.
+
+ Use it for a human message the user didn't type, such as a background task
+ update or a conversation summary. It sets `additional_kwargs["lc_source"]`
+ and, when `data` is given, `additional_kwargs["lc_data"]`. Any earlier
+ `lc_source` and `lc_data` are removed first. LangChain's chat model
+ integrations don't send these keys to the model.
+
+ It doesn't change the content. Write the content the model reads yourself.
+
+ Anyone who can send input to a thread can set these keys. Don't use them to
+ decide whether to trust a message.
+
+ `merge_message_runs` and chunk addition join a notification with adjacent
+ human messages; the merged message keeps the metadata and concatenates
+ `lc_source`.
+
+ !!! version-added "Added in `langchain-core` 1.7.2"
+
+ Args:
+ message: The message to mark.
+ source: The feature that added the message.
+ data: The feature's fields. Must be JSON-serializable.
+
+ Returns:
+ A shallow copy of `message`, with the same `id`.
+
+ Example:
+ ```python
+ from langchain_core.messages import HumanMessage,
add_notification_metadata
+
+ message = add_notification_metadata(
+ HumanMessage("Background task t_42 finished."),
+ source="async_subagent",
+ data={"task_id": "t_42", "status": "success"},
+ )
+ ```
+ """
+ kwargs = {k: v for k, v in message.additional_kwargs.items() if k !=
"lc_data"}
+ kwargs["lc_source"] = source
+ if data is not None:
+ kwargs["lc_data"] = dict(data)
+ return message.model_copy(update={"additional_kwargs": kwargs})
+
+
+def get_notification_metadata(message: BaseMessage) -> NotificationMetadata |
None:
+ """Return the notification metadata of `message`.
+
+ !!! version-added "Added in `langchain-core` 1.7.2"
+
+ Args:
+ message: The message to read.
+
+ Returns:
+ The metadata `add_notification_metadata` set, or `None` for a message
+ without a string `lc_source`. `data` is a copy of `lc_data`, left
out
+ unless `lc_data` is a dict.
+ """
+ source = message.additional_kwargs.get("lc_source")
+ if not isinstance(source, str):
+ return None
+ metadata = NotificationMetadata(source=source)
+ data = message.additional_kwargs.get("lc_data")
+ if isinstance(data, dict):
+ metadata["data"] = dict(data)
+ return metadata
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.7.1/langchain_core/version.py
new/langchain_core-1.7.3/langchain_core/version.py
--- old/langchain_core-1.7.1/langchain_core/version.py 2020-02-02
01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/langchain_core/version.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,3 +1,3 @@
"""Version information for `langchain-core`."""
-VERSION = "1.7.1"
+VERSION = "1.7.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.7.1/pyproject.toml
new/langchain_core-1.7.3/pyproject.toml
--- old/langchain_core-1.7.1/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
+++ new/langchain_core-1.7.3/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
@@ -21,11 +21,13 @@
"Topic :: Software Development :: Libraries :: Python Modules",
]
-version = "1.7.1"
+version = "1.7.3"
requires-python = ">=3.10.0,<4.0.0"
dependencies = [
"langsmith>=0.14.9,<1.0.0",
"httpx>=0.23.0",
+ # Remove once our minimum httpx version requires certifi>=2026.10.19.
+ "certifi>=2026.10.19",
"tenacity!=8.4.0,>=8.1.0",
"jsonpatch>=1.33.0",
"PyYAML>=5.3.0",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.7.1/tests/unit_tests/messages/test_imports.py
new/langchain_core-1.7.3/tests/unit_tests/messages/test_imports.py
--- old/langchain_core-1.7.1/tests/unit_tests/messages/test_imports.py
2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/tests/unit_tests/messages/test_imports.py
2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,9 @@
from langchain_core.messages import __all__
EXPECTED_ALL = [
+ "NotificationMetadata",
+ "add_notification_metadata",
+ "get_notification_metadata",
"MessageLikeRepresentation",
"_message_from_dict",
"AIMessage",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.7.1/tests/unit_tests/messages/test_notification.py
new/langchain_core-1.7.3/tests/unit_tests/messages/test_notification.py
--- old/langchain_core-1.7.1/tests/unit_tests/messages/test_notification.py
1970-01-01 01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/tests/unit_tests/messages/test_notification.py
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,86 @@
+from langchain_core.messages import (
+ HumanMessage,
+ add_notification_metadata,
+ get_notification_metadata,
+ messages_from_dict,
+ messages_to_dict,
+)
+
+
+def test_metadata_is_added_to_a_copy() -> None:
+ original = HumanMessage("done", id="msg_1", additional_kwargs={"other": 1})
+
+ message = add_notification_metadata(
+ original, source="async_subagent", data={"task_id": "t_42"}
+ )
+
+ assert message.id == "msg_1"
+ assert message.content == "done"
+ assert message.additional_kwargs == {
+ "other": 1,
+ "lc_source": "async_subagent",
+ "lc_data": {"task_id": "t_42"},
+ }
+ assert original.additional_kwargs == {"other": 1}
+
+
+def test_metadata_is_read_back() -> None:
+ message = add_notification_metadata(
+ HumanMessage("done"), source="async_subagent", data={"task_id": "t_42"}
+ )
+
+ assert get_notification_metadata(message) == {
+ "source": "async_subagent",
+ "data": {"task_id": "t_42"},
+ }
+
+
+def test_marking_again_replaces_source_and_data() -> None:
+ message = add_notification_metadata(
+ HumanMessage("x"), source="first", data={"a": 1}
+ )
+
+ remarked = add_notification_metadata(message, source="second")
+
+ assert get_notification_metadata(remarked) == {"source": "second"}
+
+
+def test_data_is_copied() -> None:
+ data = {"status": "success"}
+ message = add_notification_metadata(HumanMessage("x"), source="s",
data=data)
+ data["status"] = "error"
+
+ assert get_notification_metadata(message) == {
+ "source": "s",
+ "data": {"status": "success"},
+ }
+
+
+def test_messages_without_a_string_source_have_no_metadata() -> None:
+ assert get_notification_metadata(HumanMessage("hi")) is None
+ assert (
+ get_notification_metadata(HumanMessage("x",
additional_kwargs={"lc_source": 1}))
+ is None
+ )
+
+
+def test_non_dict_data_is_left_out() -> None:
+ kwargs = {"lc_source": "s", "lc_data": "not a dict"}
+
+ assert get_notification_metadata(HumanMessage("x",
additional_kwargs=kwargs)) == {
+ "source": "s"
+ }
+
+
+def test_metadata_survives_serialization() -> None:
+ message = add_notification_metadata(
+ HumanMessage("done", id="msg_1"), source="async_subagent", data={"a":
1}
+ )
+
+ [restored] = messages_from_dict(messages_to_dict([message]))
+
+ assert restored == message
+ assert get_notification_metadata(restored) == {
+ "source": "async_subagent",
+ "data": {"a": 1},
+ }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.7.1/tests/unit_tests/runnables/test_runnable.py
new/langchain_core-1.7.3/tests/unit_tests/runnables/test_runnable.py
--- old/langchain_core-1.7.1/tests/unit_tests/runnables/test_runnable.py
2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/tests/unit_tests/runnables/test_runnable.py
2020-02-02 01:00:00.000000000 +0100
@@ -30,12 +30,14 @@
from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.callbacks.manager import (
AsyncCallbackManagerForRetrieverRun,
+ CallbackManagerForLLMRun,
CallbackManagerForRetrieverRun,
atrace_as_chain_group,
trace_as_chain_group,
)
from langchain_core.documents import Document
from langchain_core.language_models import (
+ BaseChatModel,
FakeListChatModel,
FakeListLLM,
FakeStreamingListLLM,
@@ -50,7 +52,8 @@
CommaSeparatedListOutputParser,
StrOutputParser,
)
-from langchain_core.outputs.chat_generation import ChatGeneration
+from langchain_core.outputs.chat_generation import ChatGeneration,
ChatGenerationChunk
+from langchain_core.outputs.chat_result import ChatResult
from langchain_core.outputs.llm_result import LLMResult
from langchain_core.prompt_values import ChatPromptValue, StringPromptValue
from langchain_core.prompts import (
@@ -6064,3 +6067,67 @@
schema = sequence.get_output_jsonschema()
assert set(schema["properties"]) == {"a"}
assert "a" in schema["required"]
+
+
+class _ReasonsThenAnswers(BaseChatModel):
+ @property
+ def _llm_type(self) -> str:
+ return "reasons-then-answers"
+
+ @override
+ def _generate(
+ self,
+ messages: list[BaseMessage],
+ stop: list[str] | None = None,
+ run_manager: CallbackManagerForLLMRun | None = None,
+ **kwargs: Any,
+ ) -> ChatResult:
+ raise NotImplementedError
+
+ @override
+ def _stream(
+ self,
+ messages: list[BaseMessage],
+ stop: list[str] | None = None,
+ run_manager: CallbackManagerForLLMRun | None = None,
+ **kwargs: Any,
+ ) -> Iterator[ChatGenerationChunk]:
+ yield ChatGenerationChunk(
+ message=AIMessageChunk(content=[{"type": "thinking", "thinking":
"hmm"}])
+ )
+ for text in ["Hel", "lo", " world"]:
+ yield ChatGenerationChunk(message=AIMessageChunk(content=text))
+
+
+class _ModelOutput(BaseCallbackHandler):
+ def __init__(self) -> None:
+ self.content: Any = None
+
+ @override
+ def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:
+ generation = response.generations[0][0]
+ assert isinstance(generation, ChatGeneration)
+ self.content = generation.message.content
+
+
[email protected]("use_async", [False, True])
+async def test_streaming_a_reasoning_block_then_text_adds_the_text_once(
+ *, use_async: bool
+) -> None:
+ received: list[Any] = []
+
+ def record(message: BaseMessage) -> BaseMessage:
+ received.append(message.content)
+ return message
+
+ chain = _ReasonsThenAnswers() | RunnableLambda(record)
+ model_output = _ModelOutput()
+ config: RunnableConfig = {"callbacks": [model_output]}
+ if use_async:
+ _ = [chunk async for chunk in chain.astream("hi", config)]
+ else:
+ _ = list(chain.stream("hi", config))
+
+ content = [{"type": "thinking", "thinking": "hmm"}, "Hello world"]
+ assert received == [content]
+ assert model_output.content == content
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.7.1/tests/unit_tests/test_messages.py
new/langchain_core-1.7.3/tests/unit_tests/test_messages.py
--- old/langchain_core-1.7.1/tests/unit_tests/test_messages.py 2020-02-02
01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/tests/unit_tests/test_messages.py 2020-02-02
01:00:00.000000000 +0100
@@ -1110,6 +1110,21 @@
assert actual == expected
[email protected](
+ "first",
+ [
+ [{"type": "text", "text": "a"}],
+ ["x"],
+ ],
+)
+def test_merge_content_leaves_the_first_list_unchanged(
+ first: list[str | dict[str, Any]],
+) -> None:
+ original = list(first)
+ merge_content(first, "b")
+ assert first == original
+
+
def test_tool_message_content() -> None:
ToolMessage("foo", tool_call_id="1")
ToolMessage(["foo"], tool_call_id="1")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.7.1/uv.lock
new/langchain_core-1.7.3/uv.lock
--- old/langchain_core-1.7.1/uv.lock 2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.7.3/uv.lock 2020-02-02 01:00:00.000000000 +0100
@@ -1130,9 +1130,10 @@
[[package]]
name = "langchain-core"
-version = "1.7.1"
+version = "1.7.3"
source = { editable = "." }
dependencies = [
+ { name = "certifi" },
{ name = "httpx" },
{ name = "jsonpatch" },
{ name = "langchain-protocol" },
@@ -1181,6 +1182,7 @@
[package.metadata]
requires-dist = [
+ { name = "certifi", specifier = ">=2026.10.19" },
{ name = "httpx", specifier = ">=0.23.0" },
{ name = "jsonpatch", specifier = ">=1.33.0" },
{ name = "langchain-protocol", specifier = ">=0.0.20" },