Commit Graph

15800 Commits

Author SHA1 Message Date
Nick Hollon
922a000f21 fix(core): preserve reasoning block extras across stream deltas
Anthropic's thinking stream emits a `signature_delta` after the
reasoning text finishes. The adapter surfaces this as a reasoning
delta carrying `extras.signature` (and no new text). Two places
were dropping those fields while assembling the accumulated block:

- `_compat_bridge._accumulate` only concatenated the `reasoning`
  text, silently discarding any other keys (including `extras`) on
  later deltas.
- `chat_model_stream._push_content_block_finish` rebuilt the
  finalized reasoning block as `{"type": "reasoning", "reasoning": ...}`,
  dropping everything the finish event carried.

Together, these stripped Claude's `extras.signature` from the
assembled `AIMessage`, and the next turn in a `create_agent` loop
failed with `messages.<n>.content.<k>.thinking.signature: Field
required`.

The bridge now merges `extras` (so earlier keys survive later
deltas) and replaces other non-text fields; `ChatModelStream`
spreads the incoming finish block before overwriting the two
fields it owns.

Covered by the new
`test_lifecycle_validator_anthropic_reasoning_preserves_signature`
case.
2026-04-21 14:20:59 -04:00
Nick Hollon
be3a26b5de more testing 2026-04-21 13:44:33 -04:00
Nick Hollon
07c71ae632 docs(core): document positional-fallback fragility in bridge
When a provider emits content_blocks without an `index` field (e.g.
anthropic `_stream` with coerce_content_to_string=True for pure text),
the bridge's positional-0 fallback merges successive chunks into one
block. This works correctly today because the only coerced-string path
in the anthropic integration is mutually exclusive with any structured
(indexed) emission. Document the scenario that would surface the gap
and the two ways to close it (native _stream_chat_model_events hook or
'continue on anonymous key' bridge rule) so a future integration
doesn't discover the edge case the hard way.
2026-04-21 13:25:52 -04:00
Nick Hollon
810def4fc5 test(core): add stream lifecycle validator and provider coverage
New `langchain_tests.utils.stream_lifecycle.assert_valid_event_stream`
helper enforces the protocol contract on any event stream:

- single message-start / message-finish envelope
- blocks do not interleave (each block finishes before the next starts)
- sequential uint wire indices from 0
- accumulated deltas match the finish payload for deltaable types

Applied at three levels:

- core/test_compat_bridge: provider-style emission patterns exercised
  directly through chunks_to_events / message_to_events (openai chat
  completions int indices, openai responses/v1 string identifiers,
  anthropic-style per-chunk int indices, inline image, invalid tool
  call, empty stream)
- openai partner: validator applied to stream_v2 against the existing
  responses-api mock and to a new chat-completions stream_v2 test
- anthropic partner: new mock stream of RawMessageStartEvent +
  RawContentBlock* events threaded through _stream via `_create`
  patch; covers thinking + text + tool_use lifecycle with tool-use
  stop_reason

Enabling thinking on the anthropic test flips coerce_content_to_string
off so every block carries a proper integer index — the structured
path the bridge actually exercises. Default-mode (no tools / thinking /
docs) coerces text to a plain string and strips per-chunk indices; the
bridge handles that branch by collapsing to positional-0 and it is a
known separate code path, intentionally not covered here.
2026-04-21 12:17:56 -04:00
Nick Hollon
4062a8db89 fix(core): emit per-block lifecycle for string-keyed content blocks
Streams where content_blocks carries string index identifiers (e.g.
OpenAI responses/v1 mode with 'lc_rs_305f30', 'lc_txt_1') collapsed
all blocks to wire index 0 because _iter_protocol_blocks fell back to
positional i for non-int indices. Every block appeared as a delta of
block 0, and only one content-block-finish event fired at the end of
the stream.

Keep the raw block key (int or string) internally, allocate sequential
uint wire indices per distinct block, and finish the previously-open
block when a new block key appears — matching the protocol's
no-interleave rule.
2026-04-21 12:02:33 -04:00
Nick Hollon
2f14205acb fix(core): strip heavy payload fields from content-block-start
Self-contained content blocks (image, audio, video, file, non_standard,
finalized tool_call) were emitting their full payload on both
content-block-start and content-block-finish, doubling wire bandwidth
and JSON parse cost when providers emit large inline base64 media.

Emit a minimal skeleton on content-block-start — correlation fields
(id, name, toolCallId) and small metadata (mime_type, url, status)
are preserved; heavy fields (data, args, output, transcript, value)
are stripped and carried by content-block-finish only. Required CDDL
fields get minimal placeholders so start still validates.
2026-04-21 11:52:22 -04:00
Nick Hollon
0640e55c3a fix(infra): regenerate langchain_v1 and anthropic locks for langchain-protocol
CI was failing with 'No module named langchain_protocol' because these
two lockfiles weren't regenerated when core added the langchain-protocol
dep. Regenerated from master's baseline using --no-sources-package for
langgraph* to avoid the local editable path pollution.
2026-04-21 11:30:23 -04:00
Nick Hollon
a266a0bf73 fix(infra): drop stray langgraph bumps from polluted lockfiles
Earlier lock regens picked up editable langgraph paths from local dev
setup, inflating langgraph to 1.1.7a2 in openai/model-profiles/langchain
locks. Rebase against master's baseline via uv lock --no-sources-package
for langgraph* so the only diff vs master is the langchain-protocol
addition from core.
2026-04-21 11:24:23 -04:00
Nick Hollon
92e09dae14 Merge remote-tracking branch 'origin/master' into nh/content-block-centric-streaming
# Conflicts:
#	libs/langchain/uv.lock
#	libs/partners/huggingface/uv.lock
2026-04-21 11:13:00 -04:00
Nick Hollon
d01f5b1110 fix polluted lockfiles 2026-04-21 11:05:31 -04:00
Nick Hollon
2bb0711ca8 fix linting and update stale lock files to reflect langchain-protocol dep 2026-04-21 10:56:34 -04:00
langchain-model-profile-bot[bot]
46df8365f2 chore(model-profiles): refresh model profile data (#36911)
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-21 10:08:58 -04:00
Kanav Bansal
fb6ab993a7 docs(langchain): correct import path in ModelCallLimitMiddleware docstring (#36895)
## Summary

Updates the example in `ModelCallLimitMiddleware` docstring to use the
correct import path. The previous import referenced a non-existent
module, which could cause confusion for users following the
documentation.
2026-04-21 01:43:27 -04:00
Jacob Lee
40026a7282 feat(core): Update inheritance behavior for tracer metadata for special keys (#36900)
JS equivalent: https://github.com/langchain-ai/langchainjs/pull/10733
2026-04-20 14:58:01 -07:00
ccurme
37f0b37f1c release(openai): 1.1.15 (#36901) langchain-openai==1.1.15 2026-04-20 15:47:20 -04:00
ccurme
19b0805bc1 fix(openai): accommodate dict response items in streaming (#36899) 2026-04-20 15:44:01 -04:00
Nick Hollon
64ebfad240 fix(core): mark v2 stream output as output_version=v1
_assemble_message builds AIMessage content from v1 protocol blocks
(tool calls typed "tool_call"). Without the output_version marker,
provider request builders that gate v1->provider translation on that
flag (e.g. ChatAnthropic._get_request_payload) pass the v1 blocks
through unconverted and the API rejects them.
2026-04-20 13:19:17 -04:00
Thomas
8fec4e7cee fix(openai): infer azure chat profiles from model name (#36858) 2026-04-19 11:06:26 -04:00
langchain-model-profile-bot[bot]
02991cb4cf chore(model-profiles): refresh model profile data (#36864)
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-18 15:32:37 -05:00
Nick Hollon
c11d57a86d docs(core): add Args sections to set_arequest_more 2026-04-18 13:12:13 -04:00
Nick Hollon
06dcfaa596 feat(core): propagate async pump hook through AsyncProjection
Under caller-driven async streaming, `AsyncChatModelStream`
projections deadlocked when iterated inside an outer `async for
stream in run.messages` loop: the projection's `asyncio.Event` was
only set by external dispatch, but no task was driving the pump
while the consumer was suspended in the inner iteration.

Mirror the sync `Projection._request_more` path on the async side:
- `AsyncProjection.set_arequest_more` stores an async pull callback.
- `_AsyncProjectionIterator.__anext__` drains the callback in an
  inner loop when wired, falling back to the event wait otherwise.
- `_await_impl` drives the callback too so `await stream.output`
  and `await stream.usage` advance the producer.
- `AsyncChatModelStream.set_arequest_more` fans the callback out to
  every projection so langgraph's `AsyncGraphRunStream` can wire it
  on stream construction via a transformer `_bind_apump` hook.

Pump-exhaustion-without-completion ends iteration cleanly rather
than hanging — matches the pragmatic contract for graphs that
exhaust mid-stream.
2026-04-18 13:11:04 -04:00
Jacob Lee
ee95ad6907 feat(langchain): ls_agent_type tag on create_agent calls (#36774) 2026-04-17 15:39:22 -07:00
Mason Daugherty
fd901803f7 ci: auto-close issues without issue type from external users (#36857)
Port https://github.com/langchain-ai/deepagents/pull/2809
2026-04-17 16:23:29 -05:00
Nick Hollon
bf64733f74 feat(core): route invoke through v2 event path for _V2StreamingCallbackHandler
Adds `_V2StreamingCallbackHandler`, a marker class in
`tracers/_streaming.py` that handlers can inherit to signal they consume
`on_stream_event` rather than `on_llm_new_token`. Extracts the shared
event-producing logic from `stream_v2` / `astream_v2` into
`_iter_v2_events` / `_aiter_v2_events` helpers, which pick the native
`_stream_chat_model_events` hook or fall back to `chunks_to_events`
bridged from `_stream`.

`BaseChatModel.invoke` / `ainvoke` now route through the v2 event
generator when any attached handler inherits the marker:
`_generate_with_cache` / `_agenerate_with_cache` gain a v2 branch,
parallel to the existing v1 streaming branch, that drains the helper
into a `ChatModelStream` and wraps the assembled `AIMessage` as a
`ChatResult`. Caching, rate limiting, run lifecycle, and `llm_output`
merging stay on the existing generate path — the v2 and v1 branches
diverge only on which callback fires per chunk.

The marker is a concrete class rather than a `runtime_checkable`
`Protocol` on purpose: an empty Protocol matches every object and
would misroute every call.
2026-04-17 15:58:20 -04:00
dependabot[bot]
b921b07a92 chore: bump langsmith from 0.7.13 to 0.7.31 in /libs/langchain (#36812)
Bumps [langsmith](https://github.com/langchain-ai/langsmith-sdk) from
0.7.13 to 0.7.31.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langsmith-sdk/releases">langsmith's
releases</a>.</em></p>
<blockquote>
<h2>v0.7.31</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(deps-dev): bump langchain-core from 1.2.23 to 1.2.28 in
/python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2692">langchain-ai/langsmith-sdk#2692</a></li>
<li>chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.82.0 to
0.84.0 in /js by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2684">langchain-ai/langsmith-sdk#2684</a></li>
<li>chore(deps): bump cryptography from 46.0.6 to 46.0.7 in /python by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2693">langchain-ai/langsmith-sdk#2693</a></li>
<li>chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.84.0 to
0.85.0 in /js by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2700">langchain-ai/langsmith-sdk#2700</a></li>
<li>feat(py): Tag OpenAI Agent Python SDK runs with ls_agent_type by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2699">langchain-ai/langsmith-sdk#2699</a></li>
<li>feat(js): Adds ls_agent_type metadata to AI SDK runs by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2701">langchain-ai/langsmith-sdk#2701</a></li>
<li>chore(deps-dev): bump types-tqdm from 4.67.3.20260303 to
4.67.3.20260408 in /python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2710">langchain-ai/langsmith-sdk#2710</a></li>
<li>chore(deps): bump pnpm/action-setup from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2705">langchain-ai/langsmith-sdk#2705</a></li>
<li>chore(deps): bump the py-minor-and-patch group across 1 directory
with 10 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2711">langchain-ai/langsmith-sdk#2711</a></li>
<li>chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.85.0 to
0.86.0 in /js by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2702">langchain-ai/langsmith-sdk#2702</a></li>
<li>chore(deps): bump actions/github-script from 8 to 9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2706">langchain-ai/langsmith-sdk#2706</a></li>
<li>chore(deps-dev): bump the js-minor-and-patch group across 1
directory with 7 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2712">langchain-ai/langsmith-sdk#2712</a></li>
<li>chore(deps-dev): bump types-psutil from 7.2.2.20260130 to
7.2.2.20260408 in /python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2709">langchain-ai/langsmith-sdk#2709</a></li>
<li>chore(deps-dev): bump rich from 14.3.3 to 15.0.0 in /python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2708">langchain-ai/langsmith-sdk#2708</a></li>
<li>feat: Filter kwargs from new token events by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2714">langchain-ai/langsmith-sdk#2714</a></li>
<li>release(py): 0.7.31 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2716">langchain-ai/langsmith-sdk#2716</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.30...v0.7.31">https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.30...v0.7.31</a></p>
<h2>v0.7.30</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(python): add service feature to sandbox by <a
href="https://github.com/DanielKneipp"><code>@​DanielKneipp</code></a>
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2665">langchain-ai/langsmith-sdk#2665</a></li>
<li>fix(js): Fix prototype pollution bug in anonymizers by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2690">langchain-ai/langsmith-sdk#2690</a></li>
<li>release(js): 0.5.18 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2691">langchain-ai/langsmith-sdk#2691</a></li>
<li>chore(js/sandbox): suppress warning log by <a
href="https://github.com/hntrl"><code>@​hntrl</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2694">langchain-ai/langsmith-sdk#2694</a></li>
<li>feat(js): Add metadata to Claude Agent SDK JS tracing by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2695">langchain-ai/langsmith-sdk#2695</a></li>
<li>fix(py): Fix run tree memory leak by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2696">langchain-ai/langsmith-sdk#2696</a></li>
<li>release(py): 0.7.30 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2698">langchain-ai/langsmith-sdk#2698</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.29...v0.7.30">https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.29...v0.7.30</a></p>
<h2>v0.7.29</h2>
<h2>What's Changed</h2>
<ul>
<li>release(js): 0.5.17 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2681">langchain-ai/langsmith-sdk#2681</a></li>
<li>feat(py): Fix race condition around Claude Agent SDK instrumentation
by <a href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a>
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2685">langchain-ai/langsmith-sdk#2685</a></li>
<li>release(py): 0.7.29 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2686">langchain-ai/langsmith-sdk#2686</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.28...v0.7.29">https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.28...v0.7.29</a></p>
<h2>v0.7.28</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(py): Support subagent tracing in Claude Agents SDK, fix usage
and duplicate messages by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2670">langchain-ai/langsmith-sdk#2670</a></li>
<li>chore(deps-dev): bump the py-minor-and-patch group across 1
directory with 11 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2677">langchain-ai/langsmith-sdk#2677</a></li>
<li>chore(deps-dev): bump the js-minor-and-patch group across 1
directory with 8 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2667">langchain-ai/langsmith-sdk#2667</a></li>
<li>chore(deps): bump pnpm/action-setup from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2658">langchain-ai/langsmith-sdk#2658</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c434999d05"><code>c434999</code></a>
release(py): 0.7.31 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2716">#2716</a>)</li>
<li><a
href="47d7c4a783"><code>47d7c4a</code></a>
feat: Filter kwargs from new token events (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2714">#2714</a>)</li>
<li><a
href="3c57445b54"><code>3c57445</code></a>
chore(deps-dev): bump rich from 14.3.3 to 15.0.0 in /python (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2708">#2708</a>)</li>
<li><a
href="2be6cd01a2"><code>2be6cd0</code></a>
chore(deps-dev): bump types-psutil from 7.2.2.20260130 to 7.2.2.20260408
in /...</li>
<li><a
href="b8b6ca32d4"><code>b8b6ca3</code></a>
chore(deps-dev): bump the js-minor-and-patch group across 1 directory
with 7 ...</li>
<li><a
href="9897cb33da"><code>9897cb3</code></a>
chore(deps): bump actions/github-script from 8 to 9 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2706">#2706</a>)</li>
<li><a
href="572c018428"><code>572c018</code></a>
chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.85.0 to
0.86.0 in /js (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2702">#2702</a>)</li>
<li><a
href="57447524c8"><code>5744752</code></a>
chore(deps): bump the py-minor-and-patch group across 1 directory with
10 upd...</li>
<li><a
href="960cae7f49"><code>960cae7</code></a>
chore(deps): bump pnpm/action-setup from 5 to 6 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2705">#2705</a>)</li>
<li><a
href="9370e7670a"><code>9370e76</code></a>
chore(deps-dev): bump types-tqdm from 4.67.3.20260303 to 4.67.3.20260408
in /...</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.13...v0.7.31">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 12:54:01 -06:00
dependabot[bot]
9bd63b4ac8 chore: bump langsmith from 0.7.13 to 0.7.31 in /libs/core (#36813)
Bumps [langsmith](https://github.com/langchain-ai/langsmith-sdk) from
0.7.13 to 0.7.31.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/langchain-ai/langsmith-sdk/releases">langsmith's
releases</a>.</em></p>
<blockquote>
<h2>v0.7.31</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(deps-dev): bump langchain-core from 1.2.23 to 1.2.28 in
/python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2692">langchain-ai/langsmith-sdk#2692</a></li>
<li>chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.82.0 to
0.84.0 in /js by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2684">langchain-ai/langsmith-sdk#2684</a></li>
<li>chore(deps): bump cryptography from 46.0.6 to 46.0.7 in /python by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2693">langchain-ai/langsmith-sdk#2693</a></li>
<li>chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.84.0 to
0.85.0 in /js by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2700">langchain-ai/langsmith-sdk#2700</a></li>
<li>feat(py): Tag OpenAI Agent Python SDK runs with ls_agent_type by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2699">langchain-ai/langsmith-sdk#2699</a></li>
<li>feat(js): Adds ls_agent_type metadata to AI SDK runs by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2701">langchain-ai/langsmith-sdk#2701</a></li>
<li>chore(deps-dev): bump types-tqdm from 4.67.3.20260303 to
4.67.3.20260408 in /python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2710">langchain-ai/langsmith-sdk#2710</a></li>
<li>chore(deps): bump pnpm/action-setup from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2705">langchain-ai/langsmith-sdk#2705</a></li>
<li>chore(deps): bump the py-minor-and-patch group across 1 directory
with 10 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2711">langchain-ai/langsmith-sdk#2711</a></li>
<li>chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.85.0 to
0.86.0 in /js by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2702">langchain-ai/langsmith-sdk#2702</a></li>
<li>chore(deps): bump actions/github-script from 8 to 9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2706">langchain-ai/langsmith-sdk#2706</a></li>
<li>chore(deps-dev): bump the js-minor-and-patch group across 1
directory with 7 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2712">langchain-ai/langsmith-sdk#2712</a></li>
<li>chore(deps-dev): bump types-psutil from 7.2.2.20260130 to
7.2.2.20260408 in /python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2709">langchain-ai/langsmith-sdk#2709</a></li>
<li>chore(deps-dev): bump rich from 14.3.3 to 15.0.0 in /python by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2708">langchain-ai/langsmith-sdk#2708</a></li>
<li>feat: Filter kwargs from new token events by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2714">langchain-ai/langsmith-sdk#2714</a></li>
<li>release(py): 0.7.31 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2716">langchain-ai/langsmith-sdk#2716</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.30...v0.7.31">https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.30...v0.7.31</a></p>
<h2>v0.7.30</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(python): add service feature to sandbox by <a
href="https://github.com/DanielKneipp"><code>@​DanielKneipp</code></a>
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2665">langchain-ai/langsmith-sdk#2665</a></li>
<li>fix(js): Fix prototype pollution bug in anonymizers by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2690">langchain-ai/langsmith-sdk#2690</a></li>
<li>release(js): 0.5.18 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2691">langchain-ai/langsmith-sdk#2691</a></li>
<li>chore(js/sandbox): suppress warning log by <a
href="https://github.com/hntrl"><code>@​hntrl</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2694">langchain-ai/langsmith-sdk#2694</a></li>
<li>feat(js): Add metadata to Claude Agent SDK JS tracing by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2695">langchain-ai/langsmith-sdk#2695</a></li>
<li>fix(py): Fix run tree memory leak by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2696">langchain-ai/langsmith-sdk#2696</a></li>
<li>release(py): 0.7.30 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2698">langchain-ai/langsmith-sdk#2698</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.29...v0.7.30">https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.29...v0.7.30</a></p>
<h2>v0.7.29</h2>
<h2>What's Changed</h2>
<ul>
<li>release(js): 0.5.17 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2681">langchain-ai/langsmith-sdk#2681</a></li>
<li>feat(py): Fix race condition around Claude Agent SDK instrumentation
by <a href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a>
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2685">langchain-ai/langsmith-sdk#2685</a></li>
<li>release(py): 0.7.29 by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2686">langchain-ai/langsmith-sdk#2686</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.28...v0.7.29">https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.28...v0.7.29</a></p>
<h2>v0.7.28</h2>
<h2>What's Changed</h2>
<ul>
<li>feat(py): Support subagent tracing in Claude Agents SDK, fix usage
and duplicate messages by <a
href="https://github.com/jacoblee93"><code>@​jacoblee93</code></a> in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2670">langchain-ai/langsmith-sdk#2670</a></li>
<li>chore(deps-dev): bump the py-minor-and-patch group across 1
directory with 11 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2677">langchain-ai/langsmith-sdk#2677</a></li>
<li>chore(deps-dev): bump the js-minor-and-patch group across 1
directory with 8 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2667">langchain-ai/langsmith-sdk#2667</a></li>
<li>chore(deps): bump pnpm/action-setup from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/pull/2658">langchain-ai/langsmith-sdk#2658</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c434999d05"><code>c434999</code></a>
release(py): 0.7.31 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2716">#2716</a>)</li>
<li><a
href="47d7c4a783"><code>47d7c4a</code></a>
feat: Filter kwargs from new token events (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2714">#2714</a>)</li>
<li><a
href="3c57445b54"><code>3c57445</code></a>
chore(deps-dev): bump rich from 14.3.3 to 15.0.0 in /python (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2708">#2708</a>)</li>
<li><a
href="2be6cd01a2"><code>2be6cd0</code></a>
chore(deps-dev): bump types-psutil from 7.2.2.20260130 to 7.2.2.20260408
in /...</li>
<li><a
href="b8b6ca32d4"><code>b8b6ca3</code></a>
chore(deps-dev): bump the js-minor-and-patch group across 1 directory
with 7 ...</li>
<li><a
href="9897cb33da"><code>9897cb3</code></a>
chore(deps): bump actions/github-script from 8 to 9 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2706">#2706</a>)</li>
<li><a
href="572c018428"><code>572c018</code></a>
chore(deps-dev): bump <code>@​anthropic-ai/sdk</code> from 0.85.0 to
0.86.0 in /js (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2702">#2702</a>)</li>
<li><a
href="57447524c8"><code>5744752</code></a>
chore(deps): bump the py-minor-and-patch group across 1 directory with
10 upd...</li>
<li><a
href="960cae7f49"><code>960cae7</code></a>
chore(deps): bump pnpm/action-setup from 5 to 6 (<a
href="https://redirect.github.com/langchain-ai/langsmith-sdk/issues/2705">#2705</a>)</li>
<li><a
href="9370e7670a"><code>9370e76</code></a>
chore(deps-dev): bump types-tqdm from 4.67.3.20260303 to 4.67.3.20260408
in /...</li>
<li>Additional commits viewable in <a
href="https://github.com/langchain-ai/langsmith-sdk/compare/v0.7.13...v0.7.31">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 12:53:51 -06:00
Nick Hollon
a8ce29ab8c fix linting issues 2026-04-17 11:15:07 -04:00
Nick Hollon
cee4dd3852 fix docstring formatting to use google-style single backticks 2026-04-17 11:09:12 -04:00
Nick Hollon
84e0365438 refactor(core): centralize type-laundering cast in compat bridge
Reduce the cast count in _compat_bridge from 9 to 2.  The casts exist
because langchain_core.messages.content.ContentBlock and
langchain_protocol.protocol.ContentBlock are two nominally distinct
TypedDict Unions that are structurally near-identical.
msg.content_blocks returns the core Union; event payloads want the
protocol Union; the bridge launders between them through dict[str, Any].

- Remove redundant casts (isinstance-narrowed dict; getattr Any).
- Use TypedDict constructors (ServerToolCallChunkBlock, ToolCallBlock,
  ServerToolCallBlock) where we build fresh blocks — no cast needed
  for constructor output.
- Introduce _to_protocol_block and _to_finalized_block helpers that
  each hold a single cast with a docstring explaining the seam and
  pointing at the cross-module refactor that would retire them.

CompatBlock's docstring now explains the laundering role.
2026-04-17 10:48:02 -04:00
Eugene Yurtsev
c87cd04927 release(core): release 1.3.0 (#36851)
xRelease 1.3.0
langchain-core==1.3.0
2026-04-17 14:42:01 +00:00
Nick Hollon
2c449ca1f5 refactor(core): trust content_blocks in compat bridge
Collapse _compat_bridge to a single path that reads msg.content_blocks
and emits protocol events. The translator / best-effort / tool_call_chunks
extraction all live in content_blocks already — the legacy branch,
_PROTOCOL_PASS_THROUGH_TYPES, _SELF_CONTAINED_BLOCK_TYPES skeleton
handling, and manual reasoning-variant sniffing were duplicating work.

Side fixes picked up along the way:

- No-provider chunks with both text content and tool_call_chunks silently
  dropped the tool call because the legacy extractor put both at index 0.
  content_blocks places them on distinct indices.
- "server_tool_call_result" (typo) replaced with "server_tool_result" in
  ChatModelStream's finish dispatch and the test that exercises it —
  matches the protocol type that every translator actually emits.

Also collapses duplicated tool_call_chunk / server_tool_call_chunk
handling in chat_model_stream into shared merge/sweep helpers so the
two code paths can't drift apart again (which is how the typo survived).

_compat_bridge.py: 855 -> 581 lines. No public API changes.
2026-04-17 10:29:00 -04:00
ccurme
ae0743ec3b fix(anthropic): strip null encrypted_content from compaction blocks (#36850) langchain-anthropic==1.4.1 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
Nick Hollon
63ca3f2831 feat(core): content-block completeness in v2 stream pipeline
Extend the v2 stream and compat bridge to handle every protocol
ContentBlock variant end-to-end — server tool calls, invalid tool calls,
images, audio, video, file, and non-standard blocks — not just text,
reasoning, and regular tool calls. Previously these were silently dropped
at the bridge's extractor, had no handler in ChatModelStream, and could
not appear in .output.content.

The stream now keeps an index-ordered `_blocks` snapshot as the single
source of truth for .output.content, alongside the existing typed
accumulators that drive the public projections. `_assemble_message`
builds content from that snapshot, emitting protocol-shape `tool_call`
blocks instead of the legacy `tool_use` shape, and collapses to a bare
string only when the message contains exactly one text block.

Bridge extractors (_extract_blocks_from_chunk, _extract_final_blocks) now
pass through any protocol-shape block in msg.content, _accumulate_block
and _delta_block handle server_tool_call_chunk and self-contained types,
and _finalize_block promotes server_tool_call_chunk to server_tool_call
(falling back to invalid_tool_call on JSON failure, symmetric with
regular tool calls). The standard `invalid_tool_calls` field on AIMessage
is also surfaced by the final-block extractor.

Forward-looking: today's partners keep provider-native shapes in
msg.content and expose protocol blocks lazily via the `.content_blocks`
property, so these paths are latent until partners either populate
msg.content with protocol shape or override _stream_chat_model_events.
The bridge is ready.
2026-04-17 09:15:32 -04:00
Nick Hollon
0efc5d538e fix(core): preserve invalid_tool_call blocks in v2 stream output
The compat bridge produces InvalidToolCallBlock when tool-call JSON parse
fails, but ChatModelStream had no handler for it. The finish event was
silently ignored, the stale chunk stayed in _tool_call_chunks, and
_finish's sweep re-parsed (failed again), fell back to args={}, and
appended a valid-looking ToolCallBlock — so the protocol said "invalid"
while the assembled AIMessage said "valid with empty args". An agent layer
downstream could then dispatch the malformed call.

The finish handler now routes invalid_tool_call blocks into
_invalid_tool_calls_acc and deletes the stale chunk entry; _finish's sweep
emits InvalidToolCallBlock on JSON failure instead of an empty-args tool
call; _assemble_message passes invalid_tool_calls through to AIMessage.
2026-04-17 09:06:44 -04:00
Nick Hollon
416d55b3d6 promote projection and stream producer API to public
Renames the stream's and projections' "private" producer-side methods to
public names, since they are the intended call surface for anyone driving
the stream (the pump, langgraph's forthcoming handler, tests). Removes
~36 `noqa: SLF001` suppressions along the way.

On `_ProjectionBase`:
- `_push` -> `push`
- `_finish` -> `complete`
- `_fail` -> `fail`
- adds `done` / `error` read-only properties for sidekicks (iterator)
- `SyncProjection.set_request_more(cb)` replaces direct `_request_more` assignment

On `ChatModelStream`:
- `_bind_pump` -> `bind_pump`
- `_fail` -> `fail`
- adds `output_message` property (non-blocking peek)
- new `dispatch(event)` method replaces the module-level `dispatch_event`
  helper (kept as a thin deprecated wrapper for back-compat)

The genuinely internal helpers (`_record_event`, `_push_*`, `_finish`
on the stream, `_drain`, `_assemble_message`) stay private — they have
one caller each, inside the class.

Remaining SLF001 suppressions in this file are intentional
`_AsyncProjectionIterator` coupling to its projection's `_deltas` and
`_event`; annotated with a comment.
2026-04-16 17:45:15 -04:00
Nick Hollon
204c6af2f1 simplify AsyncProjection with asyncio.Event
Replaces the list-of-futures + `_wake()` pattern with a single
`asyncio.Event` shared by all waiters (the awaitable plus every async
iterator cursor). Each waiter clears the event before awaiting and
re-checks its own condition on wake, so stale notifications don't cause
spin loops.

Single-loop only — if cross-thread wake is ever required, revert to the
list-of-futures pattern with `call_soon_threadsafe`. Noted in the
AsyncProjection docstring.

Net -9 lines; drops `import contextlib` and the per-iteration
`create_future`/`append` boilerplate.
2026-04-16 17:24:14 -04:00
Nick Hollon
6aef1fd4fe format message_to_events per ruff 2026-04-16 17:12:21 -04:00
Nick Hollon
8773cb8c4e add on_stream_event callback for v2 protocol events
Adds a new `on_stream_event` hook on `LLMManagerMixin` / `AsyncCallbackHandler`
that fires once per `MessagesData` event produced by `stream_v2` /
`astream_v2`, with dispatch methods on `CallbackManagerForLLMRun` and
`AsyncCallbackManagerForLLMRun`.

This is v2's observer hook, analogous to `on_llm_new_token` in v1 but at
event granularity rather than chunk. It fires uniformly whether the
provider emits events natively via `_stream_chat_model_events` or goes
through the chunk-to-event compat bridge — observers see the same event
stream regardless of how the underlying model produces output.

Primary consumer: langgraph's forthcoming `StreamProtocolMessagesHandler`,
which can now be a one-line forwarder (lookup namespace metadata by run_id,
push `(ns, "messages", (event, meta))` to the graph's output stream)
instead of re-implementing the chunks-to-events state machine internally.

Does not fire from v1 `stream()` / `astream()`. Purely additive —
`on_chat_model_start`, `on_llm_end`, and `on_llm_error` continue to
bracket a v2 call as they do a v1 call.
2026-04-16 16:53:56 -04:00
Nick Hollon
a1d331e8f0 populate on_llm_end, propagate cancellation, add message_to_events
- `stream_v2` / `astream_v2` now pass the assembled `AIMessage` to
  `on_llm_end` via `LLMResult(generations=[[ChatGeneration(message=...)]])`,
  so LangSmith and other tracers see the final response on v2 calls (was
  previously `generations=[]`).
- `astream_v2`'s producer re-raises `asyncio.CancelledError` ahead of the
  generic handler, so cancellation propagates normally instead of being
  converted into `on_llm_error` + a swallowed exception.
- New `message_to_events` / `amessage_to_events` in `_compat_bridge`
  replay a finalized `AIMessage` as a synthetic content-block lifecycle.
  Intended for the langgraph-side handler that emits protocol events for
  non-streamed node outputs (cache hits, `model.invoke()` inside a node,
  checkpointed state). Turns `_extract_final_blocks` from a dangling
  helper into a real caller.
- Document the optional `_stream_chat_model_events` /
  `_astream_chat_model_events` provider hooks inline at the getattr
  sites so integrators can discover the expected signature.
2026-04-16 16:26:12 -04:00
Nick Hollon
352a725d5c bump langchain-protocol to 0.0.8 from pypi
Drop the local path override in `[tool.uv.sources]` now that 0.0.8 is
published, and raise the lower bound to match the APIs the compat
bridge relies on (notably `MessageFinishData.metadata`).
2026-04-16 16:07:46 -04:00
ccurme
6fb37dba71 release(huggingface): 1.2.2 (#36832) langchain-huggingface==1.2.2 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
Eugene Yurtsev
af0e174ef7 release(core): 1.3.0a3 (#36829)
release 1.3.0a3
langchain-core==1.3.0a3
2026-04-16 15:37:28 -04:00
Eugene Yurtsev
b00646d882 chore(core): keep checkpoint_ns behavior in streaming metadata for backwards compat (#36828)
minor buglet
2026-04-16 15:17:20 -04:00
Nick Hollon
6b203f082d fix(core): forward bound kwargs through RunnableBinding.stream_v2
Add explicit `stream_v2` / `astream_v2` overrides on `RunnableBinding` that
merge `self.kwargs` into the delegated call, mirroring the existing
`stream` / `astream` / `invoke` overrides. Without these, calls that chained
through `bind` or `bind_tools` fell through `__getattr__` (which merges
`self.config` but not `self.kwargs`) and silently dropped bound tools,
stop sequences, and other runtime kwargs.

The returns are typed as `Any` to avoid pulling chat-model types into
`langchain_core.runnables.base`; the method only makes sense when the bound
runnable is a chat model, and `AttributeError` propagates unchanged if it
isn't.

Adds tests covering bound-kwarg forwarding for both sync and async paths
plus the call-time kwarg override semantics.
2026-04-16 15:03:03 -04:00
Nick Hollon
14442f4d10 feat(core): add content-block-centric streaming (v2)
Add `BaseChatModel.stream_v2()` / `astream_v2()` returning a `ChatModelStream`
with typed projections (`.text`, `.reasoning`, `.tool_calls`, `.usage`,
`.output`) plus raw protocol event iteration. Providers that only implement
`_stream()` get a compat bridge that converts `AIMessageChunk`s to the
content-block protocol lifecycle, preserving usage and response metadata for
v1 parity.

- New module `chat_model_stream.py` with `ChatModelStream`, `AsyncChatModelStream`,
  and push/pull projection hierarchy (`SyncProjection`, `SyncTextProjection`,
  `AsyncProjection`).
- New module `_compat_bridge.py` that converts chunk streams to protocol
  events, with `response_metadata` preserved via `MessageStartData.metadata`
  and `MessageFinishData.metadata`.
- `stream_v2` wires `on_chat_model_start` / `on_llm_end` / `on_llm_error`
  callbacks into the pump; `astream_v2` spawns a producer task and awaits it
  alongside the output so `on_llm_end` fires before `await stream` returns.
- tool_use finish-reason inference runs after finalization so malformed
  tool-call JSON (finalized as `invalid_tool_call`) does not flip
  `finish_reason` to `"tool_use"`.
- Add `langchain-protocol>=0.0.6` dependency (local path override retained
  for dev).

Tests cover projection semantics, tool-call streaming (single + parallel +
malformed args), async/sync event replay, callback firing, and v1 parity
(text, tool calls, usage, response metadata, reasoning+text ordering, error
propagation).
2026-04-16 14:41:24 -04:00
Jacob Lee
c04e05feb1 feat(core): Add chat model and LLM invocation params to traceable metadata (#36771)
Equivalent to: https://github.com/langchain-ai/langchainjs/pull/10711/

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
2026-04-16 18:30:54 +00:00
ccurme
92a6e57d60 release(langchain-classic): 1.0.4 (#36827) langchain-classic==1.0.4 2026-04-16 12:55:30 -04:00