Commit Graph

28 Commits

Author SHA1 Message Date
rbuchmayer-pplx
1be54cc0e1 fix(perplexity): serialize ToolMessage and AIMessage.tool_calls (#37911)
Fixes #37912

`ChatPerplexity._convert_message_to_dict` raises `TypeError` on
`ToolMessage` and drops `AIMessage.tool_calls`, which breaks
tool-message round-trips through `ChatPerplexity` — a client-side
tool-calling loop, or a shared message history across providers via
`RunnableWithFallbacks`.

Repro:

```python
from langchain_perplexity import ChatPerplexity
from langchain_core.messages import ToolMessage

ChatPerplexity(model="sonar")._convert_message_to_dict(
    ToolMessage(content="result", tool_call_id="call_1")
)
# TypeError: Got unknown type content='result' tool_call_id='call_1'
```

An `AIMessage` carrying `tool_calls` also serializes to `{"role":
"assistant", "content": ...}` with the `tool_calls` silently dropped.

This brings the converter to parity with `langchain-openai`: serialize
`tool_calls` / `invalid_tool_calls`, send `content` as `null` when
tool_calls are present, and add a `tool`-role branch for `ToolMessage`.

How I verified: added unit tests for the `ToolMessage` and
`AIMessage.tool_calls` / `invalid_tool_calls` cases; the perplexity
package unit tests, lint, and format all pass.

Scope: translating these to the Responses (Agent) API's `function_call`
/ `function_call_output` input items is a separate follow-up; this PR is
the Chat Completions serialization parity fix.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-06-05 15:14:42 -04:00
open-swe[bot]
8951e5666f chore(perplexity): bump perplexityai to 0.34.1 (#37710)
## Description
Bumps `langchain-perplexity` to require the Perplexity SDK release with
fixed Responses streaming and removes the temporary SSE shim workaround.

## Release Note
`langchain-perplexity` now requires `perplexityai>=0.34.1` for Responses
API streaming.

## Test Plan
- [x] `NO_COLOR=1 uv run --group test pytest
tests/unit_tests/test_chat_models_responses.py --disable-socket
--allow-unix-socket`

_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>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-05-27 16:41:15 -04:00
James Liounis
f9be3cc328 feat(perplexity): use_responses_api flag on ChatPerplexity (#37359)
Closes #37360

Adds a `use_responses_api` flag to `ChatPerplexity` so requests can be
routed through Perplexity's Agent API (the Perplexity-flavored Responses
API) in addition to the existing Chat Completions endpoint. This mirrors
the `use_responses_api` flag on `ChatOpenAI`.

## Motivation

Perplexity exposes two HTTP surfaces from the same SDK client object:
`client.chat.completions.create()` (Chat Completions) and
`client.responses.create()` (Agent API, OpenAI-compatible Responses
shape). The Agent API supports built-in tools (`web_search`,
`fetch_url`, `finance_search`, `people_search`), `instructions`,
`input`, `previous_response_id`, and `include` — none of which exist on
Chat Completions. Today `ChatPerplexity` only calls Chat Completions, so
users who want the Agent API have to drop down to the raw SDK.

## What this changes

- New field `use_responses_api: bool | None = None` on `ChatPerplexity`.
- New module-level helper `_use_responses_api(payload)` that returns
`True` when the payload contains a built-in tool (any `tools[*]` whose
`type` is not `"function"`) or any of the Responses-only fields
`previous_response_id`, `instructions`, `input`, `include`.
- New instance method `ChatPerplexity._use_responses_api(payload)` that
honors `self.use_responses_api` when it is a `bool`, otherwise delegates
to the module helper.
- New converters `_convert_responses_to_chat_result(response)` and
`_convert_responses_stream_event_to_chunk(event)` that translate Agent
API objects/events into `AIMessage` and `AIMessageChunk` (preserving
`usage_metadata`, `response_metadata`, citations, images, related
questions, search results, and `function_call` tool calls).
- A surgical `_to_responses_payload(...)` helper that renames `messages`
→ `input` and `max_tokens` → `max_output_tokens`, passes through
Responses-supported fields, and parks anything Perplexity-specific under
`extra_body`.
- Each of the four API call sites (`_stream`, `_astream`, `_generate`,
`_agenerate`) now branches on `self._use_responses_api(payload)`. The
Chat Completions path is untouched.

## Auto-detection rules

When `use_responses_api` is unset (the default), routing is decided per
call from the outgoing payload:

- Has a built-in tool? → Responses
- Has `previous_response_id`, `instructions`, `input`, or `include`? →
Responses
- Otherwise → Chat Completions

Explicit `use_responses_api=True` or `=False` always overrides
auto-detection.

## Backwards compatibility

Existing usage is unchanged.
`ChatPerplexity(model="sonar").invoke("hi")` still calls
`client.chat.completions.create()`. No public field was renamed or
removed; the new field is purely additive.

## Tests

Adds `tests/unit_tests/test_chat_models_responses.py` covering the
helper, auto-detect routing, explicit overrides in both directions,
response-to-`AIMessage` conversion (content, `usage_metadata`,
`response_metadata.id`), `function_call` → `tool_calls` conversion, and
sync + async streaming of `response.output_text.delta` and
`response.completed` events. All mocks use `MagicMock`/`AsyncMock`; no
network calls.

## Notes for reviewers

This was implemented with help from an AI agent. The shape mirrors
`langchain-openai`'s `use_responses_api` — same field name, same helper
name, same docstring style — so the diff should be familiar.

Closes nothing — net new feature.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-05-26 20:17:37 -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
Mason Daugherty
2f64d80cc6 fix(core,model-profiles): add missing ModelProfile fields, warn on schema drift (#36129)
PR #35788 added 7 new fields to the `langchain-profiles` CLI output
(`name`, `status`, `release_date`, `last_updated`, `open_weights`,
`attachment`, `temperature`) but didn't update `ModelProfile` in
`langchain-core`. Partner packages like `langchain-aws` that set
`extra="forbid"` on their Pydantic models hit `extra_forbidden`
validation errors when Pydantic encountered undeclared TypedDict keys at
construction time. This adds the missing fields, makes `ModelProfile`
forward-compatible, provides a base-class hook so partners can stop
duplicating model-profile validator boilerplate, migrates all in-repo
partners to the new hook, and adds runtime + CI-time warnings for schema
drift.

## Changes

### `langchain-core`
- Add `__pydantic_config__ = ConfigDict(extra="allow")` to
`ModelProfile` so unknown profile keys pass Pydantic validation even on
models with `extra="forbid"` — forward-compatibility for when the CLI
schema evolves ahead of core
- Declare the 7 missing fields on `ModelProfile`: `name`, `status`,
`release_date`, `last_updated`, `open_weights` (metadata) and
`attachment`, `temperature` (capabilities)
- Add `_warn_unknown_profile_keys()` in `model_profile.py` — emits a
`UserWarning` when a profile dict contains keys not in `ModelProfile`,
suggesting a core upgrade. Wrapped in a bare `except` so introspection
failures never crash model construction
- Add `BaseChatModel._resolve_model_profile()` hook that returns `None`
by default. Partners can override this single method instead of
redefining the full `_set_model_profile` validator — the base validator
calls it automatically
- Add `BaseChatModel._check_profile_keys` as a separate
`model_validator` that calls `_warn_unknown_profile_keys`. Uses a
distinct method name so partner overrides of `_set_model_profile` don't
inadvertently suppress the check

### `langchain-profiles` CLI
- Add `_warn_undeclared_profile_keys()` to the CLI (`cli.py`), called
after merging augmentations in `refresh()` — warns at profile-generation
time (not just runtime) when emitted keys aren't declared in
`ModelProfile`. Gracefully skips if `langchain-core` isn't installed
- Add guard test
`test_model_data_to_profile_keys_subset_of_model_profile` in
model-profiles — feeds a fully-populated model dict to
`_model_data_to_profile()` and asserts every emitted key exists in
`ModelProfile.__annotations__`. CI fails before any release if someone
adds a CLI field without updating the TypedDict

### Partner packages
- Migrate all 10 in-repo partners to the `_resolve_model_profile()`
hook, replacing duplicated `@model_validator` / `_set_model_profile`
overrides: anthropic, deepseek, fireworks, groq, huggingface, mistralai,
openai (base + azure), openrouter, perplexity, xai
- Anthropic retains custom logic (context-1m beta → `max_input_tokens`
override); all others reduce to a one-liner
- Add `pr_lint.yml` scope for the new `model-profiles` package
2026-03-23 00:44:27 -04:00
Kesku
c5baa3ac27 feat(perplexity): overhaul integration with official SDK and Search API (#34412) 2025-12-19 12:58:41 -05:00
ccurme
33e5d01f7c feat(model-profiles): distribute data across packages (#34024) 2025-11-21 15:47:05 -05:00
Mohammad Mohtashim
65716cf590 feat(perplexity): Created Dedicated Output Parser to Support Reasoning Model Output for perplexity (#33670) 2025-11-07 10:17:35 -05:00
Mason Daugherty
e023201d42 style: some cleanup (#33857) 2025-11-06 23:50:46 -05:00
Mohammad Mohtashim
0666571519 chore(perplexity): Added all keys for usage metadata (#33480) 2025-10-24 09:32:35 -04:00
Mason Daugherty
1d2273597a docs: more fixes for refs (#33554) 2025-10-16 22:54:16 -04:00
Mason Daugherty
15db024811 chore: more sweeping (#33533)
more fixes for refs
2025-10-16 15:44:56 -04:00
Mason Daugherty
26e0a00c4c style: more work for refs (#33508)
Largely:
- Remove explicit `"Default is x"` since new refs show default inferred
from sig
- Inline code (useful for eventual parsing)
- Fix code block rendering (indentations)
2025-10-15 18:46:55 -04:00
Mason Daugherty
291a9fcea1 style: llm -> model (#33423) 2025-10-10 13:19:13 -04:00
Mason Daugherty
6fc21afbc9 style: .. code-block:: admonition translations (#33400)
biiiiiiiiiiiiiiiigggggggg pass
2025-10-09 16:52:58 -04:00
Mason Daugherty
d8a680ee57 style: address Sphinx double-backtick snippet syntax (#33389) 2025-10-09 13:35:51 -04:00
Mason Daugherty
3576e690fa chore: update Sphinx links to markdown (#33386) 2025-10-09 11:54:14 -04:00
Mason Daugherty
b6132fc23e style: remove more Optional syntax (#33371) 2025-10-08 23:28:43 -04:00
Mason Daugherty
31eeb50ce0 chore: drop UP045 (#33362)
Python 3.9 EOL
2025-10-08 21:17:53 -04:00
Mason Daugherty
d13823043d style: monorepo pass for refs (#33359)
* Delete some double backticks previously used by Sphinx (not done
everywhere yet)
* Fix some code blocks / dropdowns

Ignoring CLI CI for now
2025-10-08 18:41:39 -04:00
Mason Daugherty
ae5b105d11 docs: v1 docs updates (#33173)
Co-authored-by: Mohammad Mohtashim <45242107+keenborder786@users.noreply.github.com>
Co-authored-by: Caspar Broekhuizen <caspar@langchain.dev>
Co-authored-by: ccurme <chester.curme@gmail.com>
Co-authored-by: Christophe Bornet <cbornet@hotmail.com>
Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
Co-authored-by: Sadra Barikbin <sadraqazvin1@yahoo.com>
Co-authored-by: Vadym Barda <vadim.barda@gmail.com>
2025-10-02 18:46:26 -04:00
Mason Daugherty
d53ebf367e fix(docs): capitalization, codeblock formatting, and hyperlinks, note blocks (#32235)
widespread cleanup attempt
2025-07-24 16:55:04 -04:00
Inácio Nery
ea8f2a05ba feat(perplexity): expose search_results in chat model (#31468)
Description
The Perplexity chat model already returns a search_results field, but
LangChain dropped it when mapping Perplexity responses to
additional_kwargs.
This patch adds "search_results" to the allowed attribute lists in both
_stream and _generate, so downstream code can access it just like
images, citations, or related_questions.

Dependencies
None. The change is purely internal; no new imports or optional
dependencies required.


https://community.perplexity.ai/t/new-feature-search-results-field-with-richer-metadata/398

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2025-07-16 15:16:35 -04:00
ZhangShenao
0b5c06e89f [Doc] Improve api doc for perplexity (#31636)
- add param in api doc
- fix word spelling

---------

Co-authored-by: Chester Curme <chester.curme@gmail.com>
2025-06-17 14:10:43 +00:00
Marina Gómez
afd457d8e1 perplexity[patch]: Fix #30767: Handle missing citations attribute in ChatPerplexity (#30805)
This PR fixes an issue where ChatPerplexity would raise an
AttributeError when the citations attribute was missing from the model
response (e.g., when using offline models like r1-1776).

The fix checks for the presence of citations, images, and
related_questions before attempting to access them, avoiding crashes in
models that don't provide these fields.

Tested locally with models that omit citations, and the fix works as
expected.
2025-04-13 09:24:05 -04:00
Sydney Runkle
8c6734325b partners[lint]: run pyupgrade to get code in line with 3.9 standards (#30781)
Using `pyupgrade` to get all `partners` code up to 3.9 standards
(mostly, fixing old `typing` imports).
2025-04-11 07:18:44 -04:00
Sydney Runkle
33ed7c31da docs: fix perplexity install instructions in ChatPerplexity docstring (#30676)
* `openai` install no longer needs to be done manually
2025-04-04 12:58:18 -04:00
Sydney Runkle
3814bd1ea7 partners: Add Perplexity Chat Integration (#30618)
Perplexity's importance in the space has been growing, so we think it's
time to add an official integration!

Note: following the release of `langchain-perplexity` to `pypi`, we
should be able to add `perplexity` as an extra in
`libs/langchain/pyproject.toml`, but we're blocked by a circular import
for now.

---------

Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
Co-authored-by: Chester Curme <chester.curme@gmail.com>
2025-04-03 16:09:14 +00:00