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:
parent
863ce38137
commit
409ac543bd
@ -390,6 +390,9 @@ GID='1000'
|
|||||||
#------ Exa Search ----------- https://www.exa.ai/
|
#------ Exa Search ----------- https://www.exa.ai/
|
||||||
# AGENT_EXA_API_KEY=
|
# AGENT_EXA_API_KEY=
|
||||||
|
|
||||||
|
#------ Perplexity Search ----------- [https://console.perplexity.ai](https://console.perplexity.ai)
|
||||||
|
# AGENT_PERPLEXITY_API_KEY=
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
######## Other Configurations ############
|
######## 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 TavilySearchIcon from "./icons/tavily.svg";
|
||||||
import DuckDuckGoIcon from "./icons/duckduckgo.png";
|
import DuckDuckGoIcon from "./icons/duckduckgo.png";
|
||||||
import ExaIcon from "./icons/exa.png";
|
import ExaIcon from "./icons/exa.png";
|
||||||
|
import PerplexitySearchIcon from "./icons/perplexity.png";
|
||||||
import {
|
import {
|
||||||
CaretUpDown,
|
CaretUpDown,
|
||||||
MagnifyingGlass,
|
MagnifyingGlass,
|
||||||
@ -29,6 +30,7 @@ import {
|
|||||||
TavilySearchOptions,
|
TavilySearchOptions,
|
||||||
DuckDuckGoOptions,
|
DuckDuckGoOptions,
|
||||||
ExaSearchOptions,
|
ExaSearchOptions,
|
||||||
|
PerplexitySearchOptions,
|
||||||
} from "./SearchProviderOptions";
|
} from "./SearchProviderOptions";
|
||||||
|
|
||||||
const SEARCH_PROVIDERS = [
|
const SEARCH_PROVIDERS = [
|
||||||
@ -109,6 +111,13 @@ const SEARCH_PROVIDERS = [
|
|||||||
options: (settings) => <ExaSearchOptions settings={settings} />,
|
options: (settings) => <ExaSearchOptions settings={settings} />,
|
||||||
description: "AI-powered search engine optimized for LLM use cases.",
|
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({
|
export default function AgentWebSearchSelection({
|
||||||
|
|||||||
@ -388,6 +388,9 @@ TTS_PROVIDER="native"
|
|||||||
#------ Exa Search ----------- https://www.exa.ai/
|
#------ Exa Search ----------- https://www.exa.ai/
|
||||||
# AGENT_EXA_API_KEY=
|
# AGENT_EXA_API_KEY=
|
||||||
|
|
||||||
|
#------ Perplexity Search ----------- [https://console.perplexity.ai](https://console.perplexity.ai)
|
||||||
|
# AGENT_PERPLEXITY_API_KEY=
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
######## Other Configurations ############
|
######## Other Configurations ############
|
||||||
###########################################
|
###########################################
|
||||||
|
|||||||
@ -121,6 +121,7 @@ const SystemSettings = {
|
|||||||
"tavily-search",
|
"tavily-search",
|
||||||
"duckduckgo-engine",
|
"duckduckgo-engine",
|
||||||
"exa-search",
|
"exa-search",
|
||||||
|
"perplexity-search",
|
||||||
].includes(update)
|
].includes(update)
|
||||||
)
|
)
|
||||||
throw new Error("Invalid SERP provider.");
|
throw new Error("Invalid SERP provider.");
|
||||||
@ -300,6 +301,7 @@ const SystemSettings = {
|
|||||||
AgentSearXNGApiUrl: process.env.AGENT_SEARXNG_API_URL || null,
|
AgentSearXNGApiUrl: process.env.AGENT_SEARXNG_API_URL || null,
|
||||||
AgentTavilyApiKey: !!process.env.AGENT_TAVILY_API_KEY || null,
|
AgentTavilyApiKey: !!process.env.AGENT_TAVILY_API_KEY || null,
|
||||||
AgentExaApiKey: !!process.env.AGENT_EXA_API_KEY || null,
|
AgentExaApiKey: !!process.env.AGENT_EXA_API_KEY || null,
|
||||||
|
AgentPerplexityApiKey: !!process.env.AGENT_PERPLEXITY_API_KEY || null,
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// Compliance Settings
|
// Compliance Settings
|
||||||
|
|||||||
@ -93,6 +93,9 @@ const webBrowsing = {
|
|||||||
case "exa-search":
|
case "exa-search":
|
||||||
engine = "_exaSearch";
|
engine = "_exaSearch";
|
||||||
break;
|
break;
|
||||||
|
case "perplexity-search":
|
||||||
|
engine = "_perplexitySearch";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
engine = "_duckDuckGoEngine";
|
engine = "_duckDuckGoEngine";
|
||||||
}
|
}
|
||||||
@ -978,6 +981,84 @@ const webBrowsing = {
|
|||||||
);
|
);
|
||||||
return result;
|
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",
|
envKey: "AGENT_EXA_API_KEY",
|
||||||
checks: [],
|
checks: [],
|
||||||
},
|
},
|
||||||
|
AgentPerplexityApiKey: {
|
||||||
|
envKey: "AGENT_PERPLEXITY_API_KEY",
|
||||||
|
checks: [],
|
||||||
|
},
|
||||||
|
|
||||||
// TTS/STT Integration ENVS
|
// TTS/STT Integration ENVS
|
||||||
TextToSpeechProvider: {
|
TextToSpeechProvider: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user