Roo-Code/src/api/providers/perplexity.ts
james-pplx 16e37607d0 feat: add Perplexity as a first-class API provider
Introduce a new Perplexity provider that targets Perplexity's
OpenAI-compatible chat-completions endpoint at https://api.perplexity.ai.
Models exposed: sonar, sonar-pro, sonar-reasoning, sonar-reasoning-pro
(all 128k context).

API key resolution order:
  1. perplexityApiKey from settings
  2. PERPLEXITY_API_KEY env var
  3. PPLX_API_KEY env var (fallback)

Wired into the provider registry (packages/types), api factory,
profile validation, webview settings UI, model picker, validation,
and English locale strings.

Tests cover construction, base URL/auth, env-var fallbacks, model
selection, streaming, and error propagation.
2026-05-17 10:33:06 +00:00

38 lines
1.3 KiB
TypeScript

import { type PerplexityModelId, perplexityDefaultModelId, perplexityModels } from "@roo-code/types"
import type { ApiHandlerOptions } from "../../shared/api"
import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider"
/**
* Resolves the Perplexity API key in priority order:
* 1. explicit settings value
* 2. PERPLEXITY_API_KEY env var
* 3. PPLX_API_KEY env var (fallback)
*/
export function resolvePerplexityApiKey(explicit?: string): string | undefined {
if (explicit && explicit.length > 0) {
return explicit
}
return process.env.PERPLEXITY_API_KEY || process.env.PPLX_API_KEY || undefined
}
const REASONING_MODELS = new Set<PerplexityModelId>(["sonar-reasoning", "sonar-reasoning-pro"])
export class PerplexityHandler extends BaseOpenAiCompatibleProvider<PerplexityModelId> {
constructor(options: ApiHandlerOptions) {
super({
...options,
providerName: "Perplexity",
baseURL: "https://api.perplexity.ai",
apiKey: resolvePerplexityApiKey(options.perplexityApiKey),
defaultProviderModelId: perplexityDefaultModelId,
providerModels: perplexityModels,
defaultTemperature: 0,
})
}
protected override getTemperature(model: PerplexityModelId, info = this.providerModels[model]): number | undefined {
return REASONING_MODELS.has(model) ? undefined : super.getTemperature(model, info)
}
}