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-08-19 17:59:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-langchain-core (Old)
and /work/SRC/openSUSE:Factory/.python-langchain-core.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-langchain-core"
Wed Aug 19 17:59:19 2026 rev:10 rq:1371930 version:1.5.6
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-langchain-core/python-langchain-core.changes
2026-08-18 16:38:06.368415594 +0200
+++
/work/SRC/openSUSE:Factory/.python-langchain-core.new.1258/python-langchain-core.changes
2026-08-19 18:01:20.303493035 +0200
@@ -1,0 +2,7 @@
+Wed Aug 19 07:25:38 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to version 1.5.6:
+ * Incorporate gateway metadata into traces when the client
+ response provides it
+
+-------------------------------------------------------------------
Old:
----
langchain_core-1.5.5.tar.gz
New:
----
langchain_core-1.5.6.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-langchain-core.spec ++++++
--- /var/tmp/diff_new_pack.SiHhIb/_old 2026-08-19 18:01:20.985517555 +0200
+++ /var/tmp/diff_new_pack.SiHhIb/_new 2026-08-19 18:01:20.987517626 +0200
@@ -17,7 +17,7 @@
Name: python-langchain-core
-Version: 1.5.5
+Version: 1.5.6
Release: 0
Summary: Building applications with LLMs through composability
License: MIT
++++++ langchain_core-1.5.5.tar.gz -> langchain_core-1.5.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.5.5/PKG-INFO
new/langchain_core-1.5.6/PKG-INFO
--- old/langchain_core-1.5.5/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.6/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.5
Name: langchain-core
-Version: 1.5.5
+Version: 1.5.6
Summary: Building applications with LLMs through composability
Project-URL: Homepage, https://docs.langchain.com/
Project-URL: Documentation,
https://reference.langchain.com/python/langchain_core/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.5.5/langchain_core/language_models/chat_models.py
new/langchain_core-1.5.6/langchain_core/language_models/chat_models.py
--- old/langchain_core-1.5.5/langchain_core/language_models/chat_models.py
2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.6/langchain_core/language_models/chat_models.py
2020-02-02 01:00:00.000000000 +0100
@@ -87,6 +87,7 @@
_StreamingCallbackHandler,
_V2StreamingCallbackHandler,
)
+from langchain_core.utils._gateway import GATEWAY_METADATA_RESPONSE_KEY
from langchain_core.utils.function_calling import (
convert_to_json_schema,
convert_to_openai_tool,
@@ -2693,8 +2694,17 @@
def _gen_info_and_msg_metadata(
generation: ChatGeneration | ChatGenerationChunk,
) -> dict[str, Any]:
+ """Extract metadata for the response metadata.
+
+ Removes GATEWAY_METADATA from the generation info.
+ """
+ generation_info = generation.generation_info or {}
return {
- **(generation.generation_info or {}),
+ **{
+ key: value
+ for key, value in generation_info.items()
+ if key != GATEWAY_METADATA_RESPONSE_KEY
+ },
**generation.message.response_metadata,
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.5.5/langchain_core/tracers/core.py
new/langchain_core-1.5.6/langchain_core/tracers/core.py
--- old/langchain_core-1.5.5/langchain_core/tracers/core.py 2020-02-02
01:00:00.000000000 +0100
+++ new/langchain_core-1.5.6/langchain_core/tracers/core.py 2020-02-02
01:00:00.000000000 +0100
@@ -16,6 +16,7 @@
from langchain_core.exceptions import TracerException
from langchain_core.load import dumpd
from langchain_core.tracers.schemas import Run
+from langchain_core.utils._gateway import GATEWAY_METADATA_RESPONSE_KEY
if TYPE_CHECKING:
from collections.abc import Coroutine, Sequence
@@ -36,6 +37,31 @@
SCHEMA_FORMAT_TYPE = Literal["original", "streaming_events"]
+# Key under which gateway metadata is attached to a run's metadata for tracing.
+_GATEWAY_RUN_METADATA_KEY = "ls_gateway_info"
+
+
+def _extract_gateway_metadata(response: LLMResult) -> dict[str, Any] | None:
+ """Extract LangSmith gateway metadata from a model response.
+
+ When a request is routed through the LangSmith gateway, the gateway returns
+ metadata (e.g. the resolved provider and model) that integrations surface
on
+ the generation's `generation_info` under `GATEWAY_METADATA_RESPONSE_KEY`.
+
+ Args:
+ response: The `LLMResult` produced by the model.
+
+ Returns:
+ The gateway metadata, or `None` if the response carries none.
+ """
+ for generations in response.generations:
+ for generation in generations:
+ generation_info = getattr(generation, "generation_info", None) or
{}
+ gateway_metadata =
generation_info.get(GATEWAY_METADATA_RESPONSE_KEY)
+ if isinstance(gateway_metadata, dict):
+ return gateway_metadata
+ return None
+
class _TracerCore(ABC):
"""Abstract base class for tracers.
@@ -319,8 +345,18 @@
if tool_call_count > 0:
llm_run.extra["tool_call_count"] = tool_call_count
+ self._attach_gateway_metadata(llm_run, response)
+
return llm_run
+ def _attach_gateway_metadata(self, run: Run, response: LLMResult) -> None:
+ """Promote LangSmith gateway metadata from the response to run
metadata."""
+ gateway_metadata = _extract_gateway_metadata(response)
+ if gateway_metadata is None:
+ return
+ metadata = run.extra.setdefault("metadata", {})
+ metadata[_GATEWAY_RUN_METADATA_KEY] = gateway_metadata
+
def _errored_llm_run(
self, error: BaseException, run_id: UUID, response: LLMResult | None =
None
) -> Run:
@@ -340,6 +376,7 @@
output_generation["message"] = dumpd(
cast("ChatGeneration", generation).message
)
+ self._attach_gateway_metadata(llm_run, response)
llm_run.end_time = datetime.now(timezone.utc)
llm_run.events.append({"name": "error", "time": llm_run.end_time})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.5.5/langchain_core/utils/_gateway.py
new/langchain_core-1.5.6/langchain_core/utils/_gateway.py
--- old/langchain_core-1.5.5/langchain_core/utils/_gateway.py 2020-02-02
01:00:00.000000000 +0100
+++ new/langchain_core-1.5.6/langchain_core/utils/_gateway.py 2020-02-02
01:00:00.000000000 +0100
@@ -10,7 +10,9 @@
from __future__ import annotations
+import json
import os
+from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, NamedTuple
from pydantic import SecretStr
@@ -20,6 +22,16 @@
from pydantic import BaseModel
+# Key under which integrations place parsed gateway metadata on a generation's
+# `generation_info`. This is the contract consumed by the LangSmith tracer,
which
+# promotes it to run metadata. Defined here so integrations and the tracer
agree
+# on a single name.
+GATEWAY_METADATA_RESPONSE_KEY = "lc_gateway_metadata"
+
+# HTTP response header the LangSmith gateway uses to return per-request
metadata
+# (e.g. the resolved provider and model). The value is JSON-encoded.
+GATEWAY_METADATA_HEADER = "X-LangSmith-Gateway-Metadata"
+
_LANGSMITH_GATEWAY_ENV = "LANGSMITH_GATEWAY"
_LANGSMITH_GATEWAY_API_KEY_ENV = "LANGSMITH_GATEWAY_API_KEY"
_LANGSMITH_API_KEY_ENV = "LANGSMITH_API_KEY"
@@ -233,3 +245,30 @@
if config.api_key is not None:
values[api_key_field] = config.api_key
return config
+
+
+def _parse_gateway_metadata(headers: Any) -> dict[str, Any] | None:
+ """Parse LangSmith gateway metadata from HTTP response headers.
+
+ Provider integrations call this on the raw response headers so the parsed
+ result can be surfaced under `GATEWAY_METADATA_RESPONSE_KEY` and later
+ promoted to run metadata by the LangSmith tracer.
+
+ Args:
+ headers: The response headers.
+
+ Returns:
+ The deserialized gateway metadata, or None when the header is absent,
+ not a mapping, or not a JSON object.
+ """
+ if not isinstance(headers, Mapping):
+ return None
+
+ raw = headers.get(GATEWAY_METADATA_HEADER)
+ if not raw:
+ return None
+ try:
+ parsed = json.loads(raw)
+ except (json.JSONDecodeError, TypeError):
+ return None
+ return parsed if isinstance(parsed, dict) else None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.5.5/langchain_core/version.py
new/langchain_core-1.5.6/langchain_core/version.py
--- old/langchain_core-1.5.5/langchain_core/version.py 2020-02-02
01:00:00.000000000 +0100
+++ new/langchain_core-1.5.6/langchain_core/version.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,3 +1,3 @@
"""Version information for `langchain-core`."""
-VERSION = "1.5.5"
+VERSION = "1.5.6"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.5.5/pyproject.toml
new/langchain_core-1.5.6/pyproject.toml
--- old/langchain_core-1.5.5/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
+++ new/langchain_core-1.5.6/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
@@ -21,7 +21,7 @@
"Topic :: Software Development :: Libraries :: Python Modules",
]
-version = "1.5.5"
+version = "1.5.6"
requires-python = ">=3.10.0,<4.0.0"
dependencies = [
"langsmith>=0.3.45,<1.0.0",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.5.5/tests/unit_tests/runnables/__snapshots__/test_fallbacks.ambr
new/langchain_core-1.5.6/tests/unit_tests/runnables/__snapshots__/test_fallbacks.ambr
---
old/langchain_core-1.5.5/tests/unit_tests/runnables/__snapshots__/test_fallbacks.ambr
2020-02-02 01:00:00.000000000 +0100
+++
new/langchain_core-1.5.6/tests/unit_tests/runnables/__snapshots__/test_fallbacks.ambr
2020-02-02 01:00:00.000000000 +0100
@@ -84,7 +84,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['foo'], i=1)",
+ "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['foo'], i=1)",
"name": "FakeListLLM"
}
},
@@ -128,7 +128,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['bar'])",
+ "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['bar'])",
"name": "FakeListLLM"
}
},
@@ -268,7 +268,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['foo'], i=1)",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['foo'], i=1)",
"name": "FakeListLLM"
},
"fallbacks": [
@@ -281,7 +281,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['bar'])",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['bar'])",
"name": "FakeListLLM"
}
],
@@ -322,7 +322,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['foo'], i=1)",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['foo'], i=1)",
"name": "FakeListLLM"
},
"fallbacks": [
@@ -335,7 +335,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['baz'], i=1)",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['baz'], i=1)",
"name": "FakeListLLM"
},
{
@@ -347,7 +347,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['bar'])",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['bar'])",
"name": "FakeListLLM"
}
],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.5.5/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr
new/langchain_core-1.5.6/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr
---
old/langchain_core-1.5.5/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr
2020-02-02 01:00:00.000000000 +0100
+++
new/langchain_core-1.5.6/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr
2020-02-02 01:00:00.000000000 +0100
@@ -97,7 +97,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['foo, bar'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['foo, bar'])",
"name": "FakeListChatModel"
}
],
@@ -227,7 +227,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['baz, qux'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['baz, qux'])",
"name": "FakeListChatModel"
}
],
@@ -346,7 +346,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['foo, bar'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['foo, bar'])",
"name": "FakeListChatModel"
},
{
@@ -457,7 +457,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['baz, qux'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['baz, qux'])",
"name": "FakeListChatModel"
}
],
@@ -848,7 +848,7 @@
"fake",
"FakeStreamingListLLM"
],
- "repr": "FakeStreamingListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['first item, second item, third
item'])",
+ "repr": "FakeStreamingListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['first item, second item, third
item'])",
"name": "FakeStreamingListLLM"
},
{
@@ -884,7 +884,7 @@
"fake",
"FakeStreamingListLLM"
],
- "repr": "FakeStreamingListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['this', 'is', 'a', 'test'])",
+ "repr": "FakeStreamingListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['this', 'is', 'a', 'test'])",
"name": "FakeStreamingListLLM"
}
},
@@ -1009,7 +1009,7 @@
# name: test_prompt_with_chat_model
'''
ChatPromptTemplate(input_variables=['question'], input_types={},
partial_variables={},
messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[],
input_types={}, partial_variables={}, template='You are a nice assistant.'),
additional_kwargs={}),
HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['question'],
input_types={}, partial_variables={}, template='{question}'),
additional_kwargs={})])
- | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.5'}},
responses=['foo'])
+ | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.6'}},
responses=['foo'])
'''
# ---
# name: test_prompt_with_chat_model.1
@@ -1109,7 +1109,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['foo'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['foo'])",
"name": "FakeListChatModel"
}
},
@@ -1220,7 +1220,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['foo, bar'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['foo, bar'])",
"name": "FakeListChatModel"
}
],
@@ -1249,7 +1249,7 @@
# name: test_prompt_with_chat_model_async
'''
ChatPromptTemplate(input_variables=['question'], input_types={},
partial_variables={},
messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[],
input_types={}, partial_variables={}, template='You are a nice assistant.'),
additional_kwargs={}),
HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['question'],
input_types={}, partial_variables={}, template='{question}'),
additional_kwargs={})])
- | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.5'}},
responses=['foo'])
+ | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.6'}},
responses=['foo'])
'''
# ---
# name: test_prompt_with_chat_model_async.1
@@ -1349,7 +1349,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['foo'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['foo'])",
"name": "FakeListChatModel"
}
},
@@ -1459,7 +1459,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['foo', 'bar'])",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['foo', 'bar'])",
"name": "FakeListLLM"
}
},
@@ -1576,7 +1576,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=['foo', 'bar'])",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=['foo', 'bar'])",
"name": "FakeListLLM"
}
],
@@ -1699,7 +1699,7 @@
"fake",
"FakeStreamingListLLM"
],
- "repr": "FakeStreamingListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['bear, dog, cat', 'tomato, lettuce,
onion'])",
+ "repr": "FakeStreamingListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['bear, dog, cat', 'tomato, lettuce,
onion'])",
"name": "FakeStreamingListLLM"
}
],
@@ -1867,7 +1867,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['4'])",
+ "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['4'])",
"name": "FakeListLLM"
}
},
@@ -1940,7 +1940,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['2'])",
+ "repr": "FakeListLLM(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['2'])",
"name": "FakeListLLM"
}
},
@@ -13407,7 +13407,7 @@
just_to_test_lambda: RunnableLambda(...)
}
| ChatPromptTemplate(input_variables=['documents', 'question'],
input_types={}, partial_variables={},
messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[],
input_types={}, partial_variables={}, template='You are a nice assistant.'),
additional_kwargs={}),
HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['documents',
'question'], input_types={}, partial_variables={},
template='Context:\n{documents}\n\nQuestion:\n{question}'),
additional_kwargs={})])
- | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.5'}},
responses=['foo, bar'])
+ | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.6'}},
responses=['foo, bar'])
| CommaSeparatedListOutputParser()
'''
# ---
@@ -13610,7 +13610,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=['foo, bar'])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=['foo, bar'])",
"name": "FakeListChatModel"
}
],
@@ -13636,8 +13636,8 @@
ChatPromptTemplate(input_variables=['question'], input_types={},
partial_variables={},
messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[],
input_types={}, partial_variables={}, template='You are a nice assistant.'),
additional_kwargs={}),
HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['question'],
input_types={}, partial_variables={}, template='{question}'),
additional_kwargs={})])
| RunnableLambda(...)
| {
- chat: FakeListChatModel(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=["i'm a chatbot"]),
- llm: FakeListLLM(metadata={'lc_versions': {'langchain-core': '1.5.5'}},
responses=["i'm a textbot"])
+ chat: FakeListChatModel(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=["i'm a chatbot"]),
+ llm: FakeListLLM(metadata={'lc_versions': {'langchain-core': '1.5.6'}},
responses=["i'm a textbot"])
}
'''
# ---
@@ -13762,7 +13762,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=[\"i'm a chatbot\"])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=[\"i'm a chatbot\"])",
"name": "FakeListChatModel"
},
"llm": {
@@ -13774,7 +13774,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=[\"i'm a textbot\"])",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=[\"i'm a textbot\"])",
"name": "FakeListLLM"
}
}
@@ -13917,7 +13917,7 @@
"fake_chat_models",
"FakeListChatModel"
],
- "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.5'}}, responses=[\"i'm a chatbot\"])",
+ "repr": "FakeListChatModel(metadata={'lc_versions':
{'langchain-core': '1.5.6'}}, responses=[\"i'm a chatbot\"])",
"name": "FakeListChatModel"
},
"kwargs": {
@@ -13938,7 +13938,7 @@
"fake",
"FakeListLLM"
],
- "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.5'}}, responses=[\"i'm a textbot\"])",
+ "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core':
'1.5.6'}}, responses=[\"i'm a textbot\"])",
"name": "FakeListLLM"
},
"passthrough": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.5.5/tests/unit_tests/tracers/test_automatic_metadata.py
new/langchain_core-1.5.6/tests/unit_tests/tracers/test_automatic_metadata.py
---
old/langchain_core-1.5.5/tests/unit_tests/tracers/test_automatic_metadata.py
2020-02-02 01:00:00.000000000 +0100
+++
new/langchain_core-1.5.6/tests/unit_tests/tracers/test_automatic_metadata.py
2020-02-02 01:00:00.000000000 +0100
@@ -9,6 +9,7 @@
from langchain_core.outputs import ChatGeneration, LLMResult
from langchain_core.tracers.core import _TracerCore
from langchain_core.tracers.schemas import Run
+from langchain_core.utils._gateway import GATEWAY_METADATA_RESPONSE_KEY
class MockTracerCore(_TracerCore):
@@ -153,3 +154,79 @@
completed_run = tracer._complete_llm_run(response=response, run_id=run.id)
assert "tool_call_count" not in completed_run.extra
+
+
+def _make_run(run_id: str) -> Run:
+ run = MagicMock(spec=Run)
+ run.id = run_id
+ run.run_type = "llm"
+ run.extra = {}
+ run.outputs = {}
+ run.events = []
+ run.end_time = None
+ run.inputs = {}
+ return run
+
+
+def test_complete_llm_run_attaches_gateway_metadata() -> None:
+ """Gateway metadata on `generation_info` is promoted to run metadata."""
+ tracer = MockTracerCore()
+ run = _make_run("test-gateway-run-id")
+ tracer.run_map[str(run.id)] = run
+
+ gateway_info = {"provider": "openai", "model": "gpt-5.6-sol"}
+ message = AIMessage(content="Test")
+ response = LLMResult(
+ generations=[
+ [
+ ChatGeneration(
+ message=message,
+ generation_info={GATEWAY_METADATA_RESPONSE_KEY:
gateway_info},
+ )
+ ]
+ ]
+ )
+
+ completed_run = tracer._complete_llm_run(response=response, run_id=run.id)
+
+ assert completed_run.extra["metadata"]["ls_gateway_info"] == gateway_info
+
+
+def test_complete_llm_run_no_gateway_metadata() -> None:
+ """No gateway metadata is attached when the response carries none."""
+ tracer = MockTracerCore()
+ run = _make_run("test-no-gateway-run-id")
+ tracer.run_map[str(run.id)] = run
+
+ message = AIMessage(content="Test", response_metadata={"model_provider":
"openai"})
+ response = LLMResult(generations=[[ChatGeneration(message=message)]])
+
+ completed_run = tracer._complete_llm_run(response=response, run_id=run.id)
+
+ assert "metadata" not in completed_run.extra
+
+
+def test_errored_llm_run_attaches_gateway_metadata() -> None:
+ """Gateway metadata is attached on the error path too."""
+ tracer = MockTracerCore()
+ run = _make_run("test-gateway-error-run-id")
+ tracer.run_map[str(run.id)] = run
+
+ gateway_info = {"error": "rate_limit_exceeded"}
+ message = AIMessage(content="")
+ response = LLMResult(
+ generations=[
+ [
+ ChatGeneration(
+ message=message,
+ generation_info={GATEWAY_METADATA_RESPONSE_KEY:
gateway_info},
+ )
+ ]
+ ]
+ )
+
+ errored_run = tracer._errored_llm_run(
+ error=ValueError("boom"), run_id=run.id, response=response
+ )
+
+ assert errored_run.extra["metadata"]["ls_gateway_info"] == gateway_info
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/langchain_core-1.5.5/tests/unit_tests/utils/test_gateway.py
new/langchain_core-1.5.6/tests/unit_tests/utils/test_gateway.py
--- old/langchain_core-1.5.5/tests/unit_tests/utils/test_gateway.py
2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.6/tests/unit_tests/utils/test_gateway.py
2020-02-02 01:00:00.000000000 +0100
@@ -8,6 +8,7 @@
from langchain_core.utils._gateway import (
GatewayConfig,
_apply_gateway_config,
+ _parse_gateway_metadata,
_resolve_gateway_base_url,
_resolve_gateway_config,
)
@@ -316,3 +317,17 @@
values, config = _apply({})
assert "api_key" not in values
assert config.api_key is None
+
+
+def test_parse_gateway_metadata_deserializes_json() -> None:
+ headers = {"X-LangSmith-Gateway-Metadata": '{"provider": "openai"}'}
+ assert _parse_gateway_metadata(headers) == {"provider": "openai"}
+
+
+def test_parse_gateway_metadata_absent() -> None:
+ assert _parse_gateway_metadata({"content-type": "application/json"}) is
None
+
+
+def test_parse_gateway_metadata_non_json() -> None:
+ headers = {"X-LangSmith-Gateway-Metadata": "not-json"}
+ assert _parse_gateway_metadata(headers) is None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/langchain_core-1.5.5/uv.lock
new/langchain_core-1.5.6/uv.lock
--- old/langchain_core-1.5.5/uv.lock 2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.6/uv.lock 2020-02-02 01:00:00.000000000 +0100
@@ -1040,7 +1040,7 @@
[[package]]
name = "langchain-core"
-version = "1.5.5"
+version = "1.5.6"
source = { editable = "." }
dependencies = [
{ name = "httpx" },