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-07-26 11:29:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-langchain-core (Old)
 and      /work/SRC/openSUSE:Factory/.python-langchain-core.new.2004 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-langchain-core"

Sun Jul 26 11:29:59 2026 rev:4 rq:1367769 version:1.5.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-langchain-core/python-langchain-core.changes  
    2026-07-21 23:10:22.078230920 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-langchain-core.new.2004/python-langchain-core.changes
    2026-07-26 11:32:37.115279587 +0200
@@ -1,0 +2,9 @@
+Sat Jul 25 19:01:38 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to version 1.5.1:
+  * Support the langsmith gateway through an environment
+    variable
+  * Use the tool_call_schema cache for BaseTool token counting
+    in count_tokens_approximately
+
+-------------------------------------------------------------------

Old:
----
  langchain_core-1.5.0.tar.gz

New:
----
  langchain_core-1.5.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-langchain-core.spec ++++++
--- /var/tmp/diff_new_pack.QdzpoD/_old  2026-07-26 11:32:37.615296811 +0200
+++ /var/tmp/diff_new_pack.QdzpoD/_new  2026-07-26 11:32:37.615296811 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-langchain-core
-Version:        1.5.0
+Version:        1.5.1
 Release:        0
 Summary:        Building applications with LLMs through composability
 License:        MIT

++++++ langchain_core-1.5.0.tar.gz -> langchain_core-1.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langchain_core-1.5.0/PKG-INFO 
new/langchain_core-1.5.1/PKG-INFO
--- old/langchain_core-1.5.0/PKG-INFO   2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.1/PKG-INFO   2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: langchain-core
-Version: 1.5.0
+Version: 1.5.1
 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.0/langchain_core/messages/utils.py 
new/langchain_core-1.5.1/langchain_core/messages/utils.py
--- old/langchain_core-1.5.0/langchain_core/messages/utils.py   2020-02-02 
01:00:00.000000000 +0100
+++ new/langchain_core-1.5.1/langchain_core/messages/utils.py   2020-02-02 
01:00:00.000000000 +0100
@@ -47,7 +47,7 @@
 from langchain_core.messages.modifier import RemoveMessage
 from langchain_core.messages.system import SystemMessage, SystemMessageChunk
 from langchain_core.messages.tool import ToolCall, ToolMessage, 
ToolMessageChunk
-from langchain_core.utils.function_calling import convert_to_openai_tool
+from langchain_core.utils.pydantic import model_json_schema as 
get_model_json_schema
 
 if TYPE_CHECKING:
     from langchain_core.language_models import BaseLanguageModel
@@ -2274,9 +2274,10 @@
             using the **most recent** AI message that has
             `usage_metadata['total_tokens']`. The scaling factor is:
             `AI_total_tokens / approx_tokens_up_to_that_AI_message`
-        tools: List of tools to include in the token count. Each tool can be 
either
-            a `BaseTool` instance or a dict representing a tool schema. 
`BaseTool`
-            instances are converted to OpenAI tool format before counting.
+        tools: List of tools to include in the token count. Each tool can be a
+            `BaseTool` instance, a dict representing a tool schema, or a plain
+            callable. `BaseTool` instances and callables are converted to
+            OpenAI tool format before counting.
 
     Returns:
         Approximate number of tokens in the messages (and tools, if provided).
@@ -2304,7 +2305,24 @@
     if tools:
         tools_chars = 0
         for tool in tools:
-            tool_dict = tool if isinstance(tool, dict) else 
convert_to_openai_tool(tool)
+            if isinstance(tool, dict):
+                tool_dict = tool
+            else:
+                # tool_call_schema is memoized per instance
+                schema = tool.tool_call_schema
+                if isinstance(schema, dict):
+                    parameters = dict(schema)
+                else:
+                    parameters = dict(get_model_json_schema(schema))
+                # Drop the schema's own `title`/`description` to avoid 
double-counting:
+                # they're duplicated at the top level.
+                parameters.pop("title", None)
+                parameters.pop("description", None)
+                tool_dict = {
+                    "name": tool.name,
+                    "description": tool.description,
+                    "parameters": parameters,
+                }
             tools_chars += len(json.dumps(tool_dict))
         token_count += math.ceil(tools_chars / chars_per_token)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/langchain_core-1.5.0/langchain_core/utils/_gateway.py 
new/langchain_core-1.5.1/langchain_core/utils/_gateway.py
--- old/langchain_core-1.5.0/langchain_core/utils/_gateway.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/langchain_core-1.5.1/langchain_core/utils/_gateway.py   2020-02-02 
01:00:00.000000000 +0100
@@ -0,0 +1,229 @@
+"""Private helpers for resolving LangSmith gateway configuration.
+
+The [LangSmith LLM gateway](https://docs.langchain.com/langsmith/llm-gateway)
+lets a chat model reach a provider through a proxy configured via environment
+variables. These helpers centralize the (non-trivial) precedence rules so that
+each provider integration resolves its base URL and API key identically.
+
+This module is private: the API is not stable and may change without notice.
+"""
+
+from __future__ import annotations
+
+import os
+from typing import TYPE_CHECKING, Any, NamedTuple
+
+from pydantic import SecretStr
+
+if TYPE_CHECKING:
+    from collections.abc import Sequence
+
+    from pydantic import BaseModel
+
+_LANGSMITH_GATEWAY_ENV = "LANGSMITH_GATEWAY"
+_LANGSMITH_GATEWAY_API_KEY_ENV = "LANGSMITH_GATEWAY_API_KEY"
+_LANGSMITH_GATEWAY_DEFAULT_BASE = "https://gateway.smith.langchain.com";
+
+_TRUE_VALUES = ("true", "1", "yes")
+_FALSE_VALUES = ("false", "0", "no")
+
+
+class GatewayConfig(NamedTuple):
+    """Resolved gateway configuration.
+
+    Attributes:
+        base_url: The base URL the client should use, or None to defer to the
+            provider SDK's own default.
+        api_key: The API key to use. A ``SecretStr`` when derived from the
+            environment; the caller's value returned unchanged when one was
+            passed explicitly; None when no key could be resolved.
+        base_url_from_gateway: Whether ``base_url`` was populated from the
+            LangSmith gateway (as opposed to an explicit value, a provider env
+            var, or a default).
+    """
+
+    base_url: str | None
+    api_key: Any
+    base_url_from_gateway: bool
+
+
+def _first_env(names: str | Sequence[str]) -> str | None:
+    """Return the first non-empty value among ``names``, or None."""
+    if isinstance(names, str):
+        names = (names,)
+    for name in names:
+        value = os.getenv(name)
+        if value:
+            return value
+    return None
+
+
+def _resolve_gateway_base_url(provider_path: str) -> str | None:
+    """Resolve the LangSmith gateway base URL for a provider.
+
+    ``LANGSMITH_GATEWAY`` accepts either a boolean-ish string or an explicit
+    base URL:
+
+    - ``true`` / ``1`` / ``yes`` -> the default gateway host.
+    - ``false`` / ``0`` / ``no`` / unset -> the gateway is disabled (None).
+    - anything else -> treated as a custom gateway base URL.
+
+    The provider-specific path is appended in all enabled cases.
+
+    Args:
+        provider_path: Path segment for the provider, e.g. ``"openai/v1"`` or
+            ``"anthropic"``.
+
+    Returns:
+        The provider base URL on the gateway, or None if the gateway is
+        disabled.
+    """
+    raw = os.getenv(_LANGSMITH_GATEWAY_ENV)
+    if raw is None or raw.lower() in _FALSE_VALUES:
+        return None
+    base = (
+        _LANGSMITH_GATEWAY_DEFAULT_BASE
+        if raw.lower() in _TRUE_VALUES
+        else raw.rstrip("/")
+    )
+    return f"{base}/{provider_path}"
+
+
+def _resolve_gateway_config(
+    *,
+    base_url: str | None,
+    api_key: Any,
+    provider_path: str,
+    base_url_env: str | Sequence[str] = (),
+    api_key_env: str | Sequence[str] = (),
+    default_base_url: str | None = None,
+) -> GatewayConfig:
+    """Resolve a provider's base URL and API key, applying gateway settings.
+
+    Precedence:
+
+    - **base_url:** explicit ``base_url`` > ``base_url_env`` > LangSmith 
gateway
+      > ``default_base_url``.
+    - **api_key:** explicit ``api_key`` (returned unchanged) > the gateway key 
if
+      the base URL came from the gateway, otherwise the provider key > the 
other.
+      The gateway key is only a candidate when the gateway is enabled.
+
+    The provenance flip on the key means an ``OPENAI_API_KEY``-style provider 
key
+    is preferred whenever the caller pointed the base URL at a non-gateway
+    endpoint (so a stray gateway key is not sent to the provider), while the
+    gateway key wins for the common "just enable the gateway" setup even if a
+    provider key happens to be present in the environment.
+
+    Args:
+        base_url: Explicitly-provided base URL (e.g. a ``base_url`` kwarg), or
+            None if not set by the caller.
+        api_key: Explicitly-provided API key, or None if not set by the caller.
+            Returned unchanged when not None, so a caller-supplied value 
(secret
+            or callable) always wins.
+        provider_path: Path segment appended to the gateway host.
+        base_url_env: Env var name(s) for the provider base URL, in priority
+            order.
+        api_key_env: Env var name(s) for the provider API key, in priority 
order.
+        default_base_url: Base URL used when nothing else is set.
+
+    Returns:
+        The resolved `GatewayConfig`.
+    """
+    gateway_base_url = _resolve_gateway_base_url(provider_path)
+
+    resolved_base_url = base_url
+    base_url_from_gateway = False
+    if resolved_base_url is None:
+        resolved_base_url = _first_env(base_url_env)
+        if resolved_base_url is None:
+            if gateway_base_url is not None:
+                resolved_base_url = gateway_base_url
+                base_url_from_gateway = True
+            else:
+                resolved_base_url = default_base_url
+
+    if api_key is not None:
+        resolved_api_key: Any = api_key
+    else:
+        gateway_api_key = (
+            os.getenv(_LANGSMITH_GATEWAY_API_KEY_ENV)
+            if gateway_base_url is not None
+            else None
+        )
+        provider_api_key = _first_env(api_key_env)
+        chosen = (
+            (gateway_api_key or provider_api_key)
+            if base_url_from_gateway
+            else (provider_api_key or gateway_api_key)
+        )
+        resolved_api_key = SecretStr(chosen) if chosen else None
+
+    return GatewayConfig(resolved_base_url, resolved_api_key, 
base_url_from_gateway)
+
+
+def _pop_provided(values: dict[str, Any], cls: type[BaseModel], field: str) -> 
Any:
+    """Pop a caller-provided field value by name or alias; None if absent.
+
+    Handles models with ``populate_by_name=True``, where a field may be 
supplied
+    under either its name or its alias. Both keys are removed so the resolved
+    value can be written back canonically under the field name. The alias is 
read
+    from the model rather than hard-coded, so callers pass only field names.
+    """
+    value = values.pop(field, None)
+    alias = cls.model_fields[field].alias
+    if alias is not None:
+        alias_value = values.pop(alias, None)
+        if value is None:
+            value = alias_value
+    return value
+
+
+def _apply_gateway_config(
+    values: dict[str, Any],
+    cls: type[BaseModel],
+    *,
+    base_url_field: str,
+    api_key_field: str,
+    provider_path: str,
+    base_url_env: str | Sequence[str] = (),
+    api_key_env: str | Sequence[str] = (),
+    default_base_url: str | None = None,
+) -> GatewayConfig:
+    """Resolve gateway settings from a model's raw input in a "before" 
validator.
+
+    Reads the caller-provided base URL and API key (by field name or alias),
+    resolves them against the gateway and provider env vars via
+    `_resolve_gateway_config`, then writes the results back into ``values`` 
under
+    the canonical field names. This lets a provider integration keep a
+    non-optional key field: the resolved value is injected before field
+    validation runs, so the field always receives a concrete value.
+
+    The resolved API key is written only when non-None, so the field's own
+    default applies when no key is found. Returns the `GatewayConfig` so the
+    caller can, for example, raise when a required key is missing.
+
+    Args:
+        values: The raw input mapping passed to the model, mutated in place.
+        cls: The model class, used to look up field aliases.
+        base_url_field: Name of the base URL field (e.g. 
``"anthropic_api_url"``).
+        api_key_field: Name of the API key field (e.g. 
``"anthropic_api_key"``).
+        provider_path: Path segment appended to the gateway host.
+        base_url_env: Env var name(s) for the provider base URL.
+        api_key_env: Env var name(s) for the provider API key.
+        default_base_url: Base URL used when nothing else is set.
+
+    Returns:
+        The resolved `GatewayConfig`.
+    """
+    config = _resolve_gateway_config(
+        base_url=_pop_provided(values, cls, base_url_field),
+        api_key=_pop_provided(values, cls, api_key_field),
+        provider_path=provider_path,
+        base_url_env=base_url_env,
+        api_key_env=api_key_env,
+        default_base_url=default_base_url,
+    )
+    values[base_url_field] = config.base_url
+    if config.api_key is not None:
+        values[api_key_field] = config.api_key
+    return config
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langchain_core-1.5.0/langchain_core/version.py 
new/langchain_core-1.5.1/langchain_core/version.py
--- old/langchain_core-1.5.0/langchain_core/version.py  2020-02-02 
01:00:00.000000000 +0100
+++ new/langchain_core-1.5.1/langchain_core/version.py  2020-02-02 
01:00:00.000000000 +0100
@@ -1,3 +1,3 @@
 """Version information for `langchain-core`."""
 
-VERSION = "1.5.0"
+VERSION = "1.5.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langchain_core-1.5.0/pyproject.toml 
new/langchain_core-1.5.1/pyproject.toml
--- old/langchain_core-1.5.0/pyproject.toml     2020-02-02 01:00:00.000000000 
+0100
+++ new/langchain_core-1.5.1/pyproject.toml     2020-02-02 01:00:00.000000000 
+0100
@@ -21,7 +21,7 @@
     "Topic :: Software Development :: Libraries :: Python Modules",
 ]
 
-version = "1.5.0"
+version = "1.5.1"
 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.0/tests/unit_tests/messages/test_utils.py 
new/langchain_core-1.5.1/tests/unit_tests/messages/test_utils.py
--- old/langchain_core-1.5.0/tests/unit_tests/messages/test_utils.py    
2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.1/tests/unit_tests/messages/test_utils.py    
2020-02-02 01:00:00.000000000 +0100
@@ -29,7 +29,7 @@
     merge_message_runs,
     trim_messages,
 )
-from langchain_core.tools import BaseTool, tool
+from langchain_core.tools import BaseTool, StructuredTool, tool
 
 
 @pytest.mark.parametrize("msg_cls", [HumanMessage, AIMessage, SystemMessage])
@@ -2961,6 +2961,33 @@
     assert count_empty_tools == base_count
 
 
+def test_count_tokens_approximately_basetool_dict_args_schema() -> None:
+    """`BaseTool.tool_call_schema` can itself already be a plain dict.
+
+    This happens when `args_schema` is given as a raw JSON schema instead of
+    a Pydantic model class -- there's no model class to call
+    `model_json_schema()` on in that case.
+    """
+    schema_dict = {
+        "title": "GetWeatherInput",
+        "type": "object",
+        "properties": {"location": {"type": "string"}},
+        "required": ["location"],
+    }
+    weather_tool = StructuredTool.from_function(
+        func=lambda location: f"Weather in {location}",
+        name="get_weather",
+        description="Get the weather for a location.",
+        args_schema=schema_dict,
+    )
+    assert isinstance(weather_tool.tool_call_schema, dict)
+
+    messages = [HumanMessage(content="Hello")]
+    base_count = count_tokens_approximately(messages)
+    count_with_tool = count_tokens_approximately(messages, 
tools=[weather_tool])
+    assert count_with_tool > base_count
+
+
 # ---------------------------------------------------------------------------
 # `Serializable` constructor-envelope wire-shape acceptance in 
`_convert_to_message`
 # ---------------------------------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/langchain_core-1.5.0/tests/unit_tests/runnables/__snapshots__/test_fallbacks.ambr
 
new/langchain_core-1.5.1/tests/unit_tests/runnables/__snapshots__/test_fallbacks.ambr
--- 
old/langchain_core-1.5.0/tests/unit_tests/runnables/__snapshots__/test_fallbacks.ambr
       2020-02-02 01:00:00.000000000 +0100
+++ 
new/langchain_core-1.5.1/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.0'}}, responses=['foo'], i=1)",
+                "repr": "FakeListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['foo'], i=1)",
                 "name": "FakeListLLM"
               }
             },
@@ -128,7 +128,7 @@
                     "fake",
                     "FakeListLLM"
                   ],
-                  "repr": "FakeListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['bar'])",
+                  "repr": "FakeListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['bar'])",
                   "name": "FakeListLLM"
                 }
               },
@@ -268,7 +268,7 @@
           "fake",
           "FakeListLLM"
         ],
-        "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=['foo'], i=1)",
+        "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['foo'], i=1)",
         "name": "FakeListLLM"
       },
       "fallbacks": [
@@ -281,7 +281,7 @@
             "fake",
             "FakeListLLM"
           ],
-          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=['bar'])",
+          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['bar'])",
           "name": "FakeListLLM"
         }
       ],
@@ -322,7 +322,7 @@
           "fake",
           "FakeListLLM"
         ],
-        "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=['foo'], i=1)",
+        "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['foo'], i=1)",
         "name": "FakeListLLM"
       },
       "fallbacks": [
@@ -335,7 +335,7 @@
             "fake",
             "FakeListLLM"
           ],
-          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=['baz'], i=1)",
+          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['baz'], i=1)",
           "name": "FakeListLLM"
         },
         {
@@ -347,7 +347,7 @@
             "fake",
             "FakeListLLM"
           ],
-          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=['bar'])",
+          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['bar'])",
           "name": "FakeListLLM"
         }
       ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/langchain_core-1.5.0/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr
 
new/langchain_core-1.5.1/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr
--- 
old/langchain_core-1.5.0/tests/unit_tests/runnables/__snapshots__/test_runnable.ambr
        2020-02-02 01:00:00.000000000 +0100
+++ 
new/langchain_core-1.5.1/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.0'}}, responses=['foo, bar'])",
+          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['foo, bar'])",
           "name": "FakeListChatModel"
         }
       ],
@@ -227,7 +227,7 @@
             "fake_chat_models",
             "FakeListChatModel"
           ],
-          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['baz, qux'])",
+          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['baz, qux'])",
           "name": "FakeListChatModel"
         }
       ],
@@ -346,7 +346,7 @@
             "fake_chat_models",
             "FakeListChatModel"
           ],
-          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['foo, bar'])",
+          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['foo, bar'])",
           "name": "FakeListChatModel"
         },
         {
@@ -457,7 +457,7 @@
             "fake_chat_models",
             "FakeListChatModel"
           ],
-          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['baz, qux'])",
+          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['baz, qux'])",
           "name": "FakeListChatModel"
         }
       ],
@@ -848,7 +848,7 @@
             "fake",
             "FakeStreamingListLLM"
           ],
-          "repr": "FakeStreamingListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['first item, second item, third 
item'])",
+          "repr": "FakeStreamingListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['first item, second item, third 
item'])",
           "name": "FakeStreamingListLLM"
         },
         {
@@ -884,7 +884,7 @@
               "fake",
               "FakeStreamingListLLM"
             ],
-            "repr": "FakeStreamingListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['this', 'is', 'a', 'test'])",
+            "repr": "FakeStreamingListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, 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.0'}}, 
responses=['foo'])
+  | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.1'}}, 
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.0'}}, responses=['foo'])",
+        "repr": "FakeListChatModel(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['foo'])",
         "name": "FakeListChatModel"
       }
     },
@@ -1220,7 +1220,7 @@
             "fake_chat_models",
             "FakeListChatModel"
           ],
-          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['foo, bar'])",
+          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, 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.0'}}, 
responses=['foo'])
+  | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.1'}}, 
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.0'}}, responses=['foo'])",
+        "repr": "FakeListChatModel(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['foo'])",
         "name": "FakeListChatModel"
       }
     },
@@ -1459,7 +1459,7 @@
           "fake",
           "FakeListLLM"
         ],
-        "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=['foo', 'bar'])",
+        "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['foo', 'bar'])",
         "name": "FakeListLLM"
       }
     },
@@ -1576,7 +1576,7 @@
             "fake",
             "FakeListLLM"
           ],
-          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=['foo', 'bar'])",
+          "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=['foo', 'bar'])",
           "name": "FakeListLLM"
         }
       ],
@@ -1699,7 +1699,7 @@
             "fake",
             "FakeStreamingListLLM"
           ],
-          "repr": "FakeStreamingListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['bear, dog, cat', 'tomato, lettuce, 
onion'])",
+          "repr": "FakeStreamingListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['bear, dog, cat', 'tomato, lettuce, 
onion'])",
           "name": "FakeStreamingListLLM"
         }
       ],
@@ -1867,7 +1867,7 @@
                     "fake",
                     "FakeListLLM"
                   ],
-                  "repr": "FakeListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['4'])",
+                  "repr": "FakeListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=['4'])",
                   "name": "FakeListLLM"
                 }
               },
@@ -1940,7 +1940,7 @@
                     "fake",
                     "FakeListLLM"
                   ],
-                  "repr": "FakeListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['2'])",
+                  "repr": "FakeListLLM(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, 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.0'}}, 
responses=['foo, bar'])
+  | FakeListChatModel(metadata={'lc_versions': {'langchain-core': '1.5.1'}}, 
responses=['foo, bar'])
   | CommaSeparatedListOutputParser()
   '''
 # ---
@@ -13610,7 +13610,7 @@
             "fake_chat_models",
             "FakeListChatModel"
           ],
-          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=['foo, bar'])",
+          "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, 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.0'}}, responses=["i'm a chatbot"]),
-      llm: FakeListLLM(metadata={'lc_versions': {'langchain-core': '1.5.0'}}, 
responses=["i'm a textbot"])
+      chat: FakeListChatModel(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=["i'm a chatbot"]),
+      llm: FakeListLLM(metadata={'lc_versions': {'langchain-core': '1.5.1'}}, 
responses=["i'm a textbot"])
     }
   '''
 # ---
@@ -13762,7 +13762,7 @@
                 "fake_chat_models",
                 "FakeListChatModel"
               ],
-              "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=[\"i'm a chatbot\"])",
+              "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=[\"i'm a chatbot\"])",
               "name": "FakeListChatModel"
             },
             "llm": {
@@ -13774,7 +13774,7 @@
                 "fake",
                 "FakeListLLM"
               ],
-              "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=[\"i'm a textbot\"])",
+              "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=[\"i'm a textbot\"])",
               "name": "FakeListLLM"
             }
           }
@@ -13917,7 +13917,7 @@
                     "fake_chat_models",
                     "FakeListChatModel"
                   ],
-                  "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.0'}}, responses=[\"i'm a chatbot\"])",
+                  "repr": "FakeListChatModel(metadata={'lc_versions': 
{'langchain-core': '1.5.1'}}, responses=[\"i'm a chatbot\"])",
                   "name": "FakeListChatModel"
                 },
                 "kwargs": {
@@ -13938,7 +13938,7 @@
                 "fake",
                 "FakeListLLM"
               ],
-              "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.0'}}, responses=[\"i'm a textbot\"])",
+              "repr": "FakeListLLM(metadata={'lc_versions': {'langchain-core': 
'1.5.1'}}, responses=[\"i'm a textbot\"])",
               "name": "FakeListLLM"
             },
             "passthrough": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/langchain_core-1.5.0/tests/unit_tests/utils/test_gateway.py 
new/langchain_core-1.5.1/tests/unit_tests/utils/test_gateway.py
--- old/langchain_core-1.5.0/tests/unit_tests/utils/test_gateway.py     
1970-01-01 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.1/tests/unit_tests/utils/test_gateway.py     
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,279 @@
+"""Tests for LangSmith gateway configuration resolution."""
+
+from typing import Any
+
+import pytest
+from pydantic import BaseModel, ConfigDict, Field, SecretStr
+
+from langchain_core.utils._gateway import (
+    GatewayConfig,
+    _apply_gateway_config,
+    _resolve_gateway_base_url,
+    _resolve_gateway_config,
+)
+
+# A representative provider path; the helper is provider-agnostic.
+_PATH = "openai/v1"
+_BASE_ENV = "OPENAI_API_BASE"
+_KEY_ENV = "OPENAI_API_KEY"
+_DEFAULT_GATEWAY = "https://gateway.smith.langchain.com/openai/v1";
+
+
[email protected](autouse=True)
+def _clear_env(monkeypatch: pytest.MonkeyPatch) -> None:
+    """Ensure a hermetic environment for every test."""
+    for var in (
+        "LANGSMITH_GATEWAY",
+        "LANGSMITH_GATEWAY_API_KEY",
+        _BASE_ENV,
+        _KEY_ENV,
+    ):
+        monkeypatch.delenv(var, raising=False)
+
+
+def _config(**overrides: object) -> GatewayConfig:
+    kwargs: dict[str, Any] = {
+        "base_url": None,
+        "api_key": None,
+        "provider_path": _PATH,
+        "base_url_env": _BASE_ENV,
+        "api_key_env": _KEY_ENV,
+    }
+    kwargs.update(overrides)
+    return _resolve_gateway_config(**kwargs)
+
+
+# --- _resolve_gateway_base_url --------------------------------------------
+
+
[email protected]("value", ["true", "1", "yes", "TRUE", "Yes"])
+def test_base_url_truthy(monkeypatch: pytest.MonkeyPatch, value: str) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", value)
+    assert _resolve_gateway_base_url(_PATH) == _DEFAULT_GATEWAY
+
+
[email protected]("value", ["false", "0", "no", "FALSE"])
+def test_base_url_falsy(monkeypatch: pytest.MonkeyPatch, value: str) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", value)
+    assert _resolve_gateway_base_url(_PATH) is None
+
+
+def test_base_url_unset(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.delenv("LANGSMITH_GATEWAY", raising=False)
+    assert _resolve_gateway_base_url(_PATH) is None
+
+
+def test_base_url_custom(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "https://eu.gateway.example.com/";)
+    assert (
+        _resolve_gateway_base_url(_PATH) == 
"https://eu.gateway.example.com/openai/v1";
+    )
+
+
+# --- api key + base url resolution matrix ---------------------------------
+# Each case mirrors a documented requirement scenario.
+
+
+def test_gateway_on_with_gateway_key(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    config = _config()
+    assert config.base_url == _DEFAULT_GATEWAY
+    assert config.base_url_from_gateway is True
+    assert isinstance(config.api_key, SecretStr)
+    assert config.api_key.get_secret_value() == "gateway-key"
+
+
+def test_gateway_key_ignored_when_gateway_off(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    # Gateway key set but LANGSMITH_GATEWAY unset -> never used.
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    monkeypatch.setenv(_KEY_ENV, "provider-key")
+    config = _config()
+    assert config.base_url is None
+    assert config.base_url_from_gateway is False
+    assert isinstance(config.api_key, SecretStr)
+    assert config.api_key.get_secret_value() == "provider-key"
+
+
+def test_gateway_off_explicitly(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "false")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    config = _config()
+    assert config.base_url is None
+    assert config.api_key is None
+
+
+def test_gateway_key_beats_provider_key_on_gateway(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    monkeypatch.setenv(_KEY_ENV, "provider-key")
+    config = _config()
+    assert config.base_url == _DEFAULT_GATEWAY
+    assert config.api_key.get_secret_value() == "gateway-key"
+
+
+def test_gateway_on_falls_back_to_provider_key(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv(_KEY_ENV, "provider-key")
+    config = _config()
+    assert config.base_url == _DEFAULT_GATEWAY
+    assert config.api_key.get_secret_value() == "provider-key"
+
+
+def test_provider_base_url_uses_provider_key(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    # Base URL overridden away from the gateway -> provider key wins.
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    monkeypatch.setenv(_BASE_ENV, "https://api.openai.com/v1";)
+    monkeypatch.setenv(_KEY_ENV, "provider-key")
+    config = _config()
+    assert config.base_url == "https://api.openai.com/v1";
+    assert config.base_url_from_gateway is False
+    assert config.api_key.get_secret_value() == "provider-key"
+
+
+def test_provider_base_url_falls_back_to_gateway_key(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    # Base URL overridden, no provider key -> gateway key used as fallback.
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    monkeypatch.setenv(_BASE_ENV, "https://api.openai.com/v1";)
+    config = _config()
+    assert config.base_url == "https://api.openai.com/v1";
+    assert config.api_key.get_secret_value() == "gateway-key"
+
+
+def test_custom_gateway_url(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "https://eu.gateway.example.com";)
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    config = _config()
+    assert config.base_url == "https://eu.gateway.example.com/openai/v1";
+    assert config.base_url_from_gateway is True
+    assert config.api_key.get_secret_value() == "gateway-key"
+
+
+def test_explicit_kwargs_override_everything(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "https://eu.gateway.example.com";)
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    monkeypatch.setenv(_KEY_ENV, "provider-key")
+    explicit_key = SecretStr("explicit-key")
+    config = _config(
+        base_url="https://apac.gateway.example.com";,
+        api_key=explicit_key,
+    )
+    assert config.base_url == "https://apac.gateway.example.com";
+    assert config.base_url_from_gateway is False
+    assert config.api_key is explicit_key
+
+
+def test_explicit_base_url_pairs_with_gateway_key(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    # Explicit base URL, no explicit key: gateway key still resolved from env.
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "https://eu.gateway.example.com";)
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    config = _config(base_url="https://apac.gateway.example.com";)
+    assert config.base_url == "https://apac.gateway.example.com";
+    assert config.api_key.get_secret_value() == "gateway-key"
+
+
+def test_no_gateway_uses_provider_defaults(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setenv(_BASE_ENV, "https://provider.example.com";)
+    monkeypatch.setenv(_KEY_ENV, "provider-key")
+    config = _config(default_base_url="https://default.example.com";)
+    assert config.base_url == "https://provider.example.com";
+    assert config.api_key.get_secret_value() == "provider-key"
+
+
+def test_default_base_url_when_nothing_set() -> None:
+    config = _config(default_base_url="https://default.example.com";)
+    assert config.base_url == "https://default.example.com";
+    assert config.base_url_from_gateway is False
+    assert config.api_key is None
+
+
+def test_multiple_base_url_env_vars_priority(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setenv("SECOND_BASE", "https://second.example.com";)
+    config = _config(base_url_env=["FIRST_BASE", "SECOND_BASE"])
+    assert config.base_url == "https://second.example.com";
+
+
+# --- _apply_gateway_config (before-validator path) ------------------------
+
+
+class _Model(BaseModel):
+    """Stand-in for a provider chat model with aliased fields."""
+
+    model_config = ConfigDict(populate_by_name=True)
+
+    api_base: str | None = Field(default=None, alias="base_url")
+    api_key: SecretStr = Field(default=SecretStr(""), alias="api_key_alias")
+
+
+def _apply(values: dict[str, Any]) -> tuple[dict[str, Any], GatewayConfig]:
+    config = _apply_gateway_config(
+        values,
+        _Model,
+        base_url_field="api_base",
+        api_key_field="api_key",
+        provider_path="openai/v1",
+        base_url_env=_BASE_ENV,
+        api_key_env=_KEY_ENV,
+    )
+    return values, config
+
+
+def test_apply_writes_resolved_values_by_field_name(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    values, config = _apply({})
+    assert values["api_base"] == _DEFAULT_GATEWAY
+    assert isinstance(values["api_key"], SecretStr)
+    assert values["api_key"].get_secret_value() == "gateway-key"
+    assert config.base_url_from_gateway is True
+
+
+def test_apply_reads_explicit_via_alias(monkeypatch: pytest.MonkeyPatch) -> 
None:
+    # Values provided under aliases are consumed and rewritten under field 
names.
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    values, _ = _apply(
+        {"base_url": "https://explicit.example.com";, "api_key_alias": 
"explicit-key"}
+    )
+    assert "base_url" not in values
+    assert "api_key_alias" not in values
+    assert values["api_base"] == "https://explicit.example.com";
+    assert values["api_key"] == "explicit-key"
+
+
+def test_apply_reads_explicit_via_field_name(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    monkeypatch.setenv("LANGSMITH_GATEWAY", "true")
+    monkeypatch.setenv("LANGSMITH_GATEWAY_API_KEY", "gateway-key")
+    values, _ = _apply({"api_base": "https://explicit.example.com"})
+    assert values["api_base"] == "https://explicit.example.com";
+
+
+def test_apply_omits_key_when_unresolved() -> None:
+    # No key anywhere: the field is left unset so its own default applies.
+    values, config = _apply({})
+    assert "api_key" not in values
+    assert config.api_key is None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langchain_core-1.5.0/uv.lock 
new/langchain_core-1.5.1/uv.lock
--- old/langchain_core-1.5.0/uv.lock    2020-02-02 01:00:00.000000000 +0100
+++ new/langchain_core-1.5.1/uv.lock    2020-02-02 01:00:00.000000000 +0100
@@ -490,7 +490,7 @@
 version = "1.3.1"
 source = { registry = "https://pypi.org/simple"; }
 dependencies = [
-    { name = "typing-extensions" },
+    { name = "typing-extensions", marker = "python_full_version < '3.11'" },
 ]
 sdist = { url = 
"https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz";,
 hash = 
"sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size 
= 30371, upload-time = "2025-11-21T23:01:54.787Z" }
 wheels = [
@@ -652,17 +652,17 @@
     "python_full_version < '3.11' and platform_python_implementation != 
'PyPy'",
 ]
 dependencies = [
-    { name = "colorama", marker = "sys_platform == 'win32'" },
-    { name = "decorator" },
-    { name = "exceptiongroup" },
-    { name = "jedi" },
-    { name = "matplotlib-inline" },
-    { name = "pexpect", marker = "sys_platform != 'emscripten' and 
sys_platform != 'win32'" },
-    { name = "prompt-toolkit" },
-    { name = "pygments" },
-    { name = "stack-data" },
-    { name = "traitlets" },
-    { name = "typing-extensions" },
+    { name = "colorama", marker = "python_full_version < '3.11' and 
sys_platform == 'win32'" },
+    { name = "decorator", marker = "python_full_version < '3.11'" },
+    { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
+    { name = "jedi", marker = "python_full_version < '3.11'" },
+    { name = "matplotlib-inline", marker = "python_full_version < '3.11'" },
+    { name = "pexpect", marker = "python_full_version < '3.11' and 
sys_platform != 'emscripten' and sys_platform != 'win32'" },
+    { name = "prompt-toolkit", marker = "python_full_version < '3.11'" },
+    { name = "pygments", marker = "python_full_version < '3.11'" },
+    { name = "stack-data", marker = "python_full_version < '3.11'" },
+    { name = "traitlets", marker = "python_full_version < '3.11'" },
+    { name = "typing-extensions", marker = "python_full_version < '3.11'" },
 ]
 sdist = { url = 
"https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz";,
 hash = 
"sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size 
= 5606088, upload-time = "2025-05-31T16:39:09.613Z" }
 wheels = [
@@ -684,17 +684,17 @@
     "python_full_version >= '3.11' and python_full_version < '3.13' and 
platform_python_implementation != 'PyPy'",
 ]
 dependencies = [
-    { name = "colorama", marker = "sys_platform == 'win32'" },
-    { name = "decorator" },
-    { name = "ipython-pygments-lexers" },
-    { name = "jedi" },
-    { name = "matplotlib-inline" },
-    { name = "pexpect", marker = "sys_platform != 'emscripten' and 
sys_platform != 'win32'" },
-    { name = "prompt-toolkit" },
-    { name = "pygments" },
-    { name = "stack-data" },
-    { name = "traitlets" },
-    { name = "typing-extensions", marker = "python_full_version < '3.12'" },
+    { name = "colorama", marker = "python_full_version >= '3.11' and 
sys_platform == 'win32'" },
+    { name = "decorator", marker = "python_full_version >= '3.11'" },
+    { name = "ipython-pygments-lexers", marker = "python_full_version >= 
'3.11'" },
+    { name = "jedi", marker = "python_full_version >= '3.11'" },
+    { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" },
+    { name = "pexpect", marker = "python_full_version >= '3.11' and 
sys_platform != 'emscripten' and sys_platform != 'win32'" },
+    { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" },
+    { name = "pygments", marker = "python_full_version >= '3.11'" },
+    { name = "stack-data", marker = "python_full_version >= '3.11'" },
+    { name = "traitlets", marker = "python_full_version >= '3.11'" },
+    { name = "typing-extensions", marker = "python_full_version == '3.11.*'" },
 ]
 sdist = { url = 
"https://files.pythonhosted.org/packages/12/51/a703c030f4928646d390b4971af4938a1b10c9dfce694f0d99a0bb073cb2/ipython-9.8.0.tar.gz";,
 hash = 
"sha256:8e4ce129a627eb9dd221c41b1d2cdaed4ef7c9da8c17c63f6f578fe231141f83", size 
= 4424940, upload-time = "2025-12-03T10:18:24.353Z" }
 wheels = [
@@ -706,7 +706,7 @@
 version = "1.1.1"
 source = { registry = "https://pypi.org/simple"; }
 dependencies = [
-    { name = "pygments" },
+    { name = "pygments", marker = "python_full_version >= '3.11'" },
 ]
 sdist = { url = 
"https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz";,
 hash = 
"sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size 
= 8393, upload-time = "2025-01-17T11:24:34.505Z" }
 wheels = [
@@ -1039,7 +1039,7 @@
 
 [[package]]
 name = "langchain-core"
-version = "1.5.0"
+version = "1.5.1"
 source = { editable = "." }
 dependencies = [
     { name = "jsonpatch" },

Reply via email to