mirror of
https://github.com/Mintplex-Labs/anything-llm
synced 2026-04-25 17:15:37 +02:00
feat(agents): Add Perplexity Search API as web search provider (#5210)
* feat(agents): Add Perplexity Search API as web search provider Adds Perplexity as a search provider for the agent web-browsing plugin, using the Perplexity Search API (POST /search) which returns raw ranked web results — distinct from the existing Perplexity LLM integration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: replace docs.perplexity.ai with console.perplexity.ai * chore: replace docs.perplexity.ai with console.perplexity.ai --------- Co-authored-by: kesku <kesku@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
This commit is contained in:
@@ -390,6 +390,9 @@ GID='1000'
|
||||
#------ Exa Search ----------- https://www.exa.ai/
|
||||
# AGENT_EXA_API_KEY=
|
||||
|
||||
#------ Perplexity Search ----------- [https://console.perplexity.ai](https://console.perplexity.ai)
|
||||
# AGENT_PERPLEXITY_API_KEY=
|
||||
|
||||
###########################################
|
||||
######## Other Configurations ############
|
||||
###########################################
|
||||
|
||||
@@ -384,3 +384,38 @@ export function ExaSearchOptions({ settings }) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function PerplexitySearchOptions({ settings }) {
|
||||
return (
|
||||
<>
|
||||
<p className="text-sm text-white/60 my-2">
|
||||
You can get an API key{" "}
|
||||
<a
|
||||
href="https://console.perplexity.ai"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-blue-300 underline"
|
||||
>
|
||||
from Perplexity.
|
||||
</a>
|
||||
</p>
|
||||
<div className="flex gap-x-4">
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
API Key
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="env::AgentPerplexityApiKey"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Perplexity API Key"
|
||||
defaultValue={settings?.AgentPerplexityApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -10,6 +10,7 @@ import SearXNGSearchIcon from "./icons/searxng.png";
|
||||
import TavilySearchIcon from "./icons/tavily.svg";
|
||||
import DuckDuckGoIcon from "./icons/duckduckgo.png";
|
||||
import ExaIcon from "./icons/exa.png";
|
||||
import PerplexitySearchIcon from "./icons/perplexity.png";
|
||||
import {
|
||||
CaretUpDown,
|
||||
MagnifyingGlass,
|
||||
@@ -29,6 +30,7 @@ import {
|
||||
TavilySearchOptions,
|
||||
DuckDuckGoOptions,
|
||||
ExaSearchOptions,
|
||||
PerplexitySearchOptions,
|
||||
} from "./SearchProviderOptions";
|
||||
|
||||
const SEARCH_PROVIDERS = [
|
||||
@@ -109,6 +111,13 @@ const SEARCH_PROVIDERS = [
|
||||
options: (settings) => <ExaSearchOptions settings={settings} />,
|
||||
description: "AI-powered search engine optimized for LLM use cases.",
|
||||
},
|
||||
{
|
||||
name: "Perplexity Search",
|
||||
value: "perplexity-search",
|
||||
logo: PerplexitySearchIcon,
|
||||
options: (settings) => <PerplexitySearchOptions settings={settings} />,
|
||||
description: "AI-powered web search using the Perplexity Search API.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function AgentWebSearchSelection({
|
||||
|
||||
@@ -388,6 +388,9 @@ TTS_PROVIDER="native"
|
||||
#------ Exa Search ----------- https://www.exa.ai/
|
||||
# AGENT_EXA_API_KEY=
|
||||
|
||||
#------ Perplexity Search ----------- [https://console.perplexity.ai](https://console.perplexity.ai)
|
||||
# AGENT_PERPLEXITY_API_KEY=
|
||||
|
||||
###########################################
|
||||
######## Other Configurations ############
|
||||
###########################################
|
||||
|
||||
@@ -121,6 +121,7 @@ const SystemSettings = {
|
||||
"tavily-search",
|
||||
"duckduckgo-engine",
|
||||
"exa-search",
|
||||
"perplexity-search",
|
||||
].includes(update)
|
||||
)
|
||||
throw new Error("Invalid SERP provider.");
|
||||
@@ -300,6 +301,7 @@ const SystemSettings = {
|
||||
AgentSearXNGApiUrl: process.env.AGENT_SEARXNG_API_URL || null,
|
||||
AgentTavilyApiKey: !!process.env.AGENT_TAVILY_API_KEY || null,
|
||||
AgentExaApiKey: !!process.env.AGENT_EXA_API_KEY || null,
|
||||
AgentPerplexityApiKey: !!process.env.AGENT_PERPLEXITY_API_KEY || null,
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Compliance Settings
|
||||
|
||||
@@ -93,6 +93,9 @@ const webBrowsing = {
|
||||
case "exa-search":
|
||||
engine = "_exaSearch";
|
||||
break;
|
||||
case "perplexity-search":
|
||||
engine = "_perplexitySearch";
|
||||
break;
|
||||
default:
|
||||
engine = "_duckDuckGoEngine";
|
||||
}
|
||||
@@ -978,6 +981,84 @@ const webBrowsing = {
|
||||
);
|
||||
return result;
|
||||
},
|
||||
|
||||
_perplexitySearch: async function (query) {
|
||||
if (!process.env.AGENT_PERPLEXITY_API_KEY) {
|
||||
this.super.introspect(
|
||||
`${this.caller}: I can't use Perplexity searching because the user has not defined the required API key.\nVisit: [https://console.perplexity.ai](https://console.perplexity.ai) to create the API key.`
|
||||
);
|
||||
return `Search is disabled and no content was found. This functionality is disabled because the user has not set it up yet.`;
|
||||
}
|
||||
|
||||
this.super.introspect(
|
||||
`${this.caller}: Using Perplexity to search for "${
|
||||
query.length > 100 ? `${query.slice(0, 100)}...` : query
|
||||
}"`
|
||||
);
|
||||
|
||||
const { response, error } = await fetch(
|
||||
"https://api.perplexity.ai/search",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${process.env.AGENT_PERPLEXITY_API_KEY}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
query: query,
|
||||
max_results: 5,
|
||||
max_tokens_per_page: 2048,
|
||||
}),
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
if (res.ok) return res.json();
|
||||
throw new Error(
|
||||
`${res.status} - ${res.statusText}. params: ${JSON.stringify({
|
||||
auth: this.middleTruncate(
|
||||
process.env.AGENT_PERPLEXITY_API_KEY,
|
||||
5
|
||||
),
|
||||
q: query,
|
||||
})}`
|
||||
);
|
||||
})
|
||||
.then((data) => {
|
||||
return { response: data, error: null };
|
||||
})
|
||||
.catch((e) => {
|
||||
this.super.handlerProps.log(
|
||||
`Perplexity Search Error: ${e.message}`
|
||||
);
|
||||
return { response: null, error: e.message };
|
||||
});
|
||||
|
||||
if (error)
|
||||
return `There was an error searching for content. ${error}`;
|
||||
|
||||
const data = [];
|
||||
if (response.results) {
|
||||
response.results.forEach((result) => {
|
||||
data.push({
|
||||
title: result.title,
|
||||
link: result.url,
|
||||
snippet: result.snippet || "",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (data.length === 0)
|
||||
return "No information was found online for the search query.";
|
||||
|
||||
this.reportSearchResultsCitations(data);
|
||||
|
||||
const result = JSON.stringify(data);
|
||||
this.super.introspect(
|
||||
`${this.caller}: I found ${data.length} results - reviewing the results now. (~${this.countTokens(result)} tokens)`
|
||||
);
|
||||
|
||||
return result;
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -602,6 +602,10 @@ const KEY_MAPPING = {
|
||||
envKey: "AGENT_EXA_API_KEY",
|
||||
checks: [],
|
||||
},
|
||||
AgentPerplexityApiKey: {
|
||||
envKey: "AGENT_PERPLEXITY_API_KEY",
|
||||
checks: [],
|
||||
},
|
||||
|
||||
// TTS/STT Integration ENVS
|
||||
TextToSpeechProvider: {
|
||||
|
||||
Reference in New Issue
Block a user