Compare commits

...

6 Commits

Author SHA1 Message Date
Eugene Yurtsev
c87cd04927 release(core): release 1.3.0 (#36851)
xRelease 1.3.0
2026-04-17 14:42:01 +00:00
ccurme
ae0743ec3b fix(anthropic): strip null encrypted_content from compaction blocks (#36850) 2026-04-17 10:23:11 -04:00
ccurme
c2fd6a2d34 release(anthropic): 1.4.1 (#36848) 2026-04-17 09:42:34 -04:00
ccurme
c59e8e1cff feat(anthropic): support opus 4.7 features (#36847) 2026-04-17 09:37:02 -04:00
ccurme
6fb37dba71 release(huggingface): 1.2.2 (#36832) 2026-04-16 15:53:28 -04:00
ccurme
a029c7bf1d fix(huggingface): harden hostname validation and reject URLs in repo_id (#36831) 2026-04-16 15:49:48 -04:00
18 changed files with 249 additions and 52 deletions

View File

@@ -1,3 +1,3 @@
"""langchain-core version information and utilities."""
VERSION = "1.3.0a3"
VERSION = "1.3.0"

View File

@@ -21,7 +21,7 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
version = "1.3.0a3"
version = "1.3.0"
requires-python = ">=3.10.0,<4.0.0"
dependencies = [
"langsmith>=0.3.45,<1.0.0",

2
libs/core/uv.lock generated
View File

@@ -995,7 +995,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.3.0a3"
version = "1.3.0"
source = { editable = "." }
dependencies = [
{ name = "jsonpatch" },

View File

@@ -275,6 +275,7 @@ def test_configurable_with_default() -> None:
"streaming": False,
"stream_usage": True,
"output_version": None,
"output_config": None,
},
"kwargs": {
"tools": [{"name": "foo", "description": "foo", "input_schema": {}}],

View File

@@ -1,5 +1,5 @@
version = 1
revision = 2
revision = 3
requires-python = ">=3.10.0, <4.0.0"
resolution-markers = [
"python_full_version >= '3.14' and platform_python_implementation == 'PyPy'",
@@ -2601,7 +2601,7 @@ typing = [
[[package]]
name = "langchain-core"
version = "1.3.0a2"
version = "1.3.0"
source = { editable = "../core" }
dependencies = [
{ name = "jsonpatch" },

View File

@@ -326,6 +326,7 @@ def test_configurable_with_default() -> None:
"streaming": False,
"stream_usage": True,
"output_version": None,
"output_config": None,
},
"kwargs": {
"tools": [{"name": "foo", "description": "foo", "input_schema": {}}],

View File

@@ -173,7 +173,7 @@ wheels = [
[[package]]
name = "anthropic"
version = "0.85.0"
version = "0.96.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@@ -185,9 +185,9 @@ dependencies = [
{ name = "sniffio" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/08/c620a0eb8625539a8ea9f5a6e06f13d131be0bc8b5b714c235d4b25dd1b5/anthropic-0.85.0.tar.gz", hash = "sha256:d45b2f38a1efb1a5d15515a426b272179a0d18783efa2bb4c3925fa773eb50b9", size = 542034, upload-time = "2026-03-16T17:00:44.324Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b9/7e/672f533dee813028d2c699bfd2a7f52c9118d7353680d9aa44b9e23f717f/anthropic-0.96.0.tar.gz", hash = "sha256:9de947b737f39452f68aa520f1c2239d44119c9b73b0fb6d4e6ca80f00279ee6", size = 658210, upload-time = "2026-04-16T14:28:02.846Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e1/5a/9d85b85686d5cdd79f5488c8667e668d7920d06a0a1a1beb454a5b77b2db/anthropic-0.85.0-py3-none-any.whl", hash = "sha256:b4f54d632877ed7b7b29c6d9ba7299d5e21c4c92ae8de38947e9d862bff74adf", size = 458237, upload-time = "2026-03-16T17:00:45.877Z" },
{ url = "https://files.pythonhosted.org/packages/48/5a/72f33204064b6e87601a71a6baf8d855769f8a0c1eaae8d06a1094872371/anthropic-0.96.0-py3-none-any.whl", hash = "sha256:9a6e335a354602a521cd9e777e92bfd46ba6e115bf9bbfe6135311e8fb2015b2", size = 635930, upload-time = "2026-04-16T14:28:01.436Z" },
]
[[package]]
@@ -2062,7 +2062,7 @@ typing = [
[[package]]
name = "langchain-anthropic"
version = "1.4.0"
version = "1.4.1"
source = { editable = "../partners/anthropic" }
dependencies = [
{ name = "anthropic" },
@@ -2072,7 +2072,7 @@ dependencies = [
[package.metadata]
requires-dist = [
{ name = "anthropic", specifier = ">=0.85.0,<1.0.0" },
{ name = "anthropic", specifier = ">=0.96.0,<1.0.0" },
{ name = "langchain-core", editable = "../core" },
{ name = "pydantic", specifier = ">=2.7.4,<3.0.0" },
]
@@ -2208,7 +2208,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.3.0a2"
version = "1.3.0"
source = { editable = "../core" }
dependencies = [
{ name = "jsonpatch" },
@@ -2391,7 +2391,7 @@ wheels = [
[[package]]
name = "langchain-openai"
version = "1.1.13"
version = "1.1.14"
source = { editable = "../partners/openai" }
dependencies = [
{ name = "langchain-core" },
@@ -2499,7 +2499,7 @@ typing = [
[[package]]
name = "langchain-text-splitters"
version = "1.1.1"
version = "1.1.2"
source = { editable = "../text-splitters" }
dependencies = [
{ name = "langchain-core" },

View File

@@ -1,3 +1,3 @@
"""Version information for langchain-anthropic."""
__version__ = "1.4.0"
__version__ = "1.4.1"

View File

@@ -831,19 +831,55 @@ class ChatAnthropic(BaseChatModel):
"""
thinking: dict[str, Any] | None = Field(default=None)
"""Parameters for Claude reasoning,
"""Parameters for Claude reasoning.
e.g., `#!python {"type": "enabled", "budget_tokens": 10_000}`
Examples:
For Claude Opus 4.6, `budget_tokens` is deprecated in favor of
`#!python {"type": "adaptive"}`
- `#!python {"type": "enabled", "budget_tokens": 10_000}` (pre-4.7 models)
- `#!python {"type": "adaptive"}` (Opus 4.6+)
- `#!python {"type": "adaptive", "display": "summarized"}` (Opus 4.7+)
!!! note "Claude Opus 4.7"
`budget_tokens` is removed on Opus 4.7 — use `{"type": "adaptive"}`
with `output_config.effort` to control reasoning effort. Set `display`
to `"summarized"` to receive summarized reasoning in the response
(default is `"omitted"`).
"""
effort: Literal["max", "high", "medium", "low"] | None = None
"""Control how many tokens Claude uses when responding.
output_config: dict[str, Any] | None = None
"""Configuration options for the model's output.
This parameter will be merged into the `output_config` parameter when making
API calls.
Supports the following keys:
- `effort`: Controls how many tokens Claude uses when responding.
One of `"max"`, `"xhigh"`, `"high"`, `"medium"`, or `"low"`.
- `format`: Structured output format configuration (typically set via
`with_structured_output`).
- `task_budget`: Advisory token budget for an agentic loop (beta).
E.g., `#!python {"type": "tokens", "total": 128_000}`.
Example:
.. code-block:: python
ChatAnthropic(
model="claude-opus-4-7",
output_config={
"effort": "xhigh",
"task_budget": {"type": "tokens", "total": 128_000},
},
)
See Anthropic docs on
[extended output](https://platform.claude.com/docs/en/api/go/beta/messages/create).
"""
effort: Literal["max", "xhigh", "high", "medium", "low"] | None = None
"""Convenience shorthand for `output_config.effort`.
When set, this value takes precedence over any `effort` key inside
`output_config`.
Example: `effort="medium"`
@@ -851,11 +887,6 @@ class ChatAnthropic(BaseChatModel):
Setting `effort` to `'high'` produces exactly the same behavior as omitting the
parameter altogether.
!!! note "Model Support"
This feature is generally available on Claude Opus 4.6 and Claude Opus 4.5.
The `max` effort level is only supported by Claude Opus 4.6.
"""
mcp_servers: list[dict[str, Any]] | None = None
@@ -927,6 +958,7 @@ class ChatAnthropic(BaseChatModel):
"max_retries": self.max_retries,
"default_request_timeout": self.default_request_timeout,
"thinking": self.thinking,
"output_config": self.output_config,
}
def _get_ls_params(
@@ -1082,9 +1114,13 @@ class ChatAnthropic(BaseChatModel):
payload["inference_geo"] = self.inference_geo
# Handle output_config and effort parameter
# Priority: self.effort > payload output_config
output_config = payload.get("output_config", {})
output_config = output_config.copy() if isinstance(output_config, dict) else {}
# Priority: self.effort > kwargs output_config > self.output_config
output_config: dict[str, Any] = {}
if self.output_config:
output_config.update(self.output_config)
payload_oc = payload.get("output_config")
if isinstance(payload_oc, dict):
output_config.update(payload_oc)
if self.effort:
output_config["effort"] = self.effort
@@ -1175,6 +1211,16 @@ class ChatAnthropic(BaseChatModel):
else:
payload["betas"] = [required_beta]
# Auto-append required beta for task_budget
resolved_oc = payload.get("output_config")
if isinstance(resolved_oc, dict) and resolved_oc.get("task_budget"):
required_beta = "task-budgets-2026-03-13"
if payload.get("betas"):
if required_beta not in payload["betas"]:
payload["betas"] = [*payload["betas"], required_beta]
else:
payload["betas"] = [required_beta]
return {k: v for k, v in payload.items() if v is not None}
def _create(self, payload: dict) -> Any:
@@ -1408,6 +1454,11 @@ class ChatAnthropic(BaseChatModel):
content_block = event.delta.model_dump()
content_block["index"] = event.index
content_block["type"] = "compaction"
if (
"encrypted_content" in content_block
and content_block["encrypted_content"] is None
):
content_block.pop("encrypted_content")
message_chunk = AIMessageChunk(content=[content_block])
# Process final usage metadata and completion info
@@ -1455,6 +1506,8 @@ class ChatAnthropic(BaseChatModel):
block.pop("citations")
if "caller" in block and block["caller"] is None:
block.pop("caller")
if "encrypted_content" in block and block["encrypted_content"] is None:
block.pop("encrypted_content")
if (
block.get("type") == "thinking"
and "text" in block

View File

@@ -239,7 +239,7 @@ _PROFILES: dict[str, dict[str, Any]] = {
"image_url_inputs": True,
"pdf_tool_message": True,
"image_tool_message": True,
"structured_output": False,
"structured_output": True,
},
"claude-haiku-4-5-20251001": {
"name": "Claude Haiku 4.5",
@@ -389,7 +389,7 @@ _PROFILES: dict[str, dict[str, Any]] = {
"image_url_inputs": True,
"pdf_tool_message": True,
"image_tool_message": True,
"structured_output": False,
"structured_output": True,
},
"claude-opus-4-5-20251101": {
"name": "Claude Opus 4.5",
@@ -439,7 +439,32 @@ _PROFILES: dict[str, dict[str, Any]] = {
"image_url_inputs": True,
"pdf_tool_message": True,
"image_tool_message": True,
"structured_output": False,
"structured_output": True,
},
"claude-opus-4-7": {
"name": "Claude Opus 4.7",
"release_date": "2026-04-16",
"last_updated": "2026-04-16",
"open_weights": False,
"max_input_tokens": 1000000,
"max_output_tokens": 128000,
"text_inputs": True,
"image_inputs": True,
"audio_inputs": False,
"pdf_inputs": True,
"video_inputs": False,
"text_outputs": True,
"image_outputs": False,
"audio_outputs": False,
"video_outputs": False,
"reasoning_output": True,
"tool_calling": True,
"attachment": True,
"temperature": False,
"image_url_inputs": True,
"pdf_tool_message": True,
"image_tool_message": True,
"structured_output": True,
},
"claude-sonnet-4-0": {
"name": "Claude Sonnet 4 (latest)",
@@ -564,6 +589,6 @@ _PROFILES: dict[str, dict[str, Any]] = {
"image_url_inputs": True,
"pdf_tool_message": True,
"image_tool_message": True,
"structured_output": False,
"structured_output": True,
},
}

View File

@@ -7,8 +7,23 @@ pdf_tool_message = true
image_tool_message = true
structured_output = false
[overrides."claude-haiku-4-5"]
structured_output = true
[overrides."claude-sonnet-4-5"]
structured_output = true
[overrides."claude-sonnet-4-6"]
structured_output = true
[overrides."claude-opus-4-1"]
structured_output = true
[overrides."claude-opus-4-5"]
structured_output = true
[overrides."claude-opus-4-6"]
structured_output = true
[overrides."claude-opus-4-7"]
structured_output = true

View File

@@ -20,11 +20,11 @@ classifiers = [
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
version = "1.4.0"
version = "1.4.1"
requires-python = ">=3.10.0,<4.0.0"
dependencies = [
"anthropic>=0.85.0,<1.0.0",
"langchain-core>=1.2.21,<2.0.0",
"anthropic>=0.96.0,<1.0.0",
"langchain-core>=1.2.31,<2.0.0",
"pydantic>=2.7.4,<3.0.0",
]

View File

@@ -2313,7 +2313,9 @@ def test_effort_in_output_config() -> None:
model="claude-opus-4-5-20251101",
output_config={"effort": "low"},
)
assert model.model_kwargs["output_config"] == {"effort": "low"}
assert model.output_config == {"effort": "low"}
payload = model._get_request_payload("Test query")
assert payload["output_config"]["effort"] == "low"
def test_effort_priority() -> None:
@@ -2764,3 +2766,80 @@ def test_thinking_in_params_recognizes_adaptive() -> None:
assert not _thinking_in_params({"thinking": {"type": "disabled"}})
assert not _thinking_in_params({"thinking": {}})
assert not _thinking_in_params({})
def test_effort_xhigh() -> None:
"""Test that xhigh effort level is accepted and lands in output_config."""
model = ChatAnthropic(model="claude-opus-4-6", effort="xhigh")
assert model.effort == "xhigh"
payload = model._get_request_payload("Test query")
assert payload["output_config"]["effort"] == "xhigh"
def test_output_config_top_level_field() -> None:
"""Test that output_config is a top-level field, not model_kwargs."""
model = ChatAnthropic(
model=MODEL_NAME,
output_config={
"effort": "low",
"task_budget": {"type": "tokens", "total": 50000},
},
)
assert model.output_config == {
"effort": "low",
"task_budget": {"type": "tokens", "total": 50000},
}
assert "output_config" not in model.model_kwargs
payload = model._get_request_payload("Test query")
assert payload["output_config"]["effort"] == "low"
assert payload["output_config"]["task_budget"] == {"type": "tokens", "total": 50000}
def test_output_config_merged_with_kwargs() -> None:
"""Test that call-time output_config overrides field-level output_config."""
model = ChatAnthropic(
model=MODEL_NAME,
output_config={"effort": "low"},
)
payload = model._get_request_payload(
"Test query",
output_config={
"effort": "high",
"task_budget": {"type": "tokens", "total": 50000},
},
)
# Call-time kwargs override field-level
assert payload["output_config"]["effort"] == "high"
assert payload["output_config"]["task_budget"] == {"type": "tokens", "total": 50000}
def test_task_budget_auto_appends_beta() -> None:
"""Test that task_budget in output_config triggers beta header."""
model = ChatAnthropic(
model=MODEL_NAME,
output_config={"task_budget": {"type": "tokens", "total": 128000}},
)
payload = model._get_request_payload("Test query")
assert "betas" in payload
assert "task-budgets-2026-03-13" in payload["betas"]
def test_task_budget_beta_not_duplicated() -> None:
"""Test that task_budget beta is not duplicated if already present."""
model = ChatAnthropic(
model=MODEL_NAME,
betas=["task-budgets-2026-03-13"],
output_config={"task_budget": {"type": "tokens", "total": 128000}},
)
payload = model._get_request_payload("Test query")
assert payload["betas"].count("task-budgets-2026-03-13") == 1
def test_no_task_budget_no_beta() -> None:
"""Test that task_budget beta is not added when no task_budget is set."""
model = ChatAnthropic(model=MODEL_NAME, output_config={"effort": "high"})
payload = model._get_request_payload("Test query")
betas = payload.get("betas")
if betas:
assert "task-budgets-2026-03-13" not in betas

View File

@@ -1,5 +1,5 @@
version = 1
revision = 3
revision = 2
requires-python = ">=3.10.0, <4.0.0"
resolution-markers = [
"python_full_version >= '3.13' and platform_python_implementation == 'PyPy'",
@@ -27,7 +27,7 @@ wheels = [
[[package]]
name = "anthropic"
version = "0.85.0"
version = "0.96.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@@ -39,9 +39,9 @@ dependencies = [
{ name = "sniffio" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/08/c620a0eb8625539a8ea9f5a6e06f13d131be0bc8b5b714c235d4b25dd1b5/anthropic-0.85.0.tar.gz", hash = "sha256:d45b2f38a1efb1a5d15515a426b272179a0d18783efa2bb4c3925fa773eb50b9", size = 542034, upload-time = "2026-03-16T17:00:44.324Z" }
sdist = { url = "https://files.pythonhosted.org/packages/b9/7e/672f533dee813028d2c699bfd2a7f52c9118d7353680d9aa44b9e23f717f/anthropic-0.96.0.tar.gz", hash = "sha256:9de947b737f39452f68aa520f1c2239d44119c9b73b0fb6d4e6ca80f00279ee6", size = 658210, upload-time = "2026-04-16T14:28:02.846Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e1/5a/9d85b85686d5cdd79f5488c8667e668d7920d06a0a1a1beb454a5b77b2db/anthropic-0.85.0-py3-none-any.whl", hash = "sha256:b4f54d632877ed7b7b29c6d9ba7299d5e21c4c92ae8de38947e9d862bff74adf", size = 458237, upload-time = "2026-03-16T17:00:45.877Z" },
{ url = "https://files.pythonhosted.org/packages/48/5a/72f33204064b6e87601a71a6baf8d855769f8a0c1eaae8d06a1094872371/anthropic-0.96.0-py3-none-any.whl", hash = "sha256:9a6e335a354602a521cd9e777e92bfd46ba6e115bf9bbfe6135311e8fb2015b2", size = 635930, upload-time = "2026-04-16T14:28:01.436Z" },
]
[[package]]
@@ -575,7 +575,7 @@ typing = [
[[package]]
name = "langchain-anthropic"
version = "1.4.0"
version = "1.4.1"
source = { editable = "." }
dependencies = [
{ name = "anthropic" },
@@ -621,7 +621,7 @@ typing = [
[package.metadata]
requires-dist = [
{ name = "anthropic", specifier = ">=0.85.0,<1.0.0" },
{ name = "anthropic", specifier = ">=0.96.0,<1.0.0" },
{ name = "langchain-core", editable = "../../core" },
{ name = "pydantic", specifier = ">=2.7.4,<3.0.0" },
]
@@ -660,7 +660,7 @@ typing = [
[[package]]
name = "langchain-core"
version = "1.3.0a2"
version = "1.3.0a3"
source = { editable = "../../core" }
dependencies = [
{ name = "jsonpatch" },

View File

@@ -65,6 +65,12 @@ class HuggingFaceEndpointEmbeddings(BaseModel, Embeddings):
@model_validator(mode="after")
def validate_environment(self) -> Self:
"""Validate that api key and python package exists in environment."""
for field_name in ("model", "repo_id"):
value = getattr(self, field_name)
if value and value.startswith(("http://", "https://")):
msg = f"`{field_name}` must be a HuggingFace repo ID, not a URL."
raise ValueError(msg)
huggingfacehub_api_token = self.huggingfacehub_api_token or os.getenv(
"HF_TOKEN"
)

View File

@@ -5,6 +5,7 @@ import logging
import os
from collections.abc import AsyncIterator, Iterator, Mapping
from typing import Any
from urllib.parse import urlparse
from langchain_core.callbacks import (
AsyncCallbackManagerForLLMRun,
@@ -23,8 +24,12 @@ def _is_huggingface_hosted_url(url: str | None) -> bool:
"""True if url is HF-hosted (huggingface.co or hf.space)."""
if not url:
return False
url_lower = url.lower().strip()
return "huggingface.co" in url_lower or "hf.space" in url_lower
hostname = (urlparse(url).hostname or "").lower()
return (
hostname == "huggingface.co"
or hostname == "hf.space"
or hostname.endswith((".huggingface.co", ".hf.space"))
)
VALID_TASKS = (
@@ -220,6 +225,13 @@ class HuggingFaceEndpoint(LLM):
endpoint_url = values.get("endpoint_url")
repo_id = values.get("repo_id")
if repo_id and repo_id.startswith(("http://", "https://")):
msg = (
"`repo_id` must be a HuggingFace repo ID, not a URL. "
"Use `endpoint_url` for direct endpoints."
)
raise ValueError(msg)
if sum([bool(model), bool(endpoint_url), bool(repo_id)]) > 1:
msg = (
"Please specify either a `model` OR an `endpoint_url` OR a `repo_id`,"

View File

@@ -20,10 +20,10 @@ classifiers = [
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
version = "1.2.1"
version = "1.2.2"
requires-python = ">=3.10.0,<4.0.0"
dependencies = [
"langchain-core>=1.2.21,<2.0.0",
"langchain-core>=1.2.31,<2.0.0",
"tokenizers>=0.19.1,<1.0.0",
"huggingface-hub>=0.33.4,<2.0.0",
]

View File

@@ -1,5 +1,5 @@
version = 1
revision = 3
revision = 2
requires-python = ">=3.10.0, <4.0.0"
resolution-markers = [
"python_full_version >= '3.13' and platform_python_implementation == 'PyPy'",
@@ -613,6 +613,7 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7d/ed/6bfa4109fcb23a58819600392564fea69cdc6551ffd5e69ccf1d52a40cbc/greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c", size = 271061, upload-time = "2025-08-07T13:17:15.373Z" },
{ url = "https://files.pythonhosted.org/packages/2a/fc/102ec1a2fc015b3a7652abab7acf3541d58c04d3d17a8d3d6a44adae1eb1/greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590", size = 629475, upload-time = "2025-08-07T13:42:54.009Z" },
{ url = "https://files.pythonhosted.org/packages/c5/26/80383131d55a4ac0fb08d71660fd77e7660b9db6bdb4e8884f46d9f2cc04/greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c", size = 640802, upload-time = "2025-08-07T13:45:25.52Z" },
{ url = "https://files.pythonhosted.org/packages/9f/7c/e7833dbcd8f376f3326bd728c845d31dcde4c84268d3921afcae77d90d08/greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b", size = 636703, upload-time = "2025-08-07T13:53:12.622Z" },
{ url = "https://files.pythonhosted.org/packages/e9/49/547b93b7c0428ede7b3f309bc965986874759f7d89e4e04aeddbc9699acb/greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31", size = 635417, upload-time = "2025-08-07T13:18:25.189Z" },
{ url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" },
{ url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" },
@@ -623,6 +624,7 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" },
{ url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" },
{ url = "https://files.pythonhosted.org/packages/ae/8f/95d48d7e3d433e6dae5b1682e4292242a53f22df82e6d3dda81b1701a960/greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3", size = 644646, upload-time = "2025-08-07T13:45:26.523Z" },
{ url = "https://files.pythonhosted.org/packages/d5/5e/405965351aef8c76b8ef7ad370e5da58d57ef6068df197548b015464001a/greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633", size = 640519, upload-time = "2025-08-07T13:53:13.928Z" },
{ url = "https://files.pythonhosted.org/packages/25/5d/382753b52006ce0218297ec1b628e048c4e64b155379331f25a7316eb749/greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079", size = 639707, upload-time = "2025-08-07T13:18:27.146Z" },
{ url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" },
{ url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" },
@@ -633,6 +635,7 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" },
{ url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" },
{ url = "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", size = 655185, upload-time = "2025-08-07T13:45:27.624Z" },
{ url = "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", size = 649926, upload-time = "2025-08-07T13:53:15.251Z" },
{ url = "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", size = 651839, upload-time = "2025-08-07T13:18:30.281Z" },
{ url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" },
{ url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" },
@@ -643,6 +646,7 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" },
{ url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" },
{ url = "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", size = 655191, upload-time = "2025-08-07T13:45:29.752Z" },
{ url = "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", size = 649516, upload-time = "2025-08-07T13:53:16.314Z" },
{ url = "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", size = 652169, upload-time = "2025-08-07T13:18:32.861Z" },
{ url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" },
{ url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" },
@@ -653,6 +657,7 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" },
{ url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" },
{ url = "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", size = 699218, upload-time = "2025-08-07T13:45:30.969Z" },
{ url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" },
{ url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" },
{ url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" },
{ url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" },
@@ -1044,7 +1049,7 @@ wheels = [
[[package]]
name = "langchain-core"
version = "1.3.0a2"
version = "1.3.0a3"
source = { editable = "../../core" }
dependencies = [
{ name = "jsonpatch" },
@@ -1104,7 +1109,7 @@ typing = [
[[package]]
name = "langchain-huggingface"
version = "1.2.1"
version = "1.2.2"
source = { editable = "." }
dependencies = [
{ name = "huggingface-hub" },