θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"Qdrant",
"royalblue",
"searxng",
"SearchApi",
"Serper",
"Serply",
"streamable",
Expand Down
4 changes: 4 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ GID='1000'
# AGENT_GSE_KEY=
# AGENT_GSE_CTX=

#------ SearchApi.io ----------- https://www.searchapi.io/
# AGENT_SEARCHAPI_API_KEY=
# AGENT_SEARCHAPI_ENGINE=google

#------ Serper.dev ----------- https://serper.dev/
# AGENT_SERPER_DEV_KEY=

Expand Down
2 changes: 2 additions & 0 deletions docker/HOW_TO_USE_DOCKER.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ services:
- WHISPER_PROVIDER=local
- TTS_PROVIDER=native
- PASSWORDMINCHAR=8
- AGENT_SEARCHAPI_API_KEY="SearchApi API KEY"
- AGENT_SEARCHAPI_ENGINE=google
- AGENT_SERPER_DEV_KEY="SERPER DEV API KEY"
- AGENT_SERPLY_API_KEY="Serply.io API KEY"
volumes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,56 @@ export function GoogleSearchOptions({ settings }) {
);
}

export function SearchApiOptions({ settings }) {
return (
<>
<p className="text-sm text-white/60 my-2">
You can get a free API key{" "}
<a
href="https://www.searchapi.io/"
target="_blank"
rel="noreferrer"
className="text-blue-300 underline"
>
from SearchApi.
</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::AgentSearchApiKey"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="SearchApi API Key"
defaultValue={settings?.AgentSearchApiKey ? "*".repeat(20) : ""}
required={true}
autoComplete="off"
spellCheck={false}
/>
</div>
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-3">
Engine
</label>
<input
type="text"
name="env::AgentSearchApiEngine"
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="SearchApi engine (Google, Bing...)"
defaultValue={settings?.AgentSearchApiEngine || "google"}
required={true}
autoComplete="off"
spellCheck={false}
/>
</div>
</div>
</>
);
}

export function SerperDotDevOptions({ settings }) {
return (
<>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions frontend/src/pages/Admin/Agents/WebSearchSelection/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useRef, useState } from "react";
import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
import GoogleSearchIcon from "./icons/google.png";
import SearchApiIcon from "./icons/searchapi.png";
import SerperDotDevIcon from "./icons/serper.png";
import BingSearchIcon from "./icons/bing.png";
import SerplySearchIcon from "./icons/serply.png";
Expand All @@ -14,6 +15,7 @@ import {
import SearchProviderItem from "./SearchProviderItem";
import WebSearchImage from "@/media/agents/scrape-websites.png";
import {
SearchApiOptions,
SerperDotDevOptions,
GoogleSearchOptions,
BingSearchOptions,
Expand All @@ -38,6 +40,14 @@ const SEARCH_PROVIDERS = [
description:
"Web search powered by a custom Google Search Engine. Free for 100 queries per day.",
},
{
name: "SearchApi",
value: "searchapi",
logo: SearchApiIcon,
options: (settings) => <SearchApiOptions settings={settings} />,
description:
"SearchApi delivers structured data from search engines like Google Search, Bing Search, Baidu Search, Google News, YouTube, and many more. Free for 100 queries, but then paid. ",
},
{
name: "Serper.dev",
value: "serper-dot-dev",
Expand Down
3 changes: 3 additions & 0 deletions server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ TTS_PROVIDER="native"
# AGENT_GSE_KEY=
# AGENT_GSE_CTX=

#------ SearchApi.io ----------- https://www.searchapi.io/
# AGENT_SEARCHAPI_API_KEY=

#------ Serper.dev ----------- https://serper.dev/
# AGENT_SERPER_DEV_KEY=

Expand Down
3 changes: 3 additions & 0 deletions server/models/systemSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const SystemSettings = {
if (
![
"google-search-engine",
"searchapi",
"serper-dot-dev",
"bing-search",
"serply-engine",
Expand Down Expand Up @@ -218,6 +219,8 @@ const SystemSettings = {
// --------------------------------------------------------
AgentGoogleSearchEngineId: process.env.AGENT_GSE_CTX || null,
AgentGoogleSearchEngineKey: !!process.env.AGENT_GSE_KEY || null,
AgentSearchApiKey: !!process.env.AGENT_SEARCHAPI_API_KEY || null,
AgentSearchApiEngine: process.env.AGENT_SEARCHAPI_ENGINE || "google",
AgentSerperApiKey: !!process.env.AGENT_SERPER_DEV_KEY || null,
AgentBingSearchApiKey: !!process.env.AGENT_BING_SEARCH_API_KEY || null,
AgentSerplyApiKey: !!process.env.AGENT_SERPLY_API_KEY || null,
Expand Down
69 changes: 69 additions & 0 deletions server/utils/agents/aibitat/plugins/web-browsing.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ const webBrowsing = {
case "google-search-engine":
engine = "_googleSearchEngine";
break;
case "searchapi":
engine = "_searchApi";
break;
case "serper-dot-dev":
engine = "_serperDotDev";
break;
Expand Down Expand Up @@ -130,6 +133,72 @@ const webBrowsing = {
return JSON.stringify(data);
},

/**
* Use SearchApi
* SearchApi supports multiple search engines like Google Search, Bing Search, Baidu Search, Google News, YouTube, and many more.
* https://www.searchapi.io/
*/
_searchApi: async function (query) {
if (!process.env.AGENT_SEARCHAPI_API_KEY) {
this.super.introspect(
`${this.caller}: I can't use SearchApi searching because the user has not defined the required API key.\nVisit: https://www.searchapi.io/ to create the API key for free.`
);
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 SearchApi to search for "${
query.length > 100 ? `${query.slice(0, 100)}...` : query
}"`
);

const engine = process.env.AGENT_SEARCHAPI_ENGINE;
const params = new URLSearchParams({
engine: engine,
q: query,
});

const url = `https://www.searchapi.io/api/v1/search?${params.toString()}`;
const { response, error } = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.AGENT_SEARCHAPI_API_KEY}`,
"Content-Type": "application/json",
"X-SearchApi-Source": "AnythingLLM",
},
})
.then((res) => res.json())
.then((data) => {
return { response: data, error: null };
})
.catch((e) => {
return { response: null, error: e.message };
});
if (error)
return `There was an error searching for content. ${error}`;

const data = [];
if (response.hasOwnProperty("knowledge_graph"))
data.push(response.knowledge_graph?.description);
if (response.hasOwnProperty("answer_box"))
data.push(response.answer_box?.answer);
response.organic_results?.forEach((searchResult) => {
const { title, link, snippet } = searchResult;
data.push({
title,
link,
snippet,
});
});

if (data.length === 0)
return `No information was found online for the search query.`;
this.super.introspect(
`${this.caller}: I found ${data.length} results - looking over them now.`
);
return JSON.stringify(data);
},

/**
* Use Serper.dev
* Free to set up, easy to use, 2,500 calls for free one-time
Expand Down
8 changes: 8 additions & 0 deletions server/utils/helpers/updateENV.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,14 @@ const KEY_MAPPING = {
envKey: "AGENT_GSE_KEY",
checks: [],
},
AgentSearchApiKey: {
envKey: "AGENT_SEARCHAPI_API_KEY",
checks: [],
},
AgentSearchApiEngine: {
envKey: "AGENT_SEARCHAPI_ENGINE",
checks: [],
},
AgentSerperApiKey: {
envKey: "AGENT_SERPER_DEV_KEY",
checks: [],
Expand Down