Commit Graph

15879 Commits

Author SHA1 Message Date
Nick Hollon
ad4d43f388 fix(core): hybrid astream_events result for v1/v2 + v3 dual API 2026-04-30 15:27:18 -04:00
Nick Hollon
48c1aa62b1 fix RunnableBinding.astream_events shape for v3 awaitability 2026-04-30 15:16:31 -04:00
Nick Hollon
df861bb226 fix async stream-events calls through RunnableBinding and langgraph graph
- Use _astream_events_v3 helper (not astream_events(version="v3")) when
  calling through a RunnableBinding — the binding's astream_events is an
  async generator and cannot be awaited directly for v3.
- Revert langchain_v1 agent tests back to agent.stream_v2 / astream_v2:
  these call langgraph CompiledStateGraph.stream_v2, a graph-level API
  unrelated to BaseChatModel.stream_v2 and not supported via
  stream_events(version="v3") in the currently installed langgraph.
2026-04-30 15:07:27 -04:00
Nick Hollon
536b471efd docs(core): rewrite stream_v2 references to stream_events v3
Update all docstrings and comments in production code to refer to the
public stream_events(version="v3") / astream_events(version="v3") API
rather than the removed stream_v2 / astream_v2 methods.
2026-04-30 15:01:40 -04:00
Nick Hollon
271fcc8424 test(core): migrate streaming tests to stream_events(version='v3')
Rename test_stream_v2.py -> test_chat_model_v3_stream.py, replace all
.stream_v2() / .astream_v2() call sites in tests with the new public API
.stream_events(version="v3") / .astream_events(version="v3"), and update
function names + docstrings to match.
2026-04-30 15:01:34 -04:00
Nick Hollon
d1054edb0e refactor(core): rename _should_stream_v2 to _should_use_protocol_streaming 2026-04-30 14:48:22 -04:00
Nick Hollon
8111e9e6f1 fix forward stop kwarg through v1/v2 path 2026-04-30 14:46:41 -04:00
Nick Hollon
f8484de693 refactor(core): remove stream_v2/astream_v2 from Runnable and RunnableBinding 2026-04-30 14:45:00 -04:00
Nick Hollon
22867ecf68 feat(core): dispatch stream_events(version='v3') on BaseChatModel 2026-04-30 14:35:14 -04:00
Nick Hollon
484a99a7cb fix code review feedback for stream_events v3 2026-04-30 14:30:54 -04:00
Nick Hollon
9ab26d5e6d feat(core): add stream_events version='v3' overload
Adds @overload signatures to `Runnable.astream_events` and introduces a
new `Runnable.stream_events` sync method, both accepting `version='v3'`.
The base-class implementation raises `NotImplementedError` with a message
directing callers to use a subclass that implements the v3 streaming
protocol (BaseChatModel, CompiledGraph). v1/v2 behavior is unchanged.
2026-04-30 14:25:37 -04:00
Nick Hollon
7d91c18c6a build(langchain): point langgraph at nh/streaming-for-alpha-release 2026-04-30 14:11:07 -04:00
Nick Hollon
d0d132fef3 merge: bring in cb/chat-model-updates 2026-04-30 14:04:07 -04:00
Nick Hollon
650ec3c02b merge: bring in nh/langgraph-api-test-branch 2026-04-30 14:04:01 -04:00
Mason Daugherty
38553c3f2d release(perplexity): 1.2.0 (#37091) langchain-perplexity==1.2.0 2026-04-29 17:54:27 -04:00
James Liounis
28f5448dd4 feat(perplexity): add PerplexityEmbeddings (#37082)
## Description

This PR adds a new `PerplexityEmbeddings` class to the
`langchain-perplexity` partner package, providing first-class support
for the Perplexity Embeddings API alongside the existing
`ChatPerplexity`, `PerplexitySearchRetriever`, and
`PerplexitySearchResults` integrations.

### What was added

- `langchain_perplexity/embeddings.py` — `PerplexityEmbeddings` class
implementing `langchain_core.embeddings.Embeddings` with sync
(`embed_documents`, `embed_query`) and async (`aembed_documents`,
`aembed_query`) methods. Defaults to model `pplx-embed-v1-4b` and reuses
the existing `_utils.initialize_client` helper for API key resolution
(`PPLX_API_KEY` / `PERPLEXITY_API_KEY`).
- `__init__.py` exports `PerplexityEmbeddings` and adds it to `__all__`.
- Unit tests under `tests/unit_tests/test_embeddings.py` covering
sync/async paths with mocked clients (no network).
- Integration tests under `tests/integration_tests/test_embeddings.py`,
gated on `PPLX_API_KEY` (matches the pattern in `test_search_api.py`).
- README updated to advertise the new component.

### Why

LangChain users already get chat, search, and tool wrappers from
`langchain-perplexity`, but had to drop down to the raw Perplexity SDK
to use embeddings. This closes that gap.

### References

- Perplexity Embeddings docs: https://docs.perplexity.ai/docs/embeddings
- Perplexity Embeddings API reference:
https://docs.perplexity.ai/api-reference/embeddings-post

### Issue

Closes #36726

## Testing

- `cd libs/partners/perplexity && make lint` — passes (ruff, format,
mypy).
- `cd libs/partners/perplexity && make test` — all unit tests pass (59
passed, 1 skipped).
- Integration tests will run in CI with secrets; they exercise real
`embed_documents` / `embed_query` / async variants against the live API
and assert vector dimensionality consistency.

---------

Co-authored-by: Claude Agent <agent@anthropic.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-04-29 17:51:50 -04:00
Sydney Runkle
90b0047270 release(langchain): 1.2.16 (#37085) langchain==1.2.16 2026-04-29 17:00:34 -04:00
open-swe[bot]
ba897ffa7e chore(docs): update x handle references (#37081)
## Description
Updates package metadata and README badges so LangChain social links
point to the new `@langchain_oss` X handle. This was completed with
AI-agent assistance.

## Test Plan
- [ ] Validate README badges and package metadata links point to
`https://x.com/langchain_oss`

_Opened collaboratively by Mason Daugherty and open-swe._

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Mason Daugherty <61371264+mdrxy@users.noreply.github.com>
2026-04-29 13:56:09 -04:00
Nick Hollon
21d113aa86 chore(langchain): point langgraph at nh/langgraph-api-test-branch
Update the langgraph git source to use the nh/langgraph-api-test-branch
branch and fix the EventLog -> StreamChannel rename in tests.
2026-04-29 12:59:53 -04:00
Nick Hollon
aee5083937 chore(core): bump langchain-protocol to 0.0.14 and regen lock files
Remove git branch override for langchain-protocol and bump the version
spec to >=0.0.14. Regenerate all lock files across the monorepo.
2026-04-29 12:44:48 -04:00
Nick Hollon
0e1ebc250e fix(anthropic): cast MessageFinishData to dict for metadata access in test
The `MessageFinishData` TypedDict doesn't declare the `metadata` key
that the compat bridge injects at runtime. Cast to `dict[str, Any]` to
satisfy mypy, matching the existing pattern used for content blocks in
the same test.
2026-04-29 11:31:49 -04:00
langchain-model-profile-bot[bot]
6b4bea7d5d chore(model-profiles): refresh model profile data (#37074)
Automated refresh of model profile data for all in-monorepo partner
integrations via `langchain-profiles refresh`.

🤖 Generated by the `refresh_model_profiles` workflow.

Co-authored-by: mdrxy <61371264+mdrxy@users.noreply.github.com>
2026-04-29 10:43:12 -04:00
Christian Bromann
9e1ee842fb cr 2026-04-28 20:38:45 -07:00
Christian Bromann
8227fd329f cr 2026-04-28 20:18:12 -07:00
Christian Bromann
cb97a91d37 cr 2026-04-28 20:06:32 -07:00
Christian Bromann
522703f199 chore(core): update delta content blocks 2026-04-28 18:58:33 -07:00
ccurme
666dc16b00 release(standard-tests): 1.1.7 (#37067) langchain-tests==1.1.7 2026-04-28 21:08:06 -04:00
open-swe[bot]
97ac1d34d0 fix(anthropic): guard httpx finalizers (#37064) 2026-04-28 20:59:00 -04:00
Mason Daugherty
dfb8a6184c release(anthropic): 1.4.2 (#37061) langchain-anthropic==1.4.2 2026-04-28 16:47:29 -04:00
Mason Daugherty
7a4594b682 fix(anthropic): restore cache_control on non-direct subclasses (#37057)
Closes #37042

---

`AnthropicPromptCachingMiddleware` was unconditionally setting top-level
`cache_control` in `model_settings` for any `ChatAnthropic` subclass.
That field is direct-Anthropic-API only — `ChatAnthropicBedrock` (which
subclasses `ChatAnthropic` and passed the existing `isinstance` gate)
errored with `cache_control: Extra inputs are not permitted`.
Investigating that surfaced a related regression: PR #35967 also deleted
the block-level `cache_control` injection in `_get_request_payload`,
which silently disabled caching entirely for non-direct subclasses
(Bedrock had been falling back to in-block breakpoints). This restores
both paths.

## Changes
- Add `_is_direct_anthropic_llm_type` predicate that allowlists
`_llm_type == "anthropic-chat"`. Both the middleware's
`_supports_automatic_caching` and the new branch in
`ChatAnthropic._get_request_payload` route through it, so any subclass
that overrides `_llm_type` (Bedrock today, future direct-API variants
tomorrow) is treated as non-direct by default. Replaces the prior
substring-matching denylist on `"bedrock"`/`"vertex"`.
- Restore `_collect_code_execution_tool_ids`,
`_is_code_execution_related_block`, and a new
`_apply_cache_control_to_last_eligible_block` helper in `chat_models`.
For non-direct subclasses, `_get_request_payload` now pops
`cache_control` from kwargs and walks messages newest-to-oldest,
attaching the breakpoint to the last block that isn't
`code_execution`-related (Anthropic forbids breakpoints on those).
- Emit `UserWarning` when `cache_control` is requested but every
candidate block is `code_execution`-related — previously a silent drop.
- `AnthropicPromptCachingMiddleware._apply_caching` now sets the
top-level `cache_control` only when
`_supports_automatic_caching(request.model)`. System-message and
tool-definition breakpoints continue to apply for all `ChatAnthropic`
subclasses, since those are accepted by every transport.
- Note: `ChatAnthropicVertex` does not subclass `ChatAnthropic` (it
lives in `langchain-google-vertexai` and ships its own
`_get_request_payload`), so the chat-models changes here only affect
Bedrock. The middleware-side gate covers Vertex implicitly via the
`isinstance(request.model, ChatAnthropic)` check that already excludes
it.
2026-04-28 16:41:22 -04:00
Nick Hollon
e24a80be6c update import for tests so they will pass 2026-04-28 12:17:54 -04:00
Nick Hollon
5f36ae3131 some fixups after merge 2026-04-28 12:13:06 -04:00
Nick Hollon
5ff0b673c0 Merge remote-tracking branch 'origin/master' into nh/agent-streamer
# Conflicts:
#	libs/core/langchain_core/language_models/_compat_bridge.py
#	libs/core/langchain_core/language_models/chat_model_stream.py
#	libs/core/langchain_core/language_models/chat_models.py
#	libs/core/pyproject.toml
#	libs/core/tests/unit_tests/language_models/test_chat_model_stream.py
#	libs/core/tests/unit_tests/language_models/test_chat_model_streamer.py
#	libs/core/tests/unit_tests/language_models/test_compat_bridge.py
#	libs/core/tests/unit_tests/language_models/test_stream_v2.py
#	libs/core/tests/unit_tests/language_models/test_v1_parity.py
#	libs/core/uv.lock
#	libs/langchain/uv.lock
#	libs/langchain_v1/langchain/agents/factory.py
#	libs/langchain_v1/uv.lock
#	libs/model-profiles/uv.lock
#	libs/partners/anthropic/tests/unit_tests/test_chat_models.py
#	libs/partners/anthropic/uv.lock
#	libs/partners/chroma/uv.lock
#	libs/partners/deepseek/uv.lock
#	libs/partners/exa/uv.lock
#	libs/partners/fireworks/uv.lock
#	libs/partners/groq/uv.lock
#	libs/partners/huggingface/uv.lock
#	libs/partners/mistralai/uv.lock
#	libs/partners/nomic/uv.lock
#	libs/partners/ollama/uv.lock
#	libs/partners/openai/uv.lock
#	libs/partners/openrouter/uv.lock
#	libs/partners/perplexity/uv.lock
#	libs/partners/qdrant/uv.lock
#	libs/partners/xai/uv.lock
#	libs/standard-tests/uv.lock
#	libs/text-splitters/uv.lock
2026-04-28 11:32:34 -04:00
Nick Hollon
bbb0592703 update langchain_v1 stream_v2 to reflect latest work on langgraph 2026-04-28 11:10:20 -04:00
Mason Daugherty
37be34be82 fix(core): make removal optional in warn_deprecated (#37056)
Drop the `NotImplementedError` branch in `warn_deprecated` so callers
can pass `pending=False` without specifying a `removal` version. The
previous behavior contradicted the docstring (which claimed an empty
default would auto-compute a removal version) — no such computation
existed; the function just raised a placeholder "Need to determine which
default deprecation schedule to use" error.
2026-04-28 11:05:31 -04:00
langchain-model-profile-bot[bot]
5790244b95 chore(model-profiles): refresh model profile data (#37051)
Automated refresh of model profile data for all in-monorepo partner
integrations via `langchain-profiles refresh`.

🤖 Generated by the `refresh_model_profiles` workflow.

Co-authored-by: mdrxy <61371264+mdrxy@users.noreply.github.com>
2026-04-28 10:21:33 -04:00
Deepak Bhagat
cd80a805b2 fix(text-splitters): remove invalid and duplicate separators in Kotlin, Rust, and Haskell (#37039)
## Summary

Fixes four issues in `get_separators_for_language()` in `character.py`:

- **Kotlin**: removed `"\ncase "` — `case` is not a Kotlin keyword.
Kotlin uses `when` expressions (already present in the list). This was
copied from Java/Swift.
- **Rust**: removed duplicate `"\nconst "` — appeared twice, once under
function definitions and again under control flow statements.
- **Haskell**: removed duplicate `"\n:: "` — appeared under function
definitions and again under type declarations.
- **Haskell**: removed duplicate `"\ndata "` — appeared under type
declarations and again under record field declarations.

All four are dead separators that never match or produce redundant
splits.

## Issue

Closes #37038

## Types of changes

- [x] Bug fix

## Checklist

- [x] I have read the CONTRIBUTING doc
- [x] Lint and unit tests pass locally with my changes
2026-04-27 15:08:12 -04:00
Dayna Blackwell
3b9750f0a4 fix(text-splitters): remove incorrect C# and Elixir separator keywords (#37037)
## Summary

Removes two incorrect separators from `get_separators_for_language()` in
`RecursiveCharacterTextSplitter`:

- **C#**: `"\nimplements "` is a Java keyword. C# uses `:` for interface
implementation. This separator never matches valid C# source code.
- **Elixir**: `"\nwhile "` does not exist in Elixir. The language uses
recursion and `Enum.reduce_while/3` instead of while loops.

Both are dead separators that silently degrade chunking quality by
occupying positions in the separator priority list without contributing
useful split points.

## Tests

Added two targeted tests:
- `test_csharp_separators_no_java_keywords`: verifies `"\nimplements "`
is not in the C# separator list
- `test_elixir_separators_no_while`: verifies `"\nwhile "` is not in the
Elixir separator list

Existing `test_csharp_code_splitter` continues to pass (no change to
expected output since `implements` never matched valid C# code).

Full suite: 129 passed, 0 failed.

Fixes #37030
2026-04-27 13:48:19 -04:00
Sydney Runkle
3b945d02d9 perf(langchain): stop inlining agent state into tool-dispatch Sends (#36960)
## Summary

Stop inlining the full agent state into every tool-dispatch `Send` in
`create_agent`. Dispatch with the bare list form `Send("tools",
[tool_call])` and let `ToolNode` hydrate `ToolRuntime.state` from graph
channels at tool-execution time.

**Depends on**
[langchain-ai/langgraph#7594](https://github.com/langchain-ai/langgraph/pull/7594)
which teaches `ToolNode` to read channel state via `CONFIG_KEY_READ`
when given a bare tool-call list. `uv.lock` pins that branch for CI
while the langgraph PR is in flight — this pin will be reverted to a
published `langgraph` version before merge.

## What was happening

Before this change, every pending tool call produced a `Send` whose
payload was:

```python
ToolCallWithContext(
    __type="tool_call_with_context",
    tool_call=tool_call,
    state=state,   # ← the FULL agent state dict, including messages list
)
```

For any agent that runs many turns, `state["messages"]` grows linearly
with the conversation. Every super-step that dispatches tools serializes
that whole list into every `Send`, and those Sends live forever in the
checkpointer's `__pregel_tasks` writes. The result is **O(N²)
`__pregel_tasks` storage** across a run.

## What changed

- `libs/langchain_v1/langchain/agents/factory.py`:
- `_make_model_to_tools_edge` now returns `Send("tools", [tool_call])` —
no inlined state.
  - Drops the `ToolCallWithContext` import.
- `libs/langchain_v1/pyproject.toml` + `libs/langchain_v1/uv.lock`:
- Temporary `[tool.uv.sources]` pin on `langgraph`,
`langgraph-prebuilt`, `langgraph-checkpoint` to the companion PR branch
so CI exercises both changes end-to-end. Revert after langgraph release.

## Why it's safe

- Same snapshot semantics as before. `Send` is emitted at the end of the
model super-step and consumed at the start of the tools super-step;
channels by that point reflect every write from the model super-step
(including the new AIMessage). Parallel tool tasks all see the same
values since sibling writes don't land until end-of-super-step.
- Legacy `ToolCallWithContext` input path is preserved in `ToolNode` —
no-op for any external caller still constructing it by hand.

## Test plan

- [x] `tests/unit_tests/agents/` — **738 passed, 2 skipped, 1 xfailed**
- [x] `ruff check .` / `ruff format .` — clean
- [x] `mypy langchain/agents/factory.py` — clean
- [x] Before/after benchmark (below)

## Benchmark

Script runs `create_agent` with a mock `GenericFakeChatModel` and two
tools (`write_file`, `edit_file`). Each of the N turns dispatches 2 tool
calls. After the run, the `InMemorySaver` is inspected for bytes stored
under `__pregel_tasks` — the channel that carries the tool-dispatch
`Send` payloads.

| N | TASKS before | TASKS after | ratio |
|---:|---:|---:|---:|
| 5   | 87.6 KB | **4.7 KB**  | **18.6× smaller**   |
| 10  | 335 KB  | **9.4 KB**  | **35.7× smaller**   |
| 25  | 2.05 MB | **23.7 KB** | **86.5× smaller**   |
| 50  | 8.14 MB | **47.6 KB** | **171× smaller**    |
| 100 | 32.5 MB | **95.3 KB** | **341× smaller**    |
| 200 | 130 MB  | **192 KB**  | **677× smaller**    |
| 500 | 815 MB  | **482 KB**  | **1,691× smaller**  |

**Growth shape:**

- **Before:** per-Send bytes scale with current `messages` length (full
state is inlined), so total TASKS across N turns = Σ(2 × k) for k=1..N ≈
O(N²).
- **After:** per-Send bytes are constant — just the `tool_call` dict.
Total TASKS is O(#dispatches), completely independent of conversation
length. In this bench with ~2 dispatches/turn: **940–964 bytes per turn
across N=5..500, essentially flat.**

An agent that makes 100 tool calls in a single turn pays the same TASKS
cost as one that makes 100 across 50 turns — which is the semantically
correct behavior.

Note: the `messages` channel is unchanged by this PR — it's still the
dominant storage term (growing O(N²) via `add_messages`). TASKS was a
second, compounding cost sitting on top of it; at N=100 it added 40% on
top of `messages`, at N=500 it added 67%. After the fix, TASKS is a
rounding error regardless of N.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:32:28 -04:00
Lauren Hirata Singh
aac258eaaa chore(docs): update comment for chatopenai (#37034)
Fixes DOC-526
2026-04-27 11:43:57 -04:00
langchain-model-profile-bot[bot]
83718b1129 chore(model-profiles): refresh model profile data (#37015)
Automated refresh of model profile data for all in-monorepo partner
integrations via `langchain-profiles refresh`.

🤖 Generated by the `refresh_model_profiles` workflow.

Co-authored-by: mdrxy <61371264+mdrxy@users.noreply.github.com>
2026-04-27 09:48:09 -04:00
Sharvil Saxena
78546e9242 fix(core): validate batch_size in _batch and _abatch to prevent infinite loop (#36663) 2026-04-26 15:13:20 -04:00
Kanav Bansal
4613a4d951 docs(langchain): correct import paths in agent middleware docstrings (#36987) 2026-04-26 15:11:27 -04:00
langchain-model-profile-bot[bot]
d44833ce34 chore(model-profiles): refresh model profile data (#37005)
Automated refresh of model profile data for all in-monorepo partner
integrations via `langchain-profiles refresh`.

🤖 Generated by the `refresh_model_profiles` workflow.

Co-authored-by: mdrxy <61371264+mdrxy@users.noreply.github.com>
2026-04-25 16:24:14 -04:00
Mason Daugherty
87ba30f097 ci(infra): label release jobs, resolve package name in run title (#36998)
Polish the manual release workflow (`_release.yml`) so the Actions UI is
readable at a glance — job display names, a run title that reflects the
actual published package, and a broader partner matrix for the
core-compat sanity check.

## Changes
- Add `name:` labels to each job (`📦 Build distribution`, `📝 Generate
release notes`, `🧪 Publish to TestPyPI`, ` Pre-release checks`, `🔄 Test
prior partners against new core`, `🚀 Publish to PyPI`, `🏷️ Tag GitHub
release`). Job IDs are unchanged, so all `needs:` references still
resolve.
- Rewrite `run-name` to resolve the dropdown value to the actual PyPI
package name — e.g. `core` → `langchain-core`, `openai` →
`langchain-openai`, with explicit remaps for the three that don't follow
`langchain-{name}` (`langchain` → `langchain-classic`, `langchain_v1` →
`langchain`, `standard-tests` → `langchain-tests`). `workflow_call`
callers passing full `libs/...` paths and manual overrides are returned
verbatim.
- Simplify `test-dependents` label to `🐍 Test dependent: ${{
matrix.package.path }} (Python ${{ matrix.python-version }})`.
langchain-openai==1.2.1
2026-04-24 15:38:25 -04:00
Mason Daugherty
56d6e89be0 hotfix: bump min core versions (#36996) 2026-04-24 15:23:28 -04:00
Mason Daugherty
a70e7ab80e release(openai): 1.2.1 (#36995) 2026-04-24 15:04:36 -04:00
Mason Daugherty
5a37cd5537 fix(openai): add gpt-5.5 pro to Responses API check (#36994) 2026-04-24 14:58:48 -04:00
Nick Hollon
c4498ccaf9 chore(core): mark stream_v2/astream_v2 as beta (#36992) 2026-04-24 13:27:38 -04:00
Nick Hollon
fa0f0d8efa release(core): 1.3.2 (#36990) langchain-core==1.3.2 2026-04-24 11:46:25 -04:00