web-search-plus-plugin 2.0.0 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.template +18 -13
- package/README.md +58 -146
- package/index.ts +6 -4
- package/openclaw.plugin.json +1 -1
- package/package.json +33 -3
package/.env.template
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
#
|
|
2
|
-
SERPER_API_KEY=your-serper-key-here
|
|
1
|
+
# web-search-plus-plugin — add at least one provider key
|
|
3
2
|
|
|
4
|
-
#
|
|
5
|
-
|
|
3
|
+
# Serper (Google Search) — https://serper.dev
|
|
4
|
+
SERPER_API_KEY=
|
|
6
5
|
|
|
7
|
-
#
|
|
8
|
-
|
|
6
|
+
# Tavily (Research Search) — https://tavily.com
|
|
7
|
+
TAVILY_API_KEY=
|
|
9
8
|
|
|
10
9
|
# Exa (Neural/Deep Search) — https://exa.ai
|
|
11
|
-
EXA_API_KEY=
|
|
10
|
+
EXA_API_KEY=
|
|
12
11
|
|
|
13
|
-
#
|
|
14
|
-
|
|
12
|
+
# Querit (Multilingual AI Search) — https://querit.ai
|
|
13
|
+
QUERIT_API_KEY=
|
|
15
14
|
|
|
16
|
-
#
|
|
17
|
-
|
|
15
|
+
# Perplexity (Direct answers) — https://www.perplexity.ai/settings/api
|
|
16
|
+
PERPLEXITY_API_KEY=
|
|
18
17
|
|
|
19
18
|
# You.com — https://api.you.com
|
|
20
|
-
YOU_API_KEY=
|
|
19
|
+
YOU_API_KEY=
|
|
21
20
|
|
|
22
21
|
# SearXNG (self-hosted, no API key needed)
|
|
23
|
-
SEARXNG_INSTANCE_URL=
|
|
22
|
+
SEARXNG_INSTANCE_URL=
|
|
23
|
+
|
|
24
|
+
# Set to 'true' to allow private IPs for SearXNG — disables SSRF protection!
|
|
25
|
+
# SEARXNG_ALLOW_PRIVATE=true
|
|
26
|
+
|
|
27
|
+
# Kilo.ai gateway (alternative Perplexity/other providers route) — https://api.kilo.ai
|
|
28
|
+
KILOCODE_API_KEY=
|
package/README.md
CHANGED
|
@@ -1,173 +1,85 @@
|
|
|
1
|
-
#
|
|
1
|
+
# web-search-plus-plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Multi-provider web search plugin for OpenClaw.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- **Pure TypeScript** — single-file implementation, all logic in `index.ts`
|
|
12
|
-
- **Zero dependencies** — Node.js builtins only, no Python, no `child_process`
|
|
13
|
-
- **7 providers** — Serper, Tavily, Querit, Exa, Perplexity, You.com, SearXNG
|
|
14
|
-
- **Intelligent auto-routing** — analyzes query intent, picks the best provider
|
|
15
|
-
- **Automatic fallback** — if a provider fails, the next healthy one takes over
|
|
16
|
-
- **Local result caching** — file-based, survives restarts, saves API credits
|
|
17
|
-
- **Provider health tracking** — exponential cooldown on repeated failures
|
|
18
|
-
- **SSRF protection** — SearXNG URLs validated via `dns/promises` + `net`
|
|
19
|
-
|
|
20
|
-
## 🔎 Supported Providers
|
|
21
|
-
|
|
22
|
-
| Provider | Best for | Free tier |
|
|
23
|
-
|----------|----------|-----------|
|
|
24
|
-
| **Serper** (Google) | Facts, news, shopping, local businesses | 2,500 queries/month |
|
|
25
|
-
| **Tavily** | Deep research, analysis, explanations | 1,000 queries/month |
|
|
26
|
-
| **Querit** | Multi-lingual AI search with rich metadata and real-time info | 1,000 queries/month |
|
|
27
|
-
| **Exa** (Neural) | Semantic discovery, finding similar content | 1,000 queries/month |
|
|
28
|
-
| **Perplexity** | AI-synthesized answers with citations | Via API key |
|
|
29
|
-
| **You.com** | Real-time RAG, LLM-ready snippets | Limited free tier |
|
|
30
|
-
| **SearXNG** | Privacy-first, self-hosted, $0 cost | Free (self-hosted) |
|
|
31
|
-
|
|
32
|
-
## 🧠 Auto-Routing Examples
|
|
7
|
+
```bash
|
|
8
|
+
openclaw plugins install clawhub:web-search-plus-plugin
|
|
9
|
+
```
|
|
33
10
|
|
|
34
|
-
|
|
11
|
+
It registers a `web_search_plus` tool that can query multiple providers and auto-route to the one that best fits the query.
|
|
35
12
|
|
|
36
|
-
|
|
37
|
-
|-------|-----------|-----|
|
|
38
|
-
| "iPhone 16 Pro price" | Serper | Shopping intent detected |
|
|
39
|
-
| "how does TCP/IP work" | Tavily | Research/explanation intent |
|
|
40
|
-
| "latest multilingual EV market updates" | Querit | Real-time AI search with metadata-rich results |
|
|
41
|
-
| "companies like Stripe" | Exa | Discovery/semantic intent |
|
|
42
|
-
| "what is quantum computing" | Perplexity | Direct answer intent |
|
|
43
|
-
| "latest news AI regulation" | Serper | News intent |
|
|
13
|
+
## Why use this instead of OpenClaw's built-in `web_search`?
|
|
44
14
|
|
|
45
|
-
|
|
15
|
+
OpenClaw's built-in `web_search` uses Brave Search.
|
|
46
16
|
|
|
47
|
-
|
|
17
|
+
You might want this plugin when:
|
|
18
|
+
- Brave returns thin or no results for a query, but Serper/Google or You.com still finds relevant pages.
|
|
19
|
+
- You want research-oriented output; Tavily can return structured results that are easier to summarize.
|
|
20
|
+
- You want semantic discovery; Exa can find related content that plain keyword search may miss.
|
|
48
21
|
|
|
49
|
-
|
|
22
|
+
Supported providers:
|
|
23
|
+
- Serper (Google)
|
|
24
|
+
- Tavily
|
|
25
|
+
- Exa
|
|
26
|
+
- Querit
|
|
27
|
+
- Perplexity
|
|
28
|
+
- You.com
|
|
29
|
+
- SearXNG
|
|
50
30
|
|
|
51
|
-
|
|
52
|
-
npm install web-search-plus-plugin
|
|
53
|
-
```
|
|
31
|
+
## What you need
|
|
54
32
|
|
|
55
|
-
|
|
33
|
+
You do not need every provider.
|
|
56
34
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
35
|
+
You need at least one configured provider:
|
|
36
|
+
- an API key for any hosted provider, or
|
|
37
|
+
- a SearXNG instance URL
|
|
60
38
|
|
|
61
|
-
|
|
39
|
+
## Quick setup
|
|
62
40
|
|
|
63
41
|
```bash
|
|
64
42
|
cp .env.template .env
|
|
65
|
-
#
|
|
43
|
+
# add at least one API key or SearXNG URL
|
|
66
44
|
```
|
|
67
45
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```json
|
|
71
|
-
{
|
|
72
|
-
"plugins": {
|
|
73
|
-
"load": {
|
|
74
|
-
"paths": [
|
|
75
|
-
"./node_modules/web-search-plus-plugin"
|
|
76
|
-
]
|
|
77
|
-
},
|
|
78
|
-
"entries": {
|
|
79
|
-
"web-search-plus-plugin": {
|
|
80
|
-
"enabled": true
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Restart your gateway after adding the plugin.
|
|
88
|
-
|
|
89
|
-
## 🔑 Environment Variables
|
|
90
|
-
|
|
91
|
-
Copy `.env.template` to `.env` and add at least one API key:
|
|
92
|
-
|
|
93
|
-
| Variable | Provider | Sign up |
|
|
94
|
-
|----------|----------|---------|
|
|
95
|
-
| `SERPER_API_KEY` | Serper (Google) | [console.serper.dev](https://console.serper.dev) |
|
|
96
|
-
| `TAVILY_API_KEY` | Tavily | [tavily.com](https://tavily.com) |
|
|
97
|
-
| `QUERIT_API_KEY` | Querit | [querit.ai](https://querit.ai) |
|
|
98
|
-
| `EXA_API_KEY` | Exa | [exa.ai](https://exa.ai) |
|
|
99
|
-
| `PERPLEXITY_API_KEY` | Perplexity | [perplexity.ai](https://docs.perplexity.ai) |
|
|
100
|
-
| `KILOCODE_API_KEY` | Perplexity via Kilo | [kilocode.ai](https://kilocode.ai) |
|
|
101
|
-
| `YOU_API_KEY` | You.com | [you.com/api](https://you.com/api) |
|
|
102
|
-
| `SEARXNG_INSTANCE_URL` | SearXNG (self-hosted) | [docs.searxng.org](https://docs.searxng.org) |
|
|
103
|
-
|
|
104
|
-
You can also configure these values through OpenClaw plugin config. Local `.env` values remain convenient for development.
|
|
105
|
-
|
|
106
|
-
## 🤖 Enable for an Agent
|
|
107
|
-
|
|
108
|
-
Allow the tool in your agent config:
|
|
109
|
-
|
|
110
|
-
```json
|
|
111
|
-
{
|
|
112
|
-
"agents": {
|
|
113
|
-
"list": [
|
|
114
|
-
{
|
|
115
|
-
"name": "my-agent",
|
|
116
|
-
"tools": {
|
|
117
|
-
"allow": ["web_search_plus"]
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
]
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
## 🛠️ Tool Parameters
|
|
126
|
-
|
|
127
|
-
The registered `web_search_plus` tool accepts:
|
|
128
|
-
|
|
129
|
-
| Parameter | Type | Required | Description |
|
|
130
|
-
|-----------|------|----------|-------------|
|
|
131
|
-
| `query` | string | ✅ | Search query |
|
|
132
|
-
| `provider` | string | ❌ | Force a provider: `serper`, `tavily`, `querit`, `exa`, `perplexity`, `you`, `searxng`, or `auto` (default) |
|
|
133
|
-
| `count` | number | ❌ | Number of results (default: 5, max: 10) |
|
|
134
|
-
| `depth` | string | ❌ | Exa depth: `normal`, `deep`, or `deep-reasoning` |
|
|
135
|
-
| `time_range` | string | ❌ | Recency filter where supported: `day`, `week`, `month`, `year` |
|
|
136
|
-
| `include_domains` | string[] | ❌ | Restrict results to these domains where supported (Tavily, Exa, Querit) |
|
|
137
|
-
| `exclude_domains` | string[] | ❌ | Exclude these domains where supported (Tavily, Exa, Querit) |
|
|
138
|
-
|
|
139
|
-
## ❓ FAQ
|
|
140
|
-
|
|
141
|
-
### Do I need all 7 providers?
|
|
142
|
-
No. The plugin works with just one API key. Configure whichever providers you have — the auto-router will use what's available and skip what's not.
|
|
143
|
-
|
|
144
|
-
### What's the difference between this plugin and the `web-search-plus` skill?
|
|
145
|
-
The **plugin** registers a native tool that any agent can use directly. The **skill** provides a SKILL.md with instructions for the agent. The plugin is the recommended approach.
|
|
146
|
-
|
|
147
|
-
### How does auto-routing work?
|
|
148
|
-
The router scores each configured provider based on query signals. Shopping keywords boost Serper, explanation queries boost Tavily, multilingual/real-time queries favor Querit, semantic/discovery queries boost Exa, and direct questions boost Perplexity. Highest score wins, with automatic fallback on failure.
|
|
46
|
+
Then load the plugin in OpenClaw and restart the gateway.
|
|
149
47
|
|
|
150
|
-
|
|
151
|
-
Yes. Results are cached locally in a `.cache/` directory inside the plugin folder. Identical queries return cached results instantly and don't consume API credits. Cache is file-based and survives restarts.
|
|
48
|
+
## Provider overview
|
|
152
49
|
|
|
153
|
-
|
|
154
|
-
|
|
50
|
+
| Provider | Best for | Free tier | Rate limit (free) |
|
|
51
|
+
| --- | --- | --- | --- |
|
|
52
|
+
| Serper | Google-style general web, news, shopping, local results | Yes | 2,500/mo |
|
|
53
|
+
| Tavily | Research-style results and summaries | Yes | 1,000/mo |
|
|
54
|
+
| Exa | Semantic / neural discovery | Yes | 1,000/mo |
|
|
55
|
+
| Querit | Multilingual and regional search | Yes | Varies |
|
|
56
|
+
| Perplexity | Answer-style web results with citations | Limited / depends on plan | API credits required |
|
|
57
|
+
| You.com | General web + answer-oriented results | Limited | 60 req/hr |
|
|
58
|
+
| SearXNG | Self-hosted metasearch | Yes, self-hosted | Self-hosted, unlimited |
|
|
155
59
|
|
|
156
|
-
|
|
157
|
-
SearXNG is a self-hosted meta search engine that aggregates 70+ sources. It's free but requires your own instance. The plugin validates instance URLs before querying and includes SSRF protection using Node.js DNS/IP checks for security.
|
|
60
|
+
## Auto-routing logic
|
|
158
61
|
|
|
159
|
-
|
|
160
|
-
Yes, as long as the tool is allowed in the agent's tool config. The plugin runs on the host alongside the gateway.
|
|
62
|
+
The plugin scores each query against the providers you have configured and picks the best match for that query type. If the first choice is unavailable or fails, it falls back to another configured provider instead of failing immediately.
|
|
161
63
|
|
|
162
|
-
##
|
|
64
|
+
## Notes
|
|
163
65
|
|
|
164
|
-
-
|
|
165
|
-
-
|
|
66
|
+
- Auto-routing chooses among configured providers only.
|
|
67
|
+
- If a provider is missing credentials, it is skipped.
|
|
68
|
+
- SearXNG includes SSRF protection by default.
|
|
69
|
+
- `SEARXNG_ALLOW_PRIVATE=true` disables that protection and should only be used on trusted private networks.
|
|
166
70
|
|
|
167
|
-
##
|
|
71
|
+
## Environment variables
|
|
168
72
|
|
|
169
|
-
|
|
73
|
+
- `SERPER_API_KEY`
|
|
74
|
+
- `TAVILY_API_KEY`
|
|
75
|
+
- `EXA_API_KEY`
|
|
76
|
+
- `QUERIT_API_KEY`
|
|
77
|
+
- `PERPLEXITY_API_KEY`
|
|
78
|
+
- `KILOCODE_API_KEY`
|
|
79
|
+
- `YOU_API_KEY`
|
|
80
|
+
- `SEARXNG_INSTANCE_URL`
|
|
81
|
+
- `SEARXNG_ALLOW_PRIVATE`
|
|
170
82
|
|
|
171
|
-
##
|
|
83
|
+
## Repository
|
|
172
84
|
|
|
173
|
-
|
|
85
|
+
GitHub: <https://github.com/robbyczgw-cla/web-search-plus-plugin>
|
package/index.ts
CHANGED
|
@@ -286,7 +286,7 @@ function loadEnvFile(envPath: string): Record<string, string> {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
function getRuntimeEnv(pluginConfig: Record<string, string>): Record<string, string> {
|
|
289
|
-
const envFiles = [path.join(PLUGIN_DIR, ".env")
|
|
289
|
+
const envFiles = [path.join(PLUGIN_DIR, ".env")];
|
|
290
290
|
const fileEnv = Object.assign({}, ...envFiles.map(loadEnvFile));
|
|
291
291
|
const mapped: Record<string, string> = {};
|
|
292
292
|
const configKeyMap: Record<string, string> = {
|
|
@@ -314,8 +314,8 @@ function getApiKey(provider: ProviderName, env: Record<string, string>): string
|
|
|
314
314
|
querit: env.QUERIT_API_KEY,
|
|
315
315
|
exa: env.EXA_API_KEY,
|
|
316
316
|
perplexity: env.KILOCODE_API_KEY || env.PERPLEXITY_API_KEY,
|
|
317
|
-
you: env.YOU_API_KEY,
|
|
318
|
-
searxng: env.SEARXNG_INSTANCE_URL,
|
|
317
|
+
you: env.YOU_API_KEY || env.YOUCOM_API_KEY,
|
|
318
|
+
searxng: env.SEARXNG_INSTANCE_URL || env.SEARXNG_URL,
|
|
319
319
|
};
|
|
320
320
|
return keyMap[provider];
|
|
321
321
|
}
|
|
@@ -387,7 +387,9 @@ async function validateSearxngUrl(input: string, env: Record<string, string>): P
|
|
|
387
387
|
const blockedHosts = new Set(["169.254.169.254", "metadata.google.internal", "metadata.internal"]);
|
|
388
388
|
if (blockedHosts.has(u.hostname)) throw new ProviderConfigError("SearXNG URL blocked: metadata endpoint");
|
|
389
389
|
|
|
390
|
-
|
|
390
|
+
// WARNING: Setting SEARXNG_ALLOW_PRIVATE=true disables SSRF protection for SearXNG.
|
|
391
|
+
// Only enable on fully trusted private networks.
|
|
392
|
+
const allowPrivate = ["1", "true", "yes"].includes(String(env.SEARXNG_ALLOW_PRIVATE || "").trim().toLowerCase());
|
|
391
393
|
if (!allowPrivate) {
|
|
392
394
|
const records = await dns.lookup(u.hostname, { all: true, verbatim: true }).catch(() => [] as dns.LookupAddress[]);
|
|
393
395
|
if (!records.length && net.isIP(u.hostname)) records.push({ address: u.hostname, family: net.isIP(u.hostname) as 4 | 6 });
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "web-search-plus-plugin",
|
|
3
3
|
"name": "Web Search Plus",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"description": "Multi-provider web search (Serper/Google, Tavily, Querit/Multilingual AI Search, Exa/Neural+Deep, Perplexity, You.com, SearXNG) with intelligent auto-routing",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
package/package.json
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-search-plus-plugin",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "OpenClaw plugin: multi-provider web search (Serper/Google, Tavily, Querit/Multilingual AI Search, Exa/Neural+Deep, Perplexity, You.com, SearXNG) with intelligent auto-routing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"openclaw": {
|
|
8
|
-
"extensions": [
|
|
8
|
+
"extensions": [
|
|
9
|
+
"./index.ts"
|
|
10
|
+
],
|
|
11
|
+
"compat": {
|
|
12
|
+
"pluginApi": ">=2026.3.22"
|
|
13
|
+
},
|
|
14
|
+
"env": {
|
|
15
|
+
"SERPER_API_KEY": "optional \u2014 Serper/Google search API key",
|
|
16
|
+
"TAVILY_API_KEY": "optional \u2014 Tavily research search API key",
|
|
17
|
+
"EXA_API_KEY": "optional \u2014 Exa neural search API key",
|
|
18
|
+
"QUERIT_API_KEY": "optional \u2014 Querit multilingual search API key",
|
|
19
|
+
"PERPLEXITY_API_KEY": "optional \u2014 Perplexity AI search API key",
|
|
20
|
+
"KILOCODE_API_KEY": "optional \u2014 Kilo.ai gateway API key",
|
|
21
|
+
"YOU_API_KEY": "optional \u2014 You.com search API key",
|
|
22
|
+
"SEARXNG_INSTANCE_URL": "optional \u2014 SearXNG self-hosted instance URL",
|
|
23
|
+
"SEARXNG_ALLOW_PRIVATE": "optional \u2014 set true to allow private IPs for SearXNG (disables SSRF protection)"
|
|
24
|
+
}
|
|
9
25
|
},
|
|
10
26
|
"files": [
|
|
11
27
|
"index.ts",
|
|
@@ -14,7 +30,21 @@
|
|
|
14
30
|
"README.md",
|
|
15
31
|
"LICENSE"
|
|
16
32
|
],
|
|
17
|
-
"keywords": [
|
|
33
|
+
"keywords": [
|
|
34
|
+
"openclaw",
|
|
35
|
+
"plugin",
|
|
36
|
+
"search",
|
|
37
|
+
"serper",
|
|
38
|
+
"tavily",
|
|
39
|
+
"querit",
|
|
40
|
+
"exa",
|
|
41
|
+
"exa-deep",
|
|
42
|
+
"perplexity",
|
|
43
|
+
"you",
|
|
44
|
+
"searxng",
|
|
45
|
+
"web-search",
|
|
46
|
+
"auto-routing"
|
|
47
|
+
],
|
|
18
48
|
"peerDependencies": {
|
|
19
49
|
"openclaw": ">=2026.3.22"
|
|
20
50
|
},
|