Skip to content

feat: add Perplexity models, connectors, and Computer mode - #11

Open
Xytronix wants to merge 3 commits into
mishamyrt:masterfrom
Xytronix:master
Open

feat: add Perplexity models, connectors, and Computer mode#11
Xytronix wants to merge 3 commits into
mishamyrt:masterfrom
Xytronix:master

Conversation

@Xytronix

@Xytronix Xytronix commented Apr 21, 2026

Copy link
Copy Markdown

This PR adds support for Perplexity Computer, MAX models, Study Mode and Connectors.

I found a large variety of models that you didn't include, I had no time testing all these endpoints.
I included the ones which I am aware people have access to.

@coderabbitai

coderabbitai Bot commented Apr 21, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@Xytronix has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 39 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 9 minutes and 39 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bb2b320e-e90f-4618-a50b-646dcd314808

📥 Commits

Reviewing files that changed from the base of the PR and between f61dbe1 and 7729b28.

📒 Files selected for processing (6)
  • crates/perplexity-web-api-mcp/src/main.rs
  • crates/perplexity-web-api-mcp/src/server.rs
  • crates/perplexity-web-api/src/client.rs
  • crates/perplexity-web-api/src/lib.rs
  • crates/perplexity-web-api/src/models.rs
  • crates/perplexity-web-api/src/types.rs
📝 Walkthrough

Walkthrough

This PR extends the Perplexity Web API MCP server with support for a new Computer search mode (ASI agentic), including a new ComputerModel enum, expanded connector-based sources requiring authentication, and updated model preferences across existing search modes.

Changes

Cohort / File(s) Summary
Model Definitions
crates/perplexity-web-api/src/models.rs, crates/perplexity-web-api/src/types.rs
Added ComputerModel enum with ASI, Claude, GPT, and other variants; extended SearchMode with Computer variant; expanded Source enum to include 20\+ connector types; updated ReasonModel and SearchModel variant sets; replaced DEEP_RESEARCH_MODEL_PREFERENCE with three new preference constants.
Server Configuration & Tooling
crates/perplexity-web-api-mcp/src/main.rs, crates/perplexity-web-api-mcp/src/server.rs
Wired ComputerModel into PerplexityServer constructor and configuration; added computer_model field; implemented new perplexity_computer MCP tool handler; updated server instructions and environment-variable validation for tokenless mode.
API Client & Validation
crates/perplexity-web-api/src/client.rs, crates/perplexity-web-api/src/error.rs, crates/perplexity-web-api/src/lib.rs
Mapped SearchMode::Computer to API_MODE_COPILOT endpoint; added ConnectorRequiresAuth error variant; implemented connector-source authentication validation; updated sources serialization to Vec<String>; added query_source payload parameter; expanded public re-exports to include ComputerModel and preference constants.

Sequence Diagram

sequenceDiagram
    participant Client as MCP Client
    participant Server as PerplexityServer
    participant Validator as Validation Logic
    participant APIClient as Perplexity API Client
    participant API as Perplexity API

    Client->>Server: Call perplexity_computer(request)
    Server->>Validator: validate_request(query, sources, api_key)
    alt Connector source requires auth
        Validator->>APIClient: Check if sources contain non-public connector
        APIClient->>APIClient: is_public() check
        APIClient-->>Validator: ConnectorRequiresAuth error
        Validator-->>Server: Return Error
        Server-->>Client: CallToolResult with error
    else Auth valid or no connectors
        Server->>APIClient: Build SearchMode::Computer request
        APIClient->>APIClient: Map Computer → API_MODE_COPILOT
        APIClient->>APIClient: Apply computer_model preference
        APIClient->>APIClient: Set query_source = "computer"
        APIClient->>API: POST to Perplexity with Computer mode
        API-->>APIClient: Search results
        APIClient-->>Server: Result object
        Server->>Server: Serialize to JSON tool result
        Server-->>Client: CallToolResult with response
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Feature/token check #1: Introduced initial PerplexityServer constructor wiring; this PR extends that foundation by adding ComputerModel field and the perplexity_computer tool handler.

Poem

🐰 A new mode hops in—Computer's bright call,
With connectors galore and auth for all,
ASI agents leap through sources vast,
From Web to Cloud, no auth to outlast,
Perplexity grows wings, faster and tall!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately summarizes the main changes: it adds a new Computer mode, new Perplexity models (MAX variants, reasoning models), and connector support for authentication-based sources.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
crates/perplexity-web-api-mcp/src/server.rs (1)

134-150: ⚠️ Potential issue | 🟡 Minor

Doc for new() is stale and perplexity_computer is silently exposed in tokenless mode.

Two related concerns here:

  1. The doc comment still claims only perplexity_research and perplexity_reason require authenticated session cookies. With this PR, perplexity_computer also requires auth (ASI/connector backends) and should be listed alongside them, or — better — the doc should match the actual runtime behavior.
  2. The perplexity_computer handler added below has no tokenless guard. In tokenless mode the tool is still registered and advertised; invocations will only fail later in the client with Server/ConnectorRequiresAuth. Consider mirroring the pattern used for file attachments: short-circuit with an McpError::invalid_params(...) explaining the required tokens, so clients get an actionable error before paying for a round-trip.

As per coding guidelines: "Update documentation and examples when API behavior changes".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/perplexity-web-api-mcp/src/server.rs` around lines 134 - 150, Update
the stale doc comment on PerplexityServer::new to reflect that
perplexity_computer also requires authenticated session cookies (or reword to
match actual runtime behavior), and add a tokenless guard to the
perplexity_computer handler so it is not silently exposed: mirror the existing
pattern used for file attachments by checking the PerplexityServer.tokenless
flag in the perplexity_computer request handler and short-circuit with
McpError::invalid_params(...) providing a clear message that ASI/connector auth
is required — this ensures the tool is not advertised/usable in tokenless mode
and clients receive an actionable error before a round-trip to the
client/connector.
crates/perplexity-web-api/src/types.rs (2)

161-194: ⚠️ Potential issue | 🟠 Major

Source::FromStr became infallible — typos silently become "connector" sources.

The fallthrough now maps every unknown string to Source::Custom(other.to_owned()). Combined with Source::is_public() returning false for Custom, the effects are:

  • In tokenless mode, a user passing sources: ["wbe"] (typo for "web") fails with ConnectorRequiresAuth instead of an intuitive "unknown source" error.
  • In authenticated mode, the typo is forwarded verbatim to Perplexity's backend and will either be ignored or return an opaque server error.
  • The Err = String associated type is unreachable, and filter_map(|s| s.parse::<Source>().ok()) at crates/perplexity-web-api-mcp/src/server.rs:248 is now a dead filter.

A safer pattern is to keep FromStr strict for the known connector set and expose a separate explicit constructor (e.g. Source::custom(name)) for user-defined remote MCP connectors, so typos are caught at parse time and Custom is only produced intentionally.

Sketch
-            other => Ok(Self::Custom(other.to_owned())),
+            other => Err(format!(
+                "unknown source '{other}'. Use Source::custom(...) for user-defined MCP connectors."
+            )),

Plus an inherent pub fn custom(name: impl Into<String>) -> Self { Self::Custom(name.into()) } for callers who genuinely want to opt into an unknown connector name.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/perplexity-web-api/src/types.rs` around lines 161 - 194, The FromStr
impl for Source is currently infallible and maps any unknown string to
Source::Custom, which hides typos and breaks validation; change impl FromStr for
Source to be strict: only match the known literal variants and return
Err(String) (e.g. Err(format!("unknown source: {}", s))) for any other input,
and add an explicit constructor pub fn custom(name: impl Into<String>) -> Self {
Self::Custom(name.into()) } for callers who really intend a custom connector;
update call sites that relied on infallible parsing (e.g., uses of
s.parse::<Source>().ok() / filter_map) to either handle the Err or call
Source::custom when appropriate.

1-1: ⚠️ Potential issue | 🔴 Critical

Compile error: DEEP_RESEARCH_MODEL_PREFERENCE imported but not defined in models.rs

Line 1 imports DEEP_RESEARCH_MODEL_PREFERENCE from models, and line 32 uses it in the DeepResearch arm of the match statement. The constant no longer exists in models.rs (it was replaced with three new preference constants). This will fail to compile.

Either restore the constant in models.rs or replace line 32 with an enum-based call matching the pattern of other arms, e.g., DeepResearchModel::SomeVariant.api_preference().as_str() or a new constant that actually exists.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/perplexity-web-api/src/types.rs` at line 1, The code imports and uses
the removed DEEP_RESEARCH_MODEL_PREFERENCE constant in the DeepResearch match
arm; remove that import and replace the constant usage with the enum-based call
pattern used by the other arms (i.e., call the DeepResearch model enum variant's
api_preference() and .as_str()). Locate the import of
DEEP_RESEARCH_MODEL_PREFERENCE and the DeepResearch match arm in types.rs and
change the match to something like
<DeepResearchModelEnum>::<appropriate_variant>.api_preference().as_str() (or
call whichever DeepResearch enum method mirrors other ModelPreference usages)
and keep the ModelPreference type import intact.
🧹 Nitpick comments (1)
crates/perplexity-web-api/src/types.rs (1)

27-44: Prefer the ComputerModel enum over a hardcoded preference string in default_preference.

Every other arm delegates to SearchModel/ReasonModel's api_preference().as_str(), which keeps the preference strings in a single source of truth (models.rs). The new Computer arm hardcodes "pplx_asi_opus_thinking" inline, which will silently drift if ComputerModel::Claude46OpusThinking's preference is ever renamed.

Also worth updating the small doc comments below:

Proposed change
-            Self::DeepResearch => DEEP_RESEARCH_MODEL_PREFERENCE,
-            Self::Computer => "pplx_asi_opus_thinking",
+            Self::DeepResearch => DEEP_RESEARCH_MODEL_PREFERENCE,
+            Self::Computer => ComputerModel::Claude46OpusThinking.api_preference().as_str(),
-    /// Search mode: Auto, Pro, Reasoning, or DeepResearch.
+    /// Search mode: Auto, Pro, Reasoning, DeepResearch, or Computer.
     pub mode: SearchMode,
     /// Optional explicit model preference.
     pub model_preference: Option<ModelPreference>,
-    /// Information sources: Web, Scholar, Social.
+    /// Information sources: public (Web, Scholar, Social) or connector-based
+    /// (Google Drive, Notion, GitHub, …) — connectors require auth cookies.
     pub sources: Vec<Source>,

As per coding guidelines: "Update documentation and examples when API behavior changes".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/perplexity-web-api/src/types.rs` around lines 27 - 44, The Computer
arm in default_preference currently hardcodes "pplx_asi_opus_thinking"; replace
that with the canonical preference from the ComputerModel enum (e.g., use
ComputerModel::Claude46OpusThinking.api_preference().as_str() or the appropriate
variant) so the preference stays in sync with models.rs, and update the doc
comment on query_source if needed to reflect the change; modify the match arm in
default_preference to call the enum's api_preference() rather than a literal
string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/perplexity-web-api-mcp/src/main.rs`:
- Around line 115-129: The check that rejects PERPLEXITY_* model env vars uses
env::var(name).is_ok(), which treats empty strings as present; update this logic
to treat empty or whitespace-only values as absent by reusing the same trimming
semantics as optional_model_env (or replicate its trim-and-empty->None behavior)
when inspecting each name in the array, so only non-empty trimmed values trigger
the error in the loop that currently references env::var(name).

In `@crates/perplexity-web-api/src/models.rs`:
- Around line 9-16: The three new public constants
BUSINESS_ASSISTANT_PREFERENCE, DOCUMENT_REVIEW_PREFERENCE, and STUDY_PREFERENCE
are currently unused; wire them into the runtime by mapping them to SearchMode
(update SearchMode::default_preference() and/or add new SearchMode variants that
return these constants) and add the corresponding tool handler(s) in server.rs
(e.g., a perplexity_study handler or extend existing tool dispatch) so the
constants are actually consumed; alternatively remove the public constants if
you prefer not to implement Study/Business/Document modes now. Ensure you
reference the constants by name and update SearchMode and server.rs dispatch to
use them.

---

Outside diff comments:
In `@crates/perplexity-web-api-mcp/src/server.rs`:
- Around line 134-150: Update the stale doc comment on PerplexityServer::new to
reflect that perplexity_computer also requires authenticated session cookies (or
reword to match actual runtime behavior), and add a tokenless guard to the
perplexity_computer handler so it is not silently exposed: mirror the existing
pattern used for file attachments by checking the PerplexityServer.tokenless
flag in the perplexity_computer request handler and short-circuit with
McpError::invalid_params(...) providing a clear message that ASI/connector auth
is required — this ensures the tool is not advertised/usable in tokenless mode
and clients receive an actionable error before a round-trip to the
client/connector.

In `@crates/perplexity-web-api/src/types.rs`:
- Around line 161-194: The FromStr impl for Source is currently infallible and
maps any unknown string to Source::Custom, which hides typos and breaks
validation; change impl FromStr for Source to be strict: only match the known
literal variants and return Err(String) (e.g. Err(format!("unknown source: {}",
s))) for any other input, and add an explicit constructor pub fn custom(name:
impl Into<String>) -> Self { Self::Custom(name.into()) } for callers who really
intend a custom connector; update call sites that relied on infallible parsing
(e.g., uses of s.parse::<Source>().ok() / filter_map) to either handle the Err
or call Source::custom when appropriate.
- Line 1: The code imports and uses the removed DEEP_RESEARCH_MODEL_PREFERENCE
constant in the DeepResearch match arm; remove that import and replace the
constant usage with the enum-based call pattern used by the other arms (i.e.,
call the DeepResearch model enum variant's api_preference() and .as_str()).
Locate the import of DEEP_RESEARCH_MODEL_PREFERENCE and the DeepResearch match
arm in types.rs and change the match to something like
<DeepResearchModelEnum>::<appropriate_variant>.api_preference().as_str() (or
call whichever DeepResearch enum method mirrors other ModelPreference usages)
and keep the ModelPreference type import intact.

---

Nitpick comments:
In `@crates/perplexity-web-api/src/types.rs`:
- Around line 27-44: The Computer arm in default_preference currently hardcodes
"pplx_asi_opus_thinking"; replace that with the canonical preference from the
ComputerModel enum (e.g., use
ComputerModel::Claude46OpusThinking.api_preference().as_str() or the appropriate
variant) so the preference stays in sync with models.rs, and update the doc
comment on query_source if needed to reflect the change; modify the match arm in
default_preference to call the enum's api_preference() rather than a literal
string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1924c803-f90d-443c-9d48-f71033db174b

📥 Commits

Reviewing files that changed from the base of the PR and between 4604fee and f61dbe1.

📒 Files selected for processing (7)
  • crates/perplexity-web-api-mcp/src/main.rs
  • crates/perplexity-web-api-mcp/src/server.rs
  • crates/perplexity-web-api/src/client.rs
  • crates/perplexity-web-api/src/error.rs
  • crates/perplexity-web-api/src/lib.rs
  • crates/perplexity-web-api/src/models.rs
  • crates/perplexity-web-api/src/types.rs

Comment thread crates/perplexity-web-api-mcp/src/main.rs
Comment thread crates/perplexity-web-api/src/models.rs Outdated
Xytronix and others added 2 commits April 21, 2026 21:51
- Fix tokenless env-var check: use optional_env() trim semantics instead
  of env::var().is_ok() so empty/whitespace-only values are treated as
  unset (previously rejected as "cannot be used without auth").
- Remove unused DEEP_RESEARCH_MODEL_PREFERENCE constant; inline
  "pplx_alpha" at its single use site in SearchMode::DeepResearch.
- Add SearchMode::Study and SearchMode::DocumentReview, wired through
  client.rs copilot-mode match.
- Add perplexity_study and perplexity_document_review MCP tools
  following the perplexity_computer pattern.
- Update server instructions to document the new tools.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded 'pplx_asi_opus_thinking' in SearchMode::Computer's
default_preference() with ComputerModel::Claude46OpusThinking.api_preference()
.as_str() to ensure the preference stays synchronized with the model enum
definition. This follows the same pattern as Auto/Pro/Reasoning modes and
prevents divergence if the default model is ever updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant