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>
Fireworks's chat completions endpoint rejects unknown fields on tool
message content blocks — specifically the `id` key that LangChain
auto-generates on `TextContentBlock`. Add
`_sanitize_chat_completions_content` to strip those extra keys before
the payload hits the wire, preventing `Extra inputs are not permitted`
errors on tool message round-trips.
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>
Sweep classic deprecations so every removal lands on `2.0.0`, runtime
warnings carry the auto-generated since/removal/alternative line, and
replacements steer at `langchain.agents.create_agent` and
`with_structured_output(...)` instead of pre-v1 LangGraph +
`python.langchain.com` links.
## Changes
- **Bump removal targets from `1.0` / `1.0.0` to `2.0.0`** across
agents, chains, memory, retrievers, structured-output, vectorstore
toolkits, and the `langchain_classic._api.module_import` shim — gives
users a real runway now that v1 has shipped.
- **Move bespoke `message=` strings onto `addendum=`** (or split into
`alternative=` + `addendum=`). `warn_deprecated` skips the
auto-generated since/removal/alternative line whenever `message=` is
set, so the prior pattern silently dropped that info from the runtime
`LangChainDeprecationWarning`. Matches the pattern already used in
`HTMLHeaderTextSplitter.split_text_from_url`, which is updated for
consistency.
- **Repoint `alternative=` at v1 replacements**: chains/memory/agent
toolkits → `langchain.agents.create_agent` (with checkpointer or
retrieval-tool guidance in the addendum); `openai_functions` and
`chains/structured_output` → `ChatModel.with_structured_output(...)`;
`openapi` chains → `ChatModel.bind_tools(...)` + HTTP client.
`ConversationChain` no longer points at `RunnableWithMessageHistory`.
- **Refresh `AGENT_DEPRECATION_WARNING`** in
`langchain_classic._api.deprecation` — drop stale LangGraph and
`python.langchain.com` links in favor of `langchain.agents.create_agent`
and the `docs.langchain.com/oss/python/migrate/langchain-v1` guide.
Propagates to all 13 caller sites in `agents/`.
- **Newly deprecate `langchain_classic.chat_models.init_chat_model` and
`langchain_classic.embeddings.init_embeddings`** with the framing
*"maintained in `langchain`; `langchain-classic` retains this entry
point for import-compatibility only"*. The classic docstring examples
and the warning admonition both point at `langchain.chat_models`.
- **Improve `init_chat_model` docstrings** in both `langchain_v1` and
the classic copy: clarify `provider:model` prefix vs. `model_provider=`,
recommend pinned IDs over moving aliases, add the `upstage` provider
row, and refresh examples to GA models (`gpt-5.5`, `claude-opus-4-7`).
- **Standardize partner Anthropic deprecations**: replace
`AnthropicLLM`'s `model_validator(raise_warning)` with
`@deprecated(since="0.1.0", removal="2.0.0",
alternative="ChatAnthropic")`, and pin the `ChatAnthropic`
`output_format` runtime warning at `langchain-anthropic 2.0.0` instead
of "a future version".
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>
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>
## Description
Fixes#36400
During streaming, `AIMessageChunk.__add__` list-concatenates
`reasoning_details` in `additional_kwargs`, fragmenting a single entry
into many. When `_convert_message_to_dict()` serializes conversation
history back to the OpenRouter API for the next turn, these fragmented
entries cause `BadRequestResponseError`.
### Changes
- Add `_merge_reasoning_details()` helper that merges consecutive
entries sharing the same `type` and `index` (streaming fragments) while
preserving distinct entries (legitimate non-streaming data)
- Metadata from later fragments (e.g. `signature`) is preserved in the
merged result
- Entries without `index` are never merged (safe for non-streaming
responses)
- Call `_merge_reasoning_details()` in `_convert_message_to_dict()`
before serializing `reasoning_details`
### Why merge instead of drop?
Non-streaming users (`invoke()`) rely on `reasoning_details` for
structured metadata (`type`, `signature`, `format`, `index`). Dropping
it entirely would be a regression. This approach fixes streaming while
preserving non-streaming functionality, similar to `langchain-openai`'s
`_implode_reasoning_blocks()`.
## Test plan
- [x] Fragmented entries (same type + same index) are merged into one
- [x] Distinct entries (different index) are preserved separately
- [x] Entries without index are never merged
- [x] Metadata from later fragments (e.g. signature) is preserved
- [x] Single-entry lists pass through unchanged
- [x] Round-trip (dict → message → dict) works correctly
- [x] All 210 unit tests pass
---------
Co-authored-by: Mason Daugherty <github@mdrxy.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
Closes#37007
---
`ChatMistralAI` was POSTing `HumanMessage` content lists verbatim, so
canonical `ImageContentBlock` dicts (`{"type": "image", "url"/"base64":
...}`) reached the Mistral API unchanged and were rejected — the API
expects OpenAI-shape `{"type": "image_url", "image_url": {"url":
"..."}}`. Multimodal inputs failed for both URL and base64 images.
## Changes
- Introduce `_format_message_content` in
`langchain_mistralai.chat_models`, which delegates to
`is_data_content_block` and
`convert_to_openai_data_block(api="chat/completions")` from
`langchain-core`. Reuses the same translator `langchain-openai` and
`langchain-fireworks` (#37090) use, so v0 `source_type` blocks, v1
`url`/`base64` blocks, and `file_id` references are all handled by one
canonical path.
- Route `HumanMessage` content through `_format_message_content` in
`_convert_message_to_mistral_chat_message`. Strings, already-translated
`image_url` blocks, and Mistral-specific blocks (`document_url`,
`input_audio`) pass through unchanged; the API surfaces an error for
anything it doesn't recognize.
---------
Co-authored-by: Akash Choudhary <achoudhary@lenovo.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
Add a `service_tier` init kwarg to `ChatFireworks`, mirroring the field
on `ChatOpenAI`. Forwards to the Fireworks chat completions API when
set, and echoes the response's tier back onto `response_metadata` and
`llm_output` so callbacks and consumers can read what the server
actually applied.
Add first-class `session_id` and `trace` constructor fields on
`ChatOpenRouter`, plumbed into the request payload alongside the
existing `route` / `plugins` / `openrouter_provider` knobs. Both
correspond to the OpenRouter
[broadcast](https://openrouter.ai/docs/guides/features/broadcast/overview)
feature for grouping requests under one logical workflow and attaching
per-request observability metadata. Previously these were only reachable
by stuffing them through `model_kwargs` or `.bind()`, neither of which
is discoverable.
[Docs](https://github.com/langchain-ai/docs/pull/3840)
## Changes
- New `session_id: str | None` field with a
`from_env("OPENROUTER_SESSION_ID", default=None)` factory, so a process
can group all requests via env var without threading the value through
application code. Truthy-guarded in `_default_params` so an explicit or
env-sourced empty string is treated as unset.
- New `trace: dict[str, Any] | None` field for per-request trace
metadata (`trace_id`, `trace_name`, `span_name`, `generation_name`,
`parent_span_id`, plus arbitrary extras forwarded as custom metadata).
No env fallback — set per-call or on the constructor.
- Per-call override (`model.invoke(..., session_id=..., trace=...)`)
works through the existing `**kwargs` flow into `_generate` / `_stream`,
with the constructor value preserved across calls.
- Updated the "Key init args — client params" docstring table on
`ChatOpenRouter` to surface both fields.
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>
## Summary
`langchain_fireworks._convert_message_to_dict` ships LangChain canonical
v0/v1 multimodal content blocks (e.g. `{"type": "image", "base64": ...,
"mime_type": ...}`) on the wire unchanged. Fireworks' OpenAI-compatible
chat completions API rejects the unknown `base64`/`mime_type` keys and
the list shape on roles that expect a string, returning HTTP 422 — so
any image upload, including via tools that return image content blocks,
fails for Kimi K2.6 and other Fireworks vision models.
This change mirrors
`langchain_openai.chat_models.base._format_message_content`:
- Walk `content` blocks.
- Drop block types the chat-completions wire doesn't carry (`tool_use`,
`thinking`, `reasoning_content`, `function_call`,
`code_interpreter_call`).
- Detect v0/v1 multimodal data blocks via
`langchain_core.messages.is_data_content_block`, and translate them via
`convert_to_openai_data_block(..., api="chat/completions")`.
- Strings and non-list content pass through unchanged.
Applied in the `ChatMessage`, `HumanMessage`, `SystemMessage`, and
`ToolMessage` paths of `_convert_message_to_dict`. `AIMessage` already
routes through `_convert_from_v1_to_chat_completions` for v1 output and
assistant content is text-only on the way out, so it is left untouched.
## Why this approach
Fireworks is OpenAI-compatible. The canonical → OpenAI translator
already exists in `langchain_core.messages.block_translators.openai` and
is the same one `langchain-openai` uses. Reusing it (rather than
inventing a Fireworks-specific translator) gives:
- v0 (`source_type`-based) and v1 (`base64`/`url`-based) data block
coverage for free.
- Consistent behavior with `langchain-openai` for image, file, and any
future canonical data block.
- A small, focused diff (≈30 lines of new code, plus tests).
## Test plan
- [x] `make test` passes (64/64 unit tests, including 9 new ones for the
new helper and translation paths).
- [x] `make lint` passes (ruff check, ruff format, mypy, lint_imports).
- [ ] End-to-end: image upload to a Kimi K2.6 (Fireworks) agent
translates to `{"type": "image_url", "image_url": {"url":
"data:image/png;base64,..."}}` on the wire and the model returns a
coherent description (validated locally against
`langchain-fireworks==1.0.0` site-packages with the same patch).
---------
Co-authored-by: murugand23 <murugand23@users.noreply.github.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/langchain/network/alerts).
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## 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>
## 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>
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>
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.
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>
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>
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>
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>
`ChatFireworks.max_retries` silently did nothing. The old code assigned
the value to a `ChatCompletionV2` sub-object rather than the base
client, and the pinned Fireworks SDK (0.13.0–0.19.20) never honors its
own `_max_retries` attribute on the base client either. Since the
Stainless-generated 1.x SDK that does implement retries is still
pre-release (1.0.1a63 at time of writing), retry responsibility is
ported to the LangChain side until the pin can be bumped.
Populate `usage_metadata` on streaming responses. Newer Fireworks models
(e.g. Kimi K2 slugs) require an explicit
`stream_options.include_usage=True` opt-in and return token counts in a
final empty-`choices` chunk; the chunk was previously `continue`-d past,
so streaming usage silently came back as `None`.
Replace `accounts/fireworks/models/kimi-k2-instruct-0905` with
`accounts/fireworks/models/kimi-k2p6` across the Fireworks integration
tests. Fireworks appears to have pulled the 0905 slug from serverless
(returns 404 `NOT_FOUND` despite still appearing "Ready" in their UI);
`kimi-k2p6` is the current deployed successor and supports the same
capabilities used by these tests (tool calls, streaming, structured
output).
> [!IMPORTANT]
> **Behavior change on upgrade — minor bump (`1.1.16` → `1.2.0`).**
>
> Streaming calls now raise `StreamChunkTimeoutError` (a `TimeoutError`
subclass — existing `except TimeoutError:` / `except
asyncio.TimeoutError:` handlers catch it) after 120s of content silence
instead of hanging forever. Opt out with `stream_chunk_timeout=None` or
`LANGCHAIN_OPENAI_STREAM_CHUNK_TIMEOUT_S=0`.
>
> Kernel-level TCP keepalive / `TCP_USER_TIMEOUT` are applied via a
custom `httpx` transport. `httpx` disables its env-proxy auto-detection
(`HTTP_PROXY` / `HTTPS_PROXY` / `ALL_PROXY` / `NO_PROXY` and
macOS/Windows system proxy) whenever a transport is supplied, so to
avoid silently breaking enterprise proxy users, `ChatOpenAI` now detects
the "proxy-env-shadow" shape at construction and **skips the custom
transport entirely** when **all** of these hold:
>
> - `http_socket_options` left at default (`None`)
> - No `http_client` or `http_async_client` supplied
> - No `openai_proxy` supplied
> - A proxy env var / system proxy is visible to httpx
>
> On that shape the instance falls back to pre-PR behavior and env-proxy
auto-detection still applies. A one-time `INFO` records the bypass.
>
> Users who explicitly set `http_socket_options=[...]` alongside an env
proxy still get the shadowed behavior with a one-time `WARNING` log —
they opted in. Full opt-outs below.
---
Streaming chat completions can hang forever when the underlying TCP
connection silently dies mid-stream (idle NAT/LB timeouts, sandboxed
runtimes killing long-lived connections, peer gone without a FIN or
RST). httpx's read timeout doesn't help here because it's reset by any
bytes arriving on the socket, including OpenAI's SSE keepalive comments,
so a stream that's quiet on content but still producing keepalives looks
alive forever.
This PR adds two knobs to `ChatOpenAI`, both on by default with
opt-outs:
- `stream_chunk_timeout` (default 120s): wraps the async streaming
iterator in `asyncio.wait_for` per chunk. Measures the gap between
*parsed* SSE chunks, so keepalives don't reset it. Fires on genuine
content silence and raises `StreamChunkTimeoutError` — a `TimeoutError`
subclass carrying `timeout_s`, `model_name`, and `chunks_received` as
structured attributes (mirrored in the WARNING log's `extra=`) for
alerting without message-regex. Override with the kwarg or
`LANGCHAIN_OPENAI_STREAM_CHUNK_TIMEOUT_S`.
- `http_socket_options`: applies `SO_KEEPALIVE` + `TCP_KEEPIDLE` /
`TCP_KEEPINTVL` / `TCP_KEEPCNT` + `TCP_USER_TIMEOUT` on Linux (macOS
equivalents where available). On platforms missing some options, they're
dropped silently and the remaining set still does useful work.
Pool limits are set explicitly on the custom transport to mirror the
`openai` SDK — without that, passing `transport=` to `httpx.AsyncClient`
silently shrinks the connection pool.
## Behavior change
The default-shape proxy-env bypass (above) covers the common enterprise
case. Beyond that:
- Connections that would previously have hung forever will now error out
via `StreamChunkTimeoutError`.
- Users who explicitly opt into `http_socket_options` while also relying
on env proxies will see a one-time `WARNING` and lose env-proxy
auto-detection — the custom transport shadows it. This is the original
shipped behavior, retained for anyone who *wants* socket tuning on top
of an env-proxied setup.
Full opt-outs:
- `stream_chunk_timeout=None` or
`LANGCHAIN_OPENAI_STREAM_CHUNK_TIMEOUT_S=0`
- `http_socket_options=()` or `LANGCHAIN_OPENAI_TCP_KEEPALIVE=0`
- Supply your own `http_client` **and** `http_async_client`.
`http_socket_options` is applied per side: passing only one still leaves
the other side's default builder getting socket options. Supply both (or
combine with `http_socket_options=()`) to take full control.
Unparseable or negative values for the `LANGCHAIN_OPENAI_*` env vars
fall back to the default with a `WARNING` log rather than silently being
accepted, so a misconfigured environment still boots but the fallback is
discoverable.
---------
Co-authored-by: Mason Daugherty <github@mdrxy.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
Standardize the `integration_tests` Makefile target across all 15
partner packages in `libs/partners/`, mirroring the deepagents
`libs/evals` pattern (`-v --tb=short`). Previously each partner had its
own ad-hoc flag stack (some missing `-n auto`, some with `-vvv`, others
with nothing), and every partner that used `-n auto` was emitting a
`PytestBenchmarkWarning` because `pytest-benchmark` is pulled in
transitively via `langchain-tests` even though no partner has benchmark
tests.
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>